@askexenow/exe-os 0.9.166 → 0.9.167

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.
Files changed (244) hide show
  1. package/deploy/compose/backup.sh +45 -7
  2. package/deploy/compose/setup.sh +7 -0
  3. package/deploy/stack-manifests/v0.9.json +40 -1
  4. package/dist/{active-agent-R2KMWMR6.js → active-agent-DGTIJN2U.js} +2 -2
  5. package/dist/{active-agent-CYMM3QQA.js → active-agent-HVMLG6FH.js} +2 -2
  6. package/dist/{agentic-ontology-GKAKYNPE.js → agentic-ontology-S54AFODT.js} +1 -1
  7. package/dist/{backfill-metadata-Z5SYUWAV.js → backfill-metadata-74IWETRF.js} +4 -3
  8. package/dist/{behaviors-QGU6XI5R.js → behaviors-LZVAVHTC.js} +2 -2
  9. package/dist/bin/agentic-ontology-backfill.js +5 -4
  10. package/dist/bin/agentic-reflection-backfill.js +6 -5
  11. package/dist/bin/agentic-semantic-label.js +5 -4
  12. package/dist/bin/backfill-conversations.js +5 -4
  13. package/dist/bin/backfill-responses.js +5 -4
  14. package/dist/bin/backfill-vectors.js +6 -5
  15. package/dist/bin/bulk-sync-postgres.js +6 -5
  16. package/dist/bin/cleanup-stale-review-tasks.js +9 -9
  17. package/dist/bin/cli.js +16 -13
  18. package/dist/bin/daily-summary.js +0 -217
  19. package/dist/bin/deferred-daemon-restart.js +8 -0
  20. package/dist/bin/exe-agent-config.js +1 -1
  21. package/dist/bin/exe-agent.js +10 -10
  22. package/dist/bin/exe-assign.js +7 -6
  23. package/dist/bin/exe-boot.js +20 -19
  24. package/dist/bin/exe-call.js +4 -4
  25. package/dist/bin/exe-cloud.js +3 -3
  26. package/dist/bin/exe-dispatch.js +9 -9
  27. package/dist/bin/exe-doctor.js +1 -1
  28. package/dist/bin/exe-export-behaviors.js +7 -6
  29. package/dist/bin/exe-forget.js +6 -5
  30. package/dist/bin/exe-gateway.js +5 -5
  31. package/dist/bin/exe-heartbeat.js +9 -9
  32. package/dist/bin/exe-kill.js +13 -12
  33. package/dist/bin/exe-launch-agent.js +11 -10
  34. package/dist/bin/exe-new-employee.js +6 -6
  35. package/dist/bin/exe-pending-messages.js +10 -10
  36. package/dist/bin/exe-pending-notifications.js +9 -9
  37. package/dist/bin/exe-pending-reviews.js +9 -9
  38. package/dist/bin/exe-rename.js +4 -4
  39. package/dist/bin/exe-review.js +12 -11
  40. package/dist/bin/exe-search.js +5 -4
  41. package/dist/bin/exe-session-cleanup.js +19 -14
  42. package/dist/bin/exe-settings.js +3 -3
  43. package/dist/bin/exe-start-codex.js +11 -10
  44. package/dist/bin/exe-start-opencode.js +8 -7
  45. package/dist/bin/exe-status.js +10 -10
  46. package/dist/bin/exe-team.js +2 -2
  47. package/dist/bin/git-sweep.js +9 -9
  48. package/dist/bin/graph-backfill.js +4 -3
  49. package/dist/bin/graph-export.js +5 -4
  50. package/dist/bin/import-history.js +171 -0
  51. package/dist/bin/install-launchd.js +41 -0
  52. package/dist/bin/install.js +50 -74
  53. package/dist/bin/intercom-check.js +4 -4
  54. package/dist/bin/postgres-agentic-reflection-backfill.js +2 -2
  55. package/dist/bin/postgres-agentic-semantic-backfill.js +4 -4
  56. package/dist/bin/pre-publish.js +1 -1
  57. package/dist/bin/scan-tasks.js +22 -12
  58. package/dist/bin/setup.js +1 -1
  59. package/dist/bin/shard-migrate.js +4 -3
  60. package/dist/bin/stack-update.js +61 -857
  61. package/dist/bin/vps-backup.js +170 -0
  62. package/dist/bin/vps-health-gate.js +232 -0
  63. package/dist/{capacity-monitor-ZEAE4WP2.js → capacity-monitor-JBZB2S4P.js} +10 -10
  64. package/dist/{catchup-brief-OGWCHENC.js → catchup-brief-HE2EMZS5.js} +12 -11
  65. package/dist/{chunk-DJJNB47C.js → chunk-27DO3EZO.js} +1 -1
  66. package/dist/{chunk-45FYZIHI.js → chunk-32YUET3Y.js} +2 -2
  67. package/dist/{chunk-Y75ECPO5.js → chunk-3FW5LUGI.js} +2 -2
  68. package/dist/{chunk-4OZGQZ4U.js → chunk-3M3O56VT.js} +636 -179
  69. package/dist/{chunk-77WQOD6J.js → chunk-4CXUZ4NI.js} +2 -2
  70. package/dist/{chunk-PBXWPHEK.js → chunk-4VEHJZ6R.js} +1 -1
  71. package/dist/{chunk-TH22QIEC.js → chunk-6A4COFDG.js} +1 -1
  72. package/dist/{chunk-ACBTCC2L.js → chunk-7OJH2A6I.js} +1 -1
  73. package/dist/{chunk-NHCOTCI6.js → chunk-A7SGEBXJ.js} +2 -2
  74. package/dist/{chunk-5MPQSNZF.js → chunk-AUTCT6AY.js} +1 -1
  75. package/dist/{chunk-OEKSTOTE.js → chunk-AZAZ2C75.js} +1 -1
  76. package/dist/chunk-CHCA3ZM2.js +167 -0
  77. package/dist/{chunk-X347L57O.js → chunk-CSTJQDOE.js} +4 -3
  78. package/dist/{chunk-B234R3VW.js → chunk-D7WLV6WD.js} +2 -2
  79. package/dist/{chunk-GMXF3AHJ.js → chunk-DGAONW36.js} +1 -1
  80. package/dist/chunk-EAT5YL3W.js +229 -0
  81. package/dist/{chunk-OD4H5YCJ.js → chunk-EKTQE2R5.js} +8 -8
  82. package/dist/{chunk-Z44PC42G.js → chunk-ELUBA7XL.js} +2 -2
  83. package/dist/{chunk-ZWS6XQER.js → chunk-F5AKOE4P.js} +7 -7
  84. package/dist/{chunk-T5YULDDO.js → chunk-FVI4UBKO.js} +27 -4
  85. package/dist/{chunk-ESRI7MFI.js → chunk-GAN7PW6G.js} +28 -24
  86. package/dist/{chunk-K4OWYJSP.js → chunk-GM2WZTG3.js} +2 -2
  87. package/dist/{chunk-TAB5QGIK.js → chunk-GZYQTPTF.js} +3 -3
  88. package/dist/{chunk-CXDU5DE3.js → chunk-IAUNGATJ.js} +1 -1
  89. package/dist/{chunk-YS63NS6M.js → chunk-IHSM5GR4.js} +1 -1
  90. package/dist/{chunk-23PTS2ZD.js → chunk-IP7KJAUW.js} +117 -15
  91. package/dist/{chunk-D6IMJAV2.js → chunk-J64P2LB2.js} +2 -2
  92. package/dist/{chunk-CXAVSQZM.js → chunk-JXMSCKRM.js} +1 -1
  93. package/dist/{chunk-RQMK3IQH.js → chunk-K4OTJP6N.js} +14 -7
  94. package/dist/{chunk-L7ROZR2H.js → chunk-KXAUMIOX.js} +1 -1
  95. package/dist/{chunk-TPC3LAP7.js → chunk-LGY2BIOT.js} +13 -0
  96. package/dist/{chunk-RPIDSBK7.js → chunk-LLHRJEE4.js} +3 -3
  97. package/dist/{chunk-6WG2VIKC.js → chunk-LM7H6XU4.js} +1 -1
  98. package/dist/{chunk-Y6GMKZZ2.js → chunk-LOFFGJSY.js} +150 -23
  99. package/dist/{chunk-W7SDGBEC.js → chunk-MFI5OXYW.js} +52 -84
  100. package/dist/{chunk-KNPEVPYG.js → chunk-MSSQWF6X.js} +2 -2
  101. package/dist/{chunk-QIQAO3VG.js → chunk-NEFFFKMD.js} +3 -3
  102. package/dist/{chunk-YUC552KZ.js → chunk-NEHONJJC.js} +3 -3
  103. package/dist/{chunk-KZ7SXZ2V.js → chunk-NFMQRLCD.js} +1 -1
  104. package/dist/{chunk-52HCNDPG.js → chunk-O4TATDOV.js} +1 -1
  105. package/dist/{chunk-AR3OYGLB.js → chunk-PEFBRL4S.js} +28 -6
  106. package/dist/{chunk-AEUXUEJG.js → chunk-PEXVU3HU.js} +5 -3
  107. package/dist/chunk-Q2G5C3HV.js +217 -0
  108. package/dist/{chunk-KOO56JVC.js → chunk-Q6N6LDEJ.js} +1 -1
  109. package/dist/{chunk-TXSJ2L5O.js → chunk-QI4IXJN7.js} +1 -1
  110. package/dist/{chunk-HLVQ5Y7B.js → chunk-RE4VLK45.js} +1 -1
  111. package/dist/{chunk-TF6SZGDT.js → chunk-SA2PH6WY.js} +1 -1
  112. package/dist/{chunk-5RSYY7BE.js → chunk-SJYOPYXH.js} +117 -9
  113. package/dist/{chunk-PJGHBANY.js → chunk-TTJE7CCU.js} +1 -1
  114. package/dist/{chunk-A7KEWR6S.js → chunk-TXWQPL2U.js} +1 -1
  115. package/dist/{chunk-XXSJ35J5.js → chunk-U5ZH52FB.js} +2 -2
  116. package/dist/{chunk-G4FDG3LK.js → chunk-UVNDLF74.js} +63 -40
  117. package/dist/{chunk-5OD3AFRW.js → chunk-V6RCZ25F.js} +1 -1
  118. package/dist/{chunk-LHMBIFKD.js → chunk-VYNNN2S3.js} +4 -4
  119. package/dist/chunk-WCYT54XP.js +934 -0
  120. package/dist/{chunk-5AMSQRHT.js → chunk-XGYSTVUH.js} +1 -1
  121. package/dist/{chunk-MKZBHM6A.js → chunk-XLWF3C4R.js} +4 -4
  122. package/dist/{chunk-YL36L2SN.js → chunk-Y7YHLV57.js} +1 -1
  123. package/dist/{chunk-HZC4MR4H.js → chunk-YBKB2PXY.js} +1 -1
  124. package/dist/{chunk-NWM3A4TK.js → chunk-ZDNLKXZA.js} +1 -1
  125. package/dist/{chunk-O7KW6QMH.js → chunk-ZW4TKQUM.js} +15 -5
  126. package/dist/{chunk-6BURHBE6.js → chunk-ZXB44R3E.js} +32 -11
  127. package/dist/co-occurrence-WCED475N.js +73 -0
  128. package/dist/{code-context-index-B6VIWPSF.js → code-context-index-LSZ3DKTJ.js} +2 -2
  129. package/dist/{crdt-sync-XA22KI3S.js → crdt-sync-PBXZTHZC.js} +1 -1
  130. package/dist/{crm-webhook-CIZNOEY4.js → crm-webhook-W7Q25VZU.js} +2 -2
  131. package/dist/{cto-delegation-gate-H5IULFRC.js → cto-delegation-gate-JKULOLMC.js} +8 -8
  132. package/dist/{daemon-orchestration-VO5XQIJL.js → daemon-orchestration-CHV6MB42.js} +13 -11
  133. package/dist/{exe-drift-DMT75WR3.js → exe-drift-PW36OULT.js} +2 -2
  134. package/dist/{exe-export-2RZWOSX6.js → exe-export-XQOD3KE6.js} +6 -5
  135. package/dist/{exe-import-NFNYATHL.js → exe-import-QOFP67LW.js} +6 -5
  136. package/dist/{exe-key-4D7CF3BU.js → exe-key-WQ34UZR6.js} +1 -1
  137. package/dist/{fast-db-init-LAEISZQ2.js → fast-db-init-UKETGWQI.js} +1 -1
  138. package/dist/gateway/index.js +6 -6
  139. package/dist/{git-staleness-M46AYLPP.js → git-staleness-ATV5CGAP.js} +1 -1
  140. package/dist/{git-task-sweep-PXOS56YT.js → git-task-sweep-KXZRIP4T.js} +9 -9
  141. package/dist/{global-procedures-KROQQX54.js → global-procedures-G6IKCYKM.js} +3 -3
  142. package/dist/{graph-auto-extract-QJ2BBJM2.js → graph-auto-extract-ZJXJOLE2.js} +1 -1
  143. package/dist/hooks/bug-report-worker.js +10 -10
  144. package/dist/hooks/codex-stop-task-finalizer.js +10 -10
  145. package/dist/hooks/commit-complete.js +11 -11
  146. package/dist/hooks/error-recall.js +8 -7
  147. package/dist/hooks/exe-heartbeat-hook.js +2 -2
  148. package/dist/hooks/ingest-worker.js +3 -3
  149. package/dist/hooks/ingest.js +9 -9
  150. package/dist/hooks/instructions-loaded.js +3 -3
  151. package/dist/hooks/notification.js +3 -3
  152. package/dist/hooks/post-compact.js +10 -10
  153. package/dist/hooks/post-tool-combined.js +5 -5
  154. package/dist/hooks/pre-compact.js +16 -16
  155. package/dist/hooks/pre-tool-use.js +14 -14
  156. package/dist/hooks/prompt-submit.js +30 -29
  157. package/dist/hooks/session-end.js +46 -25
  158. package/dist/hooks/session-start.js +48 -10
  159. package/dist/hooks/stop.js +17 -17
  160. package/dist/hooks/subagent-stop.js +10 -10
  161. package/dist/hooks/summary-worker.js +17 -16
  162. package/dist/index.js +17 -17
  163. package/dist/{installer-SDBLJBAB.js → installer-DE2LH5EC.js} +4 -4
  164. package/dist/{installer-ZA6QNQ4P.js → installer-M2MDS7HC.js} +4 -4
  165. package/dist/{installer-6KAY6LD6.js → installer-VE23YFXU.js} +4 -4
  166. package/dist/{intercom-queue-K3DVKSPJ.js → intercom-queue-RNM6EPGA.js} +1 -1
  167. package/dist/keyword-extractor-UJHFWVZE.js +11 -0
  168. package/dist/lib/cloud-sync.js +3 -3
  169. package/dist/lib/consolidation.js +5 -4
  170. package/dist/lib/database.js +1 -1
  171. package/dist/lib/db-daemon-client.js +1 -1
  172. package/dist/lib/db.js +1 -1
  173. package/dist/lib/embed-worker.js +98 -0
  174. package/dist/lib/embedder.js +2 -2
  175. package/dist/lib/employee-templates.js +4 -4
  176. package/dist/lib/employees.js +1 -1
  177. package/dist/lib/exe-daemon-client.js +1 -1
  178. package/dist/lib/exe-daemon.js +523 -500
  179. package/dist/lib/hybrid-search.js +5 -6
  180. package/dist/lib/identity.js +1 -1
  181. package/dist/lib/messaging.js +9 -9
  182. package/dist/lib/reminders.js +2 -2
  183. package/dist/lib/schedules.js +5 -4
  184. package/dist/lib/skill-learning.js +3 -3
  185. package/dist/lib/store.js +4 -3
  186. package/dist/lib/task-router.js +2 -2
  187. package/dist/lib/tasks.js +9 -9
  188. package/dist/lib/tmux-routing.js +8 -8
  189. package/dist/lib/tmux-transport.js +1 -1
  190. package/dist/lib/token-spend.js +2 -2
  191. package/dist/lib/transport.js +2 -2
  192. package/dist/lib/ws-client.js +3 -1
  193. package/dist/mcp/register-tools.js +54 -51
  194. package/dist/mcp/server.js +58 -55
  195. package/dist/mcp/tools/complete-reminder.js +3 -3
  196. package/dist/mcp/tools/create-reminder.js +3 -3
  197. package/dist/mcp/tools/create-task.js +11 -11
  198. package/dist/mcp/tools/deactivate-behavior.js +4 -4
  199. package/dist/mcp/tools/list-reminders.js +3 -3
  200. package/dist/mcp/tools/list-tasks.js +11 -11
  201. package/dist/mcp/tools/send-message.js +11 -11
  202. package/dist/mcp/tools/update-task.js +10 -10
  203. package/dist/{mcp-http-config-LK2EDOEJ.js → mcp-http-config-Z2E4VUOF.js} +2 -2
  204. package/dist/{memory-cards-V3DKSRWL.js → memory-cards-SFDKDIAW.js} +1 -1
  205. package/dist/memory-graph-extractor-YD4GNH7T.js +16 -0
  206. package/dist/{memory-poisoning-defense-3B75HS74.js → memory-poisoning-defense-VEGNFELN.js} +1 -1
  207. package/dist/{memory-queue-client-LFPZPPQA.js → memory-queue-client-5HB2XUH7.js} +2 -2
  208. package/dist/{memory-reflection-HTDAUUE5.js → memory-reflection-MTPRQNI6.js} +2 -2
  209. package/dist/{notifications-76VCYXWW.js → notifications-6TCE6OBG.js} +8 -8
  210. package/dist/{orchestrator-CBNSBI5P.js → orchestrator-W2GYJR23.js} +10 -10
  211. package/dist/{plan-limits-SOR3QXKV.js → plan-limits-4EP46323.js} +2 -2
  212. package/dist/{projection-worker-FK5YOEIL.js → projection-worker-EBUYNMU2.js} +1 -1
  213. package/dist/{review-polling-ZLNDUKL4.js → review-polling-2N7KQFZZ.js} +9 -9
  214. package/dist/runtime/index.js +15 -15
  215. package/dist/{session-events-CUSPL25D.js → session-events-K47FHAXJ.js} +9 -9
  216. package/dist/{session-kill-telemetry-FLBRHBDP.js → session-kill-telemetry-275YUXM5.js} +2 -2
  217. package/dist/{session-scope-PX2ABSJO.js → session-scope-XSFJZEER.js} +8 -8
  218. package/dist/{setup-wizard-Y6PBZGFX.js → setup-wizard-UEO7HYLQ.js} +1 -1
  219. package/dist/{skill-refinement-L7PGKCYO.js → skill-refinement-WXBTANDQ.js} +1 -1
  220. package/dist/stack-update-2B2UXREV.js +50 -0
  221. package/dist/{task-enforcement-7FUILB63.js → task-enforcement-2JIJSXPU.js} +14 -16
  222. package/dist/{task-scope-2N45TE32.js → task-scope-W73Z3XWE.js} +8 -8
  223. package/dist/{tasks-crud-ADLCGHGH.js → tasks-crud-HPJKI3QQ.js} +8 -8
  224. package/dist/{tasks-review-PJ2DUI6N.js → tasks-review-MXLMPGNZ.js} +8 -8
  225. package/dist/{token-budget-T5DFXVTM.js → token-budget-BA46CVHX.js} +1 -1
  226. package/dist/{tool-capability-index-6JJN6ZRC.js → tool-capability-index-42VVN5BS.js} +1 -1
  227. package/dist/{tool-telemetry-72PVO5HV.js → tool-telemetry-GZ5E2AUL.js} +1 -1
  228. package/dist/tui/App.js +22 -18
  229. package/dist/{tui-data-63JHE6EZ.js → tui-data-PVXWQCJX.js} +8 -8
  230. package/dist/{worker-gate-REVBJUZ6.js → worker-gate-WTTK64TK.js} +1 -1
  231. package/dist/{workflow-engine-W2WNHJG5.js → workflow-engine-LT3WTT7V.js} +2 -2
  232. package/package.json +1 -1
  233. package/release-notes.json +209 -209
  234. /package/dist/{chunk-BNOZUS6J.js → chunk-6VVCAVRT.js} +0 -0
  235. /package/dist/{chunk-IC7GKK6I.js → chunk-CWQZZ7X3.js} +0 -0
  236. /package/dist/{chunk-ZI2ZVERO.js → chunk-EIW5GOBW.js} +0 -0
  237. /package/dist/{chunk-2BGGDNRD.js → chunk-IPPJEM26.js} +0 -0
  238. /package/dist/{chunk-4ISDU5KR.js → chunk-K5UR73PM.js} +0 -0
  239. /package/dist/{chunk-ZWRTVUQ6.js → chunk-KIMO5S45.js} +0 -0
  240. /package/dist/{chunk-S2FX5KJ4.js → chunk-WBLILGAP.js} +0 -0
  241. /package/dist/{core-memory-PCJ3L46L.js → core-memory-RAC6M67J.js} +0 -0
  242. /package/dist/{entity-boost-GHFPE6A2.js → entity-boost-5FIRFRDC.js} +0 -0
  243. /package/dist/{message-queue-client-CHRQYBH5.js → message-queue-client-PTQ2S7D7.js} +0 -0
  244. /package/dist/{wiki-acl-QYRAYYVQ.js → wiki-acl-MSDRCIAI.js} +0 -0
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  recordSessionKill
3
- } from "./chunk-T5YULDDO.js";
3
+ } from "./chunk-FVI4UBKO.js";
4
4
  import {
5
5
  updateTask
6
- } from "./chunk-ZWS6XQER.js";
6
+ } from "./chunk-F5AKOE4P.js";
7
7
  import {
8
8
  ensureEmployee,
9
9
  extractRootExe,
@@ -14,20 +14,20 @@ import {
14
14
  sessionScopeFilter,
15
15
  strictSessionScopeFilter,
16
16
  writeNotification
17
- } from "./chunk-W7SDGBEC.js";
17
+ } from "./chunk-MFI5OXYW.js";
18
18
  import {
19
19
  queueIntercom
20
- } from "./chunk-TXSJ2L5O.js";
20
+ } from "./chunk-QI4IXJN7.js";
21
21
  import {
22
22
  listSessions
23
23
  } from "./chunk-64WZEXXA.js";
