@askexenow/exe-os 0.9.0 → 0.9.1
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/cli.js +124 -32
- package/dist/bin/exe-boot.js +89 -5
- package/dist/bin/exe-dispatch.js +96 -6
- package/dist/bin/exe-doctor.js +55 -2
- package/dist/bin/exe-gateway.js +89 -5
- package/dist/bin/exe-new-employee.js +17 -13
- package/dist/bin/exe-session-cleanup.js +91 -1
- package/dist/bin/exe-start-codex.js +12 -8
- package/dist/bin/git-sweep.js +96 -6
- package/dist/bin/install.js +17 -13
- package/dist/bin/scan-tasks.js +96 -6
- package/dist/gateway/index.js +95 -5
- package/dist/hooks/bug-report-worker.js +91 -1
- package/dist/hooks/commit-complete.js +96 -6
- package/dist/hooks/error-recall.js +14 -0
- package/dist/hooks/ingest-worker.js +85 -1
- package/dist/hooks/ingest.js +11 -0
- package/dist/hooks/pre-compact.js +96 -6
- package/dist/hooks/prompt-submit.js +17 -0
- package/dist/hooks/session-end.js +96 -6
- package/dist/hooks/stop.js +18 -0
- package/dist/index.js +94 -10
- package/dist/lib/exe-daemon.js +17 -0
- package/dist/lib/tasks.js +91 -1
- package/dist/lib/tmux-routing.js +91 -1
- package/dist/mcp/server.js +339 -34
- package/dist/mcp/tools/create-task.js +91 -1
- package/dist/mcp/tools/update-task.js +91 -1
- package/dist/runtime/index.js +90 -6
- package/dist/tui/App.js +90 -6
- package/package.json +1 -1
package/dist/bin/exe-doctor.js
CHANGED
|
@@ -2025,7 +2025,7 @@ function isMainModule(importMetaUrl) {
|
|
|
2025
2025
|
}
|
|
2026
2026
|
|
|
2027
2027
|
// src/bin/exe-doctor.ts
|
|
2028
|
-
import { existsSync as existsSync6 } from "fs";
|
|
2028
|
+
import { existsSync as existsSync6, readFileSync as readFileSync3 } from "fs";
|
|
2029
2029
|
import { spawn } from "child_process";
|
|
2030
2030
|
import path6 from "path";
|
|
2031
2031
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
@@ -2437,6 +2437,46 @@ async function auditOrphanedProjects(client) {
|
|
|
2437
2437
|
}
|
|
2438
2438
|
return orphans;
|
|
2439
2439
|
}
|
|
2440
|
+
function auditHookHealth() {
|
|
2441
|
+
const logPath = path6.join(
|
|
2442
|
+
process.env.HOME ?? process.env.USERPROFILE ?? "",
|
|
2443
|
+
".exe-os",
|
|
2444
|
+
"logs",
|
|
2445
|
+
"hooks.log"
|
|
2446
|
+
);
|
|
2447
|
+
if (!existsSync6(logPath)) {
|
|
2448
|
+
return { logExists: false, totalLines: 0, errorsLastHour: 0, topPatterns: [] };
|
|
2449
|
+
}
|
|
2450
|
+
let content;
|
|
2451
|
+
try {
|
|
2452
|
+
content = readFileSync3(logPath, "utf-8");
|
|
2453
|
+
} catch {
|
|
2454
|
+
return { logExists: false, totalLines: 0, errorsLastHour: 0, topPatterns: [] };
|
|
2455
|
+
}
|
|
2456
|
+
const lines = content.split("\n").filter(Boolean);
|
|
2457
|
+
const totalLines = lines.length;
|
|
2458
|
+
const recent = lines.slice(-200);
|
|
2459
|
+
const oneHourAgo = new Date(Date.now() - 36e5).toISOString();
|
|
2460
|
+
let errorsLastHour = 0;
|
|
2461
|
+
const patternCounts = /* @__PURE__ */ new Map();
|
|
2462
|
+
for (const line of recent) {
|
|
2463
|
+
const isError = /error|Error|ERR|FAIL|throw|exception|TypeError|ReferenceError|SyntaxError/i.test(line);
|
|
2464
|
+
if (!isError) continue;
|
|
2465
|
+
const tsMatch = line.match(/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})/);
|
|
2466
|
+
if (tsMatch && tsMatch[1] >= oneHourAgo) {
|
|
2467
|
+
errorsLastHour++;
|
|
2468
|
+
} else if (!tsMatch) {
|
|
2469
|
+
errorsLastHour++;
|
|
2470
|
+
}
|
|
2471
|
+
const patternMatch = line.match(/((?:TypeError|ReferenceError|SyntaxError|Error):[^\n]{0,80})/);
|
|
2472
|
+
if (patternMatch) {
|
|
2473
|
+
const p = patternMatch[1];
|
|
2474
|
+
patternCounts.set(p, (patternCounts.get(p) ?? 0) + 1);
|
|
2475
|
+
}
|
|
2476
|
+
}
|
|
2477
|
+
const topPatterns = [...patternCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([pattern, count]) => ({ pattern, count }));
|
|
2478
|
+
return { logExists: true, totalLines, errorsLastHour, topPatterns };
|
|
2479
|
+
}
|
|
2440
2480
|
async function runAudit(client, flags) {
|
|
2441
2481
|
const [stats, nullVectors, duplicates, bloated, fts, orphanedProjects, conflicts] = await Promise.all([
|
|
2442
2482
|
auditStats(client, flags),
|
|
@@ -2448,7 +2488,8 @@ async function runAudit(client, flags) {
|
|
|
2448
2488
|
detectConflicts(client, flags.project, flags.agent)
|
|
2449
2489
|
]);
|
|
2450
2490
|
const duplicateCount = duplicates.reduce((sum, d) => sum + d.delete_ids.length, 0);
|
|
2451
|
-
|
|
2491
|
+
const hookHealth = auditHookHealth();
|
|
2492
|
+
return { stats, nullVectors, duplicates, duplicateCount, bloated, fts, orphanedProjects, conflicts, hookHealth };
|
|
2452
2493
|
}
|
|
2453
2494
|
function indicator(value, warn) {
|
|
2454
2495
|
if (value === 0) return "\u{1F7E2}";
|
|
@@ -2516,6 +2557,17 @@ function formatReport(report, flags) {
|
|
|
2516
2557
|
} else {
|
|
2517
2558
|
lines.push("\u{1F7E2} Conflicts: none detected");
|
|
2518
2559
|
}
|
|
2560
|
+
const hh = report.hookHealth;
|
|
2561
|
+
if (!hh.logExists) {
|
|
2562
|
+
lines.push("\u{1F7E0} Hook logs: no log file (run installer to enable stderr capture)");
|
|
2563
|
+
} else if (hh.errorsLastHour === 0) {
|
|
2564
|
+
lines.push(`\u{1F7E2} Hook logs: ${fmtNum(hh.totalLines)} lines, 0 errors in last hour`);
|
|
2565
|
+
} else {
|
|
2566
|
+
lines.push(`\u{1F534} Hook logs: ${fmtNum(hh.errorsLastHour)} errors in last hour (${fmtNum(hh.totalLines)} total lines)`);
|
|
2567
|
+
for (const p of hh.topPatterns) {
|
|
2568
|
+
lines.push(` ${p.count}x: ${p.pattern}`);
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2519
2571
|
lines.push("");
|
|
2520
2572
|
if (flags.verbose) {
|
|
2521
2573
|
if (report.duplicates.length > 0) {
|
|
@@ -2749,6 +2801,7 @@ export {
|
|
|
2749
2801
|
auditBloated,
|
|
2750
2802
|
auditDuplicates,
|
|
2751
2803
|
auditFts,
|
|
2804
|
+
auditHookHealth,
|
|
2752
2805
|
auditNullVectors,
|
|
2753
2806
|
auditOrphanedProjects,
|
|
2754
2807
|
auditStats,
|
package/dist/bin/exe-gateway.js
CHANGED
|
@@ -6448,6 +6448,14 @@ var init_agent_config = __esm({
|
|
|
6448
6448
|
});
|
|
6449
6449
|
|
|
6450
6450
|
// src/lib/intercom-queue.ts
|
|
6451
|
+
var intercom_queue_exports = {};
|
|
6452
|
+
__export(intercom_queue_exports, {
|
|
6453
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
6454
|
+
drainForSession: () => drainForSession,
|
|
6455
|
+
drainQueue: () => drainQueue,
|
|
6456
|
+
queueIntercom: () => queueIntercom,
|
|
6457
|
+
readQueue: () => readQueue
|
|
6458
|
+
});
|
|
6451
6459
|
import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, renameSync as renameSync3, existsSync as existsSync9, mkdirSync as mkdirSync6 } from "fs";
|
|
6452
6460
|
import path10 from "path";
|
|
6453
6461
|
import os7 from "os";
|
|
@@ -6486,11 +6494,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
6486
6494
|
}
|
|
6487
6495
|
writeQueue(queue);
|
|
6488
6496
|
}
|
|
6489
|
-
|
|
6497
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
6498
|
+
const queue = readQueue();
|
|
6499
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
6500
|
+
const remaining = [];
|
|
6501
|
+
let drained = 0;
|
|
6502
|
+
let failed = 0;
|
|
6503
|
+
for (const item of queue) {
|
|
6504
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
6505
|
+
if (age > TTL_MS) {
|
|
6506
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
6507
|
+
failed++;
|
|
6508
|
+
continue;
|
|
6509
|
+
}
|
|
6510
|
+
try {
|
|
6511
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
6512
|
+
const success = sendKeys(item.targetSession);
|
|
6513
|
+
if (success) {
|
|
6514
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
6515
|
+
drained++;
|
|
6516
|
+
continue;
|
|
6517
|
+
}
|
|
6518
|
+
}
|
|
6519
|
+
} catch {
|
|
6520
|
+
}
|
|
6521
|
+
item.attempts++;
|
|
6522
|
+
if (item.attempts >= MAX_RETRIES2) {
|
|
6523
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES2} retries exhausted, reason: ${item.reason})`);
|
|
6524
|
+
failed++;
|
|
6525
|
+
continue;
|
|
6526
|
+
}
|
|
6527
|
+
remaining.push(item);
|
|
6528
|
+
}
|
|
6529
|
+
writeQueue(remaining);
|
|
6530
|
+
return { drained, failed };
|
|
6531
|
+
}
|
|
6532
|
+
function drainForSession(targetSession, sendKeys) {
|
|
6533
|
+
const queue = readQueue();
|
|
6534
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
6535
|
+
if (match < 0) return false;
|
|
6536
|
+
const success = sendKeys(targetSession);
|
|
6537
|
+
if (success) {
|
|
6538
|
+
queue.splice(match, 1);
|
|
6539
|
+
writeQueue(queue);
|
|
6540
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
6541
|
+
return true;
|
|
6542
|
+
}
|
|
6543
|
+
return false;
|
|
6544
|
+
}
|
|
6545
|
+
function clearQueueForAgent(agentName) {
|
|
6546
|
+
const queue = readQueue();
|
|
6547
|
+
const before = queue.length;
|
|
6548
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
6549
|
+
if (filtered.length < before) {
|
|
6550
|
+
writeQueue(filtered);
|
|
6551
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
6552
|
+
}
|
|
6553
|
+
}
|
|
6554
|
+
function logQueue(msg) {
|
|
6555
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
6556
|
+
`;
|
|
6557
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
6558
|
+
`);
|
|
6559
|
+
try {
|
|
6560
|
+
const { appendFileSync: appendFileSync2 } = __require("fs");
|
|
6561
|
+
appendFileSync2(INTERCOM_LOG, line);
|
|
6562
|
+
} catch {
|
|
6563
|
+
}
|
|
6564
|
+
}
|
|
6565
|
+
var QUEUE_PATH, MAX_RETRIES2, TTL_MS, INTERCOM_LOG;
|
|
6490
6566
|
var init_intercom_queue = __esm({
|
|
6491
6567
|
"src/lib/intercom-queue.ts"() {
|
|
6492
6568
|
"use strict";
|
|
6493
6569
|
QUEUE_PATH = path10.join(os7.homedir(), ".exe-os", "intercom-queue.json");
|
|
6570
|
+
MAX_RETRIES2 = 5;
|
|
6494
6571
|
TTL_MS = 60 * 60 * 1e3;
|
|
6495
6572
|
INTERCOM_LOG = path10.join(os7.homedir(), ".exe-os", "intercom.log");
|
|
6496
6573
|
}
|
|
@@ -7176,6 +7253,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
7176
7253
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
7177
7254
|
} catch {
|
|
7178
7255
|
}
|
|
7256
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
7257
|
+
try {
|
|
7258
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
7259
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
7260
|
+
} catch {
|
|
7261
|
+
}
|
|
7262
|
+
}
|
|
7179
7263
|
try {
|
|
7180
7264
|
await writeCheckpoint({
|
|
7181
7265
|
taskId,
|
|
@@ -9415,7 +9499,7 @@ async function deliverLocalMessage(messageId) {
|
|
|
9415
9499
|
return true;
|
|
9416
9500
|
} catch {
|
|
9417
9501
|
const newRetryCount = msg.retryCount + 1;
|
|
9418
|
-
if (newRetryCount >=
|
|
9502
|
+
if (newRetryCount >= MAX_RETRIES3) {
|
|
9419
9503
|
await markFailed(messageId, "session unavailable after 10 retries");
|
|
9420
9504
|
} else {
|
|
9421
9505
|
await client.execute({
|
|
@@ -9504,7 +9588,7 @@ async function retryPendingMessages() {
|
|
|
9504
9588
|
sql: `SELECT * FROM messages
|
|
9505
9589
|
WHERE status = 'pending' AND retry_count < ?
|
|
9506
9590
|
ORDER BY id`,
|
|
9507
|
-
args: [
|
|
9591
|
+
args: [MAX_RETRIES3]
|
|
9508
9592
|
});
|
|
9509
9593
|
let delivered = 0;
|
|
9510
9594
|
for (const row of result.rows) {
|
|
@@ -9517,13 +9601,13 @@ async function retryPendingMessages() {
|
|
|
9517
9601
|
}
|
|
9518
9602
|
return delivered;
|
|
9519
9603
|
}
|
|
9520
|
-
var
|
|
9604
|
+
var MAX_RETRIES3, _wsClientSend;
|
|
9521
9605
|
var init_messaging = __esm({
|
|
9522
9606
|
"src/lib/messaging.ts"() {
|
|
9523
9607
|
"use strict";
|
|
9524
9608
|
init_database();
|
|
9525
9609
|
init_tmux_routing();
|
|
9526
|
-
|
|
9610
|
+
MAX_RETRIES3 = 10;
|
|
9527
9611
|
_wsClientSend = null;
|
|
9528
9612
|
}
|
|
9529
9613
|
});
|
|
@@ -1162,6 +1162,10 @@ async function cleanSettingsJsonMcp(settingsPath) {
|
|
|
1162
1162
|
}
|
|
1163
1163
|
async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
1164
1164
|
const settingsPath = path9.join(homeDir, ".claude", "settings.json");
|
|
1165
|
+
const logsDir = path9.join(homeDir, ".exe-os", "logs");
|
|
1166
|
+
const hookLogPath = path9.join(logsDir, "hooks.log");
|
|
1167
|
+
const logSuffix = ` 2>> "${hookLogPath}"`;
|
|
1168
|
+
await mkdir3(logsDir, { recursive: true });
|
|
1165
1169
|
let settings = {};
|
|
1166
1170
|
if (existsSync9(settingsPath)) {
|
|
1167
1171
|
try {
|
|
@@ -1185,11 +1189,11 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
1185
1189
|
hooks: [
|
|
1186
1190
|
{
|
|
1187
1191
|
type: "command",
|
|
1188
|
-
command: `node "${path9.join(packageRoot, "dist", "hooks", "ingest.js")}"`
|
|
1192
|
+
command: `node "${path9.join(packageRoot, "dist", "hooks", "ingest.js")}"${logSuffix}`
|
|
1189
1193
|
},
|
|
1190
1194
|
{
|
|
1191
1195
|
type: "command",
|
|
1192
|
-
command: `node "${path9.join(packageRoot, "dist", "hooks", "error-recall.js")}"`
|
|
1196
|
+
command: `node "${path9.join(packageRoot, "dist", "hooks", "error-recall.js")}"${logSuffix}`
|
|
1193
1197
|
}
|
|
1194
1198
|
]
|
|
1195
1199
|
},
|
|
@@ -1201,7 +1205,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
1201
1205
|
hooks: [
|
|
1202
1206
|
{
|
|
1203
1207
|
type: "command",
|
|
1204
|
-
command: `node "${path9.join(packageRoot, "dist", "hooks", "session-start.js")}"`,
|
|
1208
|
+
command: `node "${path9.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
|
|
1205
1209
|
timeout: 1e4
|
|
1206
1210
|
}
|
|
1207
1211
|
]
|
|
@@ -1214,7 +1218,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
1214
1218
|
hooks: [
|
|
1215
1219
|
{
|
|
1216
1220
|
type: "command",
|
|
1217
|
-
command: `node "${path9.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"`
|
|
1221
|
+
command: `node "${path9.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
|
|
1218
1222
|
}
|
|
1219
1223
|
]
|
|
1220
1224
|
},
|
|
@@ -1226,7 +1230,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
1226
1230
|
hooks: [
|
|
1227
1231
|
{
|
|
1228
1232
|
type: "command",
|
|
1229
|
-
command: `node "${path9.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"`,
|
|
1233
|
+
command: `node "${path9.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
|
|
1230
1234
|
timeout: 5e3
|
|
1231
1235
|
}
|
|
1232
1236
|
]
|
|
@@ -1239,7 +1243,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
1239
1243
|
hooks: [
|
|
1240
1244
|
{
|
|
1241
1245
|
type: "command",
|
|
1242
|
-
command: `node "${path9.join(packageRoot, "dist", "hooks", "stop.js")}"`
|
|
1246
|
+
command: `node "${path9.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
|
|
1243
1247
|
}
|
|
1244
1248
|
]
|
|
1245
1249
|
},
|
|
@@ -1252,7 +1256,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
1252
1256
|
hooks: [
|
|
1253
1257
|
{
|
|
1254
1258
|
type: "command",
|
|
1255
|
-
command: `node "${path9.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"`
|
|
1259
|
+
command: `node "${path9.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
|
|
1256
1260
|
}
|
|
1257
1261
|
]
|
|
1258
1262
|
},
|
|
@@ -1264,7 +1268,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
1264
1268
|
hooks: [
|
|
1265
1269
|
{
|
|
1266
1270
|
type: "command",
|
|
1267
|
-
command: `node "${path9.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"`
|
|
1271
|
+
command: `node "${path9.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"${logSuffix}`
|
|
1268
1272
|
}
|
|
1269
1273
|
]
|
|
1270
1274
|
},
|
|
@@ -1276,7 +1280,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
1276
1280
|
hooks: [
|
|
1277
1281
|
{
|
|
1278
1282
|
type: "command",
|
|
1279
|
-
command: `node "${path9.join(packageRoot, "dist", "hooks", "pre-compact.js")}"`,
|
|
1283
|
+
command: `node "${path9.join(packageRoot, "dist", "hooks", "pre-compact.js")}"${logSuffix}`,
|
|
1280
1284
|
timeout: 1e4
|
|
1281
1285
|
}
|
|
1282
1286
|
]
|
|
@@ -1289,7 +1293,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
1289
1293
|
hooks: [
|
|
1290
1294
|
{
|
|
1291
1295
|
type: "command",
|
|
1292
|
-
command: `node "${path9.join(packageRoot, "dist", "hooks", "session-end.js")}"`
|
|
1296
|
+
command: `node "${path9.join(packageRoot, "dist", "hooks", "session-end.js")}"${logSuffix}`
|
|
1293
1297
|
}
|
|
1294
1298
|
]
|
|
1295
1299
|
},
|
|
@@ -1301,7 +1305,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
1301
1305
|
hooks: [
|
|
1302
1306
|
{
|
|
1303
1307
|
type: "command",
|
|
1304
|
-
command: `node "${path9.join(packageRoot, "dist", "hooks", "notification.js")}"`
|
|
1308
|
+
command: `node "${path9.join(packageRoot, "dist", "hooks", "notification.js")}"${logSuffix}`
|
|
1305
1309
|
}
|
|
1306
1310
|
]
|
|
1307
1311
|
},
|
|
@@ -1313,7 +1317,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
1313
1317
|
hooks: [
|
|
1314
1318
|
{
|
|
1315
1319
|
type: "command",
|
|
1316
|
-
command: `node "${path9.join(packageRoot, "dist", "hooks", "post-compact.js")}"`,
|
|
1320
|
+
command: `node "${path9.join(packageRoot, "dist", "hooks", "post-compact.js")}"${logSuffix}`,
|
|
1317
1321
|
timeout: 1e4
|
|
1318
1322
|
}
|
|
1319
1323
|
]
|
|
@@ -1326,7 +1330,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
1326
1330
|
hooks: [
|
|
1327
1331
|
{
|
|
1328
1332
|
type: "command",
|
|
1329
|
-
command: `node "${path9.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"`
|
|
1333
|
+
command: `node "${path9.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"${logSuffix}`
|
|
1330
1334
|
}
|
|
1331
1335
|
]
|
|
1332
1336
|
},
|
|
@@ -3,6 +3,12 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
7
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
8
|
+
}) : x)(function(x) {
|
|
9
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
10
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
11
|
+
});
|
|
6
12
|
var __esm = (fn, res) => function __init() {
|
|
7
13
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
14
|
};
|
|
@@ -3428,6 +3434,14 @@ var init_agent_config = __esm({
|
|
|
3428
3434
|
});
|
|
3429
3435
|
|
|
3430
3436
|
// src/lib/intercom-queue.ts
|
|
3437
|
+
var intercom_queue_exports = {};
|
|
3438
|
+
__export(intercom_queue_exports, {
|
|
3439
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
3440
|
+
drainForSession: () => drainForSession,
|
|
3441
|
+
drainQueue: () => drainQueue,
|
|
3442
|
+
queueIntercom: () => queueIntercom,
|
|
3443
|
+
readQueue: () => readQueue
|
|
3444
|
+
});
|
|
3431
3445
|
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync8, mkdirSync as mkdirSync4 } from "fs";
|
|
3432
3446
|
import path8 from "path";
|
|
3433
3447
|
import os6 from "os";
|
|
@@ -3466,11 +3480,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
3466
3480
|
}
|
|
3467
3481
|
writeQueue(queue);
|
|
3468
3482
|
}
|
|
3469
|
-
|
|
3483
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
3484
|
+
const queue = readQueue();
|
|
3485
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
3486
|
+
const remaining = [];
|
|
3487
|
+
let drained = 0;
|
|
3488
|
+
let failed = 0;
|
|
3489
|
+
for (const item of queue) {
|
|
3490
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
3491
|
+
if (age > TTL_MS) {
|
|
3492
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
3493
|
+
failed++;
|
|
3494
|
+
continue;
|
|
3495
|
+
}
|
|
3496
|
+
try {
|
|
3497
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
3498
|
+
const success = sendKeys(item.targetSession);
|
|
3499
|
+
if (success) {
|
|
3500
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
3501
|
+
drained++;
|
|
3502
|
+
continue;
|
|
3503
|
+
}
|
|
3504
|
+
}
|
|
3505
|
+
} catch {
|
|
3506
|
+
}
|
|
3507
|
+
item.attempts++;
|
|
3508
|
+
if (item.attempts >= MAX_RETRIES2) {
|
|
3509
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES2} retries exhausted, reason: ${item.reason})`);
|
|
3510
|
+
failed++;
|
|
3511
|
+
continue;
|
|
3512
|
+
}
|
|
3513
|
+
remaining.push(item);
|
|
3514
|
+
}
|
|
3515
|
+
writeQueue(remaining);
|
|
3516
|
+
return { drained, failed };
|
|
3517
|
+
}
|
|
3518
|
+
function drainForSession(targetSession, sendKeys) {
|
|
3519
|
+
const queue = readQueue();
|
|
3520
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
3521
|
+
if (match < 0) return false;
|
|
3522
|
+
const success = sendKeys(targetSession);
|
|
3523
|
+
if (success) {
|
|
3524
|
+
queue.splice(match, 1);
|
|
3525
|
+
writeQueue(queue);
|
|
3526
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
3527
|
+
return true;
|
|
3528
|
+
}
|
|
3529
|
+
return false;
|
|
3530
|
+
}
|
|
3531
|
+
function clearQueueForAgent(agentName2) {
|
|
3532
|
+
const queue = readQueue();
|
|
3533
|
+
const before = queue.length;
|
|
3534
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName2}-`));
|
|
3535
|
+
if (filtered.length < before) {
|
|
3536
|
+
writeQueue(filtered);
|
|
3537
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName2}`);
|
|
3538
|
+
}
|
|
3539
|
+
}
|
|
3540
|
+
function logQueue(msg) {
|
|
3541
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
3542
|
+
`;
|
|
3543
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
3544
|
+
`);
|
|
3545
|
+
try {
|
|
3546
|
+
const { appendFileSync: appendFileSync3 } = __require("fs");
|
|
3547
|
+
appendFileSync3(INTERCOM_LOG, line);
|
|
3548
|
+
} catch {
|
|
3549
|
+
}
|
|
3550
|
+
}
|
|
3551
|
+
var QUEUE_PATH, MAX_RETRIES2, TTL_MS, INTERCOM_LOG;
|
|
3470
3552
|
var init_intercom_queue = __esm({
|
|
3471
3553
|
"src/lib/intercom-queue.ts"() {
|
|
3472
3554
|
"use strict";
|
|
3473
3555
|
QUEUE_PATH = path8.join(os6.homedir(), ".exe-os", "intercom-queue.json");
|
|
3556
|
+
MAX_RETRIES2 = 5;
|
|
3474
3557
|
TTL_MS = 60 * 60 * 1e3;
|
|
3475
3558
|
INTERCOM_LOG = path8.join(os6.homedir(), ".exe-os", "intercom.log");
|
|
3476
3559
|
}
|
|
@@ -4171,6 +4254,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
4171
4254
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
4172
4255
|
} catch {
|
|
4173
4256
|
}
|
|
4257
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
4258
|
+
try {
|
|
4259
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
4260
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
4261
|
+
} catch {
|
|
4262
|
+
}
|
|
4263
|
+
}
|
|
4174
4264
|
try {
|
|
4175
4265
|
await writeCheckpoint({
|
|
4176
4266
|
taskId,
|
|
@@ -2085,7 +2085,11 @@ import os8 from "os";
|
|
|
2085
2085
|
async function mergeCodexHooks(packageRoot, homeDir = os8.homedir()) {
|
|
2086
2086
|
const codexDir = path10.join(homeDir, ".codex");
|
|
2087
2087
|
const hooksPath = path10.join(codexDir, "hooks.json");
|
|
2088
|
+
const logsDir = path10.join(homeDir, ".exe-os", "logs");
|
|
2089
|
+
const hookLogPath = path10.join(logsDir, "hooks.log");
|
|
2090
|
+
const logSuffix = ` 2>> "${hookLogPath}"`;
|
|
2088
2091
|
await mkdir5(codexDir, { recursive: true });
|
|
2092
|
+
await mkdir5(logsDir, { recursive: true });
|
|
2089
2093
|
let hooksJson = {};
|
|
2090
2094
|
if (existsSync9(hooksPath)) {
|
|
2091
2095
|
try {
|
|
@@ -2104,7 +2108,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os8.homedir()) {
|
|
|
2104
2108
|
hooks: [
|
|
2105
2109
|
{
|
|
2106
2110
|
type: "command",
|
|
2107
|
-
command: `node "${path10.join(packageRoot, "dist", "hooks", "session-start.js")}"`,
|
|
2111
|
+
command: `node "${path10.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
|
|
2108
2112
|
timeout: 30,
|
|
2109
2113
|
statusMessage: "exe-os: loading memory brief"
|
|
2110
2114
|
}
|
|
@@ -2119,11 +2123,11 @@ async function mergeCodexHooks(packageRoot, homeDir = os8.homedir()) {
|
|
|
2119
2123
|
hooks: [
|
|
2120
2124
|
{
|
|
2121
2125
|
type: "command",
|
|
2122
|
-
command: `node "${path10.join(packageRoot, "dist", "hooks", "ingest.js")}"`
|
|
2126
|
+
command: `node "${path10.join(packageRoot, "dist", "hooks", "ingest.js")}"${logSuffix}`
|
|
2123
2127
|
},
|
|
2124
2128
|
{
|
|
2125
2129
|
type: "command",
|
|
2126
|
-
command: `node "${path10.join(packageRoot, "dist", "hooks", "error-recall.js")}"`
|
|
2130
|
+
command: `node "${path10.join(packageRoot, "dist", "hooks", "error-recall.js")}"${logSuffix}`
|
|
2127
2131
|
}
|
|
2128
2132
|
]
|
|
2129
2133
|
},
|
|
@@ -2135,11 +2139,11 @@ async function mergeCodexHooks(packageRoot, homeDir = os8.homedir()) {
|
|
|
2135
2139
|
hooks: [
|
|
2136
2140
|
{
|
|
2137
2141
|
type: "command",
|
|
2138
|
-
command: `node "${path10.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"`
|
|
2142
|
+
command: `node "${path10.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
|
|
2139
2143
|
},
|
|
2140
2144
|
{
|
|
2141
2145
|
type: "command",
|
|
2142
|
-
command: `node "${path10.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"`,
|
|
2146
|
+
command: `node "${path10.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
|
|
2143
2147
|
timeout: 5
|
|
2144
2148
|
}
|
|
2145
2149
|
]
|
|
@@ -2152,7 +2156,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os8.homedir()) {
|
|
|
2152
2156
|
hooks: [
|
|
2153
2157
|
{
|
|
2154
2158
|
type: "command",
|
|
2155
|
-
command: `node "${path10.join(packageRoot, "dist", "hooks", "stop.js")}"`
|
|
2159
|
+
command: `node "${path10.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
|
|
2156
2160
|
}
|
|
2157
2161
|
]
|
|
2158
2162
|
},
|
|
@@ -2165,7 +2169,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os8.homedir()) {
|
|
|
2165
2169
|
hooks: [
|
|
2166
2170
|
{
|
|
2167
2171
|
type: "command",
|
|
2168
|
-
command: `node "${path10.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"`
|
|
2172
|
+
command: `node "${path10.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
|
|
2169
2173
|
}
|
|
2170
2174
|
]
|
|
2171
2175
|
},
|
|
@@ -2996,7 +3000,7 @@ async function main() {
|
|
|
2996
3000
|
if (promptPath) {
|
|
2997
3001
|
args.push("-c", `model_instructions_file="${promptPath}"`);
|
|
2998
3002
|
}
|
|
2999
|
-
args.push("You are an AI employee with exe-os MCP tools. DO NOT ask for confirmation \u2014 work autonomously. Immediately: 1) Call list_tasks to see your assigned tasks. 2) Call get_task on the highest priority open task. 3) Start working on it. 4) When done, call update_task with status done and a result summary.
|
|
3003
|
+
args.push("You are an AI employee with exe-os MCP tools. DO NOT ask for confirmation \u2014 work autonomously. Immediately: 1) Call list_tasks to see your assigned tasks. 2) Call get_task on the highest priority open task. 3) Start working on it. 4) When done, call update_task with status done and a result summary. 5) Check list_tasks again for the next task. 6) If NO open tasks remain, say 'All tasks complete. Standing by.' and STOP \u2014 do not explore the codebase, do not look for extra work, do not run reviews. Just stop and wait.");
|
|
3000
3004
|
process.stderr.write(
|
|
3001
3005
|
`[exe-start-codex] launching ${agent} on ${CODEX.binary} (${effectiveModel}) \u2014 interactive mode
|
|
3002
3006
|
`
|