chainlesschain 0.51.0 → 0.66.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.
Files changed (39) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/.build-hash +1 -1
  3. package/src/assets/web-panel/assets/{AppLayout-Rvi759IS.js → AppLayout-6SPt_8Y_.js} +1 -1
  4. package/src/assets/web-panel/assets/{Dashboard-DBhFxXYQ.js → Dashboard-Br7kCwKJ.js} +2 -2
  5. package/src/assets/web-panel/assets/Dashboard-CKeMmCoT.css +1 -0
  6. package/src/assets/web-panel/assets/{index-uL0cZ8N_.js → index-tN-8TosE.js} +2 -2
  7. package/src/assets/web-panel/index.html +2 -2
  8. package/src/commands/agent-network.js +785 -0
  9. package/src/commands/automation.js +654 -0
  10. package/src/commands/dao.js +565 -0
  11. package/src/commands/did-v2.js +620 -0
  12. package/src/commands/economy.js +578 -0
  13. package/src/commands/evolution.js +391 -0
  14. package/src/commands/hmemory.js +442 -0
  15. package/src/commands/perf.js +433 -0
  16. package/src/commands/pipeline.js +449 -0
  17. package/src/commands/plugin-ecosystem.js +517 -0
  18. package/src/commands/sandbox.js +401 -0
  19. package/src/commands/social.js +311 -0
  20. package/src/commands/sso.js +798 -0
  21. package/src/commands/workflow.js +320 -0
  22. package/src/commands/zkp.js +227 -1
  23. package/src/index.js +21 -0
  24. package/src/lib/agent-economy.js +479 -0
  25. package/src/lib/agent-network.js +1121 -0
  26. package/src/lib/automation-engine.js +948 -0
  27. package/src/lib/dao-governance.js +569 -0
  28. package/src/lib/did-v2-manager.js +1127 -0
  29. package/src/lib/evolution-system.js +453 -0
  30. package/src/lib/hierarchical-memory.js +481 -0
  31. package/src/lib/perf-tuning.js +734 -0
  32. package/src/lib/pipeline-orchestrator.js +928 -0
  33. package/src/lib/plugin-ecosystem.js +1109 -0
  34. package/src/lib/sandbox-v2.js +306 -0
  35. package/src/lib/social-graph-analytics.js +707 -0
  36. package/src/lib/sso-manager.js +841 -0
  37. package/src/lib/workflow-engine.js +454 -1
  38. package/src/lib/zkp-engine.js +249 -20
  39. package/src/assets/web-panel/assets/Dashboard-BS-tzGNj.css +0 -1
