@askexenow/exe-os 0.8.32 → 0.8.36

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 (87) hide show
  1. package/dist/bin/backfill-conversations.js +332 -348
  2. package/dist/bin/backfill-responses.js +72 -12
  3. package/dist/bin/backfill-vectors.js +72 -12
  4. package/dist/bin/cleanup-stale-review-tasks.js +63 -3
  5. package/dist/bin/cli.js +1518 -1122
  6. package/dist/bin/exe-agent.js +4 -4
  7. package/dist/bin/exe-assign.js +80 -18
  8. package/dist/bin/exe-boot.js +408 -89
  9. package/dist/bin/exe-call.js +83 -24
  10. package/dist/bin/exe-dispatch.js +18 -10
  11. package/dist/bin/exe-doctor.js +63 -3
  12. package/dist/bin/exe-export-behaviors.js +64 -3
  13. package/dist/bin/exe-forget.js +69 -4
  14. package/dist/bin/exe-gateway.js +121 -36
  15. package/dist/bin/exe-heartbeat.js +77 -13
  16. package/dist/bin/exe-kill.js +64 -3
  17. package/dist/bin/exe-launch-agent.js +162 -35
  18. package/dist/bin/exe-link.js +946 -0
  19. package/dist/bin/exe-new-employee.js +121 -36
  20. package/dist/bin/exe-pending-messages.js +72 -7
  21. package/dist/bin/exe-pending-notifications.js +63 -3
  22. package/dist/bin/exe-pending-reviews.js +75 -10
  23. package/dist/bin/exe-rename.js +1287 -0
  24. package/dist/bin/exe-review.js +64 -4
  25. package/dist/bin/exe-search.js +79 -13
  26. package/dist/bin/exe-session-cleanup.js +91 -26
  27. package/dist/bin/exe-status.js +64 -4
  28. package/dist/bin/exe-team.js +64 -4
  29. package/dist/bin/git-sweep.js +71 -4
  30. package/dist/bin/graph-backfill.js +64 -3
  31. package/dist/bin/graph-export.js +64 -3
  32. package/dist/bin/install.js +3 -3
  33. package/dist/bin/scan-tasks.js +71 -4
  34. package/dist/bin/setup.js +156 -38
  35. package/dist/bin/shard-migrate.js +64 -3
  36. package/dist/bin/wiki-sync.js +64 -3
  37. package/dist/gateway/index.js +122 -37
  38. package/dist/hooks/bug-report-worker.js +209 -23
  39. package/dist/hooks/commit-complete.js +71 -4
  40. package/dist/hooks/error-recall.js +79 -13
  41. package/dist/hooks/ingest-worker.js +129 -43
  42. package/dist/hooks/instructions-loaded.js +71 -4
  43. package/dist/hooks/notification.js +71 -4
  44. package/dist/hooks/post-compact.js +71 -4
  45. package/dist/hooks/pre-compact.js +71 -4
  46. package/dist/hooks/pre-tool-use.js +413 -194
  47. package/dist/hooks/prompt-ingest-worker.js +82 -22
  48. package/dist/hooks/prompt-submit.js +103 -37
  49. package/dist/hooks/response-ingest-worker.js +87 -22
  50. package/dist/hooks/session-end.js +71 -4
  51. package/dist/hooks/session-start.js +79 -13
  52. package/dist/hooks/stop.js +71 -4
  53. package/dist/hooks/subagent-stop.js +71 -4
  54. package/dist/hooks/summary-worker.js +303 -50
  55. package/dist/index.js +134 -46
  56. package/dist/lib/cloud-sync.js +209 -15
  57. package/dist/lib/consolidation.js +4 -4
  58. package/dist/lib/database.js +64 -2
  59. package/dist/lib/device-registry.js +70 -3
  60. package/dist/lib/employee-templates.js +48 -22
  61. package/dist/lib/employees.js +34 -1
  62. package/dist/lib/exe-daemon.js +136 -53
  63. package/dist/lib/hybrid-search.js +79 -13
  64. package/dist/lib/identity-templates.js +57 -6
  65. package/dist/lib/identity.js +3 -3
  66. package/dist/lib/messaging.js +22 -14
  67. package/dist/lib/reminders.js +3 -3
  68. package/dist/lib/schedules.js +63 -3
  69. package/dist/lib/skill-learning.js +3 -3
  70. package/dist/lib/status-brief.js +63 -5
  71. package/dist/lib/store.js +64 -3
  72. package/dist/lib/task-router.js +4 -2
  73. package/dist/lib/tasks.js +48 -21
  74. package/dist/lib/tmux-routing.js +47 -20
  75. package/dist/mcp/server.js +727 -58
  76. package/dist/mcp/tools/complete-reminder.js +3 -3
  77. package/dist/mcp/tools/create-reminder.js +3 -3
  78. package/dist/mcp/tools/create-task.js +151 -24
  79. package/dist/mcp/tools/deactivate-behavior.js +3 -3
  80. package/dist/mcp/tools/list-reminders.js +3 -3
  81. package/dist/mcp/tools/list-tasks.js +17 -8
  82. package/dist/mcp/tools/send-message.js +24 -16
  83. package/dist/mcp/tools/update-task.js +25 -16
  84. package/dist/runtime/index.js +112 -24
  85. package/dist/tui/App.js +139 -36
  86. package/package.json +6 -2
  87. package/src/commands/exe/rename.md +12 -0
