@overdeck/desktop 0.45.22 → 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 (375) hide show
  1. package/package.json +1 -1
  2. package/server/{acceptance-criteria-BH7ac_1G.js → acceptance-criteria-DOA0KgXx.js} +5 -5
  3. package/server/{advancing-selfheal-cSvXNZLZ.js → advancing-selfheal-BBu6DSNm.js} +6 -6
  4. package/server/{agent-gc-Dj2gncak.js → agent-gc-BV1q_2EV.js} +4 -4
  5. package/server/agent-state-Bg0lhqwj.js +3 -0
  6. package/server/{agent-state-service-CsQ07Pxe.js → agent-state-service-CnzFKSAQ.js} +1 -1
  7. package/server/{agent-state-service-DistflNn.js → agent-state-service-HoK8U4jW.js} +5 -5
  8. package/server/{agents-DXdHmRTC.js → agents-B4Bjbkfv.js} +4 -4
  9. package/server/agents-FlIgQ3ql.js +3 -0
  10. package/server/{archive-planning-BvDuWNMo.js → archive-planning-DYrYojxl.js} +30 -6
  11. package/server/{archive-planning-Cp_DC1j-.js → archive-planning-zkJb3BeM.js} +1 -1
  12. package/server/{artifact-index-jobs-CDBFL4OU.js → artifact-index-jobs-C-xy7Z5v.js} +2 -2
  13. package/server/{backlog-auto-trigger-DmA1IbYf.js → backlog-auto-trigger-GtG71X8H.js} +3 -3
  14. package/server/{behavior-CGj16clS.js → behavior-B_-4EKF3.js} +2 -2
  15. package/server/{briefing-freshness-C12WgkaB.js → briefing-freshness-DWdW7vUm.js} +2 -2
  16. package/server/{build-info-NU3KbXYw.js → build-info-BT096lEl.js} +3 -3
  17. package/server/{build-info-BRpqQvNd.js → build-info-DgTqZkL5.js} +1 -1
  18. package/server/{checkpoint-manager-rOgT98WY.js → checkpoint-manager-B7Bt29J0.js} +1 -1
  19. package/server/{checkpoint-manager-CTPjAmtH.js → checkpoint-manager-DDqcGyu8.js} +2 -2
  20. package/server/checkpoint-worker.js +1 -1
  21. package/server/{checkpoints-BJum14fs.js → checkpoints-C-AXLfYT.js} +2 -2
  22. package/server/{checkpoints-B5jFNi2G.js → checkpoints-CpgCjAlN.js} +1 -1
  23. package/server/{claude-hooks-provision-BhwWK-TQ.js → claude-hooks-provision-C8wdRnN1.js} +1 -1
  24. package/server/{claude-hooks-provision-D7p5WcKZ.js → claude-hooks-provision-but-_qGY.js} +2 -2
  25. package/server/{claude-permissions-nSFKH78M.js → claude-permissions-H_5wHQZQ.js} +2 -2
  26. package/server/{claude-settings-overlay-DHBwjS1X.js → claude-settings-overlay-BTENVmYf.js} +1 -1
  27. package/server/{claude-settings-overlay-BI_UIke0.js → claude-settings-overlay-CbSz0Dvb.js} +2 -2
  28. package/server/cli-BsVIHwzC.js +3 -0
  29. package/server/{cli-CbKNkFE5.js → cli-vBeXbPrq.js} +9 -9
  30. package/server/{cliproxy-Brf_5MuG.js → cliproxy-Bgb2XCqi.js} +2 -2
  31. package/server/{cliproxy-bONZDBbC.js → cliproxy-DW0V86F8.js} +1 -1
  32. package/server/{close-issue-CxReRxIc.js → close-issue-Dn_4c4G8.js} +5 -5
  33. package/server/{closed-issue-reaper-DXP2Xyv3.js → closed-issue-reaper-CWpY2uBw.js} +1 -1
  34. package/server/{closed-issue-reaper-CQ3kqha7.js → closed-issue-reaper-hANY_ehE.js} +9 -9
  35. package/server/codex-Dg7Is5yb.js +3 -0
  36. package/server/{codex-CbmztVcc.js → codex-TmSi-yTv.js} +27 -8
  37. package/server/{codex-parser-jl8AeAmB.js → codex-parser-C4gSH-IR.js} +2 -2
  38. package/server/{config-q4Gvd8dq.js → config-CCvjQf27.js} +2 -2
  39. package/server/{config-BJKocXKd.js → config-DUIhMN_T.js} +1 -1
  40. package/server/{config-DeTsoZdR.js → config-DjLOdbgT.js} +2 -2
  41. package/server/{config-yaml-ig8Nwtiw.js → config-yaml-DvyMuOle.js} +55 -186
  42. package/server/{conflict-gate-CHU9K1vU.js → conflict-gate-BSJkNTdp.js} +1 -1
  43. package/server/{conflict-gate-CFqPVxEg.js → conflict-gate-CmrYpa47.js} +3 -3
  44. package/server/{context-layers-DlQKkHH2.js → context-layers-B3Nt58jl.js} +2 -2
  45. package/server/{context-layers-15gDOk20.js → context-layers-ZYFcWiyc.js} +3 -3
  46. package/server/{control-settings-D_odMIaC.js → control-settings-aP1ANIlI.js} +4 -4
  47. package/server/{conversation-compaction-B6YSRLda.js → conversation-compaction-CNbTLB86.js} +8 -8
  48. package/server/{conversation-compaction-CN4-5YYt.js → conversation-compaction-DiG5zWQq.js} +1 -1
  49. package/server/{conversation-service-C3avRVEr.js → conversation-service-Du-MTNpJ.js} +6 -6
  50. package/server/{conversation-service-Dq33SYEj.js → conversation-service-Up7FEzIC.js} +1 -1
  51. package/server/{conversations-H9if0bCQ.js → conversations-6mPANqvL.js} +1 -1
  52. package/server/{conversations-bYpM9-kZ.js → conversations-DbOs1e9Q.js} +4 -4
  53. package/server/{cost-wH46-WsJ.js → cost-CW4WSe72.js} +3 -3
  54. package/server/{cost-Codk1pc2.js → cost-Ca0YTWDw.js} +18 -2
  55. package/server/{cost-sync-D_cre6WM.js → cost-sync-C0VdGme1.js} +3 -3
  56. package/server/{dag-CJpgf9A3.js → dag-CdOjJVDT.js} +9 -9
  57. package/server/{dangerous-git-ops-D6AF-Hg_.js → dangerous-git-ops-CT-IypG3.js} +1 -1
  58. package/server/dashboard-db-worker.js +7 -7
  59. package/server/{deacon-B8HbQdqU.js → deacon-DYSEJb48.js} +3 -3
  60. package/server/{deacon-nudge-log-D6K9K-rE.js → deacon-nudge-log-Bjg8U4Y9.js} +3 -3
  61. package/server/{deacon-CkT_kznS.js → deacon-pRnyD5w9.js} +266 -577
  62. package/server/deacon-swarm-9jRLS5Ke.js +2 -0
  63. package/server/{deacon-swarm-BryRr6AO.js → deacon-swarm-DftYRDo8.js} +17 -17
  64. package/server/deacon.js +8 -8
  65. package/server/{deploy-patrol-1IrZxicY.js → deploy-patrol-Bjsho_ha.js} +136 -19
  66. package/server/{deploy-window-7ZYHh7Zp.js → deploy-window-CM6W1-c6.js} +1 -1
  67. package/server/{deploy-window-wDf4UgHt.js → deploy-window-DeP_OIRk.js} +77 -10
  68. package/server/{dev-supervisor-C7p9kEpc.js → dev-supervisor-BpMoHlkR.js} +2 -2
  69. package/server/{devcontainer-renderer-CNmQy0pL.js → devcontainer-renderer-CtUgrVKW.js} +3 -3
  70. package/server/dist-Bd3vn0Hw.js +3 -0
  71. package/server/{dist-D-Ed5yVw.js → dist-DyRx4cI7.js} +1 -1
  72. package/server/{docker-BCZ89M9X.js → docker-BK7HIcBj.js} +2 -2
  73. package/server/{dod-DbJLYcHv.js → dod-BrSfUHm0.js} +1 -1
  74. package/server/{ensure-devcontainer-Cs6W9Yzj.js → ensure-devcontainer-DRqaAkBR.js} +1 -1
  75. package/server/{ensure-devcontainer-V5JWaAva.js → ensure-devcontainer-DseivYEy.js} +4 -4
  76. package/server/{esm-shims-dTeNdq7X.js → esm-shims-CbI3BVkl.js} +1 -1
  77. package/server/{event-store-CpBGsO6_.js → event-store-Cr5PQwFC.js} +1 -1
  78. package/server/{event-store-TnWdydfB.js → event-store-tdiY5eDZ.js} +3 -3
  79. package/server/{events-DSUdR-04.js → events-CC1dgUpx.js} +3 -3
  80. package/server/{events-Dsuv6qyB.js → events-CvvGK6LT.js} +1 -1
  81. package/server/{factory-BMrK4TrE.js → factory-CynerjXO.js} +50 -13
  82. package/server/{feature-registry-population-B-CI9hgE.js → feature-registry-population-B0pmAz0a.js} +4 -4
  83. package/server/{feature-registry-storage-B972ph_A.js → feature-registry-storage-_wUBRD3J.js} +2 -2
  84. package/server/{features-Bc-Bmiye.js → features-Dhxz-wLc.js} +2 -2
  85. package/server/{feedback-target-DZ-iAnAa.js → feedback-target-CPS15Vte.js} +7 -7
  86. package/server/{feedback-target-DS6NUuSs.js → feedback-target-iygZwmMc.js} +1 -1
  87. package/server/{feedback-writer-BXP6g75N.js → feedback-writer-C9b6ccN1.js} +6 -5
  88. package/server/{feedback-writer-Bx5z11mF.js → feedback-writer-qmiMbqTZ.js} +1 -1
  89. package/server/{flywheel-Ctr5uuvo.js → flywheel-DMCUzDWg.js} +1 -1
  90. package/server/{flywheel-COR0mbRI.js → flywheel-DSSpWmqF.js} +13 -13
  91. package/server/{flywheel-6WHU4O7A.js → flywheel-DcBkQvgE.js} +14 -14
  92. package/server/{flywheel-merge-order-CNKAY489.js → flywheel-merge-order-C-6zRLvM.js} +1 -1
  93. package/server/{flywheel-merge-order-CTgHeg-W.js → flywheel-merge-order-DxbQKE1d.js} +8 -8
  94. package/server/forge-B-ZWyTRm.js +2 -0
  95. package/server/{forge-B1S_KZv4.js → forge-Ch9gCFod.js} +2 -2
  96. package/server/{from-DpwQ-sc3.js → from-CJ_aH5jD.js} +1 -1
  97. package/server/{fts-db-DmAcuCkV.js → fts-db-CKgg0VKg.js} +2 -2
  98. package/server/{fts-operations-7d_RkmWp.js → fts-operations-BrL_VTRr.js} +2 -2
  99. package/server/{git-utils-Cc3FHDKd.js → git-utils-BVa07a4a.js} +2 -2
  100. package/server/{git-utils-CsKGnzFA.js → git-utils-Dry_Ka_D.js} +1 -1
  101. package/server/{github-app-CDPtGF7J.js → github-app-CMBdIFBQ.js} +11 -3
  102. package/server/{github-app-CU14oYzP.js → github-app-CPfoFAdV.js} +1 -1
  103. package/server/{github-client-XjTJbBm7.js → github-client--XVlDpwM.js} +2 -2
  104. package/server/{github-client-CwBZZ3t7.js → github-client-B4QsdE-X.js} +1 -1
  105. package/server/{github-pr-lookup-CFGeVhqv.js → github-pr-lookup-BRbDW-qk.js} +2 -2
  106. package/server/{harness-binary-B2CTcD84.js → harness-binary-CVio2m-u.js} +1 -1
  107. package/server/{harness-resolve-D5FVQTmy.js → harness-resolve-qHJBhy3Z.js} +4 -4
  108. package/server/{health-events-DREeevle.js → health-events-C9B8y1Hm.js} +2 -2
  109. package/server/{health-events-C1whmd58.js → health-events-CpfvuVmm.js} +1 -1
  110. package/server/{hooks-yxRsjk-z.js → hooks-DUXw8A0-.js} +2 -2
  111. package/server/{hooks-B-HItBiS.js → hooks-ltecuFqZ.js} +1 -1
  112. package/server/{hume-Dz_OymXE.js → hume-BEq0bUDg.js} +2 -2
  113. package/server/hume-B_DbflNM.js +3 -0
  114. package/server/{idle-stack-reaper-DrCv0OAG.js → idle-stack-reaper-D7w9t3fE.js} +1 -1
  115. package/server/{idle-stack-reaper-Yf34xXxY.js → idle-stack-reaper-w1ISSlhs.js} +2 -2
  116. package/server/{in-flight-guard-BoWm66Kh.js → in-flight-guard-aQ1IxeI3.js} +2 -2
  117. package/server/{infra-D4iNWMA5.js → infra-CzaSOgul.js} +4 -4
  118. package/server/{injection-D7T75Pye.js → injection-DZ0PfYa4.js} +7 -7
  119. package/server/{injection-BVNa4MQW.js → injection-oNZeoDhL.js} +1 -1
  120. package/server/{inspect-agent-BXCgNeZ4.js → inspect-agent-DJKLWcVT.js} +12 -12
  121. package/server/inspect-agent-ch-F-5Ci.js +2 -0
  122. package/server/{internal-token-CXsfxslp.js → internal-token-Bb4XeV2x.js} +2 -2
  123. package/server/{internal-token-C9DdEOKY.js → internal-token-DXdfprGr.js} +1 -1
  124. package/server/{io-DQR9PMgS.js → io-B3_AHDfr.js} +160 -184
  125. package/server/{issue-closed-DtmJM0D0.js → issue-closed-zhdvQicO.js} +7 -7
  126. package/server/{issue-lifecycle-CeyW_HoD.js → issue-lifecycle-CreaCkjW.js} +22 -22
  127. package/server/{issue-lifecycle-8PSS9Anq.js → issue-lifecycle-Dy4vd0Oa.js} +1 -1
  128. package/server/{issue-service-singleton-D_RVYBuL.js → issue-service-singleton-B5ushCvE.js} +8 -8
  129. package/server/{issue-service-singleton-DBZabEl7.js → issue-service-singleton-DabvBWUp.js} +1 -1
  130. package/server/{issues-pDW9VUNz.js → issues-B6ToV6x1.js} +2 -2
  131. package/server/{jsonl-parser-C3HVNR5d.js → jsonl-parser-Dhflo1SH.js} +3 -3
  132. package/server/{label-cleanup-DPwiZlWo.js → label-cleanup-BKPJm4Hv.js} +3 -3
  133. package/server/{label-reconciler-Df1ZduPH.js → label-reconciler-DdWbHEBu.js} +4 -4
  134. package/server/{launcher-generator-COgR2By1.js → launcher-generator-CHVm7bGT.js} +10 -9
  135. package/server/{layers-Cp1To4L8.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-taIb0PoH.js → lifecycle-io-D8iNBcux.js} +37 -37
  139. package/server/{lifecycle-CtPDcZ9u.js → lifecycle-sycO16hj.js} +6 -6
  140. package/server/{linear-client-DsFkIxee.js → linear-client-D4zqMnX7.js} +2 -2
  141. package/server/{linear-client-YwZMDIwQ.js → linear-client-DqhDQO9k.js} +1 -1
  142. package/server/memory-fts-worker.js +1 -1
  143. package/server/{merge-C1t-bspg.js → merge-C_ZEhbqI.js} +3 -3
  144. package/server/{merge-BwsyNRJV.js → merge-DK23JEdS.js} +1 -1
  145. package/server/{merge-agent-B-SnXOoc.js → merge-agent-BQM3a8z5.js} +1 -1
  146. package/server/{merge-agent-DDiIjzk-.js → merge-agent-XrB80vfT.js} +28 -28
  147. package/server/{merge-batch-Byt-QnEl.js → merge-batch-Bwoyr8Je.js} +1 -1
  148. package/server/{merge-blockers-BYjeXrVN.js → merge-blockers-BsFjGrQ8.js} +2 -2
  149. package/server/merge-ops-DlB1IM0Y.js +2 -0
  150. package/server/{merge-rebase-Cm6fXaZN.js → merge-rebase-C1KIVr0s.js} +2 -2
  151. package/server/{merge-set-DiISXcC-.js → merge-set-DLz0MkGT.js} +3 -3
  152. package/server/{merge-set-6LEglm6o.js → merge-set-DnSYdBEp.js} +1 -1
  153. package/server/{merge-sync-Do8_q32h.js → merge-sync-DZ9dojJn.js} +2 -2
  154. package/server/{merge-sync-B95_4in_.js → merge-sync-SSv3E-pl.js} +1 -1
  155. package/server/{merge-train-CKana8EH.js → merge-train-DxDfBTjr.js} +3 -3
  156. package/server/{merge-train-deps-BgmqwIfA.js → merge-train-deps-CyYQUksx.js} +4 -4
  157. package/server/{merge-verification-CqnUzGEK.js → merge-verification-CSizH3HY.js} +4 -4
  158. package/server/{multipart-parser-tdOQDJ3o.js → multipart-parser-Dt8YPN5S.js} +2 -2
  159. package/server/{no-resume-mode-BWOSZjWd.js → no-resume-mode-Cx3K0hHi.js} +11 -8
  160. package/server/node_modules/.package-lock.json +1 -1
  161. package/server/{orphan-proposed-reconciler-DSvsJ5M7.js → orphan-proposed-reconciler-BTkDrl4R.js} +1 -1
  162. package/server/{orphan-proposed-reconciler-xklgvNA7.js → orphan-proposed-reconciler-neK8dHQk.js} +15 -13
  163. package/server/package-lock.json +2 -2
  164. package/server/package.json +1 -1
  165. package/server/{pan-dir-DOcf6ug3.js → pan-dir-DeVUgwA7.js} +78 -58
  166. package/server/{paths-DooHpt9p.js → paths-_zEts6wc.js} +2 -2
  167. package/server/{pickup-CaskQ7j6.js → pickup-Dd0Znxxy.js} +1 -1
  168. package/server/{pipeline-membership-1LGRjo-k.js → pipeline-membership-0HaEGDlH.js} +186 -67
  169. package/server/{pipeline-notifier-CZsrU_nj.js → pipeline-notifier-6iCJplFZ.js} +1 -1
  170. package/server/{pipeline-notifier-B6FVsYF9.js → pipeline-notifier-D0ykk59O.js} +2 -2
  171. package/server/{project-pipelines-CtNG_rvs.js → project-pipelines-2sK1apsO.js} +2 -2
  172. package/server/projects-9SkRpES9.js +3 -0
  173. package/server/{prompts-EvhMeeHG.js → prompts-Dp4Tpk39.js} +2 -2
  174. package/server/{providers-DNSQqy2V.js → providers-DKkBXhxU.js} +1 -1
  175. package/server/{providers-BDDPULlp.js → providers-DV7ec8l7.js} +7 -7
  176. package/server/public/assets/{chunk-BO2N2NFS-sym_ufXe.js → chunk-BO2N2NFS-CltymLRg.js} +4 -4
  177. package/server/public/assets/{diagram-OG6HWLK6-CQJPBNBu.js → diagram-OG6HWLK6-D2f6pjgA.js} +1 -1
  178. package/server/public/assets/{dist-Bio7THQU.js → dist-BWR4qFiV.js} +1 -1
  179. package/server/public/assets/{dist-DukGS2YZ.js → dist-DEmlBBNQ.js} +3 -3
  180. package/server/public/assets/{ganttDiagram-6RSMTGT7-D4lWwte3.js → ganttDiagram-6RSMTGT7-DnfiViPK.js} +1 -1
  181. package/server/public/assets/{highlighted-body-OFNGDK62-CaLboCt5.js → highlighted-body-OFNGDK62-B8Wrmj9H.js} +1 -1
  182. package/server/public/assets/index-CUr1xv8w.css +1 -0
  183. package/server/public/assets/{index-Bwejq-5s.js → index-CsSuZQBI.js} +145 -144
  184. package/server/public/assets/{linear-qUWmMZ-c.js → linear-C9zFQpkX.js} +1 -1
  185. package/server/public/assets/mermaid-GHXKKRXX-BUAB8hqt.js +1 -0
  186. package/server/public/assets/{pieDiagram-4H26LBE5-C4zYulEm.js → pieDiagram-4H26LBE5-lR8H7Yjd.js} +1 -1
  187. package/server/public/assets/{prod-C8VtLuWC.js → prod-B1jCQihw.js} +4 -4
  188. package/server/public/assets/{quadrantDiagram-W4KKPZXB-qP04zyZC.js → quadrantDiagram-W4KKPZXB-CVQ2guem.js} +1 -1
  189. package/server/public/assets/{sankeyDiagram-5OEKKPKP-eMPTX_cG.js → sankeyDiagram-5OEKKPKP-eD1RB4gm.js} +1 -1
  190. package/server/public/assets/{xychartDiagram-2RQKCTM6-Dme1PIt6.js → xychartDiagram-2RQKCTM6-ChEC6dQn.js} +1 -1
  191. package/server/public/index.html +2 -2
  192. package/server/{pull-requests-By_BteaL.js → pull-requests--Ib2jTgy.js} +1 -1
  193. package/server/{pull-requests-8z2N1UOV.js → pull-requests-CXIhdCYD.js} +13 -11
  194. package/server/{queries-ZABd5aXP.js → queries-6d7Cdtm7.js} +693 -104
  195. package/server/{rally-i_goYmiA.js → rally-B708-nZn.js} +3 -3
  196. package/server/{rally-api-DqKqIMNR.js → rally-api-nY0ZANw3.js} +2 -2
  197. package/server/{rally-api-xHazRk0d.js → rally-api-yjQ0TfHd.js} +1 -1
  198. package/server/{rally-client-COYz1vYR.js → rally-client-B1EJhfV0.js} +4 -4
  199. package/server/{rally-client-CGWEHaPd.js → rally-client-CULK2XAY.js} +1 -1
  200. package/server/rally-njs_mJrt.js +3 -0
  201. package/server/{reap-terminal-sessions-CaMkFOIH.js → reap-terminal-sessions-MWnqdLCJ.js} +1 -1
  202. package/server/{reap-terminal-sessions-DG9eiMVz.js → reap-terminal-sessions-N3BTkmX_.js} +1 -1
  203. package/server/{rebuild-stack-JUm0jqYP.js → rebuild-stack-Dp4eLkt4.js} +6 -6
  204. package/server/{rebuild-stack-CKjJAI8L.js → rebuild-stack-kA7XngID.js} +1 -1
  205. package/server/{reconstruct-cache-wU79aCee.js → reconstruct-cache-uWbZfjms.js} +6 -6
  206. package/server/record-t6V-3Dcj.js +3 -0
  207. package/server/{record-update-D3N6WMFR.js → record-update-DACtKh6_.js} +1 -1
  208. package/server/record-update-Dq0t2uBG.js +310 -0
  209. package/server/{recovery-trip-DkzJSej9.js → recovery-trip-BJtIQuag.js} +2 -2
  210. package/server/{release-engine-DMINVN8S.js → release-engine-DZpmGGzb.js} +5 -5
  211. package/server/{release-set-DeUSOEHy.js → release-set-hnXd_kga.js} +3 -3
  212. package/server/{remote-Dr5kGYSZ.js → remote-4tiENDaI.js} +3 -3
  213. package/server/{remote-b-c5bOce.js → remote-Br-ZWVIP.js} +3 -3
  214. package/server/{remote-agents-D6O_zETW.js → remote-agents-CRCg1L4H.js} +1 -1
  215. package/server/{remote-agents-Ct_WOyke.js → remote-agents-nmty1mLu.js} +6 -6
  216. package/server/{remote-completion-Dca3hAaa.js → remote-completion-BbWNd10K.js} +12 -12
  217. package/server/resume-CcKqnTvE.js +3 -0
  218. package/server/{review-agent-CCum8sGe.js → review-agent-DJRO8EG8.js} +1 -1
  219. package/server/{review-agent-CThvgK2r.js → review-agent-sKkE1FEL.js} +22 -22
  220. package/server/{review-artifacts-CXywD0F2.js → review-artifacts-BLbSC4ke.js} +5 -5
  221. package/server/{review-context-OYfKUprb.js → review-context-BgX3lcCx.js} +8 -8
  222. package/server/{review-status-DFRjDFef.js → review-status-A7quS5KJ.js} +54 -21
  223. package/server/review-status-C6n6-9f_.js +3 -0
  224. package/server/{review-status-enrichment-crNAtIpL.js → review-status-enrichment-tbOn_A_u.js} +3 -3
  225. package/server/{review-status-sync-DpAMD_WO.js → review-status-sync-BhSQ0d0l.js} +2 -2
  226. package/server/{review-status-sync-D60PJWNL.js → review-status-sync-To3-iS-N.js} +1 -1
  227. package/server/{review-verdict-feedback-JImjut0z.js → review-verdict-feedback-C1Kg8n7t.js} +1 -1
  228. package/server/{review-verdict-feedback-CpUZl5aE.js → review-verdict-feedback-CTRNtzXO.js} +6 -6
  229. package/server/{rollup-CZ02qgxk.js → rollup-B53Y81xK.js} +1 -1
  230. package/server/{rollup-SyuF09e4.js → rollup-WA0VD-Rr.js} +8 -8
  231. package/server/{scanner-Br0Z5S6R.js → scanner-D2743cp8.js} +11 -7
  232. package/server/{sequence-io-fxU0DlwW.js → sequence-io-Cg0zYj_E.js} +4 -4
  233. package/server/{sequencer-agent-B5YC5XVP.js → sequencer-agent-BGY8gjg-.js} +5 -5
  234. package/server/server.js +941 -752
  235. package/server/{service-Bagb90KZ.js → service-DCpB_SGd.js} +53 -53
  236. package/server/{session-fork-BqQxd-V6.js → session-fork-BQ8_6H32.js} +2 -2
  237. package/server/{session-history-XdS0JKp3.js → session-history-CVZDpS3c.js} +4 -4
  238. package/server/{settings-BNbocWOg.js → settings-BZ5m1UCl.js} +3 -3
  239. package/server/settings-D0OSwos5.js +2 -0
  240. package/server/{settings-uLc6DEYI.js → settings-ylxwqwQG.js} +2 -2
  241. package/server/{shadow-engineering-D4X_s3fA.js → shadow-engineering-BlxG6Xye.js} +2 -2
  242. package/server/{shadow-state-CbvsN3qG.js → shadow-state-C2_epgx2.js} +1 -1
  243. package/server/{shadow-state-C_NkP-sa.js → shadow-state-Dh-HzF2J.js} +2 -2
  244. package/server/{shadow-utils-CYMRPeRT.js → shadow-utils-4bvjn9b3.js} +2 -2
  245. package/server/{ship-log-__QtAFXG.js → ship-log-ClSMIzZX.js} +1 -1
  246. package/server/{smart-compaction-jdMkG1vo.js → smart-compaction-CHIxLr_d.js} +1 -1
  247. package/server/{smart-compaction-CLZOWin1.js → smart-compaction-r4pHQBIr.js} +7 -7
  248. package/server/{spawn-planning-session-D5OXo8pT.js → spawn-planning-session-DWAorh2B.js} +22 -21
  249. package/server/{spawn-planning-session-8D6mE033.js → spawn-planning-session-KC_UduxD.js} +1 -1
  250. package/server/{specialist-completion-CqmduO92.js → specialist-completion-BXhav38U.js} +1 -1
  251. package/server/{specialist-context-CJ-QjFR-.js → specialist-context-DtrYvGJ-.js} +5 -5
  252. package/server/{specialist-handoff-logger-Dnjlwt7g.js → specialist-handoff-logger-C45ouoZ6.js} +2 -2
  253. package/server/{specialist-logs-CQnKzuZs.js → specialist-logs-DJ3RzKxW.js} +3 -3
  254. package/server/{specialists-D0gGXMZx.js → specialists-D5fRZXmN.js} +1 -1
  255. package/server/specialists-DVj0hvaL.js +3 -0
  256. package/server/{specialists-CwZHb5cb.js → specialists-DyFeedjn.js} +66 -76
  257. package/server/{specialists-Bg9v4z3F.js → specialists-JVO00bs7.js} +340 -214
  258. package/server/specs-nN45DG2X.js +3 -0
  259. package/server/{src-BMMoA_ba.js → src-CG9mCkP6.js} +6 -6
  260. package/server/{src-Bqdtd6po.js → src-CMTQGyCK.js} +3 -3
  261. package/server/{src-k039WVYY.js → src-U7_kTPEE.js} +2 -1
  262. package/server/{stack-health-Bd06frFn.js → stack-health-Df0YEZKa.js} +1 -1
  263. package/server/{stack-health-C-ifC7b0.js → stack-health-puygdaMd.js} +2 -2
  264. package/server/{stale-task-claims-L7pJkQFL.js → stale-task-claims-BbFwCTb0.js} +4 -4
  265. package/server/{staleness-BID1BKdr.js → staleness-Bpy41ngS.js} +15 -3
  266. package/server/{staleness-_Tr-GwdA.js → staleness-Cbl_w4Bw.js} +1 -1
  267. package/server/{state-home-CONQvZR0.js → state-home-CIGjwNfJ.js} +96 -44
  268. package/server/{state-migrate-BeBW0KXA.js → state-migrate-Dkzaxvny.js} +12 -3
  269. package/server/{stuck-remediation-CKnIryGT.js → stuck-remediation-CzEov_fq.js} +26 -22
  270. package/server/{stuck-remediation-CsGD5Ksb.js → stuck-remediation-sY_MHHgQ.js} +1 -1
  271. package/server/{substrate-bug-weights-service-CpIZILj9.js → substrate-bug-weights-service-BH66lhm7.js} +3 -3
  272. package/server/{summary-fork-agEMsPSo.js → summary-fork-D8bXjCr7.js} +2 -2
  273. package/server/{summary-fork-bX6ax6X7.js → summary-fork-DHhJIsAL.js} +8 -8
  274. package/server/{supervisor-Ctt4eRYz.js → supervisor-BO-Zk_h-.js} +3 -3
  275. package/server/supervisor-BPy-o1A8.js +2 -0
  276. package/server/{swarm-readiness-DdmJVX7y.js → swarm-readiness-CQ_fwUWF.js} +4 -4
  277. package/server/{system-prerequisites-DSXBvffY.js → system-prerequisites-Bza0ffAh.js} +2 -2
  278. package/server/{teardown-workspace-DDCf5n-a.js → teardown-workspace-CEgauF4U.js} +15 -15
  279. package/server/{test-agent-queue-BJZ9Nfcc.js → test-agent-queue-DXDt0Xa-.js} +7 -7
  280. package/server/{test-verdict-Cp5tljlJ.js → test-verdict-CmUBK5cT.js} +1 -1
  281. package/server/{test-verdict-D_-sXIz_.js → test-verdict-DFjjIHR5.js} +1 -1
  282. package/server/{tldr-daemon-BQFmmFp0.js → tldr-daemon-BDtLOIlO.js} +2 -2
  283. package/server/{tldr-daemon-B8_oT5gx.js → tldr-daemon-DL566HbH.js} +1 -1
  284. package/server/tmux-DoThH6aj.js +3 -0
  285. package/server/{tmux-L5LgvGLp.js → tmux-ftABRAmc.js} +76 -44
  286. package/server/{token-BkQLy4yS.js → token-CsOhvw42.js} +2 -2
  287. package/server/{token-util-DI8sGlmF.js → token-util-CTmczIfW.js} +1 -1
  288. package/server/token-util-DrHg8abn.js +3 -0
  289. package/server/{tracker-config-DdT-nUAM.js → tracker-config-B4itFzDo.js} +2 -2
  290. package/server/{tracker-utils-DV3h1FYG.js → tracker-utils-BePq_oj-.js} +1 -1
  291. package/server/{tracker-utils-CawsPSS2.js → tracker-utils-tnxxqROg.js} +2 -2
  292. package/server/{traefik-connect-C6mJckNs.js → traefik-connect-m73vGebA.js} +1 -1
  293. package/server/{tunnel-IdK1iTHx.js → tunnel-B2vxjx_b.js} +3 -3
  294. package/server/{tunnel-BIFl98rc.js → tunnel-Cgj-IGIl.js} +1 -1
  295. package/server/{types-7-GnJn0t.js → types-BBNjPcqU.js} +1 -1
  296. package/server/{uat-train-j0cPeMSj.js → uat-train-CuEn0t9M.js} +28 -28
  297. package/server/{uat-train-0Ujk8GCv.js → uat-train-cKfM-_WW.js} +1 -1
  298. package/server/{validation-CabEISJT.js → validation-B5JxoPUS.js} +259 -9
  299. package/server/{validation-DcAgXTQp.js → validation-CIi6pnI2.js} +1 -1
  300. package/server/{verification-artifact-BuTA1QbL.js → verification-artifact-BcnIbigL.js} +1 -1
  301. package/server/{verification-artifact-Ck1tefmz.js → verification-artifact-C-lIHfUa.js} +1 -1
  302. package/server/{verification-runner-FiuAZ-H2.js → verification-runner-Br0S_Ous.js} +102 -37
  303. package/server/{verification-runner-DlJezzef.js → verification-runner-CDj4lD4t.js} +1 -1
  304. package/server/{vtt-parser-BnRsYzcz.js → vtt-parser-DKpNNW5i.js} +1 -1
  305. package/server/{work-agent-prompt-DLthEPAq.js → work-agent-prompt-Yb2bd3Fq.js} +13 -13
  306. package/server/{workflows-BZNNYkGC.js → workflows-C9WmILql.js} +39 -77
  307. package/server/workflows-D90rMOya.js +2 -0
  308. package/server/{workspace-D9ppycdg.js → workspace-BVl4rihN.js} +3 -3
  309. package/server/{workspace-3IC-UkAi.js → workspace-DuUdndHe.js} +1 -1
  310. package/server/{workspace-config-Bigl_-Lk.js → workspace-config-cEGcO6UT.js} +1 -1
  311. package/server/{workspace-manager-B1WOfKvB.js → workspace-manager-ZTdJAy9M.js} +1 -1
  312. package/server/{workspace-manager-ClkCIWTe.js → workspace-manager-hLUv3ADC.js} +22 -15
  313. package/server/{workspace-metadata-tiSRIWJP.js → workspace-metadata-CskwzzhL.js} +2 -2
  314. package/server/{workspace-metadata-BE0efUv_.js → workspace-metadata-DNpMixRq.js} +1 -1
  315. package/server/{workspaces-CFPcL0vl.js → workspaces-hWvy9eKs.js} +275 -109
  316. package/sync-sources/agents/pan-inspect-agent.md +1 -1
  317. package/sync-sources/agents/pan-merge-agent.md +1 -1
  318. package/sync-sources/agents/pan-planning-agent.md +4 -4
  319. package/sync-sources/agents/pan-work-agent.md +1 -1
  320. package/sync-sources/dev-skills/pan-commit/SKILL.md +1 -1
  321. package/sync-sources/dev-skills/test-specialist-workflow/SKILL.md +1 -1
  322. package/sync-sources/hooks/record-cost-event.js +363 -71
  323. package/sync-sources/hooks/session-start-hook +7 -0
  324. package/sync-sources/hooks/work-agent-stop-hook +1 -1
  325. package/sync-sources/rules/per-bead-durability.md +1 -1
  326. package/sync-sources/rules/prd-authoring.md +1 -1
  327. package/sync-sources/skills/feature-work/SKILL.md +1 -1
  328. package/sync-sources/skills/pan/SKILL.md +2 -2
  329. package/sync-sources/skills/pan-admin-config/SKILL.md +1 -0
  330. package/sync-sources/skills/pan-approve/SKILL.md +1 -1
  331. package/sync-sources/skills/pan-close/SKILL.md +1 -1
  332. package/sync-sources/skills/pan-doctor/SKILL.md +1 -1
  333. package/sync-sources/skills/pan-new-project/SKILL.md +9 -11
  334. package/sync-sources/skills/pan-oversee/SKILL.md +5 -5
  335. package/sync-sources/skills/pan-plan/SKILL.md +6 -6
  336. package/sync-sources/skills/pan-quickstart/SKILL.md +1 -1
  337. package/sync-sources/skills/pan-recap/SKILL.md +2 -2
  338. package/sync-sources/skills/pan-review/SKILL.md +1 -1
  339. package/sync-sources/skills/pan-start/SKILL.md +3 -3
  340. package/sync-sources/skills/pan-swarm/SKILL.md +1 -1
  341. package/sync-sources/skills/pan-sync/SKILL.md +1 -1
  342. package/sync-sources/skills/pan-task/SKILL.md +2 -2
  343. package/sync-sources/skills/pan-wipe/SKILL.md +2 -2
  344. package/sync-sources/skills/pipeline-list/SKILL.md +1 -1
  345. package/sync-sources/skills/pipeline-status/SKILL.md +2 -2
  346. package/sync-sources/skills/plan/SKILL.md +11 -11
  347. package/sync-sources/skills/write-vbrief/SKILL.md +7 -282
  348. package/sync-sources/skills/write-xbrief/SKILL.md +295 -0
  349. package/sync-sources/templates/claude-md/sections/warnings.md +1 -1
  350. package/server/agent-state-Co5Sy2Fw.js +0 -3
  351. package/server/agents-DyHKlq1I.js +0 -3
  352. package/server/cli-BRORS9qY.js +0 -3
  353. package/server/codex-DNyiQDKW.js +0 -3
  354. package/server/deacon-swarm-CV54eNmU.js +0 -2
  355. package/server/dist-j64RzSrQ.js +0 -3
  356. package/server/forge-B0_opi-V.js +0 -2
  357. package/server/hume-BmhvfVbV.js +0 -3
  358. package/server/inspect-agent-Dq0z1k3H.js +0 -2
  359. package/server/lifecycle-io-DmY2qwCn.js +0 -3
  360. package/server/merge-ops-DwWCkSgo.js +0 -2
  361. package/server/projects-BKkwpH6q.js +0 -3
  362. package/server/public/assets/index-Bdc4V9ba.css +0 -1
  363. package/server/public/assets/mermaid-GHXKKRXX-B5v_r7cI.js +0 -1
  364. package/server/rally-OSJXdiHK.js +0 -3
  365. package/server/record-rwK-nKv_.js +0 -3
  366. package/server/record-update-Crz74r-6.js +0 -168
  367. package/server/resume-wZZsWtzz.js +0 -3
  368. package/server/review-status-Bnh-rdkY.js +0 -3
  369. package/server/settings-BlUsVaUc.js +0 -2
  370. package/server/specialists-Dqe6_HE5.js +0 -3
  371. package/server/specs-BhOKBzqk.js +0 -3
  372. package/server/supervisor-COVHrBTg.js +0 -2
  373. package/server/tmux-BAvtac_u.js +0 -3
  374. package/server/token-util-BArZLN6w.js +0 -3
  375. package/server/workflows-C4mR0Reb.js +0 -2
