@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/runtime/index.js
CHANGED
|
@@ -2242,9 +2242,79 @@ __export(database_exports, {
|
|
|
2242
2242
|
isInitialized: () => isInitialized,
|
|
2243
2243
|
setExternalClient: () => setExternalClient
|
|
2244
2244
|
});
|
|
2245
|
-
import { chmodSync as chmodSync2 } from "fs";
|
|
2245
|
+
import { chmodSync as chmodSync2, existsSync as existsSync9, statSync as statSync2, copyFileSync, unlinkSync as unlinkSync3, openSync as openSync2, closeSync as closeSync2, mkdirSync as mkdirSync4 } from "fs";
|
|
2246
2246
|
import { createClient } from "@libsql/client";
|
|
2247
|
+
import { homedir } from "os";
|
|
2248
|
+
import { join } from "path";
|
|
2249
|
+
function logCatchDebug(context, err) {
|
|
2250
|
+
if (_debugDb) {
|
|
2251
|
+
process.stderr.write(
|
|
2252
|
+
`[database] ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
2253
|
+
`
|
|
2254
|
+
);
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
function acquireDbLock() {
|
|
2258
|
+
mkdirSync4(join(homedir(), ".exe-os"), { recursive: true });
|
|
2259
|
+
try {
|
|
2260
|
+
_lockFd = openSync2(DB_LOCK_PATH, "wx");
|
|
2261
|
+
} catch (err) {
|
|
2262
|
+
if (err && typeof err === "object" && "code" in err && err.code === "EEXIST") {
|
|
2263
|
+
try {
|
|
2264
|
+
const lockStat = statSync2(DB_LOCK_PATH);
|
|
2265
|
+
if (Date.now() - lockStat.mtimeMs > 6e4) {
|
|
2266
|
+
unlinkSync3(DB_LOCK_PATH);
|
|
2267
|
+
_lockFd = openSync2(DB_LOCK_PATH, "wx");
|
|
2268
|
+
return;
|
|
2269
|
+
}
|
|
2270
|
+
} catch (e) {
|
|
2271
|
+
logCatchDebug("stale lock check", e);
|
|
2272
|
+
}
|
|
2273
|
+
process.stderr.write(
|
|
2274
|
+
"[database] WARN: Another process holds db.lock \u2014 waiting briefly then proceeding.\n"
|
|
2275
|
+
);
|
|
2276
|
+
return;
|
|
2277
|
+
}
|
|
2278
|
+
throw err;
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
function releaseDbLock() {
|
|
2282
|
+
if (_lockFd !== null) {
|
|
2283
|
+
try {
|
|
2284
|
+
closeSync2(_lockFd);
|
|
2285
|
+
} catch (e) {
|
|
2286
|
+
logCatchDebug("lock close", e);
|
|
2287
|
+
}
|
|
2288
|
+
_lockFd = null;
|
|
2289
|
+
}
|
|
2290
|
+
try {
|
|
2291
|
+
unlinkSync3(DB_LOCK_PATH);
|
|
2292
|
+
} catch (e) {
|
|
2293
|
+
logCatchDebug("lock unlink", e);
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2247
2296
|
async function initDatabase(config) {
|
|
2297
|
+
acquireDbLock();
|
|
2298
|
+
if (existsSync9(config.dbPath)) {
|
|
2299
|
+
const dbStat = statSync2(config.dbPath);
|
|
2300
|
+
if (dbStat.size === 0) {
|
|
2301
|
+
const walPath = config.dbPath + "-wal";
|
|
2302
|
+
if (existsSync9(walPath) && statSync2(walPath).size > 0) {
|
|
2303
|
+
const backupPath = config.dbPath + ".zeroed-" + Date.now();
|
|
2304
|
+
copyFileSync(config.dbPath, backupPath);
|
|
2305
|
+
unlinkSync3(config.dbPath);
|
|
2306
|
+
process.stderr.write(
|
|
2307
|
+
`[database] CRITICAL: DB was 0 bytes. Moved to ${backupPath}, attempting WAL recovery.
|
|
2308
|
+
`
|
|
2309
|
+
);
|
|
2310
|
+
} else {
|
|
2311
|
+
process.stderr.write(
|
|
2312
|
+
`[database] CRITICAL: DB is 0 bytes and no WAL available for recovery. Data may be lost. Check backups at ${config.dbPath}.bak
|
|
2313
|
+
`
|
|
2314
|
+
);
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2248
2318
|
if (_walCheckpointTimer) {
|
|
2249
2319
|
clearInterval(_walCheckpointTimer);
|
|
2250
2320
|
_walCheckpointTimer = null;
|
|
@@ -2271,10 +2341,8 @@ async function initDatabase(config) {
|
|
|
2271
2341
|
_client = createClient(opts);
|
|
2272
2342
|
_resilientClient = wrapWithRetry(_client);
|
|
2273
2343
|
_adapterClient = _resilientClient;
|
|
2274
|
-
_client.execute("PRAGMA busy_timeout = 30000")
|
|
2275
|
-
|
|
2276
|
-
_client.execute("PRAGMA journal_mode = WAL").catch(() => {
|
|
2277
|
-
});
|
|
2344
|
+
await _client.execute("PRAGMA busy_timeout = 30000");
|
|
2345
|
+
await _client.execute("PRAGMA journal_mode = WAL");
|
|
2278
2346
|
if (_walCheckpointTimer) clearInterval(_walCheckpointTimer);
|
|
2279
2347
|
_walCheckpointTimer = setInterval(() => {
|
|
2280
2348
|
_client?.execute("PRAGMA wal_checkpoint(PASSIVE)").catch(() => {
|
|
@@ -2289,11 +2357,16 @@ async function initDatabase(config) {
|
|
|
2289
2357
|
for (const suffix of ["-wal", "-shm"]) {
|
|
2290
2358
|
try {
|
|
2291
2359
|
chmodSync2(config.dbPath + suffix, 384);
|
|
2292
|
-
} catch {
|
|
2360
|
+
} catch (chmodErr) {
|
|
2361
|
+
process.stderr.write(`[database] chmod ${suffix} failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
|
|
2362
|
+
`);
|
|
2293
2363
|
}
|
|
2294
2364
|
}
|
|
2295
|
-
} catch {
|
|
2365
|
+
} catch (chmodErr) {
|
|
2366
|
+
process.stderr.write(`[database] chmod db failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
|
|
2367
|
+
`);
|
|
2296
2368
|
}
|
|
2369
|
+
releaseDbLock();
|
|
2297
2370
|
}
|
|
2298
2371
|
function isInitialized() {
|
|
2299
2372
|
return _adapterClient !== null || _client !== null;
|
|
@@ -2348,7 +2421,8 @@ async function ensureSchema() {
|
|
|
2348
2421
|
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
2349
2422
|
try {
|
|
2350
2423
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
2351
|
-
} catch {
|
|
2424
|
+
} catch (e) {
|
|
2425
|
+
logCatchDebug("migration", e);
|
|
2352
2426
|
}
|
|
2353
2427
|
await client.executeMultiple(`
|
|
2354
2428
|
CREATE TABLE IF NOT EXISTS memories (
|
|
@@ -2413,6 +2487,23 @@ async function ensureSchema() {
|
|
|
2413
2487
|
INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
|
|
2414
2488
|
END;
|
|
2415
2489
|
`);
|
|
2490
|
+
try {
|
|
2491
|
+
await client.execute("SELECT COUNT(*) FROM memories_fts LIMIT 1");
|
|
2492
|
+
} catch (ftsErr) {
|
|
2493
|
+
process.stderr.write(
|
|
2494
|
+
`[database] WARN: memories_fts corrupted (${ftsErr instanceof Error ? ftsErr.message : String(ftsErr)}) \u2014 rebuilding FTS index.
|
|
2495
|
+
`
|
|
2496
|
+
);
|
|
2497
|
+
try {
|
|
2498
|
+
await client.execute("INSERT INTO memories_fts(memories_fts) VALUES('rebuild')");
|
|
2499
|
+
process.stderr.write("[database] FTS index rebuilt successfully.\n");
|
|
2500
|
+
} catch (rebuildErr) {
|
|
2501
|
+
process.stderr.write(
|
|
2502
|
+
`[database] ERROR: FTS rebuild failed: ${rebuildErr instanceof Error ? rebuildErr.message : String(rebuildErr)}
|
|
2503
|
+
`
|
|
2504
|
+
);
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
2416
2507
|
await client.executeMultiple(`
|
|
2417
2508
|
CREATE TABLE IF NOT EXISTS sync_meta (
|
|
2418
2509
|
key TEXT PRIMARY KEY,
|
|
@@ -2471,35 +2562,40 @@ async function ensureSchema() {
|
|
|
2471
2562
|
});
|
|
2472
2563
|
}
|
|
2473
2564
|
}
|
|
2474
|
-
} catch {
|
|
2565
|
+
} catch (seedErr) {
|
|
2566
|
+
logCatchDebug("behavior seed", seedErr);
|
|
2475
2567
|
}
|
|
2476
2568
|
try {
|
|
2477
2569
|
await client.execute({
|
|
2478
2570
|
sql: `ALTER TABLE behaviors ADD COLUMN priority TEXT DEFAULT 'p1'`,
|
|
2479
2571
|
args: []
|
|
2480
2572
|
});
|
|
2481
|
-
} catch {
|
|
2573
|
+
} catch (e) {
|
|
2574
|
+
logCatchDebug("migration", e);
|
|
2482
2575
|
}
|
|
2483
2576
|
try {
|
|
2484
2577
|
await client.execute({
|
|
2485
2578
|
sql: `ALTER TABLE behaviors ADD COLUMN vector F32_BLOB(${EMBEDDING_DIM})`,
|
|
2486
2579
|
args: []
|
|
2487
2580
|
});
|
|
2488
|
-
} catch {
|
|
2581
|
+
} catch (e) {
|
|
2582
|
+
logCatchDebug("migration", e);
|
|
2489
2583
|
}
|
|
2490
2584
|
try {
|
|
2491
2585
|
await client.execute({
|
|
2492
2586
|
sql: `ALTER TABLE tasks ADD COLUMN blocked_by TEXT`,
|
|
2493
2587
|
args: []
|
|
2494
2588
|
});
|
|
2495
|
-
} catch {
|
|
2589
|
+
} catch (e) {
|
|
2590
|
+
logCatchDebug("migration", e);
|
|
2496
2591
|
}
|
|
2497
2592
|
try {
|
|
2498
2593
|
await client.execute({
|
|
2499
2594
|
sql: `ALTER TABLE tasks ADD COLUMN parent_task_id TEXT`,
|
|
2500
2595
|
args: []
|
|
2501
2596
|
});
|
|
2502
|
-
} catch {
|
|
2597
|
+
} catch (e) {
|
|
2598
|
+
logCatchDebug("migration", e);
|
|
2503
2599
|
}
|
|
2504
2600
|
try {
|
|
2505
2601
|
await client.execute({
|
|
@@ -2508,98 +2604,112 @@ async function ensureSchema() {
|
|
|
2508
2604
|
WHERE parent_task_id IS NOT NULL`,
|
|
2509
2605
|
args: []
|
|
2510
2606
|
});
|
|
2511
|
-
} catch {
|
|
2607
|
+
} catch (e) {
|
|
2608
|
+
logCatchDebug("migration", e);
|
|
2512
2609
|
}
|
|
2513
2610
|
try {
|
|
2514
2611
|
await client.execute({
|
|
2515
2612
|
sql: `UPDATE tasks SET status = 'done' WHERE status = 'completed'`,
|
|
2516
2613
|
args: []
|
|
2517
2614
|
});
|
|
2518
|
-
} catch {
|
|
2615
|
+
} catch (e) {
|
|
2616
|
+
logCatchDebug("migration", e);
|
|
2519
2617
|
}
|
|
2520
2618
|
try {
|
|
2521
2619
|
await client.execute({
|
|
2522
2620
|
sql: `ALTER TABLE tasks ADD COLUMN reviewer TEXT`,
|
|
2523
2621
|
args: []
|
|
2524
2622
|
});
|
|
2525
|
-
} catch {
|
|
2623
|
+
} catch (e) {
|
|
2624
|
+
logCatchDebug("migration", e);
|
|
2526
2625
|
}
|
|
2527
2626
|
try {
|
|
2528
2627
|
await client.execute({
|
|
2529
2628
|
sql: `ALTER TABLE tasks ADD COLUMN context TEXT`,
|
|
2530
2629
|
args: []
|
|
2531
2630
|
});
|
|
2532
|
-
} catch {
|
|
2631
|
+
} catch (e) {
|
|
2632
|
+
logCatchDebug("migration", e);
|
|
2533
2633
|
}
|
|
2534
2634
|
try {
|
|
2535
2635
|
await client.execute({
|
|
2536
2636
|
sql: `ALTER TABLE tasks ADD COLUMN result TEXT`,
|
|
2537
2637
|
args: []
|
|
2538
2638
|
});
|
|
2539
|
-
} catch {
|
|
2639
|
+
} catch (e) {
|
|
2640
|
+
logCatchDebug("migration", e);
|
|
2540
2641
|
}
|
|
2541
2642
|
try {
|
|
2542
2643
|
await client.execute({
|
|
2543
2644
|
sql: `ALTER TABLE tasks ADD COLUMN assigned_tmux TEXT`,
|
|
2544
2645
|
args: []
|
|
2545
2646
|
});
|
|
2546
|
-
} catch {
|
|
2647
|
+
} catch (e) {
|
|
2648
|
+
logCatchDebug("migration", e);
|
|
2547
2649
|
}
|
|
2548
2650
|
try {
|
|
2549
2651
|
await client.execute({
|
|
2550
2652
|
sql: `ALTER TABLE tasks ADD COLUMN checkpoint TEXT`,
|
|
2551
2653
|
args: []
|
|
2552
2654
|
});
|
|
2553
|
-
} catch {
|
|
2655
|
+
} catch (e) {
|
|
2656
|
+
logCatchDebug("migration", e);
|
|
2554
2657
|
}
|
|
2555
2658
|
try {
|
|
2556
2659
|
await client.execute({
|
|
2557
2660
|
sql: `ALTER TABLE tasks ADD COLUMN checkpoint_count INTEGER NOT NULL DEFAULT 0`,
|
|
2558
2661
|
args: []
|
|
2559
2662
|
});
|
|
2560
|
-
} catch {
|
|
2663
|
+
} catch (e) {
|
|
2664
|
+
logCatchDebug("migration", e);
|
|
2561
2665
|
}
|
|
2562
2666
|
try {
|
|
2563
2667
|
await client.execute({
|
|
2564
2668
|
sql: `ALTER TABLE tasks ADD COLUMN complexity TEXT NOT NULL DEFAULT 'standard'`,
|
|
2565
2669
|
args: []
|
|
2566
2670
|
});
|
|
2567
|
-
} catch {
|
|
2671
|
+
} catch (e) {
|
|
2672
|
+
logCatchDebug("migration", e);
|
|
2568
2673
|
}
|
|
2569
2674
|
try {
|
|
2570
2675
|
await client.execute({
|
|
2571
2676
|
sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
|
|
2572
2677
|
args: []
|
|
2573
2678
|
});
|
|
2574
|
-
} catch {
|
|
2679
|
+
} catch (e) {
|
|
2680
|
+
logCatchDebug("migration", e);
|
|
2575
2681
|
}
|
|
2576
2682
|
try {
|
|
2577
2683
|
await client.execute({
|
|
2578
2684
|
sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
|
|
2579
2685
|
args: []
|
|
2580
2686
|
});
|
|
2581
|
-
} catch {
|
|
2687
|
+
} catch (e) {
|
|
2688
|
+
logCatchDebug("migration", e);
|
|
2582
2689
|
}
|
|
2583
2690
|
try {
|
|
2584
2691
|
await client.execute({
|
|
2585
2692
|
sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
|
|
2586
2693
|
args: []
|
|
2587
2694
|
});
|
|
2588
|
-
} catch {
|
|
2695
|
+
} catch (e) {
|
|
2696
|
+
logCatchDebug("migration", e);
|
|
2589
2697
|
}
|
|
2590
2698
|
try {
|
|
2591
2699
|
await client.execute({
|
|
2592
2700
|
sql: `ALTER TABLE memories ADD COLUMN author_device_id TEXT`,
|
|
2593
2701
|
args: []
|
|
2594
2702
|
});
|
|
2595
|
-
} catch {
|
|
2703
|
+
} catch (e) {
|
|
2704
|
+
logCatchDebug("migration", e);
|
|
2596
2705
|
}
|
|
2597
2706
|
try {
|
|
2598
2707
|
await client.execute({
|
|
2599
2708
|
sql: `ALTER TABLE memories ADD COLUMN scope TEXT NOT NULL DEFAULT 'business'`,
|
|
2600
2709
|
args: []
|
|
2601
2710
|
});
|
|
2602
|
-
} catch {
|
|
2711
|
+
} catch (e) {
|
|
2712
|
+
logCatchDebug("migration", e);
|
|
2603
2713
|
}
|
|
2604
2714
|
await client.executeMultiple(`
|
|
2605
2715
|
CREATE TABLE IF NOT EXISTS consolidations (
|
|
@@ -2704,14 +2814,16 @@ async function ensureSchema() {
|
|
|
2704
2814
|
sql: `ALTER TABLE notifications ADD COLUMN session_scope TEXT`,
|
|
2705
2815
|
args: []
|
|
2706
2816
|
});
|
|
2707
|
-
} catch {
|
|
2817
|
+
} catch (e) {
|
|
2818
|
+
logCatchDebug("migration", e);
|
|
2708
2819
|
}
|
|
2709
2820
|
try {
|
|
2710
2821
|
await client.execute({
|
|
2711
2822
|
sql: `ALTER TABLE messages ADD COLUMN session_scope TEXT`,
|
|
2712
2823
|
args: []
|
|
2713
2824
|
});
|
|
2714
|
-
} catch {
|
|
2825
|
+
} catch (e) {
|
|
2826
|
+
logCatchDebug("migration", e);
|
|
2715
2827
|
}
|
|
2716
2828
|
await client.executeMultiple(`
|
|
2717
2829
|
CREATE INDEX IF NOT EXISTS idx_notifications_agent_scope_read
|
|
@@ -2737,7 +2849,8 @@ async function ensureSchema() {
|
|
|
2737
2849
|
sql: `UPDATE tasks SET project_name = 'exe-os' WHERE project_name = 'worker'`,
|
|
2738
2850
|
args: []
|
|
2739
2851
|
});
|
|
2740
|
-
} catch {
|
|
2852
|
+
} catch (e) {
|
|
2853
|
+
logCatchDebug("migration", e);
|
|
2741
2854
|
}
|
|
2742
2855
|
await client.executeMultiple(`
|
|
2743
2856
|
CREATE TABLE IF NOT EXISTS trajectories (
|
|
@@ -2761,7 +2874,8 @@ async function ensureSchema() {
|
|
|
2761
2874
|
`);
|
|
2762
2875
|
try {
|
|
2763
2876
|
await client.execute("ALTER TABLE trajectories ADD COLUMN skill_id TEXT");
|
|
2764
|
-
} catch {
|
|
2877
|
+
} catch (e) {
|
|
2878
|
+
logCatchDebug("migration", e);
|
|
2765
2879
|
}
|
|
2766
2880
|
await client.executeMultiple(`
|
|
2767
2881
|
CREATE TABLE IF NOT EXISTS consolidations (
|
|
@@ -2798,63 +2912,72 @@ async function ensureSchema() {
|
|
|
2798
2912
|
sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
|
|
2799
2913
|
args: []
|
|
2800
2914
|
});
|
|
2801
|
-
} catch {
|
|
2915
|
+
} catch (e) {
|
|
2916
|
+
logCatchDebug("migration", e);
|
|
2802
2917
|
}
|
|
2803
2918
|
try {
|
|
2804
2919
|
await client.execute({
|
|
2805
2920
|
sql: `ALTER TABLE memories ADD COLUMN importance INTEGER DEFAULT 5`,
|
|
2806
2921
|
args: []
|
|
2807
2922
|
});
|
|
2808
|
-
} catch {
|
|
2923
|
+
} catch (e) {
|
|
2924
|
+
logCatchDebug("migration", e);
|
|
2809
2925
|
}
|
|
2810
2926
|
try {
|
|
2811
2927
|
await client.execute({
|
|
2812
2928
|
sql: `ALTER TABLE memories ADD COLUMN status TEXT DEFAULT 'active'`,
|
|
2813
2929
|
args: []
|
|
2814
2930
|
});
|
|
2815
|
-
} catch {
|
|
2931
|
+
} catch (e) {
|
|
2932
|
+
logCatchDebug("migration", e);
|
|
2816
2933
|
}
|
|
2817
2934
|
try {
|
|
2818
2935
|
await client.execute({
|
|
2819
2936
|
sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
|
|
2820
2937
|
args: []
|
|
2821
2938
|
});
|
|
2822
|
-
} catch {
|
|
2939
|
+
} catch (e) {
|
|
2940
|
+
logCatchDebug("migration", e);
|
|
2823
2941
|
}
|
|
2824
2942
|
try {
|
|
2825
2943
|
await client.execute({
|
|
2826
2944
|
sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
|
|
2827
2945
|
args: []
|
|
2828
2946
|
});
|
|
2829
|
-
} catch {
|
|
2947
|
+
} catch (e) {
|
|
2948
|
+
logCatchDebug("migration", e);
|
|
2830
2949
|
}
|
|
2831
2950
|
try {
|
|
2832
2951
|
await client.execute({
|
|
2833
2952
|
sql: `ALTER TABLE memories ADD COLUMN last_accessed TEXT`,
|
|
2834
2953
|
args: []
|
|
2835
2954
|
});
|
|
2836
|
-
} catch {
|
|
2955
|
+
} catch (e) {
|
|
2956
|
+
logCatchDebug("migration", e);
|
|
2837
2957
|
}
|
|
2838
2958
|
try {
|
|
2839
2959
|
await client.execute({
|
|
2840
2960
|
sql: `UPDATE memories SET last_accessed = timestamp WHERE last_accessed IS NULL`,
|
|
2841
2961
|
args: []
|
|
2842
2962
|
});
|
|
2843
|
-
} catch {
|
|
2963
|
+
} catch (e) {
|
|
2964
|
+
logCatchDebug("migration", e);
|
|
2844
2965
|
}
|
|
2845
2966
|
try {
|
|
2846
2967
|
await client.execute({
|
|
2847
2968
|
sql: `ALTER TABLE memories ADD COLUMN wiki_synced INTEGER DEFAULT 0`,
|
|
2848
2969
|
args: []
|
|
2849
2970
|
});
|
|
2850
|
-
} catch {
|
|
2971
|
+
} catch (e) {
|
|
2972
|
+
logCatchDebug("migration", e);
|
|
2851
2973
|
}
|
|
2852
2974
|
try {
|
|
2853
2975
|
await client.execute({
|
|
2854
2976
|
sql: `ALTER TABLE memories ADD COLUMN graph_extracted INTEGER DEFAULT 0`,
|
|
2855
2977
|
args: []
|
|
2856
2978
|
});
|
|
2857
|
-
} catch {
|
|
2979
|
+
} catch (e) {
|
|
2980
|
+
logCatchDebug("migration", e);
|
|
2858
2981
|
}
|
|
2859
2982
|
for (const col of [
|
|
2860
2983
|
"ALTER TABLE memories ADD COLUMN content_hash TEXT",
|
|
@@ -2862,14 +2985,16 @@ async function ensureSchema() {
|
|
|
2862
2985
|
]) {
|
|
2863
2986
|
try {
|
|
2864
2987
|
await client.execute(col);
|
|
2865
|
-
} catch {
|
|
2988
|
+
} catch (e) {
|
|
2989
|
+
logCatchDebug("migration", e);
|
|
2866
2990
|
}
|
|
2867
2991
|
}
|
|
2868
2992
|
try {
|
|
2869
2993
|
await client.execute(
|
|
2870
2994
|
`CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash, agent_id)`
|
|
2871
2995
|
);
|
|
2872
|
-
} catch {
|
|
2996
|
+
} catch (e) {
|
|
2997
|
+
logCatchDebug("migration", e);
|
|
2873
2998
|
}
|
|
2874
2999
|
try {
|
|
2875
3000
|
await client.execute(
|
|
@@ -2877,7 +3002,8 @@ async function ensureSchema() {
|
|
|
2877
3002
|
ON memories(content_hash, agent_id, project_name, memory_type)
|
|
2878
3003
|
WHERE content_hash IS NOT NULL`
|
|
2879
3004
|
);
|
|
2880
|
-
} catch {
|
|
3005
|
+
} catch (e) {
|
|
3006
|
+
logCatchDebug("migration", e);
|
|
2881
3007
|
}
|
|
2882
3008
|
await client.executeMultiple(`
|
|
2883
3009
|
CREATE TABLE IF NOT EXISTS entities (
|
|
@@ -2953,7 +3079,8 @@ async function ensureSchema() {
|
|
|
2953
3079
|
`);
|
|
2954
3080
|
try {
|
|
2955
3081
|
await client.execute("INSERT INTO entities_fts(entities_fts) VALUES('rebuild')");
|
|
2956
|
-
} catch {
|
|
3082
|
+
} catch (e) {
|
|
3083
|
+
logCatchDebug("migration", e);
|
|
2957
3084
|
}
|
|
2958
3085
|
await client.executeMultiple(`
|
|
2959
3086
|
CREATE TABLE IF NOT EXISTS entity_aliases (
|
|
@@ -2968,14 +3095,16 @@ async function ensureSchema() {
|
|
|
2968
3095
|
]) {
|
|
2969
3096
|
try {
|
|
2970
3097
|
await client.execute(col);
|
|
2971
|
-
} catch {
|
|
3098
|
+
} catch (e) {
|
|
3099
|
+
logCatchDebug("migration", e);
|
|
2972
3100
|
}
|
|
2973
3101
|
}
|
|
2974
3102
|
try {
|
|
2975
3103
|
await client.execute(
|
|
2976
3104
|
`CREATE INDEX IF NOT EXISTS idx_memories_status ON memories(status)`
|
|
2977
3105
|
);
|
|
2978
|
-
} catch {
|
|
3106
|
+
} catch (e) {
|
|
3107
|
+
logCatchDebug("migration", e);
|
|
2979
3108
|
}
|
|
2980
3109
|
await client.executeMultiple(`
|
|
2981
3110
|
CREATE TABLE IF NOT EXISTS identity (
|
|
@@ -3074,7 +3203,8 @@ async function ensureSchema() {
|
|
|
3074
3203
|
sql: `ALTER TABLE memories ADD COLUMN ${column}`,
|
|
3075
3204
|
args: []
|
|
3076
3205
|
});
|
|
3077
|
-
} catch {
|
|
3206
|
+
} catch (e) {
|
|
3207
|
+
logCatchDebug("migration", e);
|
|
3078
3208
|
}
|
|
3079
3209
|
}
|
|
3080
3210
|
for (const col of [
|
|
@@ -3083,7 +3213,8 @@ async function ensureSchema() {
|
|
|
3083
3213
|
]) {
|
|
3084
3214
|
try {
|
|
3085
3215
|
await client.execute(col);
|
|
3086
|
-
} catch {
|
|
3216
|
+
} catch (e) {
|
|
3217
|
+
logCatchDebug("migration", e);
|
|
3087
3218
|
}
|
|
3088
3219
|
}
|
|
3089
3220
|
await client.executeMultiple(`
|
|
@@ -3268,56 +3399,64 @@ async function ensureSchema() {
|
|
|
3268
3399
|
args: []
|
|
3269
3400
|
});
|
|
3270
3401
|
}
|
|
3271
|
-
} catch {
|
|
3402
|
+
} catch (e) {
|
|
3403
|
+
logCatchDebug("session_agent_map backfill", e);
|
|
3272
3404
|
}
|
|
3273
3405
|
try {
|
|
3274
3406
|
await client.execute({
|
|
3275
3407
|
sql: `ALTER TABLE session_agent_map ADD COLUMN cache_cold_count INTEGER NOT NULL DEFAULT 0`,
|
|
3276
3408
|
args: []
|
|
3277
3409
|
});
|
|
3278
|
-
} catch {
|
|
3410
|
+
} catch (e) {
|
|
3411
|
+
logCatchDebug("migration", e);
|
|
3279
3412
|
}
|
|
3280
3413
|
try {
|
|
3281
3414
|
await client.execute({
|
|
3282
3415
|
sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
|
|
3283
3416
|
args: []
|
|
3284
3417
|
});
|
|
3285
|
-
} catch {
|
|
3418
|
+
} catch (e) {
|
|
3419
|
+
logCatchDebug("migration", e);
|
|
3286
3420
|
}
|
|
3287
3421
|
try {
|
|
3288
3422
|
await client.execute({
|
|
3289
3423
|
sql: `ALTER TABLE tasks ADD COLUMN budget_fallback_model TEXT`,
|
|
3290
3424
|
args: []
|
|
3291
3425
|
});
|
|
3292
|
-
} catch {
|
|
3426
|
+
} catch (e) {
|
|
3427
|
+
logCatchDebug("migration", e);
|
|
3293
3428
|
}
|
|
3294
3429
|
try {
|
|
3295
3430
|
await client.execute({
|
|
3296
3431
|
sql: `ALTER TABLE tasks ADD COLUMN tokens_used INTEGER DEFAULT 0`,
|
|
3297
3432
|
args: []
|
|
3298
3433
|
});
|
|
3299
|
-
} catch {
|
|
3434
|
+
} catch (e) {
|
|
3435
|
+
logCatchDebug("migration", e);
|
|
3300
3436
|
}
|
|
3301
3437
|
try {
|
|
3302
3438
|
await client.execute({
|
|
3303
3439
|
sql: `ALTER TABLE tasks ADD COLUMN tokens_warned_at INTEGER`,
|
|
3304
3440
|
args: []
|
|
3305
3441
|
});
|
|
3306
|
-
} catch {
|
|
3442
|
+
} catch (e) {
|
|
3443
|
+
logCatchDebug("migration", e);
|
|
3307
3444
|
}
|
|
3308
3445
|
try {
|
|
3309
3446
|
await client.execute({
|
|
3310
3447
|
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
3311
3448
|
args: []
|
|
3312
3449
|
});
|
|
3313
|
-
} catch {
|
|
3450
|
+
} catch (e) {
|
|
3451
|
+
logCatchDebug("migration", e);
|
|
3314
3452
|
}
|
|
3315
3453
|
try {
|
|
3316
3454
|
await client.execute({
|
|
3317
3455
|
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
3318
3456
|
args: []
|
|
3319
3457
|
});
|
|
3320
|
-
} catch {
|
|
3458
|
+
} catch (e) {
|
|
3459
|
+
logCatchDebug("migration", e);
|
|
3321
3460
|
}
|
|
3322
3461
|
await client.executeMultiple(`
|
|
3323
3462
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
@@ -3516,13 +3655,15 @@ async function ensureSchema() {
|
|
|
3516
3655
|
sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
|
|
3517
3656
|
args: []
|
|
3518
3657
|
});
|
|
3519
|
-
} catch {
|
|
3658
|
+
} catch (e) {
|
|
3659
|
+
logCatchDebug("migration", e);
|
|
3520
3660
|
}
|
|
3521
3661
|
try {
|
|
3522
3662
|
await client.execute(
|
|
3523
3663
|
`CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)`
|
|
3524
3664
|
);
|
|
3525
|
-
} catch {
|
|
3665
|
+
} catch (e) {
|
|
3666
|
+
logCatchDebug("migration", e);
|
|
3526
3667
|
}
|
|
3527
3668
|
try {
|
|
3528
3669
|
await client.execute({
|
|
@@ -3533,20 +3674,23 @@ async function ensureSchema() {
|
|
|
3533
3674
|
sql: `UPDATE memories SET tier = 2 WHERE tool_name IN ('store_memory', 'manual') AND importance >= 5 AND tier = 3`,
|
|
3534
3675
|
args: []
|
|
3535
3676
|
});
|
|
3536
|
-
} catch {
|
|
3677
|
+
} catch (e) {
|
|
3678
|
+
logCatchDebug("migration", e);
|
|
3537
3679
|
}
|
|
3538
3680
|
try {
|
|
3539
3681
|
await client.execute({
|
|
3540
3682
|
sql: `ALTER TABLE memories ADD COLUMN supersedes_id TEXT`,
|
|
3541
3683
|
args: []
|
|
3542
3684
|
});
|
|
3543
|
-
} catch {
|
|
3685
|
+
} catch (e) {
|
|
3686
|
+
logCatchDebug("migration", e);
|
|
3544
3687
|
}
|
|
3545
3688
|
try {
|
|
3546
3689
|
await client.execute(
|
|
3547
3690
|
`CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL`
|
|
3548
3691
|
);
|
|
3549
|
-
} catch {
|
|
3692
|
+
} catch (e) {
|
|
3693
|
+
logCatchDebug("migration", e);
|
|
3550
3694
|
}
|
|
3551
3695
|
for (const col of [
|
|
3552
3696
|
"ALTER TABLE tasks ADD COLUMN checkpoint TEXT",
|
|
@@ -3554,7 +3698,8 @@ async function ensureSchema() {
|
|
|
3554
3698
|
]) {
|
|
3555
3699
|
try {
|
|
3556
3700
|
await client.execute(col);
|
|
3557
|
-
} catch {
|
|
3701
|
+
} catch (e) {
|
|
3702
|
+
logCatchDebug("migration", e);
|
|
3558
3703
|
}
|
|
3559
3704
|
}
|
|
3560
3705
|
try {
|
|
@@ -3562,13 +3707,15 @@ async function ensureSchema() {
|
|
|
3562
3707
|
sql: `ALTER TABLE memories ADD COLUMN draft INTEGER DEFAULT 0`,
|
|
3563
3708
|
args: []
|
|
3564
3709
|
});
|
|
3565
|
-
} catch {
|
|
3710
|
+
} catch (e) {
|
|
3711
|
+
logCatchDebug("migration", e);
|
|
3566
3712
|
}
|
|
3567
3713
|
try {
|
|
3568
3714
|
await client.execute(
|
|
3569
3715
|
`CREATE INDEX IF NOT EXISTS idx_memories_draft ON memories(draft) WHERE draft = 1`
|
|
3570
3716
|
);
|
|
3571
|
-
} catch {
|
|
3717
|
+
} catch (e) {
|
|
3718
|
+
logCatchDebug("migration", e);
|
|
3572
3719
|
}
|
|
3573
3720
|
for (const col of [
|
|
3574
3721
|
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
@@ -3576,7 +3723,8 @@ async function ensureSchema() {
|
|
|
3576
3723
|
]) {
|
|
3577
3724
|
try {
|
|
3578
3725
|
await client.execute(col);
|
|
3579
|
-
} catch {
|
|
3726
|
+
} catch (e) {
|
|
3727
|
+
logCatchDebug("migration", e);
|
|
3580
3728
|
}
|
|
3581
3729
|
}
|
|
3582
3730
|
try {
|
|
@@ -3584,27 +3732,31 @@ async function ensureSchema() {
|
|
|
3584
3732
|
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3585
3733
|
args: []
|
|
3586
3734
|
});
|
|
3587
|
-
} catch {
|
|
3735
|
+
} catch (e) {
|
|
3736
|
+
logCatchDebug("migration", e);
|
|
3588
3737
|
}
|
|
3589
3738
|
try {
|
|
3590
3739
|
await client.execute({
|
|
3591
3740
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
3592
3741
|
args: []
|
|
3593
3742
|
});
|
|
3594
|
-
} catch {
|
|
3743
|
+
} catch (e) {
|
|
3744
|
+
logCatchDebug("migration", e);
|
|
3595
3745
|
}
|
|
3596
3746
|
try {
|
|
3597
3747
|
await client.execute(
|
|
3598
3748
|
`CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(memory_type)`
|
|
3599
3749
|
);
|
|
3600
|
-
} catch {
|
|
3750
|
+
} catch (e) {
|
|
3751
|
+
logCatchDebug("migration", e);
|
|
3601
3752
|
}
|
|
3602
3753
|
try {
|
|
3603
3754
|
await client.execute({
|
|
3604
3755
|
sql: `ALTER TABLE memories ADD COLUMN trajectory TEXT`,
|
|
3605
3756
|
args: []
|
|
3606
3757
|
});
|
|
3607
|
-
} catch {
|
|
3758
|
+
} catch (e) {
|
|
3759
|
+
logCatchDebug("migration", e);
|
|
3608
3760
|
}
|
|
3609
3761
|
for (const col of [
|
|
3610
3762
|
"ALTER TABLE memories ADD COLUMN intent TEXT",
|
|
@@ -3625,7 +3777,8 @@ async function ensureSchema() {
|
|
|
3625
3777
|
]) {
|
|
3626
3778
|
try {
|
|
3627
3779
|
await client.execute(col);
|
|
3628
|
-
} catch {
|
|
3780
|
+
} catch (e) {
|
|
3781
|
+
logCatchDebug("migration", e);
|
|
3629
3782
|
}
|
|
3630
3783
|
}
|
|
3631
3784
|
try {
|
|
@@ -3633,14 +3786,16 @@ async function ensureSchema() {
|
|
|
3633
3786
|
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3634
3787
|
args: []
|
|
3635
3788
|
});
|
|
3636
|
-
} catch {
|
|
3789
|
+
} catch (e) {
|
|
3790
|
+
logCatchDebug("migration", e);
|
|
3637
3791
|
}
|
|
3638
3792
|
try {
|
|
3639
3793
|
await client.execute({
|
|
3640
3794
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
3641
3795
|
args: []
|
|
3642
3796
|
});
|
|
3643
|
-
} catch {
|
|
3797
|
+
} catch (e) {
|
|
3798
|
+
logCatchDebug("migration", e);
|
|
3644
3799
|
}
|
|
3645
3800
|
}
|
|
3646
3801
|
async function disposeDatabase() {
|
|
@@ -3651,7 +3806,8 @@ async function disposeDatabase() {
|
|
|
3651
3806
|
if (_client) {
|
|
3652
3807
|
try {
|
|
3653
3808
|
await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3654
|
-
} catch {
|
|
3809
|
+
} catch (e) {
|
|
3810
|
+
logCatchDebug("WAL checkpoint", e);
|
|
3655
3811
|
}
|
|
3656
3812
|
}
|
|
3657
3813
|
if (_daemonClient) {
|
|
@@ -3667,8 +3823,9 @@ async function disposeDatabase() {
|
|
|
3667
3823
|
_client = null;
|
|
3668
3824
|
_resilientClient = null;
|
|
3669
3825
|
}
|
|
3826
|
+
releaseDbLock();
|
|
3670
3827
|
}
|
|
3671
|
-
var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
|
|
3828
|
+
var _debugDb, _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, _lockFd, DB_LOCK_PATH, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
|
|
3672
3829
|
var init_database = __esm({
|
|
3673
3830
|
"src/lib/database.ts"() {
|
|
3674
3831
|
"use strict";
|
|
@@ -3676,11 +3833,14 @@ var init_database = __esm({
|
|
|
3676
3833
|
init_employees();
|
|
3677
3834
|
init_database_adapter();
|
|
3678
3835
|
init_memory();
|
|
3836
|
+
_debugDb = process.env.EXE_DEBUG === "1";
|
|
3679
3837
|
_client = null;
|
|
3680
3838
|
_resilientClient = null;
|
|
3681
3839
|
_walCheckpointTimer = null;
|
|
3682
3840
|
_daemonClient = null;
|
|
3683
3841
|
_adapterClient = null;
|
|
3842
|
+
_lockFd = null;
|
|
3843
|
+
DB_LOCK_PATH = join(homedir(), ".exe-os", "db.lock");
|
|
3684
3844
|
initTurso = initDatabase;
|
|
3685
3845
|
SOFT_DELETE_RETENTION_DAYS = 7;
|
|
3686
3846
|
disposeTurso = disposeDatabase;
|
|
@@ -3688,7 +3848,7 @@ var init_database = __esm({
|
|
|
3688
3848
|
});
|
|
3689
3849
|
|
|
3690
3850
|
// src/lib/license.ts
|
|
3691
|
-
import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as
|
|
3851
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync10, mkdirSync as mkdirSync5 } from "fs";
|
|
3692
3852
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
3693
3853
|
import { createRequire as createRequire2 } from "module";
|
|
3694
3854
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
@@ -3715,11 +3875,11 @@ var init_license = __esm({
|
|
|
3715
3875
|
});
|
|
3716
3876
|
|
|
3717
3877
|
// src/lib/plan-limits.ts
|
|
3718
|
-
import { readFileSync as readFileSync9, existsSync as
|
|
3878
|
+
import { readFileSync as readFileSync9, existsSync as existsSync11 } from "fs";
|
|
3719
3879
|
import path11 from "path";
|
|
3720
3880
|
function getLicenseSync() {
|
|
3721
3881
|
try {
|
|
3722
|
-
if (!
|
|
3882
|
+
if (!existsSync11(CACHE_PATH2)) return freeLicense();
|
|
3723
3883
|
const raw = JSON.parse(readFileSync9(CACHE_PATH2, "utf8"));
|
|
3724
3884
|
if (!raw.token || typeof raw.token !== "string") return freeLicense();
|
|
3725
3885
|
const parts = raw.token.split(".");
|
|
@@ -3758,7 +3918,7 @@ function assertEmployeeLimitSync(rosterPath) {
|
|
|
3758
3918
|
const filePath = rosterPath ?? EMPLOYEES_PATH;
|
|
3759
3919
|
let count = 0;
|
|
3760
3920
|
try {
|
|
3761
|
-
if (
|
|
3921
|
+
if (existsSync11(filePath)) {
|
|
3762
3922
|
const raw = readFileSync9(filePath, "utf8");
|
|
3763
3923
|
const employees = JSON.parse(raw);
|
|
3764
3924
|
count = Array.isArray(employees) ? employees.length : 0;
|
|
@@ -3796,9 +3956,9 @@ var init_plan_limits = __esm({
|
|
|
3796
3956
|
import os9 from "os";
|
|
3797
3957
|
import path12 from "path";
|
|
3798
3958
|
import {
|
|
3799
|
-
existsSync as
|
|
3959
|
+
existsSync as existsSync12,
|
|
3800
3960
|
lstatSync,
|
|
3801
|
-
mkdirSync as
|
|
3961
|
+
mkdirSync as mkdirSync6,
|
|
3802
3962
|
readlinkSync as readlinkSync2,
|
|
3803
3963
|
symlinkSync as symlinkSync2
|
|
3804
3964
|
} from "fs";
|
|
@@ -3814,8 +3974,8 @@ function claudeAgentLinkPath(homeDir, agentId) {
|
|
|
3814
3974
|
function ensureAgentSymlink(agentId, homeDir = os9.homedir()) {
|
|
3815
3975
|
const target = identitySourcePath(homeDir, agentId);
|
|
3816
3976
|
const link = claudeAgentLinkPath(homeDir, agentId);
|
|
3817
|
-
|
|
3818
|
-
if (
|
|
3977
|
+
mkdirSync6(claudeAgentsDir(homeDir), { recursive: true });
|
|
3978
|
+
if (existsSync12(link)) {
|
|
3819
3979
|
let stat;
|
|
3820
3980
|
try {
|
|
3821
3981
|
stat = lstatSync(link);
|
|
@@ -3902,8 +4062,8 @@ import os10 from "os";
|
|
|
3902
4062
|
import {
|
|
3903
4063
|
readFileSync as readFileSync10,
|
|
3904
4064
|
readdirSync,
|
|
3905
|
-
unlinkSync as
|
|
3906
|
-
existsSync as
|
|
4065
|
+
unlinkSync as unlinkSync4,
|
|
4066
|
+
existsSync as existsSync13,
|
|
3907
4067
|
rmdirSync
|
|
3908
4068
|
} from "fs";
|
|
3909
4069
|
async function writeNotification(notification) {
|
|
@@ -4151,7 +4311,7 @@ import path15 from "path";
|
|
|
4151
4311
|
import os11 from "os";
|
|
4152
4312
|
import { execSync as execSync7 } from "child_process";
|
|
4153
4313
|
import { mkdir as mkdir3, writeFile as writeFile3, appendFile } from "fs/promises";
|
|
4154
|
-
import { existsSync as
|
|
4314
|
+
import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
|
|
4155
4315
|
async function writeCheckpoint(input) {
|
|
4156
4316
|
const client = getClient();
|
|
4157
4317
|
const row = await resolveTask(client, input.taskId);
|
|
@@ -4392,7 +4552,7 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
4392
4552
|
const EXE_OS_DIR = path15.join(os11.homedir(), ".exe-os");
|
|
4393
4553
|
const mdPath = path15.join(EXE_OS_DIR, taskFile);
|
|
4394
4554
|
const mdDir = path15.dirname(mdPath);
|
|
4395
|
-
if (!
|
|
4555
|
+
if (!existsSync14(mdDir)) await mkdir3(mdDir, { recursive: true });
|
|
4396
4556
|
const reviewer = input.reviewer ?? input.assignedBy;
|
|
4397
4557
|
const mdContent = `# ${input.title}
|
|
4398
4558
|
|
|
@@ -4698,7 +4858,7 @@ async function deleteTaskCore(taskId, _baseDir) {
|
|
|
4698
4858
|
async function ensureArchitectureDoc(baseDir, projectName) {
|
|
4699
4859
|
const archPath = path15.join(baseDir, "exe", "ARCHITECTURE.md");
|
|
4700
4860
|
try {
|
|
4701
|
-
if (
|
|
4861
|
+
if (existsSync14(archPath)) return;
|
|
4702
4862
|
const template = [
|
|
4703
4863
|
`# ${projectName} \u2014 System Architecture`,
|
|
4704
4864
|
"",
|
|
@@ -4733,7 +4893,7 @@ async function ensureArchitectureDoc(baseDir, projectName) {
|
|
|
4733
4893
|
async function ensureGitignoreExe(baseDir) {
|
|
4734
4894
|
const gitignorePath = path15.join(baseDir, ".gitignore");
|
|
4735
4895
|
try {
|
|
4736
|
-
if (
|
|
4896
|
+
if (existsSync14(gitignorePath)) {
|
|
4737
4897
|
const content = readFileSync11(gitignorePath, "utf-8");
|
|
4738
4898
|
if (/^\/?exe\/?$/m.test(content)) return;
|
|
4739
4899
|
await appendFile(gitignorePath, "\n# Employee task assignments (private)\n/exe/\n");
|
|
@@ -4778,7 +4938,7 @@ __export(tasks_review_exports, {
|
|
|
4778
4938
|
listPendingReviews: () => listPendingReviews
|
|
4779
4939
|
});
|
|
4780
4940
|
import path16 from "path";
|
|
4781
|
-
import { existsSync as
|
|
4941
|
+
import { existsSync as existsSync15, readdirSync as readdirSync2, unlinkSync as unlinkSync5 } from "fs";
|
|
4782
4942
|
function formatAge(isoTimestamp) {
|
|
4783
4943
|
if (!isoTimestamp) return "";
|
|
4784
4944
|
const ms = Date.now() - new Date(isoTimestamp).getTime();
|
|
@@ -5048,10 +5208,10 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
5048
5208
|
}
|
|
5049
5209
|
try {
|
|
5050
5210
|
const cacheDir = path16.join(EXE_AI_DIR, "session-cache");
|
|
5051
|
-
if (
|
|
5211
|
+
if (existsSync15(cacheDir)) {
|
|
5052
5212
|
for (const f of readdirSync2(cacheDir)) {
|
|
5053
5213
|
if (f.startsWith("review-notified-")) {
|
|
5054
|
-
|
|
5214
|
+
unlinkSync5(path16.join(cacheDir, f));
|
|
5055
5215
|
}
|
|
5056
5216
|
}
|
|
5057
5217
|
}
|
|
@@ -5274,10 +5434,10 @@ async function disposeEmbedder() {
|
|
|
5274
5434
|
async function embedDirect(text) {
|
|
5275
5435
|
const llamaCpp = await import("node-llama-cpp");
|
|
5276
5436
|
const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
5277
|
-
const { existsSync:
|
|
5437
|
+
const { existsSync: existsSync19 } = await import("fs");
|
|
5278
5438
|
const path22 = await import("path");
|
|
5279
5439
|
const modelPath = path22.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
|
|
5280
|
-
if (!
|
|
5440
|
+
if (!existsSync19(modelPath)) {
|
|
5281
5441
|
throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
|
|
5282
5442
|
}
|
|
5283
5443
|
const llama = await llamaCpp.getLlama();
|
|
@@ -5715,7 +5875,7 @@ __export(tasks_exports, {
|
|
|
5715
5875
|
writeCheckpoint: () => writeCheckpoint
|
|
5716
5876
|
});
|
|
5717
5877
|
import path18 from "path";
|
|
5718
|
-
import { writeFileSync as writeFileSync7, mkdirSync as
|
|
5878
|
+
import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, unlinkSync as unlinkSync6 } from "fs";
|
|
5719
5879
|
async function createTask(input) {
|
|
5720
5880
|
const result = await createTaskCore(input);
|
|
5721
5881
|
if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
|
|
@@ -5737,11 +5897,11 @@ async function updateTask(input) {
|
|
|
5737
5897
|
const cacheDir = path18.join(EXE_AI_DIR, "session-cache");
|
|
5738
5898
|
const cachePath = path18.join(cacheDir, `current-task-${agent}.json`);
|
|
5739
5899
|
if (input.status === "in_progress") {
|
|
5740
|
-
|
|
5900
|
+
mkdirSync7(cacheDir, { recursive: true });
|
|
5741
5901
|
writeFileSync7(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
|
|
5742
5902
|
} else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled" || input.status === "closed") {
|
|
5743
5903
|
try {
|
|
5744
|
-
|
|
5904
|
+
unlinkSync6(cachePath);
|
|
5745
5905
|
} catch {
|
|
5746
5906
|
}
|
|
5747
5907
|
}
|
|
@@ -6209,11 +6369,11 @@ __export(tmux_routing_exports, {
|
|
|
6209
6369
|
verifyPaneAtCapacity: () => verifyPaneAtCapacity
|
|
6210
6370
|
});
|
|
6211
6371
|
import { execFileSync as execFileSync2, execSync as execSync8 } from "child_process";
|
|
6212
|
-
import { readFileSync as readFileSync12, writeFileSync as writeFileSync8, mkdirSync as
|
|
6372
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync8, mkdirSync as mkdirSync8, existsSync as existsSync16, appendFileSync, readdirSync as readdirSync3 } from "fs";
|
|
6213
6373
|
import path19 from "path";
|
|
6214
6374
|
import os12 from "os";
|
|
6215
6375
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
6216
|
-
import { unlinkSync as
|
|
6376
|
+
import { unlinkSync as unlinkSync7 } from "fs";
|
|
6217
6377
|
function spawnLockPath(sessionName) {
|
|
6218
6378
|
return path19.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
|
|
6219
6379
|
}
|
|
@@ -6226,11 +6386,11 @@ function isProcessAlive(pid) {
|
|
|
6226
6386
|
}
|
|
6227
6387
|
}
|
|
6228
6388
|
function acquireSpawnLock2(sessionName) {
|
|
6229
|
-
if (!
|
|
6230
|
-
|
|
6389
|
+
if (!existsSync16(SPAWN_LOCK_DIR)) {
|
|
6390
|
+
mkdirSync8(SPAWN_LOCK_DIR, { recursive: true });
|
|
6231
6391
|
}
|
|
6232
6392
|
const lockFile = spawnLockPath(sessionName);
|
|
6233
|
-
if (
|
|
6393
|
+
if (existsSync16(lockFile)) {
|
|
6234
6394
|
try {
|
|
6235
6395
|
const lock = JSON.parse(readFileSync12(lockFile, "utf8"));
|
|
6236
6396
|
const age = Date.now() - lock.timestamp;
|
|
@@ -6245,7 +6405,7 @@ function acquireSpawnLock2(sessionName) {
|
|
|
6245
6405
|
}
|
|
6246
6406
|
function releaseSpawnLock2(sessionName) {
|
|
6247
6407
|
try {
|
|
6248
|
-
|
|
6408
|
+
unlinkSync7(spawnLockPath(sessionName));
|
|
6249
6409
|
} catch {
|
|
6250
6410
|
}
|
|
6251
6411
|
}
|
|
@@ -6258,7 +6418,7 @@ function resolveBehaviorsExporterScript() {
|
|
|
6258
6418
|
"bin",
|
|
6259
6419
|
"exe-export-behaviors.js"
|
|
6260
6420
|
);
|
|
6261
|
-
return
|
|
6421
|
+
return existsSync16(scriptPath) ? scriptPath : null;
|
|
6262
6422
|
} catch {
|
|
6263
6423
|
return null;
|
|
6264
6424
|
}
|
|
@@ -6324,8 +6484,8 @@ function extractRootExe(name) {
|
|
|
6324
6484
|
return parts.length > 0 ? parts[parts.length - 1] : null;
|
|
6325
6485
|
}
|
|
6326
6486
|
function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
6327
|
-
if (!
|
|
6328
|
-
|
|
6487
|
+
if (!existsSync16(SESSION_CACHE)) {
|
|
6488
|
+
mkdirSync8(SESSION_CACHE, { recursive: true });
|
|
6329
6489
|
}
|
|
6330
6490
|
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
6331
6491
|
const filePath = path19.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
@@ -6355,11 +6515,13 @@ function getDispatchedBy(sessionKey) {
|
|
|
6355
6515
|
}
|
|
6356
6516
|
}
|
|
6357
6517
|
function resolveExeSession() {
|
|
6358
|
-
if (process.env.EXE_SESSION_NAME) {
|
|
6359
|
-
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
6360
|
-
}
|
|
6361
6518
|
const mySession = getMySession();
|
|
6362
|
-
if (!mySession)
|
|
6519
|
+
if (!mySession) {
|
|
6520
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
6521
|
+
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
6522
|
+
}
|
|
6523
|
+
return null;
|
|
6524
|
+
}
|
|
6363
6525
|
const fromSessionName = extractRootExe(mySession);
|
|
6364
6526
|
let candidate = null;
|
|
6365
6527
|
try {
|
|
@@ -6454,7 +6616,7 @@ async function verifyPaneAtCapacity(sessionName) {
|
|
|
6454
6616
|
}
|
|
6455
6617
|
function readDebounceState() {
|
|
6456
6618
|
try {
|
|
6457
|
-
if (!
|
|
6619
|
+
if (!existsSync16(DEBOUNCE_FILE)) return {};
|
|
6458
6620
|
const raw = JSON.parse(readFileSync12(DEBOUNCE_FILE, "utf8"));
|
|
6459
6621
|
const state = {};
|
|
6460
6622
|
for (const [key, val] of Object.entries(raw)) {
|
|
@@ -6471,7 +6633,7 @@ function readDebounceState() {
|
|
|
6471
6633
|
}
|
|
6472
6634
|
function writeDebounceState(state) {
|
|
6473
6635
|
try {
|
|
6474
|
-
if (!
|
|
6636
|
+
if (!existsSync16(SESSION_CACHE)) mkdirSync8(SESSION_CACHE, { recursive: true });
|
|
6475
6637
|
writeFileSync8(DEBOUNCE_FILE, JSON.stringify(state));
|
|
6476
6638
|
} catch {
|
|
6477
6639
|
}
|
|
@@ -6572,7 +6734,7 @@ function sendIntercom(targetSession) {
|
|
|
6572
6734
|
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
6573
6735
|
const agent = baseAgentName(rawAgent);
|
|
6574
6736
|
const markerPath = path19.join(SESSION_CACHE, `current-task-${agent}.json`);
|
|
6575
|
-
if (
|
|
6737
|
+
if (existsSync16(markerPath)) {
|
|
6576
6738
|
logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker + not idle \u2014 will auto-chain)`);
|
|
6577
6739
|
return "debounced";
|
|
6578
6740
|
}
|
|
@@ -6583,7 +6745,7 @@ function sendIntercom(targetSession) {
|
|
|
6583
6745
|
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
6584
6746
|
const agent = baseAgentName(rawAgent);
|
|
6585
6747
|
const taskDir = path19.join(process.cwd(), "exe", agent);
|
|
6586
|
-
if (
|
|
6748
|
+
if (existsSync16(taskDir)) {
|
|
6587
6749
|
const files = readdirSync3(taskDir).filter(
|
|
6588
6750
|
(f) => f.endsWith(".md") && f !== "DONE.txt"
|
|
6589
6751
|
);
|
|
@@ -6744,15 +6906,15 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
6744
6906
|
const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
|
|
6745
6907
|
const logDir = path19.join(os12.homedir(), ".exe-os", "session-logs");
|
|
6746
6908
|
const logFile = path19.join(logDir, `${instanceLabel}-${Date.now()}.log`);
|
|
6747
|
-
if (!
|
|
6748
|
-
|
|
6909
|
+
if (!existsSync16(logDir)) {
|
|
6910
|
+
mkdirSync8(logDir, { recursive: true });
|
|
6749
6911
|
}
|
|
6750
6912
|
transport.kill(sessionName);
|
|
6751
6913
|
let cleanupSuffix = "";
|
|
6752
6914
|
try {
|
|
6753
6915
|
const thisFile = fileURLToPath2(import.meta.url);
|
|
6754
6916
|
const cleanupScript = path19.join(path19.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
|
|
6755
|
-
if (
|
|
6917
|
+
if (existsSync16(cleanupScript)) {
|
|
6756
6918
|
cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
|
|
6757
6919
|
}
|
|
6758
6920
|
} catch {
|
|
@@ -6807,7 +6969,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
6807
6969
|
if (changed) {
|
|
6808
6970
|
perms.allow = allow;
|
|
6809
6971
|
settings.permissions = perms;
|
|
6810
|
-
|
|
6972
|
+
mkdirSync8(projSettingsDir, { recursive: true });
|
|
6811
6973
|
writeFileSync8(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
6812
6974
|
}
|
|
6813
6975
|
} catch {
|
|
@@ -6845,7 +7007,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
6845
7007
|
`
|
|
6846
7008
|
);
|
|
6847
7009
|
}
|
|
6848
|
-
} else if (
|
|
7010
|
+
} else if (existsSync16(identityPath)) {
|
|
6849
7011
|
identityFlag = ` --append-system-prompt-file ${identityPath}`;
|
|
6850
7012
|
legacyFallbackWarned = true;
|
|
6851
7013
|
}
|
|
@@ -6867,7 +7029,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
6867
7029
|
let sessionContextFlag = "";
|
|
6868
7030
|
try {
|
|
6869
7031
|
const ctxDir = path19.join(os12.homedir(), ".exe-os", "session-cache");
|
|
6870
|
-
|
|
7032
|
+
mkdirSync8(ctxDir, { recursive: true });
|
|
6871
7033
|
const ctxFile = path19.join(ctxDir, `session-context-${sessionName}.md`);
|
|
6872
7034
|
const ctxContent = [
|
|
6873
7035
|
`## Session Context`,
|
|
@@ -7050,7 +7212,7 @@ var init_tmux_routing = __esm({
|
|
|
7050
7212
|
|
|
7051
7213
|
// src/lib/keychain.ts
|
|
7052
7214
|
import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
|
|
7053
|
-
import { existsSync as
|
|
7215
|
+
import { existsSync as existsSync17, statSync as statSync3 } from "fs";
|
|
7054
7216
|
import { execSync as execSync9 } from "child_process";
|
|
7055
7217
|
import path20 from "path";
|
|
7056
7218
|
import os13 from "os";
|
|
@@ -7085,7 +7247,7 @@ function isRootOnlyTrustedServerKeyFile(keyPath) {
|
|
|
7085
7247
|
if (process.platform !== "linux") return false;
|
|
7086
7248
|
try {
|
|
7087
7249
|
const uid = typeof os13.userInfo().uid === "number" ? os13.userInfo().uid : -1;
|
|
7088
|
-
const st =
|
|
7250
|
+
const st = statSync3(keyPath);
|
|
7089
7251
|
if (!st.isFile() || (st.mode & 63) !== 0) return false;
|
|
7090
7252
|
if (uid === 0) return true;
|
|
7091
7253
|
const exeOsDir = process.env.EXE_OS_DIR;
|
|
@@ -7286,7 +7448,7 @@ async function getMasterKey() {
|
|
|
7286
7448
|
}
|
|
7287
7449
|
}
|
|
7288
7450
|
const keyPath = getKeyPath();
|
|
7289
|
-
if (!
|
|
7451
|
+
if (!existsSync17(keyPath)) {
|
|
7290
7452
|
process.stderr.write(
|
|
7291
7453
|
`[keychain] Key not found at ${keyPath} (HOME=${os13.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
|
|
7292
7454
|
`
|
|
@@ -7566,18 +7728,54 @@ __export(shard_manager_exports, {
|
|
|
7566
7728
|
shardExists: () => shardExists
|
|
7567
7729
|
});
|
|
7568
7730
|
import path21 from "path";
|
|
7569
|
-
import { existsSync as
|
|
7731
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync9, readdirSync as readdirSync4, renameSync as renameSync4, statSync as statSync4 } from "fs";
|
|
7570
7732
|
import { createClient as createClient2 } from "@libsql/client";
|
|
7571
7733
|
function initShardManager(encryptionKey) {
|
|
7572
7734
|
_encryptionKey = encryptionKey;
|
|
7573
|
-
|
|
7574
|
-
|
|
7735
|
+
_keyValidated = false;
|
|
7736
|
+
_keyValidationPromise = null;
|
|
7737
|
+
if (!existsSync18(SHARDS_DIR)) {
|
|
7738
|
+
mkdirSync9(SHARDS_DIR, { recursive: true });
|
|
7739
|
+
}
|
|
7740
|
+
const existingShards = readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db"));
|
|
7741
|
+
if (existingShards.length === 0) {
|
|
7742
|
+
_keyValidated = true;
|
|
7575
7743
|
}
|
|
7576
7744
|
_shardingEnabled = true;
|
|
7577
7745
|
if (_evictionTimer) clearInterval(_evictionTimer);
|
|
7578
7746
|
_evictionTimer = setInterval(evictIdleShards, EVICTION_INTERVAL_MS);
|
|
7579
7747
|
_evictionTimer.unref();
|
|
7580
7748
|
}
|
|
7749
|
+
async function validateEncryptionKey() {
|
|
7750
|
+
if (_keyValidated) return true;
|
|
7751
|
+
if (!_encryptionKey) return false;
|
|
7752
|
+
const existingShards = readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db"));
|
|
7753
|
+
if (existingShards.length === 0) {
|
|
7754
|
+
_keyValidated = true;
|
|
7755
|
+
return true;
|
|
7756
|
+
}
|
|
7757
|
+
for (const shardFile of existingShards.slice(0, 3)) {
|
|
7758
|
+
const dbPath = path21.join(SHARDS_DIR, shardFile);
|
|
7759
|
+
const testClient = createClient2({ url: `file:${dbPath}`, encryptionKey: _encryptionKey });
|
|
7760
|
+
try {
|
|
7761
|
+
await testClient.execute("SELECT COUNT(*) FROM sqlite_schema");
|
|
7762
|
+
testClient.close();
|
|
7763
|
+
_keyValidated = true;
|
|
7764
|
+
return true;
|
|
7765
|
+
} catch {
|
|
7766
|
+
try {
|
|
7767
|
+
testClient.close();
|
|
7768
|
+
} catch {
|
|
7769
|
+
}
|
|
7770
|
+
}
|
|
7771
|
+
}
|
|
7772
|
+
process.stderr.write(
|
|
7773
|
+
`[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.
|
|
7774
|
+
`
|
|
7775
|
+
);
|
|
7776
|
+
_shardingEnabled = false;
|
|
7777
|
+
return false;
|
|
7778
|
+
}
|
|
7581
7779
|
function isShardingEnabled() {
|
|
7582
7780
|
return _shardingEnabled;
|
|
7583
7781
|
}
|
|
@@ -7611,13 +7809,13 @@ function getShardClient(projectName) {
|
|
|
7611
7809
|
}
|
|
7612
7810
|
function shardExists(projectName) {
|
|
7613
7811
|
const safeName = safeShardName(projectName);
|
|
7614
|
-
return
|
|
7812
|
+
return existsSync18(path21.join(SHARDS_DIR, `${safeName}.db`));
|
|
7615
7813
|
}
|
|
7616
7814
|
function safeShardName(projectName) {
|
|
7617
7815
|
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
7618
7816
|
}
|
|
7619
7817
|
function listShards() {
|
|
7620
|
-
if (!
|
|
7818
|
+
if (!existsSync18(SHARDS_DIR)) return [];
|
|
7621
7819
|
return readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
7622
7820
|
}
|
|
7623
7821
|
async function auditShardHealth(options = {}) {
|
|
@@ -7630,7 +7828,7 @@ async function auditShardHealth(options = {}) {
|
|
|
7630
7828
|
const shards = [];
|
|
7631
7829
|
for (const name of names) {
|
|
7632
7830
|
const dbPath = path21.join(SHARDS_DIR, `${name}.db`);
|
|
7633
|
-
const stat =
|
|
7831
|
+
const stat = statSync4(dbPath);
|
|
7634
7832
|
const item = {
|
|
7635
7833
|
name,
|
|
7636
7834
|
path: dbPath,
|
|
@@ -7870,6 +8068,17 @@ async function ensureShardSchema(client) {
|
|
|
7870
8068
|
}
|
|
7871
8069
|
}
|
|
7872
8070
|
async function getReadyShardClient(projectName) {
|
|
8071
|
+
if (!_keyValidated) {
|
|
8072
|
+
if (!_keyValidationPromise) {
|
|
8073
|
+
_keyValidationPromise = validateEncryptionKey();
|
|
8074
|
+
}
|
|
8075
|
+
const valid = await _keyValidationPromise;
|
|
8076
|
+
if (!valid) {
|
|
8077
|
+
throw new Error(
|
|
8078
|
+
`Shard creation blocked: encryption key mismatch with existing shards. Run /exe-doctor to audit.`
|
|
8079
|
+
);
|
|
8080
|
+
}
|
|
8081
|
+
}
|
|
7873
8082
|
const safeName = safeShardName(projectName);
|
|
7874
8083
|
let client = getShardClient(projectName);
|
|
7875
8084
|
try {
|
|
@@ -7882,8 +8091,8 @@ async function getReadyShardClient(projectName) {
|
|
|
7882
8091
|
_shards.delete(safeName);
|
|
7883
8092
|
_shardLastAccess.delete(safeName);
|
|
7884
8093
|
const dbPath = path21.join(SHARDS_DIR, `${safeName}.db`);
|
|
7885
|
-
if (
|
|
7886
|
-
const stat =
|
|
8094
|
+
if (existsSync18(dbPath)) {
|
|
8095
|
+
const stat = statSync4(dbPath);
|
|
7887
8096
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
7888
8097
|
const archivedPath = path21.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
7889
8098
|
renameSync4(dbPath, archivedPath);
|
|
@@ -7948,7 +8157,7 @@ function disposeShards() {
|
|
|
7948
8157
|
_shardingEnabled = false;
|
|
7949
8158
|
_encryptionKey = null;
|
|
7950
8159
|
}
|
|
7951
|
-
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled;
|
|
8160
|
+
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled, _keyValidated, _keyValidationPromise;
|
|
7952
8161
|
var init_shard_manager = __esm({
|
|
7953
8162
|
"src/lib/shard-manager.ts"() {
|
|
7954
8163
|
"use strict";
|
|
@@ -7962,6 +8171,8 @@ var init_shard_manager = __esm({
|
|
|
7962
8171
|
_evictionTimer = null;
|
|
7963
8172
|
_encryptionKey = null;
|
|
7964
8173
|
_shardingEnabled = false;
|
|
8174
|
+
_keyValidated = false;
|
|
8175
|
+
_keyValidationPromise = null;
|
|
7965
8176
|
}
|
|
7966
8177
|
});
|
|
7967
8178
|
|
|
@@ -8157,6 +8368,18 @@ var init_platform_procedures = __esm({
|
|
|
8157
8368
|
priority: "p0",
|
|
8158
8369
|
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.'"
|
|
8159
8370
|
},
|
|
8371
|
+
{
|
|
8372
|
+
title: "Review chain \u2014 managers must actively pull completed work, never wait for nudges",
|
|
8373
|
+
domain: "workflow",
|
|
8374
|
+
priority: "p0",
|
|
8375
|
+
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."
|
|
8376
|
+
},
|
|
8377
|
+
{
|
|
8378
|
+
title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
|
|
8379
|
+
domain: "workflow",
|
|
8380
|
+
priority: "p0",
|
|
8381
|
+
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."
|
|
8382
|
+
},
|
|
8160
8383
|
{
|
|
8161
8384
|
title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
|
|
8162
8385
|
domain: "architecture",
|
|
@@ -8754,6 +8977,20 @@ __export(store_exports, {
|
|
|
8754
8977
|
vectorToBlob: () => vectorToBlob,
|
|
8755
8978
|
writeMemory: () => writeMemory
|
|
8756
8979
|
});
|
|
8980
|
+
function logStoreDebug(context, err) {
|
|
8981
|
+
if (_debugStore) {
|
|
8982
|
+
process.stderr.write(
|
|
8983
|
+
`[store] ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
8984
|
+
`
|
|
8985
|
+
);
|
|
8986
|
+
}
|
|
8987
|
+
}
|
|
8988
|
+
function logStoreWarn(context, err) {
|
|
8989
|
+
process.stderr.write(
|
|
8990
|
+
`[store] WARN ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
8991
|
+
`
|
|
8992
|
+
);
|
|
8993
|
+
}
|
|
8757
8994
|
function isBusyError2(err) {
|
|
8758
8995
|
if (err instanceof Error) {
|
|
8759
8996
|
const msg = err.message.toLowerCase();
|
|
@@ -8808,13 +9045,15 @@ async function initStore(options) {
|
|
|
8808
9045
|
try {
|
|
8809
9046
|
const { initDaemonClient: initDaemonClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
8810
9047
|
await initDaemonClient2();
|
|
8811
|
-
} catch {
|
|
9048
|
+
} catch (e) {
|
|
9049
|
+
logStoreWarn("catch", e);
|
|
8812
9050
|
}
|
|
8813
9051
|
if (!options?.lightweight) {
|
|
8814
9052
|
try {
|
|
8815
9053
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
8816
9054
|
initShardManager2(hexKey);
|
|
8817
|
-
} catch {
|
|
9055
|
+
} catch (e) {
|
|
9056
|
+
logStoreWarn("catch", e);
|
|
8818
9057
|
}
|
|
8819
9058
|
const client = getClient();
|
|
8820
9059
|
const vResult = await retryOnBusy2(
|
|
@@ -8825,7 +9064,8 @@ async function initStore(options) {
|
|
|
8825
9064
|
try {
|
|
8826
9065
|
const { loadGlobalProcedures: loadGlobalProcedures2 } = await Promise.resolve().then(() => (init_global_procedures(), global_procedures_exports));
|
|
8827
9066
|
await loadGlobalProcedures2();
|
|
8828
|
-
} catch {
|
|
9067
|
+
} catch (e) {
|
|
9068
|
+
logStoreWarn("catch", e);
|
|
8829
9069
|
}
|
|
8830
9070
|
}
|
|
8831
9071
|
}
|
|
@@ -8885,7 +9125,8 @@ async function writeMemory(record) {
|
|
|
8885
9125
|
memoryType
|
|
8886
9126
|
});
|
|
8887
9127
|
if (existing) return;
|
|
8888
|
-
} catch {
|
|
9128
|
+
} catch (e) {
|
|
9129
|
+
logStoreWarn("catch", e);
|
|
8889
9130
|
}
|
|
8890
9131
|
const dbRow = {
|
|
8891
9132
|
id: record.id,
|
|
@@ -9086,12 +9327,14 @@ async function flushBatch() {
|
|
|
9086
9327
|
try {
|
|
9087
9328
|
const { insertMemoryCardsForBatch: insertMemoryCardsForBatch2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
|
|
9088
9329
|
await insertMemoryCardsForBatch2(batch);
|
|
9089
|
-
} catch {
|
|
9330
|
+
} catch (e) {
|
|
9331
|
+
logStoreWarn("catch", e);
|
|
9090
9332
|
}
|
|
9091
9333
|
try {
|
|
9092
9334
|
const { insertOntologyForBatch: insertOntologyForBatch2 } = await Promise.resolve().then(() => (init_agentic_ontology(), agentic_ontology_exports));
|
|
9093
9335
|
await insertOntologyForBatch2(batch);
|
|
9094
|
-
} catch {
|
|
9336
|
+
} catch (e) {
|
|
9337
|
+
logStoreWarn("catch", e);
|
|
9095
9338
|
}
|
|
9096
9339
|
schedulePostWriteMemoryHygiene(batch.map((row) => row.id));
|
|
9097
9340
|
_pendingRecords.splice(0, batch.length);
|
|
@@ -9130,7 +9373,8 @@ ${err.stack.split("\n").slice(1, 3).join("\n")}` : ""}` : String(err);
|
|
|
9130
9373
|
}
|
|
9131
9374
|
}
|
|
9132
9375
|
}
|
|
9133
|
-
} catch {
|
|
9376
|
+
} catch (e) {
|
|
9377
|
+
logStoreWarn("catch", e);
|
|
9134
9378
|
}
|
|
9135
9379
|
return batch.length;
|
|
9136
9380
|
} finally {
|
|
@@ -9172,7 +9416,8 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
9172
9416
|
} else {
|
|
9173
9417
|
client = getClient();
|
|
9174
9418
|
}
|
|
9175
|
-
} catch {
|
|
9419
|
+
} catch (e) {
|
|
9420
|
+
logStoreDebug("shard routing fallback", e);
|
|
9176
9421
|
client = getClient();
|
|
9177
9422
|
}
|
|
9178
9423
|
const limit = options?.limit ?? 10;
|
|
@@ -9288,7 +9533,8 @@ async function attachDocumentMetadata(records) {
|
|
|
9288
9533
|
if (!record.document_id) continue;
|
|
9289
9534
|
record.document_metadata = byId.get(record.document_id) ?? null;
|
|
9290
9535
|
}
|
|
9291
|
-
} catch {
|
|
9536
|
+
} catch (e) {
|
|
9537
|
+
logStoreWarn("catch", e);
|
|
9292
9538
|
}
|
|
9293
9539
|
return records;
|
|
9294
9540
|
}
|
|
@@ -9349,11 +9595,12 @@ async function getMemoryCardinality(agentId) {
|
|
|
9349
9595
|
args: [agentId]
|
|
9350
9596
|
});
|
|
9351
9597
|
return Number(result.rows[0]?.cnt) || 0;
|
|
9352
|
-
} catch {
|
|
9598
|
+
} catch (e) {
|
|
9599
|
+
logStoreWarn("getMemoryCardinality", e);
|
|
9353
9600
|
return 0;
|
|
9354
9601
|
}
|
|
9355
9602
|
}
|
|
9356
|
-
var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
9603
|
+
var _debugStore, INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
9357
9604
|
var init_store = __esm({
|
|
9358
9605
|
"src/lib/store.ts"() {
|
|
9359
9606
|
"use strict";
|
|
@@ -9363,6 +9610,7 @@ var init_store = __esm({
|
|
|
9363
9610
|
init_config();
|
|
9364
9611
|
init_state_bus();
|
|
9365
9612
|
init_memory_write_governor();
|
|
9613
|
+
_debugStore = process.env.EXE_DEBUG === "1";
|
|
9366
9614
|
INIT_MAX_RETRIES = 3;
|
|
9367
9615
|
INIT_RETRY_DELAY_MS = 1e3;
|
|
9368
9616
|
_pendingRecords = [];
|