@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/tui/App.js
CHANGED
|
@@ -2494,9 +2494,79 @@ __export(database_exports, {
|
|
|
2494
2494
|
isInitialized: () => isInitialized,
|
|
2495
2495
|
setExternalClient: () => setExternalClient
|
|
2496
2496
|
});
|
|
2497
|
-
import { chmodSync as chmodSync2 } from "fs";
|
|
2497
|
+
import { chmodSync as chmodSync2, existsSync as existsSync10, statSync as statSync2, copyFileSync, unlinkSync as unlinkSync3, openSync as openSync2, closeSync as closeSync2, mkdirSync as mkdirSync4 } from "fs";
|
|
2498
2498
|
import { createClient } from "@libsql/client";
|
|
2499
|
+
import { homedir } from "os";
|
|
2500
|
+
import { join } from "path";
|
|
2501
|
+
function logCatchDebug(context, err) {
|
|
2502
|
+
if (_debugDb) {
|
|
2503
|
+
process.stderr.write(
|
|
2504
|
+
`[database] ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
2505
|
+
`
|
|
2506
|
+
);
|
|
2507
|
+
}
|
|
2508
|
+
}
|
|
2509
|
+
function acquireDbLock() {
|
|
2510
|
+
mkdirSync4(join(homedir(), ".exe-os"), { recursive: true });
|
|
2511
|
+
try {
|
|
2512
|
+
_lockFd = openSync2(DB_LOCK_PATH, "wx");
|
|
2513
|
+
} catch (err) {
|
|
2514
|
+
if (err && typeof err === "object" && "code" in err && err.code === "EEXIST") {
|
|
2515
|
+
try {
|
|
2516
|
+
const lockStat = statSync2(DB_LOCK_PATH);
|
|
2517
|
+
if (Date.now() - lockStat.mtimeMs > 6e4) {
|
|
2518
|
+
unlinkSync3(DB_LOCK_PATH);
|
|
2519
|
+
_lockFd = openSync2(DB_LOCK_PATH, "wx");
|
|
2520
|
+
return;
|
|
2521
|
+
}
|
|
2522
|
+
} catch (e) {
|
|
2523
|
+
logCatchDebug("stale lock check", e);
|
|
2524
|
+
}
|
|
2525
|
+
process.stderr.write(
|
|
2526
|
+
"[database] WARN: Another process holds db.lock \u2014 waiting briefly then proceeding.\n"
|
|
2527
|
+
);
|
|
2528
|
+
return;
|
|
2529
|
+
}
|
|
2530
|
+
throw err;
|
|
2531
|
+
}
|
|
2532
|
+
}
|
|
2533
|
+
function releaseDbLock() {
|
|
2534
|
+
if (_lockFd !== null) {
|
|
2535
|
+
try {
|
|
2536
|
+
closeSync2(_lockFd);
|
|
2537
|
+
} catch (e) {
|
|
2538
|
+
logCatchDebug("lock close", e);
|
|
2539
|
+
}
|
|
2540
|
+
_lockFd = null;
|
|
2541
|
+
}
|
|
2542
|
+
try {
|
|
2543
|
+
unlinkSync3(DB_LOCK_PATH);
|
|
2544
|
+
} catch (e) {
|
|
2545
|
+
logCatchDebug("lock unlink", e);
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2499
2548
|
async function initDatabase(config) {
|
|
2549
|
+
acquireDbLock();
|
|
2550
|
+
if (existsSync10(config.dbPath)) {
|
|
2551
|
+
const dbStat = statSync2(config.dbPath);
|
|
2552
|
+
if (dbStat.size === 0) {
|
|
2553
|
+
const walPath = config.dbPath + "-wal";
|
|
2554
|
+
if (existsSync10(walPath) && statSync2(walPath).size > 0) {
|
|
2555
|
+
const backupPath = config.dbPath + ".zeroed-" + Date.now();
|
|
2556
|
+
copyFileSync(config.dbPath, backupPath);
|
|
2557
|
+
unlinkSync3(config.dbPath);
|
|
2558
|
+
process.stderr.write(
|
|
2559
|
+
`[database] CRITICAL: DB was 0 bytes. Moved to ${backupPath}, attempting WAL recovery.
|
|
2560
|
+
`
|
|
2561
|
+
);
|
|
2562
|
+
} else {
|
|
2563
|
+
process.stderr.write(
|
|
2564
|
+
`[database] CRITICAL: DB is 0 bytes and no WAL available for recovery. Data may be lost. Check backups at ${config.dbPath}.bak
|
|
2565
|
+
`
|
|
2566
|
+
);
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2500
2570
|
if (_walCheckpointTimer) {
|
|
2501
2571
|
clearInterval(_walCheckpointTimer);
|
|
2502
2572
|
_walCheckpointTimer = null;
|
|
@@ -2523,10 +2593,8 @@ async function initDatabase(config) {
|
|
|
2523
2593
|
_client = createClient(opts);
|
|
2524
2594
|
_resilientClient = wrapWithRetry(_client);
|
|
2525
2595
|
_adapterClient = _resilientClient;
|
|
2526
|
-
_client.execute("PRAGMA busy_timeout = 30000")
|
|
2527
|
-
|
|
2528
|
-
_client.execute("PRAGMA journal_mode = WAL").catch(() => {
|
|
2529
|
-
});
|
|
2596
|
+
await _client.execute("PRAGMA busy_timeout = 30000");
|
|
2597
|
+
await _client.execute("PRAGMA journal_mode = WAL");
|
|
2530
2598
|
if (_walCheckpointTimer) clearInterval(_walCheckpointTimer);
|
|
2531
2599
|
_walCheckpointTimer = setInterval(() => {
|
|
2532
2600
|
_client?.execute("PRAGMA wal_checkpoint(PASSIVE)").catch(() => {
|
|
@@ -2541,11 +2609,16 @@ async function initDatabase(config) {
|
|
|
2541
2609
|
for (const suffix of ["-wal", "-shm"]) {
|
|
2542
2610
|
try {
|
|
2543
2611
|
chmodSync2(config.dbPath + suffix, 384);
|
|
2544
|
-
} catch {
|
|
2612
|
+
} catch (chmodErr) {
|
|
2613
|
+
process.stderr.write(`[database] chmod ${suffix} failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
|
|
2614
|
+
`);
|
|
2545
2615
|
}
|
|
2546
2616
|
}
|
|
2547
|
-
} catch {
|
|
2617
|
+
} catch (chmodErr) {
|
|
2618
|
+
process.stderr.write(`[database] chmod db failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
|
|
2619
|
+
`);
|
|
2548
2620
|
}
|
|
2621
|
+
releaseDbLock();
|
|
2549
2622
|
}
|
|
2550
2623
|
function isInitialized() {
|
|
2551
2624
|
return _adapterClient !== null || _client !== null;
|
|
@@ -2600,7 +2673,8 @@ async function ensureSchema() {
|
|
|
2600
2673
|
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
2601
2674
|
try {
|
|
2602
2675
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
2603
|
-
} catch {
|
|
2676
|
+
} catch (e) {
|
|
2677
|
+
logCatchDebug("migration", e);
|
|
2604
2678
|
}
|
|
2605
2679
|
await client.executeMultiple(`
|
|
2606
2680
|
CREATE TABLE IF NOT EXISTS memories (
|
|
@@ -2665,6 +2739,23 @@ async function ensureSchema() {
|
|
|
2665
2739
|
INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
|
|
2666
2740
|
END;
|
|
2667
2741
|
`);
|
|
2742
|
+
try {
|
|
2743
|
+
await client.execute("SELECT COUNT(*) FROM memories_fts LIMIT 1");
|
|
2744
|
+
} catch (ftsErr) {
|
|
2745
|
+
process.stderr.write(
|
|
2746
|
+
`[database] WARN: memories_fts corrupted (${ftsErr instanceof Error ? ftsErr.message : String(ftsErr)}) \u2014 rebuilding FTS index.
|
|
2747
|
+
`
|
|
2748
|
+
);
|
|
2749
|
+
try {
|
|
2750
|
+
await client.execute("INSERT INTO memories_fts(memories_fts) VALUES('rebuild')");
|
|
2751
|
+
process.stderr.write("[database] FTS index rebuilt successfully.\n");
|
|
2752
|
+
} catch (rebuildErr) {
|
|
2753
|
+
process.stderr.write(
|
|
2754
|
+
`[database] ERROR: FTS rebuild failed: ${rebuildErr instanceof Error ? rebuildErr.message : String(rebuildErr)}
|
|
2755
|
+
`
|
|
2756
|
+
);
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2668
2759
|
await client.executeMultiple(`
|
|
2669
2760
|
CREATE TABLE IF NOT EXISTS sync_meta (
|
|
2670
2761
|
key TEXT PRIMARY KEY,
|
|
@@ -2723,35 +2814,40 @@ async function ensureSchema() {
|
|
|
2723
2814
|
});
|
|
2724
2815
|
}
|
|
2725
2816
|
}
|
|
2726
|
-
} catch {
|
|
2817
|
+
} catch (seedErr) {
|
|
2818
|
+
logCatchDebug("behavior seed", seedErr);
|
|
2727
2819
|
}
|
|
2728
2820
|
try {
|
|
2729
2821
|
await client.execute({
|
|
2730
2822
|
sql: `ALTER TABLE behaviors ADD COLUMN priority TEXT DEFAULT 'p1'`,
|
|
2731
2823
|
args: []
|
|
2732
2824
|
});
|
|
2733
|
-
} catch {
|
|
2825
|
+
} catch (e) {
|
|
2826
|
+
logCatchDebug("migration", e);
|
|
2734
2827
|
}
|
|
2735
2828
|
try {
|
|
2736
2829
|
await client.execute({
|
|
2737
2830
|
sql: `ALTER TABLE behaviors ADD COLUMN vector F32_BLOB(${EMBEDDING_DIM})`,
|
|
2738
2831
|
args: []
|
|
2739
2832
|
});
|
|
2740
|
-
} catch {
|
|
2833
|
+
} catch (e) {
|
|
2834
|
+
logCatchDebug("migration", e);
|
|
2741
2835
|
}
|
|
2742
2836
|
try {
|
|
2743
2837
|
await client.execute({
|
|
2744
2838
|
sql: `ALTER TABLE tasks ADD COLUMN blocked_by TEXT`,
|
|
2745
2839
|
args: []
|
|
2746
2840
|
});
|
|
2747
|
-
} catch {
|
|
2841
|
+
} catch (e) {
|
|
2842
|
+
logCatchDebug("migration", e);
|
|
2748
2843
|
}
|
|
2749
2844
|
try {
|
|
2750
2845
|
await client.execute({
|
|
2751
2846
|
sql: `ALTER TABLE tasks ADD COLUMN parent_task_id TEXT`,
|
|
2752
2847
|
args: []
|
|
2753
2848
|
});
|
|
2754
|
-
} catch {
|
|
2849
|
+
} catch (e) {
|
|
2850
|
+
logCatchDebug("migration", e);
|
|
2755
2851
|
}
|
|
2756
2852
|
try {
|
|
2757
2853
|
await client.execute({
|
|
@@ -2760,98 +2856,112 @@ async function ensureSchema() {
|
|
|
2760
2856
|
WHERE parent_task_id IS NOT NULL`,
|
|
2761
2857
|
args: []
|
|
2762
2858
|
});
|
|
2763
|
-
} catch {
|
|
2859
|
+
} catch (e) {
|
|
2860
|
+
logCatchDebug("migration", e);
|
|
2764
2861
|
}
|
|
2765
2862
|
try {
|
|
2766
2863
|
await client.execute({
|
|
2767
2864
|
sql: `UPDATE tasks SET status = 'done' WHERE status = 'completed'`,
|
|
2768
2865
|
args: []
|
|
2769
2866
|
});
|
|
2770
|
-
} catch {
|
|
2867
|
+
} catch (e) {
|
|
2868
|
+
logCatchDebug("migration", e);
|
|
2771
2869
|
}
|
|
2772
2870
|
try {
|
|
2773
2871
|
await client.execute({
|
|
2774
2872
|
sql: `ALTER TABLE tasks ADD COLUMN reviewer TEXT`,
|
|
2775
2873
|
args: []
|
|
2776
2874
|
});
|
|
2777
|
-
} catch {
|
|
2875
|
+
} catch (e) {
|
|
2876
|
+
logCatchDebug("migration", e);
|
|
2778
2877
|
}
|
|
2779
2878
|
try {
|
|
2780
2879
|
await client.execute({
|
|
2781
2880
|
sql: `ALTER TABLE tasks ADD COLUMN context TEXT`,
|
|
2782
2881
|
args: []
|
|
2783
2882
|
});
|
|
2784
|
-
} catch {
|
|
2883
|
+
} catch (e) {
|
|
2884
|
+
logCatchDebug("migration", e);
|
|
2785
2885
|
}
|
|
2786
2886
|
try {
|
|
2787
2887
|
await client.execute({
|
|
2788
2888
|
sql: `ALTER TABLE tasks ADD COLUMN result TEXT`,
|
|
2789
2889
|
args: []
|
|
2790
2890
|
});
|
|
2791
|
-
} catch {
|
|
2891
|
+
} catch (e) {
|
|
2892
|
+
logCatchDebug("migration", e);
|
|
2792
2893
|
}
|
|
2793
2894
|
try {
|
|
2794
2895
|
await client.execute({
|
|
2795
2896
|
sql: `ALTER TABLE tasks ADD COLUMN assigned_tmux TEXT`,
|
|
2796
2897
|
args: []
|
|
2797
2898
|
});
|
|
2798
|
-
} catch {
|
|
2899
|
+
} catch (e) {
|
|
2900
|
+
logCatchDebug("migration", e);
|
|
2799
2901
|
}
|
|
2800
2902
|
try {
|
|
2801
2903
|
await client.execute({
|
|
2802
2904
|
sql: `ALTER TABLE tasks ADD COLUMN checkpoint TEXT`,
|
|
2803
2905
|
args: []
|
|
2804
2906
|
});
|
|
2805
|
-
} catch {
|
|
2907
|
+
} catch (e) {
|
|
2908
|
+
logCatchDebug("migration", e);
|
|
2806
2909
|
}
|
|
2807
2910
|
try {
|
|
2808
2911
|
await client.execute({
|
|
2809
2912
|
sql: `ALTER TABLE tasks ADD COLUMN checkpoint_count INTEGER NOT NULL DEFAULT 0`,
|
|
2810
2913
|
args: []
|
|
2811
2914
|
});
|
|
2812
|
-
} catch {
|
|
2915
|
+
} catch (e) {
|
|
2916
|
+
logCatchDebug("migration", e);
|
|
2813
2917
|
}
|
|
2814
2918
|
try {
|
|
2815
2919
|
await client.execute({
|
|
2816
2920
|
sql: `ALTER TABLE tasks ADD COLUMN complexity TEXT NOT NULL DEFAULT 'standard'`,
|
|
2817
2921
|
args: []
|
|
2818
2922
|
});
|
|
2819
|
-
} catch {
|
|
2923
|
+
} catch (e) {
|
|
2924
|
+
logCatchDebug("migration", e);
|
|
2820
2925
|
}
|
|
2821
2926
|
try {
|
|
2822
2927
|
await client.execute({
|
|
2823
2928
|
sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
|
|
2824
2929
|
args: []
|
|
2825
2930
|
});
|
|
2826
|
-
} catch {
|
|
2931
|
+
} catch (e) {
|
|
2932
|
+
logCatchDebug("migration", e);
|
|
2827
2933
|
}
|
|
2828
2934
|
try {
|
|
2829
2935
|
await client.execute({
|
|
2830
2936
|
sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
|
|
2831
2937
|
args: []
|
|
2832
2938
|
});
|
|
2833
|
-
} catch {
|
|
2939
|
+
} catch (e) {
|
|
2940
|
+
logCatchDebug("migration", e);
|
|
2834
2941
|
}
|
|
2835
2942
|
try {
|
|
2836
2943
|
await client.execute({
|
|
2837
2944
|
sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
|
|
2838
2945
|
args: []
|
|
2839
2946
|
});
|
|
2840
|
-
} catch {
|
|
2947
|
+
} catch (e) {
|
|
2948
|
+
logCatchDebug("migration", e);
|
|
2841
2949
|
}
|
|
2842
2950
|
try {
|
|
2843
2951
|
await client.execute({
|
|
2844
2952
|
sql: `ALTER TABLE memories ADD COLUMN author_device_id TEXT`,
|
|
2845
2953
|
args: []
|
|
2846
2954
|
});
|
|
2847
|
-
} catch {
|
|
2955
|
+
} catch (e) {
|
|
2956
|
+
logCatchDebug("migration", e);
|
|
2848
2957
|
}
|
|
2849
2958
|
try {
|
|
2850
2959
|
await client.execute({
|
|
2851
2960
|
sql: `ALTER TABLE memories ADD COLUMN scope TEXT NOT NULL DEFAULT 'business'`,
|
|
2852
2961
|
args: []
|
|
2853
2962
|
});
|
|
2854
|
-
} catch {
|
|
2963
|
+
} catch (e) {
|
|
2964
|
+
logCatchDebug("migration", e);
|
|
2855
2965
|
}
|
|
2856
2966
|
await client.executeMultiple(`
|
|
2857
2967
|
CREATE TABLE IF NOT EXISTS consolidations (
|
|
@@ -2956,14 +3066,16 @@ async function ensureSchema() {
|
|
|
2956
3066
|
sql: `ALTER TABLE notifications ADD COLUMN session_scope TEXT`,
|
|
2957
3067
|
args: []
|
|
2958
3068
|
});
|
|
2959
|
-
} catch {
|
|
3069
|
+
} catch (e) {
|
|
3070
|
+
logCatchDebug("migration", e);
|
|
2960
3071
|
}
|
|
2961
3072
|
try {
|
|
2962
3073
|
await client.execute({
|
|
2963
3074
|
sql: `ALTER TABLE messages ADD COLUMN session_scope TEXT`,
|
|
2964
3075
|
args: []
|
|
2965
3076
|
});
|
|
2966
|
-
} catch {
|
|
3077
|
+
} catch (e) {
|
|
3078
|
+
logCatchDebug("migration", e);
|
|
2967
3079
|
}
|
|
2968
3080
|
await client.executeMultiple(`
|
|
2969
3081
|
CREATE INDEX IF NOT EXISTS idx_notifications_agent_scope_read
|
|
@@ -2989,7 +3101,8 @@ async function ensureSchema() {
|
|
|
2989
3101
|
sql: `UPDATE tasks SET project_name = 'exe-os' WHERE project_name = 'worker'`,
|
|
2990
3102
|
args: []
|
|
2991
3103
|
});
|
|
2992
|
-
} catch {
|
|
3104
|
+
} catch (e) {
|
|
3105
|
+
logCatchDebug("migration", e);
|
|
2993
3106
|
}
|
|
2994
3107
|
await client.executeMultiple(`
|
|
2995
3108
|
CREATE TABLE IF NOT EXISTS trajectories (
|
|
@@ -3013,7 +3126,8 @@ async function ensureSchema() {
|
|
|
3013
3126
|
`);
|
|
3014
3127
|
try {
|
|
3015
3128
|
await client.execute("ALTER TABLE trajectories ADD COLUMN skill_id TEXT");
|
|
3016
|
-
} catch {
|
|
3129
|
+
} catch (e) {
|
|
3130
|
+
logCatchDebug("migration", e);
|
|
3017
3131
|
}
|
|
3018
3132
|
await client.executeMultiple(`
|
|
3019
3133
|
CREATE TABLE IF NOT EXISTS consolidations (
|
|
@@ -3050,63 +3164,72 @@ async function ensureSchema() {
|
|
|
3050
3164
|
sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
|
|
3051
3165
|
args: []
|
|
3052
3166
|
});
|
|
3053
|
-
} catch {
|
|
3167
|
+
} catch (e) {
|
|
3168
|
+
logCatchDebug("migration", e);
|
|
3054
3169
|
}
|
|
3055
3170
|
try {
|
|
3056
3171
|
await client.execute({
|
|
3057
3172
|
sql: `ALTER TABLE memories ADD COLUMN importance INTEGER DEFAULT 5`,
|
|
3058
3173
|
args: []
|
|
3059
3174
|
});
|
|
3060
|
-
} catch {
|
|
3175
|
+
} catch (e) {
|
|
3176
|
+
logCatchDebug("migration", e);
|
|
3061
3177
|
}
|
|
3062
3178
|
try {
|
|
3063
3179
|
await client.execute({
|
|
3064
3180
|
sql: `ALTER TABLE memories ADD COLUMN status TEXT DEFAULT 'active'`,
|
|
3065
3181
|
args: []
|
|
3066
3182
|
});
|
|
3067
|
-
} catch {
|
|
3183
|
+
} catch (e) {
|
|
3184
|
+
logCatchDebug("migration", e);
|
|
3068
3185
|
}
|
|
3069
3186
|
try {
|
|
3070
3187
|
await client.execute({
|
|
3071
3188
|
sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
|
|
3072
3189
|
args: []
|
|
3073
3190
|
});
|
|
3074
|
-
} catch {
|
|
3191
|
+
} catch (e) {
|
|
3192
|
+
logCatchDebug("migration", e);
|
|
3075
3193
|
}
|
|
3076
3194
|
try {
|
|
3077
3195
|
await client.execute({
|
|
3078
3196
|
sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
|
|
3079
3197
|
args: []
|
|
3080
3198
|
});
|
|
3081
|
-
} catch {
|
|
3199
|
+
} catch (e) {
|
|
3200
|
+
logCatchDebug("migration", e);
|
|
3082
3201
|
}
|
|
3083
3202
|
try {
|
|
3084
3203
|
await client.execute({
|
|
3085
3204
|
sql: `ALTER TABLE memories ADD COLUMN last_accessed TEXT`,
|
|
3086
3205
|
args: []
|
|
3087
3206
|
});
|
|
3088
|
-
} catch {
|
|
3207
|
+
} catch (e) {
|
|
3208
|
+
logCatchDebug("migration", e);
|
|
3089
3209
|
}
|
|
3090
3210
|
try {
|
|
3091
3211
|
await client.execute({
|
|
3092
3212
|
sql: `UPDATE memories SET last_accessed = timestamp WHERE last_accessed IS NULL`,
|
|
3093
3213
|
args: []
|
|
3094
3214
|
});
|
|
3095
|
-
} catch {
|
|
3215
|
+
} catch (e) {
|
|
3216
|
+
logCatchDebug("migration", e);
|
|
3096
3217
|
}
|
|
3097
3218
|
try {
|
|
3098
3219
|
await client.execute({
|
|
3099
3220
|
sql: `ALTER TABLE memories ADD COLUMN wiki_synced INTEGER DEFAULT 0`,
|
|
3100
3221
|
args: []
|
|
3101
3222
|
});
|
|
3102
|
-
} catch {
|
|
3223
|
+
} catch (e) {
|
|
3224
|
+
logCatchDebug("migration", e);
|
|
3103
3225
|
}
|
|
3104
3226
|
try {
|
|
3105
3227
|
await client.execute({
|
|
3106
3228
|
sql: `ALTER TABLE memories ADD COLUMN graph_extracted INTEGER DEFAULT 0`,
|
|
3107
3229
|
args: []
|
|
3108
3230
|
});
|
|
3109
|
-
} catch {
|
|
3231
|
+
} catch (e) {
|
|
3232
|
+
logCatchDebug("migration", e);
|
|
3110
3233
|
}
|
|
3111
3234
|
for (const col of [
|
|
3112
3235
|
"ALTER TABLE memories ADD COLUMN content_hash TEXT",
|
|
@@ -3114,14 +3237,16 @@ async function ensureSchema() {
|
|
|
3114
3237
|
]) {
|
|
3115
3238
|
try {
|
|
3116
3239
|
await client.execute(col);
|
|
3117
|
-
} catch {
|
|
3240
|
+
} catch (e) {
|
|
3241
|
+
logCatchDebug("migration", e);
|
|
3118
3242
|
}
|
|
3119
3243
|
}
|
|
3120
3244
|
try {
|
|
3121
3245
|
await client.execute(
|
|
3122
3246
|
`CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash, agent_id)`
|
|
3123
3247
|
);
|
|
3124
|
-
} catch {
|
|
3248
|
+
} catch (e) {
|
|
3249
|
+
logCatchDebug("migration", e);
|
|
3125
3250
|
}
|
|
3126
3251
|
try {
|
|
3127
3252
|
await client.execute(
|
|
@@ -3129,7 +3254,8 @@ async function ensureSchema() {
|
|
|
3129
3254
|
ON memories(content_hash, agent_id, project_name, memory_type)
|
|
3130
3255
|
WHERE content_hash IS NOT NULL`
|
|
3131
3256
|
);
|
|
3132
|
-
} catch {
|
|
3257
|
+
} catch (e) {
|
|
3258
|
+
logCatchDebug("migration", e);
|
|
3133
3259
|
}
|
|
3134
3260
|
await client.executeMultiple(`
|
|
3135
3261
|
CREATE TABLE IF NOT EXISTS entities (
|
|
@@ -3205,7 +3331,8 @@ async function ensureSchema() {
|
|
|
3205
3331
|
`);
|
|
3206
3332
|
try {
|
|
3207
3333
|
await client.execute("INSERT INTO entities_fts(entities_fts) VALUES('rebuild')");
|
|
3208
|
-
} catch {
|
|
3334
|
+
} catch (e) {
|
|
3335
|
+
logCatchDebug("migration", e);
|
|
3209
3336
|
}
|
|
3210
3337
|
await client.executeMultiple(`
|
|
3211
3338
|
CREATE TABLE IF NOT EXISTS entity_aliases (
|
|
@@ -3220,14 +3347,16 @@ async function ensureSchema() {
|
|
|
3220
3347
|
]) {
|
|
3221
3348
|
try {
|
|
3222
3349
|
await client.execute(col);
|
|
3223
|
-
} catch {
|
|
3350
|
+
} catch (e) {
|
|
3351
|
+
logCatchDebug("migration", e);
|
|
3224
3352
|
}
|
|
3225
3353
|
}
|
|
3226
3354
|
try {
|
|
3227
3355
|
await client.execute(
|
|
3228
3356
|
`CREATE INDEX IF NOT EXISTS idx_memories_status ON memories(status)`
|
|
3229
3357
|
);
|
|
3230
|
-
} catch {
|
|
3358
|
+
} catch (e) {
|
|
3359
|
+
logCatchDebug("migration", e);
|
|
3231
3360
|
}
|
|
3232
3361
|
await client.executeMultiple(`
|
|
3233
3362
|
CREATE TABLE IF NOT EXISTS identity (
|
|
@@ -3326,7 +3455,8 @@ async function ensureSchema() {
|
|
|
3326
3455
|
sql: `ALTER TABLE memories ADD COLUMN ${column}`,
|
|
3327
3456
|
args: []
|
|
3328
3457
|
});
|
|
3329
|
-
} catch {
|
|
3458
|
+
} catch (e) {
|
|
3459
|
+
logCatchDebug("migration", e);
|
|
3330
3460
|
}
|
|
3331
3461
|
}
|
|
3332
3462
|
for (const col of [
|
|
@@ -3335,7 +3465,8 @@ async function ensureSchema() {
|
|
|
3335
3465
|
]) {
|
|
3336
3466
|
try {
|
|
3337
3467
|
await client.execute(col);
|
|
3338
|
-
} catch {
|
|
3468
|
+
} catch (e) {
|
|
3469
|
+
logCatchDebug("migration", e);
|
|
3339
3470
|
}
|
|
3340
3471
|
}
|
|
3341
3472
|
await client.executeMultiple(`
|
|
@@ -3520,56 +3651,64 @@ async function ensureSchema() {
|
|
|
3520
3651
|
args: []
|
|
3521
3652
|
});
|
|
3522
3653
|
}
|
|
3523
|
-
} catch {
|
|
3654
|
+
} catch (e) {
|
|
3655
|
+
logCatchDebug("session_agent_map backfill", e);
|
|
3524
3656
|
}
|
|
3525
3657
|
try {
|
|
3526
3658
|
await client.execute({
|
|
3527
3659
|
sql: `ALTER TABLE session_agent_map ADD COLUMN cache_cold_count INTEGER NOT NULL DEFAULT 0`,
|
|
3528
3660
|
args: []
|
|
3529
3661
|
});
|
|
3530
|
-
} catch {
|
|
3662
|
+
} catch (e) {
|
|
3663
|
+
logCatchDebug("migration", e);
|
|
3531
3664
|
}
|
|
3532
3665
|
try {
|
|
3533
3666
|
await client.execute({
|
|
3534
3667
|
sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
|
|
3535
3668
|
args: []
|
|
3536
3669
|
});
|
|
3537
|
-
} catch {
|
|
3670
|
+
} catch (e) {
|
|
3671
|
+
logCatchDebug("migration", e);
|
|
3538
3672
|
}
|
|
3539
3673
|
try {
|
|
3540
3674
|
await client.execute({
|
|
3541
3675
|
sql: `ALTER TABLE tasks ADD COLUMN budget_fallback_model TEXT`,
|
|
3542
3676
|
args: []
|
|
3543
3677
|
});
|
|
3544
|
-
} catch {
|
|
3678
|
+
} catch (e) {
|
|
3679
|
+
logCatchDebug("migration", e);
|
|
3545
3680
|
}
|
|
3546
3681
|
try {
|
|
3547
3682
|
await client.execute({
|
|
3548
3683
|
sql: `ALTER TABLE tasks ADD COLUMN tokens_used INTEGER DEFAULT 0`,
|
|
3549
3684
|
args: []
|
|
3550
3685
|
});
|
|
3551
|
-
} catch {
|
|
3686
|
+
} catch (e) {
|
|
3687
|
+
logCatchDebug("migration", e);
|
|
3552
3688
|
}
|
|
3553
3689
|
try {
|
|
3554
3690
|
await client.execute({
|
|
3555
3691
|
sql: `ALTER TABLE tasks ADD COLUMN tokens_warned_at INTEGER`,
|
|
3556
3692
|
args: []
|
|
3557
3693
|
});
|
|
3558
|
-
} catch {
|
|
3694
|
+
} catch (e) {
|
|
3695
|
+
logCatchDebug("migration", e);
|
|
3559
3696
|
}
|
|
3560
3697
|
try {
|
|
3561
3698
|
await client.execute({
|
|
3562
3699
|
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
3563
3700
|
args: []
|
|
3564
3701
|
});
|
|
3565
|
-
} catch {
|
|
3702
|
+
} catch (e) {
|
|
3703
|
+
logCatchDebug("migration", e);
|
|
3566
3704
|
}
|
|
3567
3705
|
try {
|
|
3568
3706
|
await client.execute({
|
|
3569
3707
|
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
3570
3708
|
args: []
|
|
3571
3709
|
});
|
|
3572
|
-
} catch {
|
|
3710
|
+
} catch (e) {
|
|
3711
|
+
logCatchDebug("migration", e);
|
|
3573
3712
|
}
|
|
3574
3713
|
await client.executeMultiple(`
|
|
3575
3714
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
@@ -3768,13 +3907,15 @@ async function ensureSchema() {
|
|
|
3768
3907
|
sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
|
|
3769
3908
|
args: []
|
|
3770
3909
|
});
|
|
3771
|
-
} catch {
|
|
3910
|
+
} catch (e) {
|
|
3911
|
+
logCatchDebug("migration", e);
|
|
3772
3912
|
}
|
|
3773
3913
|
try {
|
|
3774
3914
|
await client.execute(
|
|
3775
3915
|
`CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)`
|
|
3776
3916
|
);
|
|
3777
|
-
} catch {
|
|
3917
|
+
} catch (e) {
|
|
3918
|
+
logCatchDebug("migration", e);
|
|
3778
3919
|
}
|
|
3779
3920
|
try {
|
|
3780
3921
|
await client.execute({
|
|
@@ -3785,20 +3926,23 @@ async function ensureSchema() {
|
|
|
3785
3926
|
sql: `UPDATE memories SET tier = 2 WHERE tool_name IN ('store_memory', 'manual') AND importance >= 5 AND tier = 3`,
|
|
3786
3927
|
args: []
|
|
3787
3928
|
});
|
|
3788
|
-
} catch {
|
|
3929
|
+
} catch (e) {
|
|
3930
|
+
logCatchDebug("migration", e);
|
|
3789
3931
|
}
|
|
3790
3932
|
try {
|
|
3791
3933
|
await client.execute({
|
|
3792
3934
|
sql: `ALTER TABLE memories ADD COLUMN supersedes_id TEXT`,
|
|
3793
3935
|
args: []
|
|
3794
3936
|
});
|
|
3795
|
-
} catch {
|
|
3937
|
+
} catch (e) {
|
|
3938
|
+
logCatchDebug("migration", e);
|
|
3796
3939
|
}
|
|
3797
3940
|
try {
|
|
3798
3941
|
await client.execute(
|
|
3799
3942
|
`CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL`
|
|
3800
3943
|
);
|
|
3801
|
-
} catch {
|
|
3944
|
+
} catch (e) {
|
|
3945
|
+
logCatchDebug("migration", e);
|
|
3802
3946
|
}
|
|
3803
3947
|
for (const col of [
|
|
3804
3948
|
"ALTER TABLE tasks ADD COLUMN checkpoint TEXT",
|
|
@@ -3806,7 +3950,8 @@ async function ensureSchema() {
|
|
|
3806
3950
|
]) {
|
|
3807
3951
|
try {
|
|
3808
3952
|
await client.execute(col);
|
|
3809
|
-
} catch {
|
|
3953
|
+
} catch (e) {
|
|
3954
|
+
logCatchDebug("migration", e);
|
|
3810
3955
|
}
|
|
3811
3956
|
}
|
|
3812
3957
|
try {
|
|
@@ -3814,13 +3959,15 @@ async function ensureSchema() {
|
|
|
3814
3959
|
sql: `ALTER TABLE memories ADD COLUMN draft INTEGER DEFAULT 0`,
|
|
3815
3960
|
args: []
|
|
3816
3961
|
});
|
|
3817
|
-
} catch {
|
|
3962
|
+
} catch (e) {
|
|
3963
|
+
logCatchDebug("migration", e);
|
|
3818
3964
|
}
|
|
3819
3965
|
try {
|
|
3820
3966
|
await client.execute(
|
|
3821
3967
|
`CREATE INDEX IF NOT EXISTS idx_memories_draft ON memories(draft) WHERE draft = 1`
|
|
3822
3968
|
);
|
|
3823
|
-
} catch {
|
|
3969
|
+
} catch (e) {
|
|
3970
|
+
logCatchDebug("migration", e);
|
|
3824
3971
|
}
|
|
3825
3972
|
for (const col of [
|
|
3826
3973
|
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
@@ -3828,7 +3975,8 @@ async function ensureSchema() {
|
|
|
3828
3975
|
]) {
|
|
3829
3976
|
try {
|
|
3830
3977
|
await client.execute(col);
|
|
3831
|
-
} catch {
|
|
3978
|
+
} catch (e) {
|
|
3979
|
+
logCatchDebug("migration", e);
|
|
3832
3980
|
}
|
|
3833
3981
|
}
|
|
3834
3982
|
try {
|
|
@@ -3836,27 +3984,31 @@ async function ensureSchema() {
|
|
|
3836
3984
|
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3837
3985
|
args: []
|
|
3838
3986
|
});
|
|
3839
|
-
} catch {
|
|
3987
|
+
} catch (e) {
|
|
3988
|
+
logCatchDebug("migration", e);
|
|
3840
3989
|
}
|
|
3841
3990
|
try {
|
|
3842
3991
|
await client.execute({
|
|
3843
3992
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
3844
3993
|
args: []
|
|
3845
3994
|
});
|
|
3846
|
-
} catch {
|
|
3995
|
+
} catch (e) {
|
|
3996
|
+
logCatchDebug("migration", e);
|
|
3847
3997
|
}
|
|
3848
3998
|
try {
|
|
3849
3999
|
await client.execute(
|
|
3850
4000
|
`CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(memory_type)`
|
|
3851
4001
|
);
|
|
3852
|
-
} catch {
|
|
4002
|
+
} catch (e) {
|
|
4003
|
+
logCatchDebug("migration", e);
|
|
3853
4004
|
}
|
|
3854
4005
|
try {
|
|
3855
4006
|
await client.execute({
|
|
3856
4007
|
sql: `ALTER TABLE memories ADD COLUMN trajectory TEXT`,
|
|
3857
4008
|
args: []
|
|
3858
4009
|
});
|
|
3859
|
-
} catch {
|
|
4010
|
+
} catch (e) {
|
|
4011
|
+
logCatchDebug("migration", e);
|
|
3860
4012
|
}
|
|
3861
4013
|
for (const col of [
|
|
3862
4014
|
"ALTER TABLE memories ADD COLUMN intent TEXT",
|
|
@@ -3877,7 +4029,8 @@ async function ensureSchema() {
|
|
|
3877
4029
|
]) {
|
|
3878
4030
|
try {
|
|
3879
4031
|
await client.execute(col);
|
|
3880
|
-
} catch {
|
|
4032
|
+
} catch (e) {
|
|
4033
|
+
logCatchDebug("migration", e);
|
|
3881
4034
|
}
|
|
3882
4035
|
}
|
|
3883
4036
|
try {
|
|
@@ -3885,14 +4038,16 @@ async function ensureSchema() {
|
|
|
3885
4038
|
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3886
4039
|
args: []
|
|
3887
4040
|
});
|
|
3888
|
-
} catch {
|
|
4041
|
+
} catch (e) {
|
|
4042
|
+
logCatchDebug("migration", e);
|
|
3889
4043
|
}
|
|
3890
4044
|
try {
|
|
3891
4045
|
await client.execute({
|
|
3892
4046
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
3893
4047
|
args: []
|
|
3894
4048
|
});
|
|
3895
|
-
} catch {
|
|
4049
|
+
} catch (e) {
|
|
4050
|
+
logCatchDebug("migration", e);
|
|
3896
4051
|
}
|
|
3897
4052
|
}
|
|
3898
4053
|
async function disposeDatabase() {
|
|
@@ -3903,7 +4058,8 @@ async function disposeDatabase() {
|
|
|
3903
4058
|
if (_client) {
|
|
3904
4059
|
try {
|
|
3905
4060
|
await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3906
|
-
} catch {
|
|
4061
|
+
} catch (e) {
|
|
4062
|
+
logCatchDebug("WAL checkpoint", e);
|
|
3907
4063
|
}
|
|
3908
4064
|
}
|
|
3909
4065
|
if (_daemonClient) {
|
|
@@ -3919,8 +4075,9 @@ async function disposeDatabase() {
|
|
|
3919
4075
|
_client = null;
|
|
3920
4076
|
_resilientClient = null;
|
|
3921
4077
|
}
|
|
4078
|
+
releaseDbLock();
|
|
3922
4079
|
}
|
|
3923
|
-
var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
|
|
4080
|
+
var _debugDb, _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, _lockFd, DB_LOCK_PATH, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
|
|
3924
4081
|
var init_database = __esm({
|
|
3925
4082
|
"src/lib/database.ts"() {
|
|
3926
4083
|
"use strict";
|
|
@@ -3928,11 +4085,14 @@ var init_database = __esm({
|
|
|
3928
4085
|
init_employees();
|
|
3929
4086
|
init_database_adapter();
|
|
3930
4087
|
init_memory();
|
|
4088
|
+
_debugDb = process.env.EXE_DEBUG === "1";
|
|
3931
4089
|
_client = null;
|
|
3932
4090
|
_resilientClient = null;
|
|
3933
4091
|
_walCheckpointTimer = null;
|
|
3934
4092
|
_daemonClient = null;
|
|
3935
4093
|
_adapterClient = null;
|
|
4094
|
+
_lockFd = null;
|
|
4095
|
+
DB_LOCK_PATH = join(homedir(), ".exe-os", "db.lock");
|
|
3936
4096
|
initTurso = initDatabase;
|
|
3937
4097
|
SOFT_DELETE_RETENTION_DAYS = 7;
|
|
3938
4098
|
disposeTurso = disposeDatabase;
|
|
@@ -3957,7 +4117,7 @@ __export(license_exports, {
|
|
|
3957
4117
|
stopLicenseRevalidation: () => stopLicenseRevalidation,
|
|
3958
4118
|
validateLicense: () => validateLicense
|
|
3959
4119
|
});
|
|
3960
|
-
import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, existsSync as
|
|
4120
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, existsSync as existsSync11, mkdirSync as mkdirSync5 } from "fs";
|
|
3961
4121
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
3962
4122
|
import { createRequire as createRequire2 } from "module";
|
|
3963
4123
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
@@ -3975,34 +4135,34 @@ async function fetchRetry(url, init) {
|
|
|
3975
4135
|
function loadDeviceId() {
|
|
3976
4136
|
const deviceJsonPath = path9.join(EXE_AI_DIR, "device.json");
|
|
3977
4137
|
try {
|
|
3978
|
-
if (
|
|
4138
|
+
if (existsSync11(deviceJsonPath)) {
|
|
3979
4139
|
const data = JSON.parse(readFileSync9(deviceJsonPath, "utf8"));
|
|
3980
4140
|
if (data.deviceId) return data.deviceId;
|
|
3981
4141
|
}
|
|
3982
4142
|
} catch {
|
|
3983
4143
|
}
|
|
3984
4144
|
try {
|
|
3985
|
-
if (
|
|
4145
|
+
if (existsSync11(DEVICE_ID_PATH)) {
|
|
3986
4146
|
const id2 = readFileSync9(DEVICE_ID_PATH, "utf8").trim();
|
|
3987
4147
|
if (id2) return id2;
|
|
3988
4148
|
}
|
|
3989
4149
|
} catch {
|
|
3990
4150
|
}
|
|
3991
4151
|
const id = randomUUID2();
|
|
3992
|
-
|
|
4152
|
+
mkdirSync5(EXE_AI_DIR, { recursive: true });
|
|
3993
4153
|
writeFileSync6(DEVICE_ID_PATH, id, "utf8");
|
|
3994
4154
|
return id;
|
|
3995
4155
|
}
|
|
3996
4156
|
function loadLicense() {
|
|
3997
4157
|
try {
|
|
3998
|
-
if (!
|
|
4158
|
+
if (!existsSync11(LICENSE_PATH)) return null;
|
|
3999
4159
|
return readFileSync9(LICENSE_PATH, "utf8").trim();
|
|
4000
4160
|
} catch {
|
|
4001
4161
|
return null;
|
|
4002
4162
|
}
|
|
4003
4163
|
}
|
|
4004
4164
|
function saveLicense(apiKey) {
|
|
4005
|
-
|
|
4165
|
+
mkdirSync5(EXE_AI_DIR, { recursive: true });
|
|
4006
4166
|
writeFileSync6(LICENSE_PATH, apiKey.trim(), { encoding: "utf8", mode: 384 });
|
|
4007
4167
|
}
|
|
4008
4168
|
async function verifyLicenseJwt(token) {
|
|
@@ -4029,7 +4189,7 @@ async function verifyLicenseJwt(token) {
|
|
|
4029
4189
|
}
|
|
4030
4190
|
async function getCachedLicense() {
|
|
4031
4191
|
try {
|
|
4032
|
-
if (!
|
|
4192
|
+
if (!existsSync11(CACHE_PATH)) return null;
|
|
4033
4193
|
const raw = JSON.parse(readFileSync9(CACHE_PATH, "utf8"));
|
|
4034
4194
|
if (!raw.token || typeof raw.token !== "string") return null;
|
|
4035
4195
|
return await verifyLicenseJwt(raw.token);
|
|
@@ -4039,7 +4199,7 @@ async function getCachedLicense() {
|
|
|
4039
4199
|
}
|
|
4040
4200
|
function readCachedLicenseToken() {
|
|
4041
4201
|
try {
|
|
4042
|
-
if (!
|
|
4202
|
+
if (!existsSync11(CACHE_PATH)) return null;
|
|
4043
4203
|
const raw = JSON.parse(readFileSync9(CACHE_PATH, "utf8"));
|
|
4044
4204
|
return typeof raw.token === "string" ? raw.token : null;
|
|
4045
4205
|
} catch {
|
|
@@ -4083,7 +4243,7 @@ function loadPrismaForLicense() {
|
|
|
4083
4243
|
const dbUrl = process.env.DATABASE_URL;
|
|
4084
4244
|
if (!dbUrl) {
|
|
4085
4245
|
const exeDbRoot = process.env.EXE_DB_ROOT ?? path9.join(os7.homedir(), "exe-db");
|
|
4086
|
-
if (!
|
|
4246
|
+
if (!existsSync11(path9.join(exeDbRoot, "package.json"))) {
|
|
4087
4247
|
_prismaFailed = true;
|
|
4088
4248
|
return null;
|
|
4089
4249
|
}
|
|
@@ -4187,7 +4347,7 @@ async function validateLicense(apiKey, deviceId) {
|
|
|
4187
4347
|
const cached = await getCachedLicense();
|
|
4188
4348
|
if (cached) return cached;
|
|
4189
4349
|
try {
|
|
4190
|
-
if (
|
|
4350
|
+
if (existsSync11(CACHE_PATH)) {
|
|
4191
4351
|
const raw = JSON.parse(readFileSync9(CACHE_PATH, "utf8"));
|
|
4192
4352
|
if (raw.pgLicense && raw.ts && Date.now() - raw.ts < 7 * 24 * 60 * 60 * 1e3) {
|
|
4193
4353
|
return raw.pgLicense;
|
|
@@ -4201,8 +4361,8 @@ async function validateLicense(apiKey, deviceId) {
|
|
|
4201
4361
|
}
|
|
4202
4362
|
function getCacheAgeMs() {
|
|
4203
4363
|
try {
|
|
4204
|
-
const { statSync:
|
|
4205
|
-
const s =
|
|
4364
|
+
const { statSync: statSync5 } = __require("fs");
|
|
4365
|
+
const s = statSync5(CACHE_PATH);
|
|
4206
4366
|
return Date.now() - s.mtimeMs;
|
|
4207
4367
|
} catch {
|
|
4208
4368
|
return Infinity;
|
|
@@ -4213,7 +4373,7 @@ async function checkLicense() {
|
|
|
4213
4373
|
if (!key) {
|
|
4214
4374
|
try {
|
|
4215
4375
|
const configPath = path9.join(EXE_AI_DIR, "config.json");
|
|
4216
|
-
if (
|
|
4376
|
+
if (existsSync11(configPath)) {
|
|
4217
4377
|
const raw = JSON.parse(readFileSync9(configPath, "utf8"));
|
|
4218
4378
|
const cloud = raw.cloud;
|
|
4219
4379
|
if (cloud?.apiKey) {
|
|
@@ -4407,11 +4567,11 @@ MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeHztAMOpR/ZMh+rWuOASjEZ54CGY
|
|
|
4407
4567
|
});
|
|
4408
4568
|
|
|
4409
4569
|
// src/lib/plan-limits.ts
|
|
4410
|
-
import { readFileSync as readFileSync10, existsSync as
|
|
4570
|
+
import { readFileSync as readFileSync10, existsSync as existsSync12 } from "fs";
|
|
4411
4571
|
import path10 from "path";
|
|
4412
4572
|
function getLicenseSync() {
|
|
4413
4573
|
try {
|
|
4414
|
-
if (!
|
|
4574
|
+
if (!existsSync12(CACHE_PATH2)) return freeLicense();
|
|
4415
4575
|
const raw = JSON.parse(readFileSync10(CACHE_PATH2, "utf8"));
|
|
4416
4576
|
if (!raw.token || typeof raw.token !== "string") return freeLicense();
|
|
4417
4577
|
const parts = raw.token.split(".");
|
|
@@ -4450,7 +4610,7 @@ function assertEmployeeLimitSync(rosterPath) {
|
|
|
4450
4610
|
const filePath = rosterPath ?? EMPLOYEES_PATH;
|
|
4451
4611
|
let count = 0;
|
|
4452
4612
|
try {
|
|
4453
|
-
if (
|
|
4613
|
+
if (existsSync12(filePath)) {
|
|
4454
4614
|
const raw = readFileSync10(filePath, "utf8");
|
|
4455
4615
|
const employees = JSON.parse(raw);
|
|
4456
4616
|
count = Array.isArray(employees) ? employees.length : 0;
|
|
@@ -4488,9 +4648,9 @@ var init_plan_limits = __esm({
|
|
|
4488
4648
|
import os8 from "os";
|
|
4489
4649
|
import path11 from "path";
|
|
4490
4650
|
import {
|
|
4491
|
-
existsSync as
|
|
4651
|
+
existsSync as existsSync13,
|
|
4492
4652
|
lstatSync,
|
|
4493
|
-
mkdirSync as
|
|
4653
|
+
mkdirSync as mkdirSync6,
|
|
4494
4654
|
readlinkSync as readlinkSync2,
|
|
4495
4655
|
symlinkSync as symlinkSync2
|
|
4496
4656
|
} from "fs";
|
|
@@ -4506,8 +4666,8 @@ function claudeAgentLinkPath(homeDir, agentId) {
|
|
|
4506
4666
|
function ensureAgentSymlink(agentId, homeDir = os8.homedir()) {
|
|
4507
4667
|
const target = identitySourcePath(homeDir, agentId);
|
|
4508
4668
|
const link = claudeAgentLinkPath(homeDir, agentId);
|
|
4509
|
-
|
|
4510
|
-
if (
|
|
4669
|
+
mkdirSync6(claudeAgentsDir(homeDir), { recursive: true });
|
|
4670
|
+
if (existsSync13(link)) {
|
|
4511
4671
|
let stat;
|
|
4512
4672
|
try {
|
|
4513
4673
|
stat = lstatSync(link);
|
|
@@ -4555,8 +4715,8 @@ import os9 from "os";
|
|
|
4555
4715
|
import {
|
|
4556
4716
|
readFileSync as readFileSync11,
|
|
4557
4717
|
readdirSync,
|
|
4558
|
-
unlinkSync as
|
|
4559
|
-
existsSync as
|
|
4718
|
+
unlinkSync as unlinkSync4,
|
|
4719
|
+
existsSync as existsSync14,
|
|
4560
4720
|
rmdirSync
|
|
4561
4721
|
} from "fs";
|
|
4562
4722
|
async function writeNotification(notification) {
|
|
@@ -4820,7 +4980,7 @@ import path14 from "path";
|
|
|
4820
4980
|
import os10 from "os";
|
|
4821
4981
|
import { execSync as execSync7 } from "child_process";
|
|
4822
4982
|
import { mkdir as mkdir3, writeFile as writeFile3, appendFile } from "fs/promises";
|
|
4823
|
-
import { existsSync as
|
|
4983
|
+
import { existsSync as existsSync15, readFileSync as readFileSync12 } from "fs";
|
|
4824
4984
|
async function writeCheckpoint(input) {
|
|
4825
4985
|
const client = getClient();
|
|
4826
4986
|
const row = await resolveTask(client, input.taskId);
|
|
@@ -5061,7 +5221,7 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
5061
5221
|
const EXE_OS_DIR = path14.join(os10.homedir(), ".exe-os");
|
|
5062
5222
|
const mdPath = path14.join(EXE_OS_DIR, taskFile);
|
|
5063
5223
|
const mdDir = path14.dirname(mdPath);
|
|
5064
|
-
if (!
|
|
5224
|
+
if (!existsSync15(mdDir)) await mkdir3(mdDir, { recursive: true });
|
|
5065
5225
|
const reviewer = input.reviewer ?? input.assignedBy;
|
|
5066
5226
|
const mdContent = `# ${input.title}
|
|
5067
5227
|
|
|
@@ -5367,7 +5527,7 @@ async function deleteTaskCore(taskId, _baseDir) {
|
|
|
5367
5527
|
async function ensureArchitectureDoc(baseDir, projectName) {
|
|
5368
5528
|
const archPath = path14.join(baseDir, "exe", "ARCHITECTURE.md");
|
|
5369
5529
|
try {
|
|
5370
|
-
if (
|
|
5530
|
+
if (existsSync15(archPath)) return;
|
|
5371
5531
|
const template = [
|
|
5372
5532
|
`# ${projectName} \u2014 System Architecture`,
|
|
5373
5533
|
"",
|
|
@@ -5402,7 +5562,7 @@ async function ensureArchitectureDoc(baseDir, projectName) {
|
|
|
5402
5562
|
async function ensureGitignoreExe(baseDir) {
|
|
5403
5563
|
const gitignorePath = path14.join(baseDir, ".gitignore");
|
|
5404
5564
|
try {
|
|
5405
|
-
if (
|
|
5565
|
+
if (existsSync15(gitignorePath)) {
|
|
5406
5566
|
const content = readFileSync12(gitignorePath, "utf-8");
|
|
5407
5567
|
if (/^\/?exe\/?$/m.test(content)) return;
|
|
5408
5568
|
await appendFile(gitignorePath, "\n# Employee task assignments (private)\n/exe/\n");
|
|
@@ -5447,7 +5607,7 @@ __export(tasks_review_exports, {
|
|
|
5447
5607
|
listPendingReviews: () => listPendingReviews
|
|
5448
5608
|
});
|
|
5449
5609
|
import path15 from "path";
|
|
5450
|
-
import { existsSync as
|
|
5610
|
+
import { existsSync as existsSync16, readdirSync as readdirSync2, unlinkSync as unlinkSync5 } from "fs";
|
|
5451
5611
|
function formatAge(isoTimestamp) {
|
|
5452
5612
|
if (!isoTimestamp) return "";
|
|
5453
5613
|
const ms = Date.now() - new Date(isoTimestamp).getTime();
|
|
@@ -5717,10 +5877,10 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
5717
5877
|
}
|
|
5718
5878
|
try {
|
|
5719
5879
|
const cacheDir = path15.join(EXE_AI_DIR, "session-cache");
|
|
5720
|
-
if (
|
|
5880
|
+
if (existsSync16(cacheDir)) {
|
|
5721
5881
|
for (const f of readdirSync2(cacheDir)) {
|
|
5722
5882
|
if (f.startsWith("review-notified-")) {
|
|
5723
|
-
|
|
5883
|
+
unlinkSync5(path15.join(cacheDir, f));
|
|
5724
5884
|
}
|
|
5725
5885
|
}
|
|
5726
5886
|
}
|
|
@@ -5943,10 +6103,10 @@ async function disposeEmbedder() {
|
|
|
5943
6103
|
async function embedDirect(text) {
|
|
5944
6104
|
const llamaCpp = await import("node-llama-cpp");
|
|
5945
6105
|
const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
5946
|
-
const { existsSync:
|
|
6106
|
+
const { existsSync: existsSync20 } = await import("fs");
|
|
5947
6107
|
const path29 = await import("path");
|
|
5948
6108
|
const modelPath = path29.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
|
|
5949
|
-
if (!
|
|
6109
|
+
if (!existsSync20(modelPath)) {
|
|
5950
6110
|
throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
|
|
5951
6111
|
}
|
|
5952
6112
|
const llama = await llamaCpp.getLlama();
|
|
@@ -6313,7 +6473,7 @@ __export(tasks_exports, {
|
|
|
6313
6473
|
writeCheckpoint: () => writeCheckpoint
|
|
6314
6474
|
});
|
|
6315
6475
|
import path17 from "path";
|
|
6316
|
-
import { writeFileSync as writeFileSync7, mkdirSync as
|
|
6476
|
+
import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, unlinkSync as unlinkSync6 } from "fs";
|
|
6317
6477
|
async function createTask(input) {
|
|
6318
6478
|
const result = await createTaskCore(input);
|
|
6319
6479
|
if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
|
|
@@ -6335,11 +6495,11 @@ async function updateTask(input) {
|
|
|
6335
6495
|
const cacheDir = path17.join(EXE_AI_DIR, "session-cache");
|
|
6336
6496
|
const cachePath = path17.join(cacheDir, `current-task-${agent}.json`);
|
|
6337
6497
|
if (input.status === "in_progress") {
|
|
6338
|
-
|
|
6498
|
+
mkdirSync7(cacheDir, { recursive: true });
|
|
6339
6499
|
writeFileSync7(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
|
|
6340
6500
|
} else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled" || input.status === "closed") {
|
|
6341
6501
|
try {
|
|
6342
|
-
|
|
6502
|
+
unlinkSync6(cachePath);
|
|
6343
6503
|
} catch {
|
|
6344
6504
|
}
|
|
6345
6505
|
}
|
|
@@ -6807,11 +6967,11 @@ __export(tmux_routing_exports, {
|
|
|
6807
6967
|
verifyPaneAtCapacity: () => verifyPaneAtCapacity
|
|
6808
6968
|
});
|
|
6809
6969
|
import { execFileSync as execFileSync3, execSync as execSync8 } from "child_process";
|
|
6810
|
-
import { readFileSync as readFileSync13, writeFileSync as writeFileSync8, mkdirSync as
|
|
6970
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync8, mkdirSync as mkdirSync8, existsSync as existsSync17, appendFileSync, readdirSync as readdirSync3 } from "fs";
|
|
6811
6971
|
import path18 from "path";
|
|
6812
6972
|
import os11 from "os";
|
|
6813
6973
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
6814
|
-
import { unlinkSync as
|
|
6974
|
+
import { unlinkSync as unlinkSync7 } from "fs";
|
|
6815
6975
|
function spawnLockPath(sessionName) {
|
|
6816
6976
|
return path18.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
|
|
6817
6977
|
}
|
|
@@ -6824,11 +6984,11 @@ function isProcessAlive(pid) {
|
|
|
6824
6984
|
}
|
|
6825
6985
|
}
|
|
6826
6986
|
function acquireSpawnLock2(sessionName) {
|
|
6827
|
-
if (!
|
|
6828
|
-
|
|
6987
|
+
if (!existsSync17(SPAWN_LOCK_DIR)) {
|
|
6988
|
+
mkdirSync8(SPAWN_LOCK_DIR, { recursive: true });
|
|
6829
6989
|
}
|
|
6830
6990
|
const lockFile = spawnLockPath(sessionName);
|
|
6831
|
-
if (
|
|
6991
|
+
if (existsSync17(lockFile)) {
|
|
6832
6992
|
try {
|
|
6833
6993
|
const lock = JSON.parse(readFileSync13(lockFile, "utf8"));
|
|
6834
6994
|
const age = Date.now() - lock.timestamp;
|
|
@@ -6843,7 +7003,7 @@ function acquireSpawnLock2(sessionName) {
|
|
|
6843
7003
|
}
|
|
6844
7004
|
function releaseSpawnLock2(sessionName) {
|
|
6845
7005
|
try {
|
|
6846
|
-
|
|
7006
|
+
unlinkSync7(spawnLockPath(sessionName));
|
|
6847
7007
|
} catch {
|
|
6848
7008
|
}
|
|
6849
7009
|
}
|
|
@@ -6856,7 +7016,7 @@ function resolveBehaviorsExporterScript() {
|
|
|
6856
7016
|
"bin",
|
|
6857
7017
|
"exe-export-behaviors.js"
|
|
6858
7018
|
);
|
|
6859
|
-
return
|
|
7019
|
+
return existsSync17(scriptPath) ? scriptPath : null;
|
|
6860
7020
|
} catch {
|
|
6861
7021
|
return null;
|
|
6862
7022
|
}
|
|
@@ -6922,8 +7082,8 @@ function extractRootExe(name) {
|
|
|
6922
7082
|
return parts.length > 0 ? parts[parts.length - 1] : null;
|
|
6923
7083
|
}
|
|
6924
7084
|
function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
6925
|
-
if (!
|
|
6926
|
-
|
|
7085
|
+
if (!existsSync17(SESSION_CACHE)) {
|
|
7086
|
+
mkdirSync8(SESSION_CACHE, { recursive: true });
|
|
6927
7087
|
}
|
|
6928
7088
|
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
6929
7089
|
const filePath = path18.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
@@ -6953,11 +7113,13 @@ function getDispatchedBy(sessionKey) {
|
|
|
6953
7113
|
}
|
|
6954
7114
|
}
|
|
6955
7115
|
function resolveExeSession() {
|
|
6956
|
-
if (process.env.EXE_SESSION_NAME) {
|
|
6957
|
-
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
6958
|
-
}
|
|
6959
7116
|
const mySession = getMySession();
|
|
6960
|
-
if (!mySession)
|
|
7117
|
+
if (!mySession) {
|
|
7118
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
7119
|
+
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
7120
|
+
}
|
|
7121
|
+
return null;
|
|
7122
|
+
}
|
|
6961
7123
|
const fromSessionName = extractRootExe(mySession);
|
|
6962
7124
|
let candidate = null;
|
|
6963
7125
|
try {
|
|
@@ -7052,7 +7214,7 @@ async function verifyPaneAtCapacity(sessionName) {
|
|
|
7052
7214
|
}
|
|
7053
7215
|
function readDebounceState() {
|
|
7054
7216
|
try {
|
|
7055
|
-
if (!
|
|
7217
|
+
if (!existsSync17(DEBOUNCE_FILE)) return {};
|
|
7056
7218
|
const raw = JSON.parse(readFileSync13(DEBOUNCE_FILE, "utf8"));
|
|
7057
7219
|
const state = {};
|
|
7058
7220
|
for (const [key, val] of Object.entries(raw)) {
|
|
@@ -7069,7 +7231,7 @@ function readDebounceState() {
|
|
|
7069
7231
|
}
|
|
7070
7232
|
function writeDebounceState(state) {
|
|
7071
7233
|
try {
|
|
7072
|
-
if (!
|
|
7234
|
+
if (!existsSync17(SESSION_CACHE)) mkdirSync8(SESSION_CACHE, { recursive: true });
|
|
7073
7235
|
writeFileSync8(DEBOUNCE_FILE, JSON.stringify(state));
|
|
7074
7236
|
} catch {
|
|
7075
7237
|
}
|
|
@@ -7170,7 +7332,7 @@ function sendIntercom(targetSession) {
|
|
|
7170
7332
|
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
7171
7333
|
const agent = baseAgentName(rawAgent);
|
|
7172
7334
|
const markerPath = path18.join(SESSION_CACHE, `current-task-${agent}.json`);
|
|
7173
|
-
if (
|
|
7335
|
+
if (existsSync17(markerPath)) {
|
|
7174
7336
|
logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker + not idle \u2014 will auto-chain)`);
|
|
7175
7337
|
return "debounced";
|
|
7176
7338
|
}
|
|
@@ -7181,7 +7343,7 @@ function sendIntercom(targetSession) {
|
|
|
7181
7343
|
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
7182
7344
|
const agent = baseAgentName(rawAgent);
|
|
7183
7345
|
const taskDir = path18.join(process.cwd(), "exe", agent);
|
|
7184
|
-
if (
|
|
7346
|
+
if (existsSync17(taskDir)) {
|
|
7185
7347
|
const files = readdirSync3(taskDir).filter(
|
|
7186
7348
|
(f) => f.endsWith(".md") && f !== "DONE.txt"
|
|
7187
7349
|
);
|
|
@@ -7342,15 +7504,15 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
7342
7504
|
const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
|
|
7343
7505
|
const logDir = path18.join(os11.homedir(), ".exe-os", "session-logs");
|
|
7344
7506
|
const logFile = path18.join(logDir, `${instanceLabel}-${Date.now()}.log`);
|
|
7345
|
-
if (!
|
|
7346
|
-
|
|
7507
|
+
if (!existsSync17(logDir)) {
|
|
7508
|
+
mkdirSync8(logDir, { recursive: true });
|
|
7347
7509
|
}
|
|
7348
7510
|
transport.kill(sessionName);
|
|
7349
7511
|
let cleanupSuffix = "";
|
|
7350
7512
|
try {
|
|
7351
7513
|
const thisFile = fileURLToPath2(import.meta.url);
|
|
7352
7514
|
const cleanupScript = path18.join(path18.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
|
|
7353
|
-
if (
|
|
7515
|
+
if (existsSync17(cleanupScript)) {
|
|
7354
7516
|
cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
|
|
7355
7517
|
}
|
|
7356
7518
|
} catch {
|
|
@@ -7405,7 +7567,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
7405
7567
|
if (changed) {
|
|
7406
7568
|
perms.allow = allow;
|
|
7407
7569
|
settings.permissions = perms;
|
|
7408
|
-
|
|
7570
|
+
mkdirSync8(projSettingsDir, { recursive: true });
|
|
7409
7571
|
writeFileSync8(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
7410
7572
|
}
|
|
7411
7573
|
} catch {
|
|
@@ -7443,7 +7605,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
7443
7605
|
`
|
|
7444
7606
|
);
|
|
7445
7607
|
}
|
|
7446
|
-
} else if (
|
|
7608
|
+
} else if (existsSync17(identityPath)) {
|
|
7447
7609
|
identityFlag = ` --append-system-prompt-file ${identityPath}`;
|
|
7448
7610
|
legacyFallbackWarned = true;
|
|
7449
7611
|
}
|
|
@@ -7465,7 +7627,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
7465
7627
|
let sessionContextFlag = "";
|
|
7466
7628
|
try {
|
|
7467
7629
|
const ctxDir = path18.join(os11.homedir(), ".exe-os", "session-cache");
|
|
7468
|
-
|
|
7630
|
+
mkdirSync8(ctxDir, { recursive: true });
|
|
7469
7631
|
const ctxFile = path18.join(ctxDir, `session-context-${sessionName}.md`);
|
|
7470
7632
|
const ctxContent = [
|
|
7471
7633
|
`## Session Context`,
|
|
@@ -9128,6 +9290,18 @@ var init_platform_procedures = __esm({
|
|
|
9128
9290
|
priority: "p0",
|
|
9129
9291
|
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.'"
|
|
9130
9292
|
},
|
|
9293
|
+
{
|
|
9294
|
+
title: "Review chain \u2014 managers must actively pull completed work, never wait for nudges",
|
|
9295
|
+
domain: "workflow",
|
|
9296
|
+
priority: "p0",
|
|
9297
|
+
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."
|
|
9298
|
+
},
|
|
9299
|
+
{
|
|
9300
|
+
title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
|
|
9301
|
+
domain: "workflow",
|
|
9302
|
+
priority: "p0",
|
|
9303
|
+
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."
|
|
9304
|
+
},
|
|
9131
9305
|
{
|
|
9132
9306
|
title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
|
|
9133
9307
|
domain: "architecture",
|
|
@@ -10952,7 +11126,7 @@ __export(keychain_exports, {
|
|
|
10952
11126
|
setMasterKey: () => setMasterKey
|
|
10953
11127
|
});
|
|
10954
11128
|
import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
|
|
10955
|
-
import { existsSync as
|
|
11129
|
+
import { existsSync as existsSync18, statSync as statSync3 } from "fs";
|
|
10956
11130
|
import { execSync as execSync10 } from "child_process";
|
|
10957
11131
|
import path27 from "path";
|
|
10958
11132
|
import os13 from "os";
|
|
@@ -10987,7 +11161,7 @@ function isRootOnlyTrustedServerKeyFile(keyPath) {
|
|
|
10987
11161
|
if (process.platform !== "linux") return false;
|
|
10988
11162
|
try {
|
|
10989
11163
|
const uid = typeof os13.userInfo().uid === "number" ? os13.userInfo().uid : -1;
|
|
10990
|
-
const st =
|
|
11164
|
+
const st = statSync3(keyPath);
|
|
10991
11165
|
if (!st.isFile() || (st.mode & 63) !== 0) return false;
|
|
10992
11166
|
if (uid === 0) return true;
|
|
10993
11167
|
const exeOsDir = process.env.EXE_OS_DIR;
|
|
@@ -11188,7 +11362,7 @@ async function getMasterKey() {
|
|
|
11188
11362
|
}
|
|
11189
11363
|
}
|
|
11190
11364
|
const keyPath = getKeyPath();
|
|
11191
|
-
if (!
|
|
11365
|
+
if (!existsSync18(keyPath)) {
|
|
11192
11366
|
process.stderr.write(
|
|
11193
11367
|
`[keychain] Key not found at ${keyPath} (HOME=${os13.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
|
|
11194
11368
|
`
|
|
@@ -11296,7 +11470,7 @@ async function getKeyStorageInfo() {
|
|
|
11296
11470
|
}
|
|
11297
11471
|
}
|
|
11298
11472
|
const keyPath = getKeyPath();
|
|
11299
|
-
if (!
|
|
11473
|
+
if (!existsSync18(keyPath)) {
|
|
11300
11474
|
return {
|
|
11301
11475
|
kind: "missing",
|
|
11302
11476
|
secure: false,
|
|
@@ -11392,7 +11566,7 @@ async function deleteMasterKey() {
|
|
|
11392
11566
|
}
|
|
11393
11567
|
}
|
|
11394
11568
|
const keyPath = getKeyPath();
|
|
11395
|
-
if (
|
|
11569
|
+
if (existsSync18(keyPath)) {
|
|
11396
11570
|
await unlink(keyPath);
|
|
11397
11571
|
}
|
|
11398
11572
|
}
|
|
@@ -12038,18 +12212,54 @@ __export(shard_manager_exports, {
|
|
|
12038
12212
|
shardExists: () => shardExists
|
|
12039
12213
|
});
|
|
12040
12214
|
import path28 from "path";
|
|
12041
|
-
import { existsSync as
|
|
12215
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync9, readdirSync as readdirSync4, renameSync as renameSync4, statSync as statSync4 } from "fs";
|
|
12042
12216
|
import { createClient as createClient2 } from "@libsql/client";
|
|
12043
12217
|
function initShardManager(encryptionKey) {
|
|
12044
12218
|
_encryptionKey = encryptionKey;
|
|
12045
|
-
|
|
12046
|
-
|
|
12219
|
+
_keyValidated = false;
|
|
12220
|
+
_keyValidationPromise = null;
|
|
12221
|
+
if (!existsSync19(SHARDS_DIR)) {
|
|
12222
|
+
mkdirSync9(SHARDS_DIR, { recursive: true });
|
|
12223
|
+
}
|
|
12224
|
+
const existingShards = readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db"));
|
|
12225
|
+
if (existingShards.length === 0) {
|
|
12226
|
+
_keyValidated = true;
|
|
12047
12227
|
}
|
|
12048
12228
|
_shardingEnabled = true;
|
|
12049
12229
|
if (_evictionTimer) clearInterval(_evictionTimer);
|
|
12050
12230
|
_evictionTimer = setInterval(evictIdleShards, EVICTION_INTERVAL_MS);
|
|
12051
12231
|
_evictionTimer.unref();
|
|
12052
12232
|
}
|
|
12233
|
+
async function validateEncryptionKey() {
|
|
12234
|
+
if (_keyValidated) return true;
|
|
12235
|
+
if (!_encryptionKey) return false;
|
|
12236
|
+
const existingShards = readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db"));
|
|
12237
|
+
if (existingShards.length === 0) {
|
|
12238
|
+
_keyValidated = true;
|
|
12239
|
+
return true;
|
|
12240
|
+
}
|
|
12241
|
+
for (const shardFile of existingShards.slice(0, 3)) {
|
|
12242
|
+
const dbPath = path28.join(SHARDS_DIR, shardFile);
|
|
12243
|
+
const testClient = createClient2({ url: `file:${dbPath}`, encryptionKey: _encryptionKey });
|
|
12244
|
+
try {
|
|
12245
|
+
await testClient.execute("SELECT COUNT(*) FROM sqlite_schema");
|
|
12246
|
+
testClient.close();
|
|
12247
|
+
_keyValidated = true;
|
|
12248
|
+
return true;
|
|
12249
|
+
} catch {
|
|
12250
|
+
try {
|
|
12251
|
+
testClient.close();
|
|
12252
|
+
} catch {
|
|
12253
|
+
}
|
|
12254
|
+
}
|
|
12255
|
+
}
|
|
12256
|
+
process.stderr.write(
|
|
12257
|
+
`[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.
|
|
12258
|
+
`
|
|
12259
|
+
);
|
|
12260
|
+
_shardingEnabled = false;
|
|
12261
|
+
return false;
|
|
12262
|
+
}
|
|
12053
12263
|
function isShardingEnabled() {
|
|
12054
12264
|
return _shardingEnabled;
|
|
12055
12265
|
}
|
|
@@ -12083,13 +12293,13 @@ function getShardClient(projectName) {
|
|
|
12083
12293
|
}
|
|
12084
12294
|
function shardExists(projectName) {
|
|
12085
12295
|
const safeName = safeShardName(projectName);
|
|
12086
|
-
return
|
|
12296
|
+
return existsSync19(path28.join(SHARDS_DIR, `${safeName}.db`));
|
|
12087
12297
|
}
|
|
12088
12298
|
function safeShardName(projectName) {
|
|
12089
12299
|
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
12090
12300
|
}
|
|
12091
12301
|
function listShards() {
|
|
12092
|
-
if (!
|
|
12302
|
+
if (!existsSync19(SHARDS_DIR)) return [];
|
|
12093
12303
|
return readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
12094
12304
|
}
|
|
12095
12305
|
async function auditShardHealth(options = {}) {
|
|
@@ -12102,7 +12312,7 @@ async function auditShardHealth(options = {}) {
|
|
|
12102
12312
|
const shards = [];
|
|
12103
12313
|
for (const name of names) {
|
|
12104
12314
|
const dbPath = path28.join(SHARDS_DIR, `${name}.db`);
|
|
12105
|
-
const stat =
|
|
12315
|
+
const stat = statSync4(dbPath);
|
|
12106
12316
|
const item = {
|
|
12107
12317
|
name,
|
|
12108
12318
|
path: dbPath,
|
|
@@ -12342,6 +12552,17 @@ async function ensureShardSchema(client) {
|
|
|
12342
12552
|
}
|
|
12343
12553
|
}
|
|
12344
12554
|
async function getReadyShardClient(projectName) {
|
|
12555
|
+
if (!_keyValidated) {
|
|
12556
|
+
if (!_keyValidationPromise) {
|
|
12557
|
+
_keyValidationPromise = validateEncryptionKey();
|
|
12558
|
+
}
|
|
12559
|
+
const valid = await _keyValidationPromise;
|
|
12560
|
+
if (!valid) {
|
|
12561
|
+
throw new Error(
|
|
12562
|
+
`Shard creation blocked: encryption key mismatch with existing shards. Run /exe-doctor to audit.`
|
|
12563
|
+
);
|
|
12564
|
+
}
|
|
12565
|
+
}
|
|
12345
12566
|
const safeName = safeShardName(projectName);
|
|
12346
12567
|
let client = getShardClient(projectName);
|
|
12347
12568
|
try {
|
|
@@ -12354,8 +12575,8 @@ async function getReadyShardClient(projectName) {
|
|
|
12354
12575
|
_shards.delete(safeName);
|
|
12355
12576
|
_shardLastAccess.delete(safeName);
|
|
12356
12577
|
const dbPath = path28.join(SHARDS_DIR, `${safeName}.db`);
|
|
12357
|
-
if (
|
|
12358
|
-
const stat =
|
|
12578
|
+
if (existsSync19(dbPath)) {
|
|
12579
|
+
const stat = statSync4(dbPath);
|
|
12359
12580
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
12360
12581
|
const archivedPath = path28.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
12361
12582
|
renameSync4(dbPath, archivedPath);
|
|
@@ -12420,7 +12641,7 @@ function disposeShards() {
|
|
|
12420
12641
|
_shardingEnabled = false;
|
|
12421
12642
|
_encryptionKey = null;
|
|
12422
12643
|
}
|
|
12423
|
-
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled;
|
|
12644
|
+
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled, _keyValidated, _keyValidationPromise;
|
|
12424
12645
|
var init_shard_manager = __esm({
|
|
12425
12646
|
"src/lib/shard-manager.ts"() {
|
|
12426
12647
|
"use strict";
|
|
@@ -12434,6 +12655,8 @@ var init_shard_manager = __esm({
|
|
|
12434
12655
|
_evictionTimer = null;
|
|
12435
12656
|
_encryptionKey = null;
|
|
12436
12657
|
_shardingEnabled = false;
|
|
12658
|
+
_keyValidated = false;
|
|
12659
|
+
_keyValidationPromise = null;
|
|
12437
12660
|
}
|
|
12438
12661
|
});
|
|
12439
12662
|
|
|
@@ -12881,6 +13104,20 @@ __export(store_exports, {
|
|
|
12881
13104
|
vectorToBlob: () => vectorToBlob,
|
|
12882
13105
|
writeMemory: () => writeMemory
|
|
12883
13106
|
});
|
|
13107
|
+
function logStoreDebug(context, err) {
|
|
13108
|
+
if (_debugStore) {
|
|
13109
|
+
process.stderr.write(
|
|
13110
|
+
`[store] ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
13111
|
+
`
|
|
13112
|
+
);
|
|
13113
|
+
}
|
|
13114
|
+
}
|
|
13115
|
+
function logStoreWarn(context, err) {
|
|
13116
|
+
process.stderr.write(
|
|
13117
|
+
`[store] WARN ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
13118
|
+
`
|
|
13119
|
+
);
|
|
13120
|
+
}
|
|
12884
13121
|
function isBusyError2(err) {
|
|
12885
13122
|
if (err instanceof Error) {
|
|
12886
13123
|
const msg = err.message.toLowerCase();
|
|
@@ -12935,13 +13172,15 @@ async function initStore(options) {
|
|
|
12935
13172
|
try {
|
|
12936
13173
|
const { initDaemonClient: initDaemonClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
12937
13174
|
await initDaemonClient2();
|
|
12938
|
-
} catch {
|
|
13175
|
+
} catch (e) {
|
|
13176
|
+
logStoreWarn("catch", e);
|
|
12939
13177
|
}
|
|
12940
13178
|
if (!options?.lightweight) {
|
|
12941
13179
|
try {
|
|
12942
13180
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
12943
13181
|
initShardManager2(hexKey);
|
|
12944
|
-
} catch {
|
|
13182
|
+
} catch (e) {
|
|
13183
|
+
logStoreWarn("catch", e);
|
|
12945
13184
|
}
|
|
12946
13185
|
const client = getClient();
|
|
12947
13186
|
const vResult = await retryOnBusy2(
|
|
@@ -12952,7 +13191,8 @@ async function initStore(options) {
|
|
|
12952
13191
|
try {
|
|
12953
13192
|
const { loadGlobalProcedures: loadGlobalProcedures2 } = await Promise.resolve().then(() => (init_global_procedures(), global_procedures_exports));
|
|
12954
13193
|
await loadGlobalProcedures2();
|
|
12955
|
-
} catch {
|
|
13194
|
+
} catch (e) {
|
|
13195
|
+
logStoreWarn("catch", e);
|
|
12956
13196
|
}
|
|
12957
13197
|
}
|
|
12958
13198
|
}
|
|
@@ -13012,7 +13252,8 @@ async function writeMemory(record) {
|
|
|
13012
13252
|
memoryType
|
|
13013
13253
|
});
|
|
13014
13254
|
if (existing) return;
|
|
13015
|
-
} catch {
|
|
13255
|
+
} catch (e) {
|
|
13256
|
+
logStoreWarn("catch", e);
|
|
13016
13257
|
}
|
|
13017
13258
|
const dbRow = {
|
|
13018
13259
|
id: record.id,
|
|
@@ -13213,12 +13454,14 @@ async function flushBatch() {
|
|
|
13213
13454
|
try {
|
|
13214
13455
|
const { insertMemoryCardsForBatch: insertMemoryCardsForBatch2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
|
|
13215
13456
|
await insertMemoryCardsForBatch2(batch);
|
|
13216
|
-
} catch {
|
|
13457
|
+
} catch (e) {
|
|
13458
|
+
logStoreWarn("catch", e);
|
|
13217
13459
|
}
|
|
13218
13460
|
try {
|
|
13219
13461
|
const { insertOntologyForBatch: insertOntologyForBatch2 } = await Promise.resolve().then(() => (init_agentic_ontology(), agentic_ontology_exports));
|
|
13220
13462
|
await insertOntologyForBatch2(batch);
|
|
13221
|
-
} catch {
|
|
13463
|
+
} catch (e) {
|
|
13464
|
+
logStoreWarn("catch", e);
|
|
13222
13465
|
}
|
|
13223
13466
|
schedulePostWriteMemoryHygiene(batch.map((row) => row.id));
|
|
13224
13467
|
_pendingRecords.splice(0, batch.length);
|
|
@@ -13257,7 +13500,8 @@ ${err.stack.split("\n").slice(1, 3).join("\n")}` : ""}` : String(err);
|
|
|
13257
13500
|
}
|
|
13258
13501
|
}
|
|
13259
13502
|
}
|
|
13260
|
-
} catch {
|
|
13503
|
+
} catch (e) {
|
|
13504
|
+
logStoreWarn("catch", e);
|
|
13261
13505
|
}
|
|
13262
13506
|
return batch.length;
|
|
13263
13507
|
} finally {
|
|
@@ -13299,7 +13543,8 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
13299
13543
|
} else {
|
|
13300
13544
|
client = getClient();
|
|
13301
13545
|
}
|
|
13302
|
-
} catch {
|
|
13546
|
+
} catch (e) {
|
|
13547
|
+
logStoreDebug("shard routing fallback", e);
|
|
13303
13548
|
client = getClient();
|
|
13304
13549
|
}
|
|
13305
13550
|
const limit = options?.limit ?? 10;
|
|
@@ -13415,7 +13660,8 @@ async function attachDocumentMetadata(records) {
|
|
|
13415
13660
|
if (!record.document_id) continue;
|
|
13416
13661
|
record.document_metadata = byId.get(record.document_id) ?? null;
|
|
13417
13662
|
}
|
|
13418
|
-
} catch {
|
|
13663
|
+
} catch (e) {
|
|
13664
|
+
logStoreWarn("catch", e);
|
|
13419
13665
|
}
|
|
13420
13666
|
return records;
|
|
13421
13667
|
}
|
|
@@ -13476,11 +13722,12 @@ async function getMemoryCardinality(agentId) {
|
|
|
13476
13722
|
args: [agentId]
|
|
13477
13723
|
});
|
|
13478
13724
|
return Number(result.rows[0]?.cnt) || 0;
|
|
13479
|
-
} catch {
|
|
13725
|
+
} catch (e) {
|
|
13726
|
+
logStoreWarn("getMemoryCardinality", e);
|
|
13480
13727
|
return 0;
|
|
13481
13728
|
}
|
|
13482
13729
|
}
|
|
13483
|
-
var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
13730
|
+
var _debugStore, INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
13484
13731
|
var init_store = __esm({
|
|
13485
13732
|
"src/lib/store.ts"() {
|
|
13486
13733
|
"use strict";
|
|
@@ -13490,6 +13737,7 @@ var init_store = __esm({
|
|
|
13490
13737
|
init_config();
|
|
13491
13738
|
init_state_bus();
|
|
13492
13739
|
init_memory_write_governor();
|
|
13740
|
+
_debugStore = process.env.EXE_DEBUG === "1";
|
|
13493
13741
|
INIT_MAX_RETRIES = 3;
|
|
13494
13742
|
INIT_RETRY_DELAY_MS = 1e3;
|
|
13495
13743
|
_pendingRecords = [];
|
|
@@ -19429,11 +19677,11 @@ function Footer() {
|
|
|
19429
19677
|
} catch {
|
|
19430
19678
|
}
|
|
19431
19679
|
try {
|
|
19432
|
-
const { existsSync:
|
|
19433
|
-
const { join } = await import("path");
|
|
19680
|
+
const { existsSync: existsSync20 } = await import("fs");
|
|
19681
|
+
const { join: join2 } = await import("path");
|
|
19434
19682
|
const home = process.env.HOME ?? "";
|
|
19435
|
-
const pidPath =
|
|
19436
|
-
setDaemon(
|
|
19683
|
+
const pidPath = join2(home, ".exe-os", "exed.pid");
|
|
19684
|
+
setDaemon(existsSync20(pidPath) ? "running" : "stopped");
|
|
19437
19685
|
} catch {
|
|
19438
19686
|
setDaemon("unknown");
|
|
19439
19687
|
}
|
|
@@ -19516,7 +19764,7 @@ function Footer() {
|
|
|
19516
19764
|
import { useState as useState6, useEffect as useEffect8, useMemo as useMemo4, useCallback as useCallback4, useRef as useRef4 } from "react";
|
|
19517
19765
|
import TextInput from "ink-text-input";
|
|
19518
19766
|
import path25 from "path";
|
|
19519
|
-
import { homedir } from "os";
|
|
19767
|
+
import { homedir as homedir2 } from "os";
|
|
19520
19768
|
|
|
19521
19769
|
// src/tui/components/StatusDot.tsx
|
|
19522
19770
|
import React16 from "react";
|
|
@@ -20303,13 +20551,13 @@ function CommandCenterView({
|
|
|
20303
20551
|
const { createPermissionsFromPreset: createPermissionsFromPreset2, EMPLOYEE_PERMISSIONS: EMPLOYEE_PERMISSIONS2 } = await Promise.resolve().then(() => (init_permissions(), permissions_exports));
|
|
20304
20552
|
const { getPresetByRole: getPresetByRole2 } = await Promise.resolve().then(() => (init_permission_presets(), permission_presets_exports));
|
|
20305
20553
|
const { createDefaultHooks: createDefaultHooks2 } = await Promise.resolve().then(() => (init_hooks(), hooks_exports));
|
|
20306
|
-
const { readFileSync: readFileSync14, existsSync:
|
|
20307
|
-
const { join } = await import("path");
|
|
20308
|
-
const { homedir:
|
|
20309
|
-
const configPath =
|
|
20554
|
+
const { readFileSync: readFileSync14, existsSync: existsSync20 } = await import("fs");
|
|
20555
|
+
const { join: join2 } = await import("path");
|
|
20556
|
+
const { homedir: homedir4 } = await import("os");
|
|
20557
|
+
const configPath = join2(homedir4(), ".exe-os", "config.json");
|
|
20310
20558
|
let failoverChain = ["anthropic", "opencode", "gemini", "openai"];
|
|
20311
20559
|
let providerConfigs = {};
|
|
20312
|
-
if (
|
|
20560
|
+
if (existsSync20(configPath)) {
|
|
20313
20561
|
try {
|
|
20314
20562
|
const raw = JSON.parse(readFileSync14(configPath, "utf8"));
|
|
20315
20563
|
if (Array.isArray(raw.failoverChain)) failoverChain = raw.failoverChain;
|
|
@@ -20369,10 +20617,10 @@ function CommandCenterView({
|
|
|
20369
20617
|
registry.register(BashTool2);
|
|
20370
20618
|
let agentRole = "CTO";
|
|
20371
20619
|
try {
|
|
20372
|
-
const markerDir =
|
|
20620
|
+
const markerDir = join2(homedir4(), ".exe-os", "session-cache");
|
|
20373
20621
|
const agentFiles = (await import("fs")).readdirSync(markerDir).filter((f) => f.startsWith("active-agent-"));
|
|
20374
20622
|
for (const f of agentFiles) {
|
|
20375
|
-
const data = JSON.parse(readFileSync14(
|
|
20623
|
+
const data = JSON.parse(readFileSync14(join2(markerDir, f), "utf8"));
|
|
20376
20624
|
if (data.agentRole) {
|
|
20377
20625
|
agentRole = data.agentRole;
|
|
20378
20626
|
break;
|
|
@@ -20517,7 +20765,7 @@ function CommandCenterView({
|
|
|
20517
20765
|
const demoEntries = DEMO_PROJECTS.map((p) => ({
|
|
20518
20766
|
projectName: p.projectName,
|
|
20519
20767
|
exeSession: p.exeSession,
|
|
20520
|
-
projectDir: path25.join(
|
|
20768
|
+
projectDir: path25.join(homedir2(), p.projectName),
|
|
20521
20769
|
employeeCount: p.employees.length,
|
|
20522
20770
|
activeCount: p.employees.filter((e) => e.status === "active").length,
|
|
20523
20771
|
memoryCount: p.employees.length * 4e3,
|
|
@@ -20555,8 +20803,8 @@ function CommandCenterView({
|
|
|
20555
20803
|
const { listSessions: listSessions2 } = await Promise.resolve().then(() => (init_session_registry(), session_registry_exports));
|
|
20556
20804
|
const { listTmuxSessions: listTmuxSessions2, inTmux: inTmux2 } = await Promise.resolve().then(() => (init_tmux_status(), tmux_status_exports));
|
|
20557
20805
|
const { loadEmployees: loadEmployees2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
|
|
20558
|
-
const { existsSync:
|
|
20559
|
-
const { join } = await import("path");
|
|
20806
|
+
const { existsSync: existsSync20 } = await import("fs");
|
|
20807
|
+
const { join: join2 } = await import("path");
|
|
20560
20808
|
const client = getClient2();
|
|
20561
20809
|
if (!client) {
|
|
20562
20810
|
setDbError(true);
|
|
@@ -20626,7 +20874,7 @@ function CommandCenterView({
|
|
|
20626
20874
|
}
|
|
20627
20875
|
const memoryCount = memoryCounts.get(name) ?? 0;
|
|
20628
20876
|
const openTaskCount = openTaskCounts.get(name) ?? 0;
|
|
20629
|
-
const hasGit = projectDir ?
|
|
20877
|
+
const hasGit = projectDir ? existsSync20(join2(projectDir, ".git")) : false;
|
|
20630
20878
|
const type = hasGit ? "code" : memoryCount > 0 ? "code" : "automation";
|
|
20631
20879
|
projectList.push({
|
|
20632
20880
|
projectName: name,
|
|
@@ -20650,8 +20898,8 @@ function CommandCenterView({
|
|
|
20650
20898
|
const totalResult = await client.execute("SELECT COUNT(*) as cnt FROM memories");
|
|
20651
20899
|
setHealth((h) => ({ ...h, memories: Number(totalResult.rows[0]?.cnt ?? 0) }));
|
|
20652
20900
|
try {
|
|
20653
|
-
const pidPath =
|
|
20654
|
-
setHealth((h) => ({ ...h, daemon:
|
|
20901
|
+
const pidPath = join2(process.env.HOME ?? "", ".exe-os", "exed.pid");
|
|
20902
|
+
setHealth((h) => ({ ...h, daemon: existsSync20(pidPath) ? "running" : "stopped" }));
|
|
20655
20903
|
} catch {
|
|
20656
20904
|
}
|
|
20657
20905
|
const activityResult = await client.execute(
|
|
@@ -20867,7 +21115,7 @@ function ChatMessageRow({ msg }) {
|
|
|
20867
21115
|
// src/tui/views/Sessions.tsx
|
|
20868
21116
|
import React19, { useState as useState9, useEffect as useEffect11, useCallback as useCallback6 } from "react";
|
|
20869
21117
|
import path26 from "path";
|
|
20870
|
-
import { homedir as
|
|
21118
|
+
import { homedir as homedir3 } from "os";
|
|
20871
21119
|
|
|
20872
21120
|
// src/tui/components/TmuxPane.tsx
|
|
20873
21121
|
import React18, { useState as useState7, useEffect as useEffect9 } from "react";
|
|
@@ -21170,7 +21418,7 @@ function SessionsView({
|
|
|
21170
21418
|
if (demo) {
|
|
21171
21419
|
setProjects(DEMO_PROJECTS.map((p) => ({
|
|
21172
21420
|
...p,
|
|
21173
|
-
projectDir: path26.join(
|
|
21421
|
+
projectDir: path26.join(homedir3(), p.projectName),
|
|
21174
21422
|
employees: p.employees.map((e) => ({ ...e, attached: e.status === "active" }))
|
|
21175
21423
|
})));
|
|
21176
21424
|
return;
|
|
@@ -22051,11 +22299,11 @@ async function loadGatewayConfig() {
|
|
|
22051
22299
|
state.running = false;
|
|
22052
22300
|
}
|
|
22053
22301
|
try {
|
|
22054
|
-
const { existsSync:
|
|
22055
|
-
const { join } = await import("path");
|
|
22302
|
+
const { existsSync: existsSync20, readFileSync: readFileSync14 } = await import("fs");
|
|
22303
|
+
const { join: join2 } = await import("path");
|
|
22056
22304
|
const home = process.env.HOME ?? "";
|
|
22057
|
-
const configPath =
|
|
22058
|
-
if (
|
|
22305
|
+
const configPath = join2(home, ".exe-os", "gateway.json");
|
|
22306
|
+
if (existsSync20(configPath)) {
|
|
22059
22307
|
const raw = JSON.parse(readFileSync14(configPath, "utf8"));
|
|
22060
22308
|
state.port = raw.port ?? 3100;
|
|
22061
22309
|
state.gatewayUrl = raw.gatewayUrl ?? "";
|
|
@@ -22556,11 +22804,11 @@ function TeamView({ onBack, onViewSessions }) {
|
|
|
22556
22804
|
setMembers(teamData);
|
|
22557
22805
|
setDbError(null);
|
|
22558
22806
|
try {
|
|
22559
|
-
const { existsSync:
|
|
22560
|
-
const { join } = await import("path");
|
|
22807
|
+
const { existsSync: existsSync20, readFileSync: readFileSync14 } = await import("fs");
|
|
22808
|
+
const { join: join2 } = await import("path");
|
|
22561
22809
|
const home = process.env.HOME ?? "";
|
|
22562
|
-
const gatewayConfig =
|
|
22563
|
-
if (
|
|
22810
|
+
const gatewayConfig = join2(home, ".exe-os", "gateway.json");
|
|
22811
|
+
if (existsSync20(gatewayConfig)) {
|
|
22564
22812
|
const raw = JSON.parse(readFileSync14(gatewayConfig, "utf8"));
|
|
22565
22813
|
if (raw.agents && raw.agents.length > 0) {
|
|
22566
22814
|
setExternals(raw.agents.map((a) => ({
|
|
@@ -23209,12 +23457,12 @@ function SettingsView({ onBack }) {
|
|
|
23209
23457
|
}
|
|
23210
23458
|
setProviders(providerList);
|
|
23211
23459
|
try {
|
|
23212
|
-
const { existsSync:
|
|
23213
|
-
const { join } = await import("path");
|
|
23460
|
+
const { existsSync: existsSync20 } = await import("fs");
|
|
23461
|
+
const { join: join2 } = await import("path");
|
|
23214
23462
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
23215
23463
|
const cfg = await loadConfig2();
|
|
23216
23464
|
const home = process.env.HOME ?? "";
|
|
23217
|
-
const hasKey =
|
|
23465
|
+
const hasKey = existsSync20(join2(home, ".exe-os", "master.key"));
|
|
23218
23466
|
if (cfg.cloud) {
|
|
23219
23467
|
setCloud({
|
|
23220
23468
|
configured: true,
|
|
@@ -23224,10 +23472,10 @@ function SettingsView({ onBack }) {
|
|
|
23224
23472
|
} else {
|
|
23225
23473
|
setCloud({ configured: false, endpoint: "", apiKey: "" });
|
|
23226
23474
|
}
|
|
23227
|
-
const pidPath =
|
|
23475
|
+
const pidPath = join2(home, ".exe-os", "exed.pid");
|
|
23228
23476
|
let daemon = "unknown";
|
|
23229
23477
|
try {
|
|
23230
|
-
daemon =
|
|
23478
|
+
daemon = existsSync20(pidPath) ? "running" : "stopped";
|
|
23231
23479
|
} catch {
|
|
23232
23480
|
}
|
|
23233
23481
|
let version = "unknown";
|