@askexenow/exe-os 0.8.38 → 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 +46 -10
- package/dist/bin/backfill-responses.js +46 -10
- package/dist/bin/backfill-vectors.js +42 -8
- package/dist/bin/cleanup-stale-review-tasks.js +37 -8
- package/dist/bin/cli.js +281 -154
- package/dist/bin/exe-agent.js +19 -4
- package/dist/bin/exe-assign.js +39 -5
- package/dist/bin/exe-boot.js +237 -111
- package/dist/bin/exe-call.js +11 -6
- package/dist/bin/exe-cloud.js +99 -28
- package/dist/bin/exe-dispatch.js +1 -1
- package/dist/bin/exe-doctor.js +37 -8
- package/dist/bin/exe-export-behaviors.js +39 -10
- package/dist/bin/exe-forget.js +38 -9
- package/dist/bin/exe-gateway.js +109 -42
- package/dist/bin/exe-heartbeat.js +49 -20
- package/dist/bin/exe-kill.js +39 -10
- package/dist/bin/exe-launch-agent.js +58 -22
- package/dist/bin/exe-link.js +184 -85
- package/dist/bin/exe-new-employee.js +21 -7
- package/dist/bin/exe-pending-messages.js +46 -17
- package/dist/bin/exe-pending-notifications.js +37 -8
- package/dist/bin/exe-pending-reviews.js +47 -18
- package/dist/bin/exe-rename.js +21 -7
- package/dist/bin/exe-review.js +34 -5
- package/dist/bin/exe-search.js +47 -10
- package/dist/bin/exe-session-cleanup.js +56 -19
- package/dist/bin/exe-settings.js +63 -2
- package/dist/bin/exe-status.js +34 -5
- package/dist/bin/exe-team.js +34 -5
- package/dist/bin/git-sweep.js +38 -9
- package/dist/bin/graph-backfill.js +37 -8
- package/dist/bin/graph-export.js +37 -8
- package/dist/bin/install.js +1 -1
- package/dist/bin/scan-tasks.js +40 -11
- package/dist/bin/setup.js +58 -24
- package/dist/bin/shard-migrate.js +37 -8
- package/dist/bin/wiki-sync.js +39 -9
- package/dist/gateway/index.js +102 -37
- package/dist/hooks/bug-report-worker.js +62 -28
- package/dist/hooks/commit-complete.js +38 -9
- package/dist/hooks/error-recall.js +49 -8
- package/dist/hooks/exe-heartbeat-hook.js +3 -2
- package/dist/hooks/ingest-worker.js +151 -37
- package/dist/hooks/ingest.js +74 -28
- package/dist/hooks/instructions-loaded.js +39 -9
- package/dist/hooks/notification.js +37 -7
- package/dist/hooks/post-compact.js +37 -7
- package/dist/hooks/pre-compact.js +35 -6
- package/dist/hooks/pre-tool-use.js +52 -14
- package/dist/hooks/prompt-ingest-worker.js +56 -10
- package/dist/hooks/prompt-submit.js +61 -23
- package/dist/hooks/response-ingest-worker.js +57 -11
- package/dist/hooks/session-end.js +43 -10
- package/dist/hooks/session-start.js +46 -8
- package/dist/hooks/stop.js +37 -7
- package/dist/hooks/subagent-stop.js +37 -7
- package/dist/hooks/summary-worker.js +317 -99
- package/dist/index.js +87 -22
- package/dist/lib/cloud-sync.js +172 -78
- 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/employees.js +11 -6
- package/dist/lib/exe-daemon-client.js +6 -1
- package/dist/lib/exe-daemon.js +71 -28
- package/dist/lib/hybrid-search.js +47 -10
- package/dist/lib/identity.js +1 -1
- package/dist/lib/keychain.js +2 -1
- package/dist/lib/license.js +13 -4
- package/dist/lib/messaging.js +1 -1
- package/dist/lib/reminders.js +2 -2
- package/dist/lib/schedules.js +37 -8
- package/dist/lib/skill-learning.js +1 -1
- package/dist/lib/store.js +37 -8
- package/dist/lib/tasks.js +1 -1
- package/dist/lib/tmux-routing.js +1 -1
- package/dist/mcp/server.js +97 -43
- 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 +1 -1
- package/dist/mcp/tools/send-message.js +1 -1
- package/dist/mcp/tools/update-task.js +1 -1
- package/dist/runtime/index.js +35 -6
- package/dist/tui/App.js +177 -95
- package/package.json +3 -3
|
@@ -9,7 +9,7 @@ var __export = (target, all) => {
|
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
// src/lib/config.ts
|
|
12
|
-
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
12
|
+
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
13
13
|
import { readFileSync, existsSync, renameSync } from "fs";
|
|
14
14
|
import path from "path";
|
|
15
15
|
import os from "os";
|
|
@@ -308,6 +308,7 @@ async function ensureSchema() {
|
|
|
308
308
|
const client = getRawClient();
|
|
309
309
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
310
310
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
311
|
+
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
311
312
|
try {
|
|
312
313
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
313
314
|
} catch {
|
|
@@ -1116,12 +1117,13 @@ var init_database = __esm({
|
|
|
1116
1117
|
});
|
|
1117
1118
|
|
|
1118
1119
|
// src/lib/keychain.ts
|
|
1119
|
-
import { readFile as readFile2, writeFile as writeFile2, unlink, mkdir as mkdir2, chmod } from "fs/promises";
|
|
1120
|
+
import { readFile as readFile2, writeFile as writeFile2, unlink, mkdir as mkdir2, chmod as chmod2 } from "fs/promises";
|
|
1120
1121
|
import { existsSync as existsSync2 } from "fs";
|
|
1121
1122
|
import path3 from "path";
|
|
1123
|
+
import os2 from "os";
|
|
1122
1124
|
import crypto from "crypto";
|
|
1123
1125
|
function getKeyDir() {
|
|
1124
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path3.join(
|
|
1126
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path3.join(os2.homedir(), ".exe-os");
|
|
1125
1127
|
}
|
|
1126
1128
|
function getKeyPath() {
|
|
1127
1129
|
return path3.join(getKeyDir(), "master.key");
|
|
@@ -1422,6 +1424,28 @@ __export(store_exports, {
|
|
|
1422
1424
|
vectorToBlob: () => vectorToBlob,
|
|
1423
1425
|
writeMemory: () => writeMemory
|
|
1424
1426
|
});
|
|
1427
|
+
function isBusyError2(err) {
|
|
1428
|
+
if (err instanceof Error) {
|
|
1429
|
+
const msg = err.message.toLowerCase();
|
|
1430
|
+
return msg.includes("sqlite_busy") || msg.includes("database is locked");
|
|
1431
|
+
}
|
|
1432
|
+
return false;
|
|
1433
|
+
}
|
|
1434
|
+
async function retryOnBusy2(fn, label) {
|
|
1435
|
+
for (let attempt = 0; attempt <= INIT_MAX_RETRIES; attempt++) {
|
|
1436
|
+
try {
|
|
1437
|
+
return await fn();
|
|
1438
|
+
} catch (err) {
|
|
1439
|
+
if (!isBusyError2(err) || attempt === INIT_MAX_RETRIES) throw err;
|
|
1440
|
+
process.stderr.write(
|
|
1441
|
+
`[store] SQLITE_BUSY during ${label}, retry ${attempt + 1}/${INIT_MAX_RETRIES}
|
|
1442
|
+
`
|
|
1443
|
+
);
|
|
1444
|
+
await new Promise((r) => setTimeout(r, INIT_RETRY_DELAY_MS * (attempt + 1)));
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
throw new Error("unreachable");
|
|
1448
|
+
}
|
|
1425
1449
|
async function initStore(options) {
|
|
1426
1450
|
if (_flushTimer !== null) {
|
|
1427
1451
|
clearInterval(_flushTimer);
|
|
@@ -1450,14 +1474,17 @@ async function initStore(options) {
|
|
|
1450
1474
|
dbPath,
|
|
1451
1475
|
encryptionKey: hexKey
|
|
1452
1476
|
});
|
|
1453
|
-
await ensureSchema();
|
|
1477
|
+
await retryOnBusy2(() => ensureSchema(), "ensureSchema");
|
|
1454
1478
|
try {
|
|
1455
1479
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
1456
1480
|
initShardManager2(hexKey);
|
|
1457
1481
|
} catch {
|
|
1458
1482
|
}
|
|
1459
1483
|
const client = getClient();
|
|
1460
|
-
const vResult = await
|
|
1484
|
+
const vResult = await retryOnBusy2(
|
|
1485
|
+
() => client.execute("SELECT MAX(version) as max_v FROM memories"),
|
|
1486
|
+
"version-query"
|
|
1487
|
+
);
|
|
1461
1488
|
_nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
|
|
1462
1489
|
}
|
|
1463
1490
|
function classifyTier(record) {
|
|
@@ -1837,7 +1864,7 @@ async function getMemoryCardinality(agentId) {
|
|
|
1837
1864
|
return 0;
|
|
1838
1865
|
}
|
|
1839
1866
|
}
|
|
1840
|
-
var _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
1867
|
+
var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
1841
1868
|
var init_store = __esm({
|
|
1842
1869
|
"src/lib/store.ts"() {
|
|
1843
1870
|
"use strict";
|
|
@@ -1845,6 +1872,8 @@ var init_store = __esm({
|
|
|
1845
1872
|
init_database();
|
|
1846
1873
|
init_keychain();
|
|
1847
1874
|
init_config();
|
|
1875
|
+
INIT_MAX_RETRIES = 3;
|
|
1876
|
+
INIT_RETRY_DELAY_MS = 1e3;
|
|
1848
1877
|
_pendingRecords = [];
|
|
1849
1878
|
_batchSize = 20;
|
|
1850
1879
|
_flushIntervalMs = 1e4;
|
|
@@ -1868,7 +1897,7 @@ __export(notifications_exports, {
|
|
|
1868
1897
|
});
|
|
1869
1898
|
import crypto2 from "crypto";
|
|
1870
1899
|
import path5 from "path";
|
|
1871
|
-
import
|
|
1900
|
+
import os3 from "os";
|
|
1872
1901
|
import {
|
|
1873
1902
|
readFileSync as readFileSync3,
|
|
1874
1903
|
readdirSync as readdirSync3,
|
|
@@ -2009,7 +2038,7 @@ function formatNotifications(notifications) {
|
|
|
2009
2038
|
return lines.join("\n");
|
|
2010
2039
|
}
|
|
2011
2040
|
async function migrateJsonNotifications() {
|
|
2012
|
-
const base = process.env.EXE_OS_DIR || process.env.EXE_MEM_DIR || path5.join(
|
|
2041
|
+
const base = process.env.EXE_OS_DIR || process.env.EXE_MEM_DIR || path5.join(os3.homedir(), ".exe-os");
|
|
2013
2042
|
const notifDir = path5.join(base, "notifications");
|
|
2014
2043
|
if (!existsSync4(notifDir)) return 0;
|
|
2015
2044
|
let migrated = 0;
|
|
@@ -2193,13 +2222,17 @@ var timeout = setTimeout(() => {
|
|
|
2193
2222
|
process.exit(0);
|
|
2194
2223
|
}, 5e3);
|
|
2195
2224
|
timeout.unref();
|
|
2225
|
+
var MAX_INPUT_SIZE = 1e6;
|
|
2196
2226
|
var input = "";
|
|
2197
2227
|
process.stdin.setEncoding("utf8");
|
|
2198
2228
|
process.stdin.on("data", (chunk) => {
|
|
2199
|
-
input += chunk;
|
|
2229
|
+
if (input.length < MAX_INPUT_SIZE) input += chunk;
|
|
2200
2230
|
});
|
|
2201
2231
|
process.stdin.on("end", async () => {
|
|
2202
2232
|
try {
|
|
2233
|
+
if (input.length >= MAX_INPUT_SIZE) {
|
|
2234
|
+
process.exit(0);
|
|
2235
|
+
}
|
|
2203
2236
|
const data = JSON.parse(input);
|
|
2204
2237
|
const agent = getActiveAgent();
|
|
2205
2238
|
if (agent.agentId !== "default") {
|
|
@@ -2229,7 +2262,7 @@ Orphaned tasks at session end: ${orphanResult.rows.map((r) => `"${String(r.title
|
|
|
2229
2262
|
vector: null
|
|
2230
2263
|
});
|
|
2231
2264
|
await flushBatch2();
|
|
2232
|
-
if (agent.
|
|
2265
|
+
if (agent.agentRole !== "COO") {
|
|
2233
2266
|
const inProgress = orphanResult.rows.filter((r) => String(r.status) === "in_progress");
|
|
2234
2267
|
if (inProgress.length > 0) {
|
|
2235
2268
|
const titles = inProgress.map((r) => `"${String(r.title)}"`).join(", ");
|
|
@@ -24,7 +24,7 @@ __export(config_exports, {
|
|
|
24
24
|
migrateConfig: () => migrateConfig,
|
|
25
25
|
saveConfig: () => saveConfig
|
|
26
26
|
});
|
|
27
|
-
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
27
|
+
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
28
28
|
import { readFileSync, existsSync, renameSync } from "fs";
|
|
29
29
|
import path from "path";
|
|
30
30
|
import os from "os";
|
|
@@ -150,6 +150,9 @@ async function saveConfig(config) {
|
|
|
150
150
|
await mkdir(dir, { recursive: true });
|
|
151
151
|
const configPath = path.join(dir, "config.json");
|
|
152
152
|
await writeFile(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
153
|
+
if (config.cloud?.apiKey) {
|
|
154
|
+
await chmod(configPath, 384);
|
|
155
|
+
}
|
|
153
156
|
}
|
|
154
157
|
async function loadConfigFrom(configPath) {
|
|
155
158
|
const raw = await readFile(configPath, "utf-8");
|
|
@@ -348,6 +351,7 @@ async function ensureSchema() {
|
|
|
348
351
|
const client = getRawClient();
|
|
349
352
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
350
353
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
354
|
+
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
351
355
|
try {
|
|
352
356
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
353
357
|
} catch {
|
|
@@ -1156,12 +1160,13 @@ var init_database = __esm({
|
|
|
1156
1160
|
});
|
|
1157
1161
|
|
|
1158
1162
|
// src/lib/keychain.ts
|
|
1159
|
-
import { readFile as readFile2, writeFile as writeFile2, unlink, mkdir as mkdir2, chmod } from "fs/promises";
|
|
1163
|
+
import { readFile as readFile2, writeFile as writeFile2, unlink, mkdir as mkdir2, chmod as chmod2 } from "fs/promises";
|
|
1160
1164
|
import { existsSync as existsSync2 } from "fs";
|
|
1161
1165
|
import path2 from "path";
|
|
1166
|
+
import os2 from "os";
|
|
1162
1167
|
import crypto from "crypto";
|
|
1163
1168
|
function getKeyDir() {
|
|
1164
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path2.join(
|
|
1169
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path2.join(os2.homedir(), ".exe-os");
|
|
1165
1170
|
}
|
|
1166
1171
|
function getKeyPath() {
|
|
1167
1172
|
return path2.join(getKeyDir(), "master.key");
|
|
@@ -1462,6 +1467,28 @@ __export(store_exports, {
|
|
|
1462
1467
|
vectorToBlob: () => vectorToBlob,
|
|
1463
1468
|
writeMemory: () => writeMemory
|
|
1464
1469
|
});
|
|
1470
|
+
function isBusyError2(err) {
|
|
1471
|
+
if (err instanceof Error) {
|
|
1472
|
+
const msg = err.message.toLowerCase();
|
|
1473
|
+
return msg.includes("sqlite_busy") || msg.includes("database is locked");
|
|
1474
|
+
}
|
|
1475
|
+
return false;
|
|
1476
|
+
}
|
|
1477
|
+
async function retryOnBusy2(fn, label) {
|
|
1478
|
+
for (let attempt = 0; attempt <= INIT_MAX_RETRIES; attempt++) {
|
|
1479
|
+
try {
|
|
1480
|
+
return await fn();
|
|
1481
|
+
} catch (err) {
|
|
1482
|
+
if (!isBusyError2(err) || attempt === INIT_MAX_RETRIES) throw err;
|
|
1483
|
+
process.stderr.write(
|
|
1484
|
+
`[store] SQLITE_BUSY during ${label}, retry ${attempt + 1}/${INIT_MAX_RETRIES}
|
|
1485
|
+
`
|
|
1486
|
+
);
|
|
1487
|
+
await new Promise((r) => setTimeout(r, INIT_RETRY_DELAY_MS * (attempt + 1)));
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
throw new Error("unreachable");
|
|
1491
|
+
}
|
|
1465
1492
|
async function initStore(options) {
|
|
1466
1493
|
if (_flushTimer !== null) {
|
|
1467
1494
|
clearInterval(_flushTimer);
|
|
@@ -1490,14 +1517,17 @@ async function initStore(options) {
|
|
|
1490
1517
|
dbPath,
|
|
1491
1518
|
encryptionKey: hexKey
|
|
1492
1519
|
});
|
|
1493
|
-
await ensureSchema();
|
|
1520
|
+
await retryOnBusy2(() => ensureSchema(), "ensureSchema");
|
|
1494
1521
|
try {
|
|
1495
1522
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
1496
1523
|
initShardManager2(hexKey);
|
|
1497
1524
|
} catch {
|
|
1498
1525
|
}
|
|
1499
1526
|
const client = getClient();
|
|
1500
|
-
const vResult = await
|
|
1527
|
+
const vResult = await retryOnBusy2(
|
|
1528
|
+
() => client.execute("SELECT MAX(version) as max_v FROM memories"),
|
|
1529
|
+
"version-query"
|
|
1530
|
+
);
|
|
1501
1531
|
_nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
|
|
1502
1532
|
}
|
|
1503
1533
|
function classifyTier(record) {
|
|
@@ -1877,7 +1907,7 @@ async function getMemoryCardinality(agentId) {
|
|
|
1877
1907
|
return 0;
|
|
1878
1908
|
}
|
|
1879
1909
|
}
|
|
1880
|
-
var _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
1910
|
+
var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
1881
1911
|
var init_store = __esm({
|
|
1882
1912
|
"src/lib/store.ts"() {
|
|
1883
1913
|
"use strict";
|
|
@@ -1885,6 +1915,8 @@ var init_store = __esm({
|
|
|
1885
1915
|
init_database();
|
|
1886
1916
|
init_keychain();
|
|
1887
1917
|
init_config();
|
|
1918
|
+
INIT_MAX_RETRIES = 3;
|
|
1919
|
+
INIT_RETRY_DELAY_MS = 1e3;
|
|
1888
1920
|
_pendingRecords = [];
|
|
1889
1921
|
_batchSize = 20;
|
|
1890
1922
|
_flushIntervalMs = 1e4;
|
|
@@ -1992,6 +2024,10 @@ import path4 from "path";
|
|
|
1992
2024
|
import { fileURLToPath } from "url";
|
|
1993
2025
|
function handleData(chunk) {
|
|
1994
2026
|
_buffer += chunk.toString();
|
|
2027
|
+
if (_buffer.length > MAX_BUFFER) {
|
|
2028
|
+
_buffer = "";
|
|
2029
|
+
return;
|
|
2030
|
+
}
|
|
1995
2031
|
let newlineIdx;
|
|
1996
2032
|
while ((newlineIdx = _buffer.indexOf("\n")) !== -1) {
|
|
1997
2033
|
const line = _buffer.slice(0, newlineIdx).trim();
|
|
@@ -2299,7 +2335,7 @@ function disconnectClient() {
|
|
|
2299
2335
|
entry.resolve({ error: "Client disconnected" });
|
|
2300
2336
|
}
|
|
2301
2337
|
}
|
|
2302
|
-
var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, _socket, _connected, _buffer, _requestCount, HEALTH_CHECK_INTERVAL, _pending;
|
|
2338
|
+
var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, _socket, _connected, _buffer, _requestCount, HEALTH_CHECK_INTERVAL, _pending, MAX_BUFFER;
|
|
2303
2339
|
var init_exe_daemon_client = __esm({
|
|
2304
2340
|
"src/lib/exe-daemon-client.ts"() {
|
|
2305
2341
|
"use strict";
|
|
@@ -2316,6 +2352,7 @@ var init_exe_daemon_client = __esm({
|
|
|
2316
2352
|
_requestCount = 0;
|
|
2317
2353
|
HEALTH_CHECK_INTERVAL = 100;
|
|
2318
2354
|
_pending = /* @__PURE__ */ new Map();
|
|
2355
|
+
MAX_BUFFER = 1e7;
|
|
2319
2356
|
}
|
|
2320
2357
|
});
|
|
2321
2358
|
|
|
@@ -3236,10 +3273,11 @@ var timeout = setTimeout(() => {
|
|
|
3236
3273
|
process.exit(0);
|
|
3237
3274
|
}, 5e3);
|
|
3238
3275
|
timeout.unref();
|
|
3276
|
+
var MAX_INPUT_SIZE = 1e6;
|
|
3239
3277
|
var input = "";
|
|
3240
3278
|
process.stdin.setEncoding("utf8");
|
|
3241
3279
|
process.stdin.on("data", (chunk) => {
|
|
3242
|
-
input += chunk;
|
|
3280
|
+
if (input.length < MAX_INPUT_SIZE) input += chunk;
|
|
3243
3281
|
});
|
|
3244
3282
|
process.stdin.on("end", async () => {
|
|
3245
3283
|
try {
|
package/dist/hooks/stop.js
CHANGED
|
@@ -9,7 +9,7 @@ var __export = (target, all) => {
|
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
// src/lib/config.ts
|
|
12
|
-
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
12
|
+
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
13
13
|
import { readFileSync, existsSync, renameSync } from "fs";
|
|
14
14
|
import path from "path";
|
|
15
15
|
import os from "os";
|
|
@@ -327,6 +327,7 @@ async function ensureSchema() {
|
|
|
327
327
|
const client = getRawClient();
|
|
328
328
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
329
329
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
330
|
+
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
330
331
|
try {
|
|
331
332
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
332
333
|
} catch {
|
|
@@ -1135,12 +1136,13 @@ var init_database = __esm({
|
|
|
1135
1136
|
});
|
|
1136
1137
|
|
|
1137
1138
|
// src/lib/keychain.ts
|
|
1138
|
-
import { readFile as readFile2, writeFile as writeFile2, unlink, mkdir as mkdir2, chmod } from "fs/promises";
|
|
1139
|
+
import { readFile as readFile2, writeFile as writeFile2, unlink, mkdir as mkdir2, chmod as chmod2 } from "fs/promises";
|
|
1139
1140
|
import { existsSync as existsSync2 } from "fs";
|
|
1140
1141
|
import path3 from "path";
|
|
1142
|
+
import os2 from "os";
|
|
1141
1143
|
import crypto from "crypto";
|
|
1142
1144
|
function getKeyDir() {
|
|
1143
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path3.join(
|
|
1145
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path3.join(os2.homedir(), ".exe-os");
|
|
1144
1146
|
}
|
|
1145
1147
|
function getKeyPath() {
|
|
1146
1148
|
return path3.join(getKeyDir(), "master.key");
|
|
@@ -1441,6 +1443,28 @@ __export(store_exports, {
|
|
|
1441
1443
|
vectorToBlob: () => vectorToBlob,
|
|
1442
1444
|
writeMemory: () => writeMemory
|
|
1443
1445
|
});
|
|
1446
|
+
function isBusyError2(err) {
|
|
1447
|
+
if (err instanceof Error) {
|
|
1448
|
+
const msg = err.message.toLowerCase();
|
|
1449
|
+
return msg.includes("sqlite_busy") || msg.includes("database is locked");
|
|
1450
|
+
}
|
|
1451
|
+
return false;
|
|
1452
|
+
}
|
|
1453
|
+
async function retryOnBusy2(fn, label) {
|
|
1454
|
+
for (let attempt = 0; attempt <= INIT_MAX_RETRIES; attempt++) {
|
|
1455
|
+
try {
|
|
1456
|
+
return await fn();
|
|
1457
|
+
} catch (err) {
|
|
1458
|
+
if (!isBusyError2(err) || attempt === INIT_MAX_RETRIES) throw err;
|
|
1459
|
+
process.stderr.write(
|
|
1460
|
+
`[store] SQLITE_BUSY during ${label}, retry ${attempt + 1}/${INIT_MAX_RETRIES}
|
|
1461
|
+
`
|
|
1462
|
+
);
|
|
1463
|
+
await new Promise((r) => setTimeout(r, INIT_RETRY_DELAY_MS * (attempt + 1)));
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
throw new Error("unreachable");
|
|
1467
|
+
}
|
|
1444
1468
|
async function initStore(options) {
|
|
1445
1469
|
if (_flushTimer !== null) {
|
|
1446
1470
|
clearInterval(_flushTimer);
|
|
@@ -1469,14 +1493,17 @@ async function initStore(options) {
|
|
|
1469
1493
|
dbPath,
|
|
1470
1494
|
encryptionKey: hexKey
|
|
1471
1495
|
});
|
|
1472
|
-
await ensureSchema();
|
|
1496
|
+
await retryOnBusy2(() => ensureSchema(), "ensureSchema");
|
|
1473
1497
|
try {
|
|
1474
1498
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
1475
1499
|
initShardManager2(hexKey);
|
|
1476
1500
|
} catch {
|
|
1477
1501
|
}
|
|
1478
1502
|
const client = getClient();
|
|
1479
|
-
const vResult = await
|
|
1503
|
+
const vResult = await retryOnBusy2(
|
|
1504
|
+
() => client.execute("SELECT MAX(version) as max_v FROM memories"),
|
|
1505
|
+
"version-query"
|
|
1506
|
+
);
|
|
1480
1507
|
_nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
|
|
1481
1508
|
}
|
|
1482
1509
|
function classifyTier(record) {
|
|
@@ -1856,7 +1883,7 @@ async function getMemoryCardinality(agentId) {
|
|
|
1856
1883
|
return 0;
|
|
1857
1884
|
}
|
|
1858
1885
|
}
|
|
1859
|
-
var _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
1886
|
+
var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
1860
1887
|
var init_store = __esm({
|
|
1861
1888
|
"src/lib/store.ts"() {
|
|
1862
1889
|
"use strict";
|
|
@@ -1864,6 +1891,8 @@ var init_store = __esm({
|
|
|
1864
1891
|
init_database();
|
|
1865
1892
|
init_keychain();
|
|
1866
1893
|
init_config();
|
|
1894
|
+
INIT_MAX_RETRIES = 3;
|
|
1895
|
+
INIT_RETRY_DELAY_MS = 1e3;
|
|
1867
1896
|
_pendingRecords = [];
|
|
1868
1897
|
_batchSize = 20;
|
|
1869
1898
|
_flushIntervalMs = 1e4;
|
|
@@ -1991,10 +2020,11 @@ var timeout = setTimeout(() => {
|
|
|
1991
2020
|
process.exit(0);
|
|
1992
2021
|
}, 5e3);
|
|
1993
2022
|
timeout.unref();
|
|
2023
|
+
var MAX_INPUT_SIZE = 1e6;
|
|
1994
2024
|
var input = "";
|
|
1995
2025
|
process.stdin.setEncoding("utf8");
|
|
1996
2026
|
process.stdin.on("data", (chunk) => {
|
|
1997
|
-
input += chunk;
|
|
2027
|
+
if (input.length < MAX_INPUT_SIZE) input += chunk;
|
|
1998
2028
|
});
|
|
1999
2029
|
process.stdin.on("end", () => {
|
|
2000
2030
|
try {
|
|
@@ -9,7 +9,7 @@ var __export = (target, all) => {
|
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
// src/lib/config.ts
|
|
12
|
-
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
12
|
+
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
13
13
|
import { readFileSync, existsSync, renameSync } from "fs";
|
|
14
14
|
import path from "path";
|
|
15
15
|
import os from "os";
|
|
@@ -308,6 +308,7 @@ async function ensureSchema() {
|
|
|
308
308
|
const client = getRawClient();
|
|
309
309
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
310
310
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
311
|
+
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
311
312
|
try {
|
|
312
313
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
313
314
|
} catch {
|
|
@@ -1116,12 +1117,13 @@ var init_database = __esm({
|
|
|
1116
1117
|
});
|
|
1117
1118
|
|
|
1118
1119
|
// src/lib/keychain.ts
|
|
1119
|
-
import { readFile as readFile2, writeFile as writeFile2, unlink, mkdir as mkdir2, chmod } from "fs/promises";
|
|
1120
|
+
import { readFile as readFile2, writeFile as writeFile2, unlink, mkdir as mkdir2, chmod as chmod2 } from "fs/promises";
|
|
1120
1121
|
import { existsSync as existsSync2 } from "fs";
|
|
1121
1122
|
import path3 from "path";
|
|
1123
|
+
import os2 from "os";
|
|
1122
1124
|
import crypto from "crypto";
|
|
1123
1125
|
function getKeyDir() {
|
|
1124
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path3.join(
|
|
1126
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path3.join(os2.homedir(), ".exe-os");
|
|
1125
1127
|
}
|
|
1126
1128
|
function getKeyPath() {
|
|
1127
1129
|
return path3.join(getKeyDir(), "master.key");
|
|
@@ -1422,6 +1424,28 @@ __export(store_exports, {
|
|
|
1422
1424
|
vectorToBlob: () => vectorToBlob,
|
|
1423
1425
|
writeMemory: () => writeMemory
|
|
1424
1426
|
});
|
|
1427
|
+
function isBusyError2(err) {
|
|
1428
|
+
if (err instanceof Error) {
|
|
1429
|
+
const msg = err.message.toLowerCase();
|
|
1430
|
+
return msg.includes("sqlite_busy") || msg.includes("database is locked");
|
|
1431
|
+
}
|
|
1432
|
+
return false;
|
|
1433
|
+
}
|
|
1434
|
+
async function retryOnBusy2(fn, label) {
|
|
1435
|
+
for (let attempt = 0; attempt <= INIT_MAX_RETRIES; attempt++) {
|
|
1436
|
+
try {
|
|
1437
|
+
return await fn();
|
|
1438
|
+
} catch (err) {
|
|
1439
|
+
if (!isBusyError2(err) || attempt === INIT_MAX_RETRIES) throw err;
|
|
1440
|
+
process.stderr.write(
|
|
1441
|
+
`[store] SQLITE_BUSY during ${label}, retry ${attempt + 1}/${INIT_MAX_RETRIES}
|
|
1442
|
+
`
|
|
1443
|
+
);
|
|
1444
|
+
await new Promise((r) => setTimeout(r, INIT_RETRY_DELAY_MS * (attempt + 1)));
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
throw new Error("unreachable");
|
|
1448
|
+
}
|
|
1425
1449
|
async function initStore(options) {
|
|
1426
1450
|
if (_flushTimer !== null) {
|
|
1427
1451
|
clearInterval(_flushTimer);
|
|
@@ -1450,14 +1474,17 @@ async function initStore(options) {
|
|
|
1450
1474
|
dbPath,
|
|
1451
1475
|
encryptionKey: hexKey
|
|
1452
1476
|
});
|
|
1453
|
-
await ensureSchema();
|
|
1477
|
+
await retryOnBusy2(() => ensureSchema(), "ensureSchema");
|
|
1454
1478
|
try {
|
|
1455
1479
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
1456
1480
|
initShardManager2(hexKey);
|
|
1457
1481
|
} catch {
|
|
1458
1482
|
}
|
|
1459
1483
|
const client = getClient();
|
|
1460
|
-
const vResult = await
|
|
1484
|
+
const vResult = await retryOnBusy2(
|
|
1485
|
+
() => client.execute("SELECT MAX(version) as max_v FROM memories"),
|
|
1486
|
+
"version-query"
|
|
1487
|
+
);
|
|
1461
1488
|
_nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
|
|
1462
1489
|
}
|
|
1463
1490
|
function classifyTier(record) {
|
|
@@ -1837,7 +1864,7 @@ async function getMemoryCardinality(agentId) {
|
|
|
1837
1864
|
return 0;
|
|
1838
1865
|
}
|
|
1839
1866
|
}
|
|
1840
|
-
var _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
1867
|
+
var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
1841
1868
|
var init_store = __esm({
|
|
1842
1869
|
"src/lib/store.ts"() {
|
|
1843
1870
|
"use strict";
|
|
@@ -1845,6 +1872,8 @@ var init_store = __esm({
|
|
|
1845
1872
|
init_database();
|
|
1846
1873
|
init_keychain();
|
|
1847
1874
|
init_config();
|
|
1875
|
+
INIT_MAX_RETRIES = 3;
|
|
1876
|
+
INIT_RETRY_DELAY_MS = 1e3;
|
|
1848
1877
|
_pendingRecords = [];
|
|
1849
1878
|
_batchSize = 20;
|
|
1850
1879
|
_flushIntervalMs = 1e4;
|
|
@@ -1952,10 +1981,11 @@ var timeout = setTimeout(() => {
|
|
|
1952
1981
|
process.exit(0);
|
|
1953
1982
|
}, 5e3);
|
|
1954
1983
|
timeout.unref();
|
|
1984
|
+
var MAX_INPUT_SIZE = 1e6;
|
|
1955
1985
|
var input = "";
|
|
1956
1986
|
process.stdin.setEncoding("utf8");
|
|
1957
1987
|
process.stdin.on("data", (chunk) => {
|
|
1958
|
-
input += chunk;
|
|
1988
|
+
if (input.length < MAX_INPUT_SIZE) input += chunk;
|
|
1959
1989
|
});
|
|
1960
1990
|
process.stdin.on("end", async () => {
|
|
1961
1991
|
try {
|