@overdeck/desktop 0.45.21 → 0.45.23

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 (387) hide show
  1. package/package.json +1 -1
  2. package/server/{acceptance-criteria-CJIFA8Vg.js → acceptance-criteria-DOA0KgXx.js} +5 -5
  3. package/server/{advancing-selfheal-CPOBO5ZS.js → advancing-selfheal-BBu6DSNm.js} +6 -6
  4. package/server/{agent-gc-D6PUckBB.js → agent-gc-BV1q_2EV.js} +4 -4
  5. package/server/agent-state-Bg0lhqwj.js +3 -0
  6. package/server/{agent-state-service-DHwemt96.js → agent-state-service-CnzFKSAQ.js} +1 -1
  7. package/server/{agent-state-service-6MFQqnFy.js → agent-state-service-HoK8U4jW.js} +5 -5
  8. package/server/{agents-DbrHWunF.js → agents-B4Bjbkfv.js} +4 -4
  9. package/server/agents-FlIgQ3ql.js +3 -0
  10. package/server/{archive-planning-BOnwJq8M.js → archive-planning-DYrYojxl.js} +31 -7
  11. package/server/{archive-planning-MPpvQJL4.js → archive-planning-zkJb3BeM.js} +1 -1
  12. package/server/{artifact-index-jobs-BOoySTKD.js → artifact-index-jobs-C-xy7Z5v.js} +2 -2
  13. package/server/{backlog-auto-trigger-BUaFI44J.js → backlog-auto-trigger-GtG71X8H.js} +3 -3
  14. package/server/{behavior-Dg-D8eBG.js → behavior-B_-4EKF3.js} +2 -2
  15. package/server/{briefing-freshness-OouGbJ7d.js → briefing-freshness-DWdW7vUm.js} +2 -2
  16. package/server/{build-info-27NlbKhV.js → build-info-BT096lEl.js} +3 -3
  17. package/server/{build-info-Cv6CI7Gu.js → build-info-DgTqZkL5.js} +1 -1
  18. package/server/{checkpoint-manager-C7mFCY_E.js → checkpoint-manager-B7Bt29J0.js} +1 -1
  19. package/server/{checkpoint-manager-D64fCC4p.js → checkpoint-manager-DDqcGyu8.js} +2 -2
  20. package/server/checkpoint-worker.js +1 -1
  21. package/server/{checkpoints-Vh-J15ge.js → checkpoints-C-AXLfYT.js} +2 -2
  22. package/server/{checkpoints-DwZqT2qQ.js → checkpoints-CpgCjAlN.js} +1 -1
  23. package/server/{claude-hooks-provision-CS5W_dhI.js → claude-hooks-provision-C8wdRnN1.js} +1 -1
  24. package/server/{claude-hooks-provision-BVLGfHrv.js → claude-hooks-provision-but-_qGY.js} +2 -2
  25. package/server/{claude-permissions-C2OrLYKL.js → claude-permissions-H_5wHQZQ.js} +2 -2
  26. package/server/{claude-settings-overlay-DWXjafJh.js → claude-settings-overlay-BTENVmYf.js} +1 -1
  27. package/server/{claude-settings-overlay-DX-fMFpC.js → claude-settings-overlay-CbSz0Dvb.js} +2 -2
  28. package/server/cli-BsVIHwzC.js +3 -0
  29. package/server/{cli-mvpEOb3w.js → cli-vBeXbPrq.js} +9 -9
  30. package/server/{cliproxy-Dvsr4ZkW.js → cliproxy-Bgb2XCqi.js} +2 -2
  31. package/server/{cliproxy-7g1nObvB.js → cliproxy-DW0V86F8.js} +1 -1
  32. package/server/{close-issue-8F6uawYj.js → close-issue-Dn_4c4G8.js} +5 -5
  33. package/server/{closed-issue-reaper-BhV-r-tC.js → closed-issue-reaper-CWpY2uBw.js} +1 -1
  34. package/server/{closed-issue-reaper-BaYQYF6w.js → closed-issue-reaper-hANY_ehE.js} +9 -9
  35. package/server/codex-Dg7Is5yb.js +3 -0
  36. package/server/{codex-D_UBEOwL.js → codex-TmSi-yTv.js} +30 -8
  37. package/server/{codex-parser-BTzlOZiV.js → codex-parser-C4gSH-IR.js} +2 -2
  38. package/server/{config-CrduXs4a.js → config-CCvjQf27.js} +2 -2
  39. package/server/{config-nAB_F-Gp.js → config-DUIhMN_T.js} +1 -1
  40. package/server/{config-G1TOMJZA.js → config-DjLOdbgT.js} +2 -2
  41. package/server/{config-yaml-Ciyp2mYe.js → config-yaml-DvyMuOle.js} +177 -211
  42. package/server/{conflict-gate-BKalpcjL.js → conflict-gate-BSJkNTdp.js} +1 -1
  43. package/server/{conflict-gate-BLUNMs1i.js → conflict-gate-CmrYpa47.js} +3 -3
  44. package/server/{context-layers-YNpf6Q_I.js → context-layers-B3Nt58jl.js} +2 -2
  45. package/server/{context-layers-Cg9ZgVfx.js → context-layers-ZYFcWiyc.js} +3 -3
  46. package/server/{control-settings-D_79A6gp.js → control-settings-aP1ANIlI.js} +4 -4
  47. package/server/{conversation-compaction-DiuZbIUB.js → conversation-compaction-CNbTLB86.js} +8 -8
  48. package/server/{conversation-compaction-CMIeWW4_.js → conversation-compaction-DiG5zWQq.js} +1 -1
  49. package/server/{conversation-service-DQybSPUK.js → conversation-service-Du-MTNpJ.js} +6 -6
  50. package/server/{conversation-service-CWk8mEym.js → conversation-service-Up7FEzIC.js} +1 -1
  51. package/server/{conversations-BJ-t3BRm.js → conversations-6mPANqvL.js} +1 -1
  52. package/server/{conversations-BUgGvqVL.js → conversations-DbOs1e9Q.js} +4 -4
  53. package/server/{cost-jJ2cgDcG.js → cost-CW4WSe72.js} +3 -3
  54. package/server/{cost-Drm7qeD5.js → cost-Ca0YTWDw.js} +18 -2
  55. package/server/{cost-sync-DzHP6zaR.js → cost-sync-C0VdGme1.js} +3 -3
  56. package/server/{dag-DIji6O2b.js → dag-CdOjJVDT.js} +9 -9
  57. package/server/{dangerous-git-ops-BebB-61h.js → dangerous-git-ops-CT-IypG3.js} +1 -1
  58. package/server/dashboard-db-worker.js +7 -7
  59. package/server/{deacon-pleYrvIm.js → deacon-DYSEJb48.js} +3 -3
  60. package/server/{deacon-nudge-log-C5VCKtyi.js → deacon-nudge-log-Bjg8U4Y9.js} +3 -3
  61. package/server/{deacon-1s7bM5zn.js → deacon-pRnyD5w9.js} +1133 -474
  62. package/server/deacon-swarm-9jRLS5Ke.js +2 -0
  63. package/server/{deacon-swarm-DmA3rJ7k.js → deacon-swarm-DftYRDo8.js} +17 -17
  64. package/server/deacon.js +8 -8
  65. package/server/{deploy-patrol-DmM6F-yw.js → deploy-patrol-Bjsho_ha.js} +136 -19
  66. package/server/{deploy-window-ClLq1RYf.js → deploy-window-CM6W1-c6.js} +1 -1
  67. package/server/{deploy-window-jw4S_Y-c.js → deploy-window-DeP_OIRk.js} +77 -10
  68. package/server/{dev-supervisor-Do2Stz49.js → dev-supervisor-BpMoHlkR.js} +2 -2
  69. package/server/{devcontainer-renderer-D8ylupco.js → devcontainer-renderer-CtUgrVKW.js} +3 -3
  70. package/server/dist-Bd3vn0Hw.js +3 -0
  71. package/server/{dist-yfR7G1BL.js → dist-DyRx4cI7.js} +1 -1
  72. package/server/{docker-ClwPQaba.js → docker-BK7HIcBj.js} +2 -2
  73. package/server/{dod-BLphkhjs.js → dod-BrSfUHm0.js} +1 -1
  74. package/server/{ensure-devcontainer-BA3bICoY.js → ensure-devcontainer-DRqaAkBR.js} +1 -1
  75. package/server/{ensure-devcontainer-CFpQatOc.js → ensure-devcontainer-DseivYEy.js} +4 -4
  76. package/server/{esm-shims-BZw-fTQ6.js → esm-shims-CbI3BVkl.js} +1 -1
  77. package/server/{event-store-DABarGNz.js → event-store-Cr5PQwFC.js} +1 -1
  78. package/server/{event-store-BVnON3vf.js → event-store-tdiY5eDZ.js} +3 -3
  79. package/server/{events-CmERlnwn.js → events-CC1dgUpx.js} +3 -3
  80. package/server/{events-LGeUehYW.js → events-CvvGK6LT.js} +1 -1
  81. package/server/{factory-CQNprtHe.js → factory-CynerjXO.js} +50 -13
  82. package/server/{feature-registry-population-D9Z3tYSa.js → feature-registry-population-B0pmAz0a.js} +4 -4
  83. package/server/{feature-registry-storage-BWymOgXE.js → feature-registry-storage-_wUBRD3J.js} +2 -2
  84. package/server/{features--fOza5g5.js → features-Dhxz-wLc.js} +2 -2
  85. package/server/{feedback-target-Dqik2WTe.js → feedback-target-CPS15Vte.js} +7 -7
  86. package/server/{feedback-target-Dn9vfPpz.js → feedback-target-iygZwmMc.js} +1 -1
  87. package/server/{feedback-writer-Wlq5-qgS.js → feedback-writer-C9b6ccN1.js} +6 -5
  88. package/server/{feedback-writer-DDQNV8uc.js → feedback-writer-qmiMbqTZ.js} +1 -1
  89. package/server/{flywheel-Q-38YhZG.js → flywheel-DMCUzDWg.js} +1 -1
  90. package/server/{flywheel-1Wd8WDlh.js → flywheel-DSSpWmqF.js} +13 -13
  91. package/server/{flywheel-DPUc8r3V.js → flywheel-DcBkQvgE.js} +14 -14
  92. package/server/{flywheel-merge-order-CeBuX0EJ.js → flywheel-merge-order-C-6zRLvM.js} +1 -1
  93. package/server/{flywheel-merge-order-4SqOXFAr.js → flywheel-merge-order-DxbQKE1d.js} +8 -8
  94. package/server/forge-B-ZWyTRm.js +2 -0
  95. package/server/{forge-DBbDpiYc.js → forge-Ch9gCFod.js} +2 -2
  96. package/server/{from-hh6vTBGl.js → from-CJ_aH5jD.js} +1 -1
  97. package/server/{fts-db-6ponMie2.js → fts-db-CKgg0VKg.js} +2 -2
  98. package/server/{fts-operations-KIRK165y.js → fts-operations-BrL_VTRr.js} +2 -2
  99. package/server/git-utils-BVa07a4a.js +198 -0
  100. package/server/{git-utils-DmF5xkj8.js → git-utils-Dry_Ka_D.js} +1 -1
  101. package/server/{github-app-B3yfECo8.js → github-app-CMBdIFBQ.js} +11 -3
  102. package/server/{github-app-CeSVFL6C.js → github-app-CPfoFAdV.js} +1 -1
  103. package/server/{github-client-Dslipypz.js → github-client--XVlDpwM.js} +2 -2
  104. package/server/{github-client-4A6FgA8O.js → github-client-B4QsdE-X.js} +1 -1
  105. package/server/{github-pr-lookup-DBP0YHMr.js → github-pr-lookup-BRbDW-qk.js} +2 -2
  106. package/server/harness-binary-CVio2m-u.js +106 -0
  107. package/server/{harness-resolve-BGpO-OVM.js → harness-resolve-qHJBhy3Z.js} +9 -15
  108. package/server/{health-events-CZGZ5I-A.js → health-events-C9B8y1Hm.js} +2 -2
  109. package/server/{health-events-CnwV_SSz.js → health-events-CpfvuVmm.js} +1 -1
  110. package/server/{hooks-CoNscX84.js → hooks-DUXw8A0-.js} +2 -2
  111. package/server/{hooks-DvX33gY_.js → hooks-ltecuFqZ.js} +1 -1
  112. package/server/{hume-DSJt5eA_.js → hume-BEq0bUDg.js} +2 -2
  113. package/server/hume-B_DbflNM.js +3 -0
  114. package/server/{idle-stack-reaper-5DVRoY6P.js → idle-stack-reaper-D7w9t3fE.js} +1 -1
  115. package/server/{idle-stack-reaper-BfL8HqYy.js → idle-stack-reaper-w1ISSlhs.js} +2 -2
  116. package/server/{in-flight-guard-tVGiI5ee.js → in-flight-guard-aQ1IxeI3.js} +2 -2
  117. package/server/{infra-DN2wSxle.js → infra-CzaSOgul.js} +4 -4
  118. package/server/{injection-DtlT8Akv.js → injection-DZ0PfYa4.js} +7 -7
  119. package/server/{injection-DK9zh_HL.js → injection-oNZeoDhL.js} +1 -1
  120. package/server/{inspect-agent-DKByUS_F.js → inspect-agent-DJKLWcVT.js} +15 -11
  121. package/server/inspect-agent-ch-F-5Ci.js +2 -0
  122. package/server/{internal-token-DhfFiwW7.js → internal-token-Bb4XeV2x.js} +2 -2
  123. package/server/{internal-token-7bYL5v6K.js → internal-token-DXdfprGr.js} +1 -1
  124. package/server/{io-BiM-7Zsx.js → io-B3_AHDfr.js} +160 -184
  125. package/server/{issue-closed-Dfw3QDyZ.js → issue-closed-zhdvQicO.js} +7 -7
  126. package/server/{issue-lifecycle-B7HZWnTA.js → issue-lifecycle-CreaCkjW.js} +22 -22
  127. package/server/{issue-lifecycle-ytsEdDlK.js → issue-lifecycle-Dy4vd0Oa.js} +1 -1
  128. package/server/{issue-service-singleton-CPESc4Or.js → issue-service-singleton-B5ushCvE.js} +8 -8
  129. package/server/{issue-service-singleton-D5EB5eYr.js → issue-service-singleton-DabvBWUp.js} +1 -1
  130. package/server/{issues-XYtFMxrH.js → issues-B6ToV6x1.js} +2 -2
  131. package/server/{jsonl-parser-DJV2eZUP.js → jsonl-parser-Dhflo1SH.js} +3 -3
  132. package/server/{label-cleanup-CJ4m8iRU.js → label-cleanup-BKPJm4Hv.js} +3 -3
  133. package/server/{label-reconciler-CNf3Ylm3.js → label-reconciler-DdWbHEBu.js} +4 -4
  134. package/server/{launcher-generator-5DJRiovn.js → launcher-generator-CHVm7bGT.js} +10 -9
  135. package/server/{layers-cZx7ibtV.js → layers-DzxSTGNA.js} +2 -2
  136. package/server/lifecycle-DfeyBDwA.js +121 -0
  137. package/server/lifecycle-io-Bsnr2K4F.js +3 -0
  138. package/server/{lifecycle-io-DMurK4oM.js → lifecycle-io-D8iNBcux.js} +37 -37
  139. package/server/{lifecycle-CE7619Xw.js → lifecycle-sycO16hj.js} +6 -6
  140. package/server/{linear-client-BLyN-NiP.js → linear-client-D4zqMnX7.js} +2 -2
  141. package/server/{linear-client-Bj1l4FOA.js → linear-client-DqhDQO9k.js} +1 -1
  142. package/server/memory-fts-worker.js +1 -1
  143. package/server/{merge-hSC2BENe.js → merge-C_ZEhbqI.js} +3 -3
  144. package/server/{merge-CwX2_AWm.js → merge-DK23JEdS.js} +1 -1
  145. package/server/{merge-agent-CnORPiri.js → merge-agent-BQM3a8z5.js} +1 -1
  146. package/server/{merge-agent-DnBsms_V.js → merge-agent-XrB80vfT.js} +369 -213
  147. package/server/{merge-batch-C2w2U2eK.js → merge-batch-Bwoyr8Je.js} +1 -1
  148. package/server/{merge-blockers-DhRgh76x.js → merge-blockers-BsFjGrQ8.js} +2 -2
  149. package/server/merge-ops-DlB1IM0Y.js +2 -0
  150. package/server/{merge-rebase-CE-ZyOMY.js → merge-rebase-C1KIVr0s.js} +2 -2
  151. package/server/{merge-set-D7YNU1ZB.js → merge-set-DLz0MkGT.js} +3 -3
  152. package/server/{merge-set-DHkzPCJU.js → merge-set-DnSYdBEp.js} +1 -1
  153. package/server/{merge-sync-De1FYva5.js → merge-sync-DZ9dojJn.js} +2 -2
  154. package/server/{merge-sync-CpGA9Kg7.js → merge-sync-SSv3E-pl.js} +1 -1
  155. package/server/{merge-train-SvkRJZ-k.js → merge-train-DxDfBTjr.js} +3 -3
  156. package/server/{merge-train-deps-CECJTElu.js → merge-train-deps-CyYQUksx.js} +4 -4
  157. package/server/{merge-verification-B3meGcXF.js → merge-verification-CSizH3HY.js} +4 -4
  158. package/server/{multipart-parser-ByTMgYV5.js → multipart-parser-Dt8YPN5S.js} +2 -2
  159. package/server/{no-resume-mode-BnInAFKs.js → no-resume-mode-Cx3K0hHi.js} +11 -8
  160. package/server/node_modules/.package-lock.json +5 -5
  161. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/README.md +3 -3
  162. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.d.ts.map +1 -1
  163. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.js +2 -2
  164. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.js.map +1 -1
  165. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/package.json +5 -5
  166. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/NodeChildProcessSpawner.ts +6 -8
  167. package/server/{orphan-proposed-reconciler-CAfuWTA1.js → orphan-proposed-reconciler-BTkDrl4R.js} +1 -1
  168. package/server/{orphan-proposed-reconciler-AxAGUouN.js → orphan-proposed-reconciler-neK8dHQk.js} +23 -14
  169. package/server/package-lock.json +6 -6
  170. package/server/package.json +1 -1
  171. package/server/{pan-dir-Rw17YjT1.js → pan-dir-DeVUgwA7.js} +78 -58
  172. package/server/{paths-FP8v3lTz.js → paths-_zEts6wc.js} +2 -2
  173. package/server/{pickup-xi3KTLaJ.js → pickup-Dd0Znxxy.js} +2 -2
  174. package/server/{pipeline-membership-BtKMNY7v.js → pipeline-membership-0HaEGDlH.js} +190 -68
  175. package/server/{pipeline-notifier-dQ-U4NSb.js → pipeline-notifier-6iCJplFZ.js} +1 -1
  176. package/server/{pipeline-notifier-BM2HLF7B.js → pipeline-notifier-D0ykk59O.js} +2 -2
  177. package/server/{project-pipelines-B59NfN44.js → project-pipelines-2sK1apsO.js} +2 -2
  178. package/server/projects-9SkRpES9.js +3 -0
  179. package/server/{prompts-CbqaVjbe.js → prompts-Dp4Tpk39.js} +2 -2
  180. package/server/providers-DKkBXhxU.js +3 -0
  181. package/server/{providers-d3pwXGVE.js → providers-DV7ec8l7.js} +7 -7
  182. package/server/public/assets/{chunk-BO2N2NFS-BxYSL7J-.js → chunk-BO2N2NFS-CltymLRg.js} +4 -4
  183. package/server/public/assets/{diagram-OG6HWLK6-C_F9Q2as.js → diagram-OG6HWLK6-D2f6pjgA.js} +1 -1
  184. package/server/public/assets/{dist-DQNg4CiF.js → dist-BWR4qFiV.js} +1 -1
  185. package/server/public/assets/{dist-CLSlc6cV.js → dist-DEmlBBNQ.js} +3 -3
  186. package/server/public/assets/{ganttDiagram-6RSMTGT7-Cq0my-0C.js → ganttDiagram-6RSMTGT7-DnfiViPK.js} +1 -1
  187. package/server/public/assets/{highlighted-body-OFNGDK62-eZC03dGh.js → highlighted-body-OFNGDK62-B8Wrmj9H.js} +1 -1
  188. package/server/public/assets/index-CUr1xv8w.css +1 -0
  189. package/server/public/assets/{index-SLYGA8AQ.js → index-CsSuZQBI.js} +148 -145
  190. package/server/public/assets/{linear-6Fi3qnGg.js → linear-C9zFQpkX.js} +1 -1
  191. package/server/public/assets/mermaid-GHXKKRXX-BUAB8hqt.js +1 -0
  192. package/server/public/assets/{pieDiagram-4H26LBE5-Dpmc6xsv.js → pieDiagram-4H26LBE5-lR8H7Yjd.js} +1 -1
  193. package/server/public/assets/{prod-ojHllFvN.js → prod-B1jCQihw.js} +4 -4
  194. package/server/public/assets/{quadrantDiagram-W4KKPZXB-Ulr9gON5.js → quadrantDiagram-W4KKPZXB-CVQ2guem.js} +1 -1
  195. package/server/public/assets/{sankeyDiagram-5OEKKPKP-CwdHGXfL.js → sankeyDiagram-5OEKKPKP-eD1RB4gm.js} +1 -1
  196. package/server/public/assets/{xychartDiagram-2RQKCTM6-r-bEDzJh.js → xychartDiagram-2RQKCTM6-ChEC6dQn.js} +1 -1
  197. package/server/public/index.html +54 -10
  198. package/server/{pull-requests-D3N6HQzI.js → pull-requests--Ib2jTgy.js} +1 -1
  199. package/server/{pull-requests-CjjPj7v6.js → pull-requests-CXIhdCYD.js} +13 -11
  200. package/server/{queries-B5hl7lMQ.js → queries-6d7Cdtm7.js} +723 -110
  201. package/server/{rally-Dp0Gb1DN.js → rally-B708-nZn.js} +3 -3
  202. package/server/{rally-api-DGaFz5L5.js → rally-api-nY0ZANw3.js} +2 -2
  203. package/server/{rally-api-CKr0O4DJ.js → rally-api-yjQ0TfHd.js} +1 -1
  204. package/server/{rally-client-SVbjGvqj.js → rally-client-B1EJhfV0.js} +4 -4
  205. package/server/{rally-client-Cqf6EX_r.js → rally-client-CULK2XAY.js} +1 -1
  206. package/server/rally-njs_mJrt.js +3 -0
  207. package/server/reap-terminal-sessions-MWnqdLCJ.js +4 -0
  208. package/server/{reap-terminal-sessions-CjqRAGw7.js → reap-terminal-sessions-N3BTkmX_.js} +11 -28
  209. package/server/{rebuild-stack-DHqCLvLX.js → rebuild-stack-Dp4eLkt4.js} +6 -6
  210. package/server/{rebuild-stack-DjdpALr1.js → rebuild-stack-kA7XngID.js} +1 -1
  211. package/server/{reconstruct-cache-BqrCQt0o.js → reconstruct-cache-uWbZfjms.js} +6 -6
  212. package/server/record-t6V-3Dcj.js +3 -0
  213. package/server/{record-update-BlB8mpKO.js → record-update-DACtKh6_.js} +1 -1
  214. package/server/record-update-Dq0t2uBG.js +310 -0
  215. package/server/{recovery-trip-l1Hsi37x.js → recovery-trip-BJtIQuag.js} +2 -2
  216. package/server/{release-engine-CSI4K6Oj.js → release-engine-DZpmGGzb.js} +5 -5
  217. package/server/{release-set-BywwggrE.js → release-set-hnXd_kga.js} +3 -3
  218. package/server/{remote-DYziAkiZ.js → remote-4tiENDaI.js} +3 -3
  219. package/server/{remote-cnoeuDWn.js → remote-Br-ZWVIP.js} +3 -3
  220. package/server/{remote-agents-BNORDWAX.js → remote-agents-CRCg1L4H.js} +1 -1
  221. package/server/{remote-agents-CZ2rc8I0.js → remote-agents-nmty1mLu.js} +6 -6
  222. package/server/{remote-completion-W67FNQ-A.js → remote-completion-BbWNd10K.js} +13 -13
  223. package/server/resume-CcKqnTvE.js +3 -0
  224. package/server/{review-agent-CSswH985.js → review-agent-DJRO8EG8.js} +1 -1
  225. package/server/{review-agent-CqSqSHkU.js → review-agent-sKkE1FEL.js} +23 -23
  226. package/server/{review-artifacts-BBgnd5df.js → review-artifacts-BLbSC4ke.js} +5 -5
  227. package/server/{review-context-Ctp9BdNJ.js → review-context-BgX3lcCx.js} +9 -9
  228. package/server/{review-status-CCgPVK1h.js → review-status-A7quS5KJ.js} +56 -39
  229. package/server/review-status-C6n6-9f_.js +3 -0
  230. package/server/{review-status-enrichment-DtDRGpst.js → review-status-enrichment-tbOn_A_u.js} +3 -3
  231. package/server/review-status-source-CxuEjLGg.js +39 -0
  232. package/server/{review-status-sync-jnLgd04F.js → review-status-sync-BhSQ0d0l.js} +2 -2
  233. package/server/{review-status-sync-C792ksoJ.js → review-status-sync-To3-iS-N.js} +1 -1
  234. package/server/{review-verdict-feedback-D5lW0o3k.js → review-verdict-feedback-C1Kg8n7t.js} +1 -1
  235. package/server/{review-verdict-feedback-CMsIpTpy.js → review-verdict-feedback-CTRNtzXO.js} +7 -7
  236. package/server/{rollup-B3kQmNpl.js → rollup-B53Y81xK.js} +1 -1
  237. package/server/{rollup-CLj_AK9f.js → rollup-WA0VD-Rr.js} +8 -8
  238. package/server/{scanner-C4NeC4FE.js → scanner-D2743cp8.js} +11 -7
  239. package/server/{sequence-io-Ce-6grIY.js → sequence-io-Cg0zYj_E.js} +4 -4
  240. package/server/{sequencer-agent-Bpz0yGmG.js → sequencer-agent-BGY8gjg-.js} +5 -5
  241. package/server/server.js +1348 -963
  242. package/server/{service-CqAY8Kmk.js → service-DCpB_SGd.js} +154 -51
  243. package/server/{session-fork-uNo4rMRA.js → session-fork-BQ8_6H32.js} +2 -2
  244. package/server/{session-history-DUehL3KN.js → session-history-CVZDpS3c.js} +4 -4
  245. package/server/{settings-DP2OYLXL.js → settings-BZ5m1UCl.js} +3 -3
  246. package/server/settings-D0OSwos5.js +2 -0
  247. package/server/{settings-D9grjmaP.js → settings-ylxwqwQG.js} +2 -2
  248. package/server/{shadow-engineering-Bi_oIMtF.js → shadow-engineering-BlxG6Xye.js} +3 -3
  249. package/server/{shadow-state-CDxEuPlE.js → shadow-state-C2_epgx2.js} +1 -1
  250. package/server/{shadow-state-a_ztFBJe.js → shadow-state-Dh-HzF2J.js} +2 -2
  251. package/server/{shadow-utils-CyOg6_Xq.js → shadow-utils-4bvjn9b3.js} +2 -2
  252. package/server/{ship-log-DDcueaIR.js → ship-log-ClSMIzZX.js} +1 -1
  253. package/server/{smart-compaction-C1_VVLEd.js → smart-compaction-CHIxLr_d.js} +1 -1
  254. package/server/{smart-compaction--Oj65Uov.js → smart-compaction-r4pHQBIr.js} +7 -7
  255. package/server/{spawn-planning-session-AiUSsBnH.js → spawn-planning-session-DWAorh2B.js} +25 -20
  256. package/server/{spawn-planning-session-LFtK2QCE.js → spawn-planning-session-KC_UduxD.js} +1 -1
  257. package/server/{specialist-completion-qOgqdqXH.js → specialist-completion-BXhav38U.js} +1 -1
  258. package/server/{specialist-context-gjj8Z4Ii.js → specialist-context-DtrYvGJ-.js} +5 -5
  259. package/server/{specialist-handoff-logger-BsBNvVZv.js → specialist-handoff-logger-C45ouoZ6.js} +2 -2
  260. package/server/{specialist-logs-CSLtvPx6.js → specialist-logs-DJ3RzKxW.js} +3 -3
  261. package/server/{specialists-D0VBf8g_.js → specialists-D5fRZXmN.js} +1 -1
  262. package/server/specialists-DVj0hvaL.js +3 -0
  263. package/server/{specialists-CYRwELzc.js → specialists-DyFeedjn.js} +66 -76
  264. package/server/{specialists-DAegTvRt.js → specialists-JVO00bs7.js} +374 -220
  265. package/server/specs-nN45DG2X.js +3 -0
  266. package/server/{src-OLoJhUiJ.js → src-CG9mCkP6.js} +6 -6
  267. package/server/{src-BqTcrfO_.js → src-CMTQGyCK.js} +3 -3
  268. package/server/{src-Dpq1yFIl.js → src-U7_kTPEE.js} +338 -4
  269. package/server/{stack-health-I713ELld.js → stack-health-Df0YEZKa.js} +1 -1
  270. package/server/{stack-health-DV_f-lK0.js → stack-health-puygdaMd.js} +2 -2
  271. package/server/{stale-task-claims-CQSKZVq0.js → stale-task-claims-BbFwCTb0.js} +4 -4
  272. package/server/{staleness-BbsGxmF2.js → staleness-Bpy41ngS.js} +15 -3
  273. package/server/{staleness-zGp4P1hd.js → staleness-Cbl_w4Bw.js} +1 -1
  274. package/server/{state-home-DixkE-up.js → state-home-CIGjwNfJ.js} +119 -54
  275. package/server/state-migrate-Dkzaxvny.js +487 -0
  276. package/server/{stuck-remediation-BWkK_O7A.js → stuck-remediation-CzEov_fq.js} +27 -21
  277. package/server/{stuck-remediation-CTPRC2S5.js → stuck-remediation-sY_MHHgQ.js} +1 -1
  278. package/server/{substrate-bug-weights-service-DXd0ID83.js → substrate-bug-weights-service-BH66lhm7.js} +3 -3
  279. package/server/{summary-fork-CdLn8Chr.js → summary-fork-D8bXjCr7.js} +2 -2
  280. package/server/{summary-fork-f3DpgjXh.js → summary-fork-DHhJIsAL.js} +8 -8
  281. package/server/{supervisor-Ch8CDuoF.js → supervisor-BO-Zk_h-.js} +3 -3
  282. package/server/supervisor-BPy-o1A8.js +2 -0
  283. package/server/{swarm-readiness-C9P2iPap.js → swarm-readiness-CQ_fwUWF.js} +4 -4
  284. package/server/{system-prerequisites-DkoQBn1q.js → system-prerequisites-Bza0ffAh.js} +24 -44
  285. package/server/{teardown-workspace-D-5yMyit.js → teardown-workspace-CEgauF4U.js} +15 -15
  286. package/server/{test-agent-queue-BwpUpu-o.js → test-agent-queue-DXDt0Xa-.js} +7 -7
  287. package/server/{test-verdict-BRiSu7eW.js → test-verdict-CmUBK5cT.js} +1 -1
  288. package/server/{test-verdict-BQ1yx7d4.js → test-verdict-DFjjIHR5.js} +1 -1
  289. package/server/{tldr-daemon-DjxP5g6Y.js → tldr-daemon-BDtLOIlO.js} +2 -2
  290. package/server/{tldr-daemon-BJA7TkqS.js → tldr-daemon-DL566HbH.js} +1 -1
  291. package/server/tmux-DoThH6aj.js +3 -0
  292. package/server/{tmux-y1blSxks.js → tmux-ftABRAmc.js} +76 -44
  293. package/server/{token-LUrbM9sU.js → token-CsOhvw42.js} +2 -2
  294. package/server/{token-util-BZaDAQ8S.js → token-util-CTmczIfW.js} +1 -1
  295. package/server/token-util-DrHg8abn.js +3 -0
  296. package/server/{tracker-config-DSFZBdXP.js → tracker-config-B4itFzDo.js} +2 -2
  297. package/server/{tracker-utils-WtP_V-yn.js → tracker-utils-BePq_oj-.js} +1 -1
  298. package/server/{tracker-utils-DiceZN3a.js → tracker-utils-tnxxqROg.js} +2 -2
  299. package/server/{traefik-connect-BXqfOP4-.js → traefik-connect-m73vGebA.js} +1 -1
  300. package/server/{tunnel-DTng1rfQ.js → tunnel-B2vxjx_b.js} +3 -3
  301. package/server/{tunnel-WcJImbAC.js → tunnel-Cgj-IGIl.js} +1 -1
  302. package/server/{types-BjaZ1oqH.js → types-BBNjPcqU.js} +1 -1
  303. package/server/{types-DqeBMmJN.js → types-hraoaQIp.js} +1 -1
  304. package/server/{uat-train-BpLnp7Cx.js → uat-train-CuEn0t9M.js} +28 -28
  305. package/server/{uat-train-Wismge7h.js → uat-train-cKfM-_WW.js} +1 -1
  306. package/server/{validation-BA4e5EGm.js → validation-B5JxoPUS.js} +259 -9
  307. package/server/{validation-CUWamZ4X.js → validation-CIi6pnI2.js} +1 -1
  308. package/server/{verification-artifact-Dr_0g9nb.js → verification-artifact-BcnIbigL.js} +1 -1
  309. package/server/{verification-artifact-CrbI4tJE.js → verification-artifact-C-lIHfUa.js} +1 -1
  310. package/server/{verification-runner-gAzh3cVD.js → verification-runner-Br0S_Ous.js} +103 -37
  311. package/server/{verification-runner-Dcksl_P-.js → verification-runner-CDj4lD4t.js} +1 -1
  312. package/server/{vtt-parser-3VZKsmSm.js → vtt-parser-DKpNNW5i.js} +1 -1
  313. package/server/{work-agent-prompt-ULdcANl5.js → work-agent-prompt-Yb2bd3Fq.js} +16 -15
  314. package/server/{workflows-B8ROFlfw.js → workflows-C9WmILql.js} +39 -77
  315. package/server/workflows-D90rMOya.js +2 -0
  316. package/server/{workspace-DhTDA8nB.js → workspace-BVl4rihN.js} +3 -3
  317. package/server/{workspace-DSjUJaJN.js → workspace-DuUdndHe.js} +1 -1
  318. package/server/{workspace-config-BAAsAv-o.js → workspace-config-cEGcO6UT.js} +1 -1
  319. package/server/{workspace-manager-CcujONCR.js → workspace-manager-ZTdJAy9M.js} +1 -1
  320. package/server/{workspace-manager-DsN52IMG.js → workspace-manager-hLUv3ADC.js} +23 -16
  321. package/server/{workspace-metadata-DIL5_U4c.js → workspace-metadata-CskwzzhL.js} +2 -2
  322. package/server/{workspace-metadata-CftOpNLs.js → workspace-metadata-DNpMixRq.js} +1 -1
  323. package/server/{workspaces-Dmlh1YXm.js → workspaces-hWvy9eKs.js} +276 -110
  324. package/sync-sources/agents/pan-inspect-agent.md +1 -1
  325. package/sync-sources/agents/pan-merge-agent.md +1 -1
  326. package/sync-sources/agents/pan-planning-agent.md +4 -4
  327. package/sync-sources/agents/pan-work-agent.md +1 -1
  328. package/sync-sources/dev-skills/pan-commit/SKILL.md +1 -1
  329. package/sync-sources/dev-skills/test-specialist-workflow/SKILL.md +1 -1
  330. package/sync-sources/hooks/record-cost-event.js +363 -71
  331. package/sync-sources/hooks/session-start-hook +7 -0
  332. package/sync-sources/hooks/work-agent-stop-hook +1 -1
  333. package/sync-sources/rules/per-bead-durability.md +1 -1
  334. package/sync-sources/rules/prd-authoring.md +1 -1
  335. package/sync-sources/skills/feature-work/SKILL.md +1 -1
  336. package/sync-sources/skills/pan/SKILL.md +2 -2
  337. package/sync-sources/skills/pan-admin-config/SKILL.md +1 -0
  338. package/sync-sources/skills/pan-approve/SKILL.md +1 -1
  339. package/sync-sources/skills/pan-close/SKILL.md +1 -1
  340. package/sync-sources/skills/pan-doctor/SKILL.md +1 -1
  341. package/sync-sources/skills/pan-new-project/SKILL.md +9 -11
  342. package/sync-sources/skills/pan-oversee/SKILL.md +5 -5
  343. package/sync-sources/skills/pan-plan/SKILL.md +6 -6
  344. package/sync-sources/skills/pan-quickstart/SKILL.md +1 -1
  345. package/sync-sources/skills/pan-recap/SKILL.md +2 -2
  346. package/sync-sources/skills/pan-review/SKILL.md +1 -1
  347. package/sync-sources/skills/pan-start/SKILL.md +26 -3
  348. package/sync-sources/skills/pan-swarm/SKILL.md +1 -1
  349. package/sync-sources/skills/pan-sync/SKILL.md +1 -1
  350. package/sync-sources/skills/pan-task/SKILL.md +2 -2
  351. package/sync-sources/skills/pan-wipe/SKILL.md +2 -2
  352. package/sync-sources/skills/pipeline-list/SKILL.md +1 -1
  353. package/sync-sources/skills/pipeline-status/SKILL.md +2 -2
  354. package/sync-sources/skills/plan/SKILL.md +11 -11
  355. package/sync-sources/skills/write-vbrief/SKILL.md +7 -282
  356. package/sync-sources/skills/write-xbrief/SKILL.md +295 -0
  357. package/sync-sources/templates/claude-md/sections/warnings.md +1 -1
  358. package/server/agent-state-BV_6RHnO.js +0 -3
  359. package/server/agents-Czz6R57Z.js +0 -3
  360. package/server/cli-ChErG518.js +0 -3
  361. package/server/codex-BBeZ8c3s.js +0 -3
  362. package/server/deacon-swarm-uudlSCLM.js +0 -2
  363. package/server/dist-BEDL2alY.js +0 -3
  364. package/server/forge-DbhJyH6u.js +0 -2
  365. package/server/git-utils-Bkxzr1Xf.js +0 -129
  366. package/server/hume-BrA1tUuk.js +0 -3
  367. package/server/inspect-agent-CyXNo9fM.js +0 -2
  368. package/server/lifecycle-io-CUpsxG0p.js +0 -3
  369. package/server/merge-ops-BpTtuO8x.js +0 -2
  370. package/server/projects-IRHJIPYC.js +0 -3
  371. package/server/providers-BqCdTryq.js +0 -3
  372. package/server/public/assets/index-C6NLz_1S.css +0 -1
  373. package/server/public/assets/mermaid-GHXKKRXX-BNwFoQsf.js +0 -1
  374. package/server/rally-DGimSRBQ.js +0 -3
  375. package/server/reap-terminal-sessions-C1mfzoZo.js +0 -3
  376. package/server/record-update-RviRDSNs.js +0 -168
  377. package/server/record-us0YECMO.js +0 -3
  378. package/server/resume-OyN3dEXE.js +0 -3
  379. package/server/review-status-DXeqFpk5.js +0 -3
  380. package/server/settings-BaPXXJsT.js +0 -2
  381. package/server/specialists-C6WkeKFK.js +0 -3
  382. package/server/specs-BsNcum0h.js +0 -3
  383. package/server/state-migrate-_zJJ6XKE.js +0 -362
  384. package/server/supervisor-Qy1QecAs.js +0 -2
  385. package/server/tmux-HQLgwo_C.js +0 -3
  386. package/server/token-util-Cg-QnowA.js +0 -3
  387. package/server/workflows-C5c-RPsY.js +0 -2
