@askexenow/exe-os 0.8.41 → 0.8.43

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 (76) 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 +1345 -660
  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 +2518 -1798
  9. package/dist/bin/exe-call.js +39 -1
  10. package/dist/bin/exe-cloud.js +15 -1
  11. package/dist/bin/exe-dispatch.js +39 -2
  12. package/dist/bin/exe-doctor.js +790 -633
  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 +2500 -1877
  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 +28 -2
  20. package/dist/bin/exe-new-employee.js +25 -3
  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 +147 -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 +154 -3
  27. package/dist/bin/exe-session-cleanup.js +2466 -413
  28. package/dist/bin/exe-status.js +474 -317
  29. package/dist/bin/exe-team.js +474 -317
  30. package/dist/bin/git-sweep.js +2690 -150
  31. package/dist/bin/graph-backfill.js +794 -637
  32. package/dist/bin/graph-export.js +798 -641
  33. package/dist/bin/scan-tasks.js +2951 -44
  34. package/dist/bin/setup.js +62 -26
  35. package/dist/bin/shard-migrate.js +792 -637
  36. package/dist/bin/wiki-sync.js +794 -637
  37. package/dist/gateway/index.js +2504 -1895
  38. package/dist/hooks/bug-report-worker.js +2118 -576
  39. package/dist/hooks/commit-complete.js +2689 -149
  40. package/dist/hooks/error-recall.js +154 -3
  41. package/dist/hooks/ingest-worker.js +1439 -815
  42. package/dist/hooks/instructions-loaded.js +151 -0
  43. package/dist/hooks/notification.js +153 -2
  44. package/dist/hooks/post-compact.js +164 -0
  45. package/dist/hooks/pre-compact.js +3073 -101
  46. package/dist/hooks/pre-tool-use.js +151 -0
  47. package/dist/hooks/prompt-ingest-worker.js +1714 -1537
  48. package/dist/hooks/prompt-submit.js +2658 -1113
  49. package/dist/hooks/response-ingest-worker.js +170 -6
  50. package/dist/hooks/session-end.js +153 -2
  51. package/dist/hooks/session-start.js +154 -3
  52. package/dist/hooks/stop.js +151 -0
  53. package/dist/hooks/subagent-stop.js +151 -0
  54. package/dist/hooks/summary-worker.js +179 -7
  55. package/dist/index.js +278 -100
  56. package/dist/lib/cloud-sync.js +28 -2
  57. package/dist/lib/consolidation.js +69 -2
  58. package/dist/lib/database.js +19 -0
  59. package/dist/lib/device-registry.js +19 -0
  60. package/dist/lib/employee-templates.js +20 -1
  61. package/dist/lib/exe-daemon.js +236 -16
  62. package/dist/lib/hybrid-search.js +154 -3
  63. package/dist/lib/license.js +15 -1
  64. package/dist/lib/messaging.js +39 -2
  65. package/dist/lib/schedules.js +792 -637
  66. package/dist/lib/store.js +796 -636
  67. package/dist/lib/tasks.js +1614 -1091
  68. package/dist/lib/tmux-routing.js +149 -9
  69. package/dist/mcp/server.js +1825 -1138
  70. package/dist/mcp/tools/create-task.js +2280 -828
  71. package/dist/mcp/tools/list-tasks.js +2788 -159
  72. package/dist/mcp/tools/send-message.js +39 -2
  73. package/dist/mcp/tools/update-task.js +64 -0
  74. package/dist/runtime/index.js +235 -67
  75. package/dist/tui/App.js +1452 -644
  76. package/package.json +3 -2
@@ -504,6 +504,13 @@ async function ensureSchema() {
504
504
  });
505
505
  } catch {
506
506
  }