24
- import {
25
- getTransport
26
- } from "./chunk-A7KEWR6S.js";
27
24
  import {
28
25
  listTmuxSessions,
29
26
  parseContextPercentage
30
27
  } from "./chunk-GZIAQYGI.js";
28
+ import {
29
+ getTransport
30
+ } from "./chunk-TXWQPL2U.js";
31
31
  import {
32
32
  getAgentRuntime
33
33
  } from "./chunk-H2CFBUGF.js";
@@ -35,7 +35,7 @@ import {
35
35
  baseAgentName,
36
36
  isCoordinatorName,
37
37
  shouldAutoInstance
38
- } from "./chunk-5RSYY7BE.js";
38
+ } from "./chunk-SJYOPYXH.js";
39
39
  import {
40
40
  loadConfigSync
41
41
  } from "./chunk-4GXRETYL.js";
@@ -43,8 +43,8 @@ import {
43
43
  // src/lib/daemon-orchestration.ts
44
44
  import { execSync } from "child_process";
45
45
  import { randomUUID } from "crypto";
46
- import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync } from "fs";
47
- import { homedir } from "os";
46
+ import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync, unlinkSync, statSync } from "fs";
47
+ import { homedir, loadavg, freemem, cpus as osCpus } from "os";
48
48
  import { join } from "path";
