@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
package/dist/index.js CHANGED
@@ -666,6 +666,13 @@ async function ensureSchema() {
666
666
  });
667
667
  } catch {
668
668
  }
669
+ try {
670
+ await client.execute({
671
+ sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
672
+ args: []
673
+ });
674
+ } catch {
675
+ }
669
676
  try {
670
677
  await client.execute({
671
678
  sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
@@ -1112,6 +1119,18 @@ async function ensureSchema() {
1112
1119
  CREATE INDEX IF NOT EXISTS idx_session_kills_agent
1113
1120
  ON session_kills(agent_id);
1114
1121
  `);
1122
+ await client.execute(`
1123
+ CREATE TABLE IF NOT EXISTS global_procedures (
1124
+ id TEXT PRIMARY KEY,
1125
+ title TEXT NOT NULL,
1126
+ content TEXT NOT NULL,
1127
+ priority TEXT NOT NULL DEFAULT 'p0',
1128
+ domain TEXT,
1129
+ active INTEGER NOT NULL DEFAULT 1,
1130
+ created_at TEXT NOT NULL,
1131
+ updated_at TEXT NOT NULL
1132
+ )
1133
+ `);
1115
1134
  await client.executeMultiple(`
1116
1135
  CREATE TABLE IF NOT EXISTS conversations (
1117
1136
  id TEXT PRIMARY KEY,
@@ -1274,6 +1293,7 @@ var config_exports = {};
1274
1293
  __export(config_exports, {
1275
1294
  CONFIG_MIGRATIONS: () => CONFIG_MIGRATIONS,
1276
1295
  CONFIG_PATH: () => CONFIG_PATH,
1296
+ COO_AGENT_NAME: () => COO_AGENT_NAME,
1277
1297
  CURRENT_CONFIG_VERSION: () => CURRENT_CONFIG_VERSION,
1278
1298
  DB_PATH: () => DB_PATH,
1279
1299
  EXE_AI_DIR: () => EXE_AI_DIR,
@@ -1429,7 +1449,7 @@ async function loadConfigFrom(configPath) {
1429
1449
  return { ...DEFAULT_CONFIG };
1430
1450
  }
1431
1451
  }
1432
- var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
1452
+ var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, COO_AGENT_NAME, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
1433
1453
  var init_config = __esm({
1434
1454
  "src/lib/config.ts"() {
1435
1455
  "use strict";
@@ -1437,6 +1457,7 @@ var init_config = __esm({
1437
1457
  DB_PATH = path4.join(EXE_AI_DIR, "memories.db");
1438
1458
  MODELS_DIR = path4.join(EXE_AI_DIR, "models");
1439
1459
  CONFIG_PATH = path4.join(EXE_AI_DIR, "config.json");
1460
+ COO_AGENT_NAME = "exe";
1440
1461
  LEGACY_LANCE_PATH = path4.join(EXE_AI_DIR, "local.lance");
1441
1462
  CURRENT_CONFIG_VERSION = 1;
1442
1463
  DEFAULT_CONFIG = {
@@ -1734,6 +1755,61 @@ var init_session_kill_telemetry = __esm({
1734
1755
  }
1735
1756
  });
1736
1757
 
1758
+ // src/lib/state-bus.ts
1759
+ var StateBus, orgBus;
1760
+ var init_state_bus = __esm({
1761
+ "src/lib/state-bus.ts"() {
1762
+ "use strict";
1763
+ StateBus = class {
1764
+ handlers = /* @__PURE__ */ new Map();
1765
+ globalHandlers = /* @__PURE__ */ new Set();
1766
+ /** Emit an event to all subscribers */
1767
+ emit(event) {
1768
+ const typeHandlers = this.handlers.get(event.type);
1769
+ if (typeHandlers) {
1770
+ for (const handler of typeHandlers) {
1771
+ try {
1772
+ handler(event);
1773
+ } catch {
1774
+ }
1775
+ }
1776
+ }
1777
+ for (const handler of this.globalHandlers) {
1778
+ try {
1779
+ handler(event);
1780
+ } catch {
1781
+ }
1782
+ }
1783
+ }
1784
+ /** Subscribe to a specific event type */
1785
+ on(type, handler) {
1786
+ if (!this.handlers.has(type)) {
1787
+ this.handlers.set(type, /* @__PURE__ */ new Set());
1788
+ }
1789
+ this.handlers.get(type).add(handler);
1790
+ }
1791
+ /** Subscribe to ALL events */
1792
+ onAny(handler) {
1793
+ this.globalHandlers.add(handler);
1794
+ }
1795
+ /** Unsubscribe from a specific event type */
1796
+ off(type, handler) {
1797
+ this.handlers.get(type)?.delete(handler);
1798
+ }
1799
+ /** Unsubscribe from ALL events */
1800
+ offAny(handler) {
1801
+ this.globalHandlers.delete(handler);
1802
+ }
1803
+ /** Remove all listeners */
1804
+ clear() {
1805
+ this.handlers.clear();
1806
+ this.globalHandlers.clear();
1807
+ }
1808
+ };
1809
+ orgBus = new StateBus();
1810
+ }
1811
+ });
1812
+
1737
1813
  // src/lib/tasks-crud.ts
1738
1814
  import crypto3 from "crypto";
1739
1815
  import path9 from "path";
@@ -1877,9 +1953,15 @@ async function createTaskCore(input) {
1877
1953
  }
1878
1954
  }
1879
1955
  const complexity = input.complexity ?? "standard";
1956
+ let sessionScope = null;
1957
+ try {
1958
+ const { resolveExeSession: resolveExeSession2 } = await Promise.resolve().then(() => (init_tmux_routing(), tmux_routing_exports));
1959
+ sessionScope = resolveExeSession2();
1960
+ } catch {
1961
+ }
1880
1962
  await client.execute({
1881
- sql: `INSERT INTO tasks (id, title, assigned_to, assigned_by, project_name, priority, status, task_file, blocked_by, parent_task_id, reviewer, context, complexity, budget_tokens, budget_fallback_model, tokens_used, tokens_warned_at, created_at, updated_at)
1882
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1963
+ sql: `INSERT INTO tasks (id, title, assigned_to, assigned_by, project_name, priority, status, task_file, blocked_by, parent_task_id, reviewer, context, complexity, budget_tokens, budget_fallback_model, tokens_used, tokens_warned_at, session_scope, created_at, updated_at)
1964
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1883
1965
  args: [
1884
1966
  id,
1885
1967
  input.title,
@@ -1898,6 +1980,7 @@ async function createTaskCore(input) {
1898
1980
  input.budgetFallbackModel ?? null,
1899
1981
  0,
1900
1982
  null,
1983
+ sessionScope,
1901
1984
  now,
1902
1985
  now
1903
1986
  ]
@@ -1942,9 +2025,18 @@ async function listTasks(input) {
1942
2025
  conditions.push("priority = ?");
1943
2026
  args.push(input.priority);
1944
2027
  }
2028
+ try {
2029
+ const { resolveExeSession: resolveExeSession2 } = await Promise.resolve().then(() => (init_tmux_routing(), tmux_routing_exports));
2030
+ const session = resolveExeSession2();
2031
+ if (session) {
2032
+ conditions.push("(session_scope IS NULL OR session_scope = ?)");
2033
+ args.push(session);
2034
+ }
2035
+ } catch {
2036
+ }
1945
2037
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1946
2038
  const result = await client.execute({
1947
- sql: `SELECT * FROM tasks ${where} ORDER BY CASE status WHEN 'blocked' THEN 0 WHEN 'in_progress' THEN 1 WHEN 'open' THEN 2 ELSE 3 END, priority ASC, created_at DESC`,
2039
+ sql: `SELECT * FROM tasks ${where} ORDER BY CASE status WHEN 'blocked' THEN 0 WHEN 'in_progress' THEN 1 WHEN 'open' THEN 2 ELSE 3 END, priority ASC, created_at DESC LIMIT 1000`,
1948
2040
  args
1949
2041
  });
1950
2042
  return result.rows.map((r) => ({
@@ -2165,6 +2257,34 @@ async function listPendingReviews(limit) {
2165
2257
  });
2166
2258
  return result.rows;
2167
2259
  }
2260
+ async function cleanupOrphanedReviews() {
2261
+ const client = getClient();
2262
+ const now = (/* @__PURE__ */ new Date()).toISOString();
2263
+ const r1 = await client.execute({
2264
+ sql: `UPDATE tasks SET status = 'done', updated_at = ?
2265
+ WHERE status = 'needs_review'
2266
+ AND assigned_by = 'system'
2267
+ AND title LIKE 'Review:%'
2268
+ AND parent_task_id IN (SELECT id FROM tasks WHERE status IN ('done', 'cancelled'))`,
2269
+ args: [now]
2270
+ });
2271
+ const staleThreshold = new Date(Date.now() - 60 * 60 * 1e3).toISOString();
2272
+ const r2 = await client.execute({
2273
+ sql: `UPDATE tasks SET status = 'done', updated_at = ?
2274
+ WHERE status = 'needs_review'
2275
+ AND result IS NOT NULL
2276
+ AND updated_at < ?`,
2277
+ args: [now, staleThreshold]
2278
+ });
2279
+ const total = r1.rowsAffected + r2.rowsAffected;
2280
+ if (total > 0) {
2281
+ process.stderr.write(
2282
+ `[cleanup] Closed ${total} orphaned review(s): ${r1.rowsAffected} cascade + ${r2.rowsAffected} stale
2283
+ `
2284
+ );
2285
+ }
2286
+ return total;
2287
+ }
2168
2288
  function getReviewChecklist(role, agent, taskSlug) {
2169
2289
  const roleLower = role.toLowerCase();
2170
2290
  if (roleLower.includes("engineer") || roleLower === "principal engineer") {
@@ -2278,6 +2398,7 @@ var init_tasks_review = __esm({
2278
2398
  init_tasks_crud();
2279
2399
  init_tmux_routing();
2280
2400
  init_session_key();
2401
+ init_state_bus();
2281
2402
  }
2282
2403
  });
2283
2404
 
@@ -2442,13 +2563,12 @@ function assertSessionScope(actionType, targetProject) {
2442
2563
  };
2443
2564
  }
2444
2565
  process.stderr.write(
2445
- `[session-scope] Cross-project ${actionType}: session project="${currentProject}" \u2260 target project="${targetProject}"
2566
+ `[session-scope] BLOCKED cross-project ${actionType}: session project="${currentProject}" \u2260 target project="${targetProject}"
2446
2567
  `
2447
2568
  );
2448
2569
  return {
2449
- allowed: true,
2450
- // v1: warn-only, don't block
2451
- reason: "cross_session_granted",
2570
+ allowed: false,
2571
+ reason: "cross_session_denied",
2452
2572
  currentProject,
2453
2573
  targetProject,
2454
2574
  targetSession: findSessionForProject(targetProject)?.windowName
@@ -2474,8 +2594,9 @@ async function dispatchTaskToEmployee(input) {
2474
2594
  try {
2475
2595
  const { assertSessionScope: assertSessionScope2 } = (init_session_scope(), __toCommonJS(session_scope_exports));
2476
2596
  const check = assertSessionScope2("dispatch_task", input.projectName);
2477
- if (check.reason === "cross_session_granted") {
2597
+ if (check.reason === "cross_session_denied") {
2478
2598
  crossProject = true;
2599
+ return { dispatched: "skipped", crossProject: true };
2479
2600
  }
2480
2601
  } catch {
2481
2602
  }
@@ -2906,6 +3027,7 @@ var init_skill_learning = __esm({
2906
3027
  // src/lib/tasks.ts
2907
3028
  var tasks_exports = {};
2908
3029
  __export(tasks_exports, {
3030
+ cleanupOrphanedReviews: () => cleanupOrphanedReviews,
2909
3031
  countNewPendingReviewsSince: () => countNewPendingReviewsSince,
2910
3032
  countPendingReviews: () => countPendingReviews,
2911
3033
  createTask: () => createTask,
@@ -2971,6 +3093,21 @@ async function updateTask(input) {
2971
3093
  });
2972
3094
  } catch {
2973
3095
  }
3096
+ try {
3097
+ const client = getClient();
3098
+ const cascaded = await client.execute({
3099
+ sql: `UPDATE tasks SET status = 'done', updated_at = ?
3100
+ WHERE parent_task_id = ? AND status = 'needs_review'`,
3101
+ args: [now, taskId]
3102
+ });
3103
+ if (cascaded.rowsAffected > 0) {
3104
+ process.stderr.write(
3105
+ `[cascade] Closed ${cascaded.rowsAffected} orphaned review task(s) for parent ${taskId}
3106
+ `
3107
+ );
3108
+ }
3109
+ } catch {
3110
+ }
2974
3111
  }
2975
3112
  const isTerminal = input.status === "done" || input.status === "needs_review";
2976
3113
  if (isTerminal) {
@@ -2984,6 +3121,13 @@ async function updateTask(input) {
2984
3121
  await cascadeUnblock(taskId, input.baseDir, now);
2985
3122
  } catch {
2986
3123
  }
3124
+ orgBus.emit({
3125
+ type: "task_completed",
3126
+ taskId,
3127
+ employee: String(row.assigned_to),
3128
+ result: input.result ?? "",
3129
+ timestamp: now
3130
+ });
2987
3131
  if (row.parent_task_id) {
2988
3132
  try {
2989
3133
  await checkSubtaskCompletion(String(row.parent_task_id), String(row.project_name));
@@ -3051,6 +3195,7 @@ var init_tasks = __esm({
3051
3195
  init_database();
3052
3196
  init_config();
3053
3197
  init_notifications();
3198
+ init_state_bus();
3054
3199
  init_tasks_crud();
3055
3200
  init_tasks_review();
3056
3201
  init_tasks_crud();
@@ -3441,8 +3586,28 @@ function getMySession() {
3441
3586
  return getTransport().getMySession();
3442
3587
  }
3443
3588
  function employeeSessionName(employee, exeSession, instance) {
3589
+ if (!/^exe\d+$/.test(exeSession)) {
3590
+ const root = extractRootExe(exeSession);
3591
+ if (root) {
3592
+ process.stderr.write(
3593
+ `[tmux-routing] WARN: exeSession="${exeSession}" is not a root exe session, using "${root}" instead
3594
+ `
3595
+ );
3596
+ exeSession = root;
3597
+ } else {
3598
+ throw new Error(
3599
+ `Invalid exeSession "${exeSession}" \u2014 must be a root exe session (e.g., "exe1"), not an agent session`
3600
+ );
3601
+ }
3602
+ }
3444
3603
  const suffix = instance != null && instance > 0 ? String(instance) : "";
3445
- return `${employee}${suffix}-${exeSession}`;
3604
+ const name = `${employee}${suffix}-${exeSession}`;
3605
+ if (!VALID_SESSION_NAME.test(name)) {
3606
+ throw new Error(
3607
+ `Invalid session name "${name}" \u2014 must match {agent}-exe{N} or {agent}{instance}-exe{N}`
3608
+ );
3609
+ }
3610
+ return name;
3446
3611
  }
3447
3612
  function parseParentExe(sessionName, agentId) {
3448
3613
  const escaped = agentId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -3682,6 +3847,22 @@ function ensureEmployee(employeeName, exeSession, projectDir, opts) {
3682
3847
  error: `Error: pass employee name ('${bare}'), not session name ('${employeeName}')`
3683
3848
  };
3684
3849
  }
3850
+ if (!/^exe\d+$/.test(exeSession)) {
3851
+ const root = extractRootExe(exeSession);
3852
+ if (root) {
3853
+ process.stderr.write(
3854
+ `[ensureEmployee] WARN: caller passed exeSession="${exeSession}" (not a root exe). Auto-correcting to "${root}".
3855
+ `
3856
+ );
3857
+ exeSession = root;
3858
+ } else {
3859
+ return {
3860
+ status: "failed",
3861
+ sessionName: "",
3862
+ error: `Invalid exeSession "${exeSession}" \u2014 must be a root exe session (e.g., "exe1")`
3863
+ };
3864
+ }
3865
+ }
3685
3866
  let effectiveInstance = opts?.instance;
3686
3867
  if (effectiveInstance === void 0 && opts?.autoInstance) {
3687
3868
  const free = findFreeInstance(
@@ -3928,7 +4109,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
3928
4109
  releaseSpawnLock(sessionName);
3929
4110
  return { sessionName };
3930
4111
  }
3931
- var SPAWN_LOCK_DIR, SESSION_CACHE, BEHAVIORS_EXPORT_TIMEOUT_MS, VERIFY_PANE_LINES, INTERCOM_DEBOUNCE_MS, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS, BUSY_PATTERN;
4112
+ var SPAWN_LOCK_DIR, SESSION_CACHE, BEHAVIORS_EXPORT_TIMEOUT_MS, VALID_SESSION_NAME, VERIFY_PANE_LINES, INTERCOM_DEBOUNCE_MS, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS, BUSY_PATTERN;
3932
4113
  var init_tmux_routing = __esm({
3933
4114
  "src/lib/tmux-routing.ts"() {
3934
4115
  "use strict";
@@ -3943,6 +4124,7 @@ var init_tmux_routing = __esm({
3943
4124
  SPAWN_LOCK_DIR = path14.join(os6.homedir(), ".exe-os", "spawn-locks");
3944
4125
  SESSION_CACHE = path14.join(os6.homedir(), ".exe-os", "session-cache");
3945
4126
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
4127
+ VALID_SESSION_NAME = /^[a-z]+-exe\d+$|^[a-z]+\d+-exe\d+$/;
3946
4128
  VERIFY_PANE_LINES = 200;
3947
4129
  INTERCOM_DEBOUNCE_MS = 3e4;
3948
4130
  INTERCOM_LOG2 = path14.join(os6.homedir(), ".exe-os", "intercom.log");
@@ -4252,6 +4434,71 @@ var init_shard_manager = __esm({
4252
4434
  }
4253
4435
  });
4254
4436
 
4437
+ // src/lib/global-procedures.ts
4438
+ var global_procedures_exports = {};
4439
+ __export(global_procedures_exports, {
4440
+ deactivateGlobalProcedure: () => deactivateGlobalProcedure,
4441
+ getGlobalProceduresBlock: () => getGlobalProceduresBlock,
4442
+ loadGlobalProcedures: () => loadGlobalProcedures,
4443
+ storeGlobalProcedure: () => storeGlobalProcedure
4444
+ });
4445
+ import { randomUUID as randomUUID3 } from "crypto";
4446
+ async function loadGlobalProcedures() {
4447
+ const client = getClient();
4448
+ const result = await client.execute({
4449
+ sql: "SELECT * FROM global_procedures WHERE active = 1 ORDER BY priority ASC, created_at ASC",
4450
+ args: []
4451
+ });
4452
+ const procedures = result.rows;
4453
+ if (procedures.length > 0) {
4454
+ _cache = procedures.map((p) => `### ${p.title}
4455
+ ${p.content}`).join("\n\n");
4456
+ } else {
4457
+ _cache = "";
4458
+ }
4459
+ _cacheLoaded = true;
4460
+ return procedures;
4461
+ }
4462
+ function getGlobalProceduresBlock() {
4463
+ if (!_cacheLoaded) return "";
4464
+ if (!_cache) return "";
4465
+ return `## Organization-Wide Procedures (MANDATORY \u2014 supersedes all other rules)
4466
+
4467
+ ${_cache}
4468
+ `;
4469
+ }
4470
+ async function storeGlobalProcedure(input) {
4471
+ const id = randomUUID3();
4472
+ const now = (/* @__PURE__ */ new Date()).toISOString();
4473
+ const client = getClient();
4474
+ await client.execute({
4475
+ sql: `INSERT INTO global_procedures (id, title, content, priority, domain, active, created_at, updated_at)
4476
+ VALUES (?, ?, ?, ?, ?, 1, ?, ?)`,
4477
+ args: [id, input.title, input.content, input.priority ?? "p0", input.domain ?? null, now, now]
4478
+ });
4479
+ await loadGlobalProcedures();
4480
+ return id;
4481
+ }
4482
+ async function deactivateGlobalProcedure(id) {
4483
+ const now = (/* @__PURE__ */ new Date()).toISOString();
4484
+ const client = getClient();
4485
+ const result = await client.execute({
4486
+ sql: "UPDATE global_procedures SET active = 0, updated_at = ? WHERE id = ?",
4487
+ args: [now, id]
4488
+ });
4489
+ await loadGlobalProcedures();
4490
+ return result.rowsAffected > 0;
4491
+ }
4492
+ var _cache, _cacheLoaded;
4493
+ var init_global_procedures = __esm({
4494
+ "src/lib/global-procedures.ts"() {
4495
+ "use strict";
4496
+ init_database();
4497
+ _cache = "";
4498
+ _cacheLoaded = false;
4499
+ }
4500
+ });
4501
+
4255
4502
  // src/lib/store.ts
4256
4503
  var store_exports = {};
4257
4504
  __export(store_exports, {
@@ -4331,6 +4578,11 @@ async function initStore(options) {
4331
4578
  "version-query"
4332
4579
  );
4333
4580
  _nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
4581
+ try {
4582
+ const { loadGlobalProcedures: loadGlobalProcedures2 } = await Promise.resolve().then(() => (init_global_procedures(), global_procedures_exports));
4583
+ await loadGlobalProcedures2();
4584
+ } catch {
4585
+ }
4334
4586
  }
4335
4587
  function classifyTier(record) {
4336
4588
  if (record.tool_name === "commit_to_long_term_memory" && (record.importance ?? 0) >= 8) return 1;
@@ -4372,6 +4624,12 @@ async function writeMemory(record) {
4372
4624
  supersedes_id: record.supersedes_id ?? null
4373
4625
  };
4374
4626
  _pendingRecords.push(dbRow);
4627
+ orgBus.emit({
4628
+ type: "memory_stored",
4629
+ agentId: record.agent_id,
4630
+ project: record.project_name,
4631
+ timestamp: record.timestamp
4632
+ });
4375
4633
  const MAX_PENDING = 1e3;
4376
4634
  if (_pendingRecords.length > MAX_PENDING) {
4377
4635
  const dropped = _pendingRecords.length - MAX_PENDING;
@@ -4717,6 +4975,7 @@ var init_store = __esm({
4717
4975
  init_database();
4718
4976
  init_keychain();
4719
4977
  init_config();
4978
+ init_state_bus();
4720
4979
  INIT_MAX_RETRIES = 3;
4721
4980
  INIT_RETRY_DELAY_MS = 1e3;
4722
4981
  _pendingRecords = [];
@@ -5334,7 +5593,7 @@ var init_crm_bridge = __esm({
5334
5593
  // src/lib/exe-daemon-client.ts
5335
5594
  import net from "net";
5336
5595
  import { spawn } from "child_process";
5337
- import { randomUUID as randomUUID5 } from "crypto";
5596
+ import { randomUUID as randomUUID6 } from "crypto";
5338
5597
  import { existsSync as existsSync13, unlinkSync as unlinkSync5, readFileSync as readFileSync10, openSync, closeSync, statSync } from "fs";
5339
5598
  import path17 from "path";
5340
5599
  import { fileURLToPath as fileURLToPath2 } from "url";
@@ -5526,7 +5785,7 @@ function sendRequest(texts, priority) {
5526
5785
  resolve({ error: "Not connected" });
5527
5786
  return;
5528
5787
  }
5529
- const id = randomUUID5();
5788
+ const id = randomUUID6();
5530
5789
  const timer = setTimeout(() => {
5531
5790
  _pending.delete(id);
5532
5791
  resolve({ error: "Request timeout" });
@@ -5544,7 +5803,7 @@ function sendRequest(texts, priority) {
5544
5803
  async function pingDaemon() {
5545
5804
  if (!_socket || !_connected) return null;
5546
5805
  return new Promise((resolve) => {
5547
- const id = randomUUID5();
5806
+ const id = randomUUID6();
5548
5807
  const timer = setTimeout(() => {
5549
5808
  _pending.delete(id);
5550
5809
  resolve(null);
@@ -7838,60 +8097,15 @@ function createQuietRenderer() {
7838
8097
  };
7839
8098
  }
7840
8099
 
7841
- // src/runtime/state-bus.ts
7842
- var StateBus = class {
7843
- handlers = /* @__PURE__ */ new Map();
7844
- globalHandlers = /* @__PURE__ */ new Set();
7845
- /** Emit an event to all subscribers */
7846
- emit(event) {
7847
- const typeHandlers = this.handlers.get(event.type);
7848
- if (typeHandlers) {
7849
- for (const handler of typeHandlers) {
7850
- try {
7851
- handler(event);
7852
- } catch {
7853
- }
7854
- }
7855
- }
7856
- for (const handler of this.globalHandlers) {
7857
- try {
7858
- handler(event);
7859
- } catch {
7860
- }
7861
- }
7862
- }
7863
- /** Subscribe to a specific event type */
7864
- on(type, handler) {
7865
- if (!this.handlers.has(type)) {
7866
- this.handlers.set(type, /* @__PURE__ */ new Set());
7867
- }
7868
- this.handlers.get(type).add(handler);
7869
- }
7870
- /** Subscribe to ALL events */
7871
- onAny(handler) {
7872
- this.globalHandlers.add(handler);
7873
- }
7874
- /** Unsubscribe from a specific event type */
7875
- off(type, handler) {
7876
- this.handlers.get(type)?.delete(handler);
7877
- }
7878
- /** Unsubscribe from ALL events */
7879
- offAny(handler) {
7880
- this.globalHandlers.delete(handler);
7881
- }
7882
- /** Remove all listeners */
7883
- clear() {
7884
- this.handlers.clear();
7885
- this.globalHandlers.clear();
7886
- }
7887
- };
7888
- var orgBus = new StateBus();
8100
+ // src/runtime/index.ts
8101
+ init_state_bus();
7889
8102
 
7890
8103
  // src/runtime/session-manager.ts
7891
- import { randomUUID as randomUUID4 } from "crypto";
8104
+ import { randomUUID as randomUUID5 } from "crypto";
8105
+ init_state_bus();
7892
8106
 
7893
8107
  // src/runtime/exe-hooks.ts
7894
- import { randomUUID as randomUUID3 } from "crypto";
8108
+ import { randomUUID as randomUUID4 } from "crypto";
7895
8109
  function createExeOSHooks(config2) {
7896
8110
  let sessionRegistered = false;
7897
8111
  return {
@@ -7950,7 +8164,7 @@ function createExeOSHooks(config2) {
7950
8164
  const toolResponse = result.isError ? { error: result.content } : { output: result.content };
7951
8165
  const rawText = extractSemanticText2(toolName, toolInput, toolResponse);
7952
8166
  await writeMemory2({
7953
- id: randomUUID3(),
8167
+ id: randomUUID4(),
7954
8168
  agent_id: config2.agentId,
7955
8169
  agent_role: "employee",
7956
8170
  session_id: `api-${config2.agentId}`,
@@ -7973,7 +8187,7 @@ function createExeOSHooks(config2) {
7973
8187
  const { writeMemory: writeMemory2 } = await Promise.resolve().then(() => (init_store(), store_exports));
7974
8188
  if (summary) {
7975
8189
  await writeMemory2({
7976
- id: randomUUID3(),
8190
+ id: randomUUID4(),
7977
8191
  agent_id: config2.agentId,
7978
8192
  agent_role: "employee",
7979
8193
  session_id: `api-${config2.agentId}`,
@@ -8044,7 +8258,7 @@ function createExeOSHooks(config2) {
8044
8258
  await client.execute({
8045
8259
  sql: `INSERT OR IGNORE INTO notifications (id, type, source_agent, message, task_file, created_at, read)
8046
8260
  VALUES (?, 'system', ?, ?, NULL, ?, 0)`,
8047
- args: [randomUUID3(), config2.agentId, message.slice(0, 500), (/* @__PURE__ */ new Date()).toISOString()]
8261
+ args: [randomUUID4(), config2.agentId, message.slice(0, 500), (/* @__PURE__ */ new Date()).toISOString()]
8048
8262
  });
8049
8263
  } catch {
8050
8264
  }
@@ -8060,7 +8274,7 @@ function createExeOSHooks(config2) {
8060
8274
  try {
8061
8275
  const { writeMemory: writeMemory2 } = await Promise.resolve().then(() => (init_store(), store_exports));
8062
8276
  await writeMemory2({
8063
- id: randomUUID3(),
8277
+ id: randomUUID4(),
8064
8278
  agent_id: config2.agentId,
8065
8279
  agent_role: "employee",
8066
8280
  session_id: `api-${config2.agentId}`,
@@ -8082,7 +8296,7 @@ function createExeOSHooks(config2) {
8082
8296
  try {
8083
8297
  const { writeMemory: writeMemory2 } = await Promise.resolve().then(() => (init_store(), store_exports));
8084
8298
  await writeMemory2({
8085
- id: randomUUID3(),
8299
+ id: randomUUID4(),
8086
8300
  agent_id: config2.agentId,
8087
8301
  agent_role: "employee",
8088
8302
  session_id: `api-${config2.agentId}`,
@@ -8119,7 +8333,7 @@ function createExeOSHooks(config2) {
8119
8333
  if (tasks.rows.length > 0) {
8120
8334
  const taskList = tasks.rows.map((r) => `- [${String(r.status)}] ${String(r.title)} (${String(r.task_file)})`).join("\n");
8121
8335
  await writeMemory2({
8122
- id: randomUUID3(),
8336
+ id: randomUUID4(),
8123
8337
  agent_id: config2.agentId,
8124
8338
  agent_role: "employee",
8125
8339
  session_id: `api-${config2.agentId}`,
@@ -8145,7 +8359,7 @@ ${taskList}`,
8145
8359
  try {
8146
8360
  const { writeMemory: writeMemory2 } = await Promise.resolve().then(() => (init_store(), store_exports));
8147
8361
  await writeMemory2({
8148
- id: randomUUID3(),
8362
+ id: randomUUID4(),
8149
8363
  agent_id: config2.agentId,
8150
8364
  agent_role: "employee",
8151
8365
  session_id: `api-${config2.agentId}`,
@@ -8172,7 +8386,7 @@ var SessionManager = class {
8172
8386
  eventHandlers = /* @__PURE__ */ new Set();
8173
8387
  /** Start a new agent session for an employee */
8174
8388
  startSession(employeeId, config2) {
8175
- const sessionId = randomUUID4();
8389
+ const sessionId = randomUUID5();
8176
8390
  const abortController = new AbortController();
8177
8391
  const session = {
8178
8392
  info: {
@@ -8466,6 +8680,9 @@ __export(gateway_exports, {
8466
8680
  validateGatewayConfig: () => validateGatewayConfig
8467
8681
  });
8468
8682
 
8683
+ // src/gateway/gateway.ts
8684
+ init_state_bus();
8685
+
8469
8686
  // src/gateway/router.ts
8470
8687
  function matchesPlatform(msgPlatform, matchPlatform) {
8471
8688
  if (!matchPlatform) return true;
@@ -8902,6 +9119,13 @@ var Gateway = class {
8902
9119
  console.log(
8903
9120
  `[gateway] ${msg.platform}/${msg.senderId} \u2192 ${route.employee} (${route.routeName})`
8904
9121
  );
9122
+ orgBus.emit({
9123
+ type: "gateway_message",
9124
+ platform: msg.platform,
9125
+ senderId: msg.senderId,
9126
+ botId: route.employee,
9127
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
9128
+ });
8905
9129
  const bot = this.botRegistry.get(route.employee);
8906
9130
  if (!bot) {
8907
9131
  console.error(`[gateway] No bot registered for target: ${route.employee}`);
@@ -9695,7 +9919,7 @@ var AnthropicProvider = class {
9695
9919
 
9696
9920
  // src/gateway/providers/openai-compat.ts
9697
9921
  import OpenAI from "openai";
9698
- import { randomUUID as randomUUID6 } from "crypto";
9922
+ import { randomUUID as randomUUID7 } from "crypto";
9699
9923
  var OpenAICompatProvider = class {
9700
9924
  name;
9701
9925
  client;
@@ -9808,7 +10032,7 @@ var OpenAICompatProvider = class {
9808
10032
  }
9809
10033
  content.push({
9810
10034
  type: "tool_use",
9811
- id: call.id ?? randomUUID6(),
10035
+ id: call.id ?? randomUUID7(),
9812
10036
  name: fn.name,
9813
10037
  input
9814
10038
  });
@@ -9830,7 +10054,7 @@ var OpenAICompatProvider = class {
9830
10054
  };
9831
10055
 
9832
10056
  // src/gateway/providers/ollama.ts
9833
- import { randomUUID as randomUUID7 } from "crypto";
10057
+ import { randomUUID as randomUUID8 } from "crypto";
9834
10058
  var OllamaProvider = class {
9835
10059
  name;
9836
10060
  host;
@@ -9899,7 +10123,7 @@ var OllamaProvider = class {
9899
10123
  for (const call of data.message.tool_calls) {
9900
10124
  content.push({
9901
10125
  type: "tool_use",
9902
- id: randomUUID7(),
10126
+ id: randomUUID8(),
9903
10127
  name: call.function.name,
9904
10128
  input: call.function.arguments
9905
10129
  });
@@ -9921,7 +10145,7 @@ var OllamaProvider = class {
9921
10145
  };
9922
10146
 
9923
10147
  // src/gateway/adapters/whatsapp.ts
9924
- import { randomUUID as randomUUID8 } from "crypto";
10148
+ import { randomUUID as randomUUID9 } from "crypto";
9925
10149
  import { homedir } from "os";
9926
10150
  import { join } from "path";
9927
10151
  import { mkdirSync as mkdirSync7 } from "fs";
@@ -10103,7 +10327,7 @@ var WhatsAppAdapter = class {
10103
10327
  const location = this.extractLocation(msg.message);
10104
10328
  const dataCategory = location ? "location" : "message";
10105
10329
  return {
10106
- messageId: msg.key.id ?? randomUUID8(),
10330
+ messageId: msg.key.id ?? randomUUID9(),
10107
10331
  platform: "whatsapp",
10108
10332
  senderId,
10109
10333
  senderName: msg.pushName ?? void 0,
@@ -10148,7 +10372,7 @@ var WhatsAppAdapter = class {
10148
10372
  }
10149
10373
  const timestamp = receipt.readTimestamp ?? receipt.receiptTimestamp ?? Date.now() / 1e3;
10150
10374
  return {
10151
- messageId: randomUUID8(),
10375
+ messageId: randomUUID9(),
10152
10376
  platform: "whatsapp",
10153
10377
  senderId: remoteJid.replace("@s.whatsapp.net", "").replace("@g.us", ""),
10154
10378
  channelId: remoteJid,
@@ -10171,7 +10395,7 @@ var WhatsAppAdapter = class {
10171
10395
  const phone = id.replace("@s.whatsapp.net", "").replace("@g.us", "");
10172
10396
  const name = contact.name ?? contact.notify ?? phone;
10173
10397
  return {
10174
- messageId: randomUUID8(),
10398
+ messageId: randomUUID9(),
10175
10399
  platform: "whatsapp",
10176
10400
  senderId: phone,
10177
10401
  senderName: name,
@@ -10195,7 +10419,7 @@ var WhatsAppAdapter = class {
10195
10419
  const participants = (group.participants ?? []).map((p) => p.id ?? p);
10196
10420
  const admins = (group.participants ?? []).filter((p) => p.admin === "admin" || p.admin === "superadmin").map((p) => p.id ?? p);
10197
10421
  return {
10198
- messageId: randomUUID8(),
10422
+ messageId: randomUUID9(),
10199
10423
  platform: "whatsapp",
10200
10424
  senderId: groupId,
10201
10425
  channelId: groupId,
@@ -10220,7 +10444,7 @@ var WhatsAppAdapter = class {
10220
10444
  if (!reactionData) return null;
10221
10445
  const remoteJid = key.remoteJid ?? "";
10222
10446
  return {
10223
- messageId: randomUUID8(),
10447
+ messageId: randomUUID9(),
10224
10448
  platform: "whatsapp",
10225
10449
  senderId: reactionData.key?.participant ?? reactionData.key?.remoteJid?.replace("@s.whatsapp.net", "") ?? "",
10226
10450
  channelId: remoteJid,
@@ -10242,7 +10466,7 @@ var WhatsAppAdapter = class {
10242
10466
  if (!chatId) return null;
10243
10467
  const caller = call.from?.replace("@s.whatsapp.net", "") ?? "";
10244
10468
  return {
10245
- messageId: randomUUID8(),
10469
+ messageId: randomUUID9(),
10246
10470
  platform: "whatsapp",
10247
10471
  senderId: caller,
10248
10472
  channelId: chatId,
@@ -10285,7 +10509,7 @@ var WhatsAppAdapter = class {
10285
10509
  };
10286
10510
 
10287
10511
  // src/gateway/adapters/signal.ts
10288
- import { randomUUID as randomUUID9 } from "crypto";
10512
+ import { randomUUID as randomUUID10 } from "crypto";
10289
10513
  var DEFAULT_TIMEOUT_MS = 1e4;
10290
10514
  var SignalAdapter = class {
10291
10515
  platform = "signal";
@@ -10370,7 +10594,7 @@ var SignalAdapter = class {
10370
10594
  }
10371
10595
  }
10372
10596
  async rpcRequest(method, params) {
10373
- const id = randomUUID9();
10597
+ const id = randomUUID10();
10374
10598
  const res = await fetch(`${this.baseUrl}/api/v1/rpc`, {
10375
10599
  method: "POST",
10376
10600
  headers: { "Content-Type": "application/json" },
@@ -10460,7 +10684,7 @@ ${val}` : val;
10460
10684
  if (envelope.reactionMessage) {
10461
10685
  const rm = envelope.reactionMessage;
10462
10686
  const normalized2 = {
10463
- messageId: randomUUID9(),
10687
+ messageId: randomUUID10(),
10464
10688
  platform: "signal",
10465
10689
  senderId,
10466
10690
  senderName: envelope.sourceName ?? void 0,
@@ -10488,7 +10712,7 @@ ${val}` : val;
10488
10712
  const rcpt = envelope.receiptMessage;
10489
10713
  for (const ts of rcpt.timestamps) {
10490
10714
  const normalized2 = {
10491
- messageId: randomUUID9(),
10715
+ messageId: randomUUID10(),
10492
10716
  platform: "signal",
10493
10717
  senderId,
10494
10718
  senderName: envelope.sourceName ?? void 0,
@@ -10518,7 +10742,7 @@ ${val}` : val;
10518
10742
  const dm2 = em.dataMessage;
10519
10743
  const isGroup2 = !!dm2.groupInfo?.groupId;
10520
10744
  const normalized2 = {
10521
- messageId: String(dm2.timestamp ?? randomUUID9()),
10745
+ messageId: String(dm2.timestamp ?? randomUUID10()),
10522
10746
  platform: "signal",
10523
10747
  senderId,
10524
10748
  senderName: envelope.sourceName ?? void 0,
@@ -10544,7 +10768,7 @@ ${val}` : val;
10544
10768
  const dm = envelope.dataMessage;
10545
10769
  const isGroup = !!dm.groupInfo?.groupId;
10546
10770
  const normalized = {
10547
- messageId: String(dm.timestamp ?? randomUUID9()),
10771
+ messageId: String(dm.timestamp ?? randomUUID10()),
10548
10772
  platform: "signal",
10549
10773
  senderId,
10550
10774
  senderName: envelope.sourceName ?? void 0,
@@ -10585,7 +10809,7 @@ ${val}` : val;
10585
10809
  if (!phone) continue;
10586
10810
  const name = contact.name ?? contact.profileName ?? phone;
10587
10811
  const normalized = {
10588
- messageId: randomUUID9(),
10812
+ messageId: randomUUID10(),
10589
10813
  platform: "signal",
10590
10814
  senderId: phone,
10591
10815
  senderName: name,
@@ -10614,7 +10838,7 @@ ${val}` : val;
10614
10838
  if (!Array.isArray(groups)) return;
10615
10839
  for (const group of groups) {
10616
10840
  const normalized = {
10617
- messageId: randomUUID9(),
10841
+ messageId: randomUUID10(),
10618
10842
  platform: "signal",
10619
10843
  senderId: `group:${group.id}`,
10620
10844
  channelId: `group:${group.id}`,
@@ -10649,7 +10873,7 @@ ${val}` : val;
10649
10873
  };
10650
10874
 
10651
10875
  // src/gateway/adapters/webchat.ts
10652
- import { randomUUID as randomUUID10 } from "crypto";
10876
+ import { randomUUID as randomUUID11 } from "crypto";
10653
10877
  import { createServer as createServer2 } from "http";
10654
10878
  var WebChatAdapter = class {
10655
10879
  platform = "webchat";
@@ -10745,7 +10969,7 @@ var WebChatAdapter = class {
10745
10969
  res.end(JSON.stringify({ error: "No message text" }));
10746
10970
  return;
10747
10971
  }
10748
- const requestId = randomUUID10();
10972
+ const requestId = randomUUID11();
10749
10973
  const sessionId = parsed.sessionId ?? this.extractSessionId(req);
10750
10974
  const normalized = {
10751
10975
  messageId: requestId,
@@ -10788,7 +11012,7 @@ var WebChatAdapter = class {
10788
11012
  extractSessionId(req) {
10789
11013
  const cookies = req.headers.cookie ?? "";
10790
11014
  const match = cookies.match(/exe_session=([^;]+)/);
10791
- return match?.[1] ?? `anon-${randomUUID10().slice(0, 8)}`;
11015
+ return match?.[1] ?? `anon-${randomUUID11().slice(0, 8)}`;
10792
11016
  }
10793
11017
  };
10794
11018
 
@@ -11070,7 +11294,7 @@ var DiscordAdapter = class {
11070
11294
  };
11071
11295
 
11072
11296
  // src/gateway/adapters/slack.ts
11073
- import { randomUUID as randomUUID11 } from "crypto";
11297
+ import { randomUUID as randomUUID12 } from "crypto";
11074
11298
  var SlackAdapter = class {
11075
11299
  platform = "slack";
11076
11300
  webClient = null;
@@ -11108,7 +11332,7 @@ var SlackAdapter = class {
11108
11332
  if (event.subtype) return;
11109
11333
  const isGroup = event.channel_type !== "im";
11110
11334
  const normalized = {
11111
- messageId: event.client_msg_id ?? event.ts ?? randomUUID11(),
11335
+ messageId: event.client_msg_id ?? event.ts ?? randomUUID12(),
11112
11336
  platform: "slack",
11113
11337
  senderId: event.user ?? "",
11114
11338
  channelId: event.channel ?? "",
@@ -11170,7 +11394,7 @@ var SlackAdapter = class {
11170
11394
  if (!event.text) return;
11171
11395
  const isGroup = event.channel_type !== "im";
11172
11396
  const normalized = {
11173
- messageId: event.ts ?? randomUUID11(),
11397
+ messageId: event.ts ?? randomUUID12(),
11174
11398
  platform: "slack",
11175
11399
  senderId: event.user ?? "",
11176
11400
  senderName: event.user_profile?.display_name ?? event.user_profile?.real_name ?? void 0,
@@ -11555,7 +11779,7 @@ var FailoverExhaustedError = class extends Error {
11555
11779
  };
11556
11780
 
11557
11781
  // src/gateway/session-store.ts
11558
- import { randomUUID as randomUUID12 } from "crypto";
11782
+ import { randomUUID as randomUUID13 } from "crypto";
11559
11783
  var DEFAULT_CONFIG3 = {
11560
11784
  idleTimeoutMs: 30 * 6e4,
11561
11785
  maxMessages: 100
@@ -11582,7 +11806,7 @@ var SessionStore = class {
11582
11806
  existing.status = "closed";
11583
11807
  }
11584
11808
  const session = {
11585
- sessionId: randomUUID12(),
11809
+ sessionId: randomUUID13(),
11586
11810
  customerId,
11587
11811
  botId,
11588
11812
  platform,
@@ -11979,7 +12203,7 @@ function formatAlert(alert) {
11979
12203
  }
11980
12204
 
11981
12205
  // src/gateway/customer-store.ts
11982
- import { randomUUID as randomUUID13 } from "crypto";
12206
+ import { randomUUID as randomUUID14 } from "crypto";
11983
12207
  var CustomerStore = class {
11984
12208
  customers = /* @__PURE__ */ new Map();
11985
12209
  identities = /* @__PURE__ */ new Map();
@@ -11998,7 +12222,7 @@ var CustomerStore = class {
11998
12222
  return customer2;
11999
12223
  }
12000
12224
  const customer = {
12001
- id: randomUUID13(),
12225
+ id: randomUUID14(),
12002
12226
  firstSeenAt: (/* @__PURE__ */ new Date()).toISOString(),
12003
12227
  lastSeenAt: (/* @__PURE__ */ new Date()).toISOString(),
12004
12228
  interactionCount: 1
@@ -12058,7 +12282,7 @@ async function ensureCRMContact(info) {
12058
12282
 
12059
12283
  // src/automation/trigger-engine.ts
12060
12284
  import { readFileSync as readFileSync12, writeFileSync as writeFileSync6, existsSync as existsSync14, mkdirSync as mkdirSync8 } from "fs";
12061
- import { randomUUID as randomUUID14 } from "crypto";
12285
+ import { randomUUID as randomUUID15 } from "crypto";
12062
12286
  import path19 from "path";
12063
12287
  import os9 from "os";
12064
12288
  var TRIGGERS_PATH = path19.join(os9.homedir(), ".exe-os", "triggers.json");