@overdeck/desktop 0.45.21 → 0.45.22

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 (344) hide show
  1. package/package.json +1 -1
  2. package/server/{acceptance-criteria-CJIFA8Vg.js → acceptance-criteria-BH7ac_1G.js} +2 -2
  3. package/server/{advancing-selfheal-CPOBO5ZS.js → advancing-selfheal-cSvXNZLZ.js} +6 -6
  4. package/server/{agent-gc-D6PUckBB.js → agent-gc-Dj2gncak.js} +4 -4
  5. package/server/{agent-state-BV_6RHnO.js → agent-state-Co5Sy2Fw.js} +1 -1
  6. package/server/{agent-state-service-DHwemt96.js → agent-state-service-CsQ07Pxe.js} +1 -1
  7. package/server/{agent-state-service-6MFQqnFy.js → agent-state-service-DistflNn.js} +5 -5
  8. package/server/{agents-DbrHWunF.js → agents-DXdHmRTC.js} +4 -4
  9. package/server/{agents-Czz6R57Z.js → agents-DyHKlq1I.js} +1 -1
  10. package/server/{archive-planning-BOnwJq8M.js → archive-planning-BvDuWNMo.js} +5 -5
  11. package/server/{archive-planning-MPpvQJL4.js → archive-planning-Cp_DC1j-.js} +1 -1
  12. package/server/{artifact-index-jobs-BOoySTKD.js → artifact-index-jobs-CDBFL4OU.js} +2 -2
  13. package/server/{backlog-auto-trigger-BUaFI44J.js → backlog-auto-trigger-DmA1IbYf.js} +3 -3
  14. package/server/{behavior-Dg-D8eBG.js → behavior-CGj16clS.js} +2 -2
  15. package/server/{briefing-freshness-OouGbJ7d.js → briefing-freshness-C12WgkaB.js} +2 -2
  16. package/server/{build-info-Cv6CI7Gu.js → build-info-BRpqQvNd.js} +1 -1
  17. package/server/{build-info-27NlbKhV.js → build-info-NU3KbXYw.js} +3 -3
  18. package/server/{checkpoint-manager-D64fCC4p.js → checkpoint-manager-CTPjAmtH.js} +2 -2
  19. package/server/{checkpoint-manager-C7mFCY_E.js → checkpoint-manager-rOgT98WY.js} +1 -1
  20. package/server/checkpoint-worker.js +1 -1
  21. package/server/{checkpoints-DwZqT2qQ.js → checkpoints-B5jFNi2G.js} +1 -1
  22. package/server/{checkpoints-Vh-J15ge.js → checkpoints-BJum14fs.js} +2 -2
  23. package/server/{claude-hooks-provision-CS5W_dhI.js → claude-hooks-provision-BhwWK-TQ.js} +1 -1
  24. package/server/{claude-hooks-provision-BVLGfHrv.js → claude-hooks-provision-D7p5WcKZ.js} +2 -2
  25. package/server/{claude-permissions-C2OrLYKL.js → claude-permissions-nSFKH78M.js} +2 -2
  26. package/server/{claude-settings-overlay-DX-fMFpC.js → claude-settings-overlay-BI_UIke0.js} +2 -2
  27. package/server/{claude-settings-overlay-DWXjafJh.js → claude-settings-overlay-DHBwjS1X.js} +1 -1
  28. package/server/cli-BRORS9qY.js +3 -0
  29. package/server/{cli-mvpEOb3w.js → cli-CbKNkFE5.js} +9 -9
  30. package/server/{cliproxy-Dvsr4ZkW.js → cliproxy-Brf_5MuG.js} +2 -2
  31. package/server/{cliproxy-7g1nObvB.js → cliproxy-bONZDBbC.js} +1 -1
  32. package/server/{close-issue-8F6uawYj.js → close-issue-CxReRxIc.js} +5 -5
  33. package/server/{closed-issue-reaper-BaYQYF6w.js → closed-issue-reaper-CQ3kqha7.js} +9 -9
  34. package/server/{closed-issue-reaper-BhV-r-tC.js → closed-issue-reaper-DXP2Xyv3.js} +1 -1
  35. package/server/{codex-D_UBEOwL.js → codex-CbmztVcc.js} +9 -6
  36. package/server/{codex-BBeZ8c3s.js → codex-DNyiQDKW.js} +1 -1
  37. package/server/{codex-parser-BTzlOZiV.js → codex-parser-jl8AeAmB.js} +2 -2
  38. package/server/{config-nAB_F-Gp.js → config-BJKocXKd.js} +1 -1
  39. package/server/{config-G1TOMJZA.js → config-DeTsoZdR.js} +2 -2
  40. package/server/{config-CrduXs4a.js → config-q4Gvd8dq.js} +2 -2
  41. package/server/{config-yaml-Ciyp2mYe.js → config-yaml-ig8Nwtiw.js} +124 -27
  42. package/server/{conflict-gate-BLUNMs1i.js → conflict-gate-CFqPVxEg.js} +3 -3
  43. package/server/{conflict-gate-BKalpcjL.js → conflict-gate-CHU9K1vU.js} +1 -1
  44. package/server/{context-layers-Cg9ZgVfx.js → context-layers-15gDOk20.js} +3 -3
  45. package/server/{context-layers-YNpf6Q_I.js → context-layers-DlQKkHH2.js} +2 -2
  46. package/server/{control-settings-D_79A6gp.js → control-settings-D_odMIaC.js} +4 -4
  47. package/server/{conversation-compaction-DiuZbIUB.js → conversation-compaction-B6YSRLda.js} +8 -8
  48. package/server/{conversation-compaction-CMIeWW4_.js → conversation-compaction-CN4-5YYt.js} +1 -1
  49. package/server/{conversation-service-DQybSPUK.js → conversation-service-C3avRVEr.js} +6 -6
  50. package/server/{conversation-service-CWk8mEym.js → conversation-service-Dq33SYEj.js} +1 -1
  51. package/server/{conversations-BJ-t3BRm.js → conversations-H9if0bCQ.js} +1 -1
  52. package/server/{conversations-BUgGvqVL.js → conversations-bYpM9-kZ.js} +4 -4
  53. package/server/{cost-Drm7qeD5.js → cost-Codk1pc2.js} +2 -2
  54. package/server/{cost-sync-DzHP6zaR.js → cost-sync-D_cre6WM.js} +3 -3
  55. package/server/{cost-jJ2cgDcG.js → cost-wH46-WsJ.js} +3 -3
  56. package/server/{dag-DIji6O2b.js → dag-CJpgf9A3.js} +2 -2
  57. package/server/{dangerous-git-ops-BebB-61h.js → dangerous-git-ops-D6AF-Hg_.js} +1 -1
  58. package/server/dashboard-db-worker.js +7 -7
  59. package/server/{deacon-pleYrvIm.js → deacon-B8HbQdqU.js} +3 -3
  60. package/server/{deacon-1s7bM5zn.js → deacon-CkT_kznS.js} +1377 -407
  61. package/server/{deacon-nudge-log-C5VCKtyi.js → deacon-nudge-log-D6K9K-rE.js} +3 -3
  62. package/server/{deacon-swarm-DmA3rJ7k.js → deacon-swarm-BryRr6AO.js} +13 -13
  63. package/server/deacon-swarm-CV54eNmU.js +2 -0
  64. package/server/deacon.js +8 -8
  65. package/server/{deploy-patrol-DmM6F-yw.js → deploy-patrol-1IrZxicY.js} +6 -6
  66. package/server/{deploy-window-ClLq1RYf.js → deploy-window-7ZYHh7Zp.js} +1 -1
  67. package/server/{deploy-window-jw4S_Y-c.js → deploy-window-wDf4UgHt.js} +6 -6
  68. package/server/{dev-supervisor-Do2Stz49.js → dev-supervisor-C7p9kEpc.js} +2 -2
  69. package/server/{devcontainer-renderer-D8ylupco.js → devcontainer-renderer-CNmQy0pL.js} +3 -3
  70. package/server/{dist-yfR7G1BL.js → dist-D-Ed5yVw.js} +1 -1
  71. package/server/dist-j64RzSrQ.js +3 -0
  72. package/server/{docker-ClwPQaba.js → docker-BCZ89M9X.js} +2 -2
  73. package/server/{dod-BLphkhjs.js → dod-DbJLYcHv.js} +1 -1
  74. package/server/{ensure-devcontainer-BA3bICoY.js → ensure-devcontainer-Cs6W9Yzj.js} +1 -1
  75. package/server/{ensure-devcontainer-CFpQatOc.js → ensure-devcontainer-V5JWaAva.js} +4 -4
  76. package/server/{esm-shims-BZw-fTQ6.js → esm-shims-dTeNdq7X.js} +1 -1
  77. package/server/{event-store-DABarGNz.js → event-store-CpBGsO6_.js} +1 -1
  78. package/server/{event-store-BVnON3vf.js → event-store-TnWdydfB.js} +3 -3
  79. package/server/{events-CmERlnwn.js → events-DSUdR-04.js} +3 -3
  80. package/server/{events-LGeUehYW.js → events-Dsuv6qyB.js} +1 -1
  81. package/server/{factory-CQNprtHe.js → factory-BMrK4TrE.js} +4 -4
  82. package/server/{feature-registry-population-D9Z3tYSa.js → feature-registry-population-B-CI9hgE.js} +4 -4
  83. package/server/{feature-registry-storage-BWymOgXE.js → feature-registry-storage-B972ph_A.js} +2 -2
  84. package/server/{features--fOza5g5.js → features-Bc-Bmiye.js} +2 -2
  85. package/server/{feedback-target-Dn9vfPpz.js → feedback-target-DS6NUuSs.js} +1 -1
  86. package/server/{feedback-target-Dqik2WTe.js → feedback-target-DZ-iAnAa.js} +7 -7
  87. package/server/{feedback-writer-Wlq5-qgS.js → feedback-writer-BXP6g75N.js} +4 -4
  88. package/server/{feedback-writer-DDQNV8uc.js → feedback-writer-Bx5z11mF.js} +1 -1
  89. package/server/{flywheel-DPUc8r3V.js → flywheel-6WHU4O7A.js} +14 -14
  90. package/server/{flywheel-1Wd8WDlh.js → flywheel-COR0mbRI.js} +12 -12
  91. package/server/{flywheel-Q-38YhZG.js → flywheel-Ctr5uuvo.js} +1 -1
  92. package/server/{flywheel-merge-order-CeBuX0EJ.js → flywheel-merge-order-CNKAY489.js} +1 -1
  93. package/server/{flywheel-merge-order-4SqOXFAr.js → flywheel-merge-order-CTgHeg-W.js} +7 -7
  94. package/server/forge-B0_opi-V.js +2 -0
  95. package/server/{forge-DBbDpiYc.js → forge-B1S_KZv4.js} +2 -2
  96. package/server/{from-hh6vTBGl.js → from-DpwQ-sc3.js} +1 -1
  97. package/server/{fts-db-6ponMie2.js → fts-db-DmAcuCkV.js} +2 -2
  98. package/server/{fts-operations-KIRK165y.js → fts-operations-7d_RkmWp.js} +2 -2
  99. package/server/git-utils-Cc3FHDKd.js +198 -0
  100. package/server/{git-utils-DmF5xkj8.js → git-utils-CsKGnzFA.js} +1 -1
  101. package/server/{github-app-B3yfECo8.js → github-app-CDPtGF7J.js} +2 -2
  102. package/server/{github-app-CeSVFL6C.js → github-app-CU14oYzP.js} +1 -1
  103. package/server/{github-client-4A6FgA8O.js → github-client-CwBZZ3t7.js} +1 -1
  104. package/server/{github-client-Dslipypz.js → github-client-XjTJbBm7.js} +2 -2
  105. package/server/{github-pr-lookup-DBP0YHMr.js → github-pr-lookup-CFGeVhqv.js} +2 -2
  106. package/server/harness-binary-B2CTcD84.js +106 -0
  107. package/server/{harness-resolve-BGpO-OVM.js → harness-resolve-D5FVQTmy.js} +9 -15
  108. package/server/{health-events-CnwV_SSz.js → health-events-C1whmd58.js} +1 -1
  109. package/server/{health-events-CZGZ5I-A.js → health-events-DREeevle.js} +2 -2
  110. package/server/{hooks-DvX33gY_.js → hooks-B-HItBiS.js} +1 -1
  111. package/server/{hooks-CoNscX84.js → hooks-yxRsjk-z.js} +2 -2
  112. package/server/hume-BmhvfVbV.js +3 -0
  113. package/server/{hume-DSJt5eA_.js → hume-Dz_OymXE.js} +2 -2
  114. package/server/{idle-stack-reaper-5DVRoY6P.js → idle-stack-reaper-DrCv0OAG.js} +1 -1
  115. package/server/{idle-stack-reaper-BfL8HqYy.js → idle-stack-reaper-Yf34xXxY.js} +2 -2
  116. package/server/{in-flight-guard-tVGiI5ee.js → in-flight-guard-BoWm66Kh.js} +2 -2
  117. package/server/{infra-DN2wSxle.js → infra-D4iNWMA5.js} +4 -4
  118. package/server/{injection-DK9zh_HL.js → injection-BVNa4MQW.js} +1 -1
  119. package/server/{injection-DtlT8Akv.js → injection-D7T75Pye.js} +7 -7
  120. package/server/{inspect-agent-DKByUS_F.js → inspect-agent-BXCgNeZ4.js} +13 -9
  121. package/server/inspect-agent-Dq0z1k3H.js +2 -0
  122. package/server/{internal-token-7bYL5v6K.js → internal-token-C9DdEOKY.js} +1 -1
  123. package/server/{internal-token-DhfFiwW7.js → internal-token-CXsfxslp.js} +2 -2
  124. package/server/{io-BiM-7Zsx.js → io-DQR9PMgS.js} +3 -3
  125. package/server/{issue-closed-Dfw3QDyZ.js → issue-closed-DtmJM0D0.js} +7 -7
  126. package/server/{issue-lifecycle-ytsEdDlK.js → issue-lifecycle-8PSS9Anq.js} +1 -1
  127. package/server/{issue-lifecycle-B7HZWnTA.js → issue-lifecycle-CeyW_HoD.js} +21 -21
  128. package/server/{issue-service-singleton-D5EB5eYr.js → issue-service-singleton-DBZabEl7.js} +1 -1
  129. package/server/{issue-service-singleton-CPESc4Or.js → issue-service-singleton-D_RVYBuL.js} +8 -8
  130. package/server/{issues-XYtFMxrH.js → issues-pDW9VUNz.js} +2 -2
  131. package/server/{jsonl-parser-DJV2eZUP.js → jsonl-parser-C3HVNR5d.js} +3 -3
  132. package/server/{label-cleanup-CJ4m8iRU.js → label-cleanup-DPwiZlWo.js} +3 -3
  133. package/server/{label-reconciler-CNf3Ylm3.js → label-reconciler-Df1ZduPH.js} +4 -4
  134. package/server/{launcher-generator-5DJRiovn.js → launcher-generator-COgR2By1.js} +6 -6
  135. package/server/{layers-cZx7ibtV.js → layers-Cp1To4L8.js} +2 -2
  136. package/server/{lifecycle-CE7619Xw.js → lifecycle-CtPDcZ9u.js} +6 -6
  137. package/server/{lifecycle-io-CUpsxG0p.js → lifecycle-io-DmY2qwCn.js} +1 -1
  138. package/server/{lifecycle-io-DMurK4oM.js → lifecycle-io-taIb0PoH.js} +4 -4
  139. package/server/{linear-client-BLyN-NiP.js → linear-client-DsFkIxee.js} +2 -2
  140. package/server/{linear-client-Bj1l4FOA.js → linear-client-YwZMDIwQ.js} +1 -1
  141. package/server/memory-fts-worker.js +1 -1
  142. package/server/{merge-CwX2_AWm.js → merge-BwsyNRJV.js} +1 -1
  143. package/server/{merge-hSC2BENe.js → merge-C1t-bspg.js} +3 -3
  144. package/server/{merge-agent-CnORPiri.js → merge-agent-B-SnXOoc.js} +1 -1
  145. package/server/{merge-agent-DnBsms_V.js → merge-agent-DDiIjzk-.js} +369 -213
  146. package/server/{merge-batch-C2w2U2eK.js → merge-batch-Byt-QnEl.js} +1 -1
  147. package/server/{merge-blockers-DhRgh76x.js → merge-blockers-BYjeXrVN.js} +2 -2
  148. package/server/merge-ops-DwWCkSgo.js +2 -0
  149. package/server/{merge-rebase-CE-ZyOMY.js → merge-rebase-Cm6fXaZN.js} +2 -2
  150. package/server/{merge-set-DHkzPCJU.js → merge-set-6LEglm6o.js} +1 -1
  151. package/server/{merge-set-D7YNU1ZB.js → merge-set-DiISXcC-.js} +3 -3
  152. package/server/{merge-sync-CpGA9Kg7.js → merge-sync-B95_4in_.js} +1 -1
  153. package/server/{merge-sync-De1FYva5.js → merge-sync-Do8_q32h.js} +2 -2
  154. package/server/{merge-train-SvkRJZ-k.js → merge-train-CKana8EH.js} +3 -3
  155. package/server/{merge-train-deps-CECJTElu.js → merge-train-deps-BgmqwIfA.js} +4 -4
  156. package/server/{merge-verification-B3meGcXF.js → merge-verification-CqnUzGEK.js} +4 -4
  157. package/server/{multipart-parser-ByTMgYV5.js → multipart-parser-tdOQDJ3o.js} +2 -2
  158. package/server/{no-resume-mode-BnInAFKs.js → no-resume-mode-BWOSZjWd.js} +1 -1
  159. package/server/node_modules/.package-lock.json +5 -5
  160. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/README.md +3 -3
  161. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.d.ts.map +1 -1
  162. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.js +2 -2
  163. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.js.map +1 -1
  164. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/package.json +5 -5
  165. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/NodeChildProcessSpawner.ts +6 -8
  166. package/server/{orphan-proposed-reconciler-CAfuWTA1.js → orphan-proposed-reconciler-DSvsJ5M7.js} +1 -1
  167. package/server/{orphan-proposed-reconciler-AxAGUouN.js → orphan-proposed-reconciler-xklgvNA7.js} +19 -12
  168. package/server/package-lock.json +6 -6
  169. package/server/package.json +1 -1
  170. package/server/{pan-dir-Rw17YjT1.js → pan-dir-DOcf6ug3.js} +4 -4
  171. package/server/{paths-FP8v3lTz.js → paths-DooHpt9p.js} +2 -2
  172. package/server/{pickup-xi3KTLaJ.js → pickup-CaskQ7j6.js} +2 -2
  173. package/server/{pipeline-membership-BtKMNY7v.js → pipeline-membership-1LGRjo-k.js} +11 -8
  174. package/server/{pipeline-notifier-BM2HLF7B.js → pipeline-notifier-B6FVsYF9.js} +2 -2
  175. package/server/{pipeline-notifier-dQ-U4NSb.js → pipeline-notifier-CZsrU_nj.js} +1 -1
  176. package/server/{project-pipelines-B59NfN44.js → project-pipelines-CtNG_rvs.js} +2 -2
  177. package/server/projects-BKkwpH6q.js +3 -0
  178. package/server/{prompts-CbqaVjbe.js → prompts-EvhMeeHG.js} +2 -2
  179. package/server/{providers-d3pwXGVE.js → providers-BDDPULlp.js} +7 -7
  180. package/server/providers-DNSQqy2V.js +3 -0
  181. package/server/public/assets/{chunk-BO2N2NFS-BxYSL7J-.js → chunk-BO2N2NFS-sym_ufXe.js} +4 -4
  182. package/server/public/assets/{diagram-OG6HWLK6-C_F9Q2as.js → diagram-OG6HWLK6-CQJPBNBu.js} +1 -1
  183. package/server/public/assets/{dist-DQNg4CiF.js → dist-Bio7THQU.js} +1 -1
  184. package/server/public/assets/{dist-CLSlc6cV.js → dist-DukGS2YZ.js} +3 -3
  185. package/server/public/assets/{ganttDiagram-6RSMTGT7-Cq0my-0C.js → ganttDiagram-6RSMTGT7-D4lWwte3.js} +1 -1
  186. package/server/public/assets/{highlighted-body-OFNGDK62-eZC03dGh.js → highlighted-body-OFNGDK62-CaLboCt5.js} +1 -1
  187. package/server/public/assets/{index-C6NLz_1S.css → index-Bdc4V9ba.css} +1 -1
  188. package/server/public/assets/{index-SLYGA8AQ.js → index-Bwejq-5s.js} +147 -145
  189. package/server/public/assets/{linear-6Fi3qnGg.js → linear-qUWmMZ-c.js} +1 -1
  190. package/server/public/assets/mermaid-GHXKKRXX-B5v_r7cI.js +1 -0
  191. package/server/public/assets/{pieDiagram-4H26LBE5-Dpmc6xsv.js → pieDiagram-4H26LBE5-C4zYulEm.js} +1 -1
  192. package/server/public/assets/{prod-ojHllFvN.js → prod-C8VtLuWC.js} +4 -4
  193. package/server/public/assets/{quadrantDiagram-W4KKPZXB-Ulr9gON5.js → quadrantDiagram-W4KKPZXB-qP04zyZC.js} +1 -1
  194. package/server/public/assets/{sankeyDiagram-5OEKKPKP-CwdHGXfL.js → sankeyDiagram-5OEKKPKP-eMPTX_cG.js} +1 -1
  195. package/server/public/assets/{xychartDiagram-2RQKCTM6-r-bEDzJh.js → xychartDiagram-2RQKCTM6-Dme1PIt6.js} +1 -1
  196. package/server/public/index.html +54 -10
  197. package/server/{pull-requests-CjjPj7v6.js → pull-requests-8z2N1UOV.js} +3 -3
  198. package/server/{pull-requests-D3N6HQzI.js → pull-requests-By_BteaL.js} +1 -1
  199. package/server/{queries-B5hl7lMQ.js → queries-ZABd5aXP.js} +95 -71
  200. package/server/rally-OSJXdiHK.js +3 -0
  201. package/server/{rally-api-DGaFz5L5.js → rally-api-DqKqIMNR.js} +2 -2
  202. package/server/{rally-api-CKr0O4DJ.js → rally-api-xHazRk0d.js} +1 -1
  203. package/server/{rally-client-Cqf6EX_r.js → rally-client-CGWEHaPd.js} +1 -1
  204. package/server/{rally-client-SVbjGvqj.js → rally-client-COYz1vYR.js} +4 -4
  205. package/server/{rally-Dp0Gb1DN.js → rally-i_goYmiA.js} +3 -3
  206. package/server/reap-terminal-sessions-CaMkFOIH.js +4 -0
  207. package/server/{reap-terminal-sessions-CjqRAGw7.js → reap-terminal-sessions-DG9eiMVz.js} +11 -28
  208. package/server/{rebuild-stack-DjdpALr1.js → rebuild-stack-CKjJAI8L.js} +1 -1
  209. package/server/{rebuild-stack-DHqCLvLX.js → rebuild-stack-JUm0jqYP.js} +6 -6
  210. package/server/{reconstruct-cache-BqrCQt0o.js → reconstruct-cache-wU79aCee.js} +6 -6
  211. package/server/record-rwK-nKv_.js +3 -0
  212. package/server/{record-update-RviRDSNs.js → record-update-Crz74r-6.js} +2 -2
  213. package/server/{record-update-BlB8mpKO.js → record-update-D3N6WMFR.js} +1 -1
  214. package/server/{recovery-trip-l1Hsi37x.js → recovery-trip-DkzJSej9.js} +2 -2
  215. package/server/{release-engine-CSI4K6Oj.js → release-engine-DMINVN8S.js} +5 -5
  216. package/server/{release-set-BywwggrE.js → release-set-DeUSOEHy.js} +3 -3
  217. package/server/{remote-DYziAkiZ.js → remote-Dr5kGYSZ.js} +3 -3
  218. package/server/{remote-agents-CZ2rc8I0.js → remote-agents-Ct_WOyke.js} +6 -6
  219. package/server/{remote-agents-BNORDWAX.js → remote-agents-D6O_zETW.js} +1 -1
  220. package/server/{remote-cnoeuDWn.js → remote-b-c5bOce.js} +3 -3
  221. package/server/{remote-completion-W67FNQ-A.js → remote-completion-Dca3hAaa.js} +13 -13
  222. package/server/resume-wZZsWtzz.js +3 -0
  223. package/server/{review-agent-CSswH985.js → review-agent-CCum8sGe.js} +1 -1
  224. package/server/{review-agent-CqSqSHkU.js → review-agent-CThvgK2r.js} +23 -23
  225. package/server/{review-artifacts-BBgnd5df.js → review-artifacts-CXywD0F2.js} +5 -5
  226. package/server/{review-context-Ctp9BdNJ.js → review-context-OYfKUprb.js} +8 -8
  227. package/server/{review-status-DXeqFpk5.js → review-status-Bnh-rdkY.js} +1 -1
  228. package/server/{review-status-CCgPVK1h.js → review-status-DFRjDFef.js} +21 -37
  229. package/server/{review-status-enrichment-DtDRGpst.js → review-status-enrichment-crNAtIpL.js} +3 -3
  230. package/server/review-status-source-CxuEjLGg.js +39 -0
  231. package/server/{review-status-sync-C792ksoJ.js → review-status-sync-D60PJWNL.js} +1 -1
  232. package/server/{review-status-sync-jnLgd04F.js → review-status-sync-DpAMD_WO.js} +2 -2
  233. package/server/{review-verdict-feedback-CMsIpTpy.js → review-verdict-feedback-CpUZl5aE.js} +7 -7
  234. package/server/{review-verdict-feedback-D5lW0o3k.js → review-verdict-feedback-JImjut0z.js} +1 -1
  235. package/server/{rollup-B3kQmNpl.js → rollup-CZ02qgxk.js} +1 -1
  236. package/server/{rollup-CLj_AK9f.js → rollup-SyuF09e4.js} +8 -8
  237. package/server/{scanner-C4NeC4FE.js → scanner-Br0Z5S6R.js} +7 -7
  238. package/server/{sequence-io-Ce-6grIY.js → sequence-io-fxU0DlwW.js} +4 -4
  239. package/server/{sequencer-agent-Bpz0yGmG.js → sequencer-agent-B5YC5XVP.js} +5 -5
  240. package/server/server.js +583 -387
  241. package/server/{service-CqAY8Kmk.js → service-Bagb90KZ.js} +150 -47
  242. package/server/{session-fork-uNo4rMRA.js → session-fork-BqQxd-V6.js} +2 -2
  243. package/server/{session-history-DUehL3KN.js → session-history-XdS0JKp3.js} +4 -4
  244. package/server/{settings-DP2OYLXL.js → settings-BNbocWOg.js} +3 -3
  245. package/server/settings-BlUsVaUc.js +2 -0
  246. package/server/{settings-D9grjmaP.js → settings-uLc6DEYI.js} +2 -2
  247. package/server/{shadow-engineering-Bi_oIMtF.js → shadow-engineering-D4X_s3fA.js} +3 -3
  248. package/server/{shadow-state-a_ztFBJe.js → shadow-state-C_NkP-sa.js} +2 -2
  249. package/server/{shadow-state-CDxEuPlE.js → shadow-state-CbvsN3qG.js} +1 -1
  250. package/server/{shadow-utils-CyOg6_Xq.js → shadow-utils-CYMRPeRT.js} +2 -2
  251. package/server/{ship-log-DDcueaIR.js → ship-log-__QtAFXG.js} +1 -1
  252. package/server/{smart-compaction--Oj65Uov.js → smart-compaction-CLZOWin1.js} +7 -7
  253. package/server/{smart-compaction-C1_VVLEd.js → smart-compaction-jdMkG1vo.js} +1 -1
  254. package/server/{spawn-planning-session-LFtK2QCE.js → spawn-planning-session-8D6mE033.js} +1 -1
  255. package/server/{spawn-planning-session-AiUSsBnH.js → spawn-planning-session-D5OXo8pT.js} +19 -15
  256. package/server/{specialist-completion-qOgqdqXH.js → specialist-completion-CqmduO92.js} +1 -1
  257. package/server/{specialist-context-gjj8Z4Ii.js → specialist-context-CJ-QjFR-.js} +5 -5
  258. package/server/{specialist-handoff-logger-BsBNvVZv.js → specialist-handoff-logger-Dnjlwt7g.js} +2 -2
  259. package/server/{specialist-logs-CSLtvPx6.js → specialist-logs-CQnKzuZs.js} +3 -3
  260. package/server/{specialists-DAegTvRt.js → specialists-Bg9v4z3F.js} +122 -94
  261. package/server/{specialists-CYRwELzc.js → specialists-CwZHb5cb.js} +18 -18
  262. package/server/{specialists-D0VBf8g_.js → specialists-D0gGXMZx.js} +1 -1
  263. package/server/{specialists-C6WkeKFK.js → specialists-Dqe6_HE5.js} +1 -1
  264. package/server/specs-BhOKBzqk.js +3 -0
  265. package/server/{src-OLoJhUiJ.js → src-BMMoA_ba.js} +6 -6
  266. package/server/{src-BqTcrfO_.js → src-Bqdtd6po.js} +3 -3
  267. package/server/{src-Dpq1yFIl.js → src-k039WVYY.js} +337 -4
  268. package/server/{stack-health-I713ELld.js → stack-health-Bd06frFn.js} +1 -1
  269. package/server/{stack-health-DV_f-lK0.js → stack-health-C-ifC7b0.js} +2 -2
  270. package/server/{stale-task-claims-CQSKZVq0.js → stale-task-claims-L7pJkQFL.js} +4 -4
  271. package/server/{staleness-BbsGxmF2.js → staleness-BID1BKdr.js} +1 -1
  272. package/server/{staleness-zGp4P1hd.js → staleness-_Tr-GwdA.js} +1 -1
  273. package/server/{state-home-DixkE-up.js → state-home-CONQvZR0.js} +36 -23
  274. package/server/state-migrate-BeBW0KXA.js +478 -0
  275. package/server/{stuck-remediation-BWkK_O7A.js → stuck-remediation-CKnIryGT.js} +20 -18
  276. package/server/{stuck-remediation-CTPRC2S5.js → stuck-remediation-CsGD5Ksb.js} +1 -1
  277. package/server/{substrate-bug-weights-service-DXd0ID83.js → substrate-bug-weights-service-CpIZILj9.js} +3 -3
  278. package/server/{summary-fork-CdLn8Chr.js → summary-fork-agEMsPSo.js} +2 -2
  279. package/server/{summary-fork-f3DpgjXh.js → summary-fork-bX6ax6X7.js} +8 -8
  280. package/server/supervisor-COVHrBTg.js +2 -0
  281. package/server/{supervisor-Ch8CDuoF.js → supervisor-Ctt4eRYz.js} +3 -3
  282. package/server/{swarm-readiness-C9P2iPap.js → swarm-readiness-DdmJVX7y.js} +3 -3
  283. package/server/{system-prerequisites-DkoQBn1q.js → system-prerequisites-DSXBvffY.js} +24 -44
  284. package/server/{teardown-workspace-D-5yMyit.js → teardown-workspace-DDCf5n-a.js} +15 -15
  285. package/server/{test-agent-queue-BwpUpu-o.js → test-agent-queue-BJZ9Nfcc.js} +6 -6
  286. package/server/{test-verdict-BRiSu7eW.js → test-verdict-Cp5tljlJ.js} +1 -1
  287. package/server/{test-verdict-BQ1yx7d4.js → test-verdict-D_-sXIz_.js} +1 -1
  288. package/server/{tldr-daemon-BJA7TkqS.js → tldr-daemon-B8_oT5gx.js} +1 -1
  289. package/server/{tldr-daemon-DjxP5g6Y.js → tldr-daemon-BQFmmFp0.js} +2 -2
  290. package/server/{tmux-HQLgwo_C.js → tmux-BAvtac_u.js} +1 -1
  291. package/server/{tmux-y1blSxks.js → tmux-L5LgvGLp.js} +2 -2
  292. package/server/{token-LUrbM9sU.js → token-BkQLy4yS.js} +2 -2
  293. package/server/token-util-BArZLN6w.js +3 -0
  294. package/server/{token-util-BZaDAQ8S.js → token-util-DI8sGlmF.js} +1 -1
  295. package/server/{tracker-config-DSFZBdXP.js → tracker-config-DdT-nUAM.js} +2 -2
  296. package/server/{tracker-utils-DiceZN3a.js → tracker-utils-CawsPSS2.js} +2 -2
  297. package/server/{tracker-utils-WtP_V-yn.js → tracker-utils-DV3h1FYG.js} +1 -1
  298. package/server/{traefik-connect-BXqfOP4-.js → traefik-connect-C6mJckNs.js} +1 -1
  299. package/server/{tunnel-WcJImbAC.js → tunnel-BIFl98rc.js} +1 -1
  300. package/server/{tunnel-DTng1rfQ.js → tunnel-IdK1iTHx.js} +3 -3
  301. package/server/{types-BjaZ1oqH.js → types-7-GnJn0t.js} +1 -1
  302. package/server/{types-DqeBMmJN.js → types-hraoaQIp.js} +1 -1
  303. package/server/{uat-train-Wismge7h.js → uat-train-0Ujk8GCv.js} +1 -1
  304. package/server/{uat-train-BpLnp7Cx.js → uat-train-j0cPeMSj.js} +25 -25
  305. package/server/{validation-BA4e5EGm.js → validation-CabEISJT.js} +4 -4
  306. package/server/{validation-CUWamZ4X.js → validation-DcAgXTQp.js} +1 -1
  307. package/server/{verification-artifact-Dr_0g9nb.js → verification-artifact-BuTA1QbL.js} +1 -1
  308. package/server/{verification-artifact-CrbI4tJE.js → verification-artifact-Ck1tefmz.js} +1 -1
  309. package/server/{verification-runner-Dcksl_P-.js → verification-runner-DlJezzef.js} +1 -1
  310. package/server/{verification-runner-gAzh3cVD.js → verification-runner-FiuAZ-H2.js} +15 -14
  311. package/server/{vtt-parser-3VZKsmSm.js → vtt-parser-BnRsYzcz.js} +1 -1
  312. package/server/{work-agent-prompt-ULdcANl5.js → work-agent-prompt-DLthEPAq.js} +12 -11
  313. package/server/{workflows-B8ROFlfw.js → workflows-BZNNYkGC.js} +18 -18
  314. package/server/workflows-C4mR0Reb.js +2 -0
  315. package/server/{workspace-DSjUJaJN.js → workspace-3IC-UkAi.js} +1 -1
  316. package/server/{workspace-DhTDA8nB.js → workspace-D9ppycdg.js} +3 -3
  317. package/server/{workspace-config-BAAsAv-o.js → workspace-config-Bigl_-Lk.js} +1 -1
  318. package/server/{workspace-manager-CcujONCR.js → workspace-manager-B1WOfKvB.js} +1 -1
  319. package/server/{workspace-manager-DsN52IMG.js → workspace-manager-ClkCIWTe.js} +13 -13
  320. package/server/{workspace-metadata-CftOpNLs.js → workspace-metadata-BE0efUv_.js} +1 -1
  321. package/server/{workspace-metadata-DIL5_U4c.js → workspace-metadata-tiSRIWJP.js} +2 -2
  322. package/server/{workspaces-Dmlh1YXm.js → workspaces-CFPcL0vl.js} +96 -96
  323. package/sync-sources/skills/pan-start/SKILL.md +23 -0
  324. package/server/cli-ChErG518.js +0 -3
  325. package/server/deacon-swarm-uudlSCLM.js +0 -2
  326. package/server/dist-BEDL2alY.js +0 -3
  327. package/server/forge-DbhJyH6u.js +0 -2
  328. package/server/git-utils-Bkxzr1Xf.js +0 -129
  329. package/server/hume-BrA1tUuk.js +0 -3
  330. package/server/inspect-agent-CyXNo9fM.js +0 -2
  331. package/server/merge-ops-BpTtuO8x.js +0 -2
  332. package/server/projects-IRHJIPYC.js +0 -3
  333. package/server/providers-BqCdTryq.js +0 -3
  334. package/server/public/assets/mermaid-GHXKKRXX-BNwFoQsf.js +0 -1
  335. package/server/rally-DGimSRBQ.js +0 -3
  336. package/server/reap-terminal-sessions-C1mfzoZo.js +0 -3
  337. package/server/record-us0YECMO.js +0 -3
  338. package/server/resume-OyN3dEXE.js +0 -3
  339. package/server/settings-BaPXXJsT.js +0 -2
  340. package/server/specs-BsNcum0h.js +0 -3
  341. package/server/state-migrate-_zJJ6XKE.js +0 -362
  342. package/server/supervisor-Qy1QecAs.js +0 -2
  343. package/server/token-util-Cg-QnowA.js +0 -3
  344. package/server/workflows-C5c-RPsY.js +0 -2
