@xenosystem/agent-interface-contract 0.1.0

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.
@@ -0,0 +1,2019 @@
1
+ export * from './cloudRuns.js';
2
+ import type * as Engineering from './engineering.js';
3
+ export declare const XENO_AGENT_HOST_PROTOCOL_VERSION: 1;
4
+ export declare const XENO_AGENT_HOST_MIN_PROTOCOL_VERSION: 1;
5
+ export declare const AGENT_SURFACE_KINDS: readonly ["standalone-desktop", "hub-embed", "shell-embed", "embed-preview", "headless-client"];
6
+ export type AgentSurfaceKind = (typeof AGENT_SURFACE_KINDS)[number];
7
+ export declare const AGENT_RUNTIME_PROVIDER_KINDS: readonly ["sdk-native", "xeno-cloud", "cli-app-server", "cli-remote", "acp"];
8
+ export type AgentRuntimeProviderKind = (typeof AGENT_RUNTIME_PROVIDER_KINDS)[number];
9
+ export declare const AGENT_HARNESS_CAPABILITIES: readonly ["development.execution", "turn.streaming", "turn.reasoning", "turn.cancel", "turn.resume", "acp.provider.approve", "turn.queue", "turn.steer", "tools.file.read", "tools.file.write", "tools.patch", "tools.terminal", "tools.background-process", "git.operations", "review.selective-hunks", "checkpoints.create", "checkpoints.restore", "workspace.multi-root", "code.lsp", "browser.automation", "browser.devtools", "context.semantic-retrieval", "context.compaction", "mcp", "plugins", "skills", "hooks", "subagents", "background-runs", "remote-runs", "usage.reporting", "support.diagnostics", "coordination.messages", "coordination.claims", "coordination.query"];
10
+ export type AgentHarnessCapability = (typeof AGENT_HARNESS_CAPABILITIES)[number];
11
+ export type AgentAvailability = 'available' | 'degraded' | 'blocked' | 'unavailable';
12
+ export type AgentCapabilityStatus = 'available' | 'degraded' | 'blocked' | 'unsupported';
13
+ export interface AgentCapabilityDescriptor {
14
+ status: AgentCapabilityStatus;
15
+ source: 'provider' | 'host' | 'policy';
16
+ reason?: string;
17
+ version?: string;
18
+ }
19
+ export type AgentCapabilityMatrix = Partial<Record<AgentHarnessCapability, AgentCapabilityDescriptor>>;
20
+ export interface AgentReasoningOption {
21
+ id: string;
22
+ label: string;
23
+ description?: string;
24
+ runtimeModelId?: string;
25
+ isDefault?: boolean;
26
+ }
27
+ export interface AgentModelDescriptor {
28
+ id: string;
29
+ displayName: string;
30
+ availability: AgentAvailability;
31
+ isDefault?: boolean;
32
+ contextWindowTokens?: number;
33
+ maxOutputTokens?: number;
34
+ reasoningOptions?: AgentReasoningOption[];
35
+ safeUnavailableReason?: string;
36
+ }
37
+ export interface AgentRuntimeProviderDescriptor {
38
+ id: string;
39
+ kind: AgentRuntimeProviderKind;
40
+ displayName: string;
41
+ availability: AgentAvailability;
42
+ safeUnavailableReason?: string;
43
+ capabilities: AgentCapabilityMatrix;
44
+ models: AgentModelDescriptor[];
45
+ defaultModelId?: string;
46
+ allowsProviderDefaultModel?: boolean;
47
+ catalogRevision: string;
48
+ }
49
+ export interface AgentRuntimeSelection {
50
+ providerId: string;
51
+ catalogRevision: string;
52
+ modelId?: string;
53
+ reasoningOptionId?: string;
54
+ runtimeModelId?: string;
55
+ }
56
+ export interface AgentHostProtocolRange {
57
+ min: number;
58
+ max: number;
59
+ }
60
+ export interface AgentHostClientIdentity {
61
+ clientId: string;
62
+ clientVersion: string;
63
+ instanceId: string;
64
+ surface: AgentSurfaceKind;
65
+ }
66
+ export type AgentEngineeringRequest<T extends Engineering.EngineeringRequestBase> = T & {
67
+ client: AgentHostClientIdentity;
68
+ };
69
+ export interface AgentHostHandshakeRequest {
70
+ identity: AgentHostClientIdentity;
71
+ supportedProtocol: AgentHostProtocolRange;
72
+ }
73
+ export interface AgentHostHandshake {
74
+ protocol: {
75
+ current: number;
76
+ supported: AgentHostProtocolRange;
77
+ };
78
+ host: {
79
+ instanceId: string;
80
+ version: string;
81
+ authority: 'primary' | 'diagnostic-read-only';
82
+ processBoundary: 'in-process' | 'per-user-service';
83
+ };
84
+ storage: {
85
+ owner: 'xeno-agent-host';
86
+ schemaVersion: number;
87
+ eventSchemaVersion: number;
88
+ };
89
+ surface: AgentHostClientIdentity;
90
+ }
91
+ /**
92
+ * ๐Ÿ”ด THE HANDSHAKE HAS NO `capabilities`, and its absence is deliberate.
93
+ *
94
+ * It used to carry an `AgentCapabilityMatrix`. No composition ever passed one,
95
+ * so every real host sent `{}`, and nothing anywhere read it โ€” but "unused" is
96
+ * the weaker half of the reason.
97
+ *
98
+ * The strong half: a host-level matrix is at the WRONG GRANULARITY to ever be
99
+ * correct. Capabilities in this system belong to a PROVIDER
100
+ * (`AgentRuntimeProviderDescriptor.capabilities`), because what an agent can do
101
+ * depends on which lane is executing it โ€” and the host lowers them further at
102
+ * registration when it, not the provider, owns the answer
103
+ * (`withHostBackedCapabilities`, `source: 'host'`). One matrix for the whole
104
+ * host could only ever be a summary that is wrong for some provider.
105
+ *
106
+ * Left in place it would eventually be "fixed" by populating it, and surfaces
107
+ * would start reading a claim no host can honestly make. Ask a provider.
108
+ */
109
+ export interface AgentProviderListRequest {
110
+ includeUnavailable?: boolean;
111
+ }
112
+ export type AgentProviderRefreshRequest = AgentProviderListRequest;
113
+ export interface AgentProviderListResult {
114
+ revision: string;
115
+ providers: AgentRuntimeProviderDescriptor[];
116
+ }
117
+ export interface AgentRuntimeEventEnvelope {
118
+ id: string;
119
+ sequence: number;
120
+ timestamp: string;
121
+ conversationId: string;
122
+ requestId: string;
123
+ workspaceId?: string;
124
+ teamId?: string;
125
+ agentId?: string;
126
+ parentRunId?: string;
127
+ subagentRunId?: string;
128
+ providerKind?: string;
129
+ providerId?: string;
130
+ type: string;
131
+ source: string;
132
+ schemaVersion?: string;
133
+ redactionState?: string;
134
+ event: Record<string, unknown>;
135
+ }
136
+ export interface AgentRuntimeEventDraft {
137
+ conversationId: string;
138
+ requestId: string;
139
+ workspaceId?: string;
140
+ teamId?: string;
141
+ agentId?: string;
142
+ parentRunId?: string;
143
+ subagentRunId?: string;
144
+ providerKind?: string;
145
+ providerId?: string;
146
+ source?: string;
147
+ schemaVersion?: string;
148
+ redactionState?: string;
149
+ event: Record<string, unknown> & {
150
+ id: string;
151
+ type: string;
152
+ timestamp: string;
153
+ };
154
+ }
155
+ export interface AgentRuntimeEventListRequest {
156
+ conversationId: string;
157
+ requestId?: string;
158
+ subagentRunId?: string;
159
+ type?: string;
160
+ afterSequence?: number;
161
+ limit?: number;
162
+ }
163
+ export interface AgentRuntimeEventListResult {
164
+ events: AgentRuntimeEventEnvelope[];
165
+ nextSequence: number | null;
166
+ }
167
+ /**
168
+ * Transitional host-owned snapshot persistence used while the legacy JSON
169
+ * stores are migrated into the final transactional state database. The host
170
+ * validates and sanitizes these opaque renderer projections before writing.
171
+ */
172
+ export interface AgentWorkspaceStateLoadResult {
173
+ success: boolean;
174
+ workspaces: unknown[];
175
+ error?: string;
176
+ }
177
+ export interface AgentWorkspaceStateSaveRequest {
178
+ workspaces: unknown[];
179
+ }
180
+ export interface AgentWorkspaceStateSaveResult {
181
+ success: boolean;
182
+ error?: string;
183
+ }
184
+ export interface AgentConversationStateLoadResult {
185
+ success: boolean;
186
+ conversations: unknown[];
187
+ recoveredConversationIds?: string[];
188
+ corruptConversationFiles?: string[];
189
+ error?: string;
190
+ }
191
+ export interface AgentConversationStateSaveRequest {
192
+ conversation: unknown;
193
+ }
194
+ export interface AgentConversationStateSaveResult {
195
+ success: boolean;
196
+ error?: string;
197
+ }
198
+ export interface AgentConversationStateDeleteRequest {
199
+ conversationId: string;
200
+ }
201
+ export interface AgentConversationStateDeleteResult {
202
+ success: boolean;
203
+ deleted?: boolean;
204
+ error?: string;
205
+ }
206
+ export interface AgentWorkspaceAccessContext {
207
+ client: AgentHostClientIdentity;
208
+ allowedDirectories: string[];
209
+ conversationId?: string;
210
+ workspaceId?: string;
211
+ teamId?: string;
212
+ agentId?: string;
213
+ }
214
+ export interface AgentWorkspaceGrantRequest {
215
+ path: string;
216
+ source: 'user-picker' | 'legacy-migration' | 'host-managed';
217
+ }
218
+ export interface AgentWorkspaceGrantResult {
219
+ success: boolean;
220
+ path: string | null;
221
+ error: string | null;
222
+ }
223
+ /**
224
+ * Authorising an APPLICATION the agent may launch a file with.
225
+ *
226
+ * ๐Ÿ”ด A host method rather than a local call, because the grant is mutable Agent
227
+ * state and ยง7 gives that exactly one owner. It had no method: the desktop
228
+ * composition called `WorkspaceHostService.grantApplication` directly on a
229
+ * service it built itself. In-process that happened to be the authority; under
230
+ * ยง9 step 3, where a DETACHED host owns the lease, it was a second process
231
+ * writing the authority's store behind its back โ€” and the owner holds its
232
+ * grants in memory, so it never saw the write, while the user was told
233
+ * `success: true`.
234
+ */
235
+ /**
236
+ * Messages withheld from a run, awaiting a human โ€” coordination ยง6 `hold`.
237
+ *
238
+ * ๐Ÿ”ด The human half of coordination had NO protocol surface at all. The
239
+ * message bus implements the whole lifecycle โ€” set an inbound policy, list
240
+ * what it withheld, release one โ€” and nothing above it exposed the last two,
241
+ * so `hold` was a state a message could enter and never leave. ยง6 requires a
242
+ * held message to be "surfaced to the human for approval"; without these a
243
+ * hold is a silent drop with extra steps.
244
+ */
245
+ export interface AgentCoordinationHeldListRequest {
246
+ runId: string;
247
+ }
248
+ export interface AgentCoordinationHeldMessage {
249
+ id: string;
250
+ fromRunId: string;
251
+ text: string;
252
+ sentAt: number;
253
+ }
254
+ export interface AgentCoordinationHeldListResult {
255
+ /** False when this host has no coordination service โ€” distinct from a run
256
+ * that simply has nothing held. */
257
+ available: boolean;
258
+ runId: string;
259
+ held: AgentCoordinationHeldMessage[];
260
+ reason?: string;
261
+ }
262
+ export interface AgentCoordinationHeldReleaseRequest {
263
+ command: AgentHostCommandContext;
264
+ runId: string;
265
+ messageId: string;
266
+ }
267
+ export interface AgentCoordinationHeldReleaseResult {
268
+ /** The message's OUTCOME, not a boolean: ยง6 requires the sender to learn
269
+ * what became of every message, and a release can legitimately find
270
+ * nothing, which is `expired` rather than failure. */
271
+ status: 'delivered' | 'expired' | 'refused' | 'held';
272
+ messageId: string;
273
+ reason?: string;
274
+ }
275
+ /**
276
+ * Sets or clears a run's inbound-message policy โ€” ยง6.
277
+ *
278
+ * ๐Ÿ”ด A HUMAN method, deliberately absent from the turn-execution lane port. An
279
+ * agent choosing its own receiver's policy could accept its way past the rule
280
+ * that a message never moves trust upward, which is the one thing ยง6 exists to
281
+ * prevent.
282
+ */
283
+ export interface AgentCoordinationPolicySetRequest {
284
+ command: AgentHostCommandContext;
285
+ runId: string;
286
+ /**
287
+ * `null` CLEARS the override and returns the run to the derived default.
288
+ *
289
+ * Distinct from `'accept'`: one hands the decision back to ยง6, the other pins
290
+ * the permissive answer permanently. Without a clear, setting a policy is a
291
+ * one-way door.
292
+ */
293
+ policy: 'accept' | 'hold' | 'refuse' | null;
294
+ }
295
+ export interface AgentCoordinationPolicySetResult {
296
+ ok: boolean;
297
+ /** What a human has pinned, absent when the derivation decides. */
298
+ explicit?: 'accept' | 'hold' | 'refuse';
299
+ /** Why not, when not โ€” never a bare false. */
300
+ reason?: string;
301
+ }
302
+ export interface AgentWorkspaceApplicationGrantRequest {
303
+ path: string;
304
+ source: 'user-picker' | 'legacy-migration' | 'host-managed';
305
+ }
306
+ export interface AgentWorkspaceApplicationGrantResult {
307
+ success: boolean;
308
+ appPath: string | null;
309
+ error: string | null;
310
+ }
311
+ export interface AgentWorkspaceDirectoryEntry {
312
+ name: string;
313
+ path: string;
314
+ size: number;
315
+ modified: string;
316
+ type: 'file' | 'directory';
317
+ extension: string;
318
+ }
319
+ export interface AgentWorkspaceDirectoryListRequest extends AgentWorkspaceAccessContext {
320
+ dirPath: string;
321
+ }
322
+ export interface AgentWorkspaceDirectoryListResult {
323
+ success: boolean;
324
+ entries: AgentWorkspaceDirectoryEntry[];
325
+ error: string | null;
326
+ }
327
+ export interface AgentWorkspaceFileReadRequest extends AgentWorkspaceAccessContext {
328
+ path: string;
329
+ }
330
+ export interface AgentWorkspaceFileReadResult {
331
+ success: boolean;
332
+ path: string | null;
333
+ content: string;
334
+ bytes: number;
335
+ error: string | null;
336
+ }
337
+ export interface AgentWorkspaceFileWriteRequest extends AgentWorkspaceAccessContext {
338
+ path: string;
339
+ content: string;
340
+ }
341
+ export interface AgentWorkspaceFileWriteResult {
342
+ success: boolean;
343
+ path: string | null;
344
+ bytes: number;
345
+ error: string | null;
346
+ }
347
+ export interface AgentWorkspaceCommandRunRequest extends AgentWorkspaceAccessContext {
348
+ command: string;
349
+ cwd?: string;
350
+ timeoutMs?: number;
351
+ }
352
+ export interface AgentWorkspaceCommandRunResult {
353
+ success: boolean;
354
+ stdout: string;
355
+ stderr: string;
356
+ exitCode: number | null;
357
+ cwd: string | null;
358
+ error: string | null;
359
+ /**
360
+ * Output hit the ceiling and was trimmed.
361
+ *
362
+ * ๐Ÿ”ด REQUIRED, and it was missing. This result trimmed at 200 KB and said
363
+ * nothing, so a caller could not tell a short output from a truncated one โ€”
364
+ * and the shorter one is the dangerous reading, because a reader concludes
365
+ * "that's all it printed". The host always knows whether it trimmed, so there
366
+ * is no case for making this optional: an absent field would mean "cannot
367
+ * answer", and it can.
368
+ */
369
+ truncated: boolean;
370
+ }
371
+ export interface AgentWorkspaceTerminalStartRequest extends AgentWorkspaceAccessContext {
372
+ command: string;
373
+ cwd?: string;
374
+ timeoutMs?: number;
375
+ }
376
+ export interface AgentWorkspaceTerminalStartResult {
377
+ success: boolean;
378
+ terminalId: string | null;
379
+ cwd: string | null;
380
+ error: string | null;
381
+ }
382
+ export interface AgentWorkspaceTerminalControlRequest extends AgentWorkspaceAccessContext {
383
+ terminalId: string;
384
+ }
385
+ export interface AgentWorkspaceTerminalControlResult {
386
+ success: boolean;
387
+ error: string | null;
388
+ }
389
+ export interface AgentWorkspacePtyStartRequest extends AgentWorkspaceAccessContext {
390
+ cwd?: string;
391
+ cols?: number;
392
+ rows?: number;
393
+ }
394
+ export interface AgentWorkspacePtyStartResult {
395
+ success: boolean;
396
+ terminalId: string | null;
397
+ cwd: string | null;
398
+ error: string | null;
399
+ }
400
+ export interface AgentWorkspacePtySnapshotRequest extends AgentWorkspaceTerminalControlRequest {
401
+ }
402
+ export interface AgentWorkspacePtySnapshotResult {
403
+ success: boolean;
404
+ exists: boolean;
405
+ terminalId: string;
406
+ cwd: string | null;
407
+ output: string;
408
+ error: string | null;
409
+ }
410
+ export interface AgentWorkspacePtyInputRequest extends AgentWorkspaceTerminalControlRequest {
411
+ data: string;
412
+ }
413
+ export interface AgentWorkspacePtyResizeRequest extends AgentWorkspaceTerminalControlRequest {
414
+ cols: number;
415
+ rows: number;
416
+ }
417
+ export interface AgentHostCommandContext {
418
+ schemaVersion: 1;
419
+ commandId: string;
420
+ idempotencyKey: string;
421
+ client: AgentHostClientIdentity;
422
+ }
423
+ export type AgentTurnMode = 'development' | 'chat';
424
+ export interface AgentTurnMessage {
425
+ role: 'user' | 'assistant';
426
+ content: string;
427
+ }
428
+ export interface AgentTurnWorkspace {
429
+ primaryDirectory?: string;
430
+ additionalDirectories?: string[];
431
+ permissionProfile?: string;
432
+ filesystem?: 'read-only' | 'workspace-write';
433
+ }
434
+ export interface AgentTurnExecutionOptions {
435
+ maxIterations?: number;
436
+ enableThinking?: boolean;
437
+ capabilities?: {
438
+ terminal?: boolean;
439
+ browser?: boolean;
440
+ fileRead?: boolean;
441
+ fileWrite?: boolean;
442
+ appLaunch?: boolean;
443
+ webSearch?: boolean;
444
+ };
445
+ approvalRules?: Array<Record<string, unknown>>;
446
+ }
447
+ export interface AgentTurnContinuation {
448
+ providerId: string;
449
+ providerSessionId: string;
450
+ state?: Record<string, unknown>;
451
+ providerConfigFingerprint?: string;
452
+ workspaceFingerprint?: string;
453
+ }
454
+ export interface AgentTurnContextCompaction {
455
+ strategyVersion: number;
456
+ rawMessageCount: number;
457
+ sentMessageCount: number;
458
+ compactedMessageCount: number;
459
+ estimatedRawTokens: number;
460
+ estimatedSentTokens: number;
461
+ retainedAnchorCount: number;
462
+ retainedArtifactCount: number;
463
+ retainedGrantedDirectoryCount: number;
464
+ contextDigest: string;
465
+ }
466
+ export interface AgentTurnStartRequest {
467
+ command: AgentHostCommandContext;
468
+ conversationId: string;
469
+ requestId: string;
470
+ workspaceId?: string;
471
+ teamId?: string;
472
+ agentId?: string;
473
+ subagentRunId?: string;
474
+ mode: AgentTurnMode;
475
+ selection: AgentRuntimeSelection;
476
+ prompt: string;
477
+ history?: AgentTurnMessage[];
478
+ systemPrompt?: string;
479
+ workspace?: AgentTurnWorkspace;
480
+ execution?: AgentTurnExecutionOptions;
481
+ continuation?: AgentTurnContinuation;
482
+ contextCompaction?: AgentTurnContextCompaction;
483
+ timeoutMs?: number;
484
+ }
485
+ export type AgentTurnStartFailureCode = 'invalid_request' | 'client_not_connected' | 'idempotency_conflict' | 'provider_not_found' | 'provider_unavailable' | 'catalog_revision_mismatch' | 'model_not_found' | 'model_unavailable' | 'model_required' | 'reasoning_option_not_found' | 'development_capability_missing' | 'adapter_unavailable' | 'request_already_active';
486
+ export type AgentTurnStartResult = {
487
+ success: true;
488
+ status: 'accepted' | 'replayed';
489
+ conversationId: string;
490
+ requestId: string;
491
+ adapterId: string;
492
+ selection: AgentRuntimeSelection;
493
+ } | {
494
+ success: false;
495
+ code: AgentTurnStartFailureCode;
496
+ safeError: string;
497
+ conversationId?: string;
498
+ requestId?: string;
499
+ };
500
+ export interface AgentTurnCancelRequest {
501
+ command: AgentHostCommandContext;
502
+ conversationId: string;
503
+ requestId: string;
504
+ reason?: string;
505
+ }
506
+ export type AgentTurnCancelResult = {
507
+ success: true;
508
+ status: 'cancel_requested' | 'replayed';
509
+ conversationId: string;
510
+ requestId: string;
511
+ } | {
512
+ success: false;
513
+ code: 'invalid_request' | 'client_not_connected' | 'idempotency_conflict' | 'turn_not_active';
514
+ safeError: string;
515
+ conversationId?: string;
516
+ requestId?: string;
517
+ };
518
+ /**
519
+ * How a steer reached the agent. Reported so the surface can show the user
520
+ * which structure tier a session is running at (ADE spec ร‚ยง6.3 requires the tier
521
+ * to be visible, not inferred).
522
+ *
523
+ * - `adapter` รขโ‚ฌโ€ delivered over the protocol; the agent acknowledged receipt.
524
+ * - `pty` รขโ‚ฌโ€ written into the terminal we own, indistinguishable from the
525
+ * user typing. Real steering, but WITHOUT acknowledgement: we do
526
+ * not learn whether the agent accepted or integrated it (ร‚ยง10b).
527
+ * Not yet available; arrives with the session substrate.
528
+ *
529
+ * รฐลธโ€ยด NEITHER delivery is instantaneous, and no surface may imply that it is.
530
+ * Measured against real Claude Code on 2026-08-11: a correction injected into a
531
+ * running turn was honoured at the agent's NEXT DECISION POINT, not inside the
532
+ * tool call already in flight รขโ‚ฌโ€ one further file was written after the steer
533
+ * landed. So `delivered` means "the agent has it", never "the agent has
534
+ * stopped". That distance is about one tool call, which is exactly the window
535
+ * in which a destructive command completes. `turn.cancel` is the mechanism for
536
+ * STOP; steering is for REDIRECT, and the two do not share a latency.
537
+ * Evidence: docs/evidence/PTY_STEERING_2026-08-11.md
538
+ */
539
+ export type AgentTurnSteerDelivery = 'adapter' | 'pty';
540
+ export interface AgentTurnSteerRequest {
541
+ command: AgentHostCommandContext;
542
+ conversationId: string;
543
+ requestId: string;
544
+ instruction: string;
545
+ }
546
+ export type AgentTurnSteerResult = {
547
+ success: true;
548
+ status: 'delivered' | 'replayed';
549
+ /** Whether the agent confirmed receipt. False for `pty` delivery. */
550
+ acknowledged: boolean;
551
+ deliveredVia: AgentTurnSteerDelivery;
552
+ conversationId: string;
553
+ requestId: string;
554
+ } | {
555
+ success: false;
556
+ code: 'invalid_request' | 'client_not_connected' | 'idempotency_conflict' | 'turn_not_active' | 'steer_unsupported';
557
+ safeError: string;
558
+ conversationId?: string;
559
+ requestId?: string;
560
+ };
561
+ /**
562
+ * A instruction the user stacked while a turn was still running.
563
+ *
564
+ * Queueing is deliberately a HOST concern rather than an adapter one: the host
565
+ * holds the instruction and signals when the active turn ends, so it works at
566
+ * every structure tier (ADE spec ร‚ยง2.9) รขโ‚ฌโ€ including a third-party agent running
567
+ * its own TUI, where no protocol exists to hand a steer to. This is why ร‚ยง10b
568
+ * lists `turn.queue` as available rather than degraded.
569
+ */
570
+ export interface AgentTurnQueuedInstruction {
571
+ id: string;
572
+ instruction: string;
573
+ queuedAt: string;
574
+ /** Surface instance that queued it, for provenance in the timeline. */
575
+ queuedByInstanceId: string;
576
+ }
577
+ export interface AgentTurnQueueRequest {
578
+ command: AgentHostCommandContext;
579
+ conversationId: string;
580
+ /** Discard anything already queued for this conversation first. */
581
+ replace?: boolean;
582
+ instruction: string;
583
+ }
584
+ export type AgentTurnQueueResult = {
585
+ success: true;
586
+ status: 'queued' | 'replayed';
587
+ conversationId: string;
588
+ queue: AgentTurnQueuedInstruction[];
589
+ } | {
590
+ success: false;
591
+ code: 'invalid_request' | 'client_not_connected' | 'idempotency_conflict' | 'queue_full';
592
+ safeError: string;
593
+ conversationId?: string;
594
+ };
595
+ export interface AgentTurnQueueListRequest {
596
+ conversationId: string;
597
+ }
598
+ export interface AgentTurnQueueListResult {
599
+ conversationId: string;
600
+ queue: AgentTurnQueuedInstruction[];
601
+ /** True while a turn is running, i.e. the queue is not drainable yet. */
602
+ turnActive: boolean;
603
+ }
604
+ export interface AgentTurnQueueDropRequest {
605
+ command: AgentHostCommandContext;
606
+ conversationId: string;
607
+ /** Omit to clear the whole queue. */
608
+ instructionId?: string;
609
+ }
610
+ export type AgentTurnQueueDropResult = {
611
+ success: true;
612
+ conversationId: string;
613
+ queue: AgentTurnQueuedInstruction[];
614
+ } | {
615
+ success: false;
616
+ code: 'invalid_request' | 'client_not_connected' | 'not_found';
617
+ safeError: string;
618
+ conversationId?: string;
619
+ };
620
+ export interface AgentChooseDirectoryAnswerRequest {
621
+ requestId?: string;
622
+ chooseDirectoryId: string;
623
+ path?: string;
624
+ cancelled?: boolean;
625
+ error?: string;
626
+ }
627
+ export interface AgentChooseDirectoryAnswerResult {
628
+ success: boolean;
629
+ error?: string;
630
+ chooseDirectoryId?: string;
631
+ requestId?: string;
632
+ path?: string;
633
+ cancelled?: boolean;
634
+ responseError?: string;
635
+ }
636
+ export type AgentWorkspacePlacementChoice = 'inbox' | 'reuse' | 'create';
637
+ export interface AgentWorkspacePlacementAnswerRequest {
638
+ requestId?: string;
639
+ workspacePlacementId: string;
640
+ directory?: string;
641
+ choice?: AgentWorkspacePlacementChoice;
642
+ workspaceName?: string;
643
+ result?: string;
644
+ cancelled?: boolean;
645
+ error?: string;
646
+ }
647
+ export interface AgentWorkspacePlacementResponse {
648
+ choice?: AgentWorkspacePlacementChoice;
649
+ directory?: string;
650
+ workspaceName?: string;
651
+ result?: string;
652
+ cancelled?: boolean;
653
+ error?: string;
654
+ timedOut?: boolean;
655
+ }
656
+ export interface AgentWorkspacePlacementAnswerResult {
657
+ success: boolean;
658
+ error?: string;
659
+ workspacePlacementId?: string;
660
+ requestId?: string;
661
+ response?: AgentWorkspacePlacementResponse;
662
+ }
663
+ export interface AgentPermissionAnswerRequest {
664
+ permissionId: string;
665
+ granted: boolean;
666
+ directory?: string;
667
+ /**
668
+ * An explicit choice among the options the agent offered (ACP lane). This is
669
+ * how a surface says "allow ALWAYS" rather than "allow once" โ€” the boolean
670
+ * alone cannot express it, so without this a user can never create a
671
+ * host-owned policy rule.
672
+ *
673
+ * Advisory, never authoritative: the host validates it against the options
674
+ * actually offered and ignores anything else. The renderer is untrusted (ยง7).
675
+ */
676
+ selectedOptionId?: string;
677
+ }
678
+ /**
679
+ * A stored, host-owned permission rule (ACP lane).
680
+ *
681
+ * Surfaced so a user can SEE and REVOKE what they approved. A rule that can be
682
+ * created but not removed is a one-way door, and these both persist and
683
+ * accumulate.
684
+ */
685
+ export interface AgentTurnResumeRequest {
686
+ command: AgentHostCommandContext;
687
+ conversationId: string;
688
+ requestId: string;
689
+ }
690
+ /**
691
+ * โš ๏ธ `status: 'restarted'` is deliberate and is NOT a synonym for "resumed".
692
+ *
693
+ * A turn killed by process death left no continuation point inside the agent โ€”
694
+ * only the request that produced it. So the host RE-ISSUES that request: any
695
+ * work the agent had already done is done again, and side effects it already
696
+ * performed have already happened. Where the request carries a provider
697
+ * continuation the provider session is picked up, which narrows the gap but
698
+ * does not close it.
699
+ *
700
+ * Reporting this as `resumed` would promise a continuation the host cannot
701
+ * deliver, and the user would discover the difference by watching an agent redo
702
+ * something destructive.
703
+ */
704
+ export type AgentTurnResumeResult = {
705
+ success: true;
706
+ status: 'restarted';
707
+ conversationId: string;
708
+ requestId: string;
709
+ adapterId: string;
710
+ } | {
711
+ success: false;
712
+ code: 'invalid_request' | 'client_not_connected' | 'not_interrupted' | 'turn_already_active' | 'resume_failed';
713
+ safeError: string;
714
+ conversationId?: string;
715
+ requestId?: string;
716
+ };
717
+ export interface AgentPermissionRuleView {
718
+ id: string;
719
+ decision: 'allow' | 'deny';
720
+ toolKind?: string;
721
+ pathPrefix?: string;
722
+ createdAt?: number;
723
+ }
724
+ export interface AgentPermissionRuleListResult {
725
+ success: boolean;
726
+ rules: AgentPermissionRuleView[];
727
+ error?: string;
728
+ }
729
+ export interface AgentPermissionRuleRevokeRequest {
730
+ ruleId: string;
731
+ }
732
+ export interface AgentPermissionRuleRevokeResult {
733
+ success: boolean;
734
+ revoked: boolean;
735
+ error?: string;
736
+ }
737
+ export interface AgentPermissionAnswerResult {
738
+ success: boolean;
739
+ error?: string;
740
+ }
741
+ export interface AgentAskUserAnswerRequest {
742
+ askUserId: string;
743
+ answer: string;
744
+ selectedOption?: string;
745
+ cancelled?: boolean;
746
+ }
747
+ export interface AgentAskUserAnswerResult {
748
+ success: boolean;
749
+ error?: string;
750
+ }
751
+ export interface AgentSdkControlContext {
752
+ client: AgentHostClientIdentity;
753
+ }
754
+ export interface AgentSdkSessionListRequest extends AgentSdkControlContext {
755
+ role?: string;
756
+ workingDirectory?: string;
757
+ limit?: number;
758
+ }
759
+ export interface AgentSdkSessionListResult {
760
+ success: boolean;
761
+ sessions?: unknown[];
762
+ error?: string;
763
+ }
764
+ export interface AgentSdkSessionShowRequest extends AgentSdkControlContext {
765
+ sessionId: string;
766
+ }
767
+ export interface AgentSdkSessionShowResult {
768
+ success: boolean;
769
+ session?: unknown;
770
+ sessionDir?: string;
771
+ checkpoints?: unknown[];
772
+ error?: string;
773
+ }
774
+ export interface AgentSdkSessionAttachRequest extends AgentSdkControlContext {
775
+ conversationId: string;
776
+ sessionId: string;
777
+ }
778
+ export interface AgentSdkSessionAttachResult extends AgentSdkSessionShowResult {
779
+ sessionHistoryPath?: string;
780
+ }
781
+ export interface AgentSdkSessionDetachRequest extends AgentSdkControlContext {
782
+ conversationId: string;
783
+ }
784
+ export interface AgentSdkSessionDeleteRequest extends AgentSdkControlContext {
785
+ sessionId: string;
786
+ }
787
+ export interface AgentSdkSessionCleanRequest extends AgentSdkControlContext {
788
+ workingDirectory: string;
789
+ excludeSessionIds?: string[];
790
+ }
791
+ export interface AgentSdkSessionCleanResult {
792
+ success: boolean;
793
+ result?: unknown;
794
+ error?: string;
795
+ }
796
+ export interface AgentSdkMutationResult {
797
+ success: boolean;
798
+ error?: string;
799
+ }
800
+ export interface AgentSdkCheckpointListRequest extends AgentSdkControlContext {
801
+ sessionId: string;
802
+ }
803
+ export interface AgentSdkCheckpointListResult {
804
+ success: boolean;
805
+ checkpoints?: unknown[];
806
+ error?: string;
807
+ }
808
+ export interface AgentSdkCheckpointRestoreRequest extends AgentSdkControlContext {
809
+ sessionId: string;
810
+ checkpointId: string;
811
+ conversationId?: string;
812
+ }
813
+ export interface AgentSdkCheckpointRestoreResult {
814
+ success: boolean;
815
+ restored?: unknown;
816
+ pendingRuntimeRestore?: boolean;
817
+ error?: string;
818
+ }
819
+ export interface AgentSdkCheckpointDeleteRequest extends AgentSdkControlContext {
820
+ sessionId: string;
821
+ checkpointId: string;
822
+ }
823
+ export interface AgentSdkTaskOutputRequest extends AgentSdkControlContext {
824
+ taskId: string;
825
+ offset?: number;
826
+ }
827
+ export type AgentSdkTaskStatus = 'running' | 'completed' | 'failed' | 'stopped' | 'unknown';
828
+ export interface AgentSdkTaskResult {
829
+ success: boolean;
830
+ output?: string;
831
+ error?: string;
832
+ command?: string;
833
+ status?: AgentSdkTaskStatus;
834
+ exitCode?: number | null;
835
+ totalSize?: number;
836
+ }
837
+ export interface AgentSdkTaskStopRequest extends AgentSdkControlContext {
838
+ taskId: string;
839
+ }
840
+ export interface AgentHostRequestMap {
841
+ 'host.handshake': {
842
+ input: AgentHostHandshakeRequest;
843
+ output: AgentHostHandshake;
844
+ };
845
+ 'providers.list': {
846
+ input: AgentProviderListRequest;
847
+ output: AgentProviderListResult;
848
+ };
849
+ 'providers.refresh': {
850
+ input: AgentProviderRefreshRequest;
851
+ output: AgentProviderListResult;
852
+ };
853
+ 'runtime.events.list': {
854
+ input: AgentRuntimeEventListRequest;
855
+ output: AgentRuntimeEventListResult;
856
+ };
857
+ 'state.workspaces.load': {
858
+ input: Record<string, never>;
859
+ output: AgentWorkspaceStateLoadResult;
860
+ };
861
+ 'state.workspaces.save': {
862
+ input: AgentWorkspaceStateSaveRequest;
863
+ output: AgentWorkspaceStateSaveResult;
864
+ };
865
+ 'state.conversations.load': {
866
+ input: Record<string, never>;
867
+ output: AgentConversationStateLoadResult;
868
+ };
869
+ 'state.conversations.save': {
870
+ input: AgentConversationStateSaveRequest;
871
+ output: AgentConversationStateSaveResult;
872
+ };
873
+ 'state.conversations.delete': {
874
+ input: AgentConversationStateDeleteRequest;
875
+ output: AgentConversationStateDeleteResult;
876
+ };
877
+ 'workspace.access.grant': {
878
+ input: AgentWorkspaceGrantRequest;
879
+ output: AgentWorkspaceGrantResult;
880
+ };
881
+ 'coordination.held.list': {
882
+ input: AgentCoordinationHeldListRequest;
883
+ output: AgentCoordinationHeldListResult;
884
+ };
885
+ 'coordination.held.release': {
886
+ input: AgentCoordinationHeldReleaseRequest;
887
+ output: AgentCoordinationHeldReleaseResult;
888
+ };
889
+ 'coordination.policy.set': {
890
+ input: AgentCoordinationPolicySetRequest;
891
+ output: AgentCoordinationPolicySetResult;
892
+ };
893
+ 'workspace.application.grant': {
894
+ input: AgentWorkspaceApplicationGrantRequest;
895
+ output: AgentWorkspaceApplicationGrantResult;
896
+ };
897
+ 'workspace.directory.list': {
898
+ input: AgentWorkspaceDirectoryListRequest;
899
+ output: AgentWorkspaceDirectoryListResult;
900
+ };
901
+ 'workspace.file.read': {
902
+ input: AgentWorkspaceFileReadRequest;
903
+ output: AgentWorkspaceFileReadResult;
904
+ };
905
+ 'workspace.file.write': {
906
+ input: AgentWorkspaceFileWriteRequest;
907
+ output: AgentWorkspaceFileWriteResult;
908
+ };
909
+ 'workspace.command.run': {
910
+ input: AgentWorkspaceCommandRunRequest;
911
+ output: AgentWorkspaceCommandRunResult;
912
+ };
913
+ 'workspace.terminal.start': {
914
+ input: AgentWorkspaceTerminalStartRequest;
915
+ output: AgentWorkspaceTerminalStartResult;
916
+ };
917
+ 'workspace.terminal.stop': {
918
+ input: AgentWorkspaceTerminalControlRequest;
919
+ output: AgentWorkspaceTerminalControlResult;
920
+ };
921
+ 'workspace.pty.start': {
922
+ input: AgentWorkspacePtyStartRequest;
923
+ output: AgentWorkspacePtyStartResult;
924
+ };
925
+ 'workspace.pty.snapshot': {
926
+ input: AgentWorkspacePtySnapshotRequest;
927
+ output: AgentWorkspacePtySnapshotResult;
928
+ };
929
+ 'workspace.pty.input': {
930
+ input: AgentWorkspacePtyInputRequest;
931
+ output: AgentWorkspaceTerminalControlResult;
932
+ };
933
+ 'workspace.pty.resize': {
934
+ input: AgentWorkspacePtyResizeRequest;
935
+ output: AgentWorkspaceTerminalControlResult;
936
+ };
937
+ 'workspace.pty.clear': {
938
+ input: AgentWorkspaceTerminalControlRequest;
939
+ output: AgentWorkspaceTerminalControlResult;
940
+ };
941
+ 'workspace.pty.stop': {
942
+ input: AgentWorkspaceTerminalControlRequest;
943
+ output: AgentWorkspaceTerminalControlResult;
944
+ };
945
+ 'turn.start': {
946
+ input: AgentTurnStartRequest;
947
+ output: AgentTurnStartResult;
948
+ };
949
+ 'turn.cancel': {
950
+ input: AgentTurnCancelRequest;
951
+ output: AgentTurnCancelResult;
952
+ };
953
+ 'turn.steer': {
954
+ input: AgentTurnSteerRequest;
955
+ output: AgentTurnSteerResult;
956
+ };
957
+ 'turn.queue': {
958
+ input: AgentTurnQueueRequest;
959
+ output: AgentTurnQueueResult;
960
+ };
961
+ 'turn.queue.list': {
962
+ input: AgentTurnQueueListRequest;
963
+ output: AgentTurnQueueListResult;
964
+ };
965
+ 'run.observation.snapshot': {
966
+ input: AgentRunObservationSnapshotRequest;
967
+ output: AgentRunObservationSnapshotResult;
968
+ };
969
+ 'run.observation.change': {
970
+ input: AgentRunObservationChangeRequest;
971
+ output: AgentRunObservationChangeResult;
972
+ };
973
+ 'run.observation.overlaps': {
974
+ input: AgentRunObservationOverlapsRequest;
975
+ output: AgentRunObservationOverlapsResult;
976
+ };
977
+ 'fleet.view': {
978
+ input: AgentFleetViewRequest;
979
+ output: AgentFleetViewResult;
980
+ };
981
+ 'fleet.route': {
982
+ input: AgentFleetRouteRequest;
983
+ output: AgentFleetRouteResult;
984
+ };
985
+ 'fleet.plan': {
986
+ input: AgentFleetPlanRequest;
987
+ output: AgentFleetPlanResult;
988
+ };
989
+ 'session.list': {
990
+ input: AgentSessionListRequest;
991
+ output: AgentSessionListResult;
992
+ };
993
+ 'session.attach': {
994
+ input: AgentSessionViewerRequest;
995
+ output: AgentSessionViewerResult;
996
+ };
997
+ 'session.detach': {
998
+ input: AgentSessionViewerRequest;
999
+ output: AgentSessionViewerResult;
1000
+ };
1001
+ 'session.snapshot': {
1002
+ input: AgentSessionSnapshotRequest;
1003
+ output: AgentSessionSnapshotResult;
1004
+ };
1005
+ 'session.input': {
1006
+ input: AgentSessionInputRequest;
1007
+ output: AgentSessionInputResult;
1008
+ };
1009
+ 'session.takeover': {
1010
+ input: AgentSessionTakeoverRequest;
1011
+ output: AgentSessionTakeoverResult;
1012
+ };
1013
+ 'session.release': {
1014
+ input: AgentSessionViewerRequest;
1015
+ output: AgentSessionViewerResult;
1016
+ };
1017
+ 'intake.sources.list': {
1018
+ input: AgentIntakeSourcesRequest;
1019
+ output: AgentIntakeSourcesResult;
1020
+ };
1021
+ 'intake.items.list': {
1022
+ input: AgentIntakeItemsRequest;
1023
+ output: AgentIntakeItemsResult;
1024
+ };
1025
+ 'intake.item.claim': {
1026
+ input: AgentIntakeClaimRequest;
1027
+ output: AgentIntakeClaimResult;
1028
+ };
1029
+ 'intake.item.release': {
1030
+ input: AgentIntakeClaimRequest;
1031
+ output: AgentIntakeClaimResult;
1032
+ };
1033
+ 'intake.item.dispatch': {
1034
+ input: AgentIntakeDispatchRequest;
1035
+ output: AgentIntakeClaimResult;
1036
+ };
1037
+ 'knowledge.list': {
1038
+ input: AgentKnowledgeListRequest;
1039
+ output: AgentKnowledgeListResult;
1040
+ };
1041
+ 'knowledge.record': {
1042
+ input: AgentKnowledgeRecordRequest;
1043
+ output: AgentKnowledgeRecordResult;
1044
+ };
1045
+ 'knowledge.forget': {
1046
+ input: AgentKnowledgeForgetRequest;
1047
+ output: AgentKnowledgeRecordResult;
1048
+ };
1049
+ 'knowledge.context': {
1050
+ input: AgentKnowledgeContextRequest;
1051
+ output: AgentKnowledgeContextResult;
1052
+ };
1053
+ 'turn.queue.drop': {
1054
+ input: AgentTurnQueueDropRequest;
1055
+ output: AgentTurnQueueDropResult;
1056
+ };
1057
+ 'elicitation.choose-directory.answer': {
1058
+ input: AgentChooseDirectoryAnswerRequest;
1059
+ output: AgentChooseDirectoryAnswerResult;
1060
+ };
1061
+ 'elicitation.workspace-placement.answer': {
1062
+ input: AgentWorkspacePlacementAnswerRequest;
1063
+ output: AgentWorkspacePlacementAnswerResult;
1064
+ };
1065
+ 'elicitation.permission.answer': {
1066
+ input: AgentPermissionAnswerRequest;
1067
+ output: AgentPermissionAnswerResult;
1068
+ };
1069
+ 'turn.resume': {
1070
+ input: AgentTurnResumeRequest;
1071
+ output: AgentTurnResumeResult;
1072
+ };
1073
+ 'acp.provider.approve': {
1074
+ input: AgentAcpProviderApprovalRequest;
1075
+ output: AgentAcpProviderApprovalResult;
1076
+ };
1077
+ 'permissions.rules.list': {
1078
+ input: Record<string, never>;
1079
+ output: AgentPermissionRuleListResult;
1080
+ };
1081
+ 'permissions.rules.revoke': {
1082
+ input: AgentPermissionRuleRevokeRequest;
1083
+ output: AgentPermissionRuleRevokeResult;
1084
+ };
1085
+ 'elicitation.ask-user.answer': {
1086
+ input: AgentAskUserAnswerRequest;
1087
+ output: AgentAskUserAnswerResult;
1088
+ };
1089
+ 'sdk.sessions.list': {
1090
+ input: AgentSdkSessionListRequest;
1091
+ output: AgentSdkSessionListResult;
1092
+ };
1093
+ 'sdk.sessions.show': {
1094
+ input: AgentSdkSessionShowRequest;
1095
+ output: AgentSdkSessionShowResult;
1096
+ };
1097
+ 'sdk.sessions.attach': {
1098
+ input: AgentSdkSessionAttachRequest;
1099
+ output: AgentSdkSessionAttachResult;
1100
+ };
1101
+ 'sdk.sessions.detach': {
1102
+ input: AgentSdkSessionDetachRequest;
1103
+ output: AgentSdkMutationResult;
1104
+ };
1105
+ 'sdk.sessions.delete': {
1106
+ input: AgentSdkSessionDeleteRequest;
1107
+ output: AgentSdkMutationResult;
1108
+ };
1109
+ 'sdk.sessions.clean': {
1110
+ input: AgentSdkSessionCleanRequest;
1111
+ output: AgentSdkSessionCleanResult;
1112
+ };
1113
+ 'sdk.checkpoints.list': {
1114
+ input: AgentSdkCheckpointListRequest;
1115
+ output: AgentSdkCheckpointListResult;
1116
+ };
1117
+ 'sdk.checkpoints.restore': {
1118
+ input: AgentSdkCheckpointRestoreRequest;
1119
+ output: AgentSdkCheckpointRestoreResult;
1120
+ };
1121
+ 'sdk.checkpoints.delete': {
1122
+ input: AgentSdkCheckpointDeleteRequest;
1123
+ output: AgentSdkMutationResult;
1124
+ };
1125
+ 'sdk.tasks.output': {
1126
+ input: AgentSdkTaskOutputRequest;
1127
+ output: AgentSdkTaskResult;
1128
+ };
1129
+ 'sdk.tasks.stop': {
1130
+ input: AgentSdkTaskStopRequest;
1131
+ output: AgentSdkTaskResult;
1132
+ };
1133
+ 'engineering.git.status': {
1134
+ input: AgentEngineeringRequest<Engineering.EngineeringRequestBase>;
1135
+ output: Engineering.GitStatusResponse;
1136
+ };
1137
+ 'engineering.git.diff': {
1138
+ input: AgentEngineeringRequest<Engineering.GitDiffRequest>;
1139
+ output: Engineering.GitDiffResponse;
1140
+ };
1141
+ 'engineering.git.stage': {
1142
+ input: AgentEngineeringRequest<Engineering.GitStageRequest>;
1143
+ output: Engineering.GitStatusResponse;
1144
+ };
1145
+ 'engineering.git.unstage': {
1146
+ input: AgentEngineeringRequest<Engineering.GitStageRequest>;
1147
+ output: Engineering.GitStatusResponse;
1148
+ };
1149
+ 'engineering.git.commit': {
1150
+ input: AgentEngineeringRequest<Engineering.GitCommitRequest>;
1151
+ output: Engineering.GitStatusResponse;
1152
+ };
1153
+ 'engineering.git.branch': {
1154
+ input: AgentEngineeringRequest<Engineering.GitBranchRequest>;
1155
+ output: Engineering.GitStatusResponse;
1156
+ };
1157
+ 'engineering.git.push': {
1158
+ input: AgentEngineeringRequest<Engineering.GitPushRequest>;
1159
+ output: Engineering.GitPushResponse;
1160
+ };
1161
+ 'engineering.git.pr.create': {
1162
+ input: AgentEngineeringRequest<Engineering.GitPullRequestCreateRequest>;
1163
+ output: Engineering.GitPullRequestCreateResponse;
1164
+ };
1165
+ 'engineering.landing.enqueue': {
1166
+ input: AgentEngineeringRequest<Engineering.LandingEnqueueRequest>;
1167
+ output: Engineering.LandingQueueResponse;
1168
+ };
1169
+ 'engineering.landing.remove': {
1170
+ input: AgentEngineeringRequest<Engineering.LandingRemoveRequest>;
1171
+ output: Engineering.LandingQueueResponse;
1172
+ };
1173
+ 'engineering.landing.status': {
1174
+ input: AgentEngineeringRequest<Engineering.EngineeringRequestBase>;
1175
+ output: Engineering.LandingQueueResponse;
1176
+ };
1177
+ 'engineering.landing.land': {
1178
+ input: AgentEngineeringRequest<Engineering.LandingLandRequest>;
1179
+ output: Engineering.LandingLandResponse;
1180
+ };
1181
+ 'engineering.landing.verify': {
1182
+ input: AgentEngineeringRequest<Engineering.LandingVerifyRequest>;
1183
+ output: Engineering.LandingVerifyResponse;
1184
+ };
1185
+ 'engineering.checks.discover': {
1186
+ input: AgentEngineeringRequest<Engineering.EngineeringRequestBase>;
1187
+ output: Engineering.EngineeringCheckDiscoveryResponse;
1188
+ };
1189
+ 'engineering.checks.run': {
1190
+ input: AgentEngineeringRequest<Engineering.EngineeringRunRequest>;
1191
+ output: Engineering.EngineeringRunResponse;
1192
+ };
1193
+ 'engineering.background.start': {
1194
+ input: AgentEngineeringRequest<Engineering.EngineeringBackgroundRunRequest>;
1195
+ output: Engineering.EngineeringBackgroundRunResponse;
1196
+ };
1197
+ 'engineering.background.list': {
1198
+ input: AgentEngineeringRequest<Engineering.EngineeringRequestBase>;
1199
+ output: Engineering.EngineeringBackgroundRunListResponse;
1200
+ };
1201
+ 'engineering.background.output': {
1202
+ input: AgentEngineeringRequest<Engineering.EngineeringBackgroundRunLookupRequest>;
1203
+ output: Engineering.EngineeringBackgroundRunResponse;
1204
+ };
1205
+ 'engineering.background.stop': {
1206
+ input: AgentEngineeringRequest<Engineering.EngineeringBackgroundRunLookupRequest>;
1207
+ output: Engineering.EngineeringBackgroundRunResponse;
1208
+ };
1209
+ 'engineering.runs.list': {
1210
+ input: AgentEngineeringRequest<Engineering.EngineeringRequestBase>;
1211
+ output: Engineering.EngineeringRunListResponse;
1212
+ };
1213
+ 'engineering.diagnostics': {
1214
+ input: AgentEngineeringRequest<Engineering.EngineeringRequestBase>;
1215
+ output: Engineering.EngineeringDiagnosticsResponse;
1216
+ };
1217
+ 'engineering.patches.list': {
1218
+ input: AgentEngineeringRequest<Engineering.EngineeringRequestBase>;
1219
+ output: Engineering.PatchReviewListResponse;
1220
+ };
1221
+ 'engineering.patches.enqueue': {
1222
+ input: AgentEngineeringRequest<Engineering.PatchReviewUpsertRequest>;
1223
+ output: Engineering.PatchReviewMutationResponse;
1224
+ };
1225
+ 'engineering.patches.update': {
1226
+ input: AgentEngineeringRequest<Engineering.PatchReviewUpdateRequest>;
1227
+ output: Engineering.PatchReviewMutationResponse;
1228
+ };
1229
+ 'engineering.patches.review': {
1230
+ input: AgentEngineeringRequest<Engineering.PatchReviewSelectionRequest>;
1231
+ output: Engineering.PatchReviewSelectionResponse;
1232
+ };
1233
+ 'engineering.checkpoints.list': {
1234
+ input: AgentEngineeringRequest<Engineering.EngineeringRequestBase>;
1235
+ output: Engineering.EngineeringCheckpointListResponse;
1236
+ };
1237
+ 'engineering.checkpoints.compare': {
1238
+ input: AgentEngineeringRequest<Engineering.EngineeringCheckpointCompareRequest>;
1239
+ output: Engineering.EngineeringCheckpointCompareResponse;
1240
+ };
1241
+ 'engineering.checkpoints.restore': {
1242
+ input: AgentEngineeringRequest<Engineering.EngineeringCheckpointRestoreRequest>;
1243
+ output: Engineering.EngineeringCheckpointRestoreResponse;
1244
+ };
1245
+ 'engineering.sessions.list': {
1246
+ input: AgentEngineeringRequest<Engineering.EngineeringRequestBase>;
1247
+ output: Engineering.EngineeringSessionListResponse;
1248
+ };
1249
+ 'engineering.runtime.timeline': {
1250
+ input: AgentEngineeringRequest<Engineering.EngineeringRuntimeTimelineRequest>;
1251
+ output: Engineering.EngineeringRuntimeTimelineResponse;
1252
+ };
1253
+ }
1254
+ export type AgentHostMethod = keyof AgentHostRequestMap;
1255
+ export type AgentEngineeringHostMethod = Extract<AgentHostMethod, `engineering.${string}`>;
1256
+ /** Derived from the prefix, like its siblings, so a new `run.observation.*`
1257
+ * method needs no edit here to become callable. */
1258
+ export type AgentRunObservationHostMethod = Extract<AgentHostMethod, `run.observation.${string}`>;
1259
+ /** Derived from the prefix like its siblings. */
1260
+ export type AgentFleetHostMethod = Extract<AgentHostMethod, `fleet.${string}`>;
1261
+ /** Derived from the prefix like its siblings. */
1262
+ export type AgentSessionHostMethod = Extract<AgentHostMethod, `session.${string}`>;
1263
+ /** Derived from the prefix like its siblings. */
1264
+ export type AgentIntakeHostMethod = Extract<AgentHostMethod, `intake.${string}`>;
1265
+ /** Derived from the prefix like its siblings. */
1266
+ export type AgentKnowledgeHostMethod = Extract<AgentHostMethod, `knowledge.${string}`>;
1267
+ /**
1268
+ * ACP registry operations that must run under the host's authority.
1269
+ *
1270
+ * A template-literal group like `engineering.*`, so a future ACP method joins
1271
+ * without another client helper.
1272
+ */
1273
+ export type AgentAcpHostMethod = Extract<AgentHostMethod, `acp.${string}`>;
1274
+ export type AgentHostInput<M extends AgentHostMethod> = AgentHostRequestMap[M]['input'];
1275
+ export type AgentHostOutput<M extends AgentHostMethod> = AgentHostRequestMap[M]['output'];
1276
+ export declare const AGENT_HOST_METHODS: readonly ["host.handshake", "providers.list", "providers.refresh", "runtime.events.list", "state.workspaces.load", "state.workspaces.save", "state.conversations.load", "state.conversations.save", "state.conversations.delete", "workspace.access.grant", "coordination.held.list", "coordination.held.release", "coordination.policy.set", "workspace.application.grant", "workspace.directory.list", "workspace.file.read", "workspace.file.write", "workspace.command.run", "workspace.terminal.start", "workspace.terminal.stop", "workspace.pty.start", "workspace.pty.snapshot", "workspace.pty.input", "workspace.pty.resize", "workspace.pty.clear", "workspace.pty.stop", "turn.start", "turn.cancel", "turn.steer", "turn.queue", "turn.queue.list", "run.observation.snapshot", "run.observation.change", "run.observation.overlaps", "fleet.view", "fleet.route", "fleet.plan", "session.list", "session.attach", "session.detach", "session.snapshot", "session.input", "session.takeover", "session.release", "intake.sources.list", "intake.items.list", "intake.item.claim", "intake.item.release", "intake.item.dispatch", "knowledge.list", "knowledge.record", "knowledge.forget", "knowledge.context", "turn.queue.drop", "elicitation.choose-directory.answer", "elicitation.workspace-placement.answer", "elicitation.permission.answer", "turn.resume", "acp.provider.approve", "permissions.rules.list", "permissions.rules.revoke", "elicitation.ask-user.answer", "sdk.sessions.list", "sdk.sessions.show", "sdk.sessions.attach", "sdk.sessions.detach", "sdk.sessions.delete", "sdk.sessions.clean", "sdk.checkpoints.list", "sdk.checkpoints.restore", "sdk.checkpoints.delete", "sdk.tasks.output", "sdk.tasks.stop", "engineering.git.status", "engineering.git.diff", "engineering.git.stage", "engineering.git.unstage", "engineering.git.commit", "engineering.git.branch", "engineering.git.push", "engineering.git.pr.create", "engineering.landing.enqueue", "engineering.landing.remove", "engineering.landing.status", "engineering.landing.land", "engineering.landing.verify", "engineering.checks.discover", "engineering.checks.run", "engineering.background.start", "engineering.background.list", "engineering.background.output", "engineering.background.stop", "engineering.runs.list", "engineering.diagnostics", "engineering.patches.list", "engineering.patches.enqueue", "engineering.patches.update", "engineering.patches.review", "engineering.checkpoints.list", "engineering.checkpoints.compare", "engineering.checkpoints.restore", "engineering.sessions.list", "engineering.runtime.timeline"];
1277
+ export declare function isAgentHostMethod(value: unknown): value is AgentHostMethod;
1278
+ /**
1279
+ * Approve or revoke which BINARY may run as an ACP provider.
1280
+ *
1281
+ * A trust decision, which is why it is a host method rather than something a
1282
+ * surface performs for itself: the ACP lane's equivalent of the plugin
1283
+ * `preflightTrust` gate, and ยง2.6 moves everything onto ACP. One authority
1284
+ * decides it and both surfaces get the same answer.
1285
+ */
1286
+ export interface AgentAcpProviderApprovalRequest {
1287
+ /**
1288
+ * Carries `client` directly rather than a full `AgentHostCommandContext`,
1289
+ * matching the `engineering.*` registry methods rather than the idempotent
1290
+ * turn commands. Approval is not idempotent-by-key: approving twice is
1291
+ * approving, and revoking after approving must not be deduplicated away.
1292
+ */
1293
+ client: AgentHostClientIdentity;
1294
+ /** The configured ACP agent whose provider policy is being approved. */
1295
+ agentId: string;
1296
+ /** Optional narrowing; must match the agent config's own `--provider`. */
1297
+ providerId?: string;
1298
+ action: 'approve' | 'revoke';
1299
+ }
1300
+ export interface AgentAcpProviderApprovalResult {
1301
+ success: boolean;
1302
+ status: 'approved' | 'revoked' | 'failed' | 'unavailable';
1303
+ agentId: string;
1304
+ /** Basename only โ€” a full binary path is host layout, not a surface's business. */
1305
+ commandBasename?: string;
1306
+ /** Redacted tails, so a failure is diagnosable without leaking a policy file. */
1307
+ stdoutTail?: string[];
1308
+ stderrTail?: string[];
1309
+ /** Present on failure. Never a raw exception string. */
1310
+ safeError?: string;
1311
+ }
1312
+ /**
1313
+ * Every event the host may publish, as a VALUE.
1314
+ *
1315
+ * ๐Ÿ”ด **This array is the type AND the runtime guard.** It used to be a
1316
+ * hand-written union beside a hand-written `isAgentHostEvent` predicate, and
1317
+ * they diverged: `coordination.event`, `run.observation` and `session.event`
1318
+ * were legal in the type and REJECTED by the guard.
1319
+ *
1320
+ * That is not a dropped event. `LocalAgentHostRpcClientTransport.receive` treats
1321
+ * an unrecognised frame as a protocol violation and **disconnects**, so a single
1322
+ * `session.attached` tore down every connected surface's transport. The three
1323
+ * missing types were the three newest pillars โ€” coordination (ยง5.2b),
1324
+ * tier-1 observation (ยง2.9) and the session substrate (ยง2.8) โ€” which is to
1325
+ * say the whole ADE was unusable over the real transport while every in-process
1326
+ * test passed, because `publish` never crosses the frame guard in one heap.
1327
+ *
1328
+ * Deriving both from one array makes the divergence unrepresentable.
1329
+ */
1330
+ export declare const AGENT_HOST_EVENT_TYPES: readonly ["host.ready", "provider.catalog.changed", "runtime.event.appended", "turn.execution.failed", "elicitation.choose-directory.requested", "elicitation.workspace-placement.requested", "elicitation.permission.requested", "elicitation.ask-user.requested", "task.changed", "workspace.terminal.data", "workspace.terminal.exit", "workspace.pty.data", "workspace.pty.exit", "coordination.event", "run.observation", "session.event"];
1331
+ export type AgentHostEventType = (typeof AGENT_HOST_EVENT_TYPES)[number];
1332
+ /**
1333
+ * Reading a run's observed diff โ€” the READ half of ยง2.9.
1334
+ *
1335
+ * The `run.observation` EVENT carries counts and completeness only, deliberately:
1336
+ * it is broadcast to every connected client and a diff is content. So a surface
1337
+ * that wants to show a review has to ask, and these are the questions it asks.
1338
+ *
1339
+ * ๐Ÿ”ด `available` is a first-class answer, not an error. A host with no isolation
1340
+ * substrate wired observes nothing, and a surface must be able to tell "this run
1341
+ * changed nothing" from "nobody was watching". Reporting the second as the first
1342
+ * is the false-clean diff the whole observation path exists to prevent.
1343
+ */
1344
+ export interface AgentRunObservationSnapshotRequest {
1345
+ runId: string;
1346
+ /** Drain pending events first. Default is to read what has already been folded,
1347
+ * so opening a review pane cannot consume a batch another reader is waiting on. */
1348
+ poll?: boolean;
1349
+ }
1350
+ export interface AgentRunObservationChangeSummary {
1351
+ path: string;
1352
+ kind: 'added' | 'modified' | 'deleted';
1353
+ }
1354
+ export interface AgentRunObservationSnapshotResult {
1355
+ available: boolean;
1356
+ runId: string;
1357
+ changes: AgentRunObservationChangeSummary[];
1358
+ /**
1359
+ * False when anything is known to have been missed.
1360
+ *
1361
+ * A surface must NOT present an incomplete diff as a review. ยง2.9's claim is
1362
+ * that tier 1 yields a real diff, and one that quietly omits changes is worse
1363
+ * than none, because a reviewer acts on it.
1364
+ */
1365
+ complete: boolean;
1366
+ droppedEvents: number;
1367
+ problems: string[];
1368
+ /** Why observation is unavailable, when it is. */
1369
+ reason?: string;
1370
+ }
1371
+ export interface AgentRunObservationChangeRequest {
1372
+ runId: string;
1373
+ path: string;
1374
+ }
1375
+ /**
1376
+ * Content for one changed path.
1377
+ *
1378
+ * โš ๏ธ A SNAPSHOT, not the state at the moment of the change: the agent may have
1379
+ * written again since. A surface must never label this "what the agent did at
1380
+ * 10:04:03".
1381
+ */
1382
+ export interface AgentRunObservationChangeResult {
1383
+ available: boolean;
1384
+ path: string;
1385
+ before?: string;
1386
+ after?: string;
1387
+ /** Never partially rendered as a hunk โ€” decoding binary to UTF-8 produces a
1388
+ * plausible-looking diff of something that was never text. */
1389
+ binary: boolean;
1390
+ truncated: boolean;
1391
+ /** Present when a side could not be produced, so an empty pane is legible. */
1392
+ refusal?: string;
1393
+ }
1394
+ export interface AgentRunObservationOverlapsRequest {
1395
+ /** Paths each run has CLAIMED, if the caller knows them. Complementary to the
1396
+ * observed sets, never a substitute: nothing forces an agent to claim before
1397
+ * writing, so the run that surprises us is the one whose overlap matters. */
1398
+ claimedPathsByRun?: Record<string, string[]>;
1399
+ }
1400
+ export interface AgentRunObservationOverlapSummary {
1401
+ path: string;
1402
+ runIds: string[];
1403
+ kind: 'edit-vs-edit' | 'delete-vs-edit' | 'add-vs-add';
1404
+ /** True when no run had claimed the path โ€” invisible to the registry. */
1405
+ unclaimed?: boolean;
1406
+ }
1407
+ export interface AgentRunObservationOverlapsResult {
1408
+ available: boolean;
1409
+ overlaps: AgentRunObservationOverlapSummary[];
1410
+ /**
1411
+ * Runs whose changes were NOT fully compared. An overlap cannot be ruled out
1412
+ * for these.
1413
+ *
1414
+ * TWO kinds, in one list because the reader'''s next action is the same โ€” go
1415
+ * look at that run: a run whose diff has a hole, and a run the observer never
1416
+ * saw at all. The second used to be invisible, so a landing gate could be told
1417
+ * "no overlaps, and the answer is complete" while an unobserved run was
1418
+ * editing the same files.
1419
+ */
1420
+ incompleteRuns: string[];
1421
+ complete: boolean;
1422
+ reason?: string;
1423
+ }
1424
+ /**
1425
+ * The fleet โ€” every run this host knows about, in one answer.
1426
+ *
1427
+ * ADE ยง9 step 6. The point of the step is that the workspace stops being an
1428
+ * agent WINDOW and becomes a view over many runs at once, so this deliberately
1429
+ * composes what three separate subsystems know rather than adding a fourth
1430
+ * record: coordination (who claimed what, and where two runs collided),
1431
+ * observation (what each run actually changed, and whether that diff is whole),
1432
+ * and the host itself (which runs are working right now).
1433
+ *
1434
+ * ๐Ÿ”ด **Scope is stated, not implied.** `coordinationComplete` is false when the
1435
+ * claim history is only what this host has seen since it started โ€” a restarted
1436
+ * host has a shorter record than the durable timeline, and a fleet view that
1437
+ * quietly showed fewer collisions than actually happened would be read as
1438
+ * "nobody collided". That is the same false-clean failure as an incomplete diff.
1439
+ */
1440
+ export interface AgentFleetViewRequest {
1441
+ /** Claimed paths per run, if the caller knows them. Advisory: overlaps are
1442
+ * computed from OBSERVED diffs, because nothing forces a claim before a write. */
1443
+ claimedPathsByRun?: Record<string, string[]>;
1444
+ }
1445
+ /**
1446
+ * A fan-out PLAN โ€” ADE ยง5.2's scheduler, asked without being run.
1447
+ *
1448
+ * Returned by `fleet.plan`, which starts nothing. A plan you can inspect before
1449
+ * anything begins is the reviewable artifact: it is what a person wants to see
1450
+ * before N agents start editing their repository.
1451
+ */
1452
+ export interface AgentFleetPlanRequest {
1453
+ tasks: AgentFleetPlanTask[];
1454
+ }
1455
+ export interface AgentFleetPlanTask {
1456
+ taskId: string;
1457
+ requiredCapabilities?: AgentHarnessCapability[];
1458
+ }
1459
+ export interface AgentFleetPlanAssignment {
1460
+ taskId: string;
1461
+ providerId: string;
1462
+ /** Capabilities served DEGRADED for this task โ€” carried so a worse-but-
1463
+ * possible run does not look like a clean one in the plan. */
1464
+ degraded: AgentHarnessCapability[];
1465
+ }
1466
+ export interface AgentFleetPlanRefusal {
1467
+ taskId: string;
1468
+ reason: string;
1469
+ }
1470
+ export interface AgentFleetPlanResult {
1471
+ assignments: AgentFleetPlanAssignment[];
1472
+ /** Refused INDIVIDUALLY โ€” one unroutable task does not fail the batch. */
1473
+ refusals: AgentFleetPlanRefusal[];
1474
+ /** Tasks per provider, INCLUDING idle ones at 0, so a caller can see the
1475
+ * spread rather than trust it. */
1476
+ loadByProvider: Record<string, number>;
1477
+ }
1478
+ /**
1479
+ * "Which agents could run a task requiring these capabilities?" โ€” ADE ยง5.2.
1480
+ *
1481
+ * A QUERY, deliberately: it starts nothing, so a surface or a scheduler can ask
1482
+ * before committing. ยง5.2's gate requires a task needing an undeclared
1483
+ * capability to be "refused with a named reason", and a refusal nothing can
1484
+ * observe is not a refusal anyone can act on โ€” which is what this method exists
1485
+ * to make visible.
1486
+ */
1487
+ export interface AgentFleetRouteRequest {
1488
+ /** Capabilities the task requires. Empty means "any runnable agent". */
1489
+ requiredCapabilities: AgentHarnessCapability[];
1490
+ }
1491
+ export interface AgentFleetRouteCandidate {
1492
+ providerId: string;
1493
+ /** Capabilities this provider serves DEGRADED. Non-empty means it can run the
1494
+ * task and will run it worse โ€” reported rather than hidden, so the choice is
1495
+ * informed rather than silently downgraded. */
1496
+ degraded: AgentHarnessCapability[];
1497
+ }
1498
+ export interface AgentFleetRouteRejection {
1499
+ providerId: string;
1500
+ /** Absent when the PROVIDER is unavailable rather than a capability missing. */
1501
+ capability?: AgentHarnessCapability;
1502
+ reason: string;
1503
+ }
1504
+ export interface AgentFleetRouteResult {
1505
+ /** False means NOTHING can run this task. `reason` is then required. */
1506
+ routable: boolean;
1507
+ candidates: AgentFleetRouteCandidate[];
1508
+ /** Every provider ruled out, and why โ€” a partial fan-out has to be explicable. */
1509
+ rejected: AgentFleetRouteRejection[];
1510
+ /**
1511
+ * Why nothing can run it. REQUIRED when `routable` is false โ€” the ยง5.2 gate is
1512
+ * "refused with a named reason", so a bare `false` would not satisfy it.
1513
+ */
1514
+ reason?: string;
1515
+ }
1516
+ export interface AgentFleetRun {
1517
+ runId: string;
1518
+ conversationId?: string;
1519
+ workspaceId?: string;
1520
+ agentId?: string;
1521
+ /** True while a turn is executing for this run. */
1522
+ working: boolean;
1523
+ /** Scopes this run currently holds. */
1524
+ claims: string[];
1525
+ /** Present only when the run is being observed. */
1526
+ changes?: {
1527
+ added: number;
1528
+ modified: number;
1529
+ deleted: number;
1530
+ };
1531
+ /**
1532
+ * Whether this run's diff is the whole story. ABSENT when unobserved โ€”
1533
+ * which is deliberately different from `false`: "not watched" and "watched
1534
+ * with a hole" call for different actions.
1535
+ */
1536
+ diffComplete?: boolean;
1537
+ /**
1538
+ * The intake item this run was dispatched from, when it was โ€” ยง5.1's
1539
+ * provenance, on the RUN side.
1540
+ *
1541
+ * The intake board already answers "who is working on this item". This is the
1542
+ * opposite question, and the one a reviewer asks: "where did this run's work
1543
+ * come from?" ABSENT means the run was not dispatched from intake (someone
1544
+ * typed a prompt), which is different from an unknown origin.
1545
+ */
1546
+ intakeItemId?: string;
1547
+ /** Paths another live run also changed. */
1548
+ contestedPaths: string[];
1549
+ /**
1550
+ * The run is stopped on a permission prompt โ€” ยง7's `awaiting-approval`.
1551
+ *
1552
+ * ๐Ÿ”ด Distinct from `working`, which stays TRUE throughout: a turn blocked on
1553
+ * a human is still in flight. Reporting only `working` told the person
1554
+ * reading this board that the run was busy, when the run was waiting for
1555
+ * THEM โ€” the one reader who could clear it instantly.
1556
+ *
1557
+ * ABSENT means unknown, because a host with no coordination service has no
1558
+ * roster to ask. Not `false`, which would assert the run is not waiting.
1559
+ */
1560
+ awaitingApproval?: boolean;
1561
+ /**
1562
+ * Messages withheld from this run, awaiting a human (coordination ยง6 `hold`).
1563
+ *
1564
+ * ๐Ÿ”ด ABSENT when the host has no coordination service โ€” no roster means
1565
+ * no answer, and `0` would assert that nothing is waiting. Deliberately
1566
+ * SEPARATE from `awaitingApproval`, which is the run itself stopped on a
1567
+ * permission prompt: that blocks the RUN, this blocks a message TO it, and
1568
+ * a reader clears them by different actions.
1569
+ *
1570
+ * A COUNT, never the text. Coordination facts that reach a surface this way
1571
+ * carry ids and counts and never message bytes; the text is fetched
1572
+ * deliberately through `coordination.held.list`.
1573
+ */
1574
+ heldMessages?: number;
1575
+ /**
1576
+ * ยง6's EXPLICIT inbound-policy override, absent when the derivation decides.
1577
+ *
1578
+ * Not the effective policy: the derivation is comparative, so what happens to
1579
+ * a message depends on who sent it. This is the part a human pinned, and
1580
+ * therefore the only part they can clear.
1581
+ */
1582
+ inboundPolicy?: 'accept' | 'hold' | 'refuse';
1583
+ /**
1584
+ * Whether this run is CONTAINED โ€” ADE ยง5.3.
1585
+ *
1586
+ * REQUIRED, deliberately. Every other risk-shaped field here is optional so an
1587
+ * absent one reads as "the host cannot answer", but ยง5.3 says the user always
1588
+ * knows whether the thing running is contained โ€” so the host must answer, and
1589
+ * `'none'` is a real answer rather than a missing one.
1590
+ */
1591
+ isolation: 'none' | 'sandboxed' | 'unknown';
1592
+ /** What confines it, present only alongside `sandboxed`. */
1593
+ isolationMechanism?: string;
1594
+ /** Why the answer is `unknown`, present only alongside it. */
1595
+ isolationReason?: string;
1596
+ }
1597
+ export interface AgentFleetCollision {
1598
+ scope: string;
1599
+ wantedByRunId: string;
1600
+ heldByRunId: string;
1601
+ at: string;
1602
+ /** True while the holder still holds an overlapping claim. */
1603
+ stillHeld: boolean;
1604
+ }
1605
+ export interface AgentFleetViewResult {
1606
+ runs: AgentFleetRun[];
1607
+ collisions: AgentFleetCollision[];
1608
+ /** False when the claim/collision record is known to be partial. */
1609
+ coordinationComplete: boolean;
1610
+ /**
1611
+ * True only when every listed run's diff can be trusted as the whole story.
1612
+ *
1613
+ * ๐Ÿ”ด False in THREE cases, and the last two were reported as `true`:
1614
+ * an observed run with a hole; a run nobody observed; and a host with no
1615
+ * observation substrate at all. "Nothing was watched" is not "nothing
1616
+ * changed" โ€” reporting completeness for an unwatched fleet is the
1617
+ * false-clean output ยง2.9's sensors exist to prevent, and it is the same
1618
+ * defect already found and fixed once in `coordinationComplete`.
1619
+ */
1620
+ observationComplete: boolean;
1621
+ /** Why either completeness flag is false, for a human. */
1622
+ problems: string[];
1623
+ }
1624
+ /**
1625
+ * Sessions over the protocol โ€” ADE ยง5.5 attach and takeover, build-order step 4.
1626
+ *
1627
+ * The substrate (ยง2.8) has had `attach`, `takeOver` and input routing since the
1628
+ * session work landed; none of it was reachable from a surface. These are that
1629
+ * surface.
1630
+ *
1631
+ * ๐Ÿ”ด **Terminal bytes are NEVER on the event feed.** `session.event` is a
1632
+ * broadcast to every connected client, and output is per-viewer and large. So
1633
+ * output is READ, by an explicit `session.snapshot` call from the surface that
1634
+ * wants it โ€” the same shape `workspace.pty.snapshot` already uses here.
1635
+ */
1636
+ export interface AgentSessionListRequest {
1637
+ /** Limit to one run's sessions. Absent lists every open session. */
1638
+ runId?: string;
1639
+ }
1640
+ export interface AgentSessionSummary {
1641
+ sessionId: string;
1642
+ runId: string;
1643
+ mode: string;
1644
+ switchable: boolean;
1645
+ hasProtocolChannel: boolean;
1646
+ openedAt: number;
1647
+ viewers: string[];
1648
+ /** Who may write into the session right now, and since when. */
1649
+ lease: {
1650
+ holder: string | null;
1651
+ heldSince: number | null;
1652
+ interventions: number;
1653
+ };
1654
+ }
1655
+ export interface AgentSessionListResult {
1656
+ available: boolean;
1657
+ sessions: AgentSessionSummary[];
1658
+ /** Present when this host has no session substrate mounted. */
1659
+ reason?: string;
1660
+ }
1661
+ export interface AgentSessionViewerRequest {
1662
+ sessionId: string;
1663
+ /** Identifies the watching surface. Attach is plural: two surfaces may hold
1664
+ * the same session and both see it move. */
1665
+ viewerId: string;
1666
+ }
1667
+ export interface AgentSessionViewerResult {
1668
+ ok: boolean;
1669
+ /** Why not, when not โ€” never a bare false. */
1670
+ reason?: string;
1671
+ session?: AgentSessionSummary;
1672
+ }
1673
+ export interface AgentSessionSnapshotRequest {
1674
+ sessionId: string;
1675
+ }
1676
+ export interface AgentSessionSnapshotResult {
1677
+ available: boolean;
1678
+ output: string;
1679
+ /**
1680
+ * True when older output has already been dropped from the retained window.
1681
+ * A surface must say so rather than presenting a terminal that appears to
1682
+ * begin mid-sentence for no reason.
1683
+ */
1684
+ truncated: boolean;
1685
+ reason?: string;
1686
+ }
1687
+ export interface AgentSessionInputRequest {
1688
+ sessionId: string;
1689
+ /**
1690
+ * ๐Ÿ”ด REQUIRED, because typing into a session MUTATES the run.
1691
+ *
1692
+ * For an `acp` session the host delivers these keystrokes through the one
1693
+ * `turn.steer` path, which is idempotent by command id. Without one, a
1694
+ * retried input is either delivered twice or refused as a duplicate of a
1695
+ * different instruction โ€” and two identical keystrokes are legitimately two
1696
+ * inputs, so nothing derivable from the DATA can stand in for it.
1697
+ *
1698
+ * Optional would not have helped, for the same reason `viewerId` is not: a
1699
+ * caller that omits it is indistinguishable from one entitled to skip
1700
+ * idempotency.
1701
+ */
1702
+ command: AgentHostCommandContext;
1703
+ /**
1704
+ * ๐Ÿ”ด Which surface is typing. REQUIRED, and the reason is the lease.
1705
+ *
1706
+ * `session.takeover` refuses a second human because *"interleaving two humans
1707
+ * produces a command neither typed"*. This method writes to the same PTY, so
1708
+ * without a viewer id the host cannot apply that rule here โ€” and the exact
1709
+ * interleaving the lease exists to prevent was reachable through this door
1710
+ * while being refused at the other one.
1711
+ *
1712
+ * Optional would not have fixed it: a caller that omits the field is
1713
+ * indistinguishable from one entitled to write, which is the ambiguity, not
1714
+ * a mitigation of it.
1715
+ */
1716
+ viewerId: string;
1717
+ data: string;
1718
+ }
1719
+ /**
1720
+ * ๐Ÿ”ด `turnInFlight` and `acceptsMidTurnSteering` USED TO BE FIELDS HERE, and
1721
+ * removing them is the point.
1722
+ *
1723
+ * Both decide whether a keystroke steers the agent now or waits for its next
1724
+ * turn โ€” ยง2.8's routing โ€” and both are facts the HOST owns: it holds the active
1725
+ * turns, and it knows whether the run's adapter can steer at all, because it
1726
+ * already refuses with `steer_unsupported` when the adapter cannot.
1727
+ *
1728
+ * Taking them from the caller let a surface decide how its own input would be
1729
+ * treated, which is the shape invariant 12 exists for: a caller CLAIMING
1730
+ * authority never grants it. It also made the method unusable โ€” a panel has no
1731
+ * way to know either fact, so binding it would have meant guessing, and a guess
1732
+ * here silently changes what happens to what someone typed.
1733
+ */
1734
+ export interface AgentSessionInputResult {
1735
+ ok: boolean;
1736
+ /**
1737
+ * The instruction this input became, when the disposition was `queue`.
1738
+ *
1739
+ * ๐Ÿ”ด Positive evidence that the queue actually took it. `disposition`
1740
+ * states the INTENT and cannot say whether it happened โ€” and for a long time
1741
+ * it did not: the `turn.queue` sink was derived, announced, and serviced by
1742
+ * nobody, so typing during a turn the agent could not take mid-flight fell
1743
+ * into exactly the void the comment below says never happens.
1744
+ *
1745
+ * ๐Ÿ”ด ONE object, not two optional fields. An id a surface cannot
1746
+ * address is evidence it can render and not act on โ€” `turn.queue.drop` is
1747
+ * keyed by CONVERSATION, and a session knows only its run. Shipping the id
1748
+ * alone (as this first did) left "you have something queued" with no way to
1749
+ * take it back. The two facts are true together or not at all, so they are
1750
+ * one field and the useless half is unrepresentable.
1751
+ *
1752
+ * ABSENT rather than a pair of nulls when queuing did not happen.
1753
+ */
1754
+ queued?: {
1755
+ instructionId: string;
1756
+ conversationId: string;
1757
+ };
1758
+ /** Named, so a surface can say WHY rather than showing keystrokes vanishing. */
1759
+ code?: 'no_such_session' | 'lease_held';
1760
+ /** `steer` is for the agent now; `queue` is for its next decision point. There
1761
+ * is deliberately no `drop`: typing never falls into a void. */
1762
+ disposition?: 'steer' | 'queue';
1763
+ /**
1764
+ * True when the session ALREADY put the keystrokes in front of the agent.
1765
+ *
1766
+ * ๐Ÿ”ด The disposition alone does not say this, and reading it as if it did
1767
+ * is how typing gets lost. In `native-tui` the PTY is the agent's terminal, so
1768
+ * a steer is delivered by the time this returns. In `acp` nothing sits behind
1769
+ * the PTY โ€” it renders the structured stream โ€” so delivery is still owed, via
1770
+ * `sink`. A caller that ignores this either double-delivers or drops.
1771
+ */
1772
+ delivered?: boolean;
1773
+ /** Where the keystrokes went, or must still go. */
1774
+ sink?: 'pty' | 'turn.steer' | 'turn.queue';
1775
+ reason?: string;
1776
+ }
1777
+ export interface AgentSessionTakeoverRequest {
1778
+ sessionId: string;
1779
+ /**
1780
+ * ๐Ÿ”ด REQUIRED, because typing into a session MUTATES the run.
1781
+ *
1782
+ * For an `acp` session the host delivers these keystrokes through the one
1783
+ * `turn.steer` path, which is idempotent by command id. Without one, a
1784
+ * retried input is either delivered twice or refused as a duplicate of a
1785
+ * different instruction โ€” and two identical keystrokes are legitimately two
1786
+ * inputs, so nothing derivable from the DATA can stand in for it.
1787
+ *
1788
+ * Optional would not have helped, for the same reason `viewerId` is not: a
1789
+ * caller that omits it is indistinguishable from one entitled to skip
1790
+ * idempotency.
1791
+ */
1792
+ command: AgentHostCommandContext;
1793
+ viewerId: string;
1794
+ /** The keystrokes. ยง5.5 has no request-and-wait step โ€” typing IS the takeover,
1795
+ * because the case it exists for is an agent going wrong now. */
1796
+ data: string;
1797
+ }
1798
+ export interface AgentSessionTakeoverResult {
1799
+ ok: boolean;
1800
+ /** False when another human holds the lease. Their keystrokes are NOT
1801
+ * written: interleaving two humans produces a command neither typed. */
1802
+ lease?: {
1803
+ holder: string | null;
1804
+ heldSince: number | null;
1805
+ interventions: number;
1806
+ };
1807
+ /** Whether the keystrokes reached the agent. Taking the lease and delivering
1808
+ * what was typed are separate outcomes, and a takeover with no text at all is
1809
+ * ordinary โ€” ยง5.5 has no request-and-wait step, so the first keystroke IS the
1810
+ * takeover, and there may not be one yet. */
1811
+ delivered?: boolean;
1812
+ sink?: 'pty' | 'turn.steer' | 'turn.queue';
1813
+ reason?: string;
1814
+ }
1815
+ /**
1816
+ * Intake โ€” ADE ยง5.1, work arriving from wherever a developer's work arrives.
1817
+ *
1818
+ * ๐Ÿ”ด **Claimed exactly once under concurrent clients** is the gate, so a losing
1819
+ * claim is a NAMED refusal rather than a silent no-op: the loser's next action
1820
+ * (pick something else) depends on knowing it lost.
1821
+ *
1822
+ * ๐Ÿ”ด **A source that failed is not a source with no work.** `complete: false`
1823
+ * says the inbox could not be fully read โ€” an empty inbox and an unreadable one
1824
+ * are the same zero items and opposite meanings.
1825
+ *
1826
+ * **Boundary (ยง5.1):** this renders and dispatches intake. It is not a ticket
1827
+ * system, and it does not own scheduling โ€” recurring triggers are `xeno-workflow`.
1828
+ */
1829
+ export interface AgentIntakeSourcesRequest {
1830
+ [key: string]: never;
1831
+ }
1832
+ export interface AgentIntakeSourceSummary {
1833
+ sourceId: string;
1834
+ label: string;
1835
+ /** False when the last read failed. */
1836
+ healthy: boolean;
1837
+ problem?: string;
1838
+ }
1839
+ export interface AgentIntakeSourcesResult {
1840
+ available: boolean;
1841
+ sources: AgentIntakeSourceSummary[];
1842
+ reason?: string;
1843
+ }
1844
+ export interface AgentIntakeItemsRequest {
1845
+ /** Limit to one source. Absent reads them all. */
1846
+ sourceId?: string;
1847
+ }
1848
+ export interface AgentIntakeItemSummary {
1849
+ id: string;
1850
+ sourceId: string;
1851
+ externalId: string;
1852
+ title: string;
1853
+ detail?: string;
1854
+ createdAt?: number;
1855
+ url?: string;
1856
+ /** `unclaimed` | `claimed` | `dispatched`, plus who and which run. */
1857
+ claimState: string;
1858
+ claimedBy?: string;
1859
+ runId?: string;
1860
+ }
1861
+ export interface AgentIntakeItemsResult {
1862
+ available: boolean;
1863
+ items: AgentIntakeItemSummary[];
1864
+ /** False when any source failed โ€” the inbox may be missing work. */
1865
+ complete: boolean;
1866
+ failedSources: Array<{
1867
+ sourceId: string;
1868
+ problem: string;
1869
+ }>;
1870
+ reason?: string;
1871
+ }
1872
+ export interface AgentIntakeClaimRequest {
1873
+ itemId: string;
1874
+ /** Who is claiming. Distinct clients must not share this, or exactly-once
1875
+ * degrades to first-surface-wins-forever. */
1876
+ clientId: string;
1877
+ }
1878
+ export interface AgentIntakeDispatchRequest extends AgentIntakeClaimRequest {
1879
+ /** The run that will do the work. Recorded so provenance answers "where did
1880
+ * this come from?" after the fact. */
1881
+ runId: string;
1882
+ }
1883
+ export interface AgentIntakeClaimResult {
1884
+ ok: boolean;
1885
+ /** Present on refusal, naming who holds it and why. */
1886
+ reason?: string;
1887
+ heldBy?: string;
1888
+ runId?: string;
1889
+ claimState?: string;
1890
+ }
1891
+ /**
1892
+ * Workspace knowledge โ€” ADE ยง5.8 LEARN.
1893
+ *
1894
+ * ๐Ÿ”ด The gate is CROSS-PROVIDER: *"a fact established in one run is available to
1895
+ * a different provider in a later run without the user restating it."* Provider
1896
+ * is recorded as provenance and never consulted when selecting โ€” `context` takes
1897
+ * no provider argument at all, which is the simplest way to keep the mistake
1898
+ * unrepresentable.
1899
+ *
1900
+ * **Boundary:** this is WORKSPACE knowledge โ€” conventions, architecture, prior
1901
+ * decisions. Agent-owned earned memory (the Soul model) belongs to `xeno-anima`.
1902
+ */
1903
+ export interface AgentKnowledgeListRequest {
1904
+ workspaceId: string;
1905
+ }
1906
+ export interface AgentKnowledgeEntrySummary {
1907
+ id: string;
1908
+ subject: string;
1909
+ fact: string;
1910
+ pinned?: boolean;
1911
+ runId: string;
1912
+ /** Recorded for provenance only. Never decides what a later run sees. */
1913
+ providerId?: string;
1914
+ at: number;
1915
+ }
1916
+ export interface AgentKnowledgeListResult {
1917
+ available: boolean;
1918
+ entries: AgentKnowledgeEntrySummary[];
1919
+ /** False when the store does not survive a restart. Reported rather than
1920
+ * assumed โ€” a surface promising durable memory over an in-memory store lies. */
1921
+ durable: boolean;
1922
+ reason?: string;
1923
+ }
1924
+ export interface AgentKnowledgeRecordRequest {
1925
+ workspaceId: string;
1926
+ subject: string;
1927
+ fact: string;
1928
+ pinned?: boolean;
1929
+ runId: string;
1930
+ providerId?: string;
1931
+ }
1932
+ export interface AgentKnowledgeForgetRequest {
1933
+ workspaceId: string;
1934
+ entryId: string;
1935
+ }
1936
+ export interface AgentKnowledgeRecordResult {
1937
+ ok: boolean;
1938
+ entry?: AgentKnowledgeEntrySummary;
1939
+ reason?: string;
1940
+ }
1941
+ export interface AgentKnowledgeContextRequest {
1942
+ workspaceId: string;
1943
+ /** Rough character budget. Characters rather than tokens: a token count needs
1944
+ * a tokenizer per provider, and this must not vary by provider. */
1945
+ maxChars?: number;
1946
+ }
1947
+ export interface AgentKnowledgeContextResult {
1948
+ available: boolean;
1949
+ /** The block to inject, already rendered. */
1950
+ text: string;
1951
+ entries: AgentKnowledgeEntrySummary[];
1952
+ /** Facts left out for space. Named, never silently dropped โ€” a prompt missing
1953
+ * knowledge makes an agent look like it forgot, with nothing explaining why. */
1954
+ omitted: Array<{
1955
+ subject: string;
1956
+ reason: string;
1957
+ }>;
1958
+ complete: boolean;
1959
+ reason?: string;
1960
+ }
1961
+ export interface AgentHostEvent<TPayload = unknown> {
1962
+ id: string;
1963
+ sequence: number;
1964
+ timestamp: number;
1965
+ type: AgentHostEventType;
1966
+ source: 'host';
1967
+ schemaVersion: 1;
1968
+ redactionState: 'safe';
1969
+ payload: TPayload;
1970
+ }
1971
+ export type AgentHostEventListener = (event: AgentHostEvent) => void;
1972
+ export type AgentHostUnsubscribe = () => void;
1973
+ export interface AgentHostTransport {
1974
+ request<M extends AgentHostMethod>(method: M, input: AgentHostInput<M>): Promise<AgentHostOutput<M>>;
1975
+ subscribe(listener: AgentHostEventListener): AgentHostUnsubscribe;
1976
+ }
1977
+ export type AgentHostProtocolErrorCode = 'invalid_handshake' | 'protocol_mismatch' | 'surface_mismatch' | 'not_connected' | 'invalid_response';
1978
+ export declare class AgentHostProtocolError extends Error {
1979
+ readonly code: AgentHostProtocolErrorCode;
1980
+ constructor(code: AgentHostProtocolErrorCode, message: string);
1981
+ }
1982
+ export declare function isAgentSurfaceKind(value: unknown): value is AgentSurfaceKind;
1983
+ export declare function isAgentHostClientIdentity(value: unknown): value is AgentHostClientIdentity;
1984
+ export declare function isAgentHostHandshake(value: unknown): value is AgentHostHandshake;
1985
+ export declare function isAgentProviderListResult(value: unknown): value is AgentProviderListResult;
1986
+ /**
1987
+ * Which run something belongs to, from the two identifiers that answer it.
1988
+ *
1989
+ * ๐Ÿ”ด ONE callee, deliberately, because two things need this answer and they
1990
+ * must never disagree: the host resolving a run from a turn REQUEST, and a
1991
+ * session deciding whether a runtime EVENT belongs in its terminal. Both types
1992
+ * carry the same pair of fields; if the derivations drifted, a session would
1993
+ * render another run's output โ€” in a fleet that is both confusing and a
1994
+ * disclosure, and it would look like a rendering bug rather than a routing one.
1995
+ *
1996
+ * A subagent run is its own run. That is why `subagentRunId` wins: a subagent's
1997
+ * events belong to the subagent's session, not to the conversation that spawned
1998
+ * it.
1999
+ */
2000
+ export declare function defaultRunIdOf(ids: {
2001
+ conversationId: string;
2002
+ subagentRunId?: string | undefined;
2003
+ }): string;
2004
+ export declare function isAgentRuntimeEventEnvelope(value: unknown): value is AgentRuntimeEventEnvelope;
2005
+ export declare function isAgentRuntimeEventListResult(value: unknown): value is AgentRuntimeEventListResult;
2006
+ export declare function isAgentTurnStartResult(value: unknown): value is AgentTurnStartResult;
2007
+ export declare function isAgentTurnCancelResult(value: unknown): value is AgentTurnCancelResult;
2008
+ export declare function isAgentHostEvent(value: unknown): value is AgentHostEvent;
2009
+ /**
2010
+ * ๐Ÿ”ด Reads AGENT_HOST_EVENT_TYPES rather than restating it.
2011
+ *
2012
+ * Restating it is what shipped a guard three types short of the contract. A
2013
+ * frame the guard does not recognise is not ignored โ€” it DISCONNECTS the
2014
+ * client โ€” so an omission here is an outage, not a gap.
2015
+ */
2016
+ export declare function isAgentHostEventType(value: unknown): value is AgentHostEventType;
2017
+ export declare function assertCompatibleHandshake(handshake: AgentHostHandshake, identity: AgentHostClientIdentity, supportedProtocol: AgentHostProtocolRange): void;
2018
+ export * from './engineering.js';
2019
+ //# sourceMappingURL=index.d.ts.map