@overdeck/desktop 0.45.22 → 0.45.24

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 (429) hide show
  1. package/drizzle/overdeck/0000_overdeck_init.sql +2 -0
  2. package/package.json +1 -1
  3. package/server/{acceptance-criteria-BH7ac_1G.js → acceptance-criteria-DDCnXF58.js} +5 -5
  4. package/server/{advancing-selfheal-cSvXNZLZ.js → advancing-selfheal-BVwW4qRn.js} +6 -6
  5. package/server/{agent-gc-Dj2gncak.js → agent-gc-CHcnvonI.js} +4 -4
  6. package/server/agent-state-Bc3tzUC8.js +3 -0
  7. package/server/{agent-state-service-DistflNn.js → agent-state-service-BsgWxZuB.js} +5 -5
  8. package/server/{agent-state-service-CsQ07Pxe.js → agent-state-service-D5UGKIJL.js} +1 -1
  9. package/server/{agents-DXdHmRTC.js → agents-EbI0zCJl.js} +4 -4
  10. package/server/agents-wi9NWzs2.js +3 -0
  11. package/server/{archive-planning-Cp_DC1j-.js → archive-planning-BZDgzoEj.js} +1 -1
  12. package/server/{archive-planning-BvDuWNMo.js → archive-planning-Du25Jtst.js} +30 -6
  13. package/server/{artifact-index-jobs-CDBFL4OU.js → artifact-index-jobs-CbEDfCDu.js} +2 -2
  14. package/server/assemble-J2ZZ2C15.js +339 -0
  15. package/server/{backlog-auto-trigger-DmA1IbYf.js → backlog-auto-trigger-2R2jog7n.js} +3 -3
  16. package/server/{behavior-CGj16clS.js → behavior-B3exJ42O.js} +2 -2
  17. package/server/{briefing-freshness-C12WgkaB.js → briefing-freshness-D1wzUIWv.js} +2 -2
  18. package/server/{build-info-BRpqQvNd.js → build-info-CZk_TITh.js} +1 -1
  19. package/server/{build-info-NU3KbXYw.js → build-info-Ie_D0_BT.js} +3 -3
  20. package/server/{checkpoint-manager-CTPjAmtH.js → checkpoint-manager-BI1Wxoku.js} +2 -2
  21. package/server/{checkpoint-manager-rOgT98WY.js → checkpoint-manager-DwbQoqrC.js} +1 -1
  22. package/server/checkpoint-worker.js +1 -1
  23. package/server/{checkpoints-B5jFNi2G.js → checkpoints-BJIs5QIA.js} +1 -1
  24. package/server/{checkpoints-BJum14fs.js → checkpoints-CQB1h765.js} +2 -2
  25. package/server/{claude-hooks-provision-BhwWK-TQ.js → claude-hooks-provision-8Ngo8TpT.js} +1 -1
  26. package/server/{claude-hooks-provision-D7p5WcKZ.js → claude-hooks-provision-D8GXF3_s.js} +2 -2
  27. package/server/{claude-permissions-nSFKH78M.js → claude-permissions-DNWEVV6z.js} +2 -2
  28. package/server/{claude-settings-overlay-BI_UIke0.js → claude-settings-overlay-CEdaqpWI.js} +2 -2
  29. package/server/{claude-settings-overlay-DHBwjS1X.js → claude-settings-overlay-DWy-Bb4Y.js} +1 -1
  30. package/server/cli-B86rejVV.js +3 -0
  31. package/server/{cli-CbKNkFE5.js → cli-RoOx5DUf.js} +9 -9
  32. package/server/{cliproxy-Brf_5MuG.js → cliproxy-C8a1vtTU.js} +2 -2
  33. package/server/{cliproxy-bONZDBbC.js → cliproxy-fHfIeiGd.js} +1 -1
  34. package/server/{close-issue-CxReRxIc.js → close-issue-DoOifFIK.js} +5 -5
  35. package/server/{closed-issue-reaper-CQ3kqha7.js → closed-issue-reaper-Bk3SU4RC.js} +9 -9
  36. package/server/{closed-issue-reaper-DXP2Xyv3.js → closed-issue-reaper-CktPXo8m.js} +1 -1
  37. package/server/{codex-CbmztVcc.js → codex-BZXGhUVB.js} +27 -8
  38. package/server/codex-GcHuUF-k.js +3 -0
  39. package/server/{codex-parser-jl8AeAmB.js → codex-parser-CFZ1_1Jl.js} +2 -2
  40. package/server/{config-q4Gvd8dq.js → config-BZ0sHTju.js} +2 -2
  41. package/server/{config-DeTsoZdR.js → config-CKxYiCmX.js} +2 -2
  42. package/server/{config-BJKocXKd.js → config-DzV30TOm.js} +1 -1
  43. package/server/{config-yaml-ig8Nwtiw.js → config-yaml-DySPNmKN.js} +77 -194
  44. package/server/{conflict-gate-CFqPVxEg.js → conflict-gate-BaCVrH-N.js} +3 -3
  45. package/server/{conflict-gate-CHU9K1vU.js → conflict-gate-BhAY7TUd.js} +1 -1
  46. package/server/context-layers-BrPmE__h.js +4 -0
  47. package/server/context-layers-igZ4FI4_.js +37 -0
  48. package/server/{control-settings-D_odMIaC.js → control-settings-BQp7_4uD.js} +4 -4
  49. package/server/{conversation-compaction-B6YSRLda.js → conversation-compaction-CgrR8YYp.js} +8 -8
  50. package/server/{conversation-compaction-CN4-5YYt.js → conversation-compaction-eQB5CkOe.js} +1 -1
  51. package/server/{conversation-service-Dq33SYEj.js → conversation-service-BLd3MYsG.js} +1 -1
  52. package/server/{conversation-service-C3avRVEr.js → conversation-service-DPJ71F33.js} +329 -19
  53. package/server/{conversations-bYpM9-kZ.js → conversations-6AfUfbwc.js} +5 -5
  54. package/server/{conversations-H9if0bCQ.js → conversations-CAsJF9kh.js} +1 -1
  55. package/server/{cost-Codk1pc2.js → cost-B2ddP6wq.js} +18 -2
  56. package/server/{cost-wH46-WsJ.js → cost-R-m6Yi-W.js} +3 -3
  57. package/server/{cost-sync-D_cre6WM.js → cost-sync-BsN6ER0n.js} +3 -3
  58. package/server/{dag-CJpgf9A3.js → dag-B1ucnjDU.js} +9 -9
  59. package/server/{dangerous-git-ops-D6AF-Hg_.js → dangerous-git-ops-BXqeWVSf.js} +1 -1
  60. package/server/dashboard-db-worker.js +7 -7
  61. package/server/{deacon-CkT_kznS.js → deacon-CU_cAYSR.js} +406 -607
  62. package/server/{deacon-B8HbQdqU.js → deacon-kiQrb4ZT.js} +3 -3
  63. package/server/{deacon-nudge-log-D6K9K-rE.js → deacon-nudge-log-6wVqAaqz.js} +3 -3
  64. package/server/{deacon-swarm-BryRr6AO.js → deacon-swarm-BXZZ1Z2-.js} +17 -17
  65. package/server/deacon-swarm-C-GwfjJy.js +2 -0
  66. package/server/deacon.js +8 -8
  67. package/server/{deploy-patrol-1IrZxicY.js → deploy-patrol-AiFoP8dw.js} +136 -19
  68. package/server/{deploy-window-wDf4UgHt.js → deploy-window-C3F-tihF.js} +77 -10
  69. package/server/{deploy-window-7ZYHh7Zp.js → deploy-window-DkZraDyj.js} +1 -1
  70. package/server/{dev-supervisor-C7p9kEpc.js → dev-supervisor-bcOWqdQE.js} +2 -2
  71. package/server/{devcontainer-renderer-CNmQy0pL.js → devcontainer-renderer-_d6XhyND.js} +3 -3
  72. package/server/dist-Bzy0y69j.js +3 -0
  73. package/server/{dist-D-Ed5yVw.js → dist-Cb_0uvpS.js} +1 -1
  74. package/server/{docker-BCZ89M9X.js → docker-DcMTFTUC.js} +2 -2
  75. package/server/{dod-DbJLYcHv.js → dod-C6n9RV3G.js} +1 -1
  76. package/server/{ensure-devcontainer-Cs6W9Yzj.js → ensure-devcontainer-BZgOhRo7.js} +1 -1
  77. package/server/{ensure-devcontainer-V5JWaAva.js → ensure-devcontainer-DNi-ono3.js} +4 -4
  78. package/server/{esm-shims-dTeNdq7X.js → esm-shims-OSHAYaS1.js} +1 -1
  79. package/server/{event-store-TnWdydfB.js → event-store-CQL6NeqB.js} +3 -3
  80. package/server/{event-store-CpBGsO6_.js → event-store-EV2cMiXj.js} +1 -1
  81. package/server/{events-Dsuv6qyB.js → events-BTdrdEq8.js} +1 -1
  82. package/server/{events-DSUdR-04.js → events-DTfAe4My.js} +3 -3
  83. package/server/{factory-BMrK4TrE.js → factory-CFibJuaw.js} +50 -13
  84. package/server/{feature-registry-population-B-CI9hgE.js → feature-registry-population-DKZFMbFt.js} +4 -4
  85. package/server/{feature-registry-storage-B972ph_A.js → feature-registry-storage-BdPuLcBX.js} +2 -2
  86. package/server/{features-Bc-Bmiye.js → features-ez2271oH.js} +2 -2
  87. package/server/{feedback-target-DZ-iAnAa.js → feedback-target-7mqqwrX6.js} +7 -7
  88. package/server/{feedback-target-DS6NUuSs.js → feedback-target-CoFDHiM8.js} +1 -1
  89. package/server/{feedback-writer-BXP6g75N.js → feedback-writer-CY5L1lB7.js} +6 -5
  90. package/server/{feedback-writer-Bx5z11mF.js → feedback-writer-D3a22RCd.js} +1 -1
  91. package/server/flywheel-DHrgCphM.js +1084 -0
  92. package/server/flywheel-DzGtWnJ1.js +477 -0
  93. package/server/flywheel-SVF02Jpq.js +2 -0
  94. package/server/{flywheel-merge-order-CTgHeg-W.js → flywheel-merge-order-UU0tiUld.js} +10 -9
  95. package/server/{flywheel-merge-order-CNKAY489.js → flywheel-merge-order-UUcsCDb6.js} +1 -1
  96. package/server/{forge-B1S_KZv4.js → forge-CNFnyqps.js} +2 -2
  97. package/server/forge-DXnS_YFH.js +2 -0
  98. package/server/{from-DpwQ-sc3.js → from-kNxT0bZC.js} +1 -1
  99. package/server/{fts-db-DmAcuCkV.js → fts-db-CE46vDkZ.js} +2 -2
  100. package/server/{fts-operations-7d_RkmWp.js → fts-operations-CqY6zl-i.js} +2 -2
  101. package/server/{git-utils-Cc3FHDKd.js → git-utils-CRw2zLPC.js} +68 -3
  102. package/server/git-utils-D0_yhCgF.js +3 -0
  103. package/server/{github-app-CDPtGF7J.js → github-app-C3QrAUd0.js} +27 -8
  104. package/server/{github-app-CU14oYzP.js → github-app-ClZ2lk8D.js} +1 -1
  105. package/server/{github-client-XjTJbBm7.js → github-client-BnIsSrEN.js} +2 -2
  106. package/server/{github-client-CwBZZ3t7.js → github-client-DfQYVUaw.js} +1 -1
  107. package/server/{github-pr-lookup-CFGeVhqv.js → github-pr-lookup-D16NGsSO.js} +2 -2
  108. package/server/{harness-binary-B2CTcD84.js → harness-binary-DPUi-Pv8.js} +32 -6
  109. package/server/{harness-resolve-D5FVQTmy.js → harness-resolve-3lNZkyT4.js} +18 -9
  110. package/server/{health-events-DREeevle.js → health-events-BBcTYQKU.js} +2 -2
  111. package/server/{health-events-C1whmd58.js → health-events-BDOHby5Q.js} +1 -1
  112. package/server/{hooks-yxRsjk-z.js → hooks-CKZgXlJb.js} +2 -2
  113. package/server/{hooks-B-HItBiS.js → hooks-DPVX1rwQ.js} +1 -1
  114. package/server/{hume-Dz_OymXE.js → hume-Cz8igP9E.js} +2 -2
  115. package/server/hume-ccTf4wTX.js +3 -0
  116. package/server/{idle-stack-reaper-DrCv0OAG.js → idle-stack-reaper-CuLF0j2H.js} +1 -1
  117. package/server/{idle-stack-reaper-Yf34xXxY.js → idle-stack-reaper-DDIRwxUY.js} +2 -2
  118. package/server/{in-flight-guard-BoWm66Kh.js → in-flight-guard-CAAkqPLu.js} +2 -2
  119. package/server/{infra-D4iNWMA5.js → infra-BEqFxlJc.js} +14 -4
  120. package/server/{injection-D7T75Pye.js → injection-C8aiVJrF.js} +191 -183
  121. package/server/{injection-BVNa4MQW.js → injection-CPUIqNhI.js} +1 -1
  122. package/server/{inspect-agent-BXCgNeZ4.js → inspect-agent-BLuJ1AkT.js} +137 -81
  123. package/server/inspect-agent-Brtz0URj.js +2 -0
  124. package/server/{internal-token-C9DdEOKY.js → internal-token-BrcU6qfe.js} +1 -1
  125. package/server/{internal-token-CXsfxslp.js → internal-token-s0-oKybJ.js} +2 -2
  126. package/server/{io-DQR9PMgS.js → io-C9kF1wtJ.js} +160 -184
  127. package/server/{issue-closed-DtmJM0D0.js → issue-closed-CDJk4pIp.js} +7 -7
  128. package/server/{issue-lifecycle-8PSS9Anq.js → issue-lifecycle-B8sZHVHh.js} +1 -1
  129. package/server/{issue-lifecycle-CeyW_HoD.js → issue-lifecycle-ojZAzDBP.js} +22 -22
  130. package/server/{issue-service-singleton-DBZabEl7.js → issue-service-singleton-BvJ09SaR.js} +1 -1
  131. package/server/{issue-service-singleton-D_RVYBuL.js → issue-service-singleton-Yx5DdmVJ.js} +8 -8
  132. package/server/{issues-pDW9VUNz.js → issues-BMmP_77e.js} +2 -2
  133. package/server/{jsonl-parser-C3HVNR5d.js → jsonl-parser-BXSlHwEh.js} +3 -3
  134. package/server/{label-cleanup-DPwiZlWo.js → label-cleanup-B0UJwnv5.js} +3 -3
  135. package/server/{label-reconciler-Df1ZduPH.js → label-reconciler-B4iOAjlC.js} +4 -4
  136. package/server/{launcher-generator-COgR2By1.js → launcher-generator-BBWG_SiS.js} +105 -10
  137. package/server/{lifecycle-io-taIb0PoH.js → lifecycle-io-BREGpnLk.js} +37 -37
  138. package/server/lifecycle-io-DPo7x11I.js +3 -0
  139. package/server/{lifecycle-CtPDcZ9u.js → lifecycle-xmBfK2GJ.js} +6 -6
  140. package/server/lifecycle-yPd___5E.js +121 -0
  141. package/server/{linear-client-DsFkIxee.js → linear-client-BsuUvkdA.js} +2 -2
  142. package/server/{linear-client-YwZMDIwQ.js → linear-client-CTskEeT_.js} +1 -1
  143. package/server/memory-fts-worker.js +1 -1
  144. package/server/{merge-BwsyNRJV.js → merge-B1DiziGU.js} +1 -1
  145. package/server/{merge-C1t-bspg.js → merge-CefQNAnq.js} +3 -3
  146. package/server/{merge-agent-DDiIjzk-.js → merge-agent-4WOWlSYA.js} +28 -28
  147. package/server/{merge-agent-B-SnXOoc.js → merge-agent-CKkgIBPB.js} +1 -1
  148. package/server/{merge-batch-Byt-QnEl.js → merge-batch-ClFn2T-y.js} +1 -1
  149. package/server/merge-ops-CR44oU9-.js +2 -0
  150. package/server/{merge-rebase-Cm6fXaZN.js → merge-rebase-BfaTyXsw.js} +2 -2
  151. package/server/merge-set-DJ8-UErs.js +83 -0
  152. package/server/{merge-set-6LEglm6o.js → merge-set-bUqbm3yc.js} +1 -1
  153. package/server/{merge-sync-B95_4in_.js → merge-sync-BJYeOODr.js} +1 -1
  154. package/server/{merge-sync-Do8_q32h.js → merge-sync-VPV28g0g.js} +2 -2
  155. package/server/{merge-train-CKana8EH.js → merge-train-CHopycP0.js} +3 -3
  156. package/server/{merge-train-deps-BgmqwIfA.js → merge-train-deps-D1cOZzy2.js} +4 -4
  157. package/server/{merge-verification-CqnUzGEK.js → merge-verification-BkaOqPsw.js} +4 -4
  158. package/server/{multipart-parser-tdOQDJ3o.js → multipart-parser-duPAfSBw.js} +2 -2
  159. package/server/{no-resume-mode-BWOSZjWd.js → no-resume-mode-Nw29vaFb.js} +11 -8
  160. package/server/node_modules/.package-lock.json +8 -8
  161. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/package.json +3 -3
  162. package/server/node_modules/undici/README.md +5 -0
  163. package/server/node_modules/undici/docs/docs/api/Client.md +4 -0
  164. package/server/node_modules/undici/docs/docs/api/Dispatcher.md +6 -0
  165. package/server/node_modules/undici/docs/docs/api/Interceptors.md +59 -0
  166. package/server/node_modules/undici/docs/docs/api/MockAgent.md +27 -0
  167. package/server/node_modules/undici/docs/docs/api/MockPool.md +28 -1
  168. package/server/node_modules/undici/docs/docs/index.md +5 -0
  169. package/server/node_modules/undici/lib/core/request.js +1 -1
  170. package/server/node_modules/undici/lib/core/util.js +6 -1
  171. package/server/node_modules/undici/lib/dispatcher/agent.js +3 -3
  172. package/server/node_modules/undici/lib/dispatcher/client-h1.js +31 -6
  173. package/server/node_modules/undici/lib/dispatcher/client-h2.js +34 -43
  174. package/server/node_modules/undici/lib/handler/cache-handler.js +93 -5
  175. package/server/node_modules/undici/lib/handler/cache-revalidation-handler.js +10 -0
  176. package/server/node_modules/undici/lib/handler/redirect-handler.js +5 -2
  177. package/server/node_modules/undici/lib/handler/retry-handler.js +6 -4
  178. package/server/node_modules/undici/lib/interceptor/cache.js +21 -4
  179. package/server/node_modules/undici/lib/interceptor/decompress.js +4 -0
  180. package/server/node_modules/undici/lib/mock/mock-interceptor.js +25 -7
  181. package/server/node_modules/undici/lib/mock/mock-utils.js +39 -10
  182. package/server/node_modules/undici/lib/util/cache.js +49 -7
  183. package/server/node_modules/undici/lib/web/fetch/body.js +2 -1
  184. package/server/node_modules/undici/lib/web/fetch/response.js +1 -3
  185. package/server/node_modules/undici/package.json +2 -2
  186. package/server/node_modules/undici/types/client.d.ts +2 -2
  187. package/server/node_modules/undici/types/dispatcher.d.ts +3 -3
  188. package/server/node_modules/undici/types/mock-interceptor.d.ts +5 -1
  189. package/server/{orphan-proposed-reconciler-xklgvNA7.js → orphan-proposed-reconciler-BvKkWMJQ.js} +15 -13
  190. package/server/{orphan-proposed-reconciler-DSvsJ5M7.js → orphan-proposed-reconciler-CTSGcK8p.js} +1 -1
  191. package/server/package-lock.json +9 -9
  192. package/server/package.json +1 -1
  193. package/server/{pan-dir-DOcf6ug3.js → pan-dir-B0c3w0Ya.js} +78 -58
  194. package/server/{paths-DooHpt9p.js → paths-D-xWGHdh.js} +2 -2
  195. package/server/{pickup-CaskQ7j6.js → pickup-DUCLWrJY.js} +17 -16
  196. package/server/{pipeline-membership-1LGRjo-k.js → pipeline-membership-mY3GprlK.js} +186 -67
  197. package/server/{pipeline-notifier-CZsrU_nj.js → pipeline-notifier-BJr8gQX6.js} +1 -1
  198. package/server/{pipeline-notifier-B6FVsYF9.js → pipeline-notifier-BXkJzDC4.js} +2 -2
  199. package/server/{project-pipelines-CtNG_rvs.js → project-pipelines-C0MWUeCU.js} +2 -2
  200. package/server/project-repos-B6GycDh9.js +94 -0
  201. package/server/project-repos-DXKQsc_m.js +3 -0
  202. package/server/projects-vjjcmiN8.js +3 -0
  203. package/server/{prompts-EvhMeeHG.js → prompts-DxzFXuLl.js} +2 -2
  204. package/server/{providers-BDDPULlp.js → providers-qQAwGQDW.js} +7 -7
  205. package/server/{providers-DNSQqy2V.js → providers-u4Ga0jOr.js} +1 -1
  206. package/server/public/assets/{chunk-BO2N2NFS-sym_ufXe.js → chunk-BO2N2NFS-BamJdinX.js} +4 -4
  207. package/server/public/assets/{diagram-OG6HWLK6-CQJPBNBu.js → diagram-OG6HWLK6-DfOB8-w4.js} +1 -1
  208. package/server/public/assets/{dist-DukGS2YZ.js → dist-ByIuzMQW.js} +3 -3
  209. package/server/public/assets/{dist-Bio7THQU.js → dist-D7zYSEA6.js} +1 -1
  210. package/server/public/assets/{ganttDiagram-6RSMTGT7-D4lWwte3.js → ganttDiagram-6RSMTGT7-EdmRyXL3.js} +1 -1
  211. package/server/public/assets/{highlighted-body-OFNGDK62-CaLboCt5.js → highlighted-body-OFNGDK62-MerOfTX8.js} +1 -1
  212. package/server/public/assets/{index-Bwejq-5s.js → index-CWeMerGO.js} +147 -144
  213. package/server/public/assets/index-CenuJ3Cw.css +1 -0
  214. package/server/public/assets/{linear-qUWmMZ-c.js → linear-BBbArIcK.js} +1 -1
  215. package/server/public/assets/mermaid-GHXKKRXX-CpPWAFwE.js +1 -0
  216. package/server/public/assets/{pieDiagram-4H26LBE5-C4zYulEm.js → pieDiagram-4H26LBE5-BKIddiJN.js} +1 -1
  217. package/server/public/assets/{prod-C8VtLuWC.js → prod-B8vYiu52.js} +4 -4
  218. package/server/public/assets/{quadrantDiagram-W4KKPZXB-qP04zyZC.js → quadrantDiagram-W4KKPZXB-D6RtoULk.js} +1 -1
  219. package/server/public/assets/{sankeyDiagram-5OEKKPKP-eMPTX_cG.js → sankeyDiagram-5OEKKPKP-CLrCedZX.js} +1 -1
  220. package/server/public/assets/{xychartDiagram-2RQKCTM6-Dme1PIt6.js → xychartDiagram-2RQKCTM6-hznR8DYl.js} +1 -1
  221. package/server/public/index.html +2 -2
  222. package/server/{pull-requests-By_BteaL.js → pull-requests-7N8WKseP.js} +1 -1
  223. package/server/{pull-requests-8z2N1UOV.js → pull-requests-_lHueOHW.js} +13 -11
  224. package/server/{queries-ZABd5aXP.js → queries-CjNIf-Ub.js} +1200 -201
  225. package/server/{rally-i_goYmiA.js → rally-CyWT_lNO.js} +3 -3
  226. package/server/{rally-api-DqKqIMNR.js → rally-api-C8e_1JRi.js} +2 -2
  227. package/server/{rally-api-xHazRk0d.js → rally-api-ClOSd-Tt.js} +1 -1
  228. package/server/{rally-client-COYz1vYR.js → rally-client-lc-nokqr.js} +4 -4
  229. package/server/{rally-client-CGWEHaPd.js → rally-client-sgtVqzNU.js} +1 -1
  230. package/server/rally-zhhtXuDP.js +3 -0
  231. package/server/{reap-terminal-sessions-CaMkFOIH.js → reap-terminal-sessions-7KeHv1R1.js} +1 -1
  232. package/server/{reap-terminal-sessions-DG9eiMVz.js → reap-terminal-sessions-BtHPo6Xc.js} +1 -1
  233. package/server/rebuild-stack-CFvcBHsS.js +4 -0
  234. package/server/{rebuild-stack-JUm0jqYP.js → rebuild-stack-lwtsW0GO.js} +26 -35
  235. package/server/{reconstruct-cache-wU79aCee.js → reconstruct-cache-C3Ui7ojV.js} +6 -6
  236. package/server/record-CN0pj4_5.js +3 -0
  237. package/server/{record-update-D3N6WMFR.js → record-update-bLJxAXH4.js} +1 -1
  238. package/server/record-update-dE1Aw83j.js +310 -0
  239. package/server/{recovery-trip-DkzJSej9.js → recovery-trip-BvRWfUXM.js} +2 -2
  240. package/server/{release-engine-DMINVN8S.js → release-engine-Cx48W7z8.js} +5 -5
  241. package/server/{release-set-DeUSOEHy.js → release-set-CQfuN9-v.js} +3 -3
  242. package/server/{remote-b-c5bOce.js → remote-C_2hasl7.js} +3 -3
  243. package/server/{remote-Dr5kGYSZ.js → remote-ChgimyYa.js} +3 -3
  244. package/server/{remote-agents-Ct_WOyke.js → remote-agents-By1ige5O.js} +6 -6
  245. package/server/{remote-agents-D6O_zETW.js → remote-agents-CA3Ihlxj.js} +1 -1
  246. package/server/{remote-completion-Dca3hAaa.js → remote-completion-fVe9e_3u.js} +12 -12
  247. package/server/resume-BFv1PGpA.js +3 -0
  248. package/server/{review-agent-CThvgK2r.js → review-agent-CIGOQYBD.js} +29 -25
  249. package/server/{review-agent-CCum8sGe.js → review-agent-DNboMyW4.js} +1 -1
  250. package/server/{review-artifacts-CXywD0F2.js → review-artifacts-nRDPuMxd.js} +5 -5
  251. package/server/{review-context-OYfKUprb.js → review-context-2uj-YQ8J.js} +70 -26
  252. package/server/review-status-btEYlaxA.js +3 -0
  253. package/server/{review-status-enrichment-crNAtIpL.js → review-status-enrichment-Dci-ZwEt.js} +3 -3
  254. package/server/{review-status-DFRjDFef.js → review-status-kZj_KyCk.js} +77 -28
  255. package/server/{review-status-sync-DpAMD_WO.js → review-status-sync-BTOpxtTC.js} +10 -5
  256. package/server/{review-status-sync-D60PJWNL.js → review-status-sync-DSDK3OMy.js} +1 -1
  257. package/server/{review-verdict-feedback-CpUZl5aE.js → review-verdict-feedback-CCjVA7Uk.js} +6 -6
  258. package/server/{review-verdict-feedback-JImjut0z.js → review-verdict-feedback-CTd4QMBu.js} +1 -1
  259. package/server/{rollup-CZ02qgxk.js → rollup-BKQC7jp4.js} +1 -1
  260. package/server/{rollup-SyuF09e4.js → rollup-FGsKki9R.js} +8 -8
  261. package/server/{scanner-Br0Z5S6R.js → scanner-CnqEZeDy.js} +45 -14
  262. package/server/{sequence-io-fxU0DlwW.js → sequence-io-D909zgeH.js} +4 -4
  263. package/server/{sequencer-agent-B5YC5XVP.js → sequencer-agent-CzkcK6P5.js} +5 -5
  264. package/server/server.js +2961 -919
  265. package/server/{service-Bagb90KZ.js → service-CLeAoU6G.js} +55 -54
  266. package/server/{session-fork-BqQxd-V6.js → session-fork-CHI1XvL9.js} +2 -2
  267. package/server/{session-history-XdS0JKp3.js → session-history-BT3IvqhC.js} +4 -4
  268. package/server/settings-66A6uvIA.js +2 -0
  269. package/server/{settings-BNbocWOg.js → settings-BTMvpNFU.js} +3 -3
  270. package/server/{settings-uLc6DEYI.js → settings-C0zgxOGf.js} +2 -2
  271. package/server/{shadow-engineering-D4X_s3fA.js → shadow-engineering-BJfgm-hX.js} +2 -2
  272. package/server/{shadow-state-C_NkP-sa.js → shadow-state-7a-524T8.js} +2 -2
  273. package/server/{shadow-state-CbvsN3qG.js → shadow-state-DnDyjujH.js} +1 -1
  274. package/server/{shadow-utils-CYMRPeRT.js → shadow-utils-Db3oroFG.js} +2 -2
  275. package/server/{ship-log-__QtAFXG.js → ship-log-D9MlVzYU.js} +1 -1
  276. package/server/{smart-compaction-jdMkG1vo.js → smart-compaction-CV2ukKND.js} +1 -1
  277. package/server/{smart-compaction-CLZOWin1.js → smart-compaction-KCYScAU1.js} +7 -7
  278. package/server/{spawn-planning-session-D5OXo8pT.js → spawn-planning-session-DKpdFyOC.js} +35 -27
  279. package/server/{spawn-planning-session-8D6mE033.js → spawn-planning-session-qUC2VWu3.js} +1 -1
  280. package/server/{specialist-completion-CqmduO92.js → specialist-completion-Ky9wCDpb.js} +1 -1
  281. package/server/{specialist-context-CJ-QjFR-.js → specialist-context-Bn3dCGS2.js} +5 -5
  282. package/server/{specialist-handoff-logger-Dnjlwt7g.js → specialist-handoff-logger-CMEwYxa2.js} +2 -2
  283. package/server/{specialist-logs-CQnKzuZs.js → specialist-logs-C5p8G7tx.js} +3 -3
  284. package/server/{specialists-Bg9v4z3F.js → specialists-CC4r-c2s.js} +1015 -460
  285. package/server/{specialists-D0gGXMZx.js → specialists-CShuVGWT.js} +1 -1
  286. package/server/specialists-DM6bWjsi.js +3 -0
  287. package/server/{specialists-CwZHb5cb.js → specialists-jiuuyVkp.js} +66 -74
  288. package/server/specs-C8Wsn2XO.js +3 -0
  289. package/server/{src-BMMoA_ba.js → src-CXmtj0im.js} +6 -6
  290. package/server/{src-Bqdtd6po.js → src-CdmnTM2m.js} +5 -5
  291. package/server/{src-k039WVYY.js → src-DtcUOZCq.js} +112 -18
  292. package/server/stack-health-Bn3o8FBX.js +3 -0
  293. package/server/{stack-health-C-ifC7b0.js → stack-health-DxSdG9cW.js} +63 -9
  294. package/server/{stale-task-claims-L7pJkQFL.js → stale-task-claims-KJKxxiiQ.js} +4 -4
  295. package/server/{staleness-_Tr-GwdA.js → staleness-CT34nwr9.js} +1 -1
  296. package/server/{staleness-BID1BKdr.js → staleness-DPm7ClwA.js} +15 -3
  297. package/server/{state-home-CONQvZR0.js → state-home-Cn_Qu8IX.js} +96 -44
  298. package/server/{state-migrate-BeBW0KXA.js → state-migrate-BGg2ZaOt.js} +12 -3
  299. package/server/{stuck-remediation-CKnIryGT.js → stuck-remediation-DYuPRYYw.js} +307 -26
  300. package/server/{stuck-remediation-CsGD5Ksb.js → stuck-remediation-s9_2qfi6.js} +1 -1
  301. package/server/{substrate-bug-weights-service-CpIZILj9.js → substrate-bug-weights-service-B-FwCs5V.js} +3 -3
  302. package/server/{summary-fork-bX6ax6X7.js → summary-fork-D1RAk9rJ.js} +78 -12
  303. package/server/{summary-fork-agEMsPSo.js → summary-fork-DpcxN9tf.js} +2 -2
  304. package/server/supervisor/{injection-budget-C1iPirFS.js → injection-budget-Csw5tqfJ.js} +2 -41
  305. package/server/supervisor/pty-supervisor.js +2 -1
  306. package/server/supervisor/pty-token-x-ea28Us.js +43 -0
  307. package/server/supervisor-FTJAIsAK.js +2 -0
  308. package/server/{supervisor-Ctt4eRYz.js → supervisor-wM4ooB5O.js} +3 -3
  309. package/server/{swarm-readiness-DdmJVX7y.js → swarm-readiness-DlP_UjHq.js} +4 -4
  310. package/server/{system-prerequisites-DSXBvffY.js → system-prerequisites-DUDj1YHf.js} +56 -29
  311. package/server/{teardown-workspace-DDCf5n-a.js → teardown-workspace-DeTTImn-.js} +15 -15
  312. package/server/{test-agent-queue-BJZ9Nfcc.js → test-agent-queue-MbxX5vqq.js} +7 -7
  313. package/server/{test-verdict-Cp5tljlJ.js → test-verdict-bWYBtqBg.js} +1 -1
  314. package/server/{test-verdict-D_-sXIz_.js → test-verdict-gscuksPv.js} +1 -1
  315. package/server/{tldr-daemon-B8_oT5gx.js → tldr-daemon-BYFkts95.js} +1 -1
  316. package/server/{tldr-daemon-BQFmmFp0.js → tldr-daemon-C-69c3OI.js} +2 -2
  317. package/server/tmux-B6z7h_vZ.js +3 -0
  318. package/server/{tmux-L5LgvGLp.js → tmux-R7N7y-Mh.js} +76 -44
  319. package/server/{token-BkQLy4yS.js → token-BK6t8BIT.js} +2 -2
  320. package/server/token-util-DuPuNriz.js +3 -0
  321. package/server/{token-util-DI8sGlmF.js → token-util-DxXu-vd1.js} +1 -1
  322. package/server/{tracker-config-DdT-nUAM.js → tracker-config-G6latr8C.js} +2 -2
  323. package/server/{tracker-utils-DV3h1FYG.js → tracker-utils-B4ylXZQK.js} +1 -1
  324. package/server/{tracker-utils-CawsPSS2.js → tracker-utils-DHv5pSDT.js} +2 -2
  325. package/server/{traefik-connect-C6mJckNs.js → traefik-connect-Df2uXPsQ.js} +1 -1
  326. package/server/{tunnel-IdK1iTHx.js → tunnel-CDVKJpRv.js} +3 -3
  327. package/server/{tunnel-BIFl98rc.js → tunnel-DGdUkGoZ.js} +1 -1
  328. package/server/{types-7-GnJn0t.js → types-5M0lupud.js} +1 -1
  329. package/server/{uat-train-0Ujk8GCv.js → uat-train-B05BWkp-.js} +1 -1
  330. package/server/{uat-train-j0cPeMSj.js → uat-train-DDSrSoV1.js} +28 -28
  331. package/server/validate-IfDGkaVR.js +177 -0
  332. package/server/{validation-DcAgXTQp.js → validation-CC9OPqJZ.js} +1 -1
  333. package/server/{validation-CabEISJT.js → validation-Dw1pzDzr.js} +259 -9
  334. package/server/{verification-artifact-Ck1tefmz.js → verification-artifact-B3itKTxu.js} +1 -1
  335. package/server/{verification-artifact-BuTA1QbL.js → verification-artifact-TVFSz_q1.js} +1 -1
  336. package/server/{verification-runner-DlJezzef.js → verification-runner-BW4HOKAz.js} +1 -1
  337. package/server/{verification-runner-FiuAZ-H2.js → verification-runner-CkgX6EtI.js} +174 -124
  338. package/server/{vtt-parser-BnRsYzcz.js → vtt-parser-DYPbKcIJ.js} +1 -1
  339. package/server/{work-agent-prompt-DLthEPAq.js → work-agent-prompt-Du8Vh2aJ.js} +13 -13
  340. package/server/workflows-BQu4RFQ-.js +2 -0
  341. package/server/{workflows-BZNNYkGC.js → workflows-mbQzh6mQ.js} +39 -77
  342. package/server/{workspace-3IC-UkAi.js → workspace--8tnhDI0.js} +1 -1
  343. package/server/{workspace-D9ppycdg.js → workspace-BPUws1-_.js} +3 -3
  344. package/server/{workspace-config-Bigl_-Lk.js → workspace-config-CIVWZOQr.js} +1 -1
  345. package/server/{workspace-manager-ClkCIWTe.js → workspace-manager-CBhNdzE4.js} +76 -18
  346. package/server/workspace-manager-CWT55qeI.js +3 -0
  347. package/server/{workspace-metadata-BE0efUv_.js → workspace-metadata-BzHnwwX4.js} +1 -1
  348. package/server/{workspace-metadata-tiSRIWJP.js → workspace-metadata-_WygnyoX.js} +2 -2
  349. package/server/{workspaces-CFPcL0vl.js → workspaces-Do_9J0LQ.js} +309 -124
  350. package/sync-sources/agents/pan-inspect-agent.md +1 -1
  351. package/sync-sources/agents/pan-merge-agent.md +1 -1
  352. package/sync-sources/agents/pan-planning-agent.md +4 -4
  353. package/sync-sources/agents/pan-work-agent.md +1 -1
  354. package/sync-sources/dev-skills/pan-commit/SKILL.md +1 -1
  355. package/sync-sources/dev-skills/test-specialist-workflow/SKILL.md +1 -1
  356. package/sync-sources/hooks/record-cost-event.js +369 -75
  357. package/sync-sources/hooks/session-start-hook +7 -0
  358. package/sync-sources/hooks/work-agent-stop-hook +1 -1
  359. package/sync-sources/rules/per-bead-durability.md +1 -1
  360. package/sync-sources/rules/prd-authoring.md +1 -1
  361. package/sync-sources/skills/feature-work/SKILL.md +1 -1
  362. package/sync-sources/skills/okf/README.md +11 -3
  363. package/sync-sources/skills/okf/SKILL.md +12 -1
  364. package/sync-sources/skills/okf/docs/USAGE.md +15 -0
  365. package/sync-sources/skills/okf/references/overdeck.md +28 -0
  366. package/sync-sources/skills/pan/SKILL.md +2 -2
  367. package/sync-sources/skills/pan-admin-config/SKILL.md +1 -0
  368. package/sync-sources/skills/pan-approve/SKILL.md +1 -1
  369. package/sync-sources/skills/pan-close/SKILL.md +1 -1
  370. package/sync-sources/skills/pan-doctor/SKILL.md +1 -1
  371. package/sync-sources/skills/pan-flywheel/SKILL.md +18 -1
  372. package/sync-sources/skills/pan-knowledge/SKILL.md +10 -0
  373. package/sync-sources/skills/pan-new-project/SKILL.md +9 -11
  374. package/sync-sources/skills/pan-orders/SKILL.md +33 -0
  375. package/sync-sources/skills/pan-oversee/SKILL.md +5 -5
  376. package/sync-sources/skills/pan-plan/SKILL.md +6 -6
  377. package/sync-sources/skills/pan-quickstart/SKILL.md +1 -1
  378. package/sync-sources/skills/pan-recap/SKILL.md +2 -2
  379. package/sync-sources/skills/pan-review/SKILL.md +1 -1
  380. package/sync-sources/skills/pan-start/SKILL.md +7 -3
  381. package/sync-sources/skills/pan-swarm/SKILL.md +1 -1
  382. package/sync-sources/skills/pan-sync/SKILL.md +1 -1
  383. package/sync-sources/skills/pan-task/SKILL.md +2 -2
  384. package/sync-sources/skills/pan-wipe/SKILL.md +2 -2
  385. package/sync-sources/skills/pipeline-list/SKILL.md +1 -1
  386. package/sync-sources/skills/pipeline-status/SKILL.md +2 -2
  387. package/sync-sources/skills/plan/SKILL.md +11 -11
  388. package/sync-sources/skills/write-vbrief/SKILL.md +7 -282
  389. package/sync-sources/skills/write-xbrief/SKILL.md +295 -0
  390. package/sync-sources/templates/claude-md/sections/warnings.md +1 -1
  391. package/sync-sources/templates/traefik/dynamic/overdeck.yml.template +10 -0
  392. package/server/agent-state-Co5Sy2Fw.js +0 -3
  393. package/server/agents-DyHKlq1I.js +0 -3
  394. package/server/cli-BRORS9qY.js +0 -3
  395. package/server/codex-DNyiQDKW.js +0 -3
  396. package/server/context-layers-15gDOk20.js +0 -165
  397. package/server/context-layers-DlQKkHH2.js +0 -4
  398. package/server/deacon-swarm-CV54eNmU.js +0 -2
  399. package/server/dist-j64RzSrQ.js +0 -3
  400. package/server/flywheel-6WHU4O7A.js +0 -207
  401. package/server/flywheel-COR0mbRI.js +0 -522
  402. package/server/flywheel-Ctr5uuvo.js +0 -2
  403. package/server/forge-B0_opi-V.js +0 -2
  404. package/server/git-utils-CsKGnzFA.js +0 -3
  405. package/server/hume-BmhvfVbV.js +0 -3
  406. package/server/inspect-agent-Dq0z1k3H.js +0 -2
  407. package/server/layers-Cp1To4L8.js +0 -93
  408. package/server/lifecycle-io-DmY2qwCn.js +0 -3
  409. package/server/merge-blockers-BYjeXrVN.js +0 -41
  410. package/server/merge-ops-DwWCkSgo.js +0 -2
  411. package/server/merge-set-DiISXcC-.js +0 -139
  412. package/server/projects-BKkwpH6q.js +0 -3
  413. package/server/public/assets/index-Bdc4V9ba.css +0 -1
  414. package/server/public/assets/mermaid-GHXKKRXX-B5v_r7cI.js +0 -1
  415. package/server/rally-OSJXdiHK.js +0 -3
  416. package/server/rebuild-stack-CKjJAI8L.js +0 -3
  417. package/server/record-rwK-nKv_.js +0 -3
  418. package/server/record-update-Crz74r-6.js +0 -168
  419. package/server/resume-wZZsWtzz.js +0 -3
  420. package/server/review-status-Bnh-rdkY.js +0 -3
  421. package/server/settings-BlUsVaUc.js +0 -2
  422. package/server/specialists-Dqe6_HE5.js +0 -3
  423. package/server/specs-BhOKBzqk.js +0 -3
  424. package/server/stack-health-Bd06frFn.js +0 -3
  425. package/server/supervisor-COVHrBTg.js +0 -2
  426. package/server/tmux-BAvtac_u.js +0 -3
  427. package/server/token-util-BArZLN6w.js +0 -3
  428. package/server/workflows-C4mR0Reb.js +0 -2
  429. package/server/workspace-manager-B1WOfKvB.js +0 -3