package/server/server.js CHANGED
@@ -1,110 +1,110 @@
1
1
  import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM, r as __exportAll, t as __commonJSMin } from "./rolldown-runtime-DNCzzKnI.js";
2
- import { $r as getDocsIndexPath, A as canUseHarnessSync, Br as LOGS_DIR, Cr as GitHubApiError, D as resolveTieredExecutionEnabled, Dn as extractTeamPrefix, Dr as ProcessSpawnError, E as resolveTieredExecutionBlock, Gn as listProjects, H as init_providers, Hn as init_projects, I as UnknownModelError, In as getProjectSync, J as defaultBackgroundAiFeatures, Jr as SYNC_SOURCES, Kn as listProjectsSync, Lr as CLAUDE_DIR, M as init_harness_policy, Mr as AGENTS_DIR, Nn as getIssuePrefix, Nt as init_record, Q as computeModelOrigin, Qn as renameProject, Qr as getDocsDisableStatePath, R as getBuiltInDefaultHarness, Rt as readIssueRecordSync, T as init_tier_table, Tn as ProjectRenameError, V as getProviderForModelSync, Vr as OVERDECK_HOME, X as DEFAULT_ROLES, Xr as encodeClaudeProjectDir, Y as init_registry, Z as DEFAULT_WORKHORSES, Zn as registerProjectSync, Zr as getDocsBudgetStatePath, _ as getDefaultDocsConfig, _r as require_dist$1, ai as isDevMode, at as getModelEffortLevelsSync, ci as sessionFilePath, cn as init_auto_commit, ct as modelSupportsImagesSync, d as loadConfigNoMigration, dr as extractPrefixSync, ei as getDocsTelemetryPath, er as resolveInfraRepo, f as loadConfigSync, fr as init_issue_id, g as mergeConfigs, h as jsYaml, ht as ROLE_EFFORTS, i as getConversationsConfig, ii as init_paths, jn as findProjectByTeamSync, jr as init_errors, jt as getIssueWorkspacePath, k as validateTieredExecutionConfig, kn as findProjectByPathSync, kr as TrackerError, lt as resolveModelIdSync, m as init_js_yaml, mr as parseIssueIdSync, mt as PARENT_MODEL_REF, n as clearConfigCache, ni as getLegacyHome, nr as resolveProjectFromIssueSync, nt as MODEL_CAPABILITIES, o as getGlobalConfigPath, oi as packageRoot, on as flushAllPendingAutoCommits, or as setProjectAutoMergeDefaultSync, ot as hasModelCapabilitySync, p as updateConversationsConfig, pt as COMPLIANCE_MODES, r as getConversationSearchConfigSync, ri as getOverdeckHome, rt as MODEL_DEPRECATIONS, s as init_load, sn as flushAutoCommits, sr as setProjectSwarmPolicySync, st as init_model_capabilities, t as init_config_yaml, tr as resolveProjectFromIssue, tt as resolveModel, u as isTldrEnabledSync, v as getDefaultTtsDaemonConfig, w as TieredExecutionConfigError, xr as FsError, y as mergeTtsDaemonConfigs, z as getKimiAnthropicBaseUrl } from "./config-yaml-ig8Nwtiw.js";
3
- import { a as shouldRefuseHostDashboardPort, i as readHostDashboardApiPort, n as getDashboardIdentity, r as isNonPrimaryCheckoutRoot } from "./deacon-nudge-log-D6K9K-rE.js";
4
- import { $ as runInBatches, A as handleConversationDelete, B as stopConversationRuntime, C as isPiControlChannelHarness, D as conversationNeedsRunningRepair, E as validateConversationControlAckOrigin, F as isInsideGitWorkTree, G as cleanupOrphanedConversationAttachments, H as waitForPiTuiReady, I as resolveAllowedHarness, J as extractConversationAttachmentPaths, K as cleanupUnreferencedConversationAttachments, L as shouldReportUnresolvedLiveSession, M as handleConversationResume, N as handleConversationStop, O as conversationSessionAliveFromState, P as handleConversationSwitchModel, Q as removeConversationAttachment, R as spawnConversationSession, S as handleConversationThinkingLevel, T as resolveConversationDeliveryMethod, U as waitForTmuxSession$1, V as tmuxSessionExists, W as cleanupConversationAttachments, X as hasConversationAttachment, Y as getConversationAttachmentsRoot, Z as isManagedConversationAttachmentPath, _ as handleConversationCodexApproval, _t as validateOrigin$1, a as agentsRouteLayer, at as panCliInvocation, b as handleConversationDeliveryMethod, bt as getDefaultCwd, c as hasDashboardInternalToken, ct as resolveAgentHarness, d as rejectUnsafeDashboardMutationRequest, dt as resolveJsonlPath, et as evaluateSpawnGuardrails, f as saveAgentStateAndEmitEvent, ft as resolvePiSessionPath, g as handleConversationAbort, gt as isTrustedOriginForHost, h as deliverConversationViaControlChannel, ht as getHeaderFromMap, j as handleConversationRestartAll, k as handleConversationCreate, l as rejectUnauthorizedDashboardRequest, lt as resolveClaudeSessionId, m as codexConversationPendingInput, mt as waitForSessionRespawn, nt as resolveAgentGitInfo, o as dashboardCsrfToken, p as saveAgentStateAndEmitEventProgram, pt as isRespawnPending, q as ensureConversationAttachmentDir, rt as resolveConversationGitInfo, s as dashboardSessionCookieHeader, st as readLauncherPinnedSessionId, t as specialistsRouteLayer, tt as invalidateAgentsCache, u as rejectUnauthorizedDashboardSessionMintRequest, ut as resolveCodexRolloutPath, v as handleConversationCompact, vt as validateOriginHeaders, w as pickDeliverAs, x as handleConversationPlanAction, xt as jsonResponse, y as handleConversationControlAck, yt as httpHandler, z as startConversationModelBackfill } from "./specialists-Bg9v4z3F.js";
2
+ import { A as canUseHarnessSync, Br as getOverdeckHome, Cr as LOGS_DIR, D as resolveTieredExecutionEnabled, E as resolveTieredExecutionBlock, Et as getIssueWorkspacePath, Fn as renameProject, Fr as getDocsDisableStatePath, Gr as sessionFilePath, H as init_providers, Hr as isDevMode, Ht as flushAutoCommits, I as UnknownModelError, Ir as getDocsIndexPath, J as defaultBackgroundAiFeatures, Jn as extractPrefixSync, Ln as resolveInfraRepo, Lr as getDocsTelemetryPath, M as init_harness_policy, Nr as encodeClaudeProjectDir, Nt as readIssueRecordSync, On as listProjects, Ot as init_record, Pn as registerProjectSync, Pr as getDocsBudgetStatePath, Q as computeModelOrigin, R as getBuiltInDefaultHarness, Rn as resolveProjectFromIssue, T as init_tier_table, Tn as init_projects, Un as setProjectAutoMergeDefaultSync, Ur as packageRoot, Ut as init_auto_commit, V as getProviderForModelSync, Vr as init_paths, Vt as flushAllPendingAutoCommits, Wn as setProjectSwarmPolicySync, X as DEFAULT_ROLES, Y as init_registry, Yn as init_issue_id, Z as DEFAULT_WORKHORSES, Zn as parseIssueIdSync, _ as getDefaultDocsConfig, at as getModelEffortLevelsSync, br as CLAUDE_DIR, cn as ProjectRenameError, ct as modelSupportsImagesSync, d as loadConfigNoMigration, er as require_dist$1, f as loadConfigSync, fn as findProjectByPathSync, fr as TrackerError, g as mergeConfigs, gn as getIssuePrefix, h as jsYaml, hr as AGENTS_DIR, ht as ROLE_EFFORTS, i as getConversationsConfig, ir as FsError, jr as SYNC_SOURCES, k as validateTieredExecutionConfig, kn as listProjectsSync, lt as resolveModelIdSync, m as init_js_yaml, mn as findProjectByTeamSync, mr as init_errors, mt as PARENT_MODEL_REF, n as clearConfigCache, nt as MODEL_CAPABILITIES, o as getGlobalConfigPath, or as GitHubApiError, ot as hasModelCapabilitySync, p as updateConversationsConfig, pt as COMPLIANCE_MODES, r as getConversationSearchConfigSync, rt as MODEL_DEPRECATIONS, s as init_load, st as init_model_capabilities, t as init_config_yaml, tt as resolveModel, u as isTldrEnabledSync, un as extractTeamPrefix, ur as ProcessSpawnError, v as getDefaultTtsDaemonConfig, w as TieredExecutionConfigError, wr as OVERDECK_HOME, y as mergeTtsDaemonConfigs, yn as getProjectSync, z as getKimiAnthropicBaseUrl, zn as resolveProjectFromIssueSync, zr as getLegacyHome } from "./config-yaml-DvyMuOle.js";
3
+ import { a as shouldRefuseHostDashboardPort, i as readHostDashboardApiPort, n as getDashboardIdentity, r as isNonPrimaryCheckoutRoot } from "./deacon-nudge-log-Bjg8U4Y9.js";
4
+ import { $ as runInBatches, A as handleConversationDelete, B as stopConversationRuntime, C as isPiControlChannelHarness, D as conversationNeedsRunningRepair, E as validateConversationControlAckOrigin, F as isInsideGitWorkTree, G as cleanupOrphanedConversationAttachments, H as waitForPiTuiReady, I as resolveAllowedHarness, J as extractConversationAttachmentPaths, K as cleanupUnreferencedConversationAttachments, L as shouldReportUnresolvedLiveSession, M as handleConversationResume, N as handleConversationStop, O as conversationSessionAliveFromState, P as handleConversationSwitchModel, Q as removeConversationAttachment, R as spawnConversationSession, S as handleConversationThinkingLevel, St as jsonStringResponse, T as resolveConversationDeliveryMethod, U as waitForTmuxSession$1, V as tmuxSessionExists, W as cleanupConversationAttachments, X as hasConversationAttachment, Y as getConversationAttachmentsRoot, Z as isManagedConversationAttachmentPath, _ as handleConversationCodexApproval, _t as validateOrigin$1, a as agentsRouteLayer, at as panCliInvocation, b as handleConversationDeliveryMethod, bt as getDefaultCwd, c as hasDashboardInternalToken, ct as resolveAgentHarness, d as rejectUnsafeDashboardMutationRequest, dt as resolveJsonlPath, et as evaluateSpawnGuardrails, f as saveAgentStateAndEmitEvent, ft as resolvePiSessionPath, g as handleConversationAbort, gt as isTrustedOriginForHost, h as deliverConversationViaControlChannel, ht as getHeaderFromMap, j as handleConversationRestartAll, k as handleConversationCreate, l as rejectUnauthorizedDashboardRequest, lt as resolveClaudeSessionId, m as codexConversationPendingInput, mt as waitForSessionRespawn, nt as resolveAgentGitInfo, o as dashboardCsrfToken, p as saveAgentStateAndEmitEventProgram, pt as isRespawnPending, q as ensureConversationAttachmentDir, rt as resolveConversationGitInfo, s as dashboardSessionCookieHeader, st as readLauncherPinnedSessionId, t as specialistsRouteLayer, tt as invalidateAgentsCache, u as rejectUnauthorizedDashboardSessionMintRequest, ut as resolveCodexRolloutPath, v as handleConversationCompact, vt as validateOriginHeaders, w as pickDeliverAs, x as handleConversationPlanAction, xt as jsonResponse, y as handleConversationControlAck, yt as httpHandler, z as startConversationModelBackfill } from "./specialists-JVO00bs7.js";
5
5
  import { a as init_activity_logger, i as emitDashboardLifecycleSync, n as emitActivityEntrySync, r as emitActivityTtsSync } from "./activity-logger-DDlOIAML.js";
6
- import { A as init_paths$1, O as OVERDECK_MIGRATION_PATH, f as init_infra, i as DbLive, k as getOverdeckDatabasePath, u as TmuxLive } from "./infra-D4iNWMA5.js";
6
+ import { A as init_paths$1, O as OVERDECK_MIGRATION_PATH, f as init_infra, i as DbLive, k as getOverdeckDatabasePath, u as TmuxLive } from "./infra-CzaSOgul.js";
7
7
  import { n as openDatabase, t as init_driver } from "./driver-CKVGi51s.js";
8
- import { n as updateIssueRecord, t as init_record_update } from "./record-update-Crz74r-6.js";
9
- import { C as getWindowDimensions, D as killSession, I as resizeWindow, K as init_ui_theme, M as listSessions, R as sendKeys, T as isHarnessProcessAlive, V as sessionExists, X as buildChildEnvWithoutTmuxSync, Y as buildChildEnvSync, Z as init_child_env, d as ensureManagedTmuxContextOnce, i as capturePane, j as listSessionNames, k as listPaneValues, l as deliveryVerifyLine, n as buildTmuxArgs, o as capturePaneText, q as setUiTheme, s as createSession, w as init_tmux, z as sendKeysAsync } from "./tmux-L5LgvGLp.js";
10
- import { a as init_event_store, i as initEventStore, n as getEventStore } from "./event-store-TnWdydfB.js";
11
- import { D as AgentSnapshot, E as AgentRuntimeSnapshot, O as ReviewStatusSnapshot, S as SystemHealthSnapshot, _ as WS_METHODS, b as EDITORS, c as ContextPreviewRequest, g as PanRpcGroup, h as PanRpcError, l as FlywheelStats, n as compareIssueIds, o as getHarnessBehavior, s as ContextLayerSaveRequest, t as init_src, v as FlywheelRunId, w as MemoryObservation, x as DomainEvent, y as FlywheelStatus } from "./src-k039WVYY.js";
12
- import { a as fixStuckReadyForMerge, c as init_review_status, i as fixStuckCommentedReviews, l as loadReadyForMergeFlags, n as clearReviewStatus, o as getReviewStatus, r as clearStuckMergeStatuses, s as getReviewStatusSync, u as loadReviewStatuses, v as setReviewStatus, y as setReviewStatusSync } from "./review-status-DFRjDFef.js";
13
- import { a as EventStoreService, c as ReadModelService, d as init_read_model, f as toAgentResolution, i as init_issue_lifecycle, l as ReadModelServiceLive, m as toRole, n as IssueLifecycleLive, o as EventStoreServiceLive, p as toAgentStatus, s as init_domain_services, t as IssueLifecycle } from "./issue-lifecycle-CeyW_HoD.js";
14
- import { c as listAllAgentsSync, n as AgentsResolverLive, o as init_agents } from "./agents-DXdHmRTC.js";
15
- import { i as init_paths$2, l as resolveObservationsFile, r as ensureParentDir, s as resolveIssueMemoryRoot, t as assertMemorySafeSegment } from "./paths-DooHpt9p.js";
16
- import { i as recordBriefingSessionStart, n as ensureSessionContextBriefingFile, r as init_briefing_freshness, t as appendFreshBriefingUpdate } from "./briefing-freshness-C12WgkaB.js";
17
- import { n as listFeatureRegistryEntries, t as init_feature_registry_storage } from "./feature-registry-storage-B972ph_A.js";
18
- import { a as diffAgainstMain, c as diffCheckpoints, d as diffPatchSinceCommit, f as findCommitAtTime, h as listCheckpoints, l as diffFilesAgainstHead, m as init_checkpoint_manager, o as diffAgainstMainFiles, s as diffCheckpointFiles, t as captureCheckpoint, u as diffPatchFilesAgainstHead } from "./checkpoint-manager-CTPjAmtH.js";
19
- import { Ct as probeTranscriptSince, Dn as getAgentDir, Gn as saveAgentStateSync, Gt as getProviderAuthMode, It as resolveImplicitStaffing, Jt as injectPiConversationMemory, L as messageAgent, Pt as init_staffing, Qn as readAgentHarnessModelRecordSync, R as init_operator_interventions, St as init_transcript_landing, Zn as init_agent_record_sync, _r as init_codex_auth, a as listRunningAgentsSync, ar as normalizeAgentId, cr as waitForReadySignal, dn as getOpenAIAuthStatus, fn as init_openai_auth, gr as checkCodexAuthStatus, gt as deliverAgentMessage, i as listRunningAgents, it as emergencyBrake, jn as getAgentStateSync, kn as getAgentState, lr as getAgentRuntimeState, m as init_tier_supervisor, n as init_queries, nn as init_claude_auth, on as getProviderEnvForModel, ot as init_concurrency, p as deliverCommitForReview, r as listAgentStates, s as init_agents$1, tn as getClaudeAuthStatus, ur as getAgentRuntimeStateSync, v as supervisorAgentId, xt as captureTranscriptUserRecordSnapshot, z as operatorInterventionEvent } from "./queries-ZABd5aXP.js";
20
- import { a as getCostForIssueAggregateSync, c as getDailyTrendsSync, d as init_cost_sync, l as getModelRollupSync, n as getBackgroundCostBySourceSync, p as queryCostEventsSync, r as getCavemanExperimentDataSync, s as getCostsByIssueSync, u as getTodayCostSync } from "./cost-sync-D_cre6WM.js";
21
- import { c as getAgentsNeedingAttention, d as CostResolverLive, f as CostWriter, l as CostDoorLive, n as readCloisterStateFile, o as generateHealthSummary, s as getAgentHealth, t as getCloisterService, u as CostResolver } from "./service-Bagb90KZ.js";
22
- import { u as init_agent_runtime_mirror } from "./session-history-XdS0JKp3.js";
23
- import { t as init_behavior } from "./behavior-CGj16clS.js";
24
- import { n as AgentStateServiceLive } from "./agent-state-service-DistflNn.js";
25
- import { a as init_tracker_config, i as initTrackerConfigCache, n as getLinearApiKey, r as getRallyConfig, t as getGitHubConfig } from "./tracker-config-DdT-nUAM.js";
8
+ import { n as updateIssueRecord, t as init_record_update } from "./record-update-Dq0t2uBG.js";
9
+ import { $ as init_child_env, B as sendKeysAsync, C as getWindowDimensions, D as killSession, H as sessionExists, J as init_ui_theme, L as resizeWindow, M as listSessionNames, Q as buildChildEnvWithoutTmuxSync, T as isHarnessProcessAlive, Y as setUiTheme, Z as buildChildEnvSync, d as ensureManagedTmuxContextOnce, i as capturePane, l as deliveryVerifyLine, n as buildTmuxArgs, o as capturePaneText, s as createSession, w as init_tmux, z as sendKeys } from "./tmux-ftABRAmc.js";
10
+ import { a as init_event_store, i as initEventStore, n as getEventStore } from "./event-store-tdiY5eDZ.js";
11
+ import { D as AgentSnapshot, E as AgentRuntimeSnapshot, O as ReviewStatusSnapshot, S as SystemHealthSnapshot, _ as WS_METHODS, b as EDITORS, c as ContextPreviewRequest, g as PanRpcGroup, h as PanRpcError, l as FlywheelStats, n as compareIssueIds, o as getHarnessBehavior, s as ContextLayerSaveRequest, t as init_src, v as FlywheelRunId, w as MemoryObservation, x as DomainEvent, y as FlywheelStatus } from "./src-U7_kTPEE.js";
12
+ import { a as fixStuckCommentedReviews, b as setReviewStatusSync, c as getReviewStatusSync, d as loadReviewStatuses, l as init_review_status, n as clearReviewStatus, o as fixStuckReadyForMerge, p as markWorkspaceStuck, r as clearStuckMergeStatuses, s as getReviewStatus, u as loadReadyForMergeFlags, y as setReviewStatus } from "./review-status-A7quS5KJ.js";
13
+ import { a as EventStoreService, c as ReadModelService, d as init_read_model, f as toAgentResolution, i as init_issue_lifecycle, l as ReadModelServiceLive, m as toRole, n as IssueLifecycleLive, o as EventStoreServiceLive, p as toAgentStatus, s as init_domain_services, t as IssueLifecycle } from "./issue-lifecycle-CreaCkjW.js";
14
+ import { c as listAllAgentsSync, n as AgentsResolverLive, o as init_agents } from "./agents-B4Bjbkfv.js";
15
+ import { i as init_paths$2, l as resolveObservationsFile, r as ensureParentDir, s as resolveIssueMemoryRoot, t as assertMemorySafeSegment } from "./paths-_zEts6wc.js";
16
+ import { i as recordBriefingSessionStart, n as ensureSessionContextBriefingFile, r as init_briefing_freshness, t as appendFreshBriefingUpdate } from "./briefing-freshness-DWdW7vUm.js";
17
+ import { n as listFeatureRegistryEntries, t as init_feature_registry_storage } from "./feature-registry-storage-_wUBRD3J.js";
18
+ import { a as diffAgainstMain, c as diffCheckpoints, d as diffPatchSinceCommit, f as findCommitAtTime, h as listCheckpoints, l as diffFilesAgainstHead, m as init_checkpoint_manager, o as diffAgainstMainFiles, s as diffCheckpointFiles, t as captureCheckpoint, u as diffPatchFilesAgainstHead } from "./checkpoint-manager-DDqcGyu8.js";
19
+ import { Ar as init_codex_auth, Bn as getAgentDir, Cr as getAgentRuntimeStateSync, D as init_tier_supervisor, E as deliverCommitForReview, Ft as init_transcript_landing, Hn as getAgentState, It as probeTranscriptSince, Pt as captureTranscriptUserRecordSnapshot, Q as operatorInterventionEvent, Sr as getAgentRuntimeState, Tn as init_openai_auth, Wn as getAgentStateSync, X as messageAgent, Yt as resolveImplicitStaffing, Z as init_operator_interventions, _t as emergencyBrake, a as listRunningAgentsSync, b as init_agents$1, c as getRuntimeCensus, d as panePidsForSession, dr as readAgentHarnessModelRecordSync, f as refreshRuntimeCensus, hn as init_claude_auth, i as listRunningAgents, in as getProviderAuthMode, ir as saveAgentStateSync, j as supervisorAgentId, kr as checkCodexAuthStatus, kt as deliverAgentMessage, l as getRuntimeCensusSnapshot, mn as getClaudeAuthStatus, n as init_queries, p as runtimeCensusHasHarnessProcess, qt as init_staffing, r as listAgentStates, sn as injectPiConversationMemory, u as init_runtime_census, ur as init_agent_record_sync, vr as normalizeAgentId, wn as getOpenAIAuthStatus, xr as waitForReadySignal, yn as getProviderEnvForModel, yt as init_concurrency } from "./queries-6d7Cdtm7.js";
20
+ import { a as getCostForIssueAggregateSync, c as getDailyTrendsSync, d as init_cost_sync, l as getModelRollupSync, n as getBackgroundCostBySourceSync, p as queryCostEventsSync, r as getCavemanExperimentDataSync, s as getCostsByIssueSync, u as getTodayCostSync } from "./cost-sync-C0VdGme1.js";
21
+ import { c as getAgentsNeedingAttention, d as CostResolverLive, f as CostWriter, l as CostDoorLive, n as readCloisterStateFile, o as generateHealthSummary, s as getAgentHealth, t as getCloisterService, u as CostResolver } from "./service-DCpB_SGd.js";
22
+ import { u as init_agent_runtime_mirror } from "./session-history-CVZDpS3c.js";
23
+ import { t as init_behavior } from "./behavior-B_-4EKF3.js";
24
+ import { n as AgentStateServiceLive } from "./agent-state-service-HoK8U4jW.js";
25
+ import { a as init_tracker_config, i as initTrackerConfigCache, n as getLinearApiKey, r as getRallyConfig, t as getGitHubConfig } from "./tracker-config-B4itFzDo.js";
26
26
  import { d as init_typed_errors, i as PlanEmpty, l as WorkspaceCreateError, n as AgentStartError, s as TrackerApiError, t as AgentAlreadyRunning, u as WorkspaceNotFound } from "./typed-errors-2BTMxkZq.js";
