@xmoon76/dsh-pi-tui 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +243 -6
- package/dist/index.mjs +2611 -321
- package/package.json +5 -3
- package/scripts/naming-gate.mjs +43 -1
- package/scripts/repair-core.mjs +35 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,112 @@
|
|
|
1
1
|
import z from "@deepseek-ai/schemastery";
|
|
2
|
-
import { ModelSelectionRef } from "@deepseek-ai/dsh-agent";
|
|
2
|
+
import { Agent, ModelSelectionRef } from "@deepseek-ai/dsh-agent";
|
|
3
|
+
import { ContentBlock } from "@deepseek-ai/dsh-llm";
|
|
3
4
|
import { SessionEvent, SessionId } from "@deepseek-ai/dsh-session";
|
|
5
|
+
import { CommandDescriptor } from "@deepseek-ai/dsh-commands";
|
|
4
6
|
import { EventEmitter } from "events";
|
|
5
7
|
import { Context } from "@deepseek-ai/cordis";
|
|
8
|
+
//#region src/diag.d.ts
|
|
9
|
+
interface Diag {
|
|
10
|
+
debug(message: string, fields?: Record<string, unknown>): void;
|
|
11
|
+
info(message: string, fields?: Record<string, unknown>): void;
|
|
12
|
+
warn(message: string, fields?: Record<string, unknown>): void;
|
|
13
|
+
error(message: string, fields?: Record<string, unknown>): void;
|
|
14
|
+
/** Release the file handle, if one is open. */
|
|
15
|
+
dispose(): void;
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/tui-app.d.ts
|
|
19
|
+
/** One queued inbox row for the queue pane (mirrors the agent Inbox's lists). */
|
|
20
|
+
interface QueueItem {
|
|
21
|
+
/** The pending message id (agent inbox identity). */
|
|
22
|
+
id: string;
|
|
23
|
+
/** The message text, single-line display form. */
|
|
24
|
+
text: string;
|
|
25
|
+
/** next-turn followup vs next-step steer. */
|
|
26
|
+
mode: 'followup' | 'steer';
|
|
27
|
+
/** Plugin notice (e.g. a background-job completion): NOT steerable — it
|
|
28
|
+
* renders with its own marker and the hint drops the steer verbs. */
|
|
29
|
+
notice?: boolean;
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/skill-catalog.d.ts
|
|
33
|
+
/**
|
|
34
|
+
* The standing-scope skill catalog adapter: the SINGLE narrow seam between
|
|
35
|
+
* the TUI and the dsh skill services (the non-public-API isolation
|
|
36
|
+
* contract, plan appendix B).
|
|
37
|
+
*
|
|
38
|
+
* Everything the TUI knows about dsh-skill and agent-presets lives here:
|
|
39
|
+
* - structural service types (never upstream classes) with OPTIONAL
|
|
40
|
+
* capability members — `snapshot` and `standingKeyFor` are detected at
|
|
41
|
+
* call time, so an upstream change degrades instead of breaking;
|
|
42
|
+
* - `readHumanSkillCatalog()`: snapshot-first collector (list() fallback),
|
|
43
|
+
* official `isUserInvocable` filter, field validation, stable sort,
|
|
44
|
+
* deep freeze, distinct abort propagation;
|
|
45
|
+
* - `resolveColdSkillTarget()`: capability-gated cold target selection
|
|
46
|
+
* (standing scope → rosterless global → degraded global with a notice);
|
|
47
|
+
* - `resolveLiveSkillTarget()`: the agent's own registry + agent scope.
|
|
48
|
+
*
|
|
49
|
+
* Failure contract: ordinary provider/composition failures surface as
|
|
50
|
+
* degraded targets or rethrown errors for the coordinator to classify;
|
|
51
|
+
* aborts ALWAYS propagate as aborts. No failure may hang or crash the TUI —
|
|
52
|
+
* the worst outcome is "the corresponding commands are missing".
|
|
53
|
+
* @module @xmoon76/dsh-pi-tui/skill-catalog
|
|
54
|
+
*/
|
|
55
|
+
/** The human-facing slice of one skill: display fields only. */
|
|
56
|
+
interface HumanSkillSummary {
|
|
57
|
+
readonly name: string;
|
|
58
|
+
readonly description: string;
|
|
59
|
+
readonly whenToUse?: string;
|
|
60
|
+
}
|
|
61
|
+
/** The detached human skill catalog one observation produced. */
|
|
62
|
+
interface HumanSkillCatalog {
|
|
63
|
+
readonly skills: readonly HumanSkillSummary[];
|
|
64
|
+
/** Whether discovery completed within a stable revision (an incomplete
|
|
65
|
+
* observation must not replace a last-good catalog). */
|
|
66
|
+
readonly complete: boolean;
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region src/surface-catalog.d.ts
|
|
70
|
+
/** One effective command's discovery metadata (the official descriptor's
|
|
71
|
+
* display fields; never a handler or a definition). */
|
|
72
|
+
interface SurfaceCommandSummary {
|
|
73
|
+
readonly name: string;
|
|
74
|
+
readonly description: string;
|
|
75
|
+
readonly input?: {
|
|
76
|
+
readonly hint: string;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/** One provider's detached failure text (never the thrown value itself). */
|
|
80
|
+
interface SurfaceCatalogIssue {
|
|
81
|
+
readonly provider: 'commands' | 'skills';
|
|
82
|
+
readonly message: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The complete frozen catalog view installed before the first input:
|
|
86
|
+
* - `commands` — the full effective view at read time (diagnostics/tests);
|
|
87
|
+
* - `scopedCommands` — effective entries absent from, or shadowing, the
|
|
88
|
+
* read-time global baseline (completion overrides while sessionless);
|
|
89
|
+
* - `skills` — human-invocable skill summaries (official policy applied);
|
|
90
|
+
* - `issues` — per-provider failures; an absent service is NOT an issue.
|
|
91
|
+
*/
|
|
92
|
+
interface SurfaceCatalogSnapshot {
|
|
93
|
+
readonly commands: readonly SurfaceCommandSummary[];
|
|
94
|
+
readonly scopedCommands: readonly SurfaceCommandSummary[];
|
|
95
|
+
readonly skills: readonly HumanSkillSummary[];
|
|
96
|
+
readonly issues: readonly SurfaceCatalogIssue[];
|
|
97
|
+
}
|
|
98
|
+
/** The commands-service surface the collector reads. */
|
|
99
|
+
interface SurfaceCommandsService {
|
|
100
|
+
list(agent: Agent): readonly CommandDescriptor[];
|
|
101
|
+
}
|
|
102
|
+
/** The narrow context surface {@link readSurfaceCatalog} consumes. The
|
|
103
|
+
* SKILL services are NOT reached here: every dsh skill/agent-presets
|
|
104
|
+
* access goes through `src/skill-catalog.ts` (the single-point adapter,
|
|
105
|
+
* plan appendix B.1). */
|
|
106
|
+
interface SurfaceCatalogContext {
|
|
107
|
+
get(name: 'commands'): SurfaceCommandsService | undefined;
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
6
110
|
//#region src/commands.d.ts
|
|
7
111
|
/** A balanced completed-turn prefix for forking: the log up to (and including)
|
|
8
112
|
* the last `turn/end`. Undefined when no turn has completed yet.
|
|
@@ -60,14 +164,136 @@ declare function shouldSteerOnEnter(parsed: {
|
|
|
60
164
|
name: string;
|
|
61
165
|
} | undefined, running: boolean, busyEnter: string | undefined, forceQueue: boolean): boolean;
|
|
62
166
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
167
|
+
* The advertised-claim miss decision (pure, exported for the headless
|
|
168
|
+
* suite): a slash input whose name was advertised by the completion list at
|
|
169
|
+
* submit time but that the REAL session's catalog lacks is CONSUMED with an
|
|
170
|
+
* explicit error — never sent to the model as a plain user message. An
|
|
171
|
+
* unadvertised miss keeps the existing plain-input fallback (the user may
|
|
172
|
+
* deliberately send slash text to the model).
|
|
173
|
+
* @param execution - the settled `commands.execute` outcome.
|
|
174
|
+
* @param wasAdvertised - the claim captured BEFORE session creation.
|
|
175
|
+
* @returns whether the miss must be consumed as an advertised miss.
|
|
176
|
+
*/
|
|
177
|
+
declare function shouldConsumeAdvertisedMiss(execution: {
|
|
178
|
+
readonly result: unknown;
|
|
179
|
+
} | undefined, wasAdvertised: boolean): boolean;
|
|
180
|
+
/**
|
|
181
|
+
* The pre-mount surface catalog resolution:
|
|
182
|
+
* - an explicit `--session` start PREFETCHES the resumed agent's effective
|
|
183
|
+
* catalog (a live read emits no session events);
|
|
184
|
+
* - the deferred start (no `--session`) reads the cold HUMAN SKILL catalog
|
|
185
|
+
* through the preset's STANDING SCOPE — no Agent, no session, no turn —
|
|
186
|
+
* so the first input sees human-invocable skills without any durable
|
|
187
|
+
* side effect (the mechanism that avoids the probe dead end: host
|
|
188
|
+
* `session/created` observers write durable knob events into every fresh
|
|
189
|
+
* session).
|
|
190
|
+
*
|
|
191
|
+
* The snapshot (resume) or the skill catalog (cold) installs synchronously
|
|
192
|
+
* after mount (the ready barrier).
|
|
193
|
+
*
|
|
194
|
+
* Failure taxonomy (plan appendix B):
|
|
195
|
+
* - lifecycle cancellation: nothing installed, no notice;
|
|
196
|
+
* - a prefetch/standing read failure degrades to a one-shot notice (the
|
|
197
|
+
* TUI mounts with the global view and built-in commands);
|
|
198
|
+
* - a missing/unknown preset or a broken standing mount degrades the cold
|
|
199
|
+
* target to the global layer with a one-shot notice — never a probe
|
|
200
|
+
* Agent, never a startup failure;
|
|
201
|
+
* - an ordinary provider read failure never rejects here: it becomes an
|
|
202
|
+
* empty field + detached issue inside the catalog.
|
|
203
|
+
* @param options - injected dependencies (see {@link ResolveInitialCatalogOptions}).
|
|
204
|
+
* @returns the snapshot / skill catalog to install and an optional notice.
|
|
67
205
|
*/
|
|
206
|
+
interface InitialCatalogResolution {
|
|
207
|
+
/** The resume prefetch snapshot to install at mount. */
|
|
208
|
+
readonly snapshot?: SurfaceCatalogSnapshot;
|
|
209
|
+
/** The cold standing-scope human skill catalog (deferred start). */
|
|
210
|
+
readonly skills?: HumanSkillCatalog;
|
|
211
|
+
/** A user-facing notice when the prefetch/standing read degraded. */
|
|
212
|
+
readonly notice?: string;
|
|
213
|
+
}
|
|
214
|
+
/** Options for {@link resolveInitialCatalog}. */
|
|
215
|
+
interface ResolveInitialCatalogOptions {
|
|
216
|
+
/** The resumed live agent, if any (prefetch path). */
|
|
217
|
+
readonly liveAgent?: Agent;
|
|
218
|
+
/** The effective preset id for the cold standing read (undefined = the
|
|
219
|
+
* deployment default; only consulted for the deferred start). */
|
|
220
|
+
readonly presetId?: string;
|
|
221
|
+
readonly signal: AbortSignal;
|
|
222
|
+
/** The context surface the collectors read services from. */
|
|
223
|
+
readonly ctx: SurfaceCatalogContext;
|
|
224
|
+
readonly diag: Diag;
|
|
225
|
+
}
|
|
226
|
+
declare function resolveInitialCatalog(options: ResolveInitialCatalogOptions): Promise<InitialCatalogResolution>;
|
|
68
227
|
declare function subagentJobTranscriptId(snapshot: unknown): string | undefined;
|
|
69
228
|
/** Viewer body for a subagent job with no uniquely matched child. */
|
|
70
229
|
declare function subagentJobViewHint(status: string, detail: string | undefined): string;
|
|
230
|
+
/** The message-source projection the queue filter reads (a structural subset
|
|
231
|
+
* of dsh's message sources, so the helpers are testable without dsh types). */
|
|
232
|
+
interface QueueNoticeSource {
|
|
233
|
+
readonly form?: string;
|
|
234
|
+
readonly kind?: string;
|
|
235
|
+
readonly summary?: string;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Whether a plain submitted draft is the quit word: exactly `exit` (trimmed,
|
|
239
|
+
* lowercase). The runner intercepts this BEFORE any session creation or
|
|
240
|
+
* submission (shell muscle memory); anything else — `exit!`, `Exit`, or a
|
|
241
|
+
* draft with a recalled entry still in it — is an ordinary message.
|
|
242
|
+
* @param text - the submitted draft.
|
|
243
|
+
*/
|
|
244
|
+
declare function isPlainExitPrompt(text: string): boolean;
|
|
245
|
+
/**
|
|
246
|
+
* Whether an inbox message is a BACKGROUND-SUBAGENT settlement notice — the
|
|
247
|
+
* runtime's account of a child ending, not steerable user input. Two dsh
|
|
248
|
+
* producers push these into the parent's inbox:
|
|
249
|
+
* - continuable children: `source.kind === 'subagent-settled'` (the
|
|
250
|
+
* continuation manager's settlement notice);
|
|
251
|
+
* - one-shot background subagent jobs: tool-jobs completion notices whose
|
|
252
|
+
* summary starts with the job kind (`subagent <label> [status: …]`).
|
|
253
|
+
* The queue pane mirrors the inbox, but these belong to the task browser
|
|
254
|
+
* (terminal job rows / inactive child rows), so the mirror drops them and
|
|
255
|
+
* only failures surface as a transient error notify.
|
|
256
|
+
* @param source - the message source projection, or undefined for a plain row.
|
|
257
|
+
*/
|
|
258
|
+
declare function isSubagentSettlementNotice(source: QueueNoticeSource | undefined): boolean;
|
|
259
|
+
/**
|
|
260
|
+
* Whether a subagent settlement notice reports FAILURE, classified on the
|
|
261
|
+
* producers' own deterministic wording:
|
|
262
|
+
* - `subagent-settled` summaries: "finished and will do no further work"
|
|
263
|
+
* is the only success wording; aborted / max-tokens / refusal / error /
|
|
264
|
+
* unknown endings all fail;
|
|
265
|
+
* - tool-jobs subagent summaries carry the terminal status line, whose
|
|
266
|
+
* failure statuses are `failed` and `killed` (dsh JobStatus).
|
|
267
|
+
* A notice that cannot be classified is treated as success (silent).
|
|
268
|
+
* @param source - the message source projection.
|
|
269
|
+
*/
|
|
270
|
+
declare function subagentNoticeIsFailure(source: QueueNoticeSource | undefined): boolean;
|
|
271
|
+
/** One inbox message as the queue mirror sees it (a structural projection). */
|
|
272
|
+
interface QueueInboxMessage {
|
|
273
|
+
readonly id: string;
|
|
274
|
+
readonly content: readonly ContentBlock[];
|
|
275
|
+
readonly source?: QueueNoticeSource;
|
|
276
|
+
}
|
|
277
|
+
/** The mirror result for one inbox batch: the rows to show plus the failed
|
|
278
|
+
* settlement summaries the caller should notify (each once). */
|
|
279
|
+
interface QueueFoldResult {
|
|
280
|
+
/** Queue rows (background-subagent settlement notices excluded). */
|
|
281
|
+
readonly rows: QueueItem[];
|
|
282
|
+
/** Failed settlement summaries not yet notified (the caller notifies). */
|
|
283
|
+
readonly failures: readonly string[];
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Build the queue-pane rows for one inbox batch, dropping background-subagent
|
|
287
|
+
* settlement notices (the task browser is their surface) and reporting which
|
|
288
|
+
* FAILED settlements should notify. Pure and injectable so the filter +
|
|
289
|
+
* once-notify semantics are testable without the agent.
|
|
290
|
+
* @param messages - one inbox batch (next-turn or next-step), in order.
|
|
291
|
+
* @param mode - the delivery mode for surviving rows.
|
|
292
|
+
* @param notified - the notify-once guard; failed notices already in it are
|
|
293
|
+
* skipped, and a newly-reported id is ADDED here so a re-render can never
|
|
294
|
+
* double-notify.
|
|
295
|
+
*/
|
|
296
|
+
declare function foldQueueRows(messages: readonly QueueInboxMessage[], mode: 'followup' | 'steer', notified: Set<string>): QueueFoldResult;
|
|
71
297
|
/**
|
|
72
298
|
* Whether a shell command matches a destructive pattern. `rm` is treated
|
|
73
299
|
* specially: any spelling of recursive + force flags (`rm -rf`, `rm -r -f`,
|
|
@@ -93,6 +319,17 @@ declare function runningProfile(argv?: readonly string[], fallback?: string): st
|
|
|
93
319
|
* @returns the resume command line, or undefined without a session.
|
|
94
320
|
*/
|
|
95
321
|
declare function resumeCommand(profile: string, sessionId: string): string | undefined;
|
|
322
|
+
/**
|
|
323
|
+
* A launch-time open-lock refusal: the requested session is held by another
|
|
324
|
+
* live dsh process (or its lock cannot be verified). Unlike a stale/missing
|
|
325
|
+
* session id, this is NOT recoverable by falling back to a fresh session —
|
|
326
|
+
* the user asked for a specific session and must resolve the holder first.
|
|
327
|
+
* Thrown from the resume path and re-thrown past the resume catch so the
|
|
328
|
+
* runner exits with the refusal as the error message.
|
|
329
|
+
*/
|
|
330
|
+
declare class SessionLockRefusedError extends Error {
|
|
331
|
+
constructor(message: string);
|
|
332
|
+
}
|
|
96
333
|
/** One agent's preset composition: the id to record and the setup that installs it. */
|
|
97
334
|
interface AgentComposition {
|
|
98
335
|
/** Preset id for the session header, absent when the deployment composes no roster. */
|
|
@@ -168,4 +405,4 @@ declare function recomposeBlank(ctx: Context, agent: {
|
|
|
168
405
|
*/
|
|
169
406
|
declare function apply(ctx: Context, config: Config): void;
|
|
170
407
|
//#endregion
|
|
171
|
-
export { AgentComposition, Config, LOCAL_COMMANDS, RecomposableSession, RecomposeOutcome, SESSIONLESS_COMMANDS, apply, composeAgent, dangerCommand, forkSeed, inject, name, recomposeBlank, recordedPreset, resumeCommand, runningProfile, shouldSteerOnEnter, subagentJobTranscriptId, subagentJobViewHint };
|
|
408
|
+
export { AgentComposition, Config, InitialCatalogResolution, LOCAL_COMMANDS, QueueFoldResult, QueueInboxMessage, QueueNoticeSource, RecomposableSession, RecomposeOutcome, ResolveInitialCatalogOptions, SESSIONLESS_COMMANDS, SessionLockRefusedError, apply, composeAgent, dangerCommand, foldQueueRows, forkSeed, inject, isPlainExitPrompt, isSubagentSettlementNotice, name, recomposeBlank, recordedPreset, resolveInitialCatalog, resumeCommand, runningProfile, shouldConsumeAdvertisedMiss, shouldSteerOnEnter, subagentJobTranscriptId, subagentJobViewHint, subagentNoticeIsFailure };
|