@wrongstack/acp 0.284.1 → 0.285.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.
- package/dist/agent/index.d.ts +13 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/{wrongstack-acp-agent-nzrqmJnc.d.ts → agent/protocol-handler.d.ts} +26 -75
- package/dist/agent/protocol-handler.d.ts.map +1 -0
- package/dist/{server-agent-turn-C3U0lhA-.d.ts → agent/server-agent-turn.d.ts} +8 -63
- package/dist/agent/server-agent-turn.d.ts.map +1 -0
- package/dist/agent/session-store.d.ts +53 -0
- package/dist/agent/session-store.d.ts.map +1 -0
- package/dist/agent/stdio-transport.d.ts +82 -0
- package/dist/agent/stdio-transport.d.ts.map +1 -0
- package/dist/{tools-registry-D2xdbzN7.d.ts → agent/tools-registry.d.ts} +4 -7
- package/dist/agent/tools-registry.d.ts.map +1 -0
- package/dist/agent/wrongstack-acp-agent.d.ts +58 -0
- package/dist/agent/wrongstack-acp-agent.d.ts.map +1 -0
- package/dist/agent/ws-bridge-transport.d.ts +37 -0
- package/dist/agent/ws-bridge-transport.d.ts.map +1 -0
- package/dist/agent.d.ts +1 -45
- package/dist/agent.js +21 -11
- package/dist/agent.js.map +7 -1
- package/dist/client/acp-session.d.ts +349 -0
- package/dist/client/acp-session.d.ts.map +1 -0
- package/dist/client/file-server.d.ts +44 -0
- package/dist/client/file-server.d.ts.map +1 -0
- package/dist/client/index.d.ts +12 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/permission.d.ts +45 -0
- package/dist/client/permission.d.ts.map +1 -0
- package/dist/client/terminal-server.d.ts +54 -0
- package/dist/client/terminal-server.d.ts.map +1 -0
- package/dist/{index-DEEYyEpu.d.ts → client/tool-translator.d.ts} +17 -8
- package/dist/client/tool-translator.d.ts.map +1 -0
- package/dist/client/websocket-transport.d.ts +40 -0
- package/dist/client/websocket-transport.d.ts.map +1 -0
- package/dist/client.d.ts +1 -5
- package/dist/client.js +36 -17
- package/dist/client.js.map +7 -1
- package/dist/index.d.ts +43 -457
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +126 -67
- package/dist/index.js.map +7 -1
- package/dist/integration/acp-bench.d.ts +68 -0
- package/dist/integration/acp-bench.d.ts.map +1 -0
- package/dist/integration/acp-subagent-runner.d.ts +194 -0
- package/dist/integration/acp-subagent-runner.d.ts.map +1 -0
- package/dist/integration/ensemble-runner.d.ts +147 -0
- package/dist/integration/ensemble-runner.d.ts.map +1 -0
- package/dist/integration/run-one-acp-task.d.ts +29 -0
- package/dist/integration/run-one-acp-task.d.ts.map +1 -0
- package/dist/registry/acp-registry-fetch.d.ts +86 -0
- package/dist/registry/acp-registry-fetch.d.ts.map +1 -0
- package/dist/registry/agents.catalog.d.ts +46 -0
- package/dist/registry/agents.catalog.d.ts.map +1 -0
- package/dist/registry/ensemble-registry.d.ts +104 -0
- package/dist/registry/ensemble-registry.d.ts.map +1 -0
- package/dist/sdk.d.ts +41 -12
- package/dist/sdk.d.ts.map +1 -0
- package/dist/sdk.js +142 -72
- package/dist/sdk.js.map +7 -1
- package/dist/types/acp-messages.d.ts +133 -0
- package/dist/types/acp-messages.d.ts.map +1 -0
- package/dist/types/acp-v1.d.ts +476 -0
- package/dist/types/acp-v1.d.ts.map +1 -0
- package/dist/win32-cmd.d.ts +7 -0
- package/dist/win32-cmd.d.ts.map +1 -0
- package/dist/wrongstack-acp-agent.d.ts +1 -3
- package/dist/wrongstack-acp-agent.js +11 -9
- package/dist/wrongstack-acp-agent.js.map +7 -1
- package/package.json +4 -4
- package/dist/acp-subagent-runner-BAlo23L-.d.ts +0 -644
- package/dist/acp-v1-BxskPsdo.d.ts +0 -520
- package/dist/terminal-server-P9KpMZTT.d.ts +0 -99
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { ACPSubagentRunnerOptions } from './acp-subagent-runner.js';
|
|
2
|
+
export type AcpBenchStatus = 'pass' | 'partial' | 'fail' | 'skipped';
|
|
3
|
+
export interface AcpBenchCheck {
|
|
4
|
+
name: 'handshake' | 'prompt' | 'marker' | 'fs';
|
|
5
|
+
ok: boolean;
|
|
6
|
+
detail?: string | undefined;
|
|
7
|
+
}
|
|
8
|
+
export interface AcpBenchAgentResult {
|
|
9
|
+
agentId: string;
|
|
10
|
+
status: AcpBenchStatus;
|
|
11
|
+
checks: AcpBenchCheck[];
|
|
12
|
+
/** Agent metadata from the initialize handshake. */
|
|
13
|
+
agentInfo?: {
|
|
14
|
+
name: string;
|
|
15
|
+
title?: string | undefined;
|
|
16
|
+
version: string;
|
|
17
|
+
} | undefined;
|
|
18
|
+
handshakeMs?: number | undefined;
|
|
19
|
+
promptMs?: number | undefined;
|
|
20
|
+
/** First line of the agent's reply (trimmed), for the report. */
|
|
21
|
+
sample?: string | undefined;
|
|
22
|
+
/** Why the agent failed / was skipped. */
|
|
23
|
+
reason?: string | undefined;
|
|
24
|
+
durationMs: number;
|
|
25
|
+
}
|
|
26
|
+
export interface AcpBenchResult {
|
|
27
|
+
results: AcpBenchAgentResult[];
|
|
28
|
+
summary: {
|
|
29
|
+
pass: number;
|
|
30
|
+
partial: number;
|
|
31
|
+
fail: number;
|
|
32
|
+
skipped: number;
|
|
33
|
+
};
|
|
34
|
+
totalDurationMs: number;
|
|
35
|
+
}
|
|
36
|
+
/** Resolve an agent id to its spawn command (null = unknown). */
|
|
37
|
+
export type AcpBenchCmdResolver = (id: string) => ACPSubagentRunnerOptions | null;
|
|
38
|
+
export interface AcpBenchOptions {
|
|
39
|
+
/** Agent ids to bench. */
|
|
40
|
+
agentIds: string[];
|
|
41
|
+
/** Resolve each id → spawn command (wire overrides + synced registry here). */
|
|
42
|
+
resolveCmd: AcpBenchCmdResolver;
|
|
43
|
+
/** FS sandbox + cwd for each agent. Defaults to `process.cwd()`. */
|
|
44
|
+
projectRoot?: string | undefined;
|
|
45
|
+
/** Per-agent hard timeout (handshake + each prompt). Default 60s. */
|
|
46
|
+
timeoutMs?: number | undefined;
|
|
47
|
+
/** Also verify the `fs/read_text_file` callback channel. Default false. */
|
|
48
|
+
checkFs?: boolean | undefined;
|
|
49
|
+
/** Max agents benched concurrently. Default 2 (each runs a real LLM turn). */
|
|
50
|
+
concurrency?: number | undefined;
|
|
51
|
+
/** Cancellation. Aborts the in-flight agent and skips the rest. */
|
|
52
|
+
signal?: AbortSignal | undefined;
|
|
53
|
+
/** Live per-agent status callback for the UI. */
|
|
54
|
+
onProgress?: ((agentId: string, phase: 'start' | 'done', result?: AcpBenchAgentResult) => void) | undefined;
|
|
55
|
+
/** Marker token override (tests). Default is a random per-run token. */
|
|
56
|
+
marker?: string | undefined;
|
|
57
|
+
/** Clock injection (tests). Defaults to `Date.now`. */
|
|
58
|
+
now?: (() => number) | undefined;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Bench a set of ACP agents end-to-end and return a graded report. Unknown
|
|
62
|
+
* ids are reported `skipped`. Bounded concurrency keeps the number of live
|
|
63
|
+
* ACP subprocesses (each running a real model turn) manageable.
|
|
64
|
+
*/
|
|
65
|
+
export declare function runAcpBench(opts: AcpBenchOptions): Promise<AcpBenchResult>;
|
|
66
|
+
/** Render an `AcpBenchResult` as a plain-text report. */
|
|
67
|
+
export declare function renderAcpBenchText(result: AcpBenchResult): string;
|
|
68
|
+
//# sourceMappingURL=acp-bench.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acp-bench.d.ts","sourceRoot":"","sources":["../../src/integration/acp-bench.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAEzE,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;AAErE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC/C,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,oDAAoD;IACpD,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACtF,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,iEAAiE;AACjE,MAAM,MAAM,mBAAmB,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,wBAAwB,GAAG,IAAI,CAAC;AAElF,MAAM,WAAW,eAAe;IAC9B,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,+EAA+E;IAC/E,UAAU,EAAE,mBAAmB,CAAC;IAChC,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,2EAA2E;IAC3E,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,mEAAmE;IACnE,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC,iDAAiD;IACjD,UAAU,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,mBAAmB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC5G,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,uDAAuD;IACvD,GAAG,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAC;CAClC;AAkJD;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CA2EhF;AAED,yDAAyD;AACzD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CA2BjE"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ACPSubagentRunner — `SubagentRunner` implementation for DIR-1.
|
|
3
|
+
*
|
|
4
|
+
* Wraps an external ACP-supporting agent (Claude Code, Gemini CLI, Codex
|
|
5
|
+
* CLI, Cline, Goose, OpenHands, etc.) as a WrongStack subagent. The
|
|
6
|
+
* external agent runs its own agent loop; we send it a task via the ACP
|
|
7
|
+
* v1 protocol and return the result.
|
|
8
|
+
*
|
|
9
|
+
* v1 spec: https://agentclientprotocol.com/protocol/v1/overview
|
|
10
|
+
*
|
|
11
|
+
* Connected to the Director / MultiAgentCoordinator via the
|
|
12
|
+
* `SubagentRunner` interface (same shape as `AgentSubagentRunner`).
|
|
13
|
+
*/
|
|
14
|
+
import type { SubagentRunner } from '@wrongstack/core';
|
|
15
|
+
import { ACPSession, type ACPProgressHandler } from '../client/acp-session.js';
|
|
16
|
+
import type { PermissionPolicy } from '../client/permission.js';
|
|
17
|
+
import type { McpServer } from '../types/acp-v1.js';
|
|
18
|
+
export interface ACPSubagentRunnerOptions {
|
|
19
|
+
/** How to spawn the external agent. */
|
|
20
|
+
command: string;
|
|
21
|
+
args?: string[] | undefined;
|
|
22
|
+
env?: Record<string, string> | undefined;
|
|
23
|
+
cwd?: string | undefined;
|
|
24
|
+
/** Subagent role label — surfaced in errors and used for logging. */
|
|
25
|
+
role?: string | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Hard wall-clock cap for one prompt turn. Defaults to 5 minutes.
|
|
28
|
+
* Overrides `SubagentRunContext.budget.limits.timeoutMs` if both are set.
|
|
29
|
+
*/
|
|
30
|
+
timeoutMs?: number | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Filesystem sandbox root. Defaults to `options.cwd` (when set) or
|
|
33
|
+
* the process's current working directory. All `fs/read_text_file` /
|
|
34
|
+
* `fs/write_text_file` calls are bounded to this root.
|
|
35
|
+
*/
|
|
36
|
+
projectRoot?: string | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Live progress callback. Forwarded to `ACPSession.prompt` so the host
|
|
39
|
+
* can render the external agent's tool calls / diffs / text as they
|
|
40
|
+
* stream, instead of waiting for the buffered final result.
|
|
41
|
+
*/
|
|
42
|
+
onProgress?: ACPProgressHandler | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Permission policy for the external agent's `session/request_permission`
|
|
45
|
+
* calls. Defaults to the session's own default. Inject the host's
|
|
46
|
+
* confirm/trust UI here so an external agent's file writes / commands
|
|
47
|
+
* are surfaced to a human instead of silently auto-approved.
|
|
48
|
+
*/
|
|
49
|
+
permissionPolicy?: PermissionPolicy | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* MCP servers to expose to the external agent (passed through
|
|
52
|
+
* `session/new` / `session/load`). Stdio servers are always sent;
|
|
53
|
+
* HTTP/SSE are filtered by the agent's advertised capabilities.
|
|
54
|
+
*/
|
|
55
|
+
mcpServers?: McpServer[] | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* When true, the underlying `ACPSession` is kept open across multiple
|
|
58
|
+
* runner invocations (multi-turn conversation — the external agent
|
|
59
|
+
* keeps its context). The caller MUST call `stop()` to tear it down.
|
|
60
|
+
* Defaults to false (one process per task).
|
|
61
|
+
*/
|
|
62
|
+
persistent?: boolean | undefined;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Static catalog of agent ids → spawn options.
|
|
66
|
+
*
|
|
67
|
+
* The CLI and the host's `buildACPRunner` look up entries by id. The
|
|
68
|
+
* canonical, multi-source catalog is `packages/acp/src/registry/agents.catalog.ts`
|
|
69
|
+
* (the 12-entry static catalog introduced in commit 4ad287b4). This
|
|
70
|
+
* map stays for backward compatibility with existing call sites that
|
|
71
|
+
* import it directly; new code should prefer the registry.
|
|
72
|
+
*/
|
|
73
|
+
export declare const ACP_AGENT_COMMANDS: Record<string, ACPSubagentRunnerOptions>;
|
|
74
|
+
/**
|
|
75
|
+
* Build a one-shot `SubagentRunner` for a single agent invocation. Each
|
|
76
|
+
* call to the returned function spawns a fresh child process, runs one
|
|
77
|
+
* prompt turn, and tears everything down. The cost is ~1 second of
|
|
78
|
+
* process-startup per call; for long-lived sessions (multi-turn
|
|
79
|
+
* conversations), use `makeACPSubagentRunnerWithStop` and call `stop()`
|
|
80
|
+
* explicitly.
|
|
81
|
+
*/
|
|
82
|
+
export declare function makeACPSubagentRunner(options: ACPSubagentRunnerOptions): Promise<SubagentRunner>;
|
|
83
|
+
/**
|
|
84
|
+
* Build a long-lived `SubagentRunner` plus an explicit `stop()` for
|
|
85
|
+
* teardown. The caller is responsible for calling `stop()` when done
|
|
86
|
+
* (or when the host's signal fires). Useful for the `wstack acp spawn`
|
|
87
|
+
* CLI command, which holds the child open for the duration of a user
|
|
88
|
+
* task and tears down on SIGINT.
|
|
89
|
+
*/
|
|
90
|
+
export declare function makeACPSubagentRunnerWithStop(options: ACPSubagentRunnerOptions): Promise<{
|
|
91
|
+
runner: SubagentRunner;
|
|
92
|
+
stop: () => void | Promise<void>;
|
|
93
|
+
}>;
|
|
94
|
+
/** Re-export so the CLI handler can import the session type. */
|
|
95
|
+
export type { ACPSession };
|
|
96
|
+
/** Exposed for the `wstack acp list` renderer. */
|
|
97
|
+
export declare function describeAgent(id: string): {
|
|
98
|
+
command: string;
|
|
99
|
+
args: readonly string[];
|
|
100
|
+
role: string;
|
|
101
|
+
} | null;
|
|
102
|
+
/**
|
|
103
|
+
* Per-agent ACP invocation overrides, sourced from the user's
|
|
104
|
+
* `~/.wrongstack/config.json` (`config.acp.agents`). Lets a user point an
|
|
105
|
+
* agent id at the correct ACP entry — e.g. the Zed Claude-Code adapter —
|
|
106
|
+
* without a code change. NEVER honoured from in-project config (it is an
|
|
107
|
+
* arbitrary-command exec surface); see `config-loader.ts`.
|
|
108
|
+
*/
|
|
109
|
+
export type AcpAgentCommandOverrides = Record<string, {
|
|
110
|
+
command: string;
|
|
111
|
+
args?: string[];
|
|
112
|
+
env?: Record<string, string>;
|
|
113
|
+
}>;
|
|
114
|
+
/** A synced-registry catalog keyed by registry id (from `fetchAcpRegistry`). */
|
|
115
|
+
export type AcpLiveCatalog = Record<string, {
|
|
116
|
+
command: string;
|
|
117
|
+
args?: readonly string[];
|
|
118
|
+
env?: Record<string, string>;
|
|
119
|
+
}>;
|
|
120
|
+
/**
|
|
121
|
+
* Map our stable, human-friendly catalog ids to the official registry's ids,
|
|
122
|
+
* so a live-synced registry (keyed by registry id) still resolves when the
|
|
123
|
+
* user types our id. Our id is preferred in the UI; the alias is the bridge.
|
|
124
|
+
*/
|
|
125
|
+
export declare const REGISTRY_ID_ALIASES: Readonly<Record<string, string>>;
|
|
126
|
+
/**
|
|
127
|
+
* Resolve an agent id to its spawn command. Precedence:
|
|
128
|
+
* 1. user override (`config.acp.agents[id]`)
|
|
129
|
+
* 2. the bundled static `AGENTS_CATALOG` (curated LOCAL-binary invocations)
|
|
130
|
+
* 3. live synced registry (`fetchAcpRegistry` → cache), by id or alias
|
|
131
|
+
* 4. legacy `ACP_AGENT_COMMANDS` map (last resort, kept for back-compat)
|
|
132
|
+
* Returns `null` for an id present in none of them.
|
|
133
|
+
*
|
|
134
|
+
* Why catalog BEFORE the live registry: our goal is to drive the user's
|
|
135
|
+
* already-installed, logged-in CLI. The catalog hand-curates the LOCAL-binary
|
|
136
|
+
* ACP entry for each popular agent (`gemini --acp`, `opencode acp`, …), which
|
|
137
|
+
* preserves the agent's own login and starts instantly. The official registry,
|
|
138
|
+
* by contrast, encodes "run a fresh copy" invocations — pinned `npx <pkg>@ver`
|
|
139
|
+
* downloads (no local login, slow first run) and platform binaries like
|
|
140
|
+
* `opencode.exe` that may not match a shim on PATH. So the registry is the
|
|
141
|
+
* source for the long tail of agents the catalog doesn't cover, NOT an
|
|
142
|
+
* override of the curated 12. Users force a specific command via the override.
|
|
143
|
+
*/
|
|
144
|
+
export declare function resolveAcpAgentCommand(id: string, overrides?: AcpAgentCommandOverrides, live?: AcpLiveCatalog): ACPSubagentRunnerOptions | null;
|
|
145
|
+
export { runOneAcpTask, type RunOneAcpTaskOptions, type RunOneAcpTaskResult, } from './run-one-acp-task.js';
|
|
146
|
+
export interface AcpProbeResult {
|
|
147
|
+
id: string;
|
|
148
|
+
ok: boolean;
|
|
149
|
+
ms: number;
|
|
150
|
+
agentInfo?: {
|
|
151
|
+
name: string;
|
|
152
|
+
title?: string | undefined;
|
|
153
|
+
version: string;
|
|
154
|
+
} | undefined;
|
|
155
|
+
error?: string | undefined;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Empirically test whether an agent actually speaks ACP on this machine:
|
|
159
|
+
* spawn it, run the `initialize` handshake, and close. `ok: true` means the
|
|
160
|
+
* agent answered `initialize` within `timeoutMs` (default 8s) — the truth,
|
|
161
|
+
* regardless of what the static catalog guesses. A bare CLI that drops into
|
|
162
|
+
* an interactive prompt fails here (init times out) instead of hanging a
|
|
163
|
+
* real turn.
|
|
164
|
+
*/
|
|
165
|
+
export declare function probeAcpAgent(idOrCmd: string | ACPSubagentRunnerOptions, opts?: {
|
|
166
|
+
timeoutMs?: number | undefined;
|
|
167
|
+
projectRoot?: string | undefined;
|
|
168
|
+
overrides?: AcpAgentCommandOverrides | undefined;
|
|
169
|
+
live?: AcpLiveCatalog | undefined;
|
|
170
|
+
}): Promise<AcpProbeResult>;
|
|
171
|
+
export interface ProbeAcpAgentsOptions {
|
|
172
|
+
agentIds: string[];
|
|
173
|
+
resolveCmd: (id: string) => ACPSubagentRunnerOptions | null;
|
|
174
|
+
projectRoot?: string | undefined;
|
|
175
|
+
/** Max agents probed at once. Default 4. Keeps concurrent first-run `npx`
|
|
176
|
+
* downloads from starving local agents' stdout past their timeout. */
|
|
177
|
+
concurrency?: number | undefined;
|
|
178
|
+
/** Per-agent handshake timeout for LOCAL binary commands. Default 20s. */
|
|
179
|
+
timeoutMs?: number | undefined;
|
|
180
|
+
/** Per-agent timeout for `npx`/`uvx` commands (first run downloads the
|
|
181
|
+
* package, which is slow). Default 90s. */
|
|
182
|
+
packageTimeoutMs?: number | undefined;
|
|
183
|
+
signal?: AbortSignal | undefined;
|
|
184
|
+
onProgress?: ((id: string, result: AcpProbeResult) => void) | undefined;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Probe many agents with BOUNDED concurrency. Unbounded `Promise.all` over the
|
|
188
|
+
* full set spawns every agent at once — and a few concurrent `npx` downloads
|
|
189
|
+
* peg the machine hard enough that even already-installed local agents miss
|
|
190
|
+
* their handshake window. Bounding the fan-out (and giving npx/uvx a longer
|
|
191
|
+
* timeout) is what makes a mixed install probe reliably.
|
|
192
|
+
*/
|
|
193
|
+
export declare function probeAcpAgents(opts: ProbeAcpAgentsOptions): Promise<AcpProbeResult[]>;
|
|
194
|
+
//# sourceMappingURL=acp-subagent-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acp-subagent-runner.d.ts","sourceRoot":"","sources":["../../src/integration/acp-subagent-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ensemble runner — fan a single task out to multiple ACP agents in parallel.
|
|
3
|
+
*
|
|
4
|
+
* This is the engine behind both:
|
|
5
|
+
* - `wstack acp parallel <csv> <task>` (CLI subcommand)
|
|
6
|
+
* - `/ensemble <csv> <task>` (TUI slash command)
|
|
7
|
+
*
|
|
8
|
+
* The CLI wraps `runEnsemble` with a plain-text renderer. The TUI can
|
|
9
|
+
* call it directly and format the result however it likes (text dump,
|
|
10
|
+
* per-agent tabbed panels, etc.).
|
|
11
|
+
*
|
|
12
|
+
* Design notes
|
|
13
|
+
* ────────────
|
|
14
|
+
* - Skipping is up-front. We probe the registry once, then run only
|
|
15
|
+
* the installed agents. This keeps the "no installed agents" path
|
|
16
|
+
* cheap (no spawn attempts) and the error message clear.
|
|
17
|
+
* - All agents run concurrently via `Promise.allSettled`. A single
|
|
18
|
+
* failed agent doesn't kill the others; the call returns once every
|
|
19
|
+
* agent has either completed or crashed.
|
|
20
|
+
* - Per-agent errors are captured as structured `{kind, message}`
|
|
21
|
+
* objects, not thrown. The aggregated result is one `EnsembleResult`
|
|
22
|
+
* with per-agent outcomes. Callers can render it as they please.
|
|
23
|
+
* - The `signal` option propagates as the parent AbortSignal for each
|
|
24
|
+
* `SubagentRunner`. Aborting cancels all in-flight agents.
|
|
25
|
+
* - Idempotent cleanup: each agent's `stop()` is called in a
|
|
26
|
+
* `finally`, so a throw in the body still tears the child down.
|
|
27
|
+
*/
|
|
28
|
+
import { EnsembleRegistry } from '../registry/ensemble-registry.js';
|
|
29
|
+
import { type ACPSubagentRunnerOptions } from './acp-subagent-runner.js';
|
|
30
|
+
import type { ACPProgressEvent } from '../client/acp-session.js';
|
|
31
|
+
/** Live per-agent progress callback for an ensemble run. */
|
|
32
|
+
export type EnsembleProgressHandler = (agentId: string, event: ACPProgressEvent) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Per-agent outcome from an ensemble run.
|
|
35
|
+
* `status === 'skipped'` carries a `reason`; the other statuses carry
|
|
36
|
+
* either a result or an error envelope.
|
|
37
|
+
*/
|
|
38
|
+
export interface EnsembleAgentResult {
|
|
39
|
+
agentId: string;
|
|
40
|
+
status: 'success' | 'failed' | 'skipped' | 'cancelled';
|
|
41
|
+
/** The agent's text result. Present for `status === 'success'`. */
|
|
42
|
+
result?: string | undefined;
|
|
43
|
+
/** Structured error. Present for `status === 'failed' | 'cancelled'`. */
|
|
44
|
+
error?: {
|
|
45
|
+
kind: string;
|
|
46
|
+
message: string;
|
|
47
|
+
} | undefined;
|
|
48
|
+
/** Why the agent was skipped (not installed, unknown id, etc.). */
|
|
49
|
+
reason?: string | undefined;
|
|
50
|
+
/** Wall-clock time spent on this agent. 0 for skipped. */
|
|
51
|
+
durationMs: number;
|
|
52
|
+
/** Agent-reported iteration count (1 per ACP turn). */
|
|
53
|
+
iterations: number;
|
|
54
|
+
/** Agent-reported tool call count (currently 0 for ACP). */
|
|
55
|
+
toolCalls: number;
|
|
56
|
+
}
|
|
57
|
+
/** Aggregate result of one ensemble run. */
|
|
58
|
+
export interface EnsembleResult {
|
|
59
|
+
/** The task that was dispatched. */
|
|
60
|
+
task: string;
|
|
61
|
+
/** Agent ids as the user provided them, after dedup. */
|
|
62
|
+
requested: string[];
|
|
63
|
+
/** Per-agent outcomes, in the order they were requested. */
|
|
64
|
+
results: EnsembleAgentResult[];
|
|
65
|
+
/** Roll-up of the per-agent statuses. */
|
|
66
|
+
summary: {
|
|
67
|
+
succeeded: number;
|
|
68
|
+
failed: number;
|
|
69
|
+
skipped: number;
|
|
70
|
+
cancelled: number;
|
|
71
|
+
};
|
|
72
|
+
/** Total wall-clock time of the run (longest agent). */
|
|
73
|
+
totalDurationMs: number;
|
|
74
|
+
}
|
|
75
|
+
/** Sync command resolver: id → command, or null if unknown. */
|
|
76
|
+
export type EnsembleCmdResolver = (id: string) => ACPSubagentRunnerOptions | null;
|
|
77
|
+
export interface EnsembleRunnerOptions {
|
|
78
|
+
/**
|
|
79
|
+
* Comma-separated agent ids. Whitespace, empty entries, and
|
|
80
|
+
* duplicates are filtered out. Order is preserved.
|
|
81
|
+
*/
|
|
82
|
+
agentIds: string;
|
|
83
|
+
/** The task description forwarded verbatim to each agent. */
|
|
84
|
+
task: string;
|
|
85
|
+
/**
|
|
86
|
+
* Per-agent hard timeout in ms. Defaults to 5 minutes; the
|
|
87
|
+
* `SubagentRunner` itself layers a turn-level timeout under this.
|
|
88
|
+
*/
|
|
89
|
+
timeoutMs?: number;
|
|
90
|
+
/**
|
|
91
|
+
* Override the registry used for the install probe. Defaults to
|
|
92
|
+
* `new EnsembleRegistry()`. Useful for tests.
|
|
93
|
+
*/
|
|
94
|
+
registry?: EnsembleRegistry;
|
|
95
|
+
/**
|
|
96
|
+
* Override the command resolver. Defaults to
|
|
97
|
+
* `defaultEnsembleCmdResolver` (legacy `ACP_AGENT_COMMANDS` map
|
|
98
|
+
* with catalog fallback via `findAgentDescriptor`). Useful for
|
|
99
|
+
* tests that don't want the real `makeACPSubagentRunnerWithStop`.
|
|
100
|
+
*/
|
|
101
|
+
resolveCmd?: EnsembleCmdResolver;
|
|
102
|
+
/**
|
|
103
|
+
* Cancellation signal. Aborting stops all in-flight agents via the
|
|
104
|
+
* `SubagentRunContext.signal` they receive.
|
|
105
|
+
*/
|
|
106
|
+
signal?: AbortSignal | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* Live progress callback. Invoked for every streamed update from every
|
|
109
|
+
* agent, tagged with the agent id so the caller can render interleaved
|
|
110
|
+
* progress (e.g. `[gemini-cli] edit foo.ts`).
|
|
111
|
+
*/
|
|
112
|
+
onProgress?: EnsembleProgressHandler | undefined;
|
|
113
|
+
/**
|
|
114
|
+
* Maximum number of agents to launch concurrently. Defaults to
|
|
115
|
+
* `DEFAULT_MAX_CONCURRENCY` (4). Set to 1 for serial execution;
|
|
116
|
+
* values larger than the runnable count are clamped down. Bounded
|
|
117
|
+
* fan-out keeps simultaneous ACP subprocess / WebSocket counts
|
|
118
|
+
* manageable when an ensemble has many members.
|
|
119
|
+
*/
|
|
120
|
+
maxConcurrency?: number | undefined;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Default command resolver — delegates to `resolveAcpAgentCommand`, so the
|
|
124
|
+
* catalog's corrected invocations win over the stale legacy map (the legacy
|
|
125
|
+
* map is now only a last-resort fallback). Returns `null` for unknown ids.
|
|
126
|
+
*/
|
|
127
|
+
export declare const defaultEnsembleCmdResolver: EnsembleCmdResolver;
|
|
128
|
+
/**
|
|
129
|
+
* Fan a task out to multiple ACP agents concurrently.
|
|
130
|
+
*
|
|
131
|
+
* Returns once every requested agent has either completed, failed, or
|
|
132
|
+
* been cancelled. Skipped agents (not installed, unknown id) are
|
|
133
|
+
* reported with `status: 'skipped'` and don't block the result.
|
|
134
|
+
*
|
|
135
|
+
* The function is a pure orchestrator — it does NOT render output. The
|
|
136
|
+
* caller decides how to format the `EnsembleResult`.
|
|
137
|
+
*/
|
|
138
|
+
export declare function runEnsemble(opts: EnsembleRunnerOptions): Promise<EnsembleResult>;
|
|
139
|
+
/**
|
|
140
|
+
* Render an `EnsembleResult` as a plain-text block. Useful as the
|
|
141
|
+
* default for the CLI; the TUI can call this or build a richer view.
|
|
142
|
+
*
|
|
143
|
+
* The format mirrors the output the `wstack acp parallel` subcommand
|
|
144
|
+
* emits, so existing scripts that parse the CLI's output keep working.
|
|
145
|
+
*/
|
|
146
|
+
export declare function renderEnsembleText(result: EnsembleResult): string;
|
|
147
|
+
//# sourceMappingURL=ensemble-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensemble-runner.d.ts","sourceRoot":"","sources":["../../src/integration/ensemble-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAE,gBAAgB,EAAsB,MAAM,kCAAkC,CAAC;AAExF,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,4DAA4D;AAC5D,MAAM,MAAM,uBAAuB,GAAG,CACpC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,gBAAgB,KACpB,IAAI,CAAC;AAEV;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;IACvD,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,yEAAyE;IACzE,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACtD,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,4CAA4C;AAC5C,MAAM,WAAW,cAAc;IAC7B,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,4DAA4D;IAC5D,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,yCAAyC;IACzC,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,wDAAwD;IACxD,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,+DAA+D;AAC/D,MAAM,MAAM,mBAAmB,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,wBAAwB,GAAG,IAAI,CAAC;AAElF,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC;;;;OAIG;IACH,UAAU,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC;IACjD;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAwCD;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,EAAE,mBACb,CAAC;AAkG7B;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC,CA2GtF;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAqCjE"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ACPProgressHandler } from '../client/acp-session.js';
|
|
2
|
+
import type { PermissionPolicy } from '../client/permission.js';
|
|
3
|
+
export interface RunOneAcpTaskOptions {
|
|
4
|
+
command: string;
|
|
5
|
+
args?: string[] | undefined;
|
|
6
|
+
env?: Record<string, string> | undefined;
|
|
7
|
+
/** Agent id / role label, surfaced in errors + the synthetic task id. */
|
|
8
|
+
role?: string | undefined;
|
|
9
|
+
/** The task description forwarded verbatim to the agent. */
|
|
10
|
+
task: string;
|
|
11
|
+
cwd?: string | undefined;
|
|
12
|
+
projectRoot?: string | undefined;
|
|
13
|
+
timeoutMs?: number | undefined;
|
|
14
|
+
signal?: AbortSignal | undefined;
|
|
15
|
+
onProgress?: ACPProgressHandler | undefined;
|
|
16
|
+
permissionPolicy?: PermissionPolicy | undefined;
|
|
17
|
+
}
|
|
18
|
+
export interface RunOneAcpTaskResult {
|
|
19
|
+
result: string;
|
|
20
|
+
iterations: number;
|
|
21
|
+
toolCalls: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Run a single task on one ACP agent and return its result. Spawns a fresh
|
|
25
|
+
* process, runs one prompt turn, and tears everything down. Throws a
|
|
26
|
+
* structured `SubagentError` on failure (spawn/init/prompt).
|
|
27
|
+
*/
|
|
28
|
+
export declare function runOneAcpTask(opts: RunOneAcpTaskOptions): Promise<RunOneAcpTaskResult>;
|
|
29
|
+
//# sourceMappingURL=run-one-acp-task.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-one-acp-task.d.ts","sourceRoot":"","sources":["../../src/integration/run-one-acp-task.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACzC,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC,UAAU,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAC5C,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;CACjD;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,mBAAmB,CAAC,CAyC9B"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Official ACP registry fetcher.
|
|
3
|
+
*
|
|
4
|
+
* The Agent Client Protocol maintains a canonical, hourly-updated registry of
|
|
5
|
+
* ACP-supporting agents at https://github.com/agentclientprotocol/registry,
|
|
6
|
+
* published as a single JSON document on a CDN. This module fetches that
|
|
7
|
+
* document and maps each entry to our `ACPAgentDescriptor` shape so the live
|
|
8
|
+
* list can supersede the bundled static `AGENTS_CATALOG` (which remains the
|
|
9
|
+
* offline fallback).
|
|
10
|
+
*
|
|
11
|
+
* Distribution → spawn-command mapping (per the registry FORMAT.md):
|
|
12
|
+
* - npx: { package, args } → `npx -y <package> <args>`
|
|
13
|
+
* - uvx: { package, args } → `uvx <package> <args>`
|
|
14
|
+
* - binary: { "<os>-<arch>": { cmd, args, env } }
|
|
15
|
+
* → `<basename(cmd)> <args>` for THIS host
|
|
16
|
+
*
|
|
17
|
+
* Binary entries reference a downloadable archive we do NOT fetch; we map the
|
|
18
|
+
* platform `cmd` to its basename so an already-installed on-PATH binary (the
|
|
19
|
+
* common case for goose/opencode/cursor) still launches. Agents distributed
|
|
20
|
+
* ONLY as a binary with no current-platform target are dropped (not runnable).
|
|
21
|
+
*
|
|
22
|
+
* Network is never required at runtime: this is invoked by an explicit
|
|
23
|
+
* `wstack acp sync` / `/acp sync`, the result is cached, and resolution falls
|
|
24
|
+
* back to the static catalog when no cache exists.
|
|
25
|
+
*/
|
|
26
|
+
import type { ACPAgentDescriptor } from './ensemble-registry.js';
|
|
27
|
+
/** Canonical CDN endpoint for the latest registry snapshot. */
|
|
28
|
+
export declare const ACP_REGISTRY_URL = "https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json";
|
|
29
|
+
/** One raw entry from the registry JSON (only the fields we consume). */
|
|
30
|
+
export interface RegistryAgentEntry {
|
|
31
|
+
id: string;
|
|
32
|
+
name?: string;
|
|
33
|
+
version?: string;
|
|
34
|
+
description?: string;
|
|
35
|
+
repository?: string;
|
|
36
|
+
website?: string;
|
|
37
|
+
authors?: string[];
|
|
38
|
+
distribution?: {
|
|
39
|
+
npx?: {
|
|
40
|
+
package: string;
|
|
41
|
+
args?: string[];
|
|
42
|
+
};
|
|
43
|
+
uvx?: {
|
|
44
|
+
package: string;
|
|
45
|
+
args?: string[];
|
|
46
|
+
};
|
|
47
|
+
binary?: Record<string, {
|
|
48
|
+
archive?: string;
|
|
49
|
+
cmd: string;
|
|
50
|
+
args?: string[];
|
|
51
|
+
env?: Record<string, string>;
|
|
52
|
+
}>;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export interface FetchAcpRegistryResult {
|
|
56
|
+
/** ISO timestamp the snapshot was fetched. */
|
|
57
|
+
fetchedAt: string;
|
|
58
|
+
/** Mapped, runnable descriptors (entries we could not map are dropped). */
|
|
59
|
+
agents: ACPAgentDescriptor[];
|
|
60
|
+
}
|
|
61
|
+
export interface FetchAcpRegistryOptions {
|
|
62
|
+
/** Override the endpoint (tests / mirrors). */
|
|
63
|
+
url?: string | undefined;
|
|
64
|
+
/** Abort the fetch from the caller. */
|
|
65
|
+
signal?: AbortSignal | undefined;
|
|
66
|
+
/** Hard timeout in ms (default 15s). Layered under any caller signal. */
|
|
67
|
+
timeoutMs?: number | undefined;
|
|
68
|
+
/** ISO timestamp to stamp the result with (tests pass a fixed value). */
|
|
69
|
+
now?: string | undefined;
|
|
70
|
+
/** Platform key for binary selection (tests). Defaults to this host. */
|
|
71
|
+
platformKey?: string | undefined;
|
|
72
|
+
}
|
|
73
|
+
/** Map Node's platform/arch to the registry's `<os>-<arch>` key form. */
|
|
74
|
+
export declare function currentPlatformKey(): string;
|
|
75
|
+
/**
|
|
76
|
+
* Map one registry entry to an `ACPAgentDescriptor`, or `null` if it carries
|
|
77
|
+
* no distribution runnable on this host. Pure — no I/O.
|
|
78
|
+
*/
|
|
79
|
+
export declare function mapRegistryEntry(entry: RegistryAgentEntry, platformKey?: string): ACPAgentDescriptor | null;
|
|
80
|
+
/**
|
|
81
|
+
* Fetch the live registry and return mapped descriptors. Throws on network /
|
|
82
|
+
* parse failure so the caller (`wstack acp sync`) can surface it; callers that
|
|
83
|
+
* want graceful degradation use the cached/static fallback instead.
|
|
84
|
+
*/
|
|
85
|
+
export declare function fetchAcpRegistry(opts?: FetchAcpRegistryOptions): Promise<FetchAcpRegistryResult>;
|
|
86
|
+
//# sourceMappingURL=acp-registry-fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acp-registry-fetch.d.ts","sourceRoot":"","sources":["../../src/registry/acp-registry-fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,EACV,kBAAkB,EAEnB,MAAM,wBAAwB,CAAC;AAEhC,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,yEAC2C,CAAC;AAEzE,yEAAyE;AACzE,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE;QACb,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QAC3C,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QAC3C,MAAM,CAAC,EAAE,MAAM,CACb,MAAM,EACN;YAAE,OAAO,CAAC,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;SAAE,CACjF,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,sBAAsB;IACrC,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,uCAAuC;IACvC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,yEAAyE;AACzE,wBAAgB,kBAAkB,IAAI,MAAM,CAS3C;AASD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,kBAAkB,EACzB,WAAW,GAAE,MAA6B,GACzC,kBAAkB,GAAG,IAAI,CAmC3B;AAWD;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,GAAE,uBAA4B,GACjC,OAAO,CAAC,sBAAsB,CAAC,CA+BjC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static catalog of ACP-supporting agents known to WrongStack.
|
|
3
|
+
*
|
|
4
|
+
* Scope: CLI-spawnable agents only (i.e. agents that can be run as a
|
|
5
|
+
* subprocess with stdio JSON-RPC, per the ACP v1 spec's local-transport
|
|
6
|
+
* model). IDE-only or SaaS-only entries from
|
|
7
|
+
* https://agentclientprotocol.com/get-started/agents are deliberately
|
|
8
|
+
* omitted — they can't be driven by a SubagentRunner.
|
|
9
|
+
*
|
|
10
|
+
* Maintenance
|
|
11
|
+
* ───────────
|
|
12
|
+
* This is the OFFLINE FALLBACK catalog. The official, hourly-updated registry
|
|
13
|
+
* now lives at https://github.com/agentclientprotocol/registry (CDN snapshot
|
|
14
|
+
* in `acp-registry-fetch.ts`). `wstack acp sync` / `/acp sync` fetch it into a
|
|
15
|
+
* local cache that supersedes this file at resolution time — so this catalog
|
|
16
|
+
* only needs to carry the most-used agents with invocations that work without
|
|
17
|
+
* a network round-trip. Entries here are kept aligned to the registry's
|
|
18
|
+
* authoritative ACP-entry commands; run `/acp probe` to confirm on a host.
|
|
19
|
+
*
|
|
20
|
+
* Each entry tags its `integration` mechanism:
|
|
21
|
+
* - `native` — the agent ships with a documented ACP entry flag.
|
|
22
|
+
* - `adapter` — runs through Zed's SDK adapter or similar wrapper.
|
|
23
|
+
* - `community` — community-maintained wrapper (e.g. `@agentify/cline`,
|
|
24
|
+
* `bub-acp-server`, `pi-acp`).
|
|
25
|
+
* - `experimental` — listed by ACP but no public ACP entry yet;
|
|
26
|
+
* entry may not work.
|
|
27
|
+
*
|
|
28
|
+
* When the maintainer verifies an entry works, flip `integration` from
|
|
29
|
+
* `experimental` to `native`/`adapter`/`community` and remove the warning.
|
|
30
|
+
*
|
|
31
|
+
* Detection
|
|
32
|
+
* ─────────
|
|
33
|
+
* The `EnsembleRegistry` (sibling module) probes each entry's `probe`
|
|
34
|
+
* argv in parallel via `Promise.allSettled`. A probe that exits 0 with
|
|
35
|
+
* a non-empty stdout line is considered installed. Probes that time out
|
|
36
|
+
* or print nothing are treated as not-installed.
|
|
37
|
+
*/
|
|
38
|
+
import type { ACPAgentDescriptor } from './ensemble-registry.js';
|
|
39
|
+
/**
|
|
40
|
+
* The catalog. Order is significant for the TUI render — most-requested
|
|
41
|
+
* agents go first. Edit by re-ordering, not by alphabetising.
|
|
42
|
+
*/
|
|
43
|
+
export declare const AGENTS_CATALOG: readonly ACPAgentDescriptor[];
|
|
44
|
+
/** O(1) lookup by id. Returns `undefined` for unknown ids. */
|
|
45
|
+
export declare function findAgentDescriptor(id: string): ACPAgentDescriptor | undefined;
|
|
46
|
+
//# sourceMappingURL=agents.catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.catalog.d.ts","sourceRoot":"","sources":["../../src/registry/agents.catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,kBAAkB,EAqN9C,CAAC;AAEX,8DAA8D;AAC9D,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,MAAM,GACT,kBAAkB,GAAG,SAAS,CAEhC"}
|