@agentvault/agentvault 0.14.22 → 0.14.23

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
@@ -70522,265 +70522,6 @@ var init_index = __esm({
70522
70522
  }
70523
70523
  });
70524
70524
 
70525
- // src/create-agent.ts
70526
- var create_agent_exports = {};
70527
- __export(create_agent_exports, {
70528
- findNextPort: () => findNextPort,
70529
- generateWorkspaceFiles: () => generateWorkspaceFiles,
70530
- openclawHome: () => openclawHome,
70531
- readOpenClawConfig: () => readOpenClawConfig,
70532
- runCreateCommand: () => runCreateCommand
70533
- });
70534
- import { execSync } from "node:child_process";
70535
- import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync } from "node:fs";
70536
- import { join as join4 } from "node:path";
70537
- function openclawHome() {
70538
- const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
70539
- return join4(home, ".openclaw");
70540
- }
70541
- function readOpenClawConfig(home) {
70542
- const configPath = join4(home, "openclaw.json");
70543
- const raw = readFileSync(configPath, "utf-8");
70544
- return JSON.parse(raw);
70545
- }
70546
- function writeOpenClawConfig(home, config2, backupSuffix) {
70547
- const configPath = join4(home, "openclaw.json");
70548
- const backupPath = `${configPath}.bak.pre-${backupSuffix}`;
70549
- copyFileSync(configPath, backupPath);
70550
- writeFileSync(configPath, JSON.stringify(config2, null, 2) + "\n", "utf-8");
70551
- }
70552
- function collectPorts(config2) {
70553
- const ports = [];
70554
- const accounts = config2?.channels?.agentvault?.accounts;
70555
- if (accounts && typeof accounts === "object") {
70556
- for (const acct of Object.values(accounts)) {
70557
- if (typeof acct.httpPort === "number") {
70558
- ports.push(acct.httpPort);
70559
- }
70560
- }
70561
- }
70562
- return ports;
70563
- }
70564
- function findNextPort(config2, startPort = 18800) {
70565
- const ports = collectPorts(config2);
70566
- if (ports.length === 0) return startPort;
70567
- return Math.max(...ports, startPort - 1) + 1;
70568
- }
70569
- function isPortInUse(config2, port) {
70570
- return collectPorts(config2).includes(port);
70571
- }
70572
- function generateWorkspaceFiles(name2) {
70573
- const displayName = name2.charAt(0).toUpperCase() + name2.slice(1).toLowerCase();
70574
- return {
70575
- "IDENTITY.md": `# IDENTITY.md - Who Am I?
70576
-
70577
- - **Name:** ${displayName}
70578
- - **Creature:** AI assistant \u2014 a capable peer agent in the AgentVault network
70579
- - **Vibe:** Direct, competent, focused on their specialty domain
70580
- - **Emoji:** (placeholder \u2014 update to something fitting)
70581
- - **Avatar:** _(none set yet)_
70582
-
70583
- > TODO: Customize this file to give ${name2} a distinct identity.
70584
- `,
70585
- "SOUL.md": `# SOUL.md - Who You Are
70586
-
70587
- > TODO: Define ${name2}'s personality, tone, and behavioral rules.
70588
- > Copy and adapt from ~/.openclaw/workspace/SOUL.md as a starting point.
70589
-
70590
- ## Core Truths
70591
-
70592
- - Be genuinely helpful, not performatively helpful.
70593
- - Have opinions. Be resourceful before asking.
70594
- - Earn trust through competence.
70595
-
70596
- ## Channel Reply Rules
70597
-
70598
- - Never include reasoning or internal logic in visible replies.
70599
- - No narrating your approach before or after tool calls.
70600
- - Just deliver the answer \u2014 clean and direct.
70601
-
70602
- ## Vibe
70603
-
70604
- _(Define ${name2}'s specific personality here.)_
70605
- `,
70606
- "HEARTBEAT.md": `# Heartbeat
70607
-
70608
- - Stay available. If nothing needs attention, reply HEARTBEAT_OK.
70609
- - **Heartbeat replies are INTERNAL ONLY.** Reply with ONLY \`HEARTBEAT_OK\` when nothing needs attention.
70610
- - If something genuinely urgent needs attention, send it proactively FIRST, THEN reply HEARTBEAT_OK.
70611
- `,
70612
- "MEMORY.md": `# MEMORY.md - Long-Term Memory
70613
-
70614
- _(Empty \u2014 ${name2} starts with a clean memory. Update as the agent learns.)_
70615
- `
70616
- };
70617
- }
70618
- async function runCreateCommand(options) {
70619
- const { name: name2, token: token2, apiUrl: apiUrl2, force } = options;
70620
- const home = openclawHome();
70621
- const configPath = join4(home, "openclaw.json");
70622
- const workspaceDir = join4(home, `workspace-${name2}`);
70623
- const dataDir2 = join4(home, "agents", name2, "agentvault-data");
70624
- const templateDir = join4(home, "workspace");
70625
- console.log(`
70626
- \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
70627
- \u2551 AgentVault \u2014 Create New Agent \u2551
70628
- \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
70629
- `);
70630
- console.log(" Step 1/7 \u2014 Preflight checks...");
70631
- try {
70632
- execSync("openclaw --version", { stdio: "pipe" });
70633
- } catch {
70634
- console.error(" Error: 'openclaw' not found in PATH. Is OpenClaw installed?");
70635
- process.exit(1);
70636
- }
70637
- if (!existsSync(configPath)) {
70638
- console.error(` Error: openclaw.json not found at ${configPath}`);
70639
- process.exit(1);
70640
- }
70641
- console.log(" Preflight passed.\n");
70642
- console.log(" Step 2/7 \u2014 Detecting port...");
70643
- const config2 = readOpenClawConfig(home);
70644
- let port;
70645
- if (options.port != null) {
70646
- port = options.port;
70647
- if (isPortInUse(config2, port)) {
70648
- console.error(` Error: Port ${port} is already in use in openclaw.json.`);
70649
- process.exit(1);
70650
- }
70651
- console.log(` Using explicit port ${port}.
70652
- `);
70653
- } else {
70654
- port = findNextPort(config2);
70655
- console.log(` Auto-assigned port ${port}.
70656
- `);
70657
- }
70658
- console.log(" Step 3/7 \u2014 Creating agent with OpenClaw...");
70659
- try {
70660
- execSync(`openclaw agents add -- ${name2}`, { stdio: "pipe" });
70661
- console.log(` Agent '${name2}' created.
70662
- `);
70663
- } catch {
70664
- console.log(` Warning: 'openclaw agents add' failed \u2014 agent may already exist. Continuing.
70665
- `);
70666
- }
70667
- console.log(" Step 4/7 \u2014 Creating directories...");
70668
- mkdirSync(workspaceDir, { recursive: true });
70669
- mkdirSync(dataDir2, { recursive: true });
70670
- console.log(` Workspace: ${workspaceDir}`);
70671
- console.log(` DataDir: ${dataDir2}
70672
- `);
70673
- console.log(" Step 5/7 \u2014 Writing workspace files...");
70674
- const files = generateWorkspaceFiles(name2);
70675
- for (const [filename, content] of Object.entries(files)) {
70676
- writeFileSync(join4(workspaceDir, filename), content, "utf-8");
70677
- }
70678
- for (const copyFile of ["AGENTS.md", "USER.md"]) {
70679
- const src = join4(templateDir, copyFile);
70680
- if (existsSync(src)) {
70681
- copyFileSync(src, join4(workspaceDir, copyFile));
70682
- console.log(` Copied ${copyFile} from template workspace.`);
70683
- }
70684
- }
70685
- console.log(" Workspace files written.\n");
70686
- console.log(" Step 6/7 \u2014 Enrolling with AgentVault...\n");
70687
- await runSetupCommand({
70688
- token: token2,
70689
- name: name2,
70690
- apiUrl: apiUrl2,
70691
- dataDir: dataDir2,
70692
- accountId: name2,
70693
- force
70694
- });
70695
- console.log("\n Step 7/7 \u2014 Patching openclaw.json...");
70696
- try {
70697
- const freshConfig = readOpenClawConfig(home);
70698
- let patched = false;
70699
- const avChannel = freshConfig?.channels?.agentvault;
70700
- if (avChannel?.accounts) {
70701
- const acct = avChannel.accounts[name2];
70702
- if (acct) {
70703
- acct.httpPort = port;
70704
- patched = true;
70705
- }
70706
- }
70707
- if (avChannel) {
70708
- const bindings = avChannel.bindings;
70709
- const hasWildcard = bindings?.some(
70710
- (b2) => b2.match?.accountId === "*"
70711
- );
70712
- if (!hasWildcard) {
70713
- avChannel.bindings = [{ match: { accountId: "*" } }, ...bindings ?? []];
70714
- console.log(` Added wildcard binding (accountId: "*").`);
70715
- }
70716
- }
70717
- if (patched) {
70718
- writeOpenClawConfig(home, freshConfig, name2);
70719
- console.log(` httpPort set to ${port}.
70720
- `);
70721
- } else {
70722
- console.log(` Warning: Could not find account '${name2}' in channels.agentvault.accounts.`);
70723
- console.log(` You may need to manually set httpPort: ${port} in openclaw.json.
70724
- `);
70725
- }
70726
- } catch (err) {
70727
- console.log(` Warning: Failed to patch openclaw.json: ${err.message}
70728
- `);
70729
- }
70730
- console.log(" Verifying agent...");
70731
- try {
70732
- const http = await import("node:http");
70733
- await new Promise((resolve4) => {
70734
- const req = http.get(`http://127.0.0.1:${port}/status`, { timeout: 3e3 }, (res) => {
70735
- console.log(` Port ${port} responded (HTTP ${res.statusCode}).`);
70736
- res.resume();
70737
- resolve4();
70738
- });
70739
- req.on("error", () => {
70740
- console.log(` Port ${port} not yet responding \u2014 gateway may need a moment.`);
70741
- resolve4();
70742
- });
70743
- req.on("timeout", () => {
70744
- req.destroy();
70745
- console.log(` Port ${port} timed out \u2014 check gateway logs.`);
70746
- resolve4();
70747
- });
70748
- });
70749
- } catch {
70750
- console.log(" Verification skipped.");
70751
- }
70752
- if (process.platform === "darwin") {
70753
- const { validatePlist: validatePlist2 } = await init_doctor().then(() => doctor_exports);
70754
- const plistResult = validatePlist2();
70755
- if (plistResult.status === "stale") {
70756
- console.log(`
70757
- \u26A0\uFE0F macOS LaunchAgent plist has stale paths.
70758
- Run to diagnose and fix: npx @agentvault/agentvault doctor
70759
- `);
70760
- }
70761
- }
70762
- console.log(`
70763
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
70764
- Agent '${name2}' created successfully!
70765
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
70766
-
70767
- Workspace: ${workspaceDir}
70768
- DataDir: ${dataDir2}
70769
- HTTP Port: ${port}
70770
-
70771
- Next steps:
70772
- 1. Edit ${workspaceDir}/SOUL.md \u2014 give ${name2} a personality
70773
- 2. Edit ${workspaceDir}/IDENTITY.md \u2014 set name, emoji, vibe
70774
- 3. Approve the agent in the AgentVault app
70775
- `);
70776
- }
70777
- var init_create_agent = __esm({
70778
- async "src/create-agent.ts"() {
70779
- "use strict";
70780
- await init_setup();
70781
- }
70782
- });
70783
-
70784
70525
  // src/doctor.ts
