@askexenow/exe-os 0.9.0 → 0.9.2
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 +127 -34
- package/dist/bin/exe-agent-config.js +1 -1
- package/dist/bin/exe-boot.js +89 -5
- package/dist/bin/exe-call.js +1 -1
- 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-settings.js +1 -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/bin/update.js +3 -2
- 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 +18 -1
- package/dist/hooks/session-end.js +96 -6
- package/dist/hooks/stop.js +18 -0
- package/dist/index.js +94 -10
- package/dist/lib/agent-config.js +1 -1
- package/dist/lib/exe-daemon.js +18 -1
- package/dist/lib/tasks.js +91 -1
- package/dist/lib/tmux-routing.js +91 -1
- package/dist/mcp/server.js +955 -224
- 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
|
};
|
|
@@ -949,6 +955,14 @@ var init_agent_config = __esm({
|
|
|
949
955
|
});
|
|
950
956
|
|
|
951
957
|
// src/lib/intercom-queue.ts
|
|
958
|
+
var intercom_queue_exports = {};
|
|
959
|
+
__export(intercom_queue_exports, {
|
|
960
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
961
|
+
drainForSession: () => drainForSession,
|
|
962
|
+
drainQueue: () => drainQueue,
|
|
963
|
+
queueIntercom: () => queueIntercom,
|
|
964
|
+
readQueue: () => readQueue
|
|
965
|
+
});
|
|
952
966
|
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
|
|
953
967
|
import path6 from "path";
|
|
954
968
|
import os5 from "os";
|
|
@@ -987,11 +1001,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
987
1001
|
}
|
|
988
1002
|
writeQueue(queue);
|
|
989
1003
|
}
|
|
990
|
-
|
|
1004
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
1005
|
+
const queue = readQueue();
|
|
1006
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
1007
|
+
const remaining = [];
|
|
1008
|
+
let drained = 0;
|
|
1009
|
+
let failed = 0;
|
|
1010
|
+
for (const item of queue) {
|
|
1011
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
1012
|
+
if (age > TTL_MS) {
|
|
1013
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
1014
|
+
failed++;
|
|
1015
|
+
continue;
|
|
1016
|
+
}
|
|
1017
|
+
try {
|
|
1018
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
1019
|
+
const success = sendKeys(item.targetSession);
|
|
1020
|
+
if (success) {
|
|
1021
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
1022
|
+
drained++;
|
|
1023
|
+
continue;
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
} catch {
|
|
1027
|
+
}
|
|
1028
|
+
item.attempts++;
|
|
1029
|
+
if (item.attempts >= MAX_RETRIES) {
|
|
1030
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES} retries exhausted, reason: ${item.reason})`);
|
|
1031
|
+
failed++;
|
|
1032
|
+
continue;
|
|
1033
|
+
}
|
|
1034
|
+
remaining.push(item);
|
|
1035
|
+
}
|
|
1036
|
+
writeQueue(remaining);
|
|
1037
|
+
return { drained, failed };
|
|
1038
|
+
}
|
|
1039
|
+
function drainForSession(targetSession, sendKeys) {
|
|
1040
|
+
const queue = readQueue();
|
|
1041
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
1042
|
+
if (match < 0) return false;
|
|
1043
|
+
const success = sendKeys(targetSession);
|
|
1044
|
+
if (success) {
|
|
1045
|
+
queue.splice(match, 1);
|
|
1046
|
+
writeQueue(queue);
|
|
1047
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
1048
|
+
return true;
|
|
1049
|
+
}
|
|
1050
|
+
return false;
|
|
1051
|
+
}
|
|
1052
|
+
function clearQueueForAgent(agentName) {
|
|
1053
|
+
const queue = readQueue();
|
|
1054
|
+
const before = queue.length;
|
|
1055
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
1056
|
+
if (filtered.length < before) {
|
|
1057
|
+
writeQueue(filtered);
|
|
1058
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
function logQueue(msg) {
|
|
1062
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
1063
|
+
`;
|
|
1064
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
1065
|
+
`);
|
|
1066
|
+
try {
|
|
1067
|
+
const { appendFileSync: appendFileSync2 } = __require("fs");
|
|
1068
|
+
appendFileSync2(INTERCOM_LOG, line);
|
|
1069
|
+
} catch {
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
|
|
991
1073
|
var init_intercom_queue = __esm({
|
|
992
1074
|
"src/lib/intercom-queue.ts"() {
|
|
993
1075
|
"use strict";
|
|
994
1076
|
QUEUE_PATH = path6.join(os5.homedir(), ".exe-os", "intercom-queue.json");
|
|
1077
|
+
MAX_RETRIES = 5;
|
|
995
1078
|
TTL_MS = 60 * 60 * 1e3;
|
|
996
1079
|
INTERCOM_LOG = path6.join(os5.homedir(), ".exe-os", "intercom.log");
|
|
997
1080
|
}
|
|
@@ -2685,6 +2768,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
2685
2768
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
2686
2769
|
} catch {
|
|
2687
2770
|
}
|
|
2771
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
2772
|
+
try {
|
|
2773
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
2774
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
2775
|
+
} catch {
|
|
2776
|
+
}
|
|
2777
|
+
}
|
|
2688
2778
|
try {
|
|
2689
2779
|
await writeCheckpoint({
|
|
2690
2780
|
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
|
};
|
|
@@ -673,6 +679,14 @@ var init_agent_config = __esm({
|
|
|
673
679
|
});
|
|
674
680
|
|
|
675
681
|
// src/lib/intercom-queue.ts
|
|
682
|
+
var intercom_queue_exports = {};
|
|
683
|
+
__export(intercom_queue_exports, {
|
|
684
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
685
|
+
drainForSession: () => drainForSession,
|
|
686
|
+
drainQueue: () => drainQueue,
|
|
687
|
+
queueIntercom: () => queueIntercom,
|
|
688
|
+
readQueue: () => readQueue
|
|
689
|
+
});
|
|
676
690
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, renameSync as renameSync3, existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
|
|
677
691
|
import path6 from "path";
|
|
678
692
|
import os5 from "os";
|
|
@@ -711,11 +725,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
711
725
|
}
|
|
712
726
|
writeQueue(queue);
|
|
713
727
|
}
|
|
714
|
-
|
|
728
|
+
function drainQueue(isSessionBusy, sendKeys) {
|
|
729
|
+
const queue = readQueue();
|
|
730
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
731
|
+
const remaining = [];
|
|
732
|
+
let drained = 0;
|
|
733
|
+
let failed = 0;
|
|
734
|
+
for (const item of queue) {
|
|
735
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
736
|
+
if (age > TTL_MS) {
|
|
737
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
738
|
+
failed++;
|
|
739
|
+
continue;
|
|
740
|
+
}
|
|
741
|
+
try {
|
|
742
|
+
if (!isSessionBusy(item.targetSession)) {
|
|
743
|
+
const success = sendKeys(item.targetSession);
|
|
744
|
+
if (success) {
|
|
745
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
746
|
+
drained++;
|
|
747
|
+
continue;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
} catch {
|
|
751
|
+
}
|
|
752
|
+
item.attempts++;
|
|
753
|
+
if (item.attempts >= MAX_RETRIES) {
|
|
754
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES} retries exhausted, reason: ${item.reason})`);
|
|
755
|
+
failed++;
|
|
756
|
+
continue;
|
|
757
|
+
}
|
|
758
|
+
remaining.push(item);
|
|
759
|
+
}
|
|
760
|
+
writeQueue(remaining);
|
|
761
|
+
return { drained, failed };
|
|
762
|
+
}
|
|
763
|
+
function drainForSession(targetSession, sendKeys) {
|
|
764
|
+
const queue = readQueue();
|
|
765
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
766
|
+
if (match < 0) return false;
|
|
767
|
+
const success = sendKeys(targetSession);
|
|
768
|
+
if (success) {
|
|
769
|
+
queue.splice(match, 1);
|
|
770
|
+
writeQueue(queue);
|
|
771
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
772
|
+
return true;
|
|
773
|
+
}
|
|
774
|
+
return false;
|
|
775
|
+
}
|
|
776
|
+
function clearQueueForAgent(agentName) {
|
|
777
|
+
const queue = readQueue();
|
|
778
|
+
const before = queue.length;
|
|
779
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
780
|
+
if (filtered.length < before) {
|
|
781
|
+
writeQueue(filtered);
|
|
782
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
function logQueue(msg) {
|
|
786
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
787
|
+
`;
|
|
788
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
789
|
+
`);
|
|
790
|
+
try {
|
|
791
|
+
const { appendFileSync: appendFileSync2 } = __require("fs");
|
|
792
|
+
appendFileSync2(INTERCOM_LOG, line);
|
|
793
|
+
} catch {
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
|
|
715
797
|
var init_intercom_queue = __esm({
|
|
716
798
|
"src/lib/intercom-queue.ts"() {
|
|
717
799
|
"use strict";
|
|
718
800
|
QUEUE_PATH = path6.join(os5.homedir(), ".exe-os", "intercom-queue.json");
|
|
801
|
+
MAX_RETRIES = 5;
|
|
719
802
|
TTL_MS = 60 * 60 * 1e3;
|
|
720
803
|
INTERCOM_LOG = path6.join(os5.homedir(), ".exe-os", "intercom.log");
|
|
721
804
|
}
|
|
@@ -1279,6 +1362,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
1279
1362
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
1280
1363
|
} catch {
|
|
1281
1364
|
}
|
|
1365
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
1366
|
+
try {
|
|
1367
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
1368
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
1369
|
+
} catch {
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1282
1372
|
try {
|
|
1283
1373
|
await writeCheckpoint({
|
|
1284
1374
|
taskId,
|
package/dist/runtime/index.js
CHANGED
|
@@ -647,6 +647,14 @@ var init_agent_config = __esm({
|
|
|
647
647
|
});
|
|
648
648
|
|
|
649
649
|
// src/lib/intercom-queue.ts
|
|
650
|
+
var intercom_queue_exports = {};
|
|
651
|
+
__export(intercom_queue_exports, {
|
|
652
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
653
|
+
drainForSession: () => drainForSession,
|
|
654
|
+
drainQueue: () => drainQueue,
|
|
655
|
+
queueIntercom: () => queueIntercom,
|
|
656
|
+
readQueue: () => readQueue
|
|
657
|
+
});
|
|
650
658
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
|
|
651
659
|
import path6 from "path";
|
|
652
660
|
import os5 from "os";
|
|
@@ -685,11 +693,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
685
693
|
}
|
|
686
694
|
writeQueue(queue);
|
|
687
695
|
}
|
|
688
|
-
|
|
696
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
697
|
+
const queue = readQueue();
|
|
698
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
699
|
+
const remaining = [];
|
|
700
|
+
let drained = 0;
|
|
701
|
+
let failed = 0;
|
|
702
|
+
for (const item of queue) {
|
|
703
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
704
|
+
if (age > TTL_MS) {
|
|
705
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
706
|
+
failed++;
|
|
707
|
+
continue;
|
|
708
|
+
}
|
|
709
|
+
try {
|
|
710
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
711
|
+
const success = sendKeys(item.targetSession);
|
|
712
|
+
if (success) {
|
|
713
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
714
|
+
drained++;
|
|
715
|
+
continue;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
} catch {
|
|
719
|
+
}
|
|
720
|
+
item.attempts++;
|
|
721
|
+
if (item.attempts >= MAX_RETRIES) {
|
|
722
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES} retries exhausted, reason: ${item.reason})`);
|
|
723
|
+
failed++;
|
|
724
|
+
continue;
|
|
725
|
+
}
|
|
726
|
+
remaining.push(item);
|
|
727
|
+
}
|
|
728
|
+
writeQueue(remaining);
|
|
729
|
+
return { drained, failed };
|
|
730
|
+
}
|
|
731
|
+
function drainForSession(targetSession, sendKeys) {
|
|
732
|
+
const queue = readQueue();
|
|
733
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
734
|
+
if (match < 0) return false;
|
|
735
|
+
const success = sendKeys(targetSession);
|
|
736
|
+
if (success) {
|
|
737
|
+
queue.splice(match, 1);
|
|
738
|
+
writeQueue(queue);
|
|
739
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
740
|
+
return true;
|
|
741
|
+
}
|
|
742
|
+
return false;
|
|
743
|
+
}
|
|
744
|
+
function clearQueueForAgent(agentName) {
|
|
745
|
+
const queue = readQueue();
|
|
746
|
+
const before = queue.length;
|
|
747
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
748
|
+
if (filtered.length < before) {
|
|
749
|
+
writeQueue(filtered);
|
|
750
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
function logQueue(msg) {
|
|
754
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
755
|
+
`;
|
|
756
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
757
|
+
`);
|
|
758
|
+
try {
|
|
759
|
+
const { appendFileSync: appendFileSync2 } = __require("fs");
|
|
760
|
+
appendFileSync2(INTERCOM_LOG, line);
|
|
761
|
+
} catch {
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
|
|
689
765
|
var init_intercom_queue = __esm({
|
|
690
766
|
"src/lib/intercom-queue.ts"() {
|
|
691
767
|
"use strict";
|
|
692
768
|
QUEUE_PATH = path6.join(os5.homedir(), ".exe-os", "intercom-queue.json");
|
|
769
|
+
MAX_RETRIES = 5;
|
|
693
770
|
TTL_MS = 60 * 60 * 1e3;
|
|
694
771
|
INTERCOM_LOG = path6.join(os5.homedir(), ".exe-os", "intercom.log");
|
|
695
772
|
}
|
|
@@ -708,18 +785,18 @@ function delay(ms) {
|
|
|
708
785
|
}
|
|
709
786
|
async function retryOnBusy(fn, label) {
|
|
710
787
|
let lastError;
|
|
711
|
-
for (let attempt = 0; attempt <=
|
|
788
|
+
for (let attempt = 0; attempt <= MAX_RETRIES2; attempt++) {
|
|
712
789
|
try {
|
|
713
790
|
return await fn();
|
|
714
791
|
} catch (err) {
|
|
715
792
|
lastError = err;
|
|
716
|
-
if (!isBusyError(err) || attempt ===
|
|
793
|
+
if (!isBusyError(err) || attempt === MAX_RETRIES2) {
|
|
717
794
|
throw err;
|
|
718
795
|
}
|
|
719
796
|
const backoff = BASE_DELAY_MS * Math.pow(2, attempt);
|
|
720
797
|
const jitter = Math.floor(Math.random() * MAX_JITTER_MS);
|
|
721
798
|
process.stderr.write(
|
|
722
|
-
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${
|
|
799
|
+
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${MAX_RETRIES2} \u2014 waiting ${backoff + jitter}ms
|
|
723
800
|
`
|
|
724
801
|
);
|
|
725
802
|
await delay(backoff + jitter);
|
|
@@ -740,11 +817,11 @@ function wrapWithRetry(client) {
|
|
|
740
817
|
}
|
|
741
818
|
});
|
|
742
819
|
}
|
|
743
|
-
var
|
|
820
|
+
var MAX_RETRIES2, BASE_DELAY_MS, MAX_JITTER_MS;
|
|
744
821
|
var init_db_retry = __esm({
|
|
745
822
|
"src/lib/db-retry.ts"() {
|
|
746
823
|
"use strict";
|
|
747
|
-
|
|
824
|
+
MAX_RETRIES2 = 3;
|
|
748
825
|
BASE_DELAY_MS = 200;
|
|
749
826
|
MAX_JITTER_MS = 300;
|
|
750
827
|
}
|
|
@@ -2993,6 +3070,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
2993
3070
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
2994
3071
|
} catch {
|
|
2995
3072
|
}
|
|
3073
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
3074
|
+
try {
|
|
3075
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
3076
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
3077
|
+
} catch {
|
|
3078
|
+
}
|
|
3079
|
+
}
|
|
2996
3080
|
try {
|
|
2997
3081
|
await writeCheckpoint({
|
|
2998
3082
|
taskId,
|
package/dist/tui/App.js
CHANGED
|
@@ -657,6 +657,14 @@ var init_agent_config = __esm({
|
|
|
657
657
|
});
|
|
658
658
|
|
|
659
659
|
// src/lib/intercom-queue.ts
|
|
660
|
+
var intercom_queue_exports = {};
|
|
661
|
+
__export(intercom_queue_exports, {
|
|
662
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
663
|
+
drainForSession: () => drainForSession,
|
|
664
|
+
drainQueue: () => drainQueue,
|
|
665
|
+
queueIntercom: () => queueIntercom,
|
|
666
|
+
readQueue: () => readQueue
|
|
667
|
+
});
|
|
660
668
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, renameSync as renameSync2, existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
|
|
661
669
|
import path4 from "path";
|
|
662
670
|
import os3 from "os";
|
|
@@ -695,11 +703,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
695
703
|
}
|
|
696
704
|
writeQueue(queue);
|
|
697
705
|
}
|
|
698
|
-
|
|
706
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
707
|
+
const queue = readQueue();
|
|
708
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
709
|
+
const remaining = [];
|
|
710
|
+
let drained = 0;
|
|
711
|
+
let failed = 0;
|
|
712
|
+
for (const item of queue) {
|
|
713
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
714
|
+
if (age > TTL_MS) {
|
|
715
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
716
|
+
failed++;
|
|
717
|
+
continue;
|
|
718
|
+
}
|
|
719
|
+
try {
|
|
720
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
721
|
+
const success = sendKeys(item.targetSession);
|
|
722
|
+
if (success) {
|
|
723
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
724
|
+
drained++;
|
|
725
|
+
continue;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
} catch {
|
|
729
|
+
}
|
|
730
|
+
item.attempts++;
|
|
731
|
+
if (item.attempts >= MAX_RETRIES) {
|
|
732
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES} retries exhausted, reason: ${item.reason})`);
|
|
733
|
+
failed++;
|
|
734
|
+
continue;
|
|
735
|
+
}
|
|
736
|
+
remaining.push(item);
|
|
737
|
+
}
|
|
738
|
+
writeQueue(remaining);
|
|
739
|
+
return { drained, failed };
|
|
740
|
+
}
|
|
741
|
+
function drainForSession(targetSession, sendKeys) {
|
|
742
|
+
const queue = readQueue();
|
|
743
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
744
|
+
if (match < 0) return false;
|
|
745
|
+
const success = sendKeys(targetSession);
|
|
746
|
+
if (success) {
|
|
747
|
+
queue.splice(match, 1);
|
|
748
|
+
writeQueue(queue);
|
|
749
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
750
|
+
return true;
|
|
751
|
+
}
|
|
752
|
+
return false;
|
|
753
|
+
}
|
|
754
|
+
function clearQueueForAgent(agentName) {
|
|
755
|
+
const queue = readQueue();
|
|
756
|
+
const before = queue.length;
|
|
757
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
758
|
+
if (filtered.length < before) {
|
|
759
|
+
writeQueue(filtered);
|
|
760
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
function logQueue(msg) {
|
|
764
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
765
|
+
`;
|
|
766
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
767
|
+
`);
|
|
768
|
+
try {
|
|
769
|
+
const { appendFileSync: appendFileSync2 } = __require("fs");
|
|
770
|
+
appendFileSync2(INTERCOM_LOG, line);
|
|
771
|
+
} catch {
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
|
|
699
775
|
var init_intercom_queue = __esm({
|
|
700
776
|
"src/lib/intercom-queue.ts"() {
|
|
701
777
|
"use strict";
|
|
702
778
|
QUEUE_PATH = path4.join(os3.homedir(), ".exe-os", "intercom-queue.json");
|
|
779
|
+
MAX_RETRIES = 5;
|
|
703
780
|
TTL_MS = 60 * 60 * 1e3;
|
|
704
781
|
INTERCOM_LOG = path4.join(os3.homedir(), ".exe-os", "intercom.log");
|
|
705
782
|
}
|
|
@@ -718,18 +795,18 @@ function delay(ms) {
|
|
|
718
795
|
}
|
|
719
796
|
async function retryOnBusy(fn, label) {
|
|
720
797
|
let lastError;
|
|
721
|
-
for (let attempt = 0; attempt <=
|
|
798
|
+
for (let attempt = 0; attempt <= MAX_RETRIES2; attempt++) {
|
|
722
799
|
try {
|
|
723
800
|
return await fn();
|
|
724
801
|
} catch (err) {
|
|
725
802
|
lastError = err;
|
|
726
|
-
if (!isBusyError(err) || attempt ===
|
|
803
|
+
if (!isBusyError(err) || attempt === MAX_RETRIES2) {
|
|
727
804
|
throw err;
|
|
728
805
|
}
|
|
729
806
|
const backoff = BASE_DELAY_MS * Math.pow(2, attempt);
|
|
730
807
|
const jitter = Math.floor(Math.random() * MAX_JITTER_MS);
|
|
731
808
|
process.stderr.write(
|
|
732
|
-
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${
|
|
809
|
+
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${MAX_RETRIES2} \u2014 waiting ${backoff + jitter}ms
|
|
733
810
|
`
|
|
734
811
|
);
|
|
735
812
|
await delay(backoff + jitter);
|
|
@@ -750,11 +827,11 @@ function wrapWithRetry(client) {
|
|
|
750
827
|
}
|
|
751
828
|
});
|
|
752
829
|
}
|
|
753
|
-
var
|
|
830
|
+
var MAX_RETRIES2, BASE_DELAY_MS, MAX_JITTER_MS;
|
|
754
831
|
var init_db_retry = __esm({
|
|
755
832
|
"src/lib/db-retry.ts"() {
|
|
756
833
|
"use strict";
|
|
757
|
-
|
|
834
|
+
MAX_RETRIES2 = 3;
|
|
758
835
|
BASE_DELAY_MS = 200;
|
|
759
836
|
MAX_JITTER_MS = 300;
|
|
760
837
|
}
|
|
@@ -3561,6 +3638,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
3561
3638
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3562
3639
|
} catch {
|
|
3563
3640
|
}
|
|
3641
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
3642
|
+
try {
|
|
3643
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
3644
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
3645
|
+
} catch {
|
|
3646
|
+
}
|
|
3647
|
+
}
|
|
3564
3648
|
try {
|
|
3565
3649
|
await writeCheckpoint({
|
|
3566
3650
|
taskId,
|
package/package.json
CHANGED