@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
@@ -1683,6 +1683,7 @@ var init_db_daemon_client = __esm({
1683
1683
  // src/lib/database.ts
1684
1684
  var database_exports = {};
1685
1685
  __export(database_exports, {
1686
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
1686
1687
  disposeDatabase: () => disposeDatabase,
1687
1688
  disposeTurso: () => disposeTurso,
1688
1689
  ensureSchema: () => ensureSchema,
@@ -1839,10 +1840,17 @@ async function ensureSchema() {
1839
1840
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1840
1841
  END;
1841
1842
 
1842
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
1843
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
1844
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
1843
1845
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1844
1846
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
1845
1847
  END;
1848
+
1849
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
1850
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
1851
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
1852
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1853
+ END;
1846
1854
  `);
1847
1855
  await client.executeMultiple(`
1848
1856
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2245,6 +2253,13 @@ async function ensureSchema() {
2245
2253
  });
2246
2254
  } catch {
2247
2255
  }
2256
+ try {
2257
+ await client.execute({
2258
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2259
+ args: []
2260
+ });
2261
+ } catch {
2262
+ }
2248
2263
  try {
2249
2264
  await client.execute({
2250
2265
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -2781,7 +2796,7 @@ async function disposeDatabase() {
2781
2796
  _resilientClient = null;
2782
2797
  }
2783
2798
  }
2784
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
2799
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
2785
2800
  var init_database = __esm({
2786
2801
  "src/lib/database.ts"() {
2787
2802
  "use strict";
@@ -2795,6 +2810,7 @@ var init_database = __esm({
2795
2810
  _daemonClient = null;
2796
2811
  _adapterClient = null;
2797
2812
  initTurso = initDatabase;
2813
+ SOFT_DELETE_RETENTION_DAYS = 7;
2798
2814
  disposeTurso = disposeDatabase;
2799
2815
  }
2800
2816
  });
@@ -1672,6 +1672,7 @@ var init_db_daemon_client = __esm({
1672
1672
  // src/lib/database.ts
1673
1673
  var database_exports = {};
1674
1674
  __export(database_exports, {
1675
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
1675
1676
  disposeDatabase: () => disposeDatabase,
1676
1677
  disposeTurso: () => disposeTurso,
1677
1678
  ensureSchema: () => ensureSchema,
@@ -1828,10 +1829,17 @@ async function ensureSchema() {
1828
1829
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1829
1830
  END;
1830
1831
 
1831
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
1832
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
1833
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
1832
1834
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1833
1835
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
1834
1836
  END;
1837
+
1838
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
1839
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
1840
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
1841
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1842
+ END;
1835
1843
  `);
1836
1844
  await client.executeMultiple(`
1837
1845
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2234,6 +2242,13 @@ async function ensureSchema() {
2234
2242
  });
2235
2243
  } catch {
2236
2244
  }
2245
+ try {
2246
+ await client.execute({
2247
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2248
+ args: []
2249
+ });
2250
+ } catch {
2251
+ }
2237
2252
  try {
2238
2253
  await client.execute({
2239
2254
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -2770,7 +2785,7 @@ async function disposeDatabase() {
2770
2785
  _resilientClient = null;
2771
2786
  }
2772
2787
  }
2773
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
2788
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
2774
2789
  var init_database = __esm({
2775
2790
  "src/lib/database.ts"() {
2776
2791
  "use strict";
@@ -2784,6 +2799,7 @@ var init_database = __esm({
2784
2799
  _daemonClient = null;
2785
2800
  _adapterClient = null;
2786
2801
  initTurso = initDatabase;
2802
+ SOFT_DELETE_RETENTION_DAYS = 7;
2787
2803
  disposeTurso = disposeDatabase;
2788
2804
  }
2789
2805
  });
@@ -2174,6 +2174,7 @@ var init_db_daemon_client = __esm({
2174
2174
  // src/lib/database.ts
2175
2175
  var database_exports = {};
2176
2176
  __export(database_exports, {
2177
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
2177
2178
  disposeDatabase: () => disposeDatabase,
2178
2179
  disposeTurso: () => disposeTurso,
2179
2180
  ensureSchema: () => ensureSchema,
@@ -2330,10 +2331,17 @@ async function ensureSchema() {
2330
2331
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2331
2332
  END;
2332
2333
 
2333
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
2334
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
2335
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
2334
2336
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2335
2337
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
2336
2338
  END;
2339
+
2340
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
2341
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
2342
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
2343
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2344
+ END;
2337
2345
  `);
2338
2346
  await client.executeMultiple(`
2339
2347
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2736,6 +2744,13 @@ async function ensureSchema() {
2736
2744
  });
2737
2745
  } catch {
2738
2746
  }
2747
+ try {
2748
+ await client.execute({
2749
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2750
+ args: []
2751
+ });
2752
+ } catch {
2753
+ }
2739
2754
  try {
2740
2755
  await client.execute({
2741
2756
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -3272,7 +3287,7 @@ async function disposeDatabase() {
3272
3287
  _resilientClient = null;
3273
3288
  }
3274
3289
  }
3275
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
3290
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
3276
3291
  var init_database = __esm({
3277
3292
  "src/lib/database.ts"() {
3278
3293
  "use strict";
@@ -3286,6 +3301,7 @@ var init_database = __esm({
3286
3301
  _daemonClient = null;
3287
3302
  _adapterClient = null;
3288
3303
  initTurso = initDatabase;
3304
+ SOFT_DELETE_RETENTION_DAYS = 7;
3289
3305
  disposeTurso = disposeDatabase;
3290
3306
  }
3291
3307
  });
@@ -5210,9 +5226,10 @@ async function updateTask(input) {
5210
5226
  args: [assignedAgent]
5211
5227
  });
5212
5228
  } else if (input.status === "cancelled") {
5229
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
5213
5230
  await draftClient.execute({
5214
- sql: `DELETE FROM memories WHERE agent_id = ? AND draft = 1`,
5215
- args: [assignedAgent]
5231
+ sql: `UPDATE memories SET status = 'deleted', deleted_at = ? WHERE agent_id = ? AND draft = 1`,
5232
+ args: [now2, assignedAgent]
5216
5233
  });
5217
5234
  }
5218
5235
  } catch {
@@ -1446,6 +1446,7 @@ var init_db_daemon_client = __esm({
1446
1446
  // src/lib/database.ts
1447
1447
  var database_exports = {};
1448
1448
  __export(database_exports, {
1449
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
1449
1450
  disposeDatabase: () => disposeDatabase,
1450
1451
  disposeTurso: () => disposeTurso,
1451
1452
  ensureSchema: () => ensureSchema,
@@ -1602,10 +1603,17 @@ async function ensureSchema() {
1602
1603
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1603
1604
  END;
1604
1605
 
1605
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
1606
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
1607
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
1606
1608
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1607
1609
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
1608
1610
  END;
1611
+
1612
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
1613
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
1614
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
1615
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1616
+ END;
1609
1617
  `);
1610
1618
  await client.executeMultiple(`
1611
1619
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2008,6 +2016,13 @@ async function ensureSchema() {
2008
2016
  });
2009
2017
  } catch {
2010
2018
  }
2019
+ try {
2020
+ await client.execute({
2021
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2022
+ args: []
2023
+ });
2024
+ } catch {
2025
+ }
2011
2026
  try {
2012
2027
  await client.execute({
2013
2028
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -2544,7 +2559,7 @@ async function disposeDatabase() {
2544
2559
  _resilientClient = null;
2545
2560
  }
2546
2561
  }
2547
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
2562
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
2548
2563
  var init_database = __esm({
2549
2564
  "src/lib/database.ts"() {
2550
2565
  "use strict";
@@ -2558,6 +2573,7 @@ var init_database = __esm({
2558
2573
  _daemonClient = null;
2559
2574
  _adapterClient = null;
2560
2575
  initTurso = initDatabase;
2576
+ SOFT_DELETE_RETENTION_DAYS = 7;
2561
2577
  disposeTurso = disposeDatabase;
2562
2578
  }
2563
2579
  });
@@ -1661,6 +1661,7 @@ var init_db_daemon_client = __esm({
1661
1661
  // src/lib/database.ts
1662
1662
  var database_exports = {};
1663
1663
  __export(database_exports, {
1664
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
1664
1665
  disposeDatabase: () => disposeDatabase,
1665
1666
  disposeTurso: () => disposeTurso,
1666
1667
  ensureSchema: () => ensureSchema,
@@ -1817,10 +1818,17 @@ async function ensureSchema() {
1817
1818
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1818
1819
  END;
1819
1820
 
1820
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
1821
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
1822
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
1821
1823
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1822
1824
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
1823
1825
  END;
1826
+
1827
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
1828
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
1829
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
1830
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1831
+ END;
1824
1832
  `);
1825
1833
  await client.executeMultiple(`
1826
1834
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2223,6 +2231,13 @@ async function ensureSchema() {
2223
2231
  });
2224
2232
  } catch {
2225
2233
  }
2234
+ try {
2235
+ await client.execute({
2236
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2237
+ args: []
2238
+ });
2239
+ } catch {
2240
+ }
2226
2241
  try {
2227
2242
  await client.execute({
2228
2243
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -2759,7 +2774,7 @@ async function disposeDatabase() {
2759
2774
  _resilientClient = null;
2760
2775
  }
2761
2776
  }
2762
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
2777
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
2763
2778
  var init_database = __esm({
2764
2779
  "src/lib/database.ts"() {
2765
2780
  "use strict";
@@ -2773,6 +2788,7 @@ var init_database = __esm({
2773
2788
  _daemonClient = null;
2774
2789
  _adapterClient = null;
2775
2790
  initTurso = initDatabase;
2791
+ SOFT_DELETE_RETENTION_DAYS = 7;
2776
2792
  disposeTurso = disposeDatabase;
2777
2793
  }
2778
2794
  });
@@ -1760,6 +1760,7 @@ var init_db_daemon_client = __esm({
1760
1760
  // src/lib/database.ts
1761
1761
  var database_exports = {};
1762
1762
  __export(database_exports, {
1763
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
1763
1764
  disposeDatabase: () => disposeDatabase,
1764
1765
  disposeTurso: () => disposeTurso,
1765
1766
  ensureSchema: () => ensureSchema,
@@ -1916,10 +1917,17 @@ async function ensureSchema() {
1916
1917
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1917
1918
  END;
1918
1919
 
1919
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
1920
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
1921
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
1920
1922
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1921
1923
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
1922
1924
  END;
1925
+
1926
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
1927
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
1928
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
1929
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1930
+ END;
1923
1931
  `);
1924
1932
  await client.executeMultiple(`
1925
1933
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2322,6 +2330,13 @@ async function ensureSchema() {
2322
2330
  });
2323
2331
  } catch {
2324
2332
  }
2333
+ try {
2334
+ await client.execute({
2335
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2336
+ args: []
2337
+ });
2338
+ } catch {
2339
+ }
2325
2340
  try {
2326
2341
  await client.execute({
2327
2342
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -2858,7 +2873,7 @@ async function disposeDatabase() {
2858
2873
  _resilientClient = null;
2859
2874
  }
2860
2875
  }
2861
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
2876
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
2862
2877
  var init_database = __esm({
2863
2878
  "src/lib/database.ts"() {
2864
2879
  "use strict";
@@ -2872,6 +2887,7 @@ var init_database = __esm({
2872
2887
  _daemonClient = null;
2873
2888
  _adapterClient = null;
2874
2889
  initTurso = initDatabase;
2890
+ SOFT_DELETE_RETENTION_DAYS = 7;
2875
2891
  disposeTurso = disposeDatabase;
2876
2892
  }
2877
2893
  });
@@ -6345,9 +6361,10 @@ async function updateTask(input) {
6345
6361
  args: [assignedAgent]
6346
6362
  });
6347
6363
  } else if (input.status === "cancelled") {
6364
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
6348
6365
  await draftClient.execute({
6349
- sql: `DELETE FROM memories WHERE agent_id = ? AND draft = 1`,
6350
- args: [assignedAgent]
6366
+ sql: `UPDATE memories SET status = 'deleted', deleted_at = ? WHERE agent_id = ? AND draft = 1`,
6367
+ args: [now2, assignedAgent]
6351
6368
  });
6352
6369
  }
6353
6370
  } catch {
@@ -2252,6 +2252,7 @@ var init_db_daemon_client = __esm({
2252
2252
  // src/lib/database.ts
2253
2253
  var database_exports = {};
2254
2254
  __export(database_exports, {
2255
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
2255
2256
  disposeDatabase: () => disposeDatabase,
2256
2257
  disposeTurso: () => disposeTurso,
2257
2258
  ensureSchema: () => ensureSchema,
@@ -2408,10 +2409,17 @@ async function ensureSchema() {
2408
2409
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2409
2410
  END;
2410
2411
 
2411
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
2412
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
2413
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
2412
2414
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2413
2415
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
2414
2416
  END;
2417
+
2418
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
2419
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
2420
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
2421
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2422
+ END;
2415
2423
  `);
2416
2424
  await client.executeMultiple(`
2417
2425
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2814,6 +2822,13 @@ async function ensureSchema() {
2814
2822
  });
2815
2823
  } catch {
2816
2824
  }
2825
+ try {
2826
+ await client.execute({
2827
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2828
+ args: []
2829
+ });
2830
+ } catch {
2831
+ }
2817
2832
  try {
2818
2833
  await client.execute({
2819
2834
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -3350,7 +3365,7 @@ async function disposeDatabase() {
3350
3365
  _resilientClient = null;
3351
3366
  }
3352
3367
  }
3353
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
3368
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
3354
3369
  var init_database = __esm({
3355
3370
  "src/lib/database.ts"() {
3356
3371
  "use strict";
@@ -3364,6 +3379,7 @@ var init_database = __esm({
3364
3379
  _daemonClient = null;
3365
3380
  _adapterClient = null;
3366
3381
  initTurso = initDatabase;
3382
+ SOFT_DELETE_RETENTION_DAYS = 7;
3367
3383
  disposeTurso = disposeDatabase;
3368
3384
  }
3369
3385
  });
@@ -5281,9 +5297,10 @@ async function updateTask(input) {
5281
5297
  args: [assignedAgent]
5282
5298
  });
5283
5299
  } else if (input.status === "cancelled") {
5300
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
5284
5301
  await draftClient.execute({
5285
- sql: `DELETE FROM memories WHERE agent_id = ? AND draft = 1`,
5286
- args: [assignedAgent]
5302
+ sql: `UPDATE memories SET status = 'deleted', deleted_at = ? WHERE agent_id = ? AND draft = 1`,
5303
+ args: [now2, assignedAgent]
5287
5304
  });
5288
5305
  }
5289
5306
  } catch {
package/dist/bin/setup.js CHANGED
@@ -1400,8 +1400,8 @@ async function validateLicense(apiKey, deviceId) {
1400
1400
  }
1401
1401
  function getCacheAgeMs() {
1402
1402
  try {
1403
- const { statSync: statSync3 } = __require("fs");
1404
- const s = statSync3(CACHE_PATH);
1403
+ const { statSync: statSync4 } = __require("fs");
1404
+ const s = statSync4(CACHE_PATH);
1405
1405
  return Date.now() - s.mtimeMs;
1406
1406
  } catch {
1407
1407
  return Infinity;
@@ -2877,6 +2877,7 @@ var init_db_daemon_client = __esm({
2877
2877
  // src/lib/database.ts
2878
2878
  var database_exports = {};
2879
2879
  __export(database_exports, {
2880
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
2880
2881
  disposeDatabase: () => disposeDatabase,
2881
2882
  disposeTurso: () => disposeTurso,
2882
2883
  ensureSchema: () => ensureSchema,
@@ -3033,10 +3034,17 @@ async function ensureSchema() {
3033
3034
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
3034
3035
  END;
3035
3036
 
3036
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
3037
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
3038
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
3037
3039
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
3038
3040
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
3039
3041
  END;
3042
+
3043
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
3044
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
3045
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
3046
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
3047
+ END;
3040
3048
  `);
3041
3049
  await client.executeMultiple(`
3042
3050
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -3439,6 +3447,13 @@ async function ensureSchema() {
3439
3447
  });
3440
3448
  } catch {
3441
3449
  }
3450
+ try {
3451
+ await client.execute({
3452
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
3453
+ args: []
3454
+ });
3455
+ } catch {
3456
+ }
3442
3457
  try {
3443
3458
  await client.execute({
3444
3459
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -3975,7 +3990,7 @@ async function disposeDatabase() {
3975
3990
  _resilientClient = null;
3976
3991
  }
3977
3992
  }
3978
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
3993
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
3979
3994
  var init_database = __esm({
3980
3995
  "src/lib/database.ts"() {
3981
3996
  "use strict";
@@ -3989,6 +4004,7 @@ var init_database = __esm({
3989
4004
  _daemonClient = null;
3990
4005
  _adapterClient = null;
3991
4006
  initTurso = initDatabase;
4007
+ SOFT_DELETE_RETENTION_DAYS = 7;
3992
4008
  disposeTurso = disposeDatabase;
3993
4009
  }
3994
4010
  });
@@ -4371,7 +4387,7 @@ __export(cloud_sync_exports, {
4371
4387
  pushToPostgres: () => pushToPostgres,
4372
4388
  recordRosterDeletion: () => recordRosterDeletion
4373
4389
  });
4374
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync12, readdirSync as readdirSync2, mkdirSync as mkdirSync5, appendFileSync, unlinkSync as unlinkSync6, openSync as openSync2, closeSync as closeSync2 } from "fs";
4390
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync12, readdirSync as readdirSync2, mkdirSync as mkdirSync5, appendFileSync, unlinkSync as unlinkSync6, openSync as openSync2, closeSync as closeSync2, statSync as statSync3 } from "fs";
4375
4391
  import crypto3 from "crypto";
4376
4392
  import path12 from "path";
4377
4393
  import { homedir as homedir2 } from "os";
@@ -4861,10 +4877,9 @@ async function cloudSync(config) {
4861
4877
  const totalMemories = await countRows("SELECT COUNT(*) as cnt FROM memories WHERE status = 'active' OR status IS NULL");
4862
4878
  try {
4863
4879
  const { getLatestBackup: getLatestBackup2 } = await Promise.resolve().then(() => (init_db_backup(), db_backup_exports));
4864
- const { statSync: statFile } = await import("fs");
4865
4880
  const latestBackup = getLatestBackup2();
4866
4881
  if (latestBackup) {
4867
- const backupSize = statFile(latestBackup).size;
4882
+ const backupSize = statSync3(latestBackup).size;
4868
4883
  const MAX_CLOUD_BACKUP_BYTES = 50 * 1024 * 1024;
4869
4884
  if (backupSize <= MAX_CLOUD_BACKUP_BYTES) {
4870
4885
  const backupData = readFileSync8(latestBackup);
@@ -7412,8 +7427,8 @@ async function validateModel(log) {
7412
7427
  log("Skipping in-memory model validation (low memory \u2014 will validate on first use).");
7413
7428
  const modelPath = path16.join(MODELS_DIR, LOCAL_FILENAME);
7414
7429
  if (existsSync16(modelPath)) {
7415
- const { statSync: statSync3 } = await import("fs");
7416
- const size = statSync3(modelPath).size;
7430
+ const { statSync: statSync4 } = await import("fs");
7431
+ const size = statSync4(modelPath).size;
7417
7432
  if (size > 300 * 1e6) {
7418
7433
  log(`Model file verified (${(size / 1e6).toFixed(0)} MB).`);
7419
7434
  return;
@@ -1446,6 +1446,7 @@ var init_db_daemon_client = __esm({
1446
1446
  // src/lib/database.ts
1447
1447
  var database_exports = {};
1448
1448
  __export(database_exports, {
1449
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
1449
1450
  disposeDatabase: () => disposeDatabase,
1450
1451
  disposeTurso: () => disposeTurso,
1451
1452
  ensureSchema: () => ensureSchema,
@@ -1602,10 +1603,17 @@ async function ensureSchema() {
1602
1603
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1603
1604
  END;
1604
1605
 
1605
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
1606
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
1607
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
1606
1608
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1607
1609
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
1608
1610
  END;
1611
+
1612
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
1613
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
1614
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
1615
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1616
+ END;
1609
1617
  `);
1610
1618
  await client.executeMultiple(`
1611
1619
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2008,6 +2016,13 @@ async function ensureSchema() {
2008
2016
  });
2009
2017
  } catch {
2010
2018
  }
2019
+ try {
2020
+ await client.execute({
2021
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2022
+ args: []
2023
+ });
2024
+ } catch {
2025
+ }
2011
2026
  try {
2012
2027
  await client.execute({
2013
2028
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -2544,7 +2559,7 @@ async function disposeDatabase() {
2544
2559
  _resilientClient = null;
2545
2560
  }
2546
2561
  }
2547
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
2562
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
2548
2563
  var init_database = __esm({
2549
2564
  "src/lib/database.ts"() {
2550
2565
  "use strict";
@@ -2558,6 +2573,7 @@ var init_database = __esm({
2558
2573
  _daemonClient = null;
2559
2574
  _adapterClient = null;
2560
2575
  initTurso = initDatabase;
2576
+ SOFT_DELETE_RETENTION_DAYS = 7;
2561
2577
  disposeTurso = disposeDatabase;
2562
2578
  }
2563
2579
  });
@@ -2305,6 +2305,7 @@ var init_db_daemon_client = __esm({
2305
2305
  // src/lib/database.ts
2306
2306
  var database_exports = {};
2307
2307
  __export(database_exports, {
2308
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
2308
2309
  disposeDatabase: () => disposeDatabase,
2309
2310
  disposeTurso: () => disposeTurso,
2310
2311
  ensureSchema: () => ensureSchema,
@@ -2461,10 +2462,17 @@ async function ensureSchema() {
2461
2462
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2462
2463
  END;
2463
2464
 
2464
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
2465
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
2466
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
2465
2467
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2466
2468
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
2467
2469
  END;
2470
+
2471
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
2472
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
2473
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
2474
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2475
+ END;
2468
2476
  `);
2469
2477
  await client.executeMultiple(`
2470
2478
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2867,6 +2875,13 @@ async function ensureSchema() {
2867
2875
  });
2868
2876
  } catch {
2869
2877
  }
2878
+ try {
2879
+ await client.execute({
2880
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2881
+ args: []
2882
+ });
2883
+ } catch {
2884
+ }
2870
2885
  try {
2871
2886
  await client.execute({
2872
2887
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -3403,7 +3418,7 @@ async function disposeDatabase() {
3403
3418
  _resilientClient = null;
3404
3419
  }
3405
3420
  }
3406
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
3421
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
3407
3422
  var init_database = __esm({
3408
3423
  "src/lib/database.ts"() {
3409
3424
  "use strict";
@@ -3417,6 +3432,7 @@ var init_database = __esm({
3417
3432
  _daemonClient = null;
3418
3433
  _adapterClient = null;
3419
3434
  initTurso = initDatabase;
3435
+ SOFT_DELETE_RETENTION_DAYS = 7;
3420
3436
  disposeTurso = disposeDatabase;
3421
3437
  }
3422
3438
  });
@@ -8187,9 +8203,10 @@ async function updateTask(input) {
8187
8203
  args: [assignedAgent]
8188
8204
  });
8189
8205
  } else if (input.status === "cancelled") {
8206
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
8190
8207
  await draftClient.execute({
8191
- sql: `DELETE FROM memories WHERE agent_id = ? AND draft = 1`,
8192
- args: [assignedAgent]
8208
+ sql: `UPDATE memories SET status = 'deleted', deleted_at = ? WHERE agent_id = ? AND draft = 1`,
8209
+ args: [now2, assignedAgent]
8193
8210
  });
8194
8211
  }
8195
8212
  } catch {