@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
package/dist/bin/git-sweep.js
CHANGED
|
@@ -120,6 +120,7 @@ async function ensureSchema() {
|
|
|
120
120
|
const client = getRawClient();
|
|
121
121
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
122
122
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
123
|
+
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
123
124
|
try {
|
|
124
125
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
125
126
|
} catch {
|
|
@@ -931,9 +932,10 @@ var init_database = __esm({
|
|
|
931
932
|
import { readFile, writeFile, unlink, mkdir, chmod } from "fs/promises";
|
|
932
933
|
import { existsSync } from "fs";
|
|
933
934
|
import path from "path";
|
|
935
|
+
import os from "os";
|
|
934
936
|
import crypto from "crypto";
|
|
935
937
|
function getKeyDir() {
|
|
936
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path.join(
|
|
938
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path.join(os.homedir(), ".exe-os");
|
|
937
939
|
}
|
|
938
940
|
function getKeyPath() {
|
|
939
941
|
return path.join(getKeyDir(), "master.key");
|
|
@@ -977,15 +979,15 @@ var init_keychain = __esm({
|
|
|
977
979
|
});
|
|
978
980
|
|
|
979
981
|
// src/lib/config.ts
|
|
980
|
-
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
982
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, chmod as chmod2 } from "fs/promises";
|
|
981
983
|
import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
|
|
982
984
|
import path2 from "path";
|
|
983
|
-
import
|
|
985
|
+
import os2 from "os";
|
|
984
986
|
function resolveDataDir() {
|
|
985
987
|
if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
|
|
986
988
|
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
987
|
-
const newDir = path2.join(
|
|
988
|
-
const legacyDir = path2.join(
|
|
989
|
+
const newDir = path2.join(os2.homedir(), ".exe-os");
|
|
990
|
+
const legacyDir = path2.join(os2.homedir(), ".exe-mem");
|
|
989
991
|
if (!existsSync2(newDir) && existsSync2(legacyDir)) {
|
|
990
992
|
try {
|
|
991
993
|
renameSync(legacyDir, newDir);
|
|
@@ -1072,7 +1074,7 @@ async function loadConfig() {
|
|
|
1072
1074
|
normalizeAutoUpdate(migratedCfg);
|
|
1073
1075
|
const config = { ...DEFAULT_CONFIG, dbPath: path2.join(dir, "memories.db"), ...migratedCfg };
|
|
1074
1076
|
if (config.dbPath.startsWith("~")) {
|
|
1075
|
-
config.dbPath = config.dbPath.replace(/^~/,
|
|
1077
|
+
config.dbPath = config.dbPath.replace(/^~/, os2.homedir());
|
|
1076
1078
|
}
|
|
1077
1079
|
return config;
|
|
1078
1080
|
} catch {
|
|
@@ -1423,6 +1425,28 @@ __export(store_exports, {
|
|
|
1423
1425
|
vectorToBlob: () => vectorToBlob,
|
|
1424
1426
|
writeMemory: () => writeMemory
|
|
1425
1427
|
});
|
|
1428
|
+
function isBusyError2(err) {
|
|
1429
|
+
if (err instanceof Error) {
|
|
1430
|
+
const msg = err.message.toLowerCase();
|
|
1431
|
+
return msg.includes("sqlite_busy") || msg.includes("database is locked");
|
|
1432
|
+
}
|
|
1433
|
+
return false;
|
|
1434
|
+
}
|
|
1435
|
+
async function retryOnBusy2(fn, label) {
|
|
1436
|
+
for (let attempt = 0; attempt <= INIT_MAX_RETRIES; attempt++) {
|
|
1437
|
+
try {
|
|
1438
|
+
return await fn();
|
|
1439
|
+
} catch (err) {
|
|
1440
|
+
if (!isBusyError2(err) || attempt === INIT_MAX_RETRIES) throw err;
|
|
1441
|
+
process.stderr.write(
|
|
1442
|
+
`[store] SQLITE_BUSY during ${label}, retry ${attempt + 1}/${INIT_MAX_RETRIES}
|
|
1443
|
+
`
|
|
1444
|
+
);
|
|
1445
|
+
await new Promise((r) => setTimeout(r, INIT_RETRY_DELAY_MS * (attempt + 1)));
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
throw new Error("unreachable");
|
|
1449
|
+
}
|
|
1426
1450
|
async function initStore(options) {
|
|
1427
1451
|
if (_flushTimer !== null) {
|
|
1428
1452
|
clearInterval(_flushTimer);
|
|
@@ -1451,14 +1475,17 @@ async function initStore(options) {
|
|
|
1451
1475
|
dbPath,
|
|
1452
1476
|
encryptionKey: hexKey
|
|
1453
1477
|
});
|
|
1454
|
-
await ensureSchema();
|
|
1478
|
+
await retryOnBusy2(() => ensureSchema(), "ensureSchema");
|
|
1455
1479
|
try {
|
|
1456
1480
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
1457
1481
|
initShardManager2(hexKey);
|
|
1458
1482
|
} catch {
|
|
1459
1483
|
}
|
|
1460
1484
|
const client = getClient();
|
|
1461
|
-
const vResult = await
|
|
1485
|
+
const vResult = await retryOnBusy2(
|
|
1486
|
+
() => client.execute("SELECT MAX(version) as max_v FROM memories"),
|
|
1487
|
+
"version-query"
|
|
1488
|
+
);
|
|
1462
1489
|
_nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
|
|
1463
1490
|
}
|
|
1464
1491
|
function classifyTier(record) {
|
|
@@ -1838,7 +1865,7 @@ async function getMemoryCardinality(agentId) {
|
|
|
1838
1865
|
return 0;
|
|
1839
1866
|
}
|
|
1840
1867
|
}
|
|
1841
|
-
var _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
1868
|
+
var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
1842
1869
|
var init_store = __esm({
|
|
1843
1870
|
"src/lib/store.ts"() {
|
|
1844
1871
|
"use strict";
|
|
@@ -1846,6 +1873,8 @@ var init_store = __esm({
|
|
|
1846
1873
|
init_database();
|
|
1847
1874
|
init_keychain();
|
|
1848
1875
|
init_config();
|
|
1876
|
+
INIT_MAX_RETRIES = 3;
|
|
1877
|
+
INIT_RETRY_DELAY_MS = 1e3;
|
|
1849
1878
|
_pendingRecords = [];
|
|
1850
1879
|
_batchSize = 20;
|
|
1851
1880
|
_flushIntervalMs = 1e4;
|
|
@@ -10,15 +10,15 @@ var __export = (target, all) => {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
// src/lib/config.ts
|
|
13
|
-
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";
|
|
14
14
|
import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
|
|
15
15
|
import path2 from "path";
|
|
16
|
-
import
|
|
16
|
+
import os2 from "os";
|
|
17
17
|
function resolveDataDir() {
|
|
18
18
|
if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
|
|
19
19
|
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
20
|
-
const newDir = path2.join(
|
|
21
|
-
const legacyDir = path2.join(
|
|
20
|
+
const newDir = path2.join(os2.homedir(), ".exe-os");
|
|
21
|
+
const legacyDir = path2.join(os2.homedir(), ".exe-mem");
|
|
22
22
|
if (!existsSync2(newDir) && existsSync2(legacyDir)) {
|
|
23
23
|
try {
|
|
24
24
|
renameSync(legacyDir, newDir);
|
|
@@ -105,7 +105,7 @@ async function loadConfig() {
|
|
|
105
105
|
normalizeAutoUpdate(migratedCfg);
|
|
106
106
|
const config = { ...DEFAULT_CONFIG, dbPath: path2.join(dir, "memories.db"), ...migratedCfg };
|
|
107
107
|
if (config.dbPath.startsWith("~")) {
|
|
108
|
-
config.dbPath = config.dbPath.replace(/^~/,
|
|
108
|
+
config.dbPath = config.dbPath.replace(/^~/, os2.homedir());
|
|
109
109
|
}
|
|
110
110
|
return config;
|
|
111
111
|
} catch {
|
|
@@ -526,6 +526,7 @@ async function ensureSchema() {
|
|
|
526
526
|
const client = getRawClient();
|
|
527
527
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
528
528
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
529
|
+
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
529
530
|
try {
|
|
530
531
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
531
532
|
} catch {
|
|
@@ -1327,11 +1328,12 @@ async function disposeDatabase() {
|
|
|
1327
1328
|
import { readFile, writeFile, unlink, mkdir, chmod } from "fs/promises";
|
|
1328
1329
|
import { existsSync } from "fs";
|
|
1329
1330
|
import path from "path";
|
|
1331
|
+
import os from "os";
|
|
1330
1332
|
import crypto from "crypto";
|
|
1331
1333
|
var SERVICE = "exe-mem";
|
|
1332
1334
|
var ACCOUNT = "master-key";
|
|
1333
1335
|
function getKeyDir() {
|
|
1334
|
-
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");
|
|
1335
1337
|
}
|
|
1336
1338
|
function getKeyPath() {
|
|
1337
1339
|
return path.join(getKeyDir(), "master.key");
|
|
@@ -1368,6 +1370,30 @@ async function getMasterKey() {
|
|
|
1368
1370
|
|
|
1369
1371
|
// src/lib/store.ts
|
|
1370
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
|
+
}
|
|
1371
1397
|
var _pendingRecords = [];
|
|
1372
1398
|
var _batchSize = 20;
|
|
1373
1399
|
var _flushIntervalMs = 1e4;
|
|
@@ -1402,14 +1428,17 @@ async function initStore(options) {
|
|
|
1402
1428
|
dbPath,
|
|
1403
1429
|
encryptionKey: hexKey
|
|
1404
1430
|
});
|
|
1405
|
-
await ensureSchema();
|
|
1431
|
+
await retryOnBusy2(() => ensureSchema(), "ensureSchema");
|
|
1406
1432
|
try {
|
|
1407
1433
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
1408
1434
|
initShardManager2(hexKey);
|
|
1409
1435
|
} catch {
|
|
1410
1436
|
}
|
|
1411
1437
|
const client = getClient();
|
|
1412
|
-
const vResult = await
|
|
1438
|
+
const vResult = await retryOnBusy2(
|
|
1439
|
+
() => client.execute("SELECT MAX(version) as max_v FROM memories"),
|
|
1440
|
+
"version-query"
|
|
1441
|
+
);
|
|
1413
1442
|
_nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
|
|
1414
1443
|
}
|
|
1415
1444
|
async function flushBatch() {
|
package/dist/bin/graph-export.js
CHANGED
|
@@ -10,15 +10,15 @@ var __export = (target, all) => {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
// src/lib/config.ts
|
|
13
|
-
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";
|
|
14
14
|
import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
|
|
15
15
|
import path2 from "path";
|
|
16
|
-
import
|
|
16
|
+
import os2 from "os";
|
|
17
17
|
function resolveDataDir() {
|
|
18
18
|
if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
|
|
19
19
|
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
20
|
-
const newDir = path2.join(
|
|
21
|
-
const legacyDir = path2.join(
|
|
20
|
+
const newDir = path2.join(os2.homedir(), ".exe-os");
|
|
21
|
+
const legacyDir = path2.join(os2.homedir(), ".exe-mem");
|
|
22
22
|
if (!existsSync2(newDir) && existsSync2(legacyDir)) {
|
|
23
23
|
try {
|
|
24
24
|
renameSync(legacyDir, newDir);
|
|
@@ -105,7 +105,7 @@ async function loadConfig() {
|
|
|
105
105
|
normalizeAutoUpdate(migratedCfg);
|
|
106
106
|
const config = { ...DEFAULT_CONFIG, dbPath: path2.join(dir, "memories.db"), ...migratedCfg };
|
|
107
107
|
if (config.dbPath.startsWith("~")) {
|
|
108
|
-
config.dbPath = config.dbPath.replace(/^~/,
|
|
108
|
+
config.dbPath = config.dbPath.replace(/^~/, os2.homedir());
|
|
109
109
|
}
|
|
110
110
|
return config;
|
|
111
111
|
} catch {
|
|
@@ -530,6 +530,7 @@ async function ensureSchema() {
|
|
|
530
530
|
const client = getRawClient();
|
|
531
531
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
532
532
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
533
|
+
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
533
534
|
try {
|
|
534
535
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
535
536
|
} catch {
|
|
@@ -1331,11 +1332,12 @@ async function disposeDatabase() {
|
|
|
1331
1332
|
import { readFile, writeFile, unlink, mkdir, chmod } from "fs/promises";
|
|
1332
1333
|
import { existsSync } from "fs";
|
|
1333
1334
|
import path from "path";
|
|
1335
|
+
import os from "os";
|
|
1334
1336
|
import crypto from "crypto";
|
|
1335
1337
|
var SERVICE = "exe-mem";
|
|
1336
1338
|
var ACCOUNT = "master-key";
|
|
1337
1339
|
function getKeyDir() {
|
|
1338
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path.join(
|
|
1340
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path.join(os.homedir(), ".exe-os");
|
|
1339
1341
|
}
|
|
1340
1342
|
function getKeyPath() {
|
|
1341
1343
|
return path.join(getKeyDir(), "master.key");
|
|
@@ -1372,6 +1374,30 @@ async function getMasterKey() {
|
|
|
1372
1374
|
|
|
1373
1375
|
// src/lib/store.ts
|
|
1374
1376
|
init_config();
|
|
1377
|
+
var INIT_MAX_RETRIES = 3;
|
|
1378
|
+
var INIT_RETRY_DELAY_MS = 1e3;
|
|
1379
|
+
function isBusyError2(err) {
|
|
1380
|
+
if (err instanceof Error) {
|
|
1381
|
+
const msg = err.message.toLowerCase();
|
|
1382
|
+
return msg.includes("sqlite_busy") || msg.includes("database is locked");
|
|
1383
|
+
}
|
|
1384
|
+
return false;
|
|
1385
|
+
}
|
|
1386
|
+
async function retryOnBusy2(fn, label) {
|
|
1387
|
+
for (let attempt = 0; attempt <= INIT_MAX_RETRIES; attempt++) {
|
|
1388
|
+
try {
|
|
1389
|
+
return await fn();
|
|
1390
|
+
} catch (err) {
|
|
1391
|
+
if (!isBusyError2(err) || attempt === INIT_MAX_RETRIES) throw err;
|
|
1392
|
+
process.stderr.write(
|
|
1393
|
+
`[store] SQLITE_BUSY during ${label}, retry ${attempt + 1}/${INIT_MAX_RETRIES}
|
|
1394
|
+
`
|
|
1395
|
+
);
|
|
1396
|
+
await new Promise((r) => setTimeout(r, INIT_RETRY_DELAY_MS * (attempt + 1)));
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
throw new Error("unreachable");
|
|
1400
|
+
}
|
|
1375
1401
|
var _pendingRecords = [];
|
|
1376
1402
|
var _batchSize = 20;
|
|
1377
1403
|
var _flushIntervalMs = 1e4;
|
|
@@ -1406,14 +1432,17 @@ async function initStore(options) {
|
|
|
1406
1432
|
dbPath,
|
|
1407
1433
|
encryptionKey: hexKey
|
|
1408
1434
|
});
|
|
1409
|
-
await ensureSchema();
|
|
1435
|
+
await retryOnBusy2(() => ensureSchema(), "ensureSchema");
|
|
1410
1436
|
try {
|
|
1411
1437
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
1412
1438
|
initShardManager2(hexKey);
|
|
1413
1439
|
} catch {
|
|
1414
1440
|
}
|
|
1415
1441
|
const client = getClient();
|
|
1416
|
-
const vResult = await
|
|
1442
|
+
const vResult = await retryOnBusy2(
|
|
1443
|
+
() => client.execute("SELECT MAX(version) as max_v FROM memories"),
|
|
1444
|
+
"version-query"
|
|
1445
|
+
);
|
|
1417
1446
|
_nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
|
|
1418
1447
|
}
|
|
1419
1448
|
async function flushBatch() {
|
package/dist/bin/install.js
CHANGED
|
@@ -25,7 +25,7 @@ import { execSync } from "child_process";
|
|
|
25
25
|
import path2 from "path";
|
|
26
26
|
|
|
27
27
|
// src/lib/config.ts
|
|
28
|
-
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
28
|
+
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
29
29
|
import { readFileSync, existsSync, renameSync } from "fs";
|
|
30
30
|
import path from "path";
|
|
31
31
|
import os from "os";
|
package/dist/bin/scan-tasks.js
CHANGED
|
@@ -111,6 +111,7 @@ async function ensureSchema() {
|
|
|
111
111
|
const client = getRawClient();
|
|
112
112
|
await client.execute("PRAGMA journal_mode = WAL");
|
|
113
113
|
await client.execute("PRAGMA busy_timeout = 30000");
|
|
114
|
+
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
114
115
|
try {
|
|
115
116
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
116
117
|
} catch {
|
|
@@ -931,9 +932,10 @@ var init_memory = __esm({
|
|
|
931
932
|
import { readFile, writeFile, unlink, mkdir, chmod } from "fs/promises";
|
|
932
933
|
import { existsSync } from "fs";
|
|
933
934
|
import path from "path";
|
|
935
|
+
import os from "os";
|
|
934
936
|
import crypto from "crypto";
|
|
935
937
|
function getKeyDir() {
|
|
936
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path.join(
|
|
938
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path.join(os.homedir(), ".exe-os");
|
|
937
939
|
}
|
|
938
940
|
function getKeyPath() {
|
|
939
941
|
return path.join(getKeyDir(), "master.key");
|
|
@@ -977,15 +979,15 @@ var init_keychain = __esm({
|
|
|
977
979
|
});
|
|
978
980
|
|
|
979
981
|
// src/lib/config.ts
|
|
980
|
-
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
982
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, chmod as chmod2 } from "fs/promises";
|
|
981
983
|
import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
|
|
982
984
|
import path2 from "path";
|
|
983
|
-
import
|
|
985
|
+
import os2 from "os";
|
|
984
986
|
function resolveDataDir() {
|
|
985
987
|
if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
|
|
986
988
|
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
987
|
-
const newDir = path2.join(
|
|
988
|
-
const legacyDir = path2.join(
|
|
989
|
+
const newDir = path2.join(os2.homedir(), ".exe-os");
|
|
990
|
+
const legacyDir = path2.join(os2.homedir(), ".exe-mem");
|
|
989
991
|
if (!existsSync2(newDir) && existsSync2(legacyDir)) {
|
|
990
992
|
try {
|
|
991
993
|
renameSync(legacyDir, newDir);
|
|
@@ -1072,7 +1074,7 @@ async function loadConfig() {
|
|
|
1072
1074
|
normalizeAutoUpdate(migratedCfg);
|
|
1073
1075
|
const config = { ...DEFAULT_CONFIG, dbPath: path2.join(dir, "memories.db"), ...migratedCfg };
|
|
1074
1076
|
if (config.dbPath.startsWith("~")) {
|
|
1075
|
-
config.dbPath = config.dbPath.replace(/^~/,
|
|
1077
|
+
config.dbPath = config.dbPath.replace(/^~/, os2.homedir());
|
|
1076
1078
|
}
|
|
1077
1079
|
return config;
|
|
1078
1080
|
} catch {
|
|
@@ -1423,6 +1425,28 @@ __export(store_exports, {
|
|
|
1423
1425
|
vectorToBlob: () => vectorToBlob,
|
|
1424
1426
|
writeMemory: () => writeMemory
|
|
1425
1427
|
});
|
|
1428
|
+
function isBusyError2(err) {
|
|
1429
|
+
if (err instanceof Error) {
|
|
1430
|
+
const msg = err.message.toLowerCase();
|
|
1431
|
+
return msg.includes("sqlite_busy") || msg.includes("database is locked");
|
|
1432
|
+
}
|
|
1433
|
+
return false;
|
|
1434
|
+
}
|
|
1435
|
+
async function retryOnBusy2(fn, label) {
|
|
1436
|
+
for (let attempt = 0; attempt <= INIT_MAX_RETRIES; attempt++) {
|
|
1437
|
+
try {
|
|
1438
|
+
return await fn();
|
|
1439
|
+
} catch (err) {
|
|
1440
|
+
if (!isBusyError2(err) || attempt === INIT_MAX_RETRIES) throw err;
|
|
1441
|
+
process.stderr.write(
|
|
1442
|
+
`[store] SQLITE_BUSY during ${label}, retry ${attempt + 1}/${INIT_MAX_RETRIES}
|
|
1443
|
+
`
|
|
1444
|
+
);
|
|
1445
|
+
await new Promise((r) => setTimeout(r, INIT_RETRY_DELAY_MS * (attempt + 1)));
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
throw new Error("unreachable");
|
|
1449
|
+
}
|
|
1426
1450
|
async function initStore(options) {
|
|
1427
1451
|
if (_flushTimer !== null) {
|
|
1428
1452
|
clearInterval(_flushTimer);
|
|
@@ -1451,14 +1475,17 @@ async function initStore(options) {
|
|
|
1451
1475
|
dbPath,
|
|
1452
1476
|
encryptionKey: hexKey
|
|
1453
1477
|
});
|
|
1454
|
-
await ensureSchema();
|
|
1478
|
+
await retryOnBusy2(() => ensureSchema(), "ensureSchema");
|
|
1455
1479
|
try {
|
|
1456
1480
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
1457
1481
|
initShardManager2(hexKey);
|
|
1458
1482
|
} catch {
|
|
1459
1483
|
}
|
|
1460
1484
|
const client = getClient();
|
|
1461
|
-
const vResult = await
|
|
1485
|
+
const vResult = await retryOnBusy2(
|
|
1486
|
+
() => client.execute("SELECT MAX(version) as max_v FROM memories"),
|
|
1487
|
+
"version-query"
|
|
1488
|
+
);
|
|
1462
1489
|
_nextVersion = (Number(vResult.rows[0]?.max_v) || 0) + 1;
|
|
1463
1490
|
}
|
|
1464
1491
|
function classifyTier(record) {
|
|
@@ -1838,7 +1865,7 @@ async function getMemoryCardinality(agentId) {
|
|
|
1838
1865
|
return 0;
|
|
1839
1866
|
}
|
|
1840
1867
|
}
|
|
1841
|
-
var _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
1868
|
+
var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
1842
1869
|
var init_store = __esm({
|
|
1843
1870
|
"src/lib/store.ts"() {
|
|
1844
1871
|
"use strict";
|
|
@@ -1846,6 +1873,8 @@ var init_store = __esm({
|
|
|
1846
1873
|
init_database();
|
|
1847
1874
|
init_keychain();
|
|
1848
1875
|
init_config();
|
|
1876
|
+
INIT_MAX_RETRIES = 3;
|
|
1877
|
+
INIT_RETRY_DELAY_MS = 1e3;
|
|
1849
1878
|
_pendingRecords = [];
|
|
1850
1879
|
_batchSize = 20;
|
|
1851
1880
|
_flushIntervalMs = 1e4;
|
|
@@ -1909,7 +1938,7 @@ var init_project_name = __esm({
|
|
|
1909
1938
|
// src/bin/scan-tasks.ts
|
|
1910
1939
|
import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
|
|
1911
1940
|
import path5 from "path";
|
|
1912
|
-
import
|
|
1941
|
+
import os3 from "os";
|
|
1913
1942
|
|
|
1914
1943
|
// src/lib/is-main.ts
|
|
1915
1944
|
import { realpathSync } from "fs";
|
|
@@ -1928,7 +1957,7 @@ function isMainModule(importMetaUrl) {
|
|
|
1928
1957
|
// src/bin/scan-tasks.ts
|
|
1929
1958
|
function checkMcpHealth() {
|
|
1930
1959
|
try {
|
|
1931
|
-
const claudeJson = path5.join(
|
|
1960
|
+
const claudeJson = path5.join(os3.homedir(), ".claude.json");
|
|
1932
1961
|
if (!existsSync4(claudeJson)) {
|
|
1933
1962
|
process.stderr.write(
|
|
1934
1963
|
"\u26A0\uFE0F MCP config missing (~/.claude.json not found) \u2014 close_task won't work. Run /exe-setup\n"
|
package/dist/bin/setup.js
CHANGED
|
@@ -31,7 +31,7 @@ __export(config_exports, {
|
|
|
31
31
|
migrateConfig: () => migrateConfig,
|
|
32
32
|
saveConfig: () => saveConfig
|
|
33
33
|
});
|
|
34
|
-
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
34
|
+
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
35
35
|
import { readFileSync, existsSync, renameSync } from "fs";
|
|
36
36
|
import path from "path";
|
|
37
37
|
import os from "os";
|
|
@@ -157,6 +157,9 @@ async function saveConfig(config) {
|
|
|
157
157
|
await mkdir(dir, { recursive: true });
|
|
158
158
|
const configPath = path.join(dir, "config.json");
|
|
159
159
|
await writeFile(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
160
|
+
if (config.cloud?.apiKey) {
|
|
161
|
+
await chmod(configPath, 384);
|
|
162
|
+
}
|
|
160
163
|
}
|
|
161
164
|
async function loadConfigFrom(configPath) {
|
|
162
165
|
const raw = await readFile(configPath, "utf-8");
|
|
@@ -276,6 +279,10 @@ import path4 from "path";
|
|
|
276
279
|
import { fileURLToPath } from "url";
|
|
277
280
|
function handleData(chunk) {
|
|
278
281
|
_buffer += chunk.toString();
|
|
282
|
+
if (_buffer.length > MAX_BUFFER) {
|
|
283
|
+
_buffer = "";
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
279
286
|
let newlineIdx;
|
|
280
287
|
while ((newlineIdx = _buffer.indexOf("\n")) !== -1) {
|
|
281
288
|
const line = _buffer.slice(0, newlineIdx).trim();
|
|
@@ -583,7 +590,7 @@ function disconnectClient() {
|
|
|
583
590
|
entry.resolve({ error: "Client disconnected" });
|
|
584
591
|
}
|
|
585
592
|
}
|
|
586
|
-
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;
|
|
593
|
+
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;
|
|
587
594
|
var init_exe_daemon_client = __esm({
|
|
588
595
|
"src/lib/exe-daemon-client.ts"() {
|
|
589
596
|
"use strict";
|
|
@@ -600,6 +607,7 @@ var init_exe_daemon_client = __esm({
|
|
|
600
607
|
_requestCount = 0;
|
|
601
608
|
HEALTH_CHECK_INTERVAL = 100;
|
|
602
609
|
_pending = /* @__PURE__ */ new Map();
|
|
610
|
+
MAX_BUFFER = 1e7;
|
|
603
611
|
}
|
|
604
612
|
});
|
|
605
613
|
|
|
@@ -692,6 +700,14 @@ import { readFileSync as readFileSync3, writeFileSync, existsSync as existsSync5
|
|
|
692
700
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
693
701
|
import path5 from "path";
|
|
694
702
|
import { jwtVerify, importSPKI } from "jose";
|
|
703
|
+
async function fetchRetry(url, init) {
|
|
704
|
+
try {
|
|
705
|
+
return await fetch(url, init);
|
|
706
|
+
} catch {
|
|
707
|
+
await new Promise((r) => setTimeout(r, RETRY_DELAY_MS));
|
|
708
|
+
return fetch(url, { ...init, signal: AbortSignal.timeout(1e4) });
|
|
709
|
+
}
|
|
710
|
+
}
|
|
695
711
|
function loadDeviceId() {
|
|
696
712
|
const deviceJsonPath = path5.join(EXE_AI_DIR, "device.json");
|
|
697
713
|
try {
|
|
@@ -723,7 +739,7 @@ function loadLicense() {
|
|
|
723
739
|
}
|
|
724
740
|
function saveLicense(apiKey) {
|
|
725
741
|
mkdirSync(EXE_AI_DIR, { recursive: true });
|
|
726
|
-
writeFileSync(LICENSE_PATH, apiKey.trim(), "utf8");
|
|
742
|
+
writeFileSync(LICENSE_PATH, apiKey.trim(), { encoding: "utf8", mode: 384 });
|
|
727
743
|
}
|
|
728
744
|
async function verifyLicenseJwt(token) {
|
|
729
745
|
try {
|
|
@@ -775,7 +791,7 @@ function cacheResponse(token) {
|
|
|
775
791
|
async function validateLicense(apiKey, deviceId) {
|
|
776
792
|
const did = deviceId ?? loadDeviceId();
|
|
777
793
|
try {
|
|
778
|
-
const res = await
|
|
794
|
+
const res = await fetchRetry(`${API_BASE}/auth/activate`, {
|
|
779
795
|
method: "POST",
|
|
780
796
|
headers: { "Content-Type": "application/json" },
|
|
781
797
|
body: JSON.stringify({ apiKey, deviceId: did }),
|
|
@@ -866,7 +882,7 @@ async function assertVpsLicense(opts) {
|
|
|
866
882
|
let explicitRejection = false;
|
|
867
883
|
let transientFailure = false;
|
|
868
884
|
try {
|
|
869
|
-
const res = await
|
|
885
|
+
const res = await fetchRetry(`${API_BASE}/auth/activate`, {
|
|
870
886
|
method: "POST",
|
|
871
887
|
headers: { "Content-Type": "application/json" },
|
|
872
888
|
body: JSON.stringify({ apiKey, deviceId }),
|
|
@@ -968,7 +984,7 @@ function stopLicenseRevalidation() {
|
|
|
968
984
|
_revalTimer = null;
|
|
969
985
|
}
|
|
970
986
|
}
|
|
971
|
-
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE, LICENSE_PUBLIC_KEY_PEM, LICENSE_JWT_ALG, PLAN_LIMITS, FREE_LICENSE, CACHE_MAX_AGE_MS, _revalTimer;
|
|
987
|
+
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE, RETRY_DELAY_MS, LICENSE_PUBLIC_KEY_PEM, LICENSE_JWT_ALG, PLAN_LIMITS, FREE_LICENSE, CACHE_MAX_AGE_MS, _revalTimer;
|
|
972
988
|
var init_license = __esm({
|
|
973
989
|
"src/lib/license.ts"() {
|
|
974
990
|
"use strict";
|
|
@@ -977,6 +993,7 @@ var init_license = __esm({
|
|
|
977
993
|
CACHE_PATH = path5.join(EXE_AI_DIR, "license-cache.json");
|
|
978
994
|
DEVICE_ID_PATH = path5.join(EXE_AI_DIR, "device-id");
|
|
979
995
|
API_BASE = "https://askexe.com/cloud";
|
|
996
|
+
RETRY_DELAY_MS = 500;
|
|
980
997
|
LICENSE_PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
|
|
981
998
|
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeHztAMOpR/ZMh+rWuOASjEZ54CGY
|
|
982
999
|
4uj+UqeKCcvtgNHKmOK278HJaJcANe9xAeji8AFYu27q3WtzCi04pHudow==
|
|
@@ -1090,15 +1107,20 @@ function addEmployee(employees, employee) {
|
|
|
1090
1107
|
}
|
|
1091
1108
|
return [...employees, normalized];
|
|
1092
1109
|
}
|
|
1110
|
+
function findExeBin() {
|
|
1111
|
+
try {
|
|
1112
|
+
return execSync(process.platform === "win32" ? "where exe-os" : "which exe-os", { encoding: "utf8" }).trim();
|
|
1113
|
+
} catch {
|
|
1114
|
+
return null;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1093
1117
|
function registerBinSymlinks(name) {
|
|
1094
1118
|
const created = [];
|
|
1095
1119
|
const skipped = [];
|
|
1096
1120
|
const errors = [];
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
} catch {
|
|
1101
|
-
errors.push("Could not find 'exe' in PATH");
|
|
1121
|
+
const exeBinPath = findExeBin();
|
|
1122
|
+
if (!exeBinPath) {
|
|
1123
|
+
errors.push("Could not find 'exe-os' in PATH");
|
|
1102
1124
|
return { created, skipped, errors };
|
|
1103
1125
|
}
|
|
1104
1126
|
const binDir = path6.dirname(exeBinPath);
|
|
@@ -2443,19 +2465,20 @@ ${PLAN_MODE_COMPAT}
|
|
|
2443
2465
|
init_config();
|
|
2444
2466
|
import crypto2 from "crypto";
|
|
2445
2467
|
import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync6, writeFileSync as writeFileSync3, unlinkSync as unlinkSync3 } from "fs";
|
|
2446
|
-
import
|
|
2468
|
+
import os3 from "os";
|
|
2447
2469
|
import path8 from "path";
|
|
2448
2470
|
import { createInterface } from "readline";
|
|
2449
2471
|
|
|
2450
2472
|
// src/lib/keychain.ts
|
|
2451
|
-
import { readFile as readFile2, writeFile as writeFile2, unlink, mkdir as mkdir2, chmod } from "fs/promises";
|
|
2473
|
+
import { readFile as readFile2, writeFile as writeFile2, unlink, mkdir as mkdir2, chmod as chmod2 } from "fs/promises";
|
|
2452
2474
|
import { existsSync as existsSync2 } from "fs";
|
|
2453
2475
|
import path2 from "path";
|
|
2476
|
+
import os2 from "os";
|
|
2454
2477
|
import crypto from "crypto";
|
|
2455
2478
|
var SERVICE = "exe-mem";
|
|
2456
2479
|
var ACCOUNT = "master-key";
|
|
2457
2480
|
function getKeyDir() {
|
|
2458
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path2.join(
|
|
2481
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path2.join(os2.homedir(), ".exe-os");
|
|
2459
2482
|
}
|
|
2460
2483
|
function getKeyPath() {
|
|
2461
2484
|
return path2.join(getKeyDir(), "master.key");
|
|
@@ -2503,7 +2526,7 @@ async function setMasterKey(key) {
|
|
|
2503
2526
|
await mkdir2(dir, { recursive: true });
|
|
2504
2527
|
const keyPath = getKeyPath();
|
|
2505
2528
|
await writeFile2(keyPath, b64 + "\n", "utf-8");
|
|
2506
|
-
await
|
|
2529
|
+
await chmod2(keyPath, 384);
|
|
2507
2530
|
}
|
|
2508
2531
|
|
|
2509
2532
|
// src/lib/model-downloader.ts
|
|
@@ -2594,7 +2617,7 @@ async function fileHash(filePath) {
|
|
|
2594
2617
|
}
|
|
2595
2618
|
|
|
2596
2619
|
// src/lib/setup-wizard.ts
|
|
2597
|
-
var SETUP_STATE_PATH = path8.join(
|
|
2620
|
+
var SETUP_STATE_PATH = path8.join(os3.homedir(), ".exe-os", "setup-state.json");
|
|
2598
2621
|
function loadSetupState() {
|
|
2599
2622
|
try {
|
|
2600
2623
|
return JSON.parse(readFileSync6(SETUP_STATE_PATH, "utf8"));
|
|
@@ -2685,12 +2708,23 @@ async function runSetupWizard(opts = {}) {
|
|
|
2685
2708
|
try {
|
|
2686
2709
|
const { loadDeviceId: loadDeviceId2 } = await Promise.resolve().then(() => (init_license(), license_exports));
|
|
2687
2710
|
const deviceId = loadDeviceId2();
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2711
|
+
let res;
|
|
2712
|
+
try {
|
|
2713
|
+
res = await fetch("https://askexe.com/cloud/auth/auto-provision", {
|
|
2714
|
+
method: "POST",
|
|
2715
|
+
headers: { "Content-Type": "application/json" },
|
|
2716
|
+
body: JSON.stringify({ deviceId }),
|
|
2717
|
+
signal: AbortSignal.timeout(1e4)
|
|
2718
|
+
});
|
|
2719
|
+
} catch {
|
|
2720
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
2721
|
+
res = await fetch("https://askexe.com/cloud/auth/auto-provision", {
|
|
2722
|
+
method: "POST",
|
|
2723
|
+
headers: { "Content-Type": "application/json" },
|
|
2724
|
+
body: JSON.stringify({ deviceId }),
|
|
2725
|
+
signal: AbortSignal.timeout(1e4)
|
|
2726
|
+
});
|
|
2727
|
+
}
|
|
2694
2728
|
if (res.ok) {
|
|
2695
2729
|
const data = await res.json();
|
|
2696
2730
|
if (data.apiKey) {
|
|
@@ -2748,7 +2782,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
2748
2782
|
await saveConfig(config);
|
|
2749
2783
|
log("");
|
|
2750
2784
|
try {
|
|
2751
|
-
const claudeJsonPath = path8.join(
|
|
2785
|
+
const claudeJsonPath = path8.join(os3.homedir(), ".claude.json");
|
|
2752
2786
|
let claudeJson = {};
|
|
2753
2787
|
try {
|
|
2754
2788
|
claudeJson = JSON.parse(readFileSync6(claudeJsonPath, "utf8"));
|
|
@@ -2756,7 +2790,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
2756
2790
|
}
|
|
2757
2791
|
if (!claudeJson.projects) claudeJson.projects = {};
|
|
2758
2792
|
const projects = claudeJson.projects;
|
|
2759
|
-
for (const dir of [process.cwd(),
|
|
2793
|
+
for (const dir of [process.cwd(), os3.homedir()]) {
|
|
2760
2794
|
if (!projects[dir]) projects[dir] = {};
|
|
2761
2795
|
projects[dir].hasTrustDialogAccepted = true;
|
|
2762
2796
|
}
|