70785
70526
  var doctor_exports = {};
70786
70527
  __export(doctor_exports, {
@@ -70798,13 +70539,13 @@ __export(doctor_exports, {
70798
70539
  runDoctorCommand: () => runDoctorCommand,
70799
70540
  validatePlist: () => validatePlist
70800
70541
  });
70801
- import { execSync as execSync2 } from "node:child_process";
70802
- import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, chmodSync } from "node:fs";
70803
- import { join as join5 } from "node:path";
70542
+ import { execSync } from "node:child_process";
70543
+ import { existsSync, readFileSync, writeFileSync, chmodSync } from "node:fs";
70544
+ import { join as join4 } from "node:path";
70804
70545
  import { createInterface } from "node:readline";
70805
70546
  function checkOpenClawInstalled() {
70806
70547
  try {
70807
- const out = execSync2("openclaw --version", { stdio: "pipe", timeout: 1e4 });
70548
+ const out = execSync("openclaw --version", { stdio: "pipe", timeout: 1e4 });
70808
70549
  const version2 = out.toString().trim();
70809
70550
  return { name: "OpenClaw installed", status: "pass", message: version2 };
70810
70551
  } catch {
@@ -70816,8 +70557,8 @@ function checkOpenClawInstalled() {
70816
70557
  }
70817
70558
  }
70818
70559
  function checkConfigExists(home) {
70819
- const configPath = join5(home, "openclaw.json");
70820
- if (!existsSync2(configPath)) {
70560
+ const configPath = join4(home, "openclaw.json");
70561
+ if (!existsSync(configPath)) {
70821
70562
  return {
70822
70563
  name: "Config exists",
70823
70564
  status: "fail",
@@ -70825,7 +70566,7 @@ function checkConfigExists(home) {
70825
70566
  };
70826
70567
  }
70827
70568
  try {
70828
- JSON.parse(readFileSync2(configPath, "utf-8"));
70569
+ JSON.parse(readFileSync(configPath, "utf-8"));
70829
70570
  return { name: "Config exists", status: "pass", message: configPath };
70830
70571
  } catch {
70831
70572
  return {
@@ -70901,7 +70642,7 @@ function checkPlist() {
70901
70642
  }
70902
70643
  function checkGatewayPort() {
70903
70644
  try {
70904
- execSync2("curl -sf --max-time 3 http://127.0.0.1:18789/", { stdio: "pipe" });
70645
+ execSync("curl -sf --max-time 3 http://127.0.0.1:18789/", { stdio: "pipe" });
70905
70646
  return { name: "Gateway port (18789)", status: "pass", message: "Responding" };
70906
70647
  } catch {
70907
70648
  return {
@@ -70923,12 +70664,12 @@ function checkAgentDataDirs(config2) {
70923
70664
  }
70924
70665
  const checkDir = (label, dataDir2) => {
70925
70666
  const resolved = dataDir2.replace(/^~/, home);
70926
- if (!existsSync2(resolved)) {
70667
+ if (!existsSync(resolved)) {
70927
70668
  warnings.push(`${label}: dir missing (${resolved})`);
70928
70669
  return;
70929
70670
  }
70930
- const statePath2 = join5(resolved, "agentvault.json");
70931
- if (!existsSync2(statePath2)) {
70671
+ const statePath2 = join4(resolved, "agentvault.json");
70672
+ if (!existsSync(statePath2)) {
70932
70673
  warnings.push(`${label}: no agentvault.json`);
70933
70674
  }
70934
70675
  };
@@ -70946,12 +70687,12 @@ function checkAgentDataDirs(config2) {
70946
70687
  }
70947
70688
  function checkPm2Status() {
70948
70689
  try {
70949
- execSync2("pm2 --version", { stdio: "pipe", timeout: 5e3 });
70690
+ execSync("pm2 --version", { stdio: "pipe", timeout: 5e3 });
70950
70691
  } catch {
70951
70692
  return { name: "pm2 status", status: "skip", message: "pm2 not installed" };
70952
70693
  }
70953
70694
  try {
70954
- const info = execSync2("pm2 describe openclaw-gateway", { stdio: "pipe", timeout: 5e3 });
70695
+ const info = execSync("pm2 describe openclaw-gateway", { stdio: "pipe", timeout: 5e3 });
70955
70696
  const out = info.toString();
70956
70697
  if (out.includes("online")) {
70957
70698
  return { name: "pm2 status", status: "pass", message: "openclaw-gateway: online" };
@@ -70966,22 +70707,22 @@ function checkPm2Status() {
70966
70707
  }
70967
70708
  function plistPath() {
70968
70709
  const home = process.env.HOME ?? "";
70969
- return join5(home, "Library", "LaunchAgents", PLIST_FILENAME);
70710
+ return join4(home, "Library", "LaunchAgents", PLIST_FILENAME);
70970
70711
  }
70971
70712
  function parsePlist(plistFile) {
70972
- if (!existsSync2(plistFile)) return null;
70713
+ if (!existsSync(plistFile)) return null;
70973
70714
  try {
70974
- const json2 = execSync2(`plutil -convert json -o - "${plistFile}"`, {
70715
+ const json2 = execSync(`plutil -convert json -o - "${plistFile}"`, {
70975
70716
  stdio: "pipe",
70976
70717
  timeout: 5e3
70977
70718
  }).toString();
70978
70719
  const parsed = JSON.parse(json2);
70979
70720
  const programArgs = parsed.ProgramArguments ?? [];
70980
70721
  const stalePaths = [];
70981
- const wrapperPath = join5(process.env.HOME ?? "", ".openclaw", WRAPPER_SCRIPT_NAME);
70722
+ const wrapperPath = join4(process.env.HOME ?? "", ".openclaw", WRAPPER_SCRIPT_NAME);
70982
70723
  for (const arg of programArgs) {
70983
70724
  if (arg.startsWith("/") && arg !== "/bin/bash" && arg !== wrapperPath) {
70984
- if (!existsSync2(arg)) {
70725
+ if (!existsSync(arg)) {
70985
70726
  stalePaths.push(arg);
70986
70727
  }
70987
70728
  }
@@ -70996,7 +70737,7 @@ function validatePlist() {
70996
70737
  return { status: "skip" };
70997
70738
  }
70998
70739
  const path = plistPath();
70999
- if (!existsSync2(path)) {
70740
+ if (!existsSync(path)) {
71000
70741
  return { status: "missing", plistPath: path };
71001
70742
  }
71002
70743
  const info = parsePlist(path);
@@ -71004,7 +70745,7 @@ function validatePlist() {
71004
70745
  return { status: "missing", plistPath: path };
71005
70746
  }
71006
70747
  const home = process.env.HOME ?? "";
71007
- const wrapperPath = join5(home, ".openclaw", WRAPPER_SCRIPT_NAME);
70748
+ const wrapperPath = join4(home, ".openclaw", WRAPPER_SCRIPT_NAME);
71008
70749
  if (info.programArgs.includes(wrapperPath)) {
71009
70750
  return { status: "already-fixed", plistPath: path };
71010
70751
  }
@@ -71015,14 +70756,14 @@ function validatePlist() {
71015
70756
  }
71016
70757
  function applyPlistFix(info) {
71017
70758
  const home = process.env.HOME ?? "";
71018
- const openclawDir = join5(home, ".openclaw");
71019
- const wrapperPath = join5(openclawDir, WRAPPER_SCRIPT_NAME);
70759
+ const openclawDir = join4(home, ".openclaw");
70760
+ const wrapperPath = join4(openclawDir, WRAPPER_SCRIPT_NAME);
71020
70761
  const wrapperContent = `#!/bin/bash
71021
70762
  export PATH="$HOME/.local/bin:$HOME/.pnpm/bin:$HOME/Library/pnpm/bin:$HOME/Library/pnpm:/opt/homebrew/bin:/usr/local/bin:$PATH"
71022
70763
  exec "$(which openclaw)" gateway start "$@"
71023
70764
  `;
71024
70765
  try {
71025
- writeFileSync2(wrapperPath, wrapperContent, "utf-8");
70766
+ writeFileSync(wrapperPath, wrapperContent, "utf-8");
71026
70767
  chmodSync(wrapperPath, 493);
71027
70768
  console.log(` Created wrapper: ${wrapperPath}`);
71028
70769
  } catch (err) {
@@ -71032,16 +70773,16 @@ exec "$(which openclaw)" gateway start "$@"
71032
70773
  const plistBuddy = "/usr/libexec/PlistBuddy";
71033
70774
  const plist = info.plistPath;
71034
70775
  try {
71035
- execSync2(`${plistBuddy} -c "Set :ProgramArguments:0 /bin/bash" "${plist}"`, { stdio: "pipe" });
70776
+ execSync(`${plistBuddy} -c "Set :ProgramArguments:0 /bin/bash" "${plist}"`, { stdio: "pipe" });
71036
70777
  try {
71037
- execSync2(`${plistBuddy} -c "Set :ProgramArguments:1 ${wrapperPath}" "${plist}"`, { stdio: "pipe" });
70778
+ execSync(`${plistBuddy} -c "Set :ProgramArguments:1 ${wrapperPath}" "${plist}"`, { stdio: "pipe" });
71038
70779
  } catch {
71039
- execSync2(`${plistBuddy} -c "Add :ProgramArguments:1 string ${wrapperPath}" "${plist}"`, { stdio: "pipe" });
70780
+ execSync(`${plistBuddy} -c "Add :ProgramArguments:1 string ${wrapperPath}" "${plist}"`, { stdio: "pipe" });
71040
70781
  }
71041
70782
  let argCount = info.programArgs.length;
71042
70783
  for (let i2 = argCount - 1; i2 >= 2; i2--) {
71043
70784
  try {
71044
- execSync2(`${plistBuddy} -c "Delete :ProgramArguments:${i2}" "${plist}"`, { stdio: "pipe" });
70785
+ execSync(`${plistBuddy} -c "Delete :ProgramArguments:${i2}" "${plist}"`, { stdio: "pipe" });
71045
70786
  } catch {
71046
70787
  }
71047
70788
  }
@@ -71051,11 +70792,11 @@ exec "$(which openclaw)" gateway start "$@"
71051
70792
  return false;
71052
70793
  }
71053
70794
  try {
71054
- execSync2(`launchctl unload "${plist}"`, { stdio: "pipe" });
70795
+ execSync(`launchctl unload "${plist}"`, { stdio: "pipe" });
71055
70796
  } catch {
71056
70797
  }
71057
70798
  try {
71058
- execSync2(`launchctl load "${plist}"`, { stdio: "pipe" });
70799
+ execSync(`launchctl load "${plist}"`, { stdio: "pipe" });
71059
70800
  console.log(" Reloaded LaunchAgent.");
71060
70801
  } catch (err) {
71061
70802
  console.error(` Failed to reload LaunchAgent: ${err.message}`);
@@ -71160,12 +70901,305 @@ var init_doctor = __esm({
71160
70901
  }
71161
70902
  });
71162
70903
 
71163
- // src/setup.ts
71164
- var setup_exports = {};
71165
- __export(setup_exports, {
71166
- configurePm2: () => configurePm2,
71167
- installPlugin: () => installPlugin,
71168
- runSetupCommand: () => runSetupCommand
70904
+ // src/create-agent.ts
70905
+ var create_agent_exports = {};
70906
+ __export(create_agent_exports, {
70907
+ findNextPort: () => findNextPort,
70908
+ generateWorkspaceFiles: () => generateWorkspaceFiles,
70909
+ openclawHome: () => openclawHome,
70910
+ readOpenClawConfig: () => readOpenClawConfig,
70911
+ runCreateCommand: () => runCreateCommand
70912
+ });
70913
+ import { execSync as execSync2 } from "node:child_process";
70914
+ import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2, copyFileSync } from "node:fs";
70915
+ import { join as join5 } from "node:path";
70916
+ function openclawHome() {
70917
+ const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
70918
+ return join5(home, ".openclaw");
70919
+ }
70920
+ function readOpenClawConfig(home) {
70921
+ const configPath = join5(home, "openclaw.json");
70922
+ const raw = readFileSync2(configPath, "utf-8");
70923
+ return JSON.parse(raw);
70924
+ }
70925
+ function writeOpenClawConfig(home, config2, backupSuffix) {
70926
+ const configPath = join5(home, "openclaw.json");
70927
+ const backupPath = `${configPath}.bak.pre-${backupSuffix}`;
70928
+ copyFileSync(configPath, backupPath);
70929
+ writeFileSync2(configPath, JSON.stringify(config2, null, 2) + "\n", "utf-8");
70930
+ }
70931
+ function collectPorts(config2) {
70932
+ const ports = [];
70933
+ const accounts = config2?.channels?.agentvault?.accounts;
70934
+ if (accounts && typeof accounts === "object") {
70935
+ for (const acct of Object.values(accounts)) {
70936
+ if (typeof acct.httpPort === "number") {
70937
+ ports.push(acct.httpPort);
70938
+ }
70939
+ }
70940
+ }
70941
+ return ports;
70942
+ }
70943
+ function findNextPort(config2, startPort = 18800) {
70944
+ const ports = collectPorts(config2);
70945
+ if (ports.length === 0) return startPort;
70946
+ return Math.max(...ports, startPort - 1) + 1;
70947
+ }
70948
+ function isPortInUse(config2, port) {
70949
+ return collectPorts(config2).includes(port);
70950
+ }
70951
+ function generateWorkspaceFiles(name2) {
70952
+ const displayName = name2.charAt(0).toUpperCase() + name2.slice(1).toLowerCase();
70953
+ return {
70954
+ "IDENTITY.md": `# IDENTITY.md - Who Am I?
70955
+
70956
+ - **Name:** ${displayName}
70957
+ - **Creature:** AI assistant \u2014 a capable peer agent in the AgentVault network
70958
+ - **Vibe:** Direct, competent, focused on their specialty domain
70959
+ - **Emoji:** (placeholder \u2014 update to something fitting)
70960
+ - **Avatar:** _(none set yet)_
70961
+
70962
+ > TODO: Customize this file to give ${name2} a distinct identity.
70963
+ `,
70964
+ "SOUL.md": `# SOUL.md - Who You Are
70965
+
70966
+ > TODO: Define ${name2}'s personality, tone, and behavioral rules.
70967
+ > Copy and adapt from ~/.openclaw/workspace/SOUL.md as a starting point.
70968
+
70969
+ ## Core Truths
70970
+
70971
+ - Be genuinely helpful, not performatively helpful.
70972
+ - Have opinions. Be resourceful before asking.
70973
+ - Earn trust through competence.
70974
+
70975
+ ## Channel Reply Rules
70976
+
70977
+ - Never include reasoning or internal logic in visible replies.
70978
+ - No narrating your approach before or after tool calls.
70979
+ - Just deliver the answer \u2014 clean and direct.
70980
+
70981
+ ## Vibe
70982
+
70983
+ _(Define ${name2}'s specific personality here.)_
70984
+ `,
70985
+ "HEARTBEAT.md": `# Heartbeat
70986
+
70987
+ - Stay available. If nothing needs attention, reply HEARTBEAT_OK.
70988
+ - **Heartbeat replies are INTERNAL ONLY.** Reply with ONLY \`HEARTBEAT_OK\` when nothing needs attention.
70989
+ - If something genuinely urgent needs attention, send it proactively FIRST, THEN reply HEARTBEAT_OK.
70990
+ `,
70991
+ "MEMORY.md": `# MEMORY.md - Long-Term Memory
70992
+
70993
+ _(Empty \u2014 ${name2} starts with a clean memory. Update as the agent learns.)_
70994
+ `
70995
+ };
70996
+ }
70997
+ async function runCreateCommand(options) {
70998
+ const { name: name2, token: token2, apiUrl: apiUrl2, force } = options;
70999
+ const home = openclawHome();
71000
+ const configPath = join5(home, "openclaw.json");
71001
+ const workspaceDir = join5(home, `workspace-${name2}`);
71002
+ const dataDir2 = join5(home, "agents", name2, "agentvault-data");
71003
+ const templateDir = join5(home, "workspace");
71004
+ console.log(`
71005
+ \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
71006
+ \u2551 AgentVault \u2014 Create New Agent \u2551
71007
+ \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
71008
+ `);
71009
+ console.log(" Step 1/7 \u2014 Preflight checks...");
71010
+ try {
71011
+ execSync2("openclaw --version", { stdio: "pipe" });
71012
+ } catch {
71013
+ console.error(" Error: 'openclaw' not found in PATH. Is OpenClaw installed?");
71014
+ process.exit(1);
71015
+ }
71016
+ if (!existsSync2(configPath)) {
71017
+ console.error(` Error: openclaw.json not found at ${configPath}`);
71018
+ process.exit(1);
71019
+ }
71020
+ console.log(" Preflight passed.\n");
71021
+ console.log(" Step 2/7 \u2014 Detecting port...");
71022
+ const config2 = readOpenClawConfig(home);
71023
+ let port;
71024
+ if (options.port != null) {
71025
+ port = options.port;
71026
+ if (isPortInUse(config2, port)) {
71027
+ console.error(` Error: Port ${port} is already in use in openclaw.json.`);
71028
+ process.exit(1);
71029
+ }
71030
+ console.log(` Using explicit port ${port}.
71031
+ `);
71032
+ } else {
71033
+ port = findNextPort(config2);
71034
+ console.log(` Auto-assigned port ${port}.
71035
+ `);
71036
+ }
71037
+ console.log(" Step 3/7 \u2014 Creating agent with OpenClaw...");
71038
+ try {
71039
+ execSync2(`openclaw agents add -- ${name2}`, { stdio: "pipe" });
71040
+ console.log(` Agent '${name2}' created.
71041
+ `);
71042
+ } catch {
71043
+ console.log(` Warning: 'openclaw agents add' failed \u2014 agent may already exist. Continuing.
71044
+ `);
71045
+ }
71046
+ console.log(" Step 4/7 \u2014 Creating directories...");
71047
+ mkdirSync(workspaceDir, { recursive: true });
71048
+ mkdirSync(dataDir2, { recursive: true });
71049
+ console.log(` Workspace: ${workspaceDir}`);
71050
+ console.log(` DataDir: ${dataDir2}
71051
+ `);
71052
+ console.log(" Step 5/7 \u2014 Writing workspace files...");
71053
+ const files = generateWorkspaceFiles(name2);
71054
+ for (const [filename, content] of Object.entries(files)) {
71055
+ writeFileSync2(join5(workspaceDir, filename), content, "utf-8");
71056
+ }
71057
+ for (const copyFile of ["AGENTS.md", "USER.md"]) {
71058
+ const src = join5(templateDir, copyFile);
71059
+ if (existsSync2(src)) {
71060
+ copyFileSync(src, join5(workspaceDir, copyFile));
71061
+ console.log(` Copied ${copyFile} from template workspace.`);
71062
+ }
71063
+ }
71064
+ console.log(" Workspace files written.\n");
71065
+ console.log(" Step 6/7 \u2014 Enrolling with AgentVault...\n");
71066
+ await runSetupCommand({
71067
+ token: token2,
71068
+ name: name2,
71069
+ apiUrl: apiUrl2,
71070
+ dataDir: dataDir2,
71071
+ accountId: name2,
71072
+ force
71073
+ });
71074
+ console.log("\n Step 7/7 \u2014 Patching openclaw.json...");
71075
+ try {
71076
+ const freshConfig = readOpenClawConfig(home);
71077
+ let patched = false;
71078
+ const avChannel = freshConfig?.channels?.agentvault;
71079
+ if (avChannel?.accounts) {
71080
+ const acct = avChannel.accounts[name2];
71081
+ if (acct) {
71082
+ acct.httpPort = port;
71083
+ patched = true;
71084
+ }
71085
+ }
71086
+ if (avChannel) {
71087
+ const channelBindings = avChannel.bindings;
71088
+ const hasAccountBinding = channelBindings?.some(
71089
+ (b2) => b2.match?.accountId === name2
71090
+ );
71091
+ if (!hasAccountBinding) {
71092
+ const arr = channelBindings ?? [];
71093
+ const wildcardIdx = arr.findIndex((b2) => b2.match?.accountId === "*");
71094
+ const entry = { match: { accountId: name2 } };
71095
+ if (wildcardIdx >= 0) {
71096
+ arr.splice(wildcardIdx, 0, entry);
71097
+ } else {
71098
+ arr.push(entry);
71099
+ }
71100
+ avChannel.bindings = arr;
71101
+ patched = true;
71102
+ console.log(` Added channel binding for account "${name2}".`);
71103
+ }
71104
+ const hasWildcard = avChannel.bindings.some(
71105
+ (b2) => b2.match?.accountId === "*"
71106
+ );
71107
+ if (!hasWildcard) {
71108
+ avChannel.bindings.push({ match: { accountId: "*" } });
71109
+ patched = true;
71110
+ console.log(` Added wildcard channel binding (accountId: "*").`);
71111
+ }
71112
+ }
71113
+ const topBindings = freshConfig.bindings;
71114
+ const hasTopBinding = topBindings?.some(
71115
+ (b2) => b2.agentId === name2 && b2.match?.accountId === name2
71116
+ );
71117
+ if (!hasTopBinding) {
71118
+ const entry = {
71119
+ agentId: name2,
71120
+ match: { channel: "agentvault", accountId: name2 }
71121
+ };
71122
+ if (topBindings) {
71123
+ topBindings.push(entry);
71124
+ } else {
71125
+ freshConfig.bindings = [entry];
71126
+ }
71127
+ patched = true;
71128
+ console.log(` Added top-level binding: ${name2} \u2192 agentvault:${name2}.`);
71129
+ }
71130
+ if (patched) {
71131
+ writeOpenClawConfig(home, freshConfig, name2);
71132
+ console.log(` httpPort set to ${port}.
71133
+ `);
71134
+ } else {
71135
+ console.log(` Warning: Could not find account '${name2}' in channels.agentvault.accounts.`);
71136
+ console.log(` You may need to manually set httpPort: ${port} in openclaw.json.
71137
+ `);
71138
+ }
71139
+ } catch (err) {
71140
+ console.log(` Warning: Failed to patch openclaw.json: ${err.message}
71141
+ `);
71142
+ }
71143
+ console.log(" Verifying agent...");
71144
+ try {
71145
+ const http = await import("node:http");
71146
+ await new Promise((resolve4) => {
71147
+ const req = http.get(`http://127.0.0.1:${port}/status`, { timeout: 3e3 }, (res) => {
71148
+ console.log(` Port ${port} responded (HTTP ${res.statusCode}).`);
71149
+ res.resume();
71150
+ resolve4();
71151
+ });
71152
+ req.on("error", () => {
71153
+ console.log(` Port ${port} not yet responding \u2014 gateway may need a moment.`);
71154
+ resolve4();
71155
+ });
71156
+ req.on("timeout", () => {
71157
+ req.destroy();
71158
+ console.log(` Port ${port} timed out \u2014 check gateway logs.`);
71159
+ resolve4();
71160
+ });
71161
+ });
71162
+ } catch {
71163
+ console.log(" Verification skipped.");
71164
+ }
71165
+ if (process.platform === "darwin") {
71166
+ const { validatePlist: validatePlist2 } = await init_doctor().then(() => doctor_exports);
71167
+ const plistResult = validatePlist2();
71168
+ if (plistResult.status === "stale") {
71169
+ console.log(`
71170
+ \u26A0\uFE0F macOS LaunchAgent plist has stale paths.
71171
+ Run to diagnose and fix: npx @agentvault/agentvault doctor
71172
+ `);
71173
+ }
71174
+ }
71175
+ console.log(`
71176
+ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
71177
+ Agent '${name2}' created successfully!
71178
+ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
71179
+
71180
+ Workspace: ${workspaceDir}
71181
+ DataDir: ${dataDir2}
71182
+ HTTP Port: ${port}
71183
+
71184
+ Next steps:
71185
+ 1. Edit ${workspaceDir}/SOUL.md \u2014 give ${name2} a personality
71186
+ 2. Edit ${workspaceDir}/IDENTITY.md \u2014 set name, emoji, vibe
71187
+ 3. Approve the agent in the AgentVault app
71188
+ `);
71189
+ }
71190
+ var init_create_agent = __esm({
71191
+ async "src/create-agent.ts"() {
71192
+ "use strict";
71193
+ await init_setup();
71194
+ }
71195
+ });
71196
+
71197
+ // src/setup.ts
71198
+ var setup_exports = {};
71199
+ __export(setup_exports, {
71200
+ configurePm2: () => configurePm2,
71201
+ installPlugin: () => installPlugin,
71202
+ runSetupCommand: () => runSetupCommand
71169
71203
  });
71170
71204
  import { execSync as execSync3, spawnSync } from "node:child_process";
71171
71205
  import * as readline from "node:readline";
@@ -71338,27 +71372,53 @@ async function runSetupCommand(options) {
71338
71372
  break;
71339
71373
  }
71340
71374
  }
71341
- if (configPatched) {
71375
+ if (configPatched && options.accountId) {
71342
71376
  try {
71343
- const raw = execSync3("openclaw config get channels.agentvault.bindings", {
71344
- stdio: "pipe",
71345
- env
71346
- }).toString().trim();
71347
- const hasWildcard = raw.includes('"*"') || raw.includes("'*'");
71348
- if (!hasWildcard) {
71349
- execSync3(
71350
- `openclaw config set channels.agentvault.bindings '[{"match":{"accountId":"*"}}]'`,
71351
- { stdio: "pipe", env }
71352
- );
71377
+ const { readOpenClawConfig: readOpenClawConfig2 } = await init_create_agent().then(() => create_agent_exports);
71378
+ const home2 = process.env.HOME ?? "";
71379
+ const ocHome = `${home2}/.openclaw`;
71380
+ const fs = await import("node:fs");
71381
+ const path = await import("node:path");
71382
+ const configPath = path.join(ocHome, "openclaw.json");
71383
+ if (fs.existsSync(configPath)) {
71384
+ const raw = fs.readFileSync(configPath, "utf-8");
71385
+ const cfg = JSON.parse(raw);
71386
+ let changed = false;
71387
+ const avChannel = cfg?.channels?.agentvault;
71388
+ if (avChannel) {
71389
+ const channelBindings = avChannel.bindings ?? [];
71390
+ if (!channelBindings.some((b2) => b2.match?.accountId === options.accountId)) {
71391
+ const wildcardIdx = channelBindings.findIndex((b2) => b2.match?.accountId === "*");
71392
+ const entry = { match: { accountId: options.accountId } };
71393
+ if (wildcardIdx >= 0) {
71394
+ channelBindings.splice(wildcardIdx, 0, entry);
71395
+ } else {
71396
+ channelBindings.push(entry);
71397
+ }
71398
+ avChannel.bindings = channelBindings;
71399
+ changed = true;
71400
+ }
71401
+ if (!channelBindings.some((b2) => b2.match?.accountId === "*")) {
71402
+ channelBindings.push({ match: { accountId: "*" } });
71403
+ changed = true;
71404
+ }
71405
+ }
71406
+ const topBindings = cfg.bindings ?? [];
71407
+ if (!topBindings.some((b2) => b2.agentId === options.accountId && b2.match?.accountId === options.accountId)) {
71408
+ topBindings.push({
71409
+ agentId: options.accountId,
71410
+ match: { channel: "agentvault", accountId: options.accountId }
71411
+ });
71412
+ cfg.bindings = topBindings;
71413
+ changed = true;
71414
+ }
71415
+ if (changed) {
71416
+ const backupPath = `${configPath}.bak.pre-setup-${options.accountId}`;
71417
+ fs.copyFileSync(configPath, backupPath);
71418
+ fs.writeFileSync(configPath, JSON.stringify(cfg, null, 2) + "\n", "utf-8");
71419
+ }
71353
71420
  }
71354
71421
  } catch {
71355
- try {
71356
- execSync3(
71357
- `openclaw config set channels.agentvault.bindings '[{"match":{"accountId":"*"}}]'`,
71358
- { stdio: "pipe", env }
71359
- );
71360
- } catch {
71361
- }
71362
71422
  }
71363
71423
  }
71364
71424
  if (configPatched) {