@askexenow/exe-os 0.9.102 → 0.9.104

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 (92) hide show
  1. package/dist/bin/agentic-ontology-backfill.js +334 -100
  2. package/dist/bin/agentic-reflection-backfill.js +328 -97
  3. package/dist/bin/agentic-semantic-label.js +328 -97
  4. package/dist/bin/backfill-conversations.js +332 -97
  5. package/dist/bin/backfill-responses.js +332 -97
  6. package/dist/bin/backfill-vectors.js +337 -106
  7. package/dist/bin/bulk-sync-postgres.js +335 -101
  8. package/dist/bin/cleanup-stale-review-tasks.js +356 -108
  9. package/dist/bin/cli.js +653 -405
  10. package/dist/bin/exe-agent.js +21 -3
  11. package/dist/bin/exe-assign.js +338 -94
  12. package/dist/bin/exe-boot.js +472 -239
  13. package/dist/bin/exe-call.js +22 -5
  14. package/dist/bin/exe-cloud.js +404 -158
  15. package/dist/bin/exe-dispatch.js +390 -142
  16. package/dist/bin/exe-doctor.js +349 -103
  17. package/dist/bin/exe-export-behaviors.js +351 -105
  18. package/dist/bin/exe-forget.js +352 -103
  19. package/dist/bin/exe-gateway.js +420 -172
  20. package/dist/bin/exe-heartbeat.js +361 -113
  21. package/dist/bin/exe-kill.js +344 -98
  22. package/dist/bin/exe-launch-agent.js +375 -129
  23. package/dist/bin/exe-new-employee.js +83 -67
  24. package/dist/bin/exe-pending-messages.js +356 -108
  25. package/dist/bin/exe-pending-notifications.js +358 -110
  26. package/dist/bin/exe-pending-reviews.js +359 -111
  27. package/dist/bin/exe-rename.js +354 -108
  28. package/dist/bin/exe-review.js +343 -97
  29. package/dist/bin/exe-search.js +363 -113
  30. package/dist/bin/exe-session-cleanup.js +403 -155
  31. package/dist/bin/exe-settings.js +14 -9
  32. package/dist/bin/exe-start-codex.js +365 -131
  33. package/dist/bin/exe-start-opencode.js +359 -125
  34. package/dist/bin/exe-status.js +356 -108
  35. package/dist/bin/exe-team.js +343 -97
  36. package/dist/bin/git-sweep.js +390 -142
  37. package/dist/bin/graph-backfill.js +334 -100
  38. package/dist/bin/graph-export.js +346 -100
  39. package/dist/bin/install.js +1 -0
  40. package/dist/bin/intercom-check.js +403 -155
  41. package/dist/bin/pre-publish.js +12 -0
  42. package/dist/bin/scan-tasks.js +393 -145
  43. package/dist/bin/setup.js +331 -159
  44. package/dist/bin/shard-migrate.js +328 -94
  45. package/dist/gateway/index.js +406 -158
  46. package/dist/hooks/bug-report-worker.js +396 -148
  47. package/dist/hooks/codex-stop-task-finalizer.js +374 -126
  48. package/dist/hooks/commit-complete.js +390 -142
  49. package/dist/hooks/error-recall.js +365 -115
  50. package/dist/hooks/ingest.js +357 -111
  51. package/dist/hooks/instructions-loaded.js +351 -105
  52. package/dist/hooks/notification.js +343 -97
  53. package/dist/hooks/post-compact.js +358 -110
  54. package/dist/hooks/post-tool-combined.js +384 -132
  55. package/dist/hooks/pre-compact.js +391 -143
  56. package/dist/hooks/pre-tool-use.js +362 -114
  57. package/dist/hooks/prompt-submit.js +422 -170
  58. package/dist/hooks/session-end.js +393 -145
  59. package/dist/hooks/session-start.js +390 -138
  60. package/dist/hooks/stop.js +361 -113
  61. package/dist/hooks/subagent-stop.js +354 -106
  62. package/dist/hooks/summary-worker.js +418 -185
  63. package/dist/index.js +400 -152
  64. package/dist/lib/cloud-sync.js +291 -131
  65. package/dist/lib/consolidation.js +8 -2
  66. package/dist/lib/database.js +233 -73
  67. package/dist/lib/db.js +233 -73
  68. package/dist/lib/device-registry.js +237 -77
  69. package/dist/lib/employee-templates.js +19 -1
  70. package/dist/lib/exe-daemon.js +705 -409
  71. package/dist/lib/hybrid-search.js +363 -113
  72. package/dist/lib/identity.js +9 -5
  73. package/dist/lib/messaging.js +26 -20
  74. package/dist/lib/reminders.js +5 -1
  75. package/dist/lib/schedules.js +320 -89
  76. package/dist/lib/skill-learning.js +28 -24
  77. package/dist/lib/store.js +342 -96
  78. package/dist/lib/tasks.js +82 -76
  79. package/dist/lib/tmux-routing.js +74 -68
  80. package/dist/lib/token-spend.js +5 -1
  81. package/dist/mcp/server.js +628 -355
  82. package/dist/mcp/tools/complete-reminder.js +5 -1
  83. package/dist/mcp/tools/create-reminder.js +5 -1
  84. package/dist/mcp/tools/create-task.js +89 -83
  85. package/dist/mcp/tools/deactivate-behavior.js +7 -3
  86. package/dist/mcp/tools/list-reminders.js +5 -1
  87. package/dist/mcp/tools/list-tasks.js +28 -21
  88. package/dist/mcp/tools/send-message.js +28 -22
  89. package/dist/mcp/tools/update-task.js +89 -83
  90. package/dist/runtime/index.js +390 -142
  91. package/dist/tui/App.js +437 -189
  92. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2482,9 +2482,79 @@ __export(database_exports, {
2482
2482
  isInitialized: () => isInitialized,
2483
2483
  setExternalClient: () => setExternalClient
2484
2484
  });
2485
- import { chmodSync as chmodSync2 } from "fs";
2485
+ import { chmodSync as chmodSync2, existsSync as existsSync9, statSync as statSync2, copyFileSync, unlinkSync as unlinkSync3, openSync as openSync2, closeSync as closeSync2, mkdirSync as mkdirSync4 } from "fs";
2486
2486
  import { createClient } from "@libsql/client";