@@ -1,47 +1,49 @@
1
1
  import { i as __require, t as __commonJSMin } from "./rolldown-runtime-DNCzzKnI.js";
2
- import { $n as resolveProjectFromIssueSync, At as init_record, Ft as readIssueRecordSync, Nn as getProjectSync, Or as init_errors, Rr as OVERDECK_HOME, Un as listProjectsSync, ai as sessionFilePath, an as init_auto_commit, dn as init_state_plane, f as loadConfigSync, kr as AGENTS_DIR, ln as STATE_PLANE_PATHS, pn as isStatePlanePath, s as init_load, sn as reconcileStatePlaneDrift, ti as init_paths, un as getMainDivergence, zn as init_projects } from "./config-yaml-Ciyp2mYe.js";
3
- import { n as init_build_info, t as getBuildInfo } from "./build-info-27NlbKhV.js";
4
- import { n as getDashboardIdentity, t as recordDeaconNudge } from "./deacon-nudge-log-C5VCKtyi.js";
2
+ import { Hn as init_projects, In as getProjectSync, Kn as listProjectsSync, Mr as AGENTS_DIR, Nt as init_record, Rt as readIssueRecordSync, Vr as OVERDECK_HOME, b as DEFAULT_CONFIG$1, ci as sessionFilePath, cn as init_auto_commit, f as loadConfigSync, fn as STATE_PLANE_PATHS, gn as isStatePlanePath, ii as init_paths, jr as init_errors, mn as init_state_plane, nr as resolveProjectFromIssueSync, pn as getMainDivergence, s as init_load, un as reconcileStatePlaneDrift, x as init_defaults } from "./config-yaml-ig8Nwtiw.js";
3
+ import { n as init_build_info, t as getBuildInfo } from "./build-info-NU3KbXYw.js";
4
+ import { n as getDashboardIdentity, t as recordDeaconNudge } from "./deacon-nudge-log-D6K9K-rE.js";
5
5
  import { a as init_activity_logger, n as emitActivityEntrySync, r as emitActivityTtsSync } from "./activity-logger-DDlOIAML.js";
