@overdeck/core 0.50.3 → 0.50.4
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.
- package/dist/agents-DNMRPC8n.js.map +1 -1
- package/dist/{build-info-BJuEVWOh.js → build-info-ioRdOmqT.js} +3 -3
- package/dist/{build-info-BJuEVWOh.js.map → build-info-ioRdOmqT.js.map} +1 -1
- package/dist/build-info-kMMitDOP.js +2 -0
- package/dist/cli/index.js +4 -4
- package/dist/conversation-compaction-GFfO5UZL.js.map +1 -1
- package/dist/dashboard/{advancing-selfheal-Bq8V0QUa.js → advancing-selfheal-Dp5_Gai3.js} +3 -3
- package/dist/dashboard/{advancing-selfheal-Bq8V0QUa.js.map → advancing-selfheal-Dp5_Gai3.js.map} +1 -1
- package/dist/dashboard/{agent-gc-Coz8zQt_.js → agent-gc-JzoSs5Pi.js} +3 -3
- package/dist/dashboard/{agent-gc-Coz8zQt_.js.map → agent-gc-JzoSs5Pi.js.map} +1 -1
- package/dist/dashboard/{agent-idle-CAwB-K6M.js → agent-idle-D-Qy5BN_.js} +2 -2
- package/dist/dashboard/{agent-idle-CAwB-K6M.js.map → agent-idle-D-Qy5BN_.js.map} +1 -1
- package/dist/dashboard/{agent-state-Ci6PhjOE.js → agent-state-B196fj1h.js} +38 -16
- package/dist/dashboard/agent-state-B196fj1h.js.map +1 -0
- package/dist/dashboard/{agent-state-CbUEwUEQ.js → agent-state-IpWnw8lv.js} +1 -1
- package/dist/dashboard/{agent-state-service-D6IVrX3B.js → agent-state-service-CCo5-9DR.js} +3 -3
- package/dist/dashboard/{agent-state-service-D6IVrX3B.js.map → agent-state-service-CCo5-9DR.js.map} +1 -1
- package/dist/dashboard/{agent-state-service-DcN1j6eK.js → agent-state-service-D_F3VZ23.js} +1 -1
- package/dist/dashboard/{agents-BVvL4o_4.js → agents-CkGhnAmu.js} +1 -1
- package/dist/dashboard/{backlog-auto-trigger-BuSBqG2V.js → backlog-auto-trigger-B5Z2zBtC.js} +2 -2
- package/dist/dashboard/{backlog-auto-trigger-BuSBqG2V.js.map → backlog-auto-trigger-B5Z2zBtC.js.map} +1 -1
- package/dist/dashboard/build-info-BTjOB0Xr.js +2 -0
- package/dist/dashboard/{build-info-Cj3Y0K87.js → build-info-D0EJNj6C.js} +3 -3
- package/dist/dashboard/{build-info-Cj3Y0K87.js.map → build-info-D0EJNj6C.js.map} +1 -1
- package/dist/dashboard/cli-CIznFrcE.js +2 -0
- package/dist/dashboard/{cli-DIhQieif.js → cli-DCbVrSsg.js} +2 -2
- package/dist/dashboard/{cli-DIhQieif.js.map → cli-DCbVrSsg.js.map} +1 -1
- package/dist/dashboard/{close-issue-CRlmrE5g.js → close-issue-Bmu9aOIx.js} +2 -2
- package/dist/dashboard/{close-issue-CRlmrE5g.js.map → close-issue-Bmu9aOIx.js.map} +1 -1
- package/dist/dashboard/{closed-issue-reaper-DrHyYgJR.js → closed-issue-reaper-COxfTtLz.js} +5 -5
- package/dist/dashboard/{closed-issue-reaper-DrHyYgJR.js.map → closed-issue-reaper-COxfTtLz.js.map} +1 -1
- package/dist/dashboard/{closed-issue-reaper-DWlw2EtL.js → closed-issue-reaper-DwMwG_Pz.js} +1 -1
- package/dist/dashboard/{compaction-continuation-DhYgsXmF.js → compaction-continuation-Bqc212Zm.js} +2 -2
- package/dist/dashboard/{compaction-continuation-DhYgsXmF.js.map → compaction-continuation-Bqc212Zm.js.map} +1 -1
- package/dist/dashboard/{conflict-gate-vczgdVTa.js → conflict-gate-9mPVg7-5.js} +1 -1
- package/dist/dashboard/{conflict-gate-Bt-lLgYf.js → conflict-gate-CGQTcR0I.js} +3 -3
- package/dist/dashboard/{conflict-gate-Bt-lLgYf.js.map → conflict-gate-CGQTcR0I.js.map} +1 -1
- package/dist/dashboard/{conversation-compaction-CsdCbcQB.js → conversation-compaction-C7P6V8Iw.js} +5 -5
- package/dist/dashboard/{conversation-compaction-CsdCbcQB.js.map → conversation-compaction-C7P6V8Iw.js.map} +1 -1
- package/dist/dashboard/{conversation-compaction-D0zgWM1f.js → conversation-compaction-Cck5oi-V.js} +1 -1
- package/dist/dashboard/{conversation-service-6LaymUV-.js → conversation-service-CsOpwI9Y.js} +37 -5
- package/dist/dashboard/{conversation-service-6LaymUV-.js.map → conversation-service-CsOpwI9Y.js.map} +1 -1
- package/dist/dashboard/conversation-service-plOFkoMo.js +3 -0
- package/dist/dashboard/dashboard-db-worker.js +1 -1
- package/dist/dashboard/{deacon-CU47dU7U.js → deacon-B8oMMIgN.js} +62 -62
- package/dist/dashboard/{deacon-CU47dU7U.js.map → deacon-B8oMMIgN.js.map} +1 -1
- package/dist/dashboard/{deacon-DYsOa_ss.js → deacon-b7J57Svt.js} +2 -2
- package/dist/dashboard/{deacon-pending-lifecycle-ijGX8wLb.js → deacon-pending-lifecycle-3NIJ7ew5.js} +2 -2
- package/dist/dashboard/{deacon-pending-lifecycle-ijGX8wLb.js.map → deacon-pending-lifecycle-3NIJ7ew5.js.map} +1 -1
- package/dist/dashboard/deacon.js +5 -5
- package/dist/dashboard/{delivery-DMYxIE0J.js → delivery-lnI-gQKo.js} +1 -1
- package/dist/dashboard/{deploy-patrol-C4eXco1S.js → deploy-patrol-u3v2krg9.js} +2 -2
- package/dist/dashboard/{deploy-patrol-C4eXco1S.js.map → deploy-patrol-u3v2krg9.js.map} +1 -1
- package/dist/dashboard/{feedback-stuck-retirement-Dd5XNrMr.js → feedback-stuck-retirement-CoFNqjCc.js} +2 -2
- package/dist/dashboard/{feedback-stuck-retirement-Dd5XNrMr.js.map → feedback-stuck-retirement-CoFNqjCc.js.map} +1 -1
- package/dist/dashboard/{feedback-target-BzdJ2wIR.js → feedback-target-BBCh3RRq.js} +1 -1
- package/dist/dashboard/{feedback-target-BcsA_GRV.js → feedback-target-CeCq6EhW.js} +5 -5
- package/dist/dashboard/{feedback-target-BcsA_GRV.js.map → feedback-target-CeCq6EhW.js.map} +1 -1
- package/dist/dashboard/{flywheel-Is3w2lcT.js → flywheel-DKldI63J.js} +7 -7
- package/dist/dashboard/{flywheel-Is3w2lcT.js.map → flywheel-DKldI63J.js.map} +1 -1
- package/dist/dashboard/{flywheel-D0guNqkh.js → flywheel-DpRPLErh.js} +7 -7
- package/dist/dashboard/{flywheel-D0guNqkh.js.map → flywheel-DpRPLErh.js.map} +1 -1
- package/dist/dashboard/{flywheel-B34cdfbd.js → flywheel-jeZFYvm-.js} +1 -1
- package/dist/dashboard/{flywheel-merge-order-6HiPR2WG.js → flywheel-merge-order-0OnoosaO.js} +1 -1
- package/dist/dashboard/{flywheel-merge-order-BsNPMu0S.js → flywheel-merge-order-PG5op4j7.js} +2 -2
- package/dist/dashboard/{flywheel-merge-order-BsNPMu0S.js.map → flywheel-merge-order-PG5op4j7.js.map} +1 -1
- package/dist/dashboard/{harness-resolve-CzTFVZ5l.js → harness-resolve-C0HWj3H9.js} +2 -2
- package/dist/dashboard/{harness-resolve-CzTFVZ5l.js.map → harness-resolve-C0HWj3H9.js.map} +1 -1
- package/dist/dashboard/{identity-Dc7rQLln.js → identity-Cot1Hg4G.js} +2 -2
- package/dist/dashboard/{identity-Dc7rQLln.js.map → identity-Cot1Hg4G.js.map} +1 -1
- package/dist/dashboard/{inspect-agent-CP7Bu47O.js → inspect-agent-BDmLWbGx.js} +3 -3
- package/dist/dashboard/{inspect-agent-CP7Bu47O.js.map → inspect-agent-BDmLWbGx.js.map} +1 -1
- package/dist/dashboard/inspect-agent-BcOkA-hC.js +2 -0
- package/dist/dashboard/{issue-lifecycle-BPbczKyy.js → issue-lifecycle-1B_v8Rf5.js} +6 -6
- package/dist/dashboard/{issue-lifecycle-BPbczKyy.js.map → issue-lifecycle-1B_v8Rf5.js.map} +1 -1
- package/dist/dashboard/{issue-lifecycle-FaugTi39.js → issue-lifecycle-CIrfbIbj.js} +1 -1
- package/dist/dashboard/{issue-service-singleton-Dsad9NTt.js → issue-service-singleton-BVwPzjwF.js} +1 -1
- package/dist/dashboard/{issue-service-singleton-BrZQJLRI.js → issue-service-singleton-KcRrOiFD.js} +2 -2
- package/dist/dashboard/{issue-service-singleton-BrZQJLRI.js.map → issue-service-singleton-KcRrOiFD.js.map} +1 -1
- package/dist/dashboard/{jsonl-resolver-DQEe0DHM.js → jsonl-resolver-jxbif7MD.js} +3 -3
- package/dist/dashboard/{jsonl-resolver-DQEe0DHM.js.map → jsonl-resolver-jxbif7MD.js.map} +1 -1
- package/dist/dashboard/{kimi-code-Cx5YUJpS.js → kimi-code-BZh3NgcN.js} +1 -1
- package/dist/dashboard/{lifecycle-DZFHmpGI.js → lifecycle-CvcZ4_fA.js} +4 -4
- package/dist/dashboard/{lifecycle-DZFHmpGI.js.map → lifecycle-CvcZ4_fA.js.map} +1 -1
- package/dist/dashboard/{linear-mcp-auth-DylPJABZ.js → linear-mcp-auth-CZoj_-d7.js} +1 -1
- package/dist/dashboard/{linear-mcp-auth-BFlpMvWh.js → linear-mcp-auth-Dx74yCAY.js} +2 -2
- package/dist/dashboard/{linear-mcp-auth-BFlpMvWh.js.map → linear-mcp-auth-Dx74yCAY.js.map} +1 -1
- package/dist/dashboard/{memory-governor-B7uDWRo9.js → memory-governor-Bv3LAqk3.js} +5 -5
- package/dist/dashboard/{memory-governor-B7uDWRo9.js.map → memory-governor-Bv3LAqk3.js.map} +1 -1
- package/dist/dashboard/{merge-agent-ddEcZDZD.js → merge-agent-1zVLl6k_.js} +1 -1
- package/dist/dashboard/{merge-agent-ttRY053V.js → merge-agent-8zrQu48t.js} +8 -8
- package/dist/dashboard/{merge-agent-ttRY053V.js.map → merge-agent-8zrQu48t.js.map} +1 -1
- package/dist/dashboard/merge-ops-CFJaMPLu.js +2 -0
- package/dist/dashboard/{merge-train-f_un38UJ.js → merge-train-BYH_cF7G.js} +2 -2
- package/dist/dashboard/{merge-train-f_un38UJ.js.map → merge-train-BYH_cF7G.js.map} +1 -1
- package/dist/dashboard/{merge-train-deps-GPlHOjK6.js → merge-train-deps-BTfXM5AR.js} +2 -2
- package/dist/dashboard/{merge-train-deps-GPlHOjK6.js.map → merge-train-deps-BTfXM5AR.js.map} +1 -1
- package/dist/dashboard/{messaging-BasbftDu.js → messaging-Bk6vGsMw.js} +1 -1
- package/dist/dashboard/{orphan-proposed-reconciler-DFHdQSEg.js → orphan-proposed-reconciler-B898fk26.js} +6 -6
- package/dist/dashboard/{orphan-proposed-reconciler-DFHdQSEg.js.map → orphan-proposed-reconciler-B898fk26.js.map} +1 -1
- package/dist/dashboard/{orphan-proposed-reconciler-DzAxrM99.js → orphan-proposed-reconciler-Bx_aWS4B.js} +1 -1
- package/dist/dashboard/{parked-residue-DMtbxJml.js → parked-residue-q2kzrYSm.js} +9 -9
- package/dist/dashboard/{parked-residue-DMtbxJml.js.map → parked-residue-q2kzrYSm.js.map} +1 -1
- package/dist/dashboard/{post-merge-lifecycle-worker-jzN2g_EY.js → post-merge-lifecycle-worker-Cl7-uf4g.js} +2 -2
- package/dist/dashboard/{post-merge-lifecycle-worker-jzN2g_EY.js.map → post-merge-lifecycle-worker-Cl7-uf4g.js.map} +1 -1
- package/dist/dashboard/{project-resource-refresh-queue-cqOeJ0fB.js → project-resource-refresh-queue-O_dRfPHn.js} +1 -1
- package/dist/dashboard/{project-resource-refresh-queue-DebwjPPA.js → project-resource-refresh-queue-se3T9IYP.js} +4 -4
- package/dist/dashboard/{project-resource-refresh-queue-DebwjPPA.js.map → project-resource-refresh-queue-se3T9IYP.js.map} +1 -1
- package/dist/dashboard/{reconstruct-cache-Bb2Jg2DZ.js → reconstruct-cache-XpWC9L0F.js} +2 -2
- package/dist/dashboard/{reconstruct-cache-Bb2Jg2DZ.js.map → reconstruct-cache-XpWC9L0F.js.map} +1 -1
- package/dist/dashboard/{release-engine-78iCajIc.js → release-engine-BuzxOamf.js} +2 -2
- package/dist/dashboard/{release-engine-78iCajIc.js.map → release-engine-BuzxOamf.js.map} +1 -1
- package/dist/dashboard/{remote-completion-D5wzZCte.js → remote-completion-BCZgeKPS.js} +3 -3
- package/dist/dashboard/{remote-completion-D5wzZCte.js.map → remote-completion-BCZgeKPS.js.map} +1 -1
- package/dist/dashboard/{resolver-BGZh3lXA.js → resolver-BeNrqNou.js} +5 -5
- package/dist/dashboard/{resolver-BGZh3lXA.js.map → resolver-BeNrqNou.js.map} +1 -1
- package/dist/dashboard/{resource-pressure-patrol-Bg23rPV-.js → resource-pressure-patrol-Ccg_aCgO.js} +3 -3
- package/dist/dashboard/{resource-pressure-patrol-Bg23rPV-.js.map → resource-pressure-patrol-Ccg_aCgO.js.map} +1 -1
- package/dist/dashboard/{resume-BKyB4hA1.js → resume-KGCrn0DV.js} +1 -1
- package/dist/dashboard/{review-agent-ZdP-HmwY.js → review-agent-BmM6YMZW.js} +1 -1
- package/dist/dashboard/{review-agent-DHs-JngN.js → review-agent-DRWVU8fP.js} +13 -13
- package/dist/dashboard/{review-agent-DHs-JngN.js.map → review-agent-DRWVU8fP.js.map} +1 -1
- package/dist/dashboard/{review-convoy-liveness-BTMvU4CA.js → review-convoy-liveness-EvCDv8Q_.js} +3 -3
- package/dist/dashboard/{review-convoy-liveness-BTMvU4CA.js.map → review-convoy-liveness-EvCDv8Q_.js.map} +1 -1
- package/dist/dashboard/{review-run-recovery-BYalQzbh.js → review-run-recovery-Ctm48Snt.js} +1 -1
- package/dist/dashboard/{review-run-recovery-BvVG3oUr.js → review-run-recovery-DNDI58cM.js} +2 -2
- package/dist/dashboard/{review-run-recovery-BvVG3oUr.js.map → review-run-recovery-DNDI58cM.js.map} +1 -1
- package/dist/dashboard/{review-status-DXTFzCmR.js → review-status-FnlvQuPI.js} +1 -1
- package/dist/dashboard/{review-status-emit-C9YW6SQL.js → review-status-emit-CeMS31DX.js} +2 -2
- package/dist/dashboard/{review-status-emit-C9YW6SQL.js.map → review-status-emit-CeMS31DX.js.map} +1 -1
- package/dist/dashboard/{review-status-BegAr86G.js → review-status-yY5qt7Rl.js} +5 -5
- package/dist/dashboard/{review-status-BegAr86G.js.map → review-status-yY5qt7Rl.js.map} +1 -1
- package/dist/dashboard/{review-verdict-feedback-qlVBi19-.js → review-verdict-feedback-BNgRj1e3.js} +4 -4
- package/dist/dashboard/{review-verdict-feedback-qlVBi19-.js.map → review-verdict-feedback-BNgRj1e3.js.map} +1 -1
- package/dist/dashboard/{review-verdict-feedback-Dp139Lmv.js → review-verdict-feedback-D39cuSV1.js} +1 -1
- package/dist/dashboard/{review-verdict-writer-CJr_Ob0Y.js → review-verdict-writer-DvFfKAn-.js} +2 -2
- package/dist/dashboard/{review-verdict-writer-CJr_Ob0Y.js.map → review-verdict-writer-DvFfKAn-.js.map} +1 -1
- package/dist/dashboard/{review-verdict-writer-BVco3WoI.js → review-verdict-writer-PcGBkvJ4.js} +1 -1
- package/dist/dashboard/{sequence-io-iljWlslY.js → sequence-io-DZyschsf.js} +2 -2
- package/dist/dashboard/{sequence-io-iljWlslY.js.map → sequence-io-DZyschsf.js.map} +1 -1
- package/dist/dashboard/{sequencer-agent-BGGVKxtw.js → sequencer-agent-BXDw5cNx.js} +5 -5
- package/dist/dashboard/{sequencer-agent-BGGVKxtw.js.map → sequencer-agent-BXDw5cNx.js.map} +1 -1
- package/dist/dashboard/server.js +79 -72
- package/dist/dashboard/server.js.map +1 -1
- package/dist/dashboard/{service-kzhN0DLg.js → service-DP50Omvn.js} +33 -33
- package/dist/dashboard/{service-kzhN0DLg.js.map → service-DP50Omvn.js.map} +1 -1
- package/dist/dashboard/{smart-compaction-owKHJDbL.js → smart-compaction-944GL8PN.js} +1 -1
- package/dist/dashboard/{smart-compaction-C96F2aFQ.js → smart-compaction-BzDfF6yb.js} +2 -2
- package/dist/dashboard/{smart-compaction-C96F2aFQ.js.map → smart-compaction-BzDfF6yb.js.map} +1 -1
- package/dist/dashboard/{spawn-planning-session-CiJdOHTD.js → spawn-planning-session-BcVnHJjm.js} +1 -1
- package/dist/dashboard/{spawn-planning-session-FmJa6PCS.js → spawn-planning-session-CH8IYli7.js} +3 -3
- package/dist/dashboard/{spawn-planning-session-FmJa6PCS.js.map → spawn-planning-session-CH8IYli7.js.map} +1 -1
- package/dist/dashboard/{specialist-context-_ootmzn2.js → specialist-context-DhDTXVht.js} +3 -3
- package/dist/dashboard/{specialist-context-_ootmzn2.js.map → specialist-context-DhDTXVht.js.map} +1 -1
- package/dist/dashboard/{specialist-logs-BbAX221-.js → specialist-logs-C1bcnZ-G.js} +2 -2
- package/dist/dashboard/{specialist-logs-BbAX221-.js.map → specialist-logs-C1bcnZ-G.js.map} +1 -1
- package/dist/dashboard/{specialists-COZoYaiz.js → specialists-BKmReEWT.js} +53 -53
- package/dist/dashboard/{specialists-COZoYaiz.js.map → specialists-BKmReEWT.js.map} +1 -1
- package/dist/dashboard/{specialists-RPLJnYc1.js → specialists-Bvrvt0br.js} +12 -12
- package/dist/dashboard/{specialists-RPLJnYc1.js.map → specialists-Bvrvt0br.js.map} +1 -1
- package/dist/dashboard/{specialists-DTAOVZpU.js → specialists-CD6GEKXk.js} +1 -1
- package/dist/dashboard/{specialists-D8sYZnPb.js → specialists-eFWpJRBc.js} +1 -1
- package/dist/dashboard/{stall-sweeper-9bRBZhrQ.js → stall-sweeper-D3fZvg7O.js} +3 -3
- package/dist/dashboard/{stall-sweeper-9bRBZhrQ.js.map → stall-sweeper-D3fZvg7O.js.map} +1 -1
- package/dist/dashboard/{state-migrate-J3tFJnbd.js → state-migrate-KZ2goscQ.js} +2 -2
- package/dist/dashboard/{state-migrate-J3tFJnbd.js.map → state-migrate-KZ2goscQ.js.map} +1 -1
- package/dist/dashboard/{stuck-remediation-BvTK_NYN.js → stuck-remediation-Cb2V1roj.js} +1 -1
- package/dist/dashboard/{stuck-remediation-4Rf_xMEb.js → stuck-remediation-CnoV0kcv.js} +5 -5
- package/dist/dashboard/{stuck-remediation-4Rf_xMEb.js.map → stuck-remediation-CnoV0kcv.js.map} +1 -1
- package/dist/dashboard/{summary-fork-PLcckTRE.js → summary-fork-CxuNBM0F.js} +2 -2
- package/dist/dashboard/{summary-fork-D-cylknJ.js → summary-fork-lC2vMXly.js} +4 -4
- package/dist/dashboard/{summary-fork-D-cylknJ.js.map → summary-fork-lC2vMXly.js.map} +1 -1
- package/dist/dashboard/{teardown-workspace-CTL16rnG.js → teardown-workspace-C-9murBw.js} +4 -4
- package/dist/dashboard/{teardown-workspace-CTL16rnG.js.map → teardown-workspace-C-9murBw.js.map} +1 -1
- package/dist/dashboard/{test-agent-queue-CMgYZiR_.js → test-agent-queue-YCBRzaAB.js} +3 -3
- package/dist/dashboard/{test-agent-queue-CMgYZiR_.js.map → test-agent-queue-YCBRzaAB.js.map} +1 -1
- package/dist/dashboard/{uat-failure-feedback-DS6W9X3I.js → uat-failure-feedback-B-1mL8Zp.js} +3 -3
- package/dist/dashboard/{uat-failure-feedback-DS6W9X3I.js.map → uat-failure-feedback-B-1mL8Zp.js.map} +1 -1
- package/dist/dashboard/{uat-promote-verification-CRsIHE_q.js → uat-promote-verification-BEBPcpPg.js} +2 -2
- package/dist/dashboard/{uat-promote-verification-CRsIHE_q.js.map → uat-promote-verification-BEBPcpPg.js.map} +1 -1
- package/dist/dashboard/{uat-train-BoA9r6_I.js → uat-train-BFo3OQUB.js} +1 -1
- package/dist/dashboard/{uat-train-Cd8CJeNe.js → uat-train-COgoJomz.js} +8 -8
- package/dist/dashboard/{uat-train-Cd8CJeNe.js.map → uat-train-COgoJomz.js.map} +1 -1
- package/dist/dashboard/{validate-BdmvTIym.js → validate-069_N1e2.js} +2 -2
- package/dist/dashboard/{validate-BdmvTIym.js.map → validate-069_N1e2.js.map} +1 -1
- package/dist/dashboard/{verification-runner-BO0K3xNA.js → verification-runner-CQnZyC5A.js} +1 -1
- package/dist/dashboard/{verification-runner-fEY1Qj-l.js → verification-runner-fy3wNrWn.js} +4 -4
- package/dist/dashboard/{verification-runner-fEY1Qj-l.js.map → verification-runner-fy3wNrWn.js.map} +1 -1
- package/dist/dashboard/workflows-Bk6Kt0ZQ.js +2 -0
- package/dist/dashboard/{workflows-CxVnygYU.js → workflows-N4QMkDzN.js} +10 -10
- package/dist/dashboard/{workflows-CxVnygYU.js.map → workflows-N4QMkDzN.js.map} +1 -1
- package/dist/dashboard/{workspaces-Cpz0xJWQ.js → workspaces-DmoyfHoU.js} +33 -33
- package/dist/dashboard/{workspaces-Cpz0xJWQ.js.map → workspaces-DmoyfHoU.js.map} +1 -1
- package/dist/{lifecycle-C6k0HWEO.js → lifecycle-DCFcjg7y.js} +1 -1
- package/dist/{lifecycle-D5oRpvvB.js → lifecycle-GkaHQJNK.js} +2 -2
- package/dist/{lifecycle-D5oRpvvB.js.map → lifecycle-GkaHQJNK.js.map} +1 -1
- package/dist/{merge-agent-Drufc7tU.js → merge-agent-CogNFasY.js} +2 -2
- package/dist/{merge-agent-Drufc7tU.js.map → merge-agent-CogNFasY.js.map} +1 -1
- package/dist/{merge-agent-CBOVY_eC.js → merge-agent-eteKQ9Rb.js} +1 -1
- package/package.json +1 -1
- package/dist/build-info-BgrwLUy6.js +0 -2
- package/dist/dashboard/agent-state-Ci6PhjOE.js.map +0 -1
- package/dist/dashboard/build-info-CYlxvZSQ.js +0 -2
- package/dist/dashboard/cli-ZAS502uC.js +0 -2
- package/dist/dashboard/conversation-service-Dlks_hSS.js +0 -3
- package/dist/dashboard/inspect-agent-DTuSg95i.js +0 -2
- package/dist/dashboard/merge-ops-Bgc-EScO.js +0 -2
- package/dist/dashboard/workflows-CgGNyl1z.js +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flywheel-Is3w2lcT.js","names":["OrderBookSchema","OrderBookIndexEntrySchema","decodeFlywheelRunId","setOrderBookStatus","getOrderBook"],"sources":["../../src/lib/orders/types.ts","../../src/lib/orders/io.ts","../../src/lib/orders/resolver.ts","../../src/lib/orders/writer.ts","../../src/dashboard/server/services/flywheel-run-state.ts","../../src/lib/flywheel-start.ts","../../src/lib/backlog/lookups.ts","../../src/lib/cloister/flywheel.ts"],"sourcesContent":["import { OrderBook as OrderBookSchema } from '@overdeck/contracts';\nimport { Schema } from 'effect';\n\nexport {\n OrderBook,\n OrderBookIndexEntry,\n OrderBookItem,\n OrderBookLane,\n OrderBookPosture,\n OrderBookSettings,\n OrderBookStatus,\n} from '@overdeck/contracts';\nexport type {\n OrderBook as OrderBookType,\n OrderBookIndexEntry as OrderBookIndexEntryType,\n OrderBookItem as OrderBookItemType,\n OrderBookLane as OrderBookLaneType,\n OrderBookPosture as OrderBookPostureType,\n OrderBookSettings as OrderBookSettingsType,\n OrderBookStatus as OrderBookStatusType,\n} from '@overdeck/contracts';\n\nexport type OrderBookParseError = { ok: false; error: string };\nexport type OrderBookParseResult =\n | { ok: true; book: typeof OrderBookSchema.Type }\n | OrderBookParseError;\n\nconst decodeOrderBook = Schema.decodeUnknownSync(OrderBookSchema);\n\nexport function parseOrderBookJson(value: unknown): OrderBookParseResult {\n try {\n return { ok: true, book: decodeOrderBook(value) };\n } catch (error) {\n return {\n ok: false,\n error: `Invalid order book: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n}\n\nexport interface OrderIssueState {\n issue: string;\n open: boolean;\n parked: boolean;\n}\n\nexport type OrderIssueLookup = (\n issueIds: readonly string[],\n) => ReadonlyMap<string, OrderIssueState>;\n\nexport interface OrderBookItemProgress {\n issue: string;\n lane: typeof import('@overdeck/contracts').OrderBookLane.Type;\n order: number;\n closed: boolean;\n parked: boolean;\n terminal: boolean;\n}\n\nexport interface OrderBookProgress {\n bookId: string;\n total: number;\n landed: number;\n items: readonly OrderBookItemProgress[];\n drained: boolean;\n}\n\nexport type OrderBookFindingCode =\n | 'empty-book'\n | 'issue-not-open'\n | 'duplicate-membership'\n | 'unresolved-prerequisite'\n | 'prerequisite-cycle'\n | 'missing-prd'\n | 'issue-store-unavailable';\n\nexport interface OrderBookFinding {\n code: OrderBookFindingCode;\n issue: string;\n message: string;\n}\n\nexport interface OrderBookValidationResult {\n blocks: OrderBookFinding[];\n warns: OrderBookFinding[];\n}\n","import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { OrderBookIndexEntry as OrderBookIndexEntrySchema } from '@overdeck/contracts';\nimport type { OrderBook, OrderBookIndexEntry, OrderBookItem } from '@overdeck/contracts';\nimport { Effect, Schema } from 'effect';\nimport { flushAutoCommits, queueAutoCommit } from '../pan-dir/auto-commit.js';\nimport { parseOrderBookJson } from './types.js';\n\nconst BOOK_ID_PATTERN = /^\\d{4}-\\d{2}-\\d{2}-[a-z0-9]+(?:-[a-z0-9]+)*$/;\nconst decodeIndex = Schema.decodeUnknownSync(Schema.Array(OrderBookIndexEntrySchema));\n\nexport function ordersDirectory(stateRoot: string): string {\n return join(stateRoot, 'orders');\n}\n\nexport function orderBookPath(stateRoot: string, bookId: string): string {\n if (!BOOK_ID_PATTERN.test(bookId)) {\n throw new Error(`Invalid order book id: ${bookId}`);\n }\n return join(ordersDirectory(stateRoot), `${bookId}.json`);\n}\n\nexport function orderBookIndexPath(stateRoot: string): string {\n return join(ordersDirectory(stateRoot), 'index.json');\n}\n\nexport function backlogSequencePath(stateRoot: string): string {\n return join(stateRoot, 'backlog', 'sequence.md');\n}\n\nexport async function readOrderBookAsync(stateRoot: string, bookId: string): Promise<OrderBook | null> {\n const path = orderBookPath(stateRoot, bookId);\n let value: unknown;\n try {\n value = JSON.parse(await readFile(path, 'utf8'));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return null;\n throw new Error(`Could not parse order book ${bookId}: ${error instanceof Error ? error.message : String(error)}`);\n }\n const parsed = parseOrderBookJson(value);\n if (!parsed.ok) throw new Error(`Could not parse order book ${bookId}: ${parsed.error}`);\n if (parsed.book.id !== bookId) throw new Error(`Order book ${bookId} contains mismatched id ${parsed.book.id}`);\n return parsed.book;\n}\n\nexport function readOrderBook(stateRoot: string, bookId: string): OrderBook | null {\n const path = orderBookPath(stateRoot, bookId);\n if (!existsSync(path)) return null;\n\n let value: unknown;\n try {\n value = JSON.parse(readFileSync(path, 'utf8'));\n } catch (error) {\n throw new Error(\n `Could not parse order book ${bookId}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n const parsed = parseOrderBookJson(value);\n if (!parsed.ok) throw new Error(`Could not parse order book ${bookId}: ${parsed.error}`);\n if (parsed.book.id !== bookId) {\n throw new Error(`Order book ${bookId} contains mismatched id ${parsed.book.id}`);\n }\n return parsed.book;\n}\n\nexport function readOrderBookIndex(stateRoot: string): readonly OrderBookIndexEntry[] {\n const path = orderBookIndexPath(stateRoot);\n if (!existsSync(path)) return [];\n\n try {\n return decodeIndex(JSON.parse(readFileSync(path, 'utf8')));\n } catch (error) {\n throw new Error(\n `Could not parse order book index: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nexport function listOrderBookIds(stateRoot: string): string[] {\n const indexed = readOrderBookIndex(stateRoot).map((entry) => entry.id);\n if (indexed.length > 0 || !existsSync(ordersDirectory(stateRoot))) return [...indexed];\n\n return readdirSync(ordersDirectory(stateRoot))\n .filter((name) => name !== 'index.json' && name.endsWith('.json'))\n .map((name) => name.slice(0, -'.json'.length))\n .filter((id) => BOOK_ID_PATTERN.test(id))\n .sort();\n}\n\nfunction preserveOperatorOwnedState(prior: OrderBook | null, next: OrderBook): OrderBook {\n if (!prior) return next;\n if (prior.id !== next.id) {\n throw new Error(`Order book id is immutable: ${prior.id} cannot become ${next.id}`);\n }\n\n const priorItems = new Map(prior.items.map((item) => [item.issue.toUpperCase(), item]));\n const items = next.items.map((item): OrderBookItem => {\n const existing = priorItems.get(item.issue.toUpperCase());\n if (!existing) return item;\n return {\n ...item,\n addedAt: existing.addedAt,\n addedBy: existing.addedBy,\n };\n });\n\n return { ...next, createdAt: prior.createdAt, items };\n}\n\nfunction indexEntry(book: OrderBook): OrderBookIndexEntry {\n return {\n id: book.id,\n name: book.name,\n status: book.status,\n runId: book.runId,\n updatedAt: book.updatedAt,\n };\n}\n\n/**\n * Physical state-store primitive used only by the orders writer. Domain callers\n * must mutate order books through writer.ts so the book and queue stay aligned.\n */\nexport async function writeOrderBookState(\n stateRoot: string,\n nextBook: OrderBook,\n queueOrder?: readonly string[],\n): Promise<OrderBook> {\n const prior = readOrderBook(stateRoot, nextBook.id);\n const book = preserveOperatorOwnedState(prior, nextBook);\n const bookPath = orderBookPath(stateRoot, book.id);\n const indexPath = orderBookIndexPath(stateRoot);\n const existingIndex = [...readOrderBookIndex(stateRoot)];\n const byId = new Map(existingIndex.map((entry) => [entry.id, entry]));\n byId.set(book.id, indexEntry(book));\n\n const requested = queueOrder ?? existingIndex.map((entry) => entry.id);\n const ids = [...requested];\n if (!ids.includes(book.id)) ids.push(book.id);\n for (const entry of existingIndex) {\n if (!ids.includes(entry.id)) ids.push(entry.id);\n }\n const index = ids.map((id) => byId.get(id)).filter((entry): entry is OrderBookIndexEntry => Boolean(entry));\n\n mkdirSync(dirname(bookPath), { recursive: true });\n writeFileSync(bookPath, `${JSON.stringify(book, null, 2)}\\n`, 'utf8');\n writeFileSync(indexPath, `${JSON.stringify(index, null, 2)}\\n`, 'utf8');\n\n queueAutoCommit({\n projectRoot: stateRoot,\n repoRoot: stateRoot,\n paths: [bookPath, indexPath],\n subject: `chore(state): update order book ${book.id}`,\n });\n const flushed = await Effect.runPromise(flushAutoCommits(stateRoot));\n if (flushed.errored || flushed.pushed === false) {\n throw new Error(`Failed to persist order book ${book.id}: ${flushed.reason ?? 'state commit failed'}`);\n }\n return book;\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { basename, dirname, join } from 'node:path';\nimport type { OrderBook } from '@overdeck/contracts';\nimport type { SequenceNode } from '../backlog/types.js';\nimport { parseSequenceMd } from '../backlog/sequence-io.js';\nimport { LEGACY_PARKED_LABELS, PARKED_LABEL } from '../backlog/pickup.js';\nimport { getOverdeckHome } from '../paths.js';\nimport { findProjectByPathSync, getProjectSync } from '../projects.js';\nimport { backlogSequencePath, listOrderBookIds, readOrderBook, readOrderBookAsync, readOrderBookIndex } from './io.js';\nimport type { OrderBookProgress, OrderIssueLookup, OrderIssueState } from './types.js';\n\nconst COMPLETE_STATUS = 'complete';\n\n/**\n * The issue prefix (e.g. \"PAN\") of the project that owns an orders state root,\n * or null when it cannot be determined. Migrated roots are\n * `<overdeckHome>/state/<projectKey>` — the basename is the projects.yaml key.\n * Legacy roots live inside the project checkout, where path containment is the\n * authoritative match (a checkout dir name can collide with another project's\n * yaml key, so the basename key lookup runs only for true migrated roots).\n */\nexport function issuePrefixForStateRoot(stateRoot: string): string | null {\n try {\n const byPath = findProjectByPathSync(stateRoot);\n if (byPath?.issue_prefix) return byPath.issue_prefix.toUpperCase();\n if (dirname(stateRoot) === join(getOverdeckHome(), 'state')) {\n const byKey = getProjectSync(basename(stateRoot));\n if (byKey?.issue_prefix) return byKey.issue_prefix.toUpperCase();\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Canonical form for an order-book issue reference: bare digits gain the\n * project prefix (\"2351\" → \"PAN-2351\"); anything else passes through\n * unchanged. Books written before the write door normalized on entry carry\n * bare numbers; every read-side consumer (validation, progress, membership,\n * dispatch) resolves them through this.\n */\nexport function normalizeOrderIssueId(stateRoot: string, issueId: string): string {\n if (!/^\\d+$/.test(issueId)) return issueId;\n const prefix = issuePrefixForStateRoot(stateRoot);\n return prefix ? `${prefix}-${issueId}` : issueId;\n}\n\nfunction normalizeBookIssues(stateRoot: string, book: OrderBook): OrderBook {\n const hasBare = book.items.some(\n (item) => /^\\d+$/.test(item.issue) || item.prereqs.some((prereq) => /^\\d+$/.test(prereq)),\n );\n if (!hasBare) return book;\n const prefix = issuePrefixForStateRoot(stateRoot);\n if (!prefix) return book;\n const expand = (id: string): string => (/^\\d+$/.test(id) ? `${prefix}-${id}` : id);\n return {\n ...book,\n items: book.items.map((item) => ({\n ...item,\n issue: expand(item.issue),\n prereqs: item.prereqs.map(expand),\n })),\n };\n}\n\ntype IssueServiceModule = typeof import('../../dashboard/server/services/issue-service-singleton.js');\nlet issueServiceModule: IssueServiceModule | null = null;\n\nfunction loadIssueServiceModuleSync(): IssueServiceModule {\n if (issueServiceModule) return issueServiceModule;\n // Lazy require avoids a static lib → dashboard server dependency.\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n issueServiceModule = require('../../dashboard/server/services/issue-service-singleton.js') as IssueServiceModule;\n return issueServiceModule;\n}\n\nasync function loadIssueServiceModule(): Promise<IssueServiceModule> {\n if (issueServiceModule) return issueServiceModule;\n issueServiceModule = await import('../../dashboard/server/services/issue-service-singleton.js');\n return issueServiceModule;\n}\n\nfunction labelNames(issue: Record<string, unknown>): string[] {\n const labels = Array.isArray(issue.labels) ? issue.labels : [];\n return labels\n .map((label) =>\n typeof label === 'string'\n ? label\n : typeof label === 'object' && label !== null && typeof (label as { name?: unknown }).name === 'string'\n ? (label as { name: string }).name\n : '',\n )\n .filter(Boolean)\n .map((label) => label.toLowerCase());\n}\n\nfunction issueIdentifier(issue: Record<string, unknown>): string {\n for (const key of ['identifier', 'issueId', 'id']) {\n const value = issue[key];\n if (typeof value === 'string' && value) return value.toUpperCase();\n }\n return '';\n}\n\nfunction issueIsClosed(issue: Record<string, unknown>): boolean {\n const values = [issue.canonicalStatus, issue.status, issue.state]\n .map((value) => (typeof value === 'string' ? value.toLowerCase().replace(/[ -]/g, '_') : ''));\n return values.some((value) =>\n ['done', 'completed', 'closed', 'canceled', 'cancelled'].includes(value),\n );\n}\n\nexport const liveOrderIssueLookup: OrderIssueLookup = (issueIds) => {\n const wanted = new Set(issueIds.map((id) => id.toUpperCase()));\n const result = new Map<string, OrderIssueState>();\n try {\n const { getSharedIssueService } = loadIssueServiceModuleSync();\n const issues = getSharedIssueService().getIssues({ cycle: 'all', includeCompleted: true }) as Array<Record<string, unknown>>;\n for (const issue of issues) {\n const id = issueIdentifier(issue);\n if (!wanted.has(id)) continue;\n const labels = labelNames(issue);\n const closed = issueIsClosed(issue);\n result.set(id, {\n issue: id,\n open: !closed,\n parked: labels.includes(PARKED_LABEL) || LEGACY_PARKED_LABELS.some((label) => labels.includes(label)),\n });\n }\n } catch {\n // A non-server caller receives missing issue state and validation blocks safely.\n }\n return result;\n};\n\nexport async function ensureOrderIssueStore(): Promise<void> {\n const { startSharedIssueService } = await loadIssueServiceModule();\n await startSharedIssueService({ skipPolling: true });\n}\n\nexport function orderIssueStoreStatus(): { started: boolean; issueCount: number } {\n try {\n const { getSharedIssueService, isSharedIssueServiceStarted } = loadIssueServiceModuleSync();\n const started = isSharedIssueServiceStarted();\n const issueCount = getSharedIssueService().getIssues({ cycle: 'all', includeCompleted: true }).length as number;\n return { started, issueCount };\n } catch {\n return { started: false, issueCount: 0 };\n }\n}\n\n/** The sole order-book read door. */\nexport function listBooks(stateRoot: string): OrderBook[] {\n return listOrderBookIds(stateRoot).map((id) => {\n const book = readOrderBook(stateRoot, id);\n if (!book) throw new Error(`Order book index references missing book ${id}`);\n return normalizeBookIssues(stateRoot, book);\n });\n}\n\nexport function getBook(stateRoot: string, bookId: string): OrderBook | null {\n const book = readOrderBook(stateRoot, bookId);\n return book ? normalizeBookIssues(stateRoot, book) : null;\n}\n\nexport function getBookAsync(stateRoot: string, bookId: string): Promise<OrderBook | null> {\n return readOrderBookAsync(stateRoot, bookId).then((book) => (book ? normalizeBookIssues(stateRoot, book) : null));\n}\n\n/** The first 'ready' book in index.json queue order, or null if none is ready. */\nexport function firstReadyBookInQueue(stateRoot: string): OrderBook | null {\n for (const entry of readOrderBookIndex(stateRoot)) {\n const book = getBook(stateRoot, entry.id);\n if (book?.status === 'ready') return book;\n }\n return null;\n}\n\nexport function membership(stateRoot: string): Map<string, string> {\n const result = new Map<string, string>();\n for (const book of listBooks(stateRoot)) {\n if (book.status === COMPLETE_STATUS) continue;\n for (const item of book.items) {\n const issue = item.issue.toUpperCase();\n const existing = result.get(issue);\n if (existing && existing !== book.id) {\n throw new Error(`Issue ${issue} belongs to multiple non-complete order books: ${existing}, ${book.id}`);\n }\n result.set(issue, book.id);\n }\n }\n return result;\n}\n\nexport function backlogCandidates(stateRoot: string, limit: number): SequenceNode[] {\n if (limit <= 0) return [];\n const path = backlogSequencePath(stateRoot);\n if (!existsSync(path)) return [];\n const parsed = parseSequenceMd(readFileSync(path, 'utf8'));\n if (!parsed.ok) throw new Error(`Could not parse backlog sequence: ${parsed.error}`);\n\n const assigned = membership(stateRoot);\n return [...parsed.doc.nodes]\n .sort((a, b) => a.rank - b.rank)\n .filter((node) => !assigned.has(node.issue.toUpperCase()))\n .slice(0, limit);\n}\n\nexport function computeBookProgress(\n book: OrderBook,\n issueLookup: OrderIssueLookup = liveOrderIssueLookup,\n): OrderBookProgress {\n const state = issueLookup(book.items.map((item) => item.issue));\n const items = book.items.map((item) => {\n const issue = state.get(item.issue.toUpperCase());\n const closed = issue ? !issue.open : false;\n const parked = issue?.parked ?? false;\n return {\n issue: item.issue,\n lane: item.lane,\n order: item.order,\n closed,\n parked,\n terminal: closed || parked,\n };\n });\n return {\n bookId: book.id,\n total: items.length,\n landed: items.filter((item) => item.closed).length,\n items,\n drained: items.every((item) => item.terminal),\n };\n}\n","import type {\n OrderBook,\n OrderBookItem,\n OrderBookLane,\n OrderBookSettings,\n OrderBookStatus,\n} from '@overdeck/contracts';\nimport { firstReadyBookInQueue, getBook, listBooks, membership, normalizeOrderIssueId } from './resolver.js';\nimport { writeOrderBookState } from './io.js';\n\nexport interface CreateOrderBookInput {\n id: string;\n name: string;\n settings?: Partial<OrderBookSettings>;\n createdAt?: string;\n}\n\nexport type NewOrderBookItem = Omit<OrderBookItem, 'addedAt' | 'addedBy'> &\n Partial<Pick<OrderBookItem, 'addedAt' | 'addedBy'>>;\n\nfunction timestamp(value?: string): string {\n return value ?? new Date().toISOString();\n}\n\nfunction requireBook(stateRoot: string, bookId: string): OrderBook {\n const book = getBook(stateRoot, bookId);\n if (!book) throw new Error(`Order book not found: ${bookId}`);\n return book;\n}\n\nfunction normalizeLaneOrder(items: readonly OrderBookItem[]): OrderBookItem[] {\n const laneA = items.filter((item) => item.lane === 'A').sort((a, b) => a.order - b.order);\n const laneB = items.filter((item) => item.lane === 'B').sort((a, b) => a.order - b.order);\n return [...laneA.map((item, index) => ({ ...item, order: index + 1 })), ...laneB.map((item, index) => ({ ...item, order: index + 1 }))];\n}\n\nfunction updated(book: OrderBook, changes: Partial<OrderBook>, at?: string): OrderBook {\n return { ...book, ...changes, id: book.id, createdAt: book.createdAt, updatedAt: timestamp(at) };\n}\n\n/** The sole order-book write door. */\nexport async function createBook(\n stateRoot: string,\n input: CreateOrderBookInput,\n): Promise<OrderBook> {\n if (getBook(stateRoot, input.id)) throw new Error(`Order book already exists: ${input.id}`);\n const at = timestamp(input.createdAt);\n const settings: OrderBookSettings = {\n laneAConcurrency: input.settings?.laneAConcurrency ?? 1,\n briefOverlay: input.settings?.briefOverlay,\n posture: input.settings?.posture ?? 'open',\n postureSetAt: input.settings?.postureSetAt,\n postureSetBy: input.settings?.postureSetBy,\n postureReason: input.settings?.postureReason,\n };\n if (!Number.isInteger(settings.laneAConcurrency) || settings.laneAConcurrency < 1) {\n throw new Error('laneAConcurrency must be a positive integer');\n }\n return writeOrderBookState(stateRoot, {\n id: input.id,\n name: input.name,\n status: 'draft',\n settings,\n items: [],\n createdAt: at,\n updatedAt: at,\n });\n}\n\nexport async function renameBook(\n stateRoot: string,\n bookId: string,\n name: string,\n at?: string,\n): Promise<OrderBook> {\n if (!name.trim()) throw new Error('Order book name cannot be empty');\n const book = requireBook(stateRoot, bookId);\n return writeOrderBookState(stateRoot, updated(book, { name: name.trim() }, at));\n}\n\nexport async function addItems(\n stateRoot: string,\n bookId: string,\n items: readonly NewOrderBookItem[],\n actor: string,\n at?: string,\n): Promise<OrderBook> {\n const book = requireBook(stateRoot, bookId);\n const existing = new Set(book.items.map((item) => item.issue.toUpperCase()));\n const assigned = membership(stateRoot);\n const addedAt = timestamp(at);\n const additions: OrderBookItem[] = [];\n for (const item of items) {\n const issue = normalizeOrderIssueId(stateRoot, item.issue).toUpperCase();\n if (existing.has(issue) || additions.some((candidate) => candidate.issue.toUpperCase() === issue)) {\n throw new Error(`Issue ${issue} is already in order book ${bookId}`);\n }\n const otherBook = assigned.get(issue);\n if (otherBook && otherBook !== bookId) {\n throw new Error(`Issue ${issue} already belongs to non-complete order book ${otherBook}`);\n }\n additions.push({\n ...item,\n issue,\n prereqs: item.prereqs.map((prereq) => normalizeOrderIssueId(stateRoot, prereq).toUpperCase()),\n addedAt: item.addedAt ?? addedAt,\n addedBy: item.addedBy ?? actor,\n });\n }\n const nextItems = normalizeLaneOrder([...book.items, ...additions]);\n return writeOrderBookState(stateRoot, updated(book, { items: nextItems }, at));\n}\n\nexport async function removeItem(\n stateRoot: string,\n bookId: string,\n issueId: string,\n at?: string,\n): Promise<OrderBook> {\n const book = requireBook(stateRoot, bookId);\n const issue = normalizeOrderIssueId(stateRoot, issueId).toUpperCase();\n if (!book.items.some((item) => item.issue.toUpperCase() === issue)) {\n throw new Error(`Issue ${issue} is not in order book ${bookId}`);\n }\n const items = normalizeLaneOrder(book.items.filter((item) => item.issue.toUpperCase() !== issue));\n return writeOrderBookState(stateRoot, updated(book, { items }, at));\n}\n\nexport async function moveItem(\n stateRoot: string,\n bookId: string,\n issueId: string,\n lane: OrderBookLane,\n order: number,\n at?: string,\n): Promise<OrderBook> {\n const book = requireBook(stateRoot, bookId);\n const issue = normalizeOrderIssueId(stateRoot, issueId).toUpperCase();\n const moving = book.items.find((item) => item.issue.toUpperCase() === issue);\n if (!moving) throw new Error(`Issue ${issue} is not in order book ${bookId}`);\n if (!Number.isInteger(order) || order < 1) throw new Error('Order must be a positive integer');\n\n const remaining = book.items.filter((item) => item !== moving);\n const targetLane = remaining.filter((item) => item.lane === lane).sort((a, b) => a.order - b.order);\n targetLane.splice(Math.min(order - 1, targetLane.length), 0, { ...moving, lane, order });\n const otherLane = remaining.filter((item) => item.lane !== lane).sort((a, b) => a.order - b.order);\n const items = normalizeLaneOrder([...targetLane, ...otherLane]);\n return writeOrderBookState(stateRoot, updated(book, { items }, at));\n}\n\nexport async function setItemRequirements(\n stateRoot: string,\n bookId: string,\n issueId: string,\n requirements: { prereqs?: readonly string[]; reVerify?: boolean; planAtPickup?: boolean },\n at?: string,\n): Promise<OrderBook> {\n const book = requireBook(stateRoot, bookId);\n const issue = normalizeOrderIssueId(stateRoot, issueId).toUpperCase();\n let found = false;\n const items = book.items.map((item) => {\n if (item.issue.toUpperCase() !== issue) return item;\n found = true;\n return {\n ...item,\n prereqs: requirements.prereqs === undefined\n ? item.prereqs\n : [...new Set(requirements.prereqs.map((prereq) => normalizeOrderIssueId(stateRoot, prereq).toUpperCase()))],\n reVerify: requirements.reVerify ?? item.reVerify,\n planAtPickup: requirements.planAtPickup ?? item.planAtPickup,\n };\n });\n if (!found) throw new Error(`Issue ${issue} is not in order book ${bookId}`);\n return writeOrderBookState(stateRoot, updated(book, { items }, at));\n}\n\nexport async function setSettings(\n stateRoot: string,\n bookId: string,\n settings: Partial<OrderBookSettings>,\n at?: string,\n): Promise<OrderBook> {\n const book = requireBook(stateRoot, bookId);\n const next = { ...book.settings, ...settings };\n if (!Number.isInteger(next.laneAConcurrency) || next.laneAConcurrency < 1) {\n throw new Error('laneAConcurrency must be a positive integer');\n }\n return writeOrderBookState(stateRoot, updated(book, { settings: next }, at));\n}\n\nexport async function setStatus(\n stateRoot: string,\n bookId: string,\n status: OrderBookStatus,\n options: { runId?: string | null; at?: string } = {},\n): Promise<OrderBook> {\n const book = requireBook(stateRoot, bookId);\n if (status === 'running') {\n const running = listBooks(stateRoot).find((candidate) => candidate.status === 'running' && candidate.id !== bookId);\n if (running) throw new Error(`Order book ${running.id} is already running`);\n }\n const runId = options.runId === undefined ? book.runId : options.runId ?? undefined;\n return writeOrderBookState(stateRoot, updated(book, { status, runId }, options.at));\n}\n\nexport async function advanceQueue(\n stateRoot: string,\n completedBookId: string,\n at?: string,\n): Promise<OrderBook | null> {\n const current = requireBook(stateRoot, completedBookId);\n if (current.status !== 'complete') {\n await setStatus(stateRoot, completedBookId, 'complete', { at });\n }\n return firstReadyBookInQueue(stateRoot);\n}\n","import type { Dirent } from 'node:fs';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { mkdir, readdir, readFile, rename, stat, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { Schema } from 'effect';\nimport { FlywheelRunId, FlywheelStatus, type FlywheelScopeValue, type OrderBook } from '@overdeck/contracts';\nimport {\n getFlywheelActiveRunId,\n isFlywheelGloballyPaused,\n setFlywheelActiveRunId,\n setFlywheelGloballyPaused,\n} from '../../../lib/overdeck/control-settings.js';\nimport { countAgentsByStatusRole } from '../../../lib/overdeck/agents.js';\nimport { computeBookProgress, getBook } from '../../../lib/orders/resolver.js';\nimport type { OrderBookProgress } from '../../../lib/orders/types.js';\nimport { setStatus as setOrderBookStatus } from '../../../lib/orders/writer.js';\nimport { findProjectByPathSync } from '../../../lib/projects.js';\nimport { resolveStateReadHomeSync } from '../../../lib/state-read-home.js';\n\nexport type FlywheelRunStatus = 'running' | 'paused' | 'complete' | 'aborted';\n\nexport interface FlywheelRunStateOptions {\n overdeckHome?: string;\n orderStateRoot?: (workspace: string) => string;\n getOrderBook?: typeof getBook;\n computeOrderProgress?: typeof computeBookProgress;\n setOrderStatus?: typeof setOrderBookStatus;\n}\n\nexport interface FlywheelRunListOptions extends FlywheelRunStateOptions {\n limit?: number;\n}\n\nexport interface FlywheelCurrentStatusOptions extends FlywheelRunStateOptions {\n activeRunId?: string | null;\n}\n\nexport interface FlywheelRunSummary {\n id: string;\n startedAt: string;\n status: FlywheelRunStatus;\n}\n\nexport interface FlywheelRunDetail extends FlywheelRunSummary {\n latest: FlywheelStatus | null;\n orders?: FlywheelStatus['orders'];\n /** PAN-1696: orchestrator scope this run was started/resumed with. */\n scope?: FlywheelStatus['scope'];\n paths: {\n latest: string;\n report?: string;\n openedPr?: string;\n };\n}\n\nexport interface FlywheelLaunchMetadata {\n version: 1;\n runId: string;\n workspace: string;\n briefPath: string;\n briefDisplayPath: string;\n briefOverlayPath?: string;\n orders?: { bookId: string };\n /**\n * PAN-1696: the orchestrator scope baked into this run's prompt at spawn.\n * Launch metadata is the right home rather than the status file, because the\n * orchestrator itself POSTs status updates and would otherwise overwrite it.\n */\n scope?: FlywheelScopeValue;\n}\n\nconst decodeFlywheelStatus = Schema.decodeUnknownSync(FlywheelStatus);\nconst decodeFlywheelRunId = Schema.decodeUnknownSync(FlywheelRunId);\nconst RUN_ID_PATTERN = /^RUN-(\\d+)$/;\nconst DEFAULT_RUNS_LIMIT = 20;\nconst MAX_RUNS_LIMIT = 100;\nconst RUN_SUMMARY_CONCURRENCY = 4;\ntype FlywheelStatusSnapshot = FlywheelStatus | null;\ntype FlywheelStatusListener = (status: FlywheelStatusSnapshot) => void;\nconst flywheelStatusListeners = new Set<FlywheelStatusListener>();\n\nexport function subscribeLatestFlywheelStatus(listener: FlywheelStatusListener): () => void {\n flywheelStatusListeners.add(listener);\n return () => {\n flywheelStatusListeners.delete(listener);\n };\n}\n\nfunction publishLatestFlywheelStatus(status: FlywheelStatusSnapshot): void {\n for (const listener of flywheelStatusListeners) {\n listener(status);\n }\n}\n\nexport function publishFlywheelStatusCleared(): void {\n publishLatestFlywheelStatus(null);\n}\n\nexport function parseFlywheelRunId(runId: string): FlywheelRunId {\n return decodeFlywheelRunId(runId);\n}\n\nexport function isFlywheelRunId(runId: string): runId is FlywheelRunId {\n return RUN_ID_PATTERN.test(runId);\n}\n\nfunction runNumber(runId: string): number {\n const match = RUN_ID_PATTERN.exec(runId);\n return match ? Number(match[1]) : 0;\n}\n\nfunction normalizeLimit(limit: number | undefined): number {\n if (limit === undefined) return DEFAULT_RUNS_LIMIT;\n if (!Number.isFinite(limit) || limit <= 0) return DEFAULT_RUNS_LIMIT;\n return Math.min(Math.floor(limit), MAX_RUNS_LIMIT);\n}\n\nasync function mapWithConcurrency<T, R>(items: readonly T[], concurrency: number, mapper: (item: T) => Promise<R>): Promise<R[]> {\n const results: R[] = new Array(items.length);\n let index = 0;\n await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, async () => {\n while (index < items.length) {\n const current = index;\n index += 1;\n results[current] = await mapper(items[current]!);\n }\n }));\n return results;\n}\n\nexport function getFlywheelHome(options: FlywheelRunStateOptions = {}): string {\n return join(options.overdeckHome ?? process.env['OVERDECK_HOME'] ?? join(homedir(), '.overdeck'), 'flywheel');\n}\n\nexport function getFlywheelRunsDir(options: FlywheelRunStateOptions = {}): string {\n return join(getFlywheelHome(options), 'runs');\n}\n\nexport function getFlywheelRunDir(runId: string, options: FlywheelRunStateOptions = {}): string {\n return join(getFlywheelRunsDir(options), parseFlywheelRunId(runId));\n}\n\n// ─── Run cohort (PAN-2006 WI-7: drain-to-quiescence) ──────────────────────────\n// A Run commits to draining a frozen cohort snapshotted at start: everything\n// in-flight ∪ the auto-pickable issues in the current + next wave. The Run is\n// complete when every cohort member reaches a terminal state; issues picked up\n// mid-run (e.g. unblockers) do NOT extend the cohort.\n\n/** Persist the run's cohort (issue ids) at run start. */\nexport function saveRunCohort(runId: string, issueIds: readonly string[], options: FlywheelRunStateOptions = {}): void {\n const dir = getFlywheelRunDir(runId, options);\n mkdirSync(dir, { recursive: true });\n writeFileSync(join(dir, 'cohort.json'), JSON.stringify({ issueIds: [...issueIds], snapshotAt: new Date().toISOString() }, null, 2), 'utf-8');\n}\n\n/** Load the run's cohort issue ids, or null when no snapshot exists. */\nexport function loadRunCohort(runId: string, options: FlywheelRunStateOptions = {}): string[] | null {\n const path = join(getFlywheelRunDir(runId, options), 'cohort.json');\n if (!existsSync(path)) return null;\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf-8')) as { issueIds?: unknown };\n return Array.isArray(parsed.issueIds) ? parsed.issueIds.filter((x): x is string => typeof x === 'string') : null;\n } catch {\n return null;\n }\n}\n\n/**\n * True when every cohort member is terminal (the Run has drained). Returns false\n * when there is no cohort snapshot or it is empty (nothing to declare drained).\n */\nexport function isCohortDrained(runId: string, isTerminal: (issueId: string) => boolean, options: FlywheelRunStateOptions = {}): boolean {\n const cohort = loadRunCohort(runId, options);\n if (!cohort || cohort.length === 0) return false;\n return cohort.every((id) => isTerminal(id));\n}\n\nexport async function nextFlywheelRunId(options: FlywheelRunStateOptions = {}): Promise<FlywheelRunId> {\n const runsDir = getFlywheelRunsDir(options);\n await mkdir(runsDir, { recursive: true });\n const entries = await readdir(runsDir, { withFileTypes: true });\n const maxRunNumber = entries.reduce((max, entry) => {\n if (!entry.isDirectory()) return max;\n const match = RUN_ID_PATTERN.exec(entry.name);\n if (!match) return max;\n return Math.max(max, Number(match[1]));\n }, 0);\n return parseFlywheelRunId(`RUN-${maxRunNumber + 1}`);\n}\n\nasync function writeJsonAtomic(path: string, payload: unknown): Promise<string> {\n const tmpPath = join(dirname(path), `.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`);\n await mkdir(dirname(path), { recursive: true });\n await writeFile(tmpPath, `${JSON.stringify(payload, null, 2)}\\n`, 'utf8');\n await rename(tmpPath, path);\n return path;\n}\n\nexport function enrichFlywheelStatusWithOrders(\n status: FlywheelStatus,\n book: OrderBook,\n progress: OrderBookProgress,\n): FlywheelStatus {\n const terminalPipelineStatuses = new Set(['failed', 'merged', 'parked']);\n const inFlight = new Set(status.activePipeline\n .filter((item) => !terminalPipelineStatuses.has(item.status))\n .map((item) => item.issueId.toUpperCase()));\n const laneAInFlight = book.items\n .filter((item) => item.lane === 'A' && inFlight.has(item.issue.toUpperCase()))\n .sort((left, right) => left.order - right.order)\n .map((item) => item.issue);\n const laneBInFlight = book.items\n .filter((item) => item.lane === 'B' && inFlight.has(item.issue.toUpperCase()))\n .sort((left, right) => left.order - right.order)[0]?.issue;\n return {\n ...status,\n orders: {\n bookId: book.id,\n bookName: book.name,\n landed: progress.landed,\n total: progress.total,\n laneAInFlight,\n ...(laneBInFlight ? { laneBInFlight } : {}),\n drained: progress.drained,\n },\n };\n}\n\nasync function mechanicallyEnrichOrdersStatus(\n status: FlywheelStatus,\n options: FlywheelRunStateOptions,\n): Promise<FlywheelStatus> {\n const launch = await readFlywheelLaunchMetadata(status.runId, options);\n // PAN-1696: scope is server-owned. Always restamp it from launch metadata,\n // dropping whatever the payload claimed, so a status POST from the\n // orchestrator can neither forge a scope nor silently erase the real one.\n const { scope: _claimedScope, ...unscoped } = status;\n const scoped: FlywheelStatus = launch?.scope ? { ...unscoped, scope: launch.scope } : unscoped;\n if (!launch?.orders) {\n const { orders: _untrustedOrders, ...booklessStatus } = scoped;\n return booklessStatus;\n }\n const stateRoot = options.orderStateRoot?.(launch.workspace) ?? (() => {\n const project = findProjectByPathSync(launch.workspace);\n if (!project) throw new Error(`No configured project contains orders-bound Flywheel workspace ${launch.workspace}`);\n return resolveStateReadHomeSync(project).root;\n })();\n const book = (options.getOrderBook ?? getBook)(stateRoot, launch.orders.bookId);\n if (!book) throw new Error(`Flywheel run ${status.runId} references missing order book ${launch.orders.bookId}`);\n const progress = (options.computeOrderProgress ?? computeBookProgress)(book);\n if (progress.drained && book.status === 'running') {\n await (options.setOrderStatus ?? setOrderBookStatus)(stateRoot, book.id, 'drained', { runId: book.runId });\n }\n return enrichFlywheelStatusWithOrders(scoped, book, progress);\n}\n\nexport async function writeLatestFlywheelStatus(status: FlywheelStatus, options: FlywheelRunStateOptions = {}): Promise<string> {\n const enriched = await mechanicallyEnrichOrdersStatus(status, options);\n const latestPath = join(getFlywheelRunDir(status.runId, options), 'latest.json');\n await writeJsonAtomic(latestPath, enriched);\n publishLatestFlywheelStatus(enriched);\n return latestPath;\n}\n\nfunction decodeLaunchMetadata(payload: unknown): FlywheelLaunchMetadata {\n if (typeof payload !== 'object' || payload === null) throw new Error('Invalid Flywheel launch metadata');\n const record = payload as Record<string, unknown>;\n if (record.version !== 1) throw new Error('Invalid Flywheel launch metadata version');\n for (const key of ['runId', 'workspace', 'briefPath', 'briefDisplayPath']) {\n if (typeof record[key] !== 'string' || !record[key]) throw new Error(`Invalid Flywheel launch metadata: ${key}`);\n }\n if (record.briefOverlayPath !== undefined && (typeof record.briefOverlayPath !== 'string' || !record.briefOverlayPath)) {\n throw new Error('Invalid Flywheel launch metadata: briefOverlayPath');\n }\n if (record.orders !== undefined) {\n const orders = record.orders as Record<string, unknown>;\n if (!orders || typeof orders !== 'object' || typeof orders.bookId !== 'string' || !orders.bookId) {\n throw new Error('Invalid Flywheel launch metadata: orders.bookId');\n }\n }\n if (record.scope !== undefined && record.scope !== 'pan-only' && record.scope !== 'all-tracked-projects') {\n throw new Error('Invalid Flywheel launch metadata: scope');\n }\n return record as unknown as FlywheelLaunchMetadata;\n}\n\nexport async function writeFlywheelLaunchMetadata(metadata: FlywheelLaunchMetadata, options: FlywheelRunStateOptions = {}): Promise<string> {\n const runId = parseFlywheelRunId(metadata.runId);\n const launchPath = join(getFlywheelRunDir(runId, options), 'launch.json');\n return writeJsonAtomic(launchPath, { ...metadata, runId });\n}\n\nexport async function readFlywheelLaunchMetadata(runId: string, options: FlywheelRunStateOptions = {}): Promise<FlywheelLaunchMetadata | null> {\n const launchPath = join(getFlywheelRunDir(runId, options), 'launch.json');\n try {\n return decodeLaunchMetadata(JSON.parse(await readFile(launchPath, 'utf8')) as unknown);\n } catch (error) {\n const code = typeof error === 'object' && error !== null && 'code' in error ? error.code : undefined;\n if (code === 'ENOENT') return null;\n throw error;\n }\n}\n\nexport async function readLatestFlywheelStatus(runId: string, options: FlywheelRunStateOptions = {}): Promise<FlywheelStatus | null> {\n const latestPath = join(getFlywheelRunDir(runId, options), 'latest.json');\n try {\n const payload = JSON.parse(await readFile(latestPath, 'utf8')) as unknown;\n return decodeFlywheelStatus(payload);\n } catch (error) {\n const code = typeof error === 'object' && error !== null && 'code' in error ? error.code : undefined;\n if (code === 'ENOENT') return null;\n throw error;\n }\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n const info = await stat(path);\n return info.isFile();\n } catch (error) {\n const code = typeof error === 'object' && error !== null && 'code' in error ? error.code : undefined;\n if (code === 'ENOENT') return false;\n throw error;\n }\n}\n\nasync function deriveRunStatus(runDir: string, runId: string, activeRunId: string | null): Promise<FlywheelRunStatus> {\n if (await fileExists(join(runDir, 'aborted.json'))) return 'aborted';\n if (await fileExists(join(runDir, 'report.md'))) return 'complete';\n // PAN-2108: only the CURRENT active run can be live. A run that is no longer the\n // active run but has no terminal marker was abandoned — its orchestrator died or\n // was killed before writing report.md/aborted.json. It is NOT running; reporting\n // it as such lit the sidebar \"live\" badge for every stale run forever. Treat an\n // orphaned non-active run as aborted.\n if (activeRunId !== runId) return 'aborted';\n return isFlywheelGloballyPaused() ? 'paused' : 'running';\n}\n\nasync function summarizeRun(\n runId: string,\n options: FlywheelRunStateOptions,\n activeRunId: string | null,\n): Promise<FlywheelRunSummary> {\n const runDir = getFlywheelRunDir(runId, options);\n const latest = await readLatestFlywheelStatus(runId, options);\n const status = await deriveRunStatus(runDir, runId, activeRunId);\n return {\n id: runId,\n startedAt: latest?.startedAt ?? '',\n status,\n };\n}\n\nexport async function readCurrentLatestFlywheelStatus(options: FlywheelCurrentStatusOptions = {}): Promise<FlywheelStatus | null> {\n const activeRunId = options.activeRunId === undefined ? getFlywheelActiveRunId() : options.activeRunId;\n if (!activeRunId || !isFlywheelRunId(activeRunId)) return null;\n const activeRun = await getFlywheelRunDetail(activeRunId, options);\n return (activeRun?.status === 'running' || activeRun?.status === 'paused') ? activeRun.latest : null;\n}\n\nfunction selectLatestRunIds(entries: Dirent[], limit: number): string[] {\n const selected: string[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory() || !isFlywheelRunId(entry.name)) continue;\n selected.push(entry.name);\n selected.sort((a, b) => runNumber(b) - runNumber(a));\n if (selected.length > limit) selected.length = limit;\n }\n return selected;\n}\n\nexport async function listFlywheelRuns(options: FlywheelRunListOptions = {}): Promise<FlywheelRunSummary[]> {\n const runsDir = getFlywheelRunsDir(options);\n let entries: Dirent[];\n try {\n entries = await readdir(runsDir, { withFileTypes: true });\n } catch (error) {\n const code = typeof error === 'object' && error !== null && 'code' in error ? error.code : undefined;\n if (code === 'ENOENT') return [];\n throw error;\n }\n const runIds = selectLatestRunIds(entries, normalizeLimit(options.limit));\n const activeRunId = getFlywheelActiveRunId();\n const summaries = await mapWithConcurrency(runIds, RUN_SUMMARY_CONCURRENCY, (runId) => summarizeRun(runId, options, activeRunId));\n return summaries.sort((a, b) => b.startedAt.localeCompare(a.startedAt));\n}\n\n/**\n * PAN-1528/PAN-1908: overlay the flywheel capacity gauge from the indexed\n * agents table. This status path must not enumerate state.json files.\n */\nasync function countLiveWorkAgents(_options: FlywheelRunStateOptions = {}): Promise<number> {\n return countAgentsByStatusRole('running', 'work');\n}\n\nfunction withLiveAgentsActive(latest: FlywheelStatus, liveCount: number): FlywheelStatus {\n if (latest.system.agentsActive === liveCount) return latest;\n return {\n ...latest,\n system: {\n ...latest.system,\n agentsActive: liveCount,\n },\n };\n}\n\nexport async function getFlywheelRunDetail(runId: string, options: FlywheelCurrentStatusOptions = {}): Promise<FlywheelRunDetail | null> {\n const runDir = getFlywheelRunDir(runId, options);\n const latest = await readLatestFlywheelStatus(runId, options);\n if (!latest) return null;\n const activeRunId = options.activeRunId !== undefined ? options.activeRunId : getFlywheelActiveRunId();\n const status = await deriveRunStatus(runDir, runId, activeRunId);\n const reportPath = join(runDir, 'report.md');\n const openedPrPath = join(runDir, 'opened-pr.json');\n // PAN-1528: overlay the live work-agent count so the field reflects reality\n // rather than the orchestrator's stale initial value.\n const liveCount = await countLiveWorkAgents(options);\n return {\n id: runId,\n startedAt: latest.startedAt,\n status,\n latest: withLiveAgentsActive(latest, liveCount),\n ...(latest.orders ? { orders: latest.orders } : {}),\n // PAN-1696: surface the run's own scope on the detail payload too, so a\n // consumer reading run detail does not have to dig into `latest`.\n ...(latest.scope ? { scope: latest.scope } : {}),\n paths: {\n latest: join(runDir, 'latest.json'),\n ...((await fileExists(reportPath)) ? { report: reportPath } : {}),\n ...((await fileExists(openedPrPath)) ? { openedPr: openedPrPath } : {}),\n },\n };\n}\n\n// Clear the SQLite \"active run\" gate and the pause flag, and notify subscribers.\n// Exported so callers in CLI and dashboard share a single clearing primitive\n// (PAN-1245: gate previously cleared in three different places that drifted).\nexport function clearFlywheelGate(): void {\n setFlywheelActiveRunId(null);\n setFlywheelGloballyPaused(false);\n publishFlywheelStatusCleared();\n}\n\n// Single source of truth for \"is a flywheel run live?\". Reads the SQLite gate,\n// validates it against on-disk run state, and self-heals if the gate points at\n// a run that has already ended (report.md / aborted.json present), at a run\n// whose state was wiped, or at a malformed value. Both `pan flywheel start`\n// and the dashboard Start path consult this — they cannot disagree (PAN-1245).\nexport async function resolveLiveFlywheelRunId(options: FlywheelRunStateOptions = {}): Promise<string | null> {\n const candidate = getFlywheelActiveRunId();\n if (!candidate) return null;\n if (!isFlywheelRunId(candidate)) {\n clearFlywheelGate();\n return null;\n }\n const latest = await readLatestFlywheelStatus(candidate, options);\n if (!latest) {\n // The gate points at a run with no snapshot on disk — the run dir was\n // wiped or never fully initialized. Treat as dead.\n clearFlywheelGate();\n return null;\n }\n const runDir = getFlywheelRunDir(candidate, options);\n // `candidate` is the active run id (read above), so pass it as activeRunId.\n const status = await deriveRunStatus(runDir, candidate, candidate);\n if (status === 'complete' || status === 'aborted') {\n clearFlywheelGate();\n return null;\n }\n return candidate;\n}\n\n// Mark a flywheel run as aborted and clear the gate if it still points at this\n// run. Writes `aborted.json` so `deriveRunStatus` reports the run as aborted on\n// subsequent reads, mirroring the report.md → complete convention.\nexport async function abortFlywheelRun(runId: string, options: FlywheelRunStateOptions = {}): Promise<void> {\n const parsed = parseFlywheelRunId(runId);\n const abortedPath = join(getFlywheelRunDir(parsed, options), 'aborted.json');\n await writeJsonAtomic(abortedPath, { runId: parsed, abortedAt: new Date().toISOString() });\n if (getFlywheelActiveRunId() === parsed) {\n clearFlywheelGate();\n }\n}\n","import { exec } from 'node:child_process';\nimport { readFile, realpath } from 'node:fs/promises';\nimport { dirname, isAbsolute, relative, resolve, sep } from 'node:path';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\nexport const DEFAULT_BRIEF_PATH = 'docs/flywheel-brief.md';\n\nfunction isInsideRoot(projectRoot: string, candidate: string): boolean {\n const relativePath = relative(projectRoot, candidate);\n return relativePath === '' || (!relativePath.startsWith('..') && !isAbsolute(relativePath));\n}\n\nexport function resolveFlywheelStartBriefPath(cwd: string, requestedPath?: string): { absolutePath: string; displayPath: string } {\n const rawPath = requestedPath?.trim() || DEFAULT_BRIEF_PATH;\n if (rawPath.includes('\\0')) throw new Error('Brief path is invalid');\n\n const root = resolve(cwd);\n const absolutePath = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);\n if (!isInsideRoot(root, absolutePath)) throw new Error('Brief path must stay inside the project root');\n\n const normalizedRoot = root.endsWith(sep) ? root : `${root}${sep}`;\n const displayPath = absolutePath === root ? '.' : relative(root, absolutePath);\n return { absolutePath, displayPath: absolutePath.startsWith(normalizedRoot) ? displayPath : absolutePath };\n}\n\nasync function assertExistingPathInsideRoot(projectRoot: string, candidate: string): Promise<void> {\n const [realRoot, realCandidate] = await Promise.all([realpath(projectRoot), realpath(candidate)]);\n if (!isInsideRoot(realRoot, realCandidate)) throw new Error('Brief path must stay inside the project root');\n}\n\nexport async function requireFlywheelBrief(cwd: string, requestedPath?: string): Promise<{ absolutePath: string; displayPath: string }> {\n const resolved = resolveFlywheelStartBriefPath(cwd, requestedPath);\n try {\n await assertExistingPathInsideRoot(cwd, resolved.absolutePath);\n await readFile(resolved.absolutePath, 'utf8');\n return resolved;\n } catch (error) {\n const code = typeof error === 'object' && error !== null && 'code' in error ? error.code : undefined;\n if (code === 'ENOENT') throw new Error(`Flywheel brief not found: ${resolved.displayPath}`);\n throw error;\n }\n}\n\n/**\n * The flywheel is a project-scoped singleton: it must run from the PRIMARY\n * worktree root, never a linked feature worktree. Every worktree contains\n * docs/flywheel-brief.md, so the brief check alone cannot catch a caller whose\n * shell happens to sit inside a workspaces/feature-* checkout, and an\n * orchestrator spawned there operates inside a live work agent's worktree.\n * A linked worktree is\n * detected by `git rev-parse --git-common-dir` resolving to the primary's\n * .git directory; outside a repo (or on failure) the cwd is kept and the\n * brief check reports its own error.\n */\n\nexport async function resolvePrimaryWorktreeRoot(cwd: string): Promise<string> {\n try {\n const { stdout } = await execAsync(\n 'git rev-parse --path-format=absolute --git-common-dir',\n { cwd, timeout: 5000 },\n );\n const commonDir = stdout.trim();\n if (commonDir.endsWith(`${sep}.git`)) return dirname(commonDir);\n return cwd;\n } catch {\n return cwd;\n }\n}\n","import { existsSync, readdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { getProjectPanPaths } from '../pan-dir/paths.js';\nimport { getReviewStatusSync } from '../review-status.js';\nimport type { ClassifyLookups } from './pickup.js';\n\n/**\n * Build the {@link ClassifyLookups} the shared pickup module needs from live project\n * state: labels (in-memory issue service), planned (readable xBRIEF spec), and\n * in-pipeline (review status / live workspace). Shared by the dashboard forecast\n * route and the Flywheel run-cohort snapshot so both classify issues identically\n * (PAN-2006 single source of truth). The issue service is lazy-required to avoid a\n * static lib → dashboard layering edge.\n */\nexport function buildClassifyLookups(\n projectRoot: string,\n opts: { labels?: (id: string) => readonly string[] } = {},\n): ClassifyLookups {\n // Labels come from the in-memory issue service (server-side). A CLI/sandbox process cannot\n // reach that singleton, so callers there must pass `opts.labels` (e.g. gh-derived) — without\n // it, a CLI would silently classify every issue as label-less, making ready/released/parked/\n // objection/vetoed/blocksMain all false (the `pan backlog forecast` undercount bug).\n const labelsByIssue = new Map<string, string[]>();\n if (!opts?.labels) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { getSharedIssueService } = require('../../dashboard/server/services/issue-service-singleton.js') as typeof import('../../dashboard/server/services/issue-service-singleton.js');\n for (const issue of getSharedIssueService().getIssues() as Array<Record<string, unknown>>) {\n const id = typeof issue['identifier'] === 'string' ? issue['identifier'].toUpperCase() : '';\n if (!id) continue;\n const raw = Array.isArray(issue['labels']) ? (issue['labels'] as unknown[]) : [];\n const names = raw\n .map((l) => (typeof l === 'string' ? l : ((l as { name?: string })?.name ?? '')))\n .filter((s): s is string => Boolean(s));\n labelsByIssue.set(id, names);\n }\n } catch { /* issue service not ready — treat as no labels */ }\n }\n\n const specsDir = getProjectPanPaths(projectRoot).specsDir;\n const specIssues = new Set<string>();\n if (existsSync(specsDir)) {\n for (const f of readdirSync(specsDir)) {\n const m = /^[\\d-]+-([A-Z]+-\\d+)-/i.exec(f);\n if (m) specIssues.add(m[1]!.toUpperCase());\n }\n }\n const workspacesDir = join(projectRoot, 'workspaces');\n return {\n labels: opts?.labels ?? ((id) => labelsByIssue.get(id.toUpperCase()) ?? []),\n isPlanned: (id) => {\n const u = id.toUpperCase();\n return specIssues.has(u);\n },\n isInPipeline: (id) => {\n const u = id.toUpperCase();\n const rs = getReviewStatusSync(u);\n return (rs !== null && rs.reviewStatus !== 'pending') || existsSync(join(workspacesDir, `feature-${id.toLowerCase()}`));\n },\n };\n}\n","import { existsSync, readFileSync, readdirSync } from 'node:fs';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { Effect, Schema } from 'effect';\nimport type { FlywheelRunId } from '@overdeck/contracts';\nimport type { AgentState } from '../agents.js';\nimport type { FlywheelScope, RoleEffort } from '../config-yaml.js';\nimport { getInternalTokenSync, INTERNAL_TOKEN_HEADER } from '../internal-token.js';\nimport { getProjectPanPaths } from '../pan-dir/paths.js';\nimport { getAgentDir, spawnRun, stopAgent } from '../agents.js';\nimport { parseSequenceMd } from '../backlog/sequence-io.js';\nimport { computePredictedConflictSignals, declaredIssueFootprint, pickFromSequence, type IssueFileFootprint } from '../flywheel-merge-order.js';\nimport { requireFlywheelBrief } from '../flywheel-start.js';\nimport { findProjectByPathSync, getProjectSwarmHotspots } from '../projects.js';\nimport { getBookAsync as getOrderBook } from '../orders/resolver.js';\nimport { resolveStateReadHomeSync } from '../state-read-home.js';\nimport type { XBriefDocument } from '../xbrief/types.js';\nimport {\n getFlywheelActiveRunId,\n isFlywheelAutoPickupBacklog,\n isFlywheelRequireUatBeforeMerge,\n setFlywheelActiveRunId,\n setFlywheelGloballyPaused,\n} from '../overdeck/control-settings.js';\nimport { abortFlywheelRun, readFlywheelLaunchMetadata, resolveLiveFlywheelRunId, saveRunCohort } from '../../dashboard/server/services/flywheel-run-state.js';\nimport { buildClassifyLookups } from '../backlog/lookups.js';\nimport { computeCohort } from '../backlog/pickup.js';\nimport { gatherProjectLensSignals } from '../pipeline-membership-gather.js';\nimport { resolvePipelineMembership, type PipelineMembership } from '../pipeline-membership.js';\nimport { buildResumeContract, type ResumeCause } from '../resume-contract.js';\n\nexport const FLYWHEEL_ORCHESTRATOR_AGENT_ID = 'flywheel-orchestrator';\n\nexport function isIssueInResolvedPipeline(issueId: string, memberships: PipelineMembership[]): boolean {\n return memberships.some((membership) =>\n membership.issueId.toUpperCase() === issueId.toUpperCase() && membership.inPipeline,\n );\n}\n\ninterface ActiveOrderBookIssuesDeps {\n activeRunId?: () => string | null;\n readLaunch?: typeof readFlywheelLaunchMetadata;\n stateRoot?: (projectRoot: string) => string | null;\n getBook?: typeof getOrderBook;\n}\n\nexport async function activeOrderBookIssues(\n projectRoot: string,\n runId?: string,\n deps: ActiveOrderBookIssuesDeps = {},\n): Promise<ReadonlySet<string>> {\n const activeRunId = runId ?? (deps.activeRunId ?? getFlywheelActiveRunId)();\n if (!activeRunId) return new Set();\n const launch = await (deps.readLaunch ?? readFlywheelLaunchMetadata)(activeRunId);\n const bookId = launch?.orders?.bookId;\n if (!bookId) return new Set();\n const stateRoot = deps.stateRoot?.(projectRoot) ?? (() => {\n const project = findProjectByPathSync(projectRoot);\n return project ? resolveStateReadHomeSync(project).root : null;\n })();\n if (!stateRoot) return new Set();\n const book = await (deps.getBook ?? getOrderBook)(stateRoot, bookId);\n return new Set(book?.items.map((item) => item.issue.toUpperCase()) ?? []);\n}\n\nconst FlywheelRunIdSchema = Schema.String.check(Schema.isPattern(/^RUN-\\d+$/));\nconst decodeFlywheelRunId = Schema.decodeUnknownSync(FlywheelRunIdSchema);\n\nexport interface FlywheelLifecycleOptions {\n runId?: FlywheelRunId;\n workspace?: string;\n briefPath?: string;\n briefOverlayPath?: string;\n briefOverlayContent?: string;\n prompt?: string;\n model?: string;\n harness?: 'claude-code' | 'ohmypi' | 'codex' | 'acp' | 'kimi-code' | 'opencode' | 'muse';\n effort?: RoleEffort;\n minAgents?: number;\n maxAgents?: number;\n scope?: FlywheelScope;\n autoPickupBacklog?: boolean;\n requireUatBeforeMerge?: boolean;\n env?: NodeJS.ProcessEnv;\n resumeSessionId?: string;\n resumeCause?: ResumeCause;\n}\n\nexport interface FlywheelPauseResult {\n activeRunId: string | null;\n}\n\nexport interface FlywheelResumeResult {\n activeRunId: string;\n agent: AgentState;\n}\n\nfunction parseRunId(runId: string): FlywheelRunId {\n return decodeFlywheelRunId(runId);\n}\n\nfunction defaultFlywheelRunId(): FlywheelRunId {\n return parseRunId(`RUN-${Date.now()}`);\n}\n\nfunction internalDashboardOrigin(): string {\n const port = Number.parseInt(process.env['API_PORT'] ?? process.env['PORT'] ?? '3011', 10);\n return process.env['OVERDECK_INTERNAL_DASHBOARD_URL'] ?? `http://127.0.0.1:${port}`;\n}\n\nasync function fetchIssueRowsFromDashboard(): Promise<Array<{ ref?: string; identifier?: string; labels?: string[]; author?: string; assignee?: { name?: string } | string }>> {\n const dashboardOrigin = internalDashboardOrigin();\n const token = getInternalTokenSync();\n if (!token) {\n console.error('[flywheel] Cannot load issue metadata: internal dashboard token is unavailable');\n return [];\n }\n try {\n const response = await fetch(new URL('/api/issues?cycle=all&includeCompleted=true', dashboardOrigin), {\n headers: {\n [INTERNAL_TOKEN_HEADER]: token,\n origin: dashboardOrigin,\n },\n });\n if (!response.ok) {\n console.error(`[flywheel] Cannot load issue metadata from dashboard: HTTP ${response.status}`);\n return [];\n }\n const body = await response.json();\n if (!Array.isArray(body)) {\n console.error('[flywheel] Cannot load issue metadata from dashboard: response was not an array');\n return [];\n }\n return body as Array<{ ref?: string; identifier?: string; labels?: string[]; author?: string; assignee?: { name?: string } | string }>;\n } catch (error) {\n console.error('[flywheel] Cannot load issue metadata from dashboard:', error);\n return [];\n }\n}\n\nasync function flywheelRunConfigurationSection(options: FlywheelLifecycleOptions, runId?: string): Promise<string> {\n const configLines = [\n options.harness ? `Harness: ${options.harness}` : undefined,\n options.effort ? `Effort: ${options.effort}` : undefined,\n options.minAgents ? `Min concurrent agents (target): ${options.minAgents}` : undefined,\n options.maxAgents ? `Max concurrent agents (ceiling): ${options.maxAgents}` : undefined,\n options.scope ? `Scope: ${options.scope}` : undefined,\n typeof options.autoPickupBacklog === 'boolean'\n ? `Auto-pickup backlog: ${options.autoPickupBacklog}`\n : undefined,\n typeof options.requireUatBeforeMerge === 'boolean'\n ? `Require UAT before merge: ${options.requireUatBeforeMerge}`\n : undefined,\n ].filter(Boolean).join('\\n');\n\n let sequenceSection = '';\n const projectRoot = process.cwd();\n const orderBookIssues = await activeOrderBookIssues(projectRoot, runId);\n if (options.autoPickupBacklog || orderBookIssues.size > 0) {\n const seqPath = join(projectRoot, '.pan', 'backlog', 'sequence.md');\n if (existsSync(seqPath)) {\n try {\n const md = readFileSync(seqPath, 'utf-8');\n const parsed = parseSequenceMd(md);\n if (parsed.ok) {\n // Build issue lookups through the dashboard read path. A deacon child\n // cannot safely import the dashboard's per-process issue singleton.\n type IssueRow = { ref?: string; identifier?: string; labels?: string[]; author?: string; assignee?: { name?: string } | string };\n const getIssueRows = async (): Promise<IssueRow[]> => fetchIssueRowsFromDashboard();\n const issueRowMap = new Map<string, IssueRow>(\n (await getIssueRows()).map((i) => [i.ref ?? i.identifier ?? '', i]),\n );\n\n const issueLabelsLookup = (issueId: string): string[] =>\n issueRowMap.get(issueId)?.labels ?? [];\n\n const AUTHORIZED_AUTHORS = new Set(['eltmon', 'panopticon-agent[bot]']);\n const isAuthorizedIssue = (issueId: string): boolean => {\n const row = issueRowMap.get(issueId);\n if (!row) return false; // unknown issue — skip (safe default)\n if (row.author && AUTHORIZED_AUTHORS.has(row.author)) return true;\n const assigneeName = typeof row.assignee === 'string' ? row.assignee : row.assignee?.name;\n return assigneeName === 'eltmon';\n };\n\n const paths = getProjectPanPaths(projectRoot);\n const specsDir = paths.specsDir;\n const issuesWithSpecs = new Set<string>();\n const declaredFootprints: IssueFileFootprint[] = [];\n if (existsSync(specsDir)) {\n for (const f of readdirSync(specsDir)) {\n const match = /^[\\d-]+-([A-Z]+-\\d+)-/i.exec(f);\n if (!match) continue;\n const issueId = match[1]!.toUpperCase();\n issuesWithSpecs.add(issueId);\n try {\n const doc = JSON.parse(readFileSync(join(specsDir, f), 'utf-8')) as XBriefDocument;\n declaredFootprints.push(declaredIssueFootprint(issueId, doc));\n } catch {\n // A malformed spec should not break flywheel startup; planned-ness\n // still comes from the filename and the normal plan gate handles parse errors.\n }\n }\n }\n const projectConfig = findProjectByPathSync(projectRoot);\n const predictedConflictSignals = computePredictedConflictSignals(declaredFootprints, {\n hotspots: getProjectSwarmHotspots(projectConfig),\n });\n const isReadyOrHasPrd = (issueId: string): boolean => {\n const id = issueId.toUpperCase();\n if (issuesWithSpecs.has(id)) return true;\n return existsSync(join(paths.draftsDir, `${id}.md`));\n };\n const membershipAvailable = Boolean(projectConfig?.github_repo);\n const memberships = projectConfig?.github_repo\n ? (await gatherProjectLensSignals(projectConfig)).map(resolvePipelineMembership)\n : [];\n const isInPipeline = (issueId: string): boolean =>\n membershipAvailable ? isIssueInResolvedPipeline(issueId, memberships) : true;\n\n const top10 = parsed.doc.nodes.slice(0, 10).map((n) =>\n ` #${n.rank} ${n.issue}: ${n.why.slice(0, 100)} [gate:${n.gate}]`,\n );\n const nextPick = pickFromSequence(parsed.doc.nodes, {\n issueLabels: issueLabelsLookup,\n isAuthorizedIssue,\n isReadyOrHasPrd,\n isInPipeline,\n requireReady: true,\n autoPickupBacklog: options.autoPickupBacklog,\n activeBookMembership: orderBookIssues,\n predictedConflictSignals,\n });\n let nextLine: string;\n let pickInstruction: string;\n if (!membershipAvailable) {\n nextLine = 'MEMBERSHIP UNAVAILABLE: project has no GitHub repository; auto-pickup is disabled';\n 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.';\n } else if (!nextPick) {\n nextLine = 'No eligible issue found in sequence — fall back to normal priority';\n pickInstruction = '';\n } else if (nextPick.planning === 'interactive') {\n // FR-17: interactive planning requires operator presence — must NOT be auto-started\n nextLine = `NEEDS OPERATOR ACTION: ${nextPick.issueId} (rank ${nextPick.rank}) has planning=interactive — do NOT auto-start; operator must run 'pan plan ${nextPick.issueId}'`;\n 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.`;\n } else {\n const conflictSuffix = typeof nextPick.predictedConflictCount === 'number'\n ? `, predictedConflicts=${nextPick.predictedConflictCount}${nextPick.predictedConflictsWith?.length ? ` with ${nextPick.predictedConflictsWith.join(', ')}` : ''}`\n : '';\n nextLine = `MUST start next: ${nextPick.issueId} (rank ${nextPick.rank}, planning=${nextPick.planning}${conflictSuffix})`;\n 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.`;\n }\n sequenceSection = `\\n\\nBacklog sequence (${parsed.doc.nodes.length} issues ranked):\\n${top10.join('\\n')}\\n${nextLine}${pickInstruction}`;\n }\n } catch {\n // sequence.md exists but couldn't be parsed — skip enrichment\n }\n }\n }\n\n return (configLines ? `\\n\\nRun configuration:\\n${configLines}` : '') + sequenceSection;\n}\n\nasync function defaultFlywheelPrompt(runId: string, options: FlywheelLifecycleOptions, briefContent?: string): Promise<string> {\n const configSection = await flywheelRunConfigurationSection(options, runId);\n const briefSection = options.briefPath\n ? `\\n\\nBrief path: ${options.briefPath}\\n\\n${briefContent ?? ''}`\n : '';\n return `FLYWHEEL ORCHESTRATOR TASK for ${runId}:\n\nRun 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.${configSection}${briefSection}`;\n}\n\nfunction getLocalFlywheelRunDir(runId: string): string {\n const overdeckHome = process.env.OVERDECK_HOME ?? join(homedir(), '.overdeck');\n return join(overdeckHome, 'flywheel', 'runs', runId);\n}\n\nexport async function saveResumeSessionId(runId: string, sessionId: string): Promise<void> {\n const runDir = getLocalFlywheelRunDir(runId);\n await mkdir(runDir, { recursive: true });\n await writeFile(\n join(runDir, 'resume-session.json'),\n JSON.stringify({ sessionId, pausedAt: new Date().toISOString() }),\n 'utf-8',\n );\n}\n\nexport async function loadResumeSessionId(runId: string): Promise<string | null> {\n try {\n const raw = await readFile(join(getLocalFlywheelRunDir(runId), 'resume-session.json'), 'utf-8');\n const parsed = JSON.parse(raw) as { sessionId?: unknown };\n return typeof parsed.sessionId === 'string' ? parsed.sessionId : null;\n } catch {\n return null;\n }\n}\n\nexport function isFlywheelDevcontainerRuntime(env: NodeJS.ProcessEnv = process.env): boolean {\n const disabledDeacon = env.OVERDECK_DISABLE_DEACON?.toLowerCase();\n if (disabledDeacon === '1' || disabledDeacon === 'true') return true;\n\n const hostname = env.HOSTNAME?.toLowerCase() ?? '';\n return hostname.includes('devcontainer') || hostname.startsWith('api-feature-') || hostname.startsWith('workspace-');\n}\n\n/**\n * Resume prompt. PAN-2006 FR-8: re-attach the standing brief on resume so its\n * directives (pipeline-unblock override, never-block, red-main-first) survive a\n * resume + context compaction — the pre-PAN-2006 resume prompt only pointed at\n * FLYWHEEL-STATE.md and a long-running orchestrator could drift off-brief.\n */\nexport function buildFlywheelResumePrompt(configSection: string, briefContent?: string, cause: ResumeCause = 'system'): string {\n const base =\n `FLYWHEEL RESUME: ${buildResumeContract(cause)} Resume the tick loop from your prior ` +\n 'state, run a full tick now, and call ScheduleWakeup(delaySeconds:1000) to arm the next tick. ' +\n 'Check `docs/FLYWHEEL-STATE.md` and the latest status snapshot for context.';\n const brief = briefContent\n ? `\\n\\n--- Standing brief (re-read it — it governs pickup, unblocking, and never-block) ---\\n\\n${briefContent}`\n : '';\n return `${base}${configSection}${brief}`;\n}\n\nfunction withOrderBookBriefOverlay(\n briefContent: string | undefined,\n overlayPath: string | undefined,\n overlayContent: string | undefined,\n): string | undefined {\n if (!overlayContent) return briefContent;\n const standard = briefContent?.trimEnd() ?? '';\n const overlay = `--- Order-book brief overlay${overlayPath ? `: ${overlayPath}` : ''} ---\\n\\n${overlayContent.trim()}`;\n return standard ? `${standard}\\n\\n${overlay}` : overlay;\n}\n\nexport async function spawnFlywheelAgent(runId: string, options: FlywheelLifecycleOptions = {}): Promise<AgentState> {\n const workspace = options.workspace ?? process.cwd();\n // Re-read the brief on every spawn (fresh AND resume) so its directives survive\n // resume/compaction. Default to the standard brief path when none is supplied.\n const briefPath = options.briefPath ?? join(workspace, 'docs', 'flywheel-brief.md');\n let briefOverlayPath = options.briefOverlayPath;\n let briefOverlayContent = options.briefOverlayContent;\n if (briefOverlayPath && briefOverlayContent === undefined) {\n const resolvedOverlay = await requireFlywheelBrief(workspace, briefOverlayPath);\n briefOverlayPath = resolvedOverlay.displayPath;\n briefOverlayContent = await readFile(resolvedOverlay.absolutePath, 'utf8');\n }\n const briefContent = withOrderBookBriefOverlay(\n await readFile(briefPath, 'utf8').catch(() => undefined),\n briefOverlayPath,\n briefOverlayContent,\n );\n const prompt = options.resumeSessionId\n ? buildFlywheelResumePrompt(await flywheelRunConfigurationSection(options, runId), briefContent, options.resumeCause)\n : (options.prompt ?? (await defaultFlywheelPrompt(runId, { ...options, briefPath }, briefContent)));\n return spawnRun(runId, 'flywheel', {\n agentId: FLYWHEEL_ORCHESTRATOR_AGENT_ID,\n workspace,\n prompt,\n model: options.model,\n harness: options.harness,\n effort: options.effort,\n allowHost: true,\n registerConversation: true,\n resumeSessionId: options.resumeSessionId,\n flywheelRunId: runId,\n startedBy: `flywheel:${runId}`,\n });\n}\n\nfunction withFlywheelAutonomyOptions(options: FlywheelLifecycleOptions): FlywheelLifecycleOptions {\n return {\n ...options,\n autoPickupBacklog: options.autoPickupBacklog ?? isFlywheelAutoPickupBacklog(),\n requireUatBeforeMerge: options.requireUatBeforeMerge ?? isFlywheelRequireUatBeforeMerge(),\n };\n}\n\nexport async function spawnFlywheel(options: FlywheelLifecycleOptions = {}): Promise<AgentState> {\n if (isFlywheelDevcontainerRuntime(options.env)) {\n throw new Error('Refusing to spawn flywheel-orchestrator inside a workspace devcontainer');\n }\n\n // Self-healing gate check (PAN-1245): if the SQLite gate points at a run\n // that has already ended (report.md/aborted.json) or whose on-disk state is\n // gone (post-reboot, post-wipe), resolveLiveFlywheelRunId clears the gate\n // and returns null. Only a genuinely live prior run blocks a new start.\n const activeRunId = await resolveLiveFlywheelRunId();\n if (activeRunId) {\n throw new Error(`Flywheel run ${activeRunId} is already active; pause, resume, or report it before starting another run`);\n }\n\n const runId = options.runId ? parseRunId(options.runId) : defaultFlywheelRunId();\n const agent = await spawnFlywheelAgent(runId, withFlywheelAutonomyOptions(options));\n setFlywheelActiveRunId(runId);\n setFlywheelGloballyPaused(false);\n\n // PAN-2006 WI-7: freeze the run's cohort (in-flight ∪ current+next wave) at start.\n // The Run is complete once this cohort drains; mid-run pickups don't extend it.\n // Best-effort — a missing/unparseable sequence just means no cohort gate yet.\n try {\n const workspace = options.workspace ?? process.cwd();\n const seqPath = join(workspace, '.pan', 'backlog', 'sequence.md');\n if (existsSync(seqPath)) {\n const parsed = parseSequenceMd(readFileSync(seqPath, 'utf-8'));\n if (parsed.ok) {\n saveRunCohort(runId, computeCohort(\n parsed.doc.nodes,\n buildClassifyLookups(workspace),\n options.maxAgents ?? 5,\n options.autoPickupBacklog ?? isFlywheelAutoPickupBacklog(),\n await activeOrderBookIssues(workspace, runId),\n ));\n }\n }\n } catch { /* cohort snapshot is best-effort */ }\n\n return agent;\n}\n\nexport async function abortSpawnedFlywheel(runId: string): Promise<void> {\n try {\n await Effect.runPromise(stopAgent(FLYWHEEL_ORCHESTRATOR_AGENT_ID, 'operator'));\n } finally {\n await abortFlywheelRun(runId);\n }\n}\n\nexport async function pauseFlywheel(): Promise<FlywheelPauseResult> {\n const activeRunId = getFlywheelActiveRunId();\n if (activeRunId) {\n try {\n const sessionId = (await readFile(join(getAgentDir(FLYWHEEL_ORCHESTRATOR_AGENT_ID), 'session.id'), 'utf-8')).trim();\n if (sessionId) await saveResumeSessionId(activeRunId, sessionId);\n } catch { /* non-fatal: resume falls back to fresh if session.id is missing */ }\n }\n setFlywheelGloballyPaused(true);\n await Effect.runPromise(stopAgent(FLYWHEEL_ORCHESTRATOR_AGENT_ID, 'operator'));\n return { activeRunId };\n}\n\nexport async function resumeFlywheel(options: FlywheelLifecycleOptions = {}): Promise<FlywheelResumeResult> {\n if (isFlywheelDevcontainerRuntime(options.env)) {\n throw new Error('Refusing to resume flywheel-orchestrator inside a workspace devcontainer');\n }\n\n const activeRunId = getFlywheelActiveRunId();\n if (!activeRunId) {\n throw new Error('No active flywheel run to resume');\n }\n const runId = parseRunId(activeRunId);\n\n const resumeSessionId = options.resumeSessionId ?? await loadResumeSessionId(runId) ?? undefined;\n const launch = await readFlywheelLaunchMetadata(runId);\n const agent = await spawnFlywheelAgent(runId, withFlywheelAutonomyOptions({\n ...options,\n workspace: options.workspace ?? launch?.workspace,\n briefPath: options.briefPath ?? launch?.briefPath,\n briefOverlayPath: options.briefOverlayPath ?? launch?.briefOverlayPath,\n resumeSessionId,\n }));\n setFlywheelGloballyPaused(false);\n return { activeRunId, agent };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"flywheel-DKldI63J.js","names":["OrderBookSchema","OrderBookIndexEntrySchema","decodeFlywheelRunId","setOrderBookStatus","getOrderBook"],"sources":["../../src/lib/orders/types.ts","../../src/lib/orders/io.ts","../../src/lib/orders/resolver.ts","../../src/lib/orders/writer.ts","../../src/dashboard/server/services/flywheel-run-state.ts","../../src/lib/flywheel-start.ts","../../src/lib/backlog/lookups.ts","../../src/lib/cloister/flywheel.ts"],"sourcesContent":["import { OrderBook as OrderBookSchema } from '@overdeck/contracts';\nimport { Schema } from 'effect';\n\nexport {\n OrderBook,\n OrderBookIndexEntry,\n OrderBookItem,\n OrderBookLane,\n OrderBookPosture,\n OrderBookSettings,\n OrderBookStatus,\n} from '@overdeck/contracts';\nexport type {\n OrderBook as OrderBookType,\n OrderBookIndexEntry as OrderBookIndexEntryType,\n OrderBookItem as OrderBookItemType,\n OrderBookLane as OrderBookLaneType,\n OrderBookPosture as OrderBookPostureType,\n OrderBookSettings as OrderBookSettingsType,\n OrderBookStatus as OrderBookStatusType,\n} from '@overdeck/contracts';\n\nexport type OrderBookParseError = { ok: false; error: string };\nexport type OrderBookParseResult =\n | { ok: true; book: typeof OrderBookSchema.Type }\n | OrderBookParseError;\n\nconst decodeOrderBook = Schema.decodeUnknownSync(OrderBookSchema);\n\nexport function parseOrderBookJson(value: unknown): OrderBookParseResult {\n try {\n return { ok: true, book: decodeOrderBook(value) };\n } catch (error) {\n return {\n ok: false,\n error: `Invalid order book: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n}\n\nexport interface OrderIssueState {\n issue: string;\n open: boolean;\n parked: boolean;\n}\n\nexport type OrderIssueLookup = (\n issueIds: readonly string[],\n) => ReadonlyMap<string, OrderIssueState>;\n\nexport interface OrderBookItemProgress {\n issue: string;\n lane: typeof import('@overdeck/contracts').OrderBookLane.Type;\n order: number;\n closed: boolean;\n parked: boolean;\n terminal: boolean;\n}\n\nexport interface OrderBookProgress {\n bookId: string;\n total: number;\n landed: number;\n items: readonly OrderBookItemProgress[];\n drained: boolean;\n}\n\nexport type OrderBookFindingCode =\n | 'empty-book'\n | 'issue-not-open'\n | 'duplicate-membership'\n | 'unresolved-prerequisite'\n | 'prerequisite-cycle'\n | 'missing-prd'\n | 'issue-store-unavailable';\n\nexport interface OrderBookFinding {\n code: OrderBookFindingCode;\n issue: string;\n message: string;\n}\n\nexport interface OrderBookValidationResult {\n blocks: OrderBookFinding[];\n warns: OrderBookFinding[];\n}\n","import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { OrderBookIndexEntry as OrderBookIndexEntrySchema } from '@overdeck/contracts';\nimport type { OrderBook, OrderBookIndexEntry, OrderBookItem } from '@overdeck/contracts';\nimport { Effect, Schema } from 'effect';\nimport { flushAutoCommits, queueAutoCommit } from '../pan-dir/auto-commit.js';\nimport { parseOrderBookJson } from './types.js';\n\nconst BOOK_ID_PATTERN = /^\\d{4}-\\d{2}-\\d{2}-[a-z0-9]+(?:-[a-z0-9]+)*$/;\nconst decodeIndex = Schema.decodeUnknownSync(Schema.Array(OrderBookIndexEntrySchema));\n\nexport function ordersDirectory(stateRoot: string): string {\n return join(stateRoot, 'orders');\n}\n\nexport function orderBookPath(stateRoot: string, bookId: string): string {\n if (!BOOK_ID_PATTERN.test(bookId)) {\n throw new Error(`Invalid order book id: ${bookId}`);\n }\n return join(ordersDirectory(stateRoot), `${bookId}.json`);\n}\n\nexport function orderBookIndexPath(stateRoot: string): string {\n return join(ordersDirectory(stateRoot), 'index.json');\n}\n\nexport function backlogSequencePath(stateRoot: string): string {\n return join(stateRoot, 'backlog', 'sequence.md');\n}\n\nexport async function readOrderBookAsync(stateRoot: string, bookId: string): Promise<OrderBook | null> {\n const path = orderBookPath(stateRoot, bookId);\n let value: unknown;\n try {\n value = JSON.parse(await readFile(path, 'utf8'));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return null;\n throw new Error(`Could not parse order book ${bookId}: ${error instanceof Error ? error.message : String(error)}`);\n }\n const parsed = parseOrderBookJson(value);\n if (!parsed.ok) throw new Error(`Could not parse order book ${bookId}: ${parsed.error}`);\n if (parsed.book.id !== bookId) throw new Error(`Order book ${bookId} contains mismatched id ${parsed.book.id}`);\n return parsed.book;\n}\n\nexport function readOrderBook(stateRoot: string, bookId: string): OrderBook | null {\n const path = orderBookPath(stateRoot, bookId);\n if (!existsSync(path)) return null;\n\n let value: unknown;\n try {\n value = JSON.parse(readFileSync(path, 'utf8'));\n } catch (error) {\n throw new Error(\n `Could not parse order book ${bookId}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n const parsed = parseOrderBookJson(value);\n if (!parsed.ok) throw new Error(`Could not parse order book ${bookId}: ${parsed.error}`);\n if (parsed.book.id !== bookId) {\n throw new Error(`Order book ${bookId} contains mismatched id ${parsed.book.id}`);\n }\n return parsed.book;\n}\n\nexport function readOrderBookIndex(stateRoot: string): readonly OrderBookIndexEntry[] {\n const path = orderBookIndexPath(stateRoot);\n if (!existsSync(path)) return [];\n\n try {\n return decodeIndex(JSON.parse(readFileSync(path, 'utf8')));\n } catch (error) {\n throw new Error(\n `Could not parse order book index: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nexport function listOrderBookIds(stateRoot: string): string[] {\n const indexed = readOrderBookIndex(stateRoot).map((entry) => entry.id);\n if (indexed.length > 0 || !existsSync(ordersDirectory(stateRoot))) return [...indexed];\n\n return readdirSync(ordersDirectory(stateRoot))\n .filter((name) => name !== 'index.json' && name.endsWith('.json'))\n .map((name) => name.slice(0, -'.json'.length))\n .filter((id) => BOOK_ID_PATTERN.test(id))\n .sort();\n}\n\nfunction preserveOperatorOwnedState(prior: OrderBook | null, next: OrderBook): OrderBook {\n if (!prior) return next;\n if (prior.id !== next.id) {\n throw new Error(`Order book id is immutable: ${prior.id} cannot become ${next.id}`);\n }\n\n const priorItems = new Map(prior.items.map((item) => [item.issue.toUpperCase(), item]));\n const items = next.items.map((item): OrderBookItem => {\n const existing = priorItems.get(item.issue.toUpperCase());\n if (!existing) return item;\n return {\n ...item,\n addedAt: existing.addedAt,\n addedBy: existing.addedBy,\n };\n });\n\n return { ...next, createdAt: prior.createdAt, items };\n}\n\nfunction indexEntry(book: OrderBook): OrderBookIndexEntry {\n return {\n id: book.id,\n name: book.name,\n status: book.status,\n runId: book.runId,\n updatedAt: book.updatedAt,\n };\n}\n\n/**\n * Physical state-store primitive used only by the orders writer. Domain callers\n * must mutate order books through writer.ts so the book and queue stay aligned.\n */\nexport async function writeOrderBookState(\n stateRoot: string,\n nextBook: OrderBook,\n queueOrder?: readonly string[],\n): Promise<OrderBook> {\n const prior = readOrderBook(stateRoot, nextBook.id);\n const book = preserveOperatorOwnedState(prior, nextBook);\n const bookPath = orderBookPath(stateRoot, book.id);\n const indexPath = orderBookIndexPath(stateRoot);\n const existingIndex = [...readOrderBookIndex(stateRoot)];\n const byId = new Map(existingIndex.map((entry) => [entry.id, entry]));\n byId.set(book.id, indexEntry(book));\n\n const requested = queueOrder ?? existingIndex.map((entry) => entry.id);\n const ids = [...requested];\n if (!ids.includes(book.id)) ids.push(book.id);\n for (const entry of existingIndex) {\n if (!ids.includes(entry.id)) ids.push(entry.id);\n }\n const index = ids.map((id) => byId.get(id)).filter((entry): entry is OrderBookIndexEntry => Boolean(entry));\n\n mkdirSync(dirname(bookPath), { recursive: true });\n writeFileSync(bookPath, `${JSON.stringify(book, null, 2)}\\n`, 'utf8');\n writeFileSync(indexPath, `${JSON.stringify(index, null, 2)}\\n`, 'utf8');\n\n queueAutoCommit({\n projectRoot: stateRoot,\n repoRoot: stateRoot,\n paths: [bookPath, indexPath],\n subject: `chore(state): update order book ${book.id}`,\n });\n const flushed = await Effect.runPromise(flushAutoCommits(stateRoot));\n if (flushed.errored || flushed.pushed === false) {\n throw new Error(`Failed to persist order book ${book.id}: ${flushed.reason ?? 'state commit failed'}`);\n }\n return book;\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { basename, dirname, join } from 'node:path';\nimport type { OrderBook } from '@overdeck/contracts';\nimport type { SequenceNode } from '../backlog/types.js';\nimport { parseSequenceMd } from '../backlog/sequence-io.js';\nimport { LEGACY_PARKED_LABELS, PARKED_LABEL } from '../backlog/pickup.js';\nimport { getOverdeckHome } from '../paths.js';\nimport { findProjectByPathSync, getProjectSync } from '../projects.js';\nimport { backlogSequencePath, listOrderBookIds, readOrderBook, readOrderBookAsync, readOrderBookIndex } from './io.js';\nimport type { OrderBookProgress, OrderIssueLookup, OrderIssueState } from './types.js';\n\nconst COMPLETE_STATUS = 'complete';\n\n/**\n * The issue prefix (e.g. \"PAN\") of the project that owns an orders state root,\n * or null when it cannot be determined. Migrated roots are\n * `<overdeckHome>/state/<projectKey>` — the basename is the projects.yaml key.\n * Legacy roots live inside the project checkout, where path containment is the\n * authoritative match (a checkout dir name can collide with another project's\n * yaml key, so the basename key lookup runs only for true migrated roots).\n */\nexport function issuePrefixForStateRoot(stateRoot: string): string | null {\n try {\n const byPath = findProjectByPathSync(stateRoot);\n if (byPath?.issue_prefix) return byPath.issue_prefix.toUpperCase();\n if (dirname(stateRoot) === join(getOverdeckHome(), 'state')) {\n const byKey = getProjectSync(basename(stateRoot));\n if (byKey?.issue_prefix) return byKey.issue_prefix.toUpperCase();\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Canonical form for an order-book issue reference: bare digits gain the\n * project prefix (\"2351\" → \"PAN-2351\"); anything else passes through\n * unchanged. Books written before the write door normalized on entry carry\n * bare numbers; every read-side consumer (validation, progress, membership,\n * dispatch) resolves them through this.\n */\nexport function normalizeOrderIssueId(stateRoot: string, issueId: string): string {\n if (!/^\\d+$/.test(issueId)) return issueId;\n const prefix = issuePrefixForStateRoot(stateRoot);\n return prefix ? `${prefix}-${issueId}` : issueId;\n}\n\nfunction normalizeBookIssues(stateRoot: string, book: OrderBook): OrderBook {\n const hasBare = book.items.some(\n (item) => /^\\d+$/.test(item.issue) || item.prereqs.some((prereq) => /^\\d+$/.test(prereq)),\n );\n if (!hasBare) return book;\n const prefix = issuePrefixForStateRoot(stateRoot);\n if (!prefix) return book;\n const expand = (id: string): string => (/^\\d+$/.test(id) ? `${prefix}-${id}` : id);\n return {\n ...book,\n items: book.items.map((item) => ({\n ...item,\n issue: expand(item.issue),\n prereqs: item.prereqs.map(expand),\n })),\n };\n}\n\ntype IssueServiceModule = typeof import('../../dashboard/server/services/issue-service-singleton.js');\nlet issueServiceModule: IssueServiceModule | null = null;\n\nfunction loadIssueServiceModuleSync(): IssueServiceModule {\n if (issueServiceModule) return issueServiceModule;\n // Lazy require avoids a static lib → dashboard server dependency.\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n issueServiceModule = require('../../dashboard/server/services/issue-service-singleton.js') as IssueServiceModule;\n return issueServiceModule;\n}\n\nasync function loadIssueServiceModule(): Promise<IssueServiceModule> {\n if (issueServiceModule) return issueServiceModule;\n issueServiceModule = await import('../../dashboard/server/services/issue-service-singleton.js');\n return issueServiceModule;\n}\n\nfunction labelNames(issue: Record<string, unknown>): string[] {\n const labels = Array.isArray(issue.labels) ? issue.labels : [];\n return labels\n .map((label) =>\n typeof label === 'string'\n ? label\n : typeof label === 'object' && label !== null && typeof (label as { name?: unknown }).name === 'string'\n ? (label as { name: string }).name\n : '',\n )\n .filter(Boolean)\n .map((label) => label.toLowerCase());\n}\n\nfunction issueIdentifier(issue: Record<string, unknown>): string {\n for (const key of ['identifier', 'issueId', 'id']) {\n const value = issue[key];\n if (typeof value === 'string' && value) return value.toUpperCase();\n }\n return '';\n}\n\nfunction issueIsClosed(issue: Record<string, unknown>): boolean {\n const values = [issue.canonicalStatus, issue.status, issue.state]\n .map((value) => (typeof value === 'string' ? value.toLowerCase().replace(/[ -]/g, '_') : ''));\n return values.some((value) =>\n ['done', 'completed', 'closed', 'canceled', 'cancelled'].includes(value),\n );\n}\n\nexport const liveOrderIssueLookup: OrderIssueLookup = (issueIds) => {\n const wanted = new Set(issueIds.map((id) => id.toUpperCase()));\n const result = new Map<string, OrderIssueState>();\n try {\n const { getSharedIssueService } = loadIssueServiceModuleSync();\n const issues = getSharedIssueService().getIssues({ cycle: 'all', includeCompleted: true }) as Array<Record<string, unknown>>;\n for (const issue of issues) {\n const id = issueIdentifier(issue);\n if (!wanted.has(id)) continue;\n const labels = labelNames(issue);\n const closed = issueIsClosed(issue);\n result.set(id, {\n issue: id,\n open: !closed,\n parked: labels.includes(PARKED_LABEL) || LEGACY_PARKED_LABELS.some((label) => labels.includes(label)),\n });\n }\n } catch {\n // A non-server caller receives missing issue state and validation blocks safely.\n }\n return result;\n};\n\nexport async function ensureOrderIssueStore(): Promise<void> {\n const { startSharedIssueService } = await loadIssueServiceModule();\n await startSharedIssueService({ skipPolling: true });\n}\n\nexport function orderIssueStoreStatus(): { started: boolean; issueCount: number } {\n try {\n const { getSharedIssueService, isSharedIssueServiceStarted } = loadIssueServiceModuleSync();\n const started = isSharedIssueServiceStarted();\n const issueCount = getSharedIssueService().getIssues({ cycle: 'all', includeCompleted: true }).length as number;\n return { started, issueCount };\n } catch {\n return { started: false, issueCount: 0 };\n }\n}\n\n/** The sole order-book read door. */\nexport function listBooks(stateRoot: string): OrderBook[] {\n return listOrderBookIds(stateRoot).map((id) => {\n const book = readOrderBook(stateRoot, id);\n if (!book) throw new Error(`Order book index references missing book ${id}`);\n return normalizeBookIssues(stateRoot, book);\n });\n}\n\nexport function getBook(stateRoot: string, bookId: string): OrderBook | null {\n const book = readOrderBook(stateRoot, bookId);\n return book ? normalizeBookIssues(stateRoot, book) : null;\n}\n\nexport function getBookAsync(stateRoot: string, bookId: string): Promise<OrderBook | null> {\n return readOrderBookAsync(stateRoot, bookId).then((book) => (book ? normalizeBookIssues(stateRoot, book) : null));\n}\n\n/** The first 'ready' book in index.json queue order, or null if none is ready. */\nexport function firstReadyBookInQueue(stateRoot: string): OrderBook | null {\n for (const entry of readOrderBookIndex(stateRoot)) {\n const book = getBook(stateRoot, entry.id);\n if (book?.status === 'ready') return book;\n }\n return null;\n}\n\nexport function membership(stateRoot: string): Map<string, string> {\n const result = new Map<string, string>();\n for (const book of listBooks(stateRoot)) {\n if (book.status === COMPLETE_STATUS) continue;\n for (const item of book.items) {\n const issue = item.issue.toUpperCase();\n const existing = result.get(issue);\n if (existing && existing !== book.id) {\n throw new Error(`Issue ${issue} belongs to multiple non-complete order books: ${existing}, ${book.id}`);\n }\n result.set(issue, book.id);\n }\n }\n return result;\n}\n\nexport function backlogCandidates(stateRoot: string, limit: number): SequenceNode[] {\n if (limit <= 0) return [];\n const path = backlogSequencePath(stateRoot);\n if (!existsSync(path)) return [];\n const parsed = parseSequenceMd(readFileSync(path, 'utf8'));\n if (!parsed.ok) throw new Error(`Could not parse backlog sequence: ${parsed.error}`);\n\n const assigned = membership(stateRoot);\n return [...parsed.doc.nodes]\n .sort((a, b) => a.rank - b.rank)\n .filter((node) => !assigned.has(node.issue.toUpperCase()))\n .slice(0, limit);\n}\n\nexport function computeBookProgress(\n book: OrderBook,\n issueLookup: OrderIssueLookup = liveOrderIssueLookup,\n): OrderBookProgress {\n const state = issueLookup(book.items.map((item) => item.issue));\n const items = book.items.map((item) => {\n const issue = state.get(item.issue.toUpperCase());\n const closed = issue ? !issue.open : false;\n const parked = issue?.parked ?? false;\n return {\n issue: item.issue,\n lane: item.lane,\n order: item.order,\n closed,\n parked,\n terminal: closed || parked,\n };\n });\n return {\n bookId: book.id,\n total: items.length,\n landed: items.filter((item) => item.closed).length,\n items,\n drained: items.every((item) => item.terminal),\n };\n}\n","import type {\n OrderBook,\n OrderBookItem,\n OrderBookLane,\n OrderBookSettings,\n OrderBookStatus,\n} from '@overdeck/contracts';\nimport { firstReadyBookInQueue, getBook, listBooks, membership, normalizeOrderIssueId } from './resolver.js';\nimport { writeOrderBookState } from './io.js';\n\nexport interface CreateOrderBookInput {\n id: string;\n name: string;\n settings?: Partial<OrderBookSettings>;\n createdAt?: string;\n}\n\nexport type NewOrderBookItem = Omit<OrderBookItem, 'addedAt' | 'addedBy'> &\n Partial<Pick<OrderBookItem, 'addedAt' | 'addedBy'>>;\n\nfunction timestamp(value?: string): string {\n return value ?? new Date().toISOString();\n}\n\nfunction requireBook(stateRoot: string, bookId: string): OrderBook {\n const book = getBook(stateRoot, bookId);\n if (!book) throw new Error(`Order book not found: ${bookId}`);\n return book;\n}\n\nfunction normalizeLaneOrder(items: readonly OrderBookItem[]): OrderBookItem[] {\n const laneA = items.filter((item) => item.lane === 'A').sort((a, b) => a.order - b.order);\n const laneB = items.filter((item) => item.lane === 'B').sort((a, b) => a.order - b.order);\n return [...laneA.map((item, index) => ({ ...item, order: index + 1 })), ...laneB.map((item, index) => ({ ...item, order: index + 1 }))];\n}\n\nfunction updated(book: OrderBook, changes: Partial<OrderBook>, at?: string): OrderBook {\n return { ...book, ...changes, id: book.id, createdAt: book.createdAt, updatedAt: timestamp(at) };\n}\n\n/** The sole order-book write door. */\nexport async function createBook(\n stateRoot: string,\n input: CreateOrderBookInput,\n): Promise<OrderBook> {\n if (getBook(stateRoot, input.id)) throw new Error(`Order book already exists: ${input.id}`);\n const at = timestamp(input.createdAt);\n const settings: OrderBookSettings = {\n laneAConcurrency: input.settings?.laneAConcurrency ?? 1,\n briefOverlay: input.settings?.briefOverlay,\n posture: input.settings?.posture ?? 'open',\n postureSetAt: input.settings?.postureSetAt,\n postureSetBy: input.settings?.postureSetBy,\n postureReason: input.settings?.postureReason,\n };\n if (!Number.isInteger(settings.laneAConcurrency) || settings.laneAConcurrency < 1) {\n throw new Error('laneAConcurrency must be a positive integer');\n }\n return writeOrderBookState(stateRoot, {\n id: input.id,\n name: input.name,\n status: 'draft',\n settings,\n items: [],\n createdAt: at,\n updatedAt: at,\n });\n}\n\nexport async function renameBook(\n stateRoot: string,\n bookId: string,\n name: string,\n at?: string,\n): Promise<OrderBook> {\n if (!name.trim()) throw new Error('Order book name cannot be empty');\n const book = requireBook(stateRoot, bookId);\n return writeOrderBookState(stateRoot, updated(book, { name: name.trim() }, at));\n}\n\nexport async function addItems(\n stateRoot: string,\n bookId: string,\n items: readonly NewOrderBookItem[],\n actor: string,\n at?: string,\n): Promise<OrderBook> {\n const book = requireBook(stateRoot, bookId);\n const existing = new Set(book.items.map((item) => item.issue.toUpperCase()));\n const assigned = membership(stateRoot);\n const addedAt = timestamp(at);\n const additions: OrderBookItem[] = [];\n for (const item of items) {\n const issue = normalizeOrderIssueId(stateRoot, item.issue).toUpperCase();\n if (existing.has(issue) || additions.some((candidate) => candidate.issue.toUpperCase() === issue)) {\n throw new Error(`Issue ${issue} is already in order book ${bookId}`);\n }\n const otherBook = assigned.get(issue);\n if (otherBook && otherBook !== bookId) {\n throw new Error(`Issue ${issue} already belongs to non-complete order book ${otherBook}`);\n }\n additions.push({\n ...item,\n issue,\n prereqs: item.prereqs.map((prereq) => normalizeOrderIssueId(stateRoot, prereq).toUpperCase()),\n addedAt: item.addedAt ?? addedAt,\n addedBy: item.addedBy ?? actor,\n });\n }\n const nextItems = normalizeLaneOrder([...book.items, ...additions]);\n return writeOrderBookState(stateRoot, updated(book, { items: nextItems }, at));\n}\n\nexport async function removeItem(\n stateRoot: string,\n bookId: string,\n issueId: string,\n at?: string,\n): Promise<OrderBook> {\n const book = requireBook(stateRoot, bookId);\n const issue = normalizeOrderIssueId(stateRoot, issueId).toUpperCase();\n if (!book.items.some((item) => item.issue.toUpperCase() === issue)) {\n throw new Error(`Issue ${issue} is not in order book ${bookId}`);\n }\n const items = normalizeLaneOrder(book.items.filter((item) => item.issue.toUpperCase() !== issue));\n return writeOrderBookState(stateRoot, updated(book, { items }, at));\n}\n\nexport async function moveItem(\n stateRoot: string,\n bookId: string,\n issueId: string,\n lane: OrderBookLane,\n order: number,\n at?: string,\n): Promise<OrderBook> {\n const book = requireBook(stateRoot, bookId);\n const issue = normalizeOrderIssueId(stateRoot, issueId).toUpperCase();\n const moving = book.items.find((item) => item.issue.toUpperCase() === issue);\n if (!moving) throw new Error(`Issue ${issue} is not in order book ${bookId}`);\n if (!Number.isInteger(order) || order < 1) throw new Error('Order must be a positive integer');\n\n const remaining = book.items.filter((item) => item !== moving);\n const targetLane = remaining.filter((item) => item.lane === lane).sort((a, b) => a.order - b.order);\n targetLane.splice(Math.min(order - 1, targetLane.length), 0, { ...moving, lane, order });\n const otherLane = remaining.filter((item) => item.lane !== lane).sort((a, b) => a.order - b.order);\n const items = normalizeLaneOrder([...targetLane, ...otherLane]);\n return writeOrderBookState(stateRoot, updated(book, { items }, at));\n}\n\nexport async function setItemRequirements(\n stateRoot: string,\n bookId: string,\n issueId: string,\n requirements: { prereqs?: readonly string[]; reVerify?: boolean; planAtPickup?: boolean },\n at?: string,\n): Promise<OrderBook> {\n const book = requireBook(stateRoot, bookId);\n const issue = normalizeOrderIssueId(stateRoot, issueId).toUpperCase();\n let found = false;\n const items = book.items.map((item) => {\n if (item.issue.toUpperCase() !== issue) return item;\n found = true;\n return {\n ...item,\n prereqs: requirements.prereqs === undefined\n ? item.prereqs\n : [...new Set(requirements.prereqs.map((prereq) => normalizeOrderIssueId(stateRoot, prereq).toUpperCase()))],\n reVerify: requirements.reVerify ?? item.reVerify,\n planAtPickup: requirements.planAtPickup ?? item.planAtPickup,\n };\n });\n if (!found) throw new Error(`Issue ${issue} is not in order book ${bookId}`);\n return writeOrderBookState(stateRoot, updated(book, { items }, at));\n}\n\nexport async function setSettings(\n stateRoot: string,\n bookId: string,\n settings: Partial<OrderBookSettings>,\n at?: string,\n): Promise<OrderBook> {\n const book = requireBook(stateRoot, bookId);\n const next = { ...book.settings, ...settings };\n if (!Number.isInteger(next.laneAConcurrency) || next.laneAConcurrency < 1) {\n throw new Error('laneAConcurrency must be a positive integer');\n }\n return writeOrderBookState(stateRoot, updated(book, { settings: next }, at));\n}\n\nexport async function setStatus(\n stateRoot: string,\n bookId: string,\n status: OrderBookStatus,\n options: { runId?: string | null; at?: string } = {},\n): Promise<OrderBook> {\n const book = requireBook(stateRoot, bookId);\n if (status === 'running') {\n const running = listBooks(stateRoot).find((candidate) => candidate.status === 'running' && candidate.id !== bookId);\n if (running) throw new Error(`Order book ${running.id} is already running`);\n }\n const runId = options.runId === undefined ? book.runId : options.runId ?? undefined;\n return writeOrderBookState(stateRoot, updated(book, { status, runId }, options.at));\n}\n\nexport async function advanceQueue(\n stateRoot: string,\n completedBookId: string,\n at?: string,\n): Promise<OrderBook | null> {\n const current = requireBook(stateRoot, completedBookId);\n if (current.status !== 'complete') {\n await setStatus(stateRoot, completedBookId, 'complete', { at });\n }\n return firstReadyBookInQueue(stateRoot);\n}\n","import type { Dirent } from 'node:fs';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { mkdir, readdir, readFile, rename, stat, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { Schema } from 'effect';\nimport { FlywheelRunId, FlywheelStatus, type FlywheelScopeValue, type OrderBook } from '@overdeck/contracts';\nimport {\n getFlywheelActiveRunId,\n isFlywheelGloballyPaused,\n setFlywheelActiveRunId,\n setFlywheelGloballyPaused,\n} from '../../../lib/overdeck/control-settings.js';\nimport { countAgentsByStatusRole } from '../../../lib/overdeck/agents.js';\nimport { computeBookProgress, getBook } from '../../../lib/orders/resolver.js';\nimport type { OrderBookProgress } from '../../../lib/orders/types.js';\nimport { setStatus as setOrderBookStatus } from '../../../lib/orders/writer.js';\nimport { findProjectByPathSync } from '../../../lib/projects.js';\nimport { resolveStateReadHomeSync } from '../../../lib/state-read-home.js';\n\nexport type FlywheelRunStatus = 'running' | 'paused' | 'complete' | 'aborted';\n\nexport interface FlywheelRunStateOptions {\n overdeckHome?: string;\n orderStateRoot?: (workspace: string) => string;\n getOrderBook?: typeof getBook;\n computeOrderProgress?: typeof computeBookProgress;\n setOrderStatus?: typeof setOrderBookStatus;\n}\n\nexport interface FlywheelRunListOptions extends FlywheelRunStateOptions {\n limit?: number;\n}\n\nexport interface FlywheelCurrentStatusOptions extends FlywheelRunStateOptions {\n activeRunId?: string | null;\n}\n\nexport interface FlywheelRunSummary {\n id: string;\n startedAt: string;\n status: FlywheelRunStatus;\n}\n\nexport interface FlywheelRunDetail extends FlywheelRunSummary {\n latest: FlywheelStatus | null;\n orders?: FlywheelStatus['orders'];\n /** PAN-1696: orchestrator scope this run was started/resumed with. */\n scope?: FlywheelStatus['scope'];\n paths: {\n latest: string;\n report?: string;\n openedPr?: string;\n };\n}\n\nexport interface FlywheelLaunchMetadata {\n version: 1;\n runId: string;\n workspace: string;\n briefPath: string;\n briefDisplayPath: string;\n briefOverlayPath?: string;\n orders?: { bookId: string };\n /**\n * PAN-1696: the orchestrator scope baked into this run's prompt at spawn.\n * Launch metadata is the right home rather than the status file, because the\n * orchestrator itself POSTs status updates and would otherwise overwrite it.\n */\n scope?: FlywheelScopeValue;\n}\n\nconst decodeFlywheelStatus = Schema.decodeUnknownSync(FlywheelStatus);\nconst decodeFlywheelRunId = Schema.decodeUnknownSync(FlywheelRunId);\nconst RUN_ID_PATTERN = /^RUN-(\\d+)$/;\nconst DEFAULT_RUNS_LIMIT = 20;\nconst MAX_RUNS_LIMIT = 100;\nconst RUN_SUMMARY_CONCURRENCY = 4;\ntype FlywheelStatusSnapshot = FlywheelStatus | null;\ntype FlywheelStatusListener = (status: FlywheelStatusSnapshot) => void;\nconst flywheelStatusListeners = new Set<FlywheelStatusListener>();\n\nexport function subscribeLatestFlywheelStatus(listener: FlywheelStatusListener): () => void {\n flywheelStatusListeners.add(listener);\n return () => {\n flywheelStatusListeners.delete(listener);\n };\n}\n\nfunction publishLatestFlywheelStatus(status: FlywheelStatusSnapshot): void {\n for (const listener of flywheelStatusListeners) {\n listener(status);\n }\n}\n\nexport function publishFlywheelStatusCleared(): void {\n publishLatestFlywheelStatus(null);\n}\n\nexport function parseFlywheelRunId(runId: string): FlywheelRunId {\n return decodeFlywheelRunId(runId);\n}\n\nexport function isFlywheelRunId(runId: string): runId is FlywheelRunId {\n return RUN_ID_PATTERN.test(runId);\n}\n\nfunction runNumber(runId: string): number {\n const match = RUN_ID_PATTERN.exec(runId);\n return match ? Number(match[1]) : 0;\n}\n\nfunction normalizeLimit(limit: number | undefined): number {\n if (limit === undefined) return DEFAULT_RUNS_LIMIT;\n if (!Number.isFinite(limit) || limit <= 0) return DEFAULT_RUNS_LIMIT;\n return Math.min(Math.floor(limit), MAX_RUNS_LIMIT);\n}\n\nasync function mapWithConcurrency<T, R>(items: readonly T[], concurrency: number, mapper: (item: T) => Promise<R>): Promise<R[]> {\n const results: R[] = new Array(items.length);\n let index = 0;\n await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, async () => {\n while (index < items.length) {\n const current = index;\n index += 1;\n results[current] = await mapper(items[current]!);\n }\n }));\n return results;\n}\n\nexport function getFlywheelHome(options: FlywheelRunStateOptions = {}): string {\n return join(options.overdeckHome ?? process.env['OVERDECK_HOME'] ?? join(homedir(), '.overdeck'), 'flywheel');\n}\n\nexport function getFlywheelRunsDir(options: FlywheelRunStateOptions = {}): string {\n return join(getFlywheelHome(options), 'runs');\n}\n\nexport function getFlywheelRunDir(runId: string, options: FlywheelRunStateOptions = {}): string {\n return join(getFlywheelRunsDir(options), parseFlywheelRunId(runId));\n}\n\n// ─── Run cohort (PAN-2006 WI-7: drain-to-quiescence) ──────────────────────────\n// A Run commits to draining a frozen cohort snapshotted at start: everything\n// in-flight ∪ the auto-pickable issues in the current + next wave. The Run is\n// complete when every cohort member reaches a terminal state; issues picked up\n// mid-run (e.g. unblockers) do NOT extend the cohort.\n\n/** Persist the run's cohort (issue ids) at run start. */\nexport function saveRunCohort(runId: string, issueIds: readonly string[], options: FlywheelRunStateOptions = {}): void {\n const dir = getFlywheelRunDir(runId, options);\n mkdirSync(dir, { recursive: true });\n writeFileSync(join(dir, 'cohort.json'), JSON.stringify({ issueIds: [...issueIds], snapshotAt: new Date().toISOString() }, null, 2), 'utf-8');\n}\n\n/** Load the run's cohort issue ids, or null when no snapshot exists. */\nexport function loadRunCohort(runId: string, options: FlywheelRunStateOptions = {}): string[] | null {\n const path = join(getFlywheelRunDir(runId, options), 'cohort.json');\n if (!existsSync(path)) return null;\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf-8')) as { issueIds?: unknown };\n return Array.isArray(parsed.issueIds) ? parsed.issueIds.filter((x): x is string => typeof x === 'string') : null;\n } catch {\n return null;\n }\n}\n\n/**\n * True when every cohort member is terminal (the Run has drained). Returns false\n * when there is no cohort snapshot or it is empty (nothing to declare drained).\n */\nexport function isCohortDrained(runId: string, isTerminal: (issueId: string) => boolean, options: FlywheelRunStateOptions = {}): boolean {\n const cohort = loadRunCohort(runId, options);\n if (!cohort || cohort.length === 0) return false;\n return cohort.every((id) => isTerminal(id));\n}\n\nexport async function nextFlywheelRunId(options: FlywheelRunStateOptions = {}): Promise<FlywheelRunId> {\n const runsDir = getFlywheelRunsDir(options);\n await mkdir(runsDir, { recursive: true });\n const entries = await readdir(runsDir, { withFileTypes: true });\n const maxRunNumber = entries.reduce((max, entry) => {\n if (!entry.isDirectory()) return max;\n const match = RUN_ID_PATTERN.exec(entry.name);\n if (!match) return max;\n return Math.max(max, Number(match[1]));\n }, 0);\n return parseFlywheelRunId(`RUN-${maxRunNumber + 1}`);\n}\n\nasync function writeJsonAtomic(path: string, payload: unknown): Promise<string> {\n const tmpPath = join(dirname(path), `.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`);\n await mkdir(dirname(path), { recursive: true });\n await writeFile(tmpPath, `${JSON.stringify(payload, null, 2)}\\n`, 'utf8');\n await rename(tmpPath, path);\n return path;\n}\n\nexport function enrichFlywheelStatusWithOrders(\n status: FlywheelStatus,\n book: OrderBook,\n progress: OrderBookProgress,\n): FlywheelStatus {\n const terminalPipelineStatuses = new Set(['failed', 'merged', 'parked']);\n const inFlight = new Set(status.activePipeline\n .filter((item) => !terminalPipelineStatuses.has(item.status))\n .map((item) => item.issueId.toUpperCase()));\n const laneAInFlight = book.items\n .filter((item) => item.lane === 'A' && inFlight.has(item.issue.toUpperCase()))\n .sort((left, right) => left.order - right.order)\n .map((item) => item.issue);\n const laneBInFlight = book.items\n .filter((item) => item.lane === 'B' && inFlight.has(item.issue.toUpperCase()))\n .sort((left, right) => left.order - right.order)[0]?.issue;\n return {\n ...status,\n orders: {\n bookId: book.id,\n bookName: book.name,\n landed: progress.landed,\n total: progress.total,\n laneAInFlight,\n ...(laneBInFlight ? { laneBInFlight } : {}),\n drained: progress.drained,\n },\n };\n}\n\nasync function mechanicallyEnrichOrdersStatus(\n status: FlywheelStatus,\n options: FlywheelRunStateOptions,\n): Promise<FlywheelStatus> {\n const launch = await readFlywheelLaunchMetadata(status.runId, options);\n // PAN-1696: scope is server-owned. Always restamp it from launch metadata,\n // dropping whatever the payload claimed, so a status POST from the\n // orchestrator can neither forge a scope nor silently erase the real one.\n const { scope: _claimedScope, ...unscoped } = status;\n const scoped: FlywheelStatus = launch?.scope ? { ...unscoped, scope: launch.scope } : unscoped;\n if (!launch?.orders) {\n const { orders: _untrustedOrders, ...booklessStatus } = scoped;\n return booklessStatus;\n }\n const stateRoot = options.orderStateRoot?.(launch.workspace) ?? (() => {\n const project = findProjectByPathSync(launch.workspace);\n if (!project) throw new Error(`No configured project contains orders-bound Flywheel workspace ${launch.workspace}`);\n return resolveStateReadHomeSync(project).root;\n })();\n const book = (options.getOrderBook ?? getBook)(stateRoot, launch.orders.bookId);\n if (!book) throw new Error(`Flywheel run ${status.runId} references missing order book ${launch.orders.bookId}`);\n const progress = (options.computeOrderProgress ?? computeBookProgress)(book);\n if (progress.drained && book.status === 'running') {\n await (options.setOrderStatus ?? setOrderBookStatus)(stateRoot, book.id, 'drained', { runId: book.runId });\n }\n return enrichFlywheelStatusWithOrders(scoped, book, progress);\n}\n\nexport async function writeLatestFlywheelStatus(status: FlywheelStatus, options: FlywheelRunStateOptions = {}): Promise<string> {\n const enriched = await mechanicallyEnrichOrdersStatus(status, options);\n const latestPath = join(getFlywheelRunDir(status.runId, options), 'latest.json');\n await writeJsonAtomic(latestPath, enriched);\n publishLatestFlywheelStatus(enriched);\n return latestPath;\n}\n\nfunction decodeLaunchMetadata(payload: unknown): FlywheelLaunchMetadata {\n if (typeof payload !== 'object' || payload === null) throw new Error('Invalid Flywheel launch metadata');\n const record = payload as Record<string, unknown>;\n if (record.version !== 1) throw new Error('Invalid Flywheel launch metadata version');\n for (const key of ['runId', 'workspace', 'briefPath', 'briefDisplayPath']) {\n if (typeof record[key] !== 'string' || !record[key]) throw new Error(`Invalid Flywheel launch metadata: ${key}`);\n }\n if (record.briefOverlayPath !== undefined && (typeof record.briefOverlayPath !== 'string' || !record.briefOverlayPath)) {\n throw new Error('Invalid Flywheel launch metadata: briefOverlayPath');\n }\n if (record.orders !== undefined) {\n const orders = record.orders as Record<string, unknown>;\n if (!orders || typeof orders !== 'object' || typeof orders.bookId !== 'string' || !orders.bookId) {\n throw new Error('Invalid Flywheel launch metadata: orders.bookId');\n }\n }\n if (record.scope !== undefined && record.scope !== 'pan-only' && record.scope !== 'all-tracked-projects') {\n throw new Error('Invalid Flywheel launch metadata: scope');\n }\n return record as unknown as FlywheelLaunchMetadata;\n}\n\nexport async function writeFlywheelLaunchMetadata(metadata: FlywheelLaunchMetadata, options: FlywheelRunStateOptions = {}): Promise<string> {\n const runId = parseFlywheelRunId(metadata.runId);\n const launchPath = join(getFlywheelRunDir(runId, options), 'launch.json');\n return writeJsonAtomic(launchPath, { ...metadata, runId });\n}\n\nexport async function readFlywheelLaunchMetadata(runId: string, options: FlywheelRunStateOptions = {}): Promise<FlywheelLaunchMetadata | null> {\n const launchPath = join(getFlywheelRunDir(runId, options), 'launch.json');\n try {\n return decodeLaunchMetadata(JSON.parse(await readFile(launchPath, 'utf8')) as unknown);\n } catch (error) {\n const code = typeof error === 'object' && error !== null && 'code' in error ? error.code : undefined;\n if (code === 'ENOENT') return null;\n throw error;\n }\n}\n\nexport async function readLatestFlywheelStatus(runId: string, options: FlywheelRunStateOptions = {}): Promise<FlywheelStatus | null> {\n const latestPath = join(getFlywheelRunDir(runId, options), 'latest.json');\n try {\n const payload = JSON.parse(await readFile(latestPath, 'utf8')) as unknown;\n return decodeFlywheelStatus(payload);\n } catch (error) {\n const code = typeof error === 'object' && error !== null && 'code' in error ? error.code : undefined;\n if (code === 'ENOENT') return null;\n throw error;\n }\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n const info = await stat(path);\n return info.isFile();\n } catch (error) {\n const code = typeof error === 'object' && error !== null && 'code' in error ? error.code : undefined;\n if (code === 'ENOENT') return false;\n throw error;\n }\n}\n\nasync function deriveRunStatus(runDir: string, runId: string, activeRunId: string | null): Promise<FlywheelRunStatus> {\n if (await fileExists(join(runDir, 'aborted.json'))) return 'aborted';\n if (await fileExists(join(runDir, 'report.md'))) return 'complete';\n // PAN-2108: only the CURRENT active run can be live. A run that is no longer the\n // active run but has no terminal marker was abandoned — its orchestrator died or\n // was killed before writing report.md/aborted.json. It is NOT running; reporting\n // it as such lit the sidebar \"live\" badge for every stale run forever. Treat an\n // orphaned non-active run as aborted.\n if (activeRunId !== runId) return 'aborted';\n return isFlywheelGloballyPaused() ? 'paused' : 'running';\n}\n\nasync function summarizeRun(\n runId: string,\n options: FlywheelRunStateOptions,\n activeRunId: string | null,\n): Promise<FlywheelRunSummary> {\n const runDir = getFlywheelRunDir(runId, options);\n const latest = await readLatestFlywheelStatus(runId, options);\n const status = await deriveRunStatus(runDir, runId, activeRunId);\n return {\n id: runId,\n startedAt: latest?.startedAt ?? '',\n status,\n };\n}\n\nexport async function readCurrentLatestFlywheelStatus(options: FlywheelCurrentStatusOptions = {}): Promise<FlywheelStatus | null> {\n const activeRunId = options.activeRunId === undefined ? getFlywheelActiveRunId() : options.activeRunId;\n if (!activeRunId || !isFlywheelRunId(activeRunId)) return null;\n const activeRun = await getFlywheelRunDetail(activeRunId, options);\n return (activeRun?.status === 'running' || activeRun?.status === 'paused') ? activeRun.latest : null;\n}\n\nfunction selectLatestRunIds(entries: Dirent[], limit: number): string[] {\n const selected: string[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory() || !isFlywheelRunId(entry.name)) continue;\n selected.push(entry.name);\n selected.sort((a, b) => runNumber(b) - runNumber(a));\n if (selected.length > limit) selected.length = limit;\n }\n return selected;\n}\n\nexport async function listFlywheelRuns(options: FlywheelRunListOptions = {}): Promise<FlywheelRunSummary[]> {\n const runsDir = getFlywheelRunsDir(options);\n let entries: Dirent[];\n try {\n entries = await readdir(runsDir, { withFileTypes: true });\n } catch (error) {\n const code = typeof error === 'object' && error !== null && 'code' in error ? error.code : undefined;\n if (code === 'ENOENT') return [];\n throw error;\n }\n const runIds = selectLatestRunIds(entries, normalizeLimit(options.limit));\n const activeRunId = getFlywheelActiveRunId();\n const summaries = await mapWithConcurrency(runIds, RUN_SUMMARY_CONCURRENCY, (runId) => summarizeRun(runId, options, activeRunId));\n return summaries.sort((a, b) => b.startedAt.localeCompare(a.startedAt));\n}\n\n/**\n * PAN-1528/PAN-1908: overlay the flywheel capacity gauge from the indexed\n * agents table. This status path must not enumerate state.json files.\n */\nasync function countLiveWorkAgents(_options: FlywheelRunStateOptions = {}): Promise<number> {\n return countAgentsByStatusRole('running', 'work');\n}\n\nfunction withLiveAgentsActive(latest: FlywheelStatus, liveCount: number): FlywheelStatus {\n if (latest.system.agentsActive === liveCount) return latest;\n return {\n ...latest,\n system: {\n ...latest.system,\n agentsActive: liveCount,\n },\n };\n}\n\nexport async function getFlywheelRunDetail(runId: string, options: FlywheelCurrentStatusOptions = {}): Promise<FlywheelRunDetail | null> {\n const runDir = getFlywheelRunDir(runId, options);\n const latest = await readLatestFlywheelStatus(runId, options);\n if (!latest) return null;\n const activeRunId = options.activeRunId !== undefined ? options.activeRunId : getFlywheelActiveRunId();\n const status = await deriveRunStatus(runDir, runId, activeRunId);\n const reportPath = join(runDir, 'report.md');\n const openedPrPath = join(runDir, 'opened-pr.json');\n // PAN-1528: overlay the live work-agent count so the field reflects reality\n // rather than the orchestrator's stale initial value.\n const liveCount = await countLiveWorkAgents(options);\n return {\n id: runId,\n startedAt: latest.startedAt,\n status,\n latest: withLiveAgentsActive(latest, liveCount),\n ...(latest.orders ? { orders: latest.orders } : {}),\n // PAN-1696: surface the run's own scope on the detail payload too, so a\n // consumer reading run detail does not have to dig into `latest`.\n ...(latest.scope ? { scope: latest.scope } : {}),\n paths: {\n latest: join(runDir, 'latest.json'),\n ...((await fileExists(reportPath)) ? { report: reportPath } : {}),\n ...((await fileExists(openedPrPath)) ? { openedPr: openedPrPath } : {}),\n },\n };\n}\n\n// Clear the SQLite \"active run\" gate and the pause flag, and notify subscribers.\n// Exported so callers in CLI and dashboard share a single clearing primitive\n// (PAN-1245: gate previously cleared in three different places that drifted).\nexport function clearFlywheelGate(): void {\n setFlywheelActiveRunId(null);\n setFlywheelGloballyPaused(false);\n publishFlywheelStatusCleared();\n}\n\n// Single source of truth for \"is a flywheel run live?\". Reads the SQLite gate,\n// validates it against on-disk run state, and self-heals if the gate points at\n// a run that has already ended (report.md / aborted.json present), at a run\n// whose state was wiped, or at a malformed value. Both `pan flywheel start`\n// and the dashboard Start path consult this — they cannot disagree (PAN-1245).\nexport async function resolveLiveFlywheelRunId(options: FlywheelRunStateOptions = {}): Promise<string | null> {\n const candidate = getFlywheelActiveRunId();\n if (!candidate) return null;\n if (!isFlywheelRunId(candidate)) {\n clearFlywheelGate();\n return null;\n }\n const latest = await readLatestFlywheelStatus(candidate, options);\n if (!latest) {\n // The gate points at a run with no snapshot on disk — the run dir was\n // wiped or never fully initialized. Treat as dead.\n clearFlywheelGate();\n return null;\n }\n const runDir = getFlywheelRunDir(candidate, options);\n // `candidate` is the active run id (read above), so pass it as activeRunId.\n const status = await deriveRunStatus(runDir, candidate, candidate);\n if (status === 'complete' || status === 'aborted') {\n clearFlywheelGate();\n return null;\n }\n return candidate;\n}\n\n// Mark a flywheel run as aborted and clear the gate if it still points at this\n// run. Writes `aborted.json` so `deriveRunStatus` reports the run as aborted on\n// subsequent reads, mirroring the report.md → complete convention.\nexport async function abortFlywheelRun(runId: string, options: FlywheelRunStateOptions = {}): Promise<void> {\n const parsed = parseFlywheelRunId(runId);\n const abortedPath = join(getFlywheelRunDir(parsed, options), 'aborted.json');\n await writeJsonAtomic(abortedPath, { runId: parsed, abortedAt: new Date().toISOString() });\n if (getFlywheelActiveRunId() === parsed) {\n clearFlywheelGate();\n }\n}\n","import { exec } from 'node:child_process';\nimport { readFile, realpath } from 'node:fs/promises';\nimport { dirname, isAbsolute, relative, resolve, sep } from 'node:path';\nimport { promisify } from 'node:util';\n\nconst execAsync = promisify(exec);\n\nexport const DEFAULT_BRIEF_PATH = 'docs/flywheel-brief.md';\n\nfunction isInsideRoot(projectRoot: string, candidate: string): boolean {\n const relativePath = relative(projectRoot, candidate);\n return relativePath === '' || (!relativePath.startsWith('..') && !isAbsolute(relativePath));\n}\n\nexport function resolveFlywheelStartBriefPath(cwd: string, requestedPath?: string): { absolutePath: string; displayPath: string } {\n const rawPath = requestedPath?.trim() || DEFAULT_BRIEF_PATH;\n if (rawPath.includes('\\0')) throw new Error('Brief path is invalid');\n\n const root = resolve(cwd);\n const absolutePath = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);\n if (!isInsideRoot(root, absolutePath)) throw new Error('Brief path must stay inside the project root');\n\n const normalizedRoot = root.endsWith(sep) ? root : `${root}${sep}`;\n const displayPath = absolutePath === root ? '.' : relative(root, absolutePath);\n return { absolutePath, displayPath: absolutePath.startsWith(normalizedRoot) ? displayPath : absolutePath };\n}\n\nasync function assertExistingPathInsideRoot(projectRoot: string, candidate: string): Promise<void> {\n const [realRoot, realCandidate] = await Promise.all([realpath(projectRoot), realpath(candidate)]);\n if (!isInsideRoot(realRoot, realCandidate)) throw new Error('Brief path must stay inside the project root');\n}\n\nexport async function requireFlywheelBrief(cwd: string, requestedPath?: string): Promise<{ absolutePath: string; displayPath: string }> {\n const resolved = resolveFlywheelStartBriefPath(cwd, requestedPath);\n try {\n await assertExistingPathInsideRoot(cwd, resolved.absolutePath);\n await readFile(resolved.absolutePath, 'utf8');\n return resolved;\n } catch (error) {\n const code = typeof error === 'object' && error !== null && 'code' in error ? error.code : undefined;\n if (code === 'ENOENT') throw new Error(`Flywheel brief not found: ${resolved.displayPath}`);\n throw error;\n }\n}\n\n/**\n * The flywheel is a project-scoped singleton: it must run from the PRIMARY\n * worktree root, never a linked feature worktree. Every worktree contains\n * docs/flywheel-brief.md, so the brief check alone cannot catch a caller whose\n * shell happens to sit inside a workspaces/feature-* checkout, and an\n * orchestrator spawned there operates inside a live work agent's worktree.\n * A linked worktree is\n * detected by `git rev-parse --git-common-dir` resolving to the primary's\n * .git directory; outside a repo (or on failure) the cwd is kept and the\n * brief check reports its own error.\n */\n\nexport async function resolvePrimaryWorktreeRoot(cwd: string): Promise<string> {\n try {\n const { stdout } = await execAsync(\n 'git rev-parse --path-format=absolute --git-common-dir',\n { cwd, timeout: 5000 },\n );\n const commonDir = stdout.trim();\n if (commonDir.endsWith(`${sep}.git`)) return dirname(commonDir);\n return cwd;\n } catch {\n return cwd;\n }\n}\n","import { existsSync, readdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { getProjectPanPaths } from '../pan-dir/paths.js';\nimport { getReviewStatusSync } from '../review-status.js';\nimport type { ClassifyLookups } from './pickup.js';\n\n/**\n * Build the {@link ClassifyLookups} the shared pickup module needs from live project\n * state: labels (in-memory issue service), planned (readable xBRIEF spec), and\n * in-pipeline (review status / live workspace). Shared by the dashboard forecast\n * route and the Flywheel run-cohort snapshot so both classify issues identically\n * (PAN-2006 single source of truth). The issue service is lazy-required to avoid a\n * static lib → dashboard layering edge.\n */\nexport function buildClassifyLookups(\n projectRoot: string,\n opts: { labels?: (id: string) => readonly string[] } = {},\n): ClassifyLookups {\n // Labels come from the in-memory issue service (server-side). A CLI/sandbox process cannot\n // reach that singleton, so callers there must pass `opts.labels` (e.g. gh-derived) — without\n // it, a CLI would silently classify every issue as label-less, making ready/released/parked/\n // objection/vetoed/blocksMain all false (the `pan backlog forecast` undercount bug).\n const labelsByIssue = new Map<string, string[]>();\n if (!opts?.labels) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { getSharedIssueService } = require('../../dashboard/server/services/issue-service-singleton.js') as typeof import('../../dashboard/server/services/issue-service-singleton.js');\n for (const issue of getSharedIssueService().getIssues() as Array<Record<string, unknown>>) {\n const id = typeof issue['identifier'] === 'string' ? issue['identifier'].toUpperCase() : '';\n if (!id) continue;\n const raw = Array.isArray(issue['labels']) ? (issue['labels'] as unknown[]) : [];\n const names = raw\n .map((l) => (typeof l === 'string' ? l : ((l as { name?: string })?.name ?? '')))\n .filter((s): s is string => Boolean(s));\n labelsByIssue.set(id, names);\n }\n } catch { /* issue service not ready — treat as no labels */ }\n }\n\n const specsDir = getProjectPanPaths(projectRoot).specsDir;\n const specIssues = new Set<string>();\n if (existsSync(specsDir)) {\n for (const f of readdirSync(specsDir)) {\n const m = /^[\\d-]+-([A-Z]+-\\d+)-/i.exec(f);\n if (m) specIssues.add(m[1]!.toUpperCase());\n }\n }\n const workspacesDir = join(projectRoot, 'workspaces');\n return {\n labels: opts?.labels ?? ((id) => labelsByIssue.get(id.toUpperCase()) ?? []),\n isPlanned: (id) => {\n const u = id.toUpperCase();\n return specIssues.has(u);\n },\n isInPipeline: (id) => {\n const u = id.toUpperCase();\n const rs = getReviewStatusSync(u);\n return (rs !== null && rs.reviewStatus !== 'pending') || existsSync(join(workspacesDir, `feature-${id.toLowerCase()}`));\n },\n };\n}\n","import { existsSync, readFileSync, readdirSync } from 'node:fs';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { Effect, Schema } from 'effect';\nimport type { FlywheelRunId } from '@overdeck/contracts';\nimport type { AgentState } from '../agents.js';\nimport type { FlywheelScope, RoleEffort } from '../config-yaml.js';\nimport { getInternalTokenSync, INTERNAL_TOKEN_HEADER } from '../internal-token.js';\nimport { getProjectPanPaths } from '../pan-dir/paths.js';\nimport { getAgentDir, spawnRun, stopAgent } from '../agents.js';\nimport { parseSequenceMd } from '../backlog/sequence-io.js';\nimport { computePredictedConflictSignals, declaredIssueFootprint, pickFromSequence, type IssueFileFootprint } from '../flywheel-merge-order.js';\nimport { requireFlywheelBrief } from '../flywheel-start.js';\nimport { findProjectByPathSync, getProjectSwarmHotspots } from '../projects.js';\nimport { getBookAsync as getOrderBook } from '../orders/resolver.js';\nimport { resolveStateReadHomeSync } from '../state-read-home.js';\nimport type { XBriefDocument } from '../xbrief/types.js';\nimport {\n getFlywheelActiveRunId,\n isFlywheelAutoPickupBacklog,\n isFlywheelRequireUatBeforeMerge,\n setFlywheelActiveRunId,\n setFlywheelGloballyPaused,\n} from '../overdeck/control-settings.js';\nimport { abortFlywheelRun, readFlywheelLaunchMetadata, resolveLiveFlywheelRunId, saveRunCohort } from '../../dashboard/server/services/flywheel-run-state.js';\nimport { buildClassifyLookups } from '../backlog/lookups.js';\nimport { computeCohort } from '../backlog/pickup.js';\nimport { gatherProjectLensSignals } from '../pipeline-membership-gather.js';\nimport { resolvePipelineMembership, type PipelineMembership } from '../pipeline-membership.js';\nimport { buildResumeContract, type ResumeCause } from '../resume-contract.js';\n\nexport const FLYWHEEL_ORCHESTRATOR_AGENT_ID = 'flywheel-orchestrator';\n\nexport function isIssueInResolvedPipeline(issueId: string, memberships: PipelineMembership[]): boolean {\n return memberships.some((membership) =>\n membership.issueId.toUpperCase() === issueId.toUpperCase() && membership.inPipeline,\n );\n}\n\ninterface ActiveOrderBookIssuesDeps {\n activeRunId?: () => string | null;\n readLaunch?: typeof readFlywheelLaunchMetadata;\n stateRoot?: (projectRoot: string) => string | null;\n getBook?: typeof getOrderBook;\n}\n\nexport async function activeOrderBookIssues(\n projectRoot: string,\n runId?: string,\n deps: ActiveOrderBookIssuesDeps = {},\n): Promise<ReadonlySet<string>> {\n const activeRunId = runId ?? (deps.activeRunId ?? getFlywheelActiveRunId)();\n if (!activeRunId) return new Set();\n const launch = await (deps.readLaunch ?? readFlywheelLaunchMetadata)(activeRunId);\n const bookId = launch?.orders?.bookId;\n if (!bookId) return new Set();\n const stateRoot = deps.stateRoot?.(projectRoot) ?? (() => {\n const project = findProjectByPathSync(projectRoot);\n return project ? resolveStateReadHomeSync(project).root : null;\n })();\n if (!stateRoot) return new Set();\n const book = await (deps.getBook ?? getOrderBook)(stateRoot, bookId);\n return new Set(book?.items.map((item) => item.issue.toUpperCase()) ?? []);\n}\n\nconst FlywheelRunIdSchema = Schema.String.check(Schema.isPattern(/^RUN-\\d+$/));\nconst decodeFlywheelRunId = Schema.decodeUnknownSync(FlywheelRunIdSchema);\n\nexport interface FlywheelLifecycleOptions {\n runId?: FlywheelRunId;\n workspace?: string;\n briefPath?: string;\n briefOverlayPath?: string;\n briefOverlayContent?: string;\n prompt?: string;\n model?: string;\n harness?: 'claude-code' | 'ohmypi' | 'codex' | 'acp' | 'kimi-code' | 'opencode' | 'muse';\n effort?: RoleEffort;\n minAgents?: number;\n maxAgents?: number;\n scope?: FlywheelScope;\n autoPickupBacklog?: boolean;\n requireUatBeforeMerge?: boolean;\n env?: NodeJS.ProcessEnv;\n resumeSessionId?: string;\n resumeCause?: ResumeCause;\n}\n\nexport interface FlywheelPauseResult {\n activeRunId: string | null;\n}\n\nexport interface FlywheelResumeResult {\n activeRunId: string;\n agent: AgentState;\n}\n\nfunction parseRunId(runId: string): FlywheelRunId {\n return decodeFlywheelRunId(runId);\n}\n\nfunction defaultFlywheelRunId(): FlywheelRunId {\n return parseRunId(`RUN-${Date.now()}`);\n}\n\nfunction internalDashboardOrigin(): string {\n const port = Number.parseInt(process.env['API_PORT'] ?? process.env['PORT'] ?? '3011', 10);\n return process.env['OVERDECK_INTERNAL_DASHBOARD_URL'] ?? `http://127.0.0.1:${port}`;\n}\n\nasync function fetchIssueRowsFromDashboard(): Promise<Array<{ ref?: string; identifier?: string; labels?: string[]; author?: string; assignee?: { name?: string } | string }>> {\n const dashboardOrigin = internalDashboardOrigin();\n const token = getInternalTokenSync();\n if (!token) {\n console.error('[flywheel] Cannot load issue metadata: internal dashboard token is unavailable');\n return [];\n }\n try {\n const response = await fetch(new URL('/api/issues?cycle=all&includeCompleted=true', dashboardOrigin), {\n headers: {\n [INTERNAL_TOKEN_HEADER]: token,\n origin: dashboardOrigin,\n },\n });\n if (!response.ok) {\n console.error(`[flywheel] Cannot load issue metadata from dashboard: HTTP ${response.status}`);\n return [];\n }\n const body = await response.json();\n if (!Array.isArray(body)) {\n console.error('[flywheel] Cannot load issue metadata from dashboard: response was not an array');\n return [];\n }\n return body as Array<{ ref?: string; identifier?: string; labels?: string[]; author?: string; assignee?: { name?: string } | string }>;\n } catch (error) {\n console.error('[flywheel] Cannot load issue metadata from dashboard:', error);\n return [];\n }\n}\n\nasync function flywheelRunConfigurationSection(options: FlywheelLifecycleOptions, runId?: string): Promise<string> {\n const configLines = [\n options.harness ? `Harness: ${options.harness}` : undefined,\n options.effort ? `Effort: ${options.effort}` : undefined,\n options.minAgents ? `Min concurrent agents (target): ${options.minAgents}` : undefined,\n options.maxAgents ? `Max concurrent agents (ceiling): ${options.maxAgents}` : undefined,\n options.scope ? `Scope: ${options.scope}` : undefined,\n typeof options.autoPickupBacklog === 'boolean'\n ? `Auto-pickup backlog: ${options.autoPickupBacklog}`\n : undefined,\n typeof options.requireUatBeforeMerge === 'boolean'\n ? `Require UAT before merge: ${options.requireUatBeforeMerge}`\n : undefined,\n ].filter(Boolean).join('\\n');\n\n let sequenceSection = '';\n const projectRoot = process.cwd();\n const orderBookIssues = await activeOrderBookIssues(projectRoot, runId);\n if (options.autoPickupBacklog || orderBookIssues.size > 0) {\n const seqPath = join(projectRoot, '.pan', 'backlog', 'sequence.md');\n if (existsSync(seqPath)) {\n try {\n const md = readFileSync(seqPath, 'utf-8');\n const parsed = parseSequenceMd(md);\n if (parsed.ok) {\n // Build issue lookups through the dashboard read path. A deacon child\n // cannot safely import the dashboard's per-process issue singleton.\n type IssueRow = { ref?: string; identifier?: string; labels?: string[]; author?: string; assignee?: { name?: string } | string };\n const getIssueRows = async (): Promise<IssueRow[]> => fetchIssueRowsFromDashboard();\n const issueRowMap = new Map<string, IssueRow>(\n (await getIssueRows()).map((i) => [i.ref ?? i.identifier ?? '', i]),\n );\n\n const issueLabelsLookup = (issueId: string): string[] =>\n issueRowMap.get(issueId)?.labels ?? [];\n\n const AUTHORIZED_AUTHORS = new Set(['eltmon', 'panopticon-agent[bot]']);\n const isAuthorizedIssue = (issueId: string): boolean => {\n const row = issueRowMap.get(issueId);\n if (!row) return false; // unknown issue — skip (safe default)\n if (row.author && AUTHORIZED_AUTHORS.has(row.author)) return true;\n const assigneeName = typeof row.assignee === 'string' ? row.assignee : row.assignee?.name;\n return assigneeName === 'eltmon';\n };\n\n const paths = getProjectPanPaths(projectRoot);\n const specsDir = paths.specsDir;\n const issuesWithSpecs = new Set<string>();\n const declaredFootprints: IssueFileFootprint[] = [];\n if (existsSync(specsDir)) {\n for (const f of readdirSync(specsDir)) {\n const match = /^[\\d-]+-([A-Z]+-\\d+)-/i.exec(f);\n if (!match) continue;\n const issueId = match[1]!.toUpperCase();\n issuesWithSpecs.add(issueId);\n try {\n const doc = JSON.parse(readFileSync(join(specsDir, f), 'utf-8')) as XBriefDocument;\n declaredFootprints.push(declaredIssueFootprint(issueId, doc));\n } catch {\n // A malformed spec should not break flywheel startup; planned-ness\n // still comes from the filename and the normal plan gate handles parse errors.\n }\n }\n }\n const projectConfig = findProjectByPathSync(projectRoot);\n const predictedConflictSignals = computePredictedConflictSignals(declaredFootprints, {\n hotspots: getProjectSwarmHotspots(projectConfig),\n });\n const isReadyOrHasPrd = (issueId: string): boolean => {\n const id = issueId.toUpperCase();\n if (issuesWithSpecs.has(id)) return true;\n return existsSync(join(paths.draftsDir, `${id}.md`));\n };\n const membershipAvailable = Boolean(projectConfig?.github_repo);\n const memberships = projectConfig?.github_repo\n ? (await gatherProjectLensSignals(projectConfig)).map(resolvePipelineMembership)\n : [];\n const isInPipeline = (issueId: string): boolean =>\n membershipAvailable ? isIssueInResolvedPipeline(issueId, memberships) : true;\n\n const top10 = parsed.doc.nodes.slice(0, 10).map((n) =>\n ` #${n.rank} ${n.issue}: ${n.why.slice(0, 100)} [gate:${n.gate}]`,\n );\n const nextPick = pickFromSequence(parsed.doc.nodes, {\n issueLabels: issueLabelsLookup,\n isAuthorizedIssue,\n isReadyOrHasPrd,\n isInPipeline,\n requireReady: true,\n autoPickupBacklog: options.autoPickupBacklog,\n activeBookMembership: orderBookIssues,\n predictedConflictSignals,\n });\n let nextLine: string;\n let pickInstruction: string;\n if (!membershipAvailable) {\n nextLine = 'MEMBERSHIP UNAVAILABLE: project has no GitHub repository; auto-pickup is disabled';\n 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.';\n } else if (!nextPick) {\n nextLine = 'No eligible issue found in sequence — fall back to normal priority';\n pickInstruction = '';\n } else if (nextPick.planning === 'interactive') {\n // FR-17: interactive planning requires operator presence — must NOT be auto-started\n nextLine = `NEEDS OPERATOR ACTION: ${nextPick.issueId} (rank ${nextPick.rank}) has planning=interactive — do NOT auto-start; operator must run 'pan plan ${nextPick.issueId}'`;\n 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.`;\n } else {\n const conflictSuffix = typeof nextPick.predictedConflictCount === 'number'\n ? `, predictedConflicts=${nextPick.predictedConflictCount}${nextPick.predictedConflictsWith?.length ? ` with ${nextPick.predictedConflictsWith.join(', ')}` : ''}`\n : '';\n nextLine = `MUST start next: ${nextPick.issueId} (rank ${nextPick.rank}, planning=${nextPick.planning}${conflictSuffix})`;\n 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.`;\n }\n sequenceSection = `\\n\\nBacklog sequence (${parsed.doc.nodes.length} issues ranked):\\n${top10.join('\\n')}\\n${nextLine}${pickInstruction}`;\n }\n } catch {\n // sequence.md exists but couldn't be parsed — skip enrichment\n }\n }\n }\n\n return (configLines ? `\\n\\nRun configuration:\\n${configLines}` : '') + sequenceSection;\n}\n\nasync function defaultFlywheelPrompt(runId: string, options: FlywheelLifecycleOptions, briefContent?: string): Promise<string> {\n const configSection = await flywheelRunConfigurationSection(options, runId);\n const briefSection = options.briefPath\n ? `\\n\\nBrief path: ${options.briefPath}\\n\\n${briefContent ?? ''}`\n : '';\n return `FLYWHEEL ORCHESTRATOR TASK for ${runId}:\n\nRun 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.${configSection}${briefSection}`;\n}\n\nfunction getLocalFlywheelRunDir(runId: string): string {\n const overdeckHome = process.env.OVERDECK_HOME ?? join(homedir(), '.overdeck');\n return join(overdeckHome, 'flywheel', 'runs', runId);\n}\n\nexport async function saveResumeSessionId(runId: string, sessionId: string): Promise<void> {\n const runDir = getLocalFlywheelRunDir(runId);\n await mkdir(runDir, { recursive: true });\n await writeFile(\n join(runDir, 'resume-session.json'),\n JSON.stringify({ sessionId, pausedAt: new Date().toISOString() }),\n 'utf-8',\n );\n}\n\nexport async function loadResumeSessionId(runId: string): Promise<string | null> {\n try {\n const raw = await readFile(join(getLocalFlywheelRunDir(runId), 'resume-session.json'), 'utf-8');\n const parsed = JSON.parse(raw) as { sessionId?: unknown };\n return typeof parsed.sessionId === 'string' ? parsed.sessionId : null;\n } catch {\n return null;\n }\n}\n\nexport function isFlywheelDevcontainerRuntime(env: NodeJS.ProcessEnv = process.env): boolean {\n const disabledDeacon = env.OVERDECK_DISABLE_DEACON?.toLowerCase();\n if (disabledDeacon === '1' || disabledDeacon === 'true') return true;\n\n const hostname = env.HOSTNAME?.toLowerCase() ?? '';\n return hostname.includes('devcontainer') || hostname.startsWith('api-feature-') || hostname.startsWith('workspace-');\n}\n\n/**\n * Resume prompt. PAN-2006 FR-8: re-attach the standing brief on resume so its\n * directives (pipeline-unblock override, never-block, red-main-first) survive a\n * resume + context compaction — the pre-PAN-2006 resume prompt only pointed at\n * FLYWHEEL-STATE.md and a long-running orchestrator could drift off-brief.\n */\nexport function buildFlywheelResumePrompt(configSection: string, briefContent?: string, cause: ResumeCause = 'system'): string {\n const base =\n `FLYWHEEL RESUME: ${buildResumeContract(cause)} Resume the tick loop from your prior ` +\n 'state, run a full tick now, and call ScheduleWakeup(delaySeconds:1000) to arm the next tick. ' +\n 'Check `docs/FLYWHEEL-STATE.md` and the latest status snapshot for context.';\n const brief = briefContent\n ? `\\n\\n--- Standing brief (re-read it — it governs pickup, unblocking, and never-block) ---\\n\\n${briefContent}`\n : '';\n return `${base}${configSection}${brief}`;\n}\n\nfunction withOrderBookBriefOverlay(\n briefContent: string | undefined,\n overlayPath: string | undefined,\n overlayContent: string | undefined,\n): string | undefined {\n if (!overlayContent) return briefContent;\n const standard = briefContent?.trimEnd() ?? '';\n const overlay = `--- Order-book brief overlay${overlayPath ? `: ${overlayPath}` : ''} ---\\n\\n${overlayContent.trim()}`;\n return standard ? `${standard}\\n\\n${overlay}` : overlay;\n}\n\nexport async function spawnFlywheelAgent(runId: string, options: FlywheelLifecycleOptions = {}): Promise<AgentState> {\n const workspace = options.workspace ?? process.cwd();\n // Re-read the brief on every spawn (fresh AND resume) so its directives survive\n // resume/compaction. Default to the standard brief path when none is supplied.\n const briefPath = options.briefPath ?? join(workspace, 'docs', 'flywheel-brief.md');\n let briefOverlayPath = options.briefOverlayPath;\n let briefOverlayContent = options.briefOverlayContent;\n if (briefOverlayPath && briefOverlayContent === undefined) {\n const resolvedOverlay = await requireFlywheelBrief(workspace, briefOverlayPath);\n briefOverlayPath = resolvedOverlay.displayPath;\n briefOverlayContent = await readFile(resolvedOverlay.absolutePath, 'utf8');\n }\n const briefContent = withOrderBookBriefOverlay(\n await readFile(briefPath, 'utf8').catch(() => undefined),\n briefOverlayPath,\n briefOverlayContent,\n );\n const prompt = options.resumeSessionId\n ? buildFlywheelResumePrompt(await flywheelRunConfigurationSection(options, runId), briefContent, options.resumeCause)\n : (options.prompt ?? (await defaultFlywheelPrompt(runId, { ...options, briefPath }, briefContent)));\n return spawnRun(runId, 'flywheel', {\n agentId: FLYWHEEL_ORCHESTRATOR_AGENT_ID,\n workspace,\n prompt,\n model: options.model,\n harness: options.harness,\n effort: options.effort,\n allowHost: true,\n registerConversation: true,\n resumeSessionId: options.resumeSessionId,\n flywheelRunId: runId,\n startedBy: `flywheel:${runId}`,\n });\n}\n\nfunction withFlywheelAutonomyOptions(options: FlywheelLifecycleOptions): FlywheelLifecycleOptions {\n return {\n ...options,\n autoPickupBacklog: options.autoPickupBacklog ?? isFlywheelAutoPickupBacklog(),\n requireUatBeforeMerge: options.requireUatBeforeMerge ?? isFlywheelRequireUatBeforeMerge(),\n };\n}\n\nexport async function spawnFlywheel(options: FlywheelLifecycleOptions = {}): Promise<AgentState> {\n if (isFlywheelDevcontainerRuntime(options.env)) {\n throw new Error('Refusing to spawn flywheel-orchestrator inside a workspace devcontainer');\n }\n\n // Self-healing gate check (PAN-1245): if the SQLite gate points at a run\n // that has already ended (report.md/aborted.json) or whose on-disk state is\n // gone (post-reboot, post-wipe), resolveLiveFlywheelRunId clears the gate\n // and returns null. Only a genuinely live prior run blocks a new start.\n const activeRunId = await resolveLiveFlywheelRunId();\n if (activeRunId) {\n throw new Error(`Flywheel run ${activeRunId} is already active; pause, resume, or report it before starting another run`);\n }\n\n const runId = options.runId ? parseRunId(options.runId) : defaultFlywheelRunId();\n const agent = await spawnFlywheelAgent(runId, withFlywheelAutonomyOptions(options));\n setFlywheelActiveRunId(runId);\n setFlywheelGloballyPaused(false);\n\n // PAN-2006 WI-7: freeze the run's cohort (in-flight ∪ current+next wave) at start.\n // The Run is complete once this cohort drains; mid-run pickups don't extend it.\n // Best-effort — a missing/unparseable sequence just means no cohort gate yet.\n try {\n const workspace = options.workspace ?? process.cwd();\n const seqPath = join(workspace, '.pan', 'backlog', 'sequence.md');\n if (existsSync(seqPath)) {\n const parsed = parseSequenceMd(readFileSync(seqPath, 'utf-8'));\n if (parsed.ok) {\n saveRunCohort(runId, computeCohort(\n parsed.doc.nodes,\n buildClassifyLookups(workspace),\n options.maxAgents ?? 5,\n options.autoPickupBacklog ?? isFlywheelAutoPickupBacklog(),\n await activeOrderBookIssues(workspace, runId),\n ));\n }\n }\n } catch { /* cohort snapshot is best-effort */ }\n\n return agent;\n}\n\nexport async function abortSpawnedFlywheel(runId: string): Promise<void> {\n try {\n await Effect.runPromise(stopAgent(FLYWHEEL_ORCHESTRATOR_AGENT_ID, 'operator'));\n } finally {\n await abortFlywheelRun(runId);\n }\n}\n\nexport async function pauseFlywheel(): Promise<FlywheelPauseResult> {\n const activeRunId = getFlywheelActiveRunId();\n if (activeRunId) {\n try {\n const sessionId = (await readFile(join(getAgentDir(FLYWHEEL_ORCHESTRATOR_AGENT_ID), 'session.id'), 'utf-8')).trim();\n if (sessionId) await saveResumeSessionId(activeRunId, sessionId);\n } catch { /* non-fatal: resume falls back to fresh if session.id is missing */ }\n }\n setFlywheelGloballyPaused(true);\n await Effect.runPromise(stopAgent(FLYWHEEL_ORCHESTRATOR_AGENT_ID, 'operator'));\n return { activeRunId };\n}\n\nexport async function resumeFlywheel(options: FlywheelLifecycleOptions = {}): Promise<FlywheelResumeResult> {\n if (isFlywheelDevcontainerRuntime(options.env)) {\n throw new Error('Refusing to resume flywheel-orchestrator inside a workspace devcontainer');\n }\n\n const activeRunId = getFlywheelActiveRunId();\n if (!activeRunId) {\n throw new Error('No active flywheel run to resume');\n }\n const runId = parseRunId(activeRunId);\n\n const resumeSessionId = options.resumeSessionId ?? await loadResumeSessionId(runId) ?? undefined;\n const launch = await readFlywheelLaunchMetadata(runId);\n const agent = await spawnFlywheelAgent(runId, withFlywheelAutonomyOptions({\n ...options,\n workspace: options.workspace ?? launch?.workspace,\n briefPath: options.briefPath ?? launch?.briefPath,\n briefOverlayPath: options.briefOverlayPath ?? launch?.briefOverlayPath,\n resumeSessionId,\n }));\n setFlywheelGloballyPaused(false);\n return { activeRunId, agent };\n}\n"],"mappings":"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"}
|
|
@@ -2,15 +2,15 @@ import { $t as findProjectByPathSync, Ht as init_state_read_home, Wt as resolveS
|
|
|
2
2
|
import { C as init_tmux, U as sessionExists } from "./tmux-l-yvNWhg.js";
|
|
3
3
|
import { p as FlywheelStats, t as init_src, w as FlywheelStatus } from "./src-tnFSfiXX.js";
|
|
4
4
|
import { c as init_control_settings, f as isFlywheelAutoPickupBacklog, i as getFlywheelActiveRunId, m as isFlywheelRequireUatBeforeMerge } from "./control-settings-BkaVFRdm.js";
|
|
5
|
-
import { q as init_agents } from "./agent-state-
|
|
5
|
+
import { q as init_agents } from "./agent-state-B196fj1h.js";
|
|
6
6
|
import { s as init_internal_token } from "./internal-token-Ci0LxMIq.js";
|
|
7
|
-
import { n as resolveHarness, t as init_harness_resolve } from "./harness-resolve-
|
|
7
|
+
import { n as resolveHarness, t as init_harness_resolve } from "./harness-resolve-C0HWj3H9.js";
|
|
8
8
|
import { f as init_github_app } from "./github-app-BINlfWAA.js";
|
|
9
9
|
import "./substrate-bug-weights-service-9nrkZcaP.js";
|
|
10
|
-
import "./sequence-io-
|
|
11
|
-
import { A as advanceQueue, B as ensureOrderIssueStore, D as writeFlywheelLaunchMetadata, H as getBook, L as setStatus, O as writeLatestFlywheelStatus, S as nextFlywheelRunId, V as firstReadyBookInQueue, _ as clearFlywheelGate, d as spawnFlywheel, h as resolvePrimaryWorktreeRoot, m as requireFlywheelBrief, n as abortSpawnedFlywheel, t as FLYWHEEL_ORCHESTRATOR_AGENT_ID, v as getFlywheelRunDetail, w as readFlywheelLaunchMetadata, x as listFlywheelRuns, y as getFlywheelRunDir, z as computeBookProgress } from "./flywheel-
|
|
12
|
-
import { r as computeMergeQueueFromCandidates, s as listEligibleCandidatesByProject } from "./flywheel-merge-order-
|
|
13
|
-
import { r as validateBookForStart } from "./validate-
|
|
10
|
+
import "./sequence-io-DZyschsf.js";
|
|
11
|
+
import { A as advanceQueue, B as ensureOrderIssueStore, D as writeFlywheelLaunchMetadata, H as getBook, L as setStatus, O as writeLatestFlywheelStatus, S as nextFlywheelRunId, V as firstReadyBookInQueue, _ as clearFlywheelGate, d as spawnFlywheel, h as resolvePrimaryWorktreeRoot, m as requireFlywheelBrief, n as abortSpawnedFlywheel, t as FLYWHEEL_ORCHESTRATOR_AGENT_ID, v as getFlywheelRunDetail, w as readFlywheelLaunchMetadata, x as listFlywheelRuns, y as getFlywheelRunDir, z as computeBookProgress } from "./flywheel-DKldI63J.js";
|
|
12
|
+
import { r as computeMergeQueueFromCandidates, s as listEligibleCandidatesByProject } from "./flywheel-merge-order-PG5op4j7.js";
|
|
13
|
+
import { r as validateBookForStart } from "./validate-069_N1e2.js";
|
|
14
14
|
import { join } from "node:path";
|
|
15
15
|
import { Effect, Schema } from "effect";
|
|
16
16
|
import { freemem, totalmem } from "node:os";
|
|
@@ -677,4 +677,4 @@ createFlywheelCompleteCommand({
|
|
|
677
677
|
//#endregion
|
|
678
678
|
export { flywheelReportCommand, startFlywheelRun };
|
|
679
679
|
|
|
680
|
-
//# sourceMappingURL=flywheel-
|
|
680
|
+
//# sourceMappingURL=flywheel-DpRPLErh.js.map
|