@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
|
};
|
|
@@ -608,6 +614,14 @@ var init_agent_config = __esm({
|
|
|
608
614
|
});
|
|
609
615
|
|
|
610
616
|
// src/lib/intercom-queue.ts
|
|
617
|
+
var intercom_queue_exports = {};
|
|
618
|
+
__export(intercom_queue_exports, {
|
|
619
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
620
|
+
drainForSession: () => drainForSession,
|
|
621
|
+
drainQueue: () => drainQueue,
|
|
622
|
+
queueIntercom: () => queueIntercom,
|
|
623
|
+
readQueue: () => readQueue
|
|
624
|
+
});
|
|
611
625
|
import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, renameSync as renameSync3, existsSync as existsSync5, mkdirSync as mkdirSync4 } from "fs";
|
|
612
626
|
import path6 from "path";
|
|
613
627
|
import os4 from "os";
|
|
@@ -646,11 +660,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
646
660
|
}
|
|
647
661
|
writeQueue(queue);
|
|
648
662
|
}
|
|
649
|
-
|
|
663
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
664
|
+
const queue = readQueue();
|
|
665
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
666
|
+
const remaining = [];
|
|
667
|
+
let drained = 0;
|
|
668
|
+
let failed = 0;
|
|
669
|
+
for (const item of queue) {
|
|
670
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
671
|
+
if (age > TTL_MS) {
|
|
672
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
673
|
+
failed++;
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
try {
|
|
677
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
678
|
+
const success = sendKeys(item.targetSession);
|
|
679
|
+
if (success) {
|
|
680
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
681
|
+
drained++;
|
|
682
|
+
continue;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
} catch {
|
|
686
|
+
}
|
|
687
|
+
item.attempts++;
|
|
688
|
+
if (item.attempts >= MAX_RETRIES) {
|
|
689
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES} retries exhausted, reason: ${item.reason})`);
|
|
690
|
+
failed++;
|
|
691
|
+
continue;
|
|
692
|
+
}
|
|
693
|
+
remaining.push(item);
|
|
694
|
+
}
|
|
695
|
+
writeQueue(remaining);
|
|
696
|
+
return { drained, failed };
|
|
697
|
+
}
|
|
698
|
+
function drainForSession(targetSession, sendKeys) {
|
|
699
|
+
const queue = readQueue();
|
|
700
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
701
|
+
if (match < 0) return false;
|
|
702
|
+
const success = sendKeys(targetSession);
|
|
703
|
+
if (success) {
|
|
704
|
+
queue.splice(match, 1);
|
|
705
|
+
writeQueue(queue);
|
|
706
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
707
|
+
return true;
|
|
708
|
+
}
|
|
709
|
+
return false;
|
|
710
|
+
}
|
|
711
|
+
function clearQueueForAgent(agentName) {
|
|
712
|
+
const queue = readQueue();
|
|
713
|
+
const before = queue.length;
|
|
714
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
715
|
+
if (filtered.length < before) {
|
|
716
|
+
writeQueue(filtered);
|
|
717
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
function logQueue(msg) {
|
|
721
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
722
|
+
`;
|
|
723
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
724
|
+
`);
|
|
725
|
+
try {
|
|
726
|
+
const { appendFileSync: appendFileSync2 } = __require("fs");
|
|
727
|
+
appendFileSync2(INTERCOM_LOG, line);
|
|
728
|
+
} catch {
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
|
|
650
732
|
var init_intercom_queue = __esm({
|
|
651
733
|
"src/lib/intercom-queue.ts"() {
|
|
652
734
|
"use strict";
|
|
653
735
|
QUEUE_PATH = path6.join(os4.homedir(), ".exe-os", "intercom-queue.json");
|
|
736
|
+
MAX_RETRIES = 5;
|
|
654
737
|
TTL_MS = 60 * 60 * 1e3;
|
|
655
738
|
INTERCOM_LOG = path6.join(os4.homedir(), ".exe-os", "intercom.log");
|
|
656
739
|
}
|
|
@@ -669,18 +752,18 @@ function delay(ms) {
|
|
|
669
752
|
}
|
|
670
753
|
async function retryOnBusy(fn, label) {
|
|
671
754
|
let lastError;
|
|
672
|
-
for (let attempt = 0; attempt <=
|
|
755
|
+
for (let attempt = 0; attempt <= MAX_RETRIES2; attempt++) {
|
|
673
756
|
try {
|
|
674
757
|
return await fn();
|
|
675
758
|
} catch (err) {
|
|
676
759
|
lastError = err;
|
|
677
|
-
if (!isBusyError(err) || attempt ===
|
|
760
|
+
if (!isBusyError(err) || attempt === MAX_RETRIES2) {
|
|
678
761
|
throw err;
|
|
679
762
|
}
|
|
680
763
|
const backoff = BASE_DELAY_MS * Math.pow(2, attempt);
|
|
681
764
|
const jitter = Math.floor(Math.random() * MAX_JITTER_MS);
|
|
682
765
|
process.stderr.write(
|
|
683
|
-
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${
|
|
766
|
+
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${MAX_RETRIES2} \u2014 waiting ${backoff + jitter}ms
|
|
684
767
|
`
|
|
685
768
|
);
|
|
686
769
|
await delay(backoff + jitter);
|
|
@@ -701,11 +784,11 @@ function wrapWithRetry(client) {
|
|
|
701
784
|
}
|
|
702
785
|
});
|
|
703
786
|
}
|
|
704
|
-
var
|
|
787
|
+
var MAX_RETRIES2, BASE_DELAY_MS, MAX_JITTER_MS;
|
|
705
788
|
var init_db_retry = __esm({
|
|
706
789
|
"src/lib/db-retry.ts"() {
|
|
707
790
|
"use strict";
|
|
708
|
-
|
|
791
|
+
MAX_RETRIES2 = 3;
|
|
709
792
|
BASE_DELAY_MS = 200;
|
|
710
793
|
MAX_JITTER_MS = 300;
|
|
711
794
|
}
|
|
@@ -3124,6 +3207,13 @@ ${input2.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
3124
3207
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3125
3208
|
} catch {
|
|
3126
3209
|
}
|
|
3210
|
+
if (input2.status === "done" || input2.status === "cancelled") {
|
|
3211
|
+
try {
|
|
3212
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
3213
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
3214
|
+
} catch {
|
|
3215
|
+
}
|
|
3216
|
+
}
|
|
3127
3217
|
try {
|
|
3128
3218
|
await writeCheckpoint({
|
|
3129
3219
|
taskId,
|
package/dist/hooks/stop.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
|
};
|
|
@@ -3448,6 +3454,18 @@ process.stdin.on("data", (chunk) => {
|
|
|
3448
3454
|
});
|
|
3449
3455
|
process.stdin.on("end", () => {
|
|
3450
3456
|
try {
|
|
3457
|
+
if (process.env.EXE_DEBUG_HOOKS || process.env.EXE_RUNTIME === "codex") {
|
|
3458
|
+
try {
|
|
3459
|
+
const debugPath = path13.join(EXE_AI_DIR, "logs", "hook-stdin-stop.log");
|
|
3460
|
+
const { mkdirSync: mkdirSync7, writeFileSync: writeFileSync7 } = __require("fs");
|
|
3461
|
+
mkdirSync7(path13.dirname(debugPath), { recursive: true });
|
|
3462
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
3463
|
+
const snippet = input.length > 500 ? input.slice(0, 500) + "...[truncated]" : input;
|
|
3464
|
+
writeFileSync7(debugPath, `[${ts}] len=${input.length} ${snippet}
|
|
3465
|
+
`, { flag: "a" });
|
|
3466
|
+
} catch {
|
|
3467
|
+
}
|
|
3468
|
+
}
|
|
3451
3469
|
const data = JSON.parse(input);
|
|
3452
3470
|
const message = data.last_assistant_message;
|
|
3453
3471
|
if (!message || message.length < MIN_LENGTH) {
|
package/dist/index.js
CHANGED
|
@@ -852,6 +852,14 @@ var init_agent_config = __esm({
|
|
|
852
852
|
});
|
|
853
853
|
|
|
854
854
|
// src/lib/intercom-queue.ts
|
|
855
|
+
var intercom_queue_exports = {};
|
|
856
|
+
__export(intercom_queue_exports, {
|
|
857
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
858
|
+
drainForSession: () => drainForSession,
|
|
859
|
+
drainQueue: () => drainQueue,
|
|
860
|
+
queueIntercom: () => queueIntercom,
|
|
861
|
+
readQueue: () => readQueue
|
|
862
|
+
});
|
|
855
863
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
|
|
856
864
|
import path6 from "path";
|
|
857
865
|
import os5 from "os";
|
|
@@ -890,11 +898,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
890
898
|
}
|
|
891
899
|
writeQueue(queue);
|
|
892
900
|
}
|
|
893
|
-
|
|
901
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
902
|
+
const queue = readQueue();
|
|
903
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
904
|
+
const remaining = [];
|
|
905
|
+
let drained = 0;
|
|
906
|
+
let failed = 0;
|
|
907
|
+
for (const item of queue) {
|
|
908
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
909
|
+
if (age > TTL_MS) {
|
|
910
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
911
|
+
failed++;
|
|
912
|
+
continue;
|
|
913
|
+
}
|
|
914
|
+
try {
|
|
915
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
916
|
+
const success = sendKeys(item.targetSession);
|
|
917
|
+
if (success) {
|
|
918
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
919
|
+
drained++;
|
|
920
|
+
continue;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
} catch {
|
|
924
|
+
}
|
|
925
|
+
item.attempts++;
|
|
926
|
+
if (item.attempts >= MAX_RETRIES) {
|
|
927
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES} retries exhausted, reason: ${item.reason})`);
|
|
928
|
+
failed++;
|
|
929
|
+
continue;
|
|
930
|
+
}
|
|
931
|
+
remaining.push(item);
|
|
932
|
+
}
|
|
933
|
+
writeQueue(remaining);
|
|
934
|
+
return { drained, failed };
|
|
935
|
+
}
|
|
936
|
+
function drainForSession(targetSession, sendKeys) {
|
|
937
|
+
const queue = readQueue();
|
|
938
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
939
|
+
if (match < 0) return false;
|
|
940
|
+
const success = sendKeys(targetSession);
|
|
941
|
+
if (success) {
|
|
942
|
+
queue.splice(match, 1);
|
|
943
|
+
writeQueue(queue);
|
|
944
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
945
|
+
return true;
|
|
946
|
+
}
|
|
947
|
+
return false;
|
|
948
|
+
}
|
|
949
|
+
function clearQueueForAgent(agentName) {
|
|
950
|
+
const queue = readQueue();
|
|
951
|
+
const before = queue.length;
|
|
952
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
953
|
+
if (filtered.length < before) {
|
|
954
|
+
writeQueue(filtered);
|
|
955
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
function logQueue(msg) {
|
|
959
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
960
|
+
`;
|
|
961
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
962
|
+
`);
|
|
963
|
+
try {
|
|
964
|
+
const { appendFileSync: appendFileSync2 } = __require("fs");
|
|
965
|
+
appendFileSync2(INTERCOM_LOG, line);
|
|
966
|
+
} catch {
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
|
|
894
970
|
var init_intercom_queue = __esm({
|
|
895
971
|
"src/lib/intercom-queue.ts"() {
|
|
896
972
|
"use strict";
|
|
897
973
|
QUEUE_PATH = path6.join(os5.homedir(), ".exe-os", "intercom-queue.json");
|
|
974
|
+
MAX_RETRIES = 5;
|
|
898
975
|
TTL_MS = 60 * 60 * 1e3;
|
|
899
976
|
INTERCOM_LOG = path6.join(os5.homedir(), ".exe-os", "intercom.log");
|
|
900
977
|
}
|
|
@@ -913,18 +990,18 @@ function delay(ms) {
|
|
|
913
990
|
}
|
|
914
991
|
async function retryOnBusy(fn, label) {
|
|
915
992
|
let lastError;
|
|
916
|
-
for (let attempt = 0; attempt <=
|
|
993
|
+
for (let attempt = 0; attempt <= MAX_RETRIES2; attempt++) {
|
|
917
994
|
try {
|
|
918
995
|
return await fn();
|
|
919
996
|
} catch (err) {
|
|
920
997
|
lastError = err;
|
|
921
|
-
if (!isBusyError(err) || attempt ===
|
|
998
|
+
if (!isBusyError(err) || attempt === MAX_RETRIES2) {
|
|
922
999
|
throw err;
|
|
923
1000
|
}
|
|
924
1001
|
const backoff = BASE_DELAY_MS * Math.pow(2, attempt);
|
|
925
1002
|
const jitter = Math.floor(Math.random() * MAX_JITTER_MS);
|
|
926
1003
|
process.stderr.write(
|
|
927
|
-
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${
|
|
1004
|
+
`[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${MAX_RETRIES2} \u2014 waiting ${backoff + jitter}ms
|
|
928
1005
|
`
|
|
929
1006
|
);
|
|
930
1007
|
await delay(backoff + jitter);
|
|
@@ -945,11 +1022,11 @@ function wrapWithRetry(client) {
|
|
|
945
1022
|
}
|
|
946
1023
|
});
|
|
947
1024
|
}
|
|
948
|
-
var
|
|
1025
|
+
var MAX_RETRIES2, BASE_DELAY_MS, MAX_JITTER_MS;
|
|
949
1026
|
var init_db_retry = __esm({
|
|
950
1027
|
"src/lib/db-retry.ts"() {
|
|
951
1028
|
"use strict";
|
|
952
|
-
|
|
1029
|
+
MAX_RETRIES2 = 3;
|
|
953
1030
|
BASE_DELAY_MS = 200;
|
|
954
1031
|
MAX_JITTER_MS = 300;
|
|
955
1032
|
}
|
|
@@ -3294,6 +3371,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
3294
3371
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3295
3372
|
} catch {
|
|
3296
3373
|
}
|
|
3374
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
3375
|
+
try {
|
|
3376
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
3377
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
3378
|
+
} catch {
|
|
3379
|
+
}
|
|
3380
|
+
}
|
|
3297
3381
|
try {
|
|
3298
3382
|
await writeCheckpoint({
|
|
3299
3383
|
taskId,
|
|
@@ -8443,7 +8527,7 @@ async function deliverLocalMessage(messageId) {
|
|
|
8443
8527
|
return true;
|
|
8444
8528
|
} catch {
|
|
8445
8529
|
const newRetryCount = msg.retryCount + 1;
|
|
8446
|
-
if (newRetryCount >=
|
|
8530
|
+
if (newRetryCount >= MAX_RETRIES3) {
|
|
8447
8531
|
await markFailed(messageId, "session unavailable after 10 retries");
|
|
8448
8532
|
} else {
|
|
8449
8533
|
await client.execute({
|
|
@@ -8532,7 +8616,7 @@ async function retryPendingMessages() {
|
|
|
8532
8616
|
sql: `SELECT * FROM messages
|
|
8533
8617
|
WHERE status = 'pending' AND retry_count < ?
|
|
8534
8618
|
ORDER BY id`,
|
|
8535
|
-
args: [
|
|
8619
|
+
args: [MAX_RETRIES3]
|
|
8536
8620
|
});
|
|
8537
8621
|
let delivered = 0;
|
|
8538
8622
|
for (const row of result.rows) {
|
|
@@ -8545,13 +8629,13 @@ async function retryPendingMessages() {
|
|
|
8545
8629
|
}
|
|
8546
8630
|
return delivered;
|
|
8547
8631
|
}
|
|
8548
|
-
var
|
|
8632
|
+
var MAX_RETRIES3, _wsClientSend;
|
|
8549
8633
|
var init_messaging = __esm({
|
|
8550
8634
|
"src/lib/messaging.ts"() {
|
|
8551
8635
|
"use strict";
|
|
8552
8636
|
init_database();
|
|
8553
8637
|
init_tmux_routing();
|
|
8554
|
-
|
|
8638
|
+
MAX_RETRIES3 = 10;
|
|
8555
8639
|
_wsClientSend = null;
|
|
8556
8640
|
}
|
|
8557
8641
|
});
|
package/dist/lib/agent-config.js
CHANGED
|
@@ -112,7 +112,7 @@ var DEFAULT_RUNTIME = "claude";
|
|
|
112
112
|
var AGENT_CONFIG_PATH = path2.join(EXE_AI_DIR, "agent-config.json");
|
|
113
113
|
var KNOWN_RUNTIMES = {
|
|
114
114
|
claude: ["claude-opus-4", "claude-sonnet-4", "claude-haiku-4.5"],
|
|
115
|
-
codex: ["gpt-5.4", "gpt-5.5", "o3", "o4-mini"],
|
|
115
|
+
codex: ["gpt-5.4", "gpt-5.5", "gpt-5.3-codex-spark", "o3", "o4-mini"],
|
|
116
116
|
opencode: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4", "google/gemini-2.5-pro", "deepseek/deepseek-r3", "minimax/minimax-m2.5"]
|
|
117
117
|
};
|
|
118
118
|
var RUNTIME_LABELS = {
|
package/dist/lib/exe-daemon.js
CHANGED
|
@@ -773,7 +773,7 @@ var init_agent_config = __esm({
|
|
|
773
773
|
AGENT_CONFIG_PATH = path3.join(EXE_AI_DIR, "agent-config.json");
|
|
774
774
|
KNOWN_RUNTIMES = {
|
|
775
775
|
claude: ["claude-opus-4", "claude-sonnet-4", "claude-haiku-4.5"],
|
|
776
|
-
codex: ["gpt-5.4", "gpt-5.5", "o3", "o4-mini"],
|
|
776
|
+
codex: ["gpt-5.4", "gpt-5.5", "gpt-5.3-codex-spark", "o3", "o4-mini"],
|
|
777
777
|
opencode: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4", "google/gemini-2.5-pro", "deepseek/deepseek-r3", "minimax/minimax-m2.5"]
|
|
778
778
|
};
|
|
779
779
|
RUNTIME_LABELS = {
|
|
@@ -792,6 +792,7 @@ var init_agent_config = __esm({
|
|
|
792
792
|
// src/lib/intercom-queue.ts
|
|
793
793
|
var intercom_queue_exports = {};
|
|
794
794
|
__export(intercom_queue_exports, {
|
|
795
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
795
796
|
drainForSession: () => drainForSession,
|
|
796
797
|
drainQueue: () => drainQueue,
|
|
797
798
|
queueIntercom: () => queueIntercom,
|
|
@@ -883,6 +884,15 @@ function drainForSession(targetSession, sendKeys) {
|
|
|
883
884
|
}
|
|
884
885
|
return false;
|
|
885
886
|
}
|
|
887
|
+
function clearQueueForAgent(agentName) {
|
|
888
|
+
const queue = readQueue();
|
|
889
|
+
const before = queue.length;
|
|
890
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
891
|
+
if (filtered.length < before) {
|
|
892
|
+
writeQueue(filtered);
|
|
893
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
886
896
|
function logQueue(msg) {
|
|
887
897
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
888
898
|
`;
|
|
@@ -3507,6 +3517,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
3507
3517
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
3508
3518
|
} catch {
|
|
3509
3519
|
}
|
|
3520
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
3521
|
+
try {
|
|
3522
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
3523
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
3524
|
+
} catch {
|
|
3525
|
+
}
|
|
3526
|
+
}
|
|
3510
3527
|
try {
|
|
3511
3528
|
await writeCheckpoint({
|
|
3512
3529
|
taskId,
|
package/dist/lib/tasks.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
|
};
|
|
@@ -744,6 +750,14 @@ var init_agent_config = __esm({
|
|
|
744
750
|
});
|
|
745
751
|
|
|
746
752
|
// src/lib/intercom-queue.ts
|
|
753
|
+
var intercom_queue_exports = {};
|
|
754
|
+
__export(intercom_queue_exports, {
|
|
755
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
756
|
+
drainForSession: () => drainForSession,
|
|
757
|
+
drainQueue: () => drainQueue,
|
|
758
|
+
queueIntercom: () => queueIntercom,
|
|
759
|
+
readQueue: () => readQueue
|
|
760
|
+
});
|
|
747
761
|
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
|
|
748
762
|
import path6 from "path";
|
|
749
763
|
import os5 from "os";
|
|
@@ -782,11 +796,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
782
796
|
}
|
|
783
797
|
writeQueue(queue);
|
|
784
798
|
}
|
|
785
|
-
|
|
799
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
800
|
+
const queue = readQueue();
|
|
801
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
802
|
+
const remaining = [];
|
|
803
|
+
let drained = 0;
|
|
804
|
+
let failed = 0;
|
|
805
|
+
for (const item of queue) {
|
|
806
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
807
|
+
if (age > TTL_MS) {
|
|
808
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
809
|
+
failed++;
|
|
810
|
+
continue;
|
|
811
|
+
}
|
|
812
|
+
try {
|
|
813
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
814
|
+
const success = sendKeys(item.targetSession);
|
|
815
|
+
if (success) {
|
|
816
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
817
|
+
drained++;
|
|
818
|
+
continue;
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
} catch {
|
|
822
|
+
}
|
|
823
|
+
item.attempts++;
|
|
824
|
+
if (item.attempts >= MAX_RETRIES) {
|
|
825
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES} retries exhausted, reason: ${item.reason})`);
|
|
826
|
+
failed++;
|
|
827
|
+
continue;
|
|
828
|
+
}
|
|
829
|
+
remaining.push(item);
|
|
830
|
+
}
|
|
831
|
+
writeQueue(remaining);
|
|
832
|
+
return { drained, failed };
|
|
833
|
+
}
|
|
834
|
+
function drainForSession(targetSession, sendKeys) {
|
|
835
|
+
const queue = readQueue();
|
|
836
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
837
|
+
if (match < 0) return false;
|
|
838
|
+
const success = sendKeys(targetSession);
|
|
839
|
+
if (success) {
|
|
840
|
+
queue.splice(match, 1);
|
|
841
|
+
writeQueue(queue);
|
|
842
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
843
|
+
return true;
|
|
844
|
+
}
|
|
845
|
+
return false;
|
|
846
|
+
}
|
|
847
|
+
function clearQueueForAgent(agentName) {
|
|
848
|
+
const queue = readQueue();
|
|
849
|
+
const before = queue.length;
|
|
850
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
851
|
+
if (filtered.length < before) {
|
|
852
|
+
writeQueue(filtered);
|
|
853
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
function logQueue(msg) {
|
|
857
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
858
|
+
`;
|
|
859
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
860
|
+
`);
|
|
861
|
+
try {
|
|
862
|
+
const { appendFileSync: appendFileSync2 } = __require("fs");
|
|
863
|
+
appendFileSync2(INTERCOM_LOG, line);
|
|
864
|
+
} catch {
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
|
|
786
868
|
var init_intercom_queue = __esm({
|
|
787
869
|
"src/lib/intercom-queue.ts"() {
|
|
788
870
|
"use strict";
|
|
789
871
|
QUEUE_PATH = path6.join(os5.homedir(), ".exe-os", "intercom-queue.json");
|
|
872
|
+
MAX_RETRIES = 5;
|
|
790
873
|
TTL_MS = 60 * 60 * 1e3;
|
|
791
874
|
INTERCOM_LOG = path6.join(os5.homedir(), ".exe-os", "intercom.log");
|
|
792
875
|
}
|
|
@@ -2480,6 +2563,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
2480
2563
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
2481
2564
|
} catch {
|
|
2482
2565
|
}
|
|
2566
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
2567
|
+
try {
|
|
2568
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
2569
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
2570
|
+
} catch {
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2483
2573
|
try {
|
|
2484
2574
|
await writeCheckpoint({
|
|
2485
2575
|
taskId,
|
package/dist/lib/tmux-routing.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
|
};
|
|
@@ -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
|
}
|
|
@@ -1443,6 +1526,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
1443
1526
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
1444
1527
|
} catch {
|
|
1445
1528
|
}
|
|
1529
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
1530
|
+
try {
|
|
1531
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
1532
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
1533
|
+
} catch {
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1446
1536
|
try {
|
|
1447
1537
|
await writeCheckpoint({
|
|
1448
1538
|
taskId,
|