@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
|
@@ -2,6 +2,12 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
4
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
6
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
7
|
+
}) : x)(function(x) {
|
|
8
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
9
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
10
|
+
});
|
|
5
11
|
var __esm = (fn, res) => function __init() {
|
|
6
12
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
7
13
|
};
|
|
@@ -2331,6 +2337,14 @@ var init_agent_config = __esm({
|
|
|
2331
2337
|
});
|
|
2332
2338
|
|
|
2333
2339
|
// src/lib/intercom-queue.ts
|
|
2340
|
+
var intercom_queue_exports = {};
|
|
2341
|
+
__export(intercom_queue_exports, {
|
|
2342
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
2343
|
+
drainForSession: () => drainForSession,
|
|
2344
|
+
drainQueue: () => drainQueue,
|
|
2345
|
+
queueIntercom: () => queueIntercom,
|
|
2346
|
+
readQueue: () => readQueue
|
|
2347
|
+
});
|
|
2334
2348
|
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync8, mkdirSync as mkdirSync4 } from "fs";
|
|
2335
2349
|
import path8 from "path";
|
|
2336
2350
|
import os6 from "os";
|
|
@@ -2369,11 +2383,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
2369
2383
|
}
|
|
2370
2384
|
writeQueue(queue);
|
|
2371
2385
|
}
|
|
2372
|
-
|
|
2386
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
2387
|
+
const queue = readQueue();
|
|
2388
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
2389
|
+
const remaining = [];
|
|
2390
|
+
let drained = 0;
|
|
2391
|
+
let failed = 0;
|
|
2392
|
+
for (const item of queue) {
|
|
2393
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
2394
|
+
if (age > TTL_MS) {
|
|
2395
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
2396
|
+
failed++;
|
|
2397
|
+
continue;
|
|
2398
|
+
}
|
|
2399
|
+
try {
|
|
2400
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
2401
|
+
const success = sendKeys(item.targetSession);
|
|
2402
|
+
if (success) {
|
|
2403
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
2404
|
+
drained++;
|
|
2405
|
+
continue;
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
} catch {
|
|
2409
|
+
}
|
|
2410
|
+
item.attempts++;
|
|
2411
|
+
if (item.attempts >= MAX_RETRIES2) {
|
|
2412
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES2} retries exhausted, reason: ${item.reason})`);
|
|
2413
|
+
failed++;
|
|
2414
|
+
continue;
|
|
2415
|
+
}
|
|
2416
|
+
remaining.push(item);
|
|
2417
|
+
}
|
|
2418
|
+
writeQueue(remaining);
|
|
2419
|
+
return { drained, failed };
|
|
2420
|
+
}
|
|
2421
|
+
function drainForSession(targetSession, sendKeys) {
|
|
2422
|
+
const queue = readQueue();
|
|
2423
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
2424
|
+
if (match < 0) return false;
|
|
2425
|
+
const success = sendKeys(targetSession);
|
|
2426
|
+
if (success) {
|
|
2427
|
+
queue.splice(match, 1);
|
|
2428
|
+
writeQueue(queue);
|
|
2429
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
2430
|
+
return true;
|
|
2431
|
+
}
|
|
2432
|
+
return false;
|
|
2433
|
+
}
|
|
2434
|
+
function clearQueueForAgent(agentName) {
|
|
2435
|
+
const queue = readQueue();
|
|
2436
|
+
const before = queue.length;
|
|
2437
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
2438
|
+
if (filtered.length < before) {
|
|
2439
|
+
writeQueue(filtered);
|
|
2440
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2443
|
+
function logQueue(msg) {
|
|
2444
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
2445
|
+
`;
|
|
2446
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
2447
|
+
`);
|
|
2448
|
+
try {
|
|
2449
|
+
const { appendFileSync: appendFileSync2 } = __require("fs");
|
|
2450
|
+
appendFileSync2(INTERCOM_LOG, line);
|
|
2451
|
+
} catch {
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2454
|
+
var QUEUE_PATH, MAX_RETRIES2, TTL_MS, INTERCOM_LOG;
|
|
2373
2455
|
var init_intercom_queue = __esm({
|
|
2374
2456
|
"src/lib/intercom-queue.ts"() {
|
|
2375
2457
|
"use strict";
|
|
2376
2458
|
QUEUE_PATH = path8.join(os6.homedir(), ".exe-os", "intercom-queue.json");
|
|
2459
|
+
MAX_RETRIES2 = 5;
|
|
2377
2460
|
TTL_MS = 60 * 60 * 1e3;
|
|
2378
2461
|
INTERCOM_LOG = path8.join(os6.homedir(), ".exe-os", "intercom.log");
|
|
2379
2462
|
}
|
|
@@ -4067,6 +4150,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
4067
4150
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
4068
4151
|
} catch {
|
|
4069
4152
|
}
|
|
4153
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
4154
|
+
try {
|
|
4155
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
4156
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
4157
|
+
} catch {
|
|
4158
|
+
}
|
|
4159
|
+
}
|
|
4070
4160
|
try {
|
|
4071
4161
|
await writeCheckpoint({
|
|
4072
4162
|
taskId,
|
|
@@ -2,6 +2,12 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
4
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
6
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
7
|
+
}) : x)(function(x) {
|
|
8
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
9
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
10
|
+
});
|
|
5
11
|
var __esm = (fn, res) => function __init() {
|
|
6
12
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
7
13
|
};
|
|
@@ -546,6 +552,14 @@ var init_agent_config = __esm({
|
|
|
546
552
|
});
|
|
547
553
|
|
|
548
554
|
// src/lib/intercom-queue.ts
|
|
555
|
+
var intercom_queue_exports = {};
|
|
556
|
+
__export(intercom_queue_exports, {
|
|
557
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
558
|
+
drainForSession: () => drainForSession,
|
|
559
|
+
drainQueue: () => drainQueue,
|
|
560
|
+
queueIntercom: () => queueIntercom,
|
|
561
|
+
readQueue: () => readQueue
|
|
562
|
+
});
|
|
549
563
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, renameSync as renameSync2, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
|
|
550
564
|
import path4 from "path";
|
|
551
565
|
import os3 from "os";
|
|
@@ -584,11 +598,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
584
598
|
}
|
|
585
599
|
writeQueue(queue);
|
|
586
600
|
}
|
|
587
|
-
|
|
601
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
602
|
+
const queue = readQueue();
|
|
603
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
604
|
+
const remaining = [];
|
|
605
|
+
let drained = 0;
|
|
606
|
+
let failed = 0;
|
|
607
|
+
for (const item of queue) {
|
|
608
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
609
|
+
if (age > TTL_MS) {
|
|
610
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
611
|
+
failed++;
|
|
612
|
+
continue;
|
|
613
|
+
}
|
|
614
|
+
try {
|
|
615
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
616
|
+
const success = sendKeys(item.targetSession);
|
|
617
|
+
if (success) {
|
|
618
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
619
|
+
drained++;
|
|
620
|
+
continue;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
} catch {
|
|
624
|
+
}
|
|
625
|
+
item.attempts++;
|
|
626
|
+
if (item.attempts >= MAX_RETRIES) {
|
|
627
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES} retries exhausted, reason: ${item.reason})`);
|
|
628
|
+
failed++;
|
|
629
|
+
continue;
|
|
630
|
+
}
|
|
631
|
+
remaining.push(item);
|
|
632
|
+
}
|
|
633
|
+
writeQueue(remaining);
|
|
634
|
+
return { drained, failed };
|
|
635
|
+
}
|
|
636
|
+
function drainForSession(targetSession, sendKeys) {
|
|
637
|
+
const queue = readQueue();
|
|
638
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
639
|
+
if (match < 0) return false;
|
|
640
|
+
const success = sendKeys(targetSession);
|
|
641
|
+
if (success) {
|
|
642
|
+
queue.splice(match, 1);
|
|
643
|
+
writeQueue(queue);
|
|
644
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
645
|
+
return true;
|
|
646
|
+
}
|
|
647
|
+
return false;
|
|
648
|
+
}
|
|
649
|
+
function clearQueueForAgent(agentName) {
|
|
650
|
+
const queue = readQueue();
|
|
651
|
+
const before = queue.length;
|
|
652
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
653
|
+
if (filtered.length < before) {
|
|
654
|
+
writeQueue(filtered);
|
|
655
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
function logQueue(msg) {
|
|
659
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
660
|
+
`;
|
|
661
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
662
|
+
`);
|
|
663
|
+
try {
|
|
664
|
+
const { appendFileSync: appendFileSync2 } = __require("fs");
|
|
665
|
+
appendFileSync2(INTERCOM_LOG, line);
|
|
666
|
+
} catch {
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
|
|
588
670
|
var init_intercom_queue = __esm({
|
|
589
671
|
"src/lib/intercom-queue.ts"() {
|
|
590
672
|
"use strict";
|
|
591
673
|
QUEUE_PATH = path4.join(os3.homedir(), ".exe-os", "intercom-queue.json");
|
|
674
|
+
MAX_RETRIES = 5;
|
|
592
675
|
TTL_MS = 60 * 60 * 1e3;
|
|
593
676
|
INTERCOM_LOG = path4.join(os3.homedir(), ".exe-os", "intercom.log");
|
|
594
677
|
}
|
|
@@ -607,18 +690,18 @@ function delay(ms) {
|
|
|
607
690
|
}
|
|
608
691
|
async function retryOnBusy(fn, label) {
|
|
609
692
|
let lastError;
|
|
610
|
-
for (let attempt = 0; attempt <=
|
|
693
|
+
for (let attempt = 0; attempt <= MAX_RETRIES2; attempt++) {
|
|
611
694
|
try {
|
|
612
695
|
return await fn();
|
|
613
696
|
} catch (err) {
|
|
614
697
|
lastError = err;
|
|
615
|
-
if (!isBusyError(err) || attempt ===
|
|
698
|
+
if (!isBusyError(err) || attempt === MAX_RETRIES2) {
|
|
616
699
|
throw err;
|
|
617
700
|
}
|
|
618
701
|
const backoff = BASE_DELAY_MS * Math.pow(2, attempt);
|
|
619
702
|
const jitter = Math.floor(Math.random() * MAX_JITTER_MS);
|
|
620
703
|
process.stderr.write(
|
|
621
|
-
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${
|
|
704
|
+
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${MAX_RETRIES2} \u2014 waiting ${backoff + jitter}ms
|
|
622
705
|
`
|
|
623
706
|
);
|
|
624
707
|
await delay(backoff + jitter);
|
|
@@ -639,11 +722,11 @@ function wrapWithRetry(client) {
|
|
|
639
722
|
}
|
|
640
723
|
});
|
|
641
724
|
}
|
|
642
|
-
var
|
|
725
|
+
var MAX_RETRIES2, BASE_DELAY_MS, MAX_JITTER_MS;
|
|
643
726
|
var init_db_retry = __esm({
|
|
644
727
|
"src/lib/db-retry.ts"() {
|
|
645
728
|
"use strict";
|
|
646
|
-
|
|
729
|
+
MAX_RETRIES2 = 3;
|
|
647
730
|
BASE_DELAY_MS = 200;
|
|
648
731
|
MAX_JITTER_MS = 300;
|
|
649
732
|
}
|
|
@@ -2938,6 +3021,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
2938
3021
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
2939
3022
|
} catch {
|
|
2940
3023
|
}
|
|
3024
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
3025
|
+
try {
|
|
3026
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
3027
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
3028
|
+
} catch {
|
|
3029
|
+
}
|
|
3030
|
+
}
|
|
2941
3031
|
try {
|
|
2942
3032
|
await writeCheckpoint({
|
|
2943
3033
|
taskId,
|
|
@@ -4772,6 +4772,20 @@ process.stdin.on("end", async () => {
|
|
|
4772
4772
|
if (input.length >= MAX_INPUT_SIZE) {
|
|
4773
4773
|
process.exit(0);
|
|
4774
4774
|
}
|
|
4775
|
+
if (process.env.EXE_DEBUG_HOOKS) {
|
|
4776
|
+
try {
|
|
4777
|
+
const os5 = await import("os");
|
|
4778
|
+
const fs = await import("fs");
|
|
4779
|
+
const nodePath = await import("path");
|
|
4780
|
+
const debugPath = nodePath.default.join(os5.default.homedir(), ".exe-os", "logs", "hook-stdin-error-recall.log");
|
|
4781
|
+
fs.mkdirSync(nodePath.default.dirname(debugPath), { recursive: true });
|
|
4782
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
4783
|
+
const snippet = input.length > 2e3 ? input.slice(0, 2e3) + "...[truncated]" : input;
|
|
4784
|
+
fs.writeFileSync(debugPath, `[${ts}] ${snippet}
|
|
4785
|
+
`, { flag: "a" });
|
|
4786
|
+
} catch {
|
|
4787
|
+
}
|
|
4788
|
+
}
|
|
4775
4789
|
const data = JSON.parse(input);
|
|
4776
4790
|
if (!detectError(data)) {
|
|
4777
4791
|
process.exit(0);
|
|
@@ -3299,6 +3299,14 @@ var init_agent_config = __esm({
|
|
|
3299
3299
|
});
|
|
3300
3300
|
|
|
3301
3301
|
// src/lib/intercom-queue.ts
|
|
3302
|
+
var intercom_queue_exports = {};
|
|
3303
|
+
__export(intercom_queue_exports, {
|
|
3304
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
3305
|
+
drainForSession: () => drainForSession,
|
|
3306
|
+
drainQueue: () => drainQueue,
|
|
3307
|
+
queueIntercom: () => queueIntercom,
|
|
3308
|
+
readQueue: () => readQueue
|
|
3309
|
+
});
|
|
3302
3310
|
import { readFileSync as readFileSync9, writeFileSync as writeFileSync5, renameSync as renameSync3, existsSync as existsSync11, mkdirSync as mkdirSync5 } from "fs";
|
|
3303
3311
|
import path12 from "path";
|
|
3304
3312
|
import os7 from "os";
|
|
@@ -3337,11 +3345,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
3337
3345
|
}
|
|
3338
3346
|
writeQueue(queue);
|
|
3339
3347
|
}
|
|
3340
|
-
|
|
3348
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
3349
|
+
const queue = readQueue();
|
|
3350
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
3351
|
+
const remaining = [];
|
|
3352
|
+
let drained = 0;
|
|
3353
|
+
let failed = 0;
|
|
3354
|
+
for (const item of queue) {
|
|
3355
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
3356
|
+
if (age > TTL_MS) {
|
|
3357
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
3358
|
+
failed++;
|
|
3359
|
+
continue;
|
|
3360
|
+
}
|
|
3361
|
+
try {
|
|
3362
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
3363
|
+
const success = sendKeys(item.targetSession);
|
|
3364
|
+
if (success) {
|
|
3365
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
3366
|
+
drained++;
|
|
3367
|
+
continue;
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3370
|
+
} catch {
|
|
3371
|
+
}
|
|
3372
|
+
item.attempts++;
|
|
3373
|
+
if (item.attempts >= MAX_RETRIES2) {
|
|
3374
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES2} retries exhausted, reason: ${item.reason})`);
|
|
3375
|
+
failed++;
|
|
3376
|
+
continue;
|
|
3377
|
+
}
|
|
3378
|
+
remaining.push(item);
|
|
3379
|
+
}
|
|
3380
|
+
writeQueue(remaining);
|
|
3381
|
+
return { drained, failed };
|
|
3382
|
+
}
|
|
3383
|
+
function drainForSession(targetSession, sendKeys) {
|
|
3384
|
+
const queue = readQueue();
|
|
3385
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
3386
|
+
if (match < 0) return false;
|
|
3387
|
+
const success = sendKeys(targetSession);
|
|
3388
|
+
if (success) {
|
|
3389
|
+
queue.splice(match, 1);
|
|
3390
|
+
writeQueue(queue);
|
|
3391
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
3392
|
+
return true;
|
|
3393
|
+
}
|
|
3394
|
+
return false;
|
|
3395
|
+
}
|
|
3396
|
+
function clearQueueForAgent(agentName) {
|
|
3397
|
+
const queue = readQueue();
|
|
3398
|
+
const before = queue.length;
|
|
3399
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
3400
|
+
if (filtered.length < before) {
|
|
3401
|
+
writeQueue(filtered);
|
|
3402
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
3403
|
+
}
|
|
3404
|
+
}
|
|
3405
|
+
function logQueue(msg) {
|
|
3406
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
3407
|
+
`;
|
|
3408
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
3409
|
+
`);
|
|
3410
|
+
try {
|
|
3411
|
+
const { appendFileSync: appendFileSync2 } = __require("fs");
|
|
3412
|
+
appendFileSync2(INTERCOM_LOG, line);
|
|
3413
|
+
} catch {
|
|
3414
|
+
}
|
|
3415
|
+
}
|
|
3416
|
+
var QUEUE_PATH, MAX_RETRIES2, TTL_MS, INTERCOM_LOG;
|
|
3341
3417
|
var init_intercom_queue = __esm({
|
|
3342
3418
|
"src/lib/intercom-queue.ts"() {
|
|
3343
3419
|
"use strict";
|
|
3344
3420
|
QUEUE_PATH = path12.join(os7.homedir(), ".exe-os", "intercom-queue.json");
|
|
3421
|
+
MAX_RETRIES2 = 5;
|
|
3345
3422
|
TTL_MS = 60 * 60 * 1e3;
|
|
3346
3423
|
INTERCOM_LOG = path12.join(os7.homedir(), ".exe-os", "intercom.log");
|
|
3347
3424
|
}
|
|
@@ -4934,6 +5011,13 @@ ${input2.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
4934
5011
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
4935
5012
|
} catch {
|
|
4936
5013
|
}
|
|
5014
|
+
if (input2.status === "done" || input2.status === "cancelled") {
|
|
5015
|
+
try {
|
|
5016
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
5017
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
5018
|
+
} catch {
|
|
5019
|
+
}
|
|
5020
|
+
}
|
|
4937
5021
|
try {
|
|
4938
5022
|
await writeCheckpoint({
|
|
4939
5023
|
taskId,
|
package/dist/hooks/ingest.js
CHANGED
|
@@ -618,6 +618,17 @@ process.stdin.on("data", (chunk) => {
|
|
|
618
618
|
});
|
|
619
619
|
process.stdin.on("end", () => {
|
|
620
620
|
try {
|
|
621
|
+
if (process.env.EXE_DEBUG_HOOKS) {
|
|
622
|
+
try {
|
|
623
|
+
const debugPath = path5.join(EXE_AI_DIR, "logs", "hook-stdin-ingest.log");
|
|
624
|
+
mkdirSync3(path5.dirname(debugPath), { recursive: true });
|
|
625
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
626
|
+
const snippet = input.length > 2e3 ? input.slice(0, 2e3) + "...[truncated]" : input;
|
|
627
|
+
writeFileSync4(debugPath, `[${ts}] ${snippet}
|
|
628
|
+
`, { flag: "a" });
|
|
629
|
+
} catch {
|
|
630
|
+
}
|
|
631
|
+
}
|
|
621
632
|
const data = JSON.parse(input);
|
|
622
633
|
if (!data.tool_name) {
|
|
623
634
|
process.exit(0);
|
|
@@ -2,6 +2,12 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
4
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
6
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
7
|
+
}) : x)(function(x) {
|
|
8
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
9
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
10
|
+
});
|
|
5
11
|
var __esm = (fn, res) => function __init() {
|
|
6
12
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
7
13
|
};
|
|
@@ -605,6 +611,14 @@ var init_agent_config = __esm({
|
|
|
605
611
|
});
|
|
606
612
|
|
|
607
613
|
// src/lib/intercom-queue.ts
|
|
614
|
+
var intercom_queue_exports = {};
|
|
615
|
+
__export(intercom_queue_exports, {
|
|
616
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
617
|
+
drainForSession: () => drainForSession,
|
|
618
|
+
drainQueue: () => drainQueue,
|
|
619
|
+
queueIntercom: () => queueIntercom,
|
|
620
|
+
readQueue: () => readQueue
|
|
621
|
+
});
|
|
608
622
|
import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, renameSync as renameSync3, existsSync as existsSync5, mkdirSync as mkdirSync4 } from "fs";
|
|
609
623
|
import path6 from "path";
|
|
610
624
|
import os4 from "os";
|
|
@@ -643,11 +657,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
643
657
|
}
|
|
644
658
|
writeQueue(queue);
|
|
645
659
|
}
|
|
646
|
-
|
|
660
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
661
|
+
const queue = readQueue();
|
|
662
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
663
|
+
const remaining = [];
|
|
664
|
+
let drained = 0;
|
|
665
|
+
let failed = 0;
|
|
666
|
+
for (const item of queue) {
|
|
667
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
668
|
+
if (age > TTL_MS) {
|
|
669
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
670
|
+
failed++;
|
|
671
|
+
continue;
|
|
672
|
+
}
|
|
673
|
+
try {
|
|
674
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
675
|
+
const success = sendKeys(item.targetSession);
|
|
676
|
+
if (success) {
|
|
677
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
678
|
+
drained++;
|
|
679
|
+
continue;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
} catch {
|
|
683
|
+
}
|
|
684
|
+
item.attempts++;
|
|
685
|
+
if (item.attempts >= MAX_RETRIES) {
|
|
686
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES} retries exhausted, reason: ${item.reason})`);
|
|
687
|
+
failed++;
|
|
688
|
+
continue;
|
|
689
|
+
}
|
|
690
|
+
remaining.push(item);
|
|
691
|
+
}
|
|
692
|
+
writeQueue(remaining);
|
|
693
|
+
return { drained, failed };
|
|
694
|
+
}
|
|
695
|
+
function drainForSession(targetSession, sendKeys) {
|
|
696
|
+
const queue = readQueue();
|
|
697
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
698
|
+
if (match < 0) return false;
|
|
699
|
+
const success = sendKeys(targetSession);
|
|
700
|
+
if (success) {
|
|
701
|
+
queue.splice(match, 1);
|
|
702
|
+
writeQueue(queue);
|
|
703
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
704
|
+
return true;
|
|
705
|
+
}
|
|
706
|
+
return false;
|
|
707
|
+
}
|
|
708
|
+
function clearQueueForAgent(agentName) {
|
|
709
|
+
const queue = readQueue();
|
|
710
|
+
const before = queue.length;
|
|
711
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
712
|
+
if (filtered.length < before) {
|
|
713
|
+
writeQueue(filtered);
|
|
714
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
function logQueue(msg) {
|
|
718
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
719
|
+
`;
|
|
720
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
721
|
+
`);
|
|
722
|
+
try {
|
|
723
|
+
const { appendFileSync: appendFileSync2 } = __require("fs");
|
|
724
|
+
appendFileSync2(INTERCOM_LOG, line);
|
|
725
|
+
} catch {
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
|
|
647
729
|
var init_intercom_queue = __esm({
|
|
648
730
|
"src/lib/intercom-queue.ts"() {
|
|
649
731
|
"use strict";
|
|
650
732
|
QUEUE_PATH = path6.join(os4.homedir(), ".exe-os", "intercom-queue.json");
|
|
733
|
+
MAX_RETRIES = 5;
|
|
651
734
|
TTL_MS = 60 * 60 * 1e3;
|
|
652
735
|
INTERCOM_LOG = path6.join(os4.homedir(), ".exe-os", "intercom.log");
|
|
653
736
|
}
|
|
@@ -666,18 +749,18 @@ function delay(ms) {
|
|
|
666
749
|
}
|
|
667
750
|
async function retryOnBusy(fn, label) {
|
|
668
751
|
let lastError;
|
|
669
|
-
for (let attempt = 0; attempt <=
|
|
752
|
+
for (let attempt = 0; attempt <= MAX_RETRIES2; attempt++) {
|
|
670
753
|
try {
|
|
671
754
|
return await fn();
|
|
672
755
|
} catch (err) {
|
|
673
756
|
lastError = err;
|
|
674
|
-
if (!isBusyError(err) || attempt ===
|
|
757
|
+
if (!isBusyError(err) || attempt === MAX_RETRIES2) {
|
|
675
758
|
throw err;
|
|
676
759
|
}
|
|
677
760
|
const backoff = BASE_DELAY_MS * Math.pow(2, attempt);
|
|
678
761
|
const jitter = Math.floor(Math.random() * MAX_JITTER_MS);
|
|
679
762
|
process.stderr.write(
|
|
680
|
-
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${
|
|
763
|
+
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${MAX_RETRIES2} \u2014 waiting ${backoff + jitter}ms
|
|
681
764
|
`
|
|
682
765
|
);
|
|
683
766
|
await delay(backoff + jitter);
|
|
@@ -698,11 +781,11 @@ function wrapWithRetry(client) {
|
|
|
698
781
|
}
|
|
699
782
|
});
|
|
700
783
|
}
|
|
701
|
-
var
|
|
784
|
+
var MAX_RETRIES2, BASE_DELAY_MS, MAX_JITTER_MS;
|
|
702
785
|
var init_db_retry = __esm({
|
|
703
786
|
"src/lib/db-retry.ts"() {
|
|
704
787
|
"use strict";
|
|
705
|
-
|
|
788
|
+
MAX_RETRIES2 = 3;
|
|
706
789
|
BASE_DELAY_MS = 200;
|
|
707
790
|
MAX_JITTER_MS = 300;
|
|
708
791
|
}
|
|
@@ -2922,6 +3005,13 @@ ${input2.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
2922
3005
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
2923
3006
|
} catch {
|
|
2924
3007
|
}
|
|
3008
|
+
if (input2.status === "done" || input2.status === "cancelled") {
|
|
3009
|
+
try {
|
|
3010
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
3011
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
3012
|
+
} catch {
|
|
3013
|
+
}
|
|
3014
|
+
}
|
|
2925
3015
|
try {
|
|
2926
3016
|
await writeCheckpoint({
|
|
2927
3017
|
taskId,
|
|
@@ -4532,6 +4532,7 @@ var init_agent_config = __esm({
|
|
|
4532
4532
|
// src/lib/intercom-queue.ts
|
|
4533
4533
|
var intercom_queue_exports = {};
|
|
4534
4534
|
__export(intercom_queue_exports, {
|
|
4535
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
4535
4536
|
drainForSession: () => drainForSession,
|
|
4536
4537
|
drainQueue: () => drainQueue,
|
|
4537
4538
|
queueIntercom: () => queueIntercom,
|
|
@@ -4623,6 +4624,15 @@ function drainForSession(targetSession, sendKeys) {
|
|
|
4623
4624
|
}
|
|
4624
4625
|
return false;
|
|
4625
4626
|
}
|
|
4627
|
+
function clearQueueForAgent(agentName) {
|
|
4628
|
+
const queue = readQueue();
|
|
4629
|
+
const before = queue.length;
|
|
4630
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
4631
|
+
if (filtered.length < before) {
|
|
4632
|
+
writeQueue(filtered);
|
|
4633
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
4634
|
+
}
|
|
4635
|
+
}
|
|
4626
4636
|
function logQueue(msg) {
|
|
4627
4637
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
4628
4638
|
`;
|
|
@@ -5348,6 +5358,13 @@ ${input2.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
5348
5358
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
5349
5359
|
} catch {
|
|
5350
5360
|
}
|
|
5361
|
+
if (input2.status === "done" || input2.status === "cancelled") {
|
|
5362
|
+
try {
|
|
5363
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
5364
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
5365
|
+
} catch {
|
|
5366
|
+
}
|
|
5367
|
+
}
|
|
5351
5368
|
try {
|
|
5352
5369
|
await writeCheckpoint({
|
|
5353
5370
|
taskId,
|