@xmoon76/dsh-pi-tui 0.5.0 → 0.5.1
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 +69 -11
- package/README.md +62 -11
- package/cordis.patch.yml +13 -0
- package/dist/builtins.mjs +11 -16
- package/dist/extension/advanced.d.mts +1 -1
- package/dist/extension/unstable.d.mts +1 -1
- package/dist/extensions-1WYBUQ8I.mjs +18205 -0
- package/dist/extensions-v3Rf-qJA.d.mts +139 -0
- package/dist/extensions.d.mts +2 -137
- package/dist/extensions.mjs +1 -1
- package/dist/index.d.mts +487 -433
- package/dist/index.mjs +46875 -19142
- package/dist/{public-types-YbB5Rhku.d.mts → public-types-BEjj7FEb.d.mts} +39 -5
- package/dist/runtime-CcQyhIvI.mjs +6147 -0
- package/dist/{startup-DM-xxzcX.mjs → startup-CmTYVTGC.mjs} +14 -8
- package/dist/startup.d.mts +5 -4
- package/dist/startup.mjs +1 -1
- package/dist/terminal-progress-source-BfiTKDT-.mjs +2349 -0
- package/dist/version-a-eF-QER.mjs +80 -0
- package/package.json +138 -128
- package/dist/dsh-version-V0exEv9O.mjs +0 -76
- package/dist/extensions-Dg1qhjUi.mjs +0 -39850
- package/dist/keybinding-registry-CjbtRmhd.d.mts +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,27 +1,20 @@
|
|
|
1
|
-
import { H as TuiAction } from "./public-types-
|
|
1
|
+
import { H as TuiAction } from "./public-types-BEjj7FEb.mjs";
|
|
2
2
|
import { SessionId } from "@deepseek-ai/dsh-session";
|
|
3
3
|
import { ContentBlock } from "@deepseek-ai/dsh-llm";
|
|
4
4
|
import { Context, Volatile } from "@deepseek-ai/cordis";
|
|
5
5
|
import { Agent, ModelSelectionRef } from "@deepseek-ai/dsh-agent";
|
|
6
6
|
import z from "@deepseek-ai/schemastery";
|
|
7
|
-
//#region src/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* @module @xmoon76/dsh-pi-tui/display-preset
|
|
16
|
-
*/
|
|
17
|
-
/** The complete display vocabulary. */
|
|
18
|
-
type DisplayPreset = 'focus' | 'compact' | 'full';
|
|
19
|
-
/** The shared mutable display authority passed between the runner, prompt and UI. */
|
|
20
|
-
interface DisplayState {
|
|
21
|
-
preset: DisplayPreset;
|
|
7
|
+
//#region src/domain/communication/policy.d.ts
|
|
8
|
+
type ProgressUpdates = 'off' | 'milestones' | 'frequent';
|
|
9
|
+
type ResponseStyle = 'default' | 'concise' | 'explanatory';
|
|
10
|
+
interface ProgressUpdatesState {
|
|
11
|
+
mode: ProgressUpdates;
|
|
12
|
+
}
|
|
13
|
+
interface ResponseStyleState {
|
|
14
|
+
style: ResponseStyle;
|
|
22
15
|
}
|
|
23
16
|
//#endregion
|
|
24
|
-
//#region src/
|
|
17
|
+
//#region src/runtime/process/diagnostics.d.ts
|
|
25
18
|
interface Diag {
|
|
26
19
|
debug(message: string, fields?: Record<string, unknown>): void;
|
|
27
20
|
info(message: string, fields?: Record<string, unknown>): void;
|
|
@@ -31,38 +24,18 @@ interface Diag {
|
|
|
31
24
|
dispose(): void;
|
|
32
25
|
}
|
|
33
26
|
//#endregion
|
|
34
|
-
//#region src/
|
|
35
|
-
type ProgressUpdates = 'off' | 'milestones' | 'frequent';
|
|
36
|
-
type ResponseStyle = 'default' | 'concise' | 'explanatory';
|
|
37
|
-
interface ProgressUpdatesState {
|
|
38
|
-
mode: ProgressUpdates;
|
|
39
|
-
}
|
|
40
|
-
interface ResponseStyleState {
|
|
41
|
-
style: ResponseStyle;
|
|
42
|
-
}
|
|
43
|
-
//#endregion
|
|
44
|
-
//#region src/skill-catalog.d.ts
|
|
27
|
+
//#region src/domain/catalog/skill.d.ts
|
|
45
28
|
/**
|
|
46
|
-
*
|
|
47
|
-
* the
|
|
48
|
-
*
|
|
29
|
+
* Neutral skill catalog vocabulary (TS8-E): the human-facing skill summary
|
|
30
|
+
* shape, the detached catalog (with its completeness flag) and the official
|
|
31
|
+
* user-invocation policy guard.
|
|
49
32
|
*
|
|
50
|
-
*
|
|
51
|
-
* -
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* deep freeze, distinct abort propagation;
|
|
57
|
-
* - `resolveColdSkillTarget()`: capability-gated cold target selection
|
|
58
|
-
* (standing scope → rosterless global → degraded global with a notice);
|
|
59
|
-
* - `resolveLiveSkillTarget()`: the agent's own registry + agent scope.
|
|
60
|
-
*
|
|
61
|
-
* Failure contract: ordinary provider/composition failures surface as
|
|
62
|
-
* degraded targets or rethrown errors for the coordinator to classify;
|
|
63
|
-
* aborts ALWAYS propagate as aborts. No failure may hang or crash the TUI —
|
|
64
|
-
* the worst outcome is "the corresponding commands are missing".
|
|
65
|
-
* @module @xmoon76/dsh-pi-tui/skill-catalog
|
|
33
|
+
* This module is the transport/UI-neutral semantic owner: it consumes only the
|
|
34
|
+
* official `@deepseek-ai/dsh-skill` policy helper. It never resolves ctx
|
|
35
|
+
* services, acquires standing scopes, holds revision leases, reads a live
|
|
36
|
+
* Agent, or imports a Direct/Remote adapter — the structural Direct Host read
|
|
37
|
+
* lives in `runtime/direct/skill-catalog.ts`.
|
|
38
|
+
* @module @xmoon76/dsh-pi-tui/domain/catalog/skill
|
|
66
39
|
*/
|
|
67
40
|
/** The human-facing slice of one skill: display fields only. */
|
|
68
41
|
interface HumanSkillSummary {
|
|
@@ -80,18 +53,7 @@ interface HumanSkillCatalog {
|
|
|
80
53
|
readonly complete: boolean;
|
|
81
54
|
}
|
|
82
55
|
//#endregion
|
|
83
|
-
//#region src/surface
|
|
84
|
-
/** Minimal live-agent face consumed by the effective catalog readers — and by
|
|
85
|
-
* {@link ResolveInitialCatalogOptions}, so the published option type stays
|
|
86
|
-
* structural instead of inlining the Host Agent. */
|
|
87
|
-
interface SurfaceCatalogAgent {
|
|
88
|
-
readonly ctx: object;
|
|
89
|
-
readonly session: {
|
|
90
|
-
readonly header: {
|
|
91
|
-
readonly cwd?: string;
|
|
92
|
-
};
|
|
93
|
-
};
|
|
94
|
-
}
|
|
56
|
+
//#region src/domain/catalog/surface.d.ts
|
|
95
57
|
/** Local structural command face, compatible with both npm and Source Mode DSH.
|
|
96
58
|
* The optional identity is part of the official 0.1.6 descriptor; an older
|
|
97
59
|
* runtime's descriptor may omit it. */
|
|
@@ -139,27 +101,42 @@ interface SurfaceCatalogSnapshot {
|
|
|
139
101
|
readonly skills: readonly HumanSkillSummary[];
|
|
140
102
|
readonly issues: readonly SurfaceCatalogIssue[];
|
|
141
103
|
}
|
|
104
|
+
/** The pre-mount catalog resolution result: the resume prefetch snapshot or
|
|
105
|
+
* the cold standing-scope skill catalog, plus an optional degradation notice. */
|
|
106
|
+
interface InitialCatalogResolution {
|
|
107
|
+
/** The resume prefetch snapshot to install at mount. */
|
|
108
|
+
readonly snapshot?: SurfaceCatalogSnapshot;
|
|
109
|
+
/** The cold standing-scope human skill catalog (deferred start). */
|
|
110
|
+
readonly skills?: HumanSkillCatalog;
|
|
111
|
+
/** A user-facing notice when the prefetch/standing read degraded. */
|
|
112
|
+
readonly notice?: string;
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/runtime/direct/surface-catalog.d.ts
|
|
116
|
+
/** Minimal live-agent face consumed by the effective catalog readers — and by
|
|
117
|
+
* {@link import('../../app/direct/initial-catalog.ts').SurfaceCatalogResolutionOptions}, so the
|
|
118
|
+
* published option type stays structural instead of inlining the Host Agent. */
|
|
119
|
+
interface SurfaceCatalogAgent {
|
|
120
|
+
readonly ctx: object;
|
|
121
|
+
readonly session: {
|
|
122
|
+
readonly header: {
|
|
123
|
+
readonly cwd?: string;
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
}
|
|
142
127
|
/** The commands-service surface the collector reads. */
|
|
143
128
|
interface SurfaceCommandsService {
|
|
144
129
|
list(agent: SurfaceCatalogAgent): readonly SurfaceCommandDescriptor[];
|
|
145
130
|
}
|
|
146
131
|
/** The narrow context surface {@link readSurfaceCatalog} consumes. The
|
|
147
132
|
* SKILL services are NOT reached here: every dsh skill/agent-presets
|
|
148
|
-
* access goes through `
|
|
149
|
-
* plan appendix B.1). */
|
|
133
|
+
* access goes through `runtime/direct/skill-catalog.ts` (the single-point
|
|
134
|
+
* adapter, plan appendix B.1). */
|
|
150
135
|
interface SurfaceCatalogContext {
|
|
151
136
|
get(name: 'commands'): SurfaceCommandsService | undefined;
|
|
152
137
|
}
|
|
153
|
-
interface InitialCatalogResolution {
|
|
154
|
-
/** The resume prefetch snapshot to install at mount. */
|
|
155
|
-
readonly snapshot?: SurfaceCatalogSnapshot;
|
|
156
|
-
/** The cold standing-scope human skill catalog (deferred start). */
|
|
157
|
-
readonly skills?: HumanSkillCatalog;
|
|
158
|
-
/** A user-facing notice when the prefetch/standing read degraded. */
|
|
159
|
-
readonly notice?: string;
|
|
160
|
-
}
|
|
161
138
|
//#endregion
|
|
162
|
-
//#region src/
|
|
139
|
+
//#region src/app/config/schema.d.ts
|
|
163
140
|
/** Plugin config: the session to resume, resolved from the startup service,
|
|
164
141
|
* plus the DSH 0.1.7 profile-owned live TUI preferences. Every preference
|
|
165
142
|
* field is a schemastery `.volatile()` reference (PR A): the `tui-app`
|
|
@@ -203,7 +180,7 @@ interface Config {
|
|
|
203
180
|
/** Busy-Enter delivery for plain Enter while the agent runs: 'queue'
|
|
204
181
|
* (default) or 'steer'. */
|
|
205
182
|
readonly busyEnter: Volatile<string>;
|
|
206
|
-
/**
|
|
183
|
+
/** User-shell sandbox policy for user-typed `!`/`!!` commands: 'bypass'
|
|
207
184
|
* (default) runs them outside the dsh sandbox, 'sandbox' routes them
|
|
208
185
|
* through the dsh shell capability's policy. */
|
|
209
186
|
readonly localShellSandbox: Volatile<string>;
|
|
@@ -214,16 +191,22 @@ interface Config {
|
|
|
214
191
|
readonly displayPreset: Volatile<string>;
|
|
215
192
|
/** Mid-turn progress-update cadence (off | milestones | frequent). */
|
|
216
193
|
readonly progressUpdates: Volatile<string>;
|
|
194
|
+
/** Git attribution guidance mode (off | product | product-model). */
|
|
195
|
+
readonly gitAttribution: Volatile<string>;
|
|
217
196
|
/** Visible-answer density guidance (default | concise | explanatory). */
|
|
218
197
|
readonly responseStyle: Volatile<string>;
|
|
219
198
|
/** Completion-notification mode ('unfocused' | 'always' | 'off'). */
|
|
220
199
|
readonly notificationMode: Volatile<string>;
|
|
221
200
|
/** Completion-notification method ('auto' | 'osc9' | 'osc777' | 'bell'). */
|
|
222
201
|
readonly notificationMethod: Volatile<string>;
|
|
202
|
+
/** Terminal-progress protocol selection ('off' | '9;4' | '7501' |
|
|
203
|
+
* '9;4+7501'): which native terminal status protocols the TUI reports.
|
|
204
|
+
* Defaults to the dual protocol. */
|
|
205
|
+
readonly terminalProgress: Volatile<string>;
|
|
223
206
|
/** Fullscreen mouse-wheel step ('1' | '2' | '3' | '5' | '8'). */
|
|
224
207
|
readonly wheelScrollLines: Volatile<string>;
|
|
225
208
|
/** The user keybinding overrides as a whole-value RAW field. The
|
|
226
|
-
* keybindings parser (src/keybindings/config.ts) is the only
|
|
209
|
+
* keybindings parser (src/tui/keybindings/config.ts) is the only
|
|
227
210
|
* validation/parsing authority — the keybinding business schema
|
|
228
211
|
* deliberately stays out of the plugin Config. */
|
|
229
212
|
readonly keybindings: Volatile<unknown>;
|
|
@@ -234,160 +217,26 @@ interface Config {
|
|
|
234
217
|
}
|
|
235
218
|
declare const Config: z<Config>;
|
|
236
219
|
//#endregion
|
|
237
|
-
//#region src/
|
|
238
|
-
/** Structural subset of `ImageAttachmentRef`. */
|
|
239
|
-
interface ImageAttachmentRefLike {
|
|
240
|
-
readonly attachmentId: string;
|
|
241
|
-
readonly mediaType: ImageMediaType;
|
|
242
|
-
readonly bytes: number;
|
|
243
|
-
readonly width: number;
|
|
244
|
-
readonly height: number;
|
|
245
|
-
readonly name?: string;
|
|
246
|
-
}
|
|
247
|
-
//#endregion
|
|
248
|
-
//#region src/image/types.d.ts
|
|
220
|
+
//#region src/domain/command/policy.d.ts
|
|
249
221
|
/**
|
|
250
|
-
*
|
|
222
|
+
* The transport/UI-neutral command-line policy (plan §27 / TS8-F3): which slash
|
|
223
|
+
* lines the TUI owns locally, which need no session, which lines are local for
|
|
224
|
+
* attachment purposes, and the ONE semantic line classification every dispatch
|
|
225
|
+
* gate consumes.
|
|
251
226
|
*
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
*
|
|
257
|
-
*
|
|
258
|
-
* `ImageMediaType` structurally, so drafts flow into the harness without a
|
|
259
|
-
* runtime dependency on the attachment package (AGENTS.md decision 7:
|
|
260
|
-
* structural typing for dsh services).
|
|
261
|
-
* @module @xmoon76/dsh-pi-tui/image/types
|
|
262
|
-
*/
|
|
263
|
-
/** Raster media types accepted by the TUI image intake. */
|
|
264
|
-
type ImageMediaType = 'image/png' | 'image/jpeg' | 'image/webp' | 'image/gif';
|
|
265
|
-
/** Per-TUI draft image identity; only meaningful inside one TUI run. */
|
|
266
|
-
type DraftImageId = number;
|
|
267
|
-
/** Where a staged image's bytes came from. */
|
|
268
|
-
type DraftImageSource = {
|
|
269
|
-
readonly type: 'clipboard';
|
|
270
|
-
} | {
|
|
271
|
-
readonly type: 'path';
|
|
272
|
-
readonly path: string;
|
|
273
|
-
}
|
|
274
|
-
/** The image was pulled back from a queued message: its bytes are ALREADY
|
|
275
|
-
* durable with the harness (the recalled ref) — the draft holds no local
|
|
276
|
-
* copy and re-submitting reuses the ref instead of re-uploading. */
|
|
277
|
-
| {
|
|
278
|
-
readonly type: 'recalled';
|
|
279
|
-
};
|
|
280
|
-
/**
|
|
281
|
-
* One image staged in the editor draft. The draft holds the raw bytes so
|
|
282
|
-
* clipboard and path entries share one shape and a submit never depends on
|
|
283
|
-
* the source file still existing (plan §5.1). A RECALLED draft (pulled
|
|
284
|
-
* back from the queue) instead carries the durable `ImageAttachmentRef`
|
|
285
|
-
* and NO local bytes — the bytes stay in harness storage and re-submitting
|
|
286
|
-
* reuses the ref.
|
|
287
|
-
*/
|
|
288
|
-
interface DraftImage {
|
|
289
|
-
/** Per-TUI draft identity (the `#N` of the placeholder). */
|
|
290
|
-
readonly id: DraftImageId;
|
|
291
|
-
readonly kind: 'image';
|
|
292
|
-
readonly source: DraftImageSource;
|
|
293
|
-
/** Exact encoded bytes, held only for the draft lifetime. Empty for a
|
|
294
|
-
* recalled draft (its bytes live in harness storage). */
|
|
295
|
-
readonly bytes: Uint8Array;
|
|
296
|
-
readonly mediaType: ImageMediaType;
|
|
297
|
-
/** Intrinsic encoded width in pixels. */
|
|
298
|
-
readonly width: number;
|
|
299
|
-
/** Intrinsic encoded height in pixels. */
|
|
300
|
-
readonly height: number;
|
|
301
|
-
/** Exact encoded byte length (`bytes.byteLength` for local drafts; the
|
|
302
|
-
* durable ref's recorded `bytes` for recalled drafts). */
|
|
303
|
-
readonly byteLength: number;
|
|
304
|
-
/** Optional display name (basename for path sources), never a path. */
|
|
305
|
-
readonly name?: string;
|
|
306
|
-
/** The canonical editor placeholder text for this draft. */
|
|
307
|
-
readonly placeholder: string;
|
|
308
|
-
/** The durable ref this draft reuses on submit; present ONLY for
|
|
309
|
-
* recalled drafts (already-durable images are never re-uploaded). */
|
|
310
|
-
readonly recalledRef?: ImageAttachmentRefLike;
|
|
311
|
-
}
|
|
312
|
-
/** The store surface the placeholder expansion needs (structural). */
|
|
313
|
-
interface DraftImageStoreLike {
|
|
314
|
-
values(): readonly DraftImage[];
|
|
315
|
-
}
|
|
316
|
-
//#endregion
|
|
317
|
-
//#region src/task-presentation.d.ts
|
|
318
|
-
declare function subagentJobTranscriptId(snapshot: unknown): string | undefined;
|
|
319
|
-
/**
|
|
320
|
-
* The Task Center row-selection disposition (plan §4.3/§4.4). A subagent
|
|
321
|
-
* transcript opens a session/viewer surface that REPLACES the browser; a
|
|
322
|
-
* Job row's detail keeps it mounted (the caller passes {@link openJobView}'s
|
|
323
|
-
* disposition). An UNKNOWN row — a stale panel selection after a live
|
|
324
|
-
* re-projection — also keeps the parent usable instead of dismissing it.
|
|
325
|
-
*/
|
|
326
|
-
declare function taskRowSelectionDisposition(row: {
|
|
327
|
-
readonly kind: 'job' | 'subagent';
|
|
328
|
-
} | undefined, jobDetail: 'close' | 'keep-open'): 'close' | 'keep-open';
|
|
329
|
-
/** Viewer body for a subagent job with no uniquely matched child. */
|
|
330
|
-
declare function subagentJobViewHint(status: string, detail: string | undefined): string;
|
|
331
|
-
//#endregion
|
|
332
|
-
//#region src/tui-app.d.ts
|
|
333
|
-
/** The compaction lifecycle phase the working row advertises: idle (no
|
|
334
|
-
* compaction), summarizing (compaction/start seen, the summary is being
|
|
335
|
-
* generated), or applying (the summary landed, the compacted surface is
|
|
336
|
-
* being committed). Derived by the runner from compaction/start →
|
|
337
|
-
* compaction/summary → compaction/end (foldCompactionEvent). */
|
|
338
|
-
type CompactionPhase = 'idle' | 'summarizing' | 'applying';
|
|
339
|
-
/**
|
|
340
|
-
* The WEB composer submit gestures (DSH `ComposerSubmitGesture`): plain
|
|
341
|
-
* Enter, or the Cmd/Ctrl-accelerated chord. The busy-Enter policy resolves
|
|
342
|
-
* each to a delivery mode — plain Enter to the preferred mode, the
|
|
343
|
-
* accelerated chord to its OPPOSITE — so the chord is never a fixed mode.
|
|
344
|
-
*/
|
|
345
|
-
type ComposerSubmitGesture = 'enter' | 'accelerated';
|
|
346
|
-
/** One semantic queued pending-input row for the queue pane. */
|
|
347
|
-
interface QueueItem {
|
|
348
|
-
/** The pending message id (agent inbox identity), or a local request id. */
|
|
349
|
-
id: string;
|
|
350
|
-
/** The message text, single-line display form. */
|
|
351
|
-
text: string;
|
|
352
|
-
/** next-turn followup vs next-step steer. */
|
|
353
|
-
mode: 'followup' | 'steer';
|
|
354
|
-
/** The correlation identity (authoritative rpc id or local request id). */
|
|
355
|
-
rpcId?: string;
|
|
356
|
-
/** A client-local echo not yet backed by an authoritative occurrence. */
|
|
357
|
-
local?: boolean;
|
|
358
|
-
}
|
|
359
|
-
//#endregion
|
|
360
|
-
//#region src/commands.d.ts
|
|
361
|
-
/**
|
|
362
|
-
* The effective mode ONE submission resolved at the submit boundary: whether
|
|
363
|
-
* an agent-facing delivery steers into the running turn or queues behind it
|
|
364
|
-
* (web `ComposerSubmissionPolicy` parity — an idle agent queues, plain Enter
|
|
365
|
-
* takes the preference, and the accelerated chord takes its OPPOSITE).
|
|
227
|
+
* Pure and Host-free (structural inputs plus DSH's own `parseCommand`), so the
|
|
228
|
+
* dispatch gates are testable headless and the presentation/submission paths
|
|
229
|
+
* share ONE classification. The application/submission-facing half (the
|
|
230
|
+
* image-rejection gate and the delivery resolver) lives in
|
|
231
|
+
* `app/submission/command-policy.ts`; the destructive-shell predicate lives in
|
|
232
|
+
* `domain/shell/danger.ts`.
|
|
366
233
|
*
|
|
367
|
-
*
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
*
|
|
234
|
+
* The AUTHORITATIVE Host-name fact stays an explicit input
|
|
235
|
+
* ({@link CommandLineClassificationFacts.hostOriginClaim}); this domain never
|
|
236
|
+
* derives Host authority from the effective claim union (which also carries the
|
|
237
|
+
* Client's own TUI registrations).
|
|
238
|
+
* @module @xmoon76/dsh-pi-tui/domain/command/policy
|
|
371
239
|
*/
|
|
372
|
-
type SubmitDelivery = 'steer' | 'queue';
|
|
373
|
-
/**
|
|
374
|
-
* The CURRENT host catalog's view of ONE parsed line (the DSH client
|
|
375
|
-
* `CommandUiRuntime.matchEnter` decision table): whether the host CLAIMS the
|
|
376
|
-
* line, and — for a claimed line — the claiming descriptor's attachment
|
|
377
|
-
* declaration, so the dispatch can never consult two different catalog views
|
|
378
|
-
* for the claim and the declaration.
|
|
379
|
-
*/
|
|
380
|
-
type HostCommandClaim = {
|
|
381
|
-
readonly claimed: true;
|
|
382
|
-
/** The claiming descriptor's `input.attachments`
|
|
383
|
-
* (DSH `CommandInputDescriptor.attachments`): only a declaring command
|
|
384
|
-
* may be invoked with composer attachments. */
|
|
385
|
-
readonly attachments: boolean;
|
|
386
|
-
} | {
|
|
387
|
-
readonly claimed: false;
|
|
388
|
-
};
|
|
389
|
-
//#endregion
|
|
390
|
-
//#region src/command-policy.d.ts
|
|
391
240
|
/**
|
|
392
241
|
* Slash commands that need no session: before the first user message
|
|
393
242
|
* (deferred start) they run locally without creating one. Everything else
|
|
@@ -400,38 +249,29 @@ type HostCommandClaim = {
|
|
|
400
249
|
*/
|
|
401
250
|
declare const SESSIONLESS_COMMANDS: Set<string>;
|
|
402
251
|
/**
|
|
403
|
-
* The LOCAL-execute command set
|
|
404
|
-
* control
|
|
405
|
-
*
|
|
406
|
-
*
|
|
407
|
-
*
|
|
408
|
-
*
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
*
|
|
252
|
+
* The LOCAL-execute command set (PR5 v2 §1C-6 narrows its semantic role):
|
|
253
|
+
* TUI-owned UI/control names AND core control names the TUI dispatches but
|
|
254
|
+
* does not register (/kill). It remains the STATIC policy surface —
|
|
255
|
+
* reserved-name validation, the extension collision catalog
|
|
256
|
+
* (HOST_COMMAND_CATALOG), and the fallback term of the line classifier
|
|
257
|
+
* when no LIVE Client-registry test was supplied. It is NOT by itself an
|
|
258
|
+
* answer to "who owns this production line": ownership comes from the
|
|
259
|
+
* live sources (the genuine Host-origin descriptors, the Client registry,
|
|
260
|
+
* the extension registry, the skill-wrapper state) through
|
|
261
|
+
* {@link classifyCommandLine}.
|
|
262
|
+
*
|
|
263
|
+
* `/kill` is the explicit example of the rule and its DISPOSITION is
|
|
264
|
+
* deliberate: it has NO live Client registration (and no handler anywhere in
|
|
265
|
+
* this surface), so it is NOT a TUI-owned line and this set must never be
|
|
266
|
+
* consulted to decide ownership. What actually happens to a typed `/kill ...`
|
|
267
|
+
* follows the ordinary precedence, in this order: a genuine Host claim decides
|
|
268
|
+
* per that descriptor; a genuine Host NAME that resolves while its exact line
|
|
269
|
+
* is NOT claimed makes the line an ordinary submission; and only a name
|
|
270
|
+
* nothing owns keeps the command plane's resolution chance (the final,
|
|
271
|
+
* session-scoped catalog may still provide it). It stays in this set for
|
|
272
|
+
* reserved-name validation and the extension collision catalog only.
|
|
413
273
|
*/
|
|
414
274
|
declare const LOCAL_COMMANDS: Set<string>;
|
|
415
|
-
/**
|
|
416
|
-
* Command semantics matrix (plan §19.3/M12): a LOCAL command line carrying a
|
|
417
|
-
* staged image placeholder is REJECTED — local commands are pure UI
|
|
418
|
-
* controls, never LLM prompts. AGENT-FACING input (plain prompts AND
|
|
419
|
-
* per-skill slash invocations like `/grilling`) SUPPORTS images: the skill
|
|
420
|
-
* wrapper builds its message through the same prepared-input path, so an
|
|
421
|
-
* image-bearing skill line is a real multimodal prompt (review finding 4).
|
|
422
|
-
* There is never a silent drop.
|
|
423
|
-
* @param parsed - the parsed slash command, undefined for a plain prompt.
|
|
424
|
-
* @param text - the submission text.
|
|
425
|
-
* @param store - the live draft store.
|
|
426
|
-
* @param isLocal - whether THIS LINE is a LOCAL (TUI-owned/UI) command; skill
|
|
427
|
-
* names answer false. Never derived from the name alone: a host command's
|
|
428
|
-
* input KIND decides which line it claims (see
|
|
429
|
-
* {@link commandIsLocalForAttachments}).
|
|
430
|
-
*/
|
|
431
|
-
declare function commandRejectsImages(parsed: {
|
|
432
|
-
name: string;
|
|
433
|
-
rawInput?: string;
|
|
434
|
-
} | undefined, text: string, store: DraftImageStoreLike, isLocal: boolean): boolean;
|
|
435
275
|
/**
|
|
436
276
|
* The STATIC host-owned command catalog (P1-04): the ownership sets
|
|
437
277
|
* (LOCAL_COMMANDS and SESSIONLESS_COMMANDS — the TUI's own local/UI command
|
|
@@ -454,15 +294,17 @@ declare const HOST_COMMAND_CATALOG: ReadonlySet<string>;
|
|
|
454
294
|
* @param name - the slash name.
|
|
455
295
|
* @param isSkillWrapper - the live skill-wrapper test (absent = none).
|
|
456
296
|
* @param isDynamicLocal - the live client-contribution test (absent = none).
|
|
457
|
-
* @param
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
463
|
-
*
|
|
297
|
+
* @param hostResolvesName - whether the AUTHORITATIVE HOST CATALOG resolves
|
|
298
|
+
* the NAME (PR5 supplement: derived from `hostCatalogResolves`, NEVER from
|
|
299
|
+
* the effective line claim — the claim-set union also carries this
|
|
300
|
+
* Client's own TUI registrations, so a self-claim must not disqualify the
|
|
301
|
+
* TUI's own local commands). A Host-resolved name is never a client-local
|
|
302
|
+
* line: when the catalog claims the line the host's own
|
|
303
|
+
* `input.attachments` declaration decides, and when it does not (an argued
|
|
304
|
+
* line of an execute-kind command) the line is an ordinary submission —
|
|
305
|
+
* never a same-named client contribution's.
|
|
464
306
|
*/
|
|
465
|
-
declare function isLocalCommandLine(name: string, isSkillWrapper: ((name: string) => boolean) | undefined, isDynamicLocal: ((name: string) => boolean) | undefined,
|
|
307
|
+
declare function isLocalCommandLine(name: string, isSkillWrapper: ((name: string) => boolean) | undefined, isDynamicLocal: ((name: string) => boolean) | undefined, hostResolvesName: boolean): boolean;
|
|
466
308
|
/**
|
|
467
309
|
* Whether one parsed line is the BARE slash token (DSH `matchEnter`'s `bare`:
|
|
468
310
|
* no input follows the name — trailing whitespace is not input). It is the
|
|
@@ -496,30 +338,16 @@ declare function isBareCommandLine(parsed: {
|
|
|
496
338
|
* @param parsed - the parsed slash command (undefined = plain prompt).
|
|
497
339
|
* @param isSkillWrapper - the live skill-wrapper test (absent = none).
|
|
498
340
|
* @param isDynamicLocal - the live client-contribution test (absent = none).
|
|
499
|
-
* @param
|
|
341
|
+
* @param hostResolvesName - whether the AUTHORITATIVE HOST CATALOG resolves
|
|
342
|
+
* the name (`hostCatalogResolves` — PR5 supplement: never derived from the
|
|
343
|
+
* effective line claim, whose union carries the Client's own TUI
|
|
344
|
+
* registrations).
|
|
500
345
|
* @returns whether the line is a local command line.
|
|
501
346
|
*/
|
|
502
347
|
declare function commandIsLocalForAttachments(parsed: {
|
|
503
348
|
name: string;
|
|
504
349
|
rawInput?: string;
|
|
505
|
-
} | undefined, isSkillWrapper: ((name: string) => boolean) | undefined, isDynamicLocal: ((name: string) => boolean) | undefined,
|
|
506
|
-
name: string;
|
|
507
|
-
rawInput?: string;
|
|
508
|
-
}) => HostCommandClaim | undefined) | undefined): boolean;
|
|
509
|
-
/**
|
|
510
|
-
* The TUI dispatch boundary's delivery resolution: the WEB composer policy
|
|
511
|
-
* ({@link resolveComposerDelivery}) applied to agent-facing input, with the
|
|
512
|
-
* TUI's own ownership terms on top. Pure so the dispatch gate (inside the
|
|
513
|
-
* runner closure) is testable headless.
|
|
514
|
-
* @param parsed - the parsed slash command, undefined for a plain prompt.
|
|
515
|
-
* @param running - whether the live agent reports running.
|
|
516
|
-
* @param gesture - the composer gesture that raised the submission.
|
|
517
|
-
* @param busyEnter - the persisted preference value (''/undefined = queue).
|
|
518
|
-
*/
|
|
519
|
-
declare function resolveSubmitDelivery(parsed: {
|
|
520
|
-
name: string;
|
|
521
|
-
rawInput?: string;
|
|
522
|
-
} | undefined, running: boolean, gesture: ComposerSubmitGesture, busyEnter: string | undefined): SubmitDelivery;
|
|
350
|
+
} | undefined, isSkillWrapper: ((name: string) => boolean) | undefined, isDynamicLocal: ((name: string) => boolean) | undefined, hostResolvesName: boolean): boolean;
|
|
523
351
|
/**
|
|
524
352
|
* Normalize an explicit `/skill <name> <args>` invocation to the skill's
|
|
525
353
|
* own slash line `/<name> <args>` (review finding 2). The harness's
|
|
@@ -560,6 +388,14 @@ declare function shouldConsumeAdvertisedMiss(execution: {
|
|
|
560
388
|
* @param text - the submitted draft.
|
|
561
389
|
*/
|
|
562
390
|
declare function isPlainExitPrompt(text: string): boolean;
|
|
391
|
+
//#endregion
|
|
392
|
+
//#region src/domain/shell/danger.d.ts
|
|
393
|
+
/**
|
|
394
|
+
* The destructive-shell predicate the approval dialog uses (kimi-inspired).
|
|
395
|
+
* Transport/UI-neutral: it answers exactly one question — whether one shell
|
|
396
|
+
* command matches a known destructive pattern — and owns nothing else.
|
|
397
|
+
* @module @xmoon76/dsh-pi-tui/domain/shell/danger
|
|
398
|
+
*/
|
|
563
399
|
/**
|
|
564
400
|
* Whether a shell command matches a destructive pattern. `rm` is treated
|
|
565
401
|
* specially: any spelling of recursive + force flags (`rm -rf`, `rm -r -f`,
|
|
@@ -567,37 +403,333 @@ declare function isPlainExitPrompt(text: string): boolean;
|
|
|
567
403
|
*/
|
|
568
404
|
declare function dangerCommand(command: string): boolean;
|
|
569
405
|
//#endregion
|
|
570
|
-
//#region src/
|
|
406
|
+
//#region src/domain/media/types.d.ts
|
|
571
407
|
/**
|
|
572
|
-
*
|
|
573
|
-
*
|
|
574
|
-
*
|
|
575
|
-
*
|
|
576
|
-
*
|
|
408
|
+
* Neutral media vocabulary shared by Client-local media capability, Direct
|
|
409
|
+
* application preparation, the transport-neutral prepared prompt and TUI
|
|
410
|
+
* presentation (TS8-C).
|
|
411
|
+
*
|
|
412
|
+
* Every shape here is a DETACHED structural fact — the accepted raster media
|
|
413
|
+
* types, one durable attachment reference and one deployment's image policy —
|
|
414
|
+
* that crosses several layers without carrying service, `Context`, `Agent` or
|
|
415
|
+
* Session authority. They deliberately mirror the `@deepseek-ai/dsh-attachment`
|
|
416
|
+
* shapes structurally, so no module needs a runtime dependency on that package
|
|
417
|
+
* (AGENTS.md decision 7).
|
|
418
|
+
*
|
|
419
|
+
* Host service interfaces (`saveImages`, `saveFileStream`, `resolveModelInfo`)
|
|
420
|
+
* MUST NOT enter this module: those are injected at the composition root and
|
|
421
|
+
* owned by the Direct application preparation.
|
|
422
|
+
* @module @xmoon76/dsh-pi-tui/domain/media/types
|
|
577
423
|
*/
|
|
578
|
-
/**
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
readonly
|
|
583
|
-
|
|
584
|
-
readonly
|
|
585
|
-
readonly
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
readonly message: string;
|
|
597
|
-
readonly details?: Readonly<Record<string, unknown>>;
|
|
598
|
-
};
|
|
424
|
+
/** Raster media types accepted by the TUI image intake. */
|
|
425
|
+
type ImageMediaType = 'image/png' | 'image/jpeg' | 'image/webp' | 'image/gif';
|
|
426
|
+
/** Structural subset of `ImageAttachmentRef`. */
|
|
427
|
+
interface ImageAttachmentRefLike {
|
|
428
|
+
readonly attachmentId: string;
|
|
429
|
+
readonly mediaType: ImageMediaType;
|
|
430
|
+
readonly bytes: number;
|
|
431
|
+
readonly width: number;
|
|
432
|
+
readonly height: number;
|
|
433
|
+
readonly name?: string;
|
|
434
|
+
}
|
|
435
|
+
//#endregion
|
|
436
|
+
//#region src/client/media/image/types.d.ts
|
|
437
|
+
/** Per-TUI draft image identity; only meaningful inside one TUI run. */
|
|
438
|
+
type DraftImageId = number;
|
|
439
|
+
/** Where a staged image's bytes came from. */
|
|
440
|
+
type DraftImageSource = {
|
|
441
|
+
readonly type: 'clipboard';
|
|
599
442
|
} | {
|
|
600
|
-
readonly
|
|
443
|
+
readonly type: 'path';
|
|
444
|
+
readonly path: string;
|
|
445
|
+
}
|
|
446
|
+
/** The image was pulled back from a queued message: its bytes are ALREADY
|
|
447
|
+
* durable with the harness (the recalled ref) — the draft holds no local
|
|
448
|
+
* copy and re-submitting reuses the ref instead of re-uploading. */
|
|
449
|
+
| {
|
|
450
|
+
readonly type: 'recalled';
|
|
451
|
+
};
|
|
452
|
+
/**
|
|
453
|
+
* One image staged in the editor draft. The draft holds the raw bytes so
|
|
454
|
+
* clipboard and path entries share one shape and a submit never depends on
|
|
455
|
+
* the source file still existing (plan §5.1). A RECALLED draft (pulled
|
|
456
|
+
* back from the queue) instead carries the durable `ImageAttachmentRef`
|
|
457
|
+
* and NO local bytes — the bytes stay in harness storage and re-submitting
|
|
458
|
+
* reuses the ref.
|
|
459
|
+
*/
|
|
460
|
+
interface DraftImage {
|
|
461
|
+
/** Per-TUI draft identity (the `#N` of the placeholder). */
|
|
462
|
+
readonly id: DraftImageId;
|
|
463
|
+
readonly kind: 'image';
|
|
464
|
+
readonly source: DraftImageSource;
|
|
465
|
+
/** Exact encoded bytes, held only for the draft lifetime. Empty for a
|
|
466
|
+
* recalled draft (its bytes live in harness storage). */
|
|
467
|
+
readonly bytes: Uint8Array;
|
|
468
|
+
readonly mediaType: ImageMediaType;
|
|
469
|
+
/** Intrinsic encoded width in pixels. */
|
|
470
|
+
readonly width: number;
|
|
471
|
+
/** Intrinsic encoded height in pixels. */
|
|
472
|
+
readonly height: number;
|
|
473
|
+
/** Exact encoded byte length (`bytes.byteLength` for local drafts; the
|
|
474
|
+
* durable ref's recorded `bytes` for recalled drafts). */
|
|
475
|
+
readonly byteLength: number;
|
|
476
|
+
/** Optional display name (basename for path sources), never a path. */
|
|
477
|
+
readonly name?: string;
|
|
478
|
+
/** The canonical editor placeholder text for this draft. */
|
|
479
|
+
readonly placeholder: string;
|
|
480
|
+
/** The durable ref this draft reuses on submit; present ONLY for
|
|
481
|
+
* recalled drafts (already-durable images are never re-uploaded). */
|
|
482
|
+
readonly recalledRef?: ImageAttachmentRefLike;
|
|
483
|
+
}
|
|
484
|
+
/** The store surface the placeholder expansion needs (structural). */
|
|
485
|
+
interface DraftImageStoreLike {
|
|
486
|
+
values(): readonly DraftImage[];
|
|
487
|
+
}
|
|
488
|
+
//#endregion
|
|
489
|
+
//#region src/app/surface/task-presentation.d.ts
|
|
490
|
+
declare function subagentJobTranscriptId(snapshot: unknown): string | undefined;
|
|
491
|
+
/**
|
|
492
|
+
* The Task Center row-selection disposition (plan §4.3/§4.4). A subagent
|
|
493
|
+
* transcript opens a session/viewer surface that REPLACES the browser; a
|
|
494
|
+
* Job row's detail keeps it mounted (the caller passes {@link openJobView}'s
|
|
495
|
+
* disposition). An UNKNOWN row — a stale panel selection after a live
|
|
496
|
+
* re-projection — also keeps the parent usable instead of dismissing it.
|
|
497
|
+
*/
|
|
498
|
+
declare function taskRowSelectionDisposition(row: {
|
|
499
|
+
readonly kind: 'job' | 'subagent';
|
|
500
|
+
} | undefined, jobDetail: 'close' | 'keep-open'): 'close' | 'keep-open';
|
|
501
|
+
/** Viewer body for a subagent job with no uniquely matched child. */
|
|
502
|
+
declare function subagentJobViewHint(status: string, detail: string | undefined): string;
|
|
503
|
+
//#endregion
|
|
504
|
+
//#region src/app/surface/compaction-presentation.d.ts
|
|
505
|
+
/**
|
|
506
|
+
* The compaction/context presentation module (A4-7, plan §16/§27): the pure
|
|
507
|
+
* compaction/context presentation folds consumed by the surface routing.
|
|
508
|
+
*
|
|
509
|
+
* These are the PURE presentation folds the `session/event` routing applies:
|
|
510
|
+
* compaction lifecycle pairing, the matched-settle surface effects, the
|
|
511
|
+
* turn-boundary busy rule, the context re-measure classification, and the
|
|
512
|
+
* resumed-session-log bootstrap folds (`workingFromLog`, `compactingFromLog`).
|
|
513
|
+
* They read no Host identity and no persistence, so they are an application-owned
|
|
514
|
+
* surface presentation module under `app/surface/**` (TS8-F5 moved them out of
|
|
515
|
+
* the top-level root).
|
|
516
|
+
*
|
|
517
|
+
* `src/index.ts` re-exports them unchanged to keep the public entry point
|
|
518
|
+
* byte-compatible (the published package and the regression suites import them
|
|
519
|
+
* from the package root).
|
|
520
|
+
*
|
|
521
|
+
* @module @xmoon76/dsh-pi-tui/app/surface/compaction-presentation
|
|
522
|
+
*/
|
|
523
|
+
/** The canonical compaction phase the mounted surface renders (TS8-F5 moved
|
|
524
|
+
* the union out of the tui-app.ts stable root; the root type-re-exports it). */
|
|
525
|
+
type CompactionPhase = 'idle' | 'summarizing' | 'applying';
|
|
526
|
+
/** One fold of a compaction lifecycle event over the in-flight compaction
|
|
527
|
+
* state. Pure (the routing applies the returned surface effects):
|
|
528
|
+
* dsh-compaction is not a peer, so the event is read structurally. */
|
|
529
|
+
interface CompactionFold {
|
|
530
|
+
/** The updated in-flight compaction id (the newest start wins). */
|
|
531
|
+
id: string | undefined;
|
|
532
|
+
/** compaction/start: the compacting flag turns ON (footer/working row). */
|
|
533
|
+
active: boolean;
|
|
534
|
+
/** A MATCHED compaction/end: the compacting flag turns OFF and busy is
|
|
535
|
+
* re-derived from the turn log (a stale end never clears a newer
|
|
536
|
+
* compaction's state). */
|
|
537
|
+
clear: boolean;
|
|
538
|
+
/** The compaction phase the event implies: compaction/start →
|
|
539
|
+
* 'summarizing', a MATCHED compaction/summary → 'applying'. Undefined
|
|
540
|
+
* when the event does not advance the phase (a stale summary, any
|
|
541
|
+
* compaction/end — the settle clears via {@link clear}). */
|
|
542
|
+
phase?: Exclude<CompactionPhase, 'idle'>;
|
|
543
|
+
/** The settle notification for compaction/end, when one fires. */
|
|
544
|
+
notify: {
|
|
545
|
+
text: string;
|
|
546
|
+
kind: 'info' | 'error';
|
|
547
|
+
} | undefined;
|
|
548
|
+
}
|
|
549
|
+
/** Fold one compaction lifecycle event over the in-flight state. */
|
|
550
|
+
declare function foldCompactionEvent(state: {
|
|
551
|
+
id: string | undefined;
|
|
552
|
+
}, event: {
|
|
553
|
+
type: string;
|
|
554
|
+
data: {
|
|
555
|
+
compactionId?: unknown;
|
|
556
|
+
error?: unknown;
|
|
557
|
+
};
|
|
558
|
+
}): CompactionFold;
|
|
559
|
+
/** The minimal compaction-settle surface the routing passes in — STRUCTURAL
|
|
560
|
+
* on purpose: referencing the full {@link TuiApp} class from a public
|
|
561
|
+
* export would inline the whole surface (and its internal registry/
|
|
562
|
+
* presentation dependencies) into the published declaration bundle. The
|
|
563
|
+
* settle contract only needs the three phase/busy/working setters. */
|
|
564
|
+
interface CompactionSettleSurface {
|
|
565
|
+
setCompactionPhase(phase: 'idle'): void;
|
|
566
|
+
setBusy(busy: boolean): void;
|
|
567
|
+
setWorking(busy: boolean): void;
|
|
568
|
+
}
|
|
569
|
+
/** The UI side effects of a MATCHED compaction settle: clear the phase,
|
|
570
|
+
* hand the working row back to the turn state, and re-measure the session
|
|
571
|
+
* surface so the footer context reflects the compacted log IMMEDIATELY —
|
|
572
|
+
* the next step/start or turn/end would otherwise delay the refresh.
|
|
573
|
+
* Exported as a seam so the settle contract is testable without a full
|
|
574
|
+
* runner driver (the firehose closure is not). */
|
|
575
|
+
declare function settleCompactionSurface(app: CompactionSettleSurface, refreshStatus: () => void, busyNow: boolean): void;
|
|
576
|
+
/** The busy flag after a turn-boundary event: a turn end must NOT clear
|
|
577
|
+
* the busy state while a compaction is still in flight — an interrupted
|
|
578
|
+
* turn can close (turn/end) before its compaction settles, and the
|
|
579
|
+
* single-Esc cancel must stay armed until compaction/end. */
|
|
580
|
+
declare function busyAfterTurnBoundary(eventType: 'turn/start' | 'turn/end', compacting: boolean): boolean;
|
|
581
|
+
/** PR D2 test seam: whether a session event type marks the model-visible
|
|
582
|
+
* context dirty (re-measure through the SessionReader port) or only
|
|
583
|
+
* repaints cheaply (cached measurement). The firehose routes every event
|
|
584
|
+
* through this classification — the single source of truth for the
|
|
585
|
+
* status/measurement split. `compaction/end` is classified 'measure' but
|
|
586
|
+
* the firehose deliberately SKIPS it here: a matched compaction settle
|
|
587
|
+
* re-measures through the fold-outcome path (settleCompactionSurface), so
|
|
588
|
+
* a STALE compaction/end can never trigger a measurement. */
|
|
589
|
+
declare function contextRefreshKind(eventType: string): 'measure' | 'cheap';
|
|
590
|
+
/**
|
|
591
|
+
* The in-flight compaction state a resumed session log implies: the newest
|
|
592
|
+
* compaction bracket decides. A `session/end-seed` boundary makes any
|
|
593
|
+
* EARLIER unmatched `compaction/start` STALE — the upstream invariant
|
|
594
|
+
* (inheritedOrphanStartSeqs) treats seed compactions that never settled
|
|
595
|
+
* inside the seed as abandoned, so they must not re-arm the compacting
|
|
596
|
+
* surface on resume.
|
|
597
|
+
*/
|
|
598
|
+
declare function compactingFromLog(events: readonly {
|
|
599
|
+
type: unknown;
|
|
600
|
+
data?: unknown;
|
|
601
|
+
}[]): {
|
|
602
|
+
active: boolean;
|
|
603
|
+
id: string | undefined;
|
|
604
|
+
};
|
|
605
|
+
//#endregion
|
|
606
|
+
//#region src/app/submission/pending-input.d.ts
|
|
607
|
+
/** One semantic pending-input item as the queue mirror sees it. */
|
|
608
|
+
interface QueueInboxMessage {
|
|
609
|
+
readonly id: string;
|
|
610
|
+
readonly content: readonly ContentBlock[];
|
|
611
|
+
}
|
|
612
|
+
//#endregion
|
|
613
|
+
//#region src/app/surface/pending-presentation.d.ts
|
|
614
|
+
/** One semantic queued pending-input row for the queue pane. */
|
|
615
|
+
interface QueueItem {
|
|
616
|
+
/** The pending message id (agent inbox identity), or a local request id. */
|
|
617
|
+
id: string;
|
|
618
|
+
/** The message text, single-line display form. */
|
|
619
|
+
text: string;
|
|
620
|
+
/** next-turn followup vs next-step steer. */
|
|
621
|
+
mode: 'followup' | 'steer';
|
|
622
|
+
/** The correlation identity (authoritative rpc id or local request id). */
|
|
623
|
+
rpcId?: string;
|
|
624
|
+
/** A client-local echo not yet backed by an authoritative occurrence. */
|
|
625
|
+
local?: boolean;
|
|
626
|
+
}
|
|
627
|
+
/** The queue-pane rows for one semantic pending-input batch. */
|
|
628
|
+
interface QueueFoldResult {
|
|
629
|
+
readonly rows: QueueItem[];
|
|
630
|
+
}
|
|
631
|
+
/** Build queue-pane rows from semantic pending-input occurrences, preserving
|
|
632
|
+
* their order and content without inspecting backend-specific metadata. */
|
|
633
|
+
declare function foldQueueRows(messages: readonly QueueInboxMessage[], mode: 'followup' | 'steer'): QueueFoldResult;
|
|
634
|
+
//#endregion
|
|
635
|
+
//#region src/tui-app.d.ts
|
|
636
|
+
/**
|
|
637
|
+
* The WEB composer submit gestures (DSH `ComposerSubmitGesture`): plain
|
|
638
|
+
* Enter, or the Cmd/Ctrl-accelerated chord. The busy-Enter policy resolves
|
|
639
|
+
* each to a delivery mode — plain Enter to the preferred mode, the
|
|
640
|
+
* accelerated chord to its OPPOSITE — so the chord is never a fixed mode.
|
|
641
|
+
*/
|
|
642
|
+
type ComposerSubmitGesture = 'enter' | 'accelerated';
|
|
643
|
+
//#endregion
|
|
644
|
+
//#region src/commands.d.ts
|
|
645
|
+
/**
|
|
646
|
+
* The effective mode ONE submission resolved at the submit boundary: whether
|
|
647
|
+
* an agent-facing delivery steers into the running turn or queues behind it
|
|
648
|
+
* (web `ComposerSubmissionPolicy` parity — an idle agent queues, plain Enter
|
|
649
|
+
* takes the preference, and the accelerated chord takes its OPPOSITE).
|
|
650
|
+
*
|
|
651
|
+
* It is a property of the GESTURE, not of the persisted settings: a one-shot
|
|
652
|
+
* gesture exists only inside the dispatch that resolved it, so every
|
|
653
|
+
* downstream consumer (the TUI skill delivery) accepts this value instead of
|
|
654
|
+
* re-deriving the mode from `busyEnter`.
|
|
655
|
+
*/
|
|
656
|
+
type SubmitDelivery = 'steer' | 'queue';
|
|
657
|
+
//#endregion
|
|
658
|
+
//#region src/app/submission/command-policy.d.ts
|
|
659
|
+
/**
|
|
660
|
+
* Command semantics matrix (plan §19.3/M12): a LOCAL command line carrying a
|
|
661
|
+
* staged image placeholder is REJECTED — local commands are pure UI
|
|
662
|
+
* controls, never LLM prompts. AGENT-FACING input (plain prompts AND
|
|
663
|
+
* per-skill slash invocations like `/grilling`) SUPPORTS images: the skill
|
|
664
|
+
* wrapper builds its message through the same prepared-input path, so an
|
|
665
|
+
* image-bearing skill line is a real multimodal prompt (review finding 4).
|
|
666
|
+
* There is never a silent drop.
|
|
667
|
+
* @param parsed - the parsed slash command, undefined for a plain prompt.
|
|
668
|
+
* @param text - the submission text.
|
|
669
|
+
* @param store - the live draft store.
|
|
670
|
+
* @param isLocal - whether THIS LINE is a LOCAL (TUI-owned/UI) command; skill
|
|
671
|
+
* names answer false. Never derived from the name alone: a host command's
|
|
672
|
+
* input KIND decides which line it claims (see
|
|
673
|
+
* {@link commandIsLocalForAttachments}).
|
|
674
|
+
*/
|
|
675
|
+
declare function commandRejectsImages(parsed: {
|
|
676
|
+
name: string;
|
|
677
|
+
rawInput?: string;
|
|
678
|
+
} | undefined, text: string, store: DraftImageStoreLike, isLocal: boolean): boolean;
|
|
679
|
+
/**
|
|
680
|
+
* The TUI dispatch boundary's delivery resolution: the WEB composer policy
|
|
681
|
+
* ({@link resolveComposerDelivery}) applied to agent-facing input, with the
|
|
682
|
+
* TUI's own ownership terms on top. Pure so the dispatch gate (inside the
|
|
683
|
+
* runner closure) is testable headless.
|
|
684
|
+
* @param parsed - the parsed slash command, undefined for a plain prompt.
|
|
685
|
+
* @param running - whether the live agent reports running.
|
|
686
|
+
* @param gesture - the composer gesture that raised the submission.
|
|
687
|
+
* @param busyEnter - the persisted preference value (''/undefined = queue).
|
|
688
|
+
* @param isTuiLocalLine - whether the line is a TUI-LOCAL command line by
|
|
689
|
+
* the §D3 line authority ({@link isLocalCommandLine}'s order: a
|
|
690
|
+
* HOST-RESOLVED name — claimed or merely resolved — is never local). The
|
|
691
|
+
* caller derives it once and shares it with every gate, so an argued
|
|
692
|
+
* `/export foo` of an execute-kind Host command follows the ORDINARY
|
|
693
|
+
* queue/steer busy policy instead of a local-command placeholder.
|
|
694
|
+
* Absent = fall back to the legacy LOCAL_COMMANDS set (callers that have
|
|
695
|
+
* no host view yet, e.g. the pre-parse echo path).
|
|
696
|
+
*/
|
|
697
|
+
declare function resolveSubmitDelivery(parsed: {
|
|
698
|
+
name: string;
|
|
699
|
+
rawInput?: string;
|
|
700
|
+
} | undefined, running: boolean, gesture: ComposerSubmitGesture, busyEnter: string | undefined, isTuiLocalLine?: boolean): SubmitDelivery;
|
|
701
|
+
//#endregion
|
|
702
|
+
//#region src/app/session/interrupt.d.ts
|
|
703
|
+
/**
|
|
704
|
+
* The live-turn interrupt helper (web Stop parity): abort the current
|
|
705
|
+
* turn/tool run while PRESERVING the pending queue. Kept out of the
|
|
706
|
+
* composition root so the rule is testable headless, and its structural
|
|
707
|
+
* faces keep the internal runtime port module out of the published entry.
|
|
708
|
+
* @module @xmoon76/dsh-pi-tui/app/session/interrupt
|
|
709
|
+
*/
|
|
710
|
+
/** Public settlement shape for the interrupt helper. Kept local so the
|
|
711
|
+
* entry-point declaration does not expose the internal runtime port module. */
|
|
712
|
+
type InterruptWriteOutcome = {
|
|
713
|
+
readonly kind: 'committed';
|
|
714
|
+
readonly value: undefined;
|
|
715
|
+
} | {
|
|
716
|
+
readonly kind: 'rejected';
|
|
717
|
+
readonly error: {
|
|
718
|
+
readonly code: string;
|
|
719
|
+
readonly message: string;
|
|
720
|
+
readonly details?: Readonly<Record<string, unknown>>;
|
|
721
|
+
};
|
|
722
|
+
} | {
|
|
723
|
+
readonly kind: 'cancelled';
|
|
724
|
+
} | {
|
|
725
|
+
readonly kind: 'indeterminate';
|
|
726
|
+
readonly error: {
|
|
727
|
+
readonly code: string;
|
|
728
|
+
readonly message: string;
|
|
729
|
+
readonly details?: Readonly<Record<string, unknown>>;
|
|
730
|
+
};
|
|
731
|
+
} | {
|
|
732
|
+
readonly kind: 'unsupported';
|
|
601
733
|
readonly reason: string;
|
|
602
734
|
};
|
|
603
735
|
/** The live-agent surface {@link interruptAgent} needs (structural — the
|
|
@@ -640,7 +772,7 @@ interface InterruptWriterLike {
|
|
|
640
772
|
*/
|
|
641
773
|
declare function interruptAgent(agent: InterruptAgentLike | undefined, writer: InterruptWriterLike): Promise<InterruptWriteOutcome>;
|
|
642
774
|
//#endregion
|
|
643
|
-
//#region src/
|
|
775
|
+
//#region src/app/surface/viewer-policy.d.ts
|
|
644
776
|
/** One unsettled subagent delegation, in tool/call order. */
|
|
645
777
|
interface PendingSubagentCall {
|
|
646
778
|
readonly callId: string;
|
|
@@ -713,153 +845,66 @@ declare function viewerActionCapability(action: TuiAction, viewer: {
|
|
|
713
845
|
*/
|
|
714
846
|
declare function matchPendingSubagentCall(pending: PendingSubagentCall[], label: string | undefined): PendingSubagentCall | undefined;
|
|
715
847
|
//#endregion
|
|
716
|
-
//#region src/
|
|
717
|
-
/** One semantic pending-input item as the queue mirror sees it. */
|
|
718
|
-
interface QueueInboxMessage {
|
|
719
|
-
readonly id: string;
|
|
720
|
-
readonly content: readonly ContentBlock[];
|
|
721
|
-
}
|
|
722
|
-
/** The queue-pane rows for one semantic pending-input batch. */
|
|
723
|
-
interface QueueFoldResult {
|
|
724
|
-
readonly rows: QueueItem[];
|
|
725
|
-
}
|
|
726
|
-
/** Build queue-pane rows from semantic pending-input occurrences, preserving
|
|
727
|
-
* their order and content without inspecting backend-specific metadata. */
|
|
728
|
-
declare function foldQueueRows(messages: readonly QueueInboxMessage[], mode: 'followup' | 'steer'): QueueFoldResult;
|
|
729
|
-
//#endregion
|
|
730
|
-
//#region src/compaction-presentation.d.ts
|
|
731
|
-
/** One fold of a compaction lifecycle event over the in-flight compaction
|
|
732
|
-
* state. Pure (the routing applies the returned surface effects):
|
|
733
|
-
* dsh-compaction is not a peer, so the event is read structurally. */
|
|
734
|
-
interface CompactionFold {
|
|
735
|
-
/** The updated in-flight compaction id (the newest start wins). */
|
|
736
|
-
id: string | undefined;
|
|
737
|
-
/** compaction/start: the compacting flag turns ON (footer/working row). */
|
|
738
|
-
active: boolean;
|
|
739
|
-
/** A MATCHED compaction/end: the compacting flag turns OFF and busy is
|
|
740
|
-
* re-derived from the turn log (a stale end never clears a newer
|
|
741
|
-
* compaction's state). */
|
|
742
|
-
clear: boolean;
|
|
743
|
-
/** The compaction phase the event implies: compaction/start →
|
|
744
|
-
* 'summarizing', a MATCHED compaction/summary → 'applying'. Undefined
|
|
745
|
-
* when the event does not advance the phase (a stale summary, any
|
|
746
|
-
* compaction/end — the settle clears via {@link clear}). */
|
|
747
|
-
phase?: Exclude<CompactionPhase, 'idle'>;
|
|
748
|
-
/** The settle notification for compaction/end, when one fires. */
|
|
749
|
-
notify: {
|
|
750
|
-
text: string;
|
|
751
|
-
kind: 'info' | 'error';
|
|
752
|
-
} | undefined;
|
|
753
|
-
}
|
|
754
|
-
/** Fold one compaction lifecycle event over the in-flight state. */
|
|
755
|
-
declare function foldCompactionEvent(state: {
|
|
756
|
-
id: string | undefined;
|
|
757
|
-
}, event: {
|
|
758
|
-
type: string;
|
|
759
|
-
data: {
|
|
760
|
-
compactionId?: unknown;
|
|
761
|
-
error?: unknown;
|
|
762
|
-
};
|
|
763
|
-
}): CompactionFold;
|
|
764
|
-
/** The minimal compaction-settle surface the routing passes in — STRUCTURAL
|
|
765
|
-
* on purpose: referencing the full {@link TuiApp} class from a public
|
|
766
|
-
* export would inline the whole surface (and its internal registry/
|
|
767
|
-
* presentation dependencies) into the published declaration bundle. The
|
|
768
|
-
* settle contract only needs the three phase/busy/working setters. */
|
|
769
|
-
interface CompactionSettleSurface {
|
|
770
|
-
setCompactionPhase(phase: 'idle'): void;
|
|
771
|
-
setBusy(busy: boolean): void;
|
|
772
|
-
setWorking(busy: boolean): void;
|
|
773
|
-
}
|
|
774
|
-
/** The UI side effects of a MATCHED compaction settle: clear the phase,
|
|
775
|
-
* hand the working row back to the turn state, and re-measure the session
|
|
776
|
-
* surface so the footer context reflects the compacted log IMMEDIATELY —
|
|
777
|
-
* the next step/start or turn/end would otherwise delay the refresh.
|
|
778
|
-
* Exported as a seam so the settle contract is testable without a full
|
|
779
|
-
* runner driver (the firehose closure is not). */
|
|
780
|
-
declare function settleCompactionSurface(app: CompactionSettleSurface, refreshStatus: () => void, busyNow: boolean): void;
|
|
781
|
-
/** The busy flag after a turn-boundary event: a turn end must NOT clear
|
|
782
|
-
* the busy state while a compaction is still in flight — an interrupted
|
|
783
|
-
* turn can close (turn/end) before its compaction settles, and the
|
|
784
|
-
* single-Esc cancel must stay armed until compaction/end. */
|
|
785
|
-
declare function busyAfterTurnBoundary(eventType: 'turn/start' | 'turn/end', compacting: boolean): boolean;
|
|
786
|
-
/** PR D2 test seam: whether a session event type marks the model-visible
|
|
787
|
-
* context dirty (re-measure through the SessionReader port) or only
|
|
788
|
-
* repaints cheaply (cached measurement). The firehose routes every event
|
|
789
|
-
* through this classification — the single source of truth for the
|
|
790
|
-
* status/measurement split. `compaction/end` is classified 'measure' but
|
|
791
|
-
* the firehose deliberately SKIPS it here: a matched compaction settle
|
|
792
|
-
* re-measures through the fold-outcome path (settleCompactionSurface), so
|
|
793
|
-
* a STALE compaction/end can never trigger a measurement. */
|
|
794
|
-
declare function contextRefreshKind(eventType: string): 'measure' | 'cheap';
|
|
795
|
-
/**
|
|
796
|
-
* The in-flight compaction state a resumed session log implies: the newest
|
|
797
|
-
* compaction bracket decides. A `session/end-seed` boundary makes any
|
|
798
|
-
* EARLIER unmatched `compaction/start` STALE — the upstream invariant
|
|
799
|
-
* (inheritedOrphanStartSeqs) treats seed compactions that never settled
|
|
800
|
-
* inside the seed as abandoned, so they must not re-arm the compacting
|
|
801
|
-
* surface on resume.
|
|
802
|
-
*/
|
|
803
|
-
declare function compactingFromLog(events: readonly {
|
|
804
|
-
type: unknown;
|
|
805
|
-
data?: unknown;
|
|
806
|
-
}[]): {
|
|
807
|
-
active: boolean;
|
|
808
|
-
id: string | undefined;
|
|
809
|
-
};
|
|
810
|
-
//#endregion
|
|
811
|
-
//#region src/dsh-profile.d.ts
|
|
848
|
+
//#region src/client/launcher/profile.d.ts
|
|
812
849
|
/**
|
|
813
|
-
* The DSH launcher PROFILE
|
|
850
|
+
* The Client-local DSH launcher PROFILE reads: the `--profile` argv scrape and
|
|
851
|
+
* the interactive-quit resume hint.
|
|
814
852
|
*
|
|
815
853
|
* Deliberately NOT part of `src/startup.ts`: the startup row is a
|
|
816
854
|
* zero-dependency island that must not share a bundle chunk with the runner,
|
|
817
|
-
* so these runner-side helpers live in their own module
|
|
818
|
-
*
|
|
819
|
-
*
|
|
855
|
+
* so these runner-side helpers live in their own module. The authoritative
|
|
856
|
+
* Host profile identity (`hostRunningProfile`) is application bootstrap
|
|
857
|
+
* ownership (`app/bootstrap/profile.ts`) and consumes this argv fallback.
|
|
858
|
+
* @module @xmoon76/dsh-pi-tui/client/launcher/profile
|
|
820
859
|
*/
|
|
821
860
|
/**
|
|
822
861
|
* The dsh profile named by the `--profile` flag in `argv`, in both spellings.
|
|
823
862
|
* This is the ARGV-ONLY fallback: it cannot see the positional `dsh <name>`
|
|
824
863
|
* launch form, because the launcher consumes that bare name by synthesizing
|
|
825
864
|
* `['--profile', ...argv]` for its OWN commander parse and leaves
|
|
826
|
-
* `process.argv` untouched. Prefer
|
|
827
|
-
*
|
|
865
|
+
* `process.argv` untouched. Prefer `hostRunningProfile`, which reads the Host's
|
|
866
|
+
* profile identity instead of scraping the command line.
|
|
828
867
|
* @param argv - the process argument vector.
|
|
829
868
|
* @param fallback - the default profile.
|
|
830
869
|
*/
|
|
831
870
|
declare function runningProfile(argv?: readonly string[], fallback?: string): string;
|
|
871
|
+
/**
|
|
872
|
+
* The interactive-quit resume hint (pi parity): `dsh --profile <p>
|
|
873
|
+
* --session <id>`, printed after the terminal restores so the user can
|
|
874
|
+
* re-enter the session later. Returns undefined when there is no session
|
|
875
|
+
* to resume (deferred start never created one).
|
|
876
|
+
* @param profile - the running profile (`hostRunningProfile`).
|
|
877
|
+
* @param sessionId - the live session id.
|
|
878
|
+
* @returns the resume command line, or undefined without a session.
|
|
879
|
+
*/
|
|
880
|
+
declare function resumeCommand(profile: string, sessionId: string): string | undefined;
|
|
881
|
+
//#endregion
|
|
882
|
+
//#region src/app/bootstrap/profile.d.ts
|
|
883
|
+
/**
|
|
884
|
+
* The authoritative running-profile read for this process — the official Host
|
|
885
|
+
* `profileContext.name` when it is composed, else the Client-local argv scrape
|
|
886
|
+
* (`client/launcher/profile.ts`).
|
|
887
|
+
*
|
|
888
|
+
* `profileContext.name` is the launcher's own profile identity, so it is
|
|
889
|
+
* correct for EVERY launch form: `--profile <name>`, `--profile=<name>`, the
|
|
890
|
+
* positional `dsh <name>`, and `--from-default-profile <name>`. The argv scrape
|
|
891
|
+
* only knows the flag form, which is why it is the fallback for a profile-less
|
|
892
|
+
* mount (tests, an embedded surface) rather than the primary source. Bootstrap
|
|
893
|
+
* composition ownership: it reads one Host context service and nothing else.
|
|
894
|
+
* @module @xmoon76/dsh-pi-tui/app/bootstrap/profile
|
|
895
|
+
*/
|
|
832
896
|
/** The one context read {@link hostRunningProfile} needs (a cordis Context satisfies it). */
|
|
833
897
|
interface ProfileContextReadLike {
|
|
834
898
|
get(name: string): unknown;
|
|
835
899
|
}
|
|
836
900
|
/**
|
|
837
|
-
* The profile this process actually runs
|
|
838
|
-
* `profileContext.name` when it is composed, else {@link runningProfile}'s
|
|
839
|
-
* argv scrape.
|
|
840
|
-
*
|
|
841
|
-
* `profileContext.name` is the launcher's own profile identity, so it is
|
|
842
|
-
* correct for EVERY launch form: `--profile <name>`, `--profile=<name>`, the
|
|
843
|
-
* positional `dsh <name>`, and `--from-default-profile <name>`. The argv
|
|
844
|
-
* scrape only knows the flag form, which is why it is the fallback for a
|
|
845
|
-
* profile-less mount (tests, an embedded surface) rather than the primary
|
|
846
|
-
* source.
|
|
901
|
+
* The profile this process actually runs.
|
|
847
902
|
* @param ctx - the plugin context (or any structural `get`-only stand-in).
|
|
848
903
|
* @param argv - the process argument vector for the fallback path.
|
|
849
904
|
* @param fallback - the default profile for the fallback path.
|
|
850
905
|
* @returns the running profile name.
|
|
851
906
|
*/
|
|
852
907
|
declare function hostRunningProfile(ctx: ProfileContextReadLike, argv?: readonly string[], fallback?: string): string;
|
|
853
|
-
/**
|
|
854
|
-
* The interactive-quit resume hint (pi parity): `dsh --profile <p>
|
|
855
|
-
* --session <id>`, printed after the terminal restores so the user can
|
|
856
|
-
* re-enter the session later. Returns undefined when there is no session
|
|
857
|
-
* to resume (deferred start never created one).
|
|
858
|
-
* @param profile - the running profile ({@link hostRunningProfile}).
|
|
859
|
-
* @param sessionId - the live session id.
|
|
860
|
-
* @returns the resume command line, or undefined without a session.
|
|
861
|
-
*/
|
|
862
|
-
declare function resumeCommand(profile: string, sessionId: string): string | undefined;
|
|
863
908
|
//#endregion
|
|
864
909
|
//#region src/index.d.ts
|
|
865
910
|
/** Stable Cordis plugin name. */
|
|
@@ -872,7 +917,7 @@ declare const inject: string[];
|
|
|
872
917
|
* The public declaration stays here (A5a review P1): `liveAgent` keeps the Host
|
|
873
918
|
* `Agent` type it has always had, so consumers that READ the property keep
|
|
874
919
|
* compiling. The implementation consumes the structural
|
|
875
|
-
* `SurfaceCatalogResolutionOptions` in `
|
|
920
|
+
* `SurfaceCatalogResolutionOptions` in `app/direct/initial-catalog.ts`.
|
|
876
921
|
*/
|
|
877
922
|
interface ResolveInitialCatalogOptions {
|
|
878
923
|
/** The resumed live agent, if any (prefetch path). */
|
|
@@ -896,12 +941,21 @@ interface ResolveInitialCatalogOptions {
|
|
|
896
941
|
* prefetches the resumed agent's effective catalog; the deferred start reads the
|
|
897
942
|
* cold HUMAN SKILL catalog through the preset's STANDING SCOPE — no Agent, no
|
|
898
943
|
* session, no turn — so the first input sees human-invocable skills without any
|
|
899
|
-
* durable side effect. The implementation and its failure taxonomy
|
|
900
|
-
* `
|
|
944
|
+
* durable side effect. The implementation and its pre-mount failure taxonomy
|
|
945
|
+
* live in `app/direct/initial-catalog.ts`.
|
|
901
946
|
* @param options - injected dependencies (see {@link ResolveInitialCatalogOptions}).
|
|
902
947
|
* @returns the snapshot / skill catalog to install and an optional notice.
|
|
903
948
|
*/
|
|
904
949
|
declare function resolveInitialCatalog(options: ResolveInitialCatalogOptions): Promise<InitialCatalogResolution>;
|
|
950
|
+
/**
|
|
951
|
+
* The PUBLIC structural shape of the shared mutable display authority. The
|
|
952
|
+
* canonical owner is `src/domain/display/preset.ts` (`DisplayState`); the
|
|
953
|
+
* published `composeAgent` signature stays STRUCTURAL so the internal source
|
|
954
|
+
* path never leaks into the declaration bundle (TS8-D).
|
|
955
|
+
*/
|
|
956
|
+
type DisplayState = {
|
|
957
|
+
preset: 'focus' | 'compact' | 'full';
|
|
958
|
+
};
|
|
905
959
|
/** One agent's preset composition: the id to record and the setup that installs it. */
|
|
906
960
|
interface AgentComposition {
|
|
907
961
|
/** Preset id for the session header, absent when the deployment composes no roster. */
|