@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.
@@ -4,7 +4,7 @@ import {
4
4
  } from "../chunk-GMQKS5JD.js";
5
5
  import {
6
6
  lightweightSearch
7
- } from "../chunk-UVYFJ7IU.js";
7
+ } from "../chunk-NVZODD7S.js";
8
8
  import "../chunk-E3Q4R3K6.js";
9
9
  import "../chunk-CHCA3ZM2.js";
10
10
  import "../chunk-XJQASQPO.js";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  hybridSearch,
4
4
  lightweightSearch
5
- } from "../chunk-UVYFJ7IU.js";
5
+ } from "../chunk-NVZODD7S.js";
6
6
  import {
7
7
  initStore
8
8
  } from "../chunk-E3Q4R3K6.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  lightweightSearch
3
- } from "./chunk-UVYFJ7IU.js";
3
+ } from "./chunk-NVZODD7S.js";
4
4
  import "./chunk-E3Q4R3K6.js";
5
5
  import "./chunk-CHCA3ZM2.js";
6
6
  import "./chunk-XJQASQPO.js";
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  isRerankerAvailable,
9
9
  rerankWithScores
10
- } from "./chunk-HURHILTM.js";
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-UVYFJ7IU.js";
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-ZRN4LVF3.js");
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-ZRN4LVF3.js");
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-ZRN4LVF3.js");
408
+ const { rerank } = await import("./reranker-AZN6MN2N.js");
409
409
  rerankedRecords = await rerank(effectiveQuery, merged, rerankReturnLimit);
410
410
  }
411
411
  if (rerankedRecords.length > 0) {
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  hybridSearch,
6
6
  lightweightSearch
7
- } from "../chunk-UVYFJ7IU.js";
7
+ } from "../chunk-NVZODD7S.js";
8
8
  import {
9
9
  initStore
10
10
  } from "../chunk-E3Q4R3K6.js";
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "version": 1,
3
- "generatedAt": "2026-06-03T16:18:56.965Z",
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": "17715cf538c6e76761582806b7ae9c5406f13b4b061fb6b8d4ffd89574321e82",
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": "9a7f12e04f302e903e12fa854cabfaf2bbb9ef8256facd2c8f9db4a69c94bd7a",
18
+ "prompt-submit.js": "5722df8ad7789f51bd37dbbd152209e2330952680c686460d393875c5b549072",
19
19
  "session-end.js": "2cfe3cbc196cb11bbe68ae23d128eacc99d1dbbbdd7b3698189922bf5645a71a",
20
- "session-start.js": "05e911eae9f09ebfd1eed24c0325705666d871483685e5b0cd7016a0caec9df9",
20
+ "session-start.js": "0416fc6b642529eb0125b02b892cb0014010294baaf5e864819a4fa745fddfa8",
21
21
  "stop.js": "9c784c10f1a8eddfec9f5dc66463d67a5b09eb21f340e0d92157e9e7befb367b",
22
22
  "subagent-stop.js": "a3d3a01d99dcdcebd5763e5974ce912d69c5f07ba254eb01c2f8c587903ec88c",
23
23
  "summary-worker.js": "f29f29e148ea34b38eab656131b2045e0e4020b526ab8bada9c693eb19dc690e"
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  hybridSearch,
3
3
  lightweightSearch
4
- } from "../chunk-UVYFJ7IU.js";
4
+ } from "../chunk-NVZODD7S.js";
5
5
  import {
6
6
  initStore
7
7
  } from "../chunk-E3Q4R3K6.js";
@@ -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-VAG2IH72.js");
161
+ const { buildCatchupBrief } = await import("../catchup-brief-6AD7QQZB.js");
162
162
  const brief = await buildCatchupBrief(
163
163
  agentId,
164
164
  projectName,
@@ -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 getTmuxSessions() {
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 efs = execFileSyncNode;
415
- _tmuxSessionCache = efs("tmux", ["list-sessions", "-F", "#{session_name}"], { timeout: 3e3 }).toString().trim().split("\n").filter(Boolean);
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 = getTmuxSessions();
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 deps = createIdleKillRealDeps(
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
- loadConfig().then((config) => {
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 = getTmuxSessions().filter((s) => s.includes("-"));
3099
- const paneCache = await batchCapturePanes(allSessions, 20);
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 = getTmuxSessions();
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();
@@ -5,7 +5,7 @@ import {
5
5
  recentRecords,
6
6
  rrfMerge,
7
7
  rrfMergeMulti
8
- } from "../chunk-UVYFJ7IU.js";
8
+ } from "../chunk-NVZODD7S.js";
9
9
  import "../chunk-E3Q4R3K6.js";
10
10
  import "../chunk-CHCA3ZM2.js";
11
11
  import "../chunk-XJQASQPO.js";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  registerAllTools
3
- } from "../chunk-MEP5CND3.js";
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-HURHILTM.js";
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-UVYFJ7IU.js";
59
+ import "../chunk-NVZODD7S.js";
60
60
  import "../chunk-E3Q4R3K6.js";
61
61
  import "../chunk-CHCA3ZM2.js";
62
62
  import "../chunk-XJQASQPO.js";
@@ -3,11 +3,11 @@ import {
3
3
  } from "../chunk-V4TZI6EO.js";
4
4
  import {
5
5
  registerAllTools
6
- } from "../chunk-MEP5CND3.js";
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-HURHILTM.js";
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-UVYFJ7IU.js";
69
+ import "../chunk-NVZODD7S.js";
70
70
  import {
71
71
  disposeStore,
72
72
  initStore
@@ -5,7 +5,7 @@ import {
5
5
  rerank,
6
6
  rerankWithContext,
7
7
  rerankWithScores
8
- } from "./chunk-HURHILTM.js";
8
+ } from "./chunk-UFOERR37.js";
9
9
  import "./chunk-WXW3XGWX.js";
10
10
  import "./chunk-LYH5HE24.js";
11
11
  import "./chunk-MLKGABMK.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askexenow/exe-os",
3
- "version": "0.9.212",
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",
@@ -1,9 +1,9 @@
1
1
  {
2
- "current": "0.9.212",
2
+ "current": "0.9.214",
3
3
  "notes": {
4
- "0.9.212": {
5
- "version": "0.9.212",
6
- "date": "2026-06-03",
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.211": {
105
- "version": "0.9.211",
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.210": {
205
- "version": "0.9.210",
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.209": {
305
- "version": "0.9.209",
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.208": {
405
- "version": "0.9.208",
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