@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.
- package/dist/bin/agentic-ontology-backfill.js +334 -100
- package/dist/bin/agentic-reflection-backfill.js +328 -97
- package/dist/bin/agentic-semantic-label.js +328 -97
- package/dist/bin/backfill-conversations.js +332 -97
- package/dist/bin/backfill-responses.js +332 -97
- package/dist/bin/backfill-vectors.js +337 -106
- package/dist/bin/bulk-sync-postgres.js +335 -101
- package/dist/bin/cleanup-stale-review-tasks.js +356 -108
- package/dist/bin/cli.js +653 -405
- package/dist/bin/exe-agent.js +21 -3
- package/dist/bin/exe-assign.js +338 -94
- package/dist/bin/exe-boot.js +472 -239
- package/dist/bin/exe-call.js +22 -5
- package/dist/bin/exe-cloud.js +404 -158
- package/dist/bin/exe-dispatch.js +390 -142
- package/dist/bin/exe-doctor.js +349 -103
- package/dist/bin/exe-export-behaviors.js +351 -105
- package/dist/bin/exe-forget.js +352 -103
- package/dist/bin/exe-gateway.js +420 -172
- package/dist/bin/exe-heartbeat.js +361 -113
- package/dist/bin/exe-kill.js +344 -98
- package/dist/bin/exe-launch-agent.js +375 -129
- package/dist/bin/exe-new-employee.js +83 -67
- package/dist/bin/exe-pending-messages.js +356 -108
- package/dist/bin/exe-pending-notifications.js +358 -110
- package/dist/bin/exe-pending-reviews.js +359 -111
- package/dist/bin/exe-rename.js +354 -108
- package/dist/bin/exe-review.js +343 -97
- package/dist/bin/exe-search.js +363 -113
- package/dist/bin/exe-session-cleanup.js +403 -155
- package/dist/bin/exe-settings.js +14 -9
- package/dist/bin/exe-start-codex.js +365 -131
- package/dist/bin/exe-start-opencode.js +359 -125
- package/dist/bin/exe-status.js +356 -108
- package/dist/bin/exe-team.js +343 -97
- package/dist/bin/git-sweep.js +390 -142
- package/dist/bin/graph-backfill.js +334 -100
- package/dist/bin/graph-export.js +346 -100
- package/dist/bin/install.js +1 -0
- package/dist/bin/intercom-check.js +403 -155
- package/dist/bin/pre-publish.js +12 -0
- package/dist/bin/scan-tasks.js +393 -145
- package/dist/bin/setup.js +331 -159
- package/dist/bin/shard-migrate.js +328 -94
- package/dist/gateway/index.js +406 -158
- package/dist/hooks/bug-report-worker.js +396 -148
- package/dist/hooks/codex-stop-task-finalizer.js +374 -126
- package/dist/hooks/commit-complete.js +390 -142
- package/dist/hooks/error-recall.js +365 -115
- package/dist/hooks/ingest.js +357 -111
- package/dist/hooks/instructions-loaded.js +351 -105
- package/dist/hooks/notification.js +343 -97
- package/dist/hooks/post-compact.js +358 -110
- package/dist/hooks/post-tool-combined.js +384 -132
- package/dist/hooks/pre-compact.js +391 -143
- package/dist/hooks/pre-tool-use.js +362 -114
- package/dist/hooks/prompt-submit.js +422 -170
- package/dist/hooks/session-end.js +393 -145
- package/dist/hooks/session-start.js +390 -138
- package/dist/hooks/stop.js +361 -113
- package/dist/hooks/subagent-stop.js +354 -106
- package/dist/hooks/summary-worker.js +418 -185
- package/dist/index.js +400 -152
- package/dist/lib/cloud-sync.js +291 -131
- package/dist/lib/consolidation.js +8 -2
- package/dist/lib/database.js +233 -73
- package/dist/lib/db.js +233 -73
- package/dist/lib/device-registry.js +237 -77
- package/dist/lib/employee-templates.js +19 -1
- package/dist/lib/exe-daemon.js +705 -409
- package/dist/lib/hybrid-search.js +363 -113
- package/dist/lib/identity.js +9 -5
- package/dist/lib/messaging.js +26 -20
- package/dist/lib/reminders.js +5 -1
- package/dist/lib/schedules.js +320 -89
- package/dist/lib/skill-learning.js +28 -24
- package/dist/lib/store.js +342 -96
- package/dist/lib/tasks.js +82 -76
- package/dist/lib/tmux-routing.js +74 -68
- package/dist/lib/token-spend.js +5 -1
- package/dist/mcp/server.js +628 -355
- package/dist/mcp/tools/complete-reminder.js +5 -1
- package/dist/mcp/tools/create-reminder.js +5 -1
- package/dist/mcp/tools/create-task.js +89 -83
- package/dist/mcp/tools/deactivate-behavior.js +7 -3
- package/dist/mcp/tools/list-reminders.js +5 -1
- package/dist/mcp/tools/list-tasks.js +28 -21
- package/dist/mcp/tools/send-message.js +28 -22
- package/dist/mcp/tools/update-task.js +89 -83
- package/dist/runtime/index.js +390 -142
- package/dist/tui/App.js +437 -189
- 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")
|
|
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
|
|
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
|
|
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 (!
|
|
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 (
|
|
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
|
|
4199
|
+
existsSync as existsSync12,
|
|
4040
4200
|
lstatSync,
|
|
4041
|
-
mkdirSync as
|
|
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
|
-
|
|
4058
|
-
if (
|
|
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
|
|
4146
|
-
existsSync as
|
|
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
|
|
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 (!
|
|
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 (
|
|
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 (
|
|
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
|
|
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 (
|
|
5451
|
+
if (existsSync15(cacheDir)) {
|
|
5292
5452
|
for (const f of readdirSync2(cacheDir)) {
|
|
5293
5453
|
if (f.startsWith("review-notified-")) {
|
|
5294
|
-
|
|
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:
|
|
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 (!
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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 (!
|
|
6470
|
-
|
|
6629
|
+
if (!existsSync16(SPAWN_LOCK_DIR)) {
|
|
6630
|
+
mkdirSync8(SPAWN_LOCK_DIR, { recursive: true });
|
|
6471
6631
|
}
|
|
6472
6632
|
const lockFile = spawnLockPath(sessionName);
|
|
6473
|
-
if (
|
|
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
|
-
|
|
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
|
|
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 (!
|
|
6568
|
-
|
|
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)
|
|
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 (!
|
|
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 (!
|
|
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 (
|
|
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 (
|
|
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 (!
|
|
6988
|
-
|
|
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 (
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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 (!
|
|
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
|
|
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
|
-
|
|
7814
|
-
|
|
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
|
|
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 (!
|
|
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 =
|
|
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 (
|
|
8126
|
-
const stat =
|
|
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
|
|
11373
|
-
import { homedir as
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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 (!
|
|
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);
|