@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
|
};
|
|
@@ -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) {
|
|
@@ -533,6 +526,7 @@ async function ensureSchema() {
|
|
|
533
526
|
const client = getRawClient();
|
|
534
527
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
535
528
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
529
|
+
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
536
530
|
try {
|
|
537
531
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
538
532
|
} catch {
|
|
@@ -1334,11 +1328,12 @@ async function disposeDatabase() {
|
|
|
1334
1328
|
import { readFile, writeFile, unlink, mkdir, chmod } from "fs/promises";
|
|
1335
1329
|
import { existsSync } from "fs";
|
|
1336
1330
|
import path from "path";
|
|
1331
|
+
import os from "os";
|
|
1337
1332
|
import crypto from "crypto";
|
|
1338
1333
|
var SERVICE = "exe-mem";
|
|
1339
1334
|
var ACCOUNT = "master-key";
|
|
1340
1335
|
function getKeyDir() {
|
|
1341
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path.join(
|
|
1336
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path.join(os.homedir(), ".exe-os");
|
|
1342
1337
|
}
|
|
1343
1338
|
function getKeyPath() {
|
|
1344
1339
|
return path.join(getKeyDir(), "master.key");
|
|
@@ -1375,6 +1370,30 @@ async function getMasterKey() {
|
|
|
1375
1370
|
|
|
1376
1371
|
// src/lib/store.ts
|
|
1377
1372
|
init_config();
|
|
1373
|
+
var INIT_MAX_RETRIES = 3;
|
|
1374
|
+
var INIT_RETRY_DELAY_MS = 1e3;
|
|
1375
|
+
function isBusyError2(err) {
|
|
1376
|
+
if (err instanceof Error) {
|
|
1377
|
+
const msg = err.message.toLowerCase();
|
|
1378
|
+
return msg.includes("sqlite_busy") || msg.includes("database is locked");
|
|
1379
|
+
}
|
|
1380
|
+
return false;
|
|
1381
|
+
}
|
|
1382
|
+
async function retryOnBusy2(fn, label) {
|
|
1383
|
+
for (let attempt = 0; attempt <= INIT_MAX_RETRIES; attempt++) {
|
|
1384
|
+
try {
|
|
1385
|
+
return await fn();
|
|
1386
|
+
} catch (err) {
|
|
1387
|
+
if (!isBusyError2(err) || attempt === INIT_MAX_RETRIES) throw err;
|
|
1388
|
+
process.stderr.write(
|
|
1389
|
+
`[store] SQLITE_BUSY during ${label}, retry ${attempt + 1}/${INIT_MAX_RETRIES}
|
|
1390
|
+
`
|
|
1391
|
+
);
|
|
1392
|
+
await new Promise((r) => setTimeout(r, INIT_RETRY_DELAY_MS * (attempt + 1)));
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
throw new Error("unreachable");
|
|
1396
|
+
}
|
|
1378
1397
|
var _pendingRecords = [];
|
|
1379
1398
|
var _batchSize = 20;
|
|
1380
1399
|
var _flushIntervalMs = 1e4;
|
|
@@ -1409,14 +1428,17 @@ async function initStore(options) {
|
|
|
1409
1428
|
dbPath,
|
|
1410
1429
|
encryptionKey: hexKey
|
|
1411
1430
|
});
|
|
1412
|
-
await ensureSchema();
|
|
1431
|
+
await retryOnBusy2(() => ensureSchema(), "ensureSchema");
|
|
1413
1432
|
try {
|
|
1414
1433
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
1415
1434
|
initShardManager2(hexKey);
|
|
1416
1435
|
} catch {
|
|
1417
1436
|
}
|
|
1418
1437
|
const client = getClient();
|
|
1419
|
-
const vResult = await
|
|
1438
|
+
const vResult = await retryOnBusy2(
|
|
1439
|
+
() => client.execute("SELECT MAX(version) as max_v FROM memories"),
|
|
1440
|
+
"version-query"
|
|
1441
|
+
);
|
|
1420
1442
|
_nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
|
|
1421
1443
|
}
|
|
1422
1444
|
async function flushBatch() {
|
package/dist/bin/wiki-sync.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) {
|
|
@@ -533,6 +526,7 @@ async function ensureSchema() {
|
|
|
533
526
|
const client = getRawClient();
|
|
534
527
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
535
528
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
529
|
+
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
536
530
|
try {
|
|
537
531
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
538
532
|
} catch {
|
|
@@ -1334,11 +1328,12 @@ async function disposeDatabase() {
|
|
|
1334
1328
|
import { readFile, writeFile, unlink, mkdir, chmod } from "fs/promises";
|
|
1335
1329
|
import { existsSync } from "fs";
|
|
1336
1330
|
import path from "path";
|
|
1331
|
+
import os from "os";
|
|
1337
1332
|
import crypto from "crypto";
|
|
1338
1333
|
var SERVICE = "exe-mem";
|
|
1339
1334
|
var ACCOUNT = "master-key";
|
|
1340
1335
|
function getKeyDir() {
|
|
1341
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path.join(
|
|
1336
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path.join(os.homedir(), ".exe-os");
|
|
1342
1337
|
}
|
|
1343
1338
|
function getKeyPath() {
|
|
1344
1339
|
return path.join(getKeyDir(), "master.key");
|
|
@@ -1375,6 +1370,30 @@ async function getMasterKey() {
|
|
|
1375
1370
|
|
|
1376
1371
|
// src/lib/store.ts
|
|
1377
1372
|
init_config();
|
|
1373
|
+
var INIT_MAX_RETRIES = 3;
|
|
1374
|
+
var INIT_RETRY_DELAY_MS = 1e3;
|
|
1375
|
+
function isBusyError2(err) {
|
|
1376
|
+
if (err instanceof Error) {
|
|
1377
|
+
const msg = err.message.toLowerCase();
|
|
1378
|
+
return msg.includes("sqlite_busy") || msg.includes("database is locked");
|
|
1379
|
+
}
|
|
1380
|
+
return false;
|
|
1381
|
+
}
|
|
1382
|
+
async function retryOnBusy2(fn, label) {
|
|
1383
|
+
for (let attempt = 0; attempt <= INIT_MAX_RETRIES; attempt++) {
|
|
1384
|
+
try {
|
|
1385
|
+
return await fn();
|
|
1386
|
+
} catch (err) {
|
|
1387
|
+
if (!isBusyError2(err) || attempt === INIT_MAX_RETRIES) throw err;
|
|
1388
|
+
process.stderr.write(
|
|
1389
|
+
`[store] SQLITE_BUSY during ${label}, retry ${attempt + 1}/${INIT_MAX_RETRIES}
|
|
1390
|
+
`
|
|
1391
|
+
);
|
|
1392
|
+
await new Promise((r) => setTimeout(r, INIT_RETRY_DELAY_MS * (attempt + 1)));
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
throw new Error("unreachable");
|
|
1396
|
+
}
|
|
1378
1397
|
var _pendingRecords = [];
|
|
1379
1398
|
var _batchSize = 20;
|
|
1380
1399
|
var _flushIntervalMs = 1e4;
|
|
@@ -1409,14 +1428,17 @@ async function initStore(options) {
|
|
|
1409
1428
|
dbPath,
|
|
1410
1429
|
encryptionKey: hexKey
|
|
1411
1430
|
});
|
|
1412
|
-
await ensureSchema();
|
|
1431
|
+
await retryOnBusy2(() => ensureSchema(), "ensureSchema");
|
|
1413
1432
|
try {
|
|
1414
1433
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
1415
1434
|
initShardManager2(hexKey);
|
|
1416
1435
|
} catch {
|
|
1417
1436
|
}
|
|
1418
1437
|
const client = getClient();
|
|
1419
|
-
const vResult = await
|
|
1438
|
+
const vResult = await retryOnBusy2(
|
|
1439
|
+
() => client.execute("SELECT MAX(version) as max_v FROM memories"),
|
|
1440
|
+
"version-query"
|
|
1441
|
+
);
|
|
1420
1442
|
_nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
|
|
1421
1443
|
}
|
|
1422
1444
|
async function flushBatch() {
|
|
@@ -1577,7 +1599,8 @@ async function wikiRequest(config, path4, method = "GET", body) {
|
|
|
1577
1599
|
const response = await fetch(url, {
|
|
1578
1600
|
method,
|
|
1579
1601
|
headers,
|
|
1580
|
-
body: body ? JSON.stringify(body) : void 0
|
|
1602
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
1603
|
+
signal: AbortSignal.timeout(3e4)
|
|
1581
1604
|
});
|
|
1582
1605
|
if (!response.ok) {
|
|
1583
1606
|
throw new Error(`Wiki API ${method} ${path4}: ${response.status} ${response.statusText}`);
|