@askexenow/exe-os 0.9.7 → 0.9.8

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 (95) hide show
  1. package/dist/bin/backfill-conversations.js +754 -79
  2. package/dist/bin/backfill-responses.js +752 -77
  3. package/dist/bin/backfill-vectors.js +752 -77
  4. package/dist/bin/cleanup-stale-review-tasks.js +657 -35
  5. package/dist/bin/cli.js +1388 -605
  6. package/dist/bin/exe-agent-config.js +123 -95
  7. package/dist/bin/exe-agent.js +41 -25
  8. package/dist/bin/exe-assign.js +732 -57
  9. package/dist/bin/exe-boot.js +784 -153
  10. package/dist/bin/exe-call.js +209 -138
  11. package/dist/bin/exe-cloud.js +35 -12
  12. package/dist/bin/exe-dispatch.js +692 -70
  13. package/dist/bin/exe-doctor.js +648 -26
  14. package/dist/bin/exe-export-behaviors.js +650 -20
  15. package/dist/bin/exe-forget.js +635 -13
  16. package/dist/bin/exe-gateway.js +1053 -271
  17. package/dist/bin/exe-heartbeat.js +665 -43
  18. package/dist/bin/exe-kill.js +646 -16
  19. package/dist/bin/exe-launch-agent.js +887 -97
  20. package/dist/bin/exe-link.js +658 -43
  21. package/dist/bin/exe-new-employee.js +378 -177
  22. package/dist/bin/exe-pending-messages.js +656 -34
  23. package/dist/bin/exe-pending-notifications.js +635 -13
  24. package/dist/bin/exe-pending-reviews.js +659 -37
  25. package/dist/bin/exe-rename.js +645 -30
  26. package/dist/bin/exe-review.js +635 -13
  27. package/dist/bin/exe-search.js +771 -88
  28. package/dist/bin/exe-session-cleanup.js +834 -150
  29. package/dist/bin/exe-settings.js +127 -91
  30. package/dist/bin/exe-start-codex.js +729 -94
  31. package/dist/bin/exe-start-opencode.js +717 -82
  32. package/dist/bin/exe-status.js +657 -35
  33. package/dist/bin/exe-team.js +635 -13
  34. package/dist/bin/git-sweep.js +720 -89
  35. package/dist/bin/graph-backfill.js +643 -13
  36. package/dist/bin/graph-export.js +646 -16
  37. package/dist/bin/install.js +596 -193
  38. package/dist/bin/scan-tasks.js +724 -93
  39. package/dist/bin/setup.js +1038 -210
  40. package/dist/bin/shard-migrate.js +645 -15
  41. package/dist/bin/wiki-sync.js +646 -16
  42. package/dist/gateway/index.js +1027 -245
  43. package/dist/hooks/bug-report-worker.js +891 -170
  44. package/dist/hooks/commit-complete.js +718 -87
  45. package/dist/hooks/error-recall.js +776 -93
  46. package/dist/hooks/exe-heartbeat-hook.js +85 -71
  47. package/dist/hooks/ingest-worker.js +840 -156
  48. package/dist/hooks/ingest.js +90 -73
  49. package/dist/hooks/instructions-loaded.js +669 -38
  50. package/dist/hooks/notification.js +661 -30
  51. package/dist/hooks/post-compact.js +674 -43
  52. package/dist/hooks/pre-compact.js +718 -87
  53. package/dist/hooks/pre-tool-use.js +872 -125
  54. package/dist/hooks/prompt-ingest-worker.js +758 -83
  55. package/dist/hooks/prompt-submit.js +1060 -319
  56. package/dist/hooks/response-ingest-worker.js +758 -83
  57. package/dist/hooks/session-end.js +721 -90
  58. package/dist/hooks/session-start.js +1031 -207
  59. package/dist/hooks/stop.js +680 -49
  60. package/dist/hooks/subagent-stop.js +674 -43
  61. package/dist/hooks/summary-worker.js +816 -132
  62. package/dist/index.js +1015 -232
  63. package/dist/lib/cloud-sync.js +663 -48
  64. package/dist/lib/consolidation.js +26 -3
  65. package/dist/lib/database.js +626 -18
  66. package/dist/lib/db.js +2261 -0
  67. package/dist/lib/device-registry.js +640 -25
  68. package/dist/lib/embedder.js +96 -43
  69. package/dist/lib/employee-templates.js +16 -0
  70. package/dist/lib/employees.js +259 -83
  71. package/dist/lib/exe-daemon-client.js +101 -63
  72. package/dist/lib/exe-daemon.js +894 -162
  73. package/dist/lib/hybrid-search.js +771 -88
  74. package/dist/lib/identity.js +27 -7
  75. package/dist/lib/messaging.js +55 -28
  76. package/dist/lib/reminders.js +21 -1
  77. package/dist/lib/schedules.js +636 -14
  78. package/dist/lib/skill-learning.js +21 -1
  79. package/dist/lib/store.js +643 -13
  80. package/dist/lib/task-router.js +82 -71
  81. package/dist/lib/tasks.js +98 -71
  82. package/dist/lib/tmux-routing.js +87 -60
  83. package/dist/lib/token-spend.js +26 -6
  84. package/dist/mcp/server.js +1784 -458
  85. package/dist/mcp/tools/complete-reminder.js +21 -1
  86. package/dist/mcp/tools/create-reminder.js +21 -1
  87. package/dist/mcp/tools/create-task.js +290 -164
  88. package/dist/mcp/tools/deactivate-behavior.js +24 -4
  89. package/dist/mcp/tools/list-reminders.js +21 -1
  90. package/dist/mcp/tools/list-tasks.js +195 -38
  91. package/dist/mcp/tools/send-message.js +58 -31
  92. package/dist/mcp/tools/update-task.js +75 -48
  93. package/dist/runtime/index.js +720 -89
  94. package/dist/tui/App.js +853 -123
  95. package/package.json +3 -2
