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.
- package/dist/{chunk-TBJ3FZKZ.js → chunk-4IPJJRTP.js} +1 -1
- package/dist/chunk-CKOOVZOI.js +158 -0
- package/dist/chunk-CQFBNTGT.js +145 -0
- package/dist/{chunk-P4LOYSLA.js → chunk-DYQOFGGI.js} +331 -416
- package/dist/{chunk-ALX4WS3A.js → chunk-EG6RS4JC.js} +70 -46
- package/dist/{chunk-CUONY5TO.js → chunk-EJKW57ZV.js} +19 -1
- package/dist/{chunk-5AAFG2V2.js → chunk-LKLKYXLV.js} +239 -24
- package/dist/{chunk-7EF3HYVZ.js → chunk-MCED4GDW.js} +499 -86
- package/dist/{chunk-YHY7OG6S.js → chunk-MWOXW7JQ.js} +7 -7
- package/dist/{chunk-E2OKP5CY.js → chunk-QCGIG7WW.js} +182 -86
- package/dist/{chunk-5GME4KJZ.js → chunk-QHZGOG3O.js} +148 -46
- package/dist/{chunk-D6RKW2XG.js → chunk-RYISHSHB.js} +302 -4
- package/dist/{chunk-O2OYBAVR.js → chunk-S3V6R3EN.js} +75 -39
- package/dist/{chunk-X32NE6V4.js → chunk-WNXXLCV5.js} +1 -1
- package/dist/{chunk-C537SFHV.js → chunk-XBGVQMQJ.js} +72 -48
- package/dist/{chunk-FTZTEHYG.js → chunk-Z2GEFFDO.js} +135 -8
- package/dist/cli/index.js +42 -67
- package/dist/{client-HKV3QWZ3.js → client-XOLP5IUZ.js} +4 -2
- package/dist/{conduct-W6XF6DJW.js → conduct-AZFLNUX3.js} +10 -11
- package/dist/{conduct-YB64OHI6.js → conduct-VPUYTNEA.js} +10 -11
- package/dist/{conductor-mode-AKREGDIU.js → conductor-mode-PLTB6MS3.js} +7 -8
- package/dist/{conductor-mode-TFCVCQHU.js → conductor-mode-WKB42PYM.js} +6 -3
- package/dist/{execute-EPE6MZLT.js → execute-NNDCXTN4.js} +3 -2
- package/dist/{execute-AYQWORVH.js → execute-RIRHTIBU.js} +6 -5
- package/dist/index.d.ts +8 -8
- package/dist/index.js +637 -693
- package/dist/{publish-capability-AH2HDW54.js → publish-capability-QDR2QIZ2.js} +2 -2
- package/dist/{request-HCCXSKAY.js → request-NX7GSPIG.js} +31 -36
- package/dist/{serve-skill-SZAQT5T5.js → serve-skill-E6EJQYAK.js} +10 -9
- package/dist/{server-LMY2A3GT.js → server-VBCT32FC.js} +12 -18
- package/dist/{service-coordinator-WGH6B2VT.js → service-coordinator-KMSA6BST.js} +137 -69
- package/dist/skills/agentbnb/bootstrap.js +561 -247
- package/package.json +13 -17
- package/skills/agentbnb/bootstrap.test.ts +8 -6
- package/skills/agentbnb/bootstrap.ts +21 -13
- package/skills/agentbnb/install.sh +0 -0
- package/dist/chunk-64AK4FJM.js +0 -84
- package/dist/chunk-KF3TZHA5.js +0 -91
- package/dist/chunk-LJM7FHPM.js +0 -138
- 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.
|
|
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
|
-
"
|
|
96
|
-
"
|
|
97
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
|
178
|
-
* @returns Absolute path to the CLI, or null if
|
|
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
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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
|
-
|
|
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 = {
|
|
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
|
-
|
|
237
|
-
|
|
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(
|
|
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(
|
|
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
|
package/dist/chunk-64AK4FJM.js
DELETED
|
@@ -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
|
-
};
|
package/dist/chunk-KF3TZHA5.js
DELETED
|
@@ -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
|
-
};
|
package/dist/chunk-LJM7FHPM.js
DELETED
|
@@ -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
|
-
};
|
package/dist/chunk-OH7BP5NP.js
DELETED
|
@@ -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
|
-
};
|