@xi-era/acp-cli 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +17 -0
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -194,5 +194,22 @@ program.command("serve").description("serve a module that exports components (na
|
|
|
194
194
|
`);
|
|
195
195
|
}
|
|
196
196
|
});
|
|
197
|
+
program.command("ping").description("measure RTT to an ACP server via the $ping keepalive op").argument("<url>", "server base URL").option("--timeout <ms>", "call timeout in milliseconds").action(async (url, opts) => {
|
|
198
|
+
try {
|
|
199
|
+
const client = makeClient(url, opts);
|
|
200
|
+
const sentAt = Date.now();
|
|
201
|
+
const reply = await client.request({ op: "$ping", input: { ts: sentAt } });
|
|
202
|
+
const rtt = Date.now() - sentAt;
|
|
203
|
+
const result = reply.result;
|
|
204
|
+
const serverClockDelta = typeof result?.pong === "number" ? result.pong - sentAt - rtt : void 0;
|
|
205
|
+
console.log(`rtt: ${rtt}ms`);
|
|
206
|
+
if (serverClockDelta !== void 0 && Number.isFinite(serverClockDelta)) {
|
|
207
|
+
console.log(`server clock delta (approx): ${serverClockDelta >= 0 ? "+" : ""}${serverClockDelta}ms`);
|
|
208
|
+
}
|
|
209
|
+
await client.close();
|
|
210
|
+
} catch (e) {
|
|
211
|
+
fail(e);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
197
214
|
program.parseAsync(process.argv).catch(fail);
|
|
198
215
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +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":[]}
|
|
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\n// ---------------------------------------------------------------------------\n// acp ping\n// ---------------------------------------------------------------------------\nprogram\n .command(\"ping\")\n .description(\"measure RTT to an ACP server via the $ping keepalive op\")\n .argument(\"<url>\", \"server base URL\")\n .option(\"--timeout <ms>\", \"call timeout in milliseconds\")\n .action(async (url: string, opts: CommonOpts) => {\n try {\n const client = makeClient(url, opts);\n const sentAt = Date.now();\n const reply = await client.request({ op: \"$ping\", input: { ts: sentAt } });\n const rtt = Date.now() - sentAt;\n const result = (reply as { ok?: boolean; result?: { pong?: number } }).result;\n const serverClockDelta =\n typeof result?.pong === \"number\" ? result.pong - sentAt - rtt : undefined;\n console.log(`rtt: ${rtt}ms`);\n if (serverClockDelta !== undefined && Number.isFinite(serverClockDelta)) {\n console.log(`server clock delta (approx): ${serverClockDelta >= 0 ? \"+\" : \"\"}${serverClockDelta}ms`);\n }\n await client.close();\n } catch (e) {\n fail(e);\n }\n });\n\nprogram.parseAsync(process.argv).catch(fail);\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xi-era/acp-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "ACP (Agent-Component-Protocol) CLI — discover, invoke and debug remote ACP components; also serves local component modules.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"bugs": "https://github.com/xi-era/acp-protocol/issues",
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"commander": "^12.1.0",
|
|
34
|
-
"@xi-era/acp-sdk": "0.
|
|
34
|
+
"@xi-era/acp-sdk": "0.2.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/node": "^22.7.4",
|