@xi-era/acp-cli 0.1.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,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 xi-era (open-source community arm of Stellxis)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/dist/cli.js ADDED
@@ -0,0 +1,198 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli.ts
4
+ import { Command } from "commander";
5
+ import { readFileSync } from "fs";
6
+ import { pathToFileURL } from "url";
7
+ import { resolve } from "path";
8
+ import { spawn } from "child_process";
9
+ import { AcpClient } from "@xi-era/acp-sdk/client";
10
+ import { AcpError } from "@xi-era/acp-sdk/client";
11
+ import { AcpServer } from "@xi-era/acp-sdk/server";
12
+ var program = new Command();
13
+ program.name("acp").description("ACP (Agent-Component-Protocol) \u2014 discover, invoke and serve remote components").version("0.1.0");
14
+ function normalizeUrl(url) {
15
+ const trimmed = url.replace(/\/+$/, "");
16
+ return trimmed.endsWith("/acp") ? trimmed : `${trimmed}/acp`;
17
+ }
18
+ function makeClient(url, opts) {
19
+ const headers = {};
20
+ for (const h of opts.header ?? []) {
21
+ const idx = h.indexOf("=");
22
+ if (idx <= 0) throw new Error(`bad header (expected k=v): ${h}`);
23
+ headers[h.slice(0, idx)] = h.slice(idx + 1);
24
+ }
25
+ return new AcpClient({
26
+ url: normalizeUrl(url),
27
+ headers,
28
+ timeoutMs: opts.timeout ? Number(opts.timeout) : 3e4
29
+ });
30
+ }
31
+ function printEnvelope(kind, envelope) {
32
+ process.stderr.write(`--> ${kind}: ${JSON.stringify(envelope)}
33
+ `);
34
+ }
35
+ function assertOk(reply) {
36
+ if (reply.ok !== true) {
37
+ const err = reply;
38
+ throw new AcpError(err.error.code, err.error.message);
39
+ }
40
+ return reply;
41
+ }
42
+ function fail(error) {
43
+ if (error instanceof AcpError) {
44
+ process.stderr.write(`acp: error ${error.code}: ${error.message}
45
+ `);
46
+ if (error.data !== void 0) process.stderr.write(`${JSON.stringify(error.data, null, 2)}
47
+ `);
48
+ } else {
49
+ process.stderr.write(`acp: ${error instanceof Error ? error.message : String(error)}
50
+ `);
51
+ }
52
+ process.exit(1);
53
+ }
54
+ function printDescriptorTable(components) {
55
+ if (components.length === 0) {
56
+ console.log("(no components)");
57
+ return;
58
+ }
59
+ const pad = (s, n) => s.length > n ? s.slice(0, n - 1) + "\u2026" : s.padEnd(n);
60
+ console.log(`${pad("ID", 32)}${pad("VERSION", 10)}${pad("STREAM", 8)}DESCRIPTION`);
61
+ for (const c of components) {
62
+ console.log(`${pad(c.id, 32)}${pad(c.version, 10)}${pad(String(c.stream), 8)}${c.description}`);
63
+ }
64
+ }
65
+ function parseInput(inputJson, file) {
66
+ if (file) {
67
+ try {
68
+ return JSON.parse(readFileSync(file, "utf8"));
69
+ } catch (e) {
70
+ throw new Error(`cannot read/parse input file ${file}: ${e instanceof Error ? e.message : e}`);
71
+ }
72
+ }
73
+ if (!inputJson) return void 0;
74
+ try {
75
+ return JSON.parse(inputJson);
76
+ } catch {
77
+ throw new Error("inputJson must be valid JSON (or use -f <file>)");
78
+ }
79
+ }
80
+ program.command("discover").description("list components exposed by an ACP server").argument("<url>", "server base URL, e.g. http://localhost:8080").option("--tags <tags>", "comma-separated tag filter").option("--json", "print raw JSON envelopes").action(async (url, opts) => {
81
+ try {
82
+ const client = makeClient(url, opts);
83
+ const tags = opts.tags ? opts.tags.split(",").map((t) => t.trim()).filter(Boolean) : void 0;
84
+ if (opts.json) {
85
+ const reply = await client.request({ op: "discover", ...tags ? { tags } : {} });
86
+ console.log(JSON.stringify(reply, null, 2));
87
+ } else {
88
+ const reply = assertOk(await client.request({ op: "discover", ...tags ? { tags } : {} }));
89
+ printDescriptorTable(reply.result.components);
90
+ }
91
+ await client.close();
92
+ } catch (e) {
93
+ fail(e);
94
+ }
95
+ });
96
+ program.command("describe").description("show one component's descriptor").argument("<url>", "server base URL").argument("<componentId>", "component id, e.g. sensor.temperature").option("--json", "print raw JSON").action(async (url, componentId, opts) => {
97
+ try {
98
+ const client = makeClient(url, opts);
99
+ const components = await client.discover(componentId);
100
+ if (components.length === 0) {
101
+ process.stderr.write(`acp: component not found: ${componentId}
102
+ `);
103
+ process.exit(1);
104
+ }
105
+ console.log(JSON.stringify(components[0], null, 2));
106
+ await client.close();
107
+ } catch (e) {
108
+ fail(e);
109
+ }
110
+ });
111
+ program.command("call").description("invoke a component").argument("<url>", "server base URL").argument("<componentId>", "component id").argument("[inputJson]", "input as JSON string").option("-f, --file <path>", "read input from a JSON file").option("--stream", "request streamed chunked reply").option("--raw", "print only the result value (no envelope)").option("--trace", "print request/reply envelopes to stderr").option("-H, --header <k=v>", "extra HTTP headers (repeatable)", collect, void 0).option("--timeout <ms>", "call timeout in milliseconds").action(
112
+ async (url, componentId, inputJson, opts) => {
113
+ try {
114
+ const client = makeClient(url, opts);
115
+ const input = parseInput(inputJson, opts.file) ?? {};
116
+ if (opts.stream) {
117
+ const reqId = `cli-${Date.now()}`;
118
+ const request = {
119
+ acp: "0.1",
120
+ id: reqId,
121
+ op: "call",
122
+ component: componentId,
123
+ input,
124
+ stream: true
125
+ };
126
+ if (opts.trace) printEnvelope("request", request);
127
+ for await (const chunk of client.callStream(componentId, input)) {
128
+ const out = opts.raw ? chunk.data : { chunk };
129
+ console.log(JSON.stringify(out));
130
+ }
131
+ } else {
132
+ if (opts.trace) {
133
+ printEnvelope("request", { op: "call", component: componentId, input });
134
+ }
135
+ const result = await client.call(componentId, input);
136
+ console.log(opts.raw ? JSON.stringify(result) : JSON.stringify({ ok: true, result }, null, 2));
137
+ }
138
+ await client.close();
139
+ } catch (e) {
140
+ fail(e);
141
+ }
142
+ }
143
+ );
144
+ function collect(value, previous) {
145
+ return [...previous ?? [], value];
146
+ }
147
+ program.command("info").description("show server info (name / version / protocol)").argument("<url>", "server base URL").action(async (url, opts) => {
148
+ try {
149
+ const client = makeClient(url, opts);
150
+ const reply = assertOk(await client.request({ op: "discover" }));
151
+ const { server, components } = reply.result;
152
+ console.log(`name: ${server.name}`);
153
+ console.log(`version: ${server.version}`);
154
+ console.log(`protocol: ACP ${server.protocol}`);
155
+ console.log(`components: ${components.length}`);
156
+ await client.close();
157
+ } catch (e) {
158
+ fail(e);
159
+ }
160
+ });
161
+ program.command("serve").description("serve a module that exports components (named export `components`)").argument("<modulePath>", "path to a JS/TS module exporting `components`").option("--port <port>", "HTTP+WS port", "8080").option("--stdio", "serve over stdin/stdout instead of HTTP").option("--watch", "restart on file changes (node --watch)").action(async (modulePath, opts) => {
162
+ if (opts.watch && !process.env["ACP_WATCH_CHILD"]) {
163
+ const child = spawn(
164
+ process.execPath,
165
+ ["--watch", process.argv[1], ...process.argv.slice(2).filter((a) => a !== "--watch")],
166
+ { stdio: "inherit", env: { ...process.env, ACP_WATCH_CHILD: "1" } }
167
+ );
168
+ child.on("exit", (code) => process.exit(code ?? 0));
169
+ return;
170
+ }
171
+ const abs = resolve(process.cwd(), modulePath);
172
+ let mod;
173
+ try {
174
+ mod = await import(pathToFileURL(abs).href);
175
+ } catch (e) {
176
+ fail(new Error(`cannot load module ${abs}: ${e instanceof Error ? e.message : e}`));
177
+ }
178
+ const components = mod.components ?? (Array.isArray(mod.default) ? mod.default : mod.default?.components);
179
+ if (!components || components.length === 0) {
180
+ fail(new Error(`module ${abs} exports no \`components\` array`));
181
+ }
182
+ const server = new AcpServer({
183
+ name: mod.name ?? "acp-serve",
184
+ version: mod.version ?? "0.0.0"
185
+ });
186
+ for (const c of components) server.register(c);
187
+ if (opts.stdio) {
188
+ await server.serveStdio();
189
+ } else {
190
+ const { port } = await server.listen({ port: Number(opts.port) });
191
+ process.stderr.write(`ACP server listening on http://localhost:${port}/acp (ws://localhost:${port}/acp)
192
+ `);
193
+ process.stderr.write(` discover: curl http://localhost:${port}/acp/discover
194
+ `);
195
+ }
196
+ });
197
+ program.parseAsync(process.argv).catch(fail);
198
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["/**\n * acp — CLI for discovering, invoking and serving ACP components.\n */\nimport { Command } from \"commander\";\nimport { readFileSync } from \"node:fs\";\nimport { pathToFileURL } from \"node:url\";\nimport { resolve } from \"node:path\";\nimport { spawn } from \"node:child_process\";\nimport { AcpClient } from \"@xi-era/acp-sdk/client\";\nimport type { AcpReply, ComponentDescriptor } from \"@xi-era/acp-sdk/client\";\nimport { AcpError } from \"@xi-era/acp-sdk/client\";\nimport type { AcpRequest, ComponentDef } from \"@xi-era/acp-sdk/server\";\nimport { AcpServer } from \"@xi-era/acp-sdk/server\";\n\nconst program = new Command();\n\nprogram\n .name(\"acp\")\n .description(\"ACP (Agent-Component-Protocol) — discover, invoke and serve remote components\")\n .version(\"0.1.0\");\n\ninterface CommonOpts {\n header?: string[];\n timeout?: string;\n}\n\n/** Ensures the URL points at the POST /acp endpoint. */\nfunction normalizeUrl(url: string): string {\n const trimmed = url.replace(/\\/+$/, \"\");\n return trimmed.endsWith(\"/acp\") ? trimmed : `${trimmed}/acp`;\n}\n\nfunction makeClient(url: string, opts: CommonOpts): AcpClient {\n const headers: Record<string, string> = {};\n for (const h of opts.header ?? []) {\n const idx = h.indexOf(\"=\");\n if (idx <= 0) throw new Error(`bad header (expected k=v): ${h}`);\n headers[h.slice(0, idx)] = h.slice(idx + 1);\n }\n return new AcpClient({\n url: normalizeUrl(url),\n headers,\n timeoutMs: opts.timeout ? Number(opts.timeout) : 30_000,\n });\n}\n\nfunction printEnvelope(kind: string, envelope: unknown): void {\n process.stderr.write(`--> ${kind}: ${JSON.stringify(envelope)}\\n`);\n}\n\n/** Unwraps a reply; the static type says ok:true but the wire can say otherwise. */\nfunction assertOk(reply: AcpReply): { result: unknown } {\n if (reply.ok !== true) {\n const err = reply as unknown as { error: { code: number; message: string } };\n throw new AcpError(err.error.code, err.error.message);\n }\n return reply;\n}\n\nfunction fail(error: unknown): never {\n if (error instanceof AcpError) {\n process.stderr.write(`acp: error ${error.code}: ${error.message}\\n`);\n if (error.data !== undefined) process.stderr.write(`${JSON.stringify(error.data, null, 2)}\\n`);\n } else {\n process.stderr.write(`acp: ${error instanceof Error ? error.message : String(error)}\\n`);\n }\n process.exit(1);\n}\n\nfunction printDescriptorTable(components: ComponentDescriptor[]): void {\n if (components.length === 0) {\n console.log(\"(no components)\");\n return;\n }\n const pad = (s: string, n: number) => (s.length > n ? s.slice(0, n - 1) + \"…\" : s.padEnd(n));\n console.log(`${pad(\"ID\", 32)}${pad(\"VERSION\", 10)}${pad(\"STREAM\", 8)}DESCRIPTION`);\n for (const c of components) {\n console.log(`${pad(c.id, 32)}${pad(c.version, 10)}${pad(String(c.stream), 8)}${c.description}`);\n }\n}\n\nfunction parseInput(inputJson?: string, file?: string): unknown {\n if (file) {\n try {\n return JSON.parse(readFileSync(file, \"utf8\"));\n } catch (e) {\n throw new Error(`cannot read/parse input file ${file}: ${e instanceof Error ? e.message : e}`);\n }\n }\n if (!inputJson) return undefined;\n try {\n return JSON.parse(inputJson);\n } catch {\n throw new Error(\"inputJson must be valid JSON (or use -f <file>)\");\n }\n}\n\n// ---------------------------------------------------------------------------\n// acp discover\n// ---------------------------------------------------------------------------\nprogram\n .command(\"discover\")\n .description(\"list components exposed by an ACP server\")\n .argument(\"<url>\", \"server base URL, e.g. http://localhost:8080\")\n .option(\"--tags <tags>\", \"comma-separated tag filter\")\n .option(\"--json\", \"print raw JSON envelopes\")\n .action(async (url: string, opts: CommonOpts & { tags?: string; json?: boolean }) => {\n try {\n const client = makeClient(url, opts);\n const tags = opts.tags\n ? opts.tags.split(\",\").map((t) => t.trim()).filter(Boolean)\n : undefined;\n if (opts.json) {\n const reply = await client.request({ op: \"discover\", ...(tags ? { tags } : {}) });\n console.log(JSON.stringify(reply, null, 2));\n } else {\n const reply = assertOk(await client.request({ op: \"discover\", ...(tags ? { tags } : {}) }));\n printDescriptorTable((reply.result as { components: ComponentDescriptor[] }).components);\n }\n await client.close();\n } catch (e) {\n fail(e);\n }\n });\n\n// ---------------------------------------------------------------------------\n// acp describe\n// ---------------------------------------------------------------------------\nprogram\n .command(\"describe\")\n .description(\"show one component's descriptor\")\n .argument(\"<url>\", \"server base URL\")\n .argument(\"<componentId>\", \"component id, e.g. sensor.temperature\")\n .option(\"--json\", \"print raw JSON\")\n .action(async (url: string, componentId: string, opts: CommonOpts & { json?: boolean }) => {\n try {\n const client = makeClient(url, opts);\n const components = await client.discover(componentId);\n if (components.length === 0) {\n process.stderr.write(`acp: component not found: ${componentId}\\n`);\n process.exit(1);\n }\n console.log(JSON.stringify(components[0], null, 2));\n await client.close();\n } catch (e) {\n fail(e);\n }\n });\n\n// ---------------------------------------------------------------------------\n// acp call\n// ---------------------------------------------------------------------------\nprogram\n .command(\"call\")\n .description(\"invoke a component\")\n .argument(\"<url>\", \"server base URL\")\n .argument(\"<componentId>\", \"component id\")\n .argument(\"[inputJson]\", \"input as JSON string\")\n .option(\"-f, --file <path>\", \"read input from a JSON file\")\n .option(\"--stream\", \"request streamed chunked reply\")\n .option(\"--raw\", \"print only the result value (no envelope)\")\n .option(\"--trace\", \"print request/reply envelopes to stderr\")\n .option(\"-H, --header <k=v>\", \"extra HTTP headers (repeatable)\", collect, undefined)\n .option(\"--timeout <ms>\", \"call timeout in milliseconds\")\n .action(\n async (\n url: string,\n componentId: string,\n inputJson: string | undefined,\n opts: CommonOpts & {\n file?: string;\n stream?: boolean;\n raw?: boolean;\n trace?: boolean;\n }\n ) => {\n try {\n const client = makeClient(url, opts);\n const input = parseInput(inputJson, opts.file) ?? {};\n if (opts.stream) {\n const reqId = `cli-${Date.now()}`;\n const request: AcpRequest = {\n acp: \"0.1\",\n id: reqId,\n op: \"call\",\n component: componentId,\n input,\n stream: true,\n };\n if (opts.trace) printEnvelope(\"request\", request);\n for await (const chunk of client.callStream(componentId, input)) {\n const out = opts.raw ? chunk.data : { chunk };\n console.log(JSON.stringify(out));\n }\n } else {\n if (opts.trace) {\n printEnvelope(\"request\", { op: \"call\", component: componentId, input });\n }\n const result = await client.call(componentId, input);\n console.log(opts.raw ? JSON.stringify(result) : JSON.stringify({ ok: true, result }, null, 2));\n }\n await client.close();\n } catch (e) {\n fail(e);\n }\n }\n );\n\nfunction collect(value: string, previous: string[]): string[] {\n return [...(previous ?? []), value];\n}\n\n// ---------------------------------------------------------------------------\n// acp info\n// ---------------------------------------------------------------------------\nprogram\n .command(\"info\")\n .description(\"show server info (name / version / protocol)\")\n .argument(\"<url>\", \"server base URL\")\n .action(async (url: string, opts: CommonOpts) => {\n try {\n const client = makeClient(url, opts);\n const reply = assertOk(await client.request({ op: \"discover\" }));\n const { server, components } = reply.result as {\n server: { name: string; version: string; protocol: string };\n components: ComponentDescriptor[];\n };\n console.log(`name: ${server.name}`);\n console.log(`version: ${server.version}`);\n console.log(`protocol: ACP ${server.protocol}`);\n console.log(`components: ${components.length}`);\n await client.close();\n } catch (e) {\n fail(e);\n }\n });\n\n// ---------------------------------------------------------------------------\n// acp serve\n// ---------------------------------------------------------------------------\ninterface ServeModule {\n name?: string;\n version?: string;\n components?: ComponentDef[];\n default?: { name?: string; version?: string; components?: ComponentDef[] } | ComponentDef[];\n}\n\nprogram\n .command(\"serve\")\n .description(\"serve a module that exports components (named export `components`)\")\n .argument(\"<modulePath>\", \"path to a JS/TS module exporting `components`\")\n .option(\"--port <port>\", \"HTTP+WS port\", \"8080\")\n .option(\"--stdio\", \"serve over stdin/stdout instead of HTTP\")\n .option(\"--watch\", \"restart on file changes (node --watch)\")\n .action(async (modulePath: string, opts: { port: string; stdio?: boolean; watch?: boolean }) => {\n if (opts.watch && !process.env[\"ACP_WATCH_CHILD\"]) {\n // Re-exec under node --watch; flag must not loop.\n const child = spawn(\n process.execPath,\n [\"--watch\", process.argv[1]!, ...process.argv.slice(2).filter((a) => a !== \"--watch\")],\n { stdio: \"inherit\", env: { ...process.env, ACP_WATCH_CHILD: \"1\" } }\n );\n child.on(\"exit\", (code) => process.exit(code ?? 0));\n return;\n }\n\n const abs = resolve(process.cwd(), modulePath);\n let mod: ServeModule;\n try {\n mod = (await import(pathToFileURL(abs).href)) as ServeModule;\n } catch (e) {\n fail(new Error(`cannot load module ${abs}: ${e instanceof Error ? e.message : e}`));\n }\n const components = mod.components ?? (Array.isArray(mod.default) ? mod.default : mod.default?.components);\n if (!components || components.length === 0) {\n fail(new Error(`module ${abs} exports no \\`components\\` array`));\n }\n const server = new AcpServer({\n name: mod.name ?? \"acp-serve\",\n version: mod.version ?? \"0.0.0\",\n });\n for (const c of components) server.register(c);\n\n if (opts.stdio) {\n await server.serveStdio();\n } else {\n const { port } = await server.listen({ port: Number(opts.port) });\n process.stderr.write(`ACP server listening on http://localhost:${port}/acp (ws://localhost:${port}/acp)\\n`);\n process.stderr.write(` discover: curl http://localhost:${port}/acp/discover\\n`);\n }\n });\n\nprogram.parseAsync(process.argv).catch(fail);\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@xi-era/acp-cli",
3
+ "version": "0.1.0",
4
+ "description": "ACP (Agent-Component-Protocol) CLI — discover, invoke and debug remote ACP components; also serves local component modules.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "engines": {
8
+ "node": ">=20"
9
+ },
10
+ "bin": {
11
+ "acp": "./dist/cli.js"
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "keywords": [
17
+ "acp",
18
+ "cli",
19
+ "agent",
20
+ "component",
21
+ "protocol",
22
+ "mcp",
23
+ "iot"
24
+ ],
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/xi-era/acp-protocol.git",
28
+ "directory": "packages/acp-cli"
29
+ },
30
+ "homepage": "https://github.com/xi-era/acp-protocol",
31
+ "bugs": "https://github.com/xi-era/acp-protocol/issues",
32
+ "dependencies": {
33
+ "commander": "^12.1.0",
34
+ "@xi-era/acp-sdk": "0.1.0"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^22.7.4",
38
+ "tsup": "^8.3.0"
39
+ },
40
+ "scripts": {
41
+ "build": "tsup"
42
+ }
43
+ }