@askexenow/exe-os 0.8.65 → 0.8.68

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 (54) hide show
  1. package/dist/bin/cleanup-stale-review-tasks.js +8 -7
  2. package/dist/bin/cli.js +204 -120
  3. package/dist/bin/exe-assign.js +11 -10
  4. package/dist/bin/exe-boot.js +83 -78
  5. package/dist/bin/exe-call.js +33 -1
  6. package/dist/bin/exe-cloud.js +3 -2
  7. package/dist/bin/exe-dispatch.js +31 -30
  8. package/dist/bin/exe-gateway.js +33 -32
  9. package/dist/bin/exe-heartbeat.js +21 -20
  10. package/dist/bin/exe-launch-agent.js +48 -16
  11. package/dist/bin/exe-link.js +16 -11
  12. package/dist/bin/exe-new-employee.js +20 -19
  13. package/dist/bin/exe-pending-messages.js +7 -6
  14. package/dist/bin/exe-pending-reviews.js +16 -15
  15. package/dist/bin/exe-rename.js +12 -11
  16. package/dist/bin/exe-review.js +4 -3
  17. package/dist/bin/exe-session-cleanup.js +20 -19
  18. package/dist/bin/exe-settings.js +3 -2
  19. package/dist/bin/exe-status.js +16 -15
  20. package/dist/bin/exe-team.js +4 -3
  21. package/dist/bin/git-sweep.js +31 -30
  22. package/dist/bin/install.js +284 -113
  23. package/dist/bin/scan-tasks.js +33 -32
  24. package/dist/bin/setup.js +114 -30
  25. package/dist/gateway/index.js +32 -31
  26. package/dist/hooks/bug-report-worker.js +58 -26
  27. package/dist/hooks/commit-complete.js +31 -30
  28. package/dist/hooks/ingest-worker.js +58 -57
  29. package/dist/hooks/post-compact.js +10 -9
  30. package/dist/hooks/pre-compact.js +31 -30
  31. package/dist/hooks/pre-tool-use.js +46 -14
  32. package/dist/hooks/prompt-ingest-worker.js +15 -14
  33. package/dist/hooks/prompt-submit.js +15 -14
  34. package/dist/hooks/response-ingest-worker.js +8 -7
  35. package/dist/hooks/session-end.js +14 -13
  36. package/dist/hooks/session-start.js +10 -9
  37. package/dist/hooks/stop.js +10 -9
  38. package/dist/hooks/subagent-stop.js +10 -9
  39. package/dist/hooks/summary-worker.js +41 -36
  40. package/dist/index.js +43 -42
  41. package/dist/lib/cloud-sync.js +16 -11
  42. package/dist/lib/employees.js +33 -1
  43. package/dist/lib/exe-daemon.js +56 -55
  44. package/dist/lib/messaging.js +9 -8
  45. package/dist/lib/tasks.js +27 -26
  46. package/dist/lib/tmux-routing.js +29 -28
  47. package/dist/mcp/server.js +94 -62
  48. package/dist/mcp/tools/create-task.js +60 -28
  49. package/dist/mcp/tools/list-tasks.js +10 -9
  50. package/dist/mcp/tools/send-message.js +11 -10
  51. package/dist/mcp/tools/update-task.js +21 -20
  52. package/dist/runtime/index.js +31 -30
  53. package/dist/tui/App.js +67 -35
  54. package/package.json +1 -1
@@ -1479,9 +1479,10 @@ var init_config = __esm({
1479
1479
 
1480
1480
  // src/lib/employees.ts
1481
1481
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
1482
- import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync4 } from "fs";
1482
+ import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync4, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
1483
1483
  import { execSync as execSync4 } from "child_process";
1484
1484
  import path5 from "path";
1485
+ import os5 from "os";
1485
1486
  function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
1486
1487
  if (!existsSync4(employeesPath)) return [];
1487
1488
  try {
@@ -1510,7 +1511,7 @@ var init_employees = __esm({
1510
1511
  });
1511
1512
 
1512
1513
  // src/lib/license.ts
1513
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
1514
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
1514
1515
  import { randomUUID as randomUUID2 } from "crypto";
1515
1516
  import path6 from "path";
1516
1517
  import { jwtVerify, importSPKI } from "jose";
@@ -1613,11 +1614,11 @@ var init_plan_limits = __esm({
1613
1614
  // src/lib/notifications.ts
1614
1615
  import crypto from "crypto";
1615
1616
  import path8 from "path";
1616
- import os5 from "os";
1617
+ import os6 from "os";
1617
1618
  import {
1618
1619
  readFileSync as readFileSync7,
1619
1620
  readdirSync,
1620
- unlinkSync,
1621
+ unlinkSync as unlinkSync2,
1621
1622
  existsSync as existsSync7,
1622
1623
  rmdirSync
1623
1624
  } from "fs";
@@ -2198,7 +2199,7 @@ var init_tasks_crud = __esm({
2198
2199
 
2199
2200
  // src/lib/tasks-review.ts
2200
2201
  import path10 from "path";
2201
- import { existsSync as existsSync9, readdirSync as readdirSync2, unlinkSync as unlinkSync2 } from "fs";
2202
+ import { existsSync as existsSync9, readdirSync as readdirSync2, unlinkSync as unlinkSync3 } from "fs";
2202
2203
  async function countPendingReviews(sessionScope) {
2203
2204
  const client = getClient();
2204
2205
  if (sessionScope) {
@@ -2383,7 +2384,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
2383
2384
  if (existsSync9(cacheDir)) {
2384
2385
  for (const f of readdirSync2(cacheDir)) {
2385
2386
  if (f.startsWith("review-notified-")) {
2386
- unlinkSync2(path10.join(cacheDir, f));
2387
+ unlinkSync3(path10.join(cacheDir, f));
2387
2388
  }
2388
2389
  }
2389
2390
  }
@@ -3051,7 +3052,7 @@ __export(tasks_exports, {
3051
3052
  writeCheckpoint: () => writeCheckpoint
3052
3053
  });
3053
3054
  import path13 from "path";
3054
- import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, unlinkSync as unlinkSync3 } from "fs";
3055
+ import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, unlinkSync as unlinkSync4 } from "fs";
3055
3056
  async function createTask(input) {
3056
3057
  const result = await createTaskCore(input);
3057
3058
  if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
@@ -3074,10 +3075,10 @@ async function updateTask(input) {
3074
3075
  const cachePath = path13.join(cacheDir, `current-task-${agent}.json`);
3075
3076
  if (input.status === "in_progress") {
3076
3077
  mkdirSync4(cacheDir, { recursive: true });
3077
- writeFileSync4(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
3078
+ writeFileSync5(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
3078
3079
  } else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled") {
3079
3080
  try {
3080
- unlinkSync3(cachePath);
3081
+ unlinkSync4(cachePath);
3081
3082
  } catch {
3082
3083
  }
3083
3084
  }
@@ -3519,11 +3520,11 @@ __export(tmux_routing_exports, {
3519
3520
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
3520
3521
  });
3521
3522
  import { execFileSync as execFileSync2, execSync as execSync7 } from "child_process";
3522
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, existsSync as existsSync10, appendFileSync } from "fs";
3523
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, existsSync as existsSync10, appendFileSync } from "fs";
3523
3524
  import path14 from "path";
3524
- import os6 from "os";
3525
+ import os7 from "os";
3525
3526
  import { fileURLToPath } from "url";
3526
- import { unlinkSync as unlinkSync4 } from "fs";
3527
+ import { unlinkSync as unlinkSync5 } from "fs";
3527
3528
  function spawnLockPath(sessionName) {
3528
3529
  return path14.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
3529
3530
  }
@@ -3550,12 +3551,12 @@ function acquireSpawnLock(sessionName) {
3550
3551
  } catch {
3551
3552
  }
3552
3553
  }
3553
- writeFileSync5(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
3554
+ writeFileSync6(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
3554
3555
  return true;
3555
3556
  }
3556
3557
  function releaseSpawnLock(sessionName) {
3557
3558
  try {
3558
- unlinkSync4(spawnLockPath(sessionName));
3559
+ unlinkSync5(spawnLockPath(sessionName));
3559
3560
  } catch {
3560
3561
  }
3561
3562
  }
@@ -3637,7 +3638,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
3637
3638
  }
3638
3639
  const rootExe = extractRootExe(parentExe) ?? parentExe;
3639
3640
  const filePath = path14.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
3640
- writeFileSync5(filePath, JSON.stringify({
3641
+ writeFileSync6(filePath, JSON.stringify({
3641
3642
  parentExe: rootExe,
3642
3643
  dispatchedBy: dispatchedBy || rootExe,
3643
3644
  registeredAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -3724,7 +3725,7 @@ function readDebounceState() {
3724
3725
  function writeDebounceState(state) {
3725
3726
  try {
3726
3727
  if (!existsSync10(SESSION_CACHE)) mkdirSync5(SESSION_CACHE, { recursive: true });
3727
- writeFileSync5(DEBOUNCE_FILE, JSON.stringify(state));
3728
+ writeFileSync6(DEBOUNCE_FILE, JSON.stringify(state));
3728
3729
  } catch {
3729
3730
  }
3730
3731
  }
@@ -3913,7 +3914,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3913
3914
  const transport = getTransport();
3914
3915
  const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
3915
3916
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
3916
- const logDir = path14.join(os6.homedir(), ".exe-os", "session-logs");
3917
+ const logDir = path14.join(os7.homedir(), ".exe-os", "session-logs");
3917
3918
  const logFile = path14.join(logDir, `${instanceLabel}-${Date.now()}.log`);
3918
3919
  if (!existsSync10(logDir)) {
3919
3920
  mkdirSync5(logDir, { recursive: true });
@@ -3929,7 +3930,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3929
3930
  } catch {
3930
3931
  }
3931
3932
  try {
3932
- const claudeJsonPath = path14.join(os6.homedir(), ".claude.json");
3933
+ const claudeJsonPath = path14.join(os7.homedir(), ".claude.json");
3933
3934
  let claudeJson = {};
3934
3935
  try {
3935
3936
  claudeJson = JSON.parse(readFileSync9(claudeJsonPath, "utf8"));
@@ -3940,11 +3941,11 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3940
3941
  const trustDir = opts?.cwd ?? projectDir;
3941
3942
  if (!projects[trustDir]) projects[trustDir] = {};
3942
3943
  projects[trustDir].hasTrustDialogAccepted = true;
3943
- writeFileSync5(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
3944
+ writeFileSync6(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
3944
3945
  } catch {
3945
3946
  }
3946
3947
  try {
3947
- const settingsDir = path14.join(os6.homedir(), ".claude", "projects");
3948
+ const settingsDir = path14.join(os7.homedir(), ".claude", "projects");
3948
3949
  const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
3949
3950
  const projSettingsDir = path14.join(settingsDir, normalizedKey);
3950
3951
  const settingsPath = path14.join(projSettingsDir, "settings.json");
@@ -3979,7 +3980,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3979
3980
  perms.allow = allow;
3980
3981
  settings.permissions = perms;
3981
3982
  mkdirSync5(projSettingsDir, { recursive: true });
3982
- writeFileSync5(settingsPath, JSON.stringify(settings, null, 2) + "\n");
3983
+ writeFileSync6(settingsPath, JSON.stringify(settings, null, 2) + "\n");
3983
3984
  }
3984
3985
  } catch {
3985
3986
  }
@@ -3992,7 +3993,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3992
3993
  let legacyFallbackWarned = false;
3993
3994
  if (!useExeAgent && !useBinSymlink) {
3994
3995
  const identityPath = path14.join(
3995
- os6.homedir(),
3996
+ os7.homedir(),
3996
3997
  ".exe-os",
3997
3998
  "identity",
3998
3999
  `${employeeName}.md`
@@ -4022,7 +4023,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4022
4023
  }
4023
4024
  let sessionContextFlag = "";
4024
4025
  try {
4025
- const ctxDir = path14.join(os6.homedir(), ".exe-os", "session-cache");
4026
+ const ctxDir = path14.join(os7.homedir(), ".exe-os", "session-cache");
4026
4027
  mkdirSync5(ctxDir, { recursive: true });
4027
4028
  const ctxFile = path14.join(ctxDir, `session-context-${sessionName}.md`);
4028
4029
  const ctxContent = [
@@ -4031,7 +4032,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4031
4032
  `Your parent exe session is ${exeSession}.`,
4032
4033
  `Your employees (if any) use the -${exeSession} suffix (e.g., tom-${exeSession}).`
4033
4034
  ].join("\n");
4034
- writeFileSync5(ctxFile, ctxContent);
4035
+ writeFileSync6(ctxFile, ctxContent);
4035
4036
  sessionContextFlag = ` --append-system-prompt-file ${ctxFile}`;
4036
4037
  } catch {
4037
4038
  }
@@ -4070,7 +4071,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4070
4071
  try {
4071
4072
  const mySession = getMySession();
4072
4073
  const dispatchInfo = path14.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
4073
- writeFileSync5(dispatchInfo, JSON.stringify({
4074
+ writeFileSync6(dispatchInfo, JSON.stringify({
4074
4075
  dispatchedBy: mySession,
4075
4076
  rootExe: exeSession,
4076
4077
  provider: useBinSymlink ? ccProvider : useExeAgent ? opts.provider : "anthropic",
@@ -4133,13 +4134,13 @@ var init_tmux_routing = __esm({
4133
4134
  init_provider_table();
4134
4135
  init_intercom_queue();
4135
4136
  init_plan_limits();
4136
- SPAWN_LOCK_DIR = path14.join(os6.homedir(), ".exe-os", "spawn-locks");
4137
- SESSION_CACHE = path14.join(os6.homedir(), ".exe-os", "session-cache");
4137
+ SPAWN_LOCK_DIR = path14.join(os7.homedir(), ".exe-os", "spawn-locks");
4138
+ SESSION_CACHE = path14.join(os7.homedir(), ".exe-os", "session-cache");
4138
4139
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
4139
4140
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
4140
4141
  VERIFY_PANE_LINES = 200;
4141
4142
  INTERCOM_DEBOUNCE_MS = 3e4;
4142
- INTERCOM_LOG2 = path14.join(os6.homedir(), ".exe-os", "intercom.log");
4143
+ INTERCOM_LOG2 = path14.join(os7.homedir(), ".exe-os", "intercom.log");
4143
4144
  DEBOUNCE_FILE = path14.join(SESSION_CACHE, "intercom-debounce.json");
4144
4145
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
4145
4146
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
@@ -4159,9 +4160,9 @@ var init_memory = __esm({
4159
4160
  import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
4160
4161
  import { existsSync as existsSync11 } from "fs";
4161
4162
  import path15 from "path";
4162
- import os7 from "os";
4163
+ import os8 from "os";
4163
4164
  function getKeyDir() {
4164
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path15.join(os7.homedir(), ".exe-os");
4165
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path15.join(os8.homedir(), ".exe-os");
4165
4166
  }
4166
4167
  function getKeyPath() {
4167
4168
  return path15.join(getKeyDir(), "master.key");
package/dist/tui/App.js CHANGED
@@ -1560,14 +1560,16 @@ __export(employees_exports, {
1560
1560
  isMultiInstance: () => isMultiInstance,
1561
1561
  loadEmployees: () => loadEmployees,
1562
1562
  loadEmployeesSync: () => loadEmployeesSync,
1563
+ normalizeRosterCase: () => normalizeRosterCase,
1563
1564
  registerBinSymlinks: () => registerBinSymlinks,
1564
1565
  saveEmployees: () => saveEmployees,
1565
1566
  validateEmployeeName: () => validateEmployeeName
1566
1567
  });
1567
1568
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
1568
- import { existsSync as existsSync5, symlinkSync, readlinkSync, readFileSync as readFileSync5 } from "fs";
1569
+ import { existsSync as existsSync5, symlinkSync, readlinkSync, readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
1569
1570
  import { execSync as execSync4 } from "child_process";
1570
1571
  import path4 from "path";
1572
+ import os4 from "os";
1571
1573
  function validateEmployeeName(name) {
1572
1574
  if (!name) {
1573
1575
  return { valid: false, error: "Name is required" };
@@ -1635,6 +1637,36 @@ function addEmployee(employees, employee) {
1635
1637
  }
1636
1638
  return [...employees, normalized];
1637
1639
  }
1640
+ async function normalizeRosterCase(rosterPath) {
1641
+ const employees = await loadEmployees(rosterPath);
1642
+ let changed = false;
1643
+ for (const emp of employees) {
1644
+ if (emp.name !== emp.name.toLowerCase()) {
1645
+ const oldName = emp.name;
1646
+ emp.name = emp.name.toLowerCase();
1647
+ changed = true;
1648
+ try {
1649
+ const identityDir = path4.join(os4.homedir(), ".exe-os", "identity");
1650
+ const oldPath = path4.join(identityDir, `${oldName}.md`);
1651
+ const newPath = path4.join(identityDir, `${emp.name}.md`);
1652
+ if (existsSync5(oldPath) && !existsSync5(newPath)) {
1653
+ renameSync3(oldPath, newPath);
1654
+ } else if (existsSync5(oldPath) && oldPath !== newPath) {
1655
+ const content = readFileSync5(oldPath, "utf-8");
1656
+ writeFileSync3(newPath, content, "utf-8");
1657
+ if (oldPath.toLowerCase() !== newPath.toLowerCase()) {
1658
+ unlinkSync(oldPath);
1659
+ }
1660
+ }
1661
+ } catch {
1662
+ }
1663
+ }
1664
+ }
1665
+ if (changed) {
1666
+ await saveEmployees(employees, rosterPath);
1667
+ }
1668
+ return changed;
1669
+ }
1638
1670
  function findExeBin() {
1639
1671
  try {
1640
1672
  return execSync4(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
@@ -1702,7 +1734,7 @@ __export(license_exports, {
1702
1734
  stopLicenseRevalidation: () => stopLicenseRevalidation,
1703
1735
  validateLicense: () => validateLicense
1704
1736
  });
1705
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync3, existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
1737
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
1706
1738
  import { randomUUID } from "crypto";
1707
1739
  import path5 from "path";
1708
1740
  import { jwtVerify, importSPKI } from "jose";
@@ -1732,7 +1764,7 @@ function loadDeviceId() {
1732
1764
  }
1733
1765
  const id = randomUUID();
1734
1766
  mkdirSync3(EXE_AI_DIR, { recursive: true });
1735
- writeFileSync3(DEVICE_ID_PATH, id, "utf8");
1767
+ writeFileSync4(DEVICE_ID_PATH, id, "utf8");
1736
1768
  return id;
1737
1769
  }
1738
1770
  function loadLicense() {
@@ -1745,7 +1777,7 @@ function loadLicense() {
1745
1777
  }
1746
1778
  function saveLicense(apiKey) {
1747
1779
  mkdirSync3(EXE_AI_DIR, { recursive: true });
1748
- writeFileSync3(LICENSE_PATH, apiKey.trim(), { encoding: "utf8", mode: 384 });
1780
+ writeFileSync4(LICENSE_PATH, apiKey.trim(), { encoding: "utf8", mode: 384 });
1749
1781
  }
1750
1782
  async function verifyLicenseJwt(token) {
1751
1783
  try {
@@ -1816,7 +1848,7 @@ function getRawCachedPlan() {
1816
1848
  }
1817
1849
  function cacheResponse(token) {
1818
1850
  try {
1819
- writeFileSync3(CACHE_PATH, JSON.stringify({ token }), "utf8");
1851
+ writeFileSync4(CACHE_PATH, JSON.stringify({ token }), "utf8");
1820
1852
  } catch {
1821
1853
  }
1822
1854
  }
@@ -2153,11 +2185,11 @@ var init_plan_limits = __esm({
2153
2185
  // src/lib/notifications.ts
2154
2186
  import crypto from "crypto";
2155
2187
  import path7 from "path";
2156
- import os4 from "os";
2188
+ import os5 from "os";
2157
2189
  import {
2158
2190
  readFileSync as readFileSync8,
2159
2191
  readdirSync,
2160
- unlinkSync,
2192
+ unlinkSync as unlinkSync2,
2161
2193
  existsSync as existsSync8,
2162
2194
  rmdirSync
2163
2195
  } from "fs";
@@ -2724,7 +2756,7 @@ var init_tasks_crud = __esm({
2724
2756
 
2725
2757
  // src/lib/tasks-review.ts
2726
2758
  import path9 from "path";
2727
- import { existsSync as existsSync10, readdirSync as readdirSync2, unlinkSync as unlinkSync2 } from "fs";
2759
+ import { existsSync as existsSync10, readdirSync as readdirSync2, unlinkSync as unlinkSync3 } from "fs";
2728
2760
  async function countPendingReviews(sessionScope) {
2729
2761
  const client = getClient();
2730
2762
  if (sessionScope) {
@@ -2909,7 +2941,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
2909
2941
  if (existsSync10(cacheDir)) {
2910
2942
  for (const f of readdirSync2(cacheDir)) {
2911
2943
  if (f.startsWith("review-notified-")) {
2912
- unlinkSync2(path9.join(cacheDir, f));
2944
+ unlinkSync3(path9.join(cacheDir, f));
2913
2945
  }
2914
2946
  }
2915
2947
  }
@@ -3515,7 +3547,7 @@ __export(tasks_exports, {
3515
3547
  writeCheckpoint: () => writeCheckpoint
3516
3548
  });
3517
3549
  import path12 from "path";
3518
- import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, unlinkSync as unlinkSync3 } from "fs";
3550
+ import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, unlinkSync as unlinkSync4 } from "fs";
3519
3551
  async function createTask(input) {
3520
3552
  const result = await createTaskCore(input);
3521
3553
  if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
@@ -3538,10 +3570,10 @@ async function updateTask(input) {
3538
3570
  const cachePath = path12.join(cacheDir, `current-task-${agent}.json`);
3539
3571
  if (input.status === "in_progress") {
3540
3572
  mkdirSync4(cacheDir, { recursive: true });
3541
- writeFileSync4(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
3573
+ writeFileSync5(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
3542
3574
  } else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled") {
3543
3575
  try {
3544
- unlinkSync3(cachePath);
3576
+ unlinkSync4(cachePath);
3545
3577
  } catch {
3546
3578
  }
3547
3579
  }
@@ -3983,11 +4015,11 @@ __export(tmux_routing_exports, {
3983
4015
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
3984
4016
  });
3985
4017
  import { execFileSync as execFileSync3, execSync as execSync7 } from "child_process";
3986
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, existsSync as existsSync11, appendFileSync } from "fs";
4018
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, existsSync as existsSync11, appendFileSync } from "fs";
3987
4019
  import path13 from "path";
3988
- import os5 from "os";
4020
+ import os6 from "os";
3989
4021
  import { fileURLToPath } from "url";
3990
- import { unlinkSync as unlinkSync4 } from "fs";
4022
+ import { unlinkSync as unlinkSync5 } from "fs";
3991
4023
  function spawnLockPath(sessionName) {
3992
4024
  return path13.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
3993
4025
  }
@@ -4014,12 +4046,12 @@ function acquireSpawnLock(sessionName) {
4014
4046
  } catch {
4015
4047
  }
4016
4048
  }
4017
- writeFileSync5(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
4049
+ writeFileSync6(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
4018
4050
  return true;
4019
4051
  }
4020
4052
  function releaseSpawnLock(sessionName) {
4021
4053
  try {
4022
- unlinkSync4(spawnLockPath(sessionName));
4054
+ unlinkSync5(spawnLockPath(sessionName));
4023
4055
  } catch {
4024
4056
  }
4025
4057
  }
@@ -4101,7 +4133,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
4101
4133
  }
4102
4134
  const rootExe = extractRootExe(parentExe) ?? parentExe;
4103
4135
  const filePath = path13.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
4104
- writeFileSync5(filePath, JSON.stringify({
4136
+ writeFileSync6(filePath, JSON.stringify({
4105
4137
  parentExe: rootExe,
4106
4138
  dispatchedBy: dispatchedBy || rootExe,
4107
4139
  registeredAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -4188,7 +4220,7 @@ function readDebounceState() {
4188
4220
  function writeDebounceState(state) {
4189
4221
  try {
4190
4222
  if (!existsSync11(SESSION_CACHE)) mkdirSync5(SESSION_CACHE, { recursive: true });
4191
- writeFileSync5(DEBOUNCE_FILE, JSON.stringify(state));
4223
+ writeFileSync6(DEBOUNCE_FILE, JSON.stringify(state));
4192
4224
  } catch {
4193
4225
  }
4194
4226
  }
@@ -4377,7 +4409,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4377
4409
  const transport = getTransport();
4378
4410
  const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
4379
4411
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
4380
- const logDir = path13.join(os5.homedir(), ".exe-os", "session-logs");
4412
+ const logDir = path13.join(os6.homedir(), ".exe-os", "session-logs");
4381
4413
  const logFile = path13.join(logDir, `${instanceLabel}-${Date.now()}.log`);
4382
4414
  if (!existsSync11(logDir)) {
4383
4415
  mkdirSync5(logDir, { recursive: true });
@@ -4393,7 +4425,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4393
4425
  } catch {
4394
4426
  }
4395
4427
  try {
4396
- const claudeJsonPath = path13.join(os5.homedir(), ".claude.json");
4428
+ const claudeJsonPath = path13.join(os6.homedir(), ".claude.json");
4397
4429
  let claudeJson = {};
4398
4430
  try {
4399
4431
  claudeJson = JSON.parse(readFileSync10(claudeJsonPath, "utf8"));
@@ -4404,11 +4436,11 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4404
4436
  const trustDir = opts?.cwd ?? projectDir;
4405
4437
  if (!projects[trustDir]) projects[trustDir] = {};
4406
4438
  projects[trustDir].hasTrustDialogAccepted = true;
4407
- writeFileSync5(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
4439
+ writeFileSync6(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
4408
4440
  } catch {
4409
4441
  }
4410
4442
  try {
4411
- const settingsDir = path13.join(os5.homedir(), ".claude", "projects");
4443
+ const settingsDir = path13.join(os6.homedir(), ".claude", "projects");
4412
4444
  const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
4413
4445
  const projSettingsDir = path13.join(settingsDir, normalizedKey);
4414
4446
  const settingsPath = path13.join(projSettingsDir, "settings.json");
@@ -4443,7 +4475,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4443
4475
  perms.allow = allow;
4444
4476
  settings.permissions = perms;
4445
4477
  mkdirSync5(projSettingsDir, { recursive: true });
4446
- writeFileSync5(settingsPath, JSON.stringify(settings, null, 2) + "\n");
4478
+ writeFileSync6(settingsPath, JSON.stringify(settings, null, 2) + "\n");
4447
4479
  }
4448
4480
  } catch {
4449
4481
  }
@@ -4456,7 +4488,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4456
4488
  let legacyFallbackWarned = false;
4457
4489
  if (!useExeAgent && !useBinSymlink) {
4458
4490
  const identityPath = path13.join(
4459
- os5.homedir(),
4491
+ os6.homedir(),
4460
4492
  ".exe-os",
4461
4493
  "identity",
4462
4494
  `${employeeName}.md`
@@ -4486,7 +4518,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4486
4518
  }
4487
4519
  let sessionContextFlag = "";
4488
4520
  try {
4489
- const ctxDir = path13.join(os5.homedir(), ".exe-os", "session-cache");
4521
+ const ctxDir = path13.join(os6.homedir(), ".exe-os", "session-cache");
4490
4522
  mkdirSync5(ctxDir, { recursive: true });
4491
4523
  const ctxFile = path13.join(ctxDir, `session-context-${sessionName}.md`);
4492
4524
  const ctxContent = [
@@ -4495,7 +4527,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4495
4527
  `Your parent exe session is ${exeSession}.`,
4496
4528
  `Your employees (if any) use the -${exeSession} suffix (e.g., tom-${exeSession}).`
4497
4529
  ].join("\n");
4498
- writeFileSync5(ctxFile, ctxContent);
4530
+ writeFileSync6(ctxFile, ctxContent);
4499
4531
  sessionContextFlag = ` --append-system-prompt-file ${ctxFile}`;
4500
4532
  } catch {
4501
4533
  }
@@ -4534,7 +4566,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4534
4566
  try {
4535
4567
  const mySession = getMySession();
4536
4568
  const dispatchInfo = path13.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
4537
- writeFileSync5(dispatchInfo, JSON.stringify({
4569
+ writeFileSync6(dispatchInfo, JSON.stringify({
4538
4570
  dispatchedBy: mySession,
4539
4571
  rootExe: exeSession,
4540
4572
  provider: useBinSymlink ? ccProvider : useExeAgent ? opts.provider : "anthropic",
@@ -4597,13 +4629,13 @@ var init_tmux_routing = __esm({
4597
4629
  init_provider_table();
4598
4630
  init_intercom_queue();
4599
4631
  init_plan_limits();
4600
- SPAWN_LOCK_DIR = path13.join(os5.homedir(), ".exe-os", "spawn-locks");
4601
- SESSION_CACHE = path13.join(os5.homedir(), ".exe-os", "session-cache");
4632
+ SPAWN_LOCK_DIR = path13.join(os6.homedir(), ".exe-os", "spawn-locks");
4633
+ SESSION_CACHE = path13.join(os6.homedir(), ".exe-os", "session-cache");
4602
4634
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
4603
4635
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
4604
4636
  VERIFY_PANE_LINES = 200;
4605
4637
  INTERCOM_DEBOUNCE_MS = 3e4;
4606
- INTERCOM_LOG2 = path13.join(os5.homedir(), ".exe-os", "intercom.log");
4638
+ INTERCOM_LOG2 = path13.join(os6.homedir(), ".exe-os", "intercom.log");
4607
4639
  DEBOUNCE_FILE = path13.join(SESSION_CACHE, "intercom-debounce.json");
4608
4640
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
4609
4641
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
@@ -6474,7 +6506,7 @@ var init_hooks = __esm({
6474
6506
 
6475
6507
  // src/runtime/safety-checks.ts
6476
6508
  import path14 from "path";
6477
- import os6 from "os";
6509
+ import os7 from "os";
6478
6510
  function checkPathSafety(filePath) {
6479
6511
  const resolved = path14.resolve(filePath);
6480
6512
  for (const { pattern, reason } of BYPASS_IMMUNE_PATTERNS) {
@@ -6501,7 +6533,7 @@ var HOME, BYPASS_IMMUNE_PATTERNS;
6501
6533
  var init_safety_checks = __esm({
6502
6534
  "src/runtime/safety-checks.ts"() {
6503
6535
  "use strict";
6504
- HOME = os6.homedir();
6536
+ HOME = os7.homedir();
6505
6537
  BYPASS_IMMUNE_PATTERNS = [
6506
6538
  {
6507
6539
  pattern: /\/\.git\/hooks\//,
@@ -7593,9 +7625,9 @@ __export(keychain_exports, {
7593
7625
  import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
7594
7626
  import { existsSync as existsSync12 } from "fs";
7595
7627
  import path22 from "path";
7596
- import os7 from "os";
7628
+ import os8 from "os";
7597
7629
  function getKeyDir() {
7598
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path22.join(os7.homedir(), ".exe-os");
7630
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path22.join(os8.homedir(), ".exe-os");
7599
7631
  }
7600
7632
  function getKeyPath() {
7601
7633
  return path22.join(getKeyDir(), "master.key");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askexenow/exe-os",
3
- "version": "0.8.65",
3
+ "version": "0.8.68",
4
4
  "description": "AI employee operating system — persistent memory, task management, and multi-agent coordination for Claude Code.",
5
5
  "license": "CC-BY-NC-4.0",
6
6
  "type": "module",