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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "workspaces": [
4
4
  "packages/*"
5
5
  ],
6
- "version": "8.2.0",
6
+ "version": "8.2.2",
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,91 +0,0 @@
1
- import {
2
- AgentBnBError
3
- } from "./chunk-WVY2W7AA.js";
4
-
5
- // src/cli/remote-registry.ts
6
- var RegistryTimeoutError = class extends AgentBnBError {
7
- constructor(url) {
8
- super(
9
- `Registry at ${url} did not respond within 5s. Showing local results only.`,
10
- "REGISTRY_TIMEOUT"
11
- );
12
- this.name = "RegistryTimeoutError";
13
- }
14
- };
15
- var RegistryConnectionError = class extends AgentBnBError {
16
- constructor(url) {
17
- super(
18
- `Cannot reach ${url}. Is the registry running? Showing local results only.`,
19
- "REGISTRY_CONNECTION"
20
- );
21
- this.name = "RegistryConnectionError";
22
- }
23
- };
24
- var RegistryAuthError = class extends AgentBnBError {
25
- constructor(url) {
26
- super(
27
- `Authentication failed for ${url}. Run \`agentbnb config set token <your-token>\`.`,
28
- "REGISTRY_AUTH"
29
- );
30
- this.name = "RegistryAuthError";
31
- }
32
- };
33
- async function fetchRemoteCards(registryUrl, params, timeoutMs = 5e3) {
34
- let cardsUrl;
35
- try {
36
- cardsUrl = new URL("/cards", registryUrl);
37
- } catch {
38
- throw new AgentBnBError(`Invalid registry URL: ${registryUrl}`, "INVALID_REGISTRY_URL");
39
- }
40
- const searchParams = new URLSearchParams();
41
- if (params.q !== void 0) searchParams.set("q", params.q);
42
- if (params.level !== void 0) searchParams.set("level", String(params.level));
43
- if (params.online !== void 0) searchParams.set("online", String(params.online));
44
- if (params.tag !== void 0) searchParams.set("tag", params.tag);
45
- searchParams.set("limit", "100");
46
- cardsUrl.search = searchParams.toString();
47
- const controller = new AbortController();
48
- const timer = setTimeout(() => controller.abort(), timeoutMs);
49
- let response;
50
- try {
51
- response = await fetch(cardsUrl.toString(), { signal: controller.signal });
52
- } catch (err) {
53
- clearTimeout(timer);
54
- const isTimeout = err instanceof Error && err.name === "AbortError";
55
- if (isTimeout) {
56
- throw new RegistryTimeoutError(registryUrl);
57
- }
58
- throw new RegistryConnectionError(registryUrl);
59
- } finally {
60
- clearTimeout(timer);
61
- }
62
- if (response.status === 401 || response.status === 403) {
63
- throw new RegistryAuthError(registryUrl);
64
- }
65
- if (!response.ok) {
66
- throw new RegistryConnectionError(registryUrl);
67
- }
68
- const body = await response.json();
69
- return body.items;
70
- }
71
- function mergeResults(localCards, remoteCards, hasQuery) {
72
- const taggedLocal = localCards.map((c) => ({ ...c, source: "local" }));
73
- const taggedRemote = remoteCards.map((c) => ({ ...c, source: "remote" }));
74
- const localIds = new Set(localCards.map((c) => c.id));
75
- const dedupedRemote = taggedRemote.filter((c) => !localIds.has(c.id));
76
- if (!hasQuery) {
77
- return [...taggedLocal, ...dedupedRemote];
78
- }
79
- const result = [];
80
- const maxLen = Math.max(taggedLocal.length, dedupedRemote.length);
81
- for (let i = 0; i < maxLen; i++) {
82
- if (i < taggedLocal.length) result.push(taggedLocal[i]);
83
- if (i < dedupedRemote.length) result.push(dedupedRemote[i]);
84
- }
85
- return result;
86
- }
87
-
88
- export {
89
- fetchRemoteCards,
90
- mergeResults
91
- };
@@ -1,138 +0,0 @@
1
- import {
2
- getFeedbackForProvider
3
- } from "./chunk-O2OYBAVR.js";
4
-
5
- // src/feedback/reputation.ts
6
- var QUALITY_SCORES = {
7
- excellent: 1,
8
- good: 0.8,
9
- acceptable: 0.6,
10
- poor: 0.3,
11
- failed: 0
12
- };
13
- var COST_VALUE_SCORES = {
14
- great: 1,
15
- fair: 0.6,
16
- overpriced: 0.2
17
- };
18
- var DECAY_DAYS = 30;
19
- var WEIGHTS = {
20
- rating: 0.4,
21
- quality: 0.3,
22
- would_reuse: 0.2,
23
- cost_value: 0.1
24
- };
25
- function computeReputation(feedbacks) {
26
- if (feedbacks.length === 0) return 0.5;
27
- const now = Date.now();
28
- let weightedSum = 0;
29
- let totalWeight = 0;
30
- for (const fb of feedbacks) {
31
- const feedbackDate = new Date(fb.timestamp).getTime();
32
- const ageDays = Math.max(0, (now - feedbackDate) / (1e3 * 60 * 60 * 24));
33
- const recencyWeight = Math.exp(-ageDays / DECAY_DAYS);
34
- const ratingScore = (fb.rating - 1) / 4;
35
- const qualityScore = QUALITY_SCORES[fb.result_quality];
36
- const reuseScore = fb.would_reuse ? 1 : 0;
37
- const costScore = COST_VALUE_SCORES[fb.cost_value_ratio];
38
- const componentScore = WEIGHTS.rating * ratingScore + WEIGHTS.quality * qualityScore + WEIGHTS.would_reuse * reuseScore + WEIGHTS.cost_value * costScore;
39
- weightedSum += recencyWeight * componentScore;
40
- totalWeight += recencyWeight;
41
- }
42
- if (totalWeight === 0) return 0.5;
43
- const raw = weightedSum / totalWeight;
44
- return Math.max(0, Math.min(1, raw));
45
- }
46
- function getReputationScore(db, agentId) {
47
- const feedbacks = getFeedbackForProvider(db, agentId);
48
- return computeReputation(feedbacks);
49
- }
50
-
51
- // src/registry/matcher.ts
52
- function searchCards(db, query, filters = {}) {
53
- const words = query.trim().split(/\s+/).map((w) => w.replace(/["*^{}():]/g, "")).filter((w) => w.length > 0);
54
- if (words.length === 0) return [];
55
- const ftsQuery = words.map((w) => `"${w}"`).join(" OR ");
56
- const conditions = [];
57
- const params = [ftsQuery];
58
- if (filters.level !== void 0) {
59
- conditions.push(`json_extract(cc.data, '$.level') = ?`);
60
- params.push(filters.level);
61
- }
62
- if (filters.online !== void 0) {
63
- conditions.push(`json_extract(cc.data, '$.availability.online') = ?`);
64
- params.push(filters.online ? 1 : 0);
65
- }
66
- const whereClause = conditions.length > 0 ? `AND ${conditions.join(" AND ")}` : "";
67
- const sql = `
68
- SELECT cc.data
69
- FROM capability_cards cc
70
- JOIN cards_fts ON cc.rowid = cards_fts.rowid
71
- WHERE cards_fts MATCH ?
72
- ${whereClause}
73
- ORDER BY bm25(cards_fts)
74
- LIMIT 50
75
- `;
76
- const stmt = db.prepare(sql);
77
- const rows = stmt.all(...params);
78
- const results = rows.map((row) => JSON.parse(row.data));
79
- let filtered = results;
80
- if (filters.apis_used && filters.apis_used.length > 0) {
81
- const requiredApis = filters.apis_used;
82
- filtered = filtered.filter((card) => {
83
- const cardApis = card.metadata?.apis_used ?? [];
84
- return requiredApis.every((api) => cardApis.includes(api));
85
- });
86
- }
87
- if (filters.min_reputation !== void 0 && filters.min_reputation > 0) {
88
- filtered = applyReputationFilter(db, filtered, filters.min_reputation);
89
- }
90
- return filtered;
91
- }
92
- function filterCards(db, filters) {
93
- const conditions = [];
94
- const params = [];
95
- if (filters.level !== void 0) {
96
- conditions.push(`json_extract(data, '$.level') = ?`);
97
- params.push(filters.level);
98
- }
99
- if (filters.online !== void 0) {
100
- conditions.push(`json_extract(data, '$.availability.online') = ?`);
101
- params.push(filters.online ? 1 : 0);
102
- }
103
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
104
- const sql = `SELECT data FROM capability_cards ${whereClause}`;
105
- const stmt = db.prepare(sql);
106
- const rows = stmt.all(...params);
107
- let cards = rows.map((row) => JSON.parse(row.data));
108
- if (filters.min_reputation !== void 0 && filters.min_reputation > 0) {
109
- cards = applyReputationFilter(db, cards, filters.min_reputation);
110
- }
111
- return cards;
112
- }
113
- function applyReputationFilter(db, cards, minReputation) {
114
- const owners = [...new Set(cards.map((c) => c.owner))];
115
- const reputationMap = /* @__PURE__ */ new Map();
116
- for (const owner of owners) {
117
- reputationMap.set(owner, getReputationScore(db, owner));
118
- }
119
- return cards.filter((card) => {
120
- const score = reputationMap.get(card.owner) ?? 0.5;
121
- return score >= minReputation;
122
- });
123
- }
124
- function buildReputationMap(db, owners) {
125
- const unique = [...new Set(owners)];
126
- const map = /* @__PURE__ */ new Map();
127
- for (const owner of unique) {
128
- map.set(owner, getReputationScore(db, owner));
129
- }
130
- return map;
131
- }
132
-
133
- export {
134
- computeReputation,
135
- searchCards,
136
- filterCards,
137
- buildReputationMap
138
- };
@@ -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
- };