@lingxi-ai-cn/dsh-tui-runtime 0.1.0-rc.8

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.
Files changed (39) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +109 -0
  3. package/README.zh.md +109 -0
  4. package/lib/index.js +10552 -0
  5. package/lib/invariant.js +9 -0
  6. package/lib/types/agent-view.d.ts +40 -0
  7. package/lib/types/app.d.ts +121 -0
  8. package/lib/types/composer.d.ts +188 -0
  9. package/lib/types/detail.d.ts +24 -0
  10. package/lib/types/footer.d.ts +85 -0
  11. package/lib/types/history-search.d.ts +58 -0
  12. package/lib/types/host.d.ts +210 -0
  13. package/lib/types/index.d.ts +60 -0
  14. package/lib/types/invariant.d.ts +6 -0
  15. package/lib/types/keybindings.d.ts +165 -0
  16. package/lib/types/markdown.d.ts +9 -0
  17. package/lib/types/open-url.d.ts +9 -0
  18. package/lib/types/plugin-hub.d.ts +158 -0
  19. package/lib/types/resume.d.ts +66 -0
  20. package/lib/types/rewind.d.ts +37 -0
  21. package/lib/types/sanitize.d.ts +9 -0
  22. package/lib/types/session-export.d.ts +29 -0
  23. package/lib/types/session-lifecycle.d.ts +20 -0
  24. package/lib/types/startup-logo.d.ts +45 -0
  25. package/lib/types/store.d.ts +88 -0
  26. package/lib/types/suggestion.d.ts +99 -0
  27. package/lib/types/terminal-input.d.ts +69 -0
  28. package/lib/types/terminal-session.d.ts +129 -0
  29. package/lib/types/theme.d.ts +76 -0
  30. package/lib/types/todo-panel.d.ts +12 -0
  31. package/lib/types/tool-card.d.ts +24 -0
  32. package/lib/types/tool-group.d.ts +10 -0
  33. package/lib/types/transcript-search.d.ts +67 -0
  34. package/lib/types/transcript-view.d.ts +32 -0
  35. package/lib/types/transcript.d.ts +159 -0
  36. package/lib/types/viewport.d.ts +211 -0
  37. package/lib/types/work-panel.d.ts +28 -0
  38. package/lib/types/work.d.ts +100 -0
  39. package/package.json +104 -0
