@sayknow-cli/tui 0.3.5 → 0.3.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/CHANGELOG.md +8 -0
- package/package.json +8 -9
- package/src/components/settings-list.ts +12 -0
- package/src/terminal.ts +42 -2
- package/src/tui.ts +38 -4
- package/dist/types/autocomplete.d.ts +0 -82
- package/dist/types/bracketed-paste.d.ts +0 -26
- package/dist/types/components/box.d.ts +0 -20
- package/dist/types/components/cancellable-loader.d.ts +0 -21
- package/dist/types/components/editor.d.ts +0 -112
- package/dist/types/components/image.d.ts +0 -16
- package/dist/types/components/input.d.ts +0 -16
- package/dist/types/components/loader.d.ts +0 -14
- package/dist/types/components/markdown.d.ts +0 -64
- package/dist/types/components/select-list.d.ts +0 -46
- package/dist/types/components/settings-list.d.ts +0 -39
- package/dist/types/components/spacer.d.ts +0 -11
- package/dist/types/components/tab-bar.d.ts +0 -56
- package/dist/types/components/text.d.ts +0 -13
- package/dist/types/components/truncated-text.d.ts +0 -10
- package/dist/types/editor-component.d.ts +0 -36
- package/dist/types/fuzzy.d.ts +0 -15
- package/dist/types/index.d.ts +0 -26
- package/dist/types/keybindings.d.ts +0 -201
- package/dist/types/keys.d.ts +0 -208
- package/dist/types/kill-ring.d.ts +0 -27
- package/dist/types/metrics.d.ts +0 -85
- package/dist/types/stdin-buffer.d.ts +0 -50
- package/dist/types/symbols.d.ts +0 -23
- package/dist/types/terminal-capabilities.d.ts +0 -75
- package/dist/types/terminal.d.ts +0 -80
- package/dist/types/ttyid.d.ts +0 -9
- package/dist/types/tui.d.ts +0 -182
- package/dist/types/utils.d.ts +0 -75
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Ring buffer for Emacs-style kill/yank operations.
|
|
3
|
-
*
|
|
4
|
-
* Tracks killed (deleted) text entries. Consecutive kills can accumulate
|
|
5
|
-
* into a single entry. Supports yank (paste most recent) and yank-pop
|
|
6
|
-
* (cycle through older entries).
|
|
7
|
-
*/
|
|
8
|
-
export declare class KillRing {
|
|
9
|
-
#private;
|
|
10
|
-
/**
|
|
11
|
-
* Add text to the kill ring.
|
|
12
|
-
*
|
|
13
|
-
* @param text - The killed text to add
|
|
14
|
-
* @param opts - Push options
|
|
15
|
-
* @param opts.prepend - If accumulating, prepend (backward deletion) or append (forward deletion)
|
|
16
|
-
* @param opts.accumulate - Merge with the most recent entry instead of creating a new one
|
|
17
|
-
*/
|
|
18
|
-
push(text: string, opts: {
|
|
19
|
-
prepend: boolean;
|
|
20
|
-
accumulate?: boolean;
|
|
21
|
-
}): void;
|
|
22
|
-
/** Get most recent entry without modifying the ring. */
|
|
23
|
-
peek(): string | undefined;
|
|
24
|
-
/** Move last entry to front (for yank-pop cycling). */
|
|
25
|
-
rotate(): void;
|
|
26
|
-
get length(): number;
|
|
27
|
-
}
|
package/dist/types/metrics.d.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
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;
|
|
@@ -1,50 +0,0 @@
|
|
|
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
|
-
}
|
package/dist/types/symbols.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
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 true when running in Windows Terminal with known SIXEL support.
|
|
27
|
-
*
|
|
28
|
-
* Windows Terminal introduced SIXEL support in preview 1.22.
|
|
29
|
-
*/
|
|
30
|
-
export declare function isWindowsTerminalPreviewSixelSupported(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): boolean;
|
|
31
|
-
export declare const TERMINAL_ID: TerminalId;
|
|
32
|
-
export declare const TERMINAL: TerminalInfo;
|
|
33
|
-
/**
|
|
34
|
-
* Override terminal image protocol at runtime after capability probes complete.
|
|
35
|
-
*/
|
|
36
|
-
export declare function setTerminalImageProtocol(imageProtocol: ImageProtocol | null): void;
|
|
37
|
-
export declare function getTerminalInfo(terminalId: TerminalId): TerminalInfo;
|
|
38
|
-
export interface CellDimensions {
|
|
39
|
-
widthPx: number;
|
|
40
|
-
heightPx: number;
|
|
41
|
-
}
|
|
42
|
-
export interface ImageDimensions {
|
|
43
|
-
widthPx: number;
|
|
44
|
-
heightPx: number;
|
|
45
|
-
}
|
|
46
|
-
export interface ImageRenderOptions {
|
|
47
|
-
maxWidthCells?: number;
|
|
48
|
-
maxHeightCells?: number;
|
|
49
|
-
preserveAspectRatio?: boolean;
|
|
50
|
-
}
|
|
51
|
-
export declare function getCellDimensions(): CellDimensions;
|
|
52
|
-
export declare function setCellDimensions(dims: CellDimensions): void;
|
|
53
|
-
export declare function encodeKitty(base64Data: string, options?: {
|
|
54
|
-
columns?: number;
|
|
55
|
-
rows?: number;
|
|
56
|
-
imageId?: number;
|
|
57
|
-
}): string;
|
|
58
|
-
export declare function encodeITerm2(base64Data: string, options?: {
|
|
59
|
-
width?: number | string;
|
|
60
|
-
height?: number | string;
|
|
61
|
-
name?: string;
|
|
62
|
-
preserveAspectRatio?: boolean;
|
|
63
|
-
inline?: boolean;
|
|
64
|
-
}): string;
|
|
65
|
-
export declare function calculateImageRows(imageDimensions: ImageDimensions, targetWidthCells: number, cellDimensions?: CellDimensions): number;
|
|
66
|
-
export declare function getPngDimensions(base64Data: string): ImageDimensions | null;
|
|
67
|
-
export declare function getJpegDimensions(base64Data: string): ImageDimensions | null;
|
|
68
|
-
export declare function getGifDimensions(base64Data: string): ImageDimensions | null;
|
|
69
|
-
export declare function getWebpDimensions(base64Data: string): ImageDimensions | null;
|
|
70
|
-
export declare function getImageDimensions(base64Data: string, mimeType: string): ImageDimensions | null;
|
|
71
|
-
export declare function renderImage(base64Data: string, imageDimensions: ImageDimensions, options?: ImageRenderOptions): {
|
|
72
|
-
sequence: string;
|
|
73
|
-
rows: number;
|
|
74
|
-
} | null;
|
|
75
|
-
export declare function imageFallback(mimeType: string, dimensions?: ImageDimensions, filename?: string): string;
|
package/dist/types/terminal.d.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
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
|
-
get columns(): number;
|
|
36
|
-
get rows(): number;
|
|
37
|
-
get kittyProtocolActive(): boolean;
|
|
38
|
-
moveBy(lines: number): void;
|
|
39
|
-
hideCursor(): void;
|
|
40
|
-
showCursor(): void;
|
|
41
|
-
clearLine(): void;
|
|
42
|
-
clearFromCursor(): void;
|
|
43
|
-
clearScreen(): void;
|
|
44
|
-
setTitle(title: string): void;
|
|
45
|
-
setProgress(active: boolean): void;
|
|
46
|
-
/**
|
|
47
|
-
* Register a callback for terminal appearance (dark/light) changes.
|
|
48
|
-
* Detection uses OSC 11 background color query with Mode 2031 as a change trigger.
|
|
49
|
-
* Fires when the detected appearance changes, including the initial detection.
|
|
50
|
-
*/
|
|
51
|
-
onAppearanceChange(callback: (appearance: TerminalAppearance) => void): void;
|
|
52
|
-
/** The last detected terminal appearance, or undefined if not yet known. */
|
|
53
|
-
get appearance(): TerminalAppearance | undefined;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Real terminal using process.stdin/stdout
|
|
57
|
-
*/
|
|
58
|
-
export declare class ProcessTerminal implements Terminal {
|
|
59
|
-
#private;
|
|
60
|
-
get kittyProtocolActive(): boolean;
|
|
61
|
-
get appearance(): TerminalAppearance | undefined;
|
|
62
|
-
onAppearanceChange(callback: (appearance: TerminalAppearance) => void): void;
|
|
63
|
-
start(onInput: (data: string) => void, onResize: () => void): void;
|
|
64
|
-
drainInput(maxMs?: number, idleMs?: number): Promise<void>;
|
|
65
|
-
stop(): void;
|
|
66
|
-
write(data: string): void;
|
|
67
|
-
/** Invoked by the durable module-level stdout write guard (see installStdoutWriteGuard). */
|
|
68
|
-
markStdoutUnavailable(err: unknown): void;
|
|
69
|
-
get available(): boolean;
|
|
70
|
-
get columns(): number;
|
|
71
|
-
get rows(): number;
|
|
72
|
-
moveBy(lines: number): void;
|
|
73
|
-
hideCursor(): void;
|
|
74
|
-
showCursor(): void;
|
|
75
|
-
clearLine(): void;
|
|
76
|
-
clearFromCursor(): void;
|
|
77
|
-
clearScreen(): void;
|
|
78
|
-
setTitle(title: string): void;
|
|
79
|
-
setProgress(active: boolean): void;
|
|
80
|
-
}
|
package/dist/types/ttyid.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
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;
|
package/dist/types/tui.d.ts
DELETED
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
import type { Terminal } from "./terminal";
|
|
2
|
-
import { visibleWidth } from "./utils";
|
|
3
|
-
type InputListenerResult = {
|
|
4
|
-
consume?: boolean;
|
|
5
|
-
data?: string;
|
|
6
|
-
} | undefined;
|
|
7
|
-
type InputListener = (data: string) => InputListenerResult;
|
|
8
|
-
/**
|
|
9
|
-
* Component interface - all components must implement this
|
|
10
|
-
*/
|
|
11
|
-
export interface Component {
|
|
12
|
-
/**
|
|
13
|
-
* Render the component to lines for the given viewport width
|
|
14
|
-
* @param width - Current viewport width
|
|
15
|
-
* @returns Array of strings, each representing a line
|
|
16
|
-
*/
|
|
17
|
-
render(width: number): string[];
|
|
18
|
-
/**
|
|
19
|
-
* Optional handler for keyboard input when component has focus
|
|
20
|
-
*/
|
|
21
|
-
handleInput?(data: string): void;
|
|
22
|
-
/**
|
|
23
|
-
* If true, component receives key release events (Kitty protocol).
|
|
24
|
-
* Default is false - release events are filtered out.
|
|
25
|
-
*/
|
|
26
|
-
wantsKeyRelease?: boolean;
|
|
27
|
-
/**
|
|
28
|
-
* Invalidate any cached rendering state.
|
|
29
|
-
* Called when theme changes or when component needs to re-render from scratch.
|
|
30
|
-
*/
|
|
31
|
-
invalidate(): void;
|
|
32
|
-
/**
|
|
33
|
-
* Optional cleanup hook. Called once when the component is permanently
|
|
34
|
-
* removed from the tree via removeChild/clear/dispose. Implementations MUST
|
|
35
|
-
* be idempotent. Components meant to be re-added should be detached, not
|
|
36
|
-
* removed/cleared.
|
|
37
|
-
*/
|
|
38
|
-
dispose?(): void;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Interface for components that can receive focus and display a hardware cursor.
|
|
42
|
-
* When focused, the component should emit CURSOR_MARKER at the cursor position
|
|
43
|
-
* in its render output. TUI will find this marker and position the hardware
|
|
44
|
-
* cursor there for proper IME candidate window positioning.
|
|
45
|
-
*/
|
|
46
|
-
export interface Focusable {
|
|
47
|
-
/** Set by TUI when focus changes. Component should emit CURSOR_MARKER when true. */
|
|
48
|
-
focused: boolean;
|
|
49
|
-
}
|
|
50
|
-
/** Type guard to check if a component implements Focusable */
|
|
51
|
-
export declare function isFocusable(component: Component | null): component is Component & Focusable;
|
|
52
|
-
/**
|
|
53
|
-
* Cursor position marker - APC (Application Program Command) sequence.
|
|
54
|
-
* This is a zero-width escape sequence that terminals ignore.
|
|
55
|
-
* Components emit this at the cursor position when focused.
|
|
56
|
-
* TUI finds and strips this marker, then positions the hardware cursor there.
|
|
57
|
-
*/
|
|
58
|
-
export declare const CURSOR_MARKER = "\u001B_pi:c\u0007";
|
|
59
|
-
export { visibleWidth };
|
|
60
|
-
/**
|
|
61
|
-
* Anchor position for overlays
|
|
62
|
-
*/
|
|
63
|
-
export type OverlayAnchor = "center" | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "top-center" | "bottom-center" | "left-center" | "right-center";
|
|
64
|
-
/**
|
|
65
|
-
* Margin configuration for overlays
|
|
66
|
-
*/
|
|
67
|
-
export interface OverlayMargin {
|
|
68
|
-
top?: number;
|
|
69
|
-
right?: number;
|
|
70
|
-
bottom?: number;
|
|
71
|
-
left?: number;
|
|
72
|
-
}
|
|
73
|
-
/** Value that can be absolute (number) or percentage (string like "50%") */
|
|
74
|
-
export type SizeValue = number | `${number}%`;
|
|
75
|
-
/**
|
|
76
|
-
* Options for overlay positioning and sizing.
|
|
77
|
-
* Values can be absolute numbers or percentage strings (e.g., "50%").
|
|
78
|
-
*/
|
|
79
|
-
export interface OverlayOptions {
|
|
80
|
-
/** Width in columns, or percentage of terminal width (e.g., "50%") */
|
|
81
|
-
width?: SizeValue;
|
|
82
|
-
/** Minimum width in columns */
|
|
83
|
-
minWidth?: number;
|
|
84
|
-
/** Maximum height in rows, or percentage of terminal height (e.g., "50%") */
|
|
85
|
-
maxHeight?: SizeValue;
|
|
86
|
-
/** Anchor point for positioning (default: 'center') */
|
|
87
|
-
anchor?: OverlayAnchor;
|
|
88
|
-
/** Horizontal offset from anchor position (positive = right) */
|
|
89
|
-
offsetX?: number;
|
|
90
|
-
/** Vertical offset from anchor position (positive = down) */
|
|
91
|
-
offsetY?: number;
|
|
92
|
-
/** Row position: absolute number, or percentage (e.g., "25%" = 25% from top) */
|
|
93
|
-
row?: SizeValue;
|
|
94
|
-
/** Column position: absolute number, or percentage (e.g., "50%" = centered horizontally) */
|
|
95
|
-
col?: SizeValue;
|
|
96
|
-
/** Margin from terminal edges. Number applies to all sides. */
|
|
97
|
-
margin?: OverlayMargin | number;
|
|
98
|
-
/**
|
|
99
|
-
* Control overlay visibility based on terminal dimensions.
|
|
100
|
-
* If provided, overlay is only rendered when this returns true.
|
|
101
|
-
* Called each render cycle with current terminal dimensions.
|
|
102
|
-
*/
|
|
103
|
-
visible?: (termWidth: number, termHeight: number) => boolean;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Handle returned by showOverlay for controlling the overlay
|
|
107
|
-
*/
|
|
108
|
-
export interface OverlayHandle {
|
|
109
|
-
/** Permanently remove the overlay (cannot be shown again) */
|
|
110
|
-
hide(): void;
|
|
111
|
-
/** Temporarily hide or show the overlay */
|
|
112
|
-
setHidden(hidden: boolean): void;
|
|
113
|
-
/** Check if overlay is temporarily hidden */
|
|
114
|
-
isHidden(): boolean;
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Container - a component that contains other components
|
|
118
|
-
*/
|
|
119
|
-
export declare class Container implements Component {
|
|
120
|
-
#private;
|
|
121
|
-
children: Component[];
|
|
122
|
-
addChild(component: Component): void;
|
|
123
|
-
removeChild(component: Component): void;
|
|
124
|
-
/** Remove a child without disposing it (for detach-then-readd reuse). */
|
|
125
|
-
detachChild(component: Component): void;
|
|
126
|
-
clear(): void;
|
|
127
|
-
/** Remove all children without disposing them (for detach-then-readd reuse). */
|
|
128
|
-
detachAll(): void;
|
|
129
|
-
dispose(): void;
|
|
130
|
-
invalidate(): void;
|
|
131
|
-
render(width: number): string[];
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* TUI - Main class for managing terminal UI with differential rendering
|
|
135
|
-
*/
|
|
136
|
-
export declare class TUI extends Container {
|
|
137
|
-
#private;
|
|
138
|
-
terminal: Terminal;
|
|
139
|
-
/** Global callback for debug key (Shift+Ctrl+D). Called before input is forwarded to focused component. */
|
|
140
|
-
onDebug?: () => void;
|
|
141
|
-
overlayStack: {
|
|
142
|
-
component: Component;
|
|
143
|
-
options?: OverlayOptions;
|
|
144
|
-
preFocus: Component | null;
|
|
145
|
-
hidden: boolean;
|
|
146
|
-
}[];
|
|
147
|
-
constructor(terminal: Terminal, showHardwareCursor?: boolean);
|
|
148
|
-
get fullRedraws(): number;
|
|
149
|
-
getShowHardwareCursor(): boolean;
|
|
150
|
-
setShowHardwareCursor(enabled: boolean): void;
|
|
151
|
-
getClearOnShrink(): boolean;
|
|
152
|
-
/**
|
|
153
|
-
* Set whether to trigger full re-render when content shrinks.
|
|
154
|
-
* When true (default), empty rows are cleared when content shrinks.
|
|
155
|
-
* When false, empty rows remain (reduces redraws on slower terminals).
|
|
156
|
-
*/
|
|
157
|
-
setClearOnShrink(enabled: boolean): void;
|
|
158
|
-
setFocus(component: Component | null): void;
|
|
159
|
-
setBottomPinnedComponent(component: Component | null): void;
|
|
160
|
-
/**
|
|
161
|
-
* Show an overlay component with configurable positioning and sizing.
|
|
162
|
-
* Returns a handle to control the overlay's visibility.
|
|
163
|
-
*/
|
|
164
|
-
showOverlay(component: Component, options?: OverlayOptions): OverlayHandle;
|
|
165
|
-
/** Hide the topmost overlay and restore previous focus. */
|
|
166
|
-
hideOverlay(): void;
|
|
167
|
-
/** Check if there are any visible overlays */
|
|
168
|
-
hasOverlay(): boolean;
|
|
169
|
-
invalidate(): void;
|
|
170
|
-
start(): void;
|
|
171
|
-
get terminalAvailable(): boolean;
|
|
172
|
-
addInputListener(listener: InputListener): () => void;
|
|
173
|
-
removeInputListener(listener: InputListener): void;
|
|
174
|
-
stop(): void;
|
|
175
|
-
requestRender(force?: boolean, source?: string): void;
|
|
176
|
-
getLineRenderCacheStats(): {
|
|
177
|
-
normalizationSize: number;
|
|
178
|
-
truncationSize: number;
|
|
179
|
-
normalizationLimit: number;
|
|
180
|
-
truncationLimit: number;
|
|
181
|
-
};
|
|
182
|
-
}
|
package/dist/types/utils.d.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { Ellipsis, type ExtractSegmentsResult, type SliceResult } from "@sayknow-cli/natives";
|
|
2
|
-
export { Ellipsis } from "@sayknow-cli/natives";
|
|
3
|
-
export { getDefaultTabWidth, getIndentation } from "@sayknow-cli/utils";
|
|
4
|
-
export declare function isPrintableAscii(text: string): boolean;
|
|
5
|
-
export declare function sliceWithWidth(line: string, startCol: number, length: number, strict?: boolean | null): SliceResult;
|
|
6
|
-
export declare function truncateToWidth(text: string, maxWidth: number, ellipsisKind?: Ellipsis | null, pad?: boolean | null): string;
|
|
7
|
-
export declare function wrapTextWithAnsi(text: string, width: number): string[];
|
|
8
|
-
export declare function extractSegments(line: string, beforeEnd: number, afterStart: number, afterLen: number, strictAfter: boolean): ExtractSegmentsResult;
|
|
9
|
-
/**
|
|
10
|
-
* Tab width in columns for `file`, using `process.cwd()` as the project root for relative paths.
|
|
11
|
-
*/
|
|
12
|
-
export declare function getIndentationNoescape(file?: string): number;
|
|
13
|
-
export declare function replaceTabs(text: string, file?: string): string;
|
|
14
|
-
/**
|
|
15
|
-
* Returns a string of n spaces. Uses a pre-allocated buffer for efficiency.
|
|
16
|
-
*/
|
|
17
|
-
export declare function padding(n: number): string;
|
|
18
|
-
/**
|
|
19
|
-
* Get the shared grapheme segmenter instance.
|
|
20
|
-
*/
|
|
21
|
-
export declare function getSegmenter(): Intl.Segmenter;
|
|
22
|
-
export declare function visibleWidthRaw(str: string): number;
|
|
23
|
-
/**
|
|
24
|
-
* Calculate the visible width of a string in terminal columns.
|
|
25
|
-
*/
|
|
26
|
-
export declare function visibleWidth(str: string): number;
|
|
27
|
-
/**
|
|
28
|
-
* Normalize text for terminal output without changing logical editor content.
|
|
29
|
-
* Some terminals render canonically decomposed Hangul jamo or precomposed
|
|
30
|
-
* Thai/Lao AM vowels inconsistently during differential repaint. Emit a stable
|
|
31
|
-
* terminal form while keeping the component/source strings unchanged.
|
|
32
|
-
*/
|
|
33
|
-
export declare function normalizeTerminalOutput(str: string): string;
|
|
34
|
-
/**
|
|
35
|
-
* Check if a character is whitespace.
|
|
36
|
-
*/
|
|
37
|
-
export declare function isWhitespaceChar(char: string): boolean;
|
|
38
|
-
/**
|
|
39
|
-
* Check if a character is punctuation.
|
|
40
|
-
*/
|
|
41
|
-
export declare function isPunctuationChar(char: string): boolean;
|
|
42
|
-
export type WordNavKind = "whitespace" | "delimiter" | "cjk" | "word" | "other";
|
|
43
|
-
/**
|
|
44
|
-
* Coarse Unicode-aware character classification for word navigation (Option/Alt + Left/Right).
|
|
45
|
-
* This intentionally avoids language-specific word segmentation for predictability across scripts.
|
|
46
|
-
*/
|
|
47
|
-
export declare function getWordNavKind(grapheme: string): WordNavKind;
|
|
48
|
-
export declare function isWordNavJoiner(grapheme: string): boolean;
|
|
49
|
-
/**
|
|
50
|
-
* Move the cursor one "word" to the left using Unicode-aware coarse navigation.
|
|
51
|
-
*
|
|
52
|
-
* Returns a new cursor index in the range [0, text.length].
|
|
53
|
-
*/
|
|
54
|
-
export declare function moveWordLeft(text: string, cursor: number): number;
|
|
55
|
-
/**
|
|
56
|
-
* Move the cursor one "word" to the right using Unicode-aware coarse navigation.
|
|
57
|
-
*
|
|
58
|
-
* Returns a new cursor index in the range [0, text.length].
|
|
59
|
-
*/
|
|
60
|
-
export declare function moveWordRight(text: string, cursor: number): number;
|
|
61
|
-
/**
|
|
62
|
-
* Apply background color to a line, padding to full width.
|
|
63
|
-
*
|
|
64
|
-
* @param line - Line of text (may contain ANSI codes)
|
|
65
|
-
* @param width - Total width to pad to
|
|
66
|
-
* @param bgFn - Background color function
|
|
67
|
-
* @returns Line with background applied and padded to width
|
|
68
|
-
*/
|
|
69
|
-
export declare function applyBackgroundToLine(line: string, width: number, bgFn: (text: string) => string): string;
|
|
70
|
-
/**
|
|
71
|
-
* Extract a range of visible columns from a line. Handles ANSI codes and wide chars.
|
|
72
|
-
*
|
|
73
|
-
* @param strict - If true, exclude wide chars at boundary that would extend past the range
|
|
74
|
-
*/
|
|
75
|
-
export declare function sliceByColumn(line: string, startCol: number, length: number, strict?: boolean): string;
|