Files
orca/src/shared/runtime-mobile-session-tab-contracts.ts
53852c9ca4 feat(terminal): make the contrast floor user-configurable (#10754) (#18126)
* feat(terminal): make the contrast floor user-configurable (#10754)

The xterm minimumContrastRatio floor was hardcoded (3 on dark backgrounds,
4.5 on light) and applied to every pane with no way out, so TUIs that use
deliberately low contrast were rewritten: Powerline separators drawn in the
neighbouring segment's background became visible seams, and dimmed secondary
text lost its hierarchy.

Adds an optional `terminalMinimumContrastRatio` setting under Settings ->
Terminal -> Rendering. Blank keeps today's automatic, background-luminance
gated floor; 1 disables correction entirely (matching VS Code's documented
`terminal.integrated.minimumContrastRatio` and iTerm2's off-by-default
Minimum Contrast); values are clamped to xterm's 1-21 range.

The floor is resolved in one place, so live panes, the Appearance preview
and the dashboard terminal preview all follow it, and the existing
value-gated write still avoids clearing xterm's contrast cache on no-op
re-applies. The clamp also lives at the persistence boundary that every
writer crosses, so a hand-edited profile or CLI write can never hand xterm
a non-finite option. Mobile mirrors the desktop gate, so the resolved floor
travels with the terminal theme payload as a new optional field; hosts that
omit it leave older and newer clients on the luminance gate.

Fixes #10754.

Co-authored-by: Nyanako <44753291+Nanako0129@users.noreply.github.com>

* fix(terminal): refresh mobile payload fixture and clarify contrast target

* feat(terminal): make contrast controls intent-based with custom tuning

---------

Co-authored-by: Nyanako <44753291+Nanako0129@users.noreply.github.com>
Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-09-08 00:39:33 -07:00

123 lines
3.5 KiB
TypeScript

import type { AgentStatusEntry } from './agent-status-types'
import type { BrowserCertificateFailure, BrowserLoadError } from './browser-workspace-types'
import type { RuntimeBrowserPlacement } from './runtime-browser-placement'
import type { TerminalColorOverrides } from './terminal-color-overrides'
import type { TerminalLayoutSnapshot } from './terminal-tab-types'
import type { TuiAgent } from './tui-agent'
export type RuntimeMobileSessionTerminalTab = {
type: 'terminal'
id: string
title: string
quickCommandLabel?: string | null
parentTabId: string
leafId: string
ptyId?: string | null
/** Host-owned PTY incarnation used to fence remote identity observations. */
incarnationId?: string | null
terminalTheme?: RuntimeMobileTerminalTheme
agentStatus?: AgentStatusEntry | null
/** Event-only lead-turn end time for paired clients; never persisted in AgentStatusEntry. */
turnCompletedAt?: number
launchAgent?: TuiAgent
startupCwd?: string
parentLayout?: TerminalLayoutSnapshot
color?: string | null
isPinned?: boolean
viewMode?: 'terminal' | 'chat'
launchDraft?: string
launchDraftCreatedAt?: number
isActive: boolean
}
export type RuntimeMobileTerminalTheme = {
mode: 'dark' | 'light'
theme: TerminalColorOverrides
/** Optional desktop terminalMinimumContrastRatio override (#10754). Absent means the client picks
* its own background-luminance floor, which is what pre-#10754 clients always do. */
minimumContrastRatio?: number
}
export type RuntimeMobileSessionMarkdownTab = {
type: 'markdown'
id: string
title: string
filePath: string
relativePath: string
language: 'markdown'
mode: 'edit' | 'markdown-preview'
isDirty: boolean
isActive: boolean
sourceFileId: string
sourceFilePath: string
sourceRelativePath: string
documentVersion: string
color?: string | null
isPinned?: boolean
}
export type RuntimeMobileSessionFileTab = {
type: 'file'
id: string
title: string
filePath: string
relativePath: string
language: string
mode?: 'edit' | 'diff'
diffSource?: 'staged' | 'unstaged'
isDirty: boolean
color?: string | null
isPinned?: boolean
isActive: boolean
}
export type RuntimeMobileSessionBrowserTab = {
type: 'browser'
id: string
title: string
browserWorkspaceId: string
browserPageId: string | null
browserProfileId?: string
executionHostKey?: string
placement?: RuntimeBrowserPlacement
url: string
loading: boolean
canGoBack: boolean
canGoForward: boolean
loadError?: BrowserLoadError | null
certificateFailure?: BrowserCertificateFailure | null
color?: string | null
isPinned?: boolean
isActive: boolean
}
export type RuntimeMobileSessionAgentTab = {
type: 'agent-session'
id: string
title: string
sessionId: string
replacesSessionId?: string
agent: 'claude' | 'codex'
color?: string | null
isPinned?: boolean
isActive: boolean
}
export type RuntimeMobileSessionSnapshotTab =
| RuntimeMobileSessionTerminalTab
| RuntimeMobileSessionMarkdownTab
| RuntimeMobileSessionFileTab
| RuntimeMobileSessionBrowserTab
| RuntimeMobileSessionAgentTab
export type RuntimeMobileSessionTerminalClientTab =
| (RuntimeMobileSessionTerminalTab & { status: 'pending-handle'; terminal: null })
| (RuntimeMobileSessionTerminalTab & { status: 'ready'; terminal: string })
export type RuntimeMobileSessionClientTab =
| RuntimeMobileSessionTerminalClientTab
| RuntimeMobileSessionMarkdownTab
| RuntimeMobileSessionFileTab
| RuntimeMobileSessionBrowserTab
| RuntimeMobileSessionAgentTab