@acnlabs/acn-cli 0.11.0 → 0.12.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/index.js +92 -17
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,67 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
5
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// package.json
|
|
9
|
+
var require_package = __commonJS({
|
|
10
|
+
"package.json"(exports2, module2) {
|
|
11
|
+
module2.exports = {
|
|
12
|
+
name: "@acnlabs/acn-cli",
|
|
13
|
+
version: "0.12.0",
|
|
14
|
+
description: "Official CLI for ACN (Agent Collaboration Network) \u2014 zero-integration agent access",
|
|
15
|
+
main: "dist/index.js",
|
|
16
|
+
bin: {
|
|
17
|
+
acn: "dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
files: [
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
scripts: {
|
|
24
|
+
build: "tsup",
|
|
25
|
+
dev: "tsup --watch",
|
|
26
|
+
typecheck: "tsc --noEmit",
|
|
27
|
+
"typecheck:tests": "tsc --noEmit -p tsconfig.tests.json",
|
|
28
|
+
test: "vitest run",
|
|
29
|
+
prepublishOnly: "npm run build"
|
|
30
|
+
},
|
|
31
|
+
keywords: [
|
|
32
|
+
"acn",
|
|
33
|
+
"agent",
|
|
34
|
+
"ai",
|
|
35
|
+
"cli",
|
|
36
|
+
"collaboration",
|
|
37
|
+
"a2a"
|
|
38
|
+
],
|
|
39
|
+
author: "acnlabs",
|
|
40
|
+
license: "Apache-2.0",
|
|
41
|
+
repository: {
|
|
42
|
+
type: "git",
|
|
43
|
+
url: "https://github.com/acnlabs/ACN.git",
|
|
44
|
+
directory: "clients/cli"
|
|
45
|
+
},
|
|
46
|
+
homepage: "https://github.com/acnlabs/ACN#readme",
|
|
47
|
+
bugs: {
|
|
48
|
+
url: "https://github.com/acnlabs/ACN/issues"
|
|
49
|
+
},
|
|
50
|
+
dependencies: {
|
|
51
|
+
commander: "^12.0.0"
|
|
52
|
+
},
|
|
53
|
+
devDependencies: {
|
|
54
|
+
"@types/node": "^20.0.0",
|
|
55
|
+
tsup: "^8.0.0",
|
|
56
|
+
typescript: "^5.0.0",
|
|
57
|
+
vitest: "^3.0.5"
|
|
58
|
+
},
|
|
59
|
+
engines: {
|
|
60
|
+
node: ">=18.0.0"
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
});
|
|
3
65
|
|
|
4
66
|
// src/index.ts
|
|
5
67
|
var import_commander15 = require("commander");
|
|
@@ -132,6 +194,15 @@ var AcnApiError = class extends Error {
|
|
|
132
194
|
status;
|
|
133
195
|
body;
|
|
134
196
|
};
|
|
197
|
+
function extractDetail(body) {
|
|
198
|
+
if (typeof body !== "object" || body === null) return String(body);
|
|
199
|
+
const b = body;
|
|
200
|
+
if (typeof b["message"] === "string") {
|
|
201
|
+
return typeof b["error_code"] === "string" ? `${b["error_code"]}: ${b["message"]}` : b["message"];
|
|
202
|
+
}
|
|
203
|
+
if (typeof b["detail"] === "string") return b["detail"];
|
|
204
|
+
return JSON.stringify(b);
|
|
205
|
+
}
|
|
135
206
|
async function acnFetch(path, options = {}) {
|
|
136
207
|
const config = loadConfig();
|
|
137
208
|
const { params, ...fetchOptions } = options;
|
|
@@ -156,8 +227,7 @@ async function acnFetch(path, options = {}) {
|
|
|
156
227
|
} catch {
|
|
157
228
|
body = await res.text();
|
|
158
229
|
}
|
|
159
|
-
|
|
160
|
-
throw new AcnApiError(res.status, body, `HTTP ${res.status}: ${detail}`);
|
|
230
|
+
throw new AcnApiError(res.status, body, `HTTP ${res.status}: ${extractDetail(body)}`);
|
|
161
231
|
}
|
|
162
232
|
if (res.status === 204 || res.headers.get("content-length") === "0") {
|
|
163
233
|
return {};
|
|
@@ -394,6 +464,7 @@ function formatTask(t) {
|
|
|
394
464
|
if (t.reward && t.reward !== "0") {
|
|
395
465
|
lines.push(` Reward : ${t.reward} ${t.reward_currency ?? ""}`);
|
|
396
466
|
}
|
|
467
|
+
if (t.subnet_slug) lines.push(` Subnet : ${t.subnet_slug}`);
|
|
397
468
|
if (t.description) lines.push(` Desc : ${t.description.slice(0, 120)}`);
|
|
398
469
|
if (t.created_at) lines.push(` Created : ${t.created_at}`);
|
|
399
470
|
if (t.deadline) lines.push(` Deadline : ${t.deadline}`);
|
|
@@ -483,7 +554,7 @@ ${formatTask(t)}`).join("\n\n")
|
|
|
483
554
|
handleError(err);
|
|
484
555
|
}
|
|
485
556
|
});
|
|
486
|
-
cmd.command("create").description("Create a new task (as agent)").requiredOption("-t, --title <title>", "Task title (min 3 chars)").requiredOption("-d, --description <text>", "Task description (min 10 chars)").requiredOption("--tags <tags>", "Required skill tags, comma-separated (e.g. coding,review)").option("--deadline <hours>", "Deadline in hours (default: 48)", "48").option("--reward <amount>", "Reward amount (default: 0)", "0").option("--currency <currency>", "Reward currency (e.g. USD, USDC, ap_points)", "ap_points").option("--type <type>", "Task type (e.g. coding, general)", "general").option("--max-participants <n>", "Max participants (default: 1)", "1").option("--max-resubmit <n>", "Max resubmit attempts per participant (default: unlimited)").action(
|
|
557
|
+
cmd.command("create").description("Create a new task (as agent)").requiredOption("-t, --title <title>", "Task title (min 3 chars)").requiredOption("-d, --description <text>", "Task description (min 10 chars)").requiredOption("--tags <tags>", "Required skill tags, comma-separated (e.g. coding,review)").option("--deadline <hours>", "Deadline in hours (default: 48)", "48").option("--reward <amount>", "Reward amount (default: 0)", "0").option("--currency <currency>", "Reward currency (e.g. USD, USDC, ap_points)", "ap_points").option("--type <type>", "Task type (e.g. coding, general)", "general").option("--max-participants <n>", "Max participants (default: 1)", "1").option("--max-resubmit <n>", "Max resubmit attempts per participant (default: unlimited)").option("--subnet <slug>", "Subnet slug to scope the task to (agent must be a member)").action(
|
|
487
558
|
async (opts) => {
|
|
488
559
|
const config = loadConfig();
|
|
489
560
|
if (!config.api_key) {
|
|
@@ -505,6 +576,9 @@ ${formatTask(t)}`).join("\n\n")
|
|
|
505
576
|
if (opts.maxResubmit !== void 0) {
|
|
506
577
|
body.max_resubmit_attempts = parseInt(opts.maxResubmit, 10);
|
|
507
578
|
}
|
|
579
|
+
if (opts.subnet) {
|
|
580
|
+
body.subnet_slug = opts.subnet;
|
|
581
|
+
}
|
|
508
582
|
try {
|
|
509
583
|
const task = await acnPost("/tasks/agent/create", body);
|
|
510
584
|
output(task, [`Task created!
|
|
@@ -1304,7 +1378,7 @@ function formatJoinRequest(r, index) {
|
|
|
1304
1378
|
const prefix = index !== void 0 ? `[${index + 1}] ` : "";
|
|
1305
1379
|
const lines = [
|
|
1306
1380
|
`${prefix}${r.request_id} [${r.kind} / ${r.status}]`,
|
|
1307
|
-
` Subnet : ${r.
|
|
1381
|
+
` Subnet : ${r.slug}`,
|
|
1308
1382
|
` Agent : ${r.agent_id}`,
|
|
1309
1383
|
` InitiatedBy: ${r.initiated_by}`
|
|
1310
1384
|
];
|
|
@@ -1349,12 +1423,12 @@ function formatInviteResponse(res, subnetId, targetAgentId) {
|
|
|
1349
1423
|
function formatSubnet(s, index) {
|
|
1350
1424
|
const prefix = index !== void 0 ? `[${index + 1}] ` : "";
|
|
1351
1425
|
const privacy = s.is_private ? " [private]" : " [public]";
|
|
1352
|
-
const lines = [`${prefix}${s.
|
|
1426
|
+
const lines = [`${prefix}${s.slug}${privacy}`, ` Name : ${s.name}`];
|
|
1353
1427
|
if (s.owner) lines.push(` Owner : ${s.owner}`);
|
|
1354
1428
|
if (s.description) lines.push(` Desc : ${s.description}`);
|
|
1355
1429
|
if (s.created_at) lines.push(` Since : ${s.created_at}`);
|
|
1356
|
-
if (s.parent_subnet_id) {
|
|
1357
|
-
lines.push(` Parent: ${s.parent_subnet_id}`);
|
|
1430
|
+
if (s.parent_slug ?? s.parent_subnet_id) {
|
|
1431
|
+
lines.push(` Parent: ${s.parent_slug ?? s.parent_subnet_id}`);
|
|
1358
1432
|
}
|
|
1359
1433
|
if (s.lifecycle && s.lifecycle !== "persistent") {
|
|
1360
1434
|
const task = s.linked_task_id ? ` (task=${s.linked_task_id})` : "";
|
|
@@ -1524,16 +1598,16 @@ ${JSON.stringify(res.agents, null, 2)}`);
|
|
|
1524
1598
|
name: opts.name,
|
|
1525
1599
|
is_private: !!opts.private
|
|
1526
1600
|
};
|
|
1527
|
-
if (opts.id) body.
|
|
1601
|
+
if (opts.id) body.slug = opts.id;
|
|
1528
1602
|
if (opts.description) body.description = opts.description;
|
|
1529
1603
|
if (joinPolicy !== void 0) body.join_policy = joinPolicy;
|
|
1530
|
-
if (opts.parent) body.
|
|
1604
|
+
if (opts.parent) body.parent_slug = opts.parent;
|
|
1531
1605
|
body.lifecycle = lifecycle;
|
|
1532
1606
|
if (opts.task) body.linked_task_id = opts.task;
|
|
1533
1607
|
try {
|
|
1534
1608
|
const res = await acnPost("/subnets", body);
|
|
1535
1609
|
const lines = [
|
|
1536
|
-
`Subnet created: ${res.
|
|
1610
|
+
`Subnet created: ${res.slug}`,
|
|
1537
1611
|
` Visibility : ${res.is_public ? "public" : "private"}`,
|
|
1538
1612
|
` Gateway A2A: ${res.gateway_a2a_url}`,
|
|
1539
1613
|
` Gateway WS : ${res.gateway_ws_url}`
|
|
@@ -1564,7 +1638,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
|
|
|
1564
1638
|
const lifecycle = res.lifecycle ?? "persistent";
|
|
1565
1639
|
output(
|
|
1566
1640
|
res,
|
|
1567
|
-
`Subnet ${res.
|
|
1641
|
+
`Subnet ${res.slug} lifecycle=${lifecycle}` + (res.linked_task_id ? ` (still linked to task ${res.linked_task_id})` : "")
|
|
1568
1642
|
);
|
|
1569
1643
|
} catch (err) {
|
|
1570
1644
|
handleError(err);
|
|
@@ -1580,7 +1654,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
|
|
|
1580
1654
|
const res = await acnDelete(
|
|
1581
1655
|
`/subnets/${subnetId}`
|
|
1582
1656
|
);
|
|
1583
|
-
output(res, `Subnet ${res.
|
|
1657
|
+
output(res, `Subnet ${res.slug} ${res.status}`);
|
|
1584
1658
|
} catch (err) {
|
|
1585
1659
|
handleError(err);
|
|
1586
1660
|
}
|
|
@@ -1640,7 +1714,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
|
|
|
1640
1714
|
`/subnets/${sid}/join-requests?status=pending&kind=join_request`
|
|
1641
1715
|
);
|
|
1642
1716
|
for (const r of res.items ?? []) {
|
|
1643
|
-
aggregated.push({
|
|
1717
|
+
aggregated.push({ slug: sid, request: r });
|
|
1644
1718
|
}
|
|
1645
1719
|
} catch {
|
|
1646
1720
|
continue;
|
|
@@ -1922,7 +1996,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
|
|
|
1922
1996
|
`/subnets/${subnetId}/allowlist/${opts.agentId}`
|
|
1923
1997
|
);
|
|
1924
1998
|
output(
|
|
1925
|
-
{
|
|
1999
|
+
{ slug: subnetId, agent_id: opts.agentId, removed: true },
|
|
1926
2000
|
`removed ${opts.agentId} from allowlist of subnet ${subnetId}`
|
|
1927
2001
|
);
|
|
1928
2002
|
} catch (err) {
|
|
@@ -1944,7 +2018,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
|
|
|
1944
2018
|
harness_secret: opts.secret ?? null
|
|
1945
2019
|
});
|
|
1946
2020
|
const lines = [
|
|
1947
|
-
`Harness registered on subnet ${res.
|
|
2021
|
+
`Harness registered on subnet ${res.slug}`,
|
|
1948
2022
|
` URL : ${res.harness_url}`,
|
|
1949
2023
|
` Signed : ${opts.secret ? "yes (HMAC-SHA256)" : "no (unsigned)"}`
|
|
1950
2024
|
];
|
|
@@ -1964,7 +2038,7 @@ ${JSON.stringify(res.agents, null, 2)}`);
|
|
|
1964
2038
|
harness_url: null,
|
|
1965
2039
|
harness_secret: null
|
|
1966
2040
|
});
|
|
1967
|
-
output(res, `Harness unregistered from subnet ${res.
|
|
2041
|
+
output(res, `Harness unregistered from subnet ${res.slug}`);
|
|
1968
2042
|
} catch (err) {
|
|
1969
2043
|
handleError(err);
|
|
1970
2044
|
}
|
|
@@ -2415,8 +2489,9 @@ function payCommand() {
|
|
|
2415
2489
|
}
|
|
2416
2490
|
|
|
2417
2491
|
// src/index.ts
|
|
2492
|
+
var { version } = require_package();
|
|
2418
2493
|
var program = new import_commander15.Command();
|
|
2419
|
-
program.name("acn").description("ACN CLI \u2014 Agent Collaboration Network command-line interface").version(
|
|
2494
|
+
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) => {
|
|
2420
2495
|
const opts = thisCommand.opts();
|
|
2421
2496
|
if (opts.json) setJsonMode(true);
|
|
2422
2497
|
});
|