panopticon-cli 0.6.5 → 0.6.6
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/README.md +2 -2
- package/dist/{agents-DfYify9s.js → agents-CfFDs52G.js} +14 -14
- package/dist/{agents-DfYify9s.js.map → agents-CfFDs52G.js.map} +1 -1
- package/dist/{agents-BKsVoIc9.js → agents-D_2oRFVf.js} +1 -1
- package/dist/{archive-planning-BJrZ3tmN.js → archive-planning-D97ziGec.js} +3 -3
- package/dist/{archive-planning-BJrZ3tmN.js.map → archive-planning-D97ziGec.js.map} +1 -1
- package/dist/{archive-planning-C3m3hfa5.js → archive-planning-DK90wn9Q.js} +1 -1
- package/dist/{browser-Cvdznzc0.js → browser-CX7jXfXX.js} +1 -1
- package/dist/{browser-Cvdznzc0.js.map → browser-CX7jXfXX.js.map} +1 -1
- package/dist/{clean-planning-DvhZAUv4.js → clean-planning-D_lz4aQq.js} +2 -2
- package/dist/{clean-planning-DvhZAUv4.js.map → clean-planning-D_lz4aQq.js.map} +1 -1
- package/dist/clean-planning-x1S-JdmO.js +2 -0
- package/dist/cli/index.js +291 -760
- package/dist/cli/index.js.map +1 -1
- package/dist/{close-issue-Dr7yZmrr.js → close-issue-CaFE0stN.js} +11 -7
- package/dist/close-issue-CaFE0stN.js.map +1 -0
- package/dist/close-issue-CjcfZI9s.js +2 -0
- package/dist/compact-beads-B0_qE1w3.js +2 -0
- package/dist/{compact-beads-BCOtIIRl.js → compact-beads-CjFkteSU.js} +2 -2
- package/dist/{compact-beads-BCOtIIRl.js.map → compact-beads-CjFkteSU.js.map} +1 -1
- package/dist/{config-CRzMQRgA.js → config-BQNKsi9G.js} +2 -2
- package/dist/{config-CRzMQRgA.js.map → config-BQNKsi9G.js.map} +1 -1
- package/dist/{config-BYgUzQ21.js → config-agyKgF5C.js} +1 -1
- package/dist/{config-yaml-BgOACZAB.js → config-yaml-DGbLSMCa.js} +1 -1
- package/dist/{config-yaml-BgOACZAB.js.map → config-yaml-DGbLSMCa.js.map} +1 -1
- package/dist/{config-yaml-fdyvyL0S.js → config-yaml-Dqt4FWQH.js} +1 -1
- package/dist/dashboard/{acceptance-criteria-e5iiHlRx.js → acceptance-criteria-Dk9hhiYj.js} +1 -1
- package/dist/dashboard/{acceptance-criteria-e5iiHlRx.js.map → acceptance-criteria-Dk9hhiYj.js.map} +1 -1
- package/dist/dashboard/{agent-enrichment-C67LJBgD.js → agent-enrichment-DdO7ZqjI.js} +11 -7
- package/dist/dashboard/agent-enrichment-DdO7ZqjI.js.map +1 -0
- package/dist/dashboard/{agent-enrichment-Cq0P1cNZ.js → agent-enrichment-dLeGE1fX.js} +1 -1
- package/dist/dashboard/{agents-YyO6t5Xa.js → agents-DCpQQ_W5.js} +14 -14
- package/dist/dashboard/{agents-YyO6t5Xa.js.map → agents-DCpQQ_W5.js.map} +1 -1
- package/dist/dashboard/{agents-BVBVCyat.js → agents-Dgh2TjSp.js} +1 -1
- package/dist/dashboard/{archive-planning-h-hAjk0P.js → archive-planning-BmW9UDTr.js} +3 -3
- package/dist/dashboard/{archive-planning-h-hAjk0P.js.map → archive-planning-BmW9UDTr.js.map} +1 -1
- package/dist/dashboard/{archive-planning-CScs1MOC.js → archive-planning-C3Ebf9yC.js} +1 -1
- package/dist/dashboard/{beads-qNB0yAHV.js → beads-Bv-AdX7G.js} +3 -3
- package/dist/dashboard/{beads-qNB0yAHV.js.map → beads-Bv-AdX7G.js.map} +1 -1
- package/dist/dashboard/{beads-D_FRedEJ.js → beads-By6-X07V.js} +1 -1
- package/dist/dashboard/clean-planning-D60L8rPY.js +2 -0
- package/dist/dashboard/{clean-planning-qafw99vY.js → clean-planning-VEJu5suh.js} +2 -2
- package/dist/dashboard/{clean-planning-qafw99vY.js.map → clean-planning-VEJu5suh.js.map} +1 -1
- package/dist/dashboard/close-issue-C2KeSKKJ.js +2 -0
- package/dist/dashboard/{close-issue-DfIggeZD.js → close-issue-DtKdsSTm.js} +11 -7
- package/dist/dashboard/close-issue-DtKdsSTm.js.map +1 -0
- package/dist/dashboard/compact-beads-C7BN5N11.js +2 -0
- package/dist/dashboard/{compact-beads-Dt0qTqsC.js → compact-beads-D8Vt3qyv.js} +2 -2
- package/dist/dashboard/{compact-beads-Dt0qTqsC.js.map → compact-beads-D8Vt3qyv.js.map} +1 -1
- package/dist/dashboard/{config-CUREjHP7.js → config-CDkGjnwy.js} +2 -2
- package/dist/dashboard/{config-CUREjHP7.js.map → config-CDkGjnwy.js.map} +1 -1
- package/dist/dashboard/{config-BeI3uy-8.js → config-CTXkBATQ.js} +1 -1
- package/dist/dashboard/{database-CozA13Wy.js → database-DhqASALP.js} +1 -1
- package/dist/dashboard/{database-C0y0hXBx.js → database-cxmQryoh.js} +2 -2
- package/dist/dashboard/{database-C0y0hXBx.js.map → database-cxmQryoh.js.map} +1 -1
- package/dist/dashboard/{dist-src-oG2iHzgI.js → dist-src-DTm11oQr.js} +1 -1
- package/dist/dashboard/{dist-src-oG2iHzgI.js.map → dist-src-DTm11oQr.js.map} +1 -1
- package/dist/dashboard/{event-store-D7kLBd07.js → event-store-VWWUmOfn.js} +1 -1
- package/dist/dashboard/{event-store-O9q0Gweh.js → event-store-vSmAA3Zp.js} +9 -4
- package/dist/dashboard/event-store-vSmAA3Zp.js.map +1 -0
- package/dist/dashboard/{factory-BnLdiQW-.js → factory-C8nhLGHB.js} +3 -3
- package/dist/dashboard/{factory-BnLdiQW-.js.map → factory-C8nhLGHB.js.map} +1 -1
- package/dist/dashboard/{feedback-writer-DyovUANg.js → feedback-writer-CudSe1WK.js} +2 -2
- package/dist/dashboard/{feedback-writer-DyovUANg.js.map → feedback-writer-CudSe1WK.js.map} +1 -1
- package/dist/dashboard/{feedback-writer-gSUv_W0h.js → feedback-writer-Wgv1cd1r.js} +1 -1
- package/dist/dashboard/{git-utils-BJRioREj.js → git-utils-C1m4SwAe.js} +1 -1
- package/dist/dashboard/{git-utils-BJRioREj.js.map → git-utils-C1m4SwAe.js.map} +1 -1
- package/dist/dashboard/{git-utils-BtCRddq3.js → git-utils-DQI8EYoj.js} +1 -1
- package/dist/dashboard/{github-app-XO-LBUGk.js → github-app-DClWjjHr.js} +1 -1
- package/dist/dashboard/{github-app-XO-LBUGk.js.map → github-app-DClWjjHr.js.map} +1 -1
- package/dist/dashboard/{health-events-db-584nYgJB.js → health-events-db-BMXQfInV.js} +1 -1
- package/dist/dashboard/{health-events-db-B3ChzN65.js → health-events-db-Do4NrOhC.js} +2 -2
- package/dist/dashboard/{health-events-db-B3ChzN65.js.map → health-events-db-Do4NrOhC.js.map} +1 -1
- package/dist/dashboard/{hooks-CKhs3N68.js → hooks-CB4T47NC.js} +1 -1
- package/dist/dashboard/{hooks-CErbP8Oq.js → hooks-CjqXOlNb.js} +2 -2
- package/dist/dashboard/{hooks-CErbP8Oq.js.map → hooks-CjqXOlNb.js.map} +1 -1
- package/dist/dashboard/hume-CA2pftu_.js +3 -0
- package/dist/dashboard/{hume-CX_U3Qha.js → hume-JsAlMOJC.js} +2 -2
- package/dist/dashboard/{hume-CX_U3Qha.js.map → hume-JsAlMOJC.js.map} +1 -1
- package/dist/dashboard/{inspect-agent-B57kGDUV.js → inspect-agent-7eour7EA.js} +3 -3
- package/dist/dashboard/{inspect-agent-B57kGDUV.js.map → inspect-agent-7eour7EA.js.map} +1 -1
- package/dist/dashboard/{io-yGovuG4U.js → io-CWlFW78i.js} +1 -1
- package/dist/dashboard/{io-AJg-mzFi.js → io-DKS6359z.js} +1 -1
- package/dist/dashboard/{io-AJg-mzFi.js.map → io-DKS6359z.js.map} +1 -1
- package/dist/dashboard/issue-id-vwYJdsf8.js +62 -0
- package/dist/dashboard/issue-id-vwYJdsf8.js.map +1 -0
- package/dist/dashboard/{issue-service-singleton-DQK42EqH.js → issue-service-singleton-Co__-6kL.js} +1 -1
- package/dist/dashboard/{issue-service-singleton-sb2HkB9f.js → issue-service-singleton-Wv4xBm3y.js} +7 -7
- package/dist/dashboard/{issue-service-singleton-sb2HkB9f.js.map → issue-service-singleton-Wv4xBm3y.js.map} +1 -1
- package/dist/dashboard/{label-cleanup-CZEsbtq9.js → label-cleanup-nVKTmIIW.js} +7 -4
- package/dist/dashboard/label-cleanup-nVKTmIIW.js.map +1 -0
- package/dist/dashboard/lifecycle-BcUmtkR4.js +7 -0
- package/dist/dashboard/{merge-agent-GLtMEsTu.js → merge-agent-CGN3TT0a.js} +1 -1
- package/dist/dashboard/{merge-agent-twroFuAh.js → merge-agent-yudQOPZc.js} +148 -46
- package/dist/dashboard/merge-agent-yudQOPZc.js.map +1 -0
- package/dist/dashboard/{paths-COdEvoXR.js → paths-BDyJ7BiV.js} +19 -2
- package/dist/dashboard/{paths-COdEvoXR.js.map → paths-BDyJ7BiV.js.map} +1 -1
- package/dist/dashboard/{pipeline-notifier-DM5AHG5Q.js → pipeline-notifier-CCSN-jar.js} +1 -1
- package/dist/dashboard/{pipeline-notifier-DM5AHG5Q.js.map → pipeline-notifier-CCSN-jar.js.map} +1 -1
- package/dist/dashboard/{plan-utils-BkCIhn3B.js → plan-utils-Bkcsqr_s.js} +3 -3
- package/dist/dashboard/{plan-utils-BkCIhn3B.js.map → plan-utils-Bkcsqr_s.js.map} +1 -1
- package/dist/dashboard/{prd-draft-D09Afalc.js → prd-draft-BD8oMkZ1.js} +2 -2
- package/dist/dashboard/{prd-draft-D09Afalc.js.map → prd-draft-BD8oMkZ1.js.map} +1 -1
- package/dist/dashboard/{projection-cache-DQ9zegkK.js → projection-cache-C0EL8s8h.js} +1 -1
- package/dist/dashboard/{projection-cache-DQ9zegkK.js.map → projection-cache-C0EL8s8h.js.map} +1 -1
- package/dist/dashboard/{projects-DyT3vSy-.js → projects-C5ozxjwP.js} +1 -1
- package/dist/dashboard/{projects-Cq3TWdPS.js → projects-CFVl4oHn.js} +25 -13
- package/dist/dashboard/projects-CFVl4oHn.js.map +1 -0
- package/dist/dashboard/{providers-Ck2sQd_F.js → providers-B5Y4H2Mg.js} +4 -4
- package/dist/dashboard/providers-B5Y4H2Mg.js.map +1 -0
- package/dist/dashboard/{providers-DVQnDekG.js → providers-csVZVPkE.js} +1 -1
- package/dist/dashboard/public/assets/{dist-CCJbQrSB.js → dist-BaQPC-c6.js} +1 -1
- package/dist/dashboard/public/assets/index-ByLmYGhW.js +212 -0
- package/dist/dashboard/public/assets/index-OEEbThNN.css +1 -0
- package/dist/dashboard/public/index.html +2 -2
- package/dist/dashboard/rally-6McpKKRa.js +3 -0
- package/dist/dashboard/{rally-Cwuae-4C.js → rally-YjFRxIiC.js} +2 -2
- package/dist/dashboard/{rally-Cwuae-4C.js.map → rally-YjFRxIiC.js.map} +1 -1
- package/dist/dashboard/{rally-api-DSUxm7EO.js → rally-api-C0WqCSkT.js} +1 -1
- package/dist/dashboard/{rally-api-DSUxm7EO.js.map → rally-api-C0WqCSkT.js.map} +1 -1
- package/dist/dashboard/{rally-api-CEH5KZi4.js → rally-api-DNttdCW4.js} +1 -1
- package/dist/dashboard/{remote-BHTTMpJJ.js → remote-Cigqjj3f.js} +2 -2
- package/dist/dashboard/{remote-BXo_iIku.js → remote-ObpNZ7hF.js} +2 -2
- package/dist/dashboard/{remote-BXo_iIku.js.map → remote-ObpNZ7hF.js.map} +1 -1
- package/dist/dashboard/{remote-agents-CTKVhFFY.js → remote-agents-Bf3GuM7t.js} +1 -1
- package/dist/dashboard/{remote-agents-C0_0LLNd.js → remote-agents-DFyjT1Le.js} +1 -1
- package/dist/dashboard/{remote-agents-C0_0LLNd.js.map → remote-agents-DFyjT1Le.js.map} +1 -1
- package/dist/dashboard/{review-status-CK3eBGyb.js → review-status-BtXqWBhS.js} +1 -1
- package/dist/dashboard/{review-status-CV55Tl-n.js → review-status-Bymwzh2i.js} +44 -4
- package/dist/dashboard/{review-status-CV55Tl-n.js.map → review-status-Bymwzh2i.js.map} +1 -1
- package/dist/dashboard/server.js +559 -253
- package/dist/dashboard/server.js.map +1 -1
- package/dist/dashboard/{settings-CuHV-wcv.js → settings-BHlDG7TK.js} +2 -2
- package/dist/dashboard/settings-BHlDG7TK.js.map +1 -0
- package/dist/dashboard/settings-XWvDcj-D.js +2 -0
- package/dist/dashboard/{shadow-engineering-BUeZunaE.js → shadow-engineering-lIn1W_95.js} +1 -1
- package/dist/dashboard/{shadow-engineering-BUeZunaE.js.map → shadow-engineering-lIn1W_95.js.map} +1 -1
- package/dist/dashboard/{shadow-state-DHQ-kASN.js → shadow-state-BIexcxkv.js} +1 -1
- package/dist/dashboard/{shadow-state-DHQ-kASN.js.map → shadow-state-BIexcxkv.js.map} +1 -1
- package/dist/dashboard/{spawn-planning-session-8FFAqLdK.js → spawn-planning-session-33Jf-d5T.js} +6 -6
- package/dist/dashboard/{spawn-planning-session-8FFAqLdK.js.map → spawn-planning-session-33Jf-d5T.js.map} +1 -1
- package/dist/dashboard/{spawn-planning-session-U0Lqpjen.js → spawn-planning-session-D5hrVdWM.js} +1 -1
- package/dist/dashboard/{specialist-context-ColzlmGE.js → specialist-context-DGukHSn8.js} +6 -6
- package/dist/dashboard/{specialist-context-ColzlmGE.js.map → specialist-context-DGukHSn8.js.map} +1 -1
- package/dist/dashboard/{specialist-logs-BhmDpFIq.js → specialist-logs-CIw4qfTy.js} +1 -1
- package/dist/dashboard/{specialists-C6s3U6tX.js → specialists-B_zrayaP.js} +37 -36
- package/dist/dashboard/specialists-B_zrayaP.js.map +1 -0
- package/dist/dashboard/{specialists-Cny632-T.js → specialists-Cp-PgspS.js} +1 -1
- package/dist/dashboard/{test-agent-queue-tqI4VDsu.js → test-agent-queue-ypF_ecHo.js} +4 -4
- package/dist/dashboard/{test-agent-queue-tqI4VDsu.js.map → test-agent-queue-ypF_ecHo.js.map} +1 -1
- package/dist/dashboard/{tldr-daemon-BNFyS7W_.js → tldr-daemon-B_oLRD8z.js} +2 -2
- package/dist/dashboard/{tldr-daemon-BNFyS7W_.js.map → tldr-daemon-B_oLRD8z.js.map} +1 -1
- package/dist/dashboard/{tldr-daemon-A6JqC59u.js → tldr-daemon-Cfs0bXTi.js} +1 -1
- package/dist/dashboard/{tmux-DYGAVJfb.js → tmux-BzxdKItf.js} +1 -1
- package/dist/dashboard/{tmux-IlN1Slv-.js → tmux-LwG0tHhU.js} +2 -2
- package/dist/dashboard/{tmux-IlN1Slv-.js.map → tmux-LwG0tHhU.js.map} +1 -1
- package/dist/dashboard/{tracker-config-BzNLnmcE.js → tracker-config-BP59uH4V.js} +1 -1
- package/dist/dashboard/{tracker-config-CNM_5rEf.js → tracker-config-e7ph1QqT.js} +2 -2
- package/dist/dashboard/{tracker-config-CNM_5rEf.js.map → tracker-config-e7ph1QqT.js.map} +1 -1
- package/dist/dashboard/{tunnel-D2BkwU7k.js → tunnel-0RzzuXPf.js} +1 -1
- package/dist/dashboard/{tunnel-Dub2hiAA.js → tunnel-DldbBPWL.js} +2 -2
- package/dist/dashboard/{tunnel-Dub2hiAA.js.map → tunnel-DldbBPWL.js.map} +1 -1
- package/dist/dashboard/{types-CWA-o4UN.js → types-RKZjGE5N.js} +1 -1
- package/dist/dashboard/{types-CWA-o4UN.js.map → types-RKZjGE5N.js.map} +1 -1
- package/dist/dashboard/{vtt-parser-BAXygRf0.js → vtt-parser-99vFekRQ.js} +1 -1
- package/dist/dashboard/{vtt-parser-BAXygRf0.js.map → vtt-parser-99vFekRQ.js.map} +1 -1
- package/dist/dashboard/{work-agent-prompt-JYq_OugP.js → work-agent-prompt-fCg67nyo.js} +65 -10
- package/dist/dashboard/{work-agent-prompt-JYq_OugP.js.map → work-agent-prompt-fCg67nyo.js.map} +1 -1
- package/dist/dashboard/{work-type-router-Cxp8_ur2.js → work-type-router-CWVW2Wk_.js} +1 -1
- package/dist/dashboard/{work-type-router-Cxp8_ur2.js.map → work-type-router-CWVW2Wk_.js.map} +1 -1
- package/dist/dashboard/{work-type-router-Com2amST.js → work-type-router-Di5gCQwh.js} +1 -1
- package/dist/dashboard/{workflows-N1UTipYl.js → workflows-BSMipN07.js} +35 -17
- package/dist/dashboard/workflows-BSMipN07.js.map +1 -0
- package/dist/dashboard/workflows-DaYWQIS2.js +2 -0
- package/dist/dashboard/{workspace-config-cmp5_ipD.js → workspace-config-DVDR-Ukh.js} +1 -1
- package/dist/dashboard/workspace-config-DVDR-Ukh.js.map +1 -0
- package/dist/dashboard/{workspace-manager-CjpWPgzL.js → workspace-manager-BYfzs_t2.js} +1 -1
- package/dist/dashboard/{workspace-manager-D_y9ZmW_.js → workspace-manager-C7OfT62A.js} +44 -24
- package/dist/dashboard/workspace-manager-C7OfT62A.js.map +1 -0
- package/dist/{dns-BKzHm-2q.js → dns-D_aKQJjb.js} +1 -1
- package/dist/{dns-DZwOWvVO.js → dns-Yxq4NNS7.js} +1 -1
- package/dist/{dns-DZwOWvVO.js.map → dns-Yxq4NNS7.js.map} +1 -1
- package/dist/{factory-DFu3IT4r.js → factory-BRBGw6OB.js} +1 -1
- package/dist/{factory-DfzczxN1.js → factory-DzsOiZVc.js} +3 -3
- package/dist/{factory-DfzczxN1.js.map → factory-DzsOiZVc.js.map} +1 -1
- package/dist/{feedback-writer-CwdnOkPO.js → feedback-writer-ygXN5F9N.js} +2 -2
- package/dist/{feedback-writer-CwdnOkPO.js.map → feedback-writer-ygXN5F9N.js.map} +1 -1
- package/dist/{github-app-CHKwxOeQ.js → github-app-DykduJ0X.js} +1 -1
- package/dist/{github-app-CHKwxOeQ.js.map → github-app-DykduJ0X.js.map} +1 -1
- package/dist/hume-9nv1VmMV.js +3 -0
- package/dist/{hume-DnV-tDsh.js → hume-DoCbph2h.js} +2 -2
- package/dist/{hume-DnV-tDsh.js.map → hume-DoCbph2h.js.map} +1 -1
- package/dist/index.d.ts +17 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -7
- package/dist/issue-id-CAcekoIw.js +62 -0
- package/dist/issue-id-CAcekoIw.js.map +1 -0
- package/dist/{label-cleanup-31ElPqqv.js → label-cleanup-C8R9Rspn.js} +7 -4
- package/dist/label-cleanup-C8R9Rspn.js.map +1 -0
- package/dist/{manifest-DL0oDbpv.js → manifest-B4ghOD-V.js} +1 -1
- package/dist/{manifest-DL0oDbpv.js.map → manifest-B4ghOD-V.js.map} +1 -1
- package/dist/{merge-agent-VQH9z9t8.js → merge-agent-DlUiUanN.js} +86 -33
- package/dist/merge-agent-DlUiUanN.js.map +1 -0
- package/dist/{paths-lMaxrYtT.js → paths-CDJ_HsbN.js} +19 -2
- package/dist/{paths-lMaxrYtT.js.map → paths-CDJ_HsbN.js.map} +1 -1
- package/dist/{pipeline-notifier-OJ-d3Y60.js → pipeline-notifier-XgDdCdvT.js} +1 -1
- package/dist/{pipeline-notifier-OJ-d3Y60.js.map → pipeline-notifier-XgDdCdvT.js.map} +1 -1
- package/dist/{projects-CvLepaxC.js → projects-Bk-5QhFQ.js} +25 -13
- package/dist/projects-Bk-5QhFQ.js.map +1 -0
- package/dist/{projects-DMWmPeIU.js → projects-DhU7rAVN.js} +1 -1
- package/dist/{providers-DcCPZ5K4.js → providers-DSU1vfQF.js} +4 -4
- package/dist/providers-DSU1vfQF.js.map +1 -0
- package/dist/rally-DdPvGa-w.js +3 -0
- package/dist/{rally-uUUZXp1h.js → rally-Dy00NElU.js} +1 -1
- package/dist/{rally-uUUZXp1h.js.map → rally-Dy00NElU.js.map} +1 -1
- package/dist/{remote-CkLBqLJc.js → remote-CYiOJg0q.js} +2 -2
- package/dist/{remote-CkLBqLJc.js.map → remote-CYiOJg0q.js.map} +1 -1
- package/dist/{remote-agents-C5Bd2fgt.js → remote-agents-CZXrUF4f.js} +1 -1
- package/dist/{remote-agents-C5Bd2fgt.js.map → remote-agents-CZXrUF4f.js.map} +1 -1
- package/dist/{remote-agents-BTzD-wMQ.js → remote-agents-ycHHVsgf.js} +1 -1
- package/dist/{remote-workspace-Dxghqiti.js → remote-workspace-CA33UuVI.js} +4 -4
- package/dist/{remote-workspace-Dxghqiti.js.map → remote-workspace-CA33UuVI.js.map} +1 -1
- package/dist/{review-status-2TdtHNcs.js → review-status-D6H2WOw8.js} +1 -1
- package/dist/{review-status-Bm1bWNEa.js → review-status-DEDvCKMP.js} +44 -4
- package/dist/{review-status-Bm1bWNEa.js.map → review-status-DEDvCKMP.js.map} +1 -1
- package/dist/{tracker-C_62ukEq.js → settings-BcWPTrua.js} +7 -199
- package/dist/settings-BcWPTrua.js.map +1 -0
- package/dist/shadow-state-BZzxfEGw.js +2 -0
- package/dist/{shadow-state-CFFHf05M.js → shadow-state-CE3dQfll.js} +1 -1
- package/dist/{shadow-state-CFFHf05M.js.map → shadow-state-CE3dQfll.js.map} +1 -1
- package/dist/{specialist-context-BdNFsfMG.js → specialist-context-BAUWL1Fl.js} +6 -6
- package/dist/{specialist-context-BdNFsfMG.js.map → specialist-context-BAUWL1Fl.js.map} +1 -1
- package/dist/{specialist-logs-CLztE_bE.js → specialist-logs-DQKKQV9B.js} +1 -1
- package/dist/{specialists-aUoUVWsN.js → specialists-Bfb9ATzw.js} +1 -1
- package/dist/{specialists-DEKqgkxp.js → specialists-D7Kj5o6s.js} +35 -34
- package/dist/specialists-D7Kj5o6s.js.map +1 -0
- package/dist/sync-DMfgd389.js +693 -0
- package/dist/sync-DMfgd389.js.map +1 -0
- package/dist/sync-TL6y-8K6.js +2 -0
- package/dist/{tldr-daemon-BCEFPItr.js → tldr-daemon-CFx4LXAl.js} +2 -2
- package/dist/{tldr-daemon-BCEFPItr.js.map → tldr-daemon-CFx4LXAl.js.map} +1 -1
- package/dist/{tldr-daemon-xBAx4cBE.js → tldr-daemon-D_EooADG.js} +1 -1
- package/dist/{tmux-DN6H886Y.js → tmux-CBtui_Cl.js} +1 -1
- package/dist/{tmux-CKdNxxJx.js → tmux-D6Ah4I8z.js} +2 -2
- package/dist/{tmux-CKdNxxJx.js.map → tmux-D6Ah4I8z.js.map} +1 -1
- package/dist/tracker-BhYYvU3p.js +198 -0
- package/dist/tracker-BhYYvU3p.js.map +1 -0
- package/dist/{tracker-utils-CVU2W1sX.js → tracker-utils-ChQyut8w.js} +34 -12
- package/dist/tracker-utils-ChQyut8w.js.map +1 -0
- package/dist/{traefik-DHgBoWXX.js → traefik-C80EbDu_.js} +4 -4
- package/dist/{traefik-DHgBoWXX.js.map → traefik-C80EbDu_.js.map} +1 -1
- package/dist/{traefik-BR-edbZv.js → traefik-CgHl7Bge.js} +1 -1
- package/dist/{tunnel-BZO9Q5oe.js → tunnel-DXOJ1wMM.js} +1 -1
- package/dist/{tunnel-Bl1qNSyQ.js → tunnel-DzXEPwIc.js} +2 -2
- package/dist/{tunnel-Bl1qNSyQ.js.map → tunnel-DzXEPwIc.js.map} +1 -1
- package/dist/{types-DewGdaIP.js → types-BhJj1SP1.js} +1 -1
- package/dist/{types-DewGdaIP.js.map → types-BhJj1SP1.js.map} +1 -1
- package/dist/{work-type-router-CS2BB1vS.js → work-type-router-CHjciPyS.js} +3 -3
- package/dist/{work-type-router-CS2BB1vS.js.map → work-type-router-CHjciPyS.js.map} +1 -1
- package/dist/{workspace-config-CNXOpKuj.js → workspace-config-fUafvYMp.js} +1 -1
- package/dist/workspace-config-fUafvYMp.js.map +1 -0
- package/dist/workspace-manager-B9jS4Dsq.js +3 -0
- package/dist/{workspace-manager-CncdZkIy.js → workspace-manager-DuLhnzJV.js} +112 -27
- package/dist/workspace-manager-DuLhnzJV.js.map +1 -0
- package/package.json +2 -1
- package/scripts/post-merge-deploy.sh +25 -5
- package/scripts/record-cost-event.js +57 -7
- package/scripts/record-cost-event.js.map +1 -1
- package/skills/pan-help/SKILL.md +1 -1
- package/skills/pan-sync/SKILL.md +6 -6
- package/skills/workspace-add-repo/skill.md +46 -0
- package/templates/claude-md/sections/warnings.md +15 -2
- package/dist/clean-planning-sZXvy3Y5.js +0 -2
- package/dist/close-issue-Dml437qV.js +0 -2
- package/dist/close-issue-Dr7yZmrr.js.map +0 -1
- package/dist/compact-beads-iu218JcO.js +0 -2
- package/dist/dashboard/agent-enrichment-C67LJBgD.js.map +0 -1
- package/dist/dashboard/clean-planning-DCu3cOTu.js +0 -2
- package/dist/dashboard/close-issue-DfIggeZD.js.map +0 -1
- package/dist/dashboard/close-issue-DwdwYtar.js +0 -2
- package/dist/dashboard/compact-beads-DXY2fK2s.js +0 -2
- package/dist/dashboard/event-store-O9q0Gweh.js.map +0 -1
- package/dist/dashboard/hume-MZndNDVU.js +0 -3
- package/dist/dashboard/label-cleanup-CZEsbtq9.js.map +0 -1
- package/dist/dashboard/lifecycle-ZTYdrr2O.js +0 -7
- package/dist/dashboard/merge-agent-twroFuAh.js.map +0 -1
- package/dist/dashboard/projects-Cq3TWdPS.js.map +0 -1
- package/dist/dashboard/providers-Ck2sQd_F.js.map +0 -1
- package/dist/dashboard/public/assets/index-CpSmB2ts.css +0 -1
- package/dist/dashboard/public/assets/index-yarWhi0M.js +0 -214
- package/dist/dashboard/rally-CQ1OBJrJ.js +0 -3
- package/dist/dashboard/settings-CuHV-wcv.js.map +0 -1
- package/dist/dashboard/settings-DMeGBRsk.js +0 -2
- package/dist/dashboard/specialists-C6s3U6tX.js.map +0 -1
- package/dist/dashboard/workflows-B2ARUpOa.js +0 -2
- package/dist/dashboard/workflows-N1UTipYl.js.map +0 -1
- package/dist/dashboard/workspace-config-cmp5_ipD.js.map +0 -1
- package/dist/dashboard/workspace-manager-D_y9ZmW_.js.map +0 -1
- package/dist/hume-BjmwmJ9E.js +0 -3
- package/dist/label-cleanup-31ElPqqv.js.map +0 -1
- package/dist/merge-agent-VQH9z9t8.js.map +0 -1
- package/dist/projects-CvLepaxC.js.map +0 -1
- package/dist/providers-DcCPZ5K4.js.map +0 -1
- package/dist/rally-DR9x8--6.js +0 -3
- package/dist/shadow-state-p3jpGRPJ.js +0 -2
- package/dist/specialists-DEKqgkxp.js.map +0 -1
- package/dist/tracker-C_62ukEq.js.map +0 -1
- package/dist/tracker-utils-CVU2W1sX.js.map +0 -1
- package/dist/workspace-config-CNXOpKuj.js.map +0 -1
- package/dist/workspace-manager-CncdZkIy.js.map +0 -1
- package/dist/workspace-manager-Cx0r2Jnv.js +0 -3
package/dist/dashboard/server.js
CHANGED
|
@@ -1,33 +1,34 @@
|
|
|
1
1
|
import { a as __toCommonJS, i as __require, o as __toESM, t as __commonJSMin } from "./chunk-DORXReHP.js";
|
|
2
|
-
import { d as PROJECT_PRDS_COMPLETED_SUBDIR, f as PROJECT_PRDS_PLANNED_SUBDIR,
|
|
3
|
-
import { i as initEventStore, n as getEventStore } from "./event-store-
|
|
2
|
+
import { _ as init_paths, d as PROJECT_PRDS_COMPLETED_SUBDIR, f as PROJECT_PRDS_PLANNED_SUBDIR, h as encodeClaudeProjectDir, l as PROJECT_DOCS_SUBDIR, p as PROJECT_PRDS_SUBDIR, s as PANOPTICON_HOME, t as AGENTS_DIR, u as PROJECT_PRDS_ACTIVE_SUBDIR } from "./paths-BDyJ7BiV.js";
|
|
3
|
+
import { i as initEventStore, n as getEventStore } from "./event-store-vSmAA3Zp.js";
|
|
4
4
|
import { a as MODEL_CAPABILITIES, c as init_model_capabilities, d as jsYaml, i as loadConfig$1, l as resolveModelId, o as MODEL_DEPRECATIONS, r as init_config_yaml, t as getGlobalConfigPath, u as init_js_yaml } from "./config-yaml-DSfYpzN6.js";
|
|
5
5
|
import { t as require_dist } from "./dist-C667LLmq.js";
|
|
6
|
-
import {
|
|
7
|
-
import { i as
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { r as
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import { c as
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import { n as
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import { n as
|
|
29
|
-
import { n as
|
|
30
|
-
import {
|
|
6
|
+
import { n as extractPrefix, r as init_issue_id, t as extractNumber } from "./issue-id-vwYJdsf8.js";
|
|
7
|
+
import { a as findProjectByTeam, h as listProjects, i as findProjectByPath, p as init_projects, r as extractTeamPrefix, s as getIssuePrefix, y as resolveProjectFromIssue } from "./projects-CFVl4oHn.js";
|
|
8
|
+
import { i as init_tracker_config, n as getLinearApiKey, r as getRallyConfig, t as getGitHubConfig } from "./tracker-config-e7ph1QqT.js";
|
|
9
|
+
import { d as runQualityGates, f as emitDashboardLifecycle, l as syncMainIntoWorkspace, m as resolveTrackerType, p as resolveGitHubIssue, u as DEFAULT_GATES } from "./merge-agent-yudQOPZc.js";
|
|
10
|
+
import { i as startSharedIssueService, n as init_issue_service_singleton, r as issue_service_singleton_exports, t as getSharedIssueService } from "./issue-service-singleton-Wv4xBm3y.js";
|
|
11
|
+
import { r as setPipelineHandler, t as init_pipeline_notifier } from "./pipeline-notifier-CCSN-jar.js";
|
|
12
|
+
import { i as init_database, n as getDatabase, t as closeDatabase } from "./database-cxmQryoh.js";
|
|
13
|
+
import { a as loadReviewStatuses, i as init_review_status, n as clearStuckMergeStatuses, o as saveReviewStatuses, r as getReviewStatus, s as setReviewStatus$1, t as clearReviewStatus } from "./review-status-Bymwzh2i.js";
|
|
14
|
+
import { At as getSessionFiles, Ct as getUnblockedItems, Dt as readSpecialistHandoffs, Et as init_specialist_handoff_logger, Ft as getPricing, It as init_cost, Mt as normalizeModelName, Nt as parseClaudeSession, O as getTmuxSessionName, Ot as getActiveSessionModel, Pt as calculateCost, Tt as getSpecialistHandoffStats, f as getAllProjectSpecialistStatuses, it as wakeSpecialistOrQueue, j as init_specialists, jt as init_jsonl_parser, kt as getProjectDirs, q as setSessionId, r as checkSpecialistQueue, w as getSessionId, wt as init_task_readiness } from "./specialists-B_zrayaP.js";
|
|
15
|
+
import { t as getAgentCommand } from "./settings-BHlDG7TK.js";
|
|
16
|
+
import { a as init_providers, i as getProviderForModel, r as getProviderEnv } from "./providers-B5Y4H2Mg.js";
|
|
17
|
+
import { n as spawnPlanningSession } from "./spawn-planning-session-33Jf-d5T.js";
|
|
18
|
+
import { c as loadWorkspaceMetadata, r as isRemoteAvailable, t as createFlyProviderFromConfig } from "./remote-ObpNZ7hF.js";
|
|
19
|
+
import { d as sessionExistsAsync, i as createSession, l as sendKeysAsync, o as init_tmux, s as killSession, u as sessionExists } from "./tmux-LwG0tHhU.js";
|
|
20
|
+
import { a as init_config, o as loadConfig$2 } from "./config-CDkGjnwy.js";
|
|
21
|
+
import { A as saveCloisterConfig, C as stopAgent, D as getHealthThresholdsMs, O as init_config$1, S as spawnAgent, T as transitionIssueToInReview, a as getAgentDir, b as saveAgentState, c as getAgentState, d as getProviderExportsForModel, f as getProviderTmuxFlags, g as messageAgent, h as listRunningAgents, i as getActivity, j as shouldAutoStart, k as loadCloisterConfig, l as getLatestSessionId, m as init_agents, p as getSessionId$1, s as getAgentRuntimeState, u as getProviderEnvForModel, v as resumeAgent, w as transitionIssueToInProgress, x as saveSessionId, y as saveAgentRuntimeState } from "./agents-DCpQQ_W5.js";
|
|
22
|
+
import { c as writeHealthEvent } from "./health-events-db-Do4NrOhC.js";
|
|
23
|
+
import { s as init_hooks, t as checkHook } from "./hooks-CjqXOlNb.js";
|
|
24
|
+
import { a as getModelId, s as init_work_type_router } from "./work-type-router-CWVW2Wk_.js";
|
|
25
|
+
import { i as readWorkspacePlan, n as init_io, r as readPlan, t as findPlan } from "./io-DKS6359z.js";
|
|
26
|
+
import { n as hasPRDDraft } from "./prd-draft-BD8oMkZ1.js";
|
|
27
|
+
import { a as getAgentPendingQuestions$1, r as getAgentJsonlMtime, t as computeAgentEnrichment } from "./agent-enrichment-DdO7ZqjI.js";
|
|
28
|
+
import { n as writeFeedbackFile, t as init_feedback_writer } from "./feedback-writer-CudSe1WK.js";
|
|
29
|
+
import { n as getVBriefACStatus, r as syncBeadStatusToVBrief } from "./beads-Bv-AdX7G.js";
|
|
30
|
+
import { n as getTldrDaemonService, r as init_tldr_daemon } from "./tldr-daemon-B_oLRD8z.js";
|
|
31
|
+
import { c as sendToRemoteAgent, i as killRemoteAgent, l as spawnRemoteAgent, o as loadRemoteAgentState, t as getRemoteAgentOutput } from "./remote-agents-DFyjT1Le.js";
|
|
31
32
|
import { Cause, Data, Duration, Effect, FileSystem, Layer, Option, Path, Queue, Schedule, Schema, ServiceMap, Stream } from "effect";
|
|
32
33
|
import { cpus, freemem, homedir, totalmem } from "node:os";
|
|
33
34
|
import { appendFileSync, closeSync, existsSync, fstatSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from "fs";
|
|
@@ -553,6 +554,53 @@ const ActivityUpdatedEvent = Schema.Struct({
|
|
|
553
554
|
timestamp: Schema.String,
|
|
554
555
|
payload: Schema.Struct({ events: Schema.Array(Schema.Unknown) })
|
|
555
556
|
});
|
|
557
|
+
/** Individual activity log entry — emitted by merge-agent, cloister, specialists (PAN-520) */
|
|
558
|
+
const ActivityEntryEvent = Schema.Struct({
|
|
559
|
+
type: Schema.Literal("activity.entry"),
|
|
560
|
+
sequence: SequenceNumber,
|
|
561
|
+
timestamp: Schema.String,
|
|
562
|
+
payload: Schema.Struct({
|
|
563
|
+
id: Schema.String,
|
|
564
|
+
source: Schema.String,
|
|
565
|
+
level: Schema.String,
|
|
566
|
+
message: Schema.String,
|
|
567
|
+
details: Schema.optional(Schema.String),
|
|
568
|
+
issueId: Schema.optional(IssueId)
|
|
569
|
+
})
|
|
570
|
+
});
|
|
571
|
+
/** Dashboard is restarting (post-merge deploy, pan restart, etc.) (PAN-520) */
|
|
572
|
+
const DashboardLifecycleStartedEvent = Schema.Struct({
|
|
573
|
+
type: Schema.Literal("dashboard.lifecycle_started"),
|
|
574
|
+
sequence: SequenceNumber,
|
|
575
|
+
timestamp: Schema.String,
|
|
576
|
+
payload: Schema.Struct({
|
|
577
|
+
reason: Schema.String,
|
|
578
|
+
issueId: Schema.optional(IssueId),
|
|
579
|
+
trigger: Schema.String
|
|
580
|
+
})
|
|
581
|
+
});
|
|
582
|
+
/** Dashboard restarted successfully after a lifecycle event (PAN-520) */
|
|
583
|
+
const DashboardLifecycleCompletedEvent = Schema.Struct({
|
|
584
|
+
type: Schema.Literal("dashboard.lifecycle_completed"),
|
|
585
|
+
sequence: SequenceNumber,
|
|
586
|
+
timestamp: Schema.String,
|
|
587
|
+
payload: Schema.Struct({
|
|
588
|
+
reason: Schema.String,
|
|
589
|
+
issueId: Schema.optional(IssueId),
|
|
590
|
+
durationMs: Schema.Number
|
|
591
|
+
})
|
|
592
|
+
});
|
|
593
|
+
/** Dashboard restart failed (PAN-520) */
|
|
594
|
+
const DashboardLifecycleFailedEvent = Schema.Struct({
|
|
595
|
+
type: Schema.Literal("dashboard.lifecycle_failed"),
|
|
596
|
+
sequence: SequenceNumber,
|
|
597
|
+
timestamp: Schema.String,
|
|
598
|
+
payload: Schema.Struct({
|
|
599
|
+
reason: Schema.String,
|
|
600
|
+
issueId: Schema.optional(IssueId),
|
|
601
|
+
error: Schema.String
|
|
602
|
+
})
|
|
603
|
+
});
|
|
556
604
|
/** Replaces socket.io `shadow:inference-update` */
|
|
557
605
|
const ShadowInferenceUpdateEvent = Schema.Struct({
|
|
558
606
|
type: Schema.Literal("shadow.inference_update"),
|
|
@@ -646,13 +694,17 @@ const DomainEvent = Schema.Union([
|
|
|
646
694
|
IssuesUpdatedEvent,
|
|
647
695
|
IssueStatusChangedEvent,
|
|
648
696
|
ActivityUpdatedEvent,
|
|
697
|
+
ActivityEntryEvent,
|
|
649
698
|
ShadowInferenceUpdateEvent,
|
|
650
699
|
CostEventRecordedEvent,
|
|
651
700
|
WorkspaceCreatedEvent,
|
|
652
701
|
WorkspaceWipeStartedEvent,
|
|
653
702
|
WorkspaceDestroyedEvent,
|
|
654
703
|
WorkspaceDeletedEvent,
|
|
655
|
-
WorkspaceAbortedEvent
|
|
704
|
+
WorkspaceAbortedEvent,
|
|
705
|
+
DashboardLifecycleStartedEvent,
|
|
706
|
+
DashboardLifecycleCompletedEvent,
|
|
707
|
+
DashboardLifecycleFailedEvent
|
|
656
708
|
]);
|
|
657
709
|
//#endregion
|
|
658
710
|
//#region ../../../packages/contracts/src/rpc.ts
|
|
@@ -859,7 +911,17 @@ const INITIAL_READ_MODEL_STATE = {
|
|
|
859
911
|
agentOutputById: {},
|
|
860
912
|
issuesRaw: [],
|
|
861
913
|
recentActivity: [],
|
|
862
|
-
shadowInferenceByIssueId: {}
|
|
914
|
+
shadowInferenceByIssueId: {},
|
|
915
|
+
dashboardLifecycle: {
|
|
916
|
+
active: false,
|
|
917
|
+
reason: null,
|
|
918
|
+
issueId: null,
|
|
919
|
+
trigger: null,
|
|
920
|
+
startedAt: null,
|
|
921
|
+
completedAt: null,
|
|
922
|
+
failedAt: null,
|
|
923
|
+
error: null
|
|
924
|
+
}
|
|
863
925
|
};
|
|
864
926
|
const MAX_AGENT_OUTPUT_LINES = 200;
|
|
865
927
|
const MAX_ACTIVITY_ENTRIES = 50;
|
|
@@ -1122,6 +1184,65 @@ function applyEvent(state, event) {
|
|
|
1122
1184
|
...state,
|
|
1123
1185
|
sequence: Math.max(state.sequence, event.sequence)
|
|
1124
1186
|
};
|
|
1187
|
+
case "activity.entry": {
|
|
1188
|
+
const entry = event.payload;
|
|
1189
|
+
const updated = [{
|
|
1190
|
+
id: entry.id,
|
|
1191
|
+
timestamp: event.timestamp,
|
|
1192
|
+
...entry
|
|
1193
|
+
}, ...state.recentActivity].slice(0, MAX_ACTIVITY_ENTRIES);
|
|
1194
|
+
return {
|
|
1195
|
+
...state,
|
|
1196
|
+
sequence: Math.max(state.sequence, event.sequence),
|
|
1197
|
+
recentActivity: updated
|
|
1198
|
+
};
|
|
1199
|
+
}
|
|
1200
|
+
case "dashboard.lifecycle_started": {
|
|
1201
|
+
const { reason, issueId, trigger } = event.payload;
|
|
1202
|
+
return {
|
|
1203
|
+
...state,
|
|
1204
|
+
sequence: Math.max(state.sequence, event.sequence),
|
|
1205
|
+
dashboardLifecycle: {
|
|
1206
|
+
active: true,
|
|
1207
|
+
reason,
|
|
1208
|
+
issueId,
|
|
1209
|
+
trigger,
|
|
1210
|
+
startedAt: event.timestamp,
|
|
1211
|
+
completedAt: null,
|
|
1212
|
+
failedAt: null,
|
|
1213
|
+
error: null
|
|
1214
|
+
}
|
|
1215
|
+
};
|
|
1216
|
+
}
|
|
1217
|
+
case "dashboard.lifecycle_completed": {
|
|
1218
|
+
const { reason, issueId } = event.payload;
|
|
1219
|
+
return {
|
|
1220
|
+
...state,
|
|
1221
|
+
sequence: Math.max(state.sequence, event.sequence),
|
|
1222
|
+
dashboardLifecycle: {
|
|
1223
|
+
...state.dashboardLifecycle,
|
|
1224
|
+
active: false,
|
|
1225
|
+
reason: reason ?? state.dashboardLifecycle.reason,
|
|
1226
|
+
issueId: issueId ?? state.dashboardLifecycle.issueId,
|
|
1227
|
+
completedAt: event.timestamp
|
|
1228
|
+
}
|
|
1229
|
+
};
|
|
1230
|
+
}
|
|
1231
|
+
case "dashboard.lifecycle_failed": {
|
|
1232
|
+
const { reason, issueId, error } = event.payload;
|
|
1233
|
+
return {
|
|
1234
|
+
...state,
|
|
1235
|
+
sequence: Math.max(state.sequence, event.sequence),
|
|
1236
|
+
dashboardLifecycle: {
|
|
1237
|
+
...state.dashboardLifecycle,
|
|
1238
|
+
active: false,
|
|
1239
|
+
reason: reason ?? state.dashboardLifecycle.reason,
|
|
1240
|
+
issueId: issueId ?? state.dashboardLifecycle.issueId,
|
|
1241
|
+
failedAt: event.timestamp,
|
|
1242
|
+
error
|
|
1243
|
+
}
|
|
1244
|
+
};
|
|
1245
|
+
}
|
|
1125
1246
|
default: return state;
|
|
1126
1247
|
}
|
|
1127
1248
|
}
|
|
@@ -1242,7 +1363,7 @@ const ReadModelServiceLive = Layer.effect(ReadModelService, Effect.gen(function*
|
|
|
1242
1363
|
yield* Effect.gen(function* () {
|
|
1243
1364
|
let usedProjectionCache = false;
|
|
1244
1365
|
try {
|
|
1245
|
-
const { getProjectionCache } = yield* Effect.promise(() => import("./projection-cache-
|
|
1366
|
+
const { getProjectionCache } = yield* Effect.promise(() => import("./projection-cache-C0EL8s8h.js"));
|
|
1246
1367
|
projectionCache = getProjectionCache();
|
|
1247
1368
|
const cached = projectionCache.load();
|
|
1248
1369
|
if (cached && cached.sequence > 0) {
|
|
@@ -1285,10 +1406,10 @@ const ReadModelServiceLive = Layer.effect(ReadModelService, Effect.gen(function*
|
|
|
1285
1406
|
} catch {}
|
|
1286
1407
|
if (!usedProjectionCache) {
|
|
1287
1408
|
const [{ listRunningAgents, warnOnBareNumericIssueIds }, { getAllSpecialists, getSpecialistState }, { loadReviewStatuses, getReviewStatus }, { computeAgentEnrichment }] = yield* Effect.all([
|
|
1288
|
-
Effect.promise(() => import("./agents-
|
|
1289
|
-
Effect.promise(() => import("./specialists-
|
|
1290
|
-
Effect.promise(() => import("./review-status-
|
|
1291
|
-
Effect.promise(() => import("./agent-enrichment-
|
|
1409
|
+
Effect.promise(() => import("./agents-Dgh2TjSp.js")),
|
|
1410
|
+
Effect.promise(() => import("./specialists-Cp-PgspS.js")),
|
|
1411
|
+
Effect.promise(() => import("./review-status-BtXqWBhS.js")),
|
|
1412
|
+
Effect.promise(() => import("./agent-enrichment-dLeGE1fX.js"))
|
|
1292
1413
|
]);
|
|
1293
1414
|
warnOnBareNumericIssueIds();
|
|
1294
1415
|
const running = listRunningAgents();
|
|
@@ -1354,7 +1475,7 @@ const ReadModelServiceLive = Layer.effect(ReadModelService, Effect.gen(function*
|
|
|
1354
1475
|
};
|
|
1355
1476
|
let sequence = 0;
|
|
1356
1477
|
try {
|
|
1357
|
-
const { getEventStore } = yield* Effect.promise(() => import("./event-store-
|
|
1478
|
+
const { getEventStore } = yield* Effect.promise(() => import("./event-store-VWWUmOfn.js"));
|
|
1358
1479
|
sequence = getEventStore().getLatestSequence();
|
|
1359
1480
|
} catch {}
|
|
1360
1481
|
state = {
|
|
@@ -1368,7 +1489,7 @@ const ReadModelServiceLive = Layer.effect(ReadModelService, Effect.gen(function*
|
|
|
1368
1489
|
console.log(`[ReadModel] Bootstrapped: ${Object.keys(agentsById).length} agents, ${Object.keys(specialistsByName).length} specialists, ${Object.keys(reviewStatusByIssueId).length} review statuses, seq=${sequence}`);
|
|
1369
1490
|
}
|
|
1370
1491
|
try {
|
|
1371
|
-
const { getSharedIssueService } = yield* Effect.promise(() => import("./issue-service-singleton-
|
|
1492
|
+
const { getSharedIssueService } = yield* Effect.promise(() => import("./issue-service-singleton-Co__-6kL.js"));
|
|
1372
1493
|
const issueService = getSharedIssueService();
|
|
1373
1494
|
const currentIssues = JSON.parse(JSON.stringify(issueService.getIssues()));
|
|
1374
1495
|
if (currentIssues.length > 0 || !usedProjectionCache) state = {
|
|
@@ -1383,7 +1504,7 @@ const ReadModelServiceLive = Layer.effect(ReadModelService, Effect.gen(function*
|
|
|
1383
1504
|
};
|
|
1384
1505
|
projectionCache?.save(buildSnapshot());
|
|
1385
1506
|
try {
|
|
1386
|
-
if (!_cachedEventStore) import("./event-store-
|
|
1507
|
+
if (!_cachedEventStore) import("./event-store-VWWUmOfn.js").then(({ getEventStore }) => {
|
|
1387
1508
|
_cachedEventStore = getEventStore();
|
|
1388
1509
|
try {
|
|
1389
1510
|
_cachedEventStore.append({
|
|
@@ -1438,6 +1559,7 @@ const EventStoreServiceLive = Layer.effect(EventStoreService, Effect.gen(functio
|
|
|
1438
1559
|
return {
|
|
1439
1560
|
append: (event) => Effect.sync(() => store.append(event)),
|
|
1440
1561
|
readFrom: (fromSequence) => Effect.sync(() => store.readFrom(fromSequence)),
|
|
1562
|
+
queryByType: (type, limit) => Effect.sync(() => store.queryByType(type, limit)),
|
|
1441
1563
|
getLatestSequence: Effect.sync(() => store.getLatestSequence()),
|
|
1442
1564
|
streamEvents
|
|
1443
1565
|
};
|
|
@@ -1730,6 +1852,7 @@ init_js_yaml();
|
|
|
1730
1852
|
init_model_capabilities();
|
|
1731
1853
|
init_config_yaml();
|
|
1732
1854
|
var import_dist = /* @__PURE__ */ __toESM(require_dist(), 1);
|
|
1855
|
+
init_issue_id();
|
|
1733
1856
|
init_projects();
|
|
1734
1857
|
init_tracker_config();
|
|
1735
1858
|
/**
|
|
@@ -2167,7 +2290,7 @@ function wrapRallyError(err) {
|
|
|
2167
2290
|
const RallyClientLive = Layer.effect(RallyClient, Effect.gen(function* () {
|
|
2168
2291
|
const config = getRallyConfig();
|
|
2169
2292
|
if (!config) return yield* Effect.fail(new TrackerNotConfigured({ tracker: "rally" }));
|
|
2170
|
-
const { RallyTracker } = yield* Effect.promise(() => import("./rally-
|
|
2293
|
+
const { RallyTracker } = yield* Effect.promise(() => import("./rally-6McpKKRa.js"));
|
|
2171
2294
|
const tracker = new RallyTracker({
|
|
2172
2295
|
apiKey: config.apiKey,
|
|
2173
2296
|
server: config.server,
|
|
@@ -2404,7 +2527,7 @@ const IssueLifecycleLive = Layer.effect(IssueLifecycle, Effect.gen(function* ()
|
|
|
2404
2527
|
}));
|
|
2405
2528
|
IssueLifecycleLive.pipe(Layer.provide(LinearClientOptionalLive), Layer.provide(GitHubClientOptionalLive), Layer.provide(Layer.effect(RallyClient, Effect.gen(function* () {
|
|
2406
2529
|
return yield* Effect.gen(function* () {
|
|
2407
|
-
const { getRallyConfig } = yield* Effect.promise(() => import("./tracker-config-
|
|
2530
|
+
const { getRallyConfig } = yield* Effect.promise(() => import("./tracker-config-BP59uH4V.js"));
|
|
2408
2531
|
if (!getRallyConfig()) {
|
|
2409
2532
|
const fail = Effect.fail(new TrackerNotConfigured({ tracker: "rally" }));
|
|
2410
2533
|
return {
|
|
@@ -2437,7 +2560,7 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
|
|
|
2437
2560
|
const beadsDir = join$1(workspacePath, ".beads");
|
|
2438
2561
|
const projectBeadsDir = join$1(workspacePath, "..", "..", ".beads");
|
|
2439
2562
|
if (!(existsSync$1(beadsDir) || existsSync$1(projectBeadsDir))) throw new BeadsNotInitialized({ workspace: workspacePath });
|
|
2440
|
-
const { getAgentState, spawnAgent, normalizeAgentId } = await import("./agents-
|
|
2563
|
+
const { getAgentState, spawnAgent, normalizeAgentId } = await import("./agents-Dgh2TjSp.js");
|
|
2441
2564
|
const normalizedId = normalizeAgentId(issueId);
|
|
2442
2565
|
if (getAgentState(normalizedId)?.status === "running") throw new AgentAlreadyRunning({ id: issueId });
|
|
2443
2566
|
return {
|
|
@@ -2474,7 +2597,7 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
|
|
|
2474
2597
|
const { writeFile } = fsp;
|
|
2475
2598
|
await writeFile(planningPromptPath, opts.issue.description ?? "", "utf-8");
|
|
2476
2599
|
const sessionName = opts.sessionName ?? `planning-${issueId.toLowerCase()}`;
|
|
2477
|
-
const { spawnPlanningSession } = await import("./spawn-planning-session-
|
|
2600
|
+
const { spawnPlanningSession } = await import("./spawn-planning-session-D5hrVdWM.js");
|
|
2478
2601
|
const result = await spawnPlanningSession({
|
|
2479
2602
|
issue: {
|
|
2480
2603
|
id: issue.id,
|
|
@@ -2506,14 +2629,14 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
|
|
|
2506
2629
|
}),
|
|
2507
2630
|
kill: (agentId) => Effect.tryPromise({
|
|
2508
2631
|
try: async () => {
|
|
2509
|
-
const { stopAgent } = await import("./agents-
|
|
2632
|
+
const { stopAgent } = await import("./agents-Dgh2TjSp.js");
|
|
2510
2633
|
stopAgent(agentId);
|
|
2511
2634
|
},
|
|
2512
2635
|
catch: () => void 0
|
|
2513
2636
|
}).pipe(Effect.ignore),
|
|
2514
2637
|
message: (agentId, msg) => Effect.tryPromise({
|
|
2515
2638
|
try: async () => {
|
|
2516
|
-
const { messageAgent } = await import("./agents-
|
|
2639
|
+
const { messageAgent } = await import("./agents-Dgh2TjSp.js");
|
|
2517
2640
|
await messageAgent(agentId, msg);
|
|
2518
2641
|
},
|
|
2519
2642
|
catch: (err) => new AgentStartError({
|
|
@@ -2524,8 +2647,8 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
|
|
|
2524
2647
|
}),
|
|
2525
2648
|
deepWipe: (issueId, opts) => Effect.tryPromise({
|
|
2526
2649
|
try: async () => {
|
|
2527
|
-
const { deepWipe } = await import("./workflows-
|
|
2528
|
-
const { resolveProjectFromIssue } = await import("./projects-
|
|
2650
|
+
const { deepWipe } = await import("./workflows-DaYWQIS2.js");
|
|
2651
|
+
const { resolveProjectFromIssue } = await import("./projects-C5ozxjwP.js");
|
|
2529
2652
|
const project = resolveProjectFromIssue(issueId);
|
|
2530
2653
|
await deepWipe({
|
|
2531
2654
|
issueId,
|
|
@@ -2579,8 +2702,8 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
|
|
|
2579
2702
|
const { workspacePath, branch } = getWorkspacePath(issueId);
|
|
2580
2703
|
const issueLower = issueId.toLowerCase();
|
|
2581
2704
|
if (existsSync$1(workspacePath)) return workspacePath;
|
|
2582
|
-
const { createWorkspace } = await import("./workspace-manager-
|
|
2583
|
-
const { loadProjectsConfig } = await import("./projects-
|
|
2705
|
+
const { createWorkspace } = await import("./workspace-manager-BYfzs_t2.js");
|
|
2706
|
+
const { loadProjectsConfig } = await import("./projects-C5ozxjwP.js");
|
|
2584
2707
|
const { projects } = loadProjectsConfig();
|
|
2585
2708
|
const project = resolveProjectFromIssue(issueId);
|
|
2586
2709
|
if (!project) throw new WorkspaceCreateError({
|
|
@@ -2615,7 +2738,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
|
|
|
2615
2738
|
const { workspacePath } = getWorkspacePath(issueId);
|
|
2616
2739
|
const issueLower = issueId.toLowerCase();
|
|
2617
2740
|
if (!existsSync$1(workspacePath)) throw new WorkspaceNotFound({ id: issueId });
|
|
2618
|
-
const { removeWorkspace } = await import("./workspace-manager-
|
|
2741
|
+
const { removeWorkspace } = await import("./workspace-manager-BYfzs_t2.js");
|
|
2619
2742
|
const project = resolveProjectFromIssue(issueId);
|
|
2620
2743
|
if (!project) throw new WorkspaceCreateError({
|
|
2621
2744
|
id: issueId,
|
|
@@ -2647,7 +2770,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
|
|
|
2647
2770
|
const { workspacePath } = getWorkspacePath(issueId);
|
|
2648
2771
|
const issueLower = issueId.toLowerCase();
|
|
2649
2772
|
const projectName = resolveProjectFromIssue(issueId)?.name ?? issueId;
|
|
2650
|
-
const { stopWorkspaceDocker } = await import("./workspace-manager-
|
|
2773
|
+
const { stopWorkspaceDocker } = await import("./workspace-manager-BYfzs_t2.js");
|
|
2651
2774
|
await stopWorkspaceDocker(workspacePath, projectName, issueLower);
|
|
2652
2775
|
},
|
|
2653
2776
|
catch: () => void 0
|
|
@@ -2716,7 +2839,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
|
|
|
2716
2839
|
join$1(workspacePath, ".devcontainer", "docker-compose.devcontainer.yml")
|
|
2717
2840
|
];
|
|
2718
2841
|
if (!composePaths.find((p) => existsSync$1(p))) {
|
|
2719
|
-
const { loadProjectsConfig } = await import("./projects-
|
|
2842
|
+
const { loadProjectsConfig } = await import("./projects-C5ozxjwP.js");
|
|
2720
2843
|
const { projects } = loadProjectsConfig();
|
|
2721
2844
|
const project = resolveProjectFromIssue(issueId);
|
|
2722
2845
|
if (!project) throw new WorkspaceCreateError({
|
|
@@ -2724,7 +2847,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
|
|
|
2724
2847
|
message: `No project configured for issue ${issueId} — cannot generate docker-compose.yml`
|
|
2725
2848
|
});
|
|
2726
2849
|
const projectName = Object.entries(projects).find(([, p]) => p.path === project.path)?.[0] ?? "unknown";
|
|
2727
|
-
const { createWorkspace } = await import("./workspace-manager-
|
|
2850
|
+
const { createWorkspace } = await import("./workspace-manager-BYfzs_t2.js");
|
|
2728
2851
|
const createResult = await createWorkspace({
|
|
2729
2852
|
projectConfig: {
|
|
2730
2853
|
...project,
|
|
@@ -6408,10 +6531,18 @@ var import_websocket_server = /* @__PURE__ */ __toESM(require_websocket_server()
|
|
|
6408
6531
|
/** Shared registry of active PTY hubs, keyed by tmux session name. */
|
|
6409
6532
|
const activePtyHubs = /* @__PURE__ */ new Map();
|
|
6410
6533
|
/**
|
|
6411
|
-
* Broadcast data to all open clients in the hub.
|
|
6534
|
+
* Broadcast data to all open clients in the hub, respecting per-client blackout periods.
|
|
6535
|
+
* Clients that are still within their 200ms blackout window receive nothing — this
|
|
6536
|
+
* prevents scrollback flooding when a browser tab reconnects to an existing hub.
|
|
6412
6537
|
*/
|
|
6413
6538
|
function broadcastToHub(hub, data) {
|
|
6414
|
-
|
|
6539
|
+
const now = Date.now();
|
|
6540
|
+
for (const client of hub.clients) {
|
|
6541
|
+
if (client.readyState !== import_websocket.default.OPEN) continue;
|
|
6542
|
+
const blackoutUntil = hub.clientBlackout.get(client);
|
|
6543
|
+
if (blackoutUntil && now < blackoutUntil) continue;
|
|
6544
|
+
client.send(data);
|
|
6545
|
+
}
|
|
6415
6546
|
}
|
|
6416
6547
|
/**
|
|
6417
6548
|
* Remove a client from its hub. If it was the last client, delete the hub entry
|
|
@@ -6426,6 +6557,7 @@ function removeClientFromHub(hubs, sessionName, ws) {
|
|
|
6426
6557
|
const hub = hubs.get(sessionName);
|
|
6427
6558
|
if (!hub) return false;
|
|
6428
6559
|
hub.clients.delete(ws);
|
|
6560
|
+
hub.clientBlackout.delete(ws);
|
|
6429
6561
|
if (hub.clients.size === 0) {
|
|
6430
6562
|
hubs.delete(sessionName);
|
|
6431
6563
|
return true;
|
|
@@ -6493,6 +6625,7 @@ function setupTerminalWebSocket(server) {
|
|
|
6493
6625
|
console.log(`[ws-terminal] Joining existing PTY hub for ${sessionName} (${existingHub.clients.size} existing clients)`);
|
|
6494
6626
|
existingHub.clients.add(ws);
|
|
6495
6627
|
existingHub.inputClient = ws;
|
|
6628
|
+
existingHub.clientBlackout.set(ws, Date.now() + 200);
|
|
6496
6629
|
const { cols, rows } = existingHub;
|
|
6497
6630
|
setTimeout(() => {
|
|
6498
6631
|
if (existingHub.clients.has(ws) && ws.readyState === import_websocket.default.OPEN) try {
|
|
@@ -6551,7 +6684,8 @@ function setupTerminalWebSocket(server) {
|
|
|
6551
6684
|
clients: new Set([ws]),
|
|
6552
6685
|
cols: 120,
|
|
6553
6686
|
rows: 29,
|
|
6554
|
-
inputClient: ws
|
|
6687
|
+
inputClient: ws,
|
|
6688
|
+
clientBlackout: new Map([[ws, Date.now() + 200]])
|
|
6555
6689
|
};
|
|
6556
6690
|
const startLocalPty = async (cols, rows) => {
|
|
6557
6691
|
if (ptyStarted) return;
|
|
@@ -6751,6 +6885,7 @@ function canReplaceTitle(conv) {
|
|
|
6751
6885
|
* All file I/O uses fs/promises (no sync calls).
|
|
6752
6886
|
*/
|
|
6753
6887
|
init_cost();
|
|
6888
|
+
init_paths();
|
|
6754
6889
|
/** Detect AI provider from model name */
|
|
6755
6890
|
function providerFromModel(model) {
|
|
6756
6891
|
if (model.includes("gpt")) return "openai";
|
|
@@ -7357,7 +7492,7 @@ const DEFAULT_EVENTS_SUBDIR$1 = ".pan/events";
|
|
|
7357
7492
|
*/
|
|
7358
7493
|
function resolveWalDir(issueId) {
|
|
7359
7494
|
const projects = listProjects();
|
|
7360
|
-
const issuePrefix = issueId
|
|
7495
|
+
const issuePrefix = extractPrefix(issueId);
|
|
7361
7496
|
if (!issuePrefix) return null;
|
|
7362
7497
|
for (const { key, config } of projects) {
|
|
7363
7498
|
const projectKey = key.toUpperCase();
|
|
@@ -7750,6 +7885,7 @@ function getCostsForIssue(issueId) {
|
|
|
7750
7885
|
* Migrates historical session data to the event-sourced format.
|
|
7751
7886
|
* Includes both main session files and subagent session files.
|
|
7752
7887
|
*/
|
|
7888
|
+
init_paths();
|
|
7753
7889
|
init_cost();
|
|
7754
7890
|
function getAgentsDir$1() {
|
|
7755
7891
|
return join(process.env.HOME || homedir$1(), ".panopticon", "agents");
|
|
@@ -7882,7 +8018,7 @@ function usageToCostEvents(usages, context) {
|
|
|
7882
8018
|
* Find session directory for a workspace
|
|
7883
8019
|
*/
|
|
7884
8020
|
function getSessionDir(workspacePath) {
|
|
7885
|
-
const sessionDirName =
|
|
8021
|
+
const sessionDirName = encodeClaudeProjectDir(workspacePath);
|
|
7886
8022
|
const sessionDir = join(getClaudeProjectsDir$1(), sessionDirName);
|
|
7887
8023
|
if (existsSync(sessionDir)) return sessionDir;
|
|
7888
8024
|
return null;
|
|
@@ -8507,6 +8643,7 @@ function getHandoffStats() {
|
|
|
8507
8643
|
* GET /api/issues/:id/costs
|
|
8508
8644
|
*/
|
|
8509
8645
|
init_projects();
|
|
8646
|
+
init_issue_id();
|
|
8510
8647
|
init_tracker_config();
|
|
8511
8648
|
init_tmux();
|
|
8512
8649
|
const execAsync$16 = promisify(exec);
|
|
@@ -8658,9 +8795,8 @@ const postIssuePlanRoute = HttpRouter.add("POST", "/api/issues/:id/plan", httpHa
|
|
|
8658
8795
|
if (!tasks || !Array.isArray(tasks) || tasks.length === 0) return jsonResponse({ error: "Tasks are required" }, { status: 400 });
|
|
8659
8796
|
const issue = yield* Effect.promise(() => Effect.runPromise(linear.getIssue(id).pipe(Effect.catch(() => Effect.succeed(null)))));
|
|
8660
8797
|
if (!issue) return jsonResponse({ error: "Issue not found" }, { status: 404 });
|
|
8661
|
-
const
|
|
8662
|
-
const
|
|
8663
|
-
const { findPRDFiles, analyzeComplexity, executePlan } = yield* Effect.promise(() => import("./plan-utils-BkCIhn3B.js"));
|
|
8798
|
+
const projectPath = getProjectPath$4(void 0, extractPrefix(issue.identifier) ?? issue.identifier.split("-")[0]);
|
|
8799
|
+
const { findPRDFiles, analyzeComplexity, executePlan } = yield* Effect.promise(() => import("./plan-utils-Bkcsqr_s.js"));
|
|
8664
8800
|
const prdFiles = yield* Effect.promise(() => findPRDFiles(issue.identifier, projectPath));
|
|
8665
8801
|
const planIssue = {
|
|
8666
8802
|
id: issue.id,
|
|
@@ -8717,9 +8853,8 @@ const postIssueCloseRoute = HttpRouter.add("POST", "/api/issues/:issueId/close",
|
|
|
8717
8853
|
const body = yield* readJsonBody$9;
|
|
8718
8854
|
const eventStore = yield* EventStoreService;
|
|
8719
8855
|
const { reason } = body;
|
|
8720
|
-
const
|
|
8721
|
-
const
|
|
8722
|
-
const { close: closeWorkflow } = yield* Effect.promise(() => import("./lifecycle-ZTYdrr2O.js"));
|
|
8856
|
+
const projectPath = getProjectPath$4(void 0, extractPrefix(issueId) ?? issueId.split("-")[0]);
|
|
8857
|
+
const { close: closeWorkflow } = yield* Effect.promise(() => import("./lifecycle-BcUmtkR4.js"));
|
|
8723
8858
|
const githubCheck = isGitHubIssue$1(issueId);
|
|
8724
8859
|
const issueDataService = getIssueDataService$3();
|
|
8725
8860
|
const issueSource = issueDataService.getIssueSource(issueId);
|
|
@@ -8823,8 +8958,7 @@ const postIssueStartPlanningRoute = HttpRouter.add("POST", "/api/issues/:id/star
|
|
|
8823
8958
|
};
|
|
8824
8959
|
yield* Effect.promise(() => Effect.runPromise(lifecycle.transitionTo(id, "in_planning").pipe(Effect.catch(() => Effect.void))));
|
|
8825
8960
|
}
|
|
8826
|
-
const
|
|
8827
|
-
const projectPath = getProjectPath$4(void 0, issuePrefix);
|
|
8961
|
+
const projectPath = getProjectPath$4(void 0, extractPrefix(issue.identifier) ?? issue.identifier.split("-")[0]);
|
|
8828
8962
|
const issueLower = issue.identifier.toLowerCase();
|
|
8829
8963
|
const workspacePath = join$1(projectPath, "workspaces", `feature-${issueLower}`);
|
|
8830
8964
|
const sessionName = `planning-${issueLower}`;
|
|
@@ -9003,7 +9137,7 @@ const postIssueAbortPlanningRoute = HttpRouter.add("POST", "/api/issues/:id/abor
|
|
|
9003
9137
|
let projectPath;
|
|
9004
9138
|
if (githubCheck.isGitHub && githubCheck.owner && githubCheck.repo) projectPath = getGitHubLocalPaths$1()[`${githubCheck.owner}/${githubCheck.repo}`];
|
|
9005
9139
|
if (!projectPath) {
|
|
9006
|
-
const projConfig = findProjectByTeam(issueIdentifier.split("-")[0].toUpperCase());
|
|
9140
|
+
const projConfig = findProjectByTeam(extractPrefix(issueIdentifier) ?? issueIdentifier.split("-")[0].toUpperCase());
|
|
9007
9141
|
if (projConfig) projectPath = projConfig.path;
|
|
9008
9142
|
}
|
|
9009
9143
|
if (projectPath) {
|
|
@@ -9143,8 +9277,8 @@ const postIssueCompletePlanningRoute = HttpRouter.add("POST", "/api/issues/:id/c
|
|
|
9143
9277
|
try {
|
|
9144
9278
|
const gitRoot = planningDir.includes("/workspaces/") ? join$1(projectPath, "workspaces", `feature-${issueLower}`) : projectPath;
|
|
9145
9279
|
let beadsWarning = null;
|
|
9146
|
-
const { findPlan } = await import("./io-
|
|
9147
|
-
const { createBeadsFromVBrief } = await import("./beads-
|
|
9280
|
+
const { findPlan } = await import("./io-CWlFW78i.js");
|
|
9281
|
+
const { createBeadsFromVBrief } = await import("./beads-By6-X07V.js");
|
|
9148
9282
|
if (findPlan(gitRoot)) try {
|
|
9149
9283
|
const beadsResult = await createBeadsFromVBrief(gitRoot);
|
|
9150
9284
|
if (beadsResult.created.length > 0) console.log(`[complete-planning] Created ${beadsResult.created.length} beads from vBRIEF plan`);
|
|
@@ -9305,7 +9439,7 @@ const postIssueResetRoute = HttpRouter.add("POST", "/api/issues/:id/reset", http
|
|
|
9305
9439
|
cleanupLog.push(`Deleted agent state: ${dir}`);
|
|
9306
9440
|
}
|
|
9307
9441
|
try {
|
|
9308
|
-
const { removeShadowState } = await import("./shadow-state-
|
|
9442
|
+
const { removeShadowState } = await import("./shadow-state-BIexcxkv.js");
|
|
9309
9443
|
if (removeShadowState(id).success) cleanupLog.push(`Cleared shadow state for ${id}`);
|
|
9310
9444
|
} catch {}
|
|
9311
9445
|
try {
|
|
@@ -9401,14 +9535,14 @@ const postIssueCancelRoute = HttpRouter.add("POST", "/api/issues/:id/cancel", ht
|
|
|
9401
9535
|
cleanupLog.push("Cleared review status");
|
|
9402
9536
|
} catch {}
|
|
9403
9537
|
try {
|
|
9404
|
-
const { removeShadowState } = await import("./shadow-state-
|
|
9538
|
+
const { removeShadowState } = await import("./shadow-state-BIexcxkv.js");
|
|
9405
9539
|
removeShadowState(id);
|
|
9406
9540
|
cleanupLog.push("Cleared shadow state");
|
|
9407
9541
|
} catch {}
|
|
9408
9542
|
});
|
|
9409
9543
|
if (wipeWorkspace) yield* Effect.promise(async () => {
|
|
9410
9544
|
try {
|
|
9411
|
-
const { deepWipe } = await import("./lifecycle-
|
|
9545
|
+
const { deepWipe } = await import("./lifecycle-BcUmtkR4.js");
|
|
9412
9546
|
const issuePrefix = extractTeamPrefix(id);
|
|
9413
9547
|
const projectPath = getProjectPath$4(void 0, issuePrefix);
|
|
9414
9548
|
const projectConfig = findProjectByTeam(issuePrefix);
|
|
@@ -9510,7 +9644,7 @@ const postIssueReopenRoute = HttpRouter.add("POST", "/api/issues/:id/reopen", ht
|
|
|
9510
9644
|
yield* Effect.promise(async () => {
|
|
9511
9645
|
try {
|
|
9512
9646
|
clearReviewStatus(id.toUpperCase());
|
|
9513
|
-
const { checkSpecialistQueue, completeSpecialistTask } = await import("./specialists-
|
|
9647
|
+
const { checkSpecialistQueue, completeSpecialistTask } = await import("./specialists-Cp-PgspS.js");
|
|
9514
9648
|
for (const specialist of [
|
|
9515
9649
|
"review-agent",
|
|
9516
9650
|
"test-agent",
|
|
@@ -9521,7 +9655,7 @@ const postIssueReopenRoute = HttpRouter.add("POST", "/api/issues/:id/reopen", ht
|
|
|
9521
9655
|
}
|
|
9522
9656
|
} catch {}
|
|
9523
9657
|
try {
|
|
9524
|
-
const { resetPostMergeState } = await import("./merge-agent-
|
|
9658
|
+
const { resetPostMergeState } = await import("./merge-agent-CGN3TT0a.js");
|
|
9525
9659
|
resetPostMergeState(id);
|
|
9526
9660
|
resetPostMergeState(id.toUpperCase());
|
|
9527
9661
|
} catch {}
|
|
@@ -9543,8 +9677,8 @@ const postIssueReopenRoute = HttpRouter.add("POST", "/api/issues/:id/reopen", ht
|
|
|
9543
9677
|
const projectPath = (teamPrefix ? findProjectByTeam(teamPrefix) : null)?.path || "";
|
|
9544
9678
|
if (projectPath) {
|
|
9545
9679
|
const workspacePath = join$1(projectPath, "workspaces", `feature-${issueLower}`);
|
|
9546
|
-
const { findPlan } = await import("./io-
|
|
9547
|
-
const { createBeadsFromVBrief } = await import("./beads-
|
|
9680
|
+
const { findPlan } = await import("./io-CWlFW78i.js");
|
|
9681
|
+
const { createBeadsFromVBrief } = await import("./beads-By6-X07V.js");
|
|
9548
9682
|
if (existsSync$1(workspacePath) && findPlan(workspacePath)) try {
|
|
9549
9683
|
const { stdout: bdCheck } = await execAsync$16(`bd list --json -l ${issueLower} --limit 1`, {
|
|
9550
9684
|
cwd: workspacePath,
|
|
@@ -9615,7 +9749,7 @@ const postIssueMoveStatusRoute = HttpRouter.add("POST", "/api/issues/:id/move-st
|
|
|
9615
9749
|
"done"
|
|
9616
9750
|
];
|
|
9617
9751
|
if (!targetStatus || !validStatuses.includes(targetStatus)) return jsonResponse({ error: `Invalid targetStatus. Must be one of: ${validStatuses.join(", ")}` }, { status: 400 });
|
|
9618
|
-
const { updateShadowState } = yield* Effect.promise(() => import("./shadow-state-
|
|
9752
|
+
const { updateShadowState } = yield* Effect.promise(() => import("./shadow-state-BIexcxkv.js"));
|
|
9619
9753
|
const issueState = {
|
|
9620
9754
|
backlog: "open",
|
|
9621
9755
|
todo: "open",
|
|
@@ -9737,7 +9871,7 @@ const postIssueDeepWipeRoute = HttpRouter.add("POST", "/api/issues/:id/deep-wipe
|
|
|
9737
9871
|
const body = yield* readJsonBody$9;
|
|
9738
9872
|
const eventStore = yield* EventStoreService;
|
|
9739
9873
|
const { deleteWorkspace = false } = body || {};
|
|
9740
|
-
const { deepWipe } = yield* Effect.promise(() => import("./lifecycle-
|
|
9874
|
+
const { deepWipe } = yield* Effect.promise(() => import("./lifecycle-BcUmtkR4.js"));
|
|
9741
9875
|
const githubCheck = isGitHubIssue$1(id);
|
|
9742
9876
|
let projectPath = "";
|
|
9743
9877
|
let projectName = "";
|
|
@@ -9747,7 +9881,7 @@ const postIssueDeepWipeRoute = HttpRouter.add("POST", "/api/issues/:id/deep-wipe
|
|
|
9747
9881
|
projectName = githubCheck.repo || "";
|
|
9748
9882
|
}
|
|
9749
9883
|
if (!projectPath) {
|
|
9750
|
-
projectConfig = findProjectByTeam(id.split("-")[0].toUpperCase());
|
|
9884
|
+
projectConfig = findProjectByTeam(extractPrefix(id) ?? id.split("-")[0].toUpperCase());
|
|
9751
9885
|
if (projectConfig) {
|
|
9752
9886
|
projectPath = projectConfig.path;
|
|
9753
9887
|
projectName = projectConfig.name;
|
|
@@ -9838,11 +9972,11 @@ const postIssueDeepWipeRoute = HttpRouter.add("POST", "/api/issues/:id/deep-wipe
|
|
|
9838
9972
|
const postIssueCloseOutRoute = HttpRouter.add("POST", "/api/issues/:id/close-out", httpHandler(Effect.gen(function* () {
|
|
9839
9973
|
const id = (yield* HttpRouter.params)["id"] ?? "";
|
|
9840
9974
|
const eventStore = yield* EventStoreService;
|
|
9841
|
-
const { closeOut } = yield* Effect.promise(() => import("./lifecycle-
|
|
9975
|
+
const { closeOut } = yield* Effect.promise(() => import("./lifecycle-BcUmtkR4.js"));
|
|
9842
9976
|
const githubCheck = isGitHubIssue$1(id);
|
|
9843
9977
|
let projectPath = "";
|
|
9844
9978
|
if (githubCheck.isGitHub && githubCheck.owner && githubCheck.repo) projectPath = getGitHubLocalPaths$1()[`${githubCheck.owner}/${githubCheck.repo}`] || "";
|
|
9845
|
-
if (!projectPath) projectPath = getProjectPath$4(void 0, id.split("-")[0].toUpperCase());
|
|
9979
|
+
if (!projectPath) projectPath = getProjectPath$4(void 0, extractPrefix(id) ?? id.split("-")[0].toUpperCase());
|
|
9846
9980
|
if (!projectPath) return jsonResponse({ error: `Could not resolve project path for ${id}` }, { status: 400 });
|
|
9847
9981
|
const ctx = {
|
|
9848
9982
|
issueId: id,
|
|
@@ -9901,7 +10035,7 @@ const getIssueBeadsRoute = HttpRouter.add("GET", "/api/issues/:id/beads", httpHa
|
|
|
9901
10035
|
let projectPath = "";
|
|
9902
10036
|
if (githubCheck.isGitHub && githubCheck.owner && githubCheck.repo) projectPath = getGitHubLocalPaths$1()[`${githubCheck.owner}/${githubCheck.repo}`] || "";
|
|
9903
10037
|
if (!projectPath) {
|
|
9904
|
-
const issuePrefix = id.split("-")[0];
|
|
10038
|
+
const issuePrefix = extractPrefix(id) ?? id.split("-")[0];
|
|
9905
10039
|
try {
|
|
9906
10040
|
projectPath = getProjectPath$4(void 0, issuePrefix);
|
|
9907
10041
|
} catch {
|
|
@@ -12148,10 +12282,10 @@ async function checkOrphanedReviewStatuses() {
|
|
|
12148
12282
|
const workspace = getAgentState(agentIdForCheck)?.workspace;
|
|
12149
12283
|
if (workspace) {
|
|
12150
12284
|
const branch = `feature/${issueId.toLowerCase()}`;
|
|
12151
|
-
const { resolveProjectFromIssue } = await import("./projects-
|
|
12285
|
+
const { resolveProjectFromIssue } = await import("./projects-C5ozxjwP.js");
|
|
12152
12286
|
const resolved = resolveProjectFromIssue(issueId);
|
|
12153
12287
|
if (resolved) {
|
|
12154
|
-
const { spawnEphemeralSpecialist } = await import("./specialists-
|
|
12288
|
+
const { spawnEphemeralSpecialist } = await import("./specialists-Cp-PgspS.js");
|
|
12155
12289
|
const result = await spawnEphemeralSpecialist(resolved.projectKey, "review-agent", {
|
|
12156
12290
|
issueId,
|
|
12157
12291
|
workspace,
|
|
@@ -12164,7 +12298,7 @@ async function checkOrphanedReviewStatuses() {
|
|
|
12164
12298
|
actions.push(`Re-dispatched pending review for ${issueId} via ${resolved.projectKey}/review-agent (deacon-orphan-recovery)`);
|
|
12165
12299
|
console.log(`[deacon] Re-dispatched review for ${issueId} after orphan/pending detection (project: ${resolved.projectKey})`);
|
|
12166
12300
|
} else if (result.error === "specialist_busy") {
|
|
12167
|
-
const { submitToSpecialistQueue } = await import("./specialists-
|
|
12301
|
+
const { submitToSpecialistQueue } = await import("./specialists-Cp-PgspS.js");
|
|
12168
12302
|
submitToSpecialistQueue("review-agent", {
|
|
12169
12303
|
priority: "high",
|
|
12170
12304
|
source: "deacon-orphan-recovery",
|
|
@@ -12202,10 +12336,10 @@ async function checkOrphanedReviewStatuses() {
|
|
|
12202
12336
|
const workspace = getAgentState(`agent-${issueId.toLowerCase()}`)?.workspace;
|
|
12203
12337
|
if (workspace) {
|
|
12204
12338
|
const branch = `feature/${issueId.toLowerCase()}`;
|
|
12205
|
-
const { resolveProjectFromIssue } = await import("./projects-
|
|
12339
|
+
const { resolveProjectFromIssue } = await import("./projects-C5ozxjwP.js");
|
|
12206
12340
|
const resolved = resolveProjectFromIssue(issueId);
|
|
12207
12341
|
if (resolved) {
|
|
12208
|
-
const { spawnEphemeralSpecialist } = await import("./specialists-
|
|
12342
|
+
const { spawnEphemeralSpecialist } = await import("./specialists-Cp-PgspS.js");
|
|
12209
12343
|
const result = await spawnEphemeralSpecialist(resolved.projectKey, "test-agent", {
|
|
12210
12344
|
issueId,
|
|
12211
12345
|
workspace,
|
|
@@ -12217,7 +12351,7 @@ async function checkOrphanedReviewStatuses() {
|
|
|
12217
12351
|
actions.push(`Re-dispatched orphaned test for ${issueId} via ${resolved.projectKey}/test-agent (deacon-orphan-recovery)`);
|
|
12218
12352
|
console.log(`[deacon] Re-dispatched test for ${issueId} after orphan detection (project: ${resolved.projectKey})`);
|
|
12219
12353
|
} else if (result.error === "specialist_busy") {
|
|
12220
|
-
const { submitToSpecialistQueue } = await import("./specialists-
|
|
12354
|
+
const { submitToSpecialistQueue } = await import("./specialists-Cp-PgspS.js");
|
|
12221
12355
|
submitToSpecialistQueue("test-agent", {
|
|
12222
12356
|
priority: "high",
|
|
12223
12357
|
source: "deacon-orphan-recovery",
|
|
@@ -12273,7 +12407,7 @@ async function checkPostReviewCommits() {
|
|
|
12273
12407
|
const actions = [];
|
|
12274
12408
|
try {
|
|
12275
12409
|
const statuses = loadReviewStatuses();
|
|
12276
|
-
const { resolveProjectFromIssue } = await import("./projects-
|
|
12410
|
+
const { resolveProjectFromIssue } = await import("./projects-C5ozxjwP.js");
|
|
12277
12411
|
for (const [issueId, status] of Object.entries(statuses)) {
|
|
12278
12412
|
if (status.mergeStatus === "merged") continue;
|
|
12279
12413
|
if (!status.reviewedAtCommit) continue;
|
|
@@ -12586,9 +12720,9 @@ async function patrolWorkAgentResolutions() {
|
|
|
12586
12720
|
async function checkSpecialistQueues() {
|
|
12587
12721
|
const actions = [];
|
|
12588
12722
|
try {
|
|
12589
|
-
const { checkSpecialistQueue, spawnEphemeralSpecialist, getTmuxSessionName, isRunning } = await import("./specialists-
|
|
12590
|
-
const { getAgentRuntimeState } = await import("./agents-
|
|
12591
|
-
const { resolveProjectFromIssue } = await import("./projects-
|
|
12723
|
+
const { checkSpecialistQueue, spawnEphemeralSpecialist, getTmuxSessionName, isRunning } = await import("./specialists-Cp-PgspS.js");
|
|
12724
|
+
const { getAgentRuntimeState } = await import("./agents-Dgh2TjSp.js");
|
|
12725
|
+
const { resolveProjectFromIssue } = await import("./projects-C5ozxjwP.js");
|
|
12592
12726
|
for (const specialistType of [
|
|
12593
12727
|
"review-agent",
|
|
12594
12728
|
"test-agent",
|
|
@@ -12622,7 +12756,7 @@ async function checkSpecialistQueues() {
|
|
|
12622
12756
|
if (!isIdle) continue;
|
|
12623
12757
|
console.log(`[deacon] Dispatching queued ${specialistType} work for ${issueId} (project: ${resolved.projectKey})`);
|
|
12624
12758
|
try {
|
|
12625
|
-
const { findWorkspacePath } = await import("./archive-planning-
|
|
12759
|
+
const { findWorkspacePath } = await import("./archive-planning-C3Ebf9yC.js");
|
|
12626
12760
|
const workspacePath = findWorkspacePath(resolved.projectPath, issueId.toLowerCase());
|
|
12627
12761
|
const queuePayload = item.payload;
|
|
12628
12762
|
await spawnEphemeralSpecialist(resolved.projectKey, specialistType, {
|
|
@@ -12758,7 +12892,7 @@ async function runPatrol() {
|
|
|
12758
12892
|
if (!existsSync(REVIEW_STATUS_FILE)) continue;
|
|
12759
12893
|
const statuses = JSON.parse(readFileSync(REVIEW_STATUS_FILE, "utf-8"));
|
|
12760
12894
|
if (statuses[issueId]?.mergeStatus === "merging") {
|
|
12761
|
-
const { resolveProjectFromIssue } = await import("./projects-
|
|
12895
|
+
const { resolveProjectFromIssue } = await import("./projects-C5ozxjwP.js");
|
|
12762
12896
|
const resolved = resolveProjectFromIssue(issueId);
|
|
12763
12897
|
if (resolved) {
|
|
12764
12898
|
const branch = `feature/${issueId.toLowerCase()}`;
|
|
@@ -12768,7 +12902,7 @@ async function runPatrol() {
|
|
|
12768
12902
|
statuses[issueId].mergeStatus = "merged";
|
|
12769
12903
|
statuses[issueId].readyForMerge = false;
|
|
12770
12904
|
writeFileSync(REVIEW_STATUS_FILE, JSON.stringify(statuses, null, 2), "utf-8");
|
|
12771
|
-
const { postMergeLifecycle } = await import("./merge-agent-
|
|
12905
|
+
const { postMergeLifecycle } = await import("./merge-agent-CGN3TT0a.js");
|
|
12772
12906
|
postMergeLifecycle(issueId, resolved.projectPath).catch((err) => console.warn(`[deacon] postMergeLifecycle failed for ${issueId}: ${err}`));
|
|
12773
12907
|
actions.push(`Auto-completed stale merge for ${issueId}`);
|
|
12774
12908
|
} else {
|
|
@@ -13026,7 +13160,7 @@ var CloisterService = class {
|
|
|
13026
13160
|
}
|
|
13027
13161
|
try {
|
|
13028
13162
|
if (existsSync(AGENTS_DIR)) {
|
|
13029
|
-
const { isRunning: isSpecialistRunning } = await import("./specialists-
|
|
13163
|
+
const { isRunning: isSpecialistRunning } = await import("./specialists-Cp-PgspS.js");
|
|
13030
13164
|
const specialistPattern = /^specialist-(.+)-(review-agent|test-agent|merge-agent)$/;
|
|
13031
13165
|
const entries = readdirSync(AGENTS_DIR, { withFileTypes: true });
|
|
13032
13166
|
for (const entry of entries) {
|
|
@@ -13057,8 +13191,8 @@ var CloisterService = class {
|
|
|
13057
13191
|
}
|
|
13058
13192
|
try {
|
|
13059
13193
|
const reviewStatuses = loadReviewStatuses();
|
|
13060
|
-
const { resolveProjectFromIssue } = await import("./projects-
|
|
13061
|
-
const { submitToSpecialistQueue, getTmuxSessionName, getAllProjectSpecialistStatuses } = await import("./specialists-
|
|
13194
|
+
const { resolveProjectFromIssue } = await import("./projects-C5ozxjwP.js");
|
|
13195
|
+
const { submitToSpecialistQueue, getTmuxSessionName, getAllProjectSpecialistStatuses } = await import("./specialists-Cp-PgspS.js");
|
|
13062
13196
|
const activeReviewIssues = /* @__PURE__ */ new Set();
|
|
13063
13197
|
try {
|
|
13064
13198
|
const projSpecs = await getAllProjectSpecialistStatuses();
|
|
@@ -13282,7 +13416,7 @@ var CloisterService = class {
|
|
|
13282
13416
|
const retryCount = this.processedCompletions.get(dir.name) || 0;
|
|
13283
13417
|
if (retryCount >= 3) continue;
|
|
13284
13418
|
const issueId = dir.name.replace("agent-", "").toUpperCase();
|
|
13285
|
-
const { getReviewStatus } = await import("./review-status-
|
|
13419
|
+
const { getReviewStatus } = await import("./review-status-BtXqWBhS.js");
|
|
13286
13420
|
const existingReview = getReviewStatus(issueId);
|
|
13287
13421
|
if (existingReview && ["reviewing", "passed"].includes(existingReview.reviewStatus || "")) {
|
|
13288
13422
|
console.log(`🔔 Cloister: Completion marker for ${issueId} — review already ${existingReview.reviewStatus}, marking processed`);
|
|
@@ -14005,10 +14139,11 @@ function buildResumePrompt(workspacePath, issueId, agentDir, userMessage) {
|
|
|
14005
14139
|
* GET /api/agents/:id/cost
|
|
14006
14140
|
* POST /api/agents
|
|
14007
14141
|
*/
|
|
14142
|
+
init_paths();
|
|
14008
14143
|
init_config$1();
|
|
14009
14144
|
init_agents();
|
|
14010
|
-
init_paths();
|
|
14011
14145
|
init_projects();
|
|
14146
|
+
init_issue_id();
|
|
14012
14147
|
init_tracker_config();
|
|
14013
14148
|
init_cost();
|
|
14014
14149
|
init_jsonl_parser();
|
|
@@ -14419,7 +14554,7 @@ const getAgentHealthHistoryRoute = HttpRouter.add("GET", "/api/agents/:id/health
|
|
|
14419
14554
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
14420
14555
|
const urlOpt = HttpServerRequest.toURL(request);
|
|
14421
14556
|
const hours = Option.isSome(urlOpt) ? urlOpt.value.searchParams.get("hours") ?? "24" : "24";
|
|
14422
|
-
const { getHealthHistory } = yield* Effect.promise(() => import("./health-events-db-
|
|
14557
|
+
const { getHealthHistory } = yield* Effect.promise(() => import("./health-events-db-BMXQfInV.js"));
|
|
14423
14558
|
const endTime = /* @__PURE__ */ new Date();
|
|
14424
14559
|
const startTime = /* @__PURE__ */ new Date(endTime.getTime() - parseInt(hours) * 60 * 60 * 1e3);
|
|
14425
14560
|
const events = getHealthHistory(id, startTime.toISOString(), endTime.toISOString());
|
|
@@ -14649,7 +14784,7 @@ const getAgentCostRoute = HttpRouter.add("GET", "/api/agents/:id/cost", httpHand
|
|
|
14649
14784
|
const claudeProjectsDir = join$1(process.env.HOME || homedir(), ".claude", "projects");
|
|
14650
14785
|
const workspacePath = agentState.workspace;
|
|
14651
14786
|
if (workspacePath) {
|
|
14652
|
-
const projectDir = join$1(claudeProjectsDir,
|
|
14787
|
+
const projectDir = join$1(claudeProjectsDir, encodeClaudeProjectDir(workspacePath));
|
|
14653
14788
|
const sessionsIndexPath = join$1(projectDir, "sessions-index.json");
|
|
14654
14789
|
const parseJsonlCost = async (filePath) => {
|
|
14655
14790
|
const lines = (await readFile(filePath, "utf-8")).split("\n").filter((l) => l.trim());
|
|
@@ -14710,8 +14845,7 @@ const postAgentsRoute = HttpRouter.add("POST", "/api/agents", httpHandler(Effect
|
|
|
14710
14845
|
const issueLower = issueId.toLowerCase();
|
|
14711
14846
|
const workspaceMetadata = loadWorkspaceMetadata(issueId);
|
|
14712
14847
|
const isRemote = workspaceMetadata?.location === "remote";
|
|
14713
|
-
const
|
|
14714
|
-
const projectPath = getProjectPath$3(projectId, issuePrefix);
|
|
14848
|
+
const projectPath = getProjectPath$3(projectId, extractPrefix(issueId) ?? issueId.split("-")[0]);
|
|
14715
14849
|
const workspaceExists = existsSync$1(join$1(projectPath, "workspaces", `feature-${issueLower}`));
|
|
14716
14850
|
const hasPrd = existsSync$1(join$1(projectPath, PROJECT_DOCS_SUBDIR, PROJECT_PRDS_SUBDIR, PROJECT_PRDS_ACTIVE_SUBDIR, `${issueLower}-plan.md`));
|
|
14717
14851
|
const hasDraftPrd = hasPRDDraft(issueId);
|
|
@@ -14768,7 +14902,7 @@ const postAgentsRoute = HttpRouter.add("POST", "/api/agents", httpHandler(Effect
|
|
|
14768
14902
|
issueId
|
|
14769
14903
|
}, { status: 422 });
|
|
14770
14904
|
try {
|
|
14771
|
-
const { readPlan } = yield* Effect.promise(() => import("./io-
|
|
14905
|
+
const { readPlan } = yield* Effect.promise(() => import("./io-CWlFW78i.js"));
|
|
14772
14906
|
if ((readPlan(planPath)?.plan?.items?.length ?? 0) === 0) return jsonResponse({
|
|
14773
14907
|
error: "Plan exists but contains no items. Planning may have failed or produced an empty plan.",
|
|
14774
14908
|
hint: "Re-run planning to produce a plan with tasks and acceptance criteria.",
|
|
@@ -14788,7 +14922,7 @@ const postAgentsRoute = HttpRouter.add("POST", "/api/agents", httpHandler(Effect
|
|
|
14788
14922
|
if (!hasBeads) {
|
|
14789
14923
|
console.log(`[agents] No beads for ${issueId} — attempting auto-recovery via createBeadsFromVBrief`);
|
|
14790
14924
|
try {
|
|
14791
|
-
const { createBeadsFromVBrief } = yield* Effect.promise(() => import("./beads-
|
|
14925
|
+
const { createBeadsFromVBrief } = yield* Effect.promise(() => import("./beads-By6-X07V.js"));
|
|
14792
14926
|
const recovery = yield* Effect.promise(() => createBeadsFromVBrief(workspacePath));
|
|
14793
14927
|
hasBeads = recovery.created.length > 0;
|
|
14794
14928
|
if (hasBeads) console.log(`[agents] Auto-recovery created ${recovery.created.length} beads for ${issueId}`);
|
|
@@ -14837,12 +14971,12 @@ const postAgentsRoute = HttpRouter.add("POST", "/api/agents", httpHandler(Effect
|
|
|
14837
14971
|
yield* Effect.promise(() => rename(planningPromptPath, planningPromptPath + ".archived"));
|
|
14838
14972
|
} catch {}
|
|
14839
14973
|
if (isRemote && workspaceMetadata) {
|
|
14840
|
-
const { spawnRemoteAgent } = yield* Effect.promise(() => import("./remote-agents-
|
|
14841
|
-
const { createFlyProviderFromConfig } = yield* Effect.promise(() => import("./remote-
|
|
14842
|
-
const { loadConfig: loadPanConfig } = yield* Effect.promise(() => import("./config-
|
|
14974
|
+
const { spawnRemoteAgent } = yield* Effect.promise(() => import("./remote-agents-Bf3GuM7t.js"));
|
|
14975
|
+
const { createFlyProviderFromConfig } = yield* Effect.promise(() => import("./remote-Cigqjj3f.js"));
|
|
14976
|
+
const { loadConfig: loadPanConfig } = yield* Effect.promise(() => import("./config-CTXkBATQ.js"));
|
|
14843
14977
|
const fly = createFlyProviderFromConfig(loadPanConfig().remote);
|
|
14844
14978
|
yield* Effect.promise(() => fly.syncAllCredentials(workspaceMetadata.vmName));
|
|
14845
|
-
const { buildWorkAgentPrompt, getTrackerContext } = yield* Effect.promise(() => import("./work-agent-prompt-
|
|
14979
|
+
const { buildWorkAgentPrompt, getTrackerContext } = yield* Effect.promise(() => import("./work-agent-prompt-fCg67nyo.js"));
|
|
14846
14980
|
const agentPrompt = buildWorkAgentPrompt({
|
|
14847
14981
|
issueId,
|
|
14848
14982
|
env: "REMOTE",
|
|
@@ -14909,7 +15043,7 @@ const postAgentsRoute = HttpRouter.add("POST", "/api/agents", httpHandler(Effect
|
|
|
14909
15043
|
yield* Effect.promise(() => writeFile(resumePromptFile, resumePrompt));
|
|
14910
15044
|
let agentModel = existingAgentState.model || "claude-sonnet-4-6";
|
|
14911
15045
|
try {
|
|
14912
|
-
const { getModelId } = yield* Effect.promise(() => import("./work-type-router-
|
|
15046
|
+
const { getModelId } = yield* Effect.promise(() => import("./work-type-router-Di5gCQwh.js"));
|
|
14913
15047
|
agentModel = getModelId(`issue-agent:${phase}`);
|
|
14914
15048
|
} catch {}
|
|
14915
15049
|
const resumeContent = `#!/bin/bash\n${getProviderExportsForModel(agentModel)}prompt=$(cat "${resumePromptFile}")\nexec claude --dangerously-skip-permissions --model ${agentModel} -p "$prompt"\n`;
|
|
@@ -15351,6 +15485,68 @@ async function runVerificationForIssue(issueId, workspacePath, workspaceInfo, lo
|
|
|
15351
15485
|
setReviewStatus$1(issueId, { verificationStatus: "running" });
|
|
15352
15486
|
console.log(`[${logPrefix}] Running verification gate for ${issueId} (attempt ${currentCycles + 1}/10)`);
|
|
15353
15487
|
try {
|
|
15488
|
+
try {
|
|
15489
|
+
console.log(`[${logPrefix}] Syncing main into workspace for ${issueId}...`);
|
|
15490
|
+
await execAsync$10("git fetch origin main", {
|
|
15491
|
+
cwd: workspacePath,
|
|
15492
|
+
encoding: "utf-8",
|
|
15493
|
+
timeout: 3e4
|
|
15494
|
+
});
|
|
15495
|
+
const mergeResult = await execAsync$10("git merge origin/main --no-edit", {
|
|
15496
|
+
cwd: workspacePath,
|
|
15497
|
+
encoding: "utf-8",
|
|
15498
|
+
timeout: 6e4
|
|
15499
|
+
});
|
|
15500
|
+
const mergeOut = (mergeResult.stdout || "") + (mergeResult.stderr || "");
|
|
15501
|
+
if (mergeOut.includes("Already up to date") || mergeOut.includes("Already up-to-date")) console.log(`[${logPrefix}] Already up to date with main`);
|
|
15502
|
+
else console.log(`[${logPrefix}] Merged latest main into workspace`);
|
|
15503
|
+
} catch (mergeErr) {
|
|
15504
|
+
const mergeOut = (mergeErr.stdout || "") + (mergeErr.stderr || "");
|
|
15505
|
+
if (mergeOut.includes("CONFLICT") || mergeOut.includes("Merge conflict")) {
|
|
15506
|
+
try {
|
|
15507
|
+
await execAsync$10("git merge --abort", {
|
|
15508
|
+
cwd: workspacePath,
|
|
15509
|
+
encoding: "utf-8"
|
|
15510
|
+
});
|
|
15511
|
+
} catch {}
|
|
15512
|
+
const conflictLines = mergeOut.split("\n").filter((line) => line.startsWith("CONFLICT")).map((line) => line.replace(/^CONFLICT \([^)]+\): /, "").replace(/Merge conflict in /, "")).join("\n - ");
|
|
15513
|
+
const newCycleCount = currentCycles + 1;
|
|
15514
|
+
const failedCheck = "sync-main";
|
|
15515
|
+
const summary = `Sync with main FAILED — merge conflicts detected:\n - ${conflictLines}`;
|
|
15516
|
+
setReviewStatus$1(issueId, {
|
|
15517
|
+
reviewStatus: "pending",
|
|
15518
|
+
verificationStatus: "failed",
|
|
15519
|
+
verificationNotes: summary,
|
|
15520
|
+
verificationCycleCount: newCycleCount,
|
|
15521
|
+
verificationMaxCycles: 10
|
|
15522
|
+
});
|
|
15523
|
+
const feedbackBody = `VERIFICATION FAILED for ${issueId} (attempt ${newCycleCount}/10):\n\nFailed check: ${failedCheck}\n\n${summary}\n\n## REQUIRED: Resolve merge conflicts with main BEFORE resubmitting\n\nThe main branch has advanced since you started working. Your branch has merge conflicts that must be resolved.\n\n1. Run: git fetch origin main && git merge origin/main\n2. Resolve all conflicts in the listed files\n3. Run the project's build and tests to verify nothing broke\n4. Commit and push ALL changes\n5. ONLY THEN resubmit:\ncurl -X POST ${process.env.DASHBOARD_URL || `http://localhost:${process.env.API_PORT || process.env.PORT || "3011"}`}/api/workspaces/${issueId}/request-review -H "Content-Type: application/json" -d '{}'\n\nDo NOT resubmit until all conflicts are resolved and tests pass.`;
|
|
15524
|
+
try {
|
|
15525
|
+
const fileResult = await writeFeedbackFile({
|
|
15526
|
+
issueId,
|
|
15527
|
+
workspacePath,
|
|
15528
|
+
specialist: "verification-gate",
|
|
15529
|
+
outcome: "failed",
|
|
15530
|
+
summary: `Sync with main FAILED — merge conflicts (attempt ${newCycleCount}/10)`,
|
|
15531
|
+
markdownBody: feedbackBody
|
|
15532
|
+
});
|
|
15533
|
+
if (fileResult.success) {
|
|
15534
|
+
const agentId = `agent-${issueId.toLowerCase()}`;
|
|
15535
|
+
await messageAgent(agentId, `VERIFICATION FAILED for ${issueId}.\nFailed check: ${failedCheck} — merge conflicts with main\nRead and address: ${fileResult.relativePath}`);
|
|
15536
|
+
console.log(`[${logPrefix}] Sync-main failed for ${issueId} — sent conflict feedback to ${agentId}`);
|
|
15537
|
+
}
|
|
15538
|
+
} catch (feedbackErr) {
|
|
15539
|
+
console.error(`[${logPrefix}] Failed to write sync-main feedback for ${issueId}:`, feedbackErr);
|
|
15540
|
+
}
|
|
15541
|
+
return {
|
|
15542
|
+
outcome: "failed",
|
|
15543
|
+
failedCheck,
|
|
15544
|
+
cycleCount: newCycleCount,
|
|
15545
|
+
maxCycles: 10
|
|
15546
|
+
};
|
|
15547
|
+
}
|
|
15548
|
+
console.warn(`[${logPrefix}] Sync-main warning for ${issueId}: ${mergeErr.message} (continuing)`);
|
|
15549
|
+
}
|
|
15354
15550
|
const projectConfig = findProjectByPath(workspacePath);
|
|
15355
15551
|
const gates = projectConfig?.quality_gates && Object.keys(projectConfig.quality_gates).length > 0 ? projectConfig.quality_gates : DEFAULT_GATES;
|
|
15356
15552
|
console.log(`[${logPrefix}] Project: ${projectConfig?.name || "NOT FOUND"}, gates: [${Object.keys(gates).join(", ")}], workspace: ${workspacePath}`);
|
|
@@ -15532,6 +15728,7 @@ init_agents();
|
|
|
15532
15728
|
init_jsonl_parser();
|
|
15533
15729
|
init_specialists();
|
|
15534
15730
|
init_tldr_daemon();
|
|
15731
|
+
init_issue_id();
|
|
15535
15732
|
const execAsync$9 = promisify(exec);
|
|
15536
15733
|
const PORT = parseInt(process.env.API_PORT || process.env.PORT || "3011", 10);
|
|
15537
15734
|
const MAX_AUTO_REQUEUE = 7;
|
|
@@ -15610,7 +15807,7 @@ function getWorkspaceInfoForIssue(issueId) {
|
|
|
15610
15807
|
agentId: meta.agentId
|
|
15611
15808
|
};
|
|
15612
15809
|
} catch {}
|
|
15613
|
-
const issuePrefix = issueId.split("-")[0];
|
|
15810
|
+
const issuePrefix = extractPrefix(issueId) ?? issueId.split("-")[0];
|
|
15614
15811
|
const issueLower = issueId.toLowerCase();
|
|
15615
15812
|
const numericSuffix = issueLower.replace(/^[a-z]+-/, "");
|
|
15616
15813
|
for (const { config } of listProjects()) {
|
|
@@ -15753,7 +15950,7 @@ async function getMrUrlAsync(issueId, workspacePath) {
|
|
|
15753
15950
|
*/
|
|
15754
15951
|
async function buildRichPRBody(issueId, workspacePath) {
|
|
15755
15952
|
const lines = [];
|
|
15756
|
-
lines.push(`Closes #${issueId
|
|
15953
|
+
lines.push(`Closes #${extractNumber(issueId) ?? issueId}`);
|
|
15757
15954
|
lines.push("");
|
|
15758
15955
|
try {
|
|
15759
15956
|
const planPath = join$1(workspacePath, ".planning", "plan.vbrief.json");
|
|
@@ -15996,7 +16193,7 @@ const readJsonBody$7 = Effect.gen(function* () {
|
|
|
15996
16193
|
});
|
|
15997
16194
|
const getWorkspaceRoute = HttpRouter.add("GET", "/api/workspaces/:issueId", httpHandler(Effect.gen(function* () {
|
|
15998
16195
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
15999
|
-
const issuePrefix = issueId.split("-")[0];
|
|
16196
|
+
const issuePrefix = extractPrefix(issueId) ?? issueId.split("-")[0];
|
|
16000
16197
|
const projectPath = getProjectPath$2(void 0, issuePrefix);
|
|
16001
16198
|
const issueLower = issueId.toLowerCase();
|
|
16002
16199
|
const workspaceInfo = getWorkspaceInfoForIssue(issueId);
|
|
@@ -16109,8 +16306,7 @@ const getWorkspaceRoute = HttpRouter.add("GET", "/api/workspaces/:issueId", http
|
|
|
16109
16306
|
const postWorkspacesRoute = HttpRouter.add("POST", "/api/workspaces", httpHandler(Effect.gen(function* () {
|
|
16110
16307
|
const { issueId, projectId } = yield* readJsonBody$7;
|
|
16111
16308
|
if (!issueId) return jsonResponse({ error: "issueId required" }, { status: 400 });
|
|
16112
|
-
const
|
|
16113
|
-
const projectPath = getProjectPath$2(projectId, issuePrefix);
|
|
16309
|
+
const projectPath = getProjectPath$2(projectId, extractPrefix(issueId) ?? issueId.split("-")[0]);
|
|
16114
16310
|
const activityId = spawnPanCommand([
|
|
16115
16311
|
"workspace",
|
|
16116
16312
|
"create",
|
|
@@ -16125,8 +16321,7 @@ const postWorkspacesRoute = HttpRouter.add("POST", "/api/workspaces", httpHandle
|
|
|
16125
16321
|
})));
|
|
16126
16322
|
const getWorkspacePlanRoute = HttpRouter.add("GET", "/api/workspaces/:issueId/plan", httpHandler(Effect.gen(function* () {
|
|
16127
16323
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
16128
|
-
const
|
|
16129
|
-
const planPath = findPlan(join$1(getProjectPath$2(void 0, issuePrefix), "workspaces", `feature-${issueId.toLowerCase()}`));
|
|
16324
|
+
const planPath = findPlan(join$1(getProjectPath$2(void 0, extractPrefix(issueId) ?? issueId.split("-")[0]), "workspaces", `feature-${issueId.toLowerCase()}`));
|
|
16130
16325
|
if (!planPath) return jsonResponse({ error: "No vBRIEF plan found for this workspace" }, { status: 404 });
|
|
16131
16326
|
const doc = readPlan(planPath);
|
|
16132
16327
|
const cp = criticalPath(doc);
|
|
@@ -16137,8 +16332,7 @@ const getWorkspacePlanRoute = HttpRouter.add("GET", "/api/workspaces/:issueId/pl
|
|
|
16137
16332
|
})));
|
|
16138
16333
|
const getWorkspaceCleanPreviewRoute = HttpRouter.add("GET", "/api/workspaces/:issueId/clean/preview", httpHandler(Effect.gen(function* () {
|
|
16139
16334
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
16140
|
-
const
|
|
16141
|
-
const projectPath = getProjectPath$2(void 0, issuePrefix);
|
|
16335
|
+
const projectPath = getProjectPath$2(void 0, extractPrefix(issueId) ?? issueId.split("-")[0]);
|
|
16142
16336
|
const issueLower = issueId.toLowerCase();
|
|
16143
16337
|
const workspaceName = `feature-${issueLower}`;
|
|
16144
16338
|
const workspacePath = join$1(projectPath, "workspaces", workspaceName);
|
|
@@ -16277,8 +16471,7 @@ const getWorkspaceCleanPreviewRoute = HttpRouter.add("GET", "/api/workspaces/:is
|
|
|
16277
16471
|
const postWorkspaceCleanRoute = HttpRouter.add("POST", "/api/workspaces/:issueId/clean", httpHandler(Effect.gen(function* () {
|
|
16278
16472
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
16279
16473
|
const { createBackup } = yield* readJsonBody$7;
|
|
16280
|
-
const
|
|
16281
|
-
const projectPath = getProjectPath$2(void 0, issuePrefix);
|
|
16474
|
+
const projectPath = getProjectPath$2(void 0, extractPrefix(issueId) ?? issueId.split("-")[0]);
|
|
16282
16475
|
const workspaceName = `feature-${issueId.toLowerCase()}`;
|
|
16283
16476
|
const workspacePath = join$1(projectPath, "workspaces", workspaceName);
|
|
16284
16477
|
if (!existsSync$1(workspacePath)) return jsonResponse({ error: "Workspace does not exist" }, { status: 404 });
|
|
@@ -16320,8 +16513,7 @@ const postWorkspaceCleanRoute = HttpRouter.add("POST", "/api/workspaces/:issueId
|
|
|
16320
16513
|
})));
|
|
16321
16514
|
const postWorkspaceContainerizeRoute = HttpRouter.add("POST", "/api/workspaces/:issueId/containerize", httpHandler(Effect.gen(function* () {
|
|
16322
16515
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
16323
|
-
const
|
|
16324
|
-
const projectPath = getProjectPath$2(void 0, issuePrefix);
|
|
16516
|
+
const projectPath = getProjectPath$2(void 0, extractPrefix(issueId) ?? issueId.split("-")[0]);
|
|
16325
16517
|
const issueLower = issueId.toLowerCase();
|
|
16326
16518
|
if (!existsSync$1(join$1(projectPath, "infra", "new-feature"))) return jsonResponse({ error: "Project does not support containerization (no infra/new-feature script)" }, { status: 400 });
|
|
16327
16519
|
const workspacePath = join$1(projectPath, "workspaces", `feature-${issueLower}`);
|
|
@@ -16419,8 +16611,7 @@ const postWorkspaceContainerizeRoute = HttpRouter.add("POST", "/api/workspaces/:
|
|
|
16419
16611
|
})));
|
|
16420
16612
|
const postWorkspaceStartRoute = HttpRouter.add("POST", "/api/workspaces/:issueId/start", httpHandler(Effect.gen(function* () {
|
|
16421
16613
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
16422
|
-
const
|
|
16423
|
-
const projectPath = getProjectPath$2(void 0, issuePrefix);
|
|
16614
|
+
const projectPath = getProjectPath$2(void 0, extractPrefix(issueId) ?? issueId.split("-")[0]);
|
|
16424
16615
|
const issueLower = issueId.toLowerCase();
|
|
16425
16616
|
const workspacePath = join$1(projectPath, "workspaces", `feature-${issueLower}`);
|
|
16426
16617
|
if (!existsSync$1(workspacePath)) return jsonResponse({ error: "Workspace does not exist" }, { status: 400 });
|
|
@@ -16833,7 +17024,7 @@ const postWorkspaceReviewStatusRoute = HttpRouter.add("POST", "/api/workspaces/:
|
|
|
16833
17024
|
if (testNotes) update.testNotes = testNotes;
|
|
16834
17025
|
const status = setReviewStatus(issueId, update);
|
|
16835
17026
|
console.log(`[review-status] Updated ${issueId}:`, status);
|
|
16836
|
-
const { getTmuxSessionName, checkSpecialistQueue: cSQ, completeSpecialistTask } = yield* Effect.promise(() => import("./specialists-
|
|
17027
|
+
const { getTmuxSessionName, checkSpecialistQueue: cSQ, completeSpecialistTask } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
16837
17028
|
const projectKey = resolveProjectFromIssue(issueId)?.projectKey;
|
|
16838
17029
|
if (reviewStatus && [
|
|
16839
17030
|
"passed",
|
|
@@ -16857,7 +17048,7 @@ const postWorkspaceReviewStatusRoute = HttpRouter.add("POST", "/api/workspaces/:
|
|
|
16857
17048
|
const apiUrl = process.env.DASHBOARD_URL || `http://localhost:${process.env.API_PORT || process.env.PORT || "3011"}`;
|
|
16858
17049
|
const feedbackBody = `CODE REVIEW ${reviewStatus.toUpperCase()} for ${issueId}:\n\n${reviewNotes}\n\n## REQUIRED: Fix ALL issues above BEFORE resubmitting\n\n1. Read each blocking issue carefully\n2. Fix the code for EVERY issue listed\n3. Run tests to verify your fixes\n4. Commit and push ALL changes\n5. ONLY THEN resubmit:\ncurl -X POST ${apiUrl}/api/workspaces/${issueId}/request-review -H "Content-Type: application/json" -d '{}'\n\nDo NOT run the curl command until steps 1-4 are complete. Do NOT stop until review passes.`;
|
|
16859
17050
|
try {
|
|
16860
|
-
const { writeFeedbackFile } = yield* Effect.promise(() => import("./feedback-writer-
|
|
17051
|
+
const { writeFeedbackFile } = yield* Effect.promise(() => import("./feedback-writer-Wgv1cd1r.js"));
|
|
16861
17052
|
const wsInfo = getWorkspaceInfoForIssue(issueId);
|
|
16862
17053
|
const fileResult = yield* Effect.promise(() => writeFeedbackFile({
|
|
16863
17054
|
issueId,
|
|
@@ -16887,11 +17078,10 @@ const postWorkspaceReviewStatusRoute = HttpRouter.add("POST", "/api/workspaces/:
|
|
|
16887
17078
|
}
|
|
16888
17079
|
})));
|
|
16889
17080
|
const issueLower = issueId.toLowerCase();
|
|
16890
|
-
const
|
|
16891
|
-
const projectPath = getProjectPath$2(void 0, issuePrefix);
|
|
17081
|
+
const projectPath = getProjectPath$2(void 0, extractPrefix(issueId) ?? issueId.split("-")[0]);
|
|
16892
17082
|
const testWorkspace = body.workspace || join$1(projectPath, "workspaces", `feature-${issueLower}`);
|
|
16893
17083
|
const testBranch = body.branch || `feature/${issueLower}`;
|
|
16894
|
-
const { autoQueueTestAgentAndNotify } = yield* Effect.promise(() => import("./test-agent-queue-
|
|
17084
|
+
const { autoQueueTestAgentAndNotify } = yield* Effect.promise(() => import("./test-agent-queue-ypF_ecHo.js"));
|
|
16895
17085
|
try {
|
|
16896
17086
|
yield* Effect.promise(() => autoQueueTestAgentAndNotify(issueId, testWorkspace, testBranch, messageAgent));
|
|
16897
17087
|
yield* Effect.promise(() => Effect.runPromise(eventStore.append({
|
|
@@ -16940,7 +17130,7 @@ const postWorkspaceReviewStatusRoute = HttpRouter.add("POST", "/api/workspaces/:
|
|
|
16940
17130
|
const agentId = `agent-${issueId.toLowerCase()}`;
|
|
16941
17131
|
const feedbackBody = `TESTS FAILED for ${issueId}:\n\n${testNotes}\n\n## REQUIRED: Fix ALL test failures BEFORE resubmitting\n\n1. Read each test failure carefully\n2. Fix the code causing EVERY failure\n3. Run the test suite to verify your fixes pass\n4. Commit and push ALL changes\n5. ONLY THEN resubmit:\ncurl -X POST ${process.env.DASHBOARD_URL || `http://localhost:${process.env.API_PORT || process.env.PORT || "3011"}`}/api/workspaces/${issueId}/request-review -H "Content-Type: application/json" -d '{}'\n\nDo NOT run the curl command until steps 1-4 are complete. Do NOT stop until review passes.`;
|
|
16942
17132
|
try {
|
|
16943
|
-
const { writeFeedbackFile } = yield* Effect.promise(() => import("./feedback-writer-
|
|
17133
|
+
const { writeFeedbackFile } = yield* Effect.promise(() => import("./feedback-writer-Wgv1cd1r.js"));
|
|
16944
17134
|
const wsInfo = getWorkspaceInfoForIssue(issueId);
|
|
16945
17135
|
const fileResult = yield* Effect.promise(() => writeFeedbackFile({
|
|
16946
17136
|
issueId,
|
|
@@ -16986,8 +17176,7 @@ const postWorkspaceReviewRoute = HttpRouter.add("POST", "/api/workspaces/:issueI
|
|
|
16986
17176
|
const body = yield* readJsonBody$7;
|
|
16987
17177
|
const urlOpt = HttpServerRequest.toURL(request);
|
|
16988
17178
|
const forceReview = Option.isSome(urlOpt) && urlOpt.value.searchParams.get("force") === "true" || body?.force === true;
|
|
16989
|
-
const
|
|
16990
|
-
const projectPath = getProjectPath$2(void 0, issuePrefix);
|
|
17179
|
+
const projectPath = getProjectPath$2(void 0, extractPrefix(issueId) ?? issueId.split("-")[0]);
|
|
16991
17180
|
const issueLower = issueId.toLowerCase();
|
|
16992
17181
|
const branchName = `feature/${issueLower}`;
|
|
16993
17182
|
const workspaceInfo = getWorkspaceInfoForIssue(issueId);
|
|
@@ -17064,7 +17253,7 @@ const postWorkspaceReviewRoute = HttpRouter.add("POST", "/api/workspaces/:issueI
|
|
|
17064
17253
|
console.log(`Feature branch push note: ${pushErr.message}`);
|
|
17065
17254
|
}
|
|
17066
17255
|
if (!workspaceInfo.isRemote) try {
|
|
17067
|
-
const { getWorkspaceGitInfo } = await import("./git-utils-
|
|
17256
|
+
const { getWorkspaceGitInfo } = await import("./git-utils-DQI8EYoj.js");
|
|
17068
17257
|
setReviewStatus(issueId, { lastReviewCommits: await getWorkspaceGitInfo(workspacePath) });
|
|
17069
17258
|
} catch {}
|
|
17070
17259
|
try {
|
|
@@ -17097,7 +17286,7 @@ const postWorkspaceReviewRoute = HttpRouter.add("POST", "/api/workspaces/:issueI
|
|
|
17097
17286
|
});
|
|
17098
17287
|
return;
|
|
17099
17288
|
}
|
|
17100
|
-
const { spawnEphemeralSpecialist: spawnEphemeral, isRunning, getTmuxSessionName, submitToSpecialistQueue } = await import("./specialists-
|
|
17289
|
+
const { spawnEphemeralSpecialist: spawnEphemeral, isRunning, getTmuxSessionName, submitToSpecialistQueue } = await import("./specialists-Cp-PgspS.js");
|
|
17101
17290
|
const reviewProjectKey = resolveProjectFromIssue(issueId)?.projectKey ?? null;
|
|
17102
17291
|
const reviewSession = getTmuxSessionName("review-agent", reviewProjectKey ?? void 0);
|
|
17103
17292
|
const reviewRunning = await isRunning("review-agent", reviewProjectKey ?? void 0);
|
|
@@ -17182,7 +17371,7 @@ ${workspaceAccessInstructions}
|
|
|
17182
17371
|
if (!reviewResult.success) {
|
|
17183
17372
|
if (reviewResult.error === "specialist_busy") {
|
|
17184
17373
|
console.log(`[review] review-agent busy for ${issueId} — queuing for deacon dispatch`);
|
|
17185
|
-
const { submitToSpecialistQueue } = await import("./specialists-
|
|
17374
|
+
const { submitToSpecialistQueue } = await import("./specialists-Cp-PgspS.js");
|
|
17186
17375
|
submitToSpecialistQueue("review-agent", {
|
|
17187
17376
|
priority: "high",
|
|
17188
17377
|
source: "review-pipeline",
|
|
@@ -17250,7 +17439,7 @@ const postWorkspaceRequestReviewRoute = HttpRouter.add("POST", "/api/workspaces/
|
|
|
17250
17439
|
const workspacePath = join$1(resolved.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
|
|
17251
17440
|
const branchName = `feature/${issueId.toLowerCase()}`;
|
|
17252
17441
|
setReviewStatus(issueId, { testStatus: "testing" });
|
|
17253
|
-
const { spawnEphemeralSpecialist } = yield* Effect.promise(() => import("./specialists-
|
|
17442
|
+
const { spawnEphemeralSpecialist } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
17254
17443
|
const testResult = yield* Effect.promise(() => spawnEphemeralSpecialist(resolved.projectKey, "test-agent", {
|
|
17255
17444
|
issueId,
|
|
17256
17445
|
workspace: workspacePath,
|
|
@@ -17289,8 +17478,7 @@ const postWorkspaceRequestReviewRoute = HttpRouter.add("POST", "/api/workspaces/
|
|
|
17289
17478
|
hint: "A human must click the Review button to continue."
|
|
17290
17479
|
}, { status: 429 });
|
|
17291
17480
|
}
|
|
17292
|
-
const
|
|
17293
|
-
const projectPath = getProjectPath$2(void 0, issuePrefix);
|
|
17481
|
+
const projectPath = getProjectPath$2(void 0, extractPrefix(issueId) ?? issueId.split("-")[0]);
|
|
17294
17482
|
const issueLower = issueId.toLowerCase();
|
|
17295
17483
|
const branchName = `feature/${issueLower}`;
|
|
17296
17484
|
const workspaceInfo = getWorkspaceInfoForIssue(issueId);
|
|
@@ -17306,7 +17494,7 @@ const postWorkspaceRequestReviewRoute = HttpRouter.add("POST", "/api/workspaces/
|
|
|
17306
17494
|
const reviewNotes = message ? `Agent re-review request (${newCount}/${MAX_AUTO_REQUEUE}): ${message}` : void 0;
|
|
17307
17495
|
let requestReviewCommits;
|
|
17308
17496
|
if (!workspaceInfo.isRemote) try {
|
|
17309
|
-
const { getWorkspaceGitInfo } = yield* Effect.promise(() => import("./git-utils-
|
|
17497
|
+
const { getWorkspaceGitInfo } = yield* Effect.promise(() => import("./git-utils-DQI8EYoj.js"));
|
|
17310
17498
|
requestReviewCommits = yield* Effect.promise(() => getWorkspaceGitInfo(workspacePath));
|
|
17311
17499
|
} catch {}
|
|
17312
17500
|
const reqVerifyOutcome = yield* Effect.promise(() => runVerificationForIssue(issueId, workspacePath, workspaceInfo, "request-review"));
|
|
@@ -17332,7 +17520,7 @@ const postWorkspaceRequestReviewRoute = HttpRouter.add("POST", "/api/workspaces/
|
|
|
17332
17520
|
});
|
|
17333
17521
|
console.log(`[request-review] Agent requested re-review for ${issueId} (${newCount}/${MAX_AUTO_REQUEUE})${workspaceInfo.isRemote ? ` (remote: ${workspaceInfo.vmName})` : ""}`);
|
|
17334
17522
|
try {
|
|
17335
|
-
const { spawnEphemeralSpecialist } = yield* Effect.promise(() => import("./specialists-
|
|
17523
|
+
const { spawnEphemeralSpecialist } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
17336
17524
|
const resolved = resolveProjectFromIssue(issueId);
|
|
17337
17525
|
if (!resolved) return jsonResponse({
|
|
17338
17526
|
success: false,
|
|
@@ -17361,7 +17549,7 @@ const postWorkspaceRequestReviewRoute = HttpRouter.add("POST", "/api/workspaces/
|
|
|
17361
17549
|
});
|
|
17362
17550
|
} else if (result.error === "specialist_busy") {
|
|
17363
17551
|
console.log(`[request-review] Review specialist busy for ${issueId} — queuing for deacon dispatch`);
|
|
17364
|
-
const { submitToSpecialistQueue } = yield* Effect.promise(async () => import("./specialists-
|
|
17552
|
+
const { submitToSpecialistQueue } = yield* Effect.promise(async () => import("./specialists-Cp-PgspS.js"));
|
|
17365
17553
|
submitToSpecialistQueue("review-agent", {
|
|
17366
17554
|
priority: "high",
|
|
17367
17555
|
source: "request-review",
|
|
@@ -17409,7 +17597,7 @@ const postWorkspaceResetReviewRoute = HttpRouter.add("POST", "/api/workspaces/:i
|
|
|
17409
17597
|
error: "Workspace does not exist"
|
|
17410
17598
|
}, { status: 400 });
|
|
17411
17599
|
console.log(`[reset-review] Human-initiated pipeline reset for ${issueId}`);
|
|
17412
|
-
const { checkSpecialistQueue: cSQ, completeSpecialistTask } = yield* Effect.promise(() => import("./specialists-
|
|
17600
|
+
const { checkSpecialistQueue: cSQ, completeSpecialistTask } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
17413
17601
|
for (const specialist of [
|
|
17414
17602
|
"review-agent",
|
|
17415
17603
|
"test-agent",
|
|
@@ -17435,13 +17623,13 @@ const postWorkspaceResetReviewRoute = HttpRouter.add("POST", "/api/workspaces/:i
|
|
|
17435
17623
|
verificationCycleCount: 0
|
|
17436
17624
|
});
|
|
17437
17625
|
try {
|
|
17438
|
-
const { resetPostMergeState } = yield* Effect.promise(() => import("./merge-agent-
|
|
17626
|
+
const { resetPostMergeState } = yield* Effect.promise(() => import("./merge-agent-CGN3TT0a.js"));
|
|
17439
17627
|
resetPostMergeState(issueId);
|
|
17440
17628
|
} catch {}
|
|
17441
17629
|
console.log(`[reset-review] Pipeline state reset for ${issueId} — awaiting agent to request review`);
|
|
17442
17630
|
const rerun = body?.rerun === true;
|
|
17443
17631
|
if (rerun) try {
|
|
17444
|
-
const { dispatchToSpecialist } = yield* Effect.promise(() => import("./specialists-
|
|
17632
|
+
const { dispatchToSpecialist } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
17445
17633
|
const resolved = resolveProjectFromIssue(issueId);
|
|
17446
17634
|
if (resolved) {
|
|
17447
17635
|
const wsInfo = getWorkspaceInfoForIssue(issueId);
|
|
@@ -17476,8 +17664,7 @@ const postWorkspaceResetReviewRoute = HttpRouter.add("POST", "/api/workspaces/:i
|
|
|
17476
17664
|
})));
|
|
17477
17665
|
const postWorkspaceSyncMainRoute = HttpRouter.add("POST", "/api/workspaces/:issueId/sync-main", httpHandler(Effect.gen(function* () {
|
|
17478
17666
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
17479
|
-
const
|
|
17480
|
-
const projectPath = getProjectPath$2(void 0, issuePrefix);
|
|
17667
|
+
const projectPath = getProjectPath$2(void 0, extractPrefix(issueId) ?? issueId.split("-")[0]);
|
|
17481
17668
|
const issueLower = issueId.toLowerCase();
|
|
17482
17669
|
const workspaceInfo = getWorkspaceInfoForIssue(issueId);
|
|
17483
17670
|
if (workspaceInfo.isRemote) return jsonResponse({
|
|
@@ -17522,7 +17709,7 @@ async function triggerMerge(issueId) {
|
|
|
17522
17709
|
testStatus: reviewStatus?.testStatus || "pending"
|
|
17523
17710
|
};
|
|
17524
17711
|
if (reviewStatus.prUrl) try {
|
|
17525
|
-
const { isGitHubAppConfigured, reportCommitStatus } = await import("./github-app-
|
|
17712
|
+
const { isGitHubAppConfigured, reportCommitStatus } = await import("./github-app-DClWjjHr.js");
|
|
17526
17713
|
if (isGitHubAppConfigured()) {
|
|
17527
17714
|
const prMatch = reviewStatus.prUrl.match(/\/pull\/(\d+)/);
|
|
17528
17715
|
if (prMatch) {
|
|
@@ -17558,7 +17745,7 @@ async function triggerMerge(issueId) {
|
|
|
17558
17745
|
error: "Already merged",
|
|
17559
17746
|
mergeStatus: "merged"
|
|
17560
17747
|
};
|
|
17561
|
-
const issuePrefix = issueId.split("-")[0];
|
|
17748
|
+
const issuePrefix = extractPrefix(issueId) ?? issueId.split("-")[0];
|
|
17562
17749
|
const projectPath = getProjectPath$2(void 0, issuePrefix);
|
|
17563
17750
|
const issueLower = issueId.toLowerCase();
|
|
17564
17751
|
const workspaceInfo = getWorkspaceInfoForIssue(issueId);
|
|
@@ -17604,7 +17791,7 @@ async function triggerMerge(issueId) {
|
|
|
17604
17791
|
readyForMerge: false
|
|
17605
17792
|
});
|
|
17606
17793
|
completePendingOperation(issueId, null);
|
|
17607
|
-
const { postMergeLifecycle } = await import("./merge-agent-
|
|
17794
|
+
const { postMergeLifecycle } = await import("./merge-agent-CGN3TT0a.js");
|
|
17608
17795
|
await postMergeLifecycle(issueId, projectPath);
|
|
17609
17796
|
return {
|
|
17610
17797
|
success: true,
|
|
@@ -17678,7 +17865,7 @@ async function triggerMerge(issueId) {
|
|
|
17678
17865
|
console.log(`[merge] Push note for ${repo.name}: ${pushErr.message}`);
|
|
17679
17866
|
}
|
|
17680
17867
|
try {
|
|
17681
|
-
const { spawnMergeAgentForBranches } = await import("./merge-agent-
|
|
17868
|
+
const { spawnMergeAgentForBranches } = await import("./merge-agent-CGN3TT0a.js");
|
|
17682
17869
|
const mergeResult = await spawnMergeAgentForBranches(repoMainPath, branchName, defaultBranch, issueId, { skipDoneReport: true });
|
|
17683
17870
|
if (mergeResult.success) mergeResults.push({
|
|
17684
17871
|
repo: repo.name,
|
|
@@ -17719,7 +17906,7 @@ async function triggerMerge(issueId) {
|
|
|
17719
17906
|
readyForMerge: false
|
|
17720
17907
|
});
|
|
17721
17908
|
completePendingOperation(issueId, null);
|
|
17722
|
-
const { postMergeLifecycle } = await import("./merge-agent-
|
|
17909
|
+
const { postMergeLifecycle } = await import("./merge-agent-CGN3TT0a.js");
|
|
17723
17910
|
await postMergeLifecycle(issueId, projectPath);
|
|
17724
17911
|
return {
|
|
17725
17912
|
success: true,
|
|
@@ -17754,7 +17941,7 @@ async function triggerMerge(issueId) {
|
|
|
17754
17941
|
};
|
|
17755
17942
|
}
|
|
17756
17943
|
const prNumber = prMatch[1];
|
|
17757
|
-
const { spawnRebaseAgentForBranch, postMergeLifecycle } = await import("./merge-agent-
|
|
17944
|
+
const { spawnRebaseAgentForBranch, postMergeLifecycle } = await import("./merge-agent-CGN3TT0a.js");
|
|
17758
17945
|
console.log(`[merge] Rebasing ${branchName} onto main for ${issueId}...`);
|
|
17759
17946
|
const rebaseResult = await spawnRebaseAgentForBranch(workspacePath, branchName, "main", issueId);
|
|
17760
17947
|
if (!rebaseResult.success) {
|
|
@@ -17838,8 +18025,7 @@ const postWorkspaceApproveRoute = HttpRouter.add("POST", "/api/workspaces/:issue
|
|
|
17838
18025
|
}
|
|
17839
18026
|
}
|
|
17840
18027
|
return yield* Effect.promise(async () => {
|
|
17841
|
-
const
|
|
17842
|
-
const projectPath = getProjectPath$2(void 0, issuePrefix);
|
|
18028
|
+
const projectPath = getProjectPath$2(void 0, extractPrefix(issueId) ?? issueId.split("-")[0]);
|
|
17843
18029
|
const issueLower = issueId.toLowerCase();
|
|
17844
18030
|
const workspacePath = join$1(projectPath, "workspaces", `feature-${issueLower}`);
|
|
17845
18031
|
const branchName = `feature/${issueLower}`;
|
|
@@ -17890,7 +18076,7 @@ const postWorkspaceApproveRoute = HttpRouter.add("POST", "/api/workspaces/:issue
|
|
|
17890
18076
|
completePendingOperation(issueId, error);
|
|
17891
18077
|
return jsonResponse({ error }, { status: 400 });
|
|
17892
18078
|
}
|
|
17893
|
-
const { wakeSpecialist, spawnEphemeralSpecialist: spawnApproveEphemeral } = await import("./specialists-
|
|
18079
|
+
const { wakeSpecialist, spawnEphemeralSpecialist: spawnApproveEphemeral } = await import("./specialists-Cp-PgspS.js");
|
|
17894
18080
|
const approveProjectKey = resolveProjectFromIssue(issueId)?.projectKey ?? null;
|
|
17895
18081
|
console.log(`[approve] Starting specialist pipeline for ${issueId}...`);
|
|
17896
18082
|
const pipelinePrompt = `STRICT REVIEW WORKFLOW for ${issueId}
|
|
@@ -17969,7 +18155,7 @@ curl -X POST http://localhost:${PORT}/api/specialists/test-agent/queue -H "Conte
|
|
|
17969
18155
|
}
|
|
17970
18156
|
console.log(`[approve] Step 3/3: Waking merge-agent for ${issueId}...`);
|
|
17971
18157
|
try {
|
|
17972
|
-
const { spawnMergeAgentForBranches } = await import("./merge-agent-
|
|
18158
|
+
const { spawnMergeAgentForBranches } = await import("./merge-agent-CGN3TT0a.js");
|
|
17973
18159
|
const mergeResult = await spawnMergeAgentForBranches(projectPath, branchName, "main", issueId);
|
|
17974
18160
|
if (mergeResult.success && mergeResult.testsStatus === "PASS") console.log(`merge-agent successfully merged ${issueId}`);
|
|
17975
18161
|
else if (mergeResult.success && mergeResult.testsStatus === "SKIP") console.log(`merge-agent merged ${issueId} (tests skipped)`);
|
|
@@ -18027,7 +18213,7 @@ curl -X POST http://localhost:${PORT}/api/specialists/test-agent/queue -H "Conte
|
|
|
18027
18213
|
completePendingOperation(issueId, error);
|
|
18028
18214
|
return jsonResponse({ error }, { status: 400 });
|
|
18029
18215
|
}
|
|
18030
|
-
const { approve: lifecycleApprove } = await import("./lifecycle-
|
|
18216
|
+
const { approve: lifecycleApprove } = await import("./lifecycle-BcUmtkR4.js");
|
|
18031
18217
|
const ghResolved = resolveGitHubIssue(issueId);
|
|
18032
18218
|
const isGitHubIssueFlag = ghResolved.isGitHub;
|
|
18033
18219
|
const lifecycleResult = await lifecycleApprove({
|
|
@@ -18086,9 +18272,8 @@ const getWorkspaceTldrRoute = HttpRouter.add("GET", "/api/workspaces/:issueId/tl
|
|
|
18086
18272
|
const postWorkspaceRefreshTokenRoute = HttpRouter.add("POST", "/api/workspaces/:issueId/refresh-token", httpHandler(Effect.gen(function* () {
|
|
18087
18273
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
18088
18274
|
const issueLower = issueId.toLowerCase();
|
|
18089
|
-
const
|
|
18090
|
-
const
|
|
18091
|
-
const { refreshWorkspaceToken, isGitHubAppConfigured } = yield* Effect.promise(() => import("./github-app-XO-LBUGk.js"));
|
|
18275
|
+
const workspacePath = join$1(getProjectPath$2(void 0, extractPrefix(issueId) ?? issueId.split("-")[0]), "workspaces", `feature-${issueLower}`);
|
|
18276
|
+
const { refreshWorkspaceToken, isGitHubAppConfigured } = yield* Effect.promise(() => import("./github-app-DClWjjHr.js"));
|
|
18092
18277
|
if (!isGitHubAppConfigured()) return jsonResponse({
|
|
18093
18278
|
success: false,
|
|
18094
18279
|
error: "GitHub App not configured"
|
|
@@ -18140,12 +18325,14 @@ const workspacesRouteLayer = Layer.mergeAll(getWorkspaceRoute, postWorkspacesRou
|
|
|
18140
18325
|
* GET /api/specialists/:project/:type/latest-log
|
|
18141
18326
|
* POST /api/specialists/:project/:type/logs/cleanup
|
|
18142
18327
|
*/
|
|
18328
|
+
init_paths();
|
|
18143
18329
|
init_projects();
|
|
18144
18330
|
init_review_status();
|
|
18145
18331
|
init_agents();
|
|
18146
18332
|
init_cost();
|
|
18147
18333
|
init_jsonl_parser();
|
|
18148
18334
|
init_io();
|
|
18335
|
+
init_issue_id();
|
|
18149
18336
|
const execAsync$8 = promisify(exec);
|
|
18150
18337
|
const VALID_SPECIALIST_NAMES = [
|
|
18151
18338
|
"merge-agent",
|
|
@@ -18172,12 +18359,11 @@ function firePostMergeLifecycle(issueId) {
|
|
|
18172
18359
|
console.log(`[merge] firePostMergeLifecycle: skipping ${issueId} — already in flight`);
|
|
18173
18360
|
return;
|
|
18174
18361
|
}
|
|
18175
|
-
const
|
|
18176
|
-
const projectPath = getProjectPathForIssue(issuePrefix);
|
|
18362
|
+
const projectPath = getProjectPathForIssue(extractPrefix(issueId) ?? issueId.split("-")[0]);
|
|
18177
18363
|
_postMergeInFlight.add(issueId);
|
|
18178
18364
|
(async () => {
|
|
18179
18365
|
try {
|
|
18180
|
-
const { postMergeLifecycle } = await import("./merge-agent-
|
|
18366
|
+
const { postMergeLifecycle } = await import("./merge-agent-CGN3TT0a.js");
|
|
18181
18367
|
await postMergeLifecycle(issueId, projectPath);
|
|
18182
18368
|
console.log(`[merge] post-merge lifecycle completed for ${issueId}`);
|
|
18183
18369
|
} catch (err) {
|
|
@@ -18193,15 +18379,15 @@ function getProjectPathForIssue(issuePrefix) {
|
|
|
18193
18379
|
return join$1(homedir(), "Projects");
|
|
18194
18380
|
}
|
|
18195
18381
|
const getSpecialistsRoute = HttpRouter.add("GET", "/api/specialists", httpHandler(Effect.gen(function* () {
|
|
18196
|
-
const { getAllSpecialistStatus, getAllProjectSpecialistStatuses } = yield* Effect.promise(() => import("./specialists-
|
|
18382
|
+
const { getAllSpecialistStatus, getAllProjectSpecialistStatuses } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18197
18383
|
return jsonResponse({
|
|
18198
18384
|
specialists: yield* Effect.promise(() => getAllSpecialistStatus()),
|
|
18199
18385
|
projects: yield* Effect.promise(() => getAllProjectSpecialistStatuses())
|
|
18200
18386
|
});
|
|
18201
18387
|
})));
|
|
18202
18388
|
const postSpecialistsResetAllRoute = HttpRouter.add("POST", "/api/specialists/reset-all", httpHandler(Effect.gen(function* () {
|
|
18203
|
-
const { getAllSpecialists, clearSessionId, isRunning, getTmuxSessionName } = yield* Effect.promise(() => import("./specialists-
|
|
18204
|
-
const { clearHook } = yield* Effect.promise(() => import("./hooks-
|
|
18389
|
+
const { getAllSpecialists, clearSessionId, isRunning, getTmuxSessionName } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18390
|
+
const { clearHook } = yield* Effect.promise(() => import("./hooks-CB4T47NC.js"));
|
|
18205
18391
|
const specialists = getAllSpecialists();
|
|
18206
18392
|
const results = [];
|
|
18207
18393
|
for (const specialist of specialists) {
|
|
@@ -18292,7 +18478,7 @@ const postSpecialistsDoneRoute = HttpRouter.add("POST", "/api/specialists/done",
|
|
|
18292
18478
|
const updatedStatus = setReviewStatus$1(normalizedIssueId, update);
|
|
18293
18479
|
yield* Effect.promise(async () => {
|
|
18294
18480
|
try {
|
|
18295
|
-
const { getTmuxSessionName, checkSpecialistQueue, completeSpecialistTask } = await import("./specialists-
|
|
18481
|
+
const { getTmuxSessionName, checkSpecialistQueue, completeSpecialistTask } = await import("./specialists-Cp-PgspS.js");
|
|
18296
18482
|
saveAgentRuntimeState(getTmuxSessionName(`${specialist}-agent`), {
|
|
18297
18483
|
state: "idle",
|
|
18298
18484
|
lastActivity: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -18313,7 +18499,7 @@ const postSpecialistsDoneRoute = HttpRouter.add("POST", "/api/specialists/done",
|
|
|
18313
18499
|
if (project) {
|
|
18314
18500
|
const workspacePath = join$1(project.projectPath, "workspaces", `feature-${normalizedIssueId.toLowerCase()}`);
|
|
18315
18501
|
if (existsSync$1(workspacePath)) {
|
|
18316
|
-
const { getWorkspaceGitInfo } = await import("./git-utils-
|
|
18502
|
+
const { getWorkspaceGitInfo } = await import("./git-utils-DQI8EYoj.js");
|
|
18317
18503
|
const { HEAD } = await getWorkspaceGitInfo(workspacePath);
|
|
18318
18504
|
setReviewStatus$1(normalizedIssueId, { reviewedAtCommit: HEAD });
|
|
18319
18505
|
console.log(`[specialists/done] Snapshotted reviewedAtCommit=${HEAD.substring(0, 8)} for ${normalizedIssueId}`);
|
|
@@ -18325,7 +18511,7 @@ const postSpecialistsDoneRoute = HttpRouter.add("POST", "/api/specialists/done",
|
|
|
18325
18511
|
});
|
|
18326
18512
|
if (specialist === "inspect" && status === "passed") yield* Effect.promise(async () => {
|
|
18327
18513
|
try {
|
|
18328
|
-
const { onInspectComplete } = await import("./inspect-agent-
|
|
18514
|
+
const { onInspectComplete } = await import("./inspect-agent-7eour7EA.js");
|
|
18329
18515
|
const beadId = (notes?.match(/[Bb]ead\s+(\S+)/))?.[1] || "unknown";
|
|
18330
18516
|
const project = resolveProjectFromIssue(normalizedIssueId);
|
|
18331
18517
|
if (project) {
|
|
@@ -18392,13 +18578,13 @@ const postSpecialistsDoneRoute = HttpRouter.add("POST", "/api/specialists/done",
|
|
|
18392
18578
|
if (specialist === "merge" && status === "failed" && notes?.toLowerCase().includes("conflict")) yield* Effect.promise(async () => {
|
|
18393
18579
|
try {
|
|
18394
18580
|
const workAgentId = `agent-${normalizedIssueId.toLowerCase()}`;
|
|
18395
|
-
const { sessionExists } = await import("./tmux-
|
|
18396
|
-
const { messageAgent } = await import("./agents-
|
|
18581
|
+
const { sessionExists } = await import("./tmux-BzxdKItf.js");
|
|
18582
|
+
const { messageAgent } = await import("./agents-Dgh2TjSp.js");
|
|
18397
18583
|
if (sessionExists(workAgentId)) {
|
|
18398
18584
|
await messageAgent(workAgentId, `MERGE CONFLICT: The merge-agent could not rebase your branch onto main due to conflicts. Please fix this now:\n\n1. git fetch origin main\n2. git rebase origin/main\n3. Resolve any conflicts (git add <file> && git rebase --continue)\n4. git push --force-with-lease\n5. Resubmit: curl -s -X POST http://localhost:3011/api/workspaces/${normalizedIssueId}/request-review -H "Content-Type: application/json" -d "{}"\n\nConflict details: ${notes}`);
|
|
18399
18585
|
console.log(`[specialists/done] Sent rebase instructions to ${workAgentId}`);
|
|
18400
18586
|
} else try {
|
|
18401
|
-
const { resumeAgent } = await import("./agents-
|
|
18587
|
+
const { resumeAgent } = await import("./agents-Dgh2TjSp.js");
|
|
18402
18588
|
const result = await resumeAgent(workAgentId, `MERGE CONFLICT: Your branch has conflicts with main. Run: git fetch origin main && git rebase origin/main, resolve conflicts, push with --force-with-lease, then resubmit for review.`);
|
|
18403
18589
|
if (result.success) console.log(`[specialists/done] Resumed ${workAgentId} with rebase instructions`);
|
|
18404
18590
|
else console.log(`[specialists/done] Could not resume ${workAgentId}: ${result.error}`);
|
|
@@ -18412,8 +18598,8 @@ const postSpecialistsDoneRoute = HttpRouter.add("POST", "/api/specialists/done",
|
|
|
18412
18598
|
if (specialist === "review" && status === "failed" && notes) yield* Effect.promise(async () => {
|
|
18413
18599
|
try {
|
|
18414
18600
|
const workAgentId = `agent-${normalizedIssueId.toLowerCase()}`;
|
|
18415
|
-
const { sessionExists } = await import("./tmux-
|
|
18416
|
-
const { messageAgent } = await import("./agents-
|
|
18601
|
+
const { sessionExists } = await import("./tmux-BzxdKItf.js");
|
|
18602
|
+
const { messageAgent } = await import("./agents-Dgh2TjSp.js");
|
|
18417
18603
|
if (sessionExists(workAgentId)) {
|
|
18418
18604
|
await messageAgent(workAgentId, `REVIEW FEEDBACK: The review specialist found issues that must be fixed:\n\n${notes}\n\nPlease address all issues, push your changes, then resubmit: curl -s -X POST http://localhost:3011/api/workspaces/${normalizedIssueId}/request-review -H "Content-Type: application/json" -d "{}"`);
|
|
18419
18605
|
console.log(`[specialists/done] Sent review feedback to ${workAgentId}`);
|
|
@@ -18449,7 +18635,7 @@ const postSpecialistsDoneRoute = HttpRouter.add("POST", "/api/specialists/done",
|
|
|
18449
18635
|
});
|
|
18450
18636
|
})));
|
|
18451
18637
|
const postSpecialistsLogsCleanupAllRoute = HttpRouter.add("POST", "/api/specialists/logs/cleanup-all", httpHandler(Effect.gen(function* () {
|
|
18452
|
-
const { cleanupAllLogs } = yield* Effect.promise(() => import("./specialist-logs-
|
|
18638
|
+
const { cleanupAllLogs } = yield* Effect.promise(() => import("./specialist-logs-CIw4qfTy.js"));
|
|
18453
18639
|
const results = cleanupAllLogs();
|
|
18454
18640
|
return jsonResponse({
|
|
18455
18641
|
success: true,
|
|
@@ -18459,7 +18645,7 @@ const postSpecialistsLogsCleanupAllRoute = HttpRouter.add("POST", "/api/speciali
|
|
|
18459
18645
|
});
|
|
18460
18646
|
})));
|
|
18461
18647
|
const getSpecialistQueuesRoute = HttpRouter.add("GET", "/api/specialists/queues", httpHandler(Effect.gen(function* () {
|
|
18462
|
-
const { getAllSpecialists, checkSpecialistQueue } = yield* Effect.promise(() => import("./specialists-
|
|
18648
|
+
const { getAllSpecialists, checkSpecialistQueue } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18463
18649
|
return jsonResponse({ queues: getAllSpecialists().map((specialist) => {
|
|
18464
18650
|
const queue = checkSpecialistQueue(specialist.name);
|
|
18465
18651
|
return {
|
|
@@ -18472,14 +18658,14 @@ const getSpecialistQueuesRoute = HttpRouter.add("GET", "/api/specialists/queues"
|
|
|
18472
18658
|
}) });
|
|
18473
18659
|
})));
|
|
18474
18660
|
const getSpecialistsProjectsRoute = HttpRouter.add("GET", "/api/specialists/projects", httpHandler(Effect.gen(function* () {
|
|
18475
|
-
const { getAllProjectSpecialistStatuses } = yield* Effect.promise(() => import("./specialists-
|
|
18661
|
+
const { getAllProjectSpecialistStatuses } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18476
18662
|
return jsonResponse(yield* Effect.promise(() => getAllProjectSpecialistStatuses()));
|
|
18477
18663
|
})));
|
|
18478
18664
|
const postSpecialistWakeRoute = HttpRouter.add("POST", "/api/specialists/:name/wake", httpHandler(Effect.gen(function* () {
|
|
18479
18665
|
const name = (yield* HttpRouter.params)["name"];
|
|
18480
18666
|
const { sessionId } = yield* readJsonBody$6;
|
|
18481
18667
|
const eventStore = yield* EventStoreService;
|
|
18482
|
-
const { getTmuxSessionName, getSessionId, recordWake, isRunning } = yield* Effect.promise(() => import("./specialists-
|
|
18668
|
+
const { getTmuxSessionName, getSessionId, recordWake, isRunning } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18483
18669
|
if (yield* Effect.promise(() => isRunning(name))) return jsonResponse({ error: `Specialist ${name} is already running` }, { status: 400 });
|
|
18484
18670
|
const existingSessionId = getSessionId(name);
|
|
18485
18671
|
const tmuxSession = getTmuxSessionName(name);
|
|
@@ -18487,7 +18673,7 @@ const postSpecialistWakeRoute = HttpRouter.add("POST", "/api/specialists/:name/w
|
|
|
18487
18673
|
const useSessionId = sessionId || existingSessionId;
|
|
18488
18674
|
let specModel = "claude-sonnet-4-6";
|
|
18489
18675
|
try {
|
|
18490
|
-
const { getModelId } = yield* Effect.promise(() => import("./work-type-router-
|
|
18676
|
+
const { getModelId } = yield* Effect.promise(() => import("./work-type-router-Di5gCQwh.js"));
|
|
18491
18677
|
specModel = getModelId(`specialist-${name}`);
|
|
18492
18678
|
} catch {}
|
|
18493
18679
|
const specCmd = getAgentCommand(specModel);
|
|
@@ -18515,7 +18701,7 @@ const postSpecialistWakeRoute = HttpRouter.add("POST", "/api/specialists/:name/w
|
|
|
18515
18701
|
const postSpecialistResetRoute = HttpRouter.add("POST", "/api/specialists/:name/reset", httpHandler(Effect.gen(function* () {
|
|
18516
18702
|
const name = (yield* HttpRouter.params)["name"];
|
|
18517
18703
|
const { reinitialize = false } = yield* readJsonBody$6;
|
|
18518
|
-
const { clearSessionId, isRunning, getTmuxSessionName } = yield* Effect.promise(() => import("./specialists-
|
|
18704
|
+
const { clearSessionId, isRunning, getTmuxSessionName } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18519
18705
|
if (yield* Effect.promise(() => isRunning(name))) return jsonResponse({ error: `Specialist ${name} is currently running. Stop it first (tmux kill-session -t ${getTmuxSessionName(name)})` }, { status: 400 });
|
|
18520
18706
|
const wasDeleted = clearSessionId(name);
|
|
18521
18707
|
if (reinitialize) {}
|
|
@@ -18527,7 +18713,7 @@ const postSpecialistResetRoute = HttpRouter.add("POST", "/api/specialists/:name/
|
|
|
18527
18713
|
})));
|
|
18528
18714
|
const postSpecialistInitRoute = HttpRouter.add("POST", "/api/specialists/:name/init", httpHandler(Effect.gen(function* () {
|
|
18529
18715
|
const name = (yield* HttpRouter.params)["name"];
|
|
18530
|
-
const { initializeSpecialist } = yield* Effect.promise(() => import("./specialists-
|
|
18716
|
+
const { initializeSpecialist } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18531
18717
|
const result = yield* Effect.promise(() => initializeSpecialist(name));
|
|
18532
18718
|
if (!result.success) return jsonResponse({ error: result.message }, { status: 400 });
|
|
18533
18719
|
return jsonResponse({
|
|
@@ -18566,7 +18752,7 @@ const postSpecialistReportStatusRoute = HttpRouter.add("POST", "/api/specialists
|
|
|
18566
18752
|
"blocked",
|
|
18567
18753
|
"failed"
|
|
18568
18754
|
].includes(status)) {
|
|
18569
|
-
const { getTmuxSessionName } = yield* Effect.promise(() => import("./specialists-
|
|
18755
|
+
const { getTmuxSessionName } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18570
18756
|
saveAgentRuntimeState(getTmuxSessionName(name), {
|
|
18571
18757
|
state: "idle",
|
|
18572
18758
|
lastActivity: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -18593,7 +18779,7 @@ const postSpecialistReportStatusRoute = HttpRouter.add("POST", "/api/specialists
|
|
|
18593
18779
|
})));
|
|
18594
18780
|
const getSpecialistCostRoute = HttpRouter.add("GET", "/api/specialists/:name/cost", httpHandler(Effect.gen(function* () {
|
|
18595
18781
|
const name = (yield* HttpRouter.params)["name"];
|
|
18596
|
-
const { getSessionId } = yield* Effect.promise(() => import("./specialists-
|
|
18782
|
+
const { getSessionId } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18597
18783
|
const sessionId = getSessionId(name);
|
|
18598
18784
|
if (!sessionId) return jsonResponse({
|
|
18599
18785
|
cost: 0,
|
|
@@ -18601,7 +18787,7 @@ const getSpecialistCostRoute = HttpRouter.add("GET", "/api/specialists/:name/cos
|
|
|
18601
18787
|
outputTokens: 0
|
|
18602
18788
|
});
|
|
18603
18789
|
const homeDir = process.env.HOME || homedir();
|
|
18604
|
-
const sessionsIndexPath = join$1(join$1(join$1(homeDir, ".claude", "projects"),
|
|
18790
|
+
const sessionsIndexPath = join$1(join$1(join$1(homeDir, ".claude", "projects"), encodeClaudeProjectDir(homeDir)), "sessions-index.json");
|
|
18605
18791
|
let cost = 0;
|
|
18606
18792
|
let inputTokens = 0;
|
|
18607
18793
|
let outputTokens = 0;
|
|
@@ -18648,7 +18834,7 @@ const getSpecialistCostRoute = HttpRouter.add("GET", "/api/specialists/:name/cos
|
|
|
18648
18834
|
const getSpecialistQueueRoute = HttpRouter.add("GET", "/api/specialists/:name/queue", httpHandler(Effect.gen(function* () {
|
|
18649
18835
|
const name = (yield* HttpRouter.params)["name"];
|
|
18650
18836
|
if (!VALID_SPECIALIST_NAMES.includes(name)) return jsonResponse({ error: `Invalid specialist name: ${name}` }, { status: 400 });
|
|
18651
|
-
const { checkSpecialistQueue } = yield* Effect.promise(() => import("./specialists-
|
|
18837
|
+
const { checkSpecialistQueue } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18652
18838
|
const queue = checkSpecialistQueue(name);
|
|
18653
18839
|
return jsonResponse({
|
|
18654
18840
|
specialistName: name,
|
|
@@ -18663,7 +18849,7 @@ const postSpecialistQueueRoute = HttpRouter.add("POST", "/api/specialists/:name/
|
|
|
18663
18849
|
const { issueId, workspace, branch, customPrompt, priority = "normal" } = yield* readJsonBody$6;
|
|
18664
18850
|
if (!VALID_SPECIALIST_NAMES.includes(name)) return jsonResponse({ error: `Invalid specialist name: ${name}` }, { status: 400 });
|
|
18665
18851
|
if (!issueId) return jsonResponse({ error: "issueId is required" }, { status: 400 });
|
|
18666
|
-
const { spawnEphemeralSpecialist, submitToSpecialistQueue } = yield* Effect.promise(() => import("./specialists-
|
|
18852
|
+
const { spawnEphemeralSpecialist, submitToSpecialistQueue } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18667
18853
|
const resolved = resolveProjectFromIssue(issueId);
|
|
18668
18854
|
if (!resolved) return jsonResponse({ error: `No project configured for ${issueId}. Add it to projects.yaml.` }, { status: 400 });
|
|
18669
18855
|
const result = yield* Effect.promise(() => spawnEphemeralSpecialist(resolved.projectKey, name, {
|
|
@@ -18697,7 +18883,7 @@ const deleteSpecialistQueueItemRoute = HttpRouter.add("DELETE", "/api/specialist
|
|
|
18697
18883
|
const name = params["name"];
|
|
18698
18884
|
const itemId = params["itemId"];
|
|
18699
18885
|
if (!VALID_SPECIALIST_NAMES.includes(name)) return jsonResponse({ error: `Invalid specialist name: ${name}` }, { status: 400 });
|
|
18700
|
-
const { completeSpecialistTask } = yield* Effect.promise(() => import("./specialists-
|
|
18886
|
+
const { completeSpecialistTask } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18701
18887
|
if (!completeSpecialistTask(name, itemId)) return jsonResponse({ error: `Item ${itemId} not found in queue for ${name}` }, { status: 404 });
|
|
18702
18888
|
return jsonResponse({
|
|
18703
18889
|
success: true,
|
|
@@ -18709,7 +18895,7 @@ const putSpecialistQueueReorderRoute = HttpRouter.add("PUT", "/api/specialists/:
|
|
|
18709
18895
|
const { itemIds } = yield* readJsonBody$6;
|
|
18710
18896
|
if (!Array.isArray(itemIds)) return jsonResponse({ error: "itemIds must be an array" }, { status: 400 });
|
|
18711
18897
|
if (!VALID_SPECIALIST_NAMES.includes(name)) return jsonResponse({ error: `Invalid specialist name: ${name}` }, { status: 400 });
|
|
18712
|
-
const { reorderHookItems } = yield* Effect.promise(() => import("./hooks-
|
|
18898
|
+
const { reorderHookItems } = yield* Effect.promise(() => import("./hooks-CB4T47NC.js"));
|
|
18713
18899
|
if (!reorderHookItems(name, itemIds)) return jsonResponse({ error: "Failed to reorder queue. Check that all item IDs are valid." }, { status: 400 });
|
|
18714
18900
|
return jsonResponse({
|
|
18715
18901
|
success: true,
|
|
@@ -18724,7 +18910,7 @@ const postSpecialistAutoCompleteRoute = HttpRouter.add("POST", "/api/specialists
|
|
|
18724
18910
|
if (!issueId || !status) return jsonResponse({ error: "issueId and status required" }, { status: 400 });
|
|
18725
18911
|
console.log(`[specialists] Auto-detected completion for ${name}: ${issueId} -> ${status}`);
|
|
18726
18912
|
if (!VALID_SPECIALIST_NAMES.includes(name)) return jsonResponse({ error: `Invalid specialist name: ${name}` }, { status: 400 });
|
|
18727
|
-
const { getTmuxSessionName, completeSpecialistTask, wakeSpecialistWithTask, checkSpecialistQueue, submitToSpecialistQueue } = yield* Effect.promise(() => import("./specialists-
|
|
18913
|
+
const { getTmuxSessionName, completeSpecialistTask, wakeSpecialistWithTask, checkSpecialistQueue, submitToSpecialistQueue } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18728
18914
|
saveAgentRuntimeState(getTmuxSessionName(name), {
|
|
18729
18915
|
state: "idle",
|
|
18730
18916
|
lastActivity: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -18824,7 +19010,7 @@ const getProjectSpecialistStatusRoute = HttpRouter.add("GET", "/api/specialists/
|
|
|
18824
19010
|
const project = params["project"];
|
|
18825
19011
|
const type = params["type"];
|
|
18826
19012
|
if (!validateSpecialistType(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
18827
|
-
const { getSpecialistStatus } = yield* Effect.promise(() => import("./specialists-
|
|
19013
|
+
const { getSpecialistStatus } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18828
19014
|
return jsonResponse(yield* Effect.promise(() => getSpecialistStatus(type, project)));
|
|
18829
19015
|
})));
|
|
18830
19016
|
const postProjectSpecialistKillRoute = HttpRouter.add("POST", "/api/specialists/:project/:type/kill", httpHandler(Effect.gen(function* () {
|
|
@@ -18832,7 +19018,7 @@ const postProjectSpecialistKillRoute = HttpRouter.add("POST", "/api/specialists/
|
|
|
18832
19018
|
const project = params["project"];
|
|
18833
19019
|
const type = params["type"];
|
|
18834
19020
|
if (!validateSpecialistType(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
18835
|
-
const { getTmuxSessionName } = yield* Effect.promise(() => import("./specialists-
|
|
19021
|
+
const { getTmuxSessionName } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18836
19022
|
const tmuxSession = getTmuxSessionName(type, project);
|
|
18837
19023
|
yield* Effect.promise(() => execAsync$8(`tmux kill-session -t "${tmuxSession}"`).catch(() => {}));
|
|
18838
19024
|
saveAgentRuntimeState(tmuxSession, {
|
|
@@ -18847,7 +19033,7 @@ const postProjectSpecialistKillRoute = HttpRouter.add("POST", "/api/specialists/
|
|
|
18847
19033
|
const getProjectSpecialistQueueRoute = HttpRouter.add("GET", "/api/specialists/:project/:type/queue", httpHandler(Effect.gen(function* () {
|
|
18848
19034
|
const type = (yield* HttpRouter.params)["type"];
|
|
18849
19035
|
if (!validateSpecialistType(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
18850
|
-
const { checkSpecialistQueue } = yield* Effect.promise(() => import("./specialists-
|
|
19036
|
+
const { checkSpecialistQueue } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18851
19037
|
return jsonResponse(checkSpecialistQueue(type));
|
|
18852
19038
|
})));
|
|
18853
19039
|
const postProjectSpecialistSpawnRoute = HttpRouter.add("POST", "/api/specialists/:project/:type/spawn", httpHandler(Effect.gen(function* () {
|
|
@@ -18857,7 +19043,7 @@ const postProjectSpecialistSpawnRoute = HttpRouter.add("POST", "/api/specialists
|
|
|
18857
19043
|
const { issueId, branch, workspace, prUrl, context } = yield* readJsonBody$6;
|
|
18858
19044
|
if (!issueId) return jsonResponse({ error: "issueId is required" }, { status: 400 });
|
|
18859
19045
|
if (!validateSpecialistType(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
18860
|
-
const { spawnEphemeralSpecialist } = yield* Effect.promise(() => import("./specialists-
|
|
19046
|
+
const { spawnEphemeralSpecialist } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18861
19047
|
const result = yield* Effect.promise(() => spawnEphemeralSpecialist(project, type, {
|
|
18862
19048
|
issueId,
|
|
18863
19049
|
branch,
|
|
@@ -18883,7 +19069,7 @@ const getProjectSpecialistRunsRoute = HttpRouter.add("GET", "/api/specialists/:p
|
|
|
18883
19069
|
if (limitParam) limit = parseInt(limitParam, 10);
|
|
18884
19070
|
if (offsetParam) offset = parseInt(offsetParam, 10);
|
|
18885
19071
|
}
|
|
18886
|
-
const { listRunLogs } = yield* Effect.promise(() => import("./specialist-logs-
|
|
19072
|
+
const { listRunLogs } = yield* Effect.promise(() => import("./specialist-logs-CIw4qfTy.js"));
|
|
18887
19073
|
return jsonResponse(listRunLogs(project, type, {
|
|
18888
19074
|
limit,
|
|
18889
19075
|
offset
|
|
@@ -18894,7 +19080,7 @@ const getProjectSpecialistRunStreamRoute = HttpRouter.add("GET", "/api/specialis
|
|
|
18894
19080
|
const project = params["project"];
|
|
18895
19081
|
const type = params["type"];
|
|
18896
19082
|
const runId = params["runId"];
|
|
18897
|
-
const { getRunLogPath, isRunLogActive } = yield* Effect.promise(() => import("./specialist-logs-
|
|
19083
|
+
const { getRunLogPath, isRunLogActive } = yield* Effect.promise(() => import("./specialist-logs-CIw4qfTy.js"));
|
|
18898
19084
|
const logPath = getRunLogPath(project, type, runId);
|
|
18899
19085
|
if (!existsSync$1(logPath)) return jsonResponse({ error: "Run log not found" }, { status: 404 });
|
|
18900
19086
|
const encoder = new TextEncoder();
|
|
@@ -18953,7 +19139,7 @@ const getProjectSpecialistRunRoute = HttpRouter.add("GET", "/api/specialists/:pr
|
|
|
18953
19139
|
const project = params["project"];
|
|
18954
19140
|
const type = params["type"];
|
|
18955
19141
|
const runId = params["runId"];
|
|
18956
|
-
const { getRunLog, parseLogMetadata } = yield* Effect.promise(() => import("./specialist-logs-
|
|
19142
|
+
const { getRunLog, parseLogMetadata } = yield* Effect.promise(() => import("./specialist-logs-CIw4qfTy.js"));
|
|
18957
19143
|
const content = getRunLog(project, type, runId);
|
|
18958
19144
|
if (!content) return jsonResponse({ error: "Run log not found" }, { status: 404 });
|
|
18959
19145
|
return jsonResponse({
|
|
@@ -18967,7 +19153,7 @@ const postProjectSpecialistRunTerminateRoute = HttpRouter.add("POST", "/api/spec
|
|
|
18967
19153
|
const project = params["project"];
|
|
18968
19154
|
const type = params["type"];
|
|
18969
19155
|
if (!validateSpecialistType(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
18970
|
-
const { terminateSpecialist } = yield* Effect.promise(() => import("./specialists-
|
|
19156
|
+
const { terminateSpecialist } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18971
19157
|
yield* Effect.promise(() => terminateSpecialist(project, type));
|
|
18972
19158
|
return jsonResponse({
|
|
18973
19159
|
success: true,
|
|
@@ -18979,7 +19165,7 @@ const postProjectSpecialistGracePauseRoute = HttpRouter.add("POST", "/api/specia
|
|
|
18979
19165
|
const project = params["project"];
|
|
18980
19166
|
const type = params["type"];
|
|
18981
19167
|
if (!validateSpecialistType(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
18982
|
-
const { pauseGracePeriod } = yield* Effect.promise(() => import("./specialists-
|
|
19168
|
+
const { pauseGracePeriod } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18983
19169
|
if (pauseGracePeriod(project, type)) return jsonResponse({
|
|
18984
19170
|
success: true,
|
|
18985
19171
|
message: "Grace period paused"
|
|
@@ -18991,7 +19177,7 @@ const postProjectSpecialistGraceResumeRoute = HttpRouter.add("POST", "/api/speci
|
|
|
18991
19177
|
const project = params["project"];
|
|
18992
19178
|
const type = params["type"];
|
|
18993
19179
|
if (!validateSpecialistType(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
18994
|
-
const { resumeGracePeriod } = yield* Effect.promise(() => import("./specialists-
|
|
19180
|
+
const { resumeGracePeriod } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
18995
19181
|
if (resumeGracePeriod(project, type)) return jsonResponse({
|
|
18996
19182
|
success: true,
|
|
18997
19183
|
message: "Grace period resumed"
|
|
@@ -19003,7 +19189,7 @@ const postProjectSpecialistGraceExitRoute = HttpRouter.add("POST", "/api/special
|
|
|
19003
19189
|
const project = params["project"];
|
|
19004
19190
|
const type = params["type"];
|
|
19005
19191
|
if (!validateSpecialistType(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
19006
|
-
const { exitGracePeriod } = yield* Effect.promise(() => import("./specialists-
|
|
19192
|
+
const { exitGracePeriod } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
19007
19193
|
exitGracePeriod(project, type);
|
|
19008
19194
|
return jsonResponse({
|
|
19009
19195
|
success: true,
|
|
@@ -19015,7 +19201,7 @@ const getProjectSpecialistGraceRoute = HttpRouter.add("GET", "/api/specialists/:
|
|
|
19015
19201
|
const project = params["project"];
|
|
19016
19202
|
const type = params["type"];
|
|
19017
19203
|
if (!validateSpecialistType(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
19018
|
-
const { getGracePeriodState } = yield* Effect.promise(() => import("./specialists-
|
|
19204
|
+
const { getGracePeriodState } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
19019
19205
|
const state = getGracePeriodState(project, type);
|
|
19020
19206
|
if (state) return jsonResponse(state);
|
|
19021
19207
|
else return jsonResponse({ error: "No active grace period" }, { status: 404 });
|
|
@@ -19024,7 +19210,7 @@ const getProjectSpecialistContextRoute = HttpRouter.add("GET", "/api/specialists
|
|
|
19024
19210
|
const params = yield* HttpRouter.params;
|
|
19025
19211
|
const project = params["project"];
|
|
19026
19212
|
const type = params["type"];
|
|
19027
|
-
const { loadContextDigest } = yield* Effect.promise(() => import("./specialist-context-
|
|
19213
|
+
const { loadContextDigest } = yield* Effect.promise(() => import("./specialist-context-DGukHSn8.js"));
|
|
19028
19214
|
const digest = loadContextDigest(project, type);
|
|
19029
19215
|
if (digest) return jsonResponse({ digest });
|
|
19030
19216
|
else return jsonResponse({ error: "No context digest found" }, { status: 404 });
|
|
@@ -19033,7 +19219,7 @@ const postProjectSpecialistContextRegenerateRoute = HttpRouter.add("POST", "/api
|
|
|
19033
19219
|
const params = yield* HttpRouter.params;
|
|
19034
19220
|
const project = params["project"];
|
|
19035
19221
|
const type = params["type"];
|
|
19036
|
-
const { regenerateContextDigest } = yield* Effect.promise(() => import("./specialist-context-
|
|
19222
|
+
const { regenerateContextDigest } = yield* Effect.promise(() => import("./specialist-context-DGukHSn8.js"));
|
|
19037
19223
|
const digest = yield* Effect.promise(() => regenerateContextDigest(project, type));
|
|
19038
19224
|
if (digest) return jsonResponse({
|
|
19039
19225
|
digest,
|
|
@@ -19052,7 +19238,7 @@ const postProjectSpecialistCompleteRoute = HttpRouter.add("POST", "/api/speciali
|
|
|
19052
19238
|
"blocked"
|
|
19053
19239
|
].includes(status)) return jsonResponse({ error: "Valid status (passed/failed/blocked) is required" }, { status: 400 });
|
|
19054
19240
|
if (!validateSpecialistType(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
19055
|
-
const { signalSpecialistCompletion } = yield* Effect.promise(() => import("./specialists-
|
|
19241
|
+
const { signalSpecialistCompletion } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
19056
19242
|
signalSpecialistCompletion(project, type, {
|
|
19057
19243
|
status,
|
|
19058
19244
|
notes
|
|
@@ -19086,8 +19272,8 @@ const postProjectSpecialistLogsCleanupRoute = HttpRouter.add("POST", "/api/speci
|
|
|
19086
19272
|
const params = yield* HttpRouter.params;
|
|
19087
19273
|
const project = params["project"];
|
|
19088
19274
|
const type = params["type"];
|
|
19089
|
-
const { cleanupOldLogs } = yield* Effect.promise(() => import("./specialist-logs-
|
|
19090
|
-
const { getSpecialistRetention } = yield* Effect.promise(() => import("./projects-
|
|
19275
|
+
const { cleanupOldLogs } = yield* Effect.promise(() => import("./specialist-logs-CIw4qfTy.js"));
|
|
19276
|
+
const { getSpecialistRetention } = yield* Effect.promise(() => import("./projects-C5ozxjwP.js"));
|
|
19091
19277
|
const deleted = cleanupOldLogs(project, type, getSpecialistRetention(project));
|
|
19092
19278
|
return jsonResponse({
|
|
19093
19279
|
success: true,
|
|
@@ -19099,7 +19285,7 @@ const postProjectSpecialistResetSessionRoute = HttpRouter.add("POST", "/api/spec
|
|
|
19099
19285
|
const params = yield* HttpRouter.params;
|
|
19100
19286
|
const projectKey = params["project"] ?? "";
|
|
19101
19287
|
const name = params["name"] ?? "";
|
|
19102
|
-
const { bumpSessionGeneration } = yield* Effect.promise(() => import("./specialists-
|
|
19288
|
+
const { bumpSessionGeneration } = yield* Effect.promise(() => import("./specialists-Cp-PgspS.js"));
|
|
19103
19289
|
const newGen = bumpSessionGeneration(name, projectKey);
|
|
19104
19290
|
const tmuxSession = `specialist-${projectKey}-${name}`;
|
|
19105
19291
|
try {
|
|
@@ -20050,6 +20236,7 @@ function getOpenRouterFavorites() {
|
|
|
20050
20236
|
init_agents();
|
|
20051
20237
|
init_paths();
|
|
20052
20238
|
init_projects();
|
|
20239
|
+
init_issue_id();
|
|
20053
20240
|
init_specialists();
|
|
20054
20241
|
init_tracker_config();
|
|
20055
20242
|
const execAsync$5 = promisify(exec);
|
|
@@ -20100,7 +20287,7 @@ const getMissionControlActivityRoute = HttpRouter.add("GET", "/api/command-deck/
|
|
|
20100
20287
|
})));
|
|
20101
20288
|
async function fetchActivityData(issueId) {
|
|
20102
20289
|
const issueLower = issueId.toLowerCase();
|
|
20103
|
-
const issuePrefix = issueId.split("-")[0];
|
|
20290
|
+
const issuePrefix = extractPrefix(issueId) ?? issueId.split("-")[0];
|
|
20104
20291
|
const sections = [];
|
|
20105
20292
|
const agentId = `agent-${issueLower}`;
|
|
20106
20293
|
const planningAgentId = `planning-${issueLower}`;
|
|
@@ -20293,8 +20480,7 @@ const getMissionControlPlanningRoute = HttpRouter.add("GET", "/api/command-deck/
|
|
|
20293
20480
|
})));
|
|
20294
20481
|
async function fetchPlanningData(issueId) {
|
|
20295
20482
|
const issueLower = issueId.toLowerCase();
|
|
20296
|
-
const
|
|
20297
|
-
const projectPath = getProjectPath$1(issuePrefix);
|
|
20483
|
+
const projectPath = getProjectPath$1(extractPrefix(issueId) ?? issueId.split("-")[0]);
|
|
20298
20484
|
const planningDir = join$1(join$1(projectPath, "workspaces", `feature-${issueLower}`), ".planning");
|
|
20299
20485
|
const result = {
|
|
20300
20486
|
transcripts: [],
|
|
@@ -20377,8 +20563,7 @@ const postMissionControlStatusReviewRoute = HttpRouter.add("POST", "/api/command
|
|
|
20377
20563
|
})));
|
|
20378
20564
|
async function generateStatusReview(issueId) {
|
|
20379
20565
|
const issueLower = issueId.toLowerCase();
|
|
20380
|
-
const
|
|
20381
|
-
const workspacePath = join$1(getProjectPath$1(issuePrefix), "workspaces", `feature-${issueLower}`);
|
|
20566
|
+
const workspacePath = join$1(getProjectPath$1(extractPrefix(issueId) ?? issueId.split("-")[0]), "workspaces", `feature-${issueLower}`);
|
|
20382
20567
|
const planningDir = join$1(workspacePath, ".planning");
|
|
20383
20568
|
if (!await pathExists(planningDir)) return {
|
|
20384
20569
|
type: "err",
|
|
@@ -20526,7 +20711,7 @@ Be specific: reference actual file names, function names, requirement text, disc
|
|
|
20526
20711
|
const { command: cliCmd, args: cliArgs } = getAgentCommand(statusModelId);
|
|
20527
20712
|
const modelFlag = cliArgs.length > 0 ? ` ${cliArgs.join(" ")}` : "";
|
|
20528
20713
|
const promptFile = join$1(planningDir, ".status-review-prompt.tmp");
|
|
20529
|
-
const { getProviderForModel, getProviderEnv } = await import("./providers-
|
|
20714
|
+
const { getProviderForModel, getProviderEnv } = await import("./providers-csVZVPkE.js");
|
|
20530
20715
|
const { loadConfig: loadYamlConfig } = await import("./config-yaml-DkresmrS.js");
|
|
20531
20716
|
let providerEnvStr = "";
|
|
20532
20717
|
const statusProvider = getProviderForModel(statusModelId);
|
|
@@ -20599,13 +20784,13 @@ const postMissionControlUploadRoute = HttpRouter.add("POST", "/api/command-deck/
|
|
|
20599
20784
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
20600
20785
|
const { type, filename, content } = yield* readJsonBody$4;
|
|
20601
20786
|
const issueLower = issueId.toLowerCase();
|
|
20602
|
-
const issuePrefix = issueId.split("-")[0];
|
|
20787
|
+
const issuePrefix = extractPrefix(issueId) ?? issueId.split("-")[0];
|
|
20603
20788
|
if (!type || !filename || !content) return jsonResponse({ error: "type, filename, and content are required" }, { status: 400 });
|
|
20604
20789
|
if (!["transcript", "note"].includes(type)) return jsonResponse({ error: "type must be transcript or note" }, { status: 400 });
|
|
20605
20790
|
let safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
20606
20791
|
let processedContent = content;
|
|
20607
20792
|
if (safeName.endsWith(".vtt")) {
|
|
20608
|
-
const { vttToMarkdown } = yield* Effect.promise(() => import("./vtt-parser-
|
|
20793
|
+
const { vttToMarkdown } = yield* Effect.promise(() => import("./vtt-parser-99vFekRQ.js"));
|
|
20609
20794
|
processedContent = vttToMarkdown(content);
|
|
20610
20795
|
safeName = safeName.replace(/\.vtt$/, ".md");
|
|
20611
20796
|
}
|
|
@@ -20629,7 +20814,7 @@ const postMissionControlSyncDiscussionsRoute = HttpRouter.add("POST", "/api/comm
|
|
|
20629
20814
|
const linear = yield* LinearClient$1;
|
|
20630
20815
|
const { tracker } = body;
|
|
20631
20816
|
const issueLower = issueId.toLowerCase();
|
|
20632
|
-
const issuePrefix = issueId.split("-")[0];
|
|
20817
|
+
const issuePrefix = extractPrefix(issueId) ?? issueId.split("-")[0];
|
|
20633
20818
|
if (!tracker || ![
|
|
20634
20819
|
"github",
|
|
20635
20820
|
"linear",
|
|
@@ -20738,8 +20923,7 @@ const postMissionControlPlanningInitRoute = HttpRouter.add("POST", "/api/command
|
|
|
20738
20923
|
const eventStore = yield* EventStoreService;
|
|
20739
20924
|
const { shadow } = body;
|
|
20740
20925
|
const issueLower = issueId.toLowerCase();
|
|
20741
|
-
const
|
|
20742
|
-
const planningDir = join$1(join$1(getProjectPath$1(issuePrefix), "workspaces", `feature-${issueLower}`), ".planning");
|
|
20926
|
+
const planningDir = join$1(join$1(getProjectPath$1(extractPrefix(issueId) ?? issueId.split("-")[0]), "workspaces", `feature-${issueLower}`), ".planning");
|
|
20743
20927
|
yield* Effect.tryPromise({
|
|
20744
20928
|
try: async () => {
|
|
20745
20929
|
await Promise.all([
|
|
@@ -21227,12 +21411,7 @@ const MODEL_API_IDS = {
|
|
|
21227
21411
|
"kimi-k2": { apiModel: "moonshot-v1-8k" },
|
|
21228
21412
|
"kimi-k2.5": { apiModel: "moonshot-v1-32k" },
|
|
21229
21413
|
"kimi-k2-turbo": { apiModel: "moonshot-v1-8k" },
|
|
21230
|
-
"glm-4.7": { apiModel: "glm-4" }
|
|
21231
|
-
"glm-4.7-flash": { apiModel: "glm-4-flash" },
|
|
21232
|
-
"glm-4-plus": { apiModel: "glm-4" },
|
|
21233
|
-
"glm-4-air": { apiModel: "glm-4-air" },
|
|
21234
|
-
"glm-4-flash": { apiModel: "glm-4-flash" },
|
|
21235
|
-
"glm-4-long": { apiModel: "glm-4-long" }
|
|
21414
|
+
"glm-4.7-flash": { apiModel: "glm-4.7-flash" }
|
|
21236
21415
|
};
|
|
21237
21416
|
const getSettingsRoute = HttpRouter.add("GET", "/api/settings", httpHandler(Effect.try({
|
|
21238
21417
|
try: () => jsonResponse(loadSettingsApi()),
|
|
@@ -21349,7 +21528,7 @@ const postTestApiKeyRoute = HttpRouter.add("POST", "/api/settings/test-api-key",
|
|
|
21349
21528
|
break;
|
|
21350
21529
|
}
|
|
21351
21530
|
case "zai": {
|
|
21352
|
-
const apiModel = model ? MODEL_API_IDS[model]?.apiModel || "glm-4-flash" : "glm-4-flash";
|
|
21531
|
+
const apiModel = model ? MODEL_API_IDS[model]?.apiModel || "glm-4.7-flash" : "glm-4.7-flash";
|
|
21353
21532
|
try {
|
|
21354
21533
|
const resp = await fetch("https://open.bigmodel.cn/api/paas/v4/chat/completions", {
|
|
21355
21534
|
method: "POST",
|
|
@@ -21476,7 +21655,7 @@ const postValidateApiKeyRoute = HttpRouter.add("POST", "/api/settings/validate-a
|
|
|
21476
21655
|
if (resp.ok) {
|
|
21477
21656
|
const data = await resp.json();
|
|
21478
21657
|
valid = true;
|
|
21479
|
-
models = data.data?.map((m) => m.id) || ["glm-4.7
|
|
21658
|
+
models = data.data?.map((m) => m.id) || ["glm-4.7-flash"];
|
|
21480
21659
|
} else if (resp.status === 401) error = "Invalid API key";
|
|
21481
21660
|
else if (resp.status === 429) error = "Rate limit exceeded";
|
|
21482
21661
|
else error = `HTTP error: ${resp.status}`;
|
|
@@ -21923,7 +22102,6 @@ async function stopConvoy(convoyId) {
|
|
|
21923
22102
|
* POST /api/convoys/:id/stop
|
|
21924
22103
|
* GET /api/convoys/:id/output
|
|
21925
22104
|
*/
|
|
21926
|
-
const activities = [];
|
|
21927
22105
|
const getMetricsSummaryRoute = HttpRouter.add("GET", "/api/metrics/summary", httpHandler(Effect.try({
|
|
21928
22106
|
try: () => {
|
|
21929
22107
|
const status = getCloisterService().getStatus();
|
|
@@ -21985,13 +22163,33 @@ const getMetricsStuckRoute = HttpRouter.add("GET", "/api/metrics/stuck", httpHan
|
|
|
21985
22163
|
},
|
|
21986
22164
|
catch: (err) => new Error(err instanceof Error ? err.message : String(err))
|
|
21987
22165
|
})));
|
|
21988
|
-
const getActivityRoute = HttpRouter.add("GET", "/api/activity", Effect.
|
|
21989
|
-
|
|
21990
|
-
|
|
21991
|
-
|
|
22166
|
+
const getActivityRoute = HttpRouter.add("GET", "/api/activity", httpHandler(Effect.gen(function* () {
|
|
22167
|
+
return jsonResponse((yield* (yield* EventStoreService).queryByType("activity.entry", 100)).map((e) => ({
|
|
22168
|
+
id: e.payload["id"],
|
|
22169
|
+
timestamp: e.timestamp,
|
|
22170
|
+
source: e.payload["source"],
|
|
22171
|
+
level: e.payload["level"],
|
|
22172
|
+
message: e.payload["message"],
|
|
22173
|
+
details: e.payload["details"],
|
|
22174
|
+
issueId: e.payload["issueId"]
|
|
22175
|
+
})));
|
|
22176
|
+
})));
|
|
22177
|
+
const getActivityByIdRoute = HttpRouter.add("GET", "/api/activity/:id", httpHandler(Effect.gen(function* () {
|
|
22178
|
+
const params = yield* HttpRouter.params;
|
|
22179
|
+
const eventStore = yield* EventStoreService;
|
|
22180
|
+
const id = params["id"] ?? "";
|
|
22181
|
+
const activity = (yield* eventStore.queryByType("activity.entry", 1e3)).find((e) => e.payload["id"] === id);
|
|
21992
22182
|
if (!activity) return jsonResponse({ error: "Activity not found" }, { status: 404 });
|
|
21993
|
-
return jsonResponse(
|
|
21994
|
-
|
|
22183
|
+
return jsonResponse({
|
|
22184
|
+
id: activity.payload["id"],
|
|
22185
|
+
timestamp: activity.timestamp,
|
|
22186
|
+
source: activity.payload["source"],
|
|
22187
|
+
level: activity.payload["level"],
|
|
22188
|
+
message: activity.payload["message"],
|
|
22189
|
+
details: activity.payload["details"],
|
|
22190
|
+
issueId: activity.payload["issueId"]
|
|
22191
|
+
});
|
|
22192
|
+
})));
|
|
21995
22193
|
const getConvoysRoute = HttpRouter.add("GET", "/api/convoys", httpHandler(Effect.try({
|
|
21996
22194
|
try: () => jsonResponse({ convoys: listConvoys() }),
|
|
21997
22195
|
catch: (err) => new Error(err instanceof Error ? err.message : String(err))
|
|
@@ -22160,12 +22358,14 @@ async function determineHealthStatusAsync(agentId, stateFile) {
|
|
|
22160
22358
|
* GET /api/metrics/tasks
|
|
22161
22359
|
* POST /api/shadow/:issueId/monitor
|
|
22162
22360
|
* POST /api/shadow/:issueId/observe
|
|
22361
|
+
* POST /api/dev/rebuild
|
|
22163
22362
|
*/
|
|
22164
22363
|
init_tmux();
|
|
22165
22364
|
init_projects();
|
|
22166
22365
|
init_tracker_config();
|
|
22167
22366
|
init_config_yaml();
|
|
22168
22367
|
init_config();
|
|
22368
|
+
init_issue_id();
|
|
22169
22369
|
const execAsync$2 = promisify(exec);
|
|
22170
22370
|
function readPackageVersion() {
|
|
22171
22371
|
let dir = dirname$1(fileURLToPath(import.meta.url));
|
|
@@ -22181,6 +22381,16 @@ function readPackageVersion() {
|
|
|
22181
22381
|
return "0.0.0";
|
|
22182
22382
|
}
|
|
22183
22383
|
const panopticonVersion = readPackageVersion();
|
|
22384
|
+
const panopticonDevMode = (() => {
|
|
22385
|
+
let dir = dirname$1(fileURLToPath(import.meta.url));
|
|
22386
|
+
for (let i = 0; i < 8; i++) {
|
|
22387
|
+
if (existsSync$1(join$1(dir, "package.json")) && existsSync$1(join$1(dir, "src", "dashboard"))) return true;
|
|
22388
|
+
const parent = dirname$1(dir);
|
|
22389
|
+
if (parent === dir) break;
|
|
22390
|
+
dir = parent;
|
|
22391
|
+
}
|
|
22392
|
+
return false;
|
|
22393
|
+
})();
|
|
22184
22394
|
function getIssueDataService() {
|
|
22185
22395
|
const { getSharedIssueService } = (init_issue_service_singleton(), __toCommonJS(issue_service_singleton_exports));
|
|
22186
22396
|
return getSharedIssueService();
|
|
@@ -22517,7 +22727,7 @@ const postRallyValidateRoute = HttpRouter.add("POST", "/api/rally/validate", Eff
|
|
|
22517
22727
|
}, { status: 400 });
|
|
22518
22728
|
return yield* Effect.promise(async () => {
|
|
22519
22729
|
try {
|
|
22520
|
-
const { RallyRestApi } = await import("./rally-api-
|
|
22730
|
+
const { RallyRestApi } = await import("./rally-api-DNttdCW4.js");
|
|
22521
22731
|
return jsonResponse({
|
|
22522
22732
|
valid: true,
|
|
22523
22733
|
message: "Rally connection successful",
|
|
@@ -22590,7 +22800,10 @@ const postDeaconPatrolRoute = HttpRouter.add("POST", "/api/deacon/patrol", Effec
|
|
|
22590
22800
|
return jsonResponse({ error: "Failed to run patrol: " + msg }, { status: 500 });
|
|
22591
22801
|
}
|
|
22592
22802
|
}));
|
|
22593
|
-
const getVersionRoute = HttpRouter.add("GET", "/api/version", Effect.sync(() => jsonResponse({
|
|
22803
|
+
const getVersionRoute = HttpRouter.add("GET", "/api/version", Effect.sync(() => jsonResponse({
|
|
22804
|
+
version: panopticonVersion,
|
|
22805
|
+
isDev: panopticonDevMode
|
|
22806
|
+
})));
|
|
22594
22807
|
const getRegisteredProjectsRoute = HttpRouter.add("GET", "/api/registered-projects", Effect.try({
|
|
22595
22808
|
try: () => {
|
|
22596
22809
|
return jsonResponse(listProjects().map((p) => ({
|
|
@@ -22729,7 +22942,7 @@ const getPlanningStatusRoute = HttpRouter.add("GET", "/api/planning/:issueId/sta
|
|
|
22729
22942
|
const issueId = new URL(request.url, "http://localhost").pathname.split("/")[3] || "";
|
|
22730
22943
|
const sessionName = `planning-${issueId.toLowerCase()}`;
|
|
22731
22944
|
const issueLower = issueId.toLowerCase();
|
|
22732
|
-
const issuePrefix = issueId.split("-")[0];
|
|
22945
|
+
const issuePrefix = extractPrefix(issueId) ?? issueId.split("-")[0];
|
|
22733
22946
|
return yield* Effect.promise(async () => {
|
|
22734
22947
|
try {
|
|
22735
22948
|
const projectPath = await getProjectPath(issuePrefix);
|
|
@@ -22896,10 +23109,10 @@ Continue the PLANNING session. Do NOT implement anything.
|
|
|
22896
23109
|
`);
|
|
22897
23110
|
const agentCwd = workspacePath;
|
|
22898
23111
|
if (existsSync$1(outputFile)) await rename(outputFile, join$1(planningDir, `output-${Date.now()}.jsonl`));
|
|
22899
|
-
const { getAgentCommand } = await import("./settings-
|
|
23112
|
+
const { getAgentCommand } = await import("./settings-XWvDcj-D.js");
|
|
22900
23113
|
let msgPlanningModel = "claude-sonnet-4-6";
|
|
22901
23114
|
try {
|
|
22902
|
-
const { getModelId } = await import("./work-type-router-
|
|
23115
|
+
const { getModelId } = await import("./work-type-router-Di5gCQwh.js");
|
|
22903
23116
|
msgPlanningModel = getModelId("planning-agent");
|
|
22904
23117
|
} catch {}
|
|
22905
23118
|
const msgAgentCmd = getAgentCommand(msgPlanningModel);
|
|
@@ -22946,7 +23159,7 @@ const deletePlanningSessionRoute = HttpRouter.add("DELETE", "/api/planning/:issu
|
|
|
22946
23159
|
}));
|
|
22947
23160
|
const getTldrStatusRoute = HttpRouter.add("GET", "/api/services/tldr/status", Effect.promise(async () => {
|
|
22948
23161
|
try {
|
|
22949
|
-
const { getTldrDaemonService } = await import("./tldr-daemon-
|
|
23162
|
+
const { getTldrDaemonService } = await import("./tldr-daemon-Cfs0bXTi.js");
|
|
22950
23163
|
const projectRoot = process.cwd();
|
|
22951
23164
|
const venvPath = join$1(projectRoot, ".venv");
|
|
22952
23165
|
const results = [];
|
|
@@ -22991,7 +23204,7 @@ const getTldrStatusRoute = HttpRouter.add("GET", "/api/services/tldr/status", Ef
|
|
|
22991
23204
|
}));
|
|
22992
23205
|
const postTldrStartRoute = HttpRouter.add("POST", "/api/services/tldr/start", Effect.promise(async () => {
|
|
22993
23206
|
try {
|
|
22994
|
-
const { getTldrDaemonService } = await import("./tldr-daemon-
|
|
23207
|
+
const { getTldrDaemonService } = await import("./tldr-daemon-Cfs0bXTi.js");
|
|
22995
23208
|
const projectRoot = process.cwd();
|
|
22996
23209
|
const venvPath = join$1(projectRoot, ".venv");
|
|
22997
23210
|
if (!existsSync$1(venvPath)) return jsonResponse({ error: "No .venv found in project root" }, { status: 404 });
|
|
@@ -23008,7 +23221,7 @@ const postTldrStartRoute = HttpRouter.add("POST", "/api/services/tldr/start", Ef
|
|
|
23008
23221
|
}));
|
|
23009
23222
|
const postTldrStopRoute = HttpRouter.add("POST", "/api/services/tldr/stop", Effect.promise(async () => {
|
|
23010
23223
|
try {
|
|
23011
|
-
const { getTldrDaemonService } = await import("./tldr-daemon-
|
|
23224
|
+
const { getTldrDaemonService } = await import("./tldr-daemon-Cfs0bXTi.js");
|
|
23012
23225
|
const projectRoot = process.cwd();
|
|
23013
23226
|
const venvPath = join$1(projectRoot, ".venv");
|
|
23014
23227
|
if (!existsSync$1(venvPath)) return jsonResponse({ error: "No .venv found in project root" }, { status: 404 });
|
|
@@ -23097,13 +23310,13 @@ const postShadowMonitorRoute = HttpRouter.add("POST", "/api/shadow/:issueId/moni
|
|
|
23097
23310
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
23098
23311
|
const issueId = new URL(request.url, "http://localhost").pathname.split("/")[3] || "";
|
|
23099
23312
|
const issueLower = issueId.toLowerCase();
|
|
23100
|
-
const issuePrefix = issueId.split("-")[0];
|
|
23313
|
+
const issuePrefix = extractPrefix(issueId) ?? issueId.split("-")[0];
|
|
23101
23314
|
return yield* Effect.promise(async () => {
|
|
23102
23315
|
try {
|
|
23103
23316
|
const projectPath = await getProjectPath(issuePrefix);
|
|
23104
23317
|
const workspacePath = join$1(projectPath, "workspaces", `feature-${issueLower}`);
|
|
23105
23318
|
if (!existsSync$1(workspacePath)) return jsonResponse({ error: "Workspace not found" }, { status: 404 });
|
|
23106
|
-
const { gatherArtifacts, generateBasicInference, updateInferenceDocument } = await import("./shadow-engineering-
|
|
23319
|
+
const { gatherArtifacts, generateBasicInference, updateInferenceDocument } = await import("./shadow-engineering-lIn1W_95.js");
|
|
23107
23320
|
const config = {
|
|
23108
23321
|
issueId,
|
|
23109
23322
|
workspacePath,
|
|
@@ -23124,7 +23337,7 @@ const postShadowObserveRoute = HttpRouter.add("POST", "/api/shadow/:issueId/obse
|
|
|
23124
23337
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
23125
23338
|
const issueId = new URL(request.url, "http://localhost").pathname.split("/")[3] || "";
|
|
23126
23339
|
const issueLower = issueId.toLowerCase();
|
|
23127
|
-
const issuePrefix = issueId.split("-")[0];
|
|
23340
|
+
const issuePrefix = extractPrefix(issueId) ?? issueId.split("-")[0];
|
|
23128
23341
|
const { mode } = yield* readJsonBody$1;
|
|
23129
23342
|
return yield* Effect.promise(async () => {
|
|
23130
23343
|
try {
|
|
@@ -23133,7 +23346,7 @@ const postShadowObserveRoute = HttpRouter.add("POST", "/api/shadow/:issueId/obse
|
|
|
23133
23346
|
if (!existsSync$1(workspacePath)) return jsonResponse({ error: "Workspace not found" }, { status: 404 });
|
|
23134
23347
|
const ghConfig = getGitHubConfig();
|
|
23135
23348
|
if (!ghConfig) return jsonResponse({ error: "GitHub not configured - Observer requires GitHub" }, { status: 400 });
|
|
23136
|
-
const { runObserverCycle } = await import("./shadow-engineering-
|
|
23349
|
+
const { runObserverCycle } = await import("./shadow-engineering-lIn1W_95.js");
|
|
23137
23350
|
const firstRepo = ghConfig.repos[0];
|
|
23138
23351
|
return jsonResponse({
|
|
23139
23352
|
success: true,
|
|
@@ -23150,7 +23363,35 @@ const postShadowObserveRoute = HttpRouter.add("POST", "/api/shadow/:issueId/obse
|
|
|
23150
23363
|
}
|
|
23151
23364
|
});
|
|
23152
23365
|
}));
|
|
23153
|
-
const
|
|
23366
|
+
const panopticonProjectRoot = (() => {
|
|
23367
|
+
let dir = dirname$1(fileURLToPath(import.meta.url));
|
|
23368
|
+
for (let i = 0; i < 8; i++) {
|
|
23369
|
+
if (existsSync$1(join$1(dir, "package.json")) && existsSync$1(join$1(dir, "src", "dashboard"))) return dir;
|
|
23370
|
+
const parent = dirname$1(dir);
|
|
23371
|
+
if (parent === dir) break;
|
|
23372
|
+
dir = parent;
|
|
23373
|
+
}
|
|
23374
|
+
return null;
|
|
23375
|
+
})();
|
|
23376
|
+
const postDevRebuildRoute = HttpRouter.add("POST", "/api/dev/rebuild", Effect.gen(function* () {
|
|
23377
|
+
if (!panopticonDevMode || !panopticonProjectRoot) return jsonResponse({ error: "Rebuild only available in dev mode" }, { status: 403 });
|
|
23378
|
+
return yield* Effect.promise(async () => {
|
|
23379
|
+
try {
|
|
23380
|
+
const { stdout, stderr } = await execAsync$2("npm run build", {
|
|
23381
|
+
cwd: panopticonProjectRoot,
|
|
23382
|
+
timeout: 12e4
|
|
23383
|
+
});
|
|
23384
|
+
return jsonResponse({
|
|
23385
|
+
ok: true,
|
|
23386
|
+
stdout: stdout.slice(-2e3),
|
|
23387
|
+
stderr: stderr.slice(-2e3)
|
|
23388
|
+
});
|
|
23389
|
+
} catch (error) {
|
|
23390
|
+
return jsonResponse({ error: `Build failed: ${error instanceof Error ? error.message : String(error)}` }, { status: 500 });
|
|
23391
|
+
}
|
|
23392
|
+
});
|
|
23393
|
+
}));
|
|
23394
|
+
const miscRouteLayer = Layer.mergeAll(postTrackersRefreshRoute, getProjectMappingsRoute, putProjectMappingsRoute, postProjectMappingsRoute, getGodviewSystemHealthRoute, getHealthAgentsRoute, postHealthAgentPingRoute, getTrackerStatusRoute, postRallyValidateRoute, getDeaconStatusRoute, getDeaconLogsRoute, postDeaconPatrolRoute, getVersionRoute, getRegisteredProjectsRoute, getConfirmationsRoute, postConfirmationRespondRoute, getHandoffsRoute, getHandoffsStatsRoute, getSpecialistHandoffsRoute, getSpecialistHandoffsStatsRoute, getSkillsRoute, getPlanningStatusRoute, postPlanningMessageRoute, deletePlanningSessionRoute, getTldrStatusRoute, postTldrStartRoute, postTldrStopRoute, getCacheStatusRoute, clearCacheRoute, getMetricsRuntimesRoute, getMetricsTasksRoute, postShadowMonitorRoute, postShadowObserveRoute, postDevRebuildRoute);
|
|
23154
23395
|
//#endregion
|
|
23155
23396
|
//#region routes/conversations.ts
|
|
23156
23397
|
/**
|
|
@@ -23164,6 +23405,7 @@ const miscRouteLayer = Layer.mergeAll(postTrackersRefreshRoute, getProjectMappin
|
|
|
23164
23405
|
*/
|
|
23165
23406
|
init_tmux();
|
|
23166
23407
|
init_config_yaml();
|
|
23408
|
+
init_paths();
|
|
23167
23409
|
const execAsync$1 = promisify(exec);
|
|
23168
23410
|
/**
|
|
23169
23411
|
* Wait for Claude Code to show its input prompt (❯) in the tmux pane.
|
|
@@ -23185,7 +23427,7 @@ async function waitForClaudeReady(tmuxSession) {
|
|
|
23185
23427
|
}
|
|
23186
23428
|
/** Compute the deterministic JSONL session file path from cwd + session UUID. */
|
|
23187
23429
|
function sessionFilePath(cwd, sessionId) {
|
|
23188
|
-
const encodedCwd = cwd
|
|
23430
|
+
const encodedCwd = encodeClaudeProjectDir(cwd);
|
|
23189
23431
|
return join$1(homedir(), ".claude", "projects", encodedCwd, `${sessionId}.jsonl`);
|
|
23190
23432
|
}
|
|
23191
23433
|
const readJsonBody = Effect.gen(function* () {
|
|
@@ -23421,10 +23663,13 @@ const deleteConversationRoute = HttpRouter.add("DELETE", "/api/conversations/:na
|
|
|
23421
23663
|
}));
|
|
23422
23664
|
const postConversationResumeRoute = HttpRouter.add("POST", "/api/conversations/:name/resume", Effect.gen(function* () {
|
|
23423
23665
|
const name = (yield* HttpRouter.params)["name"] ?? "";
|
|
23666
|
+
const body = yield* readJsonBody;
|
|
23424
23667
|
return yield* Effect.promise(async () => {
|
|
23425
23668
|
try {
|
|
23426
23669
|
const conv = getConversationByName(name);
|
|
23427
23670
|
if (!conv) return jsonResponse({ error: "Conversation not found" }, { status: 404 });
|
|
23671
|
+
const model = typeof body["model"] === "string" && body["model"].trim() ? body["model"].trim() : conv.model ?? void 0;
|
|
23672
|
+
const effort = typeof body["effort"] === "string" && body["effort"].trim() ? body["effort"].trim() : conv.effort ?? void 0;
|
|
23428
23673
|
if (await tmuxSessionExists$1(conv.tmuxSession)) {
|
|
23429
23674
|
updateLastAttached(name);
|
|
23430
23675
|
markConversationActive(name);
|
|
@@ -23435,7 +23680,7 @@ const postConversationResumeRoute = HttpRouter.add("POST", "/api/conversations/:
|
|
|
23435
23680
|
});
|
|
23436
23681
|
}
|
|
23437
23682
|
const oldSessionId = conv.sessionFile ? conv.sessionFile.split("/").pop()?.replace(".jsonl", "") ?? void 0 : void 0;
|
|
23438
|
-
spawnConversationSession(conv.tmuxSession, conv.cwd, oldSessionId ?? randomUUID(),
|
|
23683
|
+
spawnConversationSession(conv.tmuxSession, conv.cwd, oldSessionId ?? randomUUID(), model, effort, conv.issueId ?? void 0, !!oldSessionId).catch((err) => {
|
|
23439
23684
|
console.error(`[conversations] Failed to respawn session ${conv.tmuxSession}:`, err);
|
|
23440
23685
|
});
|
|
23441
23686
|
markConversationActive(name);
|
|
@@ -23449,6 +23694,32 @@ const postConversationResumeRoute = HttpRouter.add("POST", "/api/conversations/:
|
|
|
23449
23694
|
}
|
|
23450
23695
|
});
|
|
23451
23696
|
}));
|
|
23697
|
+
const postConversationSwitchModelRoute = HttpRouter.add("POST", "/api/conversations/:name/switch-model", Effect.gen(function* () {
|
|
23698
|
+
const name = (yield* HttpRouter.params)["name"] ?? "";
|
|
23699
|
+
const body = yield* readJsonBody;
|
|
23700
|
+
return yield* Effect.promise(async () => {
|
|
23701
|
+
try {
|
|
23702
|
+
const conv = getConversationByName(name);
|
|
23703
|
+
if (!conv) return jsonResponse({ error: "Conversation not found" }, { status: 404 });
|
|
23704
|
+
const model = typeof body["model"] === "string" && body["model"].trim() ? body["model"].trim() : conv.model ?? void 0;
|
|
23705
|
+
await execAsync$1(`tmux kill-session -t ${conv.tmuxSession} 2>/dev/null || true`, { encoding: "utf-8" });
|
|
23706
|
+
if (model) updateConversationModel(name, model);
|
|
23707
|
+
const oldSessionId = conv.sessionFile ? conv.sessionFile.split("/").pop()?.replace(".jsonl", "") ?? void 0 : void 0;
|
|
23708
|
+
spawnConversationSession(conv.tmuxSession, conv.cwd, oldSessionId ?? randomUUID(), model, conv.effort ?? void 0, conv.issueId ?? void 0, !!oldSessionId).catch((err) => {
|
|
23709
|
+
console.error(`[conversations] Failed to respawn session after model switch ${conv.tmuxSession}:`, err);
|
|
23710
|
+
});
|
|
23711
|
+
markConversationActive(name);
|
|
23712
|
+
return jsonResponse({
|
|
23713
|
+
...conv,
|
|
23714
|
+
status: "active",
|
|
23715
|
+
model,
|
|
23716
|
+
reattached: false
|
|
23717
|
+
});
|
|
23718
|
+
} catch (error) {
|
|
23719
|
+
return jsonResponse({ error: "Failed to switch model: " + (error instanceof Error ? error.message : String(error)) }, { status: 500 });
|
|
23720
|
+
}
|
|
23721
|
+
});
|
|
23722
|
+
}));
|
|
23452
23723
|
const getConversationMessagesRoute = HttpRouter.add("GET", "/api/conversations/:name/messages", Effect.gen(function* () {
|
|
23453
23724
|
const name = (yield* HttpRouter.params)["name"] ?? "";
|
|
23454
23725
|
return yield* Effect.promise(async () => {
|
|
@@ -23586,7 +23857,7 @@ const postConversationRestartAllRoute = HttpRouter.add("POST", "/api/conversatio
|
|
|
23586
23857
|
}
|
|
23587
23858
|
});
|
|
23588
23859
|
}));
|
|
23589
|
-
const conversationsRouteLayer = Layer.mergeAll(getConversationsRoute, postConversationRoute, patchConversationRoute, deleteConversationRoute, postConversationResumeRoute, postConversationRestartAllRoute, postConversationArchiveRoute, getConversationMessagesRoute, postConversationMessageRoute);
|
|
23860
|
+
const conversationsRouteLayer = Layer.mergeAll(getConversationsRoute, postConversationRoute, patchConversationRoute, deleteConversationRoute, postConversationResumeRoute, postConversationSwitchModelRoute, postConversationRestartAllRoute, postConversationArchiveRoute, getConversationMessagesRoute, postConversationMessageRoute);
|
|
23590
23861
|
//#endregion
|
|
23591
23862
|
//#region server.ts
|
|
23592
23863
|
/**
|
|
@@ -23852,19 +24123,24 @@ function stopConversationLifecycleService() {
|
|
|
23852
24123
|
//#endregion
|
|
23853
24124
|
//#region pending-lifecycle.ts
|
|
23854
24125
|
/**
|
|
23855
|
-
* Pending post-merge lifecycle handler (PAN-444).
|
|
24126
|
+
* Pending post-merge lifecycle handler (PAN-444, PAN-520).
|
|
23856
24127
|
*
|
|
23857
24128
|
* After a merge-triggered rebuild+restart, the old server writes a pending file
|
|
23858
|
-
* before dying. The fresh process
|
|
23859
|
-
*
|
|
24129
|
+
* before dying. The fresh process reads the pending file on startup and runs the
|
|
24130
|
+
* lifecycle steps with correct module chunk references (no ERR_MODULE_NOT_FOUND after rebuild).
|
|
24131
|
+
*
|
|
24132
|
+
* Lifecycle events (dashboard.lifecycle_started, _completed, _failed) are emitted
|
|
24133
|
+
* at startup so the ActivityPanel shows restart progress and App.tsx can show
|
|
24134
|
+
* the "restarting" banner.
|
|
23860
24135
|
*/
|
|
23861
24136
|
const PENDING_FILE = join(homedir$1(), ".panopticon", "pending-post-merge.json");
|
|
24137
|
+
const RESTART_MARKER = join(homedir$1(), ".panopticon", "dashboard-restarting.json");
|
|
23862
24138
|
/**
|
|
23863
24139
|
* Default lifecycle runner: dynamically imports merge-agent so the fresh process
|
|
23864
24140
|
* loads new content-hashed chunk filenames (no ERR_MODULE_NOT_FOUND after rebuild).
|
|
23865
24141
|
*/
|
|
23866
24142
|
async function defaultLifecycleRunner(pending) {
|
|
23867
|
-
const { postMergeLifecycle, notifyTldrDaemon } = await import("./merge-agent-
|
|
24143
|
+
const { postMergeLifecycle, notifyTldrDaemon } = await import("./merge-agent-CGN3TT0a.js");
|
|
23868
24144
|
await postMergeLifecycle(pending.issueId, pending.projectPath, pending.sourceBranch, { skipDeploy: true });
|
|
23869
24145
|
if (pending.sourceBranch) await notifyTldrDaemon(pending.projectPath, pending.sourceBranch);
|
|
23870
24146
|
}
|
|
@@ -23872,13 +24148,33 @@ async function defaultLifecycleRunner(pending) {
|
|
|
23872
24148
|
* Check for and process a pending post-merge lifecycle file.
|
|
23873
24149
|
* Reads, validates, deletes the file, then schedules lifecycle execution.
|
|
23874
24150
|
* Safe to call unconditionally on server startup — no-op if file absent.
|
|
24151
|
+
*
|
|
24152
|
+
* Also checks for a RESTART_MARKER file (written by deploy script before killing
|
|
24153
|
+
* the old server) and emits dashboard.lifecycle_started if found.
|
|
23875
24154
|
*/
|
|
23876
24155
|
async function processPendingLifecycle(options) {
|
|
23877
24156
|
const pendingFile = options?.pendingFile ?? PENDING_FILE;
|
|
24157
|
+
const restartMarker = options?.restartMarker ?? RESTART_MARKER;
|
|
23878
24158
|
const staleThresholdMs = options?.staleThresholdMs ?? 36e5;
|
|
23879
24159
|
const lifecycleDelayMs = options?.lifecycleDelayMs ?? 3e3;
|
|
23880
24160
|
const runner = options?._runner ?? defaultLifecycleRunner;
|
|
24161
|
+
if (existsSync(restartMarker)) try {
|
|
24162
|
+
const raw = await readFile$1(restartMarker, "utf-8");
|
|
24163
|
+
const marker = JSON.parse(raw);
|
|
24164
|
+
await unlink$1(restartMarker);
|
|
24165
|
+
if ((options?.now ?? Date.now()) - (marker.timestamp ?? 0) <= staleThresholdMs) {
|
|
24166
|
+
emitDashboardLifecycle("started", {
|
|
24167
|
+
reason: marker.reason ?? "post-merge",
|
|
24168
|
+
issueId: marker.issueId,
|
|
24169
|
+
trigger: marker.trigger ?? "deploy-script"
|
|
24170
|
+
});
|
|
24171
|
+
console.log(`[panopticon] Detected planned restart (${marker.reason}) — lifecycle_started event emitted`);
|
|
24172
|
+
}
|
|
24173
|
+
} catch (err) {
|
|
24174
|
+
console.warn(`[panopticon] Failed to process restart marker: ${err.message}`);
|
|
24175
|
+
}
|
|
23881
24176
|
if (!existsSync(pendingFile)) return;
|
|
24177
|
+
const startTime = Date.now();
|
|
23882
24178
|
try {
|
|
23883
24179
|
const raw = await readFile$1(pendingFile, "utf-8");
|
|
23884
24180
|
await unlink$1(pendingFile);
|
|
@@ -23892,8 +24188,18 @@ async function processPendingLifecycle(options) {
|
|
|
23892
24188
|
setTimeout(async () => {
|
|
23893
24189
|
try {
|
|
23894
24190
|
await runner(pending);
|
|
24191
|
+
emitDashboardLifecycle("completed", {
|
|
24192
|
+
reason: pending.reason ?? "post-merge",
|
|
24193
|
+
issueId: pending.issueId,
|
|
24194
|
+
durationMs: Date.now() - startTime
|
|
24195
|
+
});
|
|
23895
24196
|
} catch (err) {
|
|
23896
24197
|
console.error(`[panopticon] Post-merge lifecycle failed for ${pending.issueId}: ${err.message}`);
|
|
24198
|
+
emitDashboardLifecycle("failed", {
|
|
24199
|
+
reason: pending.reason ?? "post-merge",
|
|
24200
|
+
issueId: pending.issueId,
|
|
24201
|
+
error: err.message
|
|
24202
|
+
});
|
|
23897
24203
|
}
|
|
23898
24204
|
}, lifecycleDelayMs);
|
|
23899
24205
|
} catch (err) {
|