diff --git a/ui-tui/src/app/useMainApp.ts b/ui-tui/src/app/useMainApp.ts index 159489eb32..8fa7c10619 100644 --- a/ui-tui/src/app/useMainApp.ts +++ b/ui-tui/src/app/useMainApp.ts @@ -272,6 +272,7 @@ export function useMainApp(gw: GatewayClient) { gw, panel, rpc, + scrollRef, setHistoryItems, setLastUserMsg, setSessionStartedAt, diff --git a/ui-tui/src/app/useSessionLifecycle.ts b/ui-tui/src/app/useSessionLifecycle.ts index 8114916c62..e4da3e1bf8 100644 --- a/ui-tui/src/app/useSessionLifecycle.ts +++ b/ui-tui/src/app/useSessionLifecycle.ts @@ -1,4 +1,5 @@ -import { useCallback } from 'react' +import type { ScrollBoxHandle } from '@hermes/ink' +import { type RefObject, useCallback } from 'react' import { buildSetupRequiredSections, SETUP_REQUIRED_TITLE } from '../content/setup.js' import { introMsg, toTranscriptMessages } from '../domain/messages.js' @@ -41,6 +42,7 @@ export interface UseSessionLifecycleOptions { gw: GatewayClient panel: (title: string, sections: PanelSection[]) => void rpc: GatewayRpc + scrollRef: RefObject setHistoryItems: StateSetter setLastUserMsg: StateSetter setSessionStartedAt: StateSetter @@ -57,6 +59,7 @@ export function useSessionLifecycle(opts: UseSessionLifecycleOptions) { gw, panel, rpc, + scrollRef, setHistoryItems, setLastUserMsg, setSessionStartedAt, @@ -183,6 +186,7 @@ export function useSessionLifecycle(opts: UseSessionLifecycleOptions) { status: 'ready', usage: usageFrom(r.info ?? null) }) + queueMicrotask(() => scrollRef.current?.scrollToBottom()) }) .catch((e: Error) => { sys(`error: ${e.message}`) @@ -191,7 +195,7 @@ export function useSessionLifecycle(opts: UseSessionLifecycleOptions) { ) }) }, - [closeSession, colsRef, gw, panel, resetSession, rpc, setHistoryItems, setSessionStartedAt, sys] + [closeSession, colsRef, gw, panel, resetSession, rpc, scrollRef, setHistoryItems, setSessionStartedAt, sys] ) const guardBusySessionSwitch = useCallback( diff --git a/ui-tui/src/hooks/useVirtualHistory.ts b/ui-tui/src/hooks/useVirtualHistory.ts index b92c07c462..d33971fede 100644 --- a/ui-tui/src/hooks/useVirtualHistory.ts +++ b/ui-tui/src/hooks/useVirtualHistory.ts @@ -37,9 +37,17 @@ export function useVirtualHistory( const heights = useRef(new Map()) const refs = useRef(new Map void>()) const [ver, setVer] = useState(0) + const [hasScrollRef, setHasScrollRef] = useState(false) + + useLayoutEffect(() => { + setHasScrollRef(Boolean(scrollRef.current)) + }, [scrollRef]) useSyncExternalStore( - useCallback((cb: () => void) => scrollRef.current?.subscribe(cb) ?? (() => () => {}), [scrollRef]), + useCallback( + (cb: () => void) => (hasScrollRef ? scrollRef.current?.subscribe(cb) : null) ?? (() => () => {}), + [hasScrollRef, scrollRef] + ), () => { const s = scrollRef.current