@askexenow/exe-os 0.9.342 → 0.9.343

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 (358) hide show
  1. package/dist/{active-agent-TNIO6IY3.js → active-agent-MDGDKGCL.js} +4 -4
  2. package/dist/{active-agent-PVGE57FY.js → active-agent-SNVSJFI5.js} +4 -4
  3. package/dist/{agentic-ontology-3FXYMHKW.js → agentic-ontology-SCG6UUHK.js} +1 -1
  4. package/dist/{backfill-gate-65LSYVE5.js → backfill-gate-HARARX5F.js} +2 -2
  5. package/dist/{backfill-metadata-ZSMZC45J.js → backfill-metadata-SCQ5FPDR.js} +5 -5
  6. package/dist/{background-jobs-EXR5RVGG.js → background-jobs-KKRO3QRO.js} +2 -2
  7. package/dist/{backup-verify-3Y2FHGZU.js → backup-verify-KDLOT4RP.js} +3 -3
  8. package/dist/{behaviors-KYRB3NGJ.js → behaviors-MICGF3H3.js} +6 -6
  9. package/dist/bin/age-ontology-load.js +2 -2
  10. package/dist/bin/agentic-ontology-backfill.js +7 -7
  11. package/dist/bin/agentic-reflection-backfill.js +8 -8
  12. package/dist/bin/agentic-semantic-label.js +7 -7
  13. package/dist/bin/backfill-conversations.js +7 -7
  14. package/dist/bin/backfill-responses.js +7 -7
  15. package/dist/bin/backfill-vectors.js +16 -16
  16. package/dist/bin/bulk-sync-postgres.js +15 -15
  17. package/dist/bin/cc-doctor.js +8 -8
  18. package/dist/bin/cleanup-stale-review-tasks.js +20 -19
  19. package/dist/bin/cli.js +23 -23
  20. package/dist/bin/daemon-restart-handoff.js +27 -0
  21. package/dist/bin/deferred-daemon-restart.js +116 -89
  22. package/dist/bin/exe-agent-config.js +4 -4
  23. package/dist/bin/exe-agent.js +13 -13
  24. package/dist/bin/exe-assign.js +9 -9
  25. package/dist/bin/exe-boot.js +34 -33
  26. package/dist/bin/exe-call.js +6 -6
  27. package/dist/bin/exe-cloud.js +16 -16
  28. package/dist/bin/exe-config-dump.js +4 -4
  29. package/dist/bin/exe-dispatch.js +20 -19
  30. package/dist/bin/exe-doctor.js +6 -6
  31. package/dist/bin/exe-export-behaviors.js +10 -10
  32. package/dist/bin/exe-forget.js +9 -9
  33. package/dist/bin/exe-gateway.js +8 -8
  34. package/dist/bin/exe-grant.js +4 -4
  35. package/dist/bin/exe-healthcheck.js +8 -8
  36. package/dist/bin/exe-heartbeat.js +20 -19
  37. package/dist/bin/exe-kill.js +25 -24
  38. package/dist/bin/exe-launch-agent.js +46 -31
  39. package/dist/bin/exe-memory-reads.js +5 -5
  40. package/dist/bin/exe-new-employee.js +10 -10
  41. package/dist/bin/exe-os-mcp-proxy.js +365 -0
  42. package/dist/bin/exe-pending-messages.js +21 -20
  43. package/dist/bin/exe-pending-notifications.js +20 -19
  44. package/dist/bin/exe-pending-reviews.js +20 -19
  45. package/dist/bin/exe-rename.js +6 -6
  46. package/dist/bin/exe-review.js +24 -23
  47. package/dist/bin/exe-search.js +6 -6
  48. package/dist/bin/exe-session-cleanup.js +23 -22
  49. package/dist/bin/exe-settings.js +16 -16
  50. package/dist/bin/exe-start-codex.js +17 -17
  51. package/dist/bin/exe-start-opencode.js +9 -9
  52. package/dist/bin/exe-status.js +21 -20
  53. package/dist/bin/exe-support.js +4 -4
  54. package/dist/bin/exe-team.js +4 -4
  55. package/dist/bin/git-sweep.js +21 -20
  56. package/dist/bin/graph-backfill.js +6 -6
  57. package/dist/bin/graph-export.js +8 -8
  58. package/dist/bin/import-history.js +8 -8
  59. package/dist/bin/install.js +87 -86
  60. package/dist/bin/intercom-check.js +4 -4
  61. package/dist/bin/mcp-sessions.js +2 -2
  62. package/dist/bin/orchestration-metrics.js +5 -5
  63. package/dist/bin/postgres-agentic-reflection-backfill.js +4 -4
  64. package/dist/bin/postgres-agentic-semantic-backfill.js +3 -3
  65. package/dist/bin/pre-publish.js +1 -1
  66. package/dist/bin/reconcile-backlog.js +2 -2
  67. package/dist/bin/registry-proxy.js +1 -1
  68. package/dist/bin/scan-tasks.js +20 -19
  69. package/dist/bin/setup.js +3 -3
  70. package/dist/bin/shard-migrate.js +6 -6
  71. package/dist/bin/stack-update.js +5 -5
  72. package/dist/bin/vps-health-gate.js +1 -1
  73. package/dist/{boot-generation-BL2ISK4U.js → boot-generation-CFA5NKSK.js} +4 -4
  74. package/dist/{boot-review-sections-DBMQJT5N.js → boot-review-sections-FX2FYZJQ.js} +19 -18
  75. package/dist/{branch-hygiene-TZWK6QCF.js → branch-hygiene-PILXQQDF.js} +1 -1
  76. package/dist/{branding-DVXBGVDH.js → branding-ZSC6YN63.js} +2 -2
  77. package/dist/{capability-cards-DN5UIKVN.js → capability-cards-O27UB3J5.js} +3 -3
  78. package/dist/{capacity-monitor-ZG5GGFR2.js → capacity-monitor-5DVZY3SM.js} +21 -20
  79. package/dist/{catchup-brief-D6HH6DWS.js → catchup-brief-3GYI6AKV.js} +23 -22
  80. package/dist/{chunk-YTCFACP4.js → chunk-25ORSHR7.js} +137 -137
  81. package/dist/{chunk-PDWS3E22.js → chunk-2F7WGH5K.js} +6 -6
  82. package/dist/{chunk-JLZ4RYSD.js → chunk-2VZMLKNS.js} +2 -2
  83. package/dist/{chunk-CNVBKDEY.js → chunk-2YPCD2UH.js} +12 -12
  84. package/dist/{chunk-HAF2DJYV.js → chunk-34RULPS2.js} +3 -3
  85. package/dist/{chunk-JPUZPAAF.js → chunk-3MLSM77R.js} +3 -3
  86. package/dist/{chunk-JTBIS4R5.js → chunk-3OO34BOT.js} +1 -1
  87. package/dist/{chunk-L4A5DL6Z.js → chunk-3OR54BBE.js} +3 -3
  88. package/dist/{chunk-USSB56WK.js → chunk-3PFP7GV2.js} +1 -1
  89. package/dist/{chunk-TLT7NZCW.js → chunk-4AA2HRIM.js} +3 -3
  90. package/dist/{chunk-PQIDGXSG.js → chunk-4E3SZEEI.js} +2 -2
  91. package/dist/chunk-4EI5AHHR.js +37 -0
  92. package/dist/{chunk-6XWTQUO4.js → chunk-4MLSFZLY.js} +19 -8
  93. package/dist/{chunk-AJYCFKJR.js → chunk-4UIYLTA3.js} +1 -1
  94. package/dist/{chunk-I26FWCSP.js → chunk-4VUAG6DN.js} +1 -1
  95. package/dist/{chunk-V3EEVY4L.js → chunk-54O2FWRM.js} +1 -1
  96. package/dist/{chunk-TTCUG2CF.js → chunk-5DSVWSL5.js} +2 -2
  97. package/dist/{chunk-4J4PMPXZ.js → chunk-5ERB3AWT.js} +1 -1
  98. package/dist/{chunk-SQKXKV2Y.js → chunk-5GDTZOVS.js} +2 -2
  99. package/dist/{chunk-BUCXNV32.js → chunk-5HQHHQUR.js} +1 -1
  100. package/dist/chunk-5MLYU6I2.js +76 -0
  101. package/dist/{chunk-X2Q5NLUL.js → chunk-5VV2YMMB.js} +1 -1
  102. package/dist/{chunk-XZXBB3TN.js → chunk-62MYX7G4.js} +2 -2
  103. package/dist/{chunk-X33NYQYJ.js → chunk-6CYVBLZW.js} +2 -2
  104. package/dist/{chunk-GJ26DULE.js → chunk-6IK2ME5X.js} +2 -2
  105. package/dist/{chunk-4ZCD2UWW.js → chunk-6JMRRJD6.js} +3 -3
  106. package/dist/{chunk-EQHQF5IM.js → chunk-6L6SXVTP.js} +32 -16
  107. package/dist/{chunk-MR6LHP4F.js → chunk-6ST7ZWTV.js} +1 -1
  108. package/dist/{chunk-WMESXBJM.js → chunk-6TJLBXR5.js} +30 -5
  109. package/dist/{chunk-PPCDBE6Z.js → chunk-6XKIMGHA.js} +1 -1
  110. package/dist/{chunk-5ERDIOV3.js → chunk-7M5AWCR3.js} +2 -2
  111. package/dist/{chunk-MKYFAKDW.js → chunk-7MESPFOK.js} +4 -4
  112. package/dist/{chunk-RACAOE2Z.js → chunk-7S3A4TOL.js} +15 -15
  113. package/dist/{chunk-LU2FALL6.js → chunk-7UNIYLGV.js} +28 -4
  114. package/dist/{chunk-N7QJKQMX.js → chunk-AGHKOBA6.js} +10 -10
  115. package/dist/{chunk-OZEBAGKR.js → chunk-B4LOFZLB.js} +10 -10
  116. package/dist/{chunk-GDIJE6D7.js → chunk-BUI2CHLQ.js} +1 -1
  117. package/dist/{chunk-JMYHW3AL.js → chunk-BVURFD5R.js} +2 -2
  118. package/dist/{chunk-7V4JADD6.js → chunk-BXSC34Y2.js} +2 -2
  119. package/dist/{chunk-YCANDMI2.js → chunk-BZA4N43B.js} +1 -1
  120. package/dist/{chunk-QDGZJ653.js → chunk-C24F7SOO.js} +4 -4
  121. package/dist/{chunk-5TY4FPH6.js → chunk-CBD64QQG.js} +1 -1
  122. package/dist/{chunk-QRYVCDWS.js → chunk-DHW4DIGK.js} +2 -2
  123. package/dist/{chunk-2KZNGDSW.js → chunk-DLGEQJ6E.js} +1 -1
  124. package/dist/{chunk-GBTTBXAF.js → chunk-DT6LX4SV.js} +4 -4
  125. package/dist/{chunk-R2NN3JKH.js → chunk-E4FGXPHB.js} +5 -5
  126. package/dist/{chunk-UEA3LXOB.js → chunk-FCKYJSVY.js} +1 -1
  127. package/dist/{chunk-FPFPLPUY.js → chunk-FQEBVYVE.js} +5 -5
  128. package/dist/{chunk-AOHXREB7.js → chunk-GD7FA6IP.js} +70 -66
  129. package/dist/{chunk-6WQ3NNCE.js → chunk-GGQMX4IU.js} +3 -3
  130. package/dist/{chunk-H6BV5TKD.js → chunk-H6BVQIAF.js} +6 -6
  131. package/dist/{chunk-CWXVH7WV.js → chunk-H6WLWIPN.js} +1 -1
  132. package/dist/{chunk-UP75Z5X7.js → chunk-HDL7CXQ4.js} +73 -67
  133. package/dist/{chunk-RHWZUUS4.js → chunk-HENPNYGY.js} +11 -11
  134. package/dist/{chunk-C5QAPURN.js → chunk-HRBTW62M.js} +1 -1
  135. package/dist/{chunk-OLMQ4UOF.js → chunk-IKAGAKAI.js} +209 -20
  136. package/dist/{chunk-UUEKJDK6.js → chunk-IPB5QM4S.js} +2 -2
  137. package/dist/{chunk-NXUSDL37.js → chunk-IRUWKANS.js} +1 -1
  138. package/dist/{chunk-EUS4QUKP.js → chunk-JBMIIBPS.js} +1 -1
  139. package/dist/{chunk-VPZHJCKW.js → chunk-JLLJ3ER3.js} +2 -2
  140. package/dist/{chunk-F27XXN6C.js → chunk-JMMF3PPQ.js} +1 -1
  141. package/dist/{chunk-UNXQBELK.js → chunk-K2G3VDCV.js} +1 -1
  142. package/dist/{chunk-3SW4OEHB.js → chunk-KIUNO3JP.js} +1 -1
  143. package/dist/{chunk-KW2SD2FL.js → chunk-KRRZNASS.js} +2 -2
  144. package/dist/{chunk-HV4KESRY.js → chunk-LSAH73QD.js} +1 -1
  145. package/dist/chunk-LUQ57SRM.js +127 -0
  146. package/dist/{sweep-budget-WB2FKPYN.js → chunk-M6DZYWZH.js} +8 -3
  147. package/dist/{chunk-JGIPOUIK.js → chunk-MNIA3IOU.js} +3 -3
  148. package/dist/{chunk-XHK3FS3W.js → chunk-MTFSD6DH.js} +1 -1
  149. package/dist/{chunk-2ZYO73KO.js → chunk-MVWFY7IO.js} +1 -1
  150. package/dist/{chunk-ASAFVDVR.js → chunk-NDJASAXP.js} +1 -1
  151. package/dist/{chunk-K7KFGDWF.js → chunk-NG2ABIDX.js} +1 -1
  152. package/dist/{chunk-O5V57XYE.js → chunk-NPFU2NPG.js} +1 -1
  153. package/dist/{chunk-UUQBZPJJ.js → chunk-NUVP4CCD.js} +1 -1
  154. package/dist/{chunk-NX5INHHG.js → chunk-O5VMAZZH.js} +1 -1
  155. package/dist/{chunk-WZHZCDDO.js → chunk-OL4JFQ2T.js} +1 -0
  156. package/dist/{chunk-Z6RSN7KS.js → chunk-OZUQJZYO.js} +4 -4
  157. package/dist/{chunk-P5HIWY2E.js → chunk-PAYVSTF2.js} +1 -1
  158. package/dist/chunk-PWRC5XZO.js +161 -0
  159. package/dist/{chunk-MZM6EJCU.js → chunk-PXPBF2JZ.js} +4 -4
  160. package/dist/{chunk-L2R3LN2P.js → chunk-QFBT7CJH.js} +1 -1
  161. package/dist/{chunk-2WAVZ5UJ.js → chunk-QTKDGDR5.js} +1 -1
  162. package/dist/{chunk-G4RGKBCA.js → chunk-R3QDXB55.js} +13 -3
  163. package/dist/{chunk-QQ4E2RYW.js → chunk-RZZ66LSS.js} +12 -12
  164. package/dist/{chunk-HJ447YER.js → chunk-S3FIQCSM.js} +14 -6
  165. package/dist/{chunk-G5T6KDG4.js → chunk-SA7GZU3U.js} +1 -1
  166. package/dist/{chunk-7CTRGNLW.js → chunk-SIGS6D5R.js} +2 -2
  167. package/dist/{chunk-VRAQTFD6.js → chunk-SJN5ZEDI.js} +1 -1
  168. package/dist/{chunk-QOO5RW3K.js → chunk-SLK3DPYU.js} +3 -3
  169. package/dist/{chunk-F5O7V7UK.js → chunk-SXKMH4JX.js} +1 -1
  170. package/dist/{chunk-6CH3TPHR.js → chunk-T3EJIMDX.js} +3 -3
  171. package/dist/{chunk-KWZMQACA.js → chunk-TI2XFHRQ.js} +3 -3
  172. package/dist/{chunk-OTF44GXL.js → chunk-TR73G4GH.js} +2 -2
  173. package/dist/{chunk-4CMVFVFC.js → chunk-UC37QPSR.js} +4 -4
  174. package/dist/{chunk-KGWRTRKC.js → chunk-UZ2LYBY5.js} +1 -1
  175. package/dist/{chunk-EV46QTD3.js → chunk-V7AGCRLI.js} +1 -1
  176. package/dist/{chunk-H7I47RS5.js → chunk-VIIHBYIP.js} +115 -3
  177. package/dist/{chunk-HA5R6USD.js → chunk-WYRZEMRU.js} +1 -1
  178. package/dist/{chunk-CE7F6RHG.js → chunk-WZTWA4G4.js} +11 -11
  179. package/dist/{chunk-IBYL4DHM.js → chunk-X4Z5DPOC.js} +22 -2
  180. package/dist/{chunk-4VSV5P4D.js → chunk-XZTTLTPG.js} +4 -4
  181. package/dist/{chunk-S7QUM2UK.js → chunk-YCPZTX7V.js} +2 -2
  182. package/dist/{chunk-GG5NDQNN.js → chunk-YYCKKORY.js} +13 -20
  183. package/dist/{chunk-NN2B2QKU.js → chunk-Z5VL7YBR.js} +1 -1
  184. package/dist/{chunk-QYZJHTNE.js → chunk-ZCLVPTZU.js} +9 -9
  185. package/dist/{chunk-RAXVPNMR.js → chunk-ZUBUP66T.js} +1 -1
  186. package/dist/{chunk-VSRPS3J7.js → chunk-ZYLKX3KB.js} +13 -13
  187. package/dist/{cleanup-graph-garbage-XWUFAMFO.js → cleanup-graph-garbage-DDVPSPI4.js} +5 -5
  188. package/dist/{co-activation-ZCHPLLP6.js → co-activation-HLCAD44L.js} +3 -3
  189. package/dist/{co-occurrence-KG3LKALN.js → co-occurrence-I5U2PCPX.js} +3 -3
  190. package/dist/{code-context-index-WSOJQ72R.js → code-context-index-FSYP5VF2.js} +4 -4
  191. package/dist/{conversation-wiki-populator-WQN3IUU6.js → conversation-wiki-populator-YVT5AYSK.js} +1 -1
  192. package/dist/{crdt-sync-4PFGPZXV.js → crdt-sync-EMV5EZ4J.js} +1 -1
  193. package/dist/{crm-webhook-II7Z45Q6.js → crm-webhook-XJ6UOBHR.js} +2 -2
  194. package/dist/{cto-delegation-gate-JWWOJPNC.js → cto-delegation-gate-5NNZWP2M.js} +19 -18
  195. package/dist/{daemon-auth-3FEAHFWC.js → daemon-auth-TIE7HSWF.js} +2 -2
  196. package/dist/{daemon-orchestration-FX4XZDR5.js → daemon-orchestration-GGSRCXR3.js} +24 -23
  197. package/dist/{daemon-ready-4JTSFKAY.js → daemon-ready-A7R6XZRF.js} +1 -1
  198. package/dist/{daemon-restart-circuit-breaker-PEGEIP6H.js → daemon-restart-circuit-breaker-5V6B6NLS.js} +1 -1
  199. package/dist/{db-restore-events-MQ2DBGEQ.js → db-restore-events-GQGQSYHV.js} +1 -1
  200. package/dist/{doc-graph-extractor-F6ODFIID.js → doc-graph-extractor-3OXUTEKS.js} +3 -3
  201. package/dist/{documents-23WX2FPQ.js → documents-M7UI6SZ6.js} +9 -9
  202. package/dist/{dreaming-NWD22UQ5.js → dreaming-CYQWRJA5.js} +20 -19
  203. package/dist/{exe-drift-CW72FBGE.js → exe-drift-DPDRG3OM.js} +4 -4
  204. package/dist/{exe-export-AUJ7CV7G.js → exe-export-SZVIC6KI.js} +8 -8
  205. package/dist/{exe-import-JX4I52VE.js → exe-import-Q6TCHQ6P.js} +8 -8
  206. package/dist/{exe-key-2N6LY2BU.js → exe-key-EVMVLB3Y.js} +86 -85
  207. package/dist/{exe-org-X4CSNCKS.js → exe-org-3Y3RWGIU.js} +2 -2
  208. package/dist/{exe-snapshot-XZ7FVCYZ.js → exe-snapshot-UX5CFSDX.js} +23 -22
  209. package/dist/{fast-db-init-4CWHSOOR.js → fast-db-init-O62SMAQL.js} +1 -1
  210. package/dist/{founder-context-7L3CFPYN.js → founder-context-FCVTBCWI.js} +3 -3
  211. package/dist/gateway/index.js +18 -18
  212. package/dist/{git-staleness-CI2R4QOJ.js → git-staleness-AFBXWNTZ.js} +3 -3
  213. package/dist/{global-procedures-XQX3LUH6.js → global-procedures-BDREAJSZ.js} +5 -5
  214. package/dist/{graph-auto-extract-OURWMGBS.js → graph-auto-extract-JJ5OGNGJ.js} +3 -3
  215. package/dist/{hook-integrity-XY47IM7G.js → hook-integrity-IKKZ6HBC.js} +1 -1
  216. package/dist/{hook-prefetch-PHRRKY4C.js → hook-prefetch-HLCCAOSZ.js} +20 -19
  217. package/dist/hooks/bug-report-worker.js +24 -23
  218. package/dist/hooks/codex-stop-task-finalizer.js +24 -23
  219. package/dist/hooks/commit-complete.js +23 -22
  220. package/dist/hooks/error-recall.js +12 -12
  221. package/dist/hooks/exe-heartbeat-hook.js +5 -5
  222. package/dist/hooks/ingest-worker.js +7 -7
  223. package/dist/hooks/ingest.js +19 -19
  224. package/dist/hooks/instructions-loaded.js +6 -6
  225. package/dist/hooks/manifest.json +20 -20
  226. package/dist/hooks/notification.js +6 -6
  227. package/dist/hooks/post-compact.js +22 -21
  228. package/dist/hooks/post-tool-combined.js +23 -10
  229. package/dist/hooks/pre-compact.js +23 -22
  230. package/dist/hooks/pre-tool-use.js +28 -27
  231. package/dist/hooks/prompt-submit.js +53 -40
  232. package/dist/hooks/session-end.js +28 -27
  233. package/dist/hooks/session-start.js +17 -17
  234. package/dist/hooks/stop.js +29 -28
  235. package/dist/hooks/subagent-stop.js +22 -21
  236. package/dist/hooks/summary-worker.js +28 -27
  237. package/dist/index.js +33 -32
  238. package/dist/{installer-L7EVH5U5.js → installer-BZ3QV7DJ.js} +7 -7
  239. package/dist/{installer-JND3RJ6Q.js → installer-HADQQZIU.js} +7 -7
  240. package/dist/{installer-G3JAO3NT.js → installer-OJ7XKSAR.js} +7 -7
  241. package/dist/{intercom-queue-ZFEQALR3.js → intercom-queue-NFOLOBTT.js} +19 -18
  242. package/dist/{key-backup-status-LOSMVATJ.js → key-backup-status-TTO2UUYP.js} +1 -1
  243. package/dist/lib/agent-config.js +2 -2
  244. package/dist/lib/cloud-sync.js +15 -15
  245. package/dist/lib/config.js +1 -1
  246. package/dist/lib/consolidation.js +6 -6
  247. package/dist/lib/database.js +3 -3
  248. package/dist/{db-backup-W2QFSYQC.js → lib/db-backup.js} +16 -4
  249. package/dist/lib/db-checkpoint-worker.js +57 -0
  250. package/dist/lib/db-daemon-client.js +4 -4
  251. package/dist/lib/db-write-worker-client.js +17 -0
  252. package/dist/lib/db-write-worker.js +216 -0
  253. package/dist/lib/db.js +3 -3
  254. package/dist/lib/device-registry.js +2 -2
  255. package/dist/lib/embed-worker.js +1 -1
  256. package/dist/lib/embedder.js +4 -4
  257. package/dist/lib/employee-templates.js +6 -6
  258. package/dist/lib/employees.js +3 -3
  259. package/dist/lib/exe-daemon-client.js +3 -3
  260. package/dist/lib/exe-daemon.js +781 -276
  261. package/dist/lib/hybrid-search.js +6 -6
  262. package/dist/lib/identity.js +3 -3
  263. package/dist/lib/license.js +3 -3
  264. package/dist/lib/messaging.js +20 -19
  265. package/dist/lib/registry-proxy.js +1 -1
  266. package/dist/lib/reminders.js +4 -4
  267. package/dist/lib/schedules.js +6 -6
  268. package/dist/lib/session-registry.js +5 -5
  269. package/dist/lib/skill-learning.js +7 -7
  270. package/dist/lib/status-brief.js +3 -3
  271. package/dist/lib/store.js +5 -5
  272. package/dist/lib/task-router.js +4 -4
  273. package/dist/lib/tasks.js +21 -20
  274. package/dist/lib/tmux-routing.js +19 -18
  275. package/dist/lib/token-spend.js +4 -4
  276. package/dist/{license-gate-QTRQHV4F.js → license-gate-3KPSNYVA.js} +4 -4
  277. package/dist/{license-sync-N3UJFWAW.js → license-sync-CQ42HDBA.js} +3 -3
  278. package/dist/mcp/register-tools.js +83 -82
  279. package/dist/mcp/server.js +85 -84
  280. package/dist/mcp/tools/complete-reminder.js +5 -5
  281. package/dist/mcp/tools/create-reminder.js +5 -5
  282. package/dist/mcp/tools/create-task.js +23 -22
  283. package/dist/mcp/tools/deactivate-behavior.js +8 -8
  284. package/dist/mcp/tools/list-reminders.js +5 -5
  285. package/dist/mcp/tools/list-tasks.js +23 -22
  286. package/dist/mcp/tools/send-message.js +22 -21
  287. package/dist/mcp/tools/update-task.js +22 -21
  288. package/dist/{mcp-http-config-BDL36JZ3.js → mcp-http-config-BHAM376G.js} +8 -6
  289. package/dist/{mcp-port-config-6HYY6J7K.js → mcp-port-config-PA3W3BJK.js} +7 -1
  290. package/dist/{mcp-session-identity-T7H2EKFQ.js → mcp-session-identity-S7GSVRR6.js} +19 -18
  291. package/dist/mcp-session-persist-PS7BIG44.js +62 -0
  292. package/dist/mcp-stale-flag-ZM23XRSJ.js +11 -0
  293. package/dist/{memory-cards-ZRDW7QBX.js → memory-cards-47NYPFC3.js} +5 -5
  294. package/dist/{memory-graph-extractor-QLXDMHRS.js → memory-graph-extractor-IH7YBZ6U.js} +4 -4
  295. package/dist/{memory-poisoning-defense-HJTXYCWH.js → memory-poisoning-defense-MZQFCQ2G.js} +3 -3
  296. package/dist/{memory-pressure-watchdog-HN5X7AVN.js → memory-pressure-watchdog-PSVJ5BCF.js} +20 -19
  297. package/dist/{memory-queue-2UOOF27L.js → memory-queue-ZI7DX44D.js} +2 -2
  298. package/dist/{memory-queue-client-O5U6F6XP.js → memory-queue-client-6IPZTWZA.js} +5 -5
  299. package/dist/{memory-reflection-WVNFBJAA.js → memory-reflection-3VPYJS2G.js} +3 -3
  300. package/dist/{monitor-grants-E3ELDEWD.js → monitor-grants-OXKZ75TH.js} +2 -2
  301. package/dist/{notification-ledger-SZEPGJQ7.js → notification-ledger-A6MYLQAN.js} +20 -19
  302. package/dist/{notifications-4UT53CDG.js → notifications-6XCSUTJW.js} +19 -18
  303. package/dist/{orchestration-events-WV4NWKZH.js → orchestration-events-5XDNVNR2.js} +4 -4
  304. package/dist/{orchestration-phase-AWBXPO52.js → orchestration-phase-6DJUSFMV.js} +2 -2
  305. package/dist/{orchestrator-UAC3RW2T.js → orchestrator-2RQBNMZL.js} +21 -20
  306. package/dist/{pipeline-router-LM53NMWJ.js → pipeline-router-N2LDNFJ5.js} +4 -4
  307. package/dist/{plan-limits-2FEY2GOS.js → plan-limits-7BUMNQOI.js} +6 -6
  308. package/dist/{platform-procedures-X5DFJFV7.js → platform-procedures-VDW2R65H.js} +1 -1
  309. package/dist/{project-boot-4NUH5FRU.js → project-boot-RXCHF3S7.js} +1 -1
  310. package/dist/{projection-worker-FZ7YSN3G.js → projection-worker-CKC2E22U.js} +4 -4
  311. package/dist/{prospective-memory-6D2ASWM3.js → prospective-memory-Q7ZUCAS4.js} +3 -3
  312. package/dist/{push-notifications-U6FIBQRW.js → push-notifications-VCSZYVD5.js} +2 -2
  313. package/dist/{reranker-GYYRPANK.js → reranker-L3GLRUDY.js} +2 -2
  314. package/dist/{retrieval-health-4Z242P3B.js → retrieval-health-DPLY6O6P.js} +1 -1
  315. package/dist/{review-polling-HXAFJZDA.js → review-polling-DLPMK3QW.js} +20 -19
  316. package/dist/runtime/index.js +31 -30
  317. package/dist/{session-events-O3BV56ZX.js → session-events-N5VRC6IT.js} +20 -19
  318. package/dist/{session-kill-telemetry-AELE4JDK.js → session-kill-telemetry-76ZVQ525.js} +20 -19
  319. package/dist/{session-scope-5EAPUT45.js → session-scope-B3BEHGHO.js} +19 -18
  320. package/dist/{setup-wizard-NB6R4QVS.js → setup-wizard-5SIRITVN.js} +3 -3
  321. package/dist/{shard-manager-35PWFR3B.js → shard-manager-OETALPDW.js} +2 -2
  322. package/dist/{skill-refinement-DVSYXBBP.js → skill-refinement-ACXLAK2G.js} +4 -4
  323. package/dist/{stack-update-ATCJFOEK.js → stack-update-YVFP65NY.js} +4 -4
  324. package/dist/{steward-gate-3GQ5XKMJ.js → steward-gate-2M66UU6A.js} +4 -4
  325. package/dist/{support-inbox-4L62P4EP.js → support-inbox-5W2GMJGV.js} +4 -4
  326. package/dist/sweep-budget-LQYBMDTK.js +15 -0
  327. package/dist/{task-enforcement-IPIZX2MM.js → task-enforcement-C7MMJTKX.js} +20 -19
  328. package/dist/{task-scope-FOIW25HR.js → task-scope-DK666AKV.js} +19 -18
  329. package/dist/{tasks-crud-HBDKE6C5.js → tasks-crud-DFPIAAEC.js} +21 -18
  330. package/dist/{tasks-notify-G2U2U2YA.js → tasks-notify-4R5YIPZN.js} +20 -19
  331. package/dist/{tasks-review-27SFX5XN.js → tasks-review-GOYSZEZA.js} +19 -18
  332. package/dist/{telemetry-upload-ZOXHRWR5.js → telemetry-upload-Y5F6WYLD.js} +8 -8
  333. package/dist/{token-budget-5Y4YPDO3.js → token-budget-BAM5QDFV.js} +4 -4
  334. package/dist/{tool-capability-index-VYF5GNJ2.js → tool-capability-index-QOFFCWDS.js} +1 -1
  335. package/dist/{tool-telemetry-KBXSBDTK.js → tool-telemetry-4MF2HIWR.js} +1 -1
  336. package/dist/tui/App.js +33 -32
  337. package/dist/{tui-data-NLFMBIQI.js → tui-data-WMYZNTBR.js} +19 -18
  338. package/dist/{update-support-UVUSZG7R.js → update-support-44SGQUA4.js} +12 -12
  339. package/dist/{worker-gate-3KUBAU32.js → worker-gate-7OK7ZRJL.js} +2 -2
  340. package/dist/{workflow-engine-YITHXZR5.js → workflow-engine-EDZGGHAI.js} +2 -2
  341. package/dist/{worktree-LL62PLQB.js → worktree-VDCY44ZP.js} +5 -5
  342. package/dist/{worktree-sweep-WTK3MTKH.js → worktree-sweep-VSL7TRQK.js} +6 -6
  343. package/package.json +3 -2
  344. package/release-notes.json +12 -12
  345. package/dist/chunk-GIBYNT6W.js +0 -23
  346. /package/dist/{chunk-NBZL5CGA.js → chunk-735SUAT4.js} +0 -0
  347. /package/dist/{chunk-MGGOSFCR.js → chunk-CIG7FSD5.js} +0 -0
  348. /package/dist/{chunk-JRM4TAGS.js → chunk-DFCSGPNZ.js} +0 -0
  349. /package/dist/{chunk-QIFYLIUF.js → chunk-EBTWNNAS.js} +0 -0
  350. /package/dist/{chunk-KP3U5QGJ.js → chunk-L5GFREAH.js} +0 -0
  351. /package/dist/{chunk-PWUFMX75.js → chunk-UU4FHMON.js} +0 -0
  352. /package/dist/{core-memory-GAC6EWOQ.js → core-memory-VOBMIFRX.js} +0 -0
  353. /package/dist/{entity-boost-NT6UO2Z3.js → entity-boost-N4NAK4WA.js} +0 -0
  354. /package/dist/{message-queue-client-4EOQRUXW.js → message-queue-client-WMIO5FL5.js} +0 -0
  355. /package/dist/{oauth-server-67YBDP32.js → oauth-server-HPQCBLZQ.js} +0 -0
  356. /package/dist/{webhook-pipe-LEXMUQ5B.js → webhook-pipe-HH7XXXYC.js} +0 -0
  357. /package/dist/{wiki-acl-74BLWG6J.js → wiki-acl-NEM3L4LK.js} +0 -0
  358. /package/dist/{wiki-client-EAN7F5LV.js → wiki-client-WREIYJLY.js} +0 -0
