@wrongstack/acp 0.274.0 → 0.275.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,54 @@
1
+ import { b as ACPMessage, H as ACPToolCallResponse } from './acp-v1-BxskPsdo.js';
2
+ import './acp-subagent-runner-BAlo23L-.js';
3
+
4
+ /**
5
+ * ToolTranslator — bidirectional translation between WrongStack tools and
6
+ * ACP tool representations.
7
+ *
8
+ * Used by DIR-1 (WrongStack as ACP client) to:
9
+ * - Map WrongStack TaskSpec → ACP task payload
10
+ * - Map ACP tool responses → TaskResult
11
+ *
12
+ * Used by DIR-2 (WrongStack as ACP server) to:
13
+ * - Convert the WrongStack Tool.inputSchema → ACPToolDefinition.inputSchema
14
+ * - (handled by tools-registry.ts — same logic lives there)
15
+ *
16
+ * For DIR-1 async tool calls: ACP agents send progress notifications while
17
+ * a tool is running, then send a final result. The translator handles this
18
+ * by polling for the final [result] notification on the transport.
19
+ */
20
+
21
+ interface ToolTranslatorOptions {
22
+ /**
23
+ * If true (default), wrap tool calls in an async poll loop that waits
24
+ * for progress notifications until a final result arrives.
25
+ */
26
+ asyncTools?: boolean | undefined;
27
+ pollIntervalMs?: number | undefined;
28
+ totalTimeoutMs?: number | undefined;
29
+ }
30
+ /** ToolTranslator for DIR-1 — wraps ACP client transport, adds task semantics */
31
+ declare class ToolTranslator {
32
+ private readonly opts;
33
+ private readonly pending;
34
+ constructor(opts?: ToolTranslatorOptions);
35
+ /**
36
+ * Start listening to a transport for tool responses and cancellations.
37
+ * Call this once after constructing the translator and before sending tasks.
38
+ */
39
+ attachToTransport(transport: {
40
+ onMessage: (h: (msg: ACPMessage) => void) => () => void;
41
+ send: (msg: ACPMessage) => Promise<void>;
42
+ }): void;
43
+ /**
44
+ * Send a tool call over the transport and wait for a response.
45
+ * If asyncTools is true, polls for progress and resolves when the final
46
+ * response arrives.
47
+ */
48
+ callTool(transport: {
49
+ send: (msg: ACPMessage) => Promise<void>;
50
+ }, name: string, args: Record<string, unknown>, callId?: string | number): Promise<ACPToolCallResponse>;
51
+ cancelAll(): void;
52
+ }
53
+
54
+ export { ToolTranslator as T, type ToolTranslatorOptions as a };
package/dist/index.d.ts CHANGED
@@ -1,130 +1,13 @@
1
- export { c as ACPCancelParams, d as ACPCapabilities, e as ACPChildProcess, f as ACPError, g as ACPImageContent, h as ACPInitializeParams, i as ACPInputSchema, j as ACPMessage, k as ACPNotification, l as ACPPlanContent, m as ACPPlanStep, n as ACPProgressContent, o as ACPRequest, p as ACPResourceContent, q as ACPResponse, r as ACPSessionInfo, s as ACPSessionMode, t as ACPTextContent, u as ACPToolCallRequest, v as ACPToolCallResponse, w as ACPToolDefinition, a as ACPToolList, b as ACPToolResult, A as AgentServerTransport, C as ClientTransport, x as ClientTransportOptions, y as ContentBlock, S as StdioTransport } from './stdio-transport-CsFr8JzC.js';
2
- export { A as ACPToolsRegistry } from './tools-registry-BCf8evEG.js';
3
- import { T as ToolCallUpdateNotification, P as PermissionOption, b as RequestPermissionOutcome, S as StopReason, U as UsageCost, c as PlanEntry } from './wrongstack-acp-agent-Dv-A0bEm.js';
4
- export { A as ACPProtocolHandler, W as WrongStackACPServer, a as WrongStackACPServerOptions } from './wrongstack-acp-agent-Dv-A0bEm.js';
5
- import { A as ACPSubagentRunnerOptions } from './index-BvPqJHhm.js';
6
- export { a as ACP_AGENT_COMMANDS, T as ToolTranslator, b as ToolTranslatorOptions, m as makeACPSubagentRunner, c as makeACPSubagentRunnerWithStop } from './index-BvPqJHhm.js';
1
+ export { n as ACPCancelParams, o as ACPCapabilities, p as ACPChildProcess, A as ACPClientTransport, q as ACPError, r as ACPImageContent, s as ACPInitializeParams, t as ACPInputSchema, b as ACPMessage, u as ACPNotification, v as ACPPlanContent, w as ACPPlanStep, x as ACPProgressContent, y as ACPRequest, z as ACPResourceContent, B as ACPResponse, D as ACPSessionInfo, E as ACPSessionMode, F as ACPTextContent, G as ACPToolCallRequest, H as ACPToolCallResponse, I as ACPToolDefinition, c as ACPToolList, d as ACPToolResult, a as AgentServerTransport, J as ClientTransport, K as ClientTransportOptions, L as ContentBlock, S as StdioTransport } from './acp-v1-BxskPsdo.js';
2
+ export { A as ACPToolsRegistry } from './tools-registry-D2xdbzN7.js';
3
+ export { A as ACPProtocolHandler, e as WrongStackACPServer, f as WrongStackACPServerOptions } from './wrongstack-acp-agent-nzrqmJnc.js';
4
+ import { i as ACPSubagentRunnerOptions, b as ACPProgressEvent } from './acp-subagent-runner-BAlo23L-.js';
5
+ export { A as ACPCapturedDiff, a as ACPCapturedToolCall, c as ACPProgressHandler, d as ACPSession, e as ACPSessionError, f as ACPSessionErrorKind, g as ACPSessionOptions, h as ACPSessionRunResult, j as ACP_AGENT_COMMANDS, k as AcpAgentCommandOverrides, B as AcpLiveCatalog, l as AcpProbeResult, P as PermissionPolicy, m as PermissionRequest, C as ProbeAcpAgentsOptions, D as REGISTRY_ID_ALIASES, R as RunOneAcpTaskOptions, n as RunOneAcpTaskResult, W as WebSocketClientTransport, o as WebSocketClientTransportOptions, p as audioContent, q as defaultPermissionPolicy, r as imageContent, s as makeACPSubagentRunner, t as makeACPSubagentRunnerWithStop, u as makePermissionPolicy, v as probeAcpAgent, E as probeAcpAgents, w as readOnlyPermissionPolicy, x as resolveAcpAgentCommand, y as runOneAcpTask, z as textContent } from './acp-subagent-runner-BAlo23L-.js';
6
+ export { T as ToolTranslator, a as ToolTranslatorOptions } from './index-DEEYyEpu.js';
7
+ export { F as FileServer, a as FileServerOptions, b as FsError, c as FsErrorCode, R as ReadFileParams, T as TerminalServer, d as TerminalServerOptions, W as WriteFileParams } from './terminal-server-P9KpMZTT.js';
7
8
  import 'node:events';
