@sagentlab/navarch-runtime 0.1.116 → 0.1.118

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.
Files changed (52) hide show
  1. package/README.md +43 -17
  2. package/bin/muse-mcp-bridge.cjs +3 -0
  3. package/bin/worktree-guard-hook.cjs +74 -2
  4. package/dist/adapters/index.cjs +6 -1
  5. package/dist/adapters/muse.cjs +433 -0
  6. package/dist/agent-auth.cjs +2 -1
  7. package/dist/config.cjs +8 -1
  8. package/dist/conversation/capability.cjs +1 -1
  9. package/dist/exit-conditions.cjs +1 -1
  10. package/dist/muse-mcp-bridge.cjs +167 -0
  11. package/dist/session.cjs +30 -8
  12. package/node_modules/@muse-code/sdk/LICENSE +21 -0
  13. package/node_modules/@muse-code/sdk/README.md +88 -0
  14. package/node_modules/@muse-code/sdk/dist/src/connection/connection.d.ts +149 -0
  15. package/node_modules/@muse-code/sdk/dist/src/connection/connection.js +581 -0
  16. package/node_modules/@muse-code/sdk/dist/src/connection/spawn.d.ts +188 -0
  17. package/node_modules/@muse-code/sdk/dist/src/connection/spawn.js +496 -0
  18. package/node_modules/@muse-code/sdk/dist/src/errors.d.ts +71 -0
  19. package/node_modules/@muse-code/sdk/dist/src/errors.js +76 -0
  20. package/node_modules/@muse-code/sdk/dist/src/facade/approval.d.ts +96 -0
  21. package/node_modules/@muse-code/sdk/dist/src/facade/approval.js +293 -0
  22. package/node_modules/@muse-code/sdk/dist/src/facade/client.d.ts +171 -0
  23. package/node_modules/@muse-code/sdk/dist/src/facade/client.js +442 -0
  24. package/node_modules/@muse-code/sdk/dist/src/facade/discarded.d.ts +36 -0
  25. package/node_modules/@muse-code/sdk/dist/src/facade/discarded.js +36 -0
  26. package/node_modules/@muse-code/sdk/dist/src/facade/gap-fill.d.ts +80 -0
  27. package/node_modules/@muse-code/sdk/dist/src/facade/gap-fill.js +388 -0
  28. package/node_modules/@muse-code/sdk/dist/src/facade/host-death.d.ts +139 -0
  29. package/node_modules/@muse-code/sdk/dist/src/facade/host-death.js +96 -0
  30. package/node_modules/@muse-code/sdk/dist/src/facade/host-start.d.ts +62 -0
  31. package/node_modules/@muse-code/sdk/dist/src/facade/host-start.js +81 -0
  32. package/node_modules/@muse-code/sdk/dist/src/facade/session.d.ts +309 -0
  33. package/node_modules/@muse-code/sdk/dist/src/facade/session.js +654 -0
  34. package/node_modules/@muse-code/sdk/dist/src/facade/turn-handle.d.ts +156 -0
  35. package/node_modules/@muse-code/sdk/dist/src/facade/turn-handle.js +271 -0
  36. package/node_modules/@muse-code/sdk/dist/src/facade/turn-submit.d.ts +72 -0
  37. package/node_modules/@muse-code/sdk/dist/src/facade/turn-submit.js +183 -0
  38. package/node_modules/@muse-code/sdk/dist/src/fingerprint.d.ts +37 -0
  39. package/node_modules/@muse-code/sdk/dist/src/fingerprint.js +54 -0
  40. package/node_modules/@muse-code/sdk/dist/src/fold/item-store.d.ts +110 -0
  41. package/node_modules/@muse-code/sdk/dist/src/fold/item-store.js +169 -0
  42. package/node_modules/@muse-code/sdk/dist/src/fold/session-fold.d.ts +536 -0
  43. package/node_modules/@muse-code/sdk/dist/src/fold/session-fold.js +427 -0
  44. package/node_modules/@muse-code/sdk/dist/src/fold/state-store.d.ts +68 -0
  45. package/node_modules/@muse-code/sdk/dist/src/fold/state-store.js +89 -0
  46. package/node_modules/@muse-code/sdk/dist/src/index.d.ts +65 -0
  47. package/node_modules/@muse-code/sdk/dist/src/index.js +57 -0
  48. package/node_modules/@muse-code/sdk/dist/src/msp.d.ts +3380 -0
  49. package/node_modules/@muse-code/sdk/dist/src/pending/pending-command-set.d.ts +361 -0
  50. package/node_modules/@muse-code/sdk/dist/src/pending/pending-command-set.js +468 -0
  51. package/node_modules/@muse-code/sdk/package.json +47 -0
  52. package/package.json +8 -4