@@ -1,62 +1,183 @@
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 { Gr as sessionFilePath, Gt as reconcileStatePlaneDrift, Jt as getMainDivergence, Nt as readIssueRecordSync, Ot as init_record, Tn as init_projects, Ut as init_auto_commit, Vr as init_paths, Yt as init_state_plane, Zt as isStatePlanePath, b as DEFAULT_CONFIG$1, f as loadConfigSync, hr as AGENTS_DIR, kn as listProjectsSync, mr as init_errors, qt as STATE_PLANE_PATHS, s as init_load, wr as OVERDECK_HOME, x as init_defaults, yn as getProjectSync, zn as resolveProjectFromIssueSync } from "./config-yaml-DvyMuOle.js";
3
+ import { n as init_build_info, t as getBuildInfo } from "./build-info-BT096lEl.js";
4
+ import { n as getDashboardIdentity, t as recordDeaconNudge } from "./deacon-nudge-log-Bjg8U4Y9.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-Dq0t2uBG.js";
7
+ import { A as listPaneValues, B as sendKeysAsync, D as killSession, E as isPaneDead, H as sessionExists, I as querySessionSync, M as listSessionNames, N as listSessions, U as sessionExistsSync, i as capturePane, w as init_tmux, z as sendKeys } from "./tmux-ftABRAmc.js";
8
+ import { a as init_event_store, i as initEventStore } from "./event-store-tdiY5eDZ.js";
9
+ import { C as projectLegacySystemHealthSummary, t as init_src } from "./src-U7_kTPEE.js";
10
+ import { C as needsReviewDispatch, S as init_review_dispatch_decision, b as setReviewStatusSync, c as getReviewStatusSync, d as loadReviewStatuses, g as reviewGatesPassedSync, l as init_review_status } from "./review-status-A7quS5KJ.js";
11
+ import { c as listAllAgentsSync, d as isTerminalIssueStage, o as init_agents, u as getIssueStageSync } from "./agents-B4Bjbkfv.js";
12
+ import { $n as recordAgentFailure, Ar as init_codex_auth, Bn as getAgentDir, Cr as getAgentRuntimeStateSync, Ct as tryReserveAdvancingSlot, Dt as init_memory_verdict_cache, En as buildDefaultResumeContinueMessage, Ft as init_transcript_landing, G as resumeAgent, Gn as init_agent_state, Hn as getAgentState, J as isContextOverflowTail, K as init_context_overflow, Ln as clearAgentTroubledSync, Or as applyCodexAuthBurnFlag, Ot as setCachedMemoryVerdict, Pt as captureTranscriptUserRecordSnapshot, Rn as clearYieldForResumeSync, Sr as getAgentRuntimeState, St as resetPatrolDispatchBudget, Tr as saveAgentRuntimeState, Tt as workResumeSlotsAvailable, Wn as getAgentStateSync, X as messageAgent, Xn as markAgentRunningState, Y as init_messaging, _ as init_linux, a as listRunningAgentsSync, b as init_agents$1, bt as releaseAdvancingSlot, c as getRuntimeCensus, dt as init_termination, ft as stopAgent, g as LINUX_MEMORY_PRESSURE_DEFAULTS, gt as describeRunningAgents, h as init_collector, i as listRunningAgents, ir as saveAgentStateSync, jr as paneShowsCodexAuthBurn, jt as deliverInitialPromptWithRetry, m as createHostHealthCollector, mt as countRunningAgents, n as init_queries, nr as resetAgentFailureCount, or as setAgentPausedSync, r as listAgentStates, rr as saveAgentState, s as descendantPidsForSession, sr as setAgentYieldedSync, u as init_runtime_census, v as DARWIN_MEMORY_PRESSURE_DEFAULTS, vt as getConcurrencyLimits, wr as init_runtime_state, y as init_darwin, yt as init_concurrency } from "./queries-6d7Cdtm7.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-CVZDpS3c.js";
14
+ import { i as resolveGitHubIssueSync, n as init_tracker_utils } from "./tracker-utils-tnxxqROg.js";
15
+ import { i as ensureInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-Bb4XeV2x.js";
16
+ import { c as init_review_status_sync, l as markWorkspaceStuck } from "./review-status-sync-BhSQ0d0l.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-B3_AHDfr.js";
19
+ import { f as init_config, m as loadConfigSync$1, p as loadConfig$1 } from "./config-CCvjQf27.js";
20
+ import { T as stampBootReconciliation, h as setBootReconciliationDecision, l as isDeaconGloballyPaused, r as getBootReconciliationState, s as init_control_settings } from "./control-settings-aP1ANIlI.js";
21
+ import { c as init_docker_stats, s as DockerStatsCollector } from "./stack-health-puygdaMd.js";
22
+ import { l as init_dag, o as getDispatchableItems } from "./dag-CdOjJVDT.js";
23
+ import { a as loadCloisterConfigSync, i as loadCloisterConfig, r as init_config$1 } from "./config-DjLOdbgT.js";
24
+ import { a as findRecreatedLegacyStatePaths, o as init_state_home } from "./state-home-CIGjwNfJ.js";
25
+ import { A as withConcurrencyLimit, k as init_concurrency$1 } from "./github-app-CMBdIFBQ.js";
26
+ import { a as isAgentIdleForNudge, t as checkStuckAgentRemediation } from "./stuck-remediation-CzEov_fq.js";
27
+ import { n as __filename, r as init_esm_shims } from "./esm-shims-CbI3BVkl.js";
28
+ import { i as init_staleness, r as computeBuildStaleness } from "./staleness-Bpy41ngS.js";
29
+ import { a as pidsWithCwdUnder, i as sweepAutoCloseOutCache, n as pruneTerminalStoppedAgents, r as getAutoCloseOutCanonicalState } from "./agent-gc-BV1q_2EV.js";
30
+ import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-C9b6ccN1.js";
31
+ import { r as surfaceIssueFeedbackNeedsYou, t as init_feedback_target } from "./feedback-target-CPS15Vte.js";
32
+ 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-aQ1IxeI3.js";
33
+ import { J as parseReviewerSessionName, U as getTmuxSessionName, g as getAllProjectSpecialistStatuses, t as init_specialists } from "./specialists-DyFeedjn.js";
34
+ import { a as inferBranchFromWorkspace, i as findWorkspacePath, o as init_archive_planning } from "./archive-planning-DYrYojxl.js";
35
+ import { n as init_issue_closed, r as isIssueClosed } from "./issue-closed-zhdvQicO.js";
36
+ import { n as shouldSkipDispatchAsMerged, t as init_merge_verification } from "./merge-verification-CSizH3HY.js";
37
+ import { n as init_review_verdict_feedback, t as deliverReviewVerdictFeedback } from "./review-verdict-feedback-CTRNtzXO.js";
38
+ import { n as reconcileTraefikNetworks, t as init_traefik_connect } from "./traefik-connect-m73vGebA.js";
39
+ import { g as decideAgentAutonomousRedrive, r as coordinateSwarmSlots, y as listFeatureWorkspaces } from "./deacon-swarm-DftYRDo8.js";
40
+ import { t as recordRecoveryFailure } from "./recovery-trip-BJtIQuag.js";
41
+ import { n as isExplicitNoResumeRequest, t as init_no_resume_mode } from "./no-resume-mode-Cx3K0hHi.js";
42
+ import { n as reconcileClosedIssueAgents } from "./closed-issue-reaper-hANY_ehE.js";
43
+ import { n as init_label_reconciler, r as reconcilePipelineLabelsPatrol } from "./label-reconciler-DdWbHEBu.js";
44
+ import { a as spawnWorkAgentThroughAgentsEndpoint, i as reconcileOrphanProposedSpecs, o as triggerRebuildAndStart } from "./orphan-proposed-reconciler-neK8dHQk.js";
45
+ import { n as reconcileIdleWorkspaceStacks } from "./idle-stack-reaper-w1ISSlhs.js";
46
+ import { i as readTestVerdictArtifact, n as decideUnsignaledTestAction, r as init_test_verdict } from "./test-verdict-CmUBK5cT.js";
45
47
  import { createRequire } from "node:module";
46
48
  import { join } from "node:path";
47
49
  import { Effect } from "effect";
48
50
  import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "fs";
49
51
  import { dirname as dirname$1, join as join$1 } from "path";
50
52
  import { cpus, loadavg } from "os";
51
- 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";
53
+ import { freemem as freemem$1, homedir as homedir$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_darwin();
93
+ init_linux();
94
+ init_collector();
95
+ init_runtime_census();
96
+ init_queries();
97
+ const STARTUP_GRACE_MS = 300 * 1e3;
98
+ const ACTIVITY_WARNING_MS = 900 * 1e3;
99
+ const ACTIVITY_STALLED_MS = 1800 * 1e3;
100
+ function reason$1(code, severity, message) {
101
+ return {
102
+ code,
103
+ domain: "agent",
104
+ severity,
105
+ message
106
+ };
107
+ }
108
+ function validTimestamp(value) {
109
+ if (!value) return null;
110
+ const timestamp = Date.parse(value);
111
+ return Number.isFinite(timestamp) ? timestamp : null;
112
+ }
113
+ function latestActivity(persisted, runtime) {
114
+ const candidates = [persisted.lastActivity, runtime?.lastActivity].map((value) => ({
115
+ value,
116
+ timestamp: validTimestamp(value)
117
+ })).filter((entry) => entry.value !== void 0 && entry.timestamp !== null);
118
+ if (candidates.length === 0) return void 0;
119
+ return candidates.reduce((latest, entry) => entry.timestamp > latest.timestamp ? entry : latest).value;
120
+ }
121
+ function agentKind(role) {
122
+ if (role === "work") return "work";
123
+ if (role === "plan") return "planning";
124
+ if (role === "review" || role === "test" || role === "ship") return "specialist";
125
+ return "other";
126
+ }
127
+ function intentionalInactive(state) {
128
+ return state.status === "stopped" || state.status === "completed" || state.paused === true || state.stoppedByUser === true || state.stoppedByPause === true;
129
+ }
130
+ function lifecycleFor(input, state) {
131
+ if (input.reviewLifecycle === "warm" || input.reviewLifecycle === "orphaned") return input.reviewLifecycle;
132
+ if (input.liveSessions.has(input.agentId) && !intentionalInactive(state)) return "active";
133
+ return input.reviewLifecycle ?? "unknown";
134
+ }
135
+ function buildSnapshot(input, state, status, reasons) {
136
+ const lastActivityAt = latestActivity(state, input.runtime);
137
+ const observations = input.observations;
138
+ return {
139
+ id: input.agentId,
140
+ ...state.issueId ? { issueId: state.issueId } : {},
141
+ ...state.role ? { role: state.role } : {},
142
+ kind: agentKind(state.role),
143
+ status,
144
+ lifecycle: lifecycleFor(input, state),
145
+ tmuxActive: input.liveSessions.has(input.agentId),
146
+ ...lastActivityAt ? { lastActivityAt } : {},
147
+ ...observations?.consecutiveFailures !== void 0 ? { consecutiveFailures: observations.consecutiveFailures } : state.consecutiveFailures !== void 0 ? { consecutiveFailures: state.consecutiveFailures } : {},
148
+ ...observations?.killCount !== void 0 ? { killCount: observations.killCount } : {},
149
+ ...observations && Object.prototype.hasOwnProperty.call(observations, "contextPercent") ? { contextPercent: observations.contextPercent ?? null } : {},
150
+ reasons
151
+ };
152
+ }
153
+ /**
154
+ * Classifies one resolved agent snapshot. The function is intentionally free of
155
+ * filesystem, tmux, review-status, and runtime-store imports so every caller
156
+ * supplies one coherent set of evidence and cycle-prone dashboard code remains
157
+ * a thin resolver adapter.
158
+ */
159
+ function classifyAgentHealth(input) {
160
+ if (input.persisted.status === "unavailable") return buildSnapshot(input, {}, "unavailable", [reason$1("agent.persisted_state.unavailable", "warning", input.persisted.reason)]);
161
+ const state = input.persisted.value;
162
+ if (input.runtime?.contextSaturatedAt) return buildSnapshot(input, state, "wedged", [reason$1("agent.context.saturated", "critical", "Context window exhausted; recovery is required.")]);
163
+ const startedAt = validTimestamp(state.startedAt);
164
+ const startupGraceElapsed = startedAt !== null && input.nowMs - startedAt >= STARTUP_GRACE_MS;
165
+ const expectsLiveSession = state.status === "running" || state.status === "starting";
166
+ 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.")]);
167
+ 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")]);
168
+ 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.")]);
169
+ 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", []);
170
+ if (input.runtime?.state === "active") {
171
+ const lastActivityMs = validTimestamp(latestActivity(state, input.runtime));
172
+ if (lastActivityMs !== null) {
173
+ const inactivityMs = Math.max(0, input.nowMs - lastActivityMs);
174
+ 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.`)]);
175
+ 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.`)]);
176
+ }
177
+ }
178
+ return buildSnapshot(input, state, "healthy", []);
179
+ }
180
+ //#endregion
60
181
  //#region ../../../node_modules/.bun/undici@7.25.0/node_modules/undici/lib/core/symbols.js