@@ -4,10 +4,20 @@ import {
4
4
  restartBootsInWindow,
5
5
  restartBreakerAlertPath,
6
6
  writeDaemonExitBreadcrumb
7
- } from "../chunk-HJ447YER.js";
7
+ } from "../chunk-S3FIQCSM.js";
8
8
  import {
9
9
  pushNotifyAsync
10
- } from "../chunk-3SW4OEHB.js";
10
+ } from "../chunk-KIUNO3JP.js";
11
+ import {
12
+ disposeDbWriteWorker,
13
+ isDbWriteWorkerReady,
14
+ isWriteWorkerEnabled,
15
+ spawnDbWriteWorker,
16
+ writeMemoryInWorker
17
+ } from "../chunk-LUQ57SRM.js";
18
+ import {
19
+ shouldScheduleDaemonRestartHandoff
20
+ } from "../chunk-PWRC5XZO.js";
11
21
  import {
12
22
  clearDaemonReady,
13
23
  eventLoopHeartbeatPath,
@@ -17,7 +27,7 @@ import {
17
27
  getMcpToolFamily,
18
28
  inferMcpRuntime,
19
29
  recordMcpHttpEvent
20
- } from "../chunk-RAXVPNMR.js";
30
+ } from "../chunk-ZUBUP66T.js";
21
31
  import {
22
32
  deserializeArgs,
23
33
  serializeResultSet
@@ -29,11 +39,14 @@ import {
29
39
  findScopedDuplicate,
30
40
  governMemoryRecord,
31
41
  schedulePostWriteMemoryHygiene
32
- } from "../chunk-6XWTQUO4.js";
42
+ } from "../chunk-4MLSFZLY.js";
33
43
  import "../chunk-4QCFFW2H.js";
34
44
  import {
35
45
  BUSY_PATTERN
36
46
  } from "../chunk-GWDSB25T.js";
47
+ import {
48
+ sweepPauseTotalMs
49
+ } from "../chunk-M6DZYWZH.js";
37
50
  import {
38
51
  attributeSignalSource,
39
52
  consumeRestartIntentDetail,
@@ -45,7 +58,7 @@ import {
45
58
  ensureDaemonToken,
46
59
  reconcileSessionAgentIdentity,
47
60
  shouldEnforceSessionIdentity
48
- } from "../chunk-X2Q5NLUL.js";
61
+ } from "../chunk-5VV2YMMB.js";
49
62
  import {
50
63
  DAEMON_RSS_RESTART_DEBOUNCE,
51
64
  DAEMON_RSS_STARTUP_GRACE_MS,
@@ -82,7 +95,7 @@ import {
82
95
  EXE_AI_DIR,
83
96
  MODELS_DIR,
84
97
  resolveEmbedModelFile
85
- } from "../chunk-WZHZCDDO.js";
98
+ } from "../chunk-OL4JFQ2T.js";
86
99
  import "../chunk-BYTDMAGB.js";
87
100
  import "../chunk-MLKGABMK.js";
88
101
 
@@ -92,7 +105,7 @@ import net from "net";
92
105
  import v8 from "v8";
93
106
  import { createServer as createHttpServer, request as httpRequest } from "http";
94
107
  import { randomUUID, timingSafeEqual } from "crypto";
95
- import { writeFileSync as writeFileSync3, unlinkSync as unlinkSync2, mkdirSync as mkdirSync2, existsSync as existsSync4, readFileSync as readFileSync4, chmodSync, readdirSync, renameSync, statSync } from "fs";
108
+ import { writeFileSync as writeFileSync4, unlinkSync as unlinkSync3, mkdirSync as mkdirSync3, existsSync as existsSync5, readFileSync as readFileSync5, chmodSync, readdirSync, renameSync, statSync as statSync2 } from "fs";
96
109
  import { writeFile } from "fs/promises";
97
110
  import { execSync as execSyncNode, execFile as execFileNode } from "child_process";
98
111
  import { promisify } from "util";
@@ -322,6 +335,11 @@ function initMetrics() {
322
335
  });
323
336
  }
324
337
 
338
+ // src/lib/daemon-timer-warnings.ts
339
+ function shouldWarnSlowTimer(durationMs, slept, thresholdMs) {
340
+ return !slept && durationMs >= thresholdMs;
341
+ }
342
+
325
343
  // src/lib/mcp-init-grace.ts
326
344
  var defaultSleep = (ms) => new Promise((r) => setTimeout(r, ms));
