agentbnb 5.1.11 → 7.0.0-beta.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 (60) hide show
  1. package/README.md +245 -39
  2. package/dist/{card-RSGDCHCV.js → card-REW7BSWW.js} +1 -1
  3. package/dist/{chunk-FLY3WIQR.js → chunk-2HSUPCBT.js} +3 -3
  4. package/dist/{chunk-WGZ5AGOX.js → chunk-3CIMVISQ.js} +24 -1
  5. package/dist/{chunk-NH2FIERR.js → chunk-574W3HHE.js} +1 -1
  6. package/dist/{chunk-WTXRY7R2.js → chunk-APEG4QIN.js} +157 -9
  7. package/dist/chunk-BP3L2TET.js +148 -0
  8. package/dist/{chunk-NLAWT4DT.js → chunk-CWYPTQRQ.js} +7 -7
  9. package/dist/{chunk-UKT6H7YT.js → chunk-DUW6RX6I.js} +5 -2
  10. package/dist/chunk-EAD4A4KG.js +430 -0
  11. package/dist/{chunk-QT7TEVNV.js → chunk-EHSHB7TY.js} +23 -1
  12. package/dist/{chunk-B5FTAGFN.js → chunk-ETGOKDFR.js} +75 -75
  13. package/dist/{chunk-5KFI5X7B.js → chunk-F53QQIM2.js} +1 -1
  14. package/dist/{chunk-MLS6IGGG.js → chunk-FK2MDNTB.js} +117 -117
  15. package/dist/{chunk-EGUOAHCW.js → chunk-GO4FVRVN.js} +15 -13
  16. package/dist/{chunk-CRFCWD6V.js → chunk-J2K5S5MX.js} +136 -173
  17. package/dist/chunk-K5FO42YF.js +1136 -0
  18. package/dist/{chunk-DFBX3BBD.js → chunk-KA2VIEGM.js} +211 -16
  19. package/dist/chunk-NWIQJ2CL.js +108 -0
  20. package/dist/chunk-OCSU2S6W.js +168 -0
  21. package/dist/{chunk-QQFBFV4V.js → chunk-PGDBUUGR.js} +60 -19
  22. package/dist/{chunk-QITOPASZ.js → chunk-PSQHUZ7X.js} +1 -1
  23. package/dist/{chunk-C6KPAFCC.js → chunk-PU7LXOQ3.js} +23 -1
  24. package/dist/{chunk-JOY533UH.js → chunk-TW65F5EU.js} +1 -1
  25. package/dist/{chunk-ZX5623ER.js → chunk-VMH2YS2I.js} +1 -1
  26. package/dist/{chunk-XND2DWTZ.js → chunk-VPQ44XKE.js} +2 -2
  27. package/dist/{chunk-CSATDXZC.js → chunk-Y7T6IMM3.js} +1 -1
  28. package/dist/cli/index.js +755 -379
  29. package/dist/{client-T5MTY3CS.js → client-HRYRJKSA.js} +3 -3
  30. package/dist/{conduct-WU3VEXB6.js → conduct-JNYJCDHQ.js} +14 -13
  31. package/dist/conduct-KJUD2RTB.js +22 -0
  32. package/dist/{conductor-mode-ZMTFZGJP.js → conductor-mode-2VVFMKVE.js} +313 -14
  33. package/dist/conductor-mode-VGUU54QI.js +276 -0
  34. package/dist/execute-I4PKSNJM.js +12 -0
  35. package/dist/execute-MOXSSA3Q.js +15 -0
  36. package/dist/index.d.ts +795 -2
  37. package/dist/index.js +861 -111
  38. package/dist/{process-guard-CC7CNRQJ.js → process-guard-QCCBGILS.js} +1 -1
  39. package/dist/publish-capability-TS6CNR5G.js +12 -0
  40. package/dist/reliability-metrics-QG7WC5QK.js +18 -0
  41. package/dist/{request-VOXBFUOG.js → request-E7TA7COA.js} +19 -18
  42. package/dist/{serve-skill-IH7UAJNR.js → serve-skill-HIOWYKRU.js} +13 -11
  43. package/dist/{server-JVQW2TID.js → server-I63CXFX3.js} +17 -16
  44. package/dist/{service-coordinator-EYRDTHL5.js → service-coordinator-XBNT3SMU.js} +369 -260
  45. package/dist/skill-config-FETXPNVP.js +22 -0
  46. package/dist/skills/agentbnb/bootstrap.js +430 -84
  47. package/dist/websocket-client-5MH6QRJK.js +7 -0
  48. package/dist/{websocket-client-WRN3HO73.js → websocket-client-PFGVTXNE.js} +1 -1
  49. package/openclaw.plugin.json +2 -2
  50. package/package.json +2 -1
  51. package/skills/agentbnb/SKILL.md +35 -0
  52. package/skills/agentbnb/bootstrap.ts +126 -8
  53. package/skills/agentbnb/install.sh +49 -9
  54. package/dist/chunk-EANI2N2V.js +0 -309
  55. package/dist/chunk-EPIWHNB2.js +0 -946
  56. package/dist/conduct-6LKIJJKQ.js +0 -21
  57. package/dist/conductor-mode-Q4IIDY5E.js +0 -123
  58. package/dist/execute-4D4ITQCL.js +0 -10
  59. package/dist/execute-T7Y6RKSW.js +0 -13
  60. package/dist/websocket-client-6IIDGXKB.js +0 -7
package/dist/cli/index.js CHANGED
@@ -6,32 +6,54 @@ import {
6
6
  detectOpenPorts,
7
7
  discoverLocalAgents,
8
8
  getPricingStats
9
- } from "../chunk-MLS6IGGG.js";
9
+ } from "../chunk-FK2MDNTB.js";
10
10
  import {
11
11
  ensureIdentity
12
- } from "../chunk-QITOPASZ.js";
12
+ } from "../chunk-PSQHUZ7X.js";
13
+ import {
14
+ releaseRequesterEscrow,
15
+ settleRequesterEscrow
16
+ } from "../chunk-DUW6RX6I.js";
13
17
  import {
14
18
  createLedger
15
- } from "../chunk-FLY3WIQR.js";
19
+ } from "../chunk-2HSUPCBT.js";
20
+ import {
21
+ parseSoulMd
22
+ } from "../chunk-BP3L2TET.js";
16
23
  import {
17
24
  AutoRequestor,
18
25
  BudgetManager,
19
26
  DEFAULT_BUDGET_CONFIG
20
- } from "../chunk-EGUOAHCW.js";
21
- import {
22
- DEFAULT_AUTONOMY_CONFIG
23
- } from "../chunk-CSATDXZC.js";
27
+ } from "../chunk-GO4FVRVN.js";
24
28
  import {
25
29
  fetchRemoteCards,
26
30
  mergeResults
27
- } from "../chunk-ZX5623ER.js";
31
+ } from "../chunk-VMH2YS2I.js";
32
+ import {
33
+ DEFAULT_AUTONOMY_CONFIG
34
+ } from "../chunk-Y7T6IMM3.js";
28
35
  import {
29
36
  filterCards,
30
37
  searchCards
31
- } from "../chunk-NH2FIERR.js";
38
+ } from "../chunk-574W3HHE.js";
39
+ import {
40
+ bootstrapAgent,
41
+ getBalance,
42
+ getTransactions,
43
+ holdEscrow,
44
+ migrateOwner,
45
+ openCreditDb
46
+ } from "../chunk-J2K5S5MX.js";
47
+ import "../chunk-NWIQJ2CL.js";
32
48
  import {
33
49
  requestCapability
34
- } from "../chunk-XND2DWTZ.js";
50
+ } from "../chunk-VPQ44XKE.js";
51
+ import {
52
+ generateKeyPair,
53
+ loadKeyPair,
54
+ saveKeyPair,
55
+ signEscrowReceipt
56
+ } from "../chunk-F53QQIM2.js";
35
57
  import {
36
58
  findPeer,
37
59
  loadPeers,
@@ -44,42 +66,26 @@ import {
44
66
  saveConfig
45
67
  } from "../chunk-75OC6E4F.js";
46
68
  import {
47
- releaseRequesterEscrow,
48
- settleRequesterEscrow
49
- } from "../chunk-UKT6H7YT.js";
50
- import {
69
+ deleteCard,
70
+ getCard,
51
71
  insertCard,
52
72
  listCards,
53
73
  openDatabase
54
- } from "../chunk-DFBX3BBD.js";
55
- import {
56
- bootstrapAgent,
57
- getBalance,
58
- getTransactions,
59
- holdEscrow,
60
- migrateOwner,
61
- openCreditDb
62
- } from "../chunk-EANI2N2V.js";
63
- import {
64
- generateKeyPair,
65
- loadKeyPair,
66
- saveKeyPair,
67
- signEscrowReceipt
68
- } from "../chunk-5KFI5X7B.js";
74
+ } from "../chunk-KA2VIEGM.js";
69
75
  import {
70
76
  AgentBnBError,
71
77
  AnyCardSchema,
72
78
  CapabilityCardV2Schema
73
- } from "../chunk-WGZ5AGOX.js";
79
+ } from "../chunk-3CIMVISQ.js";
74
80
 
75
81
  // src/cli/index.ts
76
82
  import { Command } from "commander";
77
- import { readFileSync as readFileSync3 } from "fs";
83
+ import { readFileSync as readFileSync4 } from "fs";
78
84
  import { createRequire } from "module";
