@askexenow/exe-os 0.9.8 → 0.9.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/backfill-conversations.js +222 -49
- package/dist/bin/backfill-responses.js +221 -48
- package/dist/bin/backfill-vectors.js +225 -52
- package/dist/bin/cleanup-stale-review-tasks.js +150 -28
- package/dist/bin/cli.js +1295 -856
- package/dist/bin/exe-agent-config.js +36 -8
- package/dist/bin/exe-agent.js +14 -4
- package/dist/bin/exe-assign.js +221 -48
- package/dist/bin/exe-boot.js +778 -427
- package/dist/bin/exe-call.js +41 -13
- package/dist/bin/exe-cloud.js +163 -58
- package/dist/bin/exe-dispatch.js +276 -139
- package/dist/bin/exe-doctor.js +145 -27
- package/dist/bin/exe-export-behaviors.js +141 -23
- package/dist/bin/exe-forget.js +137 -19
- package/dist/bin/exe-gateway.js +677 -388
- package/dist/bin/exe-heartbeat.js +227 -108
- package/dist/bin/exe-kill.js +138 -20
- package/dist/bin/exe-launch-agent.js +172 -39
- package/dist/bin/exe-link.js +291 -100
- package/dist/bin/exe-new-employee.js +214 -106
- package/dist/bin/exe-pending-messages.js +395 -33
- package/dist/bin/exe-pending-notifications.js +684 -99
- package/dist/bin/exe-pending-reviews.js +420 -74
- package/dist/bin/exe-rename.js +147 -49
- package/dist/bin/exe-review.js +138 -20
- package/dist/bin/exe-search.js +240 -69
- package/dist/bin/exe-session-cleanup.js +440 -250
- package/dist/bin/exe-settings.js +61 -17
- package/dist/bin/exe-start-codex.js +158 -39
- package/dist/bin/exe-start-opencode.js +157 -38
- package/dist/bin/exe-status.js +151 -29
- package/dist/bin/exe-team.js +138 -20
- package/dist/bin/git-sweep.js +404 -212
- package/dist/bin/graph-backfill.js +137 -19
- package/dist/bin/graph-export.js +140 -22
- package/dist/bin/install.js +90 -61
- package/dist/bin/scan-tasks.js +412 -220
- package/dist/bin/setup.js +564 -293
- package/dist/bin/shard-migrate.js +139 -21
- package/dist/bin/update.js +138 -49
- package/dist/bin/wiki-sync.js +137 -19
- package/dist/gateway/index.js +533 -320
- package/dist/hooks/bug-report-worker.js +344 -193
- package/dist/hooks/codex-stop-task-finalizer.js +4678 -0
- package/dist/hooks/commit-complete.js +402 -210
- package/dist/hooks/error-recall.js +245 -74
- package/dist/hooks/exe-heartbeat-hook.js +16 -6
- package/dist/hooks/ingest-worker.js +3423 -3157
- package/dist/hooks/ingest.js +832 -97
- package/dist/hooks/instructions-loaded.js +227 -54
- package/dist/hooks/notification.js +216 -43
- package/dist/hooks/post-compact.js +239 -62
- package/dist/hooks/pre-compact.js +408 -216
- package/dist/hooks/pre-tool-use.js +268 -90
- package/dist/hooks/prompt-ingest-worker.js +352 -102
- package/dist/hooks/prompt-submit.js +541 -328
- package/dist/hooks/response-ingest-worker.js +372 -122
- package/dist/hooks/session-end.js +443 -240
- package/dist/hooks/session-start.js +313 -127
- package/dist/hooks/stop.js +293 -98
- package/dist/hooks/subagent-stop.js +239 -62
- package/dist/hooks/summary-worker.js +568 -236
- package/dist/index.js +538 -324
- package/dist/lib/agent-config.js +28 -6
- package/dist/lib/cloud-sync.js +284 -105
- package/dist/lib/config.js +30 -10
- package/dist/lib/consolidation.js +16 -6
- package/dist/lib/database.js +123 -25
- package/dist/lib/db-daemon-client.js +73 -19
- package/dist/lib/db.js +123 -25
- package/dist/lib/device-registry.js +133 -35
- package/dist/lib/embedder.js +107 -32
- package/dist/lib/employee-templates.js +14 -4
- package/dist/lib/employees.js +41 -13
- package/dist/lib/exe-daemon-client.js +88 -22
- package/dist/lib/exe-daemon.js +935 -587
- package/dist/lib/hybrid-search.js +240 -69
- package/dist/lib/identity.js +18 -8
- package/dist/lib/license.js +133 -48
- package/dist/lib/messaging.js +116 -56
- package/dist/lib/reminders.js +14 -4
- package/dist/lib/schedules.js +137 -19
- package/dist/lib/skill-learning.js +33 -6
- package/dist/lib/store.js +137 -19
- package/dist/lib/task-router.js +14 -4
- package/dist/lib/tasks.js +280 -234
- package/dist/lib/tmux-routing.js +172 -125
- package/dist/lib/token-spend.js +26 -8
- package/dist/mcp/server.js +1326 -609
- package/dist/mcp/tools/complete-reminder.js +14 -4
- package/dist/mcp/tools/create-reminder.js +14 -4
- package/dist/mcp/tools/create-task.js +306 -248
- package/dist/mcp/tools/deactivate-behavior.js +16 -6
- package/dist/mcp/tools/list-reminders.js +14 -4
- package/dist/mcp/tools/list-tasks.js +123 -107
- package/dist/mcp/tools/send-message.js +75 -29
- package/dist/mcp/tools/update-task.js +1848 -199
- package/dist/runtime/index.js +441 -248
- package/dist/tui/App.js +761 -424
- package/package.json +1 -1
|
@@ -4,9 +4,34 @@ var __esm = (fn, res) => function __init() {
|
|
|
4
4
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
+
// src/lib/secure-files.ts
|
|
8
|
+
import { chmodSync, existsSync, mkdirSync } from "fs";
|
|
9
|
+
import { chmod, mkdir } from "fs/promises";
|
|
10
|
+
function ensurePrivateDirSync(dirPath) {
|
|
11
|
+
mkdirSync(dirPath, { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
12
|
+
try {
|
|
13
|
+
chmodSync(dirPath, PRIVATE_DIR_MODE);
|
|
14
|
+
} catch {
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function enforcePrivateFileSync(filePath) {
|
|
18
|
+
try {
|
|
19
|
+
if (existsSync(filePath)) chmodSync(filePath, PRIVATE_FILE_MODE);
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
var PRIVATE_DIR_MODE, PRIVATE_FILE_MODE;
|
|
24
|
+
var init_secure_files = __esm({
|
|
25
|
+
"src/lib/secure-files.ts"() {
|
|
26
|
+
"use strict";
|
|
27
|
+
PRIVATE_DIR_MODE = 448;
|
|
28
|
+
PRIVATE_FILE_MODE = 384;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
7
32
|
// src/lib/config.ts
|
|
8
|
-
import { readFile, writeFile
|
|
9
|
-
import { readFileSync, existsSync, renameSync } from "fs";
|
|
33
|
+
import { readFile, writeFile } from "fs/promises";
|
|
34
|
+
import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
|
|
10
35
|
import path from "path";
|
|
11
36
|
import os from "os";
|
|
12
37
|
function resolveDataDir() {
|
|
@@ -14,7 +39,7 @@ function resolveDataDir() {
|
|
|
14
39
|
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
15
40
|
const newDir = path.join(os.homedir(), ".exe-os");
|
|
16
41
|
const legacyDir = path.join(os.homedir(), ".exe-mem");
|
|
17
|
-
if (!
|
|
42
|
+
if (!existsSync2(newDir) && existsSync2(legacyDir)) {
|
|
18
43
|
try {
|
|
19
44
|
renameSync(legacyDir, newDir);
|
|
20
45
|
process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
|
|
@@ -29,6 +54,7 @@ var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CON
|
|
|
29
54
|
var init_config = __esm({
|
|
30
55
|
"src/lib/config.ts"() {
|
|
31
56
|
"use strict";
|
|
57
|
+
init_secure_files();
|
|
32
58
|
EXE_AI_DIR = resolveDataDir();
|
|
33
59
|
DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
34
60
|
MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
@@ -123,10 +149,10 @@ var init_runtime_table = __esm({
|
|
|
123
149
|
});
|
|
124
150
|
|
|
125
151
|
// src/lib/agent-config.ts
|
|
126
|
-
import { readFileSync as readFileSync2, writeFileSync, existsSync as
|
|
152
|
+
import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync3 } from "fs";
|
|
127
153
|
import path2 from "path";
|
|
128
154
|
function loadAgentConfig() {
|
|
129
|
-
if (!
|
|
155
|
+
if (!existsSync3(AGENT_CONFIG_PATH)) return {};
|
|
130
156
|
try {
|
|
131
157
|
return JSON.parse(readFileSync2(AGENT_CONFIG_PATH, "utf-8"));
|
|
132
158
|
} catch {
|
|
@@ -135,8 +161,9 @@ function loadAgentConfig() {
|
|
|
135
161
|
}
|
|
136
162
|
function saveAgentConfig(config) {
|
|
137
163
|
const dir = path2.dirname(AGENT_CONFIG_PATH);
|
|
138
|
-
|
|
164
|
+
ensurePrivateDirSync(dir);
|
|
139
165
|
writeFileSync(AGENT_CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
166
|
+
enforcePrivateFileSync(AGENT_CONFIG_PATH);
|
|
140
167
|
}
|
|
141
168
|
function getAgentRuntime(agentId) {
|
|
142
169
|
const config = loadAgentConfig();
|
|
@@ -176,6 +203,7 @@ var init_agent_config = __esm({
|
|
|
176
203
|
"use strict";
|
|
177
204
|
init_config();
|
|
178
205
|
init_runtime_table();
|
|
206
|
+
init_secure_files();
|
|
179
207
|
AGENT_CONFIG_PATH = path2.join(EXE_AI_DIR, "agent-config.json");
|
|
180
208
|
KNOWN_RUNTIMES = {
|
|
181
209
|
claude: ["claude-opus-4", "claude-sonnet-4", "claude-haiku-4.5"],
|
|
@@ -197,13 +225,13 @@ init_runtime_table();
|
|
|
197
225
|
// src/lib/employees.ts
|
|
198
226
|
init_config();
|
|
199
227
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
200
|
-
import { existsSync as
|
|
228
|
+
import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync3, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
201
229
|
import { execSync } from "child_process";
|
|
202
230
|
import path3 from "path";
|
|
203
231
|
import os2 from "os";
|
|
204
232
|
var EMPLOYEES_PATH = path3.join(EXE_AI_DIR, "exe-employees.json");
|
|
205
233
|
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
206
|
-
if (!
|
|
234
|
+
if (!existsSync4(employeesPath)) return [];
|
|
207
235
|
try {
|
|
208
236
|
return JSON.parse(readFileSync3(employeesPath, "utf-8"));
|
|
209
237
|
} catch {
|
package/dist/bin/exe-agent.js
CHANGED
|
@@ -4,9 +4,18 @@ var __esm = (fn, res) => function __init() {
|
|
|
4
4
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
+
// src/lib/secure-files.ts
|
|
8
|
+
import { chmodSync, existsSync, mkdirSync } from "fs";
|
|
9
|
+
import { chmod, mkdir } from "fs/promises";
|
|
10
|
+
var init_secure_files = __esm({
|
|
11
|
+
"src/lib/secure-files.ts"() {
|
|
12
|
+
"use strict";
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
|
|
7
16
|
// src/lib/config.ts
|
|
8
|
-
import { readFile, writeFile
|
|
9
|
-
import { readFileSync, existsSync, renameSync } from "fs";
|
|
17
|
+
import { readFile, writeFile } from "fs/promises";
|
|
18
|
+
import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
|
|
10
19
|
import path from "path";
|
|
11
20
|
import os from "os";
|
|
12
21
|
function resolveDataDir() {
|
|
@@ -14,7 +23,7 @@ function resolveDataDir() {
|
|
|
14
23
|
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
15
24
|
const newDir = path.join(os.homedir(), ".exe-os");
|
|
16
25
|
const legacyDir = path.join(os.homedir(), ".exe-mem");
|
|
17
|
-
if (!
|
|
26
|
+
if (!existsSync2(newDir) && existsSync2(legacyDir)) {
|
|
18
27
|
try {
|
|
19
28
|
renameSync(legacyDir, newDir);
|
|
20
29
|
process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
|
|
@@ -29,6 +38,7 @@ var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CON
|
|
|
29
38
|
var init_config = __esm({
|
|
30
39
|
"src/lib/config.ts"() {
|
|
31
40
|
"use strict";
|
|
41
|
+
init_secure_files();
|
|
32
42
|
EXE_AI_DIR = resolveDataDir();
|
|
33
43
|
DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
34
44
|
MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
@@ -1259,7 +1269,7 @@ import { createClient } from "@libsql/client";
|
|
|
1259
1269
|
// src/lib/employees.ts
|
|
1260
1270
|
init_config();
|
|
1261
1271
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
1262
|
-
import { existsSync as
|
|
1272
|
+
import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
|
|
1263
1273
|
import { execSync } from "child_process";
|
|
1264
1274
|
import path2 from "path";
|
|
1265
1275
|
import os2 from "os";
|
package/dist/bin/exe-assign.js
CHANGED
|
@@ -9,9 +9,47 @@ var __export = (target, all) => {
|
|
|
9
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
// src/lib/secure-files.ts
|
|
13
|
+
import { chmodSync, existsSync, mkdirSync } from "fs";
|
|
14
|
+
import { chmod, mkdir } from "fs/promises";
|
|
15
|
+
async function ensurePrivateDir(dirPath) {
|
|
16
|
+
await mkdir(dirPath, { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
17
|
+
try {
|
|
18
|
+
await chmod(dirPath, PRIVATE_DIR_MODE);
|
|
19
|
+
} catch {
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function ensurePrivateDirSync(dirPath) {
|
|
23
|
+
mkdirSync(dirPath, { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
24
|
+
try {
|
|
25
|
+
chmodSync(dirPath, PRIVATE_DIR_MODE);
|
|
26
|
+
} catch {
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function enforcePrivateFile(filePath) {
|
|
30
|
+
try {
|
|
31
|
+
await chmod(filePath, PRIVATE_FILE_MODE);
|
|
32
|
+
} catch {
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function enforcePrivateFileSync(filePath) {
|
|
36
|
+
try {
|
|
37
|
+
if (existsSync(filePath)) chmodSync(filePath, PRIVATE_FILE_MODE);
|
|
38
|
+
} catch {
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
var PRIVATE_DIR_MODE, PRIVATE_FILE_MODE;
|
|
42
|
+
var init_secure_files = __esm({
|
|
43
|
+
"src/lib/secure-files.ts"() {
|
|
44
|
+
"use strict";
|
|
45
|
+
PRIVATE_DIR_MODE = 448;
|
|
46
|
+
PRIVATE_FILE_MODE = 384;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
12
50
|
// src/lib/config.ts
|
|
13
|
-
import { readFile, writeFile
|
|
14
|
-
import { readFileSync, existsSync, renameSync } from "fs";
|
|
51
|
+
import { readFile, writeFile } from "fs/promises";
|
|
52
|
+
import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
|
|
15
53
|
import path from "path";
|
|
16
54
|
import os from "os";
|
|
17
55
|
function resolveDataDir() {
|
|
@@ -19,7 +57,7 @@ function resolveDataDir() {
|
|
|
19
57
|
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
20
58
|
const newDir = path.join(os.homedir(), ".exe-os");
|
|
21
59
|
const legacyDir = path.join(os.homedir(), ".exe-mem");
|
|
22
|
-
if (!
|
|
60
|
+
if (!existsSync2(newDir) && existsSync2(legacyDir)) {
|
|
23
61
|
try {
|
|
24
62
|
renameSync(legacyDir, newDir);
|
|
25
63
|
process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
|
|
@@ -82,9 +120,9 @@ function normalizeAutoUpdate(raw) {
|
|
|
82
120
|
}
|
|
83
121
|
async function loadConfig() {
|
|
84
122
|
const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
|
|
85
|
-
await
|
|
123
|
+
await ensurePrivateDir(dir);
|
|
86
124
|
const configPath = path.join(dir, "config.json");
|
|
87
|
-
if (!
|
|
125
|
+
if (!existsSync2(configPath)) {
|
|
88
126
|
return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db") };
|
|
89
127
|
}
|
|
90
128
|
const raw = await readFile(configPath, "utf-8");
|
|
@@ -97,6 +135,7 @@ async function loadConfig() {
|
|
|
97
135
|
`);
|
|
98
136
|
try {
|
|
99
137
|
await writeFile(configPath, JSON.stringify(migratedCfg, null, 2) + "\n");
|
|
138
|
+
await enforcePrivateFile(configPath);
|
|
100
139
|
} catch {
|
|
101
140
|
}
|
|
102
141
|
}
|
|
@@ -116,6 +155,7 @@ var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CON
|
|
|
116
155
|
var init_config = __esm({
|
|
117
156
|
"src/lib/config.ts"() {
|
|
118
157
|
"use strict";
|
|
158
|
+
init_secure_files();
|
|
119
159
|
EXE_AI_DIR = resolveDataDir();
|
|
120
160
|
DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
121
161
|
MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
@@ -194,7 +234,7 @@ var init_config = __esm({
|
|
|
194
234
|
|
|
195
235
|
// src/lib/employees.ts
|
|
196
236
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
197
|
-
import { existsSync as
|
|
237
|
+
import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
|
|
198
238
|
import { execSync } from "child_process";
|
|
199
239
|
import path2 from "path";
|
|
200
240
|
import os2 from "os";
|
|
@@ -211,7 +251,7 @@ function getCoordinatorName(employees = loadEmployeesSync()) {
|
|
|
211
251
|
return getCoordinatorEmployee(employees)?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME;
|
|
212
252
|
}
|
|
213
253
|
async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
|
|
214
|
-
if (!
|
|
254
|
+
if (!existsSync3(employeesPath)) {
|
|
215
255
|
return [];
|
|
216
256
|
}
|
|
217
257
|
const raw = await readFile2(employeesPath, "utf-8");
|
|
@@ -222,7 +262,7 @@ async function loadEmployees(employeesPath = EMPLOYEES_PATH) {
|
|
|
222
262
|
}
|
|
223
263
|
}
|
|
224
264
|
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
225
|
-
if (!
|
|
265
|
+
if (!existsSync3(employeesPath)) return [];
|
|
226
266
|
try {
|
|
227
267
|
return JSON.parse(readFileSync2(employeesPath, "utf-8"));
|
|
228
268
|
} catch {
|
|
@@ -244,13 +284,50 @@ var init_employees = __esm({
|
|
|
244
284
|
}
|
|
245
285
|
});
|
|
246
286
|
|
|
287
|
+
// src/lib/daemon-auth.ts
|
|
288
|
+
import crypto from "crypto";
|
|
289
|
+
import path3 from "path";
|
|
290
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
291
|
+
function normalizeToken(token) {
|
|
292
|
+
if (!token) return null;
|
|
293
|
+
const trimmed = token.trim();
|
|
294
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
295
|
+
}
|
|
296
|
+
function readDaemonToken() {
|
|
297
|
+
try {
|
|
298
|
+
if (!existsSync4(DAEMON_TOKEN_PATH)) return null;
|
|
299
|
+
return normalizeToken(readFileSync3(DAEMON_TOKEN_PATH, "utf8"));
|
|
300
|
+
} catch {
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
function ensureDaemonToken(seed) {
|
|
305
|
+
const existing = readDaemonToken();
|
|
306
|
+
if (existing) return existing;
|
|
307
|
+
const token = normalizeToken(seed) ?? crypto.randomBytes(32).toString("hex");
|
|
308
|
+
ensurePrivateDirSync(EXE_AI_DIR);
|
|
309
|
+
writeFileSync2(DAEMON_TOKEN_PATH, `${token}
|
|
310
|
+
`, "utf8");
|
|
311
|
+
enforcePrivateFileSync(DAEMON_TOKEN_PATH);
|
|
312
|
+
return token;
|
|
313
|
+
}
|
|
314
|
+
var DAEMON_TOKEN_PATH;
|
|
315
|
+
var init_daemon_auth = __esm({
|
|
316
|
+
"src/lib/daemon-auth.ts"() {
|
|
317
|
+
"use strict";
|
|
318
|
+
init_config();
|
|
319
|
+
init_secure_files();
|
|
320
|
+
DAEMON_TOKEN_PATH = path3.join(EXE_AI_DIR, "exed.token");
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
|
|
247
324
|
// src/lib/exe-daemon-client.ts
|
|
248
325
|
import net from "net";
|
|
249
326
|
import os3 from "os";
|
|
250
327
|
import { spawn } from "child_process";
|
|
251
328
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
252
|
-
import { existsSync as
|
|
253
|
-
import
|
|
329
|
+
import { existsSync as existsSync5, unlinkSync as unlinkSync2, readFileSync as readFileSync4, openSync, closeSync, statSync } from "fs";
|
|
330
|
+
import path4 from "path";
|
|
254
331
|
import { fileURLToPath } from "url";
|
|
255
332
|
function handleData(chunk) {
|
|
256
333
|
_buffer += chunk.toString();
|
|
@@ -278,9 +355,9 @@ function handleData(chunk) {
|
|
|
278
355
|
}
|
|
279
356
|
}
|
|
280
357
|
function cleanupStaleFiles() {
|
|
281
|
-
if (
|
|
358
|
+
if (existsSync5(PID_PATH)) {
|
|
282
359
|
try {
|
|
283
|
-
const pid = parseInt(
|
|
360
|
+
const pid = parseInt(readFileSync4(PID_PATH, "utf8").trim(), 10);
|
|
284
361
|
if (pid > 0) {
|
|
285
362
|
try {
|
|
286
363
|
process.kill(pid, 0);
|
|
@@ -301,11 +378,11 @@ function cleanupStaleFiles() {
|
|
|
301
378
|
}
|
|
302
379
|
}
|
|
303
380
|
function findPackageRoot() {
|
|
304
|
-
let dir =
|
|
305
|
-
const { root } =
|
|
381
|
+
let dir = path4.dirname(fileURLToPath(import.meta.url));
|
|
382
|
+
const { root } = path4.parse(dir);
|
|
306
383
|
while (dir !== root) {
|
|
307
|
-
if (
|
|
308
|
-
dir =
|
|
384
|
+
if (existsSync5(path4.join(dir, "package.json"))) return dir;
|
|
385
|
+
dir = path4.dirname(dir);
|
|
309
386
|
}
|
|
310
387
|
return null;
|
|
311
388
|
}
|
|
@@ -331,16 +408,17 @@ function spawnDaemon() {
|
|
|
331
408
|
process.stderr.write("[exed-client] WARN: cannot find package root\n");
|
|
332
409
|
return;
|
|
333
410
|
}
|
|
334
|
-
const daemonPath =
|
|
335
|
-
if (!
|
|
411
|
+
const daemonPath = path4.join(pkgRoot, "dist", "lib", "exe-daemon.js");
|
|
412
|
+
if (!existsSync5(daemonPath)) {
|
|
336
413
|
process.stderr.write(`[exed-client] WARN: daemon script not found at ${daemonPath}
|
|
337
414
|
`);
|
|
338
415
|
return;
|
|
339
416
|
}
|
|
340
417
|
const resolvedPath = daemonPath;
|
|
418
|
+
const daemonToken = ensureDaemonToken(process.env[DAEMON_TOKEN_ENV] ?? null);
|
|
341
419
|
process.stderr.write(`[exed-client] Spawning daemon: ${resolvedPath}
|
|
342
420
|
`);
|
|
343
|
-
const logPath =
|
|
421
|
+
const logPath = path4.join(path4.dirname(SOCKET_PATH), "exed.log");
|
|
344
422
|
let stderrFd = "ignore";
|
|
345
423
|
try {
|
|
346
424
|
stderrFd = openSync(logPath, "a");
|
|
@@ -358,7 +436,8 @@ function spawnDaemon() {
|
|
|
358
436
|
TMUX_PANE: void 0,
|
|
359
437
|
// Prevents resolveExeSession() from scoping to one session
|
|
360
438
|
EXE_DAEMON_SOCK: SOCKET_PATH,
|
|
361
|
-
EXE_DAEMON_PID: PID_PATH
|
|
439
|
+
EXE_DAEMON_PID: PID_PATH,
|
|
440
|
+
[DAEMON_TOKEN_ENV]: daemonToken
|
|
362
441
|
}
|
|
363
442
|
});
|
|
364
443
|
child.unref();
|
|
@@ -468,13 +547,14 @@ function sendDaemonRequest(payload, timeoutMs = REQUEST_TIMEOUT_MS) {
|
|
|
468
547
|
return;
|
|
469
548
|
}
|
|
470
549
|
const id = randomUUID2();
|
|
550
|
+
const token = process.env[DAEMON_TOKEN_ENV] ?? readDaemonToken();
|
|
471
551
|
const timer = setTimeout(() => {
|
|
472
552
|
_pending.delete(id);
|
|
473
553
|
resolve({ error: "Request timeout" });
|
|
474
554
|
}, timeoutMs);
|
|
475
555
|
_pending.set(id, { resolve, timer });
|
|
476
556
|
try {
|
|
477
|
-
_socket.write(JSON.stringify({ id, ...payload }) + "\n");
|
|
557
|
+
_socket.write(JSON.stringify({ id, token, ...payload }) + "\n");
|
|
478
558
|
} catch {
|
|
479
559
|
clearTimeout(timer);
|
|
480
560
|
_pending.delete(id);
|
|
@@ -503,9 +583,9 @@ function killAndRespawnDaemon() {
|
|
|
503
583
|
}
|
|
504
584
|
try {
|
|
505
585
|
process.stderr.write("[exed-client] Killing daemon for restart...\n");
|
|
506
|
-
if (
|
|
586
|
+
if (existsSync5(PID_PATH)) {
|
|
507
587
|
try {
|
|
508
|
-
const pid = parseInt(
|
|
588
|
+
const pid = parseInt(readFileSync4(PID_PATH, "utf8").trim(), 10);
|
|
509
589
|
if (pid > 0) {
|
|
510
590
|
try {
|
|
511
591
|
process.kill(pid, "SIGKILL");
|
|
@@ -609,17 +689,19 @@ async function embedViaClient(text, priority = "high") {
|
|
|
609
689
|
);
|
|
610
690
|
return !result.error && result.vectors?.[0] ? result.vectors[0] : null;
|
|
611
691
|
}
|
|
612
|
-
var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, _socket, _connected, _buffer, _requestCount, _consecutiveFailures, HEALTH_CHECK_INTERVAL, MAX_RETRIES_BEFORE_RESTART, RETRY_DELAYS_MS, MIN_DAEMON_AGE_MS, _pending, MAX_BUFFER;
|
|
692
|
+
var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, DAEMON_TOKEN_ENV, _socket, _connected, _buffer, _requestCount, _consecutiveFailures, HEALTH_CHECK_INTERVAL, MAX_RETRIES_BEFORE_RESTART, RETRY_DELAYS_MS, MIN_DAEMON_AGE_MS, _pending, MAX_BUFFER;
|
|
613
693
|
var init_exe_daemon_client = __esm({
|
|
614
694
|
"src/lib/exe-daemon-client.ts"() {
|
|
615
695
|
"use strict";
|
|
616
696
|
init_config();
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
697
|
+
init_daemon_auth();
|
|
698
|
+
SOCKET_PATH = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ?? path4.join(EXE_AI_DIR, "exed.sock");
|
|
699
|
+
PID_PATH = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ?? path4.join(EXE_AI_DIR, "exed.pid");
|
|
700
|
+
SPAWN_LOCK_PATH = path4.join(EXE_AI_DIR, "exed-spawn.lock");
|
|
620
701
|
SPAWN_LOCK_STALE_MS = 3e4;
|
|
621
702
|
CONNECT_TIMEOUT_MS = 15e3;
|
|
622
703
|
REQUEST_TIMEOUT_MS = 3e4;
|
|
704
|
+
DAEMON_TOKEN_ENV = "EXE_DAEMON_TOKEN";
|
|
623
705
|
_socket = null;
|
|
624
706
|
_connected = false;
|
|
625
707
|
_buffer = "";
|
|
@@ -691,7 +773,7 @@ var init_db_retry = __esm({
|
|
|
691
773
|
|
|
692
774
|
// src/lib/database-adapter.ts
|
|
693
775
|
import os4 from "os";
|
|
694
|
-
import
|
|
776
|
+
import path5 from "path";
|
|
695
777
|
import { createRequire } from "module";
|
|
696
778
|
import { pathToFileURL } from "url";
|
|
697
779
|
function quotedIdentifier(identifier) {
|
|
@@ -1002,8 +1084,8 @@ async function loadPrismaClient() {
|
|
|
1002
1084
|
}
|
|
1003
1085
|
return new PrismaClient2();
|
|
1004
1086
|
}
|
|
1005
|
-
const exeDbRoot = process.env.EXE_DB_ROOT ??
|
|
1006
|
-
const requireFromExeDb = createRequire(
|
|
1087
|
+
const exeDbRoot = process.env.EXE_DB_ROOT ?? path5.join(os4.homedir(), "exe-db");
|
|
1088
|
+
const requireFromExeDb = createRequire(path5.join(exeDbRoot, "package.json"));
|
|
1007
1089
|
const prismaEntry = requireFromExeDb.resolve("@prisma/client");
|
|
1008
1090
|
const module = await import(pathToFileURL(prismaEntry).href);
|
|
1009
1091
|
const PrismaClient = module.PrismaClient ?? module.default?.PrismaClient;
|
|
@@ -1615,6 +1697,7 @@ async function ensureSchema() {
|
|
|
1615
1697
|
project TEXT NOT NULL,
|
|
1616
1698
|
summary TEXT NOT NULL,
|
|
1617
1699
|
task_file TEXT,
|
|
1700
|
+
session_scope TEXT,
|
|
1618
1701
|
read INTEGER NOT NULL DEFAULT 0,
|
|
1619
1702
|
created_at TEXT NOT NULL
|
|
1620
1703
|
);
|
|
@@ -1623,7 +1706,7 @@ async function ensureSchema() {
|
|
|
1623
1706
|
ON notifications(read);
|
|
1624
1707
|
|
|
1625
1708
|
CREATE INDEX IF NOT EXISTS idx_notifications_agent
|
|
1626
|
-
ON notifications(agent_id);
|
|
1709
|
+
ON notifications(agent_id, session_scope);
|
|
1627
1710
|
|
|
1628
1711
|
CREATE INDEX IF NOT EXISTS idx_notifications_task_file
|
|
1629
1712
|
ON notifications(task_file);
|
|
@@ -1661,6 +1744,7 @@ async function ensureSchema() {
|
|
|
1661
1744
|
target_agent TEXT NOT NULL,
|
|
1662
1745
|
target_project TEXT,
|
|
1663
1746
|
target_device TEXT NOT NULL DEFAULT 'local',
|
|
1747
|
+
session_scope TEXT,
|
|
1664
1748
|
content TEXT NOT NULL,
|
|
1665
1749
|
priority TEXT DEFAULT 'normal',
|
|
1666
1750
|
status TEXT DEFAULT 'pending',
|
|
@@ -1674,10 +1758,31 @@ async function ensureSchema() {
|
|
|
1674
1758
|
);
|
|
1675
1759
|
|
|
1676
1760
|
CREATE INDEX IF NOT EXISTS idx_messages_target
|
|
1677
|
-
ON messages(target_agent, status);
|
|
1761
|
+
ON messages(target_agent, session_scope, status);
|
|
1678
1762
|
|
|
1679
1763
|
CREATE INDEX IF NOT EXISTS idx_messages_conversation_order
|
|
1680
|
-
ON messages(target_agent, from_agent, server_seq);
|
|
1764
|
+
ON messages(target_agent, session_scope, from_agent, server_seq);
|
|
1765
|
+
`);
|
|
1766
|
+
try {
|
|
1767
|
+
await client.execute({
|
|
1768
|
+
sql: `ALTER TABLE notifications ADD COLUMN session_scope TEXT`,
|
|
1769
|
+
args: []
|
|
1770
|
+
});
|
|
1771
|
+
} catch {
|
|
1772
|
+
}
|
|
1773
|
+
try {
|
|
1774
|
+
await client.execute({
|
|
1775
|
+
sql: `ALTER TABLE messages ADD COLUMN session_scope TEXT`,
|
|
1776
|
+
args: []
|
|
1777
|
+
});
|
|
1778
|
+
} catch {
|
|
1779
|
+
}
|
|
1780
|
+
await client.executeMultiple(`
|
|
1781
|
+
CREATE INDEX IF NOT EXISTS idx_notifications_agent_scope_read
|
|
1782
|
+
ON notifications(agent_id, session_scope, read, created_at);
|
|
1783
|
+
|
|
1784
|
+
CREATE INDEX IF NOT EXISTS idx_messages_target_scope_status
|
|
1785
|
+
ON messages(target_agent, session_scope, status, created_at);
|
|
1681
1786
|
`);
|
|
1682
1787
|
try {
|
|
1683
1788
|
await client.execute({
|
|
@@ -2261,6 +2366,13 @@ async function ensureSchema() {
|
|
|
2261
2366
|
} catch {
|
|
2262
2367
|
}
|
|
2263
2368
|
}
|
|
2369
|
+
try {
|
|
2370
|
+
await client.execute({
|
|
2371
|
+
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
2372
|
+
args: []
|
|
2373
|
+
});
|
|
2374
|
+
} catch {
|
|
2375
|
+
}
|
|
2264
2376
|
}
|
|
2265
2377
|
var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso;
|
|
2266
2378
|
var init_database = __esm({
|
|
@@ -2283,6 +2395,7 @@ var shard_manager_exports = {};
|
|
|
2283
2395
|
__export(shard_manager_exports, {
|
|
2284
2396
|
disposeShards: () => disposeShards,
|
|
2285
2397
|
ensureShardSchema: () => ensureShardSchema,
|
|
2398
|
+
getOpenShardCount: () => getOpenShardCount,
|
|
2286
2399
|
getReadyShardClient: () => getReadyShardClient,
|
|
2287
2400
|
getShardClient: () => getShardClient,
|
|
2288
2401
|
getShardsDir: () => getShardsDir,
|
|
@@ -2291,15 +2404,18 @@ __export(shard_manager_exports, {
|
|
|
2291
2404
|
listShards: () => listShards,
|
|
2292
2405
|
shardExists: () => shardExists
|
|
2293
2406
|
});
|
|
2294
|
-
import
|
|
2295
|
-
import { existsSync as
|
|
2407
|
+
import path7 from "path";
|
|
2408
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readdirSync } from "fs";
|
|
2296
2409
|
import { createClient as createClient2 } from "@libsql/client";
|
|
2297
2410
|
function initShardManager(encryptionKey) {
|
|
2298
2411
|
_encryptionKey = encryptionKey;
|
|
2299
|
-
if (!
|
|
2300
|
-
|
|
2412
|
+
if (!existsSync7(SHARDS_DIR)) {
|
|
2413
|
+
mkdirSync2(SHARDS_DIR, { recursive: true });
|
|
2301
2414
|
}
|
|
2302
2415
|
_shardingEnabled = true;
|
|
2416
|
+
if (_evictionTimer) clearInterval(_evictionTimer);
|
|
2417
|
+
_evictionTimer = setInterval(evictIdleShards, EVICTION_INTERVAL_MS);
|
|
2418
|
+
_evictionTimer.unref();
|
|
2303
2419
|
}
|
|
2304
2420
|
function isShardingEnabled() {
|
|
2305
2421
|
return _shardingEnabled;
|
|
@@ -2316,21 +2432,28 @@ function getShardClient(projectName) {
|
|
|
2316
2432
|
throw new Error(`Invalid project name for shard: "${projectName}"`);
|
|
2317
2433
|
}
|
|
2318
2434
|
const cached = _shards.get(safeName);
|
|
2319
|
-
if (cached)
|
|
2320
|
-
|
|
2435
|
+
if (cached) {
|
|
2436
|
+
_shardLastAccess.set(safeName, Date.now());
|
|
2437
|
+
return cached;
|
|
2438
|
+
}
|
|
2439
|
+
while (_shards.size >= MAX_OPEN_SHARDS) {
|
|
2440
|
+
evictLRU();
|
|
2441
|
+
}
|
|
2442
|
+
const dbPath = path7.join(SHARDS_DIR, `${safeName}.db`);
|
|
2321
2443
|
const client = createClient2({
|
|
2322
2444
|
url: `file:${dbPath}`,
|
|
2323
2445
|
encryptionKey: _encryptionKey
|
|
2324
2446
|
});
|
|
2325
2447
|
_shards.set(safeName, client);
|
|
2448
|
+
_shardLastAccess.set(safeName, Date.now());
|
|
2326
2449
|
return client;
|
|
2327
2450
|
}
|
|
2328
2451
|
function shardExists(projectName) {
|
|
2329
2452
|
const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
2330
|
-
return
|
|
2453
|
+
return existsSync7(path7.join(SHARDS_DIR, `${safeName}.db`));
|
|
2331
2454
|
}
|
|
2332
2455
|
function listShards() {
|
|
2333
|
-
if (!
|
|
2456
|
+
if (!existsSync7(SHARDS_DIR)) return [];
|
|
2334
2457
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
2335
2458
|
}
|
|
2336
2459
|
async function ensureShardSchema(client) {
|
|
@@ -2382,6 +2505,8 @@ async function ensureShardSchema(client) {
|
|
|
2382
2505
|
for (const col of [
|
|
2383
2506
|
"ALTER TABLE memories ADD COLUMN task_id TEXT",
|
|
2384
2507
|
"ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0",
|
|
2508
|
+
"ALTER TABLE memories ADD COLUMN author_device_id TEXT",
|
|
2509
|
+
"ALTER TABLE memories ADD COLUMN scope TEXT NOT NULL DEFAULT 'business'",
|
|
2385
2510
|
"ALTER TABLE memories ADD COLUMN importance INTEGER DEFAULT 5",
|
|
2386
2511
|
"ALTER TABLE memories ADD COLUMN status TEXT DEFAULT 'active'",
|
|
2387
2512
|
"ALTER TABLE memories ADD COLUMN wiki_synced INTEGER DEFAULT 0",
|
|
@@ -2519,21 +2644,69 @@ async function getReadyShardClient(projectName) {
|
|
|
2519
2644
|
await ensureShardSchema(client);
|
|
2520
2645
|
return client;
|
|
2521
2646
|
}
|
|
2647
|
+
function evictLRU() {
|
|
2648
|
+
let oldest = null;
|
|
2649
|
+
let oldestTime = Infinity;
|
|
2650
|
+
for (const [name, time] of _shardLastAccess) {
|
|
2651
|
+
if (time < oldestTime) {
|
|
2652
|
+
oldestTime = time;
|
|
2653
|
+
oldest = name;
|
|
2654
|
+
}
|
|
2655
|
+
}
|
|
2656
|
+
if (oldest) {
|
|
2657
|
+
const client = _shards.get(oldest);
|
|
2658
|
+
if (client) {
|
|
2659
|
+
client.close();
|
|
2660
|
+
}
|
|
2661
|
+
_shards.delete(oldest);
|
|
2662
|
+
_shardLastAccess.delete(oldest);
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2665
|
+
function evictIdleShards() {
|
|
2666
|
+
const now = Date.now();
|
|
2667
|
+
const toEvict = [];
|
|
2668
|
+
for (const [name, lastAccess] of _shardLastAccess) {
|
|
2669
|
+
if (now - lastAccess > SHARD_IDLE_MS) {
|
|
2670
|
+
toEvict.push(name);
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
for (const name of toEvict) {
|
|
2674
|
+
const client = _shards.get(name);
|
|
2675
|
+
if (client) {
|
|
2676
|
+
client.close();
|
|
2677
|
+
}
|
|
2678
|
+
_shards.delete(name);
|
|
2679
|
+
_shardLastAccess.delete(name);
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
function getOpenShardCount() {
|
|
2683
|
+
return _shards.size;
|
|
2684
|
+
}
|
|
2522
2685
|
function disposeShards() {
|
|
2686
|
+
if (_evictionTimer) {
|
|
2687
|
+
clearInterval(_evictionTimer);
|
|
2688
|
+
_evictionTimer = null;
|
|
2689
|
+
}
|
|
2523
2690
|
for (const [, client] of _shards) {
|
|
2524
2691
|
client.close();
|
|
2525
2692
|
}
|
|
2526
2693
|
_shards.clear();
|
|
2694
|
+
_shardLastAccess.clear();
|
|
2527
2695
|
_shardingEnabled = false;
|
|
2528
2696
|
_encryptionKey = null;
|
|
2529
2697
|
}
|
|
2530
|
-
var SHARDS_DIR, _shards, _encryptionKey, _shardingEnabled;
|
|
2698
|
+
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled;
|
|
2531
2699
|
var init_shard_manager = __esm({
|
|
2532
2700
|
"src/lib/shard-manager.ts"() {
|
|
2533
2701
|
"use strict";
|
|
2534
2702
|
init_config();
|
|
2535
|
-
SHARDS_DIR =
|
|
2703
|
+
SHARDS_DIR = path7.join(EXE_AI_DIR, "shards");
|
|
2704
|
+
SHARD_IDLE_MS = 5 * 60 * 1e3;
|
|
2705
|
+
MAX_OPEN_SHARDS = 10;
|
|
2706
|
+
EVICTION_INTERVAL_MS = 60 * 1e3;
|
|
2536
2707
|
_shards = /* @__PURE__ */ new Map();
|
|
2708
|
+
_shardLastAccess = /* @__PURE__ */ new Map();
|
|
2709
|
+
_evictionTimer = null;
|
|
2537
2710
|
_encryptionKey = null;
|
|
2538
2711
|
_shardingEnabled = false;
|
|
2539
2712
|
}
|
|
@@ -2880,16 +3053,16 @@ init_database();
|
|
|
2880
3053
|
|
|
2881
3054
|
// src/lib/keychain.ts
|
|
2882
3055
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
2883
|
-
import { existsSync as
|
|
2884
|
-
import
|
|
3056
|
+
import { existsSync as existsSync6 } from "fs";
|
|
3057
|
+
import path6 from "path";
|
|
2885
3058
|
import os5 from "os";
|
|
2886
3059
|
var SERVICE = "exe-mem";
|
|
2887
3060
|
var ACCOUNT = "master-key";
|
|
2888
3061
|
function getKeyDir() {
|
|
2889
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ??
|
|
3062
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path6.join(os5.homedir(), ".exe-os");
|
|
2890
3063
|
}
|
|
2891
3064
|
function getKeyPath() {
|
|
2892
|
-
return
|
|
3065
|
+
return path6.join(getKeyDir(), "master.key");
|
|
2893
3066
|
}
|
|
2894
3067
|
async function tryKeytar() {
|
|
2895
3068
|
try {
|
|
@@ -2910,7 +3083,7 @@ async function getMasterKey() {
|
|
|
2910
3083
|
}
|
|
2911
3084
|
}
|
|
2912
3085
|
const keyPath = getKeyPath();
|
|
2913
|
-
if (!
|
|
3086
|
+
if (!existsSync6(keyPath)) {
|
|
2914
3087
|
process.stderr.write(
|
|
2915
3088
|
`[keychain] Key not found at ${keyPath} (HOME=${os5.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
|
|
2916
3089
|
`
|