dsh-code 1.2.0 → 1.4.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 +5 -5
- package/README.md +5 -5
- package/lib/index.mjs +6679 -5232
- package/lib/startup.mjs +1 -1
- package/lib/{theme-7u5Qo3dF.mjs → theme-B3orFUYz.mjs} +8 -0
- package/lib/types/app.d.ts +32 -45
- package/lib/types/attachments.d.ts +16 -7
- 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 +65 -5
- 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} +19 -38
- 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} +22 -1
- package/lib/types/provider-settings.d.ts +11 -0
- package/lib/types/render/inspector.d.ts +8 -0
- package/lib/types/render/status.d.ts +4 -1
- package/lib/types/render/text.d.ts +4 -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 +46 -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/{history.d.ts → session/history.d.ts} +10 -0
- package/lib/types/{session-directory.d.ts → session/session-directory.d.ts} +25 -1
- package/lib/types/{session-switch.d.ts → session/session-switch.d.ts} +8 -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/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/lib/types/version.d.ts +2 -0
- package/package.json +7 -5
- package/src/app.ts +707 -4108
- package/src/attachments.ts +65 -19
- package/src/completion.ts +117 -0
- package/src/composer.ts +1956 -0
- package/src/git-workflow.ts +18 -0
- package/src/index.ts +164 -645
- package/src/input-split.ts +24 -4
- package/src/internals.ts +1 -1
- package/src/locales/en.ts +66 -5
- package/src/locales/zh.ts +66 -5
- package/src/{authorization-panel.ts → panels/authorization-panel.ts} +30 -8
- 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} +142 -90
- 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} +117 -10
- package/src/provider-settings.ts +38 -0
- package/src/rainbow.ts +13 -3
- package/src/render/inspector.ts +23 -0
- package/src/render/status.ts +80 -29
- package/src/render/text.ts +10 -1
- 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 +206 -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/{fork.ts → session/fork.ts} +11 -7
- package/src/{history.ts → session/history.ts} +14 -0
- package/src/{session-directory.ts → session/session-directory.ts} +83 -4
- package/src/{session-switch.ts → session/session-switch.ts} +14 -0
- package/src/{store.ts → session/store.ts} +20 -2
- package/src/{subagents.ts → session/subagents.ts} +12 -1
- 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/src/version.ts +5 -0
- /package/lib/types/{fork.d.ts → session/fork.d.ts} +0 -0
|
@@ -51,13 +51,50 @@ export declare const en: {
|
|
|
51
51
|
readonly 'search.compact.searching': "searching…";
|
|
52
52
|
readonly 'search.compact.error': "error: {message}";
|
|
53
53
|
readonly 'search.footer': "↑↓ move · enter search/resume · esc close";
|
|
54
|
+
readonly 'header.hint': "/help · Esc interrupt · Ctrl+C quit";
|
|
55
|
+
readonly 'header.hintResumed': "resumed · /help · Esc interrupt";
|
|
54
56
|
readonly 'statusline.title': "/statusline · items apply to the live status line below";
|
|
57
|
+
readonly 'statusline.item.model': "model";
|
|
58
|
+
readonly 'statusline.item.model.desc': "provider/model serving this session";
|
|
59
|
+
readonly 'statusline.item.cwd': "cwd";
|
|
60
|
+
readonly 'statusline.item.cwd.desc': "working-directory basename";
|
|
61
|
+
readonly 'statusline.item.mode': "mode";
|
|
62
|
+
readonly 'statusline.item.mode.desc': "agent preset composing the session";
|
|
63
|
+
readonly 'statusline.item.branch': "branch";
|
|
64
|
+
readonly 'statusline.item.branch.desc': "git branch inside a repository";
|
|
65
|
+
readonly 'statusline.item.context': "context";
|
|
66
|
+
readonly 'statusline.item.context.desc': "context-window occupancy meter";
|
|
67
|
+
readonly 'statusline.item.permission': "permission";
|
|
68
|
+
readonly 'statusline.item.permission.desc': "permission preset badge with cycle hint";
|
|
69
|
+
readonly 'statusline.item.plan': "plan";
|
|
70
|
+
readonly 'statusline.item.plan.desc': "plan-mode state mark";
|
|
71
|
+
readonly 'statusline.item.turns': "turns";
|
|
72
|
+
readonly 'statusline.item.turns.desc': "turn and step counters";
|
|
73
|
+
readonly 'statusline.item.durations': "durations";
|
|
74
|
+
readonly 'statusline.item.durations.desc': "llm/ttft/decode/tool wall time";
|
|
75
|
+
readonly 'statusline.item.cache': "cache";
|
|
76
|
+
readonly 'statusline.item.cache.desc': "cache-hit share of billed input";
|
|
77
|
+
readonly 'statusline.item.tokens': "tokens";
|
|
78
|
+
readonly 'statusline.item.tokens.desc': "cumulative input/output tokens";
|
|
79
|
+
readonly 'statusline.item.title': "title";
|
|
80
|
+
readonly 'statusline.item.title.desc': "session title or short id";
|
|
81
|
+
readonly 'statusline.item.goal': "goal";
|
|
82
|
+
readonly 'statusline.item.goal.desc': "live goal phase and round progress";
|
|
83
|
+
readonly 'statusline.item.sandbox': "sandbox";
|
|
84
|
+
readonly 'statusline.item.sandbox.desc': "divergent sandbox-mode override";
|
|
55
85
|
readonly 'schedule.title': "/schedule · {count} active reminder";
|
|
56
86
|
readonly 'schedule.titlePlural': "/schedule · {count} active reminders";
|
|
57
87
|
readonly 'schedule.empty': "no active reminders — the model creates them with schedule_create";
|
|
58
88
|
readonly 'document.loading': "loading transcript…";
|
|
89
|
+
readonly 'attach.bar': "observing · {label} · r reload · esc/ctrl+d back";
|
|
90
|
+
readonly 'attach.loading': "loading {label}'s conversation…";
|
|
91
|
+
readonly 'attach.status': "subagent {label} · {id} · {turns} turns";
|
|
92
|
+
readonly 'notice.attachUnavailable': "subagent attachment is unavailable in this profile";
|
|
59
93
|
readonly 'document.compact': "transcript · esc close";
|
|
60
|
-
readonly 'document.
|
|
94
|
+
readonly 'document.expanded': "expanded";
|
|
95
|
+
readonly 'document.refreshHint': "r refresh";
|
|
96
|
+
readonly 'document.footerExpanded': "lines {from}-{to}/{total} · ↑↓/pg/g/G{refresh} · esc/ctrl+d back";
|
|
97
|
+
readonly 'document.footer': "lines {from}-{to}/{total} · ↑↓/pg/g/G · enter/f expand · t/esc close";
|
|
61
98
|
readonly 'review.picker.title': "/review · choose a target";
|
|
62
99
|
readonly 'review.picker.uncommitted': "Review uncommitted changes (staged / unstaged / new files)";
|
|
63
100
|
readonly 'review.picker.branch': "Compare against a base branch (lists local branches)";
|
|
@@ -197,10 +234,16 @@ export declare const en: {
|
|
|
197
234
|
readonly 'status.label.out': "out";
|
|
198
235
|
readonly 'status.label.mode': "/mode";
|
|
199
236
|
readonly 'status.label.context': "context";
|
|
237
|
+
readonly 'status.label.sandbox': "sandbox";
|
|
238
|
+
readonly 'status.plan.on': "plan on";
|
|
239
|
+
readonly 'status.plan.mark': "⧉ plan";
|
|
240
|
+
readonly 'status.goal.round': "◎ round {current}/{max}";
|
|
241
|
+
readonly 'status.goal.phase': "◎ {phase}";
|
|
200
242
|
readonly 'frozen.keysGoTo': "keys go to {owner} · esc {action}";
|
|
201
243
|
readonly 'frozen.action.rejects': "rejects";
|
|
202
244
|
readonly 'frozen.action.cancels': "cancels";
|
|
203
245
|
readonly 'frozen.action.closes': "closes";
|
|
246
|
+
readonly 'frozen.action.waits': "waits";
|
|
204
247
|
readonly 'time.justNow': "now";
|
|
205
248
|
readonly 'time.minutesAgo': "{n}m ago";
|
|
206
249
|
readonly 'time.hoursAgo': "{n}h ago";
|
|
@@ -212,6 +255,7 @@ export declare const en: {
|
|
|
212
255
|
readonly 'notice.themeSaveFailed': "theme save failed: {message}";
|
|
213
256
|
readonly 'notice.languageSaveFailed': "language save failed: {message}";
|
|
214
257
|
readonly 'notice.alreadyActive': "that session is already active";
|
|
258
|
+
readonly 'notice.permissionPresetsUnmounted': "permission presets are not mounted in this composition";
|
|
215
259
|
readonly 'notice.queueCancelled': "queued message cancelled";
|
|
216
260
|
readonly 'notice.queueActionFailed': "queue action failed: {message}";
|
|
217
261
|
readonly 'notice.queueUnavailable': "queued message is no longer pending";
|
|
@@ -226,6 +270,8 @@ export declare const en: {
|
|
|
226
270
|
readonly 'notice.usage.animation': "usage: /animation [on|off]";
|
|
227
271
|
readonly 'notice.usage.language': "usage: /language [en|zh]";
|
|
228
272
|
readonly 'notice.usage.rainbow': "usage: /rainbow [seed]";
|
|
273
|
+
readonly 'notice.usage.bareCommand': "usage: /{name}";
|
|
274
|
+
readonly 'notice.switchInProgress': "switching sessions — send again once the new session is up, or /resume cancel";
|
|
229
275
|
readonly 'notice.imageCancelled': "image submission cancelled";
|
|
230
276
|
readonly 'notice.themeConfigUnreadable': "theme config unreadable, using dark: {message}";
|
|
231
277
|
readonly 'notice.languageConfigUnreadable': "language config unreadable, using english: {message}";
|
|
@@ -256,6 +302,13 @@ export declare const en: {
|
|
|
256
302
|
readonly 'notice.resumeFailed': "resume failed: {message}";
|
|
257
303
|
readonly 'notice.forkFailed': "fork failed: {message}";
|
|
258
304
|
readonly 'notice.sessionSwitchFailed': "session switch failed: {message}";
|
|
305
|
+
readonly 'notice.sessionCreated': "created {id} · mode {mode}";
|
|
306
|
+
readonly 'notice.sessionResumed': "resumed {id} · mode {mode}";
|
|
307
|
+
readonly 'notice.sessionSwitchedDirty': "switched to {id}, but {detail}";
|
|
308
|
+
readonly 'notice.flushFailed': "previous session flush failed: {message}";
|
|
309
|
+
readonly 'notice.agentReleaseFailed': "previous agent release failed: {message}";
|
|
310
|
+
readonly 'notice.copyEmpty': "nothing to copy yet";
|
|
311
|
+
readonly 'notice.copied': "copied latest response";
|
|
259
312
|
readonly 'notice.switchQueued': "will switch to {label} when the current turn finishes · /resume cancel to abort";
|
|
260
313
|
readonly 'notice.reviewStarted': "review started under read-only permissions";
|
|
261
314
|
readonly 'notice.reviewFailed': "review failed: {message}";
|
|
@@ -307,7 +360,8 @@ export declare const en: {
|
|
|
307
360
|
readonly 'panel.footer.chooseSelect': "↑↓ choose · enter select · r refresh · esc close";
|
|
308
361
|
readonly 'panel.footer.inspectDetails': "↑↓ inspect · enter details · r refresh · esc close";
|
|
309
362
|
readonly 'panel.footer.inspectRefresh': "↑↓ inspect · r refresh · esc close";
|
|
310
|
-
readonly 'panel.footer.resume': "tab/←→ filters · ↑↓/pg navigate · ctrl+f search · e details · t transcript ·
|
|
363
|
+
readonly 'panel.footer.resume': "tab/←→ filters · ↑↓/pg navigate · ctrl+f search · e details · t transcript · enter resume";
|
|
364
|
+
readonly 'panel.footer.delete': "tab/←→ filters · ↑↓/pg navigate · ctrl+f search · e details · t transcript · enter delete · esc close";
|
|
311
365
|
readonly 'panel.footer.transcript': "lines {from}-{to}/{total} · ↑↓/pg/g/G · t/esc close";
|
|
312
366
|
readonly 'panel.footer.history': "↑↓ move · g/G ends · enter fill · esc close";
|
|
313
367
|
readonly 'panel.footer.review': "↑↓ move · enter select · esc back · q close";
|
|
@@ -319,6 +373,7 @@ export declare const en: {
|
|
|
319
373
|
readonly 'panel.jobs.title': "/jobs · background tasks · {count}";
|
|
320
374
|
readonly 'panel.resume.deleteTitle': "permanently delete {target}? this cannot be undone · subagent threads go too";
|
|
321
375
|
readonly 'panel.resume.title': "/resume{mode}{search} · {toolbar}";
|
|
376
|
+
readonly 'panel.delete.title': "/delete{search} · {toolbar}";
|
|
322
377
|
readonly 'panel.noActiveReminders': "no active reminders — the model schedules via schedule_create";
|
|
323
378
|
readonly 'panel.notMounted': "not mounted";
|
|
324
379
|
readonly 'panel.broken': "broken: {message}";
|
|
@@ -369,7 +424,6 @@ export declare const en: {
|
|
|
369
424
|
readonly 'panel.provider.notConfiguredDivider': "── not configured ──";
|
|
370
425
|
readonly 'panel.provider.title': "/model — providers";
|
|
371
426
|
readonly 'panel.provider.titleCount': "/model — providers · {index}/{total}";
|
|
372
|
-
readonly 'panel.provider.state': "{route} · {value}";
|
|
373
427
|
readonly 'panel.provider.key': "key {value}";
|
|
374
428
|
readonly 'panel.provider.authConfigured': "provider auth";
|
|
375
429
|
readonly 'panel.provider.noKey': "key missing";
|
|
@@ -384,7 +438,7 @@ export declare const en: {
|
|
|
384
438
|
readonly 'panel.provider.readOnlyLogin': "this login record is read-only";
|
|
385
439
|
readonly 'panel.provider.notManaged': "this provider is not managed by Harness settings";
|
|
386
440
|
readonly 'panel.providers.compact': "/model providers · enter configure · d remove key · esc back";
|
|
387
|
-
readonly 'panel.providers.footer': "↑↓ move · enter configure ·
|
|
441
|
+
readonly 'panel.providers.footer': "↑↓ move · enter configure · d remove key · x remove provider · r retry · esc back";
|
|
388
442
|
readonly 'panel.update.compact': "/update · {summary}";
|
|
389
443
|
readonly 'panel.update.checking': "checking…";
|
|
390
444
|
readonly 'panel.update.probeFailed': "probe failed";
|
|
@@ -412,8 +466,14 @@ export declare const en: {
|
|
|
412
466
|
readonly 'panel.setup.copyInto': "copy verbatim into {id}";
|
|
413
467
|
readonly 'panel.setup.copyTitle': "/model — copy efforts";
|
|
414
468
|
readonly 'panel.setup.copyFooter': "↑↓ move · enter copy · esc back";
|
|
469
|
+
readonly 'panel.setup.mode.subscribe': "Subscription";
|
|
470
|
+
readonly 'panel.setup.mode.key': "Key";
|
|
471
|
+
readonly 'panel.setup.mode.login.plan': "signed in · plan";
|
|
472
|
+
readonly 'panel.setup.mode.login.none': "not signed in";
|
|
473
|
+
readonly 'panel.setup.mode.login.running': "signing in…";
|
|
474
|
+
readonly 'panel.setup.mode.overridden': "⚠ the settings key overrides the plan sign-in";
|
|
415
475
|
readonly 'panel.setup.title': "/model — configure {provider}";
|
|
416
|
-
readonly 'panel.setup.footer': "↑↓ move · ←→ in/out · space remove · e efforts · c copy efforts · tab discover · enter save · esc back";
|
|
476
|
+
readonly 'panel.setup.footer': "↑↓ move · ←→ in/out · space remove · e efforts · c copy efforts · tab per channel (subscription = web sign-in, key = discover) · enter save · esc back";
|
|
417
477
|
readonly 'panel.discovery.compact': "model discovery · terminal too small · esc back";
|
|
418
478
|
readonly 'panel.discovery.loading': "discovering models…";
|
|
419
479
|
readonly 'panel.discovery.empty': "the endpoint advertised no models; add ids by hand on the setup page";
|
|
@@ -2,9 +2,14 @@
|
|
|
2
2
|
import { type ReactElement } from 'react';
|
|
3
3
|
import { type AuthorizationInteraction, type AuthorizationStatus } from '@deepseek-ai/dsh-authorization';
|
|
4
4
|
import type { CredentialKey } from '@deepseek-ai/dsh-credentials';
|
|
5
|
-
import type { ProviderAuthorizationRow } from '
|
|
5
|
+
import type { ProviderAuthorizationRow } from '../authorization.ts';
|
|
6
6
|
export interface ProviderAuthorizationPanelProps {
|
|
7
7
|
readonly row: ProviderAuthorizationRow;
|
|
8
|
+
/**
|
|
9
|
+
* Start this method immediately instead of showing the picker: a
|
|
10
|
+
* single-method provider signs in with no extra step.
|
|
11
|
+
*/
|
|
12
|
+
readonly autoStartMethod?: string;
|
|
8
13
|
begin(row: ProviderAuthorizationRow, method: string, interaction: AuthorizationInteraction, signal: AbortSignal): Promise<AuthorizationStatus>;
|
|
9
14
|
cancel(key: CredentialKey): void;
|
|
10
15
|
openUrl(url: string): boolean;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Bounded slash-command and mention completion menu. */
|
|
2
|
+
import { type ReactElement } from 'react';
|
|
3
|
+
import type { CompletionCandidate } from '../completion.ts';
|
|
4
|
+
/** Total physical rows occupied by the completion menu at this terminal height. */
|
|
5
|
+
export declare function completionMenuRowCount(terminalRows: number, rowCount: number): number;
|
|
6
|
+
/** Completion view anchored directly above the composer band. */
|
|
7
|
+
export declare function CompletionMenu({ active, mention, index, rows, error }: {
|
|
8
|
+
active: boolean;
|
|
9
|
+
mention: boolean;
|
|
10
|
+
index: number;
|
|
11
|
+
rows: readonly CompletionCandidate[];
|
|
12
|
+
error?: string;
|
|
13
|
+
}): ReactElement | undefined;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Approval and structured-question keyboard-owned terminal surfaces. */
|
|
2
|
+
import { type ReactElement } from 'react';
|
|
3
|
+
import type { ApprovalSnapshot } from '../approval.ts';
|
|
4
|
+
import type { QuestionSnapshot, QuestionStore } from '../questions.ts';
|
|
5
|
+
import type { NoticeTone } from '../ui/ui-contract.ts';
|
|
6
|
+
/**
|
|
7
|
+
* The approval dialog (Codex ApprovalOverlay contract): a bold question
|
|
8
|
+
* header, the bounded command body with an explicit overflow marker, a
|
|
9
|
+
* numbered option list with a `›` cursor, single-key shortcuts, and digits
|
|
10
|
+
* for direct selection. Askers queue FIFO — the count rides the header.
|
|
11
|
+
* The upstream answerer vocabulary stays binary (`allowed-once` /
|
|
12
|
+
* `rejected`): "tell it what to do differently" rejects and hands the
|
|
13
|
+
* composer back with a hint notice, exactly Codex's decline-then-type flow.
|
|
14
|
+
*/
|
|
15
|
+
export declare function ApprovalBar({ snapshot, locked, notify, interrupt, summarize }: {
|
|
16
|
+
snapshot: ApprovalSnapshot;
|
|
17
|
+
locked: boolean;
|
|
18
|
+
notify: (text: string, tone?: NoticeTone) => void;
|
|
19
|
+
/** Cancel the running turn (Ctrl+C), matching the composer's busy branch. */
|
|
20
|
+
interrupt: () => boolean;
|
|
21
|
+
/** Render as the bounded one-line form even on tall terminals (another
|
|
22
|
+
* human-asked surface already owns the full panel budget). */
|
|
23
|
+
summarize?: boolean;
|
|
24
|
+
}): ReactElement | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* The ask_user_question bar: walks one request question by question,
|
|
27
|
+
* retaining an independent draft for every question. Options use Space/1-9
|
|
28
|
+
* to toggle a multi-select, Enter to confirm, and arrows/Ctrl+P/N to move
|
|
29
|
+
* between questions. Plan reviews arrive through the same service with a
|
|
30
|
+
* `plan-review` intent — the approve option gets a ✓ mark, the answer
|
|
31
|
+
* encoding stays identical.
|
|
32
|
+
*/
|
|
33
|
+
export declare function QuestionBar({ store, snapshot, locked }: {
|
|
34
|
+
store: QuestionStore;
|
|
35
|
+
snapshot: QuestionSnapshot;
|
|
36
|
+
locked: boolean;
|
|
37
|
+
}): ReactElement | undefined;
|
|
38
|
+
/** The /model panel: a scrolling list over the advisory model directory. */
|
|
@@ -1,24 +1,18 @@
|
|
|
1
1
|
/** Bounded, composer-safe panels for preset, session, and plugin kernel views. */
|
|
2
2
|
import { type ReactElement } from 'react';
|
|
3
|
-
import type { ModelDirectory, ModelRow } from '
|
|
4
|
-
import type { SubagentRow } from '
|
|
5
|
-
import type {
|
|
6
|
-
|
|
7
|
-
import type {
|
|
8
|
-
import type {
|
|
9
|
-
import type {
|
|
10
|
-
import type {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
* markers are stripped and control-laden chunks are ignored.
|
|
17
|
-
*/
|
|
18
|
-
export declare function editQuery(query: string, input: string, key: {
|
|
19
|
-
backspace?: boolean;
|
|
20
|
-
delete?: boolean;
|
|
21
|
-
}): string | undefined;
|
|
3
|
+
import type { ModelDirectory, ModelRow } from '../models.ts';
|
|
4
|
+
import type { SubagentRow } from '../session/subagents.ts';
|
|
5
|
+
import type { SearchRow } from '../runner/search-rows.ts';
|
|
6
|
+
export type { SearchRow } from '../runner/search-rows.ts';
|
|
7
|
+
import type { ScheduleRow } from '../render/projection.ts';
|
|
8
|
+
import type { PermissionRow } from '../permissions.ts';
|
|
9
|
+
import type { PresetRow } from '../presets.ts';
|
|
10
|
+
import type { PluginRow } from '../plugin-inventory.ts';
|
|
11
|
+
import type { SessionDirectoryOptions, SessionRow } from '../session/session-directory.ts';
|
|
12
|
+
import type { ReviewBranch, ReviewCommit, ReviewSelection } from '../git-workflow.ts';
|
|
13
|
+
import { type UsageView } from '../render/usage.ts';
|
|
14
|
+
import { type StatusItemId } from '../render/status.ts';
|
|
15
|
+
export { editQuery } from '../ui/query-editor.ts';
|
|
22
16
|
export declare function ModePanel({ current, load, select, close }: {
|
|
23
17
|
current: string;
|
|
24
18
|
load: () => Promise<readonly PresetRow[]>;
|
|
@@ -66,7 +60,7 @@ export declare function JobsPanel({ load, close }: {
|
|
|
66
60
|
load: () => readonly JobRow[];
|
|
67
61
|
close: () => void;
|
|
68
62
|
}): ReactElement;
|
|
69
|
-
export declare function ResumePanel({ currentCwd, load, readTranscript, select, requestDelete, deleteConfirmId, reloadToken, deleteMode, close }: {
|
|
63
|
+
export declare function ResumePanel({ currentCwd, load, readTranscript, select, requestDelete, deleteConfirmId, reloadToken, deleteMode, presetId, close }: {
|
|
70
64
|
currentCwd: string;
|
|
71
65
|
load: (options: SessionDirectoryOptions, signal?: AbortSignal) => Promise<readonly SessionRow[]>;
|
|
72
66
|
readTranscript: (id: string, signal?: AbortSignal) => Promise<string>;
|
|
@@ -79,6 +73,8 @@ export declare function ResumePanel({ currentCwd, load, readTranscript, select,
|
|
|
79
73
|
reloadToken?: number;
|
|
80
74
|
/** Opened via /delete: hint-first delete mode. */
|
|
81
75
|
deleteMode?: boolean;
|
|
76
|
+
/** `/delete <id>` argument to resolve after the listing loads. */
|
|
77
|
+
presetId?: string;
|
|
82
78
|
close: () => void;
|
|
83
79
|
}): ReactElement;
|
|
84
80
|
/**
|
|
@@ -108,23 +104,6 @@ export declare function ReviewPickerPanel({ loadBranches, loadCommits, choose, c
|
|
|
108
104
|
choose: (selection: ReviewSelection) => void;
|
|
109
105
|
close: () => void;
|
|
110
106
|
}): ReactElement;
|
|
111
|
-
/** One cross-session full-text search hit mapped from the session-query engine. */
|
|
112
|
-
export interface SearchRow {
|
|
113
|
-
/** Session id (Enter resumes it through the switch machinery). */
|
|
114
|
-
readonly id: string;
|
|
115
|
-
/** Display label: session title or the short id form. */
|
|
116
|
-
readonly label: string;
|
|
117
|
-
/** Secondary facts line (workspace · preset markers). */
|
|
118
|
-
readonly detail: string;
|
|
119
|
-
/** Bounded plain-text excerpt around the strongest match. */
|
|
120
|
-
readonly snippet: string;
|
|
121
|
-
/** Match timestamp (relative labels derive from it). */
|
|
122
|
-
readonly updatedAt: number;
|
|
123
|
-
/** Whether the hit is a delegated subagent conversation (not resumable). */
|
|
124
|
-
readonly subagent: boolean;
|
|
125
|
-
/** Whether Enter may switch into it. */
|
|
126
|
-
readonly resumable: boolean;
|
|
127
|
-
}
|
|
128
107
|
/**
|
|
129
108
|
* The /search panel: full-text search over every persisted session through
|
|
130
109
|
* the in-process session-query engine (the same corpus the model's
|
|
@@ -180,13 +159,15 @@ export declare function EffortPanel({ row, current, select, back, onExit }: {
|
|
|
180
159
|
* Enter/t opening the child's full transcript in the shared read-only
|
|
181
160
|
* document view (the same projection the exporter uses).
|
|
182
161
|
*/
|
|
183
|
-
export declare function AgentsPanel({ live, load, readTranscript, close }: {
|
|
162
|
+
export declare function AgentsPanel({ live, load, readTranscript, attach, close }: {
|
|
184
163
|
/** Live feed rows (child sessions observed this process). */
|
|
185
164
|
live: readonly SubagentRow[];
|
|
186
165
|
/** Load this session's persisted child sessions by lineage. */
|
|
187
166
|
load: () => Promise<readonly SessionRow[]>;
|
|
188
167
|
/** Read one child session's full transcript as markdown. */
|
|
189
168
|
readTranscript: (id: string, signal?: AbortSignal) => Promise<string>;
|
|
169
|
+
/** Attach to one child as the whole view (the runner's live buses). */
|
|
170
|
+
attach: ((id: string, label: string) => void) | undefined;
|
|
190
171
|
close: () => void;
|
|
191
172
|
}): ReactElement;
|
|
192
173
|
/**
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* repainting the whole screen so Static-region text switches too).
|
|
5
5
|
*/
|
|
6
6
|
import { type ReactElement } from 'react';
|
|
7
|
-
import { type LanguageName } from '
|
|
7
|
+
import { type LanguageName } from '../i18n.ts';
|
|
8
8
|
export declare function LanguagePanel({ current, select, close }: {
|
|
9
9
|
current: LanguageName;
|
|
10
10
|
select: (name: LanguageName) => void;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/** Model selection and provider-management panels for the terminal app. */
|
|
2
|
+
import { type ReactElement } from 'react';
|
|
3
|
+
import type { ModelDirectory, ModelRow } from '../models.ts';
|
|
4
|
+
import { type DiscoveredModelView, type ProviderConfiguration, type ProviderSettingsDirectory, type ProviderTargetView } from '../provider-settings.ts';
|
|
5
|
+
import { type ProviderAuthorizationDirectory, type ProviderAuthorizationRow } from '../authorization.ts';
|
|
6
|
+
export declare function ModelPanel({ directory, error, current, onSelect, onProviders, onRetry, onClose }: {
|
|
7
|
+
directory: ModelDirectory | undefined;
|
|
8
|
+
error: string | undefined;
|
|
9
|
+
/** `provider/model` label of the applied model: the cursor lands on it once. */
|
|
10
|
+
current?: string;
|
|
11
|
+
onSelect: (row: ModelRow) => void;
|
|
12
|
+
onProviders?: () => void;
|
|
13
|
+
onRetry: () => void;
|
|
14
|
+
onClose: () => void;
|
|
15
|
+
}): ReactElement;
|
|
16
|
+
/** The provider-management stage reached from /model with `a`. */
|
|
17
|
+
export declare function ProviderPanel({ directory, error, authorizations, authorizationError, onConfigure, onUnset, onRemove, onRetry, onBack, onExit }: {
|
|
18
|
+
directory: ProviderSettingsDirectory | undefined;
|
|
19
|
+
error: string | undefined;
|
|
20
|
+
authorizations: ProviderAuthorizationDirectory | undefined;
|
|
21
|
+
authorizationError: string | undefined;
|
|
22
|
+
onConfigure: (target: ProviderTargetView) => void;
|
|
23
|
+
onUnset: (target: ProviderTargetView) => void;
|
|
24
|
+
onRemove: (target: ProviderTargetView) => void;
|
|
25
|
+
onRetry: () => void;
|
|
26
|
+
onBack: () => void;
|
|
27
|
+
/** Leave the whole /model flow (Ctrl+C), not just this stage. */
|
|
28
|
+
onExit: () => void;
|
|
29
|
+
}): ReactElement;
|
|
30
|
+
/** Provider configuration editor: only explicit models are written to settings. */
|
|
31
|
+
/**
|
|
32
|
+
* The unified provider setup page: API key, endpoint, and the explicit model
|
|
33
|
+
* list (with per-model context/output capacities) on ONE screen — the deep
|
|
34
|
+
* Tab menu and the separate key panel merged into a single discoverable
|
|
35
|
+
* surface. A saved key rides the same Enter as the endpoint and models; an
|
|
36
|
+
* empty endpoint keeps the provider's official default. Tab moves to the
|
|
37
|
+
* discovery page, which interrogates the real endpoint and returns checkable
|
|
38
|
+
* models for adoption; the last row also accepts hand-typed model ids.
|
|
39
|
+
*/
|
|
40
|
+
/** One declarable donor the setup page can copy reasoning efforts from verbatim. */
|
|
41
|
+
export interface EffortDonor {
|
|
42
|
+
/** Provider route the declaration lives on. */
|
|
43
|
+
readonly provider: string;
|
|
44
|
+
/** Model id the declaration belongs to. */
|
|
45
|
+
readonly id: string;
|
|
46
|
+
/** The stored display-level to wire-value map, copied verbatim. */
|
|
47
|
+
readonly efforts: Record<string, string | null>;
|
|
48
|
+
}
|
|
49
|
+
export declare function ProviderSetupPanel({ target, authorization, onSubscribe, save, saveCredential, discover, effortDonors, done, back, onExit }: {
|
|
50
|
+
target: ProviderTargetView;
|
|
51
|
+
/**
|
|
52
|
+
* The provider's sign-in flow, when it offers a web (OAuth) channel: its
|
|
53
|
+
* presence adds the subscription/key mode layer at the top of the page.
|
|
54
|
+
*/
|
|
55
|
+
authorization: ProviderAuthorizationRow | undefined;
|
|
56
|
+
/** Open the subscription channel: sign in when logged out, confirm sign-out when logged in. */
|
|
57
|
+
onSubscribe: (() => void) | undefined;
|
|
58
|
+
/** Models with declared efforts (settings first, catalog-advertised after) a model row can copy from. */
|
|
59
|
+
effortDonors: readonly EffortDonor[];
|
|
60
|
+
save: (target: ProviderTargetView, configuration: ProviderConfiguration) => Promise<void>;
|
|
61
|
+
saveCredential: ((target: ProviderTargetView, key: string) => Promise<void>) | undefined;
|
|
62
|
+
discover: (target: ProviderTargetView, request: {
|
|
63
|
+
readonly apiKey?: string;
|
|
64
|
+
readonly baseURL?: string;
|
|
65
|
+
}, signal?: AbortSignal) => Promise<readonly DiscoveredModelView[]>;
|
|
66
|
+
/** Report a successful save so the surface can notice the key rotation. */
|
|
67
|
+
done: (result: {
|
|
68
|
+
readonly key: boolean;
|
|
69
|
+
}) => void;
|
|
70
|
+
back: () => void;
|
|
71
|
+
/** Leave the whole /model flow (Ctrl+C), not just this page. */
|
|
72
|
+
onExit: () => void;
|
|
73
|
+
}): ReactElement;
|
|
74
|
+
/** Bounded destructive-action confirmation for credential or provider removal. */
|
|
75
|
+
export declare function ProviderConfirmPanel({ target, kind, confirm, done, back }: {
|
|
76
|
+
target: ProviderTargetView;
|
|
77
|
+
kind: 'credential' | 'provider';
|
|
78
|
+
confirm: (target: ProviderTargetView) => Promise<void>;
|
|
79
|
+
done: () => void;
|
|
80
|
+
back: () => void;
|
|
81
|
+
}): ReactElement;
|
|
82
|
+
/**
|
|
83
|
+
* The /help overlay: one scrolling card with the keyboard map, the TUI-local
|
|
84
|
+
* commands, the live registry commands, and the user-invocable skills — the
|
|
85
|
+
* real command surface, replacing the one-line notice.
|
|
86
|
+
*/
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @module @deepseek-ai/dsh-tui/theme-panel
|
|
8
8
|
*/
|
|
9
9
|
import { type ReactElement } from 'react';
|
|
10
|
-
import { type ThemeName } from '
|
|
10
|
+
import { type ThemeName } from '../theme.ts';
|
|
11
11
|
/**
|
|
12
12
|
* The /theme list: one row per theme, the current one marked with ●, the
|
|
13
13
|
* focused one with ›. Enter applies the focused theme (the runner persists
|
|
@@ -9,11 +9,31 @@
|
|
|
9
9
|
* here.
|
|
10
10
|
*/
|
|
11
11
|
import { type ReactElement } from 'react';
|
|
12
|
-
import type { LauncherUpdateStatus } from '
|
|
12
|
+
import type { LauncherUpdatePlan, LauncherUpdateStatus } from '../update.ts';
|
|
13
13
|
/** Retained apply-progress lines (ring tail; npm output is ephemeral). */
|
|
14
14
|
export declare const UPDATE_OUTPUT_CAP = 800;
|
|
15
15
|
/** Keep the newest UPDATE_OUTPUT_CAP lines of streamed update output. */
|
|
16
16
|
export declare function clipUpdateLines(lines: readonly string[]): readonly string[];
|
|
17
|
+
/** One in-flight `update --apply`. Closing the panel must not start a second. */
|
|
18
|
+
interface UpdateApplyJob {
|
|
19
|
+
readonly promise: Promise<number>;
|
|
20
|
+
readonly lines: string[];
|
|
21
|
+
readonly lineListeners: Set<(line: string) => void>;
|
|
22
|
+
}
|
|
23
|
+
/** True while an apply child is alive, even if the /update panel is closed. */
|
|
24
|
+
export declare function isUpdateApplyRunning(): boolean;
|
|
25
|
+
/** Subscribe to apply-running changes (frozen-hint "esc waits"). */
|
|
26
|
+
export declare function subscribeUpdateApplyRunning(listener: (running: boolean) => void): () => void;
|
|
27
|
+
/** The live apply job, if any: lines already streamed plus the shared promise. */
|
|
28
|
+
export declare function currentUpdateApply(): UpdateApplyJob | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Run `apply` once. A second call while the child is alive reuses the same
|
|
31
|
+
* promise and replays buffered lines — closing /update and opening it again
|
|
32
|
+
* must not spawn a second `npm install`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function runUpdateApply(apply: (onLine: (line: string) => void, plan: LauncherUpdatePlan) => Promise<number>, plan: LauncherUpdatePlan, onLine?: (line: string) => void): Promise<number>;
|
|
35
|
+
/** Drop a leftover job between tests. */
|
|
36
|
+
export declare function resetUpdateApply(): void;
|
|
17
37
|
/** One display row of the update surface. */
|
|
18
38
|
export interface UpdateRow {
|
|
19
39
|
readonly key: string;
|
|
@@ -47,3 +67,4 @@ export declare function UpdatePanel({ probe, apply, close, notify }: {
|
|
|
47
67
|
/** One bounded cross-surface notice (phase completions). */
|
|
48
68
|
notify: (text: string, tone?: 'info' | 'warning' | 'error') => void;
|
|
49
69
|
}): ReactElement;
|
|
70
|
+
export {};
|
|
@@ -197,6 +197,17 @@ export declare function loadProviderSettings(ctx: Context): Promise<ProviderSett
|
|
|
197
197
|
export declare function saveProviderCredential(ctx: Context, target: ProviderTargetView, rawKey: string): Promise<void>;
|
|
198
198
|
/** Save the endpoint and an explicit model allow-list without rebuilding the profile. */
|
|
199
199
|
export declare function saveProviderConfiguration(ctx: Context, target: ProviderTargetView, configuration: ProviderConfiguration): Promise<void>;
|
|
200
|
+
/**
|
|
201
|
+
* Switch one provider route to its subscription (plan sign-in) channel: the
|
|
202
|
+
* profile keeps neither a key reference nor an explicit model list, so the
|
|
203
|
+
* official catalog endpoint serves requests and the stored OAuth record — not
|
|
204
|
+
* a settings-named key override — authenticates them. Enabling a route that
|
|
205
|
+
* has no profile yet creates the empty profile that registers it.
|
|
206
|
+
* @param ctx - context carrying the `settings` service.
|
|
207
|
+
* @param target - provider row whose settings namespace owns the profile.
|
|
208
|
+
* @throws when the route is unmanaged or settings are read-only.
|
|
209
|
+
*/
|
|
210
|
+
export declare function enableProviderSubscription(ctx: Context, target: ProviderTargetView): Promise<void>;
|
|
200
211
|
/**
|
|
201
212
|
* Interrogate a provider endpoint for the models it really serves, through
|
|
202
213
|
* the model-discovery capability the provider's settings namespace
|
|
@@ -48,6 +48,14 @@ export declare function liveRegionBudget(chrome: LiveRegionChrome): number;
|
|
|
48
48
|
* accumulated `<Static>` output on every frame.
|
|
49
49
|
*/
|
|
50
50
|
export declare function panelViewport(columns: number, rows: number): InspectorViewport;
|
|
51
|
+
/**
|
|
52
|
+
* Viewport for an expanded (near-fullscreen) document overlay: the document
|
|
53
|
+
* replaces the transcript area entirely, so the half-screen overlay cap and
|
|
54
|
+
* the inter-section gaps drop away while the bottom live region (composer,
|
|
55
|
+
* status) and the Static-rewrite margin stay reserved. The result stays
|
|
56
|
+
* below terminal height, which is what keeps Ink off its full-rewrite path.
|
|
57
|
+
*/
|
|
58
|
+
export declare function expandedDocumentViewport(columns: number, rows: number): InspectorViewport;
|
|
51
59
|
/** Backward-compatible name for the Ctrl+O-specific caller and tests. */
|
|
52
60
|
export declare function inspectorViewport(columns: number, rows: number): InspectorViewport;
|
|
53
61
|
/** Clamp a first-visible row to the range representable by one viewport. */
|
|
@@ -119,6 +119,8 @@ export interface StatusItemInfo {
|
|
|
119
119
|
}
|
|
120
120
|
/** The full item catalog in canonical order (the /statusline default). */
|
|
121
121
|
export declare const STATUS_ITEMS: readonly StatusItemInfo[];
|
|
122
|
+
/** Picker rows with labels/descriptions in the active interface language. */
|
|
123
|
+
export declare function localizedStatusItems(): readonly StatusItemInfo[];
|
|
122
124
|
/**
|
|
123
125
|
* Default order: the whole catalog (matches the pre-customization bar).
|
|
124
126
|
* The busy dot is not an item — it always leads the identity cluster.
|
|
@@ -178,7 +180,8 @@ export declare function permissionTone(permission: string): StatusTone;
|
|
|
178
180
|
/**
|
|
179
181
|
* Compose the two-row footer layout under a column budget. Row 1 keeps model,
|
|
180
182
|
* cwd, mode, branch, context, then the right-pinned permission badge and cycle
|
|
181
|
-
* hint. It
|
|
183
|
+
* hint. It shrinks the context bar, drops the hint, and peels trailing
|
|
184
|
+
* identity facts before removing the context group or the permission badge.
|
|
182
185
|
* Row 2 fits all secondary figures and state within its own budget.
|
|
183
186
|
* @param facts - identity facts resolved by the runner.
|
|
184
187
|
* @param stats - session figures folded from the durable log.
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
*
|
|
12
12
|
* @module @deepseek-ai/dsh-code/render/text
|
|
13
13
|
*/
|
|
14
|
+
import { stringWidth } from './width.ts';
|
|
15
|
+
export { stringWidth };
|
|
14
16
|
/**
|
|
15
17
|
* Compact token count: exact below 1K, then one-decimal-ish K/M.
|
|
16
18
|
* @param n - token count.
|
|
@@ -35,6 +37,8 @@ export declare function singleLineText(text: string): string;
|
|
|
35
37
|
* combining sequences never split mid-cluster.
|
|
36
38
|
*/
|
|
37
39
|
export declare function truncateColumns(text: string, columns: number): string;
|
|
40
|
+
/** Sanitize, clip, and right-pad one cell to an exact terminal-column width. */
|
|
41
|
+
export declare function padColumns(text: string, columns: number): string;
|
|
38
42
|
/** A display-safe suffix bounded by terminal rows and columns. */
|
|
39
43
|
export interface DisplayTail {
|
|
40
44
|
/** Sanitized suffix suitable for direct terminal rendering. */
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load-time DeepSeek Harness version gate.
|
|
3
|
+
*
|
|
4
|
+
* The terminal driver is validated against exactly one Harness snapshot, and
|
|
5
|
+
* the host resolves every bare `@deepseek-ai/*` import the plugin makes
|
|
6
|
+
* against ITS OWN installed copies (the profile's `HostResolvedRootInclude`
|
|
7
|
+
* redirects bare names to the installed-host base). No install-time or
|
|
8
|
+
* load-time check exists anywhere on that path, so a user who updates `dsh`
|
|
9
|
+
* would otherwise run this build against unvetted upstream code silently.
|
|
10
|
+
*
|
|
11
|
+
* This gate mirrors how the host itself reads its identity: the running CLI
|
|
12
|
+
* entry (`process.argv[1]`) sits inside the `@deepseek-ai/dsh` package, whose
|
|
13
|
+
* manifest version is released in lockstep with the Harness packages bundled
|
|
14
|
+
* beside it. When the probe can identify the host it compares the running
|
|
15
|
+
* versions against the one this build declares and fails fast with an
|
|
16
|
+
* actionable message; when it cannot identify the host it stays silent rather
|
|
17
|
+
* than brick a supported embedding on a false positive.
|
|
18
|
+
*
|
|
19
|
+
* @module @deepseek-ai/dsh-code/runner/harness-gate
|
|
20
|
+
*/
|
|
21
|
+
/** The one Harness release this build was validated against. */
|
|
22
|
+
export declare const EXPECTED_HARNESS_VERSION = "0.1.5-rc.2";
|
|
23
|
+
/** Host packages whose bundled copy the plugin binds to at runtime. */
|
|
24
|
+
export declare const HARNESS_GATE_PACKAGES: readonly ["@deepseek-ai/dsh-agent", "@deepseek-ai/dsh-session"];
|
|
25
|
+
/** Filesystem slice the probe needs; injectable so tests stay pure. */
|
|
26
|
+
export interface HarnessFs {
|
|
27
|
+
/** Resolve a symlinked entry to its real path. */
|
|
28
|
+
realpathSync(path: string): string;
|
|
29
|
+
/** Read and parse one package.json; undefined when absent or unreadable. */
|
|
30
|
+
readManifest(path: string): {
|
|
31
|
+
name?: unknown;
|
|
32
|
+
version?: unknown;
|
|
33
|
+
} | undefined;
|
|
34
|
+
}
|
|
35
|
+
/** What the probe learned about the running host. */
|
|
36
|
+
export interface HarnessProbe {
|
|
37
|
+
/** Installed-host package root, when identified. */
|
|
38
|
+
readonly hostRoot?: string;
|
|
39
|
+
/** Installed-host CLI version (`@deepseek-ai/dsh`). */
|
|
40
|
+
readonly hostVersion?: string;
|
|
41
|
+
/** Version of each gate package bundled beside the host, when present. */
|
|
42
|
+
readonly packages: Readonly<Record<string, string | undefined>>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Identify the running host and the Harness versions it provides.
|
|
46
|
+
* @param argv1 - `process.argv[1]`, the running CLI entry path.
|
|
47
|
+
* @param fs - filesystem slice; defaults to the real one.
|
|
48
|
+
* @returns the probe result; `packages` is empty when the host is unknown.
|
|
49
|
+
*/
|
|
50
|
+
export declare function probeRunningHarness(argv1: string | undefined, fs?: HarnessFs): HarnessProbe;
|
|
51
|
+
/** One host fact that disagrees with the version this build declares. */
|
|
52
|
+
export interface HarnessMismatch {
|
|
53
|
+
/** What was compared: the host CLI or one bundled package. */
|
|
54
|
+
readonly source: string;
|
|
55
|
+
/** The version this build was validated against. */
|
|
56
|
+
readonly expected: string;
|
|
57
|
+
/** The version the running host actually provides. */
|
|
58
|
+
readonly provided: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Compare one probe against the expected snapshot. Unknown facts never
|
|
62
|
+
* mismatch: the gate must stay silent when it cannot judge, not brick a
|
|
63
|
+
* supported embedding on missing evidence.
|
|
64
|
+
* @param expected - the Harness version this build declares.
|
|
65
|
+
* @param probe - the running host's identified versions.
|
|
66
|
+
* @returns every concrete disagreement, empty when compatible or unknown.
|
|
67
|
+
*/
|
|
68
|
+
export declare function harnessVersionMismatches(expected: string, probe: HarnessProbe): readonly HarnessMismatch[];
|
|
69
|
+
/**
|
|
70
|
+
* Render the gate failure the user sees on stderr.
|
|
71
|
+
* @param expected - the Harness version this build declares.
|
|
72
|
+
* @param mismatches - the disagreements to report.
|
|
73
|
+
* @param hostRoot - installed-host root, when identified, for the fix hint.
|
|
74
|
+
* @returns the multi-line diagnostic.
|
|
75
|
+
*/
|
|
76
|
+
export declare function harnessGateMessage(expected: string, mismatches: readonly HarnessMismatch[], hostRoot?: string): string;
|
|
77
|
+
/**
|
|
78
|
+
* Refuse to run against an identified-but-incompatible host.
|
|
79
|
+
* @param expected - the Harness version this build declares.
|
|
80
|
+
* @param probe - the running host's identified versions.
|
|
81
|
+
* @throws an Error carrying the gate diagnostic when a version disagrees.
|
|
82
|
+
*/
|
|
83
|
+
export declare function requireHarnessVersion(expected: string, probe: HarnessProbe): void;
|