agentbnb 9.2.0 → 9.2.2
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/README.md +22 -0
- package/dist/{card-VVXNKHDX.js → card-L3ZPPBVI.js} +2 -2
- package/dist/{chunk-Z7XWQ63B.js → chunk-2KSRFDKF.js} +1 -1
- package/dist/{chunk-WEZ7PSOE.js → chunk-563ZZUOA.js} +56 -22
- package/dist/chunk-5FXLZ5FX.js +16 -0
- package/dist/{chunk-ELFGYC22.js → chunk-7YJOBVWN.js} +3 -0
- package/dist/{chunk-V5TJXK3F.js → chunk-COOBXNXU.js} +5 -5
- package/dist/{chunk-EC6DIVE5.js → chunk-CPSV5WR2.js} +1 -1
- package/dist/{process-guard-6324CZDC.js → chunk-DG4FQ4MD.js} +1 -1
- package/dist/{chunk-MPS4RE7T.js → chunk-DT2IEL5U.js} +11 -0
- package/dist/chunk-EMVVFP2L.js +54 -0
- package/dist/{chunk-FK54LVDR.js → chunk-FVLHEI3Y.js} +5 -5
- package/dist/chunk-GIK2AZQH.js +23 -0
- package/dist/{chunk-B6AKTLXB.js → chunk-NISX3N7K.js} +16 -7
- package/dist/{chunk-CMGJ52SX.js → chunk-NLGLGR2K.js} +1 -1
- package/dist/{chunk-RNALIVRR.js → chunk-OFIRWD6B.js} +1 -1
- package/dist/{chunk-GGRH5PCD.js → chunk-OI46BKQF.js} +9 -9
- package/dist/{chunk-MQIT2F5V.js → chunk-OTAZIF65.js} +1 -1
- package/dist/{chunk-KKFP5Y2Z.js → chunk-OXU4QJSZ.js} +2 -2
- package/dist/{chunk-53Q2HHHH.js → chunk-PFAEZI32.js} +9 -9
- package/dist/{chunk-D7NH6YLM.js → chunk-UJXDBOKV.js} +12 -1
- package/dist/{chunk-UPWAXWY2.js → chunk-VDYHCI5F.js} +22 -1
- package/dist/{chunk-QG2LLVXP.js → chunk-WA23XRTN.js} +1 -1
- package/dist/cli/index.js +787 -97
- package/dist/{conduct-QLWXU2ZU.js → conduct-65BGO2EU.js} +13 -11
- package/dist/{conduct-JRLLA4PB.js → conduct-AALDEKTH.js} +13 -11
- package/dist/{conductor-mode-PFO2VLH6.js → conductor-mode-6S6ADNLW.js} +15 -15
- package/dist/{conductor-mode-66IITI4I.js → conductor-mode-HJHU4XLT.js} +2 -2
- package/dist/{credits-action-XERUEDF3.js → credits-action-CLLPNRDT.js} +15 -6
- package/dist/{execute-NOQVN7ZG.js → execute-R5STYWLD.js} +10 -10
- package/dist/{execute-YBNCDAOX.js → execute-YMPHTJPN.js} +2 -2
- package/dist/{openclaw-setup-4RIZRMXA.js → openclaw-setup-HUOBTGN4.js} +14 -12
- package/dist/{openclaw-skills-TQ2JVBRM.js → openclaw-skills-74372B6I.js} +2 -2
- package/dist/process-guard-IUMZ2GSD.js +8 -0
- package/dist/{publish-capability-2FMD3K6Z.js → publish-capability-OYXXXYAU.js} +3 -3
- package/dist/remote-registry-5TM7DMCO.js +16 -0
- package/dist/{request-EYN4CVXC.js → request-NEA66RCW.js} +63 -21
- package/dist/{serve-skill-NWERGVH5.js → serve-skill-VKNRBVWE.js} +16 -15
- package/dist/{server-UPOPLZ24.js → server-4TACULIV.js} +21 -17
- package/dist/{service-coordinator-ZOZTW2U6.js → service-coordinator-RE2KPWO4.js} +91 -31
- package/dist/{session-action-OSBZB4TX.js → session-action-UBWJTQVQ.js} +17 -2
- package/dist/skills/agentbnb/bootstrap.js +213 -24
- package/dist/{store-74EWU77V.js → store-GJJFFEQZ.js} +2 -2
- package/dist/{vc-action-A6VBKERF.js → vc-action-72TQVMY2.js} +13 -3
- package/openclaw.plugin.json +36 -5
- package/package.json +12 -18
- package/skills/agentbnb/SKILL.md +106 -75
- package/skills/agentbnb/install.sh +0 -0
- package/dist/{chunk-C56X7EFJ.js → chunk-QE42IJC4.js} +3 -3
- package/dist/{daemon-ETXXE4IS.js → daemon-OM2K3U7J.js} +1 -1
- package/dist/{did-action-ODWTBVXL.js → did-action-ERXWCVEJ.js} +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "../chunk-TA73FIZU.js";
|
|
5
5
|
import {
|
|
6
6
|
syncCreditsFromRegistry
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-OXU4QJSZ.js";
|
|
8
8
|
import {
|
|
9
9
|
resolveSelfCli
|
|
10
10
|
} from "../chunk-7S4ZLFVI.js";
|
|
@@ -14,44 +14,54 @@ import {
|
|
|
14
14
|
injectHeartbeatSection,
|
|
15
15
|
performInit,
|
|
16
16
|
publishFromSoulV2
|
|
17
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-563ZZUOA.js";
|
|
18
18
|
import {
|
|
19
|
-
getPricingStats
|
|
20
|
-
|
|
19
|
+
getPricingStats,
|
|
20
|
+
probeRegistry
|
|
21
|
+
} from "../chunk-VDYHCI5F.js";
|
|
22
|
+
import {
|
|
23
|
+
TimeoutError,
|
|
24
|
+
withTimeout
|
|
25
|
+
} from "../chunk-GIK2AZQH.js";
|
|
26
|
+
import {
|
|
27
|
+
shouldSkipNetwork
|
|
28
|
+
} from "../chunk-5FXLZ5FX.js";
|
|
21
29
|
import {
|
|
22
30
|
createLedger
|
|
23
|
-
} from "../chunk-
|
|
31
|
+
} from "../chunk-2KSRFDKF.js";
|
|
24
32
|
import {
|
|
25
33
|
ensureIdentity
|
|
26
34
|
} from "../chunk-AA25Z6FW.js";
|
|
27
|
-
import "../chunk-
|
|
35
|
+
import "../chunk-OFIRWD6B.js";
|
|
28
36
|
import "../chunk-RJNKX347.js";
|
|
37
|
+
import {
|
|
38
|
+
ProcessGuard
|
|
39
|
+
} from "../chunk-DG4FQ4MD.js";
|
|
40
|
+
import {
|
|
41
|
+
parseSkillsFile
|
|
42
|
+
} from "../chunk-WX3GZVFG.js";
|
|
29
43
|
import {
|
|
30
44
|
AutoRequestor,
|
|
31
45
|
requestViaTemporaryRelay
|
|
32
|
-
} from "../chunk-
|
|
46
|
+
} from "../chunk-OI46BKQF.js";
|
|
33
47
|
import "../chunk-5PV5YCSN.js";
|
|
34
|
-
import "../chunk-
|
|
35
|
-
import {
|
|
36
|
-
fetchRemoteCards,
|
|
37
|
-
mergeResults
|
|
38
|
-
} from "../chunk-ELFGYC22.js";
|
|
48
|
+
import "../chunk-FVLHEI3Y.js";
|
|
39
49
|
import {
|
|
40
50
|
BudgetManager,
|
|
41
51
|
DEFAULT_BUDGET_CONFIG
|
|
42
|
-
} from "../chunk-
|
|
52
|
+
} from "../chunk-WA23XRTN.js";
|
|
43
53
|
import {
|
|
44
54
|
DEFAULT_AUTONOMY_CONFIG
|
|
45
55
|
} from "../chunk-G5WKW3ED.js";
|
|
46
56
|
import {
|
|
47
57
|
filterCards,
|
|
48
58
|
searchCards
|
|
49
|
-
} from "../chunk-
|
|
59
|
+
} from "../chunk-CPSV5WR2.js";
|
|
50
60
|
import {
|
|
51
61
|
getBalance,
|
|
52
62
|
getTransactions,
|
|
53
63
|
openCreditDb
|
|
54
|
-
} from "../chunk-
|
|
64
|
+
} from "../chunk-UJXDBOKV.js";
|
|
55
65
|
import {
|
|
56
66
|
attachCanonicalAgentId,
|
|
57
67
|
deleteCard,
|
|
@@ -59,7 +69,8 @@ import {
|
|
|
59
69
|
insertCard,
|
|
60
70
|
listCards,
|
|
61
71
|
openDatabase
|
|
62
|
-
} from "../chunk-
|
|
72
|
+
} from "../chunk-QE42IJC4.js";
|
|
73
|
+
import "../chunk-4XTYT4JW.js";
|
|
63
74
|
import "../chunk-GZUTU6IZ.js";
|
|
64
75
|
import "../chunk-UPNREF4L.js";
|
|
65
76
|
import "../chunk-Q5OFZ2JR.js";
|
|
@@ -74,9 +85,6 @@ import {
|
|
|
74
85
|
} from "../chunk-65GNX2KC.js";
|
|
75
86
|
import "../chunk-YDGXKH2T.js";
|
|
76
87
|
import "../chunk-J4RFJVXI.js";
|
|
77
|
-
import {
|
|
78
|
-
AnyCardSchema
|
|
79
|
-
} from "../chunk-UVCNMRPS.js";
|
|
80
88
|
import {
|
|
81
89
|
findPeer,
|
|
82
90
|
loadPeers,
|
|
@@ -88,14 +96,20 @@ import {
|
|
|
88
96
|
loadConfig,
|
|
89
97
|
saveConfig
|
|
90
98
|
} from "../chunk-3XPBFF6H.js";
|
|
91
|
-
import
|
|
99
|
+
import {
|
|
100
|
+
fetchRemoteCards,
|
|
101
|
+
mergeResults
|
|
102
|
+
} from "../chunk-7YJOBVWN.js";
|
|
103
|
+
import {
|
|
104
|
+
AnyCardSchema
|
|
105
|
+
} from "../chunk-UVCNMRPS.js";
|
|
92
106
|
import "../chunk-3RG5ZIWI.js";
|
|
93
107
|
|
|
94
108
|
// src/cli/index.ts
|
|
95
109
|
import { Command } from "commander";
|
|
96
|
-
import { existsSync as
|
|
110
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
|
|
97
111
|
import { randomUUID } from "crypto";
|
|
98
|
-
import { join as
|
|
112
|
+
import { join as join3 } from "path";
|
|
99
113
|
import { networkInterfaces } from "os";
|
|
100
114
|
import { createInterface } from "readline";
|
|
101
115
|
|
|
@@ -240,9 +254,9 @@ Skills: ${skills2.skillCount} skill(s) in ${skills2.path}`);
|
|
|
240
254
|
let daemonStatus = { running: false, reason: "skipped" };
|
|
241
255
|
if (!skipServe) {
|
|
242
256
|
try {
|
|
243
|
-
const { ProcessGuard } = await import("../process-guard-
|
|
244
|
-
const { ServiceCoordinator } = await import("../service-coordinator-
|
|
245
|
-
const guard = new
|
|
257
|
+
const { ProcessGuard: ProcessGuard2 } = await import("../process-guard-IUMZ2GSD.js");
|
|
258
|
+
const { ServiceCoordinator } = await import("../service-coordinator-RE2KPWO4.js");
|
|
259
|
+
const guard = new ProcessGuard2(join(initResult.configDir, ".pid"));
|
|
246
260
|
const coordinator = new ServiceCoordinator(initResult.config, guard);
|
|
247
261
|
const result = await coordinator.ensureRunning({
|
|
248
262
|
port: initResult.config.gateway_port,
|
|
@@ -299,11 +313,625 @@ Skills: ${skills2.skillCount} skill(s) in ${skills2.path}`);
|
|
|
299
313
|
console.log(" Consumer: In Claude Code, use agentbnb_discover and agentbnb_request");
|
|
300
314
|
console.log(" Provider: Your claude -p skills are live and accepting requests");
|
|
301
315
|
console.log(` Dashboard: http://localhost:7701/hub/#/myagent`);
|
|
316
|
+
console.log("");
|
|
317
|
+
console.log(" Verify: Run `agentbnb doctor` to validate your provider setup");
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// src/cli/doctor.ts
|
|
322
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
323
|
+
import { join as join2 } from "path";
|
|
324
|
+
function checkIdentity(configDir, config) {
|
|
325
|
+
try {
|
|
326
|
+
loadKeyPair(configDir);
|
|
327
|
+
} catch {
|
|
328
|
+
return {
|
|
329
|
+
name: "Identity",
|
|
330
|
+
status: "fail",
|
|
331
|
+
message: "keypair not found",
|
|
332
|
+
context: "Without an identity, your agent cannot sign requests or publish cards.",
|
|
333
|
+
fix: "Run `agentbnb init`"
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
let did2 = "";
|
|
337
|
+
try {
|
|
338
|
+
const identityPath = join2(configDir, "identity.json");
|
|
339
|
+
if (existsSync2(identityPath)) {
|
|
340
|
+
const raw = JSON.parse(readFileSync2(identityPath, "utf-8"));
|
|
341
|
+
did2 = raw.did ?? `did:agentbnb:${raw.agent_id ?? "unknown"}`;
|
|
342
|
+
}
|
|
343
|
+
} catch {
|
|
344
|
+
}
|
|
345
|
+
const label = did2 ? `${config.owner} (${did2})` : config.owner;
|
|
346
|
+
return { name: "Identity", status: "pass", message: label };
|
|
347
|
+
}
|
|
348
|
+
function checkSkills(configDir) {
|
|
349
|
+
const skillsPath = join2(configDir, "skills.yaml");
|
|
350
|
+
if (!existsSync2(skillsPath)) {
|
|
351
|
+
return {
|
|
352
|
+
name: "Skills",
|
|
353
|
+
status: "fail",
|
|
354
|
+
message: "skills.yaml not found",
|
|
355
|
+
context: "Skills define what your agent can do for hire.",
|
|
356
|
+
fix: "Run `agentbnb quickstart` to generate default skills"
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
let skills2;
|
|
360
|
+
try {
|
|
361
|
+
const content = readFileSync2(skillsPath, "utf-8");
|
|
362
|
+
skills2 = parseSkillsFile(content);
|
|
363
|
+
} catch (err) {
|
|
364
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
365
|
+
if (msg.includes("environment variable") || msg.includes("env var")) {
|
|
366
|
+
return {
|
|
367
|
+
name: "Skills",
|
|
368
|
+
status: "warn",
|
|
369
|
+
message: `skills.yaml has unresolved environment variables`,
|
|
370
|
+
context: "Skills exist but may not execute until env vars are set.",
|
|
371
|
+
fix: `Check missing env vars: ${msg}`
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
return {
|
|
375
|
+
name: "Skills",
|
|
376
|
+
status: "fail",
|
|
377
|
+
message: `skills.yaml parse error: ${msg}`,
|
|
378
|
+
context: "Malformed skills.yaml prevents your agent from executing any skill.",
|
|
379
|
+
fix: "Fix syntax errors in ~/.agentbnb/skills.yaml"
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
if (skills2.length === 0) {
|
|
383
|
+
return {
|
|
384
|
+
name: "Skills",
|
|
385
|
+
status: "fail",
|
|
386
|
+
message: "skills.yaml is empty (0 skills)",
|
|
387
|
+
context: "Without skills, there is nothing for other agents to hire.",
|
|
388
|
+
fix: "Add at least one skill to ~/.agentbnb/skills.yaml"
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
return { name: "Skills", status: "pass", message: `${skills2.length} skills in ~/.agentbnb/skills.yaml` };
|
|
392
|
+
}
|
|
393
|
+
async function checkGateway(configDir) {
|
|
394
|
+
const guard = new ProcessGuard(join2(configDir, ".pid"));
|
|
395
|
+
const meta = guard.getRunningMeta();
|
|
396
|
+
if (!meta) {
|
|
397
|
+
return {
|
|
398
|
+
result: {
|
|
399
|
+
name: "Gateway",
|
|
400
|
+
status: "fail",
|
|
401
|
+
message: "not running",
|
|
402
|
+
context: "Your skills cannot receive requests without the daemon.",
|
|
403
|
+
fix: "Run `agentbnb serve`"
|
|
404
|
+
},
|
|
405
|
+
meta: null
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
const healthy = await probeGatewayHealth(meta.port);
|
|
409
|
+
if (!healthy) {
|
|
410
|
+
return {
|
|
411
|
+
result: {
|
|
412
|
+
name: "Gateway",
|
|
413
|
+
status: "warn",
|
|
414
|
+
message: `pid ${meta.pid} exists but /health is not responding on port ${meta.port}`,
|
|
415
|
+
context: "The daemon process is running but may not be accepting requests.",
|
|
416
|
+
fix: "Restart with `agentbnb serve --restart` or check logs"
|
|
417
|
+
},
|
|
418
|
+
meta
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
return {
|
|
422
|
+
result: {
|
|
423
|
+
name: "Gateway",
|
|
424
|
+
status: "pass",
|
|
425
|
+
message: `running on port ${meta.port} (pid ${meta.pid})`
|
|
426
|
+
},
|
|
427
|
+
meta
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
function checkCards(config) {
|
|
431
|
+
let localCount = 0;
|
|
432
|
+
try {
|
|
433
|
+
const db = openDatabase(config.db_path);
|
|
434
|
+
try {
|
|
435
|
+
const cards = listCards(db);
|
|
436
|
+
localCount = cards.filter((c) => c.owner === config.owner).length;
|
|
437
|
+
} finally {
|
|
438
|
+
db.close();
|
|
439
|
+
}
|
|
440
|
+
} catch {
|
|
441
|
+
return {
|
|
442
|
+
result: {
|
|
443
|
+
name: "Cards",
|
|
444
|
+
status: "fail",
|
|
445
|
+
message: "cannot read registry database",
|
|
446
|
+
context: "Capability cards make your skills discoverable to other agents.",
|
|
447
|
+
fix: "Run `agentbnb init` to recreate the database"
|
|
448
|
+
},
|
|
449
|
+
localCount: 0
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
if (localCount === 0) {
|
|
453
|
+
return {
|
|
454
|
+
result: {
|
|
455
|
+
name: "Cards",
|
|
456
|
+
status: "fail",
|
|
457
|
+
message: "no capability cards published",
|
|
458
|
+
context: "Without published cards, no agent can discover or hire your skills.",
|
|
459
|
+
fix: "Run `agentbnb publish-skills` or `agentbnb serve` to auto-publish"
|
|
460
|
+
},
|
|
461
|
+
localCount: 0
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
return {
|
|
465
|
+
result: {
|
|
466
|
+
name: "Cards",
|
|
467
|
+
status: "pass",
|
|
468
|
+
// upgraded or downgraded by remote check below
|
|
469
|
+
message: `${localCount} cards published locally`
|
|
470
|
+
},
|
|
471
|
+
localCount
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
async function checkCardsRemote(config, localCount) {
|
|
475
|
+
if (!config.registry) {
|
|
476
|
+
return {
|
|
477
|
+
name: "Cards",
|
|
478
|
+
status: localCount > 0 ? "warn" : "fail",
|
|
479
|
+
message: localCount > 0 ? `${localCount} cards published locally \u2014 remote discoverability not verified (no registry configured)` : "no cards published",
|
|
480
|
+
context: localCount > 0 ? "Without a registry connection, other agents outside your network cannot discover you." : "Without published cards, no agent can discover or hire your skills.",
|
|
481
|
+
fix: localCount > 0 ? void 0 : "Run `agentbnb publish-skills`"
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
try {
|
|
485
|
+
const { fetchRemoteCards: fetchRemoteCards2 } = await import("../remote-registry-5TM7DMCO.js");
|
|
486
|
+
const remoteCards = await fetchRemoteCards2(config.registry, { q: config.owner }, 3e3);
|
|
487
|
+
const ownCards = remoteCards.filter((c) => c.owner === config.owner);
|
|
488
|
+
if (ownCards.length > 0) {
|
|
489
|
+
const host = extractHost(config.registry);
|
|
490
|
+
return {
|
|
491
|
+
name: "Cards",
|
|
492
|
+
status: "pass",
|
|
493
|
+
message: `${localCount} cards published, ${ownCards.length} verified discoverable on ${host}`
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
return {
|
|
497
|
+
name: "Cards",
|
|
498
|
+
status: "warn",
|
|
499
|
+
message: `${localCount} cards published locally \u2014 not yet discoverable on remote registry`,
|
|
500
|
+
context: "Cards are local but the relay has not propagated them yet. This may resolve after daemon restart.",
|
|
501
|
+
fix: "Restart daemon with `agentbnb serve` to push cards to registry"
|
|
502
|
+
};
|
|
503
|
+
} catch {
|
|
504
|
+
return {
|
|
505
|
+
name: "Cards",
|
|
506
|
+
status: "warn",
|
|
507
|
+
message: `${localCount} cards published locally \u2014 remote discoverability not verified (registry probe failed)`,
|
|
508
|
+
context: "Could not reach registry to verify discoverability."
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
function checkCredits(config) {
|
|
513
|
+
let balance = 0;
|
|
514
|
+
try {
|
|
515
|
+
const creditDb = openCreditDb(config.credit_db_path);
|
|
516
|
+
try {
|
|
517
|
+
balance = getBalance(creditDb, config.owner);
|
|
518
|
+
} finally {
|
|
519
|
+
creditDb.close();
|
|
520
|
+
}
|
|
521
|
+
} catch {
|
|
522
|
+
return {
|
|
523
|
+
name: "Credits",
|
|
524
|
+
status: "warn",
|
|
525
|
+
message: "cannot read credit database",
|
|
526
|
+
context: "Credit state is unknown but serving may still work.",
|
|
527
|
+
fix: "Run `agentbnb init` to recreate the database"
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
if (balance <= 0) {
|
|
531
|
+
return {
|
|
532
|
+
name: "Credits",
|
|
533
|
+
status: "warn",
|
|
534
|
+
message: "0 credits \u2014 serving still works, but `--test-hire` requires credits",
|
|
535
|
+
context: "You can receive hire requests at any balance. Credits are needed to hire others or run self-tests.",
|
|
536
|
+
fix: "Credits are earned by completing jobs. Run `agentbnb credits` for details"
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
return { name: "Credits", status: "pass", message: `${balance} credits available` };
|
|
540
|
+
}
|
|
541
|
+
async function checkRegistry(config) {
|
|
542
|
+
if (!config.registry) {
|
|
543
|
+
return {
|
|
544
|
+
name: "Registry",
|
|
545
|
+
status: "warn",
|
|
546
|
+
message: "no remote registry configured (local-only mode)",
|
|
547
|
+
context: "Without a registry, only local-network agents can discover you via mDNS."
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
const reachable = await probeRegistry(config.registry);
|
|
551
|
+
if (!reachable) {
|
|
552
|
+
const host2 = extractHost(config.registry);
|
|
553
|
+
return {
|
|
554
|
+
name: "Registry",
|
|
555
|
+
status: "fail",
|
|
556
|
+
message: `configured but unreachable (${host2})`,
|
|
557
|
+
context: "Remote agents cannot discover you if the registry is down.",
|
|
558
|
+
fix: "Check network connection, or verify registry URL with `agentbnb config get registry`"
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
const host = extractHost(config.registry);
|
|
562
|
+
return { name: "Registry", status: "pass", message: `connected to ${host}` };
|
|
563
|
+
}
|
|
564
|
+
function checkRelay(config, daemonRunning) {
|
|
565
|
+
if (!daemonRunning) {
|
|
566
|
+
return {
|
|
567
|
+
name: "Relay",
|
|
568
|
+
status: "fail",
|
|
569
|
+
message: "cannot connect without running daemon",
|
|
570
|
+
context: "Relay enables cross-network hiring \u2014 agents outside your LAN reach you through it.",
|
|
571
|
+
fix: "Start daemon first: `agentbnb serve`"
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
if (!config.registry) {
|
|
575
|
+
return {
|
|
576
|
+
name: "Relay",
|
|
577
|
+
status: "warn",
|
|
578
|
+
message: "no relay target configured (no registry URL)",
|
|
579
|
+
context: "Without a relay, only local-network agents can hire you."
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
return {
|
|
583
|
+
name: "Relay",
|
|
584
|
+
status: "warn",
|
|
585
|
+
message: "likely connected (inferred from daemon state \u2014 not directly verified)",
|
|
586
|
+
context: "Relay connectivity is inferred. A future update will add direct verification."
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
async function runTestHire(config, configDir, explicitSkillId) {
|
|
590
|
+
if (!config.registry) {
|
|
591
|
+
return {
|
|
592
|
+
success: false,
|
|
593
|
+
skillId: "",
|
|
594
|
+
selectionReason: "",
|
|
595
|
+
creditsSpent: 0,
|
|
596
|
+
latency_ms: 0,
|
|
597
|
+
error: "Test-hire requires a registry (relay) connection. Configure a registry URL with `agentbnb config set registry <url>`"
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
const reachable = await probeRegistry(config.registry);
|
|
601
|
+
if (!reachable) {
|
|
602
|
+
return {
|
|
603
|
+
success: false,
|
|
604
|
+
skillId: "",
|
|
605
|
+
selectionReason: "",
|
|
606
|
+
creditsSpent: 0,
|
|
607
|
+
latency_ms: 0,
|
|
608
|
+
error: `Registry unreachable (${extractHost(config.registry)}). Test-hire needs relay connectivity`
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
let cards;
|
|
612
|
+
try {
|
|
613
|
+
const db = openDatabase(config.db_path);
|
|
614
|
+
try {
|
|
615
|
+
cards = listCards(db).filter((c) => c.owner === config.owner);
|
|
616
|
+
} finally {
|
|
617
|
+
db.close();
|
|
618
|
+
}
|
|
619
|
+
} catch {
|
|
620
|
+
return { success: false, skillId: "", selectionReason: "", creditsSpent: 0, latency_ms: 0, error: "Cannot read registry database" };
|
|
621
|
+
}
|
|
622
|
+
if (cards.length === 0) {
|
|
623
|
+
return { success: false, skillId: "", selectionReason: "", creditsSpent: 0, latency_ms: 0, error: "No published capability cards" };
|
|
624
|
+
}
|
|
625
|
+
let skillConfigs = [];
|
|
626
|
+
try {
|
|
627
|
+
const skillsPath = join2(configDir, "skills.yaml");
|
|
628
|
+
if (existsSync2(skillsPath)) {
|
|
629
|
+
skillConfigs = parseSkillsFile(readFileSync2(skillsPath, "utf-8"));
|
|
630
|
+
}
|
|
631
|
+
} catch {
|
|
632
|
+
}
|
|
633
|
+
let selectedCard = cards[0];
|
|
634
|
+
let selectedSkillId = "";
|
|
635
|
+
let selectionReason = "";
|
|
636
|
+
let creditsCost = 0;
|
|
637
|
+
if (explicitSkillId) {
|
|
638
|
+
const found = findSkillInCards(cards, explicitSkillId);
|
|
639
|
+
if (!found) {
|
|
640
|
+
return { success: false, skillId: explicitSkillId, selectionReason: "explicit --skill flag", creditsSpent: 0, latency_ms: 0, error: `Skill "${explicitSkillId}" not found in published cards` };
|
|
641
|
+
}
|
|
642
|
+
selectedCard = found.card;
|
|
643
|
+
selectedSkillId = found.skillId;
|
|
644
|
+
creditsCost = found.credits;
|
|
645
|
+
selectionReason = "explicit --skill flag";
|
|
646
|
+
} else {
|
|
647
|
+
const safeCandidate = findSafeSkill(cards, skillConfigs);
|
|
648
|
+
if (safeCandidate) {
|
|
649
|
+
selectedCard = safeCandidate.card;
|
|
650
|
+
selectedSkillId = safeCandidate.skillId;
|
|
651
|
+
creditsCost = safeCandidate.credits;
|
|
652
|
+
selectionReason = safeCandidate.reason;
|
|
653
|
+
} else {
|
|
654
|
+
const cheapest = findCheapestSkill(cards);
|
|
655
|
+
selectedCard = cheapest.card;
|
|
656
|
+
selectedSkillId = cheapest.skillId;
|
|
657
|
+
creditsCost = cheapest.credits;
|
|
658
|
+
selectionReason = "cheapest available (no safe candidate found)";
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
try {
|
|
662
|
+
const creditDb = openCreditDb(config.credit_db_path);
|
|
663
|
+
try {
|
|
664
|
+
const balance = getBalance(creditDb, config.owner);
|
|
665
|
+
if (balance < creditsCost) {
|
|
666
|
+
return {
|
|
667
|
+
success: false,
|
|
668
|
+
skillId: selectedSkillId || selectedCard.id,
|
|
669
|
+
selectionReason,
|
|
670
|
+
creditsSpent: 0,
|
|
671
|
+
latency_ms: 0,
|
|
672
|
+
error: `Insufficient credits: need ${creditsCost}, have ${balance}. Credits are earned by completing jobs`
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
} finally {
|
|
676
|
+
creditDb.close();
|
|
677
|
+
}
|
|
678
|
+
} catch {
|
|
679
|
+
}
|
|
680
|
+
let agentId;
|
|
681
|
+
try {
|
|
682
|
+
const identity = ensureIdentity(configDir, config.owner);
|
|
683
|
+
agentId = identity.agent_id;
|
|
684
|
+
} catch {
|
|
685
|
+
}
|
|
686
|
+
const start = Date.now();
|
|
687
|
+
try {
|
|
688
|
+
await requestViaTemporaryRelay({
|
|
689
|
+
registryUrl: config.registry,
|
|
690
|
+
agent_id: agentId,
|
|
691
|
+
owner: config.owner,
|
|
692
|
+
token: config.token,
|
|
693
|
+
targetOwner: config.owner,
|
|
694
|
+
targetAgentId: agentId,
|
|
695
|
+
cardId: selectedCard.id,
|
|
696
|
+
skillId: selectedSkillId || void 0,
|
|
697
|
+
params: {
|
|
698
|
+
prompt: "Reply with exactly: DOCTOR_SMOKE_TEST_OK",
|
|
699
|
+
...selectedSkillId ? { skill_id: selectedSkillId } : {},
|
|
700
|
+
requester: config.owner
|
|
701
|
+
},
|
|
702
|
+
timeoutMs: 6e4
|
|
703
|
+
});
|
|
704
|
+
return {
|
|
705
|
+
success: true,
|
|
706
|
+
skillId: selectedSkillId || selectedCard.name || selectedCard.id,
|
|
707
|
+
selectionReason,
|
|
708
|
+
creditsSpent: creditsCost,
|
|
709
|
+
latency_ms: Date.now() - start
|
|
710
|
+
};
|
|
711
|
+
} catch (err) {
|
|
712
|
+
return {
|
|
713
|
+
success: false,
|
|
714
|
+
skillId: selectedSkillId || selectedCard.name || selectedCard.id,
|
|
715
|
+
selectionReason,
|
|
716
|
+
creditsSpent: 0,
|
|
717
|
+
latency_ms: Date.now() - start,
|
|
718
|
+
error: err instanceof Error ? err.message : String(err)
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
async function probeGatewayHealth(port, timeoutMs = 2e3) {
|
|
723
|
+
const controller = new AbortController();
|
|
724
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
725
|
+
try {
|
|
726
|
+
const res = await fetch(`http://localhost:${port}/health`, { signal: controller.signal });
|
|
727
|
+
if (!res.ok) return false;
|
|
728
|
+
const body = await res.json();
|
|
729
|
+
return body.status === "ok";
|
|
730
|
+
} catch {
|
|
731
|
+
return false;
|
|
732
|
+
} finally {
|
|
733
|
+
clearTimeout(timer);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
function extractHost(url) {
|
|
737
|
+
try {
|
|
738
|
+
return new URL(url).host;
|
|
739
|
+
} catch {
|
|
740
|
+
return url;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
function findSkillInCards(cards, skillId) {
|
|
744
|
+
for (const card of cards) {
|
|
745
|
+
if (card.skills) {
|
|
746
|
+
const skill2 = card.skills.find((s) => s.id === skillId);
|
|
747
|
+
if (skill2) {
|
|
748
|
+
return { card, skillId: skill2.id, credits: skill2.pricing?.credits_per_call ?? 0, reason: "" };
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
if (card.id === skillId) {
|
|
752
|
+
return { card, skillId: "", credits: card.pricing?.credits_per_call ?? 0, reason: "" };
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
return null;
|
|
756
|
+
}
|
|
757
|
+
function findSafeSkill(cards, skillConfigs) {
|
|
758
|
+
const safeSkillIds = /* @__PURE__ */ new Set();
|
|
759
|
+
for (const sc of skillConfigs) {
|
|
760
|
+
if (sc.type === "command") {
|
|
761
|
+
const cmd = sc.command ?? "";
|
|
762
|
+
if (/\bclaude\b/.test(cmd) || /\becho\b/.test(cmd)) {
|
|
763
|
+
safeSkillIds.add(sc.id);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
let best = null;
|
|
768
|
+
for (const card of cards) {
|
|
769
|
+
if (card.skills) {
|
|
770
|
+
for (const skill2 of card.skills) {
|
|
771
|
+
if (safeSkillIds.has(skill2.id)) {
|
|
772
|
+
const credits2 = skill2.pricing?.credits_per_call ?? 0;
|
|
773
|
+
if (!best || credits2 < best.credits) {
|
|
774
|
+
best = { card, skillId: skill2.id, credits: credits2, reason: "safe command-type skill" };
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
if (!best) {
|
|
781
|
+
for (const sc of skillConfigs) {
|
|
782
|
+
if (safeSkillIds.has(sc.id)) {
|
|
783
|
+
for (const card of cards) {
|
|
784
|
+
const pricing = card.pricing;
|
|
785
|
+
const credits2 = pricing?.credits_per_call ?? 0;
|
|
786
|
+
if (!best || credits2 < best.credits) {
|
|
787
|
+
best = { card, skillId: sc.id, credits: credits2, reason: "safe command-type skill" };
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
return best;
|
|
794
|
+
}
|
|
795
|
+
function findCheapestSkill(cards) {
|
|
796
|
+
let best = { card: cards[0], skillId: "", credits: Infinity, reason: "" };
|
|
797
|
+
for (const card of cards) {
|
|
798
|
+
if (card.skills) {
|
|
799
|
+
for (const skill2 of card.skills) {
|
|
800
|
+
const credits2 = skill2.pricing?.credits_per_call ?? 0;
|
|
801
|
+
if (credits2 < best.credits) {
|
|
802
|
+
best = { card, skillId: skill2.id, credits: credits2, reason: "cheapest available" };
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
const cardCredits = card.pricing?.credits_per_call ?? 0;
|
|
807
|
+
if (cardCredits < best.credits) {
|
|
808
|
+
best = { card, skillId: "", credits: cardCredits, reason: "cheapest available" };
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
if (best.credits === Infinity) best.credits = 0;
|
|
812
|
+
return best;
|
|
813
|
+
}
|
|
814
|
+
async function runDoctor(opts) {
|
|
815
|
+
const configDir = getConfigDir();
|
|
816
|
+
const config = loadConfig();
|
|
817
|
+
if (!config) {
|
|
818
|
+
const report2 = {
|
|
819
|
+
checks: [{
|
|
820
|
+
name: "Identity",
|
|
821
|
+
status: "fail",
|
|
822
|
+
message: "not initialized",
|
|
823
|
+
context: "AgentBnB has not been set up on this machine.",
|
|
824
|
+
fix: "Run `agentbnb quickstart` to get started"
|
|
825
|
+
}],
|
|
826
|
+
passed: 0,
|
|
827
|
+
warnings: 0,
|
|
828
|
+
failed: 1,
|
|
829
|
+
total: 1
|
|
830
|
+
};
|
|
831
|
+
renderReport(report2, opts.json ?? false);
|
|
832
|
+
process.exit(1);
|
|
833
|
+
}
|
|
834
|
+
const checks = [];
|
|
835
|
+
checks.push(checkIdentity(configDir, config));
|
|
836
|
+
checks.push(checkSkills(configDir));
|
|
837
|
+
const gateway = await checkGateway(configDir);
|
|
838
|
+
checks.push(gateway.result);
|
|
839
|
+
const daemonRunning = gateway.result.status === "pass";
|
|
840
|
+
const cardsLocal = checkCards(config);
|
|
841
|
+
checks.push(checkCredits(config));
|
|
842
|
+
const registryResult = await checkRegistry(config);
|
|
843
|
+
checks.push(registryResult);
|
|
844
|
+
if (cardsLocal.localCount > 0 && registryResult.status === "pass") {
|
|
845
|
+
checks.splice(3, 0, await checkCardsRemote(config, cardsLocal.localCount));
|
|
846
|
+
} else if (cardsLocal.localCount > 0) {
|
|
847
|
+
checks.splice(3, 0, {
|
|
848
|
+
name: "Cards",
|
|
849
|
+
status: "warn",
|
|
850
|
+
message: `${cardsLocal.localCount} cards published locally \u2014 remote discoverability not verified`,
|
|
851
|
+
context: "Without remote registry verification, other agents may not find your skills."
|
|
852
|
+
});
|
|
853
|
+
} else {
|
|
854
|
+
checks.splice(3, 0, cardsLocal.result);
|
|
855
|
+
}
|
|
856
|
+
checks.push(checkRelay(config, daemonRunning));
|
|
857
|
+
let testHireResult;
|
|
858
|
+
if (opts.testHire) {
|
|
859
|
+
testHireResult = await runTestHire(config, configDir, opts.skill);
|
|
860
|
+
}
|
|
861
|
+
const passed = checks.filter((c) => c.status === "pass").length;
|
|
862
|
+
const warnings = checks.filter((c) => c.status === "warn").length;
|
|
863
|
+
const failed = checks.filter((c) => c.status === "fail").length;
|
|
864
|
+
const report = {
|
|
865
|
+
checks,
|
|
866
|
+
testHire: testHireResult,
|
|
867
|
+
passed,
|
|
868
|
+
warnings,
|
|
869
|
+
failed,
|
|
870
|
+
total: checks.length
|
|
871
|
+
};
|
|
872
|
+
renderReport(report, opts.json ?? false);
|
|
873
|
+
if (failed > 0) process.exit(1);
|
|
874
|
+
}
|
|
875
|
+
function renderReport(report, jsonMode) {
|
|
876
|
+
if (jsonMode) {
|
|
877
|
+
console.log(JSON.stringify(report, null, 2));
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
console.log("\nagentbnb doctor \u2014 Provider Readiness Check\n");
|
|
881
|
+
for (const check of report.checks) {
|
|
882
|
+
const icon = check.status === "pass" ? "\u2713" : check.status === "warn" ? "\u26A0" : "\u2717";
|
|
883
|
+
const pad = check.name.padEnd(12);
|
|
884
|
+
console.log(` ${icon} ${pad} ${check.message}`);
|
|
885
|
+
}
|
|
886
|
+
const parts = [`${report.passed}/${report.total} checks passed`];
|
|
887
|
+
if (report.warnings > 0) parts.push(`${report.warnings} warning${report.warnings > 1 ? "s" : ""}`);
|
|
888
|
+
if (report.failed > 0) parts.push(`${report.failed} failure${report.failed > 1 ? "s" : ""}`);
|
|
889
|
+
console.log(`
|
|
890
|
+
Result: ${parts.join(", ")}
|
|
891
|
+
`);
|
|
892
|
+
const failures = report.checks.filter((c) => c.status === "fail");
|
|
893
|
+
if (failures.length > 0) {
|
|
894
|
+
console.log(" To fix:");
|
|
895
|
+
for (const f of failures) {
|
|
896
|
+
console.log(` \u2717 ${f.name} \u2014 ${f.context ?? f.message}`);
|
|
897
|
+
if (f.fix) console.log(` \u2192 ${f.fix}`);
|
|
898
|
+
}
|
|
899
|
+
console.log("");
|
|
900
|
+
}
|
|
901
|
+
const warns = report.checks.filter((c) => c.status === "warn" && c.context);
|
|
902
|
+
if (warns.length > 0) {
|
|
903
|
+
console.log(" Warnings:");
|
|
904
|
+
for (const w of warns) {
|
|
905
|
+
console.log(` \u26A0 ${w.name} \u2014 ${w.context}`);
|
|
906
|
+
if (w.fix) console.log(` \u2192 ${w.fix}`);
|
|
907
|
+
}
|
|
908
|
+
console.log("");
|
|
909
|
+
}
|
|
910
|
+
if (report.testHire) {
|
|
911
|
+
const th = report.testHire;
|
|
912
|
+
console.log(" Test hire:");
|
|
913
|
+
console.log(` Skill: ${th.skillId} (${th.creditsSpent} credits, selected: ${th.selectionReason})`);
|
|
914
|
+
if (th.success) {
|
|
915
|
+
console.log(` Result: \u2713 completed in ${th.latency_ms}ms`);
|
|
916
|
+
console.log(` Credits: ${th.creditsSpent} credits spent (self-to-self)`);
|
|
917
|
+
console.log(" Proof: Your provider can execute real hire requests end-to-end.");
|
|
918
|
+
} else {
|
|
919
|
+
console.log(` Result: \u2717 failed after ${th.latency_ms}ms`);
|
|
920
|
+
console.log(` Error: ${th.error}`);
|
|
921
|
+
}
|
|
922
|
+
console.log("");
|
|
923
|
+
}
|
|
924
|
+
if (!report.testHire && report.failed === 0) {
|
|
925
|
+
console.log(" Next steps:");
|
|
926
|
+
console.log(" \u2192 Run `agentbnb doctor --test-hire` to prove end-to-end hiring works");
|
|
927
|
+
console.log(' \u2192 Run `agentbnb discover "code review"` to see your skills as a hirer would');
|
|
928
|
+
console.log("");
|
|
302
929
|
}
|
|
303
930
|
}
|
|
304
931
|
|
|
305
932
|
// src/cli/index.ts
|
|
306
|
-
var
|
|
933
|
+
var REGISTRY_HTTP_BUDGET_MS = 5e3;
|
|
934
|
+
var VERSION = true ? "9.2.2" : "0.0.0-dev";
|
|
307
935
|
function loadIdentityAuth(owner) {
|
|
308
936
|
const configDir = getConfigDir();
|
|
309
937
|
let keys;
|
|
@@ -402,7 +1030,7 @@ program.command("publish <card.json>").description("Publish a Capability Card to
|
|
|
402
1030
|
}
|
|
403
1031
|
let raw;
|
|
404
1032
|
try {
|
|
405
|
-
raw =
|
|
1033
|
+
raw = readFileSync3(cardPath, "utf-8");
|
|
406
1034
|
} catch {
|
|
407
1035
|
console.error(`Error: cannot read file: ${cardPath}`);
|
|
408
1036
|
process.exit(1);
|
|
@@ -478,14 +1106,17 @@ program.command("publish <card.json>").description("Publish a Capability Card to
|
|
|
478
1106
|
}
|
|
479
1107
|
const registryUrl = opts.registry ?? config.registry;
|
|
480
1108
|
let remoteSuccess = false;
|
|
481
|
-
if (registryUrl) {
|
|
1109
|
+
if (registryUrl && !shouldSkipNetwork()) {
|
|
482
1110
|
const url = `${registryUrl.replace(/\/$/, "")}/cards`;
|
|
483
1111
|
const remoteCard = config.agent_id && localCard.owner === config.owner && localCard.agent_id !== config.agent_id ? { ...localCard, agent_id: config.agent_id, gateway_url: config.gateway_url } : { ...localCard, gateway_url: config.gateway_url };
|
|
1112
|
+
const controller = new AbortController();
|
|
1113
|
+
const timer = setTimeout(() => controller.abort(), REGISTRY_HTTP_BUDGET_MS);
|
|
484
1114
|
try {
|
|
485
1115
|
const response = await fetch(url, {
|
|
486
1116
|
method: "POST",
|
|
487
1117
|
headers: { "Content-Type": "application/json" },
|
|
488
|
-
body: JSON.stringify(remoteCard)
|
|
1118
|
+
body: JSON.stringify(remoteCard),
|
|
1119
|
+
signal: controller.signal
|
|
489
1120
|
});
|
|
490
1121
|
if (!response.ok) {
|
|
491
1122
|
const body = await response.text();
|
|
@@ -497,7 +1128,11 @@ program.command("publish <card.json>").description("Publish a Capability Card to
|
|
|
497
1128
|
}
|
|
498
1129
|
}
|
|
499
1130
|
} catch (err) {
|
|
500
|
-
|
|
1131
|
+
const isAbort = err.name === "AbortError";
|
|
1132
|
+
const reason = isAbort ? `timeout after ${REGISTRY_HTTP_BUDGET_MS}ms` : err.message;
|
|
1133
|
+
console.error(`Warning: cannot reach registry at ${url}: ${reason}`);
|
|
1134
|
+
} finally {
|
|
1135
|
+
clearTimeout(timer);
|
|
501
1136
|
}
|
|
502
1137
|
}
|
|
503
1138
|
if (opts.json) {
|
|
@@ -516,19 +1151,19 @@ program.command("publish-skills").description("Publish capabilities from skills.
|
|
|
516
1151
|
console.error("Error: not initialized. Run `agentbnb init` first.");
|
|
517
1152
|
process.exit(1);
|
|
518
1153
|
}
|
|
519
|
-
const { parseSkillsFile } = await import("../skill-config-VYNF7BCY.js");
|
|
520
|
-
const { skillConfigToSkill } = await import("../publish-capability-
|
|
1154
|
+
const { parseSkillsFile: parseSkillsFile2 } = await import("../skill-config-VYNF7BCY.js");
|
|
1155
|
+
const { skillConfigToSkill } = await import("../publish-capability-OYXXXYAU.js");
|
|
521
1156
|
const skillsPath = typeof opts.fromSkills === "string" ? opts.fromSkills : "./skills.yaml";
|
|
522
1157
|
let yamlContent;
|
|
523
1158
|
try {
|
|
524
|
-
yamlContent =
|
|
1159
|
+
yamlContent = readFileSync3(skillsPath, "utf-8");
|
|
525
1160
|
} catch {
|
|
526
1161
|
console.error(`Error: cannot read skills.yaml at ${skillsPath}`);
|
|
527
1162
|
process.exit(1);
|
|
528
1163
|
}
|
|
529
1164
|
let allSkillConfigs;
|
|
530
1165
|
try {
|
|
531
|
-
allSkillConfigs =
|
|
1166
|
+
allSkillConfigs = parseSkillsFile2(yamlContent);
|
|
532
1167
|
} catch (err) {
|
|
533
1168
|
const msg = err instanceof Error ? err.message : String(err);
|
|
534
1169
|
console.error(`Error: failed to parse skills.yaml \u2014 ${msg}`);
|
|
@@ -599,15 +1234,30 @@ program.command("sync").description("Push all local capability cards to the conf
|
|
|
599
1234
|
let synced = 0;
|
|
600
1235
|
let failed = 0;
|
|
601
1236
|
const results = [];
|
|
1237
|
+
if (!shouldSkipNetwork()) {
|
|
1238
|
+
const reachable = await probeRegistry(registryUrl);
|
|
1239
|
+
if (!reachable) {
|
|
1240
|
+
if (!opts.json) {
|
|
1241
|
+
console.error(`Error: cannot reach registry at ${registryUrl}. Try again when online.`);
|
|
1242
|
+
}
|
|
1243
|
+
if (opts.json) {
|
|
1244
|
+
console.log(JSON.stringify({ synced: 0, failed: localCards.length, registry: registryUrl, error: "unreachable" }, null, 2));
|
|
1245
|
+
}
|
|
1246
|
+
process.exit(1);
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
602
1249
|
for (const card of localCards) {
|
|
603
1250
|
const { _internal: _, ...publicCard } = card;
|
|
604
1251
|
const remoteCard = { ...publicCard, gateway_url: config.gateway_url };
|
|
605
1252
|
const displayName = card.name ?? card.agent_name ?? card.id;
|
|
1253
|
+
const controller = new AbortController();
|
|
1254
|
+
const timer = setTimeout(() => controller.abort(), REGISTRY_HTTP_BUDGET_MS);
|
|
606
1255
|
try {
|
|
607
1256
|
const response = await fetch(url, {
|
|
608
1257
|
method: "POST",
|
|
609
1258
|
headers: { "Content-Type": "application/json" },
|
|
610
|
-
body: JSON.stringify(remoteCard)
|
|
1259
|
+
body: JSON.stringify(remoteCard),
|
|
1260
|
+
signal: controller.signal
|
|
611
1261
|
});
|
|
612
1262
|
if (response.ok) {
|
|
613
1263
|
synced++;
|
|
@@ -625,11 +1275,14 @@ program.command("sync").description("Push all local capability cards to the conf
|
|
|
625
1275
|
}
|
|
626
1276
|
} catch (err) {
|
|
627
1277
|
failed++;
|
|
628
|
-
const
|
|
1278
|
+
const isAbort = err.name === "AbortError";
|
|
1279
|
+
const msg = isAbort ? `timeout after ${REGISTRY_HTTP_BUDGET_MS}ms` : err instanceof Error ? err.message : String(err);
|
|
629
1280
|
results.push({ id: card.id, name: displayName, ok: false, error: msg });
|
|
630
1281
|
if (!opts.json) {
|
|
631
1282
|
console.error(` Failed: ${displayName} \u2014 ${msg}`);
|
|
632
1283
|
}
|
|
1284
|
+
} finally {
|
|
1285
|
+
clearTimeout(timer);
|
|
633
1286
|
}
|
|
634
1287
|
}
|
|
635
1288
|
if (opts.json) {
|
|
@@ -760,16 +1413,19 @@ program.command("request [card-id]").description("Request a capability from anot
|
|
|
760
1413
|
console.error("Error: not initialized. Run `agentbnb init` first.");
|
|
761
1414
|
process.exit(1);
|
|
762
1415
|
}
|
|
763
|
-
if (config.registry) {
|
|
764
|
-
const
|
|
765
|
-
|
|
766
|
-
const
|
|
767
|
-
|
|
768
|
-
|
|
1416
|
+
if (config.registry && !shouldSkipNetwork()) {
|
|
1417
|
+
const reachable = await probeRegistry(config.registry);
|
|
1418
|
+
if (reachable) {
|
|
1419
|
+
const creditDb = openCreditDb(config.credit_db_path);
|
|
1420
|
+
try {
|
|
1421
|
+
const syncResult = await withTimeout(syncCreditsFromRegistry(config, creditDb), 3e3);
|
|
1422
|
+
if (syncResult.synced && syncResult.remoteBalance !== void 0) {
|
|
1423
|
+
console.log(`Credits synced: ${syncResult.remoteBalance} [registry]`);
|
|
1424
|
+
}
|
|
1425
|
+
} catch {
|
|
1426
|
+
} finally {
|
|
1427
|
+
creditDb.close();
|
|
769
1428
|
}
|
|
770
|
-
} catch {
|
|
771
|
-
} finally {
|
|
772
|
-
creditDb.close();
|
|
773
1429
|
}
|
|
774
1430
|
}
|
|
775
1431
|
if (opts.batch) {
|
|
@@ -780,13 +1436,16 @@ program.command("request [card-id]").description("Request a capability from anot
|
|
|
780
1436
|
}
|
|
781
1437
|
let batchPayload;
|
|
782
1438
|
try {
|
|
783
|
-
const raw =
|
|
1439
|
+
const raw = readFileSync3(opts.batch, "utf-8");
|
|
784
1440
|
batchPayload = JSON.parse(raw);
|
|
785
1441
|
} catch (err) {
|
|
786
1442
|
console.error(`Error: could not read batch file: ${err.message}`);
|
|
787
1443
|
process.exit(1);
|
|
788
1444
|
}
|
|
789
1445
|
const batchUrl = `${registryUrl.replace(/\/$/, "")}/api/request/batch`;
|
|
1446
|
+
const BATCH_BUDGET_MS = 6e4;
|
|
1447
|
+
const controller = new AbortController();
|
|
1448
|
+
const timer = setTimeout(() => controller.abort(), BATCH_BUDGET_MS);
|
|
790
1449
|
let batchResp;
|
|
791
1450
|
let batchResult;
|
|
792
1451
|
try {
|
|
@@ -796,12 +1455,17 @@ program.command("request [card-id]").description("Request a capability from anot
|
|
|
796
1455
|
"Content-Type": "application/json",
|
|
797
1456
|
Authorization: `Bearer ${config.owner}`
|
|
798
1457
|
},
|
|
799
|
-
body: JSON.stringify(batchPayload)
|
|
1458
|
+
body: JSON.stringify(batchPayload),
|
|
1459
|
+
signal: controller.signal
|
|
800
1460
|
});
|
|
801
1461
|
batchResult = await batchResp.json();
|
|
802
1462
|
} catch (err) {
|
|
803
|
-
|
|
1463
|
+
const isAbort = err.name === "AbortError";
|
|
1464
|
+
const reason = isAbort ? `timeout after ${BATCH_BUDGET_MS}ms` : err.message;
|
|
1465
|
+
console.error(`Error: batch request failed: ${reason}`);
|
|
804
1466
|
process.exit(1);
|
|
1467
|
+
} finally {
|
|
1468
|
+
clearTimeout(timer);
|
|
805
1469
|
}
|
|
806
1470
|
if (opts.json) {
|
|
807
1471
|
console.log(JSON.stringify(batchResult, null, 2));
|
|
@@ -841,8 +1505,8 @@ Batch Results (${res.results.length} items):`);
|
|
|
841
1505
|
process.exit(1);
|
|
842
1506
|
}
|
|
843
1507
|
}
|
|
844
|
-
const registryDb = openDatabase(
|
|
845
|
-
const creditDb = openCreditDb(
|
|
1508
|
+
const registryDb = openDatabase(join3(getConfigDir(), "registry.db"));
|
|
1509
|
+
const creditDb = openCreditDb(join3(getConfigDir(), "credit.db"));
|
|
846
1510
|
registryDb.pragma("busy_timeout = 5000");
|
|
847
1511
|
creditDb.pragma("busy_timeout = 5000");
|
|
848
1512
|
try {
|
|
@@ -924,16 +1588,22 @@ Batch Results (${res.results.length} items):`);
|
|
|
924
1588
|
}
|
|
925
1589
|
const cardUrl = `${registryUrl.replace(/\/$/, "")}/cards/${cardId}`;
|
|
926
1590
|
let remoteCard;
|
|
1591
|
+
const cardController = new AbortController();
|
|
1592
|
+
const cardTimer = setTimeout(() => cardController.abort(), REGISTRY_HTTP_BUDGET_MS);
|
|
927
1593
|
try {
|
|
928
|
-
const resp = await fetch(cardUrl);
|
|
1594
|
+
const resp = await fetch(cardUrl, { signal: cardController.signal });
|
|
929
1595
|
if (!resp.ok) {
|
|
930
1596
|
console.error(`Error: card ${cardId} not found on remote registry (${resp.status}).`);
|
|
931
1597
|
process.exit(1);
|
|
932
1598
|
}
|
|
933
1599
|
remoteCard = await resp.json();
|
|
934
1600
|
} catch (err) {
|
|
935
|
-
|
|
1601
|
+
const isAbort = err.name === "AbortError";
|
|
1602
|
+
const reason = isAbort ? `timeout after ${REGISTRY_HTTP_BUDGET_MS}ms` : err.message;
|
|
1603
|
+
console.error(`Error: cannot reach registry: ${reason}`);
|
|
936
1604
|
process.exit(1);
|
|
1605
|
+
} finally {
|
|
1606
|
+
clearTimeout(cardTimer);
|
|
937
1607
|
}
|
|
938
1608
|
targetOwner = remoteCard.owner ?? remoteCard.agent_name;
|
|
939
1609
|
targetAgentId = typeof remoteCard.agent_id === "string" ? remoteCard.agent_id : void 0;
|
|
@@ -1047,23 +1717,37 @@ program.command("status").description("Show credit balance and recent transactio
|
|
|
1047
1717
|
creditDb.close();
|
|
1048
1718
|
}
|
|
1049
1719
|
const hasRegistry = config.registry != null;
|
|
1050
|
-
if (hasRegistry) {
|
|
1051
|
-
const
|
|
1052
|
-
|
|
1053
|
-
registryUrl: config.registry,
|
|
1054
|
-
ownerPublicKey: statusIdentityAuth.publicKey,
|
|
1055
|
-
privateKey: statusIdentityAuth.privateKey
|
|
1056
|
-
});
|
|
1057
|
-
try {
|
|
1058
|
-
registryBalance = await statusLedger.getBalance(config.owner);
|
|
1059
|
-
transactions = await statusLedger.getHistory(config.owner, 5);
|
|
1060
|
-
} catch (err) {
|
|
1720
|
+
if (hasRegistry && !shouldSkipNetwork()) {
|
|
1721
|
+
const reachable = await probeRegistry(config.registry);
|
|
1722
|
+
if (!reachable) {
|
|
1061
1723
|
registryUnavailable = true;
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1724
|
+
} else {
|
|
1725
|
+
const statusIdentityAuth = loadIdentityAuth(config.owner);
|
|
1726
|
+
const statusLedger = createLedger({
|
|
1727
|
+
registryUrl: config.registry,
|
|
1728
|
+
ownerPublicKey: statusIdentityAuth.publicKey,
|
|
1729
|
+
privateKey: statusIdentityAuth.privateKey
|
|
1730
|
+
});
|
|
1731
|
+
try {
|
|
1732
|
+
const [balance, history] = await withTimeout(
|
|
1733
|
+
Promise.all([
|
|
1734
|
+
statusLedger.getBalance(config.owner),
|
|
1735
|
+
statusLedger.getHistory(config.owner, 5)
|
|
1736
|
+
]),
|
|
1737
|
+
REGISTRY_HTTP_BUDGET_MS
|
|
1738
|
+
);
|
|
1739
|
+
registryBalance = balance;
|
|
1740
|
+
transactions = history;
|
|
1741
|
+
} catch (err) {
|
|
1742
|
+
registryUnavailable = true;
|
|
1743
|
+
const msg = err instanceof TimeoutError ? `timeout after ${REGISTRY_HTTP_BUDGET_MS}ms` : err instanceof Error ? err.message : String(err);
|
|
1744
|
+
if (!opts.json) {
|
|
1745
|
+
console.warn(`Note: could not fetch balance from registry (${msg}). Run \`agentbnb init\` if this is a new agent.`);
|
|
1746
|
+
}
|
|
1065
1747
|
}
|
|
1066
1748
|
}
|
|
1749
|
+
} else if (hasRegistry) {
|
|
1750
|
+
registryUnavailable = true;
|
|
1067
1751
|
}
|
|
1068
1752
|
const syncNeeded = hasRegistry && !registryUnavailable && registryBalance !== null && Math.abs(registryBalance - localBalance) > 1;
|
|
1069
1753
|
const displayBalance = registryBalance ?? localBalance;
|
|
@@ -1122,7 +1806,7 @@ Active Escrows (${heldEscrows.length}):`);
|
|
|
1122
1806
|
});
|
|
1123
1807
|
program.command("serve").description("Start the AgentBnB gateway server").option("--port <port>", "Port to listen on (overrides config)").option("--handler-url <url>", "Local capability handler URL", "http://localhost:8080").option("--skills-yaml <path>", "Path to skills.yaml (default: ~/.agentbnb/skills.yaml)").option("--registry-port <port>", "Public registry API port (0 to disable)", "7701").option("--registry <url>", "Connect to remote registry via WebSocket relay (e.g., hub.agentbnb.dev)").option("--conductor", "Enable Conductor orchestration mode").option("--announce", "Announce this gateway on the local network via mDNS").option("--no-relay", "Do not auto-connect to remote registry relay").option("--daemon", "Run in background as daemon").option("--status", "Show daemon status").option("--stop", "Stop the daemon").option("--restart", "Restart the daemon").option("--startup", "Register for auto-start on boot").action(async (opts) => {
|
|
1124
1808
|
if (opts.status || opts.stop || opts.restart || opts.daemon || opts.startup) {
|
|
1125
|
-
const { startDaemon, stopDaemon, restartDaemon, daemonStatus, registerStartup } = await import("../daemon-
|
|
1809
|
+
const { startDaemon, stopDaemon, restartDaemon, daemonStatus, registerStartup } = await import("../daemon-OM2K3U7J.js");
|
|
1126
1810
|
if (opts.status) {
|
|
1127
1811
|
daemonStatus();
|
|
1128
1812
|
return;
|
|
@@ -1158,15 +1842,15 @@ program.command("serve").description("Start the AgentBnB gateway server").option
|
|
|
1158
1842
|
console.error("Error: not initialized. Run `agentbnb init` first.");
|
|
1159
1843
|
process.exit(1);
|
|
1160
1844
|
}
|
|
1161
|
-
const { ProcessGuard } = await import("../process-guard-
|
|
1162
|
-
const { ServiceCoordinator } = await import("../service-coordinator-
|
|
1845
|
+
const { ProcessGuard: ProcessGuard2 } = await import("../process-guard-IUMZ2GSD.js");
|
|
1846
|
+
const { ServiceCoordinator } = await import("../service-coordinator-RE2KPWO4.js");
|
|
1163
1847
|
const port = opts.port ? parseInt(opts.port, 10) : config.gateway_port;
|
|
1164
1848
|
const registryPort = parseInt(opts.registryPort, 10);
|
|
1165
1849
|
if (!Number.isFinite(port) || !Number.isFinite(registryPort)) {
|
|
1166
1850
|
console.error("Error: --port and --registry-port must be valid numbers.");
|
|
1167
1851
|
process.exit(1);
|
|
1168
1852
|
}
|
|
1169
|
-
const guard = new
|
|
1853
|
+
const guard = new ProcessGuard2(join3(getConfigDir(), ".pid"));
|
|
1170
1854
|
const coordinator = new ServiceCoordinator(config, guard);
|
|
1171
1855
|
try {
|
|
1172
1856
|
await coordinator.ensureRunning({
|
|
@@ -1528,7 +2212,7 @@ openclaw.command("sync").description("Read SOUL.md and publish/update a v2.0 cap
|
|
|
1528
2212
|
const found = findSoulMd(searchName) ?? (searchName !== config.owner ? findSoulMd(config.owner) : null);
|
|
1529
2213
|
if (found) {
|
|
1530
2214
|
resolvedSoulPath = found;
|
|
1531
|
-
} else if (
|
|
2215
|
+
} else if (existsSync3("./SOUL.md")) {
|
|
1532
2216
|
resolvedSoulPath = "./SOUL.md";
|
|
1533
2217
|
} else {
|
|
1534
2218
|
const { homedir: homedir2 } = await import("os");
|
|
@@ -1536,9 +2220,9 @@ openclaw.command("sync").description("Read SOUL.md and publish/update a v2.0 cap
|
|
|
1536
2220
|
const workspaceDir = getOpenClawWorkspaceDir();
|
|
1537
2221
|
console.error(`No SOUL.md found for agent "${searchName}".`);
|
|
1538
2222
|
console.error("Searched:");
|
|
1539
|
-
console.error(` - ${
|
|
1540
|
-
console.error(` - ${
|
|
1541
|
-
console.error(` - ${
|
|
2223
|
+
console.error(` - ${join3(workspaceDir, "brains", searchName, "SOUL.md")}`);
|
|
2224
|
+
console.error(` - ${join3(home, ".openclaw", "agents", searchName, "SOUL.md")}`);
|
|
2225
|
+
console.error(` - ${join3(workspaceDir, "SOUL.md")}`);
|
|
1542
2226
|
console.error(` - ./SOUL.md`);
|
|
1543
2227
|
console.error("");
|
|
1544
2228
|
console.error("Create a SOUL.md file in one of these locations, or use:");
|
|
@@ -1549,7 +2233,7 @@ openclaw.command("sync").description("Read SOUL.md and publish/update a v2.0 cap
|
|
|
1549
2233
|
}
|
|
1550
2234
|
let content;
|
|
1551
2235
|
try {
|
|
1552
|
-
content =
|
|
2236
|
+
content = readFileSync3(resolvedSoulPath, "utf-8");
|
|
1553
2237
|
} catch {
|
|
1554
2238
|
console.error(`Error: cannot read SOUL.md at ${resolvedSoulPath}`);
|
|
1555
2239
|
process.exit(1);
|
|
@@ -1619,34 +2303,34 @@ openclaw.command("rules").description("Print HEARTBEAT.md rules block (or inject
|
|
|
1619
2303
|
}
|
|
1620
2304
|
});
|
|
1621
2305
|
openclaw.command("setup").description("Interactive onboarding: connect an OpenClaw agent to AgentBnB").option("--agent <name>", "Agent name to set up (skip interactive selection)").option("--soul-path <path>", "Override SOUL.md path").option("-y, --yes", "Skip confirmation prompts").action(async (opts) => {
|
|
1622
|
-
const { runOpenClawSetup } = await import("../openclaw-setup-
|
|
2306
|
+
const { runOpenClawSetup } = await import("../openclaw-setup-HUOBTGN4.js");
|
|
1623
2307
|
await runOpenClawSetup(opts);
|
|
1624
2308
|
});
|
|
1625
2309
|
var skills = openclaw.command("skills").description("Manage shared skills on AgentBnB");
|
|
1626
2310
|
skills.command("list").description("List all shared skills with stats").action(async () => {
|
|
1627
|
-
const { skillsList } = await import("../openclaw-skills-
|
|
2311
|
+
const { skillsList } = await import("../openclaw-skills-74372B6I.js");
|
|
1628
2312
|
await skillsList({});
|
|
1629
2313
|
});
|
|
1630
2314
|
skills.command("add").description("Add a skill to share (interactive or --manual)").option("--manual", "Non-interactive: use flags instead of prompts").option("--name <id>", "Skill ID").option("--type <type>", "Skill type (command|openclaw)").option("--price <n>", "Credits per call", parseFloat).option("--description <text>", "Skill description").action(
|
|
1631
2315
|
async (opts) => {
|
|
1632
|
-
const { skillsAdd } = await import("../openclaw-skills-
|
|
2316
|
+
const { skillsAdd } = await import("../openclaw-skills-74372B6I.js");
|
|
1633
2317
|
await skillsAdd(opts);
|
|
1634
2318
|
}
|
|
1635
2319
|
);
|
|
1636
2320
|
skills.command("remove <skillId>").description("Remove a skill from AgentBnB").action(async (skillId) => {
|
|
1637
|
-
const { skillsRemove } = await import("../openclaw-skills-
|
|
2321
|
+
const { skillsRemove } = await import("../openclaw-skills-74372B6I.js");
|
|
1638
2322
|
await skillsRemove(skillId);
|
|
1639
2323
|
});
|
|
1640
2324
|
skills.command("price <skillId> <price>").description("Update skill price").action(async (skillId, price) => {
|
|
1641
|
-
const { skillsPrice } = await import("../openclaw-skills-
|
|
2325
|
+
const { skillsPrice } = await import("../openclaw-skills-74372B6I.js");
|
|
1642
2326
|
await skillsPrice(skillId, parseFloat(price));
|
|
1643
2327
|
});
|
|
1644
2328
|
skills.command("stats").description("Revenue and performance report").option("--days <n>", "Days to look back", parseInt, 7).action(async (opts) => {
|
|
1645
|
-
const { skillsStats } = await import("../openclaw-skills-
|
|
2329
|
+
const { skillsStats } = await import("../openclaw-skills-74372B6I.js");
|
|
1646
2330
|
await skillsStats(opts);
|
|
1647
2331
|
});
|
|
1648
2332
|
program.command("conduct <task>").description("Orchestrate a complex task across the AgentBnB network").option("--plan-only", "Show execution plan without executing").option("--max-budget <credits>", "Maximum credits to spend", "100").option("--json", "Output as JSON").action(async (task, opts) => {
|
|
1649
|
-
const { conductAction } = await import("../conduct-
|
|
2333
|
+
const { conductAction } = await import("../conduct-AALDEKTH.js");
|
|
1650
2334
|
const result = await conductAction(task, opts);
|
|
1651
2335
|
if (opts.json) {
|
|
1652
2336
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -1705,10 +2389,12 @@ feedback.command("submit").description("Submit structured feedback for a complet
|
|
|
1705
2389
|
res = await fetch(`${registryUrl}/api/feedback`, {
|
|
1706
2390
|
method: "POST",
|
|
1707
2391
|
headers: { "Content-Type": "application/json" },
|
|
1708
|
-
body: JSON.stringify(result.data)
|
|
2392
|
+
body: JSON.stringify(result.data),
|
|
2393
|
+
signal: AbortSignal.timeout(1e4)
|
|
1709
2394
|
});
|
|
1710
2395
|
} catch (err) {
|
|
1711
|
-
|
|
2396
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2397
|
+
console.error(`Error: failed to connect to registry \u2014 ${msg}`);
|
|
1712
2398
|
process.exit(1);
|
|
1713
2399
|
}
|
|
1714
2400
|
const body = await res.json();
|
|
@@ -1728,9 +2414,10 @@ feedback.command("list").description("List feedback entries for a skill").requir
|
|
|
1728
2414
|
const url = `${registryUrl}/api/feedback/${encodeURIComponent(opts.skill)}?limit=20`;
|
|
1729
2415
|
let res;
|
|
1730
2416
|
try {
|
|
1731
|
-
res = await fetch(url);
|
|
2417
|
+
res = await fetch(url, { signal: AbortSignal.timeout(1e4) });
|
|
1732
2418
|
} catch (err) {
|
|
1733
|
-
|
|
2419
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2420
|
+
console.error(`Error: failed to connect to registry \u2014 ${msg}`);
|
|
1734
2421
|
process.exit(1);
|
|
1735
2422
|
}
|
|
1736
2423
|
const body = await res.json();
|
|
@@ -1764,7 +2451,7 @@ skill.command("wrap").description("Wrap a CLI command as a rentable AgentBnB ski
|
|
|
1764
2451
|
});
|
|
1765
2452
|
var did = program.command("did").description("Decentralized Identity commands");
|
|
1766
2453
|
did.command("show").description("Display local agent DID identifiers").option("--json", "Output as JSON").action(async (opts) => {
|
|
1767
|
-
const { didShow, didShowJson } = await import("../did-action-
|
|
2454
|
+
const { didShow, didShowJson } = await import("../did-action-ERXWCVEJ.js");
|
|
1768
2455
|
if (opts.json) {
|
|
1769
2456
|
await didShowJson();
|
|
1770
2457
|
} else {
|
|
@@ -1773,45 +2460,48 @@ did.command("show").description("Display local agent DID identifiers").option("-
|
|
|
1773
2460
|
});
|
|
1774
2461
|
var vc = program.command("vc").description("Verifiable Credentials commands");
|
|
1775
2462
|
vc.command("show").description("Display Verifiable Credentials for this agent").option("--json", "Output as JSON").action(async (opts) => {
|
|
1776
|
-
const { vcShow } = await import("../vc-action-
|
|
2463
|
+
const { vcShow } = await import("../vc-action-72TQVMY2.js");
|
|
1777
2464
|
await vcShow(opts);
|
|
1778
2465
|
});
|
|
1779
2466
|
var credits = program.command("credits").description("Credit balance and transaction management");
|
|
1780
2467
|
credits.command("sync").description("Sync local credit balance from remote registry").action(async () => {
|
|
1781
|
-
const { creditsSync } = await import("../credits-action-
|
|
2468
|
+
const { creditsSync } = await import("../credits-action-CLLPNRDT.js");
|
|
1782
2469
|
await creditsSync();
|
|
1783
2470
|
});
|
|
1784
2471
|
credits.command("history").description("Show recent credit transactions").option("--limit <n>", "Number of transactions to show", "20").option("--json", "Output as JSON").action(async (opts) => {
|
|
1785
|
-
const { creditsHistory } = await import("../credits-action-
|
|
2472
|
+
const { creditsHistory } = await import("../credits-action-CLLPNRDT.js");
|
|
1786
2473
|
await creditsHistory(opts);
|
|
1787
2474
|
});
|
|
1788
2475
|
credits.command("grant <agent_id> <amount>").description("Admin: grant credits to an agent (requires ADMIN_TOKEN)").action(async (agentId, amount) => {
|
|
1789
|
-
const { creditsGrant } = await import("../credits-action-
|
|
2476
|
+
const { creditsGrant } = await import("../credits-action-CLLPNRDT.js");
|
|
1790
2477
|
await creditsGrant(agentId, amount);
|
|
1791
2478
|
});
|
|
1792
2479
|
var sessionCmd = program.command("session").description("Manage interactive agent-to-agent sessions");
|
|
1793
2480
|
sessionCmd.command("open <card_id>").description("Open an interactive session with a provider agent").requiredOption("--skill <skill_id>", "Skill ID to use").requiredOption("--budget <credits>", "Maximum credits for this session", parseInt).requiredOption("--message <msg>", "Initial message to send").option("--pricing <model>", "Pricing model: per_message, per_minute, per_session", "per_message").action(async (cardId, opts) => {
|
|
1794
|
-
const { sessionOpen } = await import("../session-action-
|
|
2481
|
+
const { sessionOpen } = await import("../session-action-UBWJTQVQ.js");
|
|
1795
2482
|
await sessionOpen(cardId, opts);
|
|
1796
2483
|
});
|
|
1797
2484
|
sessionCmd.command("send <session_id> <message>").description("Send a message within an active session").action(async (sessionId, message) => {
|
|
1798
|
-
const { sessionSend } = await import("../session-action-
|
|
2485
|
+
const { sessionSend } = await import("../session-action-UBWJTQVQ.js");
|
|
1799
2486
|
await sessionSend(sessionId, message);
|
|
1800
2487
|
});
|
|
1801
2488
|
sessionCmd.command("end <session_id>").description("End an active session").option("--reason <reason>", "End reason: completed, cancelled", "completed").action(async (sessionId, opts) => {
|
|
1802
|
-
const { sessionEnd } = await import("../session-action-
|
|
2489
|
+
const { sessionEnd } = await import("../session-action-UBWJTQVQ.js");
|
|
1803
2490
|
await sessionEnd(sessionId, opts.reason);
|
|
1804
2491
|
});
|
|
1805
2492
|
sessionCmd.command("list").description("List active sessions").action(async () => {
|
|
1806
|
-
const { sessionList } = await import("../session-action-
|
|
2493
|
+
const { sessionList } = await import("../session-action-UBWJTQVQ.js");
|
|
1807
2494
|
await sessionList();
|
|
1808
2495
|
});
|
|
1809
2496
|
sessionCmd.command("status <session_id>").description("Show session details").action(async (sessionId) => {
|
|
1810
|
-
const { sessionStatus } = await import("../session-action-
|
|
2497
|
+
const { sessionStatus } = await import("../session-action-UBWJTQVQ.js");
|
|
1811
2498
|
await sessionStatus(sessionId);
|
|
1812
2499
|
});
|
|
2500
|
+
program.command("doctor").description("Validate provider readiness \u2014 setup, skills, connectivity, discoverability").option("--json", "Output as JSON").option("--test-hire", "Run a self-hire smoke test to prove end-to-end execution").option("--skill <id>", "Specific skill to test with --test-hire").action(async (opts) => {
|
|
2501
|
+
await runDoctor(opts);
|
|
2502
|
+
});
|
|
1813
2503
|
program.command("mcp-server").description("Start an MCP (Model Context Protocol) server for IDE integration").action(async () => {
|
|
1814
|
-
const { startMcpServer } = await import("../server-
|
|
2504
|
+
const { startMcpServer } = await import("../server-4TACULIV.js");
|
|
1815
2505
|
await startMcpServer();
|
|
1816
2506
|
});
|
|
1817
2507
|
await program.parseAsync(process.argv);
|