6
- import { n as updateIssueRecord, t as init_record_update } from "./record-update-RviRDSNs.js";
7
- import { D as killSession, E as isPaneDead, F as querySessionSync, H as sessionExistsSync, M as listSessions, R as sendKeys, V as sessionExists, i as capturePane, j as listSessionNames, k as listPaneValues, w as init_tmux, z as sendKeysAsync } from "./tmux-y1blSxks.js";
8
- import { a as init_event_store, i as initEventStore } from "./event-store-BVnON3vf.js";
9
- import { S as needsReviewDispatch, c as init_review_status, h as reviewGatesPassedSync, s as getReviewStatusSync, u as loadReviewStatuses, x as init_review_dispatch_decision, y as setReviewStatusSync } from "./review-status-CCgPVK1h.js";
10
- import { c as listAllAgentsSync, d as isTerminalIssueStage, o as init_agents, u as getIssueStageSync } from "./agents-DbrHWunF.js";
11
- import { $ as stopAgent, Bn as recordAgentFailure, Dn as getAgentDir, F as isContextOverflowTail, Gn as saveAgentStateSync, I as init_messaging, Jn as setAgentYieldedSync, L as messageAgent, Ln as markAgentRunningState, M as resumeAgent, Mn as init_agent_state, N as init_context_overflow, Q as init_termination, St as init_transcript_landing, Tn as clearYieldForResumeSync, Un as resetAgentFailureCount, Wn as saveAgentState, _r as init_codex_auth, a as listRunningAgentsSync, at as getConcurrencyLimits, dr as init_runtime_state, fr as saveAgentRuntimeState, ft as workResumeSlotsAvailable, hr as applyCodexAuthBurnFlag, ht as setCachedMemoryVerdict, i as listRunningAgents, jn as getAgentStateSync, kn as getAgentState, lr as getAgentRuntimeState, lt as resetPatrolDispatchBudget, mt as init_memory_verdict_cache, n as init_queries, ot as init_concurrency, pn as buildDefaultResumeContinueMessage, qn as setAgentPausedSync, r as listAgentStates, rt as describeRunningAgents, s as init_agents$1, st as releaseAdvancingSlot, tt as countRunningAgents, ur as getAgentRuntimeStateSync, ut as tryReserveAdvancingSlot, vr as paneShowsCodexAuthBurn, vt as deliverInitialPromptWithRetry, wn as clearAgentTroubledSync, xt as captureTranscriptUserRecordSnapshot } from "./queries-B5hl7lMQ.js";
12
- import { c as logDeaconEventSync, o as init_persistent_logger, s as logAgentLifecycleSync } from "./session-history-DUehL3KN.js";
13
- import { i as resolveGitHubIssueSync, n as init_tracker_utils } from "./tracker-utils-DiceZN3a.js";
14
- import { i as ensureInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-DhfFiwW7.js";
15
- import { c as init_review_status_sync, l as markWorkspaceStuck } from "./review-status-sync-jnLgd04F.js";
16
- import { m as readWorkspacePlanSync, o as init_io } from "./io-BiM-7Zsx.js";
17
- import { f as init_config, m as loadConfigSync$1, p as loadConfig$1 } from "./config-CrduXs4a.js";
18
- import { T as stampBootReconciliation, h as setBootReconciliationDecision, l as isDeaconGloballyPaused, r as getBootReconciliationState, s as init_control_settings } from "./control-settings-D_79A6gp.js";
19
- import { c as init_docker_stats, s as DockerStatsCollector } from "./stack-health-DV_f-lK0.js";
20
- import { l as init_dag, o as getDispatchableItems } from "./dag-DIji6O2b.js";
21
- import { a as loadCloisterConfigSync, i as loadCloisterConfig, r as init_config$1 } from "./config-G1TOMJZA.js";
22
- import { a as findRecreatedLegacyStatePaths, o as init_state_home } from "./state-home-DixkE-up.js";
23
- import { a as isAgentIdleForNudge, t as checkStuckAgentRemediation } from "./stuck-remediation-BWkK_O7A.js";
24
- import { n as __filename, r as init_esm_shims } from "./esm-shims-BZw-fTQ6.js";
25
- import { i as init_staleness, r as computeBuildStaleness } from "./staleness-BbsGxmF2.js";
26
- import { a as pidsWithCwdUnder, i as sweepAutoCloseOutCache, n as pruneTerminalStoppedAgents, r as getAutoCloseOutCanonicalState } from "./agent-gc-D6PUckBB.js";
27
- import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-Wlq5-qgS.js";
28
- import { r as surfaceIssueFeedbackNeedsYou, t as init_feedback_target } from "./feedback-target-Dqik2WTe.js";
29
- import { a as init_review_convoy_liveness, c as init_review_monitor, i as evaluateReviewConvoyLiveness, o as reviewTimestampMs, r as init_in_flight_guard, s as REVIEW_SUB_ROLES, t as createInFlightGuard } from "./in-flight-guard-tVGiI5ee.js";
30
- import { H as getTmuxSessionName, J as parseReviewerSessionName, _ as getAllProjectSpecialistStatuses, t as init_specialists } from "./specialists-CYRwELzc.js";
31
- import { a as inferBranchFromWorkspace, i as findWorkspacePath, o as init_archive_planning } from "./archive-planning-BOnwJq8M.js";
32
- import { A as withConcurrencyLimit, k as init_concurrency$1 } from "./github-app-B3yfECo8.js";
33
- import { n as init_issue_closed, r as isIssueClosed } from "./issue-closed-Dfw3QDyZ.js";
34
- import { n as shouldSkipDispatchAsMerged, t as init_merge_verification } from "./merge-verification-B3meGcXF.js";
35
- import { n as init_review_verdict_feedback, t as deliverReviewVerdictFeedback } from "./review-verdict-feedback-CMsIpTpy.js";
36
- import { n as reconcileTraefikNetworks, t as init_traefik_connect } from "./traefik-connect-BXqfOP4-.js";
37
- import { g as decideAgentAutonomousRedrive, r as coordinateSwarmSlots, y as listFeatureWorkspaces } from "./deacon-swarm-DmA3rJ7k.js";
38
- import { t as recordRecoveryFailure } from "./recovery-trip-l1Hsi37x.js";
39
- import { n as isExplicitNoResumeRequest, t as init_no_resume_mode } from "./no-resume-mode-BnInAFKs.js";
40
- import { n as reconcileClosedIssueAgents } from "./closed-issue-reaper-BaYQYF6w.js";
41
- import { n as init_label_reconciler, r as reconcilePipelineLabelsPatrol } from "./label-reconciler-CNf3Ylm3.js";
42
- import { a as spawnWorkAgentThroughAgentsEndpoint, i as reconcileOrphanProposedSpecs, o as triggerRebuildAndStart } from "./orphan-proposed-reconciler-AxAGUouN.js";
43
- import { n as reconcileIdleWorkspaceStacks } from "./idle-stack-reaper-BfL8HqYy.js";
44
- import { i as readTestVerdictArtifact, n as decideUnsignaledTestAction, r as init_test_verdict } from "./test-verdict-BRiSu7eW.js";
6
+ import { n as updateIssueRecord, t as init_record_update } from "./record-update-Crz74r-6.js";
7
+ import { D as killSession, E as isPaneDead, F as querySessionSync, H as sessionExistsSync, M as listSessions, R as sendKeys, V as sessionExists, i as capturePane, j as listSessionNames, k as listPaneValues, w as init_tmux, z as sendKeysAsync } from "./tmux-L5LgvGLp.js";
8
+ import { a as init_event_store, i as initEventStore } from "./event-store-TnWdydfB.js";
9
+ import { C as projectLegacySystemHealthSummary, t as init_src } from "./src-k039WVYY.js";
10
+ import { S as needsReviewDispatch, c as init_review_status, h as reviewGatesPassedSync, s as getReviewStatusSync, u as loadReviewStatuses, x as init_review_dispatch_decision, y as setReviewStatusSync } from "./review-status-DFRjDFef.js";
11
+ import { c as listAllAgentsSync, d as isTerminalIssueStage, o as init_agents, u as getIssueStageSync } from "./agents-DXdHmRTC.js";
12
+ import { $ as stopAgent, Bn as recordAgentFailure, Dn as getAgentDir, F as isContextOverflowTail, Gn as saveAgentStateSync, I as init_messaging, Jn as setAgentYieldedSync, L as messageAgent, Ln as markAgentRunningState, M as resumeAgent, Mn as init_agent_state, N as init_context_overflow, Q as init_termination, St as init_transcript_landing, Tn as clearYieldForResumeSync, Un as resetAgentFailureCount, Wn as saveAgentState, _r as init_codex_auth, a as listRunningAgentsSync, at as getConcurrencyLimits, dr as init_runtime_state, fr as saveAgentRuntimeState, ft as workResumeSlotsAvailable, hr as applyCodexAuthBurnFlag, ht as setCachedMemoryVerdict, i as listRunningAgents, jn as getAgentStateSync, kn as getAgentState, lr as getAgentRuntimeState, lt as resetPatrolDispatchBudget, mt as init_memory_verdict_cache, n as init_queries, ot as init_concurrency, pn as buildDefaultResumeContinueMessage, qn as setAgentPausedSync, r as listAgentStates, rt as describeRunningAgents, s as init_agents$1, st as releaseAdvancingSlot, tt as countRunningAgents, ur as getAgentRuntimeStateSync, ut as tryReserveAdvancingSlot, vr as paneShowsCodexAuthBurn, vt as deliverInitialPromptWithRetry, wn as clearAgentTroubledSync, xt as captureTranscriptUserRecordSnapshot } from "./queries-ZABd5aXP.js";
13
+ import { c as logDeaconEventSync, l as getRuntimeSnapshot, o as init_persistent_logger, s as logAgentLifecycleSync, u as init_agent_runtime_mirror } from "./session-history-XdS0JKp3.js";
14
+ import { i as resolveGitHubIssueSync, n as init_tracker_utils } from "./tracker-utils-CawsPSS2.js";
15
+ import { i as ensureInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-CXsfxslp.js";
16
+ import { c as init_review_status_sync, l as markWorkspaceStuck } from "./review-status-sync-DpAMD_WO.js";
17
+ import { i as readReviewStatusMap, n as init_review_status_source, t as classifyAdvancingSessionLifecycle } from "./review-status-source-CxuEjLGg.js";
18
+ import { m as readWorkspacePlanSync, o as init_io } from "./io-DQR9PMgS.js";
19
+ import { f as init_config, m as loadConfigSync$1, p as loadConfig$1 } from "./config-q4Gvd8dq.js";
20
+ import { T as stampBootReconciliation, h as setBootReconciliationDecision, l as isDeaconGloballyPaused, r as getBootReconciliationState, s as init_control_settings } from "./control-settings-D_odMIaC.js";
21
+ import { c as init_docker_stats, s as DockerStatsCollector } from "./stack-health-C-ifC7b0.js";
22
+ import { l as init_dag, o as getDispatchableItems } from "./dag-CJpgf9A3.js";
23
+ import { a as loadCloisterConfigSync, i as loadCloisterConfig, r as init_config$1 } from "./config-DeTsoZdR.js";
24
+ import { a as findRecreatedLegacyStatePaths, o as init_state_home } from "./state-home-CONQvZR0.js";
25
+ import { a as isAgentIdleForNudge, t as checkStuckAgentRemediation } from "./stuck-remediation-CKnIryGT.js";
26
+ import { n as __filename, r as init_esm_shims } from "./esm-shims-dTeNdq7X.js";
27
+ import { i as init_staleness, r as computeBuildStaleness } from "./staleness-BID1BKdr.js";
28
+ import { a as pidsWithCwdUnder, i as sweepAutoCloseOutCache, n as pruneTerminalStoppedAgents, r as getAutoCloseOutCanonicalState } from "./agent-gc-Dj2gncak.js";
29
+ import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-BXP6g75N.js";
30
+ import { r as surfaceIssueFeedbackNeedsYou, t as init_feedback_target } from "./feedback-target-DZ-iAnAa.js";
31
+ import { a as init_review_convoy_liveness, c as init_review_monitor, i as evaluateReviewConvoyLiveness, o as reviewTimestampMs, r as init_in_flight_guard, s as REVIEW_SUB_ROLES, t as createInFlightGuard } from "./in-flight-guard-BoWm66Kh.js";
32
+ import { H as getTmuxSessionName, J as parseReviewerSessionName, _ as getAllProjectSpecialistStatuses, t as init_specialists } from "./specialists-CwZHb5cb.js";
33
+ import { a as inferBranchFromWorkspace, i as findWorkspacePath, o as init_archive_planning } from "./archive-planning-BvDuWNMo.js";
34
+ import { A as withConcurrencyLimit, k as init_concurrency$1 } from "./github-app-CDPtGF7J.js";
35
+ import { n as init_issue_closed, r as isIssueClosed } from "./issue-closed-DtmJM0D0.js";
36
+ import { n as shouldSkipDispatchAsMerged, t as init_merge_verification } from "./merge-verification-CqnUzGEK.js";
37
+ import { n as init_review_verdict_feedback, t as deliverReviewVerdictFeedback } from "./review-verdict-feedback-CpUZl5aE.js";
38
+ import { n as reconcileTraefikNetworks, t as init_traefik_connect } from "./traefik-connect-C6mJckNs.js";
39
+ import { g as decideAgentAutonomousRedrive, r as coordinateSwarmSlots, y as listFeatureWorkspaces } from "./deacon-swarm-BryRr6AO.js";
40
+ import { t as recordRecoveryFailure } from "./recovery-trip-DkzJSej9.js";
41
+ import { n as isExplicitNoResumeRequest, t as init_no_resume_mode } from "./no-resume-mode-BWOSZjWd.js";
42
+ import { n as reconcileClosedIssueAgents } from "./closed-issue-reaper-CQ3kqha7.js";
43
+ import { n as init_label_reconciler, r as reconcilePipelineLabelsPatrol } from "./label-reconciler-Df1ZduPH.js";
44
+ import { a as spawnWorkAgentThroughAgentsEndpoint, i as reconcileOrphanProposedSpecs, o as triggerRebuildAndStart } from "./orphan-proposed-reconciler-xklgvNA7.js";
45
+ import { n as reconcileIdleWorkspaceStacks } from "./idle-stack-reaper-Yf34xXxY.js";
46
+ import { i as readTestVerdictArtifact, n as decideUnsignaledTestAction, r as init_test_verdict } from "./test-verdict-Cp5tljlJ.js";
45
47
  import { createRequire } from "node:module";
46
48
  import { join } from "node:path";
47
49
  import { Effect } from "effect";
@@ -50,13 +52,128 @@ import { dirname as dirname$1, join as join$1 } from "path";
50
52
  import { cpus, loadavg } from "os";
51
53
  import { cpus as cpus$1, freemem as freemem$1, homedir as homedir$1, loadavg as loadavg$1, platform as platform$1, totalmem as totalmem$1 } from "node:os";
52
54
  import { closeSync as closeSync$1, existsSync as existsSync$1, openSync as openSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, unlinkSync as unlinkSync$1, writeFileSync as writeFileSync$1 } from "node:fs";
53
- import { access, readFile } from "node:fs/promises";
55
+ import { readFile } from "node:fs/promises";
54
56
  import { readFile as readFile$1, readdir as readdir$1, writeFile as writeFile$1 } from "fs/promises";
55
57
  import { exec, execFile, spawn } from "node:child_process";
56
58
  import { promisify } from "node:util";
57
59
  import { exec as exec$1, execFile as execFile$1, spawn as spawn$1 } from "child_process";
58
60
  import { promisify as promisify$1 } from "util";
59
61
  import { layer } from "@effect/platform-node/NodeServices";
62
+ //#region ../../lib/agents/health.ts
63
+ init_paths();
64
+ init_errors();
65
+ init_activity_logger();
66
+ init_projects();
67
+ init_state_plane();
68
+ init_auto_commit();
69
+ init_record();
70
+ init_record_update();
71
+ init_tmux();
72
+ init_src();
73
+ init_agents();
74
+ init_agent_runtime_mirror();
75
+ init_persistent_logger();
76
+ init_internal_token();
77
+ init_review_status_sync();
78
+ init_review_status_source();
79
+ init_review_dispatch_decision();
80
+ init_review_status();
81
+ init_codex_auth();
82
+ init_runtime_state();
83
+ init_agent_state();
84
+ init_transcript_landing();
85
+ init_config$1();
86
+ init_memory_verdict_cache();
87
+ init_concurrency();
88
+ init_termination();
89
+ init_messaging();
90
+ init_context_overflow();
91
+ init_agents$1();
92
+ init_queries();
93
+ const STARTUP_GRACE_MS = 300 * 1e3;
94
+ const ACTIVITY_WARNING_MS = 900 * 1e3;
95
+ const ACTIVITY_STALLED_MS = 1800 * 1e3;
96
+ function reason$1(code, severity, message) {
97
+ return {
98
+ code,
99
+ domain: "agent",
100
+ severity,
101
+ message
102
+ };
103
+ }
104
+ function validTimestamp(value) {
105
+ if (!value) return null;
106
+ const timestamp = Date.parse(value);
107
+ return Number.isFinite(timestamp) ? timestamp : null;
108
+ }
109
+ function latestActivity(persisted, runtime) {
110
+ const candidates = [persisted.lastActivity, runtime?.lastActivity].map((value) => ({
111
+ value,
112
+ timestamp: validTimestamp(value)
113
+ })).filter((entry) => entry.value !== void 0 && entry.timestamp !== null);
114
+ if (candidates.length === 0) return void 0;
115
+ return candidates.reduce((latest, entry) => entry.timestamp > latest.timestamp ? entry : latest).value;
116
+ }
117
+ function agentKind(role) {
118
+ if (role === "work") return "work";
119
+ if (role === "plan") return "planning";
120
+ if (role === "review" || role === "test" || role === "ship") return "specialist";
121
+ return "other";
122
+ }
123
+ function intentionalInactive(state) {
124
+ return state.status === "stopped" || state.status === "completed" || state.paused === true || state.stoppedByUser === true || state.stoppedByPause === true;
125
+ }
126
+ function lifecycleFor(input, state) {
127
+ if (input.reviewLifecycle === "warm" || input.reviewLifecycle === "orphaned") return input.reviewLifecycle;
128
+ if (input.liveSessions.has(input.agentId) && !intentionalInactive(state)) return "active";
129
+ return input.reviewLifecycle ?? "unknown";
130
+ }
131
+ function buildSnapshot(input, state, status, reasons) {
132
+ const lastActivityAt = latestActivity(state, input.runtime);
133
+ const observations = input.observations;
134
+ return {
135
+ id: input.agentId,
136
+ ...state.issueId ? { issueId: state.issueId } : {},
137
+ ...state.role ? { role: state.role } : {},
138
+ kind: agentKind(state.role),
139
+ status,
140
+ lifecycle: lifecycleFor(input, state),
141
+ tmuxActive: input.liveSessions.has(input.agentId),
142
+ ...lastActivityAt ? { lastActivityAt } : {},
143
+ ...observations?.consecutiveFailures !== void 0 ? { consecutiveFailures: observations.consecutiveFailures } : state.consecutiveFailures !== void 0 ? { consecutiveFailures: state.consecutiveFailures } : {},
144
+ ...observations?.killCount !== void 0 ? { killCount: observations.killCount } : {},
145
+ ...observations && Object.prototype.hasOwnProperty.call(observations, "contextPercent") ? { contextPercent: observations.contextPercent ?? null } : {},
146
+ reasons
147
+ };
148
+ }
149
+ /**
150
+ * Classifies one resolved agent snapshot. The function is intentionally free of
151
+ * filesystem, tmux, review-status, and runtime-store imports so every caller
152
+ * supplies one coherent set of evidence and cycle-prone dashboard code remains
153
+ * a thin resolver adapter.
154
+ */
155
+ function classifyAgentHealth(input) {
156
+ if (input.persisted.status === "unavailable") return buildSnapshot(input, {}, "unavailable", [reason$1("agent.persisted_state.unavailable", "warning", input.persisted.reason)]);
157
+ const state = input.persisted.value;
158
+ if (input.runtime?.contextSaturatedAt) return buildSnapshot(input, state, "wedged", [reason$1("agent.context.saturated", "critical", "Context window exhausted; recovery is required.")]);
159
+ const startedAt = validTimestamp(state.startedAt);
160
+ const startupGraceElapsed = startedAt !== null && input.nowMs - startedAt >= STARTUP_GRACE_MS;
161
+ const expectsLiveSession = state.status === "running" || state.status === "starting";
162
+ if (!input.liveSessions.has(input.agentId) && expectsLiveSession && startupGraceElapsed) return buildSnapshot(input, state, "dead", [reason$1("agent.tmux.missing", "critical", "The persisted agent is running but its tmux session is missing.")]);
163
+ if (state.role === "work" && state.status === "running" && state.kickoffDelivered === false && startupGraceElapsed) return buildSnapshot(input, state, "stalled", [reason$1("agent.kickoff.not_delivered", "warning", "Work agent running with no kickoff delivered since spawn")]);
164
+ if (input.runtime?.state === "waiting-on-human") return buildSnapshot(input, state, "waiting", [reason$1("agent.runtime.waiting_on_human", "info", "The agent is waiting for operator input.")]);
165
+ if (input.reviewLifecycle === "warm" || input.reviewLifecycle === "orphaned" || input.runtime?.state === "idle" || input.runtime?.state === "suspended" || input.runtime?.state === "stopped" || intentionalInactive(state)) return buildSnapshot(input, state, "idle", []);
166
+ if (input.runtime?.state === "active") {
167
+ const lastActivityMs = validTimestamp(latestActivity(state, input.runtime));
168
+ if (lastActivityMs !== null) {
169
+ const inactivityMs = Math.max(0, input.nowMs - lastActivityMs);
170
+ if (inactivityMs >= ACTIVITY_STALLED_MS) return buildSnapshot(input, state, "stalled", [reason$1("agent.runtime.inactive.stalled", "warning", `The active agent has produced no activity for ${Math.round(inactivityMs / 6e4)} minutes.`)]);
171
+ if (inactivityMs >= ACTIVITY_WARNING_MS) return buildSnapshot(input, state, "warning", [reason$1("agent.runtime.inactive.warning", "warning", `The active agent has produced no activity for ${Math.round(inactivityMs / 6e4)} minutes.`)]);
172
+ }
173
+ }
174
+ return buildSnapshot(input, state, "healthy", []);
175
+ }
176
+ //#endregion
60
177
  //#region ../../../node_modules/.bun/undici@7.25.0/node_modules/undici/lib/core/symbols.js
61
178
  var require_symbols = /* @__PURE__ */ __commonJSMin(((exports, module) => {
62
179
  module.exports = {
@@ -21468,9 +21585,7 @@ var require_eventsource = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21468
21585
  defaultReconnectionTime
21469
21586
  };
21470
21587
  }));
21471
- //#endregion
21472
- //#region ../../../node_modules/.bun/undici@7.25.0/node_modules/undici/index.js
21473
- var require_undici = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21588
+ new ((/* @__PURE__ */ __commonJSMin(((exports, module) => {
21474
21589
  init_esm_shims();
21475
21590
  const Client = require_client();
21476
21591
  const Dispatcher = require_dispatcher();
@@ -21636,37 +21751,7 @@ var require_undici = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21636
21751
  globalThis.EventSource = module.exports.EventSource;
21637
21752
  }
21638
21753
  module.exports.install = install;
21639
- }));
21640
- //#endregion
21641
- //#region ../../../node_modules/.bun/smee-client@5.0.0/node_modules/smee-client/index.js
21642
- init_paths();
21643
- init_errors();
21644
- init_activity_logger();
21645
- init_projects();
21646
- init_state_plane();
21647
- init_auto_commit();
21648
- init_record();
21649
- init_record_update();
21650
- init_tmux();
21651
- init_agents();
21652
- init_persistent_logger();
21653
- init_internal_token();
21654
- init_review_status_sync();
21655
- init_review_dispatch_decision();
21656
- init_review_status();
21657
- init_codex_auth();
21658
- init_runtime_state();
21659
- init_agent_state();
21660
- init_transcript_landing();
21661
- init_config$1();
21662
- init_memory_verdict_cache();
21663
- init_concurrency();
21664
- init_termination();
21665
- init_messaging();
21666
- init_context_overflow();
21667
- init_agents$1();
21668
- init_queries();
21669
- new (require_undici()).EnvHttpProxyAgent();
21754
+ })))()).EnvHttpProxyAgent();
21670
21755
  //#endregion
21671
21756
  //#region ../../lib/smee.ts
