@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
@@ -1827,6 +1827,7 @@ var init_db_daemon_client = __esm({
1827
1827
  // src/lib/database.ts
1828
1828
  var database_exports = {};
1829
1829
  __export(database_exports, {
1830
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
1830
1831
  disposeDatabase: () => disposeDatabase,
1831
1832
  disposeTurso: () => disposeTurso,
1832
1833
  ensureSchema: () => ensureSchema,
@@ -1983,10 +1984,17 @@ async function ensureSchema() {
1983
1984
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1984
1985
  END;
1985
1986
 
1986
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
1987
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
1988
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
1987
1989
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1988
1990
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
1989
1991
  END;
1992
+
1993
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
1994
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
1995
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
1996
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1997
+ END;
1990
1998
  `);
1991
1999
  await client.executeMultiple(`
1992
2000
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2389,6 +2397,13 @@ async function ensureSchema() {
2389
2397
  });
2390
2398
  } catch {
2391
2399
  }
2400
+ try {
2401
+ await client.execute({
2402
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2403
+ args: []
2404
+ });
2405
+ } catch {
2406
+ }
2392
2407
  try {
2393
2408
  await client.execute({
2394
2409
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -2925,7 +2940,7 @@ async function disposeDatabase() {
2925
2940
  _resilientClient = null;
2926
2941
  }
2927
2942
  }
2928
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
2943
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
2929
2944
  var init_database = __esm({
2930
2945
  "src/lib/database.ts"() {
2931
2946
  "use strict";
@@ -2939,6 +2954,7 @@ var init_database = __esm({
2939
2954
  _daemonClient = null;
2940
2955
  _adapterClient = null;
2941
2956
  initTurso = initDatabase;
2957
+ SOFT_DELETE_RETENTION_DAYS = 7;
2942
2958
  disposeTurso = disposeDatabase;
2943
2959
  }
2944
2960
  });
@@ -6442,6 +6458,19 @@ var init_session_key = __esm({
6442
6458
  }
6443
6459
  });
6444
6460
 
6461
+ // src/mcp/agent-context.ts
6462
+ import { AsyncLocalStorage } from "async_hooks";
6463
+ function getAgentContext() {
6464
+ return agentStore.getStore();
6465
+ }
6466
+ var agentStore;
6467
+ var init_agent_context = __esm({
6468
+ "src/mcp/agent-context.ts"() {
6469
+ "use strict";
6470
+ agentStore = new AsyncLocalStorage();
6471
+ }
6472
+ });
6473
+
6445
6474
  // src/lib/active-agent.ts
6446
6475
  import { readFileSync as readFileSync7, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, unlinkSync as unlinkSync4, readdirSync as readdirSync3 } from "fs";
6447
6476
  import { execSync as execSync6 } from "child_process";
@@ -6508,6 +6537,8 @@ function clearActiveAgent() {
6508
6537
  }
6509
6538
  }
6510
6539
  function getActiveAgent() {
6540
+ const httpCtx = getAgentContext();
6541
+ if (httpCtx) return httpCtx;
6511
6542
  try {
6512
6543
  const markerPath = getMarkerPath();
6513
6544
  const raw = readFileSync7(markerPath, "utf8");
@@ -6602,6 +6633,7 @@ var init_active_agent = __esm({
6602
6633
  "use strict";
6603
6634
  init_config();
6604
6635
  init_session_key();
6636
+ init_agent_context();
6605
6637
  init_employees();
6606
6638
  CACHE_DIR = path12.join(EXE_AI_DIR, "session-cache");
6607
6639
  STALE_MS = 24 * 60 * 60 * 1e3;
@@ -2239,6 +2239,7 @@ var init_db_daemon_client = __esm({
2239
2239
  // src/lib/database.ts
2240
2240
  var database_exports = {};
2241
2241
  __export(database_exports, {
2242
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
2242
2243
  disposeDatabase: () => disposeDatabase,
2243
2244
  disposeTurso: () => disposeTurso,
2244
2245
  ensureSchema: () => ensureSchema,
@@ -2395,10 +2396,17 @@ async function ensureSchema() {
2395
2396
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2396
2397
  END;
2397
2398
 
2398
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
2399
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
2400
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
2399
2401
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2400
2402
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
2401
2403
  END;
2404
+
2405
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
2406
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
2407
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
2408
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2409
+ END;
2402
2410
  `);
2403
2411
  await client.executeMultiple(`
2404
2412
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2801,6 +2809,13 @@ async function ensureSchema() {
2801
2809
  });
2802
2810
  } catch {
2803
2811
  }
2812
+ try {
2813
+ await client.execute({
2814
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2815
+ args: []
2816
+ });
2817
+ } catch {
2818
+ }
2804
2819
  try {
2805
2820
  await client.execute({
2806
2821
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -3337,7 +3352,7 @@ async function disposeDatabase() {
3337
3352
  _resilientClient = null;
3338
3353
  }
3339
3354
  }
3340
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
3355
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
3341
3356
  var init_database = __esm({
3342
3357
  "src/lib/database.ts"() {
3343
3358
  "use strict";
@@ -3351,6 +3366,7 @@ var init_database = __esm({
3351
3366
  _daemonClient = null;
3352
3367
  _adapterClient = null;
3353
3368
  initTurso = initDatabase;
3369
+ SOFT_DELETE_RETENTION_DAYS = 7;
3354
3370
  disposeTurso = disposeDatabase;
3355
3371
  }
3356
3372
  });
@@ -5259,9 +5275,10 @@ async function updateTask(input2) {
5259
5275
  args: [assignedAgent]
5260
5276
  });
5261
5277
  } else if (input2.status === "cancelled") {
5278
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
5262
5279
  await draftClient.execute({
5263
- sql: `DELETE FROM memories WHERE agent_id = ? AND draft = 1`,
5264
- args: [assignedAgent]
5280
+ sql: `UPDATE memories SET status = 'deleted', deleted_at = ? WHERE agent_id = ? AND draft = 1`,
5281
+ args: [now2, assignedAgent]
5265
5282
  });
5266
5283
  }
5267
5284
  } catch {
@@ -8014,10 +8031,19 @@ var init_memory_queue_client = __esm({
8014
8031
  // src/lib/active-agent.ts
8015
8032
  init_config();
8016
8033
  init_session_key();
8017
- init_employees();
8018
8034
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2, readdirSync } from "fs";
8019
8035
  import { execSync as execSync3 } from "child_process";
8020
8036
  import path3 from "path";
8037
+
8038
+ // src/mcp/agent-context.ts
8039
+ import { AsyncLocalStorage } from "async_hooks";
8040
+ var agentStore = new AsyncLocalStorage();
8041
+ function getAgentContext() {
8042
+ return agentStore.getStore();
8043
+ }
8044
+
8045
+ // src/lib/active-agent.ts
8046
+ init_employees();
8021
8047
  var CACHE_DIR = path3.join(EXE_AI_DIR, "session-cache");
8022
8048
  var STALE_MS = 24 * 60 * 60 * 1e3;
8023
8049
  function isNameWithOptionalInstance(candidate, baseName) {
@@ -8066,6 +8092,8 @@ function getMarkerPath() {
8066
8092
  return path3.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
8067
8093
  }
8068
8094
  function getActiveAgent() {
8095
+ const httpCtx = getAgentContext();
8096
+ if (httpCtx) return httpCtx;
8069
8097
  try {
8070
8098
  const markerPath = getMarkerPath();
8071
8099
  const raw = readFileSync3(markerPath, "utf8");
@@ -2244,6 +2244,7 @@ var init_db_daemon_client = __esm({
2244
2244
  // src/lib/database.ts
2245
2245
  var database_exports = {};
2246
2246
  __export(database_exports, {
2247
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
2247
2248
  disposeDatabase: () => disposeDatabase,
2248
2249
  disposeTurso: () => disposeTurso,
2249
2250
  ensureSchema: () => ensureSchema,
@@ -2400,10 +2401,17 @@ async function ensureSchema() {
2400
2401
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2401
2402
  END;
2402
2403
 
2403
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
2404
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
2405
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
2404
2406
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2405
2407
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
2406
2408
  END;
2409
+
2410
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
2411
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
2412
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
2413
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2414
+ END;
2407
2415
  `);
2408
2416
  await client.executeMultiple(`
2409
2417
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2806,6 +2814,13 @@ async function ensureSchema() {
2806
2814
  });
2807
2815
  } catch {
2808
2816
  }
2817
+ try {
2818
+ await client.execute({
2819
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2820
+ args: []
2821
+ });
2822
+ } catch {
2823
+ }
2809
2824
  try {
2810
2825
  await client.execute({
2811
2826
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -3342,7 +3357,7 @@ async function disposeDatabase() {
3342
3357
  _resilientClient = null;
3343
3358
  }
3344
3359
  }
3345
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
3360
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
3346
3361
  var init_database = __esm({
3347
3362
  "src/lib/database.ts"() {
3348
3363
  "use strict";
@@ -3356,6 +3371,7 @@ var init_database = __esm({
3356
3371
  _daemonClient = null;
3357
3372
  _adapterClient = null;
3358
3373
  initTurso = initDatabase;
3374
+ SOFT_DELETE_RETENTION_DAYS = 7;
3359
3375
  disposeTurso = disposeDatabase;
3360
3376
  }
3361
3377
  });
@@ -5284,10 +5300,19 @@ import path16 from "path";
5284
5300
  // src/lib/active-agent.ts
5285
5301
  init_config();
5286
5302
  init_session_key();
5287
- init_employees();
5288
5303
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2, readdirSync } from "fs";
5289
5304
  import { execSync as execSync3 } from "child_process";
5290
5305
  import path4 from "path";
5306
+
5307
+ // src/mcp/agent-context.ts
5308
+ import { AsyncLocalStorage } from "async_hooks";
5309
+ var agentStore = new AsyncLocalStorage();
5310
+ function getAgentContext() {
5311
+ return agentStore.getStore();
5312
+ }
5313
+
5314
+ // src/lib/active-agent.ts
5315
+ init_employees();
5291
5316
  var CACHE_DIR = path4.join(EXE_AI_DIR, "session-cache");
5292
5317
  var STALE_MS = 24 * 60 * 60 * 1e3;
5293
5318
  function isNameWithOptionalInstance(candidate, baseName) {
@@ -5336,6 +5361,8 @@ function getMarkerPath() {
5336
5361
  return path4.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
5337
5362
  }
5338
5363
  function getActiveAgent() {
5364
+ const httpCtx = getAgentContext();
5365
+ if (httpCtx) return httpCtx;
5339
5366
  try {
5340
5367
  const markerPath = getMarkerPath();
5341
5368
  const raw = readFileSync4(markerPath, "utf8");
@@ -1994,6 +1994,7 @@ var init_db_daemon_client = __esm({
1994
1994
  // src/lib/database.ts
1995
1995
  var database_exports = {};
1996
1996
  __export(database_exports, {
1997
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
1997
1998
  disposeDatabase: () => disposeDatabase,
1998
1999
  disposeTurso: () => disposeTurso,
1999
2000
  ensureSchema: () => ensureSchema,
@@ -2150,10 +2151,17 @@ async function ensureSchema() {
2150
2151
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2151
2152
  END;
2152
2153
 
2153
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
2154
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
2155
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
2154
2156
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2155
2157
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
2156
2158
  END;
2159
+
2160
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
2161
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
2162
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
2163
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2164
+ END;
2157
2165
  `);
2158
2166
  await client.executeMultiple(`
2159
2167
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2556,6 +2564,13 @@ async function ensureSchema() {
2556
2564
  });
2557
2565
  } catch {
2558
2566
  }
2567
+ try {
2568
+ await client.execute({
2569
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2570
+ args: []
2571
+ });
2572
+ } catch {
2573
+ }
2559
2574
  try {
2560
2575
  await client.execute({
2561
2576
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -3092,7 +3107,7 @@ async function disposeDatabase() {
3092
3107
  _resilientClient = null;
3093
3108
  }
3094
3109
  }
3095
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
3110
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
3096
3111
  var init_database = __esm({
3097
3112
  "src/lib/database.ts"() {
3098
3113
  "use strict";
@@ -3106,6 +3121,7 @@ var init_database = __esm({
3106
3121
  _daemonClient = null;
3107
3122
  _adapterClient = null;
3108
3123
  initTurso = initDatabase;
3124
+ SOFT_DELETE_RETENTION_DAYS = 7;
3109
3125
  disposeTurso = disposeDatabase;
3110
3126
  }
3111
3127
  });
@@ -7895,9 +7911,10 @@ async function updateTask(input2) {
7895
7911
  args: [assignedAgent]
7896
7912
  });
7897
7913
  } else if (input2.status === "cancelled") {
7914
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
7898
7915
  await draftClient.execute({
7899
- sql: `DELETE FROM memories WHERE agent_id = ? AND draft = 1`,
7900
- args: [assignedAgent]
7916
+ sql: `UPDATE memories SET status = 'deleted', deleted_at = ? WHERE agent_id = ? AND draft = 1`,
7917
+ args: [now2, assignedAgent]
7901
7918
  });
7902
7919
  }
7903
7920
  } catch {
@@ -10093,10 +10110,19 @@ function isCacheCold(sessionKey) {
10093
10110
  // src/lib/active-agent.ts
10094
10111
  init_config();
10095
10112
  init_session_key();
10096
- init_employees();
10097
10113
  import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, unlinkSync as unlinkSync4, readdirSync as readdirSync3 } from "fs";
10098
10114
  import { execSync as execSync6 } from "child_process";
10099
10115
  import path13 from "path";
10116
+
10117
+ // src/mcp/agent-context.ts
10118
+ import { AsyncLocalStorage } from "async_hooks";
10119
+ var agentStore = new AsyncLocalStorage();
10120
+ function getAgentContext() {
10121
+ return agentStore.getStore();
10122
+ }
10123
+
10124
+ // src/lib/active-agent.ts
10125
+ init_employees();
10100
10126
  var CACHE_DIR2 = path13.join(EXE_AI_DIR, "session-cache");
10101
10127
  var STALE_MS = 24 * 60 * 60 * 1e3;
10102
10128
  function isNameWithOptionalInstance(candidate, baseName) {
@@ -10145,6 +10171,8 @@ function getMarkerPath() {
10145
10171
  return path13.join(CACHE_DIR2, `active-agent-${getSessionKey()}.json`);
10146
10172
  }
10147
10173
  function getActiveAgent() {
10174
+ const httpCtx = getAgentContext();
10175
+ if (httpCtx) return httpCtx;
10148
10176
  try {
10149
10177
  const markerPath = getMarkerPath();
10150
10178
  const raw = readFileSync8(markerPath, "utf8");
@@ -2242,6 +2242,7 @@ var init_db_daemon_client = __esm({
2242
2242
  // src/lib/database.ts
2243
2243
  var database_exports = {};
2244
2244
  __export(database_exports, {
2245
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
2245
2246
  disposeDatabase: () => disposeDatabase,
2246
2247
  disposeTurso: () => disposeTurso,
2247
2248
  ensureSchema: () => ensureSchema,
@@ -2398,10 +2399,17 @@ async function ensureSchema() {
2398
2399
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2399
2400
  END;
2400
2401
 
2401
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
2402
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
2403
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
2402
2404
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2403
2405
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
2404
2406
  END;
2407
+
2408
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
2409
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
2410
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
2411
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2412
+ END;
2405
2413
  `);
2406
2414
  await client.executeMultiple(`
2407
2415
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2804,6 +2812,13 @@ async function ensureSchema() {
2804
2812
  });
2805
2813
  } catch {
2806
2814
  }
2815
+ try {
2816
+ await client.execute({
2817
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2818
+ args: []
2819
+ });
2820
+ } catch {
2821
+ }
2807
2822
  try {
2808
2823
  await client.execute({
2809
2824
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -3340,7 +3355,7 @@ async function disposeDatabase() {
3340
3355
  _resilientClient = null;
3341
3356
  }
3342
3357
  }
3343
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
3358
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
3344
3359
  var init_database = __esm({
3345
3360
  "src/lib/database.ts"() {
3346
3361
  "use strict";
@@ -3354,6 +3369,7 @@ var init_database = __esm({
3354
3369
  _daemonClient = null;
3355
3370
  _adapterClient = null;
3356
3371
  initTurso = initDatabase;
3372
+ SOFT_DELETE_RETENTION_DAYS = 7;
3357
3373
  disposeTurso = disposeDatabase;
3358
3374
  }
3359
3375
  });
@@ -5468,9 +5484,10 @@ async function updateTask(input2) {
5468
5484
  args: [assignedAgent]
5469
5485
  });
5470
5486
  } else if (input2.status === "cancelled") {
5487
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
5471
5488
  await draftClient.execute({
5472
- sql: `DELETE FROM memories WHERE agent_id = ? AND draft = 1`,
5473
- args: [assignedAgent]
5489
+ sql: `UPDATE memories SET status = 'deleted', deleted_at = ? WHERE agent_id = ? AND draft = 1`,
5490
+ args: [now2, assignedAgent]
5474
5491
  });
5475
5492
  }
5476
5493
  } catch {
@@ -8550,10 +8567,19 @@ var init_git_task_sweep = __esm({
8550
8567
  // src/lib/active-agent.ts
8551
8568
  init_config();
8552
8569
  init_session_key();
8553
- init_employees();
8554
8570
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2, readdirSync } from "fs";
8555
8571
  import { execSync as execSync3 } from "child_process";
8556
8572
  import path3 from "path";
8573
+
8574
+ // src/mcp/agent-context.ts
8575
+ import { AsyncLocalStorage } from "async_hooks";
8576
+ var agentStore = new AsyncLocalStorage();
8577
+ function getAgentContext() {
8578
+ return agentStore.getStore();
8579
+ }
8580
+
8581
+ // src/lib/active-agent.ts
8582
+ init_employees();
8557
8583
  var CACHE_DIR = path3.join(EXE_AI_DIR, "session-cache");
8558
8584
  var STALE_MS = 24 * 60 * 60 * 1e3;
8559
8585
  function isNameWithOptionalInstance(candidate, baseName) {
@@ -8608,6 +8634,8 @@ function clearActiveAgent() {
8608
8634
  }
8609
8635
  }
8610
8636
  function getActiveAgent() {
8637
+ const httpCtx = getAgentContext();
8638
+ if (httpCtx) return httpCtx;
8611
8639
  try {
8612
8640
  const markerPath = getMarkerPath();
8613
8641
  const raw = readFileSync3(markerPath, "utf8");
@@ -2060,6 +2060,7 @@ var init_db_daemon_client = __esm({
2060
2060
  // src/lib/database.ts
2061
2061
  var database_exports = {};
2062
2062
  __export(database_exports, {
2063
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
2063
2064
  disposeDatabase: () => disposeDatabase,
2064
2065
  disposeTurso: () => disposeTurso,
2065
2066
  ensureSchema: () => ensureSchema,
@@ -2216,10 +2217,17 @@ async function ensureSchema() {
2216
2217
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2217
2218
  END;
2218
2219
 
2219
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
2220
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
2221
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
2220
2222
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2221
2223
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
2222
2224
  END;
2225
+
2226
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
2227
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
2228
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
2229
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2230
+ END;
2223
2231
  `);
2224
2232
  await client.executeMultiple(`
2225
2233
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2622,6 +2630,13 @@ async function ensureSchema() {
2622
2630
  });
2623
2631
  } catch {
2624
2632
  }
2633
+ try {
2634
+ await client.execute({
2635
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2636
+ args: []
2637
+ });
2638
+ } catch {
2639
+ }
2625
2640
  try {
2626
2641
  await client.execute({
2627
2642
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -3158,7 +3173,7 @@ async function disposeDatabase() {
3158
3173
  _resilientClient = null;
3159
3174
  }
3160
3175
  }
3161
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
3176
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
3162
3177
  var init_database = __esm({
3163
3178
  "src/lib/database.ts"() {
3164
3179
  "use strict";
@@ -3172,6 +3187,7 @@ var init_database = __esm({
3172
3187
  _daemonClient = null;
3173
3188
  _adapterClient = null;
3174
3189
  initTurso = initDatabase;
3190
+ SOFT_DELETE_RETENTION_DAYS = 7;
3175
3191
  disposeTurso = disposeDatabase;
3176
3192
  }
3177
3193
  });
@@ -6407,6 +6423,19 @@ var init_session_key = __esm({
6407
6423
  }
6408
6424
  });
6409
6425
 
6426
+ // src/mcp/agent-context.ts
6427
+ import { AsyncLocalStorage } from "async_hooks";
6428
+ function getAgentContext() {
6429
+ return agentStore.getStore();
6430
+ }
6431
+ var agentStore;
6432
+ var init_agent_context = __esm({
6433
+ "src/mcp/agent-context.ts"() {
6434
+ "use strict";
6435
+ agentStore = new AsyncLocalStorage();
6436
+ }
6437
+ });
6438
+
6410
6439
  // src/lib/active-agent.ts
6411
6440
  import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3, unlinkSync as unlinkSync3, readdirSync as readdirSync3 } from "fs";
6412
6441
  import { execSync as execSync6 } from "child_process";
@@ -6473,6 +6502,8 @@ function clearActiveAgent() {
6473
6502
  }
6474
6503
  }
6475
6504
  function getActiveAgent() {
6505
+ const httpCtx = getAgentContext();
6506
+ if (httpCtx) return httpCtx;
6476
6507
  try {
6477
6508
  const markerPath = getMarkerPath();
6478
6509
  const raw = readFileSync7(markerPath, "utf8");
@@ -6567,6 +6598,7 @@ var init_active_agent = __esm({
6567
6598
  "use strict";
6568
6599
  init_config();
6569
6600
  init_session_key();
6601
+ init_agent_context();
6570
6602
  init_employees();
6571
6603
  CACHE_DIR = path12.join(EXE_AI_DIR, "session-cache");
6572
6604
  STALE_MS = 24 * 60 * 60 * 1e3;
@@ -1984,6 +1984,7 @@ var init_db_daemon_client = __esm({
1984
1984
  // src/lib/database.ts
1985
1985
  var database_exports = {};
1986
1986
  __export(database_exports, {
1987
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
1987
1988
  disposeDatabase: () => disposeDatabase,
1988
1989
  disposeTurso: () => disposeTurso,
1989
1990
  ensureSchema: () => ensureSchema,
@@ -2140,10 +2141,17 @@ async function ensureSchema() {
2140
2141
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2141
2142
  END;
2142
2143
 
2143
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
2144
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
2145
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
2144
2146
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2145
2147
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
2146
2148
  END;
2149
+
2150
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
2151
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
2152
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
2153
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2154
+ END;
2147
2155
  `);
2148
2156
  await client.executeMultiple(`
2149
2157
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2546,6 +2554,13 @@ async function ensureSchema() {
2546
2554
  });
2547
2555
  } catch {
2548
2556
  }
2557
+ try {
2558
+ await client.execute({
2559
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2560
+ args: []
2561
+ });
2562
+ } catch {
2563
+ }
2549
2564
  try {
2550
2565
  await client.execute({
2551
2566
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -3082,7 +3097,7 @@ async function disposeDatabase() {
3082
3097
  _resilientClient = null;
3083
3098
  }
3084
3099
  }
3085
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
3100
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
3086
3101
  var init_database = __esm({
3087
3102
  "src/lib/database.ts"() {
3088
3103
  "use strict";
@@ -3096,6 +3111,7 @@ var init_database = __esm({
3096
3111
  _daemonClient = null;
3097
3112
  _adapterClient = null;
3098
3113
  initTurso = initDatabase;
3114
+ SOFT_DELETE_RETENTION_DAYS = 7;
3099
3115
  disposeTurso = disposeDatabase;
3100
3116
  }
3101
3117
  });
@@ -4792,10 +4808,19 @@ import { fileURLToPath as fileURLToPath3 } from "url";
4792
4808
  // src/lib/active-agent.ts
4793
4809
  init_config();
4794
4810
  init_session_key();
4795
- init_employees();
4796
4811
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2, readdirSync } from "fs";
4797
4812
  import { execSync as execSync3 } from "child_process";
4798
4813
  import path3 from "path";
4814
+
4815
+ // src/mcp/agent-context.ts
4816
+ import { AsyncLocalStorage } from "async_hooks";
4817
+ var agentStore = new AsyncLocalStorage();
4818
+ function getAgentContext() {
4819
+ return agentStore.getStore();
4820
+ }
4821
+
4822
+ // src/lib/active-agent.ts
4823
+ init_employees();
4799
4824
  var CACHE_DIR = path3.join(EXE_AI_DIR, "session-cache");
4800
4825
  var STALE_MS = 24 * 60 * 60 * 1e3;
4801
4826
  function isNameWithOptionalInstance(candidate, baseName) {
@@ -4844,6 +4869,8 @@ function getMarkerPath() {
4844
4869
  return path3.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
4845
4870
  }
4846
4871
  function getActiveAgent() {
4872
+ const httpCtx = getAgentContext();
4873
+ if (httpCtx) return httpCtx;
4847
4874
  try {
4848
4875
  const markerPath = getMarkerPath();
4849
4876
  const raw = readFileSync3(markerPath, "utf8");