507
+ try {
508
+ await client.execute({
509
+ sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
510
+ args: []
511
+ });
512
+ } catch {
513
+ }
507
514
  try {
508
515
  await client.execute({
509
516
  sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
@@ -950,6 +957,18 @@ async function ensureSchema() {
950
957
  CREATE INDEX IF NOT EXISTS idx_session_kills_agent
951
958
  ON session_kills(agent_id);
952
959
  `);
960
+ await client.execute(`
961
+ CREATE TABLE IF NOT EXISTS global_procedures (
962
+ id TEXT PRIMARY KEY,
963
+ title TEXT NOT NULL,
964
+ content TEXT NOT NULL,
965
+ priority TEXT NOT NULL DEFAULT 'p0',
966
+ domain TEXT,
967
+ active INTEGER NOT NULL DEFAULT 1,
968
+ created_at TEXT NOT NULL,
969
+ updated_at TEXT NOT NULL
970
+ )
971
+ `);
953
972
  await client.executeMultiple(`
954
973
  CREATE TABLE IF NOT EXISTS conversations (
955
974
  id TEXT PRIMARY KEY,
@@ -1166,6 +1185,61 @@ var init_keychain = __esm({
1166
1185
  }
1167
1186
  });
1168
1187
 
1188
+ // src/lib/state-bus.ts
1189
+ var StateBus, orgBus;
1190
+ var init_state_bus = __esm({
1191
+ "src/lib/state-bus.ts"() {
1192
+ "use strict";
1193
+ StateBus = class {
1194
+ handlers = /* @__PURE__ */ new Map();
1195
+ globalHandlers = /* @__PURE__ */ new Set();
1196
+ /** Emit an event to all subscribers */
1197
+ emit(event) {
1198
+ const typeHandlers = this.handlers.get(event.type);
1199
+ if (typeHandlers) {
1200
+ for (const handler of typeHandlers) {
1201
+ try {
1202
+ handler(event);
1203
+ } catch {
1204
+ }
1205
+ }
1206
+ }
1207
+ for (const handler of this.globalHandlers) {
1208
+ try {
1209
+ handler(event);
1210
+ } catch {
1211
+ }
1212
+ }
1213
+ }
1214
+ /** Subscribe to a specific event type */
1215
+ on(type, handler) {
1216
+ if (!this.handlers.has(type)) {
1217
+ this.handlers.set(type, /* @__PURE__ */ new Set());
1218
+ }
1219
+ this.handlers.get(type).add(handler);
1220
+ }
1221
+ /** Subscribe to ALL events */
1222
+ onAny(handler) {
1223
+ this.globalHandlers.add(handler);
1224
+ }
1225
+ /** Unsubscribe from a specific event type */
1226
+ off(type, handler) {
1227
+ this.handlers.get(type)?.delete(handler);
1228
+ }
1229
+ /** Unsubscribe from ALL events */
1230
+ offAny(handler) {
1231
+ this.globalHandlers.delete(handler);
1232
+ }
1233
+ /** Remove all listeners */
1234
+ clear() {
1235
+ this.handlers.clear();
1236
+ this.globalHandlers.clear();
1237
+ }
1238
+ };
1239
+ orgBus = new StateBus();
1240
+ }
1241
+ });
1242
+
1169
1243
  // src/lib/shard-manager.ts
1170
1244
  var shard_manager_exports = {};
1171
1245
  __export(shard_manager_exports, {
@@ -1407,6 +1481,71 @@ var init_shard_manager = __esm({
1407
1481
  }
1408
1482
  });
1409
1483
 
1484
+ // src/lib/global-procedures.ts
1485
+ var global_procedures_exports = {};
1486
+ __export(global_procedures_exports, {
1487
+ deactivateGlobalProcedure: () => deactivateGlobalProcedure,
1488
+ getGlobalProceduresBlock: () => getGlobalProceduresBlock,
1489
+ loadGlobalProcedures: () => loadGlobalProcedures,
1490
+ storeGlobalProcedure: () => storeGlobalProcedure
1491
+ });
1492
+ import { randomUUID } from "crypto";
1493
+ async function loadGlobalProcedures() {
1494
+ const client = getClient();
1495
+ const result = await client.execute({
1496
+ sql: "SELECT * FROM global_procedures WHERE active = 1 ORDER BY priority ASC, created_at ASC",
1497
+ args: []
1498
+ });
1499
+ const procedures = result.rows;
1500
+ if (procedures.length > 0) {
1501
+ _cache = procedures.map((p) => `### ${p.title}
1502
+ ${p.content}`).join("\n\n");
1503
+ } else {
1504
+ _cache = "";
1505
+ }
1506
+ _cacheLoaded = true;
1507
+ return procedures;
1508
+ }
1509
+ function getGlobalProceduresBlock() {
1510
+ if (!_cacheLoaded) return "";
1511
+ if (!_cache) return "";
1512
+ return `## Organization-Wide Procedures (MANDATORY \u2014 supersedes all other rules)
1513
+
1514
+ ${_cache}
1515
+ `;
1516
+ }
1517
+ async function storeGlobalProcedure(input2) {
1518
+ const id = randomUUID();
1519
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1520
+ const client = getClient();
1521
+ await client.execute({
1522
+ sql: `INSERT INTO global_procedures (id, title, content, priority, domain, active, created_at, updated_at)
1523
+ VALUES (?, ?, ?, ?, ?, 1, ?, ?)`,
1524
+ args: [id, input2.title, input2.content, input2.priority ?? "p0", input2.domain ?? null, now, now]
1525
+ });
1526
+ await loadGlobalProcedures();
1527
+ return id;
1528
+ }
1529
+ async function deactivateGlobalProcedure(id) {
1530
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1531
+ const client = getClient();
1532
+ const result = await client.execute({
1533
+ sql: "UPDATE global_procedures SET active = 0, updated_at = ? WHERE id = ?",
1534
+ args: [now, id]
1535
+ });
1536
+ await loadGlobalProcedures();
1537
+ return result.rowsAffected > 0;
1538
+ }
1539
+ var _cache, _cacheLoaded;
1540
+ var init_global_procedures = __esm({
1541
+ "src/lib/global-procedures.ts"() {
1542
+ "use strict";
1543
+ init_database();
1544
+ _cache = "";
1545
+ _cacheLoaded = false;
1546
+ }
1547
+ });
1548
+
1410
1549
  // src/lib/store.ts
1411
1550
  var store_exports = {};
1412
1551
  __export(store_exports, {
@@ -1486,6 +1625,11 @@ async function initStore(options) {
1486
1625
  "version-query"
1487
1626
  );
1488
1627
  _nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
1628
+ try {
1629
+ const { loadGlobalProcedures: loadGlobalProcedures2 } = await Promise.resolve().then(() => (init_global_procedures(), global_procedures_exports));
1630
+ await loadGlobalProcedures2();
1631
+ } catch {
1632
+ }
1489
1633
  }
1490
1634
  function classifyTier(record) {
1491
1635
  if (record.tool_name === "commit_to_long_term_memory" && (record.importance ?? 0) >= 8) return 1;
@@ -1527,6 +1671,12 @@ async function writeMemory(record) {
1527
1671
  supersedes_id: record.supersedes_id ?? null
1528
1672
  };
1529
1673
  _pendingRecords.push(dbRow);
1674
+ orgBus.emit({
1675
+ type: "memory_stored",
1676
+ agentId: record.agent_id,
1677
+ project: record.project_name,
1678
+ timestamp: record.timestamp
1679
+ });
1530
1680
  const MAX_PENDING = 1e3;
1531
1681
  if (_pendingRecords.length > MAX_PENDING) {
1532
1682
  const dropped = _pendingRecords.length - MAX_PENDING;
@@ -1872,6 +2022,7 @@ var init_store = __esm({
1872
2022
  init_database();
1873
2023
  init_keychain();
1874
2024
  init_config();
2025
+ init_state_bus();
1875
2026
  INIT_MAX_RETRIES = 3;
1876
2027
  INIT_RETRY_DELAY_MS = 1e3;
1877
2028
  _pendingRecords = [];
@@ -513,6 +513,13 @@ async function ensureSchema() {
513
513
  });
514
514
  } catch {
515
515
  }
516
+ try {
517
+ await client.execute({
518
+ sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
519
+ args: []
520
+ });
521
+ } catch {
522
+ }
516
523
  try {
517
524
  await client.execute({
518
525
  sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
@@ -959,6 +966,18 @@ async function ensureSchema() {
959
966
  CREATE INDEX IF NOT EXISTS idx_session_kills_agent
960
967
  ON session_kills(agent_id);
961
968
  `);
969
+ await client.execute(`
970
+ CREATE TABLE IF NOT EXISTS global_procedures (
971
+ id TEXT PRIMARY KEY,
972
+ title TEXT NOT NULL,
973
+ content TEXT NOT NULL,
974
+ priority TEXT NOT NULL DEFAULT 'p0',
975
+ domain TEXT,
976
+ active INTEGER NOT NULL DEFAULT 1,
977
+ created_at TEXT NOT NULL,
978
+ updated_at TEXT NOT NULL
979
+ )
980
+ `);
962
981
  await client.executeMultiple(`
963
982
  CREATE TABLE IF NOT EXISTS conversations (
964
983
  id TEXT PRIMARY KEY,
@@ -1166,6 +1185,61 @@ var init_keychain = __esm({
1166
1185
  }
1167
1186
  });
1168
1187
 
1188
+ // src/lib/state-bus.ts
1189
+ var StateBus, orgBus;
1190
+ var init_state_bus = __esm({
1191
+ "src/lib/state-bus.ts"() {
1192
+ "use strict";
1193
+ StateBus = class {
1194
+ handlers = /* @__PURE__ */ new Map();
1195
+ globalHandlers = /* @__PURE__ */ new Set();
1196
+ /** Emit an event to all subscribers */
1197
+ emit(event) {
1198
+ const typeHandlers = this.handlers.get(event.type);
1199
+ if (typeHandlers) {
1200
+ for (const handler of typeHandlers) {
1201
+ try {
1202
+ handler(event);
1203
+ } catch {
1204
+ }
1205
+ }
1206
+ }
1207
+ for (const handler of this.globalHandlers) {
1208
+ try {
1209
+ handler(event);
1210
+ } catch {
1211
+ }
1212
+ }
1213
+ }
1214
+ /** Subscribe to a specific event type */
1215
+ on(type, handler) {
1216
+ if (!this.handlers.has(type)) {
1217
+ this.handlers.set(type, /* @__PURE__ */ new Set());
1218
+ }
1219
+ this.handlers.get(type).add(handler);
1220
+ }
1221
+ /** Subscribe to ALL events */
1222
+ onAny(handler) {
1223
+ this.globalHandlers.add(handler);
1224
+ }
1225
+ /** Unsubscribe from a specific event type */
1226
+ off(type, handler) {
1227
+ this.handlers.get(type)?.delete(handler);
1228
+ }
1229
+ /** Unsubscribe from ALL events */
1230
+ offAny(handler) {
1231
+ this.globalHandlers.delete(handler);
1232
+ }
1233
+ /** Remove all listeners */
1234
+ clear() {
1235
+ this.handlers.clear();
1236
+ this.globalHandlers.clear();
1237
+ }
1238
+ };
1239
+ orgBus = new StateBus();
1240
+ }
1241
+ });
1242
+
1169
1243
  // src/lib/shard-manager.ts
1170
1244
  var shard_manager_exports = {};
1171
1245
  __export(shard_manager_exports, {
@@ -1407,6 +1481,71 @@ var init_shard_manager = __esm({
1407
1481
  }
1408
1482
  });
1409
1483
 
1484
+ // src/lib/global-procedures.ts
1485
+ var global_procedures_exports = {};
1486
+ __export(global_procedures_exports, {
1487
+ deactivateGlobalProcedure: () => deactivateGlobalProcedure,
1488
+ getGlobalProceduresBlock: () => getGlobalProceduresBlock,
1489
+ loadGlobalProcedures: () => loadGlobalProcedures,
1490
+ storeGlobalProcedure: () => storeGlobalProcedure
1491
+ });
1492
+ import { randomUUID } from "crypto";
1493
+ async function loadGlobalProcedures() {
1494
+ const client = getClient();
1495
+ const result = await client.execute({
1496
+ sql: "SELECT * FROM global_procedures WHERE active = 1 ORDER BY priority ASC, created_at ASC",
1497
+ args: []
1498
+ });
1499
+ const procedures = result.rows;
1500
+ if (procedures.length > 0) {
1501
+ _cache = procedures.map((p) => `### ${p.title}
1502
+ ${p.content}`).join("\n\n");
1503
+ } else {
1504
+ _cache = "";
1505
+ }
1506
+ _cacheLoaded = true;
1507
+ return procedures;
1508
+ }
1509
+ function getGlobalProceduresBlock() {
1510
+ if (!_cacheLoaded) return "";
1511
+ if (!_cache) return "";
1512
+ return `## Organization-Wide Procedures (MANDATORY \u2014 supersedes all other rules)
1513
+
1514
+ ${_cache}
1515
+ `;
1516
+ }
1517
+ async function storeGlobalProcedure(input2) {
1518
+ const id = randomUUID();
1519
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1520
+ const client = getClient();
1521
+ await client.execute({
1522
+ sql: `INSERT INTO global_procedures (id, title, content, priority, domain, active, created_at, updated_at)
1523
+ VALUES (?, ?, ?, ?, ?, 1, ?, ?)`,
1524
+ args: [id, input2.title, input2.content, input2.priority ?? "p0", input2.domain ?? null, now, now]
1525
+ });
1526
+ await loadGlobalProcedures();
1527
+ return id;
1528
+ }
1529
+ async function deactivateGlobalProcedure(id) {
1530
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1531
+ const client = getClient();
1532
+ const result = await client.execute({
1533
+ sql: "UPDATE global_procedures SET active = 0, updated_at = ? WHERE id = ?",
1534
+ args: [now, id]
1535
+ });
1536
+ await loadGlobalProcedures();
1537
+ return result.rowsAffected > 0;
1538
+ }
1539
+ var _cache, _cacheLoaded;
1540
+ var init_global_procedures = __esm({
1541
+ "src/lib/global-procedures.ts"() {
1542
+ "use strict";
1543
+ init_database();
1544
+ _cache = "";
1545
+ _cacheLoaded = false;
1546
+ }
1547
+ });
1548
+
1410
1549
  // src/lib/store.ts
1411
1550
  var store_exports = {};
1412
1551
  __export(store_exports, {
@@ -1486,6 +1625,11 @@ async function initStore(options) {
1486
1625
  "version-query"
1487
1626
  );
1488
1627
  _nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
1628
+ try {
1629
+ const { loadGlobalProcedures: loadGlobalProcedures2 } = await Promise.resolve().then(() => (init_global_procedures(), global_procedures_exports));
1630
+ await loadGlobalProcedures2();
1631
+ } catch {
1632
+ }
1489
1633
  }
1490
1634
  function classifyTier(record) {
1491
1635
  if (record.tool_name === "commit_to_long_term_memory" && (record.importance ?? 0) >= 8) return 1;
@@ -1527,6 +1671,12 @@ async function writeMemory(record) {
1527
1671
  supersedes_id: record.supersedes_id ?? null
1528
1672
  };
1529
1673
  _pendingRecords.push(dbRow);
1674
+ orgBus.emit({
1675
+ type: "memory_stored",
1676
+ agentId: record.agent_id,
1677
+ project: record.project_name,
1678
+ timestamp: record.timestamp
1679
+ });
1530
1680
  const MAX_PENDING = 1e3;
1531
1681
  if (_pendingRecords.length > MAX_PENDING) {
1532
1682
  const dropped = _pendingRecords.length - MAX_PENDING;
@@ -1872,6 +2022,7 @@ var init_store = __esm({
1872
2022
  init_database();
1873
2023
  init_keychain();
1874
2024
  init_config();
2025
+ init_state_bus();
1875
2026
  INIT_MAX_RETRIES = 3;
1876
2027
  INIT_RETRY_DELAY_MS = 1e3;
1877
2028
  _pendingRecords = [];
@@ -1998,13 +2149,13 @@ process.stdin.on("end", async () => {
1998
2149
  const { initStore: initStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
1999
2150
  await initStore2();
2000
2151
  const { getClient: getClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
2001
- const { randomUUID } = await import("crypto");
2152
+ const { randomUUID: randomUUID2 } = await import("crypto");
2002
2153
  const client = getClient2();
2003
2154
  await client.execute({
2004
2155
  sql: `INSERT OR IGNORE INTO notifications (id, type, source_agent, message, task_file, created_at, read)
2005
2156
  VALUES (?, 'system', ?, ?, NULL, ?, 0)`,
2006
2157
  args: [
2007
- randomUUID(),
2158
+ randomUUID2(),
2008
2159
  agent.agentId,
2009
2160
  data.message.slice(0, 500),
2010
2161
  (/* @__PURE__ */ new Date()).toISOString()
@@ -513,6 +513,13 @@ async function ensureSchema() {
513
513
  });
514
514
  } catch {
515
515
  }
516
+ try {
517
+ await client.execute({
518
+ sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
519
+ args: []
520
+ });
521
+ } catch {
522
+ }
516
523
  try {
517
524
  await client.execute({
518
525
  sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
@@ -959,6 +966,18 @@ async function ensureSchema() {
959
966
  CREATE INDEX IF NOT EXISTS idx_session_kills_agent
960
967
  ON session_kills(agent_id);
961
968
  `);
969
+ await client.execute(`
970
+ CREATE TABLE IF NOT EXISTS global_procedures (
971
+ id TEXT PRIMARY KEY,
972
+ title TEXT NOT NULL,
973
+ content TEXT NOT NULL,
974
+ priority TEXT NOT NULL DEFAULT 'p0',
975
+ domain TEXT,
976
+ active INTEGER NOT NULL DEFAULT 1,
977
+ created_at TEXT NOT NULL,
978
+ updated_at TEXT NOT NULL
979
+ )
980
+ `);
962
981
  await client.executeMultiple(`
963
982
  CREATE TABLE IF NOT EXISTS conversations (
964
983
  id TEXT PRIMARY KEY,
@@ -1166,6 +1185,61 @@ var init_keychain = __esm({
1166
1185
  }
1167
1186
  });
1168
1187
 
1188
+ // src/lib/state-bus.ts
1189
+ var StateBus, orgBus;
1190
+ var init_state_bus = __esm({
1191
+ "src/lib/state-bus.ts"() {
1192
+ "use strict";
1193
+ StateBus = class {
1194
+ handlers = /* @__PURE__ */ new Map();
1195
+ globalHandlers = /* @__PURE__ */ new Set();
1196
+ /** Emit an event to all subscribers */
1197
+ emit(event) {
1198
+ const typeHandlers = this.handlers.get(event.type);
1199
+ if (typeHandlers) {
1200
+ for (const handler of typeHandlers) {
1201
+ try {
1202
+ handler(event);
1203
+ } catch {
1204
+ }
1205
+ }
1206
+ }
1207
+ for (const handler of this.globalHandlers) {
1208
+ try {
1209
+ handler(event);
1210
+ } catch {
1211
+ }
1212
+ }
1213
+ }
1214
+ /** Subscribe to a specific event type */
1215
+ on(type, handler) {
1216
+ if (!this.handlers.has(type)) {
1217
+ this.handlers.set(type, /* @__PURE__ */ new Set());
1218
+ }
1219
+ this.handlers.get(type).add(handler);
1220
+ }
1221
+ /** Subscribe to ALL events */
1222
+ onAny(handler) {
1223
+ this.globalHandlers.add(handler);
1224
+ }
1225
+ /** Unsubscribe from a specific event type */
1226
+ off(type, handler) {
1227
+ this.handlers.get(type)?.delete(handler);
1228
+ }
1229
+ /** Unsubscribe from ALL events */
1230
+ offAny(handler) {
1231
+ this.globalHandlers.delete(handler);
1232
+ }
1233
+ /** Remove all listeners */
1234
+ clear() {
1235
+ this.handlers.clear();
1236
+ this.globalHandlers.clear();
1237
+ }
1238
+ };
1239
+ orgBus = new StateBus();
1240
+ }
1241
+ });
1242
+
1169
1243
  // src/lib/shard-manager.ts
1170
1244
  var shard_manager_exports = {};
1171
1245
  __export(shard_manager_exports, {
@@ -1407,6 +1481,71 @@ var init_shard_manager = __esm({
1407
1481
  }
1408
1482
  });
1409
1483
 
1484
+ // src/lib/global-procedures.ts
1485
+ var global_procedures_exports = {};
1486
+ __export(global_procedures_exports, {
1487
+ deactivateGlobalProcedure: () => deactivateGlobalProcedure,
1488
+ getGlobalProceduresBlock: () => getGlobalProceduresBlock,
1489
+ loadGlobalProcedures: () => loadGlobalProcedures,
1490
+ storeGlobalProcedure: () => storeGlobalProcedure
1491
+ });
1492
+ import { randomUUID } from "crypto";
1493
+ async function loadGlobalProcedures() {
1494
+ const client = getClient();
1495
+ const result = await client.execute({
1496
+ sql: "SELECT * FROM global_procedures WHERE active = 1 ORDER BY priority ASC, created_at ASC",
1497
+ args: []
1498
+ });
1499
+ const procedures = result.rows;
1500
+ if (procedures.length > 0) {
1501
+ _cache = procedures.map((p) => `### ${p.title}
1502
+ ${p.content}`).join("\n\n");
1503
+ } else {
1504
+ _cache = "";
1505
+ }
1506
+ _cacheLoaded = true;
1507
+ return procedures;
1508
+ }
1509
+ function getGlobalProceduresBlock() {
1510
+ if (!_cacheLoaded) return "";
1511
+ if (!_cache) return "";
1512
+ return `## Organization-Wide Procedures (MANDATORY \u2014 supersedes all other rules)
1513
+
1514
+ ${_cache}
1515
+ `;
1516
+ }
1517
+ async function storeGlobalProcedure(input2) {
1518
+ const id = randomUUID();
1519
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1520
+ const client = getClient();
1521
+ await client.execute({
1522
+ sql: `INSERT INTO global_procedures (id, title, content, priority, domain, active, created_at, updated_at)
1523
+ VALUES (?, ?, ?, ?, ?, 1, ?, ?)`,
1524
+ args: [id, input2.title, input2.content, input2.priority ?? "p0", input2.domain ?? null, now, now]
1525
+ });
1526
+ await loadGlobalProcedures();
1527
+ return id;
1528
+ }
1529
+ async function deactivateGlobalProcedure(id) {
1530
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1531
+ const client = getClient();
1532
+ const result = await client.execute({
1533
+ sql: "UPDATE global_procedures SET active = 0, updated_at = ? WHERE id = ?",
1534
+ args: [now, id]
1535
+ });
1536
+ await loadGlobalProcedures();
1537
+ return result.rowsAffected > 0;
1538
+ }
1539
+ var _cache, _cacheLoaded;
1540
+ var init_global_procedures = __esm({
1541
+ "src/lib/global-procedures.ts"() {
1542
+ "use strict";
1543
+ init_database();
1544
+ _cache = "";
1545
+ _cacheLoaded = false;
1546
+ }
1547
+ });
1548
+
1410
1549
  // src/lib/store.ts
1411
1550
  var store_exports = {};
1412
1551
  __export(store_exports, {
@@ -1486,6 +1625,11 @@ async function initStore(options) {
1486
1625
  "version-query"
1487
1626
  );
1488
1627
  _nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
1628
+ try {
1629
+ const { loadGlobalProcedures: loadGlobalProcedures2 } = await Promise.resolve().then(() => (init_global_procedures(), global_procedures_exports));
1630
+ await loadGlobalProcedures2();
1631
+ } catch {
1632
+ }
1489
1633
  }
1490
1634
  function classifyTier(record) {
1491
1635
  if (record.tool_name === "commit_to_long_term_memory" && (record.importance ?? 0) >= 8) return 1;
@@ -1527,6 +1671,12 @@ async function writeMemory(record) {
1527
1671
  supersedes_id: record.supersedes_id ?? null
1528
1672
  };
1529
1673
  _pendingRecords.push(dbRow);
1674
+ orgBus.emit({
1675
+ type: "memory_stored",
1676
+ agentId: record.agent_id,
1677
+ project: record.project_name,
1678
+ timestamp: record.timestamp
1679
+ });
1530
1680
  const MAX_PENDING = 1e3;
1531
1681
  if (_pendingRecords.length > MAX_PENDING) {
1532
1682
  const dropped = _pendingRecords.length - MAX_PENDING;
@@ -1872,6 +2022,7 @@ var init_store = __esm({
1872
2022
  init_database();
1873
2023
  init_keychain();
1874
2024
  init_config();
2025
+ init_state_bus();
1875
2026
  INIT_MAX_RETRIES = 3;
1876
2027
  INIT_RETRY_DELAY_MS = 1e3;
1877
2028
  _pendingRecords = [];
@@ -2008,6 +2159,19 @@ process.stdin.on("end", async () => {
2008
2159
  sections.push(`## Active Tasks (restored after compaction)
2009
2160
  ${taskLines}`);
2010
2161
  }
2162
+ const fiveMinAgo = new Date(Date.now() - 5 * 60 * 1e3).toISOString();
2163
+ const recoveryResult = await client.execute({
2164
+ sql: `SELECT raw_text FROM memories
2165
+ WHERE agent_id = ? AND tool_name = 'pre-compact-hook'
2166
+ AND raw_text LIKE '[COMPACTION RECOVERY]%'
2167
+ AND timestamp >= ?
2168
+ ORDER BY timestamp DESC LIMIT 1`,
2169
+ args: [agent.agentId, fiveMinAgo]
2170
+ });
2171
+ if (recoveryResult.rows.length > 0) {
2172
+ sections.push(`## Recovery Context (from pre-compaction checkpoint)
2173
+ ${String(recoveryResult.rows[0].raw_text)}`);
2174
+ }
2011
2175
  }
2012
2176
  const behaviors = await client.execute({
2013
2177
  sql: `SELECT domain, content FROM behaviors