61
182
  var require_symbols = /* @__PURE__ */ __commonJSMin(((exports, module) => {
62
183
  module.exports = {
@@ -21468,9 +21589,7 @@ var require_eventsource = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21468
21589
  defaultReconnectionTime
21469
21590
  };
21470
21591
  }));
21471
- //#endregion
21472
- //#region ../../../node_modules/.bun/undici@7.25.0/node_modules/undici/index.js
21473
- var require_undici = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21592
+ new ((/* @__PURE__ */ __commonJSMin(((exports, module) => {
21474
21593
  init_esm_shims();
21475
21594
  const Client = require_client();
21476
21595
  const Dispatcher = require_dispatcher();
@@ -21636,37 +21755,7 @@ var require_undici = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21636
21755
  globalThis.EventSource = module.exports.EventSource;
21637
21756
  }
21638
21757
  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();
21758
+ })))()).EnvHttpProxyAgent();
21670
21759
  //#endregion
21671
21760
  //#region ../../lib/smee.ts
21672
21761
  /**
@@ -21849,35 +21938,486 @@ function startSmeeProcessSync() {
21849
21938
  console.log(`[smee] Started process (PID ${child.pid}) relaying to ${target}`);
21850
21939
  }
21851
21940
  //#endregion
21852
- //#region services/system-health-service.ts
21853
- init_docker_stats();
21941
+ //#region ../../lib/system-health/config.ts
21854
21942
  init_build_info();
21855
- init_staleness();
21943
+ init_docker_stats();
21944
+ init_defaults();
21945
+ init_load();
21946
+ const GIB$2 = 1024 ** 3;
21947
+ const SYSTEM_HEALTH_DEFAULTS = Object.freeze({
21948
+ pollSeconds: 15,
21949
+ memoryWarnGb: DEFAULT_CONFIG$1.resources.memoryWarnGb,
21950
+ memoryBlockGb: DEFAULT_CONFIG$1.resources.memoryBlockGb,
21951
+ agentWarnCount: DEFAULT_CONFIG$1.resources.agentWarnCount,
21952
+ agentBlockCount: DEFAULT_CONFIG$1.resources.agentBlockCount,
21953
+ swapUsedWarningPercent: 20,
21954
+ swapUsedCriticalPercent: 50,
21955
+ cpuLoadWarningPerCore: 1,
21956
+ cpuLoadCriticalPerCore: 1.5,
21957
+ overcommitWarningPercent: 150,
21958
+ overcommitCriticalPercent: 200
21959
+ });
21960
+ function finiteNonnegative(value) {
21961
+ if (value === "" || value == null) return null;
21962
+ const parsed = typeof value === "number" ? value : Number(value);
21963
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : null;
21964
+ }
21965
+ /**
21966
+ * Normalizes every health threshold in one pass. Any invalid value or reversed
21967
+ * pair falls back to its named defaults, and the caller receives one warning
21968
+ * describing the complete fallback rather than one warning per field.
21969
+ */
21970
+ function normalizeSystemHealthThresholds(input, warn = console.warn) {
21971
+ const invalid = [];
21972
+ const scalar = (name, fallback, minimum = 0) => {
21973
+ const value = finiteNonnegative(input[name]);
21974
+ if (value == null || value < minimum) {
21975
+ invalid.push(String(name));
21976
+ return fallback;
21977
+ }
21978
+ return value;
21979
+ };
21980
+ const increasingPair = (warningName, criticalName, warningDefault, criticalDefault) => {
21981
+ const warning = finiteNonnegative(input[warningName]);
21982
+ const critical = finiteNonnegative(input[criticalName]);
21983
+ if (warning == null || critical == null || warning > critical) {
21984
+ invalid.push(`${String(warningName)}/${String(criticalName)}`);
21985
+ return [warningDefault, criticalDefault];
21986
+ }
21987
+ return [warning, critical];
21988
+ };
21989
+ const decreasingPair = (warningName, criticalName, warningDefault, criticalDefault) => {
21990
+ const warning = finiteNonnegative(input[warningName]);
21991
+ const critical = finiteNonnegative(input[criticalName]);
21992
+ if (warning == null || critical == null || warning < critical) {
21993
+ invalid.push(`${String(warningName)}/${String(criticalName)}`);
21994
+ return [warningDefault, criticalDefault];
21995
+ }
21996
+ return [warning, critical];
21997
+ };
21998
+ const [memoryWarnGb, memoryBlockGb] = decreasingPair("memoryWarnGb", "memoryBlockGb", SYSTEM_HEALTH_DEFAULTS.memoryWarnGb, SYSTEM_HEALTH_DEFAULTS.memoryBlockGb);
21999
+ const [agentWarnCountValue, agentBlockCountValue] = increasingPair("agentWarnCount", "agentBlockCount", SYSTEM_HEALTH_DEFAULTS.agentWarnCount, SYSTEM_HEALTH_DEFAULTS.agentBlockCount);
22000
+ const [swapUsedWarningPercent, swapUsedCriticalPercent] = increasingPair("swapUsedWarningPercent", "swapUsedCriticalPercent", SYSTEM_HEALTH_DEFAULTS.swapUsedWarningPercent, SYSTEM_HEALTH_DEFAULTS.swapUsedCriticalPercent);
22001
+ const [cpuLoadWarningPerCore, cpuLoadCriticalPerCore] = increasingPair("cpuLoadWarningPerCore", "cpuLoadCriticalPerCore", SYSTEM_HEALTH_DEFAULTS.cpuLoadWarningPerCore, SYSTEM_HEALTH_DEFAULTS.cpuLoadCriticalPerCore);
22002
+ const [overcommitWarningPercent, overcommitCriticalPercent] = increasingPair("overcommitWarningPercent", "overcommitCriticalPercent", SYSTEM_HEALTH_DEFAULTS.overcommitWarningPercent, SYSTEM_HEALTH_DEFAULTS.overcommitCriticalPercent);
22003
+ const pollSeconds = scalar("pollSeconds", SYSTEM_HEALTH_DEFAULTS.pollSeconds, 1);
22004
+ const agentWarnCount = Math.max(1, Math.floor(agentWarnCountValue));
22005
+ const agentBlockCount = Math.max(1, Math.floor(agentBlockCountValue));
22006
+ if (invalid.length > 0) warn(`[system-health] Invalid thresholds (${invalid.join(", ")}); using named defaults.`);
22007
+ return {
22008
+ pollSeconds: Math.max(1, Math.floor(pollSeconds)),
22009
+ resources: {
22010
+ memoryWarnGb,
22011
+ memoryBlockGb,
22012
+ agentWarnCount,
22013
+ agentBlockCount
22014
+ },
22015
+ thresholds: {
22016
+ memoryAvailableWarningBytes: memoryWarnGb * GIB$2,
22017
+ memoryAvailableCriticalBytes: memoryBlockGb * GIB$2,
22018
+ swapUsedWarningPercent,
22019
+ swapUsedCriticalPercent,
22020
+ cpuLoadWarningPerCore,
22021
+ cpuLoadCriticalPerCore,
22022
+ overcommitWarningPercent,
22023
+ overcommitCriticalPercent
22024
+ }
22025
+ };
22026
+ }
22027
+ function resolveSystemHealthConfig(options = {}) {
22028
+ const resources = options.resources ?? loadConfigSync().config.resources;
22029
+ const env = options.env ?? process.env;
22030
+ return normalizeSystemHealthThresholds({
22031
+ pollSeconds: env["PAN_HEALTH_POLL_SECONDS"] ?? SYSTEM_HEALTH_DEFAULTS.pollSeconds,
22032
+ memoryWarnGb: env["PAN_MEMORY_WARN_GB"] ?? resources.memoryWarnGb,
22033
+ memoryBlockGb: env["PAN_MEMORY_BLOCK_GB"] ?? resources.memoryBlockGb,
22034
+ agentWarnCount: env["PAN_AGENT_WARN_COUNT"] ?? resources.agentWarnCount,
22035
+ agentBlockCount: env["PAN_AGENT_BLOCK_COUNT"] ?? resources.agentBlockCount,
22036
+ swapUsedWarningPercent: env["PAN_HEALTH_SWAP_WARN_PERCENT"] ?? SYSTEM_HEALTH_DEFAULTS.swapUsedWarningPercent,
22037
+ swapUsedCriticalPercent: env["PAN_HEALTH_SWAP_CRITICAL_PERCENT"] ?? SYSTEM_HEALTH_DEFAULTS.swapUsedCriticalPercent,
22038
+ cpuLoadWarningPerCore: env["PAN_HEALTH_LOAD_WARN_PER_CORE"] ?? SYSTEM_HEALTH_DEFAULTS.cpuLoadWarningPerCore,
22039
+ cpuLoadCriticalPerCore: env["PAN_HEALTH_LOAD_CRITICAL_PER_CORE"] ?? SYSTEM_HEALTH_DEFAULTS.cpuLoadCriticalPerCore,
22040
+ overcommitWarningPercent: env["PAN_HEALTH_OVERCOMMIT_WARN_PERCENT"] ?? SYSTEM_HEALTH_DEFAULTS.overcommitWarningPercent,
22041
+ overcommitCriticalPercent: env["PAN_HEALTH_OVERCOMMIT_CRITICAL_PERCENT"] ?? SYSTEM_HEALTH_DEFAULTS.overcommitCriticalPercent
22042
+ }, options.warn);
22043
+ }
22044
+ //#endregion
22045
+ //#region ../../lib/system-health/evaluate.ts
22046
+ function value(signal) {
22047
+ return signal.status === "available" ? signal.value : null;
22048
+ }
22049
+ function reason(code, domain, severity, message, metric, observed, threshold) {
22050
+ return {
22051
+ code,
22052
+ domain,
22053
+ severity,
22054
+ message,
22055
+ metric,
22056
+ observed,
22057
+ threshold
22058
+ };
22059
+ }
22060
+ function evaluateAdmission(sample, thresholds) {
22061
+ const availableMemoryBytes = value(sample.availableMemoryBytes);
22062
+ if (availableMemoryBytes == null) return {
22063
+ state: "unavailable",
22064
+ availableMemoryBytes: null,
22065
+ reasons: [{
22066
+ code: "admission.memory_available.unavailable",
22067
+ domain: "admission",
22068
+ severity: "info",
22069
+ message: "Available memory could not be measured, so admission capacity is unavailable.",
22070
+ metric: "availableMemoryBytes"
22071
+ }]
22072
+ };
22073
+ if (availableMemoryBytes <= thresholds.memoryAvailableCriticalBytes) return {
22074
+ state: "blocked",
22075
+ availableMemoryBytes,
22076
+ reasons: [reason("admission.memory_available.blocked", "admission", "critical", "Available memory is at or below the critical admission reserve.", "availableMemoryBytes", availableMemoryBytes, thresholds.memoryAvailableCriticalBytes)]
22077
+ };
22078
+ if (availableMemoryBytes <= thresholds.memoryAvailableWarningBytes) return {
22079
+ state: "soft",
22080
+ availableMemoryBytes,
22081
+ reasons: [reason("admission.memory_available.soft", "admission", "warning", "Available memory is at or below the warning admission reserve.", "availableMemoryBytes", availableMemoryBytes, thresholds.memoryAvailableWarningBytes)]
22082
+ };
22083
+ return {
22084
+ state: "open",
22085
+ availableMemoryBytes,
22086
+ reasons: []
22087
+ };
22088
+ }
22089
+ function diagnostics(sample, thresholds) {
22090
+ const results = [];
22091
+ const swapUsedPercent = value(sample.swapUsedPercent);
22092
+ 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));
22093
+ const virtualCommitmentPercent = value(sample.virtualCommitmentPercent);
22094
+ 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));
22095
+ return results;
22096
+ }
22097
+ function linuxPressureReasons(sample, admission) {
22098
+ const results = [];
22099
+ const some = value(sample.memoryPressureSomeAvg10);
22100
+ const full = value(sample.memoryPressureFullAvg10);
22101
+ const swapActivity = value(sample.swapActivityBytesPerMinute);
22102
+ if (admission.state === "blocked") {
22103
+ 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));
22104
+ 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));
22105
+ }
22106
+ if (admission.state === "soft" || admission.state === "blocked") {
22107
+ 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));
22108
+ 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));
22109
+ }
22110
+ return results;
22111
+ }
22112
+ function darwinPressureReasons(sample) {
22113
+ const freePercent = value(sample.memoryPressureFreePercent);
22114
+ if (freePercent == null) return [];
22115
+ 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)];
22116
+ 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)];
22117
+ return [];
22118
+ }
22119
+ function hasCurrentPressureSignal(sample) {
22120
+ if (sample.platform === "linux") return value(sample.memoryPressureSomeAvg10) != null || value(sample.memoryPressureFullAvg10) != null || value(sample.swapActivityBytesPerMinute) != null;
22121
+ if (sample.platform === "darwin") return value(sample.memoryPressureFreePercent) != null;
22122
+ return false;
22123
+ }
22124
+ function evaluateHostPressure(sample, thresholds) {
22125
+ const admission = evaluateAdmission(sample, thresholds);
22126
+ const diagnosticReasons = diagnostics(sample, thresholds);
22127
+ if (!hasCurrentPressureSignal(sample)) return {
22128
+ state: "unavailable",
22129
+ reasons: [{
22130
+ code: "host.current_pressure.unavailable",
22131
+ domain: "host",
22132
+ severity: "info",
22133
+ message: "The platform collector could not measure a current-pressure signal."
22134
+ }, ...diagnosticReasons],
22135
+ diagnostics: diagnosticReasons,
22136
+ admission
22137
+ };
22138
+ const pressureReasons = sample.platform === "linux" ? linuxPressureReasons(sample, admission) : darwinPressureReasons(sample);
22139
+ return {
22140
+ state: pressureReasons.some((entry) => entry.severity === "critical") ? "critical" : pressureReasons.some((entry) => entry.severity === "warning") ? "warning" : "healthy",
22141
+ reasons: [...pressureReasons, ...diagnosticReasons],
22142
+ diagnostics: diagnosticReasons,
22143
+ admission
22144
+ };
22145
+ }
22146
+ //#endregion
22147
+ //#region ../../lib/system-health/sampler.ts
22148
+ const DEFAULT_WARMUP_INTERVAL_MS = 1e3;
22149
+ const DEFAULT_WARMUP_SAMPLES = 3;
22150
+ const REQUIRED_CONSECUTIVE_SAMPLES = 3;
22151
+ function createMeasuringState(metrics, observedAt) {
22152
+ return {
22153
+ accepted: {
22154
+ state: "measuring",
22155
+ reasons: [{
22156
+ code: "host.sampler.measuring",
22157
+ domain: "host",
22158
+ severity: "info",
22159
+ message: "System health is collecting the initial three samples."
22160
+ }],
22161
+ metrics,
22162
+ sampledAt: observedAt,
22163
+ freshness: {
22164
+ status: "measuring",
22165
+ observedAt
22166
+ },
22167
+ transitionVersion: 0
22168
+ },
22169
+ candidate: null,
22170
+ candidateCount: 0
22171
+ };
22172
+ }
22173
+ function accept(previous, assessment) {
22174
+ const changed = previous.state !== assessment.state;
22175
+ const transitionVersion = changed ? previous.transitionVersion + 1 : previous.transitionVersion;
22176
+ return {
22177
+ state: {
22178
+ accepted: {
22179
+ ...assessment,
22180
+ freshness: {
22181
+ status: "fresh",
22182
+ observedAt: assessment.sampledAt
22183
+ },
22184
+ transitionVersion
22185
+ },
22186
+ candidate: null,
22187
+ candidateCount: 0
22188
+ },
22189
+ transition: changed ? {
22190
+ version: transitionVersion,
22191
+ previousState: previous.state,
22192
+ state: assessment.state,
22193
+ reasonCodes: assessment.reasons.map((entry) => entry.code),
22194
+ acceptedAt: assessment.sampledAt
22195
+ } : null
22196
+ };
22197
+ }
22198
+ /**
22199
+ * Applies symmetric three-sample hysteresis to one atomic assessment. Metrics
22200
+ * and reasons move with their state only when that complete assessment is
22201
+ * accepted, so readers never observe a new state paired with old evidence.
22202
+ */
22203
+ function transitionAcceptedAssessment(previous, raw) {
22204
+ if (raw.status === "invalid") return {
22205
+ state: {
22206
+ accepted: {
22207
+ ...previous.accepted,
22208
+ freshness: {
22209
+ status: "stale",
22210
+ observedAt: raw.sampledAt,
22211
+ reason: raw.reason
22212
+ }
22213
+ },
22214
+ candidate: null,
22215
+ candidateCount: 0
22216
+ },
22217
+ transition: null
22218
+ };
22219
+ const assessment = raw.assessment;
22220
+ if (assessment.state === previous.accepted.state) return accept(previous.accepted, assessment);
22221
+ const candidateCount = previous.candidate?.state === assessment.state ? previous.candidateCount + 1 : 1;
22222
+ if (candidateCount >= REQUIRED_CONSECUTIVE_SAMPLES) return accept(previous.accepted, assessment);
22223
+ return {
22224
+ state: {
22225
+ accepted: previous.accepted,
22226
+ candidate: assessment,
22227
+ candidateCount
22228
+ },
22229
+ transition: null
22230
+ };
22231
+ }
22232
+ function resolveMeasuringMetrics(value) {
22233
+ return typeof value === "function" ? value() : value;
22234
+ }
22235
+ function createSystemHealthSampler(options) {
22236
+ const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
22237
+ const warmupIntervalMs = options.warmupIntervalMs ?? DEFAULT_WARMUP_INTERVAL_MS;
22238
+ const warmupSamples = options.warmupSamples ?? DEFAULT_WARMUP_SAMPLES;
22239
+ let state = createMeasuringState(resolveMeasuringMetrics(options.measuringMetrics), now());
22240
+ let timer = null;
22241
+ let started = false;
22242
+ let stopped = false;
22243
+ let samplesAttempted = 0;
22244
+ const schedule = () => {
22245
+ if (stopped) return;
22246
+ const delay = samplesAttempted < warmupSamples ? warmupIntervalMs : options.pollIntervalMs;
22247
+ timer = setTimeout(() => {
22248
+ collectOnce();
22249
+ }, delay);
22250
+ };
22251
+ const collectOnce = async () => {
22252
+ if (stopped) return;
22253
+ let raw;
22254
+ try {
22255
+ raw = await options.collect();
22256
+ } catch (error) {
22257
+ raw = {
22258
+ status: "invalid",
22259
+ sampledAt: now(),
22260
+ reason: {
22261
+ code: "host.sampler.collection_failed",
22262
+ domain: "host",
22263
+ severity: "info",
22264
+ message: error instanceof Error ? error.message : "System health collection failed."
22265
+ }
22266
+ };
22267
+ }
22268
+ samplesAttempted++;
22269
+ const result = transitionAcceptedAssessment(state, raw);
22270
+ state = result.state;
22271
+ if (result.transition && options.onTransition) try {
22272
+ await options.onTransition(result.transition);
22273
+ } catch (error) {
22274
+ console.error("[system-health] Failed to publish accepted transition:", error);
22275
+ }
22276
+ schedule();
22277
+ };
22278
+ const start = () => {
22279
+ if (started || stopped) return;
22280
+ started = true;
22281
+ collectOnce();
22282
+ };
22283
+ return {
22284
+ getSnapshot() {
22285
+ start();
22286
+ return state.accepted;
22287
+ },
22288
+ stop() {
22289
+ stopped = true;
22290
+ if (timer) clearTimeout(timer);
22291
+ timer = null;
22292
+ }
22293
+ };
22294
+ }
22295
+ //#endregion
22296
+ //#region services/system-health-v2.ts
21856
22297
  init_event_store();