27
- import { i as init_linear_client, r as LinearClientOptionalLive, t as LinearClient } from "./linear-client-DsFkIxee.js";
28
- import { i as init_github_client, r as GitHubClientOptionalLive, t as GitHubClient } from "./github-client-XjTJbBm7.js";
29
- import { i as init_rally_client, r as RallyClientOptionalLive, t as RallyClient } from "./rally-client-COYz1vYR.js";
30
- import { a as resolveTrackerTypeSync, i as resolveGitHubIssueSync, n as init_tracker_utils } from "./tracker-utils-CawsPSS2.js";
31
- import { a as CacheService, i as startSharedIssueService, n as init_issue_service_singleton, o as init_cache_service, r as issue_service_singleton_exports, s as parseIntegerHeader, t as getSharedIssueService } from "./issue-service-singleton-D_RVYBuL.js";
32
- import { i as ensureInternalTokenSync, o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-CXsfxslp.js";
33
- import { a as setPipelineHandlerSync, t as init_pipeline_notifier } from "./pipeline-notifier-B6FVsYF9.js";
34
- import { c as init_review_status_sync, i as getMergeBlockerReconcileCandidates } from "./review-status-sync-DpAMD_WO.js";
27
+ import { i as init_linear_client, r as LinearClientOptionalLive, t as LinearClient } from "./linear-client-D4zqMnX7.js";
28
+ import { i as init_github_client, r as GitHubClientOptionalLive, t as GitHubClient } from "./github-client--XVlDpwM.js";
29
+ import { i as init_rally_client, r as RallyClientOptionalLive, t as RallyClient } from "./rally-client-B1EJhfV0.js";
30
+ import { a as resolveTrackerTypeSync, i as resolveGitHubIssueSync, n as init_tracker_utils } from "./tracker-utils-tnxxqROg.js";
31
+ import { a as CacheService, i as startSharedIssueService, n as init_issue_service_singleton, o as init_cache_service, r as issue_service_singleton_exports, s as parseIntegerHeader, t as getSharedIssueService } from "./issue-service-singleton-B5ushCvE.js";
32
+ import { i as ensureInternalTokenSync, o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-Bb4XeV2x.js";
33
+ import { a as setPipelineHandlerSync, t as init_pipeline_notifier } from "./pipeline-notifier-D0ykk59O.js";
34
+ import { c as init_review_status_sync, i as getMergeBlockerReconcileCandidates } from "./review-status-sync-BhSQ0d0l.js";
35
35
  import { n as init_review_status_source, t as classifyAdvancingSessionLifecycle } from "./review-status-source-CxuEjLGg.js";
36
36
  import { a as PAN_DIRNAME, d as WORKSPACE_RUNTIME_DIRNAME, f as asPanSpecDocument, i as PAN_CONTINUE_FILENAME, p as init_types } from "./types-hraoaQIp.js";
37
- import { C as transitionToMerging, _ as markFailed, c as isFlywheelGloballyPaused, d as listDuePendingAutoMerges, f as listProblemAutoMerges, g as markBlocked, n as getActionableAutoMerge, o as init_merge_sync, t as cancelPending, u as listActiveAutoMerges, v as markMerged, x as scheduleAutoMergeWithResult, y as requeueToPending } from "./merge-sync-Do8_q32h.js";
38
- import { C as init_specs, D as writeSpecDocument, O as writeSpecForIssue, a as findWorkspaceDraftPlan, m as readWorkspacePlanSync, o as init_io, p as readWorkspacePlan, r as findPlan, s as isPlanningComplete, u as readPlan, v as init_types$1, x as findSpecByIssue, y as subItemsOf } from "./io-DQR9PMgS.js";
39
- import { C as restartCliproxy, S as readPidFile, T as stopCliproxy, b as isCliproxyInstalled, d as getCliproxyAuthDir, o as bridgeCodexAuthToCliproxy, v as init_cliproxy, w as startCliproxy, x as isCliproxyRunning, y as installCliproxy } from "./cliproxy-Brf_5MuG.js";
40
- import { $ as updateConversationForkFallbackReason, A as isAgentConversationName, B as removeFavorite, C as getConversationByTmuxSession, D as importLegacyConversation, F as markConversationEnded, H as setClearedToConvId, I as markConversationRunning, J as setForkRequest, M as listConversations, N as listFavoritedIds, O as incrementForkRetryCount, P as markConversationActive, S as getConversationByName, T as getStuckForks, U as setConversationClaudeSessionId, X as unarchiveConversation, Y as setImportedConversationLinks, Z as updateConversationCost, _ as canRefineTitle, b as getConversationByClaudeSessionId, et as updateConversationTitle, gt as getDiscoveredSessionBySessionId, h as archiveConversation, j as listArchivedConversationsWithEnrichment, k as init_conversations, q as setFavorite, tt as updateForkStatus, v as canReplaceTitle, w as getConversationLedgerCosts, x as getConversationById, y as createConversation, yt as init_discovered_sessions, z as recordConversationHandoff } from "./conversations-bYpM9-kZ.js";
41
- import { n as isBackgroundFeatureEnabled, t as init_features } from "./features-Bc-Bmiye.js";
42
- import { i as init_settings, r as getMemoryWorkerConcurrency, t as areMemoryObservationsEnabled } from "./settings-BNbocWOg.js";
43
- import { i as updateMemoryHealth, n as extractWithProviderPolicy, r as init_health, t as init_providers$1 } from "./providers-BDDPULlp.js";
44
- import { i as normalizeModelOverrideSync, n as init_launcher_generator, r as init_model_validation, t as generateLauncherScriptSync } from "./launcher-generator-COgR2By1.js";
45
- import { a as init_claude_permissions, r as getClaudePermissionFlagsStringSync } from "./claude-permissions-nSFKH78M.js";
46
- import { a as globalContextFile$1, f as resolveProjectContextFile, h as workspaceContextFile, n as codexGlobalContextFile, o as init_layers, p as resolveWorkspaceContextFile, r as ensureProjectLayer } from "./layers-Cp1To4L8.js";
47
- import { l as init_codex, s as findRolloutPath } from "./codex-CbmztVcc.js";
48
- import { n as init_harness_binary, r as prepareHarnessLaunch } from "./harness-binary-B2CTcD84.js";
49
- import { f as init_config, m as loadConfigSync$1, s as getDashboardApiUrlSync } from "./config-q4Gvd8dq.js";
50
- import { C as setMergeTrainEnabled, S as setFlywheelRequireUatBeforeMerge, b as setFlywheelAutoPickupBacklog, c as isCloisterSpawnsPausedSync, d as isFlywheelAutoPickupBacklog, f as isFlywheelGloballyPaused$1, g as setCloisterSpawnsPausedSync, h as setBootReconciliationDecision, m as isMergeTrainEnabled, o as getSetting, p as isFlywheelRequireUatBeforeMerge, r as getBootReconciliationState, s as init_control_settings, u as isDeaconGloballyPausedSync, v as setDeaconGloballyPausedSync, w as setSetting } from "./control-settings-D_odMIaC.js";
51
- import { l as init_dag, r as compileGlob } from "./dag-CJpgf9A3.js";
52
- import { a as loadCloisterConfigSync, o as saveCloisterConfigSync, r as init_config$1, s as shouldAutoStart } from "./config-DeTsoZdR.js";
53
- import { c as isStateMigrated, i as ensureStateWorktree, o as init_state_home, r as clearStateMigrationCache, s as inspectStateMigration } from "./state-home-CONQvZR0.js";
54
- import { i as checkPrdGateSync, t as init_pan_dir } from "./pan-dir-DOcf6ug3.js";
55
- import { a as init_lifecycle_io, t as appendContinueSessionEntryForIssue } from "./lifecycle-io-taIb0PoH.js";
56
- import { r as init_swarm_readiness, t as analyzeSwarmReadiness } from "./swarm-readiness-DdmJVX7y.js";
57
- import { n as require_auth_errors, r as require_token_error, t as require_token_util } from "./token-util-DI8sGlmF.js";
58
- import { _ as init_codex_conversation_parser, a as contextUsageFromParseResult, c as parseEntireConversation, d as init_pi_conversation_parser, f as isPiSessionFile, g as parseOhmypiConversationMessages, h as isOhmypiSessionFile, i as computeContextUsage, l as parseFromLastCompactBoundary, m as init_ohmypi_conversation_parser, n as gateSnapshotEmission, o as summarizeConversationActivity, p as parsePiConversationMessages, r as watchConversation, s as parseConversationMessages, t as init_conversation_service, v as parseCodexConversationMessages } from "./conversation-service-C3avRVEr.js";
59
- import { c as countPendingAskUserQuestionsForAgent, h as detectAwaitingInputFromPaneSync, l as getAgentJsonlMtime, m as detectAwaitingInputForAgent, o as getRuntimeForAgent, p as scanPendingInputsPromise, s as computeAgentEnrichment } from "./stuck-remediation-CKnIryGT.js";
60
- import { i as CostThresholdError, l as embed, s as parseRelativeTime } from "./scanner-Br0Z5S6R.js";
61
- import { c as tailEventsSync, n as deduplicateEventsSync, o as readEventsSync } from "./events-DSUdR-04.js";
62
- import { n as recordBackgroundAiCost, t as init_cost } from "./cost-wH46-WsJ.js";
63
- import { a as getByIssueId, i as parseFlywheelStatsWindow, n as derivePipelineRunStatsInputs, o as markFixed, r as computeFlywheelStats, s as upsert } from "./substrate-bug-weights-service-CpIZILj9.js";
64
- import { c as startUatTrainReconciler, d as openFlywheelRunReportForDashboard, f as pauseFlywheelRunForDashboard, g as runDashboardDbJob, h as startFlywheelRunForDashboard, l as stopUatTrainReconciler, m as resumeFlywheelRunForDashboard, p as readCurrentFlywheelStatusForDashboard, u as abortFlywheelRunForDashboard } from "./uat-train-j0cPeMSj.js";
65
- import { C as writeLatestFlywheelStatus, b as resolveLiveFlywheelRunId, g as listFlywheelRuns, h as isFlywheelRunId, p as getFlywheelRunDetail, u as buildClassifyLookups, v as readCurrentLatestFlywheelStatus, x as subscribeLatestFlywheelStatus } from "./flywheel-COR0mbRI.js";
66
- import { C as getWorkspacePathForIssue, S as resolveIssueHeadlineCost, _ as getCostsForIssueSync, b as processPendingFeedbackDeliveries, d as resumeQueuedMerges, f as syncWalFromAllProjects, g as migrateAllSessionsSync, h as reclassifyUnknownCostEventsSync, l as internalEventsRouteLayer, m as reconcilePiTranscripts, p as reconcile$1, t as workspacesRouteLayer, u as eventsRouteLayer, v as rebuildCacheSync, x as getCachedRunningAgents, y as syncCacheSync } from "./workspaces-CFPcL0vl.js";
67
- import { At as getAcceptedSystemHealthSnapshot, Dt as formatUptime, Et as getResourceStacks, F as setAgentStatusChangedNotifier, Ft as isSmeeConfiguredSync, I as setAgentStoppedNotifier, It as startSmeeProcessSync, J as startBootReconciliation, K as isBootReconciliationCandidate, L as setMergeReadyNotifier, Lt as classifyAgentHealth, Nt as getSystemHealthEvidenceSnapshot, O as loadConfig, Ot as getContainerHistory, St as paneShowsClaudeBootBlockingScreen, jt as getDeployStaleness, k as loadState, kt as getCurrentDockerStats, n as assessDeaconPatrolFreshness, q as listBootReconciliationCandidates, t as applyBootReconciliationDecision, x as getDeaconLogs } from "./deacon-CkT_kznS.js";
68
- import { l as detectPlatform, u as init_platform } from "./workspace-manager-ClkCIWTe.js";
69
- import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-BXP6g75N.js";
70
- import { r as init_in_flight_guard, t as createInFlightGuard } from "./in-flight-guard-BoWm66Kh.js";
71
- import { t as init_specialists, z as getReviewerSessionName } from "./specialists-CwZHb5cb.js";
72
- import { c as findPrdAtStatusSync, l as init_prd_locations } from "./archive-planning-BvDuWNMo.js";
73
- import { a as getShadowState, s as init_shadow_state } from "./shadow-state-C_NkP-sa.js";
74
- import { A as withConcurrencyLimit, D as createPromiseConcurrencyLimiter, E as verifyAppCanMerge, O as createSettledTtlPromiseCache, d as getPullRequestState, f as init_github_app, k as init_concurrency$1, l as getMergeBackendStatus, p as isGitHubAppConfigured } from "./github-app-CDPtGF7J.js";
75
- import { n as init_issue_closed, t as clearIssueClosedCache } from "./issue-closed-DtmJM0D0.js";
76
- import { b as resolveSwarmPolicy } from "./deacon-swarm-BryRr6AO.js";
77
- import { a as init_boot_gates, i as formatBootGateState, o as resolveBootGates } from "./no-resume-mode-BWOSZjWd.js";
78
- import { _ as selectNeedsPlanning, c as classifyIssue, d as computeLanes, f as computeStats, g as normalizeGate, l as computeCohort, m as init_pickup, p as computeWaves, u as computeEpicGroups } from "./pickup-CaskQ7j6.js";
79
- import { a as applyIssueObjectionLabel, c as applyIssueReleasedLabel, d as removeIssueBlocksMainLabel, f as removeIssueObjectionLabel, g as removeIssueVetoedLabel, h as removeIssueReleasedLabel, i as applyIssueBlocksMainLabel, l as applyIssueVetoedLabel, m as removeIssueReadyLabel, o as applyIssueParkedLabel, p as removeIssueParkedLabel, s as applyIssueReadyLabel, u as init_label_ops } from "./label-reconciler-Df1ZduPH.js";
80
- import { n as parseSequenceMd, r as writeSequenceMd, t as init_sequence_io } from "./sequence-io-fxU0DlwW.js";
81
- import { c as init_resource_utils, i as gatherProjectLensSignals, l as parseIssueIdFromTextSync, n as init_pipeline_membership, o as init_pipeline_membership_gather, r as resolvePipelineMembership, s as listOpenPullRequestsSnapshot } from "./pipeline-membership-1LGRjo-k.js";
82
- import { a as loadWorkspaceMetadataSync } from "./workspace-metadata-tiSRIWJP.js";
83
- import { i as resolveAutoSpawnOnFinalize, o as spawnPlanningSession } from "./spawn-planning-session-D5OXo8pT.js";
84
- import { d as killRemoteAgent, m as loadRemoteAgentState, o as getRemoteAgentOutput, r as checkRemoteSpendCap, s as init_remote_agents, v as sendToRemoteAgent, y as spawnRemoteAgent } from "./remote-agents-Ct_WOyke.js";
85
- import { r as spawnInspectAgent } from "./inspect-agent-BXCgNeZ4.js";
86
- import { n as init_github_pr_lookup, r as lookupPullRequestNumberForBranch, t as githubPrLookupSource } from "./github-pr-lookup-CFGeVhqv.js";
87
- import { a as fetchIssuePullRequestDiff, c as getCachedIssuePrTabResponse, d as setCachedIssuePrTabResponse, i as fetchIssuePullRequestDetails, l as getIssuePrTabCacheGeneration, n as fetchIssueCheckRuns, o as init_pull_requests, r as fetchIssuePullRequest, s as bumpIssuePrTabCacheGeneration, u as init_pr_tab_cache } from "./pull-requests-8z2N1UOV.js";
88
- import { t as DOD_ROWS } from "./dod-DbJLYcHv.js";
89
- import { t as enrichReviewStatus } from "./review-status-enrichment-crNAtIpL.js";
90
- import { i as runMemoryFtsTransaction, n as init_fts_db, r as runMemoryFtsStatement, t as closeMemoryFtsDatabases } from "./fts-db-DmAcuCkV.js";
91
- import { c as init_pending, l as maybeTriggerStatusRollup, o as readRecentObservations, r as init_rollup, u as writePendingTurn } from "./rollup-SyuF09e4.js";
92
- import { n as getTldrDaemonServiceSync, r as init_tldr_daemon } from "./tldr-daemon-BQFmmFp0.js";
93
- import { T as listGitOperationsSync, w as init_git_activity } from "./merge-agent-DDiIjzk-.js";
94
- import { t as readVerificationArtifact } from "./verification-artifact-BuTA1QbL.js";
95
- import { t as getAgentCommandSync } from "./settings-uLc6DEYI.js";
96
- import { n as init_review_agent, r as isExtendedReviewEnabled } from "./review-agent-CThvgK2r.js";
97
- import { r as isRemoteAvailable, t as createFlyProviderFromConfig } from "./remote-b-c5bOce.js";
98
- import { n as init_claude_settings_overlay, t as detectProviderEnvConflicts } from "./claude-settings-overlay-BI_UIke0.js";
99
- import { a as init_query_expansion, i as clearQueryExpansionCache, n as init_injection, o as buildMatchQuery, r as injectPromptTimeMemory, s as init_search } from "./injection-D7T75Pye.js";
100
- import { _ as init_transcript_adapter, a as generateFallbackSummary, c as handoffPreconditionFallbackReason, d as prependFallbackFocus, f as requestHandoffFromAgent, g as getTranscriptAdapter, i as copySessionFromCompactBoundary, l as init_summary_fork, o as generateSummaryForFork, p as reserveSummaryForkSession, r as authorHandoffExternal, s as handoffFailureReason, u as logHandoffFallback } from "./summary-fork-bX6ax6X7.js";
101
- import { a as init_conversation_compaction, c as shouldInterceptManualCompact, n as compactConversationNative, o as isCompacting } from "./conversation-compaction-B6YSRLda.js";
102
- import { a as init_render, d as validateTemplate, i as hasManagedRegion, l as init_harness, o as userContentOutsideRegion, t as init_context_layers, u as renderForHarness } from "./context-layers-15gDOk20.js";
103
- import { r as parseArtifactRef } from "./forge-B1S_KZv4.js";
104
- import { t as getMergeBlockersPayload } from "./merge-blockers-BYjeXrVN.js";
105
- import { a as spawnSequencerAgent, i as init_sequencer_agent, n as clearFinishedSequencerRun, r as getSequencerRunStatus, t as SEQUENCER_AGENT_ID } from "./sequencer-agent-B5YC5XVP.js";
106
- import "./supervisor-Ctt4eRYz.js";
107
- import { i as listTranscriptCheckpoints, r as getTranscriptCheckpoint$1 } from "./checkpoints-BJum14fs.js";
37
+ import { C as transitionToMerging, _ as markFailed, c as isFlywheelGloballyPaused, d as listDuePendingAutoMerges, f as listProblemAutoMerges, g as markBlocked, n as getActionableAutoMerge, o as init_merge_sync, t as cancelPending, u as listActiveAutoMerges, v as markMerged, x as scheduleAutoMergeWithResult, y as requeueToPending } from "./merge-sync-DZ9dojJn.js";
38
+ import { C as init_specs, D as writeSpecDocument, O as writeSpecForIssue, a as findWorkspaceDraftPlan, m as readWorkspacePlanSync, o as init_io, p as readWorkspacePlan, r as findPlan, s as isPlanningComplete, u as readPlan, v as init_types$1, x as findSpecByIssue, y as subItemsOf } from "./io-B3_AHDfr.js";
39
+ import { C as restartCliproxy, S as readPidFile, T as stopCliproxy, b as isCliproxyInstalled, d as getCliproxyAuthDir, o as bridgeCodexAuthToCliproxy, v as init_cliproxy, w as startCliproxy, x as isCliproxyRunning, y as installCliproxy } from "./cliproxy-Bgb2XCqi.js";
40
+ import { $ as updateConversationForkFallbackReason, A as isAgentConversationName, B as removeFavorite, C as getConversationByTmuxSession, D as importLegacyConversation, F as markConversationEnded, H as setClearedToConvId, I as markConversationRunning, J as setForkRequest, M as listConversations, N as listFavoritedIds, O as incrementForkRetryCount, P as markConversationActive, S as getConversationByName, T as getStuckForks, U as setConversationClaudeSessionId, X as unarchiveConversation, Y as setImportedConversationLinks, Z as updateConversationCost, _ as canRefineTitle, b as getConversationByClaudeSessionId, et as updateConversationTitle, gt as getDiscoveredSessionBySessionId, h as archiveConversation, j as listArchivedConversationsWithEnrichment, k as init_conversations, q as setFavorite, tt as updateForkStatus, v as canReplaceTitle, w as getConversationLedgerCosts, x as getConversationById, y as createConversation, yt as init_discovered_sessions, z as recordConversationHandoff } from "./conversations-DbOs1e9Q.js";
41
+ import { n as isBackgroundFeatureEnabled, t as init_features } from "./features-Dhxz-wLc.js";
42
+ import { i as init_settings, r as getMemoryWorkerConcurrency, t as areMemoryObservationsEnabled } from "./settings-BZ5m1UCl.js";
43
+ import { i as updateMemoryHealth, n as extractWithProviderPolicy, r as init_health, t as init_providers$1 } from "./providers-DV7ec8l7.js";
44
+ import { i as normalizeModelOverrideSync, n as init_launcher_generator, r as init_model_validation, t as generateLauncherScriptSync } from "./launcher-generator-CHVm7bGT.js";
45
+ import { a as init_claude_permissions, r as getClaudePermissionFlagsStringSync } from "./claude-permissions-H_5wHQZQ.js";
46
+ import { a as globalContextFile$1, f as resolveProjectContextFile, h as workspaceContextFile, n as codexGlobalContextFile, o as init_layers, p as resolveWorkspaceContextFile, r as ensureProjectLayer } from "./layers-DzxSTGNA.js";
47
+ import { l as init_codex, s as findRolloutPath } from "./codex-TmSi-yTv.js";
48
+ import { n as init_harness_binary, r as prepareHarnessLaunch } from "./harness-binary-CVio2m-u.js";
49
+ import { f as init_config, m as loadConfigSync$1, s as getDashboardApiUrlSync } from "./config-CCvjQf27.js";
50
+ import { C as setMergeTrainEnabled, S as setFlywheelRequireUatBeforeMerge, b as setFlywheelAutoPickupBacklog, c as isCloisterSpawnsPausedSync, d as isFlywheelAutoPickupBacklog, f as isFlywheelGloballyPaused$1, g as setCloisterSpawnsPausedSync, h as setBootReconciliationDecision, m as isMergeTrainEnabled, o as getSetting, p as isFlywheelRequireUatBeforeMerge, r as getBootReconciliationState, s as init_control_settings, u as isDeaconGloballyPausedSync, v as setDeaconGloballyPausedSync, w as setSetting } from "./control-settings-aP1ANIlI.js";
51
+ import { l as init_dag, r as compileGlob } from "./dag-CdOjJVDT.js";
52
+ import { a as loadCloisterConfigSync, o as saveCloisterConfigSync, r as init_config$1, s as shouldAutoStart } from "./config-DjLOdbgT.js";
53
+ import { c as isStateMigrated, i as ensureStateWorktree, o as init_state_home, r as clearStateMigrationCache, s as inspectStateMigration } from "./state-home-CIGjwNfJ.js";
54
+ import { i as checkPrdGateSync, s as promoteWorkspacePrdDraft, t as init_pan_dir } from "./pan-dir-DeVUgwA7.js";
55
+ import { a as init_lifecycle_io, t as appendContinueSessionEntryForIssue } from "./lifecycle-io-D8iNBcux.js";
56
+ import { r as init_swarm_readiness, t as analyzeSwarmReadiness } from "./swarm-readiness-CQ_fwUWF.js";
57
+ import { n as require_auth_errors, r as require_token_error, t as require_token_util } from "./token-util-CTmczIfW.js";
58
+ import { A as withConcurrencyLimit, D as createPromiseConcurrencyLimiter, E as verifyAppCanMerge, O as createSettledTtlPromiseCache, d as getPullRequestState, f as init_github_app, k as init_concurrency$1, l as getMergeBackendStatus, p as isGitHubAppConfigured } from "./github-app-CMBdIFBQ.js";
59
+ import { C as getWorkspacePathForIssue, E as stopAgentOutputService, S as resolveIssueHeadlineCost, T as startAgentOutputService, _ as getCostsForIssueSync, b as processPendingFeedbackDeliveries, d as resumeQueuedMerges, f as syncWalFromAllProjects, g as migrateAllSessionsSync, h as reclassifyUnknownCostEventsSync, l as internalEventsRouteLayer, m as reconcilePiTranscripts, p as reconcile$1, t as workspacesRouteLayer, u as eventsRouteLayer, v as rebuildCacheSync, w as retainAgentOutputInterest, x as getCachedRunningAgents, y as syncCacheSync } from "./workspaces-hWvy9eKs.js";
60
+ import { _ as init_codex_conversation_parser, a as contextUsageFromParseResult, c as parseEntireConversation, d as init_pi_conversation_parser, f as isPiSessionFile, g as parseOhmypiConversationMessages, h as isOhmypiSessionFile, i as computeContextUsage, l as parseFromLastCompactBoundary, m as init_ohmypi_conversation_parser, n as gateSnapshotEmission, o as summarizeConversationActivity, p as parsePiConversationMessages, r as watchConversation, s as parseConversationMessages, t as init_conversation_service, v as parseCodexConversationMessages } from "./conversation-service-Du-MTNpJ.js";
61
+ import { c as countPendingAskUserQuestionsForAgent, h as detectAwaitingInputFromPaneSync, l as getAgentJsonlMtime, m as detectAwaitingInputForAgent, o as getRuntimeForAgent, p as scanPendingInputsPromise, s as computeAgentEnrichment } from "./stuck-remediation-CzEov_fq.js";
62
+ import { i as CostThresholdError, l as embed, s as parseRelativeTime } from "./scanner-D2743cp8.js";
63
+ import { c as tailEventsSync, n as deduplicateEventsSync, o as readEventsSync } from "./events-CC1dgUpx.js";
64
+ import { n as recordBackgroundAiCost, t as init_cost } from "./cost-CW4WSe72.js";
65
+ import { a as getByIssueId, i as parseFlywheelStatsWindow, n as derivePipelineRunStatsInputs, o as markFixed, r as computeFlywheelStats, s as upsert } from "./substrate-bug-weights-service-BH66lhm7.js";
66
+ import { c as startUatTrainReconciler, d as openFlywheelRunReportForDashboard, f as pauseFlywheelRunForDashboard, g as runDashboardDbJob, h as startFlywheelRunForDashboard, l as stopUatTrainReconciler, m as resumeFlywheelRunForDashboard, p as readCurrentFlywheelStatusForDashboard, u as abortFlywheelRunForDashboard } from "./uat-train-CuEn0t9M.js";
67
+ import { C as writeLatestFlywheelStatus, b as resolveLiveFlywheelRunId, g as listFlywheelRuns, h as isFlywheelRunId, p as getFlywheelRunDetail, u as buildClassifyLookups, v as readCurrentLatestFlywheelStatus, x as subscribeLatestFlywheelStatus } from "./flywheel-DSSpWmqF.js";
68
+ import { At as getContainerHistory, Ct as paneShowsClaudeBootBlockingScreen, F as setAgentStatusChangedNotifier, Ft as getSystemHealthEvidenceSnapshot, I as setAgentStoppedNotifier, J as startBootReconciliation, K as isBootReconciliationCandidate, L as setMergeReadyNotifier, Lt as isSmeeConfiguredSync, Mt as getAcceptedSystemHealthSnapshot, Nt as getDeployStaleness, O as loadConfig, Ot as getResourceStacks, Rt as startSmeeProcessSync, jt as getCurrentDockerStats, k as loadState, kt as formatUptime, n as assessDeaconPatrolFreshness, q as listBootReconciliationCandidates, t as applyBootReconciliationDecision, x as getDeaconLogs, zt as classifyAgentHealth } from "./deacon-pRnyD5w9.js";
69
+ import { l as detectPlatform, u as init_platform } from "./workspace-manager-hLUv3ADC.js";
70
+ import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-C9b6ccN1.js";
71
+ import { r as init_in_flight_guard, t as createInFlightGuard } from "./in-flight-guard-aQ1IxeI3.js";
72
+ import { V as getReviewerSessionName, t as init_specialists } from "./specialists-DyFeedjn.js";
73
+ import { c as findPrdAnywhereSync, l as init_prd_locations } from "./archive-planning-DYrYojxl.js";
74
+ import { a as getShadowState, s as init_shadow_state } from "./shadow-state-Dh-HzF2J.js";
75
+ import { n as init_issue_closed, t as clearIssueClosedCache } from "./issue-closed-zhdvQicO.js";
76
+ import { b as resolveSwarmPolicy } from "./deacon-swarm-DftYRDo8.js";
77
+ import { a as init_boot_gates, i as formatBootGateState, o as resolveBootGates } from "./no-resume-mode-Cx3K0hHi.js";
78
+ import { _ as selectNeedsPlanning, c as classifyIssue, d as computeLanes, f as computeStats, g as normalizeGate, l as computeCohort, m as init_pickup, p as computeWaves, u as computeEpicGroups } from "./pickup-Dd0Znxxy.js";
79
+ import { a as applyIssueObjectionLabel, c as applyIssueReleasedLabel, d as removeIssueBlocksMainLabel, f as removeIssueObjectionLabel, g as removeIssueVetoedLabel, h as removeIssueReleasedLabel, i as applyIssueBlocksMainLabel, l as applyIssueVetoedLabel, m as removeIssueReadyLabel, o as applyIssueParkedLabel, p as removeIssueParkedLabel, s as applyIssueReadyLabel, u as init_label_ops } from "./label-reconciler-DdWbHEBu.js";
80
+ import { n as parseSequenceMd, r as writeSequenceMd, t as init_sequence_io } from "./sequence-io-Cg0zYj_E.js";
81
+ import { c as init_resource_utils, i as gatherProjectLensSignals, l as parseIssueIdFromTextSync, n as init_pipeline_membership, o as init_pipeline_membership_gather, r as resolvePipelineMembership, s as listOpenPullRequestsSnapshot } from "./pipeline-membership-0HaEGDlH.js";
82
+ import { a as loadWorkspaceMetadataSync } from "./workspace-metadata-CskwzzhL.js";
83
+ import { i as resolveAutoSpawnOnFinalize, o as spawnPlanningSession } from "./spawn-planning-session-DWAorh2B.js";
84
+ import { d as killRemoteAgent, m as loadRemoteAgentState, o as getRemoteAgentOutput, r as checkRemoteSpendCap, s as init_remote_agents, v as sendToRemoteAgent, y as spawnRemoteAgent } from "./remote-agents-nmty1mLu.js";
85
+ import { r as spawnInspectAgent } from "./inspect-agent-DJKLWcVT.js";
86
+ import { n as init_github_pr_lookup, r as lookupPullRequestNumberForBranch, t as githubPrLookupSource } from "./github-pr-lookup-BRbDW-qk.js";
87
+ import { a as fetchIssuePullRequestDiff, c as getCachedIssuePrTabResponse, d as setCachedIssuePrTabResponse, i as fetchIssuePullRequestDetails, l as getIssuePrTabCacheGeneration, n as fetchIssueCheckRuns, o as init_pull_requests, r as fetchIssuePullRequest, s as bumpIssuePrTabCacheGeneration, u as init_pr_tab_cache } from "./pull-requests-CXIhdCYD.js";
88
+ import { t as DOD_ROWS } from "./dod-BrSfUHm0.js";
89
+ import { t as enrichReviewStatus } from "./review-status-enrichment-tbOn_A_u.js";
90
+ import { i as runMemoryFtsTransaction, n as init_fts_db, r as runMemoryFtsStatement, t as closeMemoryFtsDatabases } from "./fts-db-CKgg0VKg.js";
91
+ import { c as init_pending, l as maybeTriggerStatusRollup, o as readRecentObservations, r as init_rollup, u as writePendingTurn } from "./rollup-WA0VD-Rr.js";
92
+ import { n as getTldrDaemonServiceSync, r as init_tldr_daemon } from "./tldr-daemon-BDtLOIlO.js";
93
+ import { T as listGitOperationsSync, w as init_git_activity } from "./merge-agent-XrB80vfT.js";
94
+ import { t as readVerificationArtifact } from "./verification-artifact-BcnIbigL.js";
95
+ import { t as getAgentCommandSync } from "./settings-ylxwqwQG.js";
96
+ import { n as init_review_agent, r as isExtendedReviewEnabled } from "./review-agent-sKkE1FEL.js";
97
+ import { r as isRemoteAvailable, t as createFlyProviderFromConfig } from "./remote-Br-ZWVIP.js";
98
+ import { n as init_claude_settings_overlay, t as detectProviderEnvConflicts } from "./claude-settings-overlay-CbSz0Dvb.js";
99
+ import { a as init_query_expansion, i as clearQueryExpansionCache, n as init_injection, o as buildMatchQuery, r as injectPromptTimeMemory, s as init_search } from "./injection-DZ0PfYa4.js";
100
+ import { _ as init_transcript_adapter, a as generateFallbackSummary, c as handoffPreconditionFallbackReason, d as prependFallbackFocus, f as requestHandoffFromAgent, g as getTranscriptAdapter, i as copySessionFromCompactBoundary, l as init_summary_fork, o as generateSummaryForFork, p as reserveSummaryForkSession, r as authorHandoffExternal, s as handoffFailureReason, u as logHandoffFallback } from "./summary-fork-DHhJIsAL.js";
101
+ import { a as init_conversation_compaction, c as shouldInterceptManualCompact, n as compactConversationNative, o as isCompacting } from "./conversation-compaction-CNbTLB86.js";
102
+ import { a as init_render, d as validateTemplate, i as hasManagedRegion, l as init_harness, o as userContentOutsideRegion, t as init_context_layers, u as renderForHarness } from "./context-layers-ZYFcWiyc.js";
103
+ import { r as parseArtifactRef } from "./forge-Ch9gCFod.js";
104
+ import { t as getMergeBlockersPayload } from "./merge-blockers-BsFjGrQ8.js";
105
+ import { a as spawnSequencerAgent, i as init_sequencer_agent, n as clearFinishedSequencerRun, r as getSequencerRunStatus, t as SEQUENCER_AGENT_ID } from "./sequencer-agent-BGY8gjg-.js";
106
+ import "./supervisor-BO-Zk_h-.js";
107
+ import { i as listTranscriptCheckpoints, r as getTranscriptCheckpoint$1 } from "./checkpoints-C-AXLfYT.js";
108
108
  import { createRequire } from "node:module";
109
109
  import * as sp from "node:path";
110
110
  import { basename, delimiter, dirname, extname, isAbsolute, join, normalize, relative, resolve, sep } from "node:path";
@@ -358,6 +358,24 @@ const ServerConfigLayer = Layer.effect(ServerConfig, Effect.sync(() => {
358
358
  };
359
359
  }));
360
360
  //#endregion
361
+ //#region dashboard-listening.ts
362
+ let resolveListening;
363
+ let listening = false;
364
+ let listeningPromise = createListeningPromise();
365
+ function createListeningPromise() {
366
+ return new Promise((resolve) => {
367
+ resolveListening = resolve;
368
+ });
369
+ }
370
+ function markDashboardListening() {
371
+ if (listening) return;
372
+ listening = true;
373
+ resolveListening();
374
+ }
375
+ function whenDashboardListening() {
376
+ return listeningPromise;
377
+ }
378
+ //#endregion
361
379
  //#region services/terminal-service.ts
362
380
  init_activity_logger();
363
381
  init_paths$1();
@@ -691,7 +709,7 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
691
709
  if (!existsSync$1(workspacePath)) throw new WorkspaceNotFound({ id: issueId });
692
710
  const plan = readWorkspacePlanSync(workspacePath);
693
711
  if (!plan || plan.plan.items.length === 0) throw new PlanEmpty({ id: issueId });
694
- const { getAgentState, spawnAgent, normalizeAgentId } = await import("./agents-DyHKlq1I.js");
712
+ const { getAgentState, spawnAgent, normalizeAgentId } = await import("./agents-FlIgQ3ql.js");
695
713
  const normalizedId = normalizeAgentId(issueId);
696
714
  if ((await Effect.runPromise(getAgentState(normalizedId)))?.status === "running") throw new AgentAlreadyRunning({ id: issueId });
697
715
  return {
@@ -722,7 +740,7 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
722
740
  const { workspacePath, projectPath, issue } = opts;
723
741
  if (!existsSync$1(workspacePath)) throw new WorkspaceNotFound({ id: issueId });
724
742
  const sessionName = opts.sessionName ?? `planning-${issueId.toLowerCase()}`;
725
- const { spawnPlanningSession } = await import("./spawn-planning-session-8D6mE033.js");
743
+ const { spawnPlanningSession } = await import("./spawn-planning-session-KC_UduxD.js");
726
744
  const result = await spawnPlanningSession({
727
745
  issue: {
728
746
  id: issue.id,
@@ -755,14 +773,14 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
755
773
  }),
756
774
  kill: (agentId) => Effect.tryPromise({
757
775
  try: async () => {
758
- const { stopAgent } = await import("./agents-DyHKlq1I.js");
776
+ const { stopAgent } = await import("./agents-FlIgQ3ql.js");
759
777
  await Effect.runPromise(stopAgent(agentId));
760
778
  },
761
779
  catch: () => void 0
762
780
  }).pipe(Effect.ignore),
763
781
  message: (agentId, msg) => Effect.tryPromise({
764
782
  try: async () => {
765
- const { messageAgent } = await import("./agents-DyHKlq1I.js");
783
+ const { messageAgent } = await import("./agents-FlIgQ3ql.js");
766
784
  await messageAgent(agentId, msg);
767
785
  },
768
786
  catch: (err) => new AgentStartError({
@@ -773,8 +791,8 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
773
791
  }),
774
792
  deepWipe: (issueId, opts) => Effect.tryPromise({
775
793
  try: async () => {
776
- const { deepWipe } = await import("./workflows-C4mR0Reb.js");
777
- const { resolveProjectFromIssueSync } = await import("./projects-BKkwpH6q.js");
794
+ const { deepWipe } = await import("./workflows-D90rMOya.js");
795
+ const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
778
796
  const project = resolveProjectFromIssueSync(issueId);
779
797
  const projectPath = project?.projectPath ?? process.cwd();
780
798
  await Effect.runPromise(deepWipe({
@@ -833,8 +851,8 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
833
851
  const { workspacePath, branch } = getWorkspacePath(issueId);
834
852
  const issueLower = issueId.toLowerCase();
835
853
  if (existsSync$1(workspacePath)) return workspacePath;
836
- const { createWorkspace } = await import("./workspace-manager-B1WOfKvB.js");
837
- const { loadProjectsConfigSync } = await import("./projects-BKkwpH6q.js");
854
+ const { createWorkspace } = await import("./workspace-manager-ZTdJAy9M.js");
855
+ const { loadProjectsConfigSync } = await import("./projects-9SkRpES9.js");
838
856
  const { projects } = loadProjectsConfigSync();
839
857
  const project = resolveProjectFromIssueSync(issueId);
840
858
  if (!project) throw new WorkspaceCreateError({
@@ -869,7 +887,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
869
887
  const { workspacePath } = getWorkspacePath(issueId);
870
888
  const issueLower = issueId.toLowerCase();
871
889
  if (!existsSync$1(workspacePath)) throw new WorkspaceNotFound({ id: issueId });
872
- const { removeWorkspace } = await import("./workspace-manager-B1WOfKvB.js");
890
+ const { removeWorkspace } = await import("./workspace-manager-ZTdJAy9M.js");
873
891
  const project = resolveProjectFromIssueSync(issueId);
874
892
  if (!project) throw new WorkspaceCreateError({
875
893
  id: issueId,
@@ -900,7 +918,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
900
918
  try: async () => {
901
919
  const { workspacePath } = getWorkspacePath(issueId);
902
920
  const issueLower = issueId.toLowerCase();
903
- const { stopWorkspaceDocker } = await import("./workspace-manager-B1WOfKvB.js");
921
+ const { stopWorkspaceDocker } = await import("./workspace-manager-ZTdJAy9M.js");
904
922
  await Effect.runPromise(stopWorkspaceDocker(workspacePath, issueLower));
905
923
  },
906
924
  catch: () => void 0
@@ -969,7 +987,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
969
987
  join(workspacePath, ".devcontainer", "docker-compose.devcontainer.yml")
970
988
  ];
971
989
  if (!composePaths.find((p) => existsSync$1(p))) {
972
- const { ensureDevcontainerSync } = await import("./ensure-devcontainer-Cs6W9Yzj.js");
990
+ const { ensureDevcontainerSync } = await import("./ensure-devcontainer-DRqaAkBR.js");
973
991
  const ensure = ensureDevcontainerSync({
974
992
  workspacePath,
975
993
  issueId
@@ -5470,6 +5488,7 @@ init_launcher_generator();
5470
5488
  init_transcript_landing();
5471
5489
  init_operator_interventions();
5472
5490
  init_agents$1();
5491
+ init_runtime_census();
5473
5492
  var marker$2 = "vercel.ai.error";
5474
5493
  var symbol$3 = Symbol.for(marker$2);
5475
5494
  var _a$5, _b$2;
@@ -15949,7 +15968,7 @@ var require_get_vercel_oidc_token = /* @__PURE__ */ __commonJSMin(((exports, mod
15949
15968
  err = error;
15950
15969
  }
15951
15970
  try {
15952
- const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([await import("./token-util-BArZLN6w.js").then((m) => /* @__PURE__ */ __toESM(m.default)), await import("./token-BkQLy4yS.js").then((m) => /* @__PURE__ */ __toESM(m.default))]);
15971
+ const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([await import("./token-util-DrHg8abn.js").then((m) => /* @__PURE__ */ __toESM(m.default)), await import("./token-CsOhvw42.js").then((m) => /* @__PURE__ */ __toESM(m.default))]);
15953
15972
  if (!token || isExpired(getTokenPayload(token), options?.expirationBufferMs)) {
15954
15973
  await refreshToken(options);
15955
15974
  token = getVercelOidcTokenSync();
@@ -28266,7 +28285,7 @@ var GoogleCloudTranscription = class {
28266
28285
  }
28267
28286
  async start(apiKey, model) {
28268
28287
  try {
28269
- const { SpeechClient } = await import("./src-BMMoA_ba.js").then((m) => /* @__PURE__ */ __toESM(m.default, 1)).then((module) => module.v1p1beta1 ?? module.v1);
28288
+ const { SpeechClient } = await import("./src-CG9mCkP6.js").then((m) => /* @__PURE__ */ __toESM(m.default, 1)).then((module) => module.v1p1beta1 ?? module.v1);
28270
28289
  if (this.closed) return;
28271
28290
  const stream = new SpeechClient({ apiKey }).streamingRecognize({
28272
28291
  config: {
@@ -28931,6 +28950,21 @@ function setupAutoPresoWebSocket(server) {
28931
28950
  });
28932
28951
  }
28933
28952
  //#endregion
28953
+ //#region services/agent-output-stream.ts
28954
+ function shouldBroadcastDashboardEvent(event) {
28955
+ return event.type !== "agent.output_received";
28956
+ }
28957
+ /** Dedicated, scoped stream for one agent's ephemeral output. */
28958
+ function streamAgentOutput(eventStore, agentId) {
28959
+ return Stream.unwrap(Effect.acquireRelease(Effect.sync(() => retainAgentOutputInterest(agentId)), (release) => Effect.sync(release)).pipe(Effect.map(() => eventStore.streamEvents.pipe(Stream.filter((event) => event.type === "agent.output_received" && event.payload["agentId"] === agentId), Stream.flatMap((event) => {
28960
+ const payload = event.payload;
28961
+ return Stream.fromIterable(payload.lines.map((line) => ({
28962
+ agentId: payload.agentId,
28963
+ line
28964
+ })));
28965
+ })))));
28966
+ }
28967
+ //#endregion
28934
28968
  //#region services/read-workspace-file.ts
28935
28969
  init_codex_conversation_parser();
28936
28970
  init_ohmypi_conversation_parser();
@@ -28977,7 +29011,7 @@ const LANGUAGE_BY_EXTENSION = {
28977
29011
  function isInsidePath(parent, child) {
28978
29012
  return child === parent || child.startsWith(`${parent}${sep}`);
28979
29013
  }
28980
- function splitLines$1(text) {
29014
+ function splitLines(text) {
28981
29015
  if (text.length === 0) return [];
28982
29016
  const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
28983
29017
  return normalized.endsWith("\n") ? normalized.slice(0, -1).split("\n") : normalized.split("\n");
@@ -28991,7 +29025,7 @@ function validateIntegerAtLeast(value, name, min) {
28991
29025
  return value;
28992
29026
  }
28993
29027
  function selectRequestedLines(text, line, contextLines) {
28994
- const lines = splitLines$1(text);
29028
+ const lines = splitLines(text);
28995
29029
  const totalLines = lines.length;
28996
29030
  if (!line) return {
28997
29031
  text: contextLines === void 0 ? text : lines.slice(0, contextLines).join("\n"),
@@ -29278,7 +29312,6 @@ function normalizeSessionsFeedFilter(input) {
29278
29312
  */
29279
29313
  init_src();
29280
29314
  init_paths();
29281
- init_tmux();
29282
29315
  init_projects();
29283
29316
  function storedToDomainEvent(stored) {
29284
29317
  return {
@@ -29291,7 +29324,8 @@ function storedToDomainEvent(stored) {
29291
29324
  const isKnownDomainEvent = Schema.is(DomainEvent);
29292
29325
  function passesDomainEventSchema(event) {
29293
29326
  if (isKnownDomainEvent(event)) return true;
29294
- console.error(`[ws-rpc] dropping domain event that fails DomainEvent schema validation — add it to the contracts union: type=${event.type} seq=${event.sequence}`);
29327
+ const candidate = event;
29328
+ console.error(`[ws-rpc] dropping domain event that fails DomainEvent schema validation — add it to the contracts union: type=${String(candidate.type)} seq=${String(candidate.sequence)}`);
29295
29329
  return false;
29296
29330
  }
29297
29331
  function createSystemHeartbeatEvent() {
@@ -29662,8 +29696,9 @@ function startSharedPresencePoller() {
29662
29696
  if (sharedPresencePoller.interval) return;
29663
29697
  const tick = async () => {
29664
29698
  try {
29665
- const sessions = await Effect.runPromise(listSessionNames());
29666
- const current = new Set(sessions.filter((s) => s.trim()));
29699
+ const census = await getRuntimeCensus();
29700
+ if (!census.available) return;
29701
+ const current = new Set(census.sessionNames);
29667
29702
  for (const s of sharedPresencePoller.knownSessions) if (!current.has(s)) {
29668
29703
  const issueId = extractIssueIdFromSession(s);
29669
29704
  if (issueId) {
@@ -29727,7 +29762,7 @@ const PanRpcLayer = PanRpcGroup.toLayer(Effect.gen(function* () {
29727
29762
  [WS_METHODS.subscribeDomainEvents]: (_input) => {
29728
29763
  console.log("[ws-rpc] subscribeDomainEvents invoked");
29729
29764
  const heartbeats = Stream.tick("15 seconds").pipe(Stream.map(createSystemHeartbeatEvent));
29730
- return eventStore.streamEvents.pipe(Stream.map(storedToDomainEvent), Stream.filter(passesDomainEventSchema), Stream.merge(heartbeats));
29765
+ return eventStore.streamEvents.pipe(Stream.filter(shouldBroadcastDashboardEvent), Stream.map(storedToDomainEvent), Stream.filter(passesDomainEventSchema), Stream.merge(heartbeats));
29731
29766
  },
29732
29767
  [WS_METHODS.subscribeFlywheelStatus]: (_input) => Stream.callback((queue) => Effect.acquireRelease(Effect.promise(async () => {
29733
29768
  const latest = await readCurrentLatestFlywheelStatus({ activeRunId: await runDashboardDbJob("getSetting", "flywheel.active_run_id") });
@@ -29738,16 +29773,10 @@ const PanRpcLayer = PanRpcGroup.toLayer(Effect.gen(function* () {
29738
29773
  }), (unsubscribe) => Effect.sync(() => unsubscribe()))),
29739
29774
  [WS_METHODS.subscribeIssueEvents]: (input) => {
29740
29775
  console.log(`[ws-rpc] subscribeIssueEvents invoked issueId=${input.issueId}`);
29741
- return eventStore.streamEvents.pipe(Stream.map(storedToDomainEvent), Stream.filter(passesDomainEventSchema), Stream.mapEffect((event) => getCachedAgentIssueLookup(readModel).pipe(Effect.map((lookup) => filterDomainEventForIssue(event, input.issueId, lookup)))), Stream.filter((event) => event !== null));
29776
+ return eventStore.streamEvents.pipe(Stream.filter(shouldBroadcastDashboardEvent), Stream.map(storedToDomainEvent), Stream.filter(passesDomainEventSchema), Stream.mapEffect((event) => getCachedAgentIssueLookup(readModel).pipe(Effect.map((lookup) => filterDomainEventForIssue(event, input.issueId, lookup)))), Stream.filter((event) => event !== null));
29742
29777
  },
29743
29778
  [WS_METHODS.subscribeTerminal]: (input) => terminalService.streamSession(input.sessionName, input.cols, input.rows),
29744
- [WS_METHODS.subscribeAgentOutput]: (input) => eventStore.streamEvents.pipe(Stream.filter((e) => e.type === "agent.output_received" && e.payload["agentId"] === input.agentId), Stream.flatMap((e) => {
29745
- const payload = e.payload;
29746
- return Stream.fromIterable(payload.lines.map((line) => ({
29747
- agentId: payload.agentId,
29748
- line
29749
- })));
29750
- })),
29779
+ [WS_METHODS.subscribeAgentOutput]: (input) => streamAgentOutput(eventStore, input.agentId),
29751
29780
  [WS_METHODS.getSnapshot]: (_input) => Effect.gen(function* () {
29752
29781
  const t0 = Date.now();
29753
29782
  console.log("[ws-rpc] getSnapshot invoked");
@@ -30044,8 +30073,11 @@ const websocketRpcRouteLayer = Layer.unwrap(Effect.gen(function* () {
30044
30073
  }));
30045
30074
  }));
30046
30075
  //#endregion
30047
- //#region ../../lib/vbrief/quality-lint.ts
30076
+ //#region ../../lib/xbrief/quality-lint.ts
30048
30077
  init_internal_token();
30078
+ init_pipeline_notifier();
30079
+ init_review_status_sync();
30080
+ init_review_status();
30049
30081
  init_state_home();
30050
30082
  init_pan_dir();
30051
30083
  init_in_flight_guard();
@@ -30054,7 +30086,7 @@ init_dag();
30054
30086
  init_swarm_readiness();
30055
30087
  var PlanQualityLintError = class extends Error {
30056
30088
  constructor(issues) {
30057
- super(`vBRIEF quality lint failed with ${issues.length} issue${issues.length === 1 ? "" : "s"}`);
30089
+ super(`xBRIEF quality lint failed with ${issues.length} issue${issues.length === 1 ? "" : "s"}`);
30058
30090
  this.issues = issues;
30059
30091
  this.name = "PlanQualityLintError";
30060
30092
  }
@@ -30417,27 +30449,80 @@ function assertPlanQuality(doc, options = {}) {
30417
30449
  return issues;
30418
30450
  }
30419
30451
  //#endregion
30452
+ //#region services/resource-discovery-shared.ts
30453
+ init_conversations();
30454
+ init_runtime_census();
30455
+ const execFileAsync$18 = promisify(execFile);
30456
+ async function loadTrackerIssues() {
30457
+ const map = /* @__PURE__ */ new Map();
30458
+ try {
30459
+ const { getSharedIssueService } = await import("./issue-service-singleton-DabvBWUp.js");
30460
+ const issues = (await getSharedIssueService()).getIssues();
30461
+ for (const issue of issues) if (issue.identifier) map.set(issue.identifier.toUpperCase(), issue);
30462
+ } catch {}
30463
+ return map;
30464
+ }
30465
+ async function loadDockerContainers() {
30466
+ try {
30467
+ const { stdout } = await execFileAsync$18("docker", [
30468
+ "ps",
30469
+ "--format",
30470
+ "{{.Names}}"
30471
+ ], {
30472
+ encoding: "utf-8",
30473
+ timeout: 5e3
30474
+ });
30475
+ return stdout.split("\n").map((line) => line.trim()).filter(Boolean);
30476
+ } catch {
30477
+ return [];
30478
+ }
30479
+ }
30480
+ async function loadActiveRemoteAgentStates() {
30481
+ try {
30482
+ const { listActiveRemoteAgentStates } = await import("./remote-agents-CRCg1L4H.js");
30483
+ return listActiveRemoteAgentStates();
30484
+ } catch {
30485
+ return [];
30486
+ }
30487
+ }
30488
+ async function captureSharedResourceSignals() {
30489
+ const [trackerIssues, runtimeCensus, dockerContainers, remoteAgentStates] = await Promise.all([
30490
+ loadTrackerIssues(),
30491
+ getRuntimeCensus(),
30492
+ loadDockerContainers(),
30493
+ loadActiveRemoteAgentStates()
30494
+ ]);
30495
+ const tmuxSessions = [...runtimeCensus.sessionNames];
30496
+ let conversations = [];
30497
+ try {
30498
+ conversations = listConversations();
30499
+ } catch {}
30500
+ return {
30501
+ trackerIssues,
30502
+ tmuxSessions,
30503
+ dockerContainers,
30504
+ conversations,
30505
+ remoteAgentStates
30506
+ };
30507
+ }
30508
+ //#endregion
30420
30509
  //#region review-status.ts
30421
30510
  init_concurrency$1();
30422
30511
  init_github_app();
30423
30512
  init_resource_utils();
30424
30513
  init_pipeline_membership_gather();
30425
30514
  init_pipeline_membership();
30426
- init_review_status();
30427
30515
  //#endregion
30428
30516
  //#region services/pipeline-membership.ts
30429
- init_pipeline_notifier();
30430
- init_review_status_sync();
30431
30517
  const PIPELINE_MEMBERSHIP_TTL_MS = 3e4;
30432
30518
  function createPipelineMembershipService(deps = {
30433
30519
  gather: gatherProjectLensSignals,
30434
30520
  now: Date.now
30435
30521
  }) {
30436
30522
  const cachedGather = createSettledTtlPromiseCache(PIPELINE_MEMBERSHIP_TTL_MS, deps.now);
30437
- return async (project) => {
30438
- if (!project.github_repo) return [];
30439
- return cachedGather(project.path, () => deps.gather(project).then((signals) => signals.map(resolvePipelineMembership)));
30440
- };
30523
+ const service = async (project) => cachedGather(project.path, () => deps.gather(project).then((signals) => signals.map(resolvePipelineMembership)));
30524
+ service.invalidate = (projectPath) => cachedGather.invalidate(projectPath);
30525
+ return service;
30441
30526
  }
30442
30527
  const getProjectPipelineMembership = createPipelineMembershipService();
30443
30528
  const membershipSnapshots = /* @__PURE__ */ new Map();
@@ -30452,22 +30537,10 @@ function refreshMembershipSnapshot(project, snapshot, getMembership, now) {
30452
30537
  });
30453
30538
  return snapshot.refresh;
30454
30539
  }
30455
- /** Return the latest successful snapshot immediately and refresh stale/missing projects in the background. */
30456
- function getPipelineMembershipSnapshotsForProjects(projects, getMembership = getProjectPipelineMembership, now = Date.now) {
30540
+ /** Read the latest successful snapshots without scheduling tracker or git work. */
30541
+ function readPipelineMembershipSnapshotsForProjects(projects) {
30457
30542
  return projects.map((project) => {
30458
- if (!project.github_repo) return {
30459
- project,
30460
- error: /* @__PURE__ */ new Error("Pipeline membership unavailable: missing github_repo")
30461
- };
30462
30543
  const snapshot = membershipSnapshots.get(project.path);
30463
- if (!snapshot?.refresh && (!snapshot || now() - snapshot.refreshedAt >= 3e5)) {
30464
- const current = snapshot ?? {
30465
- value: [],
30466
- refreshedAt: 0
30467
- };
30468
- membershipSnapshots.set(project.path, current);
30469
- refreshMembershipSnapshot(project, current, getMembership, now);
30470
- }
30471
30544
  return snapshot?.refreshedAt ? {
30472
30545
  project,
30473
30546
  memberships: snapshot.value
@@ -30477,34 +30550,26 @@ function getPipelineMembershipSnapshotsForProjects(projects, getMembership = get
30477
30550
  };
30478
30551
  });
30479
30552
  }
30480
- /** Await only the first snapshot; later resource refreshes consume stale data while revalidating. */
30481
- async function getPipelineMembershipSnapshotsForResourceDiscovery(projects, getMembership = getProjectPipelineMembership, now = Date.now) {
30482
- return Promise.all(projects.map(async (project) => {
30483
- if (!project.github_repo) return {
30484
- project,
30485
- error: /* @__PURE__ */ new Error("Pipeline membership unavailable: missing github_repo")
30486
- };
30487
- const existing = membershipSnapshots.get(project.path);
30488
- if (existing?.refreshedAt) {
30489
- if (now() - existing.refreshedAt >= 3e5) refreshMembershipSnapshot(project, existing, getMembership, now);
30490
- return {
30491
- project,
30492
- memberships: existing.value
30493
- };
30494
- }
30495
- const snapshot = existing ?? {
30553
+ /**
30554
+ * PAN-2893 — event-driven refresh. Invalidate the per-project TTL cache and
30555
+ * force a snapshot re-gather NOW for the given projects, so agent lifecycle
30556
+ * changes reach membership consumers without waiting out the 5-minute TTL.
30557
+ * Refresh failures keep the last good snapshot (same policy as TTL refreshes).
30558
+ */
30559
+ async function refreshMembershipSnapshotsForProjects(projects, getMembership = getProjectPipelineMembership, now = Date.now) {
30560
+ await Promise.all(projects.map(async (project) => {
30561
+ getMembership.invalidate(project.path);
30562
+ const snapshot = membershipSnapshots.get(project.path) ?? {
30496
30563
  value: [],
30497
30564
  refreshedAt: 0
30498
30565
  };
30499
30566
  membershipSnapshots.set(project.path, snapshot);
30567
+ const inFlight = snapshot.refresh;
30568
+ if (inFlight) {
30569
+ await inFlight;
30570
+ getMembership.invalidate(project.path);
30571
+ }
30500
30572
  await refreshMembershipSnapshot(project, snapshot, getMembership, now);
30501
- return snapshot.refreshedAt ? {
30502
- project,
30503
- memberships: snapshot.value
30504
- } : {
30505
- project,
30506
- error: /* @__PURE__ */ new Error("Pipeline membership snapshot failed to load")
30507
- };
30508
30573
  }));
30509
30574
  }
30510
30575
  function summarizePipelineMembership(membership) {
@@ -30526,17 +30591,14 @@ function unavailablePipelineMembership() {
30526
30591
  //#endregion
30527
30592
  //#region services/resource-discovery.ts
30528
30593
  init_src();
30529
- init_conversations();
30530
30594
  init_projects();
30531
30595
  init_pipeline_membership();
30532
30596
  init_pipeline_membership_gather();
30533
- init_tmux();
30534
- const execFileAsync$18 = promisify(execFile);
30535
- const RESOURCE_DISCOVERY_TTL_MS = 3e4;
30597
+ const execFileAsync$17 = promisify(execFile);
30536
30598
  const RECENT_ACTIVITY_WINDOW_MS = 5e3;
30599
+ const projectResourceSnapshots = /* @__PURE__ */ new Map();
30537
30600
  let cachedResourceIssues = null;
30538
30601
  let cachedDetailedResourceIssues = null;
30539
- let resourceIssuesRefreshPromise = null;
30540
30602
  function projectPrefixes(project) {
30541
30603
  const prefixes = /* @__PURE__ */ new Set();
30542
30604
  if (project.config.issue_prefix) prefixes.add(project.config.issue_prefix.toUpperCase());
@@ -30576,7 +30638,7 @@ function summarizeResourceDetails(details) {
30576
30638
  state: pr.state,
30577
30639
  isDraft: pr.isDraft
30578
30640
  })),
30579
- hasVbrief: details.vbriefPath !== null,
30641
+ hasXbrief: details.xbriefPath !== null,
30580
30642
  hasTasks: details.tasksPath !== null,
30581
30643
  dockerContainerCount: details.dockerContainers.length,
30582
30644
  actualBranch: details.actualBranch,
@@ -30643,46 +30705,6 @@ const DISCOVERABLE_SESSION_PREFIXES = [
30643
30705
  function isDiscoverableAgentSession(sessionName) {
30644
30706
  return DISCOVERABLE_SESSION_PREFIXES.some((prefix) => sessionName.startsWith(prefix));
30645
30707
  }
30646
- async function loadTrackerIssues() {
30647
- const map = /* @__PURE__ */ new Map();
30648
- try {
30649
- const { getSharedIssueService } = await import("./issue-service-singleton-DBZabEl7.js");
30650
- const issues = (await getSharedIssueService()).getIssues();
30651
- for (const issue of issues) if (issue.identifier) map.set(issue.identifier.toUpperCase(), issue);
30652
- } catch {
30653
- return map;
30654
- }
30655
- return map;
30656
- }
30657
- async function loadTmuxSessions() {
30658
- try {
30659
- return (await Effect.runPromise(listSessionNames())).map((name) => name.trim()).filter(Boolean);
30660
- } catch {
30661
- return [];
30662
- }
30663
- }
30664
- function loadConversations() {
30665
- try {
30666
- return listConversations();
30667
- } catch {
30668
- return [];
30669
- }
30670
- }
30671
- async function loadDockerContainers() {
30672
- try {
30673
- const { stdout } = await execFileAsync$18("docker", [
30674
- "ps",
30675
- "--format",
30676
- "{{.Names}}"
30677
- ], {
30678
- encoding: "utf-8",
30679
- timeout: 5e3
30680
- });
30681
- return stdout.split("\n").map((line) => line.trim()).filter(Boolean);
30682
- } catch {
30683
- return [];
30684
- }
30685
- }
30686
30708
  async function loadOpenPullRequests(projects) {
30687
30709
  const pullRequests = /* @__PURE__ */ new Map();
30688
30710
  await Promise.all(projects.map(async (project) => {
@@ -30713,80 +30735,31 @@ async function loadOpenPullRequests(projects) {
30713
30735
  for (const [issueId, prs] of pullRequests) pullRequests.set(issueId, sortPullRequests(prs));
30714
30736
  return pullRequests;
30715
30737
  }
30716
- async function loadProjectBranches(projectPath) {
30717
- try {
30718
- const [localFeature, remoteFeature, localBypass, remoteBypass] = await Promise.all([
30719
- execFileAsync$18("git", [
30720
- "for-each-ref",
30721
- "refs/heads/feature/*",
30722
- "--format=%(refname:short)"
30723
- ], {
30724
- cwd: projectPath,
30725
- encoding: "utf-8",
30726
- timeout: 1e4
30727
- }).catch(() => ({ stdout: "" })),
30728
- execFileAsync$18("git", [
30729
- "for-each-ref",
30730
- "refs/remotes/origin/feature/*",
30731
- "--format=%(refname:short)"
30732
- ], {
30733
- cwd: projectPath,
30734
- encoding: "utf-8",
30735
- timeout: 1e4
30736
- }).catch(() => ({ stdout: "" })),
30737
- execFileAsync$18("git", [
30738
- "for-each-ref",
30739
- "refs/heads/bypass/*",
30740
- "--format=%(refname:short)"
30741
- ], {
30742
- cwd: projectPath,
30743
- encoding: "utf-8",
30744
- timeout: 1e4
30745
- }).catch(() => ({ stdout: "" })),
30746
- execFileAsync$18("git", [
30747
- "for-each-ref",
30748
- "refs/remotes/origin/bypass/*",
30749
- "--format=%(refname:short)"
30750
- ], {
30751
- cwd: projectPath,
30752
- encoding: "utf-8",
30753
- timeout: 1e4
30754
- }).catch(() => ({ stdout: "" }))
30755
- ]);
30756
- return {
30757
- local: [...localFeature.stdout.split("\n").map((line) => line.trim()).filter(Boolean), ...localBypass.stdout.split("\n").map((line) => line.trim()).filter(Boolean)],
30758
- remote: [...remoteFeature.stdout.split("\n").map((line) => line.trim()).filter(Boolean), ...remoteBypass.stdout.split("\n").map((line) => line.trim()).filter(Boolean)]
30759
- };
30760
- } catch {
30761
- return {
30762
- local: [],
30763
- remote: []
30764
- };
30765
- }
30766
- }
30767
- async function loadBranchesAheadOfMain(projectPath) {
30768
- const ahead = /* @__PURE__ */ new Set();
30769
- const run = async (patterns) => {
30770
- if (patterns.length === 0) return;
30771
- try {
30772
- const { stdout } = await execFileAsync$18("git", [
30773
- "for-each-ref",
30774
- "--format=%(refname:short)",
30775
- ...patterns,
30776
- "--no-merged=main"
30777
- ], {
30778
- cwd: projectPath,
30779
- encoding: "utf-8",
30780
- timeout: 1e4
30781
- });
30782
- for (const line of stdout.split("\n")) {
30783
- const branch = line.trim();
30784
- if (branch) ahead.add(branch);
30785
- }
30786
- } catch {}
30738
+ const PROJECT_BRANCH_PATTERNS = [
30739
+ "refs/heads/feature/*",
30740
+ "refs/remotes/origin/feature/*",
30741
+ "refs/heads/bypass/*",
30742
+ "refs/remotes/origin/bypass/*"
30743
+ ];
30744
+ async function loadProjectBranchSnapshot(projectPath) {
30745
+ const run = (extraArgs = []) => execFileAsync$17("git", [
30746
+ "for-each-ref",
30747
+ "--format=%(refname:short)",
30748
+ ...extraArgs,
30749
+ ...PROJECT_BRANCH_PATTERNS
30750
+ ], {
30751
+ cwd: projectPath,
30752
+ encoding: "utf-8",
30753
+ timeout: 1e4
30754
+ }).catch(() => ({ stdout: "" }));
30755
+ const [allRefs, unmergedRefs] = await Promise.all([run(), run(["--no-merged=main"])]);
30756
+ const branches = allRefs.stdout.split("\n").map((line) => line.trim()).filter(Boolean);
30757
+ const ahead = new Set(unmergedRefs.stdout.split("\n").map((line) => line.trim()).filter(Boolean));
30758
+ return {
30759
+ local: branches.filter((branch) => !branch.startsWith("origin/")),
30760
+ remote: branches.filter((branch) => branch.startsWith("origin/")),
30761
+ ahead
30787
30762
  };
30788
- await Promise.all([run(["refs/heads/feature/*", "refs/heads/bypass/*"]), run(["refs/remotes/origin/feature/*", "refs/remotes/origin/bypass/*"])]);
30789
- return ahead;
30790
30763
  }
30791
30764
  async function scanWorkspace(workspacesDir, workspaceName) {
30792
30765
  const workspacePath = join(workspacesDir, workspaceName);
@@ -30796,46 +30769,43 @@ async function scanWorkspace(workspacesDir, workspaceName) {
30796
30769
  const issueMatch = workspaceName.match(/^feature-([a-z]+-\d+)$/i);
30797
30770
  const issueId = issueMatch ? issueMatch[1].toUpperCase() : null;
30798
30771
  const specEntry = issueId ? await Effect.runPromise(findSpecByIssue(projectRoot, issueId)).catch(() => null) : null;
30799
- const vbriefPath = specEntry ? specEntry.path : null;
30800
- let vbriefMtime = null;
30801
- if (vbriefPath) try {
30802
- vbriefMtime = (await stat$1(vbriefPath)).mtimeMs;
30772
+ const xbriefPath = specEntry ? specEntry.path : null;
30773
+ let xbriefMtime = null;
30774
+ if (xbriefPath) try {
30775
+ xbriefMtime = (await stat$1(xbriefPath)).mtimeMs;
30803
30776
  } catch {
30804
- vbriefMtime = null;
30777
+ xbriefMtime = null;
30805
30778
  }
30806
30779
  return {
30807
30780
  workspacePath,
30808
30781
  hasPlanning: workspaceEntries.has(PAN_DIRNAME),
30809
30782
  hasPrd: panEntries.has("prd.md"),
30810
30783
  hasState: panEntries.has(PAN_CONTINUE_FILENAME),
30811
- hasVbrief: vbriefPath !== null,
30812
- vbriefPath,
30813
- vbriefMtime,
30814
- hasTasks: vbriefPath !== null
30784
+ hasXbrief: xbriefPath !== null,
30785
+ xbriefPath,
30786
+ xbriefMtime,
30787
+ hasTasks: xbriefPath !== null
30815
30788
  };
30816
30789
  }
30817
- async function computeResourceAllocatedIssues() {
30818
- const projects = listProjectsSync();
30819
- const [trackerIssues, tmuxSessions, dockerContainers, pullRequests] = await Promise.all([
30820
- loadTrackerIssues(),
30821
- loadTmuxSessions(),
30822
- loadDockerContainers(),
30823
- loadOpenPullRequests(projects)
30824
- ]);
30790
+ async function computeResourceAllocatedIssues(projectConfigs, sharedSignals) {
30791
+ const registeredProjects = listProjectsSync();
30792
+ const projects = projectConfigs.map((config) => registeredProjects.find((entry) => entry.config.path === config.path) ?? {
30793
+ key: config.name ?? config.path,
30794
+ config
30795
+ });
30796
+ const { trackerIssues, tmuxSessions, dockerContainers, conversations, remoteAgentStates } = sharedSignals ?? await captureSharedResourceSignals();
30797
+ const pullRequests = await loadOpenPullRequests(projects);
30825
30798
  const issueMap = /* @__PURE__ */ new Map();
30826
30799
  const projectByPrefix = /* @__PURE__ */ new Map();
30827
30800
  for (const project of projects) for (const prefix of projectPrefixes(project)) projectByPrefix.set(prefix, project);
30828
- const projectRefFromResolved = (resolvedProject) => ({
30829
- key: resolvedProject.projectKey,
30830
- config: {
30831
- name: resolvedProject.projectName,
30832
- path: resolvedProject.projectPath
30833
- }
30834
- });
30801
+ const projectRefFromResolved = (resolvedProject) => projects.find((project) => project.key === resolvedProject.projectKey || project.config.path === resolvedProject.projectPath) ?? null;
30835
30802
  const resolveProjectRef = (issueId, preferredProject) => {
30836
30803
  if (preferredProject) return preferredProject;
30837
30804
  const resolvedProject = resolveProjectFromIssueSync(issueId);
30838
- if (resolvedProject) return projectRefFromResolved(resolvedProject);
30805
+ if (resolvedProject) {
30806
+ const project = projectRefFromResolved(resolvedProject);
30807
+ if (project) return project;
30808
+ }
30839
30809
  const prefix = issueId.toUpperCase().match(/^([A-Z]+)-\d+$/)?.[1] ?? "";
30840
30810
  return projectByPrefix.get(prefix) ?? null;
30841
30811
  };
@@ -30868,8 +30838,8 @@ async function computeResourceAllocatedIssues() {
30868
30838
  localBranches: [],
30869
30839
  remoteBranches: [],
30870
30840
  prs: [],
30871
- vbriefPath: null,
30872
- vbriefMtime: null,
30841
+ xbriefPath: null,
30842
+ xbriefMtime: null,
30873
30843
  tasksPath: null,
30874
30844
  dockerContainers: [],
30875
30845
  actualBranch: null,
@@ -30902,7 +30872,6 @@ async function computeResourceAllocatedIssues() {
30902
30872
  issue.resourceSources.add("tmux");
30903
30873
  if (!issue.resourceDetails.tmuxSessions.includes(sessionName)) issue.resourceDetails.tmuxSessions.push(sessionName);
30904
30874
  }
30905
- const conversations = loadConversations();
30906
30875
  for (const conv of conversations) {
30907
30876
  if (!conv.issueId || conv.archivedAt) continue;
30908
30877
  const issue = ensureIssue(conv.issueId);
@@ -30916,21 +30885,18 @@ async function computeResourceAllocatedIssues() {
30916
30885
  tmuxSession: conv.tmuxSession
30917
30886
  });
30918
30887
  }
30919
- try {
30920
- const { listActiveRemoteAgentStates } = await import("./remote-agents-D6O_zETW.js");
30921
- for (const remoteState of listActiveRemoteAgentStates()) {
30922
- const issue = ensureIssue(remoteState.issueId);
30923
- if (!issue) continue;
30924
- issue.resourceSources.add("remote-agent");
30925
- issue.resourceDetails.remoteAgent = {
30926
- vmName: remoteState.vmName,
30927
- status: remoteState.status,
30928
- model: remoteState.model,
30929
- startedAt: remoteState.startedAt
30930
- };
30931
- if (!issue.agentStatus) issue.agentStatus = "active";
30932
- }
30933
- } catch {}
30888
+ for (const remoteState of remoteAgentStates) {
30889
+ const issue = ensureIssue(remoteState.issueId);
30890
+ if (!issue) continue;
30891
+ issue.resourceSources.add("remote-agent");
30892
+ issue.resourceDetails.remoteAgent = {
30893
+ vmName: remoteState.vmName,
30894
+ status: remoteState.status,
30895
+ model: remoteState.model,
30896
+ startedAt: remoteState.startedAt
30897
+ };
30898
+ if (!issue.agentStatus) issue.agentStatus = "active";
30899
+ }
30934
30900
  for (const containerName of dockerContainers) {
30935
30901
  const issueId = parseIssueIdFromTextSync(containerName.replace(/feature\//g, "feature-"));
30936
30902
  if (!issueId) continue;
@@ -30942,8 +30908,7 @@ async function computeResourceAllocatedIssues() {
30942
30908
  await Promise.all(projects.map(async (project) => {
30943
30909
  const projectPath = project.config.path;
30944
30910
  const workspacesDir = join(projectPath, "workspaces");
30945
- const [workspaceEntries, branches] = await Promise.all([readdir(workspacesDir, { withFileTypes: true }).catch(() => []), loadProjectBranches(projectPath)]);
30946
- const aheadBranches = await loadBranchesAheadOfMain(projectPath);
30911
+ const [workspaceEntries, branches] = await Promise.all([readdir(workspacesDir, { withFileTypes: true }).catch(() => []), loadProjectBranchSnapshot(projectPath)]);
30947
30912
  await Promise.all(workspaceEntries.map(async (entry) => {
30948
30913
  if (!entry.isDirectory() || !entry.name.startsWith("feature-")) return;
30949
30914
  const issue = ensureIssue(entry.name.replace(/^feature-/, "").toUpperCase(), project);
@@ -30954,10 +30919,10 @@ async function computeResourceAllocatedIssues() {
30954
30919
  issue.hasPlanning = workspace.hasPlanning;
30955
30920
  issue.hasPrd = workspace.hasPrd;
30956
30921
  issue.hasState = workspace.hasState;
30957
- if (workspace.vbriefPath) {
30922
+ if (workspace.xbriefPath) {
30958
30923
  issue.resourceSources.add("vbrief");
30959
- issue.resourceDetails.vbriefPath = workspace.vbriefPath;
30960
- issue.resourceDetails.vbriefMtime = workspace.vbriefMtime;
30924
+ issue.resourceDetails.xbriefPath = workspace.xbriefPath;
30925
+ issue.resourceDetails.xbriefMtime = workspace.xbriefMtime;
30961
30926
  }
30962
30927
  if (workspace.hasTasks) {
30963
30928
  issue.resourceSources.add("tasks");
@@ -30975,7 +30940,7 @@ async function computeResourceAllocatedIssues() {
30975
30940
  if (!issue) continue;
30976
30941
  issue.resourceSources.add("branch");
30977
30942
  if (!issue.resourceDetails[key].includes(branch)) issue.resourceDetails[key].push(branch);
30978
- if (aheadBranches.has(branch)) issue.resourceDetails.branchAheadOfMain = true;
30943
+ if (branches.ahead.has(branch)) issue.resourceDetails.branchAheadOfMain = true;
30979
30944
  }
30980
30945
  }));
30981
30946
  for (const [issueId, prs] of pullRequests) {
@@ -31000,14 +30965,18 @@ async function computeResourceAllocatedIssues() {
31000
30965
  for (const issue of issueMap.values()) issue.readyForMerge = readyForMergeFlags.get(issue.issueId) ?? false;
31001
30966
  }
31002
30967
  const memberships = /* @__PURE__ */ new Map();
31003
- const projectMemberships = await getPipelineMembershipSnapshotsForResourceDiscovery(projects.map((project) => project.config));
31004
- for (const result of projectMemberships) for (const membership of result.memberships ?? []) {
31005
- ensureIssue(membership.issueId);
31006
- memberships.set(membership.issueId, membership);
30968
+ const unavailableProjects = /* @__PURE__ */ new Set();
30969
+ const projectMemberships = readPipelineMembershipSnapshotsForProjects(projects.map((project) => project.config));
30970
+ for (const result of projectMemberships) {
30971
+ if (result.error) unavailableProjects.add(result.project.name);
30972
+ for (const membership of result.memberships ?? []) {
30973
+ ensureIssue(membership.issueId);
30974
+ memberships.set(membership.issueId, membership);
30975
+ }
31007
30976
  }
31008
30977
  return [...issueMap.values()].filter((issue) => issue.resourceSources.size > 0).filter((issue) => {
31009
30978
  const membership = memberships.get(issue.issueId);
31010
- return membership?.inPipeline === true || membership?.bucket === "clean_terminal" && isLiveResource(issue);
30979
+ return membership?.inPipeline === true || membership?.bucket === "clean_terminal" && isLiveResource(issue) || !membership && unavailableProjects.has(issue.projectName) && isLiveResource(issue);
31011
30980
  }).map((issue) => {
31012
30981
  const membership = memberships.get(issue.issueId);
31013
30982
  const hasTmux = issue.resourceDetails.tmuxSessions.length > 0;
@@ -31036,9 +31005,9 @@ async function computeResourceAllocatedIssues() {
31036
31005
  resourceSources: new Set([...issue.resourceSources].sort()),
31037
31006
  resourceDetails: issue.resourceDetails,
31038
31007
  taskTotals: issue.taskTotals,
31039
- pipelineBucket: membership.bucket,
31040
- specOnlyPlanned: membership.bucket === "planned_backlog" && membership.reasons.includes("open issue with a vBRIEF spec but no branch/PR — planned work whose plan encodes code paths that age; needs starting or re-planning"),
31041
- resourceDrift: !membership.inPipeline
31008
+ pipelineBucket: membership?.bucket,
31009
+ specOnlyPlanned: membership ? membership.bucket === "planned_backlog" && membership.reasons.includes("open issue with an xBRIEF spec but no branch/PR — planned work whose plan encodes code paths that age; needs starting or re-planning") : void 0,
31010
+ resourceDrift: membership ? !membership.inPipeline : void 0
31042
31011
  };
31043
31012
  }).sort((a, b) => compareIssueIds(a.issueId, b.issueId));
31044
31013
  }
@@ -31049,28 +31018,42 @@ function toPublicResourceIssue(issue) {
31049
31018
  resourceDetails: summarizeResourceDetails(issue.resourceDetails)
31050
31019
  };
31051
31020
  }
31052
- function refreshResourceAllocatedIssues() {
31053
- if (resourceIssuesRefreshPromise) return resourceIssuesRefreshPromise;
31054
- resourceIssuesRefreshPromise = computeResourceAllocatedIssues().then((issues) => {
31055
- cachedDetailedResourceIssues = issues;
31056
- const publicIssues = issues.map(toPublicResourceIssue);
31057
- cachedResourceIssues = {
31058
- value: publicIssues,
31059
- computedAt: Date.now()
31060
- };
31061
- return publicIssues;
31062
- }).finally(() => {
31063
- resourceIssuesRefreshPromise = null;
31021
+ function rebuildCombinedResourceSnapshot() {
31022
+ const detailed = [...projectResourceSnapshots.values()].flatMap((snapshot) => snapshot.detailed).sort((a, b) => compareIssueIds(a.issueId, b.issueId));
31023
+ const publicIssues = detailed.map(toPublicResourceIssue);
31024
+ cachedDetailedResourceIssues = detailed;
31025
+ cachedResourceIssues = {
31026
+ value: publicIssues,
31027
+ computedAt: Math.max(0, ...[...projectResourceSnapshots.values()].map((snapshot) => snapshot.computedAt))
31028
+ };
31029
+ return publicIssues;
31030
+ }
31031
+ function publishProjectResourceSnapshot(project, issues) {
31032
+ projectResourceSnapshots.set(project.path, {
31033
+ detailed: issues,
31034
+ public: issues.map(toPublicResourceIssue),
31035
+ computedAt: Date.now()
31064
31036
  });
31065
- return resourceIssuesRefreshPromise;
31037
+ rebuildCombinedResourceSnapshot();
31066
31038
  }
31067
- async function getCachedResourceAllocatedIssues() {
31068
- if (cachedResourceIssues && Date.now() - cachedResourceIssues.computedAt < RESOURCE_DISCOVERY_TTL_MS) return cachedResourceIssues.value;
31069
- if (cachedResourceIssues) {
31070
- refreshResourceAllocatedIssues().catch(() => {});
31071
- return cachedResourceIssues.value;
31039
+ /** Refresh only the requested projects, capturing fleet-wide signals once for the batch. */
31040
+ async function refreshResourceAllocatedProjects(projects, options = {}) {
31041
+ if (projects.length === 0) return cachedResourceIssues?.value ?? [];
31042
+ const sharedSignals = await captureSharedResourceSignals();
31043
+ const failures = [];
31044
+ for (const project of projects) try {
31045
+ if (options.refreshMembership !== false) await refreshMembershipSnapshotsForProjects([project]);
31046
+ publishProjectResourceSnapshot(project, await computeResourceAllocatedIssues([project], sharedSignals));
31047
+ } catch (error) {
31048
+ const failure = error instanceof Error ? error : new Error(String(error));
31049
+ failures.push(failure);
31050
+ console.warn(`[resource-discovery] refresh failed for ${project.name ?? project.path}; keeping last-good snapshot:`, failure.message);
31072
31051
  }
31073
- return refreshResourceAllocatedIssues();
31052
+ if (failures.length > 0) throw new AggregateError(failures, `${failures.length} project resource refresh(es) failed`);
31053
+ return cachedResourceIssues?.value ?? [];
31054
+ }
31055
+ async function getCachedResourceAllocatedIssues() {
31056
+ return cachedResourceIssues?.value ?? [];
31074
31057
  }
31075
31058
  function sanitizeResourceAllocatedIssues(issues) {
31076
31059
  return issues.map((issue) => ({
@@ -31086,7 +31069,7 @@ function sanitizeResourceAllocatedIssues(issues) {
31086
31069
  state: pr.state,
31087
31070
  isDraft: pr.isDraft
31088
31071
  })),
31089
- hasVbrief: issue.resourceDetails.hasVbrief,
31072
+ hasXbrief: issue.resourceDetails.hasXbrief,
31090
31073
  hasTasks: issue.resourceDetails.hasTasks,
31091
31074
  dockerContainerCount: issue.resourceDetails.dockerContainerCount,
31092
31075
  actualBranch: issue.resourceDetails.actualBranch,
@@ -31109,10 +31092,7 @@ function toPublicResourceDetailIdentifiers(details) {
31109
31092
  async function getResourceDetailIdentifiers(issueId) {
31110
31093
  const normalizedIssueId = issueId.toUpperCase();
31111
31094
  const cachedMatch = cachedDetailedResourceIssues?.find((entry) => entry.issueId === normalizedIssueId);
31112
- if (cachedMatch) return toPublicResourceDetailIdentifiers(cachedMatch.resourceDetails);
31113
- await refreshResourceAllocatedIssues();
31114
- const refreshedMatch = cachedDetailedResourceIssues?.find((entry) => entry.issueId === normalizedIssueId);
31115
- return refreshedMatch ? toPublicResourceDetailIdentifiers(refreshedMatch.resourceDetails) : null;
31095
+ return cachedMatch ? toPublicResourceDetailIdentifiers(cachedMatch.resourceDetails) : null;
31116
31096
  }
31117
31097
  function groupResourceAllocatedIssuesByProject(issues) {
31118
31098
  const projectTree = /* @__PURE__ */ new Map();
@@ -31316,7 +31296,7 @@ function getIssueTasks(id) {
31316
31296
  };
31317
31297
  });
31318
31298
  const doc = workspacePath ? readWorkspacePlanSync(workspacePath) : null;
31319
- if (!doc) return jsonResponse({ error: `The vBRIEF for ${id} is missing or unreadable.` }, { status: 404 });
31299
+ if (!doc) return jsonResponse({ error: `The xBRIEF for ${id} is missing or unreadable.` }, { status: 404 });
31320
31300
  const record = projectPath ? readIssueRecordSync({
31321
31301
  name: resolvedProject?.projectName ?? id,
31322
31302
  path: projectPath
@@ -31409,11 +31389,12 @@ init_tracker_config();
31409
31389
  init_agents$1();
31410
31390
  init_pan_dir();
31411
31391
  init_projects();
31392
+ init_review_status();
31412
31393
  init_remote_agents();
31413
31394
  init_tracker_utils();
31414
31395
  init_tmux();
31415
31396
  init_io();
31416
- const execFileAsync$17 = promisify(execFile);
31397
+ const execFileAsync$16 = promisify(execFile);
31417
31398
  function getIssueDataService$9() {
31418
31399
  return getSharedIssueService();
31419
31400
  }
@@ -31470,12 +31451,12 @@ async function completePlanningArtifacts(options) {
31470
31451
  const workspacePlanPath = await Effect.runPromise(Effect.gen(function* () {
31471
31452
  return (yield* findWorkspaceDraftPlan(workspacePath)) ?? (yield* findPlan(workspacePath));
31472
31453
  }));
31473
- if (!workspacePlanPath) throw new Error(`No workspace vBRIEF found for ${upperIssueId} at ${workspacePath}/.pan/spec.vbrief.json`);
31454
+ if (!workspacePlanPath) throw new Error(`No workspace xBRIEF found for ${upperIssueId} at ${workspacePath}/.overdeck/spec.vbrief.json`);
31474
31455
  const workspaceDoc = await Effect.runPromise(readPlan(workspacePlanPath));
31475
31456
  const workspaceIssueId = workspaceDoc.plan?.id;
31476
- if (workspaceIssueId && workspaceIssueId.toLowerCase() !== issueLower) throw new Error(`Workspace vBRIEF is for ${workspaceIssueId.toUpperCase()}, not ${upperIssueId}`);
31457
+ if (workspaceIssueId && workspaceIssueId.toLowerCase() !== issueLower) throw new Error(`Workspace xBRIEF is for ${workspaceIssueId.toUpperCase()}, not ${upperIssueId}`);
31477
31458
  assertPlanQuality(workspaceDoc);
31478
- emitCompletePlanningPhase(upperIssueId, "specWrite", "start", "writing proposed vBRIEF spec", { projectPath });
31459
+ emitCompletePlanningPhase(upperIssueId, "specWrite", "start", "writing proposed xBRIEF spec", { projectPath });
31479
31460
  const existingSpec = await Effect.runPromise(findSpecByIssue(projectPath, upperIssueId));
31480
31461
  let proposed;
31481
31462
  try {
@@ -31490,7 +31471,7 @@ async function completePlanningArtifacts(options) {
31490
31471
  path: e.path,
31491
31472
  filename: e.filename
31492
31473
  }));
31493
- emitCompletePlanningPhase(upperIssueId, "specWrite", "success", "proposed vBRIEF spec written", {
31474
+ emitCompletePlanningPhase(upperIssueId, "specWrite", "success", "proposed xBRIEF spec written", {
31494
31475
  path: proposed.path,
31495
31476
  filename: proposed.filename
31496
31477
  });
@@ -31499,7 +31480,7 @@ async function completePlanningArtifacts(options) {
31499
31480
  throw error;
31500
31481
  }
31501
31482
  const planItemCount = workspaceDoc.plan.items?.length ?? 0;
31502
- if (planItemCount === 0) throw new Error(`The vBRIEF for ${upperIssueId} contains no implementation items.`);
31483
+ if (planItemCount === 0) throw new Error(`The xBRIEF for ${upperIssueId} contains no implementation items.`);
31503
31484
  return {
31504
31485
  proposed,
31505
31486
  taskCount: planItemCount,
@@ -31539,7 +31520,7 @@ async function commitWorkspaceRecordBeforeAutoSpawn(gitRoot, issueId) {
31539
31520
  } catch {}
31540
31521
  const recordPath = join(".pan", "records", `${issueLower}.json`);
31541
31522
  try {
31542
- const { stdout: statusOut } = await execFileAsync$17("git", [
31523
+ const { stdout: statusOut } = await execFileAsync$16("git", [
31543
31524
  "status",
31544
31525
  "--porcelain",
31545
31526
  "--",
@@ -31549,7 +31530,7 @@ async function commitWorkspaceRecordBeforeAutoSpawn(gitRoot, issueId) {
31549
31530
  encoding: "utf-8"
31550
31531
  });
31551
31532
  if (!statusOut.trim()) return;
31552
- await execFileAsync$17("git", [
31533
+ await execFileAsync$16("git", [
31553
31534
  "add",
31554
31535
  "--",
31555
31536
  recordPath
@@ -31558,7 +31539,7 @@ async function commitWorkspaceRecordBeforeAutoSpawn(gitRoot, issueId) {
31558
31539
  encoding: "utf-8"
31559
31540
  });
31560
31541
  try {
31561
- await execFileAsync$17("git", [
31542
+ await execFileAsync$16("git", [
31562
31543
  "diff",
31563
31544
  "--cached",
31564
31545
  "--quiet",
@@ -31570,7 +31551,7 @@ async function commitWorkspaceRecordBeforeAutoSpawn(gitRoot, issueId) {
31570
31551
  });
31571
31552
  return;
31572
31553
  } catch {}
31573
- await execFileAsync$17("git", [
31554
+ await execFileAsync$16("git", [
31574
31555
  "commit",
31575
31556
  "-m",
31576
31557
  `chore(records): update ${issueId.toUpperCase()} per-issue record before auto-start`,
@@ -31602,6 +31583,33 @@ function classifyAutoSpawnSkip(status, body) {
31602
31583
  function resolveCompletePlanningTerminalStatus(autoSpawnRequested, autoSpawnResult) {
31603
31584
  return autoSpawnRequested && autoSpawnResult?.workAgentSpawned !== true ? "failure" : "success";
31604
31585
  }
31586
+ async function recordPlanningAutoHandoffFailure(options) {
31587
+ const skipReason = options.result.workAgentSkipReason ?? "spawn-failed";
31588
+ const error = options.result.workAgentError ?? `Work agent startup failed: ${skipReason}`;
31589
+ const details = {
31590
+ workAgentSkipReason: skipReason,
31591
+ workAgentError: error
31592
+ };
31593
+ await Effect.runPromise(options.eventStore.append({
31594
+ type: "planning.failed",
31595
+ timestamp: (options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString()))(),
31596
+ payload: {
31597
+ issueId: options.issueId,
31598
+ error,
31599
+ stage: "auto-handoff",
31600
+ ...details
31601
+ }
31602
+ }));
31603
+ (options.markStuck ?? markWorkspaceStuck)(options.issueId, "planning_auto_handoff_failed", details);
31604
+ (options.emitActivity ?? emitActivityEntrySync)({
31605
+ source: "plan",
31606
+ level: "error",
31607
+ message: `${options.issueId} planning complete, but work-agent startup failed: ${error}`,
31608
+ issueId: options.issueId,
31609
+ details: JSON.stringify(details)
31610
+ });
31611
+ return error;
31612
+ }
31605
31613
  async function completePlanningAutoSpawn(options) {
31606
31614
  if (options.autoSpawn !== true) {
31607
31615
  emitCompletePlanningPhase(options.issueId, "autoSpawn", "skipped", "autoSpawn not requested");
@@ -31784,6 +31792,19 @@ async function completePlanningForIssue(options) {
31784
31792
  }
31785
31793
  emitCompletePlanningPhase(id, "prdGate", "success", `found ${prdGate.path} (${prdGate.lineCount} lines)`);
31786
31794
  }
31795
+ try {
31796
+ const draftPromotion = await Effect.runPromise(promoteWorkspacePrdDraft({
31797
+ projectRoot: projectPath,
31798
+ workspacePath,
31799
+ issueId: id
31800
+ }));
31801
+ if (draftPromotion.promoted) emitCompletePlanningPhase(id, "prdPromote", "success", `promoted ${draftPromotion.source} -> ${draftPromotion.path}`);
31802
+ else emitCompletePlanningPhase(id, "prdPromote", "skipped", draftPromotion.reason);
31803
+ } catch (error) {
31804
+ const reason = error instanceof Error ? error.message : String(error);
31805
+ emitCompletePlanningPhase(id, "prdPromote", "failure", reason);
31806
+ return jsonResponse({ error: `PRD draft promotion failed for ${id.toUpperCase()}: ${reason}` }, { status: 500 });
31807
+ }
31787
31808
  const workspacePlanPath = await (async () => await Effect.runPromise(findWorkspaceDraftPlan(workspacePath)) ?? await Effect.runPromise(findPlan(workspacePath)))();
31788
31809
  if (workspacePlanPath) {
31789
31810
  const workspaceDoc = await Effect.runPromise(readPlan(workspacePlanPath));
@@ -31791,7 +31812,7 @@ async function completePlanningForIssue(options) {
31791
31812
  assertPlanQuality(workspaceDoc);
31792
31813
  } catch (error) {
31793
31814
  if (error instanceof PlanQualityLintError) return jsonResponse({
31794
- error: "vBRIEF quality lint failed",
31815
+ error: "xBRIEF quality lint failed",
31795
31816
  qualityIssues: error.issues
31796
31817
  }, { status: 422 });
31797
31818
  throw error;
@@ -31808,7 +31829,7 @@ async function completePlanningForIssue(options) {
31808
31829
  issueId: id
31809
31830
  });
31810
31831
  console.log(`[complete-planning] Wrote pan spec to ${proposed.path}`);
31811
- console.log(`[complete-planning] Finalized ${taskCount} vBRIEF tasks for ${upperIssueId}`);
31832
+ console.log(`[complete-planning] Finalized ${taskCount} xBRIEF tasks for ${upperIssueId}`);
31812
31833
  const project = findProjectByPathSync(projectPath);
31813
31834
  const migrated = project ? await isStateMigrated(project) : false;
31814
31835
  const filesToStage = completePlanningFilesToStage(projectPath, proposed.filename, migrated);
@@ -31816,7 +31837,7 @@ async function completePlanningForIssue(options) {
31816
31837
  if (migrated) await Effect.runPromise(flushAutoCommits(projectPath));
31817
31838
  else if (!projectIsGitRepo) console.log(`[complete-planning] Project root ${projectPath} is not a git repository (polyrepo) — pan spec updated on disk but not committed`);
31818
31839
  else {
31819
- const { stdout: branchStdout } = await execFileAsync$17("git", [
31840
+ const { stdout: branchStdout } = await execFileAsync$16("git", [
31820
31841
  "rev-parse",
31821
31842
  "--abbrev-ref",
31822
31843
  "HEAD"
@@ -31826,7 +31847,7 @@ async function completePlanningForIssue(options) {
31826
31847
  });
31827
31848
  const currentBranch = branchStdout.trim();
31828
31849
  if (currentBranch === "main") {
31829
- await execFileAsync$17("git", [
31850
+ await execFileAsync$16("git", [
31830
31851
  "add",
31831
31852
  "--",
31832
31853
  ...filesToStage
@@ -31835,7 +31856,7 @@ async function completePlanningForIssue(options) {
31835
31856
  encoding: "utf-8"
31836
31857
  });
31837
31858
  try {
31838
- await execFileAsync$17("git", [
31859
+ await execFileAsync$16("git", [
31839
31860
  "diff",
31840
31861
  "--cached",
31841
31862
  "--quiet",
@@ -31846,10 +31867,10 @@ async function completePlanningForIssue(options) {
31846
31867
  encoding: "utf-8"
31847
31868
  });
31848
31869
  } catch {
31849
- await execFileAsync$17("git", [
31870
+ await execFileAsync$16("git", [
31850
31871
  "commit",
31851
31872
  "-m",
31852
- `chore(scope): propose ${upperIssueId} vBRIEF`,
31873
+ `chore(scope): propose ${upperIssueId} xBRIEF`,
31853
31874
  "--no-verify",
31854
31875
  "--",
31855
31876
  ...filesToStage
@@ -31859,7 +31880,7 @@ async function completePlanningForIssue(options) {
31859
31880
  });
31860
31881
  console.log(`[complete-planning] Committed pan spec on main for ${upperIssueId}`);
31861
31882
  try {
31862
- const { stdout: remotes } = await execFileAsync$17("git", ["remote"], {
31883
+ const { stdout: remotes } = await execFileAsync$16("git", ["remote"], {
31863
31884
  cwd: projectPath,
31864
31885
  encoding: "utf-8"
31865
31886
  });
@@ -31872,16 +31893,16 @@ async function completePlanningForIssue(options) {
31872
31893
  }
31873
31894
  } else console.log(`[complete-planning] Project root not on main (${currentBranch}) — pan spec updated on disk but not committed on main`);
31874
31895
  }
31875
- if (!existsSync$1(join(gitRoot, ".git"))) await execFileAsync$17("git", ["init"], {
31896
+ if (!existsSync$1(join(gitRoot, ".git"))) await execFileAsync$16("git", ["init"], {
31876
31897
  cwd: gitRoot,
31877
31898
  encoding: "utf-8"
31878
31899
  });
31879
- for (const args of completePlanningWorkspaceGitAddCommands(gitRoot, migrated)) await execFileAsync$17("git", args, {
31900
+ for (const args of completePlanningWorkspaceGitAddCommands(gitRoot, migrated)) await execFileAsync$16("git", args, {
31880
31901
  cwd: gitRoot,
31881
31902
  encoding: "utf-8"
31882
31903
  });
31883
31904
  try {
31884
- await execFileAsync$17("git", [
31905
+ await execFileAsync$16("git", [
31885
31906
  "diff",
31886
31907
  "--cached",
31887
31908
  "--quiet"
@@ -31890,7 +31911,7 @@ async function completePlanningForIssue(options) {
31890
31911
  encoding: "utf-8"
31891
31912
  });
31892
31913
  } catch {
31893
- await execFileAsync$17("git", [
31914
+ await execFileAsync$16("git", [
31894
31915
  "commit",
31895
31916
  "-m",
31896
31917
  `chore(plan): complete planning for ${id}`,
@@ -31901,7 +31922,7 @@ async function completePlanningForIssue(options) {
31901
31922
  });
31902
31923
  }
31903
31924
  try {
31904
- const { stdout: remotes } = await execFileAsync$17("git", ["remote"], {
31925
+ const { stdout: remotes } = await execFileAsync$16("git", ["remote"], {
31905
31926
  cwd: gitRoot,
31906
31927
  encoding: "utf-8"
31907
31928
  });
@@ -31966,19 +31987,6 @@ async function completePlanningForIssue(options) {
31966
31987
  });
31967
31988
  } catch {}
31968
31989
  invalidateAgentsCache();
31969
- emitActivityEntrySync({
31970
- source: "plan",
31971
- level: "info",
31972
- message: `${id} planning complete — ready for work`,
31973
- issueId: id
31974
- });
31975
- emitActivityTtsSync({
31976
- utterance: `${id} planning complete, ready for work`,
31977
- priority: 2,
31978
- issueId: id,
31979
- source: "planning-agent",
31980
- eventType: "planning.complete"
31981
- });
31982
31990
  const effectiveAutoSpawn = autoSpawn || completePlanningLease.autoSpawnRequested();
31983
31991
  if (effectiveAutoSpawn && workspacePath) await commitWorkspaceRecordBeforeAutoSpawn(workspacePath, id);
31984
31992
  const autoSpawnResult = await completePlanningAutoSpawnAndKill({
@@ -31987,6 +31995,28 @@ async function completePlanningForIssue(options) {
31987
31995
  skipKill,
31988
31996
  sessionName
31989
31997
  });
31998
+ const autoHandoffFailed = effectiveAutoSpawn && autoSpawnResult?.workAgentSpawned !== true;
31999
+ let autoHandoffError;
32000
+ if (autoHandoffFailed && autoSpawnResult) autoHandoffError = await recordPlanningAutoHandoffFailure({
32001
+ issueId: id,
32002
+ result: autoSpawnResult,
32003
+ eventStore
32004
+ });
32005
+ else {
32006
+ emitActivityEntrySync({
32007
+ source: "plan",
32008
+ level: "info",
32009
+ message: autoSpawnResult?.workAgentSpawned ? `${id} planning complete — work-agent startup accepted` : `${id} planning complete — ready for work`,
32010
+ issueId: id
32011
+ });
32012
+ emitActivityTtsSync({
32013
+ utterance: autoSpawnResult?.workAgentSpawned ? `${id} planning complete, work agent starting` : `${id} planning complete, ready for work`,
32014
+ priority: 2,
32015
+ issueId: id,
32016
+ source: "planning-agent",
32017
+ eventType: "planning.complete"
32018
+ });
32019
+ }
31990
32020
  emitCompletePlanningPhase(id, "terminal", resolveCompletePlanningTerminalStatus(effectiveAutoSpawn, autoSpawnResult), autoSpawnResult?.workAgentSpawned ? "planning complete and work agent spawn requested" : autoSpawnResult?.workAgentSkipReason ?? "planning complete", {
31991
32021
  autoSpawn: effectiveAutoSpawn,
31992
32022
  workAgentSpawned: autoSpawnResult?.workAgentSpawned ?? false,
@@ -31999,7 +32029,7 @@ async function completePlanningForIssue(options) {
31999
32029
  gitPushed,
32000
32030
  ...taskWarning ? { taskWarning } : {},
32001
32031
  ...autoSpawnResult ?? {},
32002
- message: autoSpawnResult?.workAgentSpawned ? "Planning complete and work agent spawn requested" : gitPushed ? "Planning complete and pushed to git - ready for execution" : "Planning complete - ready for execution"
32032
+ message: autoHandoffFailed ? `Planning complete, but work-agent startup failed (${autoSpawnResult?.workAgentSkipReason ?? "spawn-failed"}): ${autoHandoffError}` : autoSpawnResult?.workAgentSpawned ? "Planning complete and work agent spawn requested" : gitPushed ? "Planning complete and pushed to git - ready for execution" : "Planning complete - ready for execution"
32003
32033
  });
32004
32034
  } finally {
32005
32035
  completePlanningLease.release();
@@ -32081,7 +32111,7 @@ init_tracker_utils();
32081
32111
  init_agents$1();
32082
32112
  init_issue_id();
32083
32113
  const execAsync$8 = promisify(exec);
32084
- const execFileAsync$16 = promisify(execFile);
32114
+ const execFileAsync$15 = promisify(execFile);
32085
32115
  function isGitHubIssue$4(issueId) {
32086
32116
  const resolved = resolveGitHubIssueSync(issueId);
32087
32117
  if (resolved.isGitHub) return {
@@ -32120,7 +32150,7 @@ async function closeIssuePullRequest(issueId, reason = "Canceled via Overdeck")
32120
32150
  if (!githubCheck.isGitHub || !githubCheck.owner || !githubCheck.repo) return ["No GitHub PR to close"];
32121
32151
  const branchName = `feature/${issueId.toLowerCase()}`;
32122
32152
  try {
32123
- const { stdout: prListRaw } = await execFileAsync$16("gh", [
32153
+ const { stdout: prListRaw } = await execFileAsync$15("gh", [
32124
32154
  "pr",
32125
32155
  "list",
32126
32156
  "--repo",
@@ -32139,7 +32169,7 @@ async function closeIssuePullRequest(issueId, reason = "Canceled via Overdeck")
32139
32169
  });
32140
32170
  const prNumber = prListRaw.trim();
32141
32171
  if (!prNumber) return ["No open PR found for branch"];
32142
- await execFileAsync$16("gh", [
32172
+ await execFileAsync$15("gh", [
32143
32173
  "pr",
32144
32174
  "close",
32145
32175
  prNumber,
@@ -32152,7 +32182,7 @@ async function closeIssuePullRequest(issueId, reason = "Canceled via Overdeck")
32152
32182
  timeout: 15e3
32153
32183
  });
32154
32184
  try {
32155
- const { setReviewStatusSync } = await import("./review-status-Bnh-rdkY.js");
32185
+ const { setReviewStatusSync } = await import("./review-status-C6n6-9f_.js");
32156
32186
  setReviewStatusSync(issueId.toUpperCase(), { prUrl: void 0 });
32157
32187
  } catch {}
32158
32188
  return [`Closed PR #${prNumber} on ${githubCheck.owner}/${githubCheck.repo}`];
@@ -32206,7 +32236,7 @@ async function runDestructiveIssueLifecycle(id, mode, opts = {}) {
32206
32236
  const { ctx, projectConfig } = buildLifecycleContext(id, getIssueDataService$8().getIssueSource(id) ?? void 0);
32207
32237
  const deleteWorkspace = opts.deleteWorkspace ?? true;
32208
32238
  cleanupLog.push(...await closeIssuePullRequest(id, mode === "cancel" ? "Canceled via Overdeck" : "Reset to Todo via Overdeck"));
32209
- const { resetToTodo, cancelIssueWorkflow } = await import("./lifecycle-CtPDcZ9u.js");
32239
+ const { resetToTodo, cancelIssueWorkflow } = await import("./lifecycle-sycO16hj.js");
32210
32240
  const workflow = mode === "cancel" ? cancelIssueWorkflow : resetToTodo;
32211
32241
  const result = await Effect.runPromise(workflow(ctx, {
32212
32242
  deleteWorkspace,
@@ -32221,16 +32251,16 @@ async function runDestructiveIssueLifecycle(id, mode, opts = {}) {
32221
32251
  }));
32222
32252
  cleanupLog.push(...result.steps.flatMap((step) => step.details || [step.error].filter(Boolean)));
32223
32253
  if (mode === "cancel") try {
32224
- const { transitionVBriefOnMain } = await import("./lifecycle-io-DmY2qwCn.js");
32225
- const tx = await Effect.runPromise(transitionVBriefOnMain(ctx.projectPath, id, "cancelled", "cancelled", `scope: cancel ${id.toUpperCase()} vBRIEF`));
32226
- if (tx.moved) cleanupLog.push(`vBRIEF moved ${tx.fromDir} → cancelled`);
32227
- if (tx.committed) cleanupLog.push(`Committed vBRIEF cancellation on main`);
32254
+ const { transitionXBriefOnMain } = await import("./lifecycle-io-Bsnr2K4F.js");
32255
+ const tx = await Effect.runPromise(transitionXBriefOnMain(ctx.projectPath, id, "cancelled", "cancelled", `scope: cancel ${id.toUpperCase()} xBRIEF`));
32256
+ if (tx.moved) cleanupLog.push(`xBRIEF moved ${tx.fromDir} → cancelled`);
32257
+ if (tx.committed) cleanupLog.push(`Committed xBRIEF cancellation on main`);
32228
32258
  } catch (err) {
32229
- cleanupLog.push(`vBRIEF cancel transition failed (non-fatal): ${err?.message ?? err}`);
32259
+ cleanupLog.push(`xBRIEF cancel transition failed (non-fatal): ${err?.message ?? err}`);
32230
32260
  }
32231
32261
  try {
32232
- const { killAllReviewerSessions } = await import("./review-agent-CCum8sGe.js");
32233
- const { resolveProjectFromIssueSync } = await import("./projects-BKkwpH6q.js");
32262
+ const { killAllReviewerSessions } = await import("./review-agent-DJRO8EG8.js");
32263
+ const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
32234
32264
  const projectKey = resolveProjectFromIssueSync(id)?.projectKey;
32235
32265
  if (projectKey) {
32236
32266
  const { killed } = await Effect.runPromise(killAllReviewerSessions(projectKey, id.toUpperCase()));
@@ -32244,7 +32274,7 @@ async function runDestructiveIssueLifecycle(id, mode, opts = {}) {
32244
32274
  cleanupLog.push("Cleared review status");
32245
32275
  } catch {}
32246
32276
  try {
32247
- const { resetPostMergeState } = await import("./merge-agent-B-SnXOoc.js");
32277
+ const { resetPostMergeState } = await import("./merge-agent-BQM3a8z5.js");
32248
32278
  resetPostMergeState(id);
32249
32279
  resetPostMergeState(id.toUpperCase());
32250
32280
  cleanupLog.push("Cleared merge state");
@@ -32264,7 +32294,7 @@ function closeIssueTransition(options) {
32264
32294
  const { issueId, body, eventStore } = options;
32265
32295
  const { reason } = body;
32266
32296
  const projectPath = getProjectPath$3(void 0, extractPrefixSync(issueId) ?? issueId.split("-")[0]);
32267
- const { close: closeWorkflow } = yield* Effect.promise(() => import("./lifecycle-CtPDcZ9u.js"));
32297
+ const { close: closeWorkflow } = yield* Effect.promise(() => import("./lifecycle-sycO16hj.js"));
32268
32298
  const githubCheck = isGitHubIssue$4(issueId);
32269
32299
  const issueDataService = getIssueDataService$8();
32270
32300
  const issueSource = issueDataService.getIssueSource(issueId);
@@ -32531,7 +32561,7 @@ function reopenIssueTransition(options) {
32531
32561
  else clearReviewStatus(id.toUpperCase());
32532
32562
  } catch {}
32533
32563
  try {
32534
- const { resetPostMergeState } = await import("./merge-agent-B-SnXOoc.js");
32564
+ const { resetPostMergeState } = await import("./merge-agent-BQM3a8z5.js");
32535
32565
  resetPostMergeState(id);
32536
32566
  resetPostMergeState(id.toUpperCase());
32537
32567
  } catch {}
@@ -32595,7 +32625,7 @@ function moveIssueStatus(options) {
32595
32625
  "done"
32596
32626
  ];
32597
32627
  if (!targetStatus || !validStatuses.includes(targetStatus)) return jsonResponse({ error: `Invalid targetStatus. Must be one of: ${validStatuses.join(", ")}` }, { status: 400 });
32598
- const { updateShadowState } = yield* Effect.promise(() => import("./shadow-state-CbvsN3qG.js"));
32628
+ const { updateShadowState } = yield* Effect.promise(() => import("./shadow-state-C2_epgx2.js"));
32599
32629
  const issueState = {
32600
32630
  backlog: "open",
32601
32631
  todo: "open",
@@ -32822,7 +32852,7 @@ async function copySettingsToWorkspace(id) {
32822
32852
  success: false,
32823
32853
  error: "Workspace not found"
32824
32854
  }, { status: 404 });
32825
- const { copyOverdeckSettingsToWorkspaceSync } = await import("./workspace-manager-B1WOfKvB.js");
32855
+ const { copyOverdeckSettingsToWorkspaceSync } = await import("./workspace-manager-ZTdJAy9M.js");
32826
32856
  const result = copyOverdeckSettingsToWorkspaceSync(workspacePath);
32827
32857
  return jsonResponse({
32828
32858
  success: result.errors.length === 0 || result.copied.length > 0,
@@ -32853,7 +32883,7 @@ function generateTasksForIssue(id) {
32853
32883
  const plan = readWorkspacePlanSync(join(projectPath, "workspaces", `feature-${issueLower}`));
32854
32884
  if (!plan) return jsonResponse({
32855
32885
  success: false,
32856
- error: `No vBRIEF spec found on main for ${id} — run planning first.`
32886
+ error: `No xBRIEF spec found on main for ${id} — run planning first.`
32857
32887
  }, { status: 409 });
32858
32888
  return jsonResponse({
32859
32889
  success: true,
@@ -32876,7 +32906,7 @@ init_tracker_utils();
32876
32906
  init_tmux();
32877
32907
  init_typed_errors();
32878
32908
  const execAsync$6 = promisify(exec);
32879
- const execFileAsync$15 = promisify(execFile);
32909
+ const execFileAsync$14 = promisify(execFile);
32880
32910
  function getIssueDataService$6() {
32881
32911
  return getSharedIssueService();
32882
32912
  }
@@ -33176,7 +33206,7 @@ function abortPlanningForIssue(options) {
33176
33206
  const featureWorkspacePath = join(projectPath, "workspaces", `feature-${issueIdentifier.toLowerCase()}`);
33177
33207
  const plainWorkspacePath = join(projectPath, "workspaces", issueIdentifier.toLowerCase());
33178
33208
  if (existsSync$1(existsSync$1(featureWorkspacePath) ? featureWorkspacePath : plainWorkspacePath)) {
33179
- await execFileAsync$15("pan", [
33209
+ await execFileAsync$14("pan", [
33180
33210
  "workspace",
33181
33211
  "destroy",
33182
33212
  issueIdentifier.toLowerCase(),
@@ -33285,7 +33315,7 @@ function restartFromPlan(options) {
33285
33315
  });
33286
33316
  const resetResult = yield* Effect.promise(async () => {
33287
33317
  try {
33288
- const { runGitResetHard } = await import("./dangerous-git-ops-D6AF-Hg_.js");
33318
+ const { runGitResetHard } = await import("./dangerous-git-ops-CT-IypG3.js");
33289
33319
  async function findPlanningCommit(grep, label) {
33290
33320
  try {
33291
33321
  const { stdout } = await execAsync$6(`git log --grep="${grep.replace(/"/g, "\\\"")}" --format=%H -1`, {
@@ -33738,7 +33768,7 @@ function closeOutIssue(id, opts = {}) {
33738
33768
  }
33739
33769
  const closeOutResult = yield* Effect.promise(async () => {
33740
33770
  try {
33741
- const { closeOut } = await import("./lifecycle-CtPDcZ9u.js");
33771
+ const { closeOut } = await import("./lifecycle-sycO16hj.js");
33742
33772
  return {
33743
33773
  ok: true,
33744
33774
  result: await Effect.runPromise(closeOut(ctx, {
@@ -33827,7 +33857,7 @@ function bulkCloseOut(body) {
33827
33857
  const invalidIds = issueIds.filter((id) => !isValidIssueId(id));
33828
33858
  if (invalidIds.length > 0) return jsonResponse({ error: `Invalid issue ID format: ${invalidIds.join(", ")}` }, { status: 400 });
33829
33859
  const eventStore = yield* EventStoreService;
33830
- const { closeOut } = yield* Effect.promise(() => import("./lifecycle-CtPDcZ9u.js"));
33860
+ const { closeOut } = yield* Effect.promise(() => import("./lifecycle-sycO16hj.js"));
33831
33861
  const issueDataService = getIssueDataService$5();
33832
33862
  const tasks = [];
33833
33863
  const agentChecks = yield* withConcurrencyLimit(issueIds.map((id) => Effect.promise(async () => {
@@ -33991,7 +34021,7 @@ init_issue_service_singleton();
33991
34021
  init_domain_services();
33992
34022
  init_linear_client();
33993
34023
  promisify(exec);
33994
- const execFileAsync$14 = promisify(execFile);
34024
+ const execFileAsync$13 = promisify(execFile);
33995
34025
  function getIssueDataService$4() {
33996
34026
  return getSharedIssueService();
33997
34027
  }
@@ -34026,7 +34056,7 @@ const getIssuesRoute = HttpRouter.add("GET", "/api/issues", httpHandler(Effect.g
34026
34056
  }
34027
34057
  }
34028
34058
  const membershipByIssue = /* @__PURE__ */ new Map();
34029
- const results = getPipelineMembershipSnapshotsForProjects([...projects.values()]);
34059
+ const results = readPipelineMembershipSnapshotsForProjects([...projects.values()]);
34030
34060
  const successfulPaths = /* @__PURE__ */ new Set();
34031
34061
  const failedPaths = /* @__PURE__ */ new Set();
34032
34062
  for (const result of results) {
@@ -34053,8 +34083,8 @@ const getIssueShipLogRoute = HttpRouter.add("GET", "/api/issues/:id/ship-log", h
34053
34083
  const id = (yield* HttpRouter.params)["id"] ?? "";
34054
34084
  if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
34055
34085
  return yield* Effect.promise(async () => {
34056
- const { getShipLog } = await import("./ship-log-__QtAFXG.js");
34057
- const { getReviewStatusSync } = await import("./review-status-Bnh-rdkY.js");
34086
+ const { getShipLog } = await import("./ship-log-ClSMIzZX.js");
34087
+ const { getReviewStatusSync } = await import("./review-status-C6n6-9f_.js");
34058
34088
  const log = getShipLog(id);
34059
34089
  const rs = getReviewStatusSync(id);
34060
34090
  return jsonResponse({
@@ -34069,8 +34099,8 @@ const getIssueVerificationRoute = HttpRouter.add("GET", "/api/issues/:id/verific
34069
34099
  const id = (yield* HttpRouter.params)["id"] ?? "";
34070
34100
  if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
34071
34101
  return yield* Effect.promise(async () => {
34072
- const { readVerificationArtifact } = await import("./verification-artifact-Ck1tefmz.js");
34073
- const { getReviewStatusSync } = await import("./review-status-Bnh-rdkY.js");
34102
+ const { readVerificationArtifact } = await import("./verification-artifact-C-lIHfUa.js");
34103
+ const { getReviewStatusSync } = await import("./review-status-C6n6-9f_.js");
34074
34104
  const { join } = await import("node:path");
34075
34105
  const resolved = resolveProjectFromIssueSync(id);
34076
34106
  const workspacePath = resolved ? join(resolved.projectPath, "workspaces", `feature-${id.toLowerCase()}`) : null;
@@ -34155,7 +34185,7 @@ const postIssueResetToPlannedRoute = HttpRouter.add("POST", "/api/issues/:id/res
34155
34185
  if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
34156
34186
  try {
34157
34187
  const invocation = panCliInvocation(["reset-to-planned", id]);
34158
- const { stdout } = yield* Effect.promise(() => execFileAsync$14(invocation.command, invocation.args, { encoding: "utf8" }));
34188
+ const { stdout } = yield* Effect.promise(() => execFileAsync$13(invocation.command, invocation.args, { encoding: "utf8" }));
34159
34189
  invalidateAgentsCache();
34160
34190
  return jsonResponse({
34161
34191
  success: true,
@@ -34394,7 +34424,9 @@ const getPipelineMembershipRoute = HttpRouter.add("GET", "/api/pipeline/membersh
34394
34424
  if (!projectKey) return jsonResponse({ error: "project query parameter is required" }, { status: 400 });
34395
34425
  const project = getProjectSync(projectKey);
34396
34426
  if (!project) return jsonResponse({ error: `Project not found: ${projectKey}` }, { status: 404 });
34397
- return jsonResponse(yield* Effect.promise(() => getProjectPipelineMembership(project)));
34427
+ const snapshot = readPipelineMembershipSnapshotsForProjects([project])[0];
34428
+ if (snapshot?.memberships) return jsonResponse(snapshot.memberships);
34429
+ return jsonResponse({ error: "Pipeline membership snapshot is loading" }, { status: 503 });
34398
34430
  })));
34399
34431
  const getIssueResourceDetailsRoute = HttpRouter.add("GET", "/api/issues/:id/resource-details", httpHandler(Effect.gen(function* () {
34400
34432
  return yield* getIssueResourceDetails((yield* HttpRouter.params)["id"] ?? "");
@@ -35066,8 +35098,7 @@ const cloisterRouteLayer = Layer.mergeAll(getCloisterStatusRoute, postCloisterSt
35066
35098
  //#region routes/resources/agents-stats.ts
35067
35099
  init_agents$1();
35068
35100
  init_cost_sync();
35069
- init_tmux();
35070
- const execFileAsync$13 = promisify(execFile);
35101
+ init_runtime_census();
35071
35102
  const BURN_WINDOW_MS = 1800 * 1e3;
35072
35103
  function buildAgentStatsSnapshot(options) {
35073
35104
  const nowMs = options.nowMs ?? Date.now();
@@ -35134,27 +35165,19 @@ function getAgentStatsSnapshotEffect(deps = {}) {
35134
35165
  });
35135
35166
  });
35136
35167
  }
35137
- function parseProcessTable(psTable) {
35138
- return psTable.split("\n").map((line) => line.trim()).filter(Boolean).flatMap((line) => {
35139
- const match = line.match(/^(\d+)\s+(\d+)\s+([0-9.]+)\s+(\d+)$/);
35140
- if (!match) return [];
35141
- return [{
35142
- pid: Number(match[1]),
35143
- ppid: Number(match[2]),
35144
- cpuPercent: Number(match[3]),
35145
- rssBytes: Number(match[4]) * 1024
35146
- }];
35147
- });
35148
- }
35149
35168
  async function readBatchedProcessTable() {
35150
- const { stdout } = await execFileAsync$13("ps", ["-eo", "pid=,ppid=,pcpu=,rss="], { encoding: "utf8" });
35151
- return parseProcessTable(stdout);
35169
+ return [...(await getRuntimeCensus()).processesByPid.values()].map((process) => ({
35170
+ pid: process.pid,
35171
+ ppid: process.ppid,
35172
+ cpuPercent: process.cpuPercent,
35173
+ rssBytes: process.rssBytes
35174
+ }));
35152
35175
  }
35153
35176
  function defaultListSessionNames() {
35154
- return listSessions().pipe(Effect.map((sessions) => sessions.map((session) => session.name)));
35177
+ return Effect.promise(async () => [...(await getRuntimeCensus()).sessionNames]);
35155
35178
  }
35156
35179
  function defaultListPanePids(sessionName) {
35157
- return listPaneValues(sessionName, "#{pane_pid}").pipe(Effect.map((values) => values.map((value) => Number(value.trim())).filter((value) => Number.isFinite(value) && value > 0)));
35180
+ return Effect.promise(async () => panePidsForSession(await getRuntimeCensus(), sessionName));
35158
35181
  }
35159
35182
  function buildProcessTotalsByRoot(roots, processes) {
35160
35183
  const processByPid = new Map(processes.map((process) => [process.pid, process]));
@@ -35225,7 +35248,6 @@ function roundCurrency(value) {
35225
35248
  }
35226
35249
  //#endregion
35227
35250
  //#region services/event-loop-monitor.ts
35228
- init_activity_logger();
35229
35251
  const EVENT_LOOP_MONITOR_WINDOW_MS = 6e4;
35230
35252
  let lastSample = {
35231
35253
  p50: 0,
@@ -35245,7 +35267,6 @@ function sampleEventLoopDelay(histogram, deps = {}) {
35245
35267
  const warnThresholdMs = deps.warnThresholdMs ?? 100;
35246
35268
  const now = deps.now ?? (() => /* @__PURE__ */ new Date());
35247
35269
  const warn = deps.warn ?? ((message) => console.warn(message));
35248
- const emit = deps.emit ?? emitActivityEntrySync;
35249
35270
  const sample = {
35250
35271
  p50: nsToRoundedMs(histogram.percentile(50)),
35251
35272
  p99: nsToRoundedMs(histogram.percentile(99)),
@@ -35255,16 +35276,7 @@ function sampleEventLoopDelay(histogram, deps = {}) {
35255
35276
  windowMs: EVENT_LOOP_MONITOR_WINDOW_MS
35256
35277
  };
35257
35278
  lastSample = sample;
35258
- if (sample.p99 > warnThresholdMs) {
35259
- const message = `Dashboard event loop p99 delay ${sample.p99}ms exceeded ${warnThresholdMs}ms`;
35260
- warn(`[event-loop-monitor] ${message}`);
35261
- emit({
35262
- source: "dashboard",
35263
- level: "warn",
35264
- message,
35265
- details: `p50=${sample.p50}ms p99=${sample.p99}ms max=${sample.max}ms over ${sample.windowMs}ms`
35266
- });
35267
- }
35279
+ if (sample.p99 > warnThresholdMs) warn(`[event-loop-monitor] Dashboard event loop p99 delay ${sample.p99}ms exceeded ${warnThresholdMs}ms`);
35268
35280
  histogram.reset();
35269
35281
  return sample;
35270
35282
  }
@@ -35872,17 +35884,20 @@ function spawnGatePressure(state) {
35872
35884
  //#endregion
35873
35885
  //#region routes/resources/snapshot.ts
35874
35886
  init_agents$1();
35875
- init_tmux();
35876
- /** Build the GET /api/resources response from the SQLite agents table. */
35877
- function getResourcesEffect() {
35887
+ init_runtime_census();
35888
+ const RESOURCES_SNAPSHOT_INTERVAL_MS = 3e3;
35889
+ let resourcesSnapshotJson = null;
35890
+ let resourcesSnapshotRefresh = null;
35891
+ let resourcesSnapshotTimer = null;
35892
+ /** Build the resources payload from cached collectors and the SQLite agents table. */
35893
+ function buildResourcesPayloadEffect() {
35878
35894
  return Effect.gen(function* () {
35879
35895
  const containers = enrichContainersWithLimits(getCurrentDockerStats());
35880
35896
  const agentStats = yield* getAgentStatsSnapshotEffect();
35881
35897
  const healthEvidence = yield* getResourcesHealthEvidenceEffect();
35882
35898
  const spawnGate = yield* getSpawnGatePayloadEffect(healthEvidence);
35883
35899
  const stoppedContainers = [];
35884
- const sessions = yield* listSessions().pipe(Effect.catch(() => Effect.succeed([])));
35885
- const tmuxSessionNames = new Set(sessions.map((s) => s.name));
35900
+ const tmuxSessionNames = (yield* Effect.promise(() => getRuntimeCensus()).pipe(Effect.catch(() => Effect.succeed(null))))?.sessionNames ?? /* @__PURE__ */ new Set();
35886
35901
  const agents = listAgentStates().filter((state) => state.status !== "stopped").map((state) => ({
35887
35902
  ...state,
35888
35903
  hasLiveTmuxSession: tmuxSessionNames.has(state.id)
@@ -35907,7 +35922,7 @@ function getResourcesEffect() {
35907
35922
  reclaimableBytes: reclaim.reclaimTotals.diskBytes
35908
35923
  }
35909
35924
  };
35910
- return jsonResponse({
35925
+ return {
35911
35926
  agents: agents.map((agent) => ({
35912
35927
  ...agent,
35913
35928
  resourceStats: agentStatsById.get(String(agent.id)) ?? null
@@ -35926,10 +35941,39 @@ function getResourcesEffect() {
35926
35941
  stacks,
35927
35942
  volumes: [],
35928
35943
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
35929
- });
35944
+ };
35945
+ });
35946
+ }
35947
+ function refreshResourcesSnapshot() {
35948
+ if (resourcesSnapshotRefresh) return resourcesSnapshotRefresh;
35949
+ resourcesSnapshotRefresh = Effect.runPromise(buildResourcesPayloadEffect()).then((payload) => {
35950
+ resourcesSnapshotJson = JSON.stringify(payload);
35951
+ }).finally(() => {
35952
+ resourcesSnapshotRefresh = null;
35930
35953
  });
35954
+ return resourcesSnapshotRefresh;
35931
35955
  }
35932
- const getResourcesRoute = HttpRouter.add("GET", "/api/resources", httpHandler(getResourcesEffect()));
35956
+ function getResourcesSnapshotEffect() {
35957
+ return Effect.sync(() => resourcesSnapshotJson ? jsonStringResponse(resourcesSnapshotJson) : jsonResponse({ error: "Resources snapshot is warming" }, 503));
35958
+ }
35959
+ function startResourcesSnapshotService() {
35960
+ if (resourcesSnapshotTimer) return stopResourcesSnapshotService;
35961
+ refreshResourcesSnapshot().catch((error) => {
35962
+ console.warn("[resources-snapshot] initial refresh failed:", error instanceof Error ? error.message : error);
35963
+ });
35964
+ resourcesSnapshotTimer = setInterval(() => {
35965
+ refreshResourcesSnapshot().catch((error) => {
35966
+ console.warn("[resources-snapshot] refresh failed; keeping last-good snapshot:", error instanceof Error ? error.message : error);
35967
+ });
35968
+ }, RESOURCES_SNAPSHOT_INTERVAL_MS);
35969
+ resourcesSnapshotTimer.unref?.();
35970
+ return stopResourcesSnapshotService;
35971
+ }
35972
+ function stopResourcesSnapshotService() {
35973
+ if (resourcesSnapshotTimer) clearInterval(resourcesSnapshotTimer);
35974
+ resourcesSnapshotTimer = null;
35975
+ }
35976
+ const getResourcesRoute = HttpRouter.add("GET", "/api/resources", httpHandler(getResourcesSnapshotEffect()));
35933
35977
  //#endregion
35934
35978
  //#region routes/resources/containers.ts
35935
35979
  init_domain_services();
@@ -38369,7 +38413,7 @@ async function fetchPlanningData(issueId, options = {}) {
38369
38413
  }
38370
38414
  } catch {}
38371
38415
  if (!hasPlanningDir && !hasPanContinue) {
38372
- const prd = await readPrdContent(findPrdAtStatusSync(projectPath, issueId, "active"));
38416
+ const prd = await readPrdContent(findPrdAnywhereSync(projectPath, issueId));
38373
38417
  if (prd) {
38374
38418
  result.prd = prd;
38375
38419
  result.hasPrd = true;
@@ -38397,16 +38441,11 @@ async function fetchPlanningData(issueId, options = {}) {
38397
38441
  const fileStat = await stat$1(statusReviewPath).catch(() => null);
38398
38442
  if (fileStat) result.statusReviewedAt = fileStat.mtime.toISOString();
38399
38443
  }
38400
- if (!result.prd) for (const status of [
38401
- "active",
38402
- "planned",
38403
- "completed"
38404
- ]) {
38405
- const content = await readPrdContent(findPrdAtStatusSync(projectPath, issueId, status));
38444
+ if (!result.prd) {
38445
+ const content = await readPrdContent(findPrdAnywhereSync(projectPath, issueId));
38406
38446
  if (content) {
38407
38447
  result.prd = content;
38408
38448
  result.hasPrd = true;
38409
- break;
38410
38449
  }
38411
38450
  }
38412
38451
  if (!result.prd && result.state) result.prd = result.state;
@@ -38609,7 +38648,7 @@ ${issueContext ? `\n${issueContext}\n` : ""}
38609
38648
  - Review: ${reviewStatus}
38610
38649
  - Tests: ${testStatus}
38611
38650
 
38612
- ## Planning Context (continue.vbrief.json)
38651
+ ## Planning Context (.overdeck/continue.json)
38613
38652
  ${state ? state.slice(0, 4e3) : "(No planning state available)"}
38614
38653
 
38615
38654
  ## Files Changed
@@ -38651,7 +38690,7 @@ Be specific: reference actual file names, function names, requirement text, disc
38651
38690
  const { command: cliCmd, args: cliArgs } = getAgentCommandSync(statusModelId);
38652
38691
  const modelFlag = cliArgs.length > 0 ? ` ${cliArgs.join(" ")}` : "";
38653
38692
  const promptFile = join(planningDir, ".status-review-prompt.tmp");
38654
- const { getProviderForModelSync, getProviderEnvSync } = await import("./providers-DNSQqy2V.js");
38693
+ const { getProviderForModelSync, getProviderEnvSync } = await import("./providers-DKkBXhxU.js");
38655
38694
  let providerEnvStr = "";
38656
38695
  let providerEnv = {};
38657
38696
  const statusProvider = getProviderForModelSync(statusModelId);
@@ -38734,7 +38773,7 @@ const postMissionControlUploadRoute = HttpRouter.add("POST", "/api/command-deck/
38734
38773
  let safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "-");
38735
38774
  let processedContent = content;
38736
38775
  if (safeName.endsWith(".vtt")) {
38737
- const { vttToMarkdown } = yield* Effect.promise(() => import("./vtt-parser-BnRsYzcz.js"));
38776
+ const { vttToMarkdown } = yield* Effect.promise(() => import("./vtt-parser-DKpNNW5i.js"));
38738
38777
  processedContent = vttToMarkdown(content);
38739
38778
  safeName = safeName.replace(/\.vtt$/, ".md");
38740
38779
  }
@@ -44561,7 +44600,7 @@ const postRallyValidateRoute = HttpRouter.add("POST", "/api/rally/validate", Eff
44561
44600
  }, { status: 400 });
44562
44601
  return yield* Effect.promise(async () => {
44563
44602
  try {
44564
- const { RallyRestApi } = await import("./rally-api-xHazRk0d.js");
44603
+ const { RallyRestApi } = await import("./rally-api-yjQ0TfHd.js");
44565
44604
  const api = new RallyRestApi({
44566
44605
  apiKey,
44567
44606
  server: server || "https://rally1.rallydev.com"
@@ -44609,8 +44648,13 @@ const checkAgentHealth = (agentId) => Effect.gen(function* () {
44609
44648
  init_src();
44610
44649
  init_review_status_source();
44611
44650
  init_paths();
44612
- init_tmux();
44651
+ init_runtime_census();
44613
44652
  init_read_model();
44653
+ function readHealthSessionNames(readSnapshot = getRuntimeCensusSnapshot) {
44654
+ const census = readSnapshot();
44655
+ if (!census) throw new Error("Runtime census snapshot is warming");
44656
+ return [...census.sessionNames];
44657
+ }
44614
44658
  function unavailableSystemHealthResponse() {
44615
44659
  return jsonResponse({
44616
44660
  status: "unavailable",
@@ -44787,7 +44831,7 @@ function buildHealthAgentsResponse(dependencies) {
44787
44831
  const getHealthAgentsRoute = HttpRouter.add("GET", "/api/health/agents", Effect.gen(function* () {
44788
44832
  return yield* buildHealthAgentsResponse({
44789
44833
  snapshot: (yield* ReadModelService).getSnapshot,
44790
- sessionNames: listSessionNames()
44834
+ sessionNames: Effect.sync(() => readHealthSessionNames())
44791
44835
  });
44792
44836
  }));
44793
44837
  const postHealthAgentPingRoute = HttpRouter.add("POST", "/api/health/agents/:id/ping", Effect.gen(function* () {
@@ -44941,7 +44985,7 @@ const getPlanningStatusRoute = HttpRouter.add("GET", "/api/planning/:issueId/sta
44941
44985
  const remoteState = loadRemoteAgentState(sessionName);
44942
44986
  const isRemote = !!remoteState;
44943
44987
  const vmName = remoteState?.vmName ?? "";
44944
- const { getAgentStateSync } = await import("./agents-DyHKlq1I.js");
44988
+ const { getAgentStateSync } = await import("./agents-FlIgQ3ql.js");
44945
44989
  const agentStarting = getAgentStateSync(sessionName)?.status === "starting";
44946
44990
  let tmuxSessionAlive = false;
44947
44991
  if (!isRemote) try {
@@ -45061,7 +45105,7 @@ const postPlanningMessageRoute = HttpRouter.add("POST", "/api/planning/:issueId/
45061
45105
  **YOU SHOULD ONLY:**
45062
45106
  - Ask clarifying questions
45063
45107
  - Explore the codebase to understand context
45064
- - Generate planning artifacts (\`.pan/continue.json\`, \`.pan/spec.vbrief.json\`)
45108
+ - Generate planning artifacts (\`.overdeck/continue.json\`, \`.overdeck/spec.vbrief.json\`)
45065
45109
  - Present options and tradeoffs
45066
45110
 
45067
45111
  ---
@@ -45085,7 +45129,7 @@ Continue the PLANNING session. Do NOT implement anything.
45085
45129
  const agentCwd = workspacePath;
45086
45130
  const harnessLaunch = await prepareHarnessLaunch("claude-code");
45087
45131
  if (existsSync$1(outputFile)) await rename(outputFile, join(planningDir, `output-${Date.now()}.jsonl`));
45088
- const { getAgentCommandSync } = await import("./settings-BlUsVaUc.js");
45132
+ const { getAgentCommandSync } = await import("./settings-D0OSwos5.js");
45089
45133
  let msgPlanningModel = "claude-sonnet-5";
45090
45134
  try {
45091
45135
  msgPlanningModel = resolveModel("plan", void 0, loadConfigSync().config);
@@ -45207,7 +45251,7 @@ async function getIndexStats(rootPath, isMain) {
45207
45251
  }
45208
45252
  const getTldrStatusRoute = HttpRouter.add("GET", "/api/services/tldr/status", Effect.promise(async () => {
45209
45253
  try {
45210
- const { getTldrDaemonServiceSync } = await import("./tldr-daemon-B8_oT5gx.js");
45254
+ const { getTldrDaemonServiceSync } = await import("./tldr-daemon-DL566HbH.js");
45211
45255
  const projectRoot = process.cwd();
45212
45256
  const venvPath = join(projectRoot, ".venv");
45213
45257
  const results = [];
@@ -45252,7 +45296,7 @@ const getTldrStatusRoute = HttpRouter.add("GET", "/api/services/tldr/status", Ef
45252
45296
  }));
45253
45297
  const postTldrStartRoute = HttpRouter.add("POST", "/api/services/tldr/start", Effect.promise(async () => {
45254
45298
  try {
45255
- const { getTldrDaemonServiceSync } = await import("./tldr-daemon-B8_oT5gx.js");
45299
+ const { getTldrDaemonServiceSync } = await import("./tldr-daemon-DL566HbH.js");
45256
45300
  const projectRoot = process.cwd();
45257
45301
  const venvPath = join(projectRoot, ".venv");
45258
45302
  if (!existsSync$1(venvPath)) return jsonResponse({ error: "No .venv found in project root" }, { status: 404 });
@@ -45269,7 +45313,7 @@ const postTldrStartRoute = HttpRouter.add("POST", "/api/services/tldr/start", Ef
45269
45313
  }));
45270
45314
  const postTldrStopRoute = HttpRouter.add("POST", "/api/services/tldr/stop", Effect.promise(async () => {
45271
45315
  try {
45272
- const { getTldrDaemonServiceSync } = await import("./tldr-daemon-B8_oT5gx.js");
45316
+ const { getTldrDaemonServiceSync } = await import("./tldr-daemon-DL566HbH.js");
45273
45317
  const projectRoot = process.cwd();
45274
45318
  const venvPath = join(projectRoot, ".venv");
45275
45319
  if (!existsSync$1(venvPath)) return jsonResponse({ error: "No .venv found in project root" }, { status: 404 });
@@ -45286,7 +45330,7 @@ const postTldrStopRoute = HttpRouter.add("POST", "/api/services/tldr/stop", Effe
45286
45330
  }));
45287
45331
  const postTldrReloadRoute = HttpRouter.add("POST", "/api/services/tldr/reload", Effect.promise(async () => {
45288
45332
  try {
45289
- const { getTldrDaemonServiceSync } = await import("./tldr-daemon-B8_oT5gx.js");
45333
+ const { getTldrDaemonServiceSync } = await import("./tldr-daemon-DL566HbH.js");
45290
45334
  const enabled = isTldrEnabledSync();
45291
45335
  const projectRoot = process.cwd();
45292
45336
  const targets = [];
@@ -45474,7 +45518,7 @@ const getVersionRoute = HttpRouter.add("GET", "/api/version", Effect.promise(asy
45474
45518
  const version = await getOverdeckVersion();
45475
45519
  let supervisorUrl = null;
45476
45520
  try {
45477
- const { getSupervisorUrlSync } = await import("./supervisor-COVHrBTg.js");
45521
+ const { getSupervisorUrlSync } = await import("./supervisor-BPy-o1A8.js");
45478
45522
  supervisorUrl = getSupervisorUrlSync();
45479
45523
  } catch {}
45480
45524
  return jsonResponse({
@@ -45484,11 +45528,11 @@ const getVersionRoute = HttpRouter.add("GET", "/api/version", Effect.promise(asy
45484
45528
  });
45485
45529
  }));
45486
45530
  const getPrerequisitesRoute = HttpRouter.add("GET", "/api/prerequisites", Effect.promise(async () => {
45487
- const { checkSystemPrerequisites } = await import("./system-prerequisites-DSXBvffY.js");
45531
+ const { checkSystemPrerequisites } = await import("./system-prerequisites-Bza0ffAh.js");
45488
45532
  return jsonResponse(await checkSystemPrerequisites());
45489
45533
  }));
45490
45534
  const getSetupDiagnosticsRoute = HttpRouter.add("GET", "/api/diagnostics/setup", Effect.promise(async () => {
45491
- const { collectSetupDiagnostics } = await import("./system-prerequisites-DSXBvffY.js");
45535
+ const { collectSetupDiagnostics } = await import("./system-prerequisites-Bza0ffAh.js");
45492
45536
  return jsonResponse(await collectSetupDiagnostics(await getOverdeckVersion()));
45493
45537
  }));
45494
45538
  const getSyncStatusRoute = HttpRouter.add("GET", "/api/sync-status", Effect.sync(() => {
@@ -45668,7 +45712,7 @@ const postShadowMonitorRoute = HttpRouter.add("POST", "/api/shadow/:issueId/moni
45668
45712
  const projectPath = await getProjectPath(issuePrefix);
45669
45713
  const workspacePath = join(projectPath, "workspaces", `feature-${issueLower}`);
45670
45714
  if (!existsSync$1(workspacePath)) return jsonResponse({ error: "Workspace not found" }, { status: 404 });
45671
- const { gatherArtifacts, generateBasicInference, updateInferenceDocumentSync } = await import("./shadow-engineering-D4X_s3fA.js");
45715
+ const { gatherArtifacts, generateBasicInference, updateInferenceDocumentSync } = await import("./shadow-engineering-BlxG6Xye.js");
45672
45716
  const config = {
45673
45717
  issueId,
45674
45718
  workspacePath,
@@ -45698,7 +45742,7 @@ const postShadowObserveRoute = HttpRouter.add("POST", "/api/shadow/:issueId/obse
45698
45742
  if (!existsSync$1(workspacePath)) return jsonResponse({ error: "Workspace not found" }, { status: 404 });
45699
45743
  const ghConfig = getGitHubConfig();
45700
45744
  if (!ghConfig) return jsonResponse({ error: "GitHub not configured - Observer requires GitHub" }, { status: 400 });
45701
- const { runObserverCycle } = await import("./shadow-engineering-D4X_s3fA.js");
45745
+ const { runObserverCycle } = await import("./shadow-engineering-BlxG6Xye.js");
45702
45746
  const firstRepo = ghConfig.repos[0];
45703
45747
  const config = {
45704
45748
  issueId,
@@ -46234,9 +46278,9 @@ const PAN_COMMANDS = [
46234
46278
  },
46235
46279
  {
46236
46280
  name: "pan plan <id>",
46237
- description: "Plan an issue (interactive vBRIEF + tasks)",
46281
+ description: "Plan an issue (interactive xBRIEF + tasks)",
46238
46282
  group: "Issues",
46239
- keywords: ["planning", "vbrief"]
46283
+ keywords: ["planning", "xbrief"]
46240
46284
  },
46241
46285
  {
46242
46286
  name: "pan plan <id> --auto",
@@ -46938,6 +46982,17 @@ async function diffFilesSinceBase(repoRoot, baseCommit, filePaths) {
46938
46982
  }
46939
46983
  return diffs;
46940
46984
  }
46985
+ async function diffPatchForFiles(repoRoot, createdAt, filePaths) {
46986
+ const baseCommit = await Effect.runPromise(findCommitAtTime(repoRoot, createdAt));
46987
+ if (!baseCommit) return Effect.runPromise(diffPatchFilesAgainstHead(repoRoot, filePaths));
46988
+ const quotedPaths = filePaths.map((p) => JSON.stringify(p)).join(" ");
46989
+ const { stdout } = await promisify(exec)(`git diff --patch --minimal --no-color ${baseCommit} -- ${quotedPaths}`, {
46990
+ cwd: repoRoot,
46991
+ encoding: "utf-8",
46992
+ maxBuffer: 50 * 1024 * 1024
46993
+ });
46994
+ return stdout;
46995
+ }
46941
46996
  async function getConversationDiffs(name, deps) {
46942
46997
  try {
46943
46998
  const conv = lookupConversation(name);
@@ -46983,22 +47038,28 @@ async function getConversationDiffFull(name, deps) {
46983
47038
  const conv = getConversationByName(name);
46984
47039
  if (!conv) return result$1({ error: "Conversation not found" }, 404);
46985
47040
  const cwd = conv.cwd;
46986
- if (existsSync$1(join(cwd, ".git"))) {
46987
- const baseCommit = await Effect.runPromise(findCommitAtTime(cwd, conv.createdAt));
46988
- if (!baseCommit) return result$1({ diff: "" });
46989
- return result$1({ diff: await Effect.runPromise(diffPatchSinceCommit(cwd, baseCommit)) });
47041
+ const cwdRepoRoot = existsSync$1(join(cwd, ".git")) ? cwd : null;
47042
+ const patches = [];
47043
+ if (cwdRepoRoot) {
47044
+ const baseCommit = await Effect.runPromise(findCommitAtTime(cwdRepoRoot, conv.createdAt));
47045
+ if (baseCommit) {
47046
+ const patch = await Effect.runPromise(diffPatchSinceCommit(cwdRepoRoot, baseCommit));
47047
+ if (patch) patches.push(patch);
47048
+ }
46990
47049
  }
46991
47050
  const sessionFile = await deps.resolveSessionFile(conv);
46992
- if (!sessionFile || !existsSync$1(sessionFile)) return result$1({ diff: "" });
47051
+ if (!sessionFile || !existsSync$1(sessionFile)) return result$1({ diff: patches.join("\n") });
46993
47052
  const { fileEditsByAssistantId } = await deps.getCachedMessages(sessionFile, false);
46994
- if (!fileEditsByAssistantId || fileEditsByAssistantId.size === 0) return result$1({ diff: "" });
47053
+ if (!fileEditsByAssistantId || fileEditsByAssistantId.size === 0) return result$1({ diff: patches.join("\n") });
46995
47054
  const repoRootCache = /* @__PURE__ */ new Map();
46996
47055
  const filesByRepo = await groupFilesByRepo([...fileEditsByAssistantId.values()].flat(), repoRootCache);
46997
- const patches = [];
46998
- for (const [repoRoot, filePaths] of filesByRepo) try {
46999
- const patch = await Effect.runPromise(diffPatchFilesAgainstHead(repoRoot, filePaths));
47000
- if (patch) patches.push(patch);
47001
- } catch {}
47056
+ for (const [repoRoot, filePaths] of filesByRepo) {
47057
+ if (repoRoot === cwdRepoRoot) continue;
47058
+ try {
47059
+ const patch = await diffPatchForFiles(repoRoot, conv.createdAt, filePaths);
47060
+ if (patch) patches.push(patch);
47061
+ } catch {}
47062
+ }
47002
47063
  return result$1({ diff: patches.join("\n") });
47003
47064
  } catch (error) {
47004
47065
  const msg = error instanceof Error ? error.message : String(error);
@@ -47011,35 +47072,34 @@ async function getConversationDiffTurn(name, turnId, fileFilter, deps) {
47011
47072
  const conv = lookupConversation(name);
47012
47073
  if (!conv) return result$1({ error: "Conversation not found" }, 404);
47013
47074
  const cwd = conv.cwd;
47014
- if (existsSync$1(join(cwd, ".git"))) {
47015
- const baseCommit = await Effect.runPromise(findCommitAtTime(cwd, conv.createdAt));
47016
- if (baseCommit) return result$1({
47017
- turnId,
47018
- diff: await Effect.runPromise(diffPatchSinceCommit(cwd, baseCommit, fileFilter))
47019
- });
47075
+ const cwdRepoRoot = existsSync$1(join(cwd, ".git")) ? cwd : null;
47076
+ const patches = [];
47077
+ if (cwdRepoRoot) {
47078
+ const baseCommit = await Effect.runPromise(findCommitAtTime(cwdRepoRoot, conv.createdAt));
47079
+ if (baseCommit) {
47080
+ const patch = await Effect.runPromise(diffPatchSinceCommit(cwdRepoRoot, baseCommit, fileFilter));
47081
+ if (patch) patches.push(patch);
47082
+ }
47020
47083
  }
47021
47084
  const assistantId = turnId.startsWith("conv-turn-") ? turnId.slice(10) : turnId;
47022
47085
  const sessionFile = await deps.resolveSessionFile(conv);
47023
- if (!sessionFile || !existsSync$1(sessionFile)) return result$1({ diff: "" });
47086
+ if (!sessionFile || !existsSync$1(sessionFile)) return result$1({
47087
+ turnId,
47088
+ diff: patches.join("\n")
47089
+ });
47024
47090
  const edits = (await deps.getCachedMessages(sessionFile, false)).fileEditsByAssistantId?.get(assistantId);
47025
- if (!edits || edits.length === 0) return result$1({ diff: "" });
47091
+ if (!edits || edits.length === 0) return result$1({
47092
+ turnId,
47093
+ diff: patches.join("\n")
47094
+ });
47026
47095
  const filesByRepo = await groupFilesByRepo(edits, /* @__PURE__ */ new Map(), fileFilter);
47027
- const baseCommitByRepo = /* @__PURE__ */ new Map();
47028
- const patches = [];
47029
- for (const [repoRoot, filePaths] of filesByRepo) try {
47030
- if (!baseCommitByRepo.has(repoRoot)) baseCommitByRepo.set(repoRoot, await Effect.runPromise(findCommitAtTime(repoRoot, conv.createdAt)));
47031
- const baseCommit = baseCommitByRepo.get(repoRoot) ?? null;
47032
- let patch;
47033
- if (baseCommit) {
47034
- const { stdout } = await promisify(exec)(`git diff --patch --minimal --no-color ${baseCommit} -- ${filePaths.map((p) => JSON.stringify(p)).join(" ")}`, {
47035
- cwd: repoRoot,
47036
- encoding: "utf-8",
47037
- maxBuffer: 50 * 1024 * 1024
47038
- });
47039
- patch = stdout;
47040
- } else patch = await Effect.runPromise(diffPatchFilesAgainstHead(repoRoot, filePaths));
47041
- if (patch) patches.push(patch);
47042
- } catch {}
47096
+ for (const [repoRoot, filePaths] of filesByRepo) {
47097
+ if (repoRoot === cwdRepoRoot) continue;
47098
+ try {
47099
+ const patch = await diffPatchForFiles(repoRoot, conv.createdAt, filePaths);
47100
+ if (patch) patches.push(patch);
47101
+ } catch {}
47102
+ }
47043
47103
  return result$1({
47044
47104
  turnId,
47045
47105
  diff: patches.join("\n")
@@ -48866,7 +48926,7 @@ async function refreshMergeStateFromGitHub(issueId, repo, prNumber) {
48866
48926
  let mergeState;
48867
48927
  let isDraft;
48868
48928
  let checksFailed;
48869
- const { isGitHubAppConfigured, getPullRequestState } = await import("./github-app-CU14oYzP.js");
48929
+ const { isGitHubAppConfigured, getPullRequestState } = await import("./github-app-CPfoFAdV.js");
48870
48930
  if (isGitHubAppConfigured()) {
48871
48931
  const prState = await Effect.runPromise(getPullRequestState(owner, repoName, prNumber));
48872
48932
  mergeable = prState.mergeable === null ? "UNKNOWN" : prState.mergeable ? "MERGEABLE" : "CONFLICTING";
@@ -49015,8 +49075,8 @@ async function handlePullRequestPromise(payload) {
49015
49075
  bumpIssuePrTabCacheGeneration(issueId);
49016
49076
  const repo = payload.repository.full_name;
49017
49077
  if (payload.action === "closed" && pr.merged === true) try {
49018
- const { postMergeLifecycle } = await import("./merge-agent-B-SnXOoc.js");
49019
- const { resolveProjectFromIssueSync } = await import("./projects-BKkwpH6q.js");
49078
+ const { postMergeLifecycle } = await import("./merge-agent-BQM3a8z5.js");
49079
+ const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
49020
49080
  const project = resolveProjectFromIssueSync(issueId);
49021
49081
  if (project) {
49022
49082
  const branchName = pr.head.ref;
@@ -50412,7 +50472,7 @@ async function registerProjectFromPath(opts) {
50412
50472
  registerProjectSync(key, projectConfig);
50413
50473
  const seededContextLayer = ensureProjectLayer(fullPath);
50414
50474
  try {
50415
- const { preTrustDirectorySync } = await import("./workspace-manager-B1WOfKvB.js");
50475
+ const { preTrustDirectorySync } = await import("./workspace-manager-ZTdJAy9M.js");
50416
50476
  preTrustDirectorySync(fullPath);
50417
50477
  } catch {}
50418
50478
  let hooksInstalled = 0;
@@ -50450,7 +50510,7 @@ init_specs();
50450
50510
  init_paths();
50451
50511
  const execAsync$2 = promisify(exec);
50452
50512
  async function getIssueDataService() {
50453
- const { getSharedIssueService } = await import("./issue-service-singleton-DBZabEl7.js");
50513
+ const { getSharedIssueService } = await import("./issue-service-singleton-DabvBWUp.js");
50454
50514
  return getSharedIssueService();
50455
50515
  }
50456
50516
  /** Returns true if the path exists (any type). */
@@ -50505,9 +50565,9 @@ function getSlotWorkSessionNumber(sessionId, issueLower) {
50505
50565
  return Number.parseInt(match[1], 10);
50506
50566
  }
50507
50567
  function getSessionTreeWorkspacePath(issueLower, baseWorkspacePath, projectPath, sessionId) {
50568
+ if (sessionId.toLowerCase() === `strike-${issueLower.toLowerCase()}`) return join(projectPath, "workspaces", `feature-${issueLower}-strike`);
50508
50569
  const slotNumber = getSlotWorkSessionNumber(sessionId, issueLower);
50509
- if (slotNumber === null) return baseWorkspacePath;
50510
- return join(projectPath, "workspaces", `feature-${issueLower}-slot-${slotNumber}`);
50570
+ return slotNumber === null ? baseWorkspacePath : join(projectPath, "workspaces", `feature-${issueLower}-slot-${slotNumber}`);
50511
50571
  }
50512
50572
  function compareSessionTreeSessionIds(a, b, issueLower) {
50513
50573
  const planningAgentId = `planning-${issueLower}`;
@@ -50907,7 +50967,7 @@ const getProjectReleaseStatusRoute = HttpRouter.add("GET", "/api/projects/:proje
50907
50967
  const projectKey = (yield* HttpRouter.params)["projectKey"] ?? "";
50908
50968
  return jsonResponse(yield* Effect.tryPromise({
50909
50969
  try: async () => {
50910
- const { fetchProjectReleaseStatus } = await import("./project-pipelines-CtNG_rvs.js");
50970
+ const { fetchProjectReleaseStatus } = await import("./project-pipelines-2sK1apsO.js");
50911
50971
  return fetchProjectReleaseStatus(projectKey);
50912
50972
  },
50913
50973
  catch: (err) => new Error(err instanceof Error ? err.message : String(err))
@@ -51422,7 +51482,7 @@ function fullPromptPreview(previews) {
51422
51482
  "## Runtime-only sections",
51423
51483
  "",
51424
51484
  "- Memory retrieval: injected at agent spawn when enabled; unavailable in this layer editor preview.",
51425
- "- Issue briefing and vBRIEF excerpts: injected per agent run; unavailable until a specific issue/session is selected.",
51485
+ "- Issue briefing and xBRIEF excerpts: injected per agent run; unavailable until a specific issue/session is selected.",
51426
51486
  "- Status and tool output: produced during the live session; not part of static context layers."
51427
51487
  ].join("\n");
51428
51488
  }
@@ -52578,7 +52638,7 @@ function getCheckpointWorker() {
52578
52638
  return worker;
52579
52639
  }
52580
52640
  async function runInline(operation, payload) {
52581
- const { claimTranscriptRange, commitTranscriptRange, releaseTranscriptRange, getTranscriptCheckpoint, listTranscriptCheckpoints } = await import("./checkpoints-B5jFNi2G.js");
52641
+ const { claimTranscriptRange, commitTranscriptRange, releaseTranscriptRange, getTranscriptCheckpoint, listTranscriptCheckpoints } = await import("./checkpoints-CpgCjAlN.js");
52582
52642
  switch (operation) {
52583
52643
  case "claimTranscriptRange": return claimTranscriptRange(payload);
52584
52644
  case "commitTranscriptRange": return commitTranscriptRange(payload);
@@ -53732,7 +53792,7 @@ function buildPendingTurn(input, fromOffset, toOffset, compressed) {
53732
53792
  };
53733
53793
  }
53734
53794
  async function emitMemoryObservationCreated(observation, timestamp) {
53735
- const { initEventStore } = await import("./event-store-CpBGsO6_.js");
53795
+ const { initEventStore } = await import("./event-store-Cr5PQwFC.js");
53736
53796
  await (await initEventStore()).appendAsync({
53737
53797
  type: "memory.observation_created",
53738
53798
  timestamp,
@@ -56744,7 +56804,7 @@ async function getFlywheelConversationPayload() {
56744
56804
  };
56745
56805
  }
56746
56806
  async function postFlywheelReportPayload() {
56747
- const { flywheelReportCommand } = await import("./flywheel-6WHU4O7A.js");
56807
+ const { flywheelReportCommand } = await import("./flywheel-DcBkQvgE.js");
56748
56808
  await flywheelReportCommand({ cwd: process.cwd() });
56749
56809
  return {
56750
56810
  status: 200,
@@ -56902,11 +56962,11 @@ const getMergeBlockersRoute = HttpRouter.add("GET", "/api/flywheel/merge-blocker
56902
56962
  async function defaultGetOrderedIssueIds() {
56903
56963
  const status = await readCurrentFlywheelStatusForDashboard();
56904
56964
  if (!status) return [];
56905
- const { computeMergeQueue } = await import("./flywheel-merge-order-CNKAY489.js");
56965
+ const { computeMergeQueue } = await import("./flywheel-merge-order-C-6zRLvM.js");
56906
56966
  return (await Effect.runPromise(computeMergeQueue(status.activePipeline, process.cwd()).pipe(Effect.provide(layer)))).map((i) => i.issueId);
56907
56967
  }
56908
56968
  async function defaultMergeOne(issueId) {
56909
- const { triggerMerge } = await import("./merge-ops-DwWCkSgo.js");
56969
+ const { triggerMerge } = await import("./merge-ops-DlB1IM0Y.js");
56910
56970
  const r = await triggerMerge(issueId);
56911
56971
  return r.success ? { ok: true } : {
56912
56972
  ok: false,
@@ -56926,7 +56986,7 @@ async function postFlywheelMergeNextPayload(payload, deps = {}) {
56926
56986
  body: { error: "n must be a positive integer" }
56927
56987
  };
56928
56988
  const issueIds = (await (deps.getOrderedIssueIds ?? defaultGetOrderedIssueIds)()).slice(0, n);
56929
- const { shipMergeBatch } = await import("./merge-batch-Byt-QnEl.js");
56989
+ const { shipMergeBatch } = await import("./merge-batch-Bwoyr8Je.js");
56930
56990
  return {
56931
56991
  status: 200,
56932
56992
  body: { outcomes: await shipMergeBatch(issueIds, { merge: deps.merge ?? defaultMergeOne }) }
@@ -57083,7 +57143,7 @@ const getFlywheelMergeQueueRoute = HttpRouter.add("GET", "/api/flywheel/merge-qu
57083
57143
  return yield* Effect.promise(async () => {
57084
57144
  const status = await readCurrentFlywheelStatusForDashboard();
57085
57145
  if (!status) return jsonResponse([]);
57086
- const { computeMergeQueue, resolveMergeQueuePrUrl } = await import("./flywheel-merge-order-CNKAY489.js");
57146
+ const { computeMergeQueue, resolveMergeQueuePrUrl } = await import("./flywheel-merge-order-C-6zRLvM.js");
57087
57147
  return jsonResponse(await Effect.runPromise(computeMergeQueue(status.activePipeline, process.cwd(), { getPrUrl: resolveMergeQueuePrUrl }).pipe(Effect.provide(layer))));
57088
57148
  });
57089
57149
  })));
@@ -57097,18 +57157,18 @@ function uatGenerationNameFromParam(param) {
57097
57157
  return decoded.startsWith("uat/") ? decoded : `uat/${decoded}`;
57098
57158
  }
57099
57159
  const getUatGenerationsRoute = HttpRouter.add("GET", "/api/flywheel/uat-generations", httpHandler(Effect.gen(function* () {
57100
- const { getUatGenerationsPayload } = yield* Effect.promise(() => import("./uat-train-0Ujk8GCv.js"));
57160
+ const { getUatGenerationsPayload } = yield* Effect.promise(() => import("./uat-train-cKfM-_WW.js"));
57101
57161
  return jsonResponse(yield* Effect.promise(() => getUatGenerationsPayload()));
57102
57162
  })));
57103
57163
  const getUatCandidateRoute = HttpRouter.add("GET", "/api/flywheel/uat-candidate", httpHandler(Effect.gen(function* () {
57104
- const { getUatCandidatePayload } = yield* Effect.promise(() => import("./uat-train-0Ujk8GCv.js"));
57164
+ const { getUatCandidatePayload } = yield* Effect.promise(() => import("./uat-train-cKfM-_WW.js"));
57105
57165
  return jsonResponse(yield* Effect.promise(() => getUatCandidatePayload()));
57106
57166
  })));
57107
57167
  const postUatGenerationStackRoute = HttpRouter.add("POST", "/api/flywheel/uat-generations/:name/stack", httpHandler(Effect.gen(function* () {
57108
57168
  const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
57109
57169
  if (authError) return authError;
57110
57170
  const name = uatGenerationNameFromParam((yield* HttpRouter.params)["name"] ?? "");
57111
- const { postUatGenerationStackPayload } = yield* Effect.promise(() => import("./uat-train-0Ujk8GCv.js"));
57171
+ const { postUatGenerationStackPayload } = yield* Effect.promise(() => import("./uat-train-cKfM-_WW.js"));
57112
57172
  const result = yield* Effect.promise(() => postUatGenerationStackPayload(name));
57113
57173
  if (!result.ok) return jsonResponse({ error: result.error }, { status: result.status });
57114
57174
  return jsonResponse({
@@ -57120,8 +57180,8 @@ const postUatGenerationPromoteRoute = HttpRouter.add("POST", "/api/flywheel/uat-
57120
57180
  const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
57121
57181
  if (authError) return authError;
57122
57182
  const name = uatGenerationNameFromParam((yield* HttpRouter.params)["name"] ?? "");
57123
- const { postUatGenerationPromotePayload } = yield* Effect.promise(() => import("./uat-train-0Ujk8GCv.js"));
57124
- const { firePostMergeLifecycle } = yield* Effect.promise(() => import("./specialists-D0gGXMZx.js"));
57183
+ const { postUatGenerationPromotePayload } = yield* Effect.promise(() => import("./uat-train-cKfM-_WW.js"));
57184
+ const { firePostMergeLifecycle } = yield* Effect.promise(() => import("./specialists-D5fRZXmN.js"));
57125
57185
  const result = yield* Effect.promise(() => postUatGenerationPromotePayload(name, firePostMergeLifecycle));
57126
57186
  if (!result.success) return jsonResponse(result, { status: result.reason === "not-found" ? 404 : result.reason === "merge-failed" ? 500 : 409 });
57127
57187
  return jsonResponse(result);
@@ -57134,7 +57194,7 @@ const postUatGenerationPromoteRoute = HttpRouter.add("POST", "/api/flywheel/uat-
57134
57194
  const postFlywheelAssembleUatRoute = HttpRouter.add("POST", "/api/flywheel/assemble-uat", httpHandler(Effect.gen(function* () {
57135
57195
  const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
57136
57196
  if (authError) return authError;
57137
- const { runUatTrainReconcile } = yield* Effect.promise(() => import("./uat-train-0Ujk8GCv.js"));
57197
+ const { runUatTrainReconcile } = yield* Effect.promise(() => import("./uat-train-cKfM-_WW.js"));
57138
57198
  return jsonResponse(yield* Effect.promise(() => runUatTrainReconcile({ force: true })));
57139
57199
  })));
57140
57200
  const getFlywheelStateRoute = HttpRouter.add("GET", "/api/flywheel/state", httpHandler(Effect.gen(function* () {
@@ -59957,6 +60017,27 @@ const postTieredCalloutsRoute = HttpRouter.add("POST", "/api/tiered/callouts", h
59957
60017
  })));
59958
60018
  const tieredCalloutsRouteLayer = Layer.mergeAll(postTieredCalloutsRoute);
59959
60019
  //#endregion
60020
+ //#region server-bind.ts
60021
+ function isAddressInUseError(error) {
60022
+ if (!error || typeof error !== "object") return false;
60023
+ if ("code" in error && error.code === "EADDRINUSE") return true;
60024
+ return "cause" in error && isAddressInUseError(error.cause);
60025
+ }
60026
+ const BIND_RETRY_DELAY_MS = 250;
60027
+ const BIND_RETRY_COUNT = 3;
60028
+ function retryDashboardBind(bind, onRetry) {
60029
+ let failures = 0;
60030
+ const observedBind = Effect.tapError(bind, (error) => Effect.sync(() => {
60031
+ failures += 1;
60032
+ if (failures <= BIND_RETRY_COUNT && isAddressInUseError(error)) onRetry?.(failures, BIND_RETRY_DELAY_MS);
60033
+ }));
60034
+ return Effect.retry(observedBind, {
60035
+ times: BIND_RETRY_COUNT,
60036
+ schedule: Schedule.spaced(Duration.millis(BIND_RETRY_DELAY_MS)),
60037
+ while: isAddressInUseError
60038
+ });
60039
+ }
60040
+ //#endregion
59960
60041
  //#region server.ts
59961
60042
  /**
59962
60043
  * Dashboard HTTP server — Effect-based with dual-runtime support (PAN-428 B5)
@@ -59982,14 +60063,19 @@ init_activity_logger();
59982
60063
  const HttpServerLive = Layer.unwrap(Effect.gen(function* () {
59983
60064
  const config = yield* ServerConfig;
59984
60065
  const [NodeHttpServer, NodeHttp] = yield* Effect.all([Effect.promise(() => import("@effect/platform-node/NodeHttpServer")), Effect.promise(() => import("node:http"))]);
59985
- const nodeServer = NodeHttp.createServer();
59986
- setupTerminalWebSocket(nodeServer);
59987
- setupVoiceWebSocket(nodeServer);
59988
- setupAutoPresoWebSocket(nodeServer);
59989
- return NodeHttpServer.layer(() => nodeServer, {
60066
+ const bind = retryDashboardBind(NodeHttpServer.make(() => {
60067
+ const nodeServer = NodeHttp.createServer();
60068
+ setupTerminalWebSocket(nodeServer);
60069
+ setupVoiceWebSocket(nodeServer);
60070
+ setupAutoPresoWebSocket(nodeServer);
60071
+ return nodeServer;
60072
+ }, {
59990
60073
  host: config.host,
59991
60074
  port: config.port
60075
+ }), (attempt, delayMs) => {
60076
+ console.warn(`[overdeck] HTTP bind failed with EADDRINUSE; retry ${attempt}/3 in ${delayMs}ms`);
59992
60077
  });
60078
+ return Layer.mergeAll(Layer.effect(HttpServer.HttpServer)(bind), NodeHttpServer.layerHttpServices);
59993
60079
  }));
59994
60080
  const PlatformServicesLive = Layer.unwrap(Effect.gen(function* () {
59995
60081
  const { layer } = yield* Effect.promise(() => import("@effect/platform-node/NodeServices"));
@@ -60081,6 +60167,7 @@ const makeServerLayer = Layer.unwrap(Effect.gen(function* () {
60081
60167
  const httpListeningLayer = Layer.effectDiscard(Effect.gen(function* () {
60082
60168
  yield* HttpServer.HttpServer;
60083
60169
  yield* Effect.sync(() => {
60170
+ markDashboardListening();
60084
60171
  console.log(`[boot-timing] HTTP server listening at +${Math.round(performance.now())}ms (since process start)`);
60085
60172
  console.log(`[overdeck] Dashboard listening on http://${config.host}:${config.port}`);
60086
60173
  const mode = process.env["OVERDECK_MODE"] === "production" ? "production mode" : "development mode";
@@ -60139,7 +60226,7 @@ function buildAwaitingInputActivityMessage(agentId, issueId, kinds) {
60139
60226
  const kindList = kinds.length > 0 ? kinds.join(", ") : "input";
60140
60227
  return issueId ? `${agentId} on ${issueId} is waiting for ${kindList}` : `${agentId} is waiting for ${kindList}`;
60141
60228
  }
60142
- async function pollOnce$1(state) {
60229
+ async function pollOnce(state) {
60143
60230
  let runningAgents;
60144
60231
  try {
60145
60232
  runningAgents = await Effect.runPromise(listRunningAgents());
@@ -60269,8 +60356,8 @@ async function pollOnce$1(state) {
60269
60356
  /** Poll interval: 10 seconds (was 3s). The enrichment data changes slowly —
60270
60357
  * pending questions, resolution state, phase — none of these need sub-second
60271
60358
  * latency. 10s eliminates ~70% of poller I/O without any user-visible lag. */
60272
- const POLL_INTERVAL_MS$4 = 1e4;
60273
- const serviceState$3 = {
60359
+ const POLL_INTERVAL_MS$3 = 1e4;
60360
+ const serviceState$2 = {
60274
60361
  timer: null,
60275
60362
  lastEnrichment: /* @__PURE__ */ new Map(),
60276
60363
  lastScan: /* @__PURE__ */ new Map(),
@@ -60278,18 +60365,18 @@ const serviceState$3 = {
60278
60365
  reconciledAgentIds: /* @__PURE__ */ new Set()
60279
60366
  };
60280
60367
  function startAgentEnrichmentService() {
60281
- if (serviceState$3.timer !== null) return;
60282
- serviceState$3.timer = setInterval(() => {
60283
- pollOnce$1(serviceState$3).catch(() => {});
60284
- }, POLL_INTERVAL_MS$4);
60368
+ if (serviceState$2.timer !== null) return;
60369
+ serviceState$2.timer = setInterval(() => {
60370
+ pollOnce(serviceState$2).catch(() => {});
60371
+ }, POLL_INTERVAL_MS$3);
60285
60372
  }
60286
60373
  function stopAgentEnrichmentService() {
60287
- if (serviceState$3.timer !== null) {
60288
- clearInterval(serviceState$3.timer);
60289
- serviceState$3.timer = null;
60374
+ if (serviceState$2.timer !== null) {
60375
+ clearInterval(serviceState$2.timer);
60376
+ serviceState$2.timer = null;
60290
60377
  }
60291
- serviceState$3.lastEnrichment.clear();
60292
- serviceState$3.lastScan.clear();
60378
+ serviceState$2.lastEnrichment.clear();
60379
+ serviceState$2.lastScan.clear();
60293
60380
  }
60294
60381
  //#endregion
60295
60382
  //#region services/merge-blocker-reconcile-service.ts
@@ -60309,7 +60396,7 @@ function stopAgentEnrichmentService() {
60309
60396
  * Bounded + cheap: each issue has a throttle. Ready/no-blocker rows use the PAN-1620
60310
60397
  * 3-minute cadence; already-blocked mergeability rows use a 10-minute cadence.
60311
60398
  */
60312
- const POLL_INTERVAL_MS$3 = 6e4;
60399
+ const POLL_INTERVAL_MS$2 = 6e4;
60313
60400
  /** Re-check each ready-to-merge PR at most this often, to bound `gh` calls. */
60314
60401
  const RECHECK_INTERVAL_MS = 18e4;
60315
60402
  /** Re-check already-flagged mergeability blockers less often; they are not mergeable yet. */
@@ -60320,7 +60407,7 @@ const MERGEABILITY_BLOCKERS = new Set([
60320
60407
  "failing_checks"
60321
60408
  ]);
60322
60409
  const MAX_REFRESH_CONCURRENCY = 4;
60323
- const serviceState$2 = {
60410
+ const serviceState$1 = {
60324
60411
  timer: null,
60325
60412
  lastChecked: /* @__PURE__ */ new Map(),
60326
60413
  blockerLastChecked: /* @__PURE__ */ new Map(),
@@ -60375,11 +60462,11 @@ async function reconcileOnce(state) {
60375
60462
  for (const id of [...state.blockerLastChecked.keys()]) if (!hasMergeabilityBlocker(candidateById.get(id)?.blockerReasons)) state.blockerLastChecked.delete(id);
60376
60463
  }
60377
60464
  function startMergeBlockerReconcileService() {
60378
- if (serviceState$2.timer !== null) return;
60379
- serviceState$2.timer = setInterval(() => {
60380
- reconcileOnce(serviceState$2).catch(() => {});
60381
- }, POLL_INTERVAL_MS$3);
60382
- serviceState$2.timer.unref?.();
60465
+ if (serviceState$1.timer !== null) return;
60466
+ serviceState$1.timer = setInterval(() => {
60467
+ reconcileOnce(serviceState$1).catch(() => {});
60468
+ }, POLL_INTERVAL_MS$2);
60469
+ serviceState$1.timer.unref?.();
60383
60470
  }
60384
60471
  function enqueueRefresh(state, task) {
60385
60472
  if (state.refreshInFlight.has(task.issueId)) return;
@@ -60402,6 +60489,174 @@ function drainRefreshQueue(state) {
60402
60489
  }
60403
60490
  }
60404
60491
  //#endregion
60492
+ //#region services/project-resource-refresh-queue.ts
60493
+ init_projects();
60494
+ const PROJECT_RESOURCE_CONVERGENCE_INTERVAL_MS = 5 * 6e4;
60495
+ function createProjectResourceRefreshQueue(deps) {
60496
+ const debounceMs = deps.debounceMs ?? 1e3;
60497
+ const now = deps.now ?? Date.now;
60498
+ const pending = /* @__PURE__ */ new Map();
60499
+ const reasons = /* @__PURE__ */ new Map();
60500
+ const idleWaiters = /* @__PURE__ */ new Set();
60501
+ let activeProjectPaths = [];
60502
+ let timer = null;
60503
+ let running = false;
60504
+ let stopped = false;
60505
+ let lastStartedAt = null;
60506
+ let lastCompletedAt = null;
60507
+ let lastError = null;
60508
+ const isIdle = () => !running && timer === null && pending.size === 0;
60509
+ const resolveIdleWaiters = () => {
60510
+ if (!isIdle()) return;
60511
+ for (const resolve of idleWaiters) resolve();
60512
+ idleWaiters.clear();
60513
+ };
60514
+ const drain = async () => {
60515
+ timer = null;
60516
+ if (running || stopped) return;
60517
+ running = true;
60518
+ try {
60519
+ while (!stopped && pending.size > 0) {
60520
+ const projects = [...pending.values()];
60521
+ const reasonsByProjectPath = /* @__PURE__ */ new Map();
60522
+ for (const project of projects) {
60523
+ reasonsByProjectPath.set(project.path, new Set(reasons.get(project.path) ?? []));
60524
+ reasons.delete(project.path);
60525
+ }
60526
+ pending.clear();
60527
+ activeProjectPaths = projects.map((project) => project.path);
60528
+ lastStartedAt = now();
60529
+ try {
60530
+ await deps.refreshProjects(projects, { reasonsByProjectPath });
60531
+ lastError = null;
60532
+ } catch (error) {
60533
+ lastError = error instanceof Error ? error.message : String(error);
60534
+ console.warn("[project-resource-refresh] batch failed:", lastError);
60535
+ } finally {
60536
+ activeProjectPaths = [];
60537
+ lastCompletedAt = now();
60538
+ }
60539
+ }
60540
+ } finally {
60541
+ running = false;
60542
+ resolveIdleWaiters();
60543
+ }
60544
+ };
60545
+ const schedule = () => {
60546
+ if (stopped || running || timer) return;
60547
+ timer = setTimeout(() => void drain(), debounceMs);
60548
+ timer.unref?.();
60549
+ };
60550
+ const enqueueProject = (project, reason) => {
60551
+ if (stopped) return;
60552
+ pending.set(project.path, project);
60553
+ const projectReasons = reasons.get(project.path) ?? /* @__PURE__ */ new Set();
60554
+ projectReasons.add(reason);
60555
+ reasons.set(project.path, projectReasons);
60556
+ schedule();
60557
+ };
60558
+ return {
60559
+ enqueueProject,
60560
+ enqueueProjects(projects, reason) {
60561
+ for (const project of projects) enqueueProject(project, reason);
60562
+ },
60563
+ whenIdle() {
60564
+ if (isIdle()) return Promise.resolve();
60565
+ return new Promise((resolve) => idleWaiters.add(resolve));
60566
+ },
60567
+ getState() {
60568
+ return {
60569
+ running,
60570
+ activeProjectPaths: [...activeProjectPaths],
60571
+ pendingProjectPaths: [...pending.keys()],
60572
+ lastStartedAt,
60573
+ lastCompletedAt,
60574
+ lastError
60575
+ };
60576
+ },
60577
+ stop() {
60578
+ stopped = true;
60579
+ if (timer) clearTimeout(timer);
60580
+ timer = null;
60581
+ pending.clear();
60582
+ reasons.clear();
60583
+ resolveIdleWaiters();
60584
+ }
60585
+ };
60586
+ }
60587
+ const MEMBERSHIP_REFRESH_REASONS = new Set(["boot-warm", "periodic-convergence"]);
60588
+ const projectResourceRefreshQueue = createProjectResourceRefreshQueue({ refreshProjects: (projects, context) => refreshResourceAllocatedProjects(projects, { refreshMembership: [...context.reasonsByProjectPath.values()].some((projectReasons) => [...projectReasons].some((reason) => MEMBERSHIP_REFRESH_REASONS.has(reason))) }) });
60589
+ function enqueueProjectsResourceRefresh(projects, reason) {
60590
+ projectResourceRefreshQueue.enqueueProjects(projects, reason);
60591
+ }
60592
+ function whenProjectResourceRefreshIdle() {
60593
+ return projectResourceRefreshQueue.whenIdle();
60594
+ }
60595
+ function getProjectResourceRefreshQueueState() {
60596
+ return projectResourceRefreshQueue.getState();
60597
+ }
60598
+ function stopProjectResourceRefreshQueue() {
60599
+ projectResourceRefreshQueue.stop();
60600
+ }
60601
+ function startProjectResourceConvergence() {
60602
+ const timer = setInterval(() => {
60603
+ enqueueProjectsResourceRefresh(listProjectsSync().map((entry) => entry.config), "periodic-convergence");
60604
+ }, PROJECT_RESOURCE_CONVERGENCE_INTERVAL_MS);
60605
+ timer.unref?.();
60606
+ return () => clearInterval(timer);
60607
+ }
60608
+ //#endregion
60609
+ //#region services/resource-refresh-triggers.ts
60610
+ init_agents$1();
60611
+ init_projects();
60612
+ init_event_store();
60613
+ const TRIGGER_EVENT_TYPES = new Set([
60614
+ "agent.created",
60615
+ "agent.started",
60616
+ "agent.stopped",
60617
+ "agent.completed",
60618
+ "agent.heartbeat_dead"
60619
+ ]);
60620
+ function createResourceRefreshTriggers(deps) {
60621
+ const warn = deps.warn ?? ((message) => console.warn(message));
60622
+ return deps.subscribe((event) => {
60623
+ if (!TRIGGER_EVENT_TYPES.has(event.type)) return;
60624
+ const payload = event.payload;
60625
+ let project = null;
60626
+ if (typeof payload?.projectKey === "string") project = deps.projectForKey(payload.projectKey);
60627
+ if (!project && typeof payload?.issueId === "string") project = deps.projectForIssue(payload.issueId);
60628
+ if (!project && typeof payload?.agentId === "string") {
60629
+ const issueId = deps.issueForAgent(payload.agentId);
60630
+ if (issueId) project = deps.projectForIssue(issueId);
60631
+ }
60632
+ if (!project) {
60633
+ warn(`[resource-refresh] skipped ${event.type}: affected project could not be resolved`);
60634
+ return;
60635
+ }
60636
+ deps.enqueueProjects([project], event.type);
60637
+ });
60638
+ }
60639
+ function startResourceRefreshTriggers() {
60640
+ const entries = () => listProjectsSync();
60641
+ return createResourceRefreshTriggers({
60642
+ subscribe: (fn) => getEventStore().subscribe(fn),
60643
+ projectForIssue: (issueId) => {
60644
+ const resolved = resolveProjectFromIssueSync(issueId);
60645
+ if (!resolved) return null;
60646
+ return entries().find((entry) => entry.key === resolved.projectKey)?.config ?? null;
60647
+ },
60648
+ projectForKey: (projectKey) => entries().find((entry) => entry.key === projectKey)?.config ?? null,
60649
+ issueForAgent: (agentId) => {
60650
+ try {
60651
+ return getAgentStateSync(agentId)?.issueId ?? null;
60652
+ } catch {
60653
+ return null;
60654
+ }
60655
+ },
60656
+ enqueueProjects: enqueueProjectsResourceRefresh
60657
+ });
60658
+ }
60659
+ //#endregion
60405
60660
  //#region ../../lib/cloister/stale-check-classifier.ts
60406
60661
  /**
60407
60662
  * Pure classification for stale PR checks inherited from a red main branch.
@@ -60587,12 +60842,12 @@ async function rerunFailedRun(repo, runId) {
60587
60842
  //#endregion
60588
60843
  //#region services/stale-check-retrigger-service.ts
60589
60844
  init_review_status_sync();
60590
- const POLL_INTERVAL_MS$2 = 6e4;
60845
+ const POLL_INTERVAL_MS$1 = 6e4;
60591
60846
  const MAIN_PROBE_INTERVAL_MS = 3 * 6e4;
60592
60847
  const EVAL_INTERVAL_MS = 10 * 6e4;
60593
60848
  const MAX_RERUNS_PER_TICK = 5;
60594
60849
  const RUN_STATE_RETENTION_MS = 1440 * 6e4;
60595
- const serviceState$1 = {
60850
+ const serviceState = {
60596
60851
  timer: null,
60597
60852
  repoWindows: /* @__PURE__ */ new Map(),
60598
60853
  lastEvaluated: /* @__PURE__ */ new Map(),
@@ -60738,120 +60993,21 @@ async function runTickIfIdle(state) {
60738
60993
  }
60739
60994
  }
60740
60995
  function startStaleCheckRetriggerService() {
60741
- if (serviceState$1.timer !== null) return;
60742
- serviceState$1.timer = setInterval(() => void runTickIfIdle(serviceState$1), POLL_INTERVAL_MS$2);
60743
- serviceState$1.timer.unref?.();
60996
+ if (serviceState.timer !== null) return;
60997
+ serviceState.timer = setInterval(() => void runTickIfIdle(serviceState), POLL_INTERVAL_MS$1);
60998
+ serviceState.timer.unref?.();
60744
60999
  }
60745
61000
  function shouldStartStaleCheckRetriggerService(env = process.env) {
60746
61001
  return env.OVERDECK_DISABLE_DEACON !== "1";
60747
61002
  }
60748
61003
  function stopStaleCheckRetriggerService() {
60749
- if (serviceState$1.timer !== null) clearInterval(serviceState$1.timer);
60750
- serviceState$1.timer = null;
60751
- serviceState$1.repoWindows.clear();
60752
- serviceState$1.lastEvaluated.clear();
60753
- serviceState$1.successfulRunIds.clear();
60754
- serviceState$1.failedRunsByIssue.clear();
60755
- serviceState$1.loggedSkips.clear();
60756
- }
60757
- //#endregion
60758
- //#region services/agent-output-service.ts
60759
- /**
60760
- * Agent Output Service (PAN-1221 F3)
60761
- *
60762
- * Background poller that captures tmux pane output for each running agent
60763
- * every ~3 seconds and emits `agent.output_received` domain events when
60764
- * new lines appear.
60765
- *
60766
- * This restores the event-driven output pipeline that DrawerActiveAgent
60767
- * expects — the reducer and WebSocket subscription already exist, but no
60768
- * server code was emitting the events.
60769
- */
60770
- init_agents$1();
60771
- init_tmux();
60772
- init_concurrency$1();
60773
- init_event_store();
60774
- function splitLines(text) {
60775
- const lines = text.split("\n");
60776
- if (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
60777
- return lines;
60778
- }
60779
- /**
60780
- * Find new lines by looking for the longest suffix of `previous` that matches
60781
- * a prefix of `current`. The non-overlapping prefix of `current` is returned.
60782
- * If there is no overlap, all of `current` is new (pane was cleared or scrolled
60783
- * past the overlap window).
60784
- */
60785
- function diffLines(previous, current) {
60786
- if (previous.length === 0) return current;
60787
- for (let start = 0; start < previous.length; start++) {
60788
- const suffix = previous.slice(start);
60789
- if (suffix.length > current.length) continue;
60790
- if (suffix.every((line, i) => line === current[i])) return current.slice(suffix.length);
60791
- }
60792
- return current;
60793
- }
60794
- async function pollOnce(state) {
60795
- let runningAgents;
60796
- try {
60797
- runningAgents = await Effect.runPromise(listRunningAgents());
60798
- } catch {
60799
- return;
60800
- }
60801
- const eventStore = getEventStore();
60802
- const activeAgents = runningAgents.filter((a) => a.tmuxActive);
60803
- await Effect.runPromise(withConcurrencyLimit(activeAgents.map((agent) => Effect.tryPromise({
60804
- try: async () => {
60805
- const { id: agentId } = agent;
60806
- let stdout;
60807
- try {
60808
- const remoteState = await readFile(join(homedir$1(), ".overdeck", "agents", agentId, "remote-state.json"), "utf-8").then((text) => JSON.parse(text)).catch(() => null);
60809
- if (remoteState?.location === "remote" && remoteState?.vmName) {
60810
- const { getRemoteAgentOutput } = await import("./remote-agents-D6O_zETW.js");
60811
- stdout = await getRemoteAgentOutput(agentId, remoteState.vmName, 50);
60812
- } else stdout = await Effect.runPromise(capturePane(agentId, 50));
60813
- } catch {
60814
- stdout = await Effect.runPromise(capturePane(agentId, 50).pipe(Effect.catch(() => Effect.succeed(""))));
60815
- }
60816
- if (!stdout || stdout.trim() === "" || stdout.trim() === "Session not found") return;
60817
- const previousOutput = state.lastOutput.get(agentId) ?? "";
60818
- if (stdout === previousOutput) return;
60819
- const newLines = diffLines(splitLines(previousOutput), splitLines(stdout));
60820
- state.lastOutput.set(agentId, stdout);
60821
- if (newLines.length === 0) return;
60822
- const event = {
60823
- type: "agent.output_received",
60824
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
60825
- payload: {
60826
- agentId,
60827
- lines: newLines
60828
- }
60829
- };
60830
- eventStore.emitOnly(event);
60831
- },
60832
- catch: (cause) => cause
60833
- })), 4));
60834
- const activeIds = new Set(activeAgents.map((a) => a.id));
60835
- for (const id of state.lastOutput.keys()) if (!activeIds.has(id)) state.lastOutput.delete(id);
60836
- }
60837
- /** Poll interval: 3 seconds. Output is high-frequency and latency-sensitive. */
60838
- const POLL_INTERVAL_MS$1 = 3e3;
60839
- const serviceState = {
60840
- timer: null,
60841
- lastOutput: /* @__PURE__ */ new Map()
60842
- };
60843
- function startAgentOutputService() {
60844
- if (serviceState.timer !== null) return;
60845
- serviceState.timer = setInterval(() => {
60846
- pollOnce(serviceState).catch(() => {});
60847
- }, POLL_INTERVAL_MS$1);
60848
- }
60849
- function stopAgentOutputService() {
60850
- if (serviceState.timer !== null) {
60851
- clearInterval(serviceState.timer);
60852
- serviceState.timer = null;
60853
- }
60854
- serviceState.lastOutput.clear();
61004
+ if (serviceState.timer !== null) clearInterval(serviceState.timer);
61005
+ serviceState.timer = null;
61006
+ serviceState.repoWindows.clear();
61007
+ serviceState.lastEvaluated.clear();
61008
+ serviceState.successfulRunIds.clear();
61009
+ serviceState.failedRunsByIssue.clear();
61010
+ serviceState.loggedSkips.clear();
60855
61011
  }
60856
61012
  //#endregion
60857
61013
  //#region services/conversation-lifecycle.ts
@@ -60871,7 +61027,7 @@ function stopAgentOutputService() {
60871
61027
  * spawn-only.
60872
61028
  */
60873
61029
  init_conversations();
60874
- init_tmux();
61030
+ init_runtime_census();
60875
61031
  init_paths();
60876
61032
  init_behavior();
60877
61033
  const POLL_INTERVAL_MS = 1e4;
@@ -60915,12 +61071,10 @@ async function tailFile(path, maxBytes) {
60915
61071
  * a "; "-prefixed suffix for the log line, or "" when nothing is available.
60916
61072
  * Every probe is independently guarded so a diagnostics failure never throws.
60917
61073
  */
60918
- async function captureCorpseDiagnostics(tmuxSession) {
61074
+ async function captureCorpseDiagnostics(tmuxSession, census) {
60919
61075
  const parts = [];
60920
- try {
60921
- const status = (await Effect.runPromise(listPaneValues(tmuxSession, "#{pane_dead_status}"))).find((v) => v.trim() !== "")?.trim();
60922
- if (status) parts.push(`exitStatus=${status}`);
60923
- } catch {}
61076
+ const status = (census.panesBySession.get(tmuxSession) ?? []).map((pane) => pane.paneDeadStatus).find((value) => value !== null);
61077
+ if (status !== void 0) parts.push(`exitStatus=${status}`);
60924
61078
  try {
60925
61079
  const logPath = join$1(getOverdeckHome(), "agents", tmuxSession, "output.log");
60926
61080
  if (existsSync(logPath)) {
@@ -60940,7 +61094,10 @@ async function pollConversations() {
60940
61094
  try {
60941
61095
  const conversations = listConversations();
60942
61096
  if (conversations.length === 0) return;
60943
- const aliveSessions = new Set(await Effect.runPromise(listSessionNames()));
61097
+ const census = await getRuntimeCensus();
61098
+ if (!census.available) return;
61099
+ const aliveSessions = new Set(census.sessionNames);
61100
+ let revalidationCensus = null;
60944
61101
  const endedConversations = [];
60945
61102
  let sessionGoneCount = 0;
60946
61103
  let keepAliveCorpseCount = 0;
@@ -60948,8 +61105,8 @@ async function pollConversations() {
60948
61105
  const now = Date.now();
60949
61106
  for (const conv of conversations) {
60950
61107
  if (now - new Date(conv.createdAt).getTime() < SPAWN_GRACE_PERIOD_MS) continue;
60951
- const sessionGone = !aliveSessions.has(conv.tmuxSession);
60952
- const harnessGone = !sessionGone && !await isHarnessProcessAlive(conv.tmuxSession);
61108
+ let sessionGone = !aliveSessions.has(conv.tmuxSession);
61109
+ let harnessGone = !sessionGone && !await runtimeCensusHasHarnessProcess(census, conv.tmuxSession);
60953
61110
  if (!sessionGone && !harnessGone) {
60954
61111
  if (conv.status === "ended") {
60955
61112
  console.log(`[conversation-lifecycle] Session ${conv.tmuxSession} alive but row marked ended — resurrecting to active`);
@@ -60962,9 +61119,14 @@ async function pollConversations() {
60962
61119
  const fresh = getConversationByName(conv.name) ?? conv;
60963
61120
  const lastAliveSignalMs = Math.max(new Date(fresh.createdAt).getTime() || 0, fresh.lastAttachedAt ? new Date(fresh.lastAttachedAt).getTime() || 0 : 0);
60964
61121
  if (Date.now() - lastAliveSignalMs < SPAWN_GRACE_PERIOD_MS) continue;
61122
+ revalidationCensus ??= await refreshRuntimeCensus();
61123
+ if (!revalidationCensus.available) continue;
61124
+ sessionGone = !revalidationCensus.sessionNames.has(conv.tmuxSession);
61125
+ harnessGone = !sessionGone && !await runtimeCensusHasHarnessProcess(revalidationCensus, conv.tmuxSession);
61126
+ if (!sessionGone && !harnessGone) continue;
60965
61127
  if (process.env.DEBUG?.includes("conversation-lifecycle")) console.log(sessionGone ? `[conversation-lifecycle] Session ${conv.tmuxSession} gone — marking ended` : `[conversation-lifecycle] Session ${conv.tmuxSession} alive but harness exited (keep-alive corpse) — marking ended`);
60966
61128
  if (!sessionGone) {
60967
- const diag = await captureCorpseDiagnostics(conv.tmuxSession);
61129
+ const diag = await captureCorpseDiagnostics(conv.tmuxSession, revalidationCensus);
60968
61130
  if (diag) keepAliveCorpseDiagnostics.push(`${conv.tmuxSession}${diag}`);
60969
61131
  }
60970
61132
  markConversationEnded(conv.name);
@@ -61619,7 +61781,8 @@ init_event_store();
61619
61781
  init_tracker_config();
61620
61782
  const DEFAULT_INTERVAL_MS = 6e4;
61621
61783
  const DEFAULT_LOOKBACK_MS = 5 * 6e4;
61622
- const BOT_LOGIN = "panopticon-agent[bot]";
61784
+ const FLYWHEEL_FILED_BY_TRAILER = "\"Flywheel-Filed-By:\" in:body";
61785
+ const LEGACY_BOT_LOGIN = "panopticon-agent[bot]";
61623
61786
  var CacheServiceRateLimitStore = class {
61624
61787
  cache = null;
61625
61788
  getCache() {
@@ -61725,14 +61888,14 @@ function createSubstrateBugPoller(options = {}) {
61725
61888
  const since = isoLookback(now(), lookbackMs);
61726
61889
  for (const repo of config.repos) try {
61727
61890
  const repoQualifier = `repo:${repo.owner}/${repo.repo}`;
61728
- const authorResults = await fetchSearch(config.token, searchQuery([
61891
+ const trailerResults = await fetchSearch(config.token, searchQuery([
61729
61892
  repoQualifier,
61730
61893
  "is:issue",
61731
61894
  "-is:pr",
61732
- `author:${BOT_LOGIN}`,
61895
+ FLYWHEEL_FILED_BY_TRAILER,
61733
61896
  `updated:>=${since}`
61734
61897
  ]));
61735
- if (authorResults === null) return;
61898
+ if (trailerResults === null) return;
61736
61899
  const substrateResults = await fetchSearch(config.token, searchQuery([
61737
61900
  repoQualifier,
61738
61901
  "is:issue",
@@ -61742,12 +61905,12 @@ function createSubstrateBugPoller(options = {}) {
61742
61905
  ]));
61743
61906
  if (substrateResults === null) return;
61744
61907
  const byNumber = /* @__PURE__ */ new Map();
61745
- for (const issue of [...authorResults, ...substrateResults]) byNumber.set(issue.number, issue);
61908
+ for (const issue of [...trailerResults, ...substrateResults]) byNumber.set(issue.number, issue);
61746
61909
  for (const issue of byNumber.values()) {
61747
61910
  const issueId = issueIdFor(repo.prefix, issue.number);
61748
61911
  if (!issueId) continue;
61749
61912
  const trailer = parseSubstrateBugTrailer(issue.body);
61750
- const filedBy = trailer.filedBy ?? (issue.user?.login === BOT_LOGIN ? "agent" : "operator");
61913
+ const filedBy = trailer.filedBy ?? (issue.user?.login === LEGACY_BOT_LOGIN ? "agent" : "operator");
61751
61914
  const labelNames = (issue.labels ?? []).map((label) => typeof label === "string" ? label : label.name ?? "");
61752
61915
  const affectedCriteria = parseAffectedCriteria(issue.body, labelNames);
61753
61916
  const existing = repository.getByIssueId(issueId);
@@ -62013,7 +62176,7 @@ const RESTART_MARKER = join$1(homedir(), ".overdeck", "dashboard-restarting.json
62013
62176
  * loads new content-hashed chunk filenames (no ERR_MODULE_NOT_FOUND after rebuild).
62014
62177
  */
62015
62178
  async function defaultLifecycleRunner(pending) {
62016
- const { postMergeLifecycle, notifyTldrDaemon } = await import("./merge-agent-B-SnXOoc.js");
62179
+ const { postMergeLifecycle, notifyTldrDaemon } = await import("./merge-agent-BQM3a8z5.js");
62017
62180
  await postMergeLifecycle(pending.issueId, pending.projectPath, pending.sourceBranch, { skipDeploy: true });
62018
62181
  if (pending.sourceBranch) await notifyTldrDaemon(pending.projectPath, pending.sourceBranch);
62019
62182
  }
@@ -62334,7 +62497,7 @@ function failureReason(result) {
62334
62497
  return result.error ?? result.message ?? `merge returned status ${result.statusCode ?? "unknown"}`;
62335
62498
  }
62336
62499
  async function defaultMergeIssue(issueId) {
62337
- const { triggerMerge } = await import("./merge-ops-DwWCkSgo.js");
62500
+ const { triggerMerge } = await import("./merge-ops-DlB1IM0Y.js");
62338
62501
  return triggerMerge(issueId);
62339
62502
  }
62340
62503
  function defaultAnnounceFailure(issueId, reason) {
@@ -62581,7 +62744,7 @@ const defaultDependencies = {
62581
62744
  inspect: inspectStateMigration,
62582
62745
  ensureWorktree: ensureStateWorktree,
62583
62746
  migrate: async (projectKey, project, signal) => {
62584
- const { migrateProjectState } = await import("./state-migrate-BeBW0KXA.js");
62747
+ const { migrateProjectState } = await import("./state-migrate-Dkzaxvny.js");
62585
62748
  await migrateProjectState(projectKey, { signal }, project);
62586
62749
  },
62587
62750
  clearCache: clearStateMigrationCache,
@@ -62623,7 +62786,7 @@ async function reconcile(projectKey, project, dependencies, signal) {
62623
62786
  signal
62624
62787
  });
62625
62788
  if (worktree.status === "dirty" || worktree.status === "error") return blocked(projectKey, worktreeBlockReason(worktree));
62626
- if (worktree.status === "legacy") return blocked(projectKey, "The remote migration marker is valid but the local state worktree still resolves to the legacy project checkout.");
62789
+ if (worktree.status === "legacy") return blocked(projectKey, worktree.detail);
62627
62790
  return {
62628
62791
  status: "ready",
62629
62792
  projectKey,
@@ -62724,16 +62887,34 @@ init_projects();
62724
62887
  initDashboardLogFile();
62725
62888
  console.log(`[boot-timing] module graph loaded at +${Math.round(performance.now())}ms (since process start)`);
62726
62889
  console.log(`[overdeck] Boot gates: ${formatBootGateState(resolveBootGates())}`);
62727
- startEventLoopMonitor();
62728
- console.log("[overdeck] Event loop delay monitor started");
62729
62890
  await mkdir(getOverdeckHome(), { recursive: true });
62730
62891
  ensureInternalTokenSync();
62731
- warnIfAutonomousMergeBackendUnavailable();
62732
- warnIfAppCannotMerge();
62733
62892
  await ensureManagedTmuxContextOnce();
62734
62893
  await initTrackerConfigCache().catch((err) => {
62735
62894
  console.log("[tracker-config] Warning: failed to cache .overdeck.env:", err.message);
62736
62895
  });
62896
+ try {
62897
+ const overdeckDbPath = getOverdeckDatabasePath();
62898
+ if (!existsSync$1(overdeckDbPath)) {
62899
+ createOverdeckDatabase({ dbPath: overdeckDbPath });
62900
+ console.log(`[overdeck] Created overdeck.db at ${overdeckDbPath}`);
62901
+ }
62902
+ } catch (err) {
62903
+ console.warn("[overdeck] Overdeck db init failed (non-fatal):", err);
62904
+ }
62905
+ const main = runServer.pipe(Effect.provide(ServerConfigLayer));
62906
+ if (typeof Bun !== "undefined") {
62907
+ const { runMain } = await import("@effect/platform-bun/BunRuntime");
62908
+ runMain(main);
62909
+ } else {
62910
+ const { runMain } = await import("@effect/platform-node/NodeRuntime");
62911
+ runMain(main);
62912
+ }
62913
+ await whenDashboardListening();
62914
+ startEventLoopMonitor();
62915
+ console.log("[overdeck] Event loop delay monitor started");
62916
+ warnIfAutonomousMergeBackendUnavailable();
62917
+ warnIfAppCannotMerge();
62737
62918
  const isPeerDashboard = process.env.OVERDECK_DISABLE_DEACON === "1";
62738
62919
  if (isPeerDashboard) {
62739
62920
  startSharedIssueService({ skipPolling: true });
@@ -62771,7 +62952,7 @@ if (shouldStartStaleCheckRetriggerService()) {
62771
62952
  }
62772
62953
  if (process.env.OVERDECK_MODE === "desktop") (async () => {
62773
62954
  try {
62774
- const { provisionClaudeHooks } = await import("./claude-hooks-provision-BhwWK-TQ.js");
62955
+ const { provisionClaudeHooks } = await import("./claude-hooks-provision-C8wdRnN1.js");
62775
62956
  const result = await provisionClaudeHooks();
62776
62957
  if (!result.ok) console.warn(`[overdeck] Claude hook provisioning skipped: ${result.reason}`);
62777
62958
  else if (result.changed) console.log(`[overdeck] Claude hooks provisioned: ${result.binariesSynced} scripts, registered ${result.registered.length} hook(s)${result.pruned.length ? `, pruned ${result.pruned.length} stale` : ""}`);
@@ -62998,7 +63179,8 @@ setMergeReadyNotifier((issueId) => {
62998
63179
  console.log("[overdeck] Merge-ready notifier → domain events wired");
62999
63180
  startConversationLifecycleService();
63000
63181
  console.log("[overdeck] ConversationLifecycleService started");
63001
- startSubstrateBugPoller();
63182
+ if (isPeerDashboard) console.log("[overdeck] SubstrateBugPoller skipped — peer dashboard does not poll trackers");
63183
+ else startSubstrateBugPoller();
63002
63184
  if (startUatTrainReconciler()) console.log("[overdeck] UAT batch-train reconciler started");
63003
63185
  else console.log("[overdeck] UAT batch-train reconciler skipped — non-primary dashboard process");
63004
63186
  const attachmentCleanupTimer = setInterval(() => {
@@ -63017,8 +63199,31 @@ startCostReconcileService();
63017
63199
  console.log("[overdeck] Cost reconciler started");
63018
63200
  const conversationSearchWatcher = startConversationSearchWatcher();
63019
63201
  console.log(conversationSearchWatcher ? "[overdeck] Conversation search watcher started" : "[overdeck] Conversation search watcher skipped (conversationSearch.enabled=false)");
63202
+ let stopResourceRefreshServices = () => void 0;
63020
63203
  (async () => {
63021
- (await initEventStore()).subscribe((event) => {
63204
+ const store = await initEventStore();
63205
+ whenDashboardListening().then(async () => {
63206
+ await new Promise((resolve) => setTimeout(resolve, 0));
63207
+ const stopTriggers = startResourceRefreshTriggers();
63208
+ const stopConvergence = startProjectResourceConvergence();
63209
+ const stopResourcesSnapshot = startResourcesSnapshotService();
63210
+ stopResourceRefreshServices = () => {
63211
+ stopTriggers();
63212
+ stopConvergence();
63213
+ stopResourcesSnapshot();
63214
+ stopProjectResourceRefreshQueue();
63215
+ };
63216
+ console.log("[overdeck] Project resource refresh queue and resources snapshot service started");
63217
+ const warmStart = Date.now();
63218
+ enqueueProjectsResourceRefresh(listProjectsSync().map((entry) => entry.config), "boot-warm");
63219
+ await whenProjectResourceRefreshIdle();
63220
+ const queueState = getProjectResourceRefreshQueueState();
63221
+ if (queueState.lastError) console.warn("[overdeck] Boot cache warm completed with errors:", queueState.lastError);
63222
+ else console.log(`[overdeck] Boot cache warm complete in ${Math.round((Date.now() - warmStart) / 1e3)}s`);
63223
+ }).catch((err) => {
63224
+ console.warn("[overdeck] Resource refresh startup failed:", err instanceof Error ? err.message : String(err));
63225
+ });
63226
+ store.subscribe((event) => {
63022
63227
  if (event.type === "agent.stopped" || event.type === "agent.heartbeat_dead") {
63023
63228
  const agentId = typeof event.payload.agentId === "string" ? event.payload.agentId : null;
63024
63229
  if (agentId) reconcileAgentMemory(agentId).catch((err) => console.warn("[memory-reconciliation] agent sweep failed:", err?.message ?? err));
@@ -63074,6 +63279,7 @@ const handleShutdownSignal = async (signal) => {
63074
63279
  if (forkGrace.count > 0) if (forkGrace.completed) console.log(`[overdeck] Waited for ${forkGrace.count} in-flight fork pipeline(s) before shutdown`);
63075
63280
  else console.warn(`[overdeck] ${forkGrace.count} in-flight fork pipeline(s) still running after shutdown grace window`);
63076
63281
  clearInterval(attachmentCleanupTimer);
63282
+ stopResourceRefreshServices();
63077
63283
  stopAgentEnrichmentService();
63078
63284
  stopAgentOutputService();
63079
63285
  stopConversationLifecycleService();
@@ -63089,7 +63295,7 @@ const handleShutdownSignal = async (signal) => {
63089
63295
  stopRestartAnnouncer();
63090
63296
  await stopDeaconChild().catch((err) => console.warn("[deacon-supervisor] child shutdown failed:", err?.message ?? err));
63091
63297
  try {
63092
- const { killAllGateProcessGroups } = await import("./validation-DcAgXTQp.js");
63298
+ const { killAllGateProcessGroups } = await import("./validation-CIi6pnI2.js");
63093
63299
  const reaped = killAllGateProcessGroups();
63094
63300
  if (reaped > 0) console.log(`[overdeck] reaped ${reaped} in-flight gate process group(s)`);
63095
63301
  } catch (err) {
@@ -63144,7 +63350,7 @@ reconcileStaleGitHubBlockers().then((n) => {
63144
63350
  }
63145
63351
  }).catch((err) => console.warn(`[overdeck] Startup blocker reconciliation failed: ${err.message}`));
63146
63352
  try {
63147
- const { resetProcessingToQueued } = await import("./merge-sync-B95_4in_.js");
63353
+ const { resetProcessingToQueued } = await import("./merge-sync-SSv3E-pl.js");
63148
63354
  const resetCount = resetProcessingToQueued();
63149
63355
  if (resetCount > 0) {
63150
63356
  console.log(`[overdeck] Reset ${resetCount} stuck merge queue entries to queued`);
@@ -63166,7 +63372,7 @@ else {
63166
63372
  console.log("[overdeck] Auto-merge executor started");
63167
63373
  }
63168
63374
  try {
63169
- const { reconcileInterruptedVerifications } = await import("./verification-runner-DlJezzef.js");
63375
+ const { reconcileInterruptedVerifications } = await import("./verification-runner-CDj4lD4t.js");
63170
63376
  const interrupted = reconcileInterruptedVerifications();
63171
63377
  if (interrupted > 0) console.log(`[overdeck] recovered ${interrupted} orphaned verification worker(s)`);
63172
63378
  } catch (err) {
@@ -63205,7 +63411,9 @@ if (process.env.OVERDECK_DISABLE_DEACON === "1") {
63205
63411
  message: summary
63206
63412
  });
63207
63413
  }
63208
- if (startBootReconciliation({ onGraceExpired: applyBootReconciliationDecision }).decision !== "pending") applyBootReconciliationDecision();
63414
+ if (startBootReconciliation({ onGraceExpired: async () => {
63415
+ await applyBootReconciliationDecision();
63416
+ } }).decision !== "pending") applyBootReconciliationDecision();
63209
63417
  startDeaconChild().catch((err) => {
63210
63418
  console.error("[overdeck] Cloister auto-start failed:", err);
63211
63419
  emitActivityEntrySync({
@@ -63255,25 +63463,6 @@ async function pruneClosedIssueReviewStatuses() {
63255
63463
  } catch {}
63256
63464
  if (removed > 0) console.log(`[overdeck] Pruned ${removed} stale review-status entr${removed === 1 ? "y" : "ies"} for closed issues`);
63257
63465
  }
63258
- await (async () => {
63259
- try {
63260
- const overdeckDbPath = getOverdeckDatabasePath();
63261
- if (!existsSync$1(overdeckDbPath)) {
63262
- createOverdeckDatabase({ dbPath: overdeckDbPath });
63263
- console.log(`[overdeck] Created overdeck.db at ${overdeckDbPath}`);
63264
- }
63265
- } catch (err) {
63266
- console.warn("[overdeck] Overdeck db init failed (non-fatal):", err);
63267
- }
63268
- })();
63269
- const main = runServer.pipe(Effect.provide(ServerConfigLayer));
63270
- if (typeof Bun !== "undefined") {
63271
- const { runMain } = await import("@effect/platform-bun/BunRuntime");
63272
- runMain(main);
63273
- } else {
63274
- const { runMain } = await import("@effect/platform-node/NodeRuntime");
63275
- runMain(main);
63276
- }
63277
63466
  //#endregion
63278
63467
  export {};
63279
63468