@askexenow/exe-os 0.8.40 → 0.8.42

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 (78) hide show
  1. package/dist/bin/backfill-conversations.js +805 -642
  2. package/dist/bin/backfill-responses.js +804 -641
  3. package/dist/bin/backfill-vectors.js +791 -634
  4. package/dist/bin/cleanup-stale-review-tasks.js +788 -631
  5. package/dist/bin/cli.js +1376 -659
  6. package/dist/bin/exe-agent.js +20 -1
  7. package/dist/bin/exe-assign.js +1503 -1343
  8. package/dist/bin/exe-boot.js +2549 -1784
  9. package/dist/bin/exe-call.js +39 -1
  10. package/dist/bin/exe-cloud.js +12 -2
  11. package/dist/bin/exe-dispatch.js +39 -2
  12. package/dist/bin/exe-doctor.js +791 -634
  13. package/dist/bin/exe-export-behaviors.js +792 -637
  14. package/dist/bin/exe-forget.js +145 -0
  15. package/dist/bin/exe-gateway.js +2501 -1846
  16. package/dist/bin/exe-heartbeat.js +147 -1
  17. package/dist/bin/exe-kill.js +795 -640
  18. package/dist/bin/exe-launch-agent.js +2168 -2008
  19. package/dist/bin/exe-link.js +44 -12
  20. package/dist/bin/exe-new-employee.js +6 -2
  21. package/dist/bin/exe-pending-messages.js +146 -1
  22. package/dist/bin/exe-pending-notifications.js +788 -631
  23. package/dist/bin/exe-pending-reviews.js +176 -1
  24. package/dist/bin/exe-rename.js +23 -0
  25. package/dist/bin/exe-review.js +490 -327
  26. package/dist/bin/exe-search.js +157 -4
  27. package/dist/bin/exe-session-cleanup.js +2487 -403
  28. package/dist/bin/exe-settings.js +2 -1
  29. package/dist/bin/exe-status.js +474 -317
  30. package/dist/bin/exe-team.js +474 -317
  31. package/dist/bin/git-sweep.js +2691 -151
  32. package/dist/bin/graph-backfill.js +794 -637
  33. package/dist/bin/graph-export.js +798 -641
  34. package/dist/bin/scan-tasks.js +2951 -44
  35. package/dist/bin/setup.js +50 -26
  36. package/dist/bin/shard-migrate.js +792 -637
  37. package/dist/bin/wiki-sync.js +794 -637
  38. package/dist/gateway/index.js +2542 -1887
  39. package/dist/hooks/bug-report-worker.js +2118 -576
  40. package/dist/hooks/commit-complete.js +2690 -150
  41. package/dist/hooks/error-recall.js +157 -4
  42. package/dist/hooks/ingest-worker.js +1455 -803
  43. package/dist/hooks/instructions-loaded.js +151 -0
  44. package/dist/hooks/notification.js +153 -2
  45. package/dist/hooks/post-compact.js +164 -0
  46. package/dist/hooks/pre-compact.js +3073 -101
  47. package/dist/hooks/pre-tool-use.js +151 -0
  48. package/dist/hooks/prompt-ingest-worker.js +1670 -1509
  49. package/dist/hooks/prompt-submit.js +2650 -1074
  50. package/dist/hooks/response-ingest-worker.js +154 -6
  51. package/dist/hooks/session-end.js +153 -2
  52. package/dist/hooks/session-start.js +157 -4
  53. package/dist/hooks/stop.js +151 -0
  54. package/dist/hooks/subagent-stop.js +155 -2
  55. package/dist/hooks/summary-worker.js +190 -21
  56. package/dist/index.js +326 -102
  57. package/dist/lib/cloud-sync.js +31 -10
  58. package/dist/lib/config.js +2 -0
  59. package/dist/lib/consolidation.js +69 -2
  60. package/dist/lib/database.js +19 -0
  61. package/dist/lib/device-registry.js +19 -0
  62. package/dist/lib/embedder.js +3 -1
  63. package/dist/lib/employee-templates.js +20 -1
  64. package/dist/lib/exe-daemon.js +285 -18
  65. package/dist/lib/hybrid-search.js +157 -4
  66. package/dist/lib/messaging.js +39 -2
  67. package/dist/lib/schedules.js +792 -637
  68. package/dist/lib/store.js +796 -636
  69. package/dist/lib/tasks.js +1485 -918
  70. package/dist/lib/tmux-routing.js +194 -10
  71. package/dist/mcp/server.js +1643 -924
  72. package/dist/mcp/tools/create-task.js +2283 -829
  73. package/dist/mcp/tools/list-tasks.js +2788 -159
  74. package/dist/mcp/tools/send-message.js +39 -2
  75. package/dist/mcp/tools/update-task.js +79 -0
  76. package/dist/runtime/index.js +280 -68
  77. package/dist/tui/App.js +1485 -645
  78. package/package.json +3 -2