79
- import { randomBytes, randomUUID as randomUUID5 } from "crypto";
80
- import { join as join2 } from "path";
81
- import { networkInterfaces } from "os";
82
- import { createInterface as createInterface2 } from "readline";
85
+ import { randomUUID as randomUUID4 } from "crypto";
86
+ import { join as join4 } from "path";
87
+ import { networkInterfaces as networkInterfaces2 } from "os";
88
+ import { createInterface as createInterface3 } from "readline";
83
89
 
84
90
  // src/credit/escrow-receipt.ts
85
91
  import { z } from "zod";
@@ -113,9 +119,214 @@ function createSignedEscrowReceipt(db, privateKey, publicKey, opts) {
113
119
  return { escrowId, receipt };
114
120
  }
115
121
 
116
- // src/onboarding/index.ts
122
+ // src/openclaw/soul-sync.ts
117
123
  import { randomUUID as randomUUID2 } from "crypto";
118
- import { existsSync, readFileSync } from "fs";
124
+ var SKILL_META_GLOBAL_RE = /(?:^|\s)-\s*(capability_types|requires(?:_capabilities)?|visibility)\s*:\s*([^-][^]*?)(?=\s+-\s+(?:capability_types|requires(?:_capabilities)?|visibility)\s*:|$)/gi;
125
+ function extractSkillMeta(raw) {
126
+ let capability_types;
127
+ let requires_capabilities;
128
+ let visibility;
129
+ const removedRanges = [];
130
+ SKILL_META_GLOBAL_RE.lastIndex = 0;
131
+ let m;
132
+ while ((m = SKILL_META_GLOBAL_RE.exec(raw)) !== null) {
133
+ const key = m[1].toLowerCase();
134
+ const val = m[2].trim();
135
+ if (key === "capability_types") {
136
+ capability_types = val.split(",").map((v) => v.trim()).filter(Boolean);
137
+ } else if (key === "requires" || key === "requires_capabilities") {
138
+ requires_capabilities = val.split(",").map((v) => v.trim()).filter(Boolean);
139
+ } else if (key === "visibility") {
140
+ const vis = val.toLowerCase();
141
+ if (vis === "public" || vis === "private") {
142
+ visibility = vis;
143
+ }
144
+ }
145
+ removedRanges.push({ start: m.index, end: m.index + m[0].length });
146
+ }
147
+ let description = raw;
148
+ for (const { start, end } of removedRanges.slice().reverse()) {
149
+ description = description.slice(0, start) + description.slice(end);
150
+ }
151
+ description = description.trim();
152
+ return { description, capability_types, requires_capabilities, visibility };
153
+ }
154
+ function parseSoulMdV2(content) {
155
+ const parsed = parseSoulMd(content);
156
+ const skills = parsed.capabilities.map((cap) => {
157
+ const sanitizedId = cap.name.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
158
+ const id = sanitizedId.length > 0 ? sanitizedId : randomUUID2();
159
+ const { description: cleanDesc, capability_types, requires_capabilities, visibility } = extractSkillMeta(cap.description);
160
+ const finalDescription = (cleanDesc || cap.name).slice(0, 500);
161
+ const skill = {
162
+ id,
163
+ name: cap.name,
164
+ description: finalDescription,
165
+ level: 2,
166
+ inputs: [
167
+ {
168
+ name: "input",
169
+ type: "text",
170
+ description: "Input for the skill",
171
+ required: true
172
+ }
173
+ ],
174
+ outputs: [
175
+ {
176
+ name: "output",
177
+ type: "text",
178
+ description: "Output from the skill",
179
+ required: true
180
+ }
181
+ ],
182
+ pricing: { credits_per_call: cap.pricing !== void 0 ? cap.pricing : 10 },
183
+ availability: { online: true }
184
+ };
185
+ if (capability_types !== void 0) skill.capability_types = capability_types;
186
+ if (requires_capabilities !== void 0) skill.requires_capabilities = requires_capabilities;
187
+ if (visibility !== void 0) skill.visibility = visibility;
188
+ return skill;
189
+ });
190
+ return {
191
+ agentName: parsed.name || "Unknown Agent",
192
+ description: parsed.description,
193
+ skills
194
+ };
195
+ }
196
+ function publishFromSoulV2(db, soulContent, owner, sharedSkills) {
197
+ const { agentName, skills: allSkills } = parseSoulMdV2(soulContent);
198
+ const skills = allSkills.filter((skill) => {
199
+ if (sharedSkills && sharedSkills.length > 0) {
200
+ return sharedSkills.includes(skill.id);
201
+ }
202
+ return skill.visibility !== "private";
203
+ });
204
+ if (skills.length === 0) {
205
+ throw new AgentBnBError("SOUL.md has no H2 sections", "VALIDATION_ERROR");
206
+ }
207
+ const existingCards = listCards(db, owner);
208
+ const existingV2 = existingCards.find(
209
+ (c) => c.spec_version === "2.0"
210
+ );
211
+ const now = (/* @__PURE__ */ new Date()).toISOString();
212
+ const cardId = existingV2?.id ?? randomUUID2();
213
+ const card = {
214
+ spec_version: "2.0",
215
+ id: cardId,
216
+ owner,
217
+ agent_name: agentName,
218
+ skills,
219
+ availability: { online: true },
220
+ created_at: existingV2?.created_at ?? now,
221
+ updated_at: now
222
+ };
223
+ CapabilityCardV2Schema.parse(card);
224
+ if (existingV2) {
225
+ db.prepare(
226
+ "UPDATE capability_cards SET data = ?, updated_at = ? WHERE id = ?"
227
+ ).run(JSON.stringify(card), now, cardId);
228
+ } else {
229
+ db.prepare(
230
+ "INSERT INTO capability_cards (id, owner, data, created_at, updated_at) VALUES (?, ?, ?, ?, ?)"
231
+ ).run(cardId, owner, JSON.stringify(card), now, now);
232
+ }
233
+ return card;
234
+ }
235
+
236
+ // src/openclaw/heartbeat-writer.ts
237
+ import { readFileSync, writeFileSync, existsSync } from "fs";
238
+ var HEARTBEAT_MARKER_START = "<!-- agentbnb:start -->";
239
+ var HEARTBEAT_MARKER_END = "<!-- agentbnb:end -->";
240
+ function generateHeartbeatSection(autonomy, budget) {
241
+ const t1 = autonomy.tier1_max_credits;
242
+ const t2 = autonomy.tier2_max_credits;
243
+ const reserve = budget.reserve_credits;
244
+ return [
245
+ HEARTBEAT_MARKER_START,
246
+ "## AgentBnB Protocol",
247
+ "",
248
+ "You are a participant in the AgentBnB capability sharing network.",
249
+ "",
250
+ "### Sharing Rules",
251
+ "- When your idle_rate exceeds 70%, automatically share idle capabilities",
252
+ "- Accept incoming requests that match your published Capability Card",
253
+ "- Track credit earnings and report to owner weekly",
254
+ "",
255
+ "### Requesting Rules",
256
+ "- When you encounter a task you cannot complete with local skills:",
257
+ " 1. Query AgentBnB network for matching capabilities",
258
+ " 2. If found and credit sufficient, automatically request",
259
+ " 3. Integrate result into your current workflow",
260
+ "- Budget limits:",
261
+ ` - < ${t1} credits: auto-execute, no notification`,
262
+ ` - ${t1}-${t2} credits: execute, notify owner after`,
263
+ ` - > ${t2} credits: ask owner before executing`,
264
+ "",
265
+ "### Credit Management",
266
+ `- Maintain minimum balance of ${reserve} credits (reserve for emergencies)`,
267
+ `- If balance drops below ${reserve}, increase sharing priority`,
268
+ "- If balance exceeds 500, notify owner of surplus",
269
+ HEARTBEAT_MARKER_END
270
+ ].join("\n");
271
+ }
272
+ function injectHeartbeatSection(heartbeatPath, section) {
273
+ if (!existsSync(heartbeatPath)) {
274
+ writeFileSync(heartbeatPath, section + "\n", "utf-8");
275
+ return;
276
+ }
277
+ let content = readFileSync(heartbeatPath, "utf-8");
278
+ const startIdx = content.indexOf(HEARTBEAT_MARKER_START);
279
+ const endIdx = content.indexOf(HEARTBEAT_MARKER_END);
280
+ if (startIdx !== -1 && endIdx !== -1) {
281
+ content = content.slice(0, startIdx) + section + content.slice(endIdx + HEARTBEAT_MARKER_END.length);
282
+ } else {
283
+ content = content + "\n" + section + "\n";
284
+ }
285
+ writeFileSync(heartbeatPath, content, "utf-8");
286
+ }
287
+
288
+ // src/openclaw/skill.ts
289
+ function getOpenClawStatus(config, db, creditDb) {
290
+ const autonomy = config.autonomy ?? DEFAULT_AUTONOMY_CONFIG;
291
+ const budget = config.budget ?? DEFAULT_BUDGET_CONFIG;
292
+ const balance = getBalance(creditDb, config.owner);
293
+ const allCards = listCards(db, config.owner);
294
+ const skills = [];
295
+ for (const card of allCards) {
296
+ const anyCard = card;
297
+ if (anyCard.spec_version !== "2.0" || !Array.isArray(anyCard.skills)) continue;
298
+ for (const skill of anyCard.skills) {
299
+ const internal = skill["_internal"] ?? {};
300
+ const idleRate = typeof internal["idle_rate"] === "number" ? internal["idle_rate"] : null;
301
+ const availability = skill["availability"];
302
+ const online = availability?.online ?? false;
303
+ skills.push({
304
+ id: String(skill["id"] ?? ""),
305
+ name: String(skill["name"] ?? ""),
306
+ idle_rate: idleRate,
307
+ online
308
+ });
309
+ }
310
+ }
311
+ return {
312
+ installed: true,
313
+ owner: config.owner,
314
+ gateway_url: config.gateway_url,
315
+ tier: autonomy,
316
+ balance,
317
+ reserve: budget.reserve_credits,
318
+ skills
319
+ };
320
+ }
321
+
322
+ // src/cli/init-action.ts
323
+ import { randomBytes } from "crypto";
324
+ import { join as join2 } from "path";
325
+ import { networkInterfaces } from "os";
326
+
327
+ // src/onboarding/index.ts
328
+ import { randomUUID as randomUUID3 } from "crypto";
329
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
119
330
  import { join } from "path";
