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.
- package/dist/{chunk-TBJ3FZKZ.js → chunk-7Q2XUXSA.js} +1 -1
- package/dist/{chunk-LJM7FHPM.js → chunk-BZOJ7HBT.js} +33 -1
- package/dist/{chunk-FTZTEHYG.js → chunk-DEWY7OQK.js} +135 -8
- package/dist/{chunk-CUONY5TO.js → chunk-EJKW57ZV.js} +19 -1
- package/dist/chunk-EZVOG7QS.js +161 -0
- package/dist/{chunk-E2OKP5CY.js → chunk-GJETGML6.js} +181 -83
- package/dist/{chunk-YHY7OG6S.js → chunk-GWMMYVLL.js} +4 -4
- package/dist/{chunk-D6RKW2XG.js → chunk-JLNHMNES.js} +16 -3
- package/dist/{chunk-5AAFG2V2.js → chunk-KBQNTUTN.js} +239 -24
- package/dist/{chunk-C537SFHV.js → chunk-LOUEJI6X.js} +4 -4
- package/dist/{chunk-ALX4WS3A.js → chunk-NP55V7RQ.js} +1 -1
- package/dist/{chunk-X32NE6V4.js → chunk-RBXTWWUH.js} +1 -1
- package/dist/{chunk-O2OYBAVR.js → chunk-SRBVKO2V.js} +9 -0
- package/dist/{chunk-7EF3HYVZ.js → chunk-STJLWMXH.js} +48 -4
- package/dist/{chunk-5GME4KJZ.js → chunk-UYCD3JBZ.js} +3 -3
- package/dist/{chunk-P4LOYSLA.js → chunk-WKWJWKX7.js} +286 -81
- package/dist/cli/index.js +35 -57
- package/dist/{client-HKV3QWZ3.js → client-66TFS7RS.js} +4 -2
- package/dist/{conduct-W6XF6DJW.js → conduct-A6COHLHY.js} +8 -8
- package/dist/{conduct-YB64OHI6.js → conduct-IUVAXUAV.js} +8 -8
- package/dist/{conductor-mode-TFCVCQHU.js → conductor-mode-D5TFQW5L.js} +2 -2
- package/dist/{conductor-mode-AKREGDIU.js → conductor-mode-L2MB44BW.js} +7 -7
- package/dist/{execute-AYQWORVH.js → execute-5AWLARB5.js} +5 -5
- package/dist/{execute-EPE6MZLT.js → execute-WOS457HW.js} +2 -2
- package/dist/index.js +438 -92
- package/dist/{publish-capability-AH2HDW54.js → publish-capability-JJCBBMSX.js} +2 -2
- package/dist/{request-HCCXSKAY.js → request-6YQLA7K3.js} +13 -8
- package/dist/{serve-skill-SZAQT5T5.js → serve-skill-X7TZSILV.js} +5 -5
- package/dist/{server-LMY2A3GT.js → server-5TSP4DBX.js} +10 -12
- package/dist/{service-coordinator-WGH6B2VT.js → service-coordinator-WTUSMPY6.js} +69 -46
- package/dist/skills/agentbnb/bootstrap.js +459 -189
- 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-OH7BP5NP.js +0 -96
- 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.
|
|
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
|
-
"
|
|
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-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
|
-
};
|