agentbnb 8.2.0 → 8.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.
Files changed (40) hide show
  1. package/dist/{chunk-TBJ3FZKZ.js → chunk-4IPJJRTP.js} +1 -1
  2. package/dist/chunk-CKOOVZOI.js +158 -0
  3. package/dist/chunk-CQFBNTGT.js +145 -0
  4. package/dist/{chunk-P4LOYSLA.js → chunk-DYQOFGGI.js} +331 -416
  5. package/dist/{chunk-ALX4WS3A.js → chunk-EG6RS4JC.js} +70 -46
  6. package/dist/{chunk-CUONY5TO.js → chunk-EJKW57ZV.js} +19 -1
  7. package/dist/{chunk-5AAFG2V2.js → chunk-LKLKYXLV.js} +239 -24
  8. package/dist/{chunk-7EF3HYVZ.js → chunk-MCED4GDW.js} +499 -86
  9. package/dist/{chunk-YHY7OG6S.js → chunk-MWOXW7JQ.js} +7 -7
  10. package/dist/{chunk-E2OKP5CY.js → chunk-QCGIG7WW.js} +182 -86
  11. package/dist/{chunk-5GME4KJZ.js → chunk-QHZGOG3O.js} +148 -46
  12. package/dist/{chunk-D6RKW2XG.js → chunk-RYISHSHB.js} +302 -4
  13. package/dist/{chunk-O2OYBAVR.js → chunk-S3V6R3EN.js} +75 -39
  14. package/dist/{chunk-X32NE6V4.js → chunk-WNXXLCV5.js} +1 -1
  15. package/dist/{chunk-C537SFHV.js → chunk-XBGVQMQJ.js} +72 -48
  16. package/dist/{chunk-FTZTEHYG.js → chunk-Z2GEFFDO.js} +135 -8
  17. package/dist/cli/index.js +42 -67
  18. package/dist/{client-HKV3QWZ3.js → client-XOLP5IUZ.js} +4 -2
  19. package/dist/{conduct-W6XF6DJW.js → conduct-AZFLNUX3.js} +10 -11
  20. package/dist/{conduct-YB64OHI6.js → conduct-VPUYTNEA.js} +10 -11
  21. package/dist/{conductor-mode-AKREGDIU.js → conductor-mode-PLTB6MS3.js} +7 -8
  22. package/dist/{conductor-mode-TFCVCQHU.js → conductor-mode-WKB42PYM.js} +6 -3
  23. package/dist/{execute-EPE6MZLT.js → execute-NNDCXTN4.js} +3 -2
  24. package/dist/{execute-AYQWORVH.js → execute-RIRHTIBU.js} +6 -5
  25. package/dist/index.d.ts +8 -8
  26. package/dist/index.js +637 -693
  27. package/dist/{publish-capability-AH2HDW54.js → publish-capability-QDR2QIZ2.js} +2 -2
  28. package/dist/{request-HCCXSKAY.js → request-NX7GSPIG.js} +31 -36
  29. package/dist/{serve-skill-SZAQT5T5.js → serve-skill-E6EJQYAK.js} +10 -9
  30. package/dist/{server-LMY2A3GT.js → server-VBCT32FC.js} +12 -18
  31. package/dist/{service-coordinator-WGH6B2VT.js → service-coordinator-KMSA6BST.js} +137 -69
  32. package/dist/skills/agentbnb/bootstrap.js +561 -247
  33. package/package.json +13 -17
  34. package/skills/agentbnb/bootstrap.test.ts +8 -6
  35. package/skills/agentbnb/bootstrap.ts +21 -13
  36. package/skills/agentbnb/install.sh +0 -0
  37. package/dist/chunk-64AK4FJM.js +0 -84
  38. package/dist/chunk-KF3TZHA5.js +0 -91
  39. package/dist/chunk-LJM7FHPM.js +0 -138
  40. package/dist/chunk-OH7BP5NP.js +0 -96
@@ -1,3 +1,7 @@
1
+ import {
2
+ RelayClient,
3
+ RelayMessageSchema
4
+ } from "../../chunk-3LWBH7P3.js";
1
5
  import {
2
6
  AutoRequestor,
3
7
  BudgetController,
@@ -5,23 +9,19 @@ import {
5
9
  DEFAULT_AUTONOMY_CONFIG,
6
10
  DEFAULT_BUDGET_CONFIG,
7
11
  ORCHESTRATION_FEE,
8
- buildReputationMap,
9
- computeReputation,
10
12
  decompose,
11
- fetchRemoteCards,
12
- filterCards,
13
13
  getAutonomyTier,
14
14
  insertAuditEvent,
15
15
  interpolateObject,
16
16
  listPendingRequests,
17
17
  matchSubTasks,
18
- mergeResults,
19
18
  orchestrate,
19
+ resolvePendingRequest
20
+ } from "../../chunk-DYQOFGGI.js";
21
+ import {
20
22
  requestCapability,
21
- requestViaRelay,
22
- resolvePendingRequest,
23
- searchCards
24
- } from "../../chunk-P4LOYSLA.js";
23
+ requestViaRelay
24
+ } from "../../chunk-CKOOVZOI.js";
25
25
  import {
26
26
  loadPeers
27
27
  } from "../../chunk-HLUEOLSZ.js";
@@ -30,10 +30,13 @@ import {
30
30
  executeCapabilityRequest,
31
31
  releaseRequesterEscrow,
32
32
  settleRequesterEscrow
33
- } from "../../chunk-ALX4WS3A.js";
33
+ } from "../../chunk-EG6RS4JC.js";
34
34
  import {
35
35
  bootstrapAgent,
36
- generateKeyPair,
36
+ buildReputationMap,
37
+ computeReputation,
38
+ fetchRemoteCards,
39
+ filterCards,
37
40
  getActivityFeed,
38
41
  getBalance,
39
42
  getCard,
@@ -51,20 +54,26 @@ import {
51
54
  insertFeedback,
52
55
  insertRequestLog,
53
56
  listCards,
54
- loadKeyPair,
57
+ lookupAgent,
58
+ mergeResults,
55
59
  migrateOwner,
56
60
  openCreditDb,
57
61
  openDatabase,
58
62
  releaseEscrow,
59
- saveKeyPair,
63
+ searchCards,
60
64
  settleEscrow,
61
- signEscrowReceipt,
62
65
  updateCard,
63
66
  updateSkillAvailability,
64
- updateSkillIdleRate,
65
- verifyEscrowReceipt
66
- } from "../../chunk-7EF3HYVZ.js";
67
+ updateSkillIdleRate
68
+ } from "../../chunk-MCED4GDW.js";
67
69
  import "../../chunk-NWIQJ2CL.js";