22298
+ init_staleness();
22299
+ function runtimeHealthState(runtime) {
22300
+ if (!runtime) return null;
22301
+ switch (runtime.activity) {
22302
+ case "working":
22303
+ case "thinking": return {
22304
+ state: "active",
22305
+ lastActivity: runtime.lastActivity,
22306
+ contextSaturatedAt: runtime.contextSaturatedAt
22307
+ };
22308
+ case "waiting": return {
22309
+ state: "waiting-on-human",
22310
+ lastActivity: runtime.lastActivity,
22311
+ contextSaturatedAt: runtime.contextSaturatedAt
22312
+ };
22313
+ case "idle": return {
22314
+ state: "idle",
22315
+ lastActivity: runtime.lastActivity,
22316
+ contextSaturatedAt: runtime.contextSaturatedAt
22317
+ };
22318
+ case "stopped": return {
22319
+ state: "stopped",
22320
+ lastActivity: runtime.lastActivity,
22321
+ contextSaturatedAt: runtime.contextSaturatedAt
22322
+ };
22323
+ }
22324
+ }
22325
+ function agentLifecycle(role, issueId, tmuxActive, statuses) {
22326
+ if (role !== "review" && role !== "test" && role !== "ship") return "unknown";
22327
+ return classifyAdvancingSessionLifecycle(role, statuses.get(issueId.toUpperCase()), tmuxActive);
22328
+ }
22329
+ function stateToLegacySeverity(state) {
22330
+ return state === "critical" ? "critical" : state === "warning" ? "warning" : "normal";
22331
+ }
22332
+ function signalValue(signal) {
22333
+ return signal.status === "available" ? signal.value : null;
22334
+ }
22335
+ function hostMetrics(sample) {
22336
+ return {
22337
+ cpuPercent: signalValue(sample.cpuPercent),
22338
+ loadAverage1m: signalValue(sample.loadAverage1m),
22339
+ loadPerCore1m: signalValue(sample.loadPerCore1m),
22340
+ totalMemoryBytes: signalValue(sample.totalMemoryBytes),
22341
+ usedMemoryBytes: signalValue(sample.usedMemoryBytes),
22342
+ availableMemoryBytes: signalValue(sample.availableMemoryBytes),
22343
+ memoryUsedPercent: signalValue(sample.memoryUsedPercent),
22344
+ memoryPressureSomeAvg10: signalValue(sample.memoryPressureSomeAvg10),
22345
+ memoryPressureFullAvg10: signalValue(sample.memoryPressureFullAvg10),
22346
+ memoryPressureFreePercent: signalValue(sample.memoryPressureFreePercent),
22347
+ swapTotalBytes: signalValue(sample.swapTotalBytes),
22348
+ swapUsedBytes: signalValue(sample.swapUsedBytes),
22349
+ swapUsedPercent: signalValue(sample.swapUsedPercent),
22350
+ swapActivityBytesPerMinute: signalValue(sample.swapActivityBytesPerMinute),
22351
+ committedMemoryBytes: signalValue(sample.committedMemoryBytes),
22352
+ commitLimitBytes: signalValue(sample.commitLimitBytes),
22353
+ virtualCommitmentPercent: signalValue(sample.virtualCommitmentPercent)
22354
+ };
22355
+ }
22356
+ function serviceHealth(smeeRelay) {
22357
+ if (smeeRelay.status === "running") return [{
22358
+ id: "smee-relay",
22359
+ label: "Webhook relay",
22360
+ required: false,
22361
+ status: "running",
22362
+ message: smeeRelay.message,
22363
+ reasons: []
22364
+ }];
22365
+ if (smeeRelay.status === "not_configured") return [{
22366
+ id: "smee-relay",
22367
+ label: "Webhook relay",
22368
+ required: false,
22369
+ status: "not_configured",
22370
+ message: smeeRelay.message,
22371
+ reasons: []
22372
+ }];
22373
+ const unavailable = smeeRelay.status === "unknown";
22374
+ return [{
22375
+ id: "smee-relay",
22376
+ label: "Webhook relay",
22377
+ required: false,
22378
+ status: unavailable ? "unavailable" : "stopped",
22379
+ message: smeeRelay.message,
22380
+ reasons: [{
22381
+ code: unavailable ? "service.smee_relay.unavailable" : "service.smee_relay.stopped",
22382
+ domain: "service",
22383
+ severity: unavailable ? "info" : "warning",
22384
+ message: smeeRelay.message
22385
+ }]
22386
+ }];
22387
+ }
22388
+ function overallHealthState(hostState, agents, services) {
22389
+ if (hostState === "critical" || agents.some((agent) => agent.status === "dead" || agent.status === "wedged")) return "critical";
22390
+ if (hostState === "warning" || agents.some((agent) => agent.status === "warning" || agent.status === "stalled") || services.some((service) => service.status === "degraded" || service.status === "stopped")) return "warning";
22391
+ if (hostState === "measuring") return "measuring";
22392
+ if (hostState === "unavailable" || agents.some((agent) => agent.status === "unavailable") || services.some((service) => service.status === "unavailable")) return "unavailable";
22393
+ return "healthy";
22394
+ }
22395
+ function acceptedReasons(state, hostReasons, agents, services) {
22396
+ const reasons = [
22397
+ ...hostReasons,
22398
+ ...agents.flatMap((agent) => agent.reasons),
22399
+ ...services.flatMap((service) => service.reasons)
22400
+ ];
22401
+ if (state === "measuring" && reasons.length === 0) return [{
22402
+ code: "host.sampler.measuring",
22403
+ domain: "host",
22404
+ severity: "info",
22405
+ message: "System health is collecting the initial three samples."
22406
+ }];
22407
+ return reasons;
22408
+ }
22409
+ //#endregion
22410
+ //#region services/system-health-service.ts
22411
+ init_review_status_source();
21857
22412
  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
22413
  const KB = 1024;
21866
22414
  const GIB$1 = 1024 ** 3;
21867
- const GLOBAL_CONFIG_PATH = join(homedir$1(), ".overdeck", "config.yaml");
21868
22415
  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;
22416
+ const hostHealthCollector = createHostHealthCollector();
22417
+ let previousHostMetricSample;
22418
+ let systemHealthSampler = null;
21878
22419
  let eventStorePromise = null;
21879
- let cachedResourceConfig = DEFAULT_RESOURCE_CONFIG;
21880
- let cachedPollSeconds = DEFAULT_HEALTH_POLL_SECONDS;
22420
+ let cachedSystemHealthConfig = null;
21881
22421
  let resourceConfigLoadedAt = 0;
21882
22422
  let resourceConfigInflight = null;