@@ -0,0 +1,785 @@
1
+ /**
2
+ * `cc agent-network` (alias `anet`) — CLI port of Phase 24 去中心化Agent网络.
3
+ *
4
+ * Ed25519 Agent DIDs, W3C VC credentials, federated registry (Kademlia
5
+ * k-bucket simulation), challenge-response auth, and cross-org task
6
+ * routing with reputation-weighted agent selection.
7
+ */
8
+
9
+ import { Command } from "commander";
10
+
11
+ import {
12
+ DID_STATUS,
13
+ REG_STATUS,
14
+ AUTH_STATUS,
15
+ CRED_STATUS,
16
+ TASK_STATUS,
17
+ REPUTATION_DIMENSIONS,
18
+ ensureAgentNetworkTables,
19
+ createAgentDID,
20
+ resolveAgentDID,
21
+ listAgentDIDs,
22
+ deactivateAgentDID,
23
+ signWithAgent,
24
+ verifyWithAgent,
25
+ registerAgent,
26
+ unregisterAgent,
27
+ heartbeatAgent,
28
+ discoverAgents,
29
+ sweepStaleAgents,
30
+ addPeer,
31
+ removePeer,
32
+ listPeers,
33
+ startAuth,
34
+ completeAuth,
35
+ validateSession,
36
+ listSessions,
37
+ issueCredential,
38
+ getCredential,
39
+ verifyCredential,
40
+ revokeCredential,
41
+ listCredentials,
42
+ routeTask,
43
+ getTask,
44
+ updateTaskStatus,
45
+ cancelTask,
46
+ listTasks,
47
+ updateReputation,
48
+ getReputation,
49
+ getReputationHistory,
50
+ getTopAgents,
51
+ getNetworkStats,
52
+ getNetworkConfig,
53
+ } from "../lib/agent-network.js";
54
+
55
+ function _dbFromCtx(cmd) {
56
+ const root = cmd?.parent?.parent ?? cmd?.parent;
57
+ return root?._db;
58
+ }
59
+
60
+ function _json(v) {
61
+ console.log(JSON.stringify(v, null, 2));
62
+ }
63
+
64
+ function _fmtTs(ts) {
65
+ if (!ts) return "—";
66
+ return new Date(ts).toISOString();
67
+ }
68
+
69
+ function _parseJsonArg(s, fallback) {
70
+ if (s == null) return fallback;
71
+ try {
72
+ return JSON.parse(s);
73
+ } catch {
74
+ return fallback;
75
+ }
76
+ }
77
+
78
+ export function registerAgentNetworkCommand(program) {
79
+ const anet = new Command("agent-network")
80
+ .alias("anet")
81
+ .description(
82
+ "Decentralized Agent Network (Phase 24) — DID / registry / credentials / task routing",
83
+ )
84
+ .hook("preAction", (thisCmd) => {
85
+ const db = _dbFromCtx(thisCmd);
86
+ if (db) ensureAgentNetworkTables(db);
87
+ });
88
+
89
+ /* ── Catalogs ────────────────────────────────────── */
90
+
91
+ anet
92
+ .command("config")
93
+ .description("Show network constants & reputation weights")
94
+ .option("--json", "JSON output")
95
+ .action((opts) => {
96
+ const cfg = getNetworkConfig();
97
+ if (opts.json) return _json(cfg);
98
+ console.log(`Kademlia: ${cfg.kademliaBits} bits, k=${cfg.kademliaK}`);
99
+ console.log(
100
+ `Session TTL: ${cfg.sessionTtlMs}ms Heartbeat timeout: ${cfg.heartbeatTimeoutMs}ms`,
101
+ );
102
+ console.log(`Reputation dimensions:`);
103
+ for (const d of cfg.reputationDimensions) {
104
+ console.log(` ${d.padEnd(12)} weight=${cfg.reputationWeights[d]}`);
105
+ }
106
+ console.log(
107
+ `Reputation range: [${cfg.reputationRange[0]}, ${cfg.reputationRange[1]}]` +
108
+ ` weekly decay: ${cfg.reputationDecayWeekly}`,
109
+ );
110
+ });
111
+
112
+ anet
113
+ .command("dimensions")
114
+ .description("List reputation dimensions")
115
+ .option("--json", "JSON output")
116
+ .action((opts) => {
117
+ if (opts.json) return _json(REPUTATION_DIMENSIONS);
118
+ for (const d of REPUTATION_DIMENSIONS) console.log(` ${d}`);
119
+ });
120
+
121
+ anet
122
+ .command("task-statuses")
123
+ .description("List task lifecycle statuses")
124
+ .option("--json", "JSON output")
125
+ .action((opts) => {
126
+ const rows = Object.values(TASK_STATUS);
127
+ if (opts.json) return _json(rows);
128
+ for (const r of rows) console.log(` ${r}`);
129
+ });
130
+
131
+ /* ── DID management ──────────────────────────────── */
132
+
133
+ anet
134
+ .command("did-create")
135
+ .description("Create an Agent DID (Ed25519 + DID document)")
136
+ .option("-n, --name <displayName>", "Display name")
137
+ .option(
138
+ "-m, --metadata <json>",
139
+ "Extra metadata (JSON object)",
140
+ (v) => _parseJsonArg(v, {}),
141
+ {},
142
+ )
143
+ .option("--json", "JSON output")
144
+ .action((opts) => {
145
+ const db = _dbFromCtx(anet);
146
+ const r = createAgentDID(db, {
147
+ displayName: opts.name,
148
+ metadata: opts.metadata,
149
+ });
150
+ if (opts.json) return _json(r);
151
+ console.log(`Created ${r.did}`);
152
+ console.log(` publicKey: ${r.publicKey}`);
153
+ });
154
+
155
+ anet
156
+ .command("did-resolve")
157
+ .argument("<did>", "Agent DID")
158
+ .description("Resolve DID → DID document")
159
+ .option("--json", "JSON output")
160
+ .action((did, opts) => {
161
+ const db = _dbFromCtx(anet);
162
+ const r = resolveAgentDID(db, did);
163
+ if (!r) {
164
+ console.error(`Unknown DID: ${did}`);
165
+ process.exit(1);
166
+ }
167
+ if (opts.json) return _json(r);
168
+ console.log(`DID: ${r.did} status=${r.status}`);
169
+ console.log(`publicKey: ${r.publicKey}`);
170
+ console.log(`metadata: ${JSON.stringify(r.metadata)}`);
171
+ });
172
+
173
+ anet
174
+ .command("dids")
175
+ .description("List Agent DIDs")
176
+ .option("-s, --status <status>", "Filter by status (active|deactivated)")
177
+ .option("--limit <n>", "Max rows", (v) => parseInt(v, 10), 50)
178
+ .option("--json", "JSON output")
179
+ .action((opts) => {
180
+ const db = _dbFromCtx(anet);
181
+ const rows = listAgentDIDs(db, {
182
+ status: opts.status,
183
+ limit: opts.limit,
184
+ });
185
+ if (opts.json) return _json(rows);
186
+ for (const r of rows)
187
+ console.log(` ${r.did} [${r.status}] ${JSON.stringify(r.metadata)}`);
188
+ console.log(`(${rows.length} DIDs)`);
189
+ });
190
+
191
+ anet
192
+ .command("did-deactivate")
193
+ .argument("<did>", "Agent DID")
194
+ .description("Deactivate a DID (also forces registry offline)")
195
+ .option("--json", "JSON output")
196
+ .action((did, opts) => {
197
+ const db = _dbFromCtx(anet);
198
+ const r = deactivateAgentDID(db, did);
199
+ if (opts.json) return _json(r);
200
+ if (!r.changed) {
201
+ console.error(`DID not found: ${did}`);
202
+ process.exit(1);
203
+ }
204
+ console.log(`Deactivated ${did}`);
205
+ });
206
+
207
+ anet
208
+ .command("sign")
209
+ .argument("<did>", "Agent DID")
210
+ .argument("<data>", "Data to sign (UTF-8 string)")
211
+ .description("Sign data with agent's Ed25519 key")
212
+ .option("--json", "JSON output")
213
+ .action((did, data, opts) => {
214
+ const db = _dbFromCtx(anet);
215
+ const sig = signWithAgent(db, did, data);
216
+ if (opts.json) return _json({ did, signature: sig });
217
+ console.log(sig);
218
+ });
219
+
220
+ anet
221
+ .command("verify")
222
+ .argument("<did>", "Agent DID")
223
+ .argument("<data>", "Signed data (UTF-8 string)")
224
+ .argument("<signature>", "Signature hex")
225
+ .description("Verify a signature from an agent")
226
+ .option("--json", "JSON output")
227
+ .action((did, data, sig, opts) => {
228
+ const db = _dbFromCtx(anet);
229
+ const ok = verifyWithAgent(db, did, data, sig);
230
+ if (opts.json) return _json({ valid: ok });
231
+ console.log(ok ? "valid" : "invalid");
232
+ if (!ok) process.exit(1);
233
+ });
234
+
235
+ /* ── Federated registry ──────────────────────────── */
236
+
237
+ anet
238
+ .command("register")
239
+ .argument("<did>", "Agent DID")
240
+ .argument("<orgId>", "Owning org id")
241
+ .description("Register an Agent in the federated registry")
242
+ .option(
243
+ "-c, --capabilities <json>",
244
+ "Capabilities (JSON array)",
245
+ (v) => _parseJsonArg(v, []),
246
+ [],
247
+ )
248
+ .option("-e, --endpoint <url>", "Service endpoint")
249
+ .option("--json", "JSON output")
250
+ .action((did, orgId, opts) => {
251
+ const db = _dbFromCtx(anet);
252
+ const r = registerAgent(db, {
253
+ did,
254
+ orgId,
255
+ capabilities: opts.capabilities,
256
+ endpoint: opts.endpoint,
257
+ });
258
+ if (opts.json) return _json(r);
259
+ console.log(`Registered ${r.did} → org=${r.orgId}`);
260
+ console.log(` caps=${JSON.stringify(r.capabilities)}`);
261
+ });
262
+
263
+ anet
264
+ .command("unregister")
265
+ .argument("<did>", "Agent DID")
266
+ .description("Remove an Agent from the registry")
267
+ .option("--json", "JSON output")
268
+ .action((did, opts) => {
269
+ const db = _dbFromCtx(anet);
270
+ const r = unregisterAgent(db, did);
271
+ if (opts.json) return _json(r);
272
+ if (!r.changed) {
273
+ console.error(`Agent not registered: ${did}`);
274
+ process.exit(1);
275
+ }
276
+ console.log(`Unregistered ${did}`);
277
+ });
278
+
279
+ anet
280
+ .command("heartbeat")
281
+ .argument("<did>", "Agent DID")
282
+ .description("Bump last_heartbeat (forces online)")
283
+ .option("--json", "JSON output")
284
+ .action((did, opts) => {
285
+ const db = _dbFromCtx(anet);
286
+ const r = heartbeatAgent(db, did);
287
+ if (opts.json) return _json(r);
288
+ if (!r.changed) {
289
+ console.error(`Agent not registered: ${did}`);
290
+ process.exit(1);
291
+ }
292
+ console.log(`Heartbeat ${did} @ ${_fmtTs(r.heartbeatAt)}`);
293
+ });
294
+
295
+ anet
296
+ .command("discover")
297
+ .description("Discover agents (capability / org / status)")
298
+ .option("-c, --capability <cap>", "Required capability")
299
+ .option("-o, --org <orgId>", "Filter by org")
300
+ .option("-s, --status <status>", "Filter by status", REG_STATUS.ONLINE)
301
+ .option("--limit <n>", "Max rows", (v) => parseInt(v, 10), 50)
302
+ .option("--json", "JSON output")
303
+ .action((opts) => {
304
+ const db = _dbFromCtx(anet);
305
+ const rows = discoverAgents(db, {
306
+ capability: opts.capability,
307
+ orgId: opts.org,
308
+ status: opts.status,
309
+ limit: opts.limit,
310
+ });
311
+ if (opts.json) return _json(rows);
312
+ for (const r of rows)
313
+ console.log(
314
+ ` ${r.agentDid} [${r.status}] org=${r.orgId} caps=${JSON.stringify(r.capabilities)}`,
315
+ );
316
+ console.log(`(${rows.length} agents)`);
317
+ });
318
+
319
+ anet
320
+ .command("sweep")
321
+ .description("Mark stale online agents offline")
322
+ .option("--json", "JSON output")
323
+ .action((opts) => {
324
+ const db = _dbFromCtx(anet);
325
+ const r = sweepStaleAgents(db);
326
+ if (opts.json) return _json(r);
327
+ console.log(`Swept ${r.swept} stale agents`);
328
+ });
329
+
330
+ /* ── Peer (Kademlia) bookkeeping ─────────────────── */
331
+
332
+ anet
333
+ .command("peer-add")
334
+ .argument("<peerId>", "Peer id")
335
+ .description("Add/update a Kademlia peer (k-bucket auto-computed)")
336
+ .option("-e, --endpoint <url>", "Peer endpoint")
337
+ .option("-d, --did <did>", "Agent DID served by peer")
338
+ .option("--json", "JSON output")
339
+ .action((peerId, opts) => {
340
+ const db = _dbFromCtx(anet);
341
+ const r = addPeer(db, {
342
+ peerId,
343
+ endpoint: opts.endpoint,
344
+ agentDid: opts.did,
345
+ });
346
+ if (opts.json) return _json(r);
347
+ console.log(`Peer ${peerId} kBucket=${r.kBucket}`);
348
+ });
349
+
350
+ anet
351
+ .command("peer-remove")
352
+ .argument("<peerId>", "Peer id")
353
+ .description("Remove a peer")
354
+ .option("--json", "JSON output")
355
+ .action((peerId, opts) => {
356
+ const db = _dbFromCtx(anet);
357
+ const r = removePeer(db, peerId);
358
+ if (opts.json) return _json(r);
359
+ if (!r.changed) {
360
+ console.error(`Peer not found: ${peerId}`);
361
+ process.exit(1);
362
+ }
363
+ console.log(`Removed ${peerId}`);
364
+ });
365
+
366
+ anet
367
+ .command("peers")
368
+ .description("List peers (optionally by k-bucket)")
369
+ .option("-b, --bucket <n>", "k-bucket index", (v) => parseInt(v, 10))
370
+ .option("--limit <n>", "Max rows", (v) => parseInt(v, 10), 50)
371
+ .option("--json", "JSON output")
372
+ .action((opts) => {
373
+ const db = _dbFromCtx(anet);
374
+ const rows = listPeers(db, { kBucket: opts.bucket, limit: opts.limit });
375
+ if (opts.json) return _json(rows);
376
+ for (const r of rows)
377
+ console.log(
378
+ ` ${r.peerId} bucket=${r.kBucket} endpoint=${r.endpoint || "—"} did=${r.agentDid || "—"}`,
379
+ );
380
+ console.log(`(${rows.length} peers)`);
381
+ });
382
+
383
+ /* ── Authentication ──────────────────────────────── */
384
+
385
+ anet
386
+ .command("auth-start")
387
+ .argument("<did>", "Agent DID")
388
+ .description("Issue an auth challenge for a DID")
389
+ .option("--json", "JSON output")
390
+ .action((did, opts) => {
391
+ const db = _dbFromCtx(anet);
392
+ const r = startAuth(db, did);
393
+ if (opts.json) return _json(r);
394
+ console.log(`session=${r.sessionId}`);
395
+ console.log(`challenge=${r.challenge}`);
396
+ console.log(`expiresAt=${_fmtTs(r.expiresAt)}`);
397
+ });
398
+
399
+ anet
400
+ .command("auth-complete")
401
+ .argument("<sessionId>", "Session id from auth-start")
402
+ .argument("<signature>", "Ed25519 signature over challenge (hex)")
403
+ .description("Complete auth with signature over challenge")
404
+ .option("--json", "JSON output")
405
+ .action((sessionId, signature, opts) => {
406
+ const db = _dbFromCtx(anet);
407
+ const r = completeAuth(db, sessionId, signature);
408
+ if (opts.json) return _json(r);
409
+ console.log(`token=${r.token}`);
410
+ console.log(`agentDid=${r.agentDid}`);
411
+ console.log(`expiresAt=${_fmtTs(r.expiresAt)}`);
412
+ });
413
+
414
+ anet
415
+ .command("auth-validate")
416
+ .argument("<token>", "Session token")
417
+ .description("Validate a session token (returns agentDid or exits 1)")
418
+ .option("--json", "JSON output")
419
+ .action((token, opts) => {
420
+ const db = _dbFromCtx(anet);
421
+ const r = validateSession(db, token);
422
+ if (opts.json) return _json(r);
423
+ if (!r) {
424
+ console.error("invalid or expired");
425
+ process.exit(1);
426
+ }
427
+ console.log(`agentDid=${r.agentDid} expiresAt=${_fmtTs(r.expiresAt)}`);
428
+ });
429
+
430
+ anet
431
+ .command("auth-sessions")
432
+ .description("List auth sessions")
433
+ .option("-d, --did <did>", "Filter by DID")
434
+ .option("-s, --status <status>", "Filter by status")
435
+ .option("--limit <n>", "Max rows", (v) => parseInt(v, 10), 50)
436
+ .option("--json", "JSON output")
437
+ .action((opts) => {
438
+ const db = _dbFromCtx(anet);
439
+ const rows = listSessions(db, {
440
+ agentDid: opts.did,
441
+ status: opts.status,
442
+ limit: opts.limit,
443
+ });
444
+ if (opts.json) return _json(rows);
445
+ for (const r of rows)
446
+ console.log(
447
+ ` ${r.sessionId} [${r.status}] did=${r.agentDid} exp=${_fmtTs(r.expiresAt)}`,
448
+ );
449
+ console.log(`(${rows.length} sessions)`);
450
+ });
451
+
452
+ /* ── Credentials (W3C VC) ────────────────────────── */
453
+
454
+ anet
455
+ .command("credential-issue")
456
+ .argument("<issuerDid>", "Issuer DID")
457
+ .argument("<subjectDid>", "Subject DID")
458
+ .description("Issue a VC with HMAC/Ed25519 proof")
459
+ .option("-t, --type <type>", "Credential type", "AgentCapabilityCredential")
460
+ .option(
461
+ "-c, --claims <json>",
462
+ "Claims (JSON object)",
463
+ (v) => _parseJsonArg(v, {}),
464
+ {},
465
+ )
466
+ .option("--expires-at <ms>", "Expiry (epoch ms)", (v) => parseInt(v, 10))
467
+ .option("--json", "JSON output")
468
+ .action((issuerDid, subjectDid, opts) => {
469
+ const db = _dbFromCtx(anet);
470
+ const r = issueCredential(db, {
471
+ issuerDid,
472
+ subjectDid,
473
+ type: opts.type,
474
+ claims: opts.claims,
475
+ expiresAt: opts.expiresAt,
476
+ });
477
+ if (opts.json) return _json(r);
478
+ console.log(`Issued ${r.id} (${r.type})`);
479
+ console.log(` issuer=${r.issuer} subject=${r.subject}`);
480
+ });
481
+
482
+ anet
483
+ .command("credential-verify")
484
+ .argument("<id>", "Credential id")
485
+ .description("Verify a VC (signature + expiry + revocation)")
486
+ .option("--json", "JSON output")
487
+ .action((id, opts) => {
488
+ const db = _dbFromCtx(anet);
489
+ const r = verifyCredential(db, id);
490
+ if (opts.json) return _json(r);
491
+ if (r.valid) {
492
+ console.log(`valid type=${r.credential.type}`);
493
+ } else {
494
+ console.log(`invalid (${r.reason})`);
495
+ process.exit(1);
496
+ }
497
+ });
498
+
499
+ anet
500
+ .command("credential-revoke")
501
+ .argument("<id>", "Credential id")
502
+ .description("Revoke a credential")
503
+ .option("--json", "JSON output")
504
+ .action((id, opts) => {
505
+ const db = _dbFromCtx(anet);
506
+ const r = revokeCredential(db, id);
507
+ if (opts.json) return _json(r);
508
+ if (!r.changed) {
509
+ console.error("No change (unknown or already revoked)");
510
+ process.exit(1);
511
+ }
512
+ console.log(`Revoked ${id}`);
513
+ });
514
+
515
+ anet
516
+ .command("credential-show")
517
+ .argument("<id>", "Credential id")
518
+ .description("Show a credential")
519
+ .option("--json", "JSON output")
520
+ .action((id, opts) => {
521
+ const db = _dbFromCtx(anet);
522
+ const c = getCredential(db, id);
523
+ if (!c) {
524
+ console.error(`Not found: ${id}`);
525
+ process.exit(1);
526
+ }
527
+ if (opts.json) return _json(c);
528
+ console.log(`Credential ${c.id} type=${c.type} status=${c.status}`);
529
+ console.log(` issuer=${c.issuer} subject=${c.subject}`);
530
+ console.log(
531
+ ` issuedAt=${_fmtTs(c.issuedAt)} expiresAt=${_fmtTs(c.expiresAt)}`,
532
+ );
533
+ console.log(` claims=${JSON.stringify(c.claims)}`);
534
+ });
535
+
536
+ anet
537
+ .command("credentials")
538
+ .description("List credentials (filter by subject/issuer/status/type)")
539
+ .option("-s, --subject <did>", "Filter by subject DID")
540
+ .option("-i, --issuer <did>", "Filter by issuer DID")
541
+ .option("--status <status>", "Filter by status")
542
+ .option("-t, --type <type>", "Filter by type")
543
+ .option("--limit <n>", "Max rows", (v) => parseInt(v, 10), 50)
544
+ .option("--json", "JSON output")
545
+ .action((opts) => {
546
+ const db = _dbFromCtx(anet);
547
+ const rows = listCredentials(db, {
548
+ subjectDid: opts.subject,
549
+ issuerDid: opts.issuer,
550
+ status: opts.status,
551
+ type: opts.type,
552
+ limit: opts.limit,
553
+ });
554
+ if (opts.json) return _json(rows);
555
+ for (const r of rows)
556
+ console.log(
557
+ ` ${r.id} [${r.status}] type=${r.type} subject=${r.subject}`,
558
+ );
559
+ console.log(`(${rows.length} credentials)`);
560
+ });
561
+
562
+ /* ── Cross-org task routing ──────────────────────── */
563
+
564
+ anet
565
+ .command("task-route")
566
+ .argument("<sourceOrg>", "Source org id")
567
+ .argument("<taskType>", "Task type")
568
+ .description("Route task → pick best-rep agent matching capability")
569
+ .option("-t, --target <orgId>", "Target org (optional)")
570
+ .option(
571
+ "-r, --requirements <json>",
572
+ "Requirements (JSON, supports {capability})",
573
+ (v) => _parseJsonArg(v, {}),
574
+ {},
575
+ )
576
+ .option("-p, --payload <json>", "Task payload (JSON)", (v) =>
577
+ _parseJsonArg(v, null),
578
+ )
579
+ .option("--json", "JSON output")
580
+ .action((sourceOrg, taskType, opts) => {
581
+ const db = _dbFromCtx(anet);
582
+ const r = routeTask(db, {
583
+ sourceOrg,
584
+ targetOrg: opts.target,
585
+ taskType,
586
+ requirements: opts.requirements,
587
+ payload: opts.payload,
588
+ });
589
+ if (opts.json) return _json(r);
590
+ console.log(`task=${r.taskId} status=${r.status}`);
591
+ console.log(` agentDid=${r.agentDid || "—"} score=${r.score ?? "—"}`);
592
+ });
593
+
594
+ anet
595
+ .command("task-show")
596
+ .argument("<taskId>", "Task id")
597
+ .description("Show a task")
598
+ .option("--json", "JSON output")
599
+ .action((taskId, opts) => {
600
+ const db = _dbFromCtx(anet);
601
+ const t = getTask(db, taskId);
602
+ if (!t) {
603
+ console.error(`Not found: ${taskId}`);
604
+ process.exit(1);
605
+ }
606
+ if (opts.json) return _json(t);
607
+ console.log(
608
+ `Task ${t.taskId} [${t.status}] type=${t.taskType} source=${t.sourceOrg}`,
609
+ );
610
+ console.log(
611
+ ` agentDid=${t.agentDid || "—"} targetOrg=${t.targetOrg || "—"}`,
612
+ );
613
+ console.log(
614
+ ` createdAt=${_fmtTs(t.createdAt)} completedAt=${_fmtTs(t.completedAt)}`,
615
+ );
616
+ });
617
+
618
+ anet
619
+ .command("task-status")
620
+ .argument("<taskId>", "Task id")
621
+ .argument(
622
+ "<status>",
623
+ "New status (pending|routed|running|completed|failed|cancelled)",
624
+ )
625
+ .description("Update task status (terminal states set completedAt)")
626
+ .option("-r, --result <json>", "Result payload (JSON)", (v) =>
627
+ _parseJsonArg(v, null),
628
+ )
629
+ .option("--json", "JSON output")
630
+ .action((taskId, status, opts) => {
631
+ const db = _dbFromCtx(anet);
632
+ const r = updateTaskStatus(db, taskId, status, opts.result);
633
+ if (opts.json) return _json(r);
634
+ if (!r.changed) {
635
+ console.error(`Unknown task: ${taskId}`);
636
+ process.exit(1);
637
+ }
638
+ console.log(`${taskId} → ${status}`);
639
+ });
640
+
641
+ anet
642
+ .command("task-cancel")
643
+ .argument("<taskId>", "Task id")
644
+ .description("Cancel a task (sets CANCELLED + reason)")
645
+ .option("-r, --reason <reason>", "Cancellation reason")
646
+ .option("--json", "JSON output")
647
+ .action((taskId, opts) => {
648
+ const db = _dbFromCtx(anet);
649
+ const r = cancelTask(db, taskId, opts.reason);
650
+ if (opts.json) return _json(r);
651
+ if (!r.changed) {
652
+ console.error(`Unknown task: ${taskId}`);
653
+ process.exit(1);
654
+ }
655
+ console.log(`${taskId} cancelled`);
656
+ });
657
+
658
+ anet
659
+ .command("tasks")
660
+ .description("List tasks")
661
+ .option("-o, --org <orgId>", "Filter by source org")
662
+ .option("-d, --did <did>", "Filter by agent DID")
663
+ .option("-s, --status <status>", "Filter by status")
664
+ .option("--limit <n>", "Max rows", (v) => parseInt(v, 10), 50)
665
+ .option("--json", "JSON output")
666
+ .action((opts) => {
667
+ const db = _dbFromCtx(anet);
668
+ const rows = listTasks(db, {
669
+ orgId: opts.org,
670
+ agentDid: opts.did,
671
+ status: opts.status,
672
+ limit: opts.limit,
673
+ });
674
+ if (opts.json) return _json(rows);
675
+ for (const r of rows)
676
+ console.log(
677
+ ` ${r.taskId} [${r.status}] type=${r.taskType} agent=${r.agentDid || "—"}`,
678
+ );
679
+ console.log(`(${rows.length} tasks)`);
680
+ });
681
+
682
+ /* ── Reputation ─────────────────────────────────── */
683
+
684
+ anet
685
+ .command("rep-update")
686
+ .argument("<did>", "Agent DID")
687
+ .argument(
688
+ "<dimension>",
689
+ "Dimension (reliability|quality|speed|cooperation)",
690
+ )
691
+ .argument("<score>", "Score (0..5)")
692
+ .description("Record a reputation observation")
693
+ .option("-e, --evidence <text>", "Evidence note")
694
+ .option("--json", "JSON output")
695
+ .action((did, dimension, scoreStr, opts) => {
696
+ const db = _dbFromCtx(anet);
697
+ const score = Number(scoreStr);
698
+ const r = updateReputation(db, {
699
+ agentDid: did,
700
+ dimension,
701
+ score,
702
+ evidence: opts.evidence,
703
+ });
704
+ if (opts.json) return _json(r);
705
+ console.log(
706
+ `${r.agentDid} ${r.dimension}=${r.score} (${_fmtTs(r.createdAt)})`,
707
+ );
708
+ });
709
+
710
+ anet
711
+ .command("rep-show")
712
+ .argument("<did>", "Agent DID")
713
+ .description("Show reputation summary (weighted total + per-dim avg)")
714
+ .option("--json", "JSON output")
715
+ .action((did, opts) => {
716
+ const db = _dbFromCtx(anet);
717
+ const r = getReputation(db, did);
718
+ if (opts.json) return _json(r);
719
+ console.log(`${did} total=${r.total.toFixed(3)} samples=${r.samples}`);
720
+ for (const d of REPUTATION_DIMENSIONS) {
721
+ const info = r.dimensions[d];
722
+ if (!info) continue;
723
+ console.log(
724
+ ` ${d.padEnd(12)} avg=${info.score.toFixed(3)} samples=${info.samples}`,
725
+ );
726
+ }
727
+ });
728
+
729
+ anet
730
+ .command("rep-history")
731
+ .argument("<did>", "Agent DID")
732
+ .description("Show reputation history (newest first)")
733
+ .option("--limit <n>", "Max rows", (v) => parseInt(v, 10), 20)
734
+ .option("--json", "JSON output")
735
+ .action((did, opts) => {
736
+ const db = _dbFromCtx(anet);
737
+ const rows = getReputationHistory(db, did, opts.limit);
738
+ if (opts.json) return _json(rows);
739
+ for (const r of rows)
740
+ console.log(
741
+ ` ${_fmtTs(r.createdAt)} ${r.dimension.padEnd(12)} ${r.score.toFixed(2)} ${r.evidence || ""}`,
742
+ );
743
+ console.log(`(${rows.length} observations)`);
744
+ });
745
+
746
+ anet
747
+ .command("rep-top")
748
+ .description("Top agents by dimension (or total)")
749
+ .option("-d, --dimension <dim>", "Dimension to rank by")
750
+ .option("--limit <n>", "Max rows", (v) => parseInt(v, 10), 10)
751
+ .option("--json", "JSON output")
752
+ .action((opts) => {
753
+ const db = _dbFromCtx(anet);
754
+ const rows = getTopAgents(db, {
755
+ dimension: opts.dimension,
756
+ limit: opts.limit,
757
+ });
758
+ if (opts.json) return _json(rows);
759
+ for (const r of rows)
760
+ console.log(
761
+ ` ${r.agentDid} score=${r.score.toFixed(3)} samples=${r.samples}`,
762
+ );
763
+ });
764
+
765
+ /* ── Stats ──────────────────────────────────────── */
766
+
767
+ anet
768
+ .command("stats")
769
+ .description("Network-level statistics")
770
+ .option("--json", "JSON output")
771
+ .action((opts) => {
772
+ const db = _dbFromCtx(anet);
773
+ const s = getNetworkStats(db);
774
+ if (opts.json) return _json(s);
775
+ console.log(`DIDs: ${JSON.stringify(s.dids)}`);
776
+ console.log(`Registry: ${JSON.stringify(s.registry)}`);
777
+ console.log(`Tasks: ${JSON.stringify(s.tasks)}`);
778
+ console.log(`Credentials: ${JSON.stringify(s.credentials)}`);
779
+ console.log(`Sessions: ${JSON.stringify(s.sessions)}`);
780
+ console.log(`Peers: ${s.peers}`);
781
+ });
782
+
783
+ program.addCommand(anet);
784
+ return anet;
785
+ }