70
+ import {
71
+ generateKeyPair,
72
+ loadKeyPair,
73
+ saveKeyPair,
74
+ signEscrowReceipt,
75
+ verifyEscrowReceipt
76
+ } from "../../chunk-EJKW57ZV.js";
68
77
  import {
69
78
  getConfigDir,
70
79
  loadConfig
@@ -73,17 +82,13 @@ import {
73
82
  AgentBnBError,
74
83
  AnyCardSchema
75
84
  } from "../../chunk-WVY2W7AA.js";
76
- import {
77
- RelayClient,
78
- RelayMessageSchema
79
- } from "../../chunk-3LWBH7P3.js";
80
85
 
81
86
  // skills/agentbnb/bootstrap.ts
82
- import { join as join6, basename, dirname as dirname4 } from "path";
83
- import { homedir as homedir3 } from "os";
84
- import { spawnSync, exec } from "child_process";
87
+ import { join as join7, basename as basename2, dirname as dirname3 } from "path";
88
+ import { homedir as homedir4 } from "os";
89
+ import { exec } from "child_process";
85
90
  import { promisify as promisify2 } from "util";
86
- import { randomUUID as randomUUID10 } from "crypto";
91
+ import { randomUUID as randomUUID11 } from "crypto";
87
92
 
88
93
  // src/runtime/process-guard.ts
89
94
  import { dirname, join } from "path";
@@ -1271,7 +1276,7 @@ var AgentRuntime = class {
1271
1276
  }
1272
1277
  const modes = /* @__PURE__ */ new Map();
1273
1278
  if (this.conductorEnabled) {
1274
- const { ConductorMode } = await import("../../conductor-mode-TFCVCQHU.js");
1279
+ const { ConductorMode } = await import("../../conductor-mode-WKB42PYM.js");
1275
1280
  const { registerConductorCard, CONDUCTOR_OWNER } = await import("../../card-EX2EYGCZ.js");
1276
1281
  const { loadPeers: loadPeers2 } = await import("../../peers-CJ7T4RJO.js");
1277
1282
  registerConductorCard(this.registryDb);
@@ -1435,7 +1440,54 @@ function createGatewayServer(opts) {
1435
1440
  return { status: "ok", version: VERSION, uptime: process.uptime() };
1436
1441
  });
1437
1442
  fastify.post("/rpc", async (request, reply) => {
1438
- const body = request.body;
1443
+ const rawBody = request.body;
1444
+ if (Array.isArray(rawBody)) {
1445
+ const responses = await Promise.all(
1446
+ rawBody.map(async (single) => {
1447
+ if (single.jsonrpc !== "2.0" || !single.method) {
1448
+ return { jsonrpc: "2.0", id: single.id ?? null, error: { code: -32600, message: "Invalid Request" } };
1449
+ }
1450
+ if (single.method !== "capability.execute") {
1451
+ return { jsonrpc: "2.0", id: single.id ?? null, error: { code: -32601, message: "Method not found" } };
1452
+ }
1453
+ const params2 = single.params ?? {};
1454
+ const cardId2 = params2.card_id;
1455
+ if (!cardId2) {
1456
+ return { jsonrpc: "2.0", id: single.id ?? null, error: { code: -32602, message: "Invalid params: card_id required" } };
1457
+ }
1458
+ const requester2 = params2.requester ?? "unknown";
1459
+ const receipt2 = params2.escrow_receipt;
1460
+ const batchSkillId = params2.skill_id;
1461
+ const trackKey2 = batchSkillId ?? cardId2;
1462
+ inFlight.set(trackKey2, (inFlight.get(trackKey2) ?? 0) + 1);
1463
+ try {
1464
+ const result2 = await executeCapabilityRequest({
1465
+ registryDb,
1466
+ creditDb,
1467
+ cardId: cardId2,
1468
+ skillId: batchSkillId,
1469
+ params: params2,
1470
+ requester: requester2,
1471
+ escrowReceipt: receipt2,
1472
+ skillExecutor,
1473
+ handlerUrl,
1474
+ timeoutMs
1475
+ });
1476
+ if (result2.success) {
1477
+ return { jsonrpc: "2.0", id: single.id ?? null, result: result2.result };
1478
+ } else {
1479
+ return { jsonrpc: "2.0", id: single.id ?? null, error: result2.error };
1480
+ }
1481
+ } finally {
1482
+ const next = (inFlight.get(trackKey2) ?? 1) - 1;
1483
+ if (next <= 0) inFlight.delete(trackKey2);
1484
+ else inFlight.set(trackKey2, next);
1485
+ }
1486
+ })
1487
+ );
1488
+ return reply.send(responses);
1489
+ }
1490
+ const body = rawBody;
1439
1491
  if (body.jsonrpc !== "2.0" || !body.method) {
1440
1492
  return reply.status(400).send({
1441
1493
  jsonrpc: "2.0",
@@ -1537,6 +1589,7 @@ import swaggerUi from "@fastify/swagger-ui";
1537
1589
  import fastifyStatic from "@fastify/static";
1538
1590
  import fastifyWebsocket from "@fastify/websocket";
1539
1591
  import { join as join3, dirname as dirname2 } from "path";
1592
+ import { randomUUID as randomUUID7 } from "crypto";
1540
1593
  import { fileURLToPath } from "url";
1541
1594
  import { existsSync as existsSync4 } from "fs";
1542
1595
  import { z as z7 } from "zod";
@@ -1655,13 +1708,190 @@ var LocalCreditLedger = class {
1655
1708
  }
1656
1709
  };
1657
1710
 
1711
+ // src/identity/identity.ts
1712
+ import { z as z2 } from "zod";
1713
+ import { createHash, createPrivateKey, createPublicKey } from "crypto";
1714
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync2 } from "fs";
1715
+ import { join as join2 } from "path";
1716
+ var AgentIdentitySchema = z2.object({
1717
+ /** Deterministic ID derived from public key: sha256(hex).slice(0, 16). */
1718
+ agent_id: z2.string().min(1),
1719
+ /** Human-readable owner name (from config or init). */
1720
+ owner: z2.string().min(1),
1721
+ /** Hex-encoded Ed25519 public key. */
1722
+ public_key: z2.string().min(1),
1723
+ /** ISO 8601 timestamp of identity creation. */
1724
+ created_at: z2.string().datetime(),
1725
+ /** Optional guarantor info if linked to a human. */
1726
+ guarantor: z2.object({
1727
+ github_login: z2.string().min(1),
1728
+ verified_at: z2.string().datetime()
1729
+ }).optional()
1730
+ });
1731
+ var AgentCertificateSchema = z2.object({
1732
+ identity: AgentIdentitySchema,
1733
+ /** ISO 8601 timestamp of certificate issuance. */
1734
+ issued_at: z2.string().datetime(),
1735
+ /** ISO 8601 timestamp of certificate expiry. */
1736
+ expires_at: z2.string().datetime(),
1737
+ /** Hex-encoded public key of the issuer (same as identity for self-signed). */
1738
+ issuer_public_key: z2.string().min(1),
1739
+ /** Base64url Ed25519 signature over { identity, issued_at, expires_at, issuer_public_key }. */
1740
+ signature: z2.string().min(1)
1741
+ });
1742
+ var IDENTITY_FILENAME = "identity.json";
1743
+ var PRIVATE_KEY_FILENAME = "private.key";
1744
+ var PUBLIC_KEY_FILENAME = "public.key";
1745
+ function derivePublicKeyFromPrivate(privateKey) {
1746
+ const privateKeyObject = createPrivateKey({ key: privateKey, format: "der", type: "pkcs8" });
1747
+ const publicKeyObject = createPublicKey(privateKeyObject);
1748
+ const publicKey = publicKeyObject.export({ format: "der", type: "spki" });
1749
+ return Buffer.from(publicKey);
1750
+ }
1751
+ function buildIdentityFromPublicKey(publicKey, owner, createdAt) {
1752
+ const publicKeyHex = publicKey.toString("hex");
1753
+ return {
1754
+ agent_id: deriveAgentId(publicKeyHex),
1755
+ owner,
1756
+ public_key: publicKeyHex,
1757
+ created_at: createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
1758
+ };
1759
+ }
1760
+ function generateFreshIdentity(configDir, owner) {
1761
+ const keys = generateKeyPair();
1762
+ saveKeyPair(configDir, keys);
1763
+ const identity = buildIdentityFromPublicKey(keys.publicKey, owner);
1764
+ saveIdentity(configDir, identity);
1765
+ return { identity, keys, status: "generated" };
1766
+ }
1767
+ function deriveAgentId(publicKeyHex) {
1768
+ return createHash("sha256").update(publicKeyHex, "hex").digest("hex").slice(0, 16);
1769
+ }
1770
+ function loadIdentity(configDir) {
1771
+ const filePath = join2(configDir, IDENTITY_FILENAME);
1772
+ if (!existsSync3(filePath)) return null;
1773
+ try {
1774
+ const raw = readFileSync3(filePath, "utf-8");
1775
+ return AgentIdentitySchema.parse(JSON.parse(raw));
1776
+ } catch {
1777
+ return null;
1778
+ }
1779
+ }
1780
+ function saveIdentity(configDir, identity) {
1781
+ if (!existsSync3(configDir)) {
1782
+ mkdirSync2(configDir, { recursive: true });
1783
+ }
1784
+ const filePath = join2(configDir, IDENTITY_FILENAME);
1785
+ writeFileSync2(filePath, JSON.stringify(identity, null, 2), "utf-8");
1786
+ }
1787
+ function loadOrRepairIdentity(configDir, ownerHint) {
1788
+ if (!existsSync3(configDir)) {
1789
+ mkdirSync2(configDir, { recursive: true });
1790
+ }
1791
+ const identityPath = join2(configDir, IDENTITY_FILENAME);
1792
+ const privateKeyPath = join2(configDir, PRIVATE_KEY_FILENAME);
1793
+ const publicKeyPath = join2(configDir, PUBLIC_KEY_FILENAME);
1794
+ const hasIdentity = existsSync3(identityPath);
1795
+ const hasPrivateKey = existsSync3(privateKeyPath);
1796
+ const hasPublicKey = existsSync3(publicKeyPath);
1797
+ if (!hasIdentity || !hasPrivateKey || !hasPublicKey) {
1798
+ return generateFreshIdentity(configDir, ownerHint ?? "agent");
1799
+ }
1800
+ let keys;
1801
+ try {
1802
+ keys = loadKeyPair(configDir);
1803
+ } catch {
1804
+ return generateFreshIdentity(configDir, ownerHint ?? "agent");
1805
+ }
1806
+ let derivedPublicKey;
1807
+ try {
1808
+ derivedPublicKey = derivePublicKeyFromPrivate(keys.privateKey);
1809
+ } catch {
1810
+ return generateFreshIdentity(configDir, ownerHint ?? "agent");
1811
+ }
1812
+ let keypairRepaired = false;
1813
+ if (!keys.publicKey.equals(derivedPublicKey)) {
1814
+ keypairRepaired = true;
1815
+ keys = { privateKey: keys.privateKey, publicKey: derivedPublicKey };
1816
+ saveKeyPair(configDir, keys);
1817
+ }
1818
+ const loadedIdentity = loadIdentity(configDir);
1819
+ const expectedAgentId = deriveAgentId(derivedPublicKey.toString("hex"));
1820
+ const expectedPublicKeyHex = derivedPublicKey.toString("hex");
1821
+ const identityMismatch = !loadedIdentity || loadedIdentity.public_key !== expectedPublicKeyHex || loadedIdentity.agent_id !== expectedAgentId;
1822
+ if (identityMismatch) {
1823
+ const repairedIdentity = buildIdentityFromPublicKey(
1824
+ derivedPublicKey,
1825
+ loadedIdentity?.owner ?? ownerHint ?? "agent",
1826
+ loadedIdentity?.created_at
1827
+ );
1828
+ saveIdentity(configDir, repairedIdentity);
1829
+ return { identity: repairedIdentity, keys, status: "repaired" };
1830
+ }
1831
+ if (ownerHint && loadedIdentity.owner !== ownerHint) {
1832
+ const updatedIdentity = { ...loadedIdentity, owner: ownerHint };
1833
+ saveIdentity(configDir, updatedIdentity);
1834
+ return { identity: updatedIdentity, keys, status: "repaired" };
1835
+ }
1836
+ return { identity: loadedIdentity, keys, status: keypairRepaired ? "repaired" : "existing" };
1837
+ }
1838
+ function ensureIdentity(configDir, owner) {
1839
+ return loadOrRepairIdentity(configDir, owner).identity;
1840
+ }
1841
+
1658
1842
  // src/registry/identity-auth.ts
1659
1843
  var MAX_REQUEST_AGE_MS = 5 * 60 * 1e3;
1660
- async function verifyIdentity(request, reply) {
1661
- const publicKeyHex = request.headers["x-agent-publickey"];
1662
- const signature = request.headers["x-agent-signature"];
1663
- const timestamp = request.headers["x-agent-timestamp"];
1664
- if (!publicKeyHex || !signature || !timestamp) {
1844
+ function normalizeSignedParams(body) {
1845
+ return body === void 0 ? null : body;
1846
+ }
1847
+ function buildIdentityPayload(method, path, timestamp, publicKeyHex, agentId, params) {
1848
+ return {
1849
+ method,
1850
+ path,
1851
+ timestamp,
1852
+ publicKey: publicKeyHex,
1853
+ agentId,
1854
+ params: normalizeSignedParams(params)
1855
+ };
1856
+ }
1857
+ function extractClaimedRequester(request) {
1858
+ const extractFromObject = (obj) => {
1859
+ const directOwner = typeof obj.owner === "string" ? obj.owner.trim() : "";
1860
+ if (directOwner) return directOwner;
1861
+ const directRequester = typeof obj.requester === "string" ? obj.requester.trim() : "";
1862
+ if (directRequester) return directRequester;
1863
+ const oldOwner = typeof obj.oldOwner === "string" ? obj.oldOwner.trim() : "";
1864
+ if (oldOwner) return oldOwner;
1865
+ const nestedParams = obj.params;
1866
+ if (nestedParams && typeof nestedParams === "object" && !Array.isArray(nestedParams)) {
1867
+ const nested = nestedParams;
1868
+ const nestedOwner = typeof nested.owner === "string" ? nested.owner.trim() : "";
1869
+ if (nestedOwner) return nestedOwner;
1870
+ const nestedRequester = typeof nested.requester === "string" ? nested.requester.trim() : "";
1871
+ if (nestedRequester) return nestedRequester;
1872
+ }
1873
+ return null;
1874
+ };
1875
+ if (request.body && typeof request.body === "object" && !Array.isArray(request.body)) {
1876
+ const claimed = extractFromObject(request.body);
1877
+ if (claimed) return claimed;
1878
+ }
1879
+ if (request.params && typeof request.params === "object" && !Array.isArray(request.params)) {
1880
+ const claimed = extractFromObject(request.params);
1881
+ if (claimed) return claimed;
1882
+ }
1883
+ return null;
1884
+ }
1885
+ async function verifyIdentity(request, reply, options) {
1886
+ const agentIdHeader = request.headers["x-agent-id"];
1887
+ const publicKeyHeader = request.headers["x-agent-publickey"];
1888
+ const signatureHeader = request.headers["x-agent-signature"];
1889
+ const timestampHeader = request.headers["x-agent-timestamp"];
1890
+ const agentId = agentIdHeader?.trim();
1891
+ const publicKeyHex = publicKeyHeader?.trim();
1892
+ const signature = signatureHeader?.trim();
1893
+ const timestamp = timestampHeader?.trim();
1894
+ if (!agentId || !publicKeyHex || !signature || !timestamp) {
1665
1895
  await reply.code(401).send({ error: "Missing identity headers" });
1666
1896
  return false;
1667
1897
  }
@@ -1670,12 +1900,21 @@ async function verifyIdentity(request, reply) {
1670
1900
  await reply.code(401).send({ error: "Request expired" });
1671
1901
  return false;
1672
1902
  }
1673
- const payload = {
1674
- method: request.method,
1675
- path: request.url,
1676
- timestamp,
1677
- publicKey: publicKeyHex
1678
- };
1903
+ if (!/^[0-9a-fA-F]+$/.test(publicKeyHex) || publicKeyHex.length % 2 !== 0) {
1904
+ await reply.code(401).send({ error: "Invalid identity signature" });
1905
+ return false;
1906
+ }
1907
+ let expectedAgentId;
1908
+ try {
1909
+ expectedAgentId = deriveAgentId(publicKeyHex);
1910
+ } catch {
1911
+ await reply.code(401).send({ error: "Invalid identity signature" });
1912
+ return false;
1913
+ }
1914
+ if (agentId !== expectedAgentId) {
1915
+ await reply.code(401).send({ error: "Invalid identity signature" });
1916
+ return false;
1917
+ }
1679
1918
  let publicKeyBuffer;
1680
1919
  try {
1681
1920
  publicKeyBuffer = Buffer.from(publicKeyHex, "hex");
@@ -1683,30 +1922,52 @@ async function verifyIdentity(request, reply) {
1683
1922
  await reply.code(401).send({ error: "Invalid identity signature" });
1684
1923
  return false;
1685
1924
  }
1925
+ const knownAgent = options.agentDb ? lookupAgent(options.agentDb, agentId) : null;
1926
+ if (knownAgent && knownAgent.public_key.toLowerCase() !== publicKeyHex.toLowerCase()) {
1927
+ await reply.code(401).send({ error: "Invalid identity signature" });
1928
+ return false;
1929
+ }
1930
+ const payload = buildIdentityPayload(
1931
+ request.method,
1932
+ request.url,
1933
+ timestamp,
1934
+ publicKeyHex,
1935
+ agentId,
1936
+ request.body
1937
+ );
1686
1938
  const valid = verifyEscrowReceipt(payload, signature, publicKeyBuffer);
1687
1939
  if (!valid) {
1688
1940
  await reply.code(401).send({ error: "Invalid identity signature" });
1689
1941
  return false;
1690
1942
  }
1943
+ const claimedRequester = extractClaimedRequester(request);
1944
+ if (claimedRequester) {
1945
+ const matchesAgentId = claimedRequester === agentId;
1946
+ const matchesLegacyOwner = knownAgent?.legacy_owner === claimedRequester;
1947
+ if (!matchesAgentId && !matchesLegacyOwner) {
1948
+ await reply.code(401).send({ error: "Identity does not match requester" });
1949
+ return false;
1950
+ }
1951
+ }
1691
1952
  request.agentPublicKey = publicKeyHex;
1953
+ request.agentId = agentId;
1692
1954
  return true;
1693
1955
  }
1694
- function identityAuthPlugin(fastify) {
1695
- fastify.addHook("onRequest", async (request, reply) => {
1696
- await verifyIdentity(request, reply);
1956
+ function identityAuthPlugin(fastify, options = {}) {
1957
+ fastify.addHook("preHandler", async (request, reply) => {
1958
+ const ok = await verifyIdentity(request, reply, options);
1959
+ if (!ok) {
1960
+ return reply;
1961
+ }
1697
1962
  });
1698
1963
  }
1699
- function signRequest(method, path, body, privateKey, publicKeyHex) {
1964
+ function signRequest(method, path, body, privateKey, publicKeyHex, agentIdOverride) {
1700
1965
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
1701
- const payload = {
1702
- method,
1703
- path,
1704
- timestamp,
1705
- publicKey: publicKeyHex
1706
- };
1707
- void body;
1966
+ const agentId = agentIdOverride ?? deriveAgentId(publicKeyHex);
1967
+ const payload = buildIdentityPayload(method, path, timestamp, publicKeyHex, agentId, body);
1708
1968
  const signature = signEscrowReceipt(payload, privateKey);
1709
1969
  return {
1970
+ "X-Agent-Id": agentId,
1710
1971
  "X-Agent-PublicKey": publicKeyHex,
1711
1972
  "X-Agent-Signature": signature,
1712
1973
  "X-Agent-Timestamp": timestamp
@@ -2290,92 +2551,6 @@ function getJobsByRelayOwner(db, relayOwner) {
2290
2551
  ).all(relayOwner, "queued");
2291
2552
  }
2292
2553
 
2293
- // src/identity/identity.ts
2294
- import { z as z2 } from "zod";
2295
- import { createHash } from "crypto";
2296
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync2 } from "fs";
2297
- import { join as join2 } from "path";
2298
- var AgentIdentitySchema = z2.object({
2299
- /** Deterministic ID derived from public key: sha256(hex).slice(0, 16). */
2300
- agent_id: z2.string().min(1),
2301
- /** Human-readable owner name (from config or init). */
2302
- owner: z2.string().min(1),
2303
- /** Hex-encoded Ed25519 public key. */
2304
- public_key: z2.string().min(1),
2305
- /** ISO 8601 timestamp of identity creation. */
2306
- created_at: z2.string().datetime(),
2307
- /** Optional guarantor info if linked to a human. */
2308
- guarantor: z2.object({
2309
- github_login: z2.string().min(1),
2310
- verified_at: z2.string().datetime()
2311
- }).optional()
2312
- });
2313
- var AgentCertificateSchema = z2.object({
2314
- identity: AgentIdentitySchema,
2315
- /** ISO 8601 timestamp of certificate issuance. */
2316
- issued_at: z2.string().datetime(),
2317
- /** ISO 8601 timestamp of certificate expiry. */
2318
- expires_at: z2.string().datetime(),
2319
- /** Hex-encoded public key of the issuer (same as identity for self-signed). */
2320
- issuer_public_key: z2.string().min(1),
2321
- /** Base64url Ed25519 signature over { identity, issued_at, expires_at, issuer_public_key }. */
2322
- signature: z2.string().min(1)
2323
- });
2324
- var IDENTITY_FILENAME = "identity.json";
2325
- function deriveAgentId(publicKeyHex) {
2326
- return createHash("sha256").update(publicKeyHex, "hex").digest("hex").slice(0, 16);
2327
- }
2328
- function createIdentity(configDir, owner) {
2329
- if (!existsSync3(configDir)) {
2330
- mkdirSync2(configDir, { recursive: true });
2331
- }
2332
- let keys;
2333
- try {
2334
- keys = loadKeyPair(configDir);
2335
- } catch {
2336
- keys = generateKeyPair();
2337
- saveKeyPair(configDir, keys);
2338
- }
2339
- const publicKeyHex = keys.publicKey.toString("hex");
2340
- const agentId = deriveAgentId(publicKeyHex);
2341
- const identity = {
2342
- agent_id: agentId,
2343
- owner,
2344
- public_key: publicKeyHex,
2345
- created_at: (/* @__PURE__ */ new Date()).toISOString()
2346
- };
2347
- saveIdentity(configDir, identity);
2348
- return identity;
2349
- }
2350
- function loadIdentity(configDir) {
2351
- const filePath = join2(configDir, IDENTITY_FILENAME);
2352
- if (!existsSync3(filePath)) return null;
2353
- try {
2354
- const raw = readFileSync3(filePath, "utf-8");
2355
- return AgentIdentitySchema.parse(JSON.parse(raw));
2356
- } catch {
2357
- return null;
2358
- }
2359
- }
2360
- function saveIdentity(configDir, identity) {
2361
- if (!existsSync3(configDir)) {
2362
- mkdirSync2(configDir, { recursive: true });
2363
- }
2364
- const filePath = join2(configDir, IDENTITY_FILENAME);
2365
- writeFileSync2(filePath, JSON.stringify(identity, null, 2), "utf-8");
2366
- }
2367
- function ensureIdentity(configDir, owner) {
2368
- const existing = loadIdentity(configDir);
2369
- if (existing) {
2370
- if (existing.owner !== owner) {
2371
- existing.owner = owner;
2372
- saveIdentity(configDir, existing);
2373
- }
2374
- return existing;
2375
- }
2376
- return createIdentity(configDir, owner);
2377
- }
2378
-
2379
2554
  // src/hub-agent/crypto.ts
2380
2555
  import { createCipheriv, createDecipheriv, randomBytes } from "crypto";
2381
2556
  function getMasterKey() {
@@ -3313,7 +3488,7 @@ async function creditRoutesPlugin(fastify, options) {
3313
3488
  }
3314
3489
  initFreeTierTable(creditDb);
3315
3490
  await fastify.register(async (scope) => {
3316
- identityAuthPlugin(scope);
3491
+ identityAuthPlugin(scope, { agentDb: creditDb });
3317
3492
  scope.post("/api/credits/hold", {
3318
3493
  schema: {
3319
3494
  tags: ["credits"],
@@ -4473,7 +4648,7 @@ function createRegistryServer(opts) {
4473
4648
  type: "apiKey",
4474
4649
  in: "header",
4475
4650
  name: "X-Agent-PublicKey",
4476
- description: "Ed25519 public key (hex). Also requires X-Agent-Signature and X-Agent-Timestamp headers."
4651
+ description: "Ed25519 public key (hex). Also requires X-Agent-Id, X-Agent-Signature, and X-Agent-Timestamp headers."
4477
4652
  }
4478
4653
  }
4479
4654
  }
@@ -4486,7 +4661,7 @@ function createRegistryServer(opts) {
4486
4661
  void server.register(cors, {
4487
4662
  origin: true,
4488
4663
  methods: ["GET", "POST", "PATCH", "DELETE", "OPTIONS"],
4489
- allowedHeaders: ["Content-Type", "Authorization", "X-Agent-PublicKey", "X-Agent-Signature", "X-Agent-Timestamp"]
4664
+ allowedHeaders: ["Content-Type", "Authorization", "X-Agent-Id", "X-Agent-PublicKey", "X-Agent-Signature", "X-Agent-Timestamp"]
4490
4665
  });
4491
4666
  void server.register(fastifyWebsocket);
4492
4667
  let relayState = null;
@@ -5363,15 +5538,60 @@ function createRegistryServer(opts) {
5363
5538
  });
5364
5539
  }
5365
5540
  const { requests, strategy, total_budget } = parseResult.data;
5366
- const batchResult = await executeCapabilityBatch({
5367
- requests,
5368
- strategy,
5369
- total_budget,
5370
- registryDb: db,
5371
- creditDb: opts.creditDb,
5372
- owner
5373
- });
5374
- return reply.send(batchResult);
5541
+ const host = request.headers.host ?? request.hostname;
5542
+ const relayRegistryUrl = `${request.protocol}://${host}`;
5543
+ const relayRequesterOwner = `${owner}:batch:${Date.now()}`;
5544
+ let relayClient;
5545
+ try {
5546
+ const batchResult = await executeCapabilityBatch({
5547
+ requests,
5548
+ strategy,
5549
+ total_budget,
5550
+ registryDb: db,
5551
+ creditDb: opts.creditDb,
5552
+ owner,
5553
+ registryUrl: relayRegistryUrl,
5554
+ dispatchRequest: async ({ target, params, requester }) => {
5555
+ if (!target.via_relay) {
5556
+ return { card_id: target.cardId, skill_id: target.skillId };
5557
+ }
5558
+ if (!relayClient) {
5559
+ const { RelayClient: RelayClient2 } = await import("../../websocket-client-4Z5P54RU.js");
5560
+ relayClient = new RelayClient2({
5561
+ registryUrl: relayRegistryUrl,
5562
+ owner: relayRequesterOwner,
5563
+ token: "batch-token",
5564
+ card: {
5565
+ spec_version: "1.0",
5566
+ id: randomUUID7(),
5567
+ owner: relayRequesterOwner,
5568
+ name: relayRequesterOwner,
5569
+ description: "Batch requester",
5570
+ level: 1,
5571
+ inputs: [],
5572
+ outputs: [],
5573
+ pricing: { credits_per_call: 1 },
5574
+ availability: { online: false }
5575
+ },
5576
+ onRequest: async () => ({ error: { code: -32601, message: "Batch requester does not serve capabilities" } }),
5577
+ silent: true
5578
+ });
5579
+ await relayClient.connect();
5580
+ }
5581
+ const { requestViaRelay: requestViaRelay2 } = await import("../../client-XOLP5IUZ.js");
5582
+ return requestViaRelay2(relayClient, {
5583
+ targetOwner: target.owner,
5584
+ cardId: target.cardId,
5585
+ skillId: target.skillId,
5586
+ params: { ...params, requester },
5587
+ requester
5588
+ });
5589
+ }
5590
+ });
5591
+ return reply.send(batchResult);
5592
+ } finally {
5593
+ relayClient?.disconnect();
5594
+ }
5375
5595
  });
5376
5596
  if (opts.ownerApiKey && opts.ownerName) {
5377
5597
  const ownerApiKey = opts.ownerApiKey;
@@ -5826,13 +6046,134 @@ async function stopAnnouncement() {
5826
6046
  });
5827
6047
  }
5828
6048
 
6049
+ // src/runtime/resolve-self-cli.ts
6050
+ import { execFileSync as execFileSync2 } from "child_process";
6051
+ import { existsSync as existsSync5, realpathSync } from "fs";
6052
+ import { createRequire } from "module";
6053
+ import { homedir as homedir2 } from "os";
6054
+ import { basename, isAbsolute, join as join4, resolve } from "path";
6055
+ function resolveSelfCli() {
6056
+ const require2 = createRequire(import.meta.url);
6057
+ return resolveSelfCliWithDeps({
6058
+ argv1: process.argv[1],
6059
+ cwd: process.cwd(),
6060
+ platform: process.platform,
6061
+ homeDir: homedir2(),
6062
+ envPath: process.env["PATH"],
6063
+ exists: existsSync5,
6064
+ realpath: realpathSync,
6065
+ runWhich: (pathEnv) => execFileSync2("which", ["agentbnb"], {
6066
+ encoding: "utf8",
6067
+ env: { ...process.env, PATH: pathEnv }
6068
+ }).trim(),
6069
+ requireResolve: (id) => require2.resolve(id)
6070
+ });
6071
+ }
6072
+ function resolveSelfCliWithDeps(deps) {
6073
+ const tried = [];
6074
+ const tryCandidate = (rawPath, label, requireCliShape = false) => {
6075
+ if (!rawPath || rawPath.trim().length === 0) {
6076
+ tried.push(`${label}: <empty>`);
6077
+ return null;
6078
+ }
6079
+ const maybeAbsolute = isAbsolute(rawPath) ? rawPath : resolve(deps.cwd, rawPath);
6080
+ tried.push(`${label}: ${maybeAbsolute}`);
6081
+ if (!deps.exists(maybeAbsolute)) return null;
6082
+ const resolvedPath = safeRealpath(deps.realpath, maybeAbsolute);
6083
+ if (requireCliShape && !looksLikeAgentbnbCli(resolvedPath)) return null;
6084
+ return resolvedPath;
6085
+ };
6086
+ const argvPath = tryCandidate(deps.argv1, "process.argv[1]", true);
6087
+ if (argvPath) return argvPath;
6088
+ const fullPathEnv = buildFullPathEnv(deps.envPath, deps.homeDir);
6089
+ tried.push(`which agentbnb PATH=${fullPathEnv}`);
6090
+ try {
6091
+ const whichPath = tryCandidate(deps.runWhich(fullPathEnv), "which agentbnb");
6092
+ if (whichPath) return whichPath;
6093
+ } catch (err) {
6094
+ tried.push(`which agentbnb failed: ${extractErrorMessage(err)}`);
6095
+ }
6096
+ const npmGlobalCandidates = ["/usr/local/bin/agentbnb", "/opt/homebrew/bin/agentbnb"];
6097
+ for (const candidate of npmGlobalCandidates) {
6098
+ const resolvedPath = tryCandidate(candidate, "npm-global");
6099
+ if (resolvedPath) return resolvedPath;
6100
+ }
6101
+ const pnpmCandidates = getPnpmGlobalCandidates(deps.platform, deps.homeDir);
6102
+ for (const candidate of pnpmCandidates) {
6103
+ const resolvedPath = tryCandidate(candidate, "pnpm-global");
6104
+ if (resolvedPath) return resolvedPath;
6105
+ }
6106
+ try {
6107
+ const requireResolved = deps.requireResolve("agentbnb/dist/cli/index.js");
6108
+ const resolvedPath = tryCandidate(requireResolved, "require.resolve(agentbnb/dist/cli/index.js)");
6109
+ if (resolvedPath) return resolvedPath;
6110
+ } catch (err) {
6111
+ tried.push(`require.resolve(agentbnb/dist/cli/index.js) failed: ${extractErrorMessage(err)}`);
6112
+ }
6113
+ throw new AgentBnBError(
6114
+ `Unable to resolve absolute path to agentbnb CLI.
6115
+ Paths tried:
6116
+ ${tried.map((item) => `- ${item}`).join("\n")}`,
6117
+ "CLI_ENTRY_NOT_FOUND"
6118
+ );
6119
+ }
6120
+ function buildFullPathEnv(pathEnv, homeDir) {
6121
+ const values = /* @__PURE__ */ new Set();
6122
+ for (const item of (pathEnv ?? "").split(":")) {
6123
+ if (item.trim()) values.add(item.trim());
6124
+ }
6125
+ for (const extra of [
6126
+ "/usr/local/bin",
6127
+ "/opt/homebrew/bin",
6128
+ "/usr/bin",
6129
+ "/bin",
6130
+ "/usr/sbin",
6131
+ "/sbin",
6132
+ join4(homeDir, ".local", "bin"),
6133
+ join4(homeDir, "Library", "pnpm"),
6134
+ join4(homeDir, ".local", "share", "pnpm")
6135
+ ]) {
6136
+ values.add(extra);
6137
+ }
6138
+ return [...values].join(":");
6139
+ }
6140
+ function safeRealpath(realpath, path) {
6141
+ try {
6142
+ return realpath(path);
6143
+ } catch {
6144
+ return path;
6145
+ }
6146
+ }
6147
+ function getPnpmGlobalCandidates(platform, homeDir) {
6148
+ const candidates = /* @__PURE__ */ new Set();
6149
+ if (platform === "darwin") {
6150
+ candidates.add(join4(homeDir, "Library", "pnpm", "agentbnb"));
6151
+ }
6152
+ if (platform === "linux") {
6153
+ candidates.add(join4(homeDir, ".local", "share", "pnpm", "agentbnb"));
6154
+ }
6155
+ candidates.add(join4(homeDir, "Library", "pnpm", "agentbnb"));
6156
+ candidates.add(join4(homeDir, ".local", "share", "pnpm", "agentbnb"));
6157
+ return [...candidates];
6158
+ }
6159
+ function looksLikeAgentbnbCli(path) {
6160
+ const normalized = path.replace(/\\/g, "/").toLowerCase();
6161
+ const fileName = basename(normalized);
6162
+ if (fileName === "agentbnb" || fileName === "agentbnb.cmd" || fileName === "agentbnb.exe") {
6163
+ return true;
6164
+ }
6165
+ return normalized.includes("/agentbnb/dist/cli/index.") || normalized.endsWith("/dist/cli/index.js") || normalized.endsWith("/dist/cli/index.mjs") || normalized.endsWith("/dist/cli/index.cjs");
6166
+ }
6167
+ function extractErrorMessage(err) {
6168
+ if (err instanceof Error && err.message) return err.message;
6169
+ return String(err);
6170
+ }
6171
+
5829
6172
  // src/runtime/service-coordinator.ts
5830
6173
  import { spawn as spawn2 } from "child_process";
5831
- import { createRequire } from "module";
5832
- import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
5833
- import { fileURLToPath as fileURLToPath2 } from "url";
5834
- import { dirname as dirname3, join as join4, resolve } from "path";
5835
- import { randomUUID as randomUUID7 } from "crypto";
6174
+ import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
6175
+ import { join as join5 } from "path";
6176
+ import { randomUUID as randomUUID8 } from "crypto";
5836
6177
  var ServiceCoordinator = class {
5837
6178
  config;
5838
6179
  guard;
@@ -5952,7 +6293,7 @@ var ServiceCoordinator = class {
5952
6293
  return {
5953
6294
  port: opts?.port ?? this.config.gateway_port,
5954
6295
  handlerUrl: opts?.handlerUrl ?? "http://localhost:8080",
5955
- skillsYamlPath: opts?.skillsYamlPath ?? join4(getConfigDir(), "skills.yaml"),
6296
+ skillsYamlPath: opts?.skillsYamlPath ?? join5(getConfigDir(), "skills.yaml"),
5956
6297
  registryPort: opts?.registryPort ?? 7701,
5957
6298
  registryUrl: opts?.registryUrl ?? this.config.registry ?? "",
5958
6299
  relay: opts?.relay ?? true,
@@ -6035,10 +6376,10 @@ var ServiceCoordinator = class {
6035
6376
  }
6036
6377
  if (opts.registryUrl && opts.relay) {
6037
6378
  const { RelayClient: RelayClient2 } = await import("../../websocket-client-4Z5P54RU.js");
6038
- const { executeCapabilityRequest: executeCapabilityRequest2 } = await import("../../execute-EPE6MZLT.js");
6379
+ const { executeCapabilityRequest: executeCapabilityRequest2 } = await import("../../execute-NNDCXTN4.js");
6039
6380
  const cards = listCards(this.runtime.registryDb, this.config.owner);
6040
6381
  const card = cards[0] ?? {
6041
- id: randomUUID7(),
6382
+ id: randomUUID8(),
6042
6383
  owner: this.config.owner,
6043
6384
  name: this.config.owner,
6044
6385
  description: "Agent registered via CLI",
@@ -6142,7 +6483,8 @@ var ServiceCoordinator = class {
6142
6483
  spawnManagedProcess(opts) {
6143
6484
  const runtime = loadPersistedRuntime(getConfigDir());
6144
6485
  const nodeExec = resolveNodeExecutable(runtime);
6145
- const cliArgs = resolveCliLaunchArgs(this.buildServeArgs(opts));
6486
+ const cliPath = resolveSelfCli();
6487
+ const cliArgs = [cliPath, "serve", ...this.buildServeArgs(opts)];
6146
6488
  const child = spawn2(nodeExec, cliArgs, {
6147
6489
  detached: true,
6148
6490
  stdio: "ignore",
@@ -6303,8 +6645,8 @@ var ServiceCoordinator = class {
6303
6645
  };
6304
6646
  };
6305
6647
  function loadPersistedRuntime(configDir) {
6306
- const runtimePath = join4(configDir, "runtime.json");
6307
- if (!existsSync5(runtimePath)) return null;
6648
+ const runtimePath = join5(configDir, "runtime.json");
6649
+ if (!existsSync6(runtimePath)) return null;
6308
6650
  try {
6309
6651
  const raw = readFileSync4(runtimePath, "utf8");
6310
6652
  const parsed = JSON.parse(raw);
@@ -6328,28 +6670,6 @@ function resolveNodeExecutable(runtime) {
6328
6670
  }
6329
6671
  return process.execPath;
6330
6672
  }
6331
- function resolveCliLaunchArgs(serveArgs) {
6332
- const require2 = createRequire(import.meta.url);
6333
- try {
6334
- const distCli2 = require2.resolve("agentbnb/dist/cli/index.js");
6335
- return [distCli2, "serve", ...serveArgs];
6336
- } catch {
6337
- }
6338
- const projectRoot = resolve(dirname3(fileURLToPath2(import.meta.url)), "..", "..");
6339
- const distCli = join4(projectRoot, "dist", "cli", "index.js");
6340
- if (existsSync5(distCli)) {
6341
- return [distCli, "serve", ...serveArgs];
6342
- }
6343
- const srcCli = join4(projectRoot, "src", "cli", "index.ts");
6344
- if (existsSync5(srcCli)) {
6345
- const tsxCli = require2.resolve("tsx/dist/cli.mjs");
6346
- return [tsxCli, srcCli, "serve", ...serveArgs];
6347
- }
6348
- throw new AgentBnBError(
6349
- "Unable to locate AgentBnB CLI entry (dist/cli/index.js or src/cli/index.ts)",
6350
- "CLI_ENTRY_NOT_FOUND"
6351
- );
6352
- }
6353
6673
  function isPidAlive(pid) {
6354
6674
  if (!Number.isInteger(pid) || pid <= 0) return false;
6355
6675
  try {
@@ -6365,11 +6685,11 @@ function sleep2(ms) {
6365
6685
  }
6366
6686
 
6367
6687
  // src/app/agentbnb-service.ts
6368
- import { randomUUID as randomUUID9 } from "crypto";
6688
+ import { randomUUID as randomUUID10 } from "crypto";
6369
6689
 
6370
6690
  // src/credit/escrow-receipt.ts
6371
6691
  import { z as z8 } from "zod";
6372
- import { randomUUID as randomUUID8 } from "crypto";
6692
+ import { randomUUID as randomUUID9 } from "crypto";
6373
6693
  var EscrowReceiptSchema = z8.object({
6374
6694
  requester_owner: z8.string().min(1),
6375
6695
  requester_agent_id: z8.string().optional(),
@@ -6391,7 +6711,7 @@ function createSignedEscrowReceipt(db, privateKey, publicKey, opts) {
6391
6711
  card_id: opts.cardId,
6392
6712
  ...opts.skillId ? { skill_id: opts.skillId } : {},
6393
6713
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
6394
- nonce: randomUUID8()
6714
+ nonce: randomUUID9()
6395
6715
  };
6396
6716
  const signature = signEscrowReceipt(receiptData, privateKey);
6397
6717
  const receipt = {
@@ -6458,7 +6778,7 @@ var AgentBnBService = class {
6458
6778
  const creditDb = openCreditDb(this.config.credit_db_path);
6459
6779
  creditDb.pragma("busy_timeout = 5000");
6460
6780
  try {
6461
- const keys = this.getOrCreateKeyPair();
6781
+ const { keys } = loadOrRepairIdentity(getConfigDir(), this.config.owner);
6462
6782
  const { escrowId, receipt } = createSignedEscrowReceipt(
6463
6783
  creditDb,
6464
6784
  keys.privateKey,
@@ -6633,13 +6953,13 @@ var AgentBnBService = class {
6633
6953
  if (!this.config.registry) {
6634
6954
  throw new AgentBnBError("Registry is required for relay fallback.", "RELAY_NOT_AVAILABLE");
6635
6955
  }
6636
- const requesterId = `${this.config.owner}:req:${randomUUID9()}`;
6956
+ const requesterId = `${this.config.owner}:req:${randomUUID10()}`;
6637
6957
  const tempRelay = new RelayClient({
6638
6958
  registryUrl: this.config.registry,
6639
6959
  owner: requesterId,
6640
6960
  token: this.config.token,
6641
6961
  card: {
6642
- id: randomUUID9(),
6962
+ id: randomUUID10(),
6643
6963
  owner: requesterId,
6644
6964
  name: requesterId,
6645
6965
  description: "Requester",
@@ -6667,20 +6987,9 @@ var AgentBnBService = class {
6667
6987
  tempRelay.disconnect();
6668
6988
  }
6669
6989
  }
6670
- getOrCreateKeyPair() {
6671
- const configDir = getConfigDir();
6672
- try {
6673
- return loadKeyPair(configDir);
6674
- } catch {
6675
- const keys = generateKeyPair();
6676
- saveKeyPair(configDir, keys);
6677
- return keys;
6678
- }
6679
- }
6680
6990
  loadIdentityAuth() {
6681
6991
  const configDir = getConfigDir();
6682
- const identity = ensureIdentity(configDir, this.config.owner);
6683
- const keys = this.getOrCreateKeyPair();
6992
+ const { identity, keys } = loadOrRepairIdentity(configDir, this.config.owner);
6684
6993
  return {
6685
6994
  agentId: identity.agent_id,
6686
6995
  publicKey: identity.public_key,
@@ -6748,9 +7057,9 @@ function isNetworkError(err) {
6748
7057
  }
6749
7058
 
6750
7059
  // skills/agentbnb/openclaw-tools.ts
6751
- import { readFileSync as readFileSync5, existsSync as existsSync6 } from "fs";
6752
- import { join as join5 } from "path";
6753
- import { homedir as homedir2 } from "os";
7060
+ import { readFileSync as readFileSync5, existsSync as existsSync7 } from "fs";
7061
+ import { join as join6 } from "path";
7062
+ import { homedir as homedir3 } from "os";
6754
7063
 
6755
7064
  // src/mcp/tools/discover.ts
6756
7065
  import { z as z9 } from "zod";
@@ -6870,12 +7179,23 @@ async function handleRequest(args, ctx) {
6870
7179
  } finally {
6871
7180
  db.close();
6872
7181
  }
7182
+ let identityAuth;
7183
+ try {
7184
+ const keys = loadKeyPair(ctx.configDir);
7185
+ identityAuth = {
7186
+ agentId: ctx.identity.agent_id,
7187
+ publicKey: ctx.identity.public_key,
7188
+ privateKey: keys.privateKey
7189
+ };
7190
+ } catch {
7191
+ }
6873
7192
  if (localCard && localCard.owner === ctx.config.owner) {
6874
7193
  const result = await requestCapability({
6875
7194
  gatewayUrl: ctx.config.gateway_url,
6876
7195
  token: ctx.config.token,
6877
7196
  cardId,
6878
- params: { ...args.params ?? {}, ...args.skill_id ? { skill_id: args.skill_id } : {}, requester: ctx.config.owner }
7197
+ params: { ...args.params ?? {}, ...args.skill_id ? { skill_id: args.skill_id } : {}, requester: ctx.config.owner },
7198
+ identity: identityAuth
6879
7199
  });
6880
7200
  return {
6881
7201
  content: [{ type: "text", text: JSON.stringify({ success: true, result }, null, 2) }]
@@ -6905,28 +7225,16 @@ async function handleRequest(args, ctx) {
6905
7225
  const targetOwner = remoteCard["owner"] ?? remoteCard["agent_name"];
6906
7226
  const gatewayUrl = remoteCard["gateway_url"];
6907
7227
  if (gatewayUrl) {
6908
- const keys = loadKeyPair(ctx.configDir);
6909
- const ledger = createLedger({
6910
- registryUrl: ctx.config.registry,
6911
- ownerPublicKey: ctx.identity.public_key,
6912
- privateKey: keys.privateKey
7228
+ const result = await requestCapability({
7229
+ gatewayUrl,
7230
+ token: "",
7231
+ cardId,
7232
+ params: { ...args.params ?? {}, ...args.skill_id ? { skill_id: args.skill_id } : {}, requester: ctx.config.owner },
7233
+ identity: identityAuth
6913
7234
  });
6914
- const { escrowId } = await ledger.hold(ctx.config.owner, maxCost, cardId);
6915
- try {
6916
- const result = await requestCapability({
6917
- gatewayUrl,
6918
- token: "",
6919
- cardId,
6920
- params: { ...args.params ?? {}, ...args.skill_id ? { skill_id: args.skill_id } : {}, requester: ctx.config.owner }
6921
- });
6922
- await ledger.settle(escrowId, targetOwner ?? "unknown");
6923
- return {
6924
- content: [{ type: "text", text: JSON.stringify({ success: true, result, credits_spent: maxCost }, null, 2) }]
6925
- };
6926
- } catch (err) {
6927
- await ledger.release(escrowId);
6928
- throw err;
6929
- }
7235
+ return {
7236
+ content: [{ type: "text", text: JSON.stringify({ success: true, result }, null, 2) }]
7237
+ };
6930
7238
  }
6931
7239
  if (targetOwner) {
6932
7240
  const relay = new RelayClient({
@@ -7257,19 +7565,19 @@ async function handlePublish(args, ctx) {
7257
7565
  var contextCache = /* @__PURE__ */ new Map();
7258
7566
  function resolveConfigDir(toolCtx) {
7259
7567
  if (toolCtx.agentDir) {
7260
- return toolCtx.agentDir.endsWith(".agentbnb") ? toolCtx.agentDir : join5(toolCtx.agentDir, ".agentbnb");
7568
+ return toolCtx.agentDir.endsWith(".agentbnb") ? toolCtx.agentDir : join6(toolCtx.agentDir, ".agentbnb");
7261
7569
  }
7262
7570
  if (toolCtx.workspaceDir) {
7263
- return join5(toolCtx.workspaceDir, ".agentbnb");
7571
+ return join6(toolCtx.workspaceDir, ".agentbnb");
7264
7572
  }
7265
- return join5(homedir2(), ".agentbnb");
7573
+ return join6(homedir3(), ".agentbnb");
7266
7574
  }
7267
7575
  function buildMcpContext(toolCtx) {
7268
7576
  const configDir = resolveConfigDir(toolCtx);
7269
7577
  const cached = contextCache.get(configDir);
7270
7578
  if (cached) return cached;
7271
- const configPath = join5(configDir, "config.json");
7272
- if (!existsSync6(configPath)) {
7579
+ const configPath = join6(configDir, "config.json");
7580
+ if (!existsSync7(configPath)) {
7273
7581
  throw new Error(
7274
7582
  `AgentBnB not initialized at ${configDir}. Run \`agentbnb init\` or activate the plugin first.`
7275
7583
  );
@@ -7434,23 +7742,23 @@ function resolveWorkspaceDir() {
7434
7742
  if (process.env["AGENTBNB_DIR"]) {
7435
7743
  return process.env["AGENTBNB_DIR"];
7436
7744
  }
7437
- const openclawAgentsDir = join6(homedir3(), ".openclaw", "agents");
7745
+ const openclawAgentsDir = join7(homedir4(), ".openclaw", "agents");
7438
7746
  const cwd = process.cwd();
7439
7747
  if (cwd.startsWith(openclawAgentsDir + "/")) {
7440
7748
  const relative = cwd.slice(openclawAgentsDir.length + 1);
7441
7749
  const agentName = relative.split("/")[0];
7442
- return join6(openclawAgentsDir, agentName, ".agentbnb");
7750
+ return join7(openclawAgentsDir, agentName, ".agentbnb");
7443
7751
  }
7444
- return join6(homedir3(), ".agentbnb");
7752
+ return join7(homedir4(), ".agentbnb");
7445
7753
  }
7446
7754
  function registerDecomposerCard(configDir, owner) {
7447
7755
  try {
7448
- const db = openDatabase(join6(configDir, "registry.db"));
7756
+ const db = openDatabase(join7(configDir, "registry.db"));
7449
7757
  const existing = db.prepare(
7450
7758
  "SELECT id FROM capability_cards WHERE owner = ? AND json_extract(data, '$.capability_type') = ?"
7451
7759
  ).get(owner, "task_decomposition");
7452
7760
  if (existing) return;
7453
- const cardId = randomUUID10();
7761
+ const cardId = randomUUID11();
7454
7762
  const now = (/* @__PURE__ */ new Date()).toISOString();
7455
7763
  const card = {
7456
7764
  spec_version: "2.0",
@@ -7503,37 +7811,40 @@ function registerDecomposerCard(configDir, owner) {
7503
7811
  }
7504
7812
  }
7505
7813
  function findCli() {
7506
- const result = spawnSync("which", ["agentbnb"], { encoding: "utf-8", stdio: "pipe" });
7507
- if (result.status === 0 && result.stdout.trim()) {
7508
- return result.stdout.trim();
7814
+ try {
7815
+ return resolveSelfCli();
7816
+ } catch {
7817
+ return null;
7509
7818
  }
7510
- return null;
7511
7819
  }
7512
7820
  async function runCommand(cmd, env) {
7513
7821
  return execAsync(cmd, { env });
7514
7822
  }
7515
7823
  function deriveAgentName(configDir) {
7516
- const parent = basename(dirname4(configDir));
7517
- if (parent && parent !== "." && parent !== ".agentbnb" && parent !== homedir3().split("/").pop()) {
7824
+ const parent = basename2(dirname3(configDir));
7825
+ if (parent && parent !== "." && parent !== ".agentbnb" && parent !== homedir4().split("/").pop()) {
7518
7826
  return parent;
7519
7827
  }
7520
- return `agent-${randomUUID10().slice(0, 8)}`;
7828
+ return `agent-${randomUUID11().slice(0, 8)}`;
7521
7829
  }
7522
- var defaultDeps = { findCli, runCommand };
7830
+ var defaultDeps = { resolveSelfCli, runCommand };
7523
7831
  async function autoOnboard(configDir, deps = defaultDeps) {
7524
7832
  process.stderr.write("[agentbnb] First-time setup: initializing agent identity...\n");
7525
- const cliPath = deps.findCli();
7526
- if (!cliPath) {
7833
+ let cliPath;
7834
+ try {
7835
+ cliPath = deps.resolveSelfCli();
7836
+ } catch {
7527
7837
  process.stderr.write("[agentbnb] CLI not found. Run: npm install -g agentbnb\n");
7528
7838
  throw new AgentBnBError(
7529
7839
  "agentbnb CLI not found in PATH. Install with: npm install -g agentbnb",
7530
7840
  "INIT_FAILED"
7531
7841
  );
7532
7842
  }
7843
+ const quotedCliPath = quoteShellArg(cliPath);
7533
7844
  const env = { ...process.env, AGENTBNB_DIR: configDir };
7534
7845
  const agentName = deriveAgentName(configDir);
7535
7846
  try {
7536
- await deps.runCommand(`agentbnb init --owner "${agentName}" --yes --no-detect`, env);
7847
+ await deps.runCommand(`${quotedCliPath} init --owner "${agentName}" --yes --no-detect`, env);
7537
7848
  process.stderr.write(`[agentbnb] Agent "${agentName}" initialized.
7538
7849
  `);
7539
7850
  } catch (err) {
@@ -7541,7 +7852,7 @@ async function autoOnboard(configDir, deps = defaultDeps) {
7541
7852
  throw new AgentBnBError(`Auto-init failed: ${msg}`, "INIT_FAILED");
7542
7853
  }
7543
7854
  try {
7544
- await deps.runCommand("agentbnb openclaw sync", env);
7855
+ await deps.runCommand(`${quotedCliPath} openclaw sync`, env);
7545
7856
  process.stderr.write("[agentbnb] Capabilities published from SOUL.md.\n");
7546
7857
  } catch {
7547
7858
  process.stderr.write("[agentbnb] Note: openclaw sync skipped (SOUL.md may not exist yet).\n");
@@ -7553,6 +7864,9 @@ async function autoOnboard(configDir, deps = defaultDeps) {
7553
7864
  process.stderr.write("[agentbnb] Agent initialized and published to AgentBnB network.\n");
7554
7865
  return config;
7555
7866
  }
7867
+ function quoteShellArg(input) {
7868
+ return `'${input.replace(/'/g, `'\\''`)}'`;
7869
+ }
7556
7870
  async function activate(config = {}, _onboardDeps) {
7557
7871
  if (config.agentDir) {
7558
7872
  process.env["AGENTBNB_DIR"] = config.agentDir;
@@ -7561,7 +7875,7 @@ async function activate(config = {}, _onboardDeps) {
7561
7875
  `
7562
7876
  );
7563
7877
  } else if (config.workspaceDir) {
7564
- const derived = join6(config.workspaceDir, ".agentbnb");
7878
+ const derived = join7(config.workspaceDir, ".agentbnb");
7565
7879
  process.env["AGENTBNB_DIR"] = derived;
7566
7880
  process.stderr.write(
7567
7881
  `[agentbnb] AGENTBNB_DIR derived from config.workspaceDir: ${derived}
@@ -7590,7 +7904,7 @@ async function activate(config = {}, _onboardDeps) {
7590
7904
  `[agentbnb] activate: owner=${agentConfig.owner} config=${configDir}/config.json
7591
7905
  `
7592
7906
  );
7593
- const guard = new ProcessGuard(join6(configDir, ".pid"));
7907
+ const guard = new ProcessGuard(join7(configDir, ".pid"));
7594
7908
  const coordinator = new ServiceCoordinator(agentConfig, guard);
7595
7909
  const service = new AgentBnBService(coordinator, agentConfig);
7596
7910
  const opts = {