21672
21757
  /**
@@ -21849,35 +21934,881 @@ function startSmeeProcessSync() {
21849
21934
  console.log(`[smee] Started process (PID ${child.pid}) relaying to ${target}`);
21850
21935
  }
21851
21936
  //#endregion
21852
- //#region services/system-health-service.ts
21853
- init_docker_stats();
21937
+ //#region ../../lib/system-health/config.ts
21854
21938
  init_build_info();
21855
- init_staleness();
21939
+ init_docker_stats();
21940
+ init_defaults();
21941
+ init_load();
21942
+ const GIB$2 = 1024 ** 3;
21943
+ const SYSTEM_HEALTH_DEFAULTS = Object.freeze({
21944
+ pollSeconds: 15,
21945
+ memoryWarnGb: DEFAULT_CONFIG$1.resources.memoryWarnGb,
21946
+ memoryBlockGb: DEFAULT_CONFIG$1.resources.memoryBlockGb,
21947
+ agentWarnCount: DEFAULT_CONFIG$1.resources.agentWarnCount,
21948
+ agentBlockCount: DEFAULT_CONFIG$1.resources.agentBlockCount,
21949
+ swapUsedWarningPercent: 20,
21950
+ swapUsedCriticalPercent: 50,
21951
+ cpuLoadWarningPerCore: 1,
21952
+ cpuLoadCriticalPerCore: 1.5,
21953
+ overcommitWarningPercent: 150,
21954
+ overcommitCriticalPercent: 200
21955
+ });
21956
+ function finiteNonnegative(value) {
21957
+ if (value === "" || value == null) return null;
21958
+ const parsed = typeof value === "number" ? value : Number(value);
21959
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : null;
21960
+ }
21961
+ /**
21962
+ * Normalizes every health threshold in one pass. Any invalid value or reversed
21963
+ * pair falls back to its named defaults, and the caller receives one warning
21964
+ * describing the complete fallback rather than one warning per field.
21965
+ */
21966
+ function normalizeSystemHealthThresholds(input, warn = console.warn) {
21967
+ const invalid = [];
21968
+ const scalar = (name, fallback, minimum = 0) => {
21969
+ const value = finiteNonnegative(input[name]);
21970
+ if (value == null || value < minimum) {
21971
+ invalid.push(String(name));
21972
+ return fallback;
21973
+ }
21974
+ return value;
21975
+ };
21976
+ const increasingPair = (warningName, criticalName, warningDefault, criticalDefault) => {
21977
+ const warning = finiteNonnegative(input[warningName]);
21978
+ const critical = finiteNonnegative(input[criticalName]);
21979
+ if (warning == null || critical == null || warning > critical) {
21980
+ invalid.push(`${String(warningName)}/${String(criticalName)}`);
21981
+ return [warningDefault, criticalDefault];
21982
+ }
21983
+ return [warning, critical];
21984
+ };
21985
+ const decreasingPair = (warningName, criticalName, warningDefault, criticalDefault) => {
21986
+ const warning = finiteNonnegative(input[warningName]);
21987
+ const critical = finiteNonnegative(input[criticalName]);
21988
+ if (warning == null || critical == null || warning < critical) {
21989
+ invalid.push(`${String(warningName)}/${String(criticalName)}`);
21990
+ return [warningDefault, criticalDefault];
21991
+ }
21992
+ return [warning, critical];
21993
+ };
21994
+ const [memoryWarnGb, memoryBlockGb] = decreasingPair("memoryWarnGb", "memoryBlockGb", SYSTEM_HEALTH_DEFAULTS.memoryWarnGb, SYSTEM_HEALTH_DEFAULTS.memoryBlockGb);
21995
+ const [agentWarnCountValue, agentBlockCountValue] = increasingPair("agentWarnCount", "agentBlockCount", SYSTEM_HEALTH_DEFAULTS.agentWarnCount, SYSTEM_HEALTH_DEFAULTS.agentBlockCount);
21996
+ const [swapUsedWarningPercent, swapUsedCriticalPercent] = increasingPair("swapUsedWarningPercent", "swapUsedCriticalPercent", SYSTEM_HEALTH_DEFAULTS.swapUsedWarningPercent, SYSTEM_HEALTH_DEFAULTS.swapUsedCriticalPercent);
21997
+ const [cpuLoadWarningPerCore, cpuLoadCriticalPerCore] = increasingPair("cpuLoadWarningPerCore", "cpuLoadCriticalPerCore", SYSTEM_HEALTH_DEFAULTS.cpuLoadWarningPerCore, SYSTEM_HEALTH_DEFAULTS.cpuLoadCriticalPerCore);
21998
+ const [overcommitWarningPercent, overcommitCriticalPercent] = increasingPair("overcommitWarningPercent", "overcommitCriticalPercent", SYSTEM_HEALTH_DEFAULTS.overcommitWarningPercent, SYSTEM_HEALTH_DEFAULTS.overcommitCriticalPercent);
21999
+ const pollSeconds = scalar("pollSeconds", SYSTEM_HEALTH_DEFAULTS.pollSeconds, 1);
22000
+ const agentWarnCount = Math.max(1, Math.floor(agentWarnCountValue));
22001
+ const agentBlockCount = Math.max(1, Math.floor(agentBlockCountValue));
22002
+ if (invalid.length > 0) warn(`[system-health] Invalid thresholds (${invalid.join(", ")}); using named defaults.`);
22003
+ return {
22004
+ pollSeconds: Math.max(1, Math.floor(pollSeconds)),
22005
+ resources: {
22006
+ memoryWarnGb,
22007
+ memoryBlockGb,
22008
+ agentWarnCount,
22009
+ agentBlockCount
22010
+ },
22011
+ thresholds: {
22012
+ memoryAvailableWarningBytes: memoryWarnGb * GIB$2,
22013
+ memoryAvailableCriticalBytes: memoryBlockGb * GIB$2,
22014
+ swapUsedWarningPercent,
22015
+ swapUsedCriticalPercent,
22016
+ cpuLoadWarningPerCore,
22017
+ cpuLoadCriticalPerCore,
22018
+ overcommitWarningPercent,
22019
+ overcommitCriticalPercent
22020
+ }
22021
+ };
22022
+ }
22023
+ function resolveSystemHealthConfig(options = {}) {
22024
+ const resources = options.resources ?? loadConfigSync().config.resources;
22025
+ const env = options.env ?? process.env;
22026
+ return normalizeSystemHealthThresholds({
22027
+ pollSeconds: env["PAN_HEALTH_POLL_SECONDS"] ?? SYSTEM_HEALTH_DEFAULTS.pollSeconds,
22028
+ memoryWarnGb: env["PAN_MEMORY_WARN_GB"] ?? resources.memoryWarnGb,
22029
+ memoryBlockGb: env["PAN_MEMORY_BLOCK_GB"] ?? resources.memoryBlockGb,
22030
+ agentWarnCount: env["PAN_AGENT_WARN_COUNT"] ?? resources.agentWarnCount,
22031
+ agentBlockCount: env["PAN_AGENT_BLOCK_COUNT"] ?? resources.agentBlockCount,
22032
+ swapUsedWarningPercent: env["PAN_HEALTH_SWAP_WARN_PERCENT"] ?? SYSTEM_HEALTH_DEFAULTS.swapUsedWarningPercent,
22033
+ swapUsedCriticalPercent: env["PAN_HEALTH_SWAP_CRITICAL_PERCENT"] ?? SYSTEM_HEALTH_DEFAULTS.swapUsedCriticalPercent,
22034
+ cpuLoadWarningPerCore: env["PAN_HEALTH_LOAD_WARN_PER_CORE"] ?? SYSTEM_HEALTH_DEFAULTS.cpuLoadWarningPerCore,
22035
+ cpuLoadCriticalPerCore: env["PAN_HEALTH_LOAD_CRITICAL_PER_CORE"] ?? SYSTEM_HEALTH_DEFAULTS.cpuLoadCriticalPerCore,
22036
+ overcommitWarningPercent: env["PAN_HEALTH_OVERCOMMIT_WARN_PERCENT"] ?? SYSTEM_HEALTH_DEFAULTS.overcommitWarningPercent,
22037
+ overcommitCriticalPercent: env["PAN_HEALTH_OVERCOMMIT_CRITICAL_PERCENT"] ?? SYSTEM_HEALTH_DEFAULTS.overcommitCriticalPercent
22038
+ }, options.warn);
22039
+ }
22040
+ //#endregion
22041
+ //#region ../../lib/system-health/types.ts
22042
+ function available(value) {
22043
+ return {
22044
+ status: "available",
22045
+ value
22046
+ };
22047
+ }
22048
+ function unavailable(reason) {
22049
+ return {
22050
+ status: "unavailable",
22051
+ reason
22052
+ };
22053
+ }
22054
+ //#endregion
22055
+ //#region ../../lib/system-health/darwin.ts
22056
+ const execFileAsync$8 = promisify(execFile);
22057
+ const COMMAND_TIMEOUT_MS = 5e3;
22058
+ const MIB = 1024 ** 2;
22059
+ const DARWIN_MEMORY_PRESSURE_DEFAULTS = Object.freeze({
22060
+ warningFreePercent: 10,
22061
+ criticalFreePercent: 5,
22062
+ swapActivityWarningBytesPerMinute: 64 * MIB,
22063
+ swapActivityCriticalBytesPerMinute: 256 * MIB
22064
+ });
22065
+ function parseDarwinMemoryPressure(content) {
22066
+ for (const pattern of [/System-wide memory free percentage:\s*([\d.]+)\s*%/i, /System-wide memory free percentage\s*=\s*([\d.]+)\s*%?/i]) {
22067
+ const match = content.match(pattern);
22068
+ if (!match) continue;
22069
+ const value = Number(match[1]);
22070
+ if (Number.isFinite(value) && value >= 0 && value <= 100) return value;
22071
+ }
22072
+ return null;
22073
+ }
22074
+ function parseDarwinVmStat(content) {
22075
+ const pageSizeMatch = content.match(/page size of\s+(\d+)\s+bytes/i);
22076
+ if (!pageSizeMatch) return null;
22077
+ const pageSizeBytes = Number(pageSizeMatch[1]);
22078
+ if (!Number.isFinite(pageSizeBytes) || pageSizeBytes <= 0) return null;
22079
+ const pages = /* @__PURE__ */ new Map();
22080
+ for (const line of content.split("\n")) {
22081
+ const match = line.match(/^([^:]+):\s+(\d+)\.?$/);
22082
+ if (!match) continue;
22083
+ const value = Number(match[2]);
22084
+ if (Number.isFinite(value)) pages.set(match[1].trim(), value);
22085
+ }
22086
+ const availablePageNames = [
22087
+ "Pages free",
22088
+ "Pages inactive",
22089
+ "Pages speculative"
22090
+ ];
22091
+ const availablePages = availablePageNames.every((name) => pages.has(name)) ? availablePageNames.reduce((sum, name) => sum + pages.get(name), 0) : void 0;
22092
+ const swapIn = pages.get("Swapins");
22093
+ const swapOut = pages.get("Swapouts");
22094
+ return {
22095
+ pageSizeBytes,
22096
+ availableMemoryBytes: availablePages == null ? void 0 : availablePages * pageSizeBytes,
22097
+ swap: swapIn == null || swapOut == null ? void 0 : {
22098
+ pagesIn: swapIn,
22099
+ pagesOut: swapOut
22100
+ }
22101
+ };
22102
+ }
22103
+ function unitBytes(value, unit) {
22104
+ const parsed = Number(value);
22105
+ if (!Number.isFinite(parsed) || parsed < 0) return null;
22106
+ const multiplier = unit.toUpperCase() === "G" ? 1024 ** 3 : unit.toUpperCase() === "K" ? 1024 : MIB;
22107
+ return Math.round(parsed * multiplier);
22108
+ }
22109
+ function parseDarwinSwapUsage(content) {
22110
+ const total = content.match(/total\s*=\s*([\d.]+)([KMG])/i);
22111
+ const used = content.match(/used\s*=\s*([\d.]+)([KMG])/i);
22112
+ const free = content.match(/free\s*=\s*([\d.]+)([KMG])/i);
22113
+ if (!total || !used || !free) return null;
22114
+ const totalBytes = unitBytes(total[1], total[2]);
22115
+ const usedBytes = unitBytes(used[1], used[2]);
22116
+ const freeBytes = unitBytes(free[1], free[2]);
22117
+ return totalBytes == null || usedBytes == null || freeBytes == null ? null : {
22118
+ totalBytes,
22119
+ usedBytes,
22120
+ freeBytes
22121
+ };
22122
+ }
22123
+ function aggregateDarwinCpuCounters(cpuInfo) {
22124
+ if (cpuInfo.length === 0) return null;
22125
+ let idle = 0;
22126
+ let total = 0;
22127
+ for (const cpu of cpuInfo) {
22128
+ const values = Object.values(cpu.times);
22129
+ if (values.some((value) => !Number.isFinite(value) || value < 0)) return null;
22130
+ idle += cpu.times.idle;
22131
+ total += values.reduce((sum, value) => sum + value, 0);
22132
+ }
22133
+ return {
22134
+ idle,
22135
+ total
22136
+ };
22137
+ }
22138
+ function computeCpuPercent$1(current, previous) {
22139
+ if (!previous) return unavailable("A previous CPU time sample is required.");
22140
+ const totalDelta = current.total - previous.total;
22141
+ const idleDelta = current.idle - previous.idle;
22142
+ if (totalDelta <= 0 || idleDelta < 0 || idleDelta > totalDelta) return unavailable("CPU times did not advance monotonically.");
22143
+ return available(Math.round((totalDelta - idleDelta) / totalDelta * 1e3) / 10);
22144
+ }
22145
+ function computeSwapActivity(current, previous, elapsedMs, pageSizeBytes) {
22146
+ if (!previous) return unavailable("A previous swap counter sample is required.");
22147
+ const pages = current.pagesIn - previous.pagesIn + current.pagesOut - previous.pagesOut;
22148
+ if (pages < 0 || elapsedMs <= 0) return unavailable("Swap counters or sample timing were invalid.");
22149
+ return available(Math.round(pages * pageSizeBytes * 6e4 / elapsedMs));
22150
+ }
22151
+ function percent$1(part, total) {
22152
+ if (total <= 0) return 0;
22153
+ return Math.round(part / total * 1e3) / 10;
22154
+ }
22155
+ const defaultAdapters$1 = {
22156
+ execFile: async (command, args, timeoutMs) => {
22157
+ const { stdout } = await execFileAsync$8(command, [...args], {
22158
+ encoding: "utf-8",
22159
+ timeout: timeoutMs
22160
+ });
22161
+ return stdout;
22162
+ },
22163
+ cpus: cpus$1,
22164
+ loadAverage1m: () => loadavg$1()[0] ?? 0,
22165
+ totalMemoryBytes: totalmem$1,
22166
+ now: () => Date.now()
22167
+ };
22168
+ async function command(adapters, executable, args) {
22169
+ try {
22170
+ return await adapters.execFile(executable, args, COMMAND_TIMEOUT_MS);
22171
+ } catch {
22172
+ return null;
22173
+ }
22174
+ }
22175
+ function createDarwinHostHealthCollector(adapters = defaultAdapters$1) {
22176
+ return {
22177
+ platform: "darwin",
22178
+ async sample(previous) {
22179
+ const sampledAtMs = adapters.now();
22180
+ const [pressureOutput, vmStatOutput, swapOutput] = await Promise.all([
22181
+ command(adapters, "memory_pressure", ["-Q"]),
22182
+ command(adapters, "vm_stat", []),
22183
+ command(adapters, "sysctl", ["-n", "vm.swapusage"])
22184
+ ]);
22185
+ const pressureFreePercent = pressureOutput == null ? null : parseDarwinMemoryPressure(pressureOutput);
22186
+ const vmStat = vmStatOutput == null ? null : parseDarwinVmStat(vmStatOutput);
22187
+ const swapUsage = swapOutput == null ? null : parseDarwinSwapUsage(swapOutput);
22188
+ const cpuInfo = adapters.cpus();
22189
+ const cpuCounters = aggregateDarwinCpuCounters(cpuInfo);
22190
+ const totalMemoryBytes = adapters.totalMemoryBytes();
22191
+ const availableMemoryBytes = pressureFreePercent != null ? Math.round(totalMemoryBytes * pressureFreePercent / 100) : vmStat?.availableMemoryBytes ?? null;
22192
+ const usedMemoryBytes = Number.isFinite(totalMemoryBytes) && availableMemoryBytes != null ? Math.max(totalMemoryBytes - availableMemoryBytes, 0) : null;
22193
+ const loadAverage1m = adapters.loadAverage1m();
22194
+ const elapsedMs = previous ? sampledAtMs - previous.sampledAtMs : 0;
22195
+ return {
22196
+ platform: "darwin",
22197
+ sampledAtMs,
22198
+ cpuPercent: cpuCounters ? computeCpuPercent$1(cpuCounters, previous?.counters.cpu) : unavailable("macOS CPU times are unavailable."),
22199
+ loadAverage1m: Number.isFinite(loadAverage1m) && loadAverage1m >= 0 ? available(loadAverage1m) : unavailable("The one-minute load average is unavailable."),
22200
+ loadPerCore1m: Number.isFinite(loadAverage1m) && loadAverage1m >= 0 && cpuInfo.length > 0 ? available(Math.round(loadAverage1m / cpuInfo.length * 100) / 100) : unavailable("Load average or CPU core count is unavailable."),
22201
+ totalMemoryBytes: Number.isFinite(totalMemoryBytes) && totalMemoryBytes > 0 ? available(totalMemoryBytes) : unavailable("Total memory is unavailable."),
22202
+ usedMemoryBytes: usedMemoryBytes == null ? unavailable("Used memory cannot be derived.") : available(usedMemoryBytes),
22203
+ availableMemoryBytes: availableMemoryBytes == null ? unavailable("Available memory is unavailable.") : available(availableMemoryBytes),
22204
+ memoryUsedPercent: usedMemoryBytes == null ? unavailable("Memory utilization cannot be derived.") : available(percent$1(usedMemoryBytes, totalMemoryBytes)),
22205
+ memoryPressureSomeAvg10: unavailable("macOS does not expose Linux memory PSI."),
22206
+ memoryPressureFullAvg10: unavailable("macOS does not expose Linux memory PSI."),
22207
+ memoryPressureFreePercent: pressureFreePercent == null ? unavailable("memory_pressure did not report a recognized free percentage.") : available(pressureFreePercent),
22208
+ swapTotalBytes: swapUsage ? available(swapUsage.totalBytes) : unavailable("vm.swapusage is unavailable."),
22209
+ swapUsedBytes: swapUsage ? available(swapUsage.usedBytes) : unavailable("vm.swapusage is unavailable."),
22210
+ swapUsedPercent: swapUsage ? available(percent$1(swapUsage.usedBytes, swapUsage.totalBytes)) : unavailable("vm.swapusage is unavailable."),
22211
+ swapActivityBytesPerMinute: vmStat?.swap ? computeSwapActivity(vmStat.swap, previous?.counters.swap, elapsedMs, vmStat.pageSizeBytes) : unavailable("vm_stat swap activity counters are unavailable."),
22212
+ committedMemoryBytes: unavailable("macOS does not expose Linux Committed_AS."),
22213
+ commitLimitBytes: unavailable("macOS does not expose Linux CommitLimit."),
22214
+ virtualCommitmentPercent: unavailable("macOS virtual commitment is unavailable."),
22215
+ counters: {
22216
+ cpu: cpuCounters,
22217
+ swap: vmStat?.swap ?? null
22218
+ }
22219
+ };
22220
+ }
22221
+ };
22222
+ }
22223
+ //#endregion
22224
+ //#region ../../lib/system-health/linux.ts
22225
+ const execFileAsync$7 = promisify(execFile);
22226
+ const KB$1 = 1024;
22227
+ const LINUX_MEMORY_PRESSURE_DEFAULTS = Object.freeze({
22228
+ someWarningAvg10: 5,
22229
+ fullCriticalAvg10: 1,
22230
+ swapActivityWarningBytesPerMinute: 64 * 1024 ** 2,
22231
+ swapActivityCriticalBytesPerMinute: 256 * 1024 ** 2
22232
+ });
22233
+ function parseMemInfo(content) {
22234
+ const values = /* @__PURE__ */ new Map();
22235
+ for (const line of content.split("\n")) {
22236
+ const match = line.match(/^(\w+):\s+(\d+)\s+kB$/);
22237
+ if (!match) continue;
22238
+ const value = Number(match[2]);
22239
+ if (Number.isFinite(value)) values.set(match[1], value * KB$1);
22240
+ }
22241
+ return {
22242
+ memTotalBytes: values.get("MemTotal"),
22243
+ memAvailableBytes: values.get("MemAvailable"),
22244
+ swapTotalBytes: values.get("SwapTotal"),
22245
+ swapFreeBytes: values.get("SwapFree"),
22246
+ committedMemoryBytes: values.get("Committed_AS"),
22247
+ commitLimitBytes: values.get("CommitLimit")
22248
+ };
22249
+ }
22250
+ function parseProcStat(content) {
22251
+ const lines = content.split("\n");
22252
+ const cpuLine = lines.find((line) => line.startsWith("cpu "));
22253
+ if (!cpuLine) return null;
22254
+ const values = cpuLine.trim().split(/\s+/).slice(1).map(Number);
22255
+ if (values.length < 4 || values.some((value) => !Number.isFinite(value))) return null;
22256
+ const idle = values[3] + (values[4] ?? 0);
22257
+ const total = values.reduce((sum, value) => sum + value, 0);
22258
+ const coreCount = lines.filter((line) => /^cpu\d+\s/.test(line)).length;
22259
+ if (total < 0 || idle < 0) return null;
22260
+ return {
22261
+ cpu: {
22262
+ idle,
22263
+ total
22264
+ },
22265
+ coreCount: Math.max(coreCount, 1)
22266
+ };
22267
+ }
22268
+ function parseMemoryPressure(content) {
22269
+ const result = {};
22270
+ for (const line of content.split("\n")) {
22271
+ const match = line.match(/^(some|full)\s+.*\bavg10=([^\s]+)/);
22272
+ if (!match) continue;
22273
+ const value = Number(match[2]);
22274
+ if (!Number.isFinite(value) || value < 0) continue;
22275
+ if (match[1] === "some") result.someAvg10 = value;
22276
+ if (match[1] === "full") result.fullAvg10 = value;
22277
+ }
22278
+ return result;
22279
+ }
22280
+ function parseVmstat(content) {
22281
+ let pagesIn = null;
22282
+ let pagesOut = null;
22283
+ for (const line of content.split("\n")) {
22284
+ const match = line.match(/^(pswpin|pswpout)\s+(\d+)$/);
22285
+ if (!match) continue;
22286
+ const value = Number(match[2]);
22287
+ if (!Number.isFinite(value)) continue;
22288
+ if (match[1] === "pswpin") pagesIn = value;
22289
+ if (match[1] === "pswpout") pagesOut = value;
22290
+ }
22291
+ return pagesIn == null || pagesOut == null ? null : {
22292
+ pagesIn,
22293
+ pagesOut
22294
+ };
22295
+ }
22296
+ function parseLoadAverage(content) {
22297
+ const value = Number(content.trim().split(/\s+/)[0]);
22298
+ return Number.isFinite(value) && value >= 0 ? value : null;
22299
+ }
22300
+ function computeCpuPercent(current, previous) {
22301
+ if (!previous) return unavailable("A previous CPU counter sample is required.");
22302
+ const totalDelta = current.total - previous.total;
22303
+ const idleDelta = current.idle - previous.idle;
22304
+ if (totalDelta <= 0 || idleDelta < 0 || idleDelta > totalDelta) return unavailable("CPU counters did not advance monotonically.");
22305
+ return available(Math.round((totalDelta - idleDelta) / totalDelta * 1e3) / 10);
22306
+ }
22307
+ function computeSwapActivityBytesPerMinute(current, previous, elapsedMs, pageSizeBytes) {
22308
+ if (!previous) return unavailable("A previous swap counter sample is required.");
22309
+ const pageDelta = current.pagesIn - previous.pagesIn + current.pagesOut - previous.pagesOut;
22310
+ if (pageDelta < 0 || elapsedMs <= 0 || !Number.isFinite(pageSizeBytes) || pageSizeBytes <= 0) return unavailable("Swap counters or sample timing were invalid.");
22311
+ return available(Math.round(pageDelta * pageSizeBytes * 6e4 / elapsedMs));
22312
+ }
22313
+ const defaultAdapters = {
22314
+ readFile: (path) => readFile(path, "utf-8"),
22315
+ readPageSizeBytes: async () => {
22316
+ const { stdout } = await execFileAsync$7("getconf", ["PAGESIZE"], {
22317
+ encoding: "utf-8",
22318
+ timeout: 5e3
22319
+ });
22320
+ const value = Number(stdout.trim());
22321
+ if (!Number.isFinite(value) || value <= 0) throw new Error("getconf returned an invalid page size");
22322
+ return value;
22323
+ },
22324
+ now: () => Date.now()
22325
+ };
22326
+ async function readParsed(adapters, path, parse) {
22327
+ try {
22328
+ return parse(await adapters.readFile(path));
22329
+ } catch {
22330
+ return null;
22331
+ }
22332
+ }
22333
+ function percent(part, total) {
22334
+ if (total <= 0) return 0;
22335
+ return Math.round(part / total * 1e3) / 10;
22336
+ }
22337
+ function createLinuxHostHealthCollector(adapters = defaultAdapters) {
22338
+ return {
22339
+ platform: "linux",
22340
+ async sample(previous) {
22341
+ const sampledAtMs = adapters.now();
22342
+ const [memInfo, procStat, pressure, vmstat, loadAverage, pageSizeBytes] = await Promise.all([
22343
+ readParsed(adapters, "/proc/meminfo", parseMemInfo),
22344
+ readParsed(adapters, "/proc/stat", parseProcStat),
22345
+ readParsed(adapters, "/proc/pressure/memory", parseMemoryPressure),
22346
+ readParsed(adapters, "/proc/vmstat", parseVmstat),
22347
+ readParsed(adapters, "/proc/loadavg", parseLoadAverage),
22348
+ adapters.readPageSizeBytes().catch(() => null)
22349
+ ]);
22350
+ const totalMemoryBytes = memInfo?.memTotalBytes;
22351
+ const availableMemoryBytes = memInfo?.memAvailableBytes;
22352
+ const usedMemoryBytes = totalMemoryBytes != null && availableMemoryBytes != null ? Math.max(totalMemoryBytes - availableMemoryBytes, 0) : null;
22353
+ const swapTotalBytes = memInfo?.swapTotalBytes;
22354
+ const swapFreeBytes = memInfo?.swapFreeBytes;
22355
+ const swapUsedBytes = swapTotalBytes != null && swapFreeBytes != null ? Math.max(swapTotalBytes - swapFreeBytes, 0) : null;
22356
+ const committedMemoryBytes = memInfo?.committedMemoryBytes;
22357
+ const commitLimitBytes = memInfo?.commitLimitBytes;
22358
+ const cpuCounters = procStat?.cpu ?? null;
22359
+ const swapCounters = vmstat ?? null;
22360
+ const elapsedMs = previous ? sampledAtMs - previous.sampledAtMs : 0;
22361
+ return {
22362
+ platform: "linux",
22363
+ sampledAtMs,
22364
+ cpuPercent: cpuCounters ? computeCpuPercent(cpuCounters, previous?.counters.cpu) : unavailable("The aggregate CPU counters are unavailable."),
22365
+ loadAverage1m: loadAverage == null ? unavailable("The one-minute load average is unavailable.") : available(loadAverage),
22366
+ loadPerCore1m: loadAverage == null || !procStat ? unavailable("Load average or CPU core count is unavailable.") : available(Math.round(loadAverage / procStat.coreCount * 100) / 100),
22367
+ totalMemoryBytes: totalMemoryBytes == null ? unavailable("MemTotal is unavailable.") : available(totalMemoryBytes),
22368
+ usedMemoryBytes: usedMemoryBytes == null ? unavailable("Used memory cannot be derived without MemTotal and MemAvailable.") : available(usedMemoryBytes),
22369
+ availableMemoryBytes: availableMemoryBytes == null ? unavailable("MemAvailable is unavailable.") : available(availableMemoryBytes),
22370
+ memoryUsedPercent: usedMemoryBytes == null || totalMemoryBytes == null ? unavailable("Memory utilization cannot be derived.") : available(percent(usedMemoryBytes, totalMemoryBytes)),
22371
+ memoryPressureSomeAvg10: pressure?.someAvg10 == null ? unavailable("Linux memory PSI some.avg10 is unavailable.") : available(pressure.someAvg10),
22372
+ memoryPressureFullAvg10: pressure?.fullAvg10 == null ? unavailable("Linux memory PSI full.avg10 is unavailable.") : available(pressure.fullAvg10),
22373
+ memoryPressureFreePercent: unavailable("Linux reports memory pressure through PSI."),
22374
+ swapTotalBytes: swapTotalBytes == null ? unavailable("SwapTotal is unavailable.") : available(swapTotalBytes),
22375
+ swapUsedBytes: swapUsedBytes == null ? unavailable("Swap usage cannot be derived without SwapTotal and SwapFree.") : available(swapUsedBytes),
22376
+ swapUsedPercent: swapUsedBytes == null || swapTotalBytes == null ? unavailable("Swap utilization cannot be derived.") : available(percent(swapUsedBytes, swapTotalBytes)),
22377
+ swapActivityBytesPerMinute: swapCounters && pageSizeBytes != null ? computeSwapActivityBytesPerMinute(swapCounters, previous?.counters.swap, elapsedMs, pageSizeBytes) : unavailable("Linux swap activity counters are unavailable."),
22378
+ committedMemoryBytes: committedMemoryBytes == null ? unavailable("Committed_AS is unavailable.") : available(committedMemoryBytes),
22379
+ commitLimitBytes: commitLimitBytes == null ? unavailable("CommitLimit is unavailable.") : available(commitLimitBytes),
22380
+ virtualCommitmentPercent: committedMemoryBytes == null || commitLimitBytes == null ? unavailable("Virtual commitment cannot be derived.") : available(percent(committedMemoryBytes, commitLimitBytes)),
22381
+ counters: {
22382
+ cpu: cpuCounters,
22383
+ swap: swapCounters
22384
+ }
22385
+ };
22386
+ }
22387
+ };
22388
+ }
22389
+ //#endregion
22390
+ //#region ../../lib/system-health/collector.ts
22391
+ /**
22392
+ * Selects the platform host-health collector. Linux and macOS expose native
22393
+ * current-pressure signals; unsupported platforms return unavailable signals
22394
+ * so callers never mistake missing measurements for measured zeroes.
22395
+ */
22396
+ function createUnsupportedCollector(platform = "unsupported") {
22397
+ const signal = () => unavailable("Host health collection is unsupported on this platform.");
22398
+ return {
22399
+ platform,
22400
+ async sample() {
22401
+ return {
22402
+ platform,
22403
+ sampledAtMs: Date.now(),
22404
+ cpuPercent: signal(),
22405
+ loadAverage1m: signal(),
22406
+ loadPerCore1m: signal(),
22407
+ totalMemoryBytes: signal(),
22408
+ usedMemoryBytes: signal(),
22409
+ availableMemoryBytes: signal(),
22410
+ memoryUsedPercent: signal(),
22411
+ memoryPressureSomeAvg10: signal(),
22412
+ memoryPressureFullAvg10: signal(),
22413
+ memoryPressureFreePercent: signal(),
22414
+ swapTotalBytes: signal(),
22415
+ swapUsedBytes: signal(),
22416
+ swapUsedPercent: signal(),
22417
+ swapActivityBytesPerMinute: signal(),
22418
+ committedMemoryBytes: signal(),
22419
+ commitLimitBytes: signal(),
22420
+ virtualCommitmentPercent: signal(),
22421
+ counters: {
22422
+ cpu: null,
22423
+ swap: null
22424
+ }
22425
+ };
22426
+ }
22427
+ };
22428
+ }
22429
+ function createHostHealthCollector(selection = {}) {
22430
+ const platform = selection.platform ?? platform$1();
22431
+ if (platform === "linux") return selection.linux ?? createLinuxHostHealthCollector();
22432
+ if (platform === "darwin") return selection.darwin ?? createDarwinHostHealthCollector();
22433
+ return createUnsupportedCollector();
22434
+ }
22435
+ //#endregion
22436
+ //#region ../../lib/system-health/evaluate.ts
22437
+ function value(signal) {
22438
+ return signal.status === "available" ? signal.value : null;
22439
+ }
22440
+ function reason(code, domain, severity, message, metric, observed, threshold) {
22441
+ return {
22442
+ code,
22443
+ domain,
22444
+ severity,
22445
+ message,
22446
+ metric,
22447
+ observed,
22448
+ threshold
22449
+ };
22450
+ }
22451
+ function evaluateAdmission(sample, thresholds) {
22452
+ const availableMemoryBytes = value(sample.availableMemoryBytes);
22453
+ if (availableMemoryBytes == null) return {
22454
+ state: "unavailable",
22455
+ availableMemoryBytes: null,
22456
+ reasons: [{
22457
+ code: "admission.memory_available.unavailable",
22458
+ domain: "admission",
22459
+ severity: "info",
22460
+ message: "Available memory could not be measured, so admission capacity is unavailable.",
22461
+ metric: "availableMemoryBytes"
22462
+ }]
22463
+ };
22464
+ if (availableMemoryBytes <= thresholds.memoryAvailableCriticalBytes) return {
22465
+ state: "blocked",
22466
+ availableMemoryBytes,
22467
+ reasons: [reason("admission.memory_available.blocked", "admission", "critical", "Available memory is at or below the critical admission reserve.", "availableMemoryBytes", availableMemoryBytes, thresholds.memoryAvailableCriticalBytes)]
22468
+ };
22469
+ if (availableMemoryBytes <= thresholds.memoryAvailableWarningBytes) return {
22470
+ state: "soft",
22471
+ availableMemoryBytes,
22472
+ reasons: [reason("admission.memory_available.soft", "admission", "warning", "Available memory is at or below the warning admission reserve.", "availableMemoryBytes", availableMemoryBytes, thresholds.memoryAvailableWarningBytes)]
22473
+ };
22474
+ return {
22475
+ state: "open",
22476
+ availableMemoryBytes,
22477
+ reasons: []
22478
+ };
22479
+ }
22480
+ function diagnostics(sample, thresholds) {
22481
+ const results = [];
22482
+ const swapUsedPercent = value(sample.swapUsedPercent);
22483
+ if (swapUsedPercent != null && swapUsedPercent > 0) results.push(reason("host.diagnostic.swap_occupancy", "host", "info", "Swap occupancy is historical context and does not represent current pressure.", "swapUsedPercent", swapUsedPercent, thresholds.swapUsedWarningPercent));
22484
+ const virtualCommitmentPercent = value(sample.virtualCommitmentPercent);
22485
+ if (virtualCommitmentPercent != null) results.push(reason("host.diagnostic.virtual_commitment", "host", "info", "Virtual memory commitment is diagnostic and does not represent current pressure.", "virtualCommitmentPercent", virtualCommitmentPercent, thresholds.overcommitWarningPercent));
22486
+ return results;
22487
+ }
22488
+ function linuxPressureReasons(sample, admission) {
22489
+ const results = [];
22490
+ const some = value(sample.memoryPressureSomeAvg10);
22491
+ const full = value(sample.memoryPressureFullAvg10);
22492
+ const swapActivity = value(sample.swapActivityBytesPerMinute);
22493
+ if (admission.state === "blocked") {
22494
+ if (full != null && full >= LINUX_MEMORY_PRESSURE_DEFAULTS.fullCriticalAvg10) results.push(reason("host.linux.psi_full.critical", "host", "critical", "Linux memory PSI full stalls reached the critical band while memory was below reserve.", "memoryPressureFullAvg10", full, LINUX_MEMORY_PRESSURE_DEFAULTS.fullCriticalAvg10));
22495
+ if (swapActivity != null && swapActivity >= LINUX_MEMORY_PRESSURE_DEFAULTS.swapActivityCriticalBytesPerMinute) results.push(reason("host.linux.swap_activity.critical", "host", "critical", "Linux swap activity reached the critical band while memory was below reserve.", "swapActivityBytesPerMinute", swapActivity, LINUX_MEMORY_PRESSURE_DEFAULTS.swapActivityCriticalBytesPerMinute));
22496
+ }
22497
+ if (admission.state === "soft" || admission.state === "blocked") {
22498
+ if (some != null && some >= LINUX_MEMORY_PRESSURE_DEFAULTS.someWarningAvg10) results.push(reason("host.linux.psi_some.warning", "host", "warning", "Linux memory PSI some stalls reached the warning band while memory was below reserve.", "memoryPressureSomeAvg10", some, LINUX_MEMORY_PRESSURE_DEFAULTS.someWarningAvg10));
22499
+ if (swapActivity != null && swapActivity >= LINUX_MEMORY_PRESSURE_DEFAULTS.swapActivityWarningBytesPerMinute && !(admission.state === "blocked" && swapActivity >= LINUX_MEMORY_PRESSURE_DEFAULTS.swapActivityCriticalBytesPerMinute)) results.push(reason("host.linux.swap_activity.warning", "host", "warning", "Linux swap activity reached the warning band while memory was below reserve.", "swapActivityBytesPerMinute", swapActivity, LINUX_MEMORY_PRESSURE_DEFAULTS.swapActivityWarningBytesPerMinute));
22500
+ }
22501
+ return results;
22502
+ }
22503
+ function darwinPressureReasons(sample) {
22504
+ const freePercent = value(sample.memoryPressureFreePercent);
22505
+ if (freePercent == null) return [];
22506
+ if (freePercent <= DARWIN_MEMORY_PRESSURE_DEFAULTS.criticalFreePercent) return [reason("host.darwin.memory_pressure.critical", "host", "critical", "macOS memory pressure free percentage reached the critical band.", "memoryPressureFreePercent", freePercent, DARWIN_MEMORY_PRESSURE_DEFAULTS.criticalFreePercent)];
22507
+ if (freePercent <= DARWIN_MEMORY_PRESSURE_DEFAULTS.warningFreePercent) return [reason("host.darwin.memory_pressure.warning", "host", "warning", "macOS memory pressure free percentage reached the warning band.", "memoryPressureFreePercent", freePercent, DARWIN_MEMORY_PRESSURE_DEFAULTS.warningFreePercent)];
22508
+ return [];
22509
+ }
22510
+ function hasCurrentPressureSignal(sample) {
22511
+ if (sample.platform === "linux") return value(sample.memoryPressureSomeAvg10) != null || value(sample.memoryPressureFullAvg10) != null || value(sample.swapActivityBytesPerMinute) != null;
22512
+ if (sample.platform === "darwin") return value(sample.memoryPressureFreePercent) != null;
22513
+ return false;
22514
+ }
22515
+ function evaluateHostPressure(sample, thresholds) {
22516
+ const admission = evaluateAdmission(sample, thresholds);
22517
+ const diagnosticReasons = diagnostics(sample, thresholds);
22518
+ if (!hasCurrentPressureSignal(sample)) return {
22519
+ state: "unavailable",
22520
+ reasons: [{
22521
+ code: "host.current_pressure.unavailable",
22522
+ domain: "host",
22523
+ severity: "info",
22524
+ message: "The platform collector could not measure a current-pressure signal."
22525
+ }, ...diagnosticReasons],
22526
+ diagnostics: diagnosticReasons,
22527
+ admission
22528
+ };
22529
+ const pressureReasons = sample.platform === "linux" ? linuxPressureReasons(sample, admission) : darwinPressureReasons(sample);
22530
+ return {
22531
+ state: pressureReasons.some((entry) => entry.severity === "critical") ? "critical" : pressureReasons.some((entry) => entry.severity === "warning") ? "warning" : "healthy",
22532
+ reasons: [...pressureReasons, ...diagnosticReasons],
22533
+ diagnostics: diagnosticReasons,
22534
+ admission
22535
+ };
22536
+ }
22537
+ //#endregion
22538
+ //#region ../../lib/system-health/sampler.ts
22539
+ const DEFAULT_WARMUP_INTERVAL_MS = 1e3;
22540
+ const DEFAULT_WARMUP_SAMPLES = 3;
22541
+ const REQUIRED_CONSECUTIVE_SAMPLES = 3;
22542
+ function createMeasuringState(metrics, observedAt) {
22543
+ return {
22544
+ accepted: {
22545
+ state: "measuring",
22546
+ reasons: [{
22547
+ code: "host.sampler.measuring",
22548
+ domain: "host",
22549
+ severity: "info",
22550
+ message: "System health is collecting the initial three samples."
22551
+ }],
22552
+ metrics,
22553
+ sampledAt: observedAt,
22554
+ freshness: {
22555
+ status: "measuring",
22556
+ observedAt
22557
+ },
22558
+ transitionVersion: 0
22559
+ },
22560
+ candidate: null,
22561
+ candidateCount: 0
22562
+ };
22563
+ }
22564
+ function accept(previous, assessment) {
22565
+ const changed = previous.state !== assessment.state;
22566
+ const transitionVersion = changed ? previous.transitionVersion + 1 : previous.transitionVersion;
22567
+ return {
22568
+ state: {
22569
+ accepted: {
22570
+ ...assessment,
22571
+ freshness: {
22572
+ status: "fresh",
22573
+ observedAt: assessment.sampledAt
22574
+ },
22575
+ transitionVersion
22576
+ },
22577
+ candidate: null,
22578
+ candidateCount: 0
22579
+ },
22580
+ transition: changed ? {
22581
+ version: transitionVersion,
22582
+ previousState: previous.state,
22583
+ state: assessment.state,
22584
+ reasonCodes: assessment.reasons.map((entry) => entry.code),
22585
+ acceptedAt: assessment.sampledAt
22586
+ } : null
22587
+ };
22588
+ }
22589
+ /**
22590
+ * Applies symmetric three-sample hysteresis to one atomic assessment. Metrics
22591
+ * and reasons move with their state only when that complete assessment is
22592
+ * accepted, so readers never observe a new state paired with old evidence.
22593
+ */
22594
+ function transitionAcceptedAssessment(previous, raw) {
22595
+ if (raw.status === "invalid") return {
22596
+ state: {
22597
+ accepted: {
22598
+ ...previous.accepted,
22599
+ freshness: {
22600
+ status: "stale",
22601
+ observedAt: raw.sampledAt,
22602
+ reason: raw.reason
22603
+ }
22604
+ },
22605
+ candidate: null,
22606
+ candidateCount: 0
22607
+ },
22608
+ transition: null
22609
+ };
22610
+ const assessment = raw.assessment;
22611
+ if (assessment.state === previous.accepted.state) return accept(previous.accepted, assessment);
22612
+ const candidateCount = previous.candidate?.state === assessment.state ? previous.candidateCount + 1 : 1;
22613
+ if (candidateCount >= REQUIRED_CONSECUTIVE_SAMPLES) return accept(previous.accepted, assessment);
22614
+ return {
22615
+ state: {
22616
+ accepted: previous.accepted,
22617
+ candidate: assessment,
22618
+ candidateCount
22619
+ },
22620
+ transition: null
22621
+ };
22622
+ }
22623
+ function resolveMeasuringMetrics(value) {
22624
+ return typeof value === "function" ? value() : value;
22625
+ }
22626
+ function createSystemHealthSampler(options) {
22627
+ const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
22628
+ const warmupIntervalMs = options.warmupIntervalMs ?? DEFAULT_WARMUP_INTERVAL_MS;
22629
+ const warmupSamples = options.warmupSamples ?? DEFAULT_WARMUP_SAMPLES;
22630
+ let state = createMeasuringState(resolveMeasuringMetrics(options.measuringMetrics), now());
22631
+ let timer = null;
22632
+ let started = false;
22633
+ let stopped = false;
22634
+ let samplesAttempted = 0;
22635
+ const schedule = () => {
22636
+ if (stopped) return;
22637
+ const delay = samplesAttempted < warmupSamples ? warmupIntervalMs : options.pollIntervalMs;
22638
+ timer = setTimeout(() => {
22639
+ collectOnce();
22640
+ }, delay);
22641
+ };
22642
+ const collectOnce = async () => {
22643
+ if (stopped) return;
22644
+ let raw;
22645
+ try {
22646
+ raw = await options.collect();
22647
+ } catch (error) {
22648
+ raw = {
22649
+ status: "invalid",
22650
+ sampledAt: now(),
22651
+ reason: {
22652
+ code: "host.sampler.collection_failed",
22653
+ domain: "host",
22654
+ severity: "info",
22655
+ message: error instanceof Error ? error.message : "System health collection failed."
22656
+ }
22657
+ };
22658
+ }
22659
+ samplesAttempted++;
22660
+ const result = transitionAcceptedAssessment(state, raw);
22661
+ state = result.state;
22662
+ if (result.transition && options.onTransition) try {
22663
+ await options.onTransition(result.transition);
22664
+ } catch (error) {
22665
+ console.error("[system-health] Failed to publish accepted transition:", error);
22666
+ }
22667
+ schedule();
22668
+ };
22669
+ const start = () => {
22670
+ if (started || stopped) return;
22671
+ started = true;
22672
+ collectOnce();
22673
+ };
22674
+ return {
22675
+ getSnapshot() {
22676
+ start();
22677
+ return state.accepted;
22678
+ },
22679
+ stop() {
22680
+ stopped = true;
22681
+ if (timer) clearTimeout(timer);
22682
+ timer = null;
22683
+ }
22684
+ };
22685
+ }
22686
+ //#endregion
22687
+ //#region services/system-health-v2.ts
21856
22688
  init_event_store();