327
345
  async function awaitPendingMcpInit(ownerKey, requestSessionId, deps, transientMatch) {
@@ -376,6 +394,176 @@ async function awaitPendingMcpInit(ownerKey, requestSessionId, deps, transientMa
376
394
  return null;
377
395
  }
378
396
 
397
+ // src/lib/daemon-coverage-gap.ts
398
+ import { closeSync, existsSync as existsSync2, mkdirSync, openSync, readFileSync as readFileSync2, readSync, statSync, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
399
+ import { homedir } from "os";
400
+ import { dirname, join } from "path";
401
+ var HEALTH_LOG_TAIL_BYTES = 512 * 1024;
402
+ var DEFAULT_COVERAGE_GAP_THRESHOLD_MS = 30 * 60 * 1e3;
403
+ var DEFAULT_COVERAGE_GAP_ALERT_THRESHOLD_MS = 60 * 60 * 1e3;
404
+ function resolveCoverageGapAlertThresholdMs() {
405
+ const raw = Number(process.env.EXE_HEARTBEAT_GAP_ALERT_MS);
406
+ return Number.isFinite(raw) && raw > 0 ? Math.floor(raw) : DEFAULT_COVERAGE_GAP_ALERT_THRESHOLD_MS;
407
+ }
408
+ var COVERAGE_GAP_ALERT_THRESHOLD_MS = resolveCoverageGapAlertThresholdMs();
409
+ function shouldAlertCoverageGap(a, alertThresholdMs) {
410
+ return Number.isFinite(a.gapMs) && a.gapMs > 0 && a.gapMs > alertThresholdMs;
411
+ }
412
+ function shouldWriteCoverageGapAlert(bootClass, a, alertThresholdMs) {
413
+ return bootClass === "coverage_gap" && a !== void 0 && shouldAlertCoverageGap(a, alertThresholdMs);
414
+ }
415
+ var COVERAGE_GAP_ALERT_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
416
+ function clearCoverageGapAlertIfExpired(maxAgeMs = COVERAGE_GAP_ALERT_MAX_AGE_MS) {
417
+ try {
418
+ const alert = readCoverageGapAlert();
419
+ if (!alert) return;
420
+ const detectedAt = typeof alert.detectedAt === "string" ? Date.parse(alert.detectedAt) : NaN;
421
+ if (!Number.isFinite(detectedAt) || Date.now() - detectedAt > maxAgeMs) {
422
+ clearCoverageGapAlert();
423
+ }
424
+ } catch {
425
+ }
426
+ }
427
+ function coverageGapAlertPath() {
428
+ const home = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? join(homedir(), ".exe-os");
429
+ return join(home, "daemon-coverage-gap.ALERT.json");
430
+ }
431
+ function isoOrNull(ts) {
432
+ return ts !== null && Number.isFinite(ts) ? new Date(ts).toISOString() : null;
433
+ }
434
+ function writeCoverageGapAlert(a, ctx) {
435
+ try {
436
+ const hours = a.gapMs / (60 * 60 * 1e3);
437
+ const lastHeartbeatAt = isoOrNull(ctx.lastHeartbeatTs);
438
+ const hostRebootAt = a.rebootSpansGap ? isoOrNull(ctx.hostBootTs) : null;
439
+ const rebootClause = a.rebootSpansGap && hostRebootAt ? `, host rebooted ${hostRebootAt}` : ", no host reboot was detected";
440
+ const payload = {
441
+ detectedAt: new Date(ctx.nowMs).toISOString(),
442
+ gapMs: a.gapMs,
443
+ gapHours: Number(hours.toFixed(1)),
444
+ lastHeartbeatAt,
445
+ rebootSpansGap: a.rebootSpansGap,
446
+ reason: `Daemon was down ~${hours.toFixed(1)}h: last heartbeat ${lastHeartbeatAt ?? "unknown"}${rebootClause}, daemon only starts at GUI login (LaunchAgent) - this was a coverage gap, not a crash.`,
447
+ limitation: "Root cause: the daemon is a GUI LaunchAgent and does not run pre-login after reboot."
448
+ };
449
+ if (a.rebootSpansGap) payload.hostRebootAt = hostRebootAt;
450
+ const p = coverageGapAlertPath();
451
+ mkdirSync(dirname(p), { recursive: true });
452
+ writeFileSync2(p, JSON.stringify(payload, null, 2), { mode: 384 });
453
+ } catch {
454
+ }
455
+ }
456
+ function clearCoverageGapAlert() {
457
+ try {
458
+ const p = coverageGapAlertPath();
459
+ if (existsSync2(p)) unlinkSync(p);
460
+ } catch {
461
+ }
462
+ }
463
+ function readCoverageGapAlert() {
464
+ try {
465
+ const p = coverageGapAlertPath();
466
+ if (!existsSync2(p)) return null;
467
+ return JSON.parse(readFileSync2(p, "utf8"));
468
+ } catch {
469
+ return null;
470
+ }
471
+ }
472
+ function hostBootTimeMs(nowMs, uptimeSec) {
473
+ return nowMs - uptimeSec * 1e3;
474
+ }
475
+ function readTail(p, maxBytes = HEALTH_LOG_TAIL_BYTES) {
476
+ let fd = null;
477
+ try {
478
+ const st = statSync(p);
479
+ const size = Math.max(0, Math.floor(st.size));
480
+ const len = Math.min(size, maxBytes);
481
+ const start = Math.max(0, size - len);
482
+ const buf = Buffer.alloc(len);
483
+ fd = openSync(p, "r");
484
+ const bytesRead = readSync(fd, buf, 0, len, start);
485
+ return buf.subarray(0, bytesRead).toString("utf8");
486
+ } catch {
487
+ return null;
488
+ } finally {
489
+ if (fd !== null) {
490
+ try {
491
+ closeSync(fd);
492
+ } catch {
493
+ }
494
+ }
495
+ }
496
+ }
497
+ var PROOF_OF_LIFE_EVENTS = /* @__PURE__ */ new Set(["heartbeat", "boot"]);
498
+ function lastHeartbeatFromHealthLog(p, excludePid) {
499
+ try {
500
+ const tail = readTail(p);
501
+ if (!tail) return null;
502
+ const lines = tail.split(/\r?\n/);
503
+ for (let i = lines.length - 1; i >= 0; i--) {
504
+ const line = lines[i]?.trim();
505
+ if (!line || !line.includes('"event"')) continue;
506
+ if (!line.includes('"heartbeat"') && !line.includes('"boot"')) continue;
507
+ try {
508
+ const parsed = JSON.parse(line);
509
+ if (typeof parsed.event !== "string" || !PROOF_OF_LIFE_EVENTS.has(parsed.event)) continue;
510
+ if (excludePid !== null && typeof parsed.pid === "number" && parsed.pid === excludePid) continue;
511
+ if (typeof parsed.ts !== "string") continue;
512
+ const ts = Date.parse(parsed.ts);
513
+ if (Number.isFinite(ts)) return ts;
514
+ } catch {
515
+ }
516
+ }
517
+ return null;
518
+ } catch {
519
+ return null;
520
+ }
521
+ }
522
+ function readLastHeartbeatTsMs(paths) {
523
+ try {
524
+ const signals = [];
525
+ const excludePid = paths?.excludePid === void 0 ? process.pid : paths.excludePid;
526
+ const logDir = join(homedir(), ".exe-os", "logs");
527
+ const mainLog = paths?.logPath ?? join(logDir, "daemon-health.log");
528
+ const rotatedLog = paths?.rotatedLogPath ?? join(logDir, "daemon-health.log.1");
529
+ const mainHeartbeat = lastHeartbeatFromHealthLog(mainLog, excludePid);
530
+ if (mainHeartbeat !== null) signals.push(mainHeartbeat);
531
+ else {
532
+ const rotatedHeartbeat = lastHeartbeatFromHealthLog(rotatedLog, excludePid);
533
+ if (rotatedHeartbeat !== null) signals.push(rotatedHeartbeat);
534
+ }
535
+ try {
536
+ const heartbeatPath = paths?.heartbeatFilePath ?? eventLoopHeartbeatPath();
537
+ if (existsSync2(heartbeatPath)) {
538
+ const mtimeMs = statSync(heartbeatPath).mtimeMs;
539
+ if (Number.isFinite(mtimeMs)) signals.push(mtimeMs);
540
+ }
541
+ } catch {
542
+ }
543
+ return signals.length ? Math.max(...signals) : null;
544
+ } catch {
545
+ return null;
546
+ }
547
+ }
548
+ function assessCoverageGap(ctx) {
549
+ const gapThresholdMs = ctx.gapThresholdMs ?? DEFAULT_COVERAGE_GAP_THRESHOLD_MS;
550
+ const lastHeartbeatTs = ctx.lastHeartbeatTs;
551
+ if (lastHeartbeatTs === null) {
552
+ return {
553
+ isCoverageGap: false,
554
+ gapMs: 0,
555
+ rebootSpansGap: false,
556
+ label: "no coverage-gap evidence"
557
+ };
558
+ }
559
+ const gapMs = ctx.nowMs - lastHeartbeatTs;
560
+ const rebootSpansGap = ctx.hostBootTs !== null && ctx.hostBootTs > lastHeartbeatTs;
561
+ const isCoverageGap = gapMs > gapThresholdMs;
562
+ const hours = (gapMs / (60 * 60 * 1e3)).toFixed(1);
563
+ const label = rebootSpansGap ? `coverage-gap (died ~${hours}h ago; host reboot at ${new Date(ctx.hostBootTs).toISOString()})` : `coverage-gap (died ~${hours}h ago; no reboot detected)`;
564
+ return { isCoverageGap, gapMs, rebootSpansGap, label };
565
+ }
566
+
379
567
  // src/lib/daemon-self-heal-dispatch.ts
380
568
  function dispatchSelfHealRestart(lagMs, trigger, deps) {
381
569
  deps.writeBreadcrumb(lagMs, trigger);
@@ -391,7 +579,7 @@ function resolveSelfHealThresholds(env = process.env) {
391
579
  }
392
580
 
393
581
  // src/lib/daemon-restart-backoff.ts
394
- import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, unlinkSync, mkdirSync } from "fs";
582
+ import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3, unlinkSync as unlinkSync2, mkdirSync as mkdirSync2 } from "fs";
395
583
  import { createHash } from "crypto";
396
584
  import path2 from "path";
397
585
  import os from "os";
@@ -437,8 +625,8 @@ function stateFile(workerKey) {
437
625
  function loadBackoffState(workerKey) {
438
626
  try {
439
627
  const f = stateFile(workerKey);
440
- if (!existsSync2(f)) return null;
441
- const parsed = JSON.parse(readFileSync2(f, "utf8"));
628
+ if (!existsSync3(f)) return null;
629
+ const parsed = JSON.parse(readFileSync3(f, "utf8"));
442
630
  if (typeof parsed.consecutiveFailures !== "number" || typeof parsed.lastFailureAt !== "number") {
443
631
  return null;
444
632
  }
@@ -453,15 +641,15 @@ function loadBackoffState(workerKey) {
453
641
  }
454
642
  function saveBackoffState(workerKey, state) {
455
643
  try {
456
- if (!existsSync2(STATE_DIR)) mkdirSync(STATE_DIR, { recursive: true });
457
- writeFileSync2(stateFile(workerKey), JSON.stringify(state), { mode: 384 });
644
+ if (!existsSync3(STATE_DIR)) mkdirSync2(STATE_DIR, { recursive: true });
645
+ writeFileSync3(stateFile(workerKey), JSON.stringify(state), { mode: 384 });
458
646
  } catch {
459
647
  }
460
648
  }
461
649
  function resetBackoffState(workerKey) {
462
650
  try {
463
651
  const f = stateFile(workerKey);
464
- if (existsSync2(f)) unlinkSync(f);
652
+ if (existsSync3(f)) unlinkSync2(f);
465
653
  } catch {
466
654
  }
467
655
  }
@@ -525,6 +713,31 @@ function isHostCpuStarved(load1m, cpuCount, ratio) {
525
713
  const cores = Number.isFinite(cpuCount) && cpuCount > 0 ? cpuCount : 1;
526
714
  return load1m > cores * ratio;
527
715
  }
716
+ function pruneLoadSamples(samples, keepSinceMs) {
717
+ return samples.filter((sample) => Number.isFinite(sample.ts) && sample.ts >= keepSinceMs);
718
+ }
719
+ function maxLoadOverWindow(samples, windowStartMs, currentLoad1m) {
720
+ const candidates = [currentLoad1m];
721
+ for (const sample of samples) {
722
+ if (sample.ts >= windowStartMs && Number.isFinite(sample.load1m)) {
723
+ candidates.push(sample.load1m);
724
+ }
725
+ }
726
+ const finite = candidates.filter((load) => Number.isFinite(load));
727
+ return finite.length > 0 ? Math.max(...finite) : currentLoad1m;
728
+ }
729
+ function updateLoadWindow(samples, nowMs, load1m, wallElapsedMs, keepMs) {
730
+ const blockStartMs = nowMs - wallElapsedMs - 2500;
731
+ const next = pruneLoadSamples(
732
+ [...samples, { ts: nowMs, load1m }],
733
+ Math.min(nowMs - keepMs, blockStartMs)
734
+ );
735
+ return {
736
+ samples: next,
737
+ maxLoad1mOverWindow: maxLoadOverWindow(next, blockStartMs, load1m),
738
+ blockStartMs
739
+ };
740
+ }
528
741
  function decideDaemonSelfHeal(s) {
529
742
  const alive = s.processAlive ?? true;
530
743
  if (!alive) {
@@ -543,7 +756,11 @@ function decideDaemonSelfHeal(s) {
543
756
  selfInflictedSuppressedMsAfter: sumOf(prunedWindow)
544
757
  };
545
758
  const cleared = { selfInflictedWindowAfter: [], selfInflictedStreakAfter: 0, selfInflictedSuppressedMsAfter: 0 };
546
- if (isHostCpuStarved(s.load1m, s.cpuCount, s.starvationRatio)) {
759
+ const loadCandidates = [s.load1m, s.maxLoad1mOverWindow].filter(
760
+ (load) => typeof load === "number" && Number.isFinite(load) && load > 0
761
+ );
762
+ const effectiveLoad1m = loadCandidates.length > 0 ? Math.max(...loadCandidates) : s.load1m;
763
+ if (isHostCpuStarved(effectiveLoad1m, s.cpuCount, s.starvationRatio)) {
547
764
  return { restart: false, reason: "starved_backoff", consecutiveSevereAfter: 0, ...carry };
548
765
  }
549
766
  if (s.catchUpActive) {
@@ -589,22 +806,68 @@ function decideBootBackoff(s) {
589
806
  if (!isHostCpuStarved(s.load1m, s.cpuCount, s.starvationRatio)) {
590
807
  return { wait: false, delayMs: 0, reason: "not_starved" };
591
808
  }
592
- if (s.attempt >= s.maxAttempts) {
809
+ const clientsWaiting = s.clientsWaiting === true;
810
+ const baseDelayMs = clientsWaiting ? s.baseDelayMs / 2 : s.baseDelayMs;
811
+ const maxDelayMs = clientsWaiting ? s.maxDelayMs / 2 : s.maxDelayMs;
812
+ const maxAttempts = clientsWaiting ? Math.min(s.maxAttempts, 2) : s.maxAttempts;
813
+ if (s.attempt >= maxAttempts) {
593
814
  return { wait: false, delayMs: 0, reason: "max_attempts_proceed" };
594
815
  }
595
- const base = Number.isFinite(s.baseDelayMs) && s.baseDelayMs > 0 ? s.baseDelayMs : 0;
596
- const cap = Number.isFinite(s.maxDelayMs) && s.maxDelayMs > 0 ? s.maxDelayMs : base;
816
+ const base = Number.isFinite(baseDelayMs) && baseDelayMs > 0 ? baseDelayMs : 0;
817
+ const cap = Number.isFinite(maxDelayMs) && maxDelayMs > 0 ? maxDelayMs : base;
597
818
  const exp = base * Math.pow(2, Math.max(0, s.attempt));
598
819
  const delayMs = Math.min(cap, exp);
599
820
  return { wait: true, delayMs, reason: "backoff" };
600
821
  }
822
+ function computeBootRetryAfterSeconds(nowMs, readyEtaMs, opts = {}) {
823
+ const defaultS = opts.defaultS ?? 3;
824
+ if (readyEtaMs === null) return defaultS;
825
+ const minS = opts.minS ?? 1;
826
+ const maxS = opts.maxS ?? 60;
827
+ return Math.min(maxS, Math.max(minS, Math.ceil((readyEtaMs - nowMs) / 1e3)));
828
+ }
829
+
830
+ // src/lib/bootstrap-response.ts
831
+ function buildBootstrapResponse(input) {
832
+ const headers = { "Content-Type": "application/json" };
833
+ if (input.method === "GET" && input.path === "/health") {
834
+ return {
835
+ statusCode: 200,
836
+ headers,
837
+ body: JSON.stringify(input.failedReason === null ? { status: "starting", version: input.version } : { status: "failed", reason: input.failedReason, version: input.version, recovery: "exe-os setup" })
838
+ };
839
+ }
840
+ if (input.failedReason !== null) {
841
+ return {
842
+ statusCode: 503,
843
+ headers: { ...headers, "Retry-After": "300" },
844
+ body: JSON.stringify({
845
+ jsonrpc: "2.0",
846
+ error: {
847
+ code: -32002,
848
+ message: `Terminal DB init failure (${input.failedReason}) - MCP will not start. Recover: 'exe-os setup'.`
849
+ },
850
+ id: null
851
+ })
852
+ };
853
+ }
854
+ return {
855
+ statusCode: 503,
856
+ headers: { ...headers, "Retry-After": String(input.retryAfterSeconds) },
857
+ body: JSON.stringify({
858
+ jsonrpc: "2.0",
859
+ error: { code: -32001, message: "Daemon initializing \u2014 MCP not ready yet. Retry in a few seconds." },
860
+ id: null
861
+ })
862
+ };
863
+ }
601
864
 
602
865
  // src/lib/daemon-env.ts
603
- import { readFileSync as readFileSync3, existsSync as existsSync3 } from "fs";
604
- import { homedir } from "os";
605
- import { join } from "path";
866
+ import { readFileSync as readFileSync4, existsSync as existsSync4 } from "fs";
867
+ import { homedir as homedir2 } from "os";
868
+ import { join as join2 } from "path";
606
869
  function daemonEnvPath() {
607
- return join(homedir(), ".exe-os", "daemon.env");
870
+ return join2(homedir2(), ".exe-os", "daemon.env");
608
871
  }
609
872
  function parseDaemonEnv(contents) {
610
873
  const out = {};
@@ -639,8 +902,8 @@ function applyDaemonEnv(parsed, env = process.env) {
639
902
  function loadDaemonEnv(path4 = daemonEnvPath()) {
640
903
  let contents;
641
904
  try {
642
- if (!existsSync3(path4)) return 0;
643
- contents = readFileSync3(path4, "utf8");
905
+ if (!existsSync4(path4)) return 0;
906
+ contents = readFileSync4(path4, "utf8");
644
907
  } catch {
645
908
  return 0;
646
909
  }
@@ -661,7 +924,7 @@ function stabilizeDaemonCwd() {
661
924
  } catch (err) {
662
925
  const moduleDir = path3.dirname(fileURLToPath(import.meta.url));
663
926
  const packageRoot = path3.resolve(moduleDir, "../..");
664
- const fallback = existsSync4(path3.join(packageRoot, "package.json")) ? packageRoot : os2.homedir();
927
+ const fallback = existsSync5(path3.join(packageRoot, "package.json")) ? packageRoot : os2.homedir();
665
928
  try {
666
929
  process.chdir(fallback);
667
930
  process.stderr.write(
@@ -686,7 +949,7 @@ var REVIEW_POLL_INTERVAL_MS = 60 * 1e3;
686
949
  var DAEMON_TOKEN_ENV = "EXE_DAEMON_TOKEN";
687
950
  var PACKAGE_VERSION = (() => {
688
951
  try {
689
- const pkg = JSON.parse(readFileSync4(new URL("../../package.json", import.meta.url), "utf8"));
952
+ const pkg = JSON.parse(readFileSync5(new URL("../../package.json", import.meta.url), "utf8"));
690
953
  return typeof pkg.version === "string" ? pkg.version : "unknown";
691
954
  } catch {
692
955
  return "unknown";
@@ -702,6 +965,7 @@ var _rerankPendingCallbacks = /* @__PURE__ */ new Map();
702
965
  var _shuttingDown = false;
703
966
  var _drainingWrites = false;
704
967
  var _mcpSessionDetailsRef = null;
968
+ var _mcpSessionLastSeenRef = null;
705
969
  var _activeWrites = 0;
706
970
  var _mcpHttpReady = Promise.resolve();
707
971
  var _daemonToken = "";
@@ -1029,6 +1293,7 @@ function setBootPhase(phase) {
1029
1293
  var TIMER_TRACE_BOOT_WINDOW_MS = Number(process.env.EXE_TIMER_TRACE_BOOT_WINDOW_MS) || 10 * 60 * 1e3;
1030
1294
  var TIMER_TRACE_SLOW_MS = Number(process.env.EXE_TIMER_TRACE_SLOW_MS) || 500;
1031
1295
  var TIMER_TIMEOUT_MS = Number(process.env.EXE_TIMER_TIMEOUT_MS) || 1e4;
1296
+ var TIMER_SLOW_WARN_MS = Number(process.env.EXE_TIMER_SLOW_WARN_MS) || 1e3;
1032
1297
  var _timerInFlight = /* @__PURE__ */ new Set();
1033
1298
  function shouldTraceDaemonTimer(durationMs = 0) {
1034
1299
  return Date.now() - _startedAt2 < TIMER_TRACE_BOOT_WINDOW_MS || durationMs >= TIMER_TRACE_SLOW_MS;
@@ -1082,12 +1347,17 @@ async function traceDaemonTimer(name, fn) {
1082
1347
  }
1083
1348
  _timerInFlight.add(name);
1084
1349
  const probe = captureClockProbe();
1350
+ const pauseSnapshot = sweepPauseTotalMs();
1085
1351
  const traceStart = shouldTraceDaemonTimer();
1086
1352
  if (traceStart) {
1087
1353
  process.stderr.write(`[exed] Timer start: ${name}
1088
1354
  `);
1089
1355
  }
1356
+ const watchdogStart = Date.now();
1090
1357
  const timeoutHandle = setTimeout(() => {
1358
+ const pausedMs = sweepPauseTotalMs() - pauseSnapshot;
1359
+ const busyMs = Date.now() - watchdogStart - pausedMs;
1360
+ if (busyMs < TIMER_TIMEOUT_MS) return;
1091
1361
  _lastBlockingTimer = { name, durationMs: TIMER_TIMEOUT_MS, ts: Date.now() };
1092
1362
  process.stderr.write(
1093
1363
  `[exed] Timer TIMEOUT WARNING: ${name} has been running for >${TIMER_TIMEOUT_MS / 1e3}s \u2014 likely blocking the event loop
@@ -1109,8 +1379,31 @@ async function traceDaemonTimer(name, fn) {
1109
1379
  const span = measureSpan(probe);
1110
1380
  const durationMs = Math.round(span.monoMs);
1111
1381
  const slept = span.sleptMs > 1e3;
1112
- if (!slept && durationMs >= TIMER_TIMEOUT_MS) {
1113
- _lastBlockingTimer = { name, durationMs, ts: Date.now() };
1382
+ const sweepPausedMs = Math.max(0, sweepPauseTotalMs() - pauseSnapshot);
1383
+ const busyMs = Math.max(0, durationMs - sweepPausedMs);
1384
+ if (!slept && busyMs >= TIMER_TIMEOUT_MS) {
1385
+ _lastBlockingTimer = { name, durationMs: busyMs, ts: Date.now() };
1386
+ }
1387
+ if (shouldWarnSlowTimer(busyMs, slept, TIMER_SLOW_WARN_MS)) {
1388
+ const msg = `[exed] Timer SLOW: ${name} busy ${busyMs}ms (wall ${durationMs}ms, sweep-paused ${sweepPausedMs}ms) \u2014 exceeded ${TIMER_SLOW_WARN_MS}ms per-tick budget (event loop was held)`;
1389
+ process.stderr.write(`${msg}
1390
+ `);
1391
+ logDaemonHealth({
1392
+ event: "process_stats",
1393
+ pid: process.pid,
1394
+ message: msg,
1395
+ data: {
1396
+ type: "timer_slow",
1397
+ timer: name,
1398
+ durationMs,
1399
+ busyMs,
1400
+ sweepPausedMs,
1401
+ thresholdMs: TIMER_SLOW_WARN_MS,
1402
+ wallMs: Math.round(span.wallMs),
1403
+ sleptMs: Math.round(span.sleptMs),
1404
+ uptimeMs: Date.now() - _startedAt2
1405
+ }
1406
+ });
1114
1407
  }
1115
1408
  if (shouldTraceDaemonTimer(durationMs)) {
1116
1409
  const sleepNote = slept ? ` (wall ${Math.round(span.wallMs)}ms \u2014 host slept/clock-stepped ${Math.round(span.sleptMs)}ms; not an event-loop block)` : "";
@@ -1178,18 +1471,18 @@ function recordDaemonCrash() {
1178
1471
  const now = Date.now();
1179
1472
  let counter = { crashes: [] };
1180
1473
  try {
1181
- counter = JSON.parse(readFileSync4(CRASH_LOOP_COUNTER_PATH, "utf8"));
1474
+ counter = JSON.parse(readFileSync5(CRASH_LOOP_COUNTER_PATH, "utf8"));
1182
1475
  } catch {
1183
1476
  }
1184
1477
  counter.crashes = counter.crashes.filter((t) => now - t < CRASH_LOOP_WINDOW_MS);
1185
1478
  counter.crashes.push(now);
1186
1479
  try {
1187
- writeFileSync3(CRASH_LOOP_COUNTER_PATH, JSON.stringify(counter), "utf8");
1480
+ writeFileSync4(CRASH_LOOP_COUNTER_PATH, JSON.stringify(counter), "utf8");
1188
1481
  } catch {
1189
1482
  }
1190
1483
  if (counter.crashes.length >= CRASH_LOOP_THRESHOLD) {
1191
1484
  try {
1192
- writeFileSync3(CRASH_LOOP_BREAKER_PATH, JSON.stringify({
1485
+ writeFileSync4(CRASH_LOOP_BREAKER_PATH, JSON.stringify({
1193
1486
  trippedAt: (/* @__PURE__ */ new Date()).toISOString(),
1194
1487
  crashCount: counter.crashes.length,
1195
1488
  windowMs: CRASH_LOOP_WINDOW_MS
@@ -1206,10 +1499,10 @@ function recordDaemonCrash() {
1206
1499
  }
1207
1500
  function isCrashLoopBreakerActive() {
1208
1501
  try {
1209
- if (!existsSync4(CRASH_LOOP_BREAKER_PATH)) return false;
1210
- const ageMs = Date.now() - statSync(CRASH_LOOP_BREAKER_PATH).mtimeMs;
1502
+ if (!existsSync5(CRASH_LOOP_BREAKER_PATH)) return false;
1503
+ const ageMs = Date.now() - statSync2(CRASH_LOOP_BREAKER_PATH).mtimeMs;
1211
1504
  if (ageMs > CRASH_LOOP_BREAKER_TTL_MS) {
1212
- unlinkSync2(CRASH_LOOP_BREAKER_PATH);
1505
+ unlinkSync3(CRASH_LOOP_BREAKER_PATH);
1213
1506
  process.stderr.write(`[exed] Crash-loop breaker expired after ${Math.round(ageMs / 6e4)}min \u2014 cleared.
1214
1507
  `);
1215
1508
  return false;
@@ -1221,7 +1514,7 @@ function isCrashLoopBreakerActive() {
1221
1514
  }
1222
1515
  function resetCrashCounterOnHealthy() {
1223
1516
  try {
1224
- unlinkSync2(CRASH_LOOP_COUNTER_PATH);
1517
+ unlinkSync3(CRASH_LOOP_COUNTER_PATH);
1225
1518
  } catch {
1226
1519
  }
1227
1520
  }
@@ -1247,10 +1540,10 @@ function currentEmbedConfigFingerprint() {
1247
1540
  }
1248
1541
  function clearStaleOomMarker() {
1249
1542
  try {
1250
- if (!existsSync4(OOM_MARKER_PATH)) return false;
1251
- const ageMs = Date.now() - statSync(OOM_MARKER_PATH).mtimeMs;
1543
+ if (!existsSync5(OOM_MARKER_PATH)) return false;
1544
+ const ageMs = Date.now() - statSync2(OOM_MARKER_PATH).mtimeMs;
1252
1545
  if (ageMs < OOM_MARKER_TTL_MS) return false;
1253
- unlinkSync2(OOM_MARKER_PATH);
1546
+ unlinkSync3(OOM_MARKER_PATH);
1254
1547
  process.stderr.write(`[exed] Cleared stale embedding OOM marker after ${Math.round(ageMs / 36e5)}h.
1255
1548
  `);
1256
1549
  return true;
@@ -1264,7 +1557,7 @@ function eventLoopBlockedMarkerPath() {
1264
1557
  }
1265
1558
  function isEventLoopBlockedNow(freshMs = EVENT_LOOP_BLOCKED_FRESH_MS) {
1266
1559
  try {
1267
- const ageMs = Date.now() - statSync(eventLoopBlockedMarkerPath()).mtimeMs;
1560
+ const ageMs = Date.now() - statSync2(eventLoopBlockedMarkerPath()).mtimeMs;
1268
1561
  return ageMs < freshMs && ageMs > -freshMs;
1269
1562
  } catch {
1270
1563
  return false;
@@ -1273,8 +1566,8 @@ function isEventLoopBlockedNow(freshMs = EVENT_LOOP_BLOCKED_FRESH_MS) {
1273
1566
  function touchEventLoopHeartbeat() {
1274
1567
  try {
1275
1568
  const p = eventLoopHeartbeatPath();
1276
- mkdirSync2(path3.dirname(p), { recursive: true });
1277
- writeFileSync3(p, String(Date.now()));
1569
+ mkdirSync3(path3.dirname(p), { recursive: true });
1570
+ writeFileSync4(p, String(Date.now()));
1278
1571
  } catch {
1279
1572
  }
1280
1573
  }
@@ -1282,8 +1575,8 @@ function checkLaunchdPlistHealth() {
1282
1575
  try {
1283
1576
  if (process.platform !== "darwin") return;
1284
1577
  const plistPath = path3.join(os2.homedir(), "Library", "LaunchAgents", "com.askexe.exed.plist");
1285
- if (!existsSync4(plistPath)) return;
1286
- const plist = readFileSync4(plistPath, "utf8");
1578
+ if (!existsSync5(plistPath)) return;
1579
+ const plist = readFileSync5(plistPath, "utf8");
1287
1580
  const expectedHeap = computeDaemonHeapCapMb();
1288
1581
  const heapMatch = plist.match(/--max-old-space-size=(\d+)/);
1289
1582
  const heap = heapMatch?.[1] ? parseInt(heapMatch[1], 10) : null;
@@ -1354,7 +1647,7 @@ async function loadModel() {
1354
1647
  } catch {
1355
1648
  }
1356
1649
  const modelPath = path3.join(MODELS_DIR, MODEL_FILE);
1357
- if (!existsSync4(modelPath)) {
1650
+ if (!existsSync5(modelPath)) {
1358
1651
  process.stderr.write(`[exed] No model at ${modelPath} \u2014 running without embeddings (VPS mode).
1359
1652
  `);
1360
1653
  _embeddingsDisabledByDesign = true;
@@ -1365,19 +1658,19 @@ async function loadModel() {
1365
1658
  process.stderr.write(`[exed] Embedding config changed \u2014 cleared stale embed-worker backoff (one prompt retry under new config).
1366
1659
  `);
1367
1660
  try {
1368
- if (existsSync4(EMBED_TIMEOUT_MARKER_PATH)) unlinkSync2(EMBED_TIMEOUT_MARKER_PATH);
1661
+ if (existsSync5(EMBED_TIMEOUT_MARKER_PATH)) unlinkSync3(EMBED_TIMEOUT_MARKER_PATH);
1369
1662
  } catch {
1370
1663
  }
1371
1664
  _embedConsecutiveTimeouts = 0;
1372
1665
  }
1373
1666
  clearStaleOomMarker();
1374
- if (existsSync4(OOM_MARKER_PATH)) {
1667
+ if (existsSync5(OOM_MARKER_PATH)) {
1375
1668
  process.stderr.write(`[exed] Skipping embeddings \u2014 OOM marker exists. Delete ${OOM_MARKER_PATH} to retry.
1376
1669
  `);
1377
1670
  _embeddingsDisabledByDesign = true;
1378
1671
  return;
1379
1672
  }
1380
- if (existsSync4(EMBED_TIMEOUT_MARKER_PATH)) {
1673
+ if (existsSync5(EMBED_TIMEOUT_MARKER_PATH)) {
1381
1674
  process.stderr.write(`[exed] Skipping embeddings \u2014 inference-timeout marker exists (local embeddings non-functional on this host). Set EXE_EMBEDDINGS=0 or delete ${EMBED_TIMEOUT_MARKER_PATH} to retry.
1382
1675
  `);
1383
1676
  _embeddingsDisabledByDesign = true;
@@ -1432,7 +1725,7 @@ async function loadModel() {
1432
1725
  process.stderr.write("[exed] Spawning embed worker process...\n");
1433
1726
  try {
1434
1727
  const workerPath = path3.join(path3.dirname(new URL(import.meta.url).pathname), "embed-worker.js");
1435
- if (!existsSync4(workerPath)) {
1728
+ if (!existsSync5(workerPath)) {
1436
1729
  process.stderr.write(`[exed] Embed worker not found at ${workerPath} \u2014 running without embeddings.
1437
1730
  `);
1438
1731
  return;
@@ -1518,8 +1811,8 @@ async function loadModel() {
1518
1811
  const oomShaped = code === 134 || signal === "SIGKILL" || signal === "SIGABRT";
1519
1812
  if (oomShaped) {
1520
1813
  try {
1521
- mkdirSync2(path3.dirname(OOM_MARKER_PATH), { recursive: true });
1522
- writeFileSync3(OOM_MARKER_PATH, `embed-worker OOM exit (code=${code}, signal=${signal ?? "none"}) at ${(/* @__PURE__ */ new Date()).toISOString()}
1814
+ mkdirSync3(path3.dirname(OOM_MARKER_PATH), { recursive: true });
1815
+ writeFileSync4(OOM_MARKER_PATH, `embed-worker OOM exit (code=${code}, signal=${signal ?? "none"}) at ${(/* @__PURE__ */ new Date()).toISOString()}
1523
1816
  `);
1524
1817
  process.stderr.write(`[exed] Embed worker OOM-shaped exit \u2014 wrote OOM marker; respawns will skip model load until it TTL-clears.
1525
1818
  `);
@@ -1539,7 +1832,7 @@ async function loadModel() {
1539
1832
  void (async () => {
1540
1833
  try {
1541
1834
  if (_storeInitialized) {
1542
- const { writeNotification } = await import("../notifications-4UT53CDG.js");
1835
+ const { writeNotification } = await import("../notifications-6XCSUTJW.js");
1543
1836
  await writeNotification({
1544
1837
  agentId: "exe",
1545
1838
  agentRole: "system",
@@ -1620,8 +1913,8 @@ function disableEmbeddingsForInferenceTimeouts() {
1620
1913
  if (_embeddingsDisabledByDesign) return;
1621
1914
  _embeddingsDisabledByDesign = true;
1622
1915
  try {
1623
- mkdirSync2(path3.dirname(EMBED_TIMEOUT_MARKER_PATH), { recursive: true });
1624
- writeFileSync3(
1916
+ mkdirSync3(path3.dirname(EMBED_TIMEOUT_MARKER_PATH), { recursive: true });
1917
+ writeFileSync4(
1625
1918
  EMBED_TIMEOUT_MARKER_PATH,
1626
1919
  `embed inference timed out ${_embedConsecutiveTimeouts}x consecutively at ${(/* @__PURE__ */ new Date()).toISOString()}
1627
1920
  `
@@ -1655,7 +1948,7 @@ function disableEmbeddingsForInferenceTimeouts() {
1655
1948
  void (async () => {
1656
1949
  try {
1657
1950
  if (_storeInitialized) {
1658
- const { writeNotification } = await import("../notifications-4UT53CDG.js");
1951
+ const { writeNotification } = await import("../notifications-6XCSUTJW.js");
1659
1952
  await writeNotification({
1660
1953
  agentId: "exe",
1661
1954
  agentRole: "system",
@@ -1843,11 +2136,11 @@ async function shutdown(exitCode = 0, reason = null) {
1843
2136
  `
1844
2137
  );
1845
2138
  try {
1846
- unlinkSync2(SOCKET_PATH);
2139
+ unlinkSync3(SOCKET_PATH);
1847
2140
  } catch {
1848
2141
  }
1849
2142
  try {
1850
- unlinkSync2(PID_PATH);
2143
+ unlinkSync3(PID_PATH);
1851
2144
  } catch {
1852
2145
  }
1853
2146
  process.kill(process.pid, "SIGKILL");
@@ -1875,7 +2168,7 @@ async function shutdown(exitCode = 0, reason = null) {
1875
2168
  preRestartDedupWindowMs,
1876
2169
  findActiveDb,
1877
2170
  shouldSkipBackupUnderMemoryPressure
1878
- } = await import("../db-backup-W2QFSYQC.js");
2171
+ } = await import("./db-backup.js");
1879
2172
  const PRE_RESTART_DEDUP_MS = preRestartDedupWindowMs();
1880
2173
  const PRE_RESTART_STORM_CAP = (() => {
1881
2174
  const v = Number(process.env.EXE_PRE_RESTART_STORM_CAP);
@@ -1898,10 +2191,10 @@ async function shutdown(exitCode = 0, reason = null) {
1898
2191
  const dbPath = findActiveDb();
1899
2192
  let dbBytes = 0;
1900
2193
  try {
1901
- dbBytes = dbPath ? statSync(dbPath).size : 0;
2194
+ dbBytes = dbPath ? statSync2(dbPath).size : 0;
1902
2195
  } catch {
1903
2196
  }
1904
- const { getAvailableMemoryBytesSync } = await import("../memory-pressure-watchdog-HN5X7AVN.js");
2197
+ const { getAvailableMemoryBytesSync } = await import("../memory-pressure-watchdog-PSVJ5BCF.js");
1905
2198
  const freeBytes = getAvailableMemoryBytesSync();
1906
2199
  if (shouldSkipBackupUnderMemoryPressure(freeBytes, dbBytes)) {
1907
2200
  memoryGateSkip = true;
@@ -1932,6 +2225,7 @@ async function shutdown(exitCode = 0, reason = null) {
1932
2225
  process.stderr.write(`[exed] Pre-restart backup failed (non-fatal): ${e instanceof Error ? e.message : String(e)}
1933
2226
  `);
1934
2227
  }
2228
+ const restartHandoff = shouldScheduleDaemonRestartHandoff(exitCode, reason);
1935
2229
  try {
1936
2230
  const { getClient } = await import("./database.js");
1937
2231
  const client = getClient();
@@ -1945,12 +2239,20 @@ async function shutdown(exitCode = 0, reason = null) {
1945
2239
  `);
1946
2240
  }
1947
2241
  try {
1948
- const { stopProjectionWorker } = await import("../projection-worker-FZ7YSN3G.js");
2242
+ const { disposeDatabase } = await import("./database.js");
2243
+ await disposeDatabase();
2244
+ process.stderr.write("[exed] Database disposed before restart handoff.\n");
2245
+ } catch (e) {
2246
+ process.stderr.write(`[exed] Database dispose failed during shutdown: ${e instanceof Error ? e.message : String(e)}
2247
+ `);
2248
+ }
2249
+ try {
2250
+ const { stopProjectionWorker } = await import("../projection-worker-CKC2E22U.js");
1949
2251
  stopProjectionWorker();
1950
2252
  } catch {
1951
2253
  }
1952
2254
  try {
1953
- const { disposeShards } = await import("../shard-manager-35PWFR3B.js");
2255
+ const { disposeShards } = await import("../shard-manager-OETALPDW.js");
1954
2256
  disposeShards();
1955
2257
  } catch {
1956
2258
  }
@@ -1968,18 +2270,15 @@ async function shutdown(exitCode = 0, reason = null) {
1968
2270
  } catch {
1969
2271
  }
1970
2272
  try {
1971
- const sessionsToSave = _mcpSessionDetailsRef ? Array.from(_mcpSessionDetailsRef.entries()).map(([sid, d]) => ({
1972
- sessionId: sid,
1973
- agentId: d.agentId,
1974
- agentRole: d.agentRole,
1975
- runtime: d.runtime,
1976
- sessionHint: d.sessionHint,
1977
- savedAt: Date.now()
1978
- })) : [];
1979
- if (sessionsToSave.length > 0) {
1980
- const sessPath = path3.join(EXE_AI_DIR, "mcp-sessions-persist.json");
1981
- writeFileSync3(sessPath, JSON.stringify(sessionsToSave) + "\n", { mode: 384 });
1982
- process.stderr.write(`[exed] Persisted ${sessionsToSave.length} MCP session(s) for next daemon.
2273
+ disposeDbWriteWorker();
2274
+ } catch {
2275
+ }
2276
+ try {
2277
+ const { persistMcpSessions, buildPersistedSessions } = await import("../mcp-session-persist-PS7BIG44.js");
2278
+ const sessionsToSave = _mcpSessionDetailsRef ? buildPersistedSessions(_mcpSessionDetailsRef.entries(), _mcpSessionLastSeenRef ?? /* @__PURE__ */ new Map(), Date.now()) : [];
2279
+ const persisted = persistMcpSessions(sessionsToSave, EXE_AI_DIR);
2280
+ if (persisted > 0) {
2281
+ process.stderr.write(`[exed] Persisted ${persisted} MCP session(s) for next daemon.
1983
2282
  `);
1984
2283
  }
1985
2284
  } catch (e) {
@@ -1987,17 +2286,50 @@ async function shutdown(exitCode = 0, reason = null) {
1987
2286
  `);
1988
2287
  }
1989
2288
  try {
1990
- unlinkSync2(SOCKET_PATH);
2289
+ unlinkSync3(SOCKET_PATH);
1991
2290
  } catch (e) {
1992
2291
  process.stderr.write(`[exed] socket cleanup: ${e.message}
1993
2292
  `);
1994
2293
  }
1995
2294
  try {
1996
- unlinkSync2(PID_PATH);
2295
+ unlinkSync3(PID_PATH);
1997
2296
  } catch (e) {
1998
2297
  process.stderr.write(`[exed] pid cleanup: ${e.message}
1999
2298
  `);
2000
2299
  }
2300
+ if (restartHandoff) {
2301
+ try {
2302
+ const moduleDir = path3.dirname(fileURLToPath(import.meta.url));
2303
+ const helperPath = path3.resolve(moduleDir, "../bin/daemon-restart-handoff.js");
2304
+ const daemonPath = fileURLToPath(import.meta.url);
2305
+ const logPath = path3.join(EXE_AI_DIR, "logs", "exed.log");
2306
+ const lockPath = path3.join(EXE_AI_DIR, "exed-spawn.lock");
2307
+ const heapCapMb = computeDaemonHeapCapMb(os2.totalmem() / (1024 * 1024 * 1024));
2308
+ const config = {
2309
+ oldPid: process.pid,
2310
+ daemonPath,
2311
+ pidPath: PID_PATH,
2312
+ socketPath: SOCKET_PATH,
2313
+ lockPath,
2314
+ logPath,
2315
+ heapCapMb
2316
+ };
2317
+ const child = spawn(process.execPath, [helperPath], {
2318
+ detached: true,
2319
+ stdio: "ignore",
2320
+ env: {
2321
+ ...process.env,
2322
+ EXE_DAEMON_HANDOFF_CONFIG: JSON.stringify(config)
2323
+ }
2324
+ });
2325
+ child.unref();
2326
+ process.stderr.write(`[exed] Restart handoff helper scheduled (pid ${child.pid ?? "unknown"}).
2327
+ `);
2328
+ } catch (e) {
2329
+ process.stderr.write(`[exed] Restart handoff helper schedule failed: ${e instanceof Error ? e.message : String(e)}
2330
+ `);
2331
+ }
2332
+ }
2001
2333
  process.stderr.write(`[exed] Shutdown complete (exit ${exitCode}${exitCode === 0 ? "" : " \u2014 restart-intent, launchd will relaunch"}).
2002
2334
  `);
2003
2335
  process.exit(exitCode);
@@ -2011,7 +2343,7 @@ async function handleHealthCheck(socket, requestId) {
2011
2343
  let pipelineStatus = "unknown";
2012
2344
  if (dbConnected) {
2013
2345
  try {
2014
- await import("../pipeline-router-LM53NMWJ.js");
2346
+ await import("../pipeline-router-N2LDNFJ5.js");
2015
2347
  pipelineStatus = "ok";
2016
2348
  } catch {
2017
2349
  pipelineStatus = "unavailable";
@@ -2196,11 +2528,11 @@ var _ingestCount = 0;
2196
2528
  var INGEST_OUTBOX_DIR = path3.join(EXE_AI_DIR, "ingest-outbox");
2197
2529
  function persistIngestOutbox(req) {
2198
2530
  try {
2199
- mkdirSync2(INGEST_OUTBOX_DIR, { recursive: true });
2531
+ mkdirSync3(INGEST_OUTBOX_DIR, { recursive: true });
2200
2532
  const id = randomUUID();
2201
2533
  const finalPath = path3.join(INGEST_OUTBOX_DIR, `${Date.now()}-${id}.json`);
2202
2534
  const tmpPath = `${finalPath}.tmp`;
2203
- writeFileSync3(tmpPath, JSON.stringify(req) + "\n", { mode: 384 });
2535
+ writeFileSync4(tmpPath, JSON.stringify(req) + "\n", { mode: 384 });
2204
2536
  renameSync(tmpPath, finalPath);
2205
2537
  return finalPath;
2206
2538
  } catch (err) {
@@ -2211,12 +2543,12 @@ function persistIngestOutbox(req) {
2211
2543
  }
2212
2544
  async function drainIngestOutbox() {
2213
2545
  try {
2214
- if (!existsSync4(INGEST_OUTBOX_DIR)) return;
2546
+ if (!existsSync5(INGEST_OUTBOX_DIR)) return;
2215
2547
  const files = readdirSync(INGEST_OUTBOX_DIR).filter((f) => f.endsWith(".json")).sort().slice(0, 500);
2216
2548
  for (const file of files) {
2217
2549
  const fullPath = path3.join(INGEST_OUTBOX_DIR, file);
2218
2550
  try {
2219
- const req = JSON.parse(readFileSync4(fullPath, "utf8"));
2551
+ const req = JSON.parse(readFileSync5(fullPath, "utf8"));
2220
2552
  await handleIngest(req, fullPath);
2221
2553
  } catch (err) {
2222
2554
  process.stderr.write(`[exed] Ingest outbox drain failed for ${file}: ${err instanceof Error ? err.message : String(err)}
@@ -2235,7 +2567,7 @@ async function handleIngest(req, outboxPath) {
2235
2567
  if (!req.rawText || req.rawText.length < 50) {
2236
2568
  if (persistedPath) {
2237
2569
  try {
2238
- unlinkSync2(persistedPath);
2570
+ unlinkSync3(persistedPath);
2239
2571
  } catch {
2240
2572
  }
2241
2573
  }
@@ -2258,7 +2590,7 @@ async function handleIngest(req, outboxPath) {
2258
2590
  _ingestCount++;
2259
2591
  if (persistedPath) {
2260
2592
  try {
2261
- unlinkSync2(persistedPath);
2593
+ unlinkSync3(persistedPath);
2262
2594
  } catch {
2263
2595
  }
2264
2596
  }
@@ -2306,16 +2638,16 @@ async function handleBatchWriteMemory(socket, requestId, entries) {
2306
2638
  });
2307
2639
  }
2308
2640
  }
2309
- async function writeMemoryRecord(entry) {
2641
+ async function writeMemoryRecord(entry, opts = {}) {
2310
2642
  if (_drainingWrites) throw new Error("Server shutting down \u2014 writes paused");
2311
2643
  _activeWrites++;
2312
2644
  try {
2313
- return await _writeMemoryRecordInner(entry);
2645
+ return await _writeMemoryRecordInner(entry, opts.syncOnly === true);
2314
2646
  } finally {
2315
2647
  _activeWrites--;
2316
2648
  }
2317
2649
  }
2318
- async function _writeMemoryRecordInner(entry) {
2650
+ async function _writeMemoryRecordInner(entry, syncOnly = false) {
2319
2651
  const id = randomUUID();
2320
2652
  const now = entry.timestamp || (/* @__PURE__ */ new Date()).toISOString();
2321
2653
  const governed = governMemoryRecord({
@@ -2337,15 +2669,8 @@ async function _writeMemoryRecordInner(entry) {
2337
2669
  });
2338
2670
  if (governed.shouldDrop) return id;
2339
2671
  const record = governed.record;
2340
- const duplicate = await findScopedDuplicate({
2341
- contentHash: governed.contentHash,
2342
- agentId: record.agent_id,
2343
- projectName: record.project_name,
2344
- memoryType: record.memory_type ?? "raw"
2345
- });
2346
- if (duplicate) return duplicate;
2347
2672
  let vectorBlob = null;
2348
- if (_embedWorkerReady && !governed.skipEmbedding) {
2673
+ if (!syncOnly && _embedWorkerReady && !governed.skipEmbedding) {
2349
2674
  try {
2350
2675
  const vectors = await embedTexts([record.raw_text]);
2351
2676
  if (vectors.length > 0 && vectors[0].length === EMBEDDING_DIM) {
@@ -2357,11 +2682,33 @@ async function _writeMemoryRecordInner(entry) {
2357
2682
  `);
2358
2683
  }
2359
2684
  }
2360
- const { getClient } = await import("./database.js");
2361
- const client = getClient();
2362
2685
  const hasVector = vectorBlob !== null;
2363
2686
  const embeddingModel = hasVector ? activeEmbeddingModelName() : null;
2364
- await client.execute({
2687
+ if (!syncOnly && isWriteWorkerEnabled() && isDbWriteWorkerReady()) {
2688
+ try {
2689
+ const result = await writeMemoryInWorker({
2690
+ record,
2691
+ contentHash: governed.contentHash,
2692
+ vectorBlob,
2693
+ embeddingModel,
2694
+ trajectory: entry.trajectory ?? null
2695
+ });
2696
+ return result.memoryId;
2697
+ } catch (e) {
2698
+ process.stderr.write(`[exed] write worker failed (${e instanceof Error ? e.message : String(e)}) - falling back to main-thread write
2699
+ `);
2700
+ }
2701
+ }
2702
+ const duplicate = await findScopedDuplicate({
2703
+ contentHash: governed.contentHash,
2704
+ agentId: record.agent_id,
2705
+ projectName: record.project_name,
2706
+ memoryType: record.memory_type ?? "raw"
2707
+ });
2708
+ if (duplicate) return duplicate;
2709
+ const { getClient } = await import("./database.js");
2710
+ const client = getClient();
2711
+ const insertResult = await client.execute({
2365
2712
  sql: hasVector ? `INSERT OR IGNORE INTO memories
2366
2713
  (id, agent_id, agent_role, session_id, timestamp, tool_name, project_name,
2367
2714
  has_error, raw_text, vector, version, task_id, importance, status,
@@ -2416,10 +2763,19 @@ async function _writeMemoryRecordInner(entry) {
2416
2763
  embeddingModel
2417
2764
  ]
2418
2765
  });
2766
+ if (Number(insertResult.rowsAffected) === 0) {
2767
+ const winner = await findScopedDuplicate({
2768
+ contentHash: governed.contentHash,
2769
+ agentId: record.agent_id,
2770
+ projectName: record.project_name,
2771
+ memoryType: record.memory_type ?? "raw"
2772
+ });
2773
+ return winner ?? id;
2774
+ }
2419
2775
  const vRow = await client.execute({ sql: "SELECT version FROM memories WHERE id = ?", args: [id] });
2420
2776
  const version = Number(vRow.rows[0]?.version) || 0;
2421
2777
  try {
2422
- const { insertOntologyForMemory } = await import("../agentic-ontology-3FXYMHKW.js");
2778
+ const { insertOntologyForMemory } = await import("../agentic-ontology-SCG6UUHK.js");
2423
2779
  await insertOntologyForMemory({
2424
2780
  id,
2425
2781
  agent_id: record.agent_id,
@@ -2443,20 +2799,33 @@ async function _writeMemoryRecordInner(entry) {
2443
2799
  }
2444
2800
  var MEMORY_DRAIN_INTERVAL_MS = 30 * 1e3;
2445
2801
  var MEMORY_DRAIN_BATCH = Math.max(1, Number(process.env.EXE_MEMORY_DRAIN_BATCH) || 1);
2802
+ var MEMORY_DRAIN_TX_BATCH = Math.max(1, Number(process.env.EXE_MEMORY_DRAIN_TX_BATCH) || 25);
2446
2803
  function startMemoryQueueDrain() {
2447
2804
  const drain = async () => traceDaemonTimer("memory_queue_drain", async () => {
2448
2805
  fired("memory_queue_drain");
2449
2806
  if (!await ensureStoreForPolling()) return;
2450
2807
  try {
2451
- const { ackQueue, claimQueue, retryQueueEntries, processQueueEntries } = await import("../memory-queue-2UOOF27L.js");
2808
+ const { ackQueue, claimQueue, retryQueueEntries, processQueueEntries } = await import("../memory-queue-ZI7DX44D.js");
2452
2809
  const lease = claimQueue();
2453
2810
  if (!lease || lease.entries.length === 0) return;
2454
2811
  acted("memory_queue_drain");
2455
2812
  const entries = lease.entries;
2456
- const result = await processQueueEntries(entries, (entry) => writeMemoryRecord(entry), {
2813
+ const useTxBatch = !_embedWorkerReady && !(isWriteWorkerEnabled() && isDbWriteWorkerReady());
2814
+ const txClient = useTxBatch ? (await import("./database.js")).getClient() : null;
2815
+ const drainSyncOnly = useTxBatch;
2816
+ const result = await processQueueEntries(entries, (entry) => writeMemoryRecord(entry, { syncOnly: drainSyncOnly }), {
2457
2817
  isDraining: () => _drainingWrites,
2458
- batchSize: MEMORY_DRAIN_BATCH,
2818
+ batchSize: useTxBatch ? MEMORY_DRAIN_TX_BATCH : MEMORY_DRAIN_BATCH,
2459
2819
  yieldFn: yieldToEventLoop,
2820
+ beginBatch: txClient ? async () => {
2821
+ await txClient.execute("BEGIN IMMEDIATE");
2822
+ } : void 0,
2823
+ commitBatch: txClient ? async () => {
2824
+ await txClient.execute("COMMIT");
2825
+ } : void 0,
2826
+ rollbackBatch: txClient ? async () => {
2827
+ await txClient.execute("ROLLBACK");
2828
+ } : void 0,
2460
2829
  onWriteError: (_entry, err) => {
2461
2830
  process.stderr.write(
2462
2831
  `[exed] Queue drain write error: ${err instanceof Error ? err.message : String(err)}
@@ -2484,7 +2853,24 @@ function startMemoryQueueDrain() {
2484
2853
  );
2485
2854
  }
2486
2855
  });
2487
- void drain();
2856
+ void (async () => {
2857
+ const holdStartedAt = Date.now();
2858
+ const HOLD_CAP_MS = Number(process.env.EXE_STARTUP_DRAIN_GRACE_CAP_MS) || 30 * 60 * 1e3;
2859
+ const hold = setInterval(() => {
2860
+ if (Date.now() - holdStartedAt >= HOLD_CAP_MS) {
2861
+ clearInterval(hold);
2862
+ return;
2863
+ }
2864
+ extendBootCatchUp(6e4);
2865
+ }, 3e4);
2866
+ hold.unref();
2867
+ extendBootCatchUp(6e4);
2868
+ try {
2869
+ await drain();
2870
+ } finally {
2871
+ clearInterval(hold);
2872
+ }
2873
+ })();
2488
2874
  const timer = setInterval(() => void drain(), MEMORY_DRAIN_INTERVAL_MS);
2489
2875
  timer.unref();
2490
2876
  process.stderr.write(`[exed] Memory queue drain started (every ${MEMORY_DRAIN_INTERVAL_MS / 1e3}s)
@@ -2494,19 +2880,19 @@ var MESSAGE_DRAIN_INTERVAL_MS = 3e4;
2494
2880
  function retryMessageQueueEntries(leasePath, entries) {
2495
2881
  if (entries.length === 0) {
2496
2882
  try {
2497
- unlinkSync2(leasePath);
2883
+ unlinkSync3(leasePath);
2498
2884
  } catch {
2499
2885
  }
2500
2886
  return;
2501
2887
  }
2502
- writeFileSync3(leasePath, entries.map((entry) => JSON.stringify(entry)).join("\n") + "\n");
2888
+ writeFileSync4(leasePath, entries.map((entry) => JSON.stringify(entry)).join("\n") + "\n");
2503
2889
  }
2504
2890
  function startMessageQueueDrain() {
2505
2891
  const drain = async () => traceDaemonTimer("message_queue_drain", async () => {
2506
2892
  fired("message_queue_drain");
2507
2893
  if (!await ensureStoreForPolling()) return;
2508
2894
  try {
2509
- const { claimMessageQueue, ackMessageQueue } = await import("../message-queue-client-4EOQRUXW.js");
2895
+ const { claimMessageQueue, ackMessageQueue } = await import("../message-queue-client-WMIO5FL5.js");
2510
2896
  const lease = claimMessageQueue();
2511
2897
  if (!lease || lease.entries.length === 0) return;
2512
2898
  acted("message_queue_drain");
@@ -2610,7 +2996,7 @@ async function retryPendingMessages() {
2610
2996
  }
2611
2997
  }
2612
2998
  function startServer() {
2613
- mkdirSync2(path3.dirname(SOCKET_PATH), { recursive: true });
2999
+ mkdirSync3(path3.dirname(SOCKET_PATH), { recursive: true });
2614
3000
  try {
2615
3001
  chmodSync(path3.dirname(SOCKET_PATH), 448);
2616
3002
  } catch {
@@ -2620,18 +3006,18 @@ function startServer() {
2620
3006
  const oldPath = path3.join(path3.dirname(SOCKET_PATH), oldFile);
2621
3007
  try {
2622
3008
  if (oldFile.endsWith(".pid")) {
2623
- const pid = parseInt(readFileSync4(oldPath, "utf8").trim(), 10);
3009
+ const pid = parseInt(readFileSync5(oldPath, "utf8").trim(), 10);
2624
3010
  if (pid > 0) try {
2625
3011
  process.kill(pid, "SIGKILL");
2626
3012
  } catch {
2627
3013
  }
2628
3014
  }
2629
- unlinkSync2(oldPath);
3015
+ unlinkSync3(oldPath);
2630
3016
  } catch {
2631
3017
  }
2632
3018
  }
2633
3019
  try {
2634
- unlinkSync2(SOCKET_PATH);
3020
+ unlinkSync3(SOCKET_PATH);
2635
3021
  } catch {
2636
3022
  }
2637
3023
  const server = net.createServer((socket) => {
@@ -2845,6 +3231,8 @@ async function resolveAndClaimPort() {
2845
3231
  async function startMcpHttpServer() {
2846
3232
  process.stderr.write("[exed] MCP HTTP: starting setup...\n");
2847
3233
  let _bootstrapServerRef = null;
3234
+ let _bootstrapFailedReason = null;
3235
+ let _bootReadyEtaMs = null;
2848
3236
  try {
2849
3237
  let parseDurationMs2 = function(value, fallback, options = {}) {
2850
3238
  if (!value) return fallback;
@@ -3020,6 +3408,18 @@ async function startMcpHttpServer() {
3020
3408
  }
3021
3409
  global.gc?.();
3022
3410
  }
3411
+ try {
3412
+ void import("../mcp-session-persist-PS7BIG44.js").then(({ persistMcpSessions, buildPersistedSessions }) => {
3413
+ const sessionsToSave = buildPersistedSessions(sessionDetails.entries(), sessionLastSeen, Date.now());
3414
+ persistMcpSessions(sessionsToSave, EXE_AI_DIR);
3415
+ }).catch((e) => {
3416
+ process.stderr.write(`[exed] Session persist failed (non-fatal): ${e instanceof Error ? e.message : String(e)}
3417
+ `);
3418
+ });
3419
+ } catch (e) {
3420
+ process.stderr.write(`[exed] Session persist failed (non-fatal): ${e instanceof Error ? e.message : String(e)}
3421
+ `);
3422
+ }
3023
3423
  }, getJsonRpcId2 = function(body) {
3024
3424
  if (body && typeof body === "object" && !Array.isArray(body) && "id" in body) {
3025
3425
  const id = body.id;
@@ -3055,21 +3455,21 @@ async function startMcpHttpServer() {
3055
3455
  const _earlyAllowRemote = /^(1|true|yes|on)$/i.test(process.env.EXE_MCP_ALLOW_REMOTE ?? "");
3056
3456
  const RESOLVED_MCP_HOST = _earlyIsRemoteHost && !_earlyAllowRemote ? "127.0.0.1" : _earlyRequestedHost;
3057
3457
  const RESOLVED_MCP_PORT = await resolveAndClaimPort();
3458
+ const DB_INIT_ETA_MS = 2e4;
3058
3459
  _bootstrapServerRef = createHttpServer((req, res) => {
3059
3460
  try {
3060
3461
  res.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1");
3061
- const path4 = (req.url || "/").split("?")[0];
3062
- if (req.method === "GET" && path4 === "/health") {
3063
- res.writeHead(200, { "Content-Type": "application/json" });
3064
- res.end(JSON.stringify({ status: "starting", version: PACKAGE_VERSION }));
3065
- return;
3066
- }
3067
- res.writeHead(503, { "Content-Type": "application/json", "Retry-After": "3" });
3068
- res.end(JSON.stringify({
3069
- jsonrpc: "2.0",
3070
- error: { code: -32001, message: "Daemon initializing \u2014 MCP not ready yet. Retry in a few seconds." },
3071
- id: null
3072
- }));
3462
+ const path4 = (req.url || "/").split("?")[0] ?? "/";
3463
+ const retryAfterSeconds = computeBootRetryAfterSeconds(Date.now(), _bootReadyEtaMs);
3464
+ const response = buildBootstrapResponse({
3465
+ failedReason: _bootstrapFailedReason,
3466
+ method: req.method ?? "",
3467
+ path: path4,
3468
+ retryAfterSeconds,
3469
+ version: PACKAGE_VERSION
3470
+ });
3471
+ res.writeHead(response.statusCode, response.headers);
3472
+ res.end(response.body);
3073
3473
  } catch {
3074
3474
  }
3075
3475
  });
@@ -3096,33 +3496,62 @@ async function startMcpHttpServer() {
3096
3496
  const BOOT_BACKOFF_MAX_MS = parseInt(process.env.EXE_BOOT_BACKOFF_MAX_MS ?? "") || 15e3;
3097
3497
  const BOOT_BACKOFF_MAX_ATTEMPTS = parseInt(process.env.EXE_BOOT_BACKOFF_MAX_ATTEMPTS ?? "") || 5;
3098
3498
  const starvationRatio = parseFloat(process.env.EXE_STARVATION_LOAD_RATIO ?? "1.5");
3499
+ let clientsWaiting = false;
3500
+ try {
3501
+ const sessPath = path3.join(EXE_AI_DIR, "mcp-sessions-persist.json");
3502
+ if (existsSync5(sessPath)) {
3503
+ const saved = JSON.parse(readFileSync5(sessPath, "utf-8"));
3504
+ const { hasRecentWaitingClients, mcpSessionRestoreMaxAgeMs } = await import("../mcp-session-persist-PS7BIG44.js");
3505
+ clientsWaiting = hasRecentWaitingClients(saved, Date.now(), mcpSessionRestoreMaxAgeMs());
3506
+ }
3507
+ } catch {
3508
+ clientsWaiting = false;
3509
+ }
3510
+ let loggedClientsWaitingBackoff = false;
3099
3511
  for (let attempt = 0; ; attempt++) {
3512
+ const load1m = os2.loadavg()[0] ?? 0;
3513
+ const cpuCount = os2.cpus().length || 1;
3100
3514
  const decision = decideBootBackoff({
3101
- load1m: os2.loadavg()[0] ?? 0,
3102
- cpuCount: os2.cpus().length || 1,
3515
+ load1m,
3516
+ cpuCount,
3103
3517
  starvationRatio,
3104
3518
  attempt,
3105
3519
  baseDelayMs: BOOT_BACKOFF_BASE_MS,
3106
3520
  maxDelayMs: BOOT_BACKOFF_MAX_MS,
3107
- maxAttempts: BOOT_BACKOFF_MAX_ATTEMPTS
3521
+ maxAttempts: BOOT_BACKOFF_MAX_ATTEMPTS,
3522
+ clientsWaiting
3108
3523
  });
3524
+ if (clientsWaiting && !loggedClientsWaitingBackoff) {
3525
+ const normalDecision = decideBootBackoff({
3526
+ load1m,
3527
+ cpuCount,
3528
+ starvationRatio,
3529
+ attempt,
3530
+ baseDelayMs: BOOT_BACKOFF_BASE_MS,
3531
+ maxDelayMs: BOOT_BACKOFF_MAX_MS,
3532
+ maxAttempts: BOOT_BACKOFF_MAX_ATTEMPTS
3533
+ });
3534
+ if (normalDecision.wait !== decision.wait || normalDecision.delayMs !== decision.delayMs || normalDecision.reason !== decision.reason) {
3535
+ process.stderr.write("[exed] Boot backoff: shortened because persisted MCP clients are waiting.\n");
3536
+ loggedClientsWaitingBackoff = true;
3537
+ }
3538
+ }
3109
3539
  if (!decision.wait) {
3540
+ _bootReadyEtaMs = Date.now() + DB_INIT_ETA_MS;
3110
3541
  if (decision.reason === "max_attempts_proceed") {
3111
3542
  process.stderr.write(
3112
- `[exed] Boot backoff: still starved after ${BOOT_BACKOFF_MAX_ATTEMPTS} attempts \u2014 proceeding with DB init anyway.
3543
+ `[exed] Boot backoff: still starved after ${attempt} attempts \u2014 proceeding with DB init anyway.
3113
3544
  `
3114
3545
  );
3115
3546
  logDaemonHealth({
3116
3547
  event: "boot_backoff_starvation",
3117
3548
  pid: process.pid,
3118
- message: `boot backoff exhausted (${BOOT_BACKOFF_MAX_ATTEMPTS} attempts) \u2014 proceeding`,
3119
- data: { load1m: os2.loadavg()[0] ?? 0, cpuCount: os2.cpus().length || 1, attempts: attempt }
3549
+ message: `boot backoff exhausted (${attempt} attempts) \u2014 proceeding`,
3550
+ data: { load1m, cpuCount, attempts: attempt }
3120
3551
  });
3121
3552
  }
3122
3553
  break;
3123
3554
  }
3124
- const load1m = os2.loadavg()[0] ?? 0;
3125
- const cpuCount = os2.cpus().length || 1;
3126
3555
  process.stderr.write(
3127
3556
  `[exed] Boot backoff: CPU starved (load=${load1m.toFixed(2)} cpus=${cpuCount}) \u2014 delaying DB init ${Math.round(decision.delayMs / 1e3)}s (attempt ${attempt + 1}/${BOOT_BACKOFF_MAX_ATTEMPTS}).
3128
3557
  `
@@ -3133,6 +3562,7 @@ async function startMcpHttpServer() {
3133
3562
  message: `boot delayed ${Math.round(decision.delayMs / 1e3)}s before DB init \u2014 CPU starved (load=${load1m.toFixed(2)} / cpus=${cpuCount})`,
3134
3563
  data: { load1m, cpuCount, loadPerCore: load1m / cpuCount, delayMs: decision.delayMs, attempt }
3135
3564
  });
3565
+ _bootReadyEtaMs = Date.now() + decision.delayMs + DB_INIT_ETA_MS;
3136
3566
  await new Promise((resolve) => setTimeout(resolve, decision.delayMs));
3137
3567
  }
3138
3568
  }
@@ -3143,16 +3573,17 @@ async function startMcpHttpServer() {
3143
3573
  "[exed] MCP HTTP: DB init failed \u2014 MCP HTTP endpoint will NOT start. Run 'exe-os setup' to fix keychain/encryption.\n"
3144
3574
  );
3145
3575
  if (_bootstrapServerRef) {
3146
- const srv = _bootstrapServerRef;
3147
- _bootstrapServerRef = null;
3148
- srv.close();
3576
+ _bootstrapFailedReason = "db_init";
3577
+ process.stderr.write(
3578
+ "[exed] MCP HTTP: failed-health responder remains alive on the port so tooling can distinguish terminal DB init failure from startup.\n"
3579
+ );
3149
3580
  }
3150
3581
  return;
3151
3582
  }
3152
3583
  process.stderr.write("[exed] MCP HTTP: DB ready\n");
3153
3584
  setBootPhase("db_ready");
3154
3585
  _storeInitialized = true;
3155
- const { initLicenseGate, getCachedLicenseGate } = await import("../license-gate-QTRQHV4F.js");
3586
+ const { initLicenseGate, getCachedLicenseGate } = await import("../license-gate-3KPSNYVA.js");
3156
3587
  const gateResult = await initLicenseGate();
3157
3588
  if (!gateResult.hasKey) {
3158
3589
  process.stderr.write(
@@ -3167,13 +3598,13 @@ async function startMcpHttpServer() {
3167
3598
  let _cachedWrapTelemetry = null;
3168
3599
  async function getWrapTelemetry() {
3169
3600
  if (!_cachedWrapTelemetry) {
3170
- const { wrapServerWithTelemetry } = await import("../tool-telemetry-KBXSBDTK.js");
3601
+ const { wrapServerWithTelemetry } = await import("../tool-telemetry-4MF2HIWR.js");
3171
3602
  _cachedWrapTelemetry = wrapServerWithTelemetry;
3172
3603
  }
3173
3604
  return _cachedWrapTelemetry;
3174
3605
  }
3175
3606
  Promise.all([
3176
- import("../tool-capability-index-VYF5GNJ2.js"),
3607
+ import("../tool-capability-index-QOFFCWDS.js"),
3177
3608
  import("../tool-gates-3IC7DK4R.js")
3178
3609
  ]).then(async ([{ getToolCapabilityIndex }, { TOOL_CATEGORIES }]) => {
3179
3610
  const gateState = getCachedLicenseGate();
@@ -3239,7 +3670,7 @@ async function startMcpHttpServer() {
3239
3670
  const expectedBuf = Buffer.from(_daemonToken);
3240
3671
  if (tokenBuf.length === expectedBuf.length && timingSafeEqual(tokenBuf, expectedBuf)) return true;
3241
3672
  try {
3242
- const { verifyAccessToken } = await import("../oauth-server-67YBDP32.js");
3673
+ const { verifyAccessToken } = await import("../oauth-server-HPQCBLZQ.js");
3243
3674
  const result = verifyAccessToken(token);
3244
3675
  return result.valid;
3245
3676
  } catch {
@@ -3248,28 +3679,28 @@ async function startMcpHttpServer() {
3248
3679
  }
3249
3680
  const pendingStaleSessionRecoveries = /* @__PURE__ */ new Map();
3250
3681
  _mcpSessionDetailsRef = sessionDetails;
3682
+ _mcpSessionLastSeenRef = sessionLastSeen;
3251
3683
  try {
3684
+ const { filterRestorableSessions, mcpSessionRestoreMaxAgeMs } = await import("../mcp-session-persist-PS7BIG44.js");
3252
3685
  const sessPath = path3.join(EXE_AI_DIR, "mcp-sessions-persist.json");
3253
- if (existsSync4(sessPath)) {
3254
- const raw = readFileSync4(sessPath, "utf-8");
3686
+ if (existsSync5(sessPath)) {
3687
+ const raw = readFileSync5(sessPath, "utf-8");
3255
3688
  const saved = JSON.parse(raw);
3256
- const MAX_AGE_MS = 5 * 60 * 1e3;
3689
+ const MAX_AGE_MS = mcpSessionRestoreMaxAgeMs();
3257
3690
  const now = Date.now();
3258
3691
  let restored = 0;
3259
- for (const s of saved) {
3260
- if (now - s.savedAt < MAX_AGE_MS) {
3261
- sessionLastSeen.set(s.sessionId, s.savedAt);
3262
- sessionDetails.set(s.sessionId, {
3263
- agentId: s.agentId,
3264
- agentRole: s.agentRole,
3265
- runtime: s.runtime,
3266
- sessionHint: s.sessionHint
3267
- });
3268
- restored++;
3269
- }
3692
+ for (const s of filterRestorableSessions(saved, now, MAX_AGE_MS)) {
3693
+ sessionLastSeen.set(s.sessionId, s.savedAt);
3694
+ sessionDetails.set(s.sessionId, {
3695
+ agentId: s.agentId,
3696
+ agentRole: s.agentRole,
3697
+ runtime: s.runtime,
3698
+ sessionHint: s.sessionHint
3699
+ });
3700
+ restored++;
3270
3701
  }
3271
3702
  try {
3272
- unlinkSync2(sessPath);
3703
+ unlinkSync3(sessPath);
3273
3704
  } catch {
3274
3705
  }
3275
3706
  if (restored > 0) {
@@ -3492,7 +3923,7 @@ async function startMcpHttpServer() {
3492
3923
  return;
3493
3924
  }
3494
3925
  try {
3495
- const { handleOAuthRoute } = await import("../oauth-server-67YBDP32.js");
3926
+ const { handleOAuthRoute } = await import("../oauth-server-HPQCBLZQ.js");
3496
3927
  const handled = await handleOAuthRoute(req, res, url, MCP_HTTP_PORT);
3497
3928
  if (handled) return;
3498
3929
  } catch (err) {
@@ -3524,7 +3955,7 @@ async function startMcpHttpServer() {
3524
3955
  for await (const chunk of req) chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
3525
3956
  const rawBody = Buffer.concat(chunks);
3526
3957
  try {
3527
- const { loadWebhookConfig, verifyHmac, processWebhook } = await import("../webhook-pipe-LEXMUQ5B.js");
3958
+ const { loadWebhookConfig, verifyHmac, processWebhook } = await import("../webhook-pipe-HH7XXXYC.js");
3528
3959
  const webhookConfig = await loadWebhookConfig();
3529
3960
  const serviceConfig = webhookConfig[serviceName];
3530
3961
  if (!serviceConfig) {
@@ -3620,7 +4051,7 @@ async function startMcpHttpServer() {
3620
4051
  contextPct: body.context_pct
3621
4052
  });
3622
4053
  if (body.context_pct !== void 0 && body.context_pct > 70) {
3623
- void import("../orchestration-events-WV4NWKZH.js").then(({ recordOrchestrationEventBestEffort: recordOE }) => {
4054
+ void import("../orchestration-events-5XDNVNR2.js").then(({ recordOrchestrationEventBestEffort: recordOE }) => {
3624
4055
  recordOE({
3625
4056
  eventType: "context.pressure",
3626
4057
  source: "exe-daemon.heartbeat",
@@ -3705,7 +4136,7 @@ async function startMcpHttpServer() {
3705
4136
  let sessionHint = req.headers["x-exe-session-name"] || req.headers["x-exe-session"] || "";
3706
4137
  if (sessionHint) {
3707
4138
  try {
3708
- const { sanitizeSessionHintHeader, rejectForgedSessionHint } = await import("../mcp-session-identity-T7H2EKFQ.js");
4139
+ const { sanitizeSessionHintHeader, rejectForgedSessionHint } = await import("../mcp-session-identity-S7GSVRR6.js");
3709
4140
  const rawHint = sessionHint;
3710
4141
  sessionHint = sanitizeSessionHintHeader(sessionHint);
3711
4142
  if (!sessionHint) {
@@ -3740,7 +4171,7 @@ async function startMcpHttpServer() {
3740
4171
  try {
3741
4172
  const liveSessions = await getTmuxSessionsAsync();
3742
4173
  const paneCommands = await getPaneCommandsAsync();
3743
- const { resolveMcpSessionHint } = await import("../mcp-session-identity-T7H2EKFQ.js");
4174
+ const { resolveMcpSessionHint } = await import("../mcp-session-identity-S7GSVRR6.js");
3744
4175
  let registrySessions = [];
3745
4176
  try {
3746
4177
  const { listSessions: listRegistrySessions } = await import("./session-registry.js");
@@ -3876,7 +4307,7 @@ async function startMcpHttpServer() {
3876
4307
  bindLive = await getTmuxSessionsAsync();
3877
4308
  } catch {
3878
4309
  }
3879
- const { isLauncherCorroboratedIdentity } = await import("../mcp-session-identity-T7H2EKFQ.js");
4310
+ const { isLauncherCorroboratedIdentity } = await import("../mcp-session-identity-S7GSVRR6.js");
3880
4311
  const corroborated = isLauncherCorroboratedIdentity({
3881
4312
  agentId,
3882
4313
  registrySessions: bindRegistry,
@@ -4119,7 +4550,7 @@ async function startMcpHttpServer() {
4119
4550
  }
4120
4551
  }
4121
4552
  try {
4122
- const { reconcileHintWithRegistryIdentity } = await import("../mcp-session-identity-T7H2EKFQ.js");
4553
+ const { reconcileHintWithRegistryIdentity } = await import("../mcp-session-identity-S7GSVRR6.js");
4123
4554
  const { listSessions: listRegistrySessions } = await import("./session-registry.js");
4124
4555
  const recon = reconcileHintWithRegistryIdentity({
4125
4556
  agentId,
@@ -4257,7 +4688,7 @@ async function startMcpHttpServer() {
4257
4688
  `);
4258
4689
  _boundMcpPort = MCP_HTTP_PORT;
4259
4690
  writeDaemonReady({ pid: process.pid, port: MCP_HTTP_PORT });
4260
- void import("../mcp-port-config-6HYY6J7K.js").then(({ persistMcpPortToConfig }) => persistMcpPortToConfig(String(MCP_HTTP_PORT))).catch(() => {
4691
+ void import("../mcp-port-config-PA3W3BJK.js").then(({ persistMcpPortToConfig }) => persistMcpPortToConfig(String(MCP_HTTP_PORT))).catch(() => {
4261
4692
  });
4262
4693
  recordMcpHttpEvent({
4263
4694
  level: "info",
@@ -4316,9 +4747,9 @@ async function ensureStoreForPolling() {
4316
4747
  await initDatabase({ dbPath: config.dbPath, encryptionKey: masterKey.toString("hex") });
4317
4748
  await ensureSchema();
4318
4749
  try {
4319
- const { isLedgerEnabled } = await import("../notification-ledger-SZEPGJQ7.js");
4750
+ const { isLedgerEnabled } = await import("../notification-ledger-A6MYLQAN.js");
4320
4751
  if (isLedgerEnabled()) {
4321
- const { bumpBootGeneration } = await import("../boot-generation-BL2ISK4U.js");
4752
+ const { bumpBootGeneration } = await import("../boot-generation-CFA5NKSK.js");
4322
4753
  const { setDaemonReadyGeneration } = await import("../daemon-ready-signal-LPAZWQOV.js");
4323
4754
  const generation = await bumpBootGeneration();
4324
4755
  setDaemonReadyGeneration(generation);
@@ -4332,8 +4763,18 @@ async function ensureStoreForPolling() {
4332
4763
  try {
4333
4764
  const { spawnDbReadWorker } = await import("./db-read-worker-client.js");
4334
4765
  spawnDbReadWorker(config.dbPath, masterKey.toString("hex"));
4766
+ const { registerBackupOffload } = await import("./db-backup.js");
4767
+ registerBackupOffload({ dbPath: config.dbPath, encryptionKeyHex: masterKey.toString("hex") });
4335
4768
  } catch (e) {
4336
4769
  process.stderr.write(`[exed] DB read worker spawn failed (non-fatal): ${e instanceof Error ? e.message : String(e)}
4770
+ `);
4771
+ }
4772
+ try {
4773
+ if (isWriteWorkerEnabled()) {
4774
+ spawnDbWriteWorker(config.dbPath, masterKey.toString("hex"));
4775
+ }
4776
+ } catch (e) {
4777
+ process.stderr.write(`[exed] DB write worker spawn failed (non-fatal): ${e instanceof Error ? e.message : String(e)}
4337
4778
  `);
4338
4779
  }
4339
4780
  }
@@ -4348,13 +4789,13 @@ async function ensureStoreForPolling() {
4348
4789
  }
4349
4790
  }
4350
4791
  async function startReviewPolling() {
4351
- const polling = await import("../review-polling-HXAFJZDA.js");
4792
+ const polling = await import("../review-polling-DLPMK3QW.js");
4352
4793
  const state = {
4353
4794
  lastIntercomSent: /* @__PURE__ */ new Map(),
4354
4795
  lastNudgeSent: /* @__PURE__ */ new Map(),
4355
4796
  intervalMs: REVIEW_POLL_INTERVAL_MS
4356
4797
  };
4357
- const { pollReviewNudge, createReviewNudgeRealDeps, loadNudgeState } = await import("../daemon-orchestration-FX4XZDR5.js");
4798
+ const { pollReviewNudge, createReviewNudgeRealDeps, loadNudgeState } = await import("../daemon-orchestration-GGSRCXR3.js");
4358
4799
  const nudgeState = loadNudgeState();
4359
4800
  const tick = async () => traceDaemonTimer("review_polling", async () => {
4360
4801
  fired("review_polling");
@@ -4400,7 +4841,7 @@ function startSessionTTL() {
4400
4841
  if (!await ensureStoreForPolling()) return;
4401
4842
  if (inPostRestartDestructiveGrace("session_ttl")) return;
4402
4843
  const { getClient } = await import("./database.js");
4403
- const { checkSessionTTL, createSessionTTLRealDeps } = await import("../daemon-orchestration-FX4XZDR5.js");
4844
+ const { checkSessionTTL, createSessionTTLRealDeps } = await import("../daemon-orchestration-GGSRCXR3.js");
4404
4845
  const deps = createSessionTTLRealDeps(getClient);
4405
4846
  const killed = await checkSessionTTL(deps, _wedgeObservations);
4406
4847
  if (killed.length > 0) acted("session_ttl");
@@ -4426,7 +4867,7 @@ function startIdleKill() {
4426
4867
  if (inPostRestartDestructiveGrace("idle_kill")) return;
4427
4868
  try {
4428
4869
  const signalDir = path3.join(os2.homedir(), ".exe-os", "task-signals");
4429
- if (existsSync4(signalDir)) {
4870
+ if (existsSync5(signalDir)) {
4430
4871
  const files = (await import("fs")).readdirSync(signalDir).filter((f) => f.endsWith(".terminate"));
4431
4872
  for (const file of files) {
4432
4873
  const agentId = file.replace(".terminate", "");
@@ -4440,9 +4881,9 @@ function startIdleKill() {
4440
4881
  `);
4441
4882
  acted("idle_kill");
4442
4883
  }
4443
- unlinkSync2(signalPath);
4884
+ unlinkSync3(signalPath);
4444
4885
  } catch {
4445
- unlinkSync2(signalPath);
4886
+ unlinkSync3(signalPath);
4446
4887
  }
4447
4888
  }
4448
4889
  }
@@ -4452,7 +4893,7 @@ function startIdleKill() {
4452
4893
  const cfg = await getCachedConfig();
4453
4894
  if (!cfg) return;
4454
4895
  const { getClient } = await import("./database.js");
4455
- const { pollIdleKill, createIdleKillRealDeps } = await import("../daemon-orchestration-FX4XZDR5.js");
4896
+ const { pollIdleKill, createIdleKillRealDeps } = await import("../daemon-orchestration-GGSRCXR3.js");
4456
4897
  const { sessions: liveSessions, paneCache, aliveSessions } = await getSharedOrchestrationCaches();
4457
4898
  const realDeps = createIdleKillRealDeps(
4458
4899
  getClient,
@@ -4525,7 +4966,7 @@ function startConsolidation() {
4525
4966
  `);
4526
4967
  }
4527
4968
  try {
4528
- const { createBackupAsync, enforceRetention } = await import("../db-backup-W2QFSYQC.js");
4969
+ const { createBackupAsync, enforceRetention } = await import("./db-backup.js");
4529
4970
  const p = await createBackupAsync("pre-consolidation");
4530
4971
  if (p) enforceRetention("pre-consolidation");
4531
4972
  } catch (e) {
@@ -4758,7 +5199,7 @@ function startSkillRefinement() {
4758
5199
  if (!shouldRunHeavyJob("skill_refinement")) return;
4759
5200
  try {
4760
5201
  if (!await ensureStoreForPolling()) return;
4761
- const { runSkillRefinement } = await import("../skill-refinement-DVSYXBBP.js");
5202
+ const { runSkillRefinement } = await import("../skill-refinement-ACXLAK2G.js");
4762
5203
  const result = await runSkillRefinement();
4763
5204
  if (result.reviewed > 0) {
4764
5205
  acted("skill_refinement");
@@ -4784,8 +5225,8 @@ function startStaleBranchSweep() {
4784
5225
  const tick = async () => {
4785
5226
  fired("stale_branch_sweep");
4786
5227
  try {
4787
- const { discoverRepoPaths } = await import("../worktree-sweep-WTK3MTKH.js");
4788
- const { scanUnmergedBranchesCached } = await import("../branch-hygiene-TZWK6QCF.js");
5228
+ const { discoverRepoPaths } = await import("../worktree-sweep-VSL7TRQK.js");
5229
+ const { scanUnmergedBranchesCached } = await import("../branch-hygiene-PILXQQDF.js");
4789
5230
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
4790
5231
  for (const k of _staleBranchAlertedToday) {
4791
5232
  if (!k.endsWith(today)) _staleBranchAlertedToday.delete(k);
@@ -4816,7 +5257,7 @@ function startStaleBranchSweep() {
4816
5257
  if (!_storeInitialized) continue;
4817
5258
  const stale = scan.branches.filter((b) => b.ageHours >= STALE_BRANCH_HOURS).slice(0, 5).map((b) => `${b.name} (+${b.ahead} commits, ${(b.ageHours / 24).toFixed(1)}d)`).join("; ");
4818
5259
  try {
4819
- const { writeNotification } = await import("../notifications-4UT53CDG.js");
5260
+ const { writeNotification } = await import("../notifications-6XCSUTJW.js");
4820
5261
  await writeNotification({
4821
5262
  agentId: "exe",
4822
5263
  agentRole: "system",
@@ -5273,14 +5714,14 @@ function startReflectionSweep() {
5273
5714
  );
5274
5715
  let runReflection;
5275
5716
  try {
5276
- ({ runReflection } = await import("../memory-reflection-WVNFBJAA.js"));
5717
+ ({ runReflection } = await import("../memory-reflection-3VPYJS2G.js"));
5277
5718
  } catch (importErr) {
5278
5719
  _reflectionImportFailed = true;
5279
5720
  process.stderr.write(`[exed] Reflection module unavailable (stale chunk hash?) \u2014 disabled until daemon restart: ${importErr instanceof Error ? importErr.message : String(importErr)}
5280
5721
  `);
5281
5722
  return;
5282
5723
  }
5283
- const { runBudgetedSweep } = await import("../sweep-budget-WB2FKPYN.js");
5724
+ const { runBudgetedSweep } = await import("../sweep-budget-LQYBMDTK.js");
5284
5725
  let totalInsights = 0;
5285
5726
  await runBudgetedSweep(
5286
5727
  agents.rows,
@@ -5314,7 +5755,7 @@ function startReflectionSweep() {
5314
5755
  if (memories > 100 && cards < memories * 0.1) {
5315
5756
  process.stderr.write(`[exed] Memory cards sparse (${cards} cards / ${memories} memories) \u2014 running backfill...
5316
5757
  `);
5317
- const { insertMemoryCardsForBatch } = await import("../memory-cards-ZRDW7QBX.js");
5758
+ const { insertMemoryCardsForBatch } = await import("../memory-cards-47NYPFC3.js");
5318
5759
  const batchSize = 500;
5319
5760
  let offset = 0;
5320
5761
  let totalCards = 0;
@@ -5359,7 +5800,7 @@ function startDatabaseBackup() {
5359
5800
  const tick = async () => {
5360
5801
  fired("db_backup");
5361
5802
  try {
5362
- const { createBackupAsync, enforceRetention, hasBackupToday, hasRecentBackup } = await import("../db-backup-W2QFSYQC.js");
5803
+ const { createBackupAsync, enforceRetention, hasBackupToday, hasRecentBackup } = await import("./db-backup.js");
5363
5804
  if (!hasRecentBackup("guaranteed", DB_BACKUP_TARGET_WINDOW_MS)) {
5364
5805
  const guaranteedPath = await createBackupAsync("guaranteed");
5365
5806
  if (guaranteedPath) {
@@ -5382,7 +5823,7 @@ function startDatabaseBackup() {
5382
5823
  `
5383
5824
  );
5384
5825
  try {
5385
- const { maybeVerifyDailyBackup } = await import("../backup-verify-3Y2FHGZU.js");
5826
+ const { maybeVerifyDailyBackup } = await import("../backup-verify-KDLOT4RP.js");
5386
5827
  const verdict = await maybeVerifyDailyBackup(backupPath);
5387
5828
  if (verdict && !verdict.ok) {
5388
5829
  process.stderr.write(
@@ -5459,7 +5900,7 @@ function startSessionEventsRetention() {
5459
5900
  if (!await ensureStoreForPolling()) return;
5460
5901
  try {
5461
5902
  const { getClient } = await import("./database.js");
5462
- const { sweepExpiredSessionEvents, DEFAULT_SESSION_EVENTS_RETENTION_DAYS } = await import("../session-events-O3BV56ZX.js");
5903
+ const { sweepExpiredSessionEvents, DEFAULT_SESSION_EVENTS_RETENTION_DAYS } = await import("../session-events-N5VRC6IT.js");
5463
5904
  const days = SESSION_EVENTS_RETENTION_DAYS ?? DEFAULT_SESSION_EVENTS_RETENTION_DAYS;
5464
5905
  const count = await sweepExpiredSessionEvents(getClient(), days);
5465
5906
  if (count > 0) {
@@ -5490,7 +5931,7 @@ function startIntercomQueueDrain() {
5490
5931
  const tick = async () => traceDaemonTimer("intercom_queue_drain", async () => {
5491
5932
  fired("intercom_queue_drain");
5492
5933
  try {
5493
- const { drainQueueAsync, readQueue } = await import("../intercom-queue-ZFEQALR3.js");
5934
+ const { drainQueueAsync, readQueue } = await import("../intercom-queue-NFOLOBTT.js");
5494
5935
  const {
5495
5936
  sendIntercomAsync: centralSendIntercomAsync,
5496
5937
  countScopedPendingReviews,
@@ -5622,7 +6063,7 @@ function startLedgerDrain() {
5622
6063
  const tick = async () => traceDaemonTimer("ledger_drain", async () => {
5623
6064
  fired("ledger_drain");
5624
6065
  try {
5625
- const { isLedgerEnabled, drainLedger } = await import("../notification-ledger-SZEPGJQ7.js");
6066
+ const { isLedgerEnabled, drainLedger } = await import("../notification-ledger-A6MYLQAN.js");
5626
6067
  if (!isLedgerEnabled()) return;
5627
6068
  const result = await drainLedger({
5628
6069
  // Shadow "would-deliver": idle target = would-deliver, busy = retry.
@@ -5661,7 +6102,7 @@ function startOrphanReaper() {
5661
6102
  const tick = async () => traceDaemonTimer("orphan_reaper", async () => {
5662
6103
  fired("orphan_reaper");
5663
6104
  try {
5664
- const { reapOrphanedMcpProcesses, createOrphanReaperRealDepsAsync } = await import("../daemon-orchestration-FX4XZDR5.js");
6105
+ const { reapOrphanedMcpProcesses, createOrphanReaperRealDepsAsync } = await import("../daemon-orchestration-GGSRCXR3.js");
5665
6106
  const deps = await createOrphanReaperRealDepsAsync();
5666
6107
  const reaped = await reapOrphanedMcpProcesses(deps);
5667
6108
  if (reaped.length > 0) acted("orphan_reaper");
@@ -5686,7 +6127,7 @@ function startZombieAgentReaper() {
5686
6127
  const tick = async () => traceDaemonTimer("zombie_agent_reaper", async () => {
5687
6128
  fired("zombie_agent_reaper");
5688
6129
  try {
5689
- const { reapZombieAgentProcesses, createZombieAgentReaperRealDepsAsync } = await import("../daemon-orchestration-FX4XZDR5.js");
6130
+ const { reapZombieAgentProcesses, createZombieAgentReaperRealDepsAsync } = await import("../daemon-orchestration-GGSRCXR3.js");
5690
6131
  const deps = await createZombieAgentReaperRealDepsAsync();
5691
6132
  const reaped = reapZombieAgentProcesses(deps);
5692
6133
  if (reaped.length > 0) acted("zombie_agent_reaper");
@@ -5710,7 +6151,7 @@ async function startDaemonMemoryPressureWatchdog() {
5710
6151
  try {
5711
6152
  const cfg = await getCachedConfig();
5712
6153
  if (!cfg) return;
5713
- const { startMemoryPressureWatchdog: startWatchdog, MEMORY_PRESSURE_WATCHDOG_DEFAULTS } = await import("../memory-pressure-watchdog-HN5X7AVN.js");
6154
+ const { startMemoryPressureWatchdog: startWatchdog, MEMORY_PRESSURE_WATCHDOG_DEFAULTS } = await import("../memory-pressure-watchdog-PSVJ5BCF.js");
5714
6155
  const watchdogCfg = {
5715
6156
  ...MEMORY_PRESSURE_WATCHDOG_DEFAULTS,
5716
6157
  ...cfg.memoryPressureWatchdog ?? {}
@@ -5741,7 +6182,7 @@ function startWorktreeReaper() {
5741
6182
  const tick = async () => traceDaemonTimer("worktree_reaper", async () => {
5742
6183
  fired("worktree_reaper");
5743
6184
  try {
5744
- const { reapOrphanedWorktrees, createWorktreeReaperRealDeps } = await import("../daemon-orchestration-FX4XZDR5.js");
6185
+ const { reapOrphanedWorktrees, createWorktreeReaperRealDeps } = await import("../daemon-orchestration-GGSRCXR3.js");
5745
6186
  const deps = await createWorktreeReaperRealDeps();
5746
6187
  const result = await reapOrphanedWorktrees(deps);
5747
6188
  if (result.pruned.length > 0) {
@@ -5781,8 +6222,8 @@ function startWorktreeReaper() {
5781
6222
  }
5782
6223
  continue;
5783
6224
  }
5784
- const { cleanupAgentWorktree } = await import("../worktree-sweep-WTK3MTKH.js");
5785
- const { getMainRepoRootAsync } = await import("../worktree-LL62PLQB.js");
6225
+ const { cleanupAgentWorktree } = await import("../worktree-sweep-VSL7TRQK.js");
6226
+ const { getMainRepoRootAsync } = await import("../worktree-VDCY44ZP.js");
5786
6227
  const repoRoot = await getMainRepoRootAsync(signal.worktreePath);
5787
6228
  if (repoRoot && signal.agentId) {
5788
6229
  const notes = await cleanupAgentWorktree(repoRoot, signal.agentId);
@@ -5815,7 +6256,7 @@ function startAutoWake() {
5815
6256
  if (!await ensureStoreForPolling()) return;
5816
6257
  try {
5817
6258
  const { getClient } = await import("./database.js");
5818
- const { pollOrphanedTasks, createAutoWakeRealDeps } = await import("../daemon-orchestration-FX4XZDR5.js");
6259
+ const { pollOrphanedTasks, createAutoWakeRealDeps } = await import("../daemon-orchestration-GGSRCXR3.js");
5819
6260
  const deps = createAutoWakeRealDeps(getClient, process.cwd(), getTmuxSessionsAsync);
5820
6261
  const woken = await pollOrphanedTasks(deps);
5821
6262
  if (woken.length > 0) acted("auto_wake");
@@ -5825,7 +6266,7 @@ function startAutoWake() {
5825
6266
  }
5826
6267
  try {
5827
6268
  const signalBase = path3.join(os2.homedir(), ".exe-os", "task-signals");
5828
- if (existsSync4(signalBase)) {
6269
+ if (existsSync5(signalBase)) {
5829
6270
  const { readdirSync: readdirSync2, statSync: statSyncFs } = await import("fs");
5830
6271
  const { sendIntercomAsync, extractRootExe } = await import("./tmux-routing.js");
5831
6272
  const sessionCache = path3.join(os2.homedir(), ".exe-os", "session-cache");
@@ -5841,11 +6282,11 @@ function startAutoWake() {
5841
6282
  if (cached && Date.now() - cached.ts < 3e4) return cached.runtime;
5842
6283
  try {
5843
6284
  const dispatchInfoPath = path3.join(sessionCache, `dispatch-info-${sessionName}.json`);
5844
- if (!existsSync4(dispatchInfoPath)) {
6285
+ if (!existsSync5(dispatchInfoPath)) {
5845
6286
  _runtimeCache.set(sessionName, { runtime: "claude", ts: Date.now() });
5846
6287
  return "claude";
5847
6288
  }
5848
- const raw = JSON.parse(readFileSync4(dispatchInfoPath, "utf8"));
6289
+ const raw = JSON.parse(readFileSync5(dispatchInfoPath, "utf8"));
5849
6290
  const rt = raw.runtime ?? "claude";
5850
6291
  _runtimeCache.set(sessionName, { runtime: rt, ts: Date.now() });
5851
6292
  return rt;
@@ -5865,8 +6306,8 @@ function startAutoWake() {
5865
6306
  const age = Date.now() - statSyncFs(signalPath).mtimeMs;
5866
6307
  if (age > 60 * 60 * 1e3) {
5867
6308
  try {
5868
- unlinkSync2(signalPath);
5869
- void import("../orchestration-events-WV4NWKZH.js").then(({ recordOrchestrationEventBestEffort: recordOE }) => {
6309
+ unlinkSync3(signalPath);
6310
+ void import("../orchestration-events-5XDNVNR2.js").then(({ recordOrchestrationEventBestEffort: recordOE }) => {
5870
6311
  recordOE({ eventType: "signal.stale", source: "exe-daemon.autoWake", severity: "warn", payload: { file, ageMinutes: Math.round(age / 6e4) } });
5871
6312
  }).catch(() => {
5872
6313
  });
@@ -5934,7 +6375,7 @@ function startWalCheckpoint() {
5934
6375
  try {
5935
6376
  const { getClient, runWalCheckpoint } = await import("./database.js");
5936
6377
  const client = getClient();
5937
- const { findActiveDb } = await import("../db-backup-W2QFSYQC.js");
6378
+ const { findActiveDb } = await import("./db-backup.js");
5938
6379
  const dbPath = findActiveDb();
5939
6380
  const started = Date.now();
5940
6381
  const result = await runWalCheckpoint(client, dbPath, true);
@@ -6012,7 +6453,7 @@ function startStuckTaskRelease() {
6012
6453
  createStuckTaskRealDeps,
6013
6454
  escalateStuckBlockedTasks,
6014
6455
  createStuckBlockedRealDeps
6015
- } = await import("../daemon-orchestration-FX4XZDR5.js");
6456
+ } = await import("../daemon-orchestration-GGSRCXR3.js");
6016
6457
  const deps = createStuckTaskRealDeps(getClient);
6017
6458
  const released = await releaseStuckTasks(deps);
6018
6459
  if (released.length > 0) {
@@ -6207,12 +6648,12 @@ function startTaskEnforcementScanner() {
6207
6648
  const tick = async () => traceDaemonTimer("task_enforcement", async () => {
6208
6649
  fired("task_enforcement");
6209
6650
  try {
6210
- const { runTaskEnforcementTick } = await import("../task-enforcement-IPIZX2MM.js");
6651
+ const { runTaskEnforcementTick } = await import("../task-enforcement-C7MMJTKX.js");
6211
6652
  const { getTransport } = await import("./transport.js");
6212
6653
  const { loadAgentConfig } = await import("./agent-config.js");
6213
6654
  const { getClient } = await import("./database.js");
6214
6655
  const { loadEmployeesSync } = await import("./employees.js");
6215
- const { sessionScopeFilter } = await import("../task-scope-FOIW25HR.js");
6656
+ const { sessionScopeFilter } = await import("../task-scope-DK666AKV.js");
6216
6657
  const transport = getTransport();
6217
6658
  const { sessions: allSessions, paneCache, aliveSessions } = await getSharedOrchestrationCaches();
6218
6659
  await yieldToEventLoop();
@@ -6223,10 +6664,10 @@ function startTaskEnforcementScanner() {
6223
6664
  sendKeysLiteral: transport.sendKeysLiteral?.bind(transport),
6224
6665
  isAlive: (session) => aliveSessions.has(session)
6225
6666
  };
6226
- const { checkAutoWakeGates } = await import("../daemon-orchestration-FX4XZDR5.js");
6667
+ const { checkAutoWakeGates } = await import("../daemon-orchestration-GGSRCXR3.js");
6227
6668
  const { ensureEmployeeAsync, employeeSessionName, sendIntercomAsync } = await import("./tmux-routing.js");
6228
6669
  const { shouldAutoInstance } = await import("./employees.js");
6229
- const { recordOrchestrationEventBestEffort } = await import("../orchestration-events-WV4NWKZH.js");
6670
+ const { recordOrchestrationEventBestEffort } = await import("../orchestration-events-5XDNVNR2.js");
6230
6671
  const projectDir = process.cwd();
6231
6672
  await runTaskEnforcementTick({
6232
6673
  transport: enforcementTransport,
@@ -6360,8 +6801,8 @@ function startRssWatchdog() {
6360
6801
  `
6361
6802
  );
6362
6803
  try {
6363
- mkdirSync2(path3.dirname(OOM_MARKER_PATH), { recursive: true });
6364
- writeFileSync3(OOM_MARKER_PATH, `RSS=${(effectiveRss / 1024 / 1024).toFixed(0)}MB at ${(/* @__PURE__ */ new Date()).toISOString()}
6804
+ mkdirSync3(path3.dirname(OOM_MARKER_PATH), { recursive: true });
6805
+ writeFileSync4(OOM_MARKER_PATH, `RSS=${(effectiveRss / 1024 / 1024).toFixed(0)}MB at ${(/* @__PURE__ */ new Date()).toISOString()}
6365
6806
  `);
6366
6807
  process.stderr.write(`[exed] Wrote OOM marker at ${OOM_MARKER_PATH}
6367
6808
  `);
@@ -6475,14 +6916,14 @@ function startApiWatchdog() {
6475
6916
  process.stderr.write(`[exed] API watchdog nudged ${session} (attempt ${nudgeCount}/3, matched: ${matchedPattern.source})
6476
6917
  `);
6477
6918
  try {
6478
- const { appendFileSync, mkdirSync: mkdirSync3, statSync: statSyncFs, renameSync: renameSyncFs } = await import("fs");
6479
- const { join: join2 } = await import("path");
6480
- const logDir = join2(process.env.EXE_OS_DIR ?? join2(process.env.HOME ?? "", ".exe-os"), "logs");
6919
+ const { appendFileSync, mkdirSync: mkdirSync4, statSync: statSyncFs, renameSync: renameSyncFs } = await import("fs");
6920
+ const { join: join3 } = await import("path");
6921
+ const logDir = join3(process.env.EXE_OS_DIR ?? join3(process.env.HOME ?? "", ".exe-os"), "logs");
6481
6922
  try {
6482
- mkdirSync3(logDir, { recursive: true });
6923
+ mkdirSync4(logDir, { recursive: true });
6483
6924
  } catch {
6484
6925
  }
6485
- const watchdogLogPath = join2(logDir, "api-watchdog.jsonl");
6926
+ const watchdogLogPath = join3(logDir, "api-watchdog.jsonl");
6486
6927
  try {
6487
6928
  const wStat = statSyncFs(watchdogLogPath);
6488
6929
  if (wStat.size > 5 * 1024 * 1024) renameSyncFs(watchdogLogPath, watchdogLogPath + ".1");
@@ -6518,7 +6959,7 @@ function startBackgroundJobGuardrails() {
6518
6959
  const tick = async () => traceDaemonTimer("background_job_guardrails", async () => {
6519
6960
  fired("background_job_guardrails");
6520
6961
  try {
6521
- const { enforceBackgroundJobGuardrailsAsync } = await import("../background-jobs-EXR5RVGG.js");
6962
+ const { enforceBackgroundJobGuardrailsAsync } = await import("../background-jobs-KKRO3QRO.js");
6522
6963
  const actions = await enforceBackgroundJobGuardrailsAsync();
6523
6964
  if (actions.length > 0) {
6524
6965
  acted("background_job_guardrails");
@@ -6709,18 +7150,18 @@ process.on("uncaughtException", (err) => {
6709
7150
  } catch {
6710
7151
  }
6711
7152
  try {
6712
- unlinkSync2(SOCKET_PATH);
7153
+ unlinkSync3(SOCKET_PATH);
6713
7154
  } catch (_) {
6714
7155
  }
6715
7156
  try {
6716
- unlinkSync2(PID_PATH);
7157
+ unlinkSync3(PID_PATH);
6717
7158
  } catch (_) {
6718
7159
  }
6719
7160
  setTimeout(() => process.exit(1), 3e3);
6720
7161
  });
6721
7162
  function readProcEnviron(pid) {
6722
7163
  try {
6723
- const raw = readFileSync4(`/proc/${pid}/environ`, "utf8");
7164
+ const raw = readFileSync5(`/proc/${pid}/environ`, "utf8");
6724
7165
  const env = {};
6725
7166
  for (const part of raw.split("\0")) {
6726
7167
  const idx = part.indexOf("=");
@@ -6773,18 +7214,18 @@ function killOrphanDaemons() {
6773
7214
  }
6774
7215
  function checkExistingDaemon() {
6775
7216
  try {
6776
- if (!existsSync4(PID_PATH)) {
7217
+ if (!existsSync5(PID_PATH)) {
6777
7218
  killOrphanDaemons();
6778
7219
  return false;
6779
7220
  }
6780
- const pid = parseInt(readFileSync4(PID_PATH, "utf8").trim(), 10);
7221
+ const pid = parseInt(readFileSync5(PID_PATH, "utf8").trim(), 10);
6781
7222
  if (!pid || isNaN(pid)) {
6782
7223
  killOrphanDaemons();
6783
7224
  return false;
6784
7225
  }
6785
7226
  if (pid === process.pid) {
6786
7227
  try {
6787
- unlinkSync2(PID_PATH);
7228
+ unlinkSync3(PID_PATH);
6788
7229
  } catch {
6789
7230
  }
6790
7231
  return false;
@@ -6795,11 +7236,11 @@ function checkExistingDaemon() {
6795
7236
  process.stderr.write(`[exed] PID ${pid} is a zombie \u2014 cleaning up and proceeding.
6796
7237
  `);
6797
7238
  try {
6798
- unlinkSync2(PID_PATH);
7239
+ unlinkSync3(PID_PATH);
6799
7240
  } catch {
6800
7241
  }
6801
7242
  try {
6802
- unlinkSync2(SOCKET_PATH);
7243
+ unlinkSync3(SOCKET_PATH);
6803
7244
  } catch {
6804
7245
  }
6805
7246
  killOrphanDaemons();
@@ -6809,11 +7250,11 @@ function checkExistingDaemon() {
6809
7250
  process.stderr.write(`[exed] PID ${pid} no longer exists \u2014 cleaning stale PID file.
6810
7251
  `);
6811
7252
  try {
6812
- unlinkSync2(PID_PATH);
7253
+ unlinkSync3(PID_PATH);
6813
7254
  } catch {
6814
7255
  }
6815
7256
  try {
6816
- unlinkSync2(SOCKET_PATH);
7257
+ unlinkSync3(SOCKET_PATH);
6817
7258
  } catch {
6818
7259
  }
6819
7260
  killOrphanDaemons();
@@ -6835,7 +7276,7 @@ function checkExistingDaemon() {
6835
7276
  return true;
6836
7277
  }
6837
7278
  try {
6838
- unlinkSync2(PID_PATH);
7279
+ unlinkSync3(PID_PATH);
6839
7280
  } catch {
6840
7281
  }
6841
7282
  killOrphanDaemons();
@@ -6908,21 +7349,21 @@ function startAutoUpdateCheck() {
6908
7349
  if (checkExistingDaemon()) {
6909
7350
  process.exit(0);
6910
7351
  }
6911
- writeFileSync3(PID_PATH, String(process.pid));
7352
+ writeFileSync4(PID_PATH, String(process.pid));
6912
7353
  try {
6913
7354
  chmodSync(PID_PATH, 384);
6914
7355
  } catch {
6915
7356
  }
6916
7357
  markAsDaemonProcess();
6917
7358
  var DAEMON_BOOT_PATH = path3.join(EXE_AI_DIR, "daemon-boot-ts");
6918
- writeFileSync3(DAEMON_BOOT_PATH, (/* @__PURE__ */ new Date()).toISOString());
7359
+ writeFileSync4(DAEMON_BOOT_PATH, (/* @__PURE__ */ new Date()).toISOString());
6919
7360
  try {
6920
7361
  chmodSync(DAEMON_BOOT_PATH, 420);
6921
7362
  } catch {
6922
7363
  }
6923
7364
  await new Promise((r) => setTimeout(r, 500));
6924
7365
  try {
6925
- const claimedPid = parseInt(readFileSync4(PID_PATH, "utf8").trim(), 10);
7366
+ const claimedPid = parseInt(readFileSync5(PID_PATH, "utf8").trim(), 10);
6926
7367
  if (claimedPid !== process.pid) {
6927
7368
  process.stderr.write(
6928
7369
  `[exed] Race detected \u2014 PID ${claimedPid} claimed the lock. Exiting cleanly.
@@ -6941,12 +7382,12 @@ process.env.EXE_IS_DAEMON = "1";
6941
7382
  if (process.platform === "darwin") {
6942
7383
  try {
6943
7384
  const oldPlist = path3.join(os2.homedir(), "Library", "LaunchAgents", "com.askexe.exed-keepalive.plist");
6944
- if (existsSync4(oldPlist)) {
7385
+ if (existsSync5(oldPlist)) {
6945
7386
  try {
6946
7387
  execSyncNode(`launchctl unload "${oldPlist}" 2>/dev/null`, { timeout: 5e3 });
6947
7388
  } catch {
6948
7389
  }
6949
- unlinkSync2(oldPlist);
7390
+ unlinkSync3(oldPlist);
6950
7391
  process.stderr.write("[exed] Removed old keepalive plist (replaced by launchd KeepAlive).\n");
6951
7392
  }
6952
7393
  } catch {
@@ -6955,7 +7396,7 @@ if (process.platform === "darwin") {
6955
7396
  logBoot({ socketPath: SOCKET_PATH, pidPath: PID_PATH });
6956
7397
  void (async () => {
6957
7398
  try {
6958
- const { cleanupCrashDebris } = await import("../db-backup-W2QFSYQC.js");
7399
+ const { cleanupCrashDebris } = await import("./db-backup.js");
6959
7400
  const removed = cleanupCrashDebris();
6960
7401
  if (removed > 0) {
6961
7402
  process.stderr.write(`[exed] Startup cleanup: pruned ${removed} crash-debris file(s) (backups/quarantine).
@@ -7104,11 +7545,16 @@ function startEventLoopLagDetector() {
7104
7545
  const { singleMs: SELF_HEAL_SINGLE_MS, consecutive: SELF_HEAL_CONSECUTIVE, thresholdMs: SELF_HEAL_THRESHOLD_MS } = resolveSelfHealThresholds();
7105
7546
  let consecutiveSevereBlocks = 0;
7106
7547
  let selfInflictedWindow = [];
7548
+ const LOAD_SAMPLE_KEEP_MS = Math.max(12e4, SELF_HEAL_SINGLE_MS + 6e4);
7549
+ let loadSamples = [];
7107
7550
  touchEventLoopHeartbeat();
7108
7551
  const lagTimer = setInterval(() => {
7109
7552
  touchEventLoopHeartbeat();
7110
7553
  const wallElapsedMs = monotonicElapsedMs(lastTick);
7111
7554
  const lag = wallElapsedMs - 2e3;
7555
+ const sampledLoad1m = os2.loadavg()[0] ?? 0;
7556
+ const loadWindow = updateLoadWindow(loadSamples, Date.now(), sampledLoad1m, wallElapsedMs, LOAD_SAMPLE_KEEP_MS);
7557
+ loadSamples = loadWindow.samples;
7112
7558
  const cpuDelta = process.cpuUsage(lastCpu);
7113
7559
  lastCpu = process.cpuUsage();
7114
7560
  const selfCpuBusyFraction = wallElapsedMs > 0 ? (cpuDelta.user + cpuDelta.system) / 1e3 / wallElapsedMs : 0;
@@ -7119,7 +7565,7 @@ function startEventLoopLagDetector() {
7119
7565
  if (clockJump) {
7120
7566
  consecutiveSevereBlocks = 0;
7121
7567
  try {
7122
- unlinkSync2(path3.join(os2.homedir(), ".exe-os", "session-cache", "event-loop-blocked.marker"));
7568
+ unlinkSync3(path3.join(os2.homedir(), ".exe-os", "session-cache", "event-loop-blocked.marker"));
7123
7569
  } catch {
7124
7570
  }
7125
7571
  process.stderr.write("[exed] Event loop lag detector: wall-clock jump/sleep detected; reset without self-heal.\n");
@@ -7129,12 +7575,12 @@ function startEventLoopLagDetector() {
7129
7575
  const msg = `[exed] EVENT LOOP BLOCKED ${(lag / 1e3).toFixed(1)}s \u2014 MCP UNRESPONSIVE. Sessions will die.`;
7130
7576
  process.stderr.write(msg + "\n");
7131
7577
  logDaemonHealth({ event: "event_loop_blocked", pid: process.pid, message: msg, data: { lagMs: lag } });
7132
- void import("../orchestration-events-WV4NWKZH.js").then(({ recordOrchestrationEventBestEffort: recordOE }) => {
7578
+ void import("../orchestration-events-5XDNVNR2.js").then(({ recordOrchestrationEventBestEffort: recordOE }) => {
7133
7579
  recordOE({ eventType: "daemon.event_loop_blocked", source: "exe-daemon.lagDetector", severity: "error", durationMs: lag });
7134
7580
  }).catch(() => {
7135
7581
  });
7136
7582
  try {
7137
- writeFileSync3(path3.join(os2.homedir(), ".exe-os", "session-cache", "event-loop-blocked.marker"), `lag=${lag}ms at ${(/* @__PURE__ */ new Date()).toISOString()}
7583
+ writeFileSync4(path3.join(os2.homedir(), ".exe-os", "session-cache", "event-loop-blocked.marker"), `lag=${lag}ms at ${(/* @__PURE__ */ new Date()).toISOString()}
7138
7584
  `);
7139
7585
  } catch {
7140
7586
  }
@@ -7150,13 +7596,15 @@ function startEventLoopLagDetector() {
7150
7596
  });
7151
7597
  } catch {
7152
7598
  }
7153
- const load1m = os2.loadavg()[0] ?? 0;
7599
+ const load1m = sampledLoad1m;
7600
+ const maxLoad1mOverWindow = loadWindow.maxLoad1mOverWindow;
7154
7601
  const cpuCount = os2.cpus().length || 1;
7155
7602
  const starvationRatio = resolveSelfHealThresholds().starvationRatio;
7156
7603
  const catchUpActive = inBootCatchUpGrace();
7157
7604
  const decision = decideDaemonSelfHeal({
7158
7605
  lagMs: lag,
7159
7606
  load1m,
7607
+ maxLoad1mOverWindow,
7160
7608
  cpuCount,
7161
7609
  starvationRatio,
7162
7610
  singleBlockMs: SELF_HEAL_SINGLE_MS,
@@ -7180,14 +7628,14 @@ function startEventLoopLagDetector() {
7180
7628
  selfInflictedWindow = decision.selfInflictedWindowAfter;
7181
7629
  if (decision.reason === "starved_backoff") {
7182
7630
  process.stderr.write(
7183
- `[exed] SELF-HEAL SUPPRESSED: load=${load1m.toFixed(2)} cpus=${cpuCount} \u2014 lag is CPU starvation, not internal hang. Skipping restart.
7631
+ `[exed] SELF-HEAL SUPPRESSED: load=${load1m.toFixed(2)} maxOverWindow=${maxLoad1mOverWindow.toFixed(2)} cpus=${cpuCount} \u2014 lag is CPU starvation, not internal hang. Skipping restart.
7184
7632
  `
7185
7633
  );
7186
7634
  logDaemonHealth({
7187
7635
  event: "self_heal_suppressed_starvation",
7188
7636
  pid: process.pid,
7189
- message: `CPU starved (load=${load1m.toFixed(2)} / cpus=${cpuCount}) \u2014 restart skipped`,
7190
- data: { lagMs: lag, load1m, cpuCount }
7637
+ message: `CPU starved (load=${load1m.toFixed(2)} maxOverWindow=${maxLoad1mOverWindow.toFixed(2)} / cpus=${cpuCount}) \u2014 restart skipped`,
7638
+ data: { lagMs: lag, load1m, maxLoad1mOverWindow, cpuCount }
7191
7639
  });
7192
7640
  return;
7193
7641
  }
@@ -7274,9 +7722,11 @@ function startTaskFileResync() {
7274
7722
  if (!await ensureStoreForPolling()) return;
7275
7723
  const { readdir, readFile } = await import("fs/promises");
7276
7724
  const { getClient } = await import("./database.js");
7725
+ const { runBudgetedSweep } = await import("../sweep-budget-LQYBMDTK.js");
7277
7726
  const client = getClient();
7278
7727
  const tasksRoot = path3.join(os2.homedir(), ".exe-os", "tasks");
7279
7728
  let synced = 0;
7729
+ const paths = [];
7280
7730
  let fileCount = 0;
7281
7731
  const walkAsync = async (dir) => {
7282
7732
  let entries;
@@ -7292,47 +7742,50 @@ function startTaskFileResync() {
7292
7742
  continue;
7293
7743
  }
7294
7744
  if (!e.name.endsWith(".md")) continue;
7295
- try {
7296
- const content = await readFile(full, "utf8");
7297
- const id = content.match(/\*\*ID:\*\*\s*([a-f0-9-]+)/)?.[1];
7298
- const title = content.split("\n")[0]?.replace(/^# /, "") || "";
7299
- const assignedTo = content.match(/\*\*Assigned to:\*\*\s*(\w+)/)?.[1];
7300
- const assignedBy = content.match(/\*\*Assigned by:\*\*\s*(\w+)/)?.[1] || "exe";
7301
- const project = content.match(/\*\*Project:\*\*\s*([\w-]+)/)?.[1] || "exe-os";
7302
- const status = content.match(/\*\*Status:\*\*\s*(\w+)/)?.[1] || "open";
7303
- const priority = content.match(/\*\*Priority:\*\*\s*(\w+)/)?.[1] || "p1";
7304
- const scope = full.match(/tasks\/([^/]+)\//)?.[1] || null;
7305
- if (id && assignedTo) {
7306
- try {
7307
- const res = await client.execute({
7308
- sql: `INSERT OR IGNORE INTO tasks (id, title, assigned_to, assigned_by, project_name, status, priority, task_file, session_scope, created_at, updated_at)
7745
+ paths.push(full);
7746
+ if (++fileCount % 10 === 0) await yieldToEventLoop();
7747
+ }
7748
+ };
7749
+ await walkAsync(tasksRoot);
7750
+ await runBudgetedSweep(paths, async (full) => {
7751
+ try {
7752
+ const content = await readFile(full, "utf8");
7753
+ const id = content.match(/\*\*ID:\*\*\s*([a-f0-9-]+)/)?.[1];
7754
+ const title = content.split("\n")[0]?.replace(/^# /, "") || "";
7755
+ const assignedTo = content.match(/\*\*Assigned to:\*\*\s*(\w+)/)?.[1];
7756
+ const assignedBy = content.match(/\*\*Assigned by:\*\*\s*(\w+)/)?.[1] || "exe";
7757
+ const project = content.match(/\*\*Project:\*\*\s*([\w-]+)/)?.[1] || "exe-os";
7758
+ const status = content.match(/\*\*Status:\*\*\s*(\w+)/)?.[1] || "open";
7759
+ const priority = content.match(/\*\*Priority:\*\*\s*(\w+)/)?.[1] || "p1";
7760
+ const scope = full.match(/tasks\/([^/]+)\//)?.[1] || null;
7761
+ if (id && assignedTo) {
7762
+ try {
7763
+ const res = await client.execute({
7764
+ sql: `INSERT OR IGNORE INTO tasks (id, title, assigned_to, assigned_by, project_name, status, priority, task_file, session_scope, created_at, updated_at)
7309
7765
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
7310
- args: [id, title, assignedTo, assignedBy, project, status, priority, full, scope, (/* @__PURE__ */ new Date()).toISOString(), (/* @__PURE__ */ new Date()).toISOString()]
7311
- });
7312
- if (Number(res.rowsAffected ?? 0) > 0) {
7313
- synced++;
7314
- void import("../orchestration-events-WV4NWKZH.js").then(({ recordOrchestrationEventBestEffort: recordOE }) => {
7315
- recordOE({
7316
- eventType: "task_file.resynced",
7317
- source: "exe-daemon.taskFileResync",
7318
- taskId: id,
7319
- agentId: assignedTo,
7320
- sessionScope: scope,
7321
- projectName: project,
7322
- payload: { status, priority }
7323
- });
7324
- }).catch(() => {
7766
+ args: [id, title, assignedTo, assignedBy, project, status, priority, full, scope, (/* @__PURE__ */ new Date()).toISOString(), (/* @__PURE__ */ new Date()).toISOString()]
7767
+ });
7768
+ if (Number(res.rowsAffected ?? 0) > 0) {
7769
+ synced++;
7770
+ void import("../orchestration-events-5XDNVNR2.js").then(({ recordOrchestrationEventBestEffort: recordOE }) => {
7771
+ recordOE({
7772
+ eventType: "task_file.resynced",
7773
+ source: "exe-daemon.taskFileResync",
7774
+ taskId: id,
7775
+ agentId: assignedTo,
7776
+ sessionScope: scope,
7777
+ projectName: project,
7778
+ payload: { status, priority }
7325
7779
  });
7326
- }
7327
- } catch {
7780
+ }).catch(() => {
7781
+ });
7328
7782
  }
7783
+ } catch {
7329
7784
  }
7330
- } catch {
7331
7785
  }
7332
- if (++fileCount % 10 === 0) await yieldToEventLoop();
7786
+ } catch {
7333
7787
  }
7334
- };
7335
- await walkAsync(tasksRoot);
7788
+ }, { label: "task_file_resync" });
7336
7789
  if (synced > 0) process.stderr.write(`[exed] Task re-sync: ${synced} missing DB rows restored from disk.
7337
7790
  `);
7338
7791
  } catch (e) {
@@ -7348,7 +7801,7 @@ function startTaskGroupBarriers() {
7348
7801
  fired("task_group_barriers");
7349
7802
  if (!await ensureStoreForPolling()) return;
7350
7803
  try {
7351
- const { pollTaskGroupBarriers } = await import("../daemon-orchestration-FX4XZDR5.js");
7804
+ const { pollTaskGroupBarriers } = await import("../daemon-orchestration-GGSRCXR3.js");
7352
7805
  const firedCount = await pollTaskGroupBarriers();
7353
7806
  if (firedCount > 0) {
7354
7807
  acted("task_group_barriers");
@@ -7370,7 +7823,7 @@ function startCheckpointGc() {
7370
7823
  fired("checkpoint_gc");
7371
7824
  if (!await ensureStoreForPolling()) return;
7372
7825
  try {
7373
- const { gcStaleCheckpoints } = await import("../daemon-orchestration-FX4XZDR5.js");
7826
+ const { gcStaleCheckpoints } = await import("../daemon-orchestration-GGSRCXR3.js");
7374
7827
  const cleared = await gcStaleCheckpoints();
7375
7828
  if (cleared > 0) {
7376
7829
  acted("checkpoint_gc");
@@ -7410,14 +7863,14 @@ function startDispatchAckCleanup() {
7410
7863
  function startProjectionWorkerDeferred() {
7411
7864
  setTimeout(async () => {
7412
7865
  try {
7413
- const { startProjectionWorker } = await import("../projection-worker-FZ7YSN3G.js");
7866
+ const { startProjectionWorker } = await import("../projection-worker-CKC2E22U.js");
7414
7867
  startProjectionWorker();
7415
7868
  } catch {
7416
7869
  }
7417
7870
  }, 2e4);
7418
7871
  }
7419
7872
  async function startToolTelemetry() {
7420
- const { startToolTelemetryFlush } = await import("../tool-telemetry-KBXSBDTK.js");
7873
+ const { startToolTelemetryFlush } = await import("../tool-telemetry-4MF2HIWR.js");
7421
7874
  startToolTelemetryFlush();
7422
7875
  process.stderr.write("[exed] Tool telemetry started (flush every 5m)\n");
7423
7876
  }
@@ -7553,8 +8006,8 @@ function startLocalFirstTimers() {
7553
8006
  }
7554
8007
  _intercomDedupCompleted = true;
7555
8008
  try {
7556
- const { writeFileSync: writeFileSync4 } = await import("fs");
7557
- writeFileSync4(markerPath, (/* @__PURE__ */ new Date()).toISOString(), "utf8");
8009
+ const { writeFileSync: writeFileSync5 } = await import("fs");
8010
+ writeFileSync5(markerPath, (/* @__PURE__ */ new Date()).toISOString(), "utf8");
7558
8011
  } catch {
7559
8012
  }
7560
8013
  } catch (err) {
@@ -7583,7 +8036,7 @@ function startLocalFirstTimers() {
7583
8036
  fired("orphan_task_cleanup");
7584
8037
  try {
7585
8038
  if (!await ensureStoreForPolling()) return;
7586
- const { cleanOrphanedTaskFiles } = await import("../tasks-crud-HBDKE6C5.js");
8039
+ const { cleanOrphanedTaskFiles } = await import("../tasks-crud-DFPIAAEC.js");
7587
8040
  const count = await cleanOrphanedTaskFiles();
7588
8041
  if (count > 0) {
7589
8042
  acted("orphan_task_cleanup");
@@ -7599,7 +8052,7 @@ function startLocalFirstTimers() {
7599
8052
  fired("task_file_consistency");
7600
8053
  try {
7601
8054
  if (!await ensureStoreForPolling()) return;
7602
- const { checkTaskFileConsistency } = await import("../tasks-crud-HBDKE6C5.js");
8055
+ const { checkTaskFileConsistency } = await import("../tasks-crud-DFPIAAEC.js");
7603
8056
  const mismatches = await checkTaskFileConsistency();
7604
8057
  if (mismatches > 0) {
7605
8058
  acted("task_file_consistency");
@@ -7618,7 +8071,7 @@ function startLocalFirstTimers() {
7618
8071
  const TELEMETRY_DAILY_MS = 24 * 60 * 60 * 1e3;
7619
8072
  const telemetryDaily = async () => {
7620
8073
  try {
7621
- const { sendTelemetry, isTelemetryEnabled } = await import("../telemetry-upload-ZOXHRWR5.js");
8074
+ const { sendTelemetry, isTelemetryEnabled } = await import("../telemetry-upload-Y5F6WYLD.js");
7622
8075
  if (!isTelemetryEnabled()) return;
7623
8076
  const { upstream } = await sendTelemetry(24);
7624
8077
  if (upstream.startsWith("sent")) {
@@ -7789,11 +8242,63 @@ async function enterDegradedBreakerMode(crashCount) {
7789
8242
  }, 5 * 60 * 1e3);
7790
8243
  }
7791
8244
  try {
7792
- const breaker = recordDaemonRestart();
8245
+ let coverageGap;
8246
+ let coverageGapLastHeartbeatTs = null;
8247
+ let coverageGapHostBootTs = null;
8248
+ let coverageGapNowMs = Date.now();
8249
+ try {
8250
+ coverageGapNowMs = Date.now();
8251
+ coverageGapLastHeartbeatTs = readLastHeartbeatTsMs();
8252
+ coverageGapHostBootTs = hostBootTimeMs(coverageGapNowMs, os2.uptime());
8253
+ const rawThreshold = Number(process.env.EXE_COVERAGE_GAP_THRESHOLD_MS);
8254
+ coverageGap = assessCoverageGap({
8255
+ lastHeartbeatTs: coverageGapLastHeartbeatTs,
8256
+ hostBootTs: coverageGapHostBootTs,
8257
+ nowMs: coverageGapNowMs,
8258
+ ...Number.isFinite(rawThreshold) && rawThreshold > 0 ? { gapThresholdMs: Math.floor(rawThreshold) } : {}
8259
+ });
8260
+ } catch {
8261
+ coverageGap = void 0;
8262
+ }
8263
+ const breaker = recordDaemonRestart(void 0, coverageGap);
7793
8264
  process.stderr.write(
7794
8265
  `[exed] Boot classified as ${breaker.bootClass} (${breaker.reasonLabel}); crashes=${breaker.crashInWindow}/${5}, restarts=${breaker.restartsInWindow} in window.
7795
8266
  `
7796
8267
  );
8268
+ try {
8269
+ touchEventLoopHeartbeat();
8270
+ } catch {
8271
+ }
8272
+ try {
8273
+ if (coverageGap && shouldWriteCoverageGapAlert(breaker.bootClass, coverageGap, COVERAGE_GAP_ALERT_THRESHOLD_MS)) {
8274
+ const gapHours = (coverageGap.gapMs / (60 * 60 * 1e3)).toFixed(1);
8275
+ const lastHeartbeatIso = coverageGapLastHeartbeatTs !== null ? new Date(coverageGapLastHeartbeatTs).toISOString() : "unknown";
8276
+ const rebootIso = coverageGap.rebootSpansGap && coverageGapHostBootTs !== null ? `, reboot=${new Date(coverageGapHostBootTs).toISOString()}` : "";
8277
+ process.stderr.write(
8278
+ `[exed] COVERAGE GAP: daemon was down ~${gapHours}h; lastHeartbeat=${lastHeartbeatIso}${rebootIso}; GUI LaunchAgent does not run pre-login.
8279
+ `
8280
+ );
8281
+ logDaemonHealth({
8282
+ event: "coverage_gap",
8283
+ pid: process.pid,
8284
+ message: `Daemon coverage gap detected (~${gapHours}h)`,
8285
+ data: {
8286
+ gapMs: coverageGap.gapMs,
8287
+ lastHeartbeatTs: coverageGapLastHeartbeatTs,
8288
+ hostBootTs: coverageGapHostBootTs,
8289
+ rebootSpansGap: coverageGap.rebootSpansGap
8290
+ }
8291
+ });
8292
+ writeCoverageGapAlert(coverageGap, {
8293
+ lastHeartbeatTs: coverageGapLastHeartbeatTs,
8294
+ hostBootTs: coverageGapHostBootTs,
8295
+ nowMs: coverageGapNowMs
8296
+ });
8297
+ } else if (coverageGap) {
8298
+ clearCoverageGapAlertIfExpired();
8299
+ }
8300
+ } catch {
8301
+ }
7797
8302
  if (breaker.trip) {
7798
8303
  logRestartEvent("daemon_restart_breaker_tripped", { crash_in_window: breaker.crashInWindow, restarts_in_window: breaker.restartsInWindow });
7799
8304
  await enterDegradedBreakerMode(breaker.crashInWindow);
@@ -7831,11 +8336,11 @@ try {
7831
8336
  process.stderr.write(`[exed] FATAL: ${err instanceof Error ? err.message : String(err)}
7832
8337
  `);
7833
8338
  try {
7834
- unlinkSync2(SOCKET_PATH);
8339
+ unlinkSync3(SOCKET_PATH);
7835
8340
  } catch {
7836
8341
  }
7837
8342
  try {
7838
- unlinkSync2(PID_PATH);
8343
+ unlinkSync3(PID_PATH);
7839
8344
  } catch {
7840
8345
  }
7841
8346
  process.exit(1);