From 38acced6873d63086d415625a9d04fb0240cd63e Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Thu, 4 Jun 2026 00:22:17 -0500 Subject: [PATCH] style(desktop): satisfy lint across PR-touched files --- apps/desktop/src/app/chat/composer/index.tsx | 1 + apps/desktop/src/app/chat/index.tsx | 3 +++ apps/desktop/src/app/session/hooks/use-message-stream.ts | 1 + apps/desktop/src/app/session/hooks/use-session-state-cache.ts | 2 ++ apps/desktop/src/app/settings/toolset-config-panel.tsx | 1 + apps/desktop/src/app/shell/app-shell.tsx | 1 + apps/desktop/src/components/chat/intro.tsx | 1 + apps/desktop/src/components/desktop-onboarding-overlay.tsx | 2 ++ apps/desktop/src/store/session.ts | 2 ++ 9 files changed, 14 insertions(+) diff --git a/apps/desktop/src/app/chat/composer/index.tsx b/apps/desktop/src/app/chat/composer/index.tsx index f55e3c115..069dc490f 100644 --- a/apps/desktop/src/app/chat/composer/index.tsx +++ b/apps/desktop/src/app/chat/composer/index.tsx @@ -196,6 +196,7 @@ export function ChatBar({ const [restingPlaceholder, setRestingPlaceholder] = useState(() => pickPlaceholder(sessionId ? FOLLOW_UP_PLACEHOLDERS : NEW_SESSION_PLACEHOLDERS) ) + const prevSessionIdRef = useRef(sessionId) useEffect(() => { diff --git a/apps/desktop/src/app/chat/index.tsx b/apps/desktop/src/app/chat/index.tsx index 7630bb733..38c2cff07 100644 --- a/apps/desktop/src/app/chat/index.tsx +++ b/apps/desktop/src/app/chat/index.tsx @@ -98,9 +98,12 @@ function ChatHeader({ }: ChatHeaderProps) { const sessions = useStore($sessions) const pinnedSessionIds = useStore($pinnedSessionIds) + const activeStoredSession = sessions.find(session => session.id === selectedSessionId || session._lineage_root_id === selectedSessionId) || null + const title = activeStoredSession ? sessionTitle(activeStoredSession) : 'New session' + // Pins live on the durable lineage-root id, but selectedSessionId is the live // (tip) id — resolve through the loaded row so the menu reflects the pin // state after auto-compression rotates the id. diff --git a/apps/desktop/src/app/session/hooks/use-message-stream.ts b/apps/desktop/src/app/session/hooks/use-message-stream.ts index e4c49b840..1763e5eb2 100644 --- a/apps/desktop/src/app/session/hooks/use-message-stream.ts +++ b/apps/desktop/src/app/session/hooks/use-message-stream.ts @@ -313,6 +313,7 @@ export function useMessageStream({ // commit and the synthetic harness shows longtask counts drop from ~5/5s // to ~1/5s on big sessions (see scripts/profile-typing-lag.md). const sinceLast = performance.now() - lastFlushAtRef.current + const runFlush = () => { flushHandleRef.current = null lastFlushAtRef.current = performance.now() diff --git a/apps/desktop/src/app/session/hooks/use-session-state-cache.ts b/apps/desktop/src/app/session/hooks/use-session-state-cache.ts index adb4f362e..0a6829482 100644 --- a/apps/desktop/src/app/session/hooks/use-session-state-cache.ts +++ b/apps/desktop/src/app/session/hooks/use-session-state-cache.ts @@ -158,6 +158,7 @@ export function useSessionStateCache({ setSessionWorking(next.storedSessionId, next.busy) setSessionAttention(next.storedSessionId, next.needsInput) + // Every state update is effectively a "still alive" heartbeat for // streaming events. The session-store watchdog uses this to keep the // working flag alive during long-running turns and to clear it once @@ -165,6 +166,7 @@ export function useSessionStateCache({ if (next.busy) { noteSessionActivity(next.storedSessionId) } + syncSessionStateToView(sessionId, next) return next diff --git a/apps/desktop/src/app/settings/toolset-config-panel.tsx b/apps/desktop/src/app/settings/toolset-config-panel.tsx index 4ca4f53a5..ece09e53e 100644 --- a/apps/desktop/src/app/settings/toolset-config-panel.tsx +++ b/apps/desktop/src/app/settings/toolset-config-panel.tsx @@ -211,6 +211,7 @@ export function ToolsetConfigPanel({ toolset, onConfiguredChange }: ToolsetConfi (cfg?.active_provider ? providers.find(p => p.name === cfg.active_provider) : undefined) ?? providers.find(p => providerConfigured(p, envState)) ?? providers[0] + setActiveProvider(selected.name) }, [activeProvider, providers, envState, cfg]) diff --git a/apps/desktop/src/app/shell/app-shell.tsx b/apps/desktop/src/app/shell/app-shell.tsx index 8455666a9..e9e4b90ef 100644 --- a/apps/desktop/src/app/shell/app-shell.tsx +++ b/apps/desktop/src/app/shell/app-shell.tsx @@ -71,6 +71,7 @@ export function AppShell({ // window's left edge. Default layout: the sessions sidebar sits there. // Flipped layout: the file browser does instead. const leftEdgePaneOpen = panesFlipped ? fileBrowserOpen : sidebarOpen + const titlebarContentInset = leftEdgePaneOpen ? 0 : titlebarControls.left + TITLEBAR_HEIGHT + Math.round(TITLEBAR_HEIGHT / 2) diff --git a/apps/desktop/src/components/chat/intro.tsx b/apps/desktop/src/components/chat/intro.tsx index d5ec61b0b..e942f55ff 100644 --- a/apps/desktop/src/components/chat/intro.tsx +++ b/apps/desktop/src/components/chat/intro.tsx @@ -157,6 +157,7 @@ function resolveCopy(personality?: string, seed?: number): IntroCopy { export function Intro({ personality, seed }: IntroProps) { const [mountSeed] = useState(() => Math.floor(Math.random() * 100000)) const copy = resolveCopy(personality, mountSeed + (seed ?? 0)) + return (
getGlobalModelOptions() }) + const providerRow = options.data?.providers?.find( p => String(p.slug).toLowerCase() === flow.providerSlug.toLowerCase() ) + const price = providerRow?.pricing?.[flow.currentModel] const freeTier = providerRow?.free_tier diff --git a/apps/desktop/src/store/session.ts b/apps/desktop/src/store/session.ts index 1d3197891..8106b002f 100644 --- a/apps/desktop/src/store/session.ts +++ b/apps/desktop/src/store/session.ts @@ -62,6 +62,7 @@ export function mergeSessionPage( } const incomingIds = new Set(incoming.map(session => session.id)) + const survivors = previous.filter( session => !incomingIds.has(session.id) && @@ -164,6 +165,7 @@ function armSessionWatchdog(sessionId: string) { const timer = setTimeout(() => { sessionWatchdogTimers.delete(sessionId) + // Re-check the latest state at fire-time. If the user already navigated // away or the session genuinely finished, the timer is a no-op. if ($workingSessionIds.get().includes(sessionId)) {