@askexenow/exe-os 0.9.30 → 0.9.32

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 (64) hide show
  1. package/dist/bin/backfill-conversations.js +135 -7
  2. package/dist/bin/backfill-responses.js +135 -7
  3. package/dist/bin/backfill-vectors.js +135 -7
  4. package/dist/bin/cleanup-stale-review-tasks.js +139 -11
  5. package/dist/bin/cli.js +812 -486
  6. package/dist/bin/exe-assign.js +135 -7
  7. package/dist/bin/exe-boot.js +422 -113
  8. package/dist/bin/exe-cloud.js +160 -9
  9. package/dist/bin/exe-dispatch.js +136 -8
  10. package/dist/bin/exe-doctor.js +255 -13
  11. package/dist/bin/exe-export-behaviors.js +136 -8
  12. package/dist/bin/exe-forget.js +136 -8
  13. package/dist/bin/exe-gateway.js +171 -24
  14. package/dist/bin/exe-heartbeat.js +141 -13
  15. package/dist/bin/exe-kill.js +140 -12
  16. package/dist/bin/exe-launch-agent.js +143 -15
  17. package/dist/bin/exe-link.js +357 -48
  18. package/dist/bin/exe-pending-messages.js +136 -8
  19. package/dist/bin/exe-pending-notifications.js +136 -8
  20. package/dist/bin/exe-pending-reviews.js +138 -10
  21. package/dist/bin/exe-review.js +136 -8
  22. package/dist/bin/exe-search.js +155 -20
  23. package/dist/bin/exe-session-cleanup.js +166 -38
  24. package/dist/bin/exe-start-codex.js +142 -14
  25. package/dist/bin/exe-start-opencode.js +140 -12
  26. package/dist/bin/exe-status.js +148 -20
  27. package/dist/bin/exe-team.js +136 -8
  28. package/dist/bin/git-sweep.js +138 -10
  29. package/dist/bin/graph-backfill.js +135 -7
  30. package/dist/bin/graph-export.js +136 -8
  31. package/dist/bin/intercom-check.js +153 -25
  32. package/dist/bin/scan-tasks.js +138 -10
  33. package/dist/bin/setup.js +447 -121
  34. package/dist/bin/shard-migrate.js +135 -7
  35. package/dist/gateway/index.js +151 -23
  36. package/dist/hooks/bug-report-worker.js +151 -23
  37. package/dist/hooks/codex-stop-task-finalizer.js +145 -17
  38. package/dist/hooks/commit-complete.js +138 -10
  39. package/dist/hooks/error-recall.js +159 -24
  40. package/dist/hooks/ingest.js +142 -14
  41. package/dist/hooks/instructions-loaded.js +136 -8
  42. package/dist/hooks/notification.js +136 -8
  43. package/dist/hooks/post-compact.js +136 -8
  44. package/dist/hooks/post-tool-combined.js +159 -24
  45. package/dist/hooks/pre-compact.js +136 -8
  46. package/dist/hooks/pre-tool-use.js +144 -16
  47. package/dist/hooks/prompt-submit.js +195 -55
  48. package/dist/hooks/session-end.js +141 -13
  49. package/dist/hooks/session-start.js +165 -30
  50. package/dist/hooks/stop.js +136 -8
  51. package/dist/hooks/subagent-stop.js +136 -8
  52. package/dist/hooks/summary-worker.js +374 -65
  53. package/dist/index.js +136 -8
  54. package/dist/lib/cloud-sync.js +355 -46
  55. package/dist/lib/consolidation.js +1 -0
  56. package/dist/lib/exe-daemon.js +469 -127
  57. package/dist/lib/hybrid-search.js +155 -20
  58. package/dist/lib/keychain.js +191 -7
  59. package/dist/lib/schedules.js +138 -10
  60. package/dist/lib/store.js +135 -7
  61. package/dist/mcp/server.js +706 -213
  62. package/dist/runtime/index.js +136 -8
  63. package/dist/tui/App.js +208 -31
  64. package/package.json +1 -1
package/dist/bin/cli.js CHANGED
@@ -1638,6 +1638,7 @@ __export(keychain_exports, {
1638
1638
  });
