Merge pull request #75869 from NousResearch/bb/terminal-theme-bg

Paint the integrated terminal with the transcript background
This commit is contained in:
brooklyn!
2026-08-01 00:16:09 -05:00
committed by GitHub
7 changed files with 27 additions and 17 deletions
+1 -1
View File
@@ -56,7 +56,7 @@ export const SidebarSurface = memo(function SidebarSurface({
export const TerminalSurface = memo(function TerminalSurface() {
return (
<div className="relative flex h-full min-h-0 flex-col overflow-hidden bg-(--ui-editor-surface-background)">
<div className="relative flex h-full min-h-0 flex-col overflow-hidden bg-(--ui-terminal-surface-background)">
<TerminalPaneChrome />
</div>
)
@@ -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. */}
<div
className="h-full min-h-0 overflow-hidden text-(--ui-text-secondary) [&_.xterm]:h-full [&_.xterm-screen]:bg-(--ui-editor-surface-background)! [&_.xterm-viewport]:bg-(--ui-editor-surface-background)!"
ref={hostRef}
/>
<div className={HOST_CLASS} ref={hostRef} />
</div>
)
}
@@ -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=""
>
<div
className="h-full min-h-0 overflow-hidden text-(--ui-text-secondary) [&_.xterm]:h-full [&_.xterm-screen]:bg-(--ui-editor-surface-background)! [&_.xterm-viewport]:bg-(--ui-editor-surface-background)!"
ref={hostRef}
/>
<div className={HOST_CLASS} ref={hostRef} />
</div>
)
}
@@ -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'
}
@@ -44,7 +44,7 @@ export function TerminalRail() {
return (
<div
className="group/rail relative z-40 flex h-full w-9 shrink-0 flex-col items-center border-l border-(--ui-stroke-quaternary) bg-(--ui-editor-surface-background)"
className="group/rail relative z-40 flex h-full w-9 shrink-0 flex-col items-center border-l border-(--ui-stroke-quaternary) bg-(--ui-terminal-surface-background)"
// The rail sits at the pane's outer edge, under the collapsed sidebars'
// hover-reveal triggers; mark it so those triggers go pointer-transparent
// while it's hovered (see the suppression rules in styles.css) and a reach
@@ -78,8 +78,8 @@ export function terminalTheme(mode: 'light' | 'dark', palette?: DesktopTerminalP
return overlay as ITheme
}
// Resolve --ui-editor-surface-background (a color-mix on the skin seed) to a
// concrete rgb for the WebGL renderer + contrast clamp. Custom props don't
// Resolve --ui-terminal-surface-background (a color-mix on the skin seed) to a
// concrete color for the WebGL renderer + contrast clamp. Custom props don't
// resolve via getComputedStyle, so probe a real background-color. Read AFTER
// applyTheme repaints (mount / rAF post-change) or it lags a frame behind.
export function resolveSurfaceColor(fallback: string): string {
@@ -89,7 +89,7 @@ export function resolveSurfaceColor(fallback: string): string {
const probe = document.createElement('span')
probe.style.cssText =
'position:absolute;visibility:hidden;pointer-events:none;background-color:var(--ui-editor-surface-background)'
'position:absolute;visibility:hidden;pointer-events:none;background-color:var(--ui-terminal-surface-background)'
document.body.appendChild(probe)
const resolved = getComputedStyle(probe).backgroundColor
probe.remove()
@@ -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)
+6
View File
@@ -327,6 +327,12 @@
--ui-sidebar-surface-background: var(--ui-bg-sidebar);
--ui-chat-surface-background: var(--ui-bg-chrome);
--ui-editor-surface-background: var(--ui-bg-chrome);
/* The integrated terminal wears the transcript's background, not the
editor's — it reads as part of the conversation surface. Its own token so
the two can diverge without dragging the terminal along, and so a skin
gets one knob for it. xterm's canvas can't use a var, so the probe in
terminal/selection.ts resolves this same name to a concrete rgb. */
--ui-terminal-surface-background: var(--ui-chat-surface-background);
/* Inline chat widgets (clarify, artifact card) — the card fill in light
mode, nudged down in dark so a widget settles into the transcript
instead of glowing above it (see the `.dark` override). */