@@ -302,6 +302,13 @@ async function ensureSchema() {
302
302
  });
303
303
  } catch {
304
304
  }
305
+ try {
306
+ await client.execute({
307
+ sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
308
+ args: []
309
+ });
310
+ } catch {
311
+ }
305
312
  try {
306
313
  await client.execute({
307
314
  sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
@@ -748,6 +755,18 @@ async function ensureSchema() {
748
755
  CREATE INDEX IF NOT EXISTS idx_session_kills_agent
749
756
  ON session_kills(agent_id);
750
757
  `);
758
+ await client.execute(`
759
+ CREATE TABLE IF NOT EXISTS global_procedures (
760
+ id TEXT PRIMARY KEY,
761
+ title TEXT NOT NULL,
762
+ content TEXT NOT NULL,
763
+ priority TEXT NOT NULL DEFAULT 'p0',
764
+ domain TEXT,
765
+ active INTEGER NOT NULL DEFAULT 1,
766
+ created_at TEXT NOT NULL,
767
+ updated_at TEXT NOT NULL
768
+ )
769
+ `);
751
770
  await client.executeMultiple(`
752
771
  CREATE TABLE IF NOT EXISTS conversations (
753
772
  id TEXT PRIMARY KEY,
@@ -1086,6 +1105,61 @@ var init_config = __esm({
1086
1105
  }
1087
1106
  });
1088
1107
 
1108
+ // src/lib/state-bus.ts
1109
+ var StateBus, orgBus;
1110
+ var init_state_bus = __esm({
1111
+ "src/lib/state-bus.ts"() {
1112
+ "use strict";
1113
+ StateBus = class {
1114
+ handlers = /* @__PURE__ */ new Map();
1115
+ globalHandlers = /* @__PURE__ */ new Set();
1116
+ /** Emit an event to all subscribers */
1117
+ emit(event) {
1118
+ const typeHandlers = this.handlers.get(event.type);
1119
+ if (typeHandlers) {
1120
+ for (const handler of typeHandlers) {
1121
+ try {
1122
+ handler(event);
1123
+ } catch {
1124
+ }
1125
+ }
1126
+ }
1127
+ for (const handler of this.globalHandlers) {
1128
+ try {
1129
+ handler(event);
1130
+ } catch {
1131
+ }
1132
+ }
1133
+ }
1134
+ /** Subscribe to a specific event type */
1135
+ on(type, handler) {
1136
+ if (!this.handlers.has(type)) {
1137
+ this.handlers.set(type, /* @__PURE__ */ new Set());
1138
+ }
1139
+ this.handlers.get(type).add(handler);
1140
+ }
1141
+ /** Subscribe to ALL events */
1142
+ onAny(handler) {
1143
+ this.globalHandlers.add(handler);
1144
+ }
1145
+ /** Unsubscribe from a specific event type */
1146
+ off(type, handler) {
1147
+ this.handlers.get(type)?.delete(handler);
1148
+ }
1149
+ /** Unsubscribe from ALL events */
1150
+ offAny(handler) {
1151
+ this.globalHandlers.delete(handler);
1152
+ }
1153
+ /** Remove all listeners */
1154
+ clear() {
1155
+ this.handlers.clear();
1156
+ this.globalHandlers.clear();
1157
+ }
1158
+ };
1159
+ orgBus = new StateBus();
1160
+ }
1161
+ });
1162
+
1089
1163
  // src/lib/shard-manager.ts
1090
1164
  var shard_manager_exports = {};
1091
1165
  __export(shard_manager_exports, {
@@ -1327,6 +1401,71 @@ var init_shard_manager = __esm({
1327
1401
  }
1328
1402
  });
1329
1403
 
1404
+ // src/lib/global-procedures.ts
1405
+ var global_procedures_exports = {};
1406
+ __export(global_procedures_exports, {
1407
+ deactivateGlobalProcedure: () => deactivateGlobalProcedure,
1408
+ getGlobalProceduresBlock: () => getGlobalProceduresBlock,
1409
+ loadGlobalProcedures: () => loadGlobalProcedures,
1410
+ storeGlobalProcedure: () => storeGlobalProcedure
1411
+ });
1412
+ import { randomUUID } from "crypto";
1413
+ async function loadGlobalProcedures() {
1414
+ const client = getClient();
1415
+ const result = await client.execute({
1416
+ sql: "SELECT * FROM global_procedures WHERE active = 1 ORDER BY priority ASC, created_at ASC",
1417
+ args: []
1418
+ });
1419
+ const procedures = result.rows;
1420
+ if (procedures.length > 0) {
1421
+ _cache = procedures.map((p) => `### ${p.title}
1422
+ ${p.content}`).join("\n\n");
1423
+ } else {
1424
+ _cache = "";
1425
+ }
1426
+ _cacheLoaded = true;
1427
+ return procedures;
1428
+ }
1429
+ function getGlobalProceduresBlock() {
1430
+ if (!_cacheLoaded) return "";
1431
+ if (!_cache) return "";
1432
+ return `## Organization-Wide Procedures (MANDATORY \u2014 supersedes all other rules)
1433
+
1434
+ ${_cache}
1435
+ `;
1436
+ }
1437
+ async function storeGlobalProcedure(input) {
1438
+ const id = randomUUID();
1439
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1440
+ const client = getClient();
1441
+ await client.execute({
1442
+ sql: `INSERT INTO global_procedures (id, title, content, priority, domain, active, created_at, updated_at)
1443
+ VALUES (?, ?, ?, ?, ?, 1, ?, ?)`,
1444
+ args: [id, input.title, input.content, input.priority ?? "p0", input.domain ?? null, now, now]
1445
+ });
1446
+ await loadGlobalProcedures();
1447
+ return id;
1448
+ }
1449
+ async function deactivateGlobalProcedure(id) {
1450
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1451
+ const client = getClient();
1452
+ const result = await client.execute({
1453
+ sql: "UPDATE global_procedures SET active = 0, updated_at = ? WHERE id = ?",
1454
+ args: [now, id]
1455
+ });
1456
+ await loadGlobalProcedures();
1457
+ return result.rowsAffected > 0;
1458
+ }
1459
+ var _cache, _cacheLoaded;
1460
+ var init_global_procedures = __esm({
1461
+ "src/lib/global-procedures.ts"() {
1462
+ "use strict";
1463
+ init_database();
1464
+ _cache = "";
1465
+ _cacheLoaded = false;
1466
+ }
1467
+ });
1468
+
1330
1469
  // src/lib/employees.ts
1331
1470
  import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
1332
1471
  import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync2 } from "fs";
@@ -1443,7 +1582,7 @@ var init_intercom_queue = __esm({
1443
1582
 
1444
1583
  // src/lib/license.ts
1445
1584
  import { readFileSync as readFileSync6, writeFileSync as writeFileSync2, existsSync as existsSync8, mkdirSync as mkdirSync3 } from "fs";
1446
- import { randomUUID } from "crypto";
1585
+ import { randomUUID as randomUUID2 } from "crypto";
1447
1586
  import path9 from "path";
1448
1587
  import { jwtVerify, importSPKI } from "jose";
1449
1588
  var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
@@ -1509,6 +1648,34 @@ async function listPendingReviews(limit) {
1509
1648
  });
1510
1649
  return result.rows;
1511
1650
  }
1651
+ async function cleanupOrphanedReviews() {
1652
+ const client = getClient();
1653
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1654
+ const r1 = await client.execute({
1655
+ sql: `UPDATE tasks SET status = 'done', updated_at = ?
1656
+ WHERE status = 'needs_review'
1657
+ AND assigned_by = 'system'
1658
+ AND title LIKE 'Review:%'
1659
+ AND parent_task_id IN (SELECT id FROM tasks WHERE status IN ('done', 'cancelled'))`,
1660
+ args: [now]
1661
+ });
1662
+ const staleThreshold = new Date(Date.now() - 60 * 60 * 1e3).toISOString();
1663
+ const r2 = await client.execute({
1664
+ sql: `UPDATE tasks SET status = 'done', updated_at = ?
1665
+ WHERE status = 'needs_review'
1666
+ AND result IS NOT NULL
1667
+ AND updated_at < ?`,
1668
+ args: [now, staleThreshold]
1669
+ });
1670
+ const total = r1.rowsAffected + r2.rowsAffected;
1671
+ if (total > 0) {
1672
+ process.stderr.write(
1673
+ `[cleanup] Closed ${total} orphaned review(s): ${r1.rowsAffected} cascade + ${r2.rowsAffected} stale
1674
+ `
1675
+ );
1676
+ }
1677
+ return total;
1678
+ }
1512
1679
  var init_tasks_review = __esm({
1513
1680
  "src/lib/tasks-review.ts"() {
1514
1681
  "use strict";
@@ -1519,6 +1686,7 @@ var init_tasks_review = __esm({
1519
1686
  init_tasks_crud();
1520
1687
  init_tmux_routing();
1521
1688
  init_session_key();
1689
+ init_state_bus();
1522
1690
  }
1523
1691
  });
1524
1692
 
@@ -1571,6 +1739,7 @@ async function getMasterKey() {
1571
1739
 
1572
1740
  // src/lib/store.ts
1573
1741
  init_config();
1742
+ init_state_bus();
1574
1743
  var INIT_MAX_RETRIES = 3;
1575
1744
  var INIT_RETRY_DELAY_MS = 1e3;
1576
1745
  function isBusyError2(err) {
@@ -1641,6 +1810,11 @@ async function initStore(options) {
1641
1810
  "version-query"
1642
1811
  );
1643
1812
  _nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
1813
+ try {
1814
+ const { loadGlobalProcedures: loadGlobalProcedures2 } = await Promise.resolve().then(() => (init_global_procedures(), global_procedures_exports));
1815
+ await loadGlobalProcedures2();
1816
+ } catch {
1817
+ }
1644
1818
  }
1645
1819
 
1646
1820
  // src/lib/is-main.ts
@@ -1662,6 +1836,7 @@ init_tasks_review();
1662
1836
  var PENDING_REVIEW_LIMIT = 10;
1663
1837
  async function main() {
1664
1838
  await initStore();
1839
+ await cleanupOrphanedReviews();
1665
1840
  const rows = await listPendingReviews(PENDING_REVIEW_LIMIT);
1666
1841
  if (rows.length > 0) {
1667
1842
  console.log("[REVIEW NOTIFICATIONS]");
@@ -316,6 +316,13 @@ async function ensureSchema() {
316
316
  });
317
317
  } catch {
318
318
  }
319
+ try {
320
+ await client.execute({
321
+ sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
322
+ args: []
323
+ });
324
+ } catch {
325
+ }
319
326
  try {
320
327
  await client.execute({
321
328
  sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
@@ -762,6 +769,18 @@ async function ensureSchema() {
762
769
  CREATE INDEX IF NOT EXISTS idx_session_kills_agent
763
770
  ON session_kills(agent_id);
764
771
  `);
772
+ await client.execute(`
773
+ CREATE TABLE IF NOT EXISTS global_procedures (
774
+ id TEXT PRIMARY KEY,
775
+ title TEXT NOT NULL,
776
+ content TEXT NOT NULL,
777
+ priority TEXT NOT NULL DEFAULT 'p0',
778
+ domain TEXT,
779
+ active INTEGER NOT NULL DEFAULT 1,
780
+ created_at TEXT NOT NULL,
781
+ updated_at TEXT NOT NULL
782
+ )
783
+ `);
765
784
  await client.executeMultiple(`
766
785
  CREATE TABLE IF NOT EXISTS conversations (
767
786
  id TEXT PRIMARY KEY,
@@ -1095,6 +1114,10 @@ function registerBinSymlinks(name) {
1095
1114
  return { created, skipped, errors };
1096
1115
  }
1097
1116
 
1117
+ // src/lib/global-procedures.ts
1118
+ init_database();
1119
+ import { randomUUID } from "crypto";
1120
+
1098
1121
  // src/lib/employee-templates.ts
1099
1122
  function personalizePrompt(prompt, templateName, actualName) {
1100
1123
  if (templateName === actualName) return prompt;