@agentrq/acp-gateway 0.2.3 → 0.2.4

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/README.md CHANGED
@@ -42,7 +42,7 @@ npm install -g @agentrq/acp-gateway
42
42
 
43
43
  ## Current Version
44
44
 
45
- `0.2.3`
45
+ `0.2.4`
46
46
 
47
47
  ## Usage
48
48
 
@@ -66,12 +66,99 @@ acp-gateway -- your-acp-agent --flag1 --flag2
66
66
  You can specify gateway options before the `--` separator:
67
67
 
68
68
  - `--max-concurrency` / `--maxConcurrency` `<number>`: Sets the maximum number of concurrent tasks allowed to prompt the ACP agent at once. Defaults to `2`.
69
+ - `--agent <registry-id>`: Runs an agent from the ACP registry instead of a command you supply yourself.
70
+ - `--list-agents`: Prints every agent in the registry and how each one can run on this machine, then exits.
71
+ - `--allow-unverified-agent`: Installs a registry binary that publishes no checksum. Off by default.
72
+ - `--registry-url <url>`: Reads a different registry index (for pinning, or for testing).
73
+ - `--auth-method <id>`: The authentication method to use when the agent asks for a login. Defaults to picking one automatically.
74
+ - `--help` / `-h`: Explains every option, with examples. Also shown when `acp-gateway` is run with nothing to do.
75
+ - `--list-auth-methods`: Prints the login methods the agent advertises, then exits.
76
+ - `--login [method-id]`: Logs in to the agent, then exits.
77
+ - `--logout`: Ends the agent's authenticated state, then exits (only for agents that support logout).
69
78
 
70
79
  Example:
71
80
  ```bash
72
81
  acp-gateway --max-concurrency 4 -- gemini --acp
73
82
  ```
74
83
 
84
+ ### Running an Agent from the Registry
85
+
86
+ The [ACP registry](https://github.com/agentclientprotocol/registry) lists agents that implement the
87
+ protocol, and `acp-gateway` can run one by name — no installing or wiring up by hand:
88
+
89
+ ```bash
90
+ acp-gateway --list-agents # see what's published
91
+ acp-gateway --agent gemini # run one
92
+ ```
93
+
94
+ Registry entries are distributed in three ways, and the gateway prefers them in this order:
95
+
96
+ | Distribution | How it runs | Downloads anything? |
97
+ |---|---|---|
98
+ | `npx` | `npx -y <package> <args>` | No — npm fetches and verifies the package |
99
+ | `uvx` | `uvx <package> <args>` | No — uv fetches and verifies the package |
100
+ | `binary` | Archive is downloaded, checked, unpacked and cached | Yes |
101
+
102
+ Package distributions come first because npm and PyPI verify what they serve. A binary is only used
103
+ when it is the agent's only distribution.
104
+
105
+ **Binaries are verified before they run.** The registry's `sha256` for the archive is optional, and
106
+ roughly half of the published binary targets omit it. Where there is no checksum the gateway refuses
107
+ to install rather than run something it cannot vouch for:
108
+
109
+ ```
110
+ The ACP registry publishes no sha256 for "antigravity-acp" on this platform, so the download
111
+ cannot be verified. Re-run with --allow-unverified-agent to install it anyway, or install the
112
+ agent yourself and pass it after --.
113
+ ```
114
+
115
+ Downloads are cached per agent, version and platform, so each build is fetched once:
116
+
117
+ | Platform | Cache location |
118
+ |---|---|
119
+ | macOS / Linux | `$XDG_CACHE_HOME/acp-gateway/agents`, else `~/.cache/acp-gateway/agents` |
120
+ | Windows | `%LOCALAPPDATA%\acp-gateway\agents` |
121
+
122
+ All six platforms the registry publishes for are supported — macOS, Linux and Windows on both x86_64
123
+ and arm64. Archives are unpacked with the system's own `tar` (and `unzip` for zips on Linux, whose
124
+ `tar` cannot read them), so no archive libraries are added as dependencies.
125
+
126
+ ### Authentication
127
+
128
+ Agents that require a login advertise their login methods during the ACP handshake, and refuse to open a
129
+ session until one has been used. `acp-gateway` handles that the same way an editor such as Zed does.
130
+
131
+ List what an agent offers:
132
+
133
+ ```bash
134
+ acp-gateway --list-auth-methods -- gemini --acp
135
+ ```
136
+
137
+ Log in ahead of time — with no method id, you are asked to pick one:
138
+
139
+ ```bash
140
+ acp-gateway --login -- gemini --acp
141
+ acp-gateway --login oauth-personal -- gemini --acp # or name the method directly
142
+ ```
143
+
144
+ Log out again:
145
+
146
+ ```bash
147
+ acp-gateway --logout -- gemini --acp
148
+ ```
149
+
150
+ Nothing has to be done up front, though: if an agent refuses the first session because it needs a login,
151
+ `acp-gateway` logs in and retries by itself.
152
+
153
+ There are two kinds of method:
154
+
155
+ - **Agent** methods — the agent runs the login itself (a browser flow, an API key it already holds). These
156
+ need nobody present, so they are chosen first and work in an unattended gateway.
157
+ - **Terminal** methods — the agent's own binary is re-run interactively so you can log in at a TUI.
158
+ `acp-gateway` only offers to run these when it has a real terminal to hand over.
159
+
160
+ Credentials are never stored by the gateway; the agent keeps its own, exactly as it does under an editor.
161
+
75
162
  ### Configuration