@@ -0,0 +1,1084 @@
1
+ import { a as __toCommonJS } from "./rolldown-runtime-DNCzzKnI.js";
2
+ import { Ht as flushAutoCommits, Tn as init_projects, Ut as init_auto_commit, Wt as queueAutoCommit, fn as findProjectByPathSync, nn as init_state_read_home, rn as resolveStateReadHomeSync, vn as getProjectSwarmHotspots } from "./config-yaml-DySPNmKN.js";
3
+ import { S as FlywheelStatus, d as OrderBookIndexEntry, t as init_src, u as OrderBook, x as FlywheelRunId } from "./src-DtcUOZCq.js";
4
+ import { c as getReviewStatusSync, l as init_review_status } from "./review-status-kZj_KyCk.js";
5
+ import { a as countAgentsByStatusRole, o as init_agents } from "./agents-EbI0zCJl.js";
6
+ import { Gn as getAgentDir, b as init_agents$1, ft as stopAgent, ut as spawnRun } from "./queries-CjNIf-Ub.js";
7
+ import { n as init_issue_service_singleton, r as issue_service_singleton_exports } from "./issue-service-singleton-Yx5DdmVJ.js";
8
+ import { o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-s0-oKybJ.js";
9
+ import { d as isFlywheelAutoPickupBacklog, f as isFlywheelGloballyPaused, i as getFlywheelActiveRunId, p as isFlywheelRequireUatBeforeMerge, s as init_control_settings, x as setFlywheelGloballyPaused, y as setFlywheelActiveRunId } from "./control-settings-BQp7_4uD.js";
10
+ import { n as parseSequenceMd, t as init_sequence_io } from "./sequence-io-D909zgeH.js";
11
+ import { l as computeCohort, m as init_pickup, n as LEGACY_PARKED_LABELS } from "./pickup-DUCLWrJY.js";
12
+ import { a as declaredIssueFootprint, i as computePredictedConflictSignals, s as pickFromSequence } from "./flywheel-merge-order-UU0tiUld.js";
13
+ import { i as gatherProjectLensSignals, n as init_pipeline_membership, o as init_pipeline_membership_gather, r as resolvePipelineMembership } from "./pipeline-membership-mY3GprlK.js";
14
+ import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
15
+ import { Effect, Schema } from "effect";
16
+ import { homedir } from "node:os";
17
+ import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
18
+ import { mkdir, readFile, readdir, realpath, rename, stat as stat$1, writeFile } from "node:fs/promises";
19
+ import { exec } from "node:child_process";
20
+ import { promisify } from "node:util";
21
+ //#region ../../lib/orders/types.ts
22
+ init_projects();
23
+ init_state_read_home();
24
+ init_auto_commit();
25
+ init_internal_token();
26
+ init_review_status();
27
+ init_agents$1();
28
+ init_sequence_io();
29
+ init_pickup();
30
+ init_src();
31
+ const decodeOrderBook = Schema.decodeUnknownSync(OrderBook);
32
+ function parseOrderBookJson(value) {
33
+ try {
34
+ return {
35
+ ok: true,
36
+ book: decodeOrderBook(value)
37
+ };
38
+ } catch (error) {
39
+ return {
40
+ ok: false,
41
+ error: `Invalid order book: ${error instanceof Error ? error.message : String(error)}`
42
+ };
43
+ }
44
+ }
45
+ //#endregion
46
+ //#region ../../lib/orders/io.ts
47
+ init_src();
48
+ const BOOK_ID_PATTERN = /^\d{4}-\d{2}-\d{2}-[a-z0-9]+(?:-[a-z0-9]+)*$/;
49
+ const decodeIndex = Schema.decodeUnknownSync(Schema.Array(OrderBookIndexEntry));
50
+ function ordersDirectory(stateRoot) {
51
+ return join(stateRoot, "orders");
52
+ }
53
+ function orderBookPath(stateRoot, bookId) {
54
+ if (!BOOK_ID_PATTERN.test(bookId)) throw new Error(`Invalid order book id: ${bookId}`);
55
+ return join(ordersDirectory(stateRoot), `${bookId}.json`);
56
+ }
57
+ function orderBookIndexPath(stateRoot) {
58
+ return join(ordersDirectory(stateRoot), "index.json");
59
+ }
60
+ function backlogSequencePath(stateRoot) {
61
+ return join(stateRoot, "backlog", "sequence.md");
62
+ }
63
+ function readOrderBook(stateRoot, bookId) {
64
+ const path = orderBookPath(stateRoot, bookId);
65
+ if (!existsSync(path)) return null;
66
+ let value;
67
+ try {
68
+ value = JSON.parse(readFileSync(path, "utf8"));
69
+ } catch (error) {
70
+ throw new Error(`Could not parse order book ${bookId}: ${error instanceof Error ? error.message : String(error)}`);
71
+ }
72
+ const parsed = parseOrderBookJson(value);
73
+ if (!parsed.ok) throw new Error(`Could not parse order book ${bookId}: ${parsed.error}`);
74
+ if (parsed.book.id !== bookId) throw new Error(`Order book ${bookId} contains mismatched id ${parsed.book.id}`);
75
+ return parsed.book;
76
+ }
77
+ function readOrderBookIndex(stateRoot) {
78
+ const path = orderBookIndexPath(stateRoot);
79
+ if (!existsSync(path)) return [];
80
+ try {
81
+ return decodeIndex(JSON.parse(readFileSync(path, "utf8")));
82
+ } catch (error) {
83
+ throw new Error(`Could not parse order book index: ${error instanceof Error ? error.message : String(error)}`);
84
+ }
85
+ }
86
+ function listOrderBookIds(stateRoot) {
87
+ const indexed = readOrderBookIndex(stateRoot).map((entry) => entry.id);
88
+ if (indexed.length > 0 || !existsSync(ordersDirectory(stateRoot))) return [...indexed];
89
+ return readdirSync(ordersDirectory(stateRoot)).filter((name) => name !== "index.json" && name.endsWith(".json")).map((name) => name.slice(0, -5)).filter((id) => BOOK_ID_PATTERN.test(id)).sort();
90
+ }
91
+ function preserveOperatorOwnedState(prior, next) {
92
+ if (!prior) return next;
93
+ if (prior.id !== next.id) throw new Error(`Order book id is immutable: ${prior.id} cannot become ${next.id}`);
94
+ const priorItems = new Map(prior.items.map((item) => [item.issue.toUpperCase(), item]));
95
+ const items = next.items.map((item) => {
96
+ const existing = priorItems.get(item.issue.toUpperCase());
97
+ if (!existing) return item;
98
+ return {
99
+ ...item,
100
+ addedAt: existing.addedAt,
101
+ addedBy: existing.addedBy
102
+ };
103
+ });
104
+ return {
105
+ ...next,
106
+ createdAt: prior.createdAt,
107
+ items
108
+ };
109
+ }
110
+ function indexEntry(book) {
111
+ return {
112
+ id: book.id,
113
+ name: book.name,
114
+ status: book.status,
115
+ runId: book.runId,
116
+ updatedAt: book.updatedAt
117
+ };
118
+ }
119
+ /**
120
+ * Physical state-store primitive used only by the orders writer. Domain callers
121
+ * must mutate order books through writer.ts so the book and queue stay aligned.
122
+ */
123
+ async function writeOrderBookState(stateRoot, nextBook, queueOrder) {
124
+ const book = preserveOperatorOwnedState(readOrderBook(stateRoot, nextBook.id), nextBook);
125
+ const bookPath = orderBookPath(stateRoot, book.id);
126
+ const indexPath = orderBookIndexPath(stateRoot);
127
+ const existingIndex = [...readOrderBookIndex(stateRoot)];
128
+ const byId = new Map(existingIndex.map((entry) => [entry.id, entry]));
129
+ byId.set(book.id, indexEntry(book));
130
+ const ids = [...queueOrder ?? existingIndex.map((entry) => entry.id)];
131
+ if (!ids.includes(book.id)) ids.push(book.id);
132
+ for (const entry of existingIndex) if (!ids.includes(entry.id)) ids.push(entry.id);
133
+ const index = ids.map((id) => byId.get(id)).filter((entry) => Boolean(entry));
134
+ mkdirSync(dirname(bookPath), { recursive: true });
135
+ writeFileSync(bookPath, `${JSON.stringify(book, null, 2)}\n`, "utf8");
136
+ writeFileSync(indexPath, `${JSON.stringify(index, null, 2)}\n`, "utf8");
137
+ queueAutoCommit({
138
+ projectRoot: stateRoot,
139
+ repoRoot: stateRoot,
140
+ paths: [bookPath, indexPath],
141
+ subject: `chore(state): update order book ${book.id}`
142
+ });
143
+ const flushed = await Effect.runPromise(flushAutoCommits(stateRoot));
144
+ if (flushed.errored || flushed.pushed === false) throw new Error(`Failed to persist order book ${book.id}: ${flushed.reason ?? "state commit failed"}`);
145
+ return book;
146
+ }
147
+ //#endregion
148
+ //#region ../../lib/orders/resolver.ts
149
+ const COMPLETE_STATUS = "complete";
150
+ function labelNames(issue) {
151
+ return (Array.isArray(issue.labels) ? issue.labels : []).map((label) => typeof label === "string" ? label : typeof label === "object" && label !== null && typeof label.name === "string" ? label.name : "").filter(Boolean).map((label) => label.toLowerCase());
152
+ }
153
+ function issueIdentifier(issue) {
154
+ for (const key of [
155
+ "identifier",
156
+ "issueId",
157
+ "id"
158
+ ]) {
159
+ const value = issue[key];
160
+ if (typeof value === "string" && value) return value.toUpperCase();
161
+ }
162
+ return "";
163
+ }
164
+ function issueIsClosed(issue) {
165
+ return [
166
+ issue.canonicalStatus,
167
+ issue.status,
168
+ issue.state
169
+ ].map((value) => typeof value === "string" ? value.toLowerCase().replace(/[ -]/g, "_") : "").some((value) => [
170
+ "done",
171
+ "completed",
172
+ "closed",
173
+ "canceled",
174
+ "cancelled"
175
+ ].includes(value));
176
+ }
177
+ const liveOrderIssueLookup = (issueIds) => {
178
+ const wanted = new Set(issueIds.map((id) => id.toUpperCase()));
179
+ const result = /* @__PURE__ */ new Map();
180
+ try {
181
+ const { getSharedIssueService } = (init_issue_service_singleton(), __toCommonJS(issue_service_singleton_exports));
182
+ const issues = getSharedIssueService().getIssues({
183
+ cycle: "all",
184
+ includeCompleted: true
185
+ });
186
+ for (const issue of issues) {
187
+ const id = issueIdentifier(issue);
188
+ if (!wanted.has(id)) continue;
189
+ const labels = labelNames(issue);
190
+ const closed = issueIsClosed(issue);
191
+ result.set(id, {
192
+ issue: id,
193
+ open: !closed,
194
+ parked: labels.includes("parked") || LEGACY_PARKED_LABELS.some((label) => labels.includes(label))
195
+ });
196
+ }
197
+ } catch {}
198
+ return result;
199
+ };
200
+ /** The sole order-book read door. */
201
+ function listBooks(stateRoot) {
202
+ return listOrderBookIds(stateRoot).map((id) => {
203
+ const book = readOrderBook(stateRoot, id);
204
+ if (!book) throw new Error(`Order book index references missing book ${id}`);
205
+ return book;
206
+ });
207
+ }
208
+ function getBook(stateRoot, bookId) {
209
+ return readOrderBook(stateRoot, bookId);
210
+ }
211
+ function membership(stateRoot) {
212
+ const result = /* @__PURE__ */ new Map();
213
+ for (const book of listBooks(stateRoot)) {
214
+ if (book.status === COMPLETE_STATUS) continue;
215
+ for (const item of book.items) {
216
+ const issue = item.issue.toUpperCase();
217
+ const existing = result.get(issue);
218
+ if (existing && existing !== book.id) throw new Error(`Issue ${issue} belongs to multiple non-complete order books: ${existing}, ${book.id}`);
219
+ result.set(issue, book.id);
220
+ }
221
+ }
222
+ return result;
223
+ }
224
+ function backlogCandidates(stateRoot, limit) {
225
+ if (limit <= 0) return [];
226
+ const path = backlogSequencePath(stateRoot);
227
+ if (!existsSync(path)) return [];
228
+ const parsed = parseSequenceMd(readFileSync(path, "utf8"));
229
+ if (!parsed.ok) throw new Error(`Could not parse backlog sequence: ${parsed.error}`);
230
+ const assigned = membership(stateRoot);
231
+ return [...parsed.doc.nodes].sort((a, b) => a.rank - b.rank).filter((node) => !assigned.has(node.issue.toUpperCase())).slice(0, limit);
232
+ }
233
+ function computeBookProgress(book, issueLookup = liveOrderIssueLookup) {
234
+ const state = issueLookup(book.items.map((item) => item.issue));
235
+ const items = book.items.map((item) => {
236
+ const issue = state.get(item.issue.toUpperCase());
237
+ const closed = issue ? !issue.open : false;
238
+ const parked = issue?.parked ?? false;
239
+ return {
240
+ issue: item.issue,
241
+ lane: item.lane,
242
+ order: item.order,
243
+ closed,
244
+ parked,
245
+ terminal: closed || parked
246
+ };
247
+ });
248
+ return {
249
+ bookId: book.id,
250
+ total: items.length,
251
+ landed: items.filter((item) => item.closed).length,
252
+ items,
253
+ drained: items.every((item) => item.terminal)
254
+ };
255
+ }
256
+ //#endregion
257
+ //#region ../../lib/orders/writer.ts
258
+ init_agents();
259
+ init_control_settings();
260
+ function timestamp(value) {
261
+ return value ?? (/* @__PURE__ */ new Date()).toISOString();
262
+ }
263
+ function requireBook(stateRoot, bookId) {
264
+ const book = getBook(stateRoot, bookId);
265
+ if (!book) throw new Error(`Order book not found: ${bookId}`);
266
+ return book;
267
+ }
268
+ function normalizeLaneOrder(items) {
269
+ const laneA = items.filter((item) => item.lane === "A").sort((a, b) => a.order - b.order);
270
+ const laneB = items.filter((item) => item.lane === "B").sort((a, b) => a.order - b.order);
271
+ return [...laneA.map((item, index) => ({
272
+ ...item,
273
+ order: index + 1
274
+ })), ...laneB.map((item, index) => ({
275
+ ...item,
276
+ order: index + 1
277
+ }))];
278
+ }
279
+ function updated(book, changes, at) {
280
+ return {
281
+ ...book,
282
+ ...changes,
283
+ id: book.id,
284
+ createdAt: book.createdAt,
285
+ updatedAt: timestamp(at)
286
+ };
287
+ }
288
+ /** The sole order-book write door. */
289
+ async function createBook(stateRoot, input) {
290
+ if (getBook(stateRoot, input.id)) throw new Error(`Order book already exists: ${input.id}`);
291
+ const at = timestamp(input.createdAt);
292
+ const settings = {
293
+ laneAConcurrency: input.settings?.laneAConcurrency ?? 1,
294
+ briefOverlay: input.settings?.briefOverlay,
295
+ posture: input.settings?.posture ?? "open",
296
+ postureSetAt: input.settings?.postureSetAt,
297
+ postureSetBy: input.settings?.postureSetBy,
298
+ postureReason: input.settings?.postureReason
299
+ };
300
+ if (!Number.isInteger(settings.laneAConcurrency) || settings.laneAConcurrency < 1) throw new Error("laneAConcurrency must be a positive integer");
301
+ return writeOrderBookState(stateRoot, {
302
+ id: input.id,
303
+ name: input.name,
304
+ status: "draft",
305
+ settings,
306
+ items: [],
307
+ createdAt: at,
308
+ updatedAt: at
309
+ });
310
+ }
311
+ async function renameBook(stateRoot, bookId, name, at) {
312
+ if (!name.trim()) throw new Error("Order book name cannot be empty");
313
+ return writeOrderBookState(stateRoot, updated(requireBook(stateRoot, bookId), { name: name.trim() }, at));
314
+ }
315
+ async function addItems(stateRoot, bookId, items, actor, at) {
316
+ const book = requireBook(stateRoot, bookId);
317
+ const existing = new Set(book.items.map((item) => item.issue.toUpperCase()));
318
+ const assigned = membership(stateRoot);
319
+ const addedAt = timestamp(at);
320
+ const additions = [];
321
+ for (const item of items) {
322
+ const issue = item.issue.toUpperCase();
323
+ if (existing.has(issue) || additions.some((candidate) => candidate.issue.toUpperCase() === issue)) throw new Error(`Issue ${issue} is already in order book ${bookId}`);
324
+ const otherBook = assigned.get(issue);
325
+ if (otherBook && otherBook !== bookId) throw new Error(`Issue ${issue} already belongs to non-complete order book ${otherBook}`);
326
+ additions.push({
327
+ ...item,
328
+ issue,
329
+ prereqs: item.prereqs.map((prereq) => prereq.toUpperCase()),
330
+ addedAt: item.addedAt ?? addedAt,
331
+ addedBy: item.addedBy ?? actor
332
+ });
333
+ }
334
+ return writeOrderBookState(stateRoot, updated(book, { items: normalizeLaneOrder([...book.items, ...additions]) }, at));
335
+ }
336
+ async function removeItem(stateRoot, bookId, issueId, at) {
337
+ const book = requireBook(stateRoot, bookId);
338
+ const issue = issueId.toUpperCase();
339
+ if (!book.items.some((item) => item.issue.toUpperCase() === issue)) throw new Error(`Issue ${issue} is not in order book ${bookId}`);
340
+ return writeOrderBookState(stateRoot, updated(book, { items: normalizeLaneOrder(book.items.filter((item) => item.issue.toUpperCase() !== issue)) }, at));
341
+ }
342
+ async function moveItem(stateRoot, bookId, issueId, lane, order, at) {
343
+ const book = requireBook(stateRoot, bookId);
344
+ const issue = issueId.toUpperCase();
345
+ const moving = book.items.find((item) => item.issue.toUpperCase() === issue);
346
+ if (!moving) throw new Error(`Issue ${issue} is not in order book ${bookId}`);
347
+ if (!Number.isInteger(order) || order < 1) throw new Error("Order must be a positive integer");
348
+ const remaining = book.items.filter((item) => item !== moving);
349
+ const targetLane = remaining.filter((item) => item.lane === lane).sort((a, b) => a.order - b.order);
350
+ targetLane.splice(Math.min(order - 1, targetLane.length), 0, {
351
+ ...moving,
352
+ lane,
353
+ order
354
+ });
355
+ const otherLane = remaining.filter((item) => item.lane !== lane).sort((a, b) => a.order - b.order);
356
+ return writeOrderBookState(stateRoot, updated(book, { items: normalizeLaneOrder([...targetLane, ...otherLane]) }, at));
357
+ }
358
+ async function setItemRequirements(stateRoot, bookId, issueId, requirements, at) {
359
+ const book = requireBook(stateRoot, bookId);
360
+ const issue = issueId.toUpperCase();
361
+ let found = false;
362
+ const items = book.items.map((item) => {
363
+ if (item.issue.toUpperCase() !== issue) return item;
364
+ found = true;
365
+ return {
366
+ ...item,
367
+ prereqs: requirements.prereqs === void 0 ? item.prereqs : [...new Set(requirements.prereqs.map((prereq) => prereq.toUpperCase()))],
368
+ reVerify: requirements.reVerify ?? item.reVerify,
369
+ planAtPickup: requirements.planAtPickup ?? item.planAtPickup
370
+ };
371
+ });
372
+ if (!found) throw new Error(`Issue ${issue} is not in order book ${bookId}`);
373
+ return writeOrderBookState(stateRoot, updated(book, { items }, at));
374
+ }
375
+ async function setSettings(stateRoot, bookId, settings, at) {
376
+ const book = requireBook(stateRoot, bookId);
377
+ const next = {
378
+ ...book.settings,
379
+ ...settings
380
+ };
381
+ if (!Number.isInteger(next.laneAConcurrency) || next.laneAConcurrency < 1) throw new Error("laneAConcurrency must be a positive integer");
382
+ return writeOrderBookState(stateRoot, updated(book, { settings: next }, at));
383
+ }
384
+ async function setStatus(stateRoot, bookId, status, options = {}) {
385
+ const book = requireBook(stateRoot, bookId);
386
+ if (status === "running") {
387
+ const running = listBooks(stateRoot).find((candidate) => candidate.status === "running" && candidate.id !== bookId);
388
+ if (running) throw new Error(`Order book ${running.id} is already running`);
389
+ }
390
+ return writeOrderBookState(stateRoot, updated(book, {
391
+ status,
392
+ runId: options.runId === void 0 ? book.runId : options.runId ?? void 0
393
+ }, options.at));
394
+ }
395
+ async function advanceQueue(stateRoot, completedBookId, at) {
396
+ if (requireBook(stateRoot, completedBookId).status !== "complete") await setStatus(stateRoot, completedBookId, "complete", { at });
397
+ const order = readOrderBookIndex(stateRoot).map((entry) => entry.id);
398
+ for (const id of order) {
399
+ const book = getBook(stateRoot, id);
400
+ if (book?.status === "ready") return book;
401
+ }
402
+ return null;
403
+ }
404
+ //#endregion
405
+ //#region services/flywheel-run-state.ts
406
+ init_src();
407
+ const decodeFlywheelStatus = Schema.decodeUnknownSync(FlywheelStatus);
408
+ const decodeFlywheelRunId$1 = Schema.decodeUnknownSync(FlywheelRunId);
409
+ const RUN_ID_PATTERN = /^RUN-(\d+)$/;
410
+ const DEFAULT_RUNS_LIMIT = 20;
411
+ const MAX_RUNS_LIMIT = 100;
412
+ const RUN_SUMMARY_CONCURRENCY = 4;
413
+ const flywheelStatusListeners = /* @__PURE__ */ new Set();
414
+ function subscribeLatestFlywheelStatus(listener) {
415
+ flywheelStatusListeners.add(listener);
416
+ return () => {
417
+ flywheelStatusListeners.delete(listener);
418
+ };
419
+ }
420
+ function publishLatestFlywheelStatus(status) {
421
+ for (const listener of flywheelStatusListeners) listener(status);
422
+ }
423
+ function publishFlywheelStatusCleared() {
424
+ publishLatestFlywheelStatus(null);
425
+ }
426
+ function parseFlywheelRunId(runId) {
427
+ return decodeFlywheelRunId$1(runId);
428
+ }
429
+ function isFlywheelRunId(runId) {
430
+ return RUN_ID_PATTERN.test(runId);
431
+ }
432
+ function runNumber(runId) {
433
+ const match = RUN_ID_PATTERN.exec(runId);
434
+ return match ? Number(match[1]) : 0;
435
+ }
436
+ function normalizeLimit(limit) {
437
+ if (limit === void 0) return DEFAULT_RUNS_LIMIT;
438
+ if (!Number.isFinite(limit) || limit <= 0) return DEFAULT_RUNS_LIMIT;
439
+ return Math.min(Math.floor(limit), MAX_RUNS_LIMIT);
440
+ }
441
+ async function mapWithConcurrency(items, concurrency, mapper) {
442
+ const results = new Array(items.length);
443
+ let index = 0;
444
+ await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, async () => {
445
+ while (index < items.length) {
446
+ const current = index;
447
+ index += 1;
448
+ results[current] = await mapper(items[current]);
449
+ }
450
+ }));
451
+ return results;
452
+ }
453
+ function getFlywheelHome(options = {}) {
454
+ return join(options.overdeckHome ?? process.env["OVERDECK_HOME"] ?? join(homedir(), ".overdeck"), "flywheel");
455
+ }
456
+ function getFlywheelRunsDir(options = {}) {
457
+ return join(getFlywheelHome(options), "runs");
458
+ }
459
+ function getFlywheelRunDir(runId, options = {}) {
460
+ return join(getFlywheelRunsDir(options), parseFlywheelRunId(runId));
461
+ }
462
+ /** Persist the run's cohort (issue ids) at run start. */
463
+ function saveRunCohort(runId, issueIds, options = {}) {
464
+ const dir = getFlywheelRunDir(runId, options);
465
+ mkdirSync(dir, { recursive: true });
466
+ writeFileSync(join(dir, "cohort.json"), JSON.stringify({
467
+ issueIds: [...issueIds],
468
+ snapshotAt: (/* @__PURE__ */ new Date()).toISOString()
469
+ }, null, 2), "utf-8");
470
+ }
471
+ async function nextFlywheelRunId(options = {}) {
472
+ const runsDir = getFlywheelRunsDir(options);
473
+ await mkdir(runsDir, { recursive: true });
474
+ return parseFlywheelRunId(`RUN-${(await readdir(runsDir, { withFileTypes: true })).reduce((max, entry) => {
475
+ if (!entry.isDirectory()) return max;
476
+ const match = RUN_ID_PATTERN.exec(entry.name);
477
+ if (!match) return max;
478
+ return Math.max(max, Number(match[1]));
479
+ }, 0) + 1}`);
480
+ }
481
+ async function writeJsonAtomic(path, payload) {
482
+ const tmpPath = join(dirname(path), `.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`);
483
+ await mkdir(dirname(path), { recursive: true });
484
+ await writeFile(tmpPath, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
485
+ await rename(tmpPath, path);
486
+ return path;
487
+ }
488
+ function enrichFlywheelStatusWithOrders(status, book, progress) {
489
+ const terminalPipelineStatuses = new Set([
490
+ "failed",
491
+ "merged",
492
+ "parked"
493
+ ]);
494
+ const inFlight = new Set(status.activePipeline.filter((item) => !terminalPipelineStatuses.has(item.status)).map((item) => item.issueId.toUpperCase()));
495
+ const laneAInFlight = book.items.filter((item) => item.lane === "A" && inFlight.has(item.issue.toUpperCase())).sort((left, right) => left.order - right.order).map((item) => item.issue);
496
+ const laneBInFlight = book.items.filter((item) => item.lane === "B" && inFlight.has(item.issue.toUpperCase())).sort((left, right) => left.order - right.order)[0]?.issue;
497
+ return {
498
+ ...status,
499
+ orders: {
500
+ bookId: book.id,
501
+ bookName: book.name,
502
+ landed: progress.landed,
503
+ total: progress.total,
504
+ laneAInFlight,
505
+ ...laneBInFlight ? { laneBInFlight } : {},
506
+ drained: progress.drained
507
+ }
508
+ };
509
+ }
510
+ async function mechanicallyEnrichOrdersStatus(status, options) {
511
+ const launch = await readFlywheelLaunchMetadata(status.runId, options);
512
+ if (!launch?.orders) {
513
+ const { orders: _untrustedOrders, ...booklessStatus } = status;
514
+ return booklessStatus;
515
+ }
516
+ const stateRoot = options.orderStateRoot?.(launch.workspace) ?? (() => {
517
+ const project = findProjectByPathSync(launch.workspace);
518
+ if (!project) throw new Error(`No configured project contains orders-bound Flywheel workspace ${launch.workspace}`);
519
+ return resolveStateReadHomeSync(project).root;
520
+ })();
521
+ const book = (options.getOrderBook ?? getBook)(stateRoot, launch.orders.bookId);
522
+ if (!book) throw new Error(`Flywheel run ${status.runId} references missing order book ${launch.orders.bookId}`);
523
+ const progress = (options.computeOrderProgress ?? computeBookProgress)(book);
524
+ if (progress.drained && book.status === "running") await (options.setOrderStatus ?? setStatus)(stateRoot, book.id, "drained", { runId: book.runId });
525
+ return enrichFlywheelStatusWithOrders(status, book, progress);
526
+ }
527
+ async function writeLatestFlywheelStatus(status, options = {}) {
528
+ const enriched = await mechanicallyEnrichOrdersStatus(status, options);
529
+ const latestPath = join(getFlywheelRunDir(status.runId, options), "latest.json");
530
+ await writeJsonAtomic(latestPath, enriched);
531
+ publishLatestFlywheelStatus(enriched);
532
+ return latestPath;
533
+ }
534
+ function decodeLaunchMetadata(payload) {
535
+ if (typeof payload !== "object" || payload === null) throw new Error("Invalid Flywheel launch metadata");
536
+ const record = payload;
537
+ if (record.version !== 1) throw new Error("Invalid Flywheel launch metadata version");
538
+ for (const key of [
539
+ "runId",
540
+ "workspace",
541
+ "briefPath",
542
+ "briefDisplayPath"
543
+ ]) if (typeof record[key] !== "string" || !record[key]) throw new Error(`Invalid Flywheel launch metadata: ${key}`);
544
+ if (record.briefOverlayPath !== void 0 && (typeof record.briefOverlayPath !== "string" || !record.briefOverlayPath)) throw new Error("Invalid Flywheel launch metadata: briefOverlayPath");
545
+ if (record.orders !== void 0) {
546
+ const orders = record.orders;
547
+ if (!orders || typeof orders !== "object" || typeof orders.bookId !== "string" || !orders.bookId) throw new Error("Invalid Flywheel launch metadata: orders.bookId");
548
+ }
549
+ return record;
550
+ }
551
+ async function writeFlywheelLaunchMetadata(metadata, options = {}) {
552
+ const runId = parseFlywheelRunId(metadata.runId);
553
+ return writeJsonAtomic(join(getFlywheelRunDir(runId, options), "launch.json"), {
554
+ ...metadata,
555
+ runId
556
+ });
557
+ }
558
+ async function readFlywheelLaunchMetadata(runId, options = {}) {
559
+ const launchPath = join(getFlywheelRunDir(runId, options), "launch.json");
560
+ try {
561
+ return decodeLaunchMetadata(JSON.parse(await readFile(launchPath, "utf8")));
562
+ } catch (error) {
563
+ if ((typeof error === "object" && error !== null && "code" in error ? error.code : void 0) === "ENOENT") return null;
564
+ throw error;
565
+ }
566
+ }
567
+ async function readLatestFlywheelStatus(runId, options = {}) {
568
+ const latestPath = join(getFlywheelRunDir(runId, options), "latest.json");
569
+ try {
570
+ return decodeFlywheelStatus(JSON.parse(await readFile(latestPath, "utf8")));
571
+ } catch (error) {
572
+ if ((typeof error === "object" && error !== null && "code" in error ? error.code : void 0) === "ENOENT") return null;
573
+ throw error;
574
+ }
575
+ }
576
+ async function fileExists(path) {
577
+ try {
578
+ return (await stat$1(path)).isFile();
579
+ } catch (error) {
580
+ if ((typeof error === "object" && error !== null && "code" in error ? error.code : void 0) === "ENOENT") return false;
581
+ throw error;
582
+ }
583
+ }
584
+ async function deriveRunStatus(runDir, runId, activeRunId) {
585
+ if (await fileExists(join(runDir, "aborted.json"))) return "aborted";
586
+ if (await fileExists(join(runDir, "report.md"))) return "complete";
587
+ if (activeRunId !== runId) return "aborted";
588
+ return isFlywheelGloballyPaused() ? "paused" : "running";
589
+ }
590
+ async function summarizeRun(runId, options, activeRunId) {
591
+ const runDir = getFlywheelRunDir(runId, options);
592
+ const latest = await readLatestFlywheelStatus(runId, options);
593
+ const status = await deriveRunStatus(runDir, runId, activeRunId);
594
+ return {
595
+ id: runId,
596
+ startedAt: latest?.startedAt ?? "",
597
+ status
598
+ };
599
+ }
600
+ async function readCurrentLatestFlywheelStatus(options = {}) {
601
+ const activeRunId = options.activeRunId === void 0 ? getFlywheelActiveRunId() : options.activeRunId;
602
+ if (!activeRunId || !isFlywheelRunId(activeRunId)) return null;
603
+ const activeRun = await getFlywheelRunDetail(activeRunId, options);
604
+ return activeRun?.status === "running" || activeRun?.status === "paused" ? activeRun.latest : null;
605
+ }
606
+ function selectLatestRunIds(entries, limit) {
607
+ const selected = [];
608
+ for (const entry of entries) {
609
+ if (!entry.isDirectory() || !isFlywheelRunId(entry.name)) continue;
610
+ selected.push(entry.name);
611
+ selected.sort((a, b) => runNumber(b) - runNumber(a));
612
+ if (selected.length > limit) selected.length = limit;
613
+ }
614
+ return selected;
615
+ }
616
+ async function listFlywheelRuns(options = {}) {
617
+ const runsDir = getFlywheelRunsDir(options);
618
+ let entries;
619
+ try {
620
+ entries = await readdir(runsDir, { withFileTypes: true });
621
+ } catch (error) {
622
+ if ((typeof error === "object" && error !== null && "code" in error ? error.code : void 0) === "ENOENT") return [];
623
+ throw error;
624
+ }
625
+ const runIds = selectLatestRunIds(entries, normalizeLimit(options.limit));
626
+ const activeRunId = getFlywheelActiveRunId();
627
+ return (await mapWithConcurrency(runIds, RUN_SUMMARY_CONCURRENCY, (runId) => summarizeRun(runId, options, activeRunId))).sort((a, b) => b.startedAt.localeCompare(a.startedAt));
628
+ }
629
+ /**
630
+ * PAN-1528/PAN-1908: overlay the flywheel capacity gauge from the indexed
631
+ * agents table. This status path must not enumerate state.json files.
632
+ */
633
+ async function countLiveWorkAgents(_options = {}) {
634
+ return countAgentsByStatusRole("running", "work");
635
+ }
636
+ function withLiveAgentsActive(latest, liveCount) {
637
+ if (latest.system.agentsActive === liveCount) return latest;
638
+ return {
639
+ ...latest,
640
+ system: {
641
+ ...latest.system,
642
+ agentsActive: liveCount
643
+ }
644
+ };
645
+ }
646
+ async function getFlywheelRunDetail(runId, options = {}) {
647
+ const runDir = getFlywheelRunDir(runId, options);
648
+ const latest = await readLatestFlywheelStatus(runId, options);
649
+ if (!latest) return null;
650
+ const status = await deriveRunStatus(runDir, runId, options.activeRunId !== void 0 ? options.activeRunId : getFlywheelActiveRunId());
651
+ const reportPath = join(runDir, "report.md");
652
+ const openedPrPath = join(runDir, "opened-pr.json");
653
+ const liveCount = await countLiveWorkAgents(options);
654
+ return {
655
+ id: runId,
656
+ startedAt: latest.startedAt,
657
+ status,
658
+ latest: withLiveAgentsActive(latest, liveCount),
659
+ ...latest.orders ? { orders: latest.orders } : {},
660
+ paths: {
661
+ latest: join(runDir, "latest.json"),
662
+ ...await fileExists(reportPath) ? { report: reportPath } : {},
663
+ ...await fileExists(openedPrPath) ? { openedPr: openedPrPath } : {}
664
+ }
665
+ };
666
+ }
667
+ function clearFlywheelGate() {
668
+ setFlywheelActiveRunId(null);
669
+ setFlywheelGloballyPaused(false);
670
+ publishFlywheelStatusCleared();
671
+ }
672
+ async function resolveLiveFlywheelRunId(options = {}) {
673
+ const candidate = getFlywheelActiveRunId();
674
+ if (!candidate) return null;
675
+ if (!isFlywheelRunId(candidate)) {
676
+ clearFlywheelGate();
677
+ return null;
678
+ }
679
+ if (!await readLatestFlywheelStatus(candidate, options)) {
680
+ clearFlywheelGate();
681
+ return null;
682
+ }
683
+ const status = await deriveRunStatus(getFlywheelRunDir(candidate, options), candidate, candidate);
684
+ if (status === "complete" || status === "aborted") {
685
+ clearFlywheelGate();
686
+ return null;
687
+ }
688
+ return candidate;
689
+ }
690
+ async function abortFlywheelRun(runId, options = {}) {
691
+ const parsed = parseFlywheelRunId(runId);
692
+ await writeJsonAtomic(join(getFlywheelRunDir(parsed, options), "aborted.json"), {
693
+ runId: parsed,
694
+ abortedAt: (/* @__PURE__ */ new Date()).toISOString()
695
+ });
696
+ if (getFlywheelActiveRunId() === parsed) clearFlywheelGate();
697
+ }
698
+ //#endregion
699
+ //#region ../../lib/flywheel-start.ts
700
+ const execAsync = promisify(exec);
701
+ function isInsideRoot(projectRoot, candidate) {
702
+ const relativePath = relative(projectRoot, candidate);
703
+ return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute(relativePath);
704
+ }
705
+ function resolveFlywheelStartBriefPath(cwd, requestedPath) {
706
+ const rawPath = requestedPath?.trim() || "docs/flywheel-brief.md";
707
+ if (rawPath.includes("\0")) throw new Error("Brief path is invalid");
708
+ const root = resolve(cwd);
709
+ const absolutePath = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);
710
+ if (!isInsideRoot(root, absolutePath)) throw new Error("Brief path must stay inside the project root");
711
+ const normalizedRoot = root.endsWith(sep) ? root : `${root}${sep}`;
712
+ const displayPath = absolutePath === root ? "." : relative(root, absolutePath);
713
+ return {
714
+ absolutePath,
715
+ displayPath: absolutePath.startsWith(normalizedRoot) ? displayPath : absolutePath
716
+ };
717
+ }
718
+ async function assertExistingPathInsideRoot(projectRoot, candidate) {
719
+ const [realRoot, realCandidate] = await Promise.all([realpath(projectRoot), realpath(candidate)]);
720
+ if (!isInsideRoot(realRoot, realCandidate)) throw new Error("Brief path must stay inside the project root");
721
+ }
722
+ async function requireFlywheelBrief(cwd, requestedPath) {
723
+ const resolved = resolveFlywheelStartBriefPath(cwd, requestedPath);
724
+ try {
725
+ await assertExistingPathInsideRoot(cwd, resolved.absolutePath);
726
+ await readFile(resolved.absolutePath, "utf8");
727
+ return resolved;
728
+ } catch (error) {
729
+ if ((typeof error === "object" && error !== null && "code" in error ? error.code : void 0) === "ENOENT") throw new Error(`Flywheel brief not found: ${resolved.displayPath}`);
730
+ throw error;
731
+ }
732
+ }
733
+ /**
734
+ * The flywheel is a project-scoped singleton: it must run from the PRIMARY
735
+ * worktree root, never a linked feature worktree. Every worktree contains
736
+ * docs/flywheel-brief.md, so the brief check alone cannot catch a caller whose
737
+ * shell happens to sit inside a workspaces/feature-* checkout, and an
738
+ * orchestrator spawned there operates inside a live work agent's worktree.
739
+ * A linked worktree is
740
+ * detected by `git rev-parse --git-common-dir` resolving to the primary's
741
+ * .git directory; outside a repo (or on failure) the cwd is kept and the
742
+ * brief check reports its own error.
743
+ */
744
+ async function resolvePrimaryWorktreeRoot(cwd) {
745
+ try {
746
+ const { stdout } = await execAsync("git rev-parse --path-format=absolute --git-common-dir", {
747
+ cwd,
748
+ timeout: 5e3
749
+ });
750
+ const commonDir = stdout.trim();
751
+ if (commonDir.endsWith(`${sep}.git`)) return dirname(commonDir);
752
+ return cwd;
753
+ } catch {
754
+ return cwd;
755
+ }
756
+ }
757
+ //#endregion
758
+ //#region ../../lib/backlog/lookups.ts
759
+ /**
760
+ * Build the {@link ClassifyLookups} the shared pickup module needs from live project
761
+ * state: labels (in-memory issue service), planned (readable xBRIEF spec), and
762
+ * in-pipeline (review status / live workspace). Shared by the dashboard forecast
763
+ * route and the Flywheel run-cohort snapshot so both classify issues identically
764
+ * (PAN-2006 single source of truth). The issue service is lazy-required to avoid a
765
+ * static lib → dashboard layering edge.
766
+ */
767
+ function buildClassifyLookups(projectRoot, opts = {}) {
768
+ const labelsByIssue = /* @__PURE__ */ new Map();
769
+ if (!opts?.labels) try {
770
+ const { getSharedIssueService } = (init_issue_service_singleton(), __toCommonJS(issue_service_singleton_exports));
771
+ for (const issue of getSharedIssueService().getIssues()) {
772
+ const id = typeof issue["identifier"] === "string" ? issue["identifier"].toUpperCase() : "";
773
+ if (!id) continue;
774
+ const names = (Array.isArray(issue["labels"]) ? issue["labels"] : []).map((l) => typeof l === "string" ? l : l?.name ?? "").filter((s) => Boolean(s));
775
+ labelsByIssue.set(id, names);
776
+ }
777
+ } catch {}
778
+ const specsDir = join(projectRoot, ".pan", "specs");
779
+ const specIssues = /* @__PURE__ */ new Set();
780
+ if (existsSync(specsDir)) for (const f of readdirSync(specsDir)) {
781
+ const m = /^[\d-]+-([A-Z]+-\d+)-/i.exec(f);
782
+ if (m) specIssues.add(m[1].toUpperCase());
783
+ }
784
+ const workspacesDir = join(projectRoot, "workspaces");
785
+ return {
786
+ labels: opts?.labels ?? ((id) => labelsByIssue.get(id.toUpperCase()) ?? []),
787
+ isPlanned: (id) => {
788
+ const u = id.toUpperCase();
789
+ return specIssues.has(u);
790
+ },
791
+ isInPipeline: (id) => {
792
+ const rs = getReviewStatusSync(id.toUpperCase());
793
+ return rs !== null && rs.reviewStatus !== "pending" || existsSync(join(workspacesDir, `feature-${id.toLowerCase()}`));
794
+ }
795
+ };
796
+ }
797
+ //#endregion
798
+ //#region ../../lib/cloister/flywheel.ts
799
+ init_sequence_io();
800
+ init_projects();
801
+ init_state_read_home();
802
+ init_control_settings();
803
+ init_pickup();
804
+ init_pipeline_membership_gather();
805
+ init_pipeline_membership();
806
+ const FLYWHEEL_ORCHESTRATOR_AGENT_ID = "flywheel-orchestrator";
807
+ function isIssueInResolvedPipeline(issueId, memberships) {
808
+ return memberships.some((membership) => membership.issueId.toUpperCase() === issueId.toUpperCase() && membership.inPipeline);
809
+ }
810
+ async function activeOrderBookIssues(projectRoot, runId, deps = {}) {
811
+ const activeRunId = runId ?? (deps.activeRunId ?? getFlywheelActiveRunId)();
812
+ if (!activeRunId) return /* @__PURE__ */ new Set();
813
+ const bookId = (await (deps.readLaunch ?? readFlywheelLaunchMetadata)(activeRunId))?.orders?.bookId;
814
+ if (!bookId) return /* @__PURE__ */ new Set();
815
+ const stateRoot = deps.stateRoot?.(projectRoot) ?? (() => {
816
+ const project = findProjectByPathSync(projectRoot);
817
+ return project ? resolveStateReadHomeSync(project).root : null;
818
+ })();
819
+ if (!stateRoot) return /* @__PURE__ */ new Set();
820
+ const book = (deps.getBook ?? getBook)(stateRoot, bookId);
821
+ return new Set(book?.items.map((item) => item.issue.toUpperCase()) ?? []);
822
+ }
823
+ const FlywheelRunIdSchema = Schema.String.check(Schema.isPattern(/^RUN-\d+$/));
824
+ const decodeFlywheelRunId = Schema.decodeUnknownSync(FlywheelRunIdSchema);
825
+ function parseRunId(runId) {
826
+ return decodeFlywheelRunId(runId);
827
+ }
828
+ function defaultFlywheelRunId() {
829
+ return parseRunId(`RUN-${Date.now()}`);
830
+ }
831
+ function internalDashboardOrigin() {
832
+ const port = Number.parseInt(process.env["API_PORT"] ?? process.env["PORT"] ?? "3011", 10);
833
+ return process.env["OVERDECK_INTERNAL_DASHBOARD_URL"] ?? `http://127.0.0.1:${port}`;
834
+ }
835
+ async function fetchIssueRowsFromDashboard() {
836
+ const dashboardOrigin = internalDashboardOrigin();
837
+ const token = getInternalTokenSync();
838
+ if (!token) {
839
+ console.error("[flywheel] Cannot load issue metadata: internal dashboard token is unavailable");
840
+ return [];
841
+ }
842
+ try {
843
+ const response = await fetch(new URL("/api/issues?cycle=all&includeCompleted=true", dashboardOrigin), { headers: {
844
+ [INTERNAL_TOKEN_HEADER]: token,
845
+ origin: dashboardOrigin
846
+ } });
847
+ if (!response.ok) {
848
+ console.error(`[flywheel] Cannot load issue metadata from dashboard: HTTP ${response.status}`);
849
+ return [];
850
+ }
851
+ const body = await response.json();
852
+ if (!Array.isArray(body)) {
853
+ console.error("[flywheel] Cannot load issue metadata from dashboard: response was not an array");
854
+ return [];
855
+ }
856
+ return body;
857
+ } catch (error) {
858
+ console.error("[flywheel] Cannot load issue metadata from dashboard:", error);
859
+ return [];
860
+ }
861
+ }
862
+ async function flywheelRunConfigurationSection(options, runId) {
863
+ const configLines = [
864
+ options.harness ? `Harness: ${options.harness}` : void 0,
865
+ options.effort ? `Effort: ${options.effort}` : void 0,
866
+ options.minAgents ? `Min concurrent agents (target): ${options.minAgents}` : void 0,
867
+ options.maxAgents ? `Max concurrent agents (ceiling): ${options.maxAgents}` : void 0,
868
+ options.scope ? `Scope: ${options.scope}` : void 0,
869
+ typeof options.autoPickupBacklog === "boolean" ? `Auto-pickup backlog: ${options.autoPickupBacklog}` : void 0,
870
+ typeof options.requireUatBeforeMerge === "boolean" ? `Require UAT before merge: ${options.requireUatBeforeMerge}` : void 0
871
+ ].filter(Boolean).join("\n");
872
+ let sequenceSection = "";
873
+ const projectRoot = process.cwd();
874
+ const orderBookIssues = await activeOrderBookIssues(projectRoot, runId);
875
+ if (options.autoPickupBacklog || orderBookIssues.size > 0) {
876
+ const seqPath = join(projectRoot, ".pan", "backlog", "sequence.md");
877
+ if (existsSync(seqPath)) try {
878
+ const parsed = parseSequenceMd(readFileSync(seqPath, "utf-8"));
879
+ if (parsed.ok) {
880
+ const getIssueRows = async () => fetchIssueRowsFromDashboard();
881
+ const issueRowMap = new Map((await getIssueRows()).map((i) => [i.ref ?? i.identifier ?? "", i]));
882
+ const issueLabelsLookup = (issueId) => issueRowMap.get(issueId)?.labels ?? [];
883
+ const AUTHORIZED_AUTHORS = new Set(["eltmon", "panopticon-agent[bot]"]);
884
+ const isAuthorizedIssue = (issueId) => {
885
+ const row = issueRowMap.get(issueId);
886
+ if (!row) return false;
887
+ if (row.author && AUTHORIZED_AUTHORS.has(row.author)) return true;
888
+ return (typeof row.assignee === "string" ? row.assignee : row.assignee?.name) === "eltmon";
889
+ };
890
+ const specsDir = join(projectRoot, ".pan", "specs");
891
+ const issuesWithSpecs = /* @__PURE__ */ new Set();
892
+ const declaredFootprints = [];
893
+ if (existsSync(specsDir)) for (const f of readdirSync(specsDir)) {
894
+ const match = /^[\d-]+-([A-Z]+-\d+)-/i.exec(f);
895
+ if (!match) continue;
896
+ const issueId = match[1].toUpperCase();
897
+ issuesWithSpecs.add(issueId);
898
+ try {
899
+ const doc = JSON.parse(readFileSync(join(specsDir, f), "utf-8"));
900
+ declaredFootprints.push(declaredIssueFootprint(issueId, doc));
901
+ } catch {}
902
+ }
903
+ const projectConfig = findProjectByPathSync(projectRoot);
904
+ const predictedConflictSignals = computePredictedConflictSignals(declaredFootprints, { hotspots: getProjectSwarmHotspots(projectConfig) });
905
+ const isReadyOrHasPrd = (issueId) => {
906
+ const id = issueId.toUpperCase();
907
+ if (issuesWithSpecs.has(id)) return true;
908
+ return existsSync(join(projectRoot, ".pan", "drafts", `${id}.md`));
909
+ };
910
+ const membershipAvailable = Boolean(projectConfig?.github_repo);
911
+ const memberships = projectConfig?.github_repo ? (await gatherProjectLensSignals(projectConfig)).map(resolvePipelineMembership) : [];
912
+ const isInPipeline = (issueId) => membershipAvailable ? isIssueInResolvedPipeline(issueId, memberships) : true;
913
+ const top10 = parsed.doc.nodes.slice(0, 10).map((n) => ` #${n.rank} ${n.issue}: ${n.why.slice(0, 100)} [gate:${n.gate}]`);
914
+ const nextPick = pickFromSequence(parsed.doc.nodes, {
915
+ issueLabels: issueLabelsLookup,
916
+ isAuthorizedIssue,
917
+ isReadyOrHasPrd,
918
+ isInPipeline,
919
+ requireReady: true,
920
+ autoPickupBacklog: options.autoPickupBacklog,
921
+ activeBookMembership: orderBookIssues,
922
+ predictedConflictSignals
923
+ });
924
+ let nextLine;
925
+ let pickInstruction;
926
+ if (!membershipAvailable) {
927
+ nextLine = "MEMBERSHIP UNAVAILABLE: project has no GitHub repository; auto-pickup is disabled";
928
+ pickInstruction = "\n\nIMPORTANT: Canonical pipeline membership is unavailable for this project. Do NOT auto-start backlog work; surface the missing github_repo configuration to the operator.";
929
+ } else if (!nextPick) {
930
+ nextLine = "No eligible issue found in sequence — fall back to normal priority";
931
+ pickInstruction = "";
932
+ } else if (nextPick.planning === "interactive") {
933
+ nextLine = `NEEDS OPERATOR ACTION: ${nextPick.issueId} (rank ${nextPick.rank}) has planning=interactive — do NOT auto-start; operator must run 'pan plan ${nextPick.issueId}'`;
934
+ pickInstruction = `\n\nIMPORTANT: auto_pickup_backlog=true. The top-ranked issue requires interactive planning and MUST NOT be auto-started. Surface it to the operator for manual 'pan plan' invocation instead of auto-picking it.`;
935
+ } else {
936
+ const conflictSuffix = typeof nextPick.predictedConflictCount === "number" ? `, predictedConflicts=${nextPick.predictedConflictCount}${nextPick.predictedConflictsWith?.length ? ` with ${nextPick.predictedConflictsWith.join(", ")}` : ""}` : "";
937
+ nextLine = `MUST start next: ${nextPick.issueId} (rank ${nextPick.rank}, planning=${nextPick.planning}${conflictSuffix})`;
938
+ pickInstruction = `\n\nIMPORTANT: auto_pickup_backlog=true. You MUST pick the "MUST start next" issue above as your next startup target. Do NOT apply your own P0-P3/oldest-first ranking while a sequence is available.`;
939
+ }
940
+ sequenceSection = `\n\nBacklog sequence (${parsed.doc.nodes.length} issues ranked):\n${top10.join("\n")}\n${nextLine}${pickInstruction}`;
941
+ }
942
+ } catch {}
943
+ }
944
+ return (configLines ? `\n\nRun configuration:\n${configLines}` : "") + sequenceSection;
945
+ }
946
+ async function defaultFlywheelPrompt(runId, options, briefContent) {
947
+ return `FLYWHEEL ORCHESTRATOR TASK for ${runId}:
948
+
949
+ Run the Fix-All Flywheel loop. Keep status snapshots current, coordinate Overdeck roles through the normal pipeline surfaces, respect the configured run scope and agent cap, and wait for explicit lifecycle instructions when the run is paused or complete.${await flywheelRunConfigurationSection(options, runId)}${options.briefPath ? `\n\nBrief path: ${options.briefPath}\n\n${briefContent ?? ""}` : ""}`;
950
+ }
951
+ function getLocalFlywheelRunDir(runId) {
952
+ return join(process.env.OVERDECK_HOME ?? join(homedir(), ".overdeck"), "flywheel", "runs", runId);
953
+ }
954
+ async function saveResumeSessionId(runId, sessionId) {
955
+ const runDir = getLocalFlywheelRunDir(runId);
956
+ await mkdir(runDir, { recursive: true });
957
+ await writeFile(join(runDir, "resume-session.json"), JSON.stringify({
958
+ sessionId,
959
+ pausedAt: (/* @__PURE__ */ new Date()).toISOString()
960
+ }), "utf-8");
961
+ }
962
+ async function loadResumeSessionId(runId) {
963
+ try {
964
+ const raw = await readFile(join(getLocalFlywheelRunDir(runId), "resume-session.json"), "utf-8");
965
+ const parsed = JSON.parse(raw);
966
+ return typeof parsed.sessionId === "string" ? parsed.sessionId : null;
967
+ } catch {
968
+ return null;
969
+ }
970
+ }
971
+ function isFlywheelDevcontainerRuntime(env = process.env) {
972
+ const disabledDeacon = env.OVERDECK_DISABLE_DEACON?.toLowerCase();
973
+ if (disabledDeacon === "1" || disabledDeacon === "true") return true;
974
+ const hostname = env.HOSTNAME?.toLowerCase() ?? "";
975
+ return hostname.includes("devcontainer") || hostname.startsWith("api-feature-") || hostname.startsWith("workspace-");
976
+ }
977
+ /**
978
+ * Resume prompt. PAN-2006 FR-8: re-attach the standing brief on resume so its
979
+ * directives (pipeline-unblock override, never-block, red-main-first) survive a
980
+ * resume + context compaction — the pre-PAN-2006 resume prompt only pointed at
981
+ * FLYWHEEL-STATE.md and a long-running orchestrator could drift off-brief.
982
+ */
983
+ function buildFlywheelResumePrompt(configSection, briefContent) {
984
+ return `FLYWHEEL RESUME: You were paused by the operator. Resume the tick loop from your prior state. Check \`docs/FLYWHEEL-STATE.md\` and the latest status snapshot for context.${configSection}${briefContent ? `\n\n--- Standing brief (re-read it — it governs pickup, unblocking, and never-block) ---\n\n${briefContent}` : ""}`;
985
+ }
986
+ function withOrderBookBriefOverlay(briefContent, overlayPath, overlayContent) {
987
+ if (!overlayContent) return briefContent;
988
+ const standard = briefContent?.trimEnd() ?? "";
989
+ const overlay = `--- Order-book brief overlay${overlayPath ? `: ${overlayPath}` : ""} ---\n\n${overlayContent.trim()}`;
990
+ return standard ? `${standard}\n\n${overlay}` : overlay;
991
+ }
992
+ async function spawnFlywheelAgent(runId, options = {}) {
993
+ const workspace = options.workspace ?? process.cwd();
994
+ const briefPath = options.briefPath ?? join(workspace, "docs", "flywheel-brief.md");
995
+ let briefOverlayPath = options.briefOverlayPath;
996
+ let briefOverlayContent = options.briefOverlayContent;
997
+ if (briefOverlayPath && briefOverlayContent === void 0) {
998
+ const resolvedOverlay = await requireFlywheelBrief(workspace, briefOverlayPath);
999
+ briefOverlayPath = resolvedOverlay.displayPath;
1000
+ briefOverlayContent = await readFile(resolvedOverlay.absolutePath, "utf8");
1001
+ }
1002
+ const briefContent = withOrderBookBriefOverlay(await readFile(briefPath, "utf8").catch(() => void 0), briefOverlayPath, briefOverlayContent);
1003
+ return spawnRun(runId, "flywheel", {
1004
+ agentId: FLYWHEEL_ORCHESTRATOR_AGENT_ID,
1005
+ workspace,
1006
+ prompt: options.resumeSessionId ? buildFlywheelResumePrompt(await flywheelRunConfigurationSection(options, runId), briefContent) : options.prompt ?? await defaultFlywheelPrompt(runId, {
1007
+ ...options,
1008
+ briefPath
1009
+ }, briefContent),
1010
+ model: options.model,
1011
+ harness: options.harness,
1012
+ effort: options.effort,
1013
+ allowHost: true,
1014
+ registerConversation: true,
1015
+ resumeSessionId: options.resumeSessionId,
1016
+ flywheelRunId: runId
1017
+ });
1018
+ }
1019
+ function withFlywheelAutonomyOptions(options) {
1020
+ return {
1021
+ ...options,
1022
+ autoPickupBacklog: options.autoPickupBacklog ?? isFlywheelAutoPickupBacklog(),
1023
+ requireUatBeforeMerge: options.requireUatBeforeMerge ?? isFlywheelRequireUatBeforeMerge()
1024
+ };
1025
+ }
1026
+ async function spawnFlywheel(options = {}) {
1027
+ if (isFlywheelDevcontainerRuntime(options.env)) throw new Error("Refusing to spawn flywheel-orchestrator inside a workspace devcontainer");
1028
+ const activeRunId = await resolveLiveFlywheelRunId();
1029
+ if (activeRunId) throw new Error(`Flywheel run ${activeRunId} is already active; pause, resume, or report it before starting another run`);
1030
+ const runId = options.runId ? parseRunId(options.runId) : defaultFlywheelRunId();
1031
+ const agent = await spawnFlywheelAgent(runId, withFlywheelAutonomyOptions(options));
1032
+ setFlywheelActiveRunId(runId);
1033
+ setFlywheelGloballyPaused(false);
1034
+ try {
1035
+ const workspace = options.workspace ?? process.cwd();
1036
+ const seqPath = join(workspace, ".pan", "backlog", "sequence.md");
1037
+ if (existsSync(seqPath)) {
1038
+ const parsed = parseSequenceMd(readFileSync(seqPath, "utf-8"));
1039
+ if (parsed.ok) saveRunCohort(runId, computeCohort(parsed.doc.nodes, buildClassifyLookups(workspace), options.maxAgents ?? 5, options.autoPickupBacklog ?? isFlywheelAutoPickupBacklog(), await activeOrderBookIssues(workspace, runId)));
1040
+ }
1041
+ } catch {}
1042
+ return agent;
1043
+ }
1044
+ async function abortSpawnedFlywheel(runId) {
1045
+ try {
1046
+ await Effect.runPromise(stopAgent(FLYWHEEL_ORCHESTRATOR_AGENT_ID));
1047
+ } finally {
1048
+ await abortFlywheelRun(runId);
1049
+ }
1050
+ }
1051
+ async function pauseFlywheel() {
1052
+ const activeRunId = getFlywheelActiveRunId();
1053
+ if (activeRunId) try {
1054
+ const sessionId = (await readFile(join(getAgentDir(FLYWHEEL_ORCHESTRATOR_AGENT_ID), "session.id"), "utf-8")).trim();
1055
+ if (sessionId) await saveResumeSessionId(activeRunId, sessionId);
1056
+ } catch {}
1057
+ setFlywheelGloballyPaused(true);
1058
+ await Effect.runPromise(stopAgent(FLYWHEEL_ORCHESTRATOR_AGENT_ID));
1059
+ return { activeRunId };
1060
+ }
1061
+ async function resumeFlywheel(options = {}) {
1062
+ if (isFlywheelDevcontainerRuntime(options.env)) throw new Error("Refusing to resume flywheel-orchestrator inside a workspace devcontainer");
1063
+ const activeRunId = getFlywheelActiveRunId();
1064
+ if (!activeRunId) throw new Error("No active flywheel run to resume");
1065
+ const runId = parseRunId(activeRunId);
1066
+ const resumeSessionId = options.resumeSessionId ?? await loadResumeSessionId(runId) ?? void 0;
1067
+ const launch = await readFlywheelLaunchMetadata(runId);
1068
+ const agent = await spawnFlywheelAgent(runId, withFlywheelAutonomyOptions({
1069
+ ...options,
1070
+ workspace: options.workspace ?? launch?.workspace,
1071
+ briefPath: options.briefPath ?? launch?.briefPath,
1072
+ briefOverlayPath: options.briefOverlayPath ?? launch?.briefOverlayPath,
1073
+ resumeSessionId
1074
+ }));
1075
+ setFlywheelGloballyPaused(false);
1076
+ return {
1077
+ activeRunId,
1078
+ agent
1079
+ };
1080
+ }
1081
+ //#endregion
1082
+ export { advanceQueue as A, getBook as B, readCurrentLatestFlywheelStatus as C, writeFlywheelLaunchMetadata as D, subscribeLatestFlywheelStatus as E, setItemRequirements as F, liveOrderIssueLookup as H, setSettings as I, setStatus as L, moveItem as M, removeItem as N, writeLatestFlywheelStatus as O, renameBook as P, backlogCandidates as R, nextFlywheelRunId as S, resolveLiveFlywheelRunId as T, listBooks as V, clearFlywheelGate as _, isFlywheelDevcontainerRuntime as a, isFlywheelRunId as b, pauseFlywheel as c, spawnFlywheel as d, spawnFlywheelAgent as f, abortFlywheelRun as g, resolvePrimaryWorktreeRoot as h, buildFlywheelResumePrompt as i, createBook as j, addItems as k, resumeFlywheel as l, requireFlywheelBrief as m, abortSpawnedFlywheel as n, isIssueInResolvedPipeline as o, buildClassifyLookups as p, activeOrderBookIssues as r, loadResumeSessionId as s, FLYWHEEL_ORCHESTRATOR_AGENT_ID as t, saveResumeSessionId as u, getFlywheelRunDetail as v, readFlywheelLaunchMetadata as w, listFlywheelRuns as x, getFlywheelRunDir as y, computeBookProgress as z };
1083
+
1084
+ //# sourceMappingURL=flywheel-DHrgCphM.js.map