@askexenow/exe-os 0.9.19 → 0.9.20
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 +4 -5
- package/dist/bin/exe-boot.js +1 -5
- package/dist/bin/exe-dispatch.js +1 -5
- package/dist/bin/exe-gateway.js +15 -8
- package/dist/bin/exe-session-cleanup.js +1 -5
- package/dist/bin/git-sweep.js +1 -5
- package/dist/bin/install.js +8 -1
- package/dist/bin/intercom-check.js +1 -5
- package/dist/bin/scan-tasks.js +1 -5
- package/dist/bin/update.js +3 -0
- package/dist/gateway/index.js +20 -7
- package/dist/hooks/bug-report-worker.js +1 -5
- package/dist/hooks/commit-complete.js +1 -5
- package/dist/hooks/pre-compact.js +1 -5
- package/dist/hooks/prompt-submit.js +3 -6
- package/dist/hooks/session-end.js +1 -5
- package/dist/index.js +20 -7
- package/dist/lib/exe-daemon.js +1 -5
- package/dist/lib/tasks.js +1 -5
- package/dist/lib/tmux-routing.js +1 -5
- package/dist/mcp/server.js +29 -10
- package/dist/mcp/tools/create-task.js +1 -5
- package/dist/mcp/tools/update-task.js +1 -5
- package/dist/runtime/index.js +1 -5
- package/dist/tui/App.js +1 -5
- package/package.json +3 -3
package/dist/bin/cli.js
CHANGED
|
@@ -12333,11 +12333,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
12333
12333
|
if (pending instanceof Promise) {
|
|
12334
12334
|
pending.then((count) => {
|
|
12335
12335
|
if (count > 0) {
|
|
12336
|
-
|
|
12337
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
12338
|
-
{ timeout: 3e3 }
|
|
12339
|
-
);
|
|
12340
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
12336
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
12341
12337
|
}
|
|
12342
12338
|
}).catch(() => {
|
|
12343
12339
|
});
|
|
@@ -15623,6 +15619,9 @@ async function runUpdate(cliArgs) {
|
|
|
15623
15619
|
console.log(" Try: npm cache clean --force && npm install -g @askexenow/exe-os@latest");
|
|
15624
15620
|
}
|
|
15625
15621
|
console.log(" Hooks re-wired, daemon restarted automatically.");
|
|
15622
|
+
console.log("");
|
|
15623
|
+
console.log(" \x1B[33m\u26A1 Run /mcp in each active Claude Code session to pick up new tools.\x1B[0m");
|
|
15624
|
+
console.log(" \x1B[2m(MCP servers can't hot-reload \u2014 Claude Code needs to reconnect them.)\x1B[0m");
|
|
15626
15625
|
try {
|
|
15627
15626
|
const { existsSync: exists, readFileSync: readFile8 } = await import("fs");
|
|
15628
15627
|
const p = await import("path");
|
package/dist/bin/exe-boot.js
CHANGED
|
@@ -7551,11 +7551,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
7551
7551
|
if (pending instanceof Promise) {
|
|
7552
7552
|
pending.then((count) => {
|
|
7553
7553
|
if (count > 0) {
|
|
7554
|
-
|
|
7555
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
7556
|
-
{ timeout: 3e3 }
|
|
7557
|
-
);
|
|
7558
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
7554
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
7559
7555
|
}
|
|
7560
7556
|
}).catch(() => {
|
|
7561
7557
|
});
|
package/dist/bin/exe-dispatch.js
CHANGED
|
@@ -6131,11 +6131,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6131
6131
|
if (pending instanceof Promise) {
|
|
6132
6132
|
pending.then((count) => {
|
|
6133
6133
|
if (count > 0) {
|
|
6134
|
-
|
|
6135
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6136
|
-
{ timeout: 3e3 }
|
|
6137
|
-
);
|
|
6138
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
6134
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
6139
6135
|
}
|
|
6140
6136
|
}).catch(() => {
|
|
6141
6137
|
});
|
package/dist/bin/exe-gateway.js
CHANGED
|
@@ -10968,11 +10968,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
10968
10968
|
if (pending instanceof Promise) {
|
|
10969
10969
|
pending.then((count) => {
|
|
10970
10970
|
if (count > 0) {
|
|
10971
|
-
|
|
10972
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
10973
|
-
{ timeout: 3e3 }
|
|
10974
|
-
);
|
|
10975
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
10971
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
10976
10972
|
}
|
|
10977
10973
|
}).catch(() => {
|
|
10978
10974
|
});
|
|
@@ -12265,7 +12261,7 @@ var WebhookServer = class {
|
|
|
12265
12261
|
sendJson(res, 200, {
|
|
12266
12262
|
status: "ok",
|
|
12267
12263
|
uptime,
|
|
12268
|
-
|
|
12264
|
+
adapterCount: this.handlers.size
|
|
12269
12265
|
});
|
|
12270
12266
|
}
|
|
12271
12267
|
async handleQuery(req, res) {
|
|
@@ -12418,13 +12414,24 @@ function matchesChannel(msgChannel, matchChannel) {
|
|
|
12418
12414
|
const channels = Array.isArray(matchChannel) ? matchChannel : [matchChannel];
|
|
12419
12415
|
return channels.includes(msgChannel);
|
|
12420
12416
|
}
|
|
12417
|
+
var MAX_REGEX_LENGTH = 200;
|
|
12418
|
+
function safeRegExp(pattern, flags) {
|
|
12419
|
+
if (pattern.length > MAX_REGEX_LENGTH) return null;
|
|
12420
|
+
try {
|
|
12421
|
+
return new RegExp(pattern, flags);
|
|
12422
|
+
} catch {
|
|
12423
|
+
return null;
|
|
12424
|
+
}
|
|
12425
|
+
}
|
|
12421
12426
|
function matchesSender(msgSender, matchSender) {
|
|
12422
12427
|
if (!matchSender) return true;
|
|
12423
|
-
|
|
12428
|
+
const re = safeRegExp(matchSender);
|
|
12429
|
+
return re ? re.test(msgSender) : false;
|
|
12424
12430
|
}
|
|
12425
12431
|
function matchesTextPattern(msgText, matchPattern) {
|
|
12426
12432
|
if (!matchPattern) return true;
|
|
12427
|
-
|
|
12433
|
+
const re = safeRegExp(matchPattern, "i");
|
|
12434
|
+
return re ? re.test(msgText) : false;
|
|
12428
12435
|
}
|
|
12429
12436
|
function matchesRoute(msg, match) {
|
|
12430
12437
|
return matchesPlatform(msg.platform, match.platform) && matchesChannel(msg.channelId, match.channelId) && matchesSender(msg.senderId, match.senderId) && matchesTextPattern(msg.text, match.textPattern);
|
|
@@ -7264,11 +7264,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName2, taskTit
|
|
|
7264
7264
|
if (pending instanceof Promise) {
|
|
7265
7265
|
pending.then((count) => {
|
|
7266
7266
|
if (count > 0) {
|
|
7267
|
-
|
|
7268
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
7269
|
-
{ timeout: 3e3 }
|
|
7270
|
-
);
|
|
7271
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName2} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
7267
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName2} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
7272
7268
|
}
|
|
7273
7269
|
}).catch(() => {
|
|
7274
7270
|
});
|
package/dist/bin/git-sweep.js
CHANGED
|
@@ -6048,11 +6048,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6048
6048
|
if (pending instanceof Promise) {
|
|
6049
6049
|
pending.then((count) => {
|
|
6050
6050
|
if (count > 0) {
|
|
6051
|
-
|
|
6052
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6053
|
-
{ timeout: 3e3 }
|
|
6054
|
-
);
|
|
6055
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
6051
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
6056
6052
|
}
|
|
6057
6053
|
}).catch(() => {
|
|
6058
6054
|
});
|
package/dist/bin/install.js
CHANGED
|
@@ -1597,7 +1597,7 @@ var init_installer2 = __esm({
|
|
|
1597
1597
|
|
|
1598
1598
|
// src/bin/install.ts
|
|
1599
1599
|
init_installer();
|
|
1600
|
-
import { existsSync as existsSync10, readFileSync as readFileSync7, unlinkSync as unlinkSync3, readdirSync as readdirSync2, openSync, closeSync } from "fs";
|
|
1600
|
+
import { existsSync as existsSync10, readFileSync as readFileSync7, writeFileSync as writeFileSync6, unlinkSync as unlinkSync3, readdirSync as readdirSync2, openSync, closeSync } from "fs";
|
|
1601
1601
|
import { spawn, execSync as execSync3 } from "child_process";
|
|
1602
1602
|
import path9 from "path";
|
|
1603
1603
|
import os7 from "os";
|
|
@@ -1777,6 +1777,13 @@ function restartDaemon() {
|
|
|
1777
1777
|
}
|
|
1778
1778
|
} catch {
|
|
1779
1779
|
}
|
|
1780
|
+
try {
|
|
1781
|
+
const versionPath = path9.join(EXE_DIR, "mcp-version");
|
|
1782
|
+
writeFileSync6(versionPath, `deploy-${Date.now()}`);
|
|
1783
|
+
process.stderr.write(`exe-os: MCP version marker updated \u2014 servers will hot-reload within 10s
|
|
1784
|
+
`);
|
|
1785
|
+
} catch {
|
|
1786
|
+
}
|
|
1780
1787
|
try {
|
|
1781
1788
|
const wpDir = path9.join(EXE_DIR, "worker-pids");
|
|
1782
1789
|
if (existsSync10(wpDir)) {
|
|
@@ -7041,11 +7041,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
7041
7041
|
if (pending instanceof Promise) {
|
|
7042
7042
|
pending.then((count) => {
|
|
7043
7043
|
if (count > 0) {
|
|
7044
|
-
|
|
7045
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
7046
|
-
{ timeout: 3e3 }
|
|
7047
|
-
);
|
|
7048
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
7044
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
7049
7045
|
}
|
|
7050
7046
|
}).catch(() => {
|
|
7051
7047
|
});
|
package/dist/bin/scan-tasks.js
CHANGED
|
@@ -6119,11 +6119,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6119
6119
|
if (pending instanceof Promise) {
|
|
6120
6120
|
pending.then((count) => {
|
|
6121
6121
|
if (count > 0) {
|
|
6122
|
-
|
|
6123
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6124
|
-
{ timeout: 3e3 }
|
|
6125
|
-
);
|
|
6126
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
6122
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
6127
6123
|
}
|
|
6128
6124
|
}).catch(() => {
|
|
6129
6125
|
});
|
package/dist/bin/update.js
CHANGED
|
@@ -724,6 +724,9 @@ async function runUpdate(cliArgs) {
|
|
|
724
724
|
console.log(" Try: npm cache clean --force && npm install -g @askexenow/exe-os@latest");
|
|
725
725
|
}
|
|
726
726
|
console.log(" Hooks re-wired, daemon restarted automatically.");
|
|
727
|
+
console.log("");
|
|
728
|
+
console.log(" \x1B[33m\u26A1 Run /mcp in each active Claude Code session to pick up new tools.\x1B[0m");
|
|
729
|
+
console.log(" \x1B[2m(MCP servers can't hot-reload \u2014 Claude Code needs to reconnect them.)\x1B[0m");
|
|
727
730
|
try {
|
|
728
731
|
const { existsSync: exists, readFileSync: readFile2 } = await import("fs");
|
|
729
732
|
const p = await import("path");
|
package/dist/gateway/index.js
CHANGED
|
@@ -8884,11 +8884,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
8884
8884
|
if (pending instanceof Promise) {
|
|
8885
8885
|
pending.then((count) => {
|
|
8886
8886
|
if (count > 0) {
|
|
8887
|
-
|
|
8888
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
8889
|
-
{ timeout: 3e3 }
|
|
8890
|
-
);
|
|
8891
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
8887
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
8892
8888
|
}
|
|
8893
8889
|
}).catch(() => {
|
|
8894
8890
|
});
|
|
@@ -9552,13 +9548,24 @@ function matchesChannel(msgChannel, matchChannel) {
|
|
|
9552
9548
|
const channels = Array.isArray(matchChannel) ? matchChannel : [matchChannel];
|
|
9553
9549
|
return channels.includes(msgChannel);
|
|
9554
9550
|
}
|
|
9551
|
+
var MAX_REGEX_LENGTH = 200;
|
|
9552
|
+
function safeRegExp(pattern, flags) {
|
|
9553
|
+
if (pattern.length > MAX_REGEX_LENGTH) return null;
|
|
9554
|
+
try {
|
|
9555
|
+
return new RegExp(pattern, flags);
|
|
9556
|
+
} catch {
|
|
9557
|
+
return null;
|
|
9558
|
+
}
|
|
9559
|
+
}
|
|
9555
9560
|
function matchesSender(msgSender, matchSender) {
|
|
9556
9561
|
if (!matchSender) return true;
|
|
9557
|
-
|
|
9562
|
+
const re = safeRegExp(matchSender);
|
|
9563
|
+
return re ? re.test(msgSender) : false;
|
|
9558
9564
|
}
|
|
9559
9565
|
function matchesTextPattern(msgText, matchPattern) {
|
|
9560
9566
|
if (!matchPattern) return true;
|
|
9561
|
-
|
|
9567
|
+
const re = safeRegExp(matchPattern, "i");
|
|
9568
|
+
return re ? re.test(msgText) : false;
|
|
9562
9569
|
}
|
|
9563
9570
|
function matchesRoute(msg, match) {
|
|
9564
9571
|
return matchesPlatform(msg.platform, match.platform) && matchesChannel(msg.channelId, match.channelId) && matchesSender(msg.senderId, match.senderId) && matchesTextPattern(msg.text, match.textPattern);
|
|
@@ -9598,6 +9605,12 @@ function validateGatewayConfig(config2) {
|
|
|
9598
9605
|
if (!route.target) {
|
|
9599
9606
|
warnings.push(`Route "${route.name}" has no target employee`);
|
|
9600
9607
|
}
|
|
9608
|
+
if (route.match.senderId && !safeRegExp(route.match.senderId)) {
|
|
9609
|
+
warnings.push(`Route "${route.name}" has invalid senderId regex: ${route.match.senderId}`);
|
|
9610
|
+
}
|
|
9611
|
+
if (route.match.textPattern && !safeRegExp(route.match.textPattern, "i")) {
|
|
9612
|
+
warnings.push(`Route "${route.name}" has invalid textPattern regex: ${route.match.textPattern}`);
|
|
9613
|
+
}
|
|
9601
9614
|
const isEmptyMatch = !route.match.platform && !route.match.channelId && !route.match.senderId && !route.match.textPattern;
|
|
9602
9615
|
if (isEmptyMatch && config2.routes.indexOf(route) !== config2.routes.length - 1) {
|
|
9603
9616
|
warnings.push(
|
|
@@ -5315,11 +5315,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
5315
5315
|
if (pending instanceof Promise) {
|
|
5316
5316
|
pending.then((count) => {
|
|
5317
5317
|
if (count > 0) {
|
|
5318
|
-
|
|
5319
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
5320
|
-
{ timeout: 3e3 }
|
|
5321
|
-
);
|
|
5322
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
5318
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
5323
5319
|
}
|
|
5324
5320
|
}).catch(() => {
|
|
5325
5321
|
});
|
|
@@ -6047,11 +6047,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6047
6047
|
if (pending instanceof Promise) {
|
|
6048
6048
|
pending.then((count) => {
|
|
6049
6049
|
if (count > 0) {
|
|
6050
|
-
|
|
6051
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6052
|
-
{ timeout: 3e3 }
|
|
6053
|
-
);
|
|
6054
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
6050
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
6055
6051
|
}
|
|
6056
6052
|
}).catch(() => {
|
|
6057
6053
|
});
|
|
@@ -6031,11 +6031,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6031
6031
|
if (pending instanceof Promise) {
|
|
6032
6032
|
pending.then((count) => {
|
|
6033
6033
|
if (count > 0) {
|
|
6034
|
-
|
|
6035
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6036
|
-
{ timeout: 3e3 }
|
|
6037
|
-
);
|
|
6038
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
6034
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
6039
6035
|
}
|
|
6040
6036
|
}).catch(() => {
|
|
6041
6037
|
});
|
|
@@ -8585,11 +8585,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
8585
8585
|
if (pending instanceof Promise) {
|
|
8586
8586
|
pending.then((count) => {
|
|
8587
8587
|
if (count > 0) {
|
|
8588
|
-
|
|
8589
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
8590
|
-
{ timeout: 3e3 }
|
|
8591
|
-
);
|
|
8592
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
8588
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
8593
8589
|
}
|
|
8594
8590
|
}).catch(() => {
|
|
8595
8591
|
});
|
|
@@ -10152,7 +10148,8 @@ process.stdin.on("end", async () => {
|
|
|
10152
10148
|
transport.sendKeys(session, nudgeMsg);
|
|
10153
10149
|
if (rtConfig.runtime === "codex" || rtConfig.runtime === "opencode") {
|
|
10154
10150
|
try {
|
|
10155
|
-
|
|
10151
|
+
const { execFileSync: efs } = __require("child_process");
|
|
10152
|
+
efs("tmux", ["send-keys", "-t", session, "Tab"], { encoding: "utf8", timeout: 2e3 });
|
|
10156
10153
|
} catch {
|
|
10157
10154
|
}
|
|
10158
10155
|
}
|
|
@@ -6240,11 +6240,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6240
6240
|
if (pending instanceof Promise) {
|
|
6241
6241
|
pending.then((count) => {
|
|
6242
6242
|
if (count > 0) {
|
|
6243
|
-
|
|
6244
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6245
|
-
{ timeout: 3e3 }
|
|
6246
|
-
);
|
|
6247
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
6243
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
6248
6244
|
}
|
|
6249
6245
|
}).catch(() => {
|
|
6250
6246
|
});
|
package/dist/index.js
CHANGED
|
@@ -6420,11 +6420,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6420
6420
|
if (pending instanceof Promise) {
|
|
6421
6421
|
pending.then((count) => {
|
|
6422
6422
|
if (count > 0) {
|
|
6423
|
-
|
|
6424
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6425
|
-
{ timeout: 3e3 }
|
|
6426
|
-
);
|
|
6427
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
6423
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
6428
6424
|
}
|
|
6429
6425
|
}).catch(() => {
|
|
6430
6426
|
});
|
|
@@ -12299,13 +12295,24 @@ function matchesChannel(msgChannel, matchChannel) {
|
|
|
12299
12295
|
const channels = Array.isArray(matchChannel) ? matchChannel : [matchChannel];
|
|
12300
12296
|
return channels.includes(msgChannel);
|
|
12301
12297
|
}
|
|
12298
|
+
var MAX_REGEX_LENGTH = 200;
|
|
12299
|
+
function safeRegExp(pattern, flags) {
|
|
12300
|
+
if (pattern.length > MAX_REGEX_LENGTH) return null;
|
|
12301
|
+
try {
|
|
12302
|
+
return new RegExp(pattern, flags);
|
|
12303
|
+
} catch {
|
|
12304
|
+
return null;
|
|
12305
|
+
}
|
|
12306
|
+
}
|
|
12302
12307
|
function matchesSender(msgSender, matchSender) {
|
|
12303
12308
|
if (!matchSender) return true;
|
|
12304
|
-
|
|
12309
|
+
const re = safeRegExp(matchSender);
|
|
12310
|
+
return re ? re.test(msgSender) : false;
|
|
12305
12311
|
}
|
|
12306
12312
|
function matchesTextPattern(msgText, matchPattern) {
|
|
12307
12313
|
if (!matchPattern) return true;
|
|
12308
|
-
|
|
12314
|
+
const re = safeRegExp(matchPattern, "i");
|
|
12315
|
+
return re ? re.test(msgText) : false;
|
|
12309
12316
|
}
|
|
12310
12317
|
function matchesRoute(msg, match) {
|
|
12311
12318
|
return matchesPlatform(msg.platform, match.platform) && matchesChannel(msg.channelId, match.channelId) && matchesSender(msg.senderId, match.senderId) && matchesTextPattern(msg.text, match.textPattern);
|
|
@@ -12345,6 +12352,12 @@ function validateGatewayConfig(config2) {
|
|
|
12345
12352
|
if (!route.target) {
|
|
12346
12353
|
warnings.push(`Route "${route.name}" has no target employee`);
|
|
12347
12354
|
}
|
|
12355
|
+
if (route.match.senderId && !safeRegExp(route.match.senderId)) {
|
|
12356
|
+
warnings.push(`Route "${route.name}" has invalid senderId regex: ${route.match.senderId}`);
|
|
12357
|
+
}
|
|
12358
|
+
if (route.match.textPattern && !safeRegExp(route.match.textPattern, "i")) {
|
|
12359
|
+
warnings.push(`Route "${route.name}" has invalid textPattern regex: ${route.match.textPattern}`);
|
|
12360
|
+
}
|
|
12348
12361
|
const isEmptyMatch = !route.match.platform && !route.match.channelId && !route.match.senderId && !route.match.textPattern;
|
|
12349
12362
|
if (isEmptyMatch && config2.routes.indexOf(route) !== config2.routes.length - 1) {
|
|
12350
12363
|
warnings.push(
|
package/dist/lib/exe-daemon.js
CHANGED
|
@@ -8046,11 +8046,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
8046
8046
|
if (pending instanceof Promise) {
|
|
8047
8047
|
pending.then((count) => {
|
|
8048
8048
|
if (count > 0) {
|
|
8049
|
-
|
|
8050
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
8051
|
-
{ timeout: 3e3 }
|
|
8052
|
-
);
|
|
8053
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
8049
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
8054
8050
|
}
|
|
8055
8051
|
}).catch(() => {
|
|
8056
8052
|
});
|
package/dist/lib/tasks.js
CHANGED
|
@@ -2142,11 +2142,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
2142
2142
|
if (pending instanceof Promise) {
|
|
2143
2143
|
pending.then((count) => {
|
|
2144
2144
|
if (count > 0) {
|
|
2145
|
-
|
|
2146
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
2147
|
-
{ timeout: 3e3 }
|
|
2148
|
-
);
|
|
2149
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
2145
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
2150
2146
|
}
|
|
2151
2147
|
}).catch(() => {
|
|
2152
2148
|
});
|
package/dist/lib/tmux-routing.js
CHANGED
|
@@ -4167,11 +4167,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
4167
4167
|
if (pending instanceof Promise) {
|
|
4168
4168
|
pending.then((count) => {
|
|
4169
4169
|
if (count > 0) {
|
|
4170
|
-
|
|
4171
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
4172
|
-
{ timeout: 3e3 }
|
|
4173
|
-
);
|
|
4174
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
4170
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
4175
4171
|
}
|
|
4176
4172
|
}).catch(() => {
|
|
4177
4173
|
});
|
package/dist/mcp/server.js
CHANGED
|
@@ -5792,8 +5792,8 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
5792
5792
|
try {
|
|
5793
5793
|
const fs = await import("fs");
|
|
5794
5794
|
const path44 = await import("path");
|
|
5795
|
-
const
|
|
5796
|
-
const logPath = path44.join(
|
|
5795
|
+
const os19 = await import("os");
|
|
5796
|
+
const logPath = path44.join(os19.homedir(), ".exe-os", "search-quality.jsonl");
|
|
5797
5797
|
fs.mkdirSync(path44.dirname(logPath), { recursive: true });
|
|
5798
5798
|
fs.appendFileSync(logPath, JSON.stringify(logEntry) + "\n");
|
|
5799
5799
|
} catch {
|
|
@@ -8491,11 +8491,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
8491
8491
|
if (pending instanceof Promise) {
|
|
8492
8492
|
pending.then((count) => {
|
|
8493
8493
|
if (count > 0) {
|
|
8494
|
-
|
|
8495
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
8496
|
-
{ timeout: 3e3 }
|
|
8497
|
-
);
|
|
8498
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
8494
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
8499
8495
|
}
|
|
8500
8496
|
}).catch(() => {
|
|
8501
8497
|
});
|
|
@@ -12130,8 +12126,9 @@ init_database();
|
|
|
12130
12126
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
12131
12127
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12132
12128
|
import { spawn as spawn4 } from "child_process";
|
|
12133
|
-
import { existsSync as existsSync33, openSync as openSync3, mkdirSync as mkdirSync17, closeSync as closeSync3 } from "fs";
|
|
12129
|
+
import { existsSync as existsSync33, openSync as openSync3, mkdirSync as mkdirSync17, closeSync as closeSync3, readFileSync as readFileSync28 } from "fs";
|
|
12134
12130
|
import path43 from "path";
|
|
12131
|
+
import os18 from "os";
|
|
12135
12132
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
12136
12133
|
|
|
12137
12134
|
// src/mcp/tools/recall-my-memory.ts
|
|
@@ -18920,8 +18917,8 @@ function registerExportGraph(server2) {
|
|
|
18920
18917
|
const html = await exportGraphHTML(client);
|
|
18921
18918
|
const fs = await import("fs");
|
|
18922
18919
|
const path44 = await import("path");
|
|
18923
|
-
const
|
|
18924
|
-
const outDir = path44.join(
|
|
18920
|
+
const os19 = await import("os");
|
|
18921
|
+
const outDir = path44.join(os19.homedir(), ".exe-os", "exports");
|
|
18925
18922
|
fs.mkdirSync(outDir, { recursive: true });
|
|
18926
18923
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
18927
18924
|
const filePath = path44.join(outDir, `graph-${timestamp}.html`);
|
|
@@ -23072,6 +23069,28 @@ try {
|
|
|
23072
23069
|
}
|
|
23073
23070
|
}, 3e4);
|
|
23074
23071
|
_ppidWatchdog.unref();
|
|
23072
|
+
const MCP_VERSION_PATH = path43.join(os18.homedir(), ".exe-os", "mcp-version");
|
|
23073
|
+
let _currentMcpVersion = null;
|
|
23074
|
+
try {
|
|
23075
|
+
_currentMcpVersion = existsSync33(MCP_VERSION_PATH) ? readFileSync28(MCP_VERSION_PATH, "utf8").trim() : null;
|
|
23076
|
+
} catch {
|
|
23077
|
+
}
|
|
23078
|
+
const _versionWatchdog = setInterval(() => {
|
|
23079
|
+
try {
|
|
23080
|
+
if (!existsSync33(MCP_VERSION_PATH)) return;
|
|
23081
|
+
const diskVersion = readFileSync28(MCP_VERSION_PATH, "utf8").trim();
|
|
23082
|
+
if (_currentMcpVersion && diskVersion !== _currentMcpVersion) {
|
|
23083
|
+
process.stderr.write(
|
|
23084
|
+
`[exe-os] MCP version changed (${_currentMcpVersion} \u2192 ${diskVersion}). Hot-reloading...
|
|
23085
|
+
`
|
|
23086
|
+
);
|
|
23087
|
+
void shutdown("hot_reload");
|
|
23088
|
+
}
|
|
23089
|
+
if (!_currentMcpVersion) _currentMcpVersion = diskVersion;
|
|
23090
|
+
} catch {
|
|
23091
|
+
}
|
|
23092
|
+
}, 1e4);
|
|
23093
|
+
_versionWatchdog.unref();
|
|
23075
23094
|
const BACKFILL_CHECK_MS = 5 * 60 * 1e3;
|
|
23076
23095
|
_backfillTimer = setInterval(async () => {
|
|
23077
23096
|
try {
|
|
@@ -2381,11 +2381,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
2381
2381
|
if (pending instanceof Promise) {
|
|
2382
2382
|
pending.then((count) => {
|
|
2383
2383
|
if (count > 0) {
|
|
2384
|
-
|
|
2385
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
2386
|
-
{ timeout: 3e3 }
|
|
2387
|
-
);
|
|
2388
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
2384
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
2389
2385
|
}
|
|
2390
2386
|
}).catch(() => {
|
|
2391
2387
|
});
|
|
@@ -2145,11 +2145,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
2145
2145
|
if (pending instanceof Promise) {
|
|
2146
2146
|
pending.then((count) => {
|
|
2147
2147
|
if (count > 0) {
|
|
2148
|
-
|
|
2149
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
2150
|
-
{ timeout: 3e3 }
|
|
2151
|
-
);
|
|
2152
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
2148
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
2153
2149
|
}
|
|
2154
2150
|
}).catch(() => {
|
|
2155
2151
|
});
|
package/dist/runtime/index.js
CHANGED
|
@@ -6181,11 +6181,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6181
6181
|
if (pending instanceof Promise) {
|
|
6182
6182
|
pending.then((count) => {
|
|
6183
6183
|
if (count > 0) {
|
|
6184
|
-
|
|
6185
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6186
|
-
{ timeout: 3e3 }
|
|
6187
|
-
);
|
|
6188
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
6184
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
6189
6185
|
}
|
|
6190
6186
|
}).catch(() => {
|
|
6191
6187
|
});
|
package/dist/tui/App.js
CHANGED
|
@@ -6785,11 +6785,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6785
6785
|
if (pending instanceof Promise) {
|
|
6786
6786
|
pending.then((count) => {
|
|
6787
6787
|
if (count > 0) {
|
|
6788
|
-
|
|
6789
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6790
|
-
{ timeout: 3e3 }
|
|
6791
|
-
);
|
|
6792
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending)`);
|
|
6788
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}", ${count} reviews pending \u2014 hook will surface)`);
|
|
6793
6789
|
}
|
|
6794
6790
|
}).catch(() => {
|
|
6795
6791
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askexenow/exe-os",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.20",
|
|
4
4
|
"description": "AI employee operating system — persistent memory, task management, and multi-agent coordination for Claude Code.",
|
|
5
5
|
"license": "CC-BY-NC-4.0",
|
|
6
6
|
"type": "module",
|
|
@@ -67,14 +67,14 @@
|
|
|
67
67
|
"test:watch": "vitest",
|
|
68
68
|
"typecheck": "tsc --noEmit",
|
|
69
69
|
"build": "tsup && mkdir -p dist/assets && cp src/assets/tmux.conf dist/assets/ && cp src/assets/ghostty.conf dist/assets/ && cp src/assets/statusline-command.sh dist/assets/ && cp src/bin/exe-start.sh dist/bin/exe-start.sh",
|
|
70
|
-
"deploy": "node dist/bin/pre-build-guard.js 2>/dev/null; (kill $(cat ~/.exe-os/exed.pid 2>/dev/null) 2>/dev/null; pgrep -f exe-daemon.js | xargs kill 2>/dev/null; true) && tsup && mkdir -p dist/assets && cp src/assets/tmux.conf dist/assets/ && cp src/assets/ghostty.conf dist/assets/ && cp src/assets/statusline-command.sh dist/assets/ && cp src/bin/exe-start.sh dist/bin/exe-start.sh && npm install -g . && node dist/bin/install.js --global && echo '[exe-os] Deploy complete.
|
|
70
|
+
"deploy": "node dist/bin/pre-build-guard.js 2>/dev/null; (kill $(cat ~/.exe-os/exed.pid 2>/dev/null) 2>/dev/null; pgrep -f exe-daemon.js | xargs kill 2>/dev/null; true) && tsup && mkdir -p dist/assets && cp src/assets/tmux.conf dist/assets/ && cp src/assets/ghostty.conf dist/assets/ && cp src/assets/statusline-command.sh dist/assets/ && cp src/bin/exe-start.sh dist/bin/exe-start.sh && npm install -g . && node dist/bin/install.js --global && echo '[exe-os] Deploy complete. Run /mcp in active sessions to reconnect.'",
|
|
71
71
|
"postinstall": "node dist/bin/install.js --global 2>/dev/null || true",
|
|
72
72
|
"prepublishOnly": "npm run typecheck && npm run build && node dist/bin/customer-readiness.js",
|
|
73
73
|
"test:publish": "npx vitest run --maxWorkers=4 --exclude 'tests/tui/**' --exclude 'tests/lib/tmux-routing.test.ts' --exclude 'tests/lib/intercom-routing.test.ts' --exclude 'tests/gateway/**' --exclude 'tests/installer/setup-wizard.test.ts' --exclude 'tests/mcp/ingest-document.test.ts' --exclude 'tests/lib/hybrid-search.test.ts' --exclude 'tests/lib/worker-gate.test.ts'",
|
|
74
74
|
"benchmark:longmemeval": "npx tsx tests/benchmarks/longmemeval.ts"
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
77
|
-
"@anthropic-ai/sdk": "^0.
|
|
77
|
+
"@anthropic-ai/sdk": "^0.95.1",
|
|
78
78
|
"@discordjs/voice": "^0.19.2",
|
|
79
79
|
"@libsql/client": "^0.14.0",
|
|
80
80
|
"@modelcontextprotocol/sdk": "^1.27.1",
|