@sayknow-cli/tui 0.3.13 → 0.3.15
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/types/animation-scheduler.d.ts +13 -0
- package/dist/types/autocomplete.d.ts +83 -0
- package/dist/types/bracketed-paste.d.ts +26 -0
- package/dist/types/components/box.d.ts +20 -0
- package/dist/types/components/cancellable-loader.d.ts +21 -0
- package/dist/types/components/editor.d.ts +126 -0
- package/dist/types/components/image.d.ts +18 -0
- package/dist/types/components/input.d.ts +16 -0
- package/dist/types/components/loader.d.ts +23 -0
- package/dist/types/components/markdown.d.ts +87 -0
- package/dist/types/components/sayknow-pet.d.ts +128 -0
- package/dist/types/components/select-list.d.ts +46 -0
- package/dist/types/components/settings-list.d.ts +39 -0
- package/dist/types/components/spacer.d.ts +11 -0
- package/dist/types/components/tab-bar.d.ts +56 -0
- package/dist/types/components/text.d.ts +22 -0
- package/dist/types/components/truncated-text.d.ts +10 -0
- package/dist/types/editor-component.d.ts +36 -0
- package/dist/types/fuzzy.d.ts +15 -0
- package/dist/types/index.d.ts +28 -0
- package/dist/types/keybindings.d.ts +201 -0
- package/dist/types/keys.d.ts +208 -0
- package/dist/types/kill-ring.d.ts +27 -0
- package/dist/types/metrics.d.ts +85 -0
- package/dist/types/stdin-buffer.d.ts +50 -0
- package/dist/types/symbols.d.ts +23 -0
- package/dist/types/terminal-capabilities.d.ts +187 -0
- package/dist/types/terminal.d.ts +90 -0
- package/dist/types/ttyid.d.ts +9 -0
- package/dist/types/tui.d.ts +269 -0
- package/dist/types/utils.d.ts +110 -0
- package/package.json +9 -8
- package/src/terminal-capabilities.ts +77 -4
- package/src/tui.ts +50 -21
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/** Number of consecutive unexpected full redraws that constitute a "storm". */
|
|
2
|
+
export declare const REPAINT_STORM_THRESHOLD = 3;
|
|
3
|
+
/** Hard cap on retained metric label keys; overflow is aggregated under `other`. */
|
|
4
|
+
export declare const MAX_LABEL_MAP_ENTRIES = 128;
|
|
5
|
+
export interface DurationStats {
|
|
6
|
+
count: number;
|
|
7
|
+
meanMs: number;
|
|
8
|
+
p50Ms: number;
|
|
9
|
+
p95Ms: number;
|
|
10
|
+
p99Ms: number;
|
|
11
|
+
maxMs: number;
|
|
12
|
+
}
|
|
13
|
+
export interface RssStats {
|
|
14
|
+
samples: number;
|
|
15
|
+
baselineBytes: number | null;
|
|
16
|
+
lastBytes: number | null;
|
|
17
|
+
peakBytes: number;
|
|
18
|
+
growthBytes: number;
|
|
19
|
+
/** RSS sampled after the run + a forced GC (informational). */
|
|
20
|
+
returnBytes: number | null;
|
|
21
|
+
/** Heap used at baseline and after the run + forced GC (reclaimable signal). */
|
|
22
|
+
heapBaselineBytes: number | null;
|
|
23
|
+
heapReturnBytes: number | null;
|
|
24
|
+
/** (heapReturn - heapBaseline) / heapBaseline; <= tolerance means heap returned. */
|
|
25
|
+
returnWithinBaselineFraction: number | null;
|
|
26
|
+
}
|
|
27
|
+
export interface HelperStat {
|
|
28
|
+
count: number;
|
|
29
|
+
totalMs: number;
|
|
30
|
+
meanMs: number;
|
|
31
|
+
}
|
|
32
|
+
export interface LineCountGauge {
|
|
33
|
+
last: number;
|
|
34
|
+
max: number;
|
|
35
|
+
}
|
|
36
|
+
export interface RenderMetricsSnapshot {
|
|
37
|
+
enabled: boolean;
|
|
38
|
+
renderCount: number;
|
|
39
|
+
renderDurations: DurationStats;
|
|
40
|
+
durationsTruncated: boolean;
|
|
41
|
+
requestSources: Record<string, number>;
|
|
42
|
+
fullRedrawCount: number;
|
|
43
|
+
fullRedrawCauses: Record<string, number>;
|
|
44
|
+
repaintStorms: number;
|
|
45
|
+
maxConsecutiveFullRedraws: number;
|
|
46
|
+
rss: RssStats;
|
|
47
|
+
ownerGauges: Record<string, number>;
|
|
48
|
+
timerGauges: Record<string, number>;
|
|
49
|
+
helperStats: Record<string, HelperStat>;
|
|
50
|
+
lineCounts: Record<string, LineCountGauge>;
|
|
51
|
+
}
|
|
52
|
+
export declare class RenderMetrics {
|
|
53
|
+
#private;
|
|
54
|
+
constructor(enabled?: boolean);
|
|
55
|
+
get enabled(): boolean;
|
|
56
|
+
enable(): void;
|
|
57
|
+
disable(): void;
|
|
58
|
+
/** Reset all collected data (keeps the enabled state). */
|
|
59
|
+
reset(): void;
|
|
60
|
+
/** High-resolution clock for timing render passes. Returns 0 when disabled. */
|
|
61
|
+
now(): number;
|
|
62
|
+
/** Record that a render was requested, attributed to a caller source. */
|
|
63
|
+
recordRequest(source?: string): void;
|
|
64
|
+
/** Record one completed `#doRender` pass duration (ms). */
|
|
65
|
+
recordRender(durationMs: number): void;
|
|
66
|
+
/** Record a full-redraw event and classify its cause for storm detection. */
|
|
67
|
+
recordFullRedraw(cause: string): void;
|
|
68
|
+
/** Sample current RSS. Records baseline on first sample, tracks peak/last. */
|
|
69
|
+
sampleRss(): number;
|
|
70
|
+
setOwnerGauge(name: string, value: number): void;
|
|
71
|
+
setTimerGauge(name: string, value: number): void;
|
|
72
|
+
/** Accumulate timing/count for a named render helper (e.g. "renderTree"). */
|
|
73
|
+
recordHelper(name: string, durationMs: number): void;
|
|
74
|
+
/** Record a per-render line-count gauge (e.g. "rendered", "normalized", "diffed"). */
|
|
75
|
+
recordLineCount(name: string, value: number): void;
|
|
76
|
+
/**
|
|
77
|
+
* Force a GC when the runtime exposes one and sample RSS as the post-run
|
|
78
|
+
* "return" value used by the memory-leak gate. Callers should drop large
|
|
79
|
+
* references before calling so reclaimable memory is actually freed.
|
|
80
|
+
*/
|
|
81
|
+
sampleReturn(): number;
|
|
82
|
+
snapshot(): RenderMetricsSnapshot;
|
|
83
|
+
}
|
|
84
|
+
/** Shared metrics instance used by the TUI render loop. */
|
|
85
|
+
export declare const renderMetrics: RenderMetrics;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StdinBuffer buffers input and emits complete sequences.
|
|
3
|
+
*
|
|
4
|
+
* This is necessary because stdin data events can arrive in partial chunks,
|
|
5
|
+
* especially for escape sequences like mouse events. Without buffering,
|
|
6
|
+
* partial sequences can be misinterpreted as regular keypresses.
|
|
7
|
+
*
|
|
8
|
+
* For example, the mouse SGR sequence `\x1b[<35;20;5m` might arrive as:
|
|
9
|
+
* - Event 1: `\x1b`
|
|
10
|
+
* - Event 2: `[<35`
|
|
11
|
+
* - Event 3: `;20;5m`
|
|
12
|
+
*
|
|
13
|
+
* The buffer accumulates these until a complete sequence is detected.
|
|
14
|
+
* Call the `process()` method to feed input data.
|
|
15
|
+
*
|
|
16
|
+
* Based on code from OpenTUI (https://github.com/anomalyco/opentui)
|
|
17
|
+
* MIT License - Copyright (c) 2025 opentui
|
|
18
|
+
*/
|
|
19
|
+
import { EventEmitter } from "events";
|
|
20
|
+
export type StdinBufferOptions = {
|
|
21
|
+
/**
|
|
22
|
+
* Maximum time to wait for sequence completion (default: 10ms)
|
|
23
|
+
* After this time, the buffer is flushed even if incomplete
|
|
24
|
+
*/
|
|
25
|
+
timeout?: number;
|
|
26
|
+
};
|
|
27
|
+
export type StdinBufferEventMap = {
|
|
28
|
+
data: [string];
|
|
29
|
+
paste: [string];
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Buffers stdin input and emits complete sequences via the 'data' event.
|
|
33
|
+
* Handles partial escape sequences that arrive across multiple chunks.
|
|
34
|
+
*
|
|
35
|
+
* StdinBuffer is the single raw-stdin decoding boundary: raw terminal bytes
|
|
36
|
+
* enter via `process()` and decoded string events leave via the 'data' and
|
|
37
|
+
* 'paste' events. UTF-8 is decoded exactly once here (using a persistent
|
|
38
|
+
* StringDecoder) so multi-byte characters split across chunk boundaries are
|
|
39
|
+
* reassembled rather than corrupted into U+FFFD. All downstream parsing
|
|
40
|
+
* (escape sequences, bracketed paste, Kitty/CSI, OSC/DA1) operates on strings.
|
|
41
|
+
*/
|
|
42
|
+
export declare class StdinBuffer extends EventEmitter<StdinBufferEventMap> {
|
|
43
|
+
#private;
|
|
44
|
+
constructor(options?: StdinBufferOptions);
|
|
45
|
+
process(data: string | Buffer): void;
|
|
46
|
+
flush(): string[];
|
|
47
|
+
clear(): void;
|
|
48
|
+
getBuffer(): string;
|
|
49
|
+
destroy(): void;
|
|
50
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface BoxSymbols {
|
|
2
|
+
topLeft: string;
|
|
3
|
+
topRight: string;
|
|
4
|
+
bottomLeft: string;
|
|
5
|
+
bottomRight: string;
|
|
6
|
+
horizontal: string;
|
|
7
|
+
vertical: string;
|
|
8
|
+
teeDown: string;
|
|
9
|
+
teeUp: string;
|
|
10
|
+
teeLeft: string;
|
|
11
|
+
teeRight: string;
|
|
12
|
+
cross: string;
|
|
13
|
+
}
|
|
14
|
+
export interface SymbolTheme {
|
|
15
|
+
cursor: string;
|
|
16
|
+
inputCursor: string;
|
|
17
|
+
boxRound: Omit<BoxSymbols, "teeDown" | "teeUp" | "teeLeft" | "teeRight" | "cross">;
|
|
18
|
+
boxSharp: BoxSymbols;
|
|
19
|
+
table: BoxSymbols;
|
|
20
|
+
quoteBorder: string;
|
|
21
|
+
hrChar: string;
|
|
22
|
+
spinnerFrames: string[];
|
|
23
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
export declare enum ImageProtocol {
|
|
2
|
+
Kitty = "\u001B_G",
|
|
3
|
+
Iterm2 = "\u001B]1337;File=",
|
|
4
|
+
Sixel = "\u001BPq"
|
|
5
|
+
}
|
|
6
|
+
export declare enum NotifyProtocol {
|
|
7
|
+
Bell = "\u0007",
|
|
8
|
+
Osc99 = "\u001B]99;;",
|
|
9
|
+
Osc9 = "\u001B]9;"
|
|
10
|
+
}
|
|
11
|
+
export type TerminalId = "kitty" | "ghostty" | "wezterm" | "iterm2" | "vscode" | "alacritty" | "base" | "trueColor";
|
|
12
|
+
/** Terminal capability details used for rendering and protocol selection. */
|
|
13
|
+
export declare class TerminalInfo {
|
|
14
|
+
readonly id: TerminalId;
|
|
15
|
+
readonly imageProtocol: ImageProtocol | null;
|
|
16
|
+
readonly trueColor: boolean;
|
|
17
|
+
readonly hyperlinks: boolean;
|
|
18
|
+
readonly notifyProtocol: NotifyProtocol;
|
|
19
|
+
constructor(id: TerminalId, imageProtocol: ImageProtocol | null, trueColor: boolean, hyperlinks: boolean, notifyProtocol?: NotifyProtocol);
|
|
20
|
+
isImageLine(line: string): boolean;
|
|
21
|
+
formatNotification(message: string): string;
|
|
22
|
+
sendNotification(message: string): void;
|
|
23
|
+
}
|
|
24
|
+
export declare function isNotificationSuppressed(): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Returns whether the process runs under a terminal multiplexer (tmux, GNU
|
|
27
|
+
* screen, or zellij). Recognizes the same host markers as the renderer's
|
|
28
|
+
* multiplexer predicate in tui.ts so capability selection and viewport-repaint
|
|
29
|
+
* policy agree on what counts as a multiplexed host. Multiplexers intercept
|
|
30
|
+
* graphics escapes and OSC 8 hyperlinks instead of forwarding them to the
|
|
31
|
+
* outer terminal.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isUnderTerminalMultiplexer(env?: NodeJS.ProcessEnv): boolean;
|
|
34
|
+
export interface TerminalGraphicsFallbackOptions {
|
|
35
|
+
/**
|
|
36
|
+
* Permit cursor-neutral image escapes (kitty `a=p,C=1` placements) to render
|
|
37
|
+
* inside this fallback scope. Cursor-advancing protocols (iTerm2/SIXEL)
|
|
38
|
+
* remain suppressed. A nested scope without this option revokes the
|
|
39
|
+
* permission for its own subtree.
|
|
40
|
+
*/
|
|
41
|
+
allowCursorNeutralImages?: boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Synchronously suppress terminal graphics while rendering a text-only surface.
|
|
45
|
+
* Nested scopes remain active until the outermost scope exits.
|
|
46
|
+
*/
|
|
47
|
+
export declare function withTerminalGraphicsFallback<T>(fn: () => T, options?: TerminalGraphicsFallbackOptions): T;
|
|
48
|
+
/** Returns whether terminal graphics are currently suppressed by a render scope. */
|
|
49
|
+
export declare function isTerminalGraphicsFallbackActive(): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Returns whether cursor-neutral image escapes may render despite an active
|
|
52
|
+
* graphics-fallback scope. True only when every active fallback scope opted in.
|
|
53
|
+
*/
|
|
54
|
+
export declare function isCursorNeutralImagePermittedInFallback(): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Returns whether PI_FORCE_IMAGE_PROTOCOL explicitly configures the image
|
|
57
|
+
* protocol, including an explicit "off". An explicit configuration is
|
|
58
|
+
* authoritative: runtime capability probes must not override it.
|
|
59
|
+
*/
|
|
60
|
+
export declare function isImageProtocolForced(): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Returns true when running in Windows Terminal with known SIXEL support.
|
|
63
|
+
*
|
|
64
|
+
* Windows Terminal introduced SIXEL support in preview 1.22.
|
|
65
|
+
*/
|
|
66
|
+
export declare function isWindowsTerminalPreviewSixelSupported(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): boolean;
|
|
67
|
+
export declare const TERMINAL_ID: TerminalId;
|
|
68
|
+
export declare const TERMINAL: TerminalInfo;
|
|
69
|
+
type ImageProtocolChangeListener = (imageProtocol: ImageProtocol | null) => void;
|
|
70
|
+
/**
|
|
71
|
+
* Subscribe to runtime image-protocol changes (e.g. the asynchronous sixel
|
|
72
|
+
* capability probe enabling graphics after startup). Returns an unsubscribe
|
|
73
|
+
* function. Listeners fire only on actual changes.
|
|
74
|
+
*/
|
|
75
|
+
export declare function onImageProtocolChanged(listener: ImageProtocolChangeListener): () => void;
|
|
76
|
+
/**
|
|
77
|
+
* Override terminal image protocol at runtime after capability probes complete.
|
|
78
|
+
*/
|
|
79
|
+
export declare function setTerminalImageProtocol(imageProtocol: ImageProtocol | null): void;
|
|
80
|
+
export declare function getTerminalInfo(terminalId: TerminalId): TerminalInfo;
|
|
81
|
+
export interface CellDimensions {
|
|
82
|
+
widthPx: number;
|
|
83
|
+
heightPx: number;
|
|
84
|
+
}
|
|
85
|
+
export interface ImageDimensions {
|
|
86
|
+
widthPx: number;
|
|
87
|
+
heightPx: number;
|
|
88
|
+
}
|
|
89
|
+
export interface ImageRenderOptions {
|
|
90
|
+
maxWidthCells?: number;
|
|
91
|
+
maxHeightCells?: number;
|
|
92
|
+
preserveAspectRatio?: boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Kitty-only: stable placement id (`p=`). Re-emitting the same image id +
|
|
95
|
+
* placement id *replaces* the existing placement instead of stacking a new
|
|
96
|
+
* copy, which makes diff-renderer repaints idempotent. Callers that render
|
|
97
|
+
* a persistent component should allocate one id per component instance.
|
|
98
|
+
*/
|
|
99
|
+
placementId?: number;
|
|
100
|
+
/**
|
|
101
|
+
* Kitty-only: stable image id (`i=`). Defaults to a content hash of the
|
|
102
|
+
* base64 payload ({@link kittyImageId}). Pass a precomputed id to avoid
|
|
103
|
+
* re-hashing large payloads on every render.
|
|
104
|
+
*/
|
|
105
|
+
imageId?: number;
|
|
106
|
+
/**
|
|
107
|
+
* Kitty-only: sink for the out-of-band data transmission (`a=t`) emitted
|
|
108
|
+
* the first time an image id is rendered. Defaults to the process-wide
|
|
109
|
+
* writer configured via {@link setKittyTransmitWriter} (stdout).
|
|
110
|
+
*/
|
|
111
|
+
onTransmit?: (sequence: string) => void;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Derive a stable 32-bit non-zero kitty image id (`i=`) from image content
|
|
115
|
+
* (FNV-1a over the base64 payload). Identical content maps to the same id, so
|
|
116
|
+
* retransmission replaces the stored image instead of accumulating copies.
|
|
117
|
+
*/
|
|
118
|
+
export declare function kittyImageId(base64Data: string): number;
|
|
119
|
+
export declare function getCellDimensions(): CellDimensions;
|
|
120
|
+
export declare function setCellDimensions(dims: CellDimensions): void;
|
|
121
|
+
export declare function encodeKitty(base64Data: string, options?: {
|
|
122
|
+
columns?: number;
|
|
123
|
+
rows?: number;
|
|
124
|
+
imageId?: number;
|
|
125
|
+
placementId?: number;
|
|
126
|
+
}): string;
|
|
127
|
+
/** Test hook: forget which kitty image ids were transmitted. */
|
|
128
|
+
export declare function resetKittyTransmissions(): void;
|
|
129
|
+
/**
|
|
130
|
+
* Override where out-of-band kitty data transmissions (`a=t`) are written.
|
|
131
|
+
* The default writes directly to stdout: a transmit-only escape is
|
|
132
|
+
* cursor-neutral (it uploads pixel data without drawing anything), so the
|
|
133
|
+
* only ordering requirement is that it reaches the terminal before the
|
|
134
|
+
* placement escape that references it — which the synchronous write during
|
|
135
|
+
* render guarantees. Tests use this to capture transmissions.
|
|
136
|
+
*/
|
|
137
|
+
export declare function setKittyTransmitWriter(writer: (sequence: string) => void): void;
|
|
138
|
+
/**
|
|
139
|
+
* Encode a kitty transmit-only (`a=t`) escape: uploads image data under a
|
|
140
|
+
* stable id without creating a placement. Chunked at 4096 bytes per spec.
|
|
141
|
+
*
|
|
142
|
+
* This is deliberately separate from placement: re-sending data (`a=t`/`a=T`)
|
|
143
|
+
* for an existing image id deletes the image and ALL of its placements, so
|
|
144
|
+
* data must be uploaded exactly once per id and repaints must go through
|
|
145
|
+
* {@link encodeKittyPlacement} only.
|
|
146
|
+
*/
|
|
147
|
+
export declare function encodeKittyTransmit(base64Data: string, imageId: number): string;
|
|
148
|
+
/**
|
|
149
|
+
* Encode a kitty placement-only (`a=p`) escape referencing previously
|
|
150
|
+
* transmitted data. Re-emitting the same i=/p= pair replaces that one
|
|
151
|
+
* placement (never stacks, never touches sibling placements), and C=1
|
|
152
|
+
* keeps the cursor where it is so the escape can be emitted from the
|
|
153
|
+
* component's first row without cursor-up tricks.
|
|
154
|
+
*/
|
|
155
|
+
export declare function encodeKittyPlacement(options: {
|
|
156
|
+
imageId: number;
|
|
157
|
+
placementId: number;
|
|
158
|
+
columns: number;
|
|
159
|
+
rows: number;
|
|
160
|
+
}): string;
|
|
161
|
+
export declare function encodeITerm2(base64Data: string, options?: {
|
|
162
|
+
width?: number | string;
|
|
163
|
+
height?: number | string;
|
|
164
|
+
name?: string;
|
|
165
|
+
preserveAspectRatio?: boolean;
|
|
166
|
+
inline?: boolean;
|
|
167
|
+
}): string;
|
|
168
|
+
export declare function calculateImageRows(imageDimensions: ImageDimensions, targetWidthCells: number, cellDimensions?: CellDimensions): number;
|
|
169
|
+
export declare function getPngDimensions(base64Data: string): ImageDimensions | null;
|
|
170
|
+
export declare function getJpegDimensions(base64Data: string): ImageDimensions | null;
|
|
171
|
+
export declare function getGifDimensions(base64Data: string): ImageDimensions | null;
|
|
172
|
+
export declare function getWebpDimensions(base64Data: string): ImageDimensions | null;
|
|
173
|
+
export declare function getImageDimensions(base64Data: string, mimeType: string): ImageDimensions | null;
|
|
174
|
+
export interface RenderedImage {
|
|
175
|
+
sequence: string;
|
|
176
|
+
rows: number;
|
|
177
|
+
/**
|
|
178
|
+
* True when the escape neither moves the cursor nor carries pixel data
|
|
179
|
+
* (kitty `a=p,C=1` placements). Cursor-neutral sequences can be emitted
|
|
180
|
+
* from the component's first row; cursor-advancing protocols
|
|
181
|
+
* (iTerm2/SIXEL) must draw from the last reserved row instead.
|
|
182
|
+
*/
|
|
183
|
+
cursorNeutral?: boolean;
|
|
184
|
+
}
|
|
185
|
+
export declare function renderImage(base64Data: string, imageDimensions: ImageDimensions, options?: ImageRenderOptions): RenderedImage | null;
|
|
186
|
+
export declare function imageFallback(mimeType: string, dimensions?: ImageDimensions, filename?: string): string;
|
|
187
|
+
export {};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether SKC may reprogram the keyboard with enhanced input protocols
|
|
3
|
+
* (the Kitty keyboard protocol and the xterm modifyOtherKeys fallback).
|
|
4
|
+
*
|
|
5
|
+
* Enabled by default. Set `SKC_TUI_KEYBOARD_PROTOCOL=0` to leave the keyboard in
|
|
6
|
+
* its default mode. Some terminals — notably Android Termius — break IME
|
|
7
|
+
* composition (e.g. Korean/Hangul syllable composition) while these enhanced
|
|
8
|
+
* modes are active, committing every intermediate composing jamo/syllable
|
|
9
|
+
* instead of only the final character. Disabling the protocol restores normal
|
|
10
|
+
* IME behavior, matching how other TUIs that leave the keyboard untouched render
|
|
11
|
+
* Korean correctly.
|
|
12
|
+
*/
|
|
13
|
+
export declare function keyboardEnhancementEnabled(): boolean;
|
|
14
|
+
/** Error codes for terminal/pipe write failures that should never crash the process. */
|
|
15
|
+
export declare function isBenignTerminalWriteError(err: unknown): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Emergency terminal restore - call this from signal/crash handlers
|
|
18
|
+
* Resets terminal state without requiring access to the ProcessTerminal instance
|
|
19
|
+
*/
|
|
20
|
+
export declare function emergencyTerminalRestore(): void;
|
|
21
|
+
/** Terminal-reported appearance (dark/light mode). */
|
|
22
|
+
export type TerminalAppearance = "dark" | "light";
|
|
23
|
+
export interface Terminal {
|
|
24
|
+
start(onInput: (data: string) => void, onResize: () => void): void;
|
|
25
|
+
stop(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Drain stdin before exiting to prevent Kitty key release events from
|
|
28
|
+
* leaking to the parent shell over slow SSH connections.
|
|
29
|
+
* @param maxMs - Maximum time to drain (default: 1000ms)
|
|
30
|
+
* @param idleMs - Exit early if no input arrives within this time (default: 50ms)
|
|
31
|
+
*/
|
|
32
|
+
drainInput(maxMs?: number, idleMs?: number): Promise<void>;
|
|
33
|
+
write(data: string): void;
|
|
34
|
+
get available(): boolean;
|
|
35
|
+
readonly isProcessTerminal?: boolean;
|
|
36
|
+
get columns(): number;
|
|
37
|
+
get rows(): number;
|
|
38
|
+
get kittyProtocolActive(): boolean;
|
|
39
|
+
moveBy(lines: number): void;
|
|
40
|
+
hideCursor(): void;
|
|
41
|
+
showCursor(): void;
|
|
42
|
+
clearLine(): void;
|
|
43
|
+
clearFromCursor(): void;
|
|
44
|
+
clearScreen(): void;
|
|
45
|
+
setTitle(title: string): void;
|
|
46
|
+
setProgress(active: boolean): void;
|
|
47
|
+
/**
|
|
48
|
+
* Register a callback for terminal appearance (dark/light) changes.
|
|
49
|
+
* Detection uses OSC 11 background color query with Mode 2031 as a change trigger.
|
|
50
|
+
* Fires when the detected appearance changes, including the initial detection.
|
|
51
|
+
*/
|
|
52
|
+
onAppearanceChange(callback: (appearance: TerminalAppearance) => void): void;
|
|
53
|
+
/** The last detected terminal appearance, or undefined if not yet known. */
|
|
54
|
+
get appearance(): TerminalAppearance | undefined;
|
|
55
|
+
}
|
|
56
|
+
interface TerminalSizeStream {
|
|
57
|
+
columns?: number;
|
|
58
|
+
rows?: number;
|
|
59
|
+
getWindowSize?: () => [number, number] | number[];
|
|
60
|
+
}
|
|
61
|
+
export declare function resolveTerminalColumns(stream?: TerminalSizeStream, envColumns?: string | undefined): number;
|
|
62
|
+
export declare function resolveTerminalRows(stream?: TerminalSizeStream, envRows?: string | undefined): number;
|
|
63
|
+
/**
|
|
64
|
+
* Real terminal using process.stdin/stdout
|
|
65
|
+
*/
|
|
66
|
+
export declare class ProcessTerminal implements Terminal {
|
|
67
|
+
#private;
|
|
68
|
+
get isProcessTerminal(): boolean;
|
|
69
|
+
get kittyProtocolActive(): boolean;
|
|
70
|
+
get appearance(): TerminalAppearance | undefined;
|
|
71
|
+
onAppearanceChange(callback: (appearance: TerminalAppearance) => void): void;
|
|
72
|
+
start(onInput: (data: string) => void, onResize: () => void): void;
|
|
73
|
+
drainInput(maxMs?: number, idleMs?: number): Promise<void>;
|
|
74
|
+
stop(): void;
|
|
75
|
+
write(data: string): void;
|
|
76
|
+
/** Invoked by the durable module-level stdout write guard (see installStdoutWriteGuard). */
|
|
77
|
+
markStdoutUnavailable(err: unknown): void;
|
|
78
|
+
get available(): boolean;
|
|
79
|
+
get columns(): number;
|
|
80
|
+
get rows(): number;
|
|
81
|
+
moveBy(lines: number): void;
|
|
82
|
+
hideCursor(): void;
|
|
83
|
+
showCursor(): void;
|
|
84
|
+
clearLine(): void;
|
|
85
|
+
clearFromCursor(): void;
|
|
86
|
+
clearScreen(): void;
|
|
87
|
+
setTitle(title: string): void;
|
|
88
|
+
setProgress(active: boolean): void;
|
|
89
|
+
}
|
|
90
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Resolve the TTY device path for stdin (fd 0) via POSIX `ttyname(3)`. */
|
|
2
|
+
export declare function getTtyPath(): string | null;
|
|
3
|
+
/**
|
|
4
|
+
* Get a stable identifier for the current terminal.
|
|
5
|
+
* Uses the TTY device path (e.g., /dev/pts/3), falling back to environment
|
|
6
|
+
* variables for terminal multiplexers or terminal emulators.
|
|
7
|
+
* Returns null if no terminal can be identified (e.g., piped input).
|
|
8
|
+
*/
|
|
9
|
+
export declare function getTerminalId(): string | null;
|