@agentproto/cli 0.1.0-alpha.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/LICENSE ADDED
@@ -0,0 +1 @@
1
+ MIT License — Copyright (c) 2026 agentproto contributors
package/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # @agentproto/cli
2
+
3
+ The `agentproto` binary — install, run, and serve [AIP-45 agent CLIs](https://agentproto.sh/docs/aip-45).
4
+
5
+ ```bash
6
+ npm install -g @agentproto/cli
7
+ ```
8
+
9
+ This installs the `agentproto` executable on your `PATH`.
10
+
11
+ ## Verbs
12
+
13
+ ```text
14
+ agentproto install <slug> install an adapter's underlying CLI
15
+ agentproto run <slug> [opts] spawn the adapter, dispatch a turn, stream events
16
+ agentproto serve --connect <url> long-running daemon (relays spawns over a tunnel)
17
+ ```
18
+
19
+ ### `run`
20
+
21
+ ```bash
22
+ # install an adapter package once
23
+ npm i -g @agentproto/adapter-claude-code
24
+
25
+ # run a one-shot turn against the current directory
26
+ agentproto run claude-code --cwd . --prompt "what does this repo do?"
27
+
28
+ # pipe a prompt over stdin
29
+ echo "summarise CHANGELOG.md" | agentproto run claude-code
30
+
31
+ # resume an existing protocol session
32
+ agentproto run claude-code --resume <session-id>
33
+ ```
34
+
35
+ Output is human-readable by default; pass `--json` for one-event-per-line NDJSON.
36
+
37
+ ### `install`
38
+
39
+ ```bash
40
+ agentproto install claude-code # idempotent, skips if version_check passes
41
+ agentproto install claude-code --force # reinstall regardless
42
+ agentproto install claude-code --dry-run # print steps, don't execute
43
+ ```
44
+
45
+ v0.1 implements the `npm` install method; other package managers print a clear "not yet" message and exit non-zero.
46
+
47
+ ### `serve` *(coming soon)*
48
+
49
+ Long-running daemon that exposes locally-installed adapters to a remote host over a WebSocket tunnel. Wire protocol still being designed; the verb is parsed but currently exits 64 with a tracking message.
50
+
51
+ ## Adapter resolution
52
+
53
+ `<slug>` resolves to the npm package `@agentproto/adapter-<slug>`. Install adapters globally so `agentproto` can find them on its `NODE_PATH`. Built-in adapters as of v0.1:
54
+
55
+ - `@agentproto/adapter-claude-code` — Anthropic Claude Code via [@agentclientprotocol/claude-agent-acp](https://www.npmjs.com/package/@agentclientprotocol/claude-agent-acp)
56
+ - `@agentproto/adapter-hermes` — generic Hermes-flavoured agents
57
+ - `@agentproto/adapter-mastra` — Mastra agents
58
+
59
+ ## License
60
+
61
+ MIT — see [LICENSE](./LICENSE).
package/dist/cli.mjs ADDED
@@ -0,0 +1,371 @@
1
+ #!/usr/bin/env node
2
+ import { parseArgs } from 'util';
3
+ import { spawn } from 'child_process';
4
+ import { resolve } from 'path';
5
+ import { createAgentCliRuntime } from '@agentproto/driver-agent-cli';
6
+
7
+ /**
8
+ * @agentproto/cli v0.1.0-alpha
9
+ * The `agentproto` binary — install / run / serve AIP-45 agent CLIs.
10
+ */
11
+
12
+
13
+ // src/registry/resolve.ts
14
+ var slugToCamel = (slug) => slug.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
15
+ async function resolveAdapter(slug) {
16
+ if (!/^[a-z][a-z0-9-]*$/.test(slug)) {
17
+ throw new Error(
18
+ `agentproto: invalid adapter slug '${slug}'. Slugs are lower-kebab.`
19
+ );
20
+ }
21
+ const packageName = `@agentproto/adapter-${slug}`;
22
+ let mod;
23
+ try {
24
+ mod = await import(packageName);
25
+ } catch (err) {
26
+ const cause = err instanceof Error ? err.message : String(err);
27
+ throw new Error(
28
+ `agentproto: could not load adapter '${slug}'. Tried '${packageName}'. Install it with: npm i -g ${packageName}
29
+ cause: ${cause}`
30
+ );
31
+ }
32
+ const camel = slugToCamel(slug);
33
+ const candidate = mod[camel] ?? mod.default ?? mod.handle;
34
+ if (!candidate || typeof candidate !== "object" || !("name" in candidate)) {
35
+ throw new Error(
36
+ `agentproto: adapter '${packageName}' does not export an AgentCliHandle (looked for export '${camel}', 'default', or 'handle').`
37
+ );
38
+ }
39
+ return { slug, handle: candidate, source: "npm", packageName };
40
+ }
41
+
42
+ // src/commands/install.ts
43
+ async function runInstall(args) {
44
+ const { values, positionals } = parseArgs({
45
+ args: [...args],
46
+ allowPositionals: true,
47
+ strict: true,
48
+ options: {
49
+ force: { type: "boolean", short: "f" },
50
+ "dry-run": { type: "boolean" }
51
+ }
52
+ });
53
+ const slug = positionals[0];
54
+ if (!slug) {
55
+ process.stderr.write(
56
+ "agentproto install: missing adapter slug. Try: agentproto install claude-code\n"
57
+ );
58
+ return 2;
59
+ }
60
+ const adapter = await resolveAdapter(slug);
61
+ const installSteps = adapter.handle.install ?? [];
62
+ if (installSteps.length === 0) {
63
+ process.stderr.write(
64
+ `agentproto install: adapter '${slug}' declares no install steps.
65
+ `
66
+ );
67
+ return 0;
68
+ }
69
+ if (!values.force) {
70
+ const checked = await runVersionCheck(adapter.handle.version_check);
71
+ if (checked.ok) {
72
+ process.stdout.write(
73
+ `agentproto: '${slug}' already installed (${checked.message}). Pass --force to reinstall.
74
+ `
75
+ );
76
+ return 0;
77
+ }
78
+ }
79
+ for (const [i, step] of installSteps.entries()) {
80
+ process.stdout.write(
81
+ `agentproto install [${i + 1}/${installSteps.length}] ${describeStep(step)}
82
+ `
83
+ );
84
+ if (values["dry-run"]) continue;
85
+ const code = await runStep(step);
86
+ if (code !== 0) {
87
+ process.stderr.write(
88
+ `agentproto install: step ${i + 1} failed with exit ${code}.
89
+ `
90
+ );
91
+ return code;
92
+ }
93
+ }
94
+ process.stdout.write(`agentproto: '${slug}' installed.
95
+ `);
96
+ return 0;
97
+ }
98
+ function describeStep(step) {
99
+ switch (step.method) {
100
+ case "npm":
101
+ return `npm install ${step.global ? "-g " : ""}${step.package ?? "(?)"}`;
102
+ case "brew":
103
+ return `brew install ${step.package ?? "(?)"}`;
104
+ case "pip":
105
+ return `pip install ${step.package ?? "(?)"}`;
106
+ case "cargo":
107
+ return `cargo install ${step.package ?? "(?)"}`;
108
+ case "go":
109
+ return `go install ${step.package ?? "(?)"}`;
110
+ case "curl":
111
+ case "download":
112
+ return `${step.method} ${step.url ?? "(?)"} \u2192 ${step.path ?? "(default)"}`;
113
+ default:
114
+ return `${step.method} ${step.package ?? step.url ?? "(?)"}`;
115
+ }
116
+ }
117
+ async function runStep(step) {
118
+ switch (step.method) {
119
+ case "npm": {
120
+ if (!step.package) {
121
+ process.stderr.write("agentproto install: npm step missing package.\n");
122
+ return 2;
123
+ }
124
+ const argv = ["install"];
125
+ if (step.global) argv.push("-g");
126
+ argv.push(step.package);
127
+ return spawnInherit("npm", argv);
128
+ }
129
+ default:
130
+ process.stderr.write(
131
+ `agentproto install: method '${step.method}' not yet implemented in this CLI version. Run it manually for now (see the adapter's INSTALL.md).
132
+ `
133
+ );
134
+ return 1;
135
+ }
136
+ }
137
+ function spawnInherit(cmd, argv) {
138
+ return new Promise((resolve, reject) => {
139
+ const child = spawn(cmd, argv, { stdio: "inherit" });
140
+ child.once("error", reject);
141
+ child.once("exit", (code) => resolve(code ?? 0));
142
+ });
143
+ }
144
+ async function runVersionCheck(check) {
145
+ if (!check) return { ok: false, message: "no version_check declared" };
146
+ return new Promise((resolve) => {
147
+ const child = spawn("bash", ["-lc", check.cmd], {
148
+ stdio: ["ignore", "pipe", "ignore"]
149
+ });
150
+ let buf = "";
151
+ child.stdout.on("data", (c) => {
152
+ buf += c.toString("utf8");
153
+ });
154
+ child.once("error", () => resolve({ ok: false, message: "check failed" }));
155
+ child.once("exit", (code) => {
156
+ if (code !== 0) {
157
+ resolve({ ok: false, message: `check exited ${code}` });
158
+ return;
159
+ }
160
+ const re = new RegExp(check.parse);
161
+ const m = buf.match(re);
162
+ if (!m || !m[1]) {
163
+ resolve({ ok: false, message: "could not parse version" });
164
+ return;
165
+ }
166
+ resolve({ ok: true, message: `version ${m[1]}` });
167
+ });
168
+ });
169
+ }
170
+
171
+ // src/util/stdin.ts
172
+ async function readStdinIfPiped() {
173
+ if (process.stdin.isTTY) return null;
174
+ const chunks = [];
175
+ for await (const chunk of process.stdin) {
176
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
177
+ }
178
+ const text = Buffer.concat(chunks).toString("utf8").trim();
179
+ return text.length > 0 ? text : null;
180
+ }
181
+
182
+ // src/commands/run.ts
183
+ async function runRun(args) {
184
+ const { values, positionals } = parseArgs({
185
+ args: [...args],
186
+ allowPositionals: true,
187
+ strict: true,
188
+ options: {
189
+ cwd: { type: "string" },
190
+ prompt: { type: "string", short: "p" },
191
+ resume: { type: "string" },
192
+ json: { type: "boolean" }
193
+ }
194
+ });
195
+ const slug = positionals[0];
196
+ if (!slug) {
197
+ process.stderr.write(
198
+ "agentproto run: missing adapter slug. Try: agentproto run claude-code\n"
199
+ );
200
+ return 2;
201
+ }
202
+ const cwd = values.cwd ? resolve(values.cwd) : process.cwd();
203
+ const promptArg = values.prompt ?? await readStdinIfPiped();
204
+ if (!promptArg) {
205
+ process.stderr.write(
206
+ "agentproto run: no prompt provided. Pass --prompt or pipe one over stdin.\n"
207
+ );
208
+ return 2;
209
+ }
210
+ const adapter = await resolveAdapter(slug);
211
+ const runtime = createAgentCliRuntime(adapter.handle);
212
+ const controller = new AbortController();
213
+ const onSignal = (sig) => {
214
+ process.stderr.write(`
215
+ agentproto: received ${sig}, cancelling\u2026
216
+ `);
217
+ controller.abort();
218
+ };
219
+ process.once("SIGINT", onSignal);
220
+ process.once("SIGTERM", onSignal);
221
+ let session = null;
222
+ try {
223
+ session = await runtime.start({
224
+ cwd,
225
+ signal: controller.signal,
226
+ resumeSessionId: values.resume
227
+ });
228
+ const printer = values.json ? printJson : printPretty;
229
+ let exit = 0;
230
+ for await (const ev of session.send(promptArg)) {
231
+ printer(ev);
232
+ if (ev.kind === "turn-end" && ev.reason !== "completed") exit = 1;
233
+ if (ev.kind === "error") exit = 1;
234
+ }
235
+ return exit;
236
+ } finally {
237
+ process.off("SIGINT", onSignal);
238
+ process.off("SIGTERM", onSignal);
239
+ if (session) await session.close().catch(() => {
240
+ });
241
+ }
242
+ }
243
+ function printJson(ev) {
244
+ process.stdout.write(`${JSON.stringify(ev)}
245
+ `);
246
+ }
247
+ function printPretty(ev) {
248
+ switch (ev.kind) {
249
+ case "text-delta":
250
+ process.stdout.write(ev.text);
251
+ break;
252
+ case "thought":
253
+ process.stderr.write(`\x1B[2m[thought] ${ev.text}\x1B[0m
254
+ `);
255
+ break;
256
+ case "tool-call":
257
+ process.stderr.write(`\x1B[36m[tool] ${ev.toolName}\x1B[0m
258
+ `);
259
+ break;
260
+ case "tool-result":
261
+ if (ev.isError)
262
+ process.stderr.write(`\x1B[31m[tool-error]\x1B[0m
263
+ `);
264
+ break;
265
+ case "agent-prompt":
266
+ process.stderr.write(`\x1B[33m[agent-prompt: needs input]\x1B[0m
267
+ `);
268
+ break;
269
+ case "turn-end":
270
+ process.stdout.write(`
271
+ \x1B[2m[turn-end: ${ev.reason}]\x1B[0m
272
+ `);
273
+ break;
274
+ case "error":
275
+ process.stderr.write(`\x1B[31m[error] ${ev.error.message}\x1B[0m
276
+ `);
277
+ break;
278
+ }
279
+ }
280
+ async function runServe(args) {
281
+ const { values } = parseArgs({
282
+ args: [...args],
283
+ allowPositionals: false,
284
+ strict: true,
285
+ options: {
286
+ connect: { type: "string", short: "c" },
287
+ token: { type: "string", short: "t" },
288
+ label: { type: "string", short: "l" }
289
+ }
290
+ });
291
+ if (!values.connect) {
292
+ process.stderr.write(
293
+ "agentproto serve: --connect <url> is required.\n example: agentproto serve --connect wss://guilde.work/api/v1/agentproto/tunnel --token $TOKEN\n"
294
+ );
295
+ return 2;
296
+ }
297
+ process.stderr.write(
298
+ `agentproto serve: tunnel daemon is not yet implemented in this release.
299
+ Tracking: tunnel frame protocol is landing in @agentproto/acp next.
300
+ Wanted endpoint: ${values.connect}
301
+ Label: ${values.label ?? "(none)"}
302
+ `
303
+ );
304
+ return 64;
305
+ }
306
+
307
+ // src/cli.ts
308
+ var USAGE = `agentproto \u2014 AIP-45 agent CLI host
309
+
310
+ Usage:
311
+ agentproto install <slug> [--registry <path>]
312
+ agentproto run <slug> [--cwd <dir>] [--prompt <text>] [--resume <session-id>]
313
+ agentproto serve --connect <url> [--token <jwt>] [--label <name>]
314
+ agentproto --help
315
+ agentproto --version
316
+
317
+ Examples:
318
+ agentproto install claude-code
319
+ agentproto run claude-code --cwd . --prompt "summarise this repo"
320
+ agentproto serve --connect wss://guilde.work/api/v1/agentproto/tunnel --token $AGENTPROTO_TOKEN
321
+ `;
322
+ async function main(argv) {
323
+ const { values, positionals } = parseArgs({
324
+ args: [...argv],
325
+ allowPositionals: true,
326
+ strict: false,
327
+ options: {
328
+ help: { type: "boolean", short: "h" },
329
+ version: { type: "boolean", short: "v" }
330
+ }
331
+ });
332
+ if (values.help) {
333
+ process.stdout.write(USAGE);
334
+ return 0;
335
+ }
336
+ if (values.version) {
337
+ process.stdout.write("agentproto 0.1.0-alpha\n");
338
+ return 0;
339
+ }
340
+ const [verb, ...rest] = positionals;
341
+ if (!verb) {
342
+ process.stdout.write(USAGE);
343
+ return 0;
344
+ }
345
+ switch (verb) {
346
+ case "install":
347
+ return runInstall(rest);
348
+ case "run":
349
+ return runRun(rest);
350
+ case "serve":
351
+ return runServe(rest);
352
+ default:
353
+ process.stderr.write(`agentproto: unknown verb '${verb}'
354
+
355
+ ${USAGE}`);
356
+ return 2;
357
+ }
358
+ }
359
+ main(process.argv.slice(2)).then(
360
+ (code) => {
361
+ process.exitCode = code;
362
+ },
363
+ (err) => {
364
+ const msg = err instanceof Error ? err.stack ?? err.message : String(err);
365
+ process.stderr.write(`agentproto: ${msg}
366
+ `);
367
+ process.exitCode = 1;
368
+ }
369
+ );
370
+ //# sourceMappingURL=cli.mjs.map
371
+ //# sourceMappingURL=cli.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/registry/resolve.ts","../src/commands/install.ts","../src/util/stdin.ts","../src/commands/run.ts","../src/commands/serve.ts","../src/cli.ts"],"names":["parseArgs","resolvePath"],"mappings":"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","file":"cli.mjs","sourcesContent":["/**\n * Resolve a slug like \"claude-code\" to a runnable `AgentCliHandle`.\n *\n * Resolution order:\n * 1. `@agentproto/adapter-<slug>` from npm (must default-export or\n * named-export an `AgentCliHandle` — convention is the camelCased\n * slug, e.g. `claudeCode`).\n * 2. (TODO) `~/.agentproto/adapters/<slug>/AGENT-CLI.md` on disk.\n * 3. (TODO) bundled fallbacks for the canonical adapters.\n *\n * Step 1 covers 100% of v0 usage. The on-disk path is only there for\n * users authoring their own adapters; we'll add it once `defineAgentCli`\n * supports MD-source authoring end to end.\n */\n\nimport type { AgentCliHandle } from \"@agentproto/driver-agent-cli\"\n\nexport interface ResolvedAdapter {\n readonly slug: string\n readonly handle: AgentCliHandle\n readonly source: \"npm\" | \"file\" | \"bundled\"\n readonly packageName?: string\n}\n\nconst slugToCamel = (slug: string): string =>\n slug.replace(/-([a-z0-9])/g, (_, c: string) => c.toUpperCase())\n\nexport async function resolveAdapter(slug: string): Promise<ResolvedAdapter> {\n if (!/^[a-z][a-z0-9-]*$/.test(slug)) {\n throw new Error(\n `agentproto: invalid adapter slug '${slug}'. Slugs are lower-kebab.`\n )\n }\n\n const packageName = `@agentproto/adapter-${slug}`\n let mod: Record<string, unknown>\n try {\n mod = (await import(packageName)) as Record<string, unknown>\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err)\n throw new Error(\n `agentproto: could not load adapter '${slug}'. ` +\n `Tried '${packageName}'. Install it with: npm i -g ${packageName}\\n cause: ${cause}`\n )\n }\n\n const camel = slugToCamel(slug)\n const candidate =\n (mod[camel] as AgentCliHandle | undefined) ??\n (mod.default as AgentCliHandle | undefined) ??\n (mod.handle as AgentCliHandle | undefined)\n\n if (!candidate || typeof candidate !== \"object\" || !(\"name\" in candidate)) {\n throw new Error(\n `agentproto: adapter '${packageName}' does not export an AgentCliHandle ` +\n `(looked for export '${camel}', 'default', or 'handle').`\n )\n }\n\n return { slug, handle: candidate, source: \"npm\", packageName }\n}\n","/**\n * `agentproto install <slug>`\n *\n * Reads the adapter manifest's `install` block and shells out to the\n * declared package manager. Idempotent: if `version_check` passes, we\n * skip and report \"already installed\" (override with --force).\n *\n * The adapter package itself must already be in node_modules (we resolve\n * it before reading its manifest). Bootstrapping the adapter package is\n * a separate concern — `npm i -g @agentproto/adapter-<slug>` first.\n *\n * v0 implements `npm` only. Other methods (brew/pip/cargo/go/curl/\n * download) report a clear \"not yet implemented\" message — they're a\n * shellout exercise but each needs its own checksum / chmod handling.\n */\n\nimport { spawn } from \"node:child_process\"\nimport { parseArgs } from \"node:util\"\nimport type { AgentCliInstallMethod } from \"@agentproto/driver-agent-cli\"\nimport { resolveAdapter } from \"../registry/resolve.js\"\n\nexport async function runInstall(args: readonly string[]): Promise<number> {\n const { values, positionals } = parseArgs({\n args: [...args],\n allowPositionals: true,\n strict: true,\n options: {\n force: { type: \"boolean\", short: \"f\" },\n \"dry-run\": { type: \"boolean\" },\n },\n })\n\n const slug = positionals[0]\n if (!slug) {\n process.stderr.write(\n \"agentproto install: missing adapter slug. Try: agentproto install claude-code\\n\"\n )\n return 2\n }\n\n const adapter = await resolveAdapter(slug)\n const installSteps: AgentCliInstallMethod[] = adapter.handle.install ?? []\n if (installSteps.length === 0) {\n process.stderr.write(\n `agentproto install: adapter '${slug}' declares no install steps.\\n`\n )\n return 0\n }\n\n if (!values.force) {\n const checked = await runVersionCheck(adapter.handle.version_check)\n if (checked.ok) {\n process.stdout.write(\n `agentproto: '${slug}' already installed (${checked.message}). Pass --force to reinstall.\\n`\n )\n return 0\n }\n }\n\n for (const [i, step] of installSteps.entries()) {\n process.stdout.write(\n `agentproto install [${i + 1}/${installSteps.length}] ${describeStep(step)}\\n`\n )\n if (values[\"dry-run\"]) continue\n const code = await runStep(step)\n if (code !== 0) {\n process.stderr.write(\n `agentproto install: step ${i + 1} failed with exit ${code}.\\n`\n )\n return code\n }\n }\n\n process.stdout.write(`agentproto: '${slug}' installed.\\n`)\n return 0\n}\n\nfunction describeStep(step: AgentCliInstallMethod): string {\n switch (step.method) {\n case \"npm\":\n return `npm install ${step.global ? \"-g \" : \"\"}${step.package ?? \"(?)\"}`\n case \"brew\":\n return `brew install ${step.package ?? \"(?)\"}`\n case \"pip\":\n return `pip install ${step.package ?? \"(?)\"}`\n case \"cargo\":\n return `cargo install ${step.package ?? \"(?)\"}`\n case \"go\":\n return `go install ${step.package ?? \"(?)\"}`\n case \"curl\":\n case \"download\":\n return `${step.method} ${step.url ?? \"(?)\"} → ${step.path ?? \"(default)\"}`\n default:\n return `${step.method} ${step.package ?? step.url ?? \"(?)\"}`\n }\n}\n\nasync function runStep(step: AgentCliInstallMethod): Promise<number> {\n switch (step.method) {\n case \"npm\": {\n if (!step.package) {\n process.stderr.write(\"agentproto install: npm step missing package.\\n\")\n return 2\n }\n const argv = [\"install\"]\n if (step.global) argv.push(\"-g\")\n argv.push(step.package)\n return spawnInherit(\"npm\", argv)\n }\n default:\n process.stderr.write(\n `agentproto install: method '${step.method}' not yet implemented in this CLI version. ` +\n `Run it manually for now (see the adapter's INSTALL.md).\\n`\n )\n return 1\n }\n}\n\nfunction spawnInherit(cmd: string, argv: string[]): Promise<number> {\n return new Promise((resolve, reject) => {\n const child = spawn(cmd, argv, { stdio: \"inherit\" })\n child.once(\"error\", reject)\n child.once(\"exit\", (code) => resolve(code ?? 0))\n })\n}\n\nasync function runVersionCheck(\n check: Awaited<\n ReturnType<typeof resolveAdapter>\n >[\"handle\"][\"version_check\"]\n): Promise<{ ok: boolean; message: string }> {\n if (!check) return { ok: false, message: \"no version_check declared\" }\n return new Promise((resolve) => {\n const child = spawn(\"bash\", [\"-lc\", check.cmd], {\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n })\n let buf = \"\"\n child.stdout.on(\"data\", (c: Buffer) => {\n buf += c.toString(\"utf8\")\n })\n child.once(\"error\", () => resolve({ ok: false, message: \"check failed\" }))\n child.once(\"exit\", (code) => {\n if (code !== 0) {\n resolve({ ok: false, message: `check exited ${code}` })\n return\n }\n const re = new RegExp(check.parse)\n const m = buf.match(re)\n if (!m || !m[1]) {\n resolve({ ok: false, message: \"could not parse version\" })\n return\n }\n // semver-range matching is left to a future helper; we report\n // the captured version and trust it. --force remains the\n // escape hatch when range gating actually matters.\n resolve({ ok: true, message: `version ${m[1]}` })\n })\n })\n}\n","/**\n * Read piped stdin to a string. Returns null if stdin is a TTY (no pipe).\n * Used by `agentproto run` to accept prompts via:\n * echo \"summarise this repo\" | agentproto run claude-code\n */\n\nexport async function readStdinIfPiped(): Promise<string | null> {\n if (process.stdin.isTTY) return null\n const chunks: Buffer[] = []\n for await (const chunk of process.stdin) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))\n }\n const text = Buffer.concat(chunks).toString(\"utf8\").trim()\n return text.length > 0 ? text : null\n}\n","/**\n * `agentproto run <slug> [--cwd <dir>] [--prompt <text>] [--resume <id>]`\n *\n * Boots the named adapter, dispatches a single user turn, streams events\n * to stdout, then exits. Designed for two use-cases:\n * - one-shot scripting (pipe a prompt in, get stream back)\n * - quick smoke-test from a fresh checkout (\"does claude even spawn?\")\n *\n * Long-lived multiplexing belongs to `agentproto serve`, not here.\n */\n\nimport { resolve as resolvePath } from \"node:path\"\nimport { parseArgs } from \"node:util\"\nimport {\n createAgentCliRuntime,\n type AgentCliRuntimeSession,\n type StreamEvent,\n} from \"@agentproto/driver-agent-cli\"\nimport { resolveAdapter } from \"../registry/resolve.js\"\nimport { readStdinIfPiped } from \"../util/stdin.js\"\n\nexport async function runRun(args: readonly string[]): Promise<number> {\n const { values, positionals } = parseArgs({\n args: [...args],\n allowPositionals: true,\n strict: true,\n options: {\n cwd: { type: \"string\" },\n prompt: { type: \"string\", short: \"p\" },\n resume: { type: \"string\" },\n json: { type: \"boolean\" },\n },\n })\n\n const slug = positionals[0]\n if (!slug) {\n process.stderr.write(\n \"agentproto run: missing adapter slug. Try: agentproto run claude-code\\n\"\n )\n return 2\n }\n\n const cwd = values.cwd ? resolvePath(values.cwd) : process.cwd()\n const promptArg = values.prompt ?? (await readStdinIfPiped())\n if (!promptArg) {\n process.stderr.write(\n \"agentproto run: no prompt provided. Pass --prompt or pipe one over stdin.\\n\"\n )\n return 2\n }\n\n const adapter = await resolveAdapter(slug)\n const runtime = createAgentCliRuntime(adapter.handle)\n\n const controller = new AbortController()\n const onSignal = (sig: NodeJS.Signals) => {\n process.stderr.write(`\\nagentproto: received ${sig}, cancelling…\\n`)\n controller.abort()\n }\n process.once(\"SIGINT\", onSignal)\n process.once(\"SIGTERM\", onSignal)\n\n let session: AgentCliRuntimeSession | null = null\n try {\n session = await runtime.start({\n cwd,\n signal: controller.signal,\n resumeSessionId: values.resume,\n })\n\n const printer = values.json ? printJson : printPretty\n let exit = 0\n for await (const ev of session.send(promptArg)) {\n printer(ev)\n if (ev.kind === \"turn-end\" && ev.reason !== \"completed\") exit = 1\n if (ev.kind === \"error\") exit = 1\n }\n return exit\n } finally {\n process.off(\"SIGINT\", onSignal)\n process.off(\"SIGTERM\", onSignal)\n if (session) await session.close().catch(() => {})\n }\n}\n\nfunction printJson(ev: StreamEvent): void {\n process.stdout.write(`${JSON.stringify(ev)}\\n`)\n}\n\nfunction printPretty(ev: StreamEvent): void {\n switch (ev.kind) {\n case \"text-delta\":\n process.stdout.write(ev.text)\n break\n case \"thought\":\n process.stderr.write(`\\x1b[2m[thought] ${ev.text}\\x1b[0m\\n`)\n break\n case \"tool-call\":\n process.stderr.write(`\\x1b[36m[tool] ${ev.toolName}\\x1b[0m\\n`)\n break\n case \"tool-result\":\n if (ev.isError)\n process.stderr.write(`\\x1b[31m[tool-error]\\x1b[0m\\n`)\n break\n case \"agent-prompt\":\n process.stderr.write(`\\x1b[33m[agent-prompt: needs input]\\x1b[0m\\n`)\n break\n case \"turn-end\":\n process.stdout.write(`\\n\\x1b[2m[turn-end: ${ev.reason}]\\x1b[0m\\n`)\n break\n case \"error\":\n process.stderr.write(`\\x1b[31m[error] ${ev.error.message}\\x1b[0m\\n`)\n break\n }\n}\n","/**\n * `agentproto serve --connect <url>`\n *\n * Long-running daemon. Opens a WebSocket to a host (Guilde-shaped API),\n * authenticates with a token, then accepts spawn / stdin / stdout /\n * stderr / kill / exit frames over that channel — multiplexing many\n * ACP sessions through one process. The daemon owns local resources\n * (PTYs, child processes, JSONL session stores) so a host running in\n * the cloud can drive a CLI living on the user's laptop.\n *\n * v0.1 stub: argument parsing + connection scaffolding only. The wire\n * protocol is still being designed (tunnel frames need to land in\n * @agentproto/acp first); shipping a half-baked daemon would lock us\n * into the wrong shape. For now this verb prints a clear \"not yet\"\n * and exits non-zero so CI pipelines don't accidentally rely on it.\n */\n\nimport { parseArgs } from \"node:util\"\n\nexport async function runServe(args: readonly string[]): Promise<number> {\n const { values } = parseArgs({\n args: [...args],\n allowPositionals: false,\n strict: true,\n options: {\n connect: { type: \"string\", short: \"c\" },\n token: { type: \"string\", short: \"t\" },\n label: { type: \"string\", short: \"l\" },\n },\n })\n\n if (!values.connect) {\n process.stderr.write(\n \"agentproto serve: --connect <url> is required.\\n\" +\n \" example: agentproto serve --connect wss://guilde.work/api/v1/agentproto/tunnel --token $TOKEN\\n\"\n )\n return 2\n }\n\n process.stderr.write(\n \"agentproto serve: tunnel daemon is not yet implemented in this release.\\n\" +\n \" Tracking: tunnel frame protocol is landing in @agentproto/acp next.\\n\" +\n ` Wanted endpoint: ${values.connect}\\n` +\n ` Label: ${values.label ?? \"(none)\"}\\n`\n )\n return 64\n}\n","#!/usr/bin/env node\n/**\n * `agentproto` — the binary entry. Three verbs:\n *\n * agentproto install <slug> install an adapter's underlying CLI\n * agentproto run <slug> [--cwd <dir>] spawn the adapter and stream a turn\n * agentproto serve --connect <url> daemon — relay spawns over WS\n *\n * Adapter slugs resolve through the registry (see ./registry/resolve.ts).\n * Out of the box we ship `claude-code`, `hermes` etc. via npm-installed\n * `@agentproto/adapter-<slug>` packages.\n */\n\nimport { parseArgs } from \"node:util\"\nimport { runInstall } from \"./commands/install.js\"\nimport { runRun } from \"./commands/run.js\"\nimport { runServe } from \"./commands/serve.js\"\n\nconst USAGE = `agentproto — AIP-45 agent CLI host\n\nUsage:\n agentproto install <slug> [--registry <path>]\n agentproto run <slug> [--cwd <dir>] [--prompt <text>] [--resume <session-id>]\n agentproto serve --connect <url> [--token <jwt>] [--label <name>]\n agentproto --help\n agentproto --version\n\nExamples:\n agentproto install claude-code\n agentproto run claude-code --cwd . --prompt \"summarise this repo\"\n agentproto serve --connect wss://guilde.work/api/v1/agentproto/tunnel --token \\$AGENTPROTO_TOKEN\n`\n\nasync function main(argv: readonly string[]): Promise<number> {\n const { values, positionals } = parseArgs({\n args: [...argv],\n allowPositionals: true,\n strict: false,\n options: {\n help: { type: \"boolean\", short: \"h\" },\n version: { type: \"boolean\", short: \"v\" },\n },\n })\n\n if (values.help) {\n process.stdout.write(USAGE)\n return 0\n }\n if (values.version) {\n process.stdout.write(\"agentproto 0.1.0-alpha\\n\")\n return 0\n }\n\n const [verb, ...rest] = positionals\n if (!verb) {\n process.stdout.write(USAGE)\n return 0\n }\n\n switch (verb) {\n case \"install\":\n return runInstall(rest)\n case \"run\":\n return runRun(rest)\n case \"serve\":\n return runServe(rest)\n default:\n process.stderr.write(`agentproto: unknown verb '${verb}'\\n\\n${USAGE}`)\n return 2\n }\n}\n\nmain(process.argv.slice(2)).then(\n (code) => {\n process.exitCode = code\n },\n (err: unknown) => {\n const msg = err instanceof Error ? err.stack ?? err.message : String(err)\n process.stderr.write(`agentproto: ${msg}\\n`)\n process.exitCode = 1\n }\n)\n"]}
@@ -0,0 +1,73 @@
1
+ import { AgentCliHandle } from '@agentproto/driver-agent-cli';
2
+
3
+ /**
4
+ * `agentproto install <slug>`
5
+ *
6
+ * Reads the adapter manifest's `install` block and shells out to the
7
+ * declared package manager. Idempotent: if `version_check` passes, we
8
+ * skip and report "already installed" (override with --force).
9
+ *
10
+ * The adapter package itself must already be in node_modules (we resolve
11
+ * it before reading its manifest). Bootstrapping the adapter package is
12
+ * a separate concern — `npm i -g @agentproto/adapter-<slug>` first.
13
+ *
14
+ * v0 implements `npm` only. Other methods (brew/pip/cargo/go/curl/
15
+ * download) report a clear "not yet implemented" message — they're a
16
+ * shellout exercise but each needs its own checksum / chmod handling.
17
+ */
18
+ declare function runInstall(args: readonly string[]): Promise<number>;
19
+
20
+ /**
21
+ * `agentproto run <slug> [--cwd <dir>] [--prompt <text>] [--resume <id>]`
22
+ *
23
+ * Boots the named adapter, dispatches a single user turn, streams events
24
+ * to stdout, then exits. Designed for two use-cases:
25
+ * - one-shot scripting (pipe a prompt in, get stream back)
26
+ * - quick smoke-test from a fresh checkout ("does claude even spawn?")
27
+ *
28
+ * Long-lived multiplexing belongs to `agentproto serve`, not here.
29
+ */
30
+ declare function runRun(args: readonly string[]): Promise<number>;
31
+
32
+ /**
33
+ * `agentproto serve --connect <url>`
34
+ *
35
+ * Long-running daemon. Opens a WebSocket to a host (Guilde-shaped API),
36
+ * authenticates with a token, then accepts spawn / stdin / stdout /
37
+ * stderr / kill / exit frames over that channel — multiplexing many
38
+ * ACP sessions through one process. The daemon owns local resources
39
+ * (PTYs, child processes, JSONL session stores) so a host running in
40
+ * the cloud can drive a CLI living on the user's laptop.
41
+ *
42
+ * v0.1 stub: argument parsing + connection scaffolding only. The wire
43
+ * protocol is still being designed (tunnel frames need to land in
44
+ * @agentproto/acp first); shipping a half-baked daemon would lock us
45
+ * into the wrong shape. For now this verb prints a clear "not yet"
46
+ * and exits non-zero so CI pipelines don't accidentally rely on it.
47
+ */
48
+ declare function runServe(args: readonly string[]): Promise<number>;
49
+
50
+ /**
51
+ * Resolve a slug like "claude-code" to a runnable `AgentCliHandle`.
52
+ *
53
+ * Resolution order:
54
+ * 1. `@agentproto/adapter-<slug>` from npm (must default-export or
55
+ * named-export an `AgentCliHandle` — convention is the camelCased
56
+ * slug, e.g. `claudeCode`).
57
+ * 2. (TODO) `~/.agentproto/adapters/<slug>/AGENT-CLI.md` on disk.
58
+ * 3. (TODO) bundled fallbacks for the canonical adapters.
59
+ *
60
+ * Step 1 covers 100% of v0 usage. The on-disk path is only there for
61
+ * users authoring their own adapters; we'll add it once `defineAgentCli`
62
+ * supports MD-source authoring end to end.
63
+ */
64
+
65
+ interface ResolvedAdapter {
66
+ readonly slug: string;
67
+ readonly handle: AgentCliHandle;
68
+ readonly source: "npm" | "file" | "bundled";
69
+ readonly packageName?: string;
70
+ }
71
+ declare function resolveAdapter(slug: string): Promise<ResolvedAdapter>;
72
+
73
+ export { type ResolvedAdapter, resolveAdapter, runInstall, runRun, runServe };
package/dist/index.mjs ADDED
@@ -0,0 +1,308 @@
1
+ import { spawn } from 'child_process';
2
+ import { parseArgs } from 'util';
3
+ import { resolve } from 'path';
4
+ import { createAgentCliRuntime } from '@agentproto/driver-agent-cli';
5
+
6
+ /**
7
+ * @agentproto/cli v0.1.0-alpha
8
+ * The `agentproto` binary — install / run / serve AIP-45 agent CLIs.
9
+ */
10
+
11
+
12
+ // src/registry/resolve.ts
13
+ var slugToCamel = (slug) => slug.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
14
+ async function resolveAdapter(slug) {
15
+ if (!/^[a-z][a-z0-9-]*$/.test(slug)) {
16
+ throw new Error(
17
+ `agentproto: invalid adapter slug '${slug}'. Slugs are lower-kebab.`
18
+ );
19
+ }
20
+ const packageName = `@agentproto/adapter-${slug}`;
21
+ let mod;
22
+ try {
23
+ mod = await import(packageName);
24
+ } catch (err) {
25
+ const cause = err instanceof Error ? err.message : String(err);
26
+ throw new Error(
27
+ `agentproto: could not load adapter '${slug}'. Tried '${packageName}'. Install it with: npm i -g ${packageName}
28
+ cause: ${cause}`
29
+ );
30
+ }
31
+ const camel = slugToCamel(slug);
32
+ const candidate = mod[camel] ?? mod.default ?? mod.handle;
33
+ if (!candidate || typeof candidate !== "object" || !("name" in candidate)) {
34
+ throw new Error(
35
+ `agentproto: adapter '${packageName}' does not export an AgentCliHandle (looked for export '${camel}', 'default', or 'handle').`
36
+ );
37
+ }
38
+ return { slug, handle: candidate, source: "npm", packageName };
39
+ }
40
+
41
+ // src/commands/install.ts
42
+ async function runInstall(args) {
43
+ const { values, positionals } = parseArgs({
44
+ args: [...args],
45
+ allowPositionals: true,
46
+ strict: true,
47
+ options: {
48
+ force: { type: "boolean", short: "f" },
49
+ "dry-run": { type: "boolean" }
50
+ }
51
+ });
52
+ const slug = positionals[0];
53
+ if (!slug) {
54
+ process.stderr.write(
55
+ "agentproto install: missing adapter slug. Try: agentproto install claude-code\n"
56
+ );
57
+ return 2;
58
+ }
59
+ const adapter = await resolveAdapter(slug);
60
+ const installSteps = adapter.handle.install ?? [];
61
+ if (installSteps.length === 0) {
62
+ process.stderr.write(
63
+ `agentproto install: adapter '${slug}' declares no install steps.
64
+ `
65
+ );
66
+ return 0;
67
+ }
68
+ if (!values.force) {
69
+ const checked = await runVersionCheck(adapter.handle.version_check);
70
+ if (checked.ok) {
71
+ process.stdout.write(
72
+ `agentproto: '${slug}' already installed (${checked.message}). Pass --force to reinstall.
73
+ `
74
+ );
75
+ return 0;
76
+ }
77
+ }
78
+ for (const [i, step] of installSteps.entries()) {
79
+ process.stdout.write(
80
+ `agentproto install [${i + 1}/${installSteps.length}] ${describeStep(step)}
81
+ `
82
+ );
83
+ if (values["dry-run"]) continue;
84
+ const code = await runStep(step);
85
+ if (code !== 0) {
86
+ process.stderr.write(
87
+ `agentproto install: step ${i + 1} failed with exit ${code}.
88
+ `
89
+ );
90
+ return code;
91
+ }
92
+ }
93
+ process.stdout.write(`agentproto: '${slug}' installed.
94
+ `);
95
+ return 0;
96
+ }
97
+ function describeStep(step) {
98
+ switch (step.method) {
99
+ case "npm":
100
+ return `npm install ${step.global ? "-g " : ""}${step.package ?? "(?)"}`;
101
+ case "brew":
102
+ return `brew install ${step.package ?? "(?)"}`;
103
+ case "pip":
104
+ return `pip install ${step.package ?? "(?)"}`;
105
+ case "cargo":
106
+ return `cargo install ${step.package ?? "(?)"}`;
107
+ case "go":
108
+ return `go install ${step.package ?? "(?)"}`;
109
+ case "curl":
110
+ case "download":
111
+ return `${step.method} ${step.url ?? "(?)"} \u2192 ${step.path ?? "(default)"}`;
112
+ default:
113
+ return `${step.method} ${step.package ?? step.url ?? "(?)"}`;
114
+ }
115
+ }
116
+ async function runStep(step) {
117
+ switch (step.method) {
118
+ case "npm": {
119
+ if (!step.package) {
120
+ process.stderr.write("agentproto install: npm step missing package.\n");
121
+ return 2;
122
+ }
123
+ const argv = ["install"];
124
+ if (step.global) argv.push("-g");
125
+ argv.push(step.package);
126
+ return spawnInherit("npm", argv);
127
+ }
128
+ default:
129
+ process.stderr.write(
130
+ `agentproto install: method '${step.method}' not yet implemented in this CLI version. Run it manually for now (see the adapter's INSTALL.md).
131
+ `
132
+ );
133
+ return 1;
134
+ }
135
+ }
136
+ function spawnInherit(cmd, argv) {
137
+ return new Promise((resolve, reject) => {
138
+ const child = spawn(cmd, argv, { stdio: "inherit" });
139
+ child.once("error", reject);
140
+ child.once("exit", (code) => resolve(code ?? 0));
141
+ });
142
+ }
143
+ async function runVersionCheck(check) {
144
+ if (!check) return { ok: false, message: "no version_check declared" };
145
+ return new Promise((resolve) => {
146
+ const child = spawn("bash", ["-lc", check.cmd], {
147
+ stdio: ["ignore", "pipe", "ignore"]
148
+ });
149
+ let buf = "";
150
+ child.stdout.on("data", (c) => {
151
+ buf += c.toString("utf8");
152
+ });
153
+ child.once("error", () => resolve({ ok: false, message: "check failed" }));
154
+ child.once("exit", (code) => {
155
+ if (code !== 0) {
156
+ resolve({ ok: false, message: `check exited ${code}` });
157
+ return;
158
+ }
159
+ const re = new RegExp(check.parse);
160
+ const m = buf.match(re);
161
+ if (!m || !m[1]) {
162
+ resolve({ ok: false, message: "could not parse version" });
163
+ return;
164
+ }
165
+ resolve({ ok: true, message: `version ${m[1]}` });
166
+ });
167
+ });
168
+ }
169
+
170
+ // src/util/stdin.ts
171
+ async function readStdinIfPiped() {
172
+ if (process.stdin.isTTY) return null;
173
+ const chunks = [];
174
+ for await (const chunk of process.stdin) {
175
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
176
+ }
177
+ const text = Buffer.concat(chunks).toString("utf8").trim();
178
+ return text.length > 0 ? text : null;
179
+ }
180
+
181
+ // src/commands/run.ts
182
+ async function runRun(args) {
183
+ const { values, positionals } = parseArgs({
184
+ args: [...args],
185
+ allowPositionals: true,
186
+ strict: true,
187
+ options: {
188
+ cwd: { type: "string" },
189
+ prompt: { type: "string", short: "p" },
190
+ resume: { type: "string" },
191
+ json: { type: "boolean" }
192
+ }
193
+ });
194
+ const slug = positionals[0];
195
+ if (!slug) {
196
+ process.stderr.write(
197
+ "agentproto run: missing adapter slug. Try: agentproto run claude-code\n"
198
+ );
199
+ return 2;
200
+ }
201
+ const cwd = values.cwd ? resolve(values.cwd) : process.cwd();
202
+ const promptArg = values.prompt ?? await readStdinIfPiped();
203
+ if (!promptArg) {
204
+ process.stderr.write(
205
+ "agentproto run: no prompt provided. Pass --prompt or pipe one over stdin.\n"
206
+ );
207
+ return 2;
208
+ }
209
+ const adapter = await resolveAdapter(slug);
210
+ const runtime = createAgentCliRuntime(adapter.handle);
211
+ const controller = new AbortController();
212
+ const onSignal = (sig) => {
213
+ process.stderr.write(`
214
+ agentproto: received ${sig}, cancelling\u2026
215
+ `);
216
+ controller.abort();
217
+ };
218
+ process.once("SIGINT", onSignal);
219
+ process.once("SIGTERM", onSignal);
220
+ let session = null;
221
+ try {
222
+ session = await runtime.start({
223
+ cwd,
224
+ signal: controller.signal,
225
+ resumeSessionId: values.resume
226
+ });
227
+ const printer = values.json ? printJson : printPretty;
228
+ let exit = 0;
229
+ for await (const ev of session.send(promptArg)) {
230
+ printer(ev);
231
+ if (ev.kind === "turn-end" && ev.reason !== "completed") exit = 1;
232
+ if (ev.kind === "error") exit = 1;
233
+ }
234
+ return exit;
235
+ } finally {
236
+ process.off("SIGINT", onSignal);
237
+ process.off("SIGTERM", onSignal);
238
+ if (session) await session.close().catch(() => {
239
+ });
240
+ }
241
+ }
242
+ function printJson(ev) {
243
+ process.stdout.write(`${JSON.stringify(ev)}
244
+ `);
245
+ }
246
+ function printPretty(ev) {
247
+ switch (ev.kind) {
248
+ case "text-delta":
249
+ process.stdout.write(ev.text);
250
+ break;
251
+ case "thought":
252
+ process.stderr.write(`\x1B[2m[thought] ${ev.text}\x1B[0m
253
+ `);
254
+ break;
255
+ case "tool-call":
256
+ process.stderr.write(`\x1B[36m[tool] ${ev.toolName}\x1B[0m
257
+ `);
258
+ break;
259
+ case "tool-result":
260
+ if (ev.isError)
261
+ process.stderr.write(`\x1B[31m[tool-error]\x1B[0m
262
+ `);
263
+ break;
264
+ case "agent-prompt":
265
+ process.stderr.write(`\x1B[33m[agent-prompt: needs input]\x1B[0m
266
+ `);
267
+ break;
268
+ case "turn-end":
269
+ process.stdout.write(`
270
+ \x1B[2m[turn-end: ${ev.reason}]\x1B[0m
271
+ `);
272
+ break;
273
+ case "error":
274
+ process.stderr.write(`\x1B[31m[error] ${ev.error.message}\x1B[0m
275
+ `);
276
+ break;
277
+ }
278
+ }
279
+ async function runServe(args) {
280
+ const { values } = parseArgs({
281
+ args: [...args],
282
+ allowPositionals: false,
283
+ strict: true,
284
+ options: {
285
+ connect: { type: "string", short: "c" },
286
+ token: { type: "string", short: "t" },
287
+ label: { type: "string", short: "l" }
288
+ }
289
+ });
290
+ if (!values.connect) {
291
+ process.stderr.write(
292
+ "agentproto serve: --connect <url> is required.\n example: agentproto serve --connect wss://guilde.work/api/v1/agentproto/tunnel --token $TOKEN\n"
293
+ );
294
+ return 2;
295
+ }
296
+ process.stderr.write(
297
+ `agentproto serve: tunnel daemon is not yet implemented in this release.
298
+ Tracking: tunnel frame protocol is landing in @agentproto/acp next.
299
+ Wanted endpoint: ${values.connect}
300
+ Label: ${values.label ?? "(none)"}
301
+ `
302
+ );
303
+ return 64;
304
+ }
305
+
306
+ export { resolveAdapter, runInstall, runRun, runServe };
307
+ //# sourceMappingURL=index.mjs.map
308
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/registry/resolve.ts","../src/commands/install.ts","../src/util/stdin.ts","../src/commands/run.ts","../src/commands/serve.ts"],"names":["parseArgs","resolvePath"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Resolve a slug like \"claude-code\" to a runnable `AgentCliHandle`.\n *\n * Resolution order:\n * 1. `@agentproto/adapter-<slug>` from npm (must default-export or\n * named-export an `AgentCliHandle` — convention is the camelCased\n * slug, e.g. `claudeCode`).\n * 2. (TODO) `~/.agentproto/adapters/<slug>/AGENT-CLI.md` on disk.\n * 3. (TODO) bundled fallbacks for the canonical adapters.\n *\n * Step 1 covers 100% of v0 usage. The on-disk path is only there for\n * users authoring their own adapters; we'll add it once `defineAgentCli`\n * supports MD-source authoring end to end.\n */\n\nimport type { AgentCliHandle } from \"@agentproto/driver-agent-cli\"\n\nexport interface ResolvedAdapter {\n readonly slug: string\n readonly handle: AgentCliHandle\n readonly source: \"npm\" | \"file\" | \"bundled\"\n readonly packageName?: string\n}\n\nconst slugToCamel = (slug: string): string =>\n slug.replace(/-([a-z0-9])/g, (_, c: string) => c.toUpperCase())\n\nexport async function resolveAdapter(slug: string): Promise<ResolvedAdapter> {\n if (!/^[a-z][a-z0-9-]*$/.test(slug)) {\n throw new Error(\n `agentproto: invalid adapter slug '${slug}'. Slugs are lower-kebab.`\n )\n }\n\n const packageName = `@agentproto/adapter-${slug}`\n let mod: Record<string, unknown>\n try {\n mod = (await import(packageName)) as Record<string, unknown>\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err)\n throw new Error(\n `agentproto: could not load adapter '${slug}'. ` +\n `Tried '${packageName}'. Install it with: npm i -g ${packageName}\\n cause: ${cause}`\n )\n }\n\n const camel = slugToCamel(slug)\n const candidate =\n (mod[camel] as AgentCliHandle | undefined) ??\n (mod.default as AgentCliHandle | undefined) ??\n (mod.handle as AgentCliHandle | undefined)\n\n if (!candidate || typeof candidate !== \"object\" || !(\"name\" in candidate)) {\n throw new Error(\n `agentproto: adapter '${packageName}' does not export an AgentCliHandle ` +\n `(looked for export '${camel}', 'default', or 'handle').`\n )\n }\n\n return { slug, handle: candidate, source: \"npm\", packageName }\n}\n","/**\n * `agentproto install <slug>`\n *\n * Reads the adapter manifest's `install` block and shells out to the\n * declared package manager. Idempotent: if `version_check` passes, we\n * skip and report \"already installed\" (override with --force).\n *\n * The adapter package itself must already be in node_modules (we resolve\n * it before reading its manifest). Bootstrapping the adapter package is\n * a separate concern — `npm i -g @agentproto/adapter-<slug>` first.\n *\n * v0 implements `npm` only. Other methods (brew/pip/cargo/go/curl/\n * download) report a clear \"not yet implemented\" message — they're a\n * shellout exercise but each needs its own checksum / chmod handling.\n */\n\nimport { spawn } from \"node:child_process\"\nimport { parseArgs } from \"node:util\"\nimport type { AgentCliInstallMethod } from \"@agentproto/driver-agent-cli\"\nimport { resolveAdapter } from \"../registry/resolve.js\"\n\nexport async function runInstall(args: readonly string[]): Promise<number> {\n const { values, positionals } = parseArgs({\n args: [...args],\n allowPositionals: true,\n strict: true,\n options: {\n force: { type: \"boolean\", short: \"f\" },\n \"dry-run\": { type: \"boolean\" },\n },\n })\n\n const slug = positionals[0]\n if (!slug) {\n process.stderr.write(\n \"agentproto install: missing adapter slug. Try: agentproto install claude-code\\n\"\n )\n return 2\n }\n\n const adapter = await resolveAdapter(slug)\n const installSteps: AgentCliInstallMethod[] = adapter.handle.install ?? []\n if (installSteps.length === 0) {\n process.stderr.write(\n `agentproto install: adapter '${slug}' declares no install steps.\\n`\n )\n return 0\n }\n\n if (!values.force) {\n const checked = await runVersionCheck(adapter.handle.version_check)\n if (checked.ok) {\n process.stdout.write(\n `agentproto: '${slug}' already installed (${checked.message}). Pass --force to reinstall.\\n`\n )\n return 0\n }\n }\n\n for (const [i, step] of installSteps.entries()) {\n process.stdout.write(\n `agentproto install [${i + 1}/${installSteps.length}] ${describeStep(step)}\\n`\n )\n if (values[\"dry-run\"]) continue\n const code = await runStep(step)\n if (code !== 0) {\n process.stderr.write(\n `agentproto install: step ${i + 1} failed with exit ${code}.\\n`\n )\n return code\n }\n }\n\n process.stdout.write(`agentproto: '${slug}' installed.\\n`)\n return 0\n}\n\nfunction describeStep(step: AgentCliInstallMethod): string {\n switch (step.method) {\n case \"npm\":\n return `npm install ${step.global ? \"-g \" : \"\"}${step.package ?? \"(?)\"}`\n case \"brew\":\n return `brew install ${step.package ?? \"(?)\"}`\n case \"pip\":\n return `pip install ${step.package ?? \"(?)\"}`\n case \"cargo\":\n return `cargo install ${step.package ?? \"(?)\"}`\n case \"go\":\n return `go install ${step.package ?? \"(?)\"}`\n case \"curl\":\n case \"download\":\n return `${step.method} ${step.url ?? \"(?)\"} → ${step.path ?? \"(default)\"}`\n default:\n return `${step.method} ${step.package ?? step.url ?? \"(?)\"}`\n }\n}\n\nasync function runStep(step: AgentCliInstallMethod): Promise<number> {\n switch (step.method) {\n case \"npm\": {\n if (!step.package) {\n process.stderr.write(\"agentproto install: npm step missing package.\\n\")\n return 2\n }\n const argv = [\"install\"]\n if (step.global) argv.push(\"-g\")\n argv.push(step.package)\n return spawnInherit(\"npm\", argv)\n }\n default:\n process.stderr.write(\n `agentproto install: method '${step.method}' not yet implemented in this CLI version. ` +\n `Run it manually for now (see the adapter's INSTALL.md).\\n`\n )\n return 1\n }\n}\n\nfunction spawnInherit(cmd: string, argv: string[]): Promise<number> {\n return new Promise((resolve, reject) => {\n const child = spawn(cmd, argv, { stdio: \"inherit\" })\n child.once(\"error\", reject)\n child.once(\"exit\", (code) => resolve(code ?? 0))\n })\n}\n\nasync function runVersionCheck(\n check: Awaited<\n ReturnType<typeof resolveAdapter>\n >[\"handle\"][\"version_check\"]\n): Promise<{ ok: boolean; message: string }> {\n if (!check) return { ok: false, message: \"no version_check declared\" }\n return new Promise((resolve) => {\n const child = spawn(\"bash\", [\"-lc\", check.cmd], {\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n })\n let buf = \"\"\n child.stdout.on(\"data\", (c: Buffer) => {\n buf += c.toString(\"utf8\")\n })\n child.once(\"error\", () => resolve({ ok: false, message: \"check failed\" }))\n child.once(\"exit\", (code) => {\n if (code !== 0) {\n resolve({ ok: false, message: `check exited ${code}` })\n return\n }\n const re = new RegExp(check.parse)\n const m = buf.match(re)\n if (!m || !m[1]) {\n resolve({ ok: false, message: \"could not parse version\" })\n return\n }\n // semver-range matching is left to a future helper; we report\n // the captured version and trust it. --force remains the\n // escape hatch when range gating actually matters.\n resolve({ ok: true, message: `version ${m[1]}` })\n })\n })\n}\n","/**\n * Read piped stdin to a string. Returns null if stdin is a TTY (no pipe).\n * Used by `agentproto run` to accept prompts via:\n * echo \"summarise this repo\" | agentproto run claude-code\n */\n\nexport async function readStdinIfPiped(): Promise<string | null> {\n if (process.stdin.isTTY) return null\n const chunks: Buffer[] = []\n for await (const chunk of process.stdin) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))\n }\n const text = Buffer.concat(chunks).toString(\"utf8\").trim()\n return text.length > 0 ? text : null\n}\n","/**\n * `agentproto run <slug> [--cwd <dir>] [--prompt <text>] [--resume <id>]`\n *\n * Boots the named adapter, dispatches a single user turn, streams events\n * to stdout, then exits. Designed for two use-cases:\n * - one-shot scripting (pipe a prompt in, get stream back)\n * - quick smoke-test from a fresh checkout (\"does claude even spawn?\")\n *\n * Long-lived multiplexing belongs to `agentproto serve`, not here.\n */\n\nimport { resolve as resolvePath } from \"node:path\"\nimport { parseArgs } from \"node:util\"\nimport {\n createAgentCliRuntime,\n type AgentCliRuntimeSession,\n type StreamEvent,\n} from \"@agentproto/driver-agent-cli\"\nimport { resolveAdapter } from \"../registry/resolve.js\"\nimport { readStdinIfPiped } from \"../util/stdin.js\"\n\nexport async function runRun(args: readonly string[]): Promise<number> {\n const { values, positionals } = parseArgs({\n args: [...args],\n allowPositionals: true,\n strict: true,\n options: {\n cwd: { type: \"string\" },\n prompt: { type: \"string\", short: \"p\" },\n resume: { type: \"string\" },\n json: { type: \"boolean\" },\n },\n })\n\n const slug = positionals[0]\n if (!slug) {\n process.stderr.write(\n \"agentproto run: missing adapter slug. Try: agentproto run claude-code\\n\"\n )\n return 2\n }\n\n const cwd = values.cwd ? resolvePath(values.cwd) : process.cwd()\n const promptArg = values.prompt ?? (await readStdinIfPiped())\n if (!promptArg) {\n process.stderr.write(\n \"agentproto run: no prompt provided. Pass --prompt or pipe one over stdin.\\n\"\n )\n return 2\n }\n\n const adapter = await resolveAdapter(slug)\n const runtime = createAgentCliRuntime(adapter.handle)\n\n const controller = new AbortController()\n const onSignal = (sig: NodeJS.Signals) => {\n process.stderr.write(`\\nagentproto: received ${sig}, cancelling…\\n`)\n controller.abort()\n }\n process.once(\"SIGINT\", onSignal)\n process.once(\"SIGTERM\", onSignal)\n\n let session: AgentCliRuntimeSession | null = null\n try {\n session = await runtime.start({\n cwd,\n signal: controller.signal,\n resumeSessionId: values.resume,\n })\n\n const printer = values.json ? printJson : printPretty\n let exit = 0\n for await (const ev of session.send(promptArg)) {\n printer(ev)\n if (ev.kind === \"turn-end\" && ev.reason !== \"completed\") exit = 1\n if (ev.kind === \"error\") exit = 1\n }\n return exit\n } finally {\n process.off(\"SIGINT\", onSignal)\n process.off(\"SIGTERM\", onSignal)\n if (session) await session.close().catch(() => {})\n }\n}\n\nfunction printJson(ev: StreamEvent): void {\n process.stdout.write(`${JSON.stringify(ev)}\\n`)\n}\n\nfunction printPretty(ev: StreamEvent): void {\n switch (ev.kind) {\n case \"text-delta\":\n process.stdout.write(ev.text)\n break\n case \"thought\":\n process.stderr.write(`\\x1b[2m[thought] ${ev.text}\\x1b[0m\\n`)\n break\n case \"tool-call\":\n process.stderr.write(`\\x1b[36m[tool] ${ev.toolName}\\x1b[0m\\n`)\n break\n case \"tool-result\":\n if (ev.isError)\n process.stderr.write(`\\x1b[31m[tool-error]\\x1b[0m\\n`)\n break\n case \"agent-prompt\":\n process.stderr.write(`\\x1b[33m[agent-prompt: needs input]\\x1b[0m\\n`)\n break\n case \"turn-end\":\n process.stdout.write(`\\n\\x1b[2m[turn-end: ${ev.reason}]\\x1b[0m\\n`)\n break\n case \"error\":\n process.stderr.write(`\\x1b[31m[error] ${ev.error.message}\\x1b[0m\\n`)\n break\n }\n}\n","/**\n * `agentproto serve --connect <url>`\n *\n * Long-running daemon. Opens a WebSocket to a host (Guilde-shaped API),\n * authenticates with a token, then accepts spawn / stdin / stdout /\n * stderr / kill / exit frames over that channel — multiplexing many\n * ACP sessions through one process. The daemon owns local resources\n * (PTYs, child processes, JSONL session stores) so a host running in\n * the cloud can drive a CLI living on the user's laptop.\n *\n * v0.1 stub: argument parsing + connection scaffolding only. The wire\n * protocol is still being designed (tunnel frames need to land in\n * @agentproto/acp first); shipping a half-baked daemon would lock us\n * into the wrong shape. For now this verb prints a clear \"not yet\"\n * and exits non-zero so CI pipelines don't accidentally rely on it.\n */\n\nimport { parseArgs } from \"node:util\"\n\nexport async function runServe(args: readonly string[]): Promise<number> {\n const { values } = parseArgs({\n args: [...args],\n allowPositionals: false,\n strict: true,\n options: {\n connect: { type: \"string\", short: \"c\" },\n token: { type: \"string\", short: \"t\" },\n label: { type: \"string\", short: \"l\" },\n },\n })\n\n if (!values.connect) {\n process.stderr.write(\n \"agentproto serve: --connect <url> is required.\\n\" +\n \" example: agentproto serve --connect wss://guilde.work/api/v1/agentproto/tunnel --token $TOKEN\\n\"\n )\n return 2\n }\n\n process.stderr.write(\n \"agentproto serve: tunnel daemon is not yet implemented in this release.\\n\" +\n \" Tracking: tunnel frame protocol is landing in @agentproto/acp next.\\n\" +\n ` Wanted endpoint: ${values.connect}\\n` +\n ` Label: ${values.label ?? \"(none)\"}\\n`\n )\n return 64\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@agentproto/cli",
3
+ "version": "0.1.0-alpha.0",
4
+ "description": "@agentproto/cli — the `agentproto` binary. Install AIP-45 agent CLI adapters, run them locally, or expose them over a tunnel as a long-running daemon. Reference host for hermes / claude-code / opencode / gemini-cli / goose, all driven through @agentproto/driver-agent-cli.",
5
+ "keywords": [
6
+ "agentproto",
7
+ "aip-45",
8
+ "agent-cli",
9
+ "cli",
10
+ "daemon",
11
+ "claude-code",
12
+ "hermes",
13
+ "opencode",
14
+ "goose",
15
+ "gemini-cli"
16
+ ],
17
+ "homepage": "https://agentproto.sh",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/agentproto/ts",
21
+ "directory": "packages/cli"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/agentproto/ts/issues"
25
+ },
26
+ "license": "MIT",
27
+ "type": "module",
28
+ "main": "dist/index.mjs",
29
+ "module": "dist/index.mjs",
30
+ "types": "dist/index.d.ts",
31
+ "bin": {
32
+ "agentproto": "./dist/cli.mjs"
33
+ },
34
+ "exports": {
35
+ ".": {
36
+ "types": "./dist/index.d.ts",
37
+ "import": "./dist/index.mjs",
38
+ "default": "./dist/index.mjs"
39
+ }
40
+ },
41
+ "files": [
42
+ "dist",
43
+ "README.md"
44
+ ],
45
+ "dependencies": {
46
+ "@agentproto/driver-agent-cli": "0.1.0-alpha.0"
47
+ },
48
+ "devDependencies": {
49
+ "@types/node": "^25.1.0",
50
+ "tsup": "^8.5.1",
51
+ "typescript": "^5.9.3",
52
+ "vitest": "^3.2.4",
53
+ "@agentproto/adapter-hermes": "0.1.0-alpha.0",
54
+ "@agentproto/adapter-claude-code": "0.1.0-alpha.0",
55
+ "@agentproto/tooling": "0.1.0-alpha.0"
56
+ },
57
+ "engines": {
58
+ "node": ">=20.9.0"
59
+ },
60
+ "scripts": {
61
+ "build": "tsup",
62
+ "dev": "tsup --watch",
63
+ "clean": "rm -rf dist",
64
+ "check-types": "tsc --noEmit",
65
+ "test": "vitest run --passWithNoTests",
66
+ "test:watch": "vitest"
67
+ }
68
+ }