@askexenow/exe-os 0.8.65 → 0.8.69

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 +84 -19
  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
@@ -1612,9 +1612,10 @@ var init_database = __esm({
1612
1612
 
1613
1613
  // src/lib/employees.ts
1614
1614
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
1615
- import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync4 } from "fs";
1615
+ import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync4, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
1616
1616
  import { execSync as execSync4 } from "child_process";
1617
1617
  import path4 from "path";
1618
+ import os4 from "os";
1618
1619
  async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
1619
1620
  if (!existsSync4(employeesPath)) {
1620
1621
  return [];
@@ -1654,7 +1655,7 @@ var init_employees = __esm({
1654
1655
  });
1655
1656
 
1656
1657
  // src/lib/license.ts
1657
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
1658
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
1658
1659
  import { randomUUID } from "crypto";
1659
1660
  import path5 from "path";
1660
1661
  import { jwtVerify, importSPKI } from "jose";
@@ -1757,11 +1758,11 @@ var init_plan_limits = __esm({
1757
1758
  // src/lib/notifications.ts
1758
1759
  import crypto from "crypto";
1759
1760
  import path7 from "path";
1760
- import os4 from "os";
1761
+ import os5 from "os";
1761
1762
  import {
1762
1763
  readFileSync as readFileSync7,
1763
1764
  readdirSync,
1764
- unlinkSync,
1765
+ unlinkSync as unlinkSync2,
1765
1766
  existsSync as existsSync7,
1766
1767
  rmdirSync
1767
1768
  } from "fs";
@@ -2417,7 +2418,7 @@ __export(tasks_review_exports, {
2417
2418
  listPendingReviews: () => listPendingReviews
2418
2419
  });
2419
2420
  import path9 from "path";
2420
- import { existsSync as existsSync9, readdirSync as readdirSync2, unlinkSync as unlinkSync2 } from "fs";
2421
+ import { existsSync as existsSync9, readdirSync as readdirSync2, unlinkSync as unlinkSync3 } from "fs";
2421
2422
  async function countPendingReviews(sessionScope) {
2422
2423
  const client = getClient();
2423
2424
  if (sessionScope) {
@@ -2689,7 +2690,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
2689
2690
  if (existsSync9(cacheDir)) {
2690
2691
  for (const f of readdirSync2(cacheDir)) {
2691
2692
  if (f.startsWith("review-notified-")) {
2692
- unlinkSync2(path9.join(cacheDir, f));
2693
+ unlinkSync3(path9.join(cacheDir, f));
2693
2694
  }
2694
2695
  }
2695
2696
  }
@@ -3295,7 +3296,7 @@ __export(tasks_exports, {
3295
3296
  writeCheckpoint: () => writeCheckpoint
3296
3297
  });
3297
3298
  import path12 from "path";
3298
- import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, unlinkSync as unlinkSync3 } from "fs";
3299
+ import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, unlinkSync as unlinkSync4 } from "fs";
3299
3300
  async function createTask(input) {
3300
3301
  const result = await createTaskCore(input);
3301
3302
  if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
@@ -3318,10 +3319,10 @@ async function updateTask(input) {
3318
3319
  const cachePath = path12.join(cacheDir, `current-task-${agent}.json`);
3319
3320
  if (input.status === "in_progress") {
3320
3321
  mkdirSync4(cacheDir, { recursive: true });
3321
- writeFileSync4(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
3322
+ writeFileSync5(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
3322
3323
  } else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled") {
3323
3324
  try {
3324
- unlinkSync3(cachePath);
3325
+ unlinkSync4(cachePath);
3325
3326
  } catch {
3326
3327
  }
3327
3328
  }
@@ -3763,11 +3764,11 @@ __export(tmux_routing_exports, {
3763
3764
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
3764
3765
  });
3765
3766
  import { execFileSync as execFileSync2, execSync as execSync7 } from "child_process";
3766
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, existsSync as existsSync10, appendFileSync } from "fs";
3767
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, existsSync as existsSync10, appendFileSync } from "fs";
3767
3768
  import path13 from "path";
3768
- import os5 from "os";
3769
+ import os6 from "os";
3769
3770
  import { fileURLToPath } from "url";
3770
- import { unlinkSync as unlinkSync4 } from "fs";
3771
+ import { unlinkSync as unlinkSync5 } from "fs";
3771
3772
  function spawnLockPath(sessionName) {
3772
3773
  return path13.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
3773
3774
  }
@@ -3794,12 +3795,12 @@ function acquireSpawnLock(sessionName) {
3794
3795
  } catch {
3795
3796
  }
3796
3797
  }
3797
- writeFileSync5(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
3798
+ writeFileSync6(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
3798
3799
  return true;
3799
3800
  }
3800
3801
  function releaseSpawnLock(sessionName) {
3801
3802
  try {
3802
- unlinkSync4(spawnLockPath(sessionName));
3803
+ unlinkSync5(spawnLockPath(sessionName));
3803
3804
  } catch {
3804
3805
  }
3805
3806
  }
@@ -3881,7 +3882,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
3881
3882
  }
3882
3883
  const rootExe = extractRootExe(parentExe) ?? parentExe;
3883
3884
  const filePath = path13.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
3884
- writeFileSync5(filePath, JSON.stringify({
3885
+ writeFileSync6(filePath, JSON.stringify({
3885
3886
  parentExe: rootExe,
3886
3887
  dispatchedBy: dispatchedBy || rootExe,
3887
3888
  registeredAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -3968,7 +3969,7 @@ function readDebounceState() {
3968
3969
  function writeDebounceState(state) {
3969
3970
  try {
3970
3971
  if (!existsSync10(SESSION_CACHE)) mkdirSync5(SESSION_CACHE, { recursive: true });
3971
- writeFileSync5(DEBOUNCE_FILE, JSON.stringify(state));
3972
+ writeFileSync6(DEBOUNCE_FILE, JSON.stringify(state));
3972
3973
  } catch {
3973
3974
  }
3974
3975
  }
@@ -4157,7 +4158,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4157
4158
  const transport = getTransport();
4158
4159
  const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
4159
4160
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
4160
- const logDir = path13.join(os5.homedir(), ".exe-os", "session-logs");
4161
+ const logDir = path13.join(os6.homedir(), ".exe-os", "session-logs");
4161
4162
  const logFile = path13.join(logDir, `${instanceLabel}-${Date.now()}.log`);
4162
4163
  if (!existsSync10(logDir)) {
4163
4164
  mkdirSync5(logDir, { recursive: true });
@@ -4173,7 +4174,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4173
4174
  } catch {
4174
4175
  }
4175
4176
  try {
4176
- const claudeJsonPath = path13.join(os5.homedir(), ".claude.json");
4177
+ const claudeJsonPath = path13.join(os6.homedir(), ".claude.json");
4177
4178
  let claudeJson = {};
4178
4179
  try {
4179
4180
  claudeJson = JSON.parse(readFileSync9(claudeJsonPath, "utf8"));
@@ -4184,11 +4185,11 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4184
4185
  const trustDir = opts?.cwd ?? projectDir;
4185
4186
  if (!projects[trustDir]) projects[trustDir] = {};
4186
4187
  projects[trustDir].hasTrustDialogAccepted = true;
4187
- writeFileSync5(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
4188
+ writeFileSync6(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
4188
4189
  } catch {
4189
4190
  }
4190
4191
  try {
4191
- const settingsDir = path13.join(os5.homedir(), ".claude", "projects");
4192
+ const settingsDir = path13.join(os6.homedir(), ".claude", "projects");
4192
4193
  const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
4193
4194
  const projSettingsDir = path13.join(settingsDir, normalizedKey);
4194
4195
  const settingsPath = path13.join(projSettingsDir, "settings.json");
@@ -4223,7 +4224,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4223
4224
  perms.allow = allow;
4224
4225
  settings.permissions = perms;
4225
4226
  mkdirSync5(projSettingsDir, { recursive: true });
4226
- writeFileSync5(settingsPath, JSON.stringify(settings, null, 2) + "\n");
4227
+ writeFileSync6(settingsPath, JSON.stringify(settings, null, 2) + "\n");
4227
4228
  }
4228
4229
  } catch {
4229
4230
  }
@@ -4236,7 +4237,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4236
4237
  let legacyFallbackWarned = false;
4237
4238
  if (!useExeAgent && !useBinSymlink) {
4238
4239
  const identityPath = path13.join(
4239
- os5.homedir(),
4240
+ os6.homedir(),
4240
4241
  ".exe-os",
4241
4242
  "identity",
4242
4243
  `${employeeName}.md`
@@ -4266,7 +4267,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4266
4267
  }
4267
4268
  let sessionContextFlag = "";
4268
4269
  try {
4269
- const ctxDir = path13.join(os5.homedir(), ".exe-os", "session-cache");
4270
+ const ctxDir = path13.join(os6.homedir(), ".exe-os", "session-cache");
4270
4271
  mkdirSync5(ctxDir, { recursive: true });
4271
4272
  const ctxFile = path13.join(ctxDir, `session-context-${sessionName}.md`);
4272
4273
  const ctxContent = [
@@ -4275,7 +4276,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4275
4276
  `Your parent exe session is ${exeSession}.`,
4276
4277
  `Your employees (if any) use the -${exeSession} suffix (e.g., tom-${exeSession}).`
4277
4278
  ].join("\n");
4278
- writeFileSync5(ctxFile, ctxContent);
4279
+ writeFileSync6(ctxFile, ctxContent);
4279
4280
  sessionContextFlag = ` --append-system-prompt-file ${ctxFile}`;
4280
4281
  } catch {
4281
4282
  }
@@ -4314,7 +4315,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4314
4315
  try {
4315
4316
  const mySession = getMySession();
4316
4317
  const dispatchInfo = path13.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
4317
- writeFileSync5(dispatchInfo, JSON.stringify({
4318
+ writeFileSync6(dispatchInfo, JSON.stringify({
4318
4319
  dispatchedBy: mySession,
4319
4320
  rootExe: exeSession,
4320
4321
  provider: useBinSymlink ? ccProvider : useExeAgent ? opts.provider : "anthropic",
@@ -4377,13 +4378,13 @@ var init_tmux_routing = __esm({
4377
4378
  init_provider_table();
4378
4379
  init_intercom_queue();
4379
4380
  init_plan_limits();
4380
- SPAWN_LOCK_DIR = path13.join(os5.homedir(), ".exe-os", "spawn-locks");
4381
- SESSION_CACHE = path13.join(os5.homedir(), ".exe-os", "session-cache");
4381
+ SPAWN_LOCK_DIR = path13.join(os6.homedir(), ".exe-os", "spawn-locks");
4382
+ SESSION_CACHE = path13.join(os6.homedir(), ".exe-os", "session-cache");
4382
4383
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
4383
4384
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
4384
4385
  VERIFY_PANE_LINES = 200;
4385
4386
  INTERCOM_DEBOUNCE_MS = 3e4;
4386
- INTERCOM_LOG2 = path13.join(os5.homedir(), ".exe-os", "intercom.log");
4387
+ INTERCOM_LOG2 = path13.join(os6.homedir(), ".exe-os", "intercom.log");
4387
4388
  DEBOUNCE_FILE = path13.join(SESSION_CACHE, "intercom-debounce.json");
4388
4389
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
4389
4390
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
@@ -4669,7 +4670,7 @@ __export(agent_signals_exports, {
4669
4670
  hasUnreadInbox: () => hasUnreadInbox
4670
4671
  });
4671
4672
  import { readFileSync as readFileSync10, existsSync as existsSync11 } from "fs";
4672
- import os6 from "os";
4673
+ import os7 from "os";
4673
4674
  import path14 from "path";
4674
4675
  async function hasOpenTasks(client, agentId) {
4675
4676
  try {
@@ -4712,7 +4713,7 @@ async function hasUnreadInbox(client, agentId) {
4712
4713
  return CONSERVATIVE_ON_ERROR;
4713
4714
  }
4714
4715
  }
4715
- function hadRecentIntercomAck(sessionName, windowMs, nowMs = Date.now(), intercomLog = path14.join(os6.homedir(), ".exe-os", "intercom.log")) {
4716
+ function hadRecentIntercomAck(sessionName, windowMs, nowMs = Date.now(), intercomLog = path14.join(os7.homedir(), ".exe-os", "intercom.log")) {
4716
4717
  if (!existsSync11(intercomLog)) return false;
4717
4718
  try {
4718
4719
  const raw = readFileSync10(intercomLog, "utf8");
@@ -4778,7 +4779,7 @@ __export(daemon_orchestration_exports, {
4778
4779
  shouldNudgeEmployee: () => shouldNudgeEmployee
4779
4780
  });
4780
4781
  import { execSync as execSync9 } from "child_process";
4781
- import { existsSync as existsSync12, readFileSync as readFileSync11, writeFileSync as writeFileSync6 } from "fs";
4782
+ import { existsSync as existsSync12, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
4782
4783
  import { homedir } from "os";
4783
4784
  import { join } from "path";
4784
4785
  function shouldNudgeEmployee(sessionState, hasOpenTasks2, lastNudgeMs, nowMs, dedupMs) {
@@ -4980,7 +4981,7 @@ function loadNudgeState() {
4980
4981
  }
4981
4982
  function saveNudgeState(state) {
4982
4983
  const entries = Array.from(state.lastNudge.entries());
4983
- writeFileSync6(NUDGE_STATE_PATH, JSON.stringify(entries), "utf8");
4984
+ writeFileSync7(NUDGE_STATE_PATH, JSON.stringify(entries), "utf8");
4984
4985
  }
4985
4986
  function createReviewNudgeRealDeps(getClient2) {
4986
4987
  return {
@@ -5134,9 +5135,9 @@ __export(keychain_exports, {
5134
5135
  import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
5135
5136
  import { existsSync as existsSync13 } from "fs";
5136
5137
  import path15 from "path";
5137
- import os7 from "os";
5138
+ import os8 from "os";
5138
5139
  function getKeyDir() {
5139
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path15.join(os7.homedir(), ".exe-os");
5140
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path15.join(os8.homedir(), ".exe-os");
5140
5141
  }
5141
5142
  function getKeyPath() {
5142
5143
  return path15.join(getKeyDir(), "master.key");
@@ -6724,7 +6725,7 @@ var init_consolidation = __esm({
6724
6725
  import net from "net";
6725
6726
  import { spawn } from "child_process";
6726
6727
  import { randomUUID as randomUUID4 } from "crypto";
6727
- import { existsSync as existsSync15, unlinkSync as unlinkSync5, readFileSync as readFileSync12, openSync, closeSync, statSync } from "fs";
6728
+ import { existsSync as existsSync15, unlinkSync as unlinkSync6, readFileSync as readFileSync12, openSync, closeSync, statSync } from "fs";
6728
6729
  import path17 from "path";
6729
6730
  import { fileURLToPath as fileURLToPath2 } from "url";
6730
6731
  function handleData(chunk) {
@@ -6764,11 +6765,11 @@ function cleanupStaleFiles() {
6764
6765
  } catch {
6765
6766
  }
6766
6767
  try {
6767
- unlinkSync5(PID_PATH);
6768
+ unlinkSync6(PID_PATH);
6768
6769
  } catch {
6769
6770
  }
6770
6771
  try {
6771
- unlinkSync5(SOCKET_PATH);
6772
+ unlinkSync6(SOCKET_PATH);
6772
6773
  } catch {
6773
6774
  }
6774
6775
  }
@@ -6830,7 +6831,7 @@ function acquireSpawnLock2() {
6830
6831
  const stat = statSync(SPAWN_LOCK_PATH);
6831
6832
  if (Date.now() - stat.mtimeMs > SPAWN_LOCK_STALE_MS) {
6832
6833
  try {
6833
- unlinkSync5(SPAWN_LOCK_PATH);
6834
+ unlinkSync6(SPAWN_LOCK_PATH);
6834
6835
  } catch {
6835
6836
  }
6836
6837
  try {
@@ -6847,7 +6848,7 @@ function acquireSpawnLock2() {
6847
6848
  }
6848
6849
  function releaseSpawnLock2() {
6849
6850
  try {
6850
- unlinkSync5(SPAWN_LOCK_PATH);
6851
+ unlinkSync6(SPAWN_LOCK_PATH);
6851
6852
  } catch {
6852
6853
  }
6853
6854
  }
@@ -6978,11 +6979,11 @@ function killAndRespawnDaemon() {
6978
6979
  _connected = false;
6979
6980
  _buffer = "";
6980
6981
  try {
6981
- unlinkSync5(PID_PATH);
6982
+ unlinkSync6(PID_PATH);
6982
6983
  } catch {
6983
6984
  }
6984
6985
  try {
6985
- unlinkSync5(SOCKET_PATH);
6986
+ unlinkSync6(SOCKET_PATH);
6986
6987
  } catch {
6987
6988
  }
6988
6989
  spawnDaemon();
@@ -7990,8 +7991,8 @@ __export(device_registry_exports, {
7990
7991
  setFriendlyName: () => setFriendlyName
7991
7992
  });
7992
7993
  import crypto8 from "crypto";
7993
- import os8 from "os";
7994
- import { readFileSync as readFileSync14, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, existsSync as existsSync16 } from "fs";
7994
+ import os9 from "os";
7995
+ import { readFileSync as readFileSync14, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7, existsSync as existsSync16 } from "fs";
7995
7996
  import path19 from "path";
7996
7997
  function getDeviceInfo() {
7997
7998
  if (existsSync16(DEVICE_JSON_PATH)) {
@@ -8004,20 +8005,20 @@ function getDeviceInfo() {
8004
8005
  } catch {
8005
8006
  }
8006
8007
  }
8007
- const hostname = os8.hostname();
8008
+ const hostname = os9.hostname();
8008
8009
  const info = {
8009
8010
  deviceId: crypto8.randomUUID(),
8010
8011
  friendlyName: hostname.replace(/\./g, "-").toLowerCase(),
8011
8012
  hostname
8012
8013
  };
8013
8014
  mkdirSync7(path19.dirname(DEVICE_JSON_PATH), { recursive: true });
8014
- writeFileSync7(DEVICE_JSON_PATH, JSON.stringify(info, null, 2));
8015
+ writeFileSync8(DEVICE_JSON_PATH, JSON.stringify(info, null, 2));
8015
8016
  return info;
8016
8017
  }
8017
8018
  function setFriendlyName(name) {
8018
8019
  const info = getDeviceInfo();
8019
8020
  info.friendlyName = name;
8020
- writeFileSync7(DEVICE_JSON_PATH, JSON.stringify(info, null, 2));
8021
+ writeFileSync8(DEVICE_JSON_PATH, JSON.stringify(info, null, 2));
8021
8022
  }
8022
8023
  async function resolveTargetDevice(targetAgent, targetProject) {
8023
8024
  const { getClient: getClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
@@ -8493,7 +8494,7 @@ init_config();
8493
8494
  init_memory();
8494
8495
  init_daemon_orchestration();
8495
8496
  import net2 from "net";
8496
- import { writeFileSync as writeFileSync8, unlinkSync as unlinkSync6, mkdirSync as mkdirSync8, existsSync as existsSync17, readFileSync as readFileSync15 } from "fs";
8497
+ import { writeFileSync as writeFileSync9, unlinkSync as unlinkSync7, mkdirSync as mkdirSync8, existsSync as existsSync17, readFileSync as readFileSync15 } from "fs";
8497
8498
  import path20 from "path";
8498
8499
  import { getLlama } from "node-llama-cpp";
8499
8500
  var SOCKET_PATH2 = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ?? path20.join(EXE_AI_DIR, "exed.sock");
@@ -8609,11 +8610,11 @@ async function shutdown() {
8609
8610
  }
8610
8611
  _llama = null;
8611
8612
  try {
8612
- unlinkSync6(SOCKET_PATH2);
8613
+ unlinkSync7(SOCKET_PATH2);
8613
8614
  } catch {
8614
8615
  }
8615
8616
  try {
8616
- unlinkSync6(PID_PATH2);
8617
+ unlinkSync7(PID_PATH2);
8617
8618
  } catch {
8618
8619
  }
8619
8620
  process.stderr.write("[exed] Shutdown complete.\n");
@@ -8657,12 +8658,12 @@ function startServer() {
8657
8658
  } catch {
8658
8659
  }
8659
8660
  }
8660
- unlinkSync6(oldPath);
8661
+ unlinkSync7(oldPath);
8661
8662
  } catch {
8662
8663
  }
8663
8664
  }
8664
8665
  try {
8665
- unlinkSync6(SOCKET_PATH2);
8666
+ unlinkSync7(SOCKET_PATH2);
8666
8667
  } catch {
8667
8668
  }
8668
8669
  const server = net2.createServer((socket) => {
@@ -8724,7 +8725,7 @@ function startServer() {
8724
8725
  server.listen(SOCKET_PATH2, () => {
8725
8726
  process.stderr.write(`[exed] Listening on ${SOCKET_PATH2}
8726
8727
  `);
8727
- writeFileSync8(PID_PATH2, String(process.pid));
8728
+ writeFileSync9(PID_PATH2, String(process.pid));
8728
8729
  checkIdle();
8729
8730
  });
8730
8731
  }
@@ -9116,7 +9117,7 @@ function checkExistingDaemon() {
9116
9117
  return true;
9117
9118
  }
9118
9119
  try {
9119
- unlinkSync6(PID_PATH2);
9120
+ unlinkSync7(PID_PATH2);
9120
9121
  } catch {
9121
9122
  }
9122
9123
  return false;
@@ -9280,11 +9281,11 @@ try {
9280
9281
  process.stderr.write(`[exed] FATAL: ${err instanceof Error ? err.message : String(err)}
9281
9282
  `);
9282
9283
  try {
9283
- unlinkSync6(SOCKET_PATH2);
9284
+ unlinkSync7(SOCKET_PATH2);
9284
9285
  } catch {
9285
9286
  }
9286
9287
  try {
9287
- unlinkSync6(PID_PATH2);
9288
+ unlinkSync7(PID_PATH2);
9288
9289
  } catch {
9289
9290
  }
9290
9291
  process.exit(1);
@@ -373,9 +373,10 @@ var init_config = __esm({
373
373
 
374
374
  // src/lib/employees.ts
375
375
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
376
- import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync3 } from "fs";
376
+ import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync3, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
377
377
  import { execSync as execSync3 } from "child_process";
378
378
  import path4 from "path";
379
+ import os4 from "os";
379
380
  var EMPLOYEES_PATH;
380
381
  var init_employees = __esm({
381
382
  "src/lib/employees.ts"() {
@@ -386,7 +387,7 @@ var init_employees = __esm({
386
387
  });
387
388
 
388
389
  // src/lib/license.ts
389
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
390
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
390
391
  import { randomUUID } from "crypto";
391
392
  import path5 from "path";
392
393
  import { jwtVerify, importSPKI } from "jose";
@@ -417,9 +418,9 @@ var init_plan_limits = __esm({
417
418
  });
418
419
 
419
420
  // src/lib/tmux-routing.ts
420
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync as existsSync6, appendFileSync } from "fs";
421
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3, existsSync as existsSync6, appendFileSync } from "fs";
421
422
  import path7 from "path";
422
- import os4 from "os";
423
+ import os5 from "os";
423
424
  import { fileURLToPath } from "url";
424
425
  function getMySession() {
425
426
  return getTransport().getMySession();
@@ -490,7 +491,7 @@ function readDebounceState() {
490
491
  function writeDebounceState(state) {
491
492
  try {
492
493
  if (!existsSync6(SESSION_CACHE)) mkdirSync3(SESSION_CACHE, { recursive: true });
493
- writeFileSync3(DEBOUNCE_FILE, JSON.stringify(state));
494
+ writeFileSync4(DEBOUNCE_FILE, JSON.stringify(state));
494
495
  } catch {
495
496
  }
496
497
  }
@@ -592,11 +593,11 @@ var init_tmux_routing = __esm({
592
593
  init_provider_table();
593
594
  init_intercom_queue();
594
595
  init_plan_limits();
595
- SPAWN_LOCK_DIR = path7.join(os4.homedir(), ".exe-os", "spawn-locks");
596
- SESSION_CACHE = path7.join(os4.homedir(), ".exe-os", "session-cache");
596
+ SPAWN_LOCK_DIR = path7.join(os5.homedir(), ".exe-os", "spawn-locks");
597
+ SESSION_CACHE = path7.join(os5.homedir(), ".exe-os", "session-cache");
597
598
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
598
599
  INTERCOM_DEBOUNCE_MS = 3e4;
599
- INTERCOM_LOG2 = path7.join(os4.homedir(), ".exe-os", "intercom.log");
600
+ INTERCOM_LOG2 = path7.join(os5.homedir(), ".exe-os", "intercom.log");
600
601
  DEBOUNCE_FILE = path7.join(SESSION_CACHE, "intercom-debounce.json");
601
602
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
602
603
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
package/dist/lib/tasks.js CHANGED
@@ -639,9 +639,10 @@ var init_intercom_queue = __esm({
639
639
 
640
640
  // src/lib/employees.ts
641
641
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
642
- import { existsSync as existsSync5, symlinkSync, readlinkSync, readFileSync as readFileSync5 } from "fs";
642
+ import { existsSync as existsSync5, symlinkSync, readlinkSync, readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "fs";
643
643
  import { execSync as execSync3 } from "child_process";
644
644
  import path5 from "path";
645
+ import os5 from "os";
645
646
  function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
646
647
  if (!existsSync5(employeesPath)) return [];
647
648
  try {
@@ -670,7 +671,7 @@ var init_employees = __esm({
670
671
  });
671
672
 
672
673
  // src/lib/license.ts
673
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync3, existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
674
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
674
675
  import { randomUUID } from "crypto";
675
676
  import path6 from "path";
676
677
  import { jwtVerify, importSPKI } from "jose";
@@ -1113,11 +1114,11 @@ __export(tmux_routing_exports, {
1113
1114
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
1114
1115
  });
1115
1116
  import { execFileSync as execFileSync2, execSync as execSync4 } from "child_process";
1116
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, existsSync as existsSync8, appendFileSync } from "fs";
1117
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync8, appendFileSync } from "fs";
1117
1118
  import path8 from "path";
1118
- import os5 from "os";
1119
+ import os6 from "os";
1119
1120
  import { fileURLToPath } from "url";
1120
- import { unlinkSync as unlinkSync2 } from "fs";
1121
+ import { unlinkSync as unlinkSync3 } from "fs";
1121
1122
  function spawnLockPath(sessionName) {
1122
1123
  return path8.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
1123
1124
  }
@@ -1144,12 +1145,12 @@ function acquireSpawnLock(sessionName) {
1144
1145
  } catch {
1145
1146
  }
1146
1147
  }
1147
- writeFileSync4(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
1148
+ writeFileSync5(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
1148
1149
  return true;
1149
1150
  }
1150
1151
  function releaseSpawnLock(sessionName) {
1151
1152
  try {
1152
- unlinkSync2(spawnLockPath(sessionName));
1153
+ unlinkSync3(spawnLockPath(sessionName));
1153
1154
  } catch {
1154
1155
  }
1155
1156
  }
@@ -1231,7 +1232,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
1231
1232
  }
1232
1233
  const rootExe = extractRootExe(parentExe) ?? parentExe;
1233
1234
  const filePath = path8.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
1234
- writeFileSync4(filePath, JSON.stringify({
1235
+ writeFileSync5(filePath, JSON.stringify({
1235
1236
  parentExe: rootExe,
1236
1237
  dispatchedBy: dispatchedBy || rootExe,
1237
1238
  registeredAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -1318,7 +1319,7 @@ function readDebounceState() {
1318
1319
  function writeDebounceState(state) {
1319
1320
  try {
1320
1321
  if (!existsSync8(SESSION_CACHE)) mkdirSync4(SESSION_CACHE, { recursive: true });
1321
- writeFileSync4(DEBOUNCE_FILE, JSON.stringify(state));
1322
+ writeFileSync5(DEBOUNCE_FILE, JSON.stringify(state));
1322
1323
  } catch {
1323
1324
  }
1324
1325
  }
@@ -1507,7 +1508,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
1507
1508
  const transport = getTransport();
1508
1509
  const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
1509
1510
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
1510
- const logDir = path8.join(os5.homedir(), ".exe-os", "session-logs");
1511
+ const logDir = path8.join(os6.homedir(), ".exe-os", "session-logs");
1511
1512
  const logFile = path8.join(logDir, `${instanceLabel}-${Date.now()}.log`);
1512
1513
  if (!existsSync8(logDir)) {
1513
1514
  mkdirSync4(logDir, { recursive: true });
@@ -1523,7 +1524,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
1523
1524
  } catch {
1524
1525
  }
1525
1526
  try {
1526
- const claudeJsonPath = path8.join(os5.homedir(), ".claude.json");
1527
+ const claudeJsonPath = path8.join(os6.homedir(), ".claude.json");
1527
1528
  let claudeJson = {};
1528
1529
  try {
1529
1530
  claudeJson = JSON.parse(readFileSync8(claudeJsonPath, "utf8"));
@@ -1534,11 +1535,11 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
1534
1535
  const trustDir = opts?.cwd ?? projectDir;
1535
1536
  if (!projects[trustDir]) projects[trustDir] = {};
1536
1537
  projects[trustDir].hasTrustDialogAccepted = true;
1537
- writeFileSync4(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
1538
+ writeFileSync5(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
1538
1539
  } catch {
1539
1540
  }
1540
1541
  try {
1541
- const settingsDir = path8.join(os5.homedir(), ".claude", "projects");
1542
+ const settingsDir = path8.join(os6.homedir(), ".claude", "projects");
1542
1543
  const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
1543
1544
  const projSettingsDir = path8.join(settingsDir, normalizedKey);
1544
1545
  const settingsPath = path8.join(projSettingsDir, "settings.json");
@@ -1573,7 +1574,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
1573
1574
  perms.allow = allow;
1574
1575
  settings.permissions = perms;
1575
1576
  mkdirSync4(projSettingsDir, { recursive: true });
1576
- writeFileSync4(settingsPath, JSON.stringify(settings, null, 2) + "\n");
1577
+ writeFileSync5(settingsPath, JSON.stringify(settings, null, 2) + "\n");
1577
1578
  }
1578
1579
  } catch {
1579
1580
  }
@@ -1586,7 +1587,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
1586
1587
  let legacyFallbackWarned = false;
1587
1588
  if (!useExeAgent && !useBinSymlink) {
1588
1589
  const identityPath = path8.join(
1589
- os5.homedir(),
1590
+ os6.homedir(),
1590
1591
  ".exe-os",
1591
1592
  "identity",
1592
1593
  `${employeeName}.md`
@@ -1616,7 +1617,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
1616
1617
  }
1617
1618
  let sessionContextFlag = "";
1618
1619
  try {
1619
- const ctxDir = path8.join(os5.homedir(), ".exe-os", "session-cache");
1620
+ const ctxDir = path8.join(os6.homedir(), ".exe-os", "session-cache");
1620
1621
  mkdirSync4(ctxDir, { recursive: true });
1621
1622
  const ctxFile = path8.join(ctxDir, `session-context-${sessionName}.md`);
1622
1623
  const ctxContent = [
@@ -1625,7 +1626,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
1625
1626
  `Your parent exe session is ${exeSession}.`,
1626
1627
  `Your employees (if any) use the -${exeSession} suffix (e.g., tom-${exeSession}).`
1627
1628
  ].join("\n");
1628
- writeFileSync4(ctxFile, ctxContent);
1629
+ writeFileSync5(ctxFile, ctxContent);
1629
1630
  sessionContextFlag = ` --append-system-prompt-file ${ctxFile}`;
1630
1631
  } catch {
1631
1632
  }
@@ -1664,7 +1665,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
1664
1665
  try {
1665
1666
  const mySession = getMySession();
1666
1667
  const dispatchInfo = path8.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
1667
- writeFileSync4(dispatchInfo, JSON.stringify({
1668
+ writeFileSync5(dispatchInfo, JSON.stringify({
1668
1669
  dispatchedBy: mySession,
1669
1670
  rootExe: exeSession,
1670
1671
  provider: useBinSymlink ? ccProvider : useExeAgent ? opts.provider : "anthropic",
@@ -1727,13 +1728,13 @@ var init_tmux_routing = __esm({
1727
1728
  init_provider_table();
1728
1729
  init_intercom_queue();
1729
1730
  init_plan_limits();
1730
- SPAWN_LOCK_DIR = path8.join(os5.homedir(), ".exe-os", "spawn-locks");
1731
- SESSION_CACHE = path8.join(os5.homedir(), ".exe-os", "session-cache");
1731
+ SPAWN_LOCK_DIR = path8.join(os6.homedir(), ".exe-os", "spawn-locks");
1732
+ SESSION_CACHE = path8.join(os6.homedir(), ".exe-os", "session-cache");
1732
1733
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
1733
1734
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
1734
1735
  VERIFY_PANE_LINES = 200;
1735
1736
  INTERCOM_DEBOUNCE_MS = 3e4;
1736
- INTERCOM_LOG2 = path8.join(os5.homedir(), ".exe-os", "intercom.log");
1737
+ INTERCOM_LOG2 = path8.join(os6.homedir(), ".exe-os", "intercom.log");
1737
1738
  DEBOUNCE_FILE = path8.join(SESSION_CACHE, "intercom-debounce.json");
1738
1739
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
1739
1740
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
@@ -2182,7 +2183,7 @@ var init_tasks_crud = __esm({
2182
2183
 
2183
2184
  // src/lib/tasks-review.ts
2184
2185
  import path10 from "path";
2185
- import { existsSync as existsSync10, readdirSync as readdirSync2, unlinkSync as unlinkSync3 } from "fs";
2186
+ import { existsSync as existsSync10, readdirSync as readdirSync2, unlinkSync as unlinkSync4 } from "fs";
2186
2187
  async function countPendingReviews(sessionScope) {
2187
2188
  const client = getClient();
2188
2189
  if (sessionScope) {
@@ -2367,7 +2368,7 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
2367
2368
  if (existsSync10(cacheDir)) {
2368
2369
  for (const f of readdirSync2(cacheDir)) {
2369
2370
  if (f.startsWith("review-notified-")) {
2370
- unlinkSync3(path10.join(cacheDir, f));
2371
+ unlinkSync4(path10.join(cacheDir, f));
2371
2372
  }
2372
2373
  }
2373
2374
  }
@@ -2973,7 +2974,7 @@ __export(tasks_exports, {
2973
2974
  writeCheckpoint: () => writeCheckpoint
2974
2975
  });
2975
2976
  import path13 from "path";
2976
- import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, unlinkSync as unlinkSync4 } from "fs";
2977
+ import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, unlinkSync as unlinkSync5 } from "fs";
2977
2978
  async function createTask(input) {
2978
2979
  const result = await createTaskCore(input);
2979
2980
  if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
@@ -2996,10 +2997,10 @@ async function updateTask(input) {
2996
2997
  const cachePath = path13.join(cacheDir, `current-task-${agent}.json`);
2997
2998
  if (input.status === "in_progress") {
2998
2999
  mkdirSync5(cacheDir, { recursive: true });
2999
- writeFileSync5(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
3000
+ writeFileSync6(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
3000
3001
  } else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled") {
3001
3002
  try {
3002
- unlinkSync4(cachePath);
3003
+ unlinkSync5(cachePath);
3003
3004
  } catch {
3004
3005
  }
3005
3006
  }