76
163
 
77
164
  `acp-gateway` searches for `.mcp.json` starting in the current working directory and up to 3 parent directories.
@@ -134,6 +221,9 @@ Example `.mcp.json`:
134
221
  | `src/acpClient.ts` | Implements the ACP `Client` interface — routes permission requests, handles session updates, and provides file operations. |
135
222
  | `src/mcpClient.ts` | `EventEmitter`-based MCP client with auto-reconnection, notification handling, and tool call dispatch. |
136
223
  | `src/config.ts` | Parses `.mcp.json` from the current directory tree up to 3 levels deep. |
224
+ | `src/auth.ts` | ACP authentication — lists the agent's login methods, detects `auth_required`, and runs agent or terminal logins. |
225
+ | `src/registry.ts` | Reads the ACP registry index — agent lookup, host platform matching, and package launch commands. |
226
+ | `src/agentInstall.ts` | Downloads, verifies, unpacks and caches a registry agent's binary distribution. |
137
227
 
138
228
  ## Development
139
229
 
@@ -156,9 +246,12 @@ npm test
156
246
  acp-gateway/
157
247
  ├── src/
158
248
  │ ├── acpClient.ts # ACP Client implementation
249
+ │ ├── agentInstall.ts # Registry binary download / verify / cache
250
+ │ ├── auth.ts # ACP authentication (login / logout)
159
251
  │ ├── config.ts # .mcp.json loader
160
252
  │ ├── index.ts # Entry point & orchestrator
161
253
  │ ├── mcpClient.ts # MCP Bridge with auto-reconnect
254
+ │ ├── registry.ts # ACP registry index client
162
255
  │ └── __tests__/ # Unit tests
163
256
  ├── package.json
164
257
  └── tsconfig.json
@@ -169,6 +262,8 @@ acp-gateway/
169
262
  - **Auto-reconnection**: The MCP transport auto-reconnects on disconnection with exponential backoff (1s → 30s max).
170
263
  - **Notification-driven tasks**: The MCP server pushes task content via `notifications/claude/channel`; `acp-gateway` reacts immediately.
171
264
  - **Permission flow**: ACP agent requests permission → `acp-gateway` forwards to MCP server → waits for verdict → resolves the ACP permission.
265
+ - **Registry agents**: `--agent <id>` resolves through the registry index; package distributions are preferred over binaries, and a binary without a published `sha256` is refused unless explicitly allowed.
266
+ - **Authentication**: Login methods come from the `initialize` handshake; an `auth_required` refusal triggers a login and one retry of `newSession`.
172
267
  - **File I/O**: `readTextFile` / `writeTextFile` are proxied directly to the filesystem; paths are resolved relative to `process.cwd()`.
173
268
 
174
269
  ## Contributing
