@agentvault/agentvault 0.14.12 → 0.14.14

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/cli.js CHANGED
@@ -45103,22 +45103,6 @@ var init_scan_engine = __esm({
45103
45103
  /\bghp_[a-zA-Z0-9]{36,}\b/g,
45104
45104
  /\bglpat-[a-zA-Z0-9_-]{20,}\b/g,
45105
45105
  /\bxoxb-[0-9]+-[0-9]+-[a-zA-Z0-9]+\b/g
45106
- ],
45107
- prompt_injection: [
45108
- /\bignore\s+(?:all\s+)?(?:previous|above|prior)\s+instructions\b/gi,
45109
- /\byou\s+are\s+now\s+(?:a|an)\s+/gi,
45110
- /\bsystem\s*:\s*you\b/gi,
45111
- /\bDAN\s+mode\b/gi,
45112
- /\bdo\s+anything\s+now\b/gi,
45113
- /\bdo\s+not\s+follow\s+any\s+(?:other\s+)?rules\b/gi,
45114
- /\bjailbreak\b/gi
45115
- ],
45116
- shell_injection: [
45117
- /\bcurl\s+.*\|\s*(?:sh|bash|zsh)\b/gi,
45118
- /\beval\s*\(/gi,
45119
- /\bexec\s*\(/gi,
45120
- /\bchmod\s+\+x\b/gi,
45121
- /\brm\s+-rf\s+\//gi
45122
45106
  ]
45123
45107
  };
45124
45108
  ScanEngine = class {
@@ -45230,24 +45214,6 @@ var init_scan_engine = __esm({
45230
45214
  }
45231
45215
  return false;
45232
45216
  }
45233
- if (builtinId === "prompt_injection") {
45234
- const patterns = BUILTIN_PATTERNS.prompt_injection;
45235
- for (const p2 of patterns) {
45236
- const regex = new RegExp(p2.source, p2.flags);
45237
- if (regex.test(text))
45238
- return true;
45239
- }
45240
- return false;
45241
- }
45242
- if (builtinId === "shell_injection") {
45243
- const patterns = BUILTIN_PATTERNS.shell_injection;
45244
- for (const p2 of patterns) {
45245
- const regex = new RegExp(p2.source, p2.flags);
45246
- if (regex.test(text))
45247
- return true;
45248
- }
45249
- return false;
45250
- }
45251
45217
  return false;
45252
45218
  }
45253
45219
  _buildMatchSummary(rule) {
@@ -45267,48 +45233,6 @@ var init_scan_engine = __esm({
45267
45233
  _escapeRegex(str) {
45268
45234
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
45269
45235
  }
45270
- /**
45271
- * Scan a workspace file (e.g. SOUL.md) against all builtin patterns.
45272
- * Runs api_keys, pii_*, prompt_injection, and shell_injection checks
45273
- * regardless of rule direction.
45274
- */
45275
- static scanWorkspaceFile(content) {
45276
- const violations = [];
45277
- let blocked = false;
45278
- let flagged = false;
45279
- const checks = [
45280
- { id: "api_keys", action: "block" },
45281
- { id: "prompt_injection", action: "block" },
45282
- { id: "shell_injection", action: "block" },
45283
- { id: "pii_ssn", action: "flag" },
45284
- { id: "pii_credit_card", action: "flag" },
45285
- { id: "pii_email", action: "flag" }
45286
- ];
45287
- for (const check of checks) {
45288
- const patterns = BUILTIN_PATTERNS[check.id];
45289
- if (!patterns)
45290
- continue;
45291
- for (const p2 of patterns) {
45292
- const regex = new RegExp(p2.source, p2.flags);
45293
- if (regex.test(content)) {
45294
- violations.push({
45295
- rule_id: `workspace_${check.id}`,
45296
- rule_name: check.id,
45297
- action: check.action,
45298
- scanner_type: "builtin",
45299
- match_summary: `builtin:${check.id}`
45300
- });
45301
- if (check.action === "block")
45302
- blocked = true;
45303
- if (check.action === "flag")
45304
- flagged = true;
45305
- break;
45306
- }
45307
- }
45308
- }
45309
- const status = blocked ? "blocked" : flagged ? "flagged" : "clean";
45310
- return { status, violations };
45311
- }
45312
45236
  };
45313
45237
  }
45314
45238
  });
@@ -47740,6 +47664,14 @@ var init_channel = __esm({
47740
47664
  await this._persistState();
47741
47665
  }
47742
47666
  this.emit("a2a_channel_approved", channelData);
47667
+ if (this.config.onA2AChannelReady && convId) {
47668
+ this.config.onA2AChannelReady({
47669
+ channelId,
47670
+ peerHubAddress: peerHub,
47671
+ role,
47672
+ conversationId: convId
47673
+ });
47674
+ }
47743
47675
  }
47744
47676
  if (data.event === "a2a_channel_activated") {
47745
47677
  const actData = data.data || data;
@@ -49260,187 +49192,860 @@ var init_index = __esm({
49260
49192
  }
49261
49193
  });
49262
49194
 
49263
- // src/setup.ts
49264
- var setup_exports = {};
49265
- __export(setup_exports, {
49266
- configurePm2: () => configurePm2,
49267
- installPlugin: () => installPlugin,
49268
- runSetupCommand: () => runSetupCommand
49195
+ // src/create-agent.ts
49196
+ var create_agent_exports = {};
49197
+ __export(create_agent_exports, {
49198
+ findNextPort: () => findNextPort,
49199
+ generateWorkspaceFiles: () => generateWorkspaceFiles,
49200
+ openclawHome: () => openclawHome,
49201
+ readOpenClawConfig: () => readOpenClawConfig,
49202
+ runCreateCommand: () => runCreateCommand
49269
49203
  });
49270
- import { execSync, spawnSync } from "node:child_process";
49271
- import * as readline from "node:readline";
49272
- import { resolve } from "node:path";
49273
- async function runSetupCommand(options) {
49274
- const { token: token2, name: name2, apiUrl: apiUrl2 } = options;
49275
- const dataDir2 = resolve(options.dataDir.replace(/^~/, process.env.HOME ?? "~"));
49276
- const alreadyEnrolled = await isStateValid(dataDir2);
49277
- if (alreadyEnrolled && !options.force) {
49278
- console.log(`
49279
- Already enrolled (state in ${dataDir2}).
49280
- Re-enroll with --force, or update plugin with: openclaw plugins update agentvault
49281
- `);
49282
- return;
49283
- }
49284
- console.log(`
49285
- \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
49286
- \u2551 AgentVault \u2014 First-Time Setup \u2551
49287
- \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
49288
-
49289
- Agent name : ${name2}${options.accountId ? `
49290
- Account ID : ${options.accountId}` : ""}
49291
- Data dir : ${dataDir2}
49292
- API : ${apiUrl2}
49293
- `);
49294
- let enrollDone = false;
49295
- const channel2 = new SecureChannel({
49296
- inviteToken: token2,
49297
- dataDir: dataDir2,
49298
- apiUrl: apiUrl2,
49299
- agentName: name2,
49300
- onMessage: () => {
49301
- },
49302
- // Not handling messages during setup
49303
- onStateChange: (state) => {
49304
- switch (state) {
49305
- case "enrolling":
49306
- console.log(" Enrolling with AgentVault server...");
49307
- break;
49308
- case "polling":
49309
- console.log(" Waiting for approval in your AgentVault dashboard...");
49310
- if (channel2.fingerprint) {
49311
- console.log(`
49312
- Fingerprint: ${channel2.fingerprint}`);
49313
- console.log(" Verify this fingerprint matches the one shown in your dashboard");
49314
- console.log(" before clicking Approve.\n");
49315
- }
49316
- break;
49317
- case "activating":
49318
- console.log(" Approved! Setting up encryption...");
49319
- break;
49320
- case "ready":
49321
- enrollDone = true;
49322
- console.log(" \u2705 Enrollment complete! Secure channel established.\n");
49323
- break;
49324
- case "error":
49325
- console.error(" \u274C Setup encountered an error.");
49326
- break;
49204
+ import { execSync } from "node:child_process";
49205
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync } from "node:fs";
49206
+ import { join as join4 } from "node:path";
49207
+ function openclawHome() {
49208
+ const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
49209
+ return join4(home, ".openclaw");
49210
+ }
49211
+ function readOpenClawConfig(home) {
49212
+ const configPath = join4(home, "openclaw.json");
49213
+ const raw = readFileSync(configPath, "utf-8");
49214
+ return JSON.parse(raw);
49215
+ }
49216
+ function writeOpenClawConfig(home, config, backupSuffix) {
49217
+ const configPath = join4(home, "openclaw.json");
49218
+ const backupPath = `${configPath}.bak.pre-${backupSuffix}`;
49219
+ copyFileSync(configPath, backupPath);
49220
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
49221
+ }
49222
+ function collectPorts(config) {
49223
+ const ports = [];
49224
+ const accounts = config?.channels?.agentvault?.accounts;
49225
+ if (accounts && typeof accounts === "object") {
49226
+ for (const acct of Object.values(accounts)) {
49227
+ if (typeof acct.httpPort === "number") {
49228
+ ports.push(acct.httpPort);
49327
49229
  }
49328
49230
  }
49329
- });
49330
- channel2.on("error", (err) => {
49331
- console.error(`
49332
- \u274C Setup failed: ${err.message}
49333
- `);
49334
- process.exit(1);
49335
- });
49336
- await new Promise((res, rej) => {
49337
- const check = setInterval(() => {
49338
- if (enrollDone) {
49339
- clearInterval(check);
49340
- res();
49341
- }
49342
- }, 500);
49343
- channel2.start().catch((err) => {
49344
- clearInterval(check);
49345
- rej(err);
49346
- });
49347
- });
49348
- await channel2.stop();
49349
- console.log(" Installing AgentVault plugin in OpenClaw...\n");
49350
- const home = process.env.HOME ?? "";
49351
- const extraPaths = [
49352
- `${home}/.local/bin`,
49353
- `${home}/.pnpm/bin`,
49354
- `${home}/Library/pnpm/bin`,
49355
- "/usr/local/bin",
49356
- "/opt/homebrew/bin"
49357
- ].join(":");
49358
- const env = { ...process.env, PATH: `${extraPaths}:${process.env.PATH ?? ""}` };
49359
- const pluginInstalled = installPlugin(env);
49360
- if (!pluginInstalled) {
49361
- if (options.accountId) {
49362
- console.log(`
49363
- \u26A0\uFE0F Could not auto-configure OpenClaw (is 'openclaw' in your PATH?).
49231
+ }
49232
+ return ports;
49233
+ }
49234
+ function findNextPort(config, startPort = 18800) {
49235
+ const ports = collectPorts(config);
49236
+ if (ports.length === 0) return startPort;
49237
+ return Math.max(...ports, startPort - 1) + 1;
49238
+ }
49239
+ function isPortInUse(config, port) {
49240
+ return collectPorts(config).includes(port);
49241
+ }
49242
+ function generateWorkspaceFiles(name2) {
49243
+ const displayName = name2.charAt(0).toUpperCase() + name2.slice(1).toLowerCase();
49244
+ return {
49245
+ "IDENTITY.md": `# IDENTITY.md - Who Am I?
49364
49246
 
49365
- 1. Install the plugin:
49366
- openclaw plugins install @agentvault/agentvault
49247
+ - **Name:** ${displayName}
49248
+ - **Creature:** AI assistant \u2014 a capable peer agent in the AgentVault network
49249
+ - **Vibe:** Direct, competent, focused on their specialty domain
49250
+ - **Emoji:** (placeholder \u2014 update to something fitting)
49251
+ - **Avatar:** _(none set yet)_
49367
49252
 
49368
- 2. Register the plugin in the allow list:
49369
- openclaw config set plugins.allow '["agentvault"]'
49253
+ > TODO: Customize this file to give ${name2} a distinct identity.
49254
+ `,
49255
+ "SOUL.md": `# SOUL.md - Who You Are
49370
49256
 
49371
- 3. Add this to your OpenClaw config (openclaw.yaml or openclaw.json):
49372
- channels:
49373
- agentvault:
49374
- apiUrl: "${apiUrl2}"
49375
- accounts:
49376
- ${options.accountId}:
49377
- dataDir: "${dataDir2}"
49378
- agentName: "${name2}"
49257
+ > TODO: Define ${name2}'s personality, tone, and behavioral rules.
49258
+ > Copy and adapt from ~/.openclaw/workspace/SOUL.md as a starting point.
49379
49259
 
49380
- 4. (Recommended) Install pm2 for auto-restart and crash recovery:
49381
- npm install -g pm2
49382
- pm2 start "openclaw gateway start" --name openclaw-gateway
49383
- pm2 startup
49384
- pm2 save
49260
+ ## Core Truths
49385
49261
 
49386
- 5. Restart the gateway:
49387
- openclaw gateway restart
49388
- `);
49389
- } else {
49390
- console.log(`
49391
- \u26A0\uFE0F Could not auto-configure OpenClaw (is 'openclaw' in your PATH?).
49262
+ - Be genuinely helpful, not performatively helpful.
49263
+ - Have opinions. Be resourceful before asking.
49264
+ - Earn trust through competence.
49392
49265
 
49393
- 1. Install the plugin:
49394
- openclaw plugins install @agentvault/agentvault
49266
+ ## Channel Reply Rules
49395
49267
 
49396
- 2. Register the plugin in the allow list:
49397
- openclaw config set plugins.allow '["agentvault"]'
49268
+ - Never include reasoning or internal logic in visible replies.
49269
+ - No narrating your approach before or after tool calls.
49270
+ - Just deliver the answer \u2014 clean and direct.
49398
49271
 
49399
- 3. Add this to your OpenClaw config (openclaw.yaml or openclaw.json):
49400
- channels:
49401
- agentvault:
49402
- dataDir: "${dataDir2}"
49403
- apiUrl: "${apiUrl2}"
49404
- agentName: "${name2}"
49272
+ ## Vibe
49405
49273
 
49406
- 4. (Recommended) Install pm2 for auto-restart and crash recovery:
49407
- npm install -g pm2
49408
- pm2 start "openclaw gateway start" --name openclaw-gateway
49409
- pm2 startup
49410
- pm2 save
49274
+ _(Define ${name2}'s specific personality here.)_
49275
+ `,
49276
+ "HEARTBEAT.md": `# Heartbeat
49411
49277
 
49412
- 5. Restart the gateway:
49413
- openclaw gateway restart
49414
- `);
49415
- }
49416
- return;
49417
- }
49418
- console.log("\n Registering AgentVault channel in OpenClaw config...\n");
49419
- const configPrefix = options.accountId ? `channels.agentvault.accounts.${options.accountId}` : "channels.agentvault";
49420
- const patchCommands = [
49421
- // When using multi-agent, set shared apiUrl at top level too
49422
- ...options.accountId ? [`openclaw config set channels.agentvault.apiUrl "${apiUrl2}"`] : [],
49423
- `openclaw config set ${configPrefix}.dataDir "${dataDir2}"`,
49424
- `openclaw config set ${configPrefix}.apiUrl "${apiUrl2}"`,
49425
- `openclaw config set ${configPrefix}.agentName "${name2}"`,
49426
- `openclaw config set plugins.allow '["agentvault"]'`
49427
- ];
49428
- let configPatched = false;
49278
+ - Stay available. If nothing needs attention, reply HEARTBEAT_OK.
49279
+ - **Heartbeat replies are INTERNAL ONLY.** Reply with ONLY \`HEARTBEAT_OK\` when nothing needs attention.
49280
+ - If something genuinely urgent needs attention, send it proactively FIRST, THEN reply HEARTBEAT_OK.
49281
+ `,
49282
+ "MEMORY.md": `# MEMORY.md - Long-Term Memory
49283
+
49284
+ _(Empty \u2014 ${name2} starts with a clean memory. Update as the agent learns.)_
49285
+ `
49286
+ };
49287
+ }
49288
+ async function runCreateCommand(options) {
49289
+ const { name: name2, token: token2, apiUrl: apiUrl2, force } = options;
49290
+ const home = openclawHome();
49291
+ const configPath = join4(home, "openclaw.json");
49292
+ const workspaceDir = join4(home, `workspace-${name2}`);
49293
+ const dataDir2 = join4(home, "agents", name2, "agentvault-data");
49294
+ const templateDir = join4(home, "workspace");
49295
+ console.log(`
49296
+ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
49297
+ \u2551 AgentVault \u2014 Create New Agent \u2551
49298
+ \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
49299
+ `);
49300
+ console.log(" Step 1/7 \u2014 Preflight checks...");
49301
+ try {
49302
+ execSync("openclaw --version", { stdio: "pipe" });
49303
+ } catch {
49304
+ console.error(" Error: 'openclaw' not found in PATH. Is OpenClaw installed?");
49305
+ process.exit(1);
49306
+ }
49307
+ if (!existsSync(configPath)) {
49308
+ console.error(` Error: openclaw.json not found at ${configPath}`);
49309
+ process.exit(1);
49310
+ }
49311
+ console.log(" Preflight passed.\n");
49312
+ console.log(" Step 2/7 \u2014 Detecting port...");
49313
+ const config = readOpenClawConfig(home);
49314
+ let port;
49315
+ if (options.port != null) {
49316
+ port = options.port;
49317
+ if (isPortInUse(config, port)) {
49318
+ console.error(` Error: Port ${port} is already in use in openclaw.json.`);
49319
+ process.exit(1);
49320
+ }
49321
+ console.log(` Using explicit port ${port}.
49322
+ `);
49323
+ } else {
49324
+ port = findNextPort(config);
49325
+ console.log(` Auto-assigned port ${port}.
49326
+ `);
49327
+ }
49328
+ console.log(" Step 3/7 \u2014 Creating agent with OpenClaw...");
49329
+ try {
49330
+ execSync(`openclaw agents add -- ${name2}`, { stdio: "pipe" });
49331
+ console.log(` Agent '${name2}' created.
49332
+ `);
49333
+ } catch {
49334
+ console.log(` Warning: 'openclaw agents add' failed \u2014 agent may already exist. Continuing.
49335
+ `);
49336
+ }
49337
+ console.log(" Step 4/7 \u2014 Creating directories...");
49338
+ mkdirSync(workspaceDir, { recursive: true });
49339
+ mkdirSync(dataDir2, { recursive: true });
49340
+ console.log(` Workspace: ${workspaceDir}`);
49341
+ console.log(` DataDir: ${dataDir2}
49342
+ `);
49343
+ console.log(" Step 5/7 \u2014 Writing workspace files...");
49344
+ const files = generateWorkspaceFiles(name2);
49345
+ for (const [filename, content] of Object.entries(files)) {
49346
+ writeFileSync(join4(workspaceDir, filename), content, "utf-8");
49347
+ }
49348
+ for (const copyFile of ["AGENTS.md", "USER.md"]) {
49349
+ const src = join4(templateDir, copyFile);
49350
+ if (existsSync(src)) {
49351
+ copyFileSync(src, join4(workspaceDir, copyFile));
49352
+ console.log(` Copied ${copyFile} from template workspace.`);
49353
+ }
49354
+ }
49355
+ console.log(" Workspace files written.\n");
49356
+ console.log(" Step 6/7 \u2014 Enrolling with AgentVault...\n");
49357
+ await runSetupCommand({
49358
+ token: token2,
49359
+ name: name2,
49360
+ apiUrl: apiUrl2,
49361
+ dataDir: dataDir2,
49362
+ accountId: name2,
49363
+ force
49364
+ });
49365
+ console.log("\n Step 7/7 \u2014 Patching openclaw.json...");
49366
+ try {
49367
+ const freshConfig = readOpenClawConfig(home);
49368
+ let patched = false;
49369
+ const avChannel = freshConfig?.channels?.agentvault;
49370
+ if (avChannel?.accounts) {
49371
+ const acct = avChannel.accounts[name2];
49372
+ if (acct) {
49373
+ acct.httpPort = port;
49374
+ patched = true;
49375
+ }
49376
+ }
49377
+ if (avChannel) {
49378
+ const bindings = avChannel.bindings;
49379
+ const hasWildcard = bindings?.some(
49380
+ (b2) => b2.match?.accountId === "*"
49381
+ );
49382
+ if (!hasWildcard) {
49383
+ avChannel.bindings = [{ match: { accountId: "*" } }, ...bindings ?? []];
49384
+ console.log(` Added wildcard binding (accountId: "*").`);
49385
+ }
49386
+ }
49387
+ if (patched) {
49388
+ writeOpenClawConfig(home, freshConfig, name2);
49389
+ console.log(` httpPort set to ${port}.
49390
+ `);
49391
+ } else {
49392
+ console.log(` Warning: Could not find account '${name2}' in channels.agentvault.accounts.`);
49393
+ console.log(` You may need to manually set httpPort: ${port} in openclaw.json.
49394
+ `);
49395
+ }
49396
+ } catch (err) {
49397
+ console.log(` Warning: Failed to patch openclaw.json: ${err.message}
49398
+ `);
49399
+ }
49400
+ console.log(" Verifying agent...");
49401
+ try {
49402
+ const http = await import("node:http");
49403
+ await new Promise((resolve4) => {
49404
+ const req = http.get(`http://127.0.0.1:${port}/status`, { timeout: 3e3 }, (res) => {
49405
+ console.log(` Port ${port} responded (HTTP ${res.statusCode}).`);
49406
+ res.resume();
49407
+ resolve4();
49408
+ });
49409
+ req.on("error", () => {
49410
+ console.log(` Port ${port} not yet responding \u2014 gateway may need a moment.`);
49411
+ resolve4();
49412
+ });
49413
+ req.on("timeout", () => {
49414
+ req.destroy();
49415
+ console.log(` Port ${port} timed out \u2014 check gateway logs.`);
49416
+ resolve4();
49417
+ });
49418
+ });
49419
+ } catch {
49420
+ console.log(" Verification skipped.");
49421
+ }
49422
+ if (process.platform === "darwin") {
49423
+ const { validatePlist: validatePlist2 } = await init_doctor().then(() => doctor_exports);
49424
+ const plistResult = validatePlist2();
49425
+ if (plistResult.status === "stale") {
49426
+ console.log(`
49427
+ \u26A0\uFE0F macOS LaunchAgent plist has stale paths.
49428
+ Run to diagnose and fix: npx @agentvault/agentvault doctor
49429
+ `);
49430
+ }
49431
+ }
49432
+ console.log(`
49433
+ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
49434
+ Agent '${name2}' created successfully!
49435
+ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
49436
+
49437
+ Workspace: ${workspaceDir}
49438
+ DataDir: ${dataDir2}
49439
+ HTTP Port: ${port}
49440
+
49441
+ Next steps:
49442
+ 1. Edit ${workspaceDir}/SOUL.md \u2014 give ${name2} a personality
49443
+ 2. Edit ${workspaceDir}/IDENTITY.md \u2014 set name, emoji, vibe
49444
+ 3. Approve the agent in the AgentVault app
49445
+ `);
49446
+ }
49447
+ var init_create_agent = __esm({
49448
+ async "src/create-agent.ts"() {
49449
+ "use strict";
49450
+ await init_setup();
49451
+ }
49452
+ });
49453
+
49454
+ // src/doctor.ts
49455
+ var doctor_exports = {};
49456
+ __export(doctor_exports, {
49457
+ applyPlistFix: () => applyPlistFix,
49458
+ checkAgentDataDirs: () => checkAgentDataDirs,
49459
+ checkAgentVaultChannel: () => checkAgentVaultChannel,
49460
+ checkConfigExists: () => checkConfigExists,
49461
+ checkGatewayPort: () => checkGatewayPort,
49462
+ checkOpenClawInstalled: () => checkOpenClawInstalled,
49463
+ checkPlist: () => checkPlist,
49464
+ checkPluginsAllow: () => checkPluginsAllow,
49465
+ checkPm2Status: () => checkPm2Status,
49466
+ parsePlist: () => parsePlist,
49467
+ plistPath: () => plistPath,
49468
+ runDoctorCommand: () => runDoctorCommand,
49469
+ validatePlist: () => validatePlist
49470
+ });
49471
+ import { execSync as execSync2 } from "node:child_process";
49472
+ import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, chmodSync } from "node:fs";
49473
+ import { join as join5 } from "node:path";
49474
+ import { createInterface } from "node:readline";
49475
+ function checkOpenClawInstalled() {
49476
+ try {
49477
+ const out = execSync2("openclaw --version", { stdio: "pipe", timeout: 1e4 });
49478
+ const version = out.toString().trim();
49479
+ return { name: "OpenClaw installed", status: "pass", message: version };
49480
+ } catch {
49481
+ return {
49482
+ name: "OpenClaw installed",
49483
+ status: "fail",
49484
+ message: "'openclaw' not found in PATH"
49485
+ };
49486
+ }
49487
+ }
49488
+ function checkConfigExists(home) {
49489
+ const configPath = join5(home, "openclaw.json");
49490
+ if (!existsSync2(configPath)) {
49491
+ return {
49492
+ name: "Config exists",
49493
+ status: "fail",
49494
+ message: `Not found: ${configPath}`
49495
+ };
49496
+ }
49497
+ try {
49498
+ JSON.parse(readFileSync2(configPath, "utf-8"));
49499
+ return { name: "Config exists", status: "pass", message: configPath };
49500
+ } catch {
49501
+ return {
49502
+ name: "Config exists",
49503
+ status: "fail",
49504
+ message: `Invalid JSON: ${configPath}`
49505
+ };
49506
+ }
49507
+ }
49508
+ function checkAgentVaultChannel(config) {
49509
+ if (!config) {
49510
+ return {
49511
+ name: "AgentVault channel",
49512
+ status: "fail",
49513
+ message: "Config is null"
49514
+ };
49515
+ }
49516
+ if (config.channels?.agentvault) {
49517
+ return { name: "AgentVault channel", status: "pass", message: "channels.agentvault present" };
49518
+ }
49519
+ return {
49520
+ name: "AgentVault channel",
49521
+ status: "fail",
49522
+ message: "channels.agentvault not found in config"
49523
+ };
49524
+ }
49525
+ function checkPluginsAllow(config) {
49526
+ if (!config) {
49527
+ return { name: "Plugin allow-listed", status: "warn", message: "Config is null" };
49528
+ }
49529
+ const allow = config.plugins?.allow;
49530
+ if (!Array.isArray(allow)) {
49531
+ return {
49532
+ name: "Plugin allow-listed",
49533
+ status: "warn",
49534
+ message: "plugins.allow not defined"
49535
+ };
49536
+ }
49537
+ if (allow.includes("agentvault")) {
49538
+ return { name: "Plugin allow-listed", status: "pass", message: "agentvault in plugins.allow" };
49539
+ }
49540
+ return {
49541
+ name: "Plugin allow-listed",
49542
+ status: "warn",
49543
+ message: "'agentvault' not in plugins.allow list"
49544
+ };
49545
+ }
49546
+ function checkPlist() {
49547
+ if (process.platform !== "darwin") {
49548
+ return { name: "macOS LaunchAgent plist", status: "skip", message: "Not macOS" };
49549
+ }
49550
+ const result = validatePlist();
49551
+ switch (result.status) {
49552
+ case "ok":
49553
+ return { name: "macOS LaunchAgent plist", status: "pass", message: "Plist paths valid" };
49554
+ case "already-fixed":
49555
+ return { name: "macOS LaunchAgent plist", status: "pass", message: "Wrapper script already configured" };
49556
+ case "stale":
49557
+ return {
49558
+ name: "macOS LaunchAgent plist",
49559
+ status: "fail",
49560
+ message: `Stale path: ${result.stalePaths?.[0] ?? "unknown"}`
49561
+ };
49562
+ case "missing":
49563
+ return {
49564
+ name: "macOS LaunchAgent plist",
49565
+ status: "warn",
49566
+ message: `Plist not found: ${result.plistPath ?? PLIST_FILENAME}`
49567
+ };
49568
+ default:
49569
+ return { name: "macOS LaunchAgent plist", status: "skip", message: "Skipped" };
49570
+ }
49571
+ }
49572
+ function checkGatewayPort() {
49573
+ try {
49574
+ execSync2("curl -sf --max-time 3 http://127.0.0.1:18789/", { stdio: "pipe" });
49575
+ return { name: "Gateway port (18789)", status: "pass", message: "Responding" };
49576
+ } catch {
49577
+ return {
49578
+ name: "Gateway port (18789)",
49579
+ status: "fail",
49580
+ message: "No response on 127.0.0.1:18789"
49581
+ };
49582
+ }
49583
+ }
49584
+ function checkAgentDataDirs(config) {
49585
+ if (!config) {
49586
+ return { name: "Agent data dirs", status: "warn", message: "Config is null" };
49587
+ }
49588
+ const home = process.env.HOME ?? "";
49589
+ const warnings = [];
49590
+ const av = config.channels?.agentvault;
49591
+ if (!av) {
49592
+ return { name: "Agent data dirs", status: "warn", message: "No agentvault channel" };
49593
+ }
49594
+ const checkDir = (label, dataDir2) => {
49595
+ const resolved = dataDir2.replace(/^~/, home);
49596
+ if (!existsSync2(resolved)) {
49597
+ warnings.push(`${label}: dir missing (${resolved})`);
49598
+ return;
49599
+ }
49600
+ const statePath2 = join5(resolved, "agentvault.json");
49601
+ if (!existsSync2(statePath2)) {
49602
+ warnings.push(`${label}: no agentvault.json`);
49603
+ }
49604
+ };
49605
+ if (av.accounts && typeof av.accounts === "object") {
49606
+ for (const [id, acct] of Object.entries(av.accounts)) {
49607
+ if (acct.dataDir) checkDir(id, acct.dataDir);
49608
+ }
49609
+ } else if (av.dataDir) {
49610
+ checkDir("default", av.dataDir);
49611
+ }
49612
+ if (warnings.length > 0) {
49613
+ return { name: "Agent data dirs", status: "warn", message: warnings.join("; ") };
49614
+ }
49615
+ return { name: "Agent data dirs", status: "pass", message: "All data dirs valid" };
49616
+ }
49617
+ function checkPm2Status() {
49618
+ try {
49619
+ execSync2("pm2 --version", { stdio: "pipe", timeout: 5e3 });
49620
+ } catch {
49621
+ return { name: "pm2 status", status: "skip", message: "pm2 not installed" };
49622
+ }
49623
+ try {
49624
+ const info = execSync2("pm2 describe openclaw-gateway", { stdio: "pipe", timeout: 5e3 });
49625
+ const out = info.toString();
49626
+ if (out.includes("online")) {
49627
+ return { name: "pm2 status", status: "pass", message: "openclaw-gateway: online" };
49628
+ }
49629
+ if (out.includes("stopped")) {
49630
+ return { name: "pm2 status", status: "warn", message: "openclaw-gateway: stopped" };
49631
+ }
49632
+ return { name: "pm2 status", status: "warn", message: "openclaw-gateway: unknown state" };
49633
+ } catch {
49634
+ return { name: "pm2 status", status: "warn", message: "openclaw-gateway not registered in pm2" };
49635
+ }
49636
+ }
49637
+ function plistPath() {
49638
+ const home = process.env.HOME ?? "";
49639
+ return join5(home, "Library", "LaunchAgents", PLIST_FILENAME);
49640
+ }
49641
+ function parsePlist(plistFile) {
49642
+ if (!existsSync2(plistFile)) return null;
49643
+ try {
49644
+ const json = execSync2(`plutil -convert json -o - "${plistFile}"`, {
49645
+ stdio: "pipe",
49646
+ timeout: 5e3
49647
+ }).toString();
49648
+ const parsed = JSON.parse(json);
49649
+ const programArgs = parsed.ProgramArguments ?? [];
49650
+ const stalePaths = [];
49651
+ const wrapperPath = join5(process.env.HOME ?? "", ".openclaw", WRAPPER_SCRIPT_NAME);
49652
+ for (const arg of programArgs) {
49653
+ if (arg.startsWith("/") && arg !== "/bin/bash" && arg !== wrapperPath) {
49654
+ if (!existsSync2(arg)) {
49655
+ stalePaths.push(arg);
49656
+ }
49657
+ }
49658
+ }
49659
+ return { plistPath: plistFile, programArgs, stalePaths };
49660
+ } catch {
49661
+ return null;
49662
+ }
49663
+ }
49664
+ function validatePlist() {
49665
+ if (process.platform !== "darwin") {
49666
+ return { status: "skip" };
49667
+ }
49668
+ const path = plistPath();
49669
+ if (!existsSync2(path)) {
49670
+ return { status: "missing", plistPath: path };
49671
+ }
49672
+ const info = parsePlist(path);
49673
+ if (!info) {
49674
+ return { status: "missing", plistPath: path };
49675
+ }
49676
+ const home = process.env.HOME ?? "";
49677
+ const wrapperPath = join5(home, ".openclaw", WRAPPER_SCRIPT_NAME);
49678
+ if (info.programArgs.includes(wrapperPath)) {
49679
+ return { status: "already-fixed", plistPath: path };
49680
+ }
49681
+ if (info.stalePaths.length > 0) {
49682
+ return { status: "stale", plistPath: path, stalePaths: info.stalePaths };
49683
+ }
49684
+ return { status: "ok", plistPath: path };
49685
+ }
49686
+ function applyPlistFix(info) {
49687
+ const home = process.env.HOME ?? "";
49688
+ const openclawDir = join5(home, ".openclaw");
49689
+ const wrapperPath = join5(openclawDir, WRAPPER_SCRIPT_NAME);
49690
+ const wrapperContent = `#!/bin/bash
49691
+ exec "$(which openclaw)" gateway start "$@"
49692
+ `;
49693
+ try {
49694
+ writeFileSync2(wrapperPath, wrapperContent, "utf-8");
49695
+ chmodSync(wrapperPath, 493);
49696
+ console.log(` Created wrapper: ${wrapperPath}`);
49697
+ } catch (err) {
49698
+ console.error(` Failed to create wrapper script: ${err.message}`);
49699
+ return false;
49700
+ }
49701
+ const plistBuddy = "/usr/libexec/PlistBuddy";
49702
+ const plist = info.plistPath;
49703
+ try {
49704
+ execSync2(`${plistBuddy} -c "Set :ProgramArguments:0 /bin/bash" "${plist}"`, { stdio: "pipe" });
49705
+ try {
49706
+ execSync2(`${plistBuddy} -c "Set :ProgramArguments:1 ${wrapperPath}" "${plist}"`, { stdio: "pipe" });
49707
+ } catch {
49708
+ execSync2(`${plistBuddy} -c "Add :ProgramArguments:1 string ${wrapperPath}" "${plist}"`, { stdio: "pipe" });
49709
+ }
49710
+ let argCount = info.programArgs.length;
49711
+ for (let i2 = argCount - 1; i2 >= 2; i2--) {
49712
+ try {
49713
+ execSync2(`${plistBuddy} -c "Delete :ProgramArguments:${i2}" "${plist}"`, { stdio: "pipe" });
49714
+ } catch {
49715
+ }
49716
+ }
49717
+ console.log(" Updated plist ProgramArguments.");
49718
+ } catch (err) {
49719
+ console.error(` Failed to update plist: ${err.message}`);
49720
+ return false;
49721
+ }
49722
+ try {
49723
+ execSync2(`launchctl unload "${plist}"`, { stdio: "pipe" });
49724
+ } catch {
49725
+ }
49726
+ try {
49727
+ execSync2(`launchctl load "${plist}"`, { stdio: "pipe" });
49728
+ console.log(" Reloaded LaunchAgent.");
49729
+ } catch (err) {
49730
+ console.error(` Failed to reload LaunchAgent: ${err.message}`);
49731
+ console.log(` Try manually: launchctl load "${plist}"`);
49732
+ return false;
49733
+ }
49734
+ return true;
49735
+ }
49736
+ async function runDoctorCommand(options) {
49737
+ const home = openclawHome();
49738
+ console.log(`
49739
+ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
49740
+ \u2551 AgentVault \u2014 Doctor Diagnostics \u2551
49741
+ \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
49742
+ `);
49743
+ const results = [];
49744
+ results.push(checkOpenClawInstalled());
49745
+ results.push(checkConfigExists(home));
49746
+ let config = null;
49747
+ try {
49748
+ config = readOpenClawConfig(home);
49749
+ } catch {
49750
+ }
49751
+ results.push(checkAgentVaultChannel(config));
49752
+ results.push(checkPluginsAllow(config));
49753
+ results.push(checkPlist());
49754
+ results.push(checkGatewayPort());
49755
+ results.push(checkAgentDataDirs(config));
49756
+ results.push(checkPm2Status());
49757
+ const statusLabels = {
49758
+ pass: "pass",
49759
+ warn: "WARN",
49760
+ fail: "FAIL",
49761
+ skip: "skip"
49762
+ };
49763
+ for (const r2 of results) {
49764
+ const label = `[${statusLabels[r2.status]}]`;
49765
+ console.log(` ${label.padEnd(6)} ${r2.name} \u2014 ${r2.message}`);
49766
+ }
49767
+ const passed = results.filter((r2) => r2.status === "pass").length;
49768
+ const warnings = results.filter((r2) => r2.status === "warn").length;
49769
+ const failed = results.filter((r2) => r2.status === "fail").length;
49770
+ console.log(`
49771
+ \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
49772
+ ${passed} passed ${warnings} warnings ${failed} failed
49773
+ \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
49774
+ `);
49775
+ if (failed > 0) {
49776
+ process.exitCode = 1;
49777
+ }
49778
+ const plistResult = validatePlist();
49779
+ if (plistResult.status === "stale") {
49780
+ const plistInfo = parsePlist(plistResult.plistPath);
49781
+ if (!plistInfo) return;
49782
+ if (options?.fix) {
49783
+ console.log(" Applying plist fix (--fix)...\n");
49784
+ const ok = applyPlistFix(plistInfo);
49785
+ if (ok) {
49786
+ console.log("\n \u2705 Plist fixed. Gateway should start cleanly now.\n");
49787
+ } else {
49788
+ console.log("\n \u274C Plist fix failed. See errors above.\n");
49789
+ }
49790
+ } else {
49791
+ const answer = await ask(" Stale plist detected. Apply wrapper script fix? [y/N] ");
49792
+ if (answer.trim().toLowerCase() === "y") {
49793
+ console.log("");
49794
+ const ok = applyPlistFix(plistInfo);
49795
+ if (ok) {
49796
+ console.log("\n \u2705 Plist fixed. Gateway should start cleanly now.\n");
49797
+ } else {
49798
+ console.log("\n \u274C Plist fix failed. See errors above.\n");
49799
+ }
49800
+ } else {
49801
+ console.log(`
49802
+ To fix later, run:
49803
+ npx @agentvault/agentvault doctor --fix
49804
+ `);
49805
+ }
49806
+ }
49807
+ }
49808
+ }
49809
+ function ask(question) {
49810
+ return new Promise((resolve4) => {
49811
+ const rl2 = createInterface({
49812
+ input: process.stdin,
49813
+ output: process.stdout,
49814
+ terminal: true
49815
+ });
49816
+ rl2.question(question, (answer) => {
49817
+ rl2.close();
49818
+ resolve4(answer);
49819
+ });
49820
+ });
49821
+ }
49822
+ var PLIST_FILENAME, WRAPPER_SCRIPT_NAME;
49823
+ var init_doctor = __esm({
49824
+ async "src/doctor.ts"() {
49825
+ "use strict";
49826
+ await init_create_agent();
49827
+ PLIST_FILENAME = "ai.openclaw.gateway.plist";
49828
+ WRAPPER_SCRIPT_NAME = "start-gateway.sh";
49829
+ }
49830
+ });
49831
+
49832
+ // src/setup.ts
49833
+ var setup_exports = {};
49834
+ __export(setup_exports, {
49835
+ configurePm2: () => configurePm2,
49836
+ installPlugin: () => installPlugin,
49837
+ runSetupCommand: () => runSetupCommand
49838
+ });
49839
+ import { execSync as execSync3, spawnSync } from "node:child_process";
49840
+ import * as readline from "node:readline";
49841
+ import { resolve } from "node:path";
49842
+ async function runSetupCommand(options) {
49843
+ const { token: token2, name: name2, apiUrl: apiUrl2 } = options;
49844
+ const dataDir2 = resolve(options.dataDir.replace(/^~/, process.env.HOME ?? "~"));
49845
+ const alreadyEnrolled = await isStateValid(dataDir2);
49846
+ if (alreadyEnrolled && !options.force) {
49847
+ console.log(`
49848
+ Already enrolled (state in ${dataDir2}).
49849
+ Re-enroll with --force, or update plugin with: openclaw plugins update agentvault
49850
+ `);
49851
+ return;
49852
+ }
49853
+ console.log(`
49854
+ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
49855
+ \u2551 AgentVault \u2014 First-Time Setup \u2551
49856
+ \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
49857
+
49858
+ Agent name : ${name2}${options.accountId ? `
49859
+ Account ID : ${options.accountId}` : ""}
49860
+ Data dir : ${dataDir2}
49861
+ API : ${apiUrl2}
49862
+ `);
49863
+ let enrollDone = false;
49864
+ const channel2 = new SecureChannel({
49865
+ inviteToken: token2,
49866
+ dataDir: dataDir2,
49867
+ apiUrl: apiUrl2,
49868
+ agentName: name2,
49869
+ onMessage: () => {
49870
+ },
49871
+ // Not handling messages during setup
49872
+ onStateChange: (state) => {
49873
+ switch (state) {
49874
+ case "enrolling":
49875
+ console.log(" Enrolling with AgentVault server...");
49876
+ break;
49877
+ case "polling":
49878
+ console.log(" Waiting for approval in your AgentVault dashboard...");
49879
+ if (channel2.fingerprint) {
49880
+ console.log(`
49881
+ Fingerprint: ${channel2.fingerprint}`);
49882
+ console.log(" Verify this fingerprint matches the one shown in your dashboard");
49883
+ console.log(" before clicking Approve.\n");
49884
+ }
49885
+ break;
49886
+ case "activating":
49887
+ console.log(" Approved! Setting up encryption...");
49888
+ break;
49889
+ case "ready":
49890
+ enrollDone = true;
49891
+ console.log(" \u2705 Enrollment complete! Secure channel established.\n");
49892
+ break;
49893
+ case "error":
49894
+ console.error(" \u274C Setup encountered an error.");
49895
+ break;
49896
+ }
49897
+ }
49898
+ });
49899
+ channel2.on("error", (err) => {
49900
+ console.error(`
49901
+ \u274C Setup failed: ${err.message}
49902
+ `);
49903
+ process.exit(1);
49904
+ });
49905
+ await new Promise((res, rej) => {
49906
+ const check = setInterval(() => {
49907
+ if (enrollDone) {
49908
+ clearInterval(check);
49909
+ res();
49910
+ }
49911
+ }, 500);
49912
+ channel2.start().catch((err) => {
49913
+ clearInterval(check);
49914
+ rej(err);
49915
+ });
49916
+ });
49917
+ await channel2.stop();
49918
+ console.log(" Installing AgentVault plugin in OpenClaw...\n");
49919
+ const home = process.env.HOME ?? "";
49920
+ const extraPaths = [
49921
+ `${home}/.local/bin`,
49922
+ `${home}/.pnpm/bin`,
49923
+ `${home}/Library/pnpm/bin`,
49924
+ "/usr/local/bin",
49925
+ "/opt/homebrew/bin"
49926
+ ].join(":");
49927
+ const env = { ...process.env, PATH: `${extraPaths}:${process.env.PATH ?? ""}` };
49928
+ const pluginInstalled = installPlugin(env);
49929
+ if (!pluginInstalled) {
49930
+ if (options.accountId) {
49931
+ console.log(`
49932
+ \u26A0\uFE0F Could not auto-configure OpenClaw (is 'openclaw' in your PATH?).
49933
+
49934
+ 1. Install the plugin:
49935
+ openclaw plugins install @agentvault/agentvault
49936
+
49937
+ 2. Register the plugin in the allow list:
49938
+ openclaw config set plugins.allow '["agentvault"]'
49939
+
49940
+ 3. Add this to your OpenClaw config (openclaw.yaml or openclaw.json):
49941
+ channels:
49942
+ agentvault:
49943
+ apiUrl: "${apiUrl2}"
49944
+ bindings:
49945
+ - match:
49946
+ accountId: "*"
49947
+ accounts:
49948
+ ${options.accountId}:
49949
+ dataDir: "${dataDir2}"
49950
+ agentName: "${name2}"
49951
+
49952
+ 4. (Recommended) Install pm2 for auto-restart and crash recovery:
49953
+ npm install -g pm2
49954
+ pm2 start "openclaw gateway start" --name openclaw-gateway
49955
+ pm2 startup
49956
+ pm2 save
49957
+
49958
+ 5. Restart the gateway:
49959
+ openclaw gateway restart
49960
+ `);
49961
+ } else {
49962
+ console.log(`
49963
+ \u26A0\uFE0F Could not auto-configure OpenClaw (is 'openclaw' in your PATH?).
49964
+
49965
+ 1. Install the plugin:
49966
+ openclaw plugins install @agentvault/agentvault
49967
+
49968
+ 2. Register the plugin in the allow list:
49969
+ openclaw config set plugins.allow '["agentvault"]'
49970
+
49971
+ 3. Add this to your OpenClaw config (openclaw.yaml or openclaw.json):
49972
+ channels:
49973
+ agentvault:
49974
+ dataDir: "${dataDir2}"
49975
+ apiUrl: "${apiUrl2}"
49976
+ agentName: "${name2}"
49977
+
49978
+ 4. (Recommended) Install pm2 for auto-restart and crash recovery:
49979
+ npm install -g pm2
49980
+ pm2 start "openclaw gateway start" --name openclaw-gateway
49981
+ pm2 startup
49982
+ pm2 save
49983
+
49984
+ 5. Restart the gateway:
49985
+ openclaw gateway restart
49986
+ `);
49987
+ }
49988
+ return;
49989
+ }
49990
+ console.log("\n Registering AgentVault channel in OpenClaw config...\n");
49991
+ const configPrefix = options.accountId ? `channels.agentvault.accounts.${options.accountId}` : "channels.agentvault";
49992
+ const patchCommands = [
49993
+ // When using multi-agent, set shared apiUrl at top level too
49994
+ ...options.accountId ? [`openclaw config set channels.agentvault.apiUrl "${apiUrl2}"`] : [],
49995
+ `openclaw config set ${configPrefix}.dataDir "${dataDir2}"`,
49996
+ `openclaw config set ${configPrefix}.apiUrl "${apiUrl2}"`,
49997
+ `openclaw config set ${configPrefix}.agentName "${name2}"`,
49998
+ `openclaw config set plugins.allow '["agentvault"]'`
49999
+ ];
50000
+ let configPatched = false;
49429
50001
  for (const cmd of patchCommands) {
49430
50002
  try {
49431
- execSync(cmd, { stdio: "pipe", env });
50003
+ execSync3(cmd, { stdio: "pipe", env });
49432
50004
  configPatched = true;
49433
50005
  } catch {
49434
50006
  configPatched = false;
49435
50007
  break;
49436
50008
  }
49437
50009
  }
50010
+ if (configPatched) {
50011
+ try {
50012
+ const raw = execSync3("openclaw config get channels.agentvault.bindings", {
50013
+ stdio: "pipe",
50014
+ env
50015
+ }).toString().trim();
50016
+ const hasWildcard = raw.includes('"*"') || raw.includes("'*'");
50017
+ if (!hasWildcard) {
50018
+ execSync3(
50019
+ `openclaw config set channels.agentvault.bindings '[{"match":{"accountId":"*"}}]'`,
50020
+ { stdio: "pipe", env }
50021
+ );
50022
+ }
50023
+ } catch {
50024
+ try {
50025
+ execSync3(
50026
+ `openclaw config set channels.agentvault.bindings '[{"match":{"accountId":"*"}}]'`,
50027
+ { stdio: "pipe", env }
50028
+ );
50029
+ } catch {
50030
+ }
50031
+ }
50032
+ }
49438
50033
  if (configPatched) {
49439
50034
  console.log(` \u2705 Channel registered in OpenClaw config.
49440
50035
  `);
49441
50036
  console.log(" Configuring pm2 process management...\n");
49442
50037
  configurePm2(env);
49443
50038
  await promptAndRestart(env);
50039
+ if (process.platform === "darwin") {
50040
+ const { validatePlist: validatePlist2 } = await init_doctor().then(() => doctor_exports);
50041
+ const plistResult = validatePlist2();
50042
+ if (plistResult.status === "stale") {
50043
+ console.log(`
50044
+ \u26A0\uFE0F macOS LaunchAgent plist has stale paths.
50045
+ Run to diagnose and fix: npx @agentvault/agentvault doctor
50046
+ `);
50047
+ }
50048
+ }
49444
50049
  } else {
49445
50050
  if (options.accountId) {
49446
50051
  console.log(` \u26A0\uFE0F Could not auto-configure OpenClaw channel.
@@ -49475,7 +50080,7 @@ async function runSetupCommand(options) {
49475
50080
  }
49476
50081
  function installPlugin(env) {
49477
50082
  try {
49478
- const info = execSync("openclaw plugins info agentvault", {
50083
+ const info = execSync3("openclaw plugins info agentvault", {
49479
50084
  stdio: "pipe",
49480
50085
  env
49481
50086
  });
@@ -49485,7 +50090,7 @@ function installPlugin(env) {
49485
50090
  if (installedVersion && installedVersion !== VERSION) {
49486
50091
  console.log(` Updating plugin ${installedVersion} \u2192 ${VERSION}...`);
49487
50092
  try {
49488
- execSync("openclaw plugins update agentvault", { stdio: "pipe", env });
50093
+ execSync3("openclaw plugins update agentvault", { stdio: "pipe", env });
49489
50094
  console.log(" Plugin updated.");
49490
50095
  } catch {
49491
50096
  console.log(` \u26A0\uFE0F Update failed \u2014 v${installedVersion} will be used.`);
@@ -49497,7 +50102,7 @@ function installPlugin(env) {
49497
50102
  } catch {
49498
50103
  }
49499
50104
  try {
49500
- execSync("openclaw plugins install @agentvault/agentvault", {
50105
+ execSync3("openclaw plugins install @agentvault/agentvault", {
49501
50106
  stdio: "pipe",
49502
50107
  env
49503
50108
  });
@@ -49510,7 +50115,7 @@ function installPlugin(env) {
49510
50115
  }
49511
50116
  function configurePm2(env) {
49512
50117
  try {
49513
- execSync("pm2 --version", { stdio: "pipe", env });
50118
+ execSync3("pm2 --version", { stdio: "pipe", env });
49514
50119
  } catch {
49515
50120
  console.log(`
49516
50121
  \u2139\uFE0F pm2 not found. For best reliability, install pm2:
@@ -49524,7 +50129,7 @@ function configurePm2(env) {
49524
50129
  return false;
49525
50130
  }
49526
50131
  try {
49527
- const info = execSync("pm2 describe openclaw-gateway", { stdio: "pipe", env });
50132
+ const info = execSync3("pm2 describe openclaw-gateway", { stdio: "pipe", env });
49528
50133
  const infoStr = info.toString();
49529
50134
  if (infoStr.includes("online") || infoStr.includes("stopped")) {
49530
50135
  console.log(" pm2 process 'openclaw-gateway' already exists.");
@@ -49535,20 +50140,20 @@ function configurePm2(env) {
49535
50140
  const isMac = process.platform === "darwin";
49536
50141
  const startCmd = isMac ? "caffeinate -i openclaw gateway start" : "openclaw gateway start";
49537
50142
  try {
49538
- execSync(`pm2 start "${startCmd}" --name openclaw-gateway`, { stdio: "pipe", env });
50143
+ execSync3(`pm2 start "${startCmd}" --name openclaw-gateway`, { stdio: "pipe", env });
49539
50144
  console.log(" \u2705 Gateway registered with pm2.");
49540
50145
  } catch (err) {
49541
50146
  console.log(` \u26A0\uFE0F Failed to register with pm2: ${err}`);
49542
50147
  return false;
49543
50148
  }
49544
50149
  try {
49545
- execSync("pm2 startup", { stdio: "pipe", env });
50150
+ execSync3("pm2 startup", { stdio: "pipe", env });
49546
50151
  console.log(" \u2705 pm2 startup configured (auto-start on boot).");
49547
50152
  } catch {
49548
50153
  console.log(" \u26A0\uFE0F pm2 startup failed \u2014 you may need to run 'pm2 startup' manually with sudo.");
49549
50154
  }
49550
50155
  try {
49551
- execSync("pm2 save", { stdio: "pipe", env });
50156
+ execSync3("pm2 save", { stdio: "pipe", env });
49552
50157
  console.log(" \u2705 pm2 process list saved.");
49553
50158
  } catch {
49554
50159
  console.log(" \u26A0\uFE0F pm2 save failed.");
@@ -49556,7 +50161,7 @@ function configurePm2(env) {
49556
50161
  return true;
49557
50162
  }
49558
50163
  async function promptAndRestart(env) {
49559
- const answer = await ask(
50164
+ const answer = await ask2(
49560
50165
  " \u26A0\uFE0F OpenClaw gateway will restart, briefly interrupting any active conversations.\n Restart now? [y/N] "
49561
50166
  );
49562
50167
  if (answer.trim().toLowerCase() === "y") {
@@ -49592,7 +50197,7 @@ async function promptAndRestart(env) {
49592
50197
  `);
49593
50198
  }
49594
50199
  }
49595
- function ask(question) {
50200
+ function ask2(question) {
49596
50201
  return new Promise((resolve4) => {
49597
50202
  const rl2 = readline.createInterface({
49598
50203
  input: process.stdin,
@@ -49614,255 +50219,12 @@ var init_setup = __esm({
49614
50219
  }
49615
50220
  });
49616
50221
 
49617
- // src/create-agent.ts
49618
- var create_agent_exports = {};
49619
- __export(create_agent_exports, {
49620
- findNextPort: () => findNextPort,
49621
- generateWorkspaceFiles: () => generateWorkspaceFiles,
49622
- openclawHome: () => openclawHome,
49623
- readOpenClawConfig: () => readOpenClawConfig,
49624
- runCreateCommand: () => runCreateCommand
49625
- });
49626
- import { execSync as execSync2 } from "node:child_process";
49627
- import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync } from "node:fs";
49628
- import { join as join4 } from "node:path";
49629
- function openclawHome() {
49630
- const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
49631
- return join4(home, ".openclaw");
49632
- }
49633
- function readOpenClawConfig(home) {
49634
- const configPath = join4(home, "openclaw.json");
49635
- const raw = readFileSync(configPath, "utf-8");
49636
- return JSON.parse(raw);
49637
- }
49638
- function writeOpenClawConfig(home, config, backupSuffix) {
49639
- const configPath = join4(home, "openclaw.json");
49640
- const backupPath = `${configPath}.bak.pre-${backupSuffix}`;
49641
- copyFileSync(configPath, backupPath);
49642
- writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
49643
- }
49644
- function collectPorts(config) {
49645
- const ports = [];
49646
- const accounts = config?.channels?.agentvault?.accounts;
49647
- if (accounts && typeof accounts === "object") {
49648
- for (const acct of Object.values(accounts)) {
49649
- if (typeof acct.httpPort === "number") {
49650
- ports.push(acct.httpPort);
49651
- }
49652
- }
49653
- }
49654
- return ports;
49655
- }
49656
- function findNextPort(config, startPort = 18800) {
49657
- const ports = collectPorts(config);
49658
- if (ports.length === 0) return startPort;
49659
- return Math.max(...ports, startPort - 1) + 1;
49660
- }
49661
- function isPortInUse(config, port) {
49662
- return collectPorts(config).includes(port);
49663
- }
49664
- function generateWorkspaceFiles(name2) {
49665
- const displayName = name2.charAt(0).toUpperCase() + name2.slice(1).toLowerCase();
49666
- return {
49667
- "IDENTITY.md": `# IDENTITY.md - Who Am I?
49668
-
49669
- - **Name:** ${displayName}
49670
- - **Creature:** AI assistant \u2014 a capable peer agent in the AgentVault network
49671
- - **Vibe:** Direct, competent, focused on their specialty domain
49672
- - **Emoji:** (placeholder \u2014 update to something fitting)
49673
- - **Avatar:** _(none set yet)_
49674
-
49675
- > TODO: Customize this file to give ${name2} a distinct identity.
49676
- `,
49677
- "SOUL.md": `# SOUL.md - Who You Are
49678
-
49679
- > TODO: Define ${name2}'s personality, tone, and behavioral rules.
49680
- > Copy and adapt from ~/.openclaw/workspace/SOUL.md as a starting point.
49681
-
49682
- ## Core Truths
49683
-
49684
- - Be genuinely helpful, not performatively helpful.
49685
- - Have opinions. Be resourceful before asking.
49686
- - Earn trust through competence.
49687
-
49688
- ## Channel Reply Rules
49689
-
49690
- - Never include reasoning or internal logic in visible replies.
49691
- - No narrating your approach before or after tool calls.
49692
- - Just deliver the answer \u2014 clean and direct.
49693
-
49694
- ## Vibe
49695
-
49696
- _(Define ${name2}'s specific personality here.)_
49697
- `,
49698
- "HEARTBEAT.md": `# Heartbeat
49699
-
49700
- - Stay available. If nothing needs attention, reply HEARTBEAT_OK.
49701
- - **Heartbeat replies are INTERNAL ONLY.** Reply with ONLY \`HEARTBEAT_OK\` when nothing needs attention.
49702
- - If something genuinely urgent needs attention, send it proactively FIRST, THEN reply HEARTBEAT_OK.
49703
- `,
49704
- "MEMORY.md": `# MEMORY.md - Long-Term Memory
49705
-
49706
- _(Empty \u2014 ${name2} starts with a clean memory. Update as the agent learns.)_
49707
- `
49708
- };
49709
- }
49710
- async function runCreateCommand(options) {
49711
- const { name: name2, token: token2, apiUrl: apiUrl2, force } = options;
49712
- const home = openclawHome();
49713
- const configPath = join4(home, "openclaw.json");
49714
- const workspaceDir = join4(home, `workspace-${name2}`);
49715
- const dataDir2 = join4(home, "agents", name2, "agentvault-data");
49716
- const templateDir = join4(home, "workspace");
49717
- console.log(`
49718
- \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
49719
- \u2551 AgentVault \u2014 Create New Agent \u2551
49720
- \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
49721
- `);
49722
- console.log(" Step 1/7 \u2014 Preflight checks...");
49723
- try {
49724
- execSync2("openclaw --version", { stdio: "pipe" });
49725
- } catch {
49726
- console.error(" Error: 'openclaw' not found in PATH. Is OpenClaw installed?");
49727
- process.exit(1);
49728
- }
49729
- if (!existsSync(configPath)) {
49730
- console.error(` Error: openclaw.json not found at ${configPath}`);
49731
- process.exit(1);
49732
- }
49733
- console.log(" Preflight passed.\n");
49734
- console.log(" Step 2/7 \u2014 Detecting port...");
49735
- const config = readOpenClawConfig(home);
49736
- let port;
49737
- if (options.port != null) {
49738
- port = options.port;
49739
- if (isPortInUse(config, port)) {
49740
- console.error(` Error: Port ${port} is already in use in openclaw.json.`);
49741
- process.exit(1);
49742
- }
49743
- console.log(` Using explicit port ${port}.
49744
- `);
49745
- } else {
49746
- port = findNextPort(config);
49747
- console.log(` Auto-assigned port ${port}.
49748
- `);
49749
- }
49750
- console.log(" Step 3/7 \u2014 Creating agent with OpenClaw...");
49751
- try {
49752
- execSync2(`openclaw agents add -- ${name2}`, { stdio: "pipe" });
49753
- console.log(` Agent '${name2}' created.
49754
- `);
49755
- } catch {
49756
- console.log(` Warning: 'openclaw agents add' failed \u2014 agent may already exist. Continuing.
49757
- `);
49758
- }
49759
- console.log(" Step 4/7 \u2014 Creating directories...");
49760
- mkdirSync(workspaceDir, { recursive: true });
49761
- mkdirSync(dataDir2, { recursive: true });
49762
- console.log(` Workspace: ${workspaceDir}`);
49763
- console.log(` DataDir: ${dataDir2}
49764
- `);
49765
- console.log(" Step 5/7 \u2014 Writing workspace files...");
49766
- const files = generateWorkspaceFiles(name2);
49767
- for (const [filename, content] of Object.entries(files)) {
49768
- writeFileSync(join4(workspaceDir, filename), content, "utf-8");
49769
- }
49770
- for (const copyFile of ["AGENTS.md", "USER.md"]) {
49771
- const src = join4(templateDir, copyFile);
49772
- if (existsSync(src)) {
49773
- copyFileSync(src, join4(workspaceDir, copyFile));
49774
- console.log(` Copied ${copyFile} from template workspace.`);
49775
- }
49776
- }
49777
- console.log(" Workspace files written.\n");
49778
- console.log(" Step 6/7 \u2014 Enrolling with AgentVault...\n");
49779
- await runSetupCommand({
49780
- token: token2,
49781
- name: name2,
49782
- apiUrl: apiUrl2,
49783
- dataDir: dataDir2,
49784
- accountId: name2,
49785
- force
49786
- });
49787
- console.log("\n Step 7/7 \u2014 Patching openclaw.json...");
49788
- try {
49789
- const freshConfig = readOpenClawConfig(home);
49790
- let patched = false;
49791
- const avChannel = freshConfig?.channels?.agentvault;
49792
- if (avChannel?.accounts) {
49793
- const acct = avChannel.accounts[name2];
49794
- if (acct) {
49795
- acct.httpPort = port;
49796
- patched = true;
49797
- }
49798
- }
49799
- if (avChannel && !avChannel.bindings) {
49800
- avChannel.bindings = [{ match: { accountId: "*" } }];
49801
- console.log(` Added wildcard binding (accountId: "*").`);
49802
- }
49803
- if (patched) {
49804
- writeOpenClawConfig(home, freshConfig, name2);
49805
- console.log(` httpPort set to ${port}.
49806
- `);
49807
- } else {
49808
- console.log(` Warning: Could not find account '${name2}' in channels.agentvault.accounts.`);
49809
- console.log(` You may need to manually set httpPort: ${port} in openclaw.json.
49810
- `);
49811
- }
49812
- } catch (err) {
49813
- console.log(` Warning: Failed to patch openclaw.json: ${err.message}
49814
- `);
49815
- }
49816
- console.log(" Verifying agent...");
49817
- try {
49818
- const http = await import("node:http");
49819
- await new Promise((resolve4) => {
49820
- const req = http.get(`http://127.0.0.1:${port}/status`, { timeout: 3e3 }, (res) => {
49821
- console.log(` Port ${port} responded (HTTP ${res.statusCode}).`);
49822
- res.resume();
49823
- resolve4();
49824
- });
49825
- req.on("error", () => {
49826
- console.log(` Port ${port} not yet responding \u2014 gateway may need a moment.`);
49827
- resolve4();
49828
- });
49829
- req.on("timeout", () => {
49830
- req.destroy();
49831
- console.log(` Port ${port} timed out \u2014 check gateway logs.`);
49832
- resolve4();
49833
- });
49834
- });
49835
- } catch {
49836
- console.log(" Verification skipped.");
49837
- }
49838
- console.log(`
49839
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
49840
- Agent '${name2}' created successfully!
49841
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
49842
-
49843
- Workspace: ${workspaceDir}
49844
- DataDir: ${dataDir2}
49845
- HTTP Port: ${port}
49846
-
49847
- Next steps:
49848
- 1. Edit ${workspaceDir}/SOUL.md \u2014 give ${name2} a personality
49849
- 2. Edit ${workspaceDir}/IDENTITY.md \u2014 set name, emoji, vibe
49850
- 3. Approve the agent in the AgentVault app
49851
- `);
49852
- }
49853
- var init_create_agent = __esm({
49854
- async "src/create-agent.ts"() {
49855
- "use strict";
49856
- await init_setup();
49857
- }
49858
- });
49859
-
49860
50222
  // src/skills-publish.ts
49861
50223
  var skills_publish_exports = {};
49862
50224
  __export(skills_publish_exports, {
49863
50225
  publishSkills: () => publishSkills
49864
50226
  });
49865
- import { readFileSync as readFileSync2 } from "node:fs";
50227
+ import { readFileSync as readFileSync3 } from "node:fs";
49866
50228
  import { resolve as resolve2 } from "node:path";
49867
50229
  async function publishSkills(opts) {
49868
50230
  if (!opts.manifest) {
@@ -49876,7 +50238,7 @@ async function publishSkills(opts) {
49876
50238
  const manifestPath = resolve2(opts.manifest);
49877
50239
  let raw;
49878
50240
  try {
49879
- raw = readFileSync2(manifestPath, "utf-8");
50241
+ raw = readFileSync3(manifestPath, "utf-8");
49880
50242
  } catch {
49881
50243
  console.error(`Error: Cannot read manifest file: ${manifestPath}`);
49882
50244
  process.exit(1);
@@ -49955,8 +50317,8 @@ var init_skills_publish = __esm({
49955
50317
  await init_channel();
49956
50318
  await init_setup();
49957
50319
  import { resolve as resolve3 } from "node:path";
49958
- import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
49959
- import { createInterface as createInterface2 } from "node:readline";
50320
+ import { existsSync as existsSync3, readFileSync as readFileSync4 } from "node:fs";
50321
+ import { createInterface as createInterface3 } from "node:readline";
49960
50322
  import { createRequire } from "node:module";
49961
50323
  var _require = createRequire(import.meta.url);
49962
50324
  var PKG_VERSION = (() => {
@@ -50128,6 +50490,11 @@ if (subcommand === "skills") {
50128
50490
  console.error(`Usage: agentvault skills publish --manifest=./skill-manifest.json`);
50129
50491
  process.exit(1);
50130
50492
  }
50493
+ if (subcommand === "doctor") {
50494
+ const { runDoctorCommand: runDoctorCommand2 } = await init_doctor().then(() => doctor_exports);
50495
+ await runDoctorCommand2({ fix: flags["fix"] === "true" });
50496
+ process.exit(0);
50497
+ }
50131
50498
  if (!token) {
50132
50499
  console.error(`
50133
50500
  AgentVault Secure Channel CLI
@@ -50139,6 +50506,7 @@ Usage:
50139
50506
  npx @agentvault/agentvault send "message" # Send a message to the owner
50140
50507
  npx @agentvault/agentvault status # Check gateway status
50141
50508
  npx @agentvault/agentvault skills publish --manifest=FILE # Publish skills from manifest
50509
+ npx @agentvault/agentvault doctor # Diagnose and fix gateway issues
50142
50510
  npx @agentvault/agentvault --token=TOKEN # Standalone interactive CLI
50143
50511
 
50144
50512
  Options:
@@ -50151,6 +50519,7 @@ Options:
50151
50519
  --webhook-url=URL URL for HTTP webhook notifications on new messages
50152
50520
  --no-notifications Disable OS desktop notifications
50153
50521
  --port=PORT Gateway port for send/status (default: 18790)
50522
+ --fix Apply fixes automatically (used with doctor)
50154
50523
 
50155
50524
  Environment variables:
50156
50525
  AGENTVAULT_INVITE_TOKEN Same as --token
@@ -50230,9 +50599,9 @@ channel.on("error", (err) => {
50230
50599
  var resolvedDataDir = resolve3(dataDir);
50231
50600
  var statePath = resolve3(resolvedDataDir, "agentvault.json");
50232
50601
  var existingDeviceId = null;
50233
- if (existsSync2(statePath)) {
50602
+ if (existsSync3(statePath)) {
50234
50603
  try {
50235
- const state = JSON.parse(readFileSync3(statePath, "utf-8"));
50604
+ const state = JSON.parse(readFileSync4(statePath, "utf-8"));
50236
50605
  existingDeviceId = state.deviceId ?? null;
50237
50606
  } catch {
50238
50607
  }
@@ -50255,7 +50624,7 @@ if (existingDeviceId) {
50255
50624
  `);
50256
50625
  }
50257
50626
  await channel.start();
50258
- var rl = createInterface2({
50627
+ var rl = createInterface3({
50259
50628
  input: process.stdin,
50260
50629
  output: process.stdout,
50261
50630
  prompt: "> "