dsh-ssh-tui 0.1.5 → 0.1.7

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.
@@ -10,17 +10,9 @@ export interface ResumableSession {
10
10
  label: string;
11
11
  updatedAt: number;
12
12
  cwd: string;
13
+ /** Whether the full event log could not be inspected (corrupt/unsupported). */
14
+ unreadable?: boolean;
13
15
  }
14
16
  /** `MM-DD HH:mm` local-time label for session lists. */
15
17
  export declare function formatSessionTime(timestamp: number): string;
16
- /**
17
- * List the most recent resumable top-level sessions, newest first.
18
- *
19
- * Subagent-owned sessions, the current session, and sessions with no user
20
- * input (empty/uuid-only rows) are excluded; the label is the user's first
21
- * input, falling back to the session title and then the id.
22
- * @param persistence - the session persistence service.
23
- * @param currentId - the live session to exclude (empty at launch).
24
- * @returns up to nine candidates in display order, all carrying user input.
25
- */
26
18
  export declare function listResumableSessions(persistence: SessionPersistence, currentId: string): Promise<ResumableSession[]>;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Subagent model defaults and the settings section the TUI edits with
3
+ * `/submodel` and `/subeffort`.
4
+ *
5
+ * The provider is deliberately inherited from the running parent session:
6
+ * the subagent selection only overrides the provider when the user stored an
7
+ * explicit route. The model defaults to the lightweight `deepseek-v4-flash`.
8
+ */
9
+ import z from '@deepseek-ai/schemastery';
10
+ import type { Context } from '@deepseek-ai/cordis';
11
+ import { type ReasoningEffortId as ReasoningEffort } from '@deepseek-ai/dsh-llm';
12
+ /** Settings namespace carrying the TUI's subagent model selection. */
13
+ export declare const SUBAGENT_SETTINGS_NAMESPACE: import("@deepseek-ai/dsh-settings").SettingsNamespace;
14
+ /** Lightweight default model used for subagent children. */
15
+ export declare const DEFAULT_SUBAGENT_MODEL = "deepseek-v4-flash";
16
+ /** Raw settings document shape. */
17
+ export interface SubagentSettings {
18
+ /** Explicit provider override; omitted means "same provider as the parent". */
19
+ provider?: string;
20
+ /** Subagent model id. */
21
+ model?: string;
22
+ /** Adapter-owned reasoning effort id. */
23
+ reasoningEffort?: string;
24
+ }
25
+ /** Live, typed subagent selection. */
26
+ export interface SubagentSelection {
27
+ /** Explicit provider override; undefined inherits the parent route. */
28
+ provider?: string;
29
+ /** Subagent model id. */
30
+ model: string;
31
+ /** Reasoning effort; undefined follows the provider/model default. */
32
+ reasoningEffort?: ReasoningEffort;
33
+ }
34
+ /** Mutable selection handle shared by the settings watcher and the TUI. */
35
+ export interface SubagentSelectionRef {
36
+ current: SubagentSelection;
37
+ }
38
+ /** Settings schema for `$DSH_HOME/settings.yaml`. */
39
+ export declare const SUBAGENT_SETTINGS_SCHEMA: z<Schemastery.ObjectS<{
40
+ provider: z<string, string>;
41
+ model: z<string, string>;
42
+ reasoningEffort: z<string, string>;
43
+ }>, Schemastery.ObjectT<{
44
+ provider: z<string, string>;
45
+ model: z<string, string>;
46
+ reasoningEffort: z<string, string>;
47
+ }>>;
48
+ /** Normalize a raw settings section into a live typed selection. */
49
+ export declare function normalizeSubagentSelection(value: unknown): SubagentSelection;
50
+ /**
51
+ * Install the settings-backed subagent selection for one TUI plugin fiber.
52
+ * Returns the mutable ref the request waterfall and the slash commands share.
53
+ */
54
+ export declare function createSubagentSelection(ctx: Context): SubagentSelectionRef;
55
+ /** Serialize a live selection back into the settings document shape. */
56
+ export declare function subagentSettingsValue(selection: SubagentSelection): SubagentSettings;
@@ -11,6 +11,7 @@
11
11
  */
12
12
  import type { Agent, ModelSelection, ModelSelectionRef } from '@deepseek-ai/dsh-agent';
13
13
  import type { Context } from '@deepseek-ai/cordis';
14
+ import { type SubagentSelectionRef } from './subagent-model.js';
14
15
  /** Presentation configuration for the terminal channel. */
