@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/hooks/stop.js
CHANGED
|
@@ -25,9 +25,47 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
25
25
|
};
|
|
26
26
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
27
|
|
|
28
|
+
// src/lib/secure-files.ts
|
|
29
|
+
import { chmodSync, existsSync, mkdirSync } from "fs";
|
|
30
|
+
import { chmod, mkdir } from "fs/promises";
|
|
31
|
+
async function ensurePrivateDir(dirPath) {
|
|
32
|
+
await mkdir(dirPath, { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
33
|
+
try {
|
|
34
|
+
await chmod(dirPath, PRIVATE_DIR_MODE);
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function ensurePrivateDirSync(dirPath) {
|
|
39
|
+
mkdirSync(dirPath, { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
40
|
+
try {
|
|
41
|
+
chmodSync(dirPath, PRIVATE_DIR_MODE);
|
|
42
|
+
} catch {
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function enforcePrivateFile(filePath) {
|
|
46
|
+
try {
|
|
47
|
+
await chmod(filePath, PRIVATE_FILE_MODE);
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function enforcePrivateFileSync(filePath) {
|
|
52
|
+
try {
|
|
53
|
+
if (existsSync(filePath)) chmodSync(filePath, PRIVATE_FILE_MODE);
|
|
54
|
+
} catch {
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
var PRIVATE_DIR_MODE, PRIVATE_FILE_MODE;
|
|
58
|
+
var init_secure_files = __esm({
|
|
59
|
+
"src/lib/secure-files.ts"() {
|
|
60
|
+
"use strict";
|
|
61
|
+
PRIVATE_DIR_MODE = 448;
|
|
62
|
+
PRIVATE_FILE_MODE = 384;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
28
66
|
// src/lib/config.ts
|
|
29
|
-
import { readFile, writeFile
|
|
30
|
-
import { readFileSync, existsSync, renameSync } from "fs";
|
|
67
|
+
import { readFile, writeFile } from "fs/promises";
|
|
68
|
+
import { readFileSync, existsSync as existsSync2, renameSync } from "fs";
|
|
31
69
|
import path from "path";
|
|
32
70
|
import os from "os";
|
|
33
71
|
function resolveDataDir() {
|
|
@@ -35,7 +73,7 @@ function resolveDataDir() {
|
|
|
35
73
|
if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
|
|
36
74
|
const newDir = path.join(os.homedir(), ".exe-os");
|
|
37
75
|
const legacyDir = path.join(os.homedir(), ".exe-mem");
|
|
38
|
-
if (!
|
|
76
|
+
if (!existsSync2(newDir) && existsSync2(legacyDir)) {
|
|
39
77
|
try {
|
|
40
78
|
renameSync(legacyDir, newDir);
|
|
41
79
|
process.stderr.write(`[exe-os] Migrated data directory: ~/.exe-mem \u2192 ~/.exe-os
|
|
@@ -98,9 +136,9 @@ function normalizeAutoUpdate(raw) {
|
|
|
98
136
|
}
|
|
99
137
|
async function loadConfig() {
|
|
100
138
|
const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
|
|
101
|
-
await
|
|
139
|
+
await ensurePrivateDir(dir);
|
|
102
140
|
const configPath = path.join(dir, "config.json");
|
|
103
|
-
if (!
|
|
141
|
+
if (!existsSync2(configPath)) {
|
|
104
142
|
return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db") };
|
|
105
143
|
}
|
|
106
144
|
const raw = await readFile(configPath, "utf-8");
|
|
@@ -113,6 +151,7 @@ async function loadConfig() {
|
|
|
113
151
|
`);
|
|
114
152
|
try {
|
|
115
153
|
await writeFile(configPath, JSON.stringify(migratedCfg, null, 2) + "\n");
|
|
154
|
+
await enforcePrivateFile(configPath);
|
|
116
155
|
} catch {
|
|
117
156
|
}
|
|
118
157
|
}
|
|
@@ -131,7 +170,7 @@ async function loadConfig() {
|
|
|
131
170
|
function loadConfigSync() {
|
|
132
171
|
const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
|
|
133
172
|
const configPath = path.join(dir, "config.json");
|
|
134
|
-
if (!
|
|
173
|
+
if (!existsSync2(configPath)) {
|
|
135
174
|
return { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db") };
|
|
136
175
|
}
|
|
137
176
|
try {
|
|
@@ -151,6 +190,7 @@ var EXE_AI_DIR, DB_PATH, MODELS_DIR, CONFIG_PATH, LEGACY_LANCE_PATH, CURRENT_CON
|
|
|
151
190
|
var init_config = __esm({
|
|
152
191
|
"src/lib/config.ts"() {
|
|
153
192
|
"use strict";
|
|
193
|
+
init_secure_files();
|
|
154
194
|
EXE_AI_DIR = resolveDataDir();
|
|
155
195
|
DB_PATH = path.join(EXE_AI_DIR, "memories.db");
|
|
156
196
|
MODELS_DIR = path.join(EXE_AI_DIR, "models");
|
|
@@ -297,7 +337,7 @@ var init_session_key = __esm({
|
|
|
297
337
|
|
|
298
338
|
// src/lib/employees.ts
|
|
299
339
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
300
|
-
import { existsSync as
|
|
340
|
+
import { existsSync as existsSync3, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
|
|
301
341
|
import { execSync as execSync2 } from "child_process";
|
|
302
342
|
import path2 from "path";
|
|
303
343
|
import os2 from "os";
|
|
@@ -321,7 +361,7 @@ function canCoordinate(agentName, agentRole, employees = loadEmployeesSync()) {
|
|
|
321
361
|
return agentName === "default" || isCoordinatorRole(agentRole) || isCoordinatorName(agentName, employees);
|
|
322
362
|
}
|
|
323
363
|
function loadEmployeesSync(employeesPath = EMPLOYEES_PATH) {
|
|
324
|
-
if (!
|
|
364
|
+
if (!existsSync3(employeesPath)) return [];
|
|
325
365
|
try {
|
|
326
366
|
return JSON.parse(readFileSync2(employeesPath, "utf-8"));
|
|
327
367
|
} catch {
|
|
@@ -517,7 +557,7 @@ var init_runtime_table = __esm({
|
|
|
517
557
|
});
|
|
518
558
|
|
|
519
559
|
// src/lib/agent-config.ts
|
|
520
|
-
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as
|
|
560
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync4 } from "fs";
|
|
521
561
|
import path5 from "path";
|
|
522
562
|
var AGENT_CONFIG_PATH, DEFAULT_MODELS;
|
|
523
563
|
var init_agent_config = __esm({
|
|
@@ -525,6 +565,7 @@ var init_agent_config = __esm({
|
|
|
525
565
|
"use strict";
|
|
526
566
|
init_config();
|
|
527
567
|
init_runtime_table();
|
|
568
|
+
init_secure_files();
|
|
528
569
|
AGENT_CONFIG_PATH = path5.join(EXE_AI_DIR, "agent-config.json");
|
|
529
570
|
DEFAULT_MODELS = {
|
|
530
571
|
claude: "claude-opus-4",
|
|
@@ -535,7 +576,7 @@ var init_agent_config = __esm({
|
|
|
535
576
|
});
|
|
536
577
|
|
|
537
578
|
// src/lib/intercom-queue.ts
|
|
538
|
-
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as
|
|
579
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
|
|
539
580
|
import path6 from "path";
|
|
540
581
|
import os4 from "os";
|
|
541
582
|
var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
|
|
@@ -1187,13 +1228,50 @@ var init_database_adapter = __esm({
|
|
|
1187
1228
|
}
|
|
1188
1229
|
});
|
|
1189
1230
|
|
|
1231
|
+
// src/lib/daemon-auth.ts
|
|
1232
|
+
import crypto from "crypto";
|
|
1233
|
+
import path8 from "path";
|
|
1234
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
1235
|
+
function normalizeToken(token) {
|
|
1236
|
+
if (!token) return null;
|
|
1237
|
+
const trimmed = token.trim();
|
|
1238
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
1239
|
+
}
|
|
1240
|
+
function readDaemonToken() {
|
|
1241
|
+
try {
|
|
1242
|
+
if (!existsSync6(DAEMON_TOKEN_PATH)) return null;
|
|
1243
|
+
return normalizeToken(readFileSync6(DAEMON_TOKEN_PATH, "utf8"));
|
|
1244
|
+
} catch {
|
|
1245
|
+
return null;
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
function ensureDaemonToken(seed) {
|
|
1249
|
+
const existing = readDaemonToken();
|
|
1250
|
+
if (existing) return existing;
|
|
1251
|
+
const token = normalizeToken(seed) ?? crypto.randomBytes(32).toString("hex");
|
|
1252
|
+
ensurePrivateDirSync(EXE_AI_DIR);
|
|
1253
|
+
writeFileSync5(DAEMON_TOKEN_PATH, `${token}
|
|
1254
|
+
`, "utf8");
|
|
1255
|
+
enforcePrivateFileSync(DAEMON_TOKEN_PATH);
|
|
1256
|
+
return token;
|
|
1257
|
+
}
|
|
1258
|
+
var DAEMON_TOKEN_PATH;
|
|
1259
|
+
var init_daemon_auth = __esm({
|
|
1260
|
+
"src/lib/daemon-auth.ts"() {
|
|
1261
|
+
"use strict";
|
|
1262
|
+
init_config();
|
|
1263
|
+
init_secure_files();
|
|
1264
|
+
DAEMON_TOKEN_PATH = path8.join(EXE_AI_DIR, "exed.token");
|
|
1265
|
+
}
|
|
1266
|
+
});
|
|
1267
|
+
|
|
1190
1268
|
// src/lib/exe-daemon-client.ts
|
|
1191
1269
|
import net from "net";
|
|
1192
1270
|
import os6 from "os";
|
|
1193
1271
|
import { spawn } from "child_process";
|
|
1194
1272
|
import { randomUUID } from "crypto";
|
|
1195
|
-
import { existsSync as
|
|
1196
|
-
import
|
|
1273
|
+
import { existsSync as existsSync7, unlinkSync as unlinkSync3, readFileSync as readFileSync7, openSync, closeSync, statSync } from "fs";
|
|
1274
|
+
import path9 from "path";
|
|
1197
1275
|
import { fileURLToPath } from "url";
|
|
1198
1276
|
function handleData(chunk) {
|
|
1199
1277
|
_buffer += chunk.toString();
|
|
@@ -1221,9 +1299,9 @@ function handleData(chunk) {
|
|
|
1221
1299
|
}
|
|
1222
1300
|
}
|
|
1223
1301
|
function cleanupStaleFiles() {
|
|
1224
|
-
if (
|
|
1302
|
+
if (existsSync7(PID_PATH)) {
|
|
1225
1303
|
try {
|
|
1226
|
-
const pid = parseInt(
|
|
1304
|
+
const pid = parseInt(readFileSync7(PID_PATH, "utf8").trim(), 10);
|
|
1227
1305
|
if (pid > 0) {
|
|
1228
1306
|
try {
|
|
1229
1307
|
process.kill(pid, 0);
|
|
@@ -1244,11 +1322,11 @@ function cleanupStaleFiles() {
|
|
|
1244
1322
|
}
|
|
1245
1323
|
}
|
|
1246
1324
|
function findPackageRoot() {
|
|
1247
|
-
let dir =
|
|
1248
|
-
const { root } =
|
|
1325
|
+
let dir = path9.dirname(fileURLToPath(import.meta.url));
|
|
1326
|
+
const { root } = path9.parse(dir);
|
|
1249
1327
|
while (dir !== root) {
|
|
1250
|
-
if (
|
|
1251
|
-
dir =
|
|
1328
|
+
if (existsSync7(path9.join(dir, "package.json"))) return dir;
|
|
1329
|
+
dir = path9.dirname(dir);
|
|
1252
1330
|
}
|
|
1253
1331
|
return null;
|
|
1254
1332
|
}
|
|
@@ -1274,16 +1352,17 @@ function spawnDaemon() {
|
|
|
1274
1352
|
process.stderr.write("[exed-client] WARN: cannot find package root\n");
|
|
1275
1353
|
return;
|
|
1276
1354
|
}
|
|
1277
|
-
const daemonPath =
|
|
1278
|
-
if (!
|
|
1355
|
+
const daemonPath = path9.join(pkgRoot, "dist", "lib", "exe-daemon.js");
|
|
1356
|
+
if (!existsSync7(daemonPath)) {
|
|
1279
1357
|
process.stderr.write(`[exed-client] WARN: daemon script not found at ${daemonPath}
|
|
1280
1358
|
`);
|
|
1281
1359
|
return;
|
|
1282
1360
|
}
|
|
1283
1361
|
const resolvedPath = daemonPath;
|
|
1362
|
+
const daemonToken = ensureDaemonToken(process.env[DAEMON_TOKEN_ENV] ?? null);
|
|
1284
1363
|
process.stderr.write(`[exed-client] Spawning daemon: ${resolvedPath}
|
|
1285
1364
|
`);
|
|
1286
|
-
const logPath =
|
|
1365
|
+
const logPath = path9.join(path9.dirname(SOCKET_PATH), "exed.log");
|
|
1287
1366
|
let stderrFd = "ignore";
|
|
1288
1367
|
try {
|
|
1289
1368
|
stderrFd = openSync(logPath, "a");
|
|
@@ -1301,7 +1380,8 @@ function spawnDaemon() {
|
|
|
1301
1380
|
TMUX_PANE: void 0,
|
|
1302
1381
|
// Prevents resolveExeSession() from scoping to one session
|
|
1303
1382
|
EXE_DAEMON_SOCK: SOCKET_PATH,
|
|
1304
|
-
EXE_DAEMON_PID: PID_PATH
|
|
1383
|
+
EXE_DAEMON_PID: PID_PATH,
|
|
1384
|
+
[DAEMON_TOKEN_ENV]: daemonToken
|
|
1305
1385
|
}
|
|
1306
1386
|
});
|
|
1307
1387
|
child.unref();
|
|
@@ -1408,13 +1488,14 @@ function sendDaemonRequest(payload, timeoutMs = REQUEST_TIMEOUT_MS) {
|
|
|
1408
1488
|
return;
|
|
1409
1489
|
}
|
|
1410
1490
|
const id = randomUUID();
|
|
1491
|
+
const token = process.env[DAEMON_TOKEN_ENV] ?? readDaemonToken();
|
|
1411
1492
|
const timer = setTimeout(() => {
|
|
1412
1493
|
_pending.delete(id);
|
|
1413
1494
|
resolve({ error: "Request timeout" });
|
|
1414
1495
|
}, timeoutMs);
|
|
1415
1496
|
_pending.set(id, { resolve, timer });
|
|
1416
1497
|
try {
|
|
1417
|
-
_socket.write(JSON.stringify({ id, ...payload }) + "\n");
|
|
1498
|
+
_socket.write(JSON.stringify({ id, token, ...payload }) + "\n");
|
|
1418
1499
|
} catch {
|
|
1419
1500
|
clearTimeout(timer);
|
|
1420
1501
|
_pending.delete(id);
|
|
@@ -1425,17 +1506,19 @@ function sendDaemonRequest(payload, timeoutMs = REQUEST_TIMEOUT_MS) {
|
|
|
1425
1506
|
function isClientConnected() {
|
|
1426
1507
|
return _connected;
|
|
1427
1508
|
}
|
|
1428
|
-
var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, _socket, _connected, _buffer, _pending, MAX_BUFFER;
|
|
1509
|
+
var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, DAEMON_TOKEN_ENV, _socket, _connected, _buffer, _pending, MAX_BUFFER;
|
|
1429
1510
|
var init_exe_daemon_client = __esm({
|
|
1430
1511
|
"src/lib/exe-daemon-client.ts"() {
|
|
1431
1512
|
"use strict";
|
|
1432
1513
|
init_config();
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1514
|
+
init_daemon_auth();
|
|
1515
|
+
SOCKET_PATH = process.env.EXE_DAEMON_SOCK ?? process.env.EXE_EMBED_SOCK ?? path9.join(EXE_AI_DIR, "exed.sock");
|
|
1516
|
+
PID_PATH = process.env.EXE_DAEMON_PID ?? process.env.EXE_EMBED_PID ?? path9.join(EXE_AI_DIR, "exed.pid");
|
|
1517
|
+
SPAWN_LOCK_PATH = path9.join(EXE_AI_DIR, "exed-spawn.lock");
|
|
1436
1518
|
SPAWN_LOCK_STALE_MS = 3e4;
|
|
1437
1519
|
CONNECT_TIMEOUT_MS = 15e3;
|
|
1438
1520
|
REQUEST_TIMEOUT_MS = 3e4;
|
|
1521
|
+
DAEMON_TOKEN_ENV = "EXE_DAEMON_TOKEN";
|
|
1439
1522
|
_socket = null;
|
|
1440
1523
|
_connected = false;
|
|
1441
1524
|
_buffer = "";
|
|
@@ -2014,6 +2097,7 @@ async function ensureSchema() {
|
|
|
2014
2097
|
project TEXT NOT NULL,
|
|
2015
2098
|
summary TEXT NOT NULL,
|
|
2016
2099
|
task_file TEXT,
|
|
2100
|
+
session_scope TEXT,
|
|
2017
2101
|
read INTEGER NOT NULL DEFAULT 0,
|
|
2018
2102
|
created_at TEXT NOT NULL
|
|
2019
2103
|
);
|
|
@@ -2022,7 +2106,7 @@ async function ensureSchema() {
|
|
|
2022
2106
|
ON notifications(read);
|
|
2023
2107
|
|
|
2024
2108
|
CREATE INDEX IF NOT EXISTS idx_notifications_agent
|
|
2025
|
-
ON notifications(agent_id);
|
|
2109
|
+
ON notifications(agent_id, session_scope);
|
|
2026
2110
|
|
|
2027
2111
|
CREATE INDEX IF NOT EXISTS idx_notifications_task_file
|
|
2028
2112
|
ON notifications(task_file);
|
|
@@ -2060,6 +2144,7 @@ async function ensureSchema() {
|
|
|
2060
2144
|
target_agent TEXT NOT NULL,
|
|
2061
2145
|
target_project TEXT,
|
|
2062
2146
|
target_device TEXT NOT NULL DEFAULT 'local',
|
|
2147
|
+
session_scope TEXT,
|
|
2063
2148
|
content TEXT NOT NULL,
|
|
2064
2149
|
priority TEXT DEFAULT 'normal',
|
|
2065
2150
|
status TEXT DEFAULT 'pending',
|
|
@@ -2073,10 +2158,31 @@ async function ensureSchema() {
|
|
|
2073
2158
|
);
|
|
2074
2159
|
|
|
2075
2160
|
CREATE INDEX IF NOT EXISTS idx_messages_target
|
|
2076
|
-
ON messages(target_agent, status);
|
|
2161
|
+
ON messages(target_agent, session_scope, status);
|
|
2077
2162
|
|
|
2078
2163
|
CREATE INDEX IF NOT EXISTS idx_messages_conversation_order
|
|
2079
|
-
ON messages(target_agent, from_agent, server_seq);
|
|
2164
|
+
ON messages(target_agent, session_scope, from_agent, server_seq);
|
|
2165
|
+
`);
|
|
2166
|
+
try {
|
|
2167
|
+
await client.execute({
|
|
2168
|
+
sql: `ALTER TABLE notifications ADD COLUMN session_scope TEXT`,
|
|
2169
|
+
args: []
|
|
2170
|
+
});
|
|
2171
|
+
} catch {
|
|
2172
|
+
}
|
|
2173
|
+
try {
|
|
2174
|
+
await client.execute({
|
|
2175
|
+
sql: `ALTER TABLE messages ADD COLUMN session_scope TEXT`,
|
|
2176
|
+
args: []
|
|
2177
|
+
});
|
|
2178
|
+
} catch {
|
|
2179
|
+
}
|
|
2180
|
+
await client.executeMultiple(`
|
|
2181
|
+
CREATE INDEX IF NOT EXISTS idx_notifications_agent_scope_read
|
|
2182
|
+
ON notifications(agent_id, session_scope, read, created_at);
|
|
2183
|
+
|
|
2184
|
+
CREATE INDEX IF NOT EXISTS idx_messages_target_scope_status
|
|
2185
|
+
ON messages(target_agent, session_scope, status, created_at);
|
|
2080
2186
|
`);
|
|
2081
2187
|
try {
|
|
2082
2188
|
await client.execute({
|
|
@@ -2660,6 +2766,13 @@ async function ensureSchema() {
|
|
|
2660
2766
|
} catch {
|
|
2661
2767
|
}
|
|
2662
2768
|
}
|
|
2769
|
+
try {
|
|
2770
|
+
await client.execute({
|
|
2771
|
+
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
2772
|
+
args: []
|
|
2773
|
+
});
|
|
2774
|
+
} catch {
|
|
2775
|
+
}
|
|
2663
2776
|
}
|
|
2664
2777
|
async function disposeDatabase() {
|
|
2665
2778
|
if (_walCheckpointTimer) {
|
|
@@ -2698,24 +2811,27 @@ var init_database = __esm({
|
|
|
2698
2811
|
});
|
|
2699
2812
|
|
|
2700
2813
|
// src/lib/license.ts
|
|
2701
|
-
import { readFileSync as
|
|
2814
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync8, mkdirSync as mkdirSync4 } from "fs";
|
|
2702
2815
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
2703
|
-
import
|
|
2816
|
+
import { createRequire as createRequire2 } from "module";
|
|
2817
|
+
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
2818
|
+
import os7 from "os";
|
|
2819
|
+
import path10 from "path";
|
|
2704
2820
|
import { jwtVerify, importSPKI } from "jose";
|
|
2705
2821
|
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
|
|
2706
2822
|
var init_license = __esm({
|
|
2707
2823
|
"src/lib/license.ts"() {
|
|
2708
2824
|
"use strict";
|
|
2709
2825
|
init_config();
|
|
2710
|
-
LICENSE_PATH =
|
|
2711
|
-
CACHE_PATH =
|
|
2712
|
-
DEVICE_ID_PATH =
|
|
2826
|
+
LICENSE_PATH = path10.join(EXE_AI_DIR, "license.key");
|
|
2827
|
+
CACHE_PATH = path10.join(EXE_AI_DIR, "license-cache.json");
|
|
2828
|
+
DEVICE_ID_PATH = path10.join(EXE_AI_DIR, "device-id");
|
|
2713
2829
|
}
|
|
2714
2830
|
});
|
|
2715
2831
|
|
|
2716
2832
|
// src/lib/plan-limits.ts
|
|
2717
|
-
import { readFileSync as
|
|
2718
|
-
import
|
|
2833
|
+
import { readFileSync as readFileSync9, existsSync as existsSync9 } from "fs";
|
|
2834
|
+
import path11 from "path";
|
|
2719
2835
|
var CACHE_PATH2;
|
|
2720
2836
|
var init_plan_limits = __esm({
|
|
2721
2837
|
"src/lib/plan-limits.ts"() {
|
|
@@ -2724,14 +2840,14 @@ var init_plan_limits = __esm({
|
|
|
2724
2840
|
init_employees();
|
|
2725
2841
|
init_license();
|
|
2726
2842
|
init_config();
|
|
2727
|
-
CACHE_PATH2 =
|
|
2843
|
+
CACHE_PATH2 = path11.join(EXE_AI_DIR, "license-cache.json");
|
|
2728
2844
|
}
|
|
2729
2845
|
});
|
|
2730
2846
|
|
|
2731
2847
|
// src/lib/tmux-routing.ts
|
|
2732
|
-
import { readFileSync as
|
|
2733
|
-
import
|
|
2734
|
-
import
|
|
2848
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync5, existsSync as existsSync10, appendFileSync, readdirSync as readdirSync2 } from "fs";
|
|
2849
|
+
import path12 from "path";
|
|
2850
|
+
import os8 from "os";
|
|
2735
2851
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2736
2852
|
function getMySession() {
|
|
2737
2853
|
return getTransport().getMySession();
|
|
@@ -2744,7 +2860,7 @@ function extractRootExe(name) {
|
|
|
2744
2860
|
}
|
|
2745
2861
|
function getParentExe(sessionKey) {
|
|
2746
2862
|
try {
|
|
2747
|
-
const data = JSON.parse(
|
|
2863
|
+
const data = JSON.parse(readFileSync10(path12.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
|
|
2748
2864
|
return data.parentExe || null;
|
|
2749
2865
|
} catch {
|
|
2750
2866
|
return null;
|
|
@@ -2787,10 +2903,10 @@ var init_tmux_routing = __esm({
|
|
|
2787
2903
|
init_intercom_queue();
|
|
2788
2904
|
init_plan_limits();
|
|
2789
2905
|
init_employees();
|
|
2790
|
-
SPAWN_LOCK_DIR =
|
|
2791
|
-
SESSION_CACHE =
|
|
2792
|
-
INTERCOM_LOG2 =
|
|
2793
|
-
DEBOUNCE_FILE =
|
|
2906
|
+
SPAWN_LOCK_DIR = path12.join(os8.homedir(), ".exe-os", "spawn-locks");
|
|
2907
|
+
SESSION_CACHE = path12.join(os8.homedir(), ".exe-os", "session-cache");
|
|
2908
|
+
INTERCOM_LOG2 = path12.join(os8.homedir(), ".exe-os", "intercom.log");
|
|
2909
|
+
DEBOUNCE_FILE = path12.join(SESSION_CACHE, "intercom-debounce.json");
|
|
2794
2910
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
2795
2911
|
}
|
|
2796
2912
|
});
|
|
@@ -2830,14 +2946,14 @@ var init_memory = __esm({
|
|
|
2830
2946
|
|
|
2831
2947
|
// src/lib/keychain.ts
|
|
2832
2948
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
2833
|
-
import { existsSync as
|
|
2834
|
-
import
|
|
2835
|
-
import
|
|
2949
|
+
import { existsSync as existsSync11 } from "fs";
|
|
2950
|
+
import path13 from "path";
|
|
2951
|
+
import os9 from "os";
|
|
2836
2952
|
function getKeyDir() {
|
|
2837
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ??
|
|
2953
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path13.join(os9.homedir(), ".exe-os");
|
|
2838
2954
|
}
|
|
2839
2955
|
function getKeyPath() {
|
|
2840
|
-
return
|
|
2956
|
+
return path13.join(getKeyDir(), "master.key");
|
|
2841
2957
|
}
|
|
2842
2958
|
async function tryKeytar() {
|
|
2843
2959
|
try {
|
|
@@ -2858,9 +2974,9 @@ async function getMasterKey() {
|
|
|
2858
2974
|
}
|
|
2859
2975
|
}
|
|
2860
2976
|
const keyPath = getKeyPath();
|
|
2861
|
-
if (!
|
|
2977
|
+
if (!existsSync11(keyPath)) {
|
|
2862
2978
|
process.stderr.write(
|
|
2863
|
-
`[keychain] Key not found at ${keyPath} (HOME=${
|
|
2979
|
+
`[keychain] Key not found at ${keyPath} (HOME=${os9.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
|
|
2864
2980
|
`
|
|
2865
2981
|
);
|
|
2866
2982
|
return null;
|
|
@@ -2945,6 +3061,7 @@ var shard_manager_exports = {};
|
|
|
2945
3061
|
__export(shard_manager_exports, {
|
|
2946
3062
|
disposeShards: () => disposeShards,
|
|
2947
3063
|
ensureShardSchema: () => ensureShardSchema,
|
|
3064
|
+
getOpenShardCount: () => getOpenShardCount,
|
|
2948
3065
|
getReadyShardClient: () => getReadyShardClient,
|
|
2949
3066
|
getShardClient: () => getShardClient,
|
|
2950
3067
|
getShardsDir: () => getShardsDir,
|
|
@@ -2953,15 +3070,18 @@ __export(shard_manager_exports, {
|
|
|
2953
3070
|
listShards: () => listShards,
|
|
2954
3071
|
shardExists: () => shardExists
|
|
2955
3072
|
});
|
|
2956
|
-
import
|
|
2957
|
-
import { existsSync as
|
|
3073
|
+
import path14 from "path";
|
|
3074
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync6, readdirSync as readdirSync3 } from "fs";
|
|
2958
3075
|
import { createClient as createClient2 } from "@libsql/client";
|
|
2959
3076
|
function initShardManager(encryptionKey) {
|
|
2960
3077
|
_encryptionKey = encryptionKey;
|
|
2961
|
-
if (!
|
|
3078
|
+
if (!existsSync12(SHARDS_DIR)) {
|
|
2962
3079
|
mkdirSync6(SHARDS_DIR, { recursive: true });
|
|
2963
3080
|
}
|
|
2964
3081
|
_shardingEnabled = true;
|
|
3082
|
+
if (_evictionTimer) clearInterval(_evictionTimer);
|
|
3083
|
+
_evictionTimer = setInterval(evictIdleShards, EVICTION_INTERVAL_MS);
|
|
3084
|
+
_evictionTimer.unref();
|
|
2965
3085
|
}
|
|
2966
3086
|
function isShardingEnabled() {
|
|
2967
3087
|
return _shardingEnabled;
|
|
@@ -2978,21 +3098,28 @@ function getShardClient(projectName) {
|
|
|
2978
3098
|
throw new Error(`Invalid project name for shard: "${projectName}"`);
|
|
2979
3099
|
}
|
|
2980
3100
|
const cached = _shards.get(safeName);
|
|
2981
|
-
if (cached)
|
|
2982
|
-
|
|
3101
|
+
if (cached) {
|
|
3102
|
+
_shardLastAccess.set(safeName, Date.now());
|
|
3103
|
+
return cached;
|
|
3104
|
+
}
|
|
3105
|
+
while (_shards.size >= MAX_OPEN_SHARDS) {
|
|
3106
|
+
evictLRU();
|
|
3107
|
+
}
|
|
3108
|
+
const dbPath = path14.join(SHARDS_DIR, `${safeName}.db`);
|
|
2983
3109
|
const client = createClient2({
|
|
2984
3110
|
url: `file:${dbPath}`,
|
|
2985
3111
|
encryptionKey: _encryptionKey
|
|
2986
3112
|
});
|
|
2987
3113
|
_shards.set(safeName, client);
|
|
3114
|
+
_shardLastAccess.set(safeName, Date.now());
|
|
2988
3115
|
return client;
|
|
2989
3116
|
}
|
|
2990
3117
|
function shardExists(projectName) {
|
|
2991
3118
|
const safeName = projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
2992
|
-
return
|
|
3119
|
+
return existsSync12(path14.join(SHARDS_DIR, `${safeName}.db`));
|
|
2993
3120
|
}
|
|
2994
3121
|
function listShards() {
|
|
2995
|
-
if (!
|
|
3122
|
+
if (!existsSync12(SHARDS_DIR)) return [];
|
|
2996
3123
|
return readdirSync3(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
2997
3124
|
}
|
|
2998
3125
|
async function ensureShardSchema(client) {
|
|
@@ -3044,6 +3171,8 @@ async function ensureShardSchema(client) {
|
|
|
3044
3171
|
for (const col of [
|
|
3045
3172
|
"ALTER TABLE memories ADD COLUMN task_id TEXT",
|
|
3046
3173
|
"ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0",
|
|
3174
|
+
"ALTER TABLE memories ADD COLUMN author_device_id TEXT",
|
|
3175
|
+
"ALTER TABLE memories ADD COLUMN scope TEXT NOT NULL DEFAULT 'business'",
|
|
3047
3176
|
"ALTER TABLE memories ADD COLUMN importance INTEGER DEFAULT 5",
|
|
3048
3177
|
"ALTER TABLE memories ADD COLUMN status TEXT DEFAULT 'active'",
|
|
3049
3178
|
"ALTER TABLE memories ADD COLUMN wiki_synced INTEGER DEFAULT 0",
|
|
@@ -3181,21 +3310,69 @@ async function getReadyShardClient(projectName) {
|
|
|
3181
3310
|
await ensureShardSchema(client);
|
|
3182
3311
|
return client;
|
|
3183
3312
|
}
|
|
3313
|
+
function evictLRU() {
|
|
3314
|
+
let oldest = null;
|
|
3315
|
+
let oldestTime = Infinity;
|
|
3316
|
+
for (const [name, time] of _shardLastAccess) {
|
|
3317
|
+
if (time < oldestTime) {
|
|
3318
|
+
oldestTime = time;
|
|
3319
|
+
oldest = name;
|
|
3320
|
+
}
|
|
3321
|
+
}
|
|
3322
|
+
if (oldest) {
|
|
3323
|
+
const client = _shards.get(oldest);
|
|
3324
|
+
if (client) {
|
|
3325
|
+
client.close();
|
|
3326
|
+
}
|
|
3327
|
+
_shards.delete(oldest);
|
|
3328
|
+
_shardLastAccess.delete(oldest);
|
|
3329
|
+
}
|
|
3330
|
+
}
|
|
3331
|
+
function evictIdleShards() {
|
|
3332
|
+
const now = Date.now();
|
|
3333
|
+
const toEvict = [];
|
|
3334
|
+
for (const [name, lastAccess] of _shardLastAccess) {
|
|
3335
|
+
if (now - lastAccess > SHARD_IDLE_MS) {
|
|
3336
|
+
toEvict.push(name);
|
|
3337
|
+
}
|
|
3338
|
+
}
|
|
3339
|
+
for (const name of toEvict) {
|
|
3340
|
+
const client = _shards.get(name);
|
|
3341
|
+
if (client) {
|
|
3342
|
+
client.close();
|
|
3343
|
+
}
|
|
3344
|
+
_shards.delete(name);
|
|
3345
|
+
_shardLastAccess.delete(name);
|
|
3346
|
+
}
|
|
3347
|
+
}
|
|
3348
|
+
function getOpenShardCount() {
|
|
3349
|
+
return _shards.size;
|
|
3350
|
+
}
|
|
3184
3351
|
function disposeShards() {
|
|
3352
|
+
if (_evictionTimer) {
|
|
3353
|
+
clearInterval(_evictionTimer);
|
|
3354
|
+
_evictionTimer = null;
|
|
3355
|
+
}
|
|
3185
3356
|
for (const [, client] of _shards) {
|
|
3186
3357
|
client.close();
|
|
3187
3358
|
}
|
|
3188
3359
|
_shards.clear();
|
|
3360
|
+
_shardLastAccess.clear();
|
|
3189
3361
|
_shardingEnabled = false;
|
|
3190
3362
|
_encryptionKey = null;
|
|
3191
3363
|
}
|
|
3192
|
-
var SHARDS_DIR, _shards, _encryptionKey, _shardingEnabled;
|
|
3364
|
+
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled;
|
|
3193
3365
|
var init_shard_manager = __esm({
|
|
3194
3366
|
"src/lib/shard-manager.ts"() {
|
|
3195
3367
|
"use strict";
|
|
3196
3368
|
init_config();
|
|
3197
|
-
SHARDS_DIR =
|
|
3369
|
+
SHARDS_DIR = path14.join(EXE_AI_DIR, "shards");
|
|
3370
|
+
SHARD_IDLE_MS = 5 * 60 * 1e3;
|
|
3371
|
+
MAX_OPEN_SHARDS = 10;
|
|
3372
|
+
EVICTION_INTERVAL_MS = 60 * 1e3;
|
|
3198
3373
|
_shards = /* @__PURE__ */ new Map();
|
|
3374
|
+
_shardLastAccess = /* @__PURE__ */ new Map();
|
|
3375
|
+
_evictionTimer = null;
|
|
3199
3376
|
_encryptionKey = null;
|
|
3200
3377
|
_shardingEnabled = false;
|
|
3201
3378
|
}
|
|
@@ -3962,15 +4139,15 @@ var init_store = __esm({
|
|
|
3962
4139
|
init_config();
|
|
3963
4140
|
init_config();
|
|
3964
4141
|
import { spawn as spawn2 } from "child_process";
|
|
3965
|
-
import { existsSync as
|
|
3966
|
-
import
|
|
4142
|
+
import { existsSync as existsSync13, openSync as openSync2, closeSync as closeSync2 } from "fs";
|
|
4143
|
+
import path15 from "path";
|
|
3967
4144
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3968
4145
|
|
|
3969
4146
|
// src/lib/active-agent.ts
|
|
3970
4147
|
init_config();
|
|
3971
4148
|
init_session_key();
|
|
3972
4149
|
init_employees();
|
|
3973
|
-
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync, unlinkSync as unlinkSync2, readdirSync } from "fs";
|
|
4150
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2, readdirSync } from "fs";
|
|
3974
4151
|
import { execSync as execSync3 } from "child_process";
|
|
3975
4152
|
import path3 from "path";
|
|
3976
4153
|
var CACHE_DIR = path3.join(EXE_AI_DIR, "session-cache");
|
|
@@ -4073,7 +4250,7 @@ if (!process.env.AGENT_ID) {
|
|
|
4073
4250
|
if (!loadConfigSync().autoIngestion) {
|
|
4074
4251
|
process.exit(0);
|
|
4075
4252
|
}
|
|
4076
|
-
var WORKER_LOG_PATH =
|
|
4253
|
+
var WORKER_LOG_PATH = path15.join(EXE_AI_DIR, "workers.log");
|
|
4077
4254
|
function openWorkerLog() {
|
|
4078
4255
|
try {
|
|
4079
4256
|
return openSync2(WORKER_LOG_PATH, "a");
|
|
@@ -4081,6 +4258,25 @@ function openWorkerLog() {
|
|
|
4081
4258
|
return "ignore";
|
|
4082
4259
|
}
|
|
4083
4260
|
}
|
|
4261
|
+
function spawnDetachedWorker(workerPath, env, cwd) {
|
|
4262
|
+
if (!existsSync13(workerPath)) {
|
|
4263
|
+
process.stderr.write(`[stop] WARN: worker not found at ${workerPath}
|
|
4264
|
+
`);
|
|
4265
|
+
return;
|
|
4266
|
+
}
|
|
4267
|
+
const stderrFd = openWorkerLog();
|
|
4268
|
+
const worker = spawn2(process.execPath, [workerPath], {
|
|
4269
|
+
cwd,
|
|
4270
|
+
detached: true,
|
|
4271
|
+
stdio: ["ignore", "ignore", stderrFd],
|
|
4272
|
+
env
|
|
4273
|
+
});
|
|
4274
|
+
worker.unref();
|
|
4275
|
+
if (typeof stderrFd === "number") try {
|
|
4276
|
+
closeSync2(stderrFd);
|
|
4277
|
+
} catch {
|
|
4278
|
+
}
|
|
4279
|
+
}
|
|
4084
4280
|
var MIN_LENGTH = 100;
|
|
4085
4281
|
var timeout = setTimeout(() => {
|
|
4086
4282
|
process.exit(0);
|
|
@@ -4096,22 +4292,36 @@ process.stdin.on("end", () => {
|
|
|
4096
4292
|
try {
|
|
4097
4293
|
if (process.env.EXE_DEBUG_HOOKS || process.env.EXE_RUNTIME === "codex") {
|
|
4098
4294
|
try {
|
|
4099
|
-
const debugPath =
|
|
4100
|
-
const { mkdirSync: mkdirSync7, writeFileSync:
|
|
4101
|
-
mkdirSync7(
|
|
4295
|
+
const debugPath = path15.join(EXE_AI_DIR, "logs", "hook-stdin-stop.log");
|
|
4296
|
+
const { mkdirSync: mkdirSync7, writeFileSync: writeFileSync8 } = __require("fs");
|
|
4297
|
+
mkdirSync7(path15.dirname(debugPath), { recursive: true });
|
|
4102
4298
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
4103
4299
|
const snippet = input.length > 500 ? input.slice(0, 500) + "...[truncated]" : input;
|
|
4104
|
-
|
|
4300
|
+
writeFileSync8(debugPath, `[${ts}] len=${input.length} ${snippet}
|
|
4105
4301
|
`, { flag: "a" });
|
|
4106
4302
|
} catch {
|
|
4107
4303
|
}
|
|
4108
4304
|
}
|
|
4109
4305
|
const data = JSON.parse(input);
|
|
4110
|
-
const
|
|
4306
|
+
const agent = getActiveAgent();
|
|
4307
|
+
const message = data.last_assistant_message ?? "";
|
|
4308
|
+
const cwd = data.cwd ?? process.cwd();
|
|
4309
|
+
if (process.env.EXE_RUNTIME === "codex" && !canCoordinate(agent.agentId, agent.agentRole)) {
|
|
4310
|
+
const codexFinalizerPath = path15.resolve(
|
|
4311
|
+
path15.dirname(fileURLToPath3(import.meta.url)),
|
|
4312
|
+
"codex-stop-task-finalizer.js"
|
|
4313
|
+
);
|
|
4314
|
+
spawnDetachedWorker(codexFinalizerPath, {
|
|
4315
|
+
...process.env,
|
|
4316
|
+
AGENT_ID: agent.agentId,
|
|
4317
|
+
AGENT_ROLE: agent.agentRole,
|
|
4318
|
+
EXE_RESPONSE_TEXT: message.slice(0, 5e3),
|
|
4319
|
+
EXE_SESSION_ID: data.session_id
|
|
4320
|
+
}, cwd);
|
|
4321
|
+
}
|
|
4111
4322
|
if (!message || message.length < MIN_LENGTH) {
|
|
4112
4323
|
process.exit(0);
|
|
4113
4324
|
}
|
|
4114
|
-
const agent = getActiveAgent();
|
|
4115
4325
|
const CAPACITY_SIGNALS = /context[- ]?full|hit capacity|conversation is too long|maximum context length|context window.*(?:limit|exceed|full)/i;
|
|
4116
4326
|
if (!canCoordinate(agent.agentId, agent.agentRole) && CAPACITY_SIGNALS.test(message)) {
|
|
4117
4327
|
Promise.resolve().then(() => (init_store(), store_exports)).then(({ initStore: initStore2 }) => initStore2()).then(() => Promise.all([
|
|
@@ -4136,9 +4346,9 @@ process.stdin.on("end", () => {
|
|
|
4136
4346
|
"",
|
|
4137
4347
|
`Last response fragment: ${message.slice(0, 500)}`
|
|
4138
4348
|
].join("\n");
|
|
4139
|
-
const
|
|
4349
|
+
const crypto2 = await import("crypto");
|
|
4140
4350
|
await writeMemory2({
|
|
4141
|
-
id:
|
|
4351
|
+
id: crypto2.randomUUID(),
|
|
4142
4352
|
agent_id: agent.agentId,
|
|
4143
4353
|
agent_role: agent.agentRole,
|
|
4144
4354
|
session_id: data.session_id,
|
|
@@ -4177,32 +4387,17 @@ process.stdin.on("end", () => {
|
|
|
4177
4387
|
}).catch(() => {
|
|
4178
4388
|
});
|
|
4179
4389
|
}
|
|
4180
|
-
const workerPath =
|
|
4181
|
-
|
|
4390
|
+
const workerPath = path15.resolve(
|
|
4391
|
+
path15.dirname(fileURLToPath3(import.meta.url)),
|
|
4182
4392
|
"response-ingest-worker.js"
|
|
4183
4393
|
);
|
|
4184
|
-
|
|
4185
|
-
process.
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
detached: true,
|
|
4192
|
-
stdio: ["ignore", "ignore", stderrFd],
|
|
4193
|
-
env: {
|
|
4194
|
-
...process.env,
|
|
4195
|
-
AGENT_ID: agent.agentId,
|
|
4196
|
-
AGENT_ROLE: agent.agentRole,
|
|
4197
|
-
EXE_RESPONSE_TEXT: message.slice(0, 5e3),
|
|
4198
|
-
EXE_SESSION_ID: data.session_id
|
|
4199
|
-
}
|
|
4200
|
-
});
|
|
4201
|
-
worker.unref();
|
|
4202
|
-
if (typeof stderrFd === "number") try {
|
|
4203
|
-
closeSync2(stderrFd);
|
|
4204
|
-
} catch {
|
|
4205
|
-
}
|
|
4394
|
+
spawnDetachedWorker(workerPath, {
|
|
4395
|
+
...process.env,
|
|
4396
|
+
AGENT_ID: agent.agentId,
|
|
4397
|
+
AGENT_ROLE: agent.agentRole,
|
|
4398
|
+
EXE_RESPONSE_TEXT: message.slice(0, 5e3),
|
|
4399
|
+
EXE_SESSION_ID: data.session_id
|
|
4400
|
+
}, cwd);
|
|
4206
4401
|
} catch {
|
|
4207
4402
|
}
|
|
4208
4403
|
process.exit(0);
|