@greppleai/grip-tui 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/autocomplete.d.ts +1 -1
- package/dist/autocomplete.d.ts.map +1 -1
- package/dist/autocomplete.js +0 -3
- package/dist/autocomplete.js.map +1 -1
- package/dist/components/alt-screen-flash.d.ts.map +1 -1
- package/dist/components/alt-screen-flash.js +2 -3
- package/dist/components/alt-screen-flash.js.map +1 -1
- package/dist/components/box.d.ts.map +1 -1
- package/dist/components/box.js +1 -6
- package/dist/components/box.js.map +1 -1
- package/dist/components/cancellable-loader.d.ts.map +1 -1
- package/dist/components/cancellable-loader.js +4 -3
- package/dist/components/cancellable-loader.js.map +1 -1
- package/dist/components/editor.d.ts +1 -0
- package/dist/components/editor.d.ts.map +1 -1
- package/dist/components/editor.js +51 -54
- package/dist/components/editor.js.map +1 -1
- package/dist/components/h-stack.d.ts.map +1 -1
- package/dist/components/h-stack.js +1 -1
- package/dist/components/h-stack.js.map +1 -1
- package/dist/components/image.d.ts.map +1 -1
- package/dist/components/image.js +0 -8
- package/dist/components/image.js.map +1 -1
- package/dist/components/input.d.ts.map +1 -1
- package/dist/components/input.js +14 -14
- package/dist/components/input.js.map +1 -1
- package/dist/components/loader.d.ts.map +1 -1
- package/dist/components/loader.js +8 -10
- package/dist/components/loader.js.map +1 -1
- package/dist/components/markdown.d.ts.map +1 -1
- package/dist/components/markdown.js +0 -11
- package/dist/components/markdown.js.map +1 -1
- package/dist/components/scroll-view.d.ts.map +1 -1
- package/dist/components/scroll-view.js +5 -15
- package/dist/components/scroll-view.js.map +1 -1
- package/dist/components/select-list.d.ts.map +1 -1
- package/dist/components/select-list.js +4 -9
- package/dist/components/select-list.js.map +1 -1
- package/dist/components/settings-list.d.ts.map +1 -1
- package/dist/components/settings-list.js +4 -12
- package/dist/components/settings-list.js.map +1 -1
- package/dist/components/spacer.d.ts.map +1 -1
- package/dist/components/spacer.js +0 -1
- package/dist/components/spacer.js.map +1 -1
- package/dist/components/stack.d.ts.map +1 -1
- package/dist/components/stack.js +1 -3
- package/dist/components/stack.js.map +1 -1
- package/dist/components/text.d.ts.map +1 -1
- package/dist/components/text.js +0 -8
- package/dist/components/text.js.map +1 -1
- package/dist/components/truncated-text.d.ts.map +1 -1
- package/dist/components/truncated-text.js +0 -3
- package/dist/components/truncated-text.js.map +1 -1
- package/dist/components/v-stack.d.ts.map +1 -1
- package/dist/components/v-stack.js +1 -1
- package/dist/components/v-stack.js.map +1 -1
- package/dist/editor-component.d.ts.map +1 -1
- package/dist/fuzzy.d.ts.map +1 -1
- package/dist/fuzzy.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/keybindings.d.ts.map +1 -1
- package/dist/keybindings.js +2 -4
- package/dist/keybindings.js.map +1 -1
- package/dist/keys.d.ts.map +1 -1
- package/dist/keys.js.map +1 -1
- package/dist/kill-ring.d.ts.map +1 -1
- package/dist/kill-ring.js +3 -1
- package/dist/kill-ring.js.map +1 -1
- package/dist/latex.d.ts.map +1 -1
- package/dist/latex.js +3 -7
- package/dist/latex.js.map +1 -1
- package/dist/layout-node.d.ts.map +1 -1
- package/dist/layout-node.js.map +1 -1
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js.map +1 -1
- package/dist/native-modifiers.d.ts.map +1 -1
- package/dist/native-modifiers.js.map +1 -1
- package/dist/stdin-buffer.d.ts.map +1 -1
- package/dist/stdin-buffer.js +4 -6
- package/dist/stdin-buffer.js.map +1 -1
- package/dist/terminal-control.d.ts.map +1 -1
- package/dist/terminal-control.js.map +1 -1
- package/dist/terminal-image.d.ts.map +1 -1
- package/dist/terminal-image.js.map +1 -1
- package/dist/terminal.d.ts.map +1 -1
- package/dist/terminal.js +25 -30
- package/dist/terminal.js.map +1 -1
- package/dist/tui-alt-screen.d.ts.map +1 -1
- package/dist/tui-alt-screen.js +15 -32
- package/dist/tui-alt-screen.js.map +1 -1
- package/dist/tui-main-screen.d.ts.map +1 -1
- package/dist/tui-main-screen.js +12 -9
- package/dist/tui-main-screen.js.map +1 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +17 -20
- package/dist/tui.js.map +1 -1
- package/dist/undo-stack.d.ts.map +1 -1
- package/dist/undo-stack.js +3 -1
- package/dist/undo-stack.js.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +14 -12
- package/dist/utils.js.map +1 -1
- package/dist/word-navigation.d.ts.map +1 -1
- package/dist/word-navigation.js.map +1 -1
- package/package.json +7 -7
package/dist/tui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui.js","sourceRoot":"","sources":["../src/tui.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Minimal TUI implementation with differential rendering\n */\n\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport { isKeyRelease, matchesKey } from \"./keys.ts\";\nimport type { Terminal } from \"./terminal.ts\";\nimport { getCapabilities, isImageLine, setCellDimensions } from \"./terminal-image.ts\";\nimport { extractSegments, normalizeTerminalOutput, sliceByColumn, sliceWithWidth, visibleWidth } from \"./utils.ts\";\n\n/**\n * Component interface - all components must implement this\n */\nexport interface Component {\n\t/**\n\t * Render the component to lines for the given viewport width\n\t * @param width - Current viewport width\n\t * @returns Array of strings, each representing a line\n\t */\n\trender(width: number): string[];\n\n\t/**\n\t * Optional handler for keyboard input when component has focus\n\t */\n\thandleInput?(data: string): void;\n\n\t/**\n\t * If true, component receives key release events (Kitty protocol).\n\t * Default is false - release events are filtered out.\n\t */\n\twantsKeyRelease?: boolean;\n\n\t/**\n\t * Invalidate any cached rendering state.\n\t * Called when theme changes or when component needs to re-render from scratch.\n\t */\n\tinvalidate(): void;\n}\n\nexport type TuiInputListenerResult = { consume?: boolean; data?: string } | undefined;\nexport type TuiInputListener = (data: string) => TuiInputListenerResult;\n\n/**\n * Interface for components that can receive focus and display a hardware cursor.\n * When focused, the component should emit CURSOR_MARKER at the cursor position\n * in its render output. TUI will find this marker and position the hardware\n * cursor there for proper IME candidate window positioning.\n */\nexport interface Focusable {\n\t/** Set by TUI when focus changes. Component should emit CURSOR_MARKER when true. */\n\tfocused: boolean;\n}\n\n/** Type guard to check if a component implements Focusable */\nexport function isFocusable(component: Component | null): component is Component & Focusable {\n\treturn component !== null && \"focused\" in component;\n}\n\n/**\n * Cursor position marker - APC (Application Program Command) sequence.\n * This is a zero-width escape sequence that terminals ignore.\n * Components emit this at the cursor position when focused.\n * TUI finds and strips this marker, then positions the hardware cursor there.\n */\nexport const CURSOR_MARKER = \"\\x1b_pi:c\\x07\";\n\nexport { visibleWidth };\n\n/**\n * Anchor position for overlays\n */\nexport type OverlayAnchor =\n\t| \"center\"\n\t| \"top-left\"\n\t| \"top-right\"\n\t| \"bottom-left\"\n\t| \"bottom-right\"\n\t| \"top-center\"\n\t| \"bottom-center\"\n\t| \"left-center\"\n\t| \"right-center\";\n\n/**\n * Margin configuration for overlays\n */\nexport interface OverlayMargin {\n\ttop?: number;\n\tright?: number;\n\tbottom?: number;\n\tleft?: number;\n}\n\n/** Value that can be absolute (number) or percentage (string like \"50%\") */\nexport type SizeValue = number | `${number}%`;\n\n/** Parse a SizeValue into absolute value given a reference size */\nfunction parseSizeValue(value: SizeValue | undefined, referenceSize: number): number | undefined {\n\tif (value === undefined) return undefined;\n\tif (typeof value === \"number\") return value;\n\t// Parse percentage string like \"50%\"\n\tconst match = value.match(/^(\\d+(?:\\.\\d+)?)%$/);\n\tif (match) {\n\t\treturn Math.floor((referenceSize * parseFloat(match[1])) / 100);\n\t}\n\treturn undefined;\n}\n\n/**\n * Options for overlay positioning and sizing.\n * Values can be absolute numbers or percentage strings (e.g., \"50%\").\n */\nexport interface OverlayOptions {\n\t// === Sizing ===\n\t/** Width in columns, or percentage of terminal width (e.g., \"50%\") */\n\twidth?: SizeValue;\n\t/** Minimum width in columns */\n\tminWidth?: number;\n\t/** Maximum height in rows, or percentage of terminal height (e.g., \"50%\") */\n\tmaxHeight?: SizeValue;\n\n\t// === Positioning - anchor-based ===\n\t/** Anchor point for positioning (default: 'center') */\n\tanchor?: OverlayAnchor;\n\t/** Horizontal offset from anchor position (positive = right) */\n\toffsetX?: number;\n\t/** Vertical offset from anchor position (positive = down) */\n\toffsetY?: number;\n\n\t// === Positioning - percentage or absolute ===\n\t/** Row position: absolute number, or percentage (e.g., \"25%\" = 25% from top) */\n\trow?: SizeValue;\n\t/** Column position: absolute number, or percentage (e.g., \"50%\" = centered horizontally) */\n\tcol?: SizeValue;\n\n\t// === Margin from terminal edges ===\n\t/** Margin from terminal edges. Number applies to all sides. */\n\tmargin?: OverlayMargin | number;\n\n\t// === Visibility ===\n\t/**\n\t * Control overlay visibility based on terminal dimensions.\n\t * If provided, overlay is only rendered when this returns true.\n\t * Called each render cycle with current terminal dimensions.\n\t */\n\tvisible?: (termWidth: number, termHeight: number) => boolean;\n\t/** If true, don't capture keyboard focus when shown */\n\tnonCapturing?: boolean;\n}\n\n/** Options for {@link OverlayHandle.unfocus}. */\nexport interface OverlayUnfocusOptions {\n\t/** Explicit target to focus after releasing this overlay. */\n\ttarget: Component | null;\n}\n\n/**\n * Handle returned by showOverlay for controlling the overlay\n */\nexport interface OverlayHandle {\n\t/** Permanently remove the overlay (cannot be shown again) */\n\thide(): void;\n\t/** Temporarily hide or show the overlay */\n\tsetHidden(hidden: boolean): void;\n\t/** Check if overlay is temporarily hidden */\n\tisHidden(): boolean;\n\t/** Focus this overlay and bring it to the visual front */\n\tfocus(): void;\n\t/** Release focus to the next visible capturing overlay or previous target, or to an explicit target when provided */\n\tunfocus(options?: OverlayUnfocusOptions): void;\n\t/** Check if this overlay currently has focus */\n\tisFocused(): boolean;\n}\n\ntype OverlayStackEntry = {\n\tcomponent: Component;\n\toptions?: OverlayOptions;\n\tpreFocus: Component | null;\n\thidden: boolean;\n\tfocusOrder: number;\n\tvisible: boolean;\n};\n\ntype OverlayBlockedFocusResume = { status: \"restore-overlay\" } | { status: \"focus-target\"; target: Component | null };\ntype EligibleOverlayFocusRestoreState = { status: \"eligible\"; overlay: OverlayStackEntry };\ntype BlockedOverlayFocusRestoreState = {\n\tstatus: \"blocked\";\n\toverlay: OverlayStackEntry;\n\tblockedBy: Component;\n\tresume: OverlayBlockedFocusResume;\n};\ntype ActiveOverlayFocusRestoreState = EligibleOverlayFocusRestoreState | BlockedOverlayFocusRestoreState;\ntype OverlayFocusRestoreState = { status: \"inactive\" } | ActiveOverlayFocusRestoreState;\ntype OverlayFocusRestorePolicy = \"clear\" | \"preserve\";\n\ninterface FocusTransitionRequest {\n\tcomponent: Component | null;\n\toverlayFocusRestore: OverlayFocusRestorePolicy;\n}\n\ninterface ResolvedOverlayLayout {\n\twidth: number;\n\trow: number;\n\tcol: number;\n\tmaxHeight: number | undefined;\n}\n\ninterface RenderedOverlay {\n\tlines: string[];\n\trow: number;\n\tcol: number;\n\twidth: number;\n}\n\ninterface OverlayRenderPlan {\n\toverlays: RenderedOverlay[];\n\tminimumLineCount: number;\n}\n\ninterface OverlayLayoutBounds {\n\tmarginTop: number;\n\tmarginRight: number;\n\tmarginBottom: number;\n\tmarginLeft: number;\n\tavailableWidth: number;\n\tavailableHeight: number;\n}\n\nexport interface RenderedCursorPosition {\n\trow: number;\n\tcol: number;\n}\n/**\n * Container - a component that contains other components\n */\nexport class Container implements Component {\n\tchildren: Component[] = [];\n\n\taddChild(component: Component): void {\n\t\tthis.children.push(component);\n\t}\n\n\tremoveChild(component: Component): void {\n\t\tconst index = this.children.indexOf(component);\n\t\tif (index !== -1) {\n\t\t\tthis.children.splice(index, 1);\n\t\t}\n\t}\n\n\tclear(): void {\n\t\tthis.children = [];\n\t}\n\n\tinvalidate(): void {\n\t\tfor (const child of this.children) {\n\t\t\tchild.invalidate?.();\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tfor (const child of this.children) {\n\t\t\tconst childLines = child.render(width);\n\t\t\tfor (const line of childLines) {\n\t\t\t\tlines.push(line);\n\t\t\t}\n\t\t}\n\t\treturn lines;\n\t}\n}\n\n/**\n * TUI - Main class for managing terminal UI with differential rendering\n */\nconst SEGMENT_RESET = \"\\x1b[0m\\x1b]8;;\\x07\";\n\n/** Composite overlay content into a terminal line at a fixed column. */\nexport function compositeTuiLine(\n\tbaseLine: string,\n\toverlayLine: string,\n\tstartCol: number,\n\toverlayWidth: number,\n\ttotalWidth: number,\n): string {\n\tif (isImageLine(baseLine)) return baseLine;\n\n\tconst afterStart = startCol + overlayWidth;\n\tconst base = extractSegments(baseLine, startCol, afterStart, totalWidth - afterStart, true);\n\tconst overlay = sliceWithWidth(overlayLine, 0, overlayWidth, true);\n\tconst beforePad = Math.max(0, startCol - base.beforeWidth);\n\tconst overlayPad = Math.max(0, overlayWidth - overlay.width);\n\tconst actualBeforeWidth = Math.max(startCol, base.beforeWidth);\n\tconst actualOverlayWidth = Math.max(overlayWidth, overlay.width);\n\tconst afterTarget = Math.max(0, totalWidth - actualBeforeWidth - actualOverlayWidth);\n\tconst afterPad = Math.max(0, afterTarget - base.afterWidth);\n\tconst result =\n\t\tbase.before +\n\t\t\" \".repeat(beforePad) +\n\t\tSEGMENT_RESET +\n\t\toverlay.text +\n\t\t\" \".repeat(overlayPad) +\n\t\tSEGMENT_RESET +\n\t\tbase.after +\n\t\t\" \".repeat(afterPad);\n\n\treturn visibleWidth(result) <= totalWidth ? result : sliceByColumn(result, 0, totalWidth, true);\n}\n\nexport type TuiMode = \"regular\" | \"fullscreen\";\n\nexport interface TuiStopOptions {\n\t/** Restore the previous main buffer without replaying renderer content. */\n\tpreserveScreen?: boolean;\n}\n\nexport interface TUI extends Component {\n\treadonly mode: TuiMode;\n\tchildren: Component[];\n\tterminal: Terminal;\n\tonDebug?: () => void;\n\treadonly fullRedraws: number;\n\treadonly hasOverlayEntries: boolean;\n\taddChild(component: Component): void;\n\tremoveChild(component: Component): void;\n\tclear(): void;\n\tgetShowHardwareCursor(): boolean;\n\tsetShowHardwareCursor(enabled: boolean): void;\n\tgetClearOnShrink(): boolean;\n\tsetClearOnShrink(enabled: boolean): void;\n\tgetFocusedComponent(): Component | null;\n\tsetFocus(component: Component | null): void;\n\tshowOverlay(component: Component, options?: OverlayOptions): OverlayHandle;\n\thideOverlay(): void;\n\thasOverlay(): boolean;\n\tstart(): void;\n\tstop(options?: TuiStopOptions): void;\n\trenderNow(force?: boolean): void;\n\trequestRender(force?: boolean): void;\n\taddInputListener(listener: TuiInputListener): () => void;\n\tremoveInputListener(listener: TuiInputListener): void;\n}\n\nexport const VIEWPORT_TUI = Symbol.for(\"@greppleai/grip-tui/viewport\");\n\nexport interface ViewportTUI extends TUI {\n\treadonly [VIEWPORT_TUI]: true;\n\tsetLayoutRoot(component: Component | undefined): void;\n}\n\nexport function isViewportTUI(tui: TUI): tui is ViewportTUI {\n\treturn (tui as Partial<ViewportTUI>)[VIEWPORT_TUI] === true;\n}\n\nexport abstract class TuiBase extends Container implements TUI {\n\tabstract readonly mode: TuiMode;\n\tpublic terminal: Terminal;\n\tprivate focusedComponent: Component | null = null;\n\tprivate inputListeners = new Set<TuiInputListener>();\n\n\t/** Global callback for debug key (Shift+Ctrl+D). Called before input is forwarded to focused component. */\n\tpublic onDebug?: () => void;\n\tprivate renderRequested = false;\n\tprivate immediateRenderScheduled = false;\n\tprivate renderTimer: NodeJS.Timeout | undefined;\n\tprivate lastRenderAt = 0;\n\tprivate static readonly MIN_RENDER_INTERVAL_MS = 16;\n\tprivate showHardwareCursor = process.env.GRIP_HARDWARE_CURSOR === \"1\";\n\tprivate clearOnShrink = process.env.GRIP_CLEAR_ON_SHRINK === \"1\";\n\tprotected fullRedrawCount = 0;\n\tprotected stopped = false;\n\tprotected readonly logDirectory: string;\n\n\t// Overlay stack for modal components rendered on top of base content\n\tprivate focusOrderCounter = 0;\n\tprivate overlayStack: OverlayStackEntry[] = [];\n\n\tget hasOverlayEntries(): boolean {\n\t\treturn this.overlayStack.length > 0;\n\t}\n\tprivate overlayFocusRestore: OverlayFocusRestoreState = { status: \"inactive\" };\n\n\tconstructor(terminal: Terminal, showHardwareCursor?: boolean, logDirectory?: string) {\n\t\tsuper();\n\t\tthis.terminal = terminal;\n\t\tthis.logDirectory =\n\t\t\tlogDirectory ?? process.env.GRIP_CODING_AGENT_DIR ?? path.join(os.homedir(), \".grip\", \"agent\");\n\t\tif (showHardwareCursor !== undefined) {\n\t\t\tthis.showHardwareCursor = showHardwareCursor;\n\t\t}\n\t}\n\n\tprotected abstract doRender(): void;\n\n\tprotected resetRenderState(): void {}\n\n\tprotected beforeTerminalStart(): void {}\n\n\tprotected afterTerminalStart(): void {}\n\n\tprotected onTerminalResize(): void {}\n\n\tprotected onOverlayStackChanged(): void {}\n\n\tprotected beforeTerminalStop(_options?: TuiStopOptions): void {}\n\n\tprotected afterTerminalStop(_options?: TuiStopOptions): void {}\n\n\tget fullRedraws(): number {\n\t\treturn this.fullRedrawCount;\n\t}\n\n\tgetShowHardwareCursor(): boolean {\n\t\treturn this.showHardwareCursor;\n\t}\n\n\tsetShowHardwareCursor(enabled: boolean): void {\n\t\tif (this.showHardwareCursor === enabled) return;\n\t\tthis.showHardwareCursor = enabled;\n\t\tif (!enabled) {\n\t\t\tthis.terminal.hideCursor();\n\t\t}\n\t\tthis.requestRender();\n\t}\n\n\tgetClearOnShrink(): boolean {\n\t\treturn this.clearOnShrink;\n\t}\n\n\t/**\n\t * Set whether to trigger full re-render when content shrinks.\n\t * When true (default), empty rows are cleared when content shrinks.\n\t * When false, empty rows remain (reduces redraws on slower terminals).\n\t */\n\tsetClearOnShrink(enabled: boolean): void {\n\t\tthis.clearOnShrink = enabled;\n\t}\n\n\tgetFocusedComponent(): Component | null {\n\t\treturn this.focusedComponent;\n\t}\n\n\tsetFocus(component: Component | null): void {\n\t\tthis.setFocusInternal({ component, overlayFocusRestore: \"clear\" });\n\t}\n\n\tprivate resolveNonOverlayFocus(\n\t\tnextFocus: Component,\n\t\tpreviousFocus: Component | null,\n\t\trestoreState: OverlayFocusRestoreState,\n\t): Component | null {\n\t\tif (restoreState.status === \"blocked\" && restoreState.blockedBy === previousFocus) {\n\t\t\tif (restoreState.resume.status === \"focus-target\" || !this.isComponentMounted(restoreState.blockedBy)) {\n\t\t\t\treturn this.resolveBlockedOverlayFocusResume(restoreState);\n\t\t\t}\n\t\t\tthis.overlayFocusRestore = {\n\t\t\t\tstatus: \"blocked\",\n\t\t\t\toverlay: restoreState.overlay,\n\t\t\t\tblockedBy: nextFocus,\n\t\t\t\tresume: restoreState.resume,\n\t\t\t};\n\t\t\treturn nextFocus;\n\t\t}\n\n\t\tconst previousFocusedOverlay = previousFocus\n\t\t\t? this.overlayStack.find((entry) => entry.component === previousFocus && this.isOverlayVisible(entry))\n\t\t\t: undefined;\n\t\tif (\n\t\t\tpreviousFocusedOverlay &&\n\t\t\trestoreState.status !== \"inactive\" &&\n\t\t\trestoreState.overlay === previousFocusedOverlay &&\n\t\t\t!this.isOverlayFocusAncestor(previousFocusedOverlay, nextFocus)\n\t\t) {\n\t\t\tthis.overlayFocusRestore = {\n\t\t\t\tstatus: \"blocked\",\n\t\t\t\toverlay: previousFocusedOverlay,\n\t\t\t\tblockedBy: nextFocus,\n\t\t\t\tresume: { status: \"restore-overlay\" },\n\t\t\t};\n\t\t}\n\t\treturn nextFocus;\n\t}\n\n\tprivate resolveNullFocus(\n\t\tpreviousFocus: Component | null,\n\t\trestoreState: OverlayFocusRestoreState,\n\t\toverlayFocusRestore: OverlayFocusRestorePolicy,\n\t): Component | null {\n\t\tif (restoreState.status === \"blocked\" && restoreState.blockedBy === previousFocus) {\n\t\t\treturn this.resolveBlockedOverlayFocusResume(restoreState);\n\t\t}\n\t\tif (overlayFocusRestore === \"clear\") this.clearOverlayFocusRestore();\n\t\treturn null;\n\t}\n\n\tprivate resolveFocusTarget(\n\t\tcomponent: Component | null,\n\t\toverlayFocusRestore: OverlayFocusRestorePolicy,\n\t): Component | null {\n\t\tconst previousFocus = this.focusedComponent;\n\t\tconst restoreState = this.getVisibleOverlayFocusRestore();\n\t\tif (component === null) return this.resolveNullFocus(previousFocus, restoreState, overlayFocusRestore);\n\t\tconst isOverlay = this.overlayStack.some((entry) => entry.component === component);\n\t\tif (isOverlay) return component;\n\t\treturn this.resolveNonOverlayFocus(component, previousFocus, restoreState);\n\t}\n\n\tprivate applyFocus(nextFocus: Component | null): void {\n\t\tif (isFocusable(this.focusedComponent)) this.focusedComponent.focused = false;\n\t\tthis.focusedComponent = nextFocus;\n\t\tif (isFocusable(nextFocus)) nextFocus.focused = true;\n\n\t\tconst focusedOverlay = nextFocus\n\t\t\t? this.overlayStack.find((entry) => entry.component === nextFocus && this.isOverlayVisible(entry))\n\t\t\t: undefined;\n\t\tif (focusedOverlay) this.overlayFocusRestore = { status: \"eligible\", overlay: focusedOverlay };\n\t}\n\n\tprivate setFocusInternal({ component, overlayFocusRestore }: FocusTransitionRequest): void {\n\t\tconst nextFocus = this.resolveFocusTarget(component, overlayFocusRestore);\n\t\tthis.applyFocus(nextFocus);\n\t}\n\n\tprivate clearOverlayFocusRestore(): void {\n\t\tthis.overlayFocusRestore = { status: \"inactive\" };\n\t}\n\n\tprivate clearOverlayFocusRestoreFor(overlay: OverlayStackEntry): void {\n\t\tif (this.overlayFocusRestore.status !== \"inactive\" && this.overlayFocusRestore.overlay === overlay) {\n\t\t\tthis.clearOverlayFocusRestore();\n\t\t}\n\t}\n\n\tprivate resolveBlockedOverlayFocusResume(restoreState: BlockedOverlayFocusRestoreState): Component | null {\n\t\tif (restoreState.resume.status === \"restore-overlay\") return restoreState.overlay.component;\n\t\tthis.clearOverlayFocusRestore();\n\t\treturn restoreState.resume.target;\n\t}\n\n\tprivate getVisibleOverlayFocusRestore(): OverlayFocusRestoreState {\n\t\tconst restoreState = this.overlayFocusRestore;\n\t\tif (restoreState.status === \"inactive\") return restoreState;\n\t\tif (!this.overlayStack.includes(restoreState.overlay) || !this.isOverlayVisible(restoreState.overlay)) {\n\t\t\treturn { status: \"inactive\" };\n\t\t}\n\t\treturn restoreState;\n\t}\n\n\tprivate isOverlayFocusAncestor(entry: OverlayStackEntry, component: Component): boolean {\n\t\tconst preFocusByComponent = new Map<Component, Component | null>();\n\t\tfor (const overlay of this.overlayStack) {\n\t\t\tif (!preFocusByComponent.has(overlay.component)) {\n\t\t\t\tpreFocusByComponent.set(overlay.component, overlay.preFocus);\n\t\t\t}\n\t\t}\n\n\t\tconst visited = new Set<Component>();\n\t\tlet current = entry.preFocus;\n\t\twhile (current && !visited.has(current)) {\n\t\t\tvisited.add(current);\n\t\t\tif (current === component) return true;\n\t\t\tcurrent = preFocusByComponent.get(current) ?? null;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate retargetOverlayPreFocus(removed: OverlayStackEntry): void {\n\t\tfor (const overlay of this.overlayStack) {\n\t\t\tif (overlay !== removed && overlay.preFocus === removed.component) {\n\t\t\t\toverlay.preFocus = removed.preFocus;\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected getMountedRoots(): readonly Component[] {\n\t\treturn this.children;\n\t}\n\n\tprivate isComponentMounted(component: Component): boolean {\n\t\treturn this.getMountedRoots().some((child) => this.containsComponent(child, component));\n\t}\n\n\tprivate containsComponent(root: Component, target: Component): boolean {\n\t\tif (root === target) return true;\n\t\tif (!(root instanceof Container)) return false;\n\t\treturn root.children.some((child) => this.containsComponent(child, target));\n\t}\n\n\tprivate applyBlockedOverlayUnfocus(\n\t\tentry: OverlayStackEntry,\n\t\trestoreState: OverlayFocusRestoreState,\n\t\toptions: OverlayUnfocusOptions | undefined,\n\t): boolean {\n\t\tif (\n\t\t\trestoreState.status !== \"blocked\" ||\n\t\t\trestoreState.overlay !== entry ||\n\t\t\tthis.focusedComponent !== restoreState.blockedBy\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tif (options) {\n\t\t\tthis.overlayFocusRestore = {\n\t\t\t\tstatus: \"blocked\",\n\t\t\t\toverlay: entry,\n\t\t\t\tblockedBy: restoreState.blockedBy,\n\t\t\t\tresume: { status: \"focus-target\", target: options.target },\n\t\t\t};\n\t\t} else {\n\t\t\tthis.clearOverlayFocusRestore();\n\t\t}\n\t\tthis.requestRender();\n\t\treturn true;\n\t}\n\n\tprivate unfocusOverlay(entry: OverlayStackEntry, options: OverlayUnfocusOptions | undefined): void {\n\t\tconst isFocused = this.focusedComponent === entry.component;\n\t\tconst restoreState = this.overlayFocusRestore;\n\t\tconst hasPendingRestore = restoreState.status !== \"inactive\" && restoreState.overlay === entry;\n\t\tif (!isFocused && !hasPendingRestore) return;\n\t\tif (this.applyBlockedOverlayUnfocus(entry, restoreState, options)) return;\n\n\t\tthis.clearOverlayFocusRestoreFor(entry);\n\t\tif (isFocused || options) {\n\t\t\tconst topVisible = this.getTopmostVisibleOverlay();\n\t\t\tconst fallbackTarget = topVisible && topVisible !== entry ? topVisible.component : entry.preFocus;\n\t\t\tthis.setFocus(options ? options.target : fallbackTarget);\n\t\t}\n\t\tthis.requestRender();\n\t}\n\n\t/**\n\t * Show an overlay component with configurable positioning and sizing.\n\t * Returns a handle to control the overlay's visibility.\n\t */\n\tshowOverlay(component: Component, options?: OverlayOptions): OverlayHandle {\n\t\tconst entry: OverlayStackEntry = {\n\t\t\tcomponent,\n\t\t\t...(options === undefined ? {} : { options }),\n\t\t\tpreFocus: this.focusedComponent,\n\t\t\thidden: false,\n\t\t\tfocusOrder: ++this.focusOrderCounter,\n\t\t\tvisible: false,\n\t\t};\n\t\tthis.overlayStack.push(entry);\n\t\tentry.visible = this.isOverlayVisible(entry);\n\t\tthis.onOverlayStackChanged();\n\t\t// Only focus if overlay is actually visible\n\t\tif (!options?.nonCapturing && this.isOverlayVisible(entry)) {\n\t\t\tthis.setFocus(component);\n\t\t}\n\t\tthis.terminal.hideCursor();\n\t\tthis.requestRender();\n\n\t\t// Return handle for controlling this overlay\n\t\treturn {\n\t\t\thide: () => {\n\t\t\t\tconst index = this.overlayStack.indexOf(entry);\n\t\t\t\tif (index !== -1) {\n\t\t\t\t\tthis.clearOverlayFocusRestoreFor(entry);\n\t\t\t\t\tthis.retargetOverlayPreFocus(entry);\n\t\t\t\t\tthis.overlayStack.splice(index, 1);\n\t\t\t\t\tthis.onOverlayStackChanged();\n\t\t\t\t\t// Restore focus if this overlay had focus\n\t\t\t\t\tif (this.focusedComponent === component) {\n\t\t\t\t\t\tconst topVisible = this.getTopmostVisibleOverlay();\n\t\t\t\t\t\tthis.setFocus(topVisible?.component ?? entry.preFocus);\n\t\t\t\t\t}\n\t\t\t\t\tif (this.overlayStack.length === 0) this.terminal.hideCursor();\n\t\t\t\t\tthis.requestRender();\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetHidden: (hidden: boolean) => {\n\t\t\t\tif (entry.hidden === hidden) return;\n\t\t\t\tentry.hidden = hidden;\n\t\t\t\tentry.visible = this.isOverlayVisible(entry);\n\t\t\t\t// Update focus when hiding/showing\n\t\t\t\tif (hidden) {\n\t\t\t\t\tthis.clearOverlayFocusRestoreFor(entry);\n\t\t\t\t\t// If this overlay had focus, move focus to next visible or preFocus\n\t\t\t\t\tif (this.focusedComponent === component) {\n\t\t\t\t\t\tconst topVisible = this.getTopmostVisibleOverlay();\n\t\t\t\t\t\tthis.setFocus(topVisible?.component ?? entry.preFocus);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Restore focus to this overlay when showing (if it's actually visible)\n\t\t\t\t\tif (!options?.nonCapturing && this.isOverlayVisible(entry)) {\n\t\t\t\t\t\tentry.focusOrder = ++this.focusOrderCounter;\n\t\t\t\t\t\tthis.setFocus(component);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.onOverlayStackChanged();\n\t\t\t\tthis.requestRender();\n\t\t\t},\n\t\t\tisHidden: () => entry.hidden,\n\t\t\tfocus: () => {\n\t\t\t\tif (!this.overlayStack.includes(entry) || !this.isOverlayVisible(entry)) return;\n\t\t\t\tentry.focusOrder = ++this.focusOrderCounter;\n\t\t\t\tthis.setFocus(component);\n\t\t\t\tthis.requestRender();\n\t\t\t},\n\t\t\tunfocus: (unfocusOptions) => this.unfocusOverlay(entry, unfocusOptions),\n\t\t\tisFocused: () => this.focusedComponent === component,\n\t\t};\n\t}\n\n\t/** Hide the topmost overlay and restore previous focus. */\n\thideOverlay(): void {\n\t\tconst overlay = this.overlayStack[this.overlayStack.length - 1];\n\t\tif (!overlay) return;\n\t\tthis.clearOverlayFocusRestoreFor(overlay);\n\t\tthis.retargetOverlayPreFocus(overlay);\n\t\tthis.overlayStack.pop();\n\t\tthis.onOverlayStackChanged();\n\t\tif (this.focusedComponent === overlay.component) {\n\t\t\t// Find topmost visible overlay, or fall back to preFocus\n\t\t\tconst topVisible = this.getTopmostVisibleOverlay();\n\t\t\tthis.setFocus(topVisible?.component ?? overlay.preFocus);\n\t\t}\n\t\tif (this.overlayStack.length === 0) this.terminal.hideCursor();\n\t\tthis.requestRender();\n\t}\n\n\t/** Check if there are any visible overlays */\n\thasOverlay(): boolean {\n\t\treturn this.overlayStack.some((o) => this.isOverlayVisible(o));\n\t}\n\n\tprotected hasCapturingOverlay(): boolean {\n\t\treturn this.overlayStack.some((o) => !o.options?.nonCapturing && this.isOverlayVisible(o));\n\t}\n\n\t/** Check if an overlay entry is currently visible */\n\tprivate isOverlayVisible(entry: OverlayStackEntry): boolean {\n\t\tif (entry.hidden) return false;\n\t\tif (entry.options?.visible) {\n\t\t\treturn entry.options.visible(this.terminal.columns, this.terminal.rows);\n\t\t}\n\t\treturn true;\n\t}\n\n\t/** Find the visual-frontmost visible capturing overlay, if any */\n\tprivate getTopmostVisibleOverlay(): OverlayStackEntry | undefined {\n\t\tlet topmost: OverlayStackEntry | undefined;\n\t\tfor (const overlay of this.overlayStack) {\n\t\t\tif (overlay.options?.nonCapturing || !this.isOverlayVisible(overlay)) continue;\n\t\t\tif (!topmost || overlay.focusOrder > topmost.focusOrder) {\n\t\t\t\ttopmost = overlay;\n\t\t\t}\n\t\t}\n\t\treturn topmost;\n\t}\n\n\tprivate refreshOverlayVisibility(): OverlayStackEntry | undefined {\n\t\tlet newlyVisible: OverlayStackEntry | undefined;\n\t\tfor (const overlay of this.overlayStack) {\n\t\t\tconst visible = this.isOverlayVisible(overlay);\n\t\t\tif (visible && !overlay.visible && !overlay.options?.nonCapturing) {\n\t\t\t\tif (!newlyVisible || overlay.focusOrder > newlyVisible.focusOrder) newlyVisible = overlay;\n\t\t\t}\n\t\t\toverlay.visible = visible;\n\t\t}\n\t\treturn newlyVisible;\n\t}\n\n\tprivate retargetFocusFromHiddenOverlay(): void {\n\t\tconst focusedOverlay = this.overlayStack.find((overlay) => overlay.component === this.focusedComponent);\n\t\tif (!focusedOverlay || this.isOverlayVisible(focusedOverlay)) return;\n\t\tconst topVisible = this.getTopmostVisibleOverlay();\n\t\tif (topVisible) {\n\t\t\tthis.setFocus(topVisible.component);\n\t\t\treturn;\n\t\t}\n\t\tthis.setFocusInternal({ component: focusedOverlay.preFocus, overlayFocusRestore: \"preserve\" });\n\t}\n\n\tprivate focusNewlyVisibleOverlay(newlyVisible: OverlayStackEntry | undefined): void {\n\t\tif (!newlyVisible) return;\n\t\tconst currentFocusedOverlay = this.overlayStack.find(\n\t\t\t(overlay) => overlay.component === this.focusedComponent && this.isOverlayVisible(overlay),\n\t\t);\n\t\tif (!currentFocusedOverlay || newlyVisible.focusOrder > currentFocusedOverlay.focusOrder) {\n\t\t\tthis.setFocus(newlyVisible.component);\n\t\t}\n\t}\n\n\tprivate restoreVisibleOverlayFocus(): void {\n\t\tif (this.overlayStack.some((overlay) => overlay.component === this.focusedComponent)) return;\n\t\tconst restoreState = this.getVisibleOverlayFocusRestore();\n\t\tif (restoreState.status === \"eligible\") {\n\t\t\tthis.setFocus(restoreState.overlay.component);\n\t\t\treturn;\n\t\t}\n\t\tif (restoreState.status !== \"blocked\" || restoreState.blockedBy === this.focusedComponent) return;\n\t\tif (restoreState.resume.status === \"restore-overlay\") {\n\t\t\tthis.setFocus(restoreState.overlay.component);\n\t\t\treturn;\n\t\t}\n\t\tthis.clearOverlayFocusRestore();\n\t\tthis.setFocus(restoreState.resume.target);\n\t}\n\n\tprivate reconcileOverlayFocus(): void {\n\t\tconst newlyVisible = this.refreshOverlayVisibility();\n\t\tthis.retargetFocusFromHiddenOverlay();\n\t\tthis.focusNewlyVisibleOverlay(newlyVisible);\n\t\tthis.restoreVisibleOverlayFocus();\n\t}\n\n\toverride invalidate(): void {\n\t\tfor (const root of this.getMountedRoots()) root.invalidate();\n\t\tfor (const overlay of this.overlayStack) overlay.component.invalidate?.();\n\t}\n\n\tstart(): void {\n\t\tthis.stopped = false;\n\t\ttry {\n\t\t\tthis.beforeTerminalStart();\n\t\t\tthis.terminal.start(\n\t\t\t\t(data) => this.handleTerminalInput(data),\n\t\t\t\t() => {\n\t\t\t\t\tthis.reconcileOverlayFocus();\n\t\t\t\t\tthis.onTerminalResize();\n\t\t\t\t\tthis.requestRender();\n\t\t\t\t},\n\t\t\t);\n\t\t\tthis.afterTerminalStart();\n\t\t\tthis.terminal.hideCursor();\n\t\t\tthis.queryCellSize();\n\t\t\tthis.requestRender();\n\t\t} catch (error) {\n\t\t\t// A terminal may throw after partially entering raw or alternate-screen mode.\n\t\t\t// Route startup failures through the same complete cleanup path as signals.\n\t\t\ttry {\n\t\t\t\tthis.stop();\n\t\t\t} catch {\n\t\t\t\t// Preserve the startup failure; cleanup is best-effort but exhaustive.\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\taddInputListener(listener: TuiInputListener): () => void {\n\t\tthis.inputListeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.inputListeners.delete(listener);\n\t\t};\n\t}\n\n\tremoveInputListener(listener: TuiInputListener): void {\n\t\tthis.inputListeners.delete(listener);\n\t}\n\n\tprivate queryCellSize(): void {\n\t\t// Only query if terminal supports images (cell size is only used for image rendering)\n\t\tif (!getCapabilities().images) {\n\t\t\treturn;\n\t\t}\n\t\t// Query terminal for cell size in pixels: CSI 16 t\n\t\t// Response format: CSI 6 ; height ; width t\n\t\tthis.terminal.write(\"\\x1b[16t\");\n\t}\n\n\tstop(options?: TuiStopOptions): void {\n\t\tthis.stopped = true;\n\t\tthis.renderRequested = false;\n\t\tthis.cancelRenderTimer();\n\t\tlet failure: unknown;\n\t\tconst cleanup = (action: () => void): void => {\n\t\t\ttry {\n\t\t\t\taction();\n\t\t\t} catch (error) {\n\t\t\t\tfailure ??= error;\n\t\t\t}\n\t\t};\n\t\tcleanup(() => this.beforeTerminalStop(options));\n\t\tcleanup(() => this.terminal.showCursor());\n\t\tcleanup(() => this.terminal.stop());\n\t\t// Alternate-screen exit and capability restoration must run even when\n\t\t// keyboard/raw-mode shutdown reports an error.\n\t\tcleanup(() => this.afterTerminalStop(options));\n\t\tif (failure !== undefined) throw failure;\n\t}\n\n\trenderNow(force = false): void {\n\t\tif (force) this.resetRenderState();\n\t\tthis.renderRequested = false;\n\t\tthis.cancelRenderTimer();\n\t\tthis.lastRenderAt = performance.now();\n\t\tthis.doRender();\n\t}\n\n\trequestRender(force = false): void {\n\t\tif (force) {\n\t\t\tthis.resetRenderState();\n\t\t\tthis.requestImmediateRender();\n\t\t\treturn;\n\t\t}\n\t\tif (this.renderRequested) return;\n\t\tthis.renderRequested = true;\n\t\tprocess.nextTick(() => this.scheduleRender());\n\t}\n\n\tprivate requestImmediateRender(): void {\n\t\tthis.cancelRenderTimer();\n\t\tthis.renderRequested = true;\n\t\tif (this.immediateRenderScheduled) return;\n\t\tthis.immediateRenderScheduled = true;\n\t\tprocess.nextTick(() => {\n\t\t\tthis.immediateRenderScheduled = false;\n\t\t\tif (this.stopped || !this.renderRequested) return;\n\t\t\tthis.cancelRenderTimer();\n\t\t\tthis.renderRequested = false;\n\t\t\tthis.lastRenderAt = performance.now();\n\t\t\tthis.doRender();\n\t\t});\n\t}\n\n\tprivate cancelRenderTimer(): void {\n\t\tif (!this.renderTimer) return;\n\t\tclearTimeout(this.renderTimer);\n\t\tthis.renderTimer = undefined;\n\t}\n\n\tprivate scheduleRender(): void {\n\t\tif (this.stopped || this.renderTimer || !this.renderRequested) return;\n\t\tconst elapsed = performance.now() - this.lastRenderAt;\n\t\tconst delay = Math.max(0, TuiBase.MIN_RENDER_INTERVAL_MS - elapsed);\n\t\tthis.renderTimer = setTimeout(() => {\n\t\t\tthis.renderTimer = undefined;\n\t\t\tif (this.stopped || !this.renderRequested) return;\n\t\t\tthis.renderRequested = false;\n\t\t\tthis.lastRenderAt = performance.now();\n\t\t\tthis.doRender();\n\t\t\tif (this.renderRequested) this.scheduleRender();\n\t\t}, delay);\n\t}\n\n\tprivate applyInputListeners(data: string): string | undefined {\n\t\tif (this.inputListeners.size === 0) return data;\n\t\tlet current = data;\n\t\tfor (const listener of this.inputListeners) {\n\t\t\tconst result = listener(current);\n\t\t\tif (result?.consume) return undefined;\n\t\t\tif (result?.data !== undefined) current = result.data;\n\t\t}\n\t\treturn current.length === 0 ? undefined : current;\n\t}\n\n\tprivate handleTerminalInput(data: string): void {\n\t\tthis.reconcileOverlayFocus();\n\t\tconst filteredData = this.applyInputListeners(data);\n\t\tif (filteredData === undefined) return;\n\t\tdata = filteredData;\n\n\t\t// Consume terminal cell size responses without blocking unrelated input.\n\t\tif (this.consumeCellSizeResponse(data)) return;\n\n\t\t// Global debug key handler (Shift+Ctrl+D)\n\t\tif (matchesKey(data, \"shift+ctrl+d\") && this.onDebug) {\n\t\t\tthis.onDebug();\n\t\t\treturn;\n\t\t}\n\n\t\t// Pass input to focused component (including Ctrl+C).\n\t\t// The focused component can decide how to handle Ctrl+C.\n\t\tif (!this.focusedComponent?.handleInput) return;\n\t\t// Filter out key release events unless component opts in.\n\t\tif (isKeyRelease(data) && !this.focusedComponent.wantsKeyRelease) return;\n\t\tthis.focusedComponent.handleInput(data);\n\t\tthis.requestImmediateRender();\n\t}\n\n\tprivate consumeCellSizeResponse(data: string): boolean {\n\t\t// Response format: ESC [ 6 ; height ; width t\n\t\tconst match = data.match(/^\\x1b\\[6;(\\d+);(\\d+)t$/);\n\t\tif (!match) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst heightPx = parseInt(match[1], 10);\n\t\tconst widthPx = parseInt(match[2], 10);\n\t\tif (heightPx <= 0 || widthPx <= 0) {\n\t\t\treturn true;\n\t\t}\n\n\t\tsetCellDimensions({ widthPx, heightPx });\n\t\t// Invalidate all components so images re-render with correct dimensions.\n\t\tthis.invalidate();\n\t\tthis.requestRender();\n\t\treturn true;\n\t}\n\n\tprivate resolveOverlayBounds(options: OverlayOptions, termWidth: number, termHeight: number): OverlayLayoutBounds {\n\t\tconst margin =\n\t\t\ttypeof options.margin === \"number\"\n\t\t\t\t? { top: options.margin, right: options.margin, bottom: options.margin, left: options.margin }\n\t\t\t\t: (options.margin ?? {});\n\t\tconst marginTop = Math.max(0, margin.top ?? 0);\n\t\tconst marginRight = Math.max(0, margin.right ?? 0);\n\t\tconst marginBottom = Math.max(0, margin.bottom ?? 0);\n\t\tconst marginLeft = Math.max(0, margin.left ?? 0);\n\t\treturn {\n\t\t\tmarginTop,\n\t\t\tmarginRight,\n\t\t\tmarginBottom,\n\t\t\tmarginLeft,\n\t\t\tavailableWidth: Math.max(1, termWidth - marginLeft - marginRight),\n\t\t\tavailableHeight: Math.max(1, termHeight - marginTop - marginBottom),\n\t\t};\n\t}\n\n\tprivate resolveOverlayWidth(options: OverlayOptions, termWidth: number, bounds: OverlayLayoutBounds): number {\n\t\tlet width = parseSizeValue(options.width, termWidth) ?? Math.min(80, bounds.availableWidth);\n\t\tif (options.minWidth !== undefined) width = Math.max(width, options.minWidth);\n\t\treturn Math.max(1, Math.min(width, bounds.availableWidth));\n\t}\n\n\tprivate resolveOverlayMaxHeight(\n\t\toptions: OverlayOptions,\n\t\ttermHeight: number,\n\t\tbounds: OverlayLayoutBounds,\n\t): number | undefined {\n\t\tconst maxHeight = parseSizeValue(options.maxHeight, termHeight);\n\t\treturn maxHeight === undefined ? undefined : Math.max(1, Math.min(maxHeight, bounds.availableHeight));\n\t}\n\n\tprivate resolveOverlayRow(options: OverlayOptions, overlayHeight: number, bounds: OverlayLayoutBounds): number {\n\t\tif (options.row === undefined) {\n\t\t\treturn this.resolveAnchorRow(\n\t\t\t\toptions.anchor ?? \"center\",\n\t\t\t\toverlayHeight,\n\t\t\t\tbounds.availableHeight,\n\t\t\t\tbounds.marginTop,\n\t\t\t);\n\t\t}\n\t\tif (typeof options.row === \"number\") return options.row;\n\t\tconst match = options.row.match(/^(\\d+(?:\\.\\d+)?)%$/);\n\t\tif (!match) return this.resolveAnchorRow(\"center\", overlayHeight, bounds.availableHeight, bounds.marginTop);\n\t\tconst maxRow = Math.max(0, bounds.availableHeight - overlayHeight);\n\t\treturn bounds.marginTop + Math.floor(maxRow * (parseFloat(match[1]) / 100));\n\t}\n\n\tprivate resolveOverlayColumn(options: OverlayOptions, width: number, bounds: OverlayLayoutBounds): number {\n\t\tif (options.col === undefined) {\n\t\t\treturn this.resolveAnchorCol(options.anchor ?? \"center\", width, bounds.availableWidth, bounds.marginLeft);\n\t\t}\n\t\tif (typeof options.col === \"number\") return options.col;\n\t\tconst match = options.col.match(/^(\\d+(?:\\.\\d+)?)%$/);\n\t\tif (!match) return this.resolveAnchorCol(\"center\", width, bounds.availableWidth, bounds.marginLeft);\n\t\tconst maxCol = Math.max(0, bounds.availableWidth - width);\n\t\treturn bounds.marginLeft + Math.floor(maxCol * (parseFloat(match[1]) / 100));\n\t}\n\n\t/** Resolve overlay layout from options. */\n\tprivate resolveOverlayLayout(\n\t\toptions: OverlayOptions | undefined,\n\t\toverlayHeight: number,\n\t\ttermWidth: number,\n\t\ttermHeight: number,\n\t): ResolvedOverlayLayout {\n\t\tconst resolvedOptions = options ?? {};\n\t\tconst bounds = this.resolveOverlayBounds(resolvedOptions, termWidth, termHeight);\n\t\tconst width = this.resolveOverlayWidth(resolvedOptions, termWidth, bounds);\n\t\tconst maxHeight = this.resolveOverlayMaxHeight(resolvedOptions, termHeight, bounds);\n\t\tconst effectiveHeight = maxHeight === undefined ? overlayHeight : Math.min(overlayHeight, maxHeight);\n\t\tlet row = this.resolveOverlayRow(resolvedOptions, effectiveHeight, bounds) + (resolvedOptions.offsetY ?? 0);\n\t\tlet col = this.resolveOverlayColumn(resolvedOptions, width, bounds) + (resolvedOptions.offsetX ?? 0);\n\t\trow = Math.max(bounds.marginTop, Math.min(row, termHeight - bounds.marginBottom - effectiveHeight));\n\t\tcol = Math.max(bounds.marginLeft, Math.min(col, termWidth - bounds.marginRight - width));\n\t\treturn { width, row, col, maxHeight };\n\t}\n\n\tprivate resolveAnchorRow(anchor: OverlayAnchor, height: number, availHeight: number, marginTop: number): number {\n\t\tswitch (anchor) {\n\t\t\tcase \"top-left\":\n\t\t\tcase \"top-center\":\n\t\t\tcase \"top-right\":\n\t\t\t\treturn marginTop;\n\t\t\tcase \"bottom-left\":\n\t\t\tcase \"bottom-center\":\n\t\t\tcase \"bottom-right\":\n\t\t\t\treturn marginTop + availHeight - height;\n\t\t\tcase \"left-center\":\n\t\t\tcase \"center\":\n\t\t\tcase \"right-center\":\n\t\t\t\treturn marginTop + Math.floor((availHeight - height) / 2);\n\t\t}\n\t}\n\n\tprivate resolveAnchorCol(anchor: OverlayAnchor, width: number, availWidth: number, marginLeft: number): number {\n\t\tswitch (anchor) {\n\t\t\tcase \"top-left\":\n\t\t\tcase \"left-center\":\n\t\t\tcase \"bottom-left\":\n\t\t\t\treturn marginLeft;\n\t\t\tcase \"top-right\":\n\t\t\tcase \"right-center\":\n\t\t\tcase \"bottom-right\":\n\t\t\t\treturn marginLeft + availWidth - width;\n\t\t\tcase \"top-center\":\n\t\t\tcase \"center\":\n\t\t\tcase \"bottom-center\":\n\t\t\t\treturn marginLeft + Math.floor((availWidth - width) / 2);\n\t\t}\n\t}\n\n\tprivate prepareOverlayRenderPlan(baseLineCount: number, termWidth: number, termHeight: number): OverlayRenderPlan {\n\t\tconst visibleEntries = this.overlayStack.filter((entry) => this.isOverlayVisible(entry));\n\t\tvisibleEntries.sort((left, right) => left.focusOrder - right.focusOrder);\n\t\tconst overlays: RenderedOverlay[] = [];\n\t\tlet minimumLineCount = baseLineCount;\n\t\tfor (const entry of visibleEntries) {\n\t\t\tconst { width, maxHeight } = this.resolveOverlayLayout(entry.options, 0, termWidth, termHeight);\n\t\t\tlet overlayLines = entry.component.render(width);\n\t\t\tif (maxHeight !== undefined && overlayLines.length > maxHeight) {\n\t\t\t\toverlayLines = overlayLines.slice(0, maxHeight);\n\t\t\t}\n\t\t\tconst { row, col } = this.resolveOverlayLayout(entry.options, overlayLines.length, termWidth, termHeight);\n\t\t\toverlays.push({ lines: overlayLines, row, col, width });\n\t\t\tminimumLineCount = Math.max(minimumLineCount, row + overlayLines.length);\n\t\t}\n\t\treturn { overlays, minimumLineCount };\n\t}\n\n\tprivate compositeRenderedOverlay(\n\t\tresult: string[],\n\t\toverlay: RenderedOverlay,\n\t\tviewportStart: number,\n\t\ttermWidth: number,\n\t): void {\n\t\tfor (let lineIndex = 0; lineIndex < overlay.lines.length; lineIndex++) {\n\t\t\tconst targetIndex = viewportStart + overlay.row + lineIndex;\n\t\t\tif (targetIndex < 0 || targetIndex >= result.length) continue;\n\t\t\tconst overlayLine = overlay.lines[lineIndex]!;\n\t\t\tconst truncatedLine =\n\t\t\t\tvisibleWidth(overlayLine) > overlay.width\n\t\t\t\t\t? sliceByColumn(overlayLine, 0, overlay.width, true)\n\t\t\t\t\t: overlayLine;\n\t\t\tresult[targetIndex] = this.compositeLineAt(\n\t\t\t\tresult[targetIndex]!,\n\t\t\t\ttruncatedLine,\n\t\t\t\toverlay.col,\n\t\t\t\toverlay.width,\n\t\t\t\ttermWidth,\n\t\t\t);\n\t\t}\n\t}\n\n\t/** Composite all overlays into content lines (sorted by focusOrder, higher = on top). */\n\tprotected compositeOverlays(lines: string[], termWidth: number, termHeight: number): string[] {\n\t\tif (this.overlayStack.length === 0) return lines;\n\t\tconst result = [...lines];\n\t\tconst plan = this.prepareOverlayRenderPlan(result.length, termWidth, termHeight);\n\t\tconst workingHeight = Math.max(result.length, termHeight, plan.minimumLineCount);\n\t\twhile (result.length < workingHeight) result.push(\"\");\n\t\tconst viewportStart = Math.max(0, workingHeight - termHeight);\n\t\tfor (const overlay of plan.overlays) {\n\t\t\tthis.compositeRenderedOverlay(result, overlay, viewportStart, termWidth);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprotected applyLineResets(lines: string[]): string[] {\n\t\tconst reset = SEGMENT_RESET;\n\t\tfor (let i = 0; i < lines.length; i++) {\n\t\t\tconst line = lines[i];\n\t\t\tif (!isImageLine(line)) {\n\t\t\t\tlines[i] = normalizeTerminalOutput(line) + reset;\n\t\t\t}\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate compositeLineAt(\n\t\tbaseLine: string,\n\t\toverlayLine: string,\n\t\tstartCol: number,\n\t\toverlayWidth: number,\n\t\ttotalWidth: number,\n\t): string {\n\t\treturn compositeTuiLine(baseLine, overlayLine, startCol, overlayWidth, totalWidth);\n\t}\n\n\t/**\n\t * Find and extract cursor position from rendered lines.\n\t * Searches for CURSOR_MARKER, calculates its position, and strips it from the output.\n\t * Only scans the bottom terminal height lines (visible viewport).\n\t * @param lines - Rendered lines to search\n\t * @param height - Terminal height (visible viewport size)\n\t * @returns Cursor position { row, col } or null if no marker found\n\t */\n\tprotected extractCursorPosition(lines: string[], height: number): RenderedCursorPosition | null {\n\t\t// Only scan the bottom `height` lines (visible viewport)\n\t\tconst viewportTop = Math.max(0, lines.length - height);\n\t\tfor (let row = lines.length - 1; row >= viewportTop; row--) {\n\t\t\tconst line = lines[row];\n\t\t\tconst markerIndex = line.indexOf(CURSOR_MARKER);\n\t\t\tif (markerIndex !== -1) {\n\t\t\t\t// Calculate visual column (width of text before marker)\n\t\t\t\tconst beforeMarker = line.slice(0, markerIndex);\n\t\t\t\tconst col = visibleWidth(beforeMarker);\n\n\t\t\t\t// Strip marker from the line\n\t\t\t\tlines[row] = line.slice(0, markerIndex) + line.slice(markerIndex + CURSOR_MARKER.length);\n\n\t\t\t\treturn { row, col };\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tui.js","sourceRoot":"","sources":["../src/tui.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Minimal TUI implementation with differential rendering\n */\n\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport { isKeyRelease, matchesKey } from \"./keys.ts\";\nimport type { Terminal } from \"./terminal.ts\";\nimport { getCapabilities, isImageLine, setCellDimensions } from \"./terminal-image.ts\";\nimport { extractSegments, normalizeTerminalOutput, sliceByColumn, sliceWithWidth, visibleWidth } from \"./utils.ts\";\n\n/**\n * Component interface - all components must implement this\n */\nexport interface Component {\n\t/**\n\t * Render the component to lines for the given viewport width\n\t * @param width - Current viewport width\n\t * @returns Array of strings, each representing a line\n\t */\n\trender(width: number): string[];\n\n\t/**\n\t * Optional handler for keyboard input when component has focus\n\t */\n\thandleInput?(data: string): void;\n\n\t/**\n\t * If true, component receives key release events (Kitty protocol).\n\t * Default is false - release events are filtered out.\n\t */\n\twantsKeyRelease?: boolean;\n\n\t/**\n\t * Invalidate any cached rendering state.\n\t * Called when theme changes or when component needs to re-render from scratch.\n\t */\n\tinvalidate(): void;\n}\n\nexport type TuiInputListenerResult = { consume?: boolean; data?: string } | undefined;\nexport type TuiInputListener = (data: string) => TuiInputListenerResult;\n\n/**\n * Interface for components that can receive focus and display a hardware cursor.\n * When focused, the component should emit CURSOR_MARKER at the cursor position\n * in its render output. TUI will find this marker and position the hardware\n * cursor there for proper IME candidate window positioning.\n */\nexport interface Focusable {\n\t/** Set by TUI when focus changes. Component should emit CURSOR_MARKER when true. */\n\tfocused: boolean;\n}\n\n/** Type guard to check if a component implements Focusable */\nexport function isFocusable(component: Component | null): component is Component & Focusable {\n\treturn component !== null && \"focused\" in component;\n}\n\n/**\n * Cursor position marker - APC (Application Program Command) sequence.\n * This is a zero-width escape sequence that terminals ignore.\n * Components emit this at the cursor position when focused.\n * TUI finds and strips this marker, then positions the hardware cursor there.\n */\nexport const CURSOR_MARKER = \"\\x1b_pi:c\\x07\";\n\nexport { visibleWidth };\n\n/**\n * Anchor position for overlays\n */\nexport type OverlayAnchor =\n\t| \"center\"\n\t| \"top-left\"\n\t| \"top-right\"\n\t| \"bottom-left\"\n\t| \"bottom-right\"\n\t| \"top-center\"\n\t| \"bottom-center\"\n\t| \"left-center\"\n\t| \"right-center\";\n\n/**\n * Margin configuration for overlays\n */\nexport interface OverlayMargin {\n\ttop?: number;\n\tright?: number;\n\tbottom?: number;\n\tleft?: number;\n}\n\n/** Value that can be absolute (number) or percentage (string like \"50%\") */\nexport type SizeValue = number | `${number}%`;\n\n/** Parse a SizeValue into absolute value given a reference size */\nfunction parseSizeValue(value: SizeValue | undefined, referenceSize: number): number | undefined {\n\tif (value === undefined) return undefined;\n\tif (typeof value === \"number\") return value;\n\t// Parse percentage string like \"50%\"\n\tconst match = value.match(/^(\\d+(?:\\.\\d+)?)%$/);\n\tif (match) {\n\t\treturn Math.floor((referenceSize * parseFloat(match[1])) / 100);\n\t}\n\treturn undefined;\n}\n\n/**\n * Options for overlay positioning and sizing.\n * Values can be absolute numbers or percentage strings (e.g., \"50%\").\n */\nexport interface OverlayOptions {\n\t// === Sizing ===\n\t/** Width in columns, or percentage of terminal width (e.g., \"50%\") */\n\twidth?: SizeValue;\n\t/** Minimum width in columns */\n\tminWidth?: number;\n\t/** Maximum height in rows, or percentage of terminal height (e.g., \"50%\") */\n\tmaxHeight?: SizeValue;\n\n\t// === Positioning - anchor-based ===\n\t/** Anchor point for positioning (default: 'center') */\n\tanchor?: OverlayAnchor;\n\t/** Horizontal offset from anchor position (positive = right) */\n\toffsetX?: number;\n\t/** Vertical offset from anchor position (positive = down) */\n\toffsetY?: number;\n\n\t// === Positioning - percentage or absolute ===\n\t/** Row position: absolute number, or percentage (e.g., \"25%\" = 25% from top) */\n\trow?: SizeValue;\n\t/** Column position: absolute number, or percentage (e.g., \"50%\" = centered horizontally) */\n\tcol?: SizeValue;\n\n\t// === Margin from terminal edges ===\n\t/** Margin from terminal edges. Number applies to all sides. */\n\tmargin?: OverlayMargin | number;\n\n\t// === Visibility ===\n\t/**\n\t * Control overlay visibility based on terminal dimensions.\n\t * If provided, overlay is only rendered when this returns true.\n\t * Called each render cycle with current terminal dimensions.\n\t */\n\tvisible?: (termWidth: number, termHeight: number) => boolean;\n\t/** If true, don't capture keyboard focus when shown */\n\tnonCapturing?: boolean;\n}\n\n/** Options for {@link OverlayHandle.unfocus}. */\nexport interface OverlayUnfocusOptions {\n\t/** Explicit target to focus after releasing this overlay. */\n\ttarget: Component | null;\n}\n\n/**\n * Handle returned by showOverlay for controlling the overlay\n */\nexport interface OverlayHandle {\n\t/** Permanently remove the overlay (cannot be shown again) */\n\thide(): void;\n\t/** Temporarily hide or show the overlay */\n\tsetHidden(hidden: boolean): void;\n\t/** Check if overlay is temporarily hidden */\n\tisHidden(): boolean;\n\t/** Focus this overlay and bring it to the visual front */\n\tfocus(): void;\n\t/** Release focus to the next visible capturing overlay or previous target, or to an explicit target when provided */\n\tunfocus(options?: OverlayUnfocusOptions): void;\n\t/** Check if this overlay currently has focus */\n\tisFocused(): boolean;\n}\n\ntype OverlayStackEntry = {\n\tcomponent: Component;\n\toptions?: OverlayOptions;\n\tpreFocus: Component | null;\n\thidden: boolean;\n\tfocusOrder: number;\n\tvisible: boolean;\n};\n\ntype OverlayBlockedFocusResume = { status: \"restore-overlay\" } | { status: \"focus-target\"; target: Component | null };\ntype EligibleOverlayFocusRestoreState = { status: \"eligible\"; overlay: OverlayStackEntry };\ntype BlockedOverlayFocusRestoreState = {\n\tstatus: \"blocked\";\n\toverlay: OverlayStackEntry;\n\tblockedBy: Component;\n\tresume: OverlayBlockedFocusResume;\n};\ntype ActiveOverlayFocusRestoreState = EligibleOverlayFocusRestoreState | BlockedOverlayFocusRestoreState;\ntype OverlayFocusRestoreState = { status: \"inactive\" } | ActiveOverlayFocusRestoreState;\ntype OverlayFocusRestorePolicy = \"clear\" | \"preserve\";\n\ninterface FocusTransitionRequest {\n\tcomponent: Component | null;\n\toverlayFocusRestore: OverlayFocusRestorePolicy;\n}\n\ninterface ResolvedOverlayLayout {\n\twidth: number;\n\trow: number;\n\tcol: number;\n\tmaxHeight: number | undefined;\n}\n\ninterface RenderedOverlay {\n\tlines: string[];\n\trow: number;\n\tcol: number;\n\twidth: number;\n}\n\ninterface OverlayRenderPlan {\n\toverlays: RenderedOverlay[];\n\tminimumLineCount: number;\n}\n\ninterface OverlayLayoutBounds {\n\tmarginTop: number;\n\tmarginRight: number;\n\tmarginBottom: number;\n\tmarginLeft: number;\n\tavailableWidth: number;\n\tavailableHeight: number;\n}\n\nexport interface RenderedCursorPosition {\n\trow: number;\n\tcol: number;\n}\n/**\n * Container - a component that contains other components\n */\nexport class Container implements Component {\n\tchildren: Component[] = [];\n\n\taddChild(component: Component): void {\n\t\tthis.children.push(component);\n\t}\n\n\tremoveChild(component: Component): void {\n\t\tconst index = this.children.indexOf(component);\n\t\tif (index !== -1) {\n\t\t\tthis.children.splice(index, 1);\n\t\t}\n\t}\n\n\tclear(): void {\n\t\tthis.children = [];\n\t}\n\n\tinvalidate(): void {\n\t\tfor (const child of this.children) {\n\t\t\tchild.invalidate?.();\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tfor (const child of this.children) {\n\t\t\tconst childLines = child.render(width);\n\t\t\tfor (const line of childLines) {\n\t\t\t\tlines.push(line);\n\t\t\t}\n\t\t}\n\t\treturn lines;\n\t}\n}\n\n/**\n * TUI - Main class for managing terminal UI with differential rendering\n */\nconst SEGMENT_RESET = \"\\x1b[0m\\x1b]8;;\\x07\";\n\n/** Composite overlay content into a terminal line at a fixed column. */\nexport function compositeTuiLine(\n\tbaseLine: string,\n\toverlayLine: string,\n\tstartCol: number,\n\toverlayWidth: number,\n\ttotalWidth: number,\n): string {\n\tif (isImageLine(baseLine)) return baseLine;\n\n\tconst afterStart = startCol + overlayWidth;\n\tconst base = extractSegments(baseLine, startCol, afterStart, totalWidth - afterStart, true);\n\tconst overlay = sliceWithWidth(overlayLine, 0, overlayWidth, true);\n\tconst beforePad = Math.max(0, startCol - base.beforeWidth);\n\tconst overlayPad = Math.max(0, overlayWidth - overlay.width);\n\tconst actualBeforeWidth = Math.max(startCol, base.beforeWidth);\n\tconst actualOverlayWidth = Math.max(overlayWidth, overlay.width);\n\tconst afterTarget = Math.max(0, totalWidth - actualBeforeWidth - actualOverlayWidth);\n\tconst afterPad = Math.max(0, afterTarget - base.afterWidth);\n\tconst result =\n\t\tbase.before +\n\t\t\" \".repeat(beforePad) +\n\t\tSEGMENT_RESET +\n\t\toverlay.text +\n\t\t\" \".repeat(overlayPad) +\n\t\tSEGMENT_RESET +\n\t\tbase.after +\n\t\t\" \".repeat(afterPad);\n\n\treturn visibleWidth(result) <= totalWidth ? result : sliceByColumn(result, 0, totalWidth, true);\n}\n\nexport type TuiMode = \"regular\" | \"fullscreen\";\n\nexport interface TuiStopOptions {\n\t/** Restore the previous main buffer without replaying renderer content. */\n\tpreserveScreen?: boolean;\n}\n\nexport interface TUI extends Component {\n\treadonly mode: TuiMode;\n\tchildren: Component[];\n\tterminal: Terminal;\n\tonDebug?: () => void;\n\treadonly fullRedraws: number;\n\treadonly hasOverlayEntries: boolean;\n\taddChild(component: Component): void;\n\tremoveChild(component: Component): void;\n\tclear(): void;\n\tgetShowHardwareCursor(): boolean;\n\tsetShowHardwareCursor(enabled: boolean): void;\n\tgetClearOnShrink(): boolean;\n\tsetClearOnShrink(enabled: boolean): void;\n\tgetFocusedComponent(): Component | null;\n\tsetFocus(component: Component | null): void;\n\tshowOverlay(component: Component, options?: OverlayOptions): OverlayHandle;\n\thideOverlay(): void;\n\thasOverlay(): boolean;\n\tstart(): void;\n\tstop(options?: TuiStopOptions): void;\n\trenderNow(force?: boolean): void;\n\trequestRender(force?: boolean): void;\n\taddInputListener(listener: TuiInputListener): () => void;\n\tremoveInputListener(listener: TuiInputListener): void;\n}\n\nexport const VIEWPORT_TUI = Symbol.for(\"@greppleai/grip-tui/viewport\");\n\nexport interface ViewportTUI extends TUI {\n\treadonly [VIEWPORT_TUI]: true;\n\tsetLayoutRoot(component: Component | undefined): void;\n}\n\nexport function isViewportTUI(tui: TUI): tui is ViewportTUI {\n\treturn (tui as Partial<ViewportTUI>)[VIEWPORT_TUI] === true;\n}\n\nexport abstract class TuiBase extends Container implements TUI {\n\tabstract readonly mode: TuiMode;\n\tpublic terminal: Terminal;\n\tprivate focusedComponent: Component | null = null;\n\tprivate inputListeners = new Set<TuiInputListener>();\n\n\t/** Global callback for debug key (Shift+Ctrl+D). Called before input is forwarded to focused component. */\n\tpublic onDebug?: () => void;\n\tprivate renderRequested = false;\n\tprivate immediateRenderScheduled = false;\n\tprivate renderTimer: NodeJS.Timeout | undefined;\n\tprivate lastRenderAt = 0;\n\tprivate static readonly MIN_RENDER_INTERVAL_MS = 16;\n\tprivate showHardwareCursor = process.env.GRIP_HARDWARE_CURSOR === \"1\";\n\tprivate clearOnShrink = process.env.GRIP_CLEAR_ON_SHRINK === \"1\";\n\tprotected fullRedrawCount = 0;\n\tprotected stopped = false;\n\tprotected readonly logDirectory: string;\n\n\t// Overlay stack for modal components rendered on top of base content\n\tprivate focusOrderCounter = 0;\n\tprivate overlayStack: OverlayStackEntry[] = [];\n\n\tget hasOverlayEntries(): boolean {\n\t\treturn this.overlayStack.length > 0;\n\t}\n\tprivate overlayFocusRestore: OverlayFocusRestoreState = { status: \"inactive\" };\n\n\tconstructor(terminal: Terminal, showHardwareCursor?: boolean, logDirectory?: string) {\n\t\tsuper();\n\t\tthis.terminal = terminal;\n\t\tthis.logDirectory =\n\t\t\tlogDirectory ?? process.env.GRIP_CODING_AGENT_DIR ?? path.join(os.homedir(), \".grip\", \"agent\");\n\t\tif (showHardwareCursor !== undefined) {\n\t\t\tthis.showHardwareCursor = showHardwareCursor;\n\t\t}\n\t}\n\n\tprotected abstract doRender(): void;\n\n\tprotected resetRenderState(): void {}\n\n\tprotected beforeTerminalStart(): void {}\n\n\tprotected afterTerminalStart(): void {}\n\n\tprotected onTerminalResize(): void {}\n\n\tprotected onOverlayStackChanged(): void {}\n\n\tprotected beforeTerminalStop(_options?: TuiStopOptions): void {}\n\n\tprotected afterTerminalStop(_options?: TuiStopOptions): void {}\n\n\tget fullRedraws(): number {\n\t\treturn this.fullRedrawCount;\n\t}\n\n\tgetShowHardwareCursor(): boolean {\n\t\treturn this.showHardwareCursor;\n\t}\n\n\tsetShowHardwareCursor(enabled: boolean): void {\n\t\tif (this.showHardwareCursor === enabled) return;\n\t\tthis.showHardwareCursor = enabled;\n\t\tif (!enabled) {\n\t\t\tthis.terminal.hideCursor();\n\t\t}\n\t\tthis.requestRender();\n\t}\n\n\tgetClearOnShrink(): boolean {\n\t\treturn this.clearOnShrink;\n\t}\n\n\t/**\n\t * Set whether to trigger full re-render when content shrinks.\n\t * When true (default), empty rows are cleared when content shrinks.\n\t * When false, empty rows remain (reduces redraws on slower terminals).\n\t */\n\tsetClearOnShrink(enabled: boolean): void {\n\t\tthis.clearOnShrink = enabled;\n\t}\n\n\tgetFocusedComponent(): Component | null {\n\t\treturn this.focusedComponent;\n\t}\n\n\tsetFocus(component: Component | null): void {\n\t\tthis.setFocusInternal({ component, overlayFocusRestore: \"clear\" });\n\t}\n\n\tprivate resolveNonOverlayFocus(\n\t\tnextFocus: Component,\n\t\tpreviousFocus: Component | null,\n\t\trestoreState: OverlayFocusRestoreState,\n\t): Component | null {\n\t\tif (restoreState.status === \"blocked\" && restoreState.blockedBy === previousFocus) {\n\t\t\tif (restoreState.resume.status === \"focus-target\" || !this.isComponentMounted(restoreState.blockedBy)) {\n\t\t\t\treturn this.resolveBlockedOverlayFocusResume(restoreState);\n\t\t\t}\n\t\t\tthis.overlayFocusRestore = {\n\t\t\t\tstatus: \"blocked\",\n\t\t\t\toverlay: restoreState.overlay,\n\t\t\t\tblockedBy: nextFocus,\n\t\t\t\tresume: restoreState.resume,\n\t\t\t};\n\t\t\treturn nextFocus;\n\t\t}\n\n\t\tconst previousFocusedOverlay = previousFocus\n\t\t\t? this.overlayStack.find((entry) => entry.component === previousFocus && this.isOverlayVisible(entry))\n\t\t\t: undefined;\n\t\tif (\n\t\t\tpreviousFocusedOverlay &&\n\t\t\trestoreState.status !== \"inactive\" &&\n\t\t\trestoreState.overlay === previousFocusedOverlay &&\n\t\t\t!this.isOverlayFocusAncestor(previousFocusedOverlay, nextFocus)\n\t\t) {\n\t\t\tthis.overlayFocusRestore = {\n\t\t\t\tstatus: \"blocked\",\n\t\t\t\toverlay: previousFocusedOverlay,\n\t\t\t\tblockedBy: nextFocus,\n\t\t\t\tresume: { status: \"restore-overlay\" },\n\t\t\t};\n\t\t}\n\t\treturn nextFocus;\n\t}\n\n\tprivate resolveNullFocus(\n\t\tpreviousFocus: Component | null,\n\t\trestoreState: OverlayFocusRestoreState,\n\t\toverlayFocusRestore: OverlayFocusRestorePolicy,\n\t): Component | null {\n\t\tif (restoreState.status === \"blocked\" && restoreState.blockedBy === previousFocus) {\n\t\t\treturn this.resolveBlockedOverlayFocusResume(restoreState);\n\t\t}\n\t\tif (overlayFocusRestore === \"clear\") this.clearOverlayFocusRestore();\n\t\treturn null;\n\t}\n\n\tprivate resolveFocusTarget(\n\t\tcomponent: Component | null,\n\t\toverlayFocusRestore: OverlayFocusRestorePolicy,\n\t): Component | null {\n\t\tconst previousFocus = this.focusedComponent;\n\t\tconst restoreState = this.getVisibleOverlayFocusRestore();\n\t\tif (component === null) return this.resolveNullFocus(previousFocus, restoreState, overlayFocusRestore);\n\t\tconst isOverlay = this.overlayStack.some((entry) => entry.component === component);\n\t\tif (isOverlay) return component;\n\t\treturn this.resolveNonOverlayFocus(component, previousFocus, restoreState);\n\t}\n\n\tprivate applyFocus(nextFocus: Component | null): void {\n\t\tif (isFocusable(this.focusedComponent)) this.focusedComponent.focused = false;\n\t\tthis.focusedComponent = nextFocus;\n\t\tif (isFocusable(nextFocus)) nextFocus.focused = true;\n\n\t\tconst focusedOverlay = nextFocus\n\t\t\t? this.overlayStack.find((entry) => entry.component === nextFocus && this.isOverlayVisible(entry))\n\t\t\t: undefined;\n\t\tif (focusedOverlay) this.overlayFocusRestore = { status: \"eligible\", overlay: focusedOverlay };\n\t}\n\n\tprivate setFocusInternal({ component, overlayFocusRestore }: FocusTransitionRequest): void {\n\t\tconst nextFocus = this.resolveFocusTarget(component, overlayFocusRestore);\n\t\tthis.applyFocus(nextFocus);\n\t}\n\n\tprivate clearOverlayFocusRestore(): void {\n\t\tthis.overlayFocusRestore = { status: \"inactive\" };\n\t}\n\n\tprivate clearOverlayFocusRestoreFor(overlay: OverlayStackEntry): void {\n\t\tif (this.overlayFocusRestore.status !== \"inactive\" && this.overlayFocusRestore.overlay === overlay) {\n\t\t\tthis.clearOverlayFocusRestore();\n\t\t}\n\t}\n\n\tprivate resolveBlockedOverlayFocusResume(restoreState: BlockedOverlayFocusRestoreState): Component | null {\n\t\tif (restoreState.resume.status === \"restore-overlay\") return restoreState.overlay.component;\n\t\tthis.clearOverlayFocusRestore();\n\t\treturn restoreState.resume.target;\n\t}\n\n\tprivate getVisibleOverlayFocusRestore(): OverlayFocusRestoreState {\n\t\tconst restoreState = this.overlayFocusRestore;\n\t\tif (restoreState.status === \"inactive\") return restoreState;\n\t\tif (!this.overlayStack.includes(restoreState.overlay) || !this.isOverlayVisible(restoreState.overlay)) {\n\t\t\treturn { status: \"inactive\" };\n\t\t}\n\t\treturn restoreState;\n\t}\n\n\tprivate isOverlayFocusAncestor(entry: OverlayStackEntry, component: Component): boolean {\n\t\tconst preFocusByComponent = new Map<Component, Component | null>();\n\t\tfor (const overlay of this.overlayStack) {\n\t\t\tif (!preFocusByComponent.has(overlay.component)) {\n\t\t\t\tpreFocusByComponent.set(overlay.component, overlay.preFocus);\n\t\t\t}\n\t\t}\n\n\t\tconst visited = new Set<Component>();\n\t\tlet current = entry.preFocus;\n\t\twhile (current && !visited.has(current)) {\n\t\t\tvisited.add(current);\n\t\t\tif (current === component) return true;\n\t\t\tcurrent = preFocusByComponent.get(current) ?? null;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate retargetOverlayPreFocus(removed: OverlayStackEntry): void {\n\t\tfor (const overlay of this.overlayStack) {\n\t\t\tif (overlay !== removed && overlay.preFocus === removed.component) {\n\t\t\t\toverlay.preFocus = removed.preFocus;\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected getMountedRoots(): readonly Component[] {\n\t\treturn this.children;\n\t}\n\n\tprivate isComponentMounted(component: Component): boolean {\n\t\treturn this.getMountedRoots().some((child) => this.containsComponent(child, component));\n\t}\n\n\tprivate containsComponent(root: Component, target: Component): boolean {\n\t\tif (root === target) return true;\n\t\tif (!(root instanceof Container)) return false;\n\t\treturn root.children.some((child) => this.containsComponent(child, target));\n\t}\n\n\tprivate applyBlockedOverlayUnfocus(\n\t\tentry: OverlayStackEntry,\n\t\trestoreState: OverlayFocusRestoreState,\n\t\toptions: OverlayUnfocusOptions | undefined,\n\t): boolean {\n\t\tif (\n\t\t\trestoreState.status !== \"blocked\" ||\n\t\t\trestoreState.overlay !== entry ||\n\t\t\tthis.focusedComponent !== restoreState.blockedBy\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tif (options) {\n\t\t\tthis.overlayFocusRestore = {\n\t\t\t\tstatus: \"blocked\",\n\t\t\t\toverlay: entry,\n\t\t\t\tblockedBy: restoreState.blockedBy,\n\t\t\t\tresume: { status: \"focus-target\", target: options.target },\n\t\t\t};\n\t\t} else {\n\t\t\tthis.clearOverlayFocusRestore();\n\t\t}\n\t\tthis.requestRender();\n\t\treturn true;\n\t}\n\n\tprivate unfocusOverlay(entry: OverlayStackEntry, options: OverlayUnfocusOptions | undefined): void {\n\t\tconst isFocused = this.focusedComponent === entry.component;\n\t\tconst restoreState = this.overlayFocusRestore;\n\t\tconst hasPendingRestore = restoreState.status !== \"inactive\" && restoreState.overlay === entry;\n\t\tif (!isFocused && !hasPendingRestore) return;\n\t\tif (this.applyBlockedOverlayUnfocus(entry, restoreState, options)) return;\n\n\t\tthis.clearOverlayFocusRestoreFor(entry);\n\t\tif (isFocused || options) {\n\t\t\tconst topVisible = this.getTopmostVisibleOverlay();\n\t\t\tconst fallbackTarget = topVisible && topVisible !== entry ? topVisible.component : entry.preFocus;\n\t\t\tthis.setFocus(options ? options.target : fallbackTarget);\n\t\t}\n\t\tthis.requestRender();\n\t}\n\n\t/**\n\t * Show an overlay component with configurable positioning and sizing.\n\t * Returns a handle to control the overlay's visibility.\n\t */\n\tshowOverlay(component: Component, options?: OverlayOptions): OverlayHandle {\n\t\tconst entry: OverlayStackEntry = {\n\t\t\tcomponent,\n\t\t\t...(options === undefined ? {} : { options }),\n\t\t\tpreFocus: this.focusedComponent,\n\t\t\thidden: false,\n\t\t\tfocusOrder: ++this.focusOrderCounter,\n\t\t\tvisible: false,\n\t\t};\n\t\tthis.overlayStack.push(entry);\n\t\tentry.visible = this.isOverlayVisible(entry);\n\t\tthis.onOverlayStackChanged();\n\t\t// Only focus if overlay is actually visible\n\t\tif (!options?.nonCapturing && this.isOverlayVisible(entry)) {\n\t\t\tthis.setFocus(component);\n\t\t}\n\t\tthis.terminal.hideCursor();\n\t\tthis.requestRender();\n\n\t\t// Return handle for controlling this overlay\n\t\treturn {\n\t\t\thide: () => {\n\t\t\t\tconst index = this.overlayStack.indexOf(entry);\n\t\t\t\tif (index !== -1) {\n\t\t\t\t\tthis.clearOverlayFocusRestoreFor(entry);\n\t\t\t\t\tthis.retargetOverlayPreFocus(entry);\n\t\t\t\t\tthis.overlayStack.splice(index, 1);\n\t\t\t\t\tthis.onOverlayStackChanged();\n\t\t\t\t\t// Restore focus if this overlay had focus\n\t\t\t\t\tif (this.focusedComponent === component) {\n\t\t\t\t\t\tconst topVisible = this.getTopmostVisibleOverlay();\n\t\t\t\t\t\tthis.setFocus(topVisible?.component ?? entry.preFocus);\n\t\t\t\t\t}\n\t\t\t\t\tif (this.overlayStack.length === 0) this.terminal.hideCursor();\n\t\t\t\t\tthis.requestRender();\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetHidden: (hidden: boolean) => {\n\t\t\t\tif (entry.hidden === hidden) return;\n\t\t\t\tentry.hidden = hidden;\n\t\t\t\tentry.visible = this.isOverlayVisible(entry);\n\t\t\t\t// Update focus when hiding/showing\n\t\t\t\tif (hidden) {\n\t\t\t\t\tthis.clearOverlayFocusRestoreFor(entry);\n\t\t\t\t\t// If this overlay had focus, move focus to next visible or preFocus\n\t\t\t\t\tif (this.focusedComponent === component) {\n\t\t\t\t\t\tconst topVisible = this.getTopmostVisibleOverlay();\n\t\t\t\t\t\tthis.setFocus(topVisible?.component ?? entry.preFocus);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Restore focus to this overlay when showing (if it's actually visible)\n\t\t\t\t\tif (!options?.nonCapturing && this.isOverlayVisible(entry)) {\n\t\t\t\t\t\tentry.focusOrder = ++this.focusOrderCounter;\n\t\t\t\t\t\tthis.setFocus(component);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.onOverlayStackChanged();\n\t\t\t\tthis.requestRender();\n\t\t\t},\n\t\t\tisHidden: () => entry.hidden,\n\t\t\tfocus: () => {\n\t\t\t\tif (!this.overlayStack.includes(entry) || !this.isOverlayVisible(entry)) return;\n\t\t\t\tentry.focusOrder = ++this.focusOrderCounter;\n\t\t\t\tthis.setFocus(component);\n\t\t\t\tthis.requestRender();\n\t\t\t},\n\t\t\tunfocus: (unfocusOptions) => this.unfocusOverlay(entry, unfocusOptions),\n\t\t\tisFocused: () => this.focusedComponent === component,\n\t\t};\n\t}\n\n\t/** Hide the topmost overlay and restore previous focus. */\n\thideOverlay(): void {\n\t\tconst overlay = this.overlayStack[this.overlayStack.length - 1];\n\t\tif (!overlay) return;\n\t\tthis.clearOverlayFocusRestoreFor(overlay);\n\t\tthis.retargetOverlayPreFocus(overlay);\n\t\tthis.overlayStack.pop();\n\t\tthis.onOverlayStackChanged();\n\t\tif (this.focusedComponent === overlay.component) {\n\t\t\t// Find topmost visible overlay, or fall back to preFocus\n\t\t\tconst topVisible = this.getTopmostVisibleOverlay();\n\t\t\tthis.setFocus(topVisible?.component ?? overlay.preFocus);\n\t\t}\n\t\tif (this.overlayStack.length === 0) this.terminal.hideCursor();\n\t\tthis.requestRender();\n\t}\n\n\t/** Check if there are any visible overlays */\n\thasOverlay(): boolean {\n\t\treturn this.overlayStack.some((o) => this.isOverlayVisible(o));\n\t}\n\n\tprotected hasCapturingOverlay(): boolean {\n\t\treturn this.overlayStack.some((o) => !o.options?.nonCapturing && this.isOverlayVisible(o));\n\t}\n\n\t/** Check if an overlay entry is currently visible */\n\tprivate isOverlayVisible(entry: OverlayStackEntry): boolean {\n\t\tif (entry.hidden) return false;\n\t\tif (entry.options?.visible) {\n\t\t\treturn entry.options.visible(this.terminal.columns, this.terminal.rows);\n\t\t}\n\t\treturn true;\n\t}\n\n\t/** Find the visual-frontmost visible capturing overlay, if any */\n\tprivate getTopmostVisibleOverlay(): OverlayStackEntry | undefined {\n\t\tlet topmost: OverlayStackEntry | undefined;\n\t\tfor (const overlay of this.overlayStack) {\n\t\t\tif (overlay.options?.nonCapturing || !this.isOverlayVisible(overlay)) continue;\n\t\t\tif (!topmost || overlay.focusOrder > topmost.focusOrder) {\n\t\t\t\ttopmost = overlay;\n\t\t\t}\n\t\t}\n\t\treturn topmost;\n\t}\n\n\tprivate refreshOverlayVisibility(): OverlayStackEntry | undefined {\n\t\tlet newlyVisible: OverlayStackEntry | undefined;\n\t\tfor (const overlay of this.overlayStack) {\n\t\t\tconst visible = this.isOverlayVisible(overlay);\n\t\t\tif (visible && !overlay.visible && !overlay.options?.nonCapturing) {\n\t\t\t\tif (!newlyVisible || overlay.focusOrder > newlyVisible.focusOrder) newlyVisible = overlay;\n\t\t\t}\n\t\t\toverlay.visible = visible;\n\t\t}\n\t\treturn newlyVisible;\n\t}\n\n\tprivate retargetFocusFromHiddenOverlay(): void {\n\t\tconst focusedOverlay = this.overlayStack.find((overlay) => overlay.component === this.focusedComponent);\n\t\tif (!focusedOverlay || this.isOverlayVisible(focusedOverlay)) return;\n\t\tconst topVisible = this.getTopmostVisibleOverlay();\n\t\tif (topVisible) {\n\t\t\tthis.setFocus(topVisible.component);\n\t\t\treturn;\n\t\t}\n\t\tthis.setFocusInternal({ component: focusedOverlay.preFocus, overlayFocusRestore: \"preserve\" });\n\t}\n\n\tprivate focusNewlyVisibleOverlay(newlyVisible: OverlayStackEntry | undefined): void {\n\t\tif (!newlyVisible) return;\n\t\tconst currentFocusedOverlay = this.overlayStack.find(\n\t\t\t(overlay) => overlay.component === this.focusedComponent && this.isOverlayVisible(overlay),\n\t\t);\n\t\tif (!currentFocusedOverlay || newlyVisible.focusOrder > currentFocusedOverlay.focusOrder) {\n\t\t\tthis.setFocus(newlyVisible.component);\n\t\t}\n\t}\n\n\tprivate restoreVisibleOverlayFocus(): void {\n\t\tif (this.overlayStack.some((overlay) => overlay.component === this.focusedComponent)) return;\n\t\tconst restoreState = this.getVisibleOverlayFocusRestore();\n\t\tif (restoreState.status === \"eligible\") {\n\t\t\tthis.setFocus(restoreState.overlay.component);\n\t\t\treturn;\n\t\t}\n\t\tif (restoreState.status !== \"blocked\" || restoreState.blockedBy === this.focusedComponent) return;\n\t\tif (restoreState.resume.status === \"restore-overlay\") {\n\t\t\tthis.setFocus(restoreState.overlay.component);\n\t\t\treturn;\n\t\t}\n\t\tthis.clearOverlayFocusRestore();\n\t\tthis.setFocus(restoreState.resume.target);\n\t}\n\n\tprivate reconcileOverlayFocus(): void {\n\t\tconst newlyVisible = this.refreshOverlayVisibility();\n\t\tthis.retargetFocusFromHiddenOverlay();\n\t\tthis.focusNewlyVisibleOverlay(newlyVisible);\n\t\tthis.restoreVisibleOverlayFocus();\n\t}\n\n\toverride invalidate(): void {\n\t\tfor (const root of this.getMountedRoots()) root.invalidate();\n\t\tfor (const overlay of this.overlayStack) overlay.component.invalidate?.();\n\t}\n\n\tstart(): void {\n\t\tthis.stopped = false;\n\t\ttry {\n\t\t\tthis.beforeTerminalStart();\n\t\t\tthis.terminal.start(\n\t\t\t\t(data) => this.handleTerminalInput(data),\n\t\t\t\t() => {\n\t\t\t\t\tthis.reconcileOverlayFocus();\n\t\t\t\t\tthis.onTerminalResize();\n\t\t\t\t\tthis.requestRender();\n\t\t\t\t},\n\t\t\t);\n\t\t\tthis.afterTerminalStart();\n\t\t\tthis.terminal.hideCursor();\n\t\t\tthis.queryCellSize();\n\t\t\tthis.requestRender();\n\t\t} catch (error) {\n\t\t\t// A terminal may throw after partially entering raw or alternate-screen mode.\n\t\t\t// Route startup failures through the same complete cleanup path as signals.\n\t\t\ttry {\n\t\t\t\tthis.stop();\n\t\t\t} catch {\n\t\t\t\t// Preserve the startup failure; cleanup is best-effort but exhaustive.\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\taddInputListener(listener: TuiInputListener): () => void {\n\t\tthis.inputListeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.inputListeners.delete(listener);\n\t\t};\n\t}\n\n\tremoveInputListener(listener: TuiInputListener): void {\n\t\tthis.inputListeners.delete(listener);\n\t}\n\n\tprivate queryCellSize(): void {\n\t\t// Only query if terminal supports images (cell size is only used for image rendering)\n\t\tif (!getCapabilities().images) {\n\t\t\treturn;\n\t\t}\n\t\t// Query terminal for cell size in pixels: CSI 16 t\n\t\t// Response format: CSI 6 ; height ; width t\n\t\tthis.terminal.write(\"\\x1b[16t\");\n\t}\n\n\tstop(options?: TuiStopOptions): void {\n\t\tthis.stopped = true;\n\t\tthis.renderRequested = false;\n\t\tthis.cancelRenderTimer();\n\t\tlet failure: unknown;\n\t\tconst cleanup = (action: () => void): void => {\n\t\t\ttry {\n\t\t\t\taction();\n\t\t\t} catch (error) {\n\t\t\t\tfailure ??= error;\n\t\t\t}\n\t\t};\n\t\tcleanup(() => this.beforeTerminalStop(options));\n\t\tcleanup(() => this.terminal.showCursor());\n\t\tcleanup(() => this.terminal.stop());\n\t\t// Alternate-screen exit and capability restoration must run even when\n\t\t// keyboard/raw-mode shutdown reports an error.\n\t\tcleanup(() => this.afterTerminalStop(options));\n\t\tif (failure !== undefined) throw failure;\n\t}\n\n\trenderNow(force = false): void {\n\t\tif (force) this.resetRenderState();\n\t\tthis.renderRequested = false;\n\t\tthis.cancelRenderTimer();\n\t\tthis.lastRenderAt = performance.now();\n\t\tthis.doRender();\n\t}\n\n\trequestRender(force = false): void {\n\t\tif (force) {\n\t\t\tthis.resetRenderState();\n\t\t\tthis.requestImmediateRender();\n\t\t\treturn;\n\t\t}\n\t\tif (this.renderRequested) return;\n\t\tthis.renderRequested = true;\n\t\tprocess.nextTick(() => this.scheduleRender());\n\t}\n\n\tprivate requestImmediateRender(): void {\n\t\tthis.cancelRenderTimer();\n\t\tthis.renderRequested = true;\n\t\tif (this.immediateRenderScheduled) return;\n\t\tthis.immediateRenderScheduled = true;\n\t\tprocess.nextTick(() => {\n\t\t\tthis.immediateRenderScheduled = false;\n\t\t\tif (this.stopped || !this.renderRequested) return;\n\t\t\tthis.cancelRenderTimer();\n\t\t\tthis.renderRequested = false;\n\t\t\tthis.lastRenderAt = performance.now();\n\t\t\tthis.doRender();\n\t\t});\n\t}\n\n\tprivate cancelRenderTimer(): void {\n\t\tif (!this.renderTimer) return;\n\t\tclearTimeout(this.renderTimer);\n\t\tthis.renderTimer = undefined;\n\t}\n\n\tprivate scheduleRender(): void {\n\t\tif (this.stopped || this.renderTimer || !this.renderRequested) return;\n\t\tconst elapsed = performance.now() - this.lastRenderAt;\n\t\tconst delay = Math.max(0, TuiBase.MIN_RENDER_INTERVAL_MS - elapsed);\n\t\tthis.renderTimer = setTimeout(() => {\n\t\t\tthis.renderTimer = undefined;\n\t\t\tif (this.stopped || !this.renderRequested) return;\n\t\t\tthis.renderRequested = false;\n\t\t\tthis.lastRenderAt = performance.now();\n\t\t\tthis.doRender();\n\t\t\tif (this.renderRequested) this.scheduleRender();\n\t\t}, delay);\n\t}\n\n\tprivate applyInputListeners(data: string): string | undefined {\n\t\tif (this.inputListeners.size === 0) return data;\n\t\tlet current = data;\n\t\tfor (const listener of this.inputListeners) {\n\t\t\tconst result = listener(current);\n\t\t\tif (result?.consume) return undefined;\n\t\t\tif (result?.data !== undefined) current = result.data;\n\t\t}\n\t\treturn current.length === 0 ? undefined : current;\n\t}\n\n\tprivate handleTerminalInput(data: string): void {\n\t\tthis.reconcileOverlayFocus();\n\t\tconst filteredData = this.applyInputListeners(data);\n\t\tif (filteredData === undefined) return;\n\t\tdata = filteredData;\n\n\t\t// Consume terminal cell size responses without blocking unrelated input.\n\t\tif (this.consumeCellSizeResponse(data)) return;\n\n\t\t// Global debug key handler (Shift+Ctrl+D)\n\t\tif (matchesKey(data, \"shift+ctrl+d\") && this.onDebug) {\n\t\t\tthis.onDebug();\n\t\t\treturn;\n\t\t}\n\n\t\t// Pass input to focused component (including Ctrl+C).\n\t\t// The focused component can decide how to handle Ctrl+C.\n\t\tif (!this.focusedComponent?.handleInput) return;\n\t\t// Filter out key release events unless component opts in.\n\t\tif (isKeyRelease(data) && !this.focusedComponent.wantsKeyRelease) return;\n\t\tthis.focusedComponent.handleInput(data);\n\t\tthis.requestImmediateRender();\n\t}\n\n\tprivate consumeCellSizeResponse(data: string): boolean {\n\t\t// Response format: ESC [ 6 ; height ; width t\n\t\tconst match = data.match(/^\\x1b\\[6;(\\d+);(\\d+)t$/);\n\t\tif (!match) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst heightPx = parseInt(match[1], 10);\n\t\tconst widthPx = parseInt(match[2], 10);\n\t\tif (heightPx <= 0 || widthPx <= 0) {\n\t\t\treturn true;\n\t\t}\n\n\t\tsetCellDimensions({ widthPx, heightPx });\n\t\t// Invalidate all components so images re-render with correct dimensions.\n\t\tthis.invalidate();\n\t\tthis.requestRender();\n\t\treturn true;\n\t}\n\n\tprivate resolveOverlayBounds(options: OverlayOptions, termWidth: number, termHeight: number): OverlayLayoutBounds {\n\t\tconst margin =\n\t\t\ttypeof options.margin === \"number\"\n\t\t\t\t? { top: options.margin, right: options.margin, bottom: options.margin, left: options.margin }\n\t\t\t\t: (options.margin ?? {});\n\t\tconst marginTop = Math.max(0, margin.top ?? 0);\n\t\tconst marginRight = Math.max(0, margin.right ?? 0);\n\t\tconst marginBottom = Math.max(0, margin.bottom ?? 0);\n\t\tconst marginLeft = Math.max(0, margin.left ?? 0);\n\t\treturn {\n\t\t\tmarginTop,\n\t\t\tmarginRight,\n\t\t\tmarginBottom,\n\t\t\tmarginLeft,\n\t\t\tavailableWidth: Math.max(1, termWidth - marginLeft - marginRight),\n\t\t\tavailableHeight: Math.max(1, termHeight - marginTop - marginBottom),\n\t\t};\n\t}\n\n\tprivate resolveOverlayWidth(options: OverlayOptions, termWidth: number, bounds: OverlayLayoutBounds): number {\n\t\tlet width = parseSizeValue(options.width, termWidth) ?? Math.min(80, bounds.availableWidth);\n\t\tif (options.minWidth !== undefined) width = Math.max(width, options.minWidth);\n\t\treturn Math.max(1, Math.min(width, bounds.availableWidth));\n\t}\n\n\tprivate resolveOverlayMaxHeight(\n\t\toptions: OverlayOptions,\n\t\ttermHeight: number,\n\t\tbounds: OverlayLayoutBounds,\n\t): number | undefined {\n\t\tconst maxHeight = parseSizeValue(options.maxHeight, termHeight);\n\t\treturn maxHeight === undefined ? undefined : Math.max(1, Math.min(maxHeight, bounds.availableHeight));\n\t}\n\n\tprivate resolveOverlayRow(options: OverlayOptions, overlayHeight: number, bounds: OverlayLayoutBounds): number {\n\t\tif (options.row === undefined) {\n\t\t\treturn this.resolveAnchorRow(\n\t\t\t\toptions.anchor ?? \"center\",\n\t\t\t\toverlayHeight,\n\t\t\t\tbounds.availableHeight,\n\t\t\t\tbounds.marginTop,\n\t\t\t);\n\t\t}\n\t\tif (typeof options.row === \"number\") return options.row;\n\t\tconst match = options.row.match(/^(\\d+(?:\\.\\d+)?)%$/);\n\t\tif (!match) return this.resolveAnchorRow(\"center\", overlayHeight, bounds.availableHeight, bounds.marginTop);\n\t\tconst maxRow = Math.max(0, bounds.availableHeight - overlayHeight);\n\t\treturn bounds.marginTop + Math.floor(maxRow * (parseFloat(match[1]) / 100));\n\t}\n\n\tprivate resolveOverlayColumn(options: OverlayOptions, width: number, bounds: OverlayLayoutBounds): number {\n\t\tif (options.col === undefined) {\n\t\t\treturn this.resolveAnchorCol(options.anchor ?? \"center\", width, bounds.availableWidth, bounds.marginLeft);\n\t\t}\n\t\tif (typeof options.col === \"number\") return options.col;\n\t\tconst match = options.col.match(/^(\\d+(?:\\.\\d+)?)%$/);\n\t\tif (!match) return this.resolveAnchorCol(\"center\", width, bounds.availableWidth, bounds.marginLeft);\n\t\tconst maxCol = Math.max(0, bounds.availableWidth - width);\n\t\treturn bounds.marginLeft + Math.floor(maxCol * (parseFloat(match[1]) / 100));\n\t}\n\n\t/** Resolve overlay layout from options. */\n\tprivate resolveOverlayLayout(\n\t\toptions: OverlayOptions | undefined,\n\t\toverlayHeight: number,\n\t\ttermWidth: number,\n\t\ttermHeight: number,\n\t): ResolvedOverlayLayout {\n\t\tconst resolvedOptions = options ?? {};\n\t\tconst bounds = this.resolveOverlayBounds(resolvedOptions, termWidth, termHeight);\n\t\tconst width = this.resolveOverlayWidth(resolvedOptions, termWidth, bounds);\n\t\tconst maxHeight = this.resolveOverlayMaxHeight(resolvedOptions, termHeight, bounds);\n\t\tconst effectiveHeight = maxHeight === undefined ? overlayHeight : Math.min(overlayHeight, maxHeight);\n\t\tlet row = this.resolveOverlayRow(resolvedOptions, effectiveHeight, bounds) + (resolvedOptions.offsetY ?? 0);\n\t\tlet col = this.resolveOverlayColumn(resolvedOptions, width, bounds) + (resolvedOptions.offsetX ?? 0);\n\t\trow = Math.max(bounds.marginTop, Math.min(row, termHeight - bounds.marginBottom - effectiveHeight));\n\t\tcol = Math.max(bounds.marginLeft, Math.min(col, termWidth - bounds.marginRight - width));\n\t\treturn { width, row, col, maxHeight };\n\t}\n\n\tprivate resolveAnchorRow(anchor: OverlayAnchor, height: number, availHeight: number, marginTop: number): number {\n\t\tswitch (anchor) {\n\t\t\tcase \"top-left\":\n\t\t\tcase \"top-center\":\n\t\t\tcase \"top-right\":\n\t\t\t\treturn marginTop;\n\t\t\tcase \"bottom-left\":\n\t\t\tcase \"bottom-center\":\n\t\t\tcase \"bottom-right\":\n\t\t\t\treturn marginTop + availHeight - height;\n\t\t\tcase \"left-center\":\n\t\t\tcase \"center\":\n\t\t\tcase \"right-center\":\n\t\t\t\treturn marginTop + Math.floor((availHeight - height) / 2);\n\t\t}\n\t}\n\n\tprivate resolveAnchorCol(anchor: OverlayAnchor, width: number, availWidth: number, marginLeft: number): number {\n\t\tswitch (anchor) {\n\t\t\tcase \"top-left\":\n\t\t\tcase \"left-center\":\n\t\t\tcase \"bottom-left\":\n\t\t\t\treturn marginLeft;\n\t\t\tcase \"top-right\":\n\t\t\tcase \"right-center\":\n\t\t\tcase \"bottom-right\":\n\t\t\t\treturn marginLeft + availWidth - width;\n\t\t\tcase \"top-center\":\n\t\t\tcase \"center\":\n\t\t\tcase \"bottom-center\":\n\t\t\t\treturn marginLeft + Math.floor((availWidth - width) / 2);\n\t\t}\n\t}\n\n\tprivate prepareOverlayRenderPlan(baseLineCount: number, termWidth: number, termHeight: number): OverlayRenderPlan {\n\t\tconst visibleEntries = this.overlayStack.filter((entry) => this.isOverlayVisible(entry));\n\t\tvisibleEntries.sort((left, right) => left.focusOrder - right.focusOrder);\n\t\tconst overlays: RenderedOverlay[] = [];\n\t\tlet minimumLineCount = baseLineCount;\n\t\tfor (const entry of visibleEntries) {\n\t\t\tconst { width, maxHeight } = this.resolveOverlayLayout(entry.options, 0, termWidth, termHeight);\n\t\t\tlet overlayLines = entry.component.render(width);\n\t\t\tif (maxHeight !== undefined && overlayLines.length > maxHeight) {\n\t\t\t\toverlayLines = overlayLines.slice(0, maxHeight);\n\t\t\t}\n\t\t\tconst { row, col } = this.resolveOverlayLayout(entry.options, overlayLines.length, termWidth, termHeight);\n\t\t\toverlays.push({ lines: overlayLines, row, col, width });\n\t\t\tminimumLineCount = Math.max(minimumLineCount, row + overlayLines.length);\n\t\t}\n\t\treturn { overlays, minimumLineCount };\n\t}\n\n\tprivate compositeRenderedOverlay(\n\t\tresult: string[],\n\t\toverlay: RenderedOverlay,\n\t\tviewportStart: number,\n\t\ttermWidth: number,\n\t): void {\n\t\tfor (let lineIndex = 0; lineIndex < overlay.lines.length; lineIndex++) {\n\t\t\tconst targetIndex = viewportStart + overlay.row + lineIndex;\n\t\t\tif (targetIndex < 0 || targetIndex >= result.length) continue;\n\t\t\tconst overlayLine = overlay.lines[lineIndex]!;\n\t\t\tconst truncatedLine =\n\t\t\t\tvisibleWidth(overlayLine) > overlay.width\n\t\t\t\t\t? sliceByColumn(overlayLine, 0, overlay.width, true)\n\t\t\t\t\t: overlayLine;\n\t\t\tresult[targetIndex] = this.compositeLineAt(\n\t\t\t\tresult[targetIndex]!,\n\t\t\t\ttruncatedLine,\n\t\t\t\toverlay.col,\n\t\t\t\toverlay.width,\n\t\t\t\ttermWidth,\n\t\t\t);\n\t\t}\n\t}\n\n\t/** Composite all overlays into content lines (sorted by focusOrder, higher = on top). */\n\tprotected compositeOverlays(lines: string[], termWidth: number, termHeight: number): string[] {\n\t\tif (this.overlayStack.length === 0) return lines;\n\t\tconst result = [...lines];\n\t\tconst plan = this.prepareOverlayRenderPlan(result.length, termWidth, termHeight);\n\t\tconst workingHeight = Math.max(result.length, termHeight, plan.minimumLineCount);\n\t\twhile (result.length < workingHeight) result.push(\"\");\n\t\tconst viewportStart = Math.max(0, workingHeight - termHeight);\n\t\tfor (const overlay of plan.overlays) {\n\t\t\tthis.compositeRenderedOverlay(result, overlay, viewportStart, termWidth);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprotected applyLineResets(lines: string[]): string[] {\n\t\tconst reset = SEGMENT_RESET;\n\t\tfor (let i = 0; i < lines.length; i++) {\n\t\t\tconst line = lines[i];\n\t\t\tif (!isImageLine(line)) {\n\t\t\t\tlines[i] = normalizeTerminalOutput(line) + reset;\n\t\t\t}\n\t\t}\n\t\treturn lines;\n\t}\n\n\tprivate compositeLineAt(\n\t\tbaseLine: string,\n\t\toverlayLine: string,\n\t\tstartCol: number,\n\t\toverlayWidth: number,\n\t\ttotalWidth: number,\n\t): string {\n\t\treturn compositeTuiLine(baseLine, overlayLine, startCol, overlayWidth, totalWidth);\n\t}\n\n\t/**\n\t * Find and extract cursor position from rendered lines.\n\t * Searches for CURSOR_MARKER, calculates its position, and strips it from the output.\n\t * Only scans the bottom terminal height lines (visible viewport).\n\t * @param lines - Rendered lines to search\n\t * @param height - Terminal height (visible viewport size)\n\t * @returns Cursor position { row, col } or null if no marker found\n\t */\n\tprotected extractCursorPosition(lines: string[], height: number): RenderedCursorPosition | null {\n\t\t// Only scan the bottom `height` lines (visible viewport)\n\t\tconst viewportTop = Math.max(0, lines.length - height);\n\t\tfor (let row = lines.length - 1; row >= viewportTop; row--) {\n\t\t\tconst line = lines[row];\n\t\t\tconst markerIndex = line.indexOf(CURSOR_MARKER);\n\t\t\tif (markerIndex !== -1) {\n\t\t\t\t// Calculate visual column (width of text before marker)\n\t\t\t\tconst beforeMarker = line.slice(0, markerIndex);\n\t\t\t\tconst col = visibleWidth(beforeMarker);\n\n\t\t\t\t// Strip marker from the line\n\t\t\t\tlines[row] = line.slice(0, markerIndex) + line.slice(markerIndex + CURSOR_MARKER.length);\n\n\t\t\t\treturn { row, col };\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n}\n"]}
|
package/dist/undo-stack.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"undo-stack.d.ts","sourceRoot":"","sources":["../src/undo-stack.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,qBAAa,SAAS,CAAC,CAAC;IACvB,OAAO,CAAC,KAAK,CAAW;IAExB,2DAA2D;IAC3D,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAEnB;IAED,sEAAsE;IACtE,GAAG,IAAI,CAAC,GAAG,SAAS,CAEnB;IAED,4BAA4B;IAC5B,KAAK,IAAI,IAAI,CAEZ;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;CACD"
|
|
1
|
+
{"version":3,"file":"undo-stack.d.ts","sourceRoot":"","sources":["../src/undo-stack.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,qBAAa,SAAS,CAAC,CAAC;IACvB,OAAO,CAAC,KAAK,CAAW;IAExB,2DAA2D;IAC3D,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAEnB;IAED,sEAAsE;IACtE,GAAG,IAAI,CAAC,GAAG,SAAS,CAEnB;IAED,4BAA4B;IAC5B,KAAK,IAAI,IAAI,CAEZ;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;CACD"}
|
package/dist/undo-stack.js
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
* directly (no re-cloning) since they are already detached.
|
|
6
6
|
*/
|
|
7
7
|
export class UndoStack {
|
|
8
|
-
|
|
8
|
+
constructor() {
|
|
9
|
+
this.stack = [];
|
|
10
|
+
}
|
|
9
11
|
/** Push a deep clone of the given state onto the stack. */
|
|
10
12
|
push(state) {
|
|
11
13
|
this.stack.push(structuredClone(state));
|
package/dist/undo-stack.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"undo-stack.js","sourceRoot":"","sources":["../src/undo-stack.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,OAAO,SAAS;
|
|
1
|
+
{"version":3,"file":"undo-stack.js","sourceRoot":"","sources":["../src/undo-stack.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,OAAO,SAAS;IAAtB;QACS,UAAK,GAAQ,EAAE,CAAC;IAoBzB,CAAC;IAlBA,2DAA2D;IAC3D,IAAI,CAAC,KAAQ;QACZ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;IACzC,CAAC;IAED,sEAAsE;IACtE,GAAG;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;IACzB,CAAC;IAED,4BAA4B;IAC5B,KAAK;QACJ,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IACvB,CAAC;IAED,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC1B,CAAC;CACD","sourcesContent":["/**\n * Generic undo stack with clone-on-push semantics.\n *\n * Stores deep clones of state snapshots. Popped snapshots are returned\n * directly (no re-cloning) since they are already detached.\n */\nexport class UndoStack<S> {\n\tprivate stack: S[] = [];\n\n\t/** Push a deep clone of the given state onto the stack. */\n\tpush(state: S): void {\n\t\tthis.stack.push(structuredClone(state));\n\t}\n\n\t/** Pop and return the most recent snapshot, or undefined if empty. */\n\tpop(): S | undefined {\n\t\treturn this.stack.pop();\n\t}\n\n\t/** Remove all snapshots. */\n\tclear(): void {\n\t\tthis.stack.length = 0;\n\t}\n\n\tget length(): number {\n\t\treturn this.stack.length;\n\t}\n}\n"]}
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAAC,SAAS,CAErD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAAC,SAAS,CAEjD;AA4ED,UAAU,oBAAoB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACd;AAED,UAAU,aAAa;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CACf;AAyID;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAuDhD;AAED,iFAAiF;AACjF,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAc1D;AAGD,UAAU,iBAAiB;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACZ;AAmBD,mFAAmF;AACnF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAqBhG;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAoBpF;AAaD,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAsB3D;AAqBD,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAO9E;AA0UD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAuBtE;AA+ED,eAAO,MAAM,iBAAiB,QAAyC,CAAC;AAExE;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAyED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CASzG;AAsID;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC9B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,MAAc,EACxB,GAAG,GAAE,OAAe,GAClB,MAAM,CAUR;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,MAAM,CAEpG;AAmCD,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,oBAAoB,CAenH;AAKD,UAAU,qBAAqB;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACnB;AA4DD;;;;GAIG;AACH,wBAAgB,eAAe,CAC9B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,WAAW,UAAQ,GACjB,qBAAqB,CAkCvB","sourcesContent":["import { eastAsianWidth } from \"get-east-asian-width\";\n\n// segmenters (shared instance)\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: \"grapheme\" });\nconst wordSegmenter = new Intl.Segmenter(undefined, { granularity: \"word\" });\n\n/**\n * Get the shared grapheme segmenter instance.\n */\nexport function getGraphemeSegmenter(): Intl.Segmenter {\n\treturn graphemeSegmenter;\n}\n\n/**\n * Get the shared word segmenter instance.\n */\nexport function getWordSegmenter(): Intl.Segmenter {\n\treturn wordSegmenter;\n}\n\n/**\n * Check if a grapheme cluster (after segmentation) could possibly be an RGI emoji.\n * This is a fast heuristic to avoid the expensive rgiEmojiRegex test.\n * The tested Unicode blocks are deliberately broad to account for future\n * Unicode additions.\n */\nfunction couldBeEmoji(segment: string): boolean {\n\tconst cp = segment.codePointAt(0)!;\n\treturn (\n\t\t(cp >= 0x1f000 && cp <= 0x1fbff) || // Emoji and Pictograph\n\t\t(cp >= 0x2300 && cp <= 0x23ff) || // Misc technical\n\t\t(cp >= 0x2600 && cp <= 0x27bf) || // Misc symbols, dingbats\n\t\t(cp >= 0x2b50 && cp <= 0x2b55) || // Specific stars/circles\n\t\tsegment.includes(\"\\uFE0F\") || // Contains VS16 (emoji presentation selector)\n\t\tsegment.length > 2 // Multi-codepoint sequences (ZWJ, skin tones, etc.)\n\t);\n}\n\n// Regexes for character classification (same as string-width library)\nconst zeroWidthRegex = /^(?:\\p{Default_Ignorable_Code_Point}|\\p{Control}|\\p{Mark}|\\p{Surrogate})+$/v;\nconst leadingNonPrintingRegex = /^[\\p{Default_Ignorable_Code_Point}\\p{Control}\\p{Format}\\p{Mark}\\p{Surrogate}]+/v;\nconst nonPrintingCharRegex = /^(?:\\p{Default_Ignorable_Code_Point}|\\p{Control}|\\p{Format}|\\p{Mark}|\\p{Surrogate})$/v;\nconst markCharRegex = /^\\p{Mark}$/v;\n// Marks that terminals allocate cells for when attached to a base character.\n// This includes Unicode spacing marks and non-spacing exceptions in legacy wcwidth tables.\nconst terminalSpacingMarkRegex =\n\t/^(?:[\\p{Spacing_Mark}--[\\u1734\\u302E\\u302F]]|[\\u065F\\u0F7F\\u102B\\u102C\\u1031\\u1033-\\u1035\\u1038\\u103A-\\u103E])+$/v;\nconst rgiEmojiRegex = /^\\p{RGI_Emoji}$/v;\n\n// Cache for non-ASCII strings\nconst WIDTH_CACHE_SIZE = 512;\nconst widthCache = new Map<string, number>();\n\nfunction isPrintableAscii(str: string): boolean {\n\tfor (let i = 0; i < str.length; i++) {\n\t\tconst code = str.charCodeAt(i);\n\t\tif (code < 0x20 || code > 0x7e) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\ninterface FragmentTruncationState {\n\ttext: string;\n\twidth: number;\n\tpendingAnsi: string;\n}\n\nfunction appendPendingAnsi(state: FragmentTruncationState): void {\n\tif (!state.pendingAnsi) return;\n\tstate.text += state.pendingAnsi;\n\tstate.pendingAnsi = \"\";\n}\n\nfunction appendVisibleFragment(\n\tstate: FragmentTruncationState,\n\tfragment: string,\n\tfragmentWidth: number,\n\tmaxWidth: number,\n): boolean {\n\tif (state.width + fragmentWidth > maxWidth) return false;\n\tappendPendingAnsi(state);\n\tstate.text += fragment;\n\tstate.width += fragmentWidth;\n\treturn true;\n}\n\nfunction appendGraphemeRun(state: FragmentTruncationState, text: string, maxWidth: number): boolean {\n\tfor (const { segment } of graphemeSegmenter.segment(text)) {\n\t\tif (!appendVisibleFragment(state, segment, graphemeWidth(segment), maxWidth)) return false;\n\t}\n\treturn true;\n}\ninterface TerminalTextFragment {\n\ttext: string;\n\twidth: number;\n}\n\ninterface AnsiCodeMatch {\n\tcode: string;\n\tlength: number;\n}\n\nfunction truncateStyledFragment(state: FragmentTruncationState, text: string, maxWidth: number): void {\n\tlet index = 0;\n\twhile (index < text.length) {\n\t\tconst ansi = extractAnsiCode(text, index);\n\t\tif (ansi) {\n\t\t\tstate.pendingAnsi += ansi.code;\n\t\t\tindex += ansi.length;\n\t\t\tcontinue;\n\t\t}\n\t\tif (text[index] === \"\\t\") {\n\t\t\tif (!appendVisibleFragment(state, \"\\t\", 3, maxWidth)) return;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\t\tlet end = index;\n\t\twhile (end < text.length && text[end] !== \"\\t\" && !extractAnsiCode(text, end)) end++;\n\t\tif (!appendGraphemeRun(state, text.slice(index, end), maxWidth)) return;\n\t\tindex = end;\n\t}\n}\n\nfunction truncateFragmentToWidth(text: string, maxWidth: number): TerminalTextFragment {\n\tif (maxWidth <= 0 || text.length === 0) return { text: \"\", width: 0 };\n\tif (isPrintableAscii(text)) {\n\t\tconst clipped = text.slice(0, maxWidth);\n\t\treturn { text: clipped, width: clipped.length };\n\t}\n\tconst state: FragmentTruncationState = { text: \"\", width: 0, pendingAnsi: \"\" };\n\tif (!text.includes(\"\\x1b\") && !text.includes(\"\\t\")) {\n\t\tappendGraphemeRun(state, text, maxWidth);\n\t} else {\n\t\ttruncateStyledFragment(state, text, maxWidth);\n\t}\n\treturn { text: state.text, width: state.width };\n}\n\nfunction finalizeTruncatedResult(\n\tprefix: string,\n\tprefixWidth: number,\n\tellipsis: string,\n\tellipsisWidth: number,\n\tmaxWidth: number,\n\tpad: boolean,\n): string {\n\tconst reset = \"\\x1b[0m\";\n\tconst hyperlinkClose = getActiveOsc8Close(prefix);\n\tconst visibleWidth = prefixWidth + ellipsisWidth;\n\tlet result: string;\n\n\tif (ellipsis.length > 0) {\n\t\tresult = `${prefix}${hyperlinkClose}${reset}${ellipsis}${reset}`;\n\t} else {\n\t\tresult = `${prefix}${hyperlinkClose}${reset}`;\n\t}\n\n\treturn pad ? result + \" \".repeat(Math.max(0, maxWidth - visibleWidth)) : result;\n}\n\n/**\n * Calculate the terminal width of a single grapheme cluster.\n * Based on code from the string-width library, but includes a possible-emoji\n * check to avoid running the RGI_Emoji regex unnecessarily.\n */\nfunction trailingCodePointWidth(codePoint: number, followsMark: boolean): number {\n\tif (followsMark || (codePoint >= 0xff00 && codePoint <= 0xffef)) {\n\t\t// Indic consonants after marks and halfwidth/fullwidth forms.\n\t\treturn eastAsianWidth(codePoint);\n\t}\n\tif (codePoint === 0x0e33 || codePoint === 0x0eb3) {\n\t\t// Thai/Lao AM vowels.\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nfunction trailingGraphemeWidth(base: string): number {\n\tlet width = 0;\n\tlet followsMark = false;\n\tfor (const char of [...base].slice(1)) {\n\t\tif (terminalSpacingMarkRegex.test(char)) {\n\t\t\twidth += 1;\n\t\t\tfollowsMark = false;\n\t\t\tcontinue;\n\t\t}\n\t\tif (markCharRegex.test(char)) {\n\t\t\tfollowsMark = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (nonPrintingCharRegex.test(char)) continue;\n\t\twidth += trailingCodePointWidth(char.codePointAt(0)!, followsMark);\n\t\tfollowsMark = false;\n\t}\n\treturn width;\n}\n\nfunction graphemeWidth(segment: string): number {\n\tif (segment === \"\\t\") {\n\t\treturn 3;\n\t}\n\n\t// Some marks occupy cells even without a base character.\n\tif (terminalSpacingMarkRegex.test(segment)) {\n\t\treturn [...segment].length;\n\t}\n\n\t// Zero-width clusters\n\tif (zeroWidthRegex.test(segment)) {\n\t\treturn 0;\n\t}\n\n\t// Emoji check with pre-filter\n\tif (couldBeEmoji(segment) && rgiEmojiRegex.test(segment)) {\n\t\treturn 2;\n\t}\n\n\t// Get base visible codepoint\n\tconst base = segment.replace(leadingNonPrintingRegex, \"\");\n\tconst cp = base.codePointAt(0);\n\tif (cp === undefined) {\n\t\treturn 0;\n\t}\n\n\t// Regional indicator symbols (U+1F1E6..U+1F1FF) are often rendered as\n\t// full-width emoji in terminals, even when isolated during streaming.\n\t// Keep width conservative (2) to avoid terminal auto-wrap drift artifacts.\n\tif (cp >= 0x1f1e6 && cp <= 0x1f1ff) {\n\t\treturn 2;\n\t}\n\n\t// Intl.Segmenter can group multiple terminal-spacing code points into one\n\t// grapheme. Count trailing visible code points that terminals may allocate\n\t// cells for.\n\treturn eastAsianWidth(cp) + trailingGraphemeWidth(base);\n}\n\n/**\n * Calculate the visible width of a string in terminal columns.\n */\nexport function visibleWidth(str: string): number {\n\tif (str.length === 0) {\n\t\treturn 0;\n\t}\n\n\t// Fast path: pure ASCII printable\n\tif (isPrintableAscii(str)) {\n\t\treturn str.length;\n\t}\n\n\t// Check cache\n\tconst cached = widthCache.get(str);\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\n\t// Normalize: tabs to 3 spaces, strip ANSI escape codes\n\tlet clean = str;\n\tif (str.includes(\"\\t\")) {\n\t\tclean = clean.replace(/\\t/g, \" \");\n\t}\n\tif (clean.includes(\"\\x1b\")) {\n\t\t// Strip supported ANSI/OSC/APC escape sequences in one pass.\n\t\t// This covers CSI styling/cursor codes, OSC hyperlinks and prompt markers,\n\t\t// and APC sequences like CURSOR_MARKER.\n\t\tlet stripped = \"\";\n\t\tlet i = 0;\n\t\twhile (i < clean.length) {\n\t\t\tconst ansi = extractAnsiCode(clean, i);\n\t\t\tif (ansi) {\n\t\t\t\ti += ansi.length;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tstripped += clean[i];\n\t\t\ti++;\n\t\t}\n\t\tclean = stripped;\n\t}\n\n\t// Calculate width\n\tlet width = 0;\n\tfor (const { segment } of graphemeSegmenter.segment(clean)) {\n\t\twidth += graphemeWidth(segment);\n\t}\n\n\t// Cache result\n\tif (widthCache.size >= WIDTH_CACHE_SIZE) {\n\t\tconst firstKey = widthCache.keys().next().value;\n\t\tif (firstKey !== undefined) {\n\t\t\twidthCache.delete(firstKey);\n\t\t}\n\t}\n\twidthCache.set(str, width);\n\n\treturn width;\n}\n\n/** Remove ANSI, OSC, and APC control sequences while preserving visible text. */\nexport function stripTerminalSequences(str: string): string {\n\tif (!str.includes(\"\\x1b\")) return str;\n\tlet result = \"\";\n\tlet i = 0;\n\twhile (i < str.length) {\n\t\tconst ansi = extractAnsiCode(str, i);\n\t\tif (ansi) {\n\t\t\ti += ansi.length;\n\t\t\tcontinue;\n\t\t}\n\t\tresult += str[i];\n\t\ti++;\n\t}\n\treturn result;\n}\n\n// grip-ignore noNearIdenticalDataStructures: A grapheme's rendered cell extent is a text-measurement result, while selection columns span and clip an independently managed row selection.\ninterface GraphemeCellRange {\n\tstart: number;\n\tend: number;\n}\n\ninterface TerminalTextColumnScan {\n\tcontainsColumn: boolean;\n\tnextColumn: number;\n}\n\nfunction scanTerminalTextColumn(text: string, column: number, startColumn: number): TerminalTextColumnScan {\n\tlet currentColumn = startColumn;\n\tfor (const { segment } of graphemeSegmenter.segment(text)) {\n\t\tconst width = segment === \"\\t\" ? 3 : graphemeWidth(segment);\n\t\tif (column >= currentColumn && column < currentColumn + width) {\n\t\t\treturn { containsColumn: true, nextColumn: currentColumn };\n\t\t}\n\t\tcurrentColumn += width;\n\t}\n\treturn { containsColumn: false, nextColumn: currentColumn };\n}\n\n/** Return the terminal-cell range occupied by the grapheme at a visible column. */\nexport function getGraphemeCellRange(line: string, column: number): GraphemeCellRange | undefined {\n\tlet currentCol = 0;\n\tlet i = 0;\n\twhile (i < line.length) {\n\t\tconst ansi = extractAnsiCode(line, i);\n\t\tif (ansi) {\n\t\t\ti += ansi.length;\n\t\t\tcontinue;\n\t\t}\n\t\tlet textEnd = i;\n\t\twhile (textEnd < line.length && !extractAnsiCode(line, textEnd)) textEnd++;\n\t\tfor (const { segment } of graphemeSegmenter.segment(line.slice(i, textEnd))) {\n\t\t\tconst width = graphemeWidth(segment);\n\t\t\tif (width > 0 && column >= currentCol && column < currentCol + width) {\n\t\t\t\treturn { start: currentCol, end: currentCol + width };\n\t\t\t}\n\t\t\tcurrentCol += width;\n\t\t}\n\t\ti = textEnd;\n\t}\n\treturn undefined;\n}\n\n/** Return the OSC 8 hyperlink covering a visible terminal column. */\nexport function getOsc8LinkAtColumn(line: string, column: number): string | undefined {\n\tlet activeUrl: string | undefined;\n\tlet currentCol = 0;\n\tlet i = 0;\n\twhile (i < line.length) {\n\t\tconst ansi = extractAnsiCode(line, i);\n\t\tif (ansi) {\n\t\t\tconst hyperlink = /^\\x1b\\]8;[^;]*;([^\\x07\\x1b]*)(?:\\x07|\\x1b\\\\)$/.exec(ansi.code);\n\t\t\tif (hyperlink) activeUrl = hyperlink[1] || undefined;\n\t\t\ti += ansi.length;\n\t\t\tcontinue;\n\t\t}\n\t\tlet textEnd = i;\n\t\twhile (textEnd < line.length && !extractAnsiCode(line, textEnd)) textEnd++;\n\t\tconst scan = scanTerminalTextColumn(line.slice(i, textEnd), column, currentCol);\n\t\tif (scan.containsColumn) return activeUrl;\n\t\tcurrentCol = scan.nextColumn;\n\t\ti = textEnd;\n\t}\n\treturn undefined;\n}\n\n/**\n * Normalize text for terminal output without changing logical editor content.\n * Some terminals render precomposed Thai/Lao AM vowels inconsistently during\n * differential repaint. Their compatibility decompositions have the same cell\n * width but avoid stale-cell artifacts in terminal renderers. Visible tabs are\n * expanded to the fixed width used by layout so terminal tab stops cannot wrap\n * a logical line, while tabs inside terminal string sequences stay untouched.\n */\nconst THAI_LAO_AM_REGEX = /[\\u0e33\\u0eb3]/;\nconst THAI_LAO_AM_GLOBAL_REGEX = /[\\u0e33\\u0eb3]/g;\n\nexport function normalizeTerminalOutput(str: string): string {\n\tlet normalized = str;\n\tif (THAI_LAO_AM_REGEX.test(normalized)) {\n\t\tnormalized = normalized.replace(THAI_LAO_AM_GLOBAL_REGEX, (char) =>\n\t\t\tchar === \"\\u0e33\" ? \"\\u0e4d\\u0e32\" : \"\\u0ecd\\u0eb2\",\n\t\t);\n\t}\n\tif (!normalized.includes(\"\\t\")) return normalized;\n\n\tlet result = \"\";\n\tlet i = 0;\n\twhile (i < normalized.length) {\n\t\tconst ansi = extractAnsiCode(normalized, i);\n\t\tif (ansi) {\n\t\t\tresult += ansi.code;\n\t\t\ti += ansi.length;\n\t\t\tcontinue;\n\t\t}\n\t\tresult += normalized[i] === \"\\t\" ? \" \" : normalized[i];\n\t\ti++;\n\t}\n\treturn result;\n}\n\nfunction extractCsiSequence(str: string, pos: number): AnsiCodeMatch | null {\n\tlet end = pos + 2;\n\twhile (end < str.length && !/[mGKHJ]/.test(str[end]!)) end++;\n\tif (end >= str.length) return null;\n\treturn { code: str.substring(pos, end + 1), length: end + 1 - pos };\n}\n\nfunction extractTerminatedControlString(str: string, pos: number): AnsiCodeMatch | null {\n\tlet end = pos + 2;\n\twhile (end < str.length) {\n\t\tif (str[end] === \"\\x07\") return { code: str.substring(pos, end + 1), length: end + 1 - pos };\n\t\tif (str[end] === \"\\x1b\" && str[end + 1] === \"\\\\\") {\n\t\t\treturn { code: str.substring(pos, end + 2), length: end + 2 - pos };\n\t\t}\n\t\tend++;\n\t}\n\treturn null;\n}\n\n/** Extract an ANSI escape sequence from a string at the given position. */\nexport function extractAnsiCode(str: string, pos: number): AnsiCodeMatch | null {\n\tif (pos >= str.length || str[pos] !== \"\\x1b\") return null;\n\tconst introducer = str[pos + 1];\n\tif (introducer === \"[\") return extractCsiSequence(str, pos);\n\t// OSC and APC sequences share BEL and ST termination rules.\n\tif (introducer === \"]\" || introducer === \"_\") return extractTerminatedControlString(str, pos);\n\treturn null;\n}\n\ntype Osc8Terminator = \"\\x07\" | \"\\x1b\\\\\";\n\ninterface ActiveHyperlink {\n\tparams: string;\n\turl: string;\n\tterminator: Osc8Terminator;\n}\n\nfunction parseOsc8Hyperlink(ansiCode: string): ActiveHyperlink | null | undefined {\n\tif (!ansiCode.startsWith(\"\\x1b]8;\")) {\n\t\treturn undefined;\n\t}\n\n\tconst terminator: Osc8Terminator = ansiCode.endsWith(\"\\x07\") ? \"\\x07\" : \"\\x1b\\\\\";\n\tconst body = ansiCode.slice(4, terminator === \"\\x07\" ? -1 : -2);\n\tconst separatorIndex = body.indexOf(\";\");\n\tif (separatorIndex === -1) {\n\t\treturn undefined;\n\t}\n\n\tconst params = body.slice(0, separatorIndex);\n\tconst url = body.slice(separatorIndex + 1);\n\tif (!url) {\n\t\treturn null;\n\t}\n\treturn { params, url, terminator };\n}\n\nfunction formatOsc8Hyperlink(hyperlink: ActiveHyperlink): string {\n\treturn `\\x1b]8;${hyperlink.params};${hyperlink.url}${hyperlink.terminator}`;\n}\n\nfunction formatOsc8Close(terminator: Osc8Terminator): string {\n\treturn `\\x1b]8;;${terminator}`;\n}\n\nfunction getActiveOsc8Close(prefix: string): string {\n\tif (!prefix.includes(\"\\x1b]8;\")) {\n\t\treturn \"\";\n\t}\n\n\tlet activeHyperlink: ActiveHyperlink | null = null;\n\tlet i = 0;\n\twhile (i < prefix.length) {\n\t\tconst ansi = extractAnsiCode(prefix, i);\n\t\tif (ansi) {\n\t\t\tconst hyperlink = parseOsc8Hyperlink(ansi.code);\n\t\t\tif (hyperlink !== undefined) {\n\t\t\t\tactiveHyperlink = hyperlink;\n\t\t\t}\n\t\t\ti += ansi.length;\n\t\t} else {\n\t\t\ti++;\n\t\t}\n\t}\n\treturn activeHyperlink ? formatOsc8Close(activeHyperlink.terminator) : \"\";\n}\n\n/**\n * Track active ANSI SGR codes to preserve styling across line breaks.\n */\nclass AnsiCodeTracker {\n\t// Track individual attributes separately so we can reset them specifically\n\tprivate bold = false;\n\tprivate dim = false;\n\tprivate italic = false;\n\tprivate underline = false;\n\tprivate blink = false;\n\tprivate inverse = false;\n\tprivate hidden = false;\n\tprivate strikethrough = false;\n\tprivate fgColor: string | null = null; // Stores the full code like \"31\" or \"38;5;240\"\n\tprivate bgColor: string | null = null; // Stores the full code like \"41\" or \"48;5;240\"\n\tprivate activeHyperlink: ActiveHyperlink | null = null;\n\n\tprivate setColor(code: number, color: string): void {\n\t\tif (code === 38) this.fgColor = color;\n\t\telse this.bgColor = color;\n\t}\n\n\tprivate processExtendedColor(parts: string[], index: number, code: number): number | undefined {\n\t\tif (code !== 38 && code !== 48) return undefined;\n\t\tif (parts[index + 1] === \"5\" && parts[index + 2] !== undefined) {\n\t\t\tthis.setColor(code, `${parts[index]};${parts[index + 1]};${parts[index + 2]}`);\n\t\t\treturn index + 3;\n\t\t}\n\t\tif (parts[index + 1] === \"2\" && parts[index + 4] !== undefined) {\n\t\t\tthis.setColor(\n\t\t\t\tcode,\n\t\t\t\t`${parts[index]};${parts[index + 1]};${parts[index + 2]};${parts[index + 3]};${parts[index + 4]}`,\n\t\t\t);\n\t\t\treturn index + 5;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate processStandardSgrCode(code: number): void {\n\t\tswitch (code) {\n\t\t\tcase 0:\n\t\t\t\tthis.reset();\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tthis.bold = true;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tthis.dim = true;\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tthis.italic = true;\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\tthis.underline = true;\n\t\t\t\tbreak;\n\t\t\tcase 5:\n\t\t\t\tthis.blink = true;\n\t\t\t\tbreak;\n\t\t\tcase 7:\n\t\t\t\tthis.inverse = true;\n\t\t\t\tbreak;\n\t\t\tcase 8:\n\t\t\t\tthis.hidden = true;\n\t\t\t\tbreak;\n\t\t\tcase 9:\n\t\t\t\tthis.strikethrough = true;\n\t\t\t\tbreak;\n\t\t\tcase 21:\n\t\t\t\tthis.bold = false;\n\t\t\t\tbreak;\n\t\t\tcase 22:\n\t\t\t\tthis.bold = false;\n\t\t\t\tthis.dim = false;\n\t\t\t\tbreak;\n\t\t\tcase 23:\n\t\t\t\tthis.italic = false;\n\t\t\t\tbreak;\n\t\t\tcase 24:\n\t\t\t\tthis.underline = false;\n\t\t\t\tbreak;\n\t\t\tcase 25:\n\t\t\t\tthis.blink = false;\n\t\t\t\tbreak;\n\t\t\tcase 27:\n\t\t\t\tthis.inverse = false;\n\t\t\t\tbreak;\n\t\t\tcase 28:\n\t\t\t\tthis.hidden = false;\n\t\t\t\tbreak;\n\t\t\tcase 29:\n\t\t\t\tthis.strikethrough = false;\n\t\t\t\tbreak;\n\t\t\tcase 39:\n\t\t\t\tthis.fgColor = null;\n\t\t\t\tbreak;\n\t\t\tcase 49:\n\t\t\t\tthis.bgColor = null;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif ((code >= 30 && code <= 37) || (code >= 90 && code <= 97)) this.fgColor = String(code);\n\t\t\t\telse if ((code >= 40 && code <= 47) || (code >= 100 && code <= 107)) this.bgColor = String(code);\n\t\t}\n\t}\n\n\tprocess(ansiCode: string): void {\n\t\tconst hyperlink = parseOsc8Hyperlink(ansiCode);\n\t\tif (hyperlink !== undefined) {\n\t\t\tthis.activeHyperlink = hyperlink;\n\t\t\treturn;\n\t\t}\n\t\tif (!ansiCode.endsWith(\"m\")) return;\n\t\tconst match = ansiCode.match(/\\x1b\\[([\\d;]*)m/);\n\t\tif (!match) return;\n\t\tconst params = match[1];\n\t\tif (params === \"\" || params === \"0\") {\n\t\t\tthis.reset();\n\t\t\treturn;\n\t\t}\n\t\tconst parts = params.split(\";\");\n\t\tlet index = 0;\n\t\twhile (index < parts.length) {\n\t\t\tconst code = Number.parseInt(parts[index], 10);\n\t\t\tconst nextIndex = this.processExtendedColor(parts, index, code);\n\t\t\tif (nextIndex !== undefined) {\n\t\t\t\tindex = nextIndex;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthis.processStandardSgrCode(code);\n\t\t\tindex++;\n\t\t}\n\t}\n\n\tprivate reset(): void {\n\t\tthis.bold = false;\n\t\tthis.dim = false;\n\t\tthis.italic = false;\n\t\tthis.underline = false;\n\t\tthis.blink = false;\n\t\tthis.inverse = false;\n\t\tthis.hidden = false;\n\t\tthis.strikethrough = false;\n\t\tthis.fgColor = null;\n\t\tthis.bgColor = null;\n\t\t// SGR reset does not affect OSC 8 hyperlink state\n\t}\n\n\t/** Clear all state for reuse. */\n\tclear(): void {\n\t\tthis.reset();\n\t\tthis.activeHyperlink = null;\n\t}\n\n\tgetActiveCodes(): string {\n\t\tconst codes: string[] = [];\n\t\tif (this.bold) codes.push(\"1\");\n\t\tif (this.dim) codes.push(\"2\");\n\t\tif (this.italic) codes.push(\"3\");\n\t\tif (this.underline) codes.push(\"4\");\n\t\tif (this.blink) codes.push(\"5\");\n\t\tif (this.inverse) codes.push(\"7\");\n\t\tif (this.hidden) codes.push(\"8\");\n\t\tif (this.strikethrough) codes.push(\"9\");\n\t\tif (this.fgColor) codes.push(this.fgColor);\n\t\tif (this.bgColor) codes.push(this.bgColor);\n\n\t\tlet result = codes.length > 0 ? `\\x1b[${codes.join(\";\")}m` : \"\";\n\t\tif (this.activeHyperlink) {\n\t\t\tresult += formatOsc8Hyperlink(this.activeHyperlink);\n\t\t}\n\t\treturn result;\n\t}\n\n\thasActiveCodes(): boolean {\n\t\treturn (\n\t\t\tthis.bold ||\n\t\t\tthis.dim ||\n\t\t\tthis.italic ||\n\t\t\tthis.underline ||\n\t\t\tthis.blink ||\n\t\t\tthis.inverse ||\n\t\t\tthis.hidden ||\n\t\t\tthis.strikethrough ||\n\t\t\tthis.fgColor !== null ||\n\t\t\tthis.bgColor !== null ||\n\t\t\tthis.activeHyperlink !== null\n\t\t);\n\t}\n\n\t/**\n\t * Get reset codes for attributes that need to be turned off at line end.\n\t * Underline must be closed to prevent bleeding into padding.\n\t * Active OSC 8 hyperlinks must be closed and re-opened on the next line.\n\t * Returns empty string if no attributes need closing.\n\t */\n\tgetLineEndReset(): string {\n\t\tlet result = \"\";\n\t\tif (this.underline) {\n\t\t\tresult += \"\\x1b[24m\"; // Underline off only\n\t\t}\n\t\tif (this.activeHyperlink) {\n\t\t\tresult += formatOsc8Close(this.activeHyperlink.terminator); // Re-opened at line start via getActiveCodes()\n\t\t}\n\t\treturn result;\n\t}\n}\n\nfunction updateTrackerFromText(text: string, tracker: AnsiCodeTracker): void {\n\tlet i = 0;\n\twhile (i < text.length) {\n\t\tconst ansiResult = extractAnsiCode(text, i);\n\t\tif (ansiResult) {\n\t\t\ttracker.process(ansiResult.code);\n\t\t\ti += ansiResult.length;\n\t\t} else {\n\t\t\ti++;\n\t\t}\n\t}\n}\n\n/**\n * Split text into words while keeping ANSI codes attached.\n */\nfunction splitIntoTokensWithAnsi(text: string): string[] {\n\tconst tokens: string[] = [];\n\tlet current = \"\";\n\tlet pendingAnsi = \"\"; // ANSI codes waiting to be attached to next visible content\n\tlet inWhitespace = false;\n\tlet i = 0;\n\n\twhile (i < text.length) {\n\t\tconst ansiResult = extractAnsiCode(text, i);\n\t\tif (ansiResult) {\n\t\t\t// Hold ANSI codes separately - they'll be attached to the next visible char\n\t\t\tpendingAnsi += ansiResult.code;\n\t\t\ti += ansiResult.length;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst char = text[i];\n\t\tconst charIsSpace = char === \" \";\n\n\t\tif (charIsSpace !== inWhitespace && current) {\n\t\t\t// Switching between whitespace and non-whitespace, push current token\n\t\t\ttokens.push(current);\n\t\t\tcurrent = \"\";\n\t\t}\n\n\t\t// Attach any pending ANSI codes to this visible character\n\t\tif (pendingAnsi) {\n\t\t\tcurrent += pendingAnsi;\n\t\t\tpendingAnsi = \"\";\n\t\t}\n\n\t\tinWhitespace = charIsSpace;\n\t\tcurrent += char;\n\t\ti++;\n\t}\n\n\t// Handle any remaining pending ANSI codes (attach to last token)\n\tif (pendingAnsi) {\n\t\tcurrent += pendingAnsi;\n\t}\n\n\tif (current) {\n\t\ttokens.push(current);\n\t}\n\n\treturn tokens;\n}\n\n/**\n * Wrap text with ANSI codes preserved.\n *\n * ONLY does word wrapping - NO padding, NO background colors.\n * Returns lines where each line is <= width visible chars.\n * Active ANSI codes are preserved across line breaks.\n *\n * @param text - Text to wrap (may contain ANSI codes and newlines)\n * @param width - Maximum visible width per line\n * @returns Array of wrapped lines (NOT padded to width)\n */\nexport function wrapTextWithAnsi(text: string, width: number): string[] {\n\tif (!text) {\n\t\treturn [\"\"];\n\t}\n\n\t// Handle newlines by processing each line separately\n\t// Track ANSI state across lines so styles carry over after literal newlines\n\tconst inputLines = text.split(/\\r\\n|\\r|\\n/);\n\tconst result: string[] = [];\n\tconst tracker = new AnsiCodeTracker();\n\n\tfor (const inputLine of inputLines) {\n\t\t// Prepend active ANSI codes from previous lines (except for first line)\n\t\tconst prefix = result.length > 0 ? tracker.getActiveCodes() : \"\";\n\t\tconst wrappedLines = wrapSingleLine(prefix + inputLine, width);\n\t\tfor (const wrappedLine of wrappedLines) {\n\t\t\tresult.push(wrappedLine);\n\t\t}\n\t\t// Update tracker with codes from this line for next iteration\n\t\tupdateTrackerFromText(inputLine, tracker);\n\t}\n\n\treturn result.length > 0 ? result : [\"\"];\n}\n\ninterface AnsiWrapLineState {\n\ttext: string;\n\tvisibleWidth: number;\n}\n\ninterface AnsiWrapContext {\n\tmaxWidth: number;\n\tlines: string[];\n\ttracker: AnsiCodeTracker;\n\tcurrent: AnsiWrapLineState;\n}\n\nfunction appendLineEndReset(text: string, tracker: AnsiCodeTracker): string {\n\treturn text + tracker.getLineEndReset();\n}\n\nfunction appendOversizedWrapToken(token: string, context: AnsiWrapContext): void {\n\tif (context.current.text) {\n\t\tcontext.lines.push(appendLineEndReset(context.current.text, context.tracker));\n\t\tcontext.current.text = \"\";\n\t\tcontext.current.visibleWidth = 0;\n\t}\n\n\tconst broken = breakLongWord(token, context.maxWidth, context.tracker);\n\tfor (let index = 0; index < broken.length - 1; index++) context.lines.push(broken[index]!);\n\tcontext.current.text = broken[broken.length - 1];\n\tcontext.current.visibleWidth = visibleWidth(context.current.text);\n}\n\nfunction appendFittingWrapToken(\n\ttoken: string,\n\ttokenVisibleWidth: number,\n\tisWhitespace: boolean,\n\tcontext: AnsiWrapContext,\n): void {\n\tconst exceedsLine = context.current.visibleWidth + tokenVisibleWidth > context.maxWidth;\n\tif (!exceedsLine || context.current.visibleWidth === 0) {\n\t\tcontext.current.text += token;\n\t\tcontext.current.visibleWidth += tokenVisibleWidth;\n\t\treturn;\n\t}\n\n\tcontext.lines.push(appendLineEndReset(context.current.text.trimEnd(), context.tracker));\n\tif (isWhitespace) {\n\t\tcontext.current.text = context.tracker.getActiveCodes();\n\t\tcontext.current.visibleWidth = 0;\n\t\treturn;\n\t}\n\tcontext.current.text = context.tracker.getActiveCodes() + token;\n\tcontext.current.visibleWidth = tokenVisibleWidth;\n}\n\nfunction wrapSingleLine(line: string, width: number): string[] {\n\tif (!line) return [\"\"];\n\tif (visibleWidth(line) <= width) return [line];\n\n\tconst context: AnsiWrapContext = {\n\t\tmaxWidth: width,\n\t\tlines: [],\n\t\ttracker: new AnsiCodeTracker(),\n\t\tcurrent: { text: \"\", visibleWidth: 0 },\n\t};\n\tfor (const token of splitIntoTokensWithAnsi(line)) {\n\t\tconst tokenVisibleWidth = visibleWidth(token);\n\t\tconst isWhitespace = token.trim() === \"\";\n\t\tif (tokenVisibleWidth > width && !isWhitespace) {\n\t\t\tappendOversizedWrapToken(token, context);\n\t\t\tcontinue;\n\t\t}\n\t\tappendFittingWrapToken(token, tokenVisibleWidth, isWhitespace, context);\n\t\tupdateTrackerFromText(token, context.tracker);\n\t}\n\n\tif (context.current.text) context.lines.push(context.current.text);\n\treturn context.lines.length > 0 ? context.lines.map((wrappedLine) => wrappedLine.trimEnd()) : [\"\"];\n}\n\nexport const PUNCTUATION_REGEX = /[(){}[\\]<>.,;:'\"!?+\\-=*/\\\\|&%^$#@~`]/;\n\n/**\n * Check if a character is whitespace.\n */\nexport function isWhitespaceChar(char: string): boolean {\n\treturn /\\s/.test(char);\n}\n\n/**\n * Check if a character is punctuation.\n */\nexport function isPunctuationChar(char: string): boolean {\n\treturn PUNCTUATION_REGEX.test(char);\n}\n\ntype AnsiTextSegmentType = \"ansi\" | \"grapheme\";\n\ninterface AnsiTextSegment {\n\ttype: AnsiTextSegmentType;\n\tvalue: string;\n}\n\nfunction* iterateAnsiTextSegments(text: string): Generator<AnsiTextSegment> {\n\tlet index = 0;\n\twhile (index < text.length) {\n\t\tconst ansiResult = extractAnsiCode(text, index);\n\t\tif (ansiResult) {\n\t\t\tyield { type: \"ansi\", value: ansiResult.code };\n\t\t\tindex += ansiResult.length;\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet end = index;\n\t\twhile (end < text.length) {\n\t\t\tif (extractAnsiCode(text, end)) break;\n\t\t\tend++;\n\t\t}\n\t\tfor (const segment of graphemeSegmenter.segment(text.slice(index, end))) {\n\t\t\tyield { type: \"grapheme\", value: segment.segment };\n\t\t}\n\t\tindex = end;\n\t}\n}\n\nfunction breakLongWord(word: string, width: number, tracker: AnsiCodeTracker): string[] {\n\tconst lines: string[] = [];\n\tlet currentLine = tracker.getActiveCodes();\n\tlet currentWidth = 0;\n\n\t// Now process segments\n\tfor (const seg of iterateAnsiTextSegments(word)) {\n\t\tif (seg.type === \"ansi\") {\n\t\t\tcurrentLine += seg.value;\n\t\t\ttracker.process(seg.value);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst grapheme = seg.value;\n\t\t// Skip empty graphemes to avoid issues with string-width calculation\n\t\tif (!grapheme) continue;\n\n\t\tconst graphemeWidth = visibleWidth(grapheme);\n\n\t\tif (currentWidth + graphemeWidth > width) {\n\t\t\t// Add specific reset for underline only (preserves background)\n\t\t\tconst lineEndReset = tracker.getLineEndReset();\n\t\t\tif (lineEndReset) {\n\t\t\t\tcurrentLine += lineEndReset;\n\t\t\t}\n\t\t\tlines.push(currentLine);\n\t\t\tcurrentLine = tracker.getActiveCodes();\n\t\t\tcurrentWidth = 0;\n\t\t}\n\n\t\tcurrentLine += grapheme;\n\t\tcurrentWidth += graphemeWidth;\n\t}\n\n\tif (currentLine) {\n\t\t// No reset at end of final segment - caller handles continuation\n\t\tlines.push(currentLine);\n\t}\n\n\treturn lines.length > 0 ? lines : [\"\"];\n}\n\n/**\n * Apply background color to a line, padding to full width.\n *\n * @param line - Line of text (may contain ANSI codes)\n * @param width - Total width to pad to\n * @param bgFn - Background color function\n * @returns Line with background applied and padded to width\n */\nexport function applyBackgroundToLine(line: string, width: number, bgFn: (text: string) => string): string {\n\t// Calculate padding needed\n\tconst visibleLen = visibleWidth(line);\n\tconst paddingNeeded = Math.max(0, width - visibleLen);\n\tconst padding = \" \".repeat(paddingNeeded);\n\n\t// Apply background to content + padding\n\tconst withPadding = line + padding;\n\treturn bgFn(withPadding);\n}\n\ninterface WidthTruncationScan {\n\tprefix: string;\n\tprefixWidth: number;\n\tpendingAnsi: string;\n\tvisibleWidth: number;\n\tkeepingPrefix: boolean;\n\toverflowed: boolean;\n\texhaustedInput: boolean;\n}\n\nfunction createWidthTruncationScan(): WidthTruncationScan {\n\treturn {\n\t\tprefix: \"\",\n\t\tprefixWidth: 0,\n\t\tpendingAnsi: \"\",\n\t\tvisibleWidth: 0,\n\t\tkeepingPrefix: true,\n\t\toverflowed: false,\n\t\texhaustedInput: false,\n\t};\n}\n\nfunction appendWidthTruncationFragment(\n\tstate: WidthTruncationScan,\n\tfragment: string,\n\tfragmentWidth: number,\n\ttargetWidth: number,\n\tmaxWidth: number,\n): boolean {\n\tif (state.keepingPrefix && state.prefixWidth + fragmentWidth <= targetWidth) {\n\t\tstate.prefix += state.pendingAnsi + fragment;\n\t\tstate.pendingAnsi = \"\";\n\t\tstate.prefixWidth += fragmentWidth;\n\t} else {\n\t\tstate.keepingPrefix = false;\n\t\tstate.pendingAnsi = \"\";\n\t}\n\tstate.visibleWidth += fragmentWidth;\n\tif (state.visibleWidth <= maxWidth) return true;\n\tstate.overflowed = true;\n\treturn false;\n}\n\nfunction scanTruncationGraphemes(\n\ttext: string,\n\tstate: WidthTruncationScan,\n\ttargetWidth: number,\n\tmaxWidth: number,\n): boolean {\n\tfor (const { segment } of graphemeSegmenter.segment(text)) {\n\t\tif (!appendWidthTruncationFragment(state, segment, graphemeWidth(segment), targetWidth, maxWidth)) return false;\n\t}\n\treturn true;\n}\n\nfunction scanPlainTextForTruncation(text: string, targetWidth: number, maxWidth: number): WidthTruncationScan {\n\tconst state = createWidthTruncationScan();\n\tstate.exhaustedInput = scanTruncationGraphemes(text, state, targetWidth, maxWidth);\n\treturn state;\n}\n\nfunction scanStyledTextForTruncation(text: string, targetWidth: number, maxWidth: number): WidthTruncationScan {\n\tconst state = createWidthTruncationScan();\n\tlet index = 0;\n\twhile (index < text.length) {\n\t\tconst ansi = extractAnsiCode(text, index);\n\t\tif (ansi) {\n\t\t\tstate.pendingAnsi += ansi.code;\n\t\t\tindex += ansi.length;\n\t\t\tcontinue;\n\t\t}\n\t\tif (text[index] === \"\\t\") {\n\t\t\tif (!appendWidthTruncationFragment(state, \"\\t\", 3, targetWidth, maxWidth)) break;\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet end = index;\n\t\twhile (end < text.length && text[end] !== \"\\t\" && !extractAnsiCode(text, end)) end++;\n\t\tif (!scanTruncationGraphemes(text.slice(index, end), state, targetWidth, maxWidth)) break;\n\t\tindex = end;\n\t}\n\tstate.exhaustedInput = index >= text.length;\n\treturn state;\n}\n\nfunction truncateWithOversizedEllipsis(\n\ttext: string,\n\tmaxWidth: number,\n\tellipsis: string,\n\tellipsisWidth: number,\n\tpad: boolean,\n): string | undefined {\n\tif (ellipsisWidth < maxWidth) return undefined;\n\tconst textWidth = visibleWidth(text);\n\tif (textWidth <= maxWidth) return pad ? text + \" \".repeat(maxWidth - textWidth) : text;\n\tconst clippedEllipsis = truncateFragmentToWidth(ellipsis, maxWidth);\n\tif (clippedEllipsis.width === 0) return pad ? \" \".repeat(maxWidth) : \"\";\n\treturn finalizeTruncatedResult(\"\", 0, clippedEllipsis.text, clippedEllipsis.width, maxWidth, pad);\n}\n\nfunction truncatePrintableAscii(\n\ttext: string,\n\tmaxWidth: number,\n\tellipsis: string,\n\tellipsisWidth: number,\n\tpad: boolean,\n): string | undefined {\n\tif (!isPrintableAscii(text)) return undefined;\n\tif (text.length <= maxWidth) return pad ? text + \" \".repeat(maxWidth - text.length) : text;\n\tconst targetWidth = maxWidth - ellipsisWidth;\n\treturn finalizeTruncatedResult(text.slice(0, targetWidth), targetWidth, ellipsis, ellipsisWidth, maxWidth, pad);\n}\n\nfunction truncateMeasuredText(\n\ttext: string,\n\tmaxWidth: number,\n\tellipsis: string,\n\tellipsisWidth: number,\n\tpad: boolean,\n): string {\n\tconst targetWidth = maxWidth - ellipsisWidth;\n\tconst scan =\n\t\ttext.includes(\"\\x1b\") || text.includes(\"\\t\")\n\t\t\t? scanStyledTextForTruncation(text, targetWidth, maxWidth)\n\t\t\t: scanPlainTextForTruncation(text, targetWidth, maxWidth);\n\tif (!scan.overflowed && scan.exhaustedInput) {\n\t\treturn pad ? text + \" \".repeat(Math.max(0, maxWidth - scan.visibleWidth)) : text;\n\t}\n\treturn finalizeTruncatedResult(scan.prefix, scan.prefixWidth, ellipsis, ellipsisWidth, maxWidth, pad);\n}\n\n/**\n * Truncate text to fit within a maximum visible width, adding ellipsis if needed.\n * Optionally pad with spaces to reach exactly maxWidth.\n * Properly handles ANSI escape codes (they don't count toward width).\n *\n * @param text - Text to truncate (may contain ANSI codes)\n * @param maxWidth - Maximum visible width\n * @param ellipsis - Ellipsis string to append when truncating (default: \"...\")\n * @param pad - If true, pad result with spaces to exactly maxWidth (default: false)\n * @returns Truncated text, optionally padded to exactly maxWidth\n */\nexport function truncateToWidth(\n\ttext: string,\n\tmaxWidth: number,\n\tellipsis: string = \"...\",\n\tpad: boolean = false,\n): string {\n\tif (maxWidth <= 0) return \"\";\n\tif (text.length === 0) return pad ? \" \".repeat(maxWidth) : \"\";\n\n\tconst ellipsisWidth = visibleWidth(ellipsis);\n\tconst oversizedEllipsis = truncateWithOversizedEllipsis(text, maxWidth, ellipsis, ellipsisWidth, pad);\n\tif (oversizedEllipsis !== undefined) return oversizedEllipsis;\n\tconst printableAscii = truncatePrintableAscii(text, maxWidth, ellipsis, ellipsisWidth, pad);\n\tif (printableAscii !== undefined) return printableAscii;\n\treturn truncateMeasuredText(text, maxWidth, ellipsis, ellipsisWidth, pad);\n}\n\n/**\n * Extract a range of visible columns from a line. Handles ANSI codes and wide chars.\n * @param strict - If true, exclude wide chars at boundary that would extend past the range\n */\nexport function sliceByColumn(line: string, startCol: number, length: number, strict = false): string {\n\treturn sliceWithWidth(line, startCol, length, strict).text;\n}\n\ninterface TerminalColumnSliceState extends TerminalTextFragment {\n\tcurrentColumn: number;\n\tpendingAnsi: string;\n}\n\nfunction appendAnsiToColumnSlice(\n\tstate: TerminalColumnSliceState,\n\tansi: string,\n\tstartColumn: number,\n\tendColumn: number,\n): void {\n\tif (state.currentColumn >= startColumn && state.currentColumn < endColumn) state.text += ansi;\n\telse if (state.currentColumn < startColumn) state.pendingAnsi += ansi;\n}\n\nfunction appendGraphemeToColumnSlice(\n\tstate: TerminalColumnSliceState,\n\tgrapheme: string,\n\tgraphemeWidth: number,\n\tstartColumn: number,\n\tendColumn: number,\n\tstrict: boolean,\n): void {\n\tif (state.currentColumn < startColumn || state.currentColumn >= endColumn) return;\n\tif (strict && state.currentColumn + graphemeWidth > endColumn) return;\n\tif (state.pendingAnsi) {\n\t\tstate.text += state.pendingAnsi;\n\t\tstate.pendingAnsi = \"\";\n\t}\n\tstate.text += grapheme;\n\tstate.width += graphemeWidth;\n}\n\n/** Like sliceByColumn but also returns the actual visible width of the result. */\nexport function sliceWithWidth(line: string, startCol: number, length: number, strict = false): TerminalTextFragment {\n\tif (length <= 0) return { text: \"\", width: 0 };\n\tconst endColumn = startCol + length;\n\tconst state: TerminalColumnSliceState = { text: \"\", width: 0, currentColumn: 0, pendingAnsi: \"\" };\n\tfor (const segment of iterateAnsiTextSegments(line)) {\n\t\tif (segment.type === \"ansi\") {\n\t\t\tappendAnsiToColumnSlice(state, segment.value, startCol, endColumn);\n\t\t\tcontinue;\n\t\t}\n\t\tconst width = graphemeWidth(segment.value);\n\t\tappendGraphemeToColumnSlice(state, segment.value, width, startCol, endColumn, strict);\n\t\tstate.currentColumn += width;\n\t\tif (state.currentColumn >= endColumn) break;\n\t}\n\treturn { text: state.text, width: state.width };\n}\n\n// Pooled tracker instance for extractSegments (avoids allocation per call)\nconst pooledStyleTracker = new AnsiCodeTracker();\n\ninterface ExtractedLineSegments {\n\tbefore: string;\n\tbeforeWidth: number;\n\tafter: string;\n\tafterWidth: number;\n}\n\ninterface LineSegmentExtractionContext {\n\tbeforeEnd: number;\n\tafterStart: number;\n\tafterEnd: number;\n\tafterLength: number;\n\tstrictAfter: boolean;\n}\n\ninterface LineSegmentExtractionState extends ExtractedLineSegments {\n\tcurrentColumn: number;\n\tpendingAnsiBefore: string;\n\tafterStarted: boolean;\n}\n\nfunction appendAnsiToExtractedSegments(\n\tstate: LineSegmentExtractionState,\n\tansiCode: string,\n\tcontext: LineSegmentExtractionContext,\n): void {\n\tpooledStyleTracker.process(ansiCode);\n\tif (state.currentColumn < context.beforeEnd) {\n\t\tstate.pendingAnsiBefore += ansiCode;\n\t\treturn;\n\t}\n\tif (state.currentColumn >= context.afterStart && state.currentColumn < context.afterEnd && state.afterStarted) {\n\t\tstate.after += ansiCode;\n\t}\n}\n\nfunction appendGraphemeToExtractedSegments(\n\tstate: LineSegmentExtractionState,\n\tgrapheme: string,\n\tgraphemeWidth: number,\n\tcontext: LineSegmentExtractionContext,\n): void {\n\tif (state.currentColumn < context.beforeEnd && state.currentColumn + graphemeWidth <= context.beforeEnd) {\n\t\tstate.before += state.pendingAnsiBefore + grapheme;\n\t\tstate.pendingAnsiBefore = \"\";\n\t\tstate.beforeWidth += graphemeWidth;\n\t\treturn;\n\t}\n\tif (state.currentColumn < context.afterStart || state.currentColumn >= context.afterEnd) return;\n\tif (context.strictAfter && state.currentColumn + graphemeWidth > context.afterEnd) return;\n\tif (!state.afterStarted) {\n\t\tstate.after += pooledStyleTracker.getActiveCodes();\n\t\tstate.afterStarted = true;\n\t}\n\tstate.after += grapheme;\n\tstate.afterWidth += graphemeWidth;\n}\n\nfunction isLineSegmentExtractionComplete(\n\tstate: LineSegmentExtractionState,\n\tcontext: LineSegmentExtractionContext,\n): boolean {\n\treturn context.afterLength <= 0 ? state.currentColumn >= context.beforeEnd : state.currentColumn >= context.afterEnd;\n}\n\n/**\n * Extract \"before\" and \"after\" segments from a line in a single pass.\n * Used for overlay compositing where we need content before and after the overlay region.\n * Preserves styling from before the overlay that should affect content after it.\n */\nexport function extractSegments(\n\tline: string,\n\tbeforeEnd: number,\n\tafterStart: number,\n\tafterLen: number,\n\tstrictAfter = false,\n): ExtractedLineSegments {\n\tconst context: LineSegmentExtractionContext = {\n\t\tbeforeEnd,\n\t\tafterStart,\n\t\tafterEnd: afterStart + afterLen,\n\t\tafterLength: afterLen,\n\t\tstrictAfter,\n\t};\n\tconst state: LineSegmentExtractionState = {\n\t\tbefore: \"\",\n\t\tbeforeWidth: 0,\n\t\tafter: \"\",\n\t\tafterWidth: 0,\n\t\tcurrentColumn: 0,\n\t\tpendingAnsiBefore: \"\",\n\t\tafterStarted: false,\n\t};\n\tpooledStyleTracker.clear();\n\tfor (const segment of iterateAnsiTextSegments(line)) {\n\t\tif (segment.type === \"ansi\") {\n\t\t\tappendAnsiToExtractedSegments(state, segment.value, context);\n\t\t\tcontinue;\n\t\t}\n\t\tconst width = graphemeWidth(segment.value);\n\t\tappendGraphemeToExtractedSegments(state, segment.value, width, context);\n\t\tstate.currentColumn += width;\n\t\tif (isLineSegmentExtractionComplete(state, context)) break;\n\t}\n\treturn {\n\t\tbefore: state.before,\n\t\tbeforeWidth: state.beforeWidth,\n\t\tafter: state.after,\n\t\tafterWidth: state.afterWidth,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAAC,SAAS,CAErD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAAC,SAAS,CAEjD;AA4ED,UAAU,oBAAoB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACd;AAED,UAAU,aAAa;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CACf;AAyID;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAuDhD;AAED,iFAAiF;AACjF,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAc1D;AAGD,UAAU,iBAAiB;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACZ;AAmBD,mFAAmF;AACnF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAqBhG;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAoBpF;AAaD,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAsB3D;AAqBD,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAO9E;AA0UD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAuBtE;AA+ED,eAAO,MAAM,iBAAiB,QAAyC,CAAC;AAExE;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAyED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CASzG;AAsID;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC9B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,MAAc,EACxB,GAAG,GAAE,OAAe,GAClB,MAAM,CAUR;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,MAAM,CAEpG;AAmCD,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,oBAAoB,CAenH;AAKD,UAAU,qBAAqB;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACnB;AA4DD;;;;GAIG;AACH,wBAAgB,eAAe,CAC9B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,WAAW,UAAQ,GACjB,qBAAqB,CAkCvB"}
|
package/dist/utils.js
CHANGED
|
@@ -434,18 +434,20 @@ function getActiveOsc8Close(prefix) {
|
|
|
434
434
|
* Track active ANSI SGR codes to preserve styling across line breaks.
|
|
435
435
|
*/
|
|
436
436
|
class AnsiCodeTracker {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
437
|
+
constructor() {
|
|
438
|
+
// Track individual attributes separately so we can reset them specifically
|
|
439
|
+
this.bold = false;
|
|
440
|
+
this.dim = false;
|
|
441
|
+
this.italic = false;
|
|
442
|
+
this.underline = false;
|
|
443
|
+
this.blink = false;
|
|
444
|
+
this.inverse = false;
|
|
445
|
+
this.hidden = false;
|
|
446
|
+
this.strikethrough = false;
|
|
447
|
+
this.fgColor = null; // Stores the full code like "31" or "38;5;240"
|
|
448
|
+
this.bgColor = null; // Stores the full code like "41" or "48;5;240"
|
|
449
|
+
this.activeHyperlink = null;
|
|
450
|
+
}
|
|
449
451
|
setColor(code, color) {
|
|
450
452
|
if (code === 38)
|
|
451
453
|
this.fgColor = color;
|