2487
+ import { homedir } from "os";
2488
+ import { join } from "path";
2489
+ function logCatchDebug(context, err) {
2490
+ if (_debugDb) {
2491
+ process.stderr.write(
2492
+ `[database] ${context}: ${err instanceof Error ? err.message : String(err)}
2493
+ `
2494
+ );
2495
+ }
2496
+ }
2497
+ function acquireDbLock() {
2498
+ mkdirSync4(join(homedir(), ".exe-os"), { recursive: true });
2499
+ try {
2500
+ _lockFd = openSync2(DB_LOCK_PATH, "wx");
2501
+ } catch (err) {
2502
+ if (err && typeof err === "object" && "code" in err && err.code === "EEXIST") {
2503
+ try {
2504
+ const lockStat = statSync2(DB_LOCK_PATH);
2505
+ if (Date.now() - lockStat.mtimeMs > 6e4) {
2506
+ unlinkSync3(DB_LOCK_PATH);
2507
+ _lockFd = openSync2(DB_LOCK_PATH, "wx");
2508
+ return;
2509
+ }
2510
+ } catch (e) {
2511
+ logCatchDebug("stale lock check", e);
2512
+ }
2513
+ process.stderr.write(
2514
+ "[database] WARN: Another process holds db.lock \u2014 waiting briefly then proceeding.\n"
2515
+ );
2516
+ return;
2517
+ }
2518
+ throw err;
2519
+ }
2520
+ }
2521
+ function releaseDbLock() {
2522
+ if (_lockFd !== null) {
2523
+ try {
2524
+ closeSync2(_lockFd);
2525
+ } catch (e) {
2526
+ logCatchDebug("lock close", e);
2527
+ }
2528
+ _lockFd = null;
2529
+ }
2530
+ try {
2531
+ unlinkSync3(DB_LOCK_PATH);
2532
+ } catch (e) {
2533
+ logCatchDebug("lock unlink", e);
2534
+ }
2535
+ }
2487
2536
  async function initDatabase(config2) {
2537
+ acquireDbLock();
2538
+ if (existsSync9(config2.dbPath)) {
2539
+ const dbStat = statSync2(config2.dbPath);
2540
+ if (dbStat.size === 0) {
2541
+ const walPath = config2.dbPath + "-wal";
2542
+ if (existsSync9(walPath) && statSync2(walPath).size > 0) {
2543
+ const backupPath = config2.dbPath + ".zeroed-" + Date.now();
2544
+ copyFileSync(config2.dbPath, backupPath);
2545
+ unlinkSync3(config2.dbPath);
2546
+ process.stderr.write(
2547
+ `[database] CRITICAL: DB was 0 bytes. Moved to ${backupPath}, attempting WAL recovery.
2548
+ `
2549
+ );
2550
+ } else {
2551
+ process.stderr.write(
2552
+ `[database] CRITICAL: DB is 0 bytes and no WAL available for recovery. Data may be lost. Check backups at ${config2.dbPath}.bak
2553
+ `
2554
+ );
2555
+ }
2556
+ }
2557
+ }
2488
2558
  if (_walCheckpointTimer) {
2489
2559
  clearInterval(_walCheckpointTimer);
2490
2560
  _walCheckpointTimer = null;
@@ -2511,10 +2581,8 @@ async function initDatabase(config2) {
2511
2581
  _client = createClient(opts);
2512
2582
  _resilientClient = wrapWithRetry(_client);
2513
2583
  _adapterClient = _resilientClient;
2514
- _client.execute("PRAGMA busy_timeout = 30000").catch(() => {
2515
- });
2516
- _client.execute("PRAGMA journal_mode = WAL").catch(() => {
2517
- });
2584
+ await _client.execute("PRAGMA busy_timeout = 30000");
2585
+ await _client.execute("PRAGMA journal_mode = WAL");
2518
2586
  if (_walCheckpointTimer) clearInterval(_walCheckpointTimer);
2519
2587
  _walCheckpointTimer = setInterval(() => {
2520
2588
  _client?.execute("PRAGMA wal_checkpoint(PASSIVE)").catch(() => {
@@ -2529,11 +2597,16 @@ async function initDatabase(config2) {
2529
2597
  for (const suffix of ["-wal", "-shm"]) {
2530
2598
  try {
2531
2599
  chmodSync2(config2.dbPath + suffix, 384);
2532
- } catch {
2600
+ } catch (chmodErr) {
2601
+ process.stderr.write(`[database] chmod ${suffix} failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
2602
+ `);
2533
2603
  }
2534
2604
  }
2535
- } catch {
2605
+ } catch (chmodErr) {
2606
+ process.stderr.write(`[database] chmod db failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
2607
+ `);
2536
2608
  }
2609
+ releaseDbLock();
2537
2610
  }
2538
2611
  function isInitialized() {
2539
2612
  return _adapterClient !== null || _client !== null;
@@ -2588,7 +2661,8 @@ async function ensureSchema() {
2588
2661
  await client.execute("PRAGMA wal_autocheckpoint = 1000");
2589
2662
  try {
2590
2663
  await client.execute("PRAGMA libsql_vector_search_ef = 128");
2591
- } catch {
2664
+ } catch (e) {
2665
+ logCatchDebug("migration", e);
2592
2666
  }
2593
2667
  await client.executeMultiple(`
2594
2668
  CREATE TABLE IF NOT EXISTS memories (
@@ -2653,6 +2727,23 @@ async function ensureSchema() {
2653
2727
  INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
2654
2728
  END;
2655
2729
  `);
2730
+ try {
2731
+ await client.execute("SELECT COUNT(*) FROM memories_fts LIMIT 1");
2732
+ } catch (ftsErr) {
2733
+ process.stderr.write(
2734
+ `[database] WARN: memories_fts corrupted (${ftsErr instanceof Error ? ftsErr.message : String(ftsErr)}) \u2014 rebuilding FTS index.
2735
+ `
2736
+ );
2737
+ try {
2738
+ await client.execute("INSERT INTO memories_fts(memories_fts) VALUES('rebuild')");
2739
+ process.stderr.write("[database] FTS index rebuilt successfully.\n");
2740
+ } catch (rebuildErr) {
2741
+ process.stderr.write(
2742
+ `[database] ERROR: FTS rebuild failed: ${rebuildErr instanceof Error ? rebuildErr.message : String(rebuildErr)}
2743
+ `
2744
+ );
2745
+ }
2746
+ }
2656
2747
  await client.executeMultiple(`
2657
2748
  CREATE TABLE IF NOT EXISTS sync_meta (
2658
2749
  key TEXT PRIMARY KEY,
@@ -2711,35 +2802,40 @@ async function ensureSchema() {
2711
2802
  });
2712
2803
  }
2713
2804
  }
2714
- } catch {
2805
+ } catch (seedErr) {
2806
+ logCatchDebug("behavior seed", seedErr);
2715
2807
  }
2716
2808
  try {
2717
2809
  await client.execute({
2718
2810
  sql: `ALTER TABLE behaviors ADD COLUMN priority TEXT DEFAULT 'p1'`,
2719
2811
  args: []
2720
2812
  });
2721
- } catch {
2813
+ } catch (e) {
2814
+ logCatchDebug("migration", e);
2722
2815
  }
2723
2816
  try {
2724
2817
  await client.execute({
2725
2818
  sql: `ALTER TABLE behaviors ADD COLUMN vector F32_BLOB(${EMBEDDING_DIM})`,
2726
2819
  args: []
2727
2820
  });
2728
- } catch {
2821
+ } catch (e) {
2822
+ logCatchDebug("migration", e);
2729
2823
  }
2730
2824
  try {
2731
2825
  await client.execute({
2732
2826
  sql: `ALTER TABLE tasks ADD COLUMN blocked_by TEXT`,
2733
2827
  args: []
2734
2828
  });
2735
- } catch {
2829
+ } catch (e) {
2830
+ logCatchDebug("migration", e);
2736
2831
  }
2737
2832
  try {
2738
2833
  await client.execute({
2739
2834
  sql: `ALTER TABLE tasks ADD COLUMN parent_task_id TEXT`,
2740
2835
  args: []
2741
2836
  });
2742
- } catch {
2837
+ } catch (e) {
2838
+ logCatchDebug("migration", e);
2743
2839
  }
2744
2840
  try {
2745
2841
  await client.execute({
@@ -2748,98 +2844,112 @@ async function ensureSchema() {
2748
2844
  WHERE parent_task_id IS NOT NULL`,
2749
2845
  args: []
2750
2846
  });
2751
- } catch {
2847
+ } catch (e) {
2848
+ logCatchDebug("migration", e);
2752
2849
  }
2753
2850
  try {
2754
2851
  await client.execute({
2755
2852
  sql: `UPDATE tasks SET status = 'done' WHERE status = 'completed'`,
2756
2853
  args: []
2757
2854
  });
2758
- } catch {
2855
+ } catch (e) {
2856
+ logCatchDebug("migration", e);
2759
2857
  }
2760
2858
  try {
2761
2859
  await client.execute({
2762
2860
  sql: `ALTER TABLE tasks ADD COLUMN reviewer TEXT`,
2763
2861
  args: []
2764
2862
  });
2765
- } catch {
2863
+ } catch (e) {
2864
+ logCatchDebug("migration", e);
2766
2865
  }
2767
2866
  try {
2768
2867
  await client.execute({
2769
2868
  sql: `ALTER TABLE tasks ADD COLUMN context TEXT`,
2770
2869
  args: []
2771
2870
  });
2772
- } catch {
2871
+ } catch (e) {
2872
+ logCatchDebug("migration", e);
2773
2873
  }
2774
2874
  try {
2775
2875
  await client.execute({
2776
2876
  sql: `ALTER TABLE tasks ADD COLUMN result TEXT`,
2777
2877
  args: []
2778
2878
  });
2779
- } catch {
2879
+ } catch (e) {
2880
+ logCatchDebug("migration", e);
2780
2881
  }
2781
2882
  try {
2782
2883
  await client.execute({
2783
2884
  sql: `ALTER TABLE tasks ADD COLUMN assigned_tmux TEXT`,
2784
2885
  args: []
2785
2886
  });
2786
- } catch {
2887
+ } catch (e) {
2888
+ logCatchDebug("migration", e);
2787
2889
  }
2788
2890
  try {
2789
2891
  await client.execute({
2790
2892
  sql: `ALTER TABLE tasks ADD COLUMN checkpoint TEXT`,
2791
2893
  args: []
2792
2894
  });
2793
- } catch {
2895
+ } catch (e) {
2896
+ logCatchDebug("migration", e);
2794
2897
  }
2795
2898
  try {
2796
2899
  await client.execute({
2797
2900
  sql: `ALTER TABLE tasks ADD COLUMN checkpoint_count INTEGER NOT NULL DEFAULT 0`,
2798
2901
  args: []
2799
2902
  });
2800
- } catch {
2903
+ } catch (e) {
2904
+ logCatchDebug("migration", e);
2801
2905
  }
2802
2906
  try {
2803
2907
  await client.execute({
2804
2908
  sql: `ALTER TABLE tasks ADD COLUMN complexity TEXT NOT NULL DEFAULT 'standard'`,
2805
2909
  args: []
2806
2910
  });
2807
- } catch {
2911
+ } catch (e) {
2912
+ logCatchDebug("migration", e);
2808
2913
  }
2809
2914
  try {
2810
2915
  await client.execute({
2811
2916
  sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
2812
2917
  args: []
2813
2918
  });
2814
- } catch {
2919
+ } catch (e) {
2920
+ logCatchDebug("migration", e);
2815
2921
  }
2816
2922
  try {
2817
2923
  await client.execute({
2818
2924
  sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
2819
2925
  args: []
2820
2926
  });
2821
- } catch {
2927
+ } catch (e) {
2928
+ logCatchDebug("migration", e);
2822
2929
  }
2823
2930
  try {
2824
2931
  await client.execute({
2825
2932
  sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
2826
2933
  args: []
2827
2934
  });
2828
- } catch {
2935
+ } catch (e) {
2936
+ logCatchDebug("migration", e);
2829
2937
  }
2830
2938
  try {
2831
2939
  await client.execute({
2832
2940
  sql: `ALTER TABLE memories ADD COLUMN author_device_id TEXT`,
2833
2941
  args: []
2834
2942
  });
2835
- } catch {
2943
+ } catch (e) {
2944
+ logCatchDebug("migration", e);
2836
2945
  }
2837
2946
  try {
2838
2947
  await client.execute({
2839
2948
  sql: `ALTER TABLE memories ADD COLUMN scope TEXT NOT NULL DEFAULT 'business'`,
2840
2949
  args: []
2841
2950
  });
2842
- } catch {
2951
+ } catch (e) {
2952
+ logCatchDebug("migration", e);
2843
2953
  }
2844
2954
  await client.executeMultiple(`
2845
2955
  CREATE TABLE IF NOT EXISTS consolidations (
@@ -2944,14 +3054,16 @@ async function ensureSchema() {
2944
3054
  sql: `ALTER TABLE notifications ADD COLUMN session_scope TEXT`,
2945
3055
  args: []
2946
3056
  });
2947
- } catch {
3057
+ } catch (e) {
3058
+ logCatchDebug("migration", e);
2948
3059
  }
2949
3060
  try {
2950
3061
  await client.execute({
2951
3062
  sql: `ALTER TABLE messages ADD COLUMN session_scope TEXT`,
2952
3063
  args: []
2953
3064
  });
2954
- } catch {
3065
+ } catch (e) {
3066
+ logCatchDebug("migration", e);
2955
3067
  }
2956
3068
  await client.executeMultiple(`
2957
3069
  CREATE INDEX IF NOT EXISTS idx_notifications_agent_scope_read
@@ -2977,7 +3089,8 @@ async function ensureSchema() {
2977
3089
  sql: `UPDATE tasks SET project_name = 'exe-os' WHERE project_name = 'worker'`,
2978
3090
  args: []
2979
3091
  });
2980
- } catch {
3092
+ } catch (e) {
3093
+ logCatchDebug("migration", e);
2981
3094
  }
2982
3095
  await client.executeMultiple(`
2983
3096
  CREATE TABLE IF NOT EXISTS trajectories (
@@ -3001,7 +3114,8 @@ async function ensureSchema() {
3001
3114
  `);
3002
3115
  try {
3003
3116
  await client.execute("ALTER TABLE trajectories ADD COLUMN skill_id TEXT");
3004
- } catch {
3117
+ } catch (e) {
3118
+ logCatchDebug("migration", e);
3005
3119
  }
3006
3120
  await client.executeMultiple(`
3007
3121
  CREATE TABLE IF NOT EXISTS consolidations (
@@ -3038,63 +3152,72 @@ async function ensureSchema() {
3038
3152
  sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
3039
3153
  args: []
3040
3154
  });
3041
- } catch {
3155
+ } catch (e) {
3156
+ logCatchDebug("migration", e);
3042
3157
  }
3043
3158
  try {
3044
3159
  await client.execute({
3045
3160
  sql: `ALTER TABLE memories ADD COLUMN importance INTEGER DEFAULT 5`,
3046
3161
  args: []
3047
3162
  });
3048
- } catch {
3163
+ } catch (e) {
3164
+ logCatchDebug("migration", e);
3049
3165
  }
3050
3166
  try {
3051
3167
  await client.execute({
3052
3168
  sql: `ALTER TABLE memories ADD COLUMN status TEXT DEFAULT 'active'`,
3053
3169
  args: []
3054
3170
  });
3055
- } catch {
3171
+ } catch (e) {
3172
+ logCatchDebug("migration", e);
3056
3173
  }
3057
3174
  try {
3058
3175
  await client.execute({
3059
3176
  sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
3060
3177
  args: []
3061
3178
  });
3062
- } catch {
3179
+ } catch (e) {
3180
+ logCatchDebug("migration", e);
3063
3181
  }
3064
3182
  try {
3065
3183
  await client.execute({
3066
3184
  sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
3067
3185
  args: []
3068
3186
  });
3069
- } catch {
3187
+ } catch (e) {
3188
+ logCatchDebug("migration", e);
3070
3189
  }
3071
3190
  try {
3072
3191
  await client.execute({
3073
3192
  sql: `ALTER TABLE memories ADD COLUMN last_accessed TEXT`,
3074
3193
  args: []
3075
3194
  });
3076
- } catch {
3195
+ } catch (e) {
3196
+ logCatchDebug("migration", e);
3077
3197
  }
3078
3198
  try {
3079
3199
  await client.execute({
3080
3200
  sql: `UPDATE memories SET last_accessed = timestamp WHERE last_accessed IS NULL`,
3081
3201
  args: []
3082
3202
  });
3083
- } catch {
3203
+ } catch (e) {
3204
+ logCatchDebug("migration", e);
3084
3205
  }
3085
3206
  try {
3086
3207
  await client.execute({
3087
3208
  sql: `ALTER TABLE memories ADD COLUMN wiki_synced INTEGER DEFAULT 0`,
3088
3209
  args: []
3089
3210
  });
3090
- } catch {
3211
+ } catch (e) {
3212
+ logCatchDebug("migration", e);
3091
3213
  }
3092
3214
  try {
3093
3215
  await client.execute({
3094
3216
  sql: `ALTER TABLE memories ADD COLUMN graph_extracted INTEGER DEFAULT 0`,
3095
3217
  args: []
3096
3218
  });
3097
- } catch {
3219
+ } catch (e) {
3220
+ logCatchDebug("migration", e);
3098
3221
  }
3099
3222
  for (const col of [
3100
3223
  "ALTER TABLE memories ADD COLUMN content_hash TEXT",
@@ -3102,14 +3225,16 @@ async function ensureSchema() {
3102
3225
  ]) {
3103
3226
  try {
3104
3227
  await client.execute(col);
3105
- } catch {
3228
+ } catch (e) {
3229
+ logCatchDebug("migration", e);
3106
3230
  }
3107
3231
  }
3108
3232
  try {
3109
3233
  await client.execute(
3110
3234
  `CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash, agent_id)`
3111
3235
  );
3112
- } catch {
3236
+ } catch (e) {
3237
+ logCatchDebug("migration", e);
3113
3238
  }
3114
3239
  try {
3115
3240
  await client.execute(
@@ -3117,7 +3242,8 @@ async function ensureSchema() {
3117
3242
  ON memories(content_hash, agent_id, project_name, memory_type)
3118
3243
  WHERE content_hash IS NOT NULL`
3119
3244
  );
3120
- } catch {
3245
+ } catch (e) {
3246
+ logCatchDebug("migration", e);
3121
3247
  }
3122
3248
  await client.executeMultiple(`
3123
3249
  CREATE TABLE IF NOT EXISTS entities (
@@ -3193,7 +3319,8 @@ async function ensureSchema() {
3193
3319
  `);
3194
3320
  try {
3195
3321
  await client.execute("INSERT INTO entities_fts(entities_fts) VALUES('rebuild')");
3196
- } catch {
3322
+ } catch (e) {
3323
+ logCatchDebug("migration", e);
3197
3324
  }
3198
3325
  await client.executeMultiple(`
3199
3326
  CREATE TABLE IF NOT EXISTS entity_aliases (
@@ -3208,14 +3335,16 @@ async function ensureSchema() {
3208
3335
  ]) {
3209
3336
  try {
3210
3337
  await client.execute(col);
3211
- } catch {
3338
+ } catch (e) {
3339
+ logCatchDebug("migration", e);
3212
3340
  }
3213
3341
  }
3214
3342
  try {
3215
3343
  await client.execute(
3216
3344
  `CREATE INDEX IF NOT EXISTS idx_memories_status ON memories(status)`
3217
3345
  );
3218
- } catch {
3346
+ } catch (e) {
3347
+ logCatchDebug("migration", e);
3219
3348
  }
3220
3349
  await client.executeMultiple(`
3221
3350
  CREATE TABLE IF NOT EXISTS identity (
@@ -3314,7 +3443,8 @@ async function ensureSchema() {
3314
3443
  sql: `ALTER TABLE memories ADD COLUMN ${column}`,
3315
3444
  args: []
3316
3445
  });
3317
- } catch {
3446
+ } catch (e) {
3447
+ logCatchDebug("migration", e);
3318
3448
  }
3319
3449
  }
3320
3450
  for (const col of [
@@ -3323,7 +3453,8 @@ async function ensureSchema() {
3323
3453
  ]) {
3324
3454
  try {
3325
3455
  await client.execute(col);
3326
- } catch {
3456
+ } catch (e) {
3457
+ logCatchDebug("migration", e);
3327
3458
  }
3328
3459
  }
3329
3460
  await client.executeMultiple(`
@@ -3508,56 +3639,64 @@ async function ensureSchema() {
3508
3639
  args: []
3509
3640
  });
3510
3641
  }
3511
- } catch {
3642
+ } catch (e) {
3643
+ logCatchDebug("session_agent_map backfill", e);
3512
3644
  }
3513
3645
  try {
3514
3646
  await client.execute({
3515
3647
  sql: `ALTER TABLE session_agent_map ADD COLUMN cache_cold_count INTEGER NOT NULL DEFAULT 0`,
3516
3648
  args: []
3517
3649
  });
3518
- } catch {
3650
+ } catch (e) {
3651
+ logCatchDebug("migration", e);
3519
3652
  }
3520
3653
  try {
3521
3654
  await client.execute({
3522
3655
  sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
3523
3656
  args: []
3524
3657
  });
3525
- } catch {
3658
+ } catch (e) {
3659
+ logCatchDebug("migration", e);
3526
3660
  }
3527
3661
  try {
3528
3662
  await client.execute({
3529
3663
  sql: `ALTER TABLE tasks ADD COLUMN budget_fallback_model TEXT`,
3530
3664
  args: []
3531
3665
  });
3532
- } catch {
3666
+ } catch (e) {
3667
+ logCatchDebug("migration", e);
3533
3668
  }
3534
3669
  try {
3535
3670
  await client.execute({
3536
3671
  sql: `ALTER TABLE tasks ADD COLUMN tokens_used INTEGER DEFAULT 0`,
3537
3672
  args: []
3538
3673
  });
3539
- } catch {
3674
+ } catch (e) {
3675
+ logCatchDebug("migration", e);
3540
3676
  }
3541
3677
  try {
3542
3678
  await client.execute({
3543
3679
  sql: `ALTER TABLE tasks ADD COLUMN tokens_warned_at INTEGER`,
3544
3680
  args: []
3545
3681
  });
3546
- } catch {
3682
+ } catch (e) {
3683
+ logCatchDebug("migration", e);
3547
3684
  }
3548
3685
  try {
3549
3686
  await client.execute({
3550
3687
  sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
3551
3688
  args: []
3552
3689
  });
3553
- } catch {
3690
+ } catch (e) {
3691
+ logCatchDebug("migration", e);
3554
3692
  }
3555
3693
  try {
3556
3694
  await client.execute({
3557
3695
  sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
3558
3696
  args: []
3559
3697
  });
3560
- } catch {
3698
+ } catch (e) {
3699
+ logCatchDebug("migration", e);
3561
3700
  }
3562
3701
  await client.executeMultiple(`
3563
3702
  CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
@@ -3756,13 +3895,15 @@ async function ensureSchema() {
3756
3895
  sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
3757
3896
  args: []
3758
3897
  });
3759
- } catch {
3898
+ } catch (e) {
3899
+ logCatchDebug("migration", e);
3760
3900
  }
3761
3901
  try {
3762
3902
  await client.execute(
3763
3903
  `CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)`
3764
3904
  );
3765
- } catch {
3905
+ } catch (e) {
3906
+ logCatchDebug("migration", e);
3766
3907
  }
3767
3908
  try {
3768
3909
  await client.execute({
@@ -3773,20 +3914,23 @@ async function ensureSchema() {
3773
3914
  sql: `UPDATE memories SET tier = 2 WHERE tool_name IN ('store_memory', 'manual') AND importance >= 5 AND tier = 3`,
3774
3915
  args: []
3775
3916
  });
3776
- } catch {
3917
+ } catch (e) {
3918
+ logCatchDebug("migration", e);
3777
3919
  }
3778
3920
  try {
3779
3921
  await client.execute({
3780
3922
  sql: `ALTER TABLE memories ADD COLUMN supersedes_id TEXT`,
3781
3923
  args: []
3782
3924
  });
3783
- } catch {
3925
+ } catch (e) {
3926
+ logCatchDebug("migration", e);
3784
3927
  }
3785
3928
  try {
3786
3929
  await client.execute(
3787
3930
  `CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL`
3788
3931
  );
3789
- } catch {
3932
+ } catch (e) {
3933
+ logCatchDebug("migration", e);
3790
3934
  }
3791
3935
  for (const col of [
3792
3936
  "ALTER TABLE tasks ADD COLUMN checkpoint TEXT",
@@ -3794,7 +3938,8 @@ async function ensureSchema() {
3794
3938
  ]) {
3795
3939
  try {
3796
3940
  await client.execute(col);
3797
- } catch {
3941
+ } catch (e) {
3942
+ logCatchDebug("migration", e);
3798
3943
  }
3799
3944
  }
3800
3945
  try {
@@ -3802,13 +3947,15 @@ async function ensureSchema() {
3802
3947
  sql: `ALTER TABLE memories ADD COLUMN draft INTEGER DEFAULT 0`,
3803
3948
  args: []
3804
3949
  });
3805
- } catch {
3950
+ } catch (e) {
3951
+ logCatchDebug("migration", e);
3806
3952
  }
3807
3953
  try {
3808
3954
  await client.execute(
3809
3955
  `CREATE INDEX IF NOT EXISTS idx_memories_draft ON memories(draft) WHERE draft = 1`
3810
3956
  );
3811
- } catch {
3957
+ } catch (e) {
3958
+ logCatchDebug("migration", e);
3812
3959
  }
3813
3960
  for (const col of [
3814
3961
  "ALTER TABLE memories ADD COLUMN valid_from TEXT",
@@ -3816,7 +3963,8 @@ async function ensureSchema() {
3816
3963
  ]) {
3817
3964
  try {
3818
3965
  await client.execute(col);
3819
- } catch {
3966
+ } catch (e) {
3967
+ logCatchDebug("migration", e);
3820
3968
  }
3821
3969
  }
3822
3970
  try {
@@ -3824,27 +3972,31 @@ async function ensureSchema() {
3824
3972
  sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
3825
3973
  args: []
3826
3974
  });
3827
- } catch {
3975
+ } catch (e) {
3976
+ logCatchDebug("migration", e);
3828
3977
  }
3829
3978
  try {
3830
3979
  await client.execute({
3831
3980
  sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
3832
3981
  args: []
3833
3982
  });
3834
- } catch {
3983
+ } catch (e) {
3984
+ logCatchDebug("migration", e);
3835
3985
  }
3836
3986
  try {
3837
3987
  await client.execute(
3838
3988
  `CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(memory_type)`
3839
3989
  );
3840
- } catch {
3990
+ } catch (e) {
3991
+ logCatchDebug("migration", e);
3841
3992
  }
3842
3993
  try {
3843
3994
  await client.execute({
3844
3995
  sql: `ALTER TABLE memories ADD COLUMN trajectory TEXT`,
3845
3996
  args: []
3846
3997
  });
3847
- } catch {
3998
+ } catch (e) {
3999
+ logCatchDebug("migration", e);
3848
4000
  }
3849
4001
  for (const col of [
3850
4002
  "ALTER TABLE memories ADD COLUMN intent TEXT",
@@ -3865,7 +4017,8 @@ async function ensureSchema() {
3865
4017
  ]) {
3866
4018
  try {
3867
4019
  await client.execute(col);
3868
- } catch {
4020
+ } catch (e) {
4021
+ logCatchDebug("migration", e);
3869
4022
  }
3870
4023
  }
3871
4024
  try {
@@ -3873,14 +4026,16 @@ async function ensureSchema() {
3873
4026
  sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
3874
4027
  args: []
3875
4028
  });
3876
- } catch {
4029
+ } catch (e) {
4030
+ logCatchDebug("migration", e);
3877
4031
  }
3878
4032
  try {
3879
4033
  await client.execute({
3880
4034
  sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
3881
4035
  args: []
3882
4036
  });
3883
- } catch {
4037
+ } catch (e) {
4038
+ logCatchDebug("migration", e);
3884
4039
  }
3885
4040
  }
3886
4041
  async function disposeDatabase() {
@@ -3891,7 +4046,8 @@ async function disposeDatabase() {
3891
4046
  if (_client) {
3892
4047
  try {
3893
4048
  await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
3894
- } catch {
4049
+ } catch (e) {
4050
+ logCatchDebug("WAL checkpoint", e);
3895
4051
  }
3896
4052
  }
3897
4053
  if (_daemonClient) {
@@ -3907,8 +4063,9 @@ async function disposeDatabase() {
3907
4063
  _client = null;
3908
4064
  _resilientClient = null;
3909
4065
  }
4066
+ releaseDbLock();
3910
4067
  }
3911
- var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
4068
+ var _debugDb, _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, _lockFd, DB_LOCK_PATH, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
3912
4069
  var init_database = __esm({
3913
4070
  "src/lib/database.ts"() {
3914
4071
  "use strict";
@@ -3916,11 +4073,14 @@ var init_database = __esm({
3916
4073
  init_employees();
3917
4074
  init_database_adapter();
3918
4075
  init_memory();
4076
+ _debugDb = process.env.EXE_DEBUG === "1";
3919
4077
  _client = null;
3920
4078
  _resilientClient = null;
3921
4079
  _walCheckpointTimer = null;
3922
4080
  _daemonClient = null;
3923
4081
  _adapterClient = null;
4082
+ _lockFd = null;
4083
+ DB_LOCK_PATH = join(homedir(), ".exe-os", "db.lock");
3924
4084
  initTurso = initDatabase;
3925
4085
  SOFT_DELETE_RETENTION_DAYS = 7;
3926
4086
  disposeTurso = disposeDatabase;
@@ -3928,7 +4088,7 @@ var init_database = __esm({
3928
4088
  });
3929
4089
 
3930
4090
  // src/lib/license.ts
3931
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync9, mkdirSync as mkdirSync4 } from "fs";
4091
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync10, mkdirSync as mkdirSync5 } from "fs";
3932
4092
  import { randomUUID as randomUUID3 } from "crypto";
3933
4093
  import { createRequire as createRequire2 } from "module";
3934
4094
  import { pathToFileURL as pathToFileURL2 } from "url";
@@ -3955,11 +4115,11 @@ var init_license = __esm({
3955
4115
  });
3956
4116
 
3957
4117
  // src/lib/plan-limits.ts
3958
- import { readFileSync as readFileSync9, existsSync as existsSync10 } from "fs";
4118
+ import { readFileSync as readFileSync9, existsSync as existsSync11 } from "fs";
3959
4119
  import path11 from "path";
3960
4120
  function getLicenseSync() {
3961
4121
  try {
3962
- if (!existsSync10(CACHE_PATH2)) return freeLicense();
4122
+ if (!existsSync11(CACHE_PATH2)) return freeLicense();
3963
4123
  const raw = JSON.parse(readFileSync9(CACHE_PATH2, "utf8"));
3964
4124
  if (!raw.token || typeof raw.token !== "string") return freeLicense();
3965
4125
  const parts = raw.token.split(".");
@@ -3998,7 +4158,7 @@ function assertEmployeeLimitSync(rosterPath) {
3998
4158
  const filePath = rosterPath ?? EMPLOYEES_PATH;
3999
4159
  let count = 0;
4000
4160
  try {
4001
- if (existsSync10(filePath)) {
4161
+ if (existsSync11(filePath)) {
4002
4162
  const raw = readFileSync9(filePath, "utf8");
4003
4163
  const employees = JSON.parse(raw);
4004
4164
  count = Array.isArray(employees) ? employees.length : 0;
@@ -4036,9 +4196,9 @@ var init_plan_limits = __esm({
4036
4196
  import os9 from "os";
4037
4197
  import path12 from "path";
4038
4198
  import {
4039
- existsSync as existsSync11,
4199
+ existsSync as existsSync12,
4040
4200
  lstatSync,
4041
- mkdirSync as mkdirSync5,
4201
+ mkdirSync as mkdirSync6,
4042
4202
  readlinkSync as readlinkSync2,
4043
4203
  symlinkSync as symlinkSync2
4044
4204
  } from "fs";
@@ -4054,8 +4214,8 @@ function claudeAgentLinkPath(homeDir, agentId) {
4054
4214
  function ensureAgentSymlink(agentId, homeDir = os9.homedir()) {
4055
4215
  const target = identitySourcePath(homeDir, agentId);
4056
4216
  const link = claudeAgentLinkPath(homeDir, agentId);
4057
- mkdirSync5(claudeAgentsDir(homeDir), { recursive: true });
4058
- if (existsSync11(link)) {
4217
+ mkdirSync6(claudeAgentsDir(homeDir), { recursive: true });
4218
+ if (existsSync12(link)) {
4059
4219
  let stat;
4060
4220
  try {
4061
4221
  stat = lstatSync(link);
@@ -4142,8 +4302,8 @@ import os10 from "os";
4142
4302
  import {
4143
4303
  readFileSync as readFileSync10,
4144
4304
  readdirSync,
4145
- unlinkSync as unlinkSync3,
4146
- existsSync as existsSync12,
4305
+ unlinkSync as unlinkSync4,
4306
+ existsSync as existsSync13,
4147
4307
  rmdirSync
4148
4308
  } from "fs";
4149
4309
  async function writeNotification(notification) {
@@ -4391,7 +4551,7 @@ import path15 from "path";
4391
4551
  import os11 from "os";
4392
4552
  import { execSync as execSync7 } from "child_process";
4393
4553
  import { mkdir as mkdir3, writeFile as writeFile3, appendFile } from "fs/promises";
4394
- import { existsSync as existsSync13, readFileSync as readFileSync11 } from "fs";
4554
+ import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
4395
4555
  async function writeCheckpoint(input) {
4396
4556
  const client = getClient();
4397
4557
  const row = await resolveTask(client, input.taskId);
@@ -4632,7 +4792,7 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
4632
4792
  const EXE_OS_DIR = path15.join(os11.homedir(), ".exe-os");
4633
4793
  const mdPath = path15.join(EXE_OS_DIR, taskFile);
4634
4794
  const mdDir = path15.dirname(mdPath);
4635
- if (!existsSync13(mdDir)) await mkdir3(mdDir, { recursive: true });
4795
+ if (!existsSync14(mdDir)) await mkdir3(mdDir, { recursive: true });
4636
4796
  const reviewer = input.reviewer ?? input.assignedBy;
4637
4797
  const mdContent = `# ${input.title}
4638
4798
 
@@ -4938,7 +5098,7 @@ async function deleteTaskCore(taskId, _baseDir) {
4938
5098
  async function ensureArchitectureDoc(baseDir, projectName) {
4939
5099
  const archPath = path15.join(baseDir, "exe", "ARCHITECTURE.md");
4940
5100
  try {
4941
- if (existsSync13(archPath)) return;
5101
+ if (existsSync14(archPath)) return;
4942
5102
  const template = [
4943
5103
  `# ${projectName} \u2014 System Architecture`,
4944
5104
  "",
@@ -4973,7 +5133,7 @@ async function ensureArchitectureDoc(baseDir, projectName) {
4973
5133
  async function ensureGitignoreExe(baseDir) {
4974
5134
  const gitignorePath = path15.join(baseDir, ".gitignore");
4975
5135
  try {
4976
- if (existsSync13(gitignorePath)) {
5136
+ if (existsSync14(gitignorePath)) {
4977
5137
  const content = readFileSync11(gitignorePath, "utf-8");
4978
5138
  if (/^\/?exe\/?$/m.test(content)) return;
4979
5139
  await appendFile(gitignorePath, "\n# Employee task assignments (private)\n/exe/\n");
@@ -5018,7 +5178,7 @@ __export(tasks_review_exports, {
5018
5178
  listPendingReviews: () => listPendingReviews
5019
5179
  });
5020
5180
  import path16 from "path";
5021
- import { existsSync as existsSync14, readdirSync as readdirSync2, unlinkSync as unlinkSync4 } from "fs";
5181
+ import { existsSync as existsSync15, readdirSync as readdirSync2, unlinkSync as unlinkSync5 } from "fs";
5022
5182
  function formatAge(isoTimestamp) {
5023
5183
  if (!isoTimestamp) return "";
5024
5184
  const ms = Date.now() - new Date(isoTimestamp).getTime();
@@ -5288,10 +5448,10 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
5288
5448
  }
5289
5449
  try {
5290
5450
  const cacheDir = path16.join(EXE_AI_DIR, "session-cache");
5291
- if (existsSync14(cacheDir)) {
5451
+ if (existsSync15(cacheDir)) {
5292
5452
  for (const f of readdirSync2(cacheDir)) {
5293
5453
  if (f.startsWith("review-notified-")) {
5294
- unlinkSync4(path16.join(cacheDir, f));
5454
+ unlinkSync5(path16.join(cacheDir, f));
5295
5455
  }
5296
5456
  }
5297
5457
  }
@@ -5514,10 +5674,10 @@ async function disposeEmbedder() {
5514
5674
  async function embedDirect(text) {
5515
5675
  const llamaCpp = await import("node-llama-cpp");
5516
5676
  const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
5517
- const { existsSync: existsSync19 } = await import("fs");
5677
+ const { existsSync: existsSync20 } = await import("fs");
5518
5678
  const path24 = await import("path");
5519
5679
  const modelPath = path24.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
5520
- if (!existsSync19(modelPath)) {
5680
+ if (!existsSync20(modelPath)) {
5521
5681
  throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
5522
5682
  }
5523
5683
  const llama = await llamaCpp.getLlama();
@@ -5955,7 +6115,7 @@ __export(tasks_exports, {
5955
6115
  writeCheckpoint: () => writeCheckpoint
5956
6116
  });
5957
6117
  import path18 from "path";
5958
- import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, unlinkSync as unlinkSync5 } from "fs";
6118
+ import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, unlinkSync as unlinkSync6 } from "fs";
5959
6119
  async function createTask(input) {
5960
6120
  const result = await createTaskCore(input);
5961
6121
  if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
@@ -5977,11 +6137,11 @@ async function updateTask(input) {
5977
6137
  const cacheDir = path18.join(EXE_AI_DIR, "session-cache");
5978
6138
  const cachePath = path18.join(cacheDir, `current-task-${agent}.json`);
5979
6139
  if (input.status === "in_progress") {
5980
- mkdirSync6(cacheDir, { recursive: true });
6140
+ mkdirSync7(cacheDir, { recursive: true });
5981
6141
  writeFileSync7(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
5982
6142
  } else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled" || input.status === "closed") {
5983
6143
  try {
5984
- unlinkSync5(cachePath);
6144
+ unlinkSync6(cachePath);
5985
6145
  } catch {
5986
6146
  }
5987
6147
  }
@@ -6449,11 +6609,11 @@ __export(tmux_routing_exports, {
6449
6609
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
6450
6610
  });
6451
6611
  import { execFileSync as execFileSync2, execSync as execSync8 } from "child_process";
6452
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7, existsSync as existsSync15, appendFileSync, readdirSync as readdirSync3 } from "fs";
6612
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync8, mkdirSync as mkdirSync8, existsSync as existsSync16, appendFileSync, readdirSync as readdirSync3 } from "fs";
6453
6613
  import path19 from "path";
6454
6614
  import os12 from "os";
6455
6615
  import { fileURLToPath as fileURLToPath2 } from "url";
6456
- import { unlinkSync as unlinkSync6 } from "fs";
6616
+ import { unlinkSync as unlinkSync7 } from "fs";
6457
6617
  function spawnLockPath(sessionName) {
6458
6618
  return path19.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
6459
6619
  }
@@ -6466,11 +6626,11 @@ function isProcessAlive(pid) {
6466
6626
  }
6467
6627
  }
6468
6628
  function acquireSpawnLock2(sessionName) {
6469
- if (!existsSync15(SPAWN_LOCK_DIR)) {
6470
- mkdirSync7(SPAWN_LOCK_DIR, { recursive: true });
6629
+ if (!existsSync16(SPAWN_LOCK_DIR)) {
6630
+ mkdirSync8(SPAWN_LOCK_DIR, { recursive: true });
6471
6631
  }
6472
6632
  const lockFile = spawnLockPath(sessionName);
6473
- if (existsSync15(lockFile)) {
6633
+ if (existsSync16(lockFile)) {
6474
6634
  try {
6475
6635
  const lock = JSON.parse(readFileSync12(lockFile, "utf8"));
6476
6636
  const age = Date.now() - lock.timestamp;
@@ -6485,7 +6645,7 @@ function acquireSpawnLock2(sessionName) {
6485
6645
  }
6486
6646
  function releaseSpawnLock2(sessionName) {
6487
6647
  try {
6488
- unlinkSync6(spawnLockPath(sessionName));
6648
+ unlinkSync7(spawnLockPath(sessionName));
6489
6649
  } catch {
6490
6650
  }
6491
6651
  }
@@ -6498,7 +6658,7 @@ function resolveBehaviorsExporterScript() {
6498
6658
  "bin",
6499
6659
  "exe-export-behaviors.js"
6500
6660
  );
6501
- return existsSync15(scriptPath) ? scriptPath : null;
6661
+ return existsSync16(scriptPath) ? scriptPath : null;
6502
6662
  } catch {
6503
6663
  return null;
6504
6664
  }
@@ -6564,8 +6724,8 @@ function extractRootExe(name) {
6564
6724
  return parts.length > 0 ? parts[parts.length - 1] : null;
6565
6725
  }
6566
6726
  function registerParentExe(sessionKey, parentExe, dispatchedBy) {
6567
- if (!existsSync15(SESSION_CACHE)) {
6568
- mkdirSync7(SESSION_CACHE, { recursive: true });
6727
+ if (!existsSync16(SESSION_CACHE)) {
6728
+ mkdirSync8(SESSION_CACHE, { recursive: true });
6569
6729
  }
6570
6730
  const rootExe = extractRootExe(parentExe) ?? parentExe;
6571
6731
  const filePath = path19.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
@@ -6595,11 +6755,13 @@ function getDispatchedBy(sessionKey) {
6595
6755
  }
6596
6756
  }
6597
6757
  function resolveExeSession() {
6598
- if (process.env.EXE_SESSION_NAME) {
6599
- return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
6600
- }
6601
6758
  const mySession = getMySession();
6602
- if (!mySession) return null;
6759
+ if (!mySession) {
6760
+ if (process.env.EXE_SESSION_NAME) {
6761
+ return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
6762
+ }
6763
+ return null;
6764
+ }
6603
6765
  const fromSessionName = extractRootExe(mySession);
6604
6766
  let candidate = null;
6605
6767
  try {
@@ -6694,7 +6856,7 @@ async function verifyPaneAtCapacity(sessionName) {
6694
6856
  }
6695
6857
  function readDebounceState() {
6696
6858
  try {
6697
- if (!existsSync15(DEBOUNCE_FILE)) return {};
6859
+ if (!existsSync16(DEBOUNCE_FILE)) return {};
6698
6860
  const raw = JSON.parse(readFileSync12(DEBOUNCE_FILE, "utf8"));
6699
6861
  const state = {};
6700
6862
  for (const [key, val] of Object.entries(raw)) {
@@ -6711,7 +6873,7 @@ function readDebounceState() {
6711
6873
  }
6712
6874
  function writeDebounceState(state) {
6713
6875
  try {
6714
- if (!existsSync15(SESSION_CACHE)) mkdirSync7(SESSION_CACHE, { recursive: true });
6876
+ if (!existsSync16(SESSION_CACHE)) mkdirSync8(SESSION_CACHE, { recursive: true });
6715
6877
  writeFileSync8(DEBOUNCE_FILE, JSON.stringify(state));
6716
6878
  } catch {
6717
6879
  }
@@ -6812,7 +6974,7 @@ function sendIntercom(targetSession) {
6812
6974
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
6813
6975
  const agent = baseAgentName(rawAgent);
6814
6976
  const markerPath = path19.join(SESSION_CACHE, `current-task-${agent}.json`);
6815
- if (existsSync15(markerPath)) {
6977
+ if (existsSync16(markerPath)) {
6816
6978
  logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker + not idle \u2014 will auto-chain)`);
6817
6979
  return "debounced";
6818
6980
  }
@@ -6823,7 +6985,7 @@ function sendIntercom(targetSession) {
6823
6985
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
6824
6986
  const agent = baseAgentName(rawAgent);
6825
6987
  const taskDir = path19.join(process.cwd(), "exe", agent);
6826
- if (existsSync15(taskDir)) {
6988
+ if (existsSync16(taskDir)) {
6827
6989
  const files = readdirSync3(taskDir).filter(
6828
6990
  (f) => f.endsWith(".md") && f !== "DONE.txt"
6829
6991
  );
@@ -6984,15 +7146,15 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
6984
7146
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
6985
7147
  const logDir = path19.join(os12.homedir(), ".exe-os", "session-logs");
6986
7148
  const logFile = path19.join(logDir, `${instanceLabel}-${Date.now()}.log`);
6987
- if (!existsSync15(logDir)) {
6988
- mkdirSync7(logDir, { recursive: true });
7149
+ if (!existsSync16(logDir)) {
7150
+ mkdirSync8(logDir, { recursive: true });
6989
7151
  }
6990
7152
  transport.kill(sessionName);
6991
7153
  let cleanupSuffix = "";
6992
7154
  try {
6993
7155
  const thisFile = fileURLToPath2(import.meta.url);
6994
7156
  const cleanupScript = path19.join(path19.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
6995
- if (existsSync15(cleanupScript)) {
7157
+ if (existsSync16(cleanupScript)) {
6996
7158
  cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
6997
7159
  }
6998
7160
  } catch {
@@ -7047,7 +7209,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
7047
7209
  if (changed) {
7048
7210
  perms.allow = allow;
7049
7211
  settings.permissions = perms;
7050
- mkdirSync7(projSettingsDir, { recursive: true });
7212
+ mkdirSync8(projSettingsDir, { recursive: true });
7051
7213
  writeFileSync8(settingsPath, JSON.stringify(settings, null, 2) + "\n");
7052
7214
  }
7053
7215
  } catch {
@@ -7085,7 +7247,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
7085
7247
  `
7086
7248
  );
7087
7249
  }
7088
- } else if (existsSync15(identityPath)) {
7250
+ } else if (existsSync16(identityPath)) {
7089
7251
  identityFlag = ` --append-system-prompt-file ${identityPath}`;
7090
7252
  legacyFallbackWarned = true;
7091
7253
  }
@@ -7107,7 +7269,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
7107
7269
  let sessionContextFlag = "";
7108
7270
  try {
7109
7271
  const ctxDir = path19.join(os12.homedir(), ".exe-os", "session-cache");
7110
- mkdirSync7(ctxDir, { recursive: true });
7272
+ mkdirSync8(ctxDir, { recursive: true });
7111
7273
  const ctxFile = path19.join(ctxDir, `session-context-${sessionName}.md`);
7112
7274
  const ctxContent = [
7113
7275
  `## Session Context`,
@@ -7290,7 +7452,7 @@ var init_tmux_routing = __esm({
7290
7452
 
7291
7453
  // src/lib/keychain.ts
7292
7454
  import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
7293
- import { existsSync as existsSync16, statSync as statSync2 } from "fs";
7455
+ import { existsSync as existsSync17, statSync as statSync3 } from "fs";
7294
7456
  import { execSync as execSync9 } from "child_process";
7295
7457
  import path20 from "path";
7296
7458
  import os13 from "os";
@@ -7325,7 +7487,7 @@ function isRootOnlyTrustedServerKeyFile(keyPath) {
7325
7487
  if (process.platform !== "linux") return false;
7326
7488
  try {
7327
7489
  const uid = typeof os13.userInfo().uid === "number" ? os13.userInfo().uid : -1;
7328
- const st = statSync2(keyPath);
7490
+ const st = statSync3(keyPath);
7329
7491
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
7330
7492
  if (uid === 0) return true;
7331
7493
  const exeOsDir = process.env.EXE_OS_DIR;
@@ -7526,7 +7688,7 @@ async function getMasterKey() {
7526
7688
  }
7527
7689
  }
7528
7690
  const keyPath = getKeyPath();
7529
- if (!existsSync16(keyPath)) {
7691
+ if (!existsSync17(keyPath)) {
7530
7692
  process.stderr.write(
7531
7693
  `[keychain] Key not found at ${keyPath} (HOME=${os13.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
7532
7694
  `
@@ -7806,18 +7968,54 @@ __export(shard_manager_exports, {
7806
7968
  shardExists: () => shardExists
7807
7969
  });
7808
7970
  import path21 from "path";
7809
- import { existsSync as existsSync17, mkdirSync as mkdirSync8, readdirSync as readdirSync4, renameSync as renameSync4, statSync as statSync3 } from "fs";
7971
+ import { existsSync as existsSync18, mkdirSync as mkdirSync9, readdirSync as readdirSync4, renameSync as renameSync4, statSync as statSync4 } from "fs";
7810
7972
  import { createClient as createClient2 } from "@libsql/client";
7811
7973
  function initShardManager(encryptionKey) {
7812
7974
  _encryptionKey = encryptionKey;
7813
- if (!existsSync17(SHARDS_DIR)) {
7814
- mkdirSync8(SHARDS_DIR, { recursive: true });
7975
+ _keyValidated = false;
7976
+ _keyValidationPromise = null;
7977
+ if (!existsSync18(SHARDS_DIR)) {
7978
+ mkdirSync9(SHARDS_DIR, { recursive: true });
7979
+ }
7980
+ const existingShards = readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db"));
7981
+ if (existingShards.length === 0) {
7982
+ _keyValidated = true;
7815
7983
  }
7816
7984
  _shardingEnabled = true;
7817
7985
  if (_evictionTimer) clearInterval(_evictionTimer);
7818
7986
  _evictionTimer = setInterval(evictIdleShards, EVICTION_INTERVAL_MS);
7819
7987
  _evictionTimer.unref();
7820
7988
  }
7989
+ async function validateEncryptionKey() {
7990
+ if (_keyValidated) return true;
7991
+ if (!_encryptionKey) return false;
7992
+ const existingShards = readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db"));
7993
+ if (existingShards.length === 0) {
7994
+ _keyValidated = true;
7995
+ return true;
7996
+ }
7997
+ for (const shardFile of existingShards.slice(0, 3)) {
7998
+ const dbPath = path21.join(SHARDS_DIR, shardFile);
7999
+ const testClient = createClient2({ url: `file:${dbPath}`, encryptionKey: _encryptionKey });
8000
+ try {
8001
+ await testClient.execute("SELECT COUNT(*) FROM sqlite_schema");
8002
+ testClient.close();
8003
+ _keyValidated = true;
8004
+ return true;
8005
+ } catch {
8006
+ try {
8007
+ testClient.close();
8008
+ } catch {
8009
+ }
8010
+ }
8011
+ }
8012
+ process.stderr.write(
8013
+ `[shard-manager] WARNING: encryption key cannot read any existing shards (${existingShards.length} found). New shard creation disabled to prevent stranded files. Run /exe-doctor to audit.
8014
+ `
8015
+ );
8016
+ _shardingEnabled = false;
8017
+ return false;
8018
+ }
7821
8019
  function isShardingEnabled() {
7822
8020
  return _shardingEnabled;
7823
8021
  }
@@ -7851,13 +8049,13 @@ function getShardClient(projectName) {
7851
8049
  }
7852
8050
  function shardExists(projectName) {
7853
8051
  const safeName = safeShardName(projectName);
7854
- return existsSync17(path21.join(SHARDS_DIR, `${safeName}.db`));
8052
+ return existsSync18(path21.join(SHARDS_DIR, `${safeName}.db`));
7855
8053
  }
7856
8054
  function safeShardName(projectName) {
7857
8055
  return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
7858
8056
  }
7859
8057
  function listShards() {
7860
- if (!existsSync17(SHARDS_DIR)) return [];
8058
+ if (!existsSync18(SHARDS_DIR)) return [];
7861
8059
  return readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
7862
8060
  }
7863
8061
  async function auditShardHealth(options = {}) {
@@ -7870,7 +8068,7 @@ async function auditShardHealth(options = {}) {
7870
8068
  const shards = [];
7871
8069
  for (const name of names) {
7872
8070
  const dbPath = path21.join(SHARDS_DIR, `${name}.db`);
7873
- const stat = statSync3(dbPath);
8071
+ const stat = statSync4(dbPath);
7874
8072
  const item = {
7875
8073
  name,
7876
8074
  path: dbPath,
@@ -8110,6 +8308,17 @@ async function ensureShardSchema(client) {
8110
8308
  }
8111
8309
  }
8112
8310
  async function getReadyShardClient(projectName) {
8311
+ if (!_keyValidated) {
8312
+ if (!_keyValidationPromise) {
8313
+ _keyValidationPromise = validateEncryptionKey();
8314
+ }
8315
+ const valid = await _keyValidationPromise;
8316
+ if (!valid) {
8317
+ throw new Error(
8318
+ `Shard creation blocked: encryption key mismatch with existing shards. Run /exe-doctor to audit.`
8319
+ );
8320
+ }
8321
+ }
8113
8322
  const safeName = safeShardName(projectName);
8114
8323
  let client = getShardClient(projectName);
8115
8324
  try {
@@ -8122,8 +8331,8 @@ async function getReadyShardClient(projectName) {
8122
8331
  _shards.delete(safeName);
8123
8332
  _shardLastAccess.delete(safeName);
8124
8333
  const dbPath = path21.join(SHARDS_DIR, `${safeName}.db`);
8125
- if (existsSync17(dbPath)) {
8126
- const stat = statSync3(dbPath);
8334
+ if (existsSync18(dbPath)) {
8335
+ const stat = statSync4(dbPath);
8127
8336
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
8128
8337
  const archivedPath = path21.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
8129
8338
  renameSync4(dbPath, archivedPath);
@@ -8188,7 +8397,7 @@ function disposeShards() {
8188
8397
  _shardingEnabled = false;
8189
8398
  _encryptionKey = null;
8190
8399
  }
8191
- var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled;
8400
+ var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled, _keyValidated, _keyValidationPromise;
8192
8401
  var init_shard_manager = __esm({
8193
8402
  "src/lib/shard-manager.ts"() {
8194
8403
  "use strict";
@@ -8202,6 +8411,8 @@ var init_shard_manager = __esm({
8202
8411
  _evictionTimer = null;
8203
8412
  _encryptionKey = null;
8204
8413
  _shardingEnabled = false;
8414
+ _keyValidated = false;
8415
+ _keyValidationPromise = null;
8205
8416
  }
8206
8417
  });
8207
8418
 
@@ -8397,6 +8608,18 @@ var init_platform_procedures = __esm({
8397
8608
  priority: "p0",
8398
8609
  content: "create_task is dispatch + delivery. Task lifecycle: open \u2192 in_progress (you start) \u2192 done (update_task when finished) \u2192 needs_review (reviewer nudged) \u2192 closed (COO only via close_task). DB is the reliable delivery \u2014 intercom is just a speedup nudge. If you finish a task, self-chain: check for next task immediately (step 7). Never wait for a nudge. Never say 'standing by.'"
8399
8610
  },
8611
+ {
8612
+ title: "Review chain \u2014 managers must actively pull completed work, never wait for nudges",
8613
+ domain: "workflow",
8614
+ priority: "p0",
8615
+ content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
8616
+ },
8617
+ {
8618
+ title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
8619
+ domain: "workflow",
8620
+ priority: "p0",
8621
+ content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
8622
+ },
8400
8623
  {
8401
8624
  title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
8402
8625
  domain: "architecture",
@@ -8994,6 +9217,20 @@ __export(store_exports, {
8994
9217
  vectorToBlob: () => vectorToBlob,
8995
9218
  writeMemory: () => writeMemory
8996
9219
  });
9220
+ function logStoreDebug(context, err) {
9221
+ if (_debugStore) {
9222
+ process.stderr.write(
9223
+ `[store] ${context}: ${err instanceof Error ? err.message : String(err)}
9224
+ `
9225
+ );
9226
+ }
9227
+ }
9228
+ function logStoreWarn(context, err) {
9229
+ process.stderr.write(
9230
+ `[store] WARN ${context}: ${err instanceof Error ? err.message : String(err)}
9231
+ `
9232
+ );
9233
+ }
8997
9234
  function isBusyError2(err) {
8998
9235
  if (err instanceof Error) {
8999
9236
  const msg = err.message.toLowerCase();
@@ -9048,13 +9285,15 @@ async function initStore(options) {
9048
9285
  try {
9049
9286
  const { initDaemonClient: initDaemonClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
9050
9287
  await initDaemonClient2();
9051
- } catch {
9288
+ } catch (e) {
9289
+ logStoreWarn("catch", e);
9052
9290
  }
9053
9291
  if (!options?.lightweight) {
9054
9292
  try {
9055
9293
  const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
9056
9294
  initShardManager2(hexKey);
9057
- } catch {
9295
+ } catch (e) {
9296
+ logStoreWarn("catch", e);
9058
9297
  }
9059
9298
  const client = getClient();
9060
9299
  const vResult = await retryOnBusy2(
@@ -9065,7 +9304,8 @@ async function initStore(options) {
9065
9304
  try {
9066
9305
  const { loadGlobalProcedures: loadGlobalProcedures2 } = await Promise.resolve().then(() => (init_global_procedures(), global_procedures_exports));
9067
9306
  await loadGlobalProcedures2();
9068
- } catch {
9307
+ } catch (e) {
9308
+ logStoreWarn("catch", e);
9069
9309
  }
9070
9310
  }
9071
9311
  }
@@ -9125,7 +9365,8 @@ async function writeMemory(record) {
9125
9365
  memoryType
9126
9366
  });
9127
9367
  if (existing) return;
9128
- } catch {
9368
+ } catch (e) {
9369
+ logStoreWarn("catch", e);
9129
9370
  }
9130
9371
  const dbRow = {
9131
9372
  id: record.id,
@@ -9326,12 +9567,14 @@ async function flushBatch() {
9326
9567
  try {
9327
9568
  const { insertMemoryCardsForBatch: insertMemoryCardsForBatch2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
9328
9569
  await insertMemoryCardsForBatch2(batch);
9329
- } catch {
9570
+ } catch (e) {
9571
+ logStoreWarn("catch", e);
9330
9572
  }
9331
9573
  try {
9332
9574
  const { insertOntologyForBatch: insertOntologyForBatch2 } = await Promise.resolve().then(() => (init_agentic_ontology(), agentic_ontology_exports));
9333
9575
  await insertOntologyForBatch2(batch);
9334
- } catch {
9576
+ } catch (e) {
9577
+ logStoreWarn("catch", e);
9335
9578
  }
9336
9579
  schedulePostWriteMemoryHygiene(batch.map((row) => row.id));
9337
9580
  _pendingRecords.splice(0, batch.length);
@@ -9370,7 +9613,8 @@ ${err.stack.split("\n").slice(1, 3).join("\n")}` : ""}` : String(err);
9370
9613
  }
9371
9614
  }
9372
9615
  }
9373
- } catch {
9616
+ } catch (e) {
9617
+ logStoreWarn("catch", e);
9374
9618
  }
9375
9619
  return batch.length;
9376
9620
  } finally {
@@ -9412,7 +9656,8 @@ async function searchMemories(queryVector, agentId, options) {
9412
9656
  } else {
9413
9657
  client = getClient();
9414
9658
  }
9415
- } catch {
9659
+ } catch (e) {
9660
+ logStoreDebug("shard routing fallback", e);
9416
9661
  client = getClient();
9417
9662
  }
9418
9663
  const limit = options?.limit ?? 10;
@@ -9528,7 +9773,8 @@ async function attachDocumentMetadata(records) {
9528
9773
  if (!record.document_id) continue;
9529
9774
  record.document_metadata = byId.get(record.document_id) ?? null;
9530
9775
  }
9531
- } catch {
9776
+ } catch (e) {
9777
+ logStoreWarn("catch", e);
9532
9778
  }
9533
9779
  return records;
9534
9780
  }
@@ -9589,11 +9835,12 @@ async function getMemoryCardinality(agentId) {
9589
9835
  args: [agentId]
9590
9836
  });
9591
9837
  return Number(result.rows[0]?.cnt) || 0;
9592
- } catch {
9838
+ } catch (e) {
9839
+ logStoreWarn("getMemoryCardinality", e);
9593
9840
  return 0;
9594
9841
  }
9595
9842
  }
9596
- var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
9843
+ var _debugStore, INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
9597
9844
  var init_store = __esm({
9598
9845
  "src/lib/store.ts"() {
9599
9846
  "use strict";
@@ -9603,6 +9850,7 @@ var init_store = __esm({
9603
9850
  init_config();
9604
9851
  init_state_bus();
9605
9852
  init_memory_write_governor();
9853
+ _debugStore = process.env.EXE_DEBUG === "1";
9606
9854
  INIT_MAX_RETRIES = 3;
9607
9855
  INIT_RETRY_DELAY_MS = 1e3;
9608
9856
  _pendingRecords = [];
@@ -11369,8 +11617,8 @@ __export(whatsapp_accounts_exports, {
11369
11617
  loadAccounts: () => loadAccounts
11370
11618
  });
11371
11619
  import { readFileSync as readFileSync13 } from "fs";
11372
- import { join as join2 } from "path";
11373
- import { homedir as homedir2 } from "os";
11620
+ import { join as join3 } from "path";
11621
+ import { homedir as homedir3 } from "os";
11374
11622
  function loadAccounts() {
11375
11623
  if (cachedAccounts !== null) return cachedAccounts;
11376
11624
  try {
@@ -11408,7 +11656,7 @@ var CONFIG_PATH2, cachedAccounts;
11408
11656
  var init_whatsapp_accounts = __esm({
11409
11657
  "src/gateway/whatsapp-accounts.ts"() {
11410
11658
  "use strict";
11411
- CONFIG_PATH2 = join2(homedir2(), ".exe-os", "whatsapp-accounts.json");
11659
+ CONFIG_PATH2 = join3(homedir3(), ".exe-os", "whatsapp-accounts.json");
11412
11660
  cachedAccounts = null;
11413
11661
  }
11414
11662
  });
@@ -15604,14 +15852,14 @@ var OllamaProvider = class {
15604
15852
 
15605
15853
  // src/gateway/adapters/whatsapp.ts
15606
15854
  import { randomUUID as randomUUID9 } from "crypto";
15607
- import { homedir } from "os";
15608
- import { join } from "path";
15609
- import { mkdirSync as mkdirSync9 } from "fs";
15855
+ import { homedir as homedir2 } from "os";
15856
+ import { join as join2 } from "path";
15857
+ import { mkdirSync as mkdirSync10 } from "fs";
15610
15858
  var INITIAL_BACKOFF_MS = 1e3;
15611
15859
  var MAX_BACKOFF_MS = 3e5;
15612
15860
  var BACKOFF_MULTIPLIER = 2;
15613
15861
  var JITTER_FACTOR = 0.25;
15614
- var AUTH_DIR = join(homedir(), ".exe-os", "whatsapp-auth");
15862
+ var AUTH_DIR = join2(homedir2(), ".exe-os", "whatsapp-auth");
15615
15863
  function createBaileysLogger(accountName) {
15616
15864
  const prefix = accountName ? `[whatsapp:${accountName}]` : "[whatsapp]";
15617
15865
  let logger;
@@ -15651,7 +15899,7 @@ var WhatsAppAdapter = class {
15651
15899
  disconnectedAt = 0;
15652
15900
  async connect(config2) {
15653
15901
  this.authDir = config2.credentials.authDir ?? AUTH_DIR;
15654
- mkdirSync9(this.authDir, { recursive: true });
15902
+ mkdirSync10(this.authDir, { recursive: true });
15655
15903
  const baileys = await import("@whiskeysockets/baileys");
15656
15904
  const { makeWASocket, useMultiFileAuthState, fetchLatestBaileysVersion, DisconnectReason, makeCacheableSignalKeyStore } = baileys;
15657
15905
  const { state, saveCreds } = await useMultiFileAuthState(this.authDir);
@@ -17785,7 +18033,7 @@ async function ensureCRMContact(info) {
17785
18033
  }
17786
18034
 
17787
18035
  // src/automation/trigger-engine.ts
17788
- import { readFileSync as readFileSync14, writeFileSync as writeFileSync9, existsSync as existsSync18, mkdirSync as mkdirSync10 } from "fs";
18036
+ import { readFileSync as readFileSync14, writeFileSync as writeFileSync9, existsSync as existsSync19, mkdirSync as mkdirSync11 } from "fs";
17789
18037
  import { randomUUID as randomUUID15 } from "crypto";
17790
18038
  import path23 from "path";
17791
18039
  import os15 from "os";
@@ -17843,7 +18091,7 @@ function evaluateConditions(conditions, record) {
17843
18091
  return conditions.every((c) => evaluateCondition(c, record));
17844
18092
  }
17845
18093
  function loadTriggers(project) {
17846
- if (!existsSync18(TRIGGERS_PATH)) return [];
18094
+ if (!existsSync19(TRIGGERS_PATH)) return [];
17847
18095
  try {
17848
18096
  const raw = readFileSync14(TRIGGERS_PATH, "utf-8");
17849
18097
  const all = JSON.parse(raw);