120
331
 
121
332
  // src/onboarding/capability-templates.ts
@@ -232,8 +443,8 @@ function detectCapabilities(opts = {}) {
232
443
  const cwd = opts.cwd ?? process.cwd();
233
444
  if (opts.fromFile) {
234
445
  const filePath = opts.fromFile.startsWith("/") ? opts.fromFile : join(cwd, opts.fromFile);
235
- if (existsSync(filePath)) {
236
- const content = readFileSync(filePath, "utf-8");
446
+ if (existsSync2(filePath)) {
447
+ const content = readFileSync2(filePath, "utf-8");
237
448
  const capabilities = detectFromDocs(content);
238
449
  if (capabilities.length > 0) {
239
450
  return { source: "docs", capabilities, sourceFile: filePath };
@@ -243,8 +454,8 @@ function detectCapabilities(opts = {}) {
243
454
  }
244
455
  for (const fileName of DOC_FILES) {
245
456
  const filePath = join(cwd, fileName);
246
- if (!existsSync(filePath)) continue;
247
- const content = readFileSync(filePath, "utf-8");
457
+ if (!existsSync2(filePath)) continue;
458
+ const content = readFileSync2(filePath, "utf-8");
248
459
  if (fileName === "SOUL.md") {
249
460
  return { source: "soul", capabilities: [], soulContent: content, sourceFile: filePath };
250
461
  }
@@ -253,285 +464,43 @@ function detectCapabilities(opts = {}) {
253
464
  return { source: "docs", capabilities, sourceFile: filePath };
254
465
  }
255
466
  }
256
- const envKeys = detectApiKeys(KNOWN_API_KEYS);
257
- if (envKeys.length > 0) {
258
- return { source: "env", capabilities: [], envKeys };
259
- }
260
- return { source: "none", capabilities: [] };
261
- }
262
- function capabilitiesToV2Card(capabilities, owner, agentName) {
263
- const now = (/* @__PURE__ */ new Date()).toISOString();
264
- const skills = capabilities.map((cap) => ({
265
- id: cap.key,
266
- name: cap.name,
267
- description: `${cap.name} capability \u2014 ${cap.category}`,
268
- level: 1,
269
- category: cap.category.toLowerCase().replace(/\s+/g, "_"),
270
- inputs: [{ name: "input", type: "text", required: true }],
271
- outputs: [{ name: "output", type: "text", required: true }],
272
- pricing: { credits_per_call: cap.credits_per_call },
273
- availability: { online: true },
274
- metadata: {
275
- tags: cap.tags
276
- }
277
- }));
278
- const card = {
279
- spec_version: "2.0",
280
- id: randomUUID2(),
281
- owner,
282
- agent_name: agentName ?? owner,
283
- skills,
284
- availability: { online: true },
285
- created_at: now,
286
- updated_at: now
287
- };
288
- return CapabilityCardV2Schema.parse(card);
289
- }
290
-
291
- // src/openclaw/soul-sync.ts
292
- import { randomUUID as randomUUID4 } from "crypto";
293
-
294
- // src/skills/publish-capability.ts
295
- import { randomUUID as randomUUID3 } from "crypto";
296
- function parseSoulMd(content) {
297
- const lines = content.split("\n");
298
- let name = "";
299
- let description = "";
300
- const capabilities = [];
301
- const unknownSections = [];
302
- let currentSection = null;
303
- let currentCapabilityName = "";
304
- let currentCapabilityLines = [];
305
- let currentCapabilityPricing = void 0;
306
- let descriptionLines = [];
307
- let pastFirstH1 = false;
308
- let pastFirstH2 = false;
309
- const flushCapability = () => {
310
- if (currentCapabilityName) {
311
- const cap = {
312
- name: currentCapabilityName,
313
- description: currentCapabilityLines.join(" ").trim()
314
- };
315
- if (currentCapabilityPricing !== void 0) {
316
- cap.pricing = currentCapabilityPricing;
317
- }
318
- capabilities.push(cap);
319
- currentCapabilityName = "";
320
- currentCapabilityLines = [];
321
- currentCapabilityPricing = void 0;
322
- }
323
- };
324
- for (const line of lines) {
325
- const trimmed = line.trim();
326
- if (/^# /.test(trimmed) && !pastFirstH1) {
327
- name = trimmed.slice(2).trim();
328
- pastFirstH1 = true;
329
- currentSection = "preamble";
330
- continue;
331
- }
332
- if (/^## /.test(trimmed)) {
333
- flushCapability();
334
- const capName = trimmed.slice(3).trim();
335
- currentCapabilityName = capName;
336
- currentSection = "capability";
337
- pastFirstH2 = true;
338
- continue;
339
- }
340
- if (/^#{3,} /.test(trimmed)) {
341
- const sectionName = trimmed.replace(/^#+\s*/, "");
342
- if (!unknownSections.includes(sectionName)) {
343
- unknownSections.push(sectionName);
344
- }
345
- continue;
346
- }
347
- if (trimmed === "") continue;
348
- if (currentSection === "preamble" && !pastFirstH2) {
349
- descriptionLines.push(trimmed);
350
- } else if (currentSection === "capability") {
351
- const pricingMatch = trimmed.match(/^pricing:\s*(\d+(?:\.\d+)?)$/i);
352
- if (pricingMatch) {
353
- const val = parseFloat(pricingMatch[1]);
354
- if (!isNaN(val) && val >= 0) {
355
- currentCapabilityPricing = val;
356
- }
357
- } else {
358
- currentCapabilityLines.push(trimmed);
359
- }
360
- }
361
- }
362
- flushCapability();
363
- if (descriptionLines.length > 0) {
364
- description = descriptionLines[0] ?? "";
365
- }
366
- return {
367
- name,
368
- description,
369
- level: 2,
370
- capabilities,
371
- unknownSections
372
- };
373
- }
374
-
375
- // src/openclaw/soul-sync.ts
376
- function parseSoulMdV2(content) {
377
- const parsed = parseSoulMd(content);
378
- const skills = parsed.capabilities.map((cap) => {
379
- const sanitizedId = cap.name.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
380
- const id = sanitizedId.length > 0 ? sanitizedId : randomUUID4();
381
- return {
382
- id,
383
- name: cap.name,
384
- description: (cap.description.slice(0, 500) || cap.name).slice(0, 500),
385
- level: 2,
386
- inputs: [
387
- {
388
- name: "input",
389
- type: "text",
390
- description: "Input for the skill",
391
- required: true
392
- }
393
- ],
394
- outputs: [
395
- {
396
- name: "output",
397
- type: "text",
398
- description: "Output from the skill",
399
- required: true
400
- }
401
- ],
402
- pricing: { credits_per_call: cap.pricing !== void 0 ? cap.pricing : 10 },
403
- availability: { online: true }
404
- };
405
- });
406
- return {
407
- agentName: parsed.name || "Unknown Agent",
408
- description: parsed.description,
409
- skills
410
- };
411
- }
412
- function publishFromSoulV2(db, soulContent, owner) {
413
- const { agentName, skills } = parseSoulMdV2(soulContent);
414
- if (skills.length === 0) {
415
- throw new AgentBnBError("SOUL.md has no H2 sections", "VALIDATION_ERROR");
416
- }
417
- const existingCards = listCards(db, owner);
418
- const existingV2 = existingCards.find(
419
- (c) => c.spec_version === "2.0"
420
- );
421
- const now = (/* @__PURE__ */ new Date()).toISOString();
422
- const cardId = existingV2?.id ?? randomUUID4();
423
- const card = {
424
- spec_version: "2.0",
425
- id: cardId,
426
- owner,
427
- agent_name: agentName,
428
- skills,
429
- availability: { online: true },
430
- created_at: existingV2?.created_at ?? now,
431
- updated_at: now
432
- };
433
- CapabilityCardV2Schema.parse(card);
434
- if (existingV2) {
435
- db.prepare(
436
- "UPDATE capability_cards SET data = ?, updated_at = ? WHERE id = ?"
437
- ).run(JSON.stringify(card), now, cardId);
438
- } else {
439
- db.prepare(
440
- "INSERT INTO capability_cards (id, owner, data, created_at, updated_at) VALUES (?, ?, ?, ?, ?)"
441
- ).run(cardId, owner, JSON.stringify(card), now, now);
442
- }
443
- return card;
444
- }
445
-
446
- // src/openclaw/heartbeat-writer.ts
447
- import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync2 } from "fs";
448
- var HEARTBEAT_MARKER_START = "<!-- agentbnb:start -->";
449
- var HEARTBEAT_MARKER_END = "<!-- agentbnb:end -->";
450
- function generateHeartbeatSection(autonomy, budget) {
451
- const t1 = autonomy.tier1_max_credits;
452
- const t2 = autonomy.tier2_max_credits;
453
- const reserve = budget.reserve_credits;
454
- return [
455
- HEARTBEAT_MARKER_START,
456
- "## AgentBnB Protocol",
457
- "",
458
- "You are a participant in the AgentBnB capability sharing network.",
459
- "",
460
- "### Sharing Rules",
461
- "- When your idle_rate exceeds 70%, automatically share idle capabilities",
462
- "- Accept incoming requests that match your published Capability Card",
463
- "- Track credit earnings and report to owner weekly",
464
- "",
465
- "### Requesting Rules",
466
- "- When you encounter a task you cannot complete with local skills:",
467
- " 1. Query AgentBnB network for matching capabilities",
468
- " 2. If found and credit sufficient, automatically request",
469
- " 3. Integrate result into your current workflow",
470
- "- Budget limits:",
471
- ` - < ${t1} credits: auto-execute, no notification`,
472
- ` - ${t1}-${t2} credits: execute, notify owner after`,
473
- ` - > ${t2} credits: ask owner before executing`,
474
- "",
475
- "### Credit Management",
476
- `- Maintain minimum balance of ${reserve} credits (reserve for emergencies)`,
477
- `- If balance drops below ${reserve}, increase sharing priority`,
478
- "- If balance exceeds 500, notify owner of surplus",
479
- HEARTBEAT_MARKER_END
480
- ].join("\n");
481
- }
482
- function injectHeartbeatSection(heartbeatPath, section) {
483
- if (!existsSync2(heartbeatPath)) {
484
- writeFileSync(heartbeatPath, section + "\n", "utf-8");
485
- return;
486
- }
487
- let content = readFileSync2(heartbeatPath, "utf-8");
488
- const startIdx = content.indexOf(HEARTBEAT_MARKER_START);
489
- const endIdx = content.indexOf(HEARTBEAT_MARKER_END);
490
- if (startIdx !== -1 && endIdx !== -1) {
491
- content = content.slice(0, startIdx) + section + content.slice(endIdx + HEARTBEAT_MARKER_END.length);
492
- } else {
493
- content = content + "\n" + section + "\n";
467
+ const envKeys = detectApiKeys(KNOWN_API_KEYS);
468
+ if (envKeys.length > 0) {
469
+ return { source: "env", capabilities: [], envKeys };
494
470
  }
495
- writeFileSync(heartbeatPath, content, "utf-8");
471
+ return { source: "none", capabilities: [] };
496
472
  }
497
-
498
- // src/openclaw/skill.ts
499
- function getOpenClawStatus(config, db, creditDb) {
500
- const autonomy = config.autonomy ?? DEFAULT_AUTONOMY_CONFIG;
501
- const budget = config.budget ?? DEFAULT_BUDGET_CONFIG;
502
- const balance = getBalance(creditDb, config.owner);
503
- const allCards = listCards(db, config.owner);
504
- const skills = [];
505
- for (const card of allCards) {
506
- const anyCard = card;
507
- if (anyCard.spec_version !== "2.0" || !Array.isArray(anyCard.skills)) continue;
508
- for (const skill of anyCard.skills) {
509
- const internal = skill["_internal"] ?? {};
510
- const idleRate = typeof internal["idle_rate"] === "number" ? internal["idle_rate"] : null;
511
- const availability = skill["availability"];
512
- const online = availability?.online ?? false;
513
- skills.push({
514
- id: String(skill["id"] ?? ""),
515
- name: String(skill["name"] ?? ""),
516
- idle_rate: idleRate,
517
- online
518
- });
473
+ function capabilitiesToV2Card(capabilities, owner, agentName) {
474
+ const now = (/* @__PURE__ */ new Date()).toISOString();
475
+ const skills = capabilities.map((cap) => ({
476
+ id: cap.key,
477
+ name: cap.name,
478
+ description: `${cap.name} capability \u2014 ${cap.category}`,
479
+ level: 1,
480
+ category: cap.category.toLowerCase().replace(/\s+/g, "_"),
481
+ inputs: [{ name: "input", type: "text", required: true }],
482
+ outputs: [{ name: "output", type: "text", required: true }],
483
+ pricing: { credits_per_call: cap.credits_per_call },
484
+ availability: { online: true },
485
+ metadata: {
486
+ tags: cap.tags
519
487
  }
520
- }
521
- return {
522
- installed: true,
523
- owner: config.owner,
524
- gateway_url: config.gateway_url,
525
- tier: autonomy,
526
- balance,
527
- reserve: budget.reserve_credits,
528
- skills
488
+ }));
489
+ const card = {
490
+ spec_version: "2.0",
491
+ id: randomUUID3(),
492
+ owner,
493
+ agent_name: agentName ?? owner,
494
+ skills,
495
+ availability: { online: true },
496
+ created_at: now,
497
+ updated_at: now
529
498
  };
499
+ return CapabilityCardV2Schema.parse(card);
530
500
  }
531
501
 
532
- // src/cli/index.ts
533
- var require2 = createRequire(import.meta.url);
534
- var pkg = require2("../../package.json");
502
+ // src/cli/init-action.ts
503
+ import { createInterface as createInterface2 } from "readline";
535
504
  async function confirm(question) {
536
505
  const rl = createInterface2({ input: process.stdin, output: process.stdout });
537
506
  try {
@@ -544,6 +513,15 @@ async function confirm(question) {
544
513
  rl.close();
545
514
  }
546
515
  }
516
+ function getLanIp() {
517
+ const nets = networkInterfaces();
518
+ for (const ifaces of Object.values(nets)) {
519
+ for (const iface of ifaces ?? []) {
520
+ if (iface.family === "IPv4" && !iface.internal) return iface.address;
521
+ }
522
+ }
523
+ return "localhost";
524
+ }
547
525
  function loadIdentityAuth(owner) {
548
526
  const configDir = getConfigDir();
549
527
  let keys;
@@ -560,41 +538,25 @@ function loadIdentityAuth(owner) {
560
538
  privateKey: keys.privateKey
561
539
  };
562
540
  }
563
- function getLanIp() {
564
- const nets = networkInterfaces();
565
- for (const ifaces of Object.values(nets)) {
566
- for (const iface of ifaces ?? []) {
567
- if (iface.family === "IPv4" && !iface.internal) return iface.address;
568
- }
569
- }
570
- return "localhost";
571
- }
572
- var program = new Command();
573
- program.name("agentbnb").description("P2P Agent Capability Sharing Protocol \u2014 Airbnb for AI agent pipelines").version(pkg.version);
574
- program.command("init").description("Initialize AgentBnB config and create agent identity").option("--owner <name>", "Agent owner name").option("--agent-id <id>", "Agent identity (alias for --owner, for genesis-template compat)").option("--port <port>", "Gateway port", "7700").option("--host <ip>", "Override gateway host IP (default: auto-detected LAN IP)").option("--yes", "Auto-confirm all draft cards (non-interactive)").option("--non-interactive", "Non-interactive mode (alias for --yes)").option("--no-detect", "Skip API key detection").option("--from <file>", "Parse a specific file for capability detection").option("--json", "Output as JSON").action(async (opts) => {
541
+ async function performInit(opts) {
575
542
  const configDir = getConfigDir();
576
543
  const dbPath = join2(configDir, "registry.db");
577
544
  const creditDbPath = join2(configDir, "credit.db");
578
545
  const port = parseInt(opts.port, 10);
579
546
  const ip = opts.host ?? getLanIp();
580
547
  const yesMode = opts.yes ?? opts.nonInteractive ?? false;
581
- opts.yes = yesMode;
582
548
  const existingConfig = loadConfig();
583
549
  const owner = opts.agentId ?? opts.owner ?? existingConfig?.owner ?? `agent-${randomBytes(4).toString("hex")}`;
584
550
  const config = {
585
551
  ...existingConfig,
586
- // Preserve all existing keys (registry, autonomy, budget, etc.)
587
552
  owner,
588
553
  gateway_url: `http://${ip}:${port}`,
589
554
  gateway_port: port,
590
555
  db_path: dbPath,
591
556
  credit_db_path: creditDbPath,
592
557
  token: existingConfig?.token ?? randomBytes(32).toString("hex"),
593
- // Preserve existing token
594
558
  api_key: existingConfig?.api_key ?? randomBytes(32).toString("hex"),
595
- // Default registry for fresh installs: auto-set in --yes (automated) mode only.
596
- // Interactive init leaves registry unset so users can configure it explicitly.
597
- ...existingConfig?.registry ? { registry: existingConfig.registry } : opts.yes ? { registry: "https://agentbnb.fly.dev" } : {}
559
+ ...existingConfig?.registry ? { registry: existingConfig.registry } : yesMode ? { registry: "https://agentbnb.fly.dev" } : {}
598
560
  };
599
561
  saveConfig(config);
600
562
  let keypairStatus = "existing";
@@ -700,12 +662,12 @@ program.command("init").description("Initialize AgentBnB config and create agent
700
662
  }
701
663
  }
702
664
  const card = capabilitiesToV2Card(result.capabilities, owner);
703
- if (opts.yes) {
665
+ if (yesMode) {
704
666
  const db = openDatabase(dbPath);
705
667
  try {
706
668
  db.prepare(
707
669
  `INSERT OR REPLACE INTO capability_cards (id, owner, data, created_at, updated_at)
708
- VALUES (?, ?, ?, ?, ?)`
670
+ VALUES (?, ?, ?, ?, ?)`
709
671
  ).run(card.id, card.owner, JSON.stringify(card), card.created_at, card.updated_at);
710
672
  publishedCards.push({ id: card.id, name: card.agent_name });
711
673
  if (!opts.json) {
@@ -722,7 +684,7 @@ Publish these ${card.skills.length} capabilities? [y/N] `);
722
684
  try {
723
685
  db.prepare(
724
686
  `INSERT OR REPLACE INTO capability_cards (id, owner, data, created_at, updated_at)
725
- VALUES (?, ?, ?, ?, ?)`
687
+ VALUES (?, ?, ?, ?, ?)`
726
688
  ).run(card.id, card.owner, JSON.stringify(card), card.created_at, card.updated_at);
727
689
  publishedCards.push({ id: card.id, name: card.agent_name });
728
690
  console.log(` Published v2.0 card: ${card.agent_name} (${card.skills.length} skills)`);
@@ -747,7 +709,7 @@ Publish these ${card.skills.length} capabilities? [y/N] `);
747
709
  console.log(` Found services on ports: ${detectedPorts.join(", ")}`);
748
710
  }
749
711
  const drafts = detectedKeys.map((key) => buildDraftCard(key, owner)).filter((card) => card !== null);
750
- if (opts.yes) {
712
+ if (yesMode) {
751
713
  const db = openDatabase(dbPath);
752
714
  try {
753
715
  for (const card of drafts) {
@@ -782,7 +744,7 @@ Publish these ${card.skills.length} capabilities? [y/N] `);
782
744
  }
783
745
  }
784
746
  } else {
785
- if (process.stdout.isTTY && !opts.yes && !opts.json) {
747
+ if (process.stdout.isTTY && !yesMode && !opts.json) {
786
748
  const selected = await interactiveTemplateMenu();
787
749
  if (selected.length > 0) {
788
750
  const card = capabilitiesToV2Card(selected, owner);
@@ -790,7 +752,7 @@ Publish these ${card.skills.length} capabilities? [y/N] `);
790
752
  try {
791
753
  db.prepare(
792
754
  `INSERT OR REPLACE INTO capability_cards (id, owner, data, created_at, updated_at)
793
- VALUES (?, ?, ?, ?, ?)`
755
+ VALUES (?, ?, ?, ?, ?)`
794
756
  ).run(card.id, card.owner, JSON.stringify(card), card.created_at, card.updated_at);
795
757
  publishedCards.push({ id: card.id, name: card.agent_name });
796
758
  console.log(`
@@ -804,36 +766,277 @@ Publish these ${card.skills.length} capabilities? [y/N] `);
804
766
  }
805
767
  }
806
768
  }
769
+ return {
770
+ config,
771
+ owner,
772
+ configDir,
773
+ publishedCards,
774
+ registryBalance,
775
+ identity: { agent_id: identity.agent_id },
776
+ keypairStatus,
777
+ detectedSource
778
+ };
779
+ }
780
+
781
+ // src/cli/quickstart.ts
782
+ import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
783
+ import { join as join3 } from "path";
784
+ import { homedir } from "os";
785
+ import { execSync } from "child_process";
786
+ var SKILLS_YAML_TEMPLATE = `skills:
787
+ # General-purpose AI task execution via Claude Code CLI
788
+ - id: claude-code-run
789
+ type: command
790
+ name: Claude Code Task Runner
791
+ description: "Execute any text-based AI task via Claude Code"
792
+ command: claude -p "\${params.prompt}"
793
+ output_type: text
794
+ allowed_commands:
795
+ - claude
796
+ timeout_ms: 180000
797
+ pricing:
798
+ credits_per_call: 5
799
+
800
+ # Code review skill
801
+ - id: claude-code-review
802
+ type: command
803
+ name: Code Review
804
+ description: "Review code for bugs, style, and improvements"
805
+ command: claude -p "Review this code for bugs, style issues, and improvements:\\n\\n\${params.code}"
806
+ output_type: text
807
+ allowed_commands:
808
+ - claude
809
+ timeout_ms: 120000
810
+ pricing:
811
+ credits_per_call: 3
812
+
813
+ # Text summarization skill
814
+ - id: claude-code-summarize
815
+ type: command
816
+ name: Text Summarizer
817
+ description: "Summarize long text into concise key points"
818
+ command: claude -p "Summarize the following text into concise key points:\\n\\n\${params.text}"
819
+ output_type: text
820
+ allowed_commands:
821
+ - claude
822
+ timeout_ms: 120000
823
+ pricing:
824
+ credits_per_call: 2
825
+ `;
826
+ function generateSkillsYaml(configDir) {
827
+ const skillsPath = join3(configDir, "skills.yaml");
828
+ if (existsSync3(skillsPath)) {
829
+ const content = readFileSync3(skillsPath, "utf-8");
830
+ const matches = content.match(/^\s+-\s+id:/gm);
831
+ return { generated: false, path: skillsPath, skillCount: matches?.length ?? 0 };
832
+ }
833
+ writeFileSync2(skillsPath, SKILLS_YAML_TEMPLATE, "utf-8");
834
+ return { generated: true, path: skillsPath, skillCount: 3 };
835
+ }
836
+ function registerMcpWithClaudeCode() {
837
+ const claudeDir = join3(homedir(), ".claude");
838
+ if (!existsSync3(claudeDir)) {
839
+ return {
840
+ registered: false,
841
+ reason: "Claude Code not detected. Add MCP manually: claude mcp add agentbnb -- agentbnb mcp-server"
842
+ };
843
+ }
844
+ const settingsPath = join3(claudeDir, "settings.json");
845
+ let agentbnbCommand = "agentbnb";
846
+ try {
847
+ const resolved = execSync("which agentbnb", { encoding: "utf-8" }).trim();
848
+ if (resolved) agentbnbCommand = resolved;
849
+ } catch {
850
+ }
851
+ let settings = {};
852
+ if (existsSync3(settingsPath)) {
853
+ try {
854
+ settings = JSON.parse(readFileSync3(settingsPath, "utf-8"));
855
+ } catch {
856
+ try {
857
+ writeFileSync2(`${settingsPath}.bak`, readFileSync3(settingsPath, "utf-8"), "utf-8");
858
+ } catch {
859
+ }
860
+ settings = {};
861
+ }
862
+ }
863
+ const mcpServers = settings.mcpServers ?? {};
864
+ if (mcpServers.agentbnb) {
865
+ return { registered: false, path: settingsPath, reason: "already registered" };
866
+ }
867
+ mcpServers.agentbnb = {
868
+ command: agentbnbCommand,
869
+ args: ["mcp-server"]
870
+ };
871
+ settings.mcpServers = mcpServers;
872
+ writeFileSync2(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
873
+ return { registered: true, path: settingsPath };
874
+ }
875
+ async function runQuickstart(opts) {
876
+ const jsonMode = opts.json ?? false;
877
+ const skipServe = opts.serve === false;
878
+ const skipMcp = opts.mcp === false;
879
+ if (!jsonMode) console.log("Initializing AgentBnB...");
880
+ const initResult = await performInit({
881
+ owner: opts.owner,
882
+ port: opts.port,
883
+ yes: true,
884
+ detect: true,
885
+ json: false
886
+ // We handle output ourselves
887
+ });
888
+ const skills = generateSkillsYaml(initResult.configDir);
889
+ if (!jsonMode) {
890
+ if (skills.generated) {
891
+ console.log(`
892
+ Generated skills.yaml with ${skills.skillCount} Claude Code skills`);
893
+ } else {
894
+ console.log(`
895
+ Skills: ${skills.skillCount} skill(s) in ${skills.path}`);
896
+ }
897
+ }
898
+ let mcpResult = { registered: false, reason: "skipped" };
899
+ if (!skipMcp) {
900
+ mcpResult = registerMcpWithClaudeCode();
901
+ if (!jsonMode) {
902
+ if (mcpResult.registered) {
903
+ console.log(`MCP: registered in ${mcpResult.path}`);
904
+ } else if (mcpResult.reason === "already registered") {
905
+ console.log(`MCP: already registered in ${mcpResult.path}`);
906
+ } else {
907
+ console.log(`MCP: ${mcpResult.reason}`);
908
+ }
909
+ }
910
+ }
911
+ let daemonStatus = { running: false, reason: "skipped" };
912
+ if (!skipServe) {
913
+ try {
914
+ const { ProcessGuard } = await import("../process-guard-QCCBGILS.js");
915
+ const { ServiceCoordinator } = await import("../service-coordinator-XBNT3SMU.js");
916
+ const guard = new ProcessGuard(join3(initResult.configDir, ".pid"));
917
+ const coordinator = new ServiceCoordinator(initResult.config, guard);
918
+ const result = await coordinator.ensureRunning({
919
+ port: initResult.config.gateway_port,
920
+ skillsYamlPath: join3(initResult.configDir, "skills.yaml"),
921
+ registryUrl: initResult.config.registry,
922
+ relay: true
923
+ });
924
+ if (result === "already_running") {
925
+ daemonStatus = { running: true, reason: "already running" };
926
+ } else {
927
+ const meta = guard.getRunningMeta();
928
+ daemonStatus = { running: true, pid: meta?.pid };
929
+ }
930
+ if (!jsonMode) {
931
+ if (result === "already_running") {
932
+ console.log(`Daemon: already running`);
933
+ } else {
934
+ console.log(`Daemon: started (pid ${daemonStatus.pid ?? "unknown"})`);
935
+ }
936
+ }
937
+ } catch (err) {
938
+ daemonStatus = { running: false, reason: err.message };
939
+ if (!jsonMode) {
940
+ console.warn(`Daemon: failed to start \u2014 ${err.message}`);
941
+ console.warn(` Start manually with: agentbnb serve`);
942
+ }
943
+ }
944
+ }
945
+ if (jsonMode) {
946
+ console.log(JSON.stringify({
947
+ success: true,
948
+ owner: initResult.owner,
949
+ config_dir: initResult.configDir,
950
+ gateway_url: initResult.config.gateway_url,
951
+ registry: initResult.config.registry,
952
+ credits: initResult.registryBalance ?? 100,
953
+ skills: { count: skills.skillCount, generated: skills.generated, path: skills.path },
954
+ mcp: mcpResult,
955
+ daemon: daemonStatus,
956
+ published_cards: initResult.publishedCards
957
+ }, null, 2));
958
+ } else {
959
+ console.log("\n--- AgentBnB quickstart complete! ---\n");
960
+ console.log(` Owner: ${initResult.owner}`);
961
+ console.log(` Gateway: ${initResult.config.gateway_url}`);
962
+ console.log(` Credits: ${initResult.registryBalance ?? 100}`);
963
+ console.log(` Registry: ${initResult.config.registry ?? "not configured"}`);
964
+ console.log(` Skills: ${skills.skillCount} loaded`);
965
+ console.log(` MCP: ${mcpResult.registered ? "registered" : mcpResult.reason}`);
966
+ console.log(` Daemon: ${daemonStatus.running ? `running${daemonStatus.pid ? ` (pid ${daemonStatus.pid})` : ""}` : `not running \u2014 ${daemonStatus.reason}`}`);
967
+ console.log("");
968
+ console.log(" You are now both a consumer and provider on AgentBnB.");
969
+ console.log("");
970
+ console.log(" Consumer: In Claude Code, use agentbnb_discover and agentbnb_request");
971
+ console.log(" Provider: Your claude -p skills are live and accepting requests");
972
+ console.log(` Dashboard: http://localhost:7701/hub/#/myagent`);
973
+ }
974
+ }
975
+
976
+ // src/cli/index.ts
977
+ var require2 = createRequire(import.meta.url);
978
+ var pkg = require2("../../package.json");
979
+ function loadIdentityAuth2(owner) {
980
+ const configDir = getConfigDir();
981
+ let keys;
982
+ try {
983
+ keys = loadKeyPair(configDir);
984
+ } catch {
985
+ keys = generateKeyPair();
986
+ saveKeyPair(configDir, keys);
987
+ }
988
+ const identity = ensureIdentity(configDir, owner);
989
+ return {
990
+ agentId: identity.agent_id,
991
+ publicKey: identity.public_key,
992
+ privateKey: keys.privateKey
993
+ };
994
+ }
995
+ function getLanIp2() {
996
+ const nets = networkInterfaces2();
997
+ for (const ifaces of Object.values(nets)) {
998
+ for (const iface of ifaces ?? []) {
999
+ if (iface.family === "IPv4" && !iface.internal) return iface.address;
1000
+ }
1001
+ }
1002
+ return "localhost";
1003
+ }
1004
+ var program = new Command();
1005
+ program.name("agentbnb").description("P2P Agent Capability Sharing Protocol \u2014 Airbnb for AI agent pipelines").version(pkg.version);
1006
+ program.command("init").description("Initialize AgentBnB config and create agent identity").option("--owner <name>", "Agent owner name").option("--agent-id <id>", "Agent identity (alias for --owner, for genesis-template compat)").option("--port <port>", "Gateway port", "7700").option("--host <ip>", "Override gateway host IP (default: auto-detected LAN IP)").option("--yes", "Auto-confirm all draft cards (non-interactive)").option("--non-interactive", "Non-interactive mode (alias for --yes)").option("--no-detect", "Skip API key detection").option("--from <file>", "Parse a specific file for capability detection").option("--json", "Output as JSON").action(async (opts) => {
1007
+ const result = await performInit(opts);
807
1008
  if (opts.json) {
808
1009
  const jsonOutput = {
809
1010
  success: true,
810
- owner,
811
- config_dir: configDir,
812
- token: config.token,
813
- gateway_url: config.gateway_url,
814
- keypair: keypairStatus,
815
- agent_id: identity.agent_id
1011
+ owner: result.owner,
1012
+ config_dir: result.configDir,
1013
+ token: result.config.token,
1014
+ gateway_url: result.config.gateway_url,
1015
+ keypair: result.keypairStatus,
1016
+ agent_id: result.identity.agent_id
816
1017
  };
817
- if (registryBalance !== void 0) {
818
- jsonOutput.registry_balance = registryBalance;
1018
+ if (result.registryBalance !== void 0) {
1019
+ jsonOutput.registry_balance = result.registryBalance;
819
1020
  }
820
- if (!skipDetect) {
821
- jsonOutput.detected_source = detectedSource;
822
- jsonOutput.published_cards = publishedCards;
1021
+ if (opts.detect !== false) {
1022
+ jsonOutput.detected_source = result.detectedSource;
1023
+ jsonOutput.published_cards = result.publishedCards;
823
1024
  }
824
1025
  console.log(JSON.stringify(jsonOutput, null, 2));
825
1026
  } else {
1027
+ const ip = opts.host ?? getLanIp2();
1028
+ const port = parseInt(opts.port, 10);
826
1029
  console.log(`AgentBnB initialized.`);
827
- console.log(` Owner: ${owner}`);
828
- console.log(` Token: ${config.token}`);
829
- console.log(` Config: ${configDir}/config.json`);
830
- if (registryBalance !== void 0) {
831
- console.log(` Registry balance: ${registryBalance} credits`);
1030
+ console.log(` Owner: ${result.owner}`);
1031
+ console.log(` Token: ${result.config.token}`);
1032
+ console.log(` Config: ${result.configDir}/config.json`);
1033
+ if (result.registryBalance !== void 0) {
1034
+ console.log(` Registry balance: ${result.registryBalance} credits`);
832
1035
  } else {
833
1036
  console.log(` Credits: 100 (starter grant)`);
834
1037
  }
835
- console.log(` Keypair: ${keypairStatus === "generated" ? "generated (Ed25519)" : "preserved (existing)"}`);
836
- console.log(` Agent ID: ${identity.agent_id}`);
1038
+ console.log(` Keypair: ${result.keypairStatus === "generated" ? "generated (Ed25519)" : "preserved (existing)"}`);
1039
+ console.log(` Agent ID: ${result.identity.agent_id}`);
837
1040
  console.log(` Gateway: http://${ip}:${port}`);
838
1041
  }
839
1042
  });
@@ -845,7 +1048,7 @@ program.command("publish <card.json>").description("Publish a Capability Card to
845
1048
  }
846
1049
  let raw;
847
1050
  try {
848
- raw = readFileSync3(cardPath, "utf-8");
1051
+ raw = readFileSync4(cardPath, "utf-8");
849
1052
  } catch {
850
1053
  console.error(`Error: cannot read file: ${cardPath}`);
851
1054
  process.exit(1);
@@ -946,6 +1149,62 @@ program.command("publish <card.json>").description("Publish a Capability Card to
946
1149
  } else if (!registryUrl) {
947
1150
  }
948
1151
  });
1152
+ program.command("publish-skills").description("Publish capabilities from skills.yaml to the local registry").option("--from-skills [path]", "Path to skills.yaml", "./skills.yaml").action(async (opts) => {
1153
+ const config = loadConfig();
1154
+ if (!config) {
1155
+ console.error("Error: not initialized. Run `agentbnb init` first.");
1156
+ process.exit(1);
1157
+ }
1158
+ const { parseSkillsFile } = await import("../skill-config-FETXPNVP.js");
1159
+ const { skillConfigToSkill } = await import("../publish-capability-TS6CNR5G.js");
1160
+ const skillsPath = typeof opts.fromSkills === "string" ? opts.fromSkills : "./skills.yaml";
1161
+ let yamlContent;
1162
+ try {
1163
+ yamlContent = readFileSync4(skillsPath, "utf-8");
1164
+ } catch {
1165
+ console.error(`Error: cannot read skills.yaml at ${skillsPath}`);
1166
+ process.exit(1);
1167
+ }
1168
+ let allSkillConfigs;
1169
+ try {
1170
+ allSkillConfigs = parseSkillsFile(yamlContent);
1171
+ } catch (err) {
1172
+ const msg = err instanceof Error ? err.message : String(err);
1173
+ console.error(`Error: failed to parse skills.yaml \u2014 ${msg}`);
1174
+ process.exit(1);
1175
+ }
1176
+ const publicSkillConfigs = allSkillConfigs.filter(
1177
+ (sc) => sc.visibility !== "private"
1178
+ );
1179
+ if (publicSkillConfigs.length === 0) {
1180
+ console.log("No public skills to publish (all skills have visibility: private or no skills found).");
1181
+ return;
1182
+ }
1183
+ const skills = publicSkillConfigs.map((sc) => skillConfigToSkill(sc));
1184
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1185
+ const card = {
1186
+ spec_version: "2.0",
1187
+ id: randomUUID4(),
1188
+ owner: config.owner,
1189
+ agent_name: config.owner,
1190
+ skills,
1191
+ availability: { online: true },
1192
+ created_at: now,
1193
+ updated_at: now
1194
+ };
1195
+ const db = openDatabase(config.db_path);
1196
+ try {
1197
+ db.prepare(
1198
+ "INSERT OR REPLACE INTO capability_cards (id, owner, data, created_at, updated_at) VALUES (?, ?, ?, ?, ?)"
1199
+ ).run(card.id, card.owner, JSON.stringify(card), now, now);
1200
+ } finally {
1201
+ db.close();
1202
+ }
1203
+ console.log(`Published ${skills.length} skill(s) to local registry`);
1204
+ for (const skill of skills) {
1205
+ console.log(` - ${skill.id}: ${skill.name} (${skill.pricing.credits_per_call} cr/call)`);
1206
+ }
1207
+ });
949
1208
  program.command("sync").description("Push all local capability cards to the configured remote registry").option("--registry <url>", "Remote registry URL (overrides config.registry)").option("--json", "Output as JSON").action(async (opts) => {
950
1209
  const config = loadConfig();
951
1210
  if (!config) {
@@ -1148,7 +1407,7 @@ program.command("request [card-id]").description("Request a capability from anot
1148
1407
  }
1149
1408
  let batchPayload;
1150
1409
  try {
1151
- const raw = readFileSync3(opts.batch, "utf-8");
1410
+ const raw = readFileSync4(opts.batch, "utf-8");
1152
1411
  batchPayload = JSON.parse(raw);
1153
1412
  } catch (err) {
1154
1413
  console.error(`Error: could not read batch file: ${err.message}`);
@@ -1209,8 +1468,8 @@ Batch Results (${res.results.length} items):`);
1209
1468
  process.exit(1);
1210
1469
  }
1211
1470
  }
1212
- const registryDb = openDatabase(join2(getConfigDir(), "registry.db"));
1213
- const creditDb = openCreditDb(join2(getConfigDir(), "credit.db"));
1471
+ const registryDb = openDatabase(join4(getConfigDir(), "registry.db"));
1472
+ const creditDb = openCreditDb(join4(getConfigDir(), "credit.db"));
1214
1473
  registryDb.pragma("busy_timeout = 5000");
1215
1474
  creditDb.pragma("busy_timeout = 5000");
1216
1475
  try {
@@ -1250,7 +1509,7 @@ Batch Results (${res.results.length} items):`);
1250
1509
  let token;
1251
1510
  let isRemoteRequest = false;
1252
1511
  let targetOwner;
1253
- const identityAuth = loadIdentityAuth(config.owner);
1512
+ const identityAuth = loadIdentityAuth2(config.owner);
1254
1513
  if (opts.peer) {
1255
1514
  const peer = findPeer(opts.peer);
1256
1515
  if (!peer) {
@@ -1330,7 +1589,7 @@ Batch Results (${res.results.length} items):`);
1330
1589
  process.exit(1);
1331
1590
  }
1332
1591
  if (useRegistryLedger) {
1333
- const reqIdentityAuth = loadIdentityAuth(config.owner);
1592
+ const reqIdentityAuth = loadIdentityAuth2(config.owner);
1334
1593
  requestLedger = createLedger({
1335
1594
  registryUrl: config.registry,
1336
1595
  ownerPublicKey: reqIdentityAuth.publicKey,
@@ -1353,7 +1612,7 @@ Batch Results (${res.results.length} items):`);
1353
1612
  }
1354
1613
  } else if (gatewayUrl) {
1355
1614
  const configDir = getConfigDir();
1356
- const creditDb = openCreditDb(join2(configDir, "credit.db"));
1615
+ const creditDb = openCreditDb(join4(configDir, "credit.db"));
1357
1616
  creditDb.pragma("busy_timeout = 5000");
1358
1617
  try {
1359
1618
  const keys = loadKeyPair(configDir);
@@ -1388,7 +1647,7 @@ Batch Results (${res.results.length} items):`);
1388
1647
  if (!opts.json) console.log(`Escrow settled: ${opts.cost} credits deducted.`);
1389
1648
  } else if (escrowReceipt) {
1390
1649
  const configDir = getConfigDir();
1391
- const creditDb = openCreditDb(join2(configDir, "credit.db"));
1650
+ const creditDb = openCreditDb(join4(configDir, "credit.db"));
1392
1651
  creditDb.pragma("busy_timeout = 5000");
1393
1652
  try {
1394
1653
  settleRequesterEscrow(creditDb, escrowId);
@@ -1406,7 +1665,7 @@ Batch Results (${res.results.length} items):`);
1406
1665
  if (!opts.json) console.log("Escrow released: credits refunded.");
1407
1666
  } else if (escrowReceipt) {
1408
1667
  const configDir = getConfigDir();
1409
- const creditDb = openCreditDb(join2(configDir, "credit.db"));
1668
+ const creditDb = openCreditDb(join4(configDir, "credit.db"));
1410
1669
  creditDb.pragma("busy_timeout = 5000");
1411
1670
  try {
1412
1671
  releaseRequesterEscrow(creditDb, escrowId);
@@ -1430,14 +1689,14 @@ Batch Results (${res.results.length} items):`);
1430
1689
  return msg.includes("NETWORK_ERROR") || msg.includes("ECONNREFUSED") || msg.includes("fetch failed") || msg.includes("Network error");
1431
1690
  };
1432
1691
  const tryViaRelay = async () => {
1433
- const { RelayClient } = await import("../websocket-client-6IIDGXKB.js");
1434
- const { requestViaRelay } = await import("../client-T5MTY3CS.js");
1435
- const requesterId = `${config.owner}:req:${randomUUID5()}`;
1692
+ const { RelayClient } = await import("../websocket-client-5MH6QRJK.js");
1693
+ const { requestViaRelay } = await import("../client-HRYRJKSA.js");
1694
+ const requesterId = `${config.owner}:req:${randomUUID4()}`;
1436
1695
  const tempRelay = new RelayClient({
1437
1696
  registryUrl: config.registry,
1438
1697
  owner: requesterId,
1439
1698
  token: config.token,
1440
- card: { id: randomUUID5(), owner: requesterId, name: requesterId, description: "Requester", level: 1, spec_version: "1.0", inputs: [], outputs: [], pricing: { credits_per_call: 1 }, availability: { online: false } },
1699
+ card: { id: randomUUID4(), owner: requesterId, name: requesterId, description: "Requester", level: 1, spec_version: "1.0", inputs: [], outputs: [], pricing: { credits_per_call: 1 }, availability: { online: false } },
1441
1700
  onRequest: async () => ({ error: { code: -32601, message: "Not serving" } }),
1442
1701
  silent: true
1443
1702
  });
@@ -1509,7 +1768,7 @@ program.command("status").description("Show credit balance and recent transactio
1509
1768
  let transactions;
1510
1769
  let heldEscrows;
1511
1770
  if (config.registry) {
1512
- const statusIdentityAuth = loadIdentityAuth(config.owner);
1771
+ const statusIdentityAuth = loadIdentityAuth2(config.owner);
1513
1772
  const statusLedger = createLedger({
1514
1773
  registryUrl: config.registry,
1515
1774
  ownerPublicKey: statusIdentityAuth.publicKey,
@@ -1560,15 +1819,15 @@ program.command("serve").description("Start the AgentBnB gateway server").option
1560
1819
  console.error("Error: not initialized. Run `agentbnb init` first.");
1561
1820
  process.exit(1);
1562
1821
  }
1563
- const { ProcessGuard } = await import("../process-guard-CC7CNRQJ.js");
1564
- const { ServiceCoordinator } = await import("../service-coordinator-EYRDTHL5.js");
1822
+ const { ProcessGuard } = await import("../process-guard-QCCBGILS.js");
1823
+ const { ServiceCoordinator } = await import("../service-coordinator-XBNT3SMU.js");
1565
1824
  const port = opts.port ? parseInt(opts.port, 10) : config.gateway_port;
1566
1825
  const registryPort = parseInt(opts.registryPort, 10);
1567
1826
  if (!Number.isFinite(port) || !Number.isFinite(registryPort)) {
1568
1827
  console.error("Error: --port and --registry-port must be valid numbers.");
1569
1828
  process.exit(1);
1570
1829
  }
1571
- const guard = new ProcessGuard(join2(getConfigDir(), ".pid"));
1830
+ const guard = new ProcessGuard(join4(getConfigDir(), ".pid"));
1572
1831
  const coordinator = new ServiceCoordinator(config, guard);
1573
1832
  try {
1574
1833
  await coordinator.ensureRunning({
@@ -1631,7 +1890,7 @@ peersCommand.command("remove <name>").description("Remove a registered peer").ac
1631
1890
  });
1632
1891
  var configCmd = program.command("config").description("Get or set AgentBnB configuration values");
1633
1892
  configCmd.command("set <key> <value>").description("Set a configuration value").action((key, value) => {
1634
- const allowedKeys = ["registry", "tier1", "tier2", "reserve", "idle-threshold", "conductor-public"];
1893
+ const allowedKeys = ["registry", "tier1", "tier2", "reserve", "idle-threshold", "conductor-public", "telegram-notifications", "telegram-bot-token", "telegram-chat-id", "shared-skills"];
1635
1894
  if (!allowedKeys.includes(key)) {
1636
1895
  console.error(`Unknown config key: ${key}. Valid keys: ${allowedKeys.join(", ")}`);
1637
1896
  process.exit(1);
@@ -1707,6 +1966,35 @@ configCmd.command("set <key> <value>").description("Set a configuration value").
1707
1966
  console.log(`Set conductor-public = ${boolVal} (conductor card ${boolVal ? "will be" : "will NOT be"} published to registry)`);
1708
1967
  return;
1709
1968
  }
1969
+ if (key === "telegram-notifications") {
1970
+ if (value !== "true" && value !== "false") {
1971
+ console.error('Error: telegram-notifications must be "true" or "false"');
1972
+ process.exit(1);
1973
+ }
1974
+ config.telegram_notifications = value === "true";
1975
+ saveConfig(config);
1976
+ console.log(`Set telegram-notifications = ${config.telegram_notifications}`);
1977
+ return;
1978
+ }
1979
+ if (key === "telegram-bot-token") {
1980
+ config.telegram_bot_token = value;
1981
+ saveConfig(config);
1982
+ console.log("Set telegram-bot-token");
1983
+ return;
1984
+ }
1985
+ if (key === "telegram-chat-id") {
1986
+ config.telegram_chat_id = value;
1987
+ saveConfig(config);
1988
+ console.log(`Set telegram-chat-id = ${value}`);
1989
+ return;
1990
+ }
1991
+ if (key === "shared-skills") {
1992
+ config.shared_skills = value.trim() === "" ? [] : value.split(",").map((s) => s.trim()).filter(Boolean);
1993
+ saveConfig(config);
1994
+ const display = config.shared_skills.length > 0 ? config.shared_skills.join(", ") : "(all skills published)";
1995
+ console.log(`Set shared-skills: ${display}`);
1996
+ return;
1997
+ }
1710
1998
  config[key] = value;
1711
1999
  saveConfig(config);
1712
2000
  console.log(`Set ${key} = ${value}`);
@@ -1738,11 +2026,97 @@ configCmd.command("get <key>").description("Get a configuration value").action((
1738
2026
  console.log(String(config.conductor?.public ?? false));
1739
2027
  return;
1740
2028
  }
2029
+ if (key === "telegram-notifications") {
2030
+ console.log(String(config.telegram_notifications ?? false));
2031
+ return;
2032
+ }
2033
+ if (key === "telegram-bot-token") {
2034
+ console.log(config.telegram_bot_token ?? "(not set)");
2035
+ return;
2036
+ }
2037
+ if (key === "telegram-chat-id") {
2038
+ console.log(config.telegram_chat_id ?? "(not set)");
2039
+ return;
2040
+ }
2041
+ if (key === "shared-skills") {
2042
+ const skills = config.shared_skills ?? [];
2043
+ console.log(skills.length > 0 ? skills.join(", ") : "(all skills published)");
2044
+ return;
2045
+ }
1741
2046
  const value = config[key];
1742
2047
  console.log(value !== void 0 ? String(value) : "(not set)");
1743
2048
  });
2049
+ var cardsCmd = program.command("cards").description("Manage published capability cards");
2050
+ cardsCmd.command("list").description("List all published capability cards in the local registry").action(() => {
2051
+ const config = loadConfig();
2052
+ if (!config) {
2053
+ console.error("Error: not initialized. Run `agentbnb init` first.");
2054
+ process.exit(1);
2055
+ }
2056
+ const db = openDatabase(config.db_path);
2057
+ try {
2058
+ const cards = listCards(db);
2059
+ if (cards.length === 0) {
2060
+ console.log("No published cards found.");
2061
+ return;
2062
+ }
2063
+ console.log(`Published cards (${cards.length}):`);
2064
+ for (const card of cards) {
2065
+ const v2 = card;
2066
+ const name = String(v2["agent_name"] ?? v2["name"] ?? "(unnamed)");
2067
+ const owner = String(v2["owner"] ?? "");
2068
+ const skills = Array.isArray(v2["skills"]) ? v2["skills"].length : 0;
2069
+ const skillsLabel = skills > 0 ? ` (${skills} skill${skills !== 1 ? "s" : ""})` : "";
2070
+ console.log(` ${card.id} ${name} owner: ${owner}${skillsLabel}`);
2071
+ }
2072
+ } finally {
2073
+ db.close();
2074
+ }
2075
+ });
2076
+ cardsCmd.command("delete <card-id>").description("Delete a published capability card from the local registry").option("--force", "Skip confirmation prompt").action(async (cardId, opts) => {
2077
+ const config = loadConfig();
2078
+ if (!config) {
2079
+ console.error("Error: not initialized. Run `agentbnb init` first.");
2080
+ process.exit(1);
2081
+ }
2082
+ const db = openDatabase(config.db_path);
2083
+ try {
2084
+ const card = getCard(db, cardId);
2085
+ if (!card) {
2086
+ console.error(`Error: card not found: ${cardId}`);
2087
+ process.exit(1);
2088
+ }
2089
+ const v2 = card;
2090
+ const cardName = String(v2["agent_name"] ?? v2["name"] ?? "(unnamed)");
2091
+ const skillCount = Array.isArray(v2["skills"]) ? v2["skills"].length : 0;
2092
+ console.log("Deleting card:");
2093
+ console.log(` Name: "${cardName}"`);
2094
+ console.log(` Owner: ${card.owner}`);
2095
+ console.log(` Skills: ${skillCount}`);
2096
+ console.log(` ID: ${card.id}`);
2097
+ if (!opts.force && process.stdin.isTTY) {
2098
+ const rl = createInterface3({ input: process.stdin, output: process.stdout });
2099
+ const answer = await new Promise((resolve) => {
2100
+ rl.question("Confirm deletion? [y/N] ", resolve);
2101
+ });
2102
+ rl.close();
2103
+ if (answer.toLowerCase() !== "y") {
2104
+ console.log("Cancelled.");
2105
+ process.exit(0);
2106
+ }
2107
+ }
2108
+ deleteCard(db, cardId, card.owner);
2109
+ console.log(`Deleted: "${cardName}" (${skillCount} skill${skillCount !== 1 ? "s" : ""})`);
2110
+ } catch (err) {
2111
+ const msg = err instanceof Error ? err.message : String(err);
2112
+ console.error(`Error: ${msg}`);
2113
+ process.exit(1);
2114
+ } finally {
2115
+ db.close();
2116
+ }
2117
+ });
1744
2118
  var openclaw = program.command("openclaw").description("OpenClaw integration commands");
1745
- openclaw.command("sync").description("Read SOUL.md and publish/update a v2.0 capability card").option("--soul-path <path>", "Path to SOUL.md", "./SOUL.md").action(async (opts) => {
2119
+ openclaw.command("sync").description("Read SOUL.md and publish/update a v2.0 capability card").option("--soul-path <path>", "Path to SOUL.md", "./SOUL.md").option("--skills <ids>", "Comma-separated skill IDs to publish (overrides shared-skills config and skill visibility)").action(async (opts) => {
1746
2120
  const config = loadConfig();
1747
2121
  if (!config) {
1748
2122
  console.error("Error: not initialized. Run `agentbnb init` first.");
@@ -1750,14 +2124,15 @@ openclaw.command("sync").description("Read SOUL.md and publish/update a v2.0 cap
1750
2124
  }
1751
2125
  let content;
1752
2126
  try {
1753
- content = readFileSync3(opts.soulPath, "utf-8");
2127
+ content = readFileSync4(opts.soulPath, "utf-8");
1754
2128
  } catch {
1755
2129
  console.error(`Error: cannot read SOUL.md at ${opts.soulPath}`);
1756
2130
  process.exit(1);
1757
2131
  }
2132
+ const sharedSkills = opts.skills ? opts.skills.split(",").map((s) => s.trim()).filter(Boolean) : config.shared_skills && config.shared_skills.length > 0 ? config.shared_skills : void 0;
1758
2133
  const db = openDatabase(config.db_path);
1759
2134
  try {
1760
- const card = publishFromSoulV2(db, content, config.owner);
2135
+ const card = publishFromSoulV2(db, content, config.owner, sharedSkills);
1761
2136
  console.log(`Published card ${card.id} with ${card.skills.length} skill(s)`);
1762
2137
  for (const skill of card.skills) {
1763
2138
  const stats = getPricingStats(db, skill.name);
@@ -1819,7 +2194,7 @@ openclaw.command("rules").description("Print HEARTBEAT.md rules block (or inject
1819
2194
  }
1820
2195
  });
1821
2196
  program.command("conduct <task>").description("Orchestrate a complex task across the AgentBnB network").option("--plan-only", "Show execution plan without executing").option("--max-budget <credits>", "Maximum credits to spend", "100").option("--json", "Output as JSON").action(async (task, opts) => {
1822
- const { conductAction } = await import("../conduct-6LKIJJKQ.js");
2197
+ const { conductAction } = await import("../conduct-KJUD2RTB.js");
1823
2198
  const result = await conductAction(task, opts);
1824
2199
  if (opts.json) {
1825
2200
  console.log(JSON.stringify(result, null, 2));
@@ -1929,8 +2304,9 @@ Feedback for skill: ${opts.skill} (${feedbacks.length} entries)
1929
2304
  }
1930
2305
  }
1931
2306
  });
2307
+ program.command("quickstart").alias("qs").description("One-command setup: init + skills.yaml + MCP registration + serve daemon").option("--owner <name>", "Agent owner name").option("--port <port>", "Gateway port", "7700").option("--no-serve", "Skip starting background daemon").option("--no-mcp", "Skip MCP registration with Claude Code").option("--json", "Output as JSON").action(runQuickstart);
1932
2308
  program.command("mcp-server").description("Start an MCP (Model Context Protocol) server for IDE integration").action(async () => {
1933
- const { startMcpServer } = await import("../server-JVQW2TID.js");
2309
+ const { startMcpServer } = await import("../server-I63CXFX3.js");
1934
2310
  await startMcpServer();
1935
2311
  });
1936
2312
  await program.parseAsync(process.argv);