@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
package/dist/bin/cli.js
CHANGED
|
@@ -749,6 +749,10 @@ async function cleanSettingsJsonMcp(settingsPath) {
|
|
|
749
749
|
}
|
|
750
750
|
async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
751
751
|
const settingsPath = path5.join(homeDir, ".claude", "settings.json");
|
|
752
|
+
const logsDir = path5.join(homeDir, ".exe-os", "logs");
|
|
753
|
+
const hookLogPath = path5.join(logsDir, "hooks.log");
|
|
754
|
+
const logSuffix = ` 2>> "${hookLogPath}"`;
|
|
755
|
+
await mkdir3(logsDir, { recursive: true });
|
|
752
756
|
let settings = {};
|
|
753
757
|
if (existsSync5(settingsPath)) {
|
|
754
758
|
try {
|
|
@@ -772,11 +776,11 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
772
776
|
hooks: [
|
|
773
777
|
{
|
|
774
778
|
type: "command",
|
|
775
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "ingest.js")}"`
|
|
779
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "ingest.js")}"${logSuffix}`
|
|
776
780
|
},
|
|
777
781
|
{
|
|
778
782
|
type: "command",
|
|
779
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "error-recall.js")}"`
|
|
783
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "error-recall.js")}"${logSuffix}`
|
|
780
784
|
}
|
|
781
785
|
]
|
|
782
786
|
},
|
|
@@ -788,7 +792,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
788
792
|
hooks: [
|
|
789
793
|
{
|
|
790
794
|
type: "command",
|
|
791
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "session-start.js")}"`,
|
|
795
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
|
|
792
796
|
timeout: 1e4
|
|
793
797
|
}
|
|
794
798
|
]
|
|
@@ -801,7 +805,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
801
805
|
hooks: [
|
|
802
806
|
{
|
|
803
807
|
type: "command",
|
|
804
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"`
|
|
808
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
|
|
805
809
|
}
|
|
806
810
|
]
|
|
807
811
|
},
|
|
@@ -813,7 +817,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
813
817
|
hooks: [
|
|
814
818
|
{
|
|
815
819
|
type: "command",
|
|
816
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"`,
|
|
820
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
|
|
817
821
|
timeout: 5e3
|
|
818
822
|
}
|
|
819
823
|
]
|
|
@@ -826,7 +830,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
826
830
|
hooks: [
|
|
827
831
|
{
|
|
828
832
|
type: "command",
|
|
829
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "stop.js")}"`
|
|
833
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
|
|
830
834
|
}
|
|
831
835
|
]
|
|
832
836
|
},
|
|
@@ -839,7 +843,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
839
843
|
hooks: [
|
|
840
844
|
{
|
|
841
845
|
type: "command",
|
|
842
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"`
|
|
846
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
|
|
843
847
|
}
|
|
844
848
|
]
|
|
845
849
|
},
|
|
@@ -851,7 +855,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
851
855
|
hooks: [
|
|
852
856
|
{
|
|
853
857
|
type: "command",
|
|
854
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"`
|
|
858
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"${logSuffix}`
|
|
855
859
|
}
|
|
856
860
|
]
|
|
857
861
|
},
|
|
@@ -863,7 +867,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
863
867
|
hooks: [
|
|
864
868
|
{
|
|
865
869
|
type: "command",
|
|
866
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "pre-compact.js")}"`,
|
|
870
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "pre-compact.js")}"${logSuffix}`,
|
|
867
871
|
timeout: 1e4
|
|
868
872
|
}
|
|
869
873
|
]
|
|
@@ -876,7 +880,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
876
880
|
hooks: [
|
|
877
881
|
{
|
|
878
882
|
type: "command",
|
|
879
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "session-end.js")}"`
|
|
883
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "session-end.js")}"${logSuffix}`
|
|
880
884
|
}
|
|
881
885
|
]
|
|
882
886
|
},
|
|
@@ -888,7 +892,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
888
892
|
hooks: [
|
|
889
893
|
{
|
|
890
894
|
type: "command",
|
|
891
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "notification.js")}"`
|
|
895
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "notification.js")}"${logSuffix}`
|
|
892
896
|
}
|
|
893
897
|
]
|
|
894
898
|
},
|
|
@@ -900,7 +904,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
900
904
|
hooks: [
|
|
901
905
|
{
|
|
902
906
|
type: "command",
|
|
903
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "post-compact.js")}"`,
|
|
907
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "post-compact.js")}"${logSuffix}`,
|
|
904
908
|
timeout: 1e4
|
|
905
909
|
}
|
|
906
910
|
]
|
|
@@ -913,7 +917,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
|
|
|
913
917
|
hooks: [
|
|
914
918
|
{
|
|
915
919
|
type: "command",
|
|
916
|
-
command: `node "${path5.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"`
|
|
920
|
+
command: `node "${path5.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"${logSuffix}`
|
|
917
921
|
}
|
|
918
922
|
]
|
|
919
923
|
},
|
|
@@ -3940,21 +3944,21 @@ async function withRosterLock(fn) {
|
|
|
3940
3944
|
}
|
|
3941
3945
|
}
|
|
3942
3946
|
async function fetchWithRetry(url, init) {
|
|
3943
|
-
const
|
|
3947
|
+
const MAX_RETRIES4 = 3;
|
|
3944
3948
|
const BASE_DELAY_MS2 = 200;
|
|
3945
3949
|
let lastError;
|
|
3946
|
-
for (let attempt = 0; attempt <=
|
|
3950
|
+
for (let attempt = 0; attempt <= MAX_RETRIES4; attempt++) {
|
|
3947
3951
|
try {
|
|
3948
3952
|
const signal = AbortSignal.timeout(FETCH_TIMEOUT_MS);
|
|
3949
3953
|
const resp = await fetch(url, { ...init, signal });
|
|
3950
|
-
if (resp && resp.status >= 500 && attempt <
|
|
3954
|
+
if (resp && resp.status >= 500 && attempt < MAX_RETRIES4) {
|
|
3951
3955
|
await new Promise((r) => setTimeout(r, BASE_DELAY_MS2 * Math.pow(2, attempt)));
|
|
3952
3956
|
continue;
|
|
3953
3957
|
}
|
|
3954
3958
|
return resp;
|
|
3955
3959
|
} catch (err) {
|
|
3956
3960
|
lastError = err;
|
|
3957
|
-
if (attempt ===
|
|
3961
|
+
if (attempt === MAX_RETRIES4) throw err;
|
|
3958
3962
|
await new Promise((r) => setTimeout(r, BASE_DELAY_MS2 * Math.pow(2, attempt)));
|
|
3959
3963
|
}
|
|
3960
3964
|
}
|
|
@@ -7583,6 +7587,14 @@ var init_agent_config = __esm({
|
|
|
7583
7587
|
});
|
|
7584
7588
|
|
|
7585
7589
|
// src/lib/intercom-queue.ts
|
|
7590
|
+
var intercom_queue_exports = {};
|
|
7591
|
+
__export(intercom_queue_exports, {
|
|
7592
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
7593
|
+
drainForSession: () => drainForSession,
|
|
7594
|
+
drainQueue: () => drainQueue,
|
|
7595
|
+
queueIntercom: () => queueIntercom,
|
|
7596
|
+
readQueue: () => readQueue
|
|
7597
|
+
});
|
|
7586
7598
|
import { readFileSync as readFileSync11, writeFileSync as writeFileSync9, renameSync as renameSync3, existsSync as existsSync14, mkdirSync as mkdirSync10 } from "fs";
|
|
7587
7599
|
import path15 from "path";
|
|
7588
7600
|
import os9 from "os";
|
|
@@ -7621,11 +7633,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
7621
7633
|
}
|
|
7622
7634
|
writeQueue(queue);
|
|
7623
7635
|
}
|
|
7624
|
-
|
|
7636
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
7637
|
+
const queue = readQueue();
|
|
7638
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
7639
|
+
const remaining = [];
|
|
7640
|
+
let drained = 0;
|
|
7641
|
+
let failed = 0;
|
|
7642
|
+
for (const item of queue) {
|
|
7643
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
7644
|
+
if (age > TTL_MS) {
|
|
7645
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
7646
|
+
failed++;
|
|
7647
|
+
continue;
|
|
7648
|
+
}
|
|
7649
|
+
try {
|
|
7650
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
7651
|
+
const success = sendKeys(item.targetSession);
|
|
7652
|
+
if (success) {
|
|
7653
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
7654
|
+
drained++;
|
|
7655
|
+
continue;
|
|
7656
|
+
}
|
|
7657
|
+
}
|
|
7658
|
+
} catch {
|
|
7659
|
+
}
|
|
7660
|
+
item.attempts++;
|
|
7661
|
+
if (item.attempts >= MAX_RETRIES2) {
|
|
7662
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES2} retries exhausted, reason: ${item.reason})`);
|
|
7663
|
+
failed++;
|
|
7664
|
+
continue;
|
|
7665
|
+
}
|
|
7666
|
+
remaining.push(item);
|
|
7667
|
+
}
|
|
7668
|
+
writeQueue(remaining);
|
|
7669
|
+
return { drained, failed };
|
|
7670
|
+
}
|
|
7671
|
+
function drainForSession(targetSession, sendKeys) {
|
|
7672
|
+
const queue = readQueue();
|
|
7673
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
7674
|
+
if (match < 0) return false;
|
|
7675
|
+
const success = sendKeys(targetSession);
|
|
7676
|
+
if (success) {
|
|
7677
|
+
queue.splice(match, 1);
|
|
7678
|
+
writeQueue(queue);
|
|
7679
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
7680
|
+
return true;
|
|
7681
|
+
}
|
|
7682
|
+
return false;
|
|
7683
|
+
}
|
|
7684
|
+
function clearQueueForAgent(agentName) {
|
|
7685
|
+
const queue = readQueue();
|
|
7686
|
+
const before = queue.length;
|
|
7687
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
7688
|
+
if (filtered.length < before) {
|
|
7689
|
+
writeQueue(filtered);
|
|
7690
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
7691
|
+
}
|
|
7692
|
+
}
|
|
7693
|
+
function logQueue(msg) {
|
|
7694
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
7695
|
+
`;
|
|
7696
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
7697
|
+
`);
|
|
7698
|
+
try {
|
|
7699
|
+
const { appendFileSync: appendFileSync3 } = __require("fs");
|
|
7700
|
+
appendFileSync3(INTERCOM_LOG, line);
|
|
7701
|
+
} catch {
|
|
7702
|
+
}
|
|
7703
|
+
}
|
|
7704
|
+
var QUEUE_PATH, MAX_RETRIES2, TTL_MS, INTERCOM_LOG;
|
|
7625
7705
|
var init_intercom_queue = __esm({
|
|
7626
7706
|
"src/lib/intercom-queue.ts"() {
|
|
7627
7707
|
"use strict";
|
|
7628
7708
|
QUEUE_PATH = path15.join(os9.homedir(), ".exe-os", "intercom-queue.json");
|
|
7709
|
+
MAX_RETRIES2 = 5;
|
|
7629
7710
|
TTL_MS = 60 * 60 * 1e3;
|
|
7630
7711
|
INTERCOM_LOG = path15.join(os9.homedir(), ".exe-os", "intercom.log");
|
|
7631
7712
|
}
|
|
@@ -8332,6 +8413,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
8332
8413
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
8333
8414
|
} catch {
|
|
8334
8415
|
}
|
|
8416
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
8417
|
+
try {
|
|
8418
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
8419
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
8420
|
+
} catch {
|
|
8421
|
+
}
|
|
8422
|
+
}
|
|
8335
8423
|
try {
|
|
8336
8424
|
await writeCheckpoint({
|
|
8337
8425
|
taskId,
|
|
@@ -10571,7 +10659,7 @@ async function deliverLocalMessage(messageId) {
|
|
|
10571
10659
|
return true;
|
|
10572
10660
|
} catch {
|
|
10573
10661
|
const newRetryCount = msg.retryCount + 1;
|
|
10574
|
-
if (newRetryCount >=
|
|
10662
|
+
if (newRetryCount >= MAX_RETRIES3) {
|
|
10575
10663
|
await markFailed(messageId, "session unavailable after 10 retries");
|
|
10576
10664
|
} else {
|
|
10577
10665
|
await client.execute({
|
|
@@ -10660,7 +10748,7 @@ async function retryPendingMessages() {
|
|
|
10660
10748
|
sql: `SELECT * FROM messages
|
|
10661
10749
|
WHERE status = 'pending' AND retry_count < ?
|
|
10662
10750
|
ORDER BY id`,
|
|
10663
|
-
args: [
|
|
10751
|
+
args: [MAX_RETRIES3]
|
|
10664
10752
|
});
|
|
10665
10753
|
let delivered = 0;
|
|
10666
10754
|
for (const row of result.rows) {
|
|
@@ -10673,13 +10761,13 @@ async function retryPendingMessages() {
|
|
|
10673
10761
|
}
|
|
10674
10762
|
return delivered;
|
|
10675
10763
|
}
|
|
10676
|
-
var
|
|
10764
|
+
var MAX_RETRIES3, _wsClientSend;
|
|
10677
10765
|
var init_messaging = __esm({
|
|
10678
10766
|
"src/lib/messaging.ts"() {
|
|
10679
10767
|
"use strict";
|
|
10680
10768
|
init_database();
|
|
10681
10769
|
init_tmux_routing();
|
|
10682
|
-
|
|
10770
|
+
MAX_RETRIES3 = 10;
|
|
10683
10771
|
_wsClientSend = null;
|
|
10684
10772
|
}
|
|
10685
10773
|
});
|
|
@@ -11692,11 +11780,11 @@ async function downloadModel(opts) {
|
|
|
11692
11780
|
return destPath;
|
|
11693
11781
|
}
|
|
11694
11782
|
}
|
|
11695
|
-
const
|
|
11783
|
+
const MAX_RETRIES4 = 3;
|
|
11696
11784
|
const DOWNLOAD_TIMEOUT_MS = 3e5;
|
|
11697
11785
|
let lastErr;
|
|
11698
11786
|
let downloaded = 0;
|
|
11699
|
-
for (let attempt = 1; attempt <=
|
|
11787
|
+
for (let attempt = 1; attempt <= MAX_RETRIES4; attempt++) {
|
|
11700
11788
|
try {
|
|
11701
11789
|
if (existsSync21(tmpPath)) unlinkSync11(tmpPath);
|
|
11702
11790
|
const response = await fetchFn(GGUF_URL, {
|
|
@@ -11739,7 +11827,7 @@ async function downloadModel(opts) {
|
|
|
11739
11827
|
return destPath;
|
|
11740
11828
|
} catch (err) {
|
|
11741
11829
|
lastErr = err instanceof Error ? err : new Error(String(err));
|
|
11742
|
-
if (attempt <
|
|
11830
|
+
if (attempt < MAX_RETRIES4) {
|
|
11743
11831
|
process.stderr.write(`
|
|
11744
11832
|
Download attempt ${attempt} failed, retrying...
|
|
11745
11833
|
`);
|
|
@@ -13467,10 +13555,11 @@ async function runUpdate(cliArgs) {
|
|
|
13467
13555
|
console.log(" Skipped (non-critical)");
|
|
13468
13556
|
}
|
|
13469
13557
|
console.log("\u{1F4E5} Installing @askexenow/exe-os@latest...");
|
|
13558
|
+
console.log(" This may take a minute...\n");
|
|
13470
13559
|
try {
|
|
13471
13560
|
execSync12("npm install -g @askexenow/exe-os@latest", {
|
|
13472
|
-
stdio: ["pipe", "pipe", "
|
|
13473
|
-
timeout:
|
|
13561
|
+
stdio: ["pipe", "pipe", "inherit"],
|
|
13562
|
+
timeout: 3e5
|
|
13474
13563
|
});
|
|
13475
13564
|
} catch (err) {
|
|
13476
13565
|
console.error("\n\u274C Update failed.");
|
|
@@ -27838,7 +27927,11 @@ import os16 from "os";
|
|
|
27838
27927
|
async function mergeCodexHooks(packageRoot, homeDir = os16.homedir()) {
|
|
27839
27928
|
const codexDir = path40.join(homeDir, ".codex");
|
|
27840
27929
|
const hooksPath = path40.join(codexDir, "hooks.json");
|
|
27930
|
+
const logsDir = path40.join(homeDir, ".exe-os", "logs");
|
|
27931
|
+
const hookLogPath = path40.join(logsDir, "hooks.log");
|
|
27932
|
+
const logSuffix = ` 2>> "${hookLogPath}"`;
|
|
27841
27933
|
await mkdir8(codexDir, { recursive: true });
|
|
27934
|
+
await mkdir8(logsDir, { recursive: true });
|
|
27842
27935
|
let hooksJson = {};
|
|
27843
27936
|
if (existsSync27(hooksPath)) {
|
|
27844
27937
|
try {
|
|
@@ -27857,7 +27950,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os16.homedir()) {
|
|
|
27857
27950
|
hooks: [
|
|
27858
27951
|
{
|
|
27859
27952
|
type: "command",
|
|
27860
|
-
command: `node "${path40.join(packageRoot, "dist", "hooks", "session-start.js")}"`,
|
|
27953
|
+
command: `node "${path40.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
|
|
27861
27954
|
timeout: 30,
|
|
27862
27955
|
statusMessage: "exe-os: loading memory brief"
|
|
27863
27956
|
}
|
|
@@ -27872,11 +27965,11 @@ async function mergeCodexHooks(packageRoot, homeDir = os16.homedir()) {
|
|
|
27872
27965
|
hooks: [
|
|
27873
27966
|
{
|
|
27874
27967
|
type: "command",
|
|
27875
|
-
command: `node "${path40.join(packageRoot, "dist", "hooks", "ingest.js")}"`
|
|
27968
|
+
command: `node "${path40.join(packageRoot, "dist", "hooks", "ingest.js")}"${logSuffix}`
|
|
27876
27969
|
},
|
|
27877
27970
|
{
|
|
27878
27971
|
type: "command",
|
|
27879
|
-
command: `node "${path40.join(packageRoot, "dist", "hooks", "error-recall.js")}"`
|
|
27972
|
+
command: `node "${path40.join(packageRoot, "dist", "hooks", "error-recall.js")}"${logSuffix}`
|
|
27880
27973
|
}
|
|
27881
27974
|
]
|
|
27882
27975
|
},
|
|
@@ -27888,11 +27981,11 @@ async function mergeCodexHooks(packageRoot, homeDir = os16.homedir()) {
|
|
|
27888
27981
|
hooks: [
|
|
27889
27982
|
{
|
|
27890
27983
|
type: "command",
|
|
27891
|
-
command: `node "${path40.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"`
|
|
27984
|
+
command: `node "${path40.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
|
|
27892
27985
|
},
|
|
27893
27986
|
{
|
|
27894
27987
|
type: "command",
|
|
27895
|
-
command: `node "${path40.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"`,
|
|
27988
|
+
command: `node "${path40.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
|
|
27896
27989
|
timeout: 5
|
|
27897
27990
|
}
|
|
27898
27991
|
]
|
|
@@ -27905,7 +27998,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os16.homedir()) {
|
|
|
27905
27998
|
hooks: [
|
|
27906
27999
|
{
|
|
27907
28000
|
type: "command",
|
|
27908
|
-
command: `node "${path40.join(packageRoot, "dist", "hooks", "stop.js")}"`
|
|
28001
|
+
command: `node "${path40.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
|
|
27909
28002
|
}
|
|
27910
28003
|
]
|
|
27911
28004
|
},
|
|
@@ -27918,7 +28011,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os16.homedir()) {
|
|
|
27918
28011
|
hooks: [
|
|
27919
28012
|
{
|
|
27920
28013
|
type: "command",
|
|
27921
|
-
command: `node "${path40.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"`
|
|
28014
|
+
command: `node "${path40.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
|
|
27922
28015
|
}
|
|
27923
28016
|
]
|
|
27924
28017
|
},
|
|
@@ -114,7 +114,7 @@ var DEFAULT_RUNTIME = "claude";
|
|
|
114
114
|
var AGENT_CONFIG_PATH = path2.join(EXE_AI_DIR, "agent-config.json");
|
|
115
115
|
var KNOWN_RUNTIMES = {
|
|
116
116
|
claude: ["claude-opus-4", "claude-sonnet-4", "claude-haiku-4.5"],
|
|
117
|
-
codex: ["gpt-5.4", "gpt-5.5", "o3", "o4-mini"],
|
|
117
|
+
codex: ["gpt-5.4", "gpt-5.5", "gpt-5.3-codex-spark", "o3", "o4-mini"],
|
|
118
118
|
opencode: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4", "google/gemini-2.5-pro", "deepseek/deepseek-r3", "minimax/minimax-m2.5"]
|
|
119
119
|
};
|
|
120
120
|
var DEFAULT_MODELS = {
|
package/dist/bin/exe-boot.js
CHANGED
|
@@ -2994,6 +2994,14 @@ var init_agent_config = __esm({
|
|
|
2994
2994
|
});
|
|
2995
2995
|
|
|
2996
2996
|
// src/lib/intercom-queue.ts
|
|
2997
|
+
var intercom_queue_exports = {};
|
|
2998
|
+
__export(intercom_queue_exports, {
|
|
2999
|
+
clearQueueForAgent: () => clearQueueForAgent,
|
|
3000
|
+
drainForSession: () => drainForSession,
|
|
3001
|
+
drainQueue: () => drainQueue,
|
|
3002
|
+
queueIntercom: () => queueIntercom,
|
|
3003
|
+
readQueue: () => readQueue
|
|
3004
|
+
});
|
|
2997
3005
|
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync8, mkdirSync as mkdirSync4 } from "fs";
|
|
2998
3006
|
import path8 from "path";
|
|
2999
3007
|
import os6 from "os";
|
|
@@ -3032,11 +3040,80 @@ function queueIntercom(targetSession, reason) {
|
|
|
3032
3040
|
}
|
|
3033
3041
|
writeQueue(queue);
|
|
3034
3042
|
}
|
|
3035
|
-
|
|
3043
|
+
function drainQueue(isSessionBusy2, sendKeys) {
|
|
3044
|
+
const queue = readQueue();
|
|
3045
|
+
if (queue.length === 0) return { drained: 0, failed: 0 };
|
|
3046
|
+
const remaining = [];
|
|
3047
|
+
let drained = 0;
|
|
3048
|
+
let failed = 0;
|
|
3049
|
+
for (const item of queue) {
|
|
3050
|
+
const age = Date.now() - new Date(item.queuedAt).getTime();
|
|
3051
|
+
if (age > TTL_MS) {
|
|
3052
|
+
logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
|
|
3053
|
+
failed++;
|
|
3054
|
+
continue;
|
|
3055
|
+
}
|
|
3056
|
+
try {
|
|
3057
|
+
if (!isSessionBusy2(item.targetSession)) {
|
|
3058
|
+
const success = sendKeys(item.targetSession);
|
|
3059
|
+
if (success) {
|
|
3060
|
+
logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
|
|
3061
|
+
drained++;
|
|
3062
|
+
continue;
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
} catch {
|
|
3066
|
+
}
|
|
3067
|
+
item.attempts++;
|
|
3068
|
+
if (item.attempts >= MAX_RETRIES2) {
|
|
3069
|
+
logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES2} retries exhausted, reason: ${item.reason})`);
|
|
3070
|
+
failed++;
|
|
3071
|
+
continue;
|
|
3072
|
+
}
|
|
3073
|
+
remaining.push(item);
|
|
3074
|
+
}
|
|
3075
|
+
writeQueue(remaining);
|
|
3076
|
+
return { drained, failed };
|
|
3077
|
+
}
|
|
3078
|
+
function drainForSession(targetSession, sendKeys) {
|
|
3079
|
+
const queue = readQueue();
|
|
3080
|
+
const match = queue.findIndex((q) => q.targetSession === targetSession);
|
|
3081
|
+
if (match < 0) return false;
|
|
3082
|
+
const success = sendKeys(targetSession);
|
|
3083
|
+
if (success) {
|
|
3084
|
+
queue.splice(match, 1);
|
|
3085
|
+
writeQueue(queue);
|
|
3086
|
+
logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
|
|
3087
|
+
return true;
|
|
3088
|
+
}
|
|
3089
|
+
return false;
|
|
3090
|
+
}
|
|
3091
|
+
function clearQueueForAgent(agentName) {
|
|
3092
|
+
const queue = readQueue();
|
|
3093
|
+
const before = queue.length;
|
|
3094
|
+
const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
|
|
3095
|
+
if (filtered.length < before) {
|
|
3096
|
+
writeQueue(filtered);
|
|
3097
|
+
logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
|
|
3098
|
+
}
|
|
3099
|
+
}
|
|
3100
|
+
function logQueue(msg) {
|
|
3101
|
+
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
|
|
3102
|
+
`;
|
|
3103
|
+
process.stderr.write(`[intercom-queue] ${msg}
|
|
3104
|
+
`);
|
|
3105
|
+
try {
|
|
3106
|
+
const { appendFileSync: appendFileSync3 } = __require("fs");
|
|
3107
|
+
appendFileSync3(INTERCOM_LOG, line);
|
|
3108
|
+
} catch {
|
|
3109
|
+
}
|
|
3110
|
+
}
|
|
3111
|
+
var QUEUE_PATH, MAX_RETRIES2, TTL_MS, INTERCOM_LOG;
|
|
3036
3112
|
var init_intercom_queue = __esm({
|
|
3037
3113
|
"src/lib/intercom-queue.ts"() {
|
|
3038
3114
|
"use strict";
|
|
3039
3115
|
QUEUE_PATH = path8.join(os6.homedir(), ".exe-os", "intercom-queue.json");
|
|
3116
|
+
MAX_RETRIES2 = 5;
|
|
3040
3117
|
TTL_MS = 60 * 60 * 1e3;
|
|
3041
3118
|
INTERCOM_LOG = path8.join(os6.homedir(), ".exe-os", "intercom.log");
|
|
3042
3119
|
}
|
|
@@ -4276,6 +4353,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
|
|
|
4276
4353
|
await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
4277
4354
|
} catch {
|
|
4278
4355
|
}
|
|
4356
|
+
if (input.status === "done" || input.status === "cancelled") {
|
|
4357
|
+
try {
|
|
4358
|
+
const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
|
|
4359
|
+
clearQueueForAgent2(String(row.assigned_to));
|
|
4360
|
+
} catch {
|
|
4361
|
+
}
|
|
4362
|
+
}
|
|
4279
4363
|
try {
|
|
4280
4364
|
await writeCheckpoint({
|
|
4281
4365
|
taskId,
|
|
@@ -6919,21 +7003,21 @@ async function withRosterLock(fn) {
|
|
|
6919
7003
|
}
|
|
6920
7004
|
}
|
|
6921
7005
|
async function fetchWithRetry(url, init) {
|
|
6922
|
-
const
|
|
7006
|
+
const MAX_RETRIES3 = 3;
|
|
6923
7007
|
const BASE_DELAY_MS2 = 200;
|
|
6924
7008
|
let lastError;
|
|
6925
|
-
for (let attempt = 0; attempt <=
|
|
7009
|
+
for (let attempt = 0; attempt <= MAX_RETRIES3; attempt++) {
|
|
6926
7010
|
try {
|
|
6927
7011
|
const signal = AbortSignal.timeout(FETCH_TIMEOUT_MS);
|
|
6928
7012
|
const resp = await fetch(url, { ...init, signal });
|
|
6929
|
-
if (resp && resp.status >= 500 && attempt <
|
|
7013
|
+
if (resp && resp.status >= 500 && attempt < MAX_RETRIES3) {
|
|
6930
7014
|
await new Promise((r) => setTimeout(r, BASE_DELAY_MS2 * Math.pow(2, attempt)));
|
|
6931
7015
|
continue;
|
|
6932
7016
|
}
|
|
6933
7017
|
return resp;
|
|
6934
7018
|
} catch (err) {
|
|
6935
7019
|
lastError = err;
|
|
6936
|
-
if (attempt ===
|
|
7020
|
+
if (attempt === MAX_RETRIES3) throw err;
|
|
6937
7021
|
await new Promise((r) => setTimeout(r, BASE_DELAY_MS2 * Math.pow(2, attempt)));
|
|
6938
7022
|
}
|
|
6939
7023
|
}
|
package/dist/bin/exe-call.js
CHANGED
|
@@ -1178,7 +1178,7 @@ var init_agent_config = __esm({
|
|
|
1178
1178
|
AGENT_CONFIG_PATH = path3.join(EXE_AI_DIR, "agent-config.json");
|
|
1179
1179
|
KNOWN_RUNTIMES = {
|
|
1180
1180
|
claude: ["claude-opus-4", "claude-sonnet-4", "claude-haiku-4.5"],
|
|
1181
|
-
codex: ["gpt-5.4", "gpt-5.5", "o3", "o4-mini"],
|
|
1181
|
+
codex: ["gpt-5.4", "gpt-5.5", "gpt-5.3-codex-spark", "o3", "o4-mini"],
|
|
1182
1182
|
opencode: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4", "google/gemini-2.5-pro", "deepseek/deepseek-r3", "minimax/minimax-m2.5"]
|
|
1183
1183
|
};
|
|
1184
1184
|
RUNTIME_LABELS = {
|