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
package/dist/index.js CHANGED
@@ -1,3 +1,8 @@
1
+ import {
2
+ RelayClient,
3
+ RelayMessageSchema
4
+ } from "./chunk-3LWBH7P3.js";
5
+
1
6
  // src/types/index.ts
2
7
  import { z } from "zod";
3
8
  var IOSchemaSchema = z.object({
@@ -351,7 +356,10 @@ var V2_FTS_TRIGGERS = `
351
356
  new.id,
352
357
  new.owner,
353
358
  COALESCE(
354
- (SELECT group_concat(json_extract(value, '$.name'), ' ')
359
+ (SELECT group_concat(
360
+ COALESCE(json_extract(value, '$.id'), '') || ' ' || COALESCE(json_extract(value, '$.name'), ''),
361
+ ' '
362
+ )
355
363
  FROM json_each(json_extract(new.data, '$.skills'))),
356
364
  json_extract(new.data, '$.name'),
357
365
  ''
@@ -391,7 +399,10 @@ var V2_FTS_TRIGGERS = `
391
399
  old.id,
392
400
  old.owner,
393
401
  COALESCE(
394
- (SELECT group_concat(json_extract(value, '$.name'), ' ')
402
+ (SELECT group_concat(
403
+ COALESCE(json_extract(value, '$.id'), '') || ' ' || COALESCE(json_extract(value, '$.name'), ''),
404
+ ' '
405
+ )
395
406
  FROM json_each(json_extract(old.data, '$.skills'))),
396
407
  json_extract(old.data, '$.name'),
397
408
  ''
@@ -427,7 +438,10 @@ var V2_FTS_TRIGGERS = `
427
438
  new.id,
428
439
  new.owner,
429
440
  COALESCE(
430
- (SELECT group_concat(json_extract(value, '$.name'), ' ')
441
+ (SELECT group_concat(
442
+ COALESCE(json_extract(value, '$.id'), '') || ' ' || COALESCE(json_extract(value, '$.name'), ''),
443
+ ' '
444
+ )
431
445
  FROM json_each(json_extract(new.data, '$.skills'))),
432
446
  json_extract(new.data, '$.name'),
433
447
  ''
@@ -467,7 +481,10 @@ var V2_FTS_TRIGGERS = `
467
481
  old.id,
468
482
  old.owner,
469
483
  COALESCE(
470
- (SELECT group_concat(json_extract(value, '$.name'), ' ')
484
+ (SELECT group_concat(
485
+ COALESCE(json_extract(value, '$.id'), '') || ' ' || COALESCE(json_extract(value, '$.name'), ''),
486
+ ' '
487
+ )
471
488
  FROM json_each(json_extract(old.data, '$.skills'))),
472
489
  json_extract(old.data, '$.name'),
473
490
  ''
@@ -534,6 +551,15 @@ function openDatabase(path = ":memory:") {
534
551
  tags,
535
552
  content=""
536
553
  );
554
+
555
+ -- Expression index for capability_type lookups (used by Conductor routing).
556
+ -- Turns json_extract full-table-scan into O(log n) B-tree lookup.
557
+ CREATE INDEX IF NOT EXISTS idx_cards_capability_type
558
+ ON capability_cards(json_extract(data, '$.capability_type'));
559
+
560
+ -- Owner index for listCards(owner) and other owner-scoped queries.
561
+ CREATE INDEX IF NOT EXISTS idx_cards_owner
562
+ ON capability_cards(owner);
537
563
  `);
538
564
  createRequestLogTable(db);
539
565
  initFeedbackTable(db);
@@ -545,6 +571,10 @@ function runMigrations(db) {
545
571
  const version = db.pragma("user_version")[0]?.user_version ?? 0;
546
572
  if (version < 2) {
547
573
  migrateV1toV2(db);
574
+ return;
575
+ }
576
+ if (version < 3) {
577
+ migrateV2toV3(db);
548
578
  }
549
579
  }
550
580
  function migrateV1toV2(db) {
@@ -586,44 +616,55 @@ function migrateV1toV2(db) {
586
616
  );
587
617
  }
588
618
  db.exec(V2_FTS_TRIGGERS);
589
- db.exec(`INSERT INTO cards_fts(cards_fts) VALUES('delete-all')`);
590
- const allRows = db.prepare("SELECT rowid, id, owner, data FROM capability_cards").all();
591
- const ftsInsert = db.prepare(
592
- "INSERT INTO cards_fts(rowid, id, owner, name, description, tags) VALUES (?, ?, ?, ?, ?, ?)"
593
- );
594
- for (const row of allRows) {
595
- const data = JSON.parse(row.data);
596
- const skills = data["skills"] ?? [];
597
- let name;
598
- let description;
599
- let tags;
600
- if (skills.length > 0) {
601
- name = skills.map((s) => String(s["name"] ?? "")).join(" ");
602
- description = skills.map((s) => String(s["description"] ?? "")).join(" ");
603
- tags = [
604
- // tags from metadata.tags[]
605
- ...skills.flatMap((s) => {
606
- const meta = s["metadata"];
607
- return meta?.["tags"] ?? [];
608
- }),
609
- // capability_type (singular)
610
- ...skills.map((s) => s["capability_type"]).filter((v) => typeof v === "string" && v.length > 0),
611
- // capability_types[] (plural)
612
- ...skills.flatMap((s) => s["capability_types"] ?? [])
613
- ].join(" ");
614
- } else {
615
- name = String(data["name"] ?? "");
616
- description = String(data["description"] ?? "");
617
- const meta = data["metadata"];
618
- const rawTags = meta?.["tags"] ?? [];
619
- tags = rawTags.join(" ");
620
- }
621
- ftsInsert.run(row.rowid, row.id, row.owner, name, description, tags);
622
- }
623
- db.pragma("user_version = 2");
619
+ rebuildCardsFts(db);
620
+ db.pragma("user_version = 3");
624
621
  });
625
622
  migrate();
626
623
  }
624
+ function migrateV2toV3(db) {
625
+ const migrate = db.transaction(() => {
626
+ db.exec(V2_FTS_TRIGGERS);
627
+ rebuildCardsFts(db);
628
+ db.pragma("user_version = 3");
629
+ });
630
+ migrate();
631
+ }
632
+ function rebuildCardsFts(db) {
633
+ db.exec(`INSERT INTO cards_fts(cards_fts) VALUES('delete-all')`);
634
+ const allRows = db.prepare("SELECT rowid, id, owner, data FROM capability_cards").all();
635
+ const ftsInsert = db.prepare(
636
+ "INSERT INTO cards_fts(rowid, id, owner, name, description, tags) VALUES (?, ?, ?, ?, ?, ?)"
637
+ );
638
+ for (const row of allRows) {
639
+ const data = JSON.parse(row.data);
640
+ const skills = data["skills"] ?? [];
641
+ let name;
642
+ let description;
643
+ let tags;
644
+ if (skills.length > 0) {
645
+ name = skills.map((s) => `${String(s["id"] ?? "")} ${String(s["name"] ?? "")}`.trim()).join(" ");
646
+ description = skills.map((s) => String(s["description"] ?? "")).join(" ");
647
+ tags = [
648
+ // tags from metadata.tags[]
649
+ ...skills.flatMap((s) => {
650
+ const meta = s["metadata"];
651
+ return meta?.["tags"] ?? [];
652
+ }),
653
+ // capability_type (singular)
654
+ ...skills.map((s) => s["capability_type"]).filter((v) => typeof v === "string" && v.length > 0),
655
+ // capability_types[] (plural)
656
+ ...skills.flatMap((s) => s["capability_types"] ?? [])
657
+ ].join(" ");
658
+ } else {
659
+ name = String(data["name"] ?? "");
660
+ description = String(data["description"] ?? "");
661
+ const meta = data["metadata"];
662
+ const rawTags = meta?.["tags"] ?? [];
663
+ tags = rawTags.join(" ");
664
+ }
665
+ ftsInsert.run(row.rowid, row.id, row.owner, name, description, tags);
666
+ }
667
+ }
627
668
  function insertCard(db, card) {
628
669
  const now = (/* @__PURE__ */ new Date()).toISOString();
629
670
  const withTimestamps = { ...card, created_at: card.created_at ?? now, updated_at: now };
@@ -753,9 +794,43 @@ function getReputationScore(db, agentId) {
753
794
  }
754
795
 
755
796
  // src/registry/matcher.ts
797
+ var CACHE_MAX_ENTRIES = 100;
798
+ var CACHE_TTL_MS = 3e4;
799
+ var dbCaches = /* @__PURE__ */ new WeakMap();
800
+ function getDbCache(db) {
801
+ let cache = dbCaches.get(db);
802
+ if (!cache) {
803
+ cache = /* @__PURE__ */ new Map();
804
+ dbCaches.set(db, cache);
805
+ }
806
+ return cache;
807
+ }
808
+ function cacheKey(query, filters) {
809
+ return `${query}|${filters.level ?? ""}|${filters.online ?? ""}|${(filters.apis_used ?? []).join(",")}|${filters.min_reputation ?? ""}`;
810
+ }
811
+ function evictCache(cache) {
812
+ const now = Date.now();
813
+ for (const [key, entry] of cache) {
814
+ if (entry.expiresAt <= now) cache.delete(key);
815
+ }
816
+ while (cache.size > CACHE_MAX_ENTRIES) {
817
+ const firstKey = cache.keys().next().value;
818
+ cache.delete(firstKey);
819
+ }
820
+ }
756
821
  function searchCards(db, query, filters = {}) {
822
+ const cache = getDbCache(db);
823
+ const key = cacheKey(query, filters);
824
+ const cached = cache.get(key);
825
+ if (cached && cached.expiresAt > Date.now()) {
826
+ return cached.results;
827
+ }
828
+ const trimmedQuery = query.trim();
829
+ const exactSkillMatches = findCardsByExactSkillId(db, trimmedQuery, filters);
757
830
  const words = query.trim().split(/\s+/).map((w) => w.replace(/["*^{}():]/g, "")).filter((w) => w.length > 0);
758
- if (words.length === 0) return [];
831
+ if (words.length === 0) {
832
+ return exactSkillMatches;
833
+ }
759
834
  const ftsQuery = words.map((w) => `"${w}"`).join(" OR ");
760
835
  const conditions = [];
761
836
  const params = [ftsQuery];
@@ -780,7 +855,8 @@ function searchCards(db, query, filters = {}) {
780
855
  const stmt = db.prepare(sql);
781
856
  const rows = stmt.all(...params);
782
857
  const results = rows.map((row) => JSON.parse(row.data));
783
- let filtered = results;
858
+ const mergedResults = mergeByCardId(exactSkillMatches, results);
859
+ let filtered = mergedResults;
784
860
  if (filters.apis_used && filters.apis_used.length > 0) {
785
861
  const requiredApis = filters.apis_used;
786
862
  filtered = filtered.filter((card) => {
@@ -791,8 +867,38 @@ function searchCards(db, query, filters = {}) {
791
867
  if (filters.min_reputation !== void 0 && filters.min_reputation > 0) {
792
868
  filtered = applyReputationFilter(db, filtered, filters.min_reputation);
793
869
  }
870
+ evictCache(cache);
871
+ cache.set(key, { results: filtered, expiresAt: Date.now() + CACHE_TTL_MS });
794
872
  return filtered;
795
873
  }
874
+ function mergeByCardId(primary, secondary) {
875
+ const seen = /* @__PURE__ */ new Set();
876
+ const merged = [];
877
+ for (const card of primary) {
878
+ if (seen.has(card.id)) continue;
879
+ seen.add(card.id);
880
+ merged.push(card);
881
+ }
882
+ for (const card of secondary) {
883
+ if (seen.has(card.id)) continue;
884
+ seen.add(card.id);
885
+ merged.push(card);
886
+ }
887
+ return merged;
888
+ }
889
+ function findCardsByExactSkillId(db, query, filters) {
890
+ if (query.length === 0) return [];
891
+ const rows = db.prepare("SELECT data FROM capability_cards").all();
892
+ const cards = rows.map((row) => JSON.parse(row.data));
893
+ return cards.filter((card) => {
894
+ if (filters.level !== void 0 && card.level !== filters.level) return false;
895
+ if (filters.online !== void 0 && card.availability?.online !== filters.online) return false;
896
+ const asRecord = card;
897
+ const skills = asRecord["skills"];
898
+ if (!Array.isArray(skills)) return false;
899
+ return skills.some((skill) => String(skill["id"] ?? "") === query);
900
+ });
901
+ }
796
902
  function applyReputationFilter(db, cards, minReputation) {
797
903
  const owners = [...new Set(cards.map((c) => c.owner))];
798
904
  const reputationMap = /* @__PURE__ */ new Map();
@@ -1178,7 +1284,25 @@ function loadKeyPair(configDir) {
1178
1284
  };
1179
1285
  }
1180
1286
  function canonicalJson(data) {
1181
- return JSON.stringify(data, Object.keys(data).sort());
1287
+ return JSON.stringify(sortForCanonicalJson(data));
1288
+ }
1289
+ function sortForCanonicalJson(value) {
1290
+ if (Array.isArray(value)) {
1291
+ return value.map((item) => sortForCanonicalJson(item));
1292
+ }
1293
+ if (value !== null && typeof value === "object") {
1294
+ const proto = Object.getPrototypeOf(value);
1295
+ if (proto === Object.prototype || proto === null) {
1296
+ const input = value;
1297
+ const output = {};
1298
+ const sortedKeys = Object.keys(input).sort();
1299
+ for (const key of sortedKeys) {
1300
+ output[key] = sortForCanonicalJson(input[key]);
1301
+ }
1302
+ return output;
1303
+ }
1304
+ }
1305
+ return value;
1182
1306
  }
1183
1307
  function signEscrowReceipt(data, privateKey) {
1184
1308
  const message = Buffer.from(canonicalJson(data), "utf-8");
@@ -1238,6 +1362,73 @@ function loadConfig() {
1238
1362
  }
1239
1363
  }
1240
1364
 
1365
+ // src/cli/remote-registry.ts
1366
+ var RegistryTimeoutError = class extends AgentBnBError {
1367
+ constructor(url) {
1368
+ super(
1369
+ `Registry at ${url} did not respond within 5s. Showing local results only.`,
1370
+ "REGISTRY_TIMEOUT"
1371
+ );
1372
+ this.name = "RegistryTimeoutError";
1373
+ }
1374
+ };
1375
+ var RegistryConnectionError = class extends AgentBnBError {
1376
+ constructor(url) {
1377
+ super(
1378
+ `Cannot reach ${url}. Is the registry running? Showing local results only.`,
1379
+ "REGISTRY_CONNECTION"
1380
+ );
1381
+ this.name = "RegistryConnectionError";
1382
+ }
1383
+ };
1384
+ var RegistryAuthError = class extends AgentBnBError {
1385
+ constructor(url) {
1386
+ super(
1387
+ `Authentication failed for ${url}. Run \`agentbnb config set token <your-token>\`.`,
1388
+ "REGISTRY_AUTH"
1389
+ );
1390
+ this.name = "RegistryAuthError";
1391
+ }
1392
+ };
1393
+ async function fetchRemoteCards(registryUrl, params, timeoutMs = 5e3) {
1394
+ let cardsUrl;
1395
+ try {
1396
+ cardsUrl = new URL("/cards", registryUrl);
1397
+ } catch {
1398
+ throw new AgentBnBError(`Invalid registry URL: ${registryUrl}`, "INVALID_REGISTRY_URL");
1399
+ }
1400
+ const searchParams = new URLSearchParams();
1401
+ if (params.q !== void 0) searchParams.set("q", params.q);
1402
+ if (params.level !== void 0) searchParams.set("level", String(params.level));
1403
+ if (params.online !== void 0) searchParams.set("online", String(params.online));
1404
+ if (params.tag !== void 0) searchParams.set("tag", params.tag);
1405
+ searchParams.set("limit", "100");
1406
+ cardsUrl.search = searchParams.toString();
1407
+ const controller = new AbortController();
1408
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
1409
+ let response;
1410
+ try {
1411
+ response = await fetch(cardsUrl.toString(), { signal: controller.signal });
1412
+ } catch (err) {
1413
+ clearTimeout(timer);
1414
+ const isTimeout = err instanceof Error && err.name === "AbortError";
1415
+ if (isTimeout) {
1416
+ throw new RegistryTimeoutError(registryUrl);
1417
+ }
1418
+ throw new RegistryConnectionError(registryUrl);
1419
+ } finally {
1420
+ clearTimeout(timer);
1421
+ }
1422
+ if (response.status === 401 || response.status === 403) {
1423
+ throw new RegistryAuthError(registryUrl);
1424
+ }
1425
+ if (!response.ok) {
1426
+ throw new RegistryConnectionError(registryUrl);
1427
+ }
1428
+ const body = await response.json();
1429
+ return body.items;
1430
+ }
1431
+
1241
1432
  // src/gateway/execute.ts
1242
1433
  async function notifyTelegramSkillExecuted(opts) {
1243
1434
  const cfg = loadConfig();
@@ -1520,7 +1711,54 @@ function createGatewayServer(opts) {
1520
1711
  return { status: "ok", version: VERSION, uptime: process.uptime() };
1521
1712
  });
1522
1713
  fastify.post("/rpc", async (request, reply) => {
1523
- const body = request.body;
1714
+ const rawBody = request.body;
1715
+ if (Array.isArray(rawBody)) {
1716
+ const responses = await Promise.all(
1717
+ rawBody.map(async (single) => {
1718
+ if (single.jsonrpc !== "2.0" || !single.method) {
1719
+ return { jsonrpc: "2.0", id: single.id ?? null, error: { code: -32600, message: "Invalid Request" } };
1720
+ }
1721
+ if (single.method !== "capability.execute") {
1722
+ return { jsonrpc: "2.0", id: single.id ?? null, error: { code: -32601, message: "Method not found" } };
1723
+ }
1724
+ const params2 = single.params ?? {};
1725
+ const cardId2 = params2.card_id;
1726
+ if (!cardId2) {
1727
+ return { jsonrpc: "2.0", id: single.id ?? null, error: { code: -32602, message: "Invalid params: card_id required" } };
1728
+ }
1729
+ const requester2 = params2.requester ?? "unknown";
1730
+ const receipt2 = params2.escrow_receipt;
1731
+ const batchSkillId = params2.skill_id;
1732
+ const trackKey2 = batchSkillId ?? cardId2;
1733
+ inFlight.set(trackKey2, (inFlight.get(trackKey2) ?? 0) + 1);
1734
+ try {
1735
+ const result2 = await executeCapabilityRequest({
1736
+ registryDb,
1737
+ creditDb,
1738
+ cardId: cardId2,
1739
+ skillId: batchSkillId,
1740
+ params: params2,
1741
+ requester: requester2,
1742
+ escrowReceipt: receipt2,
1743
+ skillExecutor,
1744
+ handlerUrl,
1745
+ timeoutMs
1746
+ });
1747
+ if (result2.success) {
1748
+ return { jsonrpc: "2.0", id: single.id ?? null, result: result2.result };
1749
+ } else {
1750
+ return { jsonrpc: "2.0", id: single.id ?? null, error: result2.error };
1751
+ }
1752
+ } finally {
1753
+ const next = (inFlight.get(trackKey2) ?? 1) - 1;
1754
+ if (next <= 0) inFlight.delete(trackKey2);
1755
+ else inFlight.set(trackKey2, next);
1756
+ }
1757
+ })
1758
+ );
1759
+ return reply.send(responses);
1760
+ }
1761
+ const body = rawBody;
1524
1762
  if (body.jsonrpc !== "2.0" || !body.method) {
1525
1763
  return reply.status(400).send({
1526
1764
  jsonrpc: "2.0",
@@ -2839,8 +3077,31 @@ function decompose(task, _availableCapabilities) {
2839
3077
  return [];
2840
3078
  }
2841
3079
 
3080
+ // src/autonomy/auto-request.ts
3081
+ import { randomUUID as randomUUID11 } from "crypto";
3082
+
2842
3083
  // src/gateway/client.ts
2843
3084
  import { randomUUID as randomUUID8 } from "crypto";
3085
+ import { Agent } from "undici";
3086
+ var gatewayAgent = new Agent({
3087
+ keepAliveTimeout: 3e4,
3088
+ keepAliveMaxTimeout: 6e4,
3089
+ connections: 10,
3090
+ pipelining: 1
3091
+ });
3092
+ function buildGatewayAuthHeaders(payload, token, identity) {
3093
+ const headers = { "Content-Type": "application/json" };
3094
+ if (identity) {
3095
+ const signature = signEscrowReceipt(payload, identity.privateKey);
3096
+ headers["X-Agent-Id"] = identity.agentId;
3097
+ headers["X-Agent-Public-Key"] = identity.publicKey;
3098
+ headers["X-Agent-Signature"] = signature;
3099
+ }
3100
+ if (token) {
3101
+ headers["Authorization"] = `Bearer ${token}`;
3102
+ }
3103
+ return headers;
3104
+ }
2844
3105
  async function requestCapability(opts) {
2845
3106
  const { gatewayUrl, token, cardId, params = {}, timeoutMs = 3e5, escrowReceipt, identity } = opts;
2846
3107
  const id = randomUUID8();
@@ -2854,15 +3115,7 @@ async function requestCapability(opts) {
2854
3115
  ...escrowReceipt ? { escrow_receipt: escrowReceipt } : {}
2855
3116
  }
2856
3117
  };
2857
- const headers = { "Content-Type": "application/json" };
2858
- if (identity) {
2859
- const signature = signEscrowReceipt(payload, identity.privateKey);
2860
- headers["X-Agent-Id"] = identity.agentId;
2861
- headers["X-Agent-Public-Key"] = identity.publicKey;
2862
- headers["X-Agent-Signature"] = signature;
2863
- } else if (token) {
2864
- headers["Authorization"] = `Bearer ${token}`;
2865
- }
3118
+ const headers = buildGatewayAuthHeaders(payload, token, identity);
2866
3119
  const controller = new AbortController();
2867
3120
  const timer = setTimeout(() => controller.abort(), timeoutMs);
2868
3121
  let response;
@@ -2871,7 +3124,9 @@ async function requestCapability(opts) {
2871
3124
  method: "POST",
2872
3125
  headers,
2873
3126
  body: JSON.stringify(payload),
2874
- signal: controller.signal
3127
+ signal: controller.signal,
3128
+ // undici dispatcher for connection pooling (Node.js 20+)
3129
+ dispatcher: gatewayAgent
2875
3130
  });
2876
3131
  } catch (err) {
2877
3132
  clearTimeout(timer);
@@ -2889,6 +3144,65 @@ async function requestCapability(opts) {
2889
3144
  }
2890
3145
  return body.result;
2891
3146
  }
3147
+ async function requestCapabilityBatch(gatewayUrl, token, items, opts = {}) {
3148
+ if (items.length === 0) return /* @__PURE__ */ new Map();
3149
+ if (items.length === 1) {
3150
+ const item = items[0];
3151
+ const result = await requestCapability({
3152
+ gatewayUrl,
3153
+ token,
3154
+ cardId: item.cardId,
3155
+ params: item.params,
3156
+ escrowReceipt: item.escrowReceipt,
3157
+ timeoutMs: opts.timeoutMs,
3158
+ identity: opts.identity
3159
+ });
3160
+ return /* @__PURE__ */ new Map([[item.id, result]]);
3161
+ }
3162
+ const { timeoutMs = 3e5, identity } = opts;
3163
+ const batchPayload = items.map((item) => ({
3164
+ jsonrpc: "2.0",
3165
+ id: item.id,
3166
+ method: "capability.execute",
3167
+ params: {
3168
+ card_id: item.cardId,
3169
+ ...item.params,
3170
+ ...item.escrowReceipt ? { escrow_receipt: item.escrowReceipt } : {}
3171
+ }
3172
+ }));
3173
+ const headers = buildGatewayAuthHeaders(batchPayload, token, identity);
3174
+ const controller = new AbortController();
3175
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
3176
+ let response;
3177
+ try {
3178
+ response = await fetch(`${gatewayUrl}/rpc`, {
3179
+ method: "POST",
3180
+ headers,
3181
+ body: JSON.stringify(batchPayload),
3182
+ signal: controller.signal,
3183
+ dispatcher: gatewayAgent
3184
+ });
3185
+ } catch (err) {
3186
+ clearTimeout(timer);
3187
+ const isTimeout = err instanceof Error && err.name === "AbortError";
3188
+ throw new AgentBnBError(
3189
+ isTimeout ? "Batch request timed out" : `Network error: ${String(err)}`,
3190
+ isTimeout ? "TIMEOUT" : "NETWORK_ERROR"
3191
+ );
3192
+ } finally {
3193
+ clearTimeout(timer);
3194
+ }
3195
+ const body = await response.json();
3196
+ const results = /* @__PURE__ */ new Map();
3197
+ for (const resp of body) {
3198
+ if (resp.error) {
3199
+ results.set(resp.id, new AgentBnBError(resp.error.message, `RPC_ERROR_${resp.error.code}`));
3200
+ } else {
3201
+ results.set(resp.id, resp.result);
3202
+ }
3203
+ }
3204
+ return results;
3205
+ }
2892
3206
  async function requestViaRelay(relay, opts) {
2893
3207
  try {
2894
3208
  return await relay.request({
@@ -2922,73 +3236,6 @@ import { randomUUID as randomUUID10 } from "crypto";
2922
3236
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, existsSync as existsSync3, mkdirSync as mkdirSync2 } from "fs";
2923
3237
  import { join as join3 } from "path";
2924
3238
 
2925
- // src/cli/remote-registry.ts
2926
- var RegistryTimeoutError = class extends AgentBnBError {
2927
- constructor(url) {
2928
- super(
2929
- `Registry at ${url} did not respond within 5s. Showing local results only.`,
2930
- "REGISTRY_TIMEOUT"
2931
- );
2932
- this.name = "RegistryTimeoutError";
2933
- }
2934
- };
2935
- var RegistryConnectionError = class extends AgentBnBError {
2936
- constructor(url) {
2937
- super(
2938
- `Cannot reach ${url}. Is the registry running? Showing local results only.`,
2939
- "REGISTRY_CONNECTION"
2940
- );
2941
- this.name = "RegistryConnectionError";
2942
- }
2943
- };
2944
- var RegistryAuthError = class extends AgentBnBError {
2945
- constructor(url) {
2946
- super(
2947
- `Authentication failed for ${url}. Run \`agentbnb config set token <your-token>\`.`,
2948
- "REGISTRY_AUTH"
2949
- );
2950
- this.name = "RegistryAuthError";
2951
- }
2952
- };
2953
- async function fetchRemoteCards(registryUrl, params, timeoutMs = 5e3) {
2954
- let cardsUrl;
2955
- try {
2956
- cardsUrl = new URL("/cards", registryUrl);
2957
- } catch {
2958
- throw new AgentBnBError(`Invalid registry URL: ${registryUrl}`, "INVALID_REGISTRY_URL");
2959
- }
2960
- const searchParams = new URLSearchParams();
2961
- if (params.q !== void 0) searchParams.set("q", params.q);
2962
- if (params.level !== void 0) searchParams.set("level", String(params.level));
2963
- if (params.online !== void 0) searchParams.set("online", String(params.online));
2964
- if (params.tag !== void 0) searchParams.set("tag", params.tag);
2965
- searchParams.set("limit", "100");
2966
- cardsUrl.search = searchParams.toString();
2967
- const controller = new AbortController();
2968
- const timer = setTimeout(() => controller.abort(), timeoutMs);
2969
- let response;
2970
- try {
2971
- response = await fetch(cardsUrl.toString(), { signal: controller.signal });
2972
- } catch (err) {
2973
- clearTimeout(timer);
2974
- const isTimeout = err instanceof Error && err.name === "AbortError";
2975
- if (isTimeout) {
2976
- throw new RegistryTimeoutError(registryUrl);
2977
- }
2978
- throw new RegistryConnectionError(registryUrl);
2979
- } finally {
2980
- clearTimeout(timer);
2981
- }
2982
- if (response.status === 401 || response.status === 403) {
2983
- throw new RegistryAuthError(registryUrl);
2984
- }
2985
- if (!response.ok) {
2986
- throw new RegistryConnectionError(registryUrl);
2987
- }
2988
- const body = await response.json();
2989
- return body.items;
2990
- }
2991
-
2992
3239
  // src/autonomy/auto-request.ts
2993
3240
  function minMaxNormalize(values) {
2994
3241
  if (values.length === 0) return [];
@@ -3265,6 +3512,65 @@ function computeWaves(subtasks) {
3265
3512
  }
3266
3513
  return waves;
3267
3514
  }
3515
+ async function executeSingleTask(pt, gatewayToken, timeoutMs, requesterOwner, relayClient, resolveAgentUrl) {
3516
+ const { taskId, match: m, interpolatedParams, primary, teamId, capabilityType } = pt;
3517
+ try {
3518
+ let res;
3519
+ if (primary.url.startsWith("relay://") && relayClient) {
3520
+ const targetOwner = primary.url.replace("relay://", "");
3521
+ res = await relayClient.request({
3522
+ targetOwner,
3523
+ cardId: primary.cardId,
3524
+ params: interpolatedParams,
3525
+ requester: requesterOwner,
3526
+ timeoutMs
3527
+ });
3528
+ } else {
3529
+ res = await requestCapability({
3530
+ gatewayUrl: primary.url,
3531
+ token: gatewayToken,
3532
+ cardId: primary.cardId,
3533
+ params: { ...interpolatedParams, requester: requesterOwner },
3534
+ timeoutMs
3535
+ });
3536
+ }
3537
+ return { taskId, result: res, credits: m.credits, team_id: teamId, capability_type: capabilityType };
3538
+ } catch (primaryErr) {
3539
+ if (m.alternatives.length > 0) {
3540
+ const alt = m.alternatives[0];
3541
+ const altResolved = resolveAgentUrl ? resolveAgentUrl(alt.agent) : { url: `http://${alt.agent}:7700`, cardId: `card-${alt.agent}` };
3542
+ try {
3543
+ let altRes;
3544
+ if (altResolved.url.startsWith("relay://") && relayClient) {
3545
+ const targetOwner = altResolved.url.replace("relay://", "");
3546
+ altRes = await relayClient.request({
3547
+ targetOwner,
3548
+ cardId: altResolved.cardId,
3549
+ params: interpolatedParams,
3550
+ requester: requesterOwner,
3551
+ timeoutMs
3552
+ });
3553
+ } else {
3554
+ altRes = await requestCapability({
3555
+ gatewayUrl: altResolved.url,
3556
+ token: gatewayToken,
3557
+ cardId: altResolved.cardId,
3558
+ params: { ...interpolatedParams, requester: requesterOwner },
3559
+ timeoutMs
3560
+ });
3561
+ }
3562
+ return { taskId, result: altRes, credits: alt.credits, team_id: teamId, capability_type: capabilityType };
3563
+ } catch (altErr) {
3564
+ throw new Error(
3565
+ `Task ${taskId}: primary (${m.selected_agent}) failed: ${primaryErr instanceof Error ? primaryErr.message : String(primaryErr)}; alternative (${alt.agent}) failed: ${altErr instanceof Error ? altErr.message : String(altErr)}`
3566
+ );
3567
+ }
3568
+ }
3569
+ throw new Error(
3570
+ `Task ${taskId}: ${primaryErr instanceof Error ? primaryErr.message : String(primaryErr)}`
3571
+ );
3572
+ }
3573
+ }
3268
3574
  async function orchestrate(opts) {
3269
3575
  const { subtasks, matches, gatewayToken, resolveAgentUrl, timeoutMs = 3e5, maxBudget, relayClient, requesterOwner } = opts;
3270
3576
  const startTime = Date.now();
@@ -3302,89 +3608,127 @@ async function orchestrate(opts) {
3302
3608
  }
3303
3609
  executableIds.push(taskId);
3304
3610
  }
3305
- const waveResults = await Promise.allSettled(
3306
- executableIds.map(async (taskId) => {
3307
- const subtask = subtaskMap.get(taskId);
3308
- const m = matches.get(taskId);
3309
- if (!m) {
3310
- throw new Error(`No match found for subtask ${taskId}`);
3311
- }
3312
- const stepsContext = {};
3313
- for (const [id, val] of results) {
3314
- stepsContext[id] = val;
3315
- }
3316
- const interpContext = { steps: stepsContext, prev: void 0 };
3317
- if (subtask.depends_on.length > 0) {
3318
- const lastDep = subtask.depends_on[subtask.depends_on.length - 1];
3319
- interpContext.prev = results.get(lastDep);
3320
- }
3321
- const interpolatedParams = interpolateObject(
3322
- subtask.params,
3323
- interpContext
3324
- );
3325
- const teamMember = teamMemberMap.get(taskId);
3326
- const teamId = opts.team?.team_id ?? null;
3327
- const taskCapabilityType = teamMember?.capability_type ?? null;
3328
- const agentOwner = teamMember?.agent ?? m.selected_agent;
3329
- const primary = resolveAgentUrl(agentOwner);
3330
- try {
3331
- let res;
3332
- if (primary.url.startsWith("relay://") && relayClient) {
3333
- const targetOwner = primary.url.replace("relay://", "");
3334
- res = await relayClient.request({
3335
- targetOwner,
3336
- cardId: primary.cardId,
3337
- params: interpolatedParams,
3338
- requester: requesterOwner,
3339
- timeoutMs
3340
- });
3341
- } else {
3342
- res = await requestCapability({
3343
- gatewayUrl: primary.url,
3344
- token: gatewayToken,
3345
- cardId: primary.cardId,
3346
- params: { ...interpolatedParams, requester: requesterOwner },
3347
- timeoutMs
3348
- });
3349
- }
3350
- return { taskId, result: res, credits: m.credits, team_id: teamId, capability_type: taskCapabilityType };
3351
- } catch (primaryErr) {
3352
- if (m.alternatives.length > 0) {
3353
- const alt = m.alternatives[0];
3354
- const altAgent = resolveAgentUrl(alt.agent);
3611
+ const preparedTasks = [];
3612
+ for (const taskId of executableIds) {
3613
+ const subtask = subtaskMap.get(taskId);
3614
+ const m = matches.get(taskId);
3615
+ if (!m) {
3616
+ errors.push(`No match found for subtask ${taskId}`);
3617
+ continue;
3618
+ }
3619
+ const stepsContext = {};
3620
+ for (const [id, val] of results) stepsContext[id] = val;
3621
+ const interpContext = { steps: stepsContext, prev: void 0 };
3622
+ if (subtask.depends_on.length > 0) {
3623
+ const lastDep = subtask.depends_on[subtask.depends_on.length - 1];
3624
+ interpContext.prev = results.get(lastDep);
3625
+ }
3626
+ const interpolatedParams = interpolateObject(
3627
+ subtask.params,
3628
+ interpContext
3629
+ );
3630
+ const teamMember = teamMemberMap.get(taskId);
3631
+ const agentOwner = teamMember?.agent ?? m.selected_agent;
3632
+ const primary = resolveAgentUrl(agentOwner);
3633
+ preparedTasks.push({
3634
+ taskId,
3635
+ subtask,
3636
+ match: m,
3637
+ interpolatedParams,
3638
+ agentOwner,
3639
+ primary,
3640
+ teamId: opts.team?.team_id ?? null,
3641
+ capabilityType: teamMember?.capability_type ?? null
3642
+ });
3643
+ }
3644
+ const httpGroups = /* @__PURE__ */ new Map();
3645
+ const relayTasks = [];
3646
+ for (const pt of preparedTasks) {
3647
+ if (pt.primary.url.startsWith("relay://") && relayClient) {
3648
+ relayTasks.push(pt);
3649
+ } else {
3650
+ const group = httpGroups.get(pt.primary.url) ?? [];
3651
+ group.push(pt);
3652
+ httpGroups.set(pt.primary.url, group);
3653
+ }
3654
+ }
3655
+ const batchPromises = [];
3656
+ for (const [gatewayUrl, group] of httpGroups) {
3657
+ if (group.length >= 2) {
3658
+ batchPromises.push(
3659
+ (async () => {
3660
+ const items = group.map((pt) => ({
3661
+ id: pt.taskId,
3662
+ cardId: pt.primary.cardId,
3663
+ params: { ...pt.interpolatedParams, requester: requesterOwner },
3664
+ _pt: pt
3665
+ }));
3355
3666
  try {
3356
- let altRes;
3357
- if (altAgent.url.startsWith("relay://") && relayClient) {
3358
- const targetOwner = altAgent.url.replace("relay://", "");
3359
- altRes = await relayClient.request({
3360
- targetOwner,
3361
- cardId: altAgent.cardId,
3362
- params: interpolatedParams,
3363
- requester: requesterOwner,
3364
- timeoutMs
3365
- });
3366
- } else {
3367
- altRes = await requestCapability({
3368
- gatewayUrl: altAgent.url,
3369
- token: gatewayToken,
3370
- cardId: altAgent.cardId,
3371
- params: { ...interpolatedParams, requester: requesterOwner },
3372
- timeoutMs
3373
- });
3374
- }
3375
- return { taskId, result: altRes, credits: alt.credits, team_id: teamId, capability_type: taskCapabilityType };
3376
- } catch (altErr) {
3377
- throw new Error(
3378
- `Task ${taskId}: primary (${m.selected_agent}) failed: ${primaryErr instanceof Error ? primaryErr.message : String(primaryErr)}; alternative (${alt.agent}) failed: ${altErr instanceof Error ? altErr.message : String(altErr)}`
3667
+ const batchResults = await requestCapabilityBatch(
3668
+ gatewayUrl,
3669
+ gatewayToken,
3670
+ items.map(({ _pt, ...item }) => item),
3671
+ { timeoutMs }
3379
3672
  );
3673
+ return items.map((item) => {
3674
+ const res = batchResults.get(item.id);
3675
+ if (res instanceof Error) {
3676
+ return {
3677
+ status: "rejected",
3678
+ reason: new Error(`Task ${item.id}: ${res.message}`)
3679
+ };
3680
+ }
3681
+ return {
3682
+ status: "fulfilled",
3683
+ value: {
3684
+ taskId: item.id,
3685
+ result: res,
3686
+ credits: item._pt.match.credits,
3687
+ team_id: item._pt.teamId,
3688
+ capability_type: item._pt.capabilityType
3689
+ }
3690
+ };
3691
+ });
3692
+ } catch (batchErr) {
3693
+ return Promise.all(group.map(async (pt) => {
3694
+ try {
3695
+ const res = await executeSingleTask(pt, gatewayToken, timeoutMs, requesterOwner, relayClient, resolveAgentUrl);
3696
+ return { status: "fulfilled", value: res };
3697
+ } catch (err) {
3698
+ return { status: "rejected", reason: err };
3699
+ }
3700
+ }));
3380
3701
  }
3702
+ })()
3703
+ );
3704
+ } else {
3705
+ const pt = group[0];
3706
+ batchPromises.push(
3707
+ (async () => {
3708
+ try {
3709
+ const res = await executeSingleTask(pt, gatewayToken, timeoutMs, requesterOwner, relayClient, resolveAgentUrl);
3710
+ return [{ status: "fulfilled", value: res }];
3711
+ } catch (err) {
3712
+ return [{ status: "rejected", reason: err }];
3713
+ }
3714
+ })()
3715
+ );
3716
+ }
3717
+ }
3718
+ for (const pt of relayTasks) {
3719
+ batchPromises.push(
3720
+ (async () => {
3721
+ try {
3722
+ const res = await executeSingleTask(pt, gatewayToken, timeoutMs, requesterOwner, relayClient, resolveAgentUrl);
3723
+ return [{ status: "fulfilled", value: res }];
3724
+ } catch (err) {
3725
+ return [{ status: "rejected", reason: err }];
3381
3726
  }
3382
- throw new Error(
3383
- `Task ${taskId}: ${primaryErr instanceof Error ? primaryErr.message : String(primaryErr)}`
3384
- );
3385
- }
3386
- })
3387
- );
3727
+ })()
3728
+ );
3729
+ }
3730
+ const allBatchResults = await Promise.all(batchPromises);
3731
+ const waveResults = allBatchResults.flat();
3388
3732
  for (const settlement of waveResults) {
3389
3733
  if (settlement.status === "fulfilled") {
3390
3734
  const { taskId, result, credits, team_id, capability_type } = settlement.value;
@@ -3452,7 +3796,7 @@ var BudgetManager = class {
3452
3796
  };
3453
3797
 
3454
3798
  // src/conductor/team-formation.ts
3455
- import { randomUUID as randomUUID11 } from "crypto";
3799
+ import { randomUUID as randomUUID12 } from "crypto";
3456
3800
  function selectByStrategy(matches, strategy) {
3457
3801
  if (matches.length === 0) return void 0;
3458
3802
  if (strategy === "balanced") {
@@ -3469,7 +3813,7 @@ function selectByStrategy(matches, strategy) {
3469
3813
  }
3470
3814
  async function formTeam(opts) {
3471
3815
  const { subtasks, strategy, db, conductorOwner, registryUrl } = opts;
3472
- const team_id = randomUUID11();
3816
+ const team_id = randomUUID12();
3473
3817
  if (subtasks.length === 0) {
3474
3818
  return { team_id, strategy, matched: [], unrouted: [] };
3475
3819
  }
@@ -3699,7 +4043,7 @@ var ConductorMode = class {
3699
4043
 
3700
4044
  // src/credit/escrow-receipt.ts
3701
4045
  import { z as z3 } from "zod";
3702
- import { randomUUID as randomUUID12 } from "crypto";
4046
+ import { randomUUID as randomUUID13 } from "crypto";
3703
4047
  var EscrowReceiptSchema = z3.object({
3704
4048
  requester_owner: z3.string().min(1),
3705
4049
  requester_agent_id: z3.string().optional(),
@@ -3721,7 +4065,7 @@ function createSignedEscrowReceipt(db, privateKey, publicKey, opts) {
3721
4065
  card_id: opts.cardId,
3722
4066
  ...opts.skillId ? { skill_id: opts.skillId } : {},
3723
4067
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
3724
- nonce: randomUUID12()
4068
+ nonce: randomUUID13()
3725
4069
  };
3726
4070
  const signature = signEscrowReceipt(receiptData, privateKey);
3727
4071
  const receipt = {
@@ -3733,7 +4077,7 @@ function createSignedEscrowReceipt(db, privateKey, publicKey, opts) {
3733
4077
 
3734
4078
  // src/identity/identity.ts
3735
4079
  import { z as z4 } from "zod";
3736
- import { createHash as createHash2 } from "crypto";
4080
+ import { createHash as createHash2, createPrivateKey as createPrivateKey2, createPublicKey as createPublicKey2 } from "crypto";
3737
4081
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
3738
4082
  import { join as join4 } from "path";
3739
4083
  var AgentIdentitySchema = z4.object({
@@ -3763,6 +4107,30 @@ var AgentCertificateSchema = z4.object({
3763
4107
  signature: z4.string().min(1)
3764
4108
  });
3765
4109
  var IDENTITY_FILENAME = "identity.json";
4110
+ var PRIVATE_KEY_FILENAME = "private.key";
4111
+ var PUBLIC_KEY_FILENAME = "public.key";
4112
+ function derivePublicKeyFromPrivate(privateKey) {
4113
+ const privateKeyObject = createPrivateKey2({ key: privateKey, format: "der", type: "pkcs8" });
4114
+ const publicKeyObject = createPublicKey2(privateKeyObject);
4115
+ const publicKey = publicKeyObject.export({ format: "der", type: "spki" });
4116
+ return Buffer.from(publicKey);
4117
+ }
4118
+ function buildIdentityFromPublicKey(publicKey, owner, createdAt) {
4119
+ const publicKeyHex = publicKey.toString("hex");
4120
+ return {
4121
+ agent_id: deriveAgentId(publicKeyHex),
4122
+ owner,
4123
+ public_key: publicKeyHex,
4124
+ created_at: createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
4125
+ };
4126
+ }
4127
+ function generateFreshIdentity(configDir, owner) {
4128
+ const keys = generateKeyPair();
4129
+ saveKeyPair(configDir, keys);
4130
+ const identity = buildIdentityFromPublicKey(keys.publicKey, owner);
4131
+ saveIdentity(configDir, identity);
4132
+ return { identity, keys, status: "generated" };
4133
+ }
3766
4134
  function deriveAgentId(publicKeyHex) {
3767
4135
  return createHash2("sha256").update(publicKeyHex, "hex").digest("hex").slice(0, 16);
3768
4136
  }
@@ -3805,6 +4173,57 @@ function saveIdentity(configDir, identity) {
3805
4173
  const filePath = join4(configDir, IDENTITY_FILENAME);
3806
4174
  writeFileSync4(filePath, JSON.stringify(identity, null, 2), "utf-8");
3807
4175
  }
4176
+ function loadOrRepairIdentity(configDir, ownerHint) {
4177
+ if (!existsSync4(configDir)) {
4178
+ mkdirSync3(configDir, { recursive: true });
4179
+ }
4180
+ const identityPath = join4(configDir, IDENTITY_FILENAME);
4181
+ const privateKeyPath = join4(configDir, PRIVATE_KEY_FILENAME);
4182
+ const publicKeyPath = join4(configDir, PUBLIC_KEY_FILENAME);
4183
+ const hasIdentity = existsSync4(identityPath);
4184
+ const hasPrivateKey = existsSync4(privateKeyPath);
4185
+ const hasPublicKey = existsSync4(publicKeyPath);
4186
+ if (!hasIdentity || !hasPrivateKey || !hasPublicKey) {
4187
+ return generateFreshIdentity(configDir, ownerHint ?? "agent");
4188
+ }
4189
+ let keys;
4190
+ try {
4191
+ keys = loadKeyPair(configDir);
4192
+ } catch {
4193
+ return generateFreshIdentity(configDir, ownerHint ?? "agent");
4194
+ }
4195
+ let derivedPublicKey;
4196
+ try {
4197
+ derivedPublicKey = derivePublicKeyFromPrivate(keys.privateKey);
4198
+ } catch {
4199
+ return generateFreshIdentity(configDir, ownerHint ?? "agent");
4200
+ }
4201
+ let keypairRepaired = false;
4202
+ if (!keys.publicKey.equals(derivedPublicKey)) {
4203
+ keypairRepaired = true;
4204
+ keys = { privateKey: keys.privateKey, publicKey: derivedPublicKey };
4205
+ saveKeyPair(configDir, keys);
4206
+ }
4207
+ const loadedIdentity = loadIdentity(configDir);
4208
+ const expectedAgentId = deriveAgentId(derivedPublicKey.toString("hex"));
4209
+ const expectedPublicKeyHex = derivedPublicKey.toString("hex");
4210
+ const identityMismatch = !loadedIdentity || loadedIdentity.public_key !== expectedPublicKeyHex || loadedIdentity.agent_id !== expectedAgentId;
4211
+ if (identityMismatch) {
4212
+ const repairedIdentity = buildIdentityFromPublicKey(
4213
+ derivedPublicKey,
4214
+ loadedIdentity?.owner ?? ownerHint ?? "agent",
4215
+ loadedIdentity?.created_at
4216
+ );
4217
+ saveIdentity(configDir, repairedIdentity);
4218
+ return { identity: repairedIdentity, keys, status: "repaired" };
4219
+ }
4220
+ if (ownerHint && loadedIdentity.owner !== ownerHint) {
4221
+ const updatedIdentity = { ...loadedIdentity, owner: ownerHint };
4222
+ saveIdentity(configDir, updatedIdentity);
4223
+ return { identity: updatedIdentity, keys, status: "repaired" };
4224
+ }
4225
+ return { identity: loadedIdentity, keys, status: keypairRepaired ? "repaired" : "existing" };
4226
+ }
3808
4227
  function issueAgentCertificate(identity, privateKey) {
3809
4228
  const issuedAt = (/* @__PURE__ */ new Date()).toISOString();
3810
4229
  const expiresAt = new Date(Date.now() + 365 * 24 * 60 * 60 * 1e3).toISOString();
@@ -3838,15 +4257,7 @@ function verifyAgentCertificate(cert) {
3838
4257
  return verifyEscrowReceipt(payload, cert.signature, publicKeyBuf);
3839
4258
  }
3840
4259
  function ensureIdentity(configDir, owner) {
3841
- const existing = loadIdentity(configDir);
3842
- if (existing) {
3843
- if (existing.owner !== owner) {
3844
- existing.owner = owner;
3845
- saveIdentity(configDir, existing);
3846
- }
3847
- return existing;
3848
- }
3849
- return createIdentity(configDir, owner);
4260
+ return loadOrRepairIdentity(configDir, owner).identity;
3850
4261
  }
3851
4262
 
3852
4263
  // src/sdk/consumer.ts
@@ -3916,7 +4327,12 @@ var AgentBnBConsumer = class {
3916
4327
  cardId: opts.cardId,
3917
4328
  params: opts.params,
3918
4329
  timeoutMs: opts.timeoutMs,
3919
- escrowReceipt: receipt
4330
+ escrowReceipt: receipt,
4331
+ identity: {
4332
+ agentId: identity.agent_id,
4333
+ publicKey: identity.public_key,
4334
+ privateKey: this.keys.privateKey
4335
+ }
3920
4336
  });
3921
4337
  settleRequesterEscrow(db, escrowId);
3922
4338
  return result;
@@ -4092,7 +4508,7 @@ var AgentBnBProvider = class {
4092
4508
 
4093
4509
  // src/identity/guarantor.ts
4094
4510
  import { z as z5 } from "zod";
4095
- import { randomUUID as randomUUID13 } from "crypto";
4511
+ import { randomUUID as randomUUID14 } from "crypto";
4096
4512
  var MAX_AGENTS_PER_GUARANTOR = 10;
4097
4513
  var GUARANTOR_CREDIT_POOL = 50;
4098
4514
  var GuarantorRecordSchema = z5.object({
@@ -4131,7 +4547,7 @@ function registerGuarantor(db, githubLogin) {
4131
4547
  );
4132
4548
  }
4133
4549
  const record = {
4134
- id: randomUUID13(),
4550
+ id: randomUUID14(),
4135
4551
  github_login: githubLogin,
4136
4552
  agent_count: 0,
4137
4553
  credit_pool: GUARANTOR_CREDIT_POOL,
@@ -4205,178 +4621,12 @@ function getAgentGuarantor(db, agentId) {
4205
4621
  function initiateGithubAuth() {
4206
4622
  return {
4207
4623
  auth_url: "https://github.com/login/oauth/authorize?client_id=PLACEHOLDER&scope=read:user",
4208
- state: randomUUID13()
4624
+ state: randomUUID14()
4209
4625
  };
4210
4626
  }
4211
4627
 
4212
- // src/relay/types.ts
4213
- import { z as z6 } from "zod";
4214
- var RegisterMessageSchema = z6.object({
4215
- type: z6.literal("register"),
4216
- owner: z6.string().min(1),
4217
- /** V8: Cryptographic agent identity. When present, used as the canonical key. */
4218
- agent_id: z6.string().optional(),
4219
- /** V8 Phase 3: Server identifier for multi-agent delegation. */
4220
- server_id: z6.string().optional(),
4221
- token: z6.string().min(1),
4222
- card: z6.record(z6.unknown()),
4223
- // CapabilityCard (validated separately)
4224
- cards: z6.array(z6.record(z6.unknown())).optional(),
4225
- // Additional cards (e.g., conductor card)
4226
- /** V8 Phase 3: Additional agents served by this server (multi-agent registration). */
4227
- agents: z6.array(z6.object({
4228
- agent_id: z6.string().min(1),
4229
- display_name: z6.string().min(1),
4230
- cards: z6.array(z6.record(z6.unknown())),
4231
- delegation_token: z6.record(z6.unknown()).optional()
4232
- })).optional()
4233
- });
4234
- var RegisteredMessageSchema = z6.object({
4235
- type: z6.literal("registered"),
4236
- agent_id: z6.string()
4237
- });
4238
- var RelayRequestMessageSchema = z6.object({
4239
- type: z6.literal("relay_request"),
4240
- id: z6.string().uuid(),
4241
- target_owner: z6.string().min(1),
4242
- /** V8: Target agent's cryptographic identity. Preferred over target_owner. */
4243
- target_agent_id: z6.string().optional(),
4244
- card_id: z6.string(),
4245
- skill_id: z6.string().optional(),
4246
- params: z6.record(z6.unknown()).default({}),
4247
- requester: z6.string().optional(),
4248
- escrow_receipt: z6.record(z6.unknown()).optional()
4249
- });
4250
- var IncomingRequestMessageSchema = z6.object({
4251
- type: z6.literal("incoming_request"),
4252
- id: z6.string().uuid(),
4253
- from_owner: z6.string().min(1),
4254
- card_id: z6.string(),
4255
- skill_id: z6.string().optional(),
4256
- params: z6.record(z6.unknown()).default({}),
4257
- requester: z6.string().optional(),
4258
- escrow_receipt: z6.record(z6.unknown()).optional()
4259
- });
4260
- var RelayResponseMessageSchema = z6.object({
4261
- type: z6.literal("relay_response"),
4262
- id: z6.string().uuid(),
4263
- result: z6.unknown().optional(),
4264
- error: z6.object({
4265
- code: z6.number(),
4266
- message: z6.string()
4267
- }).optional()
4268
- });
4269
- var ResponseMessageSchema = z6.object({
4270
- type: z6.literal("response"),
4271
- id: z6.string().uuid(),
4272
- result: z6.unknown().optional(),
4273
- error: z6.object({
4274
- code: z6.number(),
4275
- message: z6.string()
4276
- }).optional()
4277
- });
4278
- var ErrorMessageSchema = z6.object({
4279
- type: z6.literal("error"),
4280
- code: z6.string(),
4281
- message: z6.string(),
4282
- request_id: z6.string().optional()
4283
- });
4284
- var RelayProgressMessageSchema = z6.object({
4285
- type: z6.literal("relay_progress"),
4286
- id: z6.string().uuid(),
4287
- // request ID this progress relates to
4288
- progress: z6.number().min(0).max(100).optional(),
4289
- // optional percentage
4290
- message: z6.string().optional()
4291
- // optional status message
4292
- });
4293
- var HeartbeatMessageSchema = z6.object({
4294
- type: z6.literal("heartbeat"),
4295
- owner: z6.string().min(1),
4296
- capacity: z6.object({
4297
- current_load: z6.number(),
4298
- max_concurrent: z6.number(),
4299
- queue_depth: z6.number()
4300
- }),
4301
- self_summary: z6.object({
4302
- capabilities: z6.array(z6.string()),
4303
- success_rate: z6.number(),
4304
- credit_balance: z6.number(),
4305
- total_completed: z6.number(),
4306
- provider_number: z6.number(),
4307
- reliability: z6.object({
4308
- current_streak: z6.number(),
4309
- repeat_hire_rate: z6.number(),
4310
- avg_feedback: z6.number()
4311
- })
4312
- })
4313
- });
4314
- var EscrowHoldMessageSchema = z6.object({
4315
- type: z6.literal("escrow_hold"),
4316
- consumer_agent_id: z6.string().min(1),
4317
- provider_agent_id: z6.string().min(1),
4318
- skill_id: z6.string().min(1),
4319
- amount: z6.number().positive(),
4320
- request_id: z6.string().uuid(),
4321
- signature: z6.string().optional(),
4322
- public_key: z6.string().optional()
4323
- });
4324
- var EscrowHoldConfirmedMessageSchema = z6.object({
4325
- type: z6.literal("escrow_hold_confirmed"),
4326
- request_id: z6.string(),
4327
- escrow_id: z6.string(),
4328
- hold_amount: z6.number(),
4329
- consumer_remaining: z6.number()
4330
- });
4331
- var EscrowSettleMessageSchema = z6.object({
4332
- type: z6.literal("escrow_settle"),
4333
- escrow_id: z6.string().min(1),
4334
- request_id: z6.string().uuid(),
4335
- success: z6.boolean(),
4336
- failure_reason: z6.enum(["bad_execution", "overload", "timeout", "auth_error", "not_found"]).optional(),
4337
- result_hash: z6.string().optional(),
4338
- signature: z6.string().optional(),
4339
- public_key: z6.string().optional(),
4340
- consumer_agent_id: z6.string().optional()
4341
- });
4342
- var EscrowSettledMessageSchema = z6.object({
4343
- type: z6.literal("escrow_settled"),
4344
- escrow_id: z6.string(),
4345
- request_id: z6.string(),
4346
- provider_earned: z6.number(),
4347
- network_fee: z6.number(),
4348
- consumer_remaining: z6.number(),
4349
- provider_balance: z6.number()
4350
- });
4351
- var BalanceSyncMessageSchema = z6.object({
4352
- type: z6.literal("balance_sync"),
4353
- agent_id: z6.string().min(1)
4354
- });
4355
- var BalanceSyncResponseMessageSchema = z6.object({
4356
- type: z6.literal("balance_sync_response"),
4357
- agent_id: z6.string(),
4358
- balance: z6.number()
4359
- });
4360
- var RelayMessageSchema = z6.discriminatedUnion("type", [
4361
- RegisterMessageSchema,
4362
- RegisteredMessageSchema,
4363
- RelayRequestMessageSchema,
4364
- IncomingRequestMessageSchema,
4365
- RelayResponseMessageSchema,
4366
- ResponseMessageSchema,
4367
- ErrorMessageSchema,
4368
- RelayProgressMessageSchema,
4369
- HeartbeatMessageSchema,
4370
- EscrowHoldMessageSchema,
4371
- EscrowHoldConfirmedMessageSchema,
4372
- EscrowSettleMessageSchema,
4373
- EscrowSettledMessageSchema,
4374
- BalanceSyncMessageSchema,
4375
- BalanceSyncResponseMessageSchema
4376
- ]);
4377
-
4378
4628
  // src/relay/websocket-relay.ts
4379
- import { randomUUID as randomUUID16 } from "crypto";
4629
+ import { randomUUID as randomUUID17 } from "crypto";
4380
4630
 
4381
4631
  // src/relay/relay-credit.ts
4382
4632
  function lookupCardPrice(registryDb, cardId, skillId) {
@@ -4506,10 +4756,10 @@ function settleWithNetworkFee(creditDb, escrowId, providerOwner) {
4506
4756
  }
4507
4757
 
4508
4758
  // src/hub-agent/relay-bridge.ts
4509
- import { randomUUID as randomUUID15 } from "crypto";
4759
+ import { randomUUID as randomUUID16 } from "crypto";
4510
4760
 
4511
4761
  // src/hub-agent/job-queue.ts
4512
- import { randomUUID as randomUUID14 } from "crypto";
4762
+ import { randomUUID as randomUUID15 } from "crypto";
4513
4763
  function updateJobStatus(db, jobId, status, result) {
4514
4764
  const now = (/* @__PURE__ */ new Date()).toISOString();
4515
4765
  if (result !== void 0) {
@@ -4638,7 +4888,7 @@ function registerWebSocketRelay(server, db, creditDb) {
4638
4888
  function logAgentJoined(owner, cardName, cardId) {
4639
4889
  try {
4640
4890
  insertRequestLog(db, {
4641
- id: randomUUID16(),
4891
+ id: randomUUID17(),
4642
4892
  card_id: cardId,
4643
4893
  card_name: cardName,
4644
4894
  requester: owner,
@@ -5120,312 +5370,6 @@ function registerWebSocketRelay(server, db, creditDb) {
5120
5370
  };
5121
5371
  }
5122
5372
 
5123
- // src/relay/websocket-client.ts
5124
- import WebSocket from "ws";
5125
- import { randomUUID as randomUUID17 } from "crypto";
5126
- var RelayClient = class {
5127
- ws = null;
5128
- opts;
5129
- pendingRequests = /* @__PURE__ */ new Map();
5130
- reconnectAttempts = 0;
5131
- reconnectTimer = null;
5132
- intentionalClose = false;
5133
- registered = false;
5134
- pongTimeout = null;
5135
- pingInterval = null;
5136
- constructor(opts) {
5137
- this.opts = opts;
5138
- }
5139
- /**
5140
- * Connect to the registry relay and register.
5141
- * Resolves when registration is acknowledged.
5142
- */
5143
- async connect() {
5144
- return new Promise((resolve, reject) => {
5145
- this.intentionalClose = false;
5146
- this.registered = false;
5147
- const wsUrl = this.buildWsUrl();
5148
- this.ws = new WebSocket(wsUrl);
5149
- let resolved = false;
5150
- this.ws.on("open", () => {
5151
- this.reconnectAttempts = 0;
5152
- this.startPingInterval();
5153
- this.send({
5154
- type: "register",
5155
- owner: this.opts.owner,
5156
- ...this.opts.agent_id ? { agent_id: this.opts.agent_id } : {},
5157
- ...this.opts.server_id ? { server_id: this.opts.server_id } : {},
5158
- token: this.opts.token,
5159
- card: this.opts.card,
5160
- ...this.opts.cards && this.opts.cards.length > 0 ? { cards: this.opts.cards } : {},
5161
- ...this.opts.agents && this.opts.agents.length > 0 ? { agents: this.opts.agents } : {}
5162
- });
5163
- });
5164
- this.ws.on("message", (raw) => {
5165
- this.handleMessage(raw, (err) => {
5166
- if (!resolved) {
5167
- resolved = true;
5168
- if (err) reject(err);
5169
- else resolve();
5170
- }
5171
- });
5172
- });
5173
- this.ws.on("close", () => {
5174
- this.cleanup();
5175
- if (!this.intentionalClose) {
5176
- if (!resolved) {
5177
- resolved = true;
5178
- reject(new Error("WebSocket closed before registration"));
5179
- }
5180
- this.scheduleReconnect();
5181
- }
5182
- });
5183
- this.ws.on("error", (err) => {
5184
- if (!resolved) {
5185
- resolved = true;
5186
- reject(err);
5187
- }
5188
- });
5189
- setTimeout(() => {
5190
- if (!resolved) {
5191
- resolved = true;
5192
- reject(new Error("Connection timeout"));
5193
- this.ws?.close();
5194
- }
5195
- }, 1e4);
5196
- });
5197
- }
5198
- /**
5199
- * Disconnect from the registry relay.
5200
- */
5201
- disconnect() {
5202
- this.intentionalClose = true;
5203
- this.cleanup();
5204
- if (this.ws) {
5205
- try {
5206
- this.ws.close(1e3, "Client disconnect");
5207
- } catch {
5208
- }
5209
- this.ws = null;
5210
- }
5211
- for (const [id, pending] of this.pendingRequests) {
5212
- clearTimeout(pending.timeout);
5213
- pending.reject(new Error("Client disconnected"));
5214
- this.pendingRequests.delete(id);
5215
- }
5216
- }
5217
- /**
5218
- * Send a relay request to another agent via the registry.
5219
- * @returns The result from the target agent.
5220
- */
5221
- async request(opts) {
5222
- if (!this.ws || this.ws.readyState !== WebSocket.OPEN || !this.registered) {
5223
- throw new Error("Not connected to registry relay");
5224
- }
5225
- const id = randomUUID17();
5226
- const timeoutMs = opts.timeoutMs ?? 3e5;
5227
- return new Promise((resolve, reject) => {
5228
- const timeout = setTimeout(() => {
5229
- this.pendingRequests.delete(id);
5230
- reject(new Error("Relay request timeout"));
5231
- }, timeoutMs);
5232
- this.pendingRequests.set(id, { resolve, reject, timeout, timeoutMs, onProgress: opts.onProgress });
5233
- this.send({
5234
- type: "relay_request",
5235
- id,
5236
- target_owner: opts.targetOwner,
5237
- ...opts.targetAgentId ? { target_agent_id: opts.targetAgentId } : {},
5238
- card_id: opts.cardId,
5239
- skill_id: opts.skillId,
5240
- params: opts.params,
5241
- requester: opts.requester ?? this.opts.owner,
5242
- escrow_receipt: opts.escrowReceipt
5243
- });
5244
- });
5245
- }
5246
- /**
5247
- * Send a relay_progress message to the relay server for a given request.
5248
- * Used by the onRequest handler to forward SkillExecutor progress updates
5249
- * to the requesting agent so it can reset its timeout window.
5250
- *
5251
- * @param requestId - The relay request ID to associate progress with.
5252
- * @param info - Progress details (step, total, message).
5253
- */
5254
- sendProgress(requestId, info) {
5255
- this.send({
5256
- type: "relay_progress",
5257
- id: requestId,
5258
- progress: Math.round(info.step / info.total * 100),
5259
- message: info.message
5260
- });
5261
- }
5262
- /** Whether the client is connected and registered */
5263
- get isConnected() {
5264
- return this.ws !== null && this.ws.readyState === WebSocket.OPEN && this.registered;
5265
- }
5266
- // ── Private methods ─────────────────────────────────────────────────────────
5267
- buildWsUrl() {
5268
- let url = this.opts.registryUrl;
5269
- if (url.startsWith("http://")) {
5270
- url = "ws://" + url.slice(7);
5271
- } else if (url.startsWith("https://")) {
5272
- url = "wss://" + url.slice(8);
5273
- } else if (!url.startsWith("ws://") && !url.startsWith("wss://")) {
5274
- url = "wss://" + url;
5275
- }
5276
- if (!url.endsWith("/ws")) {
5277
- url = url.replace(/\/$/, "") + "/ws";
5278
- }
5279
- return url;
5280
- }
5281
- handleMessage(raw, onRegistered) {
5282
- let data;
5283
- try {
5284
- data = JSON.parse(typeof raw === "string" ? raw : raw.toString("utf-8"));
5285
- } catch {
5286
- return;
5287
- }
5288
- const parsed = RelayMessageSchema.safeParse(data);
5289
- if (!parsed.success) return;
5290
- const msg = parsed.data;
5291
- switch (msg.type) {
5292
- case "registered":
5293
- this.registered = true;
5294
- if (!this.opts.silent) {
5295
- console.log(` \u2713 Registered with registry (agent_id: ${msg.agent_id})`);
5296
- }
5297
- onRegistered?.();
5298
- break;
5299
- case "incoming_request":
5300
- this.handleIncomingRequest(msg);
5301
- break;
5302
- case "response":
5303
- this.handleResponse(msg);
5304
- break;
5305
- case "error":
5306
- this.handleError(msg);
5307
- break;
5308
- case "relay_progress":
5309
- this.handleProgress(msg);
5310
- break;
5311
- default:
5312
- break;
5313
- }
5314
- }
5315
- async handleIncomingRequest(msg) {
5316
- try {
5317
- const result = await this.opts.onRequest(msg);
5318
- this.send({
5319
- type: "relay_response",
5320
- id: msg.id,
5321
- result: result.result,
5322
- error: result.error
5323
- });
5324
- } catch (err) {
5325
- this.send({
5326
- type: "relay_response",
5327
- id: msg.id,
5328
- error: {
5329
- code: -32603,
5330
- message: err instanceof Error ? err.message : "Internal error"
5331
- }
5332
- });
5333
- }
5334
- }
5335
- handleResponse(msg) {
5336
- const pending = this.pendingRequests.get(msg.id);
5337
- if (!pending) return;
5338
- clearTimeout(pending.timeout);
5339
- this.pendingRequests.delete(msg.id);
5340
- if (msg.error) {
5341
- pending.reject(new Error(msg.error.message));
5342
- } else {
5343
- pending.resolve(msg.result);
5344
- }
5345
- }
5346
- handleError(msg) {
5347
- if (msg.request_id) {
5348
- const pending = this.pendingRequests.get(msg.request_id);
5349
- if (pending) {
5350
- clearTimeout(pending.timeout);
5351
- this.pendingRequests.delete(msg.request_id);
5352
- pending.reject(new Error(`${msg.code}: ${msg.message}`));
5353
- }
5354
- }
5355
- }
5356
- handleProgress(msg) {
5357
- const pending = this.pendingRequests.get(msg.id);
5358
- if (!pending) return;
5359
- clearTimeout(pending.timeout);
5360
- const newTimeout = setTimeout(() => {
5361
- this.pendingRequests.delete(msg.id);
5362
- pending.reject(new Error("Relay request timeout"));
5363
- }, pending.timeoutMs);
5364
- pending.timeout = newTimeout;
5365
- if (pending.onProgress) {
5366
- pending.onProgress({ id: msg.id, progress: msg.progress, message: msg.message });
5367
- }
5368
- }
5369
- send(msg) {
5370
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
5371
- this.ws.send(JSON.stringify(msg));
5372
- }
5373
- }
5374
- startPingInterval() {
5375
- this.stopPingInterval();
5376
- this.pingInterval = setInterval(() => {
5377
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
5378
- this.ws.ping();
5379
- this.pongTimeout = setTimeout(() => {
5380
- if (!this.opts.silent) {
5381
- console.log(" \u26A0 Registry pong timeout, reconnecting...");
5382
- }
5383
- this.ws?.terminate();
5384
- }, 15e3);
5385
- }
5386
- }, 3e4);
5387
- this.ws?.on("pong", () => {
5388
- if (this.pongTimeout) {
5389
- clearTimeout(this.pongTimeout);
5390
- this.pongTimeout = null;
5391
- }
5392
- });
5393
- }
5394
- stopPingInterval() {
5395
- if (this.pingInterval) {
5396
- clearInterval(this.pingInterval);
5397
- this.pingInterval = null;
5398
- }
5399
- if (this.pongTimeout) {
5400
- clearTimeout(this.pongTimeout);
5401
- this.pongTimeout = null;
5402
- }
5403
- }
5404
- cleanup() {
5405
- this.stopPingInterval();
5406
- this.registered = false;
5407
- }
5408
- scheduleReconnect() {
5409
- if (this.intentionalClose) return;
5410
- if (this.reconnectTimer) return;
5411
- const delay = Math.min(1e3 * Math.pow(2, this.reconnectAttempts), 3e4);
5412
- this.reconnectAttempts++;
5413
- if (!this.opts.silent) {
5414
- console.log(` \u21BB Reconnecting to registry in ${delay / 1e3}s...`);
5415
- }
5416
- this.reconnectTimer = setTimeout(async () => {
5417
- this.reconnectTimer = null;
5418
- try {
5419
- await this.connect();
5420
- if (!this.opts.silent) {
5421
- console.log(" \u2713 Reconnected to registry");
5422
- }
5423
- } catch {
5424
- }
5425
- }, delay);
5426
- }
5427
- };
5428
-
5429
5373
  // src/onboarding/index.ts
5430
5374
  import { randomUUID as randomUUID19 } from "crypto";
5431
5375
  import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";