@xmoon76/dsh-pi-tui 0.4.9 → 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 +75 -13
- package/README.md +65 -11
- package/cordis.patch.yml +13 -0
- package/dist/builtins.mjs +11 -15
- 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 +581 -502
- package/dist/index.mjs +74028 -1
- package/dist/{public-types-YbB5Rhku.d.mts → public-types-BEjj7FEb.d.mts} +39 -5
- package/dist/runtime-CcQyhIvI.mjs +6147 -0
- package/dist/{startup-xTIOW90U.mjs → startup-CmTYVTGC.mjs} +28 -14
- package/dist/startup.d.mts +7 -5
- 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 +141 -116
- package/dist/keybinding-registry-CjbtRmhd.d.mts +0 -1
- package/dist/src-BAwPimrH.mjs +0 -83282
package/dist/index.d.mts
CHANGED
|
@@ -1,107 +1,20 @@
|
|
|
1
|
-
import { H as TuiAction } from "./public-types-
|
|
2
|
-
import z from "@deepseek-ai/schemastery";
|
|
3
|
-
import { Agent, ModelSelectionRef } from "@deepseek-ai/dsh-agent";
|
|
4
|
-
import { ContentBlock } from "@deepseek-ai/dsh-llm";
|
|
1
|
+
import { H as TuiAction } from "./public-types-BEjj7FEb.mjs";
|
|
5
2
|
import { SessionId } from "@deepseek-ai/dsh-session";
|
|
3
|
+
import { ContentBlock } from "@deepseek-ai/dsh-llm";
|
|
6
4
|
import { Context, Volatile } from "@deepseek-ai/cordis";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
readonly height: number;
|
|
15
|
-
readonly name?: string;
|
|
16
|
-
}
|
|
17
|
-
//#endregion
|
|
18
|
-
//#region src/image/types.d.ts
|
|
19
|
-
/**
|
|
20
|
-
* Image draft vocabulary for the TUI input pipeline (plan M1).
|
|
21
|
-
*
|
|
22
|
-
* The draft layer is TUI-owned: it stages clipboard/file bytes until a
|
|
23
|
-
* submission turns them into durable `ImageAttachmentRef`s through the dsh
|
|
24
|
-
* attachment service. Nothing in this module persists; the durable boundary
|
|
25
|
-
* is the harness's `ctx.attachments.saveImages()`.
|
|
26
|
-
*
|
|
27
|
-
* The media-type union mirrors `@deepseek-ai/dsh-attachment`'s
|
|
28
|
-
* `ImageMediaType` structurally, so drafts flow into the harness without a
|
|
29
|
-
* runtime dependency on the attachment package (AGENTS.md decision 7:
|
|
30
|
-
* structural typing for dsh services).
|
|
31
|
-
* @module @xmoon76/dsh-pi-tui/image/types
|
|
32
|
-
*/
|
|
33
|
-
/** Raster media types accepted by the TUI image intake. */
|
|
34
|
-
type ImageMediaType = 'image/png' | 'image/jpeg' | 'image/webp' | 'image/gif';
|
|
35
|
-
/** Per-TUI draft image identity; only meaningful inside one TUI run. */
|
|
36
|
-
type DraftImageId = number;
|
|
37
|
-
/** Where a staged image's bytes came from. */
|
|
38
|
-
type DraftImageSource = {
|
|
39
|
-
readonly type: 'clipboard';
|
|
40
|
-
} | {
|
|
41
|
-
readonly type: 'path';
|
|
42
|
-
readonly path: string;
|
|
43
|
-
}
|
|
44
|
-
/** The image was pulled back from a queued message: its bytes are ALREADY
|
|
45
|
-
* durable with the harness (the recalled ref) — the draft holds no local
|
|
46
|
-
* copy and re-submitting reuses the ref instead of re-uploading. */
|
|
47
|
-
| {
|
|
48
|
-
readonly type: 'recalled';
|
|
49
|
-
};
|
|
50
|
-
/**
|
|
51
|
-
* One image staged in the editor draft. The draft holds the raw bytes so
|
|
52
|
-
* clipboard and path entries share one shape and a submit never depends on
|
|
53
|
-
* the source file still existing (plan §5.1). A RECALLED draft (pulled
|
|
54
|
-
* back from the queue) instead carries the durable `ImageAttachmentRef`
|
|
55
|
-
* and NO local bytes — the bytes stay in harness storage and re-submitting
|
|
56
|
-
* reuses the ref.
|
|
57
|
-
*/
|
|
58
|
-
interface DraftImage {
|
|
59
|
-
/** Per-TUI draft identity (the `#N` of the placeholder). */
|
|
60
|
-
readonly id: DraftImageId;
|
|
61
|
-
readonly kind: 'image';
|
|
62
|
-
readonly source: DraftImageSource;
|
|
63
|
-
/** Exact encoded bytes, held only for the draft lifetime. Empty for a
|
|
64
|
-
* recalled draft (its bytes live in harness storage). */
|
|
65
|
-
readonly bytes: Uint8Array;
|
|
66
|
-
readonly mediaType: ImageMediaType;
|
|
67
|
-
/** Intrinsic encoded width in pixels. */
|
|
68
|
-
readonly width: number;
|
|
69
|
-
/** Intrinsic encoded height in pixels. */
|
|
70
|
-
readonly height: number;
|
|
71
|
-
/** Exact encoded byte length (`bytes.byteLength` for local drafts; the
|
|
72
|
-
* durable ref's recorded `bytes` for recalled drafts). */
|
|
73
|
-
readonly byteLength: number;
|
|
74
|
-
/** Optional display name (basename for path sources), never a path. */
|
|
75
|
-
readonly name?: string;
|
|
76
|
-
/** The canonical editor placeholder text for this draft. */
|
|
77
|
-
readonly placeholder: string;
|
|
78
|
-
/** The durable ref this draft reuses on submit; present ONLY for
|
|
79
|
-
* recalled drafts (already-durable images are never re-uploaded). */
|
|
80
|
-
readonly recalledRef?: ImageAttachmentRefLike;
|
|
81
|
-
}
|
|
82
|
-
/** The store surface the placeholder expansion needs (structural). */
|
|
83
|
-
interface DraftImageStoreLike {
|
|
84
|
-
values(): readonly DraftImage[];
|
|
5
|
+
import { Agent, ModelSelectionRef } from "@deepseek-ai/dsh-agent";
|
|
6
|
+
import z from "@deepseek-ai/schemastery";
|
|
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;
|
|
85
12
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Canonical transcript display presets and their layered disclosure policy.
|
|
90
|
-
*
|
|
91
|
-
* DisplayPreset is the one runtime vocabulary for presentation state. Every
|
|
92
|
-
* preset whose projection exists in this build is available; the availability
|
|
93
|
-
* gate exists so a future preset can never be claimed by another preset's
|
|
94
|
-
* renderer before its own projection ships.
|
|
95
|
-
* @module @xmoon76/dsh-pi-tui/display-preset
|
|
96
|
-
*/
|
|
97
|
-
/** The complete display vocabulary. */
|
|
98
|
-
type DisplayPreset = 'focus' | 'compact' | 'full';
|
|
99
|
-
/** The shared mutable display authority passed between the runner, prompt and UI. */
|
|
100
|
-
interface DisplayState {
|
|
101
|
-
preset: DisplayPreset;
|
|
13
|
+
interface ResponseStyleState {
|
|
14
|
+
style: ResponseStyle;
|
|
102
15
|
}
|
|
103
16
|
//#endregion
|
|
104
|
-
//#region src/
|
|
17
|
+
//#region src/runtime/process/diagnostics.d.ts
|
|
105
18
|
interface Diag {
|
|
106
19
|
debug(message: string, fields?: Record<string, unknown>): void;
|
|
107
20
|
info(message: string, fields?: Record<string, unknown>): void;
|
|
@@ -111,38 +24,18 @@ interface Diag {
|
|
|
111
24
|
dispose(): void;
|
|
112
25
|
}
|
|
113
26
|
//#endregion
|
|
114
|
-
//#region src/
|
|
115
|
-
type ProgressUpdates = 'off' | 'milestones' | 'frequent';
|
|
116
|
-
type ResponseStyle = 'default' | 'concise' | 'explanatory';
|
|
117
|
-
interface ProgressUpdatesState {
|
|
118
|
-
mode: ProgressUpdates;
|
|
119
|
-
}
|
|
120
|
-
interface ResponseStyleState {
|
|
121
|
-
style: ResponseStyle;
|
|
122
|
-
}
|
|
123
|
-
//#endregion
|
|
124
|
-
//#region src/skill-catalog.d.ts
|
|
27
|
+
//#region src/domain/catalog/skill.d.ts
|
|
125
28
|
/**
|
|
126
|
-
*
|
|
127
|
-
* the
|
|
128
|
-
*
|
|
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.
|
|
129
32
|
*
|
|
130
|
-
*
|
|
131
|
-
* -
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
* deep freeze, distinct abort propagation;
|
|
137
|
-
* - `resolveColdSkillTarget()`: capability-gated cold target selection
|
|
138
|
-
* (standing scope → rosterless global → degraded global with a notice);
|
|
139
|
-
* - `resolveLiveSkillTarget()`: the agent's own registry + agent scope.
|
|
140
|
-
*
|
|
141
|
-
* Failure contract: ordinary provider/composition failures surface as
|
|
142
|
-
* degraded targets or rethrown errors for the coordinator to classify;
|
|
143
|
-
* aborts ALWAYS propagate as aborts. No failure may hang or crash the TUI —
|
|
144
|
-
* the worst outcome is "the corresponding commands are missing".
|
|
145
|
-
* @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
|
|
146
39
|
*/
|
|
147
40
|
/** The human-facing slice of one skill: display fields only. */
|
|
148
41
|
interface HumanSkillSummary {
|
|
@@ -160,44 +53,7 @@ interface HumanSkillCatalog {
|
|
|
160
53
|
readonly complete: boolean;
|
|
161
54
|
}
|
|
162
55
|
//#endregion
|
|
163
|
-
//#region src/
|
|
164
|
-
/** The compaction lifecycle phase the working row advertises: idle (no
|
|
165
|
-
* compaction), summarizing (compaction/start seen, the summary is being
|
|
166
|
-
* generated), or applying (the summary landed, the compacted surface is
|
|
167
|
-
* being committed). Derived by the runner from compaction/start →
|
|
168
|
-
* compaction/summary → compaction/end (foldCompactionEvent). */
|
|
169
|
-
type CompactionPhase = 'idle' | 'summarizing' | 'applying';
|
|
170
|
-
/**
|
|
171
|
-
* The WEB composer submit gestures (DSH `ComposerSubmitGesture`): plain
|
|
172
|
-
* Enter, or the Cmd/Ctrl-accelerated chord. The busy-Enter policy resolves
|
|
173
|
-
* each to a delivery mode — plain Enter to the preferred mode, the
|
|
174
|
-
* accelerated chord to its OPPOSITE — so the chord is never a fixed mode.
|
|
175
|
-
*/
|
|
176
|
-
type ComposerSubmitGesture = 'enter' | 'accelerated';
|
|
177
|
-
/** One semantic queued pending-input row for the queue pane. */
|
|
178
|
-
interface QueueItem {
|
|
179
|
-
/** The pending message id (agent inbox identity), or a local request id. */
|
|
180
|
-
id: string;
|
|
181
|
-
/** The message text, single-line display form. */
|
|
182
|
-
text: string;
|
|
183
|
-
/** next-turn followup vs next-step steer. */
|
|
184
|
-
mode: 'followup' | 'steer';
|
|
185
|
-
/** The correlation identity (authoritative rpc id or local request id). */
|
|
186
|
-
rpcId?: string;
|
|
187
|
-
/** A client-local echo not yet backed by an authoritative occurrence. */
|
|
188
|
-
local?: boolean;
|
|
189
|
-
}
|
|
190
|
-
//#endregion
|
|
191
|
-
//#region src/surface-catalog.d.ts
|
|
192
|
-
/** Minimal live-agent face consumed by the effective catalog readers. */
|
|
193
|
-
interface SurfaceCatalogAgent {
|
|
194
|
-
readonly ctx: object;
|
|
195
|
-
readonly session: {
|
|
196
|
-
readonly header: {
|
|
197
|
-
readonly cwd?: string;
|
|
198
|
-
};
|
|
199
|
-
};
|
|
200
|
-
}
|
|
56
|
+
//#region src/domain/catalog/surface.d.ts
|
|
201
57
|
/** Local structural command face, compatible with both npm and Source Mode DSH.
|
|
202
58
|
* The optional identity is part of the official 0.1.6 descriptor; an older
|
|
203
59
|
* runtime's descriptor may omit it. */
|
|
@@ -245,53 +101,42 @@ interface SurfaceCatalogSnapshot {
|
|
|
245
101
|
readonly skills: readonly HumanSkillSummary[];
|
|
246
102
|
readonly issues: readonly SurfaceCatalogIssue[];
|
|
247
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
|
+
}
|
|
248
127
|
/** The commands-service surface the collector reads. */
|
|
249
128
|
interface SurfaceCommandsService {
|
|
250
129
|
list(agent: SurfaceCatalogAgent): readonly SurfaceCommandDescriptor[];
|
|
251
130
|
}
|
|
252
131
|
/** The narrow context surface {@link readSurfaceCatalog} consumes. The
|
|
253
132
|
* SKILL services are NOT reached here: every dsh skill/agent-presets
|
|
254
|
-
* access goes through `
|
|
255
|
-
* plan appendix B.1). */
|
|
133
|
+
* access goes through `runtime/direct/skill-catalog.ts` (the single-point
|
|
134
|
+
* adapter, plan appendix B.1). */
|
|
256
135
|
interface SurfaceCatalogContext {
|
|
257
136
|
get(name: 'commands'): SurfaceCommandsService | undefined;
|
|
258
137
|
}
|
|
259
138
|
//#endregion
|
|
260
|
-
//#region src/
|
|
261
|
-
/**
|
|
262
|
-
* The effective mode ONE submission resolved at the submit boundary: whether
|
|
263
|
-
* an agent-facing delivery steers into the running turn or queues behind it
|
|
264
|
-
* (web `ComposerSubmissionPolicy` parity — an idle agent queues, plain Enter
|
|
265
|
-
* takes the preference, and the accelerated chord takes its OPPOSITE).
|
|
266
|
-
*
|
|
267
|
-
* It is a property of the GESTURE, not of the persisted settings: a one-shot
|
|
268
|
-
* gesture exists only inside the dispatch that resolved it, so every
|
|
269
|
-
* downstream consumer (the TUI skill delivery) accepts this value instead of
|
|
270
|
-
* re-deriving the mode from `busyEnter`.
|
|
271
|
-
*/
|
|
272
|
-
type SubmitDelivery = 'steer' | 'queue';
|
|
273
|
-
/**
|
|
274
|
-
* The CURRENT host catalog's view of ONE parsed line (the DSH client
|
|
275
|
-
* `CommandUiRuntime.matchEnter` decision table): whether the host CLAIMS the
|
|
276
|
-
* line, and — for a claimed line — the claiming descriptor's attachment
|
|
277
|
-
* declaration, so the dispatch can never consult two different catalog views
|
|
278
|
-
* for the claim and the declaration.
|
|
279
|
-
*/
|
|
280
|
-
type HostCommandClaim = {
|
|
281
|
-
readonly claimed: true;
|
|
282
|
-
/** The claiming descriptor's `input.attachments`
|
|
283
|
-
* (DSH `CommandInputDescriptor.attachments`): only a declaring command
|
|
284
|
-
* may be invoked with composer attachments. */
|
|
285
|
-
readonly attachments: boolean;
|
|
286
|
-
} | {
|
|
287
|
-
readonly claimed: false;
|
|
288
|
-
};
|
|
289
|
-
//#endregion
|
|
290
|
-
//#region src/index.d.ts
|
|
291
|
-
/** Stable Cordis plugin name. */
|
|
292
|
-
declare const name = "tui-runner";
|
|
293
|
-
/** Core services required before the TUI can mount. */
|
|
294
|
-
declare const inject: string[];
|
|
139
|
+
//#region src/app/config/schema.d.ts
|
|
295
140
|
/** Plugin config: the session to resume, resolved from the startup service,
|
|
296
141
|
* plus the DSH 0.1.7 profile-owned live TUI preferences. Every preference
|
|
297
142
|
* field is a schemastery `.volatile()` reference (PR A): the `tui-app`
|
|
@@ -335,7 +180,7 @@ interface Config {
|
|
|
335
180
|
/** Busy-Enter delivery for plain Enter while the agent runs: 'queue'
|
|
336
181
|
* (default) or 'steer'. */
|
|
337
182
|
readonly busyEnter: Volatile<string>;
|
|
338
|
-
/**
|
|
183
|
+
/** User-shell sandbox policy for user-typed `!`/`!!` commands: 'bypass'
|
|
339
184
|
* (default) runs them outside the dsh sandbox, 'sandbox' routes them
|
|
340
185
|
* through the dsh shell capability's policy. */
|
|
341
186
|
readonly localShellSandbox: Volatile<string>;
|
|
@@ -346,16 +191,22 @@ interface Config {
|
|
|
346
191
|
readonly displayPreset: Volatile<string>;
|
|
347
192
|
/** Mid-turn progress-update cadence (off | milestones | frequent). */
|
|
348
193
|
readonly progressUpdates: Volatile<string>;
|
|
194
|
+
/** Git attribution guidance mode (off | product | product-model). */
|
|
195
|
+
readonly gitAttribution: Volatile<string>;
|
|
349
196
|
/** Visible-answer density guidance (default | concise | explanatory). */
|
|
350
197
|
readonly responseStyle: Volatile<string>;
|
|
351
198
|
/** Completion-notification mode ('unfocused' | 'always' | 'off'). */
|
|
352
199
|
readonly notificationMode: Volatile<string>;
|
|
353
200
|
/** Completion-notification method ('auto' | 'osc9' | 'osc777' | 'bell'). */
|
|
354
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>;
|
|
355
206
|
/** Fullscreen mouse-wheel step ('1' | '2' | '3' | '5' | '8'). */
|
|
356
207
|
readonly wheelScrollLines: Volatile<string>;
|
|
357
208
|
/** The user keybinding overrides as a whole-value RAW field. The
|
|
358
|
-
* keybindings parser (src/keybindings/config.ts) is the only
|
|
209
|
+
* keybindings parser (src/tui/keybindings/config.ts) is the only
|
|
359
210
|
* validation/parsing authority — the keybinding business schema
|
|
360
211
|
* deliberately stays out of the plugin Config. */
|
|
361
212
|
readonly keybindings: Volatile<unknown>;
|
|
@@ -365,6 +216,27 @@ interface Config {
|
|
|
365
216
|
readonly legacySettingsMigrationVersion: Volatile<number>;
|
|
366
217
|
}
|
|
367
218
|
declare const Config: z<Config>;
|
|
219
|
+
//#endregion
|
|
220
|
+
//#region src/domain/command/policy.d.ts
|
|
221
|
+
/**
|
|
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.
|
|
226
|
+
*
|
|
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`.
|
|
233
|
+
*
|
|
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
|
|
239
|
+
*/
|
|
368
240
|
/**
|
|
369
241
|
* Slash commands that need no session: before the first user message
|
|
370
242
|
* (deferred start) they run locally without creating one. Everything else
|
|
@@ -377,38 +249,29 @@ declare const Config: z<Config>;
|
|
|
377
249
|
*/
|
|
378
250
|
declare const SESSIONLESS_COMMANDS: Set<string>;
|
|
379
251
|
/**
|
|
380
|
-
* The LOCAL-execute command set
|
|
381
|
-
* control
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
*
|
|
385
|
-
*
|
|
386
|
-
*
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
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.
|
|
390
273
|
*/
|
|
391
274
|
declare const LOCAL_COMMANDS: Set<string>;
|
|
392
|
-
/**
|
|
393
|
-
* Command semantics matrix (plan §19.3/M12): a LOCAL command line carrying a
|
|
394
|
-
* staged image placeholder is REJECTED — local commands are pure UI
|
|
395
|
-
* controls, never LLM prompts. AGENT-FACING input (plain prompts AND
|
|
396
|
-
* per-skill slash invocations like `/grilling`) SUPPORTS images: the skill
|
|
397
|
-
* wrapper builds its message through the same prepared-input path, so an
|
|
398
|
-
* image-bearing skill line is a real multimodal prompt (review finding 4).
|
|
399
|
-
* There is never a silent drop.
|
|
400
|
-
* @param parsed - the parsed slash command, undefined for a plain prompt.
|
|
401
|
-
* @param text - the submission text.
|
|
402
|
-
* @param store - the live draft store.
|
|
403
|
-
* @param isLocal - whether THIS LINE is a LOCAL (TUI-owned/UI) command; skill
|
|
404
|
-
* names answer false. Never derived from the name alone: a host command's
|
|
405
|
-
* input KIND decides which line it claims (see
|
|
406
|
-
* {@link commandIsLocalForAttachments}).
|
|
407
|
-
*/
|
|
408
|
-
declare function commandRejectsImages(parsed: {
|
|
409
|
-
name: string;
|
|
410
|
-
rawInput?: string;
|
|
411
|
-
} | undefined, text: string, store: DraftImageStoreLike, isLocal: boolean): boolean;
|
|
412
275
|
/**
|
|
413
276
|
* The STATIC host-owned command catalog (P1-04): the ownership sets
|
|
414
277
|
* (LOCAL_COMMANDS and SESSIONLESS_COMMANDS — the TUI's own local/UI command
|
|
@@ -431,15 +294,17 @@ declare const HOST_COMMAND_CATALOG: ReadonlySet<string>;
|
|
|
431
294
|
* @param name - the slash name.
|
|
432
295
|
* @param isSkillWrapper - the live skill-wrapper test (absent = none).
|
|
433
296
|
* @param isDynamicLocal - the live client-contribution test (absent = none).
|
|
434
|
-
* @param
|
|
435
|
-
*
|
|
436
|
-
*
|
|
437
|
-
*
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
*
|
|
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.
|
|
441
306
|
*/
|
|
442
|
-
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;
|
|
443
308
|
/**
|
|
444
309
|
* Whether one parsed line is the BARE slash token (DSH `matchEnter`'s `bare`:
|
|
445
310
|
* no input follows the name — trailing whitespace is not input). It is the
|
|
@@ -473,30 +338,16 @@ declare function isBareCommandLine(parsed: {
|
|
|
473
338
|
* @param parsed - the parsed slash command (undefined = plain prompt).
|
|
474
339
|
* @param isSkillWrapper - the live skill-wrapper test (absent = none).
|
|
475
340
|
* @param isDynamicLocal - the live client-contribution test (absent = none).
|
|
476
|
-
* @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).
|
|
477
345
|
* @returns whether the line is a local command line.
|
|
478
346
|
*/
|
|
479
347
|
declare function commandIsLocalForAttachments(parsed: {
|
|
480
348
|
name: string;
|
|
481
349
|
rawInput?: string;
|
|
482
|
-
} | undefined, isSkillWrapper: ((name: string) => boolean) | undefined, isDynamicLocal: ((name: string) => boolean) | undefined,
|
|
483
|
-
name: string;
|
|
484
|
-
rawInput?: string;
|
|
485
|
-
}) => HostCommandClaim | undefined) | undefined): boolean;
|
|
486
|
-
/**
|
|
487
|
-
* The TUI dispatch boundary's delivery resolution: the WEB composer policy
|
|
488
|
-
* ({@link resolveComposerDelivery}) applied to agent-facing input, with the
|
|
489
|
-
* TUI's own ownership terms on top. Pure so the dispatch gate (inside the
|
|
490
|
-
* runner closure) is testable headless.
|
|
491
|
-
* @param parsed - the parsed slash command, undefined for a plain prompt.
|
|
492
|
-
* @param running - whether the live agent reports running.
|
|
493
|
-
* @param gesture - the composer gesture that raised the submission.
|
|
494
|
-
* @param busyEnter - the persisted preference value (''/undefined = queue).
|
|
495
|
-
*/
|
|
496
|
-
declare function resolveSubmitDelivery(parsed: {
|
|
497
|
-
name: string;
|
|
498
|
-
rawInput?: string;
|
|
499
|
-
} | undefined, running: boolean, gesture: ComposerSubmitGesture, busyEnter: string | undefined): SubmitDelivery;
|
|
350
|
+
} | undefined, isSkillWrapper: ((name: string) => boolean) | undefined, isDynamicLocal: ((name: string) => boolean) | undefined, hostResolvesName: boolean): boolean;
|
|
500
351
|
/**
|
|
501
352
|
* Normalize an explicit `/skill <name> <args>` invocation to the skill's
|
|
502
353
|
* own slash line `/<name> <args>` (review finding 2). The harness's
|
|
@@ -529,61 +380,388 @@ declare function normalizeSkillInvocation(text: string): string | undefined;
|
|
|
529
380
|
declare function shouldConsumeAdvertisedMiss(execution: {
|
|
530
381
|
readonly result: unknown;
|
|
531
382
|
} | undefined, wasAdvertised: boolean): boolean;
|
|
532
|
-
/** Public settlement shape for the interrupt helper. Kept local so the
|
|
533
|
-
* entry-point declaration does not expose the internal runtime port module. */
|
|
534
|
-
type InterruptWriteOutcome = {
|
|
535
|
-
readonly kind: 'committed';
|
|
536
|
-
readonly value: undefined;
|
|
537
|
-
} | {
|
|
538
|
-
readonly kind: 'rejected';
|
|
539
|
-
readonly error: {
|
|
540
|
-
readonly code: string;
|
|
541
|
-
readonly message: string;
|
|
542
|
-
readonly details?: Readonly<Record<string, unknown>>;
|
|
543
|
-
};
|
|
544
|
-
} | {
|
|
545
|
-
readonly kind: 'cancelled';
|
|
546
|
-
} | {
|
|
547
|
-
readonly kind: 'indeterminate';
|
|
548
|
-
readonly error: {
|
|
549
|
-
readonly code: string;
|
|
550
|
-
readonly message: string;
|
|
551
|
-
readonly details?: Readonly<Record<string, unknown>>;
|
|
552
|
-
};
|
|
553
|
-
} | {
|
|
554
|
-
readonly kind: 'unsupported';
|
|
555
|
-
readonly reason: string;
|
|
556
|
-
};
|
|
557
|
-
/** The live-agent surface {@link interruptAgent} needs (structural — the
|
|
558
|
-
* TUI never imports the agent runtime for this call). */
|
|
559
|
-
interface InterruptAgentLike {
|
|
560
|
-
readonly session: {
|
|
561
|
-
readonly id: string;
|
|
562
|
-
};
|
|
563
|
-
readonly status: string;
|
|
564
|
-
cancel(cause: {
|
|
565
|
-
kind: 'user';
|
|
566
|
-
}, options?: {
|
|
567
|
-
keepInbox?: boolean;
|
|
568
|
-
}): void;
|
|
569
|
-
}
|
|
570
|
-
/** The writer surface {@link interruptAgent} needs (structural — a LOCAL
|
|
571
|
-
* type so the public declaration never inlines internal runtime modules;
|
|
572
|
-
* the runner's SessionWriter satisfies it). */
|
|
573
|
-
interface InterruptWriterLike {
|
|
574
|
-
cancel(sessionId: string): Promise<InterruptWriteOutcome>;
|
|
575
|
-
}
|
|
576
383
|
/**
|
|
577
|
-
*
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
384
|
+
* Whether a plain submitted draft is the quit word: exactly `exit` (trimmed,
|
|
385
|
+
* lowercase). The runner intercepts this BEFORE any session creation or
|
|
386
|
+
* submission (shell muscle memory); anything else — `exit!`, `Exit`, or a
|
|
387
|
+
* draft with a recalled entry still in it — is an ordinary message.
|
|
388
|
+
* @param text - the submitted draft.
|
|
389
|
+
*/
|
|
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
|
+
*/
|
|
399
|
+
/**
|
|
400
|
+
* Whether a shell command matches a destructive pattern. `rm` is treated
|
|
401
|
+
* specially: any spelling of recursive + force flags (`rm -rf`, `rm -r -f`,
|
|
402
|
+
* `rm -rf /`) is dangerous; the remaining patterns are verbatim matches.
|
|
403
|
+
*/
|
|
404
|
+
declare function dangerCommand(command: string): boolean;
|
|
405
|
+
//#endregion
|
|
406
|
+
//#region src/domain/media/types.d.ts
|
|
407
|
+
/**
|
|
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
|
|
423
|
+
*/
|
|
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';
|
|
442
|
+
} | {
|
|
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';
|
|
733
|
+
readonly reason: string;
|
|
734
|
+
};
|
|
735
|
+
/** The live-agent surface {@link interruptAgent} needs (structural — the
|
|
736
|
+
* TUI never imports the agent runtime for this call). */
|
|
737
|
+
interface InterruptAgentLike {
|
|
738
|
+
readonly session: {
|
|
739
|
+
readonly id: string;
|
|
740
|
+
};
|
|
741
|
+
readonly status: string;
|
|
742
|
+
cancel(cause: {
|
|
743
|
+
kind: 'user';
|
|
744
|
+
}, options?: {
|
|
745
|
+
keepInbox?: boolean;
|
|
746
|
+
}): void;
|
|
747
|
+
}
|
|
748
|
+
/** The writer surface {@link interruptAgent} needs (structural — a LOCAL
|
|
749
|
+
* type so the public declaration never inlines internal runtime modules;
|
|
750
|
+
* the runner's SessionWriter satisfies it). */
|
|
751
|
+
interface InterruptWriterLike {
|
|
752
|
+
cancel(sessionId: string): Promise<InterruptWriteOutcome>;
|
|
753
|
+
}
|
|
754
|
+
/**
|
|
755
|
+
* Interrupt the live agent (web Stop parity): abort the current
|
|
756
|
+
* turn/tool run while PRESERVING the pending queue. dsh's DEFAULT
|
|
757
|
+
* `cancel()` clears queued AND steering input, so a bare cancel would
|
|
758
|
+
* destroy everything the user queued with Ctrl+S / queue-mode Enter —
|
|
759
|
+
* the Esc-interrupt semantic is "stop the current thinking", never
|
|
760
|
+
* "drop the queue". `keepInbox: true` parks the preserved work; dsh's
|
|
761
|
+
* cancel is a documented no-op when nothing is active, so an idle
|
|
762
|
+
* interrupt (double-Esc while idle) is harmless and still aborts a
|
|
763
|
+
* local shell / maintenance task through the caller.
|
|
764
|
+
*
|
|
587
765
|
* NOTE (upstream dependency): dsh currently PARKS the preserved queue
|
|
588
766
|
* after an abort — the "Esc with a queue continues immediately" UX
|
|
589
767
|
* needs an upstream `wakePending`/`continueInbox` capability (not yet
|
|
@@ -593,6 +771,8 @@ interface InterruptWriterLike {
|
|
|
593
771
|
* agreed web-parity behavior until upstream lands the capability.
|
|
594
772
|
*/
|
|
595
773
|
declare function interruptAgent(agent: InterruptAgentLike | undefined, writer: InterruptWriterLike): Promise<InterruptWriteOutcome>;
|
|
774
|
+
//#endregion
|
|
775
|
+
//#region src/app/surface/viewer-policy.d.ts
|
|
596
776
|
/** One unsettled subagent delegation, in tool/call order. */
|
|
597
777
|
interface PendingSubagentCall {
|
|
598
778
|
readonly callId: string;
|
|
@@ -664,218 +844,117 @@ declare function viewerActionCapability(action: TuiAction, viewer: {
|
|
|
664
844
|
* @returns the matched call, or undefined when nothing matches.
|
|
665
845
|
*/
|
|
666
846
|
declare function matchPendingSubagentCall(pending: PendingSubagentCall[], label: string | undefined): PendingSubagentCall | undefined;
|
|
847
|
+
//#endregion
|
|
848
|
+
//#region src/client/launcher/profile.d.ts
|
|
667
849
|
/**
|
|
668
|
-
* The
|
|
669
|
-
*
|
|
670
|
-
* catalog (a live read emits no session events);
|
|
671
|
-
* - the deferred start (no `--session`) reads the cold HUMAN SKILL catalog
|
|
672
|
-
* through the preset's STANDING SCOPE — no Agent, no session, no turn —
|
|
673
|
-
* so the first input sees human-invocable skills without any durable
|
|
674
|
-
* side effect (the mechanism that avoids the probe dead end: host
|
|
675
|
-
* `session/created` observers write durable knob events into every fresh
|
|
676
|
-
* session).
|
|
850
|
+
* The Client-local DSH launcher PROFILE reads: the `--profile` argv scrape and
|
|
851
|
+
* the interactive-quit resume hint.
|
|
677
852
|
*
|
|
678
|
-
*
|
|
679
|
-
*
|
|
680
|
-
*
|
|
681
|
-
*
|
|
682
|
-
*
|
|
683
|
-
*
|
|
684
|
-
* TUI mounts with the global view and built-in commands);
|
|
685
|
-
* - a missing/unknown preset or a broken standing mount degrades the cold
|
|
686
|
-
* target to the global layer with a one-shot notice — never a probe
|
|
687
|
-
* Agent, never a startup failure;
|
|
688
|
-
* - an ordinary provider read failure never rejects here: it becomes an
|
|
689
|
-
* empty field + detached issue inside the catalog.
|
|
690
|
-
* @param options - injected dependencies (see {@link ResolveInitialCatalogOptions}).
|
|
691
|
-
* @returns the snapshot / skill catalog to install and an optional notice.
|
|
692
|
-
*/
|
|
693
|
-
interface InitialCatalogResolution {
|
|
694
|
-
/** The resume prefetch snapshot to install at mount. */
|
|
695
|
-
readonly snapshot?: SurfaceCatalogSnapshot;
|
|
696
|
-
/** The cold standing-scope human skill catalog (deferred start). */
|
|
697
|
-
readonly skills?: HumanSkillCatalog;
|
|
698
|
-
/** A user-facing notice when the prefetch/standing read degraded. */
|
|
699
|
-
readonly notice?: string;
|
|
700
|
-
}
|
|
701
|
-
/** Options for {@link resolveInitialCatalog}. */
|
|
702
|
-
interface ResolveInitialCatalogOptions {
|
|
703
|
-
/** The resumed live agent, if any (prefetch path). */
|
|
704
|
-
readonly liveAgent?: Agent;
|
|
705
|
-
/** The effective preset id for the cold standing read (undefined = the
|
|
706
|
-
* deployment default; only consulted for the deferred start). */
|
|
707
|
-
readonly presetId?: string;
|
|
708
|
-
readonly signal: AbortSignal;
|
|
709
|
-
/** The context surface the collectors read services from. */
|
|
710
|
-
readonly ctx: SurfaceCatalogContext;
|
|
711
|
-
readonly diag: Diag;
|
|
712
|
-
/** Suspend the pre-mount startup status before an ordinary log write
|
|
713
|
-
* (the status owns the current terminal line; a TTY shares one cursor
|
|
714
|
-
* between stdout and stderr). Called right before every diag.warn this
|
|
715
|
-
* function may emit. */
|
|
716
|
-
readonly onLog?: () => void;
|
|
717
|
-
}
|
|
718
|
-
declare function resolveInitialCatalog(options: ResolveInitialCatalogOptions): Promise<InitialCatalogResolution>;
|
|
719
|
-
declare function subagentJobTranscriptId(snapshot: unknown): string | undefined;
|
|
720
|
-
/**
|
|
721
|
-
* The Task Center row-selection disposition (plan §4.3/§4.4). A subagent
|
|
722
|
-
* transcript opens a session/viewer surface that REPLACES the browser; a
|
|
723
|
-
* Job row's detail keeps it mounted (the caller passes {@link openJobView}'s
|
|
724
|
-
* disposition). An UNKNOWN row — a stale panel selection after a live
|
|
725
|
-
* re-projection — also keeps the parent usable instead of dismissing it.
|
|
726
|
-
*/
|
|
727
|
-
declare function taskRowSelectionDisposition(row: {
|
|
728
|
-
readonly kind: 'job' | 'subagent';
|
|
729
|
-
} | undefined, jobDetail: 'close' | 'keep-open'): 'close' | 'keep-open';
|
|
730
|
-
/** Viewer body for a subagent job with no uniquely matched child. */
|
|
731
|
-
declare function subagentJobViewHint(status: string, detail: string | undefined): string;
|
|
732
|
-
/**
|
|
733
|
-
* Whether a plain submitted draft is the quit word: exactly `exit` (trimmed,
|
|
734
|
-
* lowercase). The runner intercepts this BEFORE any session creation or
|
|
735
|
-
* submission (shell muscle memory); anything else — `exit!`, `Exit`, or a
|
|
736
|
-
* draft with a recalled entry still in it — is an ordinary message.
|
|
737
|
-
* @param text - the submitted draft.
|
|
738
|
-
*/
|
|
739
|
-
declare function isPlainExitPrompt(text: string): boolean;
|
|
740
|
-
/** One semantic pending-input item as the queue mirror sees it. */
|
|
741
|
-
interface QueueInboxMessage {
|
|
742
|
-
readonly id: string;
|
|
743
|
-
readonly content: readonly ContentBlock[];
|
|
744
|
-
}
|
|
745
|
-
/** The queue-pane rows for one semantic pending-input batch. */
|
|
746
|
-
interface QueueFoldResult {
|
|
747
|
-
readonly rows: QueueItem[];
|
|
748
|
-
}
|
|
749
|
-
/** Build queue-pane rows from semantic pending-input occurrences, preserving
|
|
750
|
-
* their order and content without inspecting backend-specific metadata. */
|
|
751
|
-
declare function foldQueueRows(messages: readonly QueueInboxMessage[], mode: 'followup' | 'steer'): QueueFoldResult;
|
|
752
|
-
/**
|
|
753
|
-
* Whether a shell command matches a destructive pattern. `rm` is treated
|
|
754
|
-
* specially: any spelling of recursive + force flags (`rm -rf`, `rm -r -f`,
|
|
755
|
-
* `rm -rf /`) is dangerous; the remaining patterns are verbatim matches.
|
|
853
|
+
* Deliberately NOT part of `src/startup.ts`: the startup row is a
|
|
854
|
+
* zero-dependency island that must not share a bundle chunk with the runner,
|
|
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
|
|
756
859
|
*/
|
|
757
|
-
declare function dangerCommand(command: string): boolean;
|
|
758
860
|
/**
|
|
759
861
|
* The dsh profile named by the `--profile` flag in `argv`, in both spellings.
|
|
760
862
|
* This is the ARGV-ONLY fallback: it cannot see the positional `dsh <name>`
|
|
761
863
|
* launch form, because the launcher consumes that bare name by synthesizing
|
|
762
864
|
* `['--profile', ...argv]` for its OWN commander parse and leaves
|
|
763
|
-
* `process.argv` untouched. Prefer
|
|
764
|
-
*
|
|
865
|
+
* `process.argv` untouched. Prefer `hostRunningProfile`, which reads the Host's
|
|
866
|
+
* profile identity instead of scraping the command line.
|
|
765
867
|
* @param argv - the process argument vector.
|
|
766
868
|
* @param fallback - the default profile.
|
|
767
869
|
*/
|
|
768
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
|
+
*/
|
|
769
896
|
/** The one context read {@link hostRunningProfile} needs (a cordis Context satisfies it). */
|
|
770
897
|
interface ProfileContextReadLike {
|
|
771
898
|
get(name: string): unknown;
|
|
772
899
|
}
|
|
773
900
|
/**
|
|
774
|
-
* The profile this process actually runs
|
|
775
|
-
* `profileContext.name` when it is composed, else {@link runningProfile}'s
|
|
776
|
-
* argv scrape.
|
|
777
|
-
*
|
|
778
|
-
* `profileContext.name` is the launcher's own profile identity, so it is
|
|
779
|
-
* correct for EVERY launch form: `--profile <name>`, `--profile=<name>`, the
|
|
780
|
-
* positional `dsh <name>`, and `--from-default-profile <name>`. The argv
|
|
781
|
-
* scrape only knows the flag form, which is why it is the fallback for a
|
|
782
|
-
* profile-less mount (tests, an embedded surface) rather than the primary
|
|
783
|
-
* source.
|
|
901
|
+
* The profile this process actually runs.
|
|
784
902
|
* @param ctx - the plugin context (or any structural `get`-only stand-in).
|
|
785
903
|
* @param argv - the process argument vector for the fallback path.
|
|
786
904
|
* @param fallback - the default profile for the fallback path.
|
|
787
905
|
* @returns the running profile name.
|
|
788
906
|
*/
|
|
789
907
|
declare function hostRunningProfile(ctx: ProfileContextReadLike, argv?: readonly string[], fallback?: string): string;
|
|
908
|
+
//#endregion
|
|
909
|
+
//#region src/index.d.ts
|
|
910
|
+
/** Stable Cordis plugin name. */
|
|
911
|
+
declare const name = "tui-runner";
|
|
912
|
+
/** Core services required before the TUI can mount. */
|
|
913
|
+
declare const inject: string[];
|
|
790
914
|
/**
|
|
791
|
-
*
|
|
792
|
-
*
|
|
793
|
-
*
|
|
794
|
-
*
|
|
795
|
-
*
|
|
796
|
-
*
|
|
797
|
-
* @returns the resume command line, or undefined without a session.
|
|
915
|
+
* Options for {@link resolveInitialCatalog}.
|
|
916
|
+
*
|
|
917
|
+
* The public declaration stays here (A5a review P1): `liveAgent` keeps the Host
|
|
918
|
+
* `Agent` type it has always had, so consumers that READ the property keep
|
|
919
|
+
* compiling. The implementation consumes the structural
|
|
920
|
+
* `SurfaceCatalogResolutionOptions` in `app/direct/initial-catalog.ts`.
|
|
798
921
|
*/
|
|
799
|
-
|
|
800
|
-
/**
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
/**
|
|
810
|
-
*
|
|
811
|
-
*
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
* 'summarizing', a MATCHED compaction/summary → 'applying'. Undefined
|
|
815
|
-
* when the event does not advance the phase (a stale summary, any
|
|
816
|
-
* compaction/end — the settle clears via {@link clear}). */
|
|
817
|
-
phase?: Exclude<CompactionPhase, 'idle'>;
|
|
818
|
-
/** The settle notification for compaction/end, when one fires. */
|
|
819
|
-
notify: {
|
|
820
|
-
text: string;
|
|
821
|
-
kind: 'info' | 'error';
|
|
822
|
-
} | undefined;
|
|
823
|
-
}
|
|
824
|
-
/** Fold one compaction lifecycle event over the in-flight state. */
|
|
825
|
-
declare function foldCompactionEvent(state: {
|
|
826
|
-
id: string | undefined;
|
|
827
|
-
}, event: {
|
|
828
|
-
type: string;
|
|
829
|
-
data: {
|
|
830
|
-
compactionId?: unknown;
|
|
831
|
-
error?: unknown;
|
|
832
|
-
};
|
|
833
|
-
}): CompactionFold;
|
|
834
|
-
/** The minimal compaction-settle surface the runner passes in — STRUCTURAL
|
|
835
|
-
* on purpose: referencing the full {@link TuiApp} class from a public
|
|
836
|
-
* export would inline the whole surface (and its internal registry/
|
|
837
|
-
* presentation dependencies) into the published declaration bundle. The
|
|
838
|
-
* settle contract only needs the three phase/busy/working setters. */
|
|
839
|
-
interface CompactionSettleSurface {
|
|
840
|
-
setCompactionPhase(phase: 'idle'): void;
|
|
841
|
-
setBusy(busy: boolean): void;
|
|
842
|
-
setWorking(busy: boolean): void;
|
|
922
|
+
interface ResolveInitialCatalogOptions {
|
|
923
|
+
/** The resumed live agent, if any (prefetch path). */
|
|
924
|
+
readonly liveAgent?: Agent;
|
|
925
|
+
/** The effective preset id for the cold standing read (undefined = the
|
|
926
|
+
* deployment default; only consulted for the deferred start). */
|
|
927
|
+
readonly presetId?: string;
|
|
928
|
+
readonly signal: AbortSignal;
|
|
929
|
+
/** The context surface the collectors read services from. */
|
|
930
|
+
readonly ctx: SurfaceCatalogContext;
|
|
931
|
+
readonly diag: Diag;
|
|
932
|
+
/** Suspend the pre-mount startup status before an ordinary log write
|
|
933
|
+
* (the status owns the current terminal line; a TTY shares one cursor
|
|
934
|
+
* between stdout and stderr). Called right before every diag.warn this
|
|
935
|
+
* function may emit. */
|
|
936
|
+
readonly onLog?: () => void;
|
|
843
937
|
}
|
|
844
|
-
/** The UI side effects of a MATCHED compaction settle: clear the phase,
|
|
845
|
-
* hand the working row back to the turn state, and re-measure the session
|
|
846
|
-
* surface so the footer context reflects the compacted log IMMEDIATELY —
|
|
847
|
-
* the next step/start or turn/end would otherwise delay the refresh.
|
|
848
|
-
* Exported as a seam so the settle contract is testable without a full
|
|
849
|
-
* runner driver (the firehose closure is not). */
|
|
850
|
-
declare function settleCompactionSurface(app: CompactionSettleSurface, refreshStatus: () => void, busyNow: boolean): void;
|
|
851
|
-
/** The busy flag after a turn-boundary event: a turn end must NOT clear
|
|
852
|
-
* the busy state while a compaction is still in flight — an interrupted
|
|
853
|
-
* turn can close (turn/end) before its compaction settles, and the
|
|
854
|
-
* single-Esc cancel must stay armed until compaction/end. */
|
|
855
|
-
declare function busyAfterTurnBoundary(eventType: 'turn/start' | 'turn/end', compacting: boolean): boolean;
|
|
856
|
-
/** PR D2 test seam: whether a session event type marks the model-visible
|
|
857
|
-
* context dirty (re-measure through the SessionReader port) or only
|
|
858
|
-
* repaints cheaply (cached measurement). The firehose routes every event
|
|
859
|
-
* through this classification — the single source of truth for the
|
|
860
|
-
* status/measurement split. `compaction/end` is classified 'measure' but
|
|
861
|
-
* the firehose deliberately SKIPS it here: a matched compaction settle
|
|
862
|
-
* re-measures through the fold-outcome path (settleCompactionSurface), so
|
|
863
|
-
* a STALE compaction/end can never trigger a measurement. */
|
|
864
|
-
declare function contextRefreshKind(eventType: string): 'measure' | 'cheap';
|
|
865
938
|
/**
|
|
866
|
-
* The
|
|
867
|
-
*
|
|
868
|
-
*
|
|
869
|
-
*
|
|
870
|
-
*
|
|
871
|
-
*
|
|
939
|
+
* The pre-mount surface catalog resolution (plan §27): the published entry for
|
|
940
|
+
* {@link ResolveInitialCatalogOptions}. An explicit `--session` start
|
|
941
|
+
* prefetches the resumed agent's effective catalog; the deferred start reads the
|
|
942
|
+
* cold HUMAN SKILL catalog through the preset's STANDING SCOPE — no Agent, no
|
|
943
|
+
* session, no turn — so the first input sees human-invocable skills without any
|
|
944
|
+
* durable side effect. The implementation and its pre-mount failure taxonomy
|
|
945
|
+
* live in `app/direct/initial-catalog.ts`.
|
|
946
|
+
* @param options - injected dependencies (see {@link ResolveInitialCatalogOptions}).
|
|
947
|
+
* @returns the snapshot / skill catalog to install and an optional notice.
|
|
872
948
|
*/
|
|
873
|
-
declare function
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
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';
|
|
879
958
|
};
|
|
880
959
|
/** One agent's preset composition: the id to record and the setup that installs it. */
|
|
881
960
|
interface AgentComposition {
|
|
@@ -945,4 +1024,4 @@ declare function recordedPreset(ctx: Context, sessionId: string): Promise<string
|
|
|
945
1024
|
*/
|
|
946
1025
|
declare function apply(ctx: Context, config: Config): void;
|
|
947
1026
|
//#endregion
|
|
948
|
-
export { AgentComposition, CompactionFold, CompactionSettleSurface, Config, HOST_COMMAND_CATALOG, InitialCatalogResolution, InterruptAgentLike, InterruptWriteOutcome, InterruptWriterLike, LOCAL_COMMANDS, PendingSubagentCall, ProfileContextReadLike, QueueFoldResult, QueueInboxMessage, ResolveInitialCatalogOptions, SESSIONLESS_COMMANDS, ViewerOpenToken, apply, busyAfterTurnBoundary, commandIsLocalForAttachments, commandRejectsImages, compactingFromLog, composeAgent, contextRefreshKind, createViewerOpenToken, dangerCommand, foldCompactionEvent, foldQueueRows, hostRunningProfile, inject, interruptAgent, isBareCommandLine, isLocalCommandLine, isPlainExitPrompt, matchPendingSubagentCall, name, normalizeSkillInvocation, recordedPreset, resolveInitialCatalog, resolveSubmitDelivery, resumeCommand, runningProfile, settleCompactionSurface, shouldConsumeAdvertisedMiss, subagentJobTranscriptId, subagentJobViewHint, taskRowSelectionDisposition, teardownViewerForSessionSwap, viewerActionCapability };
|
|
1027
|
+
export { AgentComposition, type CompactionFold, type CompactionSettleSurface, Config, HOST_COMMAND_CATALOG, type InitialCatalogResolution, type InterruptAgentLike, type InterruptWriteOutcome, type InterruptWriterLike, LOCAL_COMMANDS, type PendingSubagentCall, type ProfileContextReadLike, type QueueFoldResult, type QueueInboxMessage, ResolveInitialCatalogOptions, SESSIONLESS_COMMANDS, type ViewerOpenToken, apply, busyAfterTurnBoundary, commandIsLocalForAttachments, commandRejectsImages, compactingFromLog, composeAgent, contextRefreshKind, createViewerOpenToken, dangerCommand, foldCompactionEvent, foldQueueRows, hostRunningProfile, inject, interruptAgent, isBareCommandLine, isLocalCommandLine, isPlainExitPrompt, matchPendingSubagentCall, name, normalizeSkillInvocation, recordedPreset, resolveInitialCatalog, resolveSubmitDelivery, resumeCommand, runningProfile, settleCompactionSurface, shouldConsumeAdvertisedMiss, subagentJobTranscriptId, subagentJobViewHint, taskRowSelectionDisposition, teardownViewerForSessionSwap, viewerActionCapability };
|