@oh-my-pi/pi-tui 15.1.1 → 15.1.2
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/autocomplete.d.ts +64 -0
- package/dist/types/bracketed-paste.d.ts +26 -0
- package/dist/types/components/box.d.ts +15 -0
- package/dist/types/components/cancellable-loader.d.ts +21 -0
- package/dist/types/components/editor.d.ts +101 -0
- package/dist/types/components/image.d.ts +16 -0
- package/dist/types/components/input.d.ts +16 -0
- package/dist/types/components/loader.d.ts +16 -0
- package/dist/types/components/markdown.d.ts +61 -0
- package/dist/types/components/select-list.d.ts +46 -0
- package/dist/types/components/settings-list.d.ts +31 -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 +13 -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 +25 -0
- package/dist/types/keybindings.d.ts +189 -0
- package/dist/types/keys.d.ts +208 -0
- package/dist/types/kill-ring.d.ts +27 -0
- package/dist/types/stdin-buffer.d.ts +43 -0
- package/dist/types/symbols.d.ts +23 -0
- package/dist/types/terminal-capabilities.d.ts +75 -0
- package/dist/types/terminal.d.ts +61 -0
- package/dist/types/ttyid.d.ts +9 -0
- package/dist/types/tui.d.ts +161 -0
- package/dist/types/utils.d.ts +74 -0
- package/package.json +9 -8
- package/src/components/editor.ts +4 -6
- package/src/components/input.ts +1 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export interface AutocompleteItem {
|
|
2
|
+
value: string;
|
|
3
|
+
label: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
/** Dim hint text shown inline after cursor when this item is selected */
|
|
6
|
+
hint?: string;
|
|
7
|
+
}
|
|
8
|
+
type Awaitable<T> = T | Promise<T>;
|
|
9
|
+
export interface SlashCommand {
|
|
10
|
+
name: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
argumentHint?: string;
|
|
13
|
+
getArgumentCompletions?(argumentPrefix: string): Awaitable<AutocompleteItem[] | null>;
|
|
14
|
+
/** Return inline hint text for the current argument state (shown as dim ghost text after cursor) */
|
|
15
|
+
getInlineHint?(argumentText: string): string | null;
|
|
16
|
+
}
|
|
17
|
+
export interface AutocompleteProvider {
|
|
18
|
+
/** Get autocomplete suggestions for current text/cursor position */
|
|
19
|
+
getSuggestions(lines: string[], cursorLine: number, cursorCol: number): Promise<{
|
|
20
|
+
items: AutocompleteItem[];
|
|
21
|
+
prefix: string;
|
|
22
|
+
} | null>;
|
|
23
|
+
/** Apply the selected item and return new text + cursor position */
|
|
24
|
+
applyCompletion(lines: string[], cursorLine: number, cursorCol: number, item: AutocompleteItem, prefix: string): {
|
|
25
|
+
lines: string[];
|
|
26
|
+
cursorLine: number;
|
|
27
|
+
cursorCol: number;
|
|
28
|
+
onApplied?: () => void;
|
|
29
|
+
};
|
|
30
|
+
/** Get inline hint text to show as dim ghost text after the cursor */
|
|
31
|
+
getInlineHint?(lines: string[], cursorLine: number, cursorCol: number): string | null;
|
|
32
|
+
/** Synchronously try to complete a slash command at the start of a line (no async I/O). */
|
|
33
|
+
/** Returns matched items and the full prefix, or null if not applicable. */
|
|
34
|
+
trySyncSlashCompletion?(textBeforeCursor: string): {
|
|
35
|
+
items: AutocompleteItem[];
|
|
36
|
+
prefix: string;
|
|
37
|
+
} | null;
|
|
38
|
+
}
|
|
39
|
+
export declare class CombinedAutocompleteProvider implements AutocompleteProvider {
|
|
40
|
+
#private;
|
|
41
|
+
constructor(commands?: (SlashCommand | AutocompleteItem)[], basePath?: string);
|
|
42
|
+
getSuggestions(lines: string[], cursorLine: number, cursorCol: number): Promise<{
|
|
43
|
+
items: AutocompleteItem[];
|
|
44
|
+
prefix: string;
|
|
45
|
+
} | null>;
|
|
46
|
+
applyCompletion(lines: string[], cursorLine: number, cursorCol: number, item: AutocompleteItem, prefix: string): {
|
|
47
|
+
lines: string[];
|
|
48
|
+
cursorLine: number;
|
|
49
|
+
cursorCol: number;
|
|
50
|
+
};
|
|
51
|
+
invalidateDirCache(dir?: string): void;
|
|
52
|
+
getForceFileSuggestions(lines: string[], cursorLine: number, cursorCol: number): Promise<{
|
|
53
|
+
items: AutocompleteItem[];
|
|
54
|
+
prefix: string;
|
|
55
|
+
} | null>;
|
|
56
|
+
shouldTriggerFileCompletion(lines: string[], cursorLine: number, cursorCol: number): boolean;
|
|
57
|
+
/** Get inline hint text for slash commands with subcommand hints */
|
|
58
|
+
getInlineHint(lines: string[], cursorLine: number, cursorCol: number): string | null;
|
|
59
|
+
trySyncSlashCompletion(textBeforeCursor: string): {
|
|
60
|
+
items: AutocompleteItem[];
|
|
61
|
+
prefix: string;
|
|
62
|
+
} | null;
|
|
63
|
+
}
|
|
64
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type PasteResult = {
|
|
2
|
+
handled: false;
|
|
3
|
+
} | {
|
|
4
|
+
handled: true;
|
|
5
|
+
pasteContent?: string;
|
|
6
|
+
remaining: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Handles bracketed paste mode buffering for terminal input components.
|
|
10
|
+
*
|
|
11
|
+
* Bracketed paste mode wraps pasted content between start (\x1b[200~) and
|
|
12
|
+
* end (\x1b[201~) markers, which may arrive split across multiple chunks.
|
|
13
|
+
* This class buffers incoming data and assembles complete paste payloads.
|
|
14
|
+
*/
|
|
15
|
+
export declare class BracketedPasteHandler {
|
|
16
|
+
#private;
|
|
17
|
+
/**
|
|
18
|
+
* Process incoming terminal data for bracketed paste sequences.
|
|
19
|
+
*
|
|
20
|
+
* @returns `{ handled: false }` if the data contains no paste sequence and
|
|
21
|
+
* should be processed normally. `{ handled: true }` if the data was
|
|
22
|
+
* consumed by paste buffering — `pasteContent` is set when a complete
|
|
23
|
+
* paste has been assembled; omitted when still buffering.
|
|
24
|
+
*/
|
|
25
|
+
process(data: string): PasteResult;
|
|
26
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Component } from "../tui";
|
|
2
|
+
/**
|
|
3
|
+
* Box component - a container that applies padding and background to all children
|
|
4
|
+
*/
|
|
5
|
+
export declare class Box implements Component {
|
|
6
|
+
#private;
|
|
7
|
+
children: Component[];
|
|
8
|
+
constructor(paddingX?: number, paddingY?: number, bgFn?: (text: string) => string);
|
|
9
|
+
addChild(component: Component): void;
|
|
10
|
+
removeChild(component: Component): void;
|
|
11
|
+
clear(): void;
|
|
12
|
+
setBgFn(bgFn?: (text: string) => string): void;
|
|
13
|
+
invalidate(): void;
|
|
14
|
+
render(width: number): string[];
|
|
15
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Loader } from "./loader";
|
|
2
|
+
/**
|
|
3
|
+
* Loader that can be cancelled with Escape.
|
|
4
|
+
* Extends Loader with an AbortSignal for cancelling async operations.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const loader = new CancellableLoader(tui, cyan, dim, "Working...");
|
|
8
|
+
* loader.onAbort = () => done(null);
|
|
9
|
+
* doWork(loader.signal).then(done);
|
|
10
|
+
*/
|
|
11
|
+
export declare class CancellableLoader extends Loader {
|
|
12
|
+
#private;
|
|
13
|
+
/** Called when user presses Escape */
|
|
14
|
+
onAbort?: () => void;
|
|
15
|
+
/** AbortSignal that is aborted when user presses Escape */
|
|
16
|
+
get signal(): AbortSignal;
|
|
17
|
+
/** Whether the loader was aborted */
|
|
18
|
+
get aborted(): boolean;
|
|
19
|
+
handleInput(data: string): void;
|
|
20
|
+
dispose(): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { AutocompleteProvider } from "../autocomplete";
|
|
2
|
+
import type { SymbolTheme } from "../symbols";
|
|
3
|
+
import { type Component, type Focusable } from "../tui";
|
|
4
|
+
import { type SelectListTheme } from "./select-list";
|
|
5
|
+
export interface EditorTheme {
|
|
6
|
+
borderColor: (str: string) => string;
|
|
7
|
+
selectList: SelectListTheme;
|
|
8
|
+
symbols: SymbolTheme;
|
|
9
|
+
editorPaddingX?: number;
|
|
10
|
+
/** Style function for inline hint/ghost text (dim text after cursor) */
|
|
11
|
+
hintStyle?: (text: string) => string;
|
|
12
|
+
}
|
|
13
|
+
export interface EditorTopBorder {
|
|
14
|
+
/** The status content (already styled) */
|
|
15
|
+
content: string;
|
|
16
|
+
/** Visible width of the content */
|
|
17
|
+
width: number;
|
|
18
|
+
}
|
|
19
|
+
interface HistoryEntry {
|
|
20
|
+
prompt: string;
|
|
21
|
+
}
|
|
22
|
+
interface HistoryStorage {
|
|
23
|
+
add(prompt: string, cwd?: string): Promise<void>;
|
|
24
|
+
getRecent(limit: number): HistoryEntry[];
|
|
25
|
+
}
|
|
26
|
+
export declare class Editor implements Component, Focusable {
|
|
27
|
+
#private;
|
|
28
|
+
/** Focusable interface - set by TUI when focus changes */
|
|
29
|
+
focused: boolean;
|
|
30
|
+
/** When set, replaces the normal cursor glyph at end-of-text with this ANSI-styled string. */
|
|
31
|
+
cursorOverride: string | undefined;
|
|
32
|
+
/** Display width of the cursorOverride glyph (needed because override may contain ANSI escapes). */
|
|
33
|
+
cursorOverrideWidth: number | undefined;
|
|
34
|
+
borderColor: (str: string) => string;
|
|
35
|
+
onAutocompleteUpdate?: () => void;
|
|
36
|
+
onSubmit?: (text: string) => void;
|
|
37
|
+
onAltEnter?: (text: string) => void;
|
|
38
|
+
onChange?: (text: string) => void;
|
|
39
|
+
onAutocompleteCancel?: () => void;
|
|
40
|
+
disableSubmit: boolean;
|
|
41
|
+
constructor(theme: EditorTheme);
|
|
42
|
+
setAutocompleteProvider(provider: AutocompleteProvider): void;
|
|
43
|
+
/**
|
|
44
|
+
* Set custom content for the top border (e.g., status line).
|
|
45
|
+
* Pass undefined to use the default plain border.
|
|
46
|
+
*/
|
|
47
|
+
setTopBorder(content: EditorTopBorder | undefined): void;
|
|
48
|
+
/**
|
|
49
|
+
* Show or hide the editor border chrome.
|
|
50
|
+
*/
|
|
51
|
+
setBorderVisible(borderVisible: boolean): void;
|
|
52
|
+
setPromptGutter(promptGutter: string | undefined): void;
|
|
53
|
+
/**
|
|
54
|
+
* Get the available width for top border content given a total terminal width.
|
|
55
|
+
* Accounts for the border characters and horizontal padding when visible.
|
|
56
|
+
*/
|
|
57
|
+
getTopBorderAvailableWidth(terminalWidth: number): number;
|
|
58
|
+
/**
|
|
59
|
+
* Use the real terminal cursor instead of rendering a cursor glyph.
|
|
60
|
+
*/
|
|
61
|
+
setUseTerminalCursor(useTerminalCursor: boolean): void;
|
|
62
|
+
getUseTerminalCursor(): boolean;
|
|
63
|
+
setMaxHeight(maxHeight: number | undefined): void;
|
|
64
|
+
setPaddingX(paddingX: number): void;
|
|
65
|
+
getAutocompleteMaxVisible(): number;
|
|
66
|
+
setAutocompleteMaxVisible(maxVisible: number): void;
|
|
67
|
+
setHistoryStorage(storage: HistoryStorage): void;
|
|
68
|
+
/**
|
|
69
|
+
* Add a prompt to history for up/down arrow navigation.
|
|
70
|
+
* Called after successful submission.
|
|
71
|
+
*/
|
|
72
|
+
addToHistory(text: string): void;
|
|
73
|
+
invalidate(): void;
|
|
74
|
+
render(width: number): string[];
|
|
75
|
+
handleInput(data: string): void;
|
|
76
|
+
getText(): string;
|
|
77
|
+
/**
|
|
78
|
+
* Get text with paste markers expanded to their actual content.
|
|
79
|
+
* Use this when you need the full content (e.g., for external editor).
|
|
80
|
+
*/
|
|
81
|
+
getExpandedText(): string;
|
|
82
|
+
getLines(): string[];
|
|
83
|
+
getCursor(): {
|
|
84
|
+
line: number;
|
|
85
|
+
col: number;
|
|
86
|
+
};
|
|
87
|
+
moveToLineStart(): void;
|
|
88
|
+
moveToLineEnd(): void;
|
|
89
|
+
moveToMessageStart(): void;
|
|
90
|
+
moveToMessageEnd(): void;
|
|
91
|
+
/**
|
|
92
|
+
* Undo the last meaningful edit while ignoring transient text that is still present at the cursor.
|
|
93
|
+
* Used for command-like autocomplete actions whose typed trigger should not count as the edit being undone.
|
|
94
|
+
*/
|
|
95
|
+
undoPastTransientText(transientText: string): void;
|
|
96
|
+
setText(text: string): void;
|
|
97
|
+
/** Insert text at the current cursor position */
|
|
98
|
+
insertText(text: string): void;
|
|
99
|
+
isShowingAutocomplete(): boolean;
|
|
100
|
+
}
|
|
101
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ImageDimensions } from "../terminal-capabilities";
|
|
2
|
+
import type { Component } from "../tui";
|
|
3
|
+
export interface ImageTheme {
|
|
4
|
+
fallbackColor: (str: string) => string;
|
|
5
|
+
}
|
|
6
|
+
export interface ImageOptions {
|
|
7
|
+
maxWidthCells?: number;
|
|
8
|
+
maxHeightCells?: number;
|
|
9
|
+
filename?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class Image implements Component {
|
|
12
|
+
#private;
|
|
13
|
+
constructor(base64Data: string, mimeType: string, theme: ImageTheme, options?: ImageOptions, dimensions?: ImageDimensions);
|
|
14
|
+
invalidate(): void;
|
|
15
|
+
render(width: number): string[];
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Component, type Focusable } from "../tui";
|
|
2
|
+
/**
|
|
3
|
+
* Input component - single-line text input with horizontal scrolling
|
|
4
|
+
*/
|
|
5
|
+
export declare class Input implements Component, Focusable {
|
|
6
|
+
#private;
|
|
7
|
+
onSubmit?: (value: string) => void;
|
|
8
|
+
onEscape?: () => void;
|
|
9
|
+
/** Focusable interface - set by TUI when focus changes */
|
|
10
|
+
focused: boolean;
|
|
11
|
+
getValue(): string;
|
|
12
|
+
setValue(value: string): void;
|
|
13
|
+
handleInput(data: string): void;
|
|
14
|
+
invalidate(): void;
|
|
15
|
+
render(width: number): string[];
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { TUI } from "../tui";
|
|
2
|
+
import { Text } from "./text";
|
|
3
|
+
/**
|
|
4
|
+
* Loader component that updates every 80ms with spinning animation
|
|
5
|
+
*/
|
|
6
|
+
export declare class Loader extends Text {
|
|
7
|
+
#private;
|
|
8
|
+
private spinnerColorFn;
|
|
9
|
+
private messageColorFn;
|
|
10
|
+
private message;
|
|
11
|
+
constructor(ui: TUI, spinnerColorFn: (str: string) => string, messageColorFn: (str: string) => string, message?: string, spinnerFrames?: string[]);
|
|
12
|
+
render(width: number): string[];
|
|
13
|
+
start(): void;
|
|
14
|
+
stop(): void;
|
|
15
|
+
setMessage(message: string): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { SymbolTheme } from "../symbols";
|
|
2
|
+
import type { Component } from "../tui";
|
|
3
|
+
/** Drop all L2 cache entries. Call on theme change to prevent stale styled output. */
|
|
4
|
+
export declare function clearRenderCache(): void;
|
|
5
|
+
/**
|
|
6
|
+
* Default text styling for markdown content.
|
|
7
|
+
* Applied to all text unless overridden by markdown formatting.
|
|
8
|
+
*/
|
|
9
|
+
export interface DefaultTextStyle {
|
|
10
|
+
/** Foreground color function */
|
|
11
|
+
color?: (text: string) => string;
|
|
12
|
+
/** Background color function */
|
|
13
|
+
bgColor?: (text: string) => string;
|
|
14
|
+
/** Bold text */
|
|
15
|
+
bold?: boolean;
|
|
16
|
+
/** Italic text */
|
|
17
|
+
italic?: boolean;
|
|
18
|
+
/** Strikethrough text */
|
|
19
|
+
strikethrough?: boolean;
|
|
20
|
+
/** Underline text */
|
|
21
|
+
underline?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Theme functions for markdown elements.
|
|
25
|
+
* Each function takes text and returns styled text with ANSI codes.
|
|
26
|
+
*/
|
|
27
|
+
export interface MarkdownTheme {
|
|
28
|
+
heading: (text: string) => string;
|
|
29
|
+
link: (text: string) => string;
|
|
30
|
+
linkUrl: (text: string) => string;
|
|
31
|
+
code: (text: string) => string;
|
|
32
|
+
codeBlock: (text: string) => string;
|
|
33
|
+
codeBlockBorder: (text: string) => string;
|
|
34
|
+
quote: (text: string) => string;
|
|
35
|
+
quoteBorder: (text: string) => string;
|
|
36
|
+
hr: (text: string) => string;
|
|
37
|
+
listBullet: (text: string) => string;
|
|
38
|
+
bold: (text: string) => string;
|
|
39
|
+
italic: (text: string) => string;
|
|
40
|
+
strikethrough: (text: string) => string;
|
|
41
|
+
underline: (text: string) => string;
|
|
42
|
+
highlightCode?: (code: string, lang?: string) => string[];
|
|
43
|
+
/**
|
|
44
|
+
* Resolve a mermaid ASCII rendering by fenced block source text.
|
|
45
|
+
* Return null to fall back to fenced code rendering.
|
|
46
|
+
*/
|
|
47
|
+
resolveMermaidAscii?: (source: string) => string | null;
|
|
48
|
+
symbols: SymbolTheme;
|
|
49
|
+
}
|
|
50
|
+
export declare class Markdown implements Component {
|
|
51
|
+
#private;
|
|
52
|
+
constructor(text: string, paddingX: number, paddingY: number, theme: MarkdownTheme, defaultTextStyle?: DefaultTextStyle, codeBlockIndent?: number);
|
|
53
|
+
setText(text: string): void;
|
|
54
|
+
invalidate(): void;
|
|
55
|
+
render(width: number): string[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Render inline markdown (bold, italic, code, links, strikethrough) to a styled string.
|
|
59
|
+
* Unlike the full Markdown component, this produces a single line with no block-level elements.
|
|
60
|
+
*/
|
|
61
|
+
export declare function renderInlineMarkdown(text: string, mdTheme: MarkdownTheme, baseColor?: (t: string) => string): string;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { SymbolTheme } from "../symbols";
|
|
2
|
+
import type { Component } from "../tui";
|
|
3
|
+
export interface SelectItem {
|
|
4
|
+
value: string;
|
|
5
|
+
label: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
/** Dim hint text shown inline after cursor when this item is selected */
|
|
8
|
+
hint?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface SelectListTheme {
|
|
11
|
+
selectedPrefix: (text: string) => string;
|
|
12
|
+
selectedText: (text: string) => string;
|
|
13
|
+
description: (text: string) => string;
|
|
14
|
+
scrollInfo: (text: string) => string;
|
|
15
|
+
noMatch: (text: string) => string;
|
|
16
|
+
symbols: SymbolTheme;
|
|
17
|
+
}
|
|
18
|
+
export interface SelectListTruncatePrimaryContext {
|
|
19
|
+
text: string;
|
|
20
|
+
maxWidth: number;
|
|
21
|
+
columnWidth: number;
|
|
22
|
+
item: SelectItem;
|
|
23
|
+
isSelected: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface SelectListLayoutOptions {
|
|
26
|
+
minPrimaryColumnWidth?: number;
|
|
27
|
+
maxPrimaryColumnWidth?: number;
|
|
28
|
+
truncatePrimary?: (context: SelectListTruncatePrimaryContext) => string;
|
|
29
|
+
}
|
|
30
|
+
export declare class SelectList implements Component {
|
|
31
|
+
#private;
|
|
32
|
+
private readonly items;
|
|
33
|
+
private readonly maxVisible;
|
|
34
|
+
private readonly theme;
|
|
35
|
+
private readonly layout;
|
|
36
|
+
onSelect?: (item: SelectItem) => void;
|
|
37
|
+
onCancel?: () => void;
|
|
38
|
+
onSelectionChange?: (item: SelectItem) => void;
|
|
39
|
+
constructor(items: ReadonlyArray<SelectItem>, maxVisible: number, theme: SelectListTheme, layout?: SelectListLayoutOptions);
|
|
40
|
+
setFilter(filter: string): void;
|
|
41
|
+
setSelectedIndex(index: number): void;
|
|
42
|
+
invalidate(): void;
|
|
43
|
+
render(width: number): string[];
|
|
44
|
+
handleInput(keyData: string): void;
|
|
45
|
+
getSelectedItem(): SelectItem | null;
|
|
46
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Component } from "../tui";
|
|
2
|
+
export interface SettingItem {
|
|
3
|
+
/** Unique identifier for this setting */
|
|
4
|
+
id: string;
|
|
5
|
+
/** Display label (left side) */
|
|
6
|
+
label: string;
|
|
7
|
+
/** Optional description shown when selected */
|
|
8
|
+
description?: string;
|
|
9
|
+
/** Current value to display (right side) */
|
|
10
|
+
currentValue: string;
|
|
11
|
+
/** If provided, Enter/Space cycles through these values */
|
|
12
|
+
values?: string[];
|
|
13
|
+
/** If provided, Enter opens this submenu. Receives current value and done callback. */
|
|
14
|
+
submenu?: (currentValue: string, done: (selectedValue?: string) => void) => Component;
|
|
15
|
+
}
|
|
16
|
+
export interface SettingsListTheme {
|
|
17
|
+
label: (text: string, selected: boolean) => string;
|
|
18
|
+
value: (text: string, selected: boolean) => string;
|
|
19
|
+
description: (text: string) => string;
|
|
20
|
+
cursor: string;
|
|
21
|
+
hint: (text: string) => string;
|
|
22
|
+
}
|
|
23
|
+
export declare class SettingsList implements Component {
|
|
24
|
+
#private;
|
|
25
|
+
constructor(items: SettingItem[], maxVisible: number, theme: SettingsListTheme, onChange: (id: string, newValue: string) => void, onCancel: () => void);
|
|
26
|
+
/** Update an item's currentValue */
|
|
27
|
+
updateValue(id: string, newValue: string): void;
|
|
28
|
+
invalidate(): void;
|
|
29
|
+
render(width: number): string[];
|
|
30
|
+
handleInput(data: string): void;
|
|
31
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Component } from "../tui";
|
|
2
|
+
/**
|
|
3
|
+
* Spacer component that renders empty lines
|
|
4
|
+
*/
|
|
5
|
+
export declare class Spacer implements Component {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(lines?: number);
|
|
8
|
+
setLines(lines: number): void;
|
|
9
|
+
invalidate(): void;
|
|
10
|
+
render(_width: number): string[];
|
|
11
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Component } from "../tui";
|
|
2
|
+
/** Tab definition */
|
|
3
|
+
export interface Tab {
|
|
4
|
+
/** Unique identifier for the tab */
|
|
5
|
+
id: string;
|
|
6
|
+
/** Display label shown in the tab bar */
|
|
7
|
+
label: string;
|
|
8
|
+
}
|
|
9
|
+
/** Theme for styling the tab bar */
|
|
10
|
+
export interface TabBarTheme {
|
|
11
|
+
/** Style for the label prefix (e.g., "Settings:") */
|
|
12
|
+
label: (text: string) => string;
|
|
13
|
+
/** Style for the currently active tab */
|
|
14
|
+
activeTab: (text: string) => string;
|
|
15
|
+
/** Style for inactive tabs */
|
|
16
|
+
inactiveTab: (text: string) => string;
|
|
17
|
+
/** Style for the hint text (e.g., "(tab to cycle)") */
|
|
18
|
+
hint: (text: string) => string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Horizontal tab bar component.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const tabs = [
|
|
26
|
+
* { id: "config", label: "Config" },
|
|
27
|
+
* { id: "tools", label: "Tools" },
|
|
28
|
+
* ];
|
|
29
|
+
* const tabBar = new TabBar("Settings", tabs, theme);
|
|
30
|
+
* tabBar.onTabChange = (tab) => console.log(`Switched to ${tab.id}`);
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare class TabBar implements Component {
|
|
34
|
+
#private;
|
|
35
|
+
/** Callback fired when the active tab changes */
|
|
36
|
+
onTabChange?: (tab: Tab, index: number) => void;
|
|
37
|
+
constructor(label: string, tabs: Tab[], theme: TabBarTheme, initialIndex?: number);
|
|
38
|
+
/** Get the currently active tab */
|
|
39
|
+
getActiveTab(): Tab;
|
|
40
|
+
/** Get the index of the currently active tab */
|
|
41
|
+
getActiveIndex(): number;
|
|
42
|
+
/** Set the active tab by index (clamped to valid range) */
|
|
43
|
+
setActiveIndex(index: number): void;
|
|
44
|
+
/** Move to the next tab (wraps to first tab after last) */
|
|
45
|
+
nextTab(): void;
|
|
46
|
+
/** Move to the previous tab (wraps to last tab before first) */
|
|
47
|
+
prevTab(): void;
|
|
48
|
+
invalidate(): void;
|
|
49
|
+
/**
|
|
50
|
+
* Handle keyboard input for tab navigation.
|
|
51
|
+
* @returns true if the input was handled, false otherwise
|
|
52
|
+
*/
|
|
53
|
+
handleInput(data: string): boolean;
|
|
54
|
+
/** Render the tab bar, wrapping to multiple lines if needed */
|
|
55
|
+
render(width: number): string[];
|
|
56
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Component } from "../tui";
|
|
2
|
+
/**
|
|
3
|
+
* Text component - displays multi-line text with word wrapping
|
|
4
|
+
*/
|
|
5
|
+
export declare class Text implements Component {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(text?: string, paddingX?: number, paddingY?: number, customBgFn?: (text: string) => string);
|
|
8
|
+
getText(): string;
|
|
9
|
+
setText(text: string): void;
|
|
10
|
+
setCustomBgFn(customBgFn?: (text: string) => string): void;
|
|
11
|
+
invalidate(): void;
|
|
12
|
+
render(width: number): string[];
|
|
13
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Component } from "../tui";
|
|
2
|
+
/**
|
|
3
|
+
* Text component that truncates to fit viewport width
|
|
4
|
+
*/
|
|
5
|
+
export declare class TruncatedText implements Component {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(text: string, paddingX?: number, paddingY?: number);
|
|
8
|
+
invalidate(): void;
|
|
9
|
+
render(width: number): string[];
|
|
10
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { AutocompleteProvider } from "./autocomplete";
|
|
2
|
+
import type { Component } from "./tui";
|
|
3
|
+
/**
|
|
4
|
+
* Interface for custom editor components.
|
|
5
|
+
*
|
|
6
|
+
* This allows extensions to provide their own editor implementation
|
|
7
|
+
* (e.g., vim mode, emacs mode, custom keybindings) while maintaining
|
|
8
|
+
* compatibility with the core application.
|
|
9
|
+
*/
|
|
10
|
+
export interface EditorComponent extends Component {
|
|
11
|
+
/** Get the current text content */
|
|
12
|
+
getText(): string;
|
|
13
|
+
/** Set the text content */
|
|
14
|
+
setText(text: string): void;
|
|
15
|
+
/** Handle raw terminal input (key presses, paste sequences, etc.) */
|
|
16
|
+
handleInput(data: string): void;
|
|
17
|
+
/** Called when user submits (e.g., Enter key) */
|
|
18
|
+
onSubmit?: (text: string) => void;
|
|
19
|
+
/** Called when text changes */
|
|
20
|
+
onChange?: (text: string) => void;
|
|
21
|
+
/** Add text to history for up/down navigation */
|
|
22
|
+
addToHistory?(text: string): void;
|
|
23
|
+
/** Insert text at current cursor position */
|
|
24
|
+
insertTextAtCursor?(text: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Get text with any markers expanded (e.g., paste markers).
|
|
27
|
+
* Falls back to getText() if not implemented.
|
|
28
|
+
*/
|
|
29
|
+
getExpandedText?(): string;
|
|
30
|
+
/** Set the autocomplete provider */
|
|
31
|
+
setAutocompleteProvider?(provider: AutocompleteProvider): void;
|
|
32
|
+
/** Border color function */
|
|
33
|
+
borderColor?: (str: string) => string;
|
|
34
|
+
/** Set horizontal padding */
|
|
35
|
+
setPaddingX?(padding: number): void;
|
|
36
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fuzzy matching utilities.
|
|
3
|
+
* Matches if all query characters appear in order (not necessarily consecutive).
|
|
4
|
+
* Lower score = better match.
|
|
5
|
+
*/
|
|
6
|
+
export interface FuzzyMatch {
|
|
7
|
+
matches: boolean;
|
|
8
|
+
score: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function fuzzyMatch(query: string, text: string): FuzzyMatch;
|
|
11
|
+
/**
|
|
12
|
+
* Filter and sort items by fuzzy match quality (best matches first).
|
|
13
|
+
* Supports space-separated tokens: all tokens must match.
|
|
14
|
+
*/
|
|
15
|
+
export declare function fuzzyFilter<T>(items: T[], query: string, getText: (item: T) => string): T[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export * from "./autocomplete";
|
|
2
|
+
export * from "./components/box";
|
|
3
|
+
export * from "./components/cancellable-loader";
|
|
4
|
+
export * from "./components/editor";
|
|
5
|
+
export * from "./components/image";
|
|
6
|
+
export * from "./components/input";
|
|
7
|
+
export * from "./components/loader";
|
|
8
|
+
export * from "./components/markdown";
|
|
9
|
+
export * from "./components/select-list";
|
|
10
|
+
export * from "./components/settings-list";
|
|
11
|
+
export * from "./components/spacer";
|
|
12
|
+
export * from "./components/tab-bar";
|
|
13
|
+
export * from "./components/text";
|
|
14
|
+
export * from "./components/truncated-text";
|
|
15
|
+
export type * from "./editor-component";
|
|
16
|
+
export * from "./fuzzy";
|
|
17
|
+
export * from "./keybindings";
|
|
18
|
+
export * from "./keys";
|
|
19
|
+
export * from "./stdin-buffer";
|
|
20
|
+
export type * from "./symbols";
|
|
21
|
+
export * from "./terminal";
|
|
22
|
+
export * from "./terminal-capabilities";
|
|
23
|
+
export * from "./ttyid";
|
|
24
|
+
export * from "./tui";
|
|
25
|
+
export * from "./utils";
|