@askexenow/exe-os 0.9.32 → 0.9.34

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 (75) hide show
  1. package/dist/bin/backfill-conversations.js +18 -2
  2. package/dist/bin/backfill-responses.js +18 -2
  3. package/dist/bin/backfill-vectors.js +18 -2
  4. package/dist/bin/cleanup-stale-review-tasks.js +18 -2
  5. package/dist/bin/cli.js +43 -11
  6. package/dist/bin/exe-assign.js +18 -2
  7. package/dist/bin/exe-boot.js +32 -10
  8. package/dist/bin/exe-cloud.js +3 -3
  9. package/dist/bin/exe-dispatch.js +21 -4
  10. package/dist/bin/exe-doctor.js +45 -21
  11. package/dist/bin/exe-export-behaviors.js +18 -2
  12. package/dist/bin/exe-forget.js +27 -8
  13. package/dist/bin/exe-gateway.js +21 -4
  14. package/dist/bin/exe-heartbeat.js +18 -2
  15. package/dist/bin/exe-kill.js +18 -2
  16. package/dist/bin/exe-launch-agent.js +34 -2
  17. package/dist/bin/exe-link.js +20 -5
  18. package/dist/bin/exe-pending-messages.js +18 -2
  19. package/dist/bin/exe-pending-notifications.js +18 -2
  20. package/dist/bin/exe-pending-reviews.js +18 -2
  21. package/dist/bin/exe-rename.js +18 -2
  22. package/dist/bin/exe-review.js +18 -2
  23. package/dist/bin/exe-search.js +18 -2
  24. package/dist/bin/exe-session-cleanup.js +21 -4
  25. package/dist/bin/exe-settings.js +1 -1
  26. package/dist/bin/exe-start-codex.js +42 -7
  27. package/dist/bin/exe-start-opencode.js +34 -2
  28. package/dist/bin/exe-status.js +18 -2
  29. package/dist/bin/exe-team.js +18 -2
  30. package/dist/bin/git-sweep.js +21 -4
  31. package/dist/bin/graph-backfill.js +18 -2
  32. package/dist/bin/graph-export.js +18 -2
  33. package/dist/bin/intercom-check.js +21 -4
  34. package/dist/bin/scan-tasks.js +21 -4
  35. package/dist/bin/setup.js +24 -9
  36. package/dist/bin/shard-migrate.js +18 -2
  37. package/dist/gateway/index.js +21 -4
  38. package/dist/hooks/bug-report-worker.js +21 -4
  39. package/dist/hooks/codex-stop-task-finalizer.js +21 -4
  40. package/dist/hooks/commit-complete.js +21 -4
  41. package/dist/hooks/error-recall.js +27 -2
  42. package/dist/hooks/exe-heartbeat-hook.js +9 -0
  43. package/dist/hooks/ingest.js +27 -2
  44. package/dist/hooks/instructions-loaded.js +27 -2
  45. package/dist/hooks/notification.js +27 -2
  46. package/dist/hooks/post-compact.js +30 -3
  47. package/dist/hooks/post-tool-combined.js +34 -2
  48. package/dist/hooks/pre-compact.js +33 -5
  49. package/dist/hooks/pre-tool-use.js +30 -3
  50. package/dist/hooks/prompt-submit.js +33 -5
  51. package/dist/hooks/session-end.js +33 -5
  52. package/dist/hooks/session-start.js +34 -2
  53. package/dist/hooks/stop.js +30 -3
  54. package/dist/hooks/subagent-stop.js +30 -3
  55. package/dist/hooks/summary-worker.js +22 -7
  56. package/dist/index.js +21 -4
  57. package/dist/lib/cloud-sync.js +20 -5
  58. package/dist/lib/database.js +17 -1
  59. package/dist/lib/db.js +17 -1
  60. package/dist/lib/device-registry.js +18 -2
  61. package/dist/lib/exe-daemon.js +20243 -6717
  62. package/dist/lib/hybrid-search.js +18 -2
  63. package/dist/lib/schedules.js +18 -2
  64. package/dist/lib/store.js +18 -2
  65. package/dist/lib/tasks.js +3 -2
  66. package/dist/lib/tmux-routing.js +3 -2
  67. package/dist/mcp/server.js +213 -167
  68. package/dist/mcp/tools/create-task.js +15 -3
  69. package/dist/mcp/tools/deactivate-behavior.js +9 -0
  70. package/dist/mcp/tools/list-tasks.js +12 -1
  71. package/dist/mcp/tools/send-message.js +12 -1
  72. package/dist/mcp/tools/update-task.js +19 -2
  73. package/dist/runtime/index.js +21 -4
  74. package/dist/tui/App.js +21 -4
  75. package/package.json +1 -1