8
9
  import '@wrongstack/core';
9
10
 
10
- /**
11
- * Permission policy for ACP v1 client sessions.
12
- *
13
- * ACP agents can call `session/request_permission` to ask the user
14
- * before executing a tool call. The client is expected to surface
15
- * the question, get a decision, and respond. This module is the seam
16
- * where WrongStack-specific permission UI can plug in; for v1 we ship
17
- * a minimal default that auto-approves the first `allow_once` option
18
- * (or `allow_always` if present) and rejects on abort.
19
- */
20
-
21
- /** A single permission decision request. */
22
- interface PermissionRequest {
23
- toolCall: ToolCallUpdateNotification;
24
- options: readonly PermissionOption[];
25
- signal: AbortSignal;
26
- }
27
- /** A permission policy decides how to respond to a request. */
28
- type PermissionPolicy = (req: PermissionRequest) => Promise<RequestPermissionOutcome>;
29
- /**
30
- * Default policy: pick the safest-looking allow option if the signal
31
- * is not aborted, otherwise report cancelled. Order of preference:
32
- *
33
- * 1. `allow_always`
34
- * 2. `allow_once`
35
- * 3. anything else with `optionId` (last resort)
36
- *
37
- * Real WrongStack permission UIs replace this; the contract is the
38
- * `PermissionPolicy` function type, not the implementation.
39
- */
40
- declare const defaultPermissionPolicy: PermissionPolicy;
41
-
42
- interface ACPSessionOptions {
43
- command: string;
44
- args?: readonly string[] | undefined;
45
- env?: Record<string, string> | undefined;
46
- cwd?: string | undefined;
47
- role?: string | undefined;
48
- /** Sandbox root for fs/* and terminal/* methods. */
49
- projectRoot: string;
50
- /** Hard timeout for one prompt turn. Default 5 minutes. */
51
- timeoutMs?: number | undefined;
52
- /** Override the permission policy. */
53
- permissionPolicy?: PermissionPolicy | undefined;
54
- /** Per-fs-call timeout, default 30s. */
55
- fsTimeoutMs?: number | undefined;
56
- /** Per-terminal command timeout, default 5 minutes. */
57
- terminalTimeoutMs?: number | undefined;
58
- /** Per-terminal output byte cap, default 1 MiB. */
59
- terminalOutputByteLimit?: number | undefined;
60
- }
61
- interface ACPSessionRunResult {
62
- text: string;
63
- stopReason: StopReason;
64
- hasText: boolean;
65
- usage?: {
66
- used: number;
67
- size: number;
68
- cost?: UsageCost | undefined;
69
- } | undefined;
70
- plan?: PlanEntry[] | undefined;
71
- }
72
- type ACPSessionErrorKind = 'spawn_failed' | 'init_failed' | 'protocol_error' | 'session_create_failed' | 'prompt_failed' | 'aborted' | 'closed' | 'agent_died' | 'unsupported_capability';
73
- declare class ACPSessionError extends Error {
74
- readonly kind: ACPSessionErrorKind;
75
- readonly cause: unknown;
76
- constructor(kind: ACPSessionErrorKind, message: string, cause?: unknown);
77
- }
78
- declare class ACPSession {
79
- private readonly transport;
80
- private readonly fileServer;
81
- private readonly terminalServer;
82
- private readonly permissionPolicy;
83
- private readonly timeoutMs;
84
- private readonly opts;
85
- private state;
86
- private sessionId;
87
- /** Pending outbound requests (initialize, session/new, session/prompt, etc). */
88
- private readonly pending;
89
- private nextId;
90
- /** True after close() has been called. */
91
- private closed;
92
- private constructor();
93
- /**
94
- * Spawn the child, run the initialize handshake, install the
95
- * message dispatch, and return a ready session.
96
- */
97
- static start(opts: ACPSessionOptions): Promise<ACPSession>;
98
- private initialize;
99
- /**
100
- * Run one prompt turn. Creates a session if needed, sends the
101
- * prompt, streams session/update notifications, and resolves with
102
- * the agent's response.
103
- *
104
- * Cancellation: if `signal` aborts mid-prompt, we send
105
- * `session/cancel` (a notification per spec) and keep accepting
106
- * updates until the agent returns with `stopReason: 'cancelled'`.
107
- * The result is the same shape as a normal turn, with
108
- * `stopReason === 'cancelled'`.
109
- */
110
- prompt(text: string, signal: AbortSignal): Promise<ACPSessionRunResult>;
111
- private createSession;
112
- /** Tear down the session and kill the child process. */
113
- close(): Promise<void>;
114
- private allocId;
115
- private sendRequest;
116
- private handleMessage;
117
- private handleUpdate;
118
- private scratch;
119
- private accumulatedText;
120
- private accumulatedPlan;
121
- private accumulatedUsage;
122
- private resetScratch;
123
- private handlePermissionRequest;
124
- private handleFsRequest;
125
- private handleTerminalRequest;
126
- }
127
-
128
11
  /** Vendor classification — used to filter the catalog by family. */
