@askexenow/exe-os 0.9.21 → 0.9.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.
Files changed (60) hide show
  1. package/dist/bin/backfill-conversations.js +17 -4
  2. package/dist/bin/backfill-responses.js +17 -4
  3. package/dist/bin/backfill-vectors.js +2 -2
  4. package/dist/bin/cleanup-stale-review-tasks.js +17 -4
  5. package/dist/bin/cli.js +378 -171
  6. package/dist/bin/exe-assign.js +17 -4
  7. package/dist/bin/exe-boot.js +2 -2
  8. package/dist/bin/exe-dispatch.js +17 -4
  9. package/dist/bin/exe-doctor.js +2 -2
  10. package/dist/bin/exe-export-behaviors.js +17 -4
  11. package/dist/bin/exe-forget.js +17 -4
  12. package/dist/bin/exe-gateway.js +17 -4
  13. package/dist/bin/exe-heartbeat.js +17 -4
  14. package/dist/bin/exe-kill.js +17 -4
  15. package/dist/bin/exe-launch-agent.js +17 -4
  16. package/dist/bin/exe-pending-messages.js +17 -4
  17. package/dist/bin/exe-pending-notifications.js +17 -4
  18. package/dist/bin/exe-pending-reviews.js +17 -4
  19. package/dist/bin/exe-review.js +17 -4
  20. package/dist/bin/exe-search.js +23 -8
  21. package/dist/bin/exe-session-cleanup.js +17 -4
  22. package/dist/bin/exe-start-codex.js +209 -32
  23. package/dist/bin/exe-start-opencode.js +17 -4
  24. package/dist/bin/exe-status.js +17 -4
  25. package/dist/bin/exe-team.js +17 -4
  26. package/dist/bin/git-sweep.js +17 -4
  27. package/dist/bin/graph-backfill.js +17 -4
  28. package/dist/bin/graph-export.js +17 -4
  29. package/dist/bin/install.js +42 -0
  30. package/dist/bin/intercom-check.js +17 -4
  31. package/dist/bin/scan-tasks.js +17 -4
  32. package/dist/bin/shard-migrate.js +17 -4
  33. package/dist/bin/update.js +187 -42
  34. package/dist/gateway/index.js +17 -4
  35. package/dist/hooks/bug-report-worker.js +793 -150
  36. package/dist/hooks/codex-stop-task-finalizer.js +3020 -2375
  37. package/dist/hooks/commit-complete.js +156 -6
  38. package/dist/hooks/error-recall.js +23 -8
  39. package/dist/hooks/ingest.js +17 -4
  40. package/dist/hooks/instructions-loaded.js +17 -4
  41. package/dist/hooks/notification.js +17 -4
  42. package/dist/hooks/post-compact.js +17 -4
  43. package/dist/hooks/post-tool-combined.js +23 -8
  44. package/dist/hooks/pre-compact.js +156 -8
  45. package/dist/hooks/pre-tool-use.js +21 -12
  46. package/dist/hooks/prompt-submit.js +23 -8
  47. package/dist/hooks/session-end.js +156 -8
  48. package/dist/hooks/session-start.js +23 -8
  49. package/dist/hooks/stop.js +306 -9
  50. package/dist/hooks/subagent-stop.js +306 -9
  51. package/dist/hooks/summary-worker.js +2 -2
  52. package/dist/index.js +17 -4
  53. package/dist/lib/exe-daemon.js +37 -14
  54. package/dist/lib/hybrid-search.js +23 -8
  55. package/dist/lib/schedules.js +2 -2
  56. package/dist/lib/store.js +17 -4
  57. package/dist/mcp/server.js +36 -10
  58. package/dist/runtime/index.js +17 -4
  59. package/dist/tui/App.js +17 -4
  60. package/package.json +1 -1
package/dist/bin/cli.js CHANGED
@@ -5985,9 +5985,9 @@ async function cloudPullGraphRAG(config) {
5985
5985
  pulled += stmts.length;
5986
5986
  }
