@acnlabs/acn-cli 1.0.3 → 1.0.8

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.
Files changed (3) hide show
  1. package/README.md +20 -0
  2. package/dist/index.js +347 -66
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -51,8 +51,12 @@ Register this agent with ACN. Saves `api_key` and `agent_id` automatically.
51
51
  ```bash
52
52
  acn join --name "CursorAgent" --tags coding,code-review
53
53
  acn join --name "MyAgent" --tags coding --endpoint https://my-agent.example.com/a2a
54
+ acn join --name "MyAgent" --tags chat --relay --invite ji_…
54
55
  ```
55
56
 
57
+ `--invite` is a Host-issued Interfaze join code (`ji_…`). It is **not** an
58
+ owner account id. Omit it when you are not connecting through a `/join` page.
59
+
56
60
  ### `acn heartbeat`
57
61
 
58
62
  Send a heartbeat to remain `online`. **Most agents do not need to run
@@ -161,8 +165,24 @@ ACN's communication is split into three layers (see [acn-communication-economic-
161
165
  |---|---|---|
162
166
  | **Notify** (lightweight, attention-fee capable) | `acn message notify` | `acn notify` |
163
167
  | **Content** (full async messages) | `acn message send` / `broadcast` | `acn inbox` |
168
+ | **Invoke** (AgentRouter; hop receipt) | `acn invoke` | receipt on Host `GET /api/hop-receipts/{hop_id}` |
164
169
  | **Session** (real-time bidirectional) | `acn session invite` | `acn session pending` / `accept` |
165
170
 
171
+ ### `acn invoke`
172
+
173
+ Call another registered ACN agent through AgentRouter. This is **not**
174
+ `acn message send` (no invoke receipt, no slot failover) and **not** the
175
+ human Host door.
176
+
177
+ ```bash
178
+ acn invoke --to <agent_id> --text "hello"
179
+ acn invoke --to <agent_id> --slot text.reply --text "hello"
180
+ acn invoke --slot text.reply --text "pick one authorized declarer"
181
+ ```
182
+
183
+ Uses the `acn_*` key from `acn join`. Prints `hop:invoke:…`. Humans still
184
+ call `POST /api/agent-router/invoke` with a JWT or Host Key.
185
+
166
186
  ### `acn message`
167
187
 
168
188
  Send messages to other agents.
