@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
@@ -1965,6 +1965,7 @@ var init_db_daemon_client = __esm({
1965
1965
  // src/lib/database.ts
1966
1966
  var database_exports = {};
1967
1967
  __export(database_exports, {
1968
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
1968
1969
  disposeDatabase: () => disposeDatabase,
1969
1970
  disposeTurso: () => disposeTurso,
1970
1971
  ensureSchema: () => ensureSchema,
@@ -2121,10 +2122,17 @@ async function ensureSchema() {
2121
2122
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2122
2123
  END;
2123
2124
 
2124
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
2125
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
2126
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
2125
2127
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2126
2128
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
2127
2129
  END;
2130
+
2131
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
2132
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
2133
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
2134
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2135
+ END;
2128
2136
  `);
2129
2137
  await client.executeMultiple(`
2130
2138
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2527,6 +2535,13 @@ async function ensureSchema() {
2527
2535
  });
2528
2536
  } catch {
2529
2537
  }
2538
+ try {
2539
+ await client.execute({
2540
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2541
+ args: []
2542
+ });
2543
+ } catch {
2544
+ }
2530
2545
  try {
2531
2546
  await client.execute({
2532
2547
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -3063,7 +3078,7 @@ async function disposeDatabase() {
3063
3078
  _resilientClient = null;
3064
3079
  }
3065
3080
  }
3066
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
3081
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
3067
3082
  var init_database = __esm({
3068
3083
  "src/lib/database.ts"() {
3069
3084
  "use strict";
@@ -3077,6 +3092,7 @@ var init_database = __esm({
3077
3092
  _daemonClient = null;
3078
3093
  _adapterClient = null;
3079
3094
  initTurso = initDatabase;
3095
+ SOFT_DELETE_RETENTION_DAYS = 7;
3080
3096
  disposeTurso = disposeDatabase;
3081
3097
  }
3082
3098
  });
@@ -4693,10 +4709,19 @@ var init_fast_db_init = __esm({
4693
4709
  // src/lib/active-agent.ts
4694
4710
  init_config();
4695
4711
  init_session_key();
4696
- init_employees();
4697
4712
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2, readdirSync } from "fs";
4698
4713
  import { execSync as execSync3 } from "child_process";
4699
4714
  import path3 from "path";
4715
+
4716
+ // src/mcp/agent-context.ts
4717
+ import { AsyncLocalStorage } from "async_hooks";
4718
+ var agentStore = new AsyncLocalStorage();
4719
+ function getAgentContext() {
4720
+ return agentStore.getStore();
4721
+ }
4722
+
4723
+ // src/lib/active-agent.ts
4724
+ init_employees();
4700
4725
  var CACHE_DIR = path3.join(EXE_AI_DIR, "session-cache");
4701
4726
  var STALE_MS = 24 * 60 * 60 * 1e3;
4702
4727
  function isNameWithOptionalInstance(candidate, baseName) {
@@ -4745,6 +4770,8 @@ function getMarkerPath() {
4745
4770
  return path3.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
4746
4771
  }
4747
4772
  function getActiveAgent() {
4773
+ const httpCtx = getAgentContext();
4774
+ if (httpCtx) return httpCtx;
4748
4775
  try {
4749
4776
  const markerPath = getMarkerPath();
4750
4777
  const raw = readFileSync3(markerPath, "utf8");
@@ -1722,6 +1722,7 @@ var init_db_daemon_client = __esm({
1722
1722
  // src/lib/database.ts
1723
1723
  var database_exports = {};
1724
1724
  __export(database_exports, {
1725
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
1725
1726
  disposeDatabase: () => disposeDatabase,
1726
1727
  disposeTurso: () => disposeTurso,
1727
1728
  ensureSchema: () => ensureSchema,
@@ -1878,10 +1879,17 @@ async function ensureSchema() {
1878
1879
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1879
1880
  END;
1880
1881
 
1881
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
1882
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
1883
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
1882
1884
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1883
1885
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
1884
1886
  END;
1887
+
1888
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
1889
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
1890
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
1891
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1892
+ END;
1885
1893
  `);
1886
1894
  await client.executeMultiple(`
1887
1895
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -2284,6 +2292,13 @@ async function ensureSchema() {
2284
2292
  });
2285
2293
  } catch {
2286
2294
  }
2295
+ try {
2296
+ await client.execute({
2297
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
2298
+ args: []
2299
+ });
2300
+ } catch {
2301
+ }
2287
2302
  try {
2288
2303
  await client.execute({
2289
2304
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -2820,7 +2835,7 @@ async function disposeDatabase() {
2820
2835
  _resilientClient = null;
2821
2836
  }
2822
2837
  }
2823
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
2838
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
2824
2839
  var init_database = __esm({
2825
2840
  "src/lib/database.ts"() {
2826
2841
  "use strict";
@@ -2834,6 +2849,7 @@ var init_database = __esm({
2834
2849
  _daemonClient = null;
2835
2850
  _adapterClient = null;
2836
2851
  initTurso = initDatabase;
2852
+ SOFT_DELETE_RETENTION_DAYS = 7;
2837
2853
  disposeTurso = disposeDatabase;
2838
2854
  }
2839
2855
  });
@@ -4309,8 +4325,8 @@ async function validateLicense(apiKey, deviceId) {
4309
4325
  }
4310
4326
  function getCacheAgeMs() {
4311
4327
  try {
4312
- const { statSync: statSync4 } = __require("fs");
4313
- const s = statSync4(CACHE_PATH);
4328
+ const { statSync: statSync5 } = __require("fs");
4329
+ const s = statSync5(CACHE_PATH);
4314
4330
  return Date.now() - s.mtimeMs;
4315
4331
  } catch {
4316
4332
  return Infinity;
@@ -5390,7 +5406,7 @@ __export(cloud_sync_exports, {
5390
5406
  pushToPostgres: () => pushToPostgres,
5391
5407
  recordRosterDeletion: () => recordRosterDeletion
5392
5408
  });
5393
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, existsSync as existsSync18, readdirSync as readdirSync6, mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, unlinkSync as unlinkSync8, openSync as openSync2, closeSync as closeSync2 } from "fs";
5409
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, existsSync as existsSync18, readdirSync as readdirSync6, mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, unlinkSync as unlinkSync8, openSync as openSync2, closeSync as closeSync2, statSync as statSync4 } from "fs";
5394
5410
  import crypto4 from "crypto";
5395
5411
  import path19 from "path";
5396
5412
  import { homedir as homedir2 } from "os";
@@ -5880,10 +5896,9 @@ async function cloudSync(config) {
5880
5896
  const totalMemories = await countRows("SELECT COUNT(*) as cnt FROM memories WHERE status = 'active' OR status IS NULL");
5881
5897
  try {
5882
5898
  const { getLatestBackup: getLatestBackup2 } = await Promise.resolve().then(() => (init_db_backup(), db_backup_exports));
5883
- const { statSync: statFile } = await import("fs");
5884
5899
  const latestBackup = getLatestBackup2();
5885
5900
  if (latestBackup) {
5886
- const backupSize = statFile(latestBackup).size;
5901
+ const backupSize = statSync4(latestBackup).size;
5887
5902
  const MAX_CLOUD_BACKUP_BYTES = 50 * 1024 * 1024;
5888
5903
  if (backupSize <= MAX_CLOUD_BACKUP_BYTES) {
5889
5904
  const backupData = readFileSync13(latestBackup);
package/dist/index.js CHANGED
@@ -2459,6 +2459,7 @@ var init_db_daemon_client = __esm({
2459
2459
  // src/lib/database.ts
2460
2460
  var database_exports = {};
2461
2461
  __export(database_exports, {
2462
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
2462
2463
  disposeDatabase: () => disposeDatabase,
2463
2464
  disposeTurso: () => disposeTurso,
2464
2465
  ensureSchema: () => ensureSchema,
@@ -2615,10 +2616,17 @@ async function ensureSchema() {
2615
2616
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2616
2617
  END;
2617
2618
 
2618
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
2619
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
2620
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
2619
2621
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2620
2622
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
2621
2623
  END;
2624
+
2625
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
2626
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
2627
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
2628
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2629
+ END;
2622
2630
  `);
2623
2631
  await client.executeMultiple(`
2624
2632
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -3021,6 +3029,13 @@ async function ensureSchema() {
3021
3029
  });
3022
3030
  } catch {
3023
3031
  }
3032
+ try {
3033
+ await client.execute({
3034
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
3035
+ args: []
3036
+ });
3037
+ } catch {
3038
+ }
3024
3039
  try {
3025
3040
  await client.execute({
3026
3041
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -3557,7 +3572,7 @@ async function disposeDatabase() {
3557
3572
  _resilientClient = null;
3558
3573
  }
3559
3574
  }
3560
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
3575
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
3561
3576
  var init_database = __esm({
3562
3577
  "src/lib/database.ts"() {
3563
3578
  "use strict";
@@ -3571,6 +3586,7 @@ var init_database = __esm({
3571
3586
  _daemonClient = null;
3572
3587
  _adapterClient = null;
3573
3588
  initTurso = initDatabase;
3589
+ SOFT_DELETE_RETENTION_DAYS = 7;
3574
3590
  disposeTurso = disposeDatabase;
3575
3591
  }
3576
3592
  });
@@ -5582,9 +5598,10 @@ async function updateTask(input) {
5582
5598
  args: [assignedAgent]
5583
5599
  });
5584
5600
  } else if (input.status === "cancelled") {
5601
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
5585
5602
  await draftClient.execute({
5586
- sql: `DELETE FROM memories WHERE agent_id = ? AND draft = 1`,
5587
- args: [assignedAgent]
5603
+ sql: `UPDATE memories SET status = 'deleted', deleted_at = ? WHERE agent_id = ? AND draft = 1`,
5604
+ args: [now2, assignedAgent]
5588
5605
  });
5589
5606
  }
5590
5607
  } catch {
@@ -1394,6 +1394,7 @@ var init_db_daemon_client = __esm({
1394
1394
  // src/lib/database.ts
1395
1395
  var database_exports = {};
1396
1396
  __export(database_exports, {
1397
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
1397
1398
  disposeDatabase: () => disposeDatabase,
1398
1399
  disposeTurso: () => disposeTurso,
1399
1400
  ensureSchema: () => ensureSchema,
@@ -1550,10 +1551,17 @@ async function ensureSchema() {
1550
1551
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1551
1552
  END;
1552
1553
 
1553
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
1554
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
1555
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
1554
1556
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1555
1557
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
1556
1558
  END;
1559
+
1560
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
1561
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
1562
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
1563
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1564
+ END;
1557
1565
  `);
1558
1566
  await client.executeMultiple(`
1559
1567
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -1956,6 +1964,13 @@ async function ensureSchema() {
1956
1964
  });
1957
1965
  } catch {
1958
1966
  }
1967
+ try {
1968
+ await client.execute({
1969
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
1970
+ args: []
1971
+ });
1972
+ } catch {
1973
+ }
1959
1974
  try {
1960
1975
  await client.execute({
1961
1976
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -2492,7 +2507,7 @@ async function disposeDatabase() {
2492
2507
  _resilientClient = null;
2493
2508
  }
2494
2509
  }
2495
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
2510
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
2496
2511
  var init_database = __esm({
2497
2512
  "src/lib/database.ts"() {
2498
2513
  "use strict";
@@ -2506,6 +2521,7 @@ var init_database = __esm({
2506
2521
  _daemonClient = null;
2507
2522
  _adapterClient = null;
2508
2523
  initTurso = initDatabase;
2524
+ SOFT_DELETE_RETENTION_DAYS = 7;
2509
2525
  disposeTurso = disposeDatabase;
2510
2526
  }
2511
2527
  });
@@ -3141,7 +3157,7 @@ var init_db_backup = __esm({
3141
3157
 
3142
3158
  // src/lib/cloud-sync.ts
3143
3159
  init_database();
3144
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync10, readdirSync as readdirSync2, mkdirSync as mkdirSync5, appendFileSync, unlinkSync as unlinkSync5, openSync as openSync2, closeSync as closeSync2 } from "fs";
3160
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync10, readdirSync as readdirSync2, mkdirSync as mkdirSync5, appendFileSync, unlinkSync as unlinkSync5, openSync as openSync2, closeSync as closeSync2, statSync as statSync3 } from "fs";
3145
3161
  import crypto3 from "crypto";
3146
3162
  import path10 from "path";
3147
3163
  import { homedir as homedir2 } from "os";
@@ -3739,10 +3755,9 @@ async function cloudSync(config) {
3739
3755
  const totalMemories = await countRows("SELECT COUNT(*) as cnt FROM memories WHERE status = 'active' OR status IS NULL");
3740
3756
  try {
3741
3757
  const { getLatestBackup: getLatestBackup2 } = await Promise.resolve().then(() => (init_db_backup(), db_backup_exports));
3742
- const { statSync: statFile } = await import("fs");
3743
3758
  const latestBackup = getLatestBackup2();
3744
3759
  if (latestBackup) {
3745
- const backupSize = statFile(latestBackup).size;
3760
+ const backupSize = statSync3(latestBackup).size;
3746
3761
  const MAX_CLOUD_BACKUP_BYTES = 50 * 1024 * 1024;
3747
3762
  if (backupSize <= MAX_CLOUD_BACKUP_BYTES) {
3748
3763
  const backupData = readFileSync7(latestBackup);
@@ -1369,6 +1369,7 @@ function isInitialized() {
1369
1369
  function setExternalClient(client) {
1370
1370
  _adapterClient = client;
1371
1371
  }
1372
+ var SOFT_DELETE_RETENTION_DAYS = 7;
1372
1373
  function getClient() {
1373
1374
  if (!_adapterClient) {
1374
1375
  throw new Error("Database client not initialized. Call initDatabase() first.");
@@ -1466,10 +1467,17 @@ async function ensureSchema() {
1466
1467
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1467
1468
  END;
1468
1469
 
1469
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
1470
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
1471
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
1470
1472
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1471
1473
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
1472
1474
  END;
1475
+
1476
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
1477
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
1478
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
1479
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1480
+ END;
1473
1481
  `);
1474
1482
  await client.executeMultiple(`
1475
1483
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -1872,6 +1880,13 @@ async function ensureSchema() {
1872
1880
  });
1873
1881
  } catch {
1874
1882
  }
1883
+ try {
1884
+ await client.execute({
1885
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
1886
+ args: []
1887
+ });
1888
+ } catch {
1889
+ }
1875
1890
  try {
1876
1891
  await client.execute({
1877
1892
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -2410,6 +2425,7 @@ async function disposeDatabase() {
2410
2425
  }
2411
2426
  }
2412
2427
  export {
2428
+ SOFT_DELETE_RETENTION_DAYS,
2413
2429
  disposeDatabase,
2414
2430
  disposeTurso,
2415
2431
  ensureSchema,
package/dist/lib/db.js CHANGED
@@ -1369,6 +1369,7 @@ function isInitialized() {
1369
1369
  function setExternalClient(client) {
1370
1370
  _adapterClient = client;
1371
1371
  }
1372
+ var SOFT_DELETE_RETENTION_DAYS = 7;
1372
1373
  function getClient() {
1373
1374
  if (!_adapterClient) {
1374
1375
  throw new Error("Database client not initialized. Call initDatabase() first.");
@@ -1466,10 +1467,17 @@ async function ensureSchema() {
1466
1467
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1467
1468
  END;
1468
1469
 
1469
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
1470
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
1471
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
1470
1472
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1471
1473
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
1472
1474
  END;
1475
+
1476
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
1477
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
1478
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
1479
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1480
+ END;
1473
1481
  `);
1474
1482
  await client.executeMultiple(`
1475
1483
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -1872,6 +1880,13 @@ async function ensureSchema() {
1872
1880
  });
1873
1881
  } catch {
1874
1882
  }
1883
+ try {
1884
+ await client.execute({
1885
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
1886
+ args: []
1887
+ });
1888
+ } catch {
1889
+ }
1875
1890
  try {
1876
1891
  await client.execute({
1877
1892
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -2410,6 +2425,7 @@ async function disposeDatabase() {
2410
2425
  }
2411
2426
  }
2412
2427
  export {
2428
+ SOFT_DELETE_RETENTION_DAYS,
2413
2429
  disposeDatabase,
2414
2430
  disposeTurso,
2415
2431
  ensureSchema,
@@ -1339,6 +1339,7 @@ var init_db_daemon_client = __esm({
1339
1339
  // src/lib/database.ts
1340
1340
  var database_exports = {};
1341
1341
  __export(database_exports, {
1342
+ SOFT_DELETE_RETENTION_DAYS: () => SOFT_DELETE_RETENTION_DAYS,
1342
1343
  disposeDatabase: () => disposeDatabase,
1343
1344
  disposeTurso: () => disposeTurso,
1344
1345
  ensureSchema: () => ensureSchema,
@@ -1495,10 +1496,17 @@ async function ensureSchema() {
1495
1496
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1496
1497
  END;
1497
1498
 
1498
- CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories BEGIN
1499
+ CREATE TRIGGER IF NOT EXISTS memories_fts_au AFTER UPDATE ON memories
1500
+ WHEN new.status IS NULL OR new.status != 'deleted' BEGIN
1499
1501
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1500
1502
  INSERT INTO memories_fts(rowid, raw_text) VALUES (new.rowid, new.raw_text);
1501
1503
  END;
1504
+
1505
+ -- Soft-delete trigger: remove from FTS when status changes to 'deleted'
1506
+ CREATE TRIGGER IF NOT EXISTS memories_fts_soft_delete AFTER UPDATE ON memories
1507
+ WHEN new.status = 'deleted' AND (old.status IS NULL OR old.status != 'deleted') BEGIN
1508
+ INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
1509
+ END;
1502
1510
  `);
1503
1511
  await client.executeMultiple(`
1504
1512
  CREATE TABLE IF NOT EXISTS sync_meta (
@@ -1901,6 +1909,13 @@ async function ensureSchema() {
1901
1909
  });
1902
1910
  } catch {
1903
1911
  }
1912
+ try {
1913
+ await client.execute({
1914
+ sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
1915
+ args: []
1916
+ });
1917
+ } catch {
1918
+ }
1904
1919
  try {
1905
1920
  await client.execute({
1906
1921
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
@@ -2437,7 +2452,7 @@ async function disposeDatabase() {
2437
2452
  _resilientClient = null;
2438
2453
  }
2439
2454
  }
2440
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, disposeTurso;
2455
+ var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
2441
2456
  var init_database = __esm({
2442
2457
  "src/lib/database.ts"() {
2443
2458
  "use strict";
@@ -2451,6 +2466,7 @@ var init_database = __esm({
2451
2466
  _daemonClient = null;
2452
2467
  _adapterClient = null;
2453
2468
  initTurso = initDatabase;
2469
+ SOFT_DELETE_RETENTION_DAYS = 7;
2454
2470
  disposeTurso = disposeDatabase;
2455
2471
  }
2456
2472
  });