@@ -0,0 +1,66 @@
1
+ /** Pure session-resume candidate projection and picker helpers for the native TUI. */
2
+ import { type SessionIdType as SessionId, type SessionRecord } from './host.ts';
3
+ /** One detached row shown by the native TUI Session picker. */
4
+ export interface TuiResumeCandidate {
5
+ /** Live-preferred Session record observed during the picker scan. */
6
+ record: SessionRecord;
7
+ /** Folded durable title or the local untitled fallback. */
8
+ title: string;
9
+ /** Best metadata-only activity timestamp available to the picker. */
10
+ updatedAt: number;
11
+ /** Whether this row belongs to the current Agent's workspace. */
12
+ currentWorkspace: boolean;
13
+ /** Display label for the row's own workspace. */
14
+ workspaceLabel: string;
15
+ /** Why the row cannot be resumed by this process-wide TUI composition. */
16
+ disabledReason?: string;
17
+ }
18
+ /** Current workspace scope selected in the native TUI Session picker. */
19
+ export type TuiResumeScope = 'workspace' | 'all';
20
+ /** Controller-owned asynchronous state for one Session picker generation. */
21
+ export interface TuiResumeDialogSnapshot {
22
+ /** Monotonic identity used to reset picker-local search and selection. */
23
+ generation: number;
24
+ /** Current scan or resume operation phase. */
25
+ phase: 'loading' | 'ready' | 'resuming';
26
+ /** Current Agent workspace used by the default picker scope. */
27
+ currentWorkspaceLabel: string;
28
+ /** Sorted rows after the scan settles; absent while loading. */
29
+ candidates?: readonly TuiResumeCandidate[];
30
+ /** Candidate currently being resumed. */
31
+ resumingId?: SessionId;
32
+ /** Latest activation failure; the ready picker remains open for retry. */
33
+ error?: string;
34
+ }
35
+ /**
36
+ * Summarize one logical Session for the process-wide TUI composition.
37
+ * @param record - live-preferred Session record from `ctx.sessionQuery`.
38
+ * @param title - folded durable title, when one exists.
39
+ * @param updatedAt - live last-event time or persisted artifact mtime.
40
+ * @param currentId - Session currently owned by the TUI.
41
+ * @param currentCwd - current Session workspace used by the default scope.
42
+ * @returns a detached picker row with compatibility status.
43
+ */
44
+ export declare function summarizeTuiResumeCandidate(record: SessionRecord, title: string | undefined, updatedAt: number | undefined, currentId: SessionId, currentCwd: string | undefined): TuiResumeCandidate;
45
+ /**
46
+ * Sort resume rows newest-first with a stable Session-id tie break.
47
+ * @param candidates - detached picker rows.
48
+ * @returns a new sorted array.
49
+ */
50
+ export declare function sortTuiResumeCandidates(candidates: readonly TuiResumeCandidate[]): TuiResumeCandidate[];
51
+ /**
52
+ * Apply workspace scope and normalized literal search to picker rows.
53
+ * @param candidates - complete sorted picker rows.
54
+ * @param scope - current-workspace or all-workspaces view.
55
+ * @param query - title, id, or visible workspace query.
56
+ * @returns matching rows without mutating the source array.
57
+ */
58
+ export declare function filterTuiResumeCandidates(candidates: readonly TuiResumeCandidate[], scope: TuiResumeScope, query: string): TuiResumeCandidate[];
59
+ /**
60
+ * Format one activity timestamp as a compact deterministic relative age.
61
+ * @param updatedAt - observed Unix epoch milliseconds.
62
+ * @param now - current Unix epoch milliseconds.
63
+ * @returns `now` or a compact minutes/hours/days/months/years age.
64
+ */
65
+ export declare function formatTuiRelativeTime(updatedAt: number, now: number): string;
66
+ //# sourceMappingURL=resume.d.ts.map
@@ -0,0 +1,37 @@
1
+ /** Pure human-boundary projection for native TUI Session rewind. */
2
+ import { type SessionEvent, type SessionIdType as SessionId } from './host.ts';
3
+ /** One completed human turn that can seed a rewound child Session. */
4
+ export interface TuiRewindCandidate {
5
+ /** Append-origin human `user/message` seq used as the fork anchor. */
6
+ readonly eventSeq: number;
7
+ /** Sanitized prompt text shown in the selector and confirmation. */
8
+ readonly promptText: string;
9
+ /** Durable source events retained in the child seed. */
10
+ readonly retainedEventCount: number;
11
+ /** Later durable source events that remain only in the parent. */
12
+ readonly hiddenEventCount: number;
13
+ }
14
+ /** Controller-owned selection or Agent-preparation state for one rewind request. */
15
+ export interface TuiRewindDialogSnapshot {
16
+ /** Monotonic identity for one dialog activation. */
17
+ readonly generation: number;
18
+ /** Command-audit settlement, selection, or child preparation phase. */
19
+ readonly phase: 'opening' | 'browsing' | 'rewinding';
20
+ /** Parent Session that remains active until replacement commits. */
21
+ readonly currentSessionId: SessionId;
22
+ /** Newest-first completed human boundaries, present after audit settlement. */
23
+ readonly candidates?: readonly TuiRewindCandidate[];
24
+ /** Candidate currently preparing a child Agent. */
25
+ readonly rewindingSeq?: number;
26
+ /** Latest preparation or switch failure while selection remains open. */
27
+ readonly error?: string;
28
+ }
29
+ /**
30
+ * Project every safe append-origin human boundary from a durable Session log.
31
+ * Open turns and model-only replacements are excluded; results are newest first.
32
+ *
33
+ * @param events - Complete current Session log after the rewind command audit settles.
34
+ * @returns Detached candidates with retained and parent-only event counts.
35
+ */
36
+ export declare function tuiRewindCandidates(events: readonly SessionEvent[]): TuiRewindCandidate[];
37
+ //# sourceMappingURL=rewind.d.ts.map
@@ -0,0 +1,9 @@
1
+ /** Terminal-safe text normalization. The renderer alone may emit controls. */
2
+ /**
3
+ * Remove terminal control characters from untrusted model, tool, path, and error text.
4
+ * Newline and tab remain ordinary layout input; ESC and every other C0/C1 code become visible replacement glyphs.
5
+ * @param value - untrusted text.
6
+ * @returns text that cannot open an ANSI/OSC control sequence.
7
+ */
8
+ export declare function terminalSafe(value: string): string;
9
+ //# sourceMappingURL=sanitize.d.ts.map
@@ -0,0 +1,29 @@
1
+ /** TUI-local state and path resolution for native Session archive export. */
2
+ import type { SessionIdType as SessionId } from './host.ts';
3
+ /** Lifecycle shown by the native Session export dialog. */
4
+ export type TuiSessionExportPhase = 'opening' | 'selecting' | 'exporting';
5
+ /** Process-local Session export dialog state; no field enters the Session log. */
6
+ export interface TuiSessionExportDialogSnapshot {
7
+ /** Monotonic identity preventing stale export settlement from changing a newer dialog. */
8
+ readonly generation: number;
9
+ /** Current dialog operation phase. */
10
+ readonly phase: TuiSessionExportPhase;
11
+ /** Exact Session selected before the command lifecycle settled. */
12
+ readonly sessionId: SessionId;
13
+ /** Absolute workspace used to resolve a relative directory entry. */
14
+ readonly workspaceLabel: string;
15
+ /** Resolved absolute destination while bytes are being written. */
16
+ readonly destination?: string;
17
+ /** Whether durable descendant artifacts are included while writing. */
18
+ readonly includeDescendants?: boolean;
19
+ /** Safe failure text retained while the operator edits the destination. */
20
+ readonly error?: string;
21
+ }
22
+ /**
23
+ * Resolve terminal directory input against the Session workspace.
24
+ * @param workspace - absolute Session working directory.
25
+ * @param input - absolute or workspace-relative operator input; blank selects the workspace.
26
+ * @returns an absolute directory path for the host export service to validate.
27
+ */
28
+ export declare function resolveTuiSessionExportDirectory(workspace: string, input: string): string;
29
+ //# sourceMappingURL=session-export.d.ts.map
@@ -0,0 +1,20 @@
1
+ /** TUI-local state for replacing the active Agent with a fresh Session. */
2
+ import type { SessionIdType as SessionId } from './host.ts';
3
+ /** User command that requests a fresh TUI Session. */
4
+ export type TuiFreshSessionCommand = 'clear' | 'new';
5
+ /** Controller-owned confirmation or creation state for one fresh Session request. */
6
+ export interface TuiFreshSessionDialogSnapshot {
7
+ /** Monotonic identity for one dialog activation. */
8
+ readonly generation: number;
9
+ /** Command spelling that opened the dialog. */
10
+ readonly command: TuiFreshSessionCommand;
11
+ /** Whether the user is deciding or fresh Agent preparation is active. */
12
+ readonly phase: 'confirming' | 'creating';
13
+ /** Session that remains active until replacement commits. */
14
+ readonly currentSessionId: SessionId;
15
+ /** Workspace copied into the fresh Session. */
16
+ readonly workspaceLabel: string;
17
+ /** Latest preparation or switch failure while confirmation remains open. */
18
+ readonly error?: string;
19
+ }
20
+ //# sourceMappingURL=session-lifecycle.d.ts.map
@@ -0,0 +1,45 @@
1
+ /** Electric startup mark data, terminal color fallback, and Ink rendering. */
2
+ import React from 'react';
3
+ import { type TuiTheme } from './theme.tsx';
4
+ /** Display-cell width of the full Electric startup mark. */
5
+ export declare const TUI_ELECTRIC_STARTUP_LOGO_WIDTH = 60;
6
+ /** Row count of the full Electric startup mark. */
7
+ export declare const TUI_ELECTRIC_STARTUP_LOGO_HEIGHT = 9;
8
+ /** Terminal text rows for the full Electric startup mark without color escapes. */
9
+ export declare const TUI_ELECTRIC_STARTUP_LOGO_ROWS: readonly string[];
10
+ /** Startup mark selected for the available terminal geometry. */
11
+ export type TuiStartupLogoVariant = 'electric' | 'compact';
12
+ /**
13
+ * Resolve one Electric mark cell color for the active terminal theme.
14
+ * @param theme - resolved TUI theme and negotiated color precision.
15
+ * @param column - zero-based 30-cell logo column.
16
+ * @param row - zero-based logo row.
17
+ * @returns a true/extended-color value, ANSI theme accent, or no style for blank, invalid, or colorless cells.
18
+ */
19
+ export declare function tuiElectricStartupLogoCellColor(theme: Pick<TuiTheme, 'colorDepth' | 'tokens'>, column: number, row: number): string | undefined;
20
+ /**
21
+ * Select the full mark only when both dimensions preserve the complete centered startup workspace.
22
+ * @param stdout - terminal dimensions used by the active Ink frame.
23
+ * @param composerRows - mounted editor rows inside the bordered composer.
24
+ * @param supplementalRows - suggestion rows mounted between the mark and composer.
25
+ * @returns the full Electric or compact mark variant.
26
+ */
27
+ export declare function resolveTuiStartupLogoVariant(stdout: Readonly<{
28
+ rows: number;
29
+ columns: number;
30
+ }>, composerRows: number, supplementalRows?: number): TuiStartupLogoVariant;
31
+ /**
32
+ * Return the physical row count of one startup mark variant.
33
+ * @param variant - selected startup mark.
34
+ * @returns its fixed terminal row count.
35
+ */
36
+ export declare function tuiStartupLogoHeight(variant: TuiStartupLogoVariant): number;
37
+ /**
38
+ * Render the selected startup mark through Ink and the negotiated TUI theme.
39
+ * @param props - selected startup mark variant.
40
+ * @returns fixed-dimension Ink text rows for that variant.
41
+ */
42
+ export declare const TuiStartupLogo: React.MemoExoticComponent<({ variant }: {
43
+ readonly variant: TuiStartupLogoVariant;
44
+ }) => React.ReactElement>;
45
+ //# sourceMappingURL=startup-logo.d.ts.map
@@ -0,0 +1,88 @@
1
+ /** Small external stores shared by the controller and Ink component tree. */
2
+ import { type AgentStatus, type ApprovalOutcome, type ApprovalRequest, type AskUserQuestionAnswer, type AskUserQuestionRequest, type SessionEvent } from './host.ts';
3
+ type Listener = () => void;
4
+ /** Observable immutable value with stable snapshots for `useSyncExternalStore`. */
5
+ export declare class ValueStore<T> {
6
+ private value;
7
+ private readonly listeners;
8
+ constructor(value: T);
9
+ /** Read the current immutable value for `useSyncExternalStore`. */
10
+ getSnapshot: () => T;
11
+ /**
12
+ * Subscribe to value changes.
13
+ * @param listener - callback invoked after a changed value commits.
14
+ * @returns disposer for this subscription.
15
+ */
16
+ subscribe: (listener: Listener) => (() => void);
17
+ /**
18
+ * Commit one value and notify subscribers when its identity changed.
19
+ * @param value - next immutable snapshot.
20
+ */
21
+ set(value: T): void;
22
+ }
23
+ /** Append-only observable Session-event snapshot. */
24
+ export declare class SessionEventStore extends ValueStore<readonly SessionEvent[]> {
25
+ constructor(events: readonly SessionEvent[]);
26
+ /**
27
+ * Append one committed Session event to the observable snapshot.
28
+ * @param event - exact post-commit event.
29
+ */
30
+ append(event: SessionEvent): void;
31
+ }
32
+ /** Live Agent status projection. */
33
+ export declare class AgentStatusStore extends ValueStore<AgentStatus> {
34
+ }
35
+ /** Public view of the approval currently owning terminal input. */
36
+ interface PendingApproval {
37
+ /** Interaction discriminant. */
38
+ kind: 'approval';
39
+ /** Borrowed approval request. */
40
+ request: ApprovalRequest;
41
+ }
42
+ /** Public view of the structured question currently owning terminal input. */
43
+ export interface PendingQuestion {
44
+ /** Interaction discriminant. */
45
+ kind: 'question';
46
+ /** Borrowed structured-question request. */
47
+ request: AskUserQuestionRequest;
48
+ }
49
+ /** The one FIFO interaction visible to the component tree, or no takeover. */
50
+ export type TuiPendingInteraction = PendingApproval | PendingQuestion;
51
+ /** FIFO owner for approvals and structured user questions. */
52
+ export declare class InteractionStore extends ValueStore<TuiPendingInteraction | undefined> {
53
+ private readonly queue;
54
+ private disposed;
55
+ constructor();
56
+ /**
57
+ * Queue one approval wait.
58
+ * @param request - exact scoped approval request.
59
+ * @returns its fail-closed outcome after user action, abort, or teardown.
60
+ */
61
+ askApproval(request: ApprovalRequest): Promise<ApprovalOutcome>;
62
+ /**
63
+ * Queue one structured human-question wait.
64
+ * @param request - validated request from `ctx.userQuestions`.
65
+ * @returns structured answers after every question is completed.
66
+ */
67
+ askQuestion(request: AskUserQuestionRequest): Promise<AskUserQuestionAnswer>;
68
+ /**
69
+ * Settle the current approval with a user-selectable outcome.
70
+ * @param outcome - allow once or reject.
71
+ */
72
+ answerApproval(outcome: Extract<ApprovalOutcome, 'allowed-once' | 'rejected'>): void;
73
+ /**
74
+ * Settle the current question with validated UI encoding.
75
+ * @param answer - structured answer set.
76
+ */
77
+ answerQuestion(answer: AskUserQuestionAnswer): void;
78
+ /** Reject or abort the interaction currently owning input. */
79
+ cancelCurrent(): void;
80
+ /** Fail closed and settle every queued interaction exactly once. */
81
+ dispose(): void;
82
+ private enqueue;
83
+ private settle;
84
+ private remove;
85
+ private publish;
86
+ }
87
+ export {};
88
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1,99 @@
1
+ /** Pure completion state shared by command and workspace-path suggestions. */
2
+ import type { CommandDescriptor, FsPathCompletionResult } from './host.ts';
3
+ /** Origin of one TUI completion candidate. */
4
+ export type TuiSuggestionKind = 'command' | 'path';
5
+ /** Resolution state for a bounded TUI completion query. */
6
+ export type TuiSuggestionStatus = 'ready' | 'loading' | 'empty' | 'truncated';
7
+ /** One insertable item supplied by a TUI completion source. */
8
+ export interface TuiSuggestionItem {
9
+ /** Stable identity within the source. */
10
+ id: string;
11
+ /** Text that replaces the active query range when accepted. */
12
+ insertText: string;
13
+ /** Primary text displayed in the completion list. */
14
+ label: string;
15
+ /** Concise explanation displayed beside the label. */
16
+ description: string;
17
+ /** Optional secondary information such as an argument hint. */
18
+ detail?: string | undefined;
19
+ /** Source that produced this item. */
20
+ source: TuiSuggestionKind;
21
+ }
22
+ /** Complete local state for one active TUI completion query. */
23
+ export interface TuiSuggestionState {
24
+ /** Source that owns the active query. */
25
+ kind: TuiSuggestionKind;
26
+ /** Inclusive UTF-16 offset replaced on acceptance. */
27
+ queryStart: number;
28
+ /** Exclusive UTF-16 offset replaced on acceptance. */
29
+ queryEnd: number;
30
+ /** Selected item index in the complete result. */
31
+ selectedIndex: number;
32
+ /** First item mounted by the bounded list renderer. */
33
+ visibleStart: number;
34
+ /** Complete bounded result supplied by the source. */
35
+ items: readonly TuiSuggestionItem[];
36
+ /** Query resolution state shown when candidates are unavailable or incomplete. */
37
+ status: TuiSuggestionStatus;
38
+ }
39
+ /** Text and insertion point produced by accepting a completion. */
40
+ export interface TuiSuggestionAcceptance {
41
+ /** Complete editor text after replacement. */
42
+ text: string;
43
+ /** UTF-16 insertion offset after the inserted text. */
44
+ cursor: number;
45
+ }
46
+ /** Range and workspace-relative query for the `@` token under the cursor. */
47
+ export interface TuiPathSuggestionQuery {
48
+ /** Inclusive UTF-16 offset of the `@` marker. */
49
+ queryStart: number;
50
+ /** Exclusive UTF-16 offset of the complete token. */
51
+ queryEnd: number;
52
+ /** Query text after the `@` marker. */
53
+ query: string;
54
+ }
55
+ /**
56
+ * Resolve slash-command candidates for a command-only draft.
57
+ * @param text - complete composer text.
58
+ * @param cursor - active UTF-16 insertion offset.
59
+ * @param commands - effective Agent-scoped command descriptors.
60
+ * @returns active suggestion state, or `undefined` outside a command query.
61
+ */
62
+ export declare function commandSuggestionState(text: string, cursor: number, commands: readonly CommandDescriptor[]): TuiSuggestionState | undefined;
63
+ /**
64
+ * Find an `@token` only when the token begins at the draft or after whitespace.
65
+ * @param text - complete composer text.
66
+ * @param cursor - active UTF-16 insertion offset.
67
+ * @returns the token range and workspace-relative query, or `undefined` outside one.
68
+ */
69
+ export declare function pathSuggestionQuery(text: string, cursor: number): TuiPathSuggestionQuery | undefined;
70
+ /**
71
+ * Convert one bounded filesystem result into the shared TUI suggestion state.
72
+ * @param query - active `@token` range and workspace-relative query.
73
+ * @param result - provider result, or `undefined` while the query is loading.
74
+ * @returns path suggestion state with directory/file-specific insertion text.
75
+ */
76
+ export declare function pathSuggestionState(query: TuiPathSuggestionQuery, result: FsPathCompletionResult | undefined): TuiSuggestionState;
77
+ /**
78
+ * Move the selected candidate while keeping it inside the mounted item window.
79
+ * @param state - active suggestion state.
80
+ * @param direction - selection direction.
81
+ * @param visibleLimit - maximum mounted candidate rows.
82
+ * @returns state with a clamped selection and window.
83
+ */
84
+ export declare function moveTuiSuggestion(state: TuiSuggestionState, direction: 'previous' | 'next', visibleLimit: number): TuiSuggestionState;
85
+ /**
86
+ * Replace the active query with its selected candidate.
87
+ * @param text - complete composer text.
88
+ * @param state - active suggestion state.
89
+ * @returns updated text and cursor, or `undefined` when no item is selectable.
90
+ */
91
+ export declare function acceptTuiSuggestion(text: string, state: TuiSuggestionState): TuiSuggestionAcceptance | undefined;
92
+ /**
93
+ * Return only the candidate rows mounted by the current suggestion window.
94
+ * @param state - active suggestion state.
95
+ * @param visibleLimit - maximum mounted candidate rows.
96
+ * @returns the visible item slice.
97
+ */
98
+ export declare function visibleTuiSuggestions(state: TuiSuggestionState, visibleLimit: number): readonly TuiSuggestionItem[];
99
+ //# sourceMappingURL=suggestion.d.ts.map
@@ -0,0 +1,69 @@
1
+ /** Incremental terminal protocol decoding for native TUI input dispatch. */
2
+ import type { TuiKeypress } from './keybindings.ts';
3
+ /** One normalized event emitted by the native terminal input decoder. */
4
+ export type TuiTerminalInputEvent = {
5
+ readonly kind: 'input';
6
+ /** Committed text, or the printable identity of a modified key. */
7
+ readonly input: string;
8
+ /** Normalized key flags independent of a terminal keyboard protocol. */
9
+ readonly key: TuiKeypress;
10
+ /** Whether an oversized bracketed paste was bounded before dispatch. */
11
+ readonly truncated?: boolean;
12
+ } | {
13
+ readonly kind: 'mouse';
14
+ /** SGR button and modifier bit field. */
15
+ readonly button: number;
16
+ /** One-based terminal column. */
17
+ readonly column: number;
18
+ /** One-based terminal row. */
19
+ readonly row: number;
20
+ /** Whether the report ends a press rather than starting or moving one. */
21
+ readonly release: boolean;
22
+ } | {
23
+ readonly kind: 'focus';
24
+ /** Whether the terminal reports that it gained focus. */
25
+ readonly focused: boolean;
26
+ } | {
27
+ readonly kind: 'reply';
28
+ /** Complete terminal capability or status reply, retained for negotiation. */
29
+ readonly sequence: string;
30
+ };
31
+ /** Why a decoder is retaining an incomplete terminal sequence. */
32
+ export type TuiTerminalInputWait = 'escape' | 'sequence' | 'paste';
33
+ /**
34
+ * Incrementally tokenize raw terminal input without relying on transport chunk boundaries.
35
+ *
36
+ * Complete unknown control sequences are discarded. Incomplete sequences remain bounded
37
+ * until {@link flush} applies the caller's escape timeout.
38
+ */
39
+ export declare class TuiTerminalInputDecoder {
40
+ private utf8;
41
+ private pending;
42
+ private paste;
43
+ private pasteBytes;
44
+ private pasteTruncated;
45
+ /** The kind of timeout required for the currently retained input, if any. */
46
+ get waiting(): TuiTerminalInputWait | undefined;
47
+ /**
48
+ * Decode one raw terminal chunk.
49
+ * @param data - UTF-8 input from Ink's raw input emitter or a terminal stream.
50
+ * @returns complete normalized events in byte-stream order.
51
+ */
52
+ push(data: string | Buffer): readonly TuiTerminalInputEvent[];
53
+ /**
54
+ * Settle input retained past the escape or incomplete-sequence timeout.
55
+ * @returns a standalone Escape or bounded paste event; other fragments are discarded.
56
+ */
57
+ flush(): readonly TuiTerminalInputEvent[];
58
+ /** Discard retained sequence and paste state during input-owner teardown. */
59
+ reset(): void;
60
+ private drain;
61
+ private appendPaste;
62
+ }
63
+ /**
64
+ * Own raw-mode input for one Ink component and dispatch decoder events.
65
+ * @param handler - current normalized input consumer.
66
+ * @param initialEvents - events buffered before the Ink input emitter mounted.
67
+ */
68
+ export declare function useTuiTerminalInput(handler: (event: TuiTerminalInputEvent) => void, initialEvents?: readonly TuiTerminalInputEvent[]): void;
69
+ //# sourceMappingURL=terminal-input.d.ts.map
@@ -0,0 +1,129 @@
1
+ /** Exclusive owner of terminal capability probing, alternate-screen mutation, and restoration. */
2
+ import { type TuiTerminalInputEvent } from './terminal-input.ts';
3
+ /** Process-stream capability set borrowed by one terminal transaction. */
4
+ export interface TuiStreams {
5
+ /** Interactive key input. */
6
+ stdin: NodeJS.ReadStream;
7
+ /** Full-screen renderer output. */
8
+ stdout: NodeJS.WriteStream;
9
+ /** Startup and fatal error output. */
10
+ stderr: NodeJS.WriteStream;
11
+ }
12
+ /** One-based terminal cell where IME preedit text must begin. */
13
+ export interface InputCursorTarget {
14
+ /** One-based terminal row. */
15
+ row: number;
16
+ /** One-based terminal column. */
17
+ column: number;
18
+ }
19
+ /** Terminal color precision used by semantic renderers. */
20
+ export type TuiTerminalColorDepth = 'none' | 'ansi16' | 'ansi256' | 'truecolor';
21
+ /** Keyboard protocol that the terminal agreed to receive. */
22
+ export type TuiTerminalKeyboardProtocol = 'legacy' | 'kitty';
23
+ /** Capabilities observed or conservatively inferred for one terminal session. */
24
+ export interface TuiTerminalCapabilities {
25
+ /** Color precision reported by the output stream or `NO_COLOR`. */
26
+ readonly colorDepth: TuiTerminalColorDepth;
27
+ /** Enhanced keyboard protocol enabled for this transaction. */
28
+ readonly keyboardProtocol: TuiTerminalKeyboardProtocol;
29
+ /** Whether SGR mouse reports may be enabled. */
30
+ readonly mouse: 'none' | 'sgr';
31
+ /** Whether focus-in/out reports may be enabled. */
32
+ readonly focus: boolean;
33
+ /** Whether bracketed paste may be enabled. */
34
+ readonly bracketedPaste: boolean;
35
+ /** Whether OSC terminal strings were accepted during probing. */
36
+ readonly osc: boolean;
37
+ /** Whether synchronized output was explicitly confirmed. */
38
+ readonly synchronizedOutput: boolean;
39
+ /** Whether the process is inside a verified tmux or SSH environment. */
40
+ readonly outer: Readonly<{
41
+ tmux: boolean;
42
+ ssh: boolean;
43
+ }>;
44
+ }
45
+ /** Options for the bounded terminal capability probe. */
46
+ export interface TuiTerminalNegotiationOptions {
47
+ /** Probe deadline in milliseconds; defaults to a short non-blocking window. */
48
+ readonly timeoutMs?: number;
49
+ /** Cancellation signal for startup or teardown. */
50
+ readonly signal?: AbortSignal;
51
+ /** Environment used only to identify outer transport context. */
52
+ readonly environment?: NodeJS.ProcessEnv;
53
+ }
54
+ /** Result of one bounded terminal clipboard write. */
55
+ export type TuiClipboardResult = {
56
+ readonly ok: true;
57
+ readonly method: 'osc52' | 'tmux-buffer';
58
+ } | {
59
+ readonly ok: false;
60
+ readonly reason: 'inactive' | 'unsupported' | 'too-large' | 'write-failed';
61
+ readonly message: string;
62
+ };
63
+ /** Capabilities used by the compatibility `enter()` call in isolated tests. */
64
+ export declare const DEFAULT_TUI_TERMINAL_CAPABILITIES: TuiTerminalCapabilities;
65
+ /** Full-screen transaction. Ink owns raw mode; this owner restores outer terminal modes. */
66
+ export declare class TerminalSession {
67
+ readonly streams: TuiStreams;
68
+ private active;
69
+ private rawModeHeld;
70
+ private cursorTarget;
71
+ private activeModes;
72
+ private negotiation;
73
+ private cancelNegotiation;
74
+ private capabilitiesSnapshot;
75
+ private bufferedInput;
76
+ /** Ink-facing output that restores the real terminal cursor after each full-screen render. */
77
+ readonly rendererOutput: NodeJS.WriteStream;
78
+ constructor(streams: TuiStreams);
79
+ /**
80
+ * Move the real terminal cursor to the active input insertion cell after rendering.
81
+ * @param target - one-based cell, or `undefined` while no text editor owns input.
82
+ */
83
+ setInputCursor(target: InputCursorTarget | undefined): void;
84
+ /**
85
+ * Validate the terminal before emitting any control sequence.
86
+ * @throws when stdin or stdout is not an interactive TTY.
87
+ */
88
+ assertInteractive(): void;
89
+ /**
90
+ * Probe terminal capabilities without blocking startup beyond a short deadline.
91
+ * @param options - timeout, cancellation, and outer transport context.
92
+ * @returns the disposable capability snapshot for this terminal transaction.
93
+ */
94
+ negotiate(options?: TuiTerminalNegotiationOptions): Promise<TuiTerminalCapabilities>;
95
+ /**
96
+ * Take ordinary input that arrived while terminal replies were being probed.
97
+ * @returns input events in the original byte-stream order.
98
+ */
99
+ takeBufferedInput(): readonly TuiTerminalInputEvent[];
100
+ /**
101
+ * Copy bounded text through the negotiated OSC 52 path.
102
+ * tmux receives the same sequence as buffer integration and decides whether
103
+ * its configured `set-clipboard` policy also forwards it to the outer terminal.
104
+ * @param text - complete text selected by a non-secret TUI surface.
105
+ * @returns the observed local write outcome; terminals do not acknowledge clipboard mutation.
106
+ */
107
+ copyToClipboard(text: string): TuiClipboardResult;
108
+ /**
109
+ * Enter the alternate screen exactly once after TTY validation.
110
+ * @param capabilities - negotiated capabilities controlling enabled terminal modes.
111
+ */
112
+ enter(capabilities?: TuiTerminalCapabilities): void;
113
+ /** Restore every terminal mode this application may have enabled, idempotently. */
114
+ restore(): void;
115
+ private capabilitiesForEntry;
116
+ private performNegotiation;
117
+ private cursorSequence;
118
+ private createRendererOutput;
119
+ }
120
+ /**
121
+ * Fold one decoder reply into a capability snapshot.
122
+ * @param current - current session snapshot.
123
+ * @param sequence - complete terminal reply consumed by the decoder.
124
+ * @returns a new immutable snapshot.
125
+ */
126
+ export declare function applyTuiTerminalReply(current: TuiTerminalCapabilities, sequence: string): TuiTerminalCapabilities;
127
+ /** Process streams used in production; tests replace this object. */
128
+ export declare const terminalInternals: TuiStreams;
129
+ //# sourceMappingURL=terminal-session.d.ts.map