5987
5987
  if (blob.relationship_memories.length > 0) {
5988
- const stmts = blob.relationship_memories.map((rm) => ({
5988
+ const stmts = blob.relationship_memories.map((rm2) => ({
5989
5989
  sql: `INSERT OR IGNORE INTO relationship_memories (relationship_id, memory_id) VALUES (?, ?)`,
5990
- args: [sqlSafe(rm.relationship_id), sqlSafe(rm.memory_id)]
5990
+ args: [sqlSafe(rm2.relationship_id), sqlSafe(rm2.memory_id)]
5991
5991
  }));
5992
5992
  await client.batch(stmts, "write");
5993
5993
  pulled += stmts.length;
@@ -6504,8 +6504,8 @@ function getShardClient(projectName) {
6504
6504
  throw new Error("Shard manager not initialized. Call initShardManager() first.");
6505
6505
  }
6506
6506
  const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
6507
- if (!safeName) {
6508
- throw new Error(`Invalid project name for shard: "${projectName}"`);
6507
+ if (!safeName || safeName === "unknown") {
6508
+ throw new Error(`Invalid project name for shard: "${projectName}" (resolved to "${safeName}")`);
6509
6509
  }
6510
6510
  const cached = _shards.get(safeName);
6511
6511
  if (cached) {
@@ -7374,19 +7374,32 @@ async function flushBatch() {
7374
7374
  const { isShardingEnabled: isShardingEnabled2, getReadyShardClient: getReadyShardClient2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
7375
7375
  if (isShardingEnabled2()) {
7376
7376
  const byProject = /* @__PURE__ */ new Map();
7377
+ let skippedUnknown = 0;
7377
7378
  for (const row of batch) {
7378
- const proj = row.project_name || "unknown";
7379
+ const proj = row.project_name?.trim();
7380
+ if (!proj) {
7381
+ skippedUnknown++;
7382
+ continue;
7383
+ }
7379
7384
  if (!byProject.has(proj)) byProject.set(proj, []);
7380
7385
  byProject.get(proj).push(row);
7381
7386
  }
7387
+ if (skippedUnknown > 0) {
7388
+ process.stderr.write(
7389
+ `[store] Shard skip: ${skippedUnknown} record(s) with empty project_name (kept in main DB only)
7390
+ `
7391
+ );
7392
+ }
7382
7393
  for (const [project, rows] of byProject) {
7383
7394
  try {
7384
7395
  const shardClient = await getReadyShardClient2(project);
7385
7396
  const shardStmts = rows.map(buildStmt);
7386
7397
  await shardClient.batch(shardStmts, "write");
7387
7398
  } catch (err) {
7399
+ const fullError = err instanceof Error ? `${err.name}: ${err.message}${err.stack ? `
7400
+ ${err.stack.split("\n").slice(1, 3).join("\n")}` : ""}` : String(err);
7388
7401
  process.stderr.write(
7389
- `[store] Shard write failed for ${project}: ${err instanceof Error ? err.message : String(err)}
7402
+ `[store] Shard write failed for ${project} (${rows.length} records): ${fullError}
7390
7403
  `
7391
7404
  );
7392
7405
  }
@@ -8414,9 +8427,9 @@ Unclassified: ${unclassified}
8414
8427
  }
8415
8428
  async function exportBatches(options) {
8416
8429
  const fs8 = await import("fs");
8417
- const path46 = await import("path");
8430
+ const path47 = await import("path");
8418
8431
  const client = getClient();
8419
- const outDir = path46.join(process.cwd(), "exe/output/classifications/input");
8432
+ const outDir = path47.join(process.cwd(), "exe/output/classifications/input");
8420
8433
  fs8.mkdirSync(outDir, { recursive: true });
8421
8434
  const countResult = await client.execute({
8422
8435
  sql: "SELECT COUNT(*) as cnt FROM memories WHERE intent IS NULL AND outcome IS NULL AND domain IS NULL",
@@ -8440,7 +8453,7 @@ async function exportBatches(options) {
8440
8453
  const text = String(row.text || "").replace(/\n/g, " ");
8441
8454
  return JSON.stringify({ id: row.id, text });
8442
8455
  });
8443
- const batchFile = path46.join(outDir, `batch-${String(batchNum).padStart(4, "0")}.jsonl`);
8456
+ const batchFile = path47.join(outDir, `batch-${String(batchNum).padStart(4, "0")}.jsonl`);
8444
8457
  fs8.writeFileSync(batchFile, lines.join("\n") + "\n");
8445
8458
  exported += batch.rows.length;
8446
8459
  offset += options.batchSize;
@@ -8456,7 +8469,7 @@ async function exportBatches(options) {
8456
8469
  }
8457
8470
  async function importClassifications(importDir) {
8458
8471
  const fs8 = await import("fs");
8459
- const path46 = await import("path");
8472
+ const path47 = await import("path");
8460
8473
  const client = getClient();
8461
8474
  const files = fs8.readdirSync(importDir).filter((f) => f.endsWith(".jsonl")).sort();
8462
8475
  process.stderr.write(`[backfill-metadata] Found ${files.length} JSONL files to import from ${importDir}
@@ -8464,7 +8477,7 @@ async function importClassifications(importDir) {
8464
8477
  let imported = 0;
8465
8478
  let invalid = 0;
8466
8479
  for (const file of files) {
8467
- const lines = fs8.readFileSync(path46.join(importDir, file), "utf-8").split("\n").filter(Boolean);
8480
+ const lines = fs8.readFileSync(path47.join(importDir, file), "utf-8").split("\n").filter(Boolean);
8468
8481
  for (const line of lines) {
8469
8482
  try {
8470
8483
  const rec = JSON.parse(line);
@@ -11097,10 +11110,10 @@ async function disposeEmbedder() {
11097
11110
  async function embedDirect(text) {
11098
11111
  const llamaCpp = await import("node-llama-cpp");
11099
11112
  const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
11100
- const { existsSync: existsSync32 } = await import("fs");
11101
- const path46 = await import("path");
11102
- const modelPath = path46.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
11103
- if (!existsSync32(modelPath)) {
11113
+ const { existsSync: existsSync33 } = await import("fs");
11114
+ const path47 = await import("path");
11115
+ const modelPath = path47.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
11116
+ if (!existsSync33(modelPath)) {
11104
11117
  throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
11105
11118
  }
11106
11119
  const llama = await llamaCpp.getLlama();
@@ -15515,12 +15528,108 @@ var init_setup_wizard = __esm({
15515
15528
  }
15516
15529
  });
15517
15530
 
15531
+ // src/lib/update-backup.ts
15532
+ import { copyFile, readFile as readFile6, readdir as readdir3, writeFile as writeFile7, rm, mkdir as mkdir7, cp } from "fs/promises";
15533
+ import { existsSync as existsSync28 } from "fs";
15534
+ import path34 from "path";
15535
+ import os17 from "os";
15536
+ function resolveDataDir2() {
15537
+ if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
15538
+ if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
15539
+ return path34.join(os17.homedir(), ".exe-os");
15540
+ }
15541
+ async function createUpdateBackup(currentVersion, dataDir) {
15542
+ const dir = dataDir ?? resolveDataDir2();
15543
+ const backupDir = path34.join(dir, BACKUP_DIR_NAME);
15544
+ if (existsSync28(backupDir)) {
15545
+ await rm(backupDir, { recursive: true, force: true });
15546
+ }
15547
+ await mkdir7(backupDir, { recursive: true });
15548
+ const backedUpFiles = [];
15549
+ for (const target of BACKUP_TARGETS) {
15550
+ const src = path34.join(dir, target.name);
15551
+ if (!existsSync28(src)) continue;
15552
+ const dest = path34.join(backupDir, target.name);
15553
+ if (target.type === "file") {
15554
+ await copyFile(src, dest);
15555
+ } else {
15556
+ await cp(src, dest, { recursive: true });
15557
+ }
15558
+ backedUpFiles.push(target.name);
15559
+ }
15560
+ const entries = await readdir3(dir, { withFileTypes: true });
15561
+ for (const entry of entries) {
15562
+ if (entry.isFile() && entry.name.endsWith(".db") && entry.name !== BACKUP_DIR_NAME) {
15563
+ const src = path34.join(dir, entry.name);
15564
+ const dest = path34.join(backupDir, entry.name);
15565
+ await copyFile(src, dest);
15566
+ backedUpFiles.push(entry.name);
15567
+ }
15568
+ }
15569
+ const manifest = {
15570
+ version: currentVersion,
15571
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
15572
+ files: backedUpFiles
15573
+ };
15574
+ await writeFile7(
15575
+ path34.join(backupDir, "manifest.json"),
15576
+ JSON.stringify(manifest, null, 2) + "\n"
15577
+ );
15578
+ return manifest;
15579
+ }
15580
+ async function restoreFromBackup(dataDir) {
15581
+ const dir = dataDir ?? resolveDataDir2();
15582
+ const backupDir = path34.join(dir, BACKUP_DIR_NAME);
15583
+ const manifestPath = path34.join(backupDir, "manifest.json");
15584
+ if (!existsSync28(manifestPath)) {
15585
+ throw new Error(
15586
+ `No backup found at ${backupDir}. Nothing to restore.`
15587
+ );
15588
+ }
15589
+ const manifest = JSON.parse(
15590
+ await readFile6(manifestPath, "utf-8")
15591
+ );
15592
+ for (const fileName of manifest.files) {
15593
+ const src = path34.join(backupDir, fileName);
15594
+ const dest = path34.join(dir, fileName);
15595
+ if (!existsSync28(src)) continue;
15596
+ const stat2 = await import("fs/promises").then((m) => m.stat(src));
15597
+ if (stat2.isDirectory()) {
15598
+ await cp(src, dest, { recursive: true, force: true });
15599
+ } else {
15600
+ await copyFile(src, dest);
15601
+ }
15602
+ }
15603
+ return manifest;
15604
+ }
15605
+ async function deleteBackup(dataDir) {
15606
+ const dir = dataDir ?? resolveDataDir2();
15607
+ const backupDir = path34.join(dir, BACKUP_DIR_NAME);
15608
+ if (existsSync28(backupDir)) {
15609
+ await rm(backupDir, { recursive: true, force: true });
15610
+ }
15611
+ }
15612
+ var BACKUP_DIR_NAME, BACKUP_TARGETS;
15613
+ var init_update_backup = __esm({
15614
+ "src/lib/update-backup.ts"() {
15615
+ "use strict";
15616
+ BACKUP_DIR_NAME = ".update-backup";
15617
+ BACKUP_TARGETS = [
15618
+ { name: "config.json", type: "file" },
15619
+ { name: "exe-employees.json", type: "file" },
15620
+ { name: "master.key", type: "file" },
15621
+ { name: "identity", type: "dir" }
15622
+ // All .db files (SQLCipher databases) — matched dynamically
15623
+ ];
15624
+ }
15625
+ });
15626
+
15518
15627
  // src/lib/update-check.ts
15519
15628
  import { execSync as execSync11 } from "child_process";
15520
15629
  import { readFileSync as readFileSync24 } from "fs";
15521
- import path34 from "path";
15630
+ import path35 from "path";
15522
15631
  function getLocalVersion(packageRoot) {
15523
- const pkgPath = path34.join(packageRoot, "package.json");
15632
+ const pkgPath = path35.join(packageRoot, "package.json");
15524
15633
  const pkg = JSON.parse(readFileSync24(pkgPath, "utf-8"));
15525
15634
  return pkg.version;
15526
15635
  }
@@ -15567,10 +15676,47 @@ __export(update_exports, {
15567
15676
  });
15568
15677
  import { execSync as execSync12 } from "child_process";
15569
15678
  import { createInterface as createInterface4 } from "readline";
15679
+ async function runRestore() {
15680
+ console.log("\n\u{1F504} Restoring from update backup...");
15681
+ try {
15682
+ const manifest = await restoreFromBackup();
15683
+ console.log(` Restored ${manifest.files.length} file(s) from v${manifest.version} backup.`);
15684
+ console.log(` Backup was created at ${manifest.timestamp}`);
15685
+ console.log(`
15686
+ \u{1F4E5} Reinstalling @askexenow/exe-os@${manifest.version}...`);
15687
+ try {
15688
+ execSync12(`npm install -g @askexenow/exe-os@${manifest.version}`, {
15689
+ stdio: ["pipe", "pipe", "inherit"],
15690
+ timeout: 3e5
15691
+ });
15692
+ console.log(`
15693
+ \u2705 Restored to v${manifest.version}`);
15694
+ } catch {
15695
+ console.error(`
15696
+ \u26A0\uFE0F Could not reinstall v${manifest.version} via npm.`);
15697
+ console.error(` Your data files have been restored. Try manually:`);
15698
+ console.error(` npm install -g @askexenow/exe-os@${manifest.version}`);
15699
+ }
15700
+ try {
15701
+ await deleteBackup();
15702
+ } catch {
15703
+ }
15704
+ console.log("\n\u{1F680} Restore complete. Restart your sessions.\n");
15705
+ } catch (err) {
15706
+ console.error("\u274C Restore failed.");
15707
+ if (err instanceof Error) console.error(` ${err.message}`);
15708
+ process.exit(1);
15709
+ }
15710
+ }
15570
15711
  async function runUpdate(cliArgs) {
15571
15712
  const args2 = cliArgs ?? process.argv.slice(2);
15572
15713
  const autoMode = args2.includes("--auto") || args2.includes("-y");
15573
15714
  const checkOnly = args2.includes("--check");
15715
+ const restoreMode = args2.includes("--restore");
15716
+ if (restoreMode) {
15717
+ await runRestore();
15718
+ return;
15719
+ }
15574
15720
  const packageRoot = new URL("../..", import.meta.url).pathname;
15575
15721
  const result = checkForUpdate(packageRoot);
15576
15722
  if (result.error) {
@@ -15605,7 +15751,16 @@ async function runUpdate(cliArgs) {
15605
15751
  console.log("Update skipped.");
15606
15752
  process.exit(0);
15607
15753
  }
15608
- console.log("\n\u{1F9F9} Clearing npm cache...");
15754
+ console.log("\n\u{1F4BE} Backing up customer data...");
15755
+ try {
15756
+ const backupResult = await createUpdateBackup(result.localVersion);
15757
+ console.log(` Backed up ${backupResult.files.length} file(s) to ${BACKUP_DIR_NAME}/`);
15758
+ } catch (err) {
15759
+ console.error("\u274C Backup failed \u2014 aborting update to protect your data.");
15760
+ if (err instanceof Error) console.error(` ${err.message}`);
15761
+ process.exit(1);
15762
+ }
15763
+ console.log("\u{1F9F9} Clearing npm cache...");
15609
15764
  try {
15610
15765
  execSync12("npm cache clean --force", { stdio: "pipe" });
15611
15766
  console.log(" Done");
@@ -15620,8 +15775,9 @@ async function runUpdate(cliArgs) {
15620
15775
  timeout: 3e5
15621
15776
  });
15622
15777
  } catch (err) {
15623
- console.error("\n\u274C Update failed.");
15624
- console.error(" Try manually: npm install -g @askexenow/exe-os@latest");
15778
+ console.error("\n\u274C Update failed. Your backup is preserved.");
15779
+ console.error(` Restore with: exe-os update --restore`);
15780
+ console.error(" Or try manually: npm install -g @askexenow/exe-os@latest");
15625
15781
  if (err instanceof Error && err.message) {
15626
15782
  console.error(` Error: ${err.message.split("\n")[0]}`);
15627
15783
  }
@@ -15640,30 +15796,38 @@ async function runUpdate(cliArgs) {
15640
15796
  }
15641
15797
  }
15642
15798
  const remoteVersion = result.remoteVersion;
15799
+ const updateSucceeded = newVersion !== result.localVersion;
15643
15800
  if (newVersion === remoteVersion) {
15644
15801
  console.log(`
15645
15802
  \u2705 Updated to v${newVersion}`);
15646
- } else if (newVersion !== result.localVersion) {
15803
+ } else if (updateSucceeded) {
15647
15804
  console.log(`
15648
15805
  \u2705 Updated to v${newVersion} (latest: v${remoteVersion})`);
15649
15806
  } else {
15650
15807
  console.log(`
15651
15808
  \u26A0\uFE0F Version unchanged (v${newVersion}). npm cache may be stale.`);
15809
+ console.log(" Backup preserved. Restore with: exe-os update --restore");
15652
15810
  console.log(" Try: npm cache clean --force && npm install -g @askexenow/exe-os@latest");
15653
15811
  }
15812
+ if (updateSucceeded) {
15813
+ try {
15814
+ await deleteBackup();
15815
+ } catch {
15816
+ }
15817
+ }
15654
15818
  console.log(" Hooks re-wired, daemon restarted automatically.");
15655
15819
  console.log("");
15656
15820
  console.log(" \x1B[33m\u26A1 Run /mcp in each active Claude Code session to pick up new tools.\x1B[0m");
15657
15821
  console.log(" \x1B[2m(MCP servers can't hot-reload \u2014 Claude Code needs to reconnect them.)\x1B[0m");
15658
15822
  try {
15659
- const { existsSync: exists, readFileSync: readFile8 } = await import("fs");
15823
+ const { existsSync: exists, readFileSync: readFile9 } = await import("fs");
15660
15824
  const p = await import("path");
15661
15825
  const { homedir: home } = await import("os");
15662
15826
  const exeDir = p.default.join(home(), ".exe-os");
15663
15827
  const licKeyPath = p.default.join(exeDir, "license.key");
15664
15828
  const configPath = p.default.join(exeDir, "config.json");
15665
15829
  if (!exists(licKeyPath) && exists(configPath)) {
15666
- const cfg = JSON.parse(readFile8(configPath, "utf8"));
15830
+ const cfg = JSON.parse(readFile9(configPath, "utf8"));
15667
15831
  const cloud = cfg.cloud;
15668
15832
  if (cloud?.apiKey) {
15669
15833
  const { mirrorLicenseKey: mirrorLicenseKey2 } = await Promise.resolve().then(() => (init_license(), license_exports));
@@ -15679,6 +15843,7 @@ var init_update = __esm({
15679
15843
  "src/bin/update.ts"() {
15680
15844
  "use strict";
15681
15845
  init_is_main();
15846
+ init_update_backup();
15682
15847
  init_update_check();
15683
15848
  init_update_check();
15684
15849
  if (isMainModule(import.meta.url) && process.argv[1]?.includes("update")) {
@@ -20048,8 +20213,8 @@ var init_ErrorOverview = __esm({
20048
20213
  "use strict";
20049
20214
  init_Box();
20050
20215
  init_Text();
20051
- cleanupPath = (path46) => {
20052
- return path46?.replace(`file://${cwd()}/`, "");
20216
+ cleanupPath = (path47) => {
20217
+ return path47?.replace(`file://${cwd()}/`, "");
20053
20218
  };
20054
20219
  stackUtils = new StackUtils({
20055
20220
  cwd: cwd(),
@@ -21467,8 +21632,8 @@ var init_parse_keypress = __esm({
21467
21632
  57453: "isoLevel3Shift",
21468
21633
  57454: "isoLevel5Shift"
21469
21634
  };
21470
- isValidCodepoint = (cp) => cp >= 0 && cp <= 1114111 && !(cp >= 55296 && cp <= 57343);
21471
- safeFromCodePoint = (cp) => isValidCodepoint(cp) ? String.fromCodePoint(cp) : "?";
21635
+ isValidCodepoint = (cp2) => cp2 >= 0 && cp2 <= 1114111 && !(cp2 >= 55296 && cp2 <= 57343);
21636
+ safeFromCodePoint = (cp2) => isValidCodepoint(cp2) ? String.fromCodePoint(cp2) : "?";
21472
21637
  parseKittyKeypress = (s) => {
21473
21638
  const match = kittyKeyRe.exec(s);
21474
21639
  if (!match)
@@ -21482,7 +21647,7 @@ var init_parse_keypress = __esm({
21482
21647
  }
21483
21648
  let text;
21484
21649
  if (textField) {
21485
- text = textField.split(":").map((cp) => safeFromCodePoint(parseInt(cp, 10))).join("");
21650
+ text = textField.split(":").map((cp2) => safeFromCodePoint(parseInt(cp2, 10))).join("");
21486
21651
  }
21487
21652
  let name;
21488
21653
  let isPrintable;
@@ -22457,11 +22622,11 @@ function Footer() {
22457
22622
  } catch {
22458
22623
  }
22459
22624
  try {
22460
- const { existsSync: existsSync32 } = await import("fs");
22625
+ const { existsSync: existsSync33 } = await import("fs");
22461
22626
  const { join } = await import("path");
22462
22627
  const home = process.env.HOME ?? "";
22463
22628
  const pidPath = join(home, ".exe-os", "exed.pid");
22464
- setDaemon(existsSync32(pidPath) ? "running" : "stopped");
22629
+ setDaemon(existsSync33(pidPath) ? "running" : "stopped");
22465
22630
  } catch {
22466
22631
  setDaemon("unknown");
22467
22632
  }
@@ -24512,10 +24677,10 @@ var init_hooks = __esm({
24512
24677
  });
24513
24678
 
24514
24679
  // src/runtime/safety-checks.ts
24515
- import path35 from "path";
24516
- import os17 from "os";
24680
+ import path36 from "path";
24681
+ import os18 from "os";
24517
24682
  function checkPathSafety(filePath) {
24518
- const resolved = path35.resolve(filePath);
24683
+ const resolved = path36.resolve(filePath);
24519
24684
  for (const { pattern, reason } of BYPASS_IMMUNE_PATTERNS) {
24520
24685
  const matches = typeof pattern === "function" ? pattern(resolved) : pattern.test(resolved);
24521
24686
  if (matches) {
@@ -24525,7 +24690,7 @@ function checkPathSafety(filePath) {
24525
24690
  return { safe: true, bypassImmune: true };
24526
24691
  }
24527
24692
  function checkReadPathSafety(filePath) {
24528
- const resolved = path35.resolve(filePath);
24693
+ const resolved = path36.resolve(filePath);
24529
24694
  const credPatterns = BYPASS_IMMUNE_PATTERNS.filter(
24530
24695
  (p) => typeof p.pattern !== "function" && (p.reason.includes("secrets") || p.reason.includes("Private key") || p.reason.includes("Credential"))
24531
24696
  );
@@ -24540,7 +24705,7 @@ var HOME, BYPASS_IMMUNE_PATTERNS;
24540
24705
  var init_safety_checks = __esm({
24541
24706
  "src/runtime/safety-checks.ts"() {
24542
24707
  "use strict";
24543
- HOME = os17.homedir();
24708
+ HOME = os18.homedir();
24544
24709
  BYPASS_IMMUNE_PATTERNS = [
24545
24710
  {
24546
24711
  pattern: /\/\.git\/hooks\//,
@@ -24551,11 +24716,11 @@ var init_safety_checks = __esm({
24551
24716
  reason: "Git config can set hooks and command execution"
24552
24717
  },
24553
24718
  {
24554
- pattern: (p) => p.startsWith(path35.join(HOME, ".claude")),
24719
+ pattern: (p) => p.startsWith(path36.join(HOME, ".claude")),
24555
24720
  reason: "Claude configuration files are protected"
24556
24721
  },
24557
24722
  {
24558
- pattern: (p) => p.startsWith(path35.join(HOME, ".exe-os")),
24723
+ pattern: (p) => p.startsWith(path36.join(HOME, ".exe-os")),
24559
24724
  reason: "exe-os configuration files are protected"
24560
24725
  },
24561
24726
  {
@@ -24572,7 +24737,7 @@ var init_safety_checks = __esm({
24572
24737
  },
24573
24738
  {
24574
24739
  pattern: (p) => {
24575
- const name = path35.basename(p);
24740
+ const name = path36.basename(p);
24576
24741
  return [".bashrc", ".zshrc", ".profile", ".bash_profile", ".zprofile", ".zshenv"].includes(name);
24577
24742
  },
24578
24743
  reason: "Shell configuration files can execute arbitrary code on login"
@@ -24599,7 +24764,7 @@ __export(file_read_exports, {
24599
24764
  FileReadTool: () => FileReadTool
24600
24765
  });
24601
24766
  import fs3 from "fs/promises";
24602
- import path36 from "path";
24767
+ import path37 from "path";
24603
24768
  import { z } from "zod";
24604
24769
  function isBinary(buf) {
24605
24770
  for (let i = 0; i < buf.length; i++) {
@@ -24635,7 +24800,7 @@ var init_file_read = __esm({
24635
24800
  return { behavior: "allow" };
24636
24801
  },
24637
24802
  async call(input, context) {
24638
- const filePath = path36.isAbsolute(input.file_path) ? input.file_path : path36.resolve(context.cwd, input.file_path);
24803
+ const filePath = path37.isAbsolute(input.file_path) ? input.file_path : path37.resolve(context.cwd, input.file_path);
24639
24804
  let stat2;
24640
24805
  try {
24641
24806
  stat2 = await fs3.stat(filePath);
@@ -24675,7 +24840,7 @@ __export(glob_exports, {
24675
24840
  GlobTool: () => GlobTool
24676
24841
  });
24677
24842
  import fs4 from "fs/promises";
24678
- import path37 from "path";
24843
+ import path38 from "path";
24679
24844
  import { z as z2 } from "zod";
24680
24845
  async function walkDir(dir, maxDepth = 10) {
24681
24846
  const results = [];
@@ -24691,7 +24856,7 @@ async function walkDir(dir, maxDepth = 10) {
24691
24856
  if (entry.isDirectory() && (entry.name === "node_modules" || entry.name === ".git")) {
24692
24857
  continue;
24693
24858
  }
24694
- const fullPath = path37.join(current, entry.name);
24859
+ const fullPath = path38.join(current, entry.name);
24695
24860
  if (entry.isDirectory()) {
24696
24861
  await walk(fullPath, depth + 1);
24697
24862
  } else {
@@ -24725,11 +24890,11 @@ var init_glob = __esm({
24725
24890
  inputSchema: inputSchema2,
24726
24891
  isReadOnly: true,
24727
24892
  async call(input, context) {
24728
- const baseDir = input.path ? path37.isAbsolute(input.path) ? input.path : path37.resolve(context.cwd, input.path) : context.cwd;
24893
+ const baseDir = input.path ? path38.isAbsolute(input.path) ? input.path : path38.resolve(context.cwd, input.path) : context.cwd;
24729
24894
  try {
24730
24895
  const entries = await walkDir(baseDir);
24731
24896
  const matched = entries.filter(
24732
- (e) => simpleGlobMatch(path37.relative(baseDir, e.path), input.pattern)
24897
+ (e) => simpleGlobMatch(path38.relative(baseDir, e.path), input.pattern)
24733
24898
  );
24734
24899
  matched.sort((a, b) => b.mtime - a.mtime);
24735
24900
  if (matched.length === 0) {
@@ -24755,7 +24920,7 @@ __export(grep_exports, {
24755
24920
  });
24756
24921
  import { spawn as spawn2 } from "child_process";
24757
24922
  import fs5 from "fs/promises";
24758
- import path38 from "path";
24923
+ import path39 from "path";
24759
24924
  import { z as z3 } from "zod";
24760
24925
  function runRipgrep(input, searchPath, context) {
24761
24926
  return new Promise((resolve, reject) => {
@@ -24809,7 +24974,7 @@ async function nodeGrep(input, searchPath) {
24809
24974
  }
24810
24975
  for (const entry of entries) {
24811
24976
  if (entry.name === "node_modules" || entry.name === ".git") continue;
24812
- const fullPath = path38.join(dir, entry.name);
24977
+ const fullPath = path39.join(dir, entry.name);
24813
24978
  if (entry.isDirectory()) {
24814
24979
  await walk(fullPath);
24815
24980
  } else {
@@ -24855,7 +25020,7 @@ var init_grep = __esm({
24855
25020
  inputSchema: inputSchema3,
24856
25021
  isReadOnly: true,
24857
25022
  async call(input, context) {
24858
- const searchPath = input.path ? path38.isAbsolute(input.path) ? input.path : path38.resolve(context.cwd, input.path) : context.cwd;
25023
+ const searchPath = input.path ? path39.isAbsolute(input.path) ? input.path : path39.resolve(context.cwd, input.path) : context.cwd;
24859
25024
  try {
24860
25025
  const result = await runRipgrep(input, searchPath, context);
24861
25026
  return result;
@@ -24880,7 +25045,7 @@ __export(file_write_exports, {
24880
25045
  FileWriteTool: () => FileWriteTool
24881
25046
  });
24882
25047
  import fs6 from "fs/promises";
24883
- import path39 from "path";
25048
+ import path40 from "path";
24884
25049
  import { z as z4 } from "zod";
24885
25050
  var inputSchema4, FileWriteTool;
24886
25051
  var init_file_write = __esm({
@@ -24908,8 +25073,8 @@ var init_file_write = __esm({
24908
25073
  return { behavior: "allow" };
24909
25074
  },
24910
25075
  async call(input, context) {
24911
- const filePath = path39.isAbsolute(input.file_path) ? input.file_path : path39.resolve(context.cwd, input.file_path);
24912
- const dir = path39.dirname(filePath);
25076
+ const filePath = path40.isAbsolute(input.file_path) ? input.file_path : path40.resolve(context.cwd, input.file_path);
25077
+ const dir = path40.dirname(filePath);
24913
25078
  await fs6.mkdir(dir, { recursive: true });
24914
25079
  await fs6.writeFile(filePath, input.content, "utf-8");
24915
25080
  return {
@@ -24927,7 +25092,7 @@ __export(file_edit_exports, {
24927
25092
  FileEditTool: () => FileEditTool
24928
25093
  });
24929
25094
  import fs7 from "fs/promises";
24930
- import path40 from "path";
25095
+ import path41 from "path";
24931
25096
  import { z as z5 } from "zod";
24932
25097
  function countOccurrences(haystack, needle) {
24933
25098
  let count = 0;
@@ -24968,7 +25133,7 @@ var init_file_edit = __esm({
24968
25133
  return { behavior: "allow" };
24969
25134
  },
24970
25135
  async call(input, context) {
24971
- const filePath = path40.isAbsolute(input.file_path) ? input.file_path : path40.resolve(context.cwd, input.file_path);
25136
+ const filePath = path41.isAbsolute(input.file_path) ? input.file_path : path41.resolve(context.cwd, input.file_path);
24972
25137
  let content;
24973
25138
  try {
24974
25139
  content = await fs7.readFile(filePath, "utf-8");
@@ -25210,7 +25375,7 @@ var init_bash = __esm({
25210
25375
  // src/tui/views/CommandCenter.tsx
25211
25376
  import { useState as useState6, useEffect as useEffect8, useMemo as useMemo4, useCallback as useCallback4, useRef as useRef4 } from "react";
25212
25377
  import TextInput from "ink-text-input";
25213
- import path41 from "path";
25378
+ import path42 from "path";
25214
25379
  import { homedir as homedir6 } from "os";
25215
25380
  import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
25216
25381
  function CommandCenterView({
@@ -25245,13 +25410,13 @@ function CommandCenterView({
25245
25410
  const { createPermissionsFromPreset: createPermissionsFromPreset2, EMPLOYEE_PERMISSIONS: EMPLOYEE_PERMISSIONS2 } = await Promise.resolve().then(() => (init_permissions(), permissions_exports));
25246
25411
  const { getPresetByRole: getPresetByRole2 } = await Promise.resolve().then(() => (init_permission_presets(), permission_presets_exports));
25247
25412
  const { createDefaultHooks: createDefaultHooks2 } = await Promise.resolve().then(() => (init_hooks(), hooks_exports));
25248
- const { readFileSync: readFileSync28, existsSync: existsSync32 } = await import("fs");
25413
+ const { readFileSync: readFileSync28, existsSync: existsSync33 } = await import("fs");
25249
25414
  const { join } = await import("path");
25250
25415
  const { homedir: homedir8 } = await import("os");
25251
25416
  const configPath = join(homedir8(), ".exe-os", "config.json");
25252
25417
  let failoverChain = ["anthropic", "opencode", "gemini", "openai"];
25253
25418
  let providerConfigs = {};
25254
- if (existsSync32(configPath)) {
25419
+ if (existsSync33(configPath)) {
25255
25420
  try {
25256
25421
  const raw = JSON.parse(readFileSync28(configPath, "utf8"));
25257
25422
  if (Array.isArray(raw.failoverChain)) failoverChain = raw.failoverChain;
@@ -25459,7 +25624,7 @@ function CommandCenterView({
25459
25624
  const demoEntries = DEMO_PROJECTS.map((p) => ({
25460
25625
  projectName: p.projectName,
25461
25626
  exeSession: p.exeSession,
25462
- projectDir: path41.join(homedir6(), p.projectName),
25627
+ projectDir: path42.join(homedir6(), p.projectName),
25463
25628
  employeeCount: p.employees.length,
25464
25629
  activeCount: p.employees.filter((e) => e.status === "active").length,
25465
25630
  memoryCount: p.employees.length * 4e3,
@@ -25497,7 +25662,7 @@ function CommandCenterView({
25497
25662
  const { listSessions: listSessions2 } = await Promise.resolve().then(() => (init_session_registry(), session_registry_exports));
25498
25663
  const { listTmuxSessions: listTmuxSessions2, inTmux: inTmux2 } = await Promise.resolve().then(() => (init_tmux_status(), tmux_status_exports));
25499
25664
  const { loadEmployees: loadEmployees2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
25500
- const { existsSync: existsSync32 } = await import("fs");
25665
+ const { existsSync: existsSync33 } = await import("fs");
25501
25666
  const { join } = await import("path");
25502
25667
  const client = getClient2();
25503
25668
  if (!client) {
@@ -25568,7 +25733,7 @@ function CommandCenterView({
25568
25733
  }
25569
25734
  const memoryCount = memoryCounts.get(name) ?? 0;
25570
25735
  const openTaskCount = openTaskCounts.get(name) ?? 0;
25571
- const hasGit = projectDir ? existsSync32(join(projectDir, ".git")) : false;
25736
+ const hasGit = projectDir ? existsSync33(join(projectDir, ".git")) : false;
25572
25737
  const type = hasGit ? "code" : memoryCount > 0 ? "code" : "automation";
25573
25738
  projectList.push({
25574
25739
  projectName: name,
@@ -25593,7 +25758,7 @@ function CommandCenterView({
25593
25758
  setHealth((h) => ({ ...h, memories: Number(totalResult.rows[0]?.cnt ?? 0) }));
25594
25759
  try {
25595
25760
  const pidPath = join(process.env.HOME ?? "", ".exe-os", "exed.pid");
25596
- setHealth((h) => ({ ...h, daemon: existsSync32(pidPath) ? "running" : "stopped" }));
25761
+ setHealth((h) => ({ ...h, daemon: existsSync33(pidPath) ? "running" : "stopped" }));
25597
25762
  } catch {
25598
25763
  }
25599
25764
  const activityResult = await client.execute(
@@ -26463,7 +26628,7 @@ var init_useOrchestrator = __esm({
26463
26628
 
26464
26629
  // src/tui/views/Sessions.tsx
26465
26630
  import React19, { useState as useState9, useEffect as useEffect11, useCallback as useCallback6 } from "react";
26466
- import path42 from "path";
26631
+ import path43 from "path";
26467
26632
  import { homedir as homedir7 } from "os";
26468
26633
  import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
26469
26634
  function isCoordinatorEntry(entry) {
@@ -26501,7 +26666,7 @@ function SessionsView({
26501
26666
  if (demo) {
26502
26667
  setProjects(DEMO_PROJECTS.map((p) => ({
26503
26668
  ...p,
26504
- projectDir: path42.join(homedir7(), p.projectName),
26669
+ projectDir: path43.join(homedir7(), p.projectName),
26505
26670
  employees: p.employees.map((e) => ({ ...e, attached: e.status === "active" }))
26506
26671
  })));
26507
26672
  return;
@@ -27716,11 +27881,11 @@ async function loadGatewayConfig() {
27716
27881
  state.running = false;
27717
27882
  }
27718
27883
  try {
27719
- const { existsSync: existsSync32, readFileSync: readFileSync28 } = await import("fs");
27884
+ const { existsSync: existsSync33, readFileSync: readFileSync28 } = await import("fs");
27720
27885
  const { join } = await import("path");
27721
27886
  const home = process.env.HOME ?? "";
27722
27887
  const configPath = join(home, ".exe-os", "gateway.json");
27723
- if (existsSync32(configPath)) {
27888
+ if (existsSync33(configPath)) {
27724
27889
  const raw = JSON.parse(readFileSync28(configPath, "utf8"));
27725
27890
  state.port = raw.port ?? 3100;
27726
27891
  state.gatewayUrl = raw.gatewayUrl ?? "";
@@ -28319,11 +28484,11 @@ function TeamView({ onBack, onViewSessions }) {
28319
28484
  setMembers(teamData);
28320
28485
  setDbError(null);
28321
28486
  try {
28322
- const { existsSync: existsSync32, readFileSync: readFileSync28 } = await import("fs");
28487
+ const { existsSync: existsSync33, readFileSync: readFileSync28 } = await import("fs");
28323
28488
  const { join } = await import("path");
28324
28489
  const home = process.env.HOME ?? "";
28325
28490
  const gatewayConfig = join(home, ".exe-os", "gateway.json");
28326
- if (existsSync32(gatewayConfig)) {
28491
+ if (existsSync33(gatewayConfig)) {
28327
28492
  const raw = JSON.parse(readFileSync28(gatewayConfig, "utf8"));
28328
28493
  if (raw.agents && raw.agents.length > 0) {
28329
28494
  setExternals(raw.agents.map((a) => ({
@@ -28504,8 +28669,8 @@ __export(wiki_client_exports, {
28504
28669
  listDocuments: () => listDocuments,
28505
28670
  listWorkspaces: () => listWorkspaces
28506
28671
  });
28507
- async function wikiFetch(config, path46, method = "GET", body) {
28508
- const url = `${config.baseUrl}/api/v1${path46}`;
28672
+ async function wikiFetch(config, path47, method = "GET", body) {
28673
+ const url = `${config.baseUrl}/api/v1${path47}`;
28509
28674
  const headers = {
28510
28675
  Authorization: `Bearer ${config.apiKey}`,
28511
28676
  "Content-Type": "application/json"
@@ -28538,7 +28703,7 @@ async function wikiFetch(config, path46, method = "GET", body) {
28538
28703
  }
28539
28704
  }
28540
28705
  if (!response.ok) {
28541
- throw new Error(`Wiki API ${method} ${path46}: ${response.status} ${response.statusText}`);
28706
+ throw new Error(`Wiki API ${method} ${path47}: ${response.status} ${response.statusText}`);
28542
28707
  }
28543
28708
  return response.json();
28544
28709
  } finally {
@@ -29132,12 +29297,12 @@ function SettingsView({ onBack }) {
29132
29297
  }
29133
29298
  setProviders(providerList);
29134
29299
  try {
29135
- const { existsSync: existsSync32 } = await import("fs");
29300
+ const { existsSync: existsSync33 } = await import("fs");
29136
29301
  const { join } = await import("path");
29137
29302
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
29138
29303
  const cfg = await loadConfig2();
29139
29304
  const home = process.env.HOME ?? "";
29140
- const hasKey = existsSync32(join(home, ".exe-os", "master.key"));
29305
+ const hasKey = existsSync33(join(home, ".exe-os", "master.key"));
29141
29306
  if (cfg.cloud) {
29142
29307
  setCloud({
29143
29308
  configured: true,
@@ -29150,7 +29315,7 @@ function SettingsView({ onBack }) {
29150
29315
  const pidPath = join(home, ".exe-os", "exed.pid");
29151
29316
  let daemon = "unknown";
29152
29317
  try {
29153
- daemon = existsSync32(pidPath) ? "running" : "stopped";
29318
+ daemon = existsSync33(pidPath) ? "running" : "stopped";
29154
29319
  } catch {
29155
29320
  }
29156
29321
  let version = "unknown";
@@ -29965,18 +30130,18 @@ __export(installer_exports2, {
29965
30130
  runOpenCodeInstaller: () => runOpenCodeInstaller,
29966
30131
  verifyOpenCodeHooks: () => verifyOpenCodeHooks
29967
30132
  });
29968
- import { readFile as readFile6, writeFile as writeFile7, mkdir as mkdir7 } from "fs/promises";
29969
- import { existsSync as existsSync29, readFileSync as readFileSync26 } from "fs";
29970
- import path43 from "path";
29971
- import os18 from "os";
29972
- async function registerOpenCodeMcp(packageRoot, homeDir = os18.homedir()) {
29973
- const configDir = path43.join(homeDir, ".config", "opencode");
29974
- const configPath = path43.join(configDir, "opencode.json");
29975
- await mkdir7(configDir, { recursive: true });
30133
+ import { readFile as readFile7, writeFile as writeFile8, mkdir as mkdir8 } from "fs/promises";
30134
+ import { existsSync as existsSync30, readFileSync as readFileSync26 } from "fs";
30135
+ import path44 from "path";
30136
+ import os19 from "os";
30137
+ async function registerOpenCodeMcp(packageRoot, homeDir = os19.homedir()) {
30138
+ const configDir = path44.join(homeDir, ".config", "opencode");
30139
+ const configPath = path44.join(configDir, "opencode.json");
30140
+ await mkdir8(configDir, { recursive: true });
29976
30141
  let config = {};
29977
- if (existsSync29(configPath)) {
30142
+ if (existsSync30(configPath)) {
29978
30143
  try {
29979
- config = JSON.parse(await readFile6(configPath, "utf-8"));
30144
+ config = JSON.parse(await readFile7(configPath, "utf-8"));
29980
30145
  } catch {
29981
30146
  config = {};
29982
30147
  }
@@ -29986,7 +30151,7 @@ async function registerOpenCodeMcp(packageRoot, homeDir = os18.homedir()) {
29986
30151
  }
29987
30152
  const newEntry = {
29988
30153
  type: "local",
29989
- command: ["node", path43.join(packageRoot, "dist", "mcp", "server.js")],
30154
+ command: ["node", path44.join(packageRoot, "dist", "mcp", "server.js")],
29990
30155
  enabled: true
29991
30156
  };
29992
30157
  const current = config.mcp["exe-os"];
@@ -29997,37 +30162,37 @@ async function registerOpenCodeMcp(packageRoot, homeDir = os18.homedir()) {
29997
30162
  if (!config.$schema) {
29998
30163
  config.$schema = "https://opencode.ai/config.json";
29999
30164
  }
30000
- await writeFile7(configPath, JSON.stringify(config, null, 2) + "\n");
30165
+ await writeFile8(configPath, JSON.stringify(config, null, 2) + "\n");
30001
30166
  return true;
30002
30167
  }
30003
- async function installOpenCodePlugin(packageRoot, homeDir = os18.homedir()) {
30004
- const pluginDir = path43.join(homeDir, ".config", "opencode", "plugins");
30005
- const pluginPath = path43.join(pluginDir, "exe-os.mjs");
30006
- await mkdir7(pluginDir, { recursive: true });
30168
+ async function installOpenCodePlugin(packageRoot, homeDir = os19.homedir()) {
30169
+ const pluginDir = path44.join(homeDir, ".config", "opencode", "plugins");
30170
+ const pluginPath = path44.join(pluginDir, "exe-os.mjs");
30171
+ await mkdir8(pluginDir, { recursive: true });
30007
30172
  const pluginContent = PLUGIN_TEMPLATE.replace(
30008
30173
  /__PACKAGE_ROOT__/g,
30009
30174
  packageRoot.replace(/\\/g, "\\\\")
30010
30175
  );
30011
- if (existsSync29(pluginPath)) {
30012
- const existing = await readFile6(pluginPath, "utf-8");
30176
+ if (existsSync30(pluginPath)) {
30177
+ const existing = await readFile7(pluginPath, "utf-8");
30013
30178
  if (existing === pluginContent) {
30014
30179
  return false;
30015
30180
  }
30016
30181
  }
30017
- await writeFile7(pluginPath, pluginContent);
30182
+ await writeFile8(pluginPath, pluginContent);
30018
30183
  return true;
30019
30184
  }
30020
- function verifyOpenCodeHooks(homeDir = os18.homedir()) {
30021
- const configPath = path43.join(homeDir, ".config", "opencode", "opencode.json");
30022
- const pluginPath = path43.join(homeDir, ".config", "opencode", "plugins", "exe-os.mjs");
30023
- if (!existsSync29(configPath)) return false;
30185
+ function verifyOpenCodeHooks(homeDir = os19.homedir()) {
30186
+ const configPath = path44.join(homeDir, ".config", "opencode", "opencode.json");
30187
+ const pluginPath = path44.join(homeDir, ".config", "opencode", "plugins", "exe-os.mjs");
30188
+ if (!existsSync30(configPath)) return false;
30024
30189
  try {
30025
30190
  const config = JSON.parse(readFileSync26(configPath, "utf-8"));
30026
30191
  if (!config.mcp?.["exe-os"]?.enabled) return false;
30027
30192
  } catch {
30028
30193
  return false;
30029
30194
  }
30030
- if (!existsSync29(pluginPath)) return false;
30195
+ if (!existsSync30(pluginPath)) return false;
30031
30196
  return true;
30032
30197
  }
30033
30198
  async function runOpenCodeInstaller(homeDir) {
@@ -30056,25 +30221,26 @@ var installer_exports3 = {};
30056
30221
  __export(installer_exports3, {
30057
30222
  installCodexStatusLine: () => installCodexStatusLine,
30058
30223
  mergeCodexHooks: () => mergeCodexHooks,
30224
+ registerCodexMcpServer: () => registerCodexMcpServer,
30059
30225
  runCodexInstaller: () => runCodexInstaller,
30060
30226
  verifyCodexHooks: () => verifyCodexHooks
30061
30227
  });
30062
- import { readFile as readFile7, writeFile as writeFile8, mkdir as mkdir8 } from "fs/promises";
30063
- import { existsSync as existsSync30 } from "fs";
30064
- import path44 from "path";
30065
- import os19 from "os";
30066
- async function mergeCodexHooks(packageRoot, homeDir = os19.homedir()) {
30067
- const codexDir = path44.join(homeDir, ".codex");
30068
- const hooksPath = path44.join(codexDir, "hooks.json");
30069
- const logsDir = path44.join(homeDir, ".exe-os", "logs");
30070
- const hookLogPath = path44.join(logsDir, "hooks.log");
30228
+ import { readFile as readFile8, writeFile as writeFile9, mkdir as mkdir9 } from "fs/promises";
30229
+ import { existsSync as existsSync31 } from "fs";
30230
+ import path45 from "path";
30231
+ import os20 from "os";
30232
+ async function mergeCodexHooks(packageRoot, homeDir = os20.homedir()) {
30233
+ const codexDir = path45.join(homeDir, ".codex");
30234
+ const hooksPath = path45.join(codexDir, "hooks.json");
30235
+ const logsDir = path45.join(homeDir, ".exe-os", "logs");
30236
+ const hookLogPath = path45.join(logsDir, "hooks.log");
30071
30237
  const logSuffix = ` 2>> "${hookLogPath}"`;
30072
- await mkdir8(codexDir, { recursive: true });
30073
- await mkdir8(logsDir, { recursive: true });
30238
+ await mkdir9(codexDir, { recursive: true });
30239
+ await mkdir9(logsDir, { recursive: true });
30074
30240
  let hooksJson = {};
30075
- if (existsSync30(hooksPath)) {
30241
+ if (existsSync31(hooksPath)) {
30076
30242
  try {
30077
- hooksJson = JSON.parse(await readFile7(hooksPath, "utf-8"));
30243
+ hooksJson = JSON.parse(await readFile8(hooksPath, "utf-8"));
30078
30244
  } catch {
30079
30245
  hooksJson = {};
30080
30246
  }
@@ -30089,7 +30255,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os19.homedir()) {
30089
30255
  hooks: [
30090
30256
  {
30091
30257
  type: "command",
30092
- command: `node "${path44.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
30258
+ command: `node "${path45.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
30093
30259
  timeout: 30,
30094
30260
  statusMessage: "exe-os: loading memory brief"
30095
30261
  }
@@ -30104,11 +30270,11 @@ async function mergeCodexHooks(packageRoot, homeDir = os19.homedir()) {
30104
30270
  hooks: [
30105
30271
  {
30106
30272
  type: "command",
30107
- command: `node "${path44.join(packageRoot, "dist", "hooks", "ingest.js")}"${logSuffix}`
30273
+ command: `node "${path45.join(packageRoot, "dist", "hooks", "ingest.js")}"${logSuffix}`
30108
30274
  },
30109
30275
  {
30110
30276
  type: "command",
30111
- command: `node "${path44.join(packageRoot, "dist", "hooks", "error-recall.js")}"${logSuffix}`
30277
+ command: `node "${path45.join(packageRoot, "dist", "hooks", "error-recall.js")}"${logSuffix}`
30112
30278
  }
30113
30279
  ]
30114
30280
  },
@@ -30120,11 +30286,11 @@ async function mergeCodexHooks(packageRoot, homeDir = os19.homedir()) {
30120
30286
  hooks: [
30121
30287
  {
30122
30288
  type: "command",
30123
- command: `node "${path44.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
30289
+ command: `node "${path45.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
30124
30290
  },
30125
30291
  {
30126
30292
  type: "command",
30127
- command: `node "${path44.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
30293
+ command: `node "${path45.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
30128
30294
  timeout: 5
30129
30295
  }
30130
30296
  ]
@@ -30137,7 +30303,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os19.homedir()) {
30137
30303
  hooks: [
30138
30304
  {
30139
30305
  type: "command",
30140
- command: `node "${path44.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
30306
+ command: `node "${path45.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
30141
30307
  }
30142
30308
  ]
30143
30309
  },
@@ -30150,7 +30316,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os19.homedir()) {
30150
30316
  hooks: [
30151
30317
  {
30152
30318
  type: "command",
30153
- command: `node "${path44.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
30319
+ command: `node "${path45.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
30154
30320
  }
30155
30321
  ]
30156
30322
  },
@@ -30178,12 +30344,12 @@ async function mergeCodexHooks(packageRoot, homeDir = os19.homedir()) {
30178
30344
  added++;
30179
30345
  }
30180
30346
  }
30181
- await writeFile8(hooksPath, JSON.stringify(hooksJson, null, 2) + "\n");
30347
+ await writeFile9(hooksPath, JSON.stringify(hooksJson, null, 2) + "\n");
30182
30348
  return { added, skipped };
30183
30349
  }
30184
- function verifyCodexHooks(homeDir = os19.homedir()) {
30185
- const hooksPath = path44.join(homeDir, ".codex", "hooks.json");
30186
- if (!existsSync30(hooksPath)) return false;
30350
+ function verifyCodexHooks(homeDir = os20.homedir()) {
30351
+ const hooksPath = path45.join(homeDir, ".codex", "hooks.json");
30352
+ if (!existsSync31(hooksPath)) return false;
30187
30353
  try {
30188
30354
  const hooksJson = JSON.parse(
30189
30355
  __require("fs").readFileSync(hooksPath, "utf-8")
@@ -30203,15 +30369,15 @@ function verifyCodexHooks(homeDir = os19.homedir()) {
30203
30369
  return false;
30204
30370
  }
30205
30371
  }
30206
- async function installCodexStatusLine(homeDir = os19.homedir()) {
30372
+ async function installCodexStatusLine(homeDir = os20.homedir()) {
30207
30373
  const prefs = loadPreferences(homeDir);
30208
30374
  if (prefs.codexStatusLine === false) return "opted-out";
30209
- const codexDir = path44.join(homeDir, ".codex");
30210
- const configPath = path44.join(codexDir, "config.toml");
30211
- await mkdir8(codexDir, { recursive: true });
30375
+ const codexDir = path45.join(homeDir, ".codex");
30376
+ const configPath = path45.join(codexDir, "config.toml");
30377
+ await mkdir9(codexDir, { recursive: true });
30212
30378
  let content = "";
30213
- if (existsSync30(configPath)) {
30214
- content = await readFile7(configPath, "utf-8");
30379
+ if (existsSync31(configPath)) {
30380
+ content = await readFile8(configPath, "utf-8");
30215
30381
  if (/\[tui\][\s\S]*?status_line\s*=/.test(content)) {
30216
30382
  return "already-configured";
30217
30383
  }
@@ -30224,14 +30390,55 @@ status_line = [${DEFAULT_CODEX_STATUS_LINE.map((s) => `"${s}"`).join(", ")}]`;
30224
30390
  const separator = content.length > 0 && !content.endsWith("\n") ? "\n\n" : content.length > 0 ? "\n" : "";
30225
30391
  content = content + separator + statusLineToml + "\n";
30226
30392
  }
30227
- await writeFile8(configPath, content);
30393
+ await writeFile9(configPath, content);
30228
30394
  return "installed";
30229
30395
  }
30396
+ async function registerCodexMcpServer(packageRoot, homeDir = os20.homedir()) {
30397
+ const codexDir = path45.join(homeDir, ".codex");
30398
+ const configPath = path45.join(codexDir, "config.toml");
30399
+ const serverJsPath = path45.join(packageRoot, "dist", "mcp", "server.js");
30400
+ await mkdir9(codexDir, { recursive: true });
30401
+ let content = "";
30402
+ if (existsSync31(configPath)) {
30403
+ content = await readFile8(configPath, "utf-8");
30404
+ }
30405
+ const sectionHeader = "[mcp_servers.exe-os]";
30406
+ const headerIndex = content.indexOf(sectionHeader);
30407
+ if (headerIndex !== -1) {
30408
+ const afterHeader = content.slice(headerIndex + sectionHeader.length);
30409
+ const nextSectionMatch = afterHeader.match(/\n\[(?!mcp_servers\.exe-os)/);
30410
+ const sectionEnd = nextSectionMatch ? headerIndex + sectionHeader.length + nextSectionMatch.index : content.length;
30411
+ const sectionContent = content.slice(headerIndex, sectionEnd);
30412
+ if (sectionContent.includes(serverJsPath)) {
30413
+ return "already-registered";
30414
+ }
30415
+ const newSection2 = `${sectionHeader}
30416
+ command = "node"
30417
+ args = ["${serverJsPath}"]
30418
+ `;
30419
+ content = content.slice(0, headerIndex) + newSection2 + content.slice(sectionEnd);
30420
+ await writeFile9(configPath, content);
30421
+ return "updated";
30422
+ }
30423
+ const newSection = `[mcp_servers.exe-os]
30424
+ command = "node"
30425
+ args = ["${serverJsPath}"]
30426
+ `;
30427
+ const separator = content.length > 0 && !content.endsWith("\n") ? "\n\n" : content.length > 0 ? "\n" : "";
30428
+ content = content + separator + newSection;
30429
+ await writeFile9(configPath, content);
30430
+ return "registered";
30431
+ }
30230
30432
  async function runCodexInstaller(homeDir) {
30231
30433
  const packageRoot = resolvePackageRoot();
30232
30434
  const result = await mergeCodexHooks(packageRoot, homeDir);
30233
30435
  process.stderr.write(
30234
30436
  `[exe-os] Codex hooks: ${result.added} added, ${result.skipped} unchanged
30437
+ `
30438
+ );
30439
+ const mcpResult = await registerCodexMcpServer(packageRoot, homeDir);
30440
+ process.stderr.write(
30441
+ `[exe-os] Codex MCP server: ${mcpResult}
30235
30442
  `
30236
30443
  );
30237
30444
  const statusResult = await installCodexStatusLine(homeDir);
@@ -30258,13 +30465,13 @@ var init_installer3 = __esm({
30258
30465
  });
30259
30466
 
30260
30467
  // src/bin/cli.ts
30261
- import { existsSync as existsSync31, readFileSync as readFileSync27, writeFileSync as writeFileSync20, readdirSync as readdirSync9, rmSync } from "fs";
30262
- import path45 from "path";
30263
- import os20 from "os";
30468
+ import { existsSync as existsSync32, readFileSync as readFileSync27, writeFileSync as writeFileSync20, readdirSync as readdirSync9, rmSync } from "fs";
30469
+ import path46 from "path";
30470
+ import os21 from "os";
30264
30471
  var args = process.argv.slice(2);
30265
30472
  if (args.includes("--version") || args.includes("-v")) {
30266
30473
  try {
30267
- const pkgPath = path45.join(path45.dirname(new URL(import.meta.url).pathname), "..", "..", "package.json");
30474
+ const pkgPath = path46.join(path46.dirname(new URL(import.meta.url).pathname), "..", "..", "package.json");
30268
30475
  const pkg = JSON.parse(readFileSync27(pkgPath, "utf8"));
30269
30476
  console.log(pkg.version);
30270
30477
  } catch {
@@ -30429,9 +30636,9 @@ ID: ${result.id}`);
30429
30636
  });
30430
30637
  await init_App2().then(() => App_exports);
30431
30638
  } else {
30432
- const claudeDir = path45.join(os20.homedir(), ".claude");
30433
- const settingsPath = path45.join(claudeDir, "settings.json");
30434
- const hasClaudeCode = existsSync31(settingsPath) && (() => {
30639
+ const claudeDir = path46.join(os21.homedir(), ".claude");
30640
+ const settingsPath = path46.join(claudeDir, "settings.json");
30641
+ const hasClaudeCode = existsSync32(settingsPath) && (() => {
30435
30642
  try {
30436
30643
  const raw = readFileSync27(settingsPath, "utf8");
30437
30644
  return raw.includes("exe-os") || raw.includes("exe-mem");
@@ -30443,8 +30650,8 @@ ID: ${result.id}`);
30443
30650
  const { DEFAULT_COORDINATOR_TEMPLATE_NAME: DEFAULT_COORDINATOR_TEMPLATE_NAME2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
30444
30651
  let cooName = DEFAULT_COORDINATOR_TEMPLATE_NAME2;
30445
30652
  try {
30446
- const rosterPath = path45.join(os20.homedir(), ".exe-os", "exe-employees.json");
30447
- if (existsSync31(rosterPath)) {
30653
+ const rosterPath = path46.join(os21.homedir(), ".exe-os", "exe-employees.json");
30654
+ if (existsSync32(rosterPath)) {
30448
30655
  const roster = JSON.parse(readFileSync27(rosterPath, "utf8"));
30449
30656
  const coo = roster.find((e) => e.role === "COO");
30450
30657
  if (coo) cooName = coo.name;
@@ -30509,11 +30716,11 @@ async function runCodexInstall() {
30509
30716
  }
30510
30717
  }
30511
30718
  async function runClaudeCheck() {
30512
- const claudeDir = path45.join(os20.homedir(), ".claude");
30513
- const settingsPath = path45.join(claudeDir, "settings.json");
30514
- const claudeJsonPath = path45.join(os20.homedir(), ".claude.json");
30719
+ const claudeDir = path46.join(os21.homedir(), ".claude");
30720
+ const settingsPath = path46.join(claudeDir, "settings.json");
30721
+ const claudeJsonPath = path46.join(os21.homedir(), ".claude.json");
30515
30722
  let ok = true;
30516
- if (existsSync31(settingsPath)) {
30723
+ if (existsSync32(settingsPath)) {
30517
30724
  let settings;
30518
30725
  try {
30519
30726
  settings = JSON.parse(readFileSync27(settingsPath, "utf8"));
@@ -30542,7 +30749,7 @@ async function runClaudeCheck() {
30542
30749
  console.log("\x1B[31m\u2717\x1B[0m settings.json not found");
30543
30750
  ok = false;
30544
30751
  }
30545
- if (existsSync31(claudeJsonPath)) {
30752
+ if (existsSync32(claudeJsonPath)) {
30546
30753
  let claudeJson;
30547
30754
  try {
30548
30755
  claudeJson = JSON.parse(readFileSync27(claudeJsonPath, "utf8"));
@@ -30564,8 +30771,8 @@ async function runClaudeCheck() {
30564
30771
  console.log("\x1B[31m\u2717\x1B[0m claude.json not found");
30565
30772
  ok = false;
30566
30773
  }
30567
- const skillsDir = path45.join(claudeDir, "skills");
30568
- if (existsSync31(skillsDir)) {
30774
+ const skillsDir = path46.join(claudeDir, "skills");
30775
+ if (existsSync32(skillsDir)) {
30569
30776
  console.log("\x1B[32m\u2713\x1B[0m Slash skills directory exists");
30570
30777
  } else {
30571
30778
  console.log("\x1B[31m\u2717\x1B[0m Slash skills directory missing");
@@ -30581,15 +30788,15 @@ async function runClaudeCheck() {
30581
30788
  async function runClaudeUninstall(flags = []) {
30582
30789
  const dryRun = flags.includes("--dry-run");
30583
30790
  const purge = flags.includes("--purge");
30584
- const homeDir = os20.homedir();
30585
- const claudeDir = path45.join(homeDir, ".claude");
30586
- const settingsPath = path45.join(claudeDir, "settings.json");
30587
- const claudeJsonPath = path45.join(homeDir, ".claude.json");
30588
- const exeOsDir = path45.join(homeDir, ".exe-os");
30791
+ const homeDir = os21.homedir();
30792
+ const claudeDir = path46.join(homeDir, ".claude");
30793
+ const settingsPath = path46.join(claudeDir, "settings.json");
30794
+ const claudeJsonPath = path46.join(homeDir, ".claude.json");
30795
+ const exeOsDir = path46.join(homeDir, ".exe-os");
30589
30796
  let removed = 0;
30590
30797
  const log = (msg) => console.log(dryRun ? `[dry-run] ${msg}` : msg);
30591
30798
  let settings = {};
30592
- if (existsSync31(settingsPath)) {
30799
+ if (existsSync32(settingsPath)) {
30593
30800
  try {
30594
30801
  settings = JSON.parse(readFileSync27(settingsPath, "utf8"));
30595
30802
  } catch {
@@ -30636,7 +30843,7 @@ async function runClaudeUninstall(flags = []) {
30636
30843
  removed++;
30637
30844
  }
30638
30845
  }
30639
- if (existsSync31(claudeJsonPath)) {
30846
+ if (existsSync32(claudeJsonPath)) {
30640
30847
  const raw = readFileSync27(claudeJsonPath, "utf8");
30641
30848
  if (raw.length > 1e6) {
30642
30849
  console.error("claude.json exceeds 1 MB \u2014 skipping parse.");
@@ -30666,14 +30873,14 @@ async function runClaudeUninstall(flags = []) {
30666
30873
  }
30667
30874
  }
30668
30875
  }
30669
- const skillsDir = path45.join(claudeDir, "skills");
30670
- if (existsSync31(skillsDir)) {
30876
+ const skillsDir = path46.join(claudeDir, "skills");
30877
+ if (existsSync32(skillsDir)) {
30671
30878
  let skillCount = 0;
30672
30879
  try {
30673
30880
  const entries = readdirSync9(skillsDir);
30674
30881
  for (const entry of entries) {
30675
30882
  if (entry.startsWith("exe")) {
30676
- const fullPath = path45.join(skillsDir, entry);
30883
+ const fullPath = path46.join(skillsDir, entry);
30677
30884
  if (!dryRun) rmSync(fullPath, { recursive: true, force: true });
30678
30885
  skillCount++;
30679
30886
  }
@@ -30685,8 +30892,8 @@ async function runClaudeUninstall(flags = []) {
30685
30892
  removed++;
30686
30893
  }
30687
30894
  }
30688
- const claudeMdPath = path45.join(claudeDir, "CLAUDE.md");
30689
- if (existsSync31(claudeMdPath)) {
30895
+ const claudeMdPath = path46.join(claudeDir, "CLAUDE.md");
30896
+ if (existsSync32(claudeMdPath)) {
30690
30897
  const content = readFileSync27(claudeMdPath, "utf8");
30691
30898
  const startMarker = "<!-- exe-os:orchestration-start -->";
30692
30899
  const endMarker = "<!-- exe-os:orchestration-end -->";
@@ -30699,14 +30906,14 @@ async function runClaudeUninstall(flags = []) {
30699
30906
  removed++;
30700
30907
  }
30701
30908
  }
30702
- const agentsDir = path45.join(claudeDir, "agents");
30703
- if (existsSync31(agentsDir)) {
30909
+ const agentsDir = path46.join(claudeDir, "agents");
30910
+ if (existsSync32(agentsDir)) {
30704
30911
  let agentCount = 0;
30705
30912
  try {
30706
30913
  const entries = readdirSync9(agentsDir).filter((f) => f.endsWith(".md"));
30707
30914
  let knownNames = /* @__PURE__ */ new Set();
30708
- const rosterPath = path45.join(exeOsDir, "exe-employees.json");
30709
- if (existsSync31(rosterPath)) {
30915
+ const rosterPath = path46.join(exeOsDir, "exe-employees.json");
30916
+ if (existsSync32(rosterPath)) {
30710
30917
  try {
30711
30918
  const roster = JSON.parse(readFileSync27(rosterPath, "utf8"));
30712
30919
  knownNames = new Set(roster.map((e) => e.name));
@@ -30716,7 +30923,7 @@ async function runClaudeUninstall(flags = []) {
30716
30923
  for (const entry of entries) {
30717
30924
  const name = entry.replace(/\.md$/, "");
30718
30925
  if (knownNames.has(name)) {
30719
- if (!dryRun) rmSync(path45.join(agentsDir, entry), { force: true });
30926
+ if (!dryRun) rmSync(path46.join(agentsDir, entry), { force: true });
30720
30927
  agentCount++;
30721
30928
  }
30722
30929
  }
@@ -30727,14 +30934,14 @@ async function runClaudeUninstall(flags = []) {
30727
30934
  removed++;
30728
30935
  }
30729
30936
  }
30730
- const projectsDir = path45.join(claudeDir, "projects");
30731
- if (existsSync31(projectsDir)) {
30937
+ const projectsDir = path46.join(claudeDir, "projects");
30938
+ if (existsSync32(projectsDir)) {
30732
30939
  let projectCount = 0;
30733
30940
  try {
30734
30941
  const projects = readdirSync9(projectsDir);
30735
30942
  for (const proj of projects) {
30736
- const projSettings = path45.join(projectsDir, proj, "settings.json");
30737
- if (!existsSync31(projSettings)) continue;
30943
+ const projSettings = path46.join(projectsDir, proj, "settings.json");
30944
+ if (!existsSync32(projSettings)) continue;
30738
30945
  try {
30739
30946
  const pSettings = JSON.parse(readFileSync27(projSettings, "utf8"));
30740
30947
  let changed = false;
@@ -30770,18 +30977,18 @@ async function runClaudeUninstall(flags = []) {
30770
30977
  };
30771
30978
  const exeBinPath = findExeBin3();
30772
30979
  if (!exeBinPath) throw new Error("exe-os not found in PATH");
30773
- const binDir = path45.dirname(exeBinPath);
30980
+ const binDir = path46.dirname(exeBinPath);
30774
30981
  let symlinkCount = 0;
30775
- const rosterPath = path45.join(exeOsDir, "exe-employees.json");
30776
- if (existsSync31(rosterPath)) {
30982
+ const rosterPath = path46.join(exeOsDir, "exe-employees.json");
30983
+ if (existsSync32(rosterPath)) {
30777
30984
  const roster = JSON.parse(readFileSync27(rosterPath, "utf8"));
30778
30985
  const { DEFAULT_COORDINATOR_TEMPLATE_NAME: DEFAULT_COORDINATOR_TEMPLATE_NAME2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
30779
30986
  const coordinatorName = roster.find((e) => e.role?.toLowerCase() === "coo")?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME2;
30780
30987
  for (const emp of roster) {
30781
30988
  if (emp.name === coordinatorName) continue;
30782
30989
  for (const suffix of ["", "-opencode"]) {
30783
- const linkPath = path45.join(binDir, `${emp.name}${suffix}`);
30784
- if (existsSync31(linkPath)) {
30990
+ const linkPath = path46.join(binDir, `${emp.name}${suffix}`);
30991
+ if (existsSync32(linkPath)) {
30785
30992
  if (!dryRun) rmSync(linkPath, { force: true });
30786
30993
  symlinkCount++;
30787
30994
  }
@@ -30794,7 +31001,7 @@ async function runClaudeUninstall(flags = []) {
30794
31001
  }
30795
31002
  } catch {
30796
31003
  }
30797
- if (purge && existsSync31(exeOsDir)) {
31004
+ if (purge && existsSync32(exeOsDir)) {
30798
31005
  if (!dryRun) {
30799
31006
  process.stdout.write("\x1B[33m\u26A0 This will delete all memories, identities, and agent data.\x1B[0m\n");
30800
31007
  process.stdout.write(" Removing ~/.exe-os...\n");
@@ -30819,7 +31026,7 @@ async function checkForUpdateOnBoot() {
30819
31026
  const config = await loadConfig2();
30820
31027
  if (!config.autoUpdate.checkOnBoot) return;
30821
31028
  const { checkForUpdate: checkForUpdate2 } = await Promise.resolve().then(() => (init_update(), update_exports));
30822
- const packageRoot = path45.resolve(
31029
+ const packageRoot = path46.resolve(
30823
31030
  new URL("../..", import.meta.url).pathname
30824
31031
  );
30825
31032
  const result = checkForUpdate2(packageRoot);
@@ -30879,7 +31086,7 @@ async function runActivate(key) {
30879
31086
  const idTemplate = getIdentityTemplate(identityKey);
30880
31087
  if (idTemplate) {
30881
31088
  const idPath = identityPath2(name);
30882
- const dir = path45.dirname(idPath);
31089
+ const dir = path46.dirname(idPath);
30883
31090
  if (!fs8.existsSync(dir)) fs8.mkdirSync(dir, { recursive: true });
30884
31091
  fs8.writeFileSync(idPath, idTemplate.replace(/^agent_id: \w+/m, `agent_id: ${name}`), "utf-8");
30885
31092
  }