@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/gateway/index.js
CHANGED
|
@@ -2328,9 +2328,79 @@ __export(database_exports, {
|
|
|
2328
2328
|
isInitialized: () => isInitialized,
|
|
2329
2329
|
setExternalClient: () => setExternalClient
|
|
2330
2330
|
});
|
|
2331
|
-
import { chmodSync as chmodSync2 } from "fs";
|
|
2331
|
+
import { chmodSync as chmodSync2, existsSync as existsSync7, statSync as statSync2, copyFileSync, unlinkSync as unlinkSync3, openSync as openSync2, closeSync as closeSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
2332
2332
|
import { createClient } from "@libsql/client";
|
|
2333
|
+
import { homedir } from "os";
|
|
2334
|
+
import { join } from "path";
|
|
2335
|
+
function logCatchDebug(context, err) {
|
|
2336
|
+
if (_debugDb) {
|
|
2337
|
+
process.stderr.write(
|
|
2338
|
+
`[database] ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
2339
|
+
`
|
|
2340
|
+
);
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
function acquireDbLock() {
|
|
2344
|
+
mkdirSync2(join(homedir(), ".exe-os"), { recursive: true });
|
|
2345
|
+
try {
|
|
2346
|
+
_lockFd = openSync2(DB_LOCK_PATH, "wx");
|
|
2347
|
+
} catch (err) {
|
|
2348
|
+
if (err && typeof err === "object" && "code" in err && err.code === "EEXIST") {
|
|
2349
|
+
try {
|
|
2350
|
+
const lockStat = statSync2(DB_LOCK_PATH);
|
|
2351
|
+
if (Date.now() - lockStat.mtimeMs > 6e4) {
|
|
2352
|
+
unlinkSync3(DB_LOCK_PATH);
|
|
2353
|
+
_lockFd = openSync2(DB_LOCK_PATH, "wx");
|
|
2354
|
+
return;
|
|
2355
|
+
}
|
|
2356
|
+
} catch (e) {
|
|
2357
|
+
logCatchDebug("stale lock check", e);
|
|
2358
|
+
}
|
|
2359
|
+
process.stderr.write(
|
|
2360
|
+
"[database] WARN: Another process holds db.lock \u2014 waiting briefly then proceeding.\n"
|
|
2361
|
+
);
|
|
2362
|
+
return;
|
|
2363
|
+
}
|
|
2364
|
+
throw err;
|
|
2365
|
+
}
|
|
2366
|
+
}
|
|
2367
|
+
function releaseDbLock() {
|
|
2368
|
+
if (_lockFd !== null) {
|
|
2369
|
+
try {
|
|
2370
|
+
closeSync2(_lockFd);
|
|
2371
|
+
} catch (e) {
|
|
2372
|
+
logCatchDebug("lock close", e);
|
|
2373
|
+
}
|
|
2374
|
+
_lockFd = null;
|
|
2375
|
+
}
|
|
2376
|
+
try {
|
|
2377
|
+
unlinkSync3(DB_LOCK_PATH);
|
|
2378
|
+
} catch (e) {
|
|
2379
|
+
logCatchDebug("lock unlink", e);
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2333
2382
|
async function initDatabase(config2) {
|
|
2383
|
+
acquireDbLock();
|
|
2384
|
+
if (existsSync7(config2.dbPath)) {
|
|
2385
|
+
const dbStat = statSync2(config2.dbPath);
|
|
2386
|
+
if (dbStat.size === 0) {
|
|
2387
|
+
const walPath = config2.dbPath + "-wal";
|
|
2388
|
+
if (existsSync7(walPath) && statSync2(walPath).size > 0) {
|
|
2389
|
+
const backupPath = config2.dbPath + ".zeroed-" + Date.now();
|
|
2390
|
+
copyFileSync(config2.dbPath, backupPath);
|
|
2391
|
+
unlinkSync3(config2.dbPath);
|
|
2392
|
+
process.stderr.write(
|
|
2393
|
+
`[database] CRITICAL: DB was 0 bytes. Moved to ${backupPath}, attempting WAL recovery.
|
|
2394
|
+
`
|
|
2395
|
+
);
|
|
2396
|
+
} else {
|
|
2397
|
+
process.stderr.write(
|
|
2398
|
+
`[database] CRITICAL: DB is 0 bytes and no WAL available for recovery. Data may be lost. Check backups at ${config2.dbPath}.bak
|
|
2399
|
+
`
|
|
2400
|
+
);
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
}
|
|
2334
2404
|
if (_walCheckpointTimer) {
|
|
2335
2405
|
clearInterval(_walCheckpointTimer);
|
|
2336
2406
|
_walCheckpointTimer = null;
|
|
@@ -2357,10 +2427,8 @@ async function initDatabase(config2) {
|
|
|
2357
2427
|
_client = createClient(opts);
|
|
2358
2428
|
_resilientClient = wrapWithRetry(_client);
|
|
2359
2429
|
_adapterClient = _resilientClient;
|
|
2360
|
-
_client.execute("PRAGMA busy_timeout = 30000")
|
|
2361
|
-
|
|
2362
|
-
_client.execute("PRAGMA journal_mode = WAL").catch(() => {
|
|
2363
|
-
});
|
|
2430
|
+
await _client.execute("PRAGMA busy_timeout = 30000");
|
|
2431
|
+
await _client.execute("PRAGMA journal_mode = WAL");
|
|
2364
2432
|
if (_walCheckpointTimer) clearInterval(_walCheckpointTimer);
|
|
2365
2433
|
_walCheckpointTimer = setInterval(() => {
|
|
2366
2434
|
_client?.execute("PRAGMA wal_checkpoint(PASSIVE)").catch(() => {
|
|
@@ -2375,11 +2443,16 @@ async function initDatabase(config2) {
|
|
|
2375
2443
|
for (const suffix of ["-wal", "-shm"]) {
|
|
2376
2444
|
try {
|
|
2377
2445
|
chmodSync2(config2.dbPath + suffix, 384);
|
|
2378
|
-
} catch {
|
|
2446
|
+
} catch (chmodErr) {
|
|
2447
|
+
process.stderr.write(`[database] chmod ${suffix} failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
|
|
2448
|
+
`);
|
|
2379
2449
|
}
|
|
2380
2450
|
}
|
|
2381
|
-
} catch {
|
|
2451
|
+
} catch (chmodErr) {
|
|
2452
|
+
process.stderr.write(`[database] chmod db failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
|
|
2453
|
+
`);
|
|
2382
2454
|
}
|
|
2455
|
+
releaseDbLock();
|
|
2383
2456
|
}
|
|
2384
2457
|
function isInitialized() {
|
|
2385
2458
|
return _adapterClient !== null || _client !== null;
|
|
@@ -2434,7 +2507,8 @@ async function ensureSchema() {
|
|
|
2434
2507
|
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
2435
2508
|
try {
|
|
2436
2509
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
2437
|
-
} catch {
|
|
2510
|
+
} catch (e) {
|
|
2511
|
+
logCatchDebug("migration", e);
|
|
2438
2512
|
}
|
|
2439
2513
|
await client.executeMultiple(`
|
|
2440
2514
|
CREATE TABLE IF NOT EXISTS memories (
|
|
@@ -2499,6 +2573,23 @@ async function ensureSchema() {
|
|
|
2499
2573
|
INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
|
|
2500
2574
|
END;
|
|
2501
2575
|
`);
|
|
2576
|
+
try {
|
|
2577
|
+
await client.execute("SELECT COUNT(*) FROM memories_fts LIMIT 1");
|
|
2578
|
+
} catch (ftsErr) {
|
|
2579
|
+
process.stderr.write(
|
|
2580
|
+
`[database] WARN: memories_fts corrupted (${ftsErr instanceof Error ? ftsErr.message : String(ftsErr)}) \u2014 rebuilding FTS index.
|
|
2581
|
+
`
|
|
2582
|
+
);
|
|
2583
|
+
try {
|
|
2584
|
+
await client.execute("INSERT INTO memories_fts(memories_fts) VALUES('rebuild')");
|
|
2585
|
+
process.stderr.write("[database] FTS index rebuilt successfully.\n");
|
|
2586
|
+
} catch (rebuildErr) {
|
|
2587
|
+
process.stderr.write(
|
|
2588
|
+
`[database] ERROR: FTS rebuild failed: ${rebuildErr instanceof Error ? rebuildErr.message : String(rebuildErr)}
|
|
2589
|
+
`
|
|
2590
|
+
);
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2502
2593
|
await client.executeMultiple(`
|
|
2503
2594
|
CREATE TABLE IF NOT EXISTS sync_meta (
|
|
2504
2595
|
key TEXT PRIMARY KEY,
|
|
@@ -2557,35 +2648,40 @@ async function ensureSchema() {
|
|
|
2557
2648
|
});
|
|
2558
2649
|
}
|
|
2559
2650
|
}
|
|
2560
|
-
} catch {
|
|
2651
|
+
} catch (seedErr) {
|
|
2652
|
+
logCatchDebug("behavior seed", seedErr);
|
|
2561
2653
|
}
|
|
2562
2654
|
try {
|
|
2563
2655
|
await client.execute({
|
|
2564
2656
|
sql: `ALTER TABLE behaviors ADD COLUMN priority TEXT DEFAULT 'p1'`,
|
|
2565
2657
|
args: []
|
|
2566
2658
|
});
|
|
2567
|
-
} catch {
|
|
2659
|
+
} catch (e) {
|
|
2660
|
+
logCatchDebug("migration", e);
|
|
2568
2661
|
}
|
|
2569
2662
|
try {
|
|
2570
2663
|
await client.execute({
|
|
2571
2664
|
sql: `ALTER TABLE behaviors ADD COLUMN vector F32_BLOB(${EMBEDDING_DIM})`,
|
|
2572
2665
|
args: []
|
|
2573
2666
|
});
|
|
2574
|
-
} catch {
|
|
2667
|
+
} catch (e) {
|
|
2668
|
+
logCatchDebug("migration", e);
|
|
2575
2669
|
}
|
|
2576
2670
|
try {
|
|
2577
2671
|
await client.execute({
|
|
2578
2672
|
sql: `ALTER TABLE tasks ADD COLUMN blocked_by TEXT`,
|
|
2579
2673
|
args: []
|
|
2580
2674
|
});
|
|
2581
|
-
} catch {
|
|
2675
|
+
} catch (e) {
|
|
2676
|
+
logCatchDebug("migration", e);
|
|
2582
2677
|
}
|
|
2583
2678
|
try {
|
|
2584
2679
|
await client.execute({
|
|
2585
2680
|
sql: `ALTER TABLE tasks ADD COLUMN parent_task_id TEXT`,
|
|
2586
2681
|
args: []
|
|
2587
2682
|
});
|
|
2588
|
-
} catch {
|
|
2683
|
+
} catch (e) {
|
|
2684
|
+
logCatchDebug("migration", e);
|
|
2589
2685
|
}
|
|
2590
2686
|
try {
|
|
2591
2687
|
await client.execute({
|
|
@@ -2594,98 +2690,112 @@ async function ensureSchema() {
|
|
|
2594
2690
|
WHERE parent_task_id IS NOT NULL`,
|
|
2595
2691
|
args: []
|
|
2596
2692
|
});
|
|
2597
|
-
} catch {
|
|
2693
|
+
} catch (e) {
|
|
2694
|
+
logCatchDebug("migration", e);
|
|
2598
2695
|
}
|
|
2599
2696
|
try {
|
|
2600
2697
|
await client.execute({
|
|
2601
2698
|
sql: `UPDATE tasks SET status = 'done' WHERE status = 'completed'`,
|
|
2602
2699
|
args: []
|
|
2603
2700
|
});
|
|
2604
|
-
} catch {
|
|
2701
|
+
} catch (e) {
|
|
2702
|
+
logCatchDebug("migration", e);
|
|
2605
2703
|
}
|
|
2606
2704
|
try {
|
|
2607
2705
|
await client.execute({
|
|
2608
2706
|
sql: `ALTER TABLE tasks ADD COLUMN reviewer TEXT`,
|
|
2609
2707
|
args: []
|
|
2610
2708
|
});
|
|
2611
|
-
} catch {
|
|
2709
|
+
} catch (e) {
|
|
2710
|
+
logCatchDebug("migration", e);
|
|
2612
2711
|
}
|
|
2613
2712
|
try {
|
|
2614
2713
|
await client.execute({
|
|
2615
2714
|
sql: `ALTER TABLE tasks ADD COLUMN context TEXT`,
|
|
2616
2715
|
args: []
|
|
2617
2716
|
});
|
|
2618
|
-
} catch {
|
|
2717
|
+
} catch (e) {
|
|
2718
|
+
logCatchDebug("migration", e);
|
|
2619
2719
|
}
|
|
2620
2720
|
try {
|
|
2621
2721
|
await client.execute({
|
|
2622
2722
|
sql: `ALTER TABLE tasks ADD COLUMN result TEXT`,
|
|
2623
2723
|
args: []
|
|
2624
2724
|
});
|
|
2625
|
-
} catch {
|
|
2725
|
+
} catch (e) {
|
|
2726
|
+
logCatchDebug("migration", e);
|
|
2626
2727
|
}
|
|
2627
2728
|
try {
|
|
2628
2729
|
await client.execute({
|
|
2629
2730
|
sql: `ALTER TABLE tasks ADD COLUMN assigned_tmux TEXT`,
|
|
2630
2731
|
args: []
|
|
2631
2732
|
});
|
|
2632
|
-
} catch {
|
|
2733
|
+
} catch (e) {
|
|
2734
|
+
logCatchDebug("migration", e);
|
|
2633
2735
|
}
|
|
2634
2736
|
try {
|
|
2635
2737
|
await client.execute({
|
|
2636
2738
|
sql: `ALTER TABLE tasks ADD COLUMN checkpoint TEXT`,
|
|
2637
2739
|
args: []
|
|
2638
2740
|
});
|
|
2639
|
-
} catch {
|
|
2741
|
+
} catch (e) {
|
|
2742
|
+
logCatchDebug("migration", e);
|
|
2640
2743
|
}
|
|
2641
2744
|
try {
|
|
2642
2745
|
await client.execute({
|
|
2643
2746
|
sql: `ALTER TABLE tasks ADD COLUMN checkpoint_count INTEGER NOT NULL DEFAULT 0`,
|
|
2644
2747
|
args: []
|
|
2645
2748
|
});
|
|
2646
|
-
} catch {
|
|
2749
|
+
} catch (e) {
|
|
2750
|
+
logCatchDebug("migration", e);
|
|
2647
2751
|
}
|
|
2648
2752
|
try {
|
|
2649
2753
|
await client.execute({
|
|
2650
2754
|
sql: `ALTER TABLE tasks ADD COLUMN complexity TEXT NOT NULL DEFAULT 'standard'`,
|
|
2651
2755
|
args: []
|
|
2652
2756
|
});
|
|
2653
|
-
} catch {
|
|
2757
|
+
} catch (e) {
|
|
2758
|
+
logCatchDebug("migration", e);
|
|
2654
2759
|
}
|
|
2655
2760
|
try {
|
|
2656
2761
|
await client.execute({
|
|
2657
2762
|
sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
|
|
2658
2763
|
args: []
|
|
2659
2764
|
});
|
|
2660
|
-
} catch {
|
|
2765
|
+
} catch (e) {
|
|
2766
|
+
logCatchDebug("migration", e);
|
|
2661
2767
|
}
|
|
2662
2768
|
try {
|
|
2663
2769
|
await client.execute({
|
|
2664
2770
|
sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
|
|
2665
2771
|
args: []
|
|
2666
2772
|
});
|
|
2667
|
-
} catch {
|
|
2773
|
+
} catch (e) {
|
|
2774
|
+
logCatchDebug("migration", e);
|
|
2668
2775
|
}
|
|
2669
2776
|
try {
|
|
2670
2777
|
await client.execute({
|
|
2671
2778
|
sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
|
|
2672
2779
|
args: []
|
|
2673
2780
|
});
|
|
2674
|
-
} catch {
|
|
2781
|
+
} catch (e) {
|
|
2782
|
+
logCatchDebug("migration", e);
|
|
2675
2783
|
}
|
|
2676
2784
|
try {
|
|
2677
2785
|
await client.execute({
|
|
2678
2786
|
sql: `ALTER TABLE memories ADD COLUMN author_device_id TEXT`,
|
|
2679
2787
|
args: []
|
|
2680
2788
|
});
|
|
2681
|
-
} catch {
|
|
2789
|
+
} catch (e) {
|
|
2790
|
+
logCatchDebug("migration", e);
|
|
2682
2791
|
}
|
|
2683
2792
|
try {
|
|
2684
2793
|
await client.execute({
|
|
2685
2794
|
sql: `ALTER TABLE memories ADD COLUMN scope TEXT NOT NULL DEFAULT 'business'`,
|
|
2686
2795
|
args: []
|
|
2687
2796
|
});
|
|
2688
|
-
} catch {
|
|
2797
|
+
} catch (e) {
|
|
2798
|
+
logCatchDebug("migration", e);
|
|
2689
2799
|
}
|
|
2690
2800
|
await client.executeMultiple(`
|
|
2691
2801
|
CREATE TABLE IF NOT EXISTS consolidations (
|
|
@@ -2790,14 +2900,16 @@ async function ensureSchema() {
|
|
|
2790
2900
|
sql: `ALTER TABLE notifications ADD COLUMN session_scope TEXT`,
|
|
2791
2901
|
args: []
|
|
2792
2902
|
});
|
|
2793
|
-
} catch {
|
|
2903
|
+
} catch (e) {
|
|
2904
|
+
logCatchDebug("migration", e);
|
|
2794
2905
|
}
|
|
2795
2906
|
try {
|
|
2796
2907
|
await client.execute({
|
|
2797
2908
|
sql: `ALTER TABLE messages ADD COLUMN session_scope TEXT`,
|
|
2798
2909
|
args: []
|
|
2799
2910
|
});
|
|
2800
|
-
} catch {
|
|
2911
|
+
} catch (e) {
|
|
2912
|
+
logCatchDebug("migration", e);
|
|
2801
2913
|
}
|
|
2802
2914
|
await client.executeMultiple(`
|
|
2803
2915
|
CREATE INDEX IF NOT EXISTS idx_notifications_agent_scope_read
|
|
@@ -2823,7 +2935,8 @@ async function ensureSchema() {
|
|
|
2823
2935
|
sql: `UPDATE tasks SET project_name = 'exe-os' WHERE project_name = 'worker'`,
|
|
2824
2936
|
args: []
|
|
2825
2937
|
});
|
|
2826
|
-
} catch {
|
|
2938
|
+
} catch (e) {
|
|
2939
|
+
logCatchDebug("migration", e);
|
|
2827
2940
|
}
|
|
2828
2941
|
await client.executeMultiple(`
|
|
2829
2942
|
CREATE TABLE IF NOT EXISTS trajectories (
|
|
@@ -2847,7 +2960,8 @@ async function ensureSchema() {
|
|
|
2847
2960
|
`);
|
|
2848
2961
|
try {
|
|
2849
2962
|
await client.execute("ALTER TABLE trajectories ADD COLUMN skill_id TEXT");
|
|
2850
|
-
} catch {
|
|
2963
|
+
} catch (e) {
|
|
2964
|
+
logCatchDebug("migration", e);
|
|
2851
2965
|
}
|
|
2852
2966
|
await client.executeMultiple(`
|
|
2853
2967
|
CREATE TABLE IF NOT EXISTS consolidations (
|
|
@@ -2884,63 +2998,72 @@ async function ensureSchema() {
|
|
|
2884
2998
|
sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
|
|
2885
2999
|
args: []
|
|
2886
3000
|
});
|
|
2887
|
-
} catch {
|
|
3001
|
+
} catch (e) {
|
|
3002
|
+
logCatchDebug("migration", e);
|
|
2888
3003
|
}
|
|
2889
3004
|
try {
|
|
2890
3005
|
await client.execute({
|
|
2891
3006
|
sql: `ALTER TABLE memories ADD COLUMN importance INTEGER DEFAULT 5`,
|
|
2892
3007
|
args: []
|
|
2893
3008
|
});
|
|
2894
|
-
} catch {
|
|
3009
|
+
} catch (e) {
|
|
3010
|
+
logCatchDebug("migration", e);
|
|
2895
3011
|
}
|
|
2896
3012
|
try {
|
|
2897
3013
|
await client.execute({
|
|
2898
3014
|
sql: `ALTER TABLE memories ADD COLUMN status TEXT DEFAULT 'active'`,
|
|
2899
3015
|
args: []
|
|
2900
3016
|
});
|
|
2901
|
-
} catch {
|
|
3017
|
+
} catch (e) {
|
|
3018
|
+
logCatchDebug("migration", e);
|
|
2902
3019
|
}
|
|
2903
3020
|
try {
|
|
2904
3021
|
await client.execute({
|
|
2905
3022
|
sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
|
|
2906
3023
|
args: []
|
|
2907
3024
|
});
|
|
2908
|
-
} catch {
|
|
3025
|
+
} catch (e) {
|
|
3026
|
+
logCatchDebug("migration", e);
|
|
2909
3027
|
}
|
|
2910
3028
|
try {
|
|
2911
3029
|
await client.execute({
|
|
2912
3030
|
sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
|
|
2913
3031
|
args: []
|
|
2914
3032
|
});
|
|
2915
|
-
} catch {
|
|
3033
|
+
} catch (e) {
|
|
3034
|
+
logCatchDebug("migration", e);
|
|
2916
3035
|
}
|
|
2917
3036
|
try {
|
|
2918
3037
|
await client.execute({
|
|
2919
3038
|
sql: `ALTER TABLE memories ADD COLUMN last_accessed TEXT`,
|
|
2920
3039
|
args: []
|
|
2921
3040
|
});
|
|
2922
|
-
} catch {
|
|
3041
|
+
} catch (e) {
|
|
3042
|
+
logCatchDebug("migration", e);
|
|
2923
3043
|
}
|
|
2924
3044
|
try {
|
|
2925
3045
|
await client.execute({
|
|
2926
3046
|
sql: `UPDATE memories SET last_accessed = timestamp WHERE last_accessed IS NULL`,
|
|
2927
3047
|
args: []
|
|
2928
3048
|
});
|
|
2929
|
-
} catch {
|
|
3049
|
+
} catch (e) {
|
|
3050
|
+
logCatchDebug("migration", e);
|
|
2930
3051
|
}
|
|
2931
3052
|
try {
|
|
2932
3053
|
await client.execute({
|
|
2933
3054
|
sql: `ALTER TABLE memories ADD COLUMN wiki_synced INTEGER DEFAULT 0`,
|
|
2934
3055
|
args: []
|
|
2935
3056
|
});
|
|
2936
|
-
} catch {
|
|
3057
|
+
} catch (e) {
|
|
3058
|
+
logCatchDebug("migration", e);
|
|
2937
3059
|
}
|
|
2938
3060
|
try {
|
|
2939
3061
|
await client.execute({
|
|
2940
3062
|
sql: `ALTER TABLE memories ADD COLUMN graph_extracted INTEGER DEFAULT 0`,
|
|
2941
3063
|
args: []
|
|
2942
3064
|
});
|
|
2943
|
-
} catch {
|
|
3065
|
+
} catch (e) {
|
|
3066
|
+
logCatchDebug("migration", e);
|
|
2944
3067
|
}
|
|
2945
3068
|
for (const col of [
|
|
2946
3069
|
"ALTER TABLE memories ADD COLUMN content_hash TEXT",
|
|
@@ -2948,14 +3071,16 @@ async function ensureSchema() {
|
|
|
2948
3071
|
]) {
|
|
2949
3072
|
try {
|
|
2950
3073
|
await client.execute(col);
|
|
2951
|
-
} catch {
|
|
3074
|
+
} catch (e) {
|
|
3075
|
+
logCatchDebug("migration", e);
|
|
2952
3076
|
}
|
|
2953
3077
|
}
|
|
2954
3078
|
try {
|
|
2955
3079
|
await client.execute(
|
|
2956
3080
|
`CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash, agent_id)`
|
|
2957
3081
|
);
|
|
2958
|
-
} catch {
|
|
3082
|
+
} catch (e) {
|
|
3083
|
+
logCatchDebug("migration", e);
|
|
2959
3084
|
}
|
|
2960
3085
|
try {
|
|
2961
3086
|
await client.execute(
|
|
@@ -2963,7 +3088,8 @@ async function ensureSchema() {
|
|
|
2963
3088
|
ON memories(content_hash, agent_id, project_name, memory_type)
|
|
2964
3089
|
WHERE content_hash IS NOT NULL`
|
|
2965
3090
|
);
|
|
2966
|
-
} catch {
|
|
3091
|
+
} catch (e) {
|
|
3092
|
+
logCatchDebug("migration", e);
|
|
2967
3093
|
}
|
|
2968
3094
|
await client.executeMultiple(`
|
|
2969
3095
|
CREATE TABLE IF NOT EXISTS entities (
|
|
@@ -3039,7 +3165,8 @@ async function ensureSchema() {
|
|
|
3039
3165
|
`);
|
|
3040
3166
|
try {
|
|
3041
3167
|
await client.execute("INSERT INTO entities_fts(entities_fts) VALUES('rebuild')");
|
|
3042
|
-
} catch {
|
|
3168
|
+
} catch (e) {
|
|
3169
|
+
logCatchDebug("migration", e);
|
|
3043
3170
|
}
|
|
3044
3171
|
await client.executeMultiple(`
|
|
3045
3172
|
CREATE TABLE IF NOT EXISTS entity_aliases (
|
|
@@ -3054,14 +3181,16 @@ async function ensureSchema() {
|
|
|
3054
3181
|
]) {
|
|
3055
3182
|
try {
|
|
3056
3183
|
await client.execute(col);
|
|
3057
|
-
} catch {
|
|
3184
|
+
} catch (e) {
|
|
3185
|
+
logCatchDebug("migration", e);
|
|
3058
3186
|
}
|
|
3059
3187
|
}
|
|
3060
3188
|
try {
|
|
3061
3189
|
await client.execute(
|
|
3062
3190
|
`CREATE INDEX IF NOT EXISTS idx_memories_status ON memories(status)`
|
|
3063
3191
|
);
|
|
3064
|
-
} catch {
|
|
3192
|
+
} catch (e) {
|
|
3193
|
+
logCatchDebug("migration", e);
|
|
3065
3194
|
}
|
|
3066
3195
|
await client.executeMultiple(`
|
|
3067
3196
|
CREATE TABLE IF NOT EXISTS identity (
|
|
@@ -3160,7 +3289,8 @@ async function ensureSchema() {
|
|
|
3160
3289
|
sql: `ALTER TABLE memories ADD COLUMN ${column}`,
|
|
3161
3290
|
args: []
|
|
3162
3291
|
});
|
|
3163
|
-
} catch {
|
|
3292
|
+
} catch (e) {
|
|
3293
|
+
logCatchDebug("migration", e);
|
|
3164
3294
|
}
|
|
3165
3295
|
}
|
|
3166
3296
|
for (const col of [
|
|
@@ -3169,7 +3299,8 @@ async function ensureSchema() {
|
|
|
3169
3299
|
]) {
|
|
3170
3300
|
try {
|
|
3171
3301
|
await client.execute(col);
|
|
3172
|
-
} catch {
|
|
3302
|
+
} catch (e) {
|
|
3303
|
+
logCatchDebug("migration", e);
|
|
3173
3304
|
}
|
|
3174
3305
|
}
|
|
3175
3306
|
await client.executeMultiple(`
|
|
@@ -3354,56 +3485,64 @@ async function ensureSchema() {
|
|
|
3354
3485
|
args: []
|
|
3355
3486
|
});
|
|
3356
3487
|
}
|
|
3357
|
-
} catch {
|
|
3488
|
+
} catch (e) {
|
|
3489
|
+
logCatchDebug("session_agent_map backfill", e);
|
|
3358
3490
|
}
|
|
3359
3491
|
try {
|
|
3360
3492
|
await client.execute({
|
|
3361
3493
|
sql: `ALTER TABLE session_agent_map ADD COLUMN cache_cold_count INTEGER NOT NULL DEFAULT 0`,
|
|
3362
3494
|
args: []
|
|
3363
3495
|
});
|
|
3364
|
-
} catch {
|
|
3496
|
+
} catch (e) {
|
|
3497
|
+
logCatchDebug("migration", e);
|
|
3365
3498
|
}
|
|
3366
3499
|
try {
|
|
3367
3500
|
await client.execute({
|
|
3368
3501
|
sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
|
|
3369
3502
|
args: []
|
|
3370
3503
|
});
|
|
3371
|
-
} catch {
|
|
3504
|
+
} catch (e) {
|
|
3505
|
+
logCatchDebug("migration", e);
|
|
3372
3506
|
}
|
|
3373
3507
|
try {
|
|
3374
3508
|
await client.execute({
|
|
3375
3509
|
sql: `ALTER TABLE tasks ADD COLUMN budget_fallback_model TEXT`,
|
|
3376
3510
|
args: []
|
|
3377
3511
|
});
|
|
3378
|
-
} catch {
|
|
3512
|
+
} catch (e) {
|
|
3513
|
+
logCatchDebug("migration", e);
|
|
3379
3514
|
}
|
|
3380
3515
|
try {
|
|
3381
3516
|
await client.execute({
|
|
3382
3517
|
sql: `ALTER TABLE tasks ADD COLUMN tokens_used INTEGER DEFAULT 0`,
|
|
3383
3518
|
args: []
|
|
3384
3519
|
});
|
|
3385
|
-
} catch {
|
|
3520
|
+
} catch (e) {
|
|
3521
|
+
logCatchDebug("migration", e);
|
|
3386
3522
|
}
|
|
3387
3523
|
try {
|
|
3388
3524
|
await client.execute({
|
|
3389
3525
|
sql: `ALTER TABLE tasks ADD COLUMN tokens_warned_at INTEGER`,
|
|
3390
3526
|
args: []
|
|
3391
3527
|
});
|
|
3392
|
-
} catch {
|
|
3528
|
+
} catch (e) {
|
|
3529
|
+
logCatchDebug("migration", e);
|
|
3393
3530
|
}
|
|
3394
3531
|
try {
|
|
3395
3532
|
await client.execute({
|
|
3396
3533
|
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
3397
3534
|
args: []
|
|
3398
3535
|
});
|
|
3399
|
-
} catch {
|
|
3536
|
+
} catch (e) {
|
|
3537
|
+
logCatchDebug("migration", e);
|
|
3400
3538
|
}
|
|
3401
3539
|
try {
|
|
3402
3540
|
await client.execute({
|
|
3403
3541
|
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
3404
3542
|
args: []
|
|
3405
3543
|
});
|
|
3406
|
-
} catch {
|
|
3544
|
+
} catch (e) {
|
|
3545
|
+
logCatchDebug("migration", e);
|
|
3407
3546
|
}
|
|
3408
3547
|
await client.executeMultiple(`
|
|
3409
3548
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
@@ -3602,13 +3741,15 @@ async function ensureSchema() {
|
|
|
3602
3741
|
sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
|
|
3603
3742
|
args: []
|
|
3604
3743
|
});
|
|
3605
|
-
} catch {
|
|
3744
|
+
} catch (e) {
|
|
3745
|
+
logCatchDebug("migration", e);
|
|
3606
3746
|
}
|
|
3607
3747
|
try {
|
|
3608
3748
|
await client.execute(
|
|
3609
3749
|
`CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)`
|
|
3610
3750
|
);
|
|
3611
|
-
} catch {
|
|
3751
|
+
} catch (e) {
|
|
3752
|
+
logCatchDebug("migration", e);
|
|
3612
3753
|
}
|
|
3613
3754
|
try {
|
|
3614
3755
|
await client.execute({
|
|
@@ -3619,20 +3760,23 @@ async function ensureSchema() {
|
|
|
3619
3760
|
sql: `UPDATE memories SET tier = 2 WHERE tool_name IN ('store_memory', 'manual') AND importance >= 5 AND tier = 3`,
|
|
3620
3761
|
args: []
|
|
3621
3762
|
});
|
|
3622
|
-
} catch {
|
|
3763
|
+
} catch (e) {
|
|
3764
|
+
logCatchDebug("migration", e);
|
|
3623
3765
|
}
|
|
3624
3766
|
try {
|
|
3625
3767
|
await client.execute({
|
|
3626
3768
|
sql: `ALTER TABLE memories ADD COLUMN supersedes_id TEXT`,
|
|
3627
3769
|
args: []
|
|
3628
3770
|
});
|
|
3629
|
-
} catch {
|
|
3771
|
+
} catch (e) {
|
|
3772
|
+
logCatchDebug("migration", e);
|
|
3630
3773
|
}
|
|
3631
3774
|
try {
|
|
3632
3775
|
await client.execute(
|
|
3633
3776
|
`CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL`
|
|
3634
3777
|
);
|
|
3635
|
-
} catch {
|
|
3778
|
+
} catch (e) {
|
|
3779
|
+
logCatchDebug("migration", e);
|
|
3636
3780
|
}
|
|
3637
3781
|
for (const col of [
|
|
3638
3782
|
"ALTER TABLE tasks ADD COLUMN checkpoint TEXT",
|
|
@@ -3640,7 +3784,8 @@ async function ensureSchema() {
|
|
|
3640
3784
|
]) {
|
|
3641
3785
|
try {
|
|
3642
3786
|
await client.execute(col);
|
|
3643
|
-
} catch {
|
|
3787
|
+
} catch (e) {
|
|
3788
|
+
logCatchDebug("migration", e);
|
|
3644
3789
|
}
|
|
3645
3790
|
}
|
|
3646
3791
|
try {
|
|
@@ -3648,13 +3793,15 @@ async function ensureSchema() {
|
|
|
3648
3793
|
sql: `ALTER TABLE memories ADD COLUMN draft INTEGER DEFAULT 0`,
|
|
3649
3794
|
args: []
|
|
3650
3795
|
});
|
|
3651
|
-
} catch {
|
|
3796
|
+
} catch (e) {
|
|
3797
|
+
logCatchDebug("migration", e);
|
|
3652
3798
|
}
|
|
3653
3799
|
try {
|
|
3654
3800
|
await client.execute(
|
|
3655
3801
|
`CREATE INDEX IF NOT EXISTS idx_memories_draft ON memories(draft) WHERE draft = 1`
|
|
3656
3802
|
);
|
|
3657
|
-
} catch {
|
|
3803
|
+
} catch (e) {
|
|
3804
|
+
logCatchDebug("migration", e);
|
|
3658
3805
|
}
|
|
3659
3806
|
for (const col of [
|
|
3660
3807
|
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
@@ -3662,7 +3809,8 @@ async function ensureSchema() {
|
|
|
3662
3809
|
]) {
|
|
3663
3810
|
try {
|
|
3664
3811
|
await client.execute(col);
|
|
3665
|
-
} catch {
|
|
3812
|
+
} catch (e) {
|
|
3813
|
+
logCatchDebug("migration", e);
|
|
3666
3814
|
}
|
|
3667
3815
|
}
|
|
3668
3816
|
try {
|
|
@@ -3670,27 +3818,31 @@ async function ensureSchema() {
|
|
|
3670
3818
|
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3671
3819
|
args: []
|
|
3672
3820
|
});
|
|
3673
|
-
} catch {
|
|
3821
|
+
} catch (e) {
|
|
3822
|
+
logCatchDebug("migration", e);
|
|
3674
3823
|
}
|
|
3675
3824
|
try {
|
|
3676
3825
|
await client.execute({
|
|
3677
3826
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
3678
3827
|
args: []
|
|
3679
3828
|
});
|
|
3680
|
-
} catch {
|
|
3829
|
+
} catch (e) {
|
|
3830
|
+
logCatchDebug("migration", e);
|
|
3681
3831
|
}
|
|
3682
3832
|
try {
|
|
3683
3833
|
await client.execute(
|
|
3684
3834
|
`CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(memory_type)`
|
|
3685
3835
|
);
|
|
3686
|
-
} catch {
|
|
3836
|
+
} catch (e) {
|
|
3837
|
+
logCatchDebug("migration", e);
|
|
3687
3838
|
}
|
|
3688
3839
|
try {
|
|
3689
3840
|
await client.execute({
|
|
3690
3841
|
sql: `ALTER TABLE memories ADD COLUMN trajectory TEXT`,
|
|
3691
3842
|
args: []
|
|
3692
3843
|
});
|
|
3693
|
-
} catch {
|
|
3844
|
+
} catch (e) {
|
|
3845
|
+
logCatchDebug("migration", e);
|
|
3694
3846
|
}
|
|
3695
3847
|
for (const col of [
|
|
3696
3848
|
"ALTER TABLE memories ADD COLUMN intent TEXT",
|
|
@@ -3711,7 +3863,8 @@ async function ensureSchema() {
|
|
|
3711
3863
|
]) {
|
|
3712
3864
|
try {
|
|
3713
3865
|
await client.execute(col);
|
|
3714
|
-
} catch {
|
|
3866
|
+
} catch (e) {
|
|
3867
|
+
logCatchDebug("migration", e);
|
|
3715
3868
|
}
|
|
3716
3869
|
}
|
|
3717
3870
|
try {
|
|
@@ -3719,14 +3872,16 @@ async function ensureSchema() {
|
|
|
3719
3872
|
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3720
3873
|
args: []
|
|
3721
3874
|
});
|
|
3722
|
-
} catch {
|
|
3875
|
+
} catch (e) {
|
|
3876
|
+
logCatchDebug("migration", e);
|
|
3723
3877
|
}
|
|
3724
3878
|
try {
|
|
3725
3879
|
await client.execute({
|
|
3726
3880
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
3727
3881
|
args: []
|
|
3728
3882
|
});
|
|
3729
|
-
} catch {
|
|
3883
|
+
} catch (e) {
|
|
3884
|
+
logCatchDebug("migration", e);
|
|
3730
3885
|
}
|
|
3731
3886
|
}
|
|
3732
3887
|
async function disposeDatabase() {
|
|
@@ -3737,7 +3892,8 @@ async function disposeDatabase() {
|
|
|
3737
3892
|
if (_client) {
|
|
3738
3893
|
try {
|
|
3739
3894
|
await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3740
|
-
} catch {
|
|
3895
|
+
} catch (e) {
|
|
3896
|
+
logCatchDebug("WAL checkpoint", e);
|
|
3741
3897
|
}
|
|
3742
3898
|
}
|
|
3743
3899
|
if (_daemonClient) {
|
|
@@ -3753,8 +3909,9 @@ async function disposeDatabase() {
|
|
|
3753
3909
|
_client = null;
|
|
3754
3910
|
_resilientClient = null;
|
|
3755
3911
|
}
|
|
3912
|
+
releaseDbLock();
|
|
3756
3913
|
}
|
|
3757
|
-
var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
|
|
3914
|
+
var _debugDb, _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, _lockFd, DB_LOCK_PATH, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
|
|
3758
3915
|
var init_database = __esm({
|
|
3759
3916
|
"src/lib/database.ts"() {
|
|
3760
3917
|
"use strict";
|
|
@@ -3762,11 +3919,14 @@ var init_database = __esm({
|
|
|
3762
3919
|
init_employees();
|
|
3763
3920
|
init_database_adapter();
|
|
3764
3921
|
init_memory();
|
|
3922
|
+
_debugDb = process.env.EXE_DEBUG === "1";
|
|
3765
3923
|
_client = null;
|
|
3766
3924
|
_resilientClient = null;
|
|
3767
3925
|
_walCheckpointTimer = null;
|
|
3768
3926
|
_daemonClient = null;
|
|
3769
3927
|
_adapterClient = null;
|
|
3928
|
+
_lockFd = null;
|
|
3929
|
+
DB_LOCK_PATH = join(homedir(), ".exe-os", "db.lock");
|
|
3770
3930
|
initTurso = initDatabase;
|
|
3771
3931
|
SOFT_DELETE_RETENTION_DAYS = 7;
|
|
3772
3932
|
disposeTurso = disposeDatabase;
|
|
@@ -3810,10 +3970,10 @@ async function disposeEmbedder() {
|
|
|
3810
3970
|
async function embedDirect(text) {
|
|
3811
3971
|
const llamaCpp = await import("node-llama-cpp");
|
|
3812
3972
|
const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
3813
|
-
const { existsSync:
|
|
3973
|
+
const { existsSync: existsSync20 } = await import("fs");
|
|
3814
3974
|
const path23 = await import("path");
|
|
3815
3975
|
const modelPath = path23.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
|
|
3816
|
-
if (!
|
|
3976
|
+
if (!existsSync20(modelPath)) {
|
|
3817
3977
|
throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
|
|
3818
3978
|
}
|
|
3819
3979
|
const llama = await llamaCpp.getLlama();
|
|
@@ -3843,7 +4003,7 @@ var init_embedder = __esm({
|
|
|
3843
4003
|
|
|
3844
4004
|
// src/lib/keychain.ts
|
|
3845
4005
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
3846
|
-
import { existsSync as
|
|
4006
|
+
import { existsSync as existsSync8, statSync as statSync3 } from "fs";
|
|
3847
4007
|
import { execSync as execSync3 } from "child_process";
|
|
3848
4008
|
import path7 from "path";
|
|
3849
4009
|
import os5 from "os";
|
|
@@ -3878,7 +4038,7 @@ function isRootOnlyTrustedServerKeyFile(keyPath) {
|
|
|
3878
4038
|
if (process.platform !== "linux") return false;
|
|
3879
4039
|
try {
|
|
3880
4040
|
const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
|
|
3881
|
-
const st =
|
|
4041
|
+
const st = statSync3(keyPath);
|
|
3882
4042
|
if (!st.isFile() || (st.mode & 63) !== 0) return false;
|
|
3883
4043
|
if (uid === 0) return true;
|
|
3884
4044
|
const exeOsDir = process.env.EXE_OS_DIR;
|
|
@@ -4079,7 +4239,7 @@ async function getMasterKey() {
|
|
|
4079
4239
|
}
|
|
4080
4240
|
}
|
|
4081
4241
|
const keyPath = getKeyPath();
|
|
4082
|
-
if (!
|
|
4242
|
+
if (!existsSync8(keyPath)) {
|
|
4083
4243
|
process.stderr.write(
|
|
4084
4244
|
`[keychain] Key not found at ${keyPath} (HOME=${os5.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
|
|
4085
4245
|
`
|
|
@@ -4359,18 +4519,54 @@ __export(shard_manager_exports, {
|
|
|
4359
4519
|
shardExists: () => shardExists
|
|
4360
4520
|
});
|
|
4361
4521
|
import path8 from "path";
|
|
4362
|
-
import { existsSync as
|
|
4522
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync3, readdirSync, renameSync as renameSync3, statSync as statSync4 } from "fs";
|
|
4363
4523
|
import { createClient as createClient2 } from "@libsql/client";
|
|
4364
4524
|
function initShardManager(encryptionKey) {
|
|
4365
4525
|
_encryptionKey = encryptionKey;
|
|
4366
|
-
|
|
4367
|
-
|
|
4526
|
+
_keyValidated = false;
|
|
4527
|
+
_keyValidationPromise = null;
|
|
4528
|
+
if (!existsSync9(SHARDS_DIR)) {
|
|
4529
|
+
mkdirSync3(SHARDS_DIR, { recursive: true });
|
|
4530
|
+
}
|
|
4531
|
+
const existingShards = readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db"));
|
|
4532
|
+
if (existingShards.length === 0) {
|
|
4533
|
+
_keyValidated = true;
|
|
4368
4534
|
}
|
|
4369
4535
|
_shardingEnabled = true;
|
|
4370
4536
|
if (_evictionTimer) clearInterval(_evictionTimer);
|
|
4371
4537
|
_evictionTimer = setInterval(evictIdleShards, EVICTION_INTERVAL_MS);
|
|
4372
4538
|
_evictionTimer.unref();
|
|
4373
4539
|
}
|
|
4540
|
+
async function validateEncryptionKey() {
|
|
4541
|
+
if (_keyValidated) return true;
|
|
4542
|
+
if (!_encryptionKey) return false;
|
|
4543
|
+
const existingShards = readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db"));
|
|
4544
|
+
if (existingShards.length === 0) {
|
|
4545
|
+
_keyValidated = true;
|
|
4546
|
+
return true;
|
|
4547
|
+
}
|
|
4548
|
+
for (const shardFile of existingShards.slice(0, 3)) {
|
|
4549
|
+
const dbPath = path8.join(SHARDS_DIR, shardFile);
|
|
4550
|
+
const testClient = createClient2({ url: `file:${dbPath}`, encryptionKey: _encryptionKey });
|
|
4551
|
+
try {
|
|
4552
|
+
await testClient.execute("SELECT COUNT(*) FROM sqlite_schema");
|
|
4553
|
+
testClient.close();
|
|
4554
|
+
_keyValidated = true;
|
|
4555
|
+
return true;
|
|
4556
|
+
} catch {
|
|
4557
|
+
try {
|
|
4558
|
+
testClient.close();
|
|
4559
|
+
} catch {
|
|
4560
|
+
}
|
|
4561
|
+
}
|
|
4562
|
+
}
|
|
4563
|
+
process.stderr.write(
|
|
4564
|
+
`[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.
|
|
4565
|
+
`
|
|
4566
|
+
);
|
|
4567
|
+
_shardingEnabled = false;
|
|
4568
|
+
return false;
|
|
4569
|
+
}
|
|
4374
4570
|
function isShardingEnabled() {
|
|
4375
4571
|
return _shardingEnabled;
|
|
4376
4572
|
}
|
|
@@ -4404,13 +4600,13 @@ function getShardClient(projectName) {
|
|
|
4404
4600
|
}
|
|
4405
4601
|
function shardExists(projectName) {
|
|
4406
4602
|
const safeName = safeShardName(projectName);
|
|
4407
|
-
return
|
|
4603
|
+
return existsSync9(path8.join(SHARDS_DIR, `${safeName}.db`));
|
|
4408
4604
|
}
|
|
4409
4605
|
function safeShardName(projectName) {
|
|
4410
4606
|
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
4411
4607
|
}
|
|
4412
4608
|
function listShards() {
|
|
4413
|
-
if (!
|
|
4609
|
+
if (!existsSync9(SHARDS_DIR)) return [];
|
|
4414
4610
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
4415
4611
|
}
|
|
4416
4612
|
async function auditShardHealth(options = {}) {
|
|
@@ -4423,7 +4619,7 @@ async function auditShardHealth(options = {}) {
|
|
|
4423
4619
|
const shards = [];
|
|
4424
4620
|
for (const name of names) {
|
|
4425
4621
|
const dbPath = path8.join(SHARDS_DIR, `${name}.db`);
|
|
4426
|
-
const stat =
|
|
4622
|
+
const stat = statSync4(dbPath);
|
|
4427
4623
|
const item = {
|
|
4428
4624
|
name,
|
|
4429
4625
|
path: dbPath,
|
|
@@ -4663,6 +4859,17 @@ async function ensureShardSchema(client) {
|
|
|
4663
4859
|
}
|
|
4664
4860
|
}
|
|
4665
4861
|
async function getReadyShardClient(projectName) {
|
|
4862
|
+
if (!_keyValidated) {
|
|
4863
|
+
if (!_keyValidationPromise) {
|
|
4864
|
+
_keyValidationPromise = validateEncryptionKey();
|
|
4865
|
+
}
|
|
4866
|
+
const valid = await _keyValidationPromise;
|
|
4867
|
+
if (!valid) {
|
|
4868
|
+
throw new Error(
|
|
4869
|
+
`Shard creation blocked: encryption key mismatch with existing shards. Run /exe-doctor to audit.`
|
|
4870
|
+
);
|
|
4871
|
+
}
|
|
4872
|
+
}
|
|
4666
4873
|
const safeName = safeShardName(projectName);
|
|
4667
4874
|
let client = getShardClient(projectName);
|
|
4668
4875
|
try {
|
|
@@ -4675,8 +4882,8 @@ async function getReadyShardClient(projectName) {
|
|
|
4675
4882
|
_shards.delete(safeName);
|
|
4676
4883
|
_shardLastAccess.delete(safeName);
|
|
4677
4884
|
const dbPath = path8.join(SHARDS_DIR, `${safeName}.db`);
|
|
4678
|
-
if (
|
|
4679
|
-
const stat =
|
|
4885
|
+
if (existsSync9(dbPath)) {
|
|
4886
|
+
const stat = statSync4(dbPath);
|
|
4680
4887
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
4681
4888
|
const archivedPath = path8.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
4682
4889
|
renameSync3(dbPath, archivedPath);
|
|
@@ -4741,7 +4948,7 @@ function disposeShards() {
|
|
|
4741
4948
|
_shardingEnabled = false;
|
|
4742
4949
|
_encryptionKey = null;
|
|
4743
4950
|
}
|
|
4744
|
-
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled;
|
|
4951
|
+
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled, _keyValidated, _keyValidationPromise;
|
|
4745
4952
|
var init_shard_manager = __esm({
|
|
4746
4953
|
"src/lib/shard-manager.ts"() {
|
|
4747
4954
|
"use strict";
|
|
@@ -4755,6 +4962,8 @@ var init_shard_manager = __esm({
|
|
|
4755
4962
|
_evictionTimer = null;
|
|
4756
4963
|
_encryptionKey = null;
|
|
4757
4964
|
_shardingEnabled = false;
|
|
4965
|
+
_keyValidated = false;
|
|
4966
|
+
_keyValidationPromise = null;
|
|
4758
4967
|
}
|
|
4759
4968
|
});
|
|
4760
4969
|
|
|
@@ -4950,6 +5159,18 @@ var init_platform_procedures = __esm({
|
|
|
4950
5159
|
priority: "p0",
|
|
4951
5160
|
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.'"
|
|
4952
5161
|
},
|
|
5162
|
+
{
|
|
5163
|
+
title: "Review chain \u2014 managers must actively pull completed work, never wait for nudges",
|
|
5164
|
+
domain: "workflow",
|
|
5165
|
+
priority: "p0",
|
|
5166
|
+
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."
|
|
5167
|
+
},
|
|
5168
|
+
{
|
|
5169
|
+
title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
|
|
5170
|
+
domain: "workflow",
|
|
5171
|
+
priority: "p0",
|
|
5172
|
+
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."
|
|
5173
|
+
},
|
|
4953
5174
|
{
|
|
4954
5175
|
title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
|
|
4955
5176
|
domain: "architecture",
|
|
@@ -5547,6 +5768,20 @@ __export(store_exports, {
|
|
|
5547
5768
|
vectorToBlob: () => vectorToBlob,
|
|
5548
5769
|
writeMemory: () => writeMemory
|
|
5549
5770
|
});
|
|
5771
|
+
function logStoreDebug(context, err) {
|
|
5772
|
+
if (_debugStore) {
|
|
5773
|
+
process.stderr.write(
|
|
5774
|
+
`[store] ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
5775
|
+
`
|
|
5776
|
+
);
|
|
5777
|
+
}
|
|
5778
|
+
}
|
|
5779
|
+
function logStoreWarn(context, err) {
|
|
5780
|
+
process.stderr.write(
|
|
5781
|
+
`[store] WARN ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
5782
|
+
`
|
|
5783
|
+
);
|
|
5784
|
+
}
|
|
5550
5785
|
function isBusyError2(err) {
|
|
5551
5786
|
if (err instanceof Error) {
|
|
5552
5787
|
const msg = err.message.toLowerCase();
|
|
@@ -5601,13 +5836,15 @@ async function initStore(options) {
|
|
|
5601
5836
|
try {
|
|
5602
5837
|
const { initDaemonClient: initDaemonClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
5603
5838
|
await initDaemonClient2();
|
|
5604
|
-
} catch {
|
|
5839
|
+
} catch (e) {
|
|
5840
|
+
logStoreWarn("catch", e);
|
|
5605
5841
|
}
|
|
5606
5842
|
if (!options?.lightweight) {
|
|
5607
5843
|
try {
|
|
5608
5844
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
5609
5845
|
initShardManager2(hexKey);
|
|
5610
|
-
} catch {
|
|
5846
|
+
} catch (e) {
|
|
5847
|
+
logStoreWarn("catch", e);
|
|
5611
5848
|
}
|
|
5612
5849
|
const client = getClient();
|
|
5613
5850
|
const vResult = await retryOnBusy2(
|
|
@@ -5618,7 +5855,8 @@ async function initStore(options) {
|
|
|
5618
5855
|
try {
|
|
5619
5856
|
const { loadGlobalProcedures: loadGlobalProcedures2 } = await Promise.resolve().then(() => (init_global_procedures(), global_procedures_exports));
|
|
5620
5857
|
await loadGlobalProcedures2();
|
|
5621
|
-
} catch {
|
|
5858
|
+
} catch (e) {
|
|
5859
|
+
logStoreWarn("catch", e);
|
|
5622
5860
|
}
|
|
5623
5861
|
}
|
|
5624
5862
|
}
|
|
@@ -5678,7 +5916,8 @@ async function writeMemory(record) {
|
|
|
5678
5916
|
memoryType
|
|
5679
5917
|
});
|
|
5680
5918
|
if (existing) return;
|
|
5681
|
-
} catch {
|
|
5919
|
+
} catch (e) {
|
|
5920
|
+
logStoreWarn("catch", e);
|
|
5682
5921
|
}
|
|
5683
5922
|
const dbRow = {
|
|
5684
5923
|
id: record.id,
|
|
@@ -5879,12 +6118,14 @@ async function flushBatch() {
|
|
|
5879
6118
|
try {
|
|
5880
6119
|
const { insertMemoryCardsForBatch: insertMemoryCardsForBatch2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
|
|
5881
6120
|
await insertMemoryCardsForBatch2(batch);
|
|
5882
|
-
} catch {
|
|
6121
|
+
} catch (e) {
|
|
6122
|
+
logStoreWarn("catch", e);
|
|
5883
6123
|
}
|
|
5884
6124
|
try {
|
|
5885
6125
|
const { insertOntologyForBatch: insertOntologyForBatch2 } = await Promise.resolve().then(() => (init_agentic_ontology(), agentic_ontology_exports));
|
|
5886
6126
|
await insertOntologyForBatch2(batch);
|
|
5887
|
-
} catch {
|
|
6127
|
+
} catch (e) {
|
|
6128
|
+
logStoreWarn("catch", e);
|
|
5888
6129
|
}
|
|
5889
6130
|
schedulePostWriteMemoryHygiene(batch.map((row) => row.id));
|
|
5890
6131
|
_pendingRecords.splice(0, batch.length);
|
|
@@ -5923,7 +6164,8 @@ ${err.stack.split("\n").slice(1, 3).join("\n")}` : ""}` : String(err);
|
|
|
5923
6164
|
}
|
|
5924
6165
|
}
|
|
5925
6166
|
}
|
|
5926
|
-
} catch {
|
|
6167
|
+
} catch (e) {
|
|
6168
|
+
logStoreWarn("catch", e);
|
|
5927
6169
|
}
|
|
5928
6170
|
return batch.length;
|
|
5929
6171
|
} finally {
|
|
@@ -5965,7 +6207,8 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
5965
6207
|
} else {
|
|
5966
6208
|
client = getClient();
|
|
5967
6209
|
}
|
|
5968
|
-
} catch {
|
|
6210
|
+
} catch (e) {
|
|
6211
|
+
logStoreDebug("shard routing fallback", e);
|
|
5969
6212
|
client = getClient();
|
|
5970
6213
|
}
|
|
5971
6214
|
const limit = options?.limit ?? 10;
|
|
@@ -6081,7 +6324,8 @@ async function attachDocumentMetadata(records) {
|
|
|
6081
6324
|
if (!record.document_id) continue;
|
|
6082
6325
|
record.document_metadata = byId.get(record.document_id) ?? null;
|
|
6083
6326
|
}
|
|
6084
|
-
} catch {
|
|
6327
|
+
} catch (e) {
|
|
6328
|
+
logStoreWarn("catch", e);
|
|
6085
6329
|
}
|
|
6086
6330
|
return records;
|
|
6087
6331
|
}
|
|
@@ -6142,11 +6386,12 @@ async function getMemoryCardinality(agentId) {
|
|
|
6142
6386
|
args: [agentId]
|
|
6143
6387
|
});
|
|
6144
6388
|
return Number(result.rows[0]?.cnt) || 0;
|
|
6145
|
-
} catch {
|
|
6389
|
+
} catch (e) {
|
|
6390
|
+
logStoreWarn("getMemoryCardinality", e);
|
|
6146
6391
|
return 0;
|
|
6147
6392
|
}
|
|
6148
6393
|
}
|
|
6149
|
-
var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
6394
|
+
var _debugStore, INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
6150
6395
|
var init_store = __esm({
|
|
6151
6396
|
"src/lib/store.ts"() {
|
|
6152
6397
|
"use strict";
|
|
@@ -6156,6 +6401,7 @@ var init_store = __esm({
|
|
|
6156
6401
|
init_config();
|
|
6157
6402
|
init_state_bus();
|
|
6158
6403
|
init_memory_write_governor();
|
|
6404
|
+
_debugStore = process.env.EXE_DEBUG === "1";
|
|
6159
6405
|
INIT_MAX_RETRIES = 3;
|
|
6160
6406
|
INIT_RETRY_DELAY_MS = 1e3;
|
|
6161
6407
|
_pendingRecords = [];
|
|
@@ -7319,8 +7565,8 @@ __export(whatsapp_accounts_exports, {
|
|
|
7319
7565
|
loadAccounts: () => loadAccounts
|
|
7320
7566
|
});
|
|
7321
7567
|
import { readFileSync as readFileSync6 } from "fs";
|
|
7322
|
-
import { join as
|
|
7323
|
-
import { homedir as
|
|
7568
|
+
import { join as join3 } from "path";
|
|
7569
|
+
import { homedir as homedir3 } from "os";
|
|
7324
7570
|
function loadAccounts() {
|
|
7325
7571
|
if (cachedAccounts !== null) return cachedAccounts;
|
|
7326
7572
|
try {
|
|
@@ -7358,19 +7604,19 @@ var CONFIG_PATH2, cachedAccounts;
|
|
|
7358
7604
|
var init_whatsapp_accounts = __esm({
|
|
7359
7605
|
"src/gateway/whatsapp-accounts.ts"() {
|
|
7360
7606
|
"use strict";
|
|
7361
|
-
CONFIG_PATH2 =
|
|
7607
|
+
CONFIG_PATH2 = join3(homedir3(), ".exe-os", "whatsapp-accounts.json");
|
|
7362
7608
|
cachedAccounts = null;
|
|
7363
7609
|
}
|
|
7364
7610
|
});
|
|
7365
7611
|
|
|
7366
7612
|
// src/lib/session-registry.ts
|
|
7367
|
-
import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, mkdirSync as
|
|
7613
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, existsSync as existsSync10 } from "fs";
|
|
7368
7614
|
import path10 from "path";
|
|
7369
7615
|
import os7 from "os";
|
|
7370
7616
|
function registerSession(entry) {
|
|
7371
7617
|
const dir = path10.dirname(REGISTRY_PATH);
|
|
7372
|
-
if (!
|
|
7373
|
-
|
|
7618
|
+
if (!existsSync10(dir)) {
|
|
7619
|
+
mkdirSync5(dir, { recursive: true });
|
|
7374
7620
|
}
|
|
7375
7621
|
const sessions = listSessions();
|
|
7376
7622
|
const idx = sessions.findIndex((s) => s.windowName === entry.windowName);
|
|
@@ -7664,16 +7910,16 @@ __export(intercom_queue_exports, {
|
|
|
7664
7910
|
queueIntercom: () => queueIntercom,
|
|
7665
7911
|
readQueue: () => readQueue
|
|
7666
7912
|
});
|
|
7667
|
-
import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, renameSync as renameSync4, existsSync as
|
|
7913
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, renameSync as renameSync4, existsSync as existsSync11, mkdirSync as mkdirSync6 } from "fs";
|
|
7668
7914
|
import path11 from "path";
|
|
7669
7915
|
import os8 from "os";
|
|
7670
7916
|
function ensureDir() {
|
|
7671
7917
|
const dir = path11.dirname(QUEUE_PATH);
|
|
7672
|
-
if (!
|
|
7918
|
+
if (!existsSync11(dir)) mkdirSync6(dir, { recursive: true });
|
|
7673
7919
|
}
|
|
7674
7920
|
function readQueue() {
|
|
7675
7921
|
try {
|
|
7676
|
-
if (!
|
|
7922
|
+
if (!existsSync11(QUEUE_PATH)) return [];
|
|
7677
7923
|
return JSON.parse(readFileSync8(QUEUE_PATH, "utf8"));
|
|
7678
7924
|
} catch {
|
|
7679
7925
|
return [];
|
|
@@ -7782,7 +8028,7 @@ var init_intercom_queue = __esm({
|
|
|
7782
8028
|
});
|
|
7783
8029
|
|
|
7784
8030
|
// src/lib/license.ts
|
|
7785
|
-
import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, existsSync as
|
|
8031
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, existsSync as existsSync12, mkdirSync as mkdirSync7 } from "fs";
|
|
7786
8032
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
7787
8033
|
import { createRequire as createRequire2 } from "module";
|
|
7788
8034
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
@@ -7809,11 +8055,11 @@ var init_license = __esm({
|
|
|
7809
8055
|
});
|
|
7810
8056
|
|
|
7811
8057
|
// src/lib/plan-limits.ts
|
|
7812
|
-
import { readFileSync as readFileSync10, existsSync as
|
|
8058
|
+
import { readFileSync as readFileSync10, existsSync as existsSync13 } from "fs";
|
|
7813
8059
|
import path13 from "path";
|
|
7814
8060
|
function getLicenseSync() {
|
|
7815
8061
|
try {
|
|
7816
|
-
if (!
|
|
8062
|
+
if (!existsSync13(CACHE_PATH2)) return freeLicense();
|
|
7817
8063
|
const raw = JSON.parse(readFileSync10(CACHE_PATH2, "utf8"));
|
|
7818
8064
|
if (!raw.token || typeof raw.token !== "string") return freeLicense();
|
|
7819
8065
|
const parts = raw.token.split(".");
|
|
@@ -7852,7 +8098,7 @@ function assertEmployeeLimitSync(rosterPath) {
|
|
|
7852
8098
|
const filePath = rosterPath ?? EMPLOYEES_PATH;
|
|
7853
8099
|
let count = 0;
|
|
7854
8100
|
try {
|
|
7855
|
-
if (
|
|
8101
|
+
if (existsSync13(filePath)) {
|
|
7856
8102
|
const raw = readFileSync10(filePath, "utf8");
|
|
7857
8103
|
const employees = JSON.parse(raw);
|
|
7858
8104
|
count = Array.isArray(employees) ? employees.length : 0;
|
|
@@ -7890,9 +8136,9 @@ var init_plan_limits = __esm({
|
|
|
7890
8136
|
import os10 from "os";
|
|
7891
8137
|
import path14 from "path";
|
|
7892
8138
|
import {
|
|
7893
|
-
existsSync as
|
|
8139
|
+
existsSync as existsSync14,
|
|
7894
8140
|
lstatSync,
|
|
7895
|
-
mkdirSync as
|
|
8141
|
+
mkdirSync as mkdirSync8,
|
|
7896
8142
|
readlinkSync as readlinkSync2,
|
|
7897
8143
|
symlinkSync as symlinkSync2
|
|
7898
8144
|
} from "fs";
|
|
@@ -7908,8 +8154,8 @@ function claudeAgentLinkPath(homeDir, agentId) {
|
|
|
7908
8154
|
function ensureAgentSymlink(agentId, homeDir = os10.homedir()) {
|
|
7909
8155
|
const target = identitySourcePath(homeDir, agentId);
|
|
7910
8156
|
const link = claudeAgentLinkPath(homeDir, agentId);
|
|
7911
|
-
|
|
7912
|
-
if (
|
|
8157
|
+
mkdirSync8(claudeAgentsDir(homeDir), { recursive: true });
|
|
8158
|
+
if (existsSync14(link)) {
|
|
7913
8159
|
let stat;
|
|
7914
8160
|
try {
|
|
7915
8161
|
stat = lstatSync(link);
|
|
@@ -7990,8 +8236,8 @@ import os11 from "os";
|
|
|
7990
8236
|
import {
|
|
7991
8237
|
readFileSync as readFileSync11,
|
|
7992
8238
|
readdirSync as readdirSync2,
|
|
7993
|
-
unlinkSync as
|
|
7994
|
-
existsSync as
|
|
8239
|
+
unlinkSync as unlinkSync4,
|
|
8240
|
+
existsSync as existsSync15,
|
|
7995
8241
|
rmdirSync
|
|
7996
8242
|
} from "fs";
|
|
7997
8243
|
async function writeNotification(notification) {
|
|
@@ -8184,7 +8430,7 @@ import path17 from "path";
|
|
|
8184
8430
|
import os12 from "os";
|
|
8185
8431
|
import { execSync as execSync7 } from "child_process";
|
|
8186
8432
|
import { mkdir as mkdir4, writeFile as writeFile4, appendFile } from "fs/promises";
|
|
8187
|
-
import { existsSync as
|
|
8433
|
+
import { existsSync as existsSync16, readFileSync as readFileSync12 } from "fs";
|
|
8188
8434
|
async function writeCheckpoint(input) {
|
|
8189
8435
|
const client = getClient();
|
|
8190
8436
|
const row = await resolveTask(client, input.taskId);
|
|
@@ -8425,7 +8671,7 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
8425
8671
|
const EXE_OS_DIR = path17.join(os12.homedir(), ".exe-os");
|
|
8426
8672
|
const mdPath = path17.join(EXE_OS_DIR, taskFile);
|
|
8427
8673
|
const mdDir = path17.dirname(mdPath);
|
|
8428
|
-
if (!
|
|
8674
|
+
if (!existsSync16(mdDir)) await mkdir4(mdDir, { recursive: true });
|
|
8429
8675
|
const reviewer = input.reviewer ?? input.assignedBy;
|
|
8430
8676
|
const mdContent = `# ${input.title}
|
|
8431
8677
|
|
|
@@ -8731,7 +8977,7 @@ async function deleteTaskCore(taskId, _baseDir) {
|
|
|
8731
8977
|
async function ensureArchitectureDoc(baseDir, projectName) {
|
|
8732
8978
|
const archPath = path17.join(baseDir, "exe", "ARCHITECTURE.md");
|
|
8733
8979
|
try {
|
|
8734
|
-
if (
|
|
8980
|
+
if (existsSync16(archPath)) return;
|
|
8735
8981
|
const template = [
|
|
8736
8982
|
`# ${projectName} \u2014 System Architecture`,
|
|
8737
8983
|
"",
|
|
@@ -8766,7 +9012,7 @@ async function ensureArchitectureDoc(baseDir, projectName) {
|
|
|
8766
9012
|
async function ensureGitignoreExe(baseDir) {
|
|
8767
9013
|
const gitignorePath = path17.join(baseDir, ".gitignore");
|
|
8768
9014
|
try {
|
|
8769
|
-
if (
|
|
9015
|
+
if (existsSync16(gitignorePath)) {
|
|
8770
9016
|
const content = readFileSync12(gitignorePath, "utf-8");
|
|
8771
9017
|
if (/^\/?exe\/?$/m.test(content)) return;
|
|
8772
9018
|
await appendFile(gitignorePath, "\n# Employee task assignments (private)\n/exe/\n");
|
|
@@ -8811,7 +9057,7 @@ __export(tasks_review_exports, {
|
|
|
8811
9057
|
listPendingReviews: () => listPendingReviews
|
|
8812
9058
|
});
|
|
8813
9059
|
import path18 from "path";
|
|
8814
|
-
import { existsSync as
|
|
9060
|
+
import { existsSync as existsSync17, readdirSync as readdirSync3, unlinkSync as unlinkSync5 } from "fs";
|
|
8815
9061
|
function formatAge(isoTimestamp) {
|
|
8816
9062
|
if (!isoTimestamp) return "";
|
|
8817
9063
|
const ms = Date.now() - new Date(isoTimestamp).getTime();
|
|
@@ -9081,10 +9327,10 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
9081
9327
|
}
|
|
9082
9328
|
try {
|
|
9083
9329
|
const cacheDir = path18.join(EXE_AI_DIR, "session-cache");
|
|
9084
|
-
if (
|
|
9330
|
+
if (existsSync17(cacheDir)) {
|
|
9085
9331
|
for (const f of readdirSync3(cacheDir)) {
|
|
9086
9332
|
if (f.startsWith("review-notified-")) {
|
|
9087
|
-
|
|
9333
|
+
unlinkSync5(path18.join(cacheDir, f));
|
|
9088
9334
|
}
|
|
9089
9335
|
}
|
|
9090
9336
|
}
|
|
@@ -9609,7 +9855,7 @@ __export(tasks_exports, {
|
|
|
9609
9855
|
writeCheckpoint: () => writeCheckpoint
|
|
9610
9856
|
});
|
|
9611
9857
|
import path20 from "path";
|
|
9612
|
-
import { writeFileSync as writeFileSync7, mkdirSync as
|
|
9858
|
+
import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync9, unlinkSync as unlinkSync6 } from "fs";
|
|
9613
9859
|
async function createTask(input) {
|
|
9614
9860
|
const result = await createTaskCore(input);
|
|
9615
9861
|
if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
|
|
@@ -9631,11 +9877,11 @@ async function updateTask(input) {
|
|
|
9631
9877
|
const cacheDir = path20.join(EXE_AI_DIR, "session-cache");
|
|
9632
9878
|
const cachePath = path20.join(cacheDir, `current-task-${agent}.json`);
|
|
9633
9879
|
if (input.status === "in_progress") {
|
|
9634
|
-
|
|
9880
|
+
mkdirSync9(cacheDir, { recursive: true });
|
|
9635
9881
|
writeFileSync7(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
|
|
9636
9882
|
} else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled" || input.status === "closed") {
|
|
9637
9883
|
try {
|
|
9638
|
-
|
|
9884
|
+
unlinkSync6(cachePath);
|
|
9639
9885
|
} catch {
|
|
9640
9886
|
}
|
|
9641
9887
|
}
|
|
@@ -10103,11 +10349,11 @@ __export(tmux_routing_exports, {
|
|
|
10103
10349
|
verifyPaneAtCapacity: () => verifyPaneAtCapacity
|
|
10104
10350
|
});
|
|
10105
10351
|
import { execFileSync as execFileSync2, execSync as execSync8 } from "child_process";
|
|
10106
|
-
import { readFileSync as readFileSync13, writeFileSync as writeFileSync8, mkdirSync as
|
|
10352
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync8, mkdirSync as mkdirSync10, existsSync as existsSync18, appendFileSync, readdirSync as readdirSync4 } from "fs";
|
|
10107
10353
|
import path21 from "path";
|
|
10108
10354
|
import os13 from "os";
|
|
10109
10355
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
10110
|
-
import { unlinkSync as
|
|
10356
|
+
import { unlinkSync as unlinkSync7 } from "fs";
|
|
10111
10357
|
function spawnLockPath(sessionName) {
|
|
10112
10358
|
return path21.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
|
|
10113
10359
|
}
|
|
@@ -10120,11 +10366,11 @@ function isProcessAlive(pid) {
|
|
|
10120
10366
|
}
|
|
10121
10367
|
}
|
|
10122
10368
|
function acquireSpawnLock2(sessionName) {
|
|
10123
|
-
if (!
|
|
10124
|
-
|
|
10369
|
+
if (!existsSync18(SPAWN_LOCK_DIR)) {
|
|
10370
|
+
mkdirSync10(SPAWN_LOCK_DIR, { recursive: true });
|
|
10125
10371
|
}
|
|
10126
10372
|
const lockFile = spawnLockPath(sessionName);
|
|
10127
|
-
if (
|
|
10373
|
+
if (existsSync18(lockFile)) {
|
|
10128
10374
|
try {
|
|
10129
10375
|
const lock = JSON.parse(readFileSync13(lockFile, "utf8"));
|
|
10130
10376
|
const age = Date.now() - lock.timestamp;
|
|
@@ -10139,7 +10385,7 @@ function acquireSpawnLock2(sessionName) {
|
|
|
10139
10385
|
}
|
|
10140
10386
|
function releaseSpawnLock2(sessionName) {
|
|
10141
10387
|
try {
|
|
10142
|
-
|
|
10388
|
+
unlinkSync7(spawnLockPath(sessionName));
|
|
10143
10389
|
} catch {
|
|
10144
10390
|
}
|
|
10145
10391
|
}
|
|
@@ -10152,7 +10398,7 @@ function resolveBehaviorsExporterScript() {
|
|
|
10152
10398
|
"bin",
|
|
10153
10399
|
"exe-export-behaviors.js"
|
|
10154
10400
|
);
|
|
10155
|
-
return
|
|
10401
|
+
return existsSync18(scriptPath) ? scriptPath : null;
|
|
10156
10402
|
} catch {
|
|
10157
10403
|
return null;
|
|
10158
10404
|
}
|
|
@@ -10218,8 +10464,8 @@ function extractRootExe(name) {
|
|
|
10218
10464
|
return parts.length > 0 ? parts[parts.length - 1] : null;
|
|
10219
10465
|
}
|
|
10220
10466
|
function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
10221
|
-
if (!
|
|
10222
|
-
|
|
10467
|
+
if (!existsSync18(SESSION_CACHE)) {
|
|
10468
|
+
mkdirSync10(SESSION_CACHE, { recursive: true });
|
|
10223
10469
|
}
|
|
10224
10470
|
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
10225
10471
|
const filePath = path21.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
@@ -10249,11 +10495,13 @@ function getDispatchedBy(sessionKey) {
|
|
|
10249
10495
|
}
|
|
10250
10496
|
}
|
|
10251
10497
|
function resolveExeSession() {
|
|
10252
|
-
if (process.env.EXE_SESSION_NAME) {
|
|
10253
|
-
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
10254
|
-
}
|
|
10255
10498
|
const mySession = getMySession();
|
|
10256
|
-
if (!mySession)
|
|
10499
|
+
if (!mySession) {
|
|
10500
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
10501
|
+
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
10502
|
+
}
|
|
10503
|
+
return null;
|
|
10504
|
+
}
|
|
10257
10505
|
const fromSessionName = extractRootExe(mySession);
|
|
10258
10506
|
let candidate = null;
|
|
10259
10507
|
try {
|
|
@@ -10348,7 +10596,7 @@ async function verifyPaneAtCapacity(sessionName) {
|
|
|
10348
10596
|
}
|
|
10349
10597
|
function readDebounceState() {
|
|
10350
10598
|
try {
|
|
10351
|
-
if (!
|
|
10599
|
+
if (!existsSync18(DEBOUNCE_FILE)) return {};
|
|
10352
10600
|
const raw = JSON.parse(readFileSync13(DEBOUNCE_FILE, "utf8"));
|
|
10353
10601
|
const state = {};
|
|
10354
10602
|
for (const [key, val] of Object.entries(raw)) {
|
|
@@ -10365,7 +10613,7 @@ function readDebounceState() {
|
|
|
10365
10613
|
}
|
|
10366
10614
|
function writeDebounceState(state) {
|
|
10367
10615
|
try {
|
|
10368
|
-
if (!
|
|
10616
|
+
if (!existsSync18(SESSION_CACHE)) mkdirSync10(SESSION_CACHE, { recursive: true });
|
|
10369
10617
|
writeFileSync8(DEBOUNCE_FILE, JSON.stringify(state));
|
|
10370
10618
|
} catch {
|
|
10371
10619
|
}
|
|
@@ -10466,7 +10714,7 @@ function sendIntercom(targetSession) {
|
|
|
10466
10714
|
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
10467
10715
|
const agent = baseAgentName(rawAgent);
|
|
10468
10716
|
const markerPath = path21.join(SESSION_CACHE, `current-task-${agent}.json`);
|
|
10469
|
-
if (
|
|
10717
|
+
if (existsSync18(markerPath)) {
|
|
10470
10718
|
logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker + not idle \u2014 will auto-chain)`);
|
|
10471
10719
|
return "debounced";
|
|
10472
10720
|
}
|
|
@@ -10477,7 +10725,7 @@ function sendIntercom(targetSession) {
|
|
|
10477
10725
|
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
10478
10726
|
const agent = baseAgentName(rawAgent);
|
|
10479
10727
|
const taskDir = path21.join(process.cwd(), "exe", agent);
|
|
10480
|
-
if (
|
|
10728
|
+
if (existsSync18(taskDir)) {
|
|
10481
10729
|
const files = readdirSync4(taskDir).filter(
|
|
10482
10730
|
(f) => f.endsWith(".md") && f !== "DONE.txt"
|
|
10483
10731
|
);
|
|
@@ -10638,15 +10886,15 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
10638
10886
|
const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
|
|
10639
10887
|
const logDir = path21.join(os13.homedir(), ".exe-os", "session-logs");
|
|
10640
10888
|
const logFile = path21.join(logDir, `${instanceLabel}-${Date.now()}.log`);
|
|
10641
|
-
if (!
|
|
10642
|
-
|
|
10889
|
+
if (!existsSync18(logDir)) {
|
|
10890
|
+
mkdirSync10(logDir, { recursive: true });
|
|
10643
10891
|
}
|
|
10644
10892
|
transport.kill(sessionName);
|
|
10645
10893
|
let cleanupSuffix = "";
|
|
10646
10894
|
try {
|
|
10647
10895
|
const thisFile = fileURLToPath2(import.meta.url);
|
|
10648
10896
|
const cleanupScript = path21.join(path21.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
|
|
10649
|
-
if (
|
|
10897
|
+
if (existsSync18(cleanupScript)) {
|
|
10650
10898
|
cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
|
|
10651
10899
|
}
|
|
10652
10900
|
} catch {
|
|
@@ -10701,7 +10949,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
10701
10949
|
if (changed) {
|
|
10702
10950
|
perms.allow = allow;
|
|
10703
10951
|
settings.permissions = perms;
|
|
10704
|
-
|
|
10952
|
+
mkdirSync10(projSettingsDir, { recursive: true });
|
|
10705
10953
|
writeFileSync8(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
10706
10954
|
}
|
|
10707
10955
|
} catch {
|
|
@@ -10739,7 +10987,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
10739
10987
|
`
|
|
10740
10988
|
);
|
|
10741
10989
|
}
|
|
10742
|
-
} else if (
|
|
10990
|
+
} else if (existsSync18(identityPath)) {
|
|
10743
10991
|
identityFlag = ` --append-system-prompt-file ${identityPath}`;
|
|
10744
10992
|
legacyFallbackWarned = true;
|
|
10745
10993
|
}
|
|
@@ -10761,7 +11009,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
10761
11009
|
let sessionContextFlag = "";
|
|
10762
11010
|
try {
|
|
10763
11011
|
const ctxDir = path21.join(os13.homedir(), ".exe-os", "session-cache");
|
|
10764
|
-
|
|
11012
|
+
mkdirSync10(ctxDir, { recursive: true });
|
|
10765
11013
|
const ctxFile = path21.join(ctxDir, `session-context-${sessionName}.md`);
|
|
10766
11014
|
const ctxContent = [
|
|
10767
11015
|
`## Session Context`,
|
|
@@ -12842,14 +13090,14 @@ var OllamaProvider = class {
|
|
|
12842
13090
|
|
|
12843
13091
|
// src/gateway/adapters/whatsapp.ts
|
|
12844
13092
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
12845
|
-
import { homedir } from "os";
|
|
12846
|
-
import { join } from "path";
|
|
12847
|
-
import { mkdirSync as
|
|
13093
|
+
import { homedir as homedir2 } from "os";
|
|
13094
|
+
import { join as join2 } from "path";
|
|
13095
|
+
import { mkdirSync as mkdirSync4 } from "fs";
|
|
12848
13096
|
var INITIAL_BACKOFF_MS = 1e3;
|
|
12849
13097
|
var MAX_BACKOFF_MS = 3e5;
|
|
12850
13098
|
var BACKOFF_MULTIPLIER = 2;
|
|
12851
13099
|
var JITTER_FACTOR = 0.25;
|
|
12852
|
-
var AUTH_DIR =
|
|
13100
|
+
var AUTH_DIR = join2(homedir2(), ".exe-os", "whatsapp-auth");
|
|
12853
13101
|
function createBaileysLogger(accountName) {
|
|
12854
13102
|
const prefix = accountName ? `[whatsapp:${accountName}]` : "[whatsapp]";
|
|
12855
13103
|
let logger;
|
|
@@ -12889,7 +13137,7 @@ var WhatsAppAdapter = class {
|
|
|
12889
13137
|
disconnectedAt = 0;
|
|
12890
13138
|
async connect(config2) {
|
|
12891
13139
|
this.authDir = config2.credentials.authDir ?? AUTH_DIR;
|
|
12892
|
-
|
|
13140
|
+
mkdirSync4(this.authDir, { recursive: true });
|
|
12893
13141
|
const baileys = await import("@whiskeysockets/baileys");
|
|
12894
13142
|
const { makeWASocket, useMultiFileAuthState, fetchLatestBaileysVersion, DisconnectReason, makeCacheableSignalKeyStore } = baileys;
|
|
12895
13143
|
const { state, saveCreds } = await useMultiFileAuthState(this.authDir);
|
|
@@ -15023,7 +15271,7 @@ async function ensureCRMContact(info) {
|
|
|
15023
15271
|
}
|
|
15024
15272
|
|
|
15025
15273
|
// src/automation/trigger-engine.ts
|
|
15026
|
-
import { readFileSync as readFileSync14, writeFileSync as writeFileSync9, existsSync as
|
|
15274
|
+
import { readFileSync as readFileSync14, writeFileSync as writeFileSync9, existsSync as existsSync19, mkdirSync as mkdirSync11 } from "fs";
|
|
15027
15275
|
import { randomUUID as randomUUID12 } from "crypto";
|
|
15028
15276
|
import path22 from "path";
|
|
15029
15277
|
import os14 from "os";
|
|
@@ -15081,7 +15329,7 @@ function evaluateConditions(conditions, record) {
|
|
|
15081
15329
|
return conditions.every((c) => evaluateCondition(c, record));
|
|
15082
15330
|
}
|
|
15083
15331
|
function loadTriggers(project) {
|
|
15084
|
-
if (!
|
|
15332
|
+
if (!existsSync19(TRIGGERS_PATH)) return [];
|
|
15085
15333
|
try {
|
|
15086
15334
|
const raw = readFileSync14(TRIGGERS_PATH, "utf-8");
|
|
15087
15335
|
const all = JSON.parse(raw);
|