@@ -2093,6 +2093,7 @@ var init_db_daemon_client = __esm({
2093
2093
  // src/lib/database.ts
2094
2094
  var database_exports = {};
2095
2095
  __export(database_exports, {
2096
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
2096
2097
  disposeDatabase: () => disposeDatabase,
2097
2098
  disposeTurso: () => disposeTurso,
2098
2099
  ensureSchema: () => ensureSchema,
@@ -2249,10 +2250,17 @@ async function ensureSchema() {
2249
2250
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2250
2251
  END;
2251
2252
 
2252
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
2253
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
2254
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
2253
2255
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2254
2256
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
2255
2257
  END;
2258
+
2259
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
2260
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
2261
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
2262
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2263
+ END;
2256
2264
  `);
2257
2265
  await client.executeMultiple(`
2258
2266
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2655,6 +2663,13 @@ async function ensureSchema() {
2655
2663
  });
2656
2664
  } catch {
2657
2665
  }
2666
+ try {
2667
+ await client.execute({
2668
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2669
+ args: []
2670
+ });
2671
+ } catch {
2672
+ }
2658
2673
  try {
2659
2674
  await client.execute({
2660
2675
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -3191,7 +3206,7 @@ async function disposeDatabase() {
3191
3206
  _resilientClient = null;
3192
3207
  }
3193
3208
  }
3194
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
3209
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
3195
3210
  var init_database = __esm({
3196
3211
  "src/lib/database.ts"() {
3197
3212
  "use strict";
@@ -3205,6 +3220,7 @@ var init_database = __esm({
3205
3220
  _daemonClient = null;
3206
3221
  _adapterClient = null;
3207
3222
  initTurso = initDatabase;
3223
+ SOFT_DELETE_RETENTION_DAYS = 7;
3208
3224
  disposeTurso = disposeDatabase;
3209
3225
  }
3210
3226
  });
@@ -6487,6 +6503,19 @@ var init_session_key = __esm({
6487
6503
  }
6488
6504
  });
6489
6505
 
6506
+ // src/mcp/agent-context.ts
6507
+ import { AsyncLocalStorage } from "async_hooks";
6508
+ function getAgentContext() {
6509
+ return agentStore.getStore();
6510
+ }
6511
+ var agentStore;
6512
+ var init_agent_context = __esm({
6513
+ "src/mcp/agent-context.ts"() {
6514
+ "use strict";
6515
+ agentStore = new AsyncLocalStorage();
6516
+ }
6517
+ });
6518
+
6490
6519
  // src/lib/active-agent.ts
6491
6520
  var active_agent_exports = {};
6492
6521
  __export(active_agent_exports, {
@@ -6562,6 +6591,8 @@ function clearActiveAgent() {
6562
6591
  }
6563
6592
  }
6564
6593
  function getActiveAgent() {
6594
+ const httpCtx = getAgentContext();
6595
+ if (httpCtx) return httpCtx;
6565
6596
  try {
6566
6597
  const markerPath = getMarkerPath();
6567
6598
  const raw = readFileSync7(markerPath, "utf8");
@@ -6656,6 +6687,7 @@ var init_active_agent = __esm({
6656
6687
  "use strict";
6657
6688
  init_config();
6658
6689
  init_session_key();
6690
+ init_agent_context();
6659
6691
  init_employees();
6660
6692
  CACHE_DIR = path12.join(EXE_AI_DIR, "session-cache");
6661
6693
  STALE_MS = 24 * 60 * 60 * 1e3;
@@ -6923,8 +6955,8 @@ async function validateLicense(apiKey, deviceId) {
6923
6955
  }
6924
6956
  function getCacheAgeMs() {
6925
6957
  try {
6926
- const { statSync: statSync5 } = __require("fs");
6927
- const s = statSync5(CACHE_PATH);
6958
+ const { statSync: statSync6 } = __require("fs");
6959
+ const s = statSync6(CACHE_PATH);
6928
6960
  return Date.now() - s.mtimeMs;
6929
6961
  } catch {
6930
6962
  return Infinity;
@@ -10441,9 +10473,10 @@ async function updateTask(input) {
10441
10473
  args: [assignedAgent]
10442
10474
  });
10443
10475
  } else if (input.status === "cancelled") {
10476
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
10444
10477
  await draftClient.execute({
10445
- sql: `DELETE FROM memories WHERE agent_id = ? AND draft = 1`,
10446
- args: [assignedAgent]
10478
+ sql: `UPDATE memories SET status = 'deleted', deleted_at = ? WHERE agent_id = ? AND draft = 1`,
10479
+ args: [now2, assignedAgent]
10447
10480
  });
10448
10481
  }
10449
10482
  } catch {
@@ -14429,13 +14462,14 @@ async function listDocumentsByWorkspace(workspace_id, limit = DEFAULT_LIST_LIMIT
14429
14462
  async function deleteDocumentAndChunks(id) {
14430
14463
  const client = getClient();
14431
14464
  const countResult = await client.execute({
14432
- sql: "SELECT COUNT(*) AS cnt FROM memories WHERE document_id = ?",
14465
+ sql: "SELECT COUNT(*) AS cnt FROM memories WHERE document_id = ? AND COALESCE(status, 'active') = 'active'",
14433
14466
  args: [id]
14434
14467
  });
14435
14468
  const deletedChunks = Number(countResult.rows[0]?.cnt) || 0;
14469
+ const now = (/* @__PURE__ */ new Date()).toISOString();
14436
14470
  await client.batch(
14437
14471
  [
14438
- { sql: "DELETE FROM memories WHERE document_id = ?", args: [id] },
14472
+ { sql: "UPDATE memories SET status = 'deleted', deleted_at = ? WHERE document_id = ? AND COALESCE(status, 'active') = 'active'", args: [now, id] },
14439
14473
  { sql: "DELETE FROM documents WHERE id = ?", args: [id] }
14440
14474
  ],
14441
14475
  "write"
@@ -20074,9 +20108,9 @@ async function auditDuplicates(client, flags) {
20074
20108
  const { clause, args } = agentFilter(flags);
20075
20109
  const backfillExclude = clause ? " AND tool_name != 'ConversationBackfill'" : " WHERE tool_name != 'ConversationBackfill'";
20076
20110
  const groups = await client.execute({
20077
- sql: `SELECT raw_text, COUNT(*) as cnt
20111
+ sql: `SELECT SUBSTR(raw_text, 1, 200) as text_head, LENGTH(raw_text) as text_len, COUNT(*) as cnt
20078
20112
  FROM memories${clause}${backfillExclude}
20079
- GROUP BY raw_text
20113
+ GROUP BY text_head, text_len
20080
20114
  HAVING cnt > 1
20081
20115
  ORDER BY cnt DESC
20082
20116
  LIMIT 500`,
@@ -20084,23 +20118,33 @@ async function auditDuplicates(client, flags) {
20084
20118
  });
20085
20119
  const duplicates = [];
20086
20120
  for (const g of groups.rows) {
20087
- const text = g.raw_text;
20088
- const cnt = Number(g.cnt);
20089
- const filterArgs = [text, ...args];
20090
- let filterClause = " WHERE raw_text = ?";
20121
+ const textHead = g.text_head;
20122
+ const textLen = Number(g.text_len);
20123
+ const filterArgs = [textHead, textLen, ...args];
20124
+ let filterClause = " WHERE SUBSTR(raw_text, 1, 200) = ? AND LENGTH(raw_text) = ?";
20091
20125
  if (flags.agent) filterClause += " AND agent_id = ?";
20092
20126
  if (flags.project) filterClause += " AND project_name = ?";
20093
20127
  const ids = await client.execute({
20094
- sql: `SELECT id FROM memories${filterClause} ORDER BY timestamp DESC LIMIT 10000`,
20128
+ sql: `SELECT id, raw_text FROM memories${filterClause} ORDER BY timestamp DESC LIMIT 10000`,
20095
20129
  args: filterArgs
20096
20130
  });
20097
- const allIds = ids.rows.map((r) => r.id);
20098
- duplicates.push({
20099
- raw_text: text.length > 100 ? text.slice(0, 100) + "..." : text,
20100
- count: cnt,
20101
- keep_id: allIds[0],
20102
- delete_ids: allIds.slice(1)
20103
- });
20131
+ const byText = /* @__PURE__ */ new Map();
20132
+ for (const r of ids.rows) {
20133
+ const text = r.raw_text;
20134
+ const id = r.id;
20135
+ const existing = byText.get(text);
20136
+ if (existing) existing.push(id);
20137
+ else byText.set(text, [id]);
20138
+ }
20139
+ for (const [text, allIds] of byText) {
20140
+ if (allIds.length <= 1) continue;
20141
+ duplicates.push({
20142
+ raw_text: text.length > 100 ? text.slice(0, 100) + "..." : text,
20143
+ count: allIds.length,
20144
+ keep_id: allIds[0],
20145
+ delete_ids: allIds.slice(1)
20146
+ });
20147
+ }
20104
20148
  }
20105
20149
  return duplicates;
20106
20150
  }
@@ -20394,15 +20438,13 @@ async function fixDuplicates(client, duplicates, dryRun) {
20394
20438
  continue;
20395
20439
  }
20396
20440
  const placeholders = dup.delete_ids.map(() => "?").join(",");
20441
+ const now = (/* @__PURE__ */ new Date()).toISOString();
20397
20442
  await client.execute({
20398
- sql: `DELETE FROM memories WHERE id IN (${placeholders})`,
20399
- args: dup.delete_ids
20443
+ sql: `UPDATE memories SET status = 'deleted', deleted_at = ? WHERE id IN (${placeholders})`,
20444
+ args: [now, ...dup.delete_ids]
20400
20445
  });
20401
20446
  deleted += dup.delete_ids.length;
20402
20447
  }
20403
- if (!dryRun && deleted > 0) {
20404
- await client.execute("INSERT INTO memories_fts(memories_fts) VALUES('rebuild')");
20405
- }
20406
20448
  return deleted;
20407
20449
  }
20408
20450
  async function fixBloated(client, bloated, dryRun) {
@@ -20584,7 +20626,7 @@ import { z as z63 } from "zod";
20584
20626
 
20585
20627
  // src/lib/cloud-sync.ts
20586
20628
  init_database();
20587
- import { readFileSync as readFileSync26, writeFileSync as writeFileSync20, existsSync as existsSync32, readdirSync as readdirSync13, mkdirSync as mkdirSync17, appendFileSync as appendFileSync2, unlinkSync as unlinkSync11, openSync as openSync2, closeSync as closeSync2 } from "fs";
20629
+ import { readFileSync as readFileSync26, writeFileSync as writeFileSync20, existsSync as existsSync32, readdirSync as readdirSync13, mkdirSync as mkdirSync17, appendFileSync as appendFileSync2, unlinkSync as unlinkSync11, openSync as openSync2, closeSync as closeSync2, statSync as statSync5 } from "fs";
20588
20630
  import crypto17 from "crypto";
20589
20631
  import path40 from "path";
20590
20632
  import { homedir as homedir6 } from "os";
@@ -21149,10 +21191,9 @@ async function cloudSync(config2) {
21149
21191
  const totalMemories = await countRows("SELECT COUNT(*) as cnt FROM memories WHERE status = 'active' OR status IS NULL");
21150
21192
  try {
21151
21193
  const { getLatestBackup: getLatestBackup2 } = await Promise.resolve().then(() => (init_db_backup(), db_backup_exports));
21152
- const { statSync: statFile } = await import("fs");
21153
21194
  const latestBackup = getLatestBackup2();
21154
21195
  if (latestBackup) {
21155
- const backupSize = statFile(latestBackup).size;
21196
+ const backupSize = statSync5(latestBackup).size;
21156
21197
  const MAX_CLOUD_BACKUP_BYTES = 50 * 1024 * 1024;
21157
21198
  if (backupSize <= MAX_CLOUD_BACKUP_BYTES) {
21158
21199
  const backupData = readFileSync26(latestBackup);
@@ -23281,62 +23322,6 @@ function registerQueryCompanyBrain(server2) {
23281
23322
  );
23282
23323
  }
23283
23324
 
23284
- // src/lib/telemetry.ts
23285
- var ENABLED = process.env.EXE_TELEMETRY === "1";
23286
- var initialized = false;
23287
- async function ensureInit() {
23288
- if (initialized || !ENABLED) return;
23289
- initialized = true;
23290
- try {
23291
- const { NodeSDK } = await import("@opentelemetry/sdk-node");
23292
- const { ConsoleSpanExporter } = await import("@opentelemetry/sdk-trace-base");
23293
- const sdk = new NodeSDK({
23294
- serviceName: "exe-os",
23295
- traceExporter: new ConsoleSpanExporter()
23296
- });
23297
- sdk.start();
23298
- process.stderr.write("[exe-os] OpenTelemetry tracing enabled\n");
23299
- } catch (err) {
23300
- process.stderr.write(
23301
- `[exe-os] OpenTelemetry init failed: ${err instanceof Error ? err.message : String(err)}
23302
- `
23303
- );
23304
- }
23305
- }
23306
- async function withTrace(toolName, fn) {
23307
- if (!ENABLED) return fn();
23308
- await ensureInit();
23309
- const { trace, SpanStatusCode } = await import("@opentelemetry/api");
23310
- const tracer = trace.getTracer("exe-os", "1.0.0");
23311
- return tracer.startActiveSpan(`mcp.tool.${toolName}`, async (span) => {
23312
- span.setAttribute("mcp.tool.name", toolName);
23313
- try {
23314
- const result = await fn();
23315
- span.setStatus({ code: SpanStatusCode.OK });
23316
- return result;
23317
- } catch (err) {
23318
- span.setStatus({
23319
- code: SpanStatusCode.ERROR,
23320
- message: err instanceof Error ? err.message : String(err)
23321
- });
23322
- span.recordException(
23323
- err instanceof Error ? err : new Error(String(err))
23324
- );
23325
- throw err;
23326
- } finally {
23327
- span.end();
23328
- }
23329
- });
23330
- }
23331
- function instrumentServer(server2) {
23332
- if (!ENABLED) return;
23333
- const original = server2.registerTool.bind(server2);
23334
- server2.registerTool = (name, config2, handler) => {
23335
- const traced = async (...args) => withTrace(name, () => handler(...args));
23336
- return original(name, config2, traced);
23337
- };
23338
- }
23339
-
23340
23325
  // src/mcp/tool-gates.ts
23341
23326
  var TOOL_GATES = {
23342
23327
  core: [],
@@ -23469,6 +23454,147 @@ function isToolAllowed(registerFnName) {
23469
23454
  return allowedRoles.includes(role);
23470
23455
  }
23471
23456
 
23457
+ // src/mcp/register-tools.ts
23458
+ function registerAllTools(server2) {
23459
+ const gate = (name, fn) => {
23460
+ if (isToolAllowed(name)) fn(server2);
23461
+ };
23462
+ gate("registerRecallMyMemory", registerRecallMyMemory);
23463
+ gate("registerAskTeamMemory", registerAskTeamMemory);
23464
+ gate("registerGetSessionContext", registerGetSessionContext);
23465
+ gate("registerStoreMemory", registerStoreMemory);
23466
+ gate("registerCommitMemory", registerCommitMemory);
23467
+ gate("registerQueryRelationships", registerQueryRelationships);
23468
+ gate("registerCreateTask", registerCreateTask);
23469
+ gate("registerListTasks", registerListTasks);
23470
+ gate("registerUpdateTask", registerUpdateTask);
23471
+ gate("registerCloseTask", registerCloseTask);
23472
+ gate("registerGetTask", registerGetTask);
23473
+ gate("registerCheckpointTask", registerCheckpointTask);
23474
+ gate("registerResumeEmployee", registerResumeEmployee);
23475
+ gate("registerBehavior", registerBehavior);
23476
+ gate("registerSendMessage", registerSendMessage);
23477
+ gate("registerReminder", registerReminder);
23478
+ gate("registerGetIdentity", registerGetIdentity);
23479
+ gate("registerUpdateIdentity", registerUpdateIdentity);
23480
+ gate("registerIngestDocument", registerIngestDocument);
23481
+ gate("registerListDocuments", registerListDocuments);
23482
+ gate("registerPurgeDocument", registerPurgeDocument);
23483
+ gate("registerSetDocumentImportance", registerSetDocumentImportance);
23484
+ gate("registerRerankDocuments", registerRerankDocuments);
23485
+ gate("registerAcknowledgeMessages", registerAcknowledgeMessages);
23486
+ gate("registerSendWhatsapp", registerSendWhatsapp);
23487
+ gate("registerCreateTrigger", registerCreateTrigger);
23488
+ gate("registerListTriggers", registerListTriggers);
23489
+ gate("registerApplyStarterPack", registerApplyStarterPack);
23490
+ gate("registerMergeEntities", registerMergeEntities);
23491
+ gate("registerCreateWikiPage", registerCreateWikiPage);
23492
+ gate("registerListWikiPages", registerListWikiPages);
23493
+ gate("registerGetWikiPage", registerGetWikiPage);
23494
+ gate("registerUpdateWikiPage", registerUpdateWikiPage);
23495
+ gate("registerDeployClient", registerDeployClient);
23496
+ gate("registerExportOrchestration", registerExportOrchestration);
23497
+ gate("registerImportOrchestration", registerImportOrchestration);
23498
+ gate("registerQueryConversations", registerQueryConversations);
23499
+ gate("registerLoadSkill", registerLoadSkill);
23500
+ gate("registerConsolidateMemories", registerConsolidateMemories);
23501
+ gate("registerGlobalProcedure", registerGlobalProcedure);
23502
+ gate("registerStoreGlobalProcedure", registerStoreGlobalProcedure);
23503
+ gate("registerListGlobalProcedures", registerListGlobalProcedures);
23504
+ gate("registerDeactivateGlobalProcedure", registerDeactivateGlobalProcedure);
23505
+ gate("registerStoreBehavior", registerStoreBehavior);
23506
+ gate("registerListBehaviors", registerListBehaviors);
23507
+ gate("registerDeactivateBehavior", registerDeactivateBehavior);
23508
+ gate("registerCreateReminder", registerCreateReminder);
23509
+ gate("registerListReminders", registerListReminders);
23510
+ gate("registerCompleteReminder", registerCompleteReminder);
23511
+ gate("registerSearchEverything", registerSearchEverything);
23512
+ gate("registerStoreDecision", registerStoreDecision);
23513
+ gate("registerGetDecision", registerGetDecision);
23514
+ gate("registerGetAgentSpend", registerGetAgentSpend);
23515
+ gate("registerGetGraphStats", registerGetGraphStats);
23516
+ gate("registerGetEntityNeighbors", registerGetEntityNeighbors);
23517
+ gate("registerGetHotEntities", registerGetHotEntities);
23518
+ gate("registerExportGraph", registerExportGraph);
23519
+ gate("registerFindSimilarTrajectories", registerFindSimilarTrajectories);
23520
+ gate("registerGetSessionKills", registerGetSessionKills);
23521
+ gate("registerListAgentSessions", registerListAgentSessions);
23522
+ gate("registerGetDaemonHealth", registerGetDaemonHealth);
23523
+ gate("registerGetAutoWakeStatus", registerGetAutoWakeStatus);
23524
+ gate("registerGetWorkerGate", registerGetWorkerGate);
23525
+ gate("registerRunMemoryAudit", registerRunMemoryAudit);
23526
+ gate("registerCloudSync", registerCloudSync);
23527
+ gate("registerBackupVps", registerBackupVps);
23528
+ gate("registerGetMemoryCardinality", registerGetMemoryCardinality);
23529
+ gate("registerRunConsolidation", registerRunConsolidation);
23530
+ gate("registerGetLicenseStatus", registerGetLicenseStatus);
23531
+ gate("registerAddPerson", registerAddPerson);
23532
+ gate("registerListPeople", registerListPeople);
23533
+ gate("registerGetPerson", registerGetPerson);
23534
+ gate("registerSetAgentConfig", registerSetAgentConfig);
23535
+ gate("registerListEmployees", registerListEmployees);
23536
+ gate("registerCreateLicense", registerCreateLicense);
23537
+ gate("registerListLicenses", registerListLicenses);
23538
+ gate("registerActivateLicense", registerActivateLicense);
23539
+ gate("registerQueryCompanyBrain", registerQueryCompanyBrain);
23540
+ }
23541
+
23542
+ // src/lib/telemetry.ts
23543
+ var ENABLED = process.env.EXE_TELEMETRY === "1";
23544
+ var initialized = false;
23545
+ async function ensureInit() {
23546
+ if (initialized || !ENABLED) return;
23547
+ initialized = true;
23548
+ try {
23549
+ const { NodeSDK } = await import("@opentelemetry/sdk-node");
23550
+ const { ConsoleSpanExporter } = await import("@opentelemetry/sdk-trace-base");
23551
+ const sdk = new NodeSDK({
23552
+ serviceName: "exe-os",
23553
+ traceExporter: new ConsoleSpanExporter()
23554
+ });
23555
+ sdk.start();
23556
+ process.stderr.write("[exe-os] OpenTelemetry tracing enabled\n");
23557
+ } catch (err) {
23558
+ process.stderr.write(
23559
+ `[exe-os] OpenTelemetry init failed: ${err instanceof Error ? err.message : String(err)}
23560
+ `
23561
+ );
23562
+ }
23563
+ }
23564
+ async function withTrace(toolName, fn) {
23565
+ if (!ENABLED) return fn();
23566
+ await ensureInit();
23567
+ const { trace, SpanStatusCode } = await import("@opentelemetry/api");
23568
+ const tracer = trace.getTracer("exe-os", "1.0.0");
23569
+ return tracer.startActiveSpan(`mcp.tool.${toolName}`, async (span) => {
23570
+ span.setAttribute("mcp.tool.name", toolName);
23571
+ try {
23572
+ const result = await fn();
23573
+ span.setStatus({ code: SpanStatusCode.OK });
23574
+ return result;
23575
+ } catch (err) {
23576
+ span.setStatus({
23577
+ code: SpanStatusCode.ERROR,
23578
+ message: err instanceof Error ? err.message : String(err)
23579
+ });
23580
+ span.recordException(
23581
+ err instanceof Error ? err : new Error(String(err))
23582
+ );
23583
+ throw err;
23584
+ } finally {
23585
+ span.end();
23586
+ }
23587
+ });
23588
+ }
23589
+ function instrumentServer(server2) {
23590
+ if (!ENABLED) return;
23591
+ const original = server2.registerTool.bind(server2);
23592
+ server2.registerTool = (name, config2, handler) => {
23593
+ const traced = async (...args) => withTrace(name, () => handler(...args));
23594
+ return original(name, config2, traced);
23595
+ };
23596
+ }
23597
+
23472
23598
  // src/mcp/server.ts
23473
23599
  var server = new McpServer({
23474
23600
  name: "exe-os",
@@ -23478,87 +23604,7 @@ var _backfillTimer = null;
23478
23604
  var _ppidWatchdog = null;
23479
23605
  var _shuttingDown = false;
23480
23606
  instrumentServer(server);
23481
- var gate = (name, fn) => {
23482
- if (isToolAllowed(name)) fn(server);
23483
- };
23484
- gate("registerRecallMyMemory", registerRecallMyMemory);
23485
- gate("registerAskTeamMemory", registerAskTeamMemory);
23486
- gate("registerGetSessionContext", registerGetSessionContext);
23487
- gate("registerStoreMemory", registerStoreMemory);
23488
- gate("registerCommitMemory", registerCommitMemory);
23489
- gate("registerQueryRelationships", registerQueryRelationships);
23490
- gate("registerCreateTask", registerCreateTask);
23491
- gate("registerListTasks", registerListTasks);
23492
- gate("registerUpdateTask", registerUpdateTask);
23493
- gate("registerCloseTask", registerCloseTask);
23494
- gate("registerGetTask", registerGetTask);
23495
- gate("registerCheckpointTask", registerCheckpointTask);
23496
- gate("registerResumeEmployee", registerResumeEmployee);
23497
- gate("registerBehavior", registerBehavior);
23498
- gate("registerSendMessage", registerSendMessage);
23499
- gate("registerReminder", registerReminder);
23500
- gate("registerGetIdentity", registerGetIdentity);
23501
- gate("registerUpdateIdentity", registerUpdateIdentity);
23502
- gate("registerIngestDocument", registerIngestDocument);
23503
- gate("registerListDocuments", registerListDocuments);
23504
- gate("registerPurgeDocument", registerPurgeDocument);
23505
- gate("registerSetDocumentImportance", registerSetDocumentImportance);
23506
- gate("registerRerankDocuments", registerRerankDocuments);
23507
- gate("registerAcknowledgeMessages", registerAcknowledgeMessages);
23508
- gate("registerSendWhatsapp", registerSendWhatsapp);
23509
- gate("registerCreateTrigger", registerCreateTrigger);
23510
- gate("registerListTriggers", registerListTriggers);
23511
- gate("registerApplyStarterPack", registerApplyStarterPack);
23512
- gate("registerMergeEntities", registerMergeEntities);
23513
- gate("registerCreateWikiPage", registerCreateWikiPage);
23514
- gate("registerListWikiPages", registerListWikiPages);
23515
- gate("registerGetWikiPage", registerGetWikiPage);
23516
- gate("registerUpdateWikiPage", registerUpdateWikiPage);
23517
- gate("registerDeployClient", registerDeployClient);
23518
- gate("registerExportOrchestration", registerExportOrchestration);
23519
- gate("registerImportOrchestration", registerImportOrchestration);
23520
- gate("registerQueryConversations", registerQueryConversations);
23521
- gate("registerLoadSkill", registerLoadSkill);
23522
- gate("registerConsolidateMemories", registerConsolidateMemories);
23523
- gate("registerGlobalProcedure", registerGlobalProcedure);
23524
- gate("registerStoreGlobalProcedure", registerStoreGlobalProcedure);
23525
- gate("registerListGlobalProcedures", registerListGlobalProcedures);
23526
- gate("registerDeactivateGlobalProcedure", registerDeactivateGlobalProcedure);
23527
- gate("registerStoreBehavior", registerStoreBehavior);
23528
- gate("registerListBehaviors", registerListBehaviors);
23529
- gate("registerDeactivateBehavior", registerDeactivateBehavior);
23530
- gate("registerCreateReminder", registerCreateReminder);
23531
- gate("registerListReminders", registerListReminders);
23532
- gate("registerCompleteReminder", registerCompleteReminder);
23533
- gate("registerSearchEverything", registerSearchEverything);
23534
- gate("registerStoreDecision", registerStoreDecision);
23535
- gate("registerGetDecision", registerGetDecision);
23536
- gate("registerGetAgentSpend", registerGetAgentSpend);
23537
- gate("registerGetGraphStats", registerGetGraphStats);
23538
- gate("registerGetEntityNeighbors", registerGetEntityNeighbors);
23539
- gate("registerGetHotEntities", registerGetHotEntities);
23540
- gate("registerExportGraph", registerExportGraph);
23541
- gate("registerFindSimilarTrajectories", registerFindSimilarTrajectories);
23542
- gate("registerGetSessionKills", registerGetSessionKills);
23543
- gate("registerListAgentSessions", registerListAgentSessions);
23544
- gate("registerGetDaemonHealth", registerGetDaemonHealth);
23545
- gate("registerGetAutoWakeStatus", registerGetAutoWakeStatus);
23546
- gate("registerGetWorkerGate", registerGetWorkerGate);
23547
- gate("registerRunMemoryAudit", registerRunMemoryAudit);
23548
- gate("registerCloudSync", registerCloudSync);
23549
- gate("registerBackupVps", registerBackupVps);
23550
- gate("registerGetMemoryCardinality", registerGetMemoryCardinality);
23551
- gate("registerRunConsolidation", registerRunConsolidation);
23552
- gate("registerGetLicenseStatus", registerGetLicenseStatus);
23553
- gate("registerAddPerson", registerAddPerson);
23554
- gate("registerListPeople", registerListPeople);
23555
- gate("registerGetPerson", registerGetPerson);
23556
- gate("registerSetAgentConfig", registerSetAgentConfig);
23557
- gate("registerListEmployees", registerListEmployees);
23558
- gate("registerCreateLicense", registerCreateLicense);
23559
- gate("registerListLicenses", registerListLicenses);
23560
- gate("registerActivateLicense", registerActivateLicense);
23561
- gate("registerQueryCompanyBrain", registerQueryCompanyBrain);
23607
+ registerAllTools(server);
23562
23608
  var _gatedRole = process.env.AGENT_ROLE ?? "standalone";
23563
23609
  process.stderr.write(`[exe-os] Tool gating: role=${_gatedRole}
23564
23610
  `);
@@ -4659,9 +4659,10 @@ async function updateTask(input) {
4659
4659
  args: [assignedAgent]
4660
4660
  });
4661
4661
  } else if (input.status === "cancelled") {
4662
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
4662
4663
  await draftClient.execute({
4663
- sql: `DELETE FROM memories WHERE agent_id = ? AND draft = 1`,
4664
- args: [assignedAgent]
4664
+ sql: `UPDATE memories SET status = 'deleted', deleted_at = ? WHERE agent_id = ? AND draft = 1`,
4665
+ args: [now2, assignedAgent]
4665
4666
  });
4666
4667
  }
4667
4668
  } catch {
@@ -5465,10 +5466,19 @@ import { z } from "zod";
5465
5466
  // src/lib/active-agent.ts
5466
5467
  init_config();
5467
5468
  init_session_key();
5468
- init_employees();
5469
5469
  import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, mkdirSync as mkdirSync7, unlinkSync as unlinkSync7, readdirSync as readdirSync4 } from "fs";
5470
5470
  import { execSync as execSync7 } from "child_process";
5471
5471
  import path18 from "path";
5472
+
5473
+ // src/mcp/agent-context.ts
5474
+ import { AsyncLocalStorage } from "async_hooks";
5475
+ var agentStore = new AsyncLocalStorage();
5476
+ function getAgentContext() {
5477
+ return agentStore.getStore();
5478
+ }
5479
+
5480
+ // src/lib/active-agent.ts
5481
+ init_employees();
5472
5482
  var CACHE_DIR = path18.join(EXE_AI_DIR, "session-cache");
5473
5483
  var STALE_MS = 24 * 60 * 60 * 1e3;
5474
5484
  function isNameWithOptionalInstance(candidate, baseName) {
@@ -5517,6 +5527,8 @@ function getMarkerPath() {
5517
5527
  return path18.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
5518
5528
  }
5519
5529
  function getActiveAgent() {
5530
+ const httpCtx = getAgentContext();
5531
+ if (httpCtx) return httpCtx;
5520
5532
  try {
5521
5533
  const markerPath = getMarkerPath();
5522
5534
  const raw = readFileSync13(markerPath, "utf8");
@@ -276,6 +276,13 @@ function getSessionKey() {
276
276
  return _cached;
277
277
  }
278
278
 
279
+ // src/mcp/agent-context.ts
280
+ import { AsyncLocalStorage } from "async_hooks";
281
+ var agentStore = new AsyncLocalStorage();
282
+ function getAgentContext() {
283
+ return agentStore.getStore();
284
+ }
285
+
279
286
  // src/lib/active-agent.ts
280
287
  var CACHE_DIR = path4.join(EXE_AI_DIR, "session-cache");
281
288
  var STALE_MS = 24 * 60 * 60 * 1e3;
@@ -325,6 +332,8 @@ function getMarkerPath() {
325
332
  return path4.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
326
333
  }
327
334
  function getActiveAgent() {
335
+ const httpCtx = getAgentContext();
336
+ if (httpCtx) return httpCtx;
328
337
  try {
329
338
  const markerPath = getMarkerPath();
330
339
  const raw = readFileSync3(markerPath, "utf8");
@@ -905,10 +905,19 @@ import { z } from "zod";
905
905
  // src/lib/active-agent.ts
906
906
  init_config();
907
907
  init_session_key();
908
- init_employees();
909
908
  import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, unlinkSync as unlinkSync5, readdirSync as readdirSync4 } from "fs";
910
909
  import { execSync as execSync6 } from "child_process";
911
910
  import path16 from "path";
911
+
912
+ // src/mcp/agent-context.ts
913
+ import { AsyncLocalStorage } from "async_hooks";
914
+ var agentStore = new AsyncLocalStorage();
915
+ function getAgentContext() {
916
+ return agentStore.getStore();
917
+ }
918
+
919
+ // src/lib/active-agent.ts
920
+ init_employees();
912
921
  var CACHE_DIR = path16.join(EXE_AI_DIR, "session-cache");
913
922
  var STALE_MS = 24 * 60 * 60 * 1e3;
914
923
  function isNameWithOptionalInstance(candidate, baseName) {
@@ -957,6 +966,8 @@ function getMarkerPath() {
957
966
  return path16.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
958
967
  }
959
968
  function getActiveAgent() {
969
+ const httpCtx = getAgentContext();
970
+ if (httpCtx) return httpCtx;
960
971
  try {
961
972
  const markerPath = getMarkerPath();
962
973
  const raw = readFileSync10(markerPath, "utf8");
@@ -1052,10 +1052,19 @@ async function markFailed(messageId, reason, sessionScope) {
1052
1052
  // src/lib/active-agent.ts
1053
1053
  init_config();
1054
1054
  init_session_key();
1055
- init_employees();
1056
1055
  import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, unlinkSync as unlinkSync2, readdirSync as readdirSync2 } from "fs";
1057
1056
  import { execSync as execSync4 } from "child_process";
1058
1057
  import path10 from "path";
1058
+
1059
+ // src/mcp/agent-context.ts
1060
+ import { AsyncLocalStorage } from "async_hooks";
1061
+ var agentStore = new AsyncLocalStorage();
1062
+ function getAgentContext() {
1063
+ return agentStore.getStore();
1064
+ }
1065
+
1066
+ // src/lib/active-agent.ts
1067
+ init_employees();
1059
1068
  var CACHE_DIR = path10.join(EXE_AI_DIR, "session-cache");
1060
1069
  var STALE_MS = 24 * 60 * 60 * 1e3;
1061
1070
  function isNameWithOptionalInstance(candidate, baseName) {
@@ -1104,6 +1113,8 @@ function getMarkerPath() {
1104
1113
  return path10.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
1105
1114
  }
1106
1115
  function getActiveAgent() {
1116
+ const httpCtx = getAgentContext();
1117
+ if (httpCtx) return httpCtx;
1107
1118
  try {
1108
1119
  const markerPath = getMarkerPath();
1109
1120
  const raw = readFileSync8(markerPath, "utf8");