@askexenow/exe-os 0.8.37 → 0.8.39
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/README.md +17 -8
- package/dist/bin/backfill-conversations.js +112 -70
- package/dist/bin/backfill-responses.js +53 -18
- package/dist/bin/backfill-vectors.js +43 -16
- package/dist/bin/cleanup-stale-review-tasks.js +38 -16
- package/dist/bin/cli.js +790 -468
- package/dist/bin/exe-agent.js +19 -4
- package/dist/bin/exe-assign.js +46 -13
- package/dist/bin/exe-boot.js +288 -129
- package/dist/bin/exe-call.js +20 -10
- package/dist/bin/exe-cloud.js +135 -30
- package/dist/bin/exe-dispatch.js +1 -1
- package/dist/bin/exe-doctor.js +38 -16
- package/dist/bin/exe-export-behaviors.js +43 -21
- package/dist/bin/exe-forget.js +39 -17
- package/dist/bin/exe-gateway.js +159 -50
- package/dist/bin/exe-heartbeat.js +53 -31
- package/dist/bin/exe-kill.js +40 -18
- package/dist/bin/exe-launch-agent.js +109 -36
- package/dist/bin/exe-link.js +196 -87
- package/dist/bin/exe-new-employee.js +56 -17
- package/dist/bin/exe-pending-messages.js +47 -25
- package/dist/bin/exe-pending-notifications.js +38 -16
- package/dist/bin/exe-pending-reviews.js +51 -29
- package/dist/bin/exe-rename.js +21 -7
- package/dist/bin/exe-review.js +41 -13
- package/dist/bin/exe-search.js +57 -21
- package/dist/bin/exe-session-cleanup.js +67 -31
- package/dist/bin/exe-settings.js +63 -2
- package/dist/bin/exe-status.js +35 -13
- package/dist/bin/exe-team.js +35 -13
- package/dist/bin/git-sweep.js +45 -17
- package/dist/bin/graph-backfill.js +38 -16
- package/dist/bin/graph-export.js +38 -16
- package/dist/bin/install.js +10 -1
- package/dist/bin/scan-tasks.js +47 -19
- package/dist/bin/setup.js +444 -259
- package/dist/bin/shard-migrate.js +38 -16
- package/dist/bin/wiki-sync.js +40 -17
- package/dist/gateway/index.js +113 -48
- package/dist/hooks/bug-report-worker.js +66 -39
- package/dist/hooks/commit-complete.js +45 -17
- package/dist/hooks/error-recall.js +60 -20
- package/dist/hooks/exe-heartbeat-hook.js +3 -2
- package/dist/hooks/ingest-worker.js +174 -45
- package/dist/hooks/ingest.js +74 -28
- package/dist/hooks/instructions-loaded.js +46 -17
- package/dist/hooks/notification.js +44 -15
- package/dist/hooks/post-compact.js +44 -15
- package/dist/hooks/pre-compact.js +42 -14
- package/dist/hooks/pre-tool-use.js +59 -22
- package/dist/hooks/prompt-ingest-worker.js +75 -14
- package/dist/hooks/prompt-submit.js +75 -32
- package/dist/hooks/response-ingest-worker.js +76 -15
- package/dist/hooks/session-end.js +54 -22
- package/dist/hooks/session-start.js +57 -20
- package/dist/hooks/stop.js +44 -15
- package/dist/hooks/subagent-stop.js +44 -15
- package/dist/hooks/summary-worker.js +339 -106
- package/dist/index.js +94 -23
- package/dist/lib/cloud-sync.js +191 -80
- package/dist/lib/config.js +4 -1
- package/dist/lib/consolidation.js +5 -4
- package/dist/lib/database.js +1 -0
- package/dist/lib/device-registry.js +2 -1
- package/dist/lib/embedder.js +9 -1
- package/dist/lib/employee-templates.js +5 -0
- package/dist/lib/employees.js +11 -6
- package/dist/lib/exe-daemon-client.js +6 -1
- package/dist/lib/exe-daemon.js +95 -36
- package/dist/lib/hybrid-search.js +57 -21
- package/dist/lib/identity-templates.js +16 -7
- package/dist/lib/identity.js +1 -1
- package/dist/lib/keychain.js +2 -1
- package/dist/lib/license.js +56 -6
- package/dist/lib/messaging.js +1 -1
- package/dist/lib/reminders.js +2 -2
- package/dist/lib/schedules.js +38 -16
- package/dist/lib/skill-learning.js +1 -1
- package/dist/lib/store.js +44 -16
- package/dist/lib/tasks.js +1 -1
- package/dist/lib/tmux-routing.js +1 -1
- package/dist/mcp/server.js +280 -155
- package/dist/mcp/tools/complete-reminder.js +1 -1
- package/dist/mcp/tools/create-task.js +14 -6
- package/dist/mcp/tools/deactivate-behavior.js +2 -2
- package/dist/mcp/tools/list-reminders.js +1 -1
- package/dist/mcp/tools/list-tasks.js +36 -28
- package/dist/mcp/tools/send-message.js +1 -1
- package/dist/mcp/tools/update-task.js +1 -1
- package/dist/runtime/index.js +42 -8
- package/dist/tui/App.js +220 -99
- package/package.json +5 -3
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
5
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
6
|
-
}) : x)(function(x) {
|
|
7
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
8
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
9
|
-
});
|
|
10
4
|
var __esm = (fn, res) => function __init() {
|
|
11
5
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
12
6
|
};
|
|
@@ -103,6 +97,7 @@ async function ensureSchema() {
|
|
|
103
97
|
const client = getRawClient();
|
|
104
98
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
105
99
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
100
|
+
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
106
101
|
try {
|
|
107
102
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
108
103
|
} catch {
|
|
@@ -903,15 +898,15 @@ var init_database = __esm({
|
|
|
903
898
|
});
|
|
904
899
|
|
|
905
900
|
// src/lib/config.ts
|
|
906
|
-
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
901
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, chmod as chmod2 } from "fs/promises";
|
|
907
902
|
import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
|
|
908
903
|
import path2 from "path";
|
|
909
|
-
import
|
|
904
|
+
import os2 from "os";
|
|
910
905
|
function resolveDataDir() {
|
|
911
906
|
if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
|
|
912
907
|
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
913
|
-
const newDir = path2.join(
|
|
914
|
-
const legacyDir = path2.join(
|
|
908
|
+
const newDir = path2.join(os2.homedir(), ".exe-os");
|
|
909
|
+
const legacyDir = path2.join(os2.homedir(), ".exe-mem");
|
|
915
910
|
if (!existsSync2(newDir) && existsSync2(legacyDir)) {
|
|
916
911
|
try {
|
|
917
912
|
renameSync(legacyDir, newDir);
|
|
@@ -998,7 +993,7 @@ async function loadConfig() {
|
|
|
998
993
|
normalizeAutoUpdate(migratedCfg);
|
|
999
994
|
const config = { ...DEFAULT_CONFIG, dbPath: path2.join(dir, "memories.db"), ...migratedCfg };
|
|
1000
995
|
if (config.dbPath.startsWith("~")) {
|
|
1001
|
-
config.dbPath = config.dbPath.replace(/^~/,
|
|
996
|
+
config.dbPath = config.dbPath.replace(/^~/, os2.homedir());
|
|
1002
997
|
}
|
|
1003
998
|
return config;
|
|
1004
999
|
} catch {
|
|
@@ -1124,7 +1119,7 @@ __export(shard_manager_exports, {
|
|
|
1124
1119
|
shardExists: () => shardExists
|
|
1125
1120
|
});
|
|
1126
1121
|
import path3 from "path";
|
|
1127
|
-
import { existsSync as existsSync3, mkdirSync } from "fs";
|
|
1122
|
+
import { existsSync as existsSync3, mkdirSync, readdirSync } from "fs";
|
|
1128
1123
|
import { createClient as createClient2 } from "@libsql/client";
|
|
1129
1124
|
function initShardManager(encryptionKey) {
|
|
1130
1125
|
_encryptionKey = encryptionKey;
|
|
@@ -1163,8 +1158,7 @@ function shardExists(projectName) {
|
|
|
1163
1158
|
}
|
|
1164
1159
|
function listShards() {
|
|
1165
1160
|
if (!existsSync3(SHARDS_DIR)) return [];
|
|
1166
|
-
|
|
1167
|
-
return readdirSync3(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
1161
|
+
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
1168
1162
|
}
|
|
1169
1163
|
async function ensureShardSchema(client) {
|
|
1170
1164
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
@@ -1369,10 +1363,10 @@ var init_employees = __esm({
|
|
|
1369
1363
|
// src/lib/notifications.ts
|
|
1370
1364
|
import crypto2 from "crypto";
|
|
1371
1365
|
import path5 from "path";
|
|
1372
|
-
import
|
|
1366
|
+
import os3 from "os";
|
|
1373
1367
|
import {
|
|
1374
1368
|
readFileSync as readFileSync3,
|
|
1375
|
-
readdirSync,
|
|
1369
|
+
readdirSync as readdirSync2,
|
|
1376
1370
|
unlinkSync,
|
|
1377
1371
|
existsSync as existsSync5,
|
|
1378
1372
|
rmdirSync
|
|
@@ -1399,12 +1393,12 @@ var init_tasks_crud = __esm({
|
|
|
1399
1393
|
|
|
1400
1394
|
// src/lib/session-registry.ts
|
|
1401
1395
|
import path7 from "path";
|
|
1402
|
-
import
|
|
1396
|
+
import os4 from "os";
|
|
1403
1397
|
var REGISTRY_PATH;
|
|
1404
1398
|
var init_session_registry = __esm({
|
|
1405
1399
|
"src/lib/session-registry.ts"() {
|
|
1406
1400
|
"use strict";
|
|
1407
|
-
REGISTRY_PATH = path7.join(
|
|
1401
|
+
REGISTRY_PATH = path7.join(os4.homedir(), ".exe-os", "session-registry.json");
|
|
1408
1402
|
}
|
|
1409
1403
|
});
|
|
1410
1404
|
|
|
@@ -1455,14 +1449,14 @@ var init_provider_table = __esm({
|
|
|
1455
1449
|
// src/lib/intercom-queue.ts
|
|
1456
1450
|
import { readFileSync as readFileSync5, writeFileSync, renameSync as renameSync2, existsSync as existsSync7, mkdirSync as mkdirSync2 } from "fs";
|
|
1457
1451
|
import path8 from "path";
|
|
1458
|
-
import
|
|
1452
|
+
import os5 from "os";
|
|
1459
1453
|
var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
|
|
1460
1454
|
var init_intercom_queue = __esm({
|
|
1461
1455
|
"src/lib/intercom-queue.ts"() {
|
|
1462
1456
|
"use strict";
|
|
1463
|
-
QUEUE_PATH = path8.join(
|
|
1457
|
+
QUEUE_PATH = path8.join(os5.homedir(), ".exe-os", "intercom-queue.json");
|
|
1464
1458
|
TTL_MS = 60 * 60 * 1e3;
|
|
1465
|
-
INTERCOM_LOG = path8.join(
|
|
1459
|
+
INTERCOM_LOG = path8.join(os5.homedir(), ".exe-os", "intercom.log");
|
|
1466
1460
|
}
|
|
1467
1461
|
});
|
|
1468
1462
|
|
|
@@ -1499,7 +1493,7 @@ var init_plan_limits = __esm({
|
|
|
1499
1493
|
|
|
1500
1494
|
// src/lib/tmux-routing.ts
|
|
1501
1495
|
import path11 from "path";
|
|
1502
|
-
import
|
|
1496
|
+
import os6 from "os";
|
|
1503
1497
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1504
1498
|
var SPAWN_LOCK_DIR, SESSION_CACHE, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS;
|
|
1505
1499
|
var init_tmux_routing = __esm({
|
|
@@ -1513,9 +1507,9 @@ var init_tmux_routing = __esm({
|
|
|
1513
1507
|
init_provider_table();
|
|
1514
1508
|
init_intercom_queue();
|
|
1515
1509
|
init_plan_limits();
|
|
1516
|
-
SPAWN_LOCK_DIR = path11.join(
|
|
1517
|
-
SESSION_CACHE = path11.join(
|
|
1518
|
-
INTERCOM_LOG2 = path11.join(
|
|
1510
|
+
SPAWN_LOCK_DIR = path11.join(os6.homedir(), ".exe-os", "spawn-locks");
|
|
1511
|
+
SESSION_CACHE = path11.join(os6.homedir(), ".exe-os", "session-cache");
|
|
1512
|
+
INTERCOM_LOG2 = path11.join(os6.homedir(), ".exe-os", "intercom.log");
|
|
1519
1513
|
DEBOUNCE_FILE = path11.join(SESSION_CACHE, "intercom-debounce.json");
|
|
1520
1514
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
1521
1515
|
}
|
|
@@ -1523,7 +1517,7 @@ var init_tmux_routing = __esm({
|
|
|
1523
1517
|
|
|
1524
1518
|
// src/lib/tasks-review.ts
|
|
1525
1519
|
import path12 from "path";
|
|
1526
|
-
import { existsSync as existsSync10, readdirSync as
|
|
1520
|
+
import { existsSync as existsSync10, readdirSync as readdirSync3, unlinkSync as unlinkSync2 } from "fs";
|
|
1527
1521
|
async function listPendingReviews(limit) {
|
|
1528
1522
|
const client = getClient();
|
|
1529
1523
|
const result = await client.execute({
|
|
@@ -1550,7 +1544,7 @@ var init_tasks_review = __esm({
|
|
|
1550
1544
|
// src/bin/exe-heartbeat.ts
|
|
1551
1545
|
import { createHash } from "crypto";
|
|
1552
1546
|
import { readFileSync as readFileSync8, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4 } from "fs";
|
|
1553
|
-
import
|
|
1547
|
+
import os7 from "os";
|
|
1554
1548
|
import path13 from "path";
|
|
1555
1549
|
|
|
1556
1550
|
// src/lib/store.ts
|
|
@@ -1560,11 +1554,12 @@ init_database();
|
|
|
1560
1554
|
import { readFile, writeFile, unlink, mkdir, chmod } from "fs/promises";
|
|
1561
1555
|
import { existsSync } from "fs";
|
|
1562
1556
|
import path from "path";
|
|
1557
|
+
import os from "os";
|
|
1563
1558
|
import crypto from "crypto";
|
|
1564
1559
|
var SERVICE = "exe-mem";
|
|
1565
1560
|
var ACCOUNT = "master-key";
|
|
1566
1561
|
function getKeyDir() {
|
|
1567
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path.join(
|
|
1562
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path.join(os.homedir(), ".exe-os");
|
|
1568
1563
|
}
|
|
1569
1564
|
function getKeyPath() {
|
|
1570
1565
|
return path.join(getKeyDir(), "master.key");
|
|
@@ -1601,6 +1596,30 @@ async function getMasterKey() {
|
|
|
1601
1596
|
|
|
1602
1597
|
// src/lib/store.ts
|
|
1603
1598
|
init_config();
|
|
1599
|
+
var INIT_MAX_RETRIES = 3;
|
|
1600
|
+
var INIT_RETRY_DELAY_MS = 1e3;
|
|
1601
|
+
function isBusyError2(err) {
|
|
1602
|
+
if (err instanceof Error) {
|
|
1603
|
+
const msg = err.message.toLowerCase();
|
|
1604
|
+
return msg.includes("sqlite_busy") || msg.includes("database is locked");
|
|
1605
|
+
}
|
|
1606
|
+
return false;
|
|
1607
|
+
}
|
|
1608
|
+
async function retryOnBusy2(fn, label) {
|
|
1609
|
+
for (let attempt = 0; attempt <= INIT_MAX_RETRIES; attempt++) {
|
|
1610
|
+
try {
|
|
1611
|
+
return await fn();
|
|
1612
|
+
} catch (err) {
|
|
1613
|
+
if (!isBusyError2(err) || attempt === INIT_MAX_RETRIES) throw err;
|
|
1614
|
+
process.stderr.write(
|
|
1615
|
+
`[store] SQLITE_BUSY during ${label}, retry ${attempt + 1}/${INIT_MAX_RETRIES}
|
|
1616
|
+
`
|
|
1617
|
+
);
|
|
1618
|
+
await new Promise((r) => setTimeout(r, INIT_RETRY_DELAY_MS * (attempt + 1)));
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
throw new Error("unreachable");
|
|
1622
|
+
}
|
|
1604
1623
|
var _pendingRecords = [];
|
|
1605
1624
|
var _batchSize = 20;
|
|
1606
1625
|
var _flushIntervalMs = 1e4;
|
|
@@ -1635,14 +1654,17 @@ async function initStore(options) {
|
|
|
1635
1654
|
dbPath,
|
|
1636
1655
|
encryptionKey: hexKey
|
|
1637
1656
|
});
|
|
1638
|
-
await ensureSchema();
|
|
1657
|
+
await retryOnBusy2(() => ensureSchema(), "ensureSchema");
|
|
1639
1658
|
try {
|
|
1640
1659
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
1641
1660
|
initShardManager2(hexKey);
|
|
1642
1661
|
} catch {
|
|
1643
1662
|
}
|
|
1644
1663
|
const client = getClient();
|
|
1645
|
-
const vResult = await
|
|
1664
|
+
const vResult = await retryOnBusy2(
|
|
1665
|
+
() => client.execute("SELECT MAX(version) as max_v FROM memories"),
|
|
1666
|
+
"version-query"
|
|
1667
|
+
);
|
|
1646
1668
|
_nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
|
|
1647
1669
|
}
|
|
1648
1670
|
|
|
@@ -1677,7 +1699,7 @@ var MESSAGE_PREVIEW_CHARS = 80;
|
|
|
1677
1699
|
var MARKER_FILENAME = "exe-heartbeat-marker.json";
|
|
1678
1700
|
var SESSION_CACHE_SUBDIR = "session-cache";
|
|
1679
1701
|
function resolveExeOsDir() {
|
|
1680
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path13.join(
|
|
1702
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path13.join(os7.homedir(), ".exe-os");
|
|
1681
1703
|
}
|
|
1682
1704
|
function getMarkerDir() {
|
|
1683
1705
|
return path13.join(resolveExeOsDir(), SESSION_CACHE_SUBDIR);
|
package/dist/bin/exe-kill.js
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
5
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
6
|
-
}) : x)(function(x) {
|
|
7
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
8
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
9
|
-
});
|
|
10
4
|
var __esm = (fn, res) => function __init() {
|
|
11
5
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
12
6
|
};
|
|
@@ -16,15 +10,15 @@ var __export = (target, all) => {
|
|
|
16
10
|
};
|
|
17
11
|
|
|
18
12
|
// src/lib/config.ts
|
|
19
|
-
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
13
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, chmod as chmod2 } from "fs/promises";
|
|
20
14
|
import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
|
|
21
15
|
import path2 from "path";
|
|
22
|
-
import
|
|
16
|
+
import os2 from "os";
|
|
23
17
|
function resolveDataDir() {
|
|
24
18
|
if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
|
|
25
19
|
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
26
|
-
const newDir = path2.join(
|
|
27
|
-
const legacyDir = path2.join(
|
|
20
|
+
const newDir = path2.join(os2.homedir(), ".exe-os");
|
|
21
|
+
const legacyDir = path2.join(os2.homedir(), ".exe-mem");
|
|
28
22
|
if (!existsSync2(newDir) && existsSync2(legacyDir)) {
|
|
29
23
|
try {
|
|
30
24
|
renameSync(legacyDir, newDir);
|
|
@@ -111,7 +105,7 @@ async function loadConfig() {
|
|
|
111
105
|
normalizeAutoUpdate(migratedCfg);
|
|
112
106
|
const config = { ...DEFAULT_CONFIG, dbPath: path2.join(dir, "memories.db"), ...migratedCfg };
|
|
113
107
|
if (config.dbPath.startsWith("~")) {
|
|
114
|
-
config.dbPath = config.dbPath.replace(/^~/,
|
|
108
|
+
config.dbPath = config.dbPath.replace(/^~/, os2.homedir());
|
|
115
109
|
}
|
|
116
110
|
return config;
|
|
117
111
|
} catch {
|
|
@@ -218,7 +212,7 @@ __export(shard_manager_exports, {
|
|
|
218
212
|
shardExists: () => shardExists
|
|
219
213
|
});
|
|
220
214
|
import path3 from "path";
|
|
221
|
-
import { existsSync as existsSync3, mkdirSync } from "fs";
|
|
215
|
+
import { existsSync as existsSync3, mkdirSync, readdirSync } from "fs";
|
|
222
216
|
import { createClient as createClient2 } from "@libsql/client";
|
|
223
217
|
function initShardManager(encryptionKey) {
|
|
224
218
|
_encryptionKey = encryptionKey;
|
|
@@ -257,7 +251,6 @@ function shardExists(projectName) {
|
|
|
257
251
|
}
|
|
258
252
|
function listShards() {
|
|
259
253
|
if (!existsSync3(SHARDS_DIR)) return [];
|
|
260
|
-
const { readdirSync } = __require("fs");
|
|
261
254
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
262
255
|
}
|
|
263
256
|
async function ensureShardSchema(client) {
|
|
@@ -536,6 +529,7 @@ async function ensureSchema() {
|
|
|
536
529
|
const client = getRawClient();
|
|
537
530
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
538
531
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
532
|
+
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
539
533
|
try {
|
|
540
534
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
541
535
|
} catch {
|
|
@@ -1337,11 +1331,12 @@ async function disposeDatabase() {
|
|
|
1337
1331
|
import { readFile, writeFile, unlink, mkdir, chmod } from "fs/promises";
|
|
1338
1332
|
import { existsSync } from "fs";
|
|
1339
1333
|
import path from "path";
|
|
1334
|
+
import os from "os";
|
|
1340
1335
|
import crypto from "crypto";
|
|
1341
1336
|
var SERVICE = "exe-mem";
|
|
1342
1337
|
var ACCOUNT = "master-key";
|
|
1343
1338
|
function getKeyDir() {
|
|
1344
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path.join(
|
|
1339
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path.join(os.homedir(), ".exe-os");
|
|
1345
1340
|
}
|
|
1346
1341
|
function getKeyPath() {
|
|
1347
1342
|
return path.join(getKeyDir(), "master.key");
|
|
@@ -1378,6 +1373,30 @@ async function getMasterKey() {
|
|
|
1378
1373
|
|
|
1379
1374
|
// src/lib/store.ts
|
|
1380
1375
|
init_config();
|
|
1376
|
+
var INIT_MAX_RETRIES = 3;
|
|
1377
|
+
var INIT_RETRY_DELAY_MS = 1e3;
|
|
1378
|
+
function isBusyError2(err) {
|
|
1379
|
+
if (err instanceof Error) {
|
|
1380
|
+
const msg = err.message.toLowerCase();
|
|
1381
|
+
return msg.includes("sqlite_busy") || msg.includes("database is locked");
|
|
1382
|
+
}
|
|
1383
|
+
return false;
|
|
1384
|
+
}
|
|
1385
|
+
async function retryOnBusy2(fn, label) {
|
|
1386
|
+
for (let attempt = 0; attempt <= INIT_MAX_RETRIES; attempt++) {
|
|
1387
|
+
try {
|
|
1388
|
+
return await fn();
|
|
1389
|
+
} catch (err) {
|
|
1390
|
+
if (!isBusyError2(err) || attempt === INIT_MAX_RETRIES) throw err;
|
|
1391
|
+
process.stderr.write(
|
|
1392
|
+
`[store] SQLITE_BUSY during ${label}, retry ${attempt + 1}/${INIT_MAX_RETRIES}
|
|
1393
|
+
`
|
|
1394
|
+
);
|
|
1395
|
+
await new Promise((r) => setTimeout(r, INIT_RETRY_DELAY_MS * (attempt + 1)));
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
throw new Error("unreachable");
|
|
1399
|
+
}
|
|
1381
1400
|
var _pendingRecords = [];
|
|
1382
1401
|
var _batchSize = 20;
|
|
1383
1402
|
var _flushIntervalMs = 1e4;
|
|
@@ -1412,14 +1431,17 @@ async function initStore(options) {
|
|
|
1412
1431
|
dbPath,
|
|
1413
1432
|
encryptionKey: hexKey
|
|
1414
1433
|
});
|
|
1415
|
-
await ensureSchema();
|
|
1434
|
+
await retryOnBusy2(() => ensureSchema(), "ensureSchema");
|
|
1416
1435
|
try {
|
|
1417
1436
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
1418
1437
|
initShardManager2(hexKey);
|
|
1419
1438
|
} catch {
|
|
1420
1439
|
}
|
|
1421
1440
|
const client = getClient();
|
|
1422
|
-
const vResult = await
|
|
1441
|
+
const vResult = await retryOnBusy2(
|
|
1442
|
+
() => client.execute("SELECT MAX(version) as max_v FROM memories"),
|
|
1443
|
+
"version-query"
|
|
1444
|
+
);
|
|
1423
1445
|
_nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
|
|
1424
1446
|
}
|
|
1425
1447
|
async function flushBatch() {
|
|
@@ -1601,8 +1623,8 @@ async function recordSessionKill(input) {
|
|
|
1601
1623
|
// src/lib/session-registry.ts
|
|
1602
1624
|
import { readFileSync as readFileSync2, writeFileSync, mkdirSync as mkdirSync2, existsSync as existsSync4 } from "fs";
|
|
1603
1625
|
import path4 from "path";
|
|
1604
|
-
import
|
|
1605
|
-
var REGISTRY_PATH = path4.join(
|
|
1626
|
+
import os3 from "os";
|
|
1627
|
+
var REGISTRY_PATH = path4.join(os3.homedir(), ".exe-os", "session-registry.json");
|
|
1606
1628
|
function listSessions() {
|
|
1607
1629
|
try {
|
|
1608
1630
|
const raw = readFileSync2(REGISTRY_PATH, "utf8");
|