@@ -324,7 +324,7 @@ function listShards() {
324
324
  }
325
325
  async function ensureShardSchema(client) {
326
326
  await client.execute("PRAGMA journal_mode = WAL");
327
- await client.execute("PRAGMA busy_timeout = 5000");
327
+ await client.execute("PRAGMA busy_timeout = 30000");
328
328
  try {
329
329
  await client.execute("PRAGMA libsql_vector_search_ef = 128");
330
330
  } catch {
@@ -512,7 +512,7 @@ var init_shard_manager = __esm({
512
512
  import net from "net";
513
513
  import { spawn } from "child_process";
514
514
  import { randomUUID as randomUUID2 } from "crypto";
515
- import { existsSync as existsSync7, unlinkSync, readFileSync as readFileSync4, openSync, closeSync, statSync } from "fs";
515
+ import { existsSync as existsSync7, unlinkSync, readFileSync as readFileSync5, openSync, closeSync, statSync } from "fs";
516
516
  import path8 from "path";
517
517
  import { fileURLToPath } from "url";
518
518
  function handleData(chunk) {
@@ -537,7 +537,7 @@ function handleData(chunk) {
537
537
  function cleanupStaleFiles() {
538
538
  if (existsSync7(PID_PATH)) {
539
539
  try {
540
- const pid = parseInt(readFileSync4(PID_PATH, "utf8").trim(), 10);
540
+ const pid = parseInt(readFileSync5(PID_PATH, "utf8").trim(), 10);
541
541
  if (pid > 0) {
542
542
  try {
543
543
  process.kill(pid, 0);
@@ -685,11 +685,11 @@ async function connectEmbedDaemon() {
685
685
  }
686
686
  }
687
687
  const start = Date.now();
688
- let delay = 100;
688
+ let delay2 = 100;
689
689
  while (Date.now() - start < CONNECT_TIMEOUT_MS) {
690
- await new Promise((r) => setTimeout(r, delay));
690
+ await new Promise((r) => setTimeout(r, delay2));
691
691
  if (await connectToSocket()) return true;
692
- delay = Math.min(delay * 2, 3e3);
692
+ delay2 = Math.min(delay2 * 2, 3e3);
693
693
  }
694
694
  return false;
695
695
  }
@@ -745,7 +745,7 @@ function killAndRespawnDaemon() {
745
745
  process.stderr.write("[exed-client] Killing daemon for restart...\n");
746
746
  if (existsSync7(PID_PATH)) {
747
747
  try {
748
- const pid = parseInt(readFileSync4(PID_PATH, "utf8").trim(), 10);
748
+ const pid = parseInt(readFileSync5(PID_PATH, "utf8").trim(), 10);
749
749
  if (pid > 0) {
750
750
  try {
751
751
  process.kill(pid, "SIGKILL");
@@ -781,11 +781,11 @@ async function embedViaClient(text, priority = "high") {
781
781
  `);
782
782
  killAndRespawnDaemon();
783
783
  const start = Date.now();
784
- let delay = 200;
784
+ let delay2 = 200;
785
785
  while (Date.now() - start < CONNECT_TIMEOUT_MS) {
786
- await new Promise((r) => setTimeout(r, delay));
786
+ await new Promise((r) => setTimeout(r, delay2));
787
787
  if (await connectToSocket()) break;
788
- delay = Math.min(delay * 2, 3e3);
788
+ delay2 = Math.min(delay2 * 2, 3e3);
789
789
  }
790
790
  if (!_connected) return null;
791
791
  }
@@ -797,11 +797,11 @@ async function embedViaClient(text, priority = "high") {
797
797
  `);
798
798
  killAndRespawnDaemon();
799
799
  const start = Date.now();
800
- let delay = 200;
800
+ let delay2 = 200;
801
801
  while (Date.now() - start < CONNECT_TIMEOUT_MS) {
802
- await new Promise((r) => setTimeout(r, delay));
802
+ await new Promise((r) => setTimeout(r, delay2));
803
803
  if (await connectToSocket()) break;
804
- delay = Math.min(delay * 2, 3e3);
804
+ delay2 = Math.min(delay2 * 2, 3e3);
805
805
  }
806
806
  if (!_connected) return null;
807
807
  const retry = await sendRequest([text], priority);
@@ -958,12 +958,65 @@ init_memory();
958
958
 
959
959
  // src/lib/database.ts
960
960
  import { createClient } from "@libsql/client";
961
+
962
+ // src/lib/db-retry.ts
963
+ var MAX_RETRIES = 3;
964
+ var BASE_DELAY_MS = 200;
965
+ var MAX_JITTER_MS = 300;
966
+ function isBusyError(err) {
967
+ if (err instanceof Error) {
968
+ const msg = err.message.toLowerCase();
969
+ return msg.includes("sqlite_busy") || msg.includes("database is locked");
970
+ }
971
+ return false;
972
+ }
973
+ function delay(ms) {
974
+ return new Promise((resolve) => setTimeout(resolve, ms));
975
+ }
976
+ async function retryOnBusy(fn, label) {
977
+ let lastError;
978
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
979
+ try {
980
+ return await fn();
981
+ } catch (err) {
982
+ lastError = err;
983
+ if (!isBusyError(err) || attempt === MAX_RETRIES) {
984
+ throw err;
985
+ }
986
+ const backoff = BASE_DELAY_MS * Math.pow(2, attempt);
987
+ const jitter = Math.floor(Math.random() * MAX_JITTER_MS);
988
+ process.stderr.write(
989
+ `[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${MAX_RETRIES} \u2014 waiting ${backoff + jitter}ms
990
+ `
991
+ );
992
+ await delay(backoff + jitter);
993
+ }
994
+ }
995
+ throw lastError;
996
+ }
997
+ function wrapWithRetry(client) {
998
+ return new Proxy(client, {
999
+ get(target, prop, receiver) {
1000
+ if (prop === "execute") {
1001
+ return (sql) => retryOnBusy(() => target.execute(sql), "execute");
1002
+ }
1003
+ if (prop === "batch") {
1004
+ return (stmts) => retryOnBusy(() => target.batch(stmts), "batch");
1005
+ }
1006
+ return Reflect.get(target, prop, receiver);
1007
+ }
1008
+ });
1009
+ }
1010
+
1011
+ // src/lib/database.ts
961
1012
  var _client = null;
1013
+ var _resilientClient = null;
962
1014
  var initTurso = initDatabase;
963
1015
  async function initDatabase(config) {
964
1016
  if (_client) {
965
1017
  _client.close();
966
1018
  _client = null;
1019
+ _resilientClient = null;
967
1020
  }
968
1021
  const opts = {
969
1022
  url: `file:${config.dbPath}`
@@ -972,20 +1025,27 @@ async function initDatabase(config) {
972
1025
  opts.encryptionKey = config.encryptionKey;
973
1026
  }
974
1027
  _client = createClient(opts);
1028
+ _resilientClient = wrapWithRetry(_client);
975
1029
  }
976
1030
  function isInitialized() {
977
1031
  return _client !== null;
978
1032
  }
979
1033
  function getClient() {
1034
+ if (!_resilientClient) {
1035
+ throw new Error("Database client not initialized. Call initDatabase() first.");
1036
+ }
1037
+ return _resilientClient;
1038
+ }
1039
+ function getRawClient() {
980
1040
  if (!_client) {
981
1041
  throw new Error("Database client not initialized. Call initDatabase() first.");
982
1042
  }
983
1043
  return _client;
984
1044
  }
985
1045
  async function ensureSchema() {
986
- const client = getClient();
1046
+ const client = getRawClient();
987
1047
  await client.execute("PRAGMA journal_mode = WAL");
988
- await client.execute("PRAGMA busy_timeout = 5000");
1048
+ await client.execute("PRAGMA busy_timeout = 30000");
989
1049
  try {
990
1050
  await client.execute("PRAGMA libsql_vector_search_ef = 128");
991
1051
  } catch {
@@ -2045,20 +2105,20 @@ function vectorToBlob(vector) {
2045
2105
  }
2046
2106
 
2047
2107
  // src/lib/plan-limits.ts
2048
- import { readFileSync as readFileSync3, existsSync as existsSync6 } from "fs";
2108
+ import { readFileSync as readFileSync4, existsSync as existsSync6 } from "fs";
2049
2109
  import path7 from "path";
2050
2110
 
2051
2111
  // src/lib/employees.ts
2052
2112
  init_config();
2053
2113
  import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
2054
- import { existsSync as existsSync4, symlinkSync, readlinkSync } from "fs";
2114
+ import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync2 } from "fs";
2055
2115
  import { execSync as execSync2 } from "child_process";
2056
2116
  import path5 from "path";
2057
2117
  var EMPLOYEES_PATH = path5.join(EXE_AI_DIR, "exe-employees.json");
2058
2118
 
2059
2119
  // src/lib/license.ts
2060
2120
  init_config();
2061
- import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
2121
+ import { readFileSync as readFileSync3, writeFileSync, existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
2062
2122
  import { randomUUID } from "crypto";
2063
2123
  import path6 from "path";
2064
2124
  import { jwtVerify, importSPKI } from "jose";
@@ -2091,14 +2151,14 @@ function loadDeviceId() {
2091
2151
  const deviceJsonPath = path6.join(EXE_AI_DIR, "device.json");
2092
2152
  try {
2093
2153
  if (existsSync5(deviceJsonPath)) {
2094
- const data = JSON.parse(readFileSync2(deviceJsonPath, "utf8"));
2154
+ const data = JSON.parse(readFileSync3(deviceJsonPath, "utf8"));
2095
2155
  if (data.deviceId) return data.deviceId;
2096
2156
  }
2097
2157
  } catch {
2098
2158
  }
2099
2159
  try {
2100
2160
  if (existsSync5(DEVICE_ID_PATH)) {
2101
- const id2 = readFileSync2(DEVICE_ID_PATH, "utf8").trim();
2161
+ const id2 = readFileSync3(DEVICE_ID_PATH, "utf8").trim();
2102
2162
  if (id2) return id2;
2103
2163
  }
2104
2164
  } catch {
@@ -2111,7 +2171,7 @@ function loadDeviceId() {
2111
2171
  function loadLicense() {
2112
2172
  try {
2113
2173
  if (!existsSync5(LICENSE_PATH)) return null;
2114
- return readFileSync2(LICENSE_PATH, "utf8").trim();
2174
+ return readFileSync3(LICENSE_PATH, "utf8").trim();
2115
2175
  } catch {
2116
2176
  return null;
2117
2177
  }
@@ -2141,7 +2201,7 @@ async function verifyLicenseJwt(token) {
2141
2201
  async function getCachedLicense() {
2142
2202
  try {
2143
2203
  if (!existsSync5(CACHE_PATH)) return null;
2144
- const raw = JSON.parse(readFileSync2(CACHE_PATH, "utf8"));
2204
+ const raw = JSON.parse(readFileSync3(CACHE_PATH, "utf8"));
2145
2205
  if (!raw.token || typeof raw.token !== "string") return null;
2146
2206
  return await verifyLicenseJwt(raw.token);
2147
2207
  } catch {
@@ -277,12 +277,68 @@ var init_memory = __esm({
277
277
  }
278
278
  });
279
279
 
280
+ // src/lib/db-retry.ts
281
+ function isBusyError(err) {
282
+ if (err instanceof Error) {
283
+ const msg = err.message.toLowerCase();
284
+ return msg.includes("sqlite_busy") || msg.includes("database is locked");
285
+ }
286
+ return false;
287
+ }
288
+ function delay(ms) {
289
+ return new Promise((resolve) => setTimeout(resolve, ms));
290
+ }
291
+ async function retryOnBusy(fn, label) {
292
+ let lastError;
293
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
294
+ try {
295
+ return await fn();
296
+ } catch (err) {
297
+ lastError = err;
298
+ if (!isBusyError(err) || attempt === MAX_RETRIES) {
299
+ throw err;
300
+ }
301
+ const backoff = BASE_DELAY_MS * Math.pow(2, attempt);
302
+ const jitter = Math.floor(Math.random() * MAX_JITTER_MS);
303
+ process.stderr.write(
304
+ `[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${MAX_RETRIES} \u2014 waiting ${backoff + jitter}ms
305
+ `
306
+ );
307
+ await delay(backoff + jitter);
308
+ }
309
+ }
310
+ throw lastError;
311
+ }
312
+ function wrapWithRetry(client) {
313
+ return new Proxy(client, {
314
+ get(target, prop, receiver) {
315
+ if (prop === "execute") {
316
+ return (sql) => retryOnBusy(() => target.execute(sql), "execute");
317
+ }
318
+ if (prop === "batch") {
319
+ return (stmts) => retryOnBusy(() => target.batch(stmts), "batch");
320
+ }
321
+ return Reflect.get(target, prop, receiver);
322
+ }
323
+ });
324
+ }
325
+ var MAX_RETRIES, BASE_DELAY_MS, MAX_JITTER_MS;
326
+ var init_db_retry = __esm({
327
+ "src/lib/db-retry.ts"() {
328
+ "use strict";
329
+ MAX_RETRIES = 3;
330
+ BASE_DELAY_MS = 200;
331
+ MAX_JITTER_MS = 300;
332
+ }
333
+ });
334
+
280
335
  // src/lib/database.ts
281
336
  import { createClient } from "@libsql/client";
282
337
  async function initDatabase(config) {
283
338
  if (_client) {
284
339
  _client.close();
285
340
  _client = null;
341
+ _resilientClient = null;
286
342
  }
287
343
  const opts = {
288
344
  url: `file:${config.dbPath}`
@@ -291,17 +347,24 @@ async function initDatabase(config) {
291
347
  opts.encryptionKey = config.encryptionKey;
292
348
  }
293
349
  _client = createClient(opts);
350
+ _resilientClient = wrapWithRetry(_client);
294
351
  }
295
352
  function getClient() {
353
+ if (!_resilientClient) {
354
+ throw new Error("Database client not initialized. Call initDatabase() first.");
355
+ }
356
+ return _resilientClient;
357
+ }
358
+ function getRawClient() {
296
359
  if (!_client) {
297
360
  throw new Error("Database client not initialized. Call initDatabase() first.");
298
361
  }
299
362
  return _client;
300
363
  }
301
364
  async function ensureSchema() {
302
- const client = getClient();
365
+ const client = getRawClient();
303
366
  await client.execute("PRAGMA journal_mode = WAL");
304
- await client.execute("PRAGMA busy_timeout = 5000");
367
+ await client.execute("PRAGMA busy_timeout = 30000");
305
368
  try {
306
369
  await client.execute("PRAGMA libsql_vector_search_ef = 128");
307
370
  } catch {
@@ -1094,13 +1157,16 @@ async function disposeDatabase() {
1094
1157
  if (_client) {
1095
1158
  _client.close();
1096
1159
  _client = null;
1160
+ _resilientClient = null;
1097
1161
  }
1098
1162
  }
1099
- var _client, initTurso, disposeTurso;
1163
+ var _client, _resilientClient, initTurso, disposeTurso;
1100
1164
  var init_database = __esm({
1101
1165
  "src/lib/database.ts"() {
1102
1166
  "use strict";
1167
+ init_db_retry();
1103
1168
  _client = null;
1169
+ _resilientClient = null;
1104
1170
  initTurso = initDatabase;
1105
1171
  disposeTurso = disposeDatabase;
1106
1172
  }
@@ -1213,7 +1279,7 @@ function listShards() {
1213
1279
  }
1214
1280
  async function ensureShardSchema(client) {
1215
1281
  await client.execute("PRAGMA journal_mode = WAL");
1216
- await client.execute("PRAGMA busy_timeout = 5000");
1282
+ await client.execute("PRAGMA busy_timeout = 30000");
1217
1283
  try {
1218
1284
  await client.execute("PRAGMA libsql_vector_search_ef = 128");
1219
1285
  } catch {
@@ -2098,11 +2164,11 @@ async function connectEmbedDaemon() {
2098
2164
  }
2099
2165
  }
2100
2166
  const start = Date.now();
2101
- let delay = 100;
2167
+ let delay2 = 100;
2102
2168
  while (Date.now() - start < CONNECT_TIMEOUT_MS) {
2103
- await new Promise((r) => setTimeout(r, delay));
2169
+ await new Promise((r) => setTimeout(r, delay2));
2104
2170
  if (await connectToSocket()) return true;
2105
- delay = Math.min(delay * 2, 3e3);
2171
+ delay2 = Math.min(delay2 * 2, 3e3);
2106
2172
  }
2107
2173
  return false;
2108
2174
  }
@@ -2194,11 +2260,11 @@ async function embedViaClient(text, priority = "high") {
2194
2260
  `);
2195
2261
  killAndRespawnDaemon();
2196
2262
  const start = Date.now();
2197
- let delay = 200;
2263
+ let delay2 = 200;
2198
2264
  while (Date.now() - start < CONNECT_TIMEOUT_MS) {
2199
- await new Promise((r) => setTimeout(r, delay));
2265
+ await new Promise((r) => setTimeout(r, delay2));
2200
2266
  if (await connectToSocket()) break;
2201
- delay = Math.min(delay * 2, 3e3);
2267
+ delay2 = Math.min(delay2 * 2, 3e3);
2202
2268
  }
2203
2269
  if (!_connected) return null;
2204
2270
  }
@@ -2210,11 +2276,11 @@ async function embedViaClient(text, priority = "high") {
2210
2276
  `);
2211
2277
  killAndRespawnDaemon();
2212
2278
  const start = Date.now();
2213
- let delay = 200;
2279
+ let delay2 = 200;
2214
2280
  while (Date.now() - start < CONNECT_TIMEOUT_MS) {
2215
- await new Promise((r) => setTimeout(r, delay));
2281
+ await new Promise((r) => setTimeout(r, delay2));
2216
2282
  if (await connectToSocket()) break;
2217
- delay = Math.min(delay * 2, 3e3);
2283
+ delay2 = Math.min(delay2 * 2, 3e3);
2218
2284
  }
2219
2285
  if (!_connected) return null;
2220
2286
  const retry = await sendRequest([text], priority);
@@ -3035,8 +3101,8 @@ function drainQueue(isSessionBusy, sendKeys) {
3035
3101
  } catch {
3036
3102
  }
3037
3103
  item.attempts++;
3038
- if (item.attempts >= MAX_RETRIES) {
3039
- logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES} retries exhausted, reason: ${item.reason})`);
3104
+ if (item.attempts >= MAX_RETRIES2) {
3105
+ logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES2} retries exhausted, reason: ${item.reason})`);
3040
3106
  failed++;
3041
3107
  continue;
3042
3108
  }
@@ -3069,12 +3135,12 @@ function logQueue(msg) {
3069
3135
  } catch {
3070
3136
  }
3071
3137
  }
3072
- var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
3138
+ var QUEUE_PATH, MAX_RETRIES2, TTL_MS, INTERCOM_LOG;
3073
3139
  var init_intercom_queue = __esm({
3074
3140
  "src/lib/intercom-queue.ts"() {
3075
3141
  "use strict";
3076
3142
  QUEUE_PATH = path10.join(os3.homedir(), ".exe-os", "intercom-queue.json");
3077
- MAX_RETRIES = 5;
3143
+ MAX_RETRIES2 = 5;
3078
3144
  TTL_MS = 60 * 60 * 1e3;
3079
3145
  INTERCOM_LOG = path10.join(os3.homedir(), ".exe-os", "intercom.log");
3080
3146
  }
@@ -3082,7 +3148,7 @@ var init_intercom_queue = __esm({
3082
3148
 
3083
3149
  // src/lib/employees.ts
3084
3150
  import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
3085
- import { existsSync as existsSync9, symlinkSync, readlinkSync } from "fs";
3151
+ import { existsSync as existsSync9, symlinkSync, readlinkSync, readFileSync as readFileSync7 } from "fs";
3086
3152
  import { execSync as execSync6 } from "child_process";
3087
3153
  import path11 from "path";
3088
3154
  async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
@@ -3109,7 +3175,7 @@ var init_employees = __esm({
3109
3175
  });
3110
3176
 
3111
3177
  // src/lib/license.ts
3112
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, existsSync as existsSync10, mkdirSync as mkdirSync5 } from "fs";
3178
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync4, existsSync as existsSync10, mkdirSync as mkdirSync5 } from "fs";
3113
3179
  import { randomUUID as randomUUID2 } from "crypto";
3114
3180
  import path12 from "path";
3115
3181
  import { jwtVerify, importSPKI } from "jose";
@@ -3132,12 +3198,12 @@ var init_license = __esm({
3132
3198
  });
3133
3199
 
3134
3200
  // src/lib/plan-limits.ts
3135
- import { readFileSync as readFileSync8, existsSync as existsSync11 } from "fs";
3201
+ import { readFileSync as readFileSync9, existsSync as existsSync11 } from "fs";
3136
3202
  import path13 from "path";
3137
3203
  function getLicenseSync() {
3138
3204
  try {
3139
3205
  if (!existsSync11(CACHE_PATH2)) return freeLicense();
3140
- const raw = JSON.parse(readFileSync8(CACHE_PATH2, "utf8"));
3206
+ const raw = JSON.parse(readFileSync9(CACHE_PATH2, "utf8"));
3141
3207
  if (!raw.token || typeof raw.token !== "string") return freeLicense();
3142
3208
  const parts = raw.token.split(".");
3143
3209
  if (parts.length !== 3) return freeLicense();
@@ -3176,7 +3242,7 @@ function assertEmployeeLimitSync(rosterPath) {
3176
3242
  let count = 0;
3177
3243
  try {
3178
3244
  if (existsSync11(filePath)) {
3179
- const raw = readFileSync8(filePath, "utf8");
3245
+ const raw = readFileSync9(filePath, "utf8");
3180
3246
  const employees = JSON.parse(raw);
3181
3247
  count = Array.isArray(employees) ? employees.length : 0;
3182
3248
  }
@@ -3211,7 +3277,7 @@ var init_plan_limits = __esm({
3211
3277
 
3212
3278
  // src/lib/tmux-routing.ts
3213
3279
  import { execFileSync as execFileSync2, execSync as execSync7 } from "child_process";
3214
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, existsSync as existsSync12, appendFileSync } from "fs";
3280
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, existsSync as existsSync12, appendFileSync } from "fs";
3215
3281
  import path14 from "path";
3216
3282
  import os4 from "os";
3217
3283
  import { fileURLToPath as fileURLToPath2 } from "url";
@@ -3260,7 +3326,7 @@ function extractRootExe(name) {
3260
3326
  }
3261
3327
  function getParentExe(sessionKey) {
3262
3328
  try {
3263
- const data = JSON.parse(readFileSync9(path14.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
3329
+ const data = JSON.parse(readFileSync10(path14.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
3264
3330
  return data.parentExe || null;
3265
3331
  } catch {
3266
3332
  return null;
@@ -3294,7 +3360,7 @@ function findFreeInstance(employeeName, exeSession, maxInstances = 10, isAlive =
3294
3360
  function readDebounceState() {
3295
3361
  try {
3296
3362
  if (!existsSync12(DEBOUNCE_FILE)) return {};
3297
- return JSON.parse(readFileSync9(DEBOUNCE_FILE, "utf8"));
3363
+ return JSON.parse(readFileSync10(DEBOUNCE_FILE, "utf8"));
3298
3364
  } catch {
3299
3365
  return {};
3300
3366
  }
@@ -3468,7 +3534,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3468
3534
  const claudeJsonPath = path14.join(os4.homedir(), ".claude.json");
3469
3535
  let claudeJson = {};
3470
3536
  try {
3471
- claudeJson = JSON.parse(readFileSync9(claudeJsonPath, "utf8"));
3537
+ claudeJson = JSON.parse(readFileSync10(claudeJsonPath, "utf8"));
3472
3538
  } catch {
3473
3539
  }
3474
3540
  if (!claudeJson.projects) claudeJson.projects = {};
@@ -3486,7 +3552,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3486
3552
  const settingsPath = path14.join(projSettingsDir, "settings.json");
3487
3553
  let settings = {};
3488
3554
  try {
3489
- settings = JSON.parse(readFileSync9(settingsPath, "utf8"));
3555
+ settings = JSON.parse(readFileSync10(settingsPath, "utf8"));
3490
3556
  } catch {
3491
3557
  }
3492
3558
  const perms = settings.permissions ?? {};
@@ -3813,7 +3879,7 @@ async function deliverLocalMessage(messageId) {
3813
3879
  return true;
3814
3880
  } catch {
3815
3881
  const newRetryCount = msg.retryCount + 1;
3816
- if (newRetryCount >= MAX_RETRIES2) {
3882
+ if (newRetryCount >= MAX_RETRIES3) {
3817
3883
  await markFailed(messageId, "session unavailable after 10 retries");
3818
3884
  } else {
3819
3885
  await client.execute({
@@ -3902,7 +3968,7 @@ async function retryPendingMessages() {
3902
3968
  sql: `SELECT * FROM messages
3903
3969
  WHERE status = 'pending' AND retry_count < ?
3904
3970
  ORDER BY id`,
3905
- args: [MAX_RETRIES2]
3971
+ args: [MAX_RETRIES3]
3906
3972
  });
3907
3973
  let delivered = 0;
3908
3974
  for (const row of result.rows) {
@@ -3915,13 +3981,13 @@ async function retryPendingMessages() {
3915
3981
  }
3916
3982
  return delivered;
3917
3983
  }
3918
- var MAX_RETRIES2, _wsClientSend;
3984
+ var MAX_RETRIES3, _wsClientSend;
3919
3985
  var init_messaging = __esm({
3920
3986
  "src/lib/messaging.ts"() {
3921
3987
  "use strict";
3922
3988
  init_database();
3923
3989
  init_tmux_routing();
3924
- MAX_RETRIES2 = 10;
3990
+ MAX_RETRIES3 = 10;
3925
3991
  _wsClientSend = null;
3926
3992
  }
3927
3993
  });
@@ -3931,7 +3997,7 @@ import crypto4 from "crypto";
3931
3997
  import path15 from "path";
3932
3998
  import os5 from "os";
3933
3999
  import {
3934
- readFileSync as readFileSync10,
4000
+ readFileSync as readFileSync11,
3935
4001
  readdirSync as readdirSync3,
3936
4002
  unlinkSync as unlinkSync3,
3937
4003
  existsSync as existsSync13,
@@ -3973,7 +4039,7 @@ import crypto5 from "crypto";
3973
4039
  import path16 from "path";
3974
4040
  import { execSync as execSync8 } from "child_process";
3975
4041
  import { mkdir as mkdir4, writeFile as writeFile4, appendFile } from "fs/promises";
3976
- import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
4042
+ import { existsSync as existsSync14, readFileSync as readFileSync12 } from "fs";
3977
4043
  function extractParentFromContext(contextBody) {
3978
4044
  if (!contextBody) return null;
3979
4045
  const match = contextBody.match(
@@ -4163,7 +4229,7 @@ async function ensureGitignoreExe(baseDir) {
4163
4229
  const gitignorePath = path16.join(baseDir, ".gitignore");
4164
4230
  try {
4165
4231
  if (existsSync14(gitignorePath)) {
4166
- const content = readFileSync11(gitignorePath, "utf-8");
4232
+ const content = readFileSync12(gitignorePath, "utf-8");
4167
4233
  if (/^\/?exe\/?$/m.test(content)) return;
4168
4234
  await appendFile(gitignorePath, "\n# Employee task assignments (private)\n/exe/\n");
4169
4235
  } else {
@@ -4429,7 +4495,7 @@ init_config();
4429
4495
  init_config();
4430
4496
  init_store();
4431
4497
  import { spawn as spawn2 } from "child_process";
4432
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, existsSync as existsSync16, openSync as openSync2, closeSync as closeSync2 } from "fs";
4498
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, existsSync as existsSync16, openSync as openSync2, closeSync as closeSync2 } from "fs";
4433
4499
  import path18 from "path";
4434
4500
  import { fileURLToPath as fileURLToPath3 } from "url";
4435
4501
 
@@ -4872,7 +4938,7 @@ function openWorkerLog() {
4872
4938
  var CACHE_DIR2 = path18.join(EXE_AI_DIR, "session-cache");
4873
4939
  function loadInjectedIds(sessionId) {
4874
4940
  try {
4875
- const raw = readFileSync12(path18.join(CACHE_DIR2, `${sessionId}.json`), "utf8");
4941
+ const raw = readFileSync13(path18.join(CACHE_DIR2, `${sessionId}.json`), "utf8");
4876
4942
  return new Set(JSON.parse(raw));
4877
4943
  } catch {
4878
4944
  return /* @__PURE__ */ new Set();
@@ -4967,7 +5033,7 @@ ${fresh.map(
4967
5033
  const lastCheckPath = path18.join(CACHE_DIR2, `review-lastcheck-${sessionKey}.json`);
4968
5034
  let lastCheckedAt = "";
4969
5035
  try {
4970
- lastCheckedAt = readFileSync12(lastCheckPath, "utf8").trim();
5036
+ lastCheckedAt = readFileSync13(lastCheckPath, "utf8").trim();
4971
5037
  } catch {
4972
5038
  }
4973
5039
  const totalCount = await countPendingReviews2();