49
49
 
50
50
  // src/lib/agent-signals.ts
@@ -131,6 +131,7 @@ async function collectAgentSignals(client, agentId, sessionName, intercomAckWind
131
131
  }
132
132
 
133
133
  // src/lib/daemon-orchestration.ts
134
+ var cpuCount = () => osCpus().length;
134
135
  var IDLE_NUDGE_DEDUP_MS = Number(process.env.EXE_NUDGE_INTERVAL_MS) || 6e4;
135
136
  var SESSION_TTL_HOURS = Number(process.env.EXE_SESSION_TTL_HOURS) || 8;
136
137
  var SESSION_CONTEXT_THRESHOLD_PCT = Number(process.env.EXE_CONTEXT_KILL_PCT) || 80;
@@ -304,6 +305,13 @@ async function pollIdleKill(deps, idleTickCounts, opts) {
304
305
  }
305
306
  }
306
307
  }
308
+ if (entry.registeredAt) {
309
+ const ageMs = Date.now() - new Date(entry.registeredAt).getTime();
310
+ if (ageMs < 5 * 60 * 1e3) {
311
+ idleTickCounts.delete(entry.windowName);
312
+ continue;
313
+ }
314
+ }
307
315
  if (signals.hasOpenTasks || signals.hasNeedsReview || signals.hasUnreadInbox || signals.hadRecentIntercomAck) {
308
316
  idleTickCounts.delete(entry.windowName);
309
317
  continue;
@@ -318,6 +326,25 @@ async function pollIdleKill(deps, idleTickCounts, opts) {
318
326
  ticksRequired: opts.ticksRequired,
319
327
  enabled: opts.enabled
320
328
  });
