@askexenow/exe-os 0.8.41 → 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 (74) 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 +1326 -655
  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 +2508 -1802
  9. package/dist/bin/exe-call.js +39 -1
  10. package/dist/bin/exe-dispatch.js +39 -2
  11. package/dist/bin/exe-doctor.js +790 -633
  12. package/dist/bin/exe-export-behaviors.js +792 -637
  13. package/dist/bin/exe-forget.js +145 -0
  14. package/dist/bin/exe-gateway.js +2487 -1878
  15. package/dist/bin/exe-heartbeat.js +147 -1
  16. package/dist/bin/exe-kill.js +795 -640
  17. package/dist/bin/exe-launch-agent.js +2168 -2008
  18. package/dist/bin/exe-link.js +9 -1
  19. package/dist/bin/exe-new-employee.js +6 -2
  20. package/dist/bin/exe-pending-messages.js +146 -1
  21. package/dist/bin/exe-pending-notifications.js +788 -631
  22. package/dist/bin/exe-pending-reviews.js +147 -1
  23. package/dist/bin/exe-rename.js +23 -0
  24. package/dist/bin/exe-review.js +490 -327
  25. package/dist/bin/exe-search.js +154 -3
  26. package/dist/bin/exe-session-cleanup.js +2466 -413
  27. package/dist/bin/exe-status.js +474 -317
  28. package/dist/bin/exe-team.js +474 -317
  29. package/dist/bin/git-sweep.js +2690 -150
  30. package/dist/bin/graph-backfill.js +794 -637
  31. package/dist/bin/graph-export.js +798 -641
  32. package/dist/bin/scan-tasks.js +2951 -44
  33. package/dist/bin/setup.js +47 -25
  34. package/dist/bin/shard-migrate.js +792 -637
  35. package/dist/bin/wiki-sync.js +794 -637
  36. package/dist/gateway/index.js +2504 -1895
  37. package/dist/hooks/bug-report-worker.js +2118 -576
  38. package/dist/hooks/commit-complete.js +2689 -149
  39. package/dist/hooks/error-recall.js +154 -3
  40. package/dist/hooks/ingest-worker.js +1420 -814
  41. package/dist/hooks/instructions-loaded.js +151 -0
  42. package/dist/hooks/notification.js +153 -2
  43. package/dist/hooks/post-compact.js +164 -0
  44. package/dist/hooks/pre-compact.js +3073 -101
  45. package/dist/hooks/pre-tool-use.js +151 -0
  46. package/dist/hooks/prompt-ingest-worker.js +1700 -1541
  47. package/dist/hooks/prompt-submit.js +2658 -1113
  48. package/dist/hooks/response-ingest-worker.js +151 -5
  49. package/dist/hooks/session-end.js +153 -2
  50. package/dist/hooks/session-start.js +154 -3
  51. package/dist/hooks/stop.js +151 -0
  52. package/dist/hooks/subagent-stop.js +151 -0
  53. package/dist/hooks/summary-worker.js +160 -6
  54. package/dist/index.js +278 -100
  55. package/dist/lib/cloud-sync.js +9 -1
  56. package/dist/lib/consolidation.js +69 -2
  57. package/dist/lib/database.js +19 -0
  58. package/dist/lib/device-registry.js +19 -0
  59. package/dist/lib/employee-templates.js +20 -1
  60. package/dist/lib/exe-daemon.js +236 -16
  61. package/dist/lib/hybrid-search.js +154 -3
  62. package/dist/lib/messaging.js +39 -2
  63. package/dist/lib/schedules.js +792 -637
  64. package/dist/lib/store.js +796 -636
  65. package/dist/lib/tasks.js +1614 -1091
  66. package/dist/lib/tmux-routing.js +149 -9
  67. package/dist/mcp/server.js +1810 -1137
  68. package/dist/mcp/tools/create-task.js +2280 -828
  69. package/dist/mcp/tools/list-tasks.js +2788 -159
  70. package/dist/mcp/tools/send-message.js +39 -2
  71. package/dist/mcp/tools/update-task.js +64 -0
  72. package/dist/runtime/index.js +235 -67
  73. package/dist/tui/App.js +1440 -646
  74. package/package.json +3 -2