@@ -0,0 +1,342 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { execFileSync } from "node:child_process";
3
+ import { mkdtemp, readFile, rm, stat, writeFile } from "node:fs/promises";
4
+ import { existsSync } from "node:fs";
5
+ import { tmpdir } from "node:os";
6
+ import * as path from "node:path";
7
+ import { archiveKind, assertChecksum, assertVerifiable, defaultCacheDir, downloadArchive, extractArchive, installBinaryAgent, installDir, moveInto, resolveAgentLaunch, runExtractionTool, resolveExecutable, sha256, } from "../agentInstall.js";
8
+ const agent = {
9
+ id: "demo-acp",
10
+ name: "Demo Agent",
11
+ version: "1.2.3",
12
+ description: "A demo agent",
13
+ distribution: {},
14
+ };
15
+ /** Builds a real .tar.gz containing an executable, so extraction is exercised for real. */
16
+ async function makeTarball(cmdName, contents) {
17
+ const staging = await mkdtemp(path.join(tmpdir(), "acp-gateway-fixture-"));
18
+ try {
19
+ await writeFile(path.join(staging, cmdName), contents);
20
+ const archive = path.join(staging, "out.tar.gz");
21
+ execFileSync("tar", ["-czf", archive, "-C", staging, cmdName]);
22
+ return new Uint8Array(await readFile(archive));
23
+ }
24
+ finally {
25
+ await rm(staging, { recursive: true, force: true });
26
+ }
27
+ }
28
+ function okResponse(data) {
29
+ return {
30
+ ok: true,
31
+ status: 200,
32
+ statusText: "OK",
33
+ arrayBuffer: async () => data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength),
34
+ };
35
+ }
36
+ describe("agentInstall", () => {
37
+ let cacheDir;
38
+ let errorSpy;
39
+ beforeEach(async () => {
40
+ cacheDir = await mkdtemp(path.join(tmpdir(), "acp-gateway-cache-"));
41
+ errorSpy = vi.spyOn(console, "error").mockImplementation(() => { });
42
+ });
43
+ afterEach(async () => {
44
+ errorSpy.mockRestore();
45
+ await rm(cacheDir, { recursive: true, force: true });
46
+ });
47
+ describe("defaultCacheDir", () => {
48
+ it("uses XDG_CACHE_HOME where it is set", () => {
49
+ expect(defaultCacheDir("linux", { XDG_CACHE_HOME: "/xdg" })).toBe(path.join("/xdg", "acp-gateway", "agents"));
50
+ });
51
+ it("falls back to the per-user cache on macOS and Linux", () => {
52
+ expect(defaultCacheDir("darwin", {})).toMatch(/\.cache[\\/]acp-gateway[\\/]agents$/);
53
+ });
54
+ it("uses LOCALAPPDATA on Windows", () => {
55
+ expect(defaultCacheDir("win32", { LOCALAPPDATA: "C:\\Users\\me\\AppData\\Local" })).toBe(path.join("C:\\Users\\me\\AppData\\Local", "acp-gateway", "agents"));
56
+ expect(defaultCacheDir("win32", {})).toMatch(/AppData[\\/]Local[\\/]acp-gateway/);
57
+ });
58
+ });
59
+ describe("archiveKind", () => {
60
+ it("recognises every format the registry allows", () => {
61
+ expect(archiveKind("https://x/y.zip")).toBe("zip");
62
+ expect(archiveKind("https://x/y.tar.gz")).toBe("tar.gz");
63
+ expect(archiveKind("https://x/y.tgz")).toBe("tar.gz");
64
+ expect(archiveKind("https://x/y.tar.bz2")).toBe("tar.bz2");
65
+ expect(archiveKind("https://x/y.tbz2")).toBe("tar.bz2");
66
+ });
67
+ it("ignores query strings and fragments", () => {
68
+ expect(archiveKind("https://x/y.ZIP?token=abc#frag")).toBe("zip");
69
+ });
70
+ it("treats anything else as a raw executable", () => {
71
+ expect(archiveKind("https://x/agent-darwin-arm64")).toBe("raw");
72
+ });
73
+ });
74
+ describe("installDir", () => {
75
+ it("keeps each version and platform apart", () => {
76
+ expect(installDir("/cache", "demo", "darwin-aarch64", "1.2.3")).toBe(path.join("/cache", "demo@1.2.3", "darwin-aarch64"));
77
+ });
78
+ });
79
+ describe("resolveExecutable", () => {
80
+ it("resolves the registry's cmd inside the install directory", () => {
81
+ expect(resolveExecutable("/cache/demo", "./bin/agent")).toBe(path.resolve("/cache/demo/bin/agent"));
82
+ });
83
+ it("refuses a cmd that climbs out of the install directory", () => {
84
+ expect(() => resolveExecutable("/cache/demo", "../../../usr/bin/curl")).toThrow(/points outside its install directory/);
85
+ });
86
+ });
87
+ describe("assertVerifiable", () => {
88
+ const unverifiable = { archive: "https://x/y.zip", cmd: "./demo" };
89
+ it("refuses an archive the registry publishes no checksum for", () => {
90
+ expect(() => assertVerifiable(agent, unverifiable, false)).toThrow(/publishes no sha256 for "demo-acp".*--allow-unverified-agent/s);
91
+ });
92
+ it("allows it once the user has explicitly opted in", () => {
93
+ expect(() => assertVerifiable(agent, unverifiable, true)).not.toThrow();
94
+ });
95
+ it("allows an archive that does publish a checksum", () => {
96
+ expect(() => assertVerifiable(agent, { ...unverifiable, sha256: "a".repeat(64) }, false)).not.toThrow();
97
+ });
98
+ });
99
+ describe("assertChecksum", () => {
100
+ const data = new Uint8Array([1, 2, 3]);
101
+ it("accepts a download that matches, whatever the case", () => {
102
+ const digest = sha256(data);
103
+ expect(() => assertChecksum(agent, { archive: "https://x/y", cmd: "./d", sha256: digest.toUpperCase() }, data)).not.toThrow();
104
+ });
105
+ it("refuses a download that does not match", () => {
106
+ expect(() => assertChecksum(agent, { archive: "https://x/y", cmd: "./d", sha256: "b".repeat(64) }, data)).toThrow(/Checksum mismatch for "demo-acp"/);
107
+ });
108
+ it("has nothing to check when the registry publishes no checksum", () => {
109
+ expect(() => assertChecksum(agent, { archive: "https://x/y", cmd: "./d" }, data)).not.toThrow();
110
+ });
111
+ });
112
+ describe("downloadArchive", () => {
113
+ it("returns the bytes", async () => {
114
+ const data = new Uint8Array([9, 8, 7]);
115
+ const fetchImpl = vi.fn().mockResolvedValue(okResponse(data));
116
+ expect(await downloadArchive("https://x/y.zip", fetchImpl)).toEqual(data);
117
+ });
118
+ it("reports a failed download", async () => {
119
+ const fetchImpl = vi
120
+ .fn()
121
+ .mockResolvedValue({ ok: false, status: 403, statusText: "Forbidden" });
122
+ await expect(downloadArchive("https://x/y.zip", fetchImpl)).rejects.toThrow(/Failed to download https:\/\/x\/y.zip: 403 Forbidden/);
123
+ });
124
+ });
125
+ describe("extractArchive", () => {
126
+ it("writes a raw download straight out as the executable", async () => {
127
+ const dir = path.join(cacheDir, "raw");
128
+ await extractArchive(new Uint8Array([1, 2]), "raw", dir, "./demo-agent");
129
+ expect(await readFile(path.join(dir, "demo-agent"))).toEqual(Buffer.from([1, 2]));
130
+ });
131
+ it("unpacks a real tarball and removes the archive afterwards", async () => {
132
+ const tarball = await makeTarball("demo", "#!/bin/sh\necho hi\n");
133
+ const dir = path.join(cacheDir, "tar");
134
+ await extractArchive(tarball, "tar.gz", dir, "./demo");
135
+ expect(await readFile(path.join(dir, "demo"), "utf8")).toContain("echo hi");
136
+ expect(existsSync(path.join(dir, "archive.tar.gz"))).toBe(false);
137
+ });
138
+ it("uses unzip for zips on Linux, where tar cannot read them", async () => {
139
+ const dir = path.join(cacheDir, "zip");
140
+ // `unzip` is not guaranteed on every machine, so assert on the failure
141
+ // message rather than on a successful extraction.
142
+ await expect(extractArchive(new Uint8Array([1]), "zip", dir, "./demo", "linux")).rejects.toThrow(/unzip/);
143
+ });
144
+ it("reports an extraction tool that is not installed", async () => {
145
+ await expect(runExtractionTool("acp-gateway-no-such-tool", [], cacheDir)).rejects.toThrow(/Could not run "acp-gateway-no-such-tool" to unpack the agent archive/);
146
+ });
147
+ it("reports a corrupt archive with the tool's own diagnostics", async () => {
148
+ const dir = path.join(cacheDir, "bad");
149
+ await expect(extractArchive(new Uint8Array([1, 2, 3]), "tar.gz", dir, "./demo", "darwin")).rejects.toThrow(/failed to unpack the agent archive/);
150
+ });
151
+ });
152
+ describe("moveInto", () => {
153
+ it("copies when the staged install cannot simply be renamed into place", async () => {
154
+ const from = await mkdtemp(path.join(tmpdir(), "acp-gateway-move-"));
155
+ await writeFile(path.join(from, "demo"), "binary");
156
+ // A destination whose parents do not exist: rename() fails, and the copy
157
+ // fallback — the same path taken when the temp dir is another mount —
158
+ // has to create the tree.
159
+ const to = path.join(cacheDir, "deep", "deeper", "install");
160
+ await moveInto(from, to);
161
+ expect(await readFile(path.join(to, "demo"), "utf8")).toBe("binary");
162
+ await rm(from, { recursive: true, force: true });
163
+ });
164
+ });
165
+ describe("installBinaryAgent", () => {
166
+ async function install(overrides = {}) {
167
+ const tarball = await makeTarball("demo", "#!/bin/sh\nexit 0\n");
168
+ const target = {
169
+ archive: "https://example.com/demo.tar.gz",
170
+ sha256: sha256(tarball),
171
+ cmd: "./demo",
172
+ args: ["--acp"],
173
+ ...overrides.target,
174
+ };
175
+ const fetchImpl = vi.fn().mockResolvedValue(okResponse(tarball));
176
+ const spec = await installBinaryAgent({
177
+ agent,
178
+ target,
179
+ platformTarget: "darwin-aarch64",
180
+ cacheDir,
181
+ fetchImpl: fetchImpl,
182
+ platform: "darwin",
183
+ ...overrides.options,
184
+ });
185
+ return { spec, fetchImpl, tarball };
186
+ }
187
+ it("downloads, verifies, unpacks and makes the agent executable", async () => {
188
+ const { spec } = await install();
189
+ expect(spec).toEqual({
190
+ command: path.join(cacheDir, "demo-acp@1.2.3", "darwin-aarch64", "demo"),
191
+ args: ["--acp"],
192
+ env: undefined,
193
+ kind: "binary",
194
+ });
195
+ expect(existsSync(spec.command)).toBe(true);
196
+ // 0o111 — executable by someone.
197
+ expect((await stat(spec.command)).mode & 0o111).toBeGreaterThan(0);
198
+ });
199
+ it("skips the executable bit on Windows, which has none", async () => {
200
+ const { spec } = await install({ options: { platform: "win32" } });
201
+ expect(existsSync(spec.command)).toBe(true);
202
+ });
203
+ it("reuses a cached install instead of downloading again", async () => {
204
+ await install();
205
+ const { fetchImpl } = await install();
206
+ expect(fetchImpl).not.toHaveBeenCalled();
207
+ expect(errorSpy.mock.calls.flat().join("\n")).toContain("Using cached demo-acp 1.2.3");
208
+ });
209
+ it("refuses an archive with no published checksum", async () => {
210
+ await expect(install({ target: { sha256: undefined } })).rejects.toThrow(/publishes no sha256/);
211
+ });
212
+ it("installs an unverified archive when explicitly allowed, and says so", async () => {
213
+ const { spec } = await install({
214
+ target: { sha256: undefined },
215
+ options: { allowUnverified: true },
216
+ });
217
+ expect(existsSync(spec.command)).toBe(true);
218
+ expect(errorSpy.mock.calls.flat().join("\n")).toContain("publishes no checksum");
219
+ });
220
+ it("refuses a download that does not match the checksum", async () => {
221
+ await expect(install({ target: { sha256: "c".repeat(64) } })).rejects.toThrow(/Checksum mismatch/);
222
+ });
223
+ it("leaves nothing cached when the archive lacks the promised command", async () => {
224
+ await expect(install({ target: { cmd: "./not-in-archive" } })).rejects.toThrow(/does not contain "\.\/not-in-archive"/);
225
+ expect(existsSync(installDir(cacheDir, agent.id, "darwin-aarch64", agent.version))).toBe(false);
226
+ });
227
+ });
228
+ describe("resolveAgentLaunch", () => {
229
+ const gemini = {
230
+ id: "gemini",
231
+ name: "Gemini CLI",
232
+ version: "0.58.0",
233
+ description: "Google's CLI",
234
+ distribution: { npx: { package: "@google/gemini-cli@0.58.0", args: ["--acp"] } },
235
+ };
236
+ const pyAgent = {
237
+ id: "fast-agent",
238
+ name: "fast-agent",
239
+ version: "1.0.0",
240
+ description: "A Python agent",
241
+ distribution: { uvx: { package: "fast-agent-mcp" } },
242
+ };
243
+ const binaryOnly = {
244
+ ...agent,
245
+ distribution: {
246
+ binary: {
247
+ "linux-x86_64": { archive: "https://x/y.tar.gz", sha256: "a".repeat(64), cmd: "./demo" },
248
+ },
249
+ },
250
+ };
251
+ const registry = {
252
+ version: "1.0.0",
253
+ agents: [gemini, pyAgent, binaryOnly],
254
+ };
255
+ it("runs npm-distributed agents through npx without downloading anything", async () => {
256
+ const fetchImpl = vi.fn();
257
+ const spec = await resolveAgentLaunch({
258
+ id: "gemini",
259
+ registry,
260
+ platformTarget: "darwin-aarch64",
261
+ fetchImpl: fetchImpl,
262
+ });
263
+ expect(spec).toEqual({
264
+ command: "npx",
265
+ args: ["-y", "@google/gemini-cli@0.58.0", "--acp"],
266
+ env: undefined,
267
+ kind: "npx",
268
+ });
269
+ expect(fetchImpl).not.toHaveBeenCalled();
270
+ });
271
+ it("names npx explicitly on Windows, where a bare npx cannot be spawned", async () => {
272
+ const spec = await resolveAgentLaunch({
273
+ id: "gemini",
274
+ registry,
275
+ platformTarget: "windows-x86_64",
276
+ platform: "win32",
277
+ });
278
+ expect(spec.command).toBe("npx.cmd");
279
+ });
280
+ it("runs PyPI-distributed agents through uvx", async () => {
281
+ const spec = await resolveAgentLaunch({
282
+ id: "fast-agent",
283
+ registry,
284
+ platformTarget: "linux-x86_64",
285
+ });
286
+ expect(spec).toEqual({
287
+ command: "uvx",
288
+ args: ["fast-agent-mcp"],
289
+ env: undefined,
290
+ kind: "uvx",
291
+ });
292
+ });
293
+ it("installs the binary when that is the only distribution", async () => {
294
+ const tarball = await makeTarball("demo", "#!/bin/sh\nexit 0\n");
295
+ const registryWithDigest = {
296
+ version: "1.0.0",
297
+ agents: [
298
+ {
299
+ ...binaryOnly,
300
+ distribution: {
301
+ binary: {
302
+ "linux-x86_64": {
303
+ archive: "https://x/y.tar.gz",
304
+ sha256: sha256(tarball),
305
+ cmd: "./demo",
306
+ },
307
+ },
308
+ },
309
+ },
310
+ ],
311
+ };
312
+ const fetchImpl = vi.fn().mockResolvedValue(okResponse(tarball));
313
+ const spec = await resolveAgentLaunch({
314
+ id: "demo-acp",
315
+ registry: registryWithDigest,
316
+ platformTarget: "linux-x86_64",
317
+ cacheDir,
318
+ fetchImpl: fetchImpl,
319
+ platform: "linux",
320
+ });
321
+ expect(spec.kind).toBe("binary");
322
+ expect(existsSync(spec.command)).toBe(true);
323
+ });
324
+ it("reports an id the registry does not list", async () => {
325
+ await expect(resolveAgentLaunch({ id: "nope", registry, platformTarget: "linux-x86_64" })).rejects.toThrow(/No agent "nope" in the ACP registry/);
326
+ });
327
+ it("reports an agent that has no build for this machine", async () => {
328
+ await expect(resolveAgentLaunch({ id: "demo-acp", registry, platformTarget: "windows-aarch64" })).rejects.toThrow(/publishes no build of "demo-acp" for windows-aarch64 \(it publishes: binary\)/);
329
+ });
330
+ it("says so when an agent publishes no distribution at all", async () => {
331
+ const empty = {
332
+ version: "1.0.0",
333
+ agents: [{ ...agent, distribution: {} }],
334
+ };
335
+ await expect(resolveAgentLaunch({ id: "demo-acp", registry: empty, platformTarget: "linux-x86_64" })).rejects.toThrow(/it publishes: nothing/);
336
+ });
337
+ it("reports an unsupported platform by name", async () => {
338
+ await expect(resolveAgentLaunch({ id: "demo-acp", registry, platformTarget: undefined })).rejects.toThrow(/publishes no build of "demo-acp" for/);
339
+ });
340
+ });
341
+ });
342
+ //# sourceMappingURL=agentInstall.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentInstall.test.js","sourceRoot":"","sources":["../../src/__tests__/agentInstall.test.ts"],"names":[],"mappings":"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"}