@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
|
@@ -2085,7 +2085,11 @@ import os8 from "os";
|
|
|
2085
2085
|
async function mergeCodexHooks(packageRoot, homeDir = os8.homedir()) {
|
|
2086
2086
|
const codexDir = path10.join(homeDir, ".codex");
|
|
2087
2087
|
const hooksPath = path10.join(codexDir, "hooks.json");
|
|
2088
|
+
const logsDir = path10.join(homeDir, ".exe-os", "logs");
|
|
2089
|
+
const hookLogPath = path10.join(logsDir, "hooks.log");
|
|
2090
|
+
const logSuffix = ` 2>> "${hookLogPath}"`;
|
|
2088
2091
|
await mkdir5(codexDir, { recursive: true });
|
|
2092
|
+
await mkdir5(logsDir, { recursive: true });
|
|
2089
2093
|
let hooksJson = {};
|
|
2090
2094
|
if (existsSync9(hooksPath)) {
|
|
2091
2095
|
try {
|
|
@@ -2104,7 +2108,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os8.homedir()) {
|
|
|
2104
2108
|
hooks: [
|
|
2105
2109
|
{
|
|
2106
2110
|
type: "command",
|
|
2107
|
-
command: `node "${path10.join(packageRoot, "dist", "hooks", "session-start.js")}"`,
|
|
2111
|
+
command: `node "${path10.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
|
|
2108
2112
|
timeout: 30,
|
|
2109
2113
|
statusMessage: "exe-os: loading memory brief"
|
|
2110
2114
|
}
|
|
@@ -2119,11 +2123,11 @@ async function mergeCodexHooks(packageRoot, homeDir = os8.homedir()) {
|
|
|
2119
2123
|
hooks: [
|
|
2120
2124
|
{
|
|
2121
2125
|
type: "command",
|
|
2122
|
-
command: `node "${path10.join(packageRoot, "dist", "hooks", "ingest.js")}"`
|
|
2126
|
+
command: `node "${path10.join(packageRoot, "dist", "hooks", "ingest.js")}"${logSuffix}`
|
|
2123
2127
|
},
|
|
2124
2128
|
{
|
|
2125
2129
|
type: "command",
|
|
2126
|
-
command: `node "${path10.join(packageRoot, "dist", "hooks", "error-recall.js")}"`
|
|
2130
|
+
command: `node "${path10.join(packageRoot, "dist", "hooks", "error-recall.js")}"${logSuffix}`
|
|
2127
2131
|
}
|
|
2128
2132
|
]
|
|
2129
2133
|
},
|
|
@@ -2135,11 +2139,11 @@ async function mergeCodexHooks(packageRoot, homeDir = os8.homedir()) {
|
|
|
2135
2139
|
hooks: [
|
|
2136
2140
|
{
|
|
2137
2141
|
type: "command",
|
|
2138
|
-
command: `node "${path10.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"`
|
|
2142
|
+
command: `node "${path10.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
|
|
2139
2143
|
},
|
|
2140
2144
|
{
|
|
2141
2145
|
type: "command",
|
|
2142
|
-
command: `node "${path10.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"`,
|
|
2146
|
+
command: `node "${path10.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
|
|
2143
2147
|
timeout: 5
|
|
2144
2148
|
}
|
|
2145
2149
|
]
|
|
@@ -2152,7 +2156,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os8.homedir()) {
|
|
|
2152
2156
|
hooks: [
|
|
2153
2157
|
{
|
|
2154
2158
|
type: "command",
|
|
2155
|
-
command: `node "${path10.join(packageRoot, "dist", "hooks", "stop.js")}"`
|
|
2159
|
+
command: `node "${path10.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
|
|
2156
2160
|
}
|
|
2157
2161
|
]
|
|
2158
2162
|
},
|
|
@@ -2165,7 +2169,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os8.homedir()) {
|
|
|
2165
2169
|
hooks: [
|
|
2166
2170
|
{
|
|
2167
2171
|
type: "command",
|
|
2168
|
-
command: `node "${path10.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"`
|
|
2172
|
+
command: `node "${path10.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
|
|
2169
2173
|
}
|
|
2170
2174
|
]
|
|
2171
2175
|
},
|
|
@@ -2996,7 +3000,7 @@ async function main() {
|
|
|
2996
3000
|
if (promptPath) {
|
|
2997
3001
|
args.push("-c", `model_instructions_file="${promptPath}"`);
|
|
2998
3002
|
}
|
|
2999
|
-
args.push("You are an AI employee with exe-os MCP tools. DO NOT ask for confirmation \u2014 work autonomously. Immediately: 1) Call list_tasks to see your assigned tasks. 2) Call get_task on the highest priority open task. 3) Start working on it. 4) When done, call update_task with status done and a result summary.
|
|
3003
|
+
args.push("You are an AI employee with exe-os MCP tools. DO NOT ask for confirmation \u2014 work autonomously. Immediately: 1) Call list_tasks to see your assigned tasks. 2) Call get_task on the highest priority open task. 3) Start working on it. 4) When done, call update_task with status done and a result summary. 5) Check list_tasks again for the next task. 6) If NO open tasks remain, say 'All tasks complete. Standing by.' and STOP \u2014 do not explore the codebase, do not look for extra work, do not run reviews. Just stop and wait.");
|
|
3000
3004
|
process.stderr.write(
|
|
3001
3005
|
`[exe-start-codex] launching ${agent} on ${CODEX.binary} (${effectiveModel}) \u2014 interactive mode
|
|
3002
3006
|
`
|
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/bin/update.js
CHANGED
|
@@ -596,10 +596,11 @@ async function runUpdate(cliArgs) {
|
|
|
596
596
|
console.log(" Skipped (non-critical)");
|
|
597
597
|
}
|
|
598
598
|
console.log("\u{1F4E5} Installing @askexenow/exe-os@latest...");
|
|
599
|
+
console.log(" This may take a minute...\n");
|
|
599
600
|
try {
|
|
600
601
|
execSync2("npm install -g @askexenow/exe-os@latest", {
|
|
601
|
-
stdio: ["pipe", "pipe", "
|
|
602
|
-
timeout:
|
|
602
|
+
stdio: ["pipe", "pipe", "inherit"],
|
|
603
|
+
timeout: 3e5
|
|
603
604
|
});
|
|
604
605
|
} catch (err) {
|
|
605
606
|
console.error("\n\u274C Update failed.");
|
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
|
});
|