@@ -0,0 +1,3380 @@
1
+ // Generated MSP wire declarations, bundled into the published package.
2
+ //
3
+ // Copied verbatim from `schema/msp/msp.d.ts` at pack time by
4
+ // `scripts/bundle-msp-types.mjs`. Do not edit, and do not commit: this file
5
+ // exists only in build output, so the repo keeps one copy of the generated
6
+ // artifact (spec 14990 INV-008) while the tarball stays self-contained.
7
+
8
+ // Muse Session Protocol (MSP) v1 TypeScript declarations.
9
+ // STABLE surface only; experimental twin: experimental/msp.d.ts.
10
+ // Generated by tbh-protocol (spec 206) from the same schema model as
11
+ // the JSON Schema bundle (INV-017). Do not edit by hand.
12
+
13
+ export interface ApprovalAmendment {
14
+ durability: ApprovalAmendmentDurability;
15
+ rulePreview: string;
16
+ }
17
+
18
+ export type ApprovalAmendmentDurability = "session" | "localPersistent" | (string & {});
19
+
20
+ export interface ApprovalChange {
21
+ choiceId?: string;
22
+ decision?: ApprovalDecision;
23
+ executable?: boolean;
24
+ kind: string;
25
+ reason?: string;
26
+ reparsed?: boolean;
27
+ requirementId?: ApprovalRequirementRef;
28
+ status?: ApprovalPersistenceStatus;
29
+ }
30
+
31
+ export interface ApprovalChoice {
32
+ acceptsFeedback?: boolean;
33
+ choiceId: string;
34
+ decision: ApprovalDecision;
35
+ label: string;
36
+ rulePreview?: string;
37
+ scope: ApprovalChoiceScope;
38
+ }
39
+
40
+ export type ApprovalChoiceScope = "once" | "session" | "localPersistent" | (string & {});
41
+
42
+ /** `approval/decide` params (tdd SS5.4): the decision. A standard SS3 command — requires the session loaded on this host, requires `commandId`, durable intake before ack, value-identical replay. */
43
+ export interface ApprovalDecideParams {
44
+ /** The approval being decided. */
45
+ approvalId: string;
46
+ /** One of the current `availableChoices`; else -32052. */
47
+ choiceId: string;
48
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
49
+ commandId: string;
50
+ /** Free-text guidance delivered to the model with the denial. Only valid on choices with `acceptsFeedback`. Never persisted in the durable audit record (live steer only), so it is absent from `approval/resolved` (tdd SS5.4). Omitted and explicit `null` both mean "no feedback" (#23468). */
51
+ feedback?: string | null;
52
+ /** Must equal the approval's `currentRequirementId`. The multi-stage race guard: a decision aimed at stage 1 can never accidentally satisfy stage 2, and a stale value is -32053 (tdd SS5.4). */
53
+ requirementId: ApprovalRequirementRef;
54
+ /** The target session. */
55
+ sessionId: string;
56
+ }
57
+
58
+ /** `approval/decide` result (tdd SS5.4). Admission-ack rules still apply: the authoritative outcome is `approval/resolved` / `approval/updated` on the view stream. */
59
+ export interface ApprovalDecideResult {
60
+ /** The approval this decision was applied to. */
61
+ approvalId: string;
62
+ /** Echoes the client's id. */
63
+ commandId: string;
64
+ /** Admission status. */
65
+ status: CommandStatus;
66
+ /** `false` when the choice satisfied a stage but further requirements remain (the approval stays pending and an updated `approval/request` follows); `true` when this decision produced the terminal `DecisionApplied` (tdd SS5.4). */
67
+ terminal: boolean;
68
+ }
69
+
70
+ export type ApprovalDecision = "approved" | "approvedForSession" | "approvedPolicyAmendment" | "denied" | "deniedPolicyAmendment" | "timedOut" | "abort" | (string & {});
71
+
72
+ /** `approval/listPending` params (tdd SS5.7): the pull dual of the re-issued requests. A log-fold read — no lease, works on loaded and unloaded sessions, never subscribes. */
73
+ export interface ApprovalListPendingParams {
74
+ /** The session to read. */
75
+ sessionId: string;
76
+ }
77
+
78
+ /** `approval/listPending` result (tdd SS5.7). Ordering is by opening `viewCursor`; empty arrays when nothing is pending. The result is point-in-time — to act on it race-safely, `approval/decide` carries the `requirementId` guard regardless of how the client learned the state. */
79
+ export interface ApprovalListPendingResult {
80
+ /** Exactly the `approval/request` params of tdd SS5.3, one per pending approval. */
81
+ approvals: ApprovalRequestParams[];
82
+ /** Exactly the `userInput/request` params of tdd SS5.10, one per pending prompt. */
83
+ userInputs: UserInputRequestParams[];
84
+ }
85
+
86
+ /** The approval enforcement modes (tdd SS5.12, camelCased `ApprovalBackendMode`). **Closed** by design (D-006, select-never-create): a client selects a preconfigured mode and can never construct one; widening this enum is a deliberate, gate-visible protocol change. */
87
+ export type ApprovalMode = "allowAll" | "promptUnmatched" | "onRequest" | "denyUnmatched";
88
+
89
+ /** Whether a mode change did anything (tdd SS5.12), mirroring `ApprovalReconfigureApplyOutcome`. Apply failures are `commandRejected`. */
90
+ export type ApprovalModeApplyOutcome = "completed" | "noop" | (string & {});
91
+
92
+ /** How an approval mode took effect (tdd SS5.12, the effective-mode projection's `source` vocabulary). Open. */
93
+ export type ApprovalModeSource = "startup" | "replay" | "approvalReconfigure" | (string & {});
94
+
95
+ export interface ApprovalOrigin {
96
+ command?: string;
97
+ kind: string;
98
+ url?: string;
99
+ }
100
+
101
+ export type ApprovalPersistenceStatus = "succeeded" | "failed" | (string & {});
102
+
103
+ export type ApprovalPolicyResult = "allow" | "deny" | (string & {});
104
+
105
+ /** Full params shared by `approval/request` and `approval/requested`. */
106
+ export interface ApprovalRequestParams {
107
+ approvalId: string;
108
+ availableChoices: ApprovalChoice[];
109
+ currentRequirementId: ApprovalRequirementRef;
110
+ itemId: string;
111
+ judgeEscalated: boolean;
112
+ protectedWrite: boolean;
113
+ rawArgs: string;
114
+ sessionId: string;
115
+ sourceRange: SourceRange;
116
+ /** Present only for a child (native subagent) approval projected onto the parent session's plane (ADR 36182); parent-own approvals omit it. */
117
+ subagentOrigin?: ApprovalSubagentOrigin;
118
+ subject: ApprovalSubject;
119
+ taskId: string;
120
+ toolCallId: string;
121
+ toolName: string;
122
+ turnId: string;
123
+ viewCursor: string;
124
+ }
125
+
126
+ /** Approval-stage token carried in SS5 params and stale-requirement errors. */
127
+ export interface ApprovalRequirementRef {
128
+ approvalId: string;
129
+ sourceIndex: number;
130
+ }
131
+
132
+ /** Winning terminal returned to a losing `approval/decide` command. */
133
+ export interface ApprovalResolutionSummary {
134
+ decision: string;
135
+ resolvedBy: string;
136
+ viewCursor: string;
137
+ }
138
+
139
+ export type ApprovalResolvedBy = "user" | "policy" | "llmJudge" | (string & {});
140
+
141
+ /** `approval/resolved` params: the first durable terminal decision. */
142
+ export interface ApprovalResolvedParams {
143
+ amendment?: ApprovalAmendment;
144
+ approvalId: string;
145
+ /** The decision time as RFC3339, projected from the durable `DecisionApplied` record's own stamp (ADR 45450 D3): optional on the wire so decoders tolerate its absence, always populated by current hosts. */
146
+ decidedAt?: string;
147
+ decidedByCommandId?: string;
148
+ decision: ApprovalDecision;
149
+ itemId: string;
150
+ policyResult: ApprovalPolicyResult;
151
+ resolvedBy: ApprovalResolvedBy;
152
+ sessionId: string;
153
+ sourceRange: SourceRange;
154
+ stageEvidence: ApprovalStageEvidence[];
155
+ /** Present only for a child (native subagent) approval projected onto the parent session's plane (ADR 36182); parent-own approvals omit it. */
156
+ subagentOrigin?: ApprovalSubagentOrigin;
157
+ turnId: string;
158
+ viewCursor: string;
159
+ }
160
+
161
+ export interface ApprovalStage {
162
+ argv: string[];
163
+ argvComplete: boolean;
164
+ position: number;
165
+ requirementId: ApprovalRequirementRef;
166
+ resolution: ApprovalStageResolution;
167
+ suggestedPrefix?: ApprovalSuggestedPrefix;
168
+ totalStages: number;
169
+ }
170
+
171
+ export interface ApprovalStageEvidence {
172
+ argv: string[];
173
+ position: number;
174
+ requirementId: ApprovalRequirementRef;
175
+ resolution: ApprovalStageResolution;
176
+ totalStages: number;
177
+ }
178
+
179
+ export interface ApprovalStageResolution {
180
+ argvPrefix?: string[];
181
+ diagnostic?: string;
182
+ kind: string;
183
+ }
184
+
185
+ /** Child (native subagent) provenance for an approval projected onto the PARENT session's approval plane (#36182 / ADR 36182): identifies the originating child run/agent so a client can attribute the prompt. Omitted (`skip_serializing_if`) on the parent's own approvals, so pre-existing parent frames stay byte-identical. */
186
+ export interface ApprovalSubagentOrigin {
187
+ /** The child run that parked on this approval. */
188
+ childRunId: string;
189
+ /** The child session stream id whose records carry this approval. */
190
+ childSessionId: string;
191
+ /** The originating child's subagent id, from the parent session's durable subagent control records. */
192
+ subagentId: string;
193
+ }
194
+
195
+ /** Open approval subject union. Unknown kinds are rendered generically and never auto-approved by clients (tdd SS5.2). */
196
+ export interface ApprovalSubject {
197
+ access?: string;
198
+ command?: string;
199
+ host?: string;
200
+ /** Open discriminator: `shell | fileAccess | network | unixSocket | process | tool`. */
201
+ kind: string;
202
+ origin?: ApprovalOrigin;
203
+ path?: string;
204
+ port?: number;
205
+ protocol?: string;
206
+ stages?: ApprovalStage[];
207
+ target?: string;
208
+ toolName?: string;
209
+ workspaceRoot?: string;
210
+ }
211
+
212
+ export interface ApprovalSuggestedPrefix {
213
+ argvPrefix: string[];
214
+ label: string;
215
+ }
216
+
217
+ /** `approval/updated` params: the refreshed pending view plus one change. */
218
+ export interface ApprovalUpdatedParams {
219
+ approvalId: string;
220
+ availableChoices: ApprovalChoice[];
221
+ change: ApprovalChange;
222
+ currentRequirementId: ApprovalRequirementRef;
223
+ sessionId: string;
224
+ sourceRange: SourceRange;
225
+ /** Present only for a child (native subagent) approval projected onto the parent session's plane (ADR 36182); parent-own approvals omit it. */
226
+ subagentOrigin?: ApprovalSubagentOrigin;
227
+ subject: ApprovalSubject;
228
+ viewCursor: string;
229
+ }
230
+
231
+ /** One attention flag (tdd SS2.4, ADR 31983 D3): a pending server-initiated request class parked on the session. Open on the wire — clients MUST ignore unknown values; future attention kinds are additive. */
232
+ export type AttentionFlag = "approvalPending" | "inputPending" | (string & {});
233
+
234
+ /** Who durably backgrounded a task (tdd SS4.5.5, `TaskBackgroundedInitiator`). Open — runtime vocabulary. */
235
+ export type BackgroundInitiator = "user" | "timeout" | (string & {});
236
+
237
+ /** The latest branch observation in the snapshot (tdd SS4.6.4, SS4.9.1). */
238
+ export interface BranchState {
239
+ /** The observed branch; `null` on a detached-HEAD observation. */
240
+ branch: string | null;
241
+ /** The detected version-control system; absent when none was detected. */
242
+ vcs?: Vcs;
243
+ /** The observed workspace root. */
244
+ workspaceRoot: string;
245
+ }
246
+
247
+ /** A grantable capability name (SS1.4.4). Open: the reserved `rawLog` entry joins this domain as an additive open-enum extension when SS6 un-defers (#13929, Scenario 5 AS-3) — closed would make that a retype. */
248
+ export type CapabilityName = "userShell" | "sessionMcp" | "sessionListStream" | "feedback" | "computerUseSetup" | (string & {});
249
+
250
+ /** The client's requested capability posture (SS1.4.1). Every member defaults; an absent `capabilities` object means all defaults. */
251
+ export interface ClientCapabilities {
252
+ /** Opt into experimental methods, fields, and variants (default `false`). */
253
+ experimentalApi?: boolean;
254
+ /** Exact notification method names the client declines; no wildcards; unknown names accepted and ignored; the protected set (SS1.7) cannot be opted out. */
255
+ optOutNotificationMethods?: string[];
256
+ /** Names from the capability registry. Unknown entries are not an error and simply do not appear in `grantedCapabilities` — which is why this is a list of free strings rather than of registry names. */
257
+ requestedCapabilities?: string[];
258
+ /** Whether this client can render a `userInput/request` dialog and answer it (SS5.10). **Absent means capable** (D-047): a client that predates the member keeps today's contract, so no existing client changes its handshake. `false` makes the host withhold `userInput/request` toward this client — the D-027 additive-optional-field + withheld-method convention. Deliberately NOT a `requestedCapabilities` name: that registry records operations a host GRANTS (SS1.4.4), and whether a client can draw a dialog is a fact about the client, never a privilege the host hands out. */
259
+ userInputDialogs?: boolean;
260
+ }
261
+
262
+ /** Client identification inside `initialize` params (SS1.4.1). Diagnostics and telemetry attribution only; never an authority claim (SS1.10). */
263
+ export interface ClientInfo {
264
+ /** Machine identifier, `[a-z0-9_]+` (SS1.4.1). */
265
+ name: string;
266
+ /** Human display name. */
267
+ title?: string;
268
+ /** Client version string. */
269
+ version: string;
270
+ }
271
+
272
+ /** The language a Code Mode cell ran in (ADR 42727 D2). Open: values are lowercase VS Code language identifiers, and only `javascript` (the V8 engine) is minted today. */
273
+ export type CodeModeLanguage = "javascript" | (string & {});
274
+
275
+ /** One public-output span inside the item's `visibleOutput` (ADR 42727 D3). Offsets index the UTF-8 encoding of the **decoded** `visibleOutput` string, never the JSON-escaped wire text; both ends fall on code-point boundaries; named and measured like `item/readOutput`'s byte range. */
276
+ export interface CodeModeOutputSpan {
277
+ /** Length of the span, in bytes. Range 0–9007199254740991 inclusive. */
278
+ lengthBytes: number;
279
+ /** Start of the span, in bytes. Range 0–9007199254740991 inclusive. */
280
+ offsetBytes: number;
281
+ /** What the bytes are. */
282
+ stream: CodeModeOutputStream;
283
+ }
284
+
285
+ /** What a Code Mode output span's bytes are (ADR 42727 D3). Open: each engine mints its own values. */
286
+ export type CodeModeOutputStream = "transcript" | (string & {});
287
+
288
+ /** Code Mode's `details` payload (ADR 42727 D2/D3). Every member is absent when it does not apply, never `null`; an empty `outputSpans` list is never served. */
289
+ export interface CodeModeReceipt {
290
+ /** `wait` only, when the producer resolved it: the `itemId` of the `execute` item that started the cell. */
291
+ cellItemId?: string;
292
+ /** `execute`, and `wait` when the producer resolved the originating execute: the language the cell ran in. */
293
+ language?: CodeModeLanguage;
294
+ /** The public cell-output spans, ascending and non-overlapping; absent when there is no cell body or a hook rewrote the served body. */
295
+ outputSpans?: CodeModeOutputSpan[];
296
+ /** `execute` only: the top-level key of the item's `args` object whose value is the cell source. A pointer, never source bytes. */
297
+ sourceArg?: string;
298
+ }
299
+
300
+ /** The uniform SS3.1.2 command acknowledgement: admission only, never an outcome. `session/compact` alone may answer `"noop"`; every other command answers `"accepted"`. */
301
+ export interface CommandAcceptedResult {
302
+ /** Echo of the client-minted UUIDv7 `commandId` (SS3.1.1). */
303
+ commandId: string;
304
+ /** `"accepted"` for every admitted command (SS3.1.2; closed vocabulary). */
305
+ status: CommandAckStatus;
306
+ }
307
+
308
+ /** The ack-status vocabulary (`tdd.md` SS3.1/SS3.1.2): `"accepted"` for every admitted command; `session/compact` alone may answer `"noop"`. Closed: SS3.1.2 names exactly these two values, so SDK clients get a discriminated type and validation catches a wrong status (PR #21550 review) — and a client that received a third value would have been told nothing it can act on, unlike [`TurnStartDisposition`], where "acked, not otherwise classified" is a usable reading. */
309
+ export type CommandAckStatus = "accepted" | "noop";
310
+
311
+ /** The SS3.1.2 ack `status`: `accepted` for every admitted command. `session/compact` is the one method that may additionally answer `noop` ([`crate::method::runtime::CompactStatus`]); no other command uses another status (tdd SS3.1.2). */
312
+ export type CommandStatus = "accepted" | (string & {});
313
+
314
+ /** `session/compact`'s ack status (tdd SS3.7): the one method that may answer `noop` in addition to the SS3.1.2 `accepted`. A noop is a success, not an error, and it is durably settled like any other outcome. */
315
+ export type CompactStatus = "accepted" | "noop" | (string & {});
316
+
317
+ /** Compaction outcome (tdd SS4.5.10, the SS3.7 vocabulary). Open. */
318
+ export type CompactionOutcome = "compacted" | "noop" | "failed" | "cancelled" | (string & {});
319
+
320
+ /** What initiated a compaction (tdd SS4.5.10). Open. */
321
+ export type CompactionTrigger = "manual" | "auto" | (string & {});
322
+
323
+ /** One row of the Settings blocked-apps list. */
324
+ export interface ComputerUseBlockedApp {
325
+ /** The app's bundle ID, or the family prefix when `prefix` is true. */
326
+ bundleId: string;
327
+ /** A built-in block, which Settings cannot remove (ADR 630 D18.8). */
328
+ locked: boolean;
329
+ /** A built-in family row: it blocks every bundle ID that starts with `bundleId`. Omitted means false; only locked rows are prefixes. */
330
+ prefix?: boolean;
331
+ }
332
+
333
+ /** A capability dropdown's value (ADR 630 D18.4). **Open**: the read result carries it, so an older client tolerates a value it does not know. */
334
+ export type ComputerUseChoice = "ask" | "alwaysAllow" | (string & {});
335
+
336
+ /** One macOS permission as setup last saw it. **Open**, like the phase. */
337
+ export type ComputerUsePermission = "granted" | "missing" | "unknown" | (string & {});
338
+
339
+ /** `computerUseSettings/read` result, also answered by `computerUseSettings/update`. */
340
+ export interface ComputerUseSettings {
341
+ /** The user's blocks in the order they were added, then the built-in blocks when `showBuiltIns` asked for them. */
342
+ blockedApps: ComputerUseBlockedApp[];
343
+ /** The computer-control dropdown, as it applies: `ask` while the stored blocked-apps list can't be read (ADR 630 D18.4). */
344
+ computerControl: ComputerUseChoice;
345
+ /** The screenshots dropdown, under the same rule. */
346
+ screenshots: ComputerUseChoice;
347
+ }
348
+
349
+ /** `computerUseSettings/read` params. */
350
+ export interface ComputerUseSettingsReadParams {
351
+ /** Also list the built-in blocks as locked rows (the D18.8 toggle). Omitted means false. */
352
+ showBuiltIns?: boolean;
353
+ }
354
+
355
+ /** `computerUseSettings/update` params: a patch. Omitted members are left alone; the whole patch applies or none of it does. */
356
+ export interface ComputerUseSettingsUpdateParams {
357
+ /** Bundle IDs to add to the user's blocked apps. A built-in block is refused: it is already blocked. */
358
+ blockApps?: string[];
359
+ /** The new computer-control dropdown value. */
360
+ computerControl?: ComputerUseChoice;
361
+ /** The new screenshots dropdown value. */
362
+ screenshots?: ComputerUseChoice;
363
+ /** Bundle IDs to remove from the user's blocked apps. Only the user's own entries can be removed; a built-in block stays. */
364
+ unblockApps?: string[];
365
+ }
366
+
367
+ /** `computerUseSetup/changed` params. */
368
+ export interface ComputerUseSetupChanged {
369
+ /** The session whose setup state changed. */
370
+ sessionId: string;
371
+ /** Its new state. */
372
+ state: ComputerUseSetupState;
373
+ }
374
+
375
+ /** Where the session's setup stands: `cua_setup`'s state codes, camelCase. **Open**: a result vocabulary, so an older client tolerates a new state. */
376
+ export type ComputerUseSetupPhase = "dormant" | "inProgress" | "restartRequired" | "readyForTarget" | "stopped" | (string & {});
377
+
378
+ /** `computerUseSetup/read` params. */
379
+ export interface ComputerUseSetupReadParams {
380
+ /** The session whose setup to read. */
381
+ sessionId: string;
382
+ }
383
+
384
+ /** `computerUseSetup/start` params: a human command. */
385
+ export interface ComputerUseSetupStartParams {
386
+ /** The client's id for this command. */
387
+ commandId: string;
388
+ /** The session whose setup to start. */
389
+ sessionId: string;
390
+ }
391
+
392
+ /** The session's setup state: the result of both methods and the `computerUseSetup/changed` payload's `state`. */
393
+ export interface ComputerUseSetupState {
394
+ /** Accessibility. */
395
+ accessibility: ComputerUsePermission;
396
+ /** Input Monitoring: computer use is ready without it; some actions need it. */
397
+ inputMonitoring: ComputerUsePermission;
398
+ /** The sentence `cua_setup` gives the user for this answer. */
399
+ message?: string;
400
+ /** The `cua_setup` refusal code when the call was refused, verbatim. */
401
+ refused?: string;
402
+ /** Screen Recording. */
403
+ screenRecording: ComputerUsePermission;
404
+ /** Where setup stands. */
405
+ setup: ComputerUseSetupPhase;
406
+ }
407
+
408
+ /** Context pressure level (tdd SS4.6.6): hard threshold first, both inclusive `>=`. Open. */
409
+ export type ContextPressureLevel = "normal" | "warning" | "blocked" | (string & {});
410
+
411
+ /** The SS4.9.1 snapshot `contextUsage` block: the latest `(windowTokens, usedTokens, pressure)` triple; the snapshot member is `null` until the fold's generation chain holds a tracked anchor AND the current basis is present (absent is never fabricated). */
412
+ export interface ContextUsage {
413
+ /** Server-computed pressure level. */
414
+ pressure: ContextPressureLevel;
415
+ /** Counted-once occupancy at the latest provider-reported fact. */
416
+ usedTokens: number;
417
+ /** The effective context-window size; absent when the basis has no limit. */
418
+ windowTokens?: number;
419
+ }
420
+
421
+ /** Cron's `details` payload (ADR 42728 D2, thirteenth directive). Every field a family owns lives here, under the container's one `details` key, rather than flat beside the discriminators — ADR 43399 D5 as amended. Each is a **bounded machine fact**: scalars, short identifiers and a small fixed-shape array of those. */
422
+ export interface CronReceipt {
423
+ /** Cron `create` and `delete`: the job id. On `delete`'s `missing` arm this is the caller's own id echoed back under ADR 43399 D1's declared echo — that arm has no server-side subject to name. Also the field ADR 42728 D4's D8 declaration names as conveying the hidden fact on the declared `created` + `cancelled` pairing: a job row was committed and will fire. */
424
+ jobId?: string;
425
+ /** Cron `list`: the served jobs in server order, `active` and `firing` rows only. */
426
+ jobs?: CronReceiptJob[];
427
+ /** Cron `create` (`created`, `duplicate`): absolute epoch-milliseconds of the job's next scheduled fire (the existing job's on `duplicate`, ADR 42728 D2). */
428
+ nextFireAtMs?: number;
429
+ }
430
+
431
+ /** One row of the Cron `list` receipt's `jobs` array (ADR 42728 D2). Server order, and **`active` + `firing` rows only** — the owner's `Serve active+firing only` directive. A small fixed-shape array of scalars, which is what keeps it inside D5's bounded-machine-fact rule. */
432
+ export interface CronReceiptJob {
433
+ /** The job's server-owned id. */
434
+ jobId: string;
435
+ /** Absolute epoch-milliseconds of the job's next scheduled fire. */
436
+ nextFireAtMs: number;
437
+ }
438
+
439
+ /** Server-computed session cost member of [`CumulativeTokenUsage`] (tdd SS4.6.5, Amendment #41610 FR-41610-2/3). */
440
+ export interface CumulativeCost {
441
+ /** True when at least one leg lacked price data — clients render `(partial)`. */
442
+ partial: boolean;
443
+ /** Estimated USD total, finite and non-negative. */
444
+ usd: number;
445
+ }
446
+
447
+ /** Session running totals of counted-once usage (tdd SS4.6.5). Amendment #41610: the cache splits and server-computed `cost` join the counters. The counters stay accumulate-only; `cost` is the documented exception — it may move either way on price re-adoption and is labeled estimate (INV-41610-1). `Copy` was dropped for the `cost` member. */
448
+ export interface CumulativeTokenUsage {
449
+ /** Cache-read tokens, session total (FR-41610-1): saturating sum of the per-completion splits; an absent split contributes 0. Additive-optional: absent on the wire reads as 0 and zero totals are omitted, so pre-feature bytes decode and re-encode identically. */
450
+ cacheReadTokens?: number;
451
+ /** Cache-write tokens, session total (FR-41610-1). Additive-optional like the read split. */
452
+ cacheWriteTokens?: number;
453
+ /** Server-computed session cost (FR-41610-2): `None` (wire-absent) when no leg is priced — clients omit the row. Additive-optional: absent reads as unpriced. */
454
+ cost?: CumulativeCost;
455
+ /** Output tokens, session total. */
456
+ outputTokens: number;
457
+ /** Counted-once prompt tokens, session total. */
458
+ promptTokens: number;
459
+ /** Counted-once totals, session total. */
460
+ totalTokens: number;
461
+ }
462
+
463
+ /** The effective approval-mode projection (`EffectiveApprovalModeState`, tdd SS5.12): the same object `session/setApprovalMode` returns as `effectiveMode` and the `Session` object carries as `approvalMode`. */
464
+ export interface EffectiveApprovalModeState {
465
+ /** The command that last set it; `null` when no command did. */
466
+ lastCommandId: string | null;
467
+ /** The mode in effect. */
468
+ mode: ApprovalMode;
469
+ /** How the mode took effect. */
470
+ source: ApprovalModeSource;
471
+ }
472
+
473
+ /** The latest effective-model fact in the snapshot (tdd SS4.9.1). */
474
+ export interface EffectiveModel {
475
+ /** The selected model. */
476
+ modelId: string;
477
+ /** The selected provider; `null` when the selection names none. */
478
+ providerId: string | null;
479
+ /** What drove the selection. */
480
+ source: ModelChangeSource;
481
+ }
482
+
483
+ /** The optional `error.data` object (SS1.6). All members additive-optional; `kind` is always present when `data` is. */
484
+ export interface ErrorData {
485
+ /** The next provable UTF-8 boundary on a misaligned text-media `item/readOutput` read (`-32602` `invalidParams`, FR-016b/D-17214-2): absent when no boundary is provable from the stored bytes ahead. */
486
+ alignedNextOffset?: number;
487
+ /** The rejected anchor value on `notFound`/`missingAnchor` and the `-32042` boundary arms (SS4.7.3, SS4.11); on `-32042` it is served as an explicit `null` when the request named no concrete anchor (spec 208 FM-005). */
488
+ anchor?: string | null;
489
+ /** Approval identity on SS5 errors. */
490
+ approvalId?: string;
491
+ /** The stored output's availability on `outputUnavailable` — the durable `ToolOutputAvailability` value, read-time-derived when the durable record still says `available` (SS4.5.5; spec 208 FM-008). */
492
+ availability?: string;
493
+ /** The missing capability, on `capabilityRequired` errors. Typed on the grantable registry, so `rawLog` is outside the v1 domain and joins it as an additive open-enum extension when SS6 un-defers (TEST-009). */
494
+ capability?: CapabilityName;
495
+ /** The configured command-admission bound, on `backpressured` errors. */
496
+ capacity?: number;
497
+ /** Rejected server-minted choice on `approvalChoiceInvalid`. */
498
+ choiceId?: string;
499
+ /** The rejected command's identifier, on `commandRejected` errors. The ratified v1 contract pairs it with `reason` (specs/13929-msp-activation/tdd.md SS3.6 admission-failure table and its `-32030` example), so a client can settle the exact command it sent without parsing the message string. */
500
+ commandId?: string;
501
+ /** Current stage token on `approvalRequirementStale`. */
502
+ currentRequirementId?: ApprovalRequirementRef;
503
+ /** SS1.5.1 descriptor, on `experimentalRequired` errors. */
504
+ descriptor?: string;
505
+ /** Free-form additive detail. */
506
+ details?: Record<string, unknown>;
507
+ /** The oldest servable view position on `viewTruncated` (`-32040`, SS4.11); served as an explicit `null` when nothing before the head is servable — the null is present on the wire, never a dropped key (spec 208 FM-005 / Scenario 6.2). */
508
+ earliestCursor?: string | null;
509
+ /** The item whose stored output was requested, on the `item/readOutput` arms (`notFound`, `outputUnavailable`, and the misaligned-offset `invalidParams`). */
510
+ itemId?: string;
511
+ /** The stable camelCase category clients branch on. */
512
+ kind: ErrorKind;
513
+ /** Rejected inclusive fork boundary on `forkBoundaryInvalid`. */
514
+ lastTurnId?: string;
515
+ /** The latest installed boundary's view cursor on the `-32042` arms — always present in the `-32042` JSON and explicitly `null` when no boundary exists (SS4.11, FM-004). */
516
+ latestBoundaryCursor?: string | null;
517
+ /** The exceeded byte limit, on `inputTooLarge` errors. */
518
+ limitBytes?: number;
519
+ /** The store on `pluginNotFound` (`-32035`, SS3.29.1). */
520
+ marketplace?: string;
521
+ /** The rejected marketplace name on `marketplaceNotFound` (`-32034`, SS3.29.7) and `marketplaceAlreadyExists` (`-32036`, SS3.29.2); the rejected plugin name on `pluginNotFound` (`-32035`, SS3.29.1). */
522
+ name?: string;
523
+ /** The requested `outputRef.id`, on the same `item/readOutput` arms. */
524
+ outputRef?: string;
525
+ /** Candidate retained paths on `sessionAmbiguous`. */
526
+ paths?: string[];
527
+ /** Failure detail vocabulary (e.g. `"missingAnchor"` on `notFound` for a missing view-cursor anchor). */
528
+ reason?: string;
529
+ /** Winning resolution on `approvalAlreadyResolved`. */
530
+ resolution?: ApprovalResolutionSummary;
531
+ /** Whether retrying can succeed (e.g. `overloaded`). When present, overrides the error table row's `retryable` default for this code. */
532
+ retryable?: boolean;
533
+ /** Why the branch seed did not use a checkpoint, on the same arms: one of `no_usable_checkpoint`, `unsupported_checkpoint_shape`, `checkpoint_has_model_visible_tail`, `checkpoint_missing_suffix`; absent when the seed used a checkpoint or no fallback was recorded. */
534
+ seedFallbackReason?: string;
535
+ /** The branch-seed path the host read before rejecting, on branch-validation rejections (`session/fork`, `session/sideChat`: the `forkBoundaryInvalid`, `commandRejected` and `sessionNotFound` arms; SS2.5.3, SS2.5.7; #51365): one of `runtime_checkpoint_tail`, `runtime_full_replay`, `legacy_session_data` — the durable branch-seed vocabulary, so the client cites the real seed decision instead of guessing at a stale binary. */
536
+ seedPath?: string;
537
+ /** The rejected skill selector on `skillNotFound` (`-32032`, SS3.22.4). */
538
+ selector?: string;
539
+ /** Session identity on errors whose lookup is session-scoped. */
540
+ sessionId?: string;
541
+ /** Winning settlement on `userInputAlreadySettled`. */
542
+ settlement?: UserInputSettlementSummary;
543
+ /** The rejected upload id on `uploadNotFound` (`-32038`, SS3.33). */
544
+ uploadId?: string;
545
+ /** User-input prompt identity on SS5.10 errors. */
546
+ userInputId?: string;
547
+ /** The blocked view position on `pageEventTooLarge` errors. */
548
+ viewCursor?: string;
549
+ }
550
+
551
+ /** A stable `error.data.kind` category (SS1.6): camelCase, the value clients branch on. Open: SS2–SS5 lanes add kinds additively as their methods land (Appendix B already registers them), and the spec's edge-case rule makes a new `kind` additive only because this domain is declared open. */
552
+ export type ErrorKind = "parseError" | "invalidRequest" | "notInitialized" | "alreadyInitialized" | "methodNotFound" | "invalidParams" | "experimentalRequired" | "internal" | "pageEventTooLarge" | "outputResultTooLarge" | "overloaded" | "inputTooLarge" | "capabilityRequired" | "notFound" | "interrupted" | "cancelled" | "sessionNotFound" | "sessionInUse" | "sessionAmbiguous" | "forkBoundaryInvalid" | "sessionNotLoaded" | "sessionStreamMismatch" | "commandRejected" | "backpressured" | "skillNotFound" | "computerUseUnavailable" | "marketplaceNotFound" | "pluginNotFound" | "marketplaceAlreadyExists" | "pluginMutationsDisabled" | "uploadNotFound" | "viewTruncated" | "outputUnavailable" | "boundaryPruned" | "boundaryUnusable" | "noBoundary" | "approvalNotFound" | "approvalAlreadyResolved" | "approvalChoiceInvalid" | "approvalRequirementStale" | "approvalReviewerUnavailable" | "userInputNotFound" | "userInputAlreadySettled" | "userInputAnswerInvalid" | (string & {});
553
+
554
+ /** The `error` member of an error response (SS1.2 §2.4). */
555
+ export interface ErrorObject {
556
+ /** Registry code (Appendix B). Typed as a plain integer on the wire; the value domain is the registry below (INV-018). */
557
+ code: number;
558
+ /** Structured detail; carries `kind` when present. */
559
+ data?: ErrorData;
560
+ /** Human-readable message. Never a branch point (SS1.6). */
561
+ message: string;
562
+ }
563
+
564
+ /** An error response frame (SS1.2 §2.4). Exactly one of `result` or `error` appears on a response; this type is the `error` half. */
565
+ export interface ErrorResponse {
566
+ /** The error payload (Appendix B registry). */
567
+ error: ErrorObject;
568
+ /** Echo of the request id; `null` **only** for an unrecoverable parse error whose offending id could not be recovered (SS1.3). Always serialized, so `None` renders as `null` rather than being omitted — required-but-nullable (see [`require_nullable_id`]). */
569
+ id: RequestId | null;
570
+ /** The literal `"2.0"`. */
571
+ jsonrpc: JsonRpcVersion;
572
+ }
573
+
574
+ /** `feedback/submit` classification (tdd SS3.25): the four TUI classes in camelCase wire spelling. **Closed**: a client-selected param vocabulary (#22785 E2). */
575
+ export type FeedbackClassification = "bug" | "badResult" | "goodResult" | "other";
576
+
577
+ /** `feedback/submit` result `outcome` (tdd SS3.25): how one confirmed submit resolved, mirroring the TUI `FeedbackSubmitOutcome` taxonomy. **Open**: a server-produced result vocabulary (#22785 E2) — an older client reading a newer value it does not know follows the open-enum tolerance rule instead of rejecting it. */
578
+ export type FeedbackSubmitOutcome = "uploaded" | "recorded" | "acceptedWithoutReceipt" | "trackingFailed" | "trackingUncertain" | "dark" | "disabled" | "noCredential" | "authRejected" | "rateLimited" | "failed" | (string & {});
579
+
580
+ /** `feedback/submit` params (tdd SS3.25): mirrors the TUI confirm-time `FeedbackRequest`. The call itself is the explicit confirm. */
581
+ export interface FeedbackSubmitParams {
582
+ /** Consent to attach the session record; honored only for `bug`/`badResult` with `session_id` present. `true` with `with_files: false`, with a non-`bug`/`badResult` classification, or without `session_id` is `invalidParams` (F4, F8). Defaults to `false`. */
583
+ attachSessionRecord?: boolean;
584
+ /** The report class (required). */
585
+ classification: FeedbackClassification;
586
+ /** An absolute same-host path to a client-packed bundle, admitted only as a regular file under a size cap. */
587
+ clientArtifactsPath?: string;
588
+ /** The user report text (required; non-empty for `bug`). */
589
+ note: string;
590
+ /** Names the session this call is about when present (F8, superseding F3): the bundle lands in that session's dir. Names a session this host owns. When absent, the bundle lands in the host-level feedback folder and the `session_id` tag is omitted. */
591
+ sessionId?: string;
592
+ /** The files-consent decision (required). */
593
+ withFiles: boolean;
594
+ }
595
+
596
+ /** `feedback/submit` result (tdd SS3.25): the upload receipt. */
597
+ export interface FeedbackSubmitResult {
598
+ /** The host-local absolute path of the always-written local bundle. */
599
+ bundlePath: string;
600
+ /** The failure cause on the `failed`, `acceptedWithoutReceipt`, `trackingFailed`, and `trackingUncertain` arms. */
601
+ cause?: string;
602
+ /** The consent-vs-reality local-tracing note, kept for display. */
603
+ localTracingNote?: string;
604
+ /** How the submit resolved. */
605
+ outcome: FeedbackSubmitOutcome;
606
+ /** The effective retry delay in milliseconds, on `rateLimited`. */
607
+ retryAfterMs?: number;
608
+ /** The consent-vs-reality session note, kept for display. */
609
+ sessionNote?: string;
610
+ /** Whether the consented session record rode at all. */
611
+ sessionRecordAttached: boolean;
612
+ /** Whether the consented session record rode shortened to fit. */
613
+ sessionRecordTruncated: boolean;
614
+ /** The internal receipt-Task id once that Task succeeds. */
615
+ taskId?: string;
616
+ /** The intake's accept id — always present on the `uploaded` arm, optional on `trackingFailed`/`trackingUncertain`; never fabricated on `recorded`. */
617
+ uploadId?: string;
618
+ }
619
+
620
+ /** Where a fork cuts the source history (tdd SS2.5.3). Turn ids are used instead of counts because ids stay stable across compaction and concurrent appends while indices do not. */
621
+ export interface ForkCutPoint {
622
+ /** The last completed turn to copy, inclusive. Naming an in-progress or unknown turn fails `forkBoundaryInvalid`. */
623
+ lastTurnId: string;
624
+ }
625
+
626
+ /** Fork provenance folded from the durable `session.fork.created` record (`ForkProvenance`, tdd SS2.4). */
627
+ export interface ForkProvenance {
628
+ /** The `commandId` of the `session/fork` that created it. */
629
+ commandId: string;
630
+ /** An **opaque provenance string** preserved verbatim from the durable record. Display-only — not one of the SS6.2 cursor families: clients MUST NOT parse it and no method accepts it (tdd SS2.4). */
631
+ cutCursor: string;
632
+ /** Whether the fork named an explicit cut point. */
633
+ cutExplicit: boolean;
634
+ /** The source session this fork was cut from. */
635
+ sessionId: string;
636
+ }
637
+
638
+ /** The session goal block (tdd SS4.6.2, mirrors the runtime's goal state, camelCased). `status` and `percentComplete` are carried **verbatim** — out-of-contract status strings and >100 percents pass through; display clamping is the renderer's job. */
639
+ export interface Goal {
640
+ /** Current work description, when present. */
641
+ currentWork?: string;
642
+ /** Next work description, when present. */
643
+ nextWork?: string;
644
+ /** The goal objective text. */
645
+ objective: string;
646
+ /** Percent complete, verbatim (>100 passes through). */
647
+ percentComplete: number;
648
+ /** Goal status, verbatim from the durable goal state (free string by design: out-of-contract values pass through). */
649
+ status: string;
650
+ }
651
+
652
+ /** `goal/clear` params (tdd SS3.18). An `objective` here is an unknown field and rejects `-32602 invalidParams` — the bare verbs carry exactly this pair. */
653
+ export interface GoalClearParams {
654
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
655
+ commandId: string;
656
+ /** The target session. */
657
+ sessionId: string;
658
+ }
659
+
660
+ /** The shared SS3.18 goal ack, admission-only: all five verbs answer this one shape (the tdd's "Shared contract"), differing only in when `turnId` is present. */
661
+ export interface GoalCommandResult {
662
+ /** Echoes the client's id. */
663
+ commandId: string;
664
+ /** Admission status. */
665
+ status: CommandStatus;
666
+ /** Present by exactly the four SS3.18 result cases: an idle wake carries the fresh goal turn's id; a busy `set`/`edit`/`resume` carries the admission-time active turn's id (a routing fact, not a delivery promise); `pause`/`clear` never carry it; an idle admission whose resulting goal is not unfinished parks the notification and carries none. **Additive-optional**: absent means "no turn named", never fabricated. */
667
+ turnId?: string;
668
+ }
669
+
670
+ /** `goal/edit` params (tdd SS3.18): replace the current goal's objective. Same shape as `goal/set`; the verbs differ in their `missing_goal` precondition, not their payload. */
671
+ export interface GoalEditParams {
672
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
673
+ commandId: string;
674
+ /** The replacement objective; same trim/non-empty rule as `goal/set`. */
675
+ objective: string;
676
+ /** The target session. */
677
+ sessionId: string;
678
+ }
679
+
680
+ /** `goal/pause` params (tdd SS3.18); shape as `goal/clear`. */
681
+ export interface GoalPauseParams {
682
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
683
+ commandId: string;
684
+ /** The target session. */
685
+ sessionId: string;
686
+ }
687
+
688
+ /** `goal/resume` params (tdd SS3.18); shape as `goal/clear`. */
689
+ export interface GoalResumeParams {
690
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
691
+ commandId: string;
692
+ /** The target session. */
693
+ sessionId: string;
694
+ }
695
+
696
+ /** `goal/set` params (tdd SS3.18): set the session's goal objective. */
697
+ export interface GoalSetParams {
698
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
699
+ commandId: string;
700
+ /** The objective text; required, non-empty after Unicode-whitespace trim (the trimmed text is the payload). Empty-after-trim is `-32602 invalidParams` (tdd SS3.18). */
701
+ objective: string;
702
+ /** The target session. */
703
+ sessionId: string;
704
+ }
705
+
706
+ /** What history a lifecycle result actually served (tdd SS2.5.2). Open on the client side: report-what-was-served means a client treats an unknown mode as "page it yourself". */
707
+ export type HistoryMode = "anchoredSnapshot" | "inline" | "snapshot" | "none" | (string & {});
708
+
709
+ /** Why a result served `history.mode: "none"` — spec 208 FM-005's typed unavailability (tdd SS2.5.2; D-050). Open on the client side: an absent (older server) or unknown (newer server) value decodes conservatively as an unknown reason, and `viewCursor` text never substitutes for it (spec 208 INV-19734-1). */
710
+ export type HistoryNoneReason = "excluded" | "cursorSuffix" | "historyBudget" | "projectionUnavailable" | "projectionReadLimit" | (string & {});
711
+
712
+ /** The `history` request preference of `session/resume` (tdd SS2.5.2). The forced values downgrade `anchored` → `inline` → `snapshot` → `none`; under `auto` the full rung order is anchoredSnapshot → inline → snapshot → elided snapshot → none. */
713
+ export type HistoryPreference = "auto" | "inline" | "snapshot" | "anchored";
714
+
715
+ /** One installed handler (tdd SS3.26.1). */
716
+ export interface HookCatalogEntry {
717
+ /** The row's own switch (tdd SS3.26.1). Non-enabled rows are included as `false`, never dropped. */
718
+ enabled: boolean;
719
+ /** The event the handler runs on (ADR 33398 D7 item 2). */
720
+ event: HookEventName;
721
+ /** Where the handler comes from (ADR 33398 D7 item 1). */
722
+ handlerKind: HookHandlerKind;
723
+ /** The handler key (config key or plugin hook id). */
724
+ key: string;
725
+ }
726
+
727
+ /** Hook event names (tdd SS3.26.1, ADR 33398 D7 item 2): the lowercase-first-letter spelling of every `HookEventKind::all()` variant. Open (server-produced result vocabulary, the #22785 enum-openness rule): a future event value is additive. */
728
+ export type HookEventName = "sessionStart" | "userPromptSubmit" | "preToolUse" | "permissionRequest" | "postToolUse" | "preCompact" | "postCompact" | "subagentStart" | "subagentStop" | "stop" | "sessionEnd" | "notification" | "postToolUseFailure" | "stopFailure" | "postToolBatch" | "interrupt" | "sessionFork" | "toolUseStart" | "preLLMCall" | "postLLMCall" | (string & {});
729
+
730
+ /** A hook row's origin (tdd SS3.26.1, ADR 33398 D7 item 1): the config `HookSourceKind` values plus plugin-contributed. Open (server-produced result vocabulary, the #22785 enum-openness rule): a future origin is additive. */
731
+ export type HookHandlerKind = "managed" | "user" | "project" | "plugin" | (string & {});
732
+
733
+ /** `hook/list` params (tdd SS3.26.1). Per-session because hook scope follows the session's workspace and plugin state. */
734
+ export interface HookListParams {
735
+ /** The target session. */
736
+ sessionId: string;
737
+ }
738
+
739
+ /** `hook/list` result (tdd SS3.26.1): one row per installed handler per event — a `ResolvedHookHandler` carries one event, and grouping would lose matcher/command identity (ADR 33398 D7 item 1). */
740
+ export interface HookListResult {
741
+ /** The session's installed hook rows (tdd SS3.26.1 promises the set, not an order). */
742
+ hooks: HookCatalogEntry[];
743
+ }
744
+
745
+ /** `hookRun` durable outcome (tdd SS4.5.11). Open: new outcomes are additive, and clients MUST render unknown values generically. */
746
+ export type HookRunStatus = "completed" | "blocked" | "failed" | "timedOut" | "cancelled" | (string & {});
747
+
748
+ /** Disposition when a turn is already running (tdd SS3.2). The wire default is `queue`: an SDK caller who has not looked at session state should not silently mutate an in-flight turn. */
749
+ export type IfBusy = "queue" | "steer" | "replace";
750
+
751
+ /** `initialize` request params (SS1.4.1). */
752
+ export interface InitializeParams {
753
+ /** Capability posture; absent means all defaults. */
754
+ capabilities?: ClientCapabilities;
755
+ /** Client identification. */
756
+ clientInfo: ClientInfo;
757
+ }
758
+
759
+ /** The `initialize` result (SS1.4.1). */
760
+ export interface InitializeResult {
761
+ /** Echo of the effective negotiated experimental setting. */
762
+ experimentalApi: boolean;
763
+ /** Subset of the requested capabilities, plus policy-implicit grants. Fixed for the connection lifetime (INV-009). */
764
+ grantedCapabilities: CapabilityName[];
765
+ /** Absolute path of the muse home directory. */
766
+ museHome: string;
767
+ /** Server runtime platform family. */
768
+ platformFamily: PlatformFamily;
769
+ /** Server operating system. */
770
+ platformOs: PlatformOs;
771
+ /** Envelope schema version and stable-surface fingerprint. */
772
+ schema: SchemaInfo;
773
+ /** Server identification. */
774
+ serverInfo: ServerInfo;
775
+ /** Whether this host persists its sessions (SS2.13). Optional so the addition is additive under SS1.5.4; a v1 host always sends it, and a client reads absent as `durable` because no server that omits it has the ephemeral profile. */
776
+ sessionDurability?: SessionDurability;
777
+ /** Exact user-agent string presented to upstream model providers. */
778
+ userAgent: string;
779
+ }
780
+
781
+ /** One transcript item at one revision (tdd SS4.4.1 common fields plus the per-kind fields of SS4.5.2–4.5.11, all optional and owned by the kind their doc names). `item/started`, `item/updated`, and `item/completed` carry the full object; `item/delta` appends to it by field path. */
782
+ export interface Item {
783
+ /** `subagent`: agent definition path. */
784
+ agentPath?: string;
785
+ /** `toolCall`: the approval that gated this call (tdd SS5); join key for the approval view events. */
786
+ approvalId?: string;
787
+ /** `toolCall`: the model-authored argument JSON, **verbatim**; clients parse. Verbatim keeps the fold byte-deterministic and survives model-emitted almost-JSON (tdd SS4.5.5). */
788
+ args?: string;
789
+ /** `userMessage`: image attachment metadata only — base64 payloads are not echoed back on the view (tdd SS4.5.2). */
790
+ attachments?: MessageAttachment[];
791
+ /** `toolCall`: `true` once the task was durably backgrounded; delivered via `item/updated`. */
792
+ background?: boolean;
793
+ /** `toolCall`: who backgrounded the task; absent on pre-split records — never inferred (tdd SS4.5.5). */
794
+ backgroundInitiator?: BackgroundInitiator;
795
+ /** `reminderChild`: `true` when this child is a blocking reminder (it holds the turn open until it settles); absent otherwise, never `false` (ADR 41191 D4). The status word stays off the wire; clients name the reminder from `reminderAgentId`. */
796
+ blocking?: boolean;
797
+ /** `toolCall`: the provider call id (`call_...`), opaque. */
798
+ callId?: string;
799
+ /** `workflow`: one `outputRef`-shaped link per recorded child spawn with an objective (`kind: "workflow_child_prompt"`), fetched via `item/readOutput` (tdd SS4.5.8/SS4.7.4, #45449). */
800
+ childPromptRefs?: OutputRef[];
801
+ /** `subagent`/`reminderChild`: the child's own session id, readable via `session/read`/`view/page` — child transcript drill-down without a second protocol (tdd SS4.5.7). */
802
+ childSessionId?: string;
803
+ /** `reminderChild`: parent-session-dir-relative child log path; absent when no filesystem log. */
804
+ childSessionLogPath?: string;
805
+ /** `workflow`: folded per-child state, keyed by `(childId, attempt)`, re-emitted whole on every change — the item `revision` is the ordering guard (tdd SS4.5.8). */
806
+ children?: WorkflowChild[];
807
+ /** `userMessage`/`userShell`: the submitting command — multi-client UIs de-duplicate their local echo on it. */
808
+ commandId?: string;
809
+ /** `userShell`: the command text as submitted. */
810
+ commandText?: string;
811
+ /** `subagent`: camelCased `SubagentControlStatus` (open enum); `status` stays the generic item vocabulary. */
812
+ controlStatus?: SubagentControlStatus;
813
+ /** `workflow`: the run-level declared-phase label — the last `Phase` detail-row label of the reconciled projection; terminal-only, absent while live (tdd SS4.5.8, #45449). */
814
+ declaredPhase?: string;
815
+ /** `subagent`: nesting depth. */
816
+ depth?: number;
817
+ /** `userMessage`: presentation form (tdd SS3.2); absent when the client sent none. */
818
+ displayText?: string;
819
+ /** `userShell`/`subagent`: observed wall-clock duration. `workflow`: the run's wall time from launch to reconciliation, set only on the settling `item/completed` — never a sum of child durations. */
820
+ durationMs?: number;
821
+ /** `workflow`: launched entry identity. */
822
+ entryId?: string;
823
+ /** `hookRun`: the hook event in Q2 camelCase vocabulary (tdd SS4.5.11). */
824
+ event?: HookEventName;
825
+ /** `userShell`: the process exit code, when it exited by code. */
826
+ exitCode?: number;
827
+ /** `userShell`: the terminating signal NUMBER, when signalled (e.g. 9) — the durable payload verbatim; nothing maps numbers to names, and the fold never invents one. */
828
+ exitSignal?: number;
829
+ /** `toolCall`: machine-readable failure class (`TaskFailureKind`, snake_case verbatim — durable runtime vocabulary, the SS1.6 casing exemption). */
830
+ failureKind?: string;
831
+ /** `toolCall`/`subagent`: `Failed`/`Rejected`/`Cancelled` reason text, verbatim. */
832
+ failureReason?: string;
833
+ /** Server-provided one-line human summary any kind MAY carry, for generic rendering of kinds a client does not recognize; new kinds SHOULD carry it during their first release cycle (tdd SS4.10). */
834
+ fallbackText?: string;
835
+ /** `workflow`: the human terminal summary projected from the reconciled Launch envelope, bounded at the 64 KiB surface budget; terminal-only (tdd SS4.5.8, #45449). */
836
+ finalSummary?: string;
837
+ /** `reminderChild`: the reminder generation. */
838
+ generationId?: number;
839
+ /** `hookRun`: the durable `hook_key` (tdd SS4.5.11). */
840
+ hookKey?: string;
841
+ /** Bare UUIDv7; the item's identity across its whole lifecycle. Identity rule (tdd SS4.4.1): the task id for task-backed kinds (`toolCall`, `subagent`), the pre-minted commit `message_id` for delta-streamed kinds (`agentMessage`, `reasoning`), and the opening durable record's event id for everything else. Opaque to clients. */
842
+ itemId: string;
843
+ /** The item kind (open enum): clients MUST render unknown kinds generically — kind name plus `status` plus `fallbackText` (tdd SS4.10). */
844
+ kind: ItemKind;
845
+ /** `hookRun`: capped display label (tdd SS4.5.11). */
846
+ label?: string;
847
+ /** `workflow`: the reconciled terminal message, set on completion. */
848
+ message?: string;
849
+ /** `toolCall`: rich content the model saw beyond text; base64 is not inlined on the view (tdd SS4.5.5). */
850
+ modelVisibleContent?: ModelVisibleContent[];
851
+ /** `subagent`: objective as spawned, bounded on the wire at the 64 KiB retained-text budget (tdd SS4.5.4, ADR 35691 D9); a cut sets `truncated`. The durable record stays verbatim. */
852
+ objective?: string;
853
+ /** `compaction`: terminal only — folds installed/fallback status. */
854
+ outcome?: CompactionOutcome;
855
+ /** `toolCall`/`userShell`: stored-output reference; fetch the full bytes via `item/readOutput` (served by #208). */
856
+ outputRef?: OutputRef;
857
+ /** `toolCall`: stored structured-patch reference (`kind: "tool_patch"`, `mediaType: "application/json"`); the body is fetched via `item/readOutput` with `patchRef.id`, and the ref survives the SS2.5.2 elided-snapshot rung exactly like `outputRef` without ever being an elision trigger (tdd SS2.5.2, SS4.5.5; #33025). */
858
+ patchRef?: OutputRef;
859
+ /** `toolCall`: server-authored edit-family diff summary (#33025) — always beside `patchRef`; absent = no diff available (tdd SS4.5.5). */
860
+ patchSummary?: PatchSummary;
861
+ /** `workflow`: `true` only while a durable pause fact is in force for the run's generation; absent otherwise, never `false` (tdd SS4.5.8, ADR 45437 D2; the fold sets it on pause commit and clears it on resume-commit supersession or the generation's terminal). */
862
+ paused?: boolean;
863
+ /** `reasoning`: provider reasoning item id (e.g. `rs_...`), for provider-side correlation. */
864
+ providerItemId?: string;
865
+ /** `compaction`: noop/failure reason, verbatim (snake_case durable vocabulary, e.g. `"no_compactable_history"`). `hookRun`: terminal-only capped terminal reason (tdd SS4.5.11). */
866
+ reason?: string;
867
+ /** RFC3339 timestamp of the item's driving durable record. Absent on ephemeral-opened items until first durable re-emission (tdd SS4.4.1). */
868
+ recordedAt?: string;
869
+ /** `reminderChild`: the reminder agent's id. */
870
+ reminderAgentId?: string;
871
+ /** `subagent`: the result envelope from `ResultReady` (tdd SS4.5.7). */
872
+ result?: SubagentResult;
873
+ /** `workflow`: set on resumed launches. */
874
+ resumeFromRunId?: string;
875
+ /** `userMessage`: `true` after an accepted retract (tdd SS4.5.1); re-emitted via `item/updated`. */
876
+ retracted?: boolean;
877
+ /** Integer >= 1, strictly monotonic per item; apply rule is replace-iff-higher. `item/delta` never bumps it (tdd SS4.4.1). */
878
+ revision: number;
879
+ /** `subagent`: role as spawned. */
880
+ role?: string;
881
+ /** `hookRun`: terminal-only durable outcome; stays `blocked` when the item settles `rejected` (tdd SS4.5.11). */
882
+ runStatus?: HookRunStatus;
883
+ /** `workflow`: launched script identity. */
884
+ scriptId?: string;
885
+ /** `sideChat`: the side's own session id, readable via `session/read`/`view/page` — drill-down without a second protocol (tdd SS4.5.13; ADR 45435 D3). */
886
+ sideSessionId?: string;
887
+ /** Open enum; terminal = anything other than `"inProgress"`. Unknown values MUST be treated as terminal-unknown and rendered generically (tdd SS4.4.1). */
888
+ status: ItemStatus;
889
+ /** `toolCall`: the latest external-attempt facet, field-for-field — countdown inputs the client renders the tick from; absent when the latest detail carries none (tdd SS4.5.5, #45448). */
890
+ statusAttempt?: StatusAttempt;
891
+ /** `toolCall`: the latest child-summary facet, field-for-field; absent when the latest detail carries none (tdd SS4.5.5, #45448). */
892
+ statusChildren?: StatusChildren;
893
+ /** `toolCall`: the latest health facet, field-for-field; absent when the latest detail carries none (tdd SS4.5.5, #45448). */
894
+ statusHealth?: StatusHealth;
895
+ /** `toolCall`: the task's visible latest-status line — the latest `Status` message through the shared detail normalization; absent when no status folded or nothing displayable remains (tdd SS4.5.5, #45448). */
896
+ statusLine?: string;
897
+ /** `toolCall`: the latest detail's phase row, verbatim; absent when the latest detail carries none (tdd SS4.5.5, #45448). */
898
+ statusPhase?: string;
899
+ /** `toolCall`: the latest progress facet, field-for-field; absent when the latest detail carries none (tdd SS4.5.5, #45448). */
900
+ statusProgress?: StatusProgress;
901
+ /** `toolCall`: the latest active-step facet, field-for-field; absent when the latest detail carries none (tdd SS4.5.5, #45448). */
902
+ statusStep?: StatusStep;
903
+ /** `userMessage`: `true` when injected mid-turn via `turn/steer` or `ifBusy: "steer"`; absent otherwise. */
904
+ steered?: boolean;
905
+ /** `workflow`: display-only stop affordance — `true` while the run is open, `false` once settled; stopping rides `workflow/cancel` (tdd SS4.5.8, #45449). Authorizes nothing. */
906
+ stopAvailable?: boolean;
907
+ /** `compaction`: summarizer strategy (installed only). */
908
+ strategyId?: string;
909
+ /** `subagent`: durable child identity (`subagent_id`). */
910
+ subagentId?: string;
911
+ /** `compaction`: opaque provenance string naming the compaction boundary. A compaction-anchored read anchor since D-029 (2026-08-12): accepted by `session/resume` and `view/page` (wire shape and validation are the #208 lane's). Still opaque — clients relay it, never parse it (tdd SS4.5.10). */
912
+ summarizedThrough?: string;
913
+ /** `reasoning`: one entry per summary part; part *n* streams via `item/delta` field `"summary.n"` (part boundary = index change). */
914
+ summary?: string[];
915
+ /** `reminderChild`: the linked task id. */
916
+ taskId?: string;
917
+ /** `userMessage`: the prompt text as submitted. `agentMessage`: the accumulated reply, streamed via `item/delta` field `"text"`. `reasoning`: raw committed reasoning text where the provider exposes it (never streamed in v1, tdd SS4.5.4). */
918
+ text?: string;
919
+ /** `workflow`: the run's launch token budget, set from the launch fact (tdd SS4.5.8, #45449); absent when the launch carried none. */
920
+ tokenBudget?: WorkflowTokenBudget;
921
+ /** `compaction`: token budget snapshot after, when measured. */
922
+ tokensAfter?: number;
923
+ /** `compaction`: token budget snapshot before, when measured. */
924
+ tokensBefore?: number;
925
+ /** `toolCall`: tool name. */
926
+ tool?: string;
927
+ /** `toolCall`: the shared semantic receipt — what the operation did, as machine-readable fact (ADR 43399 D1, tdd SS4.5.5). Optional and additive: absence is always valid and is never an error (D3). When present, a server serves the **same** receipt on every item path — `item/completed`, `view/page`, seeded snapshots and resume (D3). Observation only; carries no control authority (D4), and no field in it enters model-visible content (D7). */
928
+ toolReceipt?: ToolReceipt;
929
+ /** `compaction`: what initiated the compaction. */
930
+ trigger?: CompactionTrigger;
931
+ /** `workflow`: camelCased `WorkflowLaunchTriggerSource`, verbatim (durable runtime vocabulary, e.g. `"modelProposal"`). */
932
+ triggerSource?: string;
933
+ /** `true` when the server's per-surface text budget saturated a streamed surface (`agentMessage.text`, `reasoning.summary[*]`, `toolCall.visibleOutput`, `userShell.visibleOutput`), or cut a `subagent` surface (`objective`, `fallbackText`, `result.summary`, `result.text`). On a `subagent` item the flag is item-level and never cleared: once any of those four is cut, every later update keeps it, even when `result.text` arrives whole (ADR 35691 D9). The durable full text remains in the log (tdd SS4.5.4). */
934
+ truncated?: boolean;
935
+ /** The owning turn (== the submitting `commandId` for fresh turns, tdd SS3.1.4). `null` only for `userShell` — the one kind outside a turn (tdd SS4.5.6). */
936
+ turnId?: string | null;
937
+ /** `subagent`: **transitive** observed usage — the child and its own descendants; updated in place, absent until first observation; never folded into `session/tokenUsage.cumulative` (tdd SS4.6.5). */
938
+ usage?: TokenUsage;
939
+ /** `toolCall`/`userShell`: bounded transcript-visible result text (budget per tdd SS4.5.4); streams via `item/delta` field `"output"`. */
940
+ visibleOutput?: string;
941
+ /** `subagent`/`workflow`: the owning durable workflow run id (opaque string — not a UUID family). */
942
+ workflowRunId?: string;
943
+ }
944
+
945
+ /** `item/completed` params (tdd SS4.3): the item reached its terminal state — the authoritative final object. Always cites a durable `sourceRange` (tdd SS4.2). Clients MUST accept `item/completed` for an `itemId` they never saw `item/started` for (single-shot kinds; after a gap fill; tdd SS4.4.1). */
946
+ export interface ItemCompletedParams {
947
+ /** The full item at its terminal revision. */
948
+ item: Item;
949
+ /** The owning session. */
950
+ sessionId: string;
951
+ /** The durable records this event folded from. */
952
+ sourceRange: SourceRange;
953
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
954
+ viewCursor: string;
955
+ }
956
+
957
+ /** `item/delta` params (tdd SS4.3.1): a UTF-8-safe streaming append to an open item's field. Ephemeral-sourced by definition: this params object has **no** `sourceRange` member at all (spec 14653 INV-009 — the schema enforces the exemption). Deltas never bump `revision`. */
958
+ export interface ItemDeltaParams {
959
+ /** The appended text; concatenation of a field path's deltas in cursor order equals that field's value on `item/completed` unless the surface saturated (spec 14653 INV-005). */
960
+ delta: string;
961
+ /** Dotted field path the append targets (`"summary.0"`, `"output"`, ...); absent means `"text"` (tdd SS4.3.1). */
962
+ field?: string;
963
+ /** The open item being appended to. */
964
+ itemId: string;
965
+ /** The owning session. */
966
+ sessionId: string;
967
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
968
+ viewCursor: string;
969
+ }
970
+
971
+ /** The eleven v1 item kinds (tdd SS4.5.2–4.5.13) plus post-v1 kinds (tdd SS4.5.14+). Open: a new kind is additive evolution, and clients MUST render unknown kinds generically (tdd SS4.10). */
972
+ export type ItemKind = "userMessage" | "agentMessage" | "reasoning" | "toolCall" | "userShell" | "subagent" | "workflow" | "reminderChild" | "compaction" | "hookRun" | "sideChat" | "webSearch" | (string & {});
973
+
974
+ /** The `item/readOutput` content encoding (tdd SS4.7.4). Closed: text media is ALWAYS `utf8` and binary media `base64`; a third value would change the client's decode contract. */
975
+ export type ItemReadOutputEncoding = "utf8" | "base64";
976
+
977
+ /** `item/readOutput` params (tdd SS4.7.4): byte-ranged fetch of stored full output that the view truncated — the `outputRef` fetch path SS3.9 and SS4.5.5 owe. Read-only; works on loaded and unloaded sessions; no lease. */
978
+ export interface ItemReadOutputParams {
979
+ /** The item whose stored output is fetched. */
980
+ itemId: string;
981
+ /** STORED bytes requested; default and max 6 MiB (tdd SS4.7.4). A value above the max is served at the max. */
982
+ lengthBytes?: number;
983
+ /** STORED-byte offset to start from; 0 when omitted. STORED bytes are a property of the output, not of a transport (tdd SS4.7.4). */
984
+ offsetBytes?: number;
985
+ /** The `outputRef.id` from the item (never the `uri`; the uri is display/provenance). */
986
+ outputRef: string;
987
+ /** The session the item belongs to. */
988
+ sessionId: string;
989
+ }
990
+
991
+ /** `item/readOutput` result (tdd SS4.7.4): one stored-byte page. */
992
+ export interface ItemReadOutputResult {
993
+ /** STORED bytes served in THIS response (not the output's total; that is `outputRef.byteLen` on the item). The next page's `offsetBytes` is `offsetBytes + byteLen` — short-serving and advancing are separate, so paging never skips or double-reads a byte (tdd SS4.7.4). */
994
+ byteLen: number;
995
+ /** The served range, decoded per `encoding`. */
996
+ content: string;
997
+ /** How `content` encodes the stored bytes. */
998
+ encoding: ItemReadOutputEncoding;
999
+ /** `true` when this range reached the end of the stored output. */
1000
+ eof: boolean;
1001
+ /** The stored output's media type (e.g. `text/plain`). */
1002
+ mediaType: string;
1003
+ /** The STORED-byte offset this response actually served from. */
1004
+ offsetBytes: number;
1005
+ }
1006
+
1007
+ /** `item/started` params (tdd SS4.3): a new item opened on the transcript. `sourceRange` is absent when the item opens on an ephemeral record (the delta-streamed kinds); the item's authoritative open is re-stated by its durable-sourced `item/completed` (tdd SS4.2). */
1008
+ export interface ItemStartedParams {
1009
+ /** The full item at revision 1. */
1010
+ item: Item;
1011
+ /** The owning session. */
1012
+ sessionId: string;
1013
+ /** The durable records this event folded from; absent on an ephemeral-sourced open (spec 14653 INV-009). */
1014
+ sourceRange?: SourceRange;
1015
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
1016
+ viewCursor: string;
1017
+ }
1018
+
1019
+ /** Item status (tdd SS4.4.1). Open; terminal = anything other than `"inProgress"`, and unknown values are terminal-unknown, rendered generically. */
1020
+ export type ItemStatus = "inProgress" | "completed" | "failed" | "cancelled" | "rejected" | "timedOut" | (string & {});
1021
+
1022
+ /** `item/updated` params (tdd SS4.4.2): an open item changed non-terminally in a way deltas cannot express — the full item re-emitted at a higher revision (apply rule: replace iff higher). */
1023
+ export interface ItemUpdatedParams {
1024
+ /** The full item at a higher revision. */
1025
+ item: Item;
1026
+ /** The owning session. */
1027
+ sessionId: string;
1028
+ /** The durable records this event folded from. */
1029
+ sourceRange: SourceRange;
1030
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
1031
+ viewCursor: string;
1032
+ }
1033
+
1034
+ /** The literal `"2.0"` every frame carries (SS1.2). */
1035
+ export type JsonRpcVersion = "2.0";
1036
+
1037
+ /** The last `turn/completed` the session-view fold applied, restated on `session/resume` and `session/read` so a reopened session can report a failed last turn (tdd SS2.5.2, ADR 36635 D2/D3). */
1038
+ export interface LastTurn {
1039
+ /** Copied when the `turn/completed` carried it: runtime `failed` terminals do, host-death `failed` terminals do not (ADR 36635 D2). */
1040
+ error?: TurnError;
1041
+ /** Copied when the `turn/completed` carried it; a synthesized host-death `failed` terminal carries only this (`crash`, `crash_inferred`, or `incomplete`). Free display text: clients never branch on it. */
1042
+ reason?: string;
1043
+ /** The turn's terminal (tdd SS4.5.1; open enum). */
1044
+ terminal: TurnTerminal;
1045
+ /** The turn's id, as on its `turn/completed`; clients deduplicate a live `turn/completed` against this member by it (ADR 36635 D2). */
1046
+ turnId: string;
1047
+ }
1048
+
1049
+ /** Quota limit kinds (tdd SS4.5.1, ADR 50047 D2): open for evolution. */
1050
+ export type LimitKind = "tierLimit" | (string & {});
1051
+
1052
+ /** `media/upload` params (tdd SS3.33, ADR 45443 D5): one chunk of a client-minted upload. All members required. */
1053
+ export interface MediaUploadParams {
1054
+ /** This chunk's bytes; each call's frame stays in the SS1.1 budget. */
1055
+ chunkBase64: string;
1056
+ /** The upload's chunk total; positive. */
1057
+ chunkCount: number;
1058
+ /** This chunk's 0-based position. */
1059
+ chunkIndex: number;
1060
+ /** One per call; SS3.1.1 replay answers the recorded receipt. */
1061
+ commandId: string;
1062
+ /** `video/mp4` or `video/quicktime`, matching `VideoInput`. */
1063
+ mediaType: string;
1064
+ /** The session owning the video store. */
1065
+ sessionId: string;
1066
+ /** The assembled byte count; must equal the bytes the chunks deliver. */
1067
+ totalBytes: number;
1068
+ /** The client-minted upload id (UUIDv7), sent on every chunk. */
1069
+ uploadId: string;
1070
+ }
1071
+
1072
+ /** `media/upload` result (tdd SS3.33): echoes the client-minted id, on every chunk and replay. */
1073
+ export interface MediaUploadResult {
1074
+ /** The receipt the turn part references. */
1075
+ uploadId: string;
1076
+ }
1077
+
1078
+ /** `userMessage` image attachment metadata (tdd SS4.5.2): metadata only — the durable bytes live in the log and are reachable on the raw altitude. */
1079
+ export interface MessageAttachment {
1080
+ /** This attachment's name, `<itemId>/<n>` — the item's id plus this entry's 1-based position in its `attachments` array (tdd SS4.5.2, D-071, ADR 42850; #42850). Name only: no link form and no byte read by id (#42648). Set by the server on every attachment entry it emits, and identical on live, paging, snapshot and rebuild paths (tdd SS4.5.2). Optional in the schema so older servers stay valid; clients compare and store the whole string and MUST NOT parse it (ADR 42850). */
1081
+ attachmentId?: string;
1082
+ /** Pixel height, when known. */
1083
+ height?: number;
1084
+ /** The image media type (e.g. `"image/png"`). */
1085
+ mediaType: string;
1086
+ /** Attachment type, `"image"` in v1 (free string: attachment vocabulary grows additively with the runtime's intake surface). */
1087
+ type: string;
1088
+ /** Pixel width, when known. */
1089
+ width?: number;
1090
+ }
1091
+
1092
+ /** One visible catalog row (tdd SS3.10). Catalog rows marked hidden never reach the wire, so a client cannot select one. */
1093
+ export interface ModelCatalogEntry {
1094
+ /** Context limit; `null` when the catalog source declared nothing. */
1095
+ contextLimit: number | null;
1096
+ /** Cost block; `null` when the catalog source declared nothing. */
1097
+ cost: ModelCost | null;
1098
+ /** The row's catalog default. Optional only for decoding older hosts; a present value is never null and is always a member of `variants`. Absent under `"unknown"` (ADR 33400 D2). */
1099
+ defaultReasoningEffort?: ReasoningEffort;
1100
+ /** Description; `null` when the catalog source declared nothing. */
1101
+ description: string | null;
1102
+ /** Presentation label. */
1103
+ displayLabel: string;
1104
+ /** Marks the session's effective model when `sessionId` was supplied. May be false for every row — a client MUST NOT assume exactly one. */
1105
+ isActive: boolean;
1106
+ /** Marks the catalog's default row. May be false for every row. */
1107
+ isDefault: boolean;
1108
+ /** The selectable model id. */
1109
+ modelId: string;
1110
+ /** Output limit; `null` when the catalog source declared nothing. */
1111
+ outputLimit: number | null;
1112
+ /** Provider profile; `null` when the catalog source declared nothing. */
1113
+ profileId: string | null;
1114
+ /** Provider routing. */
1115
+ providerId: string;
1116
+ /** Described selectable tiers, a same-order subset of `variants`. Optional only for decoding older hosts; a present value is never null. Absent under `"unknown"` (ADR 33400 D2). */
1117
+ reasoningEffortVariants?: ModelDescribedReasoningEffort[];
1118
+ /** Release date; `null` when the catalog source declared nothing. */
1119
+ releaseDate: string | null;
1120
+ /** Complete ordered selectable efforts. Optional only for decoding older hosts; a present value is never null. Current hosts always send it. */
1121
+ variants?: ModelReasoningEffortVariants;
1122
+ }
1123
+
1124
+ /** Where a model catalog came from (tdd SS3.10). **Open**: an unrecognized value is an unknown source, not an error. */
1125
+ export type ModelCatalogSource = "providerCatalog" | "fakeCatalog" | "unresolvedCatalog" | "bundledCatalog" | "configCatalog" | (string & {});
1126
+
1127
+ /** What drove a model selection (tdd SS4.6.1). Open. */
1128
+ export type ModelChangeSource = "user" | "default" | "policy" | (string & {});
1129
+
1130
+ /** Per-1M-token catalog cost, carried **verbatim** for display and never rounded or re-formatted by the host (tdd SS3.10). Cost arithmetic stays client-local view math. */
1131
+ export interface ModelCost {
1132
+ /** Cached-input cost, a decimal string. */
1133
+ cached: string;
1134
+ /** Currency; nullable — today's catalogs are USD. */
1135
+ currency: string | null;
1136
+ /** Input cost, a decimal string. */
1137
+ input: string;
1138
+ /** Output cost, a decimal string. */
1139
+ output: string;
1140
+ }
1141
+
1142
+ /** One described reasoning-effort tier of a `model/list` row (tdd SS3.10, ADR 33400 D2): a selectable tier plus the catalog's display string for it when declared. */
1143
+ export interface ModelDescribedReasoningEffort {
1144
+ /** The catalog's per-tier display string; absent when the catalog declared none. Optional only for decoding; a present value is never null. */
1145
+ description?: string;
1146
+ /** The tier, in the closed D-024 vocabulary. */
1147
+ tier: ReasoningEffort;
1148
+ }
1149
+
1150
+ /** `model/list` params (tdd SS3.10): the discovery half of the model-picker gesture. **A query, not a command** — no `commandId`, no durable intake record, no view event. */
1151
+ export interface ModelListParams {
1152
+ /** When present, the row matching that session's effective model is flagged `isActive`. When absent, no row is active — a client may list before it has a session (tdd SS3.10). */
1153
+ sessionId?: string;
1154
+ }
1155
+
1156
+ /** `model/list` result (tdd SS3.10). A snapshot at call time: v1 has no catalog subscription. `models` MAY be empty — a build shipped with no bundled models is a supported configuration. */
1157
+ export interface ModelListResult {
1158
+ /** Visible rows only, newest `releaseDate` first. */
1159
+ models: ModelCatalogEntry[];
1160
+ /** The catalog's profile; `null` when none. */
1161
+ profileId: string | null;
1162
+ /** The catalog's provider. */
1163
+ providerId: string;
1164
+ /** Where the catalog came from — how a client tells a live provider catalog from a test fake and labels it honestly. */
1165
+ source: ModelCatalogSource;
1166
+ }
1167
+
1168
+ /** A complete ordered effort set, or an explicit unknown capability. */
1169
+ export type ModelReasoningEffortVariants = ReasoningEffort[] | UnknownModelReasoningEffortVariants;
1170
+
1171
+ /** A model selection (tdd SS3.8). Empty strings are normalized to absent. */
1172
+ export interface ModelSelection {
1173
+ /** Presentation label. */
1174
+ displayLabel?: string;
1175
+ /** Catalog model id. Required. */
1176
+ modelId: string;
1177
+ /** Provider profile. Omitted and explicit `null` both mean "no profile" (#23468). */
1178
+ profileId?: string | null;
1179
+ /** Provider routing. */
1180
+ providerId?: string;
1181
+ }
1182
+
1183
+ /** Rich content the model saw beyond text (tdd SS4.5.5, `ModelVisibleToolContent`): metadata only — fetch bytes via `item/readOutput` when an `outputRef` exists. */
1184
+ export interface ModelVisibleContent {
1185
+ /** Pixel height, when known. */
1186
+ height?: number;
1187
+ /** The content media type. */
1188
+ mediaType: string;
1189
+ /** The recorded content path. */
1190
+ path: string;
1191
+ /** The tool that produced the content. */
1192
+ sourceToolName: string;
1193
+ /** Content type, `"image"` in v1 (free string, grows with the durable vocabulary). */
1194
+ type: string;
1195
+ /** Pixel width, when known. */
1196
+ width?: number;
1197
+ }
1198
+
1199
+ /** A notification frame, either direction (SS1.2 §2.2). No `id`; a notification is never answered. */
1200
+ export interface Notification {
1201
+ /** Emission time in Unix milliseconds, recorded once at emission; server→client notifications only (SS1.2.5). Optional on the wire so decoders tolerate older servers. */
1202
+ emittedAtMs?: number;
1203
+ /** The literal `"2.0"`. */
1204
+ jsonrpc: JsonRpcVersion;
1205
+ /** Notification method name. */
1206
+ method: string;
1207
+ /** Method-specific parameters; omitted entirely when empty. */
1208
+ params?: Record<string, unknown>;
1209
+ }
1210
+
1211
+ /** Stored-output reference (tdd SS4.5.5): the camelCased fold of the durable `ToolOutputRef`. The fetch path is `item/readOutput` (#208). */
1212
+ export interface OutputRef {
1213
+ /** Whether the bytes are servable (tdd SS4.5.5). */
1214
+ availability: OutputRefAvailability;
1215
+ /** Stored byte length. */
1216
+ byteLen: number;
1217
+ /** Content digest (e.g. `"sha256:..."`), when recorded. */
1218
+ digest?: string;
1219
+ /** The stored output's durable id. */
1220
+ id: string;
1221
+ /** The stored output's kind, verbatim durable vocabulary (e.g. `"tool_output"`; snake_case per the SS1.6 casing exemption). */
1222
+ kind: string;
1223
+ /** Media type, when recorded. */
1224
+ mediaType?: string;
1225
+ /** Stored path, when recorded. */
1226
+ path?: string;
1227
+ /** The stored output's URI. */
1228
+ uri: string;
1229
+ }
1230
+
1231
+ /** Whether a stored output's bytes are servable (tdd SS4.5.5). Open — durable runtime vocabulary may grow additively. */
1232
+ export type OutputRefAvailability = "available" | "missing" | "unsupported" | "accessFailed" | (string & {});
1233
+
1234
+ /** Server-authored edit-family diff summary (tdd SS4.5.5, #33025): `files` counts the stored patch document's file entries; `added` and `removed` are the total `+`/`-` prefixed LINE counts summed over the stored patch's hunks across all files — line counts, never hunk or byte counts. Rides the `toolCall` item beside `patchRef`; the body is fetched via `item/readOutput` with `patchRef.id`. */
1235
+ export interface PatchSummary {
1236
+ /** Total `+`-prefixed line count across all files' hunks. */
1237
+ added: number;
1238
+ /** File entries in the stored patch document. */
1239
+ files: number;
1240
+ /** Total `-`-prefixed line count across all files' hunks. */
1241
+ removed: number;
1242
+ }
1243
+
1244
+ /** A pending approval in the snapshot: the SS2.5.2 pointer shape plus the gated `itemId` when one exists (tdd SS4.9.1). */
1245
+ export interface PendingApprovalPointer {
1246
+ /** The pending approval's id. */
1247
+ approvalId: string;
1248
+ /** The parked item, when one exists. */
1249
+ itemId?: string;
1250
+ /** The cursor the approval opened at. */
1251
+ viewCursor: string;
1252
+ }
1253
+
1254
+ /** The `pendingRequests` discriminator (tdd SS2.5.2). Open enum, v1 values `approval` and `userInput`. */
1255
+ export type PendingRequestKind = "approval" | "userInput" | (string & {});
1256
+
1257
+ /** A late-joiner pointer at an unsettled server-initiated request (tdd SS2.5.2, SS2.2.1). The full payloads arrive as re-issued server-to-client requests right after a `session/resume` response (tdd SS5.6); `session/read` never re-issues them (tdd SS2.5.5). **A second E4 instance, RULED with E4 (#22785, owner, 2026-08-26): the flat discriminated-object precedent is accepted for this type too, on the `ApprovalSubject` precedent, with the serialized JSON unchanged. A strict union node kind may be funded later; if it is, it must cover both this type and `TurnInputPart`.** SS2.5.2 ratifies two kind-discriminated entry shapes (`{kind: "approval", approvalId, viewCursor}` / `{kind: "userInput", userInputId, viewCursor}`); this is one flat object with both ids optional, so the published schema accepts `{"kind":"approval","userInputId":…}` and an entry carrying no id at all. The v1 model names no object-variant union (the `ApprovalSubject` precedent, followed for `TurnInputPart`), and this instance differs from that one in a way the ruling should see: `kind` here is an OPEN enum, where `TurnInputPart.type` is closed. */
1258
+ export interface PendingRequestPointer {
1259
+ /** Present on an `approval` entry. */
1260
+ approvalId?: string;
1261
+ /** The discriminator; v1 values `approval` and `userInput`. */
1262
+ kind: PendingRequestKind;
1263
+ /** Present on a `userInput` entry. */
1264
+ userInputId?: string;
1265
+ /** The cursor the request opened at. */
1266
+ viewCursor: string;
1267
+ }
1268
+
1269
+ /** A pending user-input prompt in the snapshot (tdd SS4.9.1, SS5.10). */
1270
+ export interface PendingUserInputPointer {
1271
+ /** The parked item, when one exists. */
1272
+ itemId?: string;
1273
+ /** The pending prompt's id. */
1274
+ userInputId: string;
1275
+ /** The cursor the prompt opened at. */
1276
+ viewCursor: string;
1277
+ }
1278
+
1279
+ /** The server runtime's platform family (SS1.4.1); may differ from the client's. Closed: SS1.4.1 fixes the value set, so widening it is a deliberate, gate-visible protocol change rather than a silent addition (a later `Closed`→`Open` flip is itself additive, data-model.md §5.2). */
1280
+ export type PlatformFamily = "unix" | "windows";
1281
+
1282
+ /** The server's operating system (SS1.4.1). Closed, for the same reason as [`PlatformFamily`]. */
1283
+ export type PlatformOs = "macos" | "linux" | "windows";
1284
+
1285
+ /** One installed plugin record (tdd SS3.26.2). */
1286
+ export interface PluginCatalogEntry {
1287
+ /** The record's own install switch; non-enabled rows are included as `false`, never dropped. */
1288
+ enabled: boolean;
1289
+ /** The installed plugin's identifier. */
1290
+ id: string;
1291
+ /** The installed record's source provenance (ADR 33398 D7 item 3). */
1292
+ source: PluginSource;
1293
+ /** The installed version. */
1294
+ version: string;
1295
+ }
1296
+
1297
+ /** `plugin/changed` params (tdd SS3.29.5): an install landed; clients re-issue `plugin/list` (plus `hook/list` and `skill/list`). */
1298
+ export interface PluginChangedParams {
1299
+ /** The installed record's own switch. */
1300
+ enabled: boolean;
1301
+ /** The installed record's identifier. */
1302
+ id: string;
1303
+ /** The acting session. */
1304
+ sessionId: string;
1305
+ /** The installed-list provenance vocabulary (tdd SS3.26.2). */
1306
+ source: PluginSource;
1307
+ /** The installed record's version. */
1308
+ version: string;
1309
+ }
1310
+
1311
+ /** The `plugin/install` local-path arm (tdd SS3.29.1). */
1312
+ export interface PluginInstallLocalPathTarget {
1313
+ /** The host folder to install from; absolute recommended, relative resolves against the host working directory. */
1314
+ path: string;
1315
+ /** The install lane; omitted means `default`. */
1316
+ scope?: PluginInstallScope;
1317
+ }
1318
+
1319
+ /** The `plugin/install` marketplace arm (tdd SS3.29.1). */
1320
+ export interface PluginInstallMarketplaceTarget {
1321
+ /** The configured marketplace name. */
1322
+ marketplace: string;
1323
+ /** The plugin name within the store. */
1324
+ name: string;
1325
+ }
1326
+
1327
+ /** `plugin/install` params (tdd SS3.29.1). Per-session params plus a client-generated `commandId` (UUIDv7) with the uniform SS3.1.1 idempotency contract. */
1328
+ export interface PluginInstallParams {
1329
+ /** The client-generated idempotency key (UUIDv7). */
1330
+ commandId: string;
1331
+ /** The target session; its workspace resolves project scope. */
1332
+ sessionId: string;
1333
+ /** Exactly one install target arm. */
1334
+ target: PluginInstallTarget;
1335
+ }
1336
+
1337
+ /** `plugin/install` result (tdd SS3.29.1): the SS3.1.2 ack envelope plus the installed receipt. */
1338
+ export interface PluginInstallResult {
1339
+ /** The echoed idempotency key. */
1340
+ commandId: string;
1341
+ /** The installed record's own switch. */
1342
+ enabled: boolean;
1343
+ /** The installed record's identifier. */
1344
+ id: string;
1345
+ /** The installed-list provenance vocabulary (tdd SS3.26.2). */
1346
+ source: PluginSource;
1347
+ /** The ack status. */
1348
+ status: CommandStatus;
1349
+ /** The installed record's version. */
1350
+ version: string;
1351
+ /** The installer's advisory text when the install succeeded with a caveat; absent otherwise. */
1352
+ warning?: string;
1353
+ }
1354
+
1355
+ /** The `plugin/install` local-path scope (tdd SS3.29.1). Closed: an unknown scope is `-32602 invalidParams`. */
1356
+ export type PluginInstallScope = "default" | "user" | "project";
1357
+
1358
+ /** The one structured install target (tdd SS3.29.1): a flat object with two optional arms, exactly one present — the `TurnInputPart` convention, since the v1 schema model names no object-variant union. Both arms or neither is `-32602 invalidParams`. */
1359
+ export interface PluginInstallTarget {
1360
+ /** The local-path arm: install from a host folder. */
1361
+ localPath?: PluginInstallLocalPathTarget;
1362
+ /** The marketplace arm: install a named plugin from a store. */
1363
+ marketplace?: PluginInstallMarketplaceTarget;
1364
+ }
1365
+
1366
+ /** `plugin/list` params (tdd SS3.26.2). Per-session params; rows are the installed plugin records. */
1367
+ export interface PluginListParams {
1368
+ /** The target session. */
1369
+ sessionId: string;
1370
+ }
1371
+
1372
+ /** `plugin/list` result (tdd SS3.26.2): one row per installed plugin record; the spec promises the set, not an order. */
1373
+ export interface PluginListResult {
1374
+ /** The installed plugin rows. */
1375
+ plugins: PluginCatalogEntry[];
1376
+ }
1377
+
1378
+ /** `plugin/marketplaceAdd` params (tdd SS3.29.2). Per-session params plus a client-generated `commandId` (UUIDv7). */
1379
+ export interface PluginMarketplaceAddParams {
1380
+ /** The client-generated idempotency key (UUIDv7). */
1381
+ commandId: string;
1382
+ /** The marketplace name to configure. */
1383
+ name: string;
1384
+ /** The target session. */
1385
+ sessionId: string;
1386
+ /** The app's source vocabulary: `owner/repo`, a git URL, a `file://` URL, or a local path. */
1387
+ source: string;
1388
+ }
1389
+
1390
+ /** What happened to a marketplace (tdd SS3.29.6). Closed: an unknown change is a contract violation, never tolerated. */
1391
+ export type PluginMarketplaceChange = "added" | "updated" | "removed";
1392
+
1393
+ /** `plugin/marketplaceChanged` params (tdd SS3.29.6): a marketplace was added, updated, or removed. */
1394
+ export interface PluginMarketplaceChangedParams {
1395
+ /** What happened. */
1396
+ change: PluginMarketplaceChange;
1397
+ /** The marketplace name. */
1398
+ name: string;
1399
+ /** The stored record's plugin count; omitted on `removed`, never fabricated. */
1400
+ pluginCount?: number;
1401
+ /** The acting session. */
1402
+ sessionId: string;
1403
+ /** The stored record's skipped count; omitted on `removed`, never fabricated. */
1404
+ skippedCount?: number;
1405
+ }
1406
+
1407
+ /** The stored marketplace record both add and update answer (tdd SS3.29.2, SS3.29.3): the SS3.1.2 ack envelope plus the record. */
1408
+ export interface PluginMarketplaceRecordResult {
1409
+ /** The echoed idempotency key. */
1410
+ commandId: string;
1411
+ /** The configured marketplace name. */
1412
+ name: string;
1413
+ /** The plugins the store now offers. */
1414
+ pluginCount: number;
1415
+ /** Entries the store could not offer, with the reason each was skipped; empty when nothing was skipped. */
1416
+ skipped: PluginMarketplaceSkippedEntry[];
1417
+ /** The normalized stored source. */
1418
+ source: PluginMarketplaceSourceShape;
1419
+ /** The ack status. */
1420
+ status: CommandStatus;
1421
+ }
1422
+
1423
+ /** `plugin/marketplaceRemove` params (tdd SS3.29.4). Per-session params plus a client-generated `commandId` (UUIDv7). */
1424
+ export interface PluginMarketplaceRemoveParams {
1425
+ /** The client-generated idempotency key (UUIDv7). */
1426
+ commandId: string;
1427
+ /** The marketplace name to remove. */
1428
+ name: string;
1429
+ /** The target session. */
1430
+ sessionId: string;
1431
+ }
1432
+
1433
+ /** `plugin/marketplaceRemove` result (tdd SS3.29.4): the SS3.1.2 ack envelope plus the removed name. */
1434
+ export interface PluginMarketplaceRemoveResult {
1435
+ /** The echoed idempotency key. */
1436
+ commandId: string;
1437
+ /** The removed marketplace name. */
1438
+ name: string;
1439
+ /** The ack status. */
1440
+ status: CommandStatus;
1441
+ }
1442
+
1443
+ /** One skipped marketplace entry (tdd SS3.29.2). */
1444
+ export interface PluginMarketplaceSkippedEntry {
1445
+ /** The skipped plugin. */
1446
+ plugin: string;
1447
+ /** Why it was skipped. */
1448
+ reason: string;
1449
+ }
1450
+
1451
+ /** The normalized stored marketplace source (tdd SS3.29.2). */
1452
+ export interface PluginMarketplaceSourceShape {
1453
+ /** The stored source kind. */
1454
+ kind: string;
1455
+ /** The stored source path. */
1456
+ path: string;
1457
+ }
1458
+
1459
+ /** `plugin/marketplaceUpdate` params (tdd SS3.29.3). Per-session params plus a client-generated `commandId` (UUIDv7). */
1460
+ export interface PluginMarketplaceUpdateParams {
1461
+ /** The client-generated idempotency key (UUIDv7). */
1462
+ commandId: string;
1463
+ /** The marketplace name to refresh. */
1464
+ name: string;
1465
+ /** The target session. */
1466
+ sessionId: string;
1467
+ }
1468
+
1469
+ /** A plugin row's source provenance (tdd SS3.26.2, ADR 33398 D7 item 3): camelCase of `PluginSourceProvenance`. Open (server-produced result vocabulary, the #22785 enum-openness rule): a future provenance is additive. */
1470
+ export type PluginSource = "curated" | "marketplaceUserAdded" | "foreignImport" | "nativeLocal" | (string & {});
1471
+
1472
+ /** Typed quota-exhaustion detail (tdd SS4.5.1, ADR 50047 D2): the limit kind plus the provider's reset instant. */
1473
+ export interface QuotaDetail {
1474
+ /** Which quota was exhausted (open enum; unknown values fall back). */
1475
+ limitKind: LimitKind;
1476
+ /** Epoch milliseconds at which the provider says usage resets. */
1477
+ resetsAtMs: number;
1478
+ }
1479
+
1480
+ /** The reasoning-effort tier sampled at submission (tdd SS3.2, SS3.3). The **same closed tier vocabulary** on both the fresh-turn and steer lanes, spelled identically; invalid tiers are invalid params. `none` is a tier of the vocabulary (ask for no reasoning), not a way to say "unset". */
1481
+ export type ReasoningEffort = "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | "ultra";
1482
+
1483
+ /** What drove a reasoning-effort default change (tdd SS4.6.9). Open; v1's only producer is `user` (an accepted `session/setReasoningEffort`). */
1484
+ export type ReasoningEffortChangeSource = "user" | "default" | "policy" | (string & {});
1485
+
1486
+ /** The snapshot's standing session-default reasoning effort (tdd SS4.9.1, ADR 31255 D1): the fold of the latest completed `runtime.reasoning_effort_reconfigure` fact — the same pair `session/reasoningEffortChanged` carries. */
1487
+ export interface ReasoningEffortState {
1488
+ /** The standing default tier — the closed SS3.2 vocabulary, spelled identically to `turn/start.reasoningEffort`. */
1489
+ reasoningEffort: ReasoningEffort;
1490
+ /** Which actor class set the default. */
1491
+ source: ReasoningEffortChangeSource;
1492
+ }
1493
+
1494
+ /** `recap/cancel` params (tdd SS3.28.5): the session plus the cancel's own retry id. No target — one in-flight slot per session makes the target unambiguous. */
1495
+ export interface RecapCancelParams {
1496
+ /** The cancel's own retry id (required, SS3.1.1). */
1497
+ commandId: string;
1498
+ /** The session whose in-flight recap to cancel (required). */
1499
+ sessionId: string;
1500
+ }
1501
+
1502
+ /** `recap/cancel` result (tdd SS3.28.5): admission only. In flight → the recap settles `cancelled`; idle → accepted no-op. */
1503
+ export interface RecapCancelResult {
1504
+ /** The cancel's id, echoed. */
1505
+ commandId: string;
1506
+ /** Always `accepted` on this path. */
1507
+ status: CommandStatus;
1508
+ }
1509
+
1510
+ /** `recap/completed` params (tdd SS3.28.2): the settlement, delivered to the requesting connection outside the view stream — no `viewCursor`, no `sourceRange`. `text` is required on `completed` (plus optional `title`, untrusted model output — clients MUST sanitize per spec 442 INV-015); `reason` is required on `failed`; neither rides `cancelled`/`timedOut`. The struct marks the conditional members optional; the SS prose pins the per-outcome rule, the `turn/completed` usage/error convention. */
1511
+ export interface RecapCompletedParams {
1512
+ /** The request's id — the correlation key. */
1513
+ commandId: string;
1514
+ /** How the request settled. */
1515
+ outcome: RecapOutcome;
1516
+ /** Why the side-call failed (on `failed`). */
1517
+ reason?: RecapFailureReason;
1518
+ /** The recapped session. */
1519
+ sessionId: string;
1520
+ /** The recap text verbatim (on `completed`). */
1521
+ text?: string;
1522
+ /** The model-produced short title (on `completed`, when produced). */
1523
+ title?: string;
1524
+ }
1525
+
1526
+ /** `recap/completed` failure reason (tdd SS3.28.2/SS3.28.8): post-ack failures fold to the single initial value. **Open**: later splits stay additive (#22785 E2). */
1527
+ export type RecapFailureReason = "providerFailed" | (string & {});
1528
+
1529
+ /** `recap/completed` outcome (tdd SS3.28.2): the terminal vocabulary, camelCase per SS1.6. **Open**: a server-produced result vocabulary (#22785 E2). */
1530
+ export type RecapOutcome = "completed" | "failed" | "cancelled" | "timedOut" | (string & {});
1531
+
1532
+ /** `recap/request` params (tdd SS3.28.1): the session plus the client-minted UUIDv7 retry id. No other param; unknown fields are `invalidParams`. */
1533
+ export interface RecapRequestParams {
1534
+ /** The client-minted retry id (required, SS3.1.1). */
1535
+ commandId: string;
1536
+ /** The session to recap (required). */
1537
+ sessionId: string;
1538
+ }
1539
+
1540
+ /** `recap/request` result (tdd SS3.28.1): admission only — the ack is never the recap. */
1541
+ export interface RecapRequestResult {
1542
+ /** The request's id, echoed. */
1543
+ commandId: string;
1544
+ /** Always `accepted` on this path. */
1545
+ status: CommandStatus;
1546
+ }
1547
+
1548
+ /** One end of a [`SourceRange`]: a record's event id and its sequence number within the stream (tdd SS4.2). */
1549
+ export interface RecordPosition {
1550
+ /** The record's event id. */
1551
+ id: string;
1552
+ /** The record's sequence number within its stream. */
1553
+ sequence: number;
1554
+ }
1555
+
1556
+ /** A request frame, either direction (SS1.2 §2.1). */
1557
+ export interface Request {
1558
+ /** Client-chosen id, unique among that client's in-flight requests. */
1559
+ id: RequestId;
1560
+ /** The literal `"2.0"`. */
1561
+ jsonrpc: JsonRpcVersion;
1562
+ /** Slash-namespaced camelCase method name. */
1563
+ method: string;
1564
+ /** Method-specific parameters; omitted entirely when empty, never `null`. */
1565
+ params?: Record<string, unknown>;
1566
+ /** W3C trace passthrough (SS1.8); requests only. */
1567
+ trace?: TraceContext;
1568
+ }
1569
+
1570
+ /** A request id (SS1.3): client-chosen string or integer. `1` and `"1"` do not compare equal; each direction owns its own id space. */
1571
+ export type RequestId = number | string;
1572
+
1573
+ /** The SS5.3.3 presentation receipt — the client's response to a server-initiated request (`approval/request`, `userInput/request`). The response acknowledges presentation only ("a surface showed or will show this"): it changes no state, the server uses it for diagnostics alone, and the decision/answer travels as a command (`approval/decide`, `userInput/answer`). An error response or a dropped connection means this connection could not present the request; the approval or prompt stays pending and the request is re-issued on the next subscribe (SS5.6). There is no dismiss-without-deciding on the wire. */
1574
+ export interface RequestReceipt {
1575
+ }
1576
+
1577
+ /** A `turn/retracted` settlement outcome (tdd SS4.5.1, ADR 50074 D1). Open enum (D-033): decode is tolerant — a value outside the list reads as `Accepted` (the event's historical meaning — pre-feature hosts emit it only for accepted retracts), never fails. The bundle keeps enumerating the known values for codegen and docs. */
1578
+ export type RetractOutcome = "accepted" | "declined" | (string & {});
1579
+
1580
+ /** The `schema` pair in [`InitializeResult`] (SS1.4.1, SS1.5.3). `version` is the wire **envelope** schema version — distinct from the session-view `schemaVersion`, the raw-log `schema_version`, and the 0.x/1.0 stability posture, which is not on the wire at all (INV-006a). */
1581
+ export interface SchemaInfo {
1582
+ /** `sha256:<64 lower hex>` content hash of this server binary's stable-surface bundle (INV-003). A mismatch is a warning condition, not an error (SS1.4.1). */
1583
+ fingerprint: string;
1584
+ /** Envelope schema version; `1` in v1, expected to stay `1` for a long time (SS1.4.1). */
1585
+ version: number;
1586
+ }
1587
+
1588
+ /** Server identification inside [`InitializeResult`]. */
1589
+ export interface ServerInfo {
1590
+ /** Server name. */
1591
+ name: string;
1592
+ /** Server version string. */
1593
+ version: string;
1594
+ }
1595
+
1596
+ /** The session object every lifecycle method returns or lists (tdd SS2.4). Additive-optional evolution applies: clients must ignore unknown fields. */
1597
+ export interface Session {
1598
+ /** The `turnId` of the current foreground turn when `status` is `running`, and `null` when the session is idle (tdd SS2.4). **Required-nullable, per the owner ruling on #22946** ("approve required-nullable", review comment `r3863946961`, 2026-08-26). Both production writers hard-code `"activeTurnId": null` (`session/start/commit_load.rs` for `session/start`, `session/snapshot.rs` feeding resume/read/list/fork) and nothing strips it, so this is what the binary emits and what SS2.4's example spells. The optional-absent shape published it as plain `string` and REJECTED every idle `Session` frame the host sent — the #19923 defect class this PR exists to close. E5's original evidence for optional-absent ("every committed transcript shows the omission") was wrong: those transcripts are hand-authored fixtures, not host recordings. They are corrected in the same change under the ruling's SS1.5 `regenerationJustification`. */
1599
+ activeTurnId: string | null;
1600
+ /** The folded effective approval mode. **Additive-optional**: a Session object that omits it means the host has not folded a mode, which is why the index-derived `session/list` entry may legitimately omit it (tdd SS2.4, SS5.12). */
1601
+ approvalMode?: EffectiveApprovalModeState;
1602
+ /** Attention flags (tdd SS2.4, ADR 31983 D3). **Additive-optional**, present only when at least one flag is set; absence is a NON-assertion (nothing pending, or the loaded session's pending source declined to answer). Loaded sessions only: a `notLoaded` row omits it even while its durable pending set is non-empty. */
1603
+ attention?: AttentionFlag[];
1604
+ /** Derived workspace branch (tdd SS2.14.1, #27598) — the index's last derived value; the live-change signal stays `session/branchChanged` (SS4.6.4). **Additive-optional**, omitted when underivable. */
1605
+ branch?: string;
1606
+ /** RFC3339. For a fork this is the fork session id's UUIDv7 mint instant (tdd SS2.4). */
1607
+ createdAt: string;
1608
+ /** The handshake `ClientInfo` recorded when the session was opened (FR-003), echoed verbatim — provenance, never an interpretation, and never a visibility gate (INV-005). **Additive-optional**; absence has four indistinguishable causes (INV-004): an in-process open; a pre-#23124 record; a half stamp where only one of name/version was recorded (FM-005) and `ClientInfo` requires both; and a session with no admitting handshake of its own — a fork child or a subagent — which never carries a stamp to begin with. */
1609
+ createdByClient?: ClientInfo;
1610
+ /** Derived first-user-prompt preview (tdd SS2.14.1, #27598). **Additive-optional**, omitted when underivable. */
1611
+ firstUserPrompt?: string;
1612
+ /** `null` for root sessions; fork provenance otherwise (tdd SS2.4). */
1613
+ forkedFrom: ForkProvenance | null;
1614
+ /** What kind of session this is (spec 42713 FR-001, ADR 42713 D1/D4). **Open enum**, v1 values `"root"` and `"subagent"`; a client treats an unknown value as an unknown-but-present kind and renders it, never rejecting the row. **Additive-optional**: absence asserts nothing — the host could not determine the home shape (FM-001), or the value is not yet available to serve (FM-003). */
1615
+ kind?: SessionKind;
1616
+ /** Content-activity recency, RFC3339 (tdd SS2.4, ADR 31983 D5). **Additive-optional**: omitted when no content record exists. Never advanced by lifecycle bookkeeping (the resume marker, re-stamps) or a fork's copied seed-replay records, and never precedes `createdAt`. */
1617
+ lastActivityAt?: string;
1618
+ /** The winning metadata fold's model; `null` when that record omits it. */
1619
+ modelId: string | null;
1620
+ /** The durable allocated session name (tdd SS2.4/SS2.14.1, #27598; ADR 27598 D2/D4). **Additive-optional**: present when the serving path holds an allocated name, omitted otherwise — absent is never fabricated. Authoritative and renameable via `session/rename`. */
1621
+ name?: string;
1622
+ /** The containing session's id when `kind` is `"subagent"` (FR-002, INV-002) — the id of the TOP-LEVEL session whose home holds this child, which is **not necessarily the session that spawned it**: native-child homes are physical siblings under the outer session's `subagent/` directory, so a subagent spawned by another subagent resolves to the outer session, not to its spawner. A client building a tree from this field gets one level, not a chain. Flat rather than nested: there is exactly one fact to carry, unlike `forkedFrom`'s four-field `ForkProvenance`. **Additive-optional**; a root carries none. */
1623
+ parentSessionId?: string;
1624
+ /** Absolute path of the session's durable log; non-nullable. Under the ephemeral session profile it is the **empty string**, meaning "no durable log exists" (tdd SS2.13.2) — the one value a client must not hand to a filesystem call. */
1625
+ path: string;
1626
+ /** The winning metadata fold's provider; `null` when that record omits it. */
1627
+ providerId: string | null;
1628
+ /** The session identity. */
1629
+ sessionId: string;
1630
+ /** `null` for root sessions and forks; side provenance otherwise (tdd SS2.4/SS2.5.7; ADR 45435 D2). A session carries at most one of `forkedFrom` and `sideFrom`. */
1631
+ sideFrom?: SideProvenance | null;
1632
+ /** Load state as this host knows it; `session/list` reports `notLoaded` for sessions loaded by *other* hosts (tdd SS2.4). */
1633
+ status: SessionStatus;
1634
+ /** Derived display title (tdd SS2.14.1, #27598): a heuristic that may evolve — its carriage, not its derivation, is the contract. **Additive-optional**, omitted when underivable. */
1635
+ title?: string;
1636
+ /** Completed-turn count from the session view fold (tdd SS2.4). */
1637
+ turnCount: number;
1638
+ /** RFC3339; never precedes `createdAt` (tdd SS2.4). */
1639
+ updatedAt: string;
1640
+ /** The winning metadata fold's workspace root; `null` when that record omits it — absent is never fabricated (tdd SS2.4). */
1641
+ workspaceRoot: string | null;
1642
+ }
1643
+
1644
+ /** `session/approvalModeChanged` params (tdd SS5.12): the fold of the durable approval-mode reconfigure audit fact — every accepted change writes one; a mode flip without an audit fact is a runtime bug by design. */
1645
+ export interface SessionApprovalModeChangedParams {
1646
+ /** The requesting client's `clientInfo.name` (tdd SS1.4.1), recorded on the audit fact. */
1647
+ clientName: string;
1648
+ /** The command that changed it. */
1649
+ commandId: string;
1650
+ /** The mode now in effect. */
1651
+ mode: ApprovalMode;
1652
+ /** The owning session. */
1653
+ sessionId: string;
1654
+ /** How the mode took effect. */
1655
+ source: ApprovalModeSource;
1656
+ /** The durable records this event folded from. */
1657
+ sourceRange: SourceRange;
1658
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
1659
+ viewCursor: string;
1660
+ }
1661
+
1662
+ /** `session/branchChanged` params (tdd SS4.6.4): a durable workspace-branch observation landed. */
1663
+ export interface SessionBranchChangedParams {
1664
+ /** The observed branch; `null` on a detached-HEAD observation — a fact, not "unchanged" (tdd SS4.6.4). */
1665
+ branch: string | null;
1666
+ /** The owning session. */
1667
+ sessionId: string;
1668
+ /** The durable records this event folded from. */
1669
+ sourceRange: SourceRange;
1670
+ /** The detected version-control system; absent when no repository was detected. */
1671
+ vcs?: Vcs;
1672
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
1673
+ viewCursor: string;
1674
+ /** The observed workspace root. */
1675
+ workspaceRoot: string;
1676
+ }
1677
+
1678
+ /** `session/closed` params (tdd SS2.6.2; enrolled by #33065): a loaded session was unloaded from this host, broadcast to every initialized connection. After it, the session is `notLoaded`; the log remains on disk and `session/resume` reloads it. A crash emits nothing — only the two orderly unload paths do, and both write the durable `SessionEnd` record first. */
1679
+ export interface SessionClosedParams {
1680
+ /** Which orderly unload path fired. */
1681
+ reason: SessionClosedReason;
1682
+ /** The unloaded session. */
1683
+ sessionId: string;
1684
+ /** The final view head; a client that stores it can later `session/resume {cursor}` and receive exactly the (empty) suffix. An **opaque** view cursor: clients relay it, never parse it (tdd SS4.1). **Required-nullable**: the producers always write the member and write `null` when the final fold failed at unload (`session/idle.rs`, `serve/shutdown.rs`; PR #16779 review) — the host defines no cursor values of its own and never invents one, and the subscriber still learns the session closed. */
1685
+ viewCursor: string | null;
1686
+ }
1687
+
1688
+ /** The SS2.6.2 closed-reason vocabulary. Server-produced and published OPEN by owner ruling — the #33065 menu-B pick (PR #33201 comment 5638727249, recorded in the enrollment decision record), which settles that this notification reason enum publishes open rather than resting on E2's result-vocabulary rule by analogy. A crash is deliberately not a reason, because a crash emits no notification at all. */
1689
+ export type SessionClosedReason = "idle" | "hostShutdown" | (string & {});
1690
+
1691
+ /** `session/compact` params (tdd SS3.7): manually compact the session's conversation context — the `/compact` gesture. Compaction runs asynchronously; the ack is admission only. */
1692
+ export interface SessionCompactParams {
1693
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
1694
+ commandId: string;
1695
+ /** The target session. */
1696
+ sessionId: string;
1697
+ /** The run whose context to compact. Omit and the server resolves the session's current/latest run; a session with no resolvable run rejects with `commandRejected` reason `missing_run` (tdd SS3.7). Any syntactically valid UUID: a turn from an older session may carry a v4 or v5 id. A malformed id is `invalidParams`. */
1698
+ turnId?: string;
1699
+ }
1700
+
1701
+ /** `session/compact` result (tdd SS3.7). Failures *after* admission (`summarizer_failed`, `install_rejected`, `cancelled`) are not wire errors — they arrive as the compaction's terminal view event. */
1702
+ export interface SessionCompactResult {
1703
+ /** Echoes the client's id. */
1704
+ commandId: string;
1705
+ /** Why the command was a noop, e.g. `no_compactable_history`. Present on a `noop` status (tdd SS3.7). */
1706
+ reason?: string;
1707
+ /** Admission status, or `noop`. */
1708
+ status: CompactStatus;
1709
+ }
1710
+
1711
+ /** The open configuration extension object shared by `session/start` and `session/resume` (ADR 32760 D1). Unknown keys are ignored on the wire, never rejected (tdd SS1.5.4, spec 206 INV-015; D-052 resolving [#23456](https://github.com/mslsrc/tbh/issues/23456)): the live decoder is D-042's tolerant path, and TEST-024 keeps every exported bundle free of `additionalProperties: false`. The Rust typed model's `deny_unknown_fields` is internal and never exported — the #22785 E6b closedness export applies nowhere, and the `x-msp-closed` opt-in mechanism stays inert. Recognized `mcpServers` values are typed and validated before they leave the wire boundary. */
1712
+ export interface SessionConfig {
1713
+ /** Native MCP servers added only to this session runtime. */
1714
+ mcpServers?: Record<string, SessionMcpServerConfig>;
1715
+ }
1716
+
1717
+ /** `session/contextUsage` params (tdd SS4.6.6, #14405): context-window pressure — the counted-once occupancy at the latest provider-reported durable fact, joined with the host's pressure basis. Replace wholesale; emitted only when the `(windowTokens, usedTokens, pressure)` triple changes value (identical adoptions emit nothing). */
1718
+ export interface SessionContextUsageParams {
1719
+ /** Server-computed pressure level over the basis thresholds. */
1720
+ pressure: ContextPressureLevel;
1721
+ /** The owning session. */
1722
+ sessionId: string;
1723
+ /** The durable records this event folded from. */
1724
+ sourceRange: SourceRange;
1725
+ /** Counted-once prompt tokens (#8803) plus output tokens of the driving record, saturating — the honest occupancy floor. */
1726
+ usedTokens: number;
1727
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
1728
+ viewCursor: string;
1729
+ /** The effective context-window size from the host's pressure basis; absent when the basis has no limit — the limit part is omitted, never invented (tdd SS4.6.6). */
1730
+ windowTokens?: number;
1731
+ }
1732
+
1733
+ /** Whether this host writes its sessions to disk (SS1.4.1, SS2.13). A property of the host process, fixed at construction and identical for every session and every connection it serves — never requested, granted, or negotiated, which is why it is not a capability. Open: the unrepresented degraded state (#14401) has candidate resolutions that add a third value here, so closed would make that a breaking change. */
1734
+ export type SessionDurability = "durable" | "ephemeral" | (string & {});
1735
+
1736
+ /** `session/fork` params (tdd SS2.5.3). */
1737
+ export interface SessionForkParams {
1738
+ /** The SS2.5 idempotency handle (UUIDv7). */
1739
+ commandId: string;
1740
+ /** Copy history through a completed turn, inclusive. Omitted means "all completed turns" (tdd SS2.5.3). */
1741
+ cutPoint?: ForkCutPoint;
1742
+ /** Skip inline history in the result and page it later — same as `session/resume` (tdd SS2.5.3). */
1743
+ excludeItems?: boolean;
1744
+ /** The source session. */
1745
+ sessionId: string;
1746
+ }
1747
+
1748
+ /** `session/fork` result (tdd SS2.5.3): the `session/resume` envelope for the **new** session, whose `session.forkedFrom` carries the provenance. */
1749
+ export interface SessionForkResult {
1750
+ /** The served history. */
1751
+ history: SessionHistory;
1752
+ /** The late-joiner pointer set. */
1753
+ pendingRequests: PendingRequestPointer[];
1754
+ /** The new fork session, carrying `forkedFrom` provenance. */
1755
+ session: Session;
1756
+ /** The new session's view head. */
1757
+ viewCursor: string;
1758
+ }
1759
+
1760
+ /** `session/goalChanged` params (tdd SS4.6.2): the projected goal block's value changed — identical adoptions emit nothing (the change gate), and an explicit `null` clears. Replace wholesale; `null` never means unchanged. */
1761
+ export interface SessionGoalChangedParams {
1762
+ /** The full current goal block, or `null` to clear. */
1763
+ goal: Goal | null;
1764
+ /** The owning session. */
1765
+ sessionId: string;
1766
+ /** The durable records this event folded from. */
1767
+ sourceRange: SourceRange;
1768
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
1769
+ viewCursor: string;
1770
+ }
1771
+
1772
+ /** The `history` envelope shared by `session/resume`, `session/fork`, and `session/read` (tdd SS2.5.2). */
1773
+ export interface SessionHistory {
1774
+ /** The full folded item array when `mode` is `inline`; `null` otherwise. */
1775
+ items: Item[] | null;
1776
+ /** What was actually served — never what was asked for (tdd SS2.5.2). */
1777
+ mode: HistoryMode;
1778
+ /** Why no history was served — sent exactly when `mode` is `"none"` (tdd SS2.5.2; D-050, spec 208 INV-19734-1). */
1779
+ noneReason?: HistoryNoneReason;
1780
+ /** The folded view state when `mode` is `snapshot` or `anchoredSnapshot`; `null` otherwise. */
1781
+ snapshot: ViewSnapshot | null;
1782
+ }
1783
+
1784
+ /** What kind of session this is (spec 42713 FR-001/FR-005, ADR 42713 D1/D4). **Open**: a new kind is additive evolution, and a client MUST render an unknown value as an unknown-but-present kind rather than rejecting the row. Both v1 values are terms the tree already uses — the child log directory is `subagent` and `ItemKind` already carries a `subagent` variant — so no new vocabulary is minted. */
1785
+ export type SessionKind = "root" | "subagent" | (string & {});
1786
+
1787
+ /** Exact branch selection (#42035 FR-42035-2). */
1788
+ export interface SessionListBranchFilter {
1789
+ /** 1–32 nonempty branch names, each 1–256 UTF-8 bytes, counted before deduplication; `null` selects sessions with no branch. */
1790
+ anyOf: (string | null)[];
1791
+ }
1792
+
1793
+ /** `session/listChanged` params (#33084, ADR 33084 D3): one changed row of the `session/list` shape — the full SS2.4 Session object as the answering host's list face serves it at emission (the ADR 29243 live-overlaid row), a replace, never a delta. Emitted only on connections that negotiated the `sessionListStream` capability at `initialize` (ADR 33084 D2); row birth stays on `session/started`, unload pairs with `session/closed`. */
1794
+ export interface SessionListChangedParams {
1795
+ /** The served list row for the changed session. */
1796
+ session: Session;
1797
+ }
1798
+
1799
+ /** The `session/list` filter (#42035, spec 207 FR-42035-2..5). Members are ANDed with each other and with the top-level `workspaceRoot` and `updatedAfter`; values inside each `anyOf` are ORed. The canonical form the server echoes deduplicates and sorts every set, spells session IDs as canonical UUIDs, lowercases text terms, and orders `text.fields` `name` then `title`. */
1800
+ export interface SessionListFilter {
1801
+ /** Only sessions whose branch is one of these. */
1802
+ branch?: SessionListBranchFilter;
1803
+ /** Only sessions whose ID is one of these. */
1804
+ sessionId?: SessionListSessionIdFilter;
1805
+ /** Only sessions whose served name or title matches these token prefixes. */
1806
+ text?: SessionListTextFilter;
1807
+ }
1808
+
1809
+ /** `session/list` params (tdd SS2.5.4). Read-only; never touches leases. */
1810
+ export interface SessionListParams {
1811
+ /** Opaque page cursor from a prior result. Page cursors are a distinct opaque-string family from view cursors and stream cursors, valid only for re-issuing the same listing (tdd SS2.5.4). Omitted and explicit `null` both mean "first page" (#23468). */
1812
+ cursor?: string | null;
1813
+ /** Optional structured selection applied inside the bounded index query before paging (#42035, spec 207 FR-42035-1). Present — including `{}` — makes a supporting server echo its canonical form as `appliedFilter`; omitted keeps the pre-#42035 behavior. */
1814
+ filter?: SessionListFilter;
1815
+ /** Page size; default 50, max 200 — the cap is published under #22785 E6c (owner-ruled 2026-08-26). Maximum 200. */
1816
+ limit?: number;
1817
+ /** Only sessions with log activity after this RFC3339 instant. */
1818
+ updatedAfter?: string;
1819
+ /** Only sessions whose metadata workspace root equals this path. */
1820
+ workspaceRoot?: string;
1821
+ }
1822
+
1823
+ /** `session/list` result (tdd SS2.5.4). Ordering is `updatedAt` descending. */
1824
+ export interface SessionListResult {
1825
+ /** The canonical filter the server applied, present exactly when the request carried `filter` (#42035, spec 207 FR-42035-1). The probe is per-predicate PRESENCE (ADR 42035 D6): a client that requires filtering checks that every predicate it sent comes back as a member here, and treats a missing member as unsupported. Value equality is the wrong test — canonicalization trims, lowercases, NFC-normalizes, dedupes and sorts, so the echoed values often differ from the sent ones on a correctly filtered page. */
1826
+ appliedFilter?: SessionListFilter;
1827
+ /** The next page's cursor; `null` on the last page. */
1828
+ nextCursor: string | null;
1829
+ /** The page of stored sessions. */
1830
+ sessions: Session[];
1831
+ }
1832
+
1833
+ /** Exact session-ID selection (#42035 FR-42035-2). */
1834
+ export interface SessionListSessionIdFilter {
1835
+ /** 1–200 session UUIDs, counted before deduplication. */
1836
+ anyOf: string[];
1837
+ }
1838
+
1839
+ /** A served session field `session/list` text search reads (#42035 FR-42035-3). The client selects it, so the set is closed. */
1840
+ export type SessionListTextField = "name" | "title";
1841
+
1842
+ /** Name/title token-prefix search (#42035 FR-42035-3/FR-42035-4). Each term is trimmed, lowercased with ordinary Unicode lowercase, then NFC- normalized, and matches the beginning of an alphanumeric token, accent-sensitively (`check` matches `Checkout`; `eck` does not). NFC means a decomposed and a precomposed spelling of one term are the same term, and the echo returns the composed form. Matching never reorders rows. */
1843
+ export interface SessionListTextFilter {
1844
+ /** Every term must match at least one selected field. */
1845
+ allOf?: string[];
1846
+ /** At least one term must match a selected field. `allOf` plus `anyOf` carry 1–16 terms in total, each 1–128 UTF-8 bytes in its canonical form (trimmed, lowercased, NFC) — the bytes `appliedFilter` echoes. Lowercasing and NFC can both lengthen a term, so a term inside the bound raw may still exceed it canonically. */
1847
+ anyOf?: string[];
1848
+ /** The 1–2 unique served fields searched. */
1849
+ fields: SessionListTextField[];
1850
+ }
1851
+
1852
+ /** One native MCP server supplied at session construction (ADR 32760 D1). **Closed union** (#33295 owner ruling A1, extending D-033/D-050 to `oneOf`): a validator MUST reject an undeclared `transport` arm — the server fails `session/start` decode on an unknown transport, and a future transport arrives as an explicit schema addition. */
1853
+ export type SessionMcpServerConfig = { /** Ordered child arguments. */ args?: string[]; /** Executable name or path. Configuration diagnostics never echo it. */ command: string; /** Explicit child environment additions. */ env?: Record<string, string>; /** Stdio framing mode; defaults to automatic detection. */ framing?: SessionMcpStdioFraming; /** Required/optional startup posture; defaults to required. */ mode?: SessionMcpServerMode; transport: "stdio"; } | { /** Explicit request headers. */ headers?: Record<string, string>; /** Required/optional startup posture; defaults to required. */ mode?: SessionMcpServerMode; transport: "streamableHttp"; /** HTTP(S) endpoint. Configuration diagnostics never echo it. */ url: string; };
1854
+
1855
+ /** Startup failure posture for a session MCP server. */
1856
+ export type SessionMcpServerMode = "required" | "optional";
1857
+
1858
+ /** Stdio framing choices exposed by session MCP configuration. */
1859
+ export type SessionMcpStdioFraming = "auto" | "contentLength" | "lineDelimitedJson";
1860
+
1861
+ /** `session/modelChanged` params (tdd SS4.6.1): a durable model-selection record landed (tdd SS3.8). */
1862
+ export interface SessionModelChangedParams {
1863
+ /** The selected model. */
1864
+ modelId: string;
1865
+ /** The selected provider; `null` when the selection names none. */
1866
+ providerId: string | null;
1867
+ /** The owning session. */
1868
+ sessionId: string;
1869
+ /** What drove the selection. */
1870
+ source: ModelChangeSource;
1871
+ /** The durable records this event folded from. */
1872
+ sourceRange: SourceRange;
1873
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
1874
+ viewCursor: string;
1875
+ }
1876
+
1877
+ /** `session/modelRouteUnserved` params (#25603, ADR 25603 D1, spec 5469 Amendment 16): an accepted `login.credential_update` installed a provider that cannot serve the session's STANDING model route. Disclosure only — the standing selection is unchanged (no `session/modelChanged` fires) and the repair path is a routable `session/setModel`. Folded from the durable `runtime.provider_reconfigure.standing_route_unserved` record; additive — clients that predate it skip the unknown method. */
1878
+ export interface SessionModelRouteUnservedParams {
1879
+ /** The command whose accepted swap installed the provider. */
1880
+ commandId: string;
1881
+ /** The provider id the swap installed. */
1882
+ installedProviderId: string;
1883
+ /** The standing (still bound, now unroutable) model. */
1884
+ modelId: string;
1885
+ /** The standing model's provider; `null` when the selection names none. */
1886
+ providerId: string | null;
1887
+ /** The owning session. */
1888
+ sessionId: string;
1889
+ /** The durable records this event folded from. */
1890
+ sourceRange: SourceRange;
1891
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
1892
+ viewCursor: string;
1893
+ }
1894
+
1895
+ /** `session/nameChanged` params (tdd SS4.6.7, #27598): the fold of ANY durable session-name record — the FIRST-NAMING automatic allocate as well as an accepted `session/rename` (or the same in-process runtime command). Replace-wholesale like every SS4.6 sibling. */
1896
+ export interface SessionNameChangedParams {
1897
+ /** The new canonical name now in effect. */
1898
+ name: string;
1899
+ /** The owning session. */
1900
+ sessionId: string;
1901
+ /** The durable records this event folded from. */
1902
+ sourceRange: SourceRange;
1903
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
1904
+ viewCursor: string;
1905
+ }
1906
+
1907
+ /** `session/read` params (tdd SS2.5.5): read one stored session **without attaching** — no writer lease, no load, no subscription, no `SessionResumed` record. */
1908
+ export interface SessionReadParams {
1909
+ /** Metadata-only unless you ask: `false` carries the folded item history. Same name and polarity as `session/resume`/`session/fork`; only the default differs — here it is `true` (tdd SS2.5.5). */
1910
+ excludeItems?: boolean;
1911
+ /** The session to read. */
1912
+ sessionId: string;
1913
+ }
1914
+
1915
+ /** `session/read` result (tdd SS2.5.5). The `viewCursor` is the fold head at read time — a point-in-time read, immediately stale if a foreign host is appending. */
1916
+ export interface SessionReadResult {
1917
+ /** The served history. */
1918
+ history: SessionHistory;
1919
+ /** Same member as `session/resume` (tdd SS2.5.5, ADR 36635 D2). */
1920
+ lastTurn?: LastTurn;
1921
+ /** The same pointer shape as `session/resume`. Because `session/read` never subscribes this is a point-in-time log read only: no requests are re-issued after it (tdd SS2.5.5). */
1922
+ pendingRequests: PendingRequestPointer[];
1923
+ /** The session as folded point-in-time. */
1924
+ session: Session;
1925
+ /** The fold head at read time. */
1926
+ viewCursor: string;
1927
+ }
1928
+
1929
+ /** `session/reasoningEffortChanged` params (tdd SS4.6.9, ADR 31255 D1): a durable reasoning-effort reconfigure record landed (tdd SS3.21). Replace wholesale, latest wins; the snapshot carries the latest value (SS4.9.1). */
1930
+ export interface SessionReasoningEffortChangedParams {
1931
+ /** The new session default: the closed eight-string tier vocabulary of tdd SS3.2, spelled identically. */
1932
+ reasoningEffort: ReasoningEffort;
1933
+ /** The owning session. */
1934
+ sessionId: string;
1935
+ /** What drove the change. */
1936
+ source: ReasoningEffortChangeSource;
1937
+ /** The durable records this event folded from. */
1938
+ sourceRange: SourceRange;
1939
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
1940
+ viewCursor: string;
1941
+ }
1942
+
1943
+ /** `session/rename` params (tdd SS2.14.2, #27598): set or change the durable allocated session name through the runtime `session_name` command. One writer; withheld under the ephemeral profile. */
1944
+ export interface SessionRenameParams {
1945
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
1946
+ commandId: string;
1947
+ /** The requested name; the runtime's normalization and validation apply. */
1948
+ name: string;
1949
+ /** The target session. */
1950
+ sessionId: string;
1951
+ }
1952
+
1953
+ /** `session/rename` result (tdd SS2.14.2, #27598): `name` is the canonical (normalized) name the durable record settled. */
1954
+ export interface SessionRenameResult {
1955
+ /** Echoes the client's id. */
1956
+ commandId: string;
1957
+ /** The settled canonical name. Omitted on the `RecoveryPending` arm, which answers `{commandId, status: "accepted"}` and delivers the name via `session/nameChanged` / `Session.name` (tdd SS2.14.2). */
1958
+ name?: string;
1959
+ /** Admission status. */
1960
+ status: CommandStatus;
1961
+ }
1962
+
1963
+ /** `session/resume` params (tdd SS2.5.2). */
1964
+ export interface SessionResumeParams {
1965
+ /** The SS2.5 idempotency handle (UUIDv7). A resume that loads a session writes a durable `SessionResumed` record. */
1966
+ commandId: string;
1967
+ /** The same open construction-time extension object as `session/start`. */
1968
+ config?: SessionConfig;
1969
+ /** A view cursor previously observed by this client — or an observed `summarizedThrough` compaction anchor (tdd SS4.5.10, D-029). When present the server returns only the suffix and `history.mode` is `none` (tdd SS2.5.2). Omitted and explicit `null` both mean "no cursor" (#23468). */
1970
+ cursor?: string | null;
1971
+ /** Return only session metadata and live resume state; page history separately with `view/page`. Default `false` (tdd SS2.5.2). */
1972
+ excludeItems?: boolean;
1973
+ /** History mode preference, default `auto`. A PREFERENCE, not a budget override: when the requested mode does not fit the history budget the server downgrades it and `history.mode` reports what was actually served (tdd SS2.5.2). Ignored when `cursor` or `excludeItems` makes it moot. */
1974
+ history?: HistoryPreference;
1975
+ /** The session to load. */
1976
+ sessionId: string;
1977
+ }
1978
+
1979
+ /** `session/resume` result (tdd SS2.5.2). */
1980
+ export interface SessionResumeResult {
1981
+ /** The served history. */
1982
+ history: SessionHistory;
1983
+ /** How the last folded turn ended (tdd SS2.5.2, ADR 36635 D2). **Additive-optional**; absence is a non-assertion. */
1984
+ lastTurn?: LastTurn;
1985
+ /** The late-joiner pointer set; empty when nothing is pending. */
1986
+ pendingRequests: PendingRequestPointer[];
1987
+ /** The loaded session. */
1988
+ session: Session;
1989
+ /** The session view head; the connection is subscribed after it. A still-loaded session a prior `view/unsubscribe` detached is RE-ATTACHED by this resume (spec 208 FR-002a, #28920): live delivery resumes from this head. Explicit-cursor re-attach with `(after, head]` engine replay stays `view/subscribe` (SS4.7.1). */
1990
+ viewCursor: string;
1991
+ }
1992
+
1993
+ /** `session/setApprovalMode` params (tdd SS5.12): switch the session's approval enforcement mode mid-session. A standard SS3 command. **Select, never create.** A client may *select* a mode the host's configuration already defines; it may not construct one, supply inline rules, or otherwise describe a policy on the wire — which is why [`ApprovalMode`] is closed. */
1994
+ export interface SessionSetApprovalModeParams {
1995
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
1996
+ commandId: string;
1997
+ /** The preconfigured mode to select. The requesting actor is recorded from the connection's `clientInfo.name` (tdd SS1.4.1). */
1998
+ mode: ApprovalMode;
1999
+ /** The target session. */
2000
+ sessionId: string;
2001
+ }
2002
+
2003
+ /** `session/setApprovalMode` result (tdd SS5.12). Applies next-action — an in-flight tool action's pending approval is not retroactively decided by a mode change. */
2004
+ export interface SessionSetApprovalModeResult {
2005
+ /** Whether the change did anything. */
2006
+ applyOutcome: ApprovalModeApplyOutcome;
2007
+ /** Echoes the client's id. */
2008
+ commandId: string;
2009
+ /** The folded effective-mode projection — the same object the `Session` carries as `approvalMode` (tdd SS2.4, SS5.12). */
2010
+ effectiveMode: EffectiveApprovalModeState;
2011
+ /** Admission status. */
2012
+ status: CommandStatus;
2013
+ }
2014
+
2015
+ /** `session/setModel` params (tdd SS3.8): the model-picker gesture. The selection is durable and applies to subsequent model calls. */
2016
+ export interface SessionSetModelParams {
2017
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
2018
+ commandId: string;
2019
+ /** The selection. */
2020
+ model: ModelSelection;
2021
+ /** The target session. */
2022
+ sessionId: string;
2023
+ }
2024
+
2025
+ /** `session/setModel` result (tdd SS3.8). If a turn is running the selection is admitted now and applied at the next model-call boundary; the ack does not wait for that boundary. */
2026
+ export interface SessionSetModelResult {
2027
+ /** Echoes the client's id. */
2028
+ commandId: string;
2029
+ /** Admission status. */
2030
+ status: CommandStatus;
2031
+ }
2032
+
2033
+ /** `session/setReasoningEffort` params (tdd SS3.21, ADR 31255 D1): set the session's standing reasoning-effort default. A turn carrying its own `reasoningEffort` overrides it for that turn only; the default overrides the host's configured default. Same accept/reject and `commandId` idempotency shape as `session/setModel` (SS3.8). */
2034
+ export interface SessionSetReasoningEffortParams {
2035
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
2036
+ commandId: string;
2037
+ /** The new session default: the closed eight-string tier vocabulary `turn/start` carries (SS3.2), spelled identically. Invalid tiers are invalid params. A default of `max` rides provider requests verbatim, never clamped (ADR 28621 D8, ADR 31131 D1). */
2038
+ reasoningEffort: ReasoningEffort;
2039
+ /** The target session. */
2040
+ sessionId: string;
2041
+ }
2042
+
2043
+ /** `session/setReasoningEffort` result (tdd SS3.21). The default is durable on ack and applies to turns launched after admission; a running turn keeps the request options it already resolved. */
2044
+ export interface SessionSetReasoningEffortResult {
2045
+ /** Echoes the client's id. */
2046
+ commandId: string;
2047
+ /** Admission status. */
2048
+ status: CommandStatus;
2049
+ }
2050
+
2051
+ /** `session/sideChat` params (tdd SS2.5.7; ADR 45435 D2). */
2052
+ export interface SessionSideChatParams {
2053
+ /** The SS2.5 idempotency handle (UUIDv7). */
2054
+ commandId: string;
2055
+ /** The source main session. */
2056
+ sessionId: string;
2057
+ }
2058
+
2059
+ /** `session/sideChat` result (tdd SS2.5.7; ADR 45435 D2): the `session/resume` envelope for the **new** side session, whose `session.sideFrom` carries the provenance. The side opens empty. */
2060
+ export interface SessionSideChatResult {
2061
+ /** The served history (inline; SS2.5.7's empty-items half is #49416 — inherited turns surface until the boundary-aware fold lands). */
2062
+ history: SessionHistory;
2063
+ /** The late-joiner pointer set. */
2064
+ pendingRequests: PendingRequestPointer[];
2065
+ /** The new side session, carrying `sideFrom` provenance. */
2066
+ session: Session;
2067
+ /** The new side session's view head. */
2068
+ viewCursor: string;
2069
+ }
2070
+
2071
+ /** `session/start` params (tdd SS2.5.1). */
2072
+ export interface SessionStartParams {
2073
+ /** The session's starting approval mode; server default when omitted or explicit `null` — both spellings select the default (#23468). Select, never create — the value names a mode the host's configuration already defines (tdd SS2.5.1, SS5.12). This is the only surface that declares a non-interactive run's policy (tdd SS5.11, D-008). */
2074
+ approvalMode?: ApprovalMode | null;
2075
+ /** The SS2.5 idempotency handle (UUIDv7). Required; the server never mints one. */
2076
+ commandId: string;
2077
+ /** Reserved for per-session overrides owned by a future Configuration section. Issue #32760 admits only its `mcpServers` member. */
2078
+ config?: SessionConfig;
2079
+ /** Initial model; server default when omitted. */
2080
+ modelId?: string;
2081
+ /** The new session's initial permission profile (amendment 42624 FR-42624-1, ADR 42197 D2): a profile id the host catalog already admits — the rows `permissionProfile/list` serves without `sessionId`. Select, never create. Omitted means today's behavior: the host's configured default under native admission, unchanged. An id the catalog does not carry, or one it serves unavailable, refuses the start `commandRejected` (-32030; `permission_profile_unknown` / `permission_profile_unavailable`) before any durable byte, and an ephemeral host refuses any id (`permission_profile_ephemeral_fixed`). `session/resume` and `session/fork` do not admit the member. Explicit `null` is invalid params: the set of members that tolerate `null` is closed and excludes this one, exactly as it excludes `workspaceRoots`. */
2082
+ permissionProfile?: string;
2083
+ /** Initial provider routing; server default when omitted or explicit `null` — both spellings select the default (#23468). */
2084
+ providerId?: string | null;
2085
+ /** Exact identity for this new root session. When omitted the server mints a UUIDv7. This field never selects an existing session: a retained or reserved id is rejected `commandRejected` with reason `session_id_conflict` (tdd SS2.5.1). */
2086
+ sessionId?: string;
2087
+ /** Absolute path, folded into the first metadata record. */
2088
+ workspaceRoot?: string;
2089
+ /** The session's initial runtime workspace-root set: ordered absolute canonical existing directory paths; the first root is the CWD and plays the primary-root role; every root receives the ADR 11237 `:workspace_roots` rules; extra roots grant no Project Trust. When `workspaceRoot` is also present the two must name the same folder, compared on canonical forms (the raw `workspaceRoot` is canonicalized first; ADR 37313 D9), or the request is invalid params, and so is explicit `null` (the D-049 null-tolerant set is closed and excludes this member). Omitted preserves single-root behavior (tdd SS2.5.1, ADR 37313, #37313). */
2090
+ workspaceRoots?: string[];
2091
+ }
2092
+
2093
+ /** `session/start` result (tdd SS2.5.1). */
2094
+ export interface SessionStartResult {
2095
+ /** The new session. */
2096
+ session: Session;
2097
+ /** The session view head after the start fold; the connection is subscribed and receives every view event after this cursor. A deduplicated retry returns this same result (tdd SS2.5.1). */
2098
+ viewCursor: string;
2099
+ }
2100
+
2101
+ /** `session/started` params (tdd SS2.6.1; enrolled by #33065): a session became newly loaded on this host via `session/start`, `session/fork`, or `session/sideChat` (never `session/resume` — Appendix C, OQ-F), broadcast to every initialized connection. The one member is the same `$defs/Session` object the `session/start`/`session/fork` results carry, so the broadcast and the result describe one fact through one type — the host builds the broadcast payload as a `$defs/Session` — the fresh-start arm reuses the result's `session` member, the start-replay arm builds the live attach snapshot — and the emission is parity-gated against this type at the producer (`session-server` prod-assembly capture) and over the committed transcript corpus (conformance `session_lifecycle_enrollment`). */
2102
+ export interface SessionStartedParams {
2103
+ /** The newly loaded session, as of the start/fork fold. */
2104
+ session: Session;
2105
+ }
2106
+
2107
+ /** A session's load state (tdd SS2.4). */
2108
+ export type SessionStatus = "notLoaded" | "idle" | "running" | (string & {});
2109
+
2110
+ /** `session/statusChanged` params (tdd SS4.6.10, ADR 31983 D2): a loaded session's projected `(status, attention)` value flipped. A command-plane broadcast — delivered to every connection regardless of its view subscription set, never gated, no `sourceRange`; the same facts live on the Session object, which is how a client seeds its table (no initial burst on connect). */
2111
+ export interface SessionStatusChangedParams {
2112
+ /** Attention flags after the transition; present only when at least one flag is set (tdd SS2.4, ADR 31983 D3). */
2113
+ attention?: AttentionFlag[];
2114
+ /** The owning session. */
2115
+ sessionId: string;
2116
+ /** Load state after the transition (the closed SS2.4 enum, unchanged). */
2117
+ status: SessionStatus;
2118
+ /** The causing record's view cursor (ADR 31983 D4). Required-nullable: `null` exactly when the paired `session/closed`'s cursor is `null` (the unload fold-failure arm); a definite cursor everywhere else. */
2119
+ viewCursor: string | null;
2120
+ }
2121
+
2122
+ /** `session/todoListChanged` params (tdd SS4.6.3): a `TodoSnapshotUpdated` record landed. Replace the whole list on every event; an empty `items` array is a cleared list, not a no-op. */
2123
+ export interface SessionTodoListChangedParams {
2124
+ /** The full todo list, replaced wholesale. */
2125
+ items: TodoItem[];
2126
+ /** The snapshot revision. Diagnostics only, never an ordering guard — `viewCursor` orders (tdd SS4.6.3). */
2127
+ revision: number;
2128
+ /** The owning session. */
2129
+ sessionId: string;
2130
+ /** The durable records this event folded from. */
2131
+ sourceRange: SourceRange;
2132
+ /** The tool that produced the snapshot, verbatim. */
2133
+ sourceTool: string;
2134
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
2135
+ viewCursor: string;
2136
+ }
2137
+
2138
+ /** `session/tokenUsage` params (tdd SS4.6.5): one per model completion that reports usage. Carries the raw counters verbatim plus the server-derived counted-once `promptTokens`/`totalTokens` (#8803: clients display and sum these and never re-derive the provider's cache convention) and the session `cumulative` block. Accumulate-only: `cumulative` never goes backward. */
2139
+ export interface SessionTokenUsageParams {
2140
+ /** Session running totals at this cursor; the fold owns the accumulation. Subagent/workflow-child usage is never folded in — it rides the owning items (tdd SS4.6.5). */
2141
+ cumulative: CumulativeTokenUsage;
2142
+ /** Model-call wall time, when measured. */
2143
+ durationMs?: number;
2144
+ /** Provider finish reason when reported (open vocabulary, verbatim). */
2145
+ finishReason?: string;
2146
+ /** The effective model that produced this usage; `null` on pre-schema records — never back-filled, an unpriced leg (tdd SS4.6.5). */
2147
+ modelId: string | null;
2148
+ /** Prompt tokens counted exactly once under the provider's cache convention (#8803). Server-derived; deterministic — the provider is in the log. */
2149
+ promptTokens: number;
2150
+ /** The owning session. */
2151
+ sessionId: string;
2152
+ /** The durable records this event folded from. */
2153
+ sourceRange: SourceRange;
2154
+ /** `promptTokens + outputTokens` — the honest per-completion total. */
2155
+ totalTokens: number;
2156
+ /** The turn whose model call completed. */
2157
+ turnId: string;
2158
+ /** Raw counters verbatim from the durable record. */
2159
+ usage: TokenUsage;
2160
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
2161
+ viewCursor: string;
2162
+ }
2163
+
2164
+ /** `session/userShell` params (tdd SS3.9): run a user-initiated shell command in the session's workspace — the TUI's `!` escape hatch. **Capability-gated**: the connection must negotiate `userShell` at `initialize`, and the whole justification is the SS1.10 spawn boundary. */
2165
+ export interface SessionUserShellParams {
2166
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
2167
+ commandId: string;
2168
+ /** The shell command to run. */
2169
+ commandText: string;
2170
+ /** The target session. */
2171
+ sessionId: string;
2172
+ }
2173
+
2174
+ /** `session/userShell` result (tdd SS3.9): immediate. The shell runs off the command worker so a long command cannot stall the command plane; the output arrives as the `userShell` item's terminal view event. */
2175
+ export interface SessionUserShellResult {
2176
+ /** Echoes the client's id. */
2177
+ commandId: string;
2178
+ /** Admission status. */
2179
+ status: CommandStatus;
2180
+ }
2181
+
2182
+ /** The view-health state (tdd SS2.5.2 companion). Open enum (`x-msp-openness: open`): a client MUST ignore an unrecognized value. v1 emits only `Unavailable`; openness itself reserves additive room for a future re-arm (ADR 32557 D1 names it `healthy`) and for the #14401 durable-degraded axis, so no never-emitted token is baked onto the stable surface now. */
2183
+ export type SessionViewHealth = "unavailable" | (string & {});
2184
+
2185
+ /** `session/viewHealthChanged` params (ADR 32557; #32557): the named session's live view stream became unavailable, and why. Best-effort: ordered after already-queued view frames and may be dropped (for example when the connection is closing), so a client MUST NOT assume a guaranteed push and still reads `history.noneReason` on its next resume/read (FM-005). */
2186
+ export interface SessionViewHealthChangedParams {
2187
+ /** The new view-health state. In v1 the host emits only `Unavailable`. */
2188
+ health: SessionViewHealth;
2189
+ /** Why the view is unavailable — the SAME typed `HistoryNoneReason` vocabulary the pull path stamps on `history.noneReason` (tdd SS2.5.2, D-050), so a client reuses one handler for push and pull. `projectionUnavailable` in v1; present only when `health` is `Unavailable`. Open on the client side: an unknown reason decodes conservatively and renders generically. */
2190
+ noneReason?: HistoryNoneReason;
2191
+ /** The session whose live view health changed. */
2192
+ sessionId: string;
2193
+ }
2194
+
2195
+ /** Side provenance folded from the durable side provenance (`SideChatProvenance`, tdd SS2.4/SS2.5.7; ADR 45435 D2). */
2196
+ export interface SideProvenance {
2197
+ /** The `commandId` of the `session/sideChat` that created it. */
2198
+ commandId: string;
2199
+ /** An **opaque provenance string** preserved verbatim from the durable side provenance (`source_cut_cursor`). Display-only — not one of the cursor families: clients MUST NOT parse it and no method accepts it (tdd SS2.4). */
2200
+ cutCursor: string;
2201
+ /** The source main session this side was opened from. */
2202
+ sessionId: string;
2203
+ }
2204
+
2205
+ /** `skill/setActivation` activation target (tdd SS3.30.1). **Closed**: a client-selected write vocabulary (ADR 45433 D2) — a write must fail a scope the host does not implement rather than record activation against an unknown target. Contrast the open read-side [`SkillSource`]. */
2206
+ export type SkillActivationScope = "user" | "project" | "bundled" | "plugin";
2207
+
2208
+ /** The three-state skill activation (tdd SS3.30.1, ADR 10512 — no new state). **Closed**: a client-selected write vocabulary (ADR 45433 D2). */
2209
+ export type SkillActivationState = "on" | "userInvocableOnly" | "off";
2210
+
2211
+ /** One typed-invocable shortcut spelling (tdd SS3.22.1). A plugin skill may contribute two rows: its bare-name winner and its qualified `<pluginId>:<skillId>` form. */
2212
+ export interface SkillCatalogEntry {
2213
+ /** Present when the skill declares an argument hint. */
2214
+ argumentHint?: string;
2215
+ /** The skill's palette summary. */
2216
+ description: string;
2217
+ /** The skill display name the first-party palette shows. */
2218
+ displayName: string;
2219
+ /** The owning plugin's identifier; present when `source` is `plugin`. */
2220
+ pluginId?: string;
2221
+ /** The shortcut token without the leading slash — bare (`fix-bug`) or plugin-qualified (`acme:deploy`) — the exact value a `skill` input part submits. Unique within one response. */
2222
+ selector: string;
2223
+ /** Where the skill comes from. */
2224
+ source: SkillSource;
2225
+ }
2226
+
2227
+ /** `skill/changed` params (tdd SS3.22.2): the session's user-invocable set changed; clients re-issue `skill/list`. Advisory — the host may coalesce bursts and guarantees no ordering relative to view events (ADR 32471 D3). */
2228
+ export interface SkillChangedParams {
2229
+ /** The session whose set changed. */
2230
+ sessionId: string;
2231
+ }
2232
+
2233
+ /** The four receipt-list lengths (tdd SS3.30.2): a client renders counts without walking lists. */
2234
+ export interface SkillImportCounts {
2235
+ /** `failed.len()`. */
2236
+ failed: number;
2237
+ /** `installed.len()`. */
2238
+ installed: number;
2239
+ /** `quarantined.len()`. */
2240
+ quarantined: number;
2241
+ /** `skipped.len()`. */
2242
+ skipped: number;
2243
+ }
2244
+
2245
+ /** One import candidate that could neither install nor quarantine (tdd SS3.30.2): recorded so the run continues past it. `id` is null when the candidate never yielded one — present-but-null, never omitted. */
2246
+ export interface SkillImportFailure {
2247
+ /** The candidate's id, or null when it never yielded one. */
2248
+ id: string | null;
2249
+ /** Why the candidate failed. */
2250
+ reason: string;
2251
+ }
2252
+
2253
+ /** `skill/import` params (tdd SS3.30.2, #45433): import foreign skills through the single `SkillsService::import_skills` seam. */
2254
+ export interface SkillImportParams {
2255
+ /** The SS3.1.1 idempotency handle (UUIDv7) — required even for `dryRun` previews. */
2256
+ commandId: string;
2257
+ /** Preview for the consent UI; writes nothing. Additive-optional, default false. */
2258
+ dryRun?: boolean;
2259
+ /** Re-import over already-imported ids (the CLI `--force` twin). Additive-optional, default false. */
2260
+ force?: boolean;
2261
+ /** The target session. */
2262
+ sessionId: string;
2263
+ /** The foreign ecosystem to import from. */
2264
+ source: SkillImportSource;
2265
+ }
2266
+
2267
+ /** One quarantined import candidate (tdd SS3.30.2): kept, not loaded. */
2268
+ export interface SkillImportQuarantine {
2269
+ /** The candidate's id. */
2270
+ id: string;
2271
+ /** The quarantine reasons. */
2272
+ reasons: string[];
2273
+ }
2274
+
2275
+ /** `skill/import` result (tdd SS3.30.2, #45433): the ack envelope plus the service receipt projection. */
2276
+ export interface SkillImportResult {
2277
+ /** Echoes the client's id. */
2278
+ commandId: string;
2279
+ /** The four list lengths. */
2280
+ counts: SkillImportCounts;
2281
+ /** Echoes the call's preview flag. */
2282
+ dryRun: boolean;
2283
+ /** Candidates that could neither install nor quarantine. Import never aborts the whole run on one bad candidate. */
2284
+ failed: SkillImportFailure[];
2285
+ /** The ids the run installed, in pipeline order. */
2286
+ installed: string[];
2287
+ /** Kept, not loaded, with reasons. */
2288
+ quarantined: SkillImportQuarantine[];
2289
+ /** Ids the run did not install: already-imported ids and in-run duplicates, verbatim from the seam's `skipped` vec. */
2290
+ skipped: string[];
2291
+ /** Echoes the call's ecosystem. */
2292
+ source: SkillImportSource;
2293
+ /** Admission status. */
2294
+ status: CommandStatus;
2295
+ }
2296
+
2297
+ /** `skill/import` foreign ecosystem (tdd SS3.30.2). **Closed**: a client-selected write vocabulary (ADR 45433 D2) — a write must fail an ecosystem the host does not implement rather than import from an unknown dir. The host resolves its own foreign dir (the `foreign_skills_sources` derivation); no client paths cross the wire. */
2298
+ export type SkillImportSource = "claude" | "codex";
2299
+
2300
+ /** `skill/list` params (tdd SS3.22.1, SS3.30.3). Per-session because skill scope follows the session's workspace and plugin state. */
2301
+ export interface SkillListParams {
2302
+ /** The target session. */
2303
+ sessionId: string;
2304
+ }
2305
+
2306
+ /** `skill/list` result (tdd SS3.22.1): one row per typed-invocable shortcut spelling — exactly the invocations the first-party typed dispatch accepts (spec 11352 INV-007 predicate and the shared shortcut layer's name resolution, both by call-through; ADR 32471 D2). */
2307
+ export interface SkillListResult {
2308
+ /** The session's user-invocable skill rows. */
2309
+ skills: SkillCatalogEntry[];
2310
+ }
2311
+
2312
+ /** `skill/setActivation` params (tdd SS3.30.1, #45433): turn one skill on or off in any scope through the single `SkillsService::set_activation` seam. */
2313
+ export interface SkillSetActivationParams {
2314
+ /** The activation to apply. */
2315
+ activation: SkillActivationState;
2316
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
2317
+ commandId: string;
2318
+ /** The activation target. */
2319
+ scope: SkillActivationScope;
2320
+ /** Names one skill: a bare or plugin-qualified token from the session's full catalog (tdd SS3.30.3), the SS3.22.1 row vocabulary. */
2321
+ selector: string;
2322
+ /** The target session. */
2323
+ sessionId: string;
2324
+ }
2325
+
2326
+ /** `skill/setActivation` result (tdd SS3.30.1, #45433): the ack envelope plus the applied state. */
2327
+ export interface SkillSetActivationResult {
2328
+ /** The applied activation. */
2329
+ activation: SkillActivationState;
2330
+ /** Echoes the client's id. */
2331
+ commandId: string;
2332
+ /** The activation value in force for that `(selector, scope)` immediately before the write: the same value a full-catalog `skill/list` row would have carried in `activation` for it. */
2333
+ previous: SkillActivationState;
2334
+ /** Echoes the applied write's scope. */
2335
+ scope: SkillActivationScope;
2336
+ /** Echoes the applied write's selector. */
2337
+ selector: string;
2338
+ /** Admission status. */
2339
+ status: CommandStatus;
2340
+ }
2341
+
2342
+ /** A skill row's source scope (tdd SS3.22.1): the projection of the skills crate's `SkillsSourceScope`. Open (server-produced result vocabulary, the #22785 enum-openness rule): a future scope value is additive. */
2343
+ export type SkillSource = "bundled" | "user" | "project" | "plugin" | (string & {});
2344
+
2345
+ /** The compaction boundary an anchored snapshot is anchored at (tdd SS2.5.2). */
2346
+ export interface SnapshotAnchor {
2347
+ /** The view cursor of the boundary's `compaction` event. */
2348
+ boundaryCursor: string;
2349
+ /** The boundary's opaque compaction anchor (tdd SS4.5.10). */
2350
+ summarizedThrough: string;
2351
+ }
2352
+
2353
+ /** The complete folded view at the snapshot cursor (tdd SS4.9.1). Additive-optional evolution applies exactly as everywhere else; unknown members MUST be ignored, and preserved if re-serialized. **One served site does not satisfy this type today, escalated under #22785 (E8).** The genesis snapshot rung serves `state: {"items": [...]}` alone (`tbh-session-view-serve`'s `materialized_fold.rs`, the `select_genesis_history` call), while the anchored rung serves the full folded state. A schema-validating client resuming with `{"history": "snapshot"}` against the real fold therefore sees the other required members missing. The fix is a serving change in the #208/#14653 lane (serialize the `SessionViewState` the genesis path already folds, as the anchored path does) plus its own RED against the real fold; it is not a shape change here, because SS4.9.1 ratifies this shape. */
2354
+ export interface SnapshotState {
2355
+ /** The running foreground turn; `null` when none is running. */
2356
+ activeTurn: TurnRef | null;
2357
+ /** The effective approval mode at this cursor — the same object the `Session` carries (tdd SS2.4, SS5.12). */
2358
+ approvalMode: EffectiveApprovalModeState;
2359
+ /** Latest branch observation; `null` when no fact has landed. */
2360
+ branch: BranchState | null;
2361
+ /** The latest `(windowTokens, usedTokens, pressure)` triple. SS4.9.1 says "`null`/absent" and SS4.9.2's worked example OMITS the member; the binary omits it too, so this is the absent arm — the four siblings above are present-null in the same frame. INV-017 admits one or the other, never both; escalated under #22785. */
2362
+ contextUsage?: ContextUsage;
2363
+ /** Latest effective model; `null` when no fact has landed. */
2364
+ effectiveModel: EffectiveModel | null;
2365
+ /** Latest goal block; `null` when no fact has landed. */
2366
+ goal: Goal | null;
2367
+ /** Every item, in first-opened order, each at its latest revision at the snapshot cursor. One schema per kind, shared with the notification item object — which is what makes snapshot+suffix a pure splice (tdd SS4.9.1). */
2368
+ items: Item[];
2369
+ /** The settled canonical session name; `null` when the session was never named (#27598, tdd SS4.9.1 / SS2.14). Folds the same durable `session/nameChanged` record `Session.name` reports. */
2370
+ name?: string | null;
2371
+ /** The pending-approval half of the pending set. */
2372
+ pendingApprovals: PendingApprovalPointer[];
2373
+ /** The pending-user-input half of the pending set. */
2374
+ pendingUserInputs: PendingUserInputPointer[];
2375
+ /** Admitted-but-not-launched submits, in launch order (tdd SS3.1.4). */
2376
+ queuedTurns: TurnRef[];
2377
+ /** The latest session-default reasoning effort with its source; ABSENT until a set lands (tdd SS4.9.1 `reasoningEffort`, ADR 31255 D1 — the `contextUsage` absent arm, never present-null). */
2378
+ reasoningEffort?: ReasoningEffortState;
2379
+ /** Latest todo list; `null` when no fact has landed. */
2380
+ todoList: TodoListState | null;
2381
+ /** The `cumulative` block of the last `session/tokenUsage` event; zeroes when none (tdd SS4.9.1). */
2382
+ tokenUsage: CumulativeTokenUsage;
2383
+ /** Completed-turn count at this cursor. */
2384
+ turnCount: number;
2385
+ }
2386
+
2387
+ /** The inclusive raw-record range a durable-sourced view event folded from (tdd SS4.2) — the reconciliation token: re-folding the cited records from the canonical fold state immediately before `first` — appended host-death terminals seed from the end-of-records state — reproduces the event (tdd SS7.5; spec 14653 T041/INV-009). In v1 it is an **opaque provenance token**: no wire method reads what it points at (the SS6 raw-log altitude is deferred, #13929). Ephemeral-sourced events (`item/delta`, and an `item/started` that opens on an ephemeral record) carry no `sourceRange` — ephemeral records may be evicted by retention (tdd SS4.2; spec 14653 INV-009). */
2388
+ export interface SourceRange {
2389
+ /** The first record of the inclusive range. */
2390
+ first: RecordPosition;
2391
+ /** The last record of the inclusive range; equal to `first` for an event folded from one record. */
2392
+ last: RecordPosition;
2393
+ /** The stream the folded records live on (run stream, or the session stream's mirror of task/approval/subagent-control records — whichever the fold actually consumed, tdd SS4.2). */
2394
+ stream: StreamRef;
2395
+ }
2396
+
2397
+ /** `toolCall.statusAttempt` (tdd SS4.5.5, #45448): the latest `TaskExternalAttemptDetail`, field-for-field — countdown inputs the client renders the tick from, so no event spam. */
2398
+ export interface StatusAttempt {
2399
+ /** The attempt number. */
2400
+ attempt: number;
2401
+ /** The error kind (durable vocabulary, verbatim), when recorded. */
2402
+ errorKind?: string;
2403
+ /** The HTTP status, when recorded. */
2404
+ httpStatus?: number;
2405
+ /** The maximum attempts, when known. */
2406
+ maxAttempts?: number;
2407
+ /** The scheduled next attempt, when known. */
2408
+ nextAttempt?: number;
2409
+ /** The operation (durable vocabulary, verbatim). */
2410
+ operation: string;
2411
+ /** The retry delay in ms, when known. */
2412
+ retryDelayMs?: number;
2413
+ /** The external system (durable vocabulary, verbatim). */
2414
+ system: string;
2415
+ }
2416
+
2417
+ /** `toolCall.statusChildren` (tdd SS4.5.5, #45448): the latest `TaskChildSummaryDetail`, field-for-field. */
2418
+ export interface StatusChildren {
2419
+ /** Active children. */
2420
+ active: number;
2421
+ /** Cancelled children. */
2422
+ cancelled: number;
2423
+ /** Completed children. */
2424
+ completed: number;
2425
+ /** Failed children. */
2426
+ failed: number;
2427
+ /** Total children, when known. */
2428
+ total?: number;
2429
+ }
2430
+
2431
+ /** `toolCall.statusHealth` (tdd SS4.5.5, #45448): the latest `TaskHealthDetail`, field-for-field. */
2432
+ export interface StatusHealth {
2433
+ /** The health level (the durable `TaskHealthLevel` vocabulary verbatim). */
2434
+ level: StatusHealthLevel;
2435
+ /** The reason, when recorded. */
2436
+ reason?: string;
2437
+ }
2438
+
2439
+ /** `toolCall.statusHealth.level` (tdd SS4.5.5, #45448): the durable `TaskHealthLevel` vocabulary verbatim. Open — runtime vocabulary may grow additively, and clients MUST render unknown levels generically. */
2440
+ export type StatusHealthLevel = "ok" | "waiting" | "degraded" | "retrying" | "blocked" | "failed" | (string & {});
2441
+
2442
+ /** `toolCall.statusProgress` (tdd SS4.5.5, #45448): the latest `TaskProgressDetail`, field-for-field. */
2443
+ export interface StatusProgress {
2444
+ /** Completed units. */
2445
+ current: number;
2446
+ /** Total units, when known. */
2447
+ total?: number;
2448
+ /** Unit label, when recorded. */
2449
+ unit?: string;
2450
+ }
2451
+
2452
+ /** `toolCall.statusStep` (tdd SS4.5.5, #45448): the latest `TaskActiveStepDetail`, field-for-field. */
2453
+ export interface StatusStep {
2454
+ /** The step index, when known. */
2455
+ index?: number;
2456
+ /** The active step's label. */
2457
+ label: string;
2458
+ /** The step count, when known. */
2459
+ total?: number;
2460
+ }
2461
+
2462
+ /** One raw stream named by a [`SourceRange`] (tdd SS4.2). */
2463
+ export interface StreamRef {
2464
+ /** The stream id. */
2465
+ id: string;
2466
+ /** The stream kind, verbatim raw-log vocabulary (e.g. `"run"`, `"session"`). A free string, not an enum: `sourceRange` is an opaque provenance token in v1 and the raw stream vocabulary is the deferred SS6 altitude's to freeze (#13929). */
2467
+ kind: string;
2468
+ }
2469
+
2470
+ /** Subagent control status (tdd SS4.5.7, camelCased `SubagentControlStatus`). Open; the generic item `status` is the terminal authority. */
2471
+ export type SubagentControlStatus = "accepted" | "starting" | "running" | "resultReady" | "closing" | "closed" | "recoveryPending" | "manualReconciliation" | (string & {});
2472
+
2473
+ /** Params for `subagent/sendMessage` and `subagent/followupTask` (SS3.16): a child target plus the input body. */
2474
+ export interface SubagentInputParams {
2475
+ /** The note/task text: trimmed with Unicode-whitespace semantics, rejected when empty after trimming, delivered trimmed with multibyte content byte-for-byte intact (SS3.16). */
2476
+ body: string;
2477
+ /** Client-minted UUIDv7 command id (SS3.1.1). */
2478
+ commandId: string;
2479
+ /** Target session (UUIDv7 string; SS3 preamble). */
2480
+ sessionId: string;
2481
+ /** Durable child id (the SS4.5.7 item's `subagentId`; opaque string). */
2482
+ subagentId: string;
2483
+ }
2484
+
2485
+ /** Params for `subagent/interrupt`, `subagent/stop`, and `subagent/close` (SS3.16): a child target plus an optional human-readable reason that is preserved on the durable effect record. */
2486
+ export interface SubagentOwnerReasonParams {
2487
+ /** Client-minted UUIDv7 command id (SS3.1.1). */
2488
+ commandId: string;
2489
+ /** Optional reason, preserved on the durable owner-command record. */
2490
+ reason?: string;
2491
+ /** Target session (UUIDv7 string; SS3 preamble). */
2492
+ sessionId: string;
2493
+ /** Durable child id (the SS4.5.7 item's `subagentId`; opaque string). */
2494
+ subagentId: string;
2495
+ }
2496
+
2497
+ /** A subagent's result envelope (tdd SS4.5.7, `SubagentResultEnvelope`). */
2498
+ export interface SubagentResult {
2499
+ /** Artifact references, verbatim. */
2500
+ artifactRefs: string[];
2501
+ /** Error kind, verbatim durable vocabulary, when the child failed. */
2502
+ errorKind?: string;
2503
+ /** Evidence references, verbatim. */
2504
+ evidenceRefs: string[];
2505
+ /** Structured result data, verbatim, when present. */
2506
+ structuredData?: Record<string, unknown>;
2507
+ /** Result summary, bounded on the wire at the 64 KiB retained-text budget (tdd SS4.5.4 and SS4.5.7, ADR 35691 D9); a cut sets the item's `truncated`. The durable record stays verbatim. */
2508
+ summary: string;
2509
+ /** Result text, when present, bounded on the wire at the same 64 KiB budget (ADR 35691 D9); a cut sets the item's `truncated`. */
2510
+ text?: string;
2511
+ }
2512
+
2513
+ /** Params for `subagent/resume`, `subagent/reopen`, and `subagent/readResult` (SS3.16): the bare child target. */
2514
+ export interface SubagentTargetParams {
2515
+ /** Client-minted UUIDv7 command id (SS3.1.1). */
2516
+ commandId: string;
2517
+ /** Target session (UUIDv7 string; SS3 preamble). */
2518
+ sessionId: string;
2519
+ /** Durable child id (the SS4.5.7 item's `subagentId`; opaque string). */
2520
+ subagentId: string;
2521
+ }
2522
+
2523
+ /** The one usage payload shape: the `usage/read` result's `usage` member and the `usage/changed` params (ADR 32563 D2/D3). The numbers are point-in-time — `observedAtMs` is the host's arrival stamp, so a client renders "as of", never implies live data (spec 18742 US-FR-004). */
2524
+ export interface SubscriptionUsage {
2525
+ /** When the host RECEIVED this observation (frame arrival or mint request-send), epoch milliseconds. */
2526
+ observedAtMs: number;
2527
+ /** The provider's subscription tier id, verbatim. */
2528
+ tier: string;
2529
+ /** The rolling weekly block. */
2530
+ weekly: SubscriptionUsageWeekly;
2531
+ /** The current window. */
2532
+ window: SubscriptionUsageWindow;
2533
+ }
2534
+
2535
+ /** The rolling weekly block: same semantics as [`SubscriptionUsageWindow`] without a duration (ADR 32563 D2). */
2536
+ export interface SubscriptionUsageWeekly {
2537
+ /** When the weekly window resets, epoch milliseconds. */
2538
+ resetsAtMs: number;
2539
+ /** Percent of the weekly budget used (integer ≥ 0, may exceed 100). */
2540
+ usedPercent: number;
2541
+ }
2542
+
2543
+ /** The current usage window (the provider's 5-hour-class block): verbatim provider percentages with the reset stamp normalized to epoch milliseconds (ADR 32563 D2). */
2544
+ export interface SubscriptionUsageWindow {
2545
+ /** When the window resets, epoch milliseconds. */
2546
+ resetsAtMs: number;
2547
+ /** Percent of the window's budget used: an integer ≥ 0, verbatim from the provider — over-quota values above 100 are valid. */
2548
+ usedPercent: number;
2549
+ /** The window's length in minutes (> 0). */
2550
+ windowDurationMins: number;
2551
+ }
2552
+
2553
+ /** A success response frame (SS1.2 §2.3). */
2554
+ export interface SuccessResponse {
2555
+ /** Echo of the request id. */
2556
+ id: RequestId;
2557
+ /** The literal `"2.0"`. */
2558
+ jsonrpc: JsonRpcVersion;
2559
+ /** Always a JSON object, possibly `{}`, never a bare scalar — so every result can grow additive-optional members (SS1.2). */
2560
+ result: Record<string, unknown>;
2561
+ }
2562
+
2563
+ /** `task/background` params (tdd §3.13): durably send a running foreground tool task to the background. */
2564
+ export interface TaskBackgroundParams {
2565
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
2566
+ commandId: string;
2567
+ /** The target session. */
2568
+ sessionId: string;
2569
+ /** The task to background, exactly as the view names it: the `toolCall` item's `itemId` IS the task id (SS4.5.5). */
2570
+ taskId: string;
2571
+ }
2572
+
2573
+ /** The `task/background` / `task/stop` ack (tdd §3.13/§3.14): admission-only, echoing the targeted task. */
2574
+ export interface TaskCommandResult {
2575
+ /** Echoes the client's id. */
2576
+ commandId: string;
2577
+ /** Admission status. */
2578
+ status: CommandStatus;
2579
+ /** Echoes the targeted task id. */
2580
+ taskId: string;
2581
+ }
2582
+
2583
+ /** One background-task inventory row (tdd SS3.31). The row is the stable contract: `kind` and `status` stay open so a future state extends them without breaking clients. */
2584
+ export interface TaskListEntry {
2585
+ /** Who backgrounded the task, mirroring the item field. **Additive-optional**: absent on pre-split records and registry-only rows, never inferred. */
2586
+ backgroundInitiator?: BackgroundInitiator;
2587
+ /** What the workload is: `"tool"` or `"tool.*"` for item rows (the recorded kind when the registry records one, else `"tool"`); the recorded registry kind string verbatim for registry-only rows. Open vocabulary — clients MUST ignore unknown kinds. A `String`, not an enum: registry kind strings are unbounded. */
2588
+ kind: string;
2589
+ /** The host-known task start, RFC3339. **Additive-optional**: omitted, never guessed, when the host does not know it. */
2590
+ startedAt?: string;
2591
+ /** `"inProgress"` — the only value at this increment, since every listed row is non-terminal by construction. */
2592
+ status: TaskListStatus;
2593
+ /** The `toolCall` item's `itemId` for item rows; the runtime registry id for registry-only rows. */
2594
+ taskId: string;
2595
+ /** The short tool name on item-visible tool rows only; never a label, never arguments. **Additive-optional**: absent elsewhere. */
2596
+ tool?: string;
2597
+ }
2598
+
2599
+ /** `task/list` params (tdd SS3.31): the session whose background-task inventory to read. A read-only query in the `skill/list` mold: no `commandId`, no durable record, no view event. */
2600
+ export interface TaskListParams {
2601
+ /** The target session. */
2602
+ sessionId: string;
2603
+ }
2604
+
2605
+ /** `task/list` result (tdd SS3.31): one row per running background workload in `task/stopAll` reach, oldest first; empty when nothing is running. */
2606
+ export interface TaskListResult {
2607
+ /** The session's live background-task rows. */
2608
+ tasks: TaskListEntry[];
2609
+ }
2610
+
2611
+ /** A task row's status (tdd SS3.31). Open (server-produced result vocabulary, the #22785 enum-openness rule): a future state is additive, and clients MUST ignore unknown statuses. */
2612
+ export type TaskListStatus = "inProgress" | (string & {});
2613
+
2614
+ /** `task/stopAll` params (tdd §3.15): stop every stoppable background workload live at admission. */
2615
+ export interface TaskStopAllParams {
2616
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
2617
+ commandId: string;
2618
+ /** The target session. */
2619
+ sessionId: string;
2620
+ }
2621
+
2622
+ /** The `task/stopAll` ack (tdd §3.15): always `accepted`, including over an empty set — a blanket stop over nothing is a satisfied gesture. The ack deliberately carries no stopped-task list; count the kills from the view. */
2623
+ export interface TaskStopAllResult {
2624
+ /** Echoes the client's id. */
2625
+ commandId: string;
2626
+ /** Admission status. */
2627
+ status: CommandStatus;
2628
+ }
2629
+
2630
+ /** `task/stop` params (tdd §3.14): stop one named background task. Required target, never "whichever is loudest" — §3.15 is the blanket verb. */
2631
+ export interface TaskStopParams {
2632
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
2633
+ commandId: string;
2634
+ /** The target session. */
2635
+ sessionId: string;
2636
+ /** The task to stop, the `toolCall` item's `itemId` (SS4.5.5). */
2637
+ taskId: string;
2638
+ }
2639
+
2640
+ /** One todo entry (tdd SS4.6.3). */
2641
+ export interface TodoItem {
2642
+ /** Present-tense active form, when the tool supplied one. */
2643
+ activeForm?: string;
2644
+ /** The todo status (camelCased runtime `TodoStatus`). */
2645
+ status: TodoStatus;
2646
+ /** The todo text. */
2647
+ text: string;
2648
+ }
2649
+
2650
+ /** The latest todo-list fact in the snapshot (tdd SS4.6.3, SS4.9.1). */
2651
+ export interface TodoListState {
2652
+ /** The full todo list. */
2653
+ items: TodoItem[];
2654
+ /** The snapshot revision. Diagnostics only, never an ordering guard. */
2655
+ revision: number;
2656
+ /** The tool that produced the snapshot, verbatim. */
2657
+ sourceTool: string;
2658
+ }
2659
+
2660
+ /** Todo status (tdd SS4.6.3): closed in the runtime, wire-open. */
2661
+ export type TodoStatus = "pending" | "inProgress" | "completed" | "cancelled" | (string & {});
2662
+
2663
+ /** Raw token counters, verbatim from the durable record (tdd SS4.6.5, the runtime's `Usage`, camelCased). Not directly summable across providers — sum the counted-once derivations instead (#8803). */
2664
+ export interface TokenUsage {
2665
+ /** Cache read tokens, only when the provider distinguishes writes/reads. */
2666
+ cacheReadTokens?: number;
2667
+ /** Cache write tokens, only when the provider distinguishes writes/reads. */
2668
+ cacheWriteTokens?: number;
2669
+ /** Provider-reported cache tokens (inside or beside `inputTokens`, provider-convention-dependent — the reason `promptTokens` exists). */
2670
+ cachedTokens: number;
2671
+ /** Provider-reported input tokens. */
2672
+ inputTokens: number;
2673
+ /** Provider-reported output tokens. */
2674
+ outputTokens: number;
2675
+ /** Output tokens spent on reasoning, when the provider reports it. */
2676
+ reasoningTokens: number;
2677
+ }
2678
+
2679
+ export type ToolReceipt = { details?: CronReceipt; family: "cron"; operation: ToolReceiptOperation; outcome: ToolReceiptOutcome; } | { details?: CodeModeReceipt; family: "codeMode"; operation: ToolReceiptOperation; outcome: ToolReceiptOutcome; } | { details?: Record<string, unknown>; family: string; operation: string; outcome: string; };
2680
+
2681
+ /** Which operation within the family the receipt describes (ADR 43399 D1/D2). Open — registered per family, never derived from the tool name. */
2682
+ export type ToolReceiptOperation = "create" | "delete" | "list" | "execute" | "wait" | (string & {});
2683
+
2684
+ /** What the operation did (ADR 43399 D1/D2). Open, and a **single shared vocabulary**: a value appearing in two families means the same thing in both, which is why the permitted `status` values are bound to the value here rather than per family. */
2685
+ export type ToolReceiptOutcome = "created" | "duplicate" | "deleted" | "missing" | "listed" | "rejected" | "completed" | "pending" | "failed" | "timedOut" | "cancelled" | (string & {});
2686
+
2687
+ /** Optional W3C trace context, on requests in both directions only — never on responses or notifications (SS1.8). */
2688
+ export interface TraceContext {
2689
+ /** W3C `traceparent` string; receivers that do not trace ignore it. */
2690
+ traceparent?: string;
2691
+ /** W3C `tracestate` string. */
2692
+ tracestate?: string;
2693
+ }
2694
+
2695
+ /** `turn/cancel` params (tdd SS3.5): plain cancellation on the normal command lane. Same shape as `turn/interrupt`, **without** `retract` — pairing a retract with a plain cancel is durably rejected `not_paired_interrupt`. */
2696
+ export interface TurnCancelParams {
2697
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
2698
+ commandId: string;
2699
+ /** The target session. */
2700
+ sessionId: string;
2701
+ /** The exact turn to cancel; omit to target the current foreground turn. Any syntactically valid UUID: a turn from an older session may carry a v4 or v5 id. A malformed id is `invalidParams`. */
2702
+ turnId?: string;
2703
+ }
2704
+
2705
+ /** `turn/cancel` result (tdd SS3.5): identical envelope to `turn/interrupt`. */
2706
+ export interface TurnCancelResult {
2707
+ /** Echoes the client's id. */
2708
+ commandId: string;
2709
+ /** Admission status. */
2710
+ status: CommandStatus;
2711
+ /** The cancelled turn. */
2712
+ turnId: string;
2713
+ }
2714
+
2715
+ /** `turn/completed` params (tdd SS4.5.1): the run's durable terminal record landed. */
2716
+ export interface TurnCompletedParams {
2717
+ /** Turn duration; absent means unmeasured, never fabricated. */
2718
+ durationMs?: number;
2719
+ /** Present when `terminal` is `"failed"`, except on a synthesized host-death terminal, which carries `reason` instead (tdd SS4.5.1, ADR 36635 D2): mid-turn failures reach the client here — never as a JSON-RPC error. */
2720
+ error?: TurnError;
2721
+ /** The runtime's free-text terminal reason, verbatim. Display and diagnostics only; never branch on it. */
2722
+ reason?: string;
2723
+ /** The owning session. */
2724
+ sessionId: string;
2725
+ /** The durable records this event folded from. */
2726
+ sourceRange: SourceRange;
2727
+ /** The turn terminal (open enum). */
2728
+ terminal: TurnTerminal;
2729
+ /** Time to first token, when measured. */
2730
+ timeToFirstTokenMs?: number;
2731
+ /** The terminated turn. */
2732
+ turnId: string;
2733
+ /** The turn's aggregate token usage, summed across the turn's model completions (same shape as `session/tokenUsage.usage`). */
2734
+ usage?: TokenUsage;
2735
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
2736
+ viewCursor: string;
2737
+ }
2738
+
2739
+ /** The settled turn-failure object (tdd SS4.5.1): `{kind, message, retryable}`. */
2740
+ export interface TurnError {
2741
+ /** The failure class (open camelCase enum grounded in the runtime's terminal failure classification). */
2742
+ kind: TurnErrorKind;
2743
+ /** Human-readable failure text. */
2744
+ message: string;
2745
+ /** Typed quota-exhaustion detail (ADR 50047 D2/D3): present iff the stopping failure was the quota class. Clients branch on presence, never by parsing `message`. */
2746
+ quota?: QuotaDetail;
2747
+ /** The server's judgment that resubmitting the same input may succeed. */
2748
+ retryable: boolean;
2749
+ }
2750
+
2751
+ /** Turn failure classes (tdd SS4.5.1, `TerminalErrorKind` plus the model-task failure class). Open. */
2752
+ export type TurnErrorKind = "stepLimit" | "configError" | "projectionError" | "logError" | "workflowLaunchError" | "environmentError" | "modelError" | "launchError" | "authRequired" | "mcpLinkError" | (string & {});
2753
+
2754
+ /** `turn/foregroundCompleted` params (tdd SS4.5.12): the turn's foreground work is done and named background reminder checks hold the turn open. Explicitly non-terminal: the turn ends only at `turn/completed` / `turn/unqueued`. */
2755
+ export interface TurnForegroundCompletedParams {
2756
+ /** `reminderAgentId`s of the firing's blocking set, never empty; agent ids, never display names. Live-best-effort: reads, resume, and replay may narrow it to the linked subset. */
2757
+ blockingAgents: string[];
2758
+ /** The owning session. */
2759
+ sessionId: string;
2760
+ /** The durable records this event folded from, anchored at the first blocking link of the firing window. */
2761
+ sourceRange: SourceRange;
2762
+ /** The turn whose foreground completed. */
2763
+ turnId: string;
2764
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
2765
+ viewCursor: string;
2766
+ }
2767
+
2768
+ /** One ordered content part of a turn submission (tdd SS3.2). File mentions are text, not a part type: write `@relative/path` in a text part. A structured `mention` part is reserved and currently rejected, and an unknown part type is `invalidParams` (tdd SS3.1.2, SS3.2) — which is what closes [`TurnInputPartType`]. Modelled as a discriminated flat object rather than a Rust `enum`, the convention [`crate::view::approval::ApprovalSubject`] already established for a wire union in this crate: the v1 schema model names no object-variant union shape and fails closed on one. The serialized JSON is the tdd shape either way; what a flat object cannot express is "`mediaType` is required exactly when `type` is `image`". **RULED (#22785 E4, owner, 2026-08-26): the precedent is accepted.** A strict union node kind may be funded later as a follow-up; if it is, it must cover [`crate::method::lifecycle::PendingRequestPointer`] too. `height` may only appear together with `width`. `width` may only appear together with `height`. */
2769
+ export interface TurnInputPart {
2770
+ /** Free-text skill arguments, optional on a `skill` part — the wire twin of what the TUI accepts after the shortcut token (tdd SS3.22.3). */
2771
+ arguments?: string;
2772
+ /** Base64 payload, required on an `image` part. Invalid base64 or an empty payload is rejected with invalid params. */
2773
+ base64Data?: string;
2774
+ /** Pixel height; must be provided together with `width` or not at all (tdd SS3.2, #22785 E6c). */
2775
+ height?: number;
2776
+ /** Media type, required on an `image` part. */
2777
+ mediaType?: string;
2778
+ /** The skill to invoke, required on a `skill` part (tdd SS3.2, SS3.22.3; ADR 32471 D4): a bare or plugin-qualified shortcut token from `skill/list`. The HOST resolves and expands; an unknown selector is the typed `-32032 skillNotFound` request error. */
2779
+ selector?: string;
2780
+ /** User prompt text, on a `text` part. Multiple text parts are joined in order into the turn's prompt. */
2781
+ text?: string;
2782
+ /** The part type. */
2783
+ type: TurnInputPartType;
2784
+ /** The upload receipt, required on a `video` part (tdd SS3.2, SS3.33; ADR 45443 D5): the client-minted id `media/upload` echoed. */
2785
+ uploadId?: string;
2786
+ /** Pixel width; must be provided together with `height` or not at all (tdd SS3.2). Published as a `dependentRequired` pair under #22785 E6c. */
2787
+ width?: number;
2788
+ }
2789
+
2790
+ /** The `type` discriminator of a turn input part (tdd SS3.2). Closed: an unknown part type is `invalidParams` (tdd SS3.1.2). */
2791
+ export type TurnInputPartType = "text" | "image" | "skill" | "video";
2792
+
2793
+ /** `turn/interrupt` params (tdd SS3.4): the "user pressed stop" gesture, on the runtime's priority lane. */
2794
+ export interface TurnInterruptParams {
2795
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
2796
+ commandId: string;
2797
+ /** Pair a retract intent with the interrupt: if the turn is cancelled before any assistant output committed, the submission is durably retracted (view event `turn/retracted`) so the client may restore the prompt text. A rejected retract does not undo the interrupt. Default `false` (tdd SS3.4). */
2798
+ retract?: boolean;
2799
+ /** The target session. */
2800
+ sessionId: string;
2801
+ /** The exact turn to interrupt. Omit to target the session's current foreground turn, resolved at admission; prefer passing the explicit id when you have one (tdd SS3.4). Any syntactically valid UUID: a turn from an older session may carry a v4 or v5 id. A malformed id is `invalidParams`. */
2802
+ turnId?: string;
2803
+ }
2804
+
2805
+ /** `turn/interrupt` result (tdd SS3.4). Acceptance means the interrupt was admitted, **not** that the turn is already stopped: the turn is over when you fold its `turn/completed` with terminal `cancelled`. */
2806
+ export interface TurnInterruptResult {
2807
+ /** Echoes the client's id. */
2808
+ commandId: string;
2809
+ /** Admission status. */
2810
+ status: CommandStatus;
2811
+ /** The interrupted turn. */
2812
+ turnId: string;
2813
+ }
2814
+
2815
+ /** A turn named by the snapshot's active/queued lists (tdd SS4.9.1). */
2816
+ export interface TurnRef {
2817
+ /** The `commandId` of the submit that minted it. */
2818
+ commandId: string;
2819
+ /** `queuedTurns[]` only (#45455; ADR 45443 D7): the queued submit's presentation text, so a late joiner can render it without waiting for launch. A current host sets it on every entry it admits; absent means an older host (or a pre-feature restored entry). Never set on `activeTurn`: the running turn's text is its `userMessage` item. */
2820
+ displayText?: string;
2821
+ /** `queuedTurns[]` only: set when `displayText` was cut to the committed-surface budget, mirroring `userMessage.truncated` (tdd SS4.5.2). Absent unless `true`. */
2822
+ truncated?: boolean;
2823
+ /** The turn's id, pre-minted per tdd SS3.1.4. */
2824
+ turnId: string;
2825
+ }
2826
+
2827
+ /** `turn/retracted` params (tdd SS4.5.1): an interrupt-paired retract durably settled, accepted or declined (ADR 50074 D1). On `"accepted"` the retracted user-message item is re-emitted via `item/updated` with `retracted: true`; on `"declined"` the client folds the legacy declined rollback instead and no item is re-emitted. */
2828
+ export interface TurnRetractedParams {
2829
+ /** The retracted submission's command id. */
2830
+ commandId: string;
2831
+ /** The retract settlement outcome (tdd SS4.5.1, ADR 50074 D1). Additive-optional: absent reads as `"accepted"` — pre-feature hosts emit the event only for accepted retracts — and so does an unrecognized value (open enum, D-033). */
2832
+ outcome?: RetractOutcome;
2833
+ /** The owning session. */
2834
+ sessionId: string;
2835
+ /** The durable records this event folded from. */
2836
+ sourceRange: SourceRange;
2837
+ /** The turn whose submission was retracted. */
2838
+ turnId: string;
2839
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
2840
+ viewCursor: string;
2841
+ }
2842
+
2843
+ /** `turn/retryScheduled` params (tdd SS4.5.1, spec 14412; D-026): a durable turn retry-scheduled fact folded — the failing model attempt's scheduled retry is observable BEFORE the turn terminates, so a streaming client can render "attempt N/M · retrying in Ss · reason" instead of dead air. Non-terminal: it never resolves a turn-wait (tdd SS3.1.4). The delay is the recorded scheduled backoff, never an absolute fire time — clients derive any countdown locally. `sourceRange` cites the session stream's mirror of the task-lifecycle record (tdd SS4.2). */
2844
+ export interface TurnRetryScheduledParams {
2845
+ /** The attempt that failed (producer-normalized, >= 1). */
2846
+ attempt: number;
2847
+ /** The failing model attempt's durable kind, verbatim (ADR 50047 D2/D3) — a plain string: the durable vocabulary is open-ended. */
2848
+ errorKind?: string;
2849
+ /** The failing model attempt's HTTP status (ADR 50047 D2/D3). */
2850
+ httpStatus?: number;
2851
+ /** The turn's model-retry chain bound. */
2852
+ maxAttempts: number;
2853
+ /** The attempt about to run (producer contract: attempt < nextAttempt <= maxAttempts; not a schema constraint). */
2854
+ nextAttempt: number;
2855
+ /** The recorded stopping reason through the shared task-detail normalization (non-empty; capped at 160 characters). */
2856
+ reason: string;
2857
+ /** The scheduled backoff delay in milliseconds, verbatim from the durable fact. */
2858
+ retryDelayMs: number;
2859
+ /** The owning session. */
2860
+ sessionId: string;
2861
+ /** The durable record this event folded from (the session stream's mirror of the retry-scheduled task status; `first == last`). */
2862
+ sourceRange: SourceRange;
2863
+ /** The failing model attempt's provider system, verbatim (ADR 50047 D2/D3) — e.g. `"meta"`. Absent when no model-attempt facet precedes the retry status on the task (old logs). */
2864
+ system?: string;
2865
+ /** The running turn whose model attempt is being retried. */
2866
+ turnId: string;
2867
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
2868
+ viewCursor: string;
2869
+ }
2870
+
2871
+ /** What `turn/start` did with the input (tdd SS3.2). Resolves OQ-H in v1: since `queue` is the default `ifBusy`, clients need to distinguish these without folding history. */
2872
+ export type TurnStartDisposition = "started" | "queued" | "steered" | (string & {});
2873
+
2874
+ /** `turn/start` params (tdd SS3.2). `turn/start.providerRequestOptions` is deliberately absent: **RULED (#22785 E3, owner, 2026-08-26) to stay off the published schema.** The schema is the contract, and a free-form-object node kind is revisited only if the experimental field graduates. */
2875
+ export interface TurnStartParams {
2876
+ /** The SS3.1.1 idempotency handle (UUIDv7). The fresh turn's `turnId` derives from it (tdd SS3.1.4). */
2877
+ commandId: string;
2878
+ /** Presentation form of the prompt for transcripts. Durable; carried on the resulting user-message view item. Never model-visible (tdd SS3.2). */
2879
+ displayText?: string;
2880
+ /** Disposition when a turn is already running; default `queue`. */
2881
+ ifBusy?: IfBusy;
2882
+ /** Ordered content parts; required and non-empty. */
2883
+ input: TurnInputPart[];
2884
+ /** Reasoning tier sampled at submission for this turn. */
2885
+ reasoningEffort?: ReasoningEffort;
2886
+ /** The target session. */
2887
+ sessionId: string;
2888
+ /** A queued `!` shell action riding this turn (tdd SS3.2, ADR 50034): the `!cmd` typed while a turn runs, executed at the next model-call boundary before any later steer. Exclusive with `text` and `skill` input; `input` may be empty only when this member is present. Capability-gated on `userShell`: a carrying turn on a connection without the grant fails `-32010 capabilityRequired`. Explicit `null` is invalid params (the null-tolerant set is closed). A v1 stable member. */
2889
+ userShell?: TurnUserShell;
2890
+ /** A sticky REPLACEMENT of the session's runtime workspace-root set, binding at this turn's launch and persisting for subsequent turns until replaced again — unlike `reasoningEffort`, which is this-turn-only. Same shape and validation as `session/start.workspaceRoots`; invalid params on an explicit `ifBusy: "steer"` submit and so is explicit `null` (the D-049 null-tolerant set is closed); omitted means "unchanged", never "reset" (tdd SS3.2, ADR 37313 D3, #37313). */
2891
+ workspaceRoots?: string[];
2892
+ }
2893
+
2894
+ /** `turn/start` result (tdd SS3.2). */
2895
+ export interface TurnStartResult {
2896
+ /** Echoes the client's id. */
2897
+ commandId: string;
2898
+ /** What happened to the input. */
2899
+ disposition: TurnStartDisposition;
2900
+ /** `true` iff `disposition` is `started`; retained as the boolean shorthand — `disposition` is authoritative (tdd SS3.2). */
2901
+ startedNewTurn: boolean;
2902
+ /** Admission status. */
2903
+ status: CommandStatus;
2904
+ /** The turn that will carry (or absorbed) this input. Authoritative: always take it from the ack rather than deriving it (tdd SS3.2). */
2905
+ turnId: string;
2906
+ }
2907
+
2908
+ /** `turn/started` params (tdd SS4.5.1): a foreground turn began running — fresh submits immediately, queued submits at their launch boundary, never steered submits. */
2909
+ export interface TurnStartedParams {
2910
+ /** The submitting command; `turnId == commandId` for fresh turns (tdd SS3.1.4). */
2911
+ commandId: string;
2912
+ /** The owning session. */
2913
+ sessionId: string;
2914
+ /** The durable records this event folded from. */
2915
+ sourceRange: SourceRange;
2916
+ /** The started turn. */
2917
+ turnId: string;
2918
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
2919
+ viewCursor: string;
2920
+ }
2921
+
2922
+ /** `turn/steer` params (tdd SS3.3): exact-target steering into the currently running turn. */
2923
+ export interface TurnSteerParams {
2924
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
2925
+ commandId: string;
2926
+ /** The turn you believe is running. Closes the race where the turn completes or is replaced between your read and your steer: input meant for turn A can never leak into turn B (tdd SS3.3). Any syntactically valid UUID: a turn from an older session may carry a v4 or v5 id. A malformed id is `invalidParams`; an id that is not the running turn is refused. */
2927
+ expectedTurnId: string;
2928
+ /** Same content parts as `turn/start`. */
2929
+ input: TurnInputPart[];
2930
+ /** Reasoning tier for the model calls this steer's input reaches. Applies forward, never backward; absent means unspecified, not "reset" (tdd SS3.3, D-024). */
2931
+ reasoningEffort?: ReasoningEffort;
2932
+ /** The target session. */
2933
+ sessionId: string;
2934
+ }
2935
+
2936
+ /** `turn/steer` result (tdd SS3.3). */
2937
+ export interface TurnSteerResult {
2938
+ /** Echoes the client's id. */
2939
+ commandId: string;
2940
+ /** Admission status. */
2941
+ status: CommandStatus;
2942
+ /** The running turn that absorbed the input. */
2943
+ turnId: string;
2944
+ }
2945
+
2946
+ /** Turn terminal vocabulary (tdd SS4.5.1): exactly the runtime's `RunTerminalKind` — closed in the runtime, wire-open for evolution. */
2947
+ export type TurnTerminal = "completed" | "failed" | "cancelled" | (string & {});
2948
+
2949
+ /** `turn/unqueue` params (tdd SS3.6): reclaim a queued submit before it launches. It is **not** a stop — a reclaim that arrives after its target launched is durably rejected, never silently upgraded into a cancel. */
2950
+ export interface TurnUnqueueParams {
2951
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
2952
+ commandId: string;
2953
+ /** The target session. */
2954
+ sessionId: string;
2955
+ /** The queued turn to reclaim, exactly as the queueing `turn/start`'s ack minted it and as snapshot `queuedTurns` lists it. Required, and never "whichever is newest" (tdd SS3.6). Any syntactically valid UUID: a turn from an older session may carry a v4 or v5 id. A malformed id is `invalidParams`. */
2956
+ turnId: string;
2957
+ }
2958
+
2959
+ /** `turn/unqueue` result (tdd SS3.6). Admission only — but for this command admission *is* the race: an admitted reclaim implies the turn will not launch. The authoritative removal is the `turn/unqueued` view event. */
2960
+ export interface TurnUnqueueResult {
2961
+ /** Echoes the client's id. */
2962
+ commandId: string;
2963
+ /** Admission status. */
2964
+ status: CommandStatus;
2965
+ /** The reclaimed turn. */
2966
+ turnId: string;
2967
+ }
2968
+
2969
+ /** `turn/unqueued` params (tdd SS3.6, SS4.5.1): a queued submit's reclaim durably won; its pre-minted turn never runs. Carries the reclaimed `turnId` and the `commandId` of the `turn/start` that queued it, so a client can restore the submission's text exactly as for `turn/retracted`. No `turn/started`/`turn/completed` is ever emitted for this `turnId` (SDK turn-waits settle on this event too, tdd SS3.1.4). `sourceRange` cites the SESSION stream's reclaim record — a reclaimed turn never had a run stream. */
2970
+ export interface TurnUnqueuedParams {
2971
+ /** The `commandId` of the `turn/start` that queued the reclaimed turn. */
2972
+ commandId: string;
2973
+ /** The owning session. */
2974
+ sessionId: string;
2975
+ /** The durable records this event folded from (the session stream's reclaim record). */
2976
+ sourceRange: SourceRange;
2977
+ /** The reclaimed turn: pre-minted at admission, never launched. */
2978
+ turnId: string;
2979
+ /** Opaque, strictly monotonic view cursor (tdd SS4.1). */
2980
+ viewCursor: string;
2981
+ }
2982
+
2983
+ /** The queued `!` shell action a `turn/start` carries (tdd SS3.2, ADR 50034): the `!cmd` typed while a turn runs. The shell's command id derives from the carrying turn's `commandId`, exactly as the app's own queued submit does; the params' sibling `displayText` carries the `!…` presentation form. */
2984
+ export interface TurnUserShell {
2985
+ /** The shell command text, without the leading `!`. */
2986
+ commandText: string;
2987
+ }
2988
+
2989
+ /** One element of a `view/page` result's `events` array: an **unframed view notification** exactly as tdd SS4.2.1 defines it — the nested pair `{"method", "params"}`, which is the live notification minus `jsonrpc` and `emittedAtMs`, with nothing lifted out of `params` and nothing spliced into it. SS4.2.1 is the single normative definition; SS4.7.3 and SS7.4 both cite it, so the two surfaces cannot drift. */
2990
+ export interface UnframedViewNotification {
2991
+ /** The event type — the live notification's method name, retained because the type lives only in the notification name and would otherwise be lost (tdd SS4.2.1). */
2992
+ method: string;
2993
+ /** The notification's params object, verbatim. */
2994
+ params: UnframedViewNotificationParams;
2995
+ }
2996
+
2997
+ /** The `params` of an unframed view notification (tdd SS4.2.1, SS4.2). Declares the SS4.2 base members every view notification carries, and stays **open** for the event-specific fields SS4.5/SS4.6/SS5 add per event type. The v1 schema model names no method-correlated union (the SS4.7.3 `events` element's `params` arm is selected by its sibling `method`), so the per-event arms cannot be expressed here without one; enumerating them as an uncorrelated union would additionally exclude `turn/unqueued`, whose notification row is another lane's ratified deferral (#207/#14407) — a published schema that rejects a real page element is the exact #19923 defect this PR exists to close. Recorded as a Design delta on #22785. `sourceRange` is required here and not optional: `view/page` serves durable-sourced events only (tdd SS4.7.3), and durable-sourced is *defined* as carrying a `sourceRange` — the SS4.2 ephemeral-sourced exemption applies to `item/delta`, which `view/page` never replays. */
2998
+ export interface UnframedViewNotificationParams {
2999
+ /** The owning session (tdd SS4.2). */
3000
+ sessionId: string;
3001
+ /** The durable records this event folded from (tdd SS4.2, SS6.8). */
3002
+ sourceRange: SourceRange;
3003
+ /** The event's opaque, strictly monotonic view cursor. It stays **inside** `params`, where every live notification already carries it (tdd SS4.2.1) — nothing is spliced beside `method`. */
3004
+ viewCursor: string;
3005
+ }
3006
+
3007
+ /** The only scalar alternative to a known effort array. Kept as a closed singleton so arbitrary strings and uppercase spellings fail decoding. */
3008
+ export type UnknownModelReasoningEffortVariants = "unknown";
3009
+
3010
+ /** `usage/read` result: `{usage?}` — omitted, never `null`, when the host has observed nothing (ADR 32563 D2: truthful absence, no "nothing observed" error). */
3011
+ export interface UsageReadResult {
3012
+ /** The last-observed subscription usage window, when one exists. */
3013
+ usage?: SubscriptionUsage;
3014
+ }
3015
+
3016
+ export interface UserInputAnswer {
3017
+ freeText?: string;
3018
+ note?: string;
3019
+ questionId: string;
3020
+ selectedLabel?: string;
3021
+ selectedLabels?: string[];
3022
+ }
3023
+
3024
+ /** `userInput/answer` params (tdd SS5.10.2): answer every question. Each answer carries `questionId` then exactly one of `selectedLabel` (single mode), `selectedLabels` (multiple mode, within min/max bounds), or `freeText` (<=500 chars); plus an optional `note` (<=500). Answers that do not match the prompt fail -32057 `userInputAnswerInvalid`. Image `attachments` are a **reserved** field in v1, rejected if sent, because the blob-upload path they reference is reserved in tdd SS3.2. */
3025
+ export interface UserInputAnswerParams {
3026
+ /** One entry per question. */
3027
+ answers: UserInputAnswer[];
3028
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
3029
+ commandId: string;
3030
+ /** The target session. */
3031
+ sessionId: string;
3032
+ /** The prompt being answered. */
3033
+ userInputId: string;
3034
+ }
3035
+
3036
+ /** `userInput/answer` result (tdd SS5.10.2). */
3037
+ export interface UserInputAnswerResult {
3038
+ /** Echoes the client's id. */
3039
+ commandId: string;
3040
+ /** Admission status. */
3041
+ status: CommandStatus;
3042
+ /** The prompt this answer settled. */
3043
+ userInputId: string;
3044
+ }
3045
+
3046
+ /** `userInput/cancel` params (tdd SS5.10.2): decline to answer; the tool call resolves with a cancelled result the model sees. */
3047
+ export interface UserInputCancelParams {
3048
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
3049
+ commandId: string;
3050
+ /** Why the prompt was declined. */
3051
+ reason?: string;
3052
+ /** The target session. */
3053
+ sessionId: string;
3054
+ /** The prompt being declined. */
3055
+ userInputId: string;
3056
+ }
3057
+
3058
+ /** `userInput/cancel` result (tdd SS5.10.2). */
3059
+ export interface UserInputCancelResult {
3060
+ /** Echoes the client's id. */
3061
+ commandId: string;
3062
+ /** Admission status. */
3063
+ status: CommandStatus;
3064
+ /** The prompt this cancellation settled. */
3065
+ userInputId: string;
3066
+ }
3067
+
3068
+ export interface UserInputClarification {
3069
+ content: string;
3070
+ format: string;
3071
+ }
3072
+
3073
+ /** `userInput/clarify` params (tdd SS5.10.2): answer with a free-form clarification instead of the structured options — the "let me explain" path; the model receives the clarification text and re-decides. */
3074
+ export interface UserInputClarifyParams {
3075
+ /** `format` is `"text"` in v1 (open); `content` is <=500 chars. */
3076
+ clarification: UserInputClarification;
3077
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
3078
+ commandId: string;
3079
+ /** The target session. */
3080
+ sessionId: string;
3081
+ /** The prompt being clarified. */
3082
+ userInputId: string;
3083
+ }
3084
+
3085
+ /** `userInput/clarify` result (tdd SS5.10.2). */
3086
+ export interface UserInputClarifyResult {
3087
+ /** Echoes the client's id. */
3088
+ commandId: string;
3089
+ /** Admission status. */
3090
+ status: CommandStatus;
3091
+ /** The prompt this clarification settled. */
3092
+ userInputId: string;
3093
+ }
3094
+
3095
+ /** `userInput/engaged` params (tdd SS5.10.4, ADR 45450 D2): a fire-and-forget engagement note — the user started interacting with a timed prompt, so the host disarms that prompt's auto-resolution countdown. No result, no errors, no `commandId`, no ledger row. */
3096
+ export interface UserInputEngagedParams {
3097
+ /** The target session. */
3098
+ sessionId: string;
3099
+ /** The prompt being engaged. */
3100
+ userInputId: string;
3101
+ }
3102
+
3103
+ /** `userInput/interrupt` params (tdd SS5.10.2, ADR 45450 D1): interrupt the named prompt carrying confirmed partial answers, then stop the turn. `answers` is optional and, when present, follows exactly the `userInput/answer` shape and limits (same `questionId` + one-of + `note` rules, same -32057 `userInputAnswerInvalid` on mismatch); absent or empty means interrupt with no confirmed answers. */
3104
+ export interface UserInputInterruptParams {
3105
+ /** Confirmed partial answers the named settlement carries. */
3106
+ answers?: UserInputAnswer[];
3107
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
3108
+ commandId: string;
3109
+ /** The target session. */
3110
+ sessionId: string;
3111
+ /** The prompt being interrupted. */
3112
+ userInputId: string;
3113
+ }
3114
+
3115
+ /** `userInput/interrupt` result (tdd SS5.10.2). */
3116
+ export interface UserInputInterruptResult {
3117
+ /** Echoes the client's id. */
3118
+ commandId: string;
3119
+ /** Admission status. */
3120
+ status: CommandStatus;
3121
+ /** The prompt this interruption settled. */
3122
+ userInputId: string;
3123
+ }
3124
+
3125
+ export interface UserInputOption {
3126
+ description?: string;
3127
+ label: string;
3128
+ preview?: UserInputOptionPreview;
3129
+ }
3130
+
3131
+ export interface UserInputOptionPreview {
3132
+ content: string;
3133
+ format: string;
3134
+ }
3135
+
3136
+ export type UserInputOutcome = "answered" | "cancelled" | "interrupted" | "clarified" | "timedOut" | "aborted" | (string & {});
3137
+
3138
+ export interface UserInputQuestion {
3139
+ header: string;
3140
+ id: string;
3141
+ options: UserInputOption[];
3142
+ question: string;
3143
+ selection: UserInputSelection;
3144
+ }
3145
+
3146
+ /** Full params shared by `userInput/request` and `userInput/requested`. */
3147
+ export interface UserInputRequestParams {
3148
+ autoResolutionMs?: number;
3149
+ itemId: string;
3150
+ questions: UserInputQuestion[];
3151
+ sessionId: string;
3152
+ sourceRange?: SourceRange;
3153
+ toolCallId: string;
3154
+ toolName: string;
3155
+ turnId: string;
3156
+ userInputId: string;
3157
+ viewCursor: string;
3158
+ }
3159
+
3160
+ export interface UserInputSelection {
3161
+ maxSelections?: number;
3162
+ minSelections?: number;
3163
+ mode: UserInputSelectionMode;
3164
+ }
3165
+
3166
+ export type UserInputSelectionMode = "single" | "multiple";
3167
+
3168
+ /** `userInput/settled` params: the first durable prompt settlement. */
3169
+ export interface UserInputSettledParams {
3170
+ answers: UserInputAnswer[];
3171
+ clarification: UserInputClarification | null;
3172
+ /** The decision time as RFC3339, projected from the durable settlement record's own stamp (ADR 45450 D3, ruling 2026-10-01): always present on the wire (schema-required, `null`-able); decoders still tolerate its absence (`default`, never skipped — SS5.10.3 keeps every member present), and current hosts always populate it. */
3173
+ decidedAt: string | null;
3174
+ decidedByCommandId: string | null;
3175
+ outcome: UserInputOutcome;
3176
+ reason: string | null;
3177
+ sessionId: string;
3178
+ sourceRange: SourceRange;
3179
+ userInputId: string;
3180
+ viewCursor: string;
3181
+ }
3182
+
3183
+ /** Winning terminal returned to a late user-input command. */
3184
+ export interface UserInputSettlementSummary {
3185
+ outcome: string;
3186
+ viewCursor: string;
3187
+ }
3188
+
3189
+ /** Version-control system of a branch observation (tdd SS4.6.4). Open. */
3190
+ export type Vcs = "git" | "sapling" | (string & {});
3191
+
3192
+ /** `view/gap` params (spec 208 SS4.8, FM-001): push delivery dropped events, and this names the hole. The bracket is deferred (D-16487-2): it flushes at the subscription's next ACCEPTED delivery, never at enqueue time, so `next` always names an event whose own delivery is proven. A run of consecutive undelivered events coalesces into one bracket keeping the FIRST range's `after` (D-16487-1). The gap rides the protected reserved queue, so no wire-interleaving order against neighbouring deliveries is promised — the cursors carry the semantics (INV-002, D-16487-3). On receipt a client may take either sanctioned recovery (D-030, FR-013): splice-fill — buffer live events at cursors >= `next`, page `(after, next)` forward, discard the overlap, splice — or re-anchor through the anchored read surface. The server requires neither, cannot distinguish clients by their choice, and holds no partial-fill state. */
3193
+ export interface ViewGapParams {
3194
+ /** The last cursor delivered before the hole — the exclusive lower bound of the undelivered range. An **opaque** view cursor: clients relay it, never parse it (tdd SS4.1). */
3195
+ after: string;
3196
+ /** The first cursor delivered after the hole — the exclusive upper bound of the undelivered range, and the position delivery continues from. An **opaque** view cursor: clients relay it, never parse it (tdd SS4.1). */
3197
+ next: string;
3198
+ /** The session whose subscription dropped events. */
3199
+ sessionId: string;
3200
+ }
3201
+
3202
+ /** The `view/page` request-mode anchor (tdd SS4.7.3). Declared **open**: the tdd spells it "open string enum, v1 value `latestCompaction`". */
3203
+ export type ViewPageAnchor = "latestCompaction" | (string & {});
3204
+
3205
+ /** The `view/page` paging direction (tdd SS4.7.3). Closed: the tdd spells exactly two values and a third would change the paging contract. */
3206
+ export type ViewPageDirection = "forward" | "backward";
3207
+
3208
+ /** `view/page` params (tdd SS4.7.3): cursor-paged reads of the session view. */
3209
+ export interface ViewPageParams {
3210
+ /** The cold-client request mode (D-029; spec 208 FR-008), resolved at call time to the latest installed compaction boundary. The one named exception to the SS4.1 observed-only rule. */
3211
+ anchor?: ViewPageAnchor;
3212
+ /** The exclusive anchor. Forward: the page starts strictly after it; omitted means from the beginning of the view. Backward: the page ends strictly before it; omitted means from the head. Mutually exclusive with `anchor` (tdd SS4.7.3; spec 208 FR-008a). */
3213
+ cursor?: string;
3214
+ /** Paging direction; `forward` when omitted. */
3215
+ direction?: ViewPageDirection;
3216
+ /** Maximum events to return, 1–1000. The server MAY return fewer (tdd SS4.7.3's short-serve rule). The 1–1000 range is ratified and now **published**: #22785 E6c is owner-ruled, so the model carries the bound and the bundle renders `minimum`/`maximum` instead of a bare `integer`. Range 1–1000 inclusive. */
3217
+ limit: number;
3218
+ /** The session to page. */
3219
+ sessionId: string;
3220
+ }
3221
+
3222
+ /** The `resolvedAnchor` echo (tdd SS4.7.3): subsequent pages pass ordinary cursors, so the anchor never needs re-resolving. */
3223
+ export interface ViewPageResolvedAnchor {
3224
+ /** The view cursor of the resolved boundary's `compaction` event. */
3225
+ boundaryCursor: string;
3226
+ }
3227
+
3228
+ /** `view/page` result (tdd SS4.7.3). */
3229
+ export interface ViewPageResult {
3230
+ /** The page's events, always ascending by `viewCursor` in both directions. Durable-sourced only; pages are contiguous and can never skip a cursor. */
3231
+ events: UnframedViewNotification[];
3232
+ /** The anchor for the next page in the same direction: forward, the last event's cursor; backward, the first's. `null` at the end of the view in that direction — never omitted. */
3233
+ nextCursor: string | null;
3234
+ /** The resolution echo, present exactly when the request used `anchor` (tdd SS4.7.3; spec 208 FR-008). */
3235
+ resolvedAnchor?: ViewPageResolvedAnchor;
3236
+ }
3237
+
3238
+ /** The `snapshot` object returned by `session/resume` / `session/read` (tdd SS4.9). */
3239
+ export interface ViewSnapshot {
3240
+ /** Present exactly when `history.mode` is `anchoredSnapshot` (tdd SS2.5.2). */
3241
+ anchor?: SnapshotAnchor;
3242
+ /** Snapshot schema version. A client whose generated types are older than this must fall back to inline/paged history (tdd SS4.9.2, SS2.5.2). */
3243
+ schemaVersion: number;
3244
+ /** The complete folded view at `viewCursor` (tdd SS4.9.1). */
3245
+ state: SnapshotState;
3246
+ /** The cursor the state is folded at; every event after it streams as the suffix (tdd SS4.9). */
3247
+ viewCursor: string;
3248
+ }
3249
+
3250
+ /** `view/subscribe` params (tdd SS4.7.1): attach this connection's live view subscription for a session at an explicit cursor — the fine-grained counterpart of the SS2 auto-subscribe, and the gap-free re-attachment path after `view/unsubscribe`. It never loads a session, takes no lease, writes nothing. */
3251
+ export interface ViewSubscribeParams {
3252
+ /** Resume cursor. When present, the server replays `(after, head]` as ordinary view notifications before any live event — one gapless cursor sequence. Omitted means "from now": no historical replay (tdd SS4.7.1). */
3253
+ after?: string;
3254
+ /** The session to follow. */
3255
+ sessionId: string;
3256
+ }
3257
+
3258
+ /** `view/subscribe` result (tdd SS4.7.1). */
3259
+ export interface ViewSubscribeResult {
3260
+ /** The view head at subscribe time; the client knows it is live once cursors pass it. */
3261
+ viewCursor: string;
3262
+ }
3263
+
3264
+ /** `view/unsubscribe` params (tdd SS4.7.2): remove this connection from the session's view subscription set — the protocol's single unsubscribe operation, at the altitude that owns subscriptions (tdd SS2.5.6 points here). It does not unload the session; unloading is the idle policy (tdd SS2.8). */
3265
+ export interface ViewUnsubscribeParams {
3266
+ /** The session to stop following. */
3267
+ sessionId: string;
3268
+ }
3269
+
3270
+ /** `view/unsubscribe` result (tdd SS4.7.2): the empty object. Idempotent — unsubscribing while not subscribed returns `{}`. */
3271
+ export interface ViewUnsubscribeResult {
3272
+ }
3273
+
3274
+ /** `workflow/cancel` params (tdd SS3.19): cancel a live workflow run. */
3275
+ export interface WorkflowCancelParams {
3276
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
3277
+ commandId: string;
3278
+ /** The target session. */
3279
+ sessionId: string;
3280
+ /** The run to cancel, exactly as the `workflow` item names it (SS4.5.8); required, non-empty. */
3281
+ workflowRunId: string;
3282
+ }
3283
+
3284
+ /** One workflow child's folded state (tdd SS4.5.8, `WorkflowChildLifecycleFact`), keyed by `(childId, attempt)`. */
3285
+ export interface WorkflowChild {
3286
+ /** The attempt number. */
3287
+ attempt: number;
3288
+ /** The child's id within the run. */
3289
+ childId: string;
3290
+ /** The child's observed duration, when recorded. */
3291
+ durationMs?: number;
3292
+ /** The attempt's machine failure class, verbatim when recorded (open, snake_case durable runtime vocabulary — the SS1.6 casing exemption). The attempt's outcome (`terminal`, else `status`) stays authoritative, except that `"completed"` with `failureKind` present means it failed (#17769). */
3293
+ failureKind?: string;
3294
+ /** The attempt's failure reason text, verbatim when recorded except cut to at most 2,048 UTF-8 bytes ending in U+2026 when longer. */
3295
+ failureReason?: string;
3296
+ /** The child's display label, when recorded. */
3297
+ label?: string;
3298
+ /** The child's phase, when recorded. */
3299
+ phase?: string;
3300
+ /** The child's recorded result reference, verbatim, when present — an opaque string, matching the durable owner. */
3301
+ resultRef?: string;
3302
+ /** camelCased `WorkflowChildLifecycleStatus`, verbatim (durable runtime vocabulary). */
3303
+ status: string;
3304
+ /** The child's terminal, turn vocabulary (tdd SS4.5.8). */
3305
+ terminal?: TurnTerminal;
3306
+ /** The child's observed usage, when recorded. */
3307
+ usage?: TokenUsage;
3308
+ }
3309
+
3310
+ /** Which control to apply to the child's current attempt (tdd SS3.20). Closed on the wire: an unknown value is `-32602 invalidParams`. */
3311
+ export type WorkflowChildAction = "skip" | "retry";
3312
+
3313
+ /** `workflow/childControl` params (tdd SS3.20): skip or retry one workflow child, keyed by the `(childId, attempt)` pair the `workflow` item's `children[]` carries. */
3314
+ export interface WorkflowChildControlParams {
3315
+ /** The control to apply. */
3316
+ action: WorkflowChildAction;
3317
+ /** The child's CURRENT attempt (integer >= 1). A stale value rejects `"stale_attempt"`; re-read the item and re-key — never guess. Minimum 1. */
3318
+ attempt: number;
3319
+ /** The child, from the item's `children[]`; required, non-empty. */
3320
+ childId: string;
3321
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
3322
+ commandId: string;
3323
+ /** The target session. */
3324
+ sessionId: string;
3325
+ /** The run owning the child (SS4.5.8); required, non-empty. */
3326
+ workflowRunId: string;
3327
+ }
3328
+
3329
+ /** The shared SS3.19/SS3.20/SS3.32 admission-only ack: deliberately bare `{commandId, status}` — settlement arrives as the workflow item's view events, never through the ack. */
3330
+ export interface WorkflowControlResult {
3331
+ /** Echoes the client's id. */
3332
+ commandId: string;
3333
+ /** Admission status. */
3334
+ status: CommandStatus;
3335
+ }
3336
+
3337
+ /** `workflow/pause` params (tdd SS3.32, ADR 45437 D2): pause a live workflow run, shaped exactly like `workflow/cancel`. */
3338
+ export interface WorkflowPauseParams {
3339
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
3340
+ commandId: string;
3341
+ /** The target session. */
3342
+ sessionId: string;
3343
+ /** The run to pause, exactly as the `workflow` item names it (SS4.5.8); required, non-empty. */
3344
+ workflowRunId: string;
3345
+ }
3346
+
3347
+ /** `workflow/resume` params (tdd SS3.34, ADR 45437 D3): resume a paused workflow run, host-driven. */
3348
+ export interface WorkflowResumeParams {
3349
+ /** The SS3.1.1 idempotency handle (UUIDv7). */
3350
+ commandId: string;
3351
+ /** The target session. */
3352
+ sessionId: string;
3353
+ /** The paused run to resume, exactly as the `workflow` item names it (SS4.5.8); required, non-empty. */
3354
+ workflowRunId: string;
3355
+ }
3356
+
3357
+ /** `workflow/resume` result (tdd SS3.34): admission-only plus the driven turn — always present, since resume always drives (idle fresh turn or busy steer). */
3358
+ export interface WorkflowResumeResult {
3359
+ /** Echoes the client's id. */
3360
+ commandId: string;
3361
+ /** Admission status. */
3362
+ status: CommandStatus;
3363
+ /** The turn the host drove: the fresh resume turn on an idle session, the admission-time active turn on a busy session (a routing fact like the SS3.18 wake-gate's, not settlement). */
3364
+ turnId: string;
3365
+ }
3366
+
3367
+ /** `workflow`: the run's launch token budget (tdd SS4.5.8, #45449). */
3368
+ export interface WorkflowTokenBudget {
3369
+ /** The effective launch budget in tokens, verbatim from the launch fact. */
3370
+ total: number;
3371
+ }
3372
+
3373
+ /** Every wire method in this schema (SS1.9 index). */
3374
+ export type MspMethod = "initialize" | "subagent/sendMessage" | "subagent/followupTask" | "subagent/interrupt" | "subagent/stop" | "subagent/resume" | "subagent/reopen" | "subagent/close" | "subagent/readResult" | "session/start" | "session/resume" | "session/fork" | "session/list" | "session/read" | "session/sideChat" | "turn/start" | "turn/steer" | "turn/interrupt" | "turn/cancel" | "turn/unqueue" | "session/compact" | "session/setModel" | "session/rename" | "session/setReasoningEffort" | "session/userShell" | "model/list" | "skill/list" | "skill/setActivation" | "skill/import" | "hook/list" | "plugin/list" | "plugin/install" | "plugin/marketplaceAdd" | "plugin/marketplaceUpdate" | "plugin/marketplaceRemove" | "task/background" | "task/stop" | "task/stopAll" | "task/list" | "goal/set" | "goal/edit" | "goal/clear" | "goal/pause" | "goal/resume" | "workflow/cancel" | "workflow/childControl" | "workflow/pause" | "workflow/resume" | "media/upload" | "view/subscribe" | "view/unsubscribe" | "view/page" | "item/readOutput" | "approval/decide" | "approval/listPending" | "session/setApprovalMode" | "userInput/answer" | "userInput/cancel" | "userInput/clarify" | "userInput/interrupt" | "usage/read" | "feedback/submit" | "recap/request" | "recap/cancel" | "computerUseSettings/read" | "computerUseSettings/update" | "computerUseSetup/read" | "computerUseSetup/start";
3375
+ /** Every wire notification in this schema (SS1.9 index). */
3376
+ export type MspNotification = "initialized" | "session/started" | "session/closed" | "skill/changed" | "turn/started" | "turn/completed" | "turn/retracted" | "turn/retryScheduled" | "turn/unqueued" | "turn/foregroundCompleted" | "item/started" | "item/updated" | "item/delta" | "item/completed" | "view/gap" | "approval/requested" | "approval/updated" | "approval/resolved" | "userInput/requested" | "userInput/settled" | "userInput/engaged" | "session/modelChanged" | "session/reasoningEffortChanged" | "session/statusChanged" | "session/goalChanged" | "session/todoListChanged" | "session/branchChanged" | "session/tokenUsage" | "session/contextUsage" | "session/approvalModeChanged" | "recap/completed" | "session/modelRouteUnserved" | "session/nameChanged" | "session/viewHealthChanged" | "session/listChanged" | "usage/changed" | "computerUseSetup/changed" | "plugin/changed" | "plugin/marketplaceChanged";
3377
+ /** Every server-initiated wire request in this schema (SS5.3/SS5.10.1 index). */
3378
+ export type MspServerRequest = "approval/request" | "userInput/request";
3379
+ /** Every error `data.kind` in this schema's error table (SS1.6) — each code's primary kind plus its override kinds. */
3380
+ export type MspErrorDataKind = "parseError" | "invalidRequest" | "notInitialized" | "alreadyInitialized" | "methodNotFound" | "experimentalRequired" | "invalidParams" | "internal" | "pageEventTooLarge" | "outputResultTooLarge" | "overloaded" | "inputTooLarge" | "capabilityRequired" | "notFound" | "interrupted" | "cancelled" | "sessionNotFound" | "sessionInUse" | "sessionAmbiguous" | "forkBoundaryInvalid" | "sessionNotLoaded" | "sessionStreamMismatch" | "commandRejected" | "backpressured" | "skillNotFound" | "computerUseUnavailable" | "marketplaceNotFound" | "pluginNotFound" | "marketplaceAlreadyExists" | "pluginMutationsDisabled" | "uploadNotFound" | "viewTruncated" | "outputUnavailable" | "boundaryPruned" | "boundaryUnusable" | "noBoundary" | "approvalNotFound" | "approvalAlreadyResolved" | "approvalChoiceInvalid" | "approvalRequirementStale" | "approvalReviewerUnavailable" | "userInputNotFound" | "userInputAlreadySettled" | "userInputAnswerInvalid";