@robota-sdk/agent-cli 3.0.0-beta.79 → 3.0.0-beta.81

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 (56) hide show
  1. package/README.md +740 -55
  2. package/dist/node/bin.js +3 -406
  3. package/dist/node/bounded-output-DpjpS98g-DFgAppgl.js +2 -0
  4. package/dist/node/bounded-output-DpjpS98g-DFgAppgl.js.map +1 -0
  5. package/dist/node/bounded-output-DpjpS98g-DoRuRGhV.js +2 -0
  6. package/dist/node/bounded-output-DpjpS98g-yPybHprY.cjs +1 -0
  7. package/dist/node/cli-core-Bah38oug.js +2795 -0
  8. package/dist/node/command-executor-DV-H2oD6-BfKoGoFw.js +2 -0
  9. package/dist/node/command-executor-DV-H2oD6-OKy8pwYH.js +2 -0
  10. package/dist/node/command-executor-DV-H2oD6-OKy8pwYH.js.map +1 -0
  11. package/dist/node/command-executor-DV-H2oD6-iQAXtTLY.cjs +1 -0
  12. package/dist/node/headless.js +4 -0
  13. package/dist/node/http-executor-cWzI2svn-C7F17ZGz.cjs +1 -0
  14. package/dist/node/http-executor-cWzI2svn-TG_TMYKh.js +2 -0
  15. package/dist/node/http-executor-cWzI2svn-TG_TMYKh.js.map +1 -0
  16. package/dist/node/http-executor-cWzI2svn-Ype0naht.js +2 -0
  17. package/dist/node/index.cjs +2641 -251
  18. package/dist/node/index.d.cts +3421 -0
  19. package/dist/node/index.d.cts.map +1 -0
  20. package/dist/node/index.d.ts +3412 -5
  21. package/dist/node/index.d.ts.map +1 -1
  22. package/dist/node/index.js +2641 -251
  23. package/dist/node/index.js.map +1 -1
  24. package/dist/node/node-2-nrieFn.js +2 -0
  25. package/dist/node/node-2-nrieFn.js.map +1 -0
  26. package/dist/node/node-C-hnFnOP.js +67 -0
  27. package/dist/node/node-CFTax5Wl.cjs +1 -0
  28. package/dist/node/node-CJnrbkAS.js +14 -0
  29. package/dist/node/node-CJnrbkAS.js.map +1 -0
  30. package/dist/node/node-ChG9Tg1I.js +2 -0
  31. package/dist/node/node-DDl02brx.cjs +66 -0
  32. package/dist/node/node-DIRGC_1P.js +67 -0
  33. package/dist/node/node-DIRGC_1P.js.map +1 -0
  34. package/dist/node/node-OBnZskvR.cjs +1 -0
  35. package/dist/node/node-bJ0lEuNF.js +2 -0
  36. package/dist/node/node-bJ0lEuNF.js.map +1 -0
  37. package/dist/node/node-tf433Aey.cjs +13 -0
  38. package/dist/node/node-uwhEt6sT.js +14 -0
  39. package/dist/node/rolldown-runtime-C9xYM0wc.js +1 -0
  40. package/dist/node/rolldown-runtime-DK3Fl9T5-BIInC43l.cjs +1 -0
  41. package/dist/node/rolldown-runtime-DK3Fl9T5-BeX3Bzvn.js +2 -0
  42. package/dist/node/rolldown-runtime-DK3Fl9T5-DK3Fl9T5.js +2 -0
  43. package/dist/node/rolldown-runtime-DK3Fl9T5-DK3Fl9T5.js.map +1 -0
  44. package/dist/node/rolldown-runtime-rs7quPpn.js +2 -0
  45. package/dist/node/verdict-decoder-Dk_w2NG9-BKWMtxp8.js +2 -0
  46. package/dist/node/verdict-decoder-Dk_w2NG9-Bka7Cldj.js +2 -0
  47. package/dist/node/verdict-decoder-Dk_w2NG9-Bka7Cldj.js.map +1 -0
  48. package/dist/node/verdict-decoder-Dk_w2NG9-DNTeVdQ8.cjs +1 -0
  49. package/dist/web/assets/index-8_Slbxe7.css +1 -0
  50. package/dist/web/assets/index-Cgu5C1kn.js +77 -0
  51. package/dist/web/index.html +3 -3
  52. package/package.json +106 -39
  53. package/dist/node/bin.d.ts +0 -2
  54. package/dist/node/bin.js.map +0 -1
  55. package/dist/web/assets/index-DiahfakU.css +0 -2
  56. package/dist/web/assets/index-LMW0IDmj.js +0 -37
