@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
package/dist/bin/exe-settings.js
CHANGED
|
@@ -3,9 +3,47 @@ var __esm = (fn, res) => function __init() {
|
|
|
3
3
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
4
4
|
};
|
|
5
5
|
|
|
6
|
+
// src/lib/secure-files.ts
|
|
7
|
+
import { chmodSync, existsSync, mkdirSync } from "fs";
|
|
8
|
+
import { chmod, mkdir } from "fs/promises";
|
|
9
|
+
async function ensurePrivateDir(dirPath) {
|
|
10
|
+
await mkdir(dirPath, { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
11
|
+
try {
|
|
12
|
+
await chmod(dirPath, PRIVATE_DIR_MODE);
|
|
13
|
+
} catch {
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function ensurePrivateDirSync(dirPath) {
|
|
17
|
+
mkdirSync(dirPath, { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
18
|
+
try {
|
|
19
|
+
chmodSync(dirPath, PRIVATE_DIR_MODE);
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async function enforcePrivateFile(filePath) {
|
|
24
|
+
try {
|
|
25
|
+
await chmod(filePath, PRIVATE_FILE_MODE);
|
|
26
|
+
} catch {
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function enforcePrivateFileSync(filePath) {
|
|
30
|
+
try {
|
|
31
|
+
if (existsSync(filePath)) chmodSync(filePath, PRIVATE_FILE_MODE);
|
|
32
|
+
} catch {
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
var PRIVATE_DIR_MODE, PRIVATE_FILE_MODE;
|
|
36
|
+
var init_secure_files = __esm({
|
|
37
|
+
"src/lib/secure-files.ts"() {
|
|
38
|
+
"use strict";
|
|
39
|
+
PRIVATE_DIR_MODE = 448;
|
|
40
|
+
PRIVATE_FILE_MODE = 384;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
6
44
|
// src/lib/config.ts
|
|
7
|
-
import { readFile, writeFile
|
|
8
|
-
import { readFileSync, existsSync, renameSync } from "fs";
|
|
45
|
+
import { readFile, writeFile } from "fs/promises";
|
|
46
|
+
import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
|
|
9
47
|
import path from "path";
|
|
10
48
|
import os from "os";
|
|
11
49
|
function resolveDataDir() {
|
|
@@ -13,7 +51,7 @@ function resolveDataDir() {
|
|
|
13
51
|
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
14
52
|
const newDir = path.join(os.homedir(), ".exe-os");
|
|
15
53
|
const legacyDir = path.join(os.homedir(), ".exe-mem");
|
|
16
|
-
if (!
|
|
54
|
+
if (!existsSync2(newDir) && existsSync2(legacyDir)) {
|
|
17
55
|
try {
|
|
18
56
|
renameSync(legacyDir, newDir);
|
|
19
57
|
process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
|
|
@@ -76,9 +114,9 @@ function normalizeAutoUpdate(raw) {
|
|
|
76
114
|
}
|
|
77
115
|
async function loadConfig() {
|
|
78
116
|
const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
|
|
79
|
-
await
|
|
117
|
+
await ensurePrivateDir(dir);
|
|
80
118
|
const configPath = path.join(dir, "config.json");
|
|
81
|
-
if (!
|
|
119
|
+
if (!existsSync2(configPath)) {
|
|
82
120
|
return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db") };
|
|
83
121
|
}
|
|
84
122
|
const raw = await readFile(configPath, "utf-8");
|
|
@@ -91,6 +129,7 @@ async function loadConfig() {
|
|
|
91
129
|
`);
|
|
92
130
|
try {
|
|
93
131
|
await writeFile(configPath, JSON.stringify(migratedCfg, null, 2) + "\n");
|
|
132
|
+
await enforcePrivateFile(configPath);
|
|
94
133
|
} catch {
|
|
95
134
|
}
|
|
96
135
|
}
|
|
@@ -108,17 +147,16 @@ async function loadConfig() {
|
|
|
108
147
|
}
|
|
109
148
|
async function saveConfig(config) {
|
|
110
149
|
const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
|
|
111
|
-
await
|
|
150
|
+
await ensurePrivateDir(dir);
|
|
112
151
|
const configPath = path.join(dir, "config.json");
|
|
113
152
|
await writeFile(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
114
|
-
|
|
115
|
-
await chmod(configPath, 384);
|
|
116
|
-
}
|
|
153
|
+
await enforcePrivateFile(configPath);
|
|
117
154
|
}
|
|
118
155
|
var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CONFIG_VERSION, DEFAULT_CONFIG, CONFIG_MIGRATIONS;
|
|
119
156
|
var init_config = __esm({
|
|
120
157
|
"src/lib/config.ts"() {
|
|
121
158
|
"use strict";
|
|
159
|
+
init_secure_files();
|
|
122
160
|
EXE_AI_DIR = resolveDataDir();
|
|
123
161
|
DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
124
162
|
MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
@@ -204,12 +242,12 @@ var init_db_retry = __esm({
|
|
|
204
242
|
|
|
205
243
|
// src/lib/employees.ts
|
|
206
244
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
207
|
-
import { existsSync as
|
|
245
|
+
import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
|
|
208
246
|
import { execSync } from "child_process";
|
|
209
247
|
import path2 from "path";
|
|
210
248
|
import os2 from "os";
|
|
211
249
|
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
212
|
-
if (!
|
|
250
|
+
if (!existsSync3(employeesPath)) return [];
|
|
213
251
|
try {
|
|
214
252
|
return JSON.parse(readFileSync2(employeesPath, "utf-8"));
|
|
215
253
|
} catch {
|
|
@@ -260,7 +298,7 @@ var init_database = __esm({
|
|
|
260
298
|
|
|
261
299
|
// src/lib/crdt-sync.ts
|
|
262
300
|
import * as Y from "yjs";
|
|
263
|
-
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as
|
|
301
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync5, mkdirSync as mkdirSync3, unlinkSync as unlinkSync2 } from "fs";
|
|
264
302
|
import path5 from "path";
|
|
265
303
|
import { homedir } from "os";
|
|
266
304
|
var DEFAULT_STATE_PATH;
|
|
@@ -299,10 +337,10 @@ var init_runtime_table = __esm({
|
|
|
299
337
|
});
|
|
300
338
|
|
|
301
339
|
// src/lib/agent-config.ts
|
|
302
|
-
import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, existsSync as
|
|
340
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, existsSync as existsSync7 } from "fs";
|
|
303
341
|
import path7 from "path";
|
|
304
342
|
function loadAgentConfig() {
|
|
305
|
-
if (!
|
|
343
|
+
if (!existsSync7(AGENT_CONFIG_PATH)) return {};
|
|
306
344
|
try {
|
|
307
345
|
return JSON.parse(readFileSync6(AGENT_CONFIG_PATH, "utf-8"));
|
|
308
346
|
} catch {
|
|
@@ -311,8 +349,9 @@ function loadAgentConfig() {
|
|
|
311
349
|
}
|
|
312
350
|
function saveAgentConfig(config) {
|
|
313
351
|
const dir = path7.dirname(AGENT_CONFIG_PATH);
|
|
314
|
-
|
|
352
|
+
ensurePrivateDirSync(dir);
|
|
315
353
|
writeFileSync5(AGENT_CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
354
|
+
enforcePrivateFileSync(AGENT_CONFIG_PATH);
|
|
316
355
|
}
|
|
317
356
|
function setAgentRuntime(agentId, runtime, model) {
|
|
318
357
|
const knownModels = KNOWN_RUNTIMES[runtime];
|
|
@@ -344,6 +383,7 @@ var init_agent_config = __esm({
|
|
|
344
383
|
"use strict";
|
|
345
384
|
init_config();
|
|
346
385
|
init_runtime_table();
|
|
386
|
+
init_secure_files();
|
|
347
387
|
AGENT_CONFIG_PATH = path7.join(EXE_AI_DIR, "agent-config.json");
|
|
348
388
|
KNOWN_RUNTIMES = {
|
|
349
389
|
claude: ["claude-opus-4", "claude-sonnet-4", "claude-haiku-4.5"],
|
|
@@ -384,7 +424,7 @@ function isMainModule(importMetaUrl) {
|
|
|
384
424
|
|
|
385
425
|
// src/lib/cloud-sync.ts
|
|
386
426
|
init_database();
|
|
387
|
-
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as
|
|
427
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync6, readdirSync, mkdirSync as mkdirSync4, appendFileSync, unlinkSync as unlinkSync3, openSync, closeSync } from "fs";
|
|
388
428
|
import crypto2 from "crypto";
|
|
389
429
|
import path6 from "path";
|
|
390
430
|
import { homedir as homedir2 } from "os";
|
|
@@ -397,8 +437,11 @@ import { brotliCompressSync, brotliDecompressSync, constants } from "zlib";
|
|
|
397
437
|
|
|
398
438
|
// src/lib/license.ts
|
|
399
439
|
init_config();
|
|
400
|
-
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as
|
|
440
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
|
|
401
441
|
import { randomUUID } from "crypto";
|
|
442
|
+
import { createRequire as createRequire2 } from "module";
|
|
443
|
+
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
444
|
+
import os4 from "os";
|
|
402
445
|
import path4 from "path";
|
|
403
446
|
import { jwtVerify, importSPKI } from "jose";
|
|
404
447
|
var LICENSE_PATH = path4.join(EXE_AI_DIR, "license.key");
|
|
@@ -409,6 +452,7 @@ var DEVICE_ID_PATH = path4.join(EXE_AI_DIR, "device-id");
|
|
|
409
452
|
init_config();
|
|
410
453
|
init_crdt_sync();
|
|
411
454
|
init_employees();
|
|
455
|
+
init_secure_files();
|
|
412
456
|
var LOCALHOST_PATTERNS = /^(localhost|127\.0\.0\.1|\[::1\])$/i;
|
|
413
457
|
var ROSTER_LOCK_PATH = path6.join(EXE_AI_DIR, "roster-merge.lock");
|
|
414
458
|
function assertSecureEndpoint(endpoint) {
|
|
@@ -70,9 +70,34 @@ var init_db_retry = __esm({
|
|
|
70
70
|
}
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
+
// src/lib/secure-files.ts
|
|
74
|
+
import { chmodSync, existsSync, mkdirSync } from "fs";
|
|
75
|
+
import { chmod, mkdir } from "fs/promises";
|
|
76
|
+
async function ensurePrivateDir(dirPath) {
|
|
77
|
+
await mkdir(dirPath, { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
78
|
+
try {
|
|
79
|
+
await chmod(dirPath, PRIVATE_DIR_MODE);
|
|
80
|
+
} catch {
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async function enforcePrivateFile(filePath) {
|
|
84
|
+
try {
|
|
85
|
+
await chmod(filePath, PRIVATE_FILE_MODE);
|
|
86
|
+
} catch {
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
var PRIVATE_DIR_MODE, PRIVATE_FILE_MODE;
|
|
90
|
+
var init_secure_files = __esm({
|
|
91
|
+
"src/lib/secure-files.ts"() {
|
|
92
|
+
"use strict";
|
|
93
|
+
PRIVATE_DIR_MODE = 448;
|
|
94
|
+
PRIVATE_FILE_MODE = 384;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
73
98
|
// src/lib/config.ts
|
|
74
|
-
import { readFile, writeFile
|
|
75
|
-
import { readFileSync, existsSync, renameSync } from "fs";
|
|
99
|
+
import { readFile, writeFile } from "fs/promises";
|
|
100
|
+
import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
|
|
76
101
|
import path from "path";
|
|
77
102
|
import os from "os";
|
|
78
103
|
function resolveDataDir() {
|
|
@@ -80,7 +105,7 @@ function resolveDataDir() {
|
|
|
80
105
|
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
81
106
|
const newDir = path.join(os.homedir(), ".exe-os");
|
|
82
107
|
const legacyDir = path.join(os.homedir(), ".exe-mem");
|
|
83
|
-
if (!
|
|
108
|
+
if (!existsSync2(newDir) && existsSync2(legacyDir)) {
|
|
84
109
|
try {
|
|
85
110
|
renameSync(legacyDir, newDir);
|
|
86
111
|
process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
|
|
@@ -143,9 +168,9 @@ function normalizeAutoUpdate(raw) {
|
|
|
143
168
|
}
|
|
144
169
|
async function loadConfig() {
|
|
145
170
|
const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
|
|
146
|
-
await
|
|
171
|
+
await ensurePrivateDir(dir);
|
|
147
172
|
const configPath = path.join(dir, "config.json");
|
|
148
|
-
if (!
|
|
173
|
+
if (!existsSync2(configPath)) {
|
|
149
174
|
return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db") };
|
|
150
175
|
}
|
|
151
176
|
const raw = await readFile(configPath, "utf-8");
|
|
@@ -158,6 +183,7 @@ async function loadConfig() {
|
|
|
158
183
|
`);
|
|
159
184
|
try {
|
|
160
185
|
await writeFile(configPath, JSON.stringify(migratedCfg, null, 2) + "\n");
|
|
186
|
+
await enforcePrivateFile(configPath);
|
|
161
187
|
} catch {
|
|
162
188
|
}
|
|
163
189
|
}
|
|
@@ -177,6 +203,7 @@ var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CON
|
|
|
177
203
|
var init_config = __esm({
|
|
178
204
|
"src/lib/config.ts"() {
|
|
179
205
|
"use strict";
|
|
206
|
+
init_secure_files();
|
|
180
207
|
EXE_AI_DIR = resolveDataDir();
|
|
181
208
|
DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
182
209
|
MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
@@ -255,7 +282,7 @@ var init_config = __esm({
|
|
|
255
282
|
|
|
256
283
|
// src/lib/employees.ts
|
|
257
284
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
258
|
-
import { existsSync as
|
|
285
|
+
import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
|
|
259
286
|
import { execSync } from "child_process";
|
|
260
287
|
import path2 from "path";
|
|
261
288
|
import os2 from "os";
|
|
@@ -272,7 +299,7 @@ function getCoordinatorName(employees = loadEmployeesSync()) {
|
|
|
272
299
|
return getCoordinatorEmployee(employees)?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME;
|
|
273
300
|
}
|
|
274
301
|
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
275
|
-
if (!
|
|
302
|
+
if (!existsSync3(employeesPath)) return [];
|
|
276
303
|
try {
|
|
277
304
|
return JSON.parse(readFileSync2(employeesPath, "utf-8"));
|
|
278
305
|
} catch {
|
|
@@ -1228,6 +1255,7 @@ async function ensureSchema() {
|
|
|
1228
1255
|
project TEXT NOT NULL,
|
|
1229
1256
|
summary TEXT NOT NULL,
|
|
1230
1257
|
task_file TEXT,
|
|
1258
|
+
session_scope TEXT,
|
|
1231
1259
|
read INTEGER NOT NULL DEFAULT 0,
|
|
1232
1260
|
created_at TEXT NOT NULL
|
|
1233
1261
|
);
|
|
@@ -1236,7 +1264,7 @@ async function ensureSchema() {
|
|
|
1236
1264
|
ON notifications(read);
|
|
1237
1265
|
|
|
1238
1266
|
CREATE INDEX IF NOT EXISTS idx_notifications_agent
|
|
1239
|
-
ON notifications(agent_id);
|
|
1267
|
+
ON notifications(agent_id, session_scope);
|
|
1240
1268
|
|
|
1241
1269
|
CREATE INDEX IF NOT EXISTS idx_notifications_task_file
|
|
1242
1270
|
ON notifications(task_file);
|
|
@@ -1274,6 +1302,7 @@ async function ensureSchema() {
|
|
|
1274
1302
|
target_agent TEXT NOT NULL,
|
|
1275
1303
|
target_project TEXT,
|
|
1276
1304
|
target_device TEXT NOT NULL DEFAULT 'local',
|
|
1305
|
+
session_scope TEXT,
|
|
1277
1306
|
content TEXT NOT NULL,
|
|
1278
1307
|
priority TEXT DEFAULT 'normal',
|
|
1279
1308
|
status TEXT DEFAULT 'pending',
|
|
@@ -1287,10 +1316,31 @@ async function ensureSchema() {
|
|
|
1287
1316
|
);
|
|
1288
1317
|
|
|
1289
1318
|
CREATE INDEX IF NOT EXISTS idx_messages_target
|
|
1290
|
-
ON messages(target_agent, status);
|
|
1319
|
+
ON messages(target_agent, session_scope, status);
|
|
1291
1320
|
|
|
1292
1321
|
CREATE INDEX IF NOT EXISTS idx_messages_conversation_order
|
|
1293
|
-
ON messages(target_agent, from_agent, server_seq);
|
|
1322
|
+
ON messages(target_agent, session_scope, from_agent, server_seq);
|
|
1323
|
+
`);
|
|
1324
|
+
try {
|
|
1325
|
+
await client.execute({
|
|
1326
|
+
sql: `ALTER TABLE notifications ADD COLUMN session_scope TEXT`,
|
|
1327
|
+
args: []
|
|
1328
|
+
});
|
|
1329
|
+
} catch {
|
|
1330
|
+
}
|
|
1331
|
+
try {
|
|
1332
|
+
await client.execute({
|
|
1333
|
+
sql: `ALTER TABLE messages ADD COLUMN session_scope TEXT`,
|
|
1334
|
+
args: []
|
|
1335
|
+
});
|
|
1336
|
+
} catch {
|
|
1337
|
+
}
|
|
1338
|
+
await client.executeMultiple(`
|
|
1339
|
+
CREATE INDEX IF NOT EXISTS idx_notifications_agent_scope_read
|
|
1340
|
+
ON notifications(agent_id, session_scope, read, created_at);
|
|
1341
|
+
|
|
1342
|
+
CREATE INDEX IF NOT EXISTS idx_messages_target_scope_status
|
|
1343
|
+
ON messages(target_agent, session_scope, status, created_at);
|
|
1294
1344
|
`);
|
|
1295
1345
|
try {
|
|
1296
1346
|
await client.execute({
|
|
@@ -1874,6 +1924,13 @@ async function ensureSchema() {
|
|
|
1874
1924
|
} catch {
|
|
1875
1925
|
}
|
|
1876
1926
|
}
|
|
1927
|
+
try {
|
|
1928
|
+
await client.execute({
|
|
1929
|
+
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
1930
|
+
args: []
|
|
1931
|
+
});
|
|
1932
|
+
} catch {
|
|
1933
|
+
}
|
|
1877
1934
|
}
|
|
1878
1935
|
async function disposeDatabase() {
|
|
1879
1936
|
if (_walCheckpointTimer) {
|
|
@@ -1916,6 +1973,7 @@ var shard_manager_exports = {};
|
|
|
1916
1973
|
__export(shard_manager_exports, {
|
|
1917
1974
|
disposeShards: () => disposeShards,
|
|
1918
1975
|
ensureShardSchema: () => ensureShardSchema,
|
|
1976
|
+
getOpenShardCount: () => getOpenShardCount,
|
|
1919
1977
|
getReadyShardClient: () => getReadyShardClient,
|
|
1920
1978
|
getShardClient: () => getShardClient,
|
|
1921
1979
|
getShardsDir: () => getShardsDir,
|
|
@@ -1925,14 +1983,17 @@ __export(shard_manager_exports, {
|
|
|
1925
1983
|
shardExists: () => shardExists
|
|
1926
1984
|
});
|
|
1927
1985
|
import path5 from "path";
|
|
1928
|
-
import { existsSync as
|
|
1986
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync2, readdirSync } from "fs";
|
|
1929
1987
|
import { createClient as createClient2 } from "@libsql/client";
|
|
1930
1988
|
function initShardManager(encryptionKey) {
|
|
1931
1989
|
_encryptionKey = encryptionKey;
|
|
1932
|
-
if (!
|
|
1933
|
-
|
|
1990
|
+
if (!existsSync5(SHARDS_DIR)) {
|
|
1991
|
+
mkdirSync2(SHARDS_DIR, { recursive: true });
|
|
1934
1992
|
}
|
|
1935
1993
|
_shardingEnabled = true;
|
|
1994
|
+
if (_evictionTimer) clearInterval(_evictionTimer);
|
|
1995
|
+
_evictionTimer = setInterval(evictIdleShards, EVICTION_INTERVAL_MS);
|
|
1996
|
+
_evictionTimer.unref();
|
|
1936
1997
|
}
|
|
1937
1998
|
function isShardingEnabled() {
|
|
1938
1999
|
return _shardingEnabled;
|
|
@@ -1949,21 +2010,28 @@ function getShardClient(projectName) {
|
|
|
1949
2010
|
throw new Error(`Invalid project name for shard: "${projectName}"`);
|
|
1950
2011
|
}
|
|
1951
2012
|
const cached = _shards.get(safeName);
|
|
1952
|
-
if (cached)
|
|
2013
|
+
if (cached) {
|
|
2014
|
+
_shardLastAccess.set(safeName, Date.now());
|
|
2015
|
+
return cached;
|
|
2016
|
+
}
|
|
2017
|
+
while (_shards.size >= MAX_OPEN_SHARDS) {
|
|
2018
|
+
evictLRU();
|
|
2019
|
+
}
|
|
1953
2020
|
const dbPath = path5.join(SHARDS_DIR, `${safeName}.db`);
|
|
1954
2021
|
const client = createClient2({
|
|
1955
2022
|
url: `file:${dbPath}`,
|
|
1956
2023
|
encryptionKey: _encryptionKey
|
|
1957
2024
|
});
|
|
1958
2025
|
_shards.set(safeName, client);
|
|
2026
|
+
_shardLastAccess.set(safeName, Date.now());
|
|
1959
2027
|
return client;
|
|
1960
2028
|
}
|
|
1961
2029
|
function shardExists(projectName) {
|
|
1962
2030
|
const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1963
|
-
return
|
|
2031
|
+
return existsSync5(path5.join(SHARDS_DIR, `${safeName}.db`));
|
|
1964
2032
|
}
|
|
1965
2033
|
function listShards() {
|
|
1966
|
-
if (!
|
|
2034
|
+
if (!existsSync5(SHARDS_DIR)) return [];
|
|
1967
2035
|
return readdirSync(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
1968
2036
|
}
|
|
1969
2037
|
async function ensureShardSchema(client) {
|
|
@@ -2015,6 +2083,8 @@ async function ensureShardSchema(client) {
|
|
|
2015
2083
|
for (const col of [
|
|
2016
2084
|
"ALTER TABLE memories ADD COLUMN task_id TEXT",
|
|
2017
2085
|
"ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0",
|
|
2086
|
+
"ALTER TABLE memories ADD COLUMN author_device_id TEXT",
|
|
2087
|
+
"ALTER TABLE memories ADD COLUMN scope TEXT NOT NULL DEFAULT 'business'",
|
|
2018
2088
|
"ALTER TABLE memories ADD COLUMN importance INTEGER DEFAULT 5",
|
|
2019
2089
|
"ALTER TABLE memories ADD COLUMN status TEXT DEFAULT 'active'",
|
|
2020
2090
|
"ALTER TABLE memories ADD COLUMN wiki_synced INTEGER DEFAULT 0",
|
|
@@ -2152,21 +2222,69 @@ async function getReadyShardClient(projectName) {
|
|
|
2152
2222
|
await ensureShardSchema(client);
|
|
2153
2223
|
return client;
|
|
2154
2224
|
}
|
|
2225
|
+
function evictLRU() {
|
|
2226
|
+
let oldest = null;
|
|
2227
|
+
let oldestTime = Infinity;
|
|
2228
|
+
for (const [name, time] of _shardLastAccess) {
|
|
2229
|
+
if (time < oldestTime) {
|
|
2230
|
+
oldestTime = time;
|
|
2231
|
+
oldest = name;
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
if (oldest) {
|
|
2235
|
+
const client = _shards.get(oldest);
|
|
2236
|
+
if (client) {
|
|
2237
|
+
client.close();
|
|
2238
|
+
}
|
|
2239
|
+
_shards.delete(oldest);
|
|
2240
|
+
_shardLastAccess.delete(oldest);
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
function evictIdleShards() {
|
|
2244
|
+
const now = Date.now();
|
|
2245
|
+
const toEvict = [];
|
|
2246
|
+
for (const [name, lastAccess] of _shardLastAccess) {
|
|
2247
|
+
if (now - lastAccess > SHARD_IDLE_MS) {
|
|
2248
|
+
toEvict.push(name);
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
for (const name of toEvict) {
|
|
2252
|
+
const client = _shards.get(name);
|
|
2253
|
+
if (client) {
|
|
2254
|
+
client.close();
|
|
2255
|
+
}
|
|
2256
|
+
_shards.delete(name);
|
|
2257
|
+
_shardLastAccess.delete(name);
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
function getOpenShardCount() {
|
|
2261
|
+
return _shards.size;
|
|
2262
|
+
}
|
|
2155
2263
|
function disposeShards() {
|
|
2264
|
+
if (_evictionTimer) {
|
|
2265
|
+
clearInterval(_evictionTimer);
|
|
2266
|
+
_evictionTimer = null;
|
|
2267
|
+
}
|
|
2156
2268
|
for (const [, client] of _shards) {
|
|
2157
2269
|
client.close();
|
|
2158
2270
|
}
|
|
2159
2271
|
_shards.clear();
|
|
2272
|
+
_shardLastAccess.clear();
|
|
2160
2273
|
_shardingEnabled = false;
|
|
2161
2274
|
_encryptionKey = null;
|
|
2162
2275
|
}
|
|
2163
|
-
var SHARDS_DIR, _shards, _encryptionKey, _shardingEnabled;
|
|
2276
|
+
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled;
|
|
2164
2277
|
var init_shard_manager = __esm({
|
|
2165
2278
|
"src/lib/shard-manager.ts"() {
|
|
2166
2279
|
"use strict";
|
|
2167
2280
|
init_config();
|
|
2168
2281
|
SHARDS_DIR = path5.join(EXE_AI_DIR, "shards");
|
|
2282
|
+
SHARD_IDLE_MS = 5 * 60 * 1e3;
|
|
2283
|
+
MAX_OPEN_SHARDS = 10;
|
|
2284
|
+
EVICTION_INTERVAL_MS = 60 * 1e3;
|
|
2169
2285
|
_shards = /* @__PURE__ */ new Map();
|
|
2286
|
+
_shardLastAccess = /* @__PURE__ */ new Map();
|
|
2287
|
+
_evictionTimer = null;
|
|
2170
2288
|
_encryptionKey = null;
|
|
2171
2289
|
_shardingEnabled = false;
|
|
2172
2290
|
}
|
|
@@ -2463,7 +2581,7 @@ __export(active_agent_exports, {
|
|
|
2463
2581
|
resolveActiveAgentFromTmuxSession: () => resolveActiveAgentFromTmuxSession,
|
|
2464
2582
|
writeActiveAgent: () => writeActiveAgent
|
|
2465
2583
|
});
|
|
2466
|
-
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as
|
|
2584
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, unlinkSync as unlinkSync3, readdirSync as readdirSync3 } from "fs";
|
|
2467
2585
|
import { execSync as execSync3 } from "child_process";
|
|
2468
2586
|
import path7 from "path";
|
|
2469
2587
|
function isNameWithOptionalInstance(candidate, baseName) {
|
|
@@ -2513,7 +2631,7 @@ function getMarkerPath() {
|
|
|
2513
2631
|
}
|
|
2514
2632
|
function writeActiveAgent(agentId, agentRole) {
|
|
2515
2633
|
try {
|
|
2516
|
-
|
|
2634
|
+
mkdirSync4(CACHE_DIR, { recursive: true });
|
|
2517
2635
|
writeFileSync3(
|
|
2518
2636
|
getMarkerPath(),
|
|
2519
2637
|
JSON.stringify({ agentId, agentRole, startedAt: (/* @__PURE__ */ new Date()).toISOString() })
|
|
@@ -2632,9 +2750,9 @@ var init_active_agent = __esm({
|
|
|
2632
2750
|
import os6 from "os";
|
|
2633
2751
|
import path8 from "path";
|
|
2634
2752
|
import {
|
|
2635
|
-
existsSync as
|
|
2753
|
+
existsSync as existsSync7,
|
|
2636
2754
|
lstatSync,
|
|
2637
|
-
mkdirSync as
|
|
2755
|
+
mkdirSync as mkdirSync5,
|
|
2638
2756
|
readlinkSync as readlinkSync2,
|
|
2639
2757
|
symlinkSync as symlinkSync2
|
|
2640
2758
|
} from "fs";
|
|
@@ -2660,12 +2778,12 @@ var init_mcp_prefix = __esm({
|
|
|
2660
2778
|
});
|
|
2661
2779
|
|
|
2662
2780
|
// src/lib/preferences.ts
|
|
2663
|
-
import { existsSync as
|
|
2781
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
2664
2782
|
import path9 from "path";
|
|
2665
2783
|
import os7 from "os";
|
|
2666
2784
|
function loadPreferences(homeDir = os7.homedir()) {
|
|
2667
2785
|
const configPath = path9.join(homeDir, ".exe-os", "config.json");
|
|
2668
|
-
if (!
|
|
2786
|
+
if (!existsSync8(configPath)) return {};
|
|
2669
2787
|
try {
|
|
2670
2788
|
const config = JSON.parse(readFileSync4(configPath, "utf-8"));
|
|
2671
2789
|
return config.preferences ?? {};
|
|
@@ -2676,12 +2794,13 @@ function loadPreferences(homeDir = os7.homedir()) {
|
|
|
2676
2794
|
var init_preferences = __esm({
|
|
2677
2795
|
"src/lib/preferences.ts"() {
|
|
2678
2796
|
"use strict";
|
|
2797
|
+
init_secure_files();
|
|
2679
2798
|
}
|
|
2680
2799
|
});
|
|
2681
2800
|
|
|
2682
2801
|
// src/adapters/claude/installer.ts
|
|
2683
2802
|
import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir4, readdir } from "fs/promises";
|
|
2684
|
-
import { existsSync as
|
|
2803
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5, writeFileSync as writeFileSync5, copyFileSync, mkdirSync as mkdirSync6 } from "fs";
|
|
2685
2804
|
import path10 from "path";
|
|
2686
2805
|
import os8 from "os";
|
|
2687
2806
|
import { execSync as execSync4 } from "child_process";
|
|
@@ -2692,7 +2811,7 @@ function resolvePackageRoot() {
|
|
|
2692
2811
|
const root = path10.parse(dir).root;
|
|
2693
2812
|
while (dir !== root) {
|
|
2694
2813
|
const pkgPath = path10.join(dir, "package.json");
|
|
2695
|
-
if (
|
|
2814
|
+
if (existsSync9(pkgPath)) {
|
|
2696
2815
|
try {
|
|
2697
2816
|
const pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
|
|
2698
2817
|
if (pkg.name === "@askexenow/exe-os" || pkg.name === "exe-os") return dir;
|
|
@@ -2735,7 +2854,7 @@ __export(installer_exports, {
|
|
|
2735
2854
|
verifyCodexHooks: () => verifyCodexHooks
|
|
2736
2855
|
});
|
|
2737
2856
|
import { readFile as readFile5, writeFile as writeFile5, mkdir as mkdir5 } from "fs/promises";
|
|
2738
|
-
import { existsSync as
|
|
2857
|
+
import { existsSync as existsSync10 } from "fs";
|
|
2739
2858
|
import path11 from "path";
|
|
2740
2859
|
import os9 from "os";
|
|
2741
2860
|
async function mergeCodexHooks(packageRoot, homeDir = os9.homedir()) {
|
|
@@ -2747,7 +2866,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os9.homedir()) {
|
|
|
2747
2866
|
await mkdir5(codexDir, { recursive: true });
|
|
2748
2867
|
await mkdir5(logsDir, { recursive: true });
|
|
2749
2868
|
let hooksJson = {};
|
|
2750
|
-
if (
|
|
2869
|
+
if (existsSync10(hooksPath)) {
|
|
2751
2870
|
try {
|
|
2752
2871
|
hooksJson = JSON.parse(await readFile5(hooksPath, "utf-8"));
|
|
2753
2872
|
} catch {
|
|
@@ -2858,7 +2977,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os9.homedir()) {
|
|
|
2858
2977
|
}
|
|
2859
2978
|
function verifyCodexHooks(homeDir = os9.homedir()) {
|
|
2860
2979
|
const hooksPath = path11.join(homeDir, ".codex", "hooks.json");
|
|
2861
|
-
if (!
|
|
2980
|
+
if (!existsSync10(hooksPath)) return false;
|
|
2862
2981
|
try {
|
|
2863
2982
|
const hooksJson = JSON.parse(
|
|
2864
2983
|
__require("fs").readFileSync(hooksPath, "utf-8")
|
|
@@ -2885,7 +3004,7 @@ async function installCodexStatusLine(homeDir = os9.homedir()) {
|
|
|
2885
3004
|
const configPath = path11.join(codexDir, "config.toml");
|
|
2886
3005
|
await mkdir5(codexDir, { recursive: true });
|
|
2887
3006
|
let content = "";
|
|
2888
|
-
if (
|
|
3007
|
+
if (existsSync10(configPath)) {
|
|
2889
3008
|
content = await readFile5(configPath, "utf-8");
|
|
2890
3009
|
if (/\[tui\][\s\S]*?status_line\s*=/.test(content)) {
|
|
2891
3010
|
return "already-configured";
|
|
@@ -2936,7 +3055,7 @@ var init_installer2 = __esm({
|
|
|
2936
3055
|
import os10 from "os";
|
|
2937
3056
|
import path12 from "path";
|
|
2938
3057
|
import {
|
|
2939
|
-
existsSync as
|
|
3058
|
+
existsSync as existsSync11,
|
|
2940
3059
|
readFileSync as readFileSync6,
|
|
2941
3060
|
writeFileSync as writeFileSync6,
|
|
2942
3061
|
mkdirSync as mkdirSync7,
|
|
@@ -2950,7 +3069,7 @@ init_database();
|
|
|
2950
3069
|
|
|
2951
3070
|
// src/lib/keychain.ts
|
|
2952
3071
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
2953
|
-
import { existsSync as
|
|
3072
|
+
import { existsSync as existsSync4 } from "fs";
|
|
2954
3073
|
import path4 from "path";
|
|
2955
3074
|
import os4 from "os";
|
|
2956
3075
|
var SERVICE = "exe-mem";
|
|
@@ -2980,7 +3099,7 @@ async function getMasterKey() {
|
|
|
2980
3099
|
}
|
|
2981
3100
|
}
|
|
2982
3101
|
const keyPath = getKeyPath();
|
|
2983
|
-
if (!
|
|
3102
|
+
if (!existsSync4(keyPath)) {
|
|
2984
3103
|
process.stderr.write(
|
|
2985
3104
|
`[keychain] Key not found at ${keyPath} (HOME=${os4.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
|
|
2986
3105
|
`
|
|
@@ -3296,8 +3415,8 @@ function vectorToBlob(vector) {
|
|
|
3296
3415
|
import os5 from "os";
|
|
3297
3416
|
import path6 from "path";
|
|
3298
3417
|
import {
|
|
3299
|
-
existsSync as
|
|
3300
|
-
mkdirSync as
|
|
3418
|
+
existsSync as existsSync6,
|
|
3419
|
+
mkdirSync as mkdirSync3,
|
|
3301
3420
|
readdirSync as readdirSync2,
|
|
3302
3421
|
statSync,
|
|
3303
3422
|
unlinkSync as unlinkSync2,
|
|
@@ -3344,7 +3463,7 @@ var BEHAVIORS_EXPORT_DIR = path6.join(
|
|
|
3344
3463
|
var STALE_EXPORT_AGE_MS = 60 * 60 * 1e3;
|
|
3345
3464
|
var EXPORT_BEHAVIOR_LIMIT = 30;
|
|
3346
3465
|
function sweepStaleBehaviorExports(now = Date.now()) {
|
|
3347
|
-
if (!
|
|
3466
|
+
if (!existsSync6(BEHAVIORS_EXPORT_DIR)) return;
|
|
3348
3467
|
let entries;
|
|
3349
3468
|
try {
|
|
3350
3469
|
entries = readdirSync2(BEHAVIORS_EXPORT_DIR);
|
|
@@ -3394,7 +3513,7 @@ function exportFilePath(agentId, projectName, sessionKey) {
|
|
|
3394
3513
|
);
|
|
3395
3514
|
}
|
|
3396
3515
|
async function exportBehaviorsForAgent(agentId, projectName, sessionKey) {
|
|
3397
|
-
|
|
3516
|
+
mkdirSync3(BEHAVIORS_EXPORT_DIR, { recursive: true });
|
|
3398
3517
|
sweepStaleBehaviorExports();
|
|
3399
3518
|
const behaviors = await listBehaviors(agentId, projectName, EXPORT_BEHAVIOR_LIMIT);
|
|
3400
3519
|
if (behaviors.length === 0) return null;
|
|
@@ -3445,7 +3564,7 @@ function resolveAgent(argv) {
|
|
|
3445
3564
|
function loadIdentity(agent) {
|
|
3446
3565
|
const dir = path12.join(os10.homedir(), ".exe-os", "identity");
|
|
3447
3566
|
const exact = path12.join(dir, `${agent}.md`);
|
|
3448
|
-
if (
|
|
3567
|
+
if (existsSync11(exact)) {
|
|
3449
3568
|
const content = readFileSync6(exact, "utf-8").trim();
|
|
3450
3569
|
if (content) return content;
|
|
3451
3570
|
}
|
|
@@ -3473,7 +3592,7 @@ function writePromptFile(agent, identity, behaviorsPath) {
|
|
|
3473
3592
|
const promptDir = path12.join(os10.homedir(), ".exe-os", "codex-prompt");
|
|
3474
3593
|
mkdirSync7(promptDir, { recursive: true });
|
|
3475
3594
|
let prompt = identity;
|
|
3476
|
-
if (behaviorsPath &&
|
|
3595
|
+
if (behaviorsPath && existsSync11(behaviorsPath)) {
|
|
3477
3596
|
const behaviors = readFileSync6(behaviorsPath, "utf-8").trim();
|
|
3478
3597
|
if (behaviors) {
|
|
3479
3598
|
prompt += "\n\n" + behaviors;
|
|
@@ -3600,7 +3719,7 @@ async function main() {
|
|
|
3600
3719
|
const { execSync: es } = await import("child_process");
|
|
3601
3720
|
const worktreeDir = path12.join(process.cwd(), ".worktrees", worktreeName);
|
|
3602
3721
|
const branchName = `${worktreeName}/codex-${Date.now()}`;
|
|
3603
|
-
if (
|
|
3722
|
+
if (existsSync11(worktreeDir)) {
|
|
3604
3723
|
worktreePath = worktreeDir;
|
|
3605
3724
|
process.stderr.write(`[exe-start-codex] Reusing worktree at ${worktreeDir}
|
|
3606
3725
|
`);
|