@askexenow/exe-os 0.9.18 → 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 +5 -10
- package/dist/bin/exe-boot.js +2 -10
- package/dist/bin/exe-dispatch.js +2 -10
- package/dist/bin/exe-gateway.js +16 -13
- package/dist/bin/exe-launch-agent.js +82 -7
- package/dist/bin/exe-session-cleanup.js +2 -10
- package/dist/bin/git-sweep.js +2 -10
- package/dist/bin/install.js +8 -1
- package/dist/bin/intercom-check.js +2 -10
- package/dist/bin/scan-tasks.js +2 -10
- package/dist/bin/update.js +3 -0
- package/dist/gateway/index.js +21 -12
- package/dist/hooks/bug-report-worker.js +2 -10
- package/dist/hooks/commit-complete.js +2 -10
- package/dist/hooks/pre-compact.js +2 -10
- package/dist/hooks/prompt-submit.js +6 -14
- package/dist/hooks/session-end.js +2 -10
- package/dist/index.js +21 -12
- package/dist/lib/exe-daemon.js +8 -20
- package/dist/lib/tasks.js +2 -10
- package/dist/lib/tmux-routing.js +2 -10
- package/dist/mcp/server.js +30 -15
- package/dist/mcp/tools/create-task.js +2 -10
- package/dist/mcp/tools/update-task.js +2 -10
- package/dist/runtime/index.js +2 -10
- package/dist/tui/App.js +2 -10
- 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
|
});
|
|
@@ -12345,11 +12341,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
12345
12341
|
}
|
|
12346
12342
|
} catch {
|
|
12347
12343
|
}
|
|
12348
|
-
|
|
12349
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
12350
|
-
{ timeout: 3e3 }
|
|
12351
|
-
);
|
|
12352
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
12344
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
12353
12345
|
return true;
|
|
12354
12346
|
} catch {
|
|
12355
12347
|
return false;
|
|
@@ -15627,6 +15619,9 @@ async function runUpdate(cliArgs) {
|
|
|
15627
15619
|
console.log(" Try: npm cache clean --force && npm install -g @askexenow/exe-os@latest");
|
|
15628
15620
|
}
|
|
15629
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");
|
|
15630
15625
|
try {
|
|
15631
15626
|
const { existsSync: exists, readFileSync: readFile8 } = await import("fs");
|
|
15632
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
|
});
|
|
@@ -7563,11 +7559,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
7563
7559
|
}
|
|
7564
7560
|
} catch {
|
|
7565
7561
|
}
|
|
7566
|
-
|
|
7567
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
7568
|
-
{ timeout: 3e3 }
|
|
7569
|
-
);
|
|
7570
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
7562
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
7571
7563
|
return true;
|
|
7572
7564
|
} catch {
|
|
7573
7565
|
return false;
|
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
|
});
|
|
@@ -6143,11 +6139,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6143
6139
|
}
|
|
6144
6140
|
} catch {
|
|
6145
6141
|
}
|
|
6146
|
-
|
|
6147
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6148
|
-
{ timeout: 3e3 }
|
|
6149
|
-
);
|
|
6150
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
6142
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
6151
6143
|
return true;
|
|
6152
6144
|
} catch {
|
|
6153
6145
|
return false;
|
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
|
});
|
|
@@ -10980,11 +10976,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
10980
10976
|
}
|
|
10981
10977
|
} catch {
|
|
10982
10978
|
}
|
|
10983
|
-
|
|
10984
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
10985
|
-
{ timeout: 3e3 }
|
|
10986
|
-
);
|
|
10987
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
10979
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
10988
10980
|
return true;
|
|
10989
10981
|
} catch {
|
|
10990
10982
|
return false;
|
|
@@ -12269,7 +12261,7 @@ var WebhookServer = class {
|
|
|
12269
12261
|
sendJson(res, 200, {
|
|
12270
12262
|
status: "ok",
|
|
12271
12263
|
uptime,
|
|
12272
|
-
|
|
12264
|
+
adapterCount: this.handlers.size
|
|
12273
12265
|
});
|
|
12274
12266
|
}
|
|
12275
12267
|
async handleQuery(req, res) {
|
|
@@ -12422,13 +12414,24 @@ function matchesChannel(msgChannel, matchChannel) {
|
|
|
12422
12414
|
const channels = Array.isArray(matchChannel) ? matchChannel : [matchChannel];
|
|
12423
12415
|
return channels.includes(msgChannel);
|
|
12424
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
|
+
}
|
|
12425
12426
|
function matchesSender(msgSender, matchSender) {
|
|
12426
12427
|
if (!matchSender) return true;
|
|
12427
|
-
|
|
12428
|
+
const re = safeRegExp(matchSender);
|
|
12429
|
+
return re ? re.test(msgSender) : false;
|
|
12428
12430
|
}
|
|
12429
12431
|
function matchesTextPattern(msgText, matchPattern) {
|
|
12430
12432
|
if (!matchPattern) return true;
|
|
12431
|
-
|
|
12433
|
+
const re = safeRegExp(matchPattern, "i");
|
|
12434
|
+
return re ? re.test(msgText) : false;
|
|
12432
12435
|
}
|
|
12433
12436
|
function matchesRoute(msg, match) {
|
|
12434
12437
|
return matchesPlatform(msg.platform, match.platform) && matchesChannel(msg.channelId, match.channelId) && matchesSender(msg.senderId, match.senderId) && matchesTextPattern(msg.text, match.textPattern);
|
|
@@ -4891,6 +4891,79 @@ function identityPathFor(agent) {
|
|
|
4891
4891
|
}
|
|
4892
4892
|
return exactPath;
|
|
4893
4893
|
}
|
|
4894
|
+
var DEFAULT_ROLE_MCP_MAP = {
|
|
4895
|
+
coo: ["exe-browser", "brave-search"],
|
|
4896
|
+
cto: ["brave-search"],
|
|
4897
|
+
"principal engineer": [],
|
|
4898
|
+
"staff code reviewer": [],
|
|
4899
|
+
cmo: ["exe-browser", "brave-search"],
|
|
4900
|
+
"content production specialist": ["exe-create"],
|
|
4901
|
+
"ai product lead": ["brave-search"]
|
|
4902
|
+
};
|
|
4903
|
+
var ALWAYS_INCLUDE_SERVERS = ["exe-mem"];
|
|
4904
|
+
function collectAllMcpServers() {
|
|
4905
|
+
const servers = {};
|
|
4906
|
+
const sources = [
|
|
4907
|
+
path11.join(os7.homedir(), ".claude.json"),
|
|
4908
|
+
path11.join(os7.homedir(), ".claude", "settings.json")
|
|
4909
|
+
];
|
|
4910
|
+
for (const src of sources) {
|
|
4911
|
+
try {
|
|
4912
|
+
if (!existsSync10(src)) continue;
|
|
4913
|
+
const data = JSON.parse(readFileSync7(src, "utf-8"));
|
|
4914
|
+
const block = data.mcpServers;
|
|
4915
|
+
if (!block) continue;
|
|
4916
|
+
for (const [name, cfg] of Object.entries(block)) {
|
|
4917
|
+
if (!servers[name]) servers[name] = cfg;
|
|
4918
|
+
}
|
|
4919
|
+
} catch {
|
|
4920
|
+
}
|
|
4921
|
+
}
|
|
4922
|
+
return servers;
|
|
4923
|
+
}
|
|
4924
|
+
function generateLeanMcpConfig(agent, role) {
|
|
4925
|
+
try {
|
|
4926
|
+
const allServers = collectAllMcpServers();
|
|
4927
|
+
if (Object.keys(allServers).length === 0) return null;
|
|
4928
|
+
const normalizedRole = role.toLowerCase();
|
|
4929
|
+
const extraServers = DEFAULT_ROLE_MCP_MAP[normalizedRole] ?? [];
|
|
4930
|
+
const allowedNames = /* @__PURE__ */ new Set([...ALWAYS_INCLUDE_SERVERS, ...extraServers]);
|
|
4931
|
+
const leanServers = {};
|
|
4932
|
+
for (const [name, cfg] of Object.entries(allServers)) {
|
|
4933
|
+
if (allowedNames.has(name)) {
|
|
4934
|
+
leanServers[name] = cfg;
|
|
4935
|
+
}
|
|
4936
|
+
}
|
|
4937
|
+
if (Object.keys(leanServers).length >= Object.keys(allServers).length) return null;
|
|
4938
|
+
if (!leanServers["exe-mem"]) {
|
|
4939
|
+
const packageRoot = path11.resolve(path11.dirname(new URL(import.meta.url).pathname), "..", "..");
|
|
4940
|
+
leanServers["exe-mem"] = {
|
|
4941
|
+
type: "stdio",
|
|
4942
|
+
command: "node",
|
|
4943
|
+
args: [path11.join(packageRoot, "dist", "mcp", "server.js")],
|
|
4944
|
+
env: {}
|
|
4945
|
+
};
|
|
4946
|
+
}
|
|
4947
|
+
const configDir = path11.join(os7.homedir(), ".exe-os", "mcp-configs");
|
|
4948
|
+
mkdirSync5(configDir, { recursive: true });
|
|
4949
|
+
const configPath = path11.join(configDir, `${agent}-lean.json`);
|
|
4950
|
+
writeFileSync6(configPath, JSON.stringify({ mcpServers: leanServers }, null, 2), "utf-8");
|
|
4951
|
+
const saved = Object.keys(allServers).length - Object.keys(leanServers).length;
|
|
4952
|
+
if (saved > 0) {
|
|
4953
|
+
process.stderr.write(
|
|
4954
|
+
`[exe-launch-agent] lean MCP: ${agent} (${role}) gets ${Object.keys(leanServers).length}/${Object.keys(allServers).length} servers (${saved} skipped)
|
|
4955
|
+
`
|
|
4956
|
+
);
|
|
4957
|
+
}
|
|
4958
|
+
return configPath;
|
|
4959
|
+
} catch (err) {
|
|
4960
|
+
process.stderr.write(
|
|
4961
|
+
`[exe-launch-agent] lean MCP config generation failed: ${err instanceof Error ? err.message : String(err)}
|
|
4962
|
+
`
|
|
4963
|
+
);
|
|
4964
|
+
return null;
|
|
4965
|
+
}
|
|
4966
|
+
}
|
|
4894
4967
|
function leanMcpConfigFor(agent) {
|
|
4895
4968
|
const p = path11.join(os7.homedir(), ".exe-os", "mcp-configs", `${agent}-lean.json`);
|
|
4896
4969
|
return existsSync10(p) ? p : null;
|
|
@@ -5148,16 +5221,10 @@ async function main() {
|
|
|
5148
5221
|
}
|
|
5149
5222
|
}
|
|
5150
5223
|
}
|
|
5151
|
-
const plan = buildLaunchPlan(agent, behaviorsPath, passthrough, hasAgentFlag, provider);
|
|
5152
5224
|
const memoryAgent = baseAgentName(agent);
|
|
5153
|
-
process.env.AGENT_ID = memoryAgent;
|
|
5154
|
-
if (!process.env.EXE_SESSION_KEY) {
|
|
5155
|
-
process.env.EXE_SESSION_KEY = `launcher-${Date.now()}-${process.pid}`;
|
|
5156
|
-
}
|
|
5157
|
-
process.env.EXE_RUNTIME = "claude";
|
|
5158
5225
|
const empRole = (() => {
|
|
5159
5226
|
try {
|
|
5160
|
-
const emps =
|
|
5227
|
+
const emps = readFileSync7(
|
|
5161
5228
|
path11.join(os7.homedir(), ".exe-os", "exe-employees.json"),
|
|
5162
5229
|
"utf-8"
|
|
5163
5230
|
);
|
|
@@ -5169,6 +5236,13 @@ async function main() {
|
|
|
5169
5236
|
return "employee";
|
|
5170
5237
|
}
|
|
5171
5238
|
})();
|
|
5239
|
+
generateLeanMcpConfig(memoryAgent, empRole);
|
|
5240
|
+
const plan = buildLaunchPlan(agent, behaviorsPath, passthrough, hasAgentFlag, provider);
|
|
5241
|
+
process.env.AGENT_ID = memoryAgent;
|
|
5242
|
+
if (!process.env.EXE_SESSION_KEY) {
|
|
5243
|
+
process.env.EXE_SESSION_KEY = `launcher-${Date.now()}-${process.pid}`;
|
|
5244
|
+
}
|
|
5245
|
+
process.env.EXE_RUNTIME = "claude";
|
|
5172
5246
|
process.env.AGENT_ROLE = empRole;
|
|
5173
5247
|
try {
|
|
5174
5248
|
const { writeActiveAgent: writeActiveAgent2 } = await Promise.resolve().then(() => (init_active_agent(), active_agent_exports));
|
|
@@ -5206,6 +5280,7 @@ export {
|
|
|
5206
5280
|
applyProviderEnv,
|
|
5207
5281
|
buildLaunchPlan,
|
|
5208
5282
|
ccSupportsFlag,
|
|
5283
|
+
generateLeanMcpConfig,
|
|
5209
5284
|
parseBasename,
|
|
5210
5285
|
resolveAgent
|
|
5211
5286
|
};
|
|
@@ -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
|
});
|
|
@@ -7276,11 +7272,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName2, taskTit
|
|
|
7276
7272
|
}
|
|
7277
7273
|
} catch {
|
|
7278
7274
|
}
|
|
7279
|
-
|
|
7280
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
7281
|
-
{ timeout: 3e3 }
|
|
7282
|
-
);
|
|
7283
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName2} completed "${taskTitle.slice(0, 50)}")`);
|
|
7275
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName2} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
7284
7276
|
return true;
|
|
7285
7277
|
} catch {
|
|
7286
7278
|
return false;
|
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
|
});
|
|
@@ -6060,11 +6056,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6060
6056
|
}
|
|
6061
6057
|
} catch {
|
|
6062
6058
|
}
|
|
6063
|
-
|
|
6064
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6065
|
-
{ timeout: 3e3 }
|
|
6066
|
-
);
|
|
6067
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
6059
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
6068
6060
|
return true;
|
|
6069
6061
|
} catch {
|
|
6070
6062
|
return false;
|
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
|
});
|
|
@@ -7053,11 +7049,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
7053
7049
|
}
|
|
7054
7050
|
} catch {
|
|
7055
7051
|
}
|
|
7056
|
-
|
|
7057
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
7058
|
-
{ timeout: 3e3 }
|
|
7059
|
-
);
|
|
7060
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
7052
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
7061
7053
|
return true;
|
|
7062
7054
|
} catch {
|
|
7063
7055
|
return false;
|
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
|
});
|
|
@@ -6131,11 +6127,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6131
6127
|
}
|
|
6132
6128
|
} catch {
|
|
6133
6129
|
}
|
|
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)}")`);
|
|
6130
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
6139
6131
|
return true;
|
|
6140
6132
|
} catch {
|
|
6141
6133
|
return false;
|
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
|
});
|
|
@@ -8896,11 +8892,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
8896
8892
|
}
|
|
8897
8893
|
} catch {
|
|
8898
8894
|
}
|
|
8899
|
-
|
|
8900
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
8901
|
-
{ timeout: 3e3 }
|
|
8902
|
-
);
|
|
8903
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
8895
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
8904
8896
|
return true;
|
|
8905
8897
|
} catch {
|
|
8906
8898
|
return false;
|
|
@@ -9556,13 +9548,24 @@ function matchesChannel(msgChannel, matchChannel) {
|
|
|
9556
9548
|
const channels = Array.isArray(matchChannel) ? matchChannel : [matchChannel];
|
|
9557
9549
|
return channels.includes(msgChannel);
|
|
9558
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
|
+
}
|
|
9559
9560
|
function matchesSender(msgSender, matchSender) {
|
|
9560
9561
|
if (!matchSender) return true;
|
|
9561
|
-
|
|
9562
|
+
const re = safeRegExp(matchSender);
|
|
9563
|
+
return re ? re.test(msgSender) : false;
|
|
9562
9564
|
}
|
|
9563
9565
|
function matchesTextPattern(msgText, matchPattern) {
|
|
9564
9566
|
if (!matchPattern) return true;
|
|
9565
|
-
|
|
9567
|
+
const re = safeRegExp(matchPattern, "i");
|
|
9568
|
+
return re ? re.test(msgText) : false;
|
|
9566
9569
|
}
|
|
9567
9570
|
function matchesRoute(msg, match) {
|
|
9568
9571
|
return matchesPlatform(msg.platform, match.platform) && matchesChannel(msg.channelId, match.channelId) && matchesSender(msg.senderId, match.senderId) && matchesTextPattern(msg.text, match.textPattern);
|
|
@@ -9602,6 +9605,12 @@ function validateGatewayConfig(config2) {
|
|
|
9602
9605
|
if (!route.target) {
|
|
9603
9606
|
warnings.push(`Route "${route.name}" has no target employee`);
|
|
9604
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
|
+
}
|
|
9605
9614
|
const isEmptyMatch = !route.match.platform && !route.match.channelId && !route.match.senderId && !route.match.textPattern;
|
|
9606
9615
|
if (isEmptyMatch && config2.routes.indexOf(route) !== config2.routes.length - 1) {
|
|
9607
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
|
});
|
|
@@ -5327,11 +5323,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
5327
5323
|
}
|
|
5328
5324
|
} catch {
|
|
5329
5325
|
}
|
|
5330
|
-
|
|
5331
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
5332
|
-
{ timeout: 3e3 }
|
|
5333
|
-
);
|
|
5334
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
5326
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
5335
5327
|
return true;
|
|
5336
5328
|
} catch {
|
|
5337
5329
|
return false;
|
|
@@ -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
|
});
|
|
@@ -6059,11 +6055,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6059
6055
|
}
|
|
6060
6056
|
} catch {
|
|
6061
6057
|
}
|
|
6062
|
-
|
|
6063
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6064
|
-
{ timeout: 3e3 }
|
|
6065
|
-
);
|
|
6066
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
6058
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
6067
6059
|
return true;
|
|
6068
6060
|
} catch {
|
|
6069
6061
|
return false;
|
|
@@ -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
|
});
|
|
@@ -6043,11 +6039,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6043
6039
|
}
|
|
6044
6040
|
} catch {
|
|
6045
6041
|
}
|
|
6046
|
-
|
|
6047
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6048
|
-
{ timeout: 3e3 }
|
|
6049
|
-
);
|
|
6050
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
6042
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
6051
6043
|
return true;
|
|
6052
6044
|
} catch {
|
|
6053
6045
|
return false;
|
|
@@ -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
|
});
|
|
@@ -8597,11 +8593,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
8597
8593
|
}
|
|
8598
8594
|
} catch {
|
|
8599
8595
|
}
|
|
8600
|
-
|
|
8601
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
8602
|
-
{ timeout: 3e3 }
|
|
8603
|
-
);
|
|
8604
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
8596
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
8605
8597
|
return true;
|
|
8606
8598
|
} catch {
|
|
8607
8599
|
return false;
|
|
@@ -10152,14 +10144,14 @@ process.stdin.on("end", async () => {
|
|
|
10152
10144
|
const agentName = baseAgentName2(session.split("-")[0] ?? session);
|
|
10153
10145
|
if (isSessionBusy2(session) || hasInProgressTask(agentName)) return true;
|
|
10154
10146
|
const rtConfig = getAgentRuntime2(agentName);
|
|
10147
|
+
const nudgeMsg = "You have pending notifications. Run list_tasks to check for assigned work.";
|
|
10148
|
+
transport.sendKeys(session, nudgeMsg);
|
|
10155
10149
|
if (rtConfig.runtime === "codex" || rtConfig.runtime === "opencode") {
|
|
10156
|
-
transport.sendKeys(session, "You have new notifications. Call list_tasks to check for assigned work.");
|
|
10157
10150
|
try {
|
|
10158
|
-
|
|
10151
|
+
const { execFileSync: efs } = __require("child_process");
|
|
10152
|
+
efs("tmux", ["send-keys", "-t", session, "Tab"], { encoding: "utf8", timeout: 2e3 });
|
|
10159
10153
|
} catch {
|
|
10160
10154
|
}
|
|
10161
|
-
} else {
|
|
10162
|
-
transport.sendKeys(session, "/exe-intercom");
|
|
10163
10155
|
}
|
|
10164
10156
|
return true;
|
|
10165
10157
|
} catch {
|
|
@@ -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
|
});
|
|
@@ -6252,11 +6248,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6252
6248
|
}
|
|
6253
6249
|
} catch {
|
|
6254
6250
|
}
|
|
6255
|
-
|
|
6256
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6257
|
-
{ timeout: 3e3 }
|
|
6258
|
-
);
|
|
6259
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
6251
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
6260
6252
|
return true;
|
|
6261
6253
|
} catch {
|
|
6262
6254
|
return false;
|
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
|
});
|
|
@@ -6432,11 +6428,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6432
6428
|
}
|
|
6433
6429
|
} catch {
|
|
6434
6430
|
}
|
|
6435
|
-
|
|
6436
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6437
|
-
{ timeout: 3e3 }
|
|
6438
|
-
);
|
|
6439
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
6431
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
6440
6432
|
return true;
|
|
6441
6433
|
} catch {
|
|
6442
6434
|
return false;
|
|
@@ -12303,13 +12295,24 @@ function matchesChannel(msgChannel, matchChannel) {
|
|
|
12303
12295
|
const channels = Array.isArray(matchChannel) ? matchChannel : [matchChannel];
|
|
12304
12296
|
return channels.includes(msgChannel);
|
|
12305
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
|
+
}
|
|
12306
12307
|
function matchesSender(msgSender, matchSender) {
|
|
12307
12308
|
if (!matchSender) return true;
|
|
12308
|
-
|
|
12309
|
+
const re = safeRegExp(matchSender);
|
|
12310
|
+
return re ? re.test(msgSender) : false;
|
|
12309
12311
|
}
|
|
12310
12312
|
function matchesTextPattern(msgText, matchPattern) {
|
|
12311
12313
|
if (!matchPattern) return true;
|
|
12312
|
-
|
|
12314
|
+
const re = safeRegExp(matchPattern, "i");
|
|
12315
|
+
return re ? re.test(msgText) : false;
|
|
12313
12316
|
}
|
|
12314
12317
|
function matchesRoute(msg, match) {
|
|
12315
12318
|
return matchesPlatform(msg.platform, match.platform) && matchesChannel(msg.channelId, match.channelId) && matchesSender(msg.senderId, match.senderId) && matchesTextPattern(msg.text, match.textPattern);
|
|
@@ -12349,6 +12352,12 @@ function validateGatewayConfig(config2) {
|
|
|
12349
12352
|
if (!route.target) {
|
|
12350
12353
|
warnings.push(`Route "${route.name}" has no target employee`);
|
|
12351
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
|
+
}
|
|
12352
12361
|
const isEmptyMatch = !route.match.platform && !route.match.channelId && !route.match.senderId && !route.match.textPattern;
|
|
12353
12362
|
if (isEmptyMatch && config2.routes.indexOf(route) !== config2.routes.length - 1) {
|
|
12354
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
|
});
|
|
@@ -8058,11 +8054,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
8058
8054
|
}
|
|
8059
8055
|
} catch {
|
|
8060
8056
|
}
|
|
8061
|
-
|
|
8062
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
8063
|
-
{ timeout: 3e3 }
|
|
8064
|
-
);
|
|
8065
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
8057
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
8066
8058
|
return true;
|
|
8067
8059
|
} catch {
|
|
8068
8060
|
return false;
|
|
@@ -12447,15 +12439,10 @@ function isIdlePane(paneText) {
|
|
|
12447
12439
|
}
|
|
12448
12440
|
function sendNudge(transport, session, runtime, action) {
|
|
12449
12441
|
const message = action === "nudge" ? "You have open tasks. Run list_tasks to find them." : "You have more open tasks to dispatch. Run list_tasks.";
|
|
12450
|
-
if (
|
|
12451
|
-
|
|
12452
|
-
transport.sendKeysLiteral(session, message);
|
|
12453
|
-
} else {
|
|
12454
|
-
transport.sendKeys(session, message);
|
|
12455
|
-
}
|
|
12442
|
+
if (transport.sendKeysLiteral) {
|
|
12443
|
+
transport.sendKeysLiteral(session, message);
|
|
12456
12444
|
} else {
|
|
12457
|
-
transport.sendKeys(session,
|
|
12458
|
-
transport.sendKeys(session, "Enter");
|
|
12445
|
+
transport.sendKeys(session, message);
|
|
12459
12446
|
}
|
|
12460
12447
|
process.stderr.write(
|
|
12461
12448
|
`[enforcement-audit] SENT nudge to ${session} (${runtime}, ${action})
|
|
@@ -14215,14 +14202,15 @@ function startIntercomQueueDrain() {
|
|
|
14215
14202
|
const { baseAgentName: baseAgentName2 } = (init_employees(), __toCommonJS(employees_exports));
|
|
14216
14203
|
const agentName = baseAgentName2(session.split("-")[0] ?? session);
|
|
14217
14204
|
const rtConfig = getAgentRuntime2(agentName);
|
|
14205
|
+
const nudgeMsg = "You have pending notifications. Run list_tasks to check for assigned work.";
|
|
14218
14206
|
if (rtConfig.runtime === "codex" || rtConfig.runtime === "opencode") {
|
|
14219
|
-
transport.sendKeys(session,
|
|
14207
|
+
transport.sendKeys(session, nudgeMsg);
|
|
14220
14208
|
try {
|
|
14221
14209
|
__require("child_process").execSync(`tmux send-keys -t ${session} Tab`, { timeout: 2e3 });
|
|
14222
14210
|
} catch {
|
|
14223
14211
|
}
|
|
14224
14212
|
} else {
|
|
14225
|
-
transport.sendKeys(session,
|
|
14213
|
+
transport.sendKeys(session, nudgeMsg);
|
|
14226
14214
|
}
|
|
14227
14215
|
return true;
|
|
14228
14216
|
} catch {
|
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
|
});
|
|
@@ -2154,11 +2150,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
2154
2150
|
}
|
|
2155
2151
|
} catch {
|
|
2156
2152
|
}
|
|
2157
|
-
|
|
2158
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
2159
|
-
{ timeout: 3e3 }
|
|
2160
|
-
);
|
|
2161
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
2153
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
2162
2154
|
return true;
|
|
2163
2155
|
} catch {
|
|
2164
2156
|
return false;
|
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
|
});
|
|
@@ -4179,11 +4175,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
4179
4175
|
}
|
|
4180
4176
|
} catch {
|
|
4181
4177
|
}
|
|
4182
|
-
|
|
4183
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
4184
|
-
{ timeout: 3e3 }
|
|
4185
|
-
);
|
|
4186
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
4178
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
4187
4179
|
return true;
|
|
4188
4180
|
} catch {
|
|
4189
4181
|
return false;
|
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
|
});
|
|
@@ -8503,11 +8499,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
8503
8499
|
}
|
|
8504
8500
|
} catch {
|
|
8505
8501
|
}
|
|
8506
|
-
|
|
8507
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
8508
|
-
{ timeout: 3e3 }
|
|
8509
|
-
);
|
|
8510
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
8502
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
8511
8503
|
return true;
|
|
8512
8504
|
} catch {
|
|
8513
8505
|
return false;
|
|
@@ -12134,8 +12126,9 @@ init_database();
|
|
|
12134
12126
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
12135
12127
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12136
12128
|
import { spawn as spawn4 } from "child_process";
|
|
12137
|
-
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";
|
|
12138
12130
|
import path43 from "path";
|
|
12131
|
+
import os18 from "os";
|
|
12139
12132
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
12140
12133
|
|
|
12141
12134
|
// src/mcp/tools/recall-my-memory.ts
|
|
@@ -18924,8 +18917,8 @@ function registerExportGraph(server2) {
|
|
|
18924
18917
|
const html = await exportGraphHTML(client);
|
|
18925
18918
|
const fs = await import("fs");
|
|
18926
18919
|
const path44 = await import("path");
|
|
18927
|
-
const
|
|
18928
|
-
const outDir = path44.join(
|
|
18920
|
+
const os19 = await import("os");
|
|
18921
|
+
const outDir = path44.join(os19.homedir(), ".exe-os", "exports");
|
|
18929
18922
|
fs.mkdirSync(outDir, { recursive: true });
|
|
18930
18923
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
18931
18924
|
const filePath = path44.join(outDir, `graph-${timestamp}.html`);
|
|
@@ -23076,6 +23069,28 @@ try {
|
|
|
23076
23069
|
}
|
|
23077
23070
|
}, 3e4);
|
|
23078
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();
|
|
23079
23094
|
const BACKFILL_CHECK_MS = 5 * 60 * 1e3;
|
|
23080
23095
|
_backfillTimer = setInterval(async () => {
|
|
23081
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
|
});
|
|
@@ -2393,11 +2389,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
2393
2389
|
}
|
|
2394
2390
|
} catch {
|
|
2395
2391
|
}
|
|
2396
|
-
|
|
2397
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
2398
|
-
{ timeout: 3e3 }
|
|
2399
|
-
);
|
|
2400
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
2392
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
2401
2393
|
return true;
|
|
2402
2394
|
} catch {
|
|
2403
2395
|
return false;
|
|
@@ -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
|
});
|
|
@@ -2157,11 +2153,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
2157
2153
|
}
|
|
2158
2154
|
} catch {
|
|
2159
2155
|
}
|
|
2160
|
-
|
|
2161
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
2162
|
-
{ timeout: 3e3 }
|
|
2163
|
-
);
|
|
2164
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
2156
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
2165
2157
|
return true;
|
|
2166
2158
|
} catch {
|
|
2167
2159
|
return false;
|
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
|
});
|
|
@@ -6193,11 +6189,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6193
6189
|
}
|
|
6194
6190
|
} catch {
|
|
6195
6191
|
}
|
|
6196
|
-
|
|
6197
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6198
|
-
{ timeout: 3e3 }
|
|
6199
|
-
);
|
|
6200
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
6192
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
6201
6193
|
return true;
|
|
6202
6194
|
} catch {
|
|
6203
6195
|
return false;
|
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
|
});
|
|
@@ -6797,11 +6793,7 @@ function notifyCoordinatorTaskCompletion(coordinatorSession, agentName, taskTitl
|
|
|
6797
6793
|
}
|
|
6798
6794
|
} catch {
|
|
6799
6795
|
}
|
|
6800
|
-
|
|
6801
|
-
`tmux send-keys -t ${JSON.stringify(coordinatorSession)} '/exe-intercom' Enter`,
|
|
6802
|
-
{ timeout: 3e3 }
|
|
6803
|
-
);
|
|
6804
|
-
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}")`);
|
|
6796
|
+
logIntercom(`COMPLETION \u2192 ${coordinatorSession} (${agentName} completed "${taskTitle.slice(0, 50)}") \u2014 review count unavailable, skipping intercom (hook will catch it)`);
|
|
6805
6797
|
return true;
|
|
6806
6798
|
} catch {
|
|
6807
6799
|
return false;
|
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",
|