@askexenow/exe-os 0.9.8 → 0.9.9

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 (101) hide show
  1. package/dist/bin/backfill-conversations.js +222 -49
  2. package/dist/bin/backfill-responses.js +221 -48
  3. package/dist/bin/backfill-vectors.js +225 -52
  4. package/dist/bin/cleanup-stale-review-tasks.js +150 -28
  5. package/dist/bin/cli.js +1295 -856
  6. package/dist/bin/exe-agent-config.js +36 -8
  7. package/dist/bin/exe-agent.js +14 -4
  8. package/dist/bin/exe-assign.js +221 -48
  9. package/dist/bin/exe-boot.js +778 -427
  10. package/dist/bin/exe-call.js +41 -13
  11. package/dist/bin/exe-cloud.js +163 -58
  12. package/dist/bin/exe-dispatch.js +276 -139
  13. package/dist/bin/exe-doctor.js +145 -27
  14. package/dist/bin/exe-export-behaviors.js +141 -23
  15. package/dist/bin/exe-forget.js +137 -19
  16. package/dist/bin/exe-gateway.js +677 -388
  17. package/dist/bin/exe-heartbeat.js +227 -108
  18. package/dist/bin/exe-kill.js +138 -20
  19. package/dist/bin/exe-launch-agent.js +172 -39
  20. package/dist/bin/exe-link.js +291 -100
  21. package/dist/bin/exe-new-employee.js +214 -106
  22. package/dist/bin/exe-pending-messages.js +395 -33
  23. package/dist/bin/exe-pending-notifications.js +684 -99
  24. package/dist/bin/exe-pending-reviews.js +420 -74
  25. package/dist/bin/exe-rename.js +147 -49
  26. package/dist/bin/exe-review.js +138 -20
  27. package/dist/bin/exe-search.js +240 -69
  28. package/dist/bin/exe-session-cleanup.js +440 -250
  29. package/dist/bin/exe-settings.js +61 -17
  30. package/dist/bin/exe-start-codex.js +158 -39
  31. package/dist/bin/exe-start-opencode.js +157 -38
  32. package/dist/bin/exe-status.js +151 -29
  33. package/dist/bin/exe-team.js +138 -20
  34. package/dist/bin/git-sweep.js +404 -212
  35. package/dist/bin/graph-backfill.js +137 -19
  36. package/dist/bin/graph-export.js +140 -22
  37. package/dist/bin/install.js +90 -61
  38. package/dist/bin/scan-tasks.js +412 -220
  39. package/dist/bin/setup.js +564 -293
  40. package/dist/bin/shard-migrate.js +139 -21
  41. package/dist/bin/update.js +138 -49
  42. package/dist/bin/wiki-sync.js +137 -19
  43. package/dist/gateway/index.js +533 -320
  44. package/dist/hooks/bug-report-worker.js +344 -193
  45. package/dist/hooks/codex-stop-task-finalizer.js +4678 -0
  46. package/dist/hooks/commit-complete.js +402 -210
  47. package/dist/hooks/error-recall.js +245 -74
  48. package/dist/hooks/exe-heartbeat-hook.js +16 -6
  49. package/dist/hooks/ingest-worker.js +3423 -3157
  50. package/dist/hooks/ingest.js +832 -97
  51. package/dist/hooks/instructions-loaded.js +227 -54
  52. package/dist/hooks/notification.js +216 -43
  53. package/dist/hooks/post-compact.js +239 -62
  54. package/dist/hooks/pre-compact.js +408 -216
  55. package/dist/hooks/pre-tool-use.js +268 -90
  56. package/dist/hooks/prompt-ingest-worker.js +352 -102
  57. package/dist/hooks/prompt-submit.js +541 -328
  58. package/dist/hooks/response-ingest-worker.js +372 -122
  59. package/dist/hooks/session-end.js +443 -240
  60. package/dist/hooks/session-start.js +313 -127
  61. package/dist/hooks/stop.js +293 -98
  62. package/dist/hooks/subagent-stop.js +239 -62
  63. package/dist/hooks/summary-worker.js +568 -236
  64. package/dist/index.js +538 -324
  65. package/dist/lib/agent-config.js +28 -6
  66. package/dist/lib/cloud-sync.js +284 -105
  67. package/dist/lib/config.js +30 -10
  68. package/dist/lib/consolidation.js +16 -6
  69. package/dist/lib/database.js +123 -25
  70. package/dist/lib/db-daemon-client.js +73 -19
  71. package/dist/lib/db.js +123 -25
  72. package/dist/lib/device-registry.js +133 -35
  73. package/dist/lib/embedder.js +107 -32
  74. package/dist/lib/employee-templates.js +14 -4
  75. package/dist/lib/employees.js +41 -13
  76. package/dist/lib/exe-daemon-client.js +88 -22
  77. package/dist/lib/exe-daemon.js +935 -587
  78. package/dist/lib/hybrid-search.js +240 -69
  79. package/dist/lib/identity.js +18 -8
  80. package/dist/lib/license.js +133 -48
  81. package/dist/lib/messaging.js +116 -56
  82. package/dist/lib/reminders.js +14 -4
  83. package/dist/lib/schedules.js +137 -19
  84. package/dist/lib/skill-learning.js +33 -6
  85. package/dist/lib/store.js +137 -19
  86. package/dist/lib/task-router.js +14 -4
  87. package/dist/lib/tasks.js +280 -234
  88. package/dist/lib/tmux-routing.js +172 -125
  89. package/dist/lib/token-spend.js +26 -8
  90. package/dist/mcp/server.js +1326 -609
  91. package/dist/mcp/tools/complete-reminder.js +14 -4
  92. package/dist/mcp/tools/create-reminder.js +14 -4
  93. package/dist/mcp/tools/create-task.js +306 -248
  94. package/dist/mcp/tools/deactivate-behavior.js +16 -6
  95. package/dist/mcp/tools/list-reminders.js +14 -4
  96. package/dist/mcp/tools/list-tasks.js +123 -107
  97. package/dist/mcp/tools/send-message.js +75 -29
  98. package/dist/mcp/tools/update-task.js +1848 -199
  99. package/dist/runtime/index.js +441 -248
  100. package/dist/tui/App.js +761 -424
  101. package/package.json +1 -1
@@ -19,9 +19,47 @@ var __copyProps = (to, from, except, desc) => {
19
19
  };
20
20
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
21
 
22
+ // src/lib/secure-files.ts
23
+ import { chmodSync, existsSync, mkdirSync } from "fs";
24
+ import { chmod, mkdir } from "fs/promises";
25
+ async function ensurePrivateDir(dirPath) {
26
+ await mkdir(dirPath, { recursive: true, mode: PRIVATE_DIR_MODE });
27
+ try {
28
+ await chmod(dirPath, PRIVATE_DIR_MODE);
29
+ } catch {
30
+ }
31
+ }
32
+ function ensurePrivateDirSync(dirPath) {
33
+ mkdirSync(dirPath, { recursive: true, mode: PRIVATE_DIR_MODE });
34
+ try {
35
+ chmodSync(dirPath, PRIVATE_DIR_MODE);
36
+ } catch {
37
+ }
38
+ }
39
+ async function enforcePrivateFile(filePath) {
40
+ try {
41
+ await chmod(filePath, PRIVATE_FILE_MODE);
42
+ } catch {
43
+ }
44
+ }
45
+ function enforcePrivateFileSync(filePath) {
46
+ try {
47
+ if (existsSync(filePath)) chmodSync(filePath, PRIVATE_FILE_MODE);
48
+ } catch {
49
+ }
50
+ }
51
+ var PRIVATE_DIR_MODE, PRIVATE_FILE_MODE;
52
+ var init_secure_files = __esm({
53
+ "src/lib/secure-files.ts"() {
54
+ "use strict";
55
+ PRIVATE_DIR_MODE = 448;
56
+ PRIVATE_FILE_MODE = 384;
57
+ }
58
+ });
59
+
22
60
  // src/lib/config.ts
23
- import { readFile, writeFile, mkdir, chmod } from "fs/promises";
24
- import { readFileSync, existsSync, renameSync } from "fs";
61
+ import { readFile, writeFile } from "fs/promises";
62
+ import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
25
63
  import path from "path";
26
64
  import os from "os";
27
65
  function resolveDataDir() {
@@ -29,7 +67,7 @@ function resolveDataDir() {
29
67
  if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
30
68
  const newDir = path.join(os.homedir(), ".exe-os");
31
69
  const legacyDir = path.join(os.homedir(), ".exe-mem");
32
- if (!existsSync(newDir) && existsSync(legacyDir)) {
70
+ if (!existsSync2(newDir) && existsSync2(legacyDir)) {
33
71
  try {
34
72
  renameSync(legacyDir, newDir);
35
73
  process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
@@ -92,9 +130,9 @@ function normalizeAutoUpdate(raw) {
92
130
  }
93
131
  async function loadConfig() {
94
132
  const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
95
- await mkdir(dir, { recursive: true });
133
+ await ensurePrivateDir(dir);
96
134
  const configPath = path.join(dir, "config.json");
97
- if (!existsSync(configPath)) {
135
+ if (!existsSync2(configPath)) {
98
136
  return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db") };
99
137
  }
100
138
  const raw = await readFile(configPath, "utf-8");
@@ -107,6 +145,7 @@ async function loadConfig() {
107
145
  `);
108
146
  try {
109
147
  await writeFile(configPath, JSON.stringify(migratedCfg, null, 2) + "\n");
148
+ await enforcePrivateFile(configPath);
110
149
  } catch {
111
150
  }
112
151
  }
@@ -126,6 +165,7 @@ var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CON
126
165
  var init_config = __esm({
127
166
  "src/lib/config.ts"() {
128
167
  "use strict";
168
+ init_secure_files();
129
169
  EXE_AI_DIR = resolveDataDir();
130
170
  DB_PATH = path.join(EXE_AI_DIR, "memories.db");
131
171
  MODELS_DIR = path.join(EXE_AI_DIR, "models");
@@ -310,10 +350,10 @@ __export(agent_config_exports, {
310
350
  saveAgentConfig: () => saveAgentConfig,
311
351
  setAgentRuntime: () => setAgentRuntime
312
352
  });
313
- import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync2, mkdirSync } from "fs";
353
+ import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync3 } from "fs";
314
354
  import path2 from "path";
315
355
  function loadAgentConfig() {
316
- if (!existsSync2(AGENT_CONFIG_PATH)) return {};
356
+ if (!existsSync3(AGENT_CONFIG_PATH)) return {};
317
357
  try {
318
358
  return JSON.parse(readFileSync2(AGENT_CONFIG_PATH, "utf-8"));
319
359
  } catch {
@@ -322,8 +362,9 @@ function loadAgentConfig() {
322
362
  }
323
363
  function saveAgentConfig(config) {
324
364
  const dir = path2.dirname(AGENT_CONFIG_PATH);
325
- if (!existsSync2(dir)) mkdirSync(dir, { recursive: true });
365
+ ensurePrivateDirSync(dir);
326
366
  writeFileSync(AGENT_CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf-8");
367
+ enforcePrivateFileSync(AGENT_CONFIG_PATH);
327
368
  }
328
369
  function getAgentRuntime(agentId) {
329
370
  const config = loadAgentConfig();
@@ -363,6 +404,7 @@ var init_agent_config = __esm({
363
404
  "use strict";
364
405
  init_config();
365
406
  init_runtime_table();
407
+ init_secure_files();
366
408
  AGENT_CONFIG_PATH = path2.join(EXE_AI_DIR, "agent-config.json");
367
409
  KNOWN_RUNTIMES = {
368
410
  claude: ["claude-opus-4", "claude-sonnet-4", "claude-haiku-4.5"],
@@ -410,7 +452,7 @@ __export(employees_exports, {
410
452
  validateEmployeeName: () => validateEmployeeName
411
453
  });
412
454
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
413
- import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync3, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
455
+ import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync3, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
414
456
  import { execSync as execSync2 } from "child_process";
415
457
  import path3 from "path";
416
458
  import os2 from "os";
@@ -449,7 +491,7 @@ function validateEmployeeName(name) {
449
491
  return { valid: true };
450
492
  }
451
493
  async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
452
- if (!existsSync3(employeesPath)) {
494
+ if (!existsSync4(employeesPath)) {
453
495
  return [];
454
496
  }
455
497
  const raw = await readFile2(employeesPath, "utf-8");
@@ -464,7 +506,7 @@ async function saveEmployees(employees, employeesPath = EMPLOYEES_PATH) {
464
506
  await writeFile2(employeesPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
465
507
  }
466
508
  function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
467
- if (!existsSync3(employeesPath)) return [];
509
+ if (!existsSync4(employeesPath)) return [];
468
510
  try {
469
511
  return JSON.parse(readFileSync3(employeesPath, "utf-8"));
470
512
  } catch {
@@ -512,7 +554,7 @@ function appendToCoordinatorTeam(employee) {
512
554
  const coordinator = getCoordinatorEmployee(loadEmployeesSync());
513
555
  if (!coordinator) return;
514
556
  const idPath = path3.join(IDENTITY_DIR, `${coordinator.name}.md`);
515
- if (!existsSync3(idPath)) return;
557
+ if (!existsSync4(idPath)) return;
516
558
  const content = readFileSync3(idPath, "utf-8");
517
559
  if (content.includes(`**${capitalize(employee.name)}`)) return;
518
560
  const teamMatch = content.match(TEAM_SECTION_RE);
@@ -566,9 +608,9 @@ async function normalizeRosterCase(rosterPath) {
566
608
  const identityDir = path3.join(os2.homedir(), ".exe-os", "identity");
567
609
  const oldPath = path3.join(identityDir, `${oldName}.md`);
568
610
  const newPath = path3.join(identityDir, `${emp.name}.md`);
569
- if (existsSync3(oldPath) && !existsSync3(newPath)) {
611
+ if (existsSync4(oldPath) && !existsSync4(newPath)) {
570
612
  renameSync2(oldPath, newPath);
571
- } else if (existsSync3(oldPath) && oldPath !== newPath) {
613
+ } else if (existsSync4(oldPath) && oldPath !== newPath) {
572
614
  const content = readFileSync3(oldPath, "utf-8");
573
615
  writeFileSync2(newPath, content, "utf-8");
574
616
  if (oldPath.toLowerCase() !== newPath.toLowerCase()) {
@@ -611,7 +653,7 @@ function registerBinSymlinks(name) {
611
653
  for (const suffix of ["", "-opencode"]) {
612
654
  const linkName = `${name}${suffix}`;
613
655
  const linkPath = path3.join(binDir, linkName);
614
- if (existsSync3(linkPath)) {
656
+ if (existsSync4(linkPath)) {
615
657
  skipped.push(linkName);
616
658
  continue;
617
659
  }
@@ -786,7 +828,7 @@ var init_provider_table = __esm({
786
828
  });
787
829
 
788
830
  // src/lib/intercom-queue.ts
789
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
831
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
790
832
  import path6 from "path";
791
833
  import os4 from "os";
792
834
  var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
@@ -1438,13 +1480,50 @@ var init_database_adapter = __esm({
1438
1480
  }
1439
1481
  });
1440
1482
 
1483
+ // src/lib/daemon-auth.ts
1484
+ import crypto from "crypto";
1485
+ import path8 from "path";
1486
+ import { existsSync as existsSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
1487
+ function normalizeToken(token) {
1488
+ if (!token) return null;
1489
+ const trimmed = token.trim();
1490
+ return trimmed.length > 0 ? trimmed : null;
1491
+ }
1492
+ function readDaemonToken() {
1493
+ try {
1494
+ if (!existsSync6(DAEMON_TOKEN_PATH)) return null;
1495
+ return normalizeToken(readFileSync6(DAEMON_TOKEN_PATH, "utf8"));
1496
+ } catch {
1497
+ return null;
1498
+ }
1499
+ }
1500
+ function ensureDaemonToken(seed) {
1501
+ const existing = readDaemonToken();
1502
+ if (existing) return existing;
1503
+ const token = normalizeToken(seed) ?? crypto.randomBytes(32).toString("hex");
1504
+ ensurePrivateDirSync(EXE_AI_DIR);
1505
+ writeFileSync5(DAEMON_TOKEN_PATH, `${token}
1506
+ `, "utf8");
1507
+ enforcePrivateFileSync(DAEMON_TOKEN_PATH);
1508
+ return token;
1509
+ }
1510
+ var DAEMON_TOKEN_PATH;
1511
+ var init_daemon_auth = __esm({
1512
+ "src/lib/daemon-auth.ts"() {
1513
+ "use strict";
1514
+ init_config();
1515
+ init_secure_files();
1516
+ DAEMON_TOKEN_PATH = path8.join(EXE_AI_DIR, "exed.token");
1517
+ }
1518
+ });
1519
+
1441
1520
  // src/lib/exe-daemon-client.ts
1442
1521
  import net from "net";
1443
1522
  import os6 from "os";
1444
1523
  import { spawn } from "child_process";
1445
1524
  import { randomUUID } from "crypto";
1446
- import { existsSync as existsSync5, unlinkSync as unlinkSync3, readFileSync as readFileSync6, openSync, closeSync, statSync } from "fs";
1447
- import path8 from "path";
1525
+ import { existsSync as existsSync7, unlinkSync as unlinkSync3, readFileSync as readFileSync7, openSync, closeSync, statSync } from "fs";
1526
+ import path9 from "path";
1448
1527
  import { fileURLToPath } from "url";
1449
1528
  function handleData(chunk) {
1450
1529
  _buffer += chunk.toString();
@@ -1472,9 +1551,9 @@ function handleData(chunk) {
1472
1551
  }
1473
1552
  }
1474
1553
  function cleanupStaleFiles() {
1475
- if (existsSync5(PID_PATH)) {
1554
+ if (existsSync7(PID_PATH)) {
1476
1555
  try {
1477
- const pid = parseInt(readFileSync6(PID_PATH, "utf8").trim(), 10);
1556
+ const pid = parseInt(readFileSync7(PID_PATH, "utf8").trim(), 10);
1478
1557
  if (pid > 0) {
1479
1558
  try {
1480
1559
  process.kill(pid, 0);
@@ -1495,11 +1574,11 @@ function cleanupStaleFiles() {
1495
1574
  }
1496
1575
  }
1497
1576
  function findPackageRoot() {
1498
- let dir = path8.dirname(fileURLToPath(import.meta.url));
1499
- const { root } = path8.parse(dir);
1577
+ let dir = path9.dirname(fileURLToPath(import.meta.url));
1578
+ const { root } = path9.parse(dir);
1500
1579
  while (dir !== root) {
1501
- if (existsSync5(path8.join(dir, "package.json"))) return dir;
1502
- dir = path8.dirname(dir);
1580
+ if (existsSync7(path9.join(dir, "package.json"))) return dir;
1581
+ dir = path9.dirname(dir);
1503
1582
  }
1504
1583
  return null;
1505
1584
  }
@@ -1525,16 +1604,17 @@ function spawnDaemon() {
1525
1604
  process.stderr.write("[exed-client] WARN: cannot find package root\n");
1526
1605
  return;
1527
1606
  }
1528
- const daemonPath = path8.join(pkgRoot, "dist", "lib", "exe-daemon.js");
1529
- if (!existsSync5(daemonPath)) {
1607
+ const daemonPath = path9.join(pkgRoot, "dist", "lib", "exe-daemon.js");
1608
+ if (!existsSync7(daemonPath)) {
1530
1609
  process.stderr.write(`[exed-client] WARN: daemon script not found at ${daemonPath}
1531
1610
  `);
1532
1611
  return;
1533
1612
  }
1534
1613
  const resolvedPath = daemonPath;
1614
+ const daemonToken = ensureDaemonToken(process.env[DAEMON_TOKEN_ENV] ?? null);
1535
1615
  process.stderr.write(`[exed-client] Spawning daemon: ${resolvedPath}
1536
1616
  `);
1537
- const logPath = path8.join(path8.dirname(SOCKET_PATH), "exed.log");
1617
+ const logPath = path9.join(path9.dirname(SOCKET_PATH), "exed.log");
1538
1618
  let stderrFd = "ignore";
1539
1619
  try {
1540
1620
  stderrFd = openSync(logPath, "a");
@@ -1552,7 +1632,8 @@ function spawnDaemon() {
1552
1632
  TMUX_PANE: void 0,
1553
1633
  // Prevents resolveExeSession() from scoping to one session
1554
1634
  EXE_DAEMON_SOCK: SOCKET_PATH,
1555
- EXE_DAEMON_PID: PID_PATH
1635
+ EXE_DAEMON_PID: PID_PATH,
1636
+ [DAEMON_TOKEN_ENV]: daemonToken
1556
1637
  }
1557
1638
  });
1558
1639
  child.unref();
@@ -1659,13 +1740,14 @@ function sendDaemonRequest(payload, timeoutMs = REQUEST_TIMEOUT_MS) {
1659
1740
  return;
1660
1741
  }
1661
1742
  const id = randomUUID();
1743
+ const token = process.env[DAEMON_TOKEN_ENV] ?? readDaemonToken();
1662
1744
  const timer = setTimeout(() => {
1663
1745
  _pending.delete(id);
1664
1746
  resolve({ error: "Request timeout" });
1665
1747
  }, timeoutMs);
1666
1748
  _pending.set(id, { resolve, timer });
1667
1749
  try {
1668
- _socket.write(JSON.stringify({ id, ...payload }) + "\n");
1750
+ _socket.write(JSON.stringify({ id, token, ...payload }) + "\n");
1669
1751
  } catch {
1670
1752
  clearTimeout(timer);
1671
1753
  _pending.delete(id);
@@ -1676,17 +1758,19 @@ function sendDaemonRequest(payload, timeoutMs = REQUEST_TIMEOUT_MS) {
1676
1758
  function isClientConnected() {
1677
1759
  return _connected;
1678
1760
  }
1679
- var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, _socket, _connected, _buffer, _pending, MAX_BUFFER;
1761
+ var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, DAEMON_TOKEN_ENV, _socket, _connected, _buffer, _pending, MAX_BUFFER;
1680
1762
  var init_exe_daemon_client = __esm({
1681
1763
  "src/lib/exe-daemon-client.ts"() {
1682
1764
  "use strict";
1683
1765
  init_config();
1684
- SOCKET_PATH = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ?? path8.join(EXE_AI_DIR, "exed.sock");
1685
- PID_PATH = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ?? path8.join(EXE_AI_DIR, "exed.pid");
1686
- SPAWN_LOCK_PATH = path8.join(EXE_AI_DIR, "exed-spawn.lock");
1766
+ init_daemon_auth();
1767
+ SOCKET_PATH = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ?? path9.join(EXE_AI_DIR, "exed.sock");
1768
+ PID_PATH = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ?? path9.join(EXE_AI_DIR, "exed.pid");
1769
+ SPAWN_LOCK_PATH = path9.join(EXE_AI_DIR, "exed-spawn.lock");
1687
1770
  SPAWN_LOCK_STALE_MS = 3e4;
1688
1771
  CONNECT_TIMEOUT_MS = 15e3;
1689
1772
  REQUEST_TIMEOUT_MS = 3e4;
1773
+ DAEMON_TOKEN_ENV = "EXE_DAEMON_TOKEN";
1690
1774
  _socket = null;
1691
1775
  _connected = false;
1692
1776
  _buffer = "";
@@ -2265,6 +2349,7 @@ async function ensureSchema() {
2265
2349
  project TEXT NOT NULL,
2266
2350
  summary TEXT NOT NULL,
2267
2351
  task_file TEXT,
2352
+ session_scope TEXT,
2268
2353
  read INTEGER NOT NULL DEFAULT 0,
2269
2354
  created_at TEXT NOT NULL
2270
2355
  );
@@ -2273,7 +2358,7 @@ async function ensureSchema() {
2273
2358
  ON notifications(read);
2274
2359
 
2275
2360
  CREATE INDEX IF NOT EXISTS idx_notifications_agent
2276
- ON notifications(agent_id);
2361
+ ON notifications(agent_id, session_scope);
2277
2362
 
2278
2363
  CREATE INDEX IF NOT EXISTS idx_notifications_task_file
2279
2364
  ON notifications(task_file);
@@ -2311,6 +2396,7 @@ async function ensureSchema() {
2311
2396
  target_agent TEXT NOT NULL,
2312
2397
  target_project TEXT,
2313
2398
  target_device TEXT NOT NULL DEFAULT 'local',
2399
+ session_scope TEXT,
2314
2400
  content TEXT NOT NULL,
2315
2401
  priority TEXT DEFAULT 'normal',
2316
2402
  status TEXT DEFAULT 'pending',
@@ -2324,10 +2410,31 @@ async function ensureSchema() {
2324
2410
  );
2325
2411
 
2326
2412
  CREATE INDEX IF NOT EXISTS idx_messages_target
2327
- ON messages(target_agent, status);
2413
+ ON messages(target_agent, session_scope, status);
2328
2414
 
2329
2415
  CREATE INDEX IF NOT EXISTS idx_messages_conversation_order
2330
- ON messages(target_agent, from_agent, server_seq);
2416
+ ON messages(target_agent, session_scope, from_agent, server_seq);
2417
+ `);
2418
+ try {
2419
+ await client.execute({
2420
+ sql: `ALTER TABLE notifications ADD COLUMN session_scope TEXT`,
2421
+ args: []
2422
+ });
2423
+ } catch {
2424
+ }
2425
+ try {
2426
+ await client.execute({
2427
+ sql: `ALTER TABLE messages ADD COLUMN session_scope TEXT`,
2428
+ args: []
2429
+ });
2430
+ } catch {
2431
+ }
2432
+ await client.executeMultiple(`
2433
+ CREATE INDEX IF NOT EXISTS idx_notifications_agent_scope_read
2434
+ ON notifications(agent_id, session_scope, read, created_at);
2435
+
2436
+ CREATE INDEX IF NOT EXISTS idx_messages_target_scope_status
2437
+ ON messages(target_agent, session_scope, status, created_at);
2331
2438
  `);
2332
2439
  try {
2333
2440
  await client.execute({
@@ -2911,6 +3018,13 @@ async function ensureSchema() {
2911
3018
  } catch {
2912
3019
  }
2913
3020
  }
3021
+ try {
3022
+ await client.execute({
3023
+ sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
3024
+ args: []
3025
+ });
3026
+ } catch {
3027
+ }
2914
3028
  }
2915
3029
  async function disposeDatabase() {
2916
3030
  if (_walCheckpointTimer) {
@@ -2949,24 +3063,27 @@ var init_database = __esm({
2949
3063
  });
2950
3064
 
2951
3065
  // src/lib/license.ts
2952
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync6, mkdirSync as mkdirSync4 } from "fs";
3066
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync8, mkdirSync as mkdirSync4 } from "fs";
2953
3067
  import { randomUUID as randomUUID2 } from "crypto";
2954
- import path9 from "path";
3068
+ import { createRequire as createRequire2 } from "module";
3069
+ import { pathToFileURL as pathToFileURL2 } from "url";
3070
+ import os7 from "os";
3071
+ import path10 from "path";
2955
3072
  import { jwtVerify, importSPKI } from "jose";
2956
3073
  var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
2957
3074
  var init_license = __esm({
2958
3075
  "src/lib/license.ts"() {
2959
3076
  "use strict";
2960
3077
  init_config();
2961
- LICENSE_PATH = path9.join(EXE_AI_DIR, "license.key");
2962
- CACHE_PATH = path9.join(EXE_AI_DIR, "license-cache.json");
2963
- DEVICE_ID_PATH = path9.join(EXE_AI_DIR, "device-id");
3078
+ LICENSE_PATH = path10.join(EXE_AI_DIR, "license.key");
3079
+ CACHE_PATH = path10.join(EXE_AI_DIR, "license-cache.json");
3080
+ DEVICE_ID_PATH = path10.join(EXE_AI_DIR, "device-id");
2964
3081
  }
2965
3082
  });
2966
3083
 
2967
3084
  // src/lib/plan-limits.ts
2968
- import { readFileSync as readFileSync8, existsSync as existsSync7 } from "fs";
2969
- import path10 from "path";
3085
+ import { readFileSync as readFileSync9, existsSync as existsSync9 } from "fs";
3086
+ import path11 from "path";
2970
3087
  var CACHE_PATH2;
2971
3088
  var init_plan_limits = __esm({
2972
3089
  "src/lib/plan-limits.ts"() {
@@ -2975,14 +3092,14 @@ var init_plan_limits = __esm({
2975
3092
  init_employees();
2976
3093
  init_license();
2977
3094
  init_config();
2978
- CACHE_PATH2 = path10.join(EXE_AI_DIR, "license-cache.json");
3095
+ CACHE_PATH2 = path11.join(EXE_AI_DIR, "license-cache.json");
2979
3096
  }
2980
3097
  });
2981
3098
 
2982
3099
  // src/lib/tmux-routing.ts
2983
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, existsSync as existsSync8, appendFileSync, readdirSync as readdirSync2 } from "fs";
2984
- import path11 from "path";
2985
- import os7 from "os";
3100
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync5, existsSync as existsSync10, appendFileSync, readdirSync as readdirSync2 } from "fs";
3101
+ import path12 from "path";
3102
+ import os8 from "os";
2986
3103
  import { fileURLToPath as fileURLToPath2 } from "url";
2987
3104
  function getMySession() {
2988
3105
  return getTransport().getMySession();
@@ -2995,7 +3112,7 @@ function extractRootExe(name) {
2995
3112
  }
2996
3113
  function getParentExe(sessionKey) {
2997
3114
  try {
2998
- const data = JSON.parse(readFileSync9(path11.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
3115
+ const data = JSON.parse(readFileSync10(path12.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
2999
3116
  return data.parentExe || null;
3000
3117
  } catch {
3001
3118
  return null;
@@ -3038,10 +3155,10 @@ var init_tmux_routing = __esm({
3038
3155
  init_intercom_queue();
3039
3156
  init_plan_limits();
3040
3157
  init_employees();
3041
- SPAWN_LOCK_DIR = path11.join(os7.homedir(), ".exe-os", "spawn-locks");
3042
- SESSION_CACHE = path11.join(os7.homedir(), ".exe-os", "session-cache");
3043
- INTERCOM_LOG2 = path11.join(os7.homedir(), ".exe-os", "intercom.log");
3044
- DEBOUNCE_FILE = path11.join(SESSION_CACHE, "intercom-debounce.json");
3158
+ SPAWN_LOCK_DIR = path12.join(os8.homedir(), ".exe-os", "spawn-locks");
3159
+ SESSION_CACHE = path12.join(os8.homedir(), ".exe-os", "session-cache");
3160
+ INTERCOM_LOG2 = path12.join(os8.homedir(), ".exe-os", "intercom.log");
3161
+ DEBOUNCE_FILE = path12.join(SESSION_CACHE, "intercom-debounce.json");
3045
3162
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
3046
3163
  }
3047
3164
  });
@@ -3083,9 +3200,9 @@ __export(cto_delegation_gate_exports, {
3083
3200
  hasValidScratchpadEscape: () => hasValidScratchpadEscape,
3084
3201
  scratchpadPath: () => scratchpadPath
3085
3202
  });
3086
- import os8 from "os";
3087
- import path12 from "path";
3088
- import { existsSync as existsSync9, readFileSync as readFileSync10, statSync as statSync2 } from "fs";
3203
+ import os9 from "os";
3204
+ import path13 from "path";
3205
+ import { existsSync as existsSync11, readFileSync as readFileSync11, statSync as statSync2 } from "fs";
3089
3206
  function resolveGatedAgent() {
3090
3207
  try {
3091
3208
  const employees = loadEmployeesSync();
@@ -3099,12 +3216,12 @@ function getGatedAgent() {
3099
3216
  return resolveGatedAgent() || GATED_AGENT;
3100
3217
  }
3101
3218
  function toWorkspaceRelative(filePath, cwd = process.cwd()) {
3102
- const normalized = path12.normalize(filePath);
3103
- if (normalized.startsWith(cwd + path12.sep)) {
3219
+ const normalized = path13.normalize(filePath);
3220
+ if (normalized.startsWith(cwd + path13.sep)) {
3104
3221
  return normalized.slice(cwd.length + 1);
3105
3222
  }
3106
- if (path12.isAbsolute(normalized)) {
3107
- return path12.basename(normalized);
3223
+ if (path13.isAbsolute(normalized)) {
3224
+ return path13.basename(normalized);
3108
3225
  }
3109
3226
  return normalized;
3110
3227
  }
@@ -3113,8 +3230,8 @@ function isDockerfile(basename) {
3113
3230
  }
3114
3231
  function classifyPath(filePath, cwd) {
3115
3232
  const rel = toWorkspaceRelative(filePath, cwd);
3116
- const basename = path12.basename(rel);
3117
- const ext = path12.extname(rel).toLowerCase();
3233
+ const basename = path13.basename(rel);
3234
+ const ext = path13.extname(rel).toLowerCase();
3118
3235
  if (ext === ".md") {
3119
3236
  for (const prefix of EXEMPT_MD_DIR_PREFIXES) {
3120
3237
  if (rel.startsWith(prefix)) return "exempt";
@@ -3156,22 +3273,22 @@ async function hasRecentEngineerDispatch(now = Date.now()) {
3156
3273
  return false;
3157
3274
  }
3158
3275
  }
3159
- function scratchpadPath(sessionId, homeDir = os8.homedir()) {
3160
- return path12.join(
3276
+ function scratchpadPath(sessionId, homeDir = os9.homedir()) {
3277
+ return path13.join(
3161
3278
  homeDir,
3162
3279
  ".exe-os",
3163
3280
  "session-cache",
3164
3281
  `cto-scratchpad-${sessionId}.txt`
3165
3282
  );
3166
3283
  }
3167
- function hasValidScratchpadEscape(sessionId, now = Date.now(), homeDir = os8.homedir()) {
3284
+ function hasValidScratchpadEscape(sessionId, now = Date.now(), homeDir = os9.homedir()) {
3168
3285
  const paths = [scratchpadPath(sessionId, homeDir)];
3169
3286
  for (const filePath of paths) {
3170
- if (!existsSync9(filePath)) continue;
3287
+ if (!existsSync11(filePath)) continue;
3171
3288
  try {
3172
3289
  const stat = statSync2(filePath);
3173
3290
  if (now - stat.mtimeMs > SCRATCHPAD_MAX_AGE_MS) continue;
3174
- const body = readFileSync10(filePath, "utf-8");
3291
+ const body = readFileSync11(filePath, "utf-8");
3175
3292
  if (SCRATCHPAD_ESCAPE_PATTERN.test(body)) return true;
3176
3293
  } catch {
3177
3294
  }
@@ -3262,14 +3379,14 @@ var init_memory = __esm({
3262
3379
 
3263
3380
  // src/lib/keychain.ts
3264
3381
  import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
3265
- import { existsSync as existsSync10 } from "fs";
3266
- import path13 from "path";
3267
- import os9 from "os";
3382
+ import { existsSync as existsSync12 } from "fs";
3383
+ import path14 from "path";
3384
+ import os10 from "os";
3268
3385
  function getKeyDir() {
3269
- return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path13.join(os9.homedir(), ".exe-os");
3386
+ return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path14.join(os10.homedir(), ".exe-os");
3270
3387
  }
3271
3388
  function getKeyPath() {
3272
- return path13.join(getKeyDir(), "master.key");
3389
+ return path14.join(getKeyDir(), "master.key");
3273
3390
  }
3274
3391
  async function tryKeytar() {
3275
3392
  try {
@@ -3290,9 +3407,9 @@ async function getMasterKey() {
3290
3407
  }
3291
3408
  }
3292
3409
  const keyPath = getKeyPath();
3293
- if (!existsSync10(keyPath)) {
3410
+ if (!existsSync12(keyPath)) {
3294
3411
  process.stderr.write(
3295
- `[keychain] Key not found at ${keyPath} (HOME=${os9.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
3412
+ `[keychain] Key not found at ${keyPath} (HOME=${os10.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
3296
3413
  `
3297
3414
  );
3298
3415
  return null;
@@ -3377,6 +3494,7 @@ var shard_manager_exports = {};
3377
3494
  __export(shard_manager_exports, {
3378
3495
  disposeShards: () => disposeShards,
3379
3496
  ensureShardSchema: () => ensureShardSchema,
3497
+ getOpenShardCount: () => getOpenShardCount,
3380
3498
  getReadyShardClient: () => getReadyShardClient,
3381
3499
  getShardClient: () => getShardClient,
3382
3500
  getShardsDir: () => getShardsDir,
@@ -3385,15 +3503,18 @@ __export(shard_manager_exports, {
3385
3503
  listShards: () => listShards,
3386
3504
  shardExists: () => shardExists
3387
3505
  });
3388
- import path14 from "path";
3389
- import { existsSync as existsSync11, mkdirSync as mkdirSync6, readdirSync as readdirSync3 } from "fs";
3506
+ import path15 from "path";
3507
+ import { existsSync as existsSync13, mkdirSync as mkdirSync6, readdirSync as readdirSync3 } from "fs";
3390
3508
  import { createClient as createClient2 } from "@libsql/client";
3391
3509
  function initShardManager(encryptionKey) {
3392
3510
  _encryptionKey = encryptionKey;
3393
- if (!existsSync11(SHARDS_DIR)) {
3511
+ if (!existsSync13(SHARDS_DIR)) {
3394
3512
  mkdirSync6(SHARDS_DIR, { recursive: true });
3395
3513
  }
3396
3514
  _shardingEnabled = true;
3515
+ if (_evictionTimer) clearInterval(_evictionTimer);
3516
+ _evictionTimer = setInterval(evictIdleShards, EVICTION_INTERVAL_MS);
3517
+ _evictionTimer.unref();
3397
3518
  }
3398
3519
  function isShardingEnabled() {
3399
3520
  return _shardingEnabled;
@@ -3410,21 +3531,28 @@ function getShardClient(projectName) {
3410
3531
  throw new Error(`Invalid project name for shard: "${projectName}"`);
3411
3532
  }
3412
3533
  const cached = _shards.get(safeName);
3413
- if (cached) return cached;
3414
- const dbPath = path14.join(SHARDS_DIR, `${safeName}.db`);
3534
+ if (cached) {
3535
+ _shardLastAccess.set(safeName, Date.now());
3536
+ return cached;
3537
+ }
3538
+ while (_shards.size >= MAX_OPEN_SHARDS) {
3539
+ evictLRU();
3540
+ }
3541
+ const dbPath = path15.join(SHARDS_DIR, `${safeName}.db`);
3415
3542
  const client = createClient2({
3416
3543
  url: `file:${dbPath}`,
3417
3544
  encryptionKey: _encryptionKey
3418
3545
  });
3419
3546
  _shards.set(safeName, client);
3547
+ _shardLastAccess.set(safeName, Date.now());
3420
3548
  return client;
3421
3549
  }
3422
3550
  function shardExists(projectName) {
3423
3551
  const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
3424
- return existsSync11(path14.join(SHARDS_DIR, `${safeName}.db`));
3552
+ return existsSync13(path15.join(SHARDS_DIR, `${safeName}.db`));
3425
3553
  }
3426
3554
  function listShards() {
3427
- if (!existsSync11(SHARDS_DIR)) return [];
3555
+ if (!existsSync13(SHARDS_DIR)) return [];
3428
3556
  return readdirSync3(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
3429
3557
  }
3430
3558
  async function ensureShardSchema(client) {
@@ -3476,6 +3604,8 @@ async function ensureShardSchema(client) {
3476
3604
  for (const col of [
3477
3605
  "ALTER TABLE memories ADD COLUMN task_id TEXT",
3478
3606
  "ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0",
3607
+ "ALTER TABLE memories ADD COLUMN author_device_id TEXT",
3608
+ "ALTER TABLE memories ADD COLUMN scope TEXT NOT NULL DEFAULT 'business'",
3479
3609
  "ALTER TABLE memories ADD COLUMN importance INTEGER DEFAULT 5",
3480
3610
  "ALTER TABLE memories ADD COLUMN status TEXT DEFAULT 'active'",
3481
3611
  "ALTER TABLE memories ADD COLUMN wiki_synced INTEGER DEFAULT 0",
@@ -3613,21 +3743,69 @@ async function getReadyShardClient(projectName) {
3613
3743
  await ensureShardSchema(client);
3614
3744
  return client;
3615
3745
  }
3746
+ function evictLRU() {
3747
+ let oldest = null;
3748
+ let oldestTime = Infinity;
3749
+ for (const [name, time] of _shardLastAccess) {
3750
+ if (time < oldestTime) {
3751
+ oldestTime = time;
3752
+ oldest = name;
3753
+ }
3754
+ }
3755
+ if (oldest) {
3756
+ const client = _shards.get(oldest);
3757
+ if (client) {
3758
+ client.close();
3759
+ }
3760
+ _shards.delete(oldest);
3761
+ _shardLastAccess.delete(oldest);
3762
+ }
3763
+ }
3764
+ function evictIdleShards() {
3765
+ const now = Date.now();
3766
+ const toEvict = [];
3767
+ for (const [name, lastAccess] of _shardLastAccess) {
3768
+ if (now - lastAccess > SHARD_IDLE_MS) {
3769
+ toEvict.push(name);
3770
+ }
3771
+ }
3772
+ for (const name of toEvict) {
3773
+ const client = _shards.get(name);
3774
+ if (client) {
3775
+ client.close();
3776
+ }
3777
+ _shards.delete(name);
3778
+ _shardLastAccess.delete(name);
3779
+ }
3780
+ }
3781
+ function getOpenShardCount() {
3782
+ return _shards.size;
3783
+ }
3616
3784
  function disposeShards() {
3785
+ if (_evictionTimer) {
3786
+ clearInterval(_evictionTimer);
3787
+ _evictionTimer = null;
3788
+ }
3617
3789
  for (const [, client] of _shards) {
3618
3790
  client.close();
3619
3791
  }
3620
3792
  _shards.clear();
3793
+ _shardLastAccess.clear();
3621
3794
  _shardingEnabled = false;
3622
3795
  _encryptionKey = null;
3623
3796
  }
3624
- var SHARDS_DIR, _shards, _encryptionKey, _shardingEnabled;
3797
+ var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled;
3625
3798
  var init_shard_manager = __esm({
3626
3799
  "src/lib/shard-manager.ts"() {
3627
3800
  "use strict";
3628
3801
  init_config();
3629
- SHARDS_DIR = path14.join(EXE_AI_DIR, "shards");
3802
+ SHARDS_DIR = path15.join(EXE_AI_DIR, "shards");
3803
+ SHARD_IDLE_MS = 5 * 60 * 1e3;
3804
+ MAX_OPEN_SHARDS = 10;
3805
+ EVICTION_INTERVAL_MS = 60 * 1e3;
3630
3806
  _shards = /* @__PURE__ */ new Map();
3807
+ _shardLastAccess = /* @__PURE__ */ new Map();
3808
+ _evictionTimer = null;
3631
3809
  _encryptionKey = null;
3632
3810
  _shardingEnabled = false;
3633
3811
  }
@@ -4400,7 +4578,7 @@ __export(review_gate_exports, {
4400
4578
  runReviewGate: () => runReviewGate
4401
4579
  });
4402
4580
  import { execSync as execSync5 } from "child_process";
4403
- import { existsSync as existsSync12 } from "fs";
4581
+ import { existsSync as existsSync14 } from "fs";
4404
4582
  function checkCommitsExist(taskCreatedAt) {
4405
4583
  try {
4406
4584
  const since = new Date(taskCreatedAt).toISOString();
@@ -4463,7 +4641,7 @@ function checkTestCoverage(taskCreatedAt) {
4463
4641
  const testPath = file.replace(/^src\//, "tests/").replace(/\.ts$/, ".test.ts");
4464
4642
  const baseName = file.split("/").pop()?.replace(/\.ts$/, "") ?? "";
4465
4643
  const testDir = testPath.substring(0, testPath.lastIndexOf("/"));
4466
- const hasDirectTest = existsSync12(testPath);
4644
+ const hasDirectTest = existsSync14(testPath);
4467
4645
  let hasRelatedTest = false;
4468
4646
  try {
4469
4647
  const related = execSync5(
@@ -4517,9 +4695,9 @@ var init_review_gate = __esm({
4517
4695
  });
4518
4696
 
4519
4697
  // src/adapters/claude/hooks/pre-tool-use.ts
4520
- import { existsSync as existsSync13, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7 } from "fs";
4698
+ import { existsSync as existsSync15, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7 } from "fs";
4521
4699
  import { execSync as execSync6 } from "child_process";
4522
- import path15 from "path";
4700
+ import path16 from "path";
4523
4701
 
4524
4702
  // src/lib/active-agent.ts
4525
4703
  init_config();
@@ -4633,17 +4811,17 @@ if (!process.env.AGENT_ID) {
4633
4811
  }
4634
4812
  var DELEGATION_TASK_THRESHOLD = 3;
4635
4813
  var CTO_ROLES = ["CTO", "executive"];
4636
- var CACHE_DIR2 = path15.join(EXE_AI_DIR, "session-cache");
4814
+ var CACHE_DIR2 = path16.join(EXE_AI_DIR, "session-cache");
4637
4815
  var timeout = setTimeout(() => {
4638
4816
  process.exit(0);
4639
4817
  }, 5e3);
4640
4818
  timeout.unref();
4641
4819
  function getDelegationFlagPath() {
4642
- return path15.join(CACHE_DIR2, `delegation-checkpoint-${getSessionKey()}.json`);
4820
+ return path16.join(CACHE_DIR2, `delegation-checkpoint-${getSessionKey()}.json`);
4643
4821
  }
4644
4822
  function hasDelegationFired() {
4645
4823
  try {
4646
- return existsSync13(getDelegationFlagPath());
4824
+ return existsSync15(getDelegationFlagPath());
4647
4825
  } catch {
4648
4826
  return false;
4649
4827
  }
@@ -4651,7 +4829,7 @@ function hasDelegationFired() {
4651
4829
  function markDelegationFired() {
4652
4830
  try {
4653
4831
  mkdirSync7(CACHE_DIR2, { recursive: true });
4654
- writeFileSync7(getDelegationFlagPath(), JSON.stringify({ fired: true }));
4832
+ writeFileSync8(getDelegationFlagPath(), JSON.stringify({ fired: true }));
4655
4833
  } catch {
4656
4834
  }
4657
4835
  }