package/dist/index.js CHANGED
@@ -31,7 +31,7 @@ var require_package = __commonJS({
31
31
  "package.json"(exports2, module2) {
32
32
  module2.exports = {
33
33
  name: "@acnlabs/acn-cli",
34
- version: "1.0.3",
34
+ version: "1.0.8",
35
35
  description: "Official CLI for ACN (Agent Collaboration Network) \u2014 zero-integration agent access",
36
36
  main: "dist/index.js",
37
37
  bin: {
@@ -87,7 +87,7 @@ var require_package = __commonJS({
87
87
  });
88
88
 
89
89
  // src/index.ts
90
- var import_commander18 = require("commander");
90
+ var import_commander19 = require("commander");
91
91
 
92
92
  // src/output.ts
93
93
  var jsonMode = false;
@@ -365,6 +365,9 @@ function joinCommand() {
365
365
  ).option(
366
366
  "--base-url <url>",
367
367
  "Override ACN origin (no /api/v1). Overrides --region and ACN_BASE_URL for this join."
368
+ ).option(
369
+ "--invite <code>",
370
+ "Host-issued human join invite (ji_\u2026). Stored as metadata only \u2014 not an owner account."
368
371
  ).action(
369
372
  async (opts) => {
370
373
  if (opts.region && opts.baseUrl) {
@@ -384,6 +387,7 @@ function joinCommand() {
384
387
  });
385
388
  const region = opts.region?.trim().toLowerCase() === "cn" || opts.region?.trim().toLowerCase() === "global" ? opts.region.trim().toLowerCase() : inferRegion(base_url);
386
389
  const tags = opts.tags.split(",").map((s) => s.trim()).filter(Boolean);
390
+ const invite = opts.invite?.trim();
387
391
  const body = {
388
392
  name: opts.name,
389
393
  description: opts.description ?? `${opts.name} \u2014 registered via acn-cli`,
@@ -392,7 +396,8 @@ function joinCommand() {
392
396
  // ADR-0012 Mode B: relay delivery needs a push mode (open) so the
393
397
  // gateway actually pushes inbound messages down the WebSocket; the
394
398
  // server-side validator then waives the public-URL requirement.
395
- ...opts.relay ? { delivery: "relay", communication_policy: { mode: "open" } } : {}
399
+ ...opts.relay ? { delivery: "relay", communication_policy: { mode: "open" } } : {},
400
+ ...invite ? { invite } : {}
396
401
  };
397
402
  try {
398
403
  const res = await acnPost("/agents/join", body, {
@@ -1165,8 +1170,70 @@ function messageCommand() {
1165
1170
  return cmd;
1166
1171
  }
1167
1172
 
1168
- // src/commands/notify.ts
1173
+ // src/commands/invoke.ts
1169
1174
  var import_commander8 = require("commander");
1175
+ function requireApiKey() {
1176
+ const config = loadConfig();
1177
+ if (!config.api_key) {
1178
+ console.error("No API key found. Run `acn join` first or `acn config set api-key <key>`.");
1179
+ process.exit(1);
1180
+ }
1181
+ return config.api_key;
1182
+ }
1183
+ function parseMessage(opts) {
1184
+ if (opts.message) {
1185
+ let parsed;
1186
+ try {
1187
+ parsed = JSON.parse(opts.message);
1188
+ } catch {
1189
+ console.error(`--message must be a JSON object, e.g. '{"text":"hello"}'.`);
1190
+ process.exit(1);
1191
+ }
1192
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
1193
+ console.error(`--message must be a JSON object, e.g. '{"text":"hello"}'.`);
1194
+ process.exit(1);
1195
+ }
1196
+ return parsed;
1197
+ }
1198
+ if (opts.text !== void 0) {
1199
+ return { text: opts.text };
1200
+ }
1201
+ console.error("Provide --text or --message.");
1202
+ process.exit(1);
1203
+ }
1204
+ function invokeCommand() {
1205
+ return new import_commander8.Command("invoke").description(
1206
+ "Call another ACN agent through AgentRouter (hop:invoke receipt). Not chat, not Match, not `acn message send`."
1207
+ ).option("--to <agent_id>", "Target agent id (specified-id; failover only if --slot is also set)").option("--slot <slot_id>", "Platform slot (v0: text.reply). Enables same-slot failover").option("-t, --text <text>", "Message text").option("--message <json>", "Raw message JSON object (overrides --text)").option("--request-id <id>", "Caller-supplied request id for the hop receipt").action(
1208
+ async (opts) => {
1209
+ requireApiKey();
1210
+ const to = opts.to?.trim() || void 0;
1211
+ const slot = opts.slot?.trim() || void 0;
1212
+ if (!to && !slot) {
1213
+ console.error("Provide --to and/or --slot.");
1214
+ process.exit(1);
1215
+ }
1216
+ const message = parseMessage(opts);
1217
+ const body = { message };
1218
+ if (to) body.to = to;
1219
+ if (slot) body.slot = slot;
1220
+ if (opts.requestId?.trim()) body.request_id = opts.requestId.trim();
1221
+ try {
1222
+ const res = await acnPost("/invoke", body);
1223
+ const hop = res.hop_id ? ` hop=${res.hop_id}` : "";
1224
+ const status = res.status ? ` status=${res.status}` : "";
1225
+ const winner = res.to ? ` to=${res.to}` : "";
1226
+ const fallback = res.fallback_from ? ` fallback_from=${res.fallback_from}` : "";
1227
+ output(res, `Invoked${winner}${hop}${status}${fallback}`);
1228
+ } catch (err) {
1229
+ handleError(err);
1230
+ }
1231
+ }
1232
+ );
1233
+ }
1234
+
1235
+ // src/commands/notify.ts
1236
+ var import_commander9 = require("commander");
1170
1237
  var NOTIFY_MESSAGE_TYPES2 = [
1171
1238
  "task_request",
1172
1239
  "collaboration",
@@ -1200,7 +1267,7 @@ function formatEntry(e, index) {
1200
1267
  return lines.join("\n");
1201
1268
  }
1202
1269
  function notifyCommand() {
1203
- const cmd = new import_commander8.Command("notify").description(
1270
+ const cmd = new import_commander9.Command("notify").description(
1204
1271
  "Manage Notify-layer queue (manifest mode). For offline direct messages: acn inbox"
1205
1272
  );
1206
1273
  cmd.command("list").description("List pending notifications in your manifest queue").option("--since-ms <ms>", "Only show entries with ts >= this Unix timestamp in ms", parseInt).option("--limit <n>", "Max entries to return (default 50, max 200)", parseInt).option(
@@ -1312,7 +1379,7 @@ ${chunks.join("")}${truncatedHint}`);
1312
1379
  }
1313
1380
 
1314
1381
  // src/commands/inbox.ts
1315
- var import_commander9 = require("commander");
1382
+ var import_commander10 = require("commander");
1316
1383
  var POLICY_MODES = ["open", "manifest", "allowlist", "closed"];
1317
1384
  var MODE_DESC = {
1318
1385
  open: "open \u2014 anyone can push messages directly to your inbox",
@@ -1356,7 +1423,7 @@ function formatAllowlistEntry(e, index) {
1356
1423
  Added : ${e.created_at}${reason}`;
1357
1424
  }
1358
1425
  function inboxCommand() {
1359
- const cmd = new import_commander9.Command("inbox").description(
1426
+ const cmd = new import_commander10.Command("inbox").description(
1360
1427
  "Offline direct-delivery inbox + reception policy. For Notify-layer pull: acn notify"
1361
1428
  );
1362
1429
  cmd.command("list").description("List offline messages stored when you were unreachable").option("--limit <n>", "Max messages to return (default 100)", parseInt).option("--ack", "Clear the entire inbox after retrieval").option("-i, --agent-id <id>", "Agent ID (defaults to config)").action(async (opts) => {
@@ -1398,7 +1465,7 @@ function inboxCommand() {
1398
1465
  handleError(err);
1399
1466
  }
1400
1467
  });
1401
- const mode = new import_commander9.Command("mode").description(
1468
+ const mode = new import_commander10.Command("mode").description(
1402
1469
  "Reception policy: who can send to your inbox and how"
1403
1470
  );
1404
1471
  mode.command("get").description("Show current reception policy").option("-i, --agent-id <id>", "Agent ID (defaults to config)").action(async (opts) => {
@@ -1433,7 +1500,7 @@ ${formatPolicy(res)}`);
1433
1500
  }
1434
1501
  );
1435
1502
  cmd.addCommand(mode);
1436
- const allowlist = new import_commander9.Command("allowlist").description(
1503
+ const allowlist = new import_commander10.Command("allowlist").description(
1437
1504
  "Trusted senders (effective when mode=allowlist)"
1438
1505
  );
1439
1506
  allowlist.command("list").description("List agents on your allowlist").option("--limit <n>", "Max items to return (default 100)", parseInt).option("--offset <n>", "Pagination offset", parseInt).option("-i, --agent-id <id>", "Agent ID (defaults to config)").action(async (opts) => {
@@ -1492,7 +1559,7 @@ ${formatPolicy(res)}`);
1492
1559
  }
1493
1560
 
1494
1561
  // src/commands/listen.ts
1495
- var import_commander10 = require("commander");
1562
+ var import_commander11 = require("commander");
1496
1563
  var import_child_process3 = require("child_process");
1497
1564
  var import_ws = __toESM(require("ws"));
1498
1565
 
@@ -1507,6 +1574,33 @@ function asRecord(v) {
1507
1574
  function asNonEmptyString(v) {
1508
1575
  return typeof v === "string" && v.length > 0 ? v : null;
1509
1576
  }
1577
+ function asInferencePath(v) {
1578
+ return v === "official" || v === "byo" ? v : null;
1579
+ }
1580
+ var HOST_INFERENCE_HOSTS = /* @__PURE__ */ new Set([
1581
+ "api.agentplanet.org",
1582
+ "api.agenticplanet.space"
1583
+ ]);
1584
+ function asHostInferenceUrl(v) {
1585
+ const raw = asNonEmptyString(v);
1586
+ if (!raw) return null;
1587
+ try {
1588
+ const u = new URL(raw);
1589
+ if (u.pathname.replace(/\/+$/, "") !== "/api/inference/v1") return null;
1590
+ if (u.search || u.hash) return null;
1591
+ const host = u.hostname.toLowerCase();
1592
+ const loopback = host === "localhost" || host === "127.0.0.1" || host === "::1";
1593
+ if (u.protocol === "https:" && HOST_INFERENCE_HOSTS.has(host)) {
1594
+ return `${u.origin}/api/inference/v1`;
1595
+ }
1596
+ if (u.protocol === "http:" && loopback) {
1597
+ return `${u.origin}/api/inference/v1`;
1598
+ }
1599
+ return null;
1600
+ } catch {
1601
+ return null;
1602
+ }
1603
+ }
1510
1604
  function parseJsonRpcBody(bodyText) {
1511
1605
  let parsed;
1512
1606
  try {
@@ -1598,7 +1692,10 @@ function extractChatEnvelope(message) {
1598
1692
  gateway_message_id: asNonEmptyString(ap.message_id) ?? asNonEmptyString(ap.messageId),
1599
1693
  user_text: extractUserText(message),
1600
1694
  requested_model: requested ? requested.slice(0, 200) : null,
1601
- max_output_tokens: maxOut
1695
+ max_output_tokens: maxOut,
1696
+ hop_id: asNonEmptyString(ap.hop_id),
1697
+ inference_path: asInferencePath(ap.inference_path),
1698
+ host_inference_url: asHostInferenceUrl(ap.host_inference_url)
1602
1699
  };
1603
1700
  }
1604
1701
  function normalizeEvent(body, opts = {}) {
@@ -1657,6 +1754,115 @@ var DedupeStore = class {
1657
1754
  }
1658
1755
  };
1659
1756
 
1757
+ // src/commands/official-hop-door.ts
1758
+ var import_node_http = __toESM(require("http"));
1759
+ function shouldOpenOfficialDoor(opts) {
1760
+ return Boolean(
1761
+ opts.inferencePath === "official" && opts.hopId?.trim() && asHostInferenceUrl(opts.hostInferenceUrl) && opts.jwt?.trim()
1762
+ );
1763
+ }
1764
+ function readBody(req) {
1765
+ return new Promise((resolve, reject) => {
1766
+ const chunks = [];
1767
+ req.on("data", (c) => chunks.push(Buffer.from(c)));
1768
+ req.on("end", () => resolve(Buffer.concat(chunks)));
1769
+ req.on("error", reject);
1770
+ });
1771
+ }
1772
+ function send(res, status, body, contentType = "application/json") {
1773
+ res.writeHead(status, {
1774
+ "content-type": contentType,
1775
+ "content-length": String(body.length)
1776
+ });
1777
+ res.end(body);
1778
+ }
1779
+ async function handleDoorRequest(req, res, opts) {
1780
+ const path = (req.url ?? "").split("?")[0];
1781
+ if (req.method !== "POST" || path !== "/v1/chat/completions" && path !== "/chat/completions") {
1782
+ send(res, 404, Buffer.from('{"error":"not_found"}'));
1783
+ return;
1784
+ }
1785
+ let payload;
1786
+ try {
1787
+ const raw = await readBody(req);
1788
+ payload = JSON.parse(raw.length ? raw.toString("utf-8") : "{}");
1789
+ } catch {
1790
+ send(res, 400, Buffer.from('{"error":"invalid_json"}'));
1791
+ return;
1792
+ }
1793
+ if (payload === null || typeof payload !== "object" || Array.isArray(payload)) {
1794
+ send(res, 400, Buffer.from('{"error":"invalid_json"}'));
1795
+ return;
1796
+ }
1797
+ const body = { ...payload };
1798
+ delete body.agent_id;
1799
+ body.hop_id = opts.hopId;
1800
+ const headers = {
1801
+ authorization: `Bearer ${opts.jwt}`,
1802
+ "content-type": "application/json",
1803
+ "X-Hop-Id": opts.hopId
1804
+ };
1805
+ if (opts.agentId) headers["X-Agent-Id"] = opts.agentId;
1806
+ try {
1807
+ const upstream = await opts.fetchFn(opts.upstream, {
1808
+ method: "POST",
1809
+ headers,
1810
+ body: JSON.stringify(body)
1811
+ });
1812
+ const out = Buffer.from(await upstream.arrayBuffer());
1813
+ const ct = upstream.headers.get("content-type") || "application/json";
1814
+ send(res, upstream.status, out, ct);
1815
+ } catch (err) {
1816
+ const msg = err instanceof Error ? err.message : String(err);
1817
+ send(
1818
+ res,
1819
+ 502,
1820
+ Buffer.from(JSON.stringify({ error: `upstream_unreachable:${msg.slice(0, 120)}` }))
1821
+ );
1822
+ }
1823
+ }
1824
+ function closeServer(server) {
1825
+ return new Promise((resolve) => {
1826
+ server.closeAllConnections?.();
1827
+ server.close(() => resolve());
1828
+ });
1829
+ }
1830
+ async function startOfficialHopDoor(opts) {
1831
+ const dest = asHostInferenceUrl(opts.hostInferenceUrl);
1832
+ const hopId = opts.hopId.trim();
1833
+ const jwt = opts.jwt.trim();
1834
+ if (!dest || !hopId || !jwt) return null;
1835
+ const fetchFn = opts.fetchFn ?? fetch;
1836
+ const upstream = `${dest}/chat/completions`;
1837
+ const server = import_node_http.default.createServer((req, res) => {
1838
+ void handleDoorRequest(req, res, {
1839
+ upstream,
1840
+ hopId,
1841
+ agentId: opts.agentId,
1842
+ jwt,
1843
+ fetchFn
1844
+ });
1845
+ });
1846
+ try {
1847
+ await new Promise((resolve, reject) => {
1848
+ server.once("error", reject);
1849
+ server.listen(0, "127.0.0.1", () => resolve());
1850
+ });
1851
+ } catch {
1852
+ return null;
1853
+ }
1854
+ const addr = server.address();
1855
+ const port = typeof addr === "object" && addr ? addr.port : 0;
1856
+ if (!port) {
1857
+ await closeServer(server);
1858
+ return null;
1859
+ }
1860
+ return {
1861
+ baseUrl: `http://127.0.0.1:${port}/v1`,
1862
+ close: () => closeServer(server)
1863
+ };
1864
+ }
1865
+
1660
1866
  // src/commands/chat-writeback.ts
1661
1867
  var DEFAULT_COMPLETE_TIMEOUT_MS = 12e4;
1662
1868
  var DEFAULT_WRITEBACK_TIMEOUT_MS = 3e4;
@@ -1823,6 +2029,34 @@ async function mintAgentJwt(opts, fetchFn = fetch) {
1823
2029
  function clearAgentJwtCache() {
1824
2030
  cachedJwt = null;
1825
2031
  }
2032
+ function completeInferenceEnv(event, opts, jwt, door) {
2033
+ const extra = { ACN_AGENT_ID: opts.agentId };
2034
+ const chat = event.chat;
2035
+ if (chat?.hop_id) extra.ACN_CHAT_HOP_ID = chat.hop_id;
2036
+ if (chat?.inference_path) extra.ACN_INFERENCE_PATH = chat.inference_path;
2037
+ if (chat?.host_inference_url) {
2038
+ extra.ACN_HOST_INFERENCE_URL = chat.host_inference_url;
2039
+ }
2040
+ if (jwt) extra.ACN_AGENT_JWT = jwt;
2041
+ if (door?.baseUrl && jwt) {
2042
+ extra.OPENAI_BASE_URL = door.baseUrl;
2043
+ extra.OPENAI_API_KEY = jwt;
2044
+ }
2045
+ return { ...process.env, ...extra };
2046
+ }
2047
+ function completeInferenceHeaders(event, opts) {
2048
+ const headers = {
2049
+ "content-type": "application/json"
2050
+ };
2051
+ if (opts.agentId) headers["X-ACN-Agent-Id"] = opts.agentId;
2052
+ const chat = event.chat;
2053
+ if (chat?.hop_id) headers["X-ACN-Hop-Id"] = chat.hop_id;
2054
+ if (chat?.inference_path) headers["X-ACN-Inference-Path"] = chat.inference_path;
2055
+ if (chat?.host_inference_url) {
2056
+ headers["X-ACN-Host-Inference-Url"] = chat.host_inference_url;
2057
+ }
2058
+ return headers;
2059
+ }
1826
2060
  async function completeViaHttp(event, opts, deps) {
1827
2061
  const fetchFn = deps.fetchFn ?? fetch;
1828
2062
  const timeoutMs = opts.completeTimeoutMs ?? DEFAULT_COMPLETE_TIMEOUT_MS;
@@ -1831,7 +2065,7 @@ async function completeViaHttp(event, opts, deps) {
1831
2065
  try {
1832
2066
  const res = await fetchFn(opts.completeUrl, {
1833
2067
  method: "POST",
1834
- headers: { "content-type": "application/json" },
2068
+ headers: completeInferenceHeaders(event, opts),
1835
2069
  body: JSON.stringify(event),
1836
2070
  signal: controller.signal
1837
2071
  });
@@ -1856,13 +2090,16 @@ async function completeViaHttp(event, opts, deps) {
1856
2090
  clearTimeout(timer);
1857
2091
  }
1858
2092
  }
1859
- function completeViaExec(event, opts, deps) {
2093
+ function spawnCompleteExec(event, opts, deps, jwt, door) {
1860
2094
  const spawnFn = deps.spawnFn ?? import_child_process.spawn;
1861
2095
  const timeoutMs = opts.completeTimeoutMs ?? DEFAULT_COMPLETE_TIMEOUT_MS;
1862
2096
  const body = Buffer.from(JSON.stringify(event), "utf-8");
1863
2097
  return new Promise((resolve) => {
1864
2098
  let settled = false;
1865
- const child = spawnFn(opts.completeExec, { shell: true });
2099
+ const child = spawnFn(opts.completeExec, {
2100
+ shell: true,
2101
+ env: completeInferenceEnv(event, opts, jwt, door)
2102
+ });
1866
2103
  const stdout = [];
1867
2104
  const stderr = [];
1868
2105
  const finish = (result) => {
@@ -1901,6 +2138,44 @@ function completeViaExec(event, opts, deps) {
1901
2138
  child.stdin?.end(body);
1902
2139
  });
1903
2140
  }
2141
+ async function completeViaExec(event, opts, deps, jwt) {
2142
+ let door = null;
2143
+ const logFn = deps.logFn ?? ((line) => console.error(line));
2144
+ try {
2145
+ if (shouldOpenOfficialDoor({
2146
+ inferencePath: event.chat?.inference_path,
2147
+ hopId: event.chat?.hop_id,
2148
+ hostInferenceUrl: event.chat?.host_inference_url,
2149
+ jwt
2150
+ })) {
2151
+ try {
2152
+ door = await startOfficialHopDoor({
2153
+ hostInferenceUrl: event.chat.host_inference_url,
2154
+ hopId: event.chat.hop_id,
2155
+ agentId: opts.agentId,
2156
+ jwt,
2157
+ fetchFn: deps.fetchFn
2158
+ });
2159
+ } catch {
2160
+ door = null;
2161
+ }
2162
+ if (door) {
2163
+ logFn(
2164
+ `[acn listen] official_door chat_id=${event.chat.chat_id} base=${door.baseUrl}`
2165
+ );
2166
+ } else {
2167
+ logFn(
2168
+ `[acn listen] official_door_skipped chat_id=${event.chat.chat_id}`
2169
+ );
2170
+ }
2171
+ }
2172
+ return await spawnCompleteExec(event, opts, deps, jwt, door);
2173
+ } finally {
2174
+ if (door) {
2175
+ await door.close().catch(() => void 0);
2176
+ }
2177
+ }
2178
+ }
1904
2179
  async function postWriteback(event, complete, opts, deps) {
1905
2180
  const chat = event.chat;
1906
2181
  if (!chat) return { ok: false, reason: "no_chat_envelope" };
@@ -2019,7 +2294,12 @@ async function postWriteback(event, complete, opts, deps) {
2019
2294
  async function handleChatWriteback(event, opts, deps = {}) {
2020
2295
  const logFn = deps.logFn ?? ((line) => console.error(line));
2021
2296
  if (!event.chat) return { ok: false, reason: "no_chat_envelope" };
2022
- const completed = opts.completeUrl ? await completeViaHttp(event, opts, deps) : await completeViaExec(event, opts, deps);
2297
+ let jwt = null;
2298
+ if (event.chat.inference_path === "official" && opts.completeExec) {
2299
+ const minted = await mintAgentJwt(opts, deps.fetchFn ?? fetch);
2300
+ if (minted.ok) jwt = minted.token;
2301
+ }
2302
+ const completed = opts.completeUrl ? await completeViaHttp(event, opts, deps) : await completeViaExec(event, opts, deps, jwt);
2023
2303
  if (!completed.ok) {
2024
2304
  logFn(
2025
2305
  `[acn listen] chat_complete_failed chat_id=${event.chat.chat_id} message_id=${event.message_id} reason=${completed.reason}`
@@ -2244,7 +2524,7 @@ function formatWakeFailed(event, reason) {
2244
2524
  function formatDeduped(event) {
2245
2525
  return `[acn listen] deduped key=${dedupeKey(event)}`;
2246
2526
  }
2247
- function dispatchLocalReceiver(correlationId, bodyText, opts, dedupeStore, send, deps = {}) {
2527
+ function dispatchLocalReceiver(correlationId, bodyText, opts, dedupeStore, send2, deps = {}) {
2248
2528
  const logFn = deps.logFn ?? ((line) => console.error(line));
2249
2529
  const result = processIncomingRequest(
2250
2530
  correlationId,
@@ -2253,7 +2533,7 @@ function dispatchLocalReceiver(correlationId, bodyText, opts, dedupeStore, send,
2253
2533
  dedupeStore,
2254
2534
  deps
2255
2535
  );
2256
- send(result.response);
2536
+ send2(result.response);
2257
2537
  if (result.dedupeHit && result.event) {
2258
2538
  logFn(formatDeduped(result.event));
2259
2539
  return;
@@ -2314,7 +2594,7 @@ function errorResponse(id, status, detail) {
2314
2594
  body: JSON.stringify({ error: detail })
2315
2595
  };
2316
2596
  }
2317
- async function dispatchA2aRequest(frame, opts, send, deps = {}) {
2597
+ async function dispatchA2aRequest(frame, opts, send2, deps = {}) {
2318
2598
  const bodyBuf = decodeBody(frame);
2319
2599
  try {
2320
2600
  if (opts.runtime) {
@@ -2324,7 +2604,7 @@ async function dispatchA2aRequest(frame, opts, send, deps = {}) {
2324
2604
  bodyBuf.toString("utf-8"),
2325
2605
  opts.runtime,
2326
2606
  store,
2327
- send,
2607
+ send2,
2328
2608
  {
2329
2609
  fetchFn: deps.fetchFn,
2330
2610
  spawnFn: deps.spawnFn,
@@ -2334,17 +2614,17 @@ async function dispatchA2aRequest(frame, opts, send, deps = {}) {
2334
2614
  return;
2335
2615
  }
2336
2616
  if (opts.forward) {
2337
- await forwardToHttp(frame, bodyBuf, opts.forward, deps.fetchFn ?? fetch, send);
2617
+ await forwardToHttp(frame, bodyBuf, opts.forward, deps.fetchFn ?? fetch, send2);
2338
2618
  return;
2339
2619
  }
2340
2620
  if (opts.exec) {
2341
- send(await runExec(frame, bodyBuf, opts.exec, deps.spawnFn ?? import_child_process3.spawn));
2621
+ send2(await runExec(frame, bodyBuf, opts.exec, deps.spawnFn ?? import_child_process3.spawn));
2342
2622
  return;
2343
2623
  }
2344
- send(errorResponse(frame.id, 500, "no handler configured"));
2624
+ send2(errorResponse(frame.id, 500, "no handler configured"));
2345
2625
  } catch (err) {
2346
2626
  const msg = err instanceof Error ? err.message : String(err);
2347
- send(errorResponse(frame.id, 502, `handler failed: ${msg}`));
2627
+ send2(errorResponse(frame.id, 502, `handler failed: ${msg}`));
2348
2628
  }
2349
2629
  }
2350
2630
  function buildForwardHeaders(frame) {
@@ -2354,7 +2634,7 @@ function buildForwardHeaders(frame) {
2354
2634
  }
2355
2635
  return headers;
2356
2636
  }
2357
- async function forwardToHttp(frame, bodyBuf, base, fetchFn, send) {
2637
+ async function forwardToHttp(frame, bodyBuf, base, fetchFn, send2) {
2358
2638
  const suffix = frame.path && frame.path !== "/" ? "/" + frame.path.replace(/^\//, "") : "";
2359
2639
  const targetUrl = base.replace(/\/$/, "") + suffix;
2360
2640
  const method = (frame.method ?? "POST").toUpperCase();
@@ -2372,7 +2652,7 @@ async function forwardToHttp(frame, bodyBuf, base, fetchFn, send) {
2372
2652
  const { done, value } = await reader.read();
2373
2653
  if (done) break;
2374
2654
  if (value && value.length > 0) {
2375
- send({
2655
+ send2({
2376
2656
  type: "a2a_stream_chunk",
2377
2657
  id: frame.id,
2378
2658
  seq: seq++,
@@ -2381,17 +2661,17 @@ async function forwardToHttp(frame, bodyBuf, base, fetchFn, send) {
2381
2661
  });
2382
2662
  }
2383
2663
  }
2384
- send({ type: "a2a_stream_end", id: frame.id, status: res.status });
2664
+ send2({ type: "a2a_stream_end", id: frame.id, status: res.status });
2385
2665
  } catch (err) {
2386
2666
  const msg = err instanceof Error ? err.message : String(err);
2387
- send({ type: "a2a_stream_end", id: frame.id, error: msg });
2667
+ send2({ type: "a2a_stream_end", id: frame.id, error: msg });
2388
2668
  } finally {
2389
2669
  reader.releaseLock();
2390
2670
  }
2391
2671
  return;
2392
2672
  }
2393
2673
  const respText = await res.text();
2394
- send({
2674
+ send2({
2395
2675
  type: "a2a_response",
2396
2676
  id: frame.id,
2397
2677
  status: res.status,
@@ -2502,12 +2782,12 @@ function runListener(cfg) {
2502
2782
  if (!frame || typeof frame !== "object") return;
2503
2783
  const f = frame;
2504
2784
  if (f.type === "a2a_request" && typeof f.id === "string") {
2505
- const send = (out) => {
2785
+ const send2 = (out) => {
2506
2786
  if (ws.readyState === import_ws.default.OPEN) {
2507
2787
  ws.send(JSON.stringify(out));
2508
2788
  }
2509
2789
  };
2510
- void dispatchA2aRequest(f, cfg, send, { dedupeStore });
2790
+ void dispatchA2aRequest(f, cfg, send2, { dedupeStore });
2511
2791
  }
2512
2792
  });
2513
2793
  ws.on("close", (code, reason) => {
@@ -2556,7 +2836,7 @@ function validateListenHandlerFlags(opts) {
2556
2836
  });
2557
2837
  }
2558
2838
  function listenCommand() {
2559
- const cmd = new import_commander10.Command("listen").description(
2839
+ const cmd = new import_commander11.Command("listen").description(
2560
2840
  "Hold an outbound connection to ACN and answer relayed A2A requests in real time (ADR-0012 Mode B). Prefer --runtime for production; --forward/--exec remain as compatibility tunnels."
2561
2841
  ).option(
2562
2842
  "--runtime <id>",
@@ -2734,7 +3014,7 @@ function listenCommand() {
2734
3014
  }
2735
3015
 
2736
3016
  // src/commands/delivery.ts
2737
- var import_commander11 = require("commander");
3017
+ var import_commander12 = require("commander");
2738
3018
  var DELIVERY_DESC = {
2739
3019
  direct: "direct (Mode A) \u2014 ACN dials your public A2A endpoint over HTTP",
2740
3020
  relay: "relay (Mode B) \u2014 hold an outbound WebSocket with `acn listen`; no public URL",
@@ -2773,7 +3053,7 @@ function formatDelivery(d) {
2773
3053
  return lines.join("\n");
2774
3054
  }
2775
3055
  function deliveryCommand() {
2776
- const cmd = new import_commander11.Command("delivery").description(
3056
+ const cmd = new import_commander12.Command("delivery").description(
2777
3057
  "Inbound delivery transport (Mode A direct / Mode B relay). Orthogonal to reception policy (`acn inbox mode`)."
2778
3058
  );
2779
3059
  cmd.command("get").description("Show derived delivery transport (direct | relay | none)").option("-i, --agent-id <id>", "Agent ID (defaults to config)").action(async (opts) => {
@@ -2834,7 +3114,7 @@ function deliveryCommand() {
2834
3114
  }
2835
3115
 
2836
3116
  // src/commands/session.ts
2837
- var import_commander12 = require("commander");
3117
+ var import_commander13 = require("commander");
2838
3118
  function requireAgentId4() {
2839
3119
  const config = loadConfig();
2840
3120
  if (!config.api_key) {
@@ -2879,7 +3159,7 @@ function formatEntry2(s, index) {
2879
3159
  return lines.join("\n");
2880
3160
  }
2881
3161
  function sessionCommand() {
2882
- const cmd = new import_commander12.Command("session").description(
3162
+ const cmd = new import_commander13.Command("session").description(
2883
3163
  "Real-time session layer: bidirectional channel between two agents"
2884
3164
  );
2885
3165
  cmd.command("invite <target_agent_id>").description("Invite an agent to a real-time session").option("--ttl-seconds <s>", "Session TTL in seconds (60\u20131800, default 300)", parseInt).option("--metadata <json>", "Optional JSON object attached to the invitation (max 4KB)").action(
@@ -2957,7 +3237,7 @@ ${formatEntry2(res)}`);
2957
3237
  }
2958
3238
 
2959
3239
  // src/commands/subnet.ts
2960
- var import_commander13 = require("commander");
3240
+ var import_commander14 = require("commander");
2961
3241
  function requireAgentId5() {
2962
3242
  const config = loadConfig();
2963
3243
  if (!config.api_key) {
@@ -2970,7 +3250,7 @@ function requireAgentId5() {
2970
3250
  }
2971
3251
  return config.agent_id;
2972
3252
  }
2973
- function requireApiKey() {
3253
+ function requireApiKey2() {
2974
3254
  const config = loadConfig();
2975
3255
  if (!config.api_key) {
2976
3256
  console.error("No API key found. Run `acn join` first or `acn config set api-key <key>`.");
@@ -3045,7 +3325,7 @@ function formatSubnet(s, index) {
3045
3325
  return lines.join("\n");
3046
3326
  }
3047
3327
  function subnetCommand() {
3048
- const cmd = new import_commander13.Command("subnet").description("Manage ACN subnets");
3328
+ const cmd = new import_commander14.Command("subnet").description("Manage ACN subnets");
3049
3329
  cmd.command("list").description(
3050
3330
  "List subnets. Without --all/--parent shows only subnets you have joined."
3051
3331
  ).option("--all", "Show all public subnets on ACN (not just your own)").option(
@@ -3262,7 +3542,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
3262
3542
  handleError(err);
3263
3543
  }
3264
3544
  });
3265
- const requests = new import_commander13.Command("requests").description(
3545
+ const requests = new import_commander14.Command("requests").description(
3266
3546
  "Manage join-requests for a subnet (ADR-0004)"
3267
3547
  );
3268
3548
  requests.command("list <subnet_id>").description(
@@ -3276,7 +3556,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
3276
3556
  "join_request"
3277
3557
  ).option("--limit <n>", "Page size (1-500, default 100)", "100").option("--offset <n>", "Page offset (default 0)", "0").action(
3278
3558
  async (subnetId, opts) => {
3279
- requireApiKey();
3559
+ requireApiKey2();
3280
3560
  const params = {};
3281
3561
  if (opts.status) params.status = opts.status;
3282
3562
  if (opts.kind) params.kind = opts.kind;
@@ -3342,7 +3622,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
3342
3622
  });
3343
3623
  requests.command("approve <subnet_id>").description("Owner-only: approve a pending join_request (CAS pending \u2192 approved).").requiredOption("--request-id <rid>", "Join request ID to approve").option("--note <text>", "Optional audit note (\u2264500 chars)").action(
3344
3624
  async (subnetId, opts) => {
3345
- requireApiKey();
3625
+ requireApiKey2();
3346
3626
  const body = {};
3347
3627
  if (opts.note !== void 0) body.note = opts.note;
3348
3628
  try {
@@ -3361,7 +3641,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
3361
3641
  );
3362
3642
  requests.command("reject <subnet_id>").description("Owner-only: reject a pending join_request (CAS pending \u2192 rejected).").requiredOption("--request-id <rid>", "Join request ID to reject").option("--note <text>", "Optional audit note (\u2264500 chars)").action(
3363
3643
  async (subnetId, opts) => {
3364
- requireApiKey();
3644
+ requireApiKey2();
3365
3645
  const body = {};
3366
3646
  if (opts.note !== void 0) body.note = opts.note;
3367
3647
  try {
@@ -3382,7 +3662,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
3382
3662
  "Applicant-only: withdraw your own pending join_request (CAS pending \u2192 withdrawn)."
3383
3663
  ).requiredOption("--request-id <rid>", "Your join request ID").option("--note <text>", "Optional audit note (\u2264500 chars)").action(
3384
3664
  async (subnetId, opts) => {
3385
- requireApiKey();
3665
+ requireApiKey2();
3386
3666
  const body = {};
3387
3667
  if (opts.note !== void 0) body.note = opts.note;
3388
3668
  try {
@@ -3404,14 +3684,14 @@ ${JSON.stringify(res.agents, null, 2)}`);
3404
3684
  }
3405
3685
  );
3406
3686
  cmd.addCommand(requests);
3407
- const invitations = new import_commander13.Command("invitations").description(
3687
+ const invitations = new import_commander14.Command("invitations").description(
3408
3688
  "Manage invitations on a subnet (ADR-0004)"
3409
3689
  );
3410
3690
  invitations.command("send <subnet_id>").description(
3411
3691
  "Owner-only: invite an agent to a subnet. Auto-merges with a target's pending join_request (collapses to auto-approval)."
3412
3692
  ).requiredOption("--agent-id <aid>", "Agent ID to invite").option("--note <text>", "Optional audit note (\u2264500 chars)").action(
3413
3693
  async (subnetId, opts) => {
3414
- requireApiKey();
3694
+ requireApiKey2();
3415
3695
  const body = { agent_id: opts.agentId };
3416
3696
  if (opts.note !== void 0) body.note = opts.note;
3417
3697
  try {
@@ -3430,7 +3710,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
3430
3710
  "Filter by status: pending | approved | rejected | withdrawn"
3431
3711
  ).option("--limit <n>", "Page size (1-500, default 100)", "100").option("--offset <n>", "Page offset (default 0)", "0").action(
3432
3712
  async (subnetId, opts) => {
3433
- requireApiKey();
3713
+ requireApiKey2();
3434
3714
  const params = {};
3435
3715
  if (opts.status) params.status = opts.status;
3436
3716
  if (opts.limit) params.limit = opts.limit;
@@ -3483,7 +3763,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
3483
3763
  "Invitee-only: accept a pending invitation (CAS pending \u2192 approved). Side effect: you join the subnet."
3484
3764
  ).requiredOption("--invitation-id <iid>", "Invitation ID to accept").option("--note <text>", "Optional audit note (\u2264500 chars)").action(
3485
3765
  async (subnetId, opts) => {
3486
- requireApiKey();
3766
+ requireApiKey2();
3487
3767
  const body = {};
3488
3768
  if (opts.note !== void 0) body.note = opts.note;
3489
3769
  try {
@@ -3504,7 +3784,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
3504
3784
  "Invitee-only: reject a pending invitation (CAS pending \u2192 rejected). No membership change."
3505
3785
  ).requiredOption("--invitation-id <iid>", "Invitation ID to reject").option("--note <text>", "Optional audit note (\u2264500 chars)").action(
3506
3786
  async (subnetId, opts) => {
3507
- requireApiKey();
3787
+ requireApiKey2();
3508
3788
  const body = {};
3509
3789
  if (opts.note !== void 0) body.note = opts.note;
3510
3790
  try {
@@ -3525,7 +3805,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
3525
3805
  "Owner-only: cancel a pending invitation (CAS pending \u2192 withdrawn)."
3526
3806
  ).requiredOption("--invitation-id <iid>", "Invitation ID to cancel").action(
3527
3807
  async (subnetId, opts) => {
3528
- requireApiKey();
3808
+ requireApiKey2();
3529
3809
  try {
3530
3810
  const res = await acnDelete(
3531
3811
  `/subnets/${subnetId}/invitations/${opts.invitationId}`
@@ -3540,12 +3820,12 @@ ${JSON.stringify(res.agents, null, 2)}`);
3540
3820
  }
3541
3821
  );
3542
3822
  cmd.addCommand(invitations);
3543
- const allowlist = new import_commander13.Command("allowlist").description(
3823
+ const allowlist = new import_commander14.Command("allowlist").description(
3544
3824
  "Manage a subnet allowlist (ADR-0004)"
3545
3825
  );
3546
3826
  allowlist.command("list <subnet_id>").description("Owner-only: list allowlist entries for a subnet.").option("--limit <n>", "Page size (1-500, default 100)", "100").option("--offset <n>", "Page offset (default 0)", "0").action(
3547
3827
  async (subnetId, opts) => {
3548
- requireApiKey();
3828
+ requireApiKey2();
3549
3829
  const params = {};
3550
3830
  if (opts.limit) params.limit = opts.limit;
3551
3831
  if (opts.offset) params.offset = opts.offset;
@@ -3574,7 +3854,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
3574
3854
  "Owner-only: pre-authorise an agent on the subnet allowlist. 409 ALREADY_ON_ALLOWLIST on duplicate."
3575
3855
  ).requiredOption("--agent-id <aid>", "Agent ID to add").action(
3576
3856
  async (subnetId, opts) => {
3577
- requireApiKey();
3857
+ requireApiKey2();
3578
3858
  try {
3579
3859
  const res = await acnPost(
3580
3860
  `/subnets/${subnetId}/allowlist`,
@@ -3593,7 +3873,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
3593
3873
  "Owner-only: remove an agent from the subnet allowlist. Idempotent (204 even if missing)."
3594
3874
  ).requiredOption("--agent-id <aid>", "Agent ID to remove").action(
3595
3875
  async (subnetId, opts) => {
3596
- requireApiKey();
3876
+ requireApiKey2();
3597
3877
  try {
3598
3878
  await acnDelete(
3599
3879
  `/subnets/${subnetId}/allowlist/${opts.agentId}`
@@ -3608,7 +3888,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
3608
3888
  }
3609
3889
  );
3610
3890
  cmd.addCommand(allowlist);
3611
- const harness = new import_commander13.Command("harness").description("Manage Org Harness webhook for a subnet");
3891
+ const harness = new import_commander14.Command("harness").description("Manage Org Harness webhook for a subnet");
3612
3892
  harness.command("set <subnet_id>").description("Register an Org Harness webhook on a subnet you own").requiredOption("--url <url>", "Harness webhook URL (HTTPS)").option("--secret <secret>", "HMAC-SHA256 signing secret (recommended)").action(async (subnetId, opts) => {
3613
3893
  const config = loadConfig();
3614
3894
  if (!config.api_key) {
@@ -3651,7 +3931,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
3651
3931
  }
3652
3932
 
3653
3933
  // src/commands/org.ts
3654
- var import_commander14 = require("commander");
3934
+ var import_commander15 = require("commander");
3655
3935
  function formatOrg(o) {
3656
3936
  const lines = [
3657
3937
  ` ID : ${o.org_id}`,
@@ -3668,7 +3948,7 @@ function formatOrg(o) {
3668
3948
  return lines.join("\n");
3669
3949
  }
3670
3950
  function orgCommand() {
3671
- const cmd = new import_commander14.Command("org").description("Manage ACN organisations (Org Harness)");
3951
+ const cmd = new import_commander15.Command("org").description("Manage ACN organisations (Org Harness)");
3672
3952
  cmd.command("create").description("Create an Org (binds/creates a subnet fence)").requiredOption("--name <name>", "Display name").option("--steward <agent_id>", "Steward agent (required for human JWT callers)").option("--subnet <slug>", "Bind existing subnet slug (must be owned by steward)").option("--join-policy <policy>", "open | approval", "open").option("--private", "Private subnet fence", false).option("--harness-url <url>", "Register Org Harness webhook on the fence subnet").option("--harness-secret <secret>", "HMAC secret for harness webhook").action(
3673
3953
  async (opts) => {
3674
3954
  try {
@@ -3936,7 +4216,7 @@ function orgCommand() {
3936
4216
  }
3937
4217
 
3938
4218
  // src/commands/follow.ts
3939
- var import_commander15 = require("commander");
4219
+ var import_commander16 = require("commander");
3940
4220
  function requireAgentId6() {
3941
4221
  const config = loadConfig();
3942
4222
  if (!config.api_key) {
@@ -3959,7 +4239,7 @@ function formatAgent2(a, i) {
3959
4239
  ].join("\n");
3960
4240
  }
3961
4241
  function followCommand() {
3962
- const cmd = new import_commander15.Command("follow").description("Follow/unfollow agents and inspect follow graph");
4242
+ const cmd = new import_commander16.Command("follow").description("Follow/unfollow agents and inspect follow graph");
3963
4243
  cmd.command("add <target_id>").description("Follow another agent").option("-i, --agent-id <id>", "Agent ID (defaults to config)").action(async (targetId, opts) => {
3964
4244
  const agentId = opts.agentId ?? requireAgentId6();
3965
4245
  try {
@@ -4050,7 +4330,7 @@ function followCommand() {
4050
4330
  }
4051
4331
 
4052
4332
  // src/commands/wallet.ts
4053
- var import_commander16 = require("commander");
4333
+ var import_commander17 = require("commander");
4054
4334
  function requireAgentId7() {
4055
4335
  const config = loadConfig();
4056
4336
  if (!config.api_key) {
@@ -4093,7 +4373,7 @@ async function showWalletInfo(opts) {
4093
4373
  }
4094
4374
  }
4095
4375
  function walletCommand() {
4096
- const cmd = new import_commander16.Command("wallet").description("View and manage agent's wallet & payment info");
4376
+ const cmd = new import_commander17.Command("wallet").description("View and manage agent's wallet & payment info");
4097
4377
  cmd.command("info", { isDefault: true }).description("Show wallet, payment methods, pricing, and ERC-8004 status").option("-i, --agent-id <id>", "Agent ID (defaults to config)").action(showWalletInfo);
4098
4378
  cmd.command("set-capability").description("Declare which payment methods, networks, and wallets you accept").requiredOption(
4099
4379
  "--methods <csv>",
@@ -4272,7 +4552,7 @@ function walletCommand() {
4272
4552
  }
4273
4553
 
4274
4554
  // src/commands/pay.ts
4275
- var import_commander17 = require("commander");
4555
+ var import_commander18 = require("commander");
4276
4556
  function requireAgentId8() {
4277
4557
  const config = loadConfig();
4278
4558
  if (!config.api_key) {
@@ -4286,8 +4566,8 @@ function requireAgentId8() {
4286
4566
  return config.agent_id;
4287
4567
  }
4288
4568
  function payCommand() {
4289
- const cmd = new import_commander17.Command("pay").description("Manage payment tasks between agents");
4290
- const createCmd = new import_commander17.Command("create").description("Create a payment task to another agent");
4569
+ const cmd = new import_commander18.Command("pay").description("Manage payment tasks between agents");
4570
+ const createCmd = new import_commander18.Command("create").description("Create a payment task to another agent");
4291
4571
  createCmd.requiredOption("--to <agent>", "Recipient agent ID").requiredOption("--amount <n>", "Payment amount (positive number)").requiredOption("--currency <c>", "Currency code, e.g. USD, USDC").requiredOption("--method <m>", "Payment method, e.g. usdc, eth, platform_credits").requiredOption("--network <n>", "Network, e.g. ethereum, base, solana").option("--description <text>", "Free-text description for the payment task").option("--metadata <json>", "Additional metadata as JSON object").action(
4292
4572
  async (opts) => {
4293
4573
  const fromAgent = requireAgentId8();
@@ -4333,7 +4613,7 @@ function payCommand() {
4333
4613
  }
4334
4614
  }
4335
4615
  );
4336
- const confirmCmd = new import_commander17.Command("confirm").description(
4616
+ const confirmCmd = new import_commander18.Command("confirm").description(
4337
4617
  "Confirm an external payment has been made (buyer only)"
4338
4618
  );
4339
4619
  confirmCmd.requiredOption("--task-id <id>", "Payment task ID to confirm").requiredOption(
@@ -4355,7 +4635,7 @@ function payCommand() {
4355
4635
  handleError(err);
4356
4636
  }
4357
4637
  });
4358
- const statusCmd = new import_commander17.Command("status").description(
4638
+ const statusCmd = new import_commander18.Command("status").description(
4359
4639
  "Show payment tasks for the authenticated agent"
4360
4640
  );
4361
4641
  statusCmd.option("--status <s>", "Filter by status (e.g. created, payment_confirmed)").option("--limit <n>", "Max results (default 50)", "50").action(async (opts) => {
@@ -4378,7 +4658,7 @@ function payCommand() {
4378
4658
 
4379
4659
  // src/index.ts
4380
4660
  var { version } = require_package();
4381
- var program = new import_commander18.Command();
4661
+ var program = new import_commander19.Command();
4382
4662
  program.name("acn").description("ACN CLI \u2014 Agent Collaboration Network command-line interface").version(version).option("--json", "Output raw JSON (useful for agent parsing)").hook("preAction", (thisCommand) => {
4383
4663
  const opts = thisCommand.opts();
4384
4664
  if (opts.json) setJsonMode(true);
@@ -4390,6 +4670,7 @@ program.addCommand(rotateKeyCommand());
4390
4670
  program.addCommand(agentsCommand());
4391
4671
  program.addCommand(tasksCommand());
4392
4672
  program.addCommand(messageCommand());
4673
+ program.addCommand(invokeCommand());
4393
4674
  program.addCommand(notifyCommand());
4394
4675
  program.addCommand(inboxCommand());
4395
4676
  program.addCommand(listenCommand());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acnlabs/acn-cli",
3
- "version": "1.0.3",
3
+ "version": "1.0.8",
4
4
  "description": "Official CLI for ACN (Agent Collaboration Network) \u2014 zero-integration agent access",
5
5
  "main": "dist/index.js",
6
6
  "bin": {