agentbnb 8.2.0 → 8.2.1

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 (38) hide show
  1. package/dist/{chunk-TBJ3FZKZ.js → chunk-7Q2XUXSA.js} +1 -1
  2. package/dist/{chunk-LJM7FHPM.js → chunk-BZOJ7HBT.js} +33 -1
  3. package/dist/{chunk-FTZTEHYG.js → chunk-DEWY7OQK.js} +135 -8
  4. package/dist/{chunk-CUONY5TO.js → chunk-EJKW57ZV.js} +19 -1
  5. package/dist/chunk-EZVOG7QS.js +161 -0
  6. package/dist/{chunk-E2OKP5CY.js → chunk-GJETGML6.js} +181 -83
  7. package/dist/{chunk-YHY7OG6S.js → chunk-GWMMYVLL.js} +4 -4
  8. package/dist/{chunk-D6RKW2XG.js → chunk-JLNHMNES.js} +16 -3
  9. package/dist/{chunk-5AAFG2V2.js → chunk-KBQNTUTN.js} +239 -24
  10. package/dist/{chunk-C537SFHV.js → chunk-LOUEJI6X.js} +4 -4
  11. package/dist/{chunk-ALX4WS3A.js → chunk-NP55V7RQ.js} +1 -1
  12. package/dist/{chunk-X32NE6V4.js → chunk-RBXTWWUH.js} +1 -1
  13. package/dist/{chunk-O2OYBAVR.js → chunk-SRBVKO2V.js} +9 -0
  14. package/dist/{chunk-7EF3HYVZ.js → chunk-STJLWMXH.js} +48 -4
  15. package/dist/{chunk-5GME4KJZ.js → chunk-UYCD3JBZ.js} +3 -3
  16. package/dist/{chunk-P4LOYSLA.js → chunk-WKWJWKX7.js} +286 -81
  17. package/dist/cli/index.js +35 -57
  18. package/dist/{client-HKV3QWZ3.js → client-66TFS7RS.js} +4 -2
  19. package/dist/{conduct-W6XF6DJW.js → conduct-A6COHLHY.js} +8 -8
  20. package/dist/{conduct-YB64OHI6.js → conduct-IUVAXUAV.js} +8 -8
  21. package/dist/{conductor-mode-TFCVCQHU.js → conductor-mode-D5TFQW5L.js} +2 -2
  22. package/dist/{conductor-mode-AKREGDIU.js → conductor-mode-L2MB44BW.js} +7 -7
  23. package/dist/{execute-AYQWORVH.js → execute-5AWLARB5.js} +5 -5
  24. package/dist/{execute-EPE6MZLT.js → execute-WOS457HW.js} +2 -2
  25. package/dist/index.js +438 -92
  26. package/dist/{publish-capability-AH2HDW54.js → publish-capability-JJCBBMSX.js} +2 -2
  27. package/dist/{request-HCCXSKAY.js → request-6YQLA7K3.js} +13 -8
  28. package/dist/{serve-skill-SZAQT5T5.js → serve-skill-X7TZSILV.js} +5 -5
  29. package/dist/{server-LMY2A3GT.js → server-5TSP4DBX.js} +10 -12
  30. package/dist/{service-coordinator-WGH6B2VT.js → service-coordinator-WTUSMPY6.js} +69 -46
  31. package/dist/skills/agentbnb/bootstrap.js +459 -189
  32. package/package.json +13 -17
  33. package/skills/agentbnb/bootstrap.test.ts +8 -6
  34. package/skills/agentbnb/bootstrap.ts +21 -13
  35. package/skills/agentbnb/install.sh +0 -0
  36. package/dist/chunk-64AK4FJM.js +0 -84
  37. package/dist/chunk-OH7BP5NP.js +0 -96
  38. package/dist/index.d.ts +0 -5069
@@ -21,7 +21,7 @@ import {
21
21
  requestViaRelay,
22
22
  resolvePendingRequest,
23
23
  searchCards
24
- } from "../../chunk-P4LOYSLA.js";
24
+ } from "../../chunk-WKWJWKX7.js";
25
25
  import {
26
26
  loadPeers
27
27
  } from "../../chunk-HLUEOLSZ.js";