15
16
  export interface TuiConfig {
16
17
  /** Exact shared agent/session identity driven by this terminal. */
@@ -23,6 +24,8 @@ export interface TuiConfig {
23
24
  color?: boolean;
24
25
  /** Banner subtitle line shown while no session title exists. */
25
26
  welcome?: string;
27
+ /** Override for the launcher-provided goodbye/resume hint. */
28
+ goodbye?: string;
26
29
  /** Whether this launch resumes an existing persisted session. */
27
30
  resume?: boolean;
28
31
  /** Provider route selected at launch (defaults to deepseek-official). */
@@ -31,6 +34,8 @@ export interface TuiConfig {
31
34
  model?: string;
32
35
  /** Live model-selection ref installed on the agent; mutated by /model. */
33
36
  selectionRef?: ModelSelectionRef;
37
+ /** Settings-backed model/effort selection applied to subagent requests. */
38
+ subagentSelection?: SubagentSelectionRef;
34
39
  /** Active agent-preset id (standard/code/minimal/cordis/...). */
35
40
  presetId?: string;
36
41
  /** Display name of the active preset. */
@@ -96,6 +101,8 @@ export interface TuiController {
96
101
  * links and inline spans keep their own ANSI treatment.
97
102
  */
98
103
  export declare function renderMarkdownLines(text: string, width: number, color: boolean): string[];
104
+ /** Cut one line to fit a width, appending an ellipsis when truncated. */
105
+ export declare function truncateToWidth(text: string, width: number): string;
99
106
  /** One renderable view of the input line: text plus the cursor's visual offset. */
100
107
  interface InputView {
101
108
  text: string;
@@ -183,6 +190,8 @@ export declare class SshTui {
183
190
  private historyIndex;
184
191
  private status;
185
192
  private dialog;
193
+ private readonly dialogQueue;
194
+ private onboardingCompletion;
186
195
  private dirty;
187
196
  private disposed;
188
197
  private exiting;
@@ -195,6 +204,7 @@ export declare class SshTui {
195
204
  private readonly resume;
196
205
  private readonly providerName;
197
206
  private readonly selectionRef;
207
+ private readonly subagentSelection;
198
208
  private readonly onSwitchSession;
199
209
  private readonly onSelectionChanged;
200
210
  private readonly resumePicker;
@@ -212,6 +222,7 @@ export declare class SshTui {
212
222
  private lastActivity;
213
223
  private stalledWarningShown;
214
224
  private lastPaintAt;
225
+ private commandAbort;
215
226
  private activeSubagents;
216
227
  private subagentSessions;
217
228
  private openToolCalls;
@@ -227,6 +238,7 @@ export declare class SshTui {
227
238
  private escapeTimer;
228
239
  private thinkingStartedAt;
229
240
  private completionSignaled;
241
+ private replaying;
230
242
  private completedAt;
231
243
  private lastTitleUpdateAt;
232
244
  private lastPaintRows;
@@ -271,6 +283,13 @@ export declare class SshTui {
271
283
  private playCompletionSignal;
272
284
  private render;
273
285
  private styleLine;
286
+ /**
287
+ * Apply the TUI's subagent model selection to every child-agent request.
288
+ * The parent request is left untouched (its own `/model` waterfall already
289
+ * owns the route); direct children created by tool-subagent inherit the
290
+ * parent provider unless `/submodel` stored an explicit subagent provider.
291
+ */
292
+ private readonly handleAgentRequest;
274
293
  private readonly handleSessionEvent;
275
294
  private readonly handleStatus;
276
295
  private readonly handleError;
@@ -283,8 +302,15 @@ export declare class SshTui {
283
302
  private readonly handleSubagentEnd;
284
303
  private readonly handleApproval;
285
304
  private readonly handleUserQuestions;
305
+ /** Queue one dialog behind an already-open one instead of overwriting it. */
306
+ private openDialog;
307
+ private showNextDialog;
308
+ private removeQueuedDialog;
309
+ private settleQuestion;
286
310
  private openConfirm;
287
311
  private closeConfirm;
312
+ /** Resolve one queued or active confirm from its abort signal. */
313
+ private abortConfirm;
288
314
  private openQuestion;
289
315
  /** Open one question dialog and await its answer (cancellation rejects). */
290
316
  private askQuestion;
@@ -312,6 +338,16 @@ export declare class SshTui {
312
338
  private pickModelOption;
313
339
  /** /model: pick a model and reasoning effort for the current provider. */
314
340
  private runModelCommand;
341
+ /** Provider route the next subagent request should use. */
342
+ private effectiveSubagentProvider;
343
+ /** Persist one subagent selection and publish it to the live request waterfall. */
344
+ private saveSubagentSelection;
345
+ /** Resolve the picker model list for one provider (endpoint first, then catalog). */
346
+ private subagentModelOptions;
347
+ /** /submodel: pick (or set) the model subagent children use. */
348
+ private runSubmodelCommand;
349
+ /** /subeffort: pick the reasoning effort subagent children use. */
350
+ private runSubeffortCommand;
315
351
  /** /mode: pick an agent preset (standard / minimal / code / cordis / routing-suite / ...). */
316
352
  private runModeCommand;
317
353
  /** /resume: switch to a past session, or open a picker when no id is given. */
@@ -353,6 +389,10 @@ export declare class SshTui {
353
389
  private handleCtrlC;
354
390
  private submit;
355
391
  private runCommand;
392
+ /** Grapheme cluster immediately before `cursor`; cursor-internal positions delete it whole. */
393
+ private graphemeBefore;
394
+ /** Grapheme cluster containing or following `cursor`. */
395
+ private graphemeAfter;
356
396
  private backspace;
357
397
  private deleteAtCursor;
358
398
  private moveCursor;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-ssh-tui",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "SSH-friendly interactive terminal TUI plugin for DeepSeek Harness",
5
5
  "keywords": [
6
6
  "deepseek-harness",
@@ -53,6 +53,7 @@
53
53
  "scripts": {
54
54
  "build": "tsc -p tsconfig.json",
55
55
  "typecheck": "tsc -p tsconfig.json --noEmit",
56
+ "test": "npm run build && node --test tests/*.test.mjs",
56
57
  "clean": "rm -rf lib",
57
58
  "prepare": "npm run build",
58
59
  "prepack": "npm run build",
@@ -66,6 +67,7 @@
66
67
  "node": ">=22.19"
67
68
  },
68
69
  "dependencies": {
70
+ "@deepseek-ai/schemastery": "^3.18.1",
69
71
  "commander": "^14.0.0"
70
72
  },
71
73
  "peerDependencies": {