@@ -154,7 +154,7 @@ function baseAgentName(name, employees) {
154
154
  if (getEmployee(roster, base)) return base;
155
155
  return name;
156
156
  }
157
- var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE;
157
+ var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE, IDENTITY_DIR;
158
158
  var init_employees = __esm({
159
159
  "src/lib/employees.ts"() {
160
160
  "use strict";
@@ -162,15 +162,40 @@ var init_employees = __esm({
162
162
  EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
163
163
  DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
164
164
  COORDINATOR_ROLE = "COO";
165
+ IDENTITY_DIR = path2.join(EXE_AI_DIR, "identity");
166
+ }
167
+ });
168
+
169
+ // src/lib/database-adapter.ts
170
+ import os3 from "os";
171
+ import path3 from "path";
172
+ import { createRequire } from "module";
173
+ import { pathToFileURL } from "url";
174
+ var BOOLEAN_COLUMNS_BY_TABLE, BOOLEAN_COLUMN_NAMES;
175
+ var init_database_adapter = __esm({
176
+ "src/lib/database-adapter.ts"() {
177
+ "use strict";
178
+ BOOLEAN_COLUMNS_BY_TABLE = {
179
+ memories: /* @__PURE__ */ new Set(["has_error", "draft"]),
180
+ behaviors: /* @__PURE__ */ new Set(["active"]),
181
+ notifications: /* @__PURE__ */ new Set(["read"]),
182
+ users: /* @__PURE__ */ new Set(["has_personal_memory"])
183
+ };
184
+ BOOLEAN_COLUMN_NAMES = new Set(
185
+ Object.values(BOOLEAN_COLUMNS_BY_TABLE).flatMap((cols) => [...cols])
186
+ );
165
187
  }
166
188
  });
167
189
 
168
190
  // src/lib/database.ts
169
191
  import { createClient } from "@libsql/client";
170
192
  function getClient() {
171
- if (!_resilientClient) {
193
+ if (!_adapterClient) {
172
194
  throw new Error("Database client not initialized. Call initDatabase() first.");
173
195
  }
196
+ if (process.env.DATABASE_URL) {
197
+ return _adapterClient;
198
+ }
174
199
  if (process.env.EXE_IS_DAEMON === "1") {
175
200
  return _resilientClient;
176
201
  }
@@ -179,25 +204,27 @@ function getClient() {
179
204
  }
180
205
  return _resilientClient;
181
206
  }
182
- var _resilientClient, _daemonClient;
207
+ var _resilientClient, _daemonClient, _adapterClient;
183
208
  var init_database = __esm({
184
209
  "src/lib/database.ts"() {
185
210
  "use strict";
186
211
  init_db_retry();
187
212
  init_employees();
213
+ init_database_adapter();
188
214
  _resilientClient = null;
189
215
  _daemonClient = null;
216
+ _adapterClient = null;
190
217
  }
191
218
  });
192
219
 
193
220
  // src/lib/session-registry.ts
194
- import path3 from "path";
195
- import os3 from "os";
221
+ import path4 from "path";
222
+ import os4 from "os";
196
223
  var REGISTRY_PATH;
197
224
  var init_session_registry = __esm({
198
225
  "src/lib/session-registry.ts"() {
199
226
  "use strict";
200
- REGISTRY_PATH = path3.join(os3.homedir(), ".exe-os", "session-registry.json");
227
+ REGISTRY_PATH = path4.join(os4.homedir(), ".exe-os", "session-registry.json");
201
228
  }
202
229
  });
203
230
 
@@ -434,7 +461,7 @@ var init_runtime_table = __esm({
434
461
 
435
462
  // src/lib/agent-config.ts
436
463
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync } from "fs";
437
- import path4 from "path";
464
+ import path5 from "path";
438
465
  function loadAgentConfig() {
439
466
  if (!existsSync3(AGENT_CONFIG_PATH)) return {};
440
467
  try {
@@ -457,7 +484,7 @@ var init_agent_config = __esm({
457
484
  "use strict";
458
485
  init_config();
459
486
  init_runtime_table();
460
- AGENT_CONFIG_PATH = path4.join(EXE_AI_DIR, "agent-config.json");
487
+ AGENT_CONFIG_PATH = path5.join(EXE_AI_DIR, "agent-config.json");
461
488
  DEFAULT_MODELS = {
462
489
  claude: "claude-opus-4",
463
490
  codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
@@ -468,10 +495,10 @@ var init_agent_config = __esm({
468
495
 
469
496
  // src/lib/intercom-queue.ts
470
497
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, renameSync as renameSync3, existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
471
- import path5 from "path";
472
- import os4 from "os";
498
+ import path6 from "path";
499
+ import os5 from "os";
473
500
  function ensureDir() {
474
- const dir = path5.dirname(QUEUE_PATH);
501
+ const dir = path6.dirname(QUEUE_PATH);
475
502
  if (!existsSync4(dir)) mkdirSync2(dir, { recursive: true });
476
503
  }
477
504
  function readQueue() {
@@ -509,31 +536,31 @@ var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
509
536
  var init_intercom_queue = __esm({
510
537
  "src/lib/intercom-queue.ts"() {
511
538
  "use strict";
512
- QUEUE_PATH = path5.join(os4.homedir(), ".exe-os", "intercom-queue.json");
539
+ QUEUE_PATH = path6.join(os5.homedir(), ".exe-os", "intercom-queue.json");
513
540
  TTL_MS = 60 * 60 * 1e3;
514
- INTERCOM_LOG = path5.join(os4.homedir(), ".exe-os", "intercom.log");
541
+ INTERCOM_LOG = path6.join(os5.homedir(), ".exe-os", "intercom.log");
515
542
  }
516
543
  });
517
544
 
518
545
  // src/lib/license.ts
519
546
  import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
520
547
  import { randomUUID } from "crypto";
521
- import path6 from "path";
548
+ import path7 from "path";
522
549
  import { jwtVerify, importSPKI } from "jose";
523
550
  var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
524
551
  var init_license = __esm({
525
552
  "src/lib/license.ts"() {
526
553
  "use strict";
527
554
  init_config();
528
- LICENSE_PATH = path6.join(EXE_AI_DIR, "license.key");
529
- CACHE_PATH = path6.join(EXE_AI_DIR, "license-cache.json");
530
- DEVICE_ID_PATH = path6.join(EXE_AI_DIR, "device-id");
555
+ LICENSE_PATH = path7.join(EXE_AI_DIR, "license.key");
556
+ CACHE_PATH = path7.join(EXE_AI_DIR, "license-cache.json");
557
+ DEVICE_ID_PATH = path7.join(EXE_AI_DIR, "device-id");
531
558
  }
532
559
  });
533
560
 
534
561
  // src/lib/plan-limits.ts
535
562
  import { readFileSync as readFileSync6, existsSync as existsSync6 } from "fs";
536
- import path7 from "path";
563
+ import path8 from "path";
537
564
  var CACHE_PATH2;
538
565
  var init_plan_limits = __esm({
539
566
  "src/lib/plan-limits.ts"() {
@@ -542,15 +569,15 @@ var init_plan_limits = __esm({
542
569
  init_employees();
543
570
  init_license();
544
571
  init_config();
545
- CACHE_PATH2 = path7.join(EXE_AI_DIR, "license-cache.json");
572
+ CACHE_PATH2 = path8.join(EXE_AI_DIR, "license-cache.json");
546
573
  }
547
574
  });
548
575
 
549
576
  // src/lib/tmux-routing.ts
550
577
  import { execFileSync as execFileSync2, execSync as execSync4 } from "child_process";
551
578
  import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync7, appendFileSync, readdirSync } from "fs";
552
- import path8 from "path";
553
- import os5 from "os";
579
+ import path9 from "path";
580
+ import os6 from "os";
554
581
  import { fileURLToPath } from "url";
555
582
  function getMySession() {
556
583
  return getTransport().getMySession();
@@ -590,7 +617,7 @@ function extractRootExe(name) {
590
617
  }
591
618
  function getParentExe(sessionKey) {
592
619
  try {
593
- const data = JSON.parse(readFileSync7(path8.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
620
+ const data = JSON.parse(readFileSync7(path9.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
594
621
  return data.parentExe || null;
595
622
  } catch {
596
623
  return null;
@@ -735,7 +762,7 @@ function sendIntercom(targetSession) {
735
762
  try {
736
763
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
737
764
  const agent = baseAgentName(rawAgent);
738
- const markerPath = path8.join(SESSION_CACHE, `current-task-${agent}.json`);
765
+ const markerPath = path9.join(SESSION_CACHE, `current-task-${agent}.json`);
739
766
  if (existsSync7(markerPath)) {
740
767
  logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker \u2014 will auto-chain)`);
741
768
  return "debounced";
@@ -745,7 +772,7 @@ function sendIntercom(targetSession) {
745
772
  try {
746
773
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
747
774
  const agent = baseAgentName(rawAgent);
748
- const taskDir = path8.join(process.cwd(), "exe", agent);
775
+ const taskDir = path9.join(process.cwd(), "exe", agent);
749
776
  if (existsSync7(taskDir)) {
750
777
  const files = readdirSync(taskDir).filter(
751
778
  (f) => f.endsWith(".md") && f !== "DONE.txt"
@@ -799,13 +826,13 @@ var init_tmux_routing = __esm({
799
826
  init_intercom_queue();
800
827
  init_plan_limits();
801
828
  init_employees();
802
- SPAWN_LOCK_DIR = path8.join(os5.homedir(), ".exe-os", "spawn-locks");
803
- SESSION_CACHE = path8.join(os5.homedir(), ".exe-os", "session-cache");
829
+ SPAWN_LOCK_DIR = path9.join(os6.homedir(), ".exe-os", "spawn-locks");
830
+ SESSION_CACHE = path9.join(os6.homedir(), ".exe-os", "session-cache");
804
831
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
805
832
  INTERCOM_DEBOUNCE_MS = 3e4;
806
833
  CODEX_DEBOUNCE_MS = 12e4;
807
- INTERCOM_LOG2 = path8.join(os5.homedir(), ".exe-os", "intercom.log");
808
- DEBOUNCE_FILE = path8.join(SESSION_CACHE, "intercom-debounce.json");
834
+ INTERCOM_LOG2 = path9.join(os6.homedir(), ".exe-os", "intercom.log");
835
+ DEBOUNCE_FILE = path9.join(SESSION_CACHE, "intercom-debounce.json");
809
836
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
810
837
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…|• Working|• Ran |• Explored|• Called|esc to interrupt/;
811
838
  }
@@ -962,8 +989,8 @@ init_session_key();
962
989
  init_employees();
963
990
  import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, unlinkSync as unlinkSync2, readdirSync as readdirSync2 } from "fs";
964
991
  import { execSync as execSync5 } from "child_process";
965
- import path9 from "path";
966
- var CACHE_DIR = path9.join(EXE_AI_DIR, "session-cache");
992
+ import path10 from "path";
993
+ var CACHE_DIR = path10.join(EXE_AI_DIR, "session-cache");
967
994
  var STALE_MS = 24 * 60 * 60 * 1e3;
968
995
  function isNameWithOptionalInstance(candidate, baseName) {
969
996
  if (candidate === baseName) return true;
@@ -1008,7 +1035,7 @@ function resolveActiveAgentFromTmuxSession(sessionName) {
1008
1035
  return null;
1009
1036
  }
1010
1037
  function getMarkerPath() {
1011
- return path9.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
1038
+ return path10.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
1012
1039
  }
1013
1040
  function getActiveAgent() {
1014
1041
  try {
@@ -259,7 +259,7 @@ function baseAgentName(name, employees) {
259
259
  if (getEmployee(roster, base)) return base;
260
260
  return name;
261
261
  }
262
- var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE;
262
+ var EMPLOYEES_PATH, DEFAULT_COORDINATOR_TEMPLATE_NAME, COORDINATOR_ROLE, IDENTITY_DIR;
263
263
  var init_employees = __esm({
264
264
  "src/lib/employees.ts"() {
265
265
  "use strict";
@@ -267,15 +267,40 @@ var init_employees = __esm({
267
267
  EMPLOYEES_PATH = path2.join(EXE_AI_DIR, "exe-employees.json");
268
268
  DEFAULT_COORDINATOR_TEMPLATE_NAME = "exe";
269
269
  COORDINATOR_ROLE = "COO";
270
+ IDENTITY_DIR = path2.join(EXE_AI_DIR, "identity");
271
+ }
272
+ });
273
+
274
+ // src/lib/database-adapter.ts
275
+ import os3 from "os";
276
+ import path3 from "path";
277
+ import { createRequire } from "module";
278
+ import { pathToFileURL } from "url";
279
+ var BOOLEAN_COLUMNS_BY_TABLE, BOOLEAN_COLUMN_NAMES;
280
+ var init_database_adapter = __esm({
281
+ "src/lib/database-adapter.ts"() {
282
+ "use strict";
283
+ BOOLEAN_COLUMNS_BY_TABLE = {
284
+ memories: /* @__PURE__ */ new Set(["has_error", "draft"]),
285
+ behaviors: /* @__PURE__ */ new Set(["active"]),
286
+ notifications: /* @__PURE__ */ new Set(["read"]),
287
+ users: /* @__PURE__ */ new Set(["has_personal_memory"])
288
+ };
289
+ BOOLEAN_COLUMN_NAMES = new Set(
290
+ Object.values(BOOLEAN_COLUMNS_BY_TABLE).flatMap((cols) => [...cols])
291
+ );
270
292
  }
271
293
  });
272
294
 
273
295
  // src/lib/database.ts
274
296
  import { createClient } from "@libsql/client";
275
297
  function getClient() {
276
- if (!_resilientClient) {
298
+ if (!_adapterClient) {
277
299
  throw new Error("Database client not initialized. Call initDatabase() first.");
278
300
  }
301
+ if (process.env.DATABASE_URL) {
302
+ return _adapterClient;
303
+ }
279
304
  if (process.env.EXE_IS_DAEMON === "1") {
280
305
  return _resilientClient;
281
306
  }
@@ -284,21 +309,23 @@ function getClient() {
284
309
  }
285
310
  return _resilientClient;
286
311
  }
287
- var _resilientClient, _daemonClient;
312
+ var _resilientClient, _daemonClient, _adapterClient;
288
313
  var init_database = __esm({
289
314
  "src/lib/database.ts"() {
290
315
  "use strict";
291
316
  init_db_retry();
292
317
  init_employees();
318
+ init_database_adapter();
293
319
  _resilientClient = null;
294
320
  _daemonClient = null;
321
+ _adapterClient = null;
295
322
  }
296
323
  });
297
324
 
298
325
  // src/lib/notifications.ts
299
326
  import crypto from "crypto";
300
- import path3 from "path";
301
- import os3 from "os";
327
+ import path4 from "path";
328
+ import os4 from "os";
302
329
  import {
303
330
  readFileSync as readFileSync3,
304
331
  readdirSync,
@@ -403,13 +430,13 @@ var init_state_bus = __esm({
403
430
  });
404
431
 
405
432
  // src/lib/session-registry.ts
406
- import path4 from "path";
407
- import os4 from "os";
433
+ import path5 from "path";
434
+ import os5 from "os";
408
435
  var REGISTRY_PATH;
409
436
  var init_session_registry = __esm({
410
437
  "src/lib/session-registry.ts"() {
411
438
  "use strict";
412
- REGISTRY_PATH = path4.join(os4.homedir(), ".exe-os", "session-registry.json");
439
+ REGISTRY_PATH = path5.join(os5.homedir(), ".exe-os", "session-registry.json");
413
440
  }
414
441
  });
415
442
 
@@ -646,7 +673,7 @@ var init_runtime_table = __esm({
646
673
 
647
674
  // src/lib/agent-config.ts
648
675
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, existsSync as existsSync4, mkdirSync } from "fs";
649
- import path5 from "path";
676
+ import path6 from "path";
650
677
  function loadAgentConfig() {
651
678
  if (!existsSync4(AGENT_CONFIG_PATH)) return {};
652
679
  try {
@@ -669,7 +696,7 @@ var init_agent_config = __esm({
669
696
  "use strict";
670
697
  init_config();
671
698
  init_runtime_table();
672
- AGENT_CONFIG_PATH = path5.join(EXE_AI_DIR, "agent-config.json");
699
+ AGENT_CONFIG_PATH = path6.join(EXE_AI_DIR, "agent-config.json");
673
700
  DEFAULT_MODELS = {
674
701
  claude: "claude-opus-4",
675
702
  codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
@@ -688,10 +715,10 @@ __export(intercom_queue_exports, {
688
715
  readQueue: () => readQueue
689
716
  });
690
717
  import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, renameSync as renameSync3, existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
691
- import path6 from "path";
692
- import os5 from "os";
718
+ import path7 from "path";
719
+ import os6 from "os";
693
720
  function ensureDir() {
694
- const dir = path6.dirname(QUEUE_PATH);
721
+ const dir = path7.dirname(QUEUE_PATH);
695
722
  if (!existsSync5(dir)) mkdirSync2(dir, { recursive: true });
696
723
  }
697
724
  function readQueue() {
@@ -797,32 +824,32 @@ var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
797
824
  var init_intercom_queue = __esm({
798
825
  "src/lib/intercom-queue.ts"() {
799
826
  "use strict";
800
- QUEUE_PATH = path6.join(os5.homedir(), ".exe-os", "intercom-queue.json");
827
+ QUEUE_PATH = path7.join(os6.homedir(), ".exe-os", "intercom-queue.json");
801
828
  MAX_RETRIES = 5;
802
829
  TTL_MS = 60 * 60 * 1e3;
803
- INTERCOM_LOG = path6.join(os5.homedir(), ".exe-os", "intercom.log");
830
+ INTERCOM_LOG = path7.join(os6.homedir(), ".exe-os", "intercom.log");
804
831
  }
805
832
  });
806
833
 
807
834
  // src/lib/license.ts
808
835
  import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
809
836
  import { randomUUID } from "crypto";
810
- import path7 from "path";
837
+ import path8 from "path";
811
838
  import { jwtVerify, importSPKI } from "jose";
812
839
  var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
813
840
  var init_license = __esm({
814
841
  "src/lib/license.ts"() {
815
842
  "use strict";
816
843
  init_config();
817
- LICENSE_PATH = path7.join(EXE_AI_DIR, "license.key");
818
- CACHE_PATH = path7.join(EXE_AI_DIR, "license-cache.json");
819
- DEVICE_ID_PATH = path7.join(EXE_AI_DIR, "device-id");
844
+ LICENSE_PATH = path8.join(EXE_AI_DIR, "license.key");
845
+ CACHE_PATH = path8.join(EXE_AI_DIR, "license-cache.json");
846
+ DEVICE_ID_PATH = path8.join(EXE_AI_DIR, "device-id");
820
847
  }
821
848
  });
822
849
 
823
850
  // src/lib/plan-limits.ts
824
851
  import { readFileSync as readFileSync7, existsSync as existsSync7 } from "fs";
825
- import path8 from "path";
852
+ import path9 from "path";
826
853
  var CACHE_PATH2;
827
854
  var init_plan_limits = __esm({
828
855
  "src/lib/plan-limits.ts"() {
@@ -831,15 +858,15 @@ var init_plan_limits = __esm({
831
858
  init_employees();
832
859
  init_license();
833
860
  init_config();
834
- CACHE_PATH2 = path8.join(EXE_AI_DIR, "license-cache.json");
861
+ CACHE_PATH2 = path9.join(EXE_AI_DIR, "license-cache.json");
835
862
  }
836
863
  });
837
864
 
838
865
  // src/lib/tmux-routing.ts
839
866
  import { execFileSync as execFileSync2, execSync as execSync4 } from "child_process";
840
867
  import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync8, appendFileSync, readdirSync as readdirSync2 } from "fs";
841
- import path9 from "path";
842
- import os6 from "os";
868
+ import path10 from "path";
869
+ import os7 from "os";
843
870
  import { fileURLToPath } from "url";
844
871
  function getMySession() {
845
872
  return getTransport().getMySession();
@@ -852,7 +879,7 @@ function extractRootExe(name) {
852
879
  }
853
880
  function getParentExe(sessionKey) {
854
881
  try {
855
- const data = JSON.parse(readFileSync8(path9.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
882
+ const data = JSON.parse(readFileSync8(path10.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
856
883
  return data.parentExe || null;
857
884
  } catch {
858
885
  return null;
@@ -861,7 +888,7 @@ function getParentExe(sessionKey) {
861
888
  function getDispatchedBy(sessionKey) {
862
889
  try {
863
890
  const data = JSON.parse(readFileSync8(
864
- path9.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
891
+ path10.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
865
892
  "utf8"
866
893
  ));
867
894
  return data.dispatchedBy ?? data.parentExe ?? null;
@@ -1005,7 +1032,7 @@ function sendIntercom(targetSession) {
1005
1032
  try {
1006
1033
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
1007
1034
  const agent = baseAgentName(rawAgent);
1008
- const markerPath = path9.join(SESSION_CACHE, `current-task-${agent}.json`);
1035
+ const markerPath = path10.join(SESSION_CACHE, `current-task-${agent}.json`);
1009
1036
  if (existsSync8(markerPath)) {
1010
1037
  logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker \u2014 will auto-chain)`);
1011
1038
  return "debounced";
@@ -1015,7 +1042,7 @@ function sendIntercom(targetSession) {
1015
1042
  try {
1016
1043
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
1017
1044
  const agent = baseAgentName(rawAgent);
1018
- const taskDir = path9.join(process.cwd(), "exe", agent);
1045
+ const taskDir = path10.join(process.cwd(), "exe", agent);
1019
1046
  if (existsSync8(taskDir)) {
1020
1047
  const files = readdirSync2(taskDir).filter(
1021
1048
  (f) => f.endsWith(".md") && f !== "DONE.txt"
@@ -1091,12 +1118,12 @@ var init_tmux_routing = __esm({
1091
1118
  init_intercom_queue();
1092
1119
  init_plan_limits();
1093
1120
  init_employees();
1094
- SPAWN_LOCK_DIR = path9.join(os6.homedir(), ".exe-os", "spawn-locks");
1095
- SESSION_CACHE = path9.join(os6.homedir(), ".exe-os", "session-cache");
1121
+ SPAWN_LOCK_DIR = path10.join(os7.homedir(), ".exe-os", "spawn-locks");
1122
+ SESSION_CACHE = path10.join(os7.homedir(), ".exe-os", "session-cache");
1096
1123
  INTERCOM_DEBOUNCE_MS = 3e4;
1097
1124
  CODEX_DEBOUNCE_MS = 12e4;
1098
- INTERCOM_LOG2 = path9.join(os6.homedir(), ".exe-os", "intercom.log");
1099
- DEBOUNCE_FILE = path9.join(SESSION_CACHE, "intercom-debounce.json");
1125
+ INTERCOM_LOG2 = path10.join(os7.homedir(), ".exe-os", "intercom.log");
1126
+ DEBOUNCE_FILE = path10.join(SESSION_CACHE, "intercom-debounce.json");
1100
1127
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
1101
1128
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…|• Working|• Ran |• Explored|• Called|esc to interrupt/;
1102
1129
  }
@@ -1128,8 +1155,8 @@ var init_task_scope = __esm({
1128
1155
 
1129
1156
  // src/lib/tasks-crud.ts
1130
1157
  import crypto2 from "crypto";
1131
- import path10 from "path";
1132
- import os7 from "os";
1158
+ import path11 from "path";
1159
+ import os8 from "os";
1133
1160
  import { execSync as execSync5 } from "child_process";
1134
1161
  import { mkdir as mkdir3, writeFile as writeFile3, appendFile } from "fs/promises";
1135
1162
  import { existsSync as existsSync9, readFileSync as readFileSync9 } from "fs";
@@ -1428,7 +1455,7 @@ var init_tasks_crud = __esm({
1428
1455
  });
1429
1456
 
1430
1457
  // src/lib/tasks-review.ts
1431
- import path11 from "path";
1458
+ import path12 from "path";
1432
1459
  import { existsSync as existsSync10, readdirSync as readdirSync3, unlinkSync as unlinkSync3 } from "fs";
1433
1460
  async function cleanupReviewFile(row, taskFile, _baseDir) {
1434
1461
  if (String(row.assigned_by) !== "system" || !taskFile.includes("review-")) return;
@@ -1474,11 +1501,11 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
1474
1501
  );
1475
1502
  }
1476
1503
  try {
1477
- const cacheDir = path11.join(EXE_AI_DIR, "session-cache");
1504
+ const cacheDir = path12.join(EXE_AI_DIR, "session-cache");
1478
1505
  if (existsSync10(cacheDir)) {
1479
1506
  for (const f of readdirSync3(cacheDir)) {
1480
1507
  if (f.startsWith("review-notified-")) {
1481
- unlinkSync3(path11.join(cacheDir, f));
1508
+ unlinkSync3(path12.join(cacheDir, f));
1482
1509
  }
1483
1510
  }
1484
1511
  }
@@ -1499,7 +1526,7 @@ var init_tasks_review = __esm({
1499
1526
  });
1500
1527
 
1501
1528
  // src/lib/tasks-chain.ts
1502
- import path12 from "path";
1529
+ import path13 from "path";
1503
1530
  import { readFile as readFile3, writeFile as writeFile4 } from "fs/promises";
1504
1531
  async function cascadeUnblock(taskId, baseDir, now) {
1505
1532
  const client = getClient();
@@ -1516,7 +1543,7 @@ async function cascadeUnblock(taskId, baseDir, now) {
1516
1543
  });
1517
1544
  for (const ur of unblockedRows.rows) {
1518
1545
  try {
1519
- const ubFile = path12.join(baseDir, String(ur.task_file));
1546
+ const ubFile = path13.join(baseDir, String(ur.task_file));
1520
1547
  let ubContent = await readFile3(ubFile, "utf-8");
1521
1548
  ubContent = ubContent.replace(/\*\*Status:\*\* blocked/, "**Status:** open");
1522
1549
  ubContent = ubContent.replace(/\n\*\*Blocked by:\*\*.*\n/, "\n");
@@ -1919,14 +1946,14 @@ var init_skill_learning = __esm({
1919
1946
  });
1920
1947
 
1921
1948
  // src/lib/tasks.ts
1922
- import path13 from "path";
1949
+ import path14 from "path";
1923
1950
  import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, unlinkSync as unlinkSync4 } from "fs";
1924
1951
  async function updateTask(input) {
1925
1952
  const { row, taskFile, now, taskId } = await updateTaskStatus(input);
1926
1953
  try {
1927
1954
  const agent = String(row.assigned_to);
1928
- const cacheDir = path13.join(EXE_AI_DIR, "session-cache");
1929
- const cachePath = path13.join(cacheDir, `current-task-${agent}.json`);
1955
+ const cacheDir = path14.join(EXE_AI_DIR, "session-cache");
1956
+ const cachePath = path14.join(cacheDir, `current-task-${agent}.json`);
1930
1957
  if (input.status === "in_progress") {
1931
1958
  mkdirSync5(cacheDir, { recursive: true });
1932
1959
  writeFileSync6(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
@@ -2083,7 +2110,7 @@ __export(active_agent_exports, {
2083
2110
  });
2084
2111
  import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, unlinkSync as unlinkSync5, readdirSync as readdirSync4 } from "fs";
2085
2112
  import { execSync as execSync6 } from "child_process";
2086
- import path14 from "path";
2113
+ import path15 from "path";
2087
2114
  function isNameWithOptionalInstance(candidate, baseName) {
2088
2115
  if (candidate === baseName) return true;
2089
2116
  if (!candidate.startsWith(baseName)) return false;
@@ -2127,7 +2154,7 @@ function resolveActiveAgentFromTmuxSession(sessionName) {
2127
2154
  return null;
2128
2155
  }
2129
2156
  function getMarkerPath() {
2130
- return path14.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
2157
+ return path15.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
2131
2158
  }
2132
2159
  function writeActiveAgent(agentId, agentRole) {
2133
2160
  try {
@@ -2196,14 +2223,14 @@ function getAllActiveAgents() {
2196
2223
  const key = file.slice("active-agent-".length, -".json".length);
2197
2224
  if (key === "undefined") continue;
2198
2225
  try {
2199
- const raw = readFileSync10(path14.join(CACHE_DIR, file), "utf8");
2226
+ const raw = readFileSync10(path15.join(CACHE_DIR, file), "utf8");
2200
2227
  const data = JSON.parse(raw);
2201
2228
  if (!data.agentId) continue;
2202
2229
  if (data.startedAt) {
2203
2230
  const age = Date.now() - new Date(data.startedAt).getTime();
2204
2231
  if (age > STALE_MS) {
2205
2232
  try {
2206
- unlinkSync5(path14.join(CACHE_DIR, file));
2233
+ unlinkSync5(path15.join(CACHE_DIR, file));
2207
2234
  } catch {
2208
2235
  }
2209
2236
  continue;
@@ -2226,11 +2253,11 @@ function getAllActiveAgents() {
2226
2253
  function cleanupSessionMarkers() {
2227
2254
  const key = getSessionKey();
2228
2255
  try {
2229
- unlinkSync5(path14.join(CACHE_DIR, `active-agent-${key}.json`));
2256
+ unlinkSync5(path15.join(CACHE_DIR, `active-agent-${key}.json`));
2230
2257
  } catch {
2231
2258
  }
2232
2259
  try {
2233
- unlinkSync5(path14.join(CACHE_DIR, "active-agent-undefined.json"));
2260
+ unlinkSync5(path15.join(CACHE_DIR, "active-agent-undefined.json"));
2234
2261
  } catch {
2235
2262
  }
2236
2263
  }
@@ -2241,7 +2268,7 @@ var init_active_agent = __esm({
2241
2268
  init_config();
2242
2269
  init_session_key();
2243
2270
  init_employees();
2244
- CACHE_DIR = path14.join(EXE_AI_DIR, "session-cache");
2271
+ CACHE_DIR = path15.join(EXE_AI_DIR, "session-cache");
2245
2272
  STALE_MS = 24 * 60 * 60 * 1e3;
2246
2273
  }
2247
2274
  });