129
12
  type ACPAgentVendor = 'anthropic' | 'google' | 'openai' | 'github' | 'community';
130
13
  /** How the agent is integrated into ACP. */
@@ -212,6 +95,12 @@ declare class EnsembleRegistry {
212
95
  /**
213
96
  * Probe every catalog entry in parallel and return the detection
214
97
  * results. Results are cached for `PROBE_CACHE_MS`.
98
+ *
99
+ * Probes are dispatched with bounded concurrency (`MAX_PARALLEL_PROBES`)
100
+ * so cold-start lists do not spawn `catalog.length` subprocesses at
101
+ * once — which is especially wasteful on Windows shells and on hosts
102
+ * with large agent catalogs. The output order still matches
103
+ * `this.catalog` so callers can index by position.
215
104
  */
216
105
  list(): Promise<readonly DetectedAgent[]>;
217
106
  /** Probe a single descriptor. Always returns a `DetectedAgent`. */
@@ -233,14 +122,13 @@ declare class EnsembleRegistry {
233
122
  *
234
123
  * Maintenance
235
124
  * ───────────
236
- * This is a static catalog by design. ACP v1 is a moving target: agents
237
- * ship ACP support, deprecate it, change invocation flags. Auto-fetching
238
- * a live registry sounds appealing but adds a runtime dependency on
239
- * network + on whatever schema the ACP team decides on for the Registry
240
- * RFD. A typed static file the maintainer refreshes on a known schedule
241
- * is more reliable, easier to diff in PRs, and keeps probe failures
242
- * attributable to the local machine rather than to a transient registry
243
- * outage.
125
+ * This is the OFFLINE FALLBACK catalog. The official, hourly-updated registry
126
+ * now lives at https://github.com/agentclientprotocol/registry (CDN snapshot
127
+ * in `acp-registry-fetch.ts`). `wstack acp sync` / `/acp sync` fetch it into a
128
+ * local cache that supersedes this file at resolution time so this catalog
129
+ * only needs to carry the most-used agents with invocations that work without
130
+ * a network round-trip. Entries here are kept aligned to the registry's
131
+ * authoritative ACP-entry commands; run `/acp probe` to confirm on a host.
244
132
  *
245
133
  * Each entry tags its `integration` mechanism:
246
134
  * - `native` — the agent ships with a documented ACP entry flag.
@@ -269,103 +157,91 @@ declare const AGENTS_CATALOG: readonly ACPAgentDescriptor[];
269
157
  /** O(1) lookup by id. Returns `undefined` for unknown ids. */
270
158
  declare function findAgentDescriptor(id: string): ACPAgentDescriptor | undefined;
271
159
 
272
- interface FileServerOptions {
273
- /** Absolute path; only files under this root are accessible. */
274
- projectRoot: string;
275
- /** Per-call timeout, default 30s. */
276
- timeoutMs?: number;
277
- }
278
- interface ReadFileParams {
279
- sessionId: string;
280
- path: string;
281
- }
282
- interface WriteFileParams {
283
- sessionId: string;
284
- path: string;
285
- content: string;
286
- }
287
- type FsErrorCode = 'ENOENT' | 'EACCES' | 'OUTSIDE_ROOT' | 'TIMEOUT' | 'INVALID_PATH';
288
160
  /**
289
- * Thrown for protocol-level rejections (path outside root, etc.).
290
- * The session converts these into JSON-RPC error responses.
161
+ * Official ACP registry fetcher.
162
+ *
163
+ * The Agent Client Protocol maintains a canonical, hourly-updated registry of
164
+ * ACP-supporting agents at https://github.com/agentclientprotocol/registry,
165
+ * published as a single JSON document on a CDN. This module fetches that
166
+ * document and maps each entry to our `ACPAgentDescriptor` shape so the live
167
+ * list can supersede the bundled static `AGENTS_CATALOG` (which remains the
168
+ * offline fallback).
169
+ *
170
+ * Distribution → spawn-command mapping (per the registry FORMAT.md):
171
+ * - npx: { package, args } → `npx -y <package> <args>`
172
+ * - uvx: { package, args } → `uvx <package> <args>`
173
+ * - binary: { "<os>-<arch>": { cmd, args, env } }
174
+ * → `<basename(cmd)> <args>` for THIS host
175
+ *
176
+ * Binary entries reference a downloadable archive we do NOT fetch; we map the
177
+ * platform `cmd` to its basename so an already-installed on-PATH binary (the
178
+ * common case for goose/opencode/cursor) still launches. Agents distributed
179
+ * ONLY as a binary with no current-platform target are dropped (not runnable).
180
+ *
181
+ * Network is never required at runtime: this is invoked by an explicit
182
+ * `wstack acp sync` / `/acp sync`, the result is cached, and resolution falls
183
+ * back to the static catalog when no cache exists.
291
184
  */
292
- declare class FsError extends Error {
293
- readonly code: FsErrorCode;
294
- readonly path: string;
295
- constructor(code: FsErrorCode, path: string, message: string);
296
- }
297
- declare class FileServer {
298
- private readonly root;
299
- private readonly timeoutMs;
300
- constructor(opts: FileServerOptions);
301
- /** Read a text file. Returns the content as a string. */
302
- readTextFile(params: ReadFileParams): Promise<{
303
- content: string;
304
- }>;
305
- /** Write a text file. Atomic via write-then-rename. */
306
- writeTextFile(params: WriteFileParams): Promise<void>;
307
- /**
308
- * Resolve a path; throw `FsError('OUTSIDE_ROOT')` if the result is
309
- * not under the project root. Symlinks are not followed here — we
310
- * operate on the textual path. A future hardening pass can
311
- * `fs.realpath` each access to catch symlink escapes.
312
- */
313
- private resolveInside;
314
- }
315
185
 
316
- interface TerminalServerOptions {
317
- projectRoot: string;
318
- /** Hard cap on per-command wall-clock. Default 5 minutes. */
319
- commandTimeoutMs?: number;
320
- /** Bytes of output to retain per terminal. Default 1 MiB. */
321
- outputByteLimit?: number;
322
- /** Optional abort signal that kills ALL active terminals. */
323
- signal?: AbortSignal;
324
- }
325
- declare class TerminalServer {
326
- private readonly terminals;
327
- private readonly projectRoot;
328
- private readonly commandTimeoutMs;
329
- private readonly outputByteLimit;
330
- private nextId;
331
- constructor(opts: TerminalServerOptions);
332
- /** Spawn a new terminal. Returns the agent-facing id. */
333
- create(params: {
334
- sessionId: string;
335
- command: string;
336
- args?: string[];
337
- env?: {
338
- name: string;
339
- value: string;
340
- }[];
341
- cwd?: string;
342
- outputByteLimit?: number;
343
- }): {
344
- terminalId: string;
345
- };
346
- /** Return captured output and (if available) the exit status. */
347
- output(terminalId: string): {
348
- output: string;
349
- truncated: boolean;
350
- exitStatus?: {
351
- exitCode: number | null;
352
- signal: string | null;
186
+ /** Canonical CDN endpoint for the latest registry snapshot. */
187
+ declare const ACP_REGISTRY_URL = "https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json";
188
+ /** One raw entry from the registry JSON (only the fields we consume). */
189
+ interface RegistryAgentEntry {
190
+ id: string;
191
+ name?: string;
192
+ version?: string;
193
+ description?: string;
194
+ repository?: string;
195
+ website?: string;
196
+ authors?: string[];
197
+ distribution?: {
198
+ npx?: {
199
+ package: string;
200
+ args?: string[];
201
+ };
202
+ uvx?: {
203
+ package: string;
204
+ args?: string[];
353
205
  };
206
+ binary?: Record<string, {
207
+ archive?: string;
208
+ cmd: string;
209
+ args?: string[];
210
+ env?: Record<string, string>;
211
+ }>;
354
212
  };
355
- /** Block until the process exits. Resolves with the exit status. */
356
- waitForExit(terminalId: string): Promise<{
357
- exitCode: number | null;
358
- signal: string | null;
359
- }>;
360
- /** Kill the process but keep the terminal record (agent can still read output). */
361
- kill(terminalId: string): void;
362
- /** Kill the process if alive and remove the record. */
363
- release(terminalId: string): void;
364
- /** Kill all active terminals. Used on session close. */
365
- releaseAll(): void;
366
- private resolveCwd;
367
- private buildEnv;
368
213
  }
214
+ interface FetchAcpRegistryResult {
215
+ /** ISO timestamp the snapshot was fetched. */
216
+ fetchedAt: string;
217
+ /** Mapped, runnable descriptors (entries we could not map are dropped). */
218
+ agents: ACPAgentDescriptor[];
219
+ }
220
+ interface FetchAcpRegistryOptions {
221
+ /** Override the endpoint (tests / mirrors). */
222
+ url?: string | undefined;
223
+ /** Abort the fetch from the caller. */
224
+ signal?: AbortSignal | undefined;
225
+ /** Hard timeout in ms (default 15s). Layered under any caller signal. */
226
+ timeoutMs?: number | undefined;
227
+ /** ISO timestamp to stamp the result with (tests pass a fixed value). */
228
+ now?: string | undefined;
229
+ /** Platform key for binary selection (tests). Defaults to this host. */
230
+ platformKey?: string | undefined;
231
+ }
232
+ /** Map Node's platform/arch to the registry's `<os>-<arch>` key form. */
233
+ declare function currentPlatformKey(): string;
234
+ /**
235
+ * Map one registry entry to an `ACPAgentDescriptor`, or `null` if it carries
236
+ * no distribution runnable on this host. Pure — no I/O.
237
+ */
238
+ declare function mapRegistryEntry(entry: RegistryAgentEntry, platformKey?: string): ACPAgentDescriptor | null;
239
+ /**
240
+ * Fetch the live registry and return mapped descriptors. Throws on network /
241
+ * parse failure so the caller (`wstack acp sync`) can surface it; callers that
242
+ * want graceful degradation use the cached/static fallback instead.
243
+ */
244
+ declare function fetchAcpRegistry(opts?: FetchAcpRegistryOptions): Promise<FetchAcpRegistryResult>;
369
245
 
370
246
  /**
371
247
  * Ensemble runner — fan a single task out to multiple ACP agents in parallel.
@@ -395,6 +271,8 @@ declare class TerminalServer {
395
271
  * `finally`, so a throw in the body still tears the child down.
396
272
  */
397
273
 
274
+ /** Live per-agent progress callback for an ensemble run. */
275
+ type EnsembleProgressHandler = (agentId: string, event: ACPProgressEvent) => void;
398
276
  /**
399
277
  * Per-agent outcome from an ensemble run.
400
278
  * `status === 'skipped'` carries a `reason`; the other statuses carry
@@ -469,11 +347,25 @@ interface EnsembleRunnerOptions {
469
347
  * `SubagentRunContext.signal` they receive.
470
348
  */
471
349
  signal?: AbortSignal | undefined;
350
+ /**
351
+ * Live progress callback. Invoked for every streamed update from every
352
+ * agent, tagged with the agent id so the caller can render interleaved
353
+ * progress (e.g. `[gemini-cli] edit foo.ts`).
354
+ */
355
+ onProgress?: EnsembleProgressHandler | undefined;
356
+ /**
357
+ * Maximum number of agents to launch concurrently. Defaults to
358
+ * `DEFAULT_MAX_CONCURRENCY` (4). Set to 1 for serial execution;
359
+ * values larger than the runnable count are clamped down. Bounded
360
+ * fan-out keeps simultaneous ACP subprocess / WebSocket counts
361
+ * manageable when an ensemble has many members.
362
+ */
363
+ maxConcurrency?: number | undefined;
472
364
  }
473
365
  /**
474
- * Default command resolver. Checks the legacy `ACP_AGENT_COMMANDS` map
475
- * first, then falls back to the 12-entry catalog. Returns `null` for
476
- * ids that aren't in either source.
366
+ * Default command resolver delegates to `resolveAcpAgentCommand`, so the
367
+ * catalog's corrected invocations win over the stale legacy map (the legacy
368
+ * map is now only a last-resort fallback). Returns `null` for unknown ids.
477
369
  */
478
370
  declare const defaultEnsembleCmdResolver: EnsembleCmdResolver;
479
371
  /**
@@ -496,4 +388,71 @@ declare function runEnsemble(opts: EnsembleRunnerOptions): Promise<EnsembleResul
496
388
  */
497
389
  declare function renderEnsembleText(result: EnsembleResult): string;
498
390
 
499
- export { type ACPAgentDescriptor, type ACPAgentVendor, type ACPIntegration, ACPSession, ACPSessionError, type ACPSessionErrorKind, type ACPSessionOptions, type ACPSessionRunResult, ACPSubagentRunnerOptions, AGENTS_CATALOG, type DetectedAgent, type EnsembleAgentResult, type EnsembleCmdResolver, EnsembleRegistry, type EnsembleRegistryOptions, type EnsembleResult, type EnsembleRunnerOptions, FileServer, type FileServerOptions, FsError, type FsErrorCode, type PermissionPolicy, type PermissionRequest, type ReadFileParams, TerminalServer, type TerminalServerOptions, type WriteFileParams, defaultEnsembleCmdResolver, defaultPermissionPolicy, findAgentDescriptor, renderEnsembleText, runEnsemble };
391
+ type AcpBenchStatus = 'pass' | 'partial' | 'fail' | 'skipped';
392
+ interface AcpBenchCheck {
393
+ name: 'handshake' | 'prompt' | 'marker' | 'fs';
394
+ ok: boolean;
395
+ detail?: string | undefined;
396
+ }
397
+ interface AcpBenchAgentResult {
398
+ agentId: string;
399
+ status: AcpBenchStatus;
400
+ checks: AcpBenchCheck[];
401
+ /** Agent metadata from the initialize handshake. */
402
+ agentInfo?: {
403
+ name: string;
404
+ title?: string | undefined;
405
+ version: string;
406
+ } | undefined;
407
+ handshakeMs?: number | undefined;
408
+ promptMs?: number | undefined;
409
+ /** First line of the agent's reply (trimmed), for the report. */
410
+ sample?: string | undefined;
411
+ /** Why the agent failed / was skipped. */
412
+ reason?: string | undefined;
413
+ durationMs: number;
414
+ }
415
+ interface AcpBenchResult {
416
+ results: AcpBenchAgentResult[];
417
+ summary: {
418
+ pass: number;
419
+ partial: number;
420
+ fail: number;
421
+ skipped: number;
422
+ };
423
+ totalDurationMs: number;
424
+ }
425
+ /** Resolve an agent id to its spawn command (null = unknown). */
426
+ type AcpBenchCmdResolver = (id: string) => ACPSubagentRunnerOptions | null;
427
+ interface AcpBenchOptions {
428
+ /** Agent ids to bench. */
429
+ agentIds: string[];
430
+ /** Resolve each id → spawn command (wire overrides + synced registry here). */
431
+ resolveCmd: AcpBenchCmdResolver;
432
+ /** FS sandbox + cwd for each agent. Defaults to `process.cwd()`. */
433
+ projectRoot?: string | undefined;
434
+ /** Per-agent hard timeout (handshake + each prompt). Default 60s. */
435
+ timeoutMs?: number | undefined;
436
+ /** Also verify the `fs/read_text_file` callback channel. Default false. */
437
+ checkFs?: boolean | undefined;
438
+ /** Max agents benched concurrently. Default 2 (each runs a real LLM turn). */
439
+ concurrency?: number | undefined;
440
+ /** Cancellation. Aborts the in-flight agent and skips the rest. */
441
+ signal?: AbortSignal | undefined;
442
+ /** Live per-agent status callback for the UI. */
443
+ onProgress?: ((agentId: string, phase: 'start' | 'done', result?: AcpBenchAgentResult) => void) | undefined;
444
+ /** Marker token override (tests). Default is a random per-run token. */
445
+ marker?: string | undefined;
446
+ /** Clock injection (tests). Defaults to `Date.now`. */
447
+ now?: (() => number) | undefined;
448
+ }
449
+ /**
450
+ * Bench a set of ACP agents end-to-end and return a graded report. Unknown
451
+ * ids are reported `skipped`. Bounded concurrency keeps the number of live
452
+ * ACP subprocesses (each running a real model turn) manageable.
453
+ */
454
+ declare function runAcpBench(opts: AcpBenchOptions): Promise<AcpBenchResult>;
455
+ /** Render an `AcpBenchResult` as a plain-text report. */
456
+ declare function renderAcpBenchText(result: AcpBenchResult): string;
457
+
458
+ export { type ACPAgentDescriptor, type ACPAgentVendor, type ACPIntegration, ACPProgressEvent, ACPSubagentRunnerOptions, ACP_REGISTRY_URL, AGENTS_CATALOG, type AcpBenchAgentResult, type AcpBenchCheck, type AcpBenchCmdResolver, type AcpBenchOptions, type AcpBenchResult, type AcpBenchStatus, type DetectedAgent, type EnsembleAgentResult, type EnsembleCmdResolver, type EnsembleProgressHandler, EnsembleRegistry, type EnsembleRegistryOptions, type EnsembleResult, type EnsembleRunnerOptions, type FetchAcpRegistryOptions, type FetchAcpRegistryResult, type RegistryAgentEntry, currentPlatformKey, defaultEnsembleCmdResolver, fetchAcpRegistry, findAgentDescriptor, mapRegistryEntry, renderAcpBenchText, renderEnsembleText, runAcpBench, runEnsemble };