329
+ const warningThreshold = Math.max(1, Math.floor(opts.ticksRequired * 0.7));
330
+ if (nextTicks === warningThreshold && !shouldKill) {
331
+ try {
332
+ const { execFileSync: warnExec } = await import("child_process");
333
+ const shutdownMsg = [
334
+ "/exe-intercom SHUTDOWN WARNING: Your session will be terminated in ~90 seconds due to inactivity.",
335
+ "All your tasks are complete. Before shutdown:",
336
+ "1. store_memory() any important decisions, discoveries, or context from this session",
337
+ "2. If you learned anything non-obvious, commit it to memory for future sessions",
338
+ "3. If you have in-progress thoughts or plans, checkpoint them now",
339
+ "This is your last chance to persist state. After shutdown, this context is lost."
340
+ ].join(" ");
341
+ warnExec("tmux", ["send-keys", "-t", entry.windowName, "-l", shutdownMsg], { timeout: 2e3 });
342
+ warnExec("tmux", ["send-keys", "-t", entry.windowName, "Enter"], { timeout: 1e3 });
343
+ process.stderr.write(`[exed] Idle wind-down warning sent to ${entry.windowName} (tick ${nextTicks}/${opts.ticksRequired})
344
+ `);
345
+ } catch {
346
+ }
347
+ }
321
348
  if (shouldKill) {
322
349
  process.stderr.write(
323
350
  `[exed] Idle kill: ${entry.windowName} (agentId=${entry.agentId}, ticks=${nextTicks})
@@ -518,15 +545,89 @@ function createIdleKillRealDeps(getClient, intercomAckWindowMs) {
518
545
  }
519
546
  var AUTO_WAKE_COOLDOWN_MS = 5 * 60 * 1e3;
520
547
  var AUTO_WAKE_MAX_RETRIES = 3;
521
- var _autoWakeLastSpawn = /* @__PURE__ */ new Map();
522
- var _autoWakeTaskRetries = /* @__PURE__ */ new Map();
523
- var _autoWakeRecentSpawns = /* @__PURE__ */ new Map();
548
+ var AUTO_WAKE_STATE_PATH = join(homedir(), ".exe-os", "session-cache", "auto-wake-state.json");
524
549
  var CRASH_LOOP_WINDOW_MS = 15 * 60 * 1e3;
525
550
  var CRASH_LOOP_THRESHOLD = 3;
551
+ var BACKOFF_BASE_MS = 2 * 60 * 1e3;
552
+ var BACKOFF_CAP_MS = 30 * 60 * 1e3;
553
+ var CPU_PRESSURE_THRESHOLD = 80;
554
+ var FREE_RAM_MIN_GB = 4;
555
+ function loadAutoWakeState() {
556
+ try {
557
+ if (existsSync2(AUTO_WAKE_STATE_PATH)) {
558
+ const raw = JSON.parse(readFileSync2(AUTO_WAKE_STATE_PATH, "utf8"));
559
+ return {
560
+ lastSpawn: raw.lastSpawn ?? {},
561
+ taskRetries: raw.taskRetries ?? {},
562
+ recentSpawns: raw.recentSpawns ?? {},
563
+ crashLoopCount: raw.crashLoopCount ?? {},
564
+ lastSaved: raw.lastSaved ?? 0
565
+ };
566
+ }
567
+ } catch {
568
+ }
569
+ return { lastSpawn: {}, taskRetries: {}, recentSpawns: {}, crashLoopCount: {}, lastSaved: 0 };
570
+ }
571
+ function saveAutoWakeState(state) {
572
+ try {
573
+ state.lastSaved = Date.now();
574
+ writeFileSync(AUTO_WAKE_STATE_PATH, JSON.stringify(state), "utf8");
575
+ } catch {
576
+ }
577
+ }
578
+ var _autoWakeState = loadAutoWakeState();
579
+ var _autoWakeLastSpawn = {
580
+ get: (key) => _autoWakeState.lastSpawn[key],
581
+ set: (key, val) => {
582
+ _autoWakeState.lastSpawn[key] = val;
583
+ }
584
+ };
585
+ var _autoWakeTaskRetries = {
586
+ get: (key) => _autoWakeState.taskRetries[key],
587
+ set: (key, val) => {
588
+ _autoWakeState.taskRetries[key] = val;
589
+ }
590
+ };
591
+ var _autoWakeRecentSpawns = {
592
+ get: (key) => _autoWakeState.recentSpawns[key],
593
+ set: (key, val) => {
594
+ _autoWakeState.recentSpawns[key] = val;
595
+ }
596
+ };
526
597
  function _resetAutoWakeState() {
527
- _autoWakeLastSpawn.clear();
528
- _autoWakeTaskRetries.clear();
529
- _autoWakeRecentSpawns.clear();
598
+ _autoWakeState = { lastSpawn: {}, taskRetries: {}, recentSpawns: {}, crashLoopCount: {}, lastSaved: 0 };
599
+ try {
600
+ unlinkSync(AUTO_WAKE_STATE_PATH);
601
+ } catch {
602
+ }
603
+ }
604
+ function checkAutoWakeGates(key, nowMs) {
605
+ try {
606
+ const lagMarker = join(homedir(), ".exe-os", "session-cache", "event-loop-blocked.marker");
607
+ if (existsSync2(lagMarker)) {
608
+ const age = nowMs - statSync(lagMarker).mtimeMs;
609
+ if (age < 6e4) return "daemon_event_loop_blocked";
610
+ }
611
+ } catch {
612
+ }
613
+ const loopCount = _autoWakeState.crashLoopCount[key] ?? 0;
614
+ if (loopCount > 0) {
615
+ const backoffMs = Math.min(BACKOFF_BASE_MS * Math.pow(2, loopCount - 1), BACKOFF_CAP_MS);
616
+ const lastSpawn = _autoWakeState.lastSpawn[key] ?? 0;
617
+ if (nowMs - lastSpawn < backoffMs) {
618
+ return `crash_loop_backoff_${Math.round(backoffMs / 6e4)}min`;
619
+ }
620
+ }
621
+ try {
622
+ const loadAvg = loadavg()[0];
623
+ const cpus = cpuCount();
624
+ const loadPct = loadAvg / cpus * 100;
625
+ if (loadPct > CPU_PRESSURE_THRESHOLD) return `cpu_pressure_${Math.round(loadPct)}pct`;
626
+ const freeGB = freemem() / 1024 ** 3;
627
+ if (freeGB < FREE_RAM_MIN_GB) return `low_ram_${freeGB.toFixed(1)}gb`;
628
+ } catch {
629
+ }
630
+ return null;
530
631
  }
531
632
  function shouldAutoWake(input) {
532
633
  if (isCoordinatorName(input.agentId)) return false;
@@ -537,6 +638,12 @@ function shouldAutoWake(input) {
537
638
  return true;
538
639
  }
539
640
  async function pollOrphanedTasks(deps, nowMs = Date.now()) {
641
+ const globalGate = checkAutoWakeGates("__global__", nowMs);
642
+ if (globalGate) {
643
+ process.stderr.write(`[auto-wake] GLOBAL GATE BLOCKED: ${globalGate} \u2014 skipping all spawns
644
+ `);
645
+ return [];
646
+ }
540
647
  let liveSessions;
541
648
  try {
542
649
  liveSessions = deps.listTmuxSessions();
@@ -606,24 +713,33 @@ async function pollOrphanedTasks(deps, nowMs = Date.now()) {
606
713
  const recentSpawns = _autoWakeRecentSpawns.get(key) ?? [];
607
714
  const recentCount = recentSpawns.filter((ts) => nowMs - ts < CRASH_LOOP_WINDOW_MS).length;
608
715
  if (recentCount >= CRASH_LOOP_THRESHOLD) {
716
+ const loopCount = (_autoWakeState.crashLoopCount[key] ?? 0) + 1;
717
+ _autoWakeState.crashLoopCount[key] = loopCount;
718
+ const backoffMs = Math.min(BACKOFF_BASE_MS * Math.pow(2, loopCount - 1), BACKOFF_CAP_MS);
609
719
  process.stderr.write(
610
- `[auto-wake] CRASH LOOP DETECTED: ${agentId} spawned ${recentCount} times in 5 min \u2014 suspending auto-wake. Manual intervention required.
720
+ `[auto-wake] CRASH LOOP #${loopCount}: ${agentId} spawned ${recentCount}x in ${CRASH_LOOP_WINDOW_MS / 6e4}min \u2014 backoff ${Math.round(backoffMs / 6e4)}min
611
721
  `
612
722
  );
723
+ saveAutoWakeState(_autoWakeState);
613
724
  try {
614
- const { writeNotification: writeNotification2 } = await import("./notifications-76VCYXWW.js");
615
- await writeNotification2({
725
+ await writeNotification({
616
726
  agentId,
617
727
  agentRole: "employee",
618
728
  event: "error_spike",
619
729
  project: String(tasks[0]?.sessionScope ?? ""),
620
- summary: `Crash loop: ${agentId} died ${recentCount} times in 5 min. Auto-wake suspended. Check session logs.`,
730
+ summary: `Crash loop #${loopCount}: ${agentId} died ${recentCount}x. Backoff ${Math.round(backoffMs / 6e4)}min. Check session-deaths.jsonl.`,
621
731
  sessionScope
622
732
  });
623
733
  } catch {
624
734
  }
625
735
  continue;
626
736
  }
737
+ const agentGate = checkAutoWakeGates(key, nowMs);
738
+ if (agentGate) {
739
+ process.stderr.write(`[auto-wake] AGENT GATE BLOCKED: ${agentId} \u2014 ${agentGate}
740
+ `);
741
+ continue;
742
+ }
627
743
  const topTask = tasks[0];
628
744
  const retries = _autoWakeTaskRetries.get(topTask.taskId) ?? 0;
629
745
  if (retries >= AUTO_WAKE_MAX_RETRIES) {
@@ -671,6 +787,7 @@ async function pollOrphanedTasks(deps, nowMs = Date.now()) {
671
787
  spawns.push(nowMs);
672
788
  while (spawns.length > 0 && nowMs - spawns[0] > CRASH_LOOP_WINDOW_MS) spawns.shift();
673
789
  _autoWakeRecentSpawns.set(key, spawns);
790
+ saveAutoWakeState(_autoWakeState);
674
791
  woken.push(agentId);
675
792
  } catch (err) {
676
793
  process.stderr.write(
@@ -1105,7 +1222,16 @@ var HOOK_PROCESS_PATTERNS = [
1105
1222
  "scan-tasks.js",
1106
1223
  "exe-pending-reviews.js",
1107
1224
  "exe-pending-messages.js",
1108
- "exe-pending-notifications.js"
1225
+ "exe-pending-notifications.js",
1226
+ // Hook scripts that can zombie (added 2026-06-01 — orphan bug a4eaf106)
1227
+ "prompt-submit.js",
1228
+ "stop.js",
1229
+ "subagent-stop.js",
1230
+ "pre-tool-use.js",
1231
+ "post-tool-combined.js",
1232
+ "ingest.js",
1233
+ "intercom-check.js",
1234
+ "exe-heartbeat-hook.js"
1109
1235
  ];
1110
1236
  var ZOMBIE_AGENT_MAX_AGE_SECS = 300;
1111
1237
  function reapZombieAgentProcesses(deps) {
@@ -1400,7 +1526,7 @@ async function reapOrphanedWorktrees(deps, nowMs = Date.now()) {
1400
1526
  async function createWorktreeReaperRealDeps() {
1401
1527
  const { getPaneCwd } = await import("./lib/tmux-status.js");
1402
1528
  const { getGitRoot, isWorktreeDirty: isDirty } = await import("./worktree-OMPQEJH7.js");
1403
- const { statSync } = await import("fs");
1529
+ const { statSync: statSync2 } = await import("fs");
1404
1530
  const { basename } = await import("path");
1405
1531
  return {
1406
1532
  listTmuxSessions: () => listTmuxSessions(),
@@ -1432,7 +1558,7 @@ async function createWorktreeReaperRealDeps() {
1432
1558
  isWorktreeDirty: (wtPath) => isDirty(wtPath),
1433
1559
  getDirMtimeMs: (dirPath) => {
1434
1560
  try {
1435
- return statSync(dirPath).mtimeMs;
1561
+ return statSync2(dirPath).mtimeMs;
1436
1562
  } catch {
1437
1563
  return null;
1438
1564
  }
@@ -1508,6 +1634,7 @@ export {
1508
1634
  CRASH_LOOP_WINDOW_MS,
1509
1635
  CRASH_LOOP_THRESHOLD,
1510
1636
  _resetAutoWakeState,
1637
+ checkAutoWakeGates,
1511
1638
  shouldAutoWake,
1512
1639
  pollOrphanedTasks,
1513
1640
  STUCK_TASK_GRACE_MS,
@@ -3,16 +3,16 @@ import {
3
3
  } from "./chunk-LOQCOHEW.js";
4
4
  import {
5
5
  queueIntercom
6
- } from "./chunk-TXSJ2L5O.js";
6
+ } from "./chunk-QI4IXJN7.js";
7
7
  import {
8
8
  registerSession
9
9
  } from "./chunk-64WZEXXA.js";
10
- import {
11
- getTransport
12
- } from "./chunk-A7KEWR6S.js";
13
10
  import {
14
11
  listTmuxSessions
15
12
  } from "./chunk-GZIAQYGI.js";
13
+ import {
14
+ getTransport
15
+ } from "./chunk-TXWQPL2U.js";
16
16
  import {
17
17
  DEFAULT_PROVIDER,
18
18
  PROVIDER_TABLE,
@@ -30,13 +30,13 @@ import {
30
30
  import {
31
31
  PlanLimitError,
32
32
  assertEmployeeLimitSync
33
- } from "./chunk-HLVQ5Y7B.js";
34
- import {
35
- getProjectName
36
- } from "./chunk-OPU3NYOO.js";
33
+ } from "./chunk-RE4VLK45.js";
37
34
  import {
38
35
  getSessionKey
39
36
  } from "./chunk-CVYC6DUW.js";
37
+ import {
38
+ getProjectName
39
+ } from "./chunk-OPU3NYOO.js";
40
40
  import {
41
41
  getAgentContext
42
42
  } from "./chunk-GJV3WDWM.js";
@@ -45,12 +45,11 @@ import {
45
45
  } from "./chunk-MP2AFCGL.js";
46
46
  import {
47
47
  ensureAgentSymlink
48
- } from "./chunk-YS63NS6M.js";
48
+ } from "./chunk-IHSM5GR4.js";
49
49
  import {
50
50
  expandDualPrefixTools
51
51
  } from "./chunk-HYZV25LY.js";
52
52
  import {
53
- DEFAULT_BOOT_TIMEOUT_MS,
54
53
  baseAgentName,
55
54
  getClient,
56
55
  getCoordinatorName,
@@ -58,7 +57,7 @@ import {
58
57
  isCoordinatorName,
59
58
  loadEmployees,
60
59
  loadEmployeesSync
61
- } from "./chunk-5RSYY7BE.js";
60
+ } from "./chunk-SJYOPYXH.js";
62
61
  import {
63
62
  loadDeviceId
64
63
  } from "./chunk-MVMMULOJ.js";
@@ -72,7 +71,7 @@ import {
72
71
 
73
72
  // src/lib/tmux-routing.ts
74
73
  import { execFileSync, execSync as execSync2 } from "child_process";
75
- import { readFileSync as readFileSync3, writeFileSync, mkdirSync as mkdirSync2, existsSync as existsSync5, appendFileSync as appendFileSync2, readdirSync as readdirSync3, openSync, closeSync, writeSync, renameSync as renameSync2, constants } from "fs";
74
+ import { readFileSync as readFileSync3, writeFileSync, mkdirSync as mkdirSync2, existsSync as existsSync5, appendFileSync as appendFileSync2, openSync, closeSync, writeSync, renameSync as renameSync2, constants } from "fs";
76
75
  import path5 from "path";
77
76
  import os4 from "os";
78
77
  import { fileURLToPath } from "url";
@@ -359,7 +358,7 @@ async function createTaskCore(input) {
359
358
  if (isCoordinatorSession) {
360
359
  earlySessionScope = resolved;
361
360
  } else {
362
- const { getSessionProject } = await import("./session-scope-PX2ABSJO.js");
361
+ const { getSessionProject } = await import("./session-scope-XSFJZEER.js");
363
362
  const sessionProject = getSessionProject(resolved);
364
363
  if (sessionProject && sessionProject !== input.projectName) {
365
364
  scopeMismatchWarning = `session/project mismatch: session "${resolved}" owns "${sessionProject}" but task targets "${input.projectName}". Routed to default scope.`;
@@ -440,7 +439,7 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
440
439
  const sessionScope = earlySessionScope;
441
440
  try {
442
441
  await client.execute({
443
- sql: `INSERT INTO tasks (id, title, assigned_to, assigned_by, project_name, priority, status, task_file, blocked_by, parent_task_id, reviewer, context, complexity, budget_tokens, budget_fallback_model, tokens_used, tokens_warned_at, session_scope, spawn_runtime, spawn_model, device_id, created_at, updated_at)
442
+ sql: `INSERT OR IGNORE INTO tasks (id, title, assigned_to, assigned_by, project_name, priority, status, task_file, blocked_by, parent_task_id, reviewer, context, complexity, budget_tokens, budget_fallback_model, tokens_used, tokens_warned_at, session_scope, spawn_runtime, spawn_model, device_id, created_at, updated_at)
444
443
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
445
444
  args: [
446
445
  id,
@@ -783,7 +782,7 @@ async function updateTaskStatus(input) {
783
782
  } catch {
784
783
  }
785
784
  try {
786
- const { writeNotification: writeNotification2 } = await import("./notifications-76VCYXWW.js");
785
+ const { writeNotification: writeNotification2 } = await import("./notifications-6TCE6OBG.js");
787
786
  await writeNotification2({
788
787
  agentId: reviewer,
789
788
  agentRole: isCoordinatorName(reviewer) ? "COO" : "manager",
@@ -958,7 +957,7 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
958
957
  }
959
958
  if (input.status === "done" || input.status === "needs_review") {
960
959
  try {
961
- const { incrementSkillSuccess } = await import("./skill-refinement-L7PGKCYO.js");
960
+ const { incrementSkillSuccess } = await import("./skill-refinement-WXBTANDQ.js");
962
961
  await incrementSkillSuccess(
963
962
  String(row.assigned_to),
964
963
  row.project_name ? String(row.project_name) : null
@@ -968,7 +967,7 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
968
967
  }
969
968
  if (input.status === "done" || input.status === "needs_review" || input.status === "cancelled" || input.status === "closed") {
970
969
  try {
971
- const { clearQueueForAgent } = await import("./intercom-queue-K3DVKSPJ.js");
970
+ const { clearQueueForAgent } = await import("./intercom-queue-RNM6EPGA.js");
972
971
  clearQueueForAgent(String(row.assigned_to));
973
972
  } catch {
974
973
  }
@@ -2036,7 +2035,7 @@ async function verifyPaneAtCapacity(sessionName) {
2036
2035
  reason: `capture-pane failed: ${err instanceof Error ? err.message : String(err)}`
2037
2036
  };
2038
2037
  }
2039
- const { isAtCapacity } = await import("./capacity-monitor-ZEAE4WP2.js");
2038
+ const { isAtCapacity } = await import("./capacity-monitor-JBZB2S4P.js");
2040
2039
  if (!isAtCapacity(pane)) {
2041
2040
  return {
2042
2041
  atCapacity: false,
@@ -2169,10 +2168,6 @@ function sendIntercom(targetSession, opts) {
2169
2168
  }
2170
2169
  } catch {
2171
2170
  }
2172
- if (isExeSession(targetSession)) {
2173
- logIntercom(`SKIP_COORDINATOR \u2192 ${targetSession} (coordinator sessions use prompt-submit hook)`);
2174
- return "skipped_exe";
2175
- }
2176
2171
  if (!opts?.force && isDebounced(targetSession)) {
2177
2172
  logIntercom(`DEBOUNCE \u2192 ${targetSession} (nudge batched, task safe in DB)`);
2178
2173
  return "debounced";
@@ -2190,7 +2185,7 @@ function sendIntercom(targetSession, opts) {
2190
2185
  logIntercom(`QUEUED \u2192 ${targetSession} (no claude process)${batched2 > 0 ? ` [${batched2} batched]` : ""}`);
2191
2186
  return "queued";
2192
2187
  }
2193
- if (sessionState === "thinking" || sessionState === "tool") {
2188
+ if (!opts?.force && (sessionState === "thinking" || sessionState === "tool")) {
2194
2189
  queueIntercom(targetSession, "session busy at send time");
2195
2190
  const batched2 = recordDebounce(targetSession);
2196
2191
  logIntercom(`QUEUED \u2192 ${targetSession} (session busy)${batched2 > 0 ? ` [${batched2} batched]` : ""}`);
@@ -2208,24 +2203,6 @@ function sendIntercom(targetSession, opts) {
2208
2203
  } catch {
2209
2204
  }
2210
2205
  }
2211
- try {
2212
- const rawAgent = targetSession.split("-")[0] ?? targetSession;
2213
- const agent = baseAgentName(rawAgent);
2214
- const taskDir = path5.join(process.cwd(), "exe", agent);
2215
- if (existsSync5(taskDir)) {
2216
- const files = readdirSync3(taskDir).filter(
2217
- (f) => f.endsWith(".md") && f !== "DONE.txt"
2218
- );
2219
- if (files.length === 0) {
2220
- logIntercom(`SKIP \u2192 ${targetSession} (no task files in exe/${agent}/ \u2014 nothing to do)`);
2221
- return "debounced";
2222
- }
2223
- } else {
2224
- logIntercom(`SKIP \u2192 ${targetSession} (no task folder exe/${agent}/ \u2014 nothing to do)`);
2225
- return "debounced";
2226
- }
2227
- } catch {
2228
- }
2229
2206
  if (transport.isPaneInCopyMode(targetSession)) {
2230
2207
  logIntercom(`COPY_MODE \u2192 ${targetSession} (exiting copy mode first)`);
2231
2208
  transport.sendKeys(targetSession, "q");
@@ -2246,11 +2223,7 @@ function sendIntercom(targetSession, opts) {
2246
2223
  }
2247
2224
  if (actualRuntime === "codex" || actualRuntime === "opencode" || actualRuntime === "exe-agent") {
2248
2225
  const msg = "You have a new P0 task. Run list_tasks to find it.";
2249
- if (transport.sendKeysLiteral) {
2250
- transport.sendKeysLiteral(targetSession, msg);
2251
- } else {
2252
- transport.sendKeys(targetSession, msg);
2253
- }
2226
+ transport.sendKeysLiteral(targetSession, msg);
2254
2227
  } else {
2255
2228
  transport.sendKeys(targetSession, "/exe-intercom");
2256
2229
  }
@@ -2630,17 +2603,12 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
2630
2603
  });
2631
2604
  } catch {
2632
2605
  }
2633
- let agentBootTimeout = DEFAULT_BOOT_TIMEOUT_MS;
2634
- try {
2635
- const roster = loadEmployeesSync();
2636
- const emp = roster.find((e) => baseAgentName(e.name) === baseAgentName(employeeName));
2637
- if (emp?.bootTimeout && emp.bootTimeout > 0) agentBootTimeout = emp.bootTimeout;
2638
- } catch {
2639
- }
2606
+ const callerIsDaemon = process.env.EXE_IS_DAEMON === "1";
2607
+ const POLL_CAP_MS = callerIsDaemon ? 0 : 45e3;
2640
2608
  const POLL_INTERVAL_MS = 500;
2641
- const bootPollIterations = Math.ceil(agentBootTimeout / POLL_INTERVAL_MS);
2609
+ const pollIterations = Math.ceil(POLL_CAP_MS / POLL_INTERVAL_MS);
2642
2610
  let booted = false;
2643
- for (let i = 0; i < bootPollIterations; i++) {
2611
+ for (let i = 0; i < pollIterations; i++) {
2644
2612
  try {
2645
2613
  execSync2("sleep 0.5");
2646
2614
  } catch {
@@ -2670,43 +2638,43 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
2670
2638
  releaseSpawnLock(sessionName);
2671
2639
  const runtimeLabel = useExeAgent ? "exe-agent" : useCodex ? "codex" : "claude";
2672
2640
  process.stderr.write(
2673
- `[tmux-routing] ${runtimeLabel} boot poll timed out for ${sessionName} after ${agentBootTimeout / 1e3}s \u2014 session may need manual intervention
2641
+ `[tmux-routing] ${runtimeLabel} boot poll capped at ${POLL_CAP_MS / 1e3}s for ${sessionName} \u2014 sending task nudge anyway
2674
2642
  `
2675
2643
  );
2676
2644
  }
2677
2645
  if (!useExeAgent && !useCodex) {
2678
- try {
2679
- transport.sendKeys(sessionName, `/exe-call ${employeeName}`);
2680
- } catch (e) {
2681
- process.stderr.write("[tmux-routing] sendKeys /exe-call " + employeeName + ": " + (e instanceof Error ? e.message : String(e)) + "\n");
2682
- }
2683
- try {
2684
- let callDone = false;
2685
- for (let i = 0; i < 30; i++) {
2686
- try {
2687
- execSync2("sleep 0.5");
2688
- } catch {
2689
- }
2690
- try {
2691
- const pane = transport.capturePane(sessionName);
2692
- if (i >= 8 && pane.includes("\u276F") && !pane.includes("Considering")) {
2693
- callDone = true;
2694
- break;
2695
- }
2696
- } catch {
2697
- }
2646
+ if (callerIsDaemon) {
2647
+ try {
2648
+ const empRoster = loadEmployeesSync();
2649
+ const bootCache = {
2650
+ agentId: employeeName,
2651
+ agentRole: empRoster.find((e) => baseAgentName(e.name) === baseAgentName(employeeName))?.role ?? "employee",
2652
+ sessionName,
2653
+ exeSession,
2654
+ dispatchedAt: (/* @__PURE__ */ new Date()).toISOString()
2655
+ };
2656
+ const cachePath = path5.join(os4.homedir(), ".exe-os", "session-cache", `boot-cache-${sessionName}.json`);
2657
+ writeFileSync(cachePath, JSON.stringify(bootCache));
2658
+ } catch {
2698
2659
  }
2699
- if (callDone) {
2700
- transport.sendKeys(sessionName, `/exe-intercom You have pending tasks. Start your highest priority task immediately.`);
2701
- process.stderr.write(`[tmux-routing] auto-start: sent work nudge to ${sessionName}
2660
+ const _transport = transport;
2661
+ const _session = sessionName;
2662
+ const _emp = employeeName;
2663
+ setTimeout(() => {
2664
+ try {
2665
+ _transport.sendKeysLiteral(_session, `You have pending tasks. Run list_tasks and start your highest priority task immediately.`);
2666
+ } catch (e) {
2667
+ process.stderr.write(`[tmux-routing] deferred nudge ${_emp}: ${e.message}
2702
2668
  `);
2703
- } else {
2704
- process.stderr.write(`[tmux-routing] auto-start: /exe-call did not complete within 15s for ${sessionName}, skipping nudge
2669
+ }
2670
+ }, 1e4);
2671
+ } else {
2672
+ try {
2673
+ transport.sendKeysLiteral(sessionName, `You have pending tasks. Run list_tasks and start immediately.`);
2674
+ } catch (e) {
2675
+ process.stderr.write(`[tmux-routing] CLI nudge ${employeeName}: ${e instanceof Error ? e.message : String(e)}
2705
2676
  `);
2706
2677
  }
2707
- } catch (e) {
2708
- process.stderr.write(`[tmux-routing] auto-start nudge failed for ${sessionName}: ${e instanceof Error ? e.message : String(e)}
2709
- `);
2710
2678
  }
2711
2679
  }
2712
2680
  registerSession({
@@ -2,7 +2,7 @@ import {
2
2
  listWorkflowDefinitions,
3
3
  runWorkflow,
4
4
  startWorkflow
5
- } from "./chunk-5MPQSNZF.js";
5
+ } from "./chunk-AUTCT6AY.js";
6
6
  import {
7
7
  initCRMBridge
8
8
  } from "./chunk-ONKIWA3R.js";
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-MP2AFCGL.js";
12
12
  import {
13
13
  getClient
14
- } from "./chunk-5RSYY7BE.js";
14
+ } from "./chunk-SJYOPYXH.js";
15
15
 
16
16
  // src/gateway/router.ts
17
17
  function matchesPlatform(msgPlatform, matchPlatform) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isCrdtSyncEnabled
3
- } from "./chunk-BNOZUS6J.js";
3
+ } from "./chunk-6VVCAVRT.js";
4
4
  import {
5
5
  decryptSyncBlob,
6
6
  encryptSyncBlob,
@@ -12,7 +12,7 @@ import {
12
12
  loadEmployees,
13
13
  registerBinSymlinks,
14
14
  saveEmployees
15
- } from "./chunk-5RSYY7BE.js";
15
+ } from "./chunk-SJYOPYXH.js";
16
16
  import {
17
17
  loadDeviceId
18
18
  } from "./chunk-MVMMULOJ.js";
@@ -489,7 +489,7 @@ async function cloudSync(config) {
489
489
  let pulled = 0;
490
490
  if (pullResult.records.length > 0) {
491
491
  if (isCrdtSyncEnabled()) {
492
- const { initCrdtDoc, importExistingMemories, readAllMemories } = await import("./crdt-sync-XA22KI3S.js");
492
+ const { initCrdtDoc, importExistingMemories, readAllMemories } = await import("./crdt-sync-PBXZTHZC.js");
493
493
  initCrdtDoc();
494
494
  importExistingMemories(
495
495
  pullResult.records.map((rec) => ({
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  fastDbInit
3
- } from "./chunk-4ISDU5KR.js";
3
+ } from "./chunk-K5UR73PM.js";
4
4
  import {
5
5
  sessionScopeFilter
6
- } from "./chunk-W7SDGBEC.js";
6
+ } from "./chunk-MFI5OXYW.js";
7
7
  import {
8
8
  formatStatusAll,
9
9
  formatStatusDeep,
@@ -14,7 +14,7 @@ import {
14
14
  getClient,
15
15
  isCoordinatorRole,
16
16
  loadEmployees
17
- } from "./chunk-5RSYY7BE.js";
17
+ } from "./chunk-SJYOPYXH.js";
18
18
  import {
19
19
  isMainModule
20
20
  } from "./chunk-6Y4B3QF6.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  writeMemoryViaDaemon
3
- } from "./chunk-5OD3AFRW.js";
3
+ } from "./chunk-V6RCZ25F.js";
4
4
 
5
5
  // src/lib/auto-checkpoint.ts
6
6
  var FILE_RE = /(?:^|\s)([\w./-]+\.(?:ts|tsx|js|jsx|json|md|yml|yaml|sql|go|py|css|scss|html|sh))(?:\b|$)/g;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getIdentity,
3
3
  loadEmployeesSync
4
- } from "./chunk-5RSYY7BE.js";
4
+ } from "./chunk-SJYOPYXH.js";
5
5
 
6
6
  // src/lib/drift-probes.ts
7
7
  var DRIFT_THRESHOLD = 80;