agentbnb 8.2.0 → 8.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/{chunk-TBJ3FZKZ.js → chunk-7Q2XUXSA.js} +1 -1
  2. package/dist/{chunk-LJM7FHPM.js → chunk-BZOJ7HBT.js} +33 -1
  3. package/dist/{chunk-FTZTEHYG.js → chunk-DEWY7OQK.js} +135 -8
  4. package/dist/{chunk-CUONY5TO.js → chunk-EJKW57ZV.js} +19 -1
  5. package/dist/chunk-EZVOG7QS.js +161 -0
  6. package/dist/{chunk-E2OKP5CY.js → chunk-GJETGML6.js} +181 -83
  7. package/dist/{chunk-YHY7OG6S.js → chunk-GWMMYVLL.js} +4 -4
  8. package/dist/{chunk-D6RKW2XG.js → chunk-JLNHMNES.js} +16 -3
  9. package/dist/{chunk-5AAFG2V2.js → chunk-KBQNTUTN.js} +239 -24
  10. package/dist/{chunk-C537SFHV.js → chunk-LOUEJI6X.js} +4 -4
  11. package/dist/{chunk-ALX4WS3A.js → chunk-NP55V7RQ.js} +1 -1
  12. package/dist/{chunk-X32NE6V4.js → chunk-RBXTWWUH.js} +1 -1
  13. package/dist/{chunk-O2OYBAVR.js → chunk-SRBVKO2V.js} +9 -0
  14. package/dist/{chunk-7EF3HYVZ.js → chunk-STJLWMXH.js} +48 -4
  15. package/dist/{chunk-5GME4KJZ.js → chunk-UYCD3JBZ.js} +3 -3
  16. package/dist/{chunk-P4LOYSLA.js → chunk-WKWJWKX7.js} +286 -81
  17. package/dist/cli/index.js +35 -57
  18. package/dist/{client-HKV3QWZ3.js → client-66TFS7RS.js} +4 -2
  19. package/dist/{conduct-W6XF6DJW.js → conduct-A6COHLHY.js} +8 -8
  20. package/dist/{conduct-YB64OHI6.js → conduct-IUVAXUAV.js} +8 -8
  21. package/dist/{conductor-mode-TFCVCQHU.js → conductor-mode-D5TFQW5L.js} +2 -2
  22. package/dist/{conductor-mode-AKREGDIU.js → conductor-mode-L2MB44BW.js} +7 -7
  23. package/dist/{execute-AYQWORVH.js → execute-5AWLARB5.js} +5 -5
  24. package/dist/{execute-EPE6MZLT.js → execute-WOS457HW.js} +2 -2
  25. package/dist/index.js +438 -92
  26. package/dist/{publish-capability-AH2HDW54.js → publish-capability-JJCBBMSX.js} +2 -2
  27. package/dist/{request-HCCXSKAY.js → request-6YQLA7K3.js} +13 -8
  28. package/dist/{serve-skill-SZAQT5T5.js → serve-skill-X7TZSILV.js} +5 -5
  29. package/dist/{server-LMY2A3GT.js → server-5TSP4DBX.js} +10 -12
  30. package/dist/{service-coordinator-WGH6B2VT.js → service-coordinator-WTUSMPY6.js} +69 -46
  31. package/dist/skills/agentbnb/bootstrap.js +459 -189
  32. package/package.json +13 -17
  33. package/skills/agentbnb/bootstrap.test.ts +8 -6
  34. package/skills/agentbnb/bootstrap.ts +21 -13
  35. package/skills/agentbnb/install.sh +0 -0
  36. package/dist/chunk-64AK4FJM.js +0 -84
  37. package/dist/chunk-OH7BP5NP.js +0 -96
  38. package/dist/index.d.ts +0 -5069
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "workspaces": [
4
4
  "packages/*"
5
5
  ],
6
- "version": "8.2.0",
6
+ "version": "8.2.1",
7
7
  "description": "P2P Agent Capability Sharing Protocol — Airbnb for AI agent pipelines",
8
8
  "type": "module",
9
9
  "main": "dist/index.js",
@@ -32,17 +32,6 @@
32
32
  "import": "./dist/identity/index.js"
33
33
  }
34
34
  },