1639
1639
  import { readFile as readFile4, writeFile as writeFile4, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
1640
1640
  import { existsSync as existsSync8 } from "fs";
1641
+ import { execSync as execSync3 } from "child_process";
1641
1642
  import path7 from "path";
1642
1643
  import os6 from "os";
1643
1644
  function getKeyDir() {
@@ -1646,6 +1647,83 @@ function getKeyDir() {
1646
1647
  function getKeyPath() {
1647
1648
  return path7.join(getKeyDir(), "master.key");
1648
1649
  }
1650
+ function macKeychainGet() {
1651
+ if (process.platform !== "darwin") return null;
1652
+ try {
1653
+ return execSync3(
1654
+ `security find-generic-password -s "${SERVICE}" -a "${ACCOUNT}" -w 2>/dev/null`,
1655
+ { encoding: "utf-8", timeout: 5e3 }
1656
+ ).trim();
1657
+ } catch {
1658
+ return null;
1659
+ }
1660
+ }
1661
+ function macKeychainSet(value) {
1662
+ if (process.platform !== "darwin") return false;
1663
+ try {
1664
+ try {
1665
+ execSync3(
1666
+ `security delete-generic-password -s "${SERVICE}" -a "${ACCOUNT}" 2>/dev/null`,
1667
+ { timeout: 5e3 }
1668
+ );
1669
+ } catch {
1670
+ }
1671
+ execSync3(
1672
+ `security add-generic-password -s "${SERVICE}" -a "${ACCOUNT}" -w "${value}"`,
1673
+ { timeout: 5e3 }
1674
+ );
1675
+ return true;
1676
+ } catch {
1677
+ return false;
1678
+ }
1679
+ }
1680
+ function macKeychainDelete() {
1681
+ if (process.platform !== "darwin") return false;
1682
+ try {
1683
+ execSync3(
1684
+ `security delete-generic-password -s "${SERVICE}" -a "${ACCOUNT}" 2>/dev/null`,
1685
+ { timeout: 5e3 }
1686
+ );
1687
+ return true;
1688
+ } catch {
1689
+ return false;
1690
+ }
1691
+ }
1692
+ function linuxSecretGet() {
1693
+ if (process.platform !== "linux") return null;
1694
+ try {
1695
+ return execSync3(
1696
+ `secret-tool lookup service "${SERVICE}" account "${ACCOUNT}" 2>/dev/null`,
1697
+ { encoding: "utf-8", timeout: 5e3 }
1698
+ ).trim();
1699
+ } catch {
1700
+ return null;
1701
+ }
1702
+ }
1703
+ function linuxSecretSet(value) {
1704
+ if (process.platform !== "linux") return false;
1705
+ try {
1706
+ execSync3(
1707
+ `echo -n "${value}" | secret-tool store --label="exe-os master key" service "${SERVICE}" account "${ACCOUNT}"`,
1708
+ { timeout: 5e3 }
1709
+ );
1710
+ return true;
1711
+ } catch {
1712
+ return false;
1713
+ }
1714
+ }
1715
+ function linuxSecretDelete() {
1716
+ if (process.platform !== "linux") return false;
1717
+ try {
1718
+ execSync3(
1719
+ `secret-tool clear service "${SERVICE}" account "${ACCOUNT}" 2>/dev/null`,
1720
+ { timeout: 5e3 }
1721
+ );
1722
+ return true;
1723
+ } catch {
1724
+ return false;
1725
+ }
1726
+ }
1649
1727
  async function tryKeytar() {
1650
1728
  try {
1651
1729
  return await import("keytar");
@@ -1653,13 +1731,72 @@ async function tryKeytar() {
1653
1731
  return null;
1654
1732
  }
1655
1733
  }
1734
+ function deriveMachineKey() {
1735
+ try {
1736
+ const crypto13 = __require("crypto");
1737
+ const material = [
1738
+ os6.hostname(),
1739
+ os6.userInfo().username,
1740
+ os6.arch(),
1741
+ os6.platform(),
1742
+ // Machine ID on Linux (stable across reboots)
1743
+ process.platform === "linux" ? readMachineId() : ""
1744
+ ].join("|");
1745
+ return crypto13.createHash("sha256").update(material).digest();
1746
+ } catch {
1747
+ return null;
1748
+ }
1749
+ }
1750
+ function readMachineId() {
1751
+ try {
1752
+ const { readFileSync: readFileSync28 } = __require("fs");
1753
+ return readFileSync28("/etc/machine-id", "utf-8").trim();
1754
+ } catch {
1755
+ return "";
1756
+ }
1757
+ }
1758
+ function encryptWithMachineKey(plaintext, machineKey) {
1759
+ const crypto13 = __require("crypto");
1760
+ const iv = crypto13.randomBytes(12);
1761
+ const cipher = crypto13.createCipheriv("aes-256-gcm", machineKey, iv);
1762
+ let encrypted = cipher.update(plaintext, "utf-8", "base64");
1763
+ encrypted += cipher.final("base64");
1764
+ const authTag = cipher.getAuthTag().toString("base64");
1765
+ return `${ENCRYPTED_PREFIX}${iv.toString("base64")}:${authTag}:${encrypted}`;
1766
+ }
1767
+ function decryptWithMachineKey(encrypted, machineKey) {
1768
+ if (!encrypted.startsWith(ENCRYPTED_PREFIX)) return null;
1769
+ try {
1770
+ const crypto13 = __require("crypto");
1771
+ const parts = encrypted.slice(ENCRYPTED_PREFIX.length).split(":");
1772
+ if (parts.length !== 3) return null;
1773
+ const [ivB64, tagB64, cipherB64] = parts;
1774
+ const iv = Buffer.from(ivB64, "base64");
1775
+ const authTag = Buffer.from(tagB64, "base64");
1776
+ const decipher = crypto13.createDecipheriv("aes-256-gcm", machineKey, iv);
1777
+ decipher.setAuthTag(authTag);
1778
+ let decrypted = decipher.update(cipherB64, "base64", "utf-8");
1779
+ decrypted += decipher.final("utf-8");
1780
+ return decrypted;
1781
+ } catch {
1782
+ return null;
1783
+ }
1784
+ }
1656
1785
  async function getMasterKey() {
1786
+ const nativeValue = macKeychainGet() ?? linuxSecretGet();
1787
+ if (nativeValue) {
1788
+ return Buffer.from(nativeValue, "base64");
1789
+ }
1657
1790
  const keytar = await tryKeytar();
1658
1791
  if (keytar) {
1659
1792
  try {
1660
- const stored = await keytar.getPassword(SERVICE, ACCOUNT);
1661
- if (stored) {
1662
- return Buffer.from(stored, "base64");
1793
+ const keytarValue = await keytar.getPassword(SERVICE, ACCOUNT);
1794
+ if (keytarValue) {
1795
+ const migrated = macKeychainSet(keytarValue) || linuxSecretSet(keytarValue);
1796
+ if (migrated) {
1797
+ process.stderr.write("[keychain] Migrated key from keytar to native keychain.\n");
1798
+ }
1799
+ return Buffer.from(keytarValue, "base64");
1663
1800
  }
1664
1801
  } catch {
1665
1802
  }
@@ -1673,8 +1810,31 @@ async function getMasterKey() {
1673
1810
  return null;
1674
1811
  }
1675
1812
  try {
1676
- const content = await readFile4(keyPath, "utf-8");
1677
- return Buffer.from(content.trim(), "base64");
1813
+ const content = (await readFile4(keyPath, "utf-8")).trim();
1814
+ let b64Value;
1815
+ if (content.startsWith(ENCRYPTED_PREFIX)) {
1816
+ const machineKey = deriveMachineKey();
1817
+ if (!machineKey) {
1818
+ process.stderr.write("[keychain] Cannot derive machine key to decrypt stored key.\n");
1819
+ return null;
1820
+ }
1821
+ const decrypted = decryptWithMachineKey(content, machineKey);
1822
+ if (!decrypted) {
1823
+ process.stderr.write(
1824
+ "[keychain] Key decryption failed \u2014 machine may have changed.\n Use your 24-word recovery phrase: exe-os link import\n"
1825
+ );
1826
+ return null;
1827
+ }
1828
+ b64Value = decrypted;
1829
+ } else {
1830
+ b64Value = content;
1831
+ }
1832
+ const key = Buffer.from(b64Value, "base64");
1833
+ const migrated = macKeychainSet(b64Value) || linuxSecretSet(b64Value);
1834
+ if (migrated) {
1835
+ process.stderr.write("[keychain] Migrated key from file to native keychain.\n");
1836
+ }
1837
+ return key;
1678
1838
  } catch (err) {
1679
1839
  process.stderr.write(
1680
1840
  `[keychain] Key read failed at ${keyPath}: ${err instanceof Error ? err.message : String(err)}
@@ -1685,6 +1845,9 @@ async function getMasterKey() {
1685
1845
  }
1686
1846
  async function setMasterKey(key) {
1687
1847
  const b64 = key.toString("base64");
1848
+ if (macKeychainSet(b64) || linuxSecretSet(b64)) {
1849
+ return;
1850
+ }
1688
1851
  const keytar = await tryKeytar();
1689
1852
  if (keytar) {
1690
1853
  try {
@@ -1696,10 +1859,23 @@ async function setMasterKey(key) {
1696
1859
  const dir = getKeyDir();
1697
1860
  await mkdir4(dir, { recursive: true });
1698
1861
  const keyPath = getKeyPath();
1699
- await writeFile4(keyPath, b64 + "\n", "utf-8");
1700
- await chmod2(keyPath, 384);
1862
+ const machineKey = deriveMachineKey();
1863
+ if (machineKey) {
1864
+ const encrypted = encryptWithMachineKey(b64, machineKey);
1865
+ await writeFile4(keyPath, encrypted + "\n", "utf-8");
1866
+ await chmod2(keyPath, 384);
1867
+ process.stderr.write("[keychain] Key stored encrypted (machine-bound).\n");
1868
+ } else {
1869
+ await writeFile4(keyPath, b64 + "\n", "utf-8");
1870
+ await chmod2(keyPath, 384);
1871
+ process.stderr.write(
1872
+ "[keychain] WARNING: Key stored in plaintext file \u2014 no OS keychain available.\n"
1873
+ );
1874
+ }
1701
1875
  }
1702
1876
  async function deleteMasterKey() {
1877
+ macKeychainDelete();
1878
+ linuxSecretDelete();
1703
1879
  const keytar = await tryKeytar();
1704
1880
  if (keytar) {
1705
1881
  try {
@@ -1741,12 +1917,13 @@ async function importMnemonic(mnemonic) {
1741
1917
  const entropy = mnemonicToEntropy(trimmed);
1742
1918
  return Buffer.from(entropy, "hex");
1743
1919
  }
1744
- var SERVICE, ACCOUNT;
1920
+ var SERVICE, ACCOUNT, ENCRYPTED_PREFIX;
1745
1921
  var init_keychain = __esm({
1746
1922
  "src/lib/keychain.ts"() {
1747
1923
  "use strict";
1748
1924
  SERVICE = "exe-mem";
1749
1925
  ACCOUNT = "master-key";
1926
+ ENCRYPTED_PREFIX = "enc:";
1750
1927
  }
1751
1928
  });
1752
1929
 
@@ -2550,8 +2727,8 @@ function findPackageRoot() {
2550
2727
  function getAvailableMemoryGB() {
2551
2728
  if (process.platform === "darwin") {
2552
2729
  try {
2553
- const { execSync: execSync15 } = __require("child_process");
2554
- const vmstat = execSync15("vm_stat", { encoding: "utf8" });
2730
+ const { execSync: execSync16 } = __require("child_process");
2731
+ const vmstat = execSync16("vm_stat", { encoding: "utf8" });
2555
2732
  const pageSize = 16384;
2556
2733
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
2557
2734
  const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
@@ -4572,8 +4749,8 @@ async function validateLicense(apiKey, deviceId) {
4572
4749
  }
4573
4750
  function getCacheAgeMs() {
4574
4751
  try {
4575
- const { statSync: statSync2 } = __require("fs");
4576
- const s = statSync2(CACHE_PATH);
4752
+ const { statSync: statSync3 } = __require("fs");
4753
+ const s = statSync3(CACHE_PATH);
4577
4754
  return Date.now() - s.mtimeMs;
4578
4755
  } catch {
4579
4756
  return Infinity;
@@ -5003,6 +5180,109 @@ var init_crdt_sync = __esm({
5003
5180
  }
5004
5181
  });
5005
5182
 
5183
+ // src/lib/db-backup.ts
5184
+ var db_backup_exports = {};
5185
+ __export(db_backup_exports, {
5186
+ createBackup: () => createBackup,
5187
+ findActiveDb: () => findActiveDb,
5188
+ getBackupDir: () => getBackupDir,
5189
+ getLatestBackup: () => getLatestBackup,
5190
+ hasBackupToday: () => hasBackupToday,
5191
+ listBackups: () => listBackups,
5192
+ rotateBackups: () => rotateBackups
5193
+ });
5194
+ import { copyFileSync as copyFileSync2, existsSync as existsSync13, mkdirSync as mkdirSync6, readdirSync, unlinkSync as unlinkSync4, statSync as statSync2 } from "fs";
5195
+ import path13 from "path";
5196
+ function findActiveDb() {
5197
+ for (const name of DB_NAMES) {
5198
+ const p = path13.join(EXE_AI_DIR, name);
5199
+ if (existsSync13(p)) return p;
5200
+ }
5201
+ return null;
5202
+ }
5203
+ function createBackup(reason = "manual") {
5204
+ const dbPath = findActiveDb();
5205
+ if (!dbPath) return null;
5206
+ mkdirSync6(BACKUP_DIR, { recursive: true });
5207
+ const dbName = path13.basename(dbPath, ".db");
5208
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
5209
+ const backupName = `${dbName}-${reason}-${timestamp}.db`;
5210
+ const backupPath = path13.join(BACKUP_DIR, backupName);
5211
+ copyFileSync2(dbPath, backupPath);
5212
+ const walPath = dbPath + "-wal";
5213
+ if (existsSync13(walPath)) {
5214
+ try {
5215
+ copyFileSync2(walPath, backupPath + "-wal");
5216
+ } catch {
5217
+ }
5218
+ }
5219
+ const shmPath = dbPath + "-shm";
5220
+ if (existsSync13(shmPath)) {
5221
+ try {
5222
+ copyFileSync2(shmPath, backupPath + "-shm");
5223
+ } catch {
5224
+ }
5225
+ }
5226
+ return backupPath;
5227
+ }
5228
+ function rotateBackups(keepDays = DEFAULT_KEEP_DAYS) {
5229
+ if (!existsSync13(BACKUP_DIR)) return 0;
5230
+ const cutoff = Date.now() - keepDays * 24 * 60 * 60 * 1e3;
5231
+ let deleted = 0;
5232
+ try {
5233
+ const files = readdirSync(BACKUP_DIR);
5234
+ for (const file of files) {
5235
+ if (!file.endsWith(".db") && !file.endsWith(".db-wal") && !file.endsWith(".db-shm")) continue;
5236
+ const filePath = path13.join(BACKUP_DIR, file);
5237
+ try {
5238
+ const stat2 = statSync2(filePath);
5239
+ if (stat2.mtimeMs < cutoff) {
5240
+ unlinkSync4(filePath);
5241
+ deleted++;
5242
+ }
5243
+ } catch {
5244
+ }
5245
+ }
5246
+ } catch {
5247
+ }
5248
+ return deleted;
5249
+ }
5250
+ function listBackups() {
5251
+ if (!existsSync13(BACKUP_DIR)) return [];
5252
+ try {
5253
+ const files = readdirSync(BACKUP_DIR).filter((f) => f.endsWith(".db") && !f.endsWith("-wal") && !f.endsWith("-shm"));
5254
+ return files.map((name) => {
5255
+ const p = path13.join(BACKUP_DIR, name);
5256
+ const stat2 = statSync2(p);
5257
+ return { path: p, name, size: stat2.size, date: stat2.mtime };
5258
+ }).sort((a, b) => b.date.getTime() - a.date.getTime());
5259
+ } catch {
5260
+ return [];
5261
+ }
5262
+ }
5263
+ function hasBackupToday(reason) {
5264
+ const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
5265
+ const backups = listBackups();
5266
+ return backups.some((b) => b.name.includes(reason) && b.name.includes(today.replace(/-/g, "-")));
5267
+ }
5268
+ function getLatestBackup() {
5269
+ const backups = listBackups();
5270
+ return backups.length > 0 ? backups[0].path : null;
5271
+ }
5272
+ function getBackupDir() {
5273
+ return BACKUP_DIR;
5274
+ }
5275
+ var BACKUP_DIR, DEFAULT_KEEP_DAYS, DB_NAMES;
5276
+ var init_db_backup = __esm({
5277
+ "src/lib/db-backup.ts"() {
5278
+ "use strict";
5279
+ init_config();
5280
+ BACKUP_DIR = path13.join(EXE_AI_DIR, "backups");
5281
+ DEFAULT_KEEP_DAYS = 3;
5282
+ DB_NAMES = ["memories.db", "exe-mem.db", "exe-os.db", "exe.db"];
5283
+ }
5284
+ });
5285
+
5006
5286
  // src/lib/cloud-sync.ts
5007
5287
  var cloud_sync_exports = {};
5008
5288
  __export(cloud_sync_exports, {
@@ -5032,16 +5312,16 @@ __export(cloud_sync_exports, {
5032
5312
  pushToPostgres: () => pushToPostgres,
5033
5313
  recordRosterDeletion: () => recordRosterDeletion
5034
5314
  });
5035
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync8, existsSync as existsSync13, readdirSync, mkdirSync as mkdirSync6, appendFileSync, unlinkSync as unlinkSync4, openSync as openSync2, closeSync as closeSync2 } from "fs";
5315
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync8, existsSync as existsSync14, readdirSync as readdirSync2, mkdirSync as mkdirSync7, appendFileSync, unlinkSync as unlinkSync5, openSync as openSync2, closeSync as closeSync2 } from "fs";
5036
5316
  import crypto4 from "crypto";
5037
- import path13 from "path";
5317
+ import path14 from "path";
5038
5318
  import { homedir as homedir2 } from "os";
5039
5319
  function sqlSafe(v) {
5040
5320
  return v === void 0 ? null : v;
5041
5321
  }
5042
5322
  function logError(msg) {
5043
5323
  try {
5044
- const logPath = path13.join(homedir2(), ".exe-os", "workers.log");
5324
+ const logPath = path14.join(homedir2(), ".exe-os", "workers.log");
5045
5325
  appendFileSync(logPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${msg}
5046
5326
  `);
5047
5327
  } catch {
@@ -5050,10 +5330,10 @@ function logError(msg) {
5050
5330
  function loadPgClient() {
5051
5331
  if (_pgFailed) return null;
5052
5332
  const postgresUrl = process.env.DATABASE_URL;
5053
- const configPath = path13.join(EXE_AI_DIR, "config.json");
5333
+ const configPath = path14.join(EXE_AI_DIR, "config.json");
5054
5334
  let cloudPostgresUrl;
5055
5335
  try {
5056
- if (existsSync13(configPath)) {
5336
+ if (existsSync14(configPath)) {
5057
5337
  const cfg = JSON.parse(readFileSync10(configPath, "utf8"));
5058
5338
  cloudPostgresUrl = cfg.cloud?.postgresUrl;
5059
5339
  if (cfg.cloud?.syncToPostgres === false) {
@@ -5072,8 +5352,8 @@ function loadPgClient() {
5072
5352
  _pgPromise = (async () => {
5073
5353
  const { createRequire: createRequire3 } = await import("module");
5074
5354
  const { pathToFileURL: pathToFileURL3 } = await import("url");
5075
- const exeDbRoot = process.env.EXE_DB_ROOT ?? path13.join(homedir2(), "exe-db");
5076
- const req = createRequire3(path13.join(exeDbRoot, "package.json"));
5355
+ const exeDbRoot = process.env.EXE_DB_ROOT ?? path14.join(homedir2(), "exe-db");
5356
+ const req = createRequire3(path14.join(exeDbRoot, "package.json"));
5077
5357
  const entry = req.resolve("@prisma/client");
5078
5358
  const mod = await import(pathToFileURL3(entry).href);
5079
5359
  const Ctor = mod.PrismaClient ?? mod.default?.PrismaClient;
@@ -5126,7 +5406,7 @@ async function withRosterLock(fn) {
5126
5406
  if (Date.now() - ts < LOCK_STALE_MS) {
5127
5407
  throw new Error("Roster merge already in progress \u2014 another sync is running");
5128
5408
  }
5129
- unlinkSync4(ROSTER_LOCK_PATH);
5409
+ unlinkSync5(ROSTER_LOCK_PATH);
5130
5410
  const fd = openSync2(ROSTER_LOCK_PATH, "wx");
5131
5411
  closeSync2(fd);
5132
5412
  writeFileSync8(ROSTER_LOCK_PATH, String(Date.now()));
@@ -5142,7 +5422,7 @@ async function withRosterLock(fn) {
5142
5422
  return await fn();
5143
5423
  } finally {
5144
5424
  try {
5145
- unlinkSync4(ROSTER_LOCK_PATH);
5425
+ unlinkSync5(ROSTER_LOCK_PATH);
5146
5426
  } catch {
5147
5427
  }
5148
5428
  }
@@ -5513,13 +5793,42 @@ async function cloudSync(config) {
5513
5793
  try {
5514
5794
  const employees = await loadEmployees();
5515
5795
  rosterResult.employees = employees.length;
5516
- const idDir = path13.join(EXE_AI_DIR, "identity");
5517
- if (existsSync13(idDir)) {
5518
- rosterResult.identities = readdirSync(idDir).filter((f) => f.endsWith(".md")).length;
5796
+ const idDir = path14.join(EXE_AI_DIR, "identity");
5797
+ if (existsSync14(idDir)) {
5798
+ rosterResult.identities = readdirSync2(idDir).filter((f) => f.endsWith(".md")).length;
5519
5799
  }
5520
5800
  } catch {
5521
5801
  }
5522
5802
  const totalMemories = await countRows("SELECT COUNT(*) as cnt FROM memories WHERE status = 'active' OR status IS NULL");
5803
+ try {
5804
+ const { getLatestBackup: getLatestBackup2 } = await Promise.resolve().then(() => (init_db_backup(), db_backup_exports));
5805
+ const { statSync: statFile } = await import("fs");
5806
+ const latestBackup = getLatestBackup2();
5807
+ if (latestBackup) {
5808
+ const backupSize = statFile(latestBackup).size;
5809
+ const MAX_CLOUD_BACKUP_BYTES = 50 * 1024 * 1024;
5810
+ if (backupSize <= MAX_CLOUD_BACKUP_BYTES) {
5811
+ const backupData = readFileSync10(latestBackup);
5812
+ const deviceId = loadDeviceId() ?? "unknown";
5813
+ const encrypted = encryptSyncBlob(backupData);
5814
+ const backupRes = await fetchWithRetry(`${config.endpoint}/sync/push-db-backup`, {
5815
+ method: "POST",
5816
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${config.apiKey}` },
5817
+ body: JSON.stringify({
5818
+ device_id: deviceId,
5819
+ filename: path14.basename(latestBackup),
5820
+ blob: encrypted,
5821
+ size: backupData.length
5822
+ })
5823
+ });
5824
+ if (backupRes && !backupRes.ok) {
5825
+ logError(`[cloud-sync] DB backup upload failed: ${backupRes.status}`);
5826
+ }
5827
+ }
5828
+ }
5829
+ } catch (err) {
5830
+ logError(`[cloud-sync] DB backup upload error: ${err instanceof Error ? err.message : String(err)}`);
5831
+ }
5523
5832
  return {
5524
5833
  pushed,
5525
5834
  pulled,
@@ -5535,7 +5844,7 @@ async function cloudSync(config) {
5535
5844
  function recordRosterDeletion(name) {
5536
5845
  let deletions = [];
5537
5846
  try {
5538
- if (existsSync13(ROSTER_DELETIONS_PATH)) {
5847
+ if (existsSync14(ROSTER_DELETIONS_PATH)) {
5539
5848
  deletions = JSON.parse(readFileSync10(ROSTER_DELETIONS_PATH, "utf-8"));
5540
5849
  }
5541
5850
  } catch {
@@ -5545,7 +5854,7 @@ function recordRosterDeletion(name) {
5545
5854
  }
5546
5855
  function consumeRosterDeletions() {
5547
5856
  try {
5548
- if (!existsSync13(ROSTER_DELETIONS_PATH)) return [];
5857
+ if (!existsSync14(ROSTER_DELETIONS_PATH)) return [];
5549
5858
  const deletions = JSON.parse(readFileSync10(ROSTER_DELETIONS_PATH, "utf-8"));
5550
5859
  writeFileSync8(ROSTER_DELETIONS_PATH, "[]");
5551
5860
  return deletions;
@@ -5554,35 +5863,35 @@ function consumeRosterDeletions() {
5554
5863
  }
5555
5864
  }
5556
5865
  function buildRosterBlob(paths) {
5557
- const rosterPath = paths?.rosterPath ?? path13.join(EXE_AI_DIR, "exe-employees.json");
5558
- const identityDir = paths?.identityDir ?? path13.join(EXE_AI_DIR, "identity");
5559
- const configPath = paths?.configPath ?? path13.join(EXE_AI_DIR, "config.json");
5866
+ const rosterPath = paths?.rosterPath ?? path14.join(EXE_AI_DIR, "exe-employees.json");
5867
+ const identityDir = paths?.identityDir ?? path14.join(EXE_AI_DIR, "identity");
5868
+ const configPath = paths?.configPath ?? path14.join(EXE_AI_DIR, "config.json");
5560
5869
  let roster = [];
5561
- if (existsSync13(rosterPath)) {
5870
+ if (existsSync14(rosterPath)) {
5562
5871
  try {
5563
5872
  roster = JSON.parse(readFileSync10(rosterPath, "utf-8"));
5564
5873
  } catch {
5565
5874
  }
5566
5875
  }
5567
5876
  const identities = {};
5568
- if (existsSync13(identityDir)) {
5569
- for (const file of readdirSync(identityDir).filter((f) => f.endsWith(".md"))) {
5877
+ if (existsSync14(identityDir)) {
5878
+ for (const file of readdirSync2(identityDir).filter((f) => f.endsWith(".md"))) {
5570
5879
  try {
5571
- identities[file] = readFileSync10(path13.join(identityDir, file), "utf-8");
5880
+ identities[file] = readFileSync10(path14.join(identityDir, file), "utf-8");
5572
5881
  } catch {
5573
5882
  }
5574
5883
  }
5575
5884
  }
5576
5885
  let config;
5577
- if (existsSync13(configPath)) {
5886
+ if (existsSync14(configPath)) {
5578
5887
  try {
5579
5888
  config = JSON.parse(readFileSync10(configPath, "utf-8"));
5580
5889
  } catch {
5581
5890
  }
5582
5891
  }
5583
5892
  let agentConfig;
5584
- const agentConfigPath = path13.join(EXE_AI_DIR, "agent-config.json");
5585
- if (existsSync13(agentConfigPath)) {
5893
+ const agentConfigPath = path14.join(EXE_AI_DIR, "agent-config.json");
5894
+ if (existsSync14(agentConfigPath)) {
5586
5895
  try {
5587
5896
  agentConfig = JSON.parse(readFileSync10(agentConfigPath, "utf-8"));
5588
5897
  } catch {
@@ -5660,16 +5969,16 @@ async function cloudPullRoster(config) {
5660
5969
  }
5661
5970
  }
5662
5971
  function mergeConfig(remoteConfig, configPath) {
5663
- const cfgPath = configPath ?? path13.join(EXE_AI_DIR, "config.json");
5972
+ const cfgPath = configPath ?? path14.join(EXE_AI_DIR, "config.json");
5664
5973
  let local = {};
5665
- if (existsSync13(cfgPath)) {
5974
+ if (existsSync14(cfgPath)) {
5666
5975
  try {
5667
5976
  local = JSON.parse(readFileSync10(cfgPath, "utf-8"));
5668
5977
  } catch {
5669
5978
  }
5670
5979
  }
5671
5980
  const merged = { ...remoteConfig, ...local };
5672
- const dir = path13.dirname(cfgPath);
5981
+ const dir = path14.dirname(cfgPath);
5673
5982
  ensurePrivateDirSync(dir);
5674
5983
  writeFileSync8(cfgPath, JSON.stringify(merged, null, 2), "utf-8");
5675
5984
  enforcePrivateFileSync(cfgPath);
@@ -5677,7 +5986,7 @@ function mergeConfig(remoteConfig, configPath) {
5677
5986
  async function mergeRosterFromRemote(remote, paths) {
5678
5987
  return withRosterLock(async () => {
5679
5988
  const rosterPath = paths?.rosterPath ?? void 0;
5680
- const identityDir = paths?.identityDir ?? path13.join(EXE_AI_DIR, "identity");
5989
+ const identityDir = paths?.identityDir ?? path14.join(EXE_AI_DIR, "identity");
5681
5990
  const localEmployees = await loadEmployees(rosterPath);
5682
5991
  const localNames = new Set(localEmployees.map((e) => e.name));
5683
5992
  let added = 0;
@@ -5698,11 +6007,11 @@ async function mergeRosterFromRemote(remote, paths) {
5698
6007
  ) ?? lookupKey;
5699
6008
  const remoteIdentity = remote.identities[matchedKey];
5700
6009
  if (remoteIdentity) {
5701
- if (!existsSync13(identityDir)) mkdirSync6(identityDir, { recursive: true });
5702
- const idPath = path13.join(identityDir, `${remoteEmp.name}.md`);
6010
+ if (!existsSync14(identityDir)) mkdirSync7(identityDir, { recursive: true });
6011
+ const idPath = path14.join(identityDir, `${remoteEmp.name}.md`);
5703
6012
  let localIdentity = null;
5704
6013
  try {
5705
- localIdentity = existsSync13(idPath) ? readFileSync10(idPath, "utf-8") : null;
6014
+ localIdentity = existsSync14(idPath) ? readFileSync10(idPath, "utf-8") : null;
5706
6015
  } catch {
5707
6016
  }
5708
6017
  if (localIdentity !== remoteIdentity) {
@@ -5732,16 +6041,16 @@ async function mergeRosterFromRemote(remote, paths) {
5732
6041
  }
5733
6042
  if (remote.agentConfig && Object.keys(remote.agentConfig).length > 0) {
5734
6043
  try {
5735
- const agentConfigPath = path13.join(EXE_AI_DIR, "agent-config.json");
6044
+ const agentConfigPath = path14.join(EXE_AI_DIR, "agent-config.json");
5736
6045
  let local = {};
5737
- if (existsSync13(agentConfigPath)) {
6046
+ if (existsSync14(agentConfigPath)) {
5738
6047
  try {
5739
6048
  local = JSON.parse(readFileSync10(agentConfigPath, "utf-8"));
5740
6049
  } catch {
5741
6050
  }
5742
6051
  }
5743
6052
  const merged = { ...remote.agentConfig, ...local };
5744
- ensurePrivateDirSync(path13.dirname(agentConfigPath));
6053
+ ensurePrivateDirSync(path14.dirname(agentConfigPath));
5745
6054
  writeFileSync8(agentConfigPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
5746
6055
  enforcePrivateFileSync(agentConfigPath);
5747
6056
  } catch {
@@ -6182,11 +6491,11 @@ var init_cloud_sync = __esm({
6182
6491
  LOCALHOST_PATTERNS = /^(localhost|127\.0\.0\.1|\[::1\])$/i;
6183
6492
  FETCH_TIMEOUT_MS = 3e4;
6184
6493
  PUSH_BATCH_SIZE = 5e3;
6185
- ROSTER_LOCK_PATH = path13.join(EXE_AI_DIR, "roster-merge.lock");
6494
+ ROSTER_LOCK_PATH = path14.join(EXE_AI_DIR, "roster-merge.lock");
6186
6495
  LOCK_STALE_MS = 3e4;
6187
6496
  _pgPromise = null;
6188
6497
  _pgFailed = false;
6189
- ROSTER_DELETIONS_PATH = path13.join(EXE_AI_DIR, "roster-deletions.json");
6498
+ ROSTER_DELETIONS_PATH = path14.join(EXE_AI_DIR, "roster-deletions.json");
6190
6499
  }
6191
6500
  });
6192
6501
 
@@ -6484,13 +6793,13 @@ __export(shard_manager_exports, {
6484
6793
  listShards: () => listShards,
6485
6794
  shardExists: () => shardExists
6486
6795
  });
6487
- import path14 from "path";
6488
- import { existsSync as existsSync14, mkdirSync as mkdirSync7, readdirSync as readdirSync2 } from "fs";
6796
+ import path15 from "path";
6797
+ import { existsSync as existsSync15, mkdirSync as mkdirSync8, readdirSync as readdirSync3 } from "fs";
6489
6798
  import { createClient as createClient2 } from "@libsql/client";
6490
6799
  function initShardManager(encryptionKey) {
6491
6800
  _encryptionKey = encryptionKey;
6492
- if (!existsSync14(SHARDS_DIR)) {
6493
- mkdirSync7(SHARDS_DIR, { recursive: true });
6801
+ if (!existsSync15(SHARDS_DIR)) {
6802
+ mkdirSync8(SHARDS_DIR, { recursive: true });
6494
6803
  }
6495
6804
  _shardingEnabled = true;
6496
6805
  if (_evictionTimer) clearInterval(_evictionTimer);
@@ -6519,7 +6828,7 @@ function getShardClient(projectName) {
6519
6828
  while (_shards.size >= MAX_OPEN_SHARDS) {
6520
6829
  evictLRU();
6521
6830
  }
6522
- const dbPath = path14.join(SHARDS_DIR, `${safeName}.db`);
6831
+ const dbPath = path15.join(SHARDS_DIR, `${safeName}.db`);
6523
6832
  const client = createClient2({
6524
6833
  url: `file:${dbPath}`,
6525
6834
  encryptionKey: _encryptionKey
@@ -6530,11 +6839,11 @@ function getShardClient(projectName) {
6530
6839
  }
6531
6840
  function shardExists(projectName) {
6532
6841
  const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
6533
- return existsSync14(path14.join(SHARDS_DIR, `${safeName}.db`));
6842
+ return existsSync15(path15.join(SHARDS_DIR, `${safeName}.db`));
6534
6843
  }
6535
6844
  function listShards() {
6536
- if (!existsSync14(SHARDS_DIR)) return [];
6537
- return readdirSync2(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
6845
+ if (!existsSync15(SHARDS_DIR)) return [];
6846
+ return readdirSync3(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
6538
6847
  }
6539
6848
  async function ensureShardSchema(client) {
6540
6849
  await client.execute("PRAGMA journal_mode = WAL");
@@ -6780,7 +7089,7 @@ var init_shard_manager = __esm({
6780
7089
  "src/lib/shard-manager.ts"() {
6781
7090
  "use strict";
6782
7091
  init_config();
6783
- SHARDS_DIR = path14.join(EXE_AI_DIR, "shards");
7092
+ SHARDS_DIR = path15.join(EXE_AI_DIR, "shards");
6784
7093
  SHARD_IDLE_MS = 5 * 60 * 1e3;
6785
7094
  MAX_OPEN_SHARDS = 10;
6786
7095
  EVICTION_INTERVAL_MS = 60 * 1e3;
@@ -7650,12 +7959,12 @@ __export(backfill_conversations_exports, {
7650
7959
  import crypto5 from "crypto";
7651
7960
  import { createReadStream } from "fs";
7652
7961
  import { readdir as readdir2, stat } from "fs/promises";
7653
- import path15 from "path";
7962
+ import path16 from "path";
7654
7963
  import { createInterface as createInterface2 } from "readline";
7655
7964
  import { homedir as homedir3 } from "os";
7656
7965
  import { parseArgs } from "util";
7657
7966
  async function findJsonlFiles(sinceDate, projectFilter) {
7658
- const projectsDir = path15.join(homedir3(), ".claude", "projects");
7967
+ const projectsDir = path16.join(homedir3(), ".claude", "projects");
7659
7968
  const files = [];
7660
7969
  async function walk(dir, depth = 0) {
7661
7970
  if (depth > MAX_WALK_DEPTH) return;
@@ -7666,7 +7975,7 @@ async function findJsonlFiles(sinceDate, projectFilter) {
7666
7975
  return;
7667
7976
  }
7668
7977
  for (const entry of entries) {
7669
- const full = path15.join(dir, entry.name);
7978
+ const full = path16.join(dir, entry.name);
7670
7979
  if (entry.isDirectory()) {
7671
7980
  if (entry.name === "subagents" || entry.name === "tool-results") continue;
7672
7981
  await walk(full, depth + 1);
@@ -7691,7 +8000,7 @@ async function findJsonlFiles(sinceDate, projectFilter) {
7691
8000
  if (!entry.isDirectory()) continue;
7692
8001
  const decoded = decodeProjectDir(entry.name);
7693
8002
  if (decoded.toLowerCase().includes(projectFilter.toLowerCase())) {
7694
- await walk(path15.join(projectsDir, entry.name));
8003
+ await walk(path16.join(projectsDir, entry.name));
7695
8004
  }
7696
8005
  }
7697
8006
  } else {
@@ -7708,14 +8017,14 @@ function decodeProjectDir(dirName) {
7708
8017
  return dirName;
7709
8018
  }
7710
8019
  function projectNameFromPath(filePath) {
7711
- const projectsDir = path15.join(homedir3(), ".claude", "projects");
7712
- const relative = path15.relative(projectsDir, filePath);
7713
- const projectDir = relative.split(path15.sep)[0] ?? "unknown";
8020
+ const projectsDir = path16.join(homedir3(), ".claude", "projects");
8021
+ const relative = path16.relative(projectsDir, filePath);
8022
+ const projectDir = relative.split(path16.sep)[0] ?? "unknown";
7714
8023
  return decodeProjectDir(projectDir);
7715
8024
  }
7716
8025
  async function parseConversation(filePath) {
7717
8026
  const conv = {
7718
- sessionId: path15.basename(filePath, ".jsonl"),
8027
+ sessionId: path16.basename(filePath, ".jsonl"),
7719
8028
  projectName: projectNameFromPath(filePath),
7720
8029
  cwd: void 0,
7721
8030
  startTime: void 0,
@@ -7779,7 +8088,7 @@ async function parseConversation(filePath) {
7779
8088
  }
7780
8089
  }
7781
8090
  if (conv.cwd) {
7782
- conv.projectName = path15.basename(conv.cwd);
8091
+ conv.projectName = path16.basename(conv.cwd);
7783
8092
  const worktreeMatch = conv.cwd.match(/\.worktrees\/([^/]+)/);
7784
8093
  if (worktreeMatch?.[1]) {
7785
8094
  conv.agentId = worktreeMatch[1];
@@ -8431,9 +8740,9 @@ Unclassified: ${unclassified}
8431
8740
  }
8432
8741
  async function exportBatches(options) {
8433
8742
  const fs8 = await import("fs");
8434
- const path47 = await import("path");
8743
+ const path48 = await import("path");
8435
8744
  const client = getClient();
8436
- const outDir = path47.join(process.cwd(), "exe/output/classifications/input");
8745
+ const outDir = path48.join(process.cwd(), "exe/output/classifications/input");
8437
8746
  fs8.mkdirSync(outDir, { recursive: true });
8438
8747
  const countResult = await client.execute({
8439
8748
  sql: "SELECT COUNT(*) as cnt FROM memories WHERE intent IS NULL AND outcome IS NULL AND domain IS NULL",
@@ -8457,7 +8766,7 @@ async function exportBatches(options) {
8457
8766
  const text = String(row.text || "").replace(/\n/g, " ");
8458
8767
  return JSON.stringify({ id: row.id, text });
8459
8768
  });
8460
- const batchFile = path47.join(outDir, `batch-${String(batchNum).padStart(4, "0")}.jsonl`);
8769
+ const batchFile = path48.join(outDir, `batch-${String(batchNum).padStart(4, "0")}.jsonl`);
8461
8770
  fs8.writeFileSync(batchFile, lines.join("\n") + "\n");
8462
8771
  exported += batch.rows.length;
8463
8772
  offset += options.batchSize;
@@ -8473,7 +8782,7 @@ async function exportBatches(options) {
8473
8782
  }
8474
8783
  async function importClassifications(importDir) {
8475
8784
  const fs8 = await import("fs");
8476
- const path47 = await import("path");
8785
+ const path48 = await import("path");
8477
8786
  const client = getClient();
8478
8787
  const files = fs8.readdirSync(importDir).filter((f) => f.endsWith(".jsonl")).sort();
8479
8788
  process.stderr.write(`[backfill-metadata] Found ${files.length} JSONL files to import from ${importDir}
@@ -8481,7 +8790,7 @@ async function importClassifications(importDir) {
8481
8790
  let imported = 0;
8482
8791
  let invalid = 0;
8483
8792
  for (const file of files) {
8484
- const lines = fs8.readFileSync(path47.join(importDir, file), "utf-8").split("\n").filter(Boolean);
8793
+ const lines = fs8.readFileSync(path48.join(importDir, file), "utf-8").split("\n").filter(Boolean);
8485
8794
  for (const line of lines) {
8486
8795
  try {
8487
8796
  const rec = JSON.parse(line);
@@ -8622,17 +8931,17 @@ __export(identity_exports, {
8622
8931
  listIdentities: () => listIdentities,
8623
8932
  updateIdentity: () => updateIdentity
8624
8933
  });
8625
- import { existsSync as existsSync15, mkdirSync as mkdirSync8, readFileSync as readFileSync11, writeFileSync as writeFileSync9 } from "fs";
8626
- import { readdirSync as readdirSync3 } from "fs";
8627
- import path16 from "path";
8934
+ import { existsSync as existsSync16, mkdirSync as mkdirSync9, readFileSync as readFileSync11, writeFileSync as writeFileSync9 } from "fs";
8935
+ import { readdirSync as readdirSync4 } from "fs";
8936
+ import path17 from "path";
8628
8937
  import { createHash as createHash2 } from "crypto";
8629
8938
  function ensureDir() {
8630
- if (!existsSync15(IDENTITY_DIR2)) {
8631
- mkdirSync8(IDENTITY_DIR2, { recursive: true });
8939
+ if (!existsSync16(IDENTITY_DIR2)) {
8940
+ mkdirSync9(IDENTITY_DIR2, { recursive: true });
8632
8941
  }
8633
8942
  }
8634
8943
  function identityPath(agentId) {
8635
- return path16.join(IDENTITY_DIR2, `${agentId}.md`);
8944
+ return path17.join(IDENTITY_DIR2, `${agentId}.md`);
8636
8945
  }
8637
8946
  function parseFrontmatter(raw) {
8638
8947
  const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
@@ -8673,7 +8982,7 @@ function contentHash(content) {
8673
8982
  }
8674
8983
  function getIdentity(agentId) {
8675
8984
  const filePath = identityPath(agentId);
8676
- if (!existsSync15(filePath)) return null;
8985
+ if (!existsSync16(filePath)) return null;
8677
8986
  const raw = readFileSync11(filePath, "utf-8");
8678
8987
  const { frontmatter, body } = parseFrontmatter(raw);
8679
8988
  return {
@@ -8705,7 +9014,7 @@ async function updateIdentity(agentId, content, updatedBy) {
8705
9014
  }
8706
9015
  function listIdentities() {
8707
9016
  ensureDir();
8708
- const files = readdirSync3(IDENTITY_DIR2).filter((f) => f.endsWith(".md"));
9017
+ const files = readdirSync4(IDENTITY_DIR2).filter((f) => f.endsWith(".md"));
8709
9018
  const results = [];
8710
9019
  for (const file of files) {
8711
9020
  const agentId = file.replace(".md", "");
@@ -8744,15 +9053,15 @@ var init_identity = __esm({
8744
9053
  "use strict";
8745
9054
  init_config();
8746
9055
  init_database();
8747
- IDENTITY_DIR2 = path16.join(EXE_AI_DIR, "identity");
9056
+ IDENTITY_DIR2 = path17.join(EXE_AI_DIR, "identity");
8748
9057
  }
8749
9058
  });
8750
9059
 
8751
9060
  // src/lib/orchestration-package.ts
8752
9061
  import { randomUUID as randomUUID4 } from "crypto";
8753
- import { copyFileSync as copyFileSync2, existsSync as existsSync16, mkdirSync as mkdirSync9, readFileSync as readFileSync12, writeFileSync as writeFileSync10 } from "fs";
9062
+ import { copyFileSync as copyFileSync3, existsSync as existsSync17, mkdirSync as mkdirSync10, readFileSync as readFileSync12, writeFileSync as writeFileSync10 } from "fs";
8754
9063
  import os10 from "os";
8755
- import path17 from "path";
9064
+ import path18 from "path";
8756
9065
  function ensureObject(value, label) {
8757
9066
  if (value == null || Array.isArray(value) || typeof value !== "object") {
8758
9067
  throw new Error(`${label} must be an object`);
@@ -8811,14 +9120,14 @@ function validateProcedureEntry(value, index) {
8811
9120
  };
8812
9121
  }
8813
9122
  function getRosterPath() {
8814
- return path17.join(os10.homedir(), EXE_OS_DIRNAME, ROSTER_FILENAME);
9123
+ return path18.join(os10.homedir(), EXE_OS_DIRNAME, ROSTER_FILENAME);
8815
9124
  }
8816
9125
  function getBackupPath() {
8817
- return path17.join(os10.homedir(), EXE_OS_DIRNAME, ROSTER_BACKUP_FILENAME);
9126
+ return path18.join(os10.homedir(), EXE_OS_DIRNAME, ROSTER_BACKUP_FILENAME);
8818
9127
  }
8819
9128
  function readRosterFile() {
8820
9129
  const rosterPath = getRosterPath();
8821
- if (!existsSync16(rosterPath)) return [];
9130
+ if (!existsSync17(rosterPath)) return [];
8822
9131
  const raw = readFileSync12(rosterPath, "utf-8");
8823
9132
  const parsed = JSON.parse(raw);
8824
9133
  if (!Array.isArray(parsed)) {
@@ -8831,15 +9140,15 @@ function writeRosterFile(roster) {
8831
9140
  throw new Error("Refusing to write empty roster \u2014 this would delete all employees");
8832
9141
  }
8833
9142
  const rosterPath = getRosterPath();
8834
- mkdirSync9(path17.dirname(rosterPath), { recursive: true });
8835
- if (existsSync16(rosterPath)) {
9143
+ mkdirSync10(path18.dirname(rosterPath), { recursive: true });
9144
+ if (existsSync17(rosterPath)) {
8836
9145
  const currentRoster = readRosterFile();
8837
9146
  if (roster.length < currentRoster.length) {
8838
9147
  throw new Error(
8839
9148
  `Refusing to write roster with ${roster.length} entries \u2014 current roster has ${currentRoster.length}. Import would delete ${currentRoster.length - roster.length} employee(s). Use merge strategy instead, or add the missing entries to the package.`
8840
9149
  );
8841
9150
  }
8842
- copyFileSync2(rosterPath, getBackupPath());
9151
+ copyFileSync3(rosterPath, getBackupPath());
8843
9152
  }
8844
9153
  writeFileSync10(rosterPath, `${JSON.stringify(roster, null, 2)}
8845
9154
  `, "utf-8");
@@ -9108,8 +9417,8 @@ var exe_export_exports = {};
9108
9417
  __export(exe_export_exports, {
9109
9418
  runExeExport: () => runExeExport
9110
9419
  });
9111
- import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync11 } from "fs";
9112
- import path18 from "path";
9420
+ import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync11 } from "fs";
9421
+ import path19 from "path";
9113
9422
  function printUsage() {
9114
9423
  process.stdout.write("Usage: exe-os export --output <path>\n");
9115
9424
  }
@@ -9130,7 +9439,7 @@ async function runExeExport(argv = process.argv.slice(2)) {
9130
9439
  await initStore();
9131
9440
  try {
9132
9441
  const pkg = await exportOrchestration("cli");
9133
- mkdirSync10(path18.dirname(outputPath), { recursive: true });
9442
+ mkdirSync11(path19.dirname(outputPath), { recursive: true });
9134
9443
  writeFileSync11(outputPath, `${JSON.stringify(pkg, null, 2)}
9135
9444
  `, "utf-8");
9136
9445
  process.stdout.write(
@@ -9231,14 +9540,14 @@ __export(session_registry_exports, {
9231
9540
  refreshSessionProject: () => refreshSessionProject,
9232
9541
  registerSession: () => registerSession
9233
9542
  });
9234
- import { readFileSync as readFileSync14, writeFileSync as writeFileSync12, mkdirSync as mkdirSync11, existsSync as existsSync17 } from "fs";
9235
- import { execSync as execSync3 } from "child_process";
9236
- import path19 from "path";
9543
+ import { readFileSync as readFileSync14, writeFileSync as writeFileSync12, mkdirSync as mkdirSync12, existsSync as existsSync18 } from "fs";
9544
+ import { execSync as execSync4 } from "child_process";
9545
+ import path20 from "path";
9237
9546
  import os11 from "os";
9238
9547
  function registerSession(entry) {
9239
- const dir = path19.dirname(REGISTRY_PATH);
9240
- if (!existsSync17(dir)) {
9241
- mkdirSync11(dir, { recursive: true });
9548
+ const dir = path20.dirname(REGISTRY_PATH);
9549
+ if (!existsSync18(dir)) {
9550
+ mkdirSync12(dir, { recursive: true });
9242
9551
  }
9243
9552
  const sessions = listSessions();
9244
9553
  const idx = sessions.findIndex((s) => s.windowName === entry.windowName);
@@ -9272,7 +9581,7 @@ function pruneStaleSessions() {
9272
9581
  if (sessions.length === 0) return 0;
9273
9582
  let liveSessions = [];
9274
9583
  try {
9275
- liveSessions = execSync3("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
9584
+ liveSessions = execSync4("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
9276
9585
  encoding: "utf8"
9277
9586
  }).trim().split("\n").filter(Boolean);
9278
9587
  } catch {
@@ -9290,12 +9599,12 @@ var REGISTRY_PATH;
9290
9599
  var init_session_registry = __esm({
9291
9600
  "src/lib/session-registry.ts"() {
9292
9601
  "use strict";
9293
- REGISTRY_PATH = path19.join(os11.homedir(), ".exe-os", "session-registry.json");
9602
+ REGISTRY_PATH = path20.join(os11.homedir(), ".exe-os", "session-registry.json");
9294
9603
  }
9295
9604
  });
9296
9605
 
9297
9606
  // src/lib/session-key.ts
9298
- import { execSync as execSync4 } from "child_process";
9607
+ import { execSync as execSync5 } from "child_process";
9299
9608
  function normalizeCommand(command) {
9300
9609
  const trimmed = command.trim().toLowerCase();
9301
9610
  const parts = trimmed.split(/[\\/]/);
@@ -9314,7 +9623,7 @@ function resolveRuntimeProcess() {
9314
9623
  let pid = process.ppid;
9315
9624
  for (let i = 0; i < 10; i++) {
9316
9625
  try {
9317
- const info = execSync4(`ps -p ${pid} -o ppid=,comm=`, {
9626
+ const info = execSync5(`ps -p ${pid} -o ppid=,comm=`, {
9318
9627
  encoding: "utf8",
9319
9628
  timeout: 2e3
9320
9629
  }).trim();
@@ -9488,14 +9797,14 @@ var init_transport = __esm({
9488
9797
  });
9489
9798
 
9490
9799
  // src/lib/cc-agent-support.ts
9491
- import { execSync as execSync5 } from "child_process";
9800
+ import { execSync as execSync6 } from "child_process";
9492
9801
  function _resetCcAgentSupportCache() {
9493
9802
  _cachedSupport = null;
9494
9803
  }
9495
9804
  function claudeSupportsAgentFlag() {
9496
9805
  if (_cachedSupport !== null) return _cachedSupport;
9497
9806
  try {
9498
- const helpOutput = execSync5("claude --help 2>&1", {
9807
+ const helpOutput = execSync6("claude --help 2>&1", {
9499
9808
  encoding: "utf-8",
9500
9809
  timeout: 5e3
9501
9810
  });
@@ -9546,16 +9855,16 @@ __export(intercom_queue_exports, {
9546
9855
  queueIntercom: () => queueIntercom,
9547
9856
  readQueue: () => readQueue
9548
9857
  });
9549
- import { readFileSync as readFileSync15, writeFileSync as writeFileSync13, renameSync as renameSync3, existsSync as existsSync18, mkdirSync as mkdirSync12 } from "fs";
9550
- import path20 from "path";
9858
+ import { readFileSync as readFileSync15, writeFileSync as writeFileSync13, renameSync as renameSync3, existsSync as existsSync19, mkdirSync as mkdirSync13 } from "fs";
9859
+ import path21 from "path";
9551
9860
  import os12 from "os";
9552
9861
  function ensureDir2() {
9553
- const dir = path20.dirname(QUEUE_PATH);
9554
- if (!existsSync18(dir)) mkdirSync12(dir, { recursive: true });
9862
+ const dir = path21.dirname(QUEUE_PATH);
9863
+ if (!existsSync19(dir)) mkdirSync13(dir, { recursive: true });
9555
9864
  }
9556
9865
  function readQueue() {
9557
9866
  try {
9558
- if (!existsSync18(QUEUE_PATH)) return [];
9867
+ if (!existsSync19(QUEUE_PATH)) return [];
9559
9868
  return JSON.parse(readFileSync15(QUEUE_PATH, "utf8"));
9560
9869
  } catch {
9561
9870
  return [];
@@ -9656,19 +9965,19 @@ var QUEUE_PATH, MAX_RETRIES2, TTL_MS, INTERCOM_LOG;
9656
9965
  var init_intercom_queue = __esm({
9657
9966
  "src/lib/intercom-queue.ts"() {
9658
9967
  "use strict";
9659
- QUEUE_PATH = path20.join(os12.homedir(), ".exe-os", "intercom-queue.json");
9968
+ QUEUE_PATH = path21.join(os12.homedir(), ".exe-os", "intercom-queue.json");
9660
9969
  MAX_RETRIES2 = 5;
9661
9970
  TTL_MS = 60 * 60 * 1e3;
9662
- INTERCOM_LOG = path20.join(os12.homedir(), ".exe-os", "intercom.log");
9971
+ INTERCOM_LOG = path21.join(os12.homedir(), ".exe-os", "intercom.log");
9663
9972
  }
9664
9973
  });
9665
9974
 
9666
9975
  // src/lib/plan-limits.ts
9667
- import { readFileSync as readFileSync16, existsSync as existsSync19 } from "fs";
9668
- import path21 from "path";
9976
+ import { readFileSync as readFileSync16, existsSync as existsSync20 } from "fs";
9977
+ import path22 from "path";
9669
9978
  function getLicenseSync() {
9670
9979
  try {
9671
- if (!existsSync19(CACHE_PATH2)) return freeLicense();
9980
+ if (!existsSync20(CACHE_PATH2)) return freeLicense();
9672
9981
  const raw = JSON.parse(readFileSync16(CACHE_PATH2, "utf8"));
9673
9982
  if (!raw.token || typeof raw.token !== "string") return freeLicense();
9674
9983
  const parts = raw.token.split(".");
@@ -9707,7 +10016,7 @@ function assertEmployeeLimitSync(rosterPath) {
9707
10016
  const filePath = rosterPath ?? EMPLOYEES_PATH;
9708
10017
  let count = 0;
9709
10018
  try {
9710
- if (existsSync19(filePath)) {
10019
+ if (existsSync20(filePath)) {
9711
10020
  const raw = readFileSync16(filePath, "utf8");
9712
10021
  const employees = JSON.parse(raw);
9713
10022
  count = Array.isArray(employees) ? employees.length : 0;
@@ -9737,7 +10046,7 @@ var init_plan_limits = __esm({
9737
10046
  this.name = "PlanLimitError";
9738
10047
  }
9739
10048
  };
9740
- CACHE_PATH2 = path21.join(EXE_AI_DIR, "license-cache.json");
10049
+ CACHE_PATH2 = path22.join(EXE_AI_DIR, "license-cache.json");
9741
10050
  }
9742
10051
  });
9743
10052
 
@@ -9782,13 +10091,13 @@ var init_task_scope = __esm({
9782
10091
 
9783
10092
  // src/lib/notifications.ts
9784
10093
  import crypto6 from "crypto";
9785
- import path22 from "path";
10094
+ import path23 from "path";
9786
10095
  import os13 from "os";
9787
10096
  import {
9788
10097
  readFileSync as readFileSync17,
9789
- readdirSync as readdirSync4,
9790
- unlinkSync as unlinkSync5,
9791
- existsSync as existsSync20,
10098
+ readdirSync as readdirSync5,
10099
+ unlinkSync as unlinkSync6,
10100
+ existsSync as existsSync21,
9792
10101
  rmdirSync
9793
10102
  } from "fs";
9794
10103
  async function writeNotification(notification) {
@@ -9872,34 +10181,34 @@ var init_session_kill_telemetry = __esm({
9872
10181
  });
9873
10182
 
9874
10183
  // src/lib/project-name.ts
9875
- import { execSync as execSync6 } from "child_process";
9876
- import path23 from "path";
10184
+ import { execSync as execSync7 } from "child_process";
10185
+ import path24 from "path";
9877
10186
  function getProjectName(cwd2) {
9878
10187
  const dir = cwd2 ?? process.cwd();
9879
10188
  if (_cached2 && _cachedCwd === dir) return _cached2;
9880
10189
  try {
9881
10190
  let repoRoot;
9882
10191
  try {
9883
- const gitCommonDir = execSync6("git rev-parse --path-format=absolute --git-common-dir", {
10192
+ const gitCommonDir = execSync7("git rev-parse --path-format=absolute --git-common-dir", {
9884
10193
  cwd: dir,
9885
10194
  encoding: "utf8",
9886
10195
  timeout: 2e3,
9887
10196
  stdio: ["pipe", "pipe", "pipe"]
9888
10197
  }).trim();
9889
- repoRoot = path23.dirname(gitCommonDir);
10198
+ repoRoot = path24.dirname(gitCommonDir);
9890
10199
  } catch {
9891
- repoRoot = execSync6("git rev-parse --show-toplevel", {
10200
+ repoRoot = execSync7("git rev-parse --show-toplevel", {
9892
10201
  cwd: dir,
9893
10202
  encoding: "utf8",
9894
10203
  timeout: 2e3,
9895
10204
  stdio: ["pipe", "pipe", "pipe"]
9896
10205
  }).trim();
9897
10206
  }
9898
- _cached2 = path23.basename(repoRoot);
10207
+ _cached2 = path24.basename(repoRoot);
9899
10208
  _cachedCwd = dir;
9900
10209
  return _cached2;
9901
10210
  } catch {
9902
- _cached2 = path23.basename(dir);
10211
+ _cached2 = path24.basename(dir);
9903
10212
  _cachedCwd = dir;
9904
10213
  return _cached2;
9905
10214
  }
@@ -9993,11 +10302,11 @@ __export(tasks_crud_exports, {
9993
10302
  writeCheckpoint: () => writeCheckpoint
9994
10303
  });
9995
10304
  import crypto8 from "crypto";
9996
- import path24 from "path";
10305
+ import path25 from "path";
9997
10306
  import os14 from "os";
9998
- import { execSync as execSync7 } from "child_process";
10307
+ import { execSync as execSync8 } from "child_process";
9999
10308
  import { mkdir as mkdir5, writeFile as writeFile5, appendFile } from "fs/promises";
10000
- import { existsSync as existsSync21, readFileSync as readFileSync18 } from "fs";
10309
+ import { existsSync as existsSync22, readFileSync as readFileSync18 } from "fs";
10001
10310
  async function writeCheckpoint(input) {
10002
10311
  const client = getClient();
10003
10312
  const row = await resolveTask(client, input.taskId);
@@ -10196,8 +10505,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
10196
10505
  }
10197
10506
  if (input.baseDir) {
10198
10507
  try {
10199
- await mkdir5(path24.join(input.baseDir, "exe", "output"), { recursive: true });
10200
- await mkdir5(path24.join(input.baseDir, "exe", "research"), { recursive: true });
10508
+ await mkdir5(path25.join(input.baseDir, "exe", "output"), { recursive: true });
10509
+ await mkdir5(path25.join(input.baseDir, "exe", "research"), { recursive: true });
10201
10510
  await ensureArchitectureDoc(input.baseDir, input.projectName);
10202
10511
  await ensureGitignoreExe(input.baseDir);
10203
10512
  } catch {
@@ -10233,10 +10542,10 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
10233
10542
  });
10234
10543
  if (input.baseDir) {
10235
10544
  try {
10236
- const EXE_OS_DIR = path24.join(os14.homedir(), ".exe-os");
10237
- const mdPath = path24.join(EXE_OS_DIR, taskFile);
10238
- const mdDir = path24.dirname(mdPath);
10239
- if (!existsSync21(mdDir)) await mkdir5(mdDir, { recursive: true });
10545
+ const EXE_OS_DIR = path25.join(os14.homedir(), ".exe-os");
10546
+ const mdPath = path25.join(EXE_OS_DIR, taskFile);
10547
+ const mdDir = path25.dirname(mdPath);
10548
+ if (!existsSync22(mdDir)) await mkdir5(mdDir, { recursive: true });
10240
10549
  const reviewer = input.reviewer ?? input.assignedBy;
10241
10550
  const mdContent = `# ${input.title}
10242
10551
 
@@ -10340,14 +10649,14 @@ function isTmuxSessionAlive(identifier) {
10340
10649
  if (!identifier || identifier === "unknown") return true;
10341
10650
  try {
10342
10651
  if (identifier.startsWith("%")) {
10343
- const output = execSync7("tmux list-panes -a -F '#{pane_id}'", {
10652
+ const output = execSync8("tmux list-panes -a -F '#{pane_id}'", {
10344
10653
  timeout: 2e3,
10345
10654
  encoding: "utf8",
10346
10655
  stdio: ["pipe", "pipe", "pipe"]
10347
10656
  });
10348
10657
  return output.split("\n").some((l) => l.trim() === identifier);
10349
10658
  } else {
10350
- execSync7(`tmux has-session -t ${JSON.stringify(identifier)}`, {
10659
+ execSync8(`tmux has-session -t ${JSON.stringify(identifier)}`, {
10351
10660
  timeout: 2e3,
10352
10661
  stdio: ["pipe", "pipe", "pipe"]
10353
10662
  });
@@ -10356,7 +10665,7 @@ function isTmuxSessionAlive(identifier) {
10356
10665
  } catch {
10357
10666
  if (identifier.startsWith("%")) return true;
10358
10667
  try {
10359
- execSync7("tmux list-sessions", {
10668
+ execSync8("tmux list-sessions", {
10360
10669
  timeout: 2e3,
10361
10670
  stdio: ["pipe", "pipe", "pipe"]
10362
10671
  });
@@ -10371,12 +10680,12 @@ function checkStaleCompletion(taskContext, taskCreatedAt) {
10371
10680
  if (!DELEGATION_KEYWORDS.test(taskContext)) return null;
10372
10681
  try {
10373
10682
  const since = new Date(taskCreatedAt).toISOString();
10374
- const branch = execSync7(
10683
+ const branch = execSync8(
10375
10684
  "git rev-parse --abbrev-ref HEAD 2>/dev/null",
10376
10685
  { encoding: "utf8", timeout: 3e3 }
10377
10686
  ).trim();
10378
10687
  const branchArg = branch && branch !== "HEAD" ? branch : "";
10379
- const commitCount = execSync7(
10688
+ const commitCount = execSync8(
10380
10689
  `git log --oneline --since="${since}" ${branchArg} 2>/dev/null | wc -l`,
10381
10690
  { encoding: "utf8", timeout: 5e3 }
10382
10691
  ).trim();
@@ -10536,9 +10845,9 @@ async function deleteTaskCore(taskId, _baseDir) {
10536
10845
  return { taskFile, assignedTo, assignedBy, taskSlug };
10537
10846
  }
10538
10847
  async function ensureArchitectureDoc(baseDir, projectName) {
10539
- const archPath = path24.join(baseDir, "exe", "ARCHITECTURE.md");
10848
+ const archPath = path25.join(baseDir, "exe", "ARCHITECTURE.md");
10540
10849
  try {
10541
- if (existsSync21(archPath)) return;
10850
+ if (existsSync22(archPath)) return;
10542
10851
  const template = [
10543
10852
  `# ${projectName} \u2014 System Architecture`,
10544
10853
  "",
@@ -10571,9 +10880,9 @@ async function ensureArchitectureDoc(baseDir, projectName) {
10571
10880
  }
10572
10881
  }
10573
10882
  async function ensureGitignoreExe(baseDir) {
10574
- const gitignorePath = path24.join(baseDir, ".gitignore");
10883
+ const gitignorePath = path25.join(baseDir, ".gitignore");
10575
10884
  try {
10576
- if (existsSync21(gitignorePath)) {
10885
+ if (existsSync22(gitignorePath)) {
10577
10886
  const content = readFileSync18(gitignorePath, "utf-8");
10578
10887
  if (/^\/?exe\/?$/m.test(content)) return;
10579
10888
  await appendFile(gitignorePath, "\n# Employee task assignments (private)\n/exe/\n");
@@ -10617,8 +10926,8 @@ __export(tasks_review_exports, {
10617
10926
  isStale: () => isStale,
10618
10927
  listPendingReviews: () => listPendingReviews
10619
10928
  });
10620
- import path25 from "path";
10621
- import { existsSync as existsSync22, readdirSync as readdirSync5, unlinkSync as unlinkSync6 } from "fs";
10929
+ import path26 from "path";
10930
+ import { existsSync as existsSync23, readdirSync as readdirSync6, unlinkSync as unlinkSync7 } from "fs";
10622
10931
  function formatAge(isoTimestamp) {
10623
10932
  if (!isoTimestamp) return "";
10624
10933
  const ms = Date.now() - new Date(isoTimestamp).getTime();
@@ -10887,11 +11196,11 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
10887
11196
  );
10888
11197
  }
10889
11198
  try {
10890
- const cacheDir = path25.join(EXE_AI_DIR, "session-cache");
10891
- if (existsSync22(cacheDir)) {
10892
- for (const f of readdirSync5(cacheDir)) {
11199
+ const cacheDir = path26.join(EXE_AI_DIR, "session-cache");
11200
+ if (existsSync23(cacheDir)) {
11201
+ for (const f of readdirSync6(cacheDir)) {
10893
11202
  if (f.startsWith("review-notified-")) {
10894
- unlinkSync6(path25.join(cacheDir, f));
11203
+ unlinkSync7(path26.join(cacheDir, f));
10895
11204
  }
10896
11205
  }
10897
11206
  }
@@ -10913,7 +11222,7 @@ var init_tasks_review = __esm({
10913
11222
  });
10914
11223
 
10915
11224
  // src/lib/tasks-chain.ts
10916
- import path26 from "path";
11225
+ import path27 from "path";
10917
11226
  import { readFile as readFile5, writeFile as writeFile6 } from "fs/promises";
10918
11227
  async function cascadeUnblock(taskId, baseDir, now) {
10919
11228
  const client = getClient();
@@ -10930,7 +11239,7 @@ async function cascadeUnblock(taskId, baseDir, now) {
10930
11239
  });
10931
11240
  for (const ur of unblockedRows.rows) {
10932
11241
  try {
10933
- const ubFile = path26.join(baseDir, String(ur.task_file));
11242
+ const ubFile = path27.join(baseDir, String(ur.task_file));
10934
11243
  let ubContent = await readFile5(ubFile, "utf-8");
10935
11244
  ubContent = ubContent.replace(/\*\*Status:\*\* blocked/, "**Status:** open");
10936
11245
  ubContent = ubContent.replace(/\n\*\*Blocked by:\*\*.*\n/, "\n");
@@ -11114,10 +11423,10 @@ async function disposeEmbedder() {
11114
11423
  async function embedDirect(text) {
11115
11424
  const llamaCpp = await import("node-llama-cpp");
11116
11425
  const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
11117
- const { existsSync: existsSync33 } = await import("fs");
11118
- const path47 = await import("path");
11119
- const modelPath = path47.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
11120
- if (!existsSync33(modelPath)) {
11426
+ const { existsSync: existsSync34 } = await import("fs");
11427
+ const path48 = await import("path");
11428
+ const modelPath = path48.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
11429
+ if (!existsSync34(modelPath)) {
11121
11430
  throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
11122
11431
  }
11123
11432
  const llama = await llamaCpp.getLlama();
@@ -11483,8 +11792,8 @@ __export(tasks_exports, {
11483
11792
  updateTaskStatus: () => updateTaskStatus,
11484
11793
  writeCheckpoint: () => writeCheckpoint
11485
11794
  });
11486
- import path27 from "path";
11487
- import { writeFileSync as writeFileSync14, mkdirSync as mkdirSync13, unlinkSync as unlinkSync7 } from "fs";
11795
+ import path28 from "path";
11796
+ import { writeFileSync as writeFileSync14, mkdirSync as mkdirSync14, unlinkSync as unlinkSync8 } from "fs";
11488
11797
  async function createTask(input) {
11489
11798
  const result = await createTaskCore(input);
11490
11799
  if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
@@ -11503,14 +11812,14 @@ async function updateTask(input) {
11503
11812
  const { row, taskFile, now, taskId } = await updateTaskStatus(input);
11504
11813
  try {
11505
11814
  const agent = String(row.assigned_to);
11506
- const cacheDir = path27.join(EXE_AI_DIR, "session-cache");
11507
- const cachePath = path27.join(cacheDir, `current-task-${agent}.json`);
11815
+ const cacheDir = path28.join(EXE_AI_DIR, "session-cache");
11816
+ const cachePath = path28.join(cacheDir, `current-task-${agent}.json`);
11508
11817
  if (input.status === "in_progress") {
11509
- mkdirSync13(cacheDir, { recursive: true });
11818
+ mkdirSync14(cacheDir, { recursive: true });
11510
11819
  writeFileSync14(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
11511
11820
  } else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled" || input.status === "closed") {
11512
11821
  try {
11513
- unlinkSync7(cachePath);
11822
+ unlinkSync8(cachePath);
11514
11823
  } catch {
11515
11824
  }
11516
11825
  }
@@ -11974,14 +12283,14 @@ __export(tmux_routing_exports, {
11974
12283
  spawnEmployee: () => spawnEmployee,
11975
12284
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
11976
12285
  });
11977
- import { execFileSync as execFileSync2, execSync as execSync8 } from "child_process";
11978
- import { readFileSync as readFileSync19, writeFileSync as writeFileSync15, mkdirSync as mkdirSync14, existsSync as existsSync23, appendFileSync as appendFileSync2, readdirSync as readdirSync6 } from "fs";
11979
- import path28 from "path";
12286
+ import { execFileSync as execFileSync2, execSync as execSync9 } from "child_process";
12287
+ import { readFileSync as readFileSync19, writeFileSync as writeFileSync15, mkdirSync as mkdirSync15, existsSync as existsSync24, appendFileSync as appendFileSync2, readdirSync as readdirSync7 } from "fs";
12288
+ import path29 from "path";
11980
12289
  import os15 from "os";
11981
12290
  import { fileURLToPath as fileURLToPath4 } from "url";
11982
- import { unlinkSync as unlinkSync8 } from "fs";
12291
+ import { unlinkSync as unlinkSync9 } from "fs";
11983
12292
  function spawnLockPath(sessionName) {
11984
- return path28.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
12293
+ return path29.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
11985
12294
  }
11986
12295
  function isProcessAlive(pid) {
11987
12296
  try {
@@ -11992,11 +12301,11 @@ function isProcessAlive(pid) {
11992
12301
  }
11993
12302
  }
11994
12303
  function acquireSpawnLock2(sessionName) {
11995
- if (!existsSync23(SPAWN_LOCK_DIR)) {
11996
- mkdirSync14(SPAWN_LOCK_DIR, { recursive: true });
12304
+ if (!existsSync24(SPAWN_LOCK_DIR)) {
12305
+ mkdirSync15(SPAWN_LOCK_DIR, { recursive: true });
11997
12306
  }
11998
12307
  const lockFile = spawnLockPath(sessionName);
11999
- if (existsSync23(lockFile)) {
12308
+ if (existsSync24(lockFile)) {
12000
12309
  try {
12001
12310
  const lock = JSON.parse(readFileSync19(lockFile, "utf8"));
12002
12311
  const age = Date.now() - lock.timestamp;
@@ -12011,20 +12320,20 @@ function acquireSpawnLock2(sessionName) {
12011
12320
  }
12012
12321
  function releaseSpawnLock2(sessionName) {
12013
12322
  try {
12014
- unlinkSync8(spawnLockPath(sessionName));
12323
+ unlinkSync9(spawnLockPath(sessionName));
12015
12324
  } catch {
12016
12325
  }
12017
12326
  }
12018
12327
  function resolveBehaviorsExporterScript() {
12019
12328
  try {
12020
12329
  const thisFile = fileURLToPath4(import.meta.url);
12021
- const scriptPath = path28.join(
12022
- path28.dirname(thisFile),
12330
+ const scriptPath = path29.join(
12331
+ path29.dirname(thisFile),
12023
12332
  "..",
12024
12333
  "bin",
12025
12334
  "exe-export-behaviors.js"
12026
12335
  );
12027
- return existsSync23(scriptPath) ? scriptPath : null;
12336
+ return existsSync24(scriptPath) ? scriptPath : null;
12028
12337
  } catch {
12029
12338
  return null;
12030
12339
  }
@@ -12090,11 +12399,11 @@ function extractRootExe(name) {
12090
12399
  return parts.length > 0 ? parts[parts.length - 1] : null;
12091
12400
  }
12092
12401
  function registerParentExe(sessionKey, parentExe, dispatchedBy) {
12093
- if (!existsSync23(SESSION_CACHE)) {
12094
- mkdirSync14(SESSION_CACHE, { recursive: true });
12402
+ if (!existsSync24(SESSION_CACHE)) {
12403
+ mkdirSync15(SESSION_CACHE, { recursive: true });
12095
12404
  }
12096
12405
  const rootExe = extractRootExe(parentExe) ?? parentExe;
12097
- const filePath = path28.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
12406
+ const filePath = path29.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
12098
12407
  writeFileSync15(filePath, JSON.stringify({
12099
12408
  parentExe: rootExe,
12100
12409
  dispatchedBy: dispatchedBy || rootExe,
@@ -12103,7 +12412,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
12103
12412
  }
12104
12413
  function getParentExe(sessionKey) {
12105
12414
  try {
12106
- const data = JSON.parse(readFileSync19(path28.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
12415
+ const data = JSON.parse(readFileSync19(path29.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
12107
12416
  return data.parentExe || null;
12108
12417
  } catch {
12109
12418
  return null;
@@ -12112,7 +12421,7 @@ function getParentExe(sessionKey) {
12112
12421
  function getDispatchedBy(sessionKey) {
12113
12422
  try {
12114
12423
  const data = JSON.parse(readFileSync19(
12115
- path28.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
12424
+ path29.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
12116
12425
  "utf8"
12117
12426
  ));
12118
12427
  return data.dispatchedBy ?? data.parentExe ?? null;
@@ -12182,7 +12491,7 @@ async function verifyPaneAtCapacity(sessionName) {
12182
12491
  }
12183
12492
  function readDebounceState() {
12184
12493
  try {
12185
- if (!existsSync23(DEBOUNCE_FILE)) return {};
12494
+ if (!existsSync24(DEBOUNCE_FILE)) return {};
12186
12495
  const raw = JSON.parse(readFileSync19(DEBOUNCE_FILE, "utf8"));
12187
12496
  const state = {};
12188
12497
  for (const [key, val] of Object.entries(raw)) {
@@ -12199,7 +12508,7 @@ function readDebounceState() {
12199
12508
  }
12200
12509
  function writeDebounceState(state) {
12201
12510
  try {
12202
- if (!existsSync23(SESSION_CACHE)) mkdirSync14(SESSION_CACHE, { recursive: true });
12511
+ if (!existsSync24(SESSION_CACHE)) mkdirSync15(SESSION_CACHE, { recursive: true });
12203
12512
  writeFileSync15(DEBOUNCE_FILE, JSON.stringify(state));
12204
12513
  } catch {
12205
12514
  }
@@ -12299,8 +12608,8 @@ function sendIntercom(targetSession) {
12299
12608
  try {
12300
12609
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
12301
12610
  const agent = baseAgentName(rawAgent);
12302
- const markerPath = path28.join(SESSION_CACHE, `current-task-${agent}.json`);
12303
- if (existsSync23(markerPath)) {
12611
+ const markerPath = path29.join(SESSION_CACHE, `current-task-${agent}.json`);
12612
+ if (existsSync24(markerPath)) {
12304
12613
  logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker + not idle \u2014 will auto-chain)`);
12305
12614
  return "debounced";
12306
12615
  }
@@ -12310,9 +12619,9 @@ function sendIntercom(targetSession) {
12310
12619
  try {
12311
12620
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
12312
12621
  const agent = baseAgentName(rawAgent);
12313
- const taskDir = path28.join(process.cwd(), "exe", agent);
12314
- if (existsSync23(taskDir)) {
12315
- const files = readdirSync6(taskDir).filter(
12622
+ const taskDir = path29.join(process.cwd(), "exe", agent);
12623
+ if (existsSync24(taskDir)) {
12624
+ const files = readdirSync7(taskDir).filter(
12316
12625
  (f) => f.endsWith(".md") && f !== "DONE.txt"
12317
12626
  );
12318
12627
  if (files.length === 0) {
@@ -12470,23 +12779,23 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
12470
12779
  const transport = getTransport();
12471
12780
  const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
12472
12781
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
12473
- const logDir = path28.join(os15.homedir(), ".exe-os", "session-logs");
12474
- const logFile = path28.join(logDir, `${instanceLabel}-${Date.now()}.log`);
12475
- if (!existsSync23(logDir)) {
12476
- mkdirSync14(logDir, { recursive: true });
12782
+ const logDir = path29.join(os15.homedir(), ".exe-os", "session-logs");
12783
+ const logFile = path29.join(logDir, `${instanceLabel}-${Date.now()}.log`);
12784
+ if (!existsSync24(logDir)) {
12785
+ mkdirSync15(logDir, { recursive: true });
12477
12786
  }
12478
12787
  transport.kill(sessionName);
12479
12788
  let cleanupSuffix = "";
12480
12789
  try {
12481
12790
  const thisFile = fileURLToPath4(import.meta.url);
12482
- const cleanupScript = path28.join(path28.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
12483
- if (existsSync23(cleanupScript)) {
12791
+ const cleanupScript = path29.join(path29.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
12792
+ if (existsSync24(cleanupScript)) {
12484
12793
  cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
12485
12794
  }
12486
12795
  } catch {
12487
12796
  }
12488
12797
  try {
12489
- const claudeJsonPath = path28.join(os15.homedir(), ".claude.json");
12798
+ const claudeJsonPath = path29.join(os15.homedir(), ".claude.json");
12490
12799
  let claudeJson = {};
12491
12800
  try {
12492
12801
  claudeJson = JSON.parse(readFileSync19(claudeJsonPath, "utf8"));
@@ -12501,10 +12810,10 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
12501
12810
  } catch {
12502
12811
  }
12503
12812
  try {
12504
- const settingsDir = path28.join(os15.homedir(), ".claude", "projects");
12813
+ const settingsDir = path29.join(os15.homedir(), ".claude", "projects");
12505
12814
  const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
12506
- const projSettingsDir = path28.join(settingsDir, normalizedKey);
12507
- const settingsPath = path28.join(projSettingsDir, "settings.json");
12815
+ const projSettingsDir = path29.join(settingsDir, normalizedKey);
12816
+ const settingsPath = path29.join(projSettingsDir, "settings.json");
12508
12817
  let settings = {};
12509
12818
  try {
12510
12819
  settings = JSON.parse(readFileSync19(settingsPath, "utf8"));
@@ -12535,7 +12844,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
12535
12844
  if (changed) {
12536
12845
  perms.allow = allow;
12537
12846
  settings.permissions = perms;
12538
- mkdirSync14(projSettingsDir, { recursive: true });
12847
+ mkdirSync15(projSettingsDir, { recursive: true });
12539
12848
  writeFileSync15(settingsPath, JSON.stringify(settings, null, 2) + "\n");
12540
12849
  }
12541
12850
  } catch {
@@ -12551,7 +12860,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
12551
12860
  let behaviorsFlag = "";
12552
12861
  let legacyFallbackWarned = false;
12553
12862
  if (!useExeAgent && !useBinSymlink) {
12554
- const identityPath2 = path28.join(
12863
+ const identityPath2 = path29.join(
12555
12864
  os15.homedir(),
12556
12865
  ".exe-os",
12557
12866
  "identity",
@@ -12561,13 +12870,13 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
12561
12870
  const hasAgentFlag = claudeSupportsAgentFlag();
12562
12871
  if (hasAgentFlag) {
12563
12872
  identityFlag = ` --agent ${employeeName}`;
12564
- } else if (existsSync23(identityPath2)) {
12873
+ } else if (existsSync24(identityPath2)) {
12565
12874
  identityFlag = ` --append-system-prompt-file ${identityPath2}`;
12566
12875
  legacyFallbackWarned = true;
12567
12876
  }
12568
12877
  const behaviorsFile = exportBehaviorsSync(
12569
12878
  employeeName,
12570
- path28.basename(spawnCwd),
12879
+ path29.basename(spawnCwd),
12571
12880
  sessionName
12572
12881
  );
12573
12882
  if (behaviorsFile) {
@@ -12582,9 +12891,9 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
12582
12891
  }
12583
12892
  let sessionContextFlag = "";
12584
12893
  try {
12585
- const ctxDir = path28.join(os15.homedir(), ".exe-os", "session-cache");
12586
- mkdirSync14(ctxDir, { recursive: true });
12587
- const ctxFile = path28.join(ctxDir, `session-context-${sessionName}.md`);
12894
+ const ctxDir = path29.join(os15.homedir(), ".exe-os", "session-cache");
12895
+ mkdirSync15(ctxDir, { recursive: true });
12896
+ const ctxFile = path29.join(ctxDir, `session-context-${sessionName}.md`);
12588
12897
  const ctxContent = [
12589
12898
  `## Session Context`,
12590
12899
  `You are running in tmux session: ${sessionName}.`,
@@ -12670,7 +12979,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
12670
12979
  transport.pipeLog(sessionName, logFile);
12671
12980
  try {
12672
12981
  const mySession = getMySession();
12673
- const dispatchInfo = path28.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
12982
+ const dispatchInfo = path29.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
12674
12983
  writeFileSync15(dispatchInfo, JSON.stringify({
12675
12984
  dispatchedBy: mySession,
12676
12985
  rootExe: exeSession,
@@ -12684,7 +12993,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
12684
12993
  let booted = false;
12685
12994
  for (let i = 0; i < 30; i++) {
12686
12995
  try {
12687
- execSync8("sleep 0.5");
12996
+ execSync9("sleep 0.5");
12688
12997
  } catch {
12689
12998
  }
12690
12999
  try {
@@ -12745,15 +13054,15 @@ var init_tmux_routing = __esm({
12745
13054
  init_intercom_queue();
12746
13055
  init_plan_limits();
12747
13056
  init_employees();
12748
- SPAWN_LOCK_DIR = path28.join(os15.homedir(), ".exe-os", "spawn-locks");
12749
- SESSION_CACHE = path28.join(os15.homedir(), ".exe-os", "session-cache");
13057
+ SPAWN_LOCK_DIR = path29.join(os15.homedir(), ".exe-os", "spawn-locks");
13058
+ SESSION_CACHE = path29.join(os15.homedir(), ".exe-os", "session-cache");
12750
13059
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
12751
13060
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
12752
13061
  VERIFY_PANE_LINES = 200;
12753
13062
  INTERCOM_DEBOUNCE_MS = 3e4;
12754
13063
  CODEX_DEBOUNCE_MS = 12e4;
12755
- INTERCOM_LOG2 = path28.join(os15.homedir(), ".exe-os", "intercom.log");
12756
- DEBOUNCE_FILE = path28.join(SESSION_CACHE, "intercom-debounce.json");
13064
+ INTERCOM_LOG2 = path29.join(os15.homedir(), ".exe-os", "intercom.log");
13065
+ DEBOUNCE_FILE = path29.join(SESSION_CACHE, "intercom-debounce.json");
12757
13066
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
12758
13067
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…|• Working|• Ran |• Explored|• Called|esc to interrupt/;
12759
13068
  }
@@ -13042,9 +13351,9 @@ __export(active_agent_exports, {
13042
13351
  resolveActiveAgentFromTmuxSession: () => resolveActiveAgentFromTmuxSession,
13043
13352
  writeActiveAgent: () => writeActiveAgent
13044
13353
  });
13045
- import { readFileSync as readFileSync20, writeFileSync as writeFileSync16, mkdirSync as mkdirSync15, unlinkSync as unlinkSync9, readdirSync as readdirSync7 } from "fs";
13046
- import { execSync as execSync9 } from "child_process";
13047
- import path29 from "path";
13354
+ import { readFileSync as readFileSync20, writeFileSync as writeFileSync16, mkdirSync as mkdirSync16, unlinkSync as unlinkSync10, readdirSync as readdirSync8 } from "fs";
13355
+ import { execSync as execSync10 } from "child_process";
13356
+ import path30 from "path";
13048
13357
  function isNameWithOptionalInstance(candidate, baseName) {
13049
13358
  if (candidate === baseName) return true;
13050
13359
  if (!candidate.startsWith(baseName)) return false;
@@ -13088,11 +13397,11 @@ function resolveActiveAgentFromTmuxSession(sessionName) {
13088
13397
  return null;
13089
13398
  }
13090
13399
  function getMarkerPath() {
13091
- return path29.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
13400
+ return path30.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
13092
13401
  }
13093
13402
  function writeActiveAgent(agentId, agentRole) {
13094
13403
  try {
13095
- mkdirSync15(CACHE_DIR, { recursive: true });
13404
+ mkdirSync16(CACHE_DIR, { recursive: true });
13096
13405
  writeFileSync16(
13097
13406
  getMarkerPath(),
13098
13407
  JSON.stringify({ agentId, agentRole, startedAt: (/* @__PURE__ */ new Date()).toISOString() })
@@ -13102,7 +13411,7 @@ function writeActiveAgent(agentId, agentRole) {
13102
13411
  }
13103
13412
  function clearActiveAgent() {
13104
13413
  try {
13105
- unlinkSync9(getMarkerPath());
13414
+ unlinkSync10(getMarkerPath());
13106
13415
  } catch {
13107
13416
  }
13108
13417
  }
@@ -13116,7 +13425,7 @@ function getActiveAgent() {
13116
13425
  const age = Date.now() - new Date(data.startedAt).getTime();
13117
13426
  if (age > STALE_MS) {
13118
13427
  try {
13119
- unlinkSync9(markerPath);
13428
+ unlinkSync10(markerPath);
13120
13429
  } catch {
13121
13430
  }
13122
13431
  } else {
@@ -13135,7 +13444,7 @@ function getActiveAgent() {
13135
13444
  } catch {
13136
13445
  }
13137
13446
  try {
13138
- const sessionName = execSync9(
13447
+ const sessionName = execSync10(
13139
13448
  "tmux display-message -p '#{session_name}' 2>/dev/null",
13140
13449
  { encoding: "utf8", timeout: 2e3 }
13141
13450
  ).trim();
@@ -13150,21 +13459,21 @@ function getActiveAgent() {
13150
13459
  }
13151
13460
  function getAllActiveAgents() {
13152
13461
  try {
13153
- const files = readdirSync7(CACHE_DIR);
13462
+ const files = readdirSync8(CACHE_DIR);
13154
13463
  const sessions = [];
13155
13464
  for (const file of files) {
13156
13465
  if (!file.startsWith("active-agent-") || !file.endsWith(".json")) continue;
13157
13466
  const key = file.slice("active-agent-".length, -".json".length);
13158
13467
  if (key === "undefined") continue;
13159
13468
  try {
13160
- const raw = readFileSync20(path29.join(CACHE_DIR, file), "utf8");
13469
+ const raw = readFileSync20(path30.join(CACHE_DIR, file), "utf8");
13161
13470
  const data = JSON.parse(raw);
13162
13471
  if (!data.agentId) continue;
13163
13472
  if (data.startedAt) {
13164
13473
  const age = Date.now() - new Date(data.startedAt).getTime();
13165
13474
  if (age > STALE_MS) {
13166
13475
  try {
13167
- unlinkSync9(path29.join(CACHE_DIR, file));
13476
+ unlinkSync10(path30.join(CACHE_DIR, file));
13168
13477
  } catch {
13169
13478
  }
13170
13479
  continue;
@@ -13187,11 +13496,11 @@ function getAllActiveAgents() {
13187
13496
  function cleanupSessionMarkers() {
13188
13497
  const key = getSessionKey();
13189
13498
  try {
13190
- unlinkSync9(path29.join(CACHE_DIR, `active-agent-${key}.json`));
13499
+ unlinkSync10(path30.join(CACHE_DIR, `active-agent-${key}.json`));
13191
13500
  } catch {
13192
13501
  }
13193
13502
  try {
13194
- unlinkSync9(path29.join(CACHE_DIR, "active-agent-undefined.json"));
13503
+ unlinkSync10(path30.join(CACHE_DIR, "active-agent-undefined.json"));
13195
13504
  } catch {
13196
13505
  }
13197
13506
  }
@@ -13202,7 +13511,7 @@ var init_active_agent = __esm({
13202
13511
  init_config();
13203
13512
  init_session_key();
13204
13513
  init_employees();
13205
- CACHE_DIR = path29.join(EXE_AI_DIR, "session-cache");
13514
+ CACHE_DIR = path30.join(EXE_AI_DIR, "session-cache");
13206
13515
  STALE_MS = 24 * 60 * 60 * 1e3;
13207
13516
  }
13208
13517
  });
@@ -13830,14 +14139,14 @@ __export(exe_rename_exports, {
13830
14139
  main: () => main2,
13831
14140
  renameEmployee: () => renameEmployee
13832
14141
  });
13833
- import { readFileSync as readFileSync21, writeFileSync as writeFileSync17, renameSync as renameSync4, unlinkSync as unlinkSync10, existsSync as existsSync24 } from "fs";
13834
- import { execSync as execSync10 } from "child_process";
13835
- import path30 from "path";
14142
+ import { readFileSync as readFileSync21, writeFileSync as writeFileSync17, renameSync as renameSync4, unlinkSync as unlinkSync11, existsSync as existsSync25 } from "fs";
14143
+ import { execSync as execSync11 } from "child_process";
14144
+ import path31 from "path";
13836
14145
  import { homedir as homedir4 } from "os";
13837
14146
  async function renameEmployee(oldName, newName, opts = {}) {
13838
- const rosterPath = opts.rosterPath ?? path30.join(homedir4(), ".exe-os", "exe-employees.json");
13839
- const identityDir = opts.identityDir ?? path30.join(homedir4(), ".exe-os", "identity");
13840
- const agentsDir = opts.agentsDir ?? path30.join(homedir4(), ".claude", "agents");
14147
+ const rosterPath = opts.rosterPath ?? path31.join(homedir4(), ".exe-os", "exe-employees.json");
14148
+ const identityDir = opts.identityDir ?? path31.join(homedir4(), ".exe-os", "identity");
14149
+ const agentsDir = opts.agentsDir ?? path31.join(homedir4(), ".claude", "agents");
13841
14150
  const validation = validateEmployeeName(newName);
13842
14151
  if (!validation.valid) {
13843
14152
  return { success: false, error: validation.error };
@@ -13869,9 +14178,9 @@ async function renameEmployee(oldName, newName, opts = {}) {
13869
14178
  writeFileSync17(rosterPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
13870
14179
  }
13871
14180
  });
13872
- const oldIdentityPath = path30.join(identityDir, `${rosterOldName}.md`);
13873
- const newIdentityPath = path30.join(identityDir, `${newName}.md`);
13874
- if (existsSync24(oldIdentityPath)) {
14181
+ const oldIdentityPath = path31.join(identityDir, `${rosterOldName}.md`);
14182
+ const newIdentityPath = path31.join(identityDir, `${newName}.md`);
14183
+ if (existsSync25(oldIdentityPath)) {
13875
14184
  const content = readFileSync21(oldIdentityPath, "utf-8");
13876
14185
  const updatedContent = content.replace(
13877
14186
  /^(agent_id:\s*)\S+/m,
@@ -13882,22 +14191,22 @@ async function renameEmployee(oldName, newName, opts = {}) {
13882
14191
  rollbackStack.push({
13883
14192
  description: "restore identity file",
13884
14193
  undo: () => {
13885
- if (existsSync24(newIdentityPath)) {
14194
+ if (existsSync25(newIdentityPath)) {
13886
14195
  writeFileSync17(newIdentityPath, content, "utf-8");
13887
14196
  renameSync4(newIdentityPath, oldIdentityPath);
13888
14197
  }
13889
14198
  }
13890
14199
  });
13891
14200
  }
13892
- const oldAgentPath = path30.join(agentsDir, `${rosterOldName}.md`);
13893
- const newAgentPath = path30.join(agentsDir, `${newName}.md`);
13894
- if (existsSync24(oldAgentPath)) {
14201
+ const oldAgentPath = path31.join(agentsDir, `${rosterOldName}.md`);
14202
+ const newAgentPath = path31.join(agentsDir, `${newName}.md`);
14203
+ if (existsSync25(oldAgentPath)) {
13895
14204
  const agentContent = readFileSync21(oldAgentPath, "utf-8");
13896
14205
  renameSync4(oldAgentPath, newAgentPath);
13897
14206
  rollbackStack.push({
13898
14207
  description: "restore agent file",
13899
14208
  undo: () => {
13900
- if (existsSync24(newAgentPath)) {
14209
+ if (existsSync25(newAgentPath)) {
13901
14210
  renameSync4(newAgentPath, oldAgentPath);
13902
14211
  writeFileSync17(oldAgentPath, agentContent, "utf-8");
13903
14212
  }
@@ -13968,7 +14277,7 @@ async function renameEmployee(oldName, newName, opts = {}) {
13968
14277
  }
13969
14278
  function findExeBin2() {
13970
14279
  try {
13971
- return execSync10(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
14280
+ return execSync11(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
13972
14281
  } catch {
13973
14282
  return null;
13974
14283
  }
@@ -13977,12 +14286,12 @@ function removeOldSymlinks(name) {
13977
14286
  try {
13978
14287
  const exeBinPath = findExeBin2();
13979
14288
  if (!exeBinPath) return;
13980
- const binDir = path30.dirname(exeBinPath);
14289
+ const binDir = path31.dirname(exeBinPath);
13981
14290
  for (const suffix of ["", "-opencode"]) {
13982
- const linkPath = path30.join(binDir, `${name}${suffix}`);
13983
- if (existsSync24(linkPath)) {
14291
+ const linkPath = path31.join(binDir, `${name}${suffix}`);
14292
+ if (existsSync25(linkPath)) {
13984
14293
  try {
13985
- unlinkSync10(linkPath);
14294
+ unlinkSync11(linkPath);
13986
14295
  } catch {
13987
14296
  }
13988
14297
  }
@@ -14025,16 +14334,16 @@ var init_exe_rename = __esm({
14025
14334
  });
14026
14335
 
14027
14336
  // src/lib/model-downloader.ts
14028
- import { createWriteStream, createReadStream as createReadStream2, existsSync as existsSync25, unlinkSync as unlinkSync11, renameSync as renameSync5 } from "fs";
14337
+ import { createWriteStream, createReadStream as createReadStream2, existsSync as existsSync26, unlinkSync as unlinkSync12, renameSync as renameSync5 } from "fs";
14029
14338
  import { mkdir as mkdir6 } from "fs/promises";
14030
14339
  import { createHash as createHash3 } from "crypto";
14031
- import path31 from "path";
14340
+ import path32 from "path";
14032
14341
  async function downloadModel(opts) {
14033
14342
  const { destDir, onProgress, fetchFn = globalThis.fetch } = opts;
14034
- const destPath = path31.join(destDir, LOCAL_FILENAME);
14343
+ const destPath = path32.join(destDir, LOCAL_FILENAME);
14035
14344
  const tmpPath = destPath + ".tmp";
14036
14345
  await mkdir6(destDir, { recursive: true });
14037
- if (existsSync25(destPath)) {
14346
+ if (existsSync26(destPath)) {
14038
14347
  const hash = await fileHash(destPath);
14039
14348
  if (hash === EXPECTED_SHA256) {
14040
14349
  return destPath;
@@ -14046,7 +14355,7 @@ async function downloadModel(opts) {
14046
14355
  let downloaded = 0;
14047
14356
  for (let attempt = 1; attempt <= MAX_RETRIES4; attempt++) {
14048
14357
  try {
14049
- if (existsSync25(tmpPath)) unlinkSync11(tmpPath);
14358
+ if (existsSync26(tmpPath)) unlinkSync12(tmpPath);
14050
14359
  const response = await fetchFn(GGUF_URL, {
14051
14360
  redirect: "follow",
14052
14361
  signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS)
@@ -14078,7 +14387,7 @@ async function downloadModel(opts) {
14078
14387
  }
14079
14388
  const actualHash = hash.digest("hex");
14080
14389
  if (actualHash !== EXPECTED_SHA256) {
14081
- unlinkSync11(tmpPath);
14390
+ unlinkSync12(tmpPath);
14082
14391
  throw new Error(
14083
14392
  `SHA256 mismatch: expected ${EXPECTED_SHA256}, got ${actualHash}`
14084
14393
  );
@@ -14091,7 +14400,7 @@ async function downloadModel(opts) {
14091
14400
  process.stderr.write(`
14092
14401
  Download attempt ${attempt} failed, retrying...
14093
14402
  `);
14094
- if (existsSync25(tmpPath)) unlinkSync11(tmpPath);
14403
+ if (existsSync26(tmpPath)) unlinkSync12(tmpPath);
14095
14404
  }
14096
14405
  }
14097
14406
  }
@@ -14664,28 +14973,28 @@ __export(session_wrappers_exports, {
14664
14973
  generateSessionWrappers: () => generateSessionWrappers
14665
14974
  });
14666
14975
  import {
14667
- existsSync as existsSync26,
14976
+ existsSync as existsSync27,
14668
14977
  readFileSync as readFileSync22,
14669
14978
  writeFileSync as writeFileSync18,
14670
- mkdirSync as mkdirSync16,
14979
+ mkdirSync as mkdirSync17,
14671
14980
  chmodSync as chmodSync2,
14672
- readdirSync as readdirSync8,
14673
- unlinkSync as unlinkSync12
14981
+ readdirSync as readdirSync9,
14982
+ unlinkSync as unlinkSync13
14674
14983
  } from "fs";
14675
- import path32 from "path";
14984
+ import path33 from "path";
14676
14985
  import { homedir as homedir5 } from "os";
14677
14986
  function generateSessionWrappers(packageRoot, homeDir) {
14678
14987
  const home = homeDir ?? homedir5();
14679
- const binDir = path32.join(home, ".exe-os", "bin");
14680
- const rosterPath = path32.join(home, ".exe-os", "exe-employees.json");
14681
- mkdirSync16(binDir, { recursive: true });
14682
- const exeStartDst = path32.join(binDir, "exe-start");
14988
+ const binDir = path33.join(home, ".exe-os", "bin");
14989
+ const rosterPath = path33.join(home, ".exe-os", "exe-employees.json");
14990
+ mkdirSync17(binDir, { recursive: true });
14991
+ const exeStartDst = path33.join(binDir, "exe-start");
14683
14992
  const candidates = [
14684
- path32.join(packageRoot, "dist", "bin", "exe-start.sh"),
14685
- path32.join(packageRoot, "src", "bin", "exe-start.sh")
14993
+ path33.join(packageRoot, "dist", "bin", "exe-start.sh"),
14994
+ path33.join(packageRoot, "src", "bin", "exe-start.sh")
14686
14995
  ];
14687
14996
  for (const src of candidates) {
14688
- if (existsSync26(src)) {
14997
+ if (existsSync27(src)) {
14689
14998
  writeFileSync18(exeStartDst, readFileSync22(src));
14690
14999
  chmodSync2(exeStartDst, 493);
14691
15000
  break;
@@ -14701,13 +15010,13 @@ function generateSessionWrappers(packageRoot, homeDir) {
14701
15010
  return { created: 0, pathConfigured: false };
14702
15011
  }
14703
15012
  try {
14704
- for (const f of readdirSync8(binDir)) {
15013
+ for (const f of readdirSync9(binDir)) {
14705
15014
  if (f === "exe-start") continue;
14706
- const fPath = path32.join(binDir, f);
15015
+ const fPath = path33.join(binDir, f);
14707
15016
  try {
14708
15017
  const content = readFileSync22(fPath, "utf8");
14709
15018
  if (content.includes("exe-start")) {
14710
- unlinkSync12(fPath);
15019
+ unlinkSync13(fPath);
14711
15020
  }
14712
15021
  } catch {
14713
15022
  }
@@ -14720,30 +15029,30 @@ exec "${exeStartDst}" "$0" "$@"
14720
15029
  `;
14721
15030
  for (const emp of employees) {
14722
15031
  for (let n = 1; n <= MAX_N; n++) {
14723
- const wrapperPath = path32.join(binDir, `${emp.name}${n}`);
15032
+ const wrapperPath = path33.join(binDir, `${emp.name}${n}`);
14724
15033
  writeFileSync18(wrapperPath, wrapperContent);
14725
15034
  chmodSync2(wrapperPath, 493);
14726
15035
  created++;
14727
- const codexPath = path32.join(binDir, `${emp.name}${n}-codex`);
15036
+ const codexPath = path33.join(binDir, `${emp.name}${n}-codex`);
14728
15037
  writeFileSync18(codexPath, wrapperContent);
14729
15038
  chmodSync2(codexPath, 493);
14730
15039
  created++;
14731
15040
  }
14732
15041
  }
14733
15042
  const codexLauncherCandidates = [
14734
- path32.join(packageRoot, "dist", "bin", "exe-start-codex.js"),
14735
- path32.join(packageRoot, "src", "bin", "exe-start-codex.ts")
15043
+ path33.join(packageRoot, "dist", "bin", "exe-start-codex.js"),
15044
+ path33.join(packageRoot, "src", "bin", "exe-start-codex.ts")
14736
15045
  ];
14737
15046
  let codexLauncher = null;
14738
15047
  for (const c of codexLauncherCandidates) {
14739
- if (existsSync26(c)) {
15048
+ if (existsSync27(c)) {
14740
15049
  codexLauncher = c;
14741
15050
  break;
14742
15051
  }
14743
15052
  }
14744
15053
  if (codexLauncher) {
14745
15054
  for (const emp of employees) {
14746
- const wrapperPath = path32.join(binDir, `${emp.name}-codex`);
15055
+ const wrapperPath = path33.join(binDir, `${emp.name}-codex`);
14747
15056
  const content = `#!/bin/bash
14748
15057
  exec node "${codexLauncher}" --agent ${emp.name} "$@"
14749
15058
  `;
@@ -14766,12 +15075,12 @@ export PATH="${binDir}:$PATH"
14766
15075
  const shell = process.env.SHELL ?? "/bin/bash";
14767
15076
  const profilePaths = [];
14768
15077
  if (shell.includes("zsh")) {
14769
- profilePaths.push(path32.join(home, ".zshrc"));
15078
+ profilePaths.push(path33.join(home, ".zshrc"));
14770
15079
  } else if (shell.includes("bash")) {
14771
- profilePaths.push(path32.join(home, ".bashrc"));
14772
- profilePaths.push(path32.join(home, ".bash_profile"));
15080
+ profilePaths.push(path33.join(home, ".bashrc"));
15081
+ profilePaths.push(path33.join(home, ".bash_profile"));
14773
15082
  } else {
14774
- profilePaths.push(path32.join(home, ".profile"));
15083
+ profilePaths.push(path33.join(home, ".profile"));
14775
15084
  }
14776
15085
  for (const profilePath of profilePaths) {
14777
15086
  try {
@@ -14806,23 +15115,23 @@ __export(setup_wizard_exports, {
14806
15115
  validateModel: () => validateModel
14807
15116
  });
14808
15117
  import crypto12 from "crypto";
14809
- import { existsSync as existsSync27, mkdirSync as mkdirSync17, readFileSync as readFileSync23, writeFileSync as writeFileSync19, unlinkSync as unlinkSync13 } from "fs";
15118
+ import { existsSync as existsSync28, mkdirSync as mkdirSync18, readFileSync as readFileSync23, writeFileSync as writeFileSync19, unlinkSync as unlinkSync14 } from "fs";
14810
15119
  import os16 from "os";
14811
- import path33 from "path";
15120
+ import path34 from "path";
14812
15121
  import { createInterface as createInterface3 } from "readline";
14813
15122
  function findPackageRoot2() {
14814
- let dir = path33.dirname(new URL(import.meta.url).pathname);
14815
- const root = path33.parse(dir).root;
15123
+ let dir = path34.dirname(new URL(import.meta.url).pathname);
15124
+ const root = path34.parse(dir).root;
14816
15125
  while (dir !== root) {
14817
- const pkgPath = path33.join(dir, "package.json");
14818
- if (existsSync27(pkgPath)) {
15126
+ const pkgPath = path34.join(dir, "package.json");
15127
+ if (existsSync28(pkgPath)) {
14819
15128
  try {
14820
15129
  const pkg = JSON.parse(readFileSync23(pkgPath, "utf-8"));
14821
15130
  if (pkg.name === "@askexenow/exe-os" || pkg.name === "exe-os") return dir;
14822
15131
  } catch {
14823
15132
  }
14824
15133
  }
14825
- dir = path33.dirname(dir);
15134
+ dir = path34.dirname(dir);
14826
15135
  }
14827
15136
  return null;
14828
15137
  }
@@ -14834,12 +15143,12 @@ function loadSetupState() {
14834
15143
  }
14835
15144
  }
14836
15145
  function saveSetupState(state) {
14837
- mkdirSync17(path33.dirname(SETUP_STATE_PATH), { recursive: true });
15146
+ mkdirSync18(path34.dirname(SETUP_STATE_PATH), { recursive: true });
14838
15147
  writeFileSync19(SETUP_STATE_PATH, JSON.stringify(state, null, 2));
14839
15148
  }
14840
15149
  function clearSetupState() {
14841
15150
  try {
14842
- unlinkSync13(SETUP_STATE_PATH);
15151
+ unlinkSync14(SETUP_STATE_PATH);
14843
15152
  } catch {
14844
15153
  }
14845
15154
  }
@@ -14856,8 +15165,8 @@ function ask2(rl, prompt) {
14856
15165
  function getAvailableMemoryGB2() {
14857
15166
  if (process.platform === "darwin") {
14858
15167
  try {
14859
- const { execSync: execSync15 } = __require("child_process");
14860
- const vmstat = execSync15("vm_stat", { encoding: "utf8" });
15168
+ const { execSync: execSync16 } = __require("child_process");
15169
+ const vmstat = execSync16("vm_stat", { encoding: "utf8" });
14861
15170
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
14862
15171
  const pageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : 16384;
14863
15172
  const free = vmstat.match(/Pages free:\s+(\d+)/);
@@ -14885,10 +15194,10 @@ async function validateModel(log) {
14885
15194
  if (totalGB <= 8 || isLowMemory()) {
14886
15195
  log(`System memory: ${totalGB.toFixed(0)}GB total, ${freeGB.toFixed(1)}GB free`);
14887
15196
  log("Skipping in-memory model validation (low memory \u2014 will validate on first use).");
14888
- const modelPath = path33.join(MODELS_DIR, LOCAL_FILENAME);
14889
- if (existsSync27(modelPath)) {
14890
- const { statSync: statSync2 } = await import("fs");
14891
- const size = statSync2(modelPath).size;
15197
+ const modelPath = path34.join(MODELS_DIR, LOCAL_FILENAME);
15198
+ if (existsSync28(modelPath)) {
15199
+ const { statSync: statSync3 } = await import("fs");
15200
+ const size = statSync3(modelPath).size;
14892
15201
  if (size > 300 * 1e6) {
14893
15202
  log(`Model file verified (${(size / 1e6).toFixed(0)} MB).`);
14894
15203
  return;
@@ -14977,7 +15286,7 @@ async function runSetupWizard(opts = {}) {
14977
15286
  if (state.completedSteps.length > 0) {
14978
15287
  log(`Resuming setup from step ${Math.max(...state.completedSteps) + 1}...`);
14979
15288
  }
14980
- if (existsSync27(LEGACY_LANCE_PATH)) {
15289
+ if (existsSync28(LEGACY_LANCE_PATH)) {
14981
15290
  log("\u26A0 Found v1.0 LanceDB at ~/.exe-os/local.lance");
14982
15291
  log(" v1.1 uses libSQL (SQLite). Your existing memories are not automatically migrated.");
14983
15292
  log(" The old directory will not be modified or deleted.");
@@ -14992,6 +15301,23 @@ async function runSetupWizard(opts = {}) {
14992
15301
  const key = crypto12.randomBytes(32);
14993
15302
  await setMasterKey(key);
14994
15303
  log("Encryption key generated and stored securely.");
15304
+ log("");
15305
+ const { exportMnemonic: exportMnemonic2 } = await Promise.resolve().then(() => (init_keychain(), keychain_exports));
15306
+ const mnemonic = await exportMnemonic2(key);
15307
+ log("=============================================================");
15308
+ log(" YOUR 24-WORD RECOVERY PHRASE");
15309
+ log("=============================================================");
15310
+ log("");
15311
+ log(" " + mnemonic);
15312
+ log("");
15313
+ log(" SAVE THIS NOW. Write it down or store it in your password");
15314
+ log(" manager. This phrase is the ONLY way to decrypt your memories");
15315
+ log(" if you lose this computer. We cannot recover it for you.");
15316
+ log("");
15317
+ log(" Like a Bitcoin wallet \u2014 lose the phrase, lose everything.");
15318
+ log("=============================================================");
15319
+ log("");
15320
+ await ask2(rl, "Press Enter after you've saved your recovery phrase...");
14995
15321
  }
14996
15322
  state.completedSteps.push(1);
14997
15323
  saveSetupState(state);
@@ -15141,7 +15467,7 @@ async function runSetupWizard(opts = {}) {
15141
15467
  await saveConfig(config);
15142
15468
  log("");
15143
15469
  try {
15144
- const claudeJsonPath = path33.join(os16.homedir(), ".claude.json");
15470
+ const claudeJsonPath = path34.join(os16.homedir(), ".claude.json");
15145
15471
  let claudeJson = {};
15146
15472
  try {
15147
15473
  claudeJson = JSON.parse(readFileSync23(claudeJsonPath, "utf8"));
@@ -15167,7 +15493,7 @@ async function runSetupWizard(opts = {}) {
15167
15493
  const prefs = { ...existingPrefs };
15168
15494
  log("=== Config Defaults ===");
15169
15495
  log("");
15170
- const ghosttyDetected = existsSync27(path33.join(os16.homedir(), ".config", "ghostty")) || existsSync27(path33.join(os16.homedir(), "Library", "Application Support", "com.mitchellh.ghostty"));
15496
+ const ghosttyDetected = existsSync28(path34.join(os16.homedir(), ".config", "ghostty")) || existsSync28(path34.join(os16.homedir(), "Library", "Application Support", "com.mitchellh.ghostty"));
15171
15497
  if (ghosttyDetected) {
15172
15498
  const ghosttyAnswer = await ask2(rl, "Detected Ghostty terminal. Use exe-os Ghostty defaults? (Y/n) ");
15173
15499
  prefs.ghostty = ghosttyAnswer.toLowerCase() !== "n";
@@ -15214,7 +15540,7 @@ async function runSetupWizard(opts = {}) {
15214
15540
  let missingIdentities = [];
15215
15541
  for (const emp of roster) {
15216
15542
  const idPath = identityPath2(emp.name);
15217
- if (!existsSync27(idPath)) {
15543
+ if (!existsSync28(idPath)) {
15218
15544
  missingIdentities.push(emp.name);
15219
15545
  }
15220
15546
  }
@@ -15246,7 +15572,7 @@ async function runSetupWizard(opts = {}) {
15246
15572
  }
15247
15573
  missingIdentities = [];
15248
15574
  for (const emp of roster) {
15249
- if (!existsSync27(identityPath2(emp.name))) {
15575
+ if (!existsSync28(identityPath2(emp.name))) {
15250
15576
  missingIdentities.push(emp.name);
15251
15577
  }
15252
15578
  }
@@ -15311,7 +15637,7 @@ async function runSetupWizard(opts = {}) {
15311
15637
  const cooIdentityContent = getIdentityTemplate("coo");
15312
15638
  if (cooIdentityContent) {
15313
15639
  const cooIdPath = identityPath2(cooName);
15314
- mkdirSync17(path33.dirname(cooIdPath), { recursive: true });
15640
+ mkdirSync18(path34.dirname(cooIdPath), { recursive: true });
15315
15641
  const replaced = cooIdentityContent.replace(/agent_id:\s*exe/g, `agent_id: ${cooName}`).replace(/\$\{agent_id\}/g, cooName);
15316
15642
  writeFileSync19(cooIdPath, replaced, "utf-8");
15317
15643
  }
@@ -15407,7 +15733,7 @@ async function runSetupWizard(opts = {}) {
15407
15733
  const ctoIdentityContent = getIdentityTemplate("cto");
15408
15734
  if (ctoIdentityContent) {
15409
15735
  const ctoIdPath = identityPath2(ctoName);
15410
- mkdirSync17(path33.dirname(ctoIdPath), { recursive: true });
15736
+ mkdirSync18(path34.dirname(ctoIdPath), { recursive: true });
15411
15737
  const replaced = ctoIdentityContent.replace(/agent_id:\s*\w+/g, `agent_id: ${ctoName}`).replace(/\$\{agent_id\}/g, ctoName);
15412
15738
  writeFileSync19(ctoIdPath, replaced, "utf-8");
15413
15739
  }
@@ -15430,7 +15756,7 @@ async function runSetupWizard(opts = {}) {
15430
15756
  const cmoIdentityContent = getIdentityTemplate("cmo");
15431
15757
  if (cmoIdentityContent) {
15432
15758
  const cmoIdPath = identityPath2(cmoName);
15433
- mkdirSync17(path33.dirname(cmoIdPath), { recursive: true });
15759
+ mkdirSync18(path34.dirname(cmoIdPath), { recursive: true });
15434
15760
  const replaced = cmoIdentityContent.replace(/agent_id:\s*\w+/g, `agent_id: ${cmoName}`).replace(/\$\{agent_id\}/g, cmoName);
15435
15761
  writeFileSync19(cmoIdPath, replaced, "utf-8");
15436
15762
  }
@@ -15454,7 +15780,7 @@ async function runSetupWizard(opts = {}) {
15454
15780
  log(`Session shortcuts generated (${cooName}1, ${cooName}2, ...)`);
15455
15781
  }
15456
15782
  if (wrapResult.pathConfigured) {
15457
- const binDir = path33.join(os16.homedir(), ".exe-os", "bin");
15783
+ const binDir = path34.join(os16.homedir(), ".exe-os", "bin");
15458
15784
  process.env.PATH = `${binDir}:${process.env.PATH ?? ""}`;
15459
15785
  pathJustConfigured = true;
15460
15786
  }
@@ -15497,7 +15823,7 @@ async function runSetupWizard(opts = {}) {
15497
15823
  const pkgRoot2 = findPackageRoot2();
15498
15824
  if (pkgRoot2) {
15499
15825
  try {
15500
- version = JSON.parse(readFileSync23(path33.join(pkgRoot2, "package.json"), "utf-8")).version;
15826
+ version = JSON.parse(readFileSync23(path34.join(pkgRoot2, "package.json"), "utf-8")).version;
15501
15827
  } catch {
15502
15828
  }
15503
15829
  }
@@ -15531,32 +15857,32 @@ var init_setup_wizard = __esm({
15531
15857
  init_config();
15532
15858
  init_keychain();
15533
15859
  init_model_downloader();
15534
- SETUP_STATE_PATH = path33.join(os16.homedir(), ".exe-os", "setup-state.json");
15860
+ SETUP_STATE_PATH = path34.join(os16.homedir(), ".exe-os", "setup-state.json");
15535
15861
  }
15536
15862
  });
15537
15863
 
15538
15864
  // src/lib/update-backup.ts
15539
15865
  import { copyFile, readFile as readFile6, readdir as readdir3, writeFile as writeFile7, rm, mkdir as mkdir7, cp } from "fs/promises";
15540
- import { existsSync as existsSync28 } from "fs";
15541
- import path34 from "path";
15866
+ import { existsSync as existsSync29 } from "fs";
15867
+ import path35 from "path";
15542
15868
  import os17 from "os";
15543
15869
  function resolveDataDir2() {
15544
15870
  if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
15545
15871
  if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
15546
- return path34.join(os17.homedir(), ".exe-os");
15872
+ return path35.join(os17.homedir(), ".exe-os");
15547
15873
  }
15548
15874
  async function createUpdateBackup(currentVersion, dataDir) {
15549
15875
  const dir = dataDir ?? resolveDataDir2();
15550
- const backupDir = path34.join(dir, BACKUP_DIR_NAME);
15551
- if (existsSync28(backupDir)) {
15876
+ const backupDir = path35.join(dir, BACKUP_DIR_NAME);
15877
+ if (existsSync29(backupDir)) {
15552
15878
  await rm(backupDir, { recursive: true, force: true });
15553
15879
  }
15554
15880
  await mkdir7(backupDir, { recursive: true });
15555
15881
  const backedUpFiles = [];
15556
15882
  for (const target of BACKUP_TARGETS) {
15557
- const src = path34.join(dir, target.name);
15558
- if (!existsSync28(src)) continue;
15559
- const dest = path34.join(backupDir, target.name);
15883
+ const src = path35.join(dir, target.name);
15884
+ if (!existsSync29(src)) continue;
15885
+ const dest = path35.join(backupDir, target.name);
15560
15886
  if (target.type === "file") {
15561
15887
  await copyFile(src, dest);
15562
15888
  } else {
@@ -15567,8 +15893,8 @@ async function createUpdateBackup(currentVersion, dataDir) {
15567
15893
  const entries = await readdir3(dir, { withFileTypes: true });
15568
15894
  for (const entry of entries) {
15569
15895
  if (entry.isFile() && entry.name.endsWith(".db") && entry.name !== BACKUP_DIR_NAME) {
15570
- const src = path34.join(dir, entry.name);
15571
- const dest = path34.join(backupDir, entry.name);
15896
+ const src = path35.join(dir, entry.name);
15897
+ const dest = path35.join(backupDir, entry.name);
15572
15898
  await copyFile(src, dest);
15573
15899
  backedUpFiles.push(entry.name);
15574
15900
  }
@@ -15579,16 +15905,16 @@ async function createUpdateBackup(currentVersion, dataDir) {
15579
15905
  files: backedUpFiles
15580
15906
  };
15581
15907
  await writeFile7(
15582
- path34.join(backupDir, "manifest.json"),
15908
+ path35.join(backupDir, "manifest.json"),
15583
15909
  JSON.stringify(manifest, null, 2) + "\n"
15584
15910
  );
15585
15911
  return manifest;
15586
15912
  }
15587
15913
  async function restoreFromBackup(dataDir) {
15588
15914
  const dir = dataDir ?? resolveDataDir2();
15589
- const backupDir = path34.join(dir, BACKUP_DIR_NAME);
15590
- const manifestPath = path34.join(backupDir, "manifest.json");
15591
- if (!existsSync28(manifestPath)) {
15915
+ const backupDir = path35.join(dir, BACKUP_DIR_NAME);
15916
+ const manifestPath = path35.join(backupDir, "manifest.json");
15917
+ if (!existsSync29(manifestPath)) {
15592
15918
  throw new Error(
15593
15919
  `No backup found at ${backupDir}. Nothing to restore.`
15594
15920
  );
@@ -15597,9 +15923,9 @@ async function restoreFromBackup(dataDir) {
15597
15923
  await readFile6(manifestPath, "utf-8")
15598
15924
  );
15599
15925
  for (const fileName of manifest.files) {
15600
- const src = path34.join(backupDir, fileName);
15601
- const dest = path34.join(dir, fileName);
15602
- if (!existsSync28(src)) continue;
15926
+ const src = path35.join(backupDir, fileName);
15927
+ const dest = path35.join(dir, fileName);
15928
+ if (!existsSync29(src)) continue;
15603
15929
  const stat2 = await import("fs/promises").then((m) => m.stat(src));
15604
15930
  if (stat2.isDirectory()) {
15605
15931
  await cp(src, dest, { recursive: true, force: true });
@@ -15611,8 +15937,8 @@ async function restoreFromBackup(dataDir) {
15611
15937
  }
15612
15938
  async function deleteBackup(dataDir) {
15613
15939
  const dir = dataDir ?? resolveDataDir2();
15614
- const backupDir = path34.join(dir, BACKUP_DIR_NAME);
15615
- if (existsSync28(backupDir)) {
15940
+ const backupDir = path35.join(dir, BACKUP_DIR_NAME);
15941
+ if (existsSync29(backupDir)) {
15616
15942
  await rm(backupDir, { recursive: true, force: true });
15617
15943
  }
15618
15944
  }
@@ -15632,17 +15958,17 @@ var init_update_backup = __esm({
15632
15958
  });
15633
15959
 
15634
15960
  // src/lib/update-check.ts
15635
- import { execSync as execSync11 } from "child_process";
15961
+ import { execSync as execSync12 } from "child_process";
15636
15962
  import { readFileSync as readFileSync24 } from "fs";
15637
- import path35 from "path";
15963
+ import path36 from "path";
15638
15964
  function getLocalVersion(packageRoot) {
15639
- const pkgPath = path35.join(packageRoot, "package.json");
15965
+ const pkgPath = path36.join(packageRoot, "package.json");
15640
15966
  const pkg = JSON.parse(readFileSync24(pkgPath, "utf-8"));
15641
15967
  return pkg.version;
15642
15968
  }
15643
15969
  function getRemoteVersion() {
15644
15970
  try {
15645
- const output = execSync11("npm view @askexenow/exe-os version", {
15971
+ const output = execSync12("npm view @askexenow/exe-os version", {
15646
15972
  encoding: "utf-8",
15647
15973
  timeout: 15e3,
15648
15974
  stdio: ["pipe", "pipe", "pipe"]
@@ -15681,7 +16007,7 @@ __export(update_exports, {
15681
16007
  getRemoteVersion: () => getRemoteVersion,
15682
16008
  runUpdate: () => runUpdate
15683
16009
  });
15684
- import { execSync as execSync12 } from "child_process";
16010
+ import { execSync as execSync13 } from "child_process";
15685
16011
  import { createInterface as createInterface4 } from "readline";
15686
16012
  async function runRestore() {
15687
16013
  console.log("\n\u{1F504} Restoring from update backup...");
@@ -15692,7 +16018,7 @@ async function runRestore() {
15692
16018
  console.log(`
15693
16019
  \u{1F4E5} Reinstalling @askexenow/exe-os@${manifest.version}...`);
15694
16020
  try {
15695
- execSync12(`npm install -g @askexenow/exe-os@${manifest.version}`, {
16021
+ execSync13(`npm install -g @askexenow/exe-os@${manifest.version}`, {
15696
16022
  stdio: ["pipe", "pipe", "inherit"],
15697
16023
  timeout: 3e5
15698
16024
  });
@@ -15769,7 +16095,7 @@ async function runUpdate(cliArgs) {
15769
16095
  }
15770
16096
  console.log("\u{1F9F9} Clearing npm cache...");
15771
16097
  try {
15772
- execSync12("npm cache clean --force", { stdio: "pipe" });
16098
+ execSync13("npm cache clean --force", { stdio: "pipe" });
15773
16099
  console.log(" Done");
15774
16100
  } catch {
15775
16101
  console.log(" Skipped (non-critical)");
@@ -15777,7 +16103,7 @@ async function runUpdate(cliArgs) {
15777
16103
  console.log("\u{1F4E5} Installing @askexenow/exe-os@latest...");
15778
16104
  console.log(" This may take a minute...\n");
15779
16105
  try {
15780
- execSync12("npm install -g @askexenow/exe-os@latest", {
16106
+ execSync13("npm install -g @askexenow/exe-os@latest", {
15781
16107
  stdio: ["pipe", "pipe", "inherit"],
15782
16108
  timeout: 3e5
15783
16109
  });
@@ -15795,7 +16121,7 @@ async function runUpdate(cliArgs) {
15795
16121
  newVersion = getLocalVersion(packageRoot);
15796
16122
  } catch {
15797
16123
  try {
15798
- const out = execSync12("npm list -g @askexenow/exe-os --depth=0 2>/dev/null", { encoding: "utf8" });
16124
+ const out = execSync13("npm list -g @askexenow/exe-os --depth=0 2>/dev/null", { encoding: "utf8" });
15799
16125
  const match = out.match(/@askexenow\/exe-os@(\S+)/);
15800
16126
  newVersion = match?.[1] ?? "unknown";
15801
16127
  } catch {
@@ -20220,8 +20546,8 @@ var init_ErrorOverview = __esm({
20220
20546
  "use strict";
20221
20547
  init_Box();
20222
20548
  init_Text();
20223
- cleanupPath = (path47) => {
20224
- return path47?.replace(`file://${cwd()}/`, "");
20549
+ cleanupPath = (path48) => {
20550
+ return path48?.replace(`file://${cwd()}/`, "");
20225
20551
  };
20226
20552
  stackUtils = new StackUtils({
20227
20553
  cwd: cwd(),
@@ -22325,13 +22651,13 @@ __export(tmux_status_exports, {
22325
22651
  parseActivity: () => parseActivity,
22326
22652
  parseContextPercentage: () => parseContextPercentage
22327
22653
  });
22328
- import { execSync as execSync13 } from "child_process";
22654
+ import { execSync as execSync14 } from "child_process";
22329
22655
  function inTmux() {
22330
22656
  if (process.env.TMUX || process.env.TMUX_PANE) return true;
22331
22657
  const term = process.env.TERM ?? "";
22332
22658
  if (term.startsWith("tmux") || term.startsWith("screen")) return true;
22333
22659
  try {
22334
- execSync13("tmux display-message -p '#{session_name}' 2>/dev/null", {
22660
+ execSync14("tmux display-message -p '#{session_name}' 2>/dev/null", {
22335
22661
  encoding: "utf8",
22336
22662
  timeout: 2e3
22337
22663
  });
@@ -22341,12 +22667,12 @@ function inTmux() {
22341
22667
  try {
22342
22668
  let pid = process.ppid;
22343
22669
  for (let depth = 0; depth < 8 && pid > 1; depth++) {
22344
- const comm = execSync13(`ps -p ${pid} -o comm= 2>/dev/null`, {
22670
+ const comm = execSync14(`ps -p ${pid} -o comm= 2>/dev/null`, {
22345
22671
  encoding: "utf8",
22346
22672
  timeout: 1e3
22347
22673
  }).trim();
22348
22674
  if (/tmux/.test(comm)) return true;
22349
- const ppid = execSync13(`ps -p ${pid} -o ppid= 2>/dev/null`, {
22675
+ const ppid = execSync14(`ps -p ${pid} -o ppid= 2>/dev/null`, {
22350
22676
  encoding: "utf8",
22351
22677
  timeout: 1e3
22352
22678
  }).trim();
@@ -22359,7 +22685,7 @@ function inTmux() {
22359
22685
  }
22360
22686
  function listTmuxSessions() {
22361
22687
  try {
22362
- const out = execSync13("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
22688
+ const out = execSync14("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
22363
22689
  encoding: "utf8",
22364
22690
  timeout: 3e3
22365
22691
  });
@@ -22370,7 +22696,7 @@ function listTmuxSessions() {
22370
22696
  }
22371
22697
  function capturePaneLines(windowName, lines = 10) {
22372
22698
  try {
22373
- const out = execSync13(
22699
+ const out = execSync14(
22374
22700
  `tmux capture-pane -t ${JSON.stringify(windowName)} -p 2>/dev/null | tail -${lines}`,
22375
22701
  { encoding: "utf8", timeout: 3e3 }
22376
22702
  );
@@ -22381,7 +22707,7 @@ function capturePaneLines(windowName, lines = 10) {
22381
22707
  }
22382
22708
  function getPaneCwd(windowName) {
22383
22709
  try {
22384
- const out = execSync13(
22710
+ const out = execSync14(
22385
22711
  `tmux display-message -t ${JSON.stringify(windowName)} -p '#{pane_current_path}' 2>/dev/null`,
22386
22712
  { encoding: "utf8", timeout: 3e3 }
22387
22713
  );
@@ -22392,7 +22718,7 @@ function getPaneCwd(windowName) {
22392
22718
  }
22393
22719
  function projectFromPath(dir) {
22394
22720
  try {
22395
- const root = execSync13("git -C " + JSON.stringify(dir) + " rev-parse --show-toplevel 2>/dev/null", {
22721
+ const root = execSync14("git -C " + JSON.stringify(dir) + " rev-parse --show-toplevel 2>/dev/null", {
22396
22722
  encoding: "utf8",
22397
22723
  timeout: 3e3
22398
22724
  }).trim();
@@ -22461,7 +22787,7 @@ function getEmployeeStatuses(employeeNames) {
22461
22787
  }
22462
22788
  let paneAlive = true;
22463
22789
  try {
22464
- const paneStatus = execSync13(
22790
+ const paneStatus = execSync14(
22465
22791
  `tmux list-panes -t ${JSON.stringify(sessionName)} -F '#{pane_dead}' 2>/dev/null`,
22466
22792
  { encoding: "utf8", timeout: 3e3 }
22467
22793
  ).trim();
@@ -22629,11 +22955,11 @@ function Footer() {
22629
22955
  } catch {
22630
22956
  }
22631
22957
  try {
22632
- const { existsSync: existsSync33 } = await import("fs");
22958
+ const { existsSync: existsSync34 } = await import("fs");
22633
22959
  const { join } = await import("path");
22634
22960
  const home = process.env.HOME ?? "";
22635
22961
  const pidPath = join(home, ".exe-os", "exed.pid");
22636
- setDaemon(existsSync33(pidPath) ? "running" : "stopped");
22962
+ setDaemon(existsSync34(pidPath) ? "running" : "stopped");
22637
22963
  } catch {
22638
22964
  setDaemon("unknown");
22639
22965
  }
@@ -22651,8 +22977,8 @@ function Footer() {
22651
22977
  setSessions(allSessions.length);
22652
22978
  if (!currentSession) {
22653
22979
  try {
22654
- const { execSync: execSync15 } = await import("child_process");
22655
- const name = execSync15("tmux display-message -p '#{session_name}' 2>/dev/null", {
22980
+ const { execSync: execSync16 } = await import("child_process");
22981
+ const name = execSync16("tmux display-message -p '#{session_name}' 2>/dev/null", {
22656
22982
  encoding: "utf8",
22657
22983
  timeout: 2e3
22658
22984
  }).trim();
@@ -24684,10 +25010,10 @@ var init_hooks = __esm({
24684
25010
  });
24685
25011
 
24686
25012
  // src/runtime/safety-checks.ts
24687
- import path36 from "path";
25013
+ import path37 from "path";
24688
25014
  import os18 from "os";
24689
25015
  function checkPathSafety(filePath) {
24690
- const resolved = path36.resolve(filePath);
25016
+ const resolved = path37.resolve(filePath);
24691
25017
  for (const { pattern, reason } of BYPASS_IMMUNE_PATTERNS) {
24692
25018
  const matches = typeof pattern === "function" ? pattern(resolved) : pattern.test(resolved);
24693
25019
  if (matches) {
@@ -24697,7 +25023,7 @@ function checkPathSafety(filePath) {
24697
25023
  return { safe: true, bypassImmune: true };
24698
25024
  }
24699
25025
  function checkReadPathSafety(filePath) {
24700
- const resolved = path36.resolve(filePath);
25026
+ const resolved = path37.resolve(filePath);
24701
25027
  const credPatterns = BYPASS_IMMUNE_PATTERNS.filter(
24702
25028
  (p) => typeof p.pattern !== "function" && (p.reason.includes("secrets") || p.reason.includes("Private key") || p.reason.includes("Credential"))
24703
25029
  );
@@ -24723,11 +25049,11 @@ var init_safety_checks = __esm({
24723
25049
  reason: "Git config can set hooks and command execution"
24724
25050
  },
24725
25051
  {
24726
- pattern: (p) => p.startsWith(path36.join(HOME, ".claude")),
25052
+ pattern: (p) => p.startsWith(path37.join(HOME, ".claude")),
24727
25053
  reason: "Claude configuration files are protected"
24728
25054
  },
24729
25055
  {
24730
- pattern: (p) => p.startsWith(path36.join(HOME, ".exe-os")),
25056
+ pattern: (p) => p.startsWith(path37.join(HOME, ".exe-os")),
24731
25057
  reason: "exe-os configuration files are protected"
24732
25058
  },
24733
25059
  {
@@ -24744,7 +25070,7 @@ var init_safety_checks = __esm({
24744
25070
  },
24745
25071
  {
24746
25072
  pattern: (p) => {
24747
- const name = path36.basename(p);
25073
+ const name = path37.basename(p);
24748
25074
  return [".bashrc", ".zshrc", ".profile", ".bash_profile", ".zprofile", ".zshenv"].includes(name);
24749
25075
  },
24750
25076
  reason: "Shell configuration files can execute arbitrary code on login"
@@ -24771,7 +25097,7 @@ __export(file_read_exports, {
24771
25097
  FileReadTool: () => FileReadTool
24772
25098
  });
24773
25099
  import fs3 from "fs/promises";
24774
- import path37 from "path";
25100
+ import path38 from "path";
24775
25101
  import { z } from "zod";
24776
25102
  function isBinary(buf) {
24777
25103
  for (let i = 0; i < buf.length; i++) {
@@ -24807,7 +25133,7 @@ var init_file_read = __esm({
24807
25133
  return { behavior: "allow" };
24808
25134
  },
24809
25135
  async call(input, context) {
24810
- const filePath = path37.isAbsolute(input.file_path) ? input.file_path : path37.resolve(context.cwd, input.file_path);
25136
+ const filePath = path38.isAbsolute(input.file_path) ? input.file_path : path38.resolve(context.cwd, input.file_path);
24811
25137
  let stat2;
24812
25138
  try {
24813
25139
  stat2 = await fs3.stat(filePath);
@@ -24847,7 +25173,7 @@ __export(glob_exports, {
24847
25173
  GlobTool: () => GlobTool
24848
25174
  });
24849
25175
  import fs4 from "fs/promises";
24850
- import path38 from "path";
25176
+ import path39 from "path";
24851
25177
  import { z as z2 } from "zod";
24852
25178
  async function walkDir(dir, maxDepth = 10) {
24853
25179
  const results = [];
@@ -24863,7 +25189,7 @@ async function walkDir(dir, maxDepth = 10) {
24863
25189
  if (entry.isDirectory() && (entry.name === "node_modules" || entry.name === ".git")) {
24864
25190
  continue;
24865
25191
  }
24866
- const fullPath = path38.join(current, entry.name);
25192
+ const fullPath = path39.join(current, entry.name);
24867
25193
  if (entry.isDirectory()) {
24868
25194
  await walk(fullPath, depth + 1);
24869
25195
  } else {
@@ -24897,11 +25223,11 @@ var init_glob = __esm({
24897
25223
  inputSchema: inputSchema2,
24898
25224
  isReadOnly: true,
24899
25225
  async call(input, context) {
24900
- const baseDir = input.path ? path38.isAbsolute(input.path) ? input.path : path38.resolve(context.cwd, input.path) : context.cwd;
25226
+ const baseDir = input.path ? path39.isAbsolute(input.path) ? input.path : path39.resolve(context.cwd, input.path) : context.cwd;
24901
25227
  try {
24902
25228
  const entries = await walkDir(baseDir);
24903
25229
  const matched = entries.filter(
24904
- (e) => simpleGlobMatch(path38.relative(baseDir, e.path), input.pattern)
25230
+ (e) => simpleGlobMatch(path39.relative(baseDir, e.path), input.pattern)
24905
25231
  );
24906
25232
  matched.sort((a, b) => b.mtime - a.mtime);
24907
25233
  if (matched.length === 0) {
@@ -24927,7 +25253,7 @@ __export(grep_exports, {
24927
25253
  });
24928
25254
  import { spawn as spawn2 } from "child_process";
24929
25255
  import fs5 from "fs/promises";
24930
- import path39 from "path";
25256
+ import path40 from "path";
24931
25257
  import { z as z3 } from "zod";
24932
25258
  function runRipgrep(input, searchPath, context) {
24933
25259
  return new Promise((resolve, reject) => {
@@ -24981,7 +25307,7 @@ async function nodeGrep(input, searchPath) {
24981
25307
  }
24982
25308
  for (const entry of entries) {
24983
25309
  if (entry.name === "node_modules" || entry.name === ".git") continue;
24984
- const fullPath = path39.join(dir, entry.name);
25310
+ const fullPath = path40.join(dir, entry.name);
24985
25311
  if (entry.isDirectory()) {
24986
25312
  await walk(fullPath);
24987
25313
  } else {
@@ -25027,7 +25353,7 @@ var init_grep = __esm({
25027
25353
  inputSchema: inputSchema3,
25028
25354
  isReadOnly: true,
25029
25355
  async call(input, context) {
25030
- const searchPath = input.path ? path39.isAbsolute(input.path) ? input.path : path39.resolve(context.cwd, input.path) : context.cwd;
25356
+ const searchPath = input.path ? path40.isAbsolute(input.path) ? input.path : path40.resolve(context.cwd, input.path) : context.cwd;
25031
25357
  try {
25032
25358
  const result = await runRipgrep(input, searchPath, context);
25033
25359
  return result;
@@ -25052,7 +25378,7 @@ __export(file_write_exports, {
25052
25378
  FileWriteTool: () => FileWriteTool
25053
25379
  });
25054
25380
  import fs6 from "fs/promises";
25055
- import path40 from "path";
25381
+ import path41 from "path";
25056
25382
  import { z as z4 } from "zod";
25057
25383
  var inputSchema4, FileWriteTool;
25058
25384
  var init_file_write = __esm({
@@ -25080,8 +25406,8 @@ var init_file_write = __esm({
25080
25406
  return { behavior: "allow" };
25081
25407
  },
25082
25408
  async call(input, context) {
25083
- const filePath = path40.isAbsolute(input.file_path) ? input.file_path : path40.resolve(context.cwd, input.file_path);
25084
- const dir = path40.dirname(filePath);
25409
+ const filePath = path41.isAbsolute(input.file_path) ? input.file_path : path41.resolve(context.cwd, input.file_path);
25410
+ const dir = path41.dirname(filePath);
25085
25411
  await fs6.mkdir(dir, { recursive: true });
25086
25412
  await fs6.writeFile(filePath, input.content, "utf-8");
25087
25413
  return {
@@ -25099,7 +25425,7 @@ __export(file_edit_exports, {
25099
25425
  FileEditTool: () => FileEditTool
25100
25426
  });
25101
25427
  import fs7 from "fs/promises";
25102
- import path41 from "path";
25428
+ import path42 from "path";
25103
25429
  import { z as z5 } from "zod";
25104
25430
  function countOccurrences(haystack, needle) {
25105
25431
  let count = 0;
@@ -25140,7 +25466,7 @@ var init_file_edit = __esm({
25140
25466
  return { behavior: "allow" };
25141
25467
  },
25142
25468
  async call(input, context) {
25143
- const filePath = path41.isAbsolute(input.file_path) ? input.file_path : path41.resolve(context.cwd, input.file_path);
25469
+ const filePath = path42.isAbsolute(input.file_path) ? input.file_path : path42.resolve(context.cwd, input.file_path);
25144
25470
  let content;
25145
25471
  try {
25146
25472
  content = await fs7.readFile(filePath, "utf-8");
@@ -25382,7 +25708,7 @@ var init_bash = __esm({
25382
25708
  // src/tui/views/CommandCenter.tsx
25383
25709
  import { useState as useState6, useEffect as useEffect8, useMemo as useMemo4, useCallback as useCallback4, useRef as useRef4 } from "react";
25384
25710
  import TextInput from "ink-text-input";
25385
- import path42 from "path";
25711
+ import path43 from "path";
25386
25712
  import { homedir as homedir6 } from "os";
25387
25713
  import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
25388
25714
  function CommandCenterView({
@@ -25417,13 +25743,13 @@ function CommandCenterView({
25417
25743
  const { createPermissionsFromPreset: createPermissionsFromPreset2, EMPLOYEE_PERMISSIONS: EMPLOYEE_PERMISSIONS2 } = await Promise.resolve().then(() => (init_permissions(), permissions_exports));
25418
25744
  const { getPresetByRole: getPresetByRole2 } = await Promise.resolve().then(() => (init_permission_presets(), permission_presets_exports));
25419
25745
  const { createDefaultHooks: createDefaultHooks2 } = await Promise.resolve().then(() => (init_hooks(), hooks_exports));
25420
- const { readFileSync: readFileSync28, existsSync: existsSync33 } = await import("fs");
25746
+ const { readFileSync: readFileSync28, existsSync: existsSync34 } = await import("fs");
25421
25747
  const { join } = await import("path");
25422
25748
  const { homedir: homedir8 } = await import("os");
25423
25749
  const configPath = join(homedir8(), ".exe-os", "config.json");
25424
25750
  let failoverChain = ["anthropic", "opencode", "gemini", "openai"];
25425
25751
  let providerConfigs = {};
25426
- if (existsSync33(configPath)) {
25752
+ if (existsSync34(configPath)) {
25427
25753
  try {
25428
25754
  const raw = JSON.parse(readFileSync28(configPath, "utf8"));
25429
25755
  if (Array.isArray(raw.failoverChain)) failoverChain = raw.failoverChain;
@@ -25631,7 +25957,7 @@ function CommandCenterView({
25631
25957
  const demoEntries = DEMO_PROJECTS.map((p) => ({
25632
25958
  projectName: p.projectName,
25633
25959
  exeSession: p.exeSession,
25634
- projectDir: path42.join(homedir6(), p.projectName),
25960
+ projectDir: path43.join(homedir6(), p.projectName),
25635
25961
  employeeCount: p.employees.length,
25636
25962
  activeCount: p.employees.filter((e) => e.status === "active").length,
25637
25963
  memoryCount: p.employees.length * 4e3,
@@ -25669,7 +25995,7 @@ function CommandCenterView({
25669
25995
  const { listSessions: listSessions2 } = await Promise.resolve().then(() => (init_session_registry(), session_registry_exports));
25670
25996
  const { listTmuxSessions: listTmuxSessions2, inTmux: inTmux2 } = await Promise.resolve().then(() => (init_tmux_status(), tmux_status_exports));
25671
25997
  const { loadEmployees: loadEmployees2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
25672
- const { existsSync: existsSync33 } = await import("fs");
25998
+ const { existsSync: existsSync34 } = await import("fs");
25673
25999
  const { join } = await import("path");
25674
26000
  const client = getClient2();
25675
26001
  if (!client) {
@@ -25740,7 +26066,7 @@ function CommandCenterView({
25740
26066
  }
25741
26067
  const memoryCount = memoryCounts.get(name) ?? 0;
25742
26068
  const openTaskCount = openTaskCounts.get(name) ?? 0;
25743
- const hasGit = projectDir ? existsSync33(join(projectDir, ".git")) : false;
26069
+ const hasGit = projectDir ? existsSync34(join(projectDir, ".git")) : false;
25744
26070
  const type = hasGit ? "code" : memoryCount > 0 ? "code" : "automation";
25745
26071
  projectList.push({
25746
26072
  projectName: name,
@@ -25765,7 +26091,7 @@ function CommandCenterView({
25765
26091
  setHealth((h) => ({ ...h, memories: Number(totalResult.rows[0]?.cnt ?? 0) }));
25766
26092
  try {
25767
26093
  const pidPath = join(process.env.HOME ?? "", ".exe-os", "exed.pid");
25768
- setHealth((h) => ({ ...h, daemon: existsSync33(pidPath) ? "running" : "stopped" }));
26094
+ setHealth((h) => ({ ...h, daemon: existsSync34(pidPath) ? "running" : "stopped" }));
25769
26095
  } catch {
25770
26096
  }
25771
26097
  const activityResult = await client.execute(
@@ -26006,8 +26332,8 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
26006
26332
  }
26007
26333
  const capture = () => {
26008
26334
  try {
26009
- const { execSync: execSync15 } = __require("child_process");
26010
- const output = execSync15(
26335
+ const { execSync: execSync16 } = __require("child_process");
26336
+ const output = execSync16(
26011
26337
  `tmux capture-pane -t ${JSON.stringify(sessionName)} -p -e 2>/dev/null | tail -${CAPTURE_LINES}`,
26012
26338
  { encoding: "utf8", timeout: 3e3 }
26013
26339
  );
@@ -26031,8 +26357,8 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
26031
26357
  if (key.return) {
26032
26358
  if (!demo && inputBuffer.trim()) {
26033
26359
  try {
26034
- const { execSync: execSync15 } = __require("child_process");
26035
- execSync15(
26360
+ const { execSync: execSync16 } = __require("child_process");
26361
+ execSync16(
26036
26362
  `tmux send-keys -t ${JSON.stringify(sessionName)} ${JSON.stringify(inputBuffer)} Enter`,
26037
26363
  { timeout: 2e3 }
26038
26364
  );
@@ -26040,8 +26366,8 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
26040
26366
  }
26041
26367
  } else if (!demo) {
26042
26368
  try {
26043
- const { execSync: execSync15 } = __require("child_process");
26044
- execSync15(`tmux send-keys -t ${JSON.stringify(sessionName)} Enter`, { timeout: 2e3 });
26369
+ const { execSync: execSync16 } = __require("child_process");
26370
+ execSync16(`tmux send-keys -t ${JSON.stringify(sessionName)} Enter`, { timeout: 2e3 });
26045
26371
  } catch {
26046
26372
  }
26047
26373
  }
@@ -26635,7 +26961,7 @@ var init_useOrchestrator = __esm({
26635
26961
 
26636
26962
  // src/tui/views/Sessions.tsx
26637
26963
  import React19, { useState as useState9, useEffect as useEffect11, useCallback as useCallback6 } from "react";
26638
- import path43 from "path";
26964
+ import path44 from "path";
26639
26965
  import { homedir as homedir7 } from "os";
26640
26966
  import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
26641
26967
  function isCoordinatorEntry(entry) {
@@ -26673,7 +26999,7 @@ function SessionsView({
26673
26999
  if (demo) {
26674
27000
  setProjects(DEMO_PROJECTS.map((p) => ({
26675
27001
  ...p,
26676
- projectDir: path43.join(homedir7(), p.projectName),
27002
+ projectDir: path44.join(homedir7(), p.projectName),
26677
27003
  employees: p.employees.map((e) => ({ ...e, attached: e.status === "active" }))
26678
27004
  })));
26679
27005
  return;
@@ -26728,12 +27054,12 @@ function SessionsView({
26728
27054
  return;
26729
27055
  }
26730
27056
  } else {
26731
- const { execSync: execSync15 } = await import("child_process");
27057
+ const { execSync: execSync16 } = await import("child_process");
26732
27058
  const dir = projectDir || process.cwd();
26733
- execSync15(`tmux new-session -d -s ${JSON.stringify(entry.sessionName)} -c ${JSON.stringify(dir)}`, { timeout: 5e3 });
26734
- execSync15(`tmux send-keys -t ${JSON.stringify(entry.sessionName)} "claude --dangerously-skip-permissions" Enter`, { timeout: 3e3 });
27059
+ execSync16(`tmux new-session -d -s ${JSON.stringify(entry.sessionName)} -c ${JSON.stringify(dir)}`, { timeout: 5e3 });
27060
+ execSync16(`tmux send-keys -t ${JSON.stringify(entry.sessionName)} "claude --dangerously-skip-permissions" Enter`, { timeout: 3e3 });
26735
27061
  await new Promise((r) => setTimeout(r, 3e3));
26736
- execSync15(`tmux send-keys -t ${JSON.stringify(entry.sessionName)} "/exe" Enter`, { timeout: 3e3 });
27062
+ execSync16(`tmux send-keys -t ${JSON.stringify(entry.sessionName)} "/exe" Enter`, { timeout: 3e3 });
26737
27063
  }
26738
27064
  const updated = { ...entry, status: "active", activity: "Starting...", attached: false };
26739
27065
  setViewingEmployee(updated);
@@ -26836,7 +27162,7 @@ function SessionsView({
26836
27162
  const { listTmuxSessions: listTmuxSessions2, inTmux: inTmux2, capturePaneLines: capturePaneLines2, parseActivity: parseActivity2 } = await Promise.resolve().then(() => (init_tmux_status(), tmux_status_exports));
26837
27163
  const { getCoordinatorName: getCoordinatorName2, isCoordinatorRole: isCoordinatorRole2, loadEmployees: loadEmployees2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
26838
27164
  const { isExeSession: isExeSession2 } = await Promise.resolve().then(() => (init_tmux_routing(), tmux_routing_exports));
26839
- const { execSync: execSync15 } = await import("child_process");
27165
+ const { execSync: execSync16 } = await import("child_process");
26840
27166
  if (!inTmux2()) {
26841
27167
  setTmuxAvailable(false);
26842
27168
  setProjects([]);
@@ -26845,7 +27171,7 @@ function SessionsView({
26845
27171
  setTmuxAvailable(true);
26846
27172
  const attachedMap = /* @__PURE__ */ new Map();
26847
27173
  try {
26848
- const out = execSync15("tmux list-sessions -F '#{session_name}:#{session_attached}' 2>/dev/null", {
27174
+ const out = execSync16("tmux list-sessions -F '#{session_name}:#{session_attached}' 2>/dev/null", {
26849
27175
  encoding: "utf8",
26850
27176
  timeout: 3e3
26851
27177
  });
@@ -27881,18 +28207,18 @@ function upsertConversation(conversations, platform, senderId, message) {
27881
28207
  async function loadGatewayConfig() {
27882
28208
  const state = { running: false, port: 3100, adapters: [], agents: [], gatewayUrl: "" };
27883
28209
  try {
27884
- const { execSync: execSync15 } = await import("child_process");
27885
- const ps = execSync15("pgrep -f exe-gateway 2>/dev/null", { encoding: "utf8", timeout: 3e3 });
28210
+ const { execSync: execSync16 } = await import("child_process");
28211
+ const ps = execSync16("pgrep -f exe-gateway 2>/dev/null", { encoding: "utf8", timeout: 3e3 });
27886
28212
  state.running = ps.trim().length > 0;
27887
28213
  } catch {
27888
28214
  state.running = false;
27889
28215
  }
27890
28216
  try {
27891
- const { existsSync: existsSync33, readFileSync: readFileSync28 } = await import("fs");
28217
+ const { existsSync: existsSync34, readFileSync: readFileSync28 } = await import("fs");
27892
28218
  const { join } = await import("path");
27893
28219
  const home = process.env.HOME ?? "";
27894
28220
  const configPath = join(home, ".exe-os", "gateway.json");
27895
- if (existsSync33(configPath)) {
28221
+ if (existsSync34(configPath)) {
27896
28222
  const raw = JSON.parse(readFileSync28(configPath, "utf8"));
27897
28223
  state.port = raw.port ?? 3100;
27898
28224
  state.gatewayUrl = raw.gatewayUrl ?? "";
@@ -28359,10 +28685,10 @@ var init_Gateway = __esm({
28359
28685
  });
28360
28686
 
28361
28687
  // src/tui/utils/agent-status.ts
28362
- import { execSync as execSync14 } from "child_process";
28688
+ import { execSync as execSync15 } from "child_process";
28363
28689
  function getAgentStatus(agentId) {
28364
28690
  try {
28365
- const sessions = execSync14("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
28691
+ const sessions = execSync15("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
28366
28692
  encoding: "utf8",
28367
28693
  timeout: 2e3
28368
28694
  }).trim().split("\n");
@@ -28373,7 +28699,7 @@ function getAgentStatus(agentId) {
28373
28699
  return /^\d?-/.test(suffix) || /^\d+$/.test(suffix);
28374
28700
  });
28375
28701
  if (!agentSession) return { label: "offline", color: "gray" };
28376
- const pane = execSync14(`tmux capture-pane -t "${agentSession}" -p 2>/dev/null | tail -3`, {
28702
+ const pane = execSync15(`tmux capture-pane -t "${agentSession}" -p 2>/dev/null | tail -3`, {
28377
28703
  encoding: "utf8",
28378
28704
  timeout: 2e3
28379
28705
  });
@@ -28491,11 +28817,11 @@ function TeamView({ onBack, onViewSessions }) {
28491
28817
  setMembers(teamData);
28492
28818
  setDbError(null);
28493
28819
  try {
28494
- const { existsSync: existsSync33, readFileSync: readFileSync28 } = await import("fs");
28820
+ const { existsSync: existsSync34, readFileSync: readFileSync28 } = await import("fs");
28495
28821
  const { join } = await import("path");
28496
28822
  const home = process.env.HOME ?? "";
28497
28823
  const gatewayConfig = join(home, ".exe-os", "gateway.json");
28498
- if (existsSync33(gatewayConfig)) {
28824
+ if (existsSync34(gatewayConfig)) {
28499
28825
  const raw = JSON.parse(readFileSync28(gatewayConfig, "utf8"));
28500
28826
  if (raw.agents && raw.agents.length > 0) {
28501
28827
  setExternals(raw.agents.map((a) => ({
@@ -28676,8 +29002,8 @@ __export(wiki_client_exports, {
28676
29002
  listDocuments: () => listDocuments,
28677
29003
  listWorkspaces: () => listWorkspaces
28678
29004
  });
28679
- async function wikiFetch(config, path47, method = "GET", body) {
28680
- const url = `${config.baseUrl}/api/v1${path47}`;
29005
+ async function wikiFetch(config, path48, method = "GET", body) {
29006
+ const url = `${config.baseUrl}/api/v1${path48}`;
28681
29007
  const headers = {
28682
29008
  Authorization: `Bearer ${config.apiKey}`,
28683
29009
  "Content-Type": "application/json"
@@ -28710,7 +29036,7 @@ async function wikiFetch(config, path47, method = "GET", body) {
28710
29036
  }
28711
29037
  }
28712
29038
  if (!response.ok) {
28713
- throw new Error(`Wiki API ${method} ${path47}: ${response.status} ${response.statusText}`);
29039
+ throw new Error(`Wiki API ${method} ${path48}: ${response.status} ${response.statusText}`);
28714
29040
  }
28715
29041
  return response.json();
28716
29042
  } finally {
@@ -29296,20 +29622,20 @@ function SettingsView({ onBack }) {
29296
29622
  };
29297
29623
  });
29298
29624
  try {
29299
- const { execSync: execSync15 } = await import("child_process");
29300
- execSync15("curl -s --max-time 1 http://localhost:11434/api/tags", { timeout: 2e3 });
29625
+ const { execSync: execSync16 } = await import("child_process");
29626
+ execSync16("curl -s --max-time 1 http://localhost:11434/api/tags", { timeout: 2e3 });
29301
29627
  providerList.push({ name: "Ollama", configured: true, detail: "localhost:11434" });
29302
29628
  } catch {
29303
29629
  providerList.push({ name: "Ollama", configured: false, detail: "not running" });
29304
29630
  }
29305
29631
  setProviders(providerList);
29306
29632
  try {
29307
- const { existsSync: existsSync33 } = await import("fs");
29633
+ const { existsSync: existsSync34 } = await import("fs");
29308
29634
  const { join } = await import("path");
29309
29635
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
29310
29636
  const cfg = await loadConfig2();
29311
29637
  const home = process.env.HOME ?? "";
29312
- const hasKey = existsSync33(join(home, ".exe-os", "master.key"));
29638
+ const hasKey = existsSync34(join(home, ".exe-os", "master.key"));
29313
29639
  if (cfg.cloud) {
29314
29640
  setCloud({
29315
29641
  configured: true,
@@ -29322,7 +29648,7 @@ function SettingsView({ onBack }) {
29322
29648
  const pidPath = join(home, ".exe-os", "exed.pid");
29323
29649
  let daemon = "unknown";
29324
29650
  try {
29325
- daemon = existsSync33(pidPath) ? "running" : "stopped";
29651
+ daemon = existsSync34(pidPath) ? "running" : "stopped";
29326
29652
  } catch {
29327
29653
  }
29328
29654
  let version = "unknown";
@@ -30138,15 +30464,15 @@ __export(installer_exports2, {
30138
30464
  verifyOpenCodeHooks: () => verifyOpenCodeHooks
30139
30465
  });
30140
30466
  import { readFile as readFile7, writeFile as writeFile8, mkdir as mkdir8 } from "fs/promises";
30141
- import { existsSync as existsSync30, readFileSync as readFileSync26 } from "fs";
30142
- import path44 from "path";
30467
+ import { existsSync as existsSync31, readFileSync as readFileSync26 } from "fs";
30468
+ import path45 from "path";
30143
30469
  import os19 from "os";
30144
30470
  async function registerOpenCodeMcp(packageRoot, homeDir = os19.homedir()) {
30145
- const configDir = path44.join(homeDir, ".config", "opencode");
30146
- const configPath = path44.join(configDir, "opencode.json");
30471
+ const configDir = path45.join(homeDir, ".config", "opencode");
30472
+ const configPath = path45.join(configDir, "opencode.json");
30147
30473
  await mkdir8(configDir, { recursive: true });
30148
30474
  let config = {};
30149
- if (existsSync30(configPath)) {
30475
+ if (existsSync31(configPath)) {
30150
30476
  try {
30151
30477
  config = JSON.parse(await readFile7(configPath, "utf-8"));
30152
30478
  } catch {
@@ -30158,7 +30484,7 @@ async function registerOpenCodeMcp(packageRoot, homeDir = os19.homedir()) {
30158
30484
  }
30159
30485
  const newEntry = {
30160
30486
  type: "local",
30161
- command: ["node", path44.join(packageRoot, "dist", "mcp", "server.js")],
30487
+ command: ["node", path45.join(packageRoot, "dist", "mcp", "server.js")],
30162
30488
  enabled: true
30163
30489
  };
30164
30490
  const current = config.mcp["exe-os"];
@@ -30173,14 +30499,14 @@ async function registerOpenCodeMcp(packageRoot, homeDir = os19.homedir()) {
30173
30499
  return true;
30174
30500
  }
30175
30501
  async function installOpenCodePlugin(packageRoot, homeDir = os19.homedir()) {
30176
- const pluginDir = path44.join(homeDir, ".config", "opencode", "plugins");
30177
- const pluginPath = path44.join(pluginDir, "exe-os.mjs");
30502
+ const pluginDir = path45.join(homeDir, ".config", "opencode", "plugins");
30503
+ const pluginPath = path45.join(pluginDir, "exe-os.mjs");
30178
30504
  await mkdir8(pluginDir, { recursive: true });
30179
30505
  const pluginContent = PLUGIN_TEMPLATE.replace(
30180
30506
  /__PACKAGE_ROOT__/g,
30181
30507
  packageRoot.replace(/\\/g, "\\\\")
30182
30508
  );
30183
- if (existsSync30(pluginPath)) {
30509
+ if (existsSync31(pluginPath)) {
30184
30510
  const existing = await readFile7(pluginPath, "utf-8");
30185
30511
  if (existing === pluginContent) {
30186
30512
  return false;
@@ -30190,16 +30516,16 @@ async function installOpenCodePlugin(packageRoot, homeDir = os19.homedir()) {
30190
30516
  return true;
30191
30517
  }
30192
30518
  function verifyOpenCodeHooks(homeDir = os19.homedir()) {
30193
- const configPath = path44.join(homeDir, ".config", "opencode", "opencode.json");
30194
- const pluginPath = path44.join(homeDir, ".config", "opencode", "plugins", "exe-os.mjs");
30195
- if (!existsSync30(configPath)) return false;
30519
+ const configPath = path45.join(homeDir, ".config", "opencode", "opencode.json");
30520
+ const pluginPath = path45.join(homeDir, ".config", "opencode", "plugins", "exe-os.mjs");
30521
+ if (!existsSync31(configPath)) return false;
30196
30522
  try {
30197
30523
  const config = JSON.parse(readFileSync26(configPath, "utf-8"));
30198
30524
  if (!config.mcp?.["exe-os"]?.enabled) return false;
30199
30525
  } catch {
30200
30526
  return false;
30201
30527
  }
30202
- if (!existsSync30(pluginPath)) return false;
30528
+ if (!existsSync31(pluginPath)) return false;
30203
30529
  return true;
30204
30530
  }
30205
30531
  async function runOpenCodeInstaller(homeDir) {
@@ -30234,19 +30560,19 @@ __export(installer_exports3, {
30234
30560
  verifyCodexHooks: () => verifyCodexHooks
30235
30561
  });
30236
30562
  import { readFile as readFile8, writeFile as writeFile9, mkdir as mkdir9 } from "fs/promises";
30237
- import { existsSync as existsSync31 } from "fs";
30238
- import path45 from "path";
30563
+ import { existsSync as existsSync32 } from "fs";
30564
+ import path46 from "path";
30239
30565
  import os20 from "os";
30240
30566
  async function mergeCodexHooks(packageRoot, homeDir = os20.homedir()) {
30241
- const codexDir = path45.join(homeDir, ".codex");
30242
- const hooksPath = path45.join(codexDir, "hooks.json");
30243
- const logsDir = path45.join(homeDir, ".exe-os", "logs");
30244
- const hookLogPath = path45.join(logsDir, "hooks.log");
30567
+ const codexDir = path46.join(homeDir, ".codex");
30568
+ const hooksPath = path46.join(codexDir, "hooks.json");
30569
+ const logsDir = path46.join(homeDir, ".exe-os", "logs");
30570
+ const hookLogPath = path46.join(logsDir, "hooks.log");
30245
30571
  const logSuffix = ` 2>> "${hookLogPath}"`;
30246
30572
  await mkdir9(codexDir, { recursive: true });
30247
30573
  await mkdir9(logsDir, { recursive: true });
30248
30574
  let hooksJson = {};
30249
- if (existsSync31(hooksPath)) {
30575
+ if (existsSync32(hooksPath)) {
30250
30576
  try {
30251
30577
  hooksJson = JSON.parse(await readFile8(hooksPath, "utf-8"));
30252
30578
  } catch {
@@ -30263,7 +30589,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os20.homedir()) {
30263
30589
  hooks: [
30264
30590
  {
30265
30591
  type: "command",
30266
- command: `node "${path45.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
30592
+ command: `node "${path46.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
30267
30593
  timeout: 30
30268
30594
  }
30269
30595
  ]
@@ -30279,7 +30605,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os20.homedir()) {
30279
30605
  // Combined hook: runs ingest + error-recall in one Node process.
30280
30606
  // Eliminates a cold-start cycle per tool call (~3-6s savings on Codex).
30281
30607
  type: "command",
30282
- command: `node "${path45.join(packageRoot, "dist", "hooks", "post-tool-combined.js")}"${logSuffix}`
30608
+ command: `node "${path46.join(packageRoot, "dist", "hooks", "post-tool-combined.js")}"${logSuffix}`
30283
30609
  }
30284
30610
  ]
30285
30611
  },
@@ -30293,7 +30619,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os20.homedir()) {
30293
30619
  // Single hook: prompt-submit handles memory retrieval + entity boost.
30294
30620
  // exe-heartbeat-hook is CC-specific (intercom) — omitted on Codex.
30295
30621
  type: "command",
30296
- command: `node "${path45.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
30622
+ command: `node "${path46.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
30297
30623
  }
30298
30624
  ]
30299
30625
  },
@@ -30305,7 +30631,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os20.homedir()) {
30305
30631
  hooks: [
30306
30632
  {
30307
30633
  type: "command",
30308
- command: `node "${path45.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
30634
+ command: `node "${path46.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
30309
30635
  }
30310
30636
  ]
30311
30637
  },
@@ -30318,7 +30644,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os20.homedir()) {
30318
30644
  hooks: [
30319
30645
  {
30320
30646
  type: "command",
30321
- command: `node "${path45.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
30647
+ command: `node "${path46.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
30322
30648
  }
30323
30649
  ]
30324
30650
  },
@@ -30350,8 +30676,8 @@ async function mergeCodexHooks(packageRoot, homeDir = os20.homedir()) {
30350
30676
  return { added, skipped };
30351
30677
  }
30352
30678
  function verifyCodexHooks(homeDir = os20.homedir()) {
30353
- const hooksPath = path45.join(homeDir, ".codex", "hooks.json");
30354
- if (!existsSync31(hooksPath)) return false;
30679
+ const hooksPath = path46.join(homeDir, ".codex", "hooks.json");
30680
+ if (!existsSync32(hooksPath)) return false;
30355
30681
  try {
30356
30682
  const hooksJson = JSON.parse(
30357
30683
  __require("fs").readFileSync(hooksPath, "utf-8")
@@ -30374,11 +30700,11 @@ function verifyCodexHooks(homeDir = os20.homedir()) {
30374
30700
  async function installCodexStatusLine(homeDir = os20.homedir()) {
30375
30701
  const prefs = loadPreferences(homeDir);
30376
30702
  if (prefs.codexStatusLine === false) return "opted-out";
30377
- const codexDir = path45.join(homeDir, ".codex");
30378
- const configPath = path45.join(codexDir, "config.toml");
30703
+ const codexDir = path46.join(homeDir, ".codex");
30704
+ const configPath = path46.join(codexDir, "config.toml");
30379
30705
  await mkdir9(codexDir, { recursive: true });
30380
30706
  let content = "";
30381
- if (existsSync31(configPath)) {
30707
+ if (existsSync32(configPath)) {
30382
30708
  content = await readFile8(configPath, "utf-8");
30383
30709
  if (/\[tui\][\s\S]*?status_line\s*=/.test(content)) {
30384
30710
  return "already-configured";
@@ -30436,12 +30762,12 @@ ${desired}
30436
30762
  return { content: next, changed };
30437
30763
  }
30438
30764
  async function registerCodexMcpServer(packageRoot, homeDir = os20.homedir()) {
30439
- const codexDir = path45.join(homeDir, ".codex");
30440
- const configPath = path45.join(codexDir, "config.toml");
30441
- const serverJsPath = path45.join(packageRoot, "dist", "mcp", "server.js");
30765
+ const codexDir = path46.join(homeDir, ".codex");
30766
+ const configPath = path46.join(codexDir, "config.toml");
30767
+ const serverJsPath = path46.join(packageRoot, "dist", "mcp", "server.js");
30442
30768
  await mkdir9(codexDir, { recursive: true });
30443
30769
  let content = "";
30444
- if (existsSync31(configPath)) {
30770
+ if (existsSync32(configPath)) {
30445
30771
  content = await readFile8(configPath, "utf-8");
30446
30772
  }
30447
30773
  const sectionHeader = "[mcp_servers.exe-os]";
@@ -30466,10 +30792,10 @@ async function registerCodexMcpServer(packageRoot, homeDir = os20.homedir()) {
30466
30792
  return "registered";
30467
30793
  }
30468
30794
  async function ensureCodexHooksFeature(homeDir = os20.homedir()) {
30469
- const configPath = path45.join(homeDir, ".codex", "config.toml");
30470
- await mkdir9(path45.join(homeDir, ".codex"), { recursive: true });
30795
+ const configPath = path46.join(homeDir, ".codex", "config.toml");
30796
+ await mkdir9(path46.join(homeDir, ".codex"), { recursive: true });
30471
30797
  let content = "";
30472
- if (existsSync31(configPath)) {
30798
+ if (existsSync32(configPath)) {
30473
30799
  content = await readFile8(configPath, "utf-8");
30474
30800
  }
30475
30801
  if (/\[features\][\s\S]*?codex_hooks\s*=\s*true/.test(content)) {
@@ -30537,13 +30863,13 @@ var init_installer3 = __esm({
30537
30863
  });
30538
30864
 
30539
30865
  // src/bin/cli.ts
30540
- import { existsSync as existsSync32, readFileSync as readFileSync27, writeFileSync as writeFileSync20, readdirSync as readdirSync9, rmSync } from "fs";
30541
- import path46 from "path";
30866
+ import { existsSync as existsSync33, readFileSync as readFileSync27, writeFileSync as writeFileSync20, readdirSync as readdirSync10, rmSync } from "fs";
30867
+ import path47 from "path";
30542
30868
  import os21 from "os";
30543
30869
  var args = process.argv.slice(2);
30544
30870
  if (args.includes("--version") || args.includes("-v")) {
30545
30871
  try {
30546
- const pkgPath = path46.join(path46.dirname(new URL(import.meta.url).pathname), "..", "..", "package.json");
30872
+ const pkgPath = path47.join(path47.dirname(new URL(import.meta.url).pathname), "..", "..", "package.json");
30547
30873
  const pkg = JSON.parse(readFileSync27(pkgPath, "utf8"));
30548
30874
  console.log(pkg.version);
30549
30875
  } catch {
@@ -30708,9 +31034,9 @@ ID: ${result.id}`);
30708
31034
  });
30709
31035
  await init_App2().then(() => App_exports);
30710
31036
  } else {
30711
- const claudeDir = path46.join(os21.homedir(), ".claude");
30712
- const settingsPath = path46.join(claudeDir, "settings.json");
30713
- const hasClaudeCode = existsSync32(settingsPath) && (() => {
31037
+ const claudeDir = path47.join(os21.homedir(), ".claude");
31038
+ const settingsPath = path47.join(claudeDir, "settings.json");
31039
+ const hasClaudeCode = existsSync33(settingsPath) && (() => {
30714
31040
  try {
30715
31041
  const raw = readFileSync27(settingsPath, "utf8");
30716
31042
  return raw.includes("exe-os") || raw.includes("exe-mem");
@@ -30722,8 +31048,8 @@ ID: ${result.id}`);
30722
31048
  const { DEFAULT_COORDINATOR_TEMPLATE_NAME: DEFAULT_COORDINATOR_TEMPLATE_NAME2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
30723
31049
  let cooName = DEFAULT_COORDINATOR_TEMPLATE_NAME2;
30724
31050
  try {
30725
- const rosterPath = path46.join(os21.homedir(), ".exe-os", "exe-employees.json");
30726
- if (existsSync32(rosterPath)) {
31051
+ const rosterPath = path47.join(os21.homedir(), ".exe-os", "exe-employees.json");
31052
+ if (existsSync33(rosterPath)) {
30727
31053
  const roster = JSON.parse(readFileSync27(rosterPath, "utf8"));
30728
31054
  const coo = roster.find((e) => e.role === "COO");
30729
31055
  if (coo) cooName = coo.name;
@@ -30788,11 +31114,11 @@ async function runCodexInstall() {
30788
31114
  }
30789
31115
  }
30790
31116
  async function runClaudeCheck() {
30791
- const claudeDir = path46.join(os21.homedir(), ".claude");
30792
- const settingsPath = path46.join(claudeDir, "settings.json");
30793
- const claudeJsonPath = path46.join(os21.homedir(), ".claude.json");
31117
+ const claudeDir = path47.join(os21.homedir(), ".claude");
31118
+ const settingsPath = path47.join(claudeDir, "settings.json");
31119
+ const claudeJsonPath = path47.join(os21.homedir(), ".claude.json");
30794
31120
  let ok = true;
30795
- if (existsSync32(settingsPath)) {
31121
+ if (existsSync33(settingsPath)) {
30796
31122
  let settings;
30797
31123
  try {
30798
31124
  settings = JSON.parse(readFileSync27(settingsPath, "utf8"));
@@ -30821,7 +31147,7 @@ async function runClaudeCheck() {
30821
31147
  console.log("\x1B[31m\u2717\x1B[0m settings.json not found");
30822
31148
  ok = false;
30823
31149
  }
30824
- if (existsSync32(claudeJsonPath)) {
31150
+ if (existsSync33(claudeJsonPath)) {
30825
31151
  let claudeJson;
30826
31152
  try {
30827
31153
  claudeJson = JSON.parse(readFileSync27(claudeJsonPath, "utf8"));
@@ -30843,8 +31169,8 @@ async function runClaudeCheck() {
30843
31169
  console.log("\x1B[31m\u2717\x1B[0m claude.json not found");
30844
31170
  ok = false;
30845
31171
  }
30846
- const skillsDir = path46.join(claudeDir, "skills");
30847
- if (existsSync32(skillsDir)) {
31172
+ const skillsDir = path47.join(claudeDir, "skills");
31173
+ if (existsSync33(skillsDir)) {
30848
31174
  console.log("\x1B[32m\u2713\x1B[0m Slash skills directory exists");
30849
31175
  } else {
30850
31176
  console.log("\x1B[31m\u2717\x1B[0m Slash skills directory missing");
@@ -30861,14 +31187,14 @@ async function runClaudeUninstall(flags = []) {
30861
31187
  const dryRun = flags.includes("--dry-run");
30862
31188
  const purge = flags.includes("--purge");
30863
31189
  const homeDir = os21.homedir();
30864
- const claudeDir = path46.join(homeDir, ".claude");
30865
- const settingsPath = path46.join(claudeDir, "settings.json");
30866
- const claudeJsonPath = path46.join(homeDir, ".claude.json");
30867
- const exeOsDir = path46.join(homeDir, ".exe-os");
31190
+ const claudeDir = path47.join(homeDir, ".claude");
31191
+ const settingsPath = path47.join(claudeDir, "settings.json");
31192
+ const claudeJsonPath = path47.join(homeDir, ".claude.json");
31193
+ const exeOsDir = path47.join(homeDir, ".exe-os");
30868
31194
  let removed = 0;
30869
31195
  const log = (msg) => console.log(dryRun ? `[dry-run] ${msg}` : msg);
30870
31196
  let settings = {};
30871
- if (existsSync32(settingsPath)) {
31197
+ if (existsSync33(settingsPath)) {
30872
31198
  try {
30873
31199
  settings = JSON.parse(readFileSync27(settingsPath, "utf8"));
30874
31200
  } catch {
@@ -30915,7 +31241,7 @@ async function runClaudeUninstall(flags = []) {
30915
31241
  removed++;
30916
31242
  }
30917
31243
  }
30918
- if (existsSync32(claudeJsonPath)) {
31244
+ if (existsSync33(claudeJsonPath)) {
30919
31245
  const raw = readFileSync27(claudeJsonPath, "utf8");
30920
31246
  if (raw.length > 1e6) {
30921
31247
  console.error("claude.json exceeds 1 MB \u2014 skipping parse.");
@@ -30945,14 +31271,14 @@ async function runClaudeUninstall(flags = []) {
30945
31271
  }
30946
31272
  }
30947
31273
  }
30948
- const skillsDir = path46.join(claudeDir, "skills");
30949
- if (existsSync32(skillsDir)) {
31274
+ const skillsDir = path47.join(claudeDir, "skills");
31275
+ if (existsSync33(skillsDir)) {
30950
31276
  let skillCount = 0;
30951
31277
  try {
30952
- const entries = readdirSync9(skillsDir);
31278
+ const entries = readdirSync10(skillsDir);
30953
31279
  for (const entry of entries) {
30954
31280
  if (entry.startsWith("exe")) {
30955
- const fullPath = path46.join(skillsDir, entry);
31281
+ const fullPath = path47.join(skillsDir, entry);
30956
31282
  if (!dryRun) rmSync(fullPath, { recursive: true, force: true });
30957
31283
  skillCount++;
30958
31284
  }
@@ -30964,8 +31290,8 @@ async function runClaudeUninstall(flags = []) {
30964
31290
  removed++;
30965
31291
  }
30966
31292
  }
30967
- const claudeMdPath = path46.join(claudeDir, "CLAUDE.md");
30968
- if (existsSync32(claudeMdPath)) {
31293
+ const claudeMdPath = path47.join(claudeDir, "CLAUDE.md");
31294
+ if (existsSync33(claudeMdPath)) {
30969
31295
  const content = readFileSync27(claudeMdPath, "utf8");
30970
31296
  const startMarker = "<!-- exe-os:orchestration-start -->";
30971
31297
  const endMarker = "<!-- exe-os:orchestration-end -->";
@@ -30978,14 +31304,14 @@ async function runClaudeUninstall(flags = []) {
30978
31304
  removed++;
30979
31305
  }
30980
31306
  }
30981
- const agentsDir = path46.join(claudeDir, "agents");
30982
- if (existsSync32(agentsDir)) {
31307
+ const agentsDir = path47.join(claudeDir, "agents");
31308
+ if (existsSync33(agentsDir)) {
30983
31309
  let agentCount = 0;
30984
31310
  try {
30985
- const entries = readdirSync9(agentsDir).filter((f) => f.endsWith(".md"));
31311
+ const entries = readdirSync10(agentsDir).filter((f) => f.endsWith(".md"));
30986
31312
  let knownNames = /* @__PURE__ */ new Set();
30987
- const rosterPath = path46.join(exeOsDir, "exe-employees.json");
30988
- if (existsSync32(rosterPath)) {
31313
+ const rosterPath = path47.join(exeOsDir, "exe-employees.json");
31314
+ if (existsSync33(rosterPath)) {
30989
31315
  try {
30990
31316
  const roster = JSON.parse(readFileSync27(rosterPath, "utf8"));
30991
31317
  knownNames = new Set(roster.map((e) => e.name));
@@ -30995,7 +31321,7 @@ async function runClaudeUninstall(flags = []) {
30995
31321
  for (const entry of entries) {
30996
31322
  const name = entry.replace(/\.md$/, "");
30997
31323
  if (knownNames.has(name)) {
30998
- if (!dryRun) rmSync(path46.join(agentsDir, entry), { force: true });
31324
+ if (!dryRun) rmSync(path47.join(agentsDir, entry), { force: true });
30999
31325
  agentCount++;
31000
31326
  }
31001
31327
  }
@@ -31006,14 +31332,14 @@ async function runClaudeUninstall(flags = []) {
31006
31332
  removed++;
31007
31333
  }
31008
31334
  }
31009
- const projectsDir = path46.join(claudeDir, "projects");
31010
- if (existsSync32(projectsDir)) {
31335
+ const projectsDir = path47.join(claudeDir, "projects");
31336
+ if (existsSync33(projectsDir)) {
31011
31337
  let projectCount = 0;
31012
31338
  try {
31013
- const projects = readdirSync9(projectsDir);
31339
+ const projects = readdirSync10(projectsDir);
31014
31340
  for (const proj of projects) {
31015
- const projSettings = path46.join(projectsDir, proj, "settings.json");
31016
- if (!existsSync32(projSettings)) continue;
31341
+ const projSettings = path47.join(projectsDir, proj, "settings.json");
31342
+ if (!existsSync33(projSettings)) continue;
31017
31343
  try {
31018
31344
  const pSettings = JSON.parse(readFileSync27(projSettings, "utf8"));
31019
31345
  let changed = false;
@@ -31039,28 +31365,28 @@ async function runClaudeUninstall(flags = []) {
31039
31365
  }
31040
31366
  }
31041
31367
  try {
31042
- const { execSync: execSync15 } = await import("child_process");
31368
+ const { execSync: execSync16 } = await import("child_process");
31043
31369
  const findExeBin3 = () => {
31044
31370
  try {
31045
- return execSync15(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
31371
+ return execSync16(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
31046
31372
  } catch {
31047
31373
  return null;
31048
31374
  }
31049
31375
  };
31050
31376
  const exeBinPath = findExeBin3();
31051
31377
  if (!exeBinPath) throw new Error("exe-os not found in PATH");
31052
- const binDir = path46.dirname(exeBinPath);
31378
+ const binDir = path47.dirname(exeBinPath);
31053
31379
  let symlinkCount = 0;
31054
- const rosterPath = path46.join(exeOsDir, "exe-employees.json");
31055
- if (existsSync32(rosterPath)) {
31380
+ const rosterPath = path47.join(exeOsDir, "exe-employees.json");
31381
+ if (existsSync33(rosterPath)) {
31056
31382
  const roster = JSON.parse(readFileSync27(rosterPath, "utf8"));
31057
31383
  const { DEFAULT_COORDINATOR_TEMPLATE_NAME: DEFAULT_COORDINATOR_TEMPLATE_NAME2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
31058
31384
  const coordinatorName = roster.find((e) => e.role?.toLowerCase() === "coo")?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME2;
31059
31385
  for (const emp of roster) {
31060
31386
  if (emp.name === coordinatorName) continue;
31061
31387
  for (const suffix of ["", "-opencode"]) {
31062
- const linkPath = path46.join(binDir, `${emp.name}${suffix}`);
31063
- if (existsSync32(linkPath)) {
31388
+ const linkPath = path47.join(binDir, `${emp.name}${suffix}`);
31389
+ if (existsSync33(linkPath)) {
31064
31390
  if (!dryRun) rmSync(linkPath, { force: true });
31065
31391
  symlinkCount++;
31066
31392
  }
@@ -31073,7 +31399,7 @@ async function runClaudeUninstall(flags = []) {
31073
31399
  }
31074
31400
  } catch {
31075
31401
  }
31076
- if (purge && existsSync32(exeOsDir)) {
31402
+ if (purge && existsSync33(exeOsDir)) {
31077
31403
  if (!dryRun) {
31078
31404
  process.stdout.write("\x1B[33m\u26A0 This will delete all memories, identities, and agent data.\x1B[0m\n");
31079
31405
  process.stdout.write(" Removing ~/.exe-os...\n");
@@ -31098,7 +31424,7 @@ async function checkForUpdateOnBoot() {
31098
31424
  const config = await loadConfig2();
31099
31425
  if (!config.autoUpdate.checkOnBoot) return;
31100
31426
  const { checkForUpdate: checkForUpdate2 } = await Promise.resolve().then(() => (init_update(), update_exports));
31101
- const packageRoot = path46.resolve(
31427
+ const packageRoot = path47.resolve(
31102
31428
  new URL("../..", import.meta.url).pathname
31103
31429
  );
31104
31430
  const result = checkForUpdate2(packageRoot);
@@ -31158,7 +31484,7 @@ async function runActivate(key) {
31158
31484
  const idTemplate = getIdentityTemplate(identityKey);
31159
31485
  if (idTemplate) {
31160
31486
  const idPath = identityPath2(name);
31161
- const dir = path46.dirname(idPath);
31487
+ const dir = path47.dirname(idPath);
31162
31488
  if (!fs8.existsSync(dir)) fs8.mkdirSync(dir, { recursive: true });
31163
31489
  fs8.writeFileSync(idPath, idTemplate.replace(/^agent_id: \w+/m, `agent_id: ${name}`), "utf-8");
31164
31490
  }