@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
@@ -3,9 +3,18 @@ var __esm = (fn, res) => function __init() {
3
3
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
4
4
  };
5
5
 
6
+ // src/lib/secure-files.ts
7
+ import { chmodSync, existsSync, mkdirSync } from "fs";
8
+ import { chmod, mkdir } from "fs/promises";
9
+ var init_secure_files = __esm({
10
+ "src/lib/secure-files.ts"() {
11
+ "use strict";
12
+ }
13
+ });
14
+
6
15
  // src/lib/config.ts
7
- import { readFile, writeFile, mkdir, chmod } from "fs/promises";
8
- import { readFileSync, existsSync, renameSync } from "fs";
16
+ import { readFile, writeFile } from "fs/promises";
17
+ import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
9
18
  import path from "path";
10
19
  import os from "os";
11
20
  function resolveDataDir() {
@@ -13,7 +22,7 @@ function resolveDataDir() {
13
22
  if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
14
23
  const newDir = path.join(os.homedir(), ".exe-os");
15
24
  const legacyDir = path.join(os.homedir(), ".exe-mem");
16
- if (!existsSync(newDir) && existsSync(legacyDir)) {
25
+ if (!existsSync2(newDir) && existsSync2(legacyDir)) {
17
26
  try {
18
27
  renameSync(legacyDir, newDir);
19
28
  process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
@@ -28,6 +37,7 @@ var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CON
28
37
  var init_config = __esm({
29
38
  "src/lib/config.ts"() {
30
39
  "use strict";
40
+ init_secure_files();
31
41
  EXE_AI_DIR = resolveDataDir();
32
42
  DB_PATH = path.join(EXE_AI_DIR, "memories.db");
33
43
  MODELS_DIR = path.join(EXE_AI_DIR, "models");
@@ -106,7 +116,7 @@ import { createClient } from "@libsql/client";
106
116
  // src/lib/employees.ts
107
117
  init_config();
108
118
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
109
- import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
119
+ import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
110
120
  import { execSync } from "child_process";
111
121
  import path2 from "path";
112
122
  import os2 from "os";
@@ -133,7 +143,7 @@ function canCoordinate(agentName, agentRole, employees = loadEmployeesSync()) {
133
143
  return agentName === "default" || isCoordinatorRole(agentRole) || isCoordinatorName(agentName, employees);
134
144
  }
135
145
  function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
136
- if (!existsSync2(employeesPath)) return [];
146
+ if (!existsSync3(employeesPath)) return [];
137
147
  try {
138
148
  return JSON.parse(readFileSync2(employeesPath, "utf-8"));
139
149
  } catch {
@@ -192,7 +202,7 @@ async function deactivateBehavior(id) {
192
202
 
193
203
  // src/lib/active-agent.ts
194
204
  init_config();
195
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync, unlinkSync as unlinkSync2, readdirSync } from "fs";
205
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2, readdirSync } from "fs";
196
206
  import { execSync as execSync3 } from "child_process";
197
207
  import path4 from "path";
198
208
 
@@ -3,9 +3,18 @@ var __esm = (fn, res) => function __init() {
3
3
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
4
4
  };
5
5
 
6
+ // src/lib/secure-files.ts
7
+ import { chmodSync, existsSync, mkdirSync } from "fs";
8
+ import { chmod, mkdir } from "fs/promises";
9
+ var init_secure_files = __esm({
10
+ "src/lib/secure-files.ts"() {
11
+ "use strict";
12
+ }
13
+ });
14
+
6
15
  // src/lib/config.ts
7
- import { readFile, writeFile, mkdir, chmod } from "fs/promises";
8
- import { readFileSync, existsSync, renameSync } from "fs";
16
+ import { readFile, writeFile } from "fs/promises";
17
+ import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
9
18
  import path from "path";
10
19
  import os from "os";
11
20
  function resolveDataDir() {
@@ -13,7 +22,7 @@ function resolveDataDir() {
13
22
  if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
14
23
  const newDir = path.join(os.homedir(), ".exe-os");
15
24
  const legacyDir = path.join(os.homedir(), ".exe-mem");
16
- if (!existsSync(newDir) && existsSync(legacyDir)) {
25
+ if (!existsSync2(newDir) && existsSync2(legacyDir)) {
17
26
  try {
18
27
  renameSync(legacyDir, newDir);
19
28
  process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
@@ -28,6 +37,7 @@ var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CON
28
37
  var init_config = __esm({
29
38
  "src/lib/config.ts"() {
30
39
  "use strict";
40
+ init_secure_files();
31
41
  EXE_AI_DIR = resolveDataDir();
32
42
  DB_PATH = path.join(EXE_AI_DIR, "memories.db");
33
43
  MODELS_DIR = path.join(EXE_AI_DIR, "models");
@@ -106,7 +116,7 @@ import { createClient } from "@libsql/client";
106
116
  // src/lib/employees.ts
107
117
  init_config();
108
118
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
109
- import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
119
+ import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
110
120
  import { execSync } from "child_process";
111
121
  import path2 from "path";
112
122
  import os2 from "os";
@@ -26,9 +26,18 @@ var init_db_retry = __esm({
26
26
  }
27
27
  });
28
28
 
29
+ // src/lib/secure-files.ts
30
+ import { chmodSync, existsSync, mkdirSync } from "fs";
31
+ import { chmod, mkdir } from "fs/promises";
32
+ var init_secure_files = __esm({
33
+ "src/lib/secure-files.ts"() {
34
+ "use strict";
35
+ }
36
+ });
37
+
29
38
  // src/lib/config.ts
30
- import { readFile, writeFile, mkdir, chmod } from "fs/promises";
31
- import { readFileSync, existsSync, renameSync } from "fs";
39
+ import { readFile, writeFile } from "fs/promises";
40
+ import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
32
41
  import path from "path";
33
42
  import os from "os";
34
43
  function resolveDataDir() {
@@ -36,7 +45,7 @@ function resolveDataDir() {
36
45
  if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
37
46
  const newDir = path.join(os.homedir(), ".exe-os");
38
47
  const legacyDir = path.join(os.homedir(), ".exe-mem");
39
- if (!existsSync(newDir) && existsSync(legacyDir)) {
48
+ if (!existsSync2(newDir) && existsSync2(legacyDir)) {
40
49
  try {
41
50
  renameSync(legacyDir, newDir);
42
51
  process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
@@ -51,6 +60,7 @@ var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CON
51
60
  var init_config = __esm({
52
61
  "src/lib/config.ts"() {
53
62
  "use strict";
63
+ init_secure_files();
54
64
  EXE_AI_DIR = resolveDataDir();
55
65
  DB_PATH = path.join(EXE_AI_DIR, "memories.db");
56
66
  MODELS_DIR = path.join(EXE_AI_DIR, "models");
@@ -119,7 +129,7 @@ var init_config = __esm({
119
129
 
120
130
  // src/lib/employees.ts
121
131
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
122
- import { existsSync as existsSync2, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
132
+ import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
123
133
  import { execSync } from "child_process";
124
134
  import path2 from "path";
125
135
  import os2 from "os";
@@ -133,7 +143,7 @@ function getCoordinatorEmployee(employees) {
133
143
  return employees.find((e) => isCoordinatorRole(e.role));
134
144
  }
135
145
  function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
136
- if (!existsSync2(employeesPath)) return [];
146
+ if (!existsSync3(employeesPath)) return [];
137
147
  try {
138
148
  return JSON.parse(readFileSync2(employeesPath, "utf-8"));
139
149
  } catch {
@@ -206,87 +216,14 @@ var init_database = __esm({
206
216
  }
207
217
  });
208
218
 
209
- // src/lib/notifications.ts
210
- import crypto from "crypto";
219
+ // src/lib/session-registry.ts
211
220
  import path4 from "path";
212
221
  import os4 from "os";
213
- import {
214
- readFileSync as readFileSync3,
215
- readdirSync,
216
- unlinkSync as unlinkSync2,
217
- existsSync as existsSync3,
218
- rmdirSync
219
- } from "fs";
220
- var init_notifications = __esm({
221
- "src/lib/notifications.ts"() {
222
- "use strict";
223
- init_database();
224
- }
225
- });
226
-
227
- // src/lib/state-bus.ts
228
- var StateBus, orgBus;
229
- var init_state_bus = __esm({
230
- "src/lib/state-bus.ts"() {
231
- "use strict";
232
- StateBus = class {
233
- handlers = /* @__PURE__ */ new Map();
234
- globalHandlers = /* @__PURE__ */ new Set();
235
- /** Emit an event to all subscribers */
236
- emit(event) {
237
- const typeHandlers = this.handlers.get(event.type);
238
- if (typeHandlers) {
239
- for (const handler of typeHandlers) {
240
- try {
241
- handler(event);
242
- } catch {
243
- }
244
- }
245
- }
246
- for (const handler of this.globalHandlers) {
247
- try {
248
- handler(event);
249
- } catch {
250
- }
251
- }
252
- }
253
- /** Subscribe to a specific event type */
254
- on(type, handler) {
255
- if (!this.handlers.has(type)) {
256
- this.handlers.set(type, /* @__PURE__ */ new Set());
257
- }
258
- this.handlers.get(type).add(handler);
259
- }
260
- /** Subscribe to ALL events */
261
- onAny(handler) {
262
- this.globalHandlers.add(handler);
263
- }
264
- /** Unsubscribe from a specific event type */
265
- off(type, handler) {
266
- this.handlers.get(type)?.delete(handler);
267
- }
268
- /** Unsubscribe from ALL events */
269
- offAny(handler) {
270
- this.globalHandlers.delete(handler);
271
- }
272
- /** Remove all listeners */
273
- clear() {
274
- this.handlers.clear();
275
- this.globalHandlers.clear();
276
- }
277
- };
278
- orgBus = new StateBus();
279
- }
280
- });
281
-
282
- // src/lib/session-registry.ts
283
- import path5 from "path";
284
- import os5 from "os";
285
222
  var REGISTRY_PATH;
286
223
  var init_session_registry = __esm({
287
224
  "src/lib/session-registry.ts"() {
288
225
  "use strict";
289
- REGISTRY_PATH = path5.join(os5.homedir(), ".exe-os", "session-registry.json");
226
+ REGISTRY_PATH = path4.join(os4.homedir(), ".exe-os", "session-registry.json");
290
227
  }
291
228
  });
292
229
 
@@ -521,15 +458,16 @@ var init_runtime_table = __esm({
521
458
  });
522
459
 
523
460
  // src/lib/agent-config.ts
524
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, existsSync as existsSync4, mkdirSync } from "fs";
525
- import path6 from "path";
461
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync4 } from "fs";
462
+ import path5 from "path";
526
463
  var AGENT_CONFIG_PATH, DEFAULT_MODELS;
527
464
  var init_agent_config = __esm({
528
465
  "src/lib/agent-config.ts"() {
529
466
  "use strict";
530
467
  init_config();
531
468
  init_runtime_table();
532
- AGENT_CONFIG_PATH = path6.join(EXE_AI_DIR, "agent-config.json");
469
+ init_secure_files();
470
+ AGENT_CONFIG_PATH = path5.join(EXE_AI_DIR, "agent-config.json");
533
471
  DEFAULT_MODELS = {
534
472
  claude: "claude-opus-4",
535
473
  codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
@@ -539,38 +477,41 @@ var init_agent_config = __esm({
539
477
  });
540
478
 
541
479
  // src/lib/intercom-queue.ts
542
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, renameSync as renameSync3, existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
543
- import path7 from "path";
544
- import os6 from "os";
480
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, renameSync as renameSync3, existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
481
+ import path6 from "path";
482
+ import os5 from "os";
545
483
  var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
546
484
  var init_intercom_queue = __esm({
547
485
  "src/lib/intercom-queue.ts"() {
548
486
  "use strict";
549
- QUEUE_PATH = path7.join(os6.homedir(), ".exe-os", "intercom-queue.json");
487
+ QUEUE_PATH = path6.join(os5.homedir(), ".exe-os", "intercom-queue.json");
550
488
  TTL_MS = 60 * 60 * 1e3;
551
- INTERCOM_LOG = path7.join(os6.homedir(), ".exe-os", "intercom.log");
489
+ INTERCOM_LOG = path6.join(os5.homedir(), ".exe-os", "intercom.log");
552
490
  }
553
491
  });
554
492
 
555
493
  // src/lib/license.ts
556
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
494
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
557
495
  import { randomUUID } from "crypto";
558
- import path8 from "path";
496
+ import { createRequire as createRequire2 } from "module";
497
+ import { pathToFileURL as pathToFileURL2 } from "url";
498
+ import os6 from "os";
499
+ import path7 from "path";
559
500
  import { jwtVerify, importSPKI } from "jose";
560
501
  var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
561
502
  var init_license = __esm({
562
503
  "src/lib/license.ts"() {
563
504
  "use strict";
564
505
  init_config();
565
- LICENSE_PATH = path8.join(EXE_AI_DIR, "license.key");
566
- CACHE_PATH = path8.join(EXE_AI_DIR, "license-cache.json");
567
- DEVICE_ID_PATH = path8.join(EXE_AI_DIR, "device-id");
506
+ LICENSE_PATH = path7.join(EXE_AI_DIR, "license.key");
507
+ CACHE_PATH = path7.join(EXE_AI_DIR, "license-cache.json");
508
+ DEVICE_ID_PATH = path7.join(EXE_AI_DIR, "device-id");
568
509
  }
569
510
  });
570
511
 
571
512
  // src/lib/plan-limits.ts
572
- import { readFileSync as readFileSync7, existsSync as existsSync7 } from "fs";
573
- import path9 from "path";
513
+ import { readFileSync as readFileSync6, existsSync as existsSync7 } from "fs";
514
+ import path8 from "path";
574
515
  var CACHE_PATH2;
575
516
  var init_plan_limits = __esm({
576
517
  "src/lib/plan-limits.ts"() {
@@ -579,13 +520,13 @@ var init_plan_limits = __esm({
579
520
  init_employees();
580
521
  init_license();
581
522
  init_config();
582
- CACHE_PATH2 = path9.join(EXE_AI_DIR, "license-cache.json");
523
+ CACHE_PATH2 = path8.join(EXE_AI_DIR, "license-cache.json");
583
524
  }
584
525
  });
585
526
 
586
527
  // src/lib/tmux-routing.ts
587
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync8, appendFileSync, readdirSync as readdirSync2 } from "fs";
588
- import path10 from "path";
528
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync8, appendFileSync, readdirSync } from "fs";
529
+ import path9 from "path";
589
530
  import os7 from "os";
590
531
  import { fileURLToPath } from "url";
591
532
  function getMySession() {
@@ -599,7 +540,7 @@ function extractRootExe(name) {
599
540
  }
600
541
  function getParentExe(sessionKey) {
601
542
  try {
602
- const data = JSON.parse(readFileSync8(path10.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
543
+ const data = JSON.parse(readFileSync7(path9.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
603
544
  return data.parentExe || null;
604
545
  } catch {
605
546
  return null;
@@ -642,10 +583,10 @@ var init_tmux_routing = __esm({
642
583
  init_intercom_queue();
643
584
  init_plan_limits();
644
585
  init_employees();
645
- SPAWN_LOCK_DIR = path10.join(os7.homedir(), ".exe-os", "spawn-locks");
646
- SESSION_CACHE = path10.join(os7.homedir(), ".exe-os", "session-cache");
647
- INTERCOM_LOG2 = path10.join(os7.homedir(), ".exe-os", "intercom.log");
648
- DEBOUNCE_FILE = path10.join(SESSION_CACHE, "intercom-debounce.json");
586
+ SPAWN_LOCK_DIR = path9.join(os7.homedir(), ".exe-os", "spawn-locks");
587
+ SESSION_CACHE = path9.join(os7.homedir(), ".exe-os", "session-cache");
588
+ INTERCOM_LOG2 = path9.join(os7.homedir(), ".exe-os", "intercom.log");
589
+ DEBOUNCE_FILE = path9.join(SESSION_CACHE, "intercom-debounce.json");
649
590
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
650
591
  }
651
592
  });
@@ -674,13 +615,87 @@ var init_task_scope = __esm({
674
615
  }
675
616
  });
676
617
 
618
+ // src/lib/notifications.ts
619
+ import crypto from "crypto";
620
+ import path10 from "path";
621
+ import os8 from "os";
622
+ import {
623
+ readFileSync as readFileSync8,
624
+ readdirSync as readdirSync2,
625
+ unlinkSync as unlinkSync2,
626
+ existsSync as existsSync9,
627
+ rmdirSync
628
+ } from "fs";
629
+ var init_notifications = __esm({
630
+ "src/lib/notifications.ts"() {
631
+ "use strict";
632
+ init_database();
633
+ init_task_scope();
634
+ }
635
+ });
636
+
637
+ // src/lib/state-bus.ts
638
+ var StateBus, orgBus;
639
+ var init_state_bus = __esm({
640
+ "src/lib/state-bus.ts"() {
641
+ "use strict";
642
+ StateBus = class {
643
+ handlers = /* @__PURE__ */ new Map();
644
+ globalHandlers = /* @__PURE__ */ new Set();
645
+ /** Emit an event to all subscribers */
646
+ emit(event) {
647
+ const typeHandlers = this.handlers.get(event.type);
648
+ if (typeHandlers) {
649
+ for (const handler of typeHandlers) {
650
+ try {
651
+ handler(event);
652
+ } catch {
653
+ }
654
+ }
655
+ }
656
+ for (const handler of this.globalHandlers) {
657
+ try {
658
+ handler(event);
659
+ } catch {
660
+ }
661
+ }
662
+ }
663
+ /** Subscribe to a specific event type */
664
+ on(type, handler) {
665
+ if (!this.handlers.has(type)) {
666
+ this.handlers.set(type, /* @__PURE__ */ new Set());
667
+ }
668
+ this.handlers.get(type).add(handler);
669
+ }
670
+ /** Subscribe to ALL events */
671
+ onAny(handler) {
672
+ this.globalHandlers.add(handler);
673
+ }
674
+ /** Unsubscribe from a specific event type */
675
+ off(type, handler) {
676
+ this.handlers.get(type)?.delete(handler);
677
+ }
678
+ /** Unsubscribe from ALL events */
679
+ offAny(handler) {
680
+ this.globalHandlers.delete(handler);
681
+ }
682
+ /** Remove all listeners */
683
+ clear() {
684
+ this.handlers.clear();
685
+ this.globalHandlers.clear();
686
+ }
687
+ };
688
+ orgBus = new StateBus();
689
+ }
690
+ });
691
+
677
692
  // src/lib/tasks-crud.ts
678
693
  import crypto2 from "crypto";
679
694
  import path11 from "path";
680
- import os8 from "os";
695
+ import os9 from "os";
681
696
  import { execSync as execSync4 } from "child_process";
682
697
  import { mkdir as mkdir3, writeFile as writeFile3, appendFile } from "fs/promises";
683
- import { existsSync as existsSync9, readFileSync as readFileSync9 } from "fs";
698
+ import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
684
699
  function buildKeywordIndex() {
685
700
  const idx = /* @__PURE__ */ new Map();
686
701
  for (const [role, keywords] of Object.entries(LANE_KEYWORDS)) {
@@ -763,7 +778,7 @@ var init_tasks_crud = __esm({
763
778
 
764
779
  // src/lib/tasks-review.ts
765
780
  import path12 from "path";
766
- import { existsSync as existsSync10, readdirSync as readdirSync3, unlinkSync as unlinkSync3 } from "fs";
781
+ import { existsSync as existsSync11, readdirSync as readdirSync3, unlinkSync as unlinkSync3 } from "fs";
767
782
  var init_tasks_review = __esm({
768
783
  "src/lib/tasks-review.ts"() {
769
784
  "use strict";
@@ -774,6 +789,7 @@ var init_tasks_review = __esm({
774
789
  init_tmux_routing();
775
790
  init_session_key();
776
791
  init_state_bus();
792
+ init_task_scope();
777
793
  }
778
794
  });
779
795
 
@@ -974,7 +990,7 @@ function registerListTasks(server) {
974
990
  description: "Query tasks by assignee, status, project, or priority. Defaults to current project. Pass project_name='all' for all projects. When querying your own tasks, project filter is skipped automatically.",
975
991
  inputSchema: {
976
992
  assigned_to: z.string().optional().describe("Filter by employee name"),
977
- status: z.enum(["open", "in_progress", "done", "blocked", "cancelled"]).optional().describe("Filter by status"),
993
+ status: z.enum(["open", "in_progress", "done", "needs_review", "blocked", "cancelled", "closed"]).optional().describe("Filter by status. Default: active tasks only (excludes closed/cancelled)"),
978
994
  project_name: z.string().optional().describe("Project name. Defaults to current project. Pass 'all' for all projects."),
979
995
  priority: z.enum(["p0", "p1", "p2"]).optional().describe("Filter by priority")
980
996
  }