22689
+ init_staleness();
22690
+ function runtimeHealthState(runtime) {
22691
+ if (!runtime) return null;
22692
+ switch (runtime.activity) {
22693
+ case "working":
22694
+ case "thinking": return {
22695
+ state: "active",
22696
+ lastActivity: runtime.lastActivity,
22697
+ contextSaturatedAt: runtime.contextSaturatedAt
22698
+ };
22699
+ case "waiting": return {
22700
+ state: "waiting-on-human",
22701
+ lastActivity: runtime.lastActivity,
22702
+ contextSaturatedAt: runtime.contextSaturatedAt
22703
+ };
22704
+ case "idle": return {
22705
+ state: "idle",
22706
+ lastActivity: runtime.lastActivity,
22707
+ contextSaturatedAt: runtime.contextSaturatedAt
22708
+ };
22709
+ case "stopped": return {
22710
+ state: "stopped",
22711
+ lastActivity: runtime.lastActivity,
22712
+ contextSaturatedAt: runtime.contextSaturatedAt
22713
+ };
22714
+ }
22715
+ }
22716
+ function agentLifecycle(role, issueId, tmuxActive, statuses) {
22717
+ if (role !== "review" && role !== "test" && role !== "ship") return "unknown";
22718
+ return classifyAdvancingSessionLifecycle(role, statuses.get(issueId.toUpperCase()), tmuxActive);
22719
+ }
22720
+ function stateToLegacySeverity(state) {
22721
+ return state === "critical" ? "critical" : state === "warning" ? "warning" : "normal";
22722
+ }
22723
+ function signalValue(signal) {
22724
+ return signal.status === "available" ? signal.value : null;
22725
+ }
22726
+ function hostMetrics(sample) {
22727
+ return {
22728
+ cpuPercent: signalValue(sample.cpuPercent),
22729
+ loadAverage1m: signalValue(sample.loadAverage1m),
22730
+ loadPerCore1m: signalValue(sample.loadPerCore1m),
22731
+ totalMemoryBytes: signalValue(sample.totalMemoryBytes),
22732
+ usedMemoryBytes: signalValue(sample.usedMemoryBytes),
22733
+ availableMemoryBytes: signalValue(sample.availableMemoryBytes),
22734
+ memoryUsedPercent: signalValue(sample.memoryUsedPercent),
22735
+ memoryPressureSomeAvg10: signalValue(sample.memoryPressureSomeAvg10),
22736
+ memoryPressureFullAvg10: signalValue(sample.memoryPressureFullAvg10),
22737
+ memoryPressureFreePercent: signalValue(sample.memoryPressureFreePercent),
22738
+ swapTotalBytes: signalValue(sample.swapTotalBytes),
22739
+ swapUsedBytes: signalValue(sample.swapUsedBytes),
22740
+ swapUsedPercent: signalValue(sample.swapUsedPercent),
22741
+ swapActivityBytesPerMinute: signalValue(sample.swapActivityBytesPerMinute),
22742
+ committedMemoryBytes: signalValue(sample.committedMemoryBytes),
22743
+ commitLimitBytes: signalValue(sample.commitLimitBytes),
22744
+ virtualCommitmentPercent: signalValue(sample.virtualCommitmentPercent)
22745
+ };
22746
+ }
22747
+ function serviceHealth(smeeRelay) {
22748
+ if (smeeRelay.status === "running") return [{
22749
+ id: "smee-relay",
22750
+ label: "Webhook relay",
22751
+ required: false,
22752
+ status: "running",
22753
+ message: smeeRelay.message,
22754
+ reasons: []
22755
+ }];
22756
+ if (smeeRelay.status === "not_configured") return [{
22757
+ id: "smee-relay",
22758
+ label: "Webhook relay",
22759
+ required: false,
22760
+ status: "not_configured",
22761
+ message: smeeRelay.message,
22762
+ reasons: []
22763
+ }];
22764
+ const unavailable = smeeRelay.status === "unknown";
22765
+ return [{
22766
+ id: "smee-relay",
22767
+ label: "Webhook relay",
22768
+ required: false,
22769
+ status: unavailable ? "unavailable" : "stopped",
22770
+ message: smeeRelay.message,
22771
+ reasons: [{
22772
+ code: unavailable ? "service.smee_relay.unavailable" : "service.smee_relay.stopped",
22773
+ domain: "service",
22774
+ severity: unavailable ? "info" : "warning",
22775
+ message: smeeRelay.message
22776
+ }]
22777
+ }];
22778
+ }
22779
+ function overallHealthState(hostState, agents, services) {
22780
+ if (hostState === "critical" || agents.some((agent) => agent.status === "dead" || agent.status === "wedged")) return "critical";
22781
+ if (hostState === "warning" || agents.some((agent) => agent.status === "warning" || agent.status === "stalled") || services.some((service) => service.status === "degraded" || service.status === "stopped")) return "warning";
22782
+ if (hostState === "measuring") return "measuring";
22783
+ if (hostState === "unavailable" || agents.some((agent) => agent.status === "unavailable") || services.some((service) => service.status === "unavailable")) return "unavailable";
22784
+ return "healthy";
22785
+ }
22786
+ function acceptedReasons(state, hostReasons, agents, services) {
22787
+ const reasons = [
22788
+ ...hostReasons,
22789
+ ...agents.flatMap((agent) => agent.reasons),
22790
+ ...services.flatMap((service) => service.reasons)
22791
+ ];
22792
+ if (state === "measuring" && reasons.length === 0) return [{
22793
+ code: "host.sampler.measuring",
22794
+ domain: "host",
22795
+ severity: "info",
22796
+ message: "System health is collecting the initial three samples."
22797
+ }];
22798
+ return reasons;
22799
+ }
22800
+ //#endregion
22801
+ //#region services/system-health-service.ts
22802
+ init_review_status_source();
21857
22803
  const execAsync$4 = promisify(exec);
21858
- const DEFAULT_HEALTH_POLL_SECONDS = 15;
21859
- const DEFAULT_RESOURCE_CONFIG = {
21860
- memoryWarnGb: 4,
21861
- memoryBlockGb: 2,
21862
- agentWarnCount: 8,
21863
- agentBlockCount: 10
21864
- };
21865
22804
  const KB = 1024;
21866
22805
  const GIB$1 = 1024 ** 3;
21867
- const GLOBAL_CONFIG_PATH = join(homedir$1(), ".overdeck", "config.yaml");
21868
22806
  let dockerStatsCollector$1 = null;
21869
- let previousCpuSample = null;
21870
- let previousCpuSampleAt = 0;
21871
- let cachedHealth = null;
21872
- let cacheExpiresAt = 0;
21873
- let inflightRefresh = null;
21874
- let previousSeverity = null;
21875
- let candidateSeverity = null;
21876
- let candidateCount = 0;
21877
- const HYSTERESIS_POLLS = 3;
22807
+ const hostHealthCollector = createHostHealthCollector();
22808
+ let previousHostMetricSample;
22809
+ let systemHealthSampler = null;
21878
22810
  let eventStorePromise = null;
21879
- let cachedResourceConfig = DEFAULT_RESOURCE_CONFIG;
21880
- let cachedPollSeconds = DEFAULT_HEALTH_POLL_SECONDS;
22811
+ let cachedSystemHealthConfig = null;
21881
22812
  let resourceConfigLoadedAt = 0;
21882
22813
  let resourceConfigInflight = null;
21883
22814
  let cachedDeployStaleness = null;
