dsh-code 1.3.0 → 1.5.0
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/README.en.md +10 -8
- package/README.md +10 -8
- package/lib/index.mjs +6980 -5942
- package/lib/session-query.mjs +18 -1
- package/lib/types/app.d.ts +38 -65
- package/lib/types/completion.d.ts +29 -0
- package/lib/types/composer.d.ts +150 -0
- package/lib/types/git-workflow.d.ts +6 -0
- package/lib/types/index.d.ts +6 -188
- package/lib/types/locales/en.d.ts +20 -8
- package/lib/types/{authorization-panel.d.ts → panels/authorization-panel.d.ts} +6 -1
- package/lib/types/panels/completion-panel.d.ts +13 -0
- package/lib/types/panels/interaction-bars.d.ts +38 -0
- package/lib/types/{kernel-panels.d.ts → panels/kernel-panels.d.ts} +16 -37
- package/lib/types/{language-panel.d.ts → panels/language-panel.d.ts} +1 -1
- package/lib/types/panels/model-panels.d.ts +86 -0
- package/lib/types/{theme-panel.d.ts → panels/theme-panel.d.ts} +1 -1
- package/lib/types/{update-panel.d.ts → panels/update-panel.d.ts} +1 -1
- package/lib/types/provider-settings.d.ts +11 -0
- package/lib/types/render/inspector.d.ts +16 -0
- package/lib/types/render/projection-events.d.ts +33 -0
- package/lib/types/render/text.d.ts +4 -0
- package/lib/types/render/transcript-viewport.d.ts +32 -0
- package/lib/types/runner/harness-gate.d.ts +83 -0
- package/lib/types/runner/input-history.d.ts +31 -0
- package/lib/types/runner/mode-cycle.d.ts +44 -0
- package/lib/types/runner/preferences.d.ts +40 -0
- package/lib/types/runner/quit.d.ts +27 -0
- package/lib/types/runner/search-rows.d.ts +38 -0
- package/lib/types/runner/session-io.d.ts +57 -0
- package/lib/types/runner/session-target.d.ts +42 -0
- package/lib/types/runner/startup-config.d.ts +33 -0
- package/lib/types/runner/submissions.d.ts +87 -0
- package/lib/types/session/attach.d.ts +39 -0
- package/lib/types/{store.d.ts → session/store.d.ts} +1 -1
- package/lib/types/{subagents.d.ts → session/subagents.d.ts} +8 -1
- package/lib/types/session-query.d.ts +11 -0
- package/lib/types/settings-file.d.ts +10 -0
- package/lib/types/{panel-accent.d.ts → ui/panel-accent.d.ts} +1 -1
- package/lib/types/ui/panel-gap.d.ts +6 -0
- package/lib/types/ui/query-editor.d.ts +10 -0
- package/lib/types/ui/styled-rows.d.ts +8 -0
- package/lib/types/{terminal-title.d.ts → ui/terminal-title.d.ts} +1 -1
- package/lib/types/ui/ui-contract.d.ts +12 -0
- package/lib/types/ui/use-frames.d.ts +6 -0
- package/lib/types/ui/use-stable-input.d.ts +7 -0
- package/package.json +3 -2
- package/src/app.ts +802 -4162
- package/src/completion.ts +117 -0
- package/src/composer.ts +1956 -0
- package/src/git-workflow.ts +18 -0
- package/src/index.ts +113 -633
- package/src/internals.ts +1 -1
- package/src/locales/en.ts +20 -8
- package/src/locales/zh.ts +20 -8
- package/src/{authorization-panel.ts → panels/authorization-panel.ts} +25 -6
- package/src/panels/completion-panel.ts +79 -0
- package/src/panels/interaction-bars.ts +567 -0
- package/src/{kernel-panels.ts → panels/kernel-panels.ts} +84 -65
- package/src/{language-panel.ts → panels/language-panel.ts} +4 -4
- package/src/panels/model-panels.ts +1021 -0
- package/src/{theme-panel.ts → panels/theme-panel.ts} +5 -5
- package/src/{update-panel.ts → panels/update-panel.ts} +6 -6
- package/src/provider-settings.ts +38 -0
- package/src/render/inspector.ts +35 -0
- package/src/render/lines.ts +45 -18
- package/src/render/projection-events.ts +109 -0
- package/src/render/projection.ts +11 -2
- package/src/render/text.ts +8 -0
- package/src/render/tool-preview.ts +35 -2
- package/src/render/transcript-viewport.ts +61 -0
- package/src/render/usage.ts +1 -2
- package/src/runner/harness-gate.ts +168 -0
- package/src/runner/input-history.ts +77 -0
- package/src/runner/mode-cycle.ts +49 -0
- package/src/runner/preferences.ts +67 -0
- package/src/runner/quit.ts +53 -0
- package/src/runner/search-rows.ts +55 -0
- package/src/runner/session-io.ts +245 -0
- package/src/runner/session-target.ts +81 -0
- package/src/runner/startup-config.ts +54 -0
- package/src/runner/submissions.ts +157 -0
- package/src/session/attach.ts +87 -0
- package/src/{session-directory.ts → session/session-directory.ts} +1 -1
- package/src/{store.ts → session/store.ts} +1 -1
- package/src/{subagents.ts → session/subagents.ts} +12 -1
- package/src/session-query.ts +22 -0
- package/src/settings-file.ts +19 -1
- package/src/{panel-accent.ts → ui/panel-accent.ts} +1 -1
- package/src/ui/panel-gap.ts +9 -0
- package/src/ui/query-editor.ts +16 -0
- package/src/ui/styled-rows.ts +124 -0
- package/src/{terminal-title.ts → ui/terminal-title.ts} +1 -1
- package/src/ui/ui-contract.ts +10 -0
- package/src/ui/use-frames.ts +23 -0
- package/src/ui/use-stable-input.ts +17 -0
- /package/lib/types/{fork.d.ts → session/fork.d.ts} +0 -0
- /package/lib/types/{history.d.ts → session/history.d.ts} +0 -0
- /package/lib/types/{session-directory.d.ts → session/session-directory.d.ts} +0 -0
- /package/lib/types/{session-switch.d.ts → session/session-switch.d.ts} +0 -0
- /package/src/{fork.ts → session/fork.ts} +0 -0
- /package/src/{history.ts → session/history.ts} +0 -0
- /package/src/{session-switch.ts → session/session-switch.ts} +0 -0
package/lib/session-query.mjs
CHANGED
|
@@ -139,6 +139,23 @@ async function observeStableWithSkip(engine, indexed, signal, readCold = readCol
|
|
|
139
139
|
}
|
|
140
140
|
throw new SessionQueryError("session-search persistence observation did not stabilize after one retry", "SESSION_QUERY_PERSISTENCE_FAILED");
|
|
141
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Assert the private override seam this compatibility engine relies on.
|
|
144
|
+
* Harness keeps `_observeStable` private, so TypeScript cannot protect this
|
|
145
|
+
* subclass when upstream renames the method or changes its call signature.
|
|
146
|
+
* The exact-version launcher gate prevents unsupported hosts; this import-time
|
|
147
|
+
* check additionally prevents a newly built bundle from silently mounting an
|
|
148
|
+
* override the installed base will never call.
|
|
149
|
+
*
|
|
150
|
+
* @internal Exported for the compatibility regression.
|
|
151
|
+
*/
|
|
152
|
+
function assertSessionQueryOverrideContract(candidate) {
|
|
153
|
+
if (typeof candidate !== "function") throw new TypeError("session-query sqlite engine must be a constructor");
|
|
154
|
+
const prototype = candidate.prototype;
|
|
155
|
+
const method = (prototype === void 0 ? void 0 : Object.getOwnPropertyDescriptor(prototype, "_observeStable"))?.value;
|
|
156
|
+
if (typeof method !== "function" || method.length !== 2) throw new Error("incompatible @deepseek-ai/dsh-session-query-sqlite: expected _observeStable(indexed, signal)");
|
|
157
|
+
}
|
|
158
|
+
assertSessionQueryOverrideContract(SqliteSessionQueryEngine);
|
|
142
159
|
const EngineBase = SqliteSessionQueryEngine;
|
|
143
160
|
/** The engine this bundle mounts in place of the base `session-query-sqlite` row. */
|
|
144
161
|
var SkipTolerantSessionQueryEngine = class extends EngineBase {
|
|
@@ -147,4 +164,4 @@ var SkipTolerantSessionQueryEngine = class extends EngineBase {
|
|
|
147
164
|
}
|
|
148
165
|
};
|
|
149
166
|
//#endregion
|
|
150
|
-
export { SkipTolerantSessionQueryEngine, SkipTolerantSessionQueryEngine as default, observeStableWithSkip };
|
|
167
|
+
export { SkipTolerantSessionQueryEngine, SkipTolerantSessionQueryEngine as default, assertSessionQueryOverrideContract, observeStableWithSkip };
|
package/lib/types/app.d.ts
CHANGED
|
@@ -14,42 +14,35 @@
|
|
|
14
14
|
* @module @deepseek-ai/dsh-code/app
|
|
15
15
|
*/
|
|
16
16
|
import { type ReactElement } from 'react';
|
|
17
|
-
import type { CommandDescriptor } from '@deepseek-ai/dsh-commands';
|
|
18
17
|
import type { ContentBlock, FileBlock, ImageBlock } from '@deepseek-ai/dsh-llm';
|
|
19
18
|
import type { AuthorizationInteraction, AuthorizationStatus } from '@deepseek-ai/dsh-authorization';
|
|
20
19
|
import { type ThemeName } from './theme.ts';
|
|
21
20
|
import { type LanguageName } from './i18n.ts';
|
|
22
21
|
import type { LauncherUpdateStatus } from './update.ts';
|
|
23
|
-
import type { TranscriptStore } from './store.ts';
|
|
22
|
+
import type { TranscriptStore } from './session/store.ts';
|
|
24
23
|
import { type TranscriptEntry } from './render/projection.ts';
|
|
24
|
+
import { type SubagentAttachmentServices } from './session/attach.ts';
|
|
25
25
|
import type { ApprovalStore } from './approval.ts';
|
|
26
|
-
import {
|
|
26
|
+
import type { CommandsView } from './commands.ts';
|
|
27
27
|
import type { ModelDirectory, ModelRow } from './models.ts';
|
|
28
28
|
import { type DiscoveredModelView, type ProviderConfiguration, type ProviderSettingsDirectory, type ProviderTargetView } from './provider-settings.ts';
|
|
29
29
|
import type { QuestionStore } from './questions.ts';
|
|
30
|
-
import type { SkillsView
|
|
31
|
-
import {
|
|
32
|
-
import type { SubagentFeedView } from './subagents.ts';
|
|
30
|
+
import type { SkillsView } from './skills.ts';
|
|
31
|
+
import type { MentionCandidate } from './mentions.ts';
|
|
32
|
+
import type { SubagentFeedView } from './session/subagents.ts';
|
|
33
33
|
import type { UsageView } from './render/usage.ts';
|
|
34
|
-
import { type JobRow, type SearchRow } from './kernel-panels.ts';
|
|
34
|
+
import { type JobRow, type SearchRow } from './panels/kernel-panels.ts';
|
|
35
35
|
import type { PresetRow } from './presets.ts';
|
|
36
36
|
import type { PermissionRow } from './permissions.ts';
|
|
37
37
|
import type { PluginRow } from './plugin-inventory.ts';
|
|
38
|
-
import type { SessionDirectoryOptions, SessionRow } from './session-directory.ts';
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
readonly kind: 'remove';
|
|
47
|
-
} | {
|
|
48
|
-
readonly kind: 'edit';
|
|
49
|
-
readonly text: string;
|
|
50
|
-
} | {
|
|
51
|
-
readonly kind: 'steer';
|
|
52
|
-
};
|
|
38
|
+
import type { SessionDirectoryOptions, SessionRow } from './session/session-directory.ts';
|
|
39
|
+
import type { GitDiffView, ReviewBranch, ReviewCommit, ReviewSelection } from './git-workflow.ts';
|
|
40
|
+
import type { ProviderAuthorizationDirectory, ProviderAuthorizationRow } from './authorization.ts';
|
|
41
|
+
import type { FilePathInspection, ImagePathInspection } from './attachments.ts';
|
|
42
|
+
export { completionCandidates, stepCompletionIndex } from './completion.ts';
|
|
43
|
+
import type { NoticeTone, QueueMutation } from './ui/ui-contract.ts';
|
|
44
|
+
export type { NoticeTone, QueueMutation } from './ui/ui-contract.ts';
|
|
45
|
+
import { type StyledLine } from './render/lines.ts';
|
|
53
46
|
/** Props the runner hands the app; callbacks stay owned by the runner. */
|
|
54
47
|
export interface AppProps {
|
|
55
48
|
/** Event-fed transcript store for the live session. */
|
|
@@ -132,6 +125,8 @@ export interface AppProps {
|
|
|
132
125
|
subscribeModelProviders?: (listener: () => void) => () => void;
|
|
133
126
|
/** Store or rotate one provider credential through the Harness credential service. */
|
|
134
127
|
saveModelProviderCredential?: (target: ProviderTargetView, key: string) => Promise<void>;
|
|
128
|
+
/** Switch a provider route to its subscription channel (drops the key reference). */
|
|
129
|
+
enableModelProviderSubscription?: (target: ProviderTargetView) => Promise<void>;
|
|
135
130
|
/** Remove one writable provider credential without removing its settings profile. */
|
|
136
131
|
unsetModelProviderCredential?: (target: ProviderTargetView) => Promise<void>;
|
|
137
132
|
/** Remove one user-owned provider profile and its page-managed credential. */
|
|
@@ -195,6 +190,8 @@ export interface AppProps {
|
|
|
195
190
|
searchSessions?: (query: string, signal?: AbortSignal) => Promise<readonly SearchRow[]>;
|
|
196
191
|
/** Load this session's subagent conversations (children by lineage). */
|
|
197
192
|
loadSubagents: () => Promise<readonly SessionRow[]>;
|
|
193
|
+
/** Live subagent attachment: seed + the two real-time buses, runner-wired. */
|
|
194
|
+
attachSubagent?: SubagentAttachmentServices;
|
|
198
195
|
switchSession: (row: SessionRow) => void;
|
|
199
196
|
cancelSessionSwitch: () => boolean;
|
|
200
197
|
loadPlugins: () => readonly PluginRow[];
|
|
@@ -220,8 +217,8 @@ export interface AppProps {
|
|
|
220
217
|
saveLanguage: (name: LanguageName) => void;
|
|
221
218
|
/** Apply and persist one /theme selection; the runner owns the theme.json file. */
|
|
222
219
|
saveTheme?: (name: ThemeName) => void;
|
|
223
|
-
/** Whether
|
|
224
|
-
*
|
|
220
|
+
/** Whether decorative animations run at startup (animations.json; on by
|
|
221
|
+
* default). Functional activity indicators remain live when disabled. */
|
|
225
222
|
animations?: boolean;
|
|
226
223
|
/** Apply and persist one /animation toggle; the runner owns the file. */
|
|
227
224
|
saveAnimations?: (enabled: boolean) => void;
|
|
@@ -252,44 +249,17 @@ export declare function streamTailBodyColumns(rowColumns: number, prefix: string
|
|
|
252
249
|
export declare function queuedInboxRows(entries: readonly TranscriptEntry[], ids: readonly string[]): readonly Extract<TranscriptEntry, {
|
|
253
250
|
kind: 'pending';
|
|
254
251
|
}>[];
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
description: string;
|
|
261
|
-
/** Candidate origin; skills land the same literal text but route through the prompt. */
|
|
262
|
-
origin: 'command' | 'skill' | 'mention';
|
|
252
|
+
interface SettledPhysicalRow {
|
|
253
|
+
/** Stable one-row Static element. */
|
|
254
|
+
readonly element: ReactElement;
|
|
255
|
+
/** The same row model reused by the mutable viewport tail. */
|
|
256
|
+
readonly line: StyledLine;
|
|
263
257
|
}
|
|
264
|
-
/**
|
|
265
|
-
* Wrap one completion-menu cursor step. An empty menu keeps the index at 0:
|
|
266
|
-
* `% 0` is NaN, and a NaN index silently disables the highlight, the accept
|
|
267
|
-
* key, and any later Enter that runs through the menu.
|
|
268
|
-
*/
|
|
269
|
-
export declare function stepCompletionIndex(index: number, delta: number, count: number): number;
|
|
270
|
-
/**
|
|
271
|
-
* Resolve completion candidates for the current input: TUI-local commands,
|
|
272
|
-
* the live registry descriptors, and user-invocable skills, filtered by the
|
|
273
|
-
* typed prefix. Command names win collisions (the dispatch tries the
|
|
274
|
-
* registry first and only then falls through to the skill gesture), and a
|
|
275
|
-
* later duplicate name never renders twice.
|
|
276
|
-
*
|
|
277
|
-
* A bare `/` returns the FULL merged list — Codex's command popup shows every
|
|
278
|
-
* command inside a scroll window on an empty filter, and the menu's own
|
|
279
|
-
* selection window bounds the visible rows, so no slice cap is needed.
|
|
280
|
-
*/
|
|
281
|
-
export declare function completionCandidates(value: string, descriptors: readonly CommandDescriptor[], skills: readonly SkillRow[]): readonly CompletionCandidate[];
|
|
282
|
-
/** One cached settled row: the row Box plus its roomy-prompt spacers. */
|
|
283
258
|
interface SettledRowRecord {
|
|
284
|
-
/**
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
|
|
288
|
-
/** The roomy-prompt spacer AFTER the row, or undefined. */
|
|
289
|
-
after: ReactElement | undefined;
|
|
290
|
-
/** Physical rows this record contributes (row body plus spacers) — the
|
|
291
|
-
* unit of the rendered-history cap. */
|
|
292
|
-
rows: number;
|
|
259
|
+
/** Physical rows for one settled entry, including roomy-prompt spacers. */
|
|
260
|
+
readonly physical: readonly SettledPhysicalRow[];
|
|
261
|
+
/** Physical rows this record contributes — the rendered-history-cap unit. */
|
|
262
|
+
readonly rows: number;
|
|
293
263
|
}
|
|
294
264
|
/** The incremental settled-history cache (see `computeSettledRows`). */
|
|
295
265
|
interface SettledRowsCache {
|
|
@@ -309,10 +279,13 @@ interface SettledRowsCache {
|
|
|
309
279
|
epoch: number;
|
|
310
280
|
/** The terminal width the rows were wrapped for; a change forces a rebuild. */
|
|
311
281
|
columns: number;
|
|
312
|
-
/**
|
|
282
|
+
/** Header/hint followed by one element per physical transcript row. */
|
|
313
283
|
flat: ReactElement[];
|
|
284
|
+
/** Physical transcript rows only (header/hint excluded). */
|
|
285
|
+
physical: SettledPhysicalRow[];
|
|
314
286
|
/** Settled entries dropped from the window's head (rendering only — the
|
|
315
|
-
* event log keeps everything;
|
|
287
|
+
* event log keeps everything; /export reads all of it and Ctrl+O reads its
|
|
288
|
+
* inspectable entries). */
|
|
316
289
|
droppedEntries: number;
|
|
317
290
|
/** Physical rows the window's entries contribute (excludes header/hint). */
|
|
318
291
|
totalRows: number;
|
|
@@ -342,8 +315,9 @@ interface SettledRowsResult {
|
|
|
342
315
|
*
|
|
343
316
|
* RENDERED-HISTORY CAP: the window holds at most `rowCap` physical rows of
|
|
344
317
|
* settled transcript (header and hint reserved on top). The cap exists only
|
|
345
|
-
* here — the event log, the store projection, /export,
|
|
346
|
-
*
|
|
318
|
+
* here — the event log, the store projection, /export, and /resume keep the
|
|
319
|
+
* full history; Ctrl+O keeps its inspectable subset. Ink 5's <Static> is a
|
|
320
|
+
* consumption counter
|
|
347
321
|
* (items.slice(index) keyed on length): deleting head items mid-stream while
|
|
348
322
|
* appending tail items can permanently swallow new rows, so the append branch
|
|
349
323
|
* NEVER drops the head — it only accounts rows and flags `needsTrim` once the
|
|
@@ -365,4 +339,3 @@ interface SettledRowsResult {
|
|
|
365
339
|
export declare function computeSettledRows(previous: SettledRowsCache | undefined, entries: readonly TranscriptEntry[], settled: number, showReasoning: boolean, resumed: boolean, epoch: number, columns?: number, rowCap?: number): SettledRowsResult;
|
|
366
340
|
/** The whole terminal app; state arrives via the store, output via Ink. */
|
|
367
341
|
export declare function App(props: AppProps): ReactElement;
|
|
368
|
-
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Slash-command parsing and completion candidates shared by the composer and help panel. */
|
|
2
|
+
import type { CommandDescriptor } from '@deepseek-ai/dsh-commands';
|
|
3
|
+
import { type MessageKey } from './i18n.ts';
|
|
4
|
+
import type { SkillRow } from './skills.ts';
|
|
5
|
+
/** One TUI-owned slash command: label plus its i18n description key. */
|
|
6
|
+
export interface LocalCommand {
|
|
7
|
+
readonly label: string;
|
|
8
|
+
readonly descriptionKey: MessageKey;
|
|
9
|
+
}
|
|
10
|
+
/** One source of truth for TUI-owned slash commands in completion and `/help`. */
|
|
11
|
+
export declare const LOCAL_COMMANDS: readonly LocalCommand[];
|
|
12
|
+
export declare const LOCAL_COMMAND_NAMES: ReadonlySet<string>;
|
|
13
|
+
/** TUI-local commands that reject trailing input instead of forwarding it as a prompt. */
|
|
14
|
+
export declare const BARE_LOCAL_COMMANDS: ReadonlySet<string>;
|
|
15
|
+
/** Split a slash line into the command name and any trailing input. */
|
|
16
|
+
export declare function slashNameAndArgs(text: string): {
|
|
17
|
+
readonly name: string;
|
|
18
|
+
readonly args: string;
|
|
19
|
+
} | undefined;
|
|
20
|
+
/** One completion candidate row. */
|
|
21
|
+
export interface CompletionCandidate {
|
|
22
|
+
readonly label: string;
|
|
23
|
+
readonly description: string;
|
|
24
|
+
readonly origin: 'command' | 'skill' | 'mention';
|
|
25
|
+
}
|
|
26
|
+
/** Wrap one completion-menu cursor step; an empty menu keeps the index at zero. */
|
|
27
|
+
export declare function stepCompletionIndex(index: number, delta: number, count: number): number;
|
|
28
|
+
/** Merge local commands, registry descriptors, and skills using dispatch shadowing order. */
|
|
29
|
+
export declare function completionCandidates(value: string, descriptors: readonly CommandDescriptor[], skills: readonly SkillRow[]): readonly CompletionCandidate[];
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/** Composer input, command routing, attachments, and one-shot composer animations. */
|
|
2
|
+
import { type ReactElement } from 'react';
|
|
3
|
+
import type { CommandDescriptor } from '@deepseek-ai/dsh-commands';
|
|
4
|
+
import type { ContentBlock, FileBlock, ImageBlock } from '@deepseek-ai/dsh-llm';
|
|
5
|
+
import { type FilePathInspection, type ImagePathInspection } from './attachments.ts';
|
|
6
|
+
import type { SkillRow } from './skills.ts';
|
|
7
|
+
import { type MentionCandidate } from './mentions.ts';
|
|
8
|
+
import { type ReviewSelection } from './git-workflow.ts';
|
|
9
|
+
import { type LanguageName } from './i18n.ts';
|
|
10
|
+
import { type DeepseekWaveStyle, type DeepseekWaveTier } from './render/animations.ts';
|
|
11
|
+
import type { TranscriptEntry } from './render/projection.ts';
|
|
12
|
+
import type { NoticeTone, QueueMutation } from './ui/ui-contract.ts';
|
|
13
|
+
/**
|
|
14
|
+
* The prompt box: TUI-local slash commands handled locally, other lines
|
|
15
|
+
* dispatched; input editing keeps a cursor with history and completion.
|
|
16
|
+
* While a modal (approval / question / model panel) owns the keys, the
|
|
17
|
+
* box passes every key through untouched.
|
|
18
|
+
*/
|
|
19
|
+
export declare function Composer({ active, frozen, frozenHint, busy, descriptors, skills, dispatch, steer, submitMode, cycleSubmitMode, interrupt, quit, openModel, openEffort, openHelp, openMode, openPermission, openResume, openSearch, openPlugin, openUpdate, openSchedule, openJobs, openStatusline, openTheme, openLanguage, saveLanguage, openHistory, openQueue, openAgents, openSubagent, openTodos, openUsage, openDelete, openDiff, openReviewPicker, reviewChanges, deleteConfirm, confirmDelete, cancelDelete, createSession, forkSession, cancelSessionSwitch, notify, applyEditorKeys, hasNotice, dismissNotice, toggleReasoning, openVerbose, clearView, refresh, loadMentions, inspectImages, prepareImages, inspectFiles, prepareFiles, cycleMode, exportTranscript, renameTitle, copyLastResponse, recallSpace, recordLocal, recordHistory, queued, updateQueued, historyFill, historyConsumed, animations, applyAnimations, applyRainbow, rainbowBurstId, waveTier, waveStyle, maxRows, anchorRowsBelow, tabTitle, onEditorRows, onMenuRows, sessionKey }: {
|
|
20
|
+
active: boolean;
|
|
21
|
+
frozen: boolean;
|
|
22
|
+
/** Frozen-band hint naming the surface that owns the keyboard; an empty
|
|
23
|
+
* draft otherwise advertises typing that the composer cannot accept. */
|
|
24
|
+
frozenHint?: string;
|
|
25
|
+
busy: boolean;
|
|
26
|
+
descriptors: readonly CommandDescriptor[];
|
|
27
|
+
skills: readonly SkillRow[];
|
|
28
|
+
dispatch: (text: string, attachments?: readonly ContentBlock[], origin?: string) => void;
|
|
29
|
+
/** Submit as steering into the running turn (see {@link AppProps.steer}). */
|
|
30
|
+
steer: (text: string, attachments?: readonly ContentBlock[], origin?: string) => void;
|
|
31
|
+
/** Delivery mode the next submission uses; Tab on an empty composer flips it. */
|
|
32
|
+
submitMode: 'queue' | 'steer';
|
|
33
|
+
/** Flip {@link submitMode} and report the new mode. */
|
|
34
|
+
cycleSubmitMode: () => void;
|
|
35
|
+
/** The full current session identity ('' while pending); the delivery origin. */
|
|
36
|
+
sessionKey: string;
|
|
37
|
+
interrupt: () => boolean;
|
|
38
|
+
quit: () => void;
|
|
39
|
+
openModel: () => void;
|
|
40
|
+
openEffort: () => void;
|
|
41
|
+
openHelp: () => void;
|
|
42
|
+
openMode: () => void;
|
|
43
|
+
openPermission: () => void;
|
|
44
|
+
openResume: () => void;
|
|
45
|
+
/** Open the /search panel with an optional seed query. */
|
|
46
|
+
openSearch: (query: string) => void;
|
|
47
|
+
openPlugin: (query?: string) => void;
|
|
48
|
+
/** Open the /update panel (aligned upgrade surface). */
|
|
49
|
+
openUpdate: () => void;
|
|
50
|
+
/** Open the /schedule reminder panel (read-only catalog). */
|
|
51
|
+
openSchedule: () => void;
|
|
52
|
+
openJobs: () => void;
|
|
53
|
+
openStatusline: () => void;
|
|
54
|
+
openTheme: () => void;
|
|
55
|
+
/** Open the /language picker (bare /language). */
|
|
56
|
+
openLanguage: () => void;
|
|
57
|
+
/** Apply and persist a language chosen by argument. */
|
|
58
|
+
saveLanguage: (name: LanguageName) => void;
|
|
59
|
+
openHistory: () => void;
|
|
60
|
+
openQueue: () => void;
|
|
61
|
+
/** Open the /agents panel (live subagent feed + transcript entry). */
|
|
62
|
+
openAgents: () => void;
|
|
63
|
+
/** Open the /subagent model panel. */
|
|
64
|
+
openSubagent: () => void;
|
|
65
|
+
/** Open the /todos subpage (full todo list in one bounded panel). */
|
|
66
|
+
openTodos: () => void;
|
|
67
|
+
openUsage: () => void;
|
|
68
|
+
/** Open the dedicated /delete picker, optionally pre-armed on one id. */
|
|
69
|
+
openDelete: (id?: string) => void;
|
|
70
|
+
openDiff: (argument: string) => void;
|
|
71
|
+
reviewChanges: (selection: ReviewSelection) => void;
|
|
72
|
+
/** Open the /review candidate picker (bare /review). */
|
|
73
|
+
openReviewPicker: () => void;
|
|
74
|
+
/** The row id awaiting y/n in this box, when a deletion is pending. */
|
|
75
|
+
deleteConfirm?: string;
|
|
76
|
+
/** Confirm the pending deletion (y in the box). */
|
|
77
|
+
confirmDelete: () => void;
|
|
78
|
+
/** Cancel the pending deletion (any other key in the box). */
|
|
79
|
+
cancelDelete: () => void;
|
|
80
|
+
createSession: (mode?: string) => void;
|
|
81
|
+
forkSession: (argument: string) => void;
|
|
82
|
+
cancelSessionSwitch: () => boolean;
|
|
83
|
+
notify: (text: string, tone?: NoticeTone) => void;
|
|
84
|
+
/** Apply the Ctrl+R passthrough to the detected editor (/vscode-keys); resolves to a one-line summary. */
|
|
85
|
+
applyEditorKeys: () => Promise<string>;
|
|
86
|
+
hasNotice: boolean;
|
|
87
|
+
dismissNotice: () => void;
|
|
88
|
+
toggleReasoning: () => void;
|
|
89
|
+
openVerbose: () => void;
|
|
90
|
+
clearView: () => void;
|
|
91
|
+
refresh: () => void;
|
|
92
|
+
loadMentions: (query: string, signal?: AbortSignal) => Promise<readonly MentionCandidate[]>;
|
|
93
|
+
inspectImages: (paths: readonly string[]) => Promise<readonly ImagePathInspection[]>;
|
|
94
|
+
prepareImages: (paths: readonly string[], signal?: AbortSignal) => Promise<readonly ImageBlock[]>;
|
|
95
|
+
inspectFiles: (paths: readonly string[]) => Promise<readonly FilePathInspection[]>;
|
|
96
|
+
prepareFiles: (paths: readonly string[], signal?: AbortSignal) => Promise<readonly FileBlock[]>;
|
|
97
|
+
cycleMode: () => string;
|
|
98
|
+
exportTranscript: (argument: string) => Promise<void>;
|
|
99
|
+
renameTitle: (argument: string) => string;
|
|
100
|
+
copyLastResponse: () => Promise<string>;
|
|
101
|
+
/** Newest-first recall space (persistent + in-session, deduped). */
|
|
102
|
+
recallSpace: readonly string[];
|
|
103
|
+
/** Record one in-session submission (deduped, local only). */
|
|
104
|
+
recordLocal: (text: string) => void;
|
|
105
|
+
/** Persist one submission to the global history file. */
|
|
106
|
+
recordHistory: (text: string) => void;
|
|
107
|
+
/** Next-turn inbox rows, ordered exactly as the durable inbox. */
|
|
108
|
+
queued: readonly Extract<TranscriptEntry, {
|
|
109
|
+
kind: 'pending';
|
|
110
|
+
}>[];
|
|
111
|
+
updateQueued?: (messageId: string, action: QueueMutation) => void;
|
|
112
|
+
/** Accepted /history entry waiting to be placed into the composer. */
|
|
113
|
+
historyFill: {
|
|
114
|
+
text: string;
|
|
115
|
+
index: number;
|
|
116
|
+
} | undefined;
|
|
117
|
+
/** Marks the accepted entry consumed (called after the fill is applied). */
|
|
118
|
+
historyConsumed: () => void;
|
|
119
|
+
/** Whether decorative animations run; caret and busy activity stay live. */
|
|
120
|
+
animations: boolean;
|
|
121
|
+
/** Apply and report one /animation toggle (App persists through the runner). */
|
|
122
|
+
applyAnimations: (enabled: boolean) => void;
|
|
123
|
+
/** Reroll or pin the rainbow palette (switches to rainbow if needed). */
|
|
124
|
+
applyRainbow: (seed?: number) => void;
|
|
125
|
+
/** Monotonic id of the in-flight /rainbow composer burst; 0 means none. */
|
|
126
|
+
rainbowBurstId: number;
|
|
127
|
+
/** DeepSeek easter-egg wave tier of the applied route (null otherwise):
|
|
128
|
+
* official DeepSeek models drive their flash/pro tiers, non-DeepSeek
|
|
129
|
+
* models running an effort above high drive the "Into the Unknown"
|
|
130
|
+
* variant. Drives the persistent prompt glyph/accent and the sparkle
|
|
131
|
+
* tier. */
|
|
132
|
+
waveTier: DeepseekWaveTier | null;
|
|
133
|
+
/** The ignition style running, if any: Wave / Aurora / Pulse. */
|
|
134
|
+
waveStyle: DeepseekWaveStyle | null;
|
|
135
|
+
/** Maximum physical editor rows the composer may occupy (see composerMaxRows). */
|
|
136
|
+
maxRows: number;
|
|
137
|
+
/** Terminal rows below the composer the editor does not own: the status
|
|
138
|
+
* footer and Ink's parked cursor row. The IME anchor adds these to the
|
|
139
|
+
* caret's in-band offset to reach that parked position. */
|
|
140
|
+
anchorRowsBelow: number;
|
|
141
|
+
/** The managed terminal tab label; re-asserted on terminal focus-in so a
|
|
142
|
+
* background process sharing the console cannot keep it overwritten. */
|
|
143
|
+
tabTitle: string;
|
|
144
|
+
/** Reports the editor's current physical row count so the live budget stays exact. */
|
|
145
|
+
onEditorRows: (rows: number) => void;
|
|
146
|
+
/** Reports the open completion menu's physical row count (0 when closed)
|
|
147
|
+
* for the same reason: the dynamic budget must reserve it, not overflow. */
|
|
148
|
+
onMenuRows: (rows: number) => void;
|
|
149
|
+
}): ReactElement;
|
|
150
|
+
/** One cached settled row: the row Box plus its roomy-prompt spacers. */
|
|
@@ -119,3 +119,9 @@ export declare function parseReviewConclusion(text: string): ReviewConclusion |
|
|
|
119
119
|
* priority plus the overall verdict, or a no-findings phrasing.
|
|
120
120
|
*/
|
|
121
121
|
export declare function reviewSummaryLine(conclusion: ReviewConclusion): string;
|
|
122
|
+
/**
|
|
123
|
+
* Resolve the working directory's git branch for the status line.
|
|
124
|
+
* @param cwd - the session's working directory.
|
|
125
|
+
* @returns the branch name, or '' outside a repository or on a detached HEAD.
|
|
126
|
+
*/
|
|
127
|
+
export declare function gitBranch(cwd: string): string;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -10,13 +10,12 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { Context } from '@deepseek-ai/cordis';
|
|
12
12
|
import z from '@deepseek-ai/schemastery';
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
import type { SearchRow } from './kernel-panels.ts';
|
|
13
|
+
export { planCycleDecision, type ModeCycleDecision } from './runner/mode-cycle.ts';
|
|
14
|
+
export { runQuitSequence, type QuitCleanupStep } from './runner/quit.ts';
|
|
15
|
+
export { exportSessionIdSuffix, resolveTarget } from './runner/session-target.ts';
|
|
16
|
+
export { applyQueueMutation, cancelPreservingQueue, queueEditContent, StartupInputGate, submissionBelongsToSession, type QueuedSubmission, type QueueMutationOutcome, } from './runner/submissions.ts';
|
|
17
|
+
export { subagentCatalogSeed } from './session/subagents.ts';
|
|
18
|
+
export { searchHitToRow } from './runner/search-rows.ts';
|
|
20
19
|
/** Stable Cordis plugin name. */
|
|
21
20
|
export declare const name = "tui-runner";
|
|
22
21
|
/** Core services required before the interactive session can start. */
|
|
@@ -34,190 +33,9 @@ export interface Config {
|
|
|
34
33
|
};
|
|
35
34
|
}
|
|
36
35
|
export declare const Config: z<Config>;
|
|
37
|
-
/** The session identity this invocation will run, plus whether it is resumed. */
|
|
38
|
-
interface Target {
|
|
39
|
-
sessionId: string;
|
|
40
|
-
resume: boolean;
|
|
41
|
-
mode?: string;
|
|
42
|
-
cwd?: string;
|
|
43
|
-
seed?: readonly SessionEvent[];
|
|
44
|
-
parentSession?: SessionId;
|
|
45
|
-
/** Marks the session as a subagent conversation in the durable header. */
|
|
46
|
-
origin?: 'subagent';
|
|
47
|
-
seedLength?: number;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Reduce a session id to a filename-safe /export default-name suffix. Session
|
|
51
|
-
* ids are normally minted `session-<uuid>`, but `--session` accepts arbitrary
|
|
52
|
-
* user text: path separators must never leak into the default export filename
|
|
53
|
-
* (which would escape the session cwd).
|
|
54
|
-
* @param id - the session id.
|
|
55
|
-
* @returns at most the last 8 filename-safe characters.
|
|
56
|
-
*/
|
|
57
|
-
export declare function exportSessionIdSuffix(id: string): string;
|
|
58
|
-
/** One ordered step of the terminal quit cleanup. */
|
|
59
|
-
export interface QuitCleanupStep {
|
|
60
|
-
/** Step label used in diagnostics and tests. */
|
|
61
|
-
readonly name: string;
|
|
62
|
-
/** The step's async work; a rejection is contained by the sequence. */
|
|
63
|
-
readonly run: () => Promise<void>;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Run the ordered quit cleanup, then request exit. Every step rejection is
|
|
67
|
-
* contained (reported through `onError`) so a failed flush or dispose never
|
|
68
|
-
* skips the remaining cleanup; the exit request is always reached exactly
|
|
69
|
-
* once.
|
|
70
|
-
* @param steps - the cleanup steps in dependency order (settle the visible
|
|
71
|
-
* session, await the final in-flight composition, await durable recall).
|
|
72
|
-
* @param exit - the terminal exit request (code 0).
|
|
73
|
-
* @param onError - optional failure sink; called once per failing step and
|
|
74
|
-
* itself contained, so a throwing sink cannot abort the sequence.
|
|
75
|
-
* @returns the names of the steps that started, in order (for tests).
|
|
76
|
-
*/
|
|
77
|
-
export declare function runQuitSequence(steps: readonly QuitCleanupStep[], exit: (code: number) => void, onError?: (name: string, error: unknown) => void): Promise<readonly string[]>;
|
|
78
|
-
/** One composer submission waiting behind the startup delivery. */
|
|
79
|
-
export interface QueuedSubmission {
|
|
80
|
-
readonly text: string;
|
|
81
|
-
/** `steer` inserts into the running turn; `followup` waits for the next one. */
|
|
82
|
-
readonly mode: 'followup' | 'steer';
|
|
83
|
-
readonly images: readonly ContentBlock[];
|
|
84
|
-
}
|
|
85
|
-
/** What one requested queue mutation did; the runner maps it to one notice. */
|
|
86
|
-
export type QueueMutationOutcome = 'removed' | 'edited' | 'steered' | 'unavailable' | 'empty' | 'steerUnavailable';
|
|
87
|
-
/**
|
|
88
|
-
* Replace one queued message's text while keeping its attachments. A queue
|
|
89
|
-
* edit rewrites what the user typed, not what they attached: image and file
|
|
90
|
-
* blocks ride through in delivery order (text first, then attachments, the
|
|
91
|
-
* shape {@link deliverLine} submits). Dropping them here would silently strip
|
|
92
|
-
* an attachment the user already confirmed, so this is the edit's single
|
|
93
|
-
* definition and the panel's read-only marker only mirrors it.
|
|
94
|
-
*/
|
|
95
|
-
export declare function queueEditContent(content: readonly ContentBlock[], text: string): ContentBlock[];
|
|
96
|
-
/**
|
|
97
|
-
* Apply one terminal queue mutation to the live inbox. The decision and the
|
|
98
|
-
* inbox change are pure over the supplied handles so every branch is testable
|
|
99
|
-
* without an agent; steering itself is injected because it wakes the driver
|
|
100
|
-
* rather than mutating the inbox. The durable inbox splices remain the UI's
|
|
101
|
-
* single source of truth — this helper never reports a state the inbox did not
|
|
102
|
-
* actually reach.
|
|
103
|
-
* @param inbox - the live agent inbox (pending lists plus its mutators).
|
|
104
|
-
* @param status - the agent's lifecycle status; steering needs `running`.
|
|
105
|
-
* @param messageId - identity of the queued message to mutate.
|
|
106
|
-
* @param action - the requested mutation.
|
|
107
|
-
* @param steer - submits the removed message as next-step steering.
|
|
108
|
-
* @returns the outcome the caller reports.
|
|
109
|
-
*/
|
|
110
|
-
export declare function applyQueueMutation(inbox: Pick<Inbox, 'nextTurn' | 'append' | 'remove' | 'replace'>, status: AgentStatus, messageId: string, action: QueueMutation, steer: (message: UserMessage) => void): QueueMutationOutcome;
|
|
111
|
-
/**
|
|
112
|
-
* Cancel the active turn while keeping the next-turn queue, then wake the
|
|
113
|
-
* driver again so the preserved messages actually run. `cancel` clears
|
|
114
|
-
* pending work by default and never wakes the driver on its own, so the queue
|
|
115
|
-
* is captured first and re-submitted afterwards: a waking submission latches
|
|
116
|
-
* the wake while the aborted activity converges to idle, which is what turns
|
|
117
|
-
* "preserved" into "sent next" instead of "parked forever". Next-step
|
|
118
|
-
* steering is deliberately dropped — it belonged to the cancelled turn.
|
|
119
|
-
* @param agent - the live agent handle.
|
|
120
|
-
* @returns how many queued messages were preserved across the abort.
|
|
121
|
-
*/
|
|
122
|
-
export declare function cancelPreservingQueue(agent: Pick<Agent, 'inbox' | 'cancel' | 'followup'>): number;
|
|
123
|
-
/**
|
|
124
|
-
* Whether a tagged submission still belongs to the active session. Attachment
|
|
125
|
-
* prepares resolve on the microtask timeline, while a queued session switch
|
|
126
|
-
* remounts the app asynchronously — the composing instance's unmount cleanup
|
|
127
|
-
* runs too late to abort, so the delivery itself carries the composing
|
|
128
|
-
* session's full id and the runner drops it here when the world moved on.
|
|
129
|
-
* An untagged (synchronous) or pending-session ('') submission always passes.
|
|
130
|
-
*/
|
|
131
|
-
export declare function submissionBelongsToSession(origin: string | undefined, activeSessionId: string | undefined): boolean;
|
|
132
|
-
/**
|
|
133
|
-
* Root-log catalog facts a resumed session must replay into the subagent
|
|
134
|
-
* feed: constructor seeds never fire on the live bus, so without this the
|
|
135
|
-
* children of a resumed session vanish behind a restart. The empty-child
|
|
136
|
-
* placeholder row (childId '') is a placeholder, not a child, and stays out.
|
|
137
|
-
*/
|
|
138
|
-
export declare function subagentCatalogSeed(events: readonly SessionEvent[]): readonly SessionEvent<'subagent/catalog'>[];
|
|
139
|
-
/**
|
|
140
|
-
* Map one cross-session full-text hit onto the /search panel's row (pure).
|
|
141
|
-
* Labels fall back to the short id form — the engine's hit carries the
|
|
142
|
-
* strongest matching event, not the title observation.
|
|
143
|
-
*/
|
|
144
|
-
export declare function searchHitToRow(hit: {
|
|
145
|
-
header: SessionHeader;
|
|
146
|
-
bestMatch: {
|
|
147
|
-
snippet: string;
|
|
148
|
-
time: number;
|
|
149
|
-
};
|
|
150
|
-
}): SearchRow;
|
|
151
|
-
/** One Shift+Tab station decision for the mode cycle. */
|
|
152
|
-
export type ModeCycleDecision = {
|
|
153
|
-
readonly kind: 'permission';
|
|
154
|
-
readonly preset: string;
|
|
155
|
-
} | {
|
|
156
|
-
readonly kind: 'plan-on';
|
|
157
|
-
} | {
|
|
158
|
-
readonly kind: 'plan-off';
|
|
159
|
-
readonly preset: string;
|
|
160
|
-
};
|
|
161
|
-
/**
|
|
162
|
-
* Decide the next Shift+Tab station. The cycle keeps the preset table's
|
|
163
|
-
* own order (most restrictive first) and inserts ONE plan station between
|
|
164
|
-
* the most restrictive preset and the wrap target: with the shipped three
|
|
165
|
-
* presets the user sees workspace-write → danger-full-access → read-only
|
|
166
|
-
* → plan → workspace-write. Plan IS the most restrictive preset plus the
|
|
167
|
-
* plan prompt layer — entering it switches nothing (the cycle is already
|
|
168
|
-
* parked on read-only), and leaving it lands on the next preset after the
|
|
169
|
-
* most restrictive one. Without the /plan command the cycle is exactly the
|
|
170
|
-
* preset table.
|
|
171
|
-
*
|
|
172
|
-
* `planIntent` covers the committed fold's commit lag: upstream queues a
|
|
173
|
-
* plan switch during an open turn (and the command pipeline is async even
|
|
174
|
-
* idle), so the durable plan/mode event lands AFTER the press that chose
|
|
175
|
-
* it. While an intent from an earlier press is in flight it — not the
|
|
176
|
-
* stale committed fold — decides the station, so repeated presses advance
|
|
177
|
-
* the cycle instead of re-issuing the same plan transition (the stuck
|
|
178
|
-
* plan-on/plan-off toggle). Undefined falls back to the committed fold.
|
|
179
|
-
*/
|
|
180
|
-
export declare function planCycleDecision(input: {
|
|
181
|
-
readonly names: readonly string[];
|
|
182
|
-
readonly current: string;
|
|
183
|
-
readonly inPlan: boolean;
|
|
184
|
-
readonly planAvailable: boolean;
|
|
185
|
-
readonly planIntent?: boolean;
|
|
186
|
-
}): ModeCycleDecision | undefined;
|
|
187
|
-
/**
|
|
188
|
-
* Order-preserving gate for composer input while the startup prompt/images
|
|
189
|
-
* are still preparing. Anything submitted before the startup delivery settles
|
|
190
|
-
* queues and flushes afterwards in submit order, so the initial request can
|
|
191
|
-
* never be overtaken by typing that raced a slow image preparation. The flush
|
|
192
|
-
* also runs when the startup delivery fails: user input is never stranded.
|
|
193
|
-
*/
|
|
194
|
-
export declare class StartupInputGate {
|
|
195
|
-
private readonly deliver;
|
|
196
|
-
private readonly queued;
|
|
197
|
-
private pending;
|
|
198
|
-
constructor(deliver: (submission: QueuedSubmission) => void);
|
|
199
|
-
/** Submit one line: delivered now while idle, queued behind the startup delivery otherwise. */
|
|
200
|
-
submit(submission: QueuedSubmission): void;
|
|
201
|
-
/**
|
|
202
|
-
* Run the startup delivery — the callback receives the direct-delivery sink
|
|
203
|
-
* for the startup prompt itself — then flush everything that queued behind
|
|
204
|
-
* it, in order, even when the callback rejects.
|
|
205
|
-
*/
|
|
206
|
-
run(startup: (deliver: (submission: QueuedSubmission) => void) => Promise<void>): Promise<void>;
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Resolve the invocation's target session against the persisted headers.
|
|
210
|
-
* @param startup - the parsed startup flags.
|
|
211
|
-
* @param persistence - the persistence service; required for resume/latest.
|
|
212
|
-
* @param cwd - the working directory `--continue` filters by.
|
|
213
|
-
* @returns the target identity.
|
|
214
|
-
* @throws with a user-facing message when the flags name nothing resolvable.
|
|
215
|
-
*/
|
|
216
|
-
export declare function resolveTarget(startup: TuiStartup, persistence: SessionPersistence | undefined, cwd: string): Promise<Target>;
|
|
217
36
|
/**
|
|
218
37
|
* Mount the interactive terminal driver.
|
|
219
38
|
* @param ctx - plugin context carrying core services and the launcher-provided exit request.
|
|
220
39
|
* @param config - validated startup config resolved from the tuiStartup provider.
|
|
221
40
|
*/
|
|
222
41
|
export declare function apply(ctx: Context, config: Config): void;
|
|
223
|
-
export {};
|