@@ -532,6 +532,13 @@ async function ensureSchema() {
532
532
  });
533
533
  } catch {
534
534
  }
535
+ try {
536
+ await client.execute({
537
+ sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
538
+ args: []
539
+ });
540
+ } catch {
541
+ }
535
542
  try {
536
543
  await client.execute({
537
544
  sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
@@ -978,6 +985,18 @@ async function ensureSchema() {
978
985
  CREATE INDEX IF NOT EXISTS idx_session_kills_agent
979
986
  ON session_kills(agent_id);
980
987
  `);
988
+ await client.execute(`
989
+ CREATE TABLE IF NOT EXISTS global_procedures (
990
+ id TEXT PRIMARY KEY,
991
+ title TEXT NOT NULL,
992
+ content TEXT NOT NULL,
993
+ priority TEXT NOT NULL DEFAULT 'p0',
994
+ domain TEXT,
995
+ active INTEGER NOT NULL DEFAULT 1,
996
+ created_at TEXT NOT NULL,
997
+ updated_at TEXT NOT NULL
998
+ )
999
+ `);
981
1000
  await client.executeMultiple(`
982
1001
  CREATE TABLE IF NOT EXISTS conversations (
983
1002
  id TEXT PRIMARY KEY,
@@ -1185,6 +1204,61 @@ var init_keychain = __esm({
1185
1204
  }
1186
1205
  });
1187
1206
 
1207
+ // src/lib/state-bus.ts
1208
+ var StateBus, orgBus;
1209
+ var init_state_bus = __esm({
1210
+ "src/lib/state-bus.ts"() {
1211
+ "use strict";
1212
+ StateBus = class {
1213
+ handlers = /* @__PURE__ */ new Map();
1214
+ globalHandlers = /* @__PURE__ */ new Set();
1215
+ /** Emit an event to all subscribers */
1216
+ emit(event) {
1217
+ const typeHandlers = this.handlers.get(event.type);
1218
+ if (typeHandlers) {
1219
+ for (const handler of typeHandlers) {
1220
+ try {
1221
+ handler(event);
1222
+ } catch {
1223
+ }
1224
+ }
1225
+ }
1226
+ for (const handler of this.globalHandlers) {
1227
+ try {
1228
+ handler(event);
1229
+ } catch {
1230
+ }
1231
+ }
1232
+ }
1233
+ /** Subscribe to a specific event type */
1234
+ on(type, handler) {
1235
+ if (!this.handlers.has(type)) {
1236
+ this.handlers.set(type, /* @__PURE__ */ new Set());
1237
+ }
1238
+ this.handlers.get(type).add(handler);
1239
+ }
1240
+ /** Subscribe to ALL events */
1241
+ onAny(handler) {
1242
+ this.globalHandlers.add(handler);
1243
+ }
1244
+ /** Unsubscribe from a specific event type */
1245
+ off(type, handler) {
1246
+ this.handlers.get(type)?.delete(handler);
1247
+ }
1248
+ /** Unsubscribe from ALL events */
1249
+ offAny(handler) {
1250
+ this.globalHandlers.delete(handler);
1251
+ }
1252
+ /** Remove all listeners */
1253
+ clear() {
1254
+ this.handlers.clear();
1255
+ this.globalHandlers.clear();
1256
+ }
1257
+ };
1258
+ orgBus = new StateBus();
1259
+ }
1260
+ });
1261
+
1188
1262
  // src/lib/shard-manager.ts
1189
1263
  var shard_manager_exports = {};
1190
1264
  __export(shard_manager_exports, {
@@ -1426,6 +1500,71 @@ var init_shard_manager = __esm({
1426
1500
  }
1427
1501
  });
1428
1502
 
1503
+ // src/lib/global-procedures.ts
1504
+ var global_procedures_exports = {};
1505
+ __export(global_procedures_exports, {
1506
+ deactivateGlobalProcedure: () => deactivateGlobalProcedure,
1507
+ getGlobalProceduresBlock: () => getGlobalProceduresBlock,
1508
+ loadGlobalProcedures: () => loadGlobalProcedures,
1509
+ storeGlobalProcedure: () => storeGlobalProcedure
1510
+ });
1511
+ import { randomUUID } from "crypto";
1512
+ async function loadGlobalProcedures() {
1513
+ const client = getClient();
1514
+ const result = await client.execute({
1515
+ sql: "SELECT * FROM global_procedures WHERE active = 1 ORDER BY priority ASC, created_at ASC",
1516
+ args: []
1517
+ });
1518
+ const procedures = result.rows;
1519
+ if (procedures.length > 0) {
1520
+ _cache = procedures.map((p) => `### ${p.title}
1521
+ ${p.content}`).join("\n\n");
1522
+ } else {
1523
+ _cache = "";
1524
+ }
1525
+ _cacheLoaded = true;
1526
+ return procedures;
1527
+ }
1528
+ function getGlobalProceduresBlock() {
1529
+ if (!_cacheLoaded) return "";
1530
+ if (!_cache) return "";
1531
+ return `## Organization-Wide Procedures (MANDATORY \u2014 supersedes all other rules)
1532
+
1533
+ ${_cache}
1534
+ `;
1535
+ }
1536
+ async function storeGlobalProcedure(input2) {
1537
+ const id = randomUUID();
1538
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1539
+ const client = getClient();
1540
+ await client.execute({
1541
+ sql: `INSERT INTO global_procedures (id, title, content, priority, domain, active, created_at, updated_at)
1542
+ VALUES (?, ?, ?, ?, ?, 1, ?, ?)`,
1543
+ args: [id, input2.title, input2.content, input2.priority ?? "p0", input2.domain ?? null, now, now]
1544
+ });
1545
+ await loadGlobalProcedures();
1546
+ return id;
1547
+ }
1548
+ async function deactivateGlobalProcedure(id) {
1549
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1550
+ const client = getClient();
1551
+ const result = await client.execute({
1552
+ sql: "UPDATE global_procedures SET active = 0, updated_at = ? WHERE id = ?",
1553
+ args: [now, id]
1554
+ });
1555
+ await loadGlobalProcedures();
1556
+ return result.rowsAffected > 0;
1557
+ }
1558
+ var _cache, _cacheLoaded;
1559
+ var init_global_procedures = __esm({
1560
+ "src/lib/global-procedures.ts"() {
1561
+ "use strict";
1562
+ init_database();
1563
+ _cache = "";
1564
+ _cacheLoaded = false;
1565
+ }
1566
+ });
1567
+
1429
1568
  // src/lib/store.ts
1430
1569
  var store_exports = {};
1431
1570
  __export(store_exports, {
@@ -1505,6 +1644,11 @@ async function initStore(options) {
1505
1644
  "version-query"
1506
1645
  );
1507
1646
  _nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
1647
+ try {
1648
+ const { loadGlobalProcedures: loadGlobalProcedures2 } = await Promise.resolve().then(() => (init_global_procedures(), global_procedures_exports));
1649
+ await loadGlobalProcedures2();
1650
+ } catch {
1651
+ }
1508
1652
  }
1509
1653
  function classifyTier(record) {
1510
1654
  if (record.tool_name === "commit_to_long_term_memory" && (record.importance ?? 0) >= 8) return 1;
@@ -1546,6 +1690,12 @@ async function writeMemory(record) {
1546
1690
  supersedes_id: record.supersedes_id ?? null
1547
1691
  };
1548
1692
  _pendingRecords.push(dbRow);
1693
+ orgBus.emit({
1694
+ type: "memory_stored",
1695
+ agentId: record.agent_id,
1696
+ project: record.project_name,
1697
+ timestamp: record.timestamp
1698
+ });
1549
1699
  const MAX_PENDING = 1e3;
1550
1700
  if (_pendingRecords.length > MAX_PENDING) {
1551
1701
  const dropped = _pendingRecords.length - MAX_PENDING;
@@ -1891,6 +2041,7 @@ var init_store = __esm({
1891
2041
  init_database();
1892
2042
  init_keychain();
1893
2043
  init_config();
2044
+ init_state_bus();
1894
2045
  INIT_MAX_RETRIES = 3;
1895
2046
  INIT_RETRY_DELAY_MS = 1e3;
1896
2047
  _pendingRecords = [];
@@ -514,6 +514,13 @@ async function ensureSchema() {
514
514
  });
515
515
  } catch {
516
516
  }
517
+ try {
518
+ await client.execute({
519
+ sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
520
+ args: []
521
+ });
522
+ } catch {
523
+ }
517
524
  try {
518
525
  await client.execute({
519
526
  sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
@@ -960,6 +967,18 @@ async function ensureSchema() {
960
967
  CREATE INDEX IF NOT EXISTS idx_session_kills_agent
961
968
  ON session_kills(agent_id);
962
969
  `);
970
+ await client.execute(`
971
+ CREATE TABLE IF NOT EXISTS global_procedures (
972
+ id TEXT PRIMARY KEY,
973
+ title TEXT NOT NULL,
974
+ content TEXT NOT NULL,
975
+ priority TEXT NOT NULL DEFAULT 'p0',
976
+ domain TEXT,
977
+ active INTEGER NOT NULL DEFAULT 1,
978
+ created_at TEXT NOT NULL,
979
+ updated_at TEXT NOT NULL
980
+ )
981
+ `);
963
982
  await client.executeMultiple(`
964
983
  CREATE TABLE IF NOT EXISTS conversations (
965
984
  id TEXT PRIMARY KEY,
@@ -1167,6 +1186,61 @@ var init_keychain = __esm({
1167
1186
  }
1168
1187
  });
1169
1188
 
1189
+ // src/lib/state-bus.ts
1190
+ var StateBus, orgBus;
1191
+ var init_state_bus = __esm({
1192
+ "src/lib/state-bus.ts"() {
1193
+ "use strict";
1194
+ StateBus = class {
1195
+ handlers = /* @__PURE__ */ new Map();
1196
+ globalHandlers = /* @__PURE__ */ new Set();
1197
+ /** Emit an event to all subscribers */
1198
+ emit(event) {
1199
+ const typeHandlers = this.handlers.get(event.type);
1200
+ if (typeHandlers) {
1201
+ for (const handler of typeHandlers) {
1202
+ try {
1203
+ handler(event);
1204
+ } catch {
1205
+ }
1206
+ }
1207
+ }
1208
+ for (const handler of this.globalHandlers) {
1209
+ try {
1210
+ handler(event);
1211
+ } catch {
1212
+ }
1213
+ }
1214
+ }
1215
+ /** Subscribe to a specific event type */
1216
+ on(type, handler) {
1217
+ if (!this.handlers.has(type)) {
1218
+ this.handlers.set(type, /* @__PURE__ */ new Set());
1219
+ }
1220
+ this.handlers.get(type).add(handler);
1221
+ }
1222
+ /** Subscribe to ALL events */
1223
+ onAny(handler) {
1224
+ this.globalHandlers.add(handler);
1225
+ }
1226
+ /** Unsubscribe from a specific event type */
1227
+ off(type, handler) {
1228
+ this.handlers.get(type)?.delete(handler);
1229
+ }
1230
+ /** Unsubscribe from ALL events */
1231
+ offAny(handler) {
1232
+ this.globalHandlers.delete(handler);
1233
+ }
1234
+ /** Remove all listeners */
1235
+ clear() {
1236
+ this.handlers.clear();
1237
+ this.globalHandlers.clear();
1238
+ }
1239
+ };
1240
+ orgBus = new StateBus();
1241
+ }
1242
+ });
1243
+
1170
1244
  // src/lib/shard-manager.ts
1171
1245
  var shard_manager_exports = {};
1172
1246
  __export(shard_manager_exports, {
@@ -1408,6 +1482,71 @@ var init_shard_manager = __esm({
1408
1482
  }
1409
1483
  });
1410
1484
 
1485
+ // src/lib/global-procedures.ts
1486
+ var global_procedures_exports = {};
1487
+ __export(global_procedures_exports, {
1488
+ deactivateGlobalProcedure: () => deactivateGlobalProcedure,
1489
+ getGlobalProceduresBlock: () => getGlobalProceduresBlock,
1490
+ loadGlobalProcedures: () => loadGlobalProcedures,
1491
+ storeGlobalProcedure: () => storeGlobalProcedure
1492
+ });
1493
+ import { randomUUID } from "crypto";
1494
+ async function loadGlobalProcedures() {
1495
+ const client = getClient();
1496
+ const result = await client.execute({
1497
+ sql: "SELECT * FROM global_procedures WHERE active = 1 ORDER BY priority ASC, created_at ASC",
1498
+ args: []
1499
+ });
1500
+ const procedures = result.rows;
1501
+ if (procedures.length > 0) {
1502
+ _cache = procedures.map((p) => `### ${p.title}
1503
+ ${p.content}`).join("\n\n");
1504
+ } else {
1505
+ _cache = "";
1506
+ }
1507
+ _cacheLoaded = true;
1508
+ return procedures;
1509
+ }
1510
+ function getGlobalProceduresBlock() {
1511
+ if (!_cacheLoaded) return "";
1512
+ if (!_cache) return "";
1513
+ return `## Organization-Wide Procedures (MANDATORY \u2014 supersedes all other rules)
1514
+
1515
+ ${_cache}
1516
+ `;
1517
+ }
1518
+ async function storeGlobalProcedure(input2) {
1519
+ const id = randomUUID();
1520
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1521
+ const client = getClient();
1522
+ await client.execute({
1523
+ sql: `INSERT INTO global_procedures (id, title, content, priority, domain, active, created_at, updated_at)
1524
+ VALUES (?, ?, ?, ?, ?, 1, ?, ?)`,
1525
+ args: [id, input2.title, input2.content, input2.priority ?? "p0", input2.domain ?? null, now, now]
1526
+ });
1527
+ await loadGlobalProcedures();
1528
+ return id;
1529
+ }
1530
+ async function deactivateGlobalProcedure(id) {
1531
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1532
+ const client = getClient();
1533
+ const result = await client.execute({
1534
+ sql: "UPDATE global_procedures SET active = 0, updated_at = ? WHERE id = ?",
1535
+ args: [now, id]
1536
+ });
1537
+ await loadGlobalProcedures();
1538
+ return result.rowsAffected > 0;
1539
+ }
1540
+ var _cache, _cacheLoaded;
1541
+ var init_global_procedures = __esm({
1542
+ "src/lib/global-procedures.ts"() {
1543
+ "use strict";
1544
+ init_database();
1545
+ _cache = "";
1546
+ _cacheLoaded = false;
1547
+ }
1548
+ });
1549
+
1411
1550
  // src/lib/store.ts
1412
1551
  var store_exports = {};
1413
1552
  __export(store_exports, {
@@ -1487,6 +1626,11 @@ async function initStore(options) {
1487
1626
  "version-query"
1488
1627
  );
1489
1628
  _nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
1629
+ try {
1630
+ const { loadGlobalProcedures: loadGlobalProcedures2 } = await Promise.resolve().then(() => (init_global_procedures(), global_procedures_exports));
1631
+ await loadGlobalProcedures2();
1632
+ } catch {
1633
+ }
1490
1634
  }
1491
1635
  function classifyTier(record) {
1492
1636
  if (record.tool_name === "commit_to_long_term_memory" && (record.importance ?? 0) >= 8) return 1;
@@ -1528,6 +1672,12 @@ async function writeMemory(record) {
1528
1672
  supersedes_id: record.supersedes_id ?? null
1529
1673
  };
1530
1674
  _pendingRecords.push(dbRow);
1675
+ orgBus.emit({
1676
+ type: "memory_stored",
1677
+ agentId: record.agent_id,
1678
+ project: record.project_name,
1679
+ timestamp: record.timestamp
1680
+ });
1531
1681
  const MAX_PENDING = 1e3;
1532
1682
  if (_pendingRecords.length > MAX_PENDING) {
1533
1683
  const dropped = _pendingRecords.length - MAX_PENDING;
@@ -1873,6 +2023,7 @@ var init_store = __esm({
1873
2023
  init_database();
1874
2024
  init_keychain();
1875
2025
  init_config();
2026
+ init_state_bus();
1876
2027
  INIT_MAX_RETRIES = 3;
1877
2028
  INIT_RETRY_DELAY_MS = 1e3;
1878
2029
  _pendingRecords = [];
@@ -330,6 +330,13 @@ async function ensureSchema() {
330
330
  });
331
331
  } catch {
332
332
  }
333
+ try {
334
+ await client.execute({
335
+ sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
336
+ args: []
337
+ });
338
+ } catch {
339
+ }
333
340
  try {
334
341
  await client.execute({
335
342
  sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
@@ -776,6 +783,18 @@ async function ensureSchema() {
776
783
  CREATE INDEX IF NOT EXISTS idx_session_kills_agent
777
784
  ON session_kills(agent_id);
778
785
  `);
786
+ await client.execute(`
787
+ CREATE TABLE IF NOT EXISTS global_procedures (
788
+ id TEXT PRIMARY KEY,
789
+ title TEXT NOT NULL,
790
+ content TEXT NOT NULL,
791
+ priority TEXT NOT NULL DEFAULT 'p0',
792
+ domain TEXT,
793
+ active INTEGER NOT NULL DEFAULT 1,
794
+ created_at TEXT NOT NULL,
795
+ updated_at TEXT NOT NULL
796
+ )
797
+ `);
779
798
  await client.executeMultiple(`
780
799
  CREATE TABLE IF NOT EXISTS conversations (
781
800
  id TEXT PRIMARY KEY,
@@ -1569,6 +1588,71 @@ var init_shard_manager = __esm({
1569
1588
  }
1570
1589
  });
1571
1590
 
1591
+ // src/lib/global-procedures.ts
1592
+ var global_procedures_exports = {};
1593
+ __export(global_procedures_exports, {
1594
+ deactivateGlobalProcedure: () => deactivateGlobalProcedure,
1595
+ getGlobalProceduresBlock: () => getGlobalProceduresBlock,
1596
+ loadGlobalProcedures: () => loadGlobalProcedures,
1597
+ storeGlobalProcedure: () => storeGlobalProcedure
1598
+ });
1599
+ import { randomUUID } from "crypto";
1600
+ async function loadGlobalProcedures() {
1601
+ const client = getClient();
1602
+ const result = await client.execute({
1603
+ sql: "SELECT * FROM global_procedures WHERE active = 1 ORDER BY priority ASC, created_at ASC",
1604
+ args: []
1605
+ });
1606
+ const procedures = result.rows;
1607
+ if (procedures.length > 0) {
1608
+ _cache = procedures.map((p) => `### ${p.title}
1609
+ ${p.content}`).join("\n\n");
1610
+ } else {
1611
+ _cache = "";
1612
+ }
1613
+ _cacheLoaded = true;
1614
+ return procedures;
1615
+ }
1616
+ function getGlobalProceduresBlock() {
1617
+ if (!_cacheLoaded) return "";
1618
+ if (!_cache) return "";
1619
+ return `## Organization-Wide Procedures (MANDATORY \u2014 supersedes all other rules)
1620
+
1621
+ ${_cache}
1622
+ `;
1623
+ }
1624
+ async function storeGlobalProcedure(input) {
1625
+ const id = randomUUID();
1626
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1627
+ const client = getClient();
1628
+ await client.execute({
1629
+ sql: `INSERT INTO global_procedures (id, title, content, priority, domain, active, created_at, updated_at)
1630
+ VALUES (?, ?, ?, ?, ?, 1, ?, ?)`,
1631
+ args: [id, input.title, input.content, input.priority ?? "p0", input.domain ?? null, now, now]
1632
+ });
1633
+ await loadGlobalProcedures();
1634
+ return id;
1635
+ }
1636
+ async function deactivateGlobalProcedure(id) {
1637
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1638
+ const client = getClient();
1639
+ const result = await client.execute({
1640
+ sql: "UPDATE global_procedures SET active = 0, updated_at = ? WHERE id = ?",
1641
+ args: [now, id]
1642
+ });
1643
+ await loadGlobalProcedures();
1644
+ return result.rowsAffected > 0;
1645
+ }
1646
+ var _cache, _cacheLoaded;
1647
+ var init_global_procedures = __esm({
1648
+ "src/lib/global-procedures.ts"() {
1649
+ "use strict";
1650
+ init_database();
1651
+ _cache = "";
1652
+ _cacheLoaded = false;
1653
+ }
1654
+ });
1655
+
1572
1656
  // src/lib/employees.ts
1573
1657
  import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
1574
1658
  import { existsSync as existsSync5, symlinkSync, readlinkSync, readFileSync as readFileSync3 } from "fs";
@@ -1640,7 +1724,7 @@ var init_employees = __esm({
1640
1724
 
1641
1725
  // src/lib/license.ts
1642
1726
  import { readFileSync as readFileSync4, writeFileSync, existsSync as existsSync6, mkdirSync as mkdirSync2 } from "fs";
1643
- import { randomUUID } from "crypto";
1727
+ import { randomUUID as randomUUID2 } from "crypto";
1644
1728
  import path6 from "path";
1645
1729
  import { jwtVerify, importSPKI } from "jose";
1646
1730
  async function fetchRetry(url, init) {
@@ -1667,7 +1751,7 @@ function loadDeviceId() {
1667
1751
  }
1668
1752
  } catch {
1669
1753
  }
1670
- const id = randomUUID();
1754
+ const id = randomUUID2();
1671
1755
  mkdirSync2(EXE_AI_DIR, { recursive: true });
1672
1756
  writeFileSync(DEVICE_ID_PATH, id, "utf8");
1673
1757
  return id;
@@ -1949,7 +2033,7 @@ var init_plan_limits = __esm({
1949
2033
  // src/lib/exe-daemon-client.ts
1950
2034
  import net from "net";
1951
2035
  import { spawn } from "child_process";
1952
- import { randomUUID as randomUUID2 } from "crypto";
2036
+ import { randomUUID as randomUUID3 } from "crypto";
1953
2037
  import { existsSync as existsSync8, unlinkSync as unlinkSync2, readFileSync as readFileSync6, openSync, closeSync, statSync } from "fs";
1954
2038
  import path8 from "path";
1955
2039
  import { fileURLToPath } from "url";
@@ -2141,7 +2225,7 @@ function sendRequest(texts, priority) {
2141
2225
  resolve({ error: "Not connected" });
2142
2226
  return;
2143
2227
  }
2144
- const id = randomUUID2();
2228
+ const id = randomUUID3();
2145
2229
  const timer = setTimeout(() => {
2146
2230
  _pending.delete(id);
2147
2231
  resolve({ error: "Request timeout" });
@@ -2159,7 +2243,7 @@ function sendRequest(texts, priority) {
2159
2243
  async function pingDaemon() {
2160
2244
  if (!_socket || !_connected) return null;
2161
2245
  return new Promise((resolve) => {
2162
- const id = randomUUID2();
2246
+ const id = randomUUID3();
2163
2247
  const timer = setTimeout(() => {
2164
2248
  _pending.delete(id);
2165
2249
  resolve(null);
@@ -2513,7 +2597,7 @@ async function fetchWithRetry(url, init) {
2513
2597
  try {
2514
2598
  const signal = AbortSignal.timeout(FETCH_TIMEOUT_MS);
2515
2599
  const resp = await fetch(url, { ...init, signal });
2516
- if (resp.status >= 500 && attempt < MAX_RETRIES2) {
2600
+ if (resp && resp.status >= 500 && attempt < MAX_RETRIES2) {
2517
2601
  await new Promise((r) => setTimeout(r, BASE_DELAY_MS2 * Math.pow(2, attempt)));
2518
2602
  continue;
2519
2603
  }
@@ -2557,6 +2641,10 @@ async function cloudPush(records, maxVersion, config) {
2557
2641
  },
2558
2642
  body: JSON.stringify({ version: maxVersion, blob })
2559
2643
  });
2644
+ if (resp == null) {
2645
+ logError("[cloud-sync] PUSH FAILED: no response from server");
2646
+ return false;
2647
+ }
2560
2648
  if (resp.status === 409) {
2561
2649
  logError("[cloud-sync] PUSH VERSION CONFLICT \u2014 re-pull required before next push");
2562
2650
  return false;
@@ -2579,6 +2667,10 @@ async function cloudPull(sinceVersion, config) {
2579
2667
  },
2580
2668
  body: JSON.stringify({ since_version: sinceVersion })
2581
2669
  });
2670
+ if (response == null) {
2671
+ logError("[cloud-sync] PULL FAILED: no response from server");
2672
+ return { records: [], maxVersion: sinceVersion };
2673
+ }
2582
2674
  if (!response.ok) return { records: [], maxVersion: sinceVersion };
2583
2675
  const data = await response.json();
2584
2676
  const allRecords = [];
@@ -3401,6 +3493,57 @@ init_memory();
3401
3493
  init_database();
3402
3494
  init_keychain();
3403
3495
  init_config();
3496
+
3497
+ // src/lib/state-bus.ts
3498
+ var StateBus = class {
3499
+ handlers = /* @__PURE__ */ new Map();
3500
+ globalHandlers = /* @__PURE__ */ new Set();
3501
+ /** Emit an event to all subscribers */
3502
+ emit(event) {
3503
+ const typeHandlers = this.handlers.get(event.type);
3504
+ if (typeHandlers) {
3505
+ for (const handler of typeHandlers) {
3506
+ try {
3507
+ handler(event);
3508
+ } catch {
3509
+ }
3510
+ }
3511
+ }
3512
+ for (const handler of this.globalHandlers) {
3513
+ try {
3514
+ handler(event);
3515
+ } catch {
3516
+ }
3517
+ }
3518
+ }
3519
+ /** Subscribe to a specific event type */
3520
+ on(type, handler) {
3521
+ if (!this.handlers.has(type)) {
3522
+ this.handlers.set(type, /* @__PURE__ */ new Set());
3523
+ }
3524
+ this.handlers.get(type).add(handler);
3525
+ }
3526
+ /** Subscribe to ALL events */
3527
+ onAny(handler) {
3528
+ this.globalHandlers.add(handler);
3529
+ }
3530
+ /** Unsubscribe from a specific event type */
3531
+ off(type, handler) {
3532
+ this.handlers.get(type)?.delete(handler);
3533
+ }
3534
+ /** Unsubscribe from ALL events */
3535
+ offAny(handler) {
3536
+ this.globalHandlers.delete(handler);
3537
+ }
3538
+ /** Remove all listeners */
3539
+ clear() {
3540
+ this.handlers.clear();
3541
+ this.globalHandlers.clear();
3542
+ }
3543
+ };
3544
+ var orgBus = new StateBus();
3545
+
3546
+ // src/lib/store.ts
3404
3547
  var INIT_MAX_RETRIES = 3;
3405
3548
  var INIT_RETRY_DELAY_MS = 1e3;
3406
3549
  function isBusyError2(err) {
@@ -3471,6 +3614,11 @@ async function initStore(options) {
3471
3614
  "version-query"
3472
3615
  );
3473
3616
  _nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
3617
+ try {
3618
+ const { loadGlobalProcedures: loadGlobalProcedures2 } = await Promise.resolve().then(() => (init_global_procedures(), global_procedures_exports));
3619
+ await loadGlobalProcedures2();
3620
+ } catch {
3621
+ }
3474
3622
  }
3475
3623
  function classifyTier(record) {
3476
3624
  if (record.tool_name === "commit_to_long_term_memory" && (record.importance ?? 0) >= 8) return 1;
@@ -3512,6 +3660,12 @@ async function writeMemory(record) {
3512
3660
  supersedes_id: record.supersedes_id ?? null
3513
3661
  };
3514
3662
  _pendingRecords.push(dbRow);
3663
+ orgBus.emit({
3664
+ type: "memory_stored",
3665
+ agentId: record.agent_id,
3666
+ project: record.project_name,
3667
+ timestamp: record.timestamp
3668
+ });
3515
3669
  const MAX_PENDING = 1e3;
3516
3670
  if (_pendingRecords.length > MAX_PENDING) {
3517
3671
  const dropped = _pendingRecords.length - MAX_PENDING;