@@ -30,7 +30,7 @@ import {
30
30
  executeCapabilityRequest,
31
31
  releaseRequesterEscrow,
32
32
  settleRequesterEscrow
33
- } from "../../chunk-ALX4WS3A.js";
33
+ } from "../../chunk-NP55V7RQ.js";
34
34
  import {
35
35
  bootstrapAgent,
36
36
  generateKeyPair,
@@ -52,6 +52,7 @@ import {
52
52
  insertRequestLog,
53
53
  listCards,
54
54
  loadKeyPair,
55
+ lookupAgent,
55
56
  migrateOwner,
56
57
  openCreditDb,
57
58
  openDatabase,
@@ -63,7 +64,7 @@ import {
63
64
  updateSkillAvailability,
64
65
  updateSkillIdleRate,
65
66
  verifyEscrowReceipt
66
- } from "../../chunk-7EF3HYVZ.js";
67
+ } from "../../chunk-STJLWMXH.js";
67
68
  import "../../chunk-NWIQJ2CL.js";
68
69
  import {
69
70
  getConfigDir,
@@ -79,9 +80,9 @@ import {
79
80
  } from "../../chunk-3LWBH7P3.js";
80
81
 
81
82
  // 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";
83
+ import { join as join7, basename as basename2, dirname as dirname3 } from "path";
84
+ import { homedir as homedir4 } from "os";
85
+ import { exec } from "child_process";
85
86
  import { promisify as promisify2 } from "util";
86
87
  import { randomUUID as randomUUID10 } from "crypto";
87
88
 
@@ -1271,7 +1272,7 @@ var AgentRuntime = class {
1271
1272
  }
1272
1273
  const modes = /* @__PURE__ */ new Map();
1273
1274
  if (this.conductorEnabled) {
1274
- const { ConductorMode } = await import("../../conductor-mode-TFCVCQHU.js");
1275
+ const { ConductorMode } = await import("../../conductor-mode-D5TFQW5L.js");
1275
1276
  const { registerConductorCard, CONDUCTOR_OWNER } = await import("../../card-EX2EYGCZ.js");
1276
1277
  const { loadPeers: loadPeers2 } = await import("../../peers-CJ7T4RJO.js");
1277
1278
  registerConductorCard(this.registryDb);
@@ -1435,7 +1436,54 @@ function createGatewayServer(opts) {
1435
1436
  return { status: "ok", version: VERSION, uptime: process.uptime() };
1436
1437
  });
1437
1438
  fastify.post("/rpc", async (request, reply) => {
1438
- const body = request.body;
1439
+ const rawBody = request.body;
1440
+ if (Array.isArray(rawBody)) {
1441
+ const responses = await Promise.all(
1442
+ rawBody.map(async (single) => {
1443
+ if (single.jsonrpc !== "2.0" || !single.method) {
1444
+ return { jsonrpc: "2.0", id: single.id ?? null, error: { code: -32600, message: "Invalid Request" } };
1445
+ }
1446
+ if (single.method !== "capability.execute") {
1447
+ return { jsonrpc: "2.0", id: single.id ?? null, error: { code: -32601, message: "Method not found" } };
1448
+ }
1449
+ const params2 = single.params ?? {};
1450
+ const cardId2 = params2.card_id;
1451
+ if (!cardId2) {
1452
+ return { jsonrpc: "2.0", id: single.id ?? null, error: { code: -32602, message: "Invalid params: card_id required" } };
1453
+ }
1454
+ const requester2 = params2.requester ?? "unknown";
1455
+ const receipt2 = params2.escrow_receipt;
1456
+ const batchSkillId = params2.skill_id;
1457
+ const trackKey2 = batchSkillId ?? cardId2;
1458
+ inFlight.set(trackKey2, (inFlight.get(trackKey2) ?? 0) + 1);
1459
+ try {
1460
+ const result2 = await executeCapabilityRequest({
1461
+ registryDb,
1462
+ creditDb,
1463
+ cardId: cardId2,
1464
+ skillId: batchSkillId,
1465
+ params: params2,
1466
+ requester: requester2,
1467
+ escrowReceipt: receipt2,
1468
+ skillExecutor,
1469
+ handlerUrl,
1470
+ timeoutMs
1471
+ });
1472
+ if (result2.success) {
1473
+ return { jsonrpc: "2.0", id: single.id ?? null, result: result2.result };
1474
+ } else {
1475
+ return { jsonrpc: "2.0", id: single.id ?? null, error: result2.error };
1476
+ }
1477
+ } finally {
1478
+ const next = (inFlight.get(trackKey2) ?? 1) - 1;
1479
+ if (next <= 0) inFlight.delete(trackKey2);
1480
+ else inFlight.set(trackKey2, next);
1481
+ }
1482
+ })
1483
+ );
1484
+ return reply.send(responses);
1485
+ }
1486
+ const body = rawBody;
1439
1487
  if (body.jsonrpc !== "2.0" || !body.method) {
1440
1488
  return reply.status(400).send({
1441
1489
  jsonrpc: "2.0",
@@ -1655,13 +1703,190 @@ var LocalCreditLedger = class {
1655
1703
  }
1656
1704
  };
1657
1705
 
1706
+ // src/identity/identity.ts
1707
+ import { z as z2 } from "zod";
1708
+ import { createHash, createPrivateKey, createPublicKey } from "crypto";
1709
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync2 } from "fs";
1710
+ import { join as join2 } from "path";
1711
+ var AgentIdentitySchema = z2.object({
1712
+ /** Deterministic ID derived from public key: sha256(hex).slice(0, 16). */
1713
+ agent_id: z2.string().min(1),
1714
+ /** Human-readable owner name (from config or init). */
1715
+ owner: z2.string().min(1),
1716
+ /** Hex-encoded Ed25519 public key. */
1717
+ public_key: z2.string().min(1),
1718
+ /** ISO 8601 timestamp of identity creation. */
1719
+ created_at: z2.string().datetime(),
1720
+ /** Optional guarantor info if linked to a human. */
1721
+ guarantor: z2.object({
1722
+ github_login: z2.string().min(1),
1723
+ verified_at: z2.string().datetime()
1724
+ }).optional()
1725
+ });
1726
+ var AgentCertificateSchema = z2.object({
1727
+ identity: AgentIdentitySchema,
1728
+ /** ISO 8601 timestamp of certificate issuance. */
1729
+ issued_at: z2.string().datetime(),
1730
+ /** ISO 8601 timestamp of certificate expiry. */
1731
+ expires_at: z2.string().datetime(),
1732
+ /** Hex-encoded public key of the issuer (same as identity for self-signed). */
1733
+ issuer_public_key: z2.string().min(1),
1734
+ /** Base64url Ed25519 signature over { identity, issued_at, expires_at, issuer_public_key }. */
1735
+ signature: z2.string().min(1)
1736
+ });
1737
+ var IDENTITY_FILENAME = "identity.json";
1738
+ var PRIVATE_KEY_FILENAME = "private.key";
1739
+ var PUBLIC_KEY_FILENAME = "public.key";
1740
+ function derivePublicKeyFromPrivate(privateKey) {
1741
+ const privateKeyObject = createPrivateKey({ key: privateKey, format: "der", type: "pkcs8" });
1742
+ const publicKeyObject = createPublicKey(privateKeyObject);
1743
+ const publicKey = publicKeyObject.export({ format: "der", type: "spki" });
1744
+ return Buffer.from(publicKey);
1745
+ }
1746
+ function buildIdentityFromPublicKey(publicKey, owner, createdAt) {
1747
+ const publicKeyHex = publicKey.toString("hex");
1748
+ return {
1749
+ agent_id: deriveAgentId(publicKeyHex),
1750
+ owner,
1751
+ public_key: publicKeyHex,
1752
+ created_at: createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
1753
+ };
1754
+ }
1755
+ function generateFreshIdentity(configDir, owner) {
1756
+ const keys = generateKeyPair();
1757
+ saveKeyPair(configDir, keys);
1758
+ const identity = buildIdentityFromPublicKey(keys.publicKey, owner);
1759
+ saveIdentity(configDir, identity);
1760
+ return { identity, keys, status: "generated" };
1761
+ }
1762
+ function deriveAgentId(publicKeyHex) {
1763
+ return createHash("sha256").update(publicKeyHex, "hex").digest("hex").slice(0, 16);
1764
+ }
1765
+ function loadIdentity(configDir) {
1766
+ const filePath = join2(configDir, IDENTITY_FILENAME);
1767
+ if (!existsSync3(filePath)) return null;
1768
+ try {
1769
+ const raw = readFileSync3(filePath, "utf-8");
1770
+ return AgentIdentitySchema.parse(JSON.parse(raw));
1771
+ } catch {
1772
+ return null;
1773
+ }
1774
+ }
1775
+ function saveIdentity(configDir, identity) {
1776
+ if (!existsSync3(configDir)) {
1777
+ mkdirSync2(configDir, { recursive: true });
1778
+ }
1779
+ const filePath = join2(configDir, IDENTITY_FILENAME);
1780
+ writeFileSync2(filePath, JSON.stringify(identity, null, 2), "utf-8");
1781
+ }
1782
+ function loadOrRepairIdentity(configDir, ownerHint) {
1783
+ if (!existsSync3(configDir)) {
1784
+ mkdirSync2(configDir, { recursive: true });
1785
+ }
1786
+ const identityPath = join2(configDir, IDENTITY_FILENAME);
1787
+ const privateKeyPath = join2(configDir, PRIVATE_KEY_FILENAME);
1788
+ const publicKeyPath = join2(configDir, PUBLIC_KEY_FILENAME);
1789
+ const hasIdentity = existsSync3(identityPath);
1790
+ const hasPrivateKey = existsSync3(privateKeyPath);
1791
+ const hasPublicKey = existsSync3(publicKeyPath);
1792
+ if (!hasIdentity || !hasPrivateKey || !hasPublicKey) {
1793
+ return generateFreshIdentity(configDir, ownerHint ?? "agent");
1794
+ }
1795
+ let keys;
1796
+ try {
1797
+ keys = loadKeyPair(configDir);
1798
+ } catch {
1799
+ return generateFreshIdentity(configDir, ownerHint ?? "agent");
1800
+ }
1801
+ let derivedPublicKey;
1802
+ try {
1803
+ derivedPublicKey = derivePublicKeyFromPrivate(keys.privateKey);
1804
+ } catch {
1805
+ return generateFreshIdentity(configDir, ownerHint ?? "agent");
1806
+ }
1807
+ let keypairRepaired = false;
1808
+ if (!keys.publicKey.equals(derivedPublicKey)) {
1809
+ keypairRepaired = true;
1810
+ keys = { privateKey: keys.privateKey, publicKey: derivedPublicKey };
1811
+ saveKeyPair(configDir, keys);
1812
+ }
1813
+ const loadedIdentity = loadIdentity(configDir);
1814
+ const expectedAgentId = deriveAgentId(derivedPublicKey.toString("hex"));
1815
+ const expectedPublicKeyHex = derivedPublicKey.toString("hex");
1816
+ const identityMismatch = !loadedIdentity || loadedIdentity.public_key !== expectedPublicKeyHex || loadedIdentity.agent_id !== expectedAgentId;
1817
+ if (identityMismatch) {
1818
+ const repairedIdentity = buildIdentityFromPublicKey(
1819
+ derivedPublicKey,
1820
+ loadedIdentity?.owner ?? ownerHint ?? "agent",
1821
+ loadedIdentity?.created_at
1822
+ );
1823
+ saveIdentity(configDir, repairedIdentity);
1824
+ return { identity: repairedIdentity, keys, status: "repaired" };
1825
+ }
1826
+ if (ownerHint && loadedIdentity.owner !== ownerHint) {
1827
+ const updatedIdentity = { ...loadedIdentity, owner: ownerHint };
1828
+ saveIdentity(configDir, updatedIdentity);
1829
+ return { identity: updatedIdentity, keys, status: "repaired" };
1830
+ }
1831
+ return { identity: loadedIdentity, keys, status: keypairRepaired ? "repaired" : "existing" };
1832
+ }
1833
+ function ensureIdentity(configDir, owner) {
1834
+ return loadOrRepairIdentity(configDir, owner).identity;
1835
+ }
1836
+
1658
1837
  // src/registry/identity-auth.ts
1659
1838
  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) {
1839
+ function normalizeSignedParams(body) {
1840
+ return body === void 0 ? null : body;
1841
+ }
1842
+ function buildIdentityPayload(method, path, timestamp, publicKeyHex, agentId, params) {
1843
+ return {
1844
+ method,
1845
+ path,
1846
+ timestamp,
1847
+ publicKey: publicKeyHex,
1848
+ agentId,
1849
+ params: normalizeSignedParams(params)
1850
+ };
1851
+ }
1852
+ function extractClaimedRequester(request) {
1853
+ const extractFromObject = (obj) => {
1854
+ const directOwner = typeof obj.owner === "string" ? obj.owner.trim() : "";
1855
+ if (directOwner) return directOwner;
1856
+ const directRequester = typeof obj.requester === "string" ? obj.requester.trim() : "";
1857
+ if (directRequester) return directRequester;
1858
+ const oldOwner = typeof obj.oldOwner === "string" ? obj.oldOwner.trim() : "";
1859
+ if (oldOwner) return oldOwner;
1860
+ const nestedParams = obj.params;
1861
+ if (nestedParams && typeof nestedParams === "object" && !Array.isArray(nestedParams)) {
1862
+ const nested = nestedParams;
1863
+ const nestedOwner = typeof nested.owner === "string" ? nested.owner.trim() : "";
1864
+ if (nestedOwner) return nestedOwner;
1865
+ const nestedRequester = typeof nested.requester === "string" ? nested.requester.trim() : "";
1866
+ if (nestedRequester) return nestedRequester;
1867
+ }
1868
+ return null;
1869
+ };
1870
+ if (request.body && typeof request.body === "object" && !Array.isArray(request.body)) {
1871
+ const claimed = extractFromObject(request.body);
1872
+ if (claimed) return claimed;
1873
+ }
1874
+ if (request.params && typeof request.params === "object" && !Array.isArray(request.params)) {
1875
+ const claimed = extractFromObject(request.params);
1876
+ if (claimed) return claimed;
1877
+ }
1878
+ return null;
1879
+ }
1880
+ async function verifyIdentity(request, reply, options) {
1881
+ const agentIdHeader = request.headers["x-agent-id"];
1882
+ const publicKeyHeader = request.headers["x-agent-publickey"];
1883
+ const signatureHeader = request.headers["x-agent-signature"];
1884
+ const timestampHeader = request.headers["x-agent-timestamp"];
1885
+ const agentId = agentIdHeader?.trim();
1886
+ const publicKeyHex = publicKeyHeader?.trim();
1887
+ const signature = signatureHeader?.trim();
1888
+ const timestamp = timestampHeader?.trim();
1889
+ if (!agentId || !publicKeyHex || !signature || !timestamp) {
1665
1890
  await reply.code(401).send({ error: "Missing identity headers" });
1666
1891
  return false;
1667
1892
  }
@@ -1670,12 +1895,21 @@ async function verifyIdentity(request, reply) {
1670
1895
  await reply.code(401).send({ error: "Request expired" });
1671
1896
  return false;
1672
1897
  }
1673
- const payload = {
1674
- method: request.method,
1675
- path: request.url,
1676
- timestamp,
1677
- publicKey: publicKeyHex
1678
- };
1898
+ if (!/^[0-9a-fA-F]+$/.test(publicKeyHex) || publicKeyHex.length % 2 !== 0) {
1899
+ await reply.code(401).send({ error: "Invalid identity signature" });
1900
+ return false;
1901
+ }
1902
+ let expectedAgentId;
1903
+ try {
1904
+ expectedAgentId = deriveAgentId(publicKeyHex);
1905
+ } catch {
1906
+ await reply.code(401).send({ error: "Invalid identity signature" });
1907
+ return false;
1908
+ }
1909
+ if (agentId !== expectedAgentId) {
1910
+ await reply.code(401).send({ error: "Invalid identity signature" });
1911
+ return false;
1912
+ }
1679
1913
  let publicKeyBuffer;
1680
1914
  try {
1681
1915
  publicKeyBuffer = Buffer.from(publicKeyHex, "hex");
@@ -1683,30 +1917,52 @@ async function verifyIdentity(request, reply) {
1683
1917
  await reply.code(401).send({ error: "Invalid identity signature" });
1684
1918
  return false;
1685
1919
  }
1920
+ const knownAgent = options.agentDb ? lookupAgent(options.agentDb, agentId) : null;
1921
+ if (knownAgent && knownAgent.public_key.toLowerCase() !== publicKeyHex.toLowerCase()) {
1922
+ await reply.code(401).send({ error: "Invalid identity signature" });
1923
+ return false;
1924
+ }
1925
+ const payload = buildIdentityPayload(
1926
+ request.method,
1927
+ request.url,
1928
+ timestamp,
1929
+ publicKeyHex,
1930
+ agentId,
1931
+ request.body
1932
+ );
1686
1933
  const valid = verifyEscrowReceipt(payload, signature, publicKeyBuffer);
1687
1934
  if (!valid) {
1688
1935
  await reply.code(401).send({ error: "Invalid identity signature" });
1689
1936
  return false;
1690
1937
  }
1938
+ const claimedRequester = extractClaimedRequester(request);
1939
+ if (claimedRequester) {
1940
+ const matchesAgentId = claimedRequester === agentId;
1941
+ const matchesLegacyOwner = knownAgent?.legacy_owner === claimedRequester;
1942
+ if (!matchesAgentId && !matchesLegacyOwner) {
1943
+ await reply.code(401).send({ error: "Identity does not match requester" });
1944
+ return false;
1945
+ }
1946
+ }
1691
1947
  request.agentPublicKey = publicKeyHex;
1948
+ request.agentId = agentId;
1692
1949
  return true;
1693
1950
  }
1694
- function identityAuthPlugin(fastify) {
1695
- fastify.addHook("onRequest", async (request, reply) => {
1696
- await verifyIdentity(request, reply);
1951
+ function identityAuthPlugin(fastify, options = {}) {
1952
+ fastify.addHook("preHandler", async (request, reply) => {
1953
+ const ok = await verifyIdentity(request, reply, options);
1954
+ if (!ok) {
1955
+ return reply;
1956
+ }
1697
1957
  });
1698
1958
  }
1699
- function signRequest(method, path, body, privateKey, publicKeyHex) {
1959
+ function signRequest(method, path, body, privateKey, publicKeyHex, agentIdOverride) {
1700
1960
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
1701
- const payload = {
1702
- method,
1703
- path,
1704
- timestamp,
1705
- publicKey: publicKeyHex
1706
- };
1707
- void body;
1961
+ const agentId = agentIdOverride ?? deriveAgentId(publicKeyHex);
1962
+ const payload = buildIdentityPayload(method, path, timestamp, publicKeyHex, agentId, body);
1708
1963
  const signature = signEscrowReceipt(payload, privateKey);
1709
1964
  return {
1965
+ "X-Agent-Id": agentId,
1710
1966
  "X-Agent-PublicKey": publicKeyHex,
1711
1967
  "X-Agent-Signature": signature,
1712
1968
  "X-Agent-Timestamp": timestamp
@@ -2290,92 +2546,6 @@ function getJobsByRelayOwner(db, relayOwner) {
2290
2546
  ).all(relayOwner, "queued");
2291
2547
  }
2292
2548
 
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
2549
  // src/hub-agent/crypto.ts
2380
2550
  import { createCipheriv, createDecipheriv, randomBytes } from "crypto";
2381
2551
  function getMasterKey() {
@@ -3313,7 +3483,7 @@ async function creditRoutesPlugin(fastify, options) {
3313
3483
  }
3314
3484
  initFreeTierTable(creditDb);
3315
3485
  await fastify.register(async (scope) => {
3316
- identityAuthPlugin(scope);
3486
+ identityAuthPlugin(scope, { agentDb: creditDb });
3317
3487
  scope.post("/api/credits/hold", {
3318
3488
  schema: {
3319
3489
  tags: ["credits"],
@@ -4473,7 +4643,7 @@ function createRegistryServer(opts) {
4473
4643
  type: "apiKey",
4474
4644
  in: "header",
4475
4645
  name: "X-Agent-PublicKey",
4476
- description: "Ed25519 public key (hex). Also requires X-Agent-Signature and X-Agent-Timestamp headers."
4646
+ description: "Ed25519 public key (hex). Also requires X-Agent-Id, X-Agent-Signature, and X-Agent-Timestamp headers."
4477
4647
  }
4478
4648
  }
4479
4649
  }
@@ -4486,7 +4656,7 @@ function createRegistryServer(opts) {
4486
4656
  void server.register(cors, {
4487
4657
  origin: true,
4488
4658
  methods: ["GET", "POST", "PATCH", "DELETE", "OPTIONS"],
4489
- allowedHeaders: ["Content-Type", "Authorization", "X-Agent-PublicKey", "X-Agent-Signature", "X-Agent-Timestamp"]
4659
+ allowedHeaders: ["Content-Type", "Authorization", "X-Agent-Id", "X-Agent-PublicKey", "X-Agent-Signature", "X-Agent-Timestamp"]
4490
4660
  });
4491
4661
  void server.register(fastifyWebsocket);
4492
4662
  let relayState = null;
@@ -5826,12 +5996,133 @@ async function stopAnnouncement() {
5826
5996
  });
5827
5997
  }
5828
5998
 
5999
+ // src/runtime/resolve-self-cli.ts
6000
+ import { execFileSync as execFileSync2 } from "child_process";
6001
+ import { existsSync as existsSync5, realpathSync } from "fs";
6002
+ import { createRequire } from "module";
6003
+ import { homedir as homedir2 } from "os";
6004
+ import { basename, isAbsolute, join as join4, resolve } from "path";
6005
+ function resolveSelfCli() {
6006
+ const require2 = createRequire(import.meta.url);
6007
+ return resolveSelfCliWithDeps({
6008
+ argv1: process.argv[1],
6009
+ cwd: process.cwd(),
6010
+ platform: process.platform,
6011
+ homeDir: homedir2(),
6012
+ envPath: process.env["PATH"],
6013
+ exists: existsSync5,
6014
+ realpath: realpathSync,
6015
+ runWhich: (pathEnv) => execFileSync2("which", ["agentbnb"], {
6016
+ encoding: "utf8",
6017
+ env: { ...process.env, PATH: pathEnv }
6018
+ }).trim(),
6019
+ requireResolve: (id) => require2.resolve(id)
6020
+ });
6021
+ }
6022
+ function resolveSelfCliWithDeps(deps) {
6023
+ const tried = [];
6024
+ const tryCandidate = (rawPath, label, requireCliShape = false) => {
6025
+ if (!rawPath || rawPath.trim().length === 0) {
6026
+ tried.push(`${label}: <empty>`);
6027
+ return null;
6028
+ }
6029
+ const maybeAbsolute = isAbsolute(rawPath) ? rawPath : resolve(deps.cwd, rawPath);
6030
+ tried.push(`${label}: ${maybeAbsolute}`);
6031
+ if (!deps.exists(maybeAbsolute)) return null;
6032
+ const resolvedPath = safeRealpath(deps.realpath, maybeAbsolute);
6033
+ if (requireCliShape && !looksLikeAgentbnbCli(resolvedPath)) return null;
6034
+ return resolvedPath;
6035
+ };
6036
+ const argvPath = tryCandidate(deps.argv1, "process.argv[1]", true);
6037
+ if (argvPath) return argvPath;
6038
+ const fullPathEnv = buildFullPathEnv(deps.envPath, deps.homeDir);
6039
+ tried.push(`which agentbnb PATH=${fullPathEnv}`);
6040
+ try {
6041
+ const whichPath = tryCandidate(deps.runWhich(fullPathEnv), "which agentbnb");
6042
+ if (whichPath) return whichPath;
6043
+ } catch (err) {
6044
+ tried.push(`which agentbnb failed: ${extractErrorMessage(err)}`);
6045
+ }
6046
+ const npmGlobalCandidates = ["/usr/local/bin/agentbnb", "/opt/homebrew/bin/agentbnb"];
6047
+ for (const candidate of npmGlobalCandidates) {
6048
+ const resolvedPath = tryCandidate(candidate, "npm-global");
6049
+ if (resolvedPath) return resolvedPath;
6050
+ }
6051
+ const pnpmCandidates = getPnpmGlobalCandidates(deps.platform, deps.homeDir);
6052
+ for (const candidate of pnpmCandidates) {
6053
+ const resolvedPath = tryCandidate(candidate, "pnpm-global");
6054
+ if (resolvedPath) return resolvedPath;
6055
+ }
6056
+ try {
6057
+ const requireResolved = deps.requireResolve("agentbnb/dist/cli/index.js");
6058
+ const resolvedPath = tryCandidate(requireResolved, "require.resolve(agentbnb/dist/cli/index.js)");
6059
+ if (resolvedPath) return resolvedPath;
6060
+ } catch (err) {
6061
+ tried.push(`require.resolve(agentbnb/dist/cli/index.js) failed: ${extractErrorMessage(err)}`);
6062
+ }
6063
+ throw new AgentBnBError(
6064
+ `Unable to resolve absolute path to agentbnb CLI.
6065
+ Paths tried:
6066
+ ${tried.map((item) => `- ${item}`).join("\n")}`,
6067
+ "CLI_ENTRY_NOT_FOUND"
6068
+ );
6069
+ }
6070
+ function buildFullPathEnv(pathEnv, homeDir) {
6071
+ const values = /* @__PURE__ */ new Set();
6072
+ for (const item of (pathEnv ?? "").split(":")) {
6073
+ if (item.trim()) values.add(item.trim());
6074
+ }
6075
+ for (const extra of [
6076
+ "/usr/local/bin",
6077
+ "/opt/homebrew/bin",
6078
+ "/usr/bin",
6079
+ "/bin",
6080
+ "/usr/sbin",
6081
+ "/sbin",
6082
+ join4(homeDir, ".local", "bin"),
6083
+ join4(homeDir, "Library", "pnpm"),
6084
+ join4(homeDir, ".local", "share", "pnpm")
6085
+ ]) {
6086
+ values.add(extra);
6087
+ }
6088
+ return [...values].join(":");
6089
+ }
6090
+ function safeRealpath(realpath, path) {
6091
+ try {
6092
+ return realpath(path);
6093
+ } catch {
6094
+ return path;
6095
+ }
6096
+ }
6097
+ function getPnpmGlobalCandidates(platform, homeDir) {
6098
+ const candidates = /* @__PURE__ */ new Set();
6099
+ if (platform === "darwin") {
6100
+ candidates.add(join4(homeDir, "Library", "pnpm", "agentbnb"));
6101
+ }
6102
+ if (platform === "linux") {
6103
+ candidates.add(join4(homeDir, ".local", "share", "pnpm", "agentbnb"));
6104
+ }
6105
+ candidates.add(join4(homeDir, "Library", "pnpm", "agentbnb"));
6106
+ candidates.add(join4(homeDir, ".local", "share", "pnpm", "agentbnb"));
6107
+ return [...candidates];
6108
+ }
6109
+ function looksLikeAgentbnbCli(path) {
6110
+ const normalized = path.replace(/\\/g, "/").toLowerCase();
6111
+ const fileName = basename(normalized);
6112
+ if (fileName === "agentbnb" || fileName === "agentbnb.cmd" || fileName === "agentbnb.exe") {
6113
+ return true;
6114
+ }
6115
+ 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");
6116
+ }
6117
+ function extractErrorMessage(err) {
6118
+ if (err instanceof Error && err.message) return err.message;
6119
+ return String(err);
6120
+ }
6121
+
5829
6122
  // src/runtime/service-coordinator.ts
5830
6123
  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";
6124
+ import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
6125
+ import { join as join5 } from "path";
5835
6126
  import { randomUUID as randomUUID7 } from "crypto";
5836
6127
  var ServiceCoordinator = class {
5837
6128
  config;
@@ -5952,7 +6243,7 @@ var ServiceCoordinator = class {
5952
6243
  return {
5953
6244
  port: opts?.port ?? this.config.gateway_port,
5954
6245
  handlerUrl: opts?.handlerUrl ?? "http://localhost:8080",
5955
- skillsYamlPath: opts?.skillsYamlPath ?? join4(getConfigDir(), "skills.yaml"),
6246
+ skillsYamlPath: opts?.skillsYamlPath ?? join5(getConfigDir(), "skills.yaml"),
5956
6247
  registryPort: opts?.registryPort ?? 7701,
5957
6248
  registryUrl: opts?.registryUrl ?? this.config.registry ?? "",
5958
6249
  relay: opts?.relay ?? true,
@@ -6035,7 +6326,7 @@ var ServiceCoordinator = class {
6035
6326
  }
6036
6327
  if (opts.registryUrl && opts.relay) {
6037
6328
  const { RelayClient: RelayClient2 } = await import("../../websocket-client-4Z5P54RU.js");
6038
- const { executeCapabilityRequest: executeCapabilityRequest2 } = await import("../../execute-EPE6MZLT.js");
6329
+ const { executeCapabilityRequest: executeCapabilityRequest2 } = await import("../../execute-WOS457HW.js");
6039
6330
  const cards = listCards(this.runtime.registryDb, this.config.owner);
6040
6331
  const card = cards[0] ?? {
6041
6332
  id: randomUUID7(),
@@ -6142,7 +6433,8 @@ var ServiceCoordinator = class {
6142
6433
  spawnManagedProcess(opts) {
6143
6434
  const runtime = loadPersistedRuntime(getConfigDir());
6144
6435
  const nodeExec = resolveNodeExecutable(runtime);
6145
- const cliArgs = resolveCliLaunchArgs(this.buildServeArgs(opts));
6436
+ const cliPath = resolveSelfCli();
6437
+ const cliArgs = [cliPath, "serve", ...this.buildServeArgs(opts)];
6146
6438
  const child = spawn2(nodeExec, cliArgs, {
6147
6439
  detached: true,
6148
6440
  stdio: "ignore",
@@ -6303,8 +6595,8 @@ var ServiceCoordinator = class {
6303
6595
  };
6304
6596
  };
6305
6597
  function loadPersistedRuntime(configDir) {
6306
- const runtimePath = join4(configDir, "runtime.json");
6307
- if (!existsSync5(runtimePath)) return null;
6598
+ const runtimePath = join5(configDir, "runtime.json");
6599
+ if (!existsSync6(runtimePath)) return null;
6308
6600
  try {
6309
6601
  const raw = readFileSync4(runtimePath, "utf8");
6310
6602
  const parsed = JSON.parse(raw);
@@ -6328,28 +6620,6 @@ function resolveNodeExecutable(runtime) {
6328
6620
  }
6329
6621
  return process.execPath;
6330
6622
  }
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
6623
  function isPidAlive(pid) {
6354
6624
  if (!Number.isInteger(pid) || pid <= 0) return false;
6355
6625
  try {
@@ -6458,7 +6728,7 @@ var AgentBnBService = class {
6458
6728
  const creditDb = openCreditDb(this.config.credit_db_path);
6459
6729
  creditDb.pragma("busy_timeout = 5000");
6460
6730
  try {
6461
- const keys = this.getOrCreateKeyPair();
6731
+ const { keys } = loadOrRepairIdentity(getConfigDir(), this.config.owner);
6462
6732
  const { escrowId, receipt } = createSignedEscrowReceipt(
6463
6733
  creditDb,
6464
6734
  keys.privateKey,
@@ -6667,20 +6937,9 @@ var AgentBnBService = class {
6667
6937
  tempRelay.disconnect();
6668
6938
  }
6669
6939
  }
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
6940
  loadIdentityAuth() {
6681
6941
  const configDir = getConfigDir();
6682
- const identity = ensureIdentity(configDir, this.config.owner);
6683
- const keys = this.getOrCreateKeyPair();
6942
+ const { identity, keys } = loadOrRepairIdentity(configDir, this.config.owner);
6684
6943
  return {
6685
6944
  agentId: identity.agent_id,
6686
6945
  publicKey: identity.public_key,
@@ -6748,9 +7007,9 @@ function isNetworkError(err) {
6748
7007
  }
6749
7008
 
6750
7009
  // 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";
7010
+ import { readFileSync as readFileSync5, existsSync as existsSync7 } from "fs";
7011
+ import { join as join6 } from "path";
7012
+ import { homedir as homedir3 } from "os";
6754
7013
 
6755
7014
  // src/mcp/tools/discover.ts
6756
7015
  import { z as z9 } from "zod";
@@ -6917,7 +7176,12 @@ async function handleRequest(args, ctx) {
6917
7176
  gatewayUrl,
6918
7177
  token: "",
6919
7178
  cardId,
6920
- params: { ...args.params ?? {}, ...args.skill_id ? { skill_id: args.skill_id } : {}, requester: ctx.config.owner }
7179
+ params: { ...args.params ?? {}, ...args.skill_id ? { skill_id: args.skill_id } : {}, requester: ctx.config.owner },
7180
+ identity: {
7181
+ agentId: ctx.identity.agent_id,
7182
+ publicKey: ctx.identity.public_key,
7183
+ privateKey: keys.privateKey
7184
+ }
6921
7185
  });
6922
7186
  await ledger.settle(escrowId, targetOwner ?? "unknown");
6923
7187
  return {
@@ -7257,19 +7521,19 @@ async function handlePublish(args, ctx) {
7257
7521
  var contextCache = /* @__PURE__ */ new Map();
7258
7522
  function resolveConfigDir(toolCtx) {
7259
7523
  if (toolCtx.agentDir) {
7260
- return toolCtx.agentDir.endsWith(".agentbnb") ? toolCtx.agentDir : join5(toolCtx.agentDir, ".agentbnb");
7524
+ return toolCtx.agentDir.endsWith(".agentbnb") ? toolCtx.agentDir : join6(toolCtx.agentDir, ".agentbnb");
7261
7525
  }
7262
7526
  if (toolCtx.workspaceDir) {
7263
- return join5(toolCtx.workspaceDir, ".agentbnb");
7527
+ return join6(toolCtx.workspaceDir, ".agentbnb");
7264
7528
  }
7265
- return join5(homedir2(), ".agentbnb");
7529
+ return join6(homedir3(), ".agentbnb");
7266
7530
  }
7267
7531
  function buildMcpContext(toolCtx) {
7268
7532
  const configDir = resolveConfigDir(toolCtx);
7269
7533
  const cached = contextCache.get(configDir);
7270
7534
  if (cached) return cached;
7271
- const configPath = join5(configDir, "config.json");
7272
- if (!existsSync6(configPath)) {
7535
+ const configPath = join6(configDir, "config.json");
7536
+ if (!existsSync7(configPath)) {
7273
7537
  throw new Error(
7274
7538
  `AgentBnB not initialized at ${configDir}. Run \`agentbnb init\` or activate the plugin first.`
7275
7539
  );
@@ -7434,18 +7698,18 @@ function resolveWorkspaceDir() {
7434
7698
  if (process.env["AGENTBNB_DIR"]) {
7435
7699
  return process.env["AGENTBNB_DIR"];
7436
7700
  }
7437
- const openclawAgentsDir = join6(homedir3(), ".openclaw", "agents");
7701
+ const openclawAgentsDir = join7(homedir4(), ".openclaw", "agents");
7438
7702
  const cwd = process.cwd();
7439
7703
  if (cwd.startsWith(openclawAgentsDir + "/")) {
7440
7704
  const relative = cwd.slice(openclawAgentsDir.length + 1);
7441
7705
  const agentName = relative.split("/")[0];
7442
- return join6(openclawAgentsDir, agentName, ".agentbnb");
7706
+ return join7(openclawAgentsDir, agentName, ".agentbnb");
7443
7707
  }
7444
- return join6(homedir3(), ".agentbnb");
7708
+ return join7(homedir4(), ".agentbnb");
7445
7709
  }
7446
7710
  function registerDecomposerCard(configDir, owner) {
7447
7711
  try {
7448
- const db = openDatabase(join6(configDir, "registry.db"));
7712
+ const db = openDatabase(join7(configDir, "registry.db"));
7449
7713
  const existing = db.prepare(
7450
7714
  "SELECT id FROM capability_cards WHERE owner = ? AND json_extract(data, '$.capability_type') = ?"
7451
7715
  ).get(owner, "task_decomposition");
@@ -7503,37 +7767,40 @@ function registerDecomposerCard(configDir, owner) {
7503
7767
  }
7504
7768
  }
7505
7769
  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();
7770
+ try {
7771
+ return resolveSelfCli();
7772
+ } catch {
7773
+ return null;
7509
7774
  }
7510
- return null;
7511
7775
  }
7512
7776
  async function runCommand(cmd, env) {
7513
7777
  return execAsync(cmd, { env });
7514
7778
  }
7515
7779
  function deriveAgentName(configDir) {
7516
- const parent = basename(dirname4(configDir));
7517
- if (parent && parent !== "." && parent !== ".agentbnb" && parent !== homedir3().split("/").pop()) {
7780
+ const parent = basename2(dirname3(configDir));
7781
+ if (parent && parent !== "." && parent !== ".agentbnb" && parent !== homedir4().split("/").pop()) {
7518
7782
  return parent;
7519
7783
  }
7520
7784
  return `agent-${randomUUID10().slice(0, 8)}`;
7521
7785
  }
7522
- var defaultDeps = { findCli, runCommand };
7786
+ var defaultDeps = { resolveSelfCli, runCommand };
7523
7787
  async function autoOnboard(configDir, deps = defaultDeps) {
7524
7788
  process.stderr.write("[agentbnb] First-time setup: initializing agent identity...\n");
7525
- const cliPath = deps.findCli();
7526
- if (!cliPath) {
7789
+ let cliPath;
7790
+ try {
7791
+ cliPath = deps.resolveSelfCli();
7792
+ } catch {
7527
7793
  process.stderr.write("[agentbnb] CLI not found. Run: npm install -g agentbnb\n");
7528
7794
  throw new AgentBnBError(
7529
7795
  "agentbnb CLI not found in PATH. Install with: npm install -g agentbnb",
7530
7796
  "INIT_FAILED"
7531
7797
  );
7532
7798
  }
7799
+ const quotedCliPath = quoteShellArg(cliPath);
7533
7800
  const env = { ...process.env, AGENTBNB_DIR: configDir };
7534
7801
  const agentName = deriveAgentName(configDir);
7535
7802
  try {
7536
- await deps.runCommand(`agentbnb init --owner "${agentName}" --yes --no-detect`, env);
7803
+ await deps.runCommand(`${quotedCliPath} init --owner "${agentName}" --yes --no-detect`, env);
7537
7804
  process.stderr.write(`[agentbnb] Agent "${agentName}" initialized.
7538
7805
  `);
7539
7806
  } catch (err) {
@@ -7541,7 +7808,7 @@ async function autoOnboard(configDir, deps = defaultDeps) {
7541
7808
  throw new AgentBnBError(`Auto-init failed: ${msg}`, "INIT_FAILED");
7542
7809
  }
7543
7810
  try {
7544
- await deps.runCommand("agentbnb openclaw sync", env);
7811
+ await deps.runCommand(`${quotedCliPath} openclaw sync`, env);
7545
7812
  process.stderr.write("[agentbnb] Capabilities published from SOUL.md.\n");
7546
7813
  } catch {
7547
7814
  process.stderr.write("[agentbnb] Note: openclaw sync skipped (SOUL.md may not exist yet).\n");
@@ -7553,6 +7820,9 @@ async function autoOnboard(configDir, deps = defaultDeps) {
7553
7820
  process.stderr.write("[agentbnb] Agent initialized and published to AgentBnB network.\n");
7554
7821
  return config;
7555
7822
  }
7823
+ function quoteShellArg(input) {
7824
+ return `'${input.replace(/'/g, `'\\''`)}'`;
7825
+ }
7556
7826
  async function activate(config = {}, _onboardDeps) {
7557
7827
  if (config.agentDir) {
7558
7828
  process.env["AGENTBNB_DIR"] = config.agentDir;
@@ -7561,7 +7831,7 @@ async function activate(config = {}, _onboardDeps) {
7561
7831
  `
7562
7832
  );
7563
7833
  } else if (config.workspaceDir) {
7564
- const derived = join6(config.workspaceDir, ".agentbnb");
7834
+ const derived = join7(config.workspaceDir, ".agentbnb");
7565
7835
  process.env["AGENTBNB_DIR"] = derived;
7566
7836
  process.stderr.write(
7567
7837
  `[agentbnb] AGENTBNB_DIR derived from config.workspaceDir: ${derived}
@@ -7590,7 +7860,7 @@ async function activate(config = {}, _onboardDeps) {
7590
7860
  `[agentbnb] activate: owner=${agentConfig.owner} config=${configDir}/config.json
7591
7861
  `
7592
7862
  );
7593
- const guard = new ProcessGuard(join6(configDir, ".pid"));
7863
+ const guard = new ProcessGuard(join7(configDir, ".pid"));
7594
7864
  const coordinator = new ServiceCoordinator(agentConfig, guard);
7595
7865
  const service = new AgentBnBService(coordinator, agentConfig);
7596
7866
  const opts = {