@@ -21911,9 +22842,17 @@ function getDockerStatsCollector() {
21911
22842
  function bytesToGb(bytes) {
21912
22843
  return Math.round(bytes / GIB$1 * 100) / 100;
21913
22844
  }
21914
- function toPercent(part, total) {
21915
- if (total <= 0) return 0;
21916
- return Math.round(part / total * 1e3) / 10;
22845
+ const AGENT_STARTUP_GRACE_MS = 300 * 1e3;
22846
+ function countAdmittedWorkAgents(agents, nowMs = Date.now()) {
22847
+ return agents.filter((agent) => {
22848
+ if (agent.role !== "work") return false;
22849
+ if (agent.status !== "running" && agent.status !== "starting") return false;
22850
+ if (agent.tmuxActive) return true;
22851
+ if (agent.status !== "starting" || !agent.startedAt) return false;
22852
+ const startedAtMs = Date.parse(agent.startedAt);
22853
+ const ageMs = nowMs - startedAtMs;
22854
+ return Number.isFinite(startedAtMs) && ageMs >= 0 && ageMs < AGENT_STARTUP_GRACE_MS;
22855
+ }).length;
21917
22856
  }
21918
22857
  function classifyAgentKind(agentId, role) {
21919
22858
  if (agentId.startsWith("planning-")) return "planning";
@@ -21925,41 +22864,13 @@ function classifyAgentKind(agentId, role) {
21925
22864
  if (agentId.endsWith("-agent")) return "specialist";
21926
22865
  return "other";
21927
22866
  }
21928
- function resolveFiniteNumber(value, fallback) {
21929
- if (value == null || value.trim() === "") return fallback;
21930
- const parsed = Number(value);
21931
- return Number.isFinite(parsed) ? parsed : fallback;
21932
- }
21933
22867
  async function readGlobalResourceConfig() {
21934
- let next = DEFAULT_RESOURCE_CONFIG;
21935
- try {
21936
- await access(GLOBAL_CONFIG_PATH);
21937
- const raw = await readFile(GLOBAL_CONFIG_PATH, "utf-8");
21938
- const memoryWarnMatch = raw.match(/^\s*memory_warn_gb:\s*(\d+(?:\.\d+)?)\s*$/m);
21939
- const memoryBlockMatch = raw.match(/^\s*memory_block_gb:\s*(\d+(?:\.\d+)?)\s*$/m);
21940
- const agentWarnMatch = raw.match(/^\s*agent_warn_count:\s*(\d+(?:\.\d+)?)\s*$/m);
21941
- const agentBlockMatch = raw.match(/^\s*agent_block_count:\s*(\d+(?:\.\d+)?)\s*$/m);
21942
- const pollSecondsMatch = raw.match(/^\s*poll_seconds:\s*(\d+(?:\.\d+)?)\s*$/m);
21943
- next = {
21944
- memoryWarnGb: resolveFiniteNumber(memoryWarnMatch?.[1], DEFAULT_RESOURCE_CONFIG.memoryWarnGb),
21945
- memoryBlockGb: resolveFiniteNumber(memoryBlockMatch?.[1], DEFAULT_RESOURCE_CONFIG.memoryBlockGb),
21946
- agentWarnCount: Math.max(1, Math.floor(resolveFiniteNumber(agentWarnMatch?.[1], DEFAULT_RESOURCE_CONFIG.agentWarnCount))),
21947
- agentBlockCount: Math.max(1, Math.floor(resolveFiniteNumber(agentBlockMatch?.[1], DEFAULT_RESOURCE_CONFIG.agentBlockCount)))
21948
- };
21949
- cachedPollSeconds = Math.max(1, Math.floor(resolveFiniteNumber(process.env["PAN_HEALTH_POLL_SECONDS"], resolveFiniteNumber(pollSecondsMatch?.[1], DEFAULT_HEALTH_POLL_SECONDS))));
21950
- } catch {
21951
- cachedPollSeconds = Math.max(1, Math.floor(resolveFiniteNumber(process.env["PAN_HEALTH_POLL_SECONDS"], DEFAULT_HEALTH_POLL_SECONDS)));
21952
- }
21953
- cachedResourceConfig = {
21954
- memoryWarnGb: resolveFiniteNumber(process.env["PAN_MEMORY_WARN_GB"], next.memoryWarnGb),
21955
- memoryBlockGb: resolveFiniteNumber(process.env["PAN_MEMORY_BLOCK_GB"], next.memoryBlockGb),
21956
- agentWarnCount: Math.max(1, Math.floor(resolveFiniteNumber(process.env["PAN_AGENT_WARN_COUNT"], next.agentWarnCount))),
21957
- agentBlockCount: Math.max(1, Math.floor(resolveFiniteNumber(process.env["PAN_AGENT_BLOCK_COUNT"], next.agentBlockCount)))
21958
- };
22868
+ cachedSystemHealthConfig = resolveSystemHealthConfig();
21959
22869
  resourceConfigLoadedAt = Date.now();
21960
22870
  }
21961
22871
  async function ensureResourceConfigLoaded() {
21962
- const ttl = Math.max(5e3, cachedPollSeconds * 1e3);
22872
+ const pollSeconds = cachedSystemHealthConfig?.pollSeconds ?? SYSTEM_HEALTH_DEFAULTS.pollSeconds;
22873
+ const ttl = Math.max(5e3, pollSeconds * 1e3);
21963
22874
  if (resourceConfigLoadedAt > 0 && Date.now() - resourceConfigLoadedAt < ttl) return;
21964
22875
  if (!resourceConfigInflight) resourceConfigInflight = readGlobalResourceConfig().finally(() => {
21965
22876
  resourceConfigInflight = null;
@@ -21967,23 +22878,8 @@ async function ensureResourceConfigLoaded() {
21967
22878
  await resourceConfigInflight;
21968
22879
  }
21969
22880
  function getResourceConfig() {
21970
- return cachedResourceConfig;
21971
- }
21972
- function getHealthPollTtlMs() {
21973
- return Math.max(1, cachedPollSeconds) * 1e3;
21974
- }
21975
- function defaultThresholds() {
21976
- const resources = getResourceConfig();
21977
- return {
21978
- memoryAvailableWarningBytes: resources.memoryWarnGb * GIB$1,
21979
- memoryAvailableCriticalBytes: resources.memoryBlockGb * GIB$1,
21980
- swapUsedWarningPercent: Number(process.env["PAN_HEALTH_SWAP_WARN_PERCENT"] ?? 20),
21981
- swapUsedCriticalPercent: Number(process.env["PAN_HEALTH_SWAP_CRITICAL_PERCENT"] ?? 50),
21982
- cpuLoadWarningPerCore: Number(process.env["PAN_HEALTH_LOAD_WARN_PER_CORE"] ?? 1),
21983
- cpuLoadCriticalPerCore: Number(process.env["PAN_HEALTH_LOAD_CRITICAL_PER_CORE"] ?? 1.5),
21984
- overcommitWarningPercent: Number(process.env["PAN_HEALTH_OVERCOMMIT_WARN_PERCENT"] ?? 150),
21985
- overcommitCriticalPercent: Number(process.env["PAN_HEALTH_OVERCOMMIT_CRITICAL_PERCENT"] ?? 200)
21986
- };
22881
+ cachedSystemHealthConfig ??= resolveSystemHealthConfig();
22882
+ return cachedSystemHealthConfig.resources;
21987
22883
  }
21988
22884
  async function readProcMemoryLinux() {
21989
22885
  const content = await readFile("/proc/meminfo", "utf-8");
@@ -22049,43 +22945,6 @@ async function readProcMemoryDarwin() {
22049
22945
  async function readProcMemory() {
22050
22946
  return platform$1() === "darwin" ? readProcMemoryDarwin() : readProcMemoryLinux();
22051
22947
  }
22052
- async function readLoadAverage() {
22053
- if (platform$1() === "darwin") {
22054
- const load = loadavg$1()[0] ?? 0;
22055
- return Number.isFinite(load) ? load : 0;
22056
- }
22057
- const content = await readFile("/proc/loadavg", "utf-8");
22058
- const load = Number((content.trim().split(/\s+/)[0] ?? "0").trim());
22059
- return Number.isFinite(load) ? load : 0;
22060
- }
22061
- async function readCpuPercent() {
22062
- if (platform$1() === "darwin") {
22063
- const coreCount = Math.max(cpus$1().length, 1);
22064
- const load = loadavg$1()[0] ?? 0;
22065
- return Math.round(Math.min(load / coreCount, 1) * 1e3) / 10;
22066
- }
22067
- const cpuLine = (await readFile("/proc/stat", "utf-8")).split("\n").find((line) => line.startsWith("cpu "));
22068
- if (!cpuLine) return 0;
22069
- const values = cpuLine.trim().split(/\s+/).slice(1).map((value) => Number(value));
22070
- const current = {
22071
- idle: (values[3] ?? 0) + (values[4] ?? 0),
22072
- total: values.reduce((sum, value) => sum + value, 0)
22073
- };
22074
- const now = Date.now();
22075
- if (!previousCpuSample || previousCpuSampleAt > 0 && now - previousCpuSampleAt > getHealthPollTtlMs() * 2) {
22076
- previousCpuSample = current;
22077
- previousCpuSampleAt = now;
22078
- const coreCount = Math.max(cpus$1().length, 1);
22079
- const fallback = Math.min(await readLoadAverage() / coreCount, 1) * 100;
22080
- return Math.round(fallback * 10) / 10;
22081
- }
22082
- const totalDelta = current.total - previousCpuSample.total;
22083
- const idleDelta = current.idle - previousCpuSample.idle;
22084
- previousCpuSample = current;
22085
- previousCpuSampleAt = now;
22086
- if (totalDelta <= 0) return 0;
22087
- return Math.round((totalDelta - idleDelta) / totalDelta * 1e3) / 10;
22088
- }
22089
22948
  async function readProcessTable() {
22090
22949
  const { stdout } = await execAsync$4("ps -eo pid=,ppid=,rss=,args=", {
22091
22950
  encoding: "utf-8",
@@ -22127,41 +22986,13 @@ function sumProcessMemory(descendants, processes) {
22127
22986
  for (const pid of descendants) totalRssKb += processes.get(pid)?.rssKb ?? 0;
22128
22987
  return totalRssKb * KB;
22129
22988
  }
22130
- function buildLeakedSpecialists(snapshot, runningAgents) {
22131
- if (!snapshot) return [];
22132
- const activeWorkIssues = new Set(runningAgents.filter((agent) => agent.kind === "work" && agent.status !== "stopped" && agent.tmuxActive).map((agent) => agent.issueId.toUpperCase()));
22133
- return snapshot.specialists.filter((specialist) => specialist.isRunning && !!specialist.currentIssue).filter((specialist) => !activeWorkIssues.has((specialist.currentIssue ?? "").toUpperCase())).map((specialist) => ({
22134
- name: specialist.name ?? "",
22135
- currentIssue: specialist.currentIssue ?? "",
22136
- reason: `Specialist is active for ${specialist.currentIssue} but no running work agent exists for that issue.`
22989
+ function buildLeakedSpecialists(agents) {
22990
+ return agents.filter((agent) => agent.kind === "specialist" && agent.lifecycle === "orphaned").map((agent) => ({
22991
+ name: agent.id,
22992
+ currentIssue: agent.currentIssue ?? agent.issueId,
22993
+ reason: `Advancing session remains live after ${agent.issueId} merged.`
22137
22994
  }));
22138
22995
  }
22139
- function evaluateSeverity(thresholds, data) {
22140
- const criticalReasons = [];
22141
- const warningReasons = [];
22142
- if (data.availableMemoryBytes < thresholds.memoryAvailableCriticalBytes) criticalReasons.push(`Available RAM is low (${bytesToGb(data.availableMemoryBytes)} GB).`);
22143
- else if (data.availableMemoryBytes < thresholds.memoryAvailableWarningBytes) warningReasons.push(`Available RAM is tight (${bytesToGb(data.availableMemoryBytes)} GB).`);
22144
- if (data.swapUsedPercent >= thresholds.swapUsedCriticalPercent) criticalReasons.push(`Swap usage is high (${data.swapUsedPercent}%).`);
22145
- else if (data.swapUsedPercent >= thresholds.swapUsedWarningPercent) warningReasons.push(`Swap usage is elevated (${data.swapUsedPercent}%).`);
22146
- if (data.loadPerCore1m >= thresholds.cpuLoadCriticalPerCore) criticalReasons.push(`CPU load is high (${data.loadPerCore1m.toFixed(2)} per core).`);
22147
- else if (data.loadPerCore1m >= thresholds.cpuLoadWarningPerCore) warningReasons.push(`CPU load is elevated (${data.loadPerCore1m.toFixed(2)} per core).`);
22148
- if (data.overcommitPercent >= thresholds.overcommitCriticalPercent) criticalReasons.push(`Committed memory exceeds the safe limit (${data.overcommitPercent}%).`);
22149
- else if (data.overcommitPercent >= thresholds.overcommitWarningPercent) warningReasons.push(`Committed memory is near the limit (${data.overcommitPercent}%).`);
22150
- if (data.leakedSpecialistCount > 0) warningReasons.push(`${data.leakedSpecialistCount} leaked specialist session${data.leakedSpecialistCount === 1 ? "" : "s"} detected.`);
22151
- if (data.smeeRelay.configured && !data.smeeRelay.running) warningReasons.push("smee-client webhook relay is configured but not running.");
22152
- if (criticalReasons.length > 0) return {
22153
- severity: "critical",
22154
- reasons: criticalReasons.concat(warningReasons)
22155
- };
22156
- if (warningReasons.length > 0) return {
22157
- severity: "warning",
22158
- reasons: warningReasons
22159
- };
22160
- return {
22161
- severity: "normal",
22162
- reasons: []
22163
- };
22164
- }
22165
22996
  function collectSmeeRelayHealth() {
22166
22997
  try {
22167
22998
  if (!isSmeeConfiguredSync()) return {
@@ -22190,32 +23021,77 @@ function collectSmeeRelayHealth() {
22190
23021
  };
22191
23022
  }
22192
23023
  }
23024
+ function reviewStatusMap() {
23025
+ return new Map(Object.entries(readReviewStatusMap() ?? {}));
23026
+ }
22193
23027
  async function collectAgentProcesses() {
22194
- const activeAgents = (await Effect.runPromise(listRunningAgents())).filter((agent) => agent.status !== "stopped");
23028
+ const registeredAgents = await Effect.runPromise(listRunningAgents());
23029
+ const nowMs = Date.now();
23030
+ const admittedWorkAgentCount = countAdmittedWorkAgents(registeredAgents, nowMs);
23031
+ const activeAgents = registeredAgents.filter((agent) => agent.status !== "stopped");
23032
+ const liveSessions = new Set(registeredAgents.filter((agent) => agent.tmuxActive).map((agent) => agent.id));
22195
23033
  const processTable = await readProcessTable().catch(() => /* @__PURE__ */ new Map());
22196
- return Promise.all(activeAgents.map(async (agent) => {
22197
- const runtimeState = await Effect.runPromise(getAgentRuntimeState(agent.id)).catch(() => null);
23034
+ const reviewStatuses = reviewStatusMap();
23035
+ const collected = await Promise.all(activeAgents.map(async (agent) => {
23036
+ const [runtimeState, runtimeSnapshot] = await Promise.all([Effect.runPromise(getAgentRuntimeState(agent.id)).catch(() => null), Effect.runPromise(getRuntimeSnapshot(agent.id)).catch(() => null)]);
22198
23037
  const panePidValue = (await Effect.runPromise(listPaneValues(agent.id, "#{pane_pid}")))[0];
22199
23038
  const panePid = Number(panePidValue ?? "0");
22200
23039
  const descendants = Number.isFinite(panePid) && panePid > 0 ? getDescendantPids(panePid, processTable) : /* @__PURE__ */ new Set();
22201
23040
  const memoryBytes = descendants.size > 0 ? sumProcessMemory(descendants, processTable) : 0;
23041
+ const lifecycle = agentLifecycle(agent.role, agent.issueId, agent.tmuxActive, reviewStatuses);
22202
23042
  return {
22203
- id: agent.id,
22204
- issueId: agent.issueId,
22205
- kind: classifyAgentKind(agent.id, agent.role),
22206
- status: agent.status,
22207
- tmuxActive: agent.tmuxActive,
22208
- memoryBytes,
22209
- memoryGb: bytesToGb(memoryBytes),
22210
- currentIssue: runtimeState?.currentIssue
23043
+ process: {
23044
+ id: agent.id,
23045
+ issueId: agent.issueId,
23046
+ role: agent.role,
23047
+ kind: classifyAgentKind(agent.id, agent.role),
23048
+ status: agent.status,
23049
+ lifecycle,
23050
+ tmuxActive: agent.tmuxActive,
23051
+ memoryBytes,
23052
+ memoryGb: bytesToGb(memoryBytes),
23053
+ currentIssue: runtimeState?.currentIssue
23054
+ },
23055
+ health: {
23056
+ ...classifyAgentHealth({
23057
+ agentId: agent.id,
23058
+ persisted: {
23059
+ status: "available",
23060
+ value: {
23061
+ id: agent.id,
23062
+ issueId: agent.issueId,
23063
+ role: agent.role,
23064
+ status: agent.status,
23065
+ startedAt: agent.startedAt,
23066
+ lastActivity: agent.lastActivity,
23067
+ kickoffDelivered: agent.kickoffDelivered,
23068
+ paused: agent.paused,
23069
+ stoppedByUser: agent.stoppedByUser,
23070
+ stoppedByPause: agent.stoppedByPause,
23071
+ consecutiveFailures: agent.consecutiveFailures
23072
+ }
23073
+ },
23074
+ runtime: runtimeHealthState(runtimeSnapshot),
23075
+ liveSessions,
23076
+ reviewLifecycle: lifecycle,
23077
+ nowMs
23078
+ }),
23079
+ memoryBytes,
23080
+ memoryGb: bytesToGb(memoryBytes),
23081
+ ...runtimeState?.currentIssue ? { currentIssue: runtimeState.currentIssue } : {}
23082
+ }
22211
23083
  };
22212
23084
  }));
23085
+ return {
23086
+ agents: collected.map((entry) => entry.process),
23087
+ healthAgents: collected.map((entry) => entry.health),
23088
+ admittedWorkAgentCount
23089
+ };
22213
23090
  }
22214
- function buildTopConsumers(agents, containers, leakedSpecialists) {
22215
- const leakedByName = new Map(leakedSpecialists.map((item) => [item.name, item]));
23091
+ function buildTopConsumers(agents, containers) {
22216
23092
  const agentConsumers = agents.map((agent) => {
22217
23093
  const isSpecialist = agent.kind === "specialist";
22218
- const leaked = leakedByName.has(agent.id.replace(/^specialist-/, "")) || leakedByName.has(agent.id);
23094
+ const leaked = agent.lifecycle === "orphaned";
22219
23095
  const currentIssue = agent.currentIssue ?? agent.issueId;
22220
23096
  const resolved = currentIssue ? resolveProjectFromIssueSync(currentIssue) : null;
22221
23097
  const specialistType = isSpecialist ? agent.id.startsWith("specialist-") ? agent.id.replace(/^specialist-/, "") : agent.id : void 0;
@@ -22251,122 +23127,215 @@ function buildTopConsumers(agents, containers, leakedSpecialists) {
22251
23127
  containerId: container.id
22252
23128
  }
22253
23129
  }));
22254
- return [...agentConsumers, ...containerConsumers].sort((a, b) => b.memoryBytes - a.memoryBytes).slice(0, 10);
23130
+ return [...agentConsumers, ...containerConsumers].sort((a, b) => b.memoryBytes - a.memoryBytes);
22255
23131
  }
22256
- async function refreshSystemHealth(snapshot) {
23132
+ function createMeasuringSnapshot() {
23133
+ cachedSystemHealthConfig ??= resolveSystemHealthConfig();
23134
+ const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
23135
+ const smeeRelay = collectSmeeRelayHealth();
23136
+ const services = serviceHealth(smeeRelay);
23137
+ const base = {
23138
+ version: 2,
23139
+ state: "measuring",
23140
+ updatedAt,
23141
+ nextPollMs: cachedSystemHealthConfig.pollSeconds * 1e3,
23142
+ host: {
23143
+ state: "measuring",
23144
+ platform: hostHealthCollector.platform,
23145
+ reasons: [{
23146
+ code: "host.sampler.measuring",
23147
+ domain: "host",
23148
+ severity: "info",
23149
+ message: "System health is collecting the initial three samples."
23150
+ }],
23151
+ metrics: {
23152
+ cpuPercent: null,
23153
+ loadAverage1m: null,
23154
+ loadPerCore1m: null,
23155
+ totalMemoryBytes: null,
23156
+ usedMemoryBytes: null,
23157
+ availableMemoryBytes: null,
23158
+ memoryUsedPercent: null,
23159
+ memoryPressureSomeAvg10: null,
23160
+ memoryPressureFullAvg10: null,
23161
+ memoryPressureFreePercent: null,
23162
+ swapTotalBytes: null,
23163
+ swapUsedBytes: null,
23164
+ swapUsedPercent: null,
23165
+ swapActivityBytesPerMinute: null,
23166
+ committedMemoryBytes: null,
23167
+ commitLimitBytes: null,
23168
+ virtualCommitmentPercent: null
23169
+ }
23170
+ },
23171
+ admission: {
23172
+ state: "unavailable",
23173
+ availableMemoryBytes: null,
23174
+ admittedWorkAgentCount: 0,
23175
+ reasons: [{
23176
+ code: "admission.sampler.measuring",
23177
+ domain: "admission",
23178
+ severity: "info",
23179
+ message: "Admission capacity is unavailable until the initial health sample is accepted."
23180
+ }]
23181
+ },
23182
+ agents: [],
23183
+ services,
23184
+ topConsumers: []
23185
+ };
23186
+ const accepted = {
23187
+ ...base,
23188
+ summary: projectLegacySystemHealthSummary(base)
23189
+ };
23190
+ return {
23191
+ accepted,
23192
+ compatibility: {
23193
+ severity: "normal",
23194
+ updatedAt,
23195
+ admission: { admittedWorkAgentCount: 0 },
23196
+ summary: accepted.summary,
23197
+ thresholds: cachedSystemHealthConfig.thresholds,
23198
+ reasons: accepted.host.reasons.map((reason) => reason.message),
23199
+ agents: [],
23200
+ leakedSpecialists: [],
23201
+ topConsumers: [],
23202
+ smeeRelay,
23203
+ deployStaleness: null
23204
+ }
23205
+ };
23206
+ }
23207
+ async function collectSystemHealth() {
22257
23208
  await ensureResourceConfigLoaded();
22258
- const [memory, loadAverage1m, cpuPercent, agents, containers] = await Promise.all([
22259
- readProcMemory(),
22260
- readLoadAverage(),
22261
- readCpuPercent(),
23209
+ const [sample, agentProcesses, containers, deployStaleness] = await Promise.all([
23210
+ hostHealthCollector.sample(previousHostMetricSample),
22262
23211
  collectAgentProcesses(),
22263
- Promise.resolve(getDockerStatsCollector().getStats())
23212
+ Promise.resolve(getDockerStatsCollector().getStats()),
23213
+ getDeployStaleness()
22264
23214
  ]);
22265
- const thresholds = defaultThresholds();
23215
+ previousHostMetricSample = sample;
23216
+ const config = cachedSystemHealthConfig;
23217
+ const host = evaluateHostPressure(sample, config.thresholds);
22266
23218
  const smeeRelay = collectSmeeRelayHealth();
22267
- const coreCount = Math.max(cpus$1().length, 1);
22268
- const loadPerCore1m = Math.round(loadAverage1m / coreCount * 100) / 100;
22269
- const usedMemoryBytes = Math.max(memory.memTotal - memory.memAvailable, 0);
22270
- const swapUsedBytes = Math.max(memory.swapTotal - memory.swapFree, 0);
22271
- const overcommitPercent = toPercent(memory.committedAs, memory.memTotal);
22272
- const leakedSpecialists = buildLeakedSpecialists(snapshot, agents);
22273
- const evaluation = evaluateSeverity(thresholds, {
22274
- availableMemoryBytes: memory.memAvailable,
22275
- swapUsedPercent: toPercent(swapUsedBytes, memory.swapTotal),
22276
- loadPerCore1m,
22277
- overcommitPercent,
22278
- leakedSpecialistCount: leakedSpecialists.length,
22279
- smeeRelay
22280
- });
22281
- const containerMemoryBytes = containers.reduce((sum, container) => sum + container.memoryUsage, 0);
22282
- const workAgentCount = agents.filter((agent) => agent.kind === "work").length;
22283
- const planningAgentCount = agents.filter((agent) => agent.kind === "planning").length;
22284
- const specialistSessionCount = agents.filter((agent) => agent.kind === "specialist").length;
22285
- const swapUsedPercent = toPercent(swapUsedBytes, memory.swapTotal);
22286
- const overdeckMemoryBytes = agents.reduce((sum, agent) => sum + agent.memoryBytes, 0) + containerMemoryBytes;
22287
- const overdeckMemoryPercent = toPercent(overdeckMemoryBytes, memory.memTotal);
22288
- const sortedAgents = [...agents].sort((a, b) => b.memoryBytes - a.memoryBytes);
22289
- const deployStaleness = await getDeployStaleness();
22290
- let effectiveSeverity;
22291
- if (previousSeverity == null) effectiveSeverity = evaluation.severity;
22292
- else if (evaluation.severity === previousSeverity) {
22293
- candidateSeverity = null;
22294
- candidateCount = 0;
22295
- effectiveSeverity = previousSeverity;
22296
- } else if (evaluation.severity === candidateSeverity) {
22297
- candidateCount++;
22298
- effectiveSeverity = candidateCount >= HYSTERESIS_POLLS ? evaluation.severity : previousSeverity;
22299
- if (effectiveSeverity !== previousSeverity) {
22300
- candidateSeverity = null;
22301
- candidateCount = 0;
22302
- }
22303
- } else {
22304
- candidateSeverity = evaluation.severity;
22305
- candidateCount = 1;
22306
- effectiveSeverity = previousSeverity;
22307
- }
22308
- const result = {
22309
- severity: effectiveSeverity,
22310
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
22311
- summary: {
22312
- cpuPercent,
22313
- loadAverage1m,
22314
- loadPerCore1m,
22315
- totalMemoryBytes: memory.memTotal,
22316
- usedMemoryBytes,
22317
- availableMemoryBytes: memory.memAvailable,
22318
- memoryUsedPercent: toPercent(usedMemoryBytes, memory.memTotal),
22319
- swapTotalBytes: memory.swapTotal,
22320
- swapUsedBytes,
22321
- swapUsedPercent,
22322
- overcommitPercent,
22323
- agentCount: agents.length,
22324
- workAgentCount,
22325
- planningAgentCount,
22326
- specialistSessionCount,
22327
- leakedSpecialistCount: leakedSpecialists.length,
22328
- containerCount: containers.length,
22329
- containerMemoryBytes,
22330
- overdeckMemoryBytes,
22331
- overdeckMemoryPercent
23219
+ const services = serviceHealth(smeeRelay);
23220
+ const consumers = buildTopConsumers(agentProcesses.agents, containers);
23221
+ const state = overallHealthState(host.state, agentProcesses.healthAgents, services);
23222
+ const reasons = acceptedReasons(state, host.reasons, agentProcesses.healthAgents, services);
23223
+ const updatedAt = new Date(sample.sampledAtMs).toISOString();
23224
+ const base = {
23225
+ version: 2,
23226
+ state,
23227
+ updatedAt,
23228
+ nextPollMs: config.pollSeconds * 1e3,
23229
+ host: {
23230
+ state: host.state,
23231
+ platform: sample.platform,
23232
+ reasons: host.reasons,
23233
+ metrics: hostMetrics(sample)
23234
+ },
23235
+ admission: {
23236
+ ...host.admission,
23237
+ admittedWorkAgentCount: agentProcesses.admittedWorkAgentCount
22332
23238
  },
22333
- thresholds,
22334
- reasons: evaluation.reasons,
22335
- agents: sortedAgents,
22336
- leakedSpecialists,
22337
- topConsumers: buildTopConsumers(sortedAgents, containers, leakedSpecialists),
22338
- smeeRelay,
22339
- deployStaleness
22340
- };
22341
- if (previousSeverity && previousSeverity !== result.severity) try {
23239
+ agents: agentProcesses.healthAgents,
23240
+ services,
23241
+ topConsumers: consumers
23242
+ };
23243
+ const accepted = {
23244
+ ...base,
23245
+ summary: projectLegacySystemHealthSummary(base)
23246
+ };
23247
+ const sortedAgents = [...agentProcesses.agents].sort((left, right) => right.memoryBytes - left.memoryBytes);
23248
+ const leakedSpecialists = buildLeakedSpecialists(sortedAgents);
23249
+ return {
23250
+ accepted,
23251
+ compatibility: {
23252
+ severity: stateToLegacySeverity(state),
23253
+ updatedAt,
23254
+ admission: { admittedWorkAgentCount: agentProcesses.admittedWorkAgentCount },
23255
+ summary: accepted.summary,
23256
+ thresholds: config.thresholds,
23257
+ reasons: reasons.map((reason) => reason.message),
23258
+ agents: sortedAgents,
23259
+ leakedSpecialists,
23260
+ topConsumers: consumers.slice(0, 10),
23261
+ smeeRelay,
23262
+ deployStaleness
23263
+ }
23264
+ };
23265
+ }
23266
+ async function collectRawSystemHealth() {
23267
+ const bundle = await collectSystemHealth();
23268
+ const reasons = acceptedReasons(bundle.accepted.state, bundle.accepted.host.reasons, bundle.accepted.agents, bundle.accepted.services);
23269
+ return {
23270
+ status: "valid",
23271
+ assessment: {
23272
+ state: bundle.accepted.state,
23273
+ reasons,
23274
+ metrics: bundle,
23275
+ sampledAt: bundle.accepted.updatedAt
23276
+ }
23277
+ };
23278
+ }
23279
+ function buildSystemHealthTransitionPayload(transition, leakedSpecialistCount) {
23280
+ return {
23281
+ version: 2,
23282
+ transitionVersion: transition.version,
23283
+ previousSeverity: stateToLegacySeverity(transition.previousState),
23284
+ severity: stateToLegacySeverity(transition.state),
23285
+ previousState: transition.previousState,
23286
+ state: transition.state,
23287
+ reasons: transition.reasonCodes,
23288
+ reasonCodes: transition.reasonCodes,
23289
+ acceptedAt: transition.acceptedAt,
23290
+ leakedSpecialistCount
23291
+ };
23292
+ }
23293
+ async function publishSystemHealthTransition(transition) {
23294
+ const accepted = systemHealthSampler?.getSnapshot();
23295
+ try {
22342
23296
  await (await (eventStorePromise ??= initEventStore())).appendAsync({
22343
23297
  type: "system.health_severity_changed",
22344
- timestamp: result.updatedAt,
22345
- payload: {
22346
- previousSeverity,
22347
- severity: result.severity,
22348
- reasons: result.reasons,
22349
- leakedSpecialistCount: leakedSpecialists.length
22350
- }
23298
+ timestamp: transition.acceptedAt,
23299
+ payload: buildSystemHealthTransitionPayload(transition, accepted?.metrics.accepted.summary.leakedSpecialistCount ?? 0)
22351
23300
  });
22352
23301
  } catch (err) {
22353
- console.error("[system-health] Failed to append severity transition event:", err);
23302
+ console.error("[system-health] Failed to append accepted transition event:", err);
22354
23303
  }
22355
- previousSeverity = result.severity;
22356
- cachedHealth = result;
22357
- cacheExpiresAt = Date.now() + getHealthPollTtlMs();
22358
- return result;
22359
23304
  }
22360
- async function getSystemHealthSnapshot(snapshot) {
22361
- if (cachedHealth && Date.now() < cacheExpiresAt) return cachedHealth;
22362
- if (!inflightRefresh) inflightRefresh = refreshSystemHealth(snapshot).finally(() => {
22363
- inflightRefresh = null;
22364
- });
22365
- return inflightRefresh;
23305
+ function getSystemHealthSampler() {
23306
+ if (!systemHealthSampler) {
23307
+ const config = cachedSystemHealthConfig ?? resolveSystemHealthConfig();
23308
+ cachedSystemHealthConfig = config;
23309
+ systemHealthSampler = createSystemHealthSampler({
23310
+ collect: collectRawSystemHealth,
23311
+ measuringMetrics: createMeasuringSnapshot,
23312
+ pollIntervalMs: config.pollSeconds * 1e3,
23313
+ onTransition: publishSystemHealthTransition
23314
+ });
23315
+ }
23316
+ return systemHealthSampler;
23317
+ }
23318
+ async function getSystemHealthEvidenceSnapshot() {
23319
+ const assessment = getSystemHealthSampler().getSnapshot();
23320
+ return {
23321
+ accepted: assessment.metrics.accepted,
23322
+ compatibility: {
23323
+ ...assessment.metrics.compatibility,
23324
+ state: assessment.state,
23325
+ structuredReasons: assessment.reasons,
23326
+ freshness: assessment.freshness,
23327
+ transitionVersion: assessment.transitionVersion
23328
+ }
23329
+ };
23330
+ }
23331
+ async function getAcceptedSystemHealthSnapshot() {
23332
+ return (await getSystemHealthEvidenceSnapshot()).accepted;
23333
+ }
23334
+ async function getSystemHealthSnapshot() {
23335
+ return (await getSystemHealthEvidenceSnapshot()).compatibility;
22366
23336
  }
22367
23337
  //#endregion
22368
23338
  //#region routes/resources/shared.ts
22369
- init_load();
22370
23339
  init_docker_stats();
22371
23340
  function getCurrentDockerStats() {
22372
23341
  return [];
@@ -22467,6 +23436,7 @@ function roundOne(value) {
22467
23436
  }
22468
23437
  //#endregion
22469
23438
  //#region ../../lib/cloister/memory-governor.ts
23439
+ init_load();
22470
23440
  init_projects();
22471
23441
  promisify(execFile);
22472
23442
  const GIB = 1024 ** 3;
@@ -22578,7 +23548,7 @@ async function checkInspectAgentTimeouts(now = /* @__PURE__ */ new Date()) {
22578
23548
  console.warn(`[deacon] Failed to kill inspect session ${sessionName}: ${msg}`);
22579
23549
  });
22580
23550
  try {
22581
- const { messageAgent } = await import("./agents-Czz6R57Z.js");
23551
+ const { messageAgent } = await import("./agents-DyHKlq1I.js");
22582
23552
  await messageAgent(`agent-${issueId.toLowerCase()}`, verdict, "deacon:inspect-watchdog");
22583
23553
  } catch (err) {
22584
23554
  const msg = err instanceof Error ? err.message : String(err);
@@ -22730,7 +23700,7 @@ async function maybeProactivelyCompactContext(sessionName, now) {
22730
23700
  if (!agentState?.workspace || !sessionId || !agentState.model) return null;
22731
23701
  let usage = null;
22732
23702
  try {
22733
- const { computeContextUsage } = await import("./conversation-service-CWk8mEym.js");
23703
+ const { computeContextUsage } = await import("./conversation-service-Dq33SYEj.js");
22734
23704
  usage = await computeContextUsage(sessionFilePath(agentState.workspace, sessionId), agentState.model);
22735
23705
  } catch {
22736
23706
  return null;
@@ -22840,13 +23810,13 @@ async function checkApiErrorAgents() {
22840
23810
  const st = getAgentStateSync(sessionName);
22841
23811
  const sid = st?.sessionId ?? runtimeState?.claudeSessionId;
22842
23812
  if (st?.workspace && sid && st.model) {
22843
- const { computeContextUsage } = await import("./conversation-service-CWk8mEym.js");
23813
+ const { computeContextUsage } = await import("./conversation-service-Dq33SYEj.js");
22844
23814
  const usage = await computeContextUsage(sessionFilePath(st.workspace, sid), st.model);
22845
23815
  if (usage && usage.percentUsed < 85) recoveredPct = usage.percentUsed;
22846
23816
  }
22847
23817
  } catch {}
22848
23818
  if (recoveredPct !== null) {
22849
- const { clearWorkspaceStuck } = await import("./review-status-sync-C792ksoJ.js");
23819
+ const { clearWorkspaceStuck } = await import("./review-status-sync-D60PJWNL.js");
22850
23820
  clearWorkspaceStuck(issueId);
22851
23821
  stuckOverflowNativeRecoveryState.delete(sessionName);
22852
23822
  actions.push(`Context overflow recovery: cleared stuck flag for ${sessionName} (context back to ${Math.round(recoveredPct)}%)`);
@@ -22862,7 +23832,7 @@ async function checkApiErrorAgents() {
22862
23832
  rec.attempts += 1;
22863
23833
  rec.lastAttempt = now;
22864
23834
  stuckOverflowNativeRecoveryState.set(sessionName, rec);
22865
- const { resumeAgent } = await import("./agents-Czz6R57Z.js");
23835
+ const { resumeAgent } = await import("./agents-DyHKlq1I.js");
22866
23836
  const recovered = await resumeAgent(sessionName, void 0, { compact: true });
22867
23837
  if (recovered.success) {
22868
23838
  stuckOverflowNativeRecoveryState.delete(sessionName);
@@ -22910,7 +23880,7 @@ async function checkApiErrorAgents() {
22910
23880
  }
22911
23881
  const compactAttempts = (ov?.compactAttempts ?? 0) + 1;
22912
23882
  if (issueId !== null) {
22913
- const { resumeAgent } = await import("./agents-Czz6R57Z.js");
23883
+ const { resumeAgent } = await import("./agents-DyHKlq1I.js");
22914
23884
  const resumeResult = await resumeAgent(sessionName, void 0, { compact: true });
22915
23885
  contextOverflowRecoveryState.set(sessionName, {
22916
23886
  lastAttempt: now,
@@ -23433,7 +24403,7 @@ function reviewConvoyLiveness(issueId) {
23433
24403
  */
23434
24404
  async function recoverUnhealthyTestStack(issueId, workspacePath) {
23435
24405
  const key = issueId.toUpperCase();
23436
- const { getWorkspaceStackHealth } = await import("./stack-health-I713ELld.js");
24406
+ const { getWorkspaceStackHealth } = await import("./stack-health-Bd06frFn.js");
23437
24407
  const health = await Effect.runPromise(getWorkspaceStackHealth(issueId, { workspacePath }));
23438
24408
  if (health.healthy) {
23439
24409
  testStackRebuildState.delete(key);
@@ -23465,7 +24435,7 @@ async function recoverUnhealthyTestStack(issueId, workspacePath) {
23465
24435
  record.attempts += 1;
23466
24436
  testStackRebuildState.set(key, record);
23467
24437
  console.log(`[deacon] Test stack for ${key} unhealthy (${health.reasons.join("; ")}) — rebuilding (attempt ${record.attempts}/${TEST_STACK_REBUILD_MAX_ATTEMPTS})`);
23468
- const { rebuildWorkspaceStack } = await import("./rebuild-stack-DjdpALr1.js");
24438
+ const { rebuildWorkspaceStack } = await import("./rebuild-stack-CKjJAI8L.js");
23469
24439
  const result = await Effect.runPromise(rebuildWorkspaceStack(issueId, { onProgress: (m) => console.log(`[deacon] ${key} stack rebuild: ${m}`) }));
23470
24440
  if (!result.success) {
23471
24441
  console.warn(`[deacon] Test stack rebuild failed for ${key}: ${result.error}`);
@@ -23633,7 +24603,7 @@ async function handleReviewCoordinatorDied(issueId, _sessionName, _reason) {
23633
24603
  return actions;
23634
24604
  }
23635
24605
  try {
23636
- const { spawnReviewRoleForIssue } = await import("./review-agent-CSswH985.js");
24606
+ const { spawnReviewRoleForIssue } = await import("./review-agent-CCum8sGe.js");
23637
24607
  const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
23638
24608
  issueId,
23639
24609
  workspace,
@@ -23785,7 +24755,7 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
23785
24755
  const workspace = agentState?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
23786
24756
  if (workspace && resolved && !tryReserveAdvancingSlot() && !await tryYieldForAdvancingDispatch("review", issueId)) actions.push(`Deferred review re-dispatch for ${issueId} — advancing-role concurrency ceiling reached`);
23787
24757
  else if (workspace && resolved) try {
23788
- const { spawnReviewRoleForIssue } = await import("./review-agent-CSswH985.js");
24758
+ const { spawnReviewRoleForIssue } = await import("./review-agent-CCum8sGe.js");
23789
24759
  const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
23790
24760
  issueId,
23791
24761
  workspace,
@@ -23810,8 +24780,8 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
23810
24780
  const workspace = agentState?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
23811
24781
  if (workspace && resolved) {
23812
24782
  const branch = `feature/${issueLower}`;
23813
- const { spawnRun } = await import("./agents-Czz6R57Z.js");
23814
- const { buildTestRolePrompt } = await import("./test-agent-queue-BwpUpu-o.js");
24783
+ const { spawnRun } = await import("./agents-DyHKlq1I.js");
24784
+ const { buildTestRolePrompt } = await import("./test-agent-queue-BJZ9Nfcc.js");
23815
24785
  const stackRecovery = await recoverUnhealthyTestStack(issueId, workspace);
23816
24786
  if (stackRecovery === "cooldown" || stackRecovery === "exhausted") {
23817
24787
  setReviewStatusSync(issueId, { testStatus: "dispatch_failed" });
@@ -23949,7 +24919,7 @@ async function recoverStalledReviewConvoys(getCanonicalState = getAutoCloseOutCa
23949
24919
  record.lastAttempt = now;
23950
24920
  record.attempts += 1;
23951
24921
  stalledReviewConvoyRecoveryState.set(key, record);
23952
- const { spawnReviewRoleForIssue } = await import("./review-agent-CSswH985.js");
24922
+ const { spawnReviewRoleForIssue } = await import("./review-agent-CCum8sGe.js");
23953
24923
  try {
23954
24924
  const result = await Effect.runPromise(spawnReviewRoleForIssue({
23955
24925
  issueId,
@@ -24020,7 +24990,7 @@ async function checkMissingReviewStatuses() {
24020
24990
  continue;
24021
24991
  }
24022
24992
  try {
24023
- const { spawnReviewRoleForIssue } = await import("./review-agent-CSswH985.js");
24993
+ const { spawnReviewRoleForIssue } = await import("./review-agent-CCum8sGe.js");
24024
24994
  await Effect.runPromise(spawnReviewRoleForIssue({
24025
24995
  issueId,
24026
24996
  workspace,
@@ -24073,7 +25043,7 @@ async function checkStuckReviewing() {
24073
25043
  const actions = [];
24074
25044
  const REVIEW_STUCK_THRESHOLD_MS = 1800 * 1e3;
24075
25045
  try {
24076
- const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-DXeqFpk5.js");
25046
+ const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-Bnh-rdkY.js");
24077
25047
  const statuses = loadReviewStatuses();
24078
25048
  const now = Date.now();
24079
25049
  const activeReviewIssues = /* @__PURE__ */ new Set();
@@ -24218,7 +25188,7 @@ async function checkCompletedButUnsignaledReviews() {
24218
25188
  }
24219
25189
  const nudge = `Your review synthesis is already written and saved. Your ONLY remaining task is to execute this Bash command immediately — do not analyze, do not summarize, do not ask questions, just run it:\n\n${`pan admin specialists done review ${issueId} --status ${verdict}${verdict === "blocked" || verdict === "failed" ? ` --notes "${topBlocker || "See synthesis.md"}"` : ""}`}\n\nRun this command NOW. Do not write any other response before executing it.`;
24220
25190
  try {
24221
- const { messageAgent } = await import("./agents-Czz6R57Z.js");
25191
+ const { messageAgent } = await import("./agents-DyHKlq1I.js");
24222
25192
  await messageAgent(reviewSession, nudge);
24223
25193
  unsignaledReviewNudges.set(latestDir, now);
24224
25194
  actions.push(`Nudged ${reviewSession} to signal ${verdict} (synthesis written ${Math.round((now - latestMtime) / 6e4)}min ago)`);
@@ -24340,7 +25310,7 @@ async function respawnIdleReviewer(state, agentId) {
24340
25310
  return false;
24341
25311
  }
24342
25312
  try {
24343
- const { spawnReviewSubRoleForIssue } = await import("./review-agent-CSswH985.js");
25313
+ const { spawnReviewSubRoleForIssue } = await import("./review-agent-CCum8sGe.js");
24344
25314
  const contextManifestPath = join$1(dirname$1(outputPath), "context.json");
24345
25315
  const result = await Effect.runPromise(spawnReviewSubRoleForIssue({
24346
25316
  issueId: state.issueId,
@@ -24469,7 +25439,7 @@ async function nudgeSynthesisForCompleteReviewerReports(states) {
24469
25439
  "Read the four reports, write synthesis.md, then signal review status exactly as roles/review.md instructs."
24470
25440
  ].join("\n");
24471
25441
  try {
24472
- const { messageAgent } = await import("./agents-Czz6R57Z.js");
25442
+ const { messageAgent } = await import("./agents-DyHKlq1I.js");
24473
25443
  await messageAgent(state.id, message);
24474
25444
  reviewReportsPresentNudges.set(nudgeKey, now);
24475
25445
  const action = `Nudged ${state.id} to synthesize from ${REVIEW_SUB_ROLES.length} reviewer reports`;
@@ -24555,7 +25525,7 @@ async function monitorReviewConvoySignals() {
24555
25525
  if (!signal) continue;
24556
25526
  const message = signal === "ready" ? `REVIEWER_READY ${state.reviewSubRole} ${outputPath}` : signal === "timeout" ? `REVIEWER_TIMEOUT ${state.reviewSubRole} ${reason}` : `REVIEWER_FAILED ${state.reviewSubRole} ${reason}`;
24557
25527
  try {
24558
- const { messageAgent } = await import("./agents-Czz6R57Z.js");
25528
+ const { messageAgent } = await import("./agents-DyHKlq1I.js");
24559
25529
  await messageAgent(state.reviewSynthesisAgentId, message);
24560
25530
  state.reviewMonitorSignaled = signal;
24561
25531
  saveAgentStateSync(state);
@@ -24563,7 +25533,7 @@ async function monitorReviewConvoySignals() {
24563
25533
  actions.push(action);
24564
25534
  logDeaconEventSync(`monitorReviewConvoySignals: ${action}`);
24565
25535
  if (signal === "ready") try {
24566
- const { notifyPipelineSync } = await import("./pipeline-notifier-dQ-U4NSb.js");
25536
+ const { notifyPipelineSync } = await import("./pipeline-notifier-CZsrU_nj.js");
24567
25537
  notifyPipelineSync({
24568
25538
  type: "reviewer_completed",
24569
25539
  issueId: state.issueId,
@@ -24571,7 +25541,7 @@ async function monitorReviewConvoySignals() {
24571
25541
  });
24572
25542
  } catch {}
24573
25543
  else if (signal === "timeout") try {
24574
- const { notifyPipelineSync } = await import("./pipeline-notifier-dQ-U4NSb.js");
25544
+ const { notifyPipelineSync } = await import("./pipeline-notifier-CZsrU_nj.js");
24575
25545
  notifyPipelineSync({
24576
25546
  type: "reviewer_timed_out",
24577
25547
  issueId: state.issueId,
@@ -24671,7 +25641,7 @@ const FORK_CACHE_CHECK_DELAY_MS = 180 * 1e3;
24671
25641
  async function checkStalledReviewDiscovery() {
24672
25642
  const actions = [];
24673
25643
  try {
24674
- const { listAgentStates } = await import("./agents-Czz6R57Z.js");
25644
+ const { listAgentStates } = await import("./agents-DyHKlq1I.js");
24675
25645
  const states = listAgentStates();
24676
25646
  const now = Date.now();
24677
25647
  for (const state of states) {
@@ -24680,7 +25650,7 @@ async function checkStalledReviewDiscovery() {
24680
25650
  const aged = Number.isFinite(startedMs) && now - startedMs > 48e4;
24681
25651
  const dead = !await Effect.runPromise(sessionExists(state.id)).catch(() => false) || await Effect.runPromise(isPaneDead(state.id)).catch(() => true);
24682
25652
  if (!aged && !dead) continue;
24683
- const { handleReviewDiscoveryReady } = await import("./review-agent-CSswH985.js");
25653
+ const { handleReviewDiscoveryReady } = await import("./review-agent-CCum8sGe.js");
24684
25654
  const result = await handleReviewDiscoveryReady(state.issueId, { source: dead ? "deacon-backstop (parent dead)" : "deacon-backstop (discovery timeout)" });
24685
25655
  actions.push(result.message);
24686
25656
  logDeaconEventSync(`checkStalledReviewDiscovery: ${result.message}`);
@@ -24703,8 +25673,8 @@ async function checkStalledReviewDiscovery() {
24703
25673
  async function checkStalledReviewParents() {
24704
25674
  const actions = [];
24705
25675
  try {
24706
- const { listAgentStates, markAgentStoppedState } = await import("./agents-Czz6R57Z.js");
24707
- const { PARENT_REVIEW_TIMEOUT_MS } = await import("./review-agent-CSswH985.js");
25676
+ const { listAgentStates, markAgentStoppedState } = await import("./agents-DyHKlq1I.js");
25677
+ const { PARENT_REVIEW_TIMEOUT_MS } = await import("./review-agent-CCum8sGe.js");
24708
25678
  const states = listAgentStates();
24709
25679
  const now = Date.now();
24710
25680
  for (const state of states) {
@@ -24753,8 +25723,8 @@ async function checkStalledReviewParents() {
24753
25723
  async function checkReviewForkCacheMisses() {
24754
25724
  const actions = [];
24755
25725
  try {
24756
- const { listAgentStates, saveAgentState } = await import("./agents-Czz6R57Z.js");
24757
- const { readEventsSync } = await import("./events-LGeUehYW.js");
25726
+ const { listAgentStates, saveAgentState } = await import("./agents-DyHKlq1I.js");
25727
+ const { readEventsSync } = await import("./events-Dsuv6qyB.js");
24758
25728
  const { emitActivityEntrySync } = await import("./activity-logger-OEUBdfZ8.js");
24759
25729
  const states = listAgentStates();
24760
25730
  const now = Date.now();
@@ -24890,7 +25860,7 @@ async function reconcileStaleMergeStatus() {
24890
25860
  if (!project) continue;
24891
25861
  let specStatus;
24892
25862
  try {
24893
- const { findSpecByIssue } = await import("./specs-BsNcum0h.js");
25863
+ const { findSpecByIssue } = await import("./specs-BhOKBzqk.js");
24894
25864
  const spec = await Effect.runPromise(findSpecByIssue(project.projectPath, issueId));
24895
25865
  specStatus = spec?.status;
24896
25866
  if (spec && (spec.status === "completed" || spec.status === "cancelled")) {
@@ -24905,7 +25875,7 @@ async function reconcileStaleMergeStatus() {
24905
25875
  if (branchTip.stdout.trim() === mainTip.stdout.trim()) console.log(`[deacon] ${issueId}: branch ${branch} points at main; not treating zero-commit branch as merged`);
24906
25876
  } catch {}
24907
25877
  if (!isMerged) {
24908
- const { resolveGitHubIssueSync: _resolveGitHubIssue } = await import("./tracker-utils-WtP_V-yn.js");
25878
+ const { resolveGitHubIssueSync: _resolveGitHubIssue } = await import("./tracker-utils-DV3h1FYG.js");
24909
25879
  const ghResolved = _resolveGitHubIssue(issueId);
24910
25880
  if (ghResolved.isGitHub) try {
24911
25881
  const { stdout } = await execFileAsync$4("gh", [
@@ -24942,7 +25912,7 @@ async function reconcileStaleMergeStatus() {
24942
25912
  actions.push(msg);
24943
25913
  console.log(`[deacon] ${msg}`);
24944
25914
  try {
24945
- const { postMergeLifecycle } = await import("./merge-agent-CnORPiri.js");
25915
+ const { postMergeLifecycle } = await import("./merge-agent-B-SnXOoc.js");
24946
25916
  postMergeLifecycle(issueId, project.projectPath, branch, { skipDeploy: true }).catch((err) => console.warn(`[deacon] postMergeLifecycle (reconcile) failed for ${issueId}: ${err}`));
24947
25917
  } catch (err) {
24948
25918
  console.warn(`[deacon] Could not import postMergeLifecycle: ${err}`);
@@ -24967,7 +25937,7 @@ const falseMergedReset = /* @__PURE__ */ new Set();
24967
25937
  async function reconcileFalseMerged() {
24968
25938
  const actions = [];
24969
25939
  try {
24970
- const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CeSVFL6C.js");
25940
+ const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CU14oYzP.js");
24971
25941
  if (!isGitHubAppConfigured()) return actions;
24972
25942
  const statuses = loadReviewStatuses();
24973
25943
  for (const [issueId, status] of Object.entries(statuses)) {
@@ -25012,7 +25982,7 @@ const CLOSED_PR_RECONCILE_COOLDOWN_MS = 600 * 1e3;
25012
25982
  async function reconcileClosedPrReadyForMerge() {
25013
25983
  const actions = [];
25014
25984
  try {
25015
- const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CeSVFL6C.js");
25985
+ const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CU14oYzP.js");
25016
25986
  if (!isGitHubAppConfigured()) return actions;
25017
25987
  const statuses = loadReviewStatuses();
25018
25988
  const now = Date.now();
@@ -25084,7 +26054,7 @@ const STALE_MERGE_BLOCKER_COOLDOWN_MS = 120 * 1e3;
25084
26054
  async function reconcileStaleMergeBlockers() {
25085
26055
  const actions = [];
25086
26056
  try {
25087
- const { resolveConflictGate, buildRealConflictGateDeps } = await import("./conflict-gate-BKalpcjL.js");
26057
+ const { resolveConflictGate, buildRealConflictGateDeps } = await import("./conflict-gate-CHU9K1vU.js");
25088
26058
  const statuses = loadReviewStatuses();
25089
26059
  const now = Date.now();
25090
26060
  const deps = buildRealConflictGateDeps();
@@ -25227,7 +26197,7 @@ async function checkFailedMergeRetry() {
25227
26197
  if (ciEntry.count === 5) {
25228
26198
  console.log(`[deacon] CI check failure for ${issueId} — retries exhausted, notifying work agent`);
25229
26199
  const ciNotes = status.mergeNotes || "CI checks are failing on the PR";
25230
- const { writeFeedbackFile } = await import("./feedback-writer-DDQNV8uc.js");
26200
+ const { writeFeedbackFile } = await import("./feedback-writer-Bx5z11mF.js");
25231
26201
  const ciFileResult = await Effect.runPromise(writeFeedbackFile({
25232
26202
  issueId,
25233
26203
  specialist: "merge-agent",
@@ -25259,7 +26229,7 @@ async function checkFailedMergeRetry() {
25259
26229
  ciRetryMap.set(issueId, ciEntry);
25260
26230
  console.log(`[deacon] CI check failure for ${issueId} — notifying agent to re-submit (attempt ${ciEntry.count}/5)`);
25261
26231
  const ciNotes = status.mergeNotes || "CI checks are failing on the PR";
25262
- const { writeFeedbackFile } = await import("./feedback-writer-DDQNV8uc.js");
26232
+ const { writeFeedbackFile } = await import("./feedback-writer-Bx5z11mF.js");
25263
26233
  const ciFileResult2 = await Effect.runPromise(writeFeedbackFile({
25264
26234
  issueId,
25265
26235
  specialist: "merge-agent",
@@ -25287,7 +26257,7 @@ async function checkFailedMergeRetry() {
25287
26257
  const lastNudge = timeoutNudgeCooldowns.get(issueIdForFb);
25288
26258
  if (!lastNudge || now - lastNudge >= TIMEOUT_NUDGE_COOLDOWN_MS) {
25289
26259
  const timeoutNotes = status.mergeNotes;
25290
- const { writeFeedbackFile } = await import("./feedback-writer-DDQNV8uc.js");
26260
+ const { writeFeedbackFile } = await import("./feedback-writer-Bx5z11mF.js");
25291
26261
  await Effect.runPromise(writeFeedbackFile({
25292
26262
  issueId: issueIdForFb,
25293
26263
  specialist: "merge-agent",
@@ -25392,7 +26362,7 @@ async function autoCloseOut(now = /* @__PURE__ */ new Date()) {
25392
26362
  } } : {}
25393
26363
  };
25394
26364
  try {
25395
- const { closeOut } = await import("./workflows-C5c-RPsY.js");
26365
+ const { closeOut } = await import("./workflows-C4mR0Reb.js");
25396
26366
  const result = await Effect.runPromise(closeOut(ctx));
25397
26367
  if (!result.success) {
25398
26368
  const failed = result.steps.find((step) => !step.success && !step.skipped);
@@ -25990,7 +26960,7 @@ async function nudgeStalledResumeWorkAgents() {
25990
26960
  const message = buildStalledResumePrompt(state);
25991
26961
  if (!message) continue;
25992
26962
  try {
25993
- const { messageAgent } = await import("./agents-Czz6R57Z.js");
26963
+ const { messageAgent } = await import("./agents-DyHKlq1I.js");
25994
26964
  await messageAgent(agentId, message);
25995
26965
  recordCooldown(agentId, ".last-stalled-resume-nudge");
25996
26966
  const action = `Re-sent stalled resume prompt to ${agentId} (${state.issueId})`;
@@ -26104,7 +27074,7 @@ async function nudgeIdleWorkAgentsWithOpenBeads() {
26104
27074
  "Continue the per-item workflow without asking — claim it (`pan task claim <item-id>`), implement, commit, push, then complete it through `pan task done <item-id>`. Inspection is conditional on metadata.requiresInspection (default false; check the plan item before deciding to call `pan inspect`). Do NOT end your turn with a multi-paragraph summary; just advance to the next bead."
26105
27075
  ].join("\n");
26106
27076
  try {
26107
- const { messageAgent } = await import("./agents-Czz6R57Z.js");
27077
+ const { messageAgent } = await import("./agents-DyHKlq1I.js");
26108
27078
  await messageAgent(agentId, message);
26109
27079
  writeFileSync(join$1(getAgentDir(agentId), ".last-bead-nudge"), String(Date.now()), "utf-8");
26110
27080
  const action = `Nudged idle ${agentId} (${state.issueId}) — ${openTasks.length} ready task(s)`;
@@ -27373,8 +28343,8 @@ async function cleanupStaleAgentState() {
27373
28343
  */
27374
28344
  async function cleanupAbandonedFeedback() {
27375
28345
  const actions = [];
27376
- const { getReviewStatusSync } = await import("./review-status-DXeqFpk5.js");
27377
- const { clearFeedbackFiles } = await import("./feedback-writer-DDQNV8uc.js");
28346
+ const { getReviewStatusSync } = await import("./review-status-Bnh-rdkY.js");
28347
+ const { clearFeedbackFiles } = await import("./feedback-writer-Bx5z11mF.js");
27378
28348
  for (const { issueId, workspacePath } of listFeatureWorkspaces()) {
27379
28349
  const panFeedbackDir = join$1(workspacePath, ".pan", "feedback");
27380
28350
  if (!existsSync(panFeedbackDir)) continue;
@@ -27445,7 +28415,7 @@ async function handleOrphanReviewerSession(sessionName, sessions, creationTimes,
27445
28415
  if (!issueId) return null;
27446
28416
  const agentSession = `agent-${issueId.toLowerCase()}`;
27447
28417
  if (sessions.includes(agentSession)) return null;
27448
- const { getReviewStatusSync } = await import("./review-status-DXeqFpk5.js");
28418
+ const { getReviewStatusSync } = await import("./review-status-Bnh-rdkY.js");
27449
28419
  try {
27450
28420
  if (getReviewStatusSync(issueId)?.reviewStatus === "reviewing") return null;
27451
28421
  } catch {}
@@ -27567,7 +28537,7 @@ async function checkOrphanedCompletions() {
27567
28537
  async function checkPendingTestDispatch() {
27568
28538
  const actions = [];
27569
28539
  try {
27570
- const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-DXeqFpk5.js");
28540
+ const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-Bnh-rdkY.js");
27571
28541
  const statuses = loadReviewStatuses();
27572
28542
  const now = Date.now();
27573
28543
  for (const [issueId, status] of Object.entries(statuses)) {
@@ -27600,7 +28570,7 @@ async function checkPendingTestDispatch() {
27600
28570
  console.log(`[deacon] ${issueId}: skipping test re-dispatch — issue is closed`);
27601
28571
  continue;
27602
28572
  }
27603
- const { resolveProjectFromIssueSync } = await import("./projects-IRHJIPYC.js");
28573
+ const { resolveProjectFromIssueSync } = await import("./projects-BKkwpH6q.js");
27604
28574
  const resolved = resolveProjectFromIssueSync(issueId);
27605
28575
  if (!resolved) continue;
27606
28576
  const issueLower = issueId.toLowerCase();
@@ -27615,8 +28585,8 @@ async function checkPendingTestDispatch() {
27615
28585
  logDeaconEventSync(`checkPendingTestDispatch: deferred test for ${issueId} — advancing ceiling reached (PAN-1665) — ${describeRunningAgents()}`);
27616
28586
  continue;
27617
28587
  }
27618
- const { spawnRun } = await import("./agents-Czz6R57Z.js");
27619
- const { buildTestRolePrompt } = await import("./test-agent-queue-BwpUpu-o.js");
28588
+ const { spawnRun } = await import("./agents-DyHKlq1I.js");
28589
+ const { buildTestRolePrompt } = await import("./test-agent-queue-BJZ9Nfcc.js");
27620
28590
  try {
27621
28591
  const run = await spawnRun(issueId, "test", {
27622
28592
  workspace,
@@ -27739,7 +28709,7 @@ async function checkCompletedButUnsignaledTests() {
27739
28709
  const cmd = `pan admin specialists done test ${issueId} --status ${decision.status}${noteArg}`;
27740
28710
  const nudge = `Your test verdict (${decision.status}) is already written to .pan/test/result.json. Your ONLY remaining task is to execute this Bash command immediately — do not analyze, do not summarize, do not ask questions, just run it:\n\n${cmd}\n\nRun this command NOW. Do not write any other response before executing it.`;
27741
28711
  try {
27742
- const { messageAgent } = await import("./agents-Czz6R57Z.js");
28712
+ const { messageAgent } = await import("./agents-DyHKlq1I.js");
27743
28713
  await messageAgent(testSession, nudge);
27744
28714
  unsignaledTestNudges.set(testSession, now);
27745
28715
  const msg = `Nudged ${testSession} to signal ${decision.status} (verdict artifact present)`;
@@ -27753,7 +28723,7 @@ async function checkCompletedButUnsignaledTests() {
27753
28723
  case "nudge-write": {
27754
28724
  const nudge = `Your test run for ${issueId} looks finished but no verdict was recorded. Decide the verdict from the gates/UAT you ran, then do BOTH of these now: (1) write the workspace file .pan/test/result.json as {"status":"passed"|"failed","notes":"<evidence>"}, and (2) run: pan admin specialists done test ${issueId} --status passed|failed. Do this immediately — do not summarize or ask questions, just write the file and run the command.`;
27755
28725
  try {
27756
- const { messageAgent } = await import("./agents-Czz6R57Z.js");
28726
+ const { messageAgent } = await import("./agents-DyHKlq1I.js");
27757
28727
  await messageAgent(testSession, nudge);
27758
28728
  unsignaledTestNudges.set(testSession, now);
27759
28729
  const msg = `Nudged ${testSession} to write+signal a test verdict (no artifact yet)`;
@@ -27776,8 +28746,8 @@ async function checkCompletedButUnsignaledTests() {
27776
28746
  async function checkVerificationReviewContradiction() {
27777
28747
  const actions = [];
27778
28748
  try {
27779
- const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-DXeqFpk5.js");
27780
- const { resolveProjectFromIssueSync } = await import("./projects-IRHJIPYC.js");
28749
+ const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-Bnh-rdkY.js");
28750
+ const { resolveProjectFromIssueSync } = await import("./projects-BKkwpH6q.js");
27781
28751
  const statuses = loadReviewStatuses();
27782
28752
  for (const [issueId, status] of Object.entries(statuses)) if (status.verificationStatus === "passed" && status.reviewStatus === "reviewing" && status.stuckReason === "review_infrastructure_failure") {
27783
28753
  let reviewedAtCommit;
@@ -27826,7 +28796,7 @@ async function checkPostReviewCommits() {
27826
28796
  const actions = [];
27827
28797
  try {
27828
28798
  const statuses = loadReviewStatuses();
27829
- const { resolveProjectFromIssueSync } = await import("./projects-IRHJIPYC.js");
28799
+ const { resolveProjectFromIssueSync } = await import("./projects-BKkwpH6q.js");
27830
28800
  for (const [issueId, status] of Object.entries(statuses)) {
27831
28801
  if (status.mergeStatus === "merged") continue;
27832
28802
  if (!status.reviewedAtCommit) continue;
@@ -27881,7 +28851,7 @@ async function checkPostReviewCommits() {
27881
28851
  actions.push(`Deferred post-review re-dispatch for ${issueId} — advancing-role concurrency ceiling reached`);
27882
28852
  logDeaconEventSync(`checkPostReviewCommits: deferred review for ${issueId} — advancing ceiling reached (PAN-1665) — ${describeRunningAgents()}`);
27883
28853
  } else if (freshStatus?.reviewStatus === "pending") {
27884
- const { spawnReviewRoleForIssue } = await import("./review-agent-CSswH985.js");
28854
+ const { spawnReviewRoleForIssue } = await import("./review-agent-CCum8sGe.js");
27885
28855
  const branch = `feature/${issueId.toLowerCase()}`;
27886
28856
  const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
27887
28857
  issueId,
@@ -27981,7 +28951,7 @@ async function checkReadyForMergeStuck() {
27981
28951
  const testStatusGreenCiReconcileCooldowns = /* @__PURE__ */ new Map();
27982
28952
  const TEST_STATUS_GREEN_CI_RECONCILE_COOLDOWN_MS = 300 * 1e3;
27983
28953
  async function reconcileTestStatusFromGreenCi() {
27984
- const { getCiCheckRunsState, getPullRequestHeadState, isGitHubAppConfigured } = await import("./github-app-CeSVFL6C.js");
28954
+ const { getCiCheckRunsState, getPullRequestHeadState, isGitHubAppConfigured } = await import("./github-app-CU14oYzP.js");
27985
28955
  return reconcileTestStatusFromGreenCiWithDeps({
27986
28956
  isGitHubAppConfigured,
27987
28957
  loadReviewStatuses,
@@ -28002,7 +28972,7 @@ async function reconcileTestStatusFromGreenCi() {
28002
28972
  */
28003
28973
  async function clearStaleCiFeedback(issueId) {
28004
28974
  const { readdir, rm } = await import("fs/promises");
28005
- const { resolveProjectFromIssueSync } = await import("./projects-IRHJIPYC.js");
28975
+ const { resolveProjectFromIssueSync } = await import("./projects-BKkwpH6q.js");
28006
28976
  const projectConfig = resolveProjectFromIssueSync(issueId);
28007
28977
  if (!projectConfig) return;
28008
28978
  const repoDir = projectConfig.projectPath;
@@ -28298,7 +29268,7 @@ async function checkWorkspaceContainerHealth(sharedState) {
28298
29268
  }
28299
29269
  }
28300
29270
  try {
28301
- const { resolveProjectFromIssueSync } = await import("./projects-IRHJIPYC.js");
29271
+ const { resolveProjectFromIssueSync } = await import("./projects-BKkwpH6q.js");
28302
29272
  const resolved = resolveProjectFromIssueSync(issueLower.toUpperCase());
28303
29273
  if (resolved) await killOrphanedWorkspaceProcesses(`${resolved.projectPath}/workspaces/feature-${issueLower}`);
28304
29274
  } catch {}
@@ -28347,8 +29317,8 @@ async function checkWorkspaceContainerHealth(sharedState) {
28347
29317
  async function checkMergedWorkSessions() {
28348
29318
  const actions = [];
28349
29319
  try {
28350
- const { selectMergedWorkSessions } = await import("./reap-terminal-sessions-C1mfzoZo.js");
28351
- const { setAgentPaused } = await import("./agents-Czz6R57Z.js");
29320
+ const { selectMergedWorkSessions } = await import("./reap-terminal-sessions-CaMkFOIH.js");
29321
+ const { setAgentPaused } = await import("./agents-DyHKlq1I.js");
28352
29322
  const toKill = selectMergedWorkSessions(loadReviewStatuses(), [...await Effect.runPromise(listSessionNames())]);
28353
29323
  for (const session of toKill) try {
28354
29324
  await Effect.runPromise(setAgentPaused(session, "merged — awaiting close-out (verify on main)", true));
@@ -28388,7 +29358,7 @@ const AWAITING_TEST_IDLE_REAP_MS = 600 * 1e3;
28388
29358
  async function checkAwaitingTestWorkSessions() {
28389
29359
  const actions = [];
28390
29360
  try {
28391
- const { selectAwaitingTestWorkSessions } = await import("./reap-terminal-sessions-C1mfzoZo.js");
29361
+ const { selectAwaitingTestWorkSessions } = await import("./reap-terminal-sessions-CaMkFOIH.js");
28392
29362
  const candidates = selectAwaitingTestWorkSessions(loadReviewStatuses(), [...await Effect.runPromise(listSessionNames())]);
28393
29363
  const now = Date.now();
28394
29364
  for (const session of candidates) {
@@ -28441,14 +29411,14 @@ async function runPatrol() {
28441
29411
  hasLoggedGlobalPauseSkip = false;
28442
29412
  addLog("info", `Patrol cycle ${state.patrolCycle} — checking per-project specialists`, state.patrolCycle);
28443
29413
  console.log(`[deacon] Patrol cycle ${state.patrolCycle} - checking per-project specialists`);
28444
- for (const a of await (await import("./stale-task-claims-CQSKZVq0.js")).patrolStaleTaskClaims()) {
29414
+ for (const a of await (await import("./stale-task-claims-L7pJkQFL.js")).patrolStaleTaskClaims()) {
28445
29415
  actions.push(a);
28446
29416
  addLog("action", a, state.patrolCycle);
28447
29417
  }
28448
29418
  const stuckRemediationActions = await checkStuckAgentRemediation();
28449
29419
  actions.push(...stuckRemediationActions);
28450
29420
  for (const a of stuckRemediationActions) addLog("action", a, state.patrolCycle);
28451
- const { reconcileInFlightJournals } = await import("./advancing-selfheal-CPOBO5ZS.js");
29421
+ const { reconcileInFlightJournals } = await import("./advancing-selfheal-cSvXNZLZ.js");
28452
29422
  const reconciledJournalActions = await reconcileInFlightJournals();
28453
29423
  actions.push(...reconciledJournalActions);
28454
29424
  for (const a of reconciledJournalActions) addLog("action", a, state.patrolCycle);
@@ -28460,7 +29430,7 @@ async function runPatrol() {
28460
29430
  const age = Date.now() - (pending.timestamp ?? 0);
28461
29431
  if (age < 3600 * 1e3) {
28462
29432
  console.log(`[deacon] Processing pending post-merge lifecycle for ${pending.issueId} (age: ${Math.round(age / 1e3)}s)`);
28463
- const { postMergeLifecycle } = await import("./merge-agent-CnORPiri.js");
29433
+ const { postMergeLifecycle } = await import("./merge-agent-B-SnXOoc.js");
28464
29434
  const { unlinkSync } = await import("fs");
28465
29435
  unlinkSync(pendingFile);
28466
29436
  await postMergeLifecycle(pending.issueId, pending.projectPath, pending.sourceBranch, { skipDeploy: true });
@@ -28474,7 +29444,7 @@ async function runPatrol() {
28474
29444
  } catch (err) {
28475
29445
  console.warn(`[deacon] Failed to process pending lifecycle: ${err.message}`);
28476
29446
  }
28477
- if (state.patrolCycle % 5 === 0) await (await import("./deploy-patrol-DmM6F-yw.js")).runScheduledDeployPatrol();
29447
+ if (state.patrolCycle % 5 === 0) await (await import("./deploy-patrol-1IrZxicY.js")).runScheduledDeployPatrol();
28478
29448
  const livenessActions = await reconcileAgentLiveness();
28479
29449
  actions.push(...livenessActions);
28480
29450
  for (const a of livenessActions) addLog("action", a, state.patrolCycle);
@@ -28506,7 +29476,7 @@ async function runPatrol() {
28506
29476
  actions.push(...suspendActions);
28507
29477
  for (const a of suspendActions) addLog("action", a, state.patrolCycle);
28508
29478
  try {
28509
- const { resolveProjectFromIssueSync } = await import("./projects-IRHJIPYC.js");
29479
+ const { resolveProjectFromIssueSync } = await import("./projects-BKkwpH6q.js");
28510
29480
  const allStatuses = loadReviewStatuses();
28511
29481
  for (const [issueId, status] of Object.entries(allStatuses)) {
28512
29482
  if (!status.readyForMerge || status.mergeStatus === "merged") continue;
@@ -28526,7 +29496,7 @@ async function runPatrol() {
28526
29496
  } catch (err) {
28527
29497
  console.warn(`[deacon] Failed to check workspace existence: ${err.message}`);
28528
29498
  }
28529
- const { checkMergedAdvancingSessions } = await import("./advancing-selfheal-CPOBO5ZS.js");
29499
+ const { checkMergedAdvancingSessions } = await import("./advancing-selfheal-cSvXNZLZ.js");
28530
29500
  const reapedWorkActions = await checkMergedWorkSessions();
28531
29501
  actions.push(...reapedWorkActions);
28532
29502
  for (const a of reapedWorkActions) addLog("action", a, state.patrolCycle);
@@ -28534,7 +29504,7 @@ async function runPatrol() {
28534
29504
  actions.push(...reapedMergedAdvancingActions);
28535
29505
  for (const a of reapedMergedAdvancingActions) addLog("action", a, state.patrolCycle);
28536
29506
  try {
28537
- const { refreshClaudeCredentialsForActiveRemoteAgents } = await import("./remote-completion-W67FNQ-A.js");
29507
+ const { refreshClaudeCredentialsForActiveRemoteAgents } = await import("./remote-completion-Dca3hAaa.js");
28538
29508
  const remoteCredentialActions = await refreshClaudeCredentialsForActiveRemoteAgents();
28539
29509
  actions.push(...remoteCredentialActions);
28540
29510
  for (const a of remoteCredentialActions) addLog(a.includes("failed") ? "warn" : "action", a, state.patrolCycle);
@@ -28542,7 +29512,7 @@ async function runPatrol() {
28542
29512
  addLog("warn", `Remote credential refresh patrol failed: ${err.message}`, state.patrolCycle);
28543
29513
  }
28544
29514
  try {
28545
- const { refreshHostHeartbeatForEphemeralVms } = await import("./remote-agents-BNORDWAX.js");
29515
+ const { refreshHostHeartbeatForEphemeralVms } = await import("./remote-agents-D6O_zETW.js");
28546
29516
  const heartbeatActions = await refreshHostHeartbeatForEphemeralVms();
28547
29517
  actions.push(...heartbeatActions);
28548
29518
  for (const a of heartbeatActions) addLog(a.includes("failed") ? "warn" : "action", a, state.patrolCycle);
@@ -28550,7 +29520,7 @@ async function runPatrol() {
28550
29520
  addLog("warn", `Remote heartbeat refresh patrol failed: ${err.message}`, state.patrolCycle);
28551
29521
  }
28552
29522
  try {
28553
- const { reapCompletedRemoteAgents } = await import("./remote-completion-W67FNQ-A.js");
29523
+ const { reapCompletedRemoteAgents } = await import("./remote-completion-Dca3hAaa.js");
28554
29524
  const remoteReap = await reapCompletedRemoteAgents();
28555
29525
  for (const r of remoteReap) if (r.status === "handed-off" || r.status === "error") {
28556
29526
  const msg = `Remote reap ${r.issueId}: ${r.status} (${r.details.join("; ")})`;
@@ -28735,7 +29705,7 @@ async function runPatrol() {
28735
29705
  const issueId = runtimeState.currentIssue;
28736
29706
  try {
28737
29707
  if (getReviewStatusSync(issueId)?.mergeStatus === "merging") {
28738
- const { resolveProjectFromIssueSync } = await import("./projects-IRHJIPYC.js");
29708
+ const { resolveProjectFromIssueSync } = await import("./projects-BKkwpH6q.js");
28739
29709
  const resolved = resolveProjectFromIssueSync(issueId);
28740
29710
  if (resolved) {
28741
29711
  const branch = `feature/${issueId.toLowerCase()}`;
@@ -28749,7 +29719,7 @@ async function runPatrol() {
28749
29719
  mergeStatus: "merged",
28750
29720
  readyForMerge: false
28751
29721
  });
28752
- const { postMergeLifecycle } = await import("./merge-agent-CnORPiri.js");
29722
+ const { postMergeLifecycle } = await import("./merge-agent-B-SnXOoc.js");
28753
29723
  postMergeLifecycle(issueId, resolved.projectPath).catch((err) => console.warn(`[deacon] postMergeLifecycle failed for ${issueId}: ${err}`));
28754
29724
  actions.push(`Auto-completed stale merge for ${issueId}`);
28755
29725
  } else {
@@ -28929,7 +29899,7 @@ function startDeacon() {
28929
29899
  logDeaconEventSync(`startDeacon: health monitor starting (patrol every ${config.patrolIntervalMs / 1e3}s)`);
28930
29900
  (async () => {
28931
29901
  await reconcileAgentLiveness();
28932
- const { runBootAdvancingSelfHeal } = await import("./advancing-selfheal-CPOBO5ZS.js");
29902
+ const { runBootAdvancingSelfHeal } = await import("./advancing-selfheal-cSvXNZLZ.js");
28933
29903
  await runBootAdvancingSelfHeal();
28934
29904
  runScheduledPatrol("startup");
28935
29905
  })().catch((err) => {
@@ -28999,6 +29969,6 @@ function assessDeaconPatrolFreshness(params) {
28999
29969
  };
29000
29970
  }
29001
29971
  //#endregion
29002
- export { reconcileFalseMerged as $, reconcileAgentLiveness as A, getSystemHealthSnapshot as At, isPreKickoffLaunchDeath as B, getLastPatrolResult as C, checkInspectAgentTimeouts as Ct, isDeaconRunning as D, getContainerHistory as Dt, handleAgentStoppedForOrphanReviewerSessions as E, formatUptime as Et, setAgentStatusChangedNotifier as F, isBootReconciliationCandidate as G, nudgeIdleWorkAgentsWithOpenBeads as H, setAgentStoppedNotifier as I, autoCloseOut as J, listBootReconciliationCandidates as K, setMergeReadyNotifier as L, resetPatrolHeartbeatForStartup as M, startSmeeProcessSync as Mt, runPatrol as N, loadConfig as O, getCurrentDockerStats as Ot, saveState as P, reconcileClosedPrReadyForMerge as Q, startDeacon as R, getDeaconStatus as S, INSPECT_TIMEOUT_MS as St, handleAgentStoppedEvent as T, getResourceStacks as Tt, nudgeStalledResumeWorkAgents as U, isRapidPostResumeDeath as V, redeliverUndeliveredKickoffs as W, checkFirstCompletionAgents as X, checkFailedMergeRetry as Y, ciRetryMap as Z, cleanupOrphanReviewerSessions as _, checkApiErrorAgents as _t, checkCompletedButUnsignaledTests as a, monitorReviewConvoySignals as at, containerRestartBackoffMs as b, stuckOverflowNativeRecoveryState as bt, checkMergedWorkSessions as c, checkStuckReviewing as ct, checkPostReviewCommits as d, checkOrphanedReviewStatuses as dt, reconcileMergedButReviewing as et, checkReadyForMergeStuck as f, handleReviewCoordinatorDied as ft, cleanupAbandonedFeedback as g, stalledReviewConvoyRecoveryState as gt, checkWorkspaceContainerHealth as h, reviewConvoyLiveness as ht, checkAwaitingTestWorkSessions as i, cleanupOrphanedReviewSessions as it, reconcileTestStatusFromGreenCi as j, isSmeeConfiguredSync as jt, loadState as k, getResourceConfig as kt, checkOrphanedCompletions as l, isSynthesisForActiveReviewRun as lt, checkVerificationReviewContradiction as m, recoverStalledReviewConvoys as mt, assessDeaconPatrolFreshness as n, reconcileStaleMergeStatus as nt, checkDeadEndAgents as o, synthesizeReviewFromReports as ot, checkStuckWorkAgents as p, handleWorkCompleted as pt, startBootReconciliation as q, checkAndSuspendIdleAgents as r, reconcileStuckReadyForMerge as rt, checkMassDeath as s, checkCompletedButUnsignaledReviews as st, applyBootReconciliationDecision as t, reconcileStaleMergeBlockers as tt, checkPendingTestDispatch as u, checkMissingReviewStatuses as ut, cleanupOrphanedPlanningSessions as v, contextOverflowRecoveryState as vt, handleAgentHeartbeatDeadEvent as w, classifyMemoryPressure as wt, getDeaconLogs as x, paneShowsClaudeBootBlockingScreen as xt, cleanupStaleAgentState as y, contextProactiveCompactState as yt, stopDeacon as z };
29972
+ export { reconcileClosedPrReadyForMerge as $, reconcileAgentLiveness as A, getAcceptedSystemHealthSnapshot as At, recordDeadEndNeedsYou as B, getLastPatrolResult as C, INSPECT_TIMEOUT_MS as Ct, isDeaconRunning as D, formatUptime as Dt, handleAgentStoppedForOrphanReviewerSessions as E, getResourceStacks as Et, setAgentStatusChangedNotifier as F, isSmeeConfiguredSync as Ft, redeliverUndeliveredKickoffs as G, isRapidPostResumeDeath as H, setAgentStoppedNotifier as I, startSmeeProcessSync as It, startBootReconciliation as J, isBootReconciliationCandidate as K, setMergeReadyNotifier as L, classifyAgentHealth as Lt, resetPatrolHeartbeatForStartup as M, getResourceConfig as Mt, runPatrol as N, getSystemHealthEvidenceSnapshot as Nt, loadConfig as O, getContainerHistory as Ot, saveState as P, getSystemHealthSnapshot as Pt, ciRetryMap as Q, startDeacon as R, getDeaconStatus as S, paneShowsClaudeBootBlockingScreen as St, handleAgentStoppedEvent as T, classifyMemoryPressure as Tt, nudgeIdleWorkAgentsWithOpenBeads as U, isPreKickoffLaunchDeath as V, nudgeStalledResumeWorkAgents as W, checkFailedMergeRetry as X, autoCloseOut as Y, checkFirstCompletionAgents as Z, cleanupOrphanReviewerSessions as _, stalledReviewConvoyRecoveryState as _t, checkCompletedButUnsignaledTests as a, cleanupOrphanedReviewSessions as at, containerRestartBackoffMs as b, contextProactiveCompactState as bt, checkMergedWorkSessions as c, checkCompletedButUnsignaledReviews as ct, checkPostReviewCommits as d, checkMissingReviewStatuses as dt, reconcileFalseMerged as et, checkReadyForMergeStuck as f, checkOrphanedReviewStatuses as ft, cleanupAbandonedFeedback as g, reviewConvoyLiveness as gt, checkWorkspaceContainerHealth as h, recoverStalledReviewConvoys as ht, checkAwaitingTestWorkSessions as i, reconcileStuckReadyForMerge as it, reconcileTestStatusFromGreenCi as j, getDeployStaleness as jt, loadState as k, getCurrentDockerStats as kt, checkOrphanedCompletions as l, checkStuckReviewing as lt, checkVerificationReviewContradiction as m, handleWorkCompleted as mt, assessDeaconPatrolFreshness as n, reconcileStaleMergeBlockers as nt, checkDeadEndAgents as o, monitorReviewConvoySignals as ot, checkStuckWorkAgents as p, handleReviewCoordinatorDied as pt, listBootReconciliationCandidates as q, checkAndSuspendIdleAgents as r, reconcileStaleMergeStatus as rt, checkMassDeath as s, synthesizeReviewFromReports as st, applyBootReconciliationDecision as t, reconcileMergedButReviewing as tt, checkPendingTestDispatch as u, isSynthesisForActiveReviewRun as ut, cleanupOrphanedPlanningSessions as v, checkApiErrorAgents as vt, handleAgentHeartbeatDeadEvent as w, checkInspectAgentTimeouts as wt, getDeaconLogs as x, stuckOverflowNativeRecoveryState as xt, cleanupStaleAgentState as y, contextOverflowRecoveryState as yt, stopDeacon as z };
29003
29973
 
29004
- //# sourceMappingURL=deacon-1s7bM5zn.js.map
29974
+ //# sourceMappingURL=deacon-CkT_kznS.js.map