@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 +96 -1
- package/dist/__tests__/agentInstall.test.js +342 -0
- package/dist/__tests__/agentInstall.test.js.map +1 -0
- package/dist/__tests__/auth.test.js +283 -0
- package/dist/__tests__/auth.test.js.map +1 -0
- package/dist/__tests__/index.test.js +401 -8
- package/dist/__tests__/index.test.js.map +1 -1
- package/dist/__tests__/registry.test.js +175 -0
- package/dist/__tests__/registry.test.js.map +1 -0
- package/dist/agentInstall.js +241 -0
- package/dist/agentInstall.js.map +1 -0
- package/dist/auth.js +189 -0
- package/dist/auth.js.map +1 -0
- package/dist/index.js +375 -32
- package/dist/index.js.map +1 -1
- package/dist/mcpClient.js +1 -1
- package/dist/registry.js +118 -0
- package/dist/registry.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from "vitest";
|
|
2
|
+
import { DEFAULT_REGISTRY_URL, availableKinds, describeAgents, fetchRegistry, findAgent, hostPlatformTarget, packageLaunchSpec, selectBinaryTarget, } from "../registry.js";
|
|
3
|
+
const gemini = {
|
|
4
|
+
id: "gemini",
|
|
5
|
+
name: "Gemini CLI",
|
|
6
|
+
version: "0.58.0",
|
|
7
|
+
description: "Google's official CLI for Gemini",
|
|
8
|
+
distribution: {
|
|
9
|
+
npx: { package: "@google/gemini-cli@0.58.0", args: ["--acp"] },
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
const antigravity = {
|
|
13
|
+
id: "antigravity-acp",
|
|
14
|
+
name: "Google Antigravity",
|
|
15
|
+
version: "1.0.0",
|
|
16
|
+
description: "Google's AI coding agent",
|
|
17
|
+
distribution: {
|
|
18
|
+
binary: {
|
|
19
|
+
"darwin-aarch64": {
|
|
20
|
+
archive: "https://dl.google.com/agy/darwin-arm64.zip",
|
|
21
|
+
cmd: "./agy_acp_server.par",
|
|
22
|
+
},
|
|
23
|
+
"linux-x86_64": {
|
|
24
|
+
archive: "https://dl.google.com/agy/linux-x86_64.zip",
|
|
25
|
+
sha256: "a".repeat(64),
|
|
26
|
+
cmd: "./agy_acp_server.par",
|
|
27
|
+
args: ["--uid="],
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
const fastAgent = {
|
|
33
|
+
id: "fast-agent",
|
|
34
|
+
name: "fast-agent",
|
|
35
|
+
version: "1.0.0",
|
|
36
|
+
description: "A Python agent",
|
|
37
|
+
distribution: { uvx: { package: "fast-agent-mcp", args: ["serve"] } },
|
|
38
|
+
};
|
|
39
|
+
const registry = {
|
|
40
|
+
version: "1.0.0",
|
|
41
|
+
agents: [gemini, antigravity, fastAgent],
|
|
42
|
+
};
|
|
43
|
+
function jsonResponse(body, init = {}) {
|
|
44
|
+
return {
|
|
45
|
+
ok: true,
|
|
46
|
+
status: 200,
|
|
47
|
+
statusText: "OK",
|
|
48
|
+
json: async () => body,
|
|
49
|
+
...init,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
describe("registry", () => {
|
|
53
|
+
describe("hostPlatformTarget", () => {
|
|
54
|
+
it("maps Node's platform and arch onto the registry's identifiers", () => {
|
|
55
|
+
expect(hostPlatformTarget("darwin", "arm64")).toBe("darwin-aarch64");
|
|
56
|
+
expect(hostPlatformTarget("darwin", "x64")).toBe("darwin-x86_64");
|
|
57
|
+
expect(hostPlatformTarget("linux", "arm64")).toBe("linux-aarch64");
|
|
58
|
+
expect(hostPlatformTarget("linux", "x64")).toBe("linux-x86_64");
|
|
59
|
+
expect(hostPlatformTarget("win32", "x64")).toBe("windows-x86_64");
|
|
60
|
+
expect(hostPlatformTarget("win32", "arm64")).toBe("windows-aarch64");
|
|
61
|
+
});
|
|
62
|
+
it("returns nothing for platforms the registry does not publish for", () => {
|
|
63
|
+
expect(hostPlatformTarget("freebsd", "x64")).toBeUndefined();
|
|
64
|
+
expect(hostPlatformTarget("linux", "ppc64")).toBeUndefined();
|
|
65
|
+
});
|
|
66
|
+
it("describes the machine it is running on by default", () => {
|
|
67
|
+
// Every platform this package supports is one the registry publishes for.
|
|
68
|
+
expect(hostPlatformTarget()).toMatch(/^(darwin|linux|windows)-(aarch64|x86_64)$/);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
describe("fetchRegistry", () => {
|
|
72
|
+
it("fetches the published index by default", async () => {
|
|
73
|
+
const fetchImpl = vi.fn().mockResolvedValue(jsonResponse(registry));
|
|
74
|
+
expect(await fetchRegistry(undefined, fetchImpl)).toEqual(registry);
|
|
75
|
+
expect(fetchImpl).toHaveBeenCalledWith(DEFAULT_REGISTRY_URL);
|
|
76
|
+
});
|
|
77
|
+
it("accepts a different registry so a local copy can be used", async () => {
|
|
78
|
+
const fetchImpl = vi.fn().mockResolvedValue(jsonResponse(registry));
|
|
79
|
+
await fetchRegistry("http://localhost:9000/registry.json", fetchImpl);
|
|
80
|
+
expect(fetchImpl).toHaveBeenCalledWith("http://localhost:9000/registry.json");
|
|
81
|
+
});
|
|
82
|
+
it("reports a failed request", async () => {
|
|
83
|
+
const fetchImpl = vi
|
|
84
|
+
.fn()
|
|
85
|
+
.mockResolvedValue({ ok: false, status: 404, statusText: "Not Found" });
|
|
86
|
+
await expect(fetchRegistry(DEFAULT_REGISTRY_URL, fetchImpl)).rejects.toThrow(/404 Not Found/);
|
|
87
|
+
});
|
|
88
|
+
it("rejects a response that is not a registry index", async () => {
|
|
89
|
+
const fetchImpl = vi.fn().mockResolvedValue(jsonResponse({ nope: true }));
|
|
90
|
+
await expect(fetchRegistry(DEFAULT_REGISTRY_URL, fetchImpl)).rejects.toThrow(/did not return an ACP registry index/);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
describe("findAgent", () => {
|
|
94
|
+
it("finds an agent by id", () => {
|
|
95
|
+
expect(findAgent(registry, "gemini")).toBe(gemini);
|
|
96
|
+
});
|
|
97
|
+
it("returns nothing for an unknown id", () => {
|
|
98
|
+
expect(findAgent(registry, "nope")).toBeUndefined();
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe("availableKinds", () => {
|
|
102
|
+
it("lists the distributions that can run here", () => {
|
|
103
|
+
expect(availableKinds(gemini, "darwin-aarch64")).toEqual(["npx"]);
|
|
104
|
+
expect(availableKinds(fastAgent, "darwin-aarch64")).toEqual(["uvx"]);
|
|
105
|
+
expect(availableKinds(antigravity, "darwin-aarch64")).toEqual(["binary"]);
|
|
106
|
+
});
|
|
107
|
+
it("omits a binary the registry does not publish for this platform", () => {
|
|
108
|
+
expect(availableKinds(antigravity, "windows-aarch64")).toEqual([]);
|
|
109
|
+
expect(availableKinds(antigravity, undefined)).toEqual([]);
|
|
110
|
+
});
|
|
111
|
+
it("lists every distribution an agent offers", () => {
|
|
112
|
+
const both = {
|
|
113
|
+
...gemini,
|
|
114
|
+
distribution: { ...gemini.distribution, binary: antigravity.distribution.binary },
|
|
115
|
+
};
|
|
116
|
+
expect(availableKinds(both, "darwin-aarch64")).toEqual(["npx", "binary"]);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
describe("describeAgents", () => {
|
|
120
|
+
it("lists every agent with how it can be run here", () => {
|
|
121
|
+
const text = describeAgents(registry, "darwin-aarch64");
|
|
122
|
+
expect(text).toContain("gemini");
|
|
123
|
+
expect(text).toContain("Gemini CLI — npx");
|
|
124
|
+
expect(text).toContain("fast-agent");
|
|
125
|
+
});
|
|
126
|
+
it("says when an agent cannot run on this machine", () => {
|
|
127
|
+
const unavailable = {
|
|
128
|
+
version: "1.0.0",
|
|
129
|
+
agents: [{ ...antigravity, distribution: { binary: {} } }],
|
|
130
|
+
};
|
|
131
|
+
expect(describeAgents(unavailable, "darwin-aarch64")).toContain("unavailable on this platform");
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
describe("selectBinaryTarget", () => {
|
|
135
|
+
it("picks the build for this machine", () => {
|
|
136
|
+
expect(selectBinaryTarget(antigravity, "linux-x86_64").args).toEqual(["--uid="]);
|
|
137
|
+
});
|
|
138
|
+
it("refuses an agent that ships no binaries", () => {
|
|
139
|
+
expect(() => selectBinaryTarget(gemini, "darwin-aarch64")).toThrow(/publishes no binary distribution/);
|
|
140
|
+
});
|
|
141
|
+
it("refuses a platform the registry does not cover", () => {
|
|
142
|
+
expect(() => selectBinaryTarget(antigravity, undefined)).toThrow(/registry publishes no binaries for/);
|
|
143
|
+
});
|
|
144
|
+
it("refuses to substitute another platform's build", () => {
|
|
145
|
+
expect(() => selectBinaryTarget(antigravity, "windows-x86_64")).toThrow(/no binary for windows-x86_64 \(available: darwin-aarch64, linux-x86_64\)/);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
describe("packageLaunchSpec", () => {
|
|
149
|
+
it("runs npm packages through npx without prompting", () => {
|
|
150
|
+
expect(packageLaunchSpec("npx", gemini.distribution.npx)).toEqual({
|
|
151
|
+
command: "npx",
|
|
152
|
+
args: ["-y", "@google/gemini-cli@0.58.0", "--acp"],
|
|
153
|
+
env: undefined,
|
|
154
|
+
kind: "npx",
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
it("runs PyPI packages through uvx", () => {
|
|
158
|
+
expect(packageLaunchSpec("uvx", fastAgent.distribution.uvx)).toEqual({
|
|
159
|
+
command: "uvx",
|
|
160
|
+
args: ["fast-agent-mcp", "serve"],
|
|
161
|
+
env: undefined,
|
|
162
|
+
kind: "uvx",
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
it("passes the distribution's env through and tolerates missing args", () => {
|
|
166
|
+
expect(packageLaunchSpec("npx", { package: "some-agent", env: { KEY: "v" } })).toEqual({
|
|
167
|
+
command: "npx",
|
|
168
|
+
args: ["-y", "some-agent"],
|
|
169
|
+
env: { KEY: "v" },
|
|
170
|
+
kind: "npx",
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
//# sourceMappingURL=registry.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.test.js","sourceRoot":"","sources":["../../src/__tests__/registry.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agentInstall.ts
|
|
3
|
+
*
|
|
4
|
+
* Downloads, verifies and unpacks the binary distribution of a registry agent,
|
|
5
|
+
* caching it so the download happens once.
|
|
6
|
+
*
|
|
7
|
+
* This is the one place in the gateway that fetches a third-party executable
|
|
8
|
+
* and runs it, so the rules here are deliberately strict: an archive is only
|
|
9
|
+
* installed when the registry publishes a `sha256` that the download matches,
|
|
10
|
+
* unless the user has explicitly said otherwise.
|
|
11
|
+
*/
|
|
12
|
+
import { createHash } from "node:crypto";
|
|
13
|
+
import { spawn } from "node:child_process";
|
|
14
|
+
import { chmod, cp, mkdir, mkdtemp, rename, rm, writeFile } from "node:fs/promises";
|
|
15
|
+
import { existsSync } from "node:fs";
|
|
16
|
+
import { homedir, tmpdir } from "node:os";
|
|
17
|
+
import * as path from "node:path";
|
|
18
|
+
import { availableKinds, findAgent, packageLaunchSpec, selectBinaryTarget, } from "./registry.js";
|
|
19
|
+
/**
|
|
20
|
+
* Where downloaded agents live, unless overridden.
|
|
21
|
+
*
|
|
22
|
+
* Follows each platform's own convention: `%LOCALAPPDATA%` on Windows,
|
|
23
|
+
* `XDG_CACHE_HOME` where it is set, and `~/.cache` otherwise.
|
|
24
|
+
*/
|
|
25
|
+
export function defaultCacheDir(platform = process.platform, env = process.env) {
|
|
26
|
+
const base = platform === "win32"
|
|
27
|
+
? env.LOCALAPPDATA || path.join(homedir(), "AppData", "Local")
|
|
28
|
+
: env.XDG_CACHE_HOME || path.join(homedir(), ".cache");
|
|
29
|
+
return path.join(base, "acp-gateway", "agents");
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Classifies an archive by its URL.
|
|
33
|
+
*
|
|
34
|
+
* The registry documents exactly which formats may appear; anything else is a
|
|
35
|
+
* raw executable to be saved as-is.
|
|
36
|
+
*/
|
|
37
|
+
export function archiveKind(url) {
|
|
38
|
+
const pathname = url.split("?")[0].split("#")[0].toLowerCase();
|
|
39
|
+
if (pathname.endsWith(".zip"))
|
|
40
|
+
return "zip";
|
|
41
|
+
if (pathname.endsWith(".tar.gz") || pathname.endsWith(".tgz"))
|
|
42
|
+
return "tar.gz";
|
|
43
|
+
if (pathname.endsWith(".tar.bz2") || pathname.endsWith(".tbz2"))
|
|
44
|
+
return "tar.bz2";
|
|
45
|
+
return "raw";
|
|
46
|
+
}
|
|
47
|
+
/** The directory one agent build is unpacked into. */
|
|
48
|
+
export function installDir(cacheDir, agentId, target, version) {
|
|
49
|
+
// The version is part of the path so a registry bump installs alongside the
|
|
50
|
+
// old build rather than half-overwriting it.
|
|
51
|
+
return path.join(cacheDir, `${agentId}@${version}`, target);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Resolves the registry's `cmd` inside the install directory.
|
|
55
|
+
*
|
|
56
|
+
* `cmd` is third-party text, so a path that climbs out of the directory — and
|
|
57
|
+
* would have us run something else entirely — is rejected rather than resolved.
|
|
58
|
+
*/
|
|
59
|
+
export function resolveExecutable(dir, cmd) {
|
|
60
|
+
const executable = path.resolve(dir, cmd);
|
|
61
|
+
const root = path.resolve(dir);
|
|
62
|
+
if (executable !== root && !executable.startsWith(root + path.sep)) {
|
|
63
|
+
throw new Error(`Agent command "${cmd}" points outside its install directory; refusing to run it.`);
|
|
64
|
+
}
|
|
65
|
+
return executable;
|
|
66
|
+
}
|
|
67
|
+
export function sha256(data) {
|
|
68
|
+
return createHash("sha256").update(data).digest("hex");
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Refuses an archive we cannot vouch for.
|
|
72
|
+
*
|
|
73
|
+
* Roughly half the registry's binary targets publish no checksum. Running one
|
|
74
|
+
* means trusting whatever the vendor's host served, so it takes an explicit
|
|
75
|
+
* opt-in rather than happening quietly.
|
|
76
|
+
*/
|
|
77
|
+
export function assertVerifiable(agent, target, allowUnverified) {
|
|
78
|
+
if (target.sha256 || allowUnverified)
|
|
79
|
+
return;
|
|
80
|
+
throw new Error(`The ACP registry publishes no sha256 for "${agent.id}" on this platform, so the ` +
|
|
81
|
+
`download cannot be verified. Re-run with --allow-unverified-agent to install it anyway, ` +
|
|
82
|
+
`or install the agent yourself and pass it after --.`);
|
|
83
|
+
}
|
|
84
|
+
/** Checks a download against the registry's checksum. */
|
|
85
|
+
export function assertChecksum(agent, target, data) {
|
|
86
|
+
if (!target.sha256)
|
|
87
|
+
return;
|
|
88
|
+
const actual = sha256(data);
|
|
89
|
+
if (actual.toLowerCase() !== target.sha256.toLowerCase()) {
|
|
90
|
+
throw new Error(`Checksum mismatch for "${agent.id}": the registry expects ${target.sha256.toLowerCase()} ` +
|
|
91
|
+
`but ${target.archive} produced ${actual}. Refusing to run it.`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/** Downloads an archive into memory so it can be checksummed before it touches disk. */
|
|
95
|
+
export async function downloadArchive(url, fetchImpl = fetch) {
|
|
96
|
+
const response = await fetchImpl(url);
|
|
97
|
+
if (!response.ok) {
|
|
98
|
+
throw new Error(`Failed to download ${url}: ${response.status} ${response.statusText}`);
|
|
99
|
+
}
|
|
100
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
101
|
+
}
|
|
102
|
+
/** Runs an extraction tool, failing with its own diagnostics attached. */
|
|
103
|
+
export async function runExtractionTool(command, args, cwd) {
|
|
104
|
+
const child = spawn(command, args, { cwd, stdio: ["ignore", "ignore", "pipe"] });
|
|
105
|
+
let stderr = "";
|
|
106
|
+
child.stderr?.on("data", (chunk) => {
|
|
107
|
+
stderr += chunk.toString();
|
|
108
|
+
});
|
|
109
|
+
await new Promise((resolve, reject) => {
|
|
110
|
+
child.on("error", (err) => reject(new Error(`Could not run "${command}" to unpack the agent archive: ${err.message}. ` +
|
|
111
|
+
`Install it, or install the agent yourself and pass it after --.`)));
|
|
112
|
+
child.on("exit", (code) => {
|
|
113
|
+
if (code === 0)
|
|
114
|
+
return resolve();
|
|
115
|
+
reject(new Error(`"${command}" failed to unpack the agent archive (code=${code}): ${stderr.trim()}`));
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Unpacks an archive into `dir`.
|
|
121
|
+
*
|
|
122
|
+
* Uses the system's own tools rather than adding archive libraries as
|
|
123
|
+
* dependencies. `tar` handles the tarballs everywhere and zips on macOS and
|
|
124
|
+
* Windows, where it is bsdtar; GNU tar cannot read zips, so Linux falls back
|
|
125
|
+
* to `unzip`.
|
|
126
|
+
*/
|
|
127
|
+
export async function extractArchive(data, kind, dir, cmd, platform = process.platform) {
|
|
128
|
+
await mkdir(dir, { recursive: true });
|
|
129
|
+
if (kind === "raw") {
|
|
130
|
+
// No archive to unpack: the download is the executable itself.
|
|
131
|
+
await writeFile(path.join(dir, path.basename(cmd)), data);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const archivePath = path.join(dir, `archive.${kind}`);
|
|
135
|
+
await writeFile(archivePath, data);
|
|
136
|
+
try {
|
|
137
|
+
if (kind === "zip" && platform === "linux") {
|
|
138
|
+
await runExtractionTool("unzip", ["-q", "-o", archivePath], dir);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
await runExtractionTool("tar", ["-xf", archivePath], dir);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
await rm(archivePath, { force: true });
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Makes a registry agent runnable, returning the command that launches it.
|
|
150
|
+
*
|
|
151
|
+
* A cached install is reused as-is; the version in the cache path means a
|
|
152
|
+
* registry bump installs a fresh copy rather than reusing a stale one.
|
|
153
|
+
*/
|
|
154
|
+
export async function installBinaryAgent({ agent, target, platformTarget, cacheDir, allowUnverified = false, fetchImpl = fetch, platform = process.platform, }) {
|
|
155
|
+
cacheDir ??= defaultCacheDir(platform);
|
|
156
|
+
const dir = installDir(cacheDir, agent.id, platformTarget, agent.version);
|
|
157
|
+
const executable = resolveExecutable(dir, target.cmd);
|
|
158
|
+
const spec = {
|
|
159
|
+
command: executable,
|
|
160
|
+
args: target.args ?? [],
|
|
161
|
+
env: target.env,
|
|
162
|
+
kind: "binary",
|
|
163
|
+
};
|
|
164
|
+
if (existsSync(executable)) {
|
|
165
|
+
console.error(`[registry] Using cached ${agent.id} ${agent.version} from ${dir}`);
|
|
166
|
+
return spec;
|
|
167
|
+
}
|
|
168
|
+
assertVerifiable(agent, target, allowUnverified);
|
|
169
|
+
console.error(`[registry] Downloading ${agent.id} ${agent.version} from ${target.archive}`);
|
|
170
|
+
const data = await downloadArchive(target.archive, fetchImpl);
|
|
171
|
+
assertChecksum(agent, target, data);
|
|
172
|
+
if (!target.sha256) {
|
|
173
|
+
console.error(`[registry] ⚠️ ${agent.id} publishes no checksum; installing it unverified at your request.`);
|
|
174
|
+
}
|
|
175
|
+
// Unpack somewhere temporary and move into place only once it succeeded, so
|
|
176
|
+
// a failed extraction never leaves a half-installed agent to be cached.
|
|
177
|
+
const staging = await mkdtemp(path.join(tmpdir(), `acp-gateway-${agent.id}-`));
|
|
178
|
+
try {
|
|
179
|
+
await extractArchive(data, archiveKind(target.archive), staging, target.cmd, platform);
|
|
180
|
+
const staged = resolveExecutable(staging, target.cmd);
|
|
181
|
+
if (!existsSync(staged)) {
|
|
182
|
+
throw new Error(`The archive for "${agent.id}" does not contain "${target.cmd}" where the registry says it should.`);
|
|
183
|
+
}
|
|
184
|
+
await rm(dir, { recursive: true, force: true });
|
|
185
|
+
await mkdir(path.dirname(dir), { recursive: true });
|
|
186
|
+
await moveInto(staging, dir);
|
|
187
|
+
}
|
|
188
|
+
finally {
|
|
189
|
+
await rm(staging, { recursive: true, force: true });
|
|
190
|
+
}
|
|
191
|
+
// Archive formats do not always carry the executable bit. Windows has no
|
|
192
|
+
// such bit — chmod there only toggles the read-only flag — so skip it.
|
|
193
|
+
if (platform !== "win32") {
|
|
194
|
+
await chmod(executable, 0o755);
|
|
195
|
+
}
|
|
196
|
+
console.error(`[registry] Installed ${agent.id} ${agent.version} to ${dir}`);
|
|
197
|
+
return spec;
|
|
198
|
+
}
|
|
199
|
+
/** Moves a staged install into the cache, copying across filesystems if needed. */
|
|
200
|
+
export async function moveInto(from, to) {
|
|
201
|
+
try {
|
|
202
|
+
await rename(from, to);
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
// rename() fails across devices — the temp dir is often a different mount.
|
|
206
|
+
await cp(from, to, { recursive: true });
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Turns a registry id into the command that runs that agent, installing it
|
|
211
|
+
* first where the only distribution is a binary.
|
|
212
|
+
*
|
|
213
|
+
* Package distributions are preferred over binaries: npm and PyPI verify what
|
|
214
|
+
* they serve, and nothing has to be downloaded, unpacked or cached here.
|
|
215
|
+
*/
|
|
216
|
+
export async function resolveAgentLaunch({ id, registry, platformTarget, cacheDir, allowUnverified = false, fetchImpl = fetch, platform = process.platform, }) {
|
|
217
|
+
const agent = findAgent(registry, id);
|
|
218
|
+
if (!agent) {
|
|
219
|
+
throw new Error(`No agent "${id}" in the ACP registry. Run --list-agents to see what it publishes.`);
|
|
220
|
+
}
|
|
221
|
+
const kinds = availableKinds(agent, platformTarget);
|
|
222
|
+
if (!kinds.length) {
|
|
223
|
+
const published = Object.keys(agent.distribution).join(", ") || "nothing";
|
|
224
|
+
throw new Error(`The ACP registry publishes no build of "${id}" for ${platformTarget ?? `${process.platform}/${process.arch}`} ` +
|
|
225
|
+
`(it publishes: ${published}).`);
|
|
226
|
+
}
|
|
227
|
+
if (kinds.includes("npx"))
|
|
228
|
+
return packageLaunchSpec("npx", agent.distribution.npx, platform);
|
|
229
|
+
if (kinds.includes("uvx"))
|
|
230
|
+
return packageLaunchSpec("uvx", agent.distribution.uvx, platform);
|
|
231
|
+
return installBinaryAgent({
|
|
232
|
+
agent,
|
|
233
|
+
target: selectBinaryTarget(agent, platformTarget),
|
|
234
|
+
platformTarget: platformTarget,
|
|
235
|
+
cacheDir,
|
|
236
|
+
allowUnverified,
|
|
237
|
+
fetchImpl,
|
|
238
|
+
platform,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=agentInstall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentInstall.js","sourceRoot":"","sources":["../src/agentInstall.ts"],"names":[],"mappings":"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"}
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* auth.ts
|
|
3
|
+
*
|
|
4
|
+
* ACP authentication support: reading the login methods an agent advertises
|
|
5
|
+
* during `initialize`, recognising the protocol's `auth_required` failure, and
|
|
6
|
+
* running either kind of login on the user's behalf.
|
|
7
|
+
*
|
|
8
|
+
* See https://agentclientprotocol.com/protocol/v1/authentication
|
|
9
|
+
*/
|
|
10
|
+
import { spawn } from "node:child_process";
|
|
11
|
+
import { createInterface } from "node:readline/promises";
|
|
12
|
+
/** JSON-RPC code ACP reserves for "the user must authenticate first". */
|
|
13
|
+
export const AUTH_REQUIRED_CODE = -32000;
|
|
14
|
+
/**
|
|
15
|
+
* `type` discriminates the two kinds of auth method on the wire, and the
|
|
16
|
+
* protocol treats a missing `type` as `agent`.
|
|
17
|
+
*/
|
|
18
|
+
export function authMethodType(method) {
|
|
19
|
+
return method.type === "terminal" ? "terminal" : "agent";
|
|
20
|
+
}
|
|
21
|
+
/** Renders the agent's login options as a numbered list for the terminal. */
|
|
22
|
+
export function describeAuthMethods(methods) {
|
|
23
|
+
if (!methods?.length) {
|
|
24
|
+
return "The agent advertises no authentication methods — no login is needed.";
|
|
25
|
+
}
|
|
26
|
+
return methods
|
|
27
|
+
.map((m, i) => {
|
|
28
|
+
const kind = authMethodType(m) === "terminal" ? " [terminal login]" : "";
|
|
29
|
+
const description = m.description ? ` — ${m.description}` : "";
|
|
30
|
+
return ` ${i + 1}. ${m.name} (${m.id})${kind}${description}`;
|
|
31
|
+
})
|
|
32
|
+
.join("\n");
|
|
33
|
+
}
|
|
34
|
+
/** Pulls `code`/`message` out of a JSON-RPC failure in either shape it arrives in. */
|
|
35
|
+
function errorParts(err) {
|
|
36
|
+
if (!err || typeof err !== "object")
|
|
37
|
+
return { message: "" };
|
|
38
|
+
const candidate = err;
|
|
39
|
+
const source = candidate.error && typeof candidate.error === "object"
|
|
40
|
+
? candidate.error
|
|
41
|
+
: candidate;
|
|
42
|
+
return {
|
|
43
|
+
code: typeof source.code === "number" ? source.code : undefined,
|
|
44
|
+
message: typeof source.message === "string" ? source.message : "",
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Tells an "authenticate first" refusal apart from any other failure.
|
|
49
|
+
*
|
|
50
|
+
* ACP carries `auth_required` on the reserved code -32000, which agents also
|
|
51
|
+
* use for unrelated errors (a denied permission, for one), so the message has
|
|
52
|
+
* to agree before we send the user through a login.
|
|
53
|
+
*/
|
|
54
|
+
export function isAuthRequiredError(err) {
|
|
55
|
+
const { code, message } = errorParts(err);
|
|
56
|
+
return code === AUTH_REQUIRED_CODE && /auth/i.test(message);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Chooses the login method to run without asking anyone.
|
|
60
|
+
*
|
|
61
|
+
* An explicitly named id always wins. Otherwise `agent` methods come first:
|
|
62
|
+
* the agent drives those itself, so they work in an unattended gateway, while
|
|
63
|
+
* a `terminal` method needs a human at a TTY.
|
|
64
|
+
*/
|
|
65
|
+
export function pickAuthMethod(methods, { preferredId, allowTerminal = false } = {}) {
|
|
66
|
+
if (!methods?.length)
|
|
67
|
+
return undefined;
|
|
68
|
+
if (preferredId)
|
|
69
|
+
return methods.find((m) => m.id === preferredId);
|
|
70
|
+
return (methods.find((m) => authMethodType(m) === "agent") ??
|
|
71
|
+
(allowTerminal ? methods.find((m) => authMethodType(m) === "terminal") : undefined));
|
|
72
|
+
}
|
|
73
|
+
/** Asks on stderr so the gateway's stdout stays free for its own output. */
|
|
74
|
+
async function askOnTerminal(question) {
|
|
75
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
76
|
+
try {
|
|
77
|
+
return await rl.question(question);
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
rl.close();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Asks the user which login to use, the way an editor would on first run.
|
|
85
|
+
*
|
|
86
|
+
* A single method needs no question. An empty answer takes the first method,
|
|
87
|
+
* and an unrecognised one re-asks rather than logging in with something the
|
|
88
|
+
* user did not choose.
|
|
89
|
+
*/
|
|
90
|
+
export async function promptForAuthMethod(methods, ask = askOnTerminal) {
|
|
91
|
+
if (!methods.length)
|
|
92
|
+
return undefined;
|
|
93
|
+
if (methods.length === 1)
|
|
94
|
+
return methods[0];
|
|
95
|
+
console.error(`\n[auth] The agent requires a login. Available methods:\n${describeAuthMethods(methods)}`);
|
|
96
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
97
|
+
const answer = (await ask(`[auth] Choose a method [1-${methods.length}, default 1]: `)).trim();
|
|
98
|
+
if (!answer)
|
|
99
|
+
return methods[0];
|
|
100
|
+
const byIndex = Number(answer);
|
|
101
|
+
if (Number.isInteger(byIndex) && byIndex >= 1 && byIndex <= methods.length) {
|
|
102
|
+
return methods[byIndex - 1];
|
|
103
|
+
}
|
|
104
|
+
const byId = methods.find((m) => m.id === answer);
|
|
105
|
+
if (byId)
|
|
106
|
+
return byId;
|
|
107
|
+
console.error(`[auth] "${answer}" is not one of the listed methods.`);
|
|
108
|
+
}
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Runs a `terminal` login by re-launching the configured agent interactively.
|
|
113
|
+
*
|
|
114
|
+
* The protocol has the client reproduce its own agent invocation with the
|
|
115
|
+
* method's extra args and env, hand the process the user's terminal, and read
|
|
116
|
+
* success off the exit status.
|
|
117
|
+
*/
|
|
118
|
+
export async function runTerminalAuth(method, launch) {
|
|
119
|
+
const extra = method.args ?? [];
|
|
120
|
+
const extraEnv = method.env ?? {};
|
|
121
|
+
const args = [...launch.args, ...extra];
|
|
122
|
+
console.error(`[auth] Running terminal login: ${launch.command} ${args.join(" ")}\n` +
|
|
123
|
+
`[auth] Complete the login in your terminal; the gateway resumes when it exits.`);
|
|
124
|
+
const child = spawn(launch.command, args, {
|
|
125
|
+
stdio: "inherit",
|
|
126
|
+
env: { ...process.env, ...launch.env, ...extraEnv },
|
|
127
|
+
});
|
|
128
|
+
await new Promise((resolve, reject) => {
|
|
129
|
+
child.on("error", (err) => reject(new Error(`Terminal login "${method.id}" failed to start: ${err.message}`)));
|
|
130
|
+
child.on("exit", (code, signal) => {
|
|
131
|
+
if (code === 0)
|
|
132
|
+
return resolve();
|
|
133
|
+
reject(new Error(`Terminal login "${method.id}" failed (code=${code}, signal=${signal}).`));
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
/** Runs whichever kind of login the chosen method calls for. */
|
|
138
|
+
export async function runAuthMethod(connection, method, launch) {
|
|
139
|
+
if (authMethodType(method) === "terminal") {
|
|
140
|
+
await runTerminalAuth(method, launch);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
// A `terminal` method must never reach `authenticate` — the agent does not
|
|
144
|
+
// implement one for it.
|
|
145
|
+
await connection.authenticate({ methodId: method.id });
|
|
146
|
+
}
|
|
147
|
+
console.error(`[auth] Logged in with "${method.name}" (${method.id}).`);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Logs in: picks a method — asking the user when one is there to ask — and
|
|
151
|
+
* runs it. Returns the method used, or undefined when the agent advertises no
|
|
152
|
+
* login at all.
|
|
153
|
+
*/
|
|
154
|
+
export async function login({ connection, methods, launch, preferredId, interactive = false, ask, }) {
|
|
155
|
+
if (!methods?.length) {
|
|
156
|
+
console.error("[auth] The agent advertises no authentication methods; nothing to log in to.");
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
159
|
+
let method = pickAuthMethod(methods, { preferredId, allowTerminal: interactive });
|
|
160
|
+
if (preferredId && !method) {
|
|
161
|
+
throw new Error(`Unknown authentication method "${preferredId}". Available:\n${describeAuthMethods(methods)}`);
|
|
162
|
+
}
|
|
163
|
+
if (!preferredId && interactive) {
|
|
164
|
+
method = await promptForAuthMethod(methods, ask);
|
|
165
|
+
}
|
|
166
|
+
if (!method) {
|
|
167
|
+
throw new Error(`No usable authentication method. Available:\n${describeAuthMethods(methods)}\n` +
|
|
168
|
+
`Terminal logins need an interactive terminal; re-run acp-gateway from one, ` +
|
|
169
|
+
`or pass --auth-method <id>.`);
|
|
170
|
+
}
|
|
171
|
+
await runAuthMethod(connection, method, launch);
|
|
172
|
+
return method;
|
|
173
|
+
}
|
|
174
|
+
/** Whether the agent said it implements `logout` during `initialize`. */
|
|
175
|
+
export function supportsLogout(agentCapabilities) {
|
|
176
|
+
const auth = agentCapabilities?.auth;
|
|
177
|
+
return auth?.logout !== undefined && auth?.logout !== null;
|
|
178
|
+
}
|
|
179
|
+
/** Ends the agent's authenticated state, if it implements logout. */
|
|
180
|
+
export async function logout(connection, agentCapabilities) {
|
|
181
|
+
if (!supportsLogout(agentCapabilities)) {
|
|
182
|
+
console.error("[auth] The agent does not support logout.");
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
await connection.logout({});
|
|
186
|
+
console.error("[auth] Logged out.");
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|