21883
22423
  let cachedDeployStaleness = null;
@@ -21911,9 +22451,17 @@ function getDockerStatsCollector() {
21911
22451
  function bytesToGb(bytes) {
21912
22452
  return Math.round(bytes / GIB$1 * 100) / 100;
21913
22453
  }
21914
- function toPercent(part, total) {
21915
- if (total <= 0) return 0;
21916
- return Math.round(part / total * 1e3) / 10;
22454
+ const AGENT_STARTUP_GRACE_MS = 300 * 1e3;
22455
+ function countAdmittedWorkAgents(agents, nowMs = Date.now()) {
22456
+ return agents.filter((agent) => {
22457
+ if (agent.role !== "work") return false;
22458
+ if (agent.status !== "running" && agent.status !== "starting") return false;
22459
+ if (agent.tmuxActive) return true;
22460
+ if (agent.status !== "starting" || !agent.startedAt) return false;
22461
+ const startedAtMs = Date.parse(agent.startedAt);
22462
+ const ageMs = nowMs - startedAtMs;
22463
+ return Number.isFinite(startedAtMs) && ageMs >= 0 && ageMs < AGENT_STARTUP_GRACE_MS;
22464
+ }).length;
21917
22465
  }
21918
22466
  function classifyAgentKind(agentId, role) {
21919
22467
  if (agentId.startsWith("planning-")) return "planning";
@@ -21925,41 +22473,13 @@ function classifyAgentKind(agentId, role) {
21925
22473
  if (agentId.endsWith("-agent")) return "specialist";
21926
22474
  return "other";
21927
22475
  }
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
22476
  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
- };
22477
+ cachedSystemHealthConfig = resolveSystemHealthConfig();
21959
22478
  resourceConfigLoadedAt = Date.now();
21960
22479
  }
21961
22480
  async function ensureResourceConfigLoaded() {
21962
- const ttl = Math.max(5e3, cachedPollSeconds * 1e3);
22481
+ const pollSeconds = cachedSystemHealthConfig?.pollSeconds ?? SYSTEM_HEALTH_DEFAULTS.pollSeconds;
22482
+ const ttl = Math.max(5e3, pollSeconds * 1e3);
21963
22483
  if (resourceConfigLoadedAt > 0 && Date.now() - resourceConfigLoadedAt < ttl) return;
21964
22484
  if (!resourceConfigInflight) resourceConfigInflight = readGlobalResourceConfig().finally(() => {
21965
22485
  resourceConfigInflight = null;
@@ -21967,23 +22487,8 @@ async function ensureResourceConfigLoaded() {
21967
22487
  await resourceConfigInflight;
21968
22488
  }
21969
22489
  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
- };
22490
+ cachedSystemHealthConfig ??= resolveSystemHealthConfig();
22491
+ return cachedSystemHealthConfig.resources;
21987
22492
  }
21988
22493
  async function readProcMemoryLinux() {
21989
22494
  const content = await readFile("/proc/meminfo", "utf-8");
@@ -22049,119 +22554,13 @@ async function readProcMemoryDarwin() {
22049
22554
  async function readProcMemory() {
22050
22555
  return platform$1() === "darwin" ? readProcMemoryDarwin() : readProcMemoryLinux();
22051
22556
  }
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
- async function readProcessTable() {
22090
- const { stdout } = await execAsync$4("ps -eo pid=,ppid=,rss=,args=", {
22091
- encoding: "utf-8",
22092
- timeout: 1e4
22093
- });
22094
- const rows = /* @__PURE__ */ new Map();
22095
- for (const line of stdout.split("\n")) {
22096
- const trimmed = line.trim();
22097
- if (!trimmed) continue;
22098
- const match = trimmed.match(/^(\d+)\s+(\d+)\s+(\d+)\s+(.+)$/);
22099
- if (!match) continue;
22100
- const pid = Number(match[1]);
22101
- const ppid = Number(match[2]);
22102
- const rssKb = Number(match[3]);
22103
- const command = match[4] ?? "";
22104
- if (!Number.isFinite(pid) || !Number.isFinite(ppid) || !Number.isFinite(rssKb)) continue;
22105
- rows.set(pid, {
22106
- pid,
22107
- ppid,
22108
- rssKb,
22109
- command
22110
- });
22111
- }
22112
- return rows;
22113
- }
22114
- function getDescendantPids(rootPid, processes) {
22115
- const descendants = /* @__PURE__ */ new Set();
22116
- const queue = [rootPid];
22117
- while (queue.length > 0) {
22118
- const pid = queue.shift();
22119
- if (!pid || descendants.has(pid)) continue;
22120
- descendants.add(pid);
22121
- for (const process of processes.values()) if (process.ppid === pid && !descendants.has(process.pid)) queue.push(process.pid);
22122
- }
22123
- return descendants;
22124
- }
22125
- function sumProcessMemory(descendants, processes) {
22126
- let totalRssKb = 0;
22127
- for (const pid of descendants) totalRssKb += processes.get(pid)?.rssKb ?? 0;
22128
- return totalRssKb * KB;
22129
- }
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.`
22557
+ function buildLeakedSpecialists(agents) {
22558
+ return agents.filter((agent) => agent.kind === "specialist" && agent.lifecycle === "orphaned").map((agent) => ({
22559
+ name: agent.id,
22560
+ currentIssue: agent.currentIssue ?? agent.issueId,
22561
+ reason: `Advancing session remains live after ${agent.issueId} merged.`
22137
22562
  }));
22138
22563
  }
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
22564
  function collectSmeeRelayHealth() {
22166
22565
  try {
22167
22566
  if (!isSmeeConfiguredSync()) return {
@@ -22190,32 +22589,74 @@ function collectSmeeRelayHealth() {
22190
22589
  };
22191
22590
  }
22192
22591
  }
22592
+ function reviewStatusMap() {
22593
+ return new Map(Object.entries(readReviewStatusMap() ?? {}));
22594
+ }
22193
22595
  async function collectAgentProcesses() {
22194
- const activeAgents = (await Effect.runPromise(listRunningAgents())).filter((agent) => agent.status !== "stopped");
22195
- 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);
22198
- const panePidValue = (await Effect.runPromise(listPaneValues(agent.id, "#{pane_pid}")))[0];
22199
- const panePid = Number(panePidValue ?? "0");
22200
- const descendants = Number.isFinite(panePid) && panePid > 0 ? getDescendantPids(panePid, processTable) : /* @__PURE__ */ new Set();
22201
- const memoryBytes = descendants.size > 0 ? sumProcessMemory(descendants, processTable) : 0;
22596
+ const registeredAgents = await Effect.runPromise(listRunningAgents());
22597
+ const nowMs = Date.now();
22598
+ const admittedWorkAgentCount = countAdmittedWorkAgents(registeredAgents, nowMs);
22599
+ const activeAgents = registeredAgents.filter((agent) => agent.status !== "stopped");
22600
+ const liveSessions = new Set(registeredAgents.filter((agent) => agent.tmuxActive).map((agent) => agent.id));
22601
+ const runtimeCensus = await getRuntimeCensus();
22602
+ const reviewStatuses = reviewStatusMap();
22603
+ const collected = await Promise.all(activeAgents.map(async (agent) => {
22604
+ const [runtimeState, runtimeSnapshot] = await Promise.all([Effect.runPromise(getAgentRuntimeState(agent.id)).catch(() => null), Effect.runPromise(getRuntimeSnapshot(agent.id)).catch(() => null)]);
22605
+ const memoryBytes = [...descendantPidsForSession(runtimeCensus, agent.id)].reduce((sum, pid) => sum + (runtimeCensus.processesByPid.get(pid)?.rssBytes ?? 0), 0);
22606
+ const lifecycle = agentLifecycle(agent.role, agent.issueId, agent.tmuxActive, reviewStatuses);
22202
22607
  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
22608
+ process: {
22609
+ id: agent.id,
22610
+ issueId: agent.issueId,
22611
+ role: agent.role,
22612
+ kind: classifyAgentKind(agent.id, agent.role),
22613
+ status: agent.status,
22614
+ lifecycle,
22615
+ tmuxActive: agent.tmuxActive,
22616
+ memoryBytes,
22617
+ memoryGb: bytesToGb(memoryBytes),
22618
+ currentIssue: runtimeState?.currentIssue
22619
+ },
22620
+ health: {
22621
+ ...classifyAgentHealth({
22622
+ agentId: agent.id,
22623
+ persisted: {
22624
+ status: "available",
22625
+ value: {
22626
+ id: agent.id,
22627
+ issueId: agent.issueId,
22628
+ role: agent.role,
22629
+ status: agent.status,
22630
+ startedAt: agent.startedAt,
22631
+ lastActivity: agent.lastActivity,
22632
+ kickoffDelivered: agent.kickoffDelivered,
22633
+ paused: agent.paused,
22634
+ stoppedByUser: agent.stoppedByUser,
22635
+ stoppedByPause: agent.stoppedByPause,
22636
+ consecutiveFailures: agent.consecutiveFailures
22637
+ }
22638
+ },
22639
+ runtime: runtimeHealthState(runtimeSnapshot),
22640
+ liveSessions,
22641
+ reviewLifecycle: lifecycle,
22642
+ nowMs
22643
+ }),
22644
+ memoryBytes,
22645
+ memoryGb: bytesToGb(memoryBytes),
22646
+ ...runtimeState?.currentIssue ? { currentIssue: runtimeState.currentIssue } : {}
22647
+ }
22211
22648
  };
22212
22649
  }));
22650
+ return {
22651
+ agents: collected.map((entry) => entry.process),
22652
+ healthAgents: collected.map((entry) => entry.health),
22653
+ admittedWorkAgentCount
22654
+ };
22213
22655
  }
22214
- function buildTopConsumers(agents, containers, leakedSpecialists) {
22215
- const leakedByName = new Map(leakedSpecialists.map((item) => [item.name, item]));
22656
+ function buildTopConsumers(agents, containers) {
22216
22657
  const agentConsumers = agents.map((agent) => {
22217
22658
  const isSpecialist = agent.kind === "specialist";
22218
- const leaked = leakedByName.has(agent.id.replace(/^specialist-/, "")) || leakedByName.has(agent.id);
22659
+ const leaked = agent.lifecycle === "orphaned";
22219
22660
  const currentIssue = agent.currentIssue ?? agent.issueId;
22220
22661
  const resolved = currentIssue ? resolveProjectFromIssueSync(currentIssue) : null;
22221
22662
  const specialistType = isSpecialist ? agent.id.startsWith("specialist-") ? agent.id.replace(/^specialist-/, "") : agent.id : void 0;
@@ -22251,122 +22692,215 @@ function buildTopConsumers(agents, containers, leakedSpecialists) {
22251
22692
  containerId: container.id
22252
22693
  }
22253
22694
  }));
22254
- return [...agentConsumers, ...containerConsumers].sort((a, b) => b.memoryBytes - a.memoryBytes).slice(0, 10);
22695
+ return [...agentConsumers, ...containerConsumers].sort((a, b) => b.memoryBytes - a.memoryBytes);
22696
+ }
22697
+ function createMeasuringSnapshot() {
22698
+ cachedSystemHealthConfig ??= resolveSystemHealthConfig();
22699
+ const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
22700
+ const smeeRelay = collectSmeeRelayHealth();
22701
+ const services = serviceHealth(smeeRelay);
22702
+ const base = {
22703
+ version: 2,
22704
+ state: "measuring",
22705
+ updatedAt,
22706
+ nextPollMs: cachedSystemHealthConfig.pollSeconds * 1e3,
22707
+ host: {
22708
+ state: "measuring",
22709
+ platform: hostHealthCollector.platform,
22710
+ reasons: [{
22711
+ code: "host.sampler.measuring",
22712
+ domain: "host",
22713
+ severity: "info",
22714
+ message: "System health is collecting the initial three samples."
22715
+ }],
22716
+ metrics: {
22717
+ cpuPercent: null,
22718
+ loadAverage1m: null,
22719
+ loadPerCore1m: null,
22720
+ totalMemoryBytes: null,
22721
+ usedMemoryBytes: null,
22722
+ availableMemoryBytes: null,
22723
+ memoryUsedPercent: null,
22724
+ memoryPressureSomeAvg10: null,
22725
+ memoryPressureFullAvg10: null,
22726
+ memoryPressureFreePercent: null,
22727
+ swapTotalBytes: null,
22728
+ swapUsedBytes: null,
22729
+ swapUsedPercent: null,
22730
+ swapActivityBytesPerMinute: null,
22731
+ committedMemoryBytes: null,
22732
+ commitLimitBytes: null,
22733
+ virtualCommitmentPercent: null
22734
+ }
22735
+ },
22736
+ admission: {
22737
+ state: "unavailable",
22738
+ availableMemoryBytes: null,
22739
+ admittedWorkAgentCount: 0,
22740
+ reasons: [{
22741
+ code: "admission.sampler.measuring",
22742
+ domain: "admission",
22743
+ severity: "info",
22744
+ message: "Admission capacity is unavailable until the initial health sample is accepted."
22745
+ }]
22746
+ },
22747
+ agents: [],
22748
+ services,
22749
+ topConsumers: []
22750
+ };
22751
+ const accepted = {
22752
+ ...base,
22753
+ summary: projectLegacySystemHealthSummary(base)
22754
+ };
22755
+ return {
22756
+ accepted,
22757
+ compatibility: {
22758
+ severity: "normal",
22759
+ updatedAt,
22760
+ admission: { admittedWorkAgentCount: 0 },
22761
+ summary: accepted.summary,
22762
+ thresholds: cachedSystemHealthConfig.thresholds,
22763
+ reasons: accepted.host.reasons.map((reason) => reason.message),
22764
+ agents: [],
22765
+ leakedSpecialists: [],
22766
+ topConsumers: [],
22767
+ smeeRelay,
22768
+ deployStaleness: null
22769
+ }
22770
+ };
22255
22771
  }
22256
- async function refreshSystemHealth(snapshot) {
22772
+ async function collectSystemHealth() {
22257
22773
  await ensureResourceConfigLoaded();
22258
- const [memory, loadAverage1m, cpuPercent, agents, containers] = await Promise.all([
22259
- readProcMemory(),
22260
- readLoadAverage(),
22261
- readCpuPercent(),
22774
+ const [sample, agentProcesses, containers, deployStaleness] = await Promise.all([
22775
+ hostHealthCollector.sample(previousHostMetricSample),
22262
22776
  collectAgentProcesses(),
22263
- Promise.resolve(getDockerStatsCollector().getStats())
22777
+ Promise.resolve(getDockerStatsCollector().getStats()),
22778
+ getDeployStaleness()
22264
22779
  ]);
22265
- const thresholds = defaultThresholds();
22780
+ previousHostMetricSample = sample;
22781
+ const config = cachedSystemHealthConfig;
22782
+ const host = evaluateHostPressure(sample, config.thresholds);
22266
22783
  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
22784
+ const services = serviceHealth(smeeRelay);
22785
+ const consumers = buildTopConsumers(agentProcesses.agents, containers);
22786
+ const state = overallHealthState(host.state, agentProcesses.healthAgents, services);
22787
+ const reasons = acceptedReasons(state, host.reasons, agentProcesses.healthAgents, services);
22788
+ const updatedAt = new Date(sample.sampledAtMs).toISOString();
22789
+ const base = {
22790
+ version: 2,
22791
+ state,
22792
+ updatedAt,
22793
+ nextPollMs: config.pollSeconds * 1e3,
22794
+ host: {
22795
+ state: host.state,
22796
+ platform: sample.platform,
22797
+ reasons: host.reasons,
22798
+ metrics: hostMetrics(sample)
22799
+ },
22800
+ admission: {
22801
+ ...host.admission,
22802
+ admittedWorkAgentCount: agentProcesses.admittedWorkAgentCount
22332
22803
  },
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 {
22804
+ agents: agentProcesses.healthAgents,
22805
+ services,
22806
+ topConsumers: consumers
22807
+ };
22808
+ const accepted = {
22809
+ ...base,
22810
+ summary: projectLegacySystemHealthSummary(base)
22811
+ };
22812
+ const sortedAgents = [...agentProcesses.agents].sort((left, right) => right.memoryBytes - left.memoryBytes);
22813
+ const leakedSpecialists = buildLeakedSpecialists(sortedAgents);
22814
+ return {
22815
+ accepted,
22816
+ compatibility: {
22817
+ severity: stateToLegacySeverity(state),
22818
+ updatedAt,
22819
+ admission: { admittedWorkAgentCount: agentProcesses.admittedWorkAgentCount },
22820
+ summary: accepted.summary,
22821
+ thresholds: config.thresholds,
22822
+ reasons: reasons.map((reason) => reason.message),
22823
+ agents: sortedAgents,
22824
+ leakedSpecialists,
22825
+ topConsumers: consumers.slice(0, 10),
22826
+ smeeRelay,
22827
+ deployStaleness
22828
+ }
22829
+ };
22830
+ }
22831
+ async function collectRawSystemHealth() {
22832
+ const bundle = await collectSystemHealth();
22833
+ const reasons = acceptedReasons(bundle.accepted.state, bundle.accepted.host.reasons, bundle.accepted.agents, bundle.accepted.services);
22834
+ return {
22835
+ status: "valid",
22836
+ assessment: {
22837
+ state: bundle.accepted.state,
22838
+ reasons,
22839
+ metrics: bundle,
22840
+ sampledAt: bundle.accepted.updatedAt
22841
+ }
22842
+ };
22843
+ }
22844
+ function buildSystemHealthTransitionPayload(transition, leakedSpecialistCount) {
22845
+ return {
22846
+ version: 2,
22847
+ transitionVersion: transition.version,
22848
+ previousSeverity: stateToLegacySeverity(transition.previousState),
22849
+ severity: stateToLegacySeverity(transition.state),
22850
+ previousState: transition.previousState,
22851
+ state: transition.state,
22852
+ reasons: transition.reasonCodes,
22853
+ reasonCodes: transition.reasonCodes,
22854
+ acceptedAt: transition.acceptedAt,
22855
+ leakedSpecialistCount
22856
+ };
22857
+ }
22858
+ async function publishSystemHealthTransition(transition) {
22859
+ const accepted = systemHealthSampler?.getSnapshot();
22860
+ try {
22342
22861
  await (await (eventStorePromise ??= initEventStore())).appendAsync({
22343
22862
  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
- }
22863
+ timestamp: transition.acceptedAt,
22864
+ payload: buildSystemHealthTransitionPayload(transition, accepted?.metrics.accepted.summary.leakedSpecialistCount ?? 0)
22351
22865
  });
22352
22866
  } catch (err) {
22353
- console.error("[system-health] Failed to append severity transition event:", err);
22867
+ console.error("[system-health] Failed to append accepted transition event:", err);
22354
22868
  }
22355
- previousSeverity = result.severity;
22356
- cachedHealth = result;
22357
- cacheExpiresAt = Date.now() + getHealthPollTtlMs();
22358
- return result;
22359
22869
  }
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;
22870
+ function getSystemHealthSampler() {
22871
+ if (!systemHealthSampler) {
22872
+ const config = cachedSystemHealthConfig ?? resolveSystemHealthConfig();
22873
+ cachedSystemHealthConfig = config;
22874
+ systemHealthSampler = createSystemHealthSampler({
22875
+ collect: collectRawSystemHealth,
22876
+ measuringMetrics: createMeasuringSnapshot,
22877
+ pollIntervalMs: config.pollSeconds * 1e3,
22878
+ onTransition: publishSystemHealthTransition
22879
+ });
22880
+ }
22881
+ return systemHealthSampler;
22882
+ }
22883
+ async function getSystemHealthEvidenceSnapshot() {
22884
+ const assessment = getSystemHealthSampler().getSnapshot();
22885
+ return {
22886
+ accepted: assessment.metrics.accepted,
22887
+ compatibility: {
22888
+ ...assessment.metrics.compatibility,
22889
+ state: assessment.state,
22890
+ structuredReasons: assessment.reasons,
22891
+ freshness: assessment.freshness,
22892
+ transitionVersion: assessment.transitionVersion
22893
+ }
22894
+ };
22895
+ }
22896
+ async function getAcceptedSystemHealthSnapshot() {
22897
+ return (await getSystemHealthEvidenceSnapshot()).accepted;
22898
+ }
22899
+ async function getSystemHealthSnapshot() {
22900
+ return (await getSystemHealthEvidenceSnapshot()).compatibility;
22366
22901
  }
22367
22902
  //#endregion
22368
22903
  //#region routes/resources/shared.ts
22369
- init_load();
22370
22904
  init_docker_stats();
22371
22905
  function getCurrentDockerStats() {
22372
22906
  return [];
@@ -22467,6 +23001,7 @@ function roundOne(value) {
22467
23001
  }
22468
23002
  //#endregion
22469
23003
  //#region ../../lib/cloister/memory-governor.ts
23004
+ init_load();
22470
23005
  init_projects();
22471
23006
  promisify(execFile);
22472
23007
  const GIB = 1024 ** 3;
@@ -22535,9 +23070,18 @@ async function assessMemoryPressure() {
22535
23070
  return verdict;
22536
23071
  }
22537
23072
  //#endregion
23073
+ //#region ../../lib/cloister/agent-grace.ts
23074
+ init_tracker_utils();
23075
+ init_concurrency$1();
23076
+ const WORK_LAUNCHER_GRACE_MS = 12e4;
23077
+ function isStartingWithinGrace(state, now = Date.now(), graceMs = WORK_LAUNCHER_GRACE_MS) {
23078
+ if (state.status !== "starting") return false;
23079
+ const startedMs = Date.parse(state.startedAt ?? "");
23080
+ return Number.isFinite(startedMs) && now - startedMs < graceMs;
23081
+ }
23082
+ //#endregion
22538
23083
  //#region ../../lib/cloister/deacon-inspect.ts
22539
23084
  init_review_status();
22540
- init_tmux();
22541
23085
  /**
22542
23086
  * Inspect prompts state a 10-minute budget. Deacon gives the agent a small
22543
23087
  * grace window beyond that, then fails loud so the parent work agent never waits
@@ -22578,7 +23122,7 @@ async function checkInspectAgentTimeouts(now = /* @__PURE__ */ new Date()) {
22578
23122
  console.warn(`[deacon] Failed to kill inspect session ${sessionName}: ${msg}`);
22579
23123
  });
22580
23124
  try {
22581
- const { messageAgent } = await import("./agents-Czz6R57Z.js");
23125
+ const { messageAgent } = await import("./agents-FlIgQ3ql.js");
22582
23126
  await messageAgent(`agent-${issueId.toLowerCase()}`, verdict, "deacon:inspect-watchdog");
22583
23127
  } catch (err) {
22584
23128
  const msg = err instanceof Error ? err.message : String(err);
@@ -22631,8 +23175,50 @@ async function handleKnownAgentModal(agentId, deps = defaultDeps$1, initialPane)
22631
23175
  await deps.settle();
22632
23176
  return modal.matches(await deps.capturePane(agentId)) ? "needs-you" : "handled";
22633
23177
  }
23178
+ const ORCHESTRATED_COMPACTION_CONTINUE_MESSAGE = "Compaction complete. Continue from the compacted summary now. Re-read your current xBRIEF item and latest feedback file if needed, then resume work; do not wait for further input.";
23179
+ const orchestratedCompactionContinuations = /* @__PURE__ */ new Map();
23180
+ function scheduleOrchestratedCompactionContinuation(sessionName, requestedAt = Date.now()) {
23181
+ orchestratedCompactionContinuations.set(sessionName, {
23182
+ requestedAt,
23183
+ observedBusy: false
23184
+ });
23185
+ }
23186
+ function cancelOrchestratedCompactionContinuation(sessionName) {
23187
+ orchestratedCompactionContinuations.delete(sessionName);
23188
+ }
23189
+ function hasOrchestratedCompactionContinuation(sessionName) {
23190
+ return orchestratedCompactionContinuations.has(sessionName);
23191
+ }
23192
+ async function deliverOrchestratedCompact(sessionName, deliver) {
23193
+ scheduleOrchestratedCompactionContinuation(sessionName);
23194
+ try {
23195
+ await deliver();
23196
+ } catch (error) {
23197
+ cancelOrchestratedCompactionContinuation(sessionName);
23198
+ throw error;
23199
+ }
23200
+ }
23201
+ async function maybeContinueOrchestratedCompaction(args) {
23202
+ const pending = orchestratedCompactionContinuations.get(args.sessionName);
23203
+ if (!pending) return false;
23204
+ const elapsed = (args.now ?? Date.now()) - pending.requestedAt;
23205
+ if (!args.tmuxOutput.includes("❯")) {
23206
+ pending.observedBusy = true;
23207
+ if (elapsed >= 15e4) orchestratedCompactionContinuations.delete(args.sessionName);
23208
+ return false;
23209
+ }
23210
+ if (isContextOverflowTail(args.tmuxOutput)) {
23211
+ if (elapsed >= 15e4) orchestratedCompactionContinuations.delete(args.sessionName);
23212
+ return false;
23213
+ }
23214
+ if (!pending.observedBusy && elapsed < 3e4) return false;
23215
+ await args.send(args.sessionName, ORCHESTRATED_COMPACTION_CONTINUE_MESSAGE);
23216
+ orchestratedCompactionContinuations.delete(args.sessionName);
23217
+ return true;
23218
+ }
22634
23219
  //#endregion
22635
23220
  //#region ../../lib/cloister/deacon-api-recovery.ts
23221
+ init_context_overflow();
22636
23222
  init_agents$1();
22637
23223
  init_review_status();
22638
23224
  init_tmux();
@@ -22730,13 +23316,13 @@ async function maybeProactivelyCompactContext(sessionName, now) {
22730
23316
  if (!agentState?.workspace || !sessionId || !agentState.model) return null;
22731
23317
  let usage = null;
22732
23318
  try {
22733
- const { computeContextUsage } = await import("./conversation-service-CWk8mEym.js");
23319
+ const { computeContextUsage } = await import("./conversation-service-Up7FEzIC.js");
22734
23320
  usage = await computeContextUsage(sessionFilePath(agentState.workspace, sessionId), agentState.model);
22735
23321
  } catch {
22736
23322
  return null;
22737
23323
  }
22738
23324
  if (!usage || usage.percentUsed < 85) return null;
22739
- await Effect.runPromise(sendKeys(sessionName, "/compact"));
23325
+ await deliverOrchestratedCompact(sessionName, () => Effect.runPromise(sendKeys(sessionName, "/compact")));
22740
23326
  contextProactiveCompactState.set(sessionName, { lastAttempt: now });
22741
23327
  try {
22742
23328
  await writeFile$1(join$1(getAgentDir(sessionName), PROACTIVE_COMPACT_STAMP_FILE), new Date(now).toISOString(), "utf-8");
@@ -22766,10 +23352,11 @@ async function checkApiErrorAgents() {
22766
23352
  } catch {
22767
23353
  return actions;
22768
23354
  }
22769
- const nonReviewerSessions = sessionNames.filter((name) => name.startsWith("agent-") || name.startsWith("specialist-") || name.startsWith("planning-")).filter((name) => !/^agent-.*-review-(?:security|correctness|performance|requirements)$/.test(name));
22770
- for (const sessionName of nonReviewerSessions) {
23355
+ const sessionsToInspect = sessionNames.filter((name) => name.startsWith("agent-") || name.startsWith("specialist-") || name.startsWith("planning-")).filter((name) => !/^agent-.*-review-(?:security|correctness|performance|requirements)$/.test(name) || hasOrchestratedCompactionContinuation(name));
23356
+ for (const sessionName of sessionsToInspect) {
23357
+ const compactionPendingAtStart = hasOrchestratedCompactionContinuation(sessionName);
22771
23358
  const recovery = apiErrorRecoveryState.get(sessionName);
22772
- if (recovery && now - recovery.lastAttempt < API_ERROR_RECOVERY_COOLDOWN_MS) continue;
23359
+ if (!compactionPendingAtStart && recovery && now - recovery.lastAttempt < API_ERROR_RECOVERY_COOLDOWN_MS) continue;
22773
23360
  let tmuxOutput;
22774
23361
  try {
22775
23362
  tmuxOutput = await Effect.runPromise(capturePane(sessionName, 100));
@@ -22809,6 +23396,23 @@ async function checkApiErrorAgents() {
22809
23396
  continue;
22810
23397
  }
22811
23398
  }
23399
+ if (compactionPendingAtStart || hasOrchestratedCompactionContinuation(sessionName)) {
23400
+ try {
23401
+ if (await maybeContinueOrchestratedCompaction({
23402
+ sessionName,
23403
+ tmuxOutput,
23404
+ now,
23405
+ send: (target, message) => Effect.runPromise(sendKeys(target, message))
23406
+ })) {
23407
+ contextOverflowRecoveryState.delete(sessionName);
23408
+ actions.push(`Context compaction recovery: resumed ${sessionName} after compaction`);
23409
+ continue;
23410
+ }
23411
+ } catch (err) {
23412
+ console.error(`[deacon] Failed to resume ${sessionName} after orchestrated compaction:`, err);
23413
+ }
23414
+ if (hasOrchestratedCompactionContinuation(sessionName)) continue;
23415
+ }
22812
23416
  if (!tmuxOutput.includes("❯")) continue;
22813
23417
  {
22814
23418
  const issueId = sessionName.startsWith("agent-") ? sessionName.replace("agent-", "").toUpperCase() : null;
@@ -22840,13 +23444,13 @@ async function checkApiErrorAgents() {
22840
23444
  const st = getAgentStateSync(sessionName);
22841
23445
  const sid = st?.sessionId ?? runtimeState?.claudeSessionId;
22842
23446
  if (st?.workspace && sid && st.model) {
22843
- const { computeContextUsage } = await import("./conversation-service-CWk8mEym.js");
23447
+ const { computeContextUsage } = await import("./conversation-service-Up7FEzIC.js");
22844
23448
  const usage = await computeContextUsage(sessionFilePath(st.workspace, sid), st.model);
22845
23449
  if (usage && usage.percentUsed < 85) recoveredPct = usage.percentUsed;
22846
23450
  }
22847
23451
  } catch {}
22848
23452
  if (recoveredPct !== null) {
22849
- const { clearWorkspaceStuck } = await import("./review-status-sync-C792ksoJ.js");
23453
+ const { clearWorkspaceStuck } = await import("./review-status-sync-To3-iS-N.js");
22850
23454
  clearWorkspaceStuck(issueId);
22851
23455
  stuckOverflowNativeRecoveryState.delete(sessionName);
22852
23456
  actions.push(`Context overflow recovery: cleared stuck flag for ${sessionName} (context back to ${Math.round(recoveredPct)}%)`);
@@ -22862,7 +23466,7 @@ async function checkApiErrorAgents() {
22862
23466
  rec.attempts += 1;
22863
23467
  rec.lastAttempt = now;
22864
23468
  stuckOverflowNativeRecoveryState.set(sessionName, rec);
22865
- const { resumeAgent } = await import("./agents-Czz6R57Z.js");
23469
+ const { resumeAgent } = await import("./agents-FlIgQ3ql.js");
22866
23470
  const recovered = await resumeAgent(sessionName, void 0, { compact: true });
22867
23471
  if (recovered.success) {
22868
23472
  stuckOverflowNativeRecoveryState.delete(sessionName);
@@ -22910,7 +23514,7 @@ async function checkApiErrorAgents() {
22910
23514
  }
22911
23515
  const compactAttempts = (ov?.compactAttempts ?? 0) + 1;
22912
23516
  if (issueId !== null) {
22913
- const { resumeAgent } = await import("./agents-Czz6R57Z.js");
23517
+ const { resumeAgent } = await import("./agents-FlIgQ3ql.js");
22914
23518
  const resumeResult = await resumeAgent(sessionName, void 0, { compact: true });
22915
23519
  contextOverflowRecoveryState.set(sessionName, {
22916
23520
  lastAttempt: now,
@@ -22939,7 +23543,7 @@ async function checkApiErrorAgents() {
22939
23543
  continue;
22940
23544
  }
22941
23545
  try {
22942
- await Effect.runPromise(sendKeys(sessionName, "/compact"));
23546
+ await deliverOrchestratedCompact(sessionName, () => Effect.runPromise(sendKeys(sessionName, "/compact")));
22943
23547
  contextOverflowRecoveryState.set(sessionName, {
22944
23548
  lastAttempt: now,
22945
23549
  compactAttempts,
@@ -23433,7 +24037,7 @@ function reviewConvoyLiveness(issueId) {
23433
24037
  */
23434
24038
  async function recoverUnhealthyTestStack(issueId, workspacePath) {
23435
24039
  const key = issueId.toUpperCase();
23436
- const { getWorkspaceStackHealth } = await import("./stack-health-I713ELld.js");
24040
+ const { getWorkspaceStackHealth } = await import("./stack-health-Df0YEZKa.js");
23437
24041
  const health = await Effect.runPromise(getWorkspaceStackHealth(issueId, { workspacePath }));
23438
24042
  if (health.healthy) {
23439
24043
  testStackRebuildState.delete(key);
@@ -23465,7 +24069,7 @@ async function recoverUnhealthyTestStack(issueId, workspacePath) {
23465
24069
  record.attempts += 1;
23466
24070
  testStackRebuildState.set(key, record);
23467
24071
  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");
24072
+ const { rebuildWorkspaceStack } = await import("./rebuild-stack-kA7XngID.js");
23469
24073
  const result = await Effect.runPromise(rebuildWorkspaceStack(issueId, { onProgress: (m) => console.log(`[deacon] ${key} stack rebuild: ${m}`) }));
23470
24074
  if (!result.success) {
23471
24075
  console.warn(`[deacon] Test stack rebuild failed for ${key}: ${result.error}`);
@@ -23633,7 +24237,7 @@ async function handleReviewCoordinatorDied(issueId, _sessionName, _reason) {
23633
24237
  return actions;
23634
24238
  }
23635
24239
  try {
23636
- const { spawnReviewRoleForIssue } = await import("./review-agent-CSswH985.js");
24240
+ const { spawnReviewRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
23637
24241
  const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
23638
24242
  issueId,
23639
24243
  workspace,
@@ -23785,7 +24389,7 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
23785
24389
  const workspace = agentState?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
23786
24390
  if (workspace && resolved && !tryReserveAdvancingSlot() && !await tryYieldForAdvancingDispatch("review", issueId)) actions.push(`Deferred review re-dispatch for ${issueId} — advancing-role concurrency ceiling reached`);
23787
24391
  else if (workspace && resolved) try {
23788
- const { spawnReviewRoleForIssue } = await import("./review-agent-CSswH985.js");
24392
+ const { spawnReviewRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
23789
24393
  const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
23790
24394
  issueId,
23791
24395
  workspace,
@@ -23810,8 +24414,8 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
23810
24414
  const workspace = agentState?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
23811
24415
  if (workspace && resolved) {
23812
24416
  const branch = `feature/${issueLower}`;
23813
- const { spawnRun } = await import("./agents-Czz6R57Z.js");
23814
- const { buildTestRolePrompt } = await import("./test-agent-queue-BwpUpu-o.js");
24417
+ const { spawnRun } = await import("./agents-FlIgQ3ql.js");
24418
+ const { buildTestRolePrompt } = await import("./test-agent-queue-DXDt0Xa-.js");
23815
24419
  const stackRecovery = await recoverUnhealthyTestStack(issueId, workspace);
23816
24420
  if (stackRecovery === "cooldown" || stackRecovery === "exhausted") {
23817
24421
  setReviewStatusSync(issueId, { testStatus: "dispatch_failed" });
@@ -23949,7 +24553,7 @@ async function recoverStalledReviewConvoys(getCanonicalState = getAutoCloseOutCa
23949
24553
  record.lastAttempt = now;
23950
24554
  record.attempts += 1;
23951
24555
  stalledReviewConvoyRecoveryState.set(key, record);
23952
- const { spawnReviewRoleForIssue } = await import("./review-agent-CSswH985.js");
24556
+ const { spawnReviewRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
23953
24557
  try {
23954
24558
  const result = await Effect.runPromise(spawnReviewRoleForIssue({
23955
24559
  issueId,
@@ -24020,7 +24624,7 @@ async function checkMissingReviewStatuses() {
24020
24624
  continue;
24021
24625
  }
24022
24626
  try {
24023
- const { spawnReviewRoleForIssue } = await import("./review-agent-CSswH985.js");
24627
+ const { spawnReviewRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
24024
24628
  await Effect.runPromise(spawnReviewRoleForIssue({
24025
24629
  issueId,
24026
24630
  workspace,
@@ -24047,7 +24651,6 @@ async function checkMissingReviewStatuses() {
24047
24651
  }
24048
24652
  //#endregion
24049
24653
  //#region ../../lib/cloister/deacon-review-unsignaled.ts
24050
- init_tracker_utils();
24051
24654
  init_agents$1();
24052
24655
  init_projects();
24053
24656
  init_review_status();
@@ -24073,7 +24676,7 @@ async function checkStuckReviewing() {
24073
24676
  const actions = [];
24074
24677
  const REVIEW_STUCK_THRESHOLD_MS = 1800 * 1e3;
24075
24678
  try {
24076
- const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-DXeqFpk5.js");
24679
+ const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-C6n6-9f_.js");
24077
24680
  const statuses = loadReviewStatuses();
24078
24681
  const now = Date.now();
24079
24682
  const activeReviewIssues = /* @__PURE__ */ new Set();
@@ -24218,7 +24821,7 @@ async function checkCompletedButUnsignaledReviews() {
24218
24821
  }
24219
24822
  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
24823
  try {
24221
- const { messageAgent } = await import("./agents-Czz6R57Z.js");
24824
+ const { messageAgent } = await import("./agents-FlIgQ3ql.js");
24222
24825
  await messageAgent(reviewSession, nudge);
24223
24826
  unsignaledReviewNudges.set(latestDir, now);
24224
24827
  actions.push(`Nudged ${reviewSession} to signal ${verdict} (synthesis written ${Math.round((now - latestMtime) / 6e4)}min ago)`);
@@ -24340,7 +24943,7 @@ async function respawnIdleReviewer(state, agentId) {
24340
24943
  return false;
24341
24944
  }
24342
24945
  try {
24343
- const { spawnReviewSubRoleForIssue } = await import("./review-agent-CSswH985.js");
24946
+ const { spawnReviewSubRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
24344
24947
  const contextManifestPath = join$1(dirname$1(outputPath), "context.json");
24345
24948
  const result = await Effect.runPromise(spawnReviewSubRoleForIssue({
24346
24949
  issueId: state.issueId,
@@ -24469,7 +25072,7 @@ async function nudgeSynthesisForCompleteReviewerReports(states) {
24469
25072
  "Read the four reports, write synthesis.md, then signal review status exactly as roles/review.md instructs."
24470
25073
  ].join("\n");
24471
25074
  try {
24472
- const { messageAgent } = await import("./agents-Czz6R57Z.js");
25075
+ const { messageAgent } = await import("./agents-FlIgQ3ql.js");
24473
25076
  await messageAgent(state.id, message);
24474
25077
  reviewReportsPresentNudges.set(nudgeKey, now);
24475
25078
  const action = `Nudged ${state.id} to synthesize from ${REVIEW_SUB_ROLES.length} reviewer reports`;
@@ -24555,7 +25158,7 @@ async function monitorReviewConvoySignals() {
24555
25158
  if (!signal) continue;
24556
25159
  const message = signal === "ready" ? `REVIEWER_READY ${state.reviewSubRole} ${outputPath}` : signal === "timeout" ? `REVIEWER_TIMEOUT ${state.reviewSubRole} ${reason}` : `REVIEWER_FAILED ${state.reviewSubRole} ${reason}`;
24557
25160
  try {
24558
- const { messageAgent } = await import("./agents-Czz6R57Z.js");
25161
+ const { messageAgent } = await import("./agents-FlIgQ3ql.js");
24559
25162
  await messageAgent(state.reviewSynthesisAgentId, message);
24560
25163
  state.reviewMonitorSignaled = signal;
24561
25164
  saveAgentStateSync(state);
@@ -24563,7 +25166,7 @@ async function monitorReviewConvoySignals() {
24563
25166
  actions.push(action);
24564
25167
  logDeaconEventSync(`monitorReviewConvoySignals: ${action}`);
24565
25168
  if (signal === "ready") try {
24566
- const { notifyPipelineSync } = await import("./pipeline-notifier-dQ-U4NSb.js");
25169
+ const { notifyPipelineSync } = await import("./pipeline-notifier-6iCJplFZ.js");
24567
25170
  notifyPipelineSync({
24568
25171
  type: "reviewer_completed",
24569
25172
  issueId: state.issueId,
@@ -24571,7 +25174,7 @@ async function monitorReviewConvoySignals() {
24571
25174
  });
24572
25175
  } catch {}
24573
25176
  else if (signal === "timeout") try {
24574
- const { notifyPipelineSync } = await import("./pipeline-notifier-dQ-U4NSb.js");
25177
+ const { notifyPipelineSync } = await import("./pipeline-notifier-6iCJplFZ.js");
24575
25178
  notifyPipelineSync({
24576
25179
  type: "reviewer_timed_out",
24577
25180
  issueId: state.issueId,
@@ -24671,7 +25274,7 @@ const FORK_CACHE_CHECK_DELAY_MS = 180 * 1e3;
24671
25274
  async function checkStalledReviewDiscovery() {
24672
25275
  const actions = [];
24673
25276
  try {
24674
- const { listAgentStates } = await import("./agents-Czz6R57Z.js");
25277
+ const { listAgentStates } = await import("./agents-FlIgQ3ql.js");
24675
25278
  const states = listAgentStates();
24676
25279
  const now = Date.now();
24677
25280
  for (const state of states) {
@@ -24680,7 +25283,7 @@ async function checkStalledReviewDiscovery() {
24680
25283
  const aged = Number.isFinite(startedMs) && now - startedMs > 48e4;
24681
25284
  const dead = !await Effect.runPromise(sessionExists(state.id)).catch(() => false) || await Effect.runPromise(isPaneDead(state.id)).catch(() => true);
24682
25285
  if (!aged && !dead) continue;
24683
- const { handleReviewDiscoveryReady } = await import("./review-agent-CSswH985.js");
25286
+ const { handleReviewDiscoveryReady } = await import("./review-agent-DJRO8EG8.js");
24684
25287
  const result = await handleReviewDiscoveryReady(state.issueId, { source: dead ? "deacon-backstop (parent dead)" : "deacon-backstop (discovery timeout)" });
24685
25288
  actions.push(result.message);
24686
25289
  logDeaconEventSync(`checkStalledReviewDiscovery: ${result.message}`);
@@ -24703,8 +25306,8 @@ async function checkStalledReviewDiscovery() {
24703
25306
  async function checkStalledReviewParents() {
24704
25307
  const actions = [];
24705
25308
  try {
24706
- const { listAgentStates, markAgentStoppedState } = await import("./agents-Czz6R57Z.js");
24707
- const { PARENT_REVIEW_TIMEOUT_MS } = await import("./review-agent-CSswH985.js");
25309
+ const { listAgentStates, markAgentStoppedState } = await import("./agents-FlIgQ3ql.js");
25310
+ const { PARENT_REVIEW_TIMEOUT_MS } = await import("./review-agent-DJRO8EG8.js");
24708
25311
  const states = listAgentStates();
24709
25312
  const now = Date.now();
24710
25313
  for (const state of states) {
@@ -24753,8 +25356,8 @@ async function checkStalledReviewParents() {
24753
25356
  async function checkReviewForkCacheMisses() {
24754
25357
  const actions = [];
24755
25358
  try {
24756
- const { listAgentStates, saveAgentState } = await import("./agents-Czz6R57Z.js");
24757
- const { readEventsSync } = await import("./events-LGeUehYW.js");
25359
+ const { listAgentStates, saveAgentState } = await import("./agents-FlIgQ3ql.js");
25360
+ const { readEventsSync } = await import("./events-CvvGK6LT.js");
24758
25361
  const { emitActivityEntrySync } = await import("./activity-logger-OEUBdfZ8.js");
24759
25362
  const states = listAgentStates();
24760
25363
  const now = Date.now();
@@ -24805,7 +25408,6 @@ async function checkReviewForkCacheMisses() {
24805
25408
  init_paths();
24806
25409
  init_activity_logger();
24807
25410
  init_agents$1();
24808
- init_concurrency$1();
24809
25411
  init_review_status();
24810
25412
  init_projects();
24811
25413
  init_tmux();
@@ -24890,7 +25492,7 @@ async function reconcileStaleMergeStatus() {
24890
25492
  if (!project) continue;
24891
25493
  let specStatus;
24892
25494
  try {
24893
- const { findSpecByIssue } = await import("./specs-BsNcum0h.js");
25495
+ const { findSpecByIssue } = await import("./specs-nN45DG2X.js");
24894
25496
  const spec = await Effect.runPromise(findSpecByIssue(project.projectPath, issueId));
24895
25497
  specStatus = spec?.status;
24896
25498
  if (spec && (spec.status === "completed" || spec.status === "cancelled")) {
@@ -24905,7 +25507,7 @@ async function reconcileStaleMergeStatus() {
24905
25507
  if (branchTip.stdout.trim() === mainTip.stdout.trim()) console.log(`[deacon] ${issueId}: branch ${branch} points at main; not treating zero-commit branch as merged`);
24906
25508
  } catch {}
24907
25509
  if (!isMerged) {
24908
- const { resolveGitHubIssueSync: _resolveGitHubIssue } = await import("./tracker-utils-WtP_V-yn.js");
25510
+ const { resolveGitHubIssueSync: _resolveGitHubIssue } = await import("./tracker-utils-BePq_oj-.js");
24909
25511
  const ghResolved = _resolveGitHubIssue(issueId);
24910
25512
  if (ghResolved.isGitHub) try {
24911
25513
  const { stdout } = await execFileAsync$4("gh", [
@@ -24942,7 +25544,7 @@ async function reconcileStaleMergeStatus() {
24942
25544
  actions.push(msg);
24943
25545
  console.log(`[deacon] ${msg}`);
24944
25546
  try {
24945
- const { postMergeLifecycle } = await import("./merge-agent-CnORPiri.js");
25547
+ const { postMergeLifecycle } = await import("./merge-agent-BQM3a8z5.js");
24946
25548
  postMergeLifecycle(issueId, project.projectPath, branch, { skipDeploy: true }).catch((err) => console.warn(`[deacon] postMergeLifecycle (reconcile) failed for ${issueId}: ${err}`));
24947
25549
  } catch (err) {
24948
25550
  console.warn(`[deacon] Could not import postMergeLifecycle: ${err}`);
@@ -24967,7 +25569,7 @@ const falseMergedReset = /* @__PURE__ */ new Set();
24967
25569
  async function reconcileFalseMerged() {
24968
25570
  const actions = [];
24969
25571
  try {
24970
- const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CeSVFL6C.js");
25572
+ const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CPfoFAdV.js");
24971
25573
  if (!isGitHubAppConfigured()) return actions;
24972
25574
  const statuses = loadReviewStatuses();
24973
25575
  for (const [issueId, status] of Object.entries(statuses)) {
@@ -25012,7 +25614,7 @@ const CLOSED_PR_RECONCILE_COOLDOWN_MS = 600 * 1e3;
25012
25614
  async function reconcileClosedPrReadyForMerge() {
25013
25615
  const actions = [];
25014
25616
  try {
25015
- const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CeSVFL6C.js");
25617
+ const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CPfoFAdV.js");
25016
25618
  if (!isGitHubAppConfigured()) return actions;
25017
25619
  const statuses = loadReviewStatuses();
25018
25620
  const now = Date.now();
@@ -25084,7 +25686,7 @@ const STALE_MERGE_BLOCKER_COOLDOWN_MS = 120 * 1e3;
25084
25686
  async function reconcileStaleMergeBlockers() {
25085
25687
  const actions = [];
25086
25688
  try {
25087
- const { resolveConflictGate, buildRealConflictGateDeps } = await import("./conflict-gate-BKalpcjL.js");
25689
+ const { resolveConflictGate, buildRealConflictGateDeps } = await import("./conflict-gate-BSJkNTdp.js");
25088
25690
  const statuses = loadReviewStatuses();
25089
25691
  const now = Date.now();
25090
25692
  const deps = buildRealConflictGateDeps();
@@ -25227,7 +25829,7 @@ async function checkFailedMergeRetry() {
25227
25829
  if (ciEntry.count === 5) {
25228
25830
  console.log(`[deacon] CI check failure for ${issueId} — retries exhausted, notifying work agent`);
25229
25831
  const ciNotes = status.mergeNotes || "CI checks are failing on the PR";
25230
- const { writeFeedbackFile } = await import("./feedback-writer-DDQNV8uc.js");
25832
+ const { writeFeedbackFile } = await import("./feedback-writer-qmiMbqTZ.js");
25231
25833
  const ciFileResult = await Effect.runPromise(writeFeedbackFile({
25232
25834
  issueId,
25233
25835
  specialist: "merge-agent",
@@ -25259,7 +25861,7 @@ async function checkFailedMergeRetry() {
25259
25861
  ciRetryMap.set(issueId, ciEntry);
25260
25862
  console.log(`[deacon] CI check failure for ${issueId} — notifying agent to re-submit (attempt ${ciEntry.count}/5)`);
25261
25863
  const ciNotes = status.mergeNotes || "CI checks are failing on the PR";
25262
- const { writeFeedbackFile } = await import("./feedback-writer-DDQNV8uc.js");
25864
+ const { writeFeedbackFile } = await import("./feedback-writer-qmiMbqTZ.js");
25263
25865
  const ciFileResult2 = await Effect.runPromise(writeFeedbackFile({
25264
25866
  issueId,
25265
25867
  specialist: "merge-agent",
@@ -25287,7 +25889,7 @@ async function checkFailedMergeRetry() {
25287
25889
  const lastNudge = timeoutNudgeCooldowns.get(issueIdForFb);
25288
25890
  if (!lastNudge || now - lastNudge >= TIMEOUT_NUDGE_COOLDOWN_MS) {
25289
25891
  const timeoutNotes = status.mergeNotes;
25290
- const { writeFeedbackFile } = await import("./feedback-writer-DDQNV8uc.js");
25892
+ const { writeFeedbackFile } = await import("./feedback-writer-qmiMbqTZ.js");
25291
25893
  await Effect.runPromise(writeFeedbackFile({
25292
25894
  issueId: issueIdForFb,
25293
25895
  specialist: "merge-agent",
@@ -25392,7 +25994,7 @@ async function autoCloseOut(now = /* @__PURE__ */ new Date()) {
25392
25994
  } } : {}
25393
25995
  };
25394
25996
  try {
25395
- const { closeOut } = await import("./workflows-C5c-RPsY.js");
25997
+ const { closeOut } = await import("./workflows-D90rMOya.js");
25396
25998
  const result = await Effect.runPromise(closeOut(ctx));
25397
25999
  if (!result.success) {
25398
26000
  const failed = result.steps.find((step) => !step.success && !step.skipped);
@@ -25511,16 +26113,8 @@ async function checkFirstCompletionAgents() {
25511
26113
  return actions;
25512
26114
  }
25513
26115
  //#endregion
25514
- //#region ../../lib/cloister/agent-grace.ts
25515
- init_traefik_connect();
25516
- const WORK_LAUNCHER_GRACE_MS = 12e4;
25517
- function isStartingWithinGrace(state, now = Date.now(), graceMs = WORK_LAUNCHER_GRACE_MS) {
25518
- if (state.status !== "starting") return false;
25519
- const startedMs = Date.parse(state.startedAt ?? "");
25520
- return Number.isFinite(startedMs) && now - startedMs < graceMs;
25521
- }
25522
- //#endregion
25523
26116
  //#region ../../lib/cloister/boot-reconciliation-outcomes.ts
26117
+ init_traefik_connect();
25524
26118
  function resumedBootReconciliationOutcome(agent) {
25525
26119
  return {
25526
26120
  id: agent.id,
@@ -25688,9 +26282,71 @@ function startBootReconciliation(options = {}) {
25688
26282
  };
25689
26283
  }
25690
26284
  //#endregion
25691
- //#region ../../lib/cloister/confirmed-session-query.ts
26285
+ //#region ../../lib/agents/pinned-launch.ts
25692
26286
  init_io();
25693
26287
  init_dag();
26288
+ init_agent_state();
26289
+ function parseFlagValue(content, flag) {
26290
+ const escapedFlag = flag.replace("-", "\\-");
26291
+ const quoted = content.match(new RegExp(`${escapedFlag}\\s+'([^']+)'`)) ?? content.match(new RegExp(`${escapedFlag}\\s+"([^"]+)"`));
26292
+ if (quoted?.[1]) return quoted[1];
26293
+ return content.match(new RegExp(`${escapedFlag}\\s+([^\\s'"\\\\]+)`))?.[1] ?? null;
26294
+ }
26295
+ function parsePinnedAgentLaunch(launcher, sessionId) {
26296
+ const pinnedSessionId = sessionId.trim();
26297
+ if (!pinnedSessionId) return null;
26298
+ const harness = launcher.includes("codex-app-server-host.js") || /(?:^|\s)(?:exec\s+)?codex(?:\s|$)/m.test(launcher) ? "codex" : /(?:^|\s)(?:exec\s+)?omp\s+--mode\s+rpc(?:\s|$)/m.test(launcher) ? "ohmypi" : /(?:^|\s)claude(?:\s|$)/m.test(launcher) ? "claude-code" : null;
26299
+ const model = parseFlagValue(launcher, "--model") ?? parseFlagValue(launcher, "-m");
26300
+ if (!harness || !model || model.startsWith("pending-")) return null;
26301
+ return {
26302
+ sessionId: pinnedSessionId,
26303
+ model,
26304
+ harness
26305
+ };
26306
+ }
26307
+ function readPinnedAgentLaunchSync(agentId) {
26308
+ const agentDir = getAgentDir(agentId);
26309
+ const launcherPath = join(agentDir, "launcher.sh");
26310
+ const sessionIdPath = join(agentDir, "session.id");
26311
+ if (!existsSync$1(launcherPath) || !existsSync$1(sessionIdPath)) return null;
26312
+ try {
26313
+ return parsePinnedAgentLaunch(readFileSync$1(launcherPath, "utf8"), readFileSync$1(sessionIdPath, "utf8"));
26314
+ } catch {
26315
+ return null;
26316
+ }
26317
+ }
26318
+ //#endregion
26319
+ //#region ../../lib/agents/placeholder-reconciliation.ts
26320
+ init_persistent_logger();
26321
+ init_agent_state();
26322
+ function defaultPlaceholderReconciliationDeps() {
26323
+ return {
26324
+ readPinnedLaunch: readPinnedAgentLaunchSync,
26325
+ markRunning: markAgentRunningState,
26326
+ saveState: (state) => Effect.runPromise(saveAgentState(state)),
26327
+ logDeacon: logDeaconEventSync,
26328
+ logAgent: logAgentLifecycleSync
26329
+ };
26330
+ }
26331
+ async function reconcileLiveWorkSpawnPlaceholder(state, notifyStatusChanged, deps) {
26332
+ if (state.model !== "pending-work-spawn") return null;
26333
+ const resolvedDeps = deps ?? defaultPlaceholderReconciliationDeps();
26334
+ const pinnedLaunch = resolvedDeps.readPinnedLaunch(state.id);
26335
+ if (!pinnedLaunch) return null;
26336
+ const previousStatus = state.status;
26337
+ state.model = pinnedLaunch.model;
26338
+ state.harness = pinnedLaunch.harness;
26339
+ state.sessionId = pinnedLaunch.sessionId;
26340
+ resolvedDeps.markRunning(state);
26341
+ await resolvedDeps.saveState(state);
26342
+ notifyStatusChanged(state, previousStatus, true);
26343
+ const message = `Reconciled ${state.id} placeholder to running (${pinnedLaunch.harness}/${pinnedLaunch.model})`;
26344
+ resolvedDeps.logDeacon(`handleAgentHeartbeatDeadEvent: ${message}`);
26345
+ resolvedDeps.logAgent(state.id, message);
26346
+ return message;
26347
+ }
26348
+ //#endregion
26349
+ //#region ../../lib/cloister/confirmed-session-query.ts
25694
26350
  init_tmux();
25695
26351
  const consecutiveMisses = /* @__PURE__ */ new Map();
25696
26352
  function queryConfirmedSession(agentId) {
@@ -25832,7 +26488,10 @@ async function handleAgentHeartbeatDeadEvent$1(agentId, context, deps) {
25832
26488
  } catch {
25833
26489
  return [];
25834
26490
  }
25835
- else return [];
26491
+ else {
26492
+ const action = await reconcileLiveWorkSpawnPlaceholder(state, deps.notifyAgentStatusChanged);
26493
+ return action ? [action] : [];
26494
+ }
25836
26495
  else if (state.status === "starting") {
25837
26496
  if (isStartingWithinGrace(state)) return [];
25838
26497
  }
@@ -25990,7 +26649,7 @@ async function nudgeStalledResumeWorkAgents() {
25990
26649
  const message = buildStalledResumePrompt(state);
25991
26650
  if (!message) continue;
25992
26651
  try {
25993
- const { messageAgent } = await import("./agents-Czz6R57Z.js");
26652
+ const { messageAgent } = await import("./agents-FlIgQ3ql.js");
25994
26653
  await messageAgent(agentId, message);
25995
26654
  recordCooldown(agentId, ".last-stalled-resume-nudge");
25996
26655
  const action = `Re-sent stalled resume prompt to ${agentId} (${state.issueId})`;
@@ -26099,12 +26758,12 @@ async function nudgeIdleWorkAgentsWithOpenBeads() {
26099
26758
  ``,
26100
26759
  `Next ready task: ${firstTask}`,
26101
26760
  ``,
26102
- `If you don't already have your full brief for ${state.issueId} in context (work-agent role instructions, the vBRIEF plan, recorded decisions & hazards), re-read it now — it is on disk at ${briefPath}, plus .pan/continue.json and .pan/spec.vbrief.json in your workspace. Startup kickoff delivery can silently fail on large briefs, so do not assume you received it.`,
26761
+ `If you don't already have your full brief for ${state.issueId} in context (work-agent role instructions, the xBRIEF plan, recorded decisions & hazards), re-read it now — it is on disk at ${briefPath}, plus .pan/continue.json and .pan/spec.vbrief.json in your workspace. Startup kickoff delivery can silently fail on large briefs, so do not assume you received it.`,
26103
26762
  ``,
26104
26763
  "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
26764
  ].join("\n");
26106
26765
  try {
26107
- const { messageAgent } = await import("./agents-Czz6R57Z.js");
26766
+ const { messageAgent } = await import("./agents-FlIgQ3ql.js");
26108
26767
  await messageAgent(agentId, message);
26109
26768
  writeFileSync(join$1(getAgentDir(agentId), ".last-bead-nudge"), String(Date.now()), "utf-8");
26110
26769
  const action = `Nudged idle ${agentId} (${state.issueId}) — ${openTasks.length} ready task(s)`;
@@ -27373,8 +28032,8 @@ async function cleanupStaleAgentState() {
27373
28032
  */
27374
28033
  async function cleanupAbandonedFeedback() {
27375
28034
  const actions = [];
27376
- const { getReviewStatusSync } = await import("./review-status-DXeqFpk5.js");
27377
- const { clearFeedbackFiles } = await import("./feedback-writer-DDQNV8uc.js");
28035
+ const { getReviewStatusSync } = await import("./review-status-C6n6-9f_.js");
28036
+ const { clearFeedbackFiles } = await import("./feedback-writer-qmiMbqTZ.js");
27378
28037
  for (const { issueId, workspacePath } of listFeatureWorkspaces()) {
27379
28038
  const panFeedbackDir = join$1(workspacePath, ".pan", "feedback");
27380
28039
  if (!existsSync(panFeedbackDir)) continue;
@@ -27445,7 +28104,7 @@ async function handleOrphanReviewerSession(sessionName, sessions, creationTimes,
27445
28104
  if (!issueId) return null;
27446
28105
  const agentSession = `agent-${issueId.toLowerCase()}`;
27447
28106
  if (sessions.includes(agentSession)) return null;
27448
- const { getReviewStatusSync } = await import("./review-status-DXeqFpk5.js");
28107
+ const { getReviewStatusSync } = await import("./review-status-C6n6-9f_.js");
27449
28108
  try {
27450
28109
  if (getReviewStatusSync(issueId)?.reviewStatus === "reviewing") return null;
27451
28110
  } catch {}
@@ -27567,7 +28226,7 @@ async function checkOrphanedCompletions() {
27567
28226
  async function checkPendingTestDispatch() {
27568
28227
  const actions = [];
27569
28228
  try {
27570
- const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-DXeqFpk5.js");
28229
+ const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-C6n6-9f_.js");
27571
28230
  const statuses = loadReviewStatuses();
27572
28231
  const now = Date.now();
27573
28232
  for (const [issueId, status] of Object.entries(statuses)) {
@@ -27600,7 +28259,7 @@ async function checkPendingTestDispatch() {
27600
28259
  console.log(`[deacon] ${issueId}: skipping test re-dispatch — issue is closed`);
27601
28260
  continue;
27602
28261
  }
27603
- const { resolveProjectFromIssueSync } = await import("./projects-IRHJIPYC.js");
28262
+ const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
27604
28263
  const resolved = resolveProjectFromIssueSync(issueId);
27605
28264
  if (!resolved) continue;
27606
28265
  const issueLower = issueId.toLowerCase();
@@ -27615,8 +28274,8 @@ async function checkPendingTestDispatch() {
27615
28274
  logDeaconEventSync(`checkPendingTestDispatch: deferred test for ${issueId} — advancing ceiling reached (PAN-1665) — ${describeRunningAgents()}`);
27616
28275
  continue;
27617
28276
  }
27618
- const { spawnRun } = await import("./agents-Czz6R57Z.js");
27619
- const { buildTestRolePrompt } = await import("./test-agent-queue-BwpUpu-o.js");
28277
+ const { spawnRun } = await import("./agents-FlIgQ3ql.js");
28278
+ const { buildTestRolePrompt } = await import("./test-agent-queue-DXDt0Xa-.js");
27620
28279
  try {
27621
28280
  const run = await spawnRun(issueId, "test", {
27622
28281
  workspace,
@@ -27739,7 +28398,7 @@ async function checkCompletedButUnsignaledTests() {
27739
28398
  const cmd = `pan admin specialists done test ${issueId} --status ${decision.status}${noteArg}`;
27740
28399
  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
28400
  try {
27742
- const { messageAgent } = await import("./agents-Czz6R57Z.js");
28401
+ const { messageAgent } = await import("./agents-FlIgQ3ql.js");
27743
28402
  await messageAgent(testSession, nudge);
27744
28403
  unsignaledTestNudges.set(testSession, now);
27745
28404
  const msg = `Nudged ${testSession} to signal ${decision.status} (verdict artifact present)`;
@@ -27753,7 +28412,7 @@ async function checkCompletedButUnsignaledTests() {
27753
28412
  case "nudge-write": {
27754
28413
  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
28414
  try {
27756
- const { messageAgent } = await import("./agents-Czz6R57Z.js");
28415
+ const { messageAgent } = await import("./agents-FlIgQ3ql.js");
27757
28416
  await messageAgent(testSession, nudge);
27758
28417
  unsignaledTestNudges.set(testSession, now);
27759
28418
  const msg = `Nudged ${testSession} to write+signal a test verdict (no artifact yet)`;
@@ -27776,8 +28435,8 @@ async function checkCompletedButUnsignaledTests() {
27776
28435
  async function checkVerificationReviewContradiction() {
27777
28436
  const actions = [];
27778
28437
  try {
27779
- const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-DXeqFpk5.js");
27780
- const { resolveProjectFromIssueSync } = await import("./projects-IRHJIPYC.js");
28438
+ const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-C6n6-9f_.js");
28439
+ const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
27781
28440
  const statuses = loadReviewStatuses();
27782
28441
  for (const [issueId, status] of Object.entries(statuses)) if (status.verificationStatus === "passed" && status.reviewStatus === "reviewing" && status.stuckReason === "review_infrastructure_failure") {
27783
28442
  let reviewedAtCommit;
@@ -27826,7 +28485,7 @@ async function checkPostReviewCommits() {
27826
28485
  const actions = [];
27827
28486
  try {
27828
28487
  const statuses = loadReviewStatuses();
27829
- const { resolveProjectFromIssueSync } = await import("./projects-IRHJIPYC.js");
28488
+ const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
27830
28489
  for (const [issueId, status] of Object.entries(statuses)) {
27831
28490
  if (status.mergeStatus === "merged") continue;
27832
28491
  if (!status.reviewedAtCommit) continue;
@@ -27881,7 +28540,7 @@ async function checkPostReviewCommits() {
27881
28540
  actions.push(`Deferred post-review re-dispatch for ${issueId} — advancing-role concurrency ceiling reached`);
27882
28541
  logDeaconEventSync(`checkPostReviewCommits: deferred review for ${issueId} — advancing ceiling reached (PAN-1665) — ${describeRunningAgents()}`);
27883
28542
  } else if (freshStatus?.reviewStatus === "pending") {
27884
- const { spawnReviewRoleForIssue } = await import("./review-agent-CSswH985.js");
28543
+ const { spawnReviewRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
27885
28544
  const branch = `feature/${issueId.toLowerCase()}`;
27886
28545
  const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
27887
28546
  issueId,
@@ -27981,7 +28640,7 @@ async function checkReadyForMergeStuck() {
27981
28640
  const testStatusGreenCiReconcileCooldowns = /* @__PURE__ */ new Map();
27982
28641
  const TEST_STATUS_GREEN_CI_RECONCILE_COOLDOWN_MS = 300 * 1e3;
27983
28642
  async function reconcileTestStatusFromGreenCi() {
27984
- const { getCiCheckRunsState, getPullRequestHeadState, isGitHubAppConfigured } = await import("./github-app-CeSVFL6C.js");
28643
+ const { getCiCheckRunsState, getPullRequestHeadState, isGitHubAppConfigured } = await import("./github-app-CPfoFAdV.js");
27985
28644
  return reconcileTestStatusFromGreenCiWithDeps({
27986
28645
  isGitHubAppConfigured,
27987
28646
  loadReviewStatuses,
@@ -28002,7 +28661,7 @@ async function reconcileTestStatusFromGreenCi() {
28002
28661
  */
28003
28662
  async function clearStaleCiFeedback(issueId) {
28004
28663
  const { readdir, rm } = await import("fs/promises");
28005
- const { resolveProjectFromIssueSync } = await import("./projects-IRHJIPYC.js");
28664
+ const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
28006
28665
  const projectConfig = resolveProjectFromIssueSync(issueId);
28007
28666
  if (!projectConfig) return;
28008
28667
  const repoDir = projectConfig.projectPath;
@@ -28298,7 +28957,7 @@ async function checkWorkspaceContainerHealth(sharedState) {
28298
28957
  }
28299
28958
  }
28300
28959
  try {
28301
- const { resolveProjectFromIssueSync } = await import("./projects-IRHJIPYC.js");
28960
+ const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
28302
28961
  const resolved = resolveProjectFromIssueSync(issueLower.toUpperCase());
28303
28962
  if (resolved) await killOrphanedWorkspaceProcesses(`${resolved.projectPath}/workspaces/feature-${issueLower}`);
28304
28963
  } catch {}
@@ -28347,8 +29006,8 @@ async function checkWorkspaceContainerHealth(sharedState) {
28347
29006
  async function checkMergedWorkSessions() {
28348
29007
  const actions = [];
28349
29008
  try {
28350
- const { selectMergedWorkSessions } = await import("./reap-terminal-sessions-C1mfzoZo.js");
28351
- const { setAgentPaused } = await import("./agents-Czz6R57Z.js");
29009
+ const { selectMergedWorkSessions } = await import("./reap-terminal-sessions-MWnqdLCJ.js");
29010
+ const { setAgentPaused } = await import("./agents-FlIgQ3ql.js");
28352
29011
  const toKill = selectMergedWorkSessions(loadReviewStatuses(), [...await Effect.runPromise(listSessionNames())]);
28353
29012
  for (const session of toKill) try {
28354
29013
  await Effect.runPromise(setAgentPaused(session, "merged — awaiting close-out (verify on main)", true));
@@ -28388,7 +29047,7 @@ const AWAITING_TEST_IDLE_REAP_MS = 600 * 1e3;
28388
29047
  async function checkAwaitingTestWorkSessions() {
28389
29048
  const actions = [];
28390
29049
  try {
28391
- const { selectAwaitingTestWorkSessions } = await import("./reap-terminal-sessions-C1mfzoZo.js");
29050
+ const { selectAwaitingTestWorkSessions } = await import("./reap-terminal-sessions-MWnqdLCJ.js");
28392
29051
  const candidates = selectAwaitingTestWorkSessions(loadReviewStatuses(), [...await Effect.runPromise(listSessionNames())]);
28393
29052
  const now = Date.now();
28394
29053
  for (const session of candidates) {
@@ -28441,14 +29100,14 @@ async function runPatrol() {
28441
29100
  hasLoggedGlobalPauseSkip = false;
28442
29101
  addLog("info", `Patrol cycle ${state.patrolCycle} — checking per-project specialists`, state.patrolCycle);
28443
29102
  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()) {
29103
+ for (const a of await (await import("./stale-task-claims-BbFwCTb0.js")).patrolStaleTaskClaims()) {
28445
29104
  actions.push(a);
28446
29105
  addLog("action", a, state.patrolCycle);
28447
29106
  }
28448
29107
  const stuckRemediationActions = await checkStuckAgentRemediation();
28449
29108
  actions.push(...stuckRemediationActions);
28450
29109
  for (const a of stuckRemediationActions) addLog("action", a, state.patrolCycle);
28451
- const { reconcileInFlightJournals } = await import("./advancing-selfheal-CPOBO5ZS.js");
29110
+ const { reconcileInFlightJournals } = await import("./advancing-selfheal-BBu6DSNm.js");
28452
29111
  const reconciledJournalActions = await reconcileInFlightJournals();
28453
29112
  actions.push(...reconciledJournalActions);
28454
29113
  for (const a of reconciledJournalActions) addLog("action", a, state.patrolCycle);
@@ -28460,7 +29119,7 @@ async function runPatrol() {
28460
29119
  const age = Date.now() - (pending.timestamp ?? 0);
28461
29120
  if (age < 3600 * 1e3) {
28462
29121
  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");
29122
+ const { postMergeLifecycle } = await import("./merge-agent-BQM3a8z5.js");
28464
29123
  const { unlinkSync } = await import("fs");
28465
29124
  unlinkSync(pendingFile);
28466
29125
  await postMergeLifecycle(pending.issueId, pending.projectPath, pending.sourceBranch, { skipDeploy: true });
@@ -28474,7 +29133,7 @@ async function runPatrol() {
28474
29133
  } catch (err) {
28475
29134
  console.warn(`[deacon] Failed to process pending lifecycle: ${err.message}`);
28476
29135
  }
28477
- if (state.patrolCycle % 5 === 0) await (await import("./deploy-patrol-DmM6F-yw.js")).runScheduledDeployPatrol();
29136
+ if (state.patrolCycle % 5 === 0) await (await import("./deploy-patrol-Bjsho_ha.js")).runScheduledDeployPatrol();
28478
29137
  const livenessActions = await reconcileAgentLiveness();
28479
29138
  actions.push(...livenessActions);
28480
29139
  for (const a of livenessActions) addLog("action", a, state.patrolCycle);
@@ -28506,7 +29165,7 @@ async function runPatrol() {
28506
29165
  actions.push(...suspendActions);
28507
29166
  for (const a of suspendActions) addLog("action", a, state.patrolCycle);
28508
29167
  try {
28509
- const { resolveProjectFromIssueSync } = await import("./projects-IRHJIPYC.js");
29168
+ const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
28510
29169
  const allStatuses = loadReviewStatuses();
28511
29170
  for (const [issueId, status] of Object.entries(allStatuses)) {
28512
29171
  if (!status.readyForMerge || status.mergeStatus === "merged") continue;
@@ -28526,7 +29185,7 @@ async function runPatrol() {
28526
29185
  } catch (err) {
28527
29186
  console.warn(`[deacon] Failed to check workspace existence: ${err.message}`);
28528
29187
  }
28529
- const { checkMergedAdvancingSessions } = await import("./advancing-selfheal-CPOBO5ZS.js");
29188
+ const { checkMergedAdvancingSessions } = await import("./advancing-selfheal-BBu6DSNm.js");
28530
29189
  const reapedWorkActions = await checkMergedWorkSessions();
28531
29190
  actions.push(...reapedWorkActions);
28532
29191
  for (const a of reapedWorkActions) addLog("action", a, state.patrolCycle);
@@ -28534,7 +29193,7 @@ async function runPatrol() {
28534
29193
  actions.push(...reapedMergedAdvancingActions);
28535
29194
  for (const a of reapedMergedAdvancingActions) addLog("action", a, state.patrolCycle);
28536
29195
  try {
28537
- const { refreshClaudeCredentialsForActiveRemoteAgents } = await import("./remote-completion-W67FNQ-A.js");
29196
+ const { refreshClaudeCredentialsForActiveRemoteAgents } = await import("./remote-completion-BbWNd10K.js");
28538
29197
  const remoteCredentialActions = await refreshClaudeCredentialsForActiveRemoteAgents();
28539
29198
  actions.push(...remoteCredentialActions);
28540
29199
  for (const a of remoteCredentialActions) addLog(a.includes("failed") ? "warn" : "action", a, state.patrolCycle);
@@ -28542,7 +29201,7 @@ async function runPatrol() {
28542
29201
  addLog("warn", `Remote credential refresh patrol failed: ${err.message}`, state.patrolCycle);
28543
29202
  }
28544
29203
  try {
28545
- const { refreshHostHeartbeatForEphemeralVms } = await import("./remote-agents-BNORDWAX.js");
29204
+ const { refreshHostHeartbeatForEphemeralVms } = await import("./remote-agents-CRCg1L4H.js");
28546
29205
  const heartbeatActions = await refreshHostHeartbeatForEphemeralVms();
28547
29206
  actions.push(...heartbeatActions);
28548
29207
  for (const a of heartbeatActions) addLog(a.includes("failed") ? "warn" : "action", a, state.patrolCycle);
@@ -28550,7 +29209,7 @@ async function runPatrol() {
28550
29209
  addLog("warn", `Remote heartbeat refresh patrol failed: ${err.message}`, state.patrolCycle);
28551
29210
  }
28552
29211
  try {
28553
- const { reapCompletedRemoteAgents } = await import("./remote-completion-W67FNQ-A.js");
29212
+ const { reapCompletedRemoteAgents } = await import("./remote-completion-BbWNd10K.js");
28554
29213
  const remoteReap = await reapCompletedRemoteAgents();
28555
29214
  for (const r of remoteReap) if (r.status === "handed-off" || r.status === "error") {
28556
29215
  const msg = `Remote reap ${r.issueId}: ${r.status} (${r.details.join("; ")})`;
@@ -28735,7 +29394,7 @@ async function runPatrol() {
28735
29394
  const issueId = runtimeState.currentIssue;
28736
29395
  try {
28737
29396
  if (getReviewStatusSync(issueId)?.mergeStatus === "merging") {
28738
- const { resolveProjectFromIssueSync } = await import("./projects-IRHJIPYC.js");
29397
+ const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
28739
29398
  const resolved = resolveProjectFromIssueSync(issueId);
28740
29399
  if (resolved) {
28741
29400
  const branch = `feature/${issueId.toLowerCase()}`;
@@ -28749,7 +29408,7 @@ async function runPatrol() {
28749
29408
  mergeStatus: "merged",
28750
29409
  readyForMerge: false
28751
29410
  });
28752
- const { postMergeLifecycle } = await import("./merge-agent-CnORPiri.js");
29411
+ const { postMergeLifecycle } = await import("./merge-agent-BQM3a8z5.js");
28753
29412
  postMergeLifecycle(issueId, resolved.projectPath).catch((err) => console.warn(`[deacon] postMergeLifecycle failed for ${issueId}: ${err}`));
28754
29413
  actions.push(`Auto-completed stale merge for ${issueId}`);
28755
29414
  } else {
@@ -28929,7 +29588,7 @@ function startDeacon() {
28929
29588
  logDeaconEventSync(`startDeacon: health monitor starting (patrol every ${config.patrolIntervalMs / 1e3}s)`);
28930
29589
  (async () => {
28931
29590
  await reconcileAgentLiveness();
28932
- const { runBootAdvancingSelfHeal } = await import("./advancing-selfheal-CPOBO5ZS.js");
29591
+ const { runBootAdvancingSelfHeal } = await import("./advancing-selfheal-BBu6DSNm.js");
28933
29592
  await runBootAdvancingSelfHeal();
28934
29593
  runScheduledPatrol("startup");
28935
29594
  })().catch((err) => {
@@ -28999,6 +29658,6 @@ function assessDeaconPatrolFreshness(params) {
28999
29658
  };
29000
29659
  }
29001
29660
  //#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 };
29661
+ export { reconcileClosedPrReadyForMerge as $, reconcileAgentLiveness as A, getContainerHistory as At, recordDeadEndNeedsYou as B, getLastPatrolResult as C, paneShowsClaudeBootBlockingScreen as Ct, isDeaconRunning as D, classifyMemoryPressure as Dt, handleAgentStoppedForOrphanReviewerSessions as E, WORK_LAUNCHER_GRACE_MS as Et, setAgentStatusChangedNotifier as F, getSystemHealthEvidenceSnapshot as Ft, redeliverUndeliveredKickoffs as G, isRapidPostResumeDeath as H, setAgentStoppedNotifier as I, getSystemHealthSnapshot as It, startBootReconciliation as J, isBootReconciliationCandidate as K, setMergeReadyNotifier as L, isSmeeConfiguredSync as Lt, resetPatrolHeartbeatForStartup as M, getAcceptedSystemHealthSnapshot as Mt, runPatrol as N, getDeployStaleness as Nt, loadConfig as O, getResourceStacks as Ot, saveState as P, getResourceConfig as Pt, ciRetryMap as Q, startDeacon as R, startSmeeProcessSync as Rt, getDeaconStatus as S, deliverOrchestratedCompact as St, handleAgentStoppedEvent as T, checkInspectAgentTimeouts 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, getCurrentDockerStats as jt, loadState as k, formatUptime 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, INSPECT_TIMEOUT_MS as wt, getDeaconLogs as x, stuckOverflowNativeRecoveryState as xt, cleanupStaleAgentState as y, contextOverflowRecoveryState as yt, stopDeacon as z, classifyAgentHealth as zt };
29003
29662
 
29004
- //# sourceMappingURL=deacon-1s7bM5zn.js.map
29663
+ //# sourceMappingURL=deacon-pRnyD5w9.js.map