@@ -0,0 +1,3421 @@
1
+ import "zod";
2
+ import "@modelcontextprotocol/sdk/client/streamableHttp.js";
3
+ import "@modelcontextprotocol/sdk/shared/auth.js";
4
+ import "@modelcontextprotocol/sdk/types.js";
5
+ import "@modelcontextprotocol/sdk/shared/transport.js";
6
+ //#region ../agent-core/dist/node/types-gNrckgFE.d.ts
7
+ //#region src/interfaces/universal-value.d.ts
8
+ /**
9
+ * Universal value type axis (recursive, JSON-like + Date).
10
+ *
11
+ * Extracted from `types.ts` into its own leaf module: several foundational modules (e.g.
12
+ * `provider.ts`) need only this axis, not the rest of `types.ts` (which itself depends on
13
+ * plugin-execution types) — importing the whole barrel there created a module-level import
14
+ * cycle. `types.ts` re-exports these names, so existing `from './types'` imports are unaffected.
15
+ *
16
+ * IMPORTANT:
17
+ * - This axis is the single source of truth for payload/context/result values.
18
+ * - It must support nested objects/arrays without `any`/`unknown`.
19
+ */
20
+ /**
21
+ * Primitive value types - foundation for all other types
22
+ * Extended to include null/undefined for agent contexts
23
+ */
24
+ type TPrimitiveValue = string | number | boolean | null | undefined;
25
+ type TUniversalValue = TPrimitiveValue | Date | TUniversalArrayValue | IUniversalObjectValue;
26
+ type TUniversalArrayValue = TUniversalValue[];
27
+ interface IUniversalObjectValue {
28
+ [key: string]: TUniversalValue;
29
+ }
30
+ //#endregion
31
+ //#region src/interfaces/model-effort-capability.d.ts
32
+ /** Provider-neutral native effort controls. `auto` is selection state, not a control. */
33
+ type TModelEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
34
+ /** A caller can preserve provider-default selection without serializing a native control. */
35
+ type TModelEffortSelection = TModelEffort | 'auto';
36
+ /** The verified effort facts an adapter declares for one exact model identifier. */
37
+ interface IModelEffortCapability {
38
+ supportedEfforts: readonly TModelEffort[];
39
+ defaultEffort: TModelEffort;
40
+ /** Adapter-owned opaque identity for the verified native control. */
41
+ nativeControlId: string;
42
+ }
43
+ /** Source-dated provider data. Core owns the shape but never provides the data. */
44
+ interface IProviderModelEffortTable {
45
+ verifiedAt: string;
46
+ sourceUrl: string;
47
+ models: Readonly<Record<string, IModelEffortCapability>>;
48
+ }
49
+ type TModelEffortDisposition = 'exact' | 'clamped' | 'model-default' | 'not-applied';
50
+ /** Serializable output of resolving a selection against a verified provider table. */
51
+ interface IModelEffortResolution$1 {
52
+ selection: TModelEffortSelection;
53
+ effective: TModelEffort | null;
54
+ disposition: TModelEffortDisposition;
55
+ fingerprint: string;
56
+ }
57
+ /** Whether the adapter serialized a verified native effort control. */
58
+ type TModelEffortNativeControl = {
59
+ readonly state: 'sent';
60
+ readonly id: string;
61
+ } | {
62
+ readonly state: 'omitted';
63
+ readonly reason: string;
64
+ };
65
+ /** Whether an endpoint dispatch occurred after the effort decision. */
66
+ type TModelEffortProviderDispatch = {
67
+ readonly state: 'sent';
68
+ } | {
69
+ readonly state: 'not-dispatched';
70
+ readonly reason: string;
71
+ };
72
+ /** Serializable terminal result of one effort-bearing provider request. */
73
+ interface IModelEffortOutcome {
74
+ readonly resolution: IModelEffortResolution$1;
75
+ readonly nativeControl: TModelEffortNativeControl;
76
+ readonly providerDispatch: TModelEffortProviderDispatch;
77
+ }
78
+ /** Local observer for a request's one terminal provider effort outcome. */
79
+ type TModelEffortOutcomeCallback = (outcome: IModelEffortOutcome) => void;
80
+ /** What one child process receives: exactly one environment variable, never `TRACESTATE`. */
81
+ interface ISubprocessTraceEnv {
82
+ readonly TRACEPARENT: string;
83
+ }
84
+ /** What one invoked provider call carries: the header value and where it may go. */
85
+ interface IOutboundTraceContext {
86
+ /** `00-<trace-id>-<provider-call-span-id>-01`. */
87
+ readonly traceparent: string;
88
+ /** Exact origins the adapter may send `traceparent` to; any other origin gets nothing. */
89
+ readonly allowedOrigins: readonly string[];
90
+ }
91
+ /** Claude Code compatible session end reasons. */
92
+ type TSessionEndReason = 'clear' | 'resume' | 'logout' | 'prompt_input_exit' | 'bypass_permissions_disabled' | 'other';
93
+ //#endregion
94
+ //#region ../agent-core/dist/node/index-DFlMw376.d.ts
95
+ /**
96
+ * Context data type - for execution contexts
97
+ */
98
+ type TContextData = Record<string, TUniversalValue>;
99
+ /**
100
+ * Logger data type - for logging contexts
101
+ */
102
+ type TLoggerData = Record<string, TUniversalValue | Date | Error>;
103
+ /**
104
+ * Tool parameter value type - specific for tool parameters
105
+ */
106
+ type TToolParameters = Record<string, TUniversalValue>;
107
+ //#endregion
108
+ //#region src/interfaces/interaction.d.ts
109
+ /**
110
+ * UI-agnostic "ask the user" contract (CMD-004).
111
+ *
112
+ * The SSOT for the interaction action lives in agent-core so every interaction *source* can reach it:
113
+ * command execution (`ICommandHostContext`, agent-framework) AND tool execution
114
+ * (`IToolExecutionContext`, agent-core, for model-issued questions — CMD-005). These are pure types
115
+ * with no runtime dependency, so the contract crosses a serialization/transport boundary unchanged
116
+ * (no function-valued fields).
117
+ *
118
+ * A single shape covers every interaction kind, parameterised by fields rather than split into
119
+ * variants:
120
+ * - confirm → two options, `maxSelect` 1
121
+ * - single → options, `maxSelect` 1
122
+ * - multi → options, `maxSelect` > 1
123
+ * - free text → no options, `allowFreeText` true
124
+ * - secret → free text with `masked` true
125
+ */
126
+ /** One predefined option the user can choose. */
127
+ interface IActionOption {
128
+ value: string;
129
+ label: string;
130
+ description?: string;
131
+ }
132
+ /** Pre-selected option values and/or prefilled free text for an action request. */
133
+ interface IActionDefault {
134
+ values?: readonly string[];
135
+ text?: string;
136
+ }
137
+ /** One request for the user to answer. See the module doc for how the fields encode each kind. */
138
+ interface IActionRequest {
139
+ /** Correlation key; the ask port resolves a given id exactly once (idempotent, first-answer wins). */
140
+ id: string;
141
+ title: string;
142
+ description?: string;
143
+ /** Predefined options. Empty/omitted ⇒ pure free-text entry. */
144
+ options?: readonly IActionOption[];
145
+ /** Minimum selections required (default 1). */
146
+ minSelect?: number;
147
+ /** Maximum selections allowed (default 1 ⇒ single; > 1 ⇒ multi). */
148
+ maxSelect?: number;
149
+ /** Allow a typed custom answer in addition to / instead of the options. */
150
+ allowFreeText?: boolean;
151
+ /** Free-text entry is masked (secret entry such as an API key); the renderer hides input. */
152
+ masked?: boolean;
153
+ /** Allow submitting empty free text. */
154
+ allowEmpty?: boolean;
155
+ /** Placeholder shown in the free-text field. */
156
+ placeholder?: string;
157
+ /** Maximum options shown before scrolling (renderer hint). */
158
+ maxVisible?: number;
159
+ /** Pre-selected option values and/or prefilled free text. */
160
+ default?: IActionDefault;
161
+ }
162
+ /**
163
+ * The user's answer to an {@link IActionRequest}. `answer` carries the selected option values and/or
164
+ * the typed text; `cancelled` means the user dismissed the request, or no interactive renderer was
165
+ * available to answer it.
166
+ */
167
+ type TActionResponse = {
168
+ type: 'answer';
169
+ values: readonly string[];
170
+ text?: string;
171
+ } | {
172
+ type: 'cancelled';
173
+ };
174
+ /**
175
+ * The injected "ask the user" port — a single seam reachable by every interaction source (command
176
+ * execution now; tool execution for model-issued questions later) and rendered per-environment by each
177
+ * transport. The concurrency model (broadcast to attached interactive channels, first answer wins,
178
+ * later answers for an already-resolved `id` ignored) is owned by the port implementation, not the
179
+ * contract.
180
+ */
181
+ interface IUserInteraction {
182
+ ask(request: IActionRequest): Promise<TActionResponse>;
183
+ }
184
+ /**
185
+ * Message metadata used across conversation history and provider adapters.
186
+ */
187
+ type TUniversalMessageMetadata = Record<string, string | number | boolean | Date | string[] | number[] | Record<string, number>>;
188
+ /**
189
+ * Universal multimodal message part contracts.
190
+ */
191
+ interface ITextMessagePart {
192
+ type: 'text';
193
+ text: string;
194
+ }
195
+ interface IInlineImageMessagePart {
196
+ type: 'image_inline';
197
+ mimeType: string;
198
+ data: string;
199
+ }
200
+ interface IUriImageMessagePart {
201
+ type: 'image_uri';
202
+ uri: string;
203
+ mimeType?: string;
204
+ }
205
+ type TUniversalMessagePart = ITextMessagePart | IInlineImageMessagePart | IUriImageMessagePart;
206
+ /**
207
+ * Tool call (OpenAI tool calling format).
208
+ */
209
+ interface IToolCall {
210
+ id: string;
211
+ type: 'function';
212
+ function: {
213
+ name: string;
214
+ arguments: string;
215
+ };
216
+ }
217
+ /** State of a message in conversation history */
218
+ type TMessageState = 'complete' | 'interrupted';
219
+ /**
220
+ * Base message contract shared by all message variants.
221
+ */
222
+ interface IBaseMessage {
223
+ /** Unique message identifier */
224
+ id: string;
225
+ /** Message creation timestamp */
226
+ timestamp: Date;
227
+ /** Whether this message is complete or was interrupted */
228
+ state: TMessageState;
229
+ /** Additional metadata */
230
+ metadata?: TUniversalMessageMetadata;
231
+ }
232
+ interface IUserMessage extends IBaseMessage {
233
+ role: 'user';
234
+ content: string;
235
+ parts?: TUniversalMessagePart[];
236
+ name?: string;
237
+ }
238
+ interface IAssistantMessage extends IBaseMessage {
239
+ role: 'assistant';
240
+ /** Assistant response content (can be null when making tool calls) */
241
+ content: string | null;
242
+ parts?: TUniversalMessagePart[];
243
+ toolCalls?: IToolCall[];
244
+ }
245
+ interface ISystemMessage extends IBaseMessage {
246
+ role: 'system';
247
+ content: string;
248
+ parts?: TUniversalMessagePart[];
249
+ name?: string;
250
+ }
251
+ interface IToolMessage extends IBaseMessage {
252
+ role: 'tool';
253
+ content: string;
254
+ parts?: TUniversalMessagePart[];
255
+ toolCallId: string;
256
+ name?: string;
257
+ }
258
+ /**
259
+ * Universal message union used across the SDK as the canonical contract.
260
+ * Used for AI provider communication. Extracted from IHistoryEntry[] via filtering.
261
+ */
262
+ type TUniversalMessage = IUserMessage | IAssistantMessage | ISystemMessage | IToolMessage;
263
+ /**
264
+ * Universal history entry — the base type for all records in conversation history.
265
+ *
266
+ * History is a universal timeline that records everything: AI chat messages,
267
+ * system events, skill invocations, permission decisions, etc.
268
+ * AI provider receives only chat entries (filtered and converted to TUniversalMessage).
269
+ * TUI can render any range of entries.
270
+ *
271
+ * - append-only, read-only
272
+ * - category + type for classification (free-form strings, no pre-defined enum)
273
+ * - data holds type-specific structured content
274
+ */
275
+ interface IHistoryEntry<T = unknown> {
276
+ /** Unique entry identifier */
277
+ id: string;
278
+ /** Entry creation timestamp */
279
+ timestamp: Date;
280
+ /** Top-level classification: 'chat', 'event', etc. */
281
+ category: string;
282
+ /** Sub-classification within category. Free-form, not pre-defined. */
283
+ type: string;
284
+ /** Type-specific structured data */
285
+ data?: T;
286
+ }
287
+ //#endregion
288
+ //#region src/interfaces/provider-model-capability-kind.d.ts
289
+ /**
290
+ * The vocabulary of per-model capability flags (PROV-006 / PROV-008).
291
+ *
292
+ * Extracted from `provider-definition.ts` into its own leaf module: `model-capability.ts` needs
293
+ * only this vocabulary, not the rest of `provider-definition.ts` (which itself depends on
294
+ * `IAIProvider` from `provider.ts`) — importing the whole module there created a module-level
295
+ * import cycle (`provider.ts` -> `model-capability.ts` -> `provider-definition.ts` ->
296
+ * `provider.ts`). `provider-definition.ts` re-exports this name, so existing
297
+ * `from './provider-definition'` imports are unaffected.
298
+ */
299
+ type TProviderModelCapability = 'tools' | 'vision' |
300
+ /** A first-class schema parameter the endpoint enforces. */
301
+ 'json_schema' |
302
+ /**
303
+ * JSON is guaranteed, the SHAPE is not (CORE-043).
304
+ *
305
+ * Without this DeepSeek is unrepresentable: the vocabulary offered only `json_schema`, which
306
+ * DeepSeek does not support, so its catalog entry was wrong and DELETING the entry would have left
307
+ * it wrong in the other direction — silent about a real capability.
308
+ */
309
+ 'json_object' | 'reasoning' | 'native_web' | 'streaming' |
310
+ /**
311
+ * CLI-1990: the vendor documents a server-side tool search — deferred definitions the API expands
312
+ * on demand. Declaration-only in v1: Robota runs its own client-side catalog on every provider
313
+ * and emits no vendor block. The member exists so a later offload can be capability-gated in this
314
+ * table rather than by provider name.
315
+ */
316
+ 'tool_search';
317
+ //#endregion
318
+ //#region src/interfaces/model-capability.d.ts
319
+ /** One model that verifiably differs from its vendor's default, and when that was checked. */
320
+ interface IModelCapabilityDeviation {
321
+ /** The complete capability set for this model — not a delta against the default. */
322
+ capabilities: readonly TProviderModelCapability[];
323
+ /** ISO date this deviation was verified against the vendor's documentation. */
324
+ verifiedAt: string;
325
+ sourceUrl?: string;
326
+ }
327
+ /**
328
+ * What a provider package declares about its own models.
329
+ *
330
+ * A package with no verified source for its vendor's baseline declares NO TABLE rather than an empty
331
+ * one: an empty default would resolve every capability to "false", which is the silence-read-as-denial
332
+ * inversion this contract exists to forbid.
333
+ */
334
+ interface IProviderCapabilityTable {
335
+ /** What this vendor's models can do unless a model below says otherwise. */
336
+ vendorDefault: readonly TProviderModelCapability[];
337
+ /** Only models that verifiably differ. Absent means none do. */
338
+ deviations?: Readonly<Record<string, IModelCapabilityDeviation>>;
339
+ /** ISO date the vendor default was verified. */
340
+ verifiedAt: string;
341
+ sourceUrl?: string;
342
+ }
343
+ //#endregion
344
+ //#region src/interfaces/role-model.d.ts
345
+ /**
346
+ * SELFHOST-006 — per-role model routing contract (type-only, neutral).
347
+ *
348
+ * A role→model mapping keyed by an OPAQUE `string` role id — deliberately NOT a fixed
349
+ * `planner|editor|reviewer` union and NOT a TS `enum`: a fixed vocabulary would embed an
350
+ * app-workflow opinion into a neutral library. The concrete role set lives in the product/default
351
+ * layer (`agent-builtin-providers` / `agent-cli`), never here. Mirrors the existing subagent
352
+ * opaque-key model resolution (`resolveModelId` → `MODEL_SHORTCUTS[x] ?? x`).
353
+ *
354
+ * Each role maps to an ORDERED fallback chain: the first entry is the primary; the rest are
355
+ * fallbacks in order. Each entry carries BOTH provider identity AND model — mirroring the global
356
+ * `defaultModel: { provider, model }` — so "fall back to an alternate provider" is expressible (a
357
+ * model id alone cannot express it).
358
+ */
359
+ /** One provider+model target in a role's fallback chain. */
360
+ interface IModelRef {
361
+ provider: string;
362
+ model: string;
363
+ }
364
+ //#endregion
365
+ //#region src/utils/provider-failure.d.ts
366
+ /** Why a provider call failed, as far as switching models is concerned. */
367
+ type TProviderFailureReason = 'overloaded' | 'service-unavailable' | 'server-error' | 'model-unavailable' | 'authentication' | 'billing' | 'rate-limit' | 'invalid-request' | 'network' | 'aborted' | 'unknown';
368
+ //#endregion
369
+ //#region src/interfaces/model-fallback.d.ts
370
+ /** A request moved to another model because the one it was on failed in a way another could serve. */
371
+ interface IModelFallbackNotice {
372
+ /** The model that failed. */
373
+ from: IModelRef;
374
+ /** The model the request moved to. */
375
+ to: IModelRef;
376
+ /** Why `from` could not serve it. */
377
+ reason: TProviderFailureReason;
378
+ }
379
+ type TModelFallbackCallback = (notice: IModelFallbackNotice) => void;
380
+ //#endregion
381
+ //#region src/interfaces/provider-capabilities.d.ts
382
+ interface IProviderFunctionCallingCapability {
383
+ supported: boolean;
384
+ reason?: string;
385
+ }
386
+ interface IProviderNativeWebToolCapability {
387
+ supported: boolean;
388
+ enabled: boolean;
389
+ source?: string;
390
+ reason?: string;
391
+ }
392
+ interface IProviderNativeWebToolCapabilities {
393
+ webSearch: IProviderNativeWebToolCapability;
394
+ webFetch: IProviderNativeWebToolCapability;
395
+ }
396
+ interface IProviderCapabilities {
397
+ functionCalling: IProviderFunctionCallingCapability;
398
+ nativeWebTools: IProviderNativeWebToolCapabilities;
399
+ }
400
+ /**
401
+ * Hosted web tools asked of one call: `true` requires the tool (a provider without it throws),
402
+ * `false` withholds it from this call even when the provider is configured with it, and absent
403
+ * leaves the provider's own configuration.
404
+ */
405
+ interface IProviderNativeWebToolRequest {
406
+ webSearch?: boolean;
407
+ webFetch?: boolean;
408
+ }
409
+ //#endregion
410
+ //#region src/interfaces/provider-specific-options.d.ts
411
+ /**
412
+ * Vendor-specific request options, kept out of `provider.ts`.
413
+ *
414
+ * Split by responsibility rather than shaved: `provider.ts` is long past the size ceiling, and these
415
+ * are the one part of it that describes particular VENDORS rather than the neutral contract every
416
+ * provider implements. They are re-exported from `provider.ts`, so no consumer sees a difference.
417
+ */
418
+ /**
419
+ * Provider-specific configuration options
420
+ */
421
+ interface IProviderSpecificOptions {
422
+ /** OpenAI specific options */
423
+ openai?: {
424
+ organization?: string;
425
+ user?: string;
426
+ stop?: string | string[];
427
+ presencePenalty?: number;
428
+ frequencyPenalty?: number;
429
+ logitBias?: Record<string, number>;
430
+ topP?: number;
431
+ n?: number;
432
+ stream?: boolean;
433
+ suffix?: string;
434
+ echo?: boolean;
435
+ bestOf?: number;
436
+ logprobs?: number;
437
+ };
438
+ /** Anthropic specific options */
439
+ anthropic?: {
440
+ stopSequences?: string[];
441
+ topP?: number;
442
+ topK?: number;
443
+ metadata?: {
444
+ userId?: string;
445
+ };
446
+ };
447
+ /** Google specific options */
448
+ google?: {
449
+ candidateCount?: number;
450
+ stopSequences?: string[];
451
+ safetySettings?: Array<{
452
+ category: string;
453
+ threshold: string;
454
+ }>;
455
+ responseModalities?: Array<'TEXT' | 'IMAGE'>;
456
+ topP?: number;
457
+ topK?: number;
458
+ };
459
+ }
460
+ /**
461
+ * Callback for receiving text deltas during streaming.
462
+ * Called for each text chunk as the model generates output.
463
+ */
464
+ //#endregion
465
+ //#region src/interfaces/tool-schema.d.ts
466
+ /**
467
+ * The universal JSON-schema subset (CORE-039 SSOT).
468
+ *
469
+ * Every tool schema and every structured-output schema in the repo is expressed in these types.
470
+ * They live in their own module rather than inside `provider.ts` because they are their own
471
+ * concept: producers (the Zod converter), validators, and four provider adapters all reach them,
472
+ * and only some of those care about the rest of the provider contract.
473
+ *
474
+ * The full contract — which member means what, and what a walk over it must do — is in
475
+ * agent-core `docs/SPEC.md` § Universal JSON-Schema Subset. `provider.ts` re-exports everything
476
+ * here, so existing `from './provider'` imports keep resolving.
477
+ */
478
+ /**
479
+ * JSON Schema parameter default value type
480
+ * Used for default values in parameter schemas
481
+ */
482
+ type TParameterDefaultValue = string | number | boolean | null;
483
+ /**
484
+ * JSON Schema primitive types
485
+ */
486
+ type TJSONSchemaKind = 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object' | 'null';
487
+ /**
488
+ * JSON Schema enum values
489
+ */
490
+ type TJSONSchemaEnum = string[] | number[] | boolean[] | (string | number | boolean)[];
491
+ /**
492
+ * Parameter schema — one shape for a root object and every node inside it.
493
+ *
494
+ * `required` and `anyOf` are members at every level, so a nested object states its own requirements
495
+ * rather than losing them. Splitting root from nested is what let a nested object be treated as a
496
+ * leaf: the root named its fields while everything below it reached the model as
497
+ * `{ "type": "object" }` and nothing else.
498
+ *
499
+ * `type` is optional because a union node carries `anyOf` INSTEAD of a type — emitting both is
500
+ * invalid JSON Schema, since a provider applies the two constraints together and rejects the branch
501
+ * that does not match the type. A node with neither is not valid: every walk over this subset
502
+ * refuses it rather than passing it silently.
503
+ *
504
+ * `additionalProperties` declares closure relative to a declared `properties` set — a node that
505
+ * declares no `properties` permits any, exactly as JSON Schema does. See the SPEC section above for
506
+ * why the rule is keyed on member presence.
507
+ */
508
+ interface IParameterSchema {
509
+ type?: TJSONSchemaKind;
510
+ description?: string;
511
+ enum?: TJSONSchemaEnum;
512
+ items?: IParameterSchema;
513
+ properties?: Record<string, IParameterSchema>;
514
+ required?: string[];
515
+ /** Union node: the value must match at least one member. Carried instead of `type`. */
516
+ anyOf?: IParameterSchema[];
517
+ additionalProperties?: boolean | IParameterSchema;
518
+ minimum?: number;
519
+ maximum?: number;
520
+ pattern?: string;
521
+ format?: string;
522
+ default?: TParameterDefaultValue;
523
+ }
524
+ /**
525
+ * An {@link IParameterSchema} narrowed to an object node that names its properties — the shape a
526
+ * tool's `parameters` root must take.
527
+ */
528
+ interface IObjectParameterSchema extends IParameterSchema {
529
+ type: 'object';
530
+ properties: Record<string, IParameterSchema>;
531
+ }
532
+ /**
533
+ * Tool schema definition
534
+ */
535
+ interface IToolSchema {
536
+ name: string;
537
+ description: string;
538
+ parameters: IObjectParameterSchema;
539
+ /**
540
+ * SELFHOST-005: optional schema the tool's OUTPUT (`result.data`) must match. When present, the
541
+ * tool-registry validates the returned value against it in `FunctionTool.execute` (beside the
542
+ * tool-INPUT `parameter-validator`) and throws on mismatch before the result returns. Absent =
543
+ * no output validation (backward-compatible). Model-output validation is separate (CORE-015).
544
+ *
545
+ * An object output is declared as an {@link IObjectParameterSchema} (so it names its properties);
546
+ * a non-object output is a bare {@link IParameterSchema}. Both are the same subset — CORE-039
547
+ * removed the second, structurally identical root shape that used to be spelled out here purely
548
+ * to regain `required`, which `IParameterSchema` now carries at every level.
549
+ */
550
+ outputSchema?: IParameterSchema;
551
+ /**
552
+ * CLI-1990: withheld from the model's tool list until loaded; omission means resident.
553
+ *
554
+ * A CLIENT-SIDE marker — the schema leaves the request entirely, not merely the context window,
555
+ * which is what the vendor's `defer_loading` does. Deferral engages only when the tool-search
556
+ * policy says so (`resolveToolSearchMode`); until then a deferred tool is offered like any other,
557
+ * so declaring it costs nothing at today's tool counts. Loaded by the search tool (by query or by
558
+ * name) or by a `toolChoice` that forces the tool, and it stays loaded for the session. Provider
559
+ * adapters never emit it: it is not part of any vendor wire format.
560
+ */
561
+ deferLoading?: boolean;
562
+ }
563
+ //#endregion
564
+ //#region src/interfaces/provider.d.ts
565
+ /**
566
+ * Reusable type definitions for provider layer
567
+ */
568
+ /**
569
+ * Provider configuration value type
570
+ * Used for storing provider-specific configuration values
571
+ */
572
+ type TProviderConfigValue = string | number | boolean;
573
+ /**
574
+ * Token usage statistics
575
+ */
576
+ interface ITokenUsage {
577
+ promptTokens: number;
578
+ completionTokens: number;
579
+ totalTokens: number;
580
+ }
581
+ /**
582
+ * Raw provider response interface
583
+ */
584
+ interface IRawProviderResponse {
585
+ content: string | null;
586
+ toolCalls?: IToolCall[];
587
+ usage?: ITokenUsage;
588
+ finishReason?: string;
589
+ model?: string;
590
+ metadata?: Record<string, TProviderConfigValue>;
591
+ /** One terminal effort result for generic raw non-streaming calls or the explicit stream envelope. */
592
+ modelEffortOutcome?: IModelEffortOutcome;
593
+ }
594
+ /**
595
+ * Provider request payload
596
+ */
597
+ interface IProviderRequest {
598
+ messages: TUniversalMessage[];
599
+ model?: string;
600
+ /** Caller selection retained until the adapter resolves its verified model table. */
601
+ effort?: TModelEffortSelection;
602
+ /** Immutable adapter-bound resolution handoff for this request. */
603
+ effortResolution?: IModelEffortResolution$1;
604
+ /** Local-only observer for the terminal serializable outcome. */
605
+ onModelEffortOutcome?: TModelEffortOutcomeCallback;
606
+ temperature?: number;
607
+ maxTokens?: number;
608
+ tools?: IToolSchema[];
609
+ systemMessage?: string;
610
+ metadata?: Record<string, string | number | boolean>;
611
+ }
612
+ type TTextDeltaCallback = (delta: string) => void;
613
+ type TProviderNativeRawPayloadKind = 'request' | 'response' | 'stream_event';
614
+ type TProviderNativeRawPayload = string | number | boolean | object | null | undefined;
615
+ interface IProviderNativeRawPayloadEvent {
616
+ provider: string;
617
+ apiSurface?: string;
618
+ payloadKind: TProviderNativeRawPayloadKind;
619
+ payload: TProviderNativeRawPayload;
620
+ sequence?: number;
621
+ metadata?: Record<string, TProviderConfigValue>;
622
+ }
623
+ type TProviderNativeRawPayloadCallback = (event: IProviderNativeRawPayloadEvent) => void;
624
+ /**
625
+ * Tool-invocation directive threaded per model invocation (CORE-017).
626
+ *
627
+ * Canonical SSOT for the union. `'auto'` lets the model decide (provider default),
628
+ * `'none'` suppresses tool calls for the invocation, `'required'` forces the model to call
629
+ * some tool, and `{ tool: name }` forces a call to the named tool. Core validates that a
630
+ * named tool exists in the invocation's tool list and that `'required'`/named forcing is
631
+ * only used when tools are present — a violation throws instead of degrading silently.
632
+ * Within a multi-round run, forcing directives apply to the FIRST model call only; rounds
633
+ * after tool results revert to `'auto'` so the model can consume the results and finish.
634
+ */
635
+ type TToolChoice = 'auto' | 'none' | 'required' | {
636
+ tool: string;
637
+ };
638
+ /**
639
+ * Options for AI provider chat requests
640
+ */
641
+ interface IChatOptions extends IProviderSpecificOptions {
642
+ /** Tool schemas to provide to the AI provider */
643
+ tools?: IToolSchema[];
644
+ /** Maximum number of tokens to generate */
645
+ maxTokens?: number;
646
+ /** Temperature for response randomness (0-1) */
647
+ temperature?: number;
648
+ /**
649
+ * Reasoning-effort dial for this invocation. Native-effort providers map it to their
650
+ * request parameter; providers without native effort ignore it (documented no-op).
651
+ * Threaded from session/model options; `auto` remains provider-default selection until resolution.
652
+ */
653
+ effort?: TModelEffortSelection;
654
+ /** Immutable adapter-bound resolution handoff for this request. */
655
+ effortResolution?: IModelEffortResolution$1;
656
+ /** Local-only observer for this request's terminal model-effort outcome. */
657
+ onModelEffortOutcome?: TModelEffortOutcomeCallback;
658
+ /** Model to use for the request */
659
+ model?: string;
660
+ /** Callback for text deltas during streaming. When provided, the provider
661
+ * should use streaming internally and call this for each text chunk,
662
+ * while still returning the complete assembled message. */
663
+ onTextDelta?: TTextDeltaCallback;
664
+ /** Callback for provider-owned native SDK request/response/stream payload capture. */
665
+ onProviderNativeRawPayload?: TProviderNativeRawPayloadCallback;
666
+ /** AbortSignal for cancelling the provider call */
667
+ signal?: AbortSignal;
668
+ /**
669
+ * Trusted trace context for THIS invoked call. Core sets it only on a call it actually hands to the
670
+ * adapter, and only for a provider that answers `canPropagateTraceContext()` with true. An adapter
671
+ * adds `traceparent` (via `traceHeadersFor`) to its per-request headers when its effective origin
672
+ * is listed, after raw-payload capture, and never copies this into any captured payload.
673
+ */
674
+ outboundTraceContext?: IOutboundTraceContext;
675
+ /**
676
+ * Tool-invocation directive for this call. Adapters map it onto their wire format
677
+ * (`tool_choice` / `functionCallingConfig`); omitted = provider default ('auto').
678
+ */
679
+ toolChoice?: TToolChoice;
680
+ /** Provider-native hosted web tools requested for this call */
681
+ nativeWebTools?: IProviderNativeWebToolRequest;
682
+ /** Request structured output from the provider (CORE-015: `json_schema` carries the schema). */
683
+ responseFormat?: {
684
+ type: 'text' | 'json_object';
685
+ } | {
686
+ type: 'json_schema';
687
+ name?: string;
688
+ schema: Record<string, TUniversalValue>;
689
+ };
690
+ /**
691
+ * The run this call belongs to: the same for every call of one run and different for the next.
692
+ * A provider that can answer on another model keys its per-run choice on it; a call without one
693
+ * belongs to no run and starts from the requested model.
694
+ */
695
+ executionId?: string;
696
+ /** Told when this request moved to another model, so the caller can attribute the answer. */
697
+ onModelFallback?: TModelFallbackCallback;
698
+ /**
699
+ * Any other model this request moves to must offer at least the requested model's context
700
+ * window; a model whose window is unknown counts as smaller. Set by compaction, whose input was
701
+ * sized to the requested model.
702
+ */
703
+ preserveContextWindow?: boolean;
704
+ }
705
+ /**
706
+ * Provider-agnostic AI Provider interface
707
+ * This interface uses only TUniversalMessage types and avoids provider-specific types
708
+ */
709
+ interface IAIProvider {
710
+ /** Provider identifier */
711
+ readonly name: string;
712
+ /** Provider version */
713
+ readonly version: string;
714
+ /**
715
+ * Generate response from AI model using TUniversalMessage
716
+ * @param messages - Array of TUniversalMessage from conversation history
717
+ * @param options - Chat options including tools, model settings, etc.
718
+ * @returns Promise resolving to a TUniversalMessage response
719
+ */
720
+ chat(messages: TUniversalMessage[], options?: IChatOptions): Promise<TUniversalMessage>;
721
+ /**
722
+ * Generate streaming response from AI model using TUniversalMessage
723
+ * @param messages - Array of TUniversalMessage from conversation history
724
+ * @param options - Chat options including tools, model settings, etc.
725
+ * @returns AsyncIterable of TUniversalMessage chunks
726
+ */
727
+ chatStream?(messages: TUniversalMessage[], options?: IChatOptions): AsyncIterable<TUniversalMessage>;
728
+ /**
729
+ * Generate response from AI model (raw provider response)
730
+ * @param payload - Provider request payload
731
+ * @returns Promise resolving to raw provider response
732
+ */
733
+ generateResponse(payload: IProviderRequest): Promise<IRawProviderResponse>;
734
+ /**
735
+ * Generate streaming response from AI model (raw provider response)
736
+ * @param payload - Provider request payload
737
+ * @returns AsyncIterable of raw provider response chunks
738
+ */
739
+ generateStreamingResponse?(payload: IProviderRequest): AsyncIterable<IRawProviderResponse>;
740
+ /**
741
+ * Check if the provider supports tool calling
742
+ * @returns true if tool calling is supported
743
+ */
744
+ supportsTools(): boolean;
745
+ /**
746
+ * Report provider-neutral capability state.
747
+ * Providers without native web support can omit this and use default capability helpers.
748
+ */
749
+ getCapabilities?(): IProviderCapabilities;
750
+ /**
751
+ * What this provider's models can do (PROV-006/PROV-008).
752
+ *
753
+ * `supportsTools()` answers for the vendor, which is the wrong granularity when models differ.
754
+ * This is the per-MODEL answer, declared by the package that ships the adapter and reachable from
755
+ * the instance — the catalog on `IProviderDefinition` is discovery, which the instance never
756
+ * holds. Optional, and silence is NOT denial: see `interfaces/model-capability.ts`.
757
+ */
758
+ capabilityTable?(): IProviderCapabilityTable | undefined;
759
+ /**
760
+ * Source-dated effort data for exact models this adapter can verify. Optional: a missing table is
761
+ * a visible `not-applied` result, never a vendor-wide inferred default.
762
+ */
763
+ effortTable?(): IProviderModelEffortTable | undefined;
764
+ /**
765
+ * Whether this provider instance is pointed at its vendor's own endpoint. CORE-043.
766
+ *
767
+ * A provider configured with a custom `baseURL` still speaks the vendor's protocol, but the
768
+ * vendor's guarantees are no longer the ones in force — a gateway can accept a structured-output
769
+ * parameter and forward a request that ignores it, so the runtime would claim enforcement the
770
+ * endpoint does not provide.
771
+ *
772
+ * Separate from `capabilityTable()` deliberately. Endpoint identity and capability declaration are
773
+ * independent facts, and coupling them would force a provider with no verified table to invent one
774
+ * in order to report its endpoint. Silence means the provider did not say, which is not a claim
775
+ * that the endpoint is the vendor's.
776
+ */
777
+ endpointIsVendorDefault?(): boolean;
778
+ /**
779
+ * Whether this instance can put a trusted `traceparent` on its own HTTP requests: it knows its
780
+ * effective origin and sends through a transport it controls. Optional, and silence means it
781
+ * cannot — core then sends it no trace context and tells the host which provider could not.
782
+ */
783
+ canPropagateTraceContext?(): boolean;
784
+ /**
785
+ * Where a request for `model` in the run `executionId` will go first. Only a provider that can
786
+ * answer on another model implements it; absent, the request goes to this provider and `model`.
787
+ */
788
+ resolveModelRoute?(model: string, executionId?: string): IModelRef;
789
+ /**
790
+ * Optional generic hook for enabling provider-native hosted web behavior.
791
+ */
792
+ configureNativeWebTools?(request: IProviderNativeWebToolRequest): IProviderCapabilities;
793
+ /**
794
+ * Validate provider configuration
795
+ * @returns true if configuration is valid
796
+ */
797
+ validateConfig(): boolean;
798
+ /**
799
+ * Clean up resources when provider is no longer needed
800
+ */
801
+ dispose?(): Promise<void>;
802
+ /**
803
+ * Close provider connections and cleanup resources
804
+ */
805
+ close?(): Promise<void>;
806
+ }
807
+ /**
808
+ * The catalog a search tool loads through — the port `IToolExecutionContext.deferredTools` carries.
809
+ *
810
+ * Narrow on purpose: a tool that can list and load must not be able to register, remove or execute.
811
+ */
812
+ interface IDeferredToolCatalog {
813
+ /**
814
+ * Deferred tools not yet loaded — the population a search can still discover. Empty while
815
+ * deferral is not engaged, because nothing is withheld then.
816
+ */
817
+ listDeferredTools(): IToolSchema[];
818
+ /**
819
+ * Mark the named deferred tools loaded for the rest of the session and return their schemas. A
820
+ * resident name is returned as it is (it was never withheld); an unknown name throws, naming the
821
+ * entry, and then nothing is loaded — the check runs over every name before the first load.
822
+ */
823
+ loadDeferredTools(names: readonly string[]): IToolSchema[];
824
+ }
825
+ //#endregion
826
+ //#region src/event-service/interfaces.d.ts
827
+ /**
828
+ * @fileoverview Event service interface definitions.
829
+ *
830
+ * These interfaces are the single source of truth for event-related contracts
831
+ * within @robota-sdk/agent-core.
832
+ */
833
+ /**
834
+ * Primitive value types for event payloads.
835
+ */
836
+ type TEventPrimitiveValue = string | number | boolean | null | undefined;
837
+ /**
838
+ * Recursive universal value type for event payloads (JSON-like + Date).
839
+ */
840
+ type TEventUniversalValue = TEventPrimitiveValue | Date | TEventUniversalValue[] | IEventObjectValue;
841
+ interface IEventObjectValue {
842
+ [key: string]: TEventUniversalValue;
843
+ }
844
+ /**
845
+ * Logger data type for event metadata.
846
+ */
847
+ type TEventLoggerData = Record<string, TEventUniversalValue | Date | Error>;
848
+ /**
849
+ * A single segment in an explicit ownerPath.
850
+ *
851
+ * Path-only rule:
852
+ * - Relationships must be derived from these explicit segments, not from parsing IDs.
853
+ */
854
+ interface IOwnerPathSegment {
855
+ type: string;
856
+ id: string;
857
+ }
858
+ /**
859
+ * Event context that accompanies an emitted event.
860
+ * This is the single source of truth for deterministic linking in subscribers.
861
+ */
862
+ interface IEventContext {
863
+ ownerType: string;
864
+ ownerId: string;
865
+ ownerPath: IOwnerPathSegment[];
866
+ /** Depth of the current execution in the hierarchy (0 = root) */
867
+ depth?: number;
868
+ /** Unique span identifier for distributed tracing correlation */
869
+ spanId?: string;
870
+ /** Optional structured metadata for debugging/observability */
871
+ metadata?: TEventLoggerData;
872
+ }
873
+ /**
874
+ * Allowed extension values for event payloads.
875
+ */
876
+ type TEventExtensionValue = TEventUniversalValue | TEventLoggerData | Error | IEventContext | IOwnerPathSegment[];
877
+ /**
878
+ * Base event payload shape.
879
+ * Emitters may add additional fields, but MUST keep linkage information explicit.
880
+ */
881
+ interface IBaseEventData {
882
+ /** Timestamp when the event was emitted. This is required for deterministic ordering. */
883
+ timestamp: Date;
884
+ /** Optional structured metadata */
885
+ metadata?: TEventLoggerData;
886
+ /** Extensible fields for event-specific payloads */
887
+ [key: string]: TEventExtensionValue | undefined;
888
+ }
889
+ type TEventListener = (eventType: string, data: IBaseEventData, context?: IEventContext) => void;
890
+ /**
891
+ * Minimal EventService contract for emitting events.
892
+ */
893
+ interface IEventService {
894
+ emit(eventType: string, data: IBaseEventData, context?: IEventContext): void;
895
+ subscribe(listener: TEventListener): void;
896
+ unsubscribe(listener: TEventListener): void;
897
+ }
898
+ //#endregion
899
+ //#region src/interfaces/tool.d.ts
900
+ type TToolContextExtensionValue = TUniversalValue | Date | Error | TLoggerData | TContextData | TToolParameters | TToolMetadata;
901
+ /**
902
+ * Tool metadata structure - specific type definition
903
+ */
904
+ type TToolMetadata = Record<string, string | number | boolean | string[] | number[] | boolean[] | TToolParameters>;
905
+ /**
906
+ * Tool execution data - domain payload for tool results.
907
+ *
908
+ * IMPORTANT:
909
+ * - This must support structured tool outputs without resorting to `any`.
910
+ * - Prefer `ToolResultData` (derived from the canonical `UniversalValue` axis).
911
+ */
912
+ /**
913
+ * Tool execution result - extended for ToolExecutionData compatibility
914
+ */
915
+ interface IToolResult {
916
+ success: boolean;
917
+ data?: TUniversalValue;
918
+ error?: string;
919
+ metadata?: TToolMetadata;
920
+ [key: string]: TToolContextExtensionValue | undefined;
921
+ }
922
+ /**
923
+ * Tool execution context - type-safe context for tool execution
924
+ * Enhanced with hierarchical execution tracking support
925
+ */
926
+ interface IToolExecutionContext {
927
+ toolName: string;
928
+ parameters: TToolParameters;
929
+ /**
930
+ * Run-scoped cancellation signal (CORE-018). Long-running tools MUST honor it: terminate
931
+ * the underlying work (kill the child process, abort the network request) and return an
932
+ * interrupted/failed result. Completing silently after an abort is a contract violation.
933
+ */
934
+ signal?: AbortSignal;
935
+ /** Direct remote calls deny decisions that would require human interaction. */
936
+ permissionInteraction?: 'interactive' | 'deny';
937
+ executionId?: string;
938
+ userId?: string;
939
+ sessionId?: string;
940
+ metadata?: TToolMetadata;
941
+ /** Parent execution ID for hierarchical tool execution tracking */
942
+ parentExecutionId?: string;
943
+ /** Root execution ID (Team/Agent level) for complete execution tree tracking */
944
+ rootExecutionId?: string;
945
+ /** Execution depth level (0: Team, 1: Agent, 2: Tool, etc.) */
946
+ executionLevel?: number;
947
+ /** Execution path array showing the complete execution hierarchy */
948
+ executionPath?: string[];
949
+ /** Real-time execution data for accurate tracking (no simulation) */
950
+ realTimeData?: {
951
+ /** Actual execution start time */
952
+ startTime: Date;
953
+ /** Actual input parameters passed to the tool */
954
+ actualParameters: TToolParameters;
955
+ /** Tool-provided estimated duration (optional) */
956
+ estimatedDuration?: number;
957
+ };
958
+ /**
959
+ * Additional tool execution context extensions.
960
+ *
961
+ * IMPORTANT:
962
+ * - Avoid ad-hoc top-level fields to keep the contract stable.
963
+ * - Use this map for forward-compatible extra data with constrained value types.
964
+ */
965
+ extensions?: Record<string, TToolContextExtensionValue>;
966
+ /** Owner context propagated from EventService */
967
+ ownerType?: string;
968
+ ownerId?: string;
969
+ ownerPath?: IOwnerPathSegment[];
970
+ sourceId?: string;
971
+ /**
972
+ * Tool-call scoped EventService instance.
973
+ * Caller (ExecutionService/ToolExecutionService) is responsible for providing
974
+ * an ownerPath-bound EventService for this tool call.
975
+ */
976
+ eventService?: IEventService;
977
+ /**
978
+ * Unbound base EventService instance.
979
+ *
980
+ * Required when a tool needs to create another owner-bound EventService
981
+ * for a different owner (e.g., creating an agent from a tool call).
982
+ *
983
+ * NOTE: Do not wrap an already owner-bound EventService to bind a different owner.
984
+ * Owner-bound instances must not be layered across different owners.
985
+ */
986
+ baseEventService?: IEventService;
987
+ /**
988
+ * Injected "ask the user" port (CMD-004). Present when an interactive renderer is attached, letting
989
+ * a tool solicit a structured answer from the user (the model-issued question seam consumed by
990
+ * CMD-005). Absent in non-interactive contexts; a tool that asks must treat absence as "no human
991
+ * available" (never a silent guess).
992
+ */
993
+ ask?: IUserInteraction['ask'];
994
+ /**
995
+ * CLI-1990: the deferred-tool catalog the runtime injects (`ToolExecutionService`), so a search
996
+ * tool can list what is withheld and load it for the rest of the session. Present on every tool
997
+ * call the execution loop issues; a tool other than the search tool has no reason to read it.
998
+ */
999
+ deferredTools?: IDeferredToolCatalog;
1000
+ /**
1001
+ * The ID core mints for this one tool body, unique even when a vendor reuses its tool call ID.
1002
+ * The body's exported span is derived from it, so it is also what a propagated parent names.
1003
+ */
1004
+ toolBodyId?: string;
1005
+ /**
1006
+ * Present only when the run carries trusted trace context: the `traceparent` naming this body's
1007
+ * span and the exact origins it may be sent to. A tool that makes outbound requests sends it only
1008
+ * to a listed origin.
1009
+ */
1010
+ outboundTraceContext?: IOutboundTraceContext;
1011
+ /**
1012
+ * Present only when the host lets shell children inherit the trace: the environment naming this
1013
+ * body's span. Only the foreground shell tool applies it, to its own child.
1014
+ */
1015
+ shellTraceEnv?: ISubprocessTraceEnv;
1016
+ /**
1017
+ * Present only when the host lets command hooks inherit the trace: the environment naming the
1018
+ * prompt root, for the hooks fired around this body. Separate from {@link shellTraceEnv}, whose
1019
+ * span is the body's own.
1020
+ */
1021
+ hookTraceEnv?: ISubprocessTraceEnv;
1022
+ }
1023
+ /**
1024
+ * Parameter validation result
1025
+ */
1026
+ interface IParameterValidationResult {
1027
+ /** Whether parameters are valid */
1028
+ isValid: boolean;
1029
+ /** Validation error messages */
1030
+ errors: string[];
1031
+ }
1032
+ /**
1033
+ * Type-safe tool interface with type parameters
1034
+ *
1035
+ * @template TParameters - Tool parameters type (defaults to AbstractToolParameters for backward compatibility)
1036
+ * @template TResult - Tool result type (defaults to ToolResult for backward compatibility)
1037
+ */
1038
+ interface IToolContract<TParameters = TToolParameters, TResult = IToolResult> {
1039
+ readonly schema: IToolSchema;
1040
+ execute(parameters: TParameters, context: IToolExecutionContext): Promise<TResult>;
1041
+ validate(parameters: TParameters): boolean;
1042
+ validateParameters(parameters: TParameters): IParameterValidationResult;
1043
+ getDescription(): string;
1044
+ getName(): string;
1045
+ }
1046
+ /**
1047
+ * Runtime tool instance contract used by Robota internals.
1048
+ *
1049
+ * Tools passed into Agent configuration must support EventService injection
1050
+ * so Robota can emit unified tool lifecycle events.
1051
+ */
1052
+ interface IToolWithEventService<TParameters = TToolParameters, TResult = IToolResult> extends IToolContract<TParameters, TResult> {
1053
+ setEventService(eventService: IEventService | undefined): void;
1054
+ }
1055
+ //#endregion
1056
+ //#region src/interfaces/provider-definition.d.ts
1057
+ interface IProviderDefinitionConfig {
1058
+ name: string;
1059
+ model: string;
1060
+ apiKey?: string;
1061
+ /**
1062
+ * Name of the environment variable `apiKey` was resolved FROM, when the stored settings value
1063
+ * was a `$ENV:` reference (SEC-009). Config loading resolves such a reference into the secret
1064
+ * itself, which is correct for an in-process provider and wrong for anything that has to
1065
+ * SERIALIZE the config — the resolved value then crosses a boundary the credential's owner
1066
+ * never opted into. Keeping the variable name lets a serializing caller carry the reference and
1067
+ * leave the secret behind; `ISerializableProviderProfile` already declares the same field, and
1068
+ * `resolveProfileApiKey` already reads it.
1069
+ *
1070
+ * Distinct from `sourceEnvVar`, which is set only for a synthesized `'env-default'` config.
1071
+ */
1072
+ apiKeyEnv?: string;
1073
+ baseURL?: string;
1074
+ timeout?: number;
1075
+ options?: Record<string, TUniversalValue>;
1076
+ /**
1077
+ * Resolution origin. `'env-default'` means no settings profile existed and the config
1078
+ * was synthesized from a provider definition's defaults because its `$ENV:` apiKey
1079
+ * reference resolved — callers surface a startup notice for this case.
1080
+ */
1081
+ source?: 'env-default';
1082
+ /**
1083
+ * Name of the environment variable the env-default key was resolved from
1084
+ * (set only when `source` is `'env-default'`) — lets callers name the variable in the
1085
+ * startup notice without exposing the key value.
1086
+ */
1087
+ sourceEnvVar?: string;
1088
+ }
1089
+ interface IProviderProfileDefaults {
1090
+ model?: string;
1091
+ apiKey?: string;
1092
+ baseURL?: string;
1093
+ timeout?: number;
1094
+ options?: Record<string, TUniversalValue>;
1095
+ }
1096
+ interface IProviderProfileConfig {
1097
+ type?: string;
1098
+ model?: string;
1099
+ apiKey?: string;
1100
+ baseURL?: string;
1101
+ timeout?: number;
1102
+ options?: Record<string, TUniversalValue>;
1103
+ }
1104
+ interface IProviderProbeResult {
1105
+ ok: boolean;
1106
+ message: string;
1107
+ models?: string[];
1108
+ }
1109
+ type TProviderCredentialField = 'apiKey';
1110
+ type TProviderSetupField = 'baseURL' | 'model' | TProviderCredentialField;
1111
+ type TProviderSetupHelpLinkKind = 'api-key' | 'console' | 'official';
1112
+ interface IProviderCredentialRequirement {
1113
+ anyOf: readonly TProviderCredentialField[];
1114
+ }
1115
+ interface IProviderSetupHelpLink {
1116
+ kind: TProviderSetupHelpLinkKind;
1117
+ label: string;
1118
+ url: string;
1119
+ sourceUrl?: string;
1120
+ lastVerifiedAt?: string;
1121
+ }
1122
+ type TProviderModelCatalogStatus = 'live' | 'generated' | 'fallback' | 'unavailable';
1123
+ type TProviderModelLifecycle = 'active' | 'preview' | 'deprecated' | 'unavailable';
1124
+ interface IProviderModelCatalogEntry {
1125
+ id: string;
1126
+ displayName: string;
1127
+ aliases?: readonly string[];
1128
+ contextWindow?: number;
1129
+ capabilities?: readonly TProviderModelCapability[];
1130
+ lifecycle?: TProviderModelLifecycle;
1131
+ lastVerifiedAt?: string;
1132
+ sourceUrl?: string;
1133
+ /**
1134
+ * Per-model USD cost per input/output token (ARCH-PROVIDER-003). This is the correct SSOT home for
1135
+ * cost — it is a per-**model** attribute, not per-provider — consumed by cost-estimating nodes/commands
1136
+ * so pricing is not hardcoded in the execution layer. Both optional; absent means cost is unknown for
1137
+ * this model and estimators must degrade explicitly rather than assume a default price.
1138
+ */
1139
+ costPerInputToken?: number;
1140
+ costPerOutputToken?: number;
1141
+ }
1142
+ interface IProviderModelCatalog {
1143
+ status: TProviderModelCatalogStatus;
1144
+ entries?: readonly IProviderModelCatalogEntry[];
1145
+ lastVerifiedAt?: string;
1146
+ sourceUrl?: string;
1147
+ message?: string;
1148
+ }
1149
+ interface IProviderSetupStepDefinition {
1150
+ key: TProviderSetupField;
1151
+ title: string;
1152
+ defaultValue?: string;
1153
+ required?: boolean;
1154
+ masked?: boolean;
1155
+ }
1156
+ type TProviderCategory = 'cloud-paid' | 'cloud-free' | 'local-free';
1157
+ /**
1158
+ * Passive reachability declaration for diagnostics (OBSERVABILITY-1991).
1159
+ *
1160
+ * The host and port a pre-session doctor may TCP-probe when a profile declares no `baseURL` and the
1161
+ * definition declares no `defaults.baseURL` — the case for vendors whose SDK embeds its endpoint. It
1162
+ * is deliberately not a URL and not part of `defaults`: nothing in setup, persistence or provider
1163
+ * construction reads it, so declaring it cannot switch an API surface or persist a base URL. It is
1164
+ * distinct from `probeProfile`, which is an active HTTP probe.
1165
+ */
1166
+ interface IProviderEndpoint {
1167
+ readonly host: string;
1168
+ readonly port: number;
1169
+ }
1170
+ interface IProviderDefinition {
1171
+ type: string;
1172
+ aliases?: readonly string[];
1173
+ displayName?: string;
1174
+ description?: string;
1175
+ /** Billing/hosting category shown as a badge in provider selection UI. */
1176
+ category?: TProviderCategory;
1177
+ defaults?: IProviderProfileDefaults;
1178
+ /**
1179
+ * Optional enforced model allowlist (ARCH-PROVIDER-003). Distinct from {@link modelCatalog}: the catalog
1180
+ * is the *descriptive* model inventory (often `status:'unavailable'` with no entries), whereas
1181
+ * `allowedModels` is the *enforced* execution allowlist — a node rejects a requested model outside it.
1182
+ * When present it should be a subset/override consistent with `modelCatalog.entries[].id`, not a second
1183
+ * drifting inventory. Absent means no allowlist enforcement (any model the provider accepts is allowed).
1184
+ */
1185
+ allowedModels?: readonly string[];
1186
+ /**
1187
+ * INTERIM provider-level cost per token in USD (ARCH-PROVIDER-003), migrated verbatim from the per-vendor
1188
+ * LLM nodes' single `COST_PER_TOKEN_USD` scalar. The correct long-term home is the per-model
1189
+ * {@link IProviderModelCatalogEntry.costPerInputToken}/`costPerOutputToken`; this flat scalar is a
1190
+ * fidelity-preserving interim used only while model catalogs are `status:'unavailable'` (no per-model
1191
+ * entries to attach cost to). Consumed by the collapsed `llm-text` node's `maxCostUsd` estimation. Absent
1192
+ * means cost is unknown for this provider and estimators must degrade explicitly.
1193
+ */
1194
+ costPerTokenUsd?: number;
1195
+ modelCatalog?: IProviderModelCatalog;
1196
+ setupHelpLinks?: readonly IProviderSetupHelpLink[];
1197
+ setupSteps?: readonly IProviderSetupStepDefinition[];
1198
+ credentialRequirement?: IProviderCredentialRequirement;
1199
+ requiresApiKey?: boolean;
1200
+ /**
1201
+ * The environment variables this provider's client reads to decide where it connects or which
1202
+ * credential it sends, beyond its configuration (for example a base-URL variable the SDK falls
1203
+ * back to). A process that builds this provider from another process's configuration must see
1204
+ * the same values, or the credential goes somewhere its owner did not choose.
1205
+ */
1206
+ destinationEnvironment?: readonly string[];
1207
+ createProvider: (config: IProviderDefinitionConfig) => IAIProvider;
1208
+ probeProfile?: (profile: IProviderProfileConfig) => Promise<IProviderProbeResult>;
1209
+ /** Diagnostic-only reachability declaration; read by no setup, persistence or runtime path. */
1210
+ endpoint?: IProviderEndpoint;
1211
+ }
1212
+ /** The host owns secure persistence; core only admits its opaque reference. */
1213
+ interface IToolResultSpillStore {
1214
+ write(content: string): Promise<{
1215
+ readonly reference: string;
1216
+ }>;
1217
+ }
1218
+ interface IToolResultAdmissionOptions {
1219
+ readonly warningChars?: number;
1220
+ readonly hardChars?: number;
1221
+ readonly repositoryMaxChars?: number;
1222
+ readonly spillStore?: IToolResultSpillStore;
1223
+ readonly onWarning?: (event: {
1224
+ readonly toolName: string;
1225
+ readonly resultChars: number;
1226
+ readonly warningChars: number;
1227
+ }) => void;
1228
+ }
1229
+ //#endregion
1230
+ //#region src/permissions/types.d.ts
1231
+ /**
1232
+ * Permission system types — Claude Code compatible permission model.
1233
+ */
1234
+ /**
1235
+ * Permission modes (Claude Code compatible)
1236
+ * - plan: read-only tools only
1237
+ * - default: reads auto, writes/bash need approval
1238
+ * - acceptEdits: reads + writes auto, bash needs approval
1239
+ * - bypassPermissions: all tools auto
1240
+ * - auto: reads and in-workspace edits auto; anything else a model classifier decides, and a person
1241
+ * when the classifier keeps refusing
1242
+ */
1243
+ type TPermissionMode = 'plan' | 'default' | 'acceptEdits' | 'bypassPermissions' | 'auto';
1244
+ /** Context window state snapshot */
1245
+ interface IContextWindowState {
1246
+ /** Max tokens for the current model */
1247
+ maxTokens: number;
1248
+ /** Current estimated token usage (input + cache, excludes output) */
1249
+ usedTokens: number;
1250
+ /** Usage percentage (0-100) */
1251
+ usedPercentage: number;
1252
+ /** Remaining percentage (0-100) */
1253
+ remainingPercentage: number;
1254
+ }
1255
+ //#endregion
1256
+ //#region ../agent-interface-analytics/dist/node/index.d.ts
1257
+ //#region src/usage-contracts.d.ts
1258
+ /**
1259
+ * @robota-sdk/agent-interface-analytics — usage and run-trace contracts.
1260
+ *
1261
+ * Extracted from `agent-interface-transport`'s `session-contracts.ts` by ARCH-105 (issue #2112).
1262
+ *
1263
+ * This family was declared INSIDE another module rather than as a file of its own, which is why the
1264
+ * extraction split declarations rather than moving a whole file.
1265
+ *
1266
+ * LAYER 0, with an EMPTY dependency set — every field below is a primitive or another declaration in
1267
+ * this file, so the package needs nothing, not even `agent-core`. Consumers compose it downward.
1268
+ */
1269
+ /**
1270
+ * ANALYTICS-001: the execution unit a usage snapshot is attributed to, so session-log usage can be
1271
+ * reported and asserted per source (main thread vs a specific subagent / background task). A minimal
1272
+ * contract-layer descriptor — the framework's `IExecutionOrigin` lives a layer up and cannot be
1273
+ * imported here; the two stay aligned by `scope`/`id`.
1274
+ */
1275
+ interface IUsageSource {
1276
+ scope: 'main' | 'subagent' | 'background' | 'tool' | 'command' | 'skill';
1277
+ /** Stable id of the source (e.g. the subagent / background-task id); omitted for the main thread. */
1278
+ id?: string;
1279
+ /** Human label for reports (e.g. the agent type or task title). */
1280
+ label?: string;
1281
+ }
1282
+ //#endregion
1283
+ //#region ../agent-interface-command/dist/node/index.d.ts
1284
+ //#region src/capability-contracts.d.ts
1285
+ /**
1286
+ * Capability descriptor contracts — model-visible capability metadata.
1287
+ *
1288
+ * SSOT for the capability-safety taxonomy shared by command modules and transports.
1289
+ */
1290
+ type TCapabilityKind = 'builtin-command' | 'skill' | 'agent' | 'tool';
1291
+ type TCapabilitySafety = 'read-only' | 'write' | 'process' | 'network' | 'background-agent';
1292
+ interface ICapabilityDescriptor {
1293
+ readonly name: string;
1294
+ readonly kind: TCapabilityKind;
1295
+ readonly description: string;
1296
+ readonly userInvocable: boolean;
1297
+ readonly modelInvocable: boolean;
1298
+ readonly argumentHint?: string;
1299
+ readonly safety?: TCapabilitySafety;
1300
+ /** When false, the projected tool is auto-approved without prompting the user. */
1301
+ readonly requiresPermission?: boolean;
1302
+ }
1303
+ //#endregion
1304
+ //#region src/command-contracts.d.ts
1305
+ /**
1306
+ * Origin of a command invocation. `'user'` = the local operator; `'model'` = a model-invoked command;
1307
+ * `'remote'` = a command arriving over a transport (WebSocket / WebRTC) from an untrusted remote peer.
1308
+ * SSOT lives here (the transport-facing `IInteractiveSession.executeCommand` carries it); `agent-framework`
1309
+ * re-exports it. A transport-origin command runs as a local one by default; an optional policy may restrict (REMOTE-006).
1310
+ */
1311
+ type TCommandInvocationSource = 'user' | 'model' | 'remote';
1312
+ /** A command entry */
1313
+ interface ICommand {
1314
+ /** Command name without slash (e.g., "mode") — used for invocation */
1315
+ name: string;
1316
+ /** User-friendly display label (e.g., "Interaction Mode"). Falls back to `name` if not set. */
1317
+ displayName?: string;
1318
+ /** Short description shown in autocomplete */
1319
+ description: string;
1320
+ /** Optional usage example shown in /help output (e.g., "/compact Summarize the context"). */
1321
+ example?: string;
1322
+ /** Source identifier (e.g., "builtin", "skill") */
1323
+ source: string;
1324
+ /** Subcommands for hierarchical menus */
1325
+ subcommands?: ICommand[];
1326
+ /**
1327
+ * When true, the bare command is a complete action of its own (a default view), so choosing it
1328
+ * from a menu runs it rather than opening its subcommands. Declaring subcommands (for example to
1329
+ * narrow what the model may run) then does not change what the user's Enter does.
1330
+ */
1331
+ runsBare?: boolean;
1332
+ /** Execute the command. Args is everything after the command name. */
1333
+ execute?: (args: string) => void | Promise<void>;
1334
+ /** Full SKILL.md content (only for skill commands) */
1335
+ skillContent?: string;
1336
+ /** Hint for the expected argument (Claude Code frontmatter) */
1337
+ argumentHint?: string;
1338
+ /** When true, models cannot invoke this skill autonomously */
1339
+ disableModelInvocation?: boolean;
1340
+ /**
1341
+ * When true, models may invoke this command through the SDK-projected command tool.
1342
+ *
1343
+ * On a SUBCOMMAND entry it narrows what the model may run: once any subcommand of a
1344
+ * model-invocable command declares this flag, the model may run only the bare command and the
1345
+ * subcommands declared `true` — every other first argument, including an alias or a subcommand
1346
+ * added later without the flag, is refused. That is how a command that mixes read-only views with
1347
+ * trust, credential or permission-widening actions offers the model only the safe subset.
1348
+ */
1349
+ modelInvocable?: boolean;
1350
+ /**
1351
+ * What the model is told about this command, when it differs from the short `description` shown
1352
+ * in `/help`: what it does, when to use it, and what it returns. Absent → `description`.
1353
+ */
1354
+ modelDescription?: string;
1355
+ /** When false, users cannot invoke this skill directly */
1356
+ userInvocable?: boolean;
1357
+ /** Safety category for model-visible capability descriptors */
1358
+ safety?: TCapabilitySafety;
1359
+ /** List of tools this skill is allowed to use */
1360
+ allowedTools?: string[];
1361
+ /** Preferred model for executing this skill */
1362
+ model?: string;
1363
+ /** Effort level hint for the skill */
1364
+ effort?: TModelEffort;
1365
+ /** Context scope for the skill (e.g., "project") */
1366
+ context?: string;
1367
+ /** Agent identity to use when executing this skill */
1368
+ agent?: string;
1369
+ /** Plugin installation directory (plugin skills/commands only) */
1370
+ pluginDir?: string;
1371
+ }
1372
+ /** A source that provides commands */
1373
+ interface ICommandSource {
1374
+ name: string;
1375
+ getCommands(): ICommand[];
1376
+ }
1377
+ /** Status-line command settings persisted in the settings document. */
1378
+ interface IStatusLineCommandSettings {
1379
+ enabled: boolean;
1380
+ gitBranch: boolean;
1381
+ }
1382
+ type TStatusLineCommandSettingsPatch = Partial<IStatusLineCommandSettings> & Record<string, TUniversalValue>;
1383
+ /**
1384
+ * SCREEN-2002: the appearance a run renders with, persisted as three FLAT keys in the settings
1385
+ * document (`theme`, `syntaxHighlighting`, `reducedMotion`) rather than one nested object — the
1386
+ * shape `screenReader` and `outputStyle` already use, and the shape a user editing the file by hand
1387
+ * expects. The theme is named by ID, not by value: the settings document never holds a colour, so a
1388
+ * theme that is renamed or removed degrades to a notice instead of persisting stale colours.
1389
+ */
1390
+ interface IAppearanceSettings {
1391
+ /** A theme id the registry holds. An unknown id resolves to the default WITH a visible notice. */
1392
+ theme: string;
1393
+ /** Whether fenced code blocks are syntax-highlighted. Orthogonal to the theme. */
1394
+ syntaxHighlighting: boolean;
1395
+ /** Whether animation is suppressed. A flag or the environment can override this for one run. */
1396
+ reducedMotion: boolean;
1397
+ }
1398
+ type TAppearanceSettingsPatch = Partial<IAppearanceSettings> & Record<string, TUniversalValue>;
1399
+ /**
1400
+ * CMD-004 Phase 2: host-executed command ACTIONS — semantic operations the SESSION layer (the host)
1401
+ * executes via `ICommandHostAdapters` or directly on the session, BEFORE the command result is
1402
+ * returned. They execute with zero surfaces attached (headless parity — the LSP
1403
+ * `workspace/executeCommand` model); surfaces observe the outcome via session events / the result,
1404
+ * never by executing the semantics themselves.
1405
+ */
1406
+ type TCommandHostAction = {
1407
+ type: 'provider-hot-swap';
1408
+ profileName: string;
1409
+ } | {
1410
+ type: 'output-style-change';
1411
+ styleId: string;
1412
+ } | {
1413
+ type: 'language-change';
1414
+ language: string;
1415
+ } | {
1416
+ type: 'settings-reset';
1417
+ } | {
1418
+ type: 'session-exit';
1419
+ reason?: TSessionEndReason;
1420
+ message?: string;
1421
+ } | {
1422
+ type: 'session-restart';
1423
+ reason: TSessionEndReason;
1424
+ message: string;
1425
+ } | {
1426
+ type: 'session-rename';
1427
+ name: string;
1428
+ } |
1429
+ /** Move the session to another working directory (`/cd`); `path` is as the user typed it. */
1430
+ {
1431
+ type: 'workspace-move';
1432
+ path: string;
1433
+ } | {
1434
+ type: 'statusline-settings-patch';
1435
+ patch: TStatusLineCommandSettingsPatch;
1436
+ } | {
1437
+ type: 'appearance-settings-patch';
1438
+ patch: TAppearanceSettingsPatch;
1439
+ } | {
1440
+ type: 'remote-control-enable';
1441
+ } | {
1442
+ type: 'remote-control-stop';
1443
+ };
1444
+ /**
1445
+ * CMD-004 Phase 2: surface-rendered UI INTENTS — presentation requests (full-screen navigation)
1446
+ * rendered by the surface that issued the command (requester-routed via
1447
+ * `IUiIntentEvent.requesterDriverId`), fire-and-forget. Names are UI-neutral (LSP `window/show*`
1448
+ * style — never a UI-technology token); a surface that cannot render an intent reports an explicit
1449
+ * "not available on this surface" notice, never a silent drop.
1450
+ */
1451
+ type TCommandUiIntent = {
1452
+ type: 'show-plugin-manager';
1453
+ } | {
1454
+ type: 'show-settings';
1455
+ } | {
1456
+ type: 'show-session-picker';
1457
+ } | {
1458
+ type: 'show-agent-switcher';
1459
+ } | {
1460
+ type: 'show-theme-picker';
1461
+ };
1462
+ /** Result of a system command execution. */
1463
+ interface ICommandResult {
1464
+ /** Human-readable output message */
1465
+ message: string;
1466
+ /** Command completed successfully */
1467
+ success: boolean;
1468
+ /** Additional structured data (command-specific diagnostics only) */
1469
+ data?: Record<string, unknown>;
1470
+ /** CMD-004 Phase 2: host-executed actions — applied by the session layer before the result returns. */
1471
+ hostActions?: readonly TCommandHostAction[];
1472
+ /** CMD-004 Phase 2: UI intents — emitted as `ui_intent` session events routed to the requesting surface. */
1473
+ uiIntents?: readonly TCommandUiIntent[];
1474
+ }
1475
+ /** Minimal command projection surfaced to host UIs and autocomplete. */
1476
+ interface ICommandListEntry {
1477
+ name: string;
1478
+ /** User-friendly display label. Falls back to `name` if not set. */
1479
+ displayName?: string;
1480
+ description: string;
1481
+ /** Optional usage example shown in /help output (e.g., "/compact Summarize the context"). */
1482
+ example?: string;
1483
+ /**
1484
+ * SEC-008: whether a MODEL may invoke this command, carried through instead of dropped.
1485
+ *
1486
+ * The list used to stop at name/description, so every consumer received a flat catalogue with no
1487
+ * way to tell an operator-only command from a model-callable one. The MCP adapter read that list
1488
+ * and registered all of it as callable tools, which turned commands explicitly marked
1489
+ * `modelInvocable: false` — `plugin` installs and enables code — into things a remote peer's model
1490
+ * could call.
1491
+ *
1492
+ * REQUIRED rather than optional, because an optional flag would let a consumer read `undefined`
1493
+ * for two unrelated situations: "this command may not be model-invoked" and "the producer of this
1494
+ * list does not say". Those need different handling and the first must not be reached by accident.
1495
+ */
1496
+ modelInvocable: boolean;
1497
+ }
1498
+ type TPluginInstallScope = 'user' | 'project';
1499
+ interface ICommandInstalledPlugin {
1500
+ name: string;
1501
+ description: string;
1502
+ enabled: boolean;
1503
+ }
1504
+ interface ICommandAvailablePlugin {
1505
+ name: string;
1506
+ description: string;
1507
+ installed: boolean;
1508
+ }
1509
+ interface ICommandMarketplaceSource {
1510
+ name: string;
1511
+ type: string;
1512
+ }
1513
+ interface ICommandPluginReloadResult {
1514
+ loadedPluginCount: number;
1515
+ }
1516
+ interface ICommandPluginAdapter {
1517
+ listInstalled(): Promise<readonly ICommandInstalledPlugin[]>;
1518
+ listAvailablePlugins(marketplace: string): Promise<readonly ICommandAvailablePlugin[]>;
1519
+ install(pluginId: string, scope?: TPluginInstallScope): Promise<void>;
1520
+ uninstall(pluginId: string): Promise<void>;
1521
+ enable(pluginId: string): Promise<void>;
1522
+ disable(pluginId: string): Promise<void>;
1523
+ marketplaceAdd(source: string): Promise<string>;
1524
+ marketplaceRemove(name: string): Promise<void>;
1525
+ marketplaceUpdate(name: string): Promise<void>;
1526
+ marketplaceList(): Promise<readonly ICommandMarketplaceSource[]>;
1527
+ reloadPlugins(): Promise<ICommandPluginReloadResult>;
1528
+ }
1529
+ //#endregion
1530
+ //#region ../agent-interface-execution/dist/node/index.d.ts
1531
+ //#region src/background-task-contracts.d.ts
1532
+ type TBackgroundTaskKind = 'agent' | 'process' | 'scheduled' | 'tool-invocation';
1533
+ type TBackgroundTaskMode = 'foreground' | 'background';
1534
+ type TBackgroundTaskIsolation = 'none' | 'worktree';
1535
+ type TBackgroundTaskStatus = 'queued' | 'running' | 'waiting_permission' | 'sleeping' | 'paused' | 'completed' | 'failed' | 'cancelled';
1536
+ type TBackgroundTaskTimeoutReason = 'idle' | 'max_runtime' | 'output_limit' | 'repetition' | 'stale_worker';
1537
+ type TBackgroundTaskErrorCategory = 'validation' | 'capacity' | 'permission' | 'timeout' | 'runner' | 'crash' | 'provider' | 'process';
1538
+ type TBackgroundPrimitive = string | number | boolean;
1539
+ interface IBackgroundTaskError {
1540
+ category: TBackgroundTaskErrorCategory;
1541
+ message: string;
1542
+ recoverable: boolean;
1543
+ }
1544
+ /**
1545
+ * ANALYTICS-001 (Phase 2): token usage a completed task/subagent consumed, for source attribution.
1546
+ * TYPE-003: alias of the `agent-core` usage-triple SSOT (`ITokenUsage`) — derived, not re-declared.
1547
+ */
1548
+ type IBackgroundTaskUsage = ITokenUsage;
1549
+ interface IBaseBackgroundTaskResult {
1550
+ taskId: string;
1551
+ output: string;
1552
+ metadata?: Record<string, TBackgroundPrimitive>;
1553
+ }
1554
+ interface IAgentBackgroundTaskResult extends IBaseBackgroundTaskResult {
1555
+ kind: 'agent';
1556
+ /** ANALYTICS-001 (Phase 2): total token usage of an agent task, attributed to it in the parent log. */
1557
+ usage?: IBackgroundTaskUsage;
1558
+ }
1559
+ interface IProcessBackgroundTaskResult extends IBaseBackgroundTaskResult {
1560
+ kind: 'process';
1561
+ exitCode?: number;
1562
+ signalCode?: string;
1563
+ }
1564
+ interface IScheduledBackgroundTaskResult extends IBaseBackgroundTaskResult {
1565
+ kind: 'scheduled';
1566
+ }
1567
+ interface IToolInvocationBackgroundTaskResult extends IBaseBackgroundTaskResult {
1568
+ kind: 'tool-invocation';
1569
+ }
1570
+ /**
1571
+ * #2079: the outcome hop discriminates by kind exactly as the request hop
1572
+ * (`TBackgroundTaskRequest`) does — `exitCode`/`signalCode` are producible only by the process
1573
+ * runner and `usage` only by the agent runner (`ISubagentJobResult` is now
1574
+ * `Omit<IBackgroundTaskResult<'agent'>, 'kind'>`, not a hand-maintained `Omit` off the flat shape).
1575
+ * `IBackgroundTaskResult<K>` narrows to the kind-specific member for a caller that knows `K`
1576
+ * statically (a runner's `start()`, the decoder once it has
1577
+ * checked `kind`); called with no type argument it stays the full union. `IBackgroundTaskState<K>`
1578
+ * is discriminated the same way, and its `result` field is `IBackgroundTaskResult<K>` — correlated
1579
+ * with `state.kind`, not the free-standing full union.
1580
+ */
1581
+ type TBackgroundTaskResult = IAgentBackgroundTaskResult | IProcessBackgroundTaskResult | IScheduledBackgroundTaskResult | IToolInvocationBackgroundTaskResult;
1582
+ type IBackgroundTaskResult<K extends TBackgroundTaskKind = TBackgroundTaskKind> = Extract<TBackgroundTaskResult, {
1583
+ kind: K;
1584
+ }>;
1585
+ /**
1586
+ * #2079: the persisted/live state hop discriminates by kind exactly as the request and result hops
1587
+ * do. Fields a single runner alone can produce — `agentType`/`isolation`/`resumeSessionId`/
1588
+ * `promptPreview`/the worktree-isolation fields (agent), `schedule`/`nextFireAt` (scheduled) — live
1589
+ * only on that kind's member. `commandPreview` is produced by every runner except the agent one (a
1590
+ * process command, a tool-invocation summary, or a schedule's shell command / wake instruction), so
1591
+ * it stays on the three non-agent members, not the base. `pid`/`logPath`/`transcriptPath` stay on
1592
+ * the shared base: the handle SPI (`IBackgroundTaskHandle`) already reports them generically for
1593
+ * whichever runner's process happens to produce them, and a subagent run as a child process (the
1594
+ * worktree-isolation runner) carries a `pid` exactly as a `process`-kind task does — an audit of
1595
+ * every producer (`background-task-manager-helpers.ts`, `subagent-manager.ts`,
1596
+ * `worktree-subagent-runner.ts`) found no case of an agent/process pid being kind-exclusive.
1597
+ * `timeoutReason` is likewise base: `interactive-session-restore.ts` sets `'stale_worker'` on ANY
1598
+ * non-terminal, non-rearmable task regardless of kind, not only on agent tasks.
1599
+ */
1600
+ interface IBaseBackgroundTaskState<K extends TBackgroundTaskKind> {
1601
+ id: string;
1602
+ kind: K;
1603
+ label: string;
1604
+ status: TBackgroundTaskStatus;
1605
+ mode: TBackgroundTaskMode;
1606
+ parentSessionId: string;
1607
+ parentTaskId?: string;
1608
+ depth: number;
1609
+ cwd: string;
1610
+ pid?: number;
1611
+ startedAt?: string;
1612
+ updatedAt: string;
1613
+ lastActivityAt?: string;
1614
+ completedAt?: string;
1615
+ currentAction?: string;
1616
+ unread: boolean;
1617
+ result?: IBackgroundTaskResult<K>;
1618
+ error?: IBackgroundTaskError;
1619
+ logPath?: string;
1620
+ transcriptPath?: string;
1621
+ timeoutReason?: TBackgroundTaskTimeoutReason;
1622
+ metadata?: Record<string, TBackgroundPrimitive>;
1623
+ }
1624
+ interface IAgentBackgroundTaskState extends IBaseBackgroundTaskState<'agent'> {
1625
+ agentType?: string;
1626
+ promptPreview?: string;
1627
+ isolation?: TBackgroundTaskIsolation;
1628
+ /**
1629
+ * CLI-1994: carried from `IAgentBackgroundTaskRequest.resumeSessionId` so a surface can offer to
1630
+ * ATTACH to the forked session — a view switch onto that record, never a merge with the parent.
1631
+ */
1632
+ resumeSessionId?: string;
1633
+ worktreePath?: string;
1634
+ branchName?: string;
1635
+ worktreeStatus?: string;
1636
+ worktreeNextAction?: string;
1637
+ worktreeBaseRevision?: string;
1638
+ parentWorktreeStatus?: string;
1639
+ }
1640
+ interface IProcessBackgroundTaskState extends IBaseBackgroundTaskState<'process'> {
1641
+ commandPreview?: string;
1642
+ }
1643
+ interface IScheduledBackgroundTaskState extends IBaseBackgroundTaskState<'scheduled'> {
1644
+ commandPreview?: string;
1645
+ nextFireAt?: string;
1646
+ /**
1647
+ * FLOW-003: for `kind: 'scheduled'` tasks, the reconstructable schedule definition.
1648
+ * Persisted with the task so a resumed session can re-arm the croner job.
1649
+ */
1650
+ schedule?: IBackgroundTaskSchedule;
1651
+ }
1652
+ interface IToolInvocationBackgroundTaskState extends IBaseBackgroundTaskState<'tool-invocation'> {
1653
+ commandPreview?: string;
1654
+ }
1655
+ type TBackgroundTaskState = IAgentBackgroundTaskState | IProcessBackgroundTaskState | IScheduledBackgroundTaskState | IToolInvocationBackgroundTaskState;
1656
+ type IBackgroundTaskState<K extends TBackgroundTaskKind = TBackgroundTaskKind> = Extract<TBackgroundTaskState, {
1657
+ kind: K;
1658
+ }>;
1659
+ /** FLOW-003: the persisted, reconstructable definition of a scheduled wake. */
1660
+ interface IBackgroundTaskSchedule {
1661
+ cronExpression: string;
1662
+ agentInstruction?: string;
1663
+ command?: string;
1664
+ shell?: string;
1665
+ env?: Record<string, string>;
1666
+ }
1667
+ interface IBackgroundTaskLogCursor {
1668
+ offset: number;
1669
+ }
1670
+ interface IBackgroundTaskLogPage {
1671
+ taskId: string;
1672
+ cursor?: IBackgroundTaskLogCursor;
1673
+ nextCursor?: IBackgroundTaskLogCursor;
1674
+ lines: string[];
1675
+ }
1676
+ interface IBackgroundTaskListFilter {
1677
+ kind?: TBackgroundTaskKind;
1678
+ status?: TBackgroundTaskStatus;
1679
+ mode?: TBackgroundTaskMode;
1680
+ includeClosed?: boolean;
1681
+ }
1682
+ type TBackgroundTaskEvent = {
1683
+ type: 'background_task_created';
1684
+ task: IBackgroundTaskState;
1685
+ } | {
1686
+ type: 'background_task_started';
1687
+ task: IBackgroundTaskState;
1688
+ } | {
1689
+ type: 'background_task_updated';
1690
+ task: IBackgroundTaskState;
1691
+ } | {
1692
+ type: 'background_task_text_delta';
1693
+ taskId: string;
1694
+ delta: string;
1695
+ } | {
1696
+ type: 'background_task_tool_start';
1697
+ taskId: string;
1698
+ toolName: string;
1699
+ firstArg?: string;
1700
+ } | {
1701
+ type: 'background_task_tool_end';
1702
+ taskId: string;
1703
+ toolName: string;
1704
+ success: boolean;
1705
+ error?: string;
1706
+ } | {
1707
+ type: 'background_task_permission_request';
1708
+ taskId: string;
1709
+ requestId: string;
1710
+ toolName: string;
1711
+ toolArgs: Record<string, TBackgroundPrimitive>;
1712
+ } | {
1713
+ type: 'background_task_completed';
1714
+ task: IBackgroundTaskState;
1715
+ } | {
1716
+ type: 'background_task_failed';
1717
+ task: IBackgroundTaskState;
1718
+ } | {
1719
+ type: 'background_task_cancelled';
1720
+ task: IBackgroundTaskState;
1721
+ } | {
1722
+ type: 'background_task_closed';
1723
+ taskId: string;
1724
+ } | {
1725
+ type: 'background_task_waking';
1726
+ taskId: string;
1727
+ instruction?: string;
1728
+ };
1729
+ //#endregion
1730
+ //#region src/background-group-contracts.d.ts
1731
+ type TBackgroundJobWaitPolicy = 'detached' | 'wait_all' | 'wait_any' | 'manual';
1732
+ type TBackgroundJobGroupStatus = 'running' | 'completed';
1733
+ interface IBackgroundJobResultEnvelope {
1734
+ taskId: string;
1735
+ label: string;
1736
+ status: TBackgroundTaskStatus;
1737
+ summary?: string;
1738
+ outputRef?: string;
1739
+ error?: IBackgroundTaskError;
1740
+ startedAt?: string;
1741
+ completedAt?: string;
1742
+ }
1743
+ interface IBackgroundJobGroupState {
1744
+ id: string;
1745
+ parentSessionId: string;
1746
+ waitPolicy: TBackgroundJobWaitPolicy;
1747
+ taskIds: string[];
1748
+ status: TBackgroundJobGroupStatus;
1749
+ createdAt: string;
1750
+ updatedAt: string;
1751
+ label?: string;
1752
+ completedAt?: string;
1753
+ results: IBackgroundJobResultEnvelope[];
1754
+ }
1755
+ interface IBackgroundJobGroupCreateRequest {
1756
+ parentSessionId: string;
1757
+ waitPolicy: TBackgroundJobWaitPolicy;
1758
+ taskIds: string[];
1759
+ label?: string;
1760
+ }
1761
+ type TBackgroundJobGroupEvent = {
1762
+ type: 'background_job_group_created';
1763
+ group: IBackgroundJobGroupState;
1764
+ } | {
1765
+ type: 'background_job_group_updated';
1766
+ group: IBackgroundJobGroupState;
1767
+ } | {
1768
+ type: 'background_job_group_completed';
1769
+ group: IBackgroundJobGroupState;
1770
+ };
1771
+ //#endregion
1772
+ //#region src/subagent-contracts.d.ts
1773
+ /**
1774
+ * TYPE-003: derived from the background-task status SSOT ({@link TBackgroundTaskStatus}) instead of
1775
+ * a second hand-maintained union — a status added to the SSOT now flows here mechanically (the
1776
+ * prior manual copy silently missed `paused` when SELFHOST-012 added it). `paused` is excluded on
1777
+ * purpose: it is a scheduled-task-only status and a subagent is never a scheduled task
1778
+ * (`SubagentManager.toSubagentState` maps it to `sleeping`).
1779
+ */
1780
+ type TSubagentJobStatus = Exclude<TBackgroundTaskStatus, 'paused'>;
1781
+ /**
1782
+ * Subagent-job projection of {@link IBackgroundTaskState}.
1783
+ *
1784
+ * TYPE-003: every field a subagent job shares with the background-task SSOT is derived via `Pick`
1785
+ * (previously a ~20-field manual mirror that could drift silently). Only the genuinely
1786
+ * subagent-specific fields are declared here:
1787
+ * - `type` — the agent-definition type (the task-side counterpart is the optional `agentType`);
1788
+ * - `status` — the derived {@link TSubagentJobStatus} (no `paused`);
1789
+ * - `promptPreview` — required here (every subagent job is created from a prompt; optional on tasks);
1790
+ * - `currentTool` — the job-level projection of the task's free-form `currentAction`;
1791
+ * - `result`/`error` — flattened display strings (the task carries structured
1792
+ * `IBackgroundTaskResult`/`IBackgroundTaskError` objects).
1793
+ */
1794
+ interface ISubagentJobState extends Pick<IBackgroundTaskState<'agent'>, 'id' | 'label' | 'parentSessionId' | 'mode' | 'depth' | 'pid' | 'cwd' | 'isolation' | 'resumeSessionId' | 'worktreePath' | 'branchName' | 'worktreeStatus' | 'worktreeNextAction' | 'worktreeBaseRevision' | 'parentWorktreeStatus' | 'logPath' | 'transcriptPath' | 'startedAt' | 'updatedAt' | 'completedAt' | 'timeoutReason' | 'metadata'> {
1795
+ type: string;
1796
+ status: TSubagentJobStatus;
1797
+ promptPreview: string;
1798
+ currentTool?: string;
1799
+ result?: string;
1800
+ error?: string;
1801
+ }
1802
+ //#endregion
1803
+ //#region ../agent-interface-session/dist/node/session-contracts-BVCzd3uY.d.ts
1804
+ //#endregion
1805
+ //#region src/session-loop-contracts.d.ts
1806
+ /** A self-paced loop's durable lifecycle, independent of its disposable wake timer. */
1807
+ type TSessionLoopPhase = 'waiting' | 'pending' | 'running' | 'stopped' | 'expired';
1808
+ /** Session-owned state needed to resume without replaying an uncertain iteration. */
1809
+ interface ISessionLoopState {
1810
+ loopId: string;
1811
+ instruction: string;
1812
+ /** Omitted prompts are re-resolved by the host before each iteration. */
1813
+ useDefaultPrompt?: boolean;
1814
+ createdAt: string;
1815
+ expiresAt: string;
1816
+ /** Monotonic change counter, used to reconcile an ambiguous store write. */
1817
+ revision: number;
1818
+ /** Incremented whenever a new opportunity to run is committed. */
1819
+ generation: number;
1820
+ phase: TSessionLoopPhase;
1821
+ /** Required while waiting; absent once that opportunity has been consumed. */
1822
+ nextAllowedAt?: string;
1823
+ /** Last committed choice, in the 1 minute–1 hour self-paced range. */
1824
+ delaySeconds?: number;
1825
+ reason?: string;
1826
+ /** Once consumed, an omitted decision cannot produce another fallback. */
1827
+ fallbackUsed: boolean;
1828
+ terminalReason?: string;
1829
+ }
1830
+ //#endregion
1831
+ //#region src/event-contracts.d.ts
1832
+ type TSkillActivationSource = 'skill' | 'plugin';
1833
+ type TSkillActivationInvocation = 'user-slash' | 'model-tool';
1834
+ type TSkillActivationMode = 'inject' | 'fork';
1835
+ type TSkillActivationStatus = 'started' | 'completed' | 'failed';
1836
+ interface ISkillActivationEvent {
1837
+ readonly type: 'skill-activation';
1838
+ readonly skillName: string;
1839
+ readonly source: TSkillActivationSource;
1840
+ readonly invocation: TSkillActivationInvocation;
1841
+ readonly mode: TSkillActivationMode;
1842
+ readonly status: TSkillActivationStatus;
1843
+ readonly timestamp: string;
1844
+ readonly qualifiedName?: string;
1845
+ readonly error?: string;
1846
+ }
1847
+ type TMemoryType = 'user' | 'feedback' | 'project' | 'reference';
1848
+ interface IMemoryReference {
1849
+ topic: string;
1850
+ path: string;
1851
+ score: number;
1852
+ truncated: boolean;
1853
+ }
1854
+ interface IMemoryEvent {
1855
+ type: 'memory_candidate_extracted' | 'memory_candidate_queued' | 'memory_candidate_saved' | 'memory_candidate_skipped' | 'memory_candidate_approved' | 'memory_candidate_rejected' | 'memory_retrieved';
1856
+ at: string;
1857
+ candidateId?: string;
1858
+ topic?: string;
1859
+ reason?: string;
1860
+ data?: Record<string, TUniversalValue>;
1861
+ }
1862
+ type TContextReferenceLoadType = 'manual' | 'prompt-reference' | 'system';
1863
+ type TContextReferenceStatus = 'active' | 'observed';
1864
+ interface IContextReferenceItem {
1865
+ id: string;
1866
+ sourcePath: string;
1867
+ relativePath: string;
1868
+ originalReference: string;
1869
+ loadType: TContextReferenceLoadType;
1870
+ status: TContextReferenceStatus;
1871
+ byteLength: number;
1872
+ loadedAt: string;
1873
+ lastUsedAt?: string;
1874
+ }
1875
+ /**
1876
+ * SELFHOST-007: the persisted active-branch pointer — added to the resumable session record (beside
1877
+ * `goal`) so a branch survives `--resume`. Pure data. The branch TREE persists in the agent-framework
1878
+ * checkpoint manifest; a resume whose pointer references a `branchId`/`checkpointId` absent from that
1879
+ * manifest store must degrade gracefully (fall back to the linear HEAD), not crash.
1880
+ */
1881
+ interface IActiveBranchPointer {
1882
+ branchId: string;
1883
+ checkpointId: string;
1884
+ }
1885
+ /**
1886
+ * Lifecycle status of an autonomous goal (GOAL-001).
1887
+ * `active` while the agent is pursuing it; terminal otherwise.
1888
+ */
1889
+ type TGoalStatus = 'active' | 'satisfied' | 'stopped';
1890
+ /**
1891
+ * Why an autonomous goal stopped (GOAL-001). `satisfied` = the agent signalled completion;
1892
+ * `max-iterations` = the turn budget was exhausted; `cancelled` = the user stopped it;
1893
+ * `no-progress` = consecutive idle turns detected a stall (convergence guard).
1894
+ */
1895
+ type TGoalStopReason = 'satisfied' | 'max-iterations' | 'cancelled' | 'no-progress';
1896
+ /** One recorded iteration of goal pursuit (GOAL-001). */
1897
+ interface IGoalProgressEntry {
1898
+ iteration: number;
1899
+ signal: 'continue' | 'satisfied';
1900
+ reason: string;
1901
+ }
1902
+ /**
1903
+ * Persisted state of an autonomous objective-pursuit loop (GOAL-001). Stored in the session
1904
+ * record so an in-flight goal survives `--resume`.
1905
+ */
1906
+ interface IGoalState {
1907
+ id: string;
1908
+ objective: string;
1909
+ status: TGoalStatus;
1910
+ stopReason?: TGoalStopReason;
1911
+ iterations: number;
1912
+ maxIterations: number;
1913
+ startedAt: string;
1914
+ progress: IGoalProgressEntry[];
1915
+ }
1916
+ /** Execution status of one plan step (SELFHOST-002 plan-mode). */
1917
+ type TPlanStepStatus = 'pending' | 'in-progress' | 'done';
1918
+ /** One reviewable step in a plan artifact (SELFHOST-002 plan-mode). */
1919
+ interface IPlanStep {
1920
+ /** Stable id within the plan. */
1921
+ id: string;
1922
+ /** Human-readable description of the step. */
1923
+ description: string;
1924
+ /** Step status as the plan is executed. */
1925
+ status: TPlanStepStatus;
1926
+ }
1927
+ /**
1928
+ * Lifecycle phase of a plan artifact (SELFHOST-002). `planning` = drafted in `plan` mode (read-only
1929
+ * tools); `awaiting-approval` = presented for review; `executing` = approved, edits unblocked per
1930
+ * `acceptEdits` (shell still per-call confirmed); `completed` = finished (mode reverts to `plan`).
1931
+ */
1932
+ type TPlanPhase = 'planning' | 'awaiting-approval' | 'executing' | 'completed';
1933
+ /**
1934
+ * A reviewable plan/todo artifact produced during plan mode (SELFHOST-002). Persisted in the
1935
+ * session record beside {@link IGoalState} so an in-flight plan survives resume. Pure data — the
1936
+ * mutation block stays the existing `plan` permission mode (no artifact-carried enforcement).
1937
+ */
1938
+ interface IPlanArtifact {
1939
+ id: string;
1940
+ /** The objective the plan addresses. */
1941
+ objective: string;
1942
+ /** The ordered plan steps. */
1943
+ steps: IPlanStep[];
1944
+ /** Current lifecycle phase. */
1945
+ phase: TPlanPhase;
1946
+ createdAt: string;
1947
+ /** Set when the plan was approved (phase → `executing`). */
1948
+ approvedAt?: string;
1949
+ }
1950
+ /** Persisted record for a resumable interactive session. */
1951
+ interface IInteractiveSessionRecord {
1952
+ id: string;
1953
+ name?: string;
1954
+ cwd: string;
1955
+ createdAt: string;
1956
+ updatedAt: string;
1957
+ messages: TUniversalMessage[];
1958
+ history?: IHistoryEntry[];
1959
+ systemPrompt?: string;
1960
+ toolSchemas?: IToolSchema[];
1961
+ backgroundTasks?: IBackgroundTaskState[];
1962
+ backgroundTaskEvents?: TBackgroundTaskEvent[];
1963
+ backgroundJobGroups?: IBackgroundJobGroupState[];
1964
+ backgroundJobGroupEvents?: TBackgroundJobGroupEvent[];
1965
+ sessionLoops?: ISessionLoopState[];
1966
+ skillActivationEvents?: ISkillActivationEvent[];
1967
+ memoryEvents?: IMemoryEvent[];
1968
+ usedMemoryReferences?: IMemoryReference[];
1969
+ contextReferences?: IContextReferenceItem[];
1970
+ sandboxSnapshotId?: string;
1971
+ /** In-flight autonomous goal, persisted so it survives resume (GOAL-001). */
1972
+ goal?: IGoalState;
1973
+ /** In-flight plan artifact, persisted so it survives resume (SELFHOST-002 plan-mode). */
1974
+ plan?: IPlanArtifact;
1975
+ /** Active checkpoint branch pointer, persisted so a branch survives resume (SELFHOST-007). */
1976
+ activeBranch?: IActiveBranchPointer;
1977
+ }
1978
+ //#endregion
1979
+ //#region ../agent-executor/dist/node/index.d.ts
1980
+ /** SELFHOST-012: an in-place schedule edit — any provided field replaces the current value; identity is kept. */
1981
+ interface IScheduleEditPatch {
1982
+ cronExpression?: string;
1983
+ agentInstruction?: string;
1984
+ command?: string;
1985
+ /** CMD-009: the list-view label summarizes the instruction, so an edit may refresh it too. */
1986
+ label?: string;
1987
+ }
1988
+ //#endregion
1989
+ //#region ../agent-core/dist/node/node.d.ts
1990
+ //#endregion
1991
+ //#region src/utils/egress-policy.d.ts
1992
+ type TEgressLookup = (hostname: string) => Promise<readonly string[]>;
1993
+ interface IEgressPolicy {
1994
+ /** Exact lowercase hostnames that may be reached even when they resolve to a private address. */
1995
+ readonly allowedHosts?: readonly string[];
1996
+ /** Explicit enterprise opt-out from private/loopback/metadata blocking. Default `false`. */
1997
+ readonly allowPrivateAddresses?: boolean;
1998
+ /** Redirect hops followed before refusing. Default 5. */
1999
+ readonly maxRedirects?: number;
2000
+ }
2001
+ //#endregion
2002
+ //#region ../agent-session/dist/node/index.d.ts
2003
+ type TAutoCompactThreshold = number | false;
2004
+ //#endregion
2005
+ //#region src/permission-denial-log.d.ts
2006
+ /**
2007
+ * Why a call was refused:
2008
+ * - `policy` — the gate answered deny: a deny rule, a background ceiling, or plan mode;
2009
+ * - `user` — a person was asked and declined, or the turn was cancelled while asking;
2010
+ * - `no-approver` — the call needed a person and none was attached;
2011
+ * - `classifier` — in `auto` mode, the classifier blocked the call or gave no usable verdict.
2012
+ */
2013
+ type TPermissionDenialReason = 'policy' | 'user' | 'no-approver' | 'classifier';
2014
+ interface IPermissionDenial {
2015
+ readonly toolName: string;
2016
+ /** The argument the tool's permission profile names (command, path, URL), when it has one. */
2017
+ readonly argument?: string;
2018
+ readonly reason: TPermissionDenialReason;
2019
+ /** The classifier's reason, for a `classifier` denial. */
2020
+ readonly detail?: string;
2021
+ /** Epoch milliseconds. */
2022
+ readonly at: number;
2023
+ }
2024
+ //#endregion
2025
+ //#region src/session-log-validation.d.ts
2026
+ interface ISessionReplayValidationIssue {
2027
+ code: 'PROVIDER_RESPONSE_RAW_MISSING' | 'PROVIDER_NATIVE_RAW_PAYLOAD_MISSING' | 'PROVIDER_RESPONSE_NORMALIZED_MISSING' | 'TOOL_RESULT_MISSING' | 'PAYLOAD_REFERENCE_INVALID' | 'UNRESOLVED_REPLAY_PAYLOAD';
2028
+ message: string;
2029
+ eventIndex?: number;
2030
+ executionId?: string;
2031
+ round?: number;
2032
+ toolCallId?: string;
2033
+ }
2034
+ interface ISessionReplayValidationResult {
2035
+ ok: boolean;
2036
+ issues: ISessionReplayValidationIssue[];
2037
+ }
2038
+ //#endregion
2039
+ //#region ../agent-interface-session-mobility/dist/node/index.d.ts
2040
+ /**
2041
+ * How two sessions' workspaces relate. `unknown` covers a session outside git, one that published no
2042
+ * claim, and a claim whose path did not read back as claimed — a claim is checked, never taken as
2043
+ * written.
2044
+ */
2045
+ type TWorkspaceRelation = 'same-worktree' | 'same-repo' | 'different-repo' | 'unknown';
2046
+ //#endregion
2047
+ //#region ../agent-framework/dist/node/createInteractiveRuntime-GD7gJ7ig.d.ts
2048
+ //#region src/effort/effort-resolution.d.ts
2049
+ type TEffortSelection = TModelEffort | 'auto';
2050
+ type TEffortSource = 'command' | 'flag' | 'environment' | 'settings' | 'preset' | 'model-default';
2051
+ type TEffortDisposition = 'applied' | 'model-default' | 'clamped' | 'not-applied';
2052
+ interface IModelEffortResolution {
2053
+ readonly requested: TEffortSelection;
2054
+ readonly effective: TModelEffort;
2055
+ readonly source: TEffortSource;
2056
+ readonly disposition: TEffortDisposition;
2057
+ readonly modelDefault: TModelEffort;
2058
+ readonly reason?: string;
2059
+ }
2060
+ interface IEditCheckpointSummary {
2061
+ id: string;
2062
+ sessionId: string;
2063
+ sequence: number;
2064
+ prompt: string;
2065
+ createdAt: string;
2066
+ fileCount: number;
2067
+ }
2068
+ type TEditCheckpointFileRestoreAction = 'restore-preimage' | 'delete-created-file';
2069
+ interface IEditCheckpointFileInspection {
2070
+ originalPath: string;
2071
+ relativePath: string;
2072
+ existed: boolean;
2073
+ restoreAction: TEditCheckpointFileRestoreAction;
2074
+ snapshotAvailable: boolean;
2075
+ snapshotSizeBytes?: number;
2076
+ }
2077
+ interface IEditCheckpointInspectionPlan {
2078
+ checkpointIds: string[];
2079
+ fileCount: number;
2080
+ }
2081
+ interface IEditCheckpointInspection {
2082
+ target: IEditCheckpointSummary;
2083
+ capturedFiles: IEditCheckpointFileInspection[];
2084
+ restoreToCheckpoint: IEditCheckpointInspectionPlan;
2085
+ rollbackThroughCheckpoint: IEditCheckpointInspectionPlan;
2086
+ }
2087
+ interface IEditCheckpointRestoreResult {
2088
+ target: IEditCheckpointSummary;
2089
+ restoredCheckpointCount: number;
2090
+ restoredFileCount: number;
2091
+ removedCheckpointCount: number;
2092
+ }
2093
+ //#endregion
2094
+ //#region src/command-api/host-context-types.d.ts
2095
+ interface ICommandSkillListEntry {
2096
+ readonly name: string;
2097
+ readonly description: string;
2098
+ readonly source: string;
2099
+ readonly modelInvocable: boolean;
2100
+ readonly userInvocable: boolean;
2101
+ readonly argumentHint?: string;
2102
+ readonly context?: string;
2103
+ readonly agent?: string;
2104
+ }
2105
+ interface ICommandSkillActivationRequest {
2106
+ readonly invocationSource: TCommandInvocationSource;
2107
+ readonly displayInput?: string;
2108
+ readonly rawInput?: string;
2109
+ }
2110
+ type TAutoCompactThresholdSource = 'default' | 'settings' | 'session';
2111
+ /**
2112
+ * Live model re-application options (PRESET-013). Carries the model group a preset switch may
2113
+ * re-apply to a running session; `maxOutputTokens` maps to the agent's `maxTokens` channel.
2114
+ */
2115
+ interface IModelReapplyOptions {
2116
+ model?: string;
2117
+ effort?: TModelEffortSelection;
2118
+ temperature?: number;
2119
+ maxOutputTokens?: number;
2120
+ }
2121
+ /**
2122
+ * A preset `enabledCommandModules`/`disabledCommandModules` name that matched no built command
2123
+ * module (INFRA-032). Surfaced as a non-fatal notice on both the startup `--preset` path and the
2124
+ * in-session `/preset` path instead of being silently dropped. `kind` records which list the
2125
+ * unmatched name came from.
2126
+ */
2127
+ interface IUnknownCommandModuleName {
2128
+ readonly name: string;
2129
+ readonly kind: 'enabled' | 'disabled';
2130
+ }
2131
+ interface ICommandSessionReplayValidationReport {
2132
+ logFile: string;
2133
+ entryCount: number;
2134
+ validation: ISessionReplayValidationResult;
2135
+ }
2136
+ //#endregion
2137
+ //#region src/command-api/session-roles.d.ts
2138
+ /** Reading and clearing the conversation the session holds. */
2139
+ interface ICommandSessionHistory {
2140
+ clearHistory(): void;
2141
+ getMessageCount(): number;
2142
+ getFullHistory(): IHistoryEntry[];
2143
+ getHistory(): TUniversalMessage[];
2144
+ }
2145
+ /** The session's context window and its compaction policy. */
2146
+ interface ICommandSessionContextWindow {
2147
+ compact(instructions?: string): Promise<void>;
2148
+ getContextState(): IContextWindowState;
2149
+ getAutoCompactThreshold(): number | false;
2150
+ setAutoCompactThreshold(threshold: TAutoCompactThreshold): void;
2151
+ }
2152
+ /** What the session is currently permitted to do. */
2153
+ interface ICommandSessionPermissions {
2154
+ getPermissionMode(): TPermissionMode;
2155
+ setPermissionMode(mode: TPermissionMode): void;
2156
+ getSessionAllowedTools(): readonly string[];
2157
+ /** The allow/deny/ask rules the gate reads right now, whatever layer or preset supplied them. */
2158
+ getPermissionRules(): {
2159
+ readonly allow: readonly string[];
2160
+ readonly deny: readonly string[];
2161
+ readonly ask: readonly string[];
2162
+ };
2163
+ /** The calls this session refused, most recent first. */
2164
+ getRecentPermissionDenials(): readonly IPermissionDenial[];
2165
+ /** Let the call behind a classifier denial (0-based) run once; `undefined` when there is none. */
2166
+ retryPermissionDenial(index: number): IPermissionDenial | undefined;
2167
+ /**
2168
+ * ARCH-040 Group C (issue #1934): re-apply a preset's tool lists to the LIVE enforcer.
2169
+ *
2170
+ * REQUIRED, not optional. An optional member would let every consumer invent its own answer for an
2171
+ * absent one, and the answer here governs permissions — a runtime that quietly did nothing would
2172
+ * be the startup/live divergence this seam exists to close, wearing a different hat.
2173
+ *
2174
+ * Without it the startup path could apply a preset's tool lists and `/preset` could not: one
2175
+ * session holding two answers for the same preset depending on WHEN it was chosen.
2176
+ */
2177
+ applyPresetToolLists(preset: {
2178
+ allowedTools?: readonly string[];
2179
+ deniedTools?: readonly string[];
2180
+ }): void;
2181
+ }
2182
+ /**
2183
+ * The tool schemas this session puts in front of the model (CLI-1990).
2184
+ *
2185
+ * The OFFERED set, not the registered one: with deferral engaged, a withheld tool's schema never
2186
+ * reaches the request, and `/context` reports what the request actually costs. Reading it is how the
2187
+ * saving deferral produces becomes observable at all — before this, no surface separated the tool
2188
+ * schemas from the system prompt they are billed alongside.
2189
+ */
2190
+ interface ICommandSessionTools {
2191
+ getOfferedToolSchemas(): IToolSchema[];
2192
+ /**
2193
+ * Offer tools that became usable mid-session — an MCP server connected after its sign-in — from
2194
+ * the next turn on (never within a running turn), under the same wrappers and permission gate as
2195
+ * the session's own. A name the session already has is left out, never replaced. Resolves to the
2196
+ * names that will be offered.
2197
+ */
2198
+ addTools(tools: readonly IToolWithEventService[]): Promise<readonly string[]>;
2199
+ }
2200
+ /** Who this session is, and what it has spent. */
2201
+ interface ICommandSessionIdentity {
2202
+ getSessionId(): string;
2203
+ getSessionTokenUsage(): {
2204
+ inputTokens: number;
2205
+ outputTokens: number;
2206
+ } | undefined;
2207
+ getModelId(): string | undefined;
2208
+ }
2209
+ /** Live model reconfiguration. */
2210
+ interface ICommandSessionModel {
2211
+ /**
2212
+ * Re-apply model/effort/temperature/maxOutputTokens to the live session (PRESET-013).
2213
+ * May be async: the runtime ensures the agent is fully initialized before mutating its model
2214
+ * configuration, so callers must await the result.
2215
+ */
2216
+ applyModelOptions(options: IModelReapplyOptions): void | Promise<void>;
2217
+ /** Read the model-effort selection for the next model call. */
2218
+ getModelEffort(): TModelEffortSelection;
2219
+ /**
2220
+ * ARCH-040 — re-apply the preset's `agentName` to the live agent.
2221
+ *
2222
+ * REQUIRED, like every other member of this role port: an optional one would make each consumer
2223
+ * decide what "no rename seam" means, and `/preset` would decide it alone.
2224
+ */
2225
+ applyAgentName(name: string): void | Promise<void>;
2226
+ }
2227
+ /** Live preset state carried by the session. */
2228
+ interface ICommandSessionPreset {
2229
+ /** Read the active preset id (PRESET-011 runtime state). */
2230
+ getActivePresetId(): string;
2231
+ /** Set the active preset id (PRESET-011 runtime state — pure state, no option re-application). */
2232
+ setActivePresetId(id: string): void;
2233
+ /** Toggle subagent dispatch live for the running session (PRESET-016 runtime gate). */
2234
+ setParallelSubagentsEnabled(enabled: boolean): void;
2235
+ }
2236
+ /** Aggregate: every member remains source-compatible. Declare a role port instead of this. */
2237
+ interface ICommandSessionRuntime extends ICommandSessionHistory, ICommandSessionContextWindow, ICommandSessionPermissions, ICommandSessionIdentity, ICommandSessionModel, ICommandSessionPreset, ICommandSessionTools {}
2238
+ //#endregion
2239
+ //#region src/command-api/session/session-usage.d.ts
2240
+ interface ISessionUsageRecord {
2241
+ readonly promptTokens: number;
2242
+ readonly completionTokens: number;
2243
+ /** Present when the usage was priced on the model that produced it. */
2244
+ readonly costUsd?: number;
2245
+ /** Who spent it; absent for the main thread. */
2246
+ readonly source?: IUsageSource;
2247
+ }
2248
+ //#endregion
2249
+ //#region src/command-api/agent-job-roles.d.ts
2250
+ /** Starting, steering and ending subagent jobs. */
2251
+ interface IAgentJobDispatch {
2252
+ listAgentDefinitions(): Array<{
2253
+ name: string;
2254
+ description: string;
2255
+ }>;
2256
+ listAgentJobs(): ISubagentJobState[];
2257
+ spawnAgentJob(input: {
2258
+ agentType: string;
2259
+ label: string;
2260
+ mode: 'foreground' | 'background';
2261
+ prompt: string;
2262
+ model?: string;
2263
+ isolation?: TBackgroundTaskIsolation;
2264
+ /** CLI-1994: the forked session record the job restores before its first turn (id only). */
2265
+ resumeSessionId?: string;
2266
+ }): Promise<ISubagentJobState>;
2267
+ sendAgentJob(taskId: string, prompt: string): Promise<void>;
2268
+ cancelAgentJob(taskId: string, reason?: string): Promise<void>;
2269
+ closeAgentJob(taskId: string): Promise<void>;
2270
+ }
2271
+ /** Fanning jobs out as a group and waiting on it. */
2272
+ interface IAgentJobGroups {
2273
+ createBackgroundJobGroup(input: Omit<IBackgroundJobGroupCreateRequest, 'parentSessionId'>): IBackgroundJobGroupState;
2274
+ waitBackgroundJobGroup(groupId: string): Promise<IBackgroundJobGroupState>;
2275
+ }
2276
+ /** Cron-driven wakes and their lifecycle. */
2277
+ interface IAgentJobSchedules {
2278
+ /** Optional for hosts without a persisted interactive session. */
2279
+ createSelfPacedLoop?(instruction: string, options?: {
2280
+ useDefaultPrompt?: boolean;
2281
+ }): Promise<ISessionLoopState>;
2282
+ listSelfPacedLoops?(): readonly ISessionLoopState[];
2283
+ stopSelfPacedLoop?(loopId: string, reason?: string): Promise<void>;
2284
+ /**
2285
+ * FLOW-005: schedule a recurring/one-shot agent wake. On each cron fire the agent loop
2286
+ * re-enters with `agentInstruction` (FLOW-001/002). `cronExpression` may be a standard cron
2287
+ * string or an ISO timestamp (one-shot).
2288
+ */
2289
+ spawnScheduledWake(input: {
2290
+ label: string;
2291
+ cronExpression: string;
2292
+ agentInstruction: string;
2293
+ /** Session-loop identity marker; kept apart from the editable display label. */
2294
+ sessionLoop?: boolean;
2295
+ /** Stable loop id carried in persisted task metadata across runtime task-id remapping. */
2296
+ sessionLoopId?: string;
2297
+ /** Re-resolve the product-owned default prompt before each fixed-loop iteration. */
2298
+ sessionLoopDefaultPrompt?: boolean;
2299
+ /** Earliest instant at which the first scheduled loop wake may enter the session. */
2300
+ sessionLoopFirstAllowedAt?: string;
2301
+ /** Absolute expiry for a session loop; persisted with its stable identity. */
2302
+ sessionLoopExpiresAt?: string;
2303
+ }): Promise<IBackgroundTaskState>;
2304
+ /** SELFHOST-012: list the caller's scheduled tasks (each carries cadence, `nextFireAt`, and status). */
2305
+ listSchedules(): IBackgroundTaskState[];
2306
+ /** SELFHOST-012: non-destructively pause a scheduled task — it stops firing until `resumeSchedule`. */
2307
+ pauseSchedule(taskId: string): Promise<void>;
2308
+ /** SELFHOST-012: resume a paused scheduled task, re-armed with the same identity. */
2309
+ resumeSchedule(taskId: string): Promise<void>;
2310
+ /** SELFHOST-012: edit a scheduled task's cron / instruction in place (same task id). */
2311
+ editSchedule(taskId: string, patch: IScheduleEditPatch): Promise<void>;
2312
+ }
2313
+ /** Output-driven wakes. */
2314
+ interface IAgentJobMonitors {
2315
+ /**
2316
+ * FLOW-005: monitor a process's output and wake the agent with `agentInstruction` when a
2317
+ * line matches `matchPattern` (FLOW-004). When the model asked for it, the command is first
2318
+ * decided by the shell tool's gate; a refusal rejects with {@link MonitorCommandRefusedError}.
2319
+ */
2320
+ spawnMonitorWake(input: {
2321
+ label: string;
2322
+ command: string;
2323
+ matchPattern: string;
2324
+ agentInstruction: string;
2325
+ }): Promise<IBackgroundTaskState>;
2326
+ }
2327
+ /** Reading a job's output. */
2328
+ interface IAgentJobLogs {
2329
+ readBackgroundTaskLog(taskId: string, cursor?: IBackgroundTaskLogCursor): Promise<IBackgroundTaskLogPage>;
2330
+ }
2331
+ /** Aggregate: all 15 members remain source-compatible. Declare a role port instead of this. */
2332
+ interface IAgentJobHostContext extends IAgentJobDispatch, IAgentJobGroups, IAgentJobSchedules, IAgentJobMonitors, IAgentJobLogs {}
2333
+ //#endregion
2334
+ //#region src/command-api/preset/preset-application-types.d.ts
2335
+ /**
2336
+ * Resolved-preset option subset that can be re-applied to a *live* session.
2337
+ *
2338
+ * This is a framework-owned shape. The agent-preset package's `IResolvedPresetOptions` satisfies it
2339
+ * structurally, so a consumer can hand a `resolvePreset(...)` result straight to
2340
+ * {@link applyPresetToSession} without framework importing agent-preset (no dependency cycle).
2341
+ *
2342
+ * PRESET-012 carries the permission/trust group (`permissionMode`); PRESET-013 adds the model group
2343
+ * (`model`, `effort`, `temperature`, `maxOutputTokens`); PRESET-014 adds the `persona` block,
2344
+ * re-applied to the live system prompt; PRESET-015 adds the command-module selection group
2345
+ * (`enabledCommandModules`/`disabledCommandModules`), re-filtered against the session-start set.
2346
+ */
2347
+ interface IPresetApplicationOptions {
2348
+ permissionMode?: TPermissionMode;
2349
+ model?: string;
2350
+ effort?: TModelEffortSelection;
2351
+ temperature?: number;
2352
+ maxOutputTokens?: number;
2353
+ /** PRESET-014 — preset persona re-applied to the live system prompt. */
2354
+ persona?: string;
2355
+ /** ARCH-040 — the agent's identity label, re-applied to the live agent. */
2356
+ agentName?: string;
2357
+ /** ARCH-040 — response language, re-applied as a prompt section. */
2358
+ language?: string;
2359
+ /** ARCH-040 — a preset-supplied system prompt that SEEDS the composed prompt (priority 4). */
2360
+ systemPrompt?: string;
2361
+ /**
2362
+ * ARCH-040 Group C — the preset's tool lists, re-applied to the live enforcer.
2363
+ *
2364
+ * An allowlist REPLACES what the preset layer previously contributed; a denylist UNIONS, because a
2365
+ * denial is not weakened by a later layer that forgot to repeat it. Both halves ship together: an
2366
+ * allowlist that replaces while its paired denylist stayed behind would widen what the session
2367
+ * permits, which is the failure the pairing exists to prevent.
2368
+ */
2369
+ allowedTools?: readonly string[];
2370
+ deniedTools?: readonly string[];
2371
+ /** PRESET-015 — allowlist of command-module names to keep on the live session. */
2372
+ enabledCommandModules?: readonly string[];
2373
+ /** PRESET-015 — denylist of command-module names to remove from the live session. */
2374
+ disabledCommandModules?: readonly string[];
2375
+ /** PRESET-016 — runtime gate toggle for subagent dispatch on the live session. */
2376
+ enableParallelSubagents?: boolean;
2377
+ /** PRESET-017 — toggle the verify-before-done self-verification section on the live prompt. */
2378
+ selfVerification?: boolean;
2379
+ }
2380
+ //#endregion
2381
+ //#region src/context/output-style-prompt.d.ts
2382
+ /** Prompt-only projection of an output style. The preset package's richer value satisfies this shape. */
2383
+ interface IOutputStylePrompt {
2384
+ readonly id: string;
2385
+ readonly name: string;
2386
+ readonly instructions: string;
2387
+ readonly keepCodingInstructions: boolean;
2388
+ readonly tokenCost?: string;
2389
+ }
2390
+ //#endregion
2391
+ //#region src/workspace-trust/types.d.ts
2392
+ declare const workspaceProjectAuthorityType: unique symbol;
2393
+ declare const workspaceProjectSettingsWriterType: unique symbol;
2394
+ declare const workspaceProjectMutationType: unique symbol;
2395
+ /**
2396
+ * Opaque proof that the host granted project access for the currently resolved workspace identity.
2397
+ * Runtime acceptance is stricter than this type: only an exact service-minted object is accepted.
2398
+ */
2399
+ interface IWorkspaceProjectAuthority {
2400
+ readonly [workspaceProjectAuthorityType]: true;
2401
+ }
2402
+ type TWorkspaceTrustState = 'trusted' | 'untrusted' | 'revoked' | 'stale/replaced' | 'identity-unavailable' | 'store-unavailable';
2403
+ interface IWorkspaceIdentity {
2404
+ readonly repositoryKey: string;
2405
+ readonly displayPath: string;
2406
+ readonly worktreeRoot: string;
2407
+ }
2408
+ type TWorkspaceProjectSettingsTarget = 'project' | 'project-local';
2409
+ interface IWorkspaceProjectSettingsWriter {
2410
+ readonly [workspaceProjectSettingsWriterType]: true;
2411
+ readonly target: TWorkspaceProjectSettingsTarget;
2412
+ readonly relativePath: string;
2413
+ writeText(content: string): void;
2414
+ }
2415
+ /** Root-bounded mutation authority minted separately from trusted project reads. */
2416
+ interface IWorkspaceProjectMutation {
2417
+ readonly [workspaceProjectMutationType]: true;
2418
+ writeBytes(relativePath: string, content: Uint8Array, purpose: string): void;
2419
+ deleteFile(relativePath: string, purpose: string): boolean;
2420
+ }
2421
+ interface ITrustedWorkspaceProjectAccess {
2422
+ readonly status: 'trusted';
2423
+ readonly authority: IWorkspaceProjectAuthority;
2424
+ readonly identity: IWorkspaceIdentity;
2425
+ readonly grantedAt?: string;
2426
+ }
2427
+ /**
2428
+ * The owner error behind an `identity-unavailable` or `store-unavailable` trust state
2429
+ * (OBSERVABILITY-1991). Name and message only — never file content.
2430
+ */
2431
+ interface IWorkspaceTrustCause {
2432
+ readonly name: string;
2433
+ readonly message: string;
2434
+ }
2435
+ interface IRestrictedWorkspaceProjectAccess {
2436
+ readonly status: 'restricted';
2437
+ readonly reason: 'WorkspaceAuthorityRequired';
2438
+ readonly trustState: Exclude<TWorkspaceTrustState, 'trusted'>;
2439
+ readonly displayPath?: string;
2440
+ /**
2441
+ * SCREEN-1993: the identity the trust service resolved before deciding the state — present for
2442
+ * every state except `identity-unavailable`, so a consumer that needs the worktree root (the
2443
+ * prompt-history project key) reads the one resolution already made instead of resolving again.
2444
+ */
2445
+ readonly identity?: IWorkspaceIdentity;
2446
+ /** Present when the state was caused by a swallowed identity/store error a diagnostic should name. */
2447
+ readonly cause?: IWorkspaceTrustCause;
2448
+ }
2449
+ type TWorkspaceProjectAccess = ITrustedWorkspaceProjectAccess | IRestrictedWorkspaceProjectAccess;
2450
+ interface IAdvisorStatus {
2451
+ /** The target, as `profile` or `profile:model`; absent when none is set. */
2452
+ readonly target?: string;
2453
+ readonly enabled: boolean;
2454
+ /** Whether this session has the Advisor tool (decided at session start). */
2455
+ readonly registered: boolean;
2456
+ readonly killSwitch: boolean;
2457
+ readonly sessionCalls: number;
2458
+ readonly maxCallsPerSession: number;
2459
+ }
2460
+ interface IAdvisorSetResult {
2461
+ readonly success: boolean;
2462
+ readonly message: string;
2463
+ /** The spec to save as the default, or `'off'`; absent when nothing changed. */
2464
+ readonly saved?: string;
2465
+ }
2466
+ /** What `/advisor` reads and changes on the live session. */
2467
+ interface ICommandAdvisorAdapter {
2468
+ status(): IAdvisorStatus;
2469
+ set(value: string): IAdvisorSetResult;
2470
+ }
2471
+ //#endregion
2472
+ //#region src/command-api/host-adapters.d.ts
2473
+ interface ICommandSettingsDocument {
2474
+ [key: string]: TUniversalValue;
2475
+ }
2476
+ interface ICommandSettingsAdapter<TSettings extends ICommandSettingsDocument = ICommandSettingsDocument> {
2477
+ read(): TSettings;
2478
+ write(settings: TSettings): void;
2479
+ /**
2480
+ * CMD-004 Phase 2: delete the settings document (the host-executed `settings-reset` action).
2481
+ * Returns `true` when a document existed and was removed. Optional — a composition that does not
2482
+ * wire it makes the reset action fail EXPLICITLY in the command result (no-fallback), never a
2483
+ * silent skip.
2484
+ */
2485
+ delete?(): boolean;
2486
+ }
2487
+ interface ICommandProcessAdapter {
2488
+ requestExit(reason?: TSessionEndReason): void;
2489
+ requestRestart(reason: TSessionEndReason, message: string): void;
2490
+ }
2491
+ interface ICommandPermissionModeAdapter {
2492
+ getPermissionMode(): TPermissionMode;
2493
+ setPermissionMode(mode: TPermissionMode): void;
2494
+ listSessionAllowedTools(): readonly string[];
2495
+ /** The allow/deny/ask rules the gate reads right now. */
2496
+ getPermissionRules(): {
2497
+ readonly allow: readonly string[];
2498
+ readonly deny: readonly string[];
2499
+ readonly ask: readonly string[];
2500
+ };
2501
+ /** The calls the session refused, most recent first. */
2502
+ listRecentDenials(): readonly IPermissionDenial[];
2503
+ /** Let the call behind a classifier denial (0-based) run once; `undefined` when there is none. */
2504
+ retryDenial(index: number): IPermissionDenial | undefined;
2505
+ }
2506
+ /** The permission rules one settings layer declares, named the way the user would find the file. */
2507
+ interface IPermissionRuleLayer {
2508
+ /** The file as the user would find it, e.g. `~/.robota/settings.json`. */
2509
+ readonly source: string;
2510
+ readonly scope: string;
2511
+ readonly allow: readonly string[];
2512
+ readonly deny: readonly string[];
2513
+ readonly ask: readonly string[];
2514
+ }
2515
+ /** Where each configured permission rule comes from, read fresh on every call. */
2516
+ interface ICommandPermissionRulesAdapter {
2517
+ readLayers(): readonly IPermissionRuleLayer[];
2518
+ }
2519
+ /** How shell commands are confined: not at all, confined without prompts, or confined and asked. */
2520
+ type TSandboxCommandMode = 'off' | 'auto-allow' | 'regular';
2521
+ interface ICommandSandboxStatus {
2522
+ readonly mode: TSandboxCommandMode;
2523
+ /** `bubblewrap` or `seatbelt`; absent where the platform has none. */
2524
+ readonly backend?: string;
2525
+ /** Why confinement cannot run here, when it cannot: what to install, or the platform. */
2526
+ readonly unavailable?: string;
2527
+ readonly network: boolean;
2528
+ readonly excludedCommands: readonly string[];
2529
+ }
2530
+ /** The OS sandbox, live: `/sandbox` reads it and changes the mode for the next command. */
2531
+ interface ICommandSandboxAdapter {
2532
+ status(): ICommandSandboxStatus;
2533
+ /** Apply the mode now and save it in the user settings. */
2534
+ setMode(mode: TSandboxCommandMode): void;
2535
+ }
2536
+ /** Live model-effort state and application seam supplied by the composition root. */
2537
+ interface ICommandEffortAdapter {
2538
+ getResolution(): IModelEffortResolution;
2539
+ apply(selection: TEffortSelection, session: ICommandSessionModel): IModelEffortResolution | Promise<IModelEffortResolution>;
2540
+ }
2541
+ /**
2542
+ * REMOTE-008: view of `/remote-control` state, so the command can report status without touching the
2543
+ * transport. CMD-004 Phase 2 supersedes the original status-only design: the enable/stop ACTIONS are
2544
+ * now host-executed through this adapter (wired at the composition root) instead of surface-rendered
2545
+ * legacy command effects, so they work on every surface (remote/headless included).
2546
+ */
2547
+ type TRemoteControlStatus = {
2548
+ readonly state: 'off';
2549
+ } | {
2550
+ readonly state: 'no-relay';
2551
+ } | {
2552
+ readonly state: 'awaiting-pairing';
2553
+ readonly pairingUrl: string;
2554
+ } | {
2555
+ readonly state: 'paired';
2556
+ };
2557
+ /** A trusted device summary for `/remote-control devices` (public data only; REMOTE-012 E3). */
2558
+ interface IRemoteTrustedDeviceSummary {
2559
+ readonly deviceId: string;
2560
+ readonly label: string;
2561
+ readonly lastSeenAt: string;
2562
+ }
2563
+ interface ICommandRemoteControlAdapter {
2564
+ getStatus(): TRemoteControlStatus;
2565
+ /** REMOTE-012 E3: enrolled trusted devices (for `/remote-control devices`). Absent → TOFU not available. */
2566
+ listDevices?(): IRemoteTrustedDeviceSummary[];
2567
+ /** REMOTE-012 E3: revoke a trusted device by id (for `/remote-control revoke <id>`); returns true if removed. */
2568
+ revokeDevice?(deviceId: string): boolean;
2569
+ /**
2570
+ * Where the host keeps its identity key, in one line for the operator (for `/remote-control
2571
+ * status`), or `undefined` while no key has been needed yet. Absent ⇒ the host keeps no key.
2572
+ */
2573
+ describeKeyStorage?(): string | undefined;
2574
+ /**
2575
+ * CMD-004 Phase 2: enable remote control (host-executed `remote-control-enable` action). Resolves
2576
+ * to the user-facing message (pairing QR/link, or a fail-closed notice) which the host folds into
2577
+ * the command result. Absent ⇒ the action fails explicitly in the result (no-fallback).
2578
+ */
2579
+ enable?(): string | Promise<string>;
2580
+ /** CMD-004 Phase 2: stop remote control; resolves to the user-facing message (see {@link enable}). */
2581
+ stop?(): string | Promise<string>;
2582
+ }
2583
+ /**
2584
+ * MCP-2520 — public, secret-free view of one resolved MCP definition. The command layer can show
2585
+ * this value and request a decision, but it cannot construct or connect an MCP client.
2586
+ */
2587
+ interface ICommandMCPActivationSummary {
2588
+ readonly serverId: string;
2589
+ readonly displayName?: string;
2590
+ readonly source: 'managed' | 'user' | 'project' | 'plugin' | 'local';
2591
+ readonly status: 'approved' | 'pending' | 'rejected' | 'revoked' | 'stale' | 'untrusted';
2592
+ readonly allowed: boolean;
2593
+ readonly reason: string;
2594
+ readonly provenanceId: string;
2595
+ readonly definitionFingerprint: string;
2596
+ readonly securityIdentity: string;
2597
+ }
2598
+ /**
2599
+ * A definition-source-level problem — issue #2794: a configuration root that is not an object, no
2600
+ * `mcpServers` key, `mcpServers` not an object, or a source that could not be parsed at all. It
2601
+ * names no server, so it cannot be an `ICommandMCPActivationSummary`; this is its own carrier so
2602
+ * `/mcp status` can say which source could not be read, beside the servers that did resolve.
2603
+ *
2604
+ * `blockedServerNames` (PR #3076 review): when this problem is in the MANAGED tier, `agent-mcp`'s
2605
+ * `resolveByPrecedence` fails closed and blocks every name that would otherwise have resolved from a
2606
+ * lower tier — those names would otherwise vanish from `/mcp status` with no explanation, since a
2607
+ * blocked entry is `unresolved` and `ICommandMCPActivationAdapter.list()` only ever offers resolved
2608
+ * candidates. Optional and empty for a non-managed-tier problem, which blocks nothing.
2609
+ */
2610
+ interface ICommandMCPSourceProblem {
2611
+ readonly source: 'managed' | 'user' | 'project' | 'plugin' | 'local';
2612
+ readonly origin: string;
2613
+ readonly reason: string;
2614
+ readonly blockedServerNames?: readonly string[];
2615
+ }
2616
+ /**
2617
+ * One OAuth server's sign-in state as `/mcp` may show it: a fixed word, never a token, scope, expiry
2618
+ * time or anything else derived from a credential.
2619
+ */
2620
+ interface ICommandMCPOAuthStatus {
2621
+ readonly serverId: string;
2622
+ readonly state: 'signed-in' | 'expired-refreshable' | 'sign-in-required' | 'signed-out';
2623
+ }
2624
+ /** What signing out did, by fixed reasons only. */
2625
+ interface ICommandMCPOAuthLogoutResult {
2626
+ readonly serverId: string;
2627
+ /** Whether a credential was stored before the sign-out. */
2628
+ readonly removed: boolean;
2629
+ readonly revocation: 'revoked' | 'partial' | 'unsupported' | 'failed' | 'not-attempted';
2630
+ /** The first step that refused, when a revocation was not confirmed. */
2631
+ readonly revocationFailure?: string;
2632
+ /** Each token a revocation was asked for, by kind — never its value. */
2633
+ readonly tokens?: readonly {
2634
+ readonly token: 'refresh_token' | 'access_token';
2635
+ readonly revoked: boolean;
2636
+ readonly failure?: string;
2637
+ }[];
2638
+ }
2639
+ /** Where the user signs in, shown when they paste the redirect back rather than a listener receiving it. */
2640
+ interface ICommandMCPOAuthRedirectPrompt {
2641
+ readonly authorizationUrl: string;
2642
+ /** Where the browser is sent after approval; that page may not load. */
2643
+ readonly redirectUri: string;
2644
+ }
2645
+ /** One in-session sign-in, as the command asks for it. */
2646
+ interface ICommandMCPOAuthLoginRequest {
2647
+ readonly serverId: string;
2648
+ /** Open no browser: the user opens the authorization URL and pastes the redirect back. */
2649
+ readonly noBrowser: boolean;
2650
+ /**
2651
+ * Asks the user, through the session's own prompt, for the redirect URL their browser was sent
2652
+ * to — with `noBrowser`, or when no browser could be opened. Absent: no one can be asked, and a
2653
+ * sign-in that needs a paste is refused before it starts or fails as `browser-failed`.
2654
+ */
2655
+ readonly readRedirect?: (prompt: ICommandMCPOAuthRedirectPrompt, signal: AbortSignal) => Promise<string>;
2656
+ /**
2657
+ * Without `noBrowser`: shows the user the authorization URL before the browser is opened, so a
2658
+ * browser that opens silently or not at all never leaves them waiting on nothing. `paste` switches
2659
+ * to reading the pasted redirect; `cancel` ends the sign-in. Absent: the browser opens directly.
2660
+ */
2661
+ readonly confirmBrowser?: (prompt: ICommandMCPOAuthRedirectPrompt, signal: AbortSignal) => Promise<'open' | 'paste' | 'cancel'>;
2662
+ /** Cancels the sign-in; it then fails as `cancelled` and changes nothing. */
2663
+ readonly signal?: AbortSignal;
2664
+ }
2665
+ /**
2666
+ * What an in-session sign-in did, by fixed words and reasons only — never a code, token or
2667
+ * authorization-server text.
2668
+ */
2669
+ interface ICommandMCPOAuthLoginResult {
2670
+ readonly serverId: string;
2671
+ /** Present when the sign-in did not complete; the session was then left unchanged. */
2672
+ readonly failure?: string;
2673
+ /** Whether the definition names a pre-registered client, which may need a client secret. */
2674
+ readonly preRegisteredClient: boolean;
2675
+ /**
2676
+ * After a sign-in, the server in this session: `connected` with the tools it now offers,
2677
+ * `recovered` when its tools were already offered and its connection works again,
2678
+ * `not-admitted` when admission refused it, `not-connected` when it still could not connect.
2679
+ */
2680
+ readonly connection?: 'connected' | 'recovered' | 'not-admitted' | 'not-connected';
2681
+ /** The tools a newly connected server offers, for the session to add. */
2682
+ readonly tools: readonly IToolWithEventService[];
2683
+ }
2684
+ /** MCP activation lifecycle port. Implemented by the composition root over the MCP policy service. */
2685
+ interface ICommandMCPActivationAdapter {
2686
+ list(): readonly ICommandMCPActivationSummary[];
2687
+ /**
2688
+ * Where the user acts on a command the model suggests: `session` when they can type a `/mcp`
2689
+ * command, `terminal` for a run with no such prompt (sign-in is then the terminal command).
2690
+ * Absent → `session`.
2691
+ */
2692
+ readonly userActionSurface?: 'session' | 'terminal';
2693
+ /**
2694
+ * Every source-level problem from the most recent resolution (issue #2794). Optional so an older
2695
+ * or narrower adapter implementation still satisfies this interface; a caller that wants to render
2696
+ * source problems treats a missing method the same as an empty list.
2697
+ */
2698
+ sourceProblems?(): readonly ICommandMCPSourceProblem[];
2699
+ approve(serverId: string): ICommandMCPActivationSummary | Promise<ICommandMCPActivationSummary>;
2700
+ reject(serverId: string): ICommandMCPActivationSummary | Promise<ICommandMCPActivationSummary>;
2701
+ revoke(serverId: string): ICommandMCPActivationSummary | Promise<ICommandMCPActivationSummary>;
2702
+ /** Sign-in state of every server that declares OAuth. Absent: the host offers no OAuth. */
2703
+ oauthStatus?(): Promise<readonly ICommandMCPOAuthStatus[]>;
2704
+ /** Sign out of one OAuth server. Rejects for a server that does not declare OAuth. */
2705
+ oauthLogout?(serverId: string): Promise<ICommandMCPOAuthLogoutResult>;
2706
+ /**
2707
+ * Sign in to one OAuth server, then connect it in this session through the normal admission.
2708
+ * Never rejects for a failed sign-in: it names the failure. Absent: the host offers no in-session
2709
+ * sign-in.
2710
+ */
2711
+ oauthLogin?(request: ICommandMCPOAuthLoginRequest): Promise<ICommandMCPOAuthLoginResult>;
2712
+ /**
2713
+ * Which of the tools `oauthLogin` returned the session actually took; any other was left out for
2714
+ * a name it already had. Called once per sign-in that returned tools.
2715
+ */
2716
+ oauthToolsAdded?(serverId: string, added: readonly string[]): void;
2717
+ }
2718
+ /**
2719
+ * PEER-004 (#1863): a live session this one can address, as the operator sees it.
2720
+ *
2721
+ * Display data only. `sessionId` names the peer for a later `send`; `liveness` is carried rather
2722
+ * than filtered so the operator can tell "I could not determine" from "not running" — a host with no
2723
+ * way to read process start times answers `unknown`, and collapsing that into either verdict would
2724
+ * be the guess the registry refuses to make.
2725
+ */
2726
+ interface ILocalPeerSummary {
2727
+ readonly sessionId: string;
2728
+ readonly name?: string;
2729
+ readonly liveness: 'alive' | 'dead' | 'unknown';
2730
+ /** Content-free observed activity; unknown when stale or unverified. */
2731
+ readonly status?: 'working' | 'needs-input' | 'idle' | 'unknown';
2732
+ /** How the peer's workspace relates to this one's, judged from what this session read at the claimed path. */
2733
+ readonly workspaceRelation?: TWorkspaceRelation;
2734
+ /** `mismatched` when the peer's claim disagreed with what this session read; it is not believed. */
2735
+ readonly workspaceClaim?: 'verified' | 'mismatched' | 'absent';
2736
+ }
2737
+ /**
2738
+ * PEER-004: what `/peers` reads. The registry, the guarded directory and the liveness rule all live
2739
+ * in the composition root — a command never touches the filesystem, for the same reason it never
2740
+ * constructs a transport.
2741
+ */
2742
+ interface ICommandLocalPeersAdapter {
2743
+ /** Every announced session, this one included. Ordering is the adapter's. */
2744
+ list(): readonly ILocalPeerSummary[];
2745
+ /**
2746
+ * The same rows with each other peer's workspace relation filled in. Separate and asynchronous
2747
+ * because judging a relation reads git; `list` stays cheap for callers that only need liveness.
2748
+ */
2749
+ listWithWorkspace?(): Promise<readonly ILocalPeerSummary[]>;
2750
+ /** This session's own id, so the command can mark which row is the reader. */
2751
+ ownSessionId(): string;
2752
+ /**
2753
+ * PEER-006: hand `text` to another announced session, and report what came back.
2754
+ *
2755
+ * Returns a delivery state rather than throwing, because "the peer refused it" and "the carrier
2756
+ * broke" are both answers the operator needs, and an exception would flatten them into one.
2757
+ * Absent on a host that can discover peers but cannot address them.
2758
+ *
2759
+ * `inReplyTo` names the received message this answers, which threads a conversation; the host
2760
+ * refuses a reply that would run a conversation past its limits, and tells the operator.
2761
+ */
2762
+ send?(targetSessionId: string, text: string, options?: {
2763
+ readonly inReplyTo?: string;
2764
+ }): Promise<ILocalPeerSendResult>;
2765
+ }
2766
+ /**
2767
+ * PEER-006: what the sender learns, in the vocabulary the operator reads.
2768
+ *
2769
+ * Deliberately not the transport's ack type: the command layer must not import the wire contract to
2770
+ * print a sentence, and `pending` — the honest answer while a message waits behind a running turn —
2771
+ * is a state the operator has to be able to see named.
2772
+ */
2773
+ interface ILocalPeerSendResult {
2774
+ readonly state: 'pending' | 'delivered' | 'acknowledged' | 'duplicate' | 'refused' | 'failed';
2775
+ readonly reason?: string;
2776
+ }
2777
+ /**
2778
+ * ARCH-009 — the discovery half of a preset registry, named HERE rather than imported.
2779
+ *
2780
+ * `agent-preset` depends on `agent-framework`, not the other way round, so importing its
2781
+ * `IPresetRegistry` would invert the layering to describe a value this package only hands to a
2782
+ * command. Structural typing means the registry `agent-preset` builds satisfies this without either
2783
+ * package naming the other.
2784
+ *
2785
+ * Only the three members `/preset` actually calls are named. A port that mirrors a whole contract it
2786
+ * does not use is a second copy of that contract waiting to drift.
2787
+ *
2788
+ * It is an ADAPTER and not a host-role member, because that is what it is: a capability the
2789
+ * composition root supplies, reached the way `/permission-mode` and `/plugin` already reach theirs.
2790
+ * Absent ⇒ the host loaded no external presets, and `/preset` lists the built-ins.
2791
+ */
2792
+ interface ICommandPresetRegistryAdapter {
2793
+ /**
2794
+ * `title` and `description` are REQUIRED, because `/preset list` renders both. Optional members
2795
+ * here would let a conforming host typecheck and then print `id — undefined: undefined`; review of
2796
+ * ARCH-009 reported exactly that. A port requires what its consumer needs, and variation belongs in
2797
+ * the VALUE, not in whether the member exists.
2798
+ */
2799
+ listPresets(): readonly {
2800
+ id: string;
2801
+ title: string;
2802
+ description: string;
2803
+ }[];
2804
+ /** PRESENCE only — `/preset` asks whether the id is known, never what it holds. */
2805
+ getPreset(id: string): unknown;
2806
+ /**
2807
+ * The re-appliable option subset. `IPresetApplicationOptions` is framework-owned and
2808
+ * `agent-preset`'s `IResolvedPresetOptions` satisfies it structurally, so naming it here crosses no
2809
+ * layer and leaves nothing for a consumer to assert about a value it did not check.
2810
+ */
2811
+ resolvePreset(id: string, context?: unknown): IPresetApplicationOptions;
2812
+ }
2813
+ /** CLI-1988: the command-facing projection of the host's provider-neutral output-style registry. */
2814
+ interface ICommandOutputStyleSummary {
2815
+ readonly id: string;
2816
+ readonly name: string;
2817
+ readonly description: string;
2818
+ readonly tokenCost?: string;
2819
+ readonly source?: string;
2820
+ }
2821
+ /** CLI-1988: discovery and resolution only; commands never read style files or own persistence. */
2822
+ interface ICommandOutputStyleRegistryAdapter {
2823
+ listOutputStyles(): readonly ICommandOutputStyleSummary[];
2824
+ getOutputStyle(id: string): IOutputStylePrompt | undefined;
2825
+ }
2826
+ /**
2827
+ * HANDOFF-001 (issue #1864): what a hand-off looks like to the operator, in the operator's words.
2828
+ *
2829
+ * Deliberately not the wire package's `THandoffPhase`. The command layer must not import the wire
2830
+ * contract to print a sentence, and the two vocabularies answer different questions — `staged` is a
2831
+ * protocol state, while "the other machine has it and is not running it yet" is what the person
2832
+ * standing at the keyboard needs to be told.
2833
+ */
2834
+ interface IHandoffProgress {
2835
+ readonly state: 'offered' | 'sending' | 'awaiting-confirmation' | 'done' | 'stopped';
2836
+ /** Present when the transfer stopped without completing. Named so the operator can act on it. */
2837
+ readonly reason?: string;
2838
+ /** Is THIS machine still in charge of the session? The single question the whole design answers. */
2839
+ readonly stillMine: boolean;
2840
+ }
2841
+ /** What stays behind, surfaced BEFORE the operator confirms, because it is their choice to lose it. */
2842
+ interface IHandoffStaysBehind {
2843
+ readonly uncommittedChanges: boolean;
2844
+ readonly subprocesses: number;
2845
+ }
2846
+ /** A `/cd` the session has already checked and prepared; the host carries it out. */
2847
+ interface IWorkspaceMoveRequest {
2848
+ /** The directory the session runs in now. */
2849
+ readonly fromCwd: string;
2850
+ /** The canonical absolute directory to move to. */
2851
+ readonly targetCwd: string;
2852
+ /** The conversation, copied for the target — its `cwd` is already `targetCwd`. */
2853
+ readonly record: IInteractiveSessionRecord;
2854
+ /**
2855
+ * The session is Restricted. A move never widens access, so the target stays Restricted whatever
2856
+ * its own trust decision; a trusted session takes the target's own decision.
2857
+ */
2858
+ readonly restricted: boolean;
2859
+ }
2860
+ /**
2861
+ * What `/cd` hands the host. A move is a NEW session in the target directory, composed the way the
2862
+ * host composes any session there — its settings, trust decision, tools and instructions — resuming
2863
+ * this conversation. Absent on a host that cannot start one; `/cd` then says so.
2864
+ */
2865
+ interface ICommandWorkspaceAdapter {
2866
+ move(request: IWorkspaceMoveRequest): Promise<void>;
2867
+ }
2868
+ /**
2869
+ * What `/handoff` reads. The carrier, the wire composition and the device identity all live in the
2870
+ * composition root — a command never constructs a transport.
2871
+ */
2872
+ interface ICommandHandoffAdapter {
2873
+ /** The machines this session could be moved to. Empty is an answer, not an error. */
2874
+ destinations(): Promise<readonly {
2875
+ readonly deviceId: string;
2876
+ readonly name?: string;
2877
+ }[]>;
2878
+ /**
2879
+ * What will not travel, so the operator is asked with the facts in front of them.
2880
+ *
2881
+ * Read before the confirmation prompt rather than after: uncommitted work and running
2882
+ * subprocesses stay on this machine by design, and a consent that did not mention them is not
2883
+ * consent to lose them.
2884
+ */
2885
+ staysBehind(): Promise<IHandoffStaysBehind>;
2886
+ /**
2887
+ * Move this session to `deviceId`, reporting progress as it goes.
2888
+ *
2889
+ * Returns the final progress rather than throwing: "the destination cannot run it" and "the link
2890
+ * broke" are both answers the operator needs, and an exception would flatten them into one. In
2891
+ * every non-`done` outcome `stillMine` is true — that is the invariant the command prints.
2892
+ */
2893
+ transfer(deviceId: string, onProgress?: (progress: IHandoffProgress) => void): Promise<IHandoffProgress>;
2894
+ /** Is this machine still authoritative? Asked without starting anything. */
2895
+ status(): IHandoffProgress;
2896
+ }
2897
+ /** The persisted `/cost budget` document. */
2898
+ interface ICommandCostBudget {
2899
+ monthly: number;
2900
+ }
2901
+ /**
2902
+ * CMD-007 (issue #2058): the narrow storage port `/cost budget` reads and writes through.
2903
+ *
2904
+ * The command used to own the budget file's location and the filesystem calls itself, which made a
2905
+ * reusable command package responsible for a product's storage location and symlink policy. The
2906
+ * shell now composes an adapter (agent-cli: a file under the workspace, written atomically and never
2907
+ * through a symlink); the command sees `read/write/clear` and nothing else, so another product can
2908
+ * store the budget wherever it likes. `write`/`clear` throw a typed failure the command renders.
2909
+ */
2910
+ interface ICommandCostBudgetAdapter {
2911
+ /** `undefined` when no budget is set (absent, empty or unreadable document alike). */
2912
+ read(): ICommandCostBudget | undefined;
2913
+ write(budget: ICommandCostBudget): void;
2914
+ clear(): void;
2915
+ }
2916
+ interface ICommandHostAdapters {
2917
+ settings?: ICommandSettingsAdapter;
2918
+ effort?: ICommandEffortAdapter;
2919
+ /** The live advisor: `/advisor` changes its target without touching the session's tools. */
2920
+ advisor?: ICommandAdvisorAdapter;
2921
+ /** CMD-007 (issue #2058). Absent on a host with no budget storage — `/cost budget` then says so. */
2922
+ costBudget?: ICommandCostBudgetAdapter;
2923
+ process?: ICommandProcessAdapter;
2924
+ permissionMode?: ICommandPermissionModeAdapter;
2925
+ /** Absent on a host that cannot name its settings layers — `/permissions` then lists rules unattributed. */
2926
+ permissionRules?: ICommandPermissionRulesAdapter;
2927
+ plugin?: ICommandPluginAdapter;
2928
+ remoteControl?: ICommandRemoteControlAdapter;
2929
+ mcpActivation?: ICommandMCPActivationAdapter;
2930
+ localPeers?: ICommandLocalPeersAdapter;
2931
+ /**
2932
+ * ARCH-009 — the instance registry the host resolved with, so in-session `/preset` discovers THIS
2933
+ * product's presets. Its absence is why `agent-preset` had to keep a module-global registry: a
2934
+ * command runs with an `ICommandHostContext` and nothing else, so this bag is the path from the
2935
+ * shell to the command.
2936
+ */
2937
+ presetRegistry?: ICommandPresetRegistryAdapter;
2938
+ /** CLI-1988 — the instance-scoped output-style catalog resolved by the composition root. */
2939
+ outputStyleRegistry?: ICommandOutputStyleRegistryAdapter;
2940
+ /**
2941
+ * HANDOFF-001 (issue #1864). Absent on a host with no carrier — `/handoff` then says so rather
2942
+ * than offering a transfer it cannot perform.
2943
+ */
2944
+ handoff?: ICommandHandoffAdapter;
2945
+ /** Absent on a host that cannot start a session elsewhere — `/cd` then says so. */
2946
+ workspace?: ICommandWorkspaceAdapter;
2947
+ /** Absent on a host with no OS sandbox — `/sandbox` then says so. */
2948
+ sandbox?: ICommandSandboxAdapter;
2949
+ }
2950
+ interface IContextReferenceAddResult {
2951
+ reference?: IContextReferenceItem;
2952
+ evicted: IContextReferenceItem[];
2953
+ diagnostics: string[];
2954
+ }
2955
+ interface IContextReferenceRemoveResult {
2956
+ removed?: IContextReferenceItem;
2957
+ }
2958
+ interface IContextReferenceClearResult {
2959
+ removed: IContextReferenceItem[];
2960
+ }
2961
+ /** Options for {@link GoalController.start}. */
2962
+ interface IGoalStartOptions {
2963
+ maxIterations?: number;
2964
+ noProgressLimit?: number;
2965
+ }
2966
+ interface IStartupMemory {
2967
+ content: string;
2968
+ path: string;
2969
+ lineCount: number;
2970
+ truncated: boolean;
2971
+ }
2972
+ interface IMemoryTopicSummary {
2973
+ name: string;
2974
+ path: string;
2975
+ }
2976
+ interface IProjectMemorySummary {
2977
+ indexPath: string;
2978
+ topicsPath: string;
2979
+ topics: IMemoryTopicSummary[];
2980
+ }
2981
+ interface IAppendMemoryInput {
2982
+ type: TMemoryType;
2983
+ topic: string;
2984
+ text: string;
2985
+ }
2986
+ interface IAppendMemoryResult {
2987
+ indexPath: string;
2988
+ topicPath: string;
2989
+ topic: string;
2990
+ deduplicated: boolean;
2991
+ }
2992
+ type TMemoryCandidateStatus = 'pending' | 'approved' | 'rejected' | 'saved' | 'skipped';
2993
+ interface IMemoryCandidate {
2994
+ id: string;
2995
+ type: TMemoryType;
2996
+ topic: string;
2997
+ text: string;
2998
+ sourceMessageIds: string[];
2999
+ confidence: number;
3000
+ createdAt: string;
3001
+ reason: string;
3002
+ }
3003
+ interface IMemoryPendingRecord extends IMemoryCandidate {
3004
+ status: TMemoryCandidateStatus;
3005
+ updatedAt: string;
3006
+ decisionReason?: string;
3007
+ }
3008
+ interface IMemoryRetrievalResult {
3009
+ content: string;
3010
+ references: IMemoryReference[];
3011
+ truncated: boolean;
3012
+ }
3013
+ //#endregion
3014
+ //#region src/memory/types.d.ts
3015
+ /** A recall budget: at most `maxTopics` topics, each truncated to `maxTopicChars` characters. */
3016
+ interface IMemoryBudget {
3017
+ maxTopics: number;
3018
+ maxTopicChars: number;
3019
+ }
3020
+ /**
3021
+ * Segregated role interfaces (ISP). The durable-memory capability is four distinct client roles —
3022
+ * a reader (startup injection needs only this), a writer, a recaller, and a curation queue. `IMemoryStore`
3023
+ * composes all four; a consumer depends only on the slice it uses. Every method is **async**
3024
+ * (`Promise`-returning), matching the repo's I/O-capability port precedents (`ISandboxClient`,
3025
+ * `IRetrievalAdapter`) so a remote/heavy backend — including the async `ISemanticMemoryAdapter` — fits
3026
+ * behind the same port without a breaking migration. The fs reference adapter wraps its synchronous `fs`
3027
+ * calls in already-resolved Promises (zero behavior change).
3028
+ */
3029
+ interface IDurableMemoryReader {
3030
+ /** The startup-memory index (budget-limited), injected into the system prompt. */
3031
+ loadStartupMemory(): Promise<IStartupMemory>;
3032
+ /** Summarize the memory index + topic files. */
3033
+ list(): Promise<IProjectMemorySummary>;
3034
+ /** Read a single topic's content ('' if absent). */
3035
+ readTopic(topic: string): Promise<string>;
3036
+ }
3037
+ interface IMemoryWriter {
3038
+ /** Append a durable memory entry (deduplicated). */
3039
+ append(input: IAppendMemoryInput): Promise<IAppendMemoryResult>;
3040
+ }
3041
+ interface IMemoryRecaller {
3042
+ /** Recall the most relevant topics for `query`, never exceeding `budget`. */
3043
+ recall(query: string, budget: IMemoryBudget): Promise<IMemoryRetrievalResult>;
3044
+ }
3045
+ interface IMemoryCurationQueue {
3046
+ /** A pending candidate by id (undefined if absent). */
3047
+ getPending(id: string): Promise<IMemoryPendingRecord | undefined>;
3048
+ /** Pending candidates, optionally filtered by status. */
3049
+ listPending(status?: TMemoryCandidateStatus): Promise<IMemoryPendingRecord[]>;
3050
+ /** Transition a pending candidate to a new status with a reason. */
3051
+ markPending(id: string, status: TMemoryCandidateStatus, reason: string): Promise<IMemoryPendingRecord>;
3052
+ /** Insert or update a pending candidate with a status + reason. */
3053
+ upsertPending(candidate: IMemoryCandidate, status: TMemoryCandidateStatus, reason: string): Promise<void>;
3054
+ }
3055
+ /**
3056
+ * The neutral durable-memory port — the composition of the four role interfaces above. It is the single
3057
+ * DIP seam a surface swaps to change the whole backend (fs, FTS, or a semantic/vector store behind
3058
+ * `ISemanticMemoryAdapter`); startup injection, the `/memory` command path, and the post-turn capture
3059
+ * controller ALL read/write through it, so an injected store is authoritative everywhere (no split-brain).
3060
+ */
3061
+ interface IMemoryStore extends IDurableMemoryReader, IMemoryWriter, IMemoryRecaller, IMemoryCurationQueue {}
3062
+ //#endregion
3063
+ //#region src/command-api/host-roles.d.ts
3064
+ /** Reaching the live session, and the whole-conversation operations that sit beside it. */
3065
+ interface ICommandHostSessionAccess {
3066
+ getSession(): ICommandSessionRuntime;
3067
+ /** Read the active response style id for the command listing. */
3068
+ getActiveOutputStyleId(): string;
3069
+ clearConversationHistory(): void;
3070
+ /**
3071
+ * CLI-1994 — write a COPY of the live conversation as a new session record (fresh id, distinct
3072
+ * name, the parent's messages and assembled system message) and return its identity. A role-port
3073
+ * member rather than an `ICommandHostAdapters` entry because the session store is owned by the
3074
+ * session, not by the shell. The copy is not started here: `/fork` spawns the background job that
3075
+ * resumes it, carrying only the returned id.
3076
+ */
3077
+ forkSession(input?: {
3078
+ name?: string;
3079
+ }): Promise<{
3080
+ sessionId: string;
3081
+ name: string;
3082
+ }>;
3083
+ /**
3084
+ * ARCH-029 TC-08 — required, and the host delegates to `computeSessionReplayValidationReport`.
3085
+ * It was an optional override with a framework-computed default and no implementor, which is
3086
+ * two declared paths with only one live. One owner, one path.
3087
+ */
3088
+ validateCurrentSessionReplayLog(): ICommandSessionReplayValidationReport;
3089
+ /**
3090
+ * Every usage record the session has persisted — its turns and any other model it consulted —
3091
+ * so a total read from here is the whole session's spend, each part priced on its own model.
3092
+ */
3093
+ getSessionUsage(): readonly ISessionUsageRecord[];
3094
+ }
3095
+ /** Reaching the agent-job capability, when the host has one. */
3096
+ interface ICommandHostAgentJobs {
3097
+ getAgentJobCapability(): IAgentJobHostContext | undefined;
3098
+ }
3099
+ /** Asking the user a question. */
3100
+ interface ICommandHostUserInteraction {
3101
+ /**
3102
+ * CMD-004: the injected "ask the user" port, or undefined when no interactive renderer is attached.
3103
+ * A command solicits a structured answer via `getUserInteraction()?.ask(request)`; absence means no
3104
+ * human is available (headless/automation, or a model-invoked command) — the command must handle it
3105
+ * as a cancellation, never a silent guess.
3106
+ */
3107
+ getUserInteraction(): IUserInteraction | undefined;
3108
+ }
3109
+ /** Re-applying preset-owned configuration to the live session. */
3110
+ interface ICommandHostPresetApplication {
3111
+ /** Apply an additive response style to the live system prompt. */
3112
+ applyOutputStyle(style: IOutputStylePrompt): void;
3113
+ /** PRESET-014 — re-apply a preset persona to the live system prompt. */
3114
+ applyPersona(persona: string): void;
3115
+ /** PRESET-017 — toggle the verify-before-done self-verification section on the live prompt. */
3116
+ applySelfVerification(enabled: boolean): void;
3117
+ /** ARCH-040 — re-apply the preset's response language to the live system prompt. */
3118
+ applyResponseLanguage(language: string): void;
3119
+ /** ARCH-040 — re-apply the preset's seeding system prompt to the live system prompt. */
3120
+ applyPresetSystemPrompt(text: string): void;
3121
+ /**
3122
+ * PRESET-015 — re-apply command-module selection to the live session. Returns any
3123
+ * `enabled`/`disabled` names that matched no live command module (INFRA-032) so the `/preset`
3124
+ * command can surface them as a non-fatal notice; an empty array means every name matched.
3125
+ */
3126
+ applyCommandModuleSelection(enabled: readonly string[] | undefined, disabled: readonly string[] | undefined): readonly IUnknownCommandModuleName[];
3127
+ }
3128
+ /** The host's view of the context window and its compaction. */
3129
+ interface ICommandHostContextWindow {
3130
+ getContextState(): IContextWindowState;
3131
+ getAutoCompactThreshold(): TAutoCompactThreshold;
3132
+ getAutoCompactThresholdSource(): TAutoCompactThresholdSource;
3133
+ setAutoCompactThreshold(threshold: TAutoCompactThreshold, source?: TAutoCompactThresholdSource): void;
3134
+ compactContext(instructions?: string): Promise<void>;
3135
+ }
3136
+ /** The files pinned into context by reference. */
3137
+ interface ICommandHostContextReferences {
3138
+ listContextReferences(): IContextReferenceItem[];
3139
+ addContextReference(path: string): Promise<IContextReferenceAddResult>;
3140
+ removeContextReference(path: string): IContextReferenceRemoveResult;
3141
+ clearContextReferences(): IContextReferenceClearResult;
3142
+ }
3143
+ /** Where the command is running, and how it was invoked. */
3144
+ interface ICommandHostWorkspace {
3145
+ getCwd(): string;
3146
+ getCommandInvocationSource(): TCommandInvocationSource;
3147
+ }
3148
+ /** What commands and skills this host can dispatch. */
3149
+ interface ICommandHostCatalog {
3150
+ listCommands(): ICommandListEntry[];
3151
+ listSkills(): ICommandSkillListEntry[];
3152
+ executeSkillCommandByName(name: string, args: string, request: ICommandSkillActivationRequest): Promise<ICommandResult | null>;
3153
+ }
3154
+ /** The edit-checkpoint tree: inspection, restore, and branching. */
3155
+ interface ICommandHostCheckpoints {
3156
+ listEditCheckpoints(): IEditCheckpointSummary[];
3157
+ inspectEditCheckpoint(checkpointId: string): IEditCheckpointInspection;
3158
+ restoreEditCheckpoint(checkpointId: string): Promise<IEditCheckpointRestoreResult>;
3159
+ rollbackEditCheckpoint(checkpointId: string): Promise<IEditCheckpointRestoreResult>;
3160
+ /** SELFHOST-007: list the checkpoint branch tips (leaf ids) via the neutral tree. */
3161
+ listCheckpointBranches(): string[];
3162
+ /** SELFHOST-007: fork a new branch from a past checkpoint (non-destructive restore). */
3163
+ forkCheckpointBranch(checkpointId: string): Promise<IEditCheckpointRestoreResult>;
3164
+ /** SELFHOST-007: switch the active branch to an existing checkpoint/branch tip. */
3165
+ switchCheckpointBranch(checkpointId: string): void;
3166
+ }
3167
+ /** Durable memory: what was used, what happened, and the store behind it. */
3168
+ interface ICommandHostMemory {
3169
+ getUsedMemoryReferences(): IMemoryReference[];
3170
+ recordMemoryEvent(event: IMemoryEvent): void;
3171
+ /**
3172
+ * SELFHOST-008 P1R — the injected durable-memory port the `/memory` command reads/writes through, so a
3173
+ * surface that swaps the store is authoritative for command operations too (no split-brain). Must
3174
+ * return the SAME instance the session injected (SSOT for a stateful store). ARCH-029 TC-09: the
3175
+ * "when absent, default to the neutral fs store over `getCwd()`" fallback is GONE — the one
3176
+ * production host already built and cached that store itself, so the framework was re-deriving
3177
+ * what the host owned.
3178
+ */
3179
+ getMemoryStore(): IMemoryStore;
3180
+ }
3181
+ /** Observing and ending background tasks. */
3182
+ interface ICommandHostBackgroundTasks {
3183
+ listBackgroundTasks(filter?: IBackgroundTaskListFilter): IBackgroundTaskState[];
3184
+ readBackgroundTaskLog(taskId: string, cursor?: IBackgroundTaskLogCursor): Promise<IBackgroundTaskLogPage>;
3185
+ cancelBackgroundTask(taskId: string, reason?: string): Promise<void>;
3186
+ closeBackgroundTask(taskId: string): Promise<void>;
3187
+ }
3188
+ /** The autonomous-goal lifecycle. */
3189
+ interface ICommandHostGoal {
3190
+ /** GOAL-001 — assign and begin pursuing an autonomous goal. */
3191
+ setGoal(objective: string, options?: IGoalStartOptions): Promise<IGoalState>;
3192
+ /** GOAL-001 — the current goal state, or null when no goal has been set. */
3193
+ getGoalState(): IGoalState | null;
3194
+ /** GOAL-001 — cancel an in-flight goal; returns the stopped state or null. */
3195
+ cancelGoal(): IGoalState | null;
3196
+ }
3197
+ /** The plan lifecycle, including the mode flip approval performs. */
3198
+ interface ICommandHostPlan {
3199
+ /** SELFHOST-002 — start a plan (draft for review; keeps `plan` mode). */
3200
+ setPlan(objective: string, steps?: readonly string[]): Promise<IPlanArtifact>;
3201
+ /** SELFHOST-002 — the current plan artifact, or null when none started. */
3202
+ getPlanState(): IPlanArtifact | null;
3203
+ /** SELFHOST-002 — approve the plan; applies the `plan → acceptEdits` mode flip. */
3204
+ approvePlan(): IPlanArtifact;
3205
+ /** SELFHOST-002 — revert the plan to drafting; returns mode to `plan`. */
3206
+ revertPlan(): IPlanArtifact;
3207
+ }
3208
+ /** Handing the real terminal to a child process. */
3209
+ interface ICommandHostTerminalHandoff {
3210
+ /**
3211
+ * TERM-001 — whether the active transport can hand the real terminal to a child process. `false`
3212
+ * when there is no interactive TTY (e.g. headless). `runWithTerminal` is required and present
3213
+ * either way; whether a handoff is possible is a VALUE this returns, not a member that is missing.
3214
+ */
3215
+ canHandoffTerminal(): boolean;
3216
+ /**
3217
+ * TERM-001 — suspend the display, run `fn` (which spawns a child with inherited stdio), then
3218
+ * restore the display. Exclusive (one handoff at a time) and abort-safe; rejects without running
3219
+ * `fn` when a handoff is not possible. The framework owns this orchestration; the transport
3220
+ * implements the underlying suspend/resume.
3221
+ */
3222
+ runWithTerminal<T>(fn: () => Promise<T>): Promise<T>;
3223
+ }
3224
+ /** The injected adapter bag — genuinely variational, and the named zero-optional carve-out. */
3225
+ interface ICommandHostAdapterAccess {
3226
+ getCommandHostAdapters?(): ICommandHostAdapters;
3227
+ }
3228
+ /** Aggregate: all 47 members remain source-compatible. Declare a role port instead of this. */
3229
+ interface ICommandHostContext extends ICommandHostSessionAccess, ICommandHostAgentJobs, ICommandHostUserInteraction, ICommandHostPresetApplication, ICommandHostContextWindow, ICommandHostContextReferences, ICommandHostWorkspace, ICommandHostCatalog, ICommandHostCheckpoints, ICommandHostMemory, ICommandHostBackgroundTasks, ICommandHostGoal, ICommandHostPlan, ICommandHostTerminalHandoff, ICommandHostAdapterAccess {}
3230
+ //#endregion
3231
+ //#region src/command-api/contracts.d.ts
3232
+ type TSystemCommandLifecycle = 'inline' | 'blocking' | 'background';
3233
+ type TSystemCommandSemanticRole = 'skillActivation' | 'contextReduction' | 'subagentSpawn';
3234
+ /** A user-visible command with descriptor metadata and execute logic. */
3235
+ interface ISystemCommand {
3236
+ name: string;
3237
+ /** Optional framework-owned behavior role; command owners declare it beside the real command id. */
3238
+ semanticRole?: TSystemCommandSemanticRole;
3239
+ /** User-friendly display label (e.g., "Interaction Mode"). Falls back to `name` if not set. */
3240
+ displayName?: string;
3241
+ description: string;
3242
+ /** Optional usage example shown in /help output (e.g., "/compact Summarize the context"). */
3243
+ example?: string;
3244
+ modelInvocable?: boolean;
3245
+ /** What the model is told about this command; absent → `description`. See `ICommand.modelDescription`. */
3246
+ modelDescription?: string;
3247
+ userInvocable?: boolean;
3248
+ argumentHint?: string;
3249
+ safety?: TCapabilitySafety;
3250
+ subcommands?: readonly ICommand[];
3251
+ lifecycle?: TSystemCommandLifecycle;
3252
+ /**
3253
+ * Whether executing this command requires explicit user permission/confirmation.
3254
+ * - `false`: runs immediately without any approval gate
3255
+ * - `true`: user confirmation is required before execution
3256
+ * - `undefined` (default): derived from `safety` — `'read-only'` → false, others → true
3257
+ */
3258
+ requiresPermission?: boolean;
3259
+ /**
3260
+ * Whether the MODEL's call to this command is asked about by name, when that differs from
3261
+ * `requiresPermission`. It may be `false` only when everything the model can reach through the
3262
+ * command (its model subcommand allowlist) is read-only, or when the command decides each
3263
+ * model call through the gate of the tool whose effect it has — never merely to skip a prompt.
3264
+ * Absent → `requiresPermission`'s resolution. It never changes the user or remote path.
3265
+ */
3266
+ modelRequiresPermission?: boolean;
3267
+ execute(context: ICommandHostContext, args: string): Promise<ICommandResult> | ICommandResult;
3268
+ }
3269
+ //#endregion
3270
+ //#region src/command-api/command-module.d.ts
3271
+ /**
3272
+ * CMD-008: a session requirement is a DEMAND SWITCH, not a registration gate. Declaring one does
3273
+ * not gate the module on runtime capability being available; it makes the session projection
3274
+ * enable that facility (`'agent-runtime'` → `enableAgentRuntime: true`) so the module's commands
3275
+ * can rely on it. Pinned by `interactive/__tests__/command-module-session-requirements.test.ts`.
3276
+ */
3277
+ type TCommandModuleSessionRequirement = 'agent-runtime';
3278
+ /** Composable command capability module. */
3279
+ interface ICommandModule {
3280
+ /** Stable module id for diagnostics and duplicate handling. */
3281
+ readonly name: string;
3282
+ /** Slash palette/autocomplete command sources contributed by this module. */
3283
+ readonly commandSources?: readonly ICommandSource[];
3284
+ /** Executable system commands contributed by this module. */
3285
+ readonly systemCommands?: readonly ISystemCommand[];
3286
+ /** Additional model-visible descriptors not derived from executable commands. */
3287
+ readonly commandDescriptors?: readonly ICapabilityDescriptor[];
3288
+ /** Runtime facilities this module DEMANDS — the session enables each one when the module is composed. */
3289
+ readonly sessionRequirements?: readonly TCommandModuleSessionRequirement[];
3290
+ /** Stop and join module-owned work before its host session closes. */
3291
+ readonly shutdown?: (host: ICommandHostWorkspace) => Promise<void>;
3292
+ }
3293
+ //#endregion
3294
+ //#region ../agent-preset/dist/node/index.d.ts
3295
+ //#endregion
3296
+ //#region src/output-style-types.d.ts
3297
+ type TOutputStyleSource = 'built-in' | 'managed' | 'user' | 'project';
3298
+ interface IOutputStyleFile {
3299
+ readonly fileName: string;
3300
+ readonly content: string;
3301
+ }
3302
+ /** A source is already bounded by its owner; this package only decodes the supplied Markdown. */
3303
+ interface IOutputStyleSource {
3304
+ readonly scope: Exclude<TOutputStyleSource, 'built-in'>;
3305
+ readonly displayName: string;
3306
+ /** Lower values are applied first. The last scope with an id wins. */
3307
+ readonly precedence: number;
3308
+ readonly files: readonly IOutputStyleFile[];
3309
+ }
3310
+ //#endregion
3311
+ //#region ../agent-mcp/dist/node/index.d.ts
3312
+ //#region src/mcp-activation.d.ts
3313
+ /**
3314
+ * MCP activation is a policy boundary, not a transport concern.
3315
+ *
3316
+ * The request deliberately contains only public identity material. Connection secrets such as
3317
+ * API keys and arbitrary headers stay in IMCPServerDefinition(Resolved) and are never persisted in
3318
+ * this ledger.
3319
+ */
3320
+ type TMCPActivationSource = 'managed' | 'user' | 'project' | 'plugin' | 'local';
3321
+ interface IMCPActivationProvenance {
3322
+ readonly kind: TMCPActivationSource;
3323
+ readonly id: string;
3324
+ readonly version?: string;
3325
+ }
3326
+ type TMCPActivationStatus = 'approved' | 'pending' | 'rejected' | 'revoked' | 'stale' | 'untrusted';
3327
+ type TMCPApprovalAuthority = 'managed' | 'user' | 'local' | 'project' | 'plugin';
3328
+ interface IMCPActivationApprovalRecord {
3329
+ readonly serverId: string;
3330
+ readonly source: TMCPActivationSource;
3331
+ readonly provenance: IMCPActivationProvenance;
3332
+ readonly definitionFingerprint: string;
3333
+ readonly securityIdentity: string;
3334
+ readonly approvalAuthority: TMCPApprovalAuthority;
3335
+ readonly decision: Extract<TMCPActivationStatus, 'approved' | 'rejected' | 'revoked'>;
3336
+ readonly repositoryKey?: string;
3337
+ readonly workspaceGeneration?: number;
3338
+ readonly decidedAt: string;
3339
+ }
3340
+ /** Public audit data. It intentionally has no endpoint, API key, or arbitrary request headers. */
3341
+ interface IMCPActivationAuditEvent {
3342
+ readonly action: 'approve' | 'reject' | 'revoke';
3343
+ readonly serverId: string;
3344
+ readonly source: TMCPActivationSource;
3345
+ readonly provenanceId: string;
3346
+ readonly definitionFingerprint: string;
3347
+ readonly securityIdentity: string;
3348
+ readonly decision: Extract<TMCPActivationStatus, 'approved' | 'rejected' | 'revoked'>;
3349
+ readonly at: string;
3350
+ }
3351
+ interface IMCPActivationApprovalStore {
3352
+ list(): readonly IMCPActivationApprovalRecord[];
3353
+ put(record: IMCPActivationApprovalRecord): void;
3354
+ listAudit(): readonly IMCPActivationAuditEvent[];
3355
+ appendAudit(event: IMCPActivationAuditEvent): void;
3356
+ }
3357
+ interface IMCPHttpTransportDeps {
3358
+ /** Egress policy; default refuses private, loopback and metadata destinations. */
3359
+ readonly policy?: IEgressPolicy;
3360
+ /** Hostname resolver injected so tests never touch DNS. */
3361
+ readonly lookup?: TEgressLookup;
3362
+ /** Fetch used by the SDK transport; default is the global one. */
3363
+ readonly fetch?: typeof globalThis.fetch;
3364
+ }
3365
+ //#endregion
3366
+ //#region src/client/stdio-types.d.ts
3367
+ interface IMCPStdioExecutable {
3368
+ readonly command: string;
3369
+ /** Every vector is one exact command line the host permits. */
3370
+ readonly args: readonly (readonly string[])[];
3371
+ }
3372
+ interface IMCPStdioAuthority {
3373
+ readonly allowedRoot: string;
3374
+ /** Changing this value invalidates every existing admitted snapshot. */
3375
+ readonly generation: string;
3376
+ readonly executables: readonly IMCPStdioExecutable[];
3377
+ /** Only host-selected values are passed to the child. */
3378
+ readonly environment?: Readonly<Record<string, string>>;
3379
+ /** Definition env keys must be explicitly allowed and their values match host-selected values. */
3380
+ readonly allowedEnvironmentKeys?: readonly string[];
3381
+ readonly startupMs?: number;
3382
+ readonly cleanupMs?: number;
3383
+ }
3384
+ //#endregion
3385
+ //#region src/startup/cli-options-types.d.ts
3386
+ /**
3387
+ * Leaf type module: holds {@link IStartCliOptions} so it can be imported by both
3388
+ * `command-setup.ts` and `doctor-inputs.ts` without creating an import cycle between them.
3389
+ * Re-exported from `command-setup.ts` so existing imports keep working.
3390
+ */
3391
+ interface IStartCliOptions {
3392
+ commandModules?: readonly ICommandModule[];
3393
+ providerDefinitions?: readonly IProviderDefinition[];
3394
+ /** Initial trusted-or-restricted workspace decision. Absence is Restricted. */
3395
+ projectAccess?: TWorkspaceProjectAccess;
3396
+ /** `--safe-mode`: every customization off — see `SAFE_MODE_FLAG`. */
3397
+ safeMode?: boolean;
3398
+ /** Separately approved project-settings write capability. */
3399
+ projectSettingsWriter?: IWorkspaceProjectSettingsWriter;
3400
+ /** Separately approved bounded project mutation capability. */
3401
+ projectMutation?: IWorkspaceProjectMutation;
3402
+ /** Host-composed MCP definition registry and trust-admission controller. */
3403
+ mcpActivationAdapter?: ICommandMCPActivationAdapter;
3404
+ /** Host-owned per-server subprocess capabilities; never inferred from settings. */
3405
+ mcpStdioAuthorities?: Readonly<Record<string, IMCPStdioAuthority>>;
3406
+ /** Host-owned approval state, shared with the canonical MCP activation controller. */
3407
+ mcpApprovalStore?: IMCPActivationApprovalStore;
3408
+ /** Host-owned HTTP transport policy; never supplied by MCP settings or a remote caller. */
3409
+ mcpHttpTransportDeps?: IMCPHttpTransportDeps;
3410
+ /** Host-configured character limits; generic admission validates the ordering and ceiling. */
3411
+ mcpResultAdmissionLimits?: Pick<IToolResultAdmissionOptions, 'warningChars' | 'hardChars' | 'repositoryMaxChars'>;
3412
+ /** Host-composed managed output styles, applied above user/project style sources. */
3413
+ managedOutputStyleSources?: readonly IOutputStyleSource[];
3414
+ }
3415
+ //#endregion
3416
+ //#region src/cli.d.ts
3417
+ /** Full CLI entry: supplies its terminal presentation to the shared serve/bootstrap path. */
3418
+ declare function startCli(options?: IStartCliOptions): Promise<void>;
3419
+ //#endregion
3420
+ export { type IStartCliOptions, startCli };
3421
+ //# sourceMappingURL=index.d.cts.map