From 1a2eee0d637c98c36c4ddf3863e1175c33d3b8db Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Sat, 1 Aug 2026 00:06:42 -0500 Subject: [PATCH 1/2] feat(desktop): paint the integrated terminal with the transcript background MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The terminal borrowed --ui-editor-surface-background, the same token the preview pane, diff gutters, and pane tabs wear. Nothing could retint the terminal without moving all of them, and it was pinned to the editor surface rather than the conversation it sits beside. Give it --ui-terminal-surface-background, aliased to the chat surface, and point every layer that paints the terminal at it: the pane wrapper, the persistent overlay, the rail, the instance chrome, the xterm host, and the probe that feeds xterm's canvas. One knob, and a skin can now move the terminal alone. No visual change today — both tokens resolve to --ui-bg-chrome. The two xterm host divs carried an identical class string; hoist it to HOST_CLASS so the user terminal and the agent mirror can't drift again. --- apps/desktop/src/app/contrib/surfaces.tsx | 2 +- .../app/right-sidebar/terminal/instance.tsx | 18 +++++++++--------- .../app/right-sidebar/terminal/persistent.tsx | 2 +- .../src/app/right-sidebar/terminal/rail.tsx | 2 +- .../app/right-sidebar/terminal/selection.ts | 6 +++--- apps/desktop/src/styles.css | 6 ++++++ 6 files changed, 21 insertions(+), 15 deletions(-) diff --git a/apps/desktop/src/app/contrib/surfaces.tsx b/apps/desktop/src/app/contrib/surfaces.tsx index 2e40092ffc..750248fbfe 100644 --- a/apps/desktop/src/app/contrib/surfaces.tsx +++ b/apps/desktop/src/app/contrib/surfaces.tsx @@ -56,7 +56,7 @@ export const SidebarSurface = memo(function SidebarSurface({ export const TerminalSurface = memo(function TerminalSurface() { return ( -
+
) diff --git a/apps/desktop/src/app/right-sidebar/terminal/instance.tsx b/apps/desktop/src/app/right-sidebar/terminal/instance.tsx index 933916b640..9d81495642 100644 --- a/apps/desktop/src/app/right-sidebar/terminal/instance.tsx +++ b/apps/desktop/src/app/right-sidebar/terminal/instance.tsx @@ -12,7 +12,13 @@ import { useTerminalSession } from './use-terminal-session' // Absolute-stacked so inactive tabs keep layout size (a display:none host goes // 0×0 and renders garbled on re-show); visibility toggles which one is seen. -const INSTANCE_CLASS = 'absolute inset-0 flex flex-col bg-(--ui-editor-surface-background) px-2 pb-2 pt-0' +const INSTANCE_CLASS = 'absolute inset-0 flex flex-col bg-(--ui-terminal-surface-background) px-2 pb-2 pt-0' + +// xterm host. The screen/viewport overrides matter for the DOM renderer (the +// WebGL fast-path paints the canvas from ITheme.background instead) — both +// resolve to the same token, so the two renderers can't disagree. +const HOST_CLASS = + 'h-full min-h-0 overflow-hidden text-(--ui-text-secondary) [&_.xterm]:h-full [&_.xterm-screen]:bg-(--ui-terminal-surface-background)! [&_.xterm-viewport]:bg-(--ui-terminal-surface-background)!' interface TerminalInstanceProps { id: string @@ -81,10 +87,7 @@ export function TerminalInstance({ )} {/* Outer div paints the terminal inset; inner div is the xterm host so the canvas sizes to the content area and p-2 stays as terminal padding. */} -
+
) } @@ -107,10 +110,7 @@ export function AgentTerminalInstance({ active, id, procId }: AgentTerminalInsta // routes ⌘W here and closes the focused agent tab (not a preview). data-terminal="" > -
+
) } diff --git a/apps/desktop/src/app/right-sidebar/terminal/persistent.tsx b/apps/desktop/src/app/right-sidebar/terminal/persistent.tsx index 3fe2edb04a..b5e75978b0 100644 --- a/apps/desktop/src/app/right-sidebar/terminal/persistent.tsx +++ b/apps/desktop/src/app/right-sidebar/terminal/persistent.tsx @@ -207,7 +207,7 @@ export function PersistentTerminal({ onAddSelectionToChat }: PersistentTerminalP zIndex: 4, // Match the live skin surface so the header strip (transparent) and body // read as one cohesive pane instead of revealing a near-black slab behind. - backgroundColor: 'var(--ui-editor-surface-background)', + backgroundColor: 'var(--ui-terminal-surface-background)', contain: 'layout size paint' } diff --git a/apps/desktop/src/app/right-sidebar/terminal/rail.tsx b/apps/desktop/src/app/right-sidebar/terminal/rail.tsx index ced1675032..7b5aee0ffa 100644 --- a/apps/desktop/src/app/right-sidebar/terminal/rail.tsx +++ b/apps/desktop/src/app/right-sidebar/terminal/rail.tsx @@ -44,7 +44,7 @@ export function TerminalRail() { return (
Date: Sat, 1 Aug 2026 00:06:48 -0500 Subject: [PATCH 2/2] fix(desktop): stop the agent terminal falling back to a white background MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit useAgentTerminal hardcoded resolveSurfaceColor('#ffffff'), so any read that misses the surface token — a pre-paint mount — flashed a white slab in dark mode. The user terminal already passes the palette's own background; the agent mirror is a copy of it that lost that detail. Pass the same fallback, so both siblings degrade to their mode's surface. --- .../src/app/right-sidebar/terminal/use-agent-terminal.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/desktop/src/app/right-sidebar/terminal/use-agent-terminal.ts b/apps/desktop/src/app/right-sidebar/terminal/use-agent-terminal.ts index a8d92d9e36..f87840e95c 100644 --- a/apps/desktop/src/app/right-sidebar/terminal/use-agent-terminal.ts +++ b/apps/desktop/src/app/right-sidebar/terminal/use-agent-terminal.ts @@ -26,9 +26,13 @@ export function useAgentTerminal({ active, id, procId }: { active: boolean; id: const surfaceTheme = () => { const ansi = renderedMode === 'dark' ? (theme.darkTerminal ?? theme.terminal) : theme.terminal - const surface = resolveSurfaceColor('#ffffff') + const base = terminalTheme(renderedMode, ansi) + // Fall back to the palette's own background, not white — a hardcoded + // '#ffffff' flashes a white slab in dark mode whenever the probe can't read + // the token (pre-paint mount). Same contract as the user terminal. + const surface = resolveSurfaceColor(base.background ?? '#ffffff') - return { ...terminalTheme(renderedMode, ansi), background: surface, cursorAccent: surface } + return { ...base, background: surface, cursorAccent: surface } } // eslint-disable-next-line no-restricted-syntax -- legitimate non-atom ref write (see eslint rule comment)