35
- "scripts": {
36
- "build": "tsup",
37
- "build:hub": "cd hub && pnpm install && pnpm build",
38
- "build:all": "pnpm build && pnpm build:hub",
39
- "dev": "tsx watch src/cli/index.ts",
40
- "test": "vitest",
41
- "test:run": "vitest run",
42
- "lint": "eslint src/",
43
- "typecheck": "tsc --noEmit",
44
- "prepublishOnly": "pnpm run build && pnpm run typecheck && pnpm run test:run"
45
- },
46
35
  "keywords": [
47
36
  "ai",
48
37
  "agent",
@@ -81,6 +70,7 @@
81
70
  "fastify": "^5.1.0",
82
71
  "js-yaml": "^4.1.1",
83
72
  "typed-emitter": "^2.1.0",
73
+ "undici": "^7.24.6",
84
74
  "ws": "^8.19.0",
85
75
  "zod": "^3.24.0"
86
76
  },
@@ -92,9 +82,15 @@
92
82
  "engines": {
93
83
  "node": ">=20.0.0"
94
84
  },
95
- "pnpm": {
96
- "onlyBuiltDependencies": [
97
- "better-sqlite3"
98
- ]
85
+ "scripts": {
86
+ "build": "tsup",
87
+ "build:hub": "cd hub && pnpm install && pnpm build",
88
+ "build:all": "pnpm build && pnpm build:hub",
89
+ "dev": "tsx watch src/cli/index.ts",
90
+ "test": "vitest run",
91
+ "test:run": "vitest run",
92
+ "test:watch": "vitest",
93
+ "lint": "eslint src/",
94
+ "typecheck": "tsc --noEmit"
99
95
  }
100
- }
96
+ }
@@ -110,7 +110,9 @@ describe('bootstrap activate/deactivate lifecycle', () => {
110
110
  it('activate() throws INIT_FAILED when CLI not found and config missing', async () => {
111
111
  mockLoadConfig.mockReturnValue(null);
112
112
  const deps: OnboardDeps = {
113
- findCli: () => null,
113
+ resolveSelfCli: () => {
114
+ throw new Error('not found');
115
+ },
114
116
  runCommand: vi.fn(),
115
117
  };
116
118
 
@@ -126,15 +128,15 @@ describe('bootstrap activate/deactivate lifecycle', () => {
126
128
  mockLoadConfig.mockReturnValueOnce(null).mockReturnValue(MINIMAL_CONFIG as ReturnType<typeof loadConfig>);
127
129
  const mockRun = vi.fn().mockResolvedValue({ stdout: '', stderr: '' });
128
130
  const deps: OnboardDeps = {
129
- findCli: () => '/usr/local/bin/agentbnb',
131
+ resolveSelfCli: () => '/usr/local/bin/agentbnb',
130
132
  runCommand: mockRun,
131
133
  };
132
134
 
133
135
  ctx = await activate({}, deps);
134
136
 
135
137
  expect(mockRun).toHaveBeenCalledTimes(2);
136
- expect(mockRun.mock.calls[0][0]).toMatch(/agentbnb init --owner .* --yes --no-detect/);
137
- expect(mockRun.mock.calls[1][0]).toBe('agentbnb openclaw sync');
138
+ expect(mockRun.mock.calls[0][0]).toMatch(/^'\/usr\/local\/bin\/agentbnb' init --owner .* --yes --no-detect$/);
139
+ expect(mockRun.mock.calls[1][0]).toBe('\'/usr/local/bin/agentbnb\' openclaw sync');
138
140
  });
139
141
 
140
142
  // ---------------------------------------------------------------------------
@@ -146,7 +148,7 @@ describe('bootstrap activate/deactivate lifecycle', () => {
146
148
  .mockResolvedValueOnce({ stdout: '', stderr: '' })
147
149
  .mockRejectedValueOnce(new Error('SOUL.md not found'));
148
150
  const deps: OnboardDeps = {
149
- findCli: () => '/usr/local/bin/agentbnb',
151
+ resolveSelfCli: () => '/usr/local/bin/agentbnb',
150
152
  runCommand: mockRun,
151
153
  };
152
154
 
@@ -161,7 +163,7 @@ describe('bootstrap activate/deactivate lifecycle', () => {
161
163
  it('activate() skips auto-onboard when config already exists', async () => {
162
164
  const mockRun = vi.fn();
163
165
  const deps: OnboardDeps = {
164
- findCli: () => '/usr/local/bin/agentbnb',
166
+ resolveSelfCli: () => '/usr/local/bin/agentbnb',
165
167
  runCommand: mockRun,
166
168
  };
167
169
 
@@ -11,7 +11,7 @@
11
11
  import { join, basename, dirname } from 'node:path';
12
12
  import { existsSync } from 'node:fs';
13
13
  import { homedir } from 'node:os';
14
- import { spawnSync, exec } from 'node:child_process';
14
+ import { exec } from 'node:child_process';
15
15
  import { promisify } from 'node:util';
16
16
  import { randomUUID } from 'node:crypto';
17
17
 
@@ -51,6 +51,7 @@ import { getConfigDir, loadConfig } from '../../src/cli/config.js';
51
51
  import { AgentBnBError } from '../../src/types/index.js';
52
52
  import { ProcessGuard } from '../../src/runtime/process-guard.js';
53
53
  import { ServiceCoordinator } from '../../src/runtime/service-coordinator.js';
54
+ import { resolveSelfCli } from '../../src/runtime/resolve-self-cli.js';
54
55
  import type { ServiceOptions, ServiceStatus } from '../../src/runtime/service-coordinator.js';
55
56
  import { AgentBnBService } from '../../src/app/agentbnb-service.js';
56
57
  import { openDatabase } from '../../src/registry/store.js';
@@ -174,15 +175,15 @@ function registerDecomposerCard(configDir: string, owner: string): void {
174
175
  }
175
176
 
176
177
  /**
177
- * Checks if the `agentbnb` CLI is available in PATH.
178
- * @returns Absolute path to the CLI, or null if not found.
178
+ * Checks if the `agentbnb` CLI can be resolved to an absolute executable path.
179
+ * @returns Absolute path to the CLI, or null if resolution fails.
179
180
  */
180
181
  export function findCli(): string | null {
181
- const result = spawnSync('which', ['agentbnb'], { encoding: 'utf-8', stdio: 'pipe' });
182
- if (result.status === 0 && result.stdout.trim()) {
183
- return result.stdout.trim();
182
+ try {
183
+ return resolveSelfCli();
184
+ } catch {
185
+ return null;
184
186
  }
185
- return null;
186
187
  }
187
188
 
188
189
  /**
@@ -222,32 +223,35 @@ function deriveAgentName(configDir: string): string {
222
223
  */
223
224
  /** Injectable dependencies for autoOnboard (test seam). */
224
225
  export interface OnboardDeps {
225
- findCli: () => string | null;
226
+ resolveSelfCli: () => string;
226
227
  runCommand: (cmd: string, env: Record<string, string | undefined>) => Promise<{ stdout: string; stderr: string }>;
227
228
  }
228
229
 
229
230
  /** Default production dependencies. */
230
- const defaultDeps: OnboardDeps = { findCli, runCommand };
231
+ const defaultDeps: OnboardDeps = { resolveSelfCli, runCommand };
231
232
 
232
233
  async function autoOnboard(configDir: string, deps: OnboardDeps = defaultDeps): Promise<import('./../../src/cli/config.js').AgentBnBConfig> {
233
234
  process.stderr.write('[agentbnb] First-time setup: initializing agent identity...\n');
234
235
 
235
236
  // Step 0: Check CLI exists
236
- const cliPath = deps.findCli();
237
- if (!cliPath) {
237
+ let cliPath: string;
238
+ try {
239
+ cliPath = deps.resolveSelfCli();
240
+ } catch {
238
241
  process.stderr.write('[agentbnb] CLI not found. Run: npm install -g agentbnb\n');
239
242
  throw new AgentBnBError(
240
243
  'agentbnb CLI not found in PATH. Install with: npm install -g agentbnb',
241
244
  'INIT_FAILED',
242
245
  );
243
246
  }
247
+ const quotedCliPath = quoteShellArg(cliPath);
244
248
 
245
249
  const env = { ...process.env, AGENTBNB_DIR: configDir };
246
250
  const agentName = deriveAgentName(configDir);
247
251
 
248
252
  // Step 1: Initialize identity (keypair + config.json + credit bootstrap)
249
253
  try {
250
- await deps.runCommand(`agentbnb init --owner "${agentName}" --yes --no-detect`, env);
254
+ await deps.runCommand(`${quotedCliPath} init --owner "${agentName}" --yes --no-detect`, env);
251
255
  process.stderr.write(`[agentbnb] Agent "${agentName}" initialized.\n`);
252
256
  } catch (err) {
253
257
  const msg = err instanceof Error ? err.message : String(err);
@@ -256,7 +260,7 @@ async function autoOnboard(configDir: string, deps: OnboardDeps = defaultDeps):
256
260
 
257
261
  // Step 2: Publish capabilities from SOUL.md (if it exists)
258
262
  try {
259
- await deps.runCommand('agentbnb openclaw sync', env);
263
+ await deps.runCommand(`${quotedCliPath} openclaw sync`, env);
260
264
  process.stderr.write('[agentbnb] Capabilities published from SOUL.md.\n');
261
265
  } catch {
262
266
  // Non-fatal: SOUL.md may not exist yet, or sync may fail for other reasons.
@@ -276,6 +280,10 @@ async function autoOnboard(configDir: string, deps: OnboardDeps = defaultDeps):
276
280
  return config;
277
281
  }
278
282
 
283
+ function quoteShellArg(input: string): string {
284
+ return `'${input.replace(/'/g, `'\\''`)}'`;
285
+ }
286
+
279
287
  /**
280
288
  * Brings an AgentBnB node online (idempotent — safe to call when already running).
281
289
  * Registers SIGTERM/SIGINT handlers that conditionally stop the node on process exit.
File without changes
@@ -1,84 +0,0 @@
1
- import {
2
- signEscrowReceipt
3
- } from "./chunk-CUONY5TO.js";
4
- import {
5
- AgentBnBError
6
- } from "./chunk-WVY2W7AA.js";
7
-
8
- // src/gateway/client.ts
9
- import { randomUUID } from "crypto";
10
- async function requestCapability(opts) {
11
- const { gatewayUrl, token, cardId, params = {}, timeoutMs = 3e5, escrowReceipt, identity } = opts;
12
- const id = randomUUID();
13
- const payload = {
14
- jsonrpc: "2.0",
15
- id,
16
- method: "capability.execute",
17
- params: {
18
- card_id: cardId,
19
- ...params,
20
- ...escrowReceipt ? { escrow_receipt: escrowReceipt } : {}
21
- }
22
- };
23
- const headers = { "Content-Type": "application/json" };
24
- if (identity) {
25
- const signature = signEscrowReceipt(payload, identity.privateKey);
26
- headers["X-Agent-Id"] = identity.agentId;
27
- headers["X-Agent-Public-Key"] = identity.publicKey;
28
- headers["X-Agent-Signature"] = signature;
29
- } else if (token) {
30
- headers["Authorization"] = `Bearer ${token}`;
31
- }
32
- const controller = new AbortController();
33
- const timer = setTimeout(() => controller.abort(), timeoutMs);
34
- let response;
35
- try {
36
- response = await fetch(`${gatewayUrl}/rpc`, {
37
- method: "POST",
38
- headers,
39
- body: JSON.stringify(payload),
40
- signal: controller.signal
41
- });
42
- } catch (err) {
43
- clearTimeout(timer);
44
- const isTimeout = err instanceof Error && err.name === "AbortError";
45
- throw new AgentBnBError(
46
- isTimeout ? "Request timed out" : `Network error: ${String(err)}`,
47
- isTimeout ? "TIMEOUT" : "NETWORK_ERROR"
48
- );
49
- } finally {
50
- clearTimeout(timer);
51
- }
52
- const body = await response.json();
53
- if (body.error) {
54
- throw new AgentBnBError(body.error.message, `RPC_ERROR_${body.error.code}`);
55
- }
56
- return body.result;
57
- }
58
- async function requestViaRelay(relay, opts) {
59
- try {
60
- return await relay.request({
61
- targetOwner: opts.targetOwner,
62
- cardId: opts.cardId,
63
- skillId: opts.skillId,
64
- params: opts.params ?? {},
65
- requester: opts.requester,
66
- escrowReceipt: opts.escrowReceipt,
67
- timeoutMs: opts.timeoutMs
68
- });
69
- } catch (err) {
70
- const message = err instanceof Error ? err.message : String(err);
71
- if (message.includes("timeout")) {
72
- throw new AgentBnBError(message, "TIMEOUT");
73
- }
74
- if (message.includes("offline")) {
75
- throw new AgentBnBError(message, "AGENT_OFFLINE");
76
- }
77
- throw new AgentBnBError(message, "RELAY_ERROR");
78
- }
79
- }
80
-
81
- export {
82
- requestCapability,
83
- requestViaRelay
84
- };
@@ -1,96 +0,0 @@
1
- import {
2
- generateKeyPair,
3
- loadKeyPair,
4
- saveKeyPair
5
- } from "./chunk-CUONY5TO.js";
6
-
7
- // src/identity/identity.ts
8
- import { z } from "zod";
9
- import { createHash } from "crypto";
10
- import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
11
- import { join } from "path";
12
- var AgentIdentitySchema = z.object({
13
- /** Deterministic ID derived from public key: sha256(hex).slice(0, 16). */
14
- agent_id: z.string().min(1),
15
- /** Human-readable owner name (from config or init). */
16
- owner: z.string().min(1),
17
- /** Hex-encoded Ed25519 public key. */
18
- public_key: z.string().min(1),
19
- /** ISO 8601 timestamp of identity creation. */
20
- created_at: z.string().datetime(),
21
- /** Optional guarantor info if linked to a human. */
22
- guarantor: z.object({
23
- github_login: z.string().min(1),
24
- verified_at: z.string().datetime()
25
- }).optional()
26
- });
27
- var AgentCertificateSchema = z.object({
28
- identity: AgentIdentitySchema,
29
- /** ISO 8601 timestamp of certificate issuance. */
30
- issued_at: z.string().datetime(),
31
- /** ISO 8601 timestamp of certificate expiry. */
32
- expires_at: z.string().datetime(),
33
- /** Hex-encoded public key of the issuer (same as identity for self-signed). */
34
- issuer_public_key: z.string().min(1),
35
- /** Base64url Ed25519 signature over { identity, issued_at, expires_at, issuer_public_key }. */
36
- signature: z.string().min(1)
37
- });
38
- var IDENTITY_FILENAME = "identity.json";
39
- function deriveAgentId(publicKeyHex) {
40
- return createHash("sha256").update(publicKeyHex, "hex").digest("hex").slice(0, 16);
41
- }
42
- function createIdentity(configDir, owner) {
43
- if (!existsSync(configDir)) {
44
- mkdirSync(configDir, { recursive: true });
45
- }
46
- let keys;
47
- try {
48
- keys = loadKeyPair(configDir);
49
- } catch {
50
- keys = generateKeyPair();
51
- saveKeyPair(configDir, keys);
52
- }
53
- const publicKeyHex = keys.publicKey.toString("hex");
54
- const agentId = deriveAgentId(publicKeyHex);
55
- const identity = {
56
- agent_id: agentId,
57
- owner,
58
- public_key: publicKeyHex,
59
- created_at: (/* @__PURE__ */ new Date()).toISOString()
60
- };
61
- saveIdentity(configDir, identity);
62
- return identity;
63
- }
64
- function loadIdentity(configDir) {
65
- const filePath = join(configDir, IDENTITY_FILENAME);
66
- if (!existsSync(filePath)) return null;
67
- try {
68
- const raw = readFileSync(filePath, "utf-8");
69
- return AgentIdentitySchema.parse(JSON.parse(raw));
70
- } catch {
71
- return null;
72
- }
73
- }
74
- function saveIdentity(configDir, identity) {
75
- if (!existsSync(configDir)) {
76
- mkdirSync(configDir, { recursive: true });
77
- }
78
- const filePath = join(configDir, IDENTITY_FILENAME);
79
- writeFileSync(filePath, JSON.stringify(identity, null, 2), "utf-8");
80
- }
81
- function ensureIdentity(configDir, owner) {
82
- const existing = loadIdentity(configDir);
83
- if (existing) {
84
- if (existing.owner !== owner) {
85
- existing.owner = owner;
86
- saveIdentity(configDir, existing);
87
- }
88
- return existing;
89
- }
90
- return createIdentity(configDir, owner);
91
- }
92
-
93
- export {
94
- deriveAgentId,
95
- ensureIdentity
96
- };