@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
@@ -1335,9 +1335,10 @@ var init_database = __esm({
1335
1335
 
1336
1336
  // src/lib/employees.ts
1337
1337
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
1338
- import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync4 } from "fs";
1338
+ import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync4, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "fs";
1339
1339
  import { execSync as execSync4 } from "child_process";
1340
1340
  import path5 from "path";
1341
+ import os4 from "os";
1341
1342
  var EMPLOYEES_PATH;
1342
1343
  var init_employees = __esm({
1343
1344
  "src/lib/employees.ts"() {
@@ -1348,7 +1349,7 @@ var init_employees = __esm({
1348
1349
  });
1349
1350
 
1350
1351
  // src/lib/license.ts
1351
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
1352
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
1352
1353
  import { randomUUID } from "crypto";
1353
1354
  import path6 from "path";
1354
1355
  import { jwtVerify, importSPKI } from "jose";
@@ -1379,9 +1380,9 @@ var init_plan_limits = __esm({
1379
1380
  });
1380
1381
 
1381
1382
  // src/lib/tmux-routing.ts
1382
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, existsSync as existsSync6, appendFileSync } from "fs";
1383
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync6, appendFileSync } from "fs";
1383
1384
  import path8 from "path";
1384
- import os4 from "os";
1385
+ import os5 from "os";
1385
1386
  import { fileURLToPath } from "url";
1386
1387
  function getMySession() {
1387
1388
  return getTransport().getMySession();
@@ -1423,9 +1424,9 @@ var init_tmux_routing = __esm({
1423
1424
  init_provider_table();
1424
1425
  init_intercom_queue();
1425
1426
  init_plan_limits();
1426
- SPAWN_LOCK_DIR = path8.join(os4.homedir(), ".exe-os", "spawn-locks");
1427
- SESSION_CACHE = path8.join(os4.homedir(), ".exe-os", "session-cache");
1428
- INTERCOM_LOG2 = path8.join(os4.homedir(), ".exe-os", "intercom.log");
1427
+ SPAWN_LOCK_DIR = path8.join(os5.homedir(), ".exe-os", "spawn-locks");
1428
+ SESSION_CACHE = path8.join(os5.homedir(), ".exe-os", "session-cache");
1429
+ INTERCOM_LOG2 = path8.join(os5.homedir(), ".exe-os", "intercom.log");
1429
1430
  DEBOUNCE_FILE = path8.join(SESSION_CACHE, "intercom-debounce.json");
1430
1431
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
1431
1432
  }
@@ -1468,9 +1469,9 @@ var init_memory = __esm({
1468
1469
  import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
1469
1470
  import { existsSync as existsSync7 } from "fs";
1470
1471
  import path9 from "path";
1471
- import os5 from "os";
1472
+ import os6 from "os";
1472
1473
  function getKeyDir() {
1473
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path9.join(os5.homedir(), ".exe-os");
1474
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path9.join(os6.homedir(), ".exe-os");
1474
1475
  }
1475
1476
  function getKeyPath() {
1476
1477
  return path9.join(getKeyDir(), "master.key");
@@ -1437,9 +1437,10 @@ var init_database = __esm({
1437
1437
 
1438
1438
  // src/lib/employees.ts
1439
1439
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
1440
- import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync5 } from "fs";
1440
+ import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "fs";
1441
1441
  import { execSync as execSync4 } from "child_process";
1442
1442
  import path5 from "path";
1443
+ import os4 from "os";
1443
1444
  function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
1444
1445
  if (!existsSync4(employeesPath)) return [];
1445
1446
  try {
@@ -1468,7 +1469,7 @@ var init_employees = __esm({
1468
1469
  });
1469
1470
 
1470
1471
  // src/lib/license.ts
1471
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync5, mkdirSync as mkdirSync4 } from "fs";
1472
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, existsSync as existsSync5, mkdirSync as mkdirSync4 } from "fs";
1472
1473
  import { randomUUID } from "crypto";
1473
1474
  import path6 from "path";
1474
1475
  import { jwtVerify, importSPKI } from "jose";
@@ -1571,11 +1572,11 @@ var init_plan_limits = __esm({
1571
1572
  // src/lib/notifications.ts
1572
1573
  import crypto from "crypto";
1573
1574
  import path8 from "path";
1574
- import os4 from "os";
1575
+ import os5 from "os";
1575
1576
  import {
1576
1577
  readFileSync as readFileSync8,
1577
1578
  readdirSync as readdirSync2,
1578
- unlinkSync as unlinkSync2,
1579
+ unlinkSync as unlinkSync3,
1579
1580
  existsSync as existsSync7,
1580
1581
  rmdirSync
1581
1582
  } from "fs";
@@ -2127,7 +2128,7 @@ var init_tasks_crud = __esm({
2127
2128
 
2128
2129
  // src/lib/tasks-review.ts
2129
2130
  import path10 from "path";
2130
- import { existsSync as existsSync9, readdirSync as readdirSync3, unlinkSync as unlinkSync3 } from "fs";
2131
+ import { existsSync as existsSync9, readdirSync as readdirSync3, unlinkSync as unlinkSync4 } from "fs";
2131
2132
  async function countPendingReviews(sessionScope) {
2132
2133
  const client = getClient();
2133
2134
  if (sessionScope) {
@@ -2312,7 +2313,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
2312
2313
  if (existsSync9(cacheDir)) {
2313
2314
  for (const f of readdirSync3(cacheDir)) {
2314
2315
  if (f.startsWith("review-notified-")) {
2315
- unlinkSync3(path10.join(cacheDir, f));
2316
+ unlinkSync4(path10.join(cacheDir, f));
2316
2317
  }
2317
2318
  }
2318
2319
  }
@@ -2918,7 +2919,7 @@ __export(tasks_exports, {
2918
2919
  writeCheckpoint: () => writeCheckpoint
2919
2920
  });
2920
2921
  import path13 from "path";
2921
- import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, unlinkSync as unlinkSync4 } from "fs";
2922
+ import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, unlinkSync as unlinkSync5 } from "fs";
2922
2923
  async function createTask(input2) {
2923
2924
  const result = await createTaskCore(input2);
2924
2925
  if (!input2.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
@@ -2941,10 +2942,10 @@ async function updateTask(input2) {
2941
2942
  const cachePath = path13.join(cacheDir, `current-task-${agent}.json`);
2942
2943
  if (input2.status === "in_progress") {
2943
2944
  mkdirSync5(cacheDir, { recursive: true });
2944
- writeFileSync5(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
2945
+ writeFileSync6(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
2945
2946
  } else if (input2.status === "done" || input2.status === "blocked" || input2.status === "cancelled") {
2946
2947
  try {
2947
- unlinkSync4(cachePath);
2948
+ unlinkSync5(cachePath);
2948
2949
  } catch {
2949
2950
  }
2950
2951
  }
@@ -3386,11 +3387,11 @@ __export(tmux_routing_exports, {
3386
3387
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
3387
3388
  });
3388
3389
  import { execFileSync as execFileSync2, execSync as execSync7 } from "child_process";
3389
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, existsSync as existsSync10, appendFileSync } from "fs";
3390
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, existsSync as existsSync10, appendFileSync } from "fs";
3390
3391
  import path14 from "path";
3391
- import os5 from "os";
3392
+ import os6 from "os";
3392
3393
  import { fileURLToPath } from "url";
3393
- import { unlinkSync as unlinkSync5 } from "fs";
3394
+ import { unlinkSync as unlinkSync6 } from "fs";
3394
3395
  function spawnLockPath(sessionName) {
3395
3396
  return path14.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
3396
3397
  }
@@ -3417,12 +3418,12 @@ function acquireSpawnLock(sessionName) {
3417
3418
  } catch {
3418
3419
  }
3419
3420
  }
3420
- writeFileSync6(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
3421
+ writeFileSync7(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
3421
3422
  return true;
3422
3423
  }
3423
3424
  function releaseSpawnLock(sessionName) {
3424
3425
  try {
3425
- unlinkSync5(spawnLockPath(sessionName));
3426
+ unlinkSync6(spawnLockPath(sessionName));
3426
3427
  } catch {
3427
3428
  }
3428
3429
  }
@@ -3504,7 +3505,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
3504
3505
  }
3505
3506
  const rootExe = extractRootExe(parentExe) ?? parentExe;
3506
3507
  const filePath = path14.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
3507
- writeFileSync6(filePath, JSON.stringify({
3508
+ writeFileSync7(filePath, JSON.stringify({
3508
3509
  parentExe: rootExe,
3509
3510
  dispatchedBy: dispatchedBy || rootExe,
3510
3511
  registeredAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -3591,7 +3592,7 @@ function readDebounceState() {
3591
3592
  function writeDebounceState(state) {
3592
3593
  try {
3593
3594
  if (!existsSync10(SESSION_CACHE)) mkdirSync6(SESSION_CACHE, { recursive: true });
3594
- writeFileSync6(DEBOUNCE_FILE, JSON.stringify(state));
3595
+ writeFileSync7(DEBOUNCE_FILE, JSON.stringify(state));
3595
3596
  } catch {
3596
3597
  }
3597
3598
  }
@@ -3780,7 +3781,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3780
3781
  const transport = getTransport();
3781
3782
  const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
3782
3783
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
3783
- const logDir = path14.join(os5.homedir(), ".exe-os", "session-logs");
3784
+ const logDir = path14.join(os6.homedir(), ".exe-os", "session-logs");
3784
3785
  const logFile = path14.join(logDir, `${instanceLabel}-${Date.now()}.log`);
3785
3786
  if (!existsSync10(logDir)) {
3786
3787
  mkdirSync6(logDir, { recursive: true });
@@ -3796,7 +3797,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3796
3797
  } catch {
3797
3798
  }
3798
3799
  try {
3799
- const claudeJsonPath = path14.join(os5.homedir(), ".claude.json");
3800
+ const claudeJsonPath = path14.join(os6.homedir(), ".claude.json");
3800
3801
  let claudeJson = {};
3801
3802
  try {
3802
3803
  claudeJson = JSON.parse(readFileSync10(claudeJsonPath, "utf8"));
@@ -3807,11 +3808,11 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3807
3808
  const trustDir = opts?.cwd ?? projectDir;
3808
3809
  if (!projects[trustDir]) projects[trustDir] = {};
3809
3810
  projects[trustDir].hasTrustDialogAccepted = true;
3810
- writeFileSync6(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
3811
+ writeFileSync7(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
3811
3812
  } catch {
3812
3813
  }
3813
3814
  try {
3814
- const settingsDir = path14.join(os5.homedir(), ".claude", "projects");
3815
+ const settingsDir = path14.join(os6.homedir(), ".claude", "projects");
3815
3816
  const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
3816
3817
  const projSettingsDir = path14.join(settingsDir, normalizedKey);
3817
3818
  const settingsPath = path14.join(projSettingsDir, "settings.json");
@@ -3846,7 +3847,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3846
3847
  perms.allow = allow;
3847
3848
  settings.permissions = perms;
3848
3849
  mkdirSync6(projSettingsDir, { recursive: true });
3849
- writeFileSync6(settingsPath, JSON.stringify(settings, null, 2) + "\n");
3850
+ writeFileSync7(settingsPath, JSON.stringify(settings, null, 2) + "\n");
3850
3851
  }
3851
3852
  } catch {
3852
3853
  }
@@ -3859,7 +3860,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3859
3860
  let legacyFallbackWarned = false;
3860
3861
  if (!useExeAgent && !useBinSymlink) {
3861
3862
  const identityPath = path14.join(
3862
- os5.homedir(),
3863
+ os6.homedir(),
3863
3864
  ".exe-os",
3864
3865
  "identity",
3865
3866
  `${employeeName}.md`
@@ -3889,7 +3890,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3889
3890
  }
3890
3891
  let sessionContextFlag = "";
3891
3892
  try {
3892
- const ctxDir = path14.join(os5.homedir(), ".exe-os", "session-cache");
3893
+ const ctxDir = path14.join(os6.homedir(), ".exe-os", "session-cache");
3893
3894
  mkdirSync6(ctxDir, { recursive: true });
3894
3895
  const ctxFile = path14.join(ctxDir, `session-context-${sessionName}.md`);
3895
3896
  const ctxContent = [
@@ -3898,7 +3899,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3898
3899
  `Your parent exe session is ${exeSession}.`,
3899
3900
  `Your employees (if any) use the -${exeSession} suffix (e.g., tom-${exeSession}).`
3900
3901
  ].join("\n");
3901
- writeFileSync6(ctxFile, ctxContent);
3902
+ writeFileSync7(ctxFile, ctxContent);
3902
3903
  sessionContextFlag = ` --append-system-prompt-file ${ctxFile}`;
3903
3904
  } catch {
3904
3905
  }
@@ -3937,7 +3938,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3937
3938
  try {
3938
3939
  const mySession = getMySession();
3939
3940
  const dispatchInfo = path14.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
3940
- writeFileSync6(dispatchInfo, JSON.stringify({
3941
+ writeFileSync7(dispatchInfo, JSON.stringify({
3941
3942
  dispatchedBy: mySession,
3942
3943
  rootExe: exeSession,
3943
3944
  provider: useBinSymlink ? ccProvider : useExeAgent ? opts.provider : "anthropic",
@@ -4000,13 +4001,13 @@ var init_tmux_routing = __esm({
4000
4001
  init_provider_table();
4001
4002
  init_intercom_queue();
4002
4003
  init_plan_limits();
4003
- SPAWN_LOCK_DIR = path14.join(os5.homedir(), ".exe-os", "spawn-locks");
4004
- SESSION_CACHE = path14.join(os5.homedir(), ".exe-os", "session-cache");
4004
+ SPAWN_LOCK_DIR = path14.join(os6.homedir(), ".exe-os", "spawn-locks");
4005
+ SESSION_CACHE = path14.join(os6.homedir(), ".exe-os", "session-cache");
4005
4006
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
4006
4007
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
4007
4008
  VERIFY_PANE_LINES = 200;
4008
4009
  INTERCOM_DEBOUNCE_MS = 3e4;
4009
- INTERCOM_LOG2 = path14.join(os5.homedir(), ".exe-os", "intercom.log");
4010
+ INTERCOM_LOG2 = path14.join(os6.homedir(), ".exe-os", "intercom.log");
4010
4011
  DEBOUNCE_FILE = path14.join(SESSION_CACHE, "intercom-debounce.json");
4011
4012
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
4012
4013
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
@@ -4050,9 +4051,9 @@ var init_memory = __esm({
4050
4051
  import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
4051
4052
  import { existsSync as existsSync11 } from "fs";
4052
4053
  import path15 from "path";
4053
- import os6 from "os";
4054
+ import os7 from "os";
4054
4055
  function getKeyDir() {
4055
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path15.join(os6.homedir(), ".exe-os");
4056
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path15.join(os7.homedir(), ".exe-os");
4056
4057
  }
4057
4058
  function getKeyPath() {
4058
4059
  return path15.join(getKeyDir(), "master.key");
@@ -1345,14 +1345,16 @@ __export(employees_exports, {
1345
1345
  isMultiInstance: () => isMultiInstance,
1346
1346
  loadEmployees: () => loadEmployees,
1347
1347
  loadEmployeesSync: () => loadEmployeesSync,
1348
+ normalizeRosterCase: () => normalizeRosterCase,
1348
1349
  registerBinSymlinks: () => registerBinSymlinks,
1349
1350
  saveEmployees: () => saveEmployees,
1350
1351
  validateEmployeeName: () => validateEmployeeName
1351
1352
  });
1352
1353
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
1353
- import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync4 } from "fs";
1354
+ import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync4, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "fs";
1354
1355
  import { execSync as execSync4 } from "child_process";
1355
1356
  import path5 from "path";
1357
+ import os4 from "os";
1356
1358
  function validateEmployeeName(name) {
1357
1359
  if (!name) {
1358
1360
  return { valid: false, error: "Name is required" };
@@ -1420,6 +1422,36 @@ function addEmployee(employees, employee) {
1420
1422
  }
1421
1423
  return [...employees, normalized];
1422
1424
  }
1425
+ async function normalizeRosterCase(rosterPath) {
1426
+ const employees = await loadEmployees(rosterPath);
1427
+ let changed = false;
1428
+ for (const emp of employees) {
1429
+ if (emp.name !== emp.name.toLowerCase()) {
1430
+ const oldName = emp.name;
1431
+ emp.name = emp.name.toLowerCase();
1432
+ changed = true;
1433
+ try {
1434
+ const identityDir = path5.join(os4.homedir(), ".exe-os", "identity");
1435
+ const oldPath = path5.join(identityDir, `${oldName}.md`);
1436
+ const newPath = path5.join(identityDir, `${emp.name}.md`);
1437
+ if (existsSync3(oldPath) && !existsSync3(newPath)) {
1438
+ renameSync3(oldPath, newPath);
1439
+ } else if (existsSync3(oldPath) && oldPath !== newPath) {
1440
+ const content = readFileSync4(oldPath, "utf-8");
1441
+ writeFileSync3(newPath, content, "utf-8");
1442
+ if (oldPath.toLowerCase() !== newPath.toLowerCase()) {
1443
+ unlinkSync2(oldPath);
1444
+ }
1445
+ }
1446
+ } catch {
1447
+ }
1448
+ }
1449
+ }
1450
+ if (changed) {
1451
+ await saveEmployees(employees, rosterPath);
1452
+ }
1453
+ return changed;
1454
+ }
1423
1455
  function findExeBin() {
1424
1456
  try {
1425
1457
  return execSync4(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
@@ -1471,7 +1503,7 @@ var init_employees = __esm({
1471
1503
  });
1472
1504
 
1473
1505
  // src/lib/license.ts
1474
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
1506
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
1475
1507
  import { randomUUID } from "crypto";
1476
1508
  import path6 from "path";
1477
1509
  import { jwtVerify, importSPKI } from "jose";
@@ -1502,9 +1534,9 @@ var init_plan_limits = __esm({
1502
1534
  });
1503
1535
 
1504
1536
  // src/lib/tmux-routing.ts
1505
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, existsSync as existsSync6, appendFileSync } from "fs";
1537
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync6, appendFileSync } from "fs";
1506
1538
  import path8 from "path";
1507
- import os4 from "os";
1539
+ import os5 from "os";
1508
1540
  import { fileURLToPath } from "url";
1509
1541
  function getMySession() {
1510
1542
  return getTransport().getMySession();
@@ -1546,9 +1578,9 @@ var init_tmux_routing = __esm({
1546
1578
  init_provider_table();
1547
1579
  init_intercom_queue();
1548
1580
  init_plan_limits();
1549
- SPAWN_LOCK_DIR = path8.join(os4.homedir(), ".exe-os", "spawn-locks");
1550
- SESSION_CACHE = path8.join(os4.homedir(), ".exe-os", "session-cache");
1551
- INTERCOM_LOG2 = path8.join(os4.homedir(), ".exe-os", "intercom.log");
1581
+ SPAWN_LOCK_DIR = path8.join(os5.homedir(), ".exe-os", "spawn-locks");
1582
+ SESSION_CACHE = path8.join(os5.homedir(), ".exe-os", "session-cache");
1583
+ INTERCOM_LOG2 = path8.join(os5.homedir(), ".exe-os", "intercom.log");
1552
1584
  DEBOUNCE_FILE = path8.join(SESSION_CACHE, "intercom-debounce.json");
1553
1585
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
1554
1586
  }
@@ -1590,7 +1622,7 @@ __export(yoshi_delegation_gate_exports, {
1590
1622
  hasValidScratchpadEscape: () => hasValidScratchpadEscape,
1591
1623
  scratchpadPath: () => scratchpadPath
1592
1624
  });
1593
- import os5 from "os";
1625
+ import os6 from "os";
1594
1626
  import path9 from "path";
1595
1627
  import { existsSync as existsSync7, readFileSync as readFileSync8, statSync } from "fs";
1596
1628
  function resolveGatedAgent() {
@@ -1658,7 +1690,7 @@ async function hasRecentTomDispatch(now = Date.now()) {
1658
1690
  return false;
1659
1691
  }
1660
1692
  }
1661
- function scratchpadPath(sessionId, homeDir = os5.homedir()) {
1693
+ function scratchpadPath(sessionId, homeDir = os6.homedir()) {
1662
1694
  return path9.join(
1663
1695
  homeDir,
1664
1696
  ".exe-os",
@@ -1666,7 +1698,7 @@ function scratchpadPath(sessionId, homeDir = os5.homedir()) {
1666
1698
  `yoshi-scratchpad-${sessionId}.txt`
1667
1699
  );
1668
1700
  }
1669
- function hasValidScratchpadEscape(sessionId, now = Date.now(), homeDir = os5.homedir()) {
1701
+ function hasValidScratchpadEscape(sessionId, now = Date.now(), homeDir = os6.homedir()) {
1670
1702
  const filePath = scratchpadPath(sessionId, homeDir);
1671
1703
  if (!existsSync7(filePath)) return false;
1672
1704
  try {
@@ -1765,9 +1797,9 @@ var init_memory = __esm({
1765
1797
  import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
1766
1798
  import { existsSync as existsSync8 } from "fs";
1767
1799
  import path10 from "path";
1768
- import os6 from "os";
1800
+ import os7 from "os";
1769
1801
  function getKeyDir() {
1770
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path10.join(os6.homedir(), ".exe-os");
1802
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path10.join(os7.homedir(), ".exe-os");
1771
1803
  }
1772
1804
  function getKeyPath() {
1773
1805
  return path10.join(getKeyDir(), "master.key");
@@ -2902,7 +2934,7 @@ var init_review_gate = __esm({
2902
2934
  });
2903
2935
 
2904
2936
  // src/adapters/claude/hooks/pre-tool-use.ts
2905
- import { existsSync as existsSync11, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6 } from "fs";
2937
+ import { existsSync as existsSync11, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6 } from "fs";
2906
2938
  import { execSync as execSync6 } from "child_process";
2907
2939
  import path12 from "path";
2908
2940
 
@@ -2997,7 +3029,7 @@ function hasDelegationFired() {
2997
3029
  function markDelegationFired() {
2998
3030
  try {
2999
3031
  mkdirSync6(CACHE_DIR2, { recursive: true });
3000
- writeFileSync5(getDelegationFlagPath(), JSON.stringify({ fired: true }));
3032
+ writeFileSync6(getDelegationFlagPath(), JSON.stringify({ fired: true }));
3001
3033
  } catch {
3002
3034
  }
3003
3035
  }
@@ -1607,7 +1607,7 @@ ${p.content}`).join("\n\n");
1607
1607
  import net from "net";
1608
1608
  import { spawn } from "child_process";
1609
1609
  import { randomUUID as randomUUID3 } from "crypto";
1610
- import { existsSync as existsSync7, unlinkSync, readFileSync as readFileSync5, openSync, closeSync, statSync } from "fs";
1610
+ import { existsSync as existsSync7, unlinkSync as unlinkSync2, readFileSync as readFileSync5, openSync, closeSync, statSync } from "fs";
1611
1611
  import path8 from "path";
1612
1612
  import { fileURLToPath } from "url";
1613
1613
  function handleData(chunk) {
@@ -1647,11 +1647,11 @@ function cleanupStaleFiles() {
1647
1647
  } catch {
1648
1648
  }
1649
1649
  try {
1650
- unlinkSync(PID_PATH);
1650
+ unlinkSync2(PID_PATH);
1651
1651
  } catch {
1652
1652
  }
1653
1653
  try {
1654
- unlinkSync(SOCKET_PATH);
1654
+ unlinkSync2(SOCKET_PATH);
1655
1655
  } catch {
1656
1656
  }
1657
1657
  }
@@ -1713,7 +1713,7 @@ function acquireSpawnLock() {
1713
1713
  const stat = statSync(SPAWN_LOCK_PATH);
1714
1714
  if (Date.now() - stat.mtimeMs > SPAWN_LOCK_STALE_MS) {
1715
1715
  try {
1716
- unlinkSync(SPAWN_LOCK_PATH);
1716
+ unlinkSync2(SPAWN_LOCK_PATH);
1717
1717
  } catch {
1718
1718
  }
1719
1719
  try {
@@ -1730,7 +1730,7 @@ function acquireSpawnLock() {
1730
1730
  }
1731
1731
  function releaseSpawnLock() {
1732
1732
  try {
1733
- unlinkSync(SPAWN_LOCK_PATH);
1733
+ unlinkSync2(SPAWN_LOCK_PATH);
1734
1734
  } catch {
1735
1735
  }
1736
1736
  }
@@ -1861,11 +1861,11 @@ function killAndRespawnDaemon() {
1861
1861
  _connected = false;
1862
1862
  _buffer = "";
1863
1863
  try {
1864
- unlinkSync(PID_PATH);
1864
+ unlinkSync2(PID_PATH);
1865
1865
  } catch {
1866
1866
  }
1867
1867
  try {
1868
- unlinkSync(SOCKET_PATH);
1868
+ unlinkSync2(SOCKET_PATH);
1869
1869
  } catch {
1870
1870
  }
1871
1871
  spawnDaemon();
@@ -2014,7 +2014,7 @@ var init_embedder = __esm({
2014
2014
 
2015
2015
  // src/adapters/claude/hooks/prompt-ingest-worker.ts
2016
2016
  import crypto from "crypto";
2017
- import { writeFileSync as writeFileSync2 } from "fs";
2017
+ import { writeFileSync as writeFileSync3 } from "fs";
2018
2018
  import path9 from "path";
2019
2019
 
2020
2020
  // src/lib/project-name.ts
@@ -2437,14 +2437,15 @@ import path7 from "path";
2437
2437
  // src/lib/employees.ts
2438
2438
  init_config();
2439
2439
  import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
2440
- import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync2 } from "fs";
2440
+ import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
2441
2441
  import { execSync as execSync2 } from "child_process";
2442
2442
  import path5 from "path";
2443
+ import os3 from "os";
2443
2444
  var EMPLOYEES_PATH = path5.join(EXE_AI_DIR, "exe-employees.json");
2444
2445
 
2445
2446
  // src/lib/license.ts
2446
2447
  init_config();
2447
- import { readFileSync as readFileSync3, writeFileSync, existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
2448
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
2448
2449
  import { randomUUID as randomUUID2 } from "crypto";
2449
2450
  import path6 from "path";
2450
2451
  import { jwtVerify, importSPKI } from "jose";
@@ -2500,7 +2501,7 @@ function loadDeviceId() {
2500
2501
  }
2501
2502
  const id = randomUUID2();
2502
2503
  mkdirSync2(EXE_AI_DIR, { recursive: true });
2503
- writeFileSync(DEVICE_ID_PATH, id, "utf8");
2504
+ writeFileSync2(DEVICE_ID_PATH, id, "utf8");
2504
2505
  return id;
2505
2506
  }
2506
2507
  function loadLicense() {
@@ -2513,7 +2514,7 @@ function loadLicense() {
2513
2514
  }
2514
2515
  function saveLicense(apiKey) {
2515
2516
  mkdirSync2(EXE_AI_DIR, { recursive: true });
2516
- writeFileSync(LICENSE_PATH, apiKey.trim(), { encoding: "utf8", mode: 384 });
2517
+ writeFileSync2(LICENSE_PATH, apiKey.trim(), { encoding: "utf8", mode: 384 });
2517
2518
  }
2518
2519
  async function verifyLicenseJwt(token) {
2519
2520
  try {
@@ -2584,7 +2585,7 @@ function getRawCachedPlan() {
2584
2585
  }
2585
2586
  function cacheResponse(token) {
2586
2587
  try {
2587
- writeFileSync(CACHE_PATH, JSON.stringify({ token }), "utf8");
2588
+ writeFileSync2(CACHE_PATH, JSON.stringify({ token }), "utf8");
2588
2589
  } catch {
2589
2590
  }
2590
2591
  }
@@ -2740,7 +2741,7 @@ async function main() {
2740
2741
  try {
2741
2742
  const { EXE_AI_DIR: exeDir } = await Promise.resolve().then(() => (init_config(), config_exports));
2742
2743
  const flagPath = path9.join(exeDir, "session-cache", "needs-backfill");
2743
- writeFileSync2(flagPath, "1");
2744
+ writeFileSync3(flagPath, "1");
2744
2745
  } catch (err) {
2745
2746
  process.stderr.write(`[prompt-ingest-worker] backfill flag write failed: ${err instanceof Error ? err.message : String(err)}
2746
2747
  `);
@@ -3399,9 +3399,10 @@ var init_intercom_queue = __esm({
3399
3399
 
3400
3400
  // src/lib/employees.ts
3401
3401
  import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
3402
- import { existsSync as existsSync8, symlinkSync, readlinkSync, readFileSync as readFileSync6 } from "fs";
3402
+ import { existsSync as existsSync8, symlinkSync, readlinkSync, readFileSync as readFileSync6, renameSync as renameSync3, unlinkSync as unlinkSync3, writeFileSync as writeFileSync3 } from "fs";
3403
3403
  import { execSync as execSync6 } from "child_process";
3404
3404
  import path11 from "path";
3405
+ import os5 from "os";
3405
3406
  async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
3406
3407
  if (!existsSync8(employeesPath)) {
3407
3408
  return [];
@@ -3426,7 +3427,7 @@ var init_employees = __esm({
3426
3427
  });
3427
3428
 
3428
3429
  // src/lib/license.ts
3429
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync3, existsSync as existsSync9, mkdirSync as mkdirSync4 } from "fs";
3430
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, existsSync as existsSync9, mkdirSync as mkdirSync4 } from "fs";
3430
3431
  import { randomUUID as randomUUID3 } from "crypto";
3431
3432
  import path12 from "path";
3432
3433
  import { jwtVerify, importSPKI } from "jose";
@@ -3457,9 +3458,9 @@ var init_plan_limits = __esm({
3457
3458
  });
3458
3459
 
3459
3460
  // src/lib/tmux-routing.ts
3460
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, existsSync as existsSync11, appendFileSync } from "fs";
3461
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, existsSync as existsSync11, appendFileSync } from "fs";
3461
3462
  import path14 from "path";
3462
- import os5 from "os";
3463
+ import os6 from "os";
3463
3464
  import { fileURLToPath as fileURLToPath2 } from "url";
3464
3465
  function getMySession() {
3465
3466
  return getTransport().getMySession();
@@ -3530,7 +3531,7 @@ function readDebounceState() {
3530
3531
  function writeDebounceState(state) {
3531
3532
  try {
3532
3533
  if (!existsSync11(SESSION_CACHE)) mkdirSync5(SESSION_CACHE, { recursive: true });
3533
- writeFileSync4(DEBOUNCE_FILE, JSON.stringify(state));
3534
+ writeFileSync5(DEBOUNCE_FILE, JSON.stringify(state));
3534
3535
  } catch {
3535
3536
  }
3536
3537
  }
@@ -3632,11 +3633,11 @@ var init_tmux_routing = __esm({
3632
3633
  init_provider_table();
3633
3634
  init_intercom_queue();
3634
3635
  init_plan_limits();
3635
- SPAWN_LOCK_DIR = path14.join(os5.homedir(), ".exe-os", "spawn-locks");
3636
- SESSION_CACHE = path14.join(os5.homedir(), ".exe-os", "session-cache");
3636
+ SPAWN_LOCK_DIR = path14.join(os6.homedir(), ".exe-os", "spawn-locks");
3637
+ SESSION_CACHE = path14.join(os6.homedir(), ".exe-os", "session-cache");
3637
3638
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
3638
3639
  INTERCOM_DEBOUNCE_MS = 3e4;
3639
- INTERCOM_LOG2 = path14.join(os5.homedir(), ".exe-os", "intercom.log");
3640
+ INTERCOM_LOG2 = path14.join(os6.homedir(), ".exe-os", "intercom.log");
3640
3641
  DEBOUNCE_FILE = path14.join(SESSION_CACHE, "intercom-debounce.json");
3641
3642
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
3642
3643
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
@@ -3897,11 +3898,11 @@ var init_messaging = __esm({
3897
3898
  // src/lib/notifications.ts
3898
3899
  import crypto3 from "crypto";
3899
3900
  import path15 from "path";
3900
- import os6 from "os";
3901
+ import os7 from "os";
3901
3902
  import {
3902
3903
  readFileSync as readFileSync10,
3903
3904
  readdirSync as readdirSync4,
3904
- unlinkSync as unlinkSync3,
3905
+ unlinkSync as unlinkSync4,
3905
3906
  existsSync as existsSync12,
3906
3907
  rmdirSync
3907
3908
  } from "fs";
@@ -3948,7 +3949,7 @@ __export(tasks_review_exports, {
3948
3949
  listPendingReviews: () => listPendingReviews
3949
3950
  });
3950
3951
  import path16 from "path";
3951
- import { existsSync as existsSync13, readdirSync as readdirSync5, unlinkSync as unlinkSync4 } from "fs";
3952
+ import { existsSync as existsSync13, readdirSync as readdirSync5, unlinkSync as unlinkSync5 } from "fs";
3952
3953
  async function countPendingReviews(sessionScope) {
3953
3954
  const client = getClient();
3954
3955
  if (sessionScope) {
@@ -4220,7 +4221,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
4220
4221
  if (existsSync13(cacheDir)) {
4221
4222
  for (const f of readdirSync5(cacheDir)) {
4222
4223
  if (f.startsWith("review-notified-")) {
4223
- unlinkSync4(path16.join(cacheDir, f));
4224
+ unlinkSync5(path16.join(cacheDir, f));
4224
4225
  }
4225
4226
  }
4226
4227
  }
@@ -4245,7 +4246,7 @@ init_config();
4245
4246
  init_config();
4246
4247
  init_store();
4247
4248
  import { spawn as spawn2 } from "child_process";
4248
- import { readFileSync as readFileSync11, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, existsSync as existsSync14, openSync as openSync2, closeSync as closeSync2 } from "fs";
4249
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, existsSync as existsSync14, openSync as openSync2, closeSync as closeSync2 } from "fs";
4249
4250
  import path17 from "path";
4250
4251
  import { fileURLToPath as fileURLToPath3 } from "url";
4251
4252
 
@@ -4697,7 +4698,7 @@ function loadInjectedIds(sessionId) {
4697
4698
  function saveInjectedIds(sessionId, ids) {
4698
4699
  try {
4699
4700
  mkdirSync6(CACHE_DIR2, { recursive: true });
4700
- writeFileSync5(
4701
+ writeFileSync6(
4701
4702
  path17.join(CACHE_DIR2, `${sessionId}.json`),
4702
4703
  JSON.stringify([...ids])
4703
4704
  );