@askexenow/exe-os 0.9.102 → 0.9.104

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 (92) hide show
  1. package/dist/bin/agentic-ontology-backfill.js +334 -100
  2. package/dist/bin/agentic-reflection-backfill.js +328 -97
  3. package/dist/bin/agentic-semantic-label.js +328 -97
  4. package/dist/bin/backfill-conversations.js +332 -97
  5. package/dist/bin/backfill-responses.js +332 -97
  6. package/dist/bin/backfill-vectors.js +337 -106
  7. package/dist/bin/bulk-sync-postgres.js +335 -101
  8. package/dist/bin/cleanup-stale-review-tasks.js +356 -108
  9. package/dist/bin/cli.js +653 -405
  10. package/dist/bin/exe-agent.js +21 -3
  11. package/dist/bin/exe-assign.js +338 -94
  12. package/dist/bin/exe-boot.js +472 -239
  13. package/dist/bin/exe-call.js +22 -5
  14. package/dist/bin/exe-cloud.js +404 -158
  15. package/dist/bin/exe-dispatch.js +390 -142
  16. package/dist/bin/exe-doctor.js +349 -103
  17. package/dist/bin/exe-export-behaviors.js +351 -105
  18. package/dist/bin/exe-forget.js +352 -103
  19. package/dist/bin/exe-gateway.js +420 -172
  20. package/dist/bin/exe-heartbeat.js +361 -113
  21. package/dist/bin/exe-kill.js +344 -98
  22. package/dist/bin/exe-launch-agent.js +375 -129
  23. package/dist/bin/exe-new-employee.js +83 -67
  24. package/dist/bin/exe-pending-messages.js +356 -108
  25. package/dist/bin/exe-pending-notifications.js +358 -110
  26. package/dist/bin/exe-pending-reviews.js +359 -111
  27. package/dist/bin/exe-rename.js +354 -108
  28. package/dist/bin/exe-review.js +343 -97
  29. package/dist/bin/exe-search.js +363 -113
  30. package/dist/bin/exe-session-cleanup.js +403 -155
  31. package/dist/bin/exe-settings.js +14 -9
  32. package/dist/bin/exe-start-codex.js +365 -131
  33. package/dist/bin/exe-start-opencode.js +359 -125
  34. package/dist/bin/exe-status.js +356 -108
  35. package/dist/bin/exe-team.js +343 -97
  36. package/dist/bin/git-sweep.js +390 -142
  37. package/dist/bin/graph-backfill.js +334 -100
  38. package/dist/bin/graph-export.js +346 -100
  39. package/dist/bin/install.js +1 -0
  40. package/dist/bin/intercom-check.js +403 -155
  41. package/dist/bin/pre-publish.js +12 -0
  42. package/dist/bin/scan-tasks.js +393 -145
  43. package/dist/bin/setup.js +331 -159
  44. package/dist/bin/shard-migrate.js +328 -94
  45. package/dist/gateway/index.js +406 -158
  46. package/dist/hooks/bug-report-worker.js +396 -148
  47. package/dist/hooks/codex-stop-task-finalizer.js +374 -126
  48. package/dist/hooks/commit-complete.js +390 -142
  49. package/dist/hooks/error-recall.js +365 -115
  50. package/dist/hooks/ingest.js +357 -111
  51. package/dist/hooks/instructions-loaded.js +351 -105
  52. package/dist/hooks/notification.js +343 -97
  53. package/dist/hooks/post-compact.js +358 -110
  54. package/dist/hooks/post-tool-combined.js +384 -132
  55. package/dist/hooks/pre-compact.js +391 -143
  56. package/dist/hooks/pre-tool-use.js +362 -114
  57. package/dist/hooks/prompt-submit.js +422 -170
  58. package/dist/hooks/session-end.js +393 -145
  59. package/dist/hooks/session-start.js +390 -138
  60. package/dist/hooks/stop.js +361 -113
  61. package/dist/hooks/subagent-stop.js +354 -106
  62. package/dist/hooks/summary-worker.js +418 -185
  63. package/dist/index.js +400 -152
  64. package/dist/lib/cloud-sync.js +291 -131
  65. package/dist/lib/consolidation.js +8 -2
  66. package/dist/lib/database.js +233 -73
  67. package/dist/lib/db.js +233 -73
  68. package/dist/lib/device-registry.js +237 -77
  69. package/dist/lib/employee-templates.js +19 -1
  70. package/dist/lib/exe-daemon.js +705 -409
  71. package/dist/lib/hybrid-search.js +363 -113
  72. package/dist/lib/identity.js +9 -5
  73. package/dist/lib/messaging.js +26 -20
  74. package/dist/lib/reminders.js +5 -1
  75. package/dist/lib/schedules.js +320 -89
  76. package/dist/lib/skill-learning.js +28 -24
  77. package/dist/lib/store.js +342 -96
  78. package/dist/lib/tasks.js +82 -76
  79. package/dist/lib/tmux-routing.js +74 -68
  80. package/dist/lib/token-spend.js +5 -1
  81. package/dist/mcp/server.js +628 -355
  82. package/dist/mcp/tools/complete-reminder.js +5 -1
  83. package/dist/mcp/tools/create-reminder.js +5 -1
  84. package/dist/mcp/tools/create-task.js +89 -83
  85. package/dist/mcp/tools/deactivate-behavior.js +7 -3
  86. package/dist/mcp/tools/list-reminders.js +5 -1
  87. package/dist/mcp/tools/list-tasks.js +28 -21
  88. package/dist/mcp/tools/send-message.js +28 -22
  89. package/dist/mcp/tools/update-task.js +89 -83
  90. package/dist/runtime/index.js +390 -142
  91. package/dist/tui/App.js +437 -189
  92. package/package.json +1 -1
@@ -919,8 +919,10 @@ var init_memory = __esm({
919
919
  });
920
920
 
921
921
  // src/lib/database.ts
922
- import { chmodSync as chmodSync2 } from "fs";
922
+ import { chmodSync as chmodSync2, existsSync as existsSync7, statSync, copyFileSync, unlinkSync as unlinkSync2, openSync, closeSync, mkdirSync as mkdirSync4 } from "fs";
923
923
  import { createClient } from "@libsql/client";
924
+ import { homedir } from "os";
925
+ import { join } from "path";
924
926
  function getClient() {
925
927
  if (!_adapterClient) {
926
928
  throw new Error("Database client not initialized. Call initDatabase() first.");
@@ -939,7 +941,7 @@ function getClient() {
939
941
  }
940
942
  return _resilientClient;
941
943
  }
942
- var _resilientClient, _daemonClient, _adapterClient;
944
+ var _debugDb, _resilientClient, _daemonClient, _adapterClient, DB_LOCK_PATH;
943
945
  var init_database = __esm({
944
946
  "src/lib/database.ts"() {
945
947
  "use strict";
@@ -947,14 +949,16 @@ var init_database = __esm({
947
949
  init_employees();
948
950
  init_database_adapter();
949
951
  init_memory();
952
+ _debugDb = process.env.EXE_DEBUG === "1";
950
953
  _resilientClient = null;
951
954
  _daemonClient = null;
952
955
  _adapterClient = null;
956
+ DB_LOCK_PATH = join(homedir(), ".exe-os", "db.lock");
953
957
  }
954
958
  });
955
959
 
956
960
  // src/lib/license.ts
957
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, existsSync as existsSync7, mkdirSync as mkdirSync4 } from "fs";
961
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, existsSync as existsSync8, mkdirSync as mkdirSync5 } from "fs";
958
962
  import { randomUUID } from "crypto";
959
963
  import { createRequire as createRequire2 } from "module";
960
964
  import { pathToFileURL as pathToFileURL2 } from "url";
@@ -981,11 +985,11 @@ var init_license = __esm({
981
985
  });
982
986
 
983
987
  // src/lib/plan-limits.ts
984
- import { readFileSync as readFileSync7, existsSync as existsSync8 } from "fs";
988
+ import { readFileSync as readFileSync7, existsSync as existsSync9 } from "fs";
985
989
  import path8 from "path";
986
990
  function getLicenseSync() {
987
991
  try {
988
- if (!existsSync8(CACHE_PATH2)) return freeLicense();
992
+ if (!existsSync9(CACHE_PATH2)) return freeLicense();
989
993
  const raw = JSON.parse(readFileSync7(CACHE_PATH2, "utf8"));
990
994
  if (!raw.token || typeof raw.token !== "string") return freeLicense();
991
995
  const parts = raw.token.split(".");
@@ -1024,7 +1028,7 @@ function assertEmployeeLimitSync(rosterPath) {
1024
1028
  const filePath = rosterPath ?? EMPLOYEES_PATH;
1025
1029
  let count = 0;
1026
1030
  try {
1027
- if (existsSync8(filePath)) {
1031
+ if (existsSync9(filePath)) {
1028
1032
  const raw = readFileSync7(filePath, "utf8");
1029
1033
  const employees = JSON.parse(raw);
1030
1034
  count = Array.isArray(employees) ? employees.length : 0;
@@ -1062,9 +1066,9 @@ var init_plan_limits = __esm({
1062
1066
  import os7 from "os";
1063
1067
  import path9 from "path";
1064
1068
  import {
1065
- existsSync as existsSync9,
1069
+ existsSync as existsSync10,
1066
1070
  lstatSync,
1067
- mkdirSync as mkdirSync5,
1071
+ mkdirSync as mkdirSync6,
1068
1072
  readlinkSync as readlinkSync2,
1069
1073
  symlinkSync as symlinkSync2
1070
1074
  } from "fs";
@@ -1080,8 +1084,8 @@ function claudeAgentLinkPath(homeDir, agentId) {
1080
1084
  function ensureAgentSymlink(agentId, homeDir = os7.homedir()) {
1081
1085
  const target = identitySourcePath(homeDir, agentId);
1082
1086
  const link = claudeAgentLinkPath(homeDir, agentId);
1083
- mkdirSync5(claudeAgentsDir(homeDir), { recursive: true });
1084
- if (existsSync9(link)) {
1087
+ mkdirSync6(claudeAgentsDir(homeDir), { recursive: true });
1088
+ if (existsSync10(link)) {
1085
1089
  let stat;
1086
1090
  try {
1087
1091
  stat = lstatSync(link);
@@ -1162,8 +1166,8 @@ import os8 from "os";
1162
1166
  import {
1163
1167
  readFileSync as readFileSync8,
1164
1168
  readdirSync,
1165
- unlinkSync as unlinkSync2,
1166
- existsSync as existsSync10,
1169
+ unlinkSync as unlinkSync3,
1170
+ existsSync as existsSync11,
1167
1171
  rmdirSync
1168
1172
  } from "fs";
1169
1173
  async function writeNotification(notification) {
@@ -1411,7 +1415,7 @@ import path12 from "path";
1411
1415
  import os9 from "os";
1412
1416
  import { execSync as execSync5 } from "child_process";
1413
1417
  import { mkdir as mkdir3, writeFile as writeFile3, appendFile } from "fs/promises";
1414
- import { existsSync as existsSync11, readFileSync as readFileSync9 } from "fs";
1418
+ import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
1415
1419
  async function writeCheckpoint(input) {
1416
1420
  const client = getClient();
1417
1421
  const row = await resolveTask(client, input.taskId);
@@ -1652,7 +1656,7 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
1652
1656
  const EXE_OS_DIR = path12.join(os9.homedir(), ".exe-os");
1653
1657
  const mdPath = path12.join(EXE_OS_DIR, taskFile);
1654
1658
  const mdDir = path12.dirname(mdPath);
1655
- if (!existsSync11(mdDir)) await mkdir3(mdDir, { recursive: true });
1659
+ if (!existsSync12(mdDir)) await mkdir3(mdDir, { recursive: true });
1656
1660
  const reviewer = input.reviewer ?? input.assignedBy;
1657
1661
  const mdContent = `# ${input.title}
1658
1662
 
@@ -1958,7 +1962,7 @@ async function deleteTaskCore(taskId, _baseDir) {
1958
1962
  async function ensureArchitectureDoc(baseDir, projectName) {
1959
1963
  const archPath = path12.join(baseDir, "exe", "ARCHITECTURE.md");
1960
1964
  try {
1961
- if (existsSync11(archPath)) return;
1965
+ if (existsSync12(archPath)) return;
1962
1966
  const template = [
1963
1967
  `# ${projectName} \u2014 System Architecture`,
1964
1968
  "",
@@ -1993,7 +1997,7 @@ async function ensureArchitectureDoc(baseDir, projectName) {
1993
1997
  async function ensureGitignoreExe(baseDir) {
1994
1998
  const gitignorePath = path12.join(baseDir, ".gitignore");
1995
1999
  try {
1996
- if (existsSync11(gitignorePath)) {
2000
+ if (existsSync12(gitignorePath)) {
1997
2001
  const content = readFileSync9(gitignorePath, "utf-8");
1998
2002
  if (/^\/?exe\/?$/m.test(content)) return;
1999
2003
  await appendFile(gitignorePath, "\n# Employee task assignments (private)\n/exe/\n");
@@ -2038,7 +2042,7 @@ __export(tasks_review_exports, {
2038
2042
  listPendingReviews: () => listPendingReviews
2039
2043
  });
2040
2044
  import path13 from "path";
2041
- import { existsSync as existsSync12, readdirSync as readdirSync2, unlinkSync as unlinkSync3 } from "fs";
2045
+ import { existsSync as existsSync13, readdirSync as readdirSync2, unlinkSync as unlinkSync4 } from "fs";
2042
2046
  function formatAge(isoTimestamp) {
2043
2047
  if (!isoTimestamp) return "";
2044
2048
  const ms = Date.now() - new Date(isoTimestamp).getTime();
@@ -2308,10 +2312,10 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
2308
2312
  }
2309
2313
  try {
2310
2314
  const cacheDir = path13.join(EXE_AI_DIR, "session-cache");
2311
- if (existsSync12(cacheDir)) {
2315
+ if (existsSync13(cacheDir)) {
2312
2316
  for (const f of readdirSync2(cacheDir)) {
2313
2317
  if (f.startsWith("review-notified-")) {
2314
- unlinkSync3(path13.join(cacheDir, f));
2318
+ unlinkSync4(path13.join(cacheDir, f));
2315
2319
  }
2316
2320
  }
2317
2321
  }
@@ -2500,7 +2504,7 @@ var init_tasks_notify = __esm({
2500
2504
  // src/lib/daemon-auth.ts
2501
2505
  import crypto4 from "crypto";
2502
2506
  import path15 from "path";
2503
- import { existsSync as existsSync13, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
2507
+ import { existsSync as existsSync14, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
2504
2508
  function normalizeToken(token) {
2505
2509
  if (!token) return null;
2506
2510
  const trimmed = token.trim();
@@ -2508,7 +2512,7 @@ function normalizeToken(token) {
2508
2512
  }
2509
2513
  function readDaemonToken() {
2510
2514
  try {
2511
- if (!existsSync13(DAEMON_TOKEN_PATH)) return null;
2515
+ if (!existsSync14(DAEMON_TOKEN_PATH)) return null;
2512
2516
  return normalizeToken(readFileSync10(DAEMON_TOKEN_PATH, "utf8"));
2513
2517
  } catch {
2514
2518
  return null;
@@ -2539,7 +2543,7 @@ import net from "net";
2539
2543
  import os10 from "os";
2540
2544
  import { spawn, execSync as execSync6 } from "child_process";
2541
2545
  import { randomUUID as randomUUID2 } from "crypto";
2542
- import { existsSync as existsSync14, unlinkSync as unlinkSync4, readFileSync as readFileSync11, openSync, closeSync, statSync } from "fs";
2546
+ import { existsSync as existsSync15, unlinkSync as unlinkSync5, readFileSync as readFileSync11, openSync as openSync2, closeSync as closeSync2, statSync as statSync2 } from "fs";
2543
2547
  import path16 from "path";
2544
2548
  import { fileURLToPath } from "url";
2545
2549
  function handleData(chunk) {
@@ -2576,7 +2580,7 @@ function isZombie(pid) {
2576
2580
  }
2577
2581
  }
2578
2582
  function cleanupStaleFiles() {
2579
- if (existsSync14(PID_PATH)) {
2583
+ if (existsSync15(PID_PATH)) {
2580
2584
  try {
2581
2585
  const pid = parseInt(readFileSync11(PID_PATH, "utf8").trim(), 10);
2582
2586
  if (pid > 0) {
@@ -2593,11 +2597,11 @@ function cleanupStaleFiles() {
2593
2597
  } catch {
2594
2598
  }
2595
2599
  try {
2596
- unlinkSync4(PID_PATH);
2600
+ unlinkSync5(PID_PATH);
2597
2601
  } catch {
2598
2602
  }
2599
2603
  try {
2600
- unlinkSync4(SOCKET_PATH);
2604
+ unlinkSync5(SOCKET_PATH);
2601
2605
  } catch {
2602
2606
  }
2603
2607
  }
@@ -2606,7 +2610,7 @@ function findPackageRoot() {
2606
2610
  let dir = path16.dirname(fileURLToPath(import.meta.url));
2607
2611
  const { root } = path16.parse(dir);
2608
2612
  while (dir !== root) {
2609
- if (existsSync14(path16.join(dir, "package.json"))) return dir;
2613
+ if (existsSync15(path16.join(dir, "package.json"))) return dir;
2610
2614
  dir = path16.dirname(dir);
2611
2615
  }
2612
2616
  return null;
@@ -2626,7 +2630,7 @@ function spawnDaemon() {
2626
2630
  return;
2627
2631
  }
2628
2632
  const daemonPath = path16.join(pkgRoot, "dist", "lib", "exe-daemon.js");
2629
- if (!existsSync14(daemonPath)) {
2633
+ if (!existsSync15(daemonPath)) {
2630
2634
  process.stderr.write(`[exed-client] WARN: daemon script not found at ${daemonPath}
2631
2635
  `);
2632
2636
  return;
@@ -2638,7 +2642,7 @@ function spawnDaemon() {
2638
2642
  const logPath = path16.join(path16.dirname(SOCKET_PATH), "exed.log");
2639
2643
  let stderrFd = "ignore";
2640
2644
  try {
2641
- stderrFd = openSync(logPath, "a");
2645
+ stderrFd = openSync2(logPath, "a");
2642
2646
  } catch {
2643
2647
  }
2644
2648
  const heapCapMB = totalGB <= 8 ? 256 : 512;
@@ -2660,27 +2664,27 @@ function spawnDaemon() {
2660
2664
  child.unref();
2661
2665
  if (typeof stderrFd === "number") {
2662
2666
  try {
2663
- closeSync(stderrFd);
2667
+ closeSync2(stderrFd);
2664
2668
  } catch {
2665
2669
  }
2666
2670
  }
2667
2671
  }
2668
2672
  function acquireSpawnLock() {
2669
2673
  try {
2670
- const fd = openSync(SPAWN_LOCK_PATH, "wx");
2671
- closeSync(fd);
2674
+ const fd = openSync2(SPAWN_LOCK_PATH, "wx");
2675
+ closeSync2(fd);
2672
2676
  return true;
2673
2677
  } catch {
2674
2678
  try {
2675
- const stat = statSync(SPAWN_LOCK_PATH);
2679
+ const stat = statSync2(SPAWN_LOCK_PATH);
2676
2680
  if (Date.now() - stat.mtimeMs > SPAWN_LOCK_STALE_MS) {
2677
2681
  try {
2678
- unlinkSync4(SPAWN_LOCK_PATH);
2682
+ unlinkSync5(SPAWN_LOCK_PATH);
2679
2683
  } catch {
2680
2684
  }
2681
2685
  try {
2682
- const fd = openSync(SPAWN_LOCK_PATH, "wx");
2683
- closeSync(fd);
2686
+ const fd = openSync2(SPAWN_LOCK_PATH, "wx");
2687
+ closeSync2(fd);
2684
2688
  return true;
2685
2689
  } catch {
2686
2690
  }
@@ -2692,7 +2696,7 @@ function acquireSpawnLock() {
2692
2696
  }
2693
2697
  function releaseSpawnLock() {
2694
2698
  try {
2695
- unlinkSync4(SPAWN_LOCK_PATH);
2699
+ unlinkSync5(SPAWN_LOCK_PATH);
2696
2700
  } catch {
2697
2701
  }
2698
2702
  }
@@ -2800,7 +2804,7 @@ function killAndRespawnDaemon() {
2800
2804
  }
2801
2805
  try {
2802
2806
  process.stderr.write("[exed-client] Killing daemon for restart...\n");
2803
- if (existsSync14(PID_PATH)) {
2807
+ if (existsSync15(PID_PATH)) {
2804
2808
  try {
2805
2809
  const pid = parseInt(readFileSync11(PID_PATH, "utf8").trim(), 10);
2806
2810
  if (pid > 0) {
@@ -2819,11 +2823,11 @@ function killAndRespawnDaemon() {
2819
2823
  _connected = false;
2820
2824
  _buffer = "";
2821
2825
  try {
2822
- unlinkSync4(PID_PATH);
2826
+ unlinkSync5(PID_PATH);
2823
2827
  } catch {
2824
2828
  }
2825
2829
  try {
2826
- unlinkSync4(SOCKET_PATH);
2830
+ unlinkSync5(SOCKET_PATH);
2827
2831
  } catch {
2828
2832
  }
2829
2833
  spawnDaemon();
@@ -2833,7 +2837,7 @@ function killAndRespawnDaemon() {
2833
2837
  }
2834
2838
  function isDaemonTooYoung() {
2835
2839
  try {
2836
- const stat = statSync(PID_PATH);
2840
+ const stat = statSync2(PID_PATH);
2837
2841
  return Date.now() - stat.mtimeMs < MIN_DAEMON_AGE_MS;
2838
2842
  } catch {
2839
2843
  return false;
@@ -2983,10 +2987,10 @@ async function disposeEmbedder() {
2983
2987
  async function embedDirect(text) {
2984
2988
  const llamaCpp = await import("node-llama-cpp");
2985
2989
  const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
2986
- const { existsSync: existsSync16 } = await import("fs");
2990
+ const { existsSync: existsSync17 } = await import("fs");
2987
2991
  const path19 = await import("path");
2988
2992
  const modelPath = path19.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
2989
- if (!existsSync16(modelPath)) {
2993
+ if (!existsSync17(modelPath)) {
2990
2994
  throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
2991
2995
  }
2992
2996
  const llama = await llamaCpp.getLlama();
@@ -3353,7 +3357,7 @@ __export(tasks_exports, {
3353
3357
  writeCheckpoint: () => writeCheckpoint
3354
3358
  });
3355
3359
  import path17 from "path";
3356
- import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, unlinkSync as unlinkSync5 } from "fs";
3360
+ import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, unlinkSync as unlinkSync6 } from "fs";
3357
3361
  async function createTask(input) {
3358
3362
  const result = await createTaskCore(input);
3359
3363
  if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
@@ -3375,11 +3379,11 @@ async function updateTask(input) {
3375
3379
  const cacheDir = path17.join(EXE_AI_DIR, "session-cache");
3376
3380
  const cachePath = path17.join(cacheDir, `current-task-${agent}.json`);
3377
3381
  if (input.status === "in_progress") {
3378
- mkdirSync6(cacheDir, { recursive: true });
3382
+ mkdirSync7(cacheDir, { recursive: true });
3379
3383
  writeFileSync7(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
3380
3384
  } else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled" || input.status === "closed") {
3381
3385
  try {
3382
- unlinkSync5(cachePath);
3386
+ unlinkSync6(cachePath);
3383
3387
  } catch {
3384
3388
  }
3385
3389
  }
@@ -3847,11 +3851,11 @@ __export(tmux_routing_exports, {
3847
3851
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
3848
3852
  });
3849
3853
  import { execFileSync as execFileSync2, execSync as execSync7 } from "child_process";
3850
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7, existsSync as existsSync15, appendFileSync, readdirSync as readdirSync3 } from "fs";
3854
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync8, mkdirSync as mkdirSync8, existsSync as existsSync16, appendFileSync, readdirSync as readdirSync3 } from "fs";
3851
3855
  import path18 from "path";
3852
3856
  import os11 from "os";
3853
3857
  import { fileURLToPath as fileURLToPath2 } from "url";
3854
- import { unlinkSync as unlinkSync6 } from "fs";
3858
+ import { unlinkSync as unlinkSync7 } from "fs";
3855
3859
  function spawnLockPath(sessionName) {
3856
3860
  return path18.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
3857
3861
  }
@@ -3864,11 +3868,11 @@ function isProcessAlive(pid) {
3864
3868
  }
3865
3869
  }
3866
3870
  function acquireSpawnLock2(sessionName) {
3867
- if (!existsSync15(SPAWN_LOCK_DIR)) {
3868
- mkdirSync7(SPAWN_LOCK_DIR, { recursive: true });
3871
+ if (!existsSync16(SPAWN_LOCK_DIR)) {
3872
+ mkdirSync8(SPAWN_LOCK_DIR, { recursive: true });
3869
3873
  }
3870
3874
  const lockFile = spawnLockPath(sessionName);
3871
- if (existsSync15(lockFile)) {
3875
+ if (existsSync16(lockFile)) {
3872
3876
  try {
3873
3877
  const lock = JSON.parse(readFileSync12(lockFile, "utf8"));
3874
3878
  const age = Date.now() - lock.timestamp;
@@ -3883,7 +3887,7 @@ function acquireSpawnLock2(sessionName) {
3883
3887
  }
3884
3888
  function releaseSpawnLock2(sessionName) {
3885
3889
  try {
3886
- unlinkSync6(spawnLockPath(sessionName));
3890
+ unlinkSync7(spawnLockPath(sessionName));
3887
3891
  } catch {
3888
3892
  }
3889
3893
  }
@@ -3896,7 +3900,7 @@ function resolveBehaviorsExporterScript() {
3896
3900
  "bin",
3897
3901
  "exe-export-behaviors.js"
3898
3902
  );
3899
- return existsSync15(scriptPath) ? scriptPath : null;
3903
+ return existsSync16(scriptPath) ? scriptPath : null;
3900
3904
  } catch {
3901
3905
  return null;
3902
3906
  }
@@ -3962,8 +3966,8 @@ function extractRootExe(name) {
3962
3966
  return parts.length > 0 ? parts[parts.length - 1] : null;
3963
3967
  }
3964
3968
  function registerParentExe(sessionKey, parentExe, dispatchedBy) {
3965
- if (!existsSync15(SESSION_CACHE)) {
3966
- mkdirSync7(SESSION_CACHE, { recursive: true });
3969
+ if (!existsSync16(SESSION_CACHE)) {
3970
+ mkdirSync8(SESSION_CACHE, { recursive: true });
3967
3971
  }
3968
3972
  const rootExe = extractRootExe(parentExe) ?? parentExe;
3969
3973
  const filePath = path18.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
@@ -3993,11 +3997,13 @@ function getDispatchedBy(sessionKey) {
3993
3997
  }
3994
3998
  }
3995
3999
  function resolveExeSession() {
3996
- if (process.env.EXE_SESSION_NAME) {
3997
- return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
3998
- }
3999
4000
  const mySession = getMySession();
4000
- if (!mySession) return null;
4001
+ if (!mySession) {
4002
+ if (process.env.EXE_SESSION_NAME) {
4003
+ return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
4004
+ }
4005
+ return null;
4006
+ }
4001
4007
  const fromSessionName = extractRootExe(mySession);
4002
4008
  let candidate = null;
4003
4009
  try {
@@ -4092,7 +4098,7 @@ async function verifyPaneAtCapacity(sessionName) {
4092
4098
  }
4093
4099
  function readDebounceState() {
4094
4100
  try {
4095
- if (!existsSync15(DEBOUNCE_FILE)) return {};
4101
+ if (!existsSync16(DEBOUNCE_FILE)) return {};
4096
4102
  const raw = JSON.parse(readFileSync12(DEBOUNCE_FILE, "utf8"));
4097
4103
  const state = {};
4098
4104
  for (const [key, val] of Object.entries(raw)) {
@@ -4109,7 +4115,7 @@ function readDebounceState() {
4109
4115
  }
4110
4116
  function writeDebounceState(state) {
4111
4117
  try {
4112
- if (!existsSync15(SESSION_CACHE)) mkdirSync7(SESSION_CACHE, { recursive: true });
4118
+ if (!existsSync16(SESSION_CACHE)) mkdirSync8(SESSION_CACHE, { recursive: true });
4113
4119
  writeFileSync8(DEBOUNCE_FILE, JSON.stringify(state));
4114
4120
  } catch {
4115
4121
  }
@@ -4210,7 +4216,7 @@ function sendIntercom(targetSession) {
4210
4216
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
4211
4217
  const agent = baseAgentName(rawAgent);
4212
4218
  const markerPath = path18.join(SESSION_CACHE, `current-task-${agent}.json`);
4213
- if (existsSync15(markerPath)) {
4219
+ if (existsSync16(markerPath)) {
4214
4220
  logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker + not idle \u2014 will auto-chain)`);
4215
4221
  return "debounced";
4216
4222
  }
@@ -4221,7 +4227,7 @@ function sendIntercom(targetSession) {
4221
4227
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
4222
4228
  const agent = baseAgentName(rawAgent);
4223
4229
  const taskDir = path18.join(process.cwd(), "exe", agent);
4224
- if (existsSync15(taskDir)) {
4230
+ if (existsSync16(taskDir)) {
4225
4231
  const files = readdirSync3(taskDir).filter(
4226
4232
  (f) => f.endsWith(".md") && f !== "DONE.txt"
4227
4233
  );
@@ -4382,15 +4388,15 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4382
4388
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
4383
4389
  const logDir = path18.join(os11.homedir(), ".exe-os", "session-logs");
4384
4390
  const logFile = path18.join(logDir, `${instanceLabel}-${Date.now()}.log`);
4385
- if (!existsSync15(logDir)) {
4386
- mkdirSync7(logDir, { recursive: true });
4391
+ if (!existsSync16(logDir)) {
4392
+ mkdirSync8(logDir, { recursive: true });
4387
4393
  }
4388
4394
  transport.kill(sessionName);
4389
4395
  let cleanupSuffix = "";
4390
4396
  try {
4391
4397
  const thisFile = fileURLToPath2(import.meta.url);
4392
4398
  const cleanupScript = path18.join(path18.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
4393
- if (existsSync15(cleanupScript)) {
4399
+ if (existsSync16(cleanupScript)) {
4394
4400
  cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
4395
4401
  }
4396
4402
  } catch {
@@ -4445,7 +4451,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4445
4451
  if (changed) {
4446
4452
  perms.allow = allow;
4447
4453
  settings.permissions = perms;
4448
- mkdirSync7(projSettingsDir, { recursive: true });
4454
+ mkdirSync8(projSettingsDir, { recursive: true });
4449
4455
  writeFileSync8(settingsPath, JSON.stringify(settings, null, 2) + "\n");
4450
4456
  }
4451
4457
  } catch {
@@ -4483,7 +4489,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4483
4489
  `
4484
4490
  );
4485
4491
  }
4486
- } else if (existsSync15(identityPath)) {
4492
+ } else if (existsSync16(identityPath)) {
4487
4493
  identityFlag = ` --append-system-prompt-file ${identityPath}`;
4488
4494
  legacyFallbackWarned = true;
4489
4495
  }
@@ -4505,7 +4511,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
4505
4511
  let sessionContextFlag = "";
4506
4512
  try {
4507
4513
  const ctxDir = path18.join(os11.homedir(), ".exe-os", "session-cache");
4508
- mkdirSync7(ctxDir, { recursive: true });
4514
+ mkdirSync8(ctxDir, { recursive: true });
4509
4515
  const ctxFile = path18.join(ctxDir, `session-context-${sessionName}.md`);
4510
4516
  const ctxContent = [
4511
4517
  `## Session Context`,
@@ -119,8 +119,10 @@ import path4 from "path";
119
119
  import os4 from "os";
120
120
 
121
121
  // src/lib/database.ts
122
- import { chmodSync as chmodSync2 } from "fs";
122
+ import { chmodSync as chmodSync2, existsSync as existsSync4, statSync, copyFileSync, unlinkSync as unlinkSync2, openSync, closeSync, mkdirSync as mkdirSync2 } from "fs";
123
123
  import { createClient } from "@libsql/client";
124
+ import { homedir } from "os";
125
+ import { join } from "path";
124
126
 
125
127
  // src/lib/employees.ts
126
128
  init_config();
@@ -148,9 +150,11 @@ var BOOLEAN_COLUMN_NAMES = new Set(
148
150
  );
149
151
 
150
152
  // src/lib/database.ts
153
+ var _debugDb = process.env.EXE_DEBUG === "1";
151
154
  var _resilientClient = null;
152
155
  var _daemonClient = null;
153
156
  var _adapterClient = null;
157
+ var DB_LOCK_PATH = join(homedir(), ".exe-os", "db.lock");
154
158
  function getClient() {
155
159
  if (!_adapterClient) {
156
160
  throw new Error("Database client not initialized. Call initDatabase() first.");