@askexenow/exe-os 0.9.212 → 0.9.214
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/exe-forget.js +1 -1
- package/dist/bin/exe-search.js +1 -1
- package/dist/{catchup-brief-VAG2IH72.js → catchup-brief-6AD7QQZB.js} +1 -1
- package/dist/{chunk-MEP5CND3.js → chunk-LSARQLX3.js} +2 -2
- package/dist/{chunk-UVYFJ7IU.js → chunk-NVZODD7S.js} +3 -3
- package/dist/hooks/error-recall.js +1 -1
- package/dist/hooks/manifest.json +4 -4
- package/dist/hooks/prompt-submit.js +1 -1
- package/dist/hooks/session-start.js +1 -1
- package/dist/lib/exe-daemon.js +143 -48
- package/dist/lib/hybrid-search.js +1 -1
- package/dist/mcp/register-tools.js +3 -3
- package/dist/mcp/server.js +3 -3
- package/dist/{reranker-ZRN4LVF3.js → reranker-AZN6MN2N.js} +1 -1
- package/package.json +1 -1
- package/release-notes.json +39 -39
- /package/dist/{chunk-HURHILTM.js → chunk-UFOERR37.js} +0 -0
package/dist/bin/exe-forget.js
CHANGED
package/dist/bin/exe-search.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
isRerankerAvailable,
|
|
9
9
|
rerankWithScores
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-UFOERR37.js";
|
|
11
11
|
import {
|
|
12
12
|
getEntityByName,
|
|
13
13
|
getEntityNeighbors,
|
|
@@ -187,7 +187,7 @@ import {
|
|
|
187
187
|
import {
|
|
188
188
|
hybridSearch,
|
|
189
189
|
recentRecords
|
|
190
|
-
} from "./chunk-
|
|
190
|
+
} from "./chunk-NVZODD7S.js";
|
|
191
191
|
import {
|
|
192
192
|
attachDocumentMetadata,
|
|
193
193
|
flushBatch,
|
|
@@ -233,7 +233,7 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
233
233
|
let rerankerAvailable = false;
|
|
234
234
|
if (process.env.EXE_IS_DAEMON === "1") {
|
|
235
235
|
try {
|
|
236
|
-
const { isRerankerAvailable } = await import("./reranker-
|
|
236
|
+
const { isRerankerAvailable } = await import("./reranker-AZN6MN2N.js");
|
|
237
237
|
rerankerAvailable = isRerankerAvailable();
|
|
238
238
|
} catch {
|
|
239
239
|
}
|
|
@@ -397,7 +397,7 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
397
397
|
try {
|
|
398
398
|
let rerankedRecords;
|
|
399
399
|
if (graphContextMap.size > 0) {
|
|
400
|
-
const { rerankWithContext } = await import("./reranker-
|
|
400
|
+
const { rerankWithContext } = await import("./reranker-AZN6MN2N.js");
|
|
401
401
|
const candidates = merged.map((m) => ({
|
|
402
402
|
text: m.raw_text,
|
|
403
403
|
context: graphContextMap.get(m.id)
|
|
@@ -405,7 +405,7 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
405
405
|
const scored = await rerankWithContext(effectiveQuery, candidates, rerankReturnLimit);
|
|
406
406
|
rerankedRecords = scored.map((s) => merged[s.index]);
|
|
407
407
|
} else {
|
|
408
|
-
const { rerank } = await import("./reranker-
|
|
408
|
+
const { rerank } = await import("./reranker-AZN6MN2N.js");
|
|
409
409
|
rerankedRecords = await rerank(effectiveQuery, merged, rerankReturnLimit);
|
|
410
410
|
}
|
|
411
411
|
if (rerankedRecords.length > 0) {
|
package/dist/hooks/manifest.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
|
-
"generatedAt": "2026-06-
|
|
3
|
+
"generatedAt": "2026-06-04T08:59:34.433Z",
|
|
4
4
|
"hashes": {
|
|
5
5
|
"bug-report-worker.js": "0026604aac324e295b46bde719681de6800b2df144012cc2c2b349dcdbb082be",
|
|
6
6
|
"codex-stop-task-finalizer.js": "f6188b6e85f247546996d138de58cd658e40c8175511e22b1b201a1379502632",
|
|
7
7
|
"commit-complete.js": "1bc2e33e1d00daebc727c5c3e73ec8d5025ad08544e4cde2848d035ee5e21352",
|
|
8
|
-
"error-recall.js": "
|
|
8
|
+
"error-recall.js": "b21822616521e68d752ac273a70c9e505fb3636379c31e66ab8609a95a87b02d",
|
|
9
9
|
"exe-heartbeat-hook.js": "10688da0e9c9972fff33c3bb33923df4e743df9d48e744b96d227836c6270c4c",
|
|
10
10
|
"ingest-worker.js": "df9693b3a590f313868019ab91dd2f7298750492f792c2b8055c4ad68a1c9d67",
|
|
11
11
|
"ingest.js": "5af6b8a3a4e30c282d27a17a82d55337b7102d84e796198c6390315a39755404",
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"post-tool-combined.js": "19469891de74713eab9d5d9273c130d5fe5ad95a2b99618ac4bb9d60120b5c71",
|
|
16
16
|
"pre-compact.js": "01761e0a404d9cc5fa2ef1788829bd62bbd426395703491906f4b255f32976f4",
|
|
17
17
|
"pre-tool-use.js": "c2e10257f91ba7a759aa41db28e374b20780d7376eb17d3d167c3e7cbf0a226d",
|
|
18
|
-
"prompt-submit.js": "
|
|
18
|
+
"prompt-submit.js": "5722df8ad7789f51bd37dbbd152209e2330952680c686460d393875c5b549072",
|
|
19
19
|
"session-end.js": "2cfe3cbc196cb11bbe68ae23d128eacc99d1dbbbdd7b3698189922bf5645a71a",
|
|
20
|
-
"session-start.js": "
|
|
20
|
+
"session-start.js": "0416fc6b642529eb0125b02b892cb0014010294baaf5e864819a4fa745fddfa8",
|
|
21
21
|
"stop.js": "9c784c10f1a8eddfec9f5dc66463d67a5b09eb21f340e0d92157e9e7befb367b",
|
|
22
22
|
"subagent-stop.js": "a3d3a01d99dcdcebd5763e5974ce912d69c5f07ba254eb01c2f8c587903ec88c",
|
|
23
23
|
"summary-worker.js": "f29f29e148ea34b38eab656131b2045e0e4020b526ab8bada9c693eb19dc690e"
|
|
@@ -158,7 +158,7 @@ You are **${ag.agentId}** (${ag.agentRole}). Daemon is degraded \u2014 memory un
|
|
|
158
158
|
query = `last actions on ${projectName}`;
|
|
159
159
|
header = "## Resuming Session\nHere's where you left off:";
|
|
160
160
|
try {
|
|
161
|
-
const { buildCatchupBrief } = await import("../catchup-brief-
|
|
161
|
+
const { buildCatchupBrief } = await import("../catchup-brief-6AD7QQZB.js");
|
|
162
162
|
const brief = await buildCatchupBrief(
|
|
163
163
|
agentId,
|
|
164
164
|
projectName,
|
package/dist/lib/exe-daemon.js
CHANGED
|
@@ -407,12 +407,15 @@ var MAX_QUEUE_SIZE = 5e3;
|
|
|
407
407
|
var _tmuxSessionCache = [];
|
|
408
408
|
var _tmuxCacheTimestamp = 0;
|
|
409
409
|
var TMUX_CACHE_TTL_MS = 5e3;
|
|
410
|
-
function
|
|
410
|
+
async function getTmuxSessionsAsync() {
|
|
411
411
|
const now = Date.now();
|
|
412
412
|
if (now - _tmuxCacheTimestamp < TMUX_CACHE_TTL_MS) return _tmuxSessionCache;
|
|
413
413
|
try {
|
|
414
|
-
const
|
|
415
|
-
|
|
414
|
+
const { stdout } = await execFileAsync("tmux", ["list-sessions", "-F", "#{session_name}"], {
|
|
415
|
+
encoding: "utf8",
|
|
416
|
+
timeout: 3e3
|
|
417
|
+
});
|
|
418
|
+
_tmuxSessionCache = String(stdout ?? "").trim().split("\n").filter(Boolean);
|
|
416
419
|
_tmuxCacheTimestamp = now;
|
|
417
420
|
} catch {
|
|
418
421
|
_tmuxSessionCache = [];
|
|
@@ -451,6 +454,48 @@ async function batchCapturePanes(sessions, lines = 20) {
|
|
|
451
454
|
}
|
|
452
455
|
return results;
|
|
453
456
|
}
|
|
457
|
+
async function tmuxPaneAliveAsync(session) {
|
|
458
|
+
try {
|
|
459
|
+
const { stdout } = await execFileAsync(
|
|
460
|
+
"tmux",
|
|
461
|
+
["list-panes", "-t", session, "-F", "#{pane_dead}"],
|
|
462
|
+
{ encoding: "utf8", timeout: 3e3 }
|
|
463
|
+
);
|
|
464
|
+
return String(stdout ?? "").trim() !== "1";
|
|
465
|
+
} catch {
|
|
466
|
+
return false;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
async function batchPaneAlive(sessions) {
|
|
470
|
+
const alive = /* @__PURE__ */ new Set();
|
|
471
|
+
const CONCURRENCY = 4;
|
|
472
|
+
for (let i = 0; i < sessions.length; i += CONCURRENCY) {
|
|
473
|
+
const batch = sessions.slice(i, i + CONCURRENCY);
|
|
474
|
+
const settled = await Promise.allSettled(
|
|
475
|
+
batch.map(async (session) => ({ session, alive: await tmuxPaneAliveAsync(session) }))
|
|
476
|
+
);
|
|
477
|
+
for (const result of settled) {
|
|
478
|
+
if (result.status === "fulfilled" && result.value.alive) {
|
|
479
|
+
alive.add(result.value.session);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
return alive;
|
|
484
|
+
}
|
|
485
|
+
var CACHED_SESSION_BUSY_PATTERN = /[✻✽✶✳·].*…|Running…|• Working|• Ran |• Explored|• Called|esc to interrupt/;
|
|
486
|
+
function getCachedSessionState(sessionName, paneCache, aliveSessions) {
|
|
487
|
+
if (!aliveSessions.has(sessionName)) return "offline";
|
|
488
|
+
const pane = paneCache.get(sessionName);
|
|
489
|
+
if (!pane) return "offline";
|
|
490
|
+
if (!pane.includes("\u276F") && !pane.includes("Claude Code") && !CACHED_SESSION_BUSY_PATTERN.test(pane) && !/Running…/.test(pane)) {
|
|
491
|
+
if (/\$\s*$/.test(pane) || /% $/.test(pane.trimEnd())) {
|
|
492
|
+
return "no_claude";
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
if (/Running…/.test(pane)) return "tool";
|
|
496
|
+
if (CACHED_SESSION_BUSY_PATTERN.test(pane)) return "thinking";
|
|
497
|
+
return "idle";
|
|
498
|
+
}
|
|
454
499
|
setInterval(() => {
|
|
455
500
|
const now = Date.now();
|
|
456
501
|
for (const [key, entry] of _paneCacheMap) {
|
|
@@ -480,6 +525,35 @@ var _idleTimer = null;
|
|
|
480
525
|
var _requestsServed = 0;
|
|
481
526
|
var _droppedRequests = 0;
|
|
482
527
|
var _startedAt2 = Date.now();
|
|
528
|
+
var TIMER_TRACE_BOOT_WINDOW_MS = Number(process.env.EXE_TIMER_TRACE_BOOT_WINDOW_MS) || 10 * 60 * 1e3;
|
|
529
|
+
var TIMER_TRACE_SLOW_MS = Number(process.env.EXE_TIMER_TRACE_SLOW_MS) || 500;
|
|
530
|
+
function shouldTraceDaemonTimer(durationMs = 0) {
|
|
531
|
+
return Date.now() - _startedAt2 < TIMER_TRACE_BOOT_WINDOW_MS || durationMs >= TIMER_TRACE_SLOW_MS;
|
|
532
|
+
}
|
|
533
|
+
async function traceDaemonTimer(name, fn) {
|
|
534
|
+
const startedAt = Date.now();
|
|
535
|
+
const traceStart = shouldTraceDaemonTimer();
|
|
536
|
+
if (traceStart) {
|
|
537
|
+
process.stderr.write(`[exed] Timer start: ${name}
|
|
538
|
+
`);
|
|
539
|
+
}
|
|
540
|
+
try {
|
|
541
|
+
return await fn();
|
|
542
|
+
} finally {
|
|
543
|
+
const durationMs = Date.now() - startedAt;
|
|
544
|
+
if (shouldTraceDaemonTimer(durationMs)) {
|
|
545
|
+
const msg = `[exed] Timer duration: ${name} ${durationMs}ms`;
|
|
546
|
+
process.stderr.write(`${msg}
|
|
547
|
+
`);
|
|
548
|
+
logDaemonHealth({
|
|
549
|
+
event: "process_stats",
|
|
550
|
+
pid: process.pid,
|
|
551
|
+
message: msg,
|
|
552
|
+
data: { type: "timer_duration", timer: name, durationMs, uptimeMs: Date.now() - _startedAt2 }
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
483
557
|
function enqueue(queue, entry) {
|
|
484
558
|
if (queue.length >= MAX_QUEUE_SIZE) {
|
|
485
559
|
queue.shift();
|
|
@@ -1200,7 +1274,7 @@ async function _writeMemoryRecordInner(entry) {
|
|
|
1200
1274
|
}
|
|
1201
1275
|
var MEMORY_DRAIN_INTERVAL_MS = 30 * 1e3;
|
|
1202
1276
|
function startMemoryQueueDrain() {
|
|
1203
|
-
const drain = async () => {
|
|
1277
|
+
const drain = async () => traceDaemonTimer("memory_queue_drain", async () => {
|
|
1204
1278
|
fired("memory_queue_drain");
|
|
1205
1279
|
if (!await ensureStoreForPolling()) return;
|
|
1206
1280
|
try {
|
|
@@ -1237,7 +1311,7 @@ function startMemoryQueueDrain() {
|
|
|
1237
1311
|
`
|
|
1238
1312
|
);
|
|
1239
1313
|
}
|
|
1240
|
-
};
|
|
1314
|
+
});
|
|
1241
1315
|
void drain();
|
|
1242
1316
|
const timer = setInterval(() => void drain(), MEMORY_DRAIN_INTERVAL_MS);
|
|
1243
1317
|
timer.unref();
|
|
@@ -1246,7 +1320,7 @@ function startMemoryQueueDrain() {
|
|
|
1246
1320
|
}
|
|
1247
1321
|
var MESSAGE_DRAIN_INTERVAL_MS = 3e4;
|
|
1248
1322
|
function startMessageQueueDrain() {
|
|
1249
|
-
const drain = async () => {
|
|
1323
|
+
const drain = async () => traceDaemonTimer("message_queue_drain", async () => {
|
|
1250
1324
|
fired("message_queue_drain");
|
|
1251
1325
|
if (!await ensureStoreForPolling()) return;
|
|
1252
1326
|
try {
|
|
@@ -1290,7 +1364,7 @@ function startMessageQueueDrain() {
|
|
|
1290
1364
|
`
|
|
1291
1365
|
);
|
|
1292
1366
|
}
|
|
1293
|
-
};
|
|
1367
|
+
});
|
|
1294
1368
|
void drain();
|
|
1295
1369
|
const timer = setInterval(() => void drain(), MESSAGE_DRAIN_INTERVAL_MS);
|
|
1296
1370
|
timer.unref();
|
|
@@ -2252,7 +2326,7 @@ async function startReviewPolling() {
|
|
|
2252
2326
|
};
|
|
2253
2327
|
const { pollReviewNudge, createReviewNudgeRealDeps, loadNudgeState } = await import("../daemon-orchestration-QVJ26DDN.js");
|
|
2254
2328
|
const nudgeState = loadNudgeState();
|
|
2255
|
-
const tick = async () => {
|
|
2329
|
+
const tick = async () => traceDaemonTimer("review_polling", async () => {
|
|
2256
2330
|
fired("review_polling");
|
|
2257
2331
|
if (!await ensureStoreForPolling()) return;
|
|
2258
2332
|
try {
|
|
@@ -2279,7 +2353,7 @@ async function startReviewPolling() {
|
|
|
2279
2353
|
process.stderr.write(`[exed] Review poll error: ${err instanceof Error ? err.message : String(err)}
|
|
2280
2354
|
`);
|
|
2281
2355
|
}
|
|
2282
|
-
};
|
|
2356
|
+
});
|
|
2283
2357
|
const timer = setInterval(() => void tick(), REVIEW_POLL_INTERVAL_MS);
|
|
2284
2358
|
timer.unref();
|
|
2285
2359
|
process.stderr.write(`[exed] Review polling started (every ${REVIEW_POLL_INTERVAL_MS / 6e4}m)
|
|
@@ -2287,7 +2361,7 @@ async function startReviewPolling() {
|
|
|
2287
2361
|
}
|
|
2288
2362
|
var SESSION_TTL_INTERVAL_MS = 5 * 60 * 1e3;
|
|
2289
2363
|
function startSessionTTL() {
|
|
2290
|
-
const tick = async () => {
|
|
2364
|
+
const tick = async () => traceDaemonTimer("session_ttl", async () => {
|
|
2291
2365
|
fired("session_ttl");
|
|
2292
2366
|
if (!await ensureStoreForPolling()) return;
|
|
2293
2367
|
try {
|
|
@@ -2300,7 +2374,7 @@ function startSessionTTL() {
|
|
|
2300
2374
|
process.stderr.write(`[exed] Session TTL error: ${err instanceof Error ? err.message : String(err)}
|
|
2301
2375
|
`);
|
|
2302
2376
|
}
|
|
2303
|
-
};
|
|
2377
|
+
});
|
|
2304
2378
|
const timer = setInterval(() => void tick(), SESSION_TTL_INTERVAL_MS);
|
|
2305
2379
|
timer.unref();
|
|
2306
2380
|
process.stderr.write(`[exed] Session TTL started (every ${SESSION_TTL_INTERVAL_MS / 6e4}m)
|
|
@@ -2310,7 +2384,7 @@ var COO_RESTART_COOLDOWN_MS = 5 * 6e4;
|
|
|
2310
2384
|
var IDLE_KILL_INTERVAL_MS = 30 * 1e3;
|
|
2311
2385
|
var _idleTickCounts = /* @__PURE__ */ new Map();
|
|
2312
2386
|
function startIdleKill() {
|
|
2313
|
-
const tick = async () => {
|
|
2387
|
+
const tick = async () => traceDaemonTimer("idle_kill", async () => {
|
|
2314
2388
|
fired("idle_kill");
|
|
2315
2389
|
if (!await ensureStoreForPolling()) return;
|
|
2316
2390
|
try {
|
|
@@ -2321,7 +2395,7 @@ function startIdleKill() {
|
|
|
2321
2395
|
const agentId = file.replace(".terminate", "");
|
|
2322
2396
|
const signalPath = path3.join(signalDir, file);
|
|
2323
2397
|
try {
|
|
2324
|
-
const sessions =
|
|
2398
|
+
const sessions = await getTmuxSessionsAsync();
|
|
2325
2399
|
const match = sessions.find((s) => s.startsWith(`${agentId}-`) || s.startsWith(`${agentId}2-`) || s.startsWith(`${agentId}3-`));
|
|
2326
2400
|
if (match) {
|
|
2327
2401
|
execSyncNode(`tmux kill-session -t ${match} 2>/dev/null`, { timeout: 2e3 });
|
|
@@ -2342,10 +2416,20 @@ function startIdleKill() {
|
|
|
2342
2416
|
if (!cfg) return;
|
|
2343
2417
|
const { getClient } = await import("./database.js");
|
|
2344
2418
|
const { pollIdleKill, createIdleKillRealDeps } = await import("../daemon-orchestration-QVJ26DDN.js");
|
|
2345
|
-
const
|
|
2419
|
+
const liveSessions = (await getTmuxSessionsAsync()).filter((s) => s.includes("-"));
|
|
2420
|
+
const [paneCache, aliveSessions] = await Promise.all([
|
|
2421
|
+
batchCapturePanes(liveSessions, 5),
|
|
2422
|
+
batchPaneAlive(liveSessions)
|
|
2423
|
+
]);
|
|
2424
|
+
const realDeps = createIdleKillRealDeps(
|
|
2346
2425
|
getClient,
|
|
2347
2426
|
cfg.sessionLifecycle.idleKillIntercomAckWindowMs
|
|
2348
2427
|
);
|
|
2428
|
+
const deps = {
|
|
2429
|
+
...realDeps,
|
|
2430
|
+
listTmuxSessions: () => liveSessions,
|
|
2431
|
+
getSessionState: (sessionName) => getCachedSessionState(sessionName, paneCache, aliveSessions)
|
|
2432
|
+
};
|
|
2349
2433
|
const killed = await pollIdleKill(deps, _idleTickCounts, {
|
|
2350
2434
|
ticksRequired: cfg.sessionLifecycle.idleKillTicksRequired,
|
|
2351
2435
|
enabled: cfg.sessionLifecycle.idleKillEnabled
|
|
@@ -2359,7 +2443,7 @@ function startIdleKill() {
|
|
|
2359
2443
|
process.stderr.write(`[exed] Idle kill error: ${err instanceof Error ? err.message : String(err)}
|
|
2360
2444
|
`);
|
|
2361
2445
|
}
|
|
2362
|
-
};
|
|
2446
|
+
});
|
|
2363
2447
|
const timer = setInterval(() => void tick(), IDLE_KILL_INTERVAL_MS);
|
|
2364
2448
|
timer.unref();
|
|
2365
2449
|
process.stderr.write(`[exed] Idle kill started (every ${IDLE_KILL_INTERVAL_MS / 1e3}s)
|
|
@@ -2370,7 +2454,7 @@ function startConsolidation() {
|
|
|
2370
2454
|
const { loadConfig: lc } = await import("./config.js");
|
|
2371
2455
|
return lc();
|
|
2372
2456
|
};
|
|
2373
|
-
const tick = async () => {
|
|
2457
|
+
const tick = async () => traceDaemonTimer("consolidation_tick", async () => {
|
|
2374
2458
|
fired("consolidation");
|
|
2375
2459
|
try {
|
|
2376
2460
|
const config = await loadConfig();
|
|
@@ -2421,8 +2505,9 @@ function startConsolidation() {
|
|
|
2421
2505
|
process.stderr.write(`[exed] Consolidation error: ${err instanceof Error ? err.message : String(err)}
|
|
2422
2506
|
`);
|
|
2423
2507
|
}
|
|
2424
|
-
};
|
|
2425
|
-
|
|
2508
|
+
});
|
|
2509
|
+
void traceDaemonTimer("consolidation_init", async () => {
|
|
2510
|
+
const config = await loadConfig();
|
|
2426
2511
|
const intervalMs = config.consolidationIntervalMs;
|
|
2427
2512
|
const timer = setInterval(() => void tick(), intervalMs);
|
|
2428
2513
|
timer.unref();
|
|
@@ -2717,11 +2802,11 @@ async function refreshAgentData() {
|
|
|
2717
2802
|
}
|
|
2718
2803
|
}
|
|
2719
2804
|
function startAgentStats() {
|
|
2720
|
-
const statsTimer = setInterval(() => void writeAgentStats(), AGENT_STATS_INTERVAL_MS);
|
|
2805
|
+
const statsTimer = setInterval(() => void traceDaemonTimer("agent_stats_write", () => writeAgentStats()), AGENT_STATS_INTERVAL_MS);
|
|
2721
2806
|
statsTimer.unref();
|
|
2722
2807
|
setTimeout(() => {
|
|
2723
|
-
void refreshAgentData();
|
|
2724
|
-
const refreshTimer = setInterval(() => void refreshAgentData(), AGENT_STATS_REFRESH_INTERVAL_MS);
|
|
2808
|
+
void traceDaemonTimer("agent_data_refresh", () => refreshAgentData());
|
|
2809
|
+
const refreshTimer = setInterval(() => void traceDaemonTimer("agent_data_refresh", () => refreshAgentData()), AGENT_STATS_REFRESH_INTERVAL_MS);
|
|
2725
2810
|
refreshTimer.unref();
|
|
2726
2811
|
}, 3 * 60 * 1e3);
|
|
2727
2812
|
process.stderr.write(`[exed] Agent stats started (file every ${AGENT_STATS_INTERVAL_MS / 1e3}s, data refresh every ${AGENT_STATS_REFRESH_INTERVAL_MS / 6e4}m, first refresh at +3m)
|
|
@@ -2791,7 +2876,7 @@ function startReflectionSweep() {
|
|
|
2791
2876
|
`);
|
|
2792
2877
|
}
|
|
2793
2878
|
};
|
|
2794
|
-
setTimeout(async () => {
|
|
2879
|
+
setTimeout(() => void traceDaemonTimer("memory_card_backfill", async () => {
|
|
2795
2880
|
try {
|
|
2796
2881
|
if (!await ensureStoreForPolling()) return;
|
|
2797
2882
|
const { getClient: gc } = await import("./database.js");
|
|
@@ -2836,7 +2921,7 @@ function startReflectionSweep() {
|
|
|
2836
2921
|
process.stderr.write("[exe-daemon] card backfill: " + (e instanceof Error ? e.message : String(e)) + "\n");
|
|
2837
2922
|
}
|
|
2838
2923
|
void tick();
|
|
2839
|
-
}, 5 * 60 * 1e3);
|
|
2924
|
+
}), 5 * 60 * 1e3);
|
|
2840
2925
|
const timer = setInterval(() => void tick(), REFLECTION_SWEEP_INTERVAL_MS);
|
|
2841
2926
|
timer.unref();
|
|
2842
2927
|
process.stderr.write(`[exed] Reflection sweep started (every 6h)
|
|
@@ -2906,7 +2991,7 @@ function startSoftDeletePurge() {
|
|
|
2906
2991
|
}
|
|
2907
2992
|
var QUEUE_DRAIN_INTERVAL_MS = 6e4;
|
|
2908
2993
|
function startIntercomQueueDrain() {
|
|
2909
|
-
const tick = async () => {
|
|
2994
|
+
const tick = async () => traceDaemonTimer("intercom_queue_drain", async () => {
|
|
2910
2995
|
fired("intercom_queue_drain");
|
|
2911
2996
|
try {
|
|
2912
2997
|
const { drainQueue } = await import("../intercom-queue-RNM6EPGA.js");
|
|
@@ -2934,7 +3019,7 @@ function startIntercomQueueDrain() {
|
|
|
2934
3019
|
} catch (e) {
|
|
2935
3020
|
process.stderr.write("[exe-daemon] intercom queue drain: " + (e instanceof Error ? e.message : String(e)) + "\n");
|
|
2936
3021
|
}
|
|
2937
|
-
};
|
|
3022
|
+
});
|
|
2938
3023
|
const timer = setInterval(tick, QUEUE_DRAIN_INTERVAL_MS);
|
|
2939
3024
|
timer.unref();
|
|
2940
3025
|
process.stderr.write(`[exed] Intercom queue drain started (every ${QUEUE_DRAIN_INTERVAL_MS / 1e3}s)
|
|
@@ -3085,7 +3170,7 @@ function getV8HeapLimitBytes() {
|
|
|
3085
3170
|
}
|
|
3086
3171
|
var TASK_ENFORCEMENT_INTERVAL_MS = 6e4;
|
|
3087
3172
|
function startTaskEnforcementScanner() {
|
|
3088
|
-
const tick = async () => {
|
|
3173
|
+
const tick = async () => traceDaemonTimer("task_enforcement", async () => {
|
|
3089
3174
|
fired("task_enforcement");
|
|
3090
3175
|
try {
|
|
3091
3176
|
const { runTaskEnforcementTick } = await import("../task-enforcement-OSPCFH5T.js");
|
|
@@ -3095,10 +3180,20 @@ function startTaskEnforcementScanner() {
|
|
|
3095
3180
|
const { loadEmployeesSync } = await import("./employees.js");
|
|
3096
3181
|
const { sessionScopeFilter } = await import("../task-scope-4CBJ3QI2.js");
|
|
3097
3182
|
const transport = getTransport();
|
|
3098
|
-
const allSessions =
|
|
3099
|
-
const paneCache = await
|
|
3183
|
+
const allSessions = (await getTmuxSessionsAsync()).filter((s) => s.includes("-"));
|
|
3184
|
+
const [paneCache, aliveSessions] = await Promise.all([
|
|
3185
|
+
batchCapturePanes(allSessions, 20),
|
|
3186
|
+
batchPaneAlive(allSessions)
|
|
3187
|
+
]);
|
|
3188
|
+
const enforcementTransport = {
|
|
3189
|
+
listSessions: () => allSessions,
|
|
3190
|
+
capturePane: transport.capturePane.bind(transport),
|
|
3191
|
+
sendKeys: transport.sendKeys.bind(transport),
|
|
3192
|
+
sendKeysLiteral: transport.sendKeysLiteral?.bind(transport),
|
|
3193
|
+
isAlive: (session) => aliveSessions.has(session)
|
|
3194
|
+
};
|
|
3100
3195
|
await runTaskEnforcementTick({
|
|
3101
|
-
transport,
|
|
3196
|
+
transport: enforcementTransport,
|
|
3102
3197
|
agentConfig: loadAgentConfig(),
|
|
3103
3198
|
employees: loadEmployeesSync(),
|
|
3104
3199
|
client: await getClient(),
|
|
@@ -3113,7 +3208,7 @@ function startTaskEnforcementScanner() {
|
|
|
3113
3208
|
`
|
|
3114
3209
|
);
|
|
3115
3210
|
}
|
|
3116
|
-
};
|
|
3211
|
+
});
|
|
3117
3212
|
const timer = setInterval(tick, TASK_ENFORCEMENT_INTERVAL_MS);
|
|
3118
3213
|
timer.unref();
|
|
3119
3214
|
process.stderr.write(`[exed] Task enforcement scanner started (${TASK_ENFORCEMENT_INTERVAL_MS / 1e3}s interval)
|
|
@@ -3199,13 +3294,13 @@ var _apiWatchdogLastNudge = /* @__PURE__ */ new Map();
|
|
|
3199
3294
|
var _apiWatchdogLastError = /* @__PURE__ */ new Map();
|
|
3200
3295
|
var _apiWatchdogNudgeCounts = /* @__PURE__ */ new Map();
|
|
3201
3296
|
function startApiWatchdog() {
|
|
3202
|
-
const tick = async () => {
|
|
3297
|
+
const tick = async () => traceDaemonTimer("api_watchdog", async () => {
|
|
3203
3298
|
fired("api_watchdog");
|
|
3204
3299
|
try {
|
|
3205
3300
|
const cfg = await getCachedConfig();
|
|
3206
3301
|
if (!cfg?.apiWatchdog?.enabled) return;
|
|
3207
3302
|
const cooldownMs = (cfg.apiWatchdog.cooldownMinutes ?? 10) * 6e4;
|
|
3208
|
-
const sessions =
|
|
3303
|
+
const sessions = await getTmuxSessionsAsync();
|
|
3209
3304
|
if (sessions.length === 0) return;
|
|
3210
3305
|
for (const session of sessions) {
|
|
3211
3306
|
if (!session.includes("-")) continue;
|
|
@@ -3270,13 +3365,13 @@ function startApiWatchdog() {
|
|
|
3270
3365
|
process.stderr.write(`[exed] API watchdog error: ${err instanceof Error ? err.message : String(err)}
|
|
3271
3366
|
`);
|
|
3272
3367
|
}
|
|
3273
|
-
};
|
|
3368
|
+
});
|
|
3274
3369
|
const timer = setInterval(() => void tick(), API_WATCHDOG_INTERVAL_MS);
|
|
3275
3370
|
timer.unref();
|
|
3276
3371
|
process.stderr.write("[exed] API watchdog started (30s scan, 10m cooldown per session)\n");
|
|
3277
3372
|
}
|
|
3278
3373
|
function startBackgroundJobGuardrails() {
|
|
3279
|
-
const tick = async () => {
|
|
3374
|
+
const tick = async () => traceDaemonTimer("background_job_guardrails", async () => {
|
|
3280
3375
|
fired("background_job_guardrails");
|
|
3281
3376
|
try {
|
|
3282
3377
|
const { enforceBackgroundJobGuardrails } = await import("../background-jobs-Q4S27FCN.js");
|
|
@@ -3295,7 +3390,7 @@ function startBackgroundJobGuardrails() {
|
|
|
3295
3390
|
process.stderr.write(`[exed] Background job guardrail error: ${err instanceof Error ? err.message : String(err)}
|
|
3296
3391
|
`);
|
|
3297
3392
|
}
|
|
3298
|
-
};
|
|
3393
|
+
});
|
|
3299
3394
|
const timer = setInterval(() => void tick(), 6e4);
|
|
3300
3395
|
timer.unref();
|
|
3301
3396
|
process.stderr.write("[exed] Background job guardrails started (every 60s)\n");
|
|
@@ -3682,7 +3777,7 @@ try {
|
|
|
3682
3777
|
startApiWatchdog();
|
|
3683
3778
|
startRssWatchdog();
|
|
3684
3779
|
setTimeout(startWalCheckpoint, 5e3);
|
|
3685
|
-
setTimeout(async () => {
|
|
3780
|
+
setTimeout(() => void traceDaemonTimer("task_file_resync", async () => {
|
|
3686
3781
|
try {
|
|
3687
3782
|
if (!await ensureStoreForPolling()) return;
|
|
3688
3783
|
const { readdir, readFile } = await import("fs/promises");
|
|
@@ -3750,17 +3845,17 @@ try {
|
|
|
3750
3845
|
process.stderr.write(`[exed] Task re-sync error: ${e.message}
|
|
3751
3846
|
`);
|
|
3752
3847
|
}
|
|
3753
|
-
}, 8e3);
|
|
3848
|
+
}), 8e3);
|
|
3754
3849
|
setTimeout(startIdleKill, 1e4);
|
|
3755
3850
|
setTimeout(startStuckTaskRelease, 15e3);
|
|
3756
3851
|
setTimeout(startOrphanReaper, 2e4);
|
|
3757
3852
|
setTimeout(startCloudSyncTimer, 25e3);
|
|
3758
3853
|
setTimeout(startAgentStats, 3e4);
|
|
3759
|
-
setTimeout(async () => {
|
|
3854
|
+
setTimeout(() => void traceDaemonTimer("session_registry_consistency", async () => {
|
|
3760
3855
|
fired("session_registry_consistency");
|
|
3761
3856
|
try {
|
|
3762
3857
|
const { checkSessionRegistryConsistency } = await import("./session-registry.js");
|
|
3763
|
-
const result = checkSessionRegistryConsistency();
|
|
3858
|
+
const result = checkSessionRegistryConsistency(await getTmuxSessionsAsync());
|
|
3764
3859
|
if (result.missingTmux > 0 || result.missingRegistry > 0) {
|
|
3765
3860
|
acted("session_registry_consistency");
|
|
3766
3861
|
process.stderr.write(
|
|
@@ -3772,8 +3867,8 @@ try {
|
|
|
3772
3867
|
process.stderr.write(`[exed] Session registry consistency error: ${err instanceof Error ? err.message : String(err)}
|
|
3773
3868
|
`);
|
|
3774
3869
|
}
|
|
3775
|
-
}, 35e3);
|
|
3776
|
-
setTimeout(startConsolidation, 6e4);
|
|
3870
|
+
}), 35e3);
|
|
3871
|
+
setTimeout(() => void traceDaemonTimer("consolidation_start", () => startConsolidation()), 6e4);
|
|
3777
3872
|
setTimeout(startSkillSweep, 9e4);
|
|
3778
3873
|
setTimeout(startSkillRefinement, 18e4);
|
|
3779
3874
|
setTimeout(startGraphExtraction, 27e4);
|
|
@@ -3783,10 +3878,10 @@ try {
|
|
|
3783
3878
|
setTimeout(startBugAutoFix, 24e4);
|
|
3784
3879
|
setTimeout(startDatabaseBackup, 27e4);
|
|
3785
3880
|
setTimeout(startAutoUpdateCheck, 3e5);
|
|
3786
|
-
setTimeout(startBackgroundJobGuardrails, 6e4);
|
|
3881
|
+
setTimeout(() => void traceDaemonTimer("background_job_guardrails_start", () => startBackgroundJobGuardrails()), 6e4);
|
|
3787
3882
|
setTimeout(startWorktreeReaper, 12e4);
|
|
3788
3883
|
setTimeout(startZombieAgentReaper, 25e3);
|
|
3789
|
-
setTimeout(async () => {
|
|
3884
|
+
setTimeout(() => void traceDaemonTimer("intercom_dedup_cleanup", async () => {
|
|
3790
3885
|
fired("intercom_dedup_cleanup");
|
|
3791
3886
|
try {
|
|
3792
3887
|
if (!await ensureStoreForPolling()) return;
|
|
@@ -3802,8 +3897,8 @@ try {
|
|
|
3802
3897
|
process.stderr.write(`[exed] Intercom dedup error: ${err instanceof Error ? err.message : String(err)}
|
|
3803
3898
|
`);
|
|
3804
3899
|
}
|
|
3805
|
-
}, 3e4);
|
|
3806
|
-
setTimeout(async () => {
|
|
3900
|
+
}), 3e4);
|
|
3901
|
+
setTimeout(() => void traceDaemonTimer("trace_ttl_sweep", async () => {
|
|
3807
3902
|
fired("trace_ttl_sweep");
|
|
3808
3903
|
try {
|
|
3809
3904
|
if (!await ensureStoreForPolling()) return;
|
|
@@ -3819,8 +3914,8 @@ try {
|
|
|
3819
3914
|
process.stderr.write(`[exed] Trace TTL error: ${err instanceof Error ? err.message : String(err)}
|
|
3820
3915
|
`);
|
|
3821
3916
|
}
|
|
3822
|
-
}, 45e3);
|
|
3823
|
-
setTimeout(async () => {
|
|
3917
|
+
}), 45e3);
|
|
3918
|
+
setTimeout(() => void traceDaemonTimer("orphan_task_cleanup", async () => {
|
|
3824
3919
|
fired("orphan_task_cleanup");
|
|
3825
3920
|
try {
|
|
3826
3921
|
if (!await ensureStoreForPolling()) return;
|
|
@@ -3840,7 +3935,7 @@ try {
|
|
|
3840
3935
|
process.stderr.write(`[exed] Orphan cleanup error: ${err instanceof Error ? err.message : String(err)}
|
|
3841
3936
|
`);
|
|
3842
3937
|
}
|
|
3843
|
-
}, 45e3);
|
|
3938
|
+
}), 45e3);
|
|
3844
3939
|
const HEALTH_HEARTBEAT_MS = 5 * 60 * 1e3;
|
|
3845
3940
|
setInterval(() => {
|
|
3846
3941
|
logHeartbeat();
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
registerAllTools
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-LSARQLX3.js";
|
|
4
4
|
import "../chunk-557C2IGL.js";
|
|
5
5
|
import "../chunk-3GFXV46R.js";
|
|
6
6
|
import "../chunk-BO6HP63V.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-UFOERR37.js";
|
|
8
8
|
import "../chunk-KH5Y6RR4.js";
|
|
9
9
|
import "../chunk-GCMXBQ7Y.js";
|
|
10
10
|
import "../chunk-IENYOYZ6.js";
|
|
@@ -56,7 +56,7 @@ import "../chunk-GMQKS5JD.js";
|
|
|
56
56
|
import "../chunk-K5EXLDQD.js";
|
|
57
57
|
import "../chunk-EF4PA3TY.js";
|
|
58
58
|
import "../chunk-LMSRF47U.js";
|
|
59
|
-
import "../chunk-
|
|
59
|
+
import "../chunk-NVZODD7S.js";
|
|
60
60
|
import "../chunk-E3Q4R3K6.js";
|
|
61
61
|
import "../chunk-CHCA3ZM2.js";
|
|
62
62
|
import "../chunk-XJQASQPO.js";
|
package/dist/mcp/server.js
CHANGED
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
} from "../chunk-V4TZI6EO.js";
|
|
4
4
|
import {
|
|
5
5
|
registerAllTools
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-LSARQLX3.js";
|
|
7
7
|
import "../chunk-557C2IGL.js";
|
|
8
8
|
import "../chunk-3GFXV46R.js";
|
|
9
9
|
import "../chunk-BO6HP63V.js";
|
|
10
|
-
import "../chunk-
|
|
10
|
+
import "../chunk-UFOERR37.js";
|
|
11
11
|
import "../chunk-KH5Y6RR4.js";
|
|
12
12
|
import {
|
|
13
13
|
initLicenseGate
|
|
@@ -66,7 +66,7 @@ import "../chunk-GMQKS5JD.js";
|
|
|
66
66
|
import "../chunk-K5EXLDQD.js";
|
|
67
67
|
import "../chunk-EF4PA3TY.js";
|
|
68
68
|
import "../chunk-LMSRF47U.js";
|
|
69
|
-
import "../chunk-
|
|
69
|
+
import "../chunk-NVZODD7S.js";
|
|
70
70
|
import {
|
|
71
71
|
disposeStore,
|
|
72
72
|
initStore
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askexenow/exe-os",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.214",
|
|
4
4
|
"description": "AI employee operating system — persistent memory, task management, and multi-agent coordination for Claude Code.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|
package/release-notes.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"current": "0.9.
|
|
2
|
+
"current": "0.9.214",
|
|
3
3
|
"notes": {
|
|
4
|
-
"0.9.
|
|
5
|
-
"version": "0.9.
|
|
6
|
-
"date": "2026-06-
|
|
4
|
+
"0.9.214": {
|
|
5
|
+
"version": "0.9.214",
|
|
6
|
+
"date": "2026-06-04",
|
|
7
7
|
"features": [
|
|
8
8
|
"free license telemetry is mandatory, paid can opt out",
|
|
9
9
|
"add mcp-sessions CLI — rich status table for running sessions",
|
|
@@ -32,6 +32,10 @@
|
|
|
32
32
|
"wire update.askexe.com — billing schema + non-fatal image credentials"
|
|
33
33
|
],
|
|
34
34
|
"fixes": [
|
|
35
|
+
"remove failed DB warmup workaround",
|
|
36
|
+
"trace daemon timers and async tmux session checks",
|
|
37
|
+
"add scope comment to DB warmup task query (readiness gate)",
|
|
38
|
+
"add DB warmup at boot+5s to prevent 15s block on first query",
|
|
35
39
|
"move DB memory count query to slow path — fast path is cache-only",
|
|
36
40
|
"split agent stats into fast path (60s) + slow path (10m)",
|
|
37
41
|
"defer agent stats first tick + async file write",
|
|
@@ -52,11 +56,7 @@
|
|
|
52
56
|
"shard circuit breaker, event loop self-healing, heap cap, intercom reason",
|
|
53
57
|
"add generate-hook-manifest to tsup entries — unblocks publish gate",
|
|
54
58
|
"remove unused cleanupExpiredJars import — fixes TS6133 blocking publish",
|
|
55
|
-
"remove dead actualRuntime variable — fixes TS6133 blocking publish"
|
|
56
|
-
"isolate Metal/GPU ops in worker process — reranker dispose crash was killing daemon",
|
|
57
|
-
"remove remaining /exe-intercom invocations + update tests",
|
|
58
|
-
"replace /exe-intercom skill invocation with plain text prompt",
|
|
59
|
-
"remove ALL --strict-mcp-config usage — was blocking /exe-intercom in session MCP config too"
|
|
59
|
+
"remove dead actualRuntime variable — fixes TS6133 blocking publish"
|
|
60
60
|
],
|
|
61
61
|
"security": [
|
|
62
62
|
"fix shell injection, SSRF, socket leaks, backup validation",
|
|
@@ -73,6 +73,8 @@
|
|
|
73
73
|
"fix 4 pricing tier bypass vulnerabilities (audit F1-F4)"
|
|
74
74
|
],
|
|
75
75
|
"other": [
|
|
76
|
+
"bump to v0.9.214",
|
|
77
|
+
"bump to v0.9.213",
|
|
76
78
|
"bump to v0.9.212",
|
|
77
79
|
"bump to v0.9.211",
|
|
78
80
|
"bump to v0.9.210",
|
|
@@ -95,14 +97,12 @@
|
|
|
95
97
|
"bump to v0.9.201",
|
|
96
98
|
"bump to v0.9.200",
|
|
97
99
|
"design orchestration measurement baseline",
|
|
98
|
-
"capture tmux hardening path"
|
|
99
|
-
"add orchestration counterargument",
|
|
100
|
-
"audit tmux orchestration architecture"
|
|
100
|
+
"capture tmux hardening path"
|
|
101
101
|
],
|
|
102
102
|
"migration_notes": []
|
|
103
103
|
},
|
|
104
|
-
"0.9.
|
|
105
|
-
"version": "0.9.
|
|
104
|
+
"0.9.212": {
|
|
105
|
+
"version": "0.9.212",
|
|
106
106
|
"date": "2026-06-03",
|
|
107
107
|
"features": [
|
|
108
108
|
"free license telemetry is mandatory, paid can opt out",
|
|
@@ -132,6 +132,7 @@
|
|
|
132
132
|
"wire update.askexe.com — billing schema + non-fatal image credentials"
|
|
133
133
|
],
|
|
134
134
|
"fixes": [
|
|
135
|
+
"move DB memory count query to slow path — fast path is cache-only",
|
|
135
136
|
"split agent stats into fast path (60s) + slow path (10m)",
|
|
136
137
|
"defer agent stats first tick + async file write",
|
|
137
138
|
"Fix daemon agent stats event-loop stalls",
|
|
@@ -155,8 +156,7 @@
|
|
|
155
156
|
"isolate Metal/GPU ops in worker process — reranker dispose crash was killing daemon",
|
|
156
157
|
"remove remaining /exe-intercom invocations + update tests",
|
|
157
158
|
"replace /exe-intercom skill invocation with plain text prompt",
|
|
158
|
-
"remove ALL --strict-mcp-config usage — was blocking /exe-intercom in session MCP config too"
|
|
159
|
-
"tsup outputs to dist directly — kill dist-next migration shim"
|
|
159
|
+
"remove ALL --strict-mcp-config usage — was blocking /exe-intercom in session MCP config too"
|
|
160
160
|
],
|
|
161
161
|
"security": [
|
|
162
162
|
"fix shell injection, SSRF, socket leaks, backup validation",
|
|
@@ -173,6 +173,7 @@
|
|
|
173
173
|
"fix 4 pricing tier bypass vulnerabilities (audit F1-F4)"
|
|
174
174
|
],
|
|
175
175
|
"other": [
|
|
176
|
+
"bump to v0.9.212",
|
|
176
177
|
"bump to v0.9.211",
|
|
177
178
|
"bump to v0.9.210",
|
|
178
179
|
"bump to v0.9.209",
|
|
@@ -196,13 +197,12 @@
|
|
|
196
197
|
"design orchestration measurement baseline",
|
|
197
198
|
"capture tmux hardening path",
|
|
198
199
|
"add orchestration counterargument",
|
|
199
|
-
"audit tmux orchestration architecture"
|
|
200
|
-
"bump to v0.9.199"
|
|
200
|
+
"audit tmux orchestration architecture"
|
|
201
201
|
],
|
|
202
202
|
"migration_notes": []
|
|
203
203
|
},
|
|
204
|
-
"0.9.
|
|
205
|
-
"version": "0.9.
|
|
204
|
+
"0.9.211": {
|
|
205
|
+
"version": "0.9.211",
|
|
206
206
|
"date": "2026-06-03",
|
|
207
207
|
"features": [
|
|
208
208
|
"free license telemetry is mandatory, paid can opt out",
|
|
@@ -232,6 +232,7 @@
|
|
|
232
232
|
"wire update.askexe.com — billing schema + non-fatal image credentials"
|
|
233
233
|
],
|
|
234
234
|
"fixes": [
|
|
235
|
+
"split agent stats into fast path (60s) + slow path (10m)",
|
|
235
236
|
"defer agent stats first tick + async file write",
|
|
236
237
|
"Fix daemon agent stats event-loop stalls",
|
|
237
238
|
"async-ify task re-sync walk + git worktree list in daemon",
|
|
@@ -255,8 +256,7 @@
|
|
|
255
256
|
"remove remaining /exe-intercom invocations + update tests",
|
|
256
257
|
"replace /exe-intercom skill invocation with plain text prompt",
|
|
257
258
|
"remove ALL --strict-mcp-config usage — was blocking /exe-intercom in session MCP config too",
|
|
258
|
-
"tsup outputs to dist directly — kill dist-next migration shim"
|
|
259
|
-
"drop --strict-mcp-config from lean MCP — was blocking skill loading (/exe-intercom)"
|
|
259
|
+
"tsup outputs to dist directly — kill dist-next migration shim"
|
|
260
260
|
],
|
|
261
261
|
"security": [
|
|
262
262
|
"fix shell injection, SSRF, socket leaks, backup validation",
|
|
@@ -273,6 +273,7 @@
|
|
|
273
273
|
"fix 4 pricing tier bypass vulnerabilities (audit F1-F4)"
|
|
274
274
|
],
|
|
275
275
|
"other": [
|
|
276
|
+
"bump to v0.9.211",
|
|
276
277
|
"bump to v0.9.210",
|
|
277
278
|
"bump to v0.9.209",
|
|
278
279
|
"update release-notes.json",
|
|
@@ -296,13 +297,12 @@
|
|
|
296
297
|
"capture tmux hardening path",
|
|
297
298
|
"add orchestration counterargument",
|
|
298
299
|
"audit tmux orchestration architecture",
|
|
299
|
-
"bump to v0.9.199"
|
|
300
|
-
"remove registry.askexe.com references — fully consolidated to update.askexe.com"
|
|
300
|
+
"bump to v0.9.199"
|
|
301
301
|
],
|
|
302
302
|
"migration_notes": []
|
|
303
303
|
},
|
|
304
|
-
"0.9.
|
|
305
|
-
"version": "0.9.
|
|
304
|
+
"0.9.210": {
|
|
305
|
+
"version": "0.9.210",
|
|
306
306
|
"date": "2026-06-03",
|
|
307
307
|
"features": [
|
|
308
308
|
"free license telemetry is mandatory, paid can opt out",
|
|
@@ -332,6 +332,7 @@
|
|
|
332
332
|
"wire update.askexe.com — billing schema + non-fatal image credentials"
|
|
333
333
|
],
|
|
334
334
|
"fixes": [
|
|
335
|
+
"defer agent stats first tick + async file write",
|
|
335
336
|
"Fix daemon agent stats event-loop stalls",
|
|
336
337
|
"async-ify task re-sync walk + git worktree list in daemon",
|
|
337
338
|
"async worktree reaper — eliminates 30-min event loop blocks",
|
|
@@ -355,8 +356,7 @@
|
|
|
355
356
|
"replace /exe-intercom skill invocation with plain text prompt",
|
|
356
357
|
"remove ALL --strict-mcp-config usage — was blocking /exe-intercom in session MCP config too",
|
|
357
358
|
"tsup outputs to dist directly — kill dist-next migration shim",
|
|
358
|
-
"drop --strict-mcp-config from lean MCP — was blocking skill loading (/exe-intercom)"
|
|
359
|
-
"zombie agent reaper never kills coordinator/exe session processes"
|
|
359
|
+
"drop --strict-mcp-config from lean MCP — was blocking skill loading (/exe-intercom)"
|
|
360
360
|
],
|
|
361
361
|
"security": [
|
|
362
362
|
"fix shell injection, SSRF, socket leaks, backup validation",
|
|
@@ -373,6 +373,7 @@
|
|
|
373
373
|
"fix 4 pricing tier bypass vulnerabilities (audit F1-F4)"
|
|
374
374
|
],
|
|
375
375
|
"other": [
|
|
376
|
+
"bump to v0.9.210",
|
|
376
377
|
"bump to v0.9.209",
|
|
377
378
|
"update release-notes.json",
|
|
378
379
|
"Standardize task completion reports",
|
|
@@ -396,15 +397,16 @@
|
|
|
396
397
|
"add orchestration counterargument",
|
|
397
398
|
"audit tmux orchestration architecture",
|
|
398
399
|
"bump to v0.9.199",
|
|
399
|
-
"remove registry.askexe.com references — fully consolidated to update.askexe.com"
|
|
400
|
-
"bump to 0.9.198 — coordinator reaper guard"
|
|
400
|
+
"remove registry.askexe.com references — fully consolidated to update.askexe.com"
|
|
401
401
|
],
|
|
402
402
|
"migration_notes": []
|
|
403
403
|
},
|
|
404
|
-
"0.9.
|
|
405
|
-
"version": "0.9.
|
|
404
|
+
"0.9.209": {
|
|
405
|
+
"version": "0.9.209",
|
|
406
406
|
"date": "2026-06-03",
|
|
407
407
|
"features": [
|
|
408
|
+
"free license telemetry is mandatory, paid can opt out",
|
|
409
|
+
"add mcp-sessions CLI — rich status table for running sessions",
|
|
408
410
|
"5-minute telemetry batching + per-tool-call usage in payload",
|
|
409
411
|
"disk outbox for failed telemetry + remote killswitch",
|
|
410
412
|
"auto-attach orchestration metrics to every bug report",
|
|
@@ -427,9 +429,7 @@
|
|
|
427
429
|
"scale daemon heap to 25% of system RAM, support 10+ coordinators",
|
|
428
430
|
"add query expansion + benchmark results to retrieval platform procedure",
|
|
429
431
|
"3-mode BEAM benchmark — FTS vs FTS+Graph vs Hybrid",
|
|
430
|
-
"wire update.askexe.com — billing schema + non-fatal image credentials"
|
|
431
|
-
"add 'never defer' platform procedure — fix it now or assign it now",
|
|
432
|
-
"BEAM multi-tier support — 100K, 1M, 10M token scales"
|
|
432
|
+
"wire update.askexe.com — billing schema + non-fatal image credentials"
|
|
433
433
|
],
|
|
434
434
|
"fixes": [
|
|
435
435
|
"Fix daemon agent stats event-loop stalls",
|
|
@@ -473,12 +473,14 @@
|
|
|
473
473
|
"fix 4 pricing tier bypass vulnerabilities (audit F1-F4)"
|
|
474
474
|
],
|
|
475
475
|
"other": [
|
|
476
|
+
"bump to v0.9.209",
|
|
477
|
+
"update release-notes.json",
|
|
478
|
+
"Standardize task completion reports",
|
|
476
479
|
"bump to v0.9.208",
|
|
477
480
|
"bump to v0.9.207",
|
|
478
481
|
"bump to v0.9.206",
|
|
479
482
|
"bump to v0.9.205",
|
|
480
483
|
"bump to v0.9.204",
|
|
481
|
-
"update release-notes.json",
|
|
482
484
|
"bump stack manifest to v0.9.12 — CRM v0.9.44, exe-os v0.9.199",
|
|
483
485
|
"review full orchestration measurement coverage",
|
|
484
486
|
"bump to v0.9.203",
|
|
@@ -495,9 +497,7 @@
|
|
|
495
497
|
"audit tmux orchestration architecture",
|
|
496
498
|
"bump to v0.9.199",
|
|
497
499
|
"remove registry.askexe.com references — fully consolidated to update.askexe.com",
|
|
498
|
-
"bump to 0.9.198 — coordinator reaper guard"
|
|
499
|
-
"bump to 0.9.197 — TTL fix + registry consolidation + TS fixes",
|
|
500
|
-
"update all manifest images to update.askexe.com + compose + beam tuning"
|
|
500
|
+
"bump to 0.9.198 — coordinator reaper guard"
|
|
501
501
|
],
|
|
502
502
|
"migration_notes": []
|
|
503
503
|
}
|
|
File without changes
|