@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/git-sweep.js
CHANGED
|
@@ -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
|
};
|
|
@@ -547,6 +553,14 @@ var init_agent_config = __esm({
|
|
|
547
553
|
});
|
|
548
554
|
|
|
549
555
|
// src/lib/intercom-queue.ts
|
|
556
|
+
var intercom_queue_exports = {};
|
|
557
|
+
__export(intercom_queue_exports, {
|
|
558
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
559
|
+
drainForSession: () => drainForSession,
|
|
560
|
+
drainQueue: () => drainQueue,
|
|
561
|
+
queueIntercom: () => queueIntercom,
|
|
562
|
+
readQueue: () => readQueue
|
|
563
|
+
});
|
|
550
564
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, renameSync as renameSync2, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
|
|
551
565
|
import path4 from "path";
|
|
552
566
|
import os3 from "os";
|
|
@@ -585,11 +599,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
585
599
|
}
|
|
586
600
|
writeQueue(queue);
|
|
587
601
|
}
|
|
588
|
-
|
|
602
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
603
|
+
const queue = readQueue();
|
|
604
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
605
|
+
const remaining = [];
|
|
606
|
+
let drained = 0;
|
|
607
|
+
let failed = 0;
|
|
608
|
+
for (const item of queue) {
|
|
609
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
610
|
+
if (age > TTL_MS) {
|
|
611
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
612
|
+
failed++;
|
|
613
|
+
continue;
|
|
614
|
+
}
|
|
615
|
+
try {
|
|
616
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
617
|
+
const success = sendKeys(item.targetSession);
|
|
618
|
+
if (success) {
|
|
619
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
620
|
+
drained++;
|
|
621
|
+
continue;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
} catch {
|
|
625
|
+
}
|
|
626
|
+
item.attempts++;
|
|
627
|
+
if (item.attempts >= MAX_RETRIES) {
|
|
628
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES} retries exhausted, reason: ${item.reason})`);
|
|
629
|
+
failed++;
|
|
630
|
+
continue;
|
|
631
|
+
}
|
|
632
|
+
remaining.push(item);
|
|
633
|
+
}
|
|
634
|
+
writeQueue(remaining);
|
|
635
|
+
return { drained, failed };
|
|
636
|
+
}
|
|
637
|
+
function drainForSession(targetSession, sendKeys) {
|
|
638
|
+
const queue = readQueue();
|
|
639
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
640
|
+
if (match < 0) return false;
|
|
641
|
+
const success = sendKeys(targetSession);
|
|
642
|
+
if (success) {
|
|
643
|
+
queue.splice(match, 1);
|
|
644
|
+
writeQueue(queue);
|
|
645
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
646
|
+
return true;
|
|
647
|
+
}
|
|
648
|
+
return false;
|
|
649
|
+
}
|
|
650
|
+
function clearQueueForAgent(agentName) {
|
|
651
|
+
const queue = readQueue();
|
|
652
|
+
const before = queue.length;
|
|
653
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
654
|
+
if (filtered.length < before) {
|
|
655
|
+
writeQueue(filtered);
|
|
656
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
function logQueue(msg) {
|
|
660
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
661
|
+
`;
|
|
662
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
663
|
+
`);
|
|
664
|
+
try {
|
|
665
|
+
const { appendFileSync: appendFileSync2 } = __require("fs");
|
|
666
|
+
appendFileSync2(INTERCOM_LOG, line);
|
|
667
|
+
} catch {
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
|
|
589
671
|
var init_intercom_queue = __esm({
|
|
590
672
|
"src/lib/intercom-queue.ts"() {
|
|
591
673
|
"use strict";
|
|
592
674
|
QUEUE_PATH = path4.join(os3.homedir(), ".exe-os", "intercom-queue.json");
|
|
675
|
+
MAX_RETRIES = 5;
|
|
593
676
|
TTL_MS = 60 * 60 * 1e3;
|
|
594
677
|
INTERCOM_LOG = path4.join(os3.homedir(), ".exe-os", "intercom.log");
|
|
595
678
|
}
|
|
@@ -608,18 +691,18 @@ function delay(ms) {
|
|
|
608
691
|
}
|
|
609
692
|
async function retryOnBusy(fn, label) {
|
|
610
693
|
let lastError;
|
|
611
|
-
for (let attempt = 0; attempt <=
|
|
694
|
+
for (let attempt = 0; attempt <= MAX_RETRIES2; attempt++) {
|
|
612
695
|
try {
|
|
613
696
|
return await fn();
|
|
614
697
|
} catch (err) {
|
|
615
698
|
lastError = err;
|
|
616
|
-
if (!isBusyError(err) || attempt ===
|
|
699
|
+
if (!isBusyError(err) || attempt === MAX_RETRIES2) {
|
|
617
700
|
throw err;
|
|
618
701
|
}
|
|
619
702
|
const backoff = BASE_DELAY_MS * Math.pow(2, attempt);
|
|
620
703
|
const jitter = Math.floor(Math.random() * MAX_JITTER_MS);
|
|
621
704
|
process.stderr.write(
|
|
622
|
-
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${
|
|
705
|
+
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${MAX_RETRIES2} \u2014 waiting ${backoff + jitter}ms
|
|
623
706
|
`
|
|
624
707
|
);
|
|
625
708
|
await delay(backoff + jitter);
|
|
@@ -640,11 +723,11 @@ function wrapWithRetry(client) {
|
|
|
640
723
|
}
|
|
641
724
|
});
|
|
642
725
|
}
|
|
643
|
-
var
|
|
726
|
+
var MAX_RETRIES2, BASE_DELAY_MS, MAX_JITTER_MS;
|
|
644
727
|
var init_db_retry = __esm({
|
|
645
728
|
"src/lib/db-retry.ts"() {
|
|
646
729
|
"use strict";
|
|
647
|
-
|
|
730
|
+
MAX_RETRIES2 = 3;
|
|
648
731
|
BASE_DELAY_MS = 200;
|
|
649
732
|
MAX_JITTER_MS = 300;
|
|
650
733
|
}
|
|
@@ -2939,6 +3022,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
2939
3022
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
2940
3023
|
} catch {
|
|
2941
3024
|
}
|
|
3025
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
3026
|
+
try {
|
|
3027
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
3028
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
3029
|
+
} catch {
|
|
3030
|
+
}
|
|
3031
|
+
}
|
|
2942
3032
|
try {
|
|
2943
3033
|
await writeCheckpoint({
|
|
2944
3034
|
taskId,
|
package/dist/bin/install.js
CHANGED
|
@@ -537,6 +537,10 @@ async function cleanSettingsJsonMcp(settingsPath) {
|
|
|
537
537
|
}
|
|
538
538
|
async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
539
539
|
const settingsPath = path5.join(homeDir, ".claude", "settings.json");
|
|
540
|
+
const logsDir = path5.join(homeDir, ".exe-os", "logs");
|
|
541
|
+
const hookLogPath = path5.join(logsDir, "hooks.log");
|
|
542
|
+
const logSuffix = ` 2>> "${hookLogPath}"`;
|
|
543
|
+
await mkdir3(logsDir, { recursive: true });
|
|
540
544
|
let settings = {};
|
|
541
545
|
if (existsSync5(settingsPath)) {
|
|
542
546
|
try {
|
|
@@ -560,11 +564,11 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
560
564
|
hooks: [
|
|
561
565
|
{
|
|
562
566
|
type: "command",
|
|
563
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "ingest.js")}"`
|
|
567
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "ingest.js")}"${logSuffix}`
|
|
564
568
|
},
|
|
565
569
|
{
|
|
566
570
|
type: "command",
|
|
567
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "error-recall.js")}"`
|
|
571
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "error-recall.js")}"${logSuffix}`
|
|
568
572
|
}
|
|
569
573
|
]
|
|
570
574
|
},
|
|
@@ -576,7 +580,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
576
580
|
hooks: [
|
|
577
581
|
{
|
|
578
582
|
type: "command",
|
|
579
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "session-start.js")}"`,
|
|
583
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
|
|
580
584
|
timeout: 1e4
|
|
581
585
|
}
|
|
582
586
|
]
|
|
@@ -589,7 +593,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
589
593
|
hooks: [
|
|
590
594
|
{
|
|
591
595
|
type: "command",
|
|
592
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"`
|
|
596
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
|
|
593
597
|
}
|
|
594
598
|
]
|
|
595
599
|
},
|
|
@@ -601,7 +605,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
601
605
|
hooks: [
|
|
602
606
|
{
|
|
603
607
|
type: "command",
|
|
604
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"`,
|
|
608
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
|
|
605
609
|
timeout: 5e3
|
|
606
610
|
}
|
|
607
611
|
]
|
|
@@ -614,7 +618,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
614
618
|
hooks: [
|
|
615
619
|
{
|
|
616
620
|
type: "command",
|
|
617
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "stop.js")}"`
|
|
621
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
|
|
618
622
|
}
|
|
619
623
|
]
|
|
620
624
|
},
|
|
@@ -627,7 +631,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
627
631
|
hooks: [
|
|
628
632
|
{
|
|
629
633
|
type: "command",
|
|
630
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"`
|
|
634
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
|
|
631
635
|
}
|
|
632
636
|
]
|
|
633
637
|
},
|
|
@@ -639,7 +643,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
639
643
|
hooks: [
|
|
640
644
|
{
|
|
641
645
|
type: "command",
|
|
642
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"`
|
|
646
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"${logSuffix}`
|
|
643
647
|
}
|
|
644
648
|
]
|
|
645
649
|
},
|
|
@@ -651,7 +655,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
651
655
|
hooks: [
|
|
652
656
|
{
|
|
653
657
|
type: "command",
|
|
654
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "pre-compact.js")}"`,
|
|
658
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "pre-compact.js")}"${logSuffix}`,
|
|
655
659
|
timeout: 1e4
|
|
656
660
|
}
|
|
657
661
|
]
|
|
@@ -664,7 +668,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
664
668
|
hooks: [
|
|
665
669
|
{
|
|
666
670
|
type: "command",
|
|
667
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "session-end.js")}"`
|
|
671
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "session-end.js")}"${logSuffix}`
|
|
668
672
|
}
|
|
669
673
|
]
|
|
670
674
|
},
|
|
@@ -676,7 +680,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
676
680
|
hooks: [
|
|
677
681
|
{
|
|
678
682
|
type: "command",
|
|
679
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "notification.js")}"`
|
|
683
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "notification.js")}"${logSuffix}`
|
|
680
684
|
}
|
|
681
685
|
]
|
|
682
686
|
},
|
|
@@ -688,7 +692,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
688
692
|
hooks: [
|
|
689
693
|
{
|
|
690
694
|
type: "command",
|
|
691
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "post-compact.js")}"`,
|
|
695
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "post-compact.js")}"${logSuffix}`,
|
|
692
696
|
timeout: 1e4
|
|
693
697
|
}
|
|
694
698
|
]
|
|
@@ -701,7 +705,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
701
705
|
hooks: [
|
|
702
706
|
{
|
|
703
707
|
type: "command",
|
|
704
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"`
|
|
708
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"${logSuffix}`
|
|
705
709
|
}
|
|
706
710
|
]
|
|
707
711
|
},
|
package/dist/bin/scan-tasks.js
CHANGED
|
@@ -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
|
};
|
|
@@ -559,6 +565,14 @@ var init_agent_config = __esm({
|
|
|
559
565
|
});
|
|
560
566
|
|
|
561
567
|
// src/lib/intercom-queue.ts
|
|
568
|
+
var intercom_queue_exports = {};
|
|
569
|
+
__export(intercom_queue_exports, {
|
|
570
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
571
|
+
drainForSession: () => drainForSession,
|
|
572
|
+
drainQueue: () => drainQueue,
|
|
573
|
+
queueIntercom: () => queueIntercom,
|
|
574
|
+
readQueue: () => readQueue
|
|
575
|
+
});
|
|
562
576
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, renameSync as renameSync2, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
|
|
563
577
|
import path4 from "path";
|
|
564
578
|
import os3 from "os";
|
|
@@ -597,11 +611,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
597
611
|
}
|
|
598
612
|
writeQueue(queue);
|
|
599
613
|
}
|
|
600
|
-
|
|
614
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
615
|
+
const queue = readQueue();
|
|
616
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
617
|
+
const remaining = [];
|
|
618
|
+
let drained = 0;
|
|
619
|
+
let failed = 0;
|
|
620
|
+
for (const item of queue) {
|
|
621
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
622
|
+
if (age > TTL_MS) {
|
|
623
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
624
|
+
failed++;
|
|
625
|
+
continue;
|
|
626
|
+
}
|
|
627
|
+
try {
|
|
628
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
629
|
+
const success = sendKeys(item.targetSession);
|
|
630
|
+
if (success) {
|
|
631
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
632
|
+
drained++;
|
|
633
|
+
continue;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
} catch {
|
|
637
|
+
}
|
|
638
|
+
item.attempts++;
|
|
639
|
+
if (item.attempts >= MAX_RETRIES) {
|
|
640
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES} retries exhausted, reason: ${item.reason})`);
|
|
641
|
+
failed++;
|
|
642
|
+
continue;
|
|
643
|
+
}
|
|
644
|
+
remaining.push(item);
|
|
645
|
+
}
|
|
646
|
+
writeQueue(remaining);
|
|
647
|
+
return { drained, failed };
|
|
648
|
+
}
|
|
649
|
+
function drainForSession(targetSession, sendKeys) {
|
|
650
|
+
const queue = readQueue();
|
|
651
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
652
|
+
if (match < 0) return false;
|
|
653
|
+
const success = sendKeys(targetSession);
|
|
654
|
+
if (success) {
|
|
655
|
+
queue.splice(match, 1);
|
|
656
|
+
writeQueue(queue);
|
|
657
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
658
|
+
return true;
|
|
659
|
+
}
|
|
660
|
+
return false;
|
|
661
|
+
}
|
|
662
|
+
function clearQueueForAgent(agentName) {
|
|
663
|
+
const queue = readQueue();
|
|
664
|
+
const before = queue.length;
|
|
665
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
666
|
+
if (filtered.length < before) {
|
|
667
|
+
writeQueue(filtered);
|
|
668
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
function logQueue(msg) {
|
|
672
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
673
|
+
`;
|
|
674
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
675
|
+
`);
|
|
676
|
+
try {
|
|
677
|
+
const { appendFileSync: appendFileSync2 } = __require("fs");
|
|
678
|
+
appendFileSync2(INTERCOM_LOG, line);
|
|
679
|
+
} catch {
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
|
|
601
683
|
var init_intercom_queue = __esm({
|
|
602
684
|
"src/lib/intercom-queue.ts"() {
|
|
603
685
|
"use strict";
|
|
604
686
|
QUEUE_PATH = path4.join(os3.homedir(), ".exe-os", "intercom-queue.json");
|
|
687
|
+
MAX_RETRIES = 5;
|
|
605
688
|
TTL_MS = 60 * 60 * 1e3;
|
|
606
689
|
INTERCOM_LOG = path4.join(os3.homedir(), ".exe-os", "intercom.log");
|
|
607
690
|
}
|
|
@@ -620,18 +703,18 @@ function delay(ms) {
|
|
|
620
703
|
}
|
|
621
704
|
async function retryOnBusy(fn, label) {
|
|
622
705
|
let lastError;
|
|
623
|
-
for (let attempt = 0; attempt <=
|
|
706
|
+
for (let attempt = 0; attempt <= MAX_RETRIES2; attempt++) {
|
|
624
707
|
try {
|
|
625
708
|
return await fn();
|
|
626
709
|
} catch (err) {
|
|
627
710
|
lastError = err;
|
|
628
|
-
if (!isBusyError(err) || attempt ===
|
|
711
|
+
if (!isBusyError(err) || attempt === MAX_RETRIES2) {
|
|
629
712
|
throw err;
|
|
630
713
|
}
|
|
631
714
|
const backoff = BASE_DELAY_MS * Math.pow(2, attempt);
|
|
632
715
|
const jitter = Math.floor(Math.random() * MAX_JITTER_MS);
|
|
633
716
|
process.stderr.write(
|
|
634
|
-
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${
|
|
717
|
+
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${MAX_RETRIES2} \u2014 waiting ${backoff + jitter}ms
|
|
635
718
|
`
|
|
636
719
|
);
|
|
637
720
|
await delay(backoff + jitter);
|
|
@@ -652,11 +735,11 @@ function wrapWithRetry(client) {
|
|
|
652
735
|
}
|
|
653
736
|
});
|
|
654
737
|
}
|
|
655
|
-
var
|
|
738
|
+
var MAX_RETRIES2, BASE_DELAY_MS, MAX_JITTER_MS;
|
|
656
739
|
var init_db_retry = __esm({
|
|
657
740
|
"src/lib/db-retry.ts"() {
|
|
658
741
|
"use strict";
|
|
659
|
-
|
|
742
|
+
MAX_RETRIES2 = 3;
|
|
660
743
|
BASE_DELAY_MS = 200;
|
|
661
744
|
MAX_JITTER_MS = 300;
|
|
662
745
|
}
|
|
@@ -2935,6 +3018,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
2935
3018
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
2936
3019
|
} catch {
|
|
2937
3020
|
}
|
|
3021
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
3022
|
+
try {
|
|
3023
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
3024
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
3025
|
+
} catch {
|
|
3026
|
+
}
|
|
3027
|
+
}
|
|
2938
3028
|
try {
|
|
2939
3029
|
await writeCheckpoint({
|
|
2940
3030
|
taskId,
|
package/dist/gateway/index.js
CHANGED
|
@@ -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
|
};
|
|
@@ -4767,6 +4773,14 @@ var init_agent_config = __esm({
|
|
|
4767
4773
|
});
|
|
4768
4774
|
|
|
4769
4775
|
// src/lib/intercom-queue.ts
|
|
4776
|
+
var intercom_queue_exports = {};
|
|
4777
|
+
__export(intercom_queue_exports, {
|
|
4778
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
4779
|
+
drainForSession: () => drainForSession,
|
|
4780
|
+
drainQueue: () => drainQueue,
|
|
4781
|
+
queueIntercom: () => queueIntercom,
|
|
4782
|
+
readQueue: () => readQueue
|
|
4783
|
+
});
|
|
4770
4784
|
import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync8, mkdirSync as mkdirSync5 } from "fs";
|
|
4771
4785
|
import path9 from "path";
|
|
4772
4786
|
import os7 from "os";
|
|
@@ -4805,11 +4819,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
4805
4819
|
}
|
|
4806
4820
|
writeQueue(queue);
|
|
4807
4821
|
}
|
|
4808
|
-
|
|
4822
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
4823
|
+
const queue = readQueue();
|
|
4824
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
4825
|
+
const remaining = [];
|
|
4826
|
+
let drained = 0;
|
|
4827
|
+
let failed = 0;
|
|
4828
|
+
for (const item of queue) {
|
|
4829
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
4830
|
+
if (age > TTL_MS) {
|
|
4831
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
4832
|
+
failed++;
|
|
4833
|
+
continue;
|
|
4834
|
+
}
|
|
4835
|
+
try {
|
|
4836
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
4837
|
+
const success = sendKeys(item.targetSession);
|
|
4838
|
+
if (success) {
|
|
4839
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
4840
|
+
drained++;
|
|
4841
|
+
continue;
|
|
4842
|
+
}
|
|
4843
|
+
}
|
|
4844
|
+
} catch {
|
|
4845
|
+
}
|
|
4846
|
+
item.attempts++;
|
|
4847
|
+
if (item.attempts >= MAX_RETRIES2) {
|
|
4848
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES2} retries exhausted, reason: ${item.reason})`);
|
|
4849
|
+
failed++;
|
|
4850
|
+
continue;
|
|
4851
|
+
}
|
|
4852
|
+
remaining.push(item);
|
|
4853
|
+
}
|
|
4854
|
+
writeQueue(remaining);
|
|
4855
|
+
return { drained, failed };
|
|
4856
|
+
}
|
|
4857
|
+
function drainForSession(targetSession, sendKeys) {
|
|
4858
|
+
const queue = readQueue();
|
|
4859
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
4860
|
+
if (match < 0) return false;
|
|
4861
|
+
const success = sendKeys(targetSession);
|
|
4862
|
+
if (success) {
|
|
4863
|
+
queue.splice(match, 1);
|
|
4864
|
+
writeQueue(queue);
|
|
4865
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
4866
|
+
return true;
|
|
4867
|
+
}
|
|
4868
|
+
return false;
|
|
4869
|
+
}
|
|
4870
|
+
function clearQueueForAgent(agentName) {
|
|
4871
|
+
const queue = readQueue();
|
|
4872
|
+
const before = queue.length;
|
|
4873
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
4874
|
+
if (filtered.length < before) {
|
|
4875
|
+
writeQueue(filtered);
|
|
4876
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
4877
|
+
}
|
|
4878
|
+
}
|
|
4879
|
+
function logQueue(msg) {
|
|
4880
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
4881
|
+
`;
|
|
4882
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
4883
|
+
`);
|
|
4884
|
+
try {
|
|
4885
|
+
const { appendFileSync: appendFileSync2 } = __require("fs");
|
|
4886
|
+
appendFileSync2(INTERCOM_LOG, line);
|
|
4887
|
+
} catch {
|
|
4888
|
+
}
|
|
4889
|
+
}
|
|
4890
|
+
var QUEUE_PATH, MAX_RETRIES2, TTL_MS, INTERCOM_LOG;
|
|
4809
4891
|
var init_intercom_queue = __esm({
|
|
4810
4892
|
"src/lib/intercom-queue.ts"() {
|
|
4811
4893
|
"use strict";
|
|
4812
4894
|
QUEUE_PATH = path9.join(os7.homedir(), ".exe-os", "intercom-queue.json");
|
|
4895
|
+
MAX_RETRIES2 = 5;
|
|
4813
4896
|
TTL_MS = 60 * 60 * 1e3;
|
|
4814
4897
|
INTERCOM_LOG = path9.join(os7.homedir(), ".exe-os", "intercom.log");
|
|
4815
4898
|
}
|
|
@@ -5518,6 +5601,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
5518
5601
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
5519
5602
|
} catch {
|
|
5520
5603
|
}
|
|
5604
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
5605
|
+
try {
|
|
5606
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
5607
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
5608
|
+
} catch {
|
|
5609
|
+
}
|
|
5610
|
+
}
|
|
5521
5611
|
try {
|
|
5522
5612
|
await writeCheckpoint({
|
|
5523
5613
|
taskId,
|
|
@@ -7757,7 +7847,7 @@ async function deliverLocalMessage(messageId) {
|
|
|
7757
7847
|
return true;
|
|
7758
7848
|
} catch {
|
|
7759
7849
|
const newRetryCount = msg.retryCount + 1;
|
|
7760
|
-
if (newRetryCount >=
|
|
7850
|
+
if (newRetryCount >= MAX_RETRIES3) {
|
|
7761
7851
|
await markFailed(messageId, "session unavailable after 10 retries");
|
|
7762
7852
|
} else {
|
|
7763
7853
|
await client.execute({
|
|
@@ -7846,7 +7936,7 @@ async function retryPendingMessages() {
|
|
|
7846
7936
|
sql: `SELECT * FROM messages
|
|
7847
7937
|
WHERE status = 'pending' AND retry_count < ?
|
|
7848
7938
|
ORDER BY id`,
|
|
7849
|
-
args: [
|
|
7939
|
+
args: [MAX_RETRIES3]
|
|
7850
7940
|
});
|
|
7851
7941
|
let delivered = 0;
|
|
7852
7942
|
for (const row of result.rows) {
|
|
@@ -7859,13 +7949,13 @@ async function retryPendingMessages() {
|
|
|
7859
7949
|
}
|
|
7860
7950
|
return delivered;
|
|
7861
7951
|
}
|
|
7862
|
-
var
|
|
7952
|
+
var MAX_RETRIES3, _wsClientSend;
|
|
7863
7953
|
var init_messaging = __esm({
|
|
7864
7954
|
"src/lib/messaging.ts"() {
|
|
7865
7955
|
"use strict";
|
|
7866
7956
|
init_database();
|
|
7867
7957
|
init_tmux_routing();
|
|
7868
|
-
|
|
7958
|
+
MAX_RETRIES3 = 10;
|
|
7869
7959
|
_wsClientSend = null;
|
|
7870
7960
|
}
|
|
7871
7961
|
});
|