@overdeck/core 0.50.3 → 0.50.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents-DNMRPC8n.js.map +1 -1
- package/dist/{build-info-BJuEVWOh.js → build-info-ioRdOmqT.js} +3 -3
- package/dist/{build-info-BJuEVWOh.js.map → build-info-ioRdOmqT.js.map} +1 -1
- package/dist/build-info-kMMitDOP.js +2 -0
- package/dist/cli/index.js +4 -4
- package/dist/conversation-compaction-GFfO5UZL.js.map +1 -1
- package/dist/dashboard/{advancing-selfheal-Bq8V0QUa.js → advancing-selfheal-Dp5_Gai3.js} +3 -3
- package/dist/dashboard/{advancing-selfheal-Bq8V0QUa.js.map → advancing-selfheal-Dp5_Gai3.js.map} +1 -1
- package/dist/dashboard/{agent-gc-Coz8zQt_.js → agent-gc-JzoSs5Pi.js} +3 -3
- package/dist/dashboard/{agent-gc-Coz8zQt_.js.map → agent-gc-JzoSs5Pi.js.map} +1 -1
- package/dist/dashboard/{agent-idle-CAwB-K6M.js → agent-idle-D-Qy5BN_.js} +2 -2
- package/dist/dashboard/{agent-idle-CAwB-K6M.js.map → agent-idle-D-Qy5BN_.js.map} +1 -1
- package/dist/dashboard/{agent-state-Ci6PhjOE.js → agent-state-B196fj1h.js} +38 -16
- package/dist/dashboard/agent-state-B196fj1h.js.map +1 -0
- package/dist/dashboard/{agent-state-CbUEwUEQ.js → agent-state-IpWnw8lv.js} +1 -1
- package/dist/dashboard/{agent-state-service-D6IVrX3B.js → agent-state-service-CCo5-9DR.js} +3 -3
- package/dist/dashboard/{agent-state-service-D6IVrX3B.js.map → agent-state-service-CCo5-9DR.js.map} +1 -1
- package/dist/dashboard/{agent-state-service-DcN1j6eK.js → agent-state-service-D_F3VZ23.js} +1 -1
- package/dist/dashboard/{agents-BVvL4o_4.js → agents-CkGhnAmu.js} +1 -1
- package/dist/dashboard/{backlog-auto-trigger-BuSBqG2V.js → backlog-auto-trigger-B5Z2zBtC.js} +2 -2
- package/dist/dashboard/{backlog-auto-trigger-BuSBqG2V.js.map → backlog-auto-trigger-B5Z2zBtC.js.map} +1 -1
- package/dist/dashboard/build-info-BTjOB0Xr.js +2 -0
- package/dist/dashboard/{build-info-Cj3Y0K87.js → build-info-D0EJNj6C.js} +3 -3
- package/dist/dashboard/{build-info-Cj3Y0K87.js.map → build-info-D0EJNj6C.js.map} +1 -1
- package/dist/dashboard/cli-CIznFrcE.js +2 -0
- package/dist/dashboard/{cli-DIhQieif.js → cli-DCbVrSsg.js} +2 -2
- package/dist/dashboard/{cli-DIhQieif.js.map → cli-DCbVrSsg.js.map} +1 -1
- package/dist/dashboard/{close-issue-CRlmrE5g.js → close-issue-Bmu9aOIx.js} +2 -2
- package/dist/dashboard/{close-issue-CRlmrE5g.js.map → close-issue-Bmu9aOIx.js.map} +1 -1
- package/dist/dashboard/{closed-issue-reaper-DrHyYgJR.js → closed-issue-reaper-COxfTtLz.js} +5 -5
- package/dist/dashboard/{closed-issue-reaper-DrHyYgJR.js.map → closed-issue-reaper-COxfTtLz.js.map} +1 -1
- package/dist/dashboard/{closed-issue-reaper-DWlw2EtL.js → closed-issue-reaper-DwMwG_Pz.js} +1 -1
- package/dist/dashboard/{compaction-continuation-DhYgsXmF.js → compaction-continuation-Bqc212Zm.js} +2 -2
- package/dist/dashboard/{compaction-continuation-DhYgsXmF.js.map → compaction-continuation-Bqc212Zm.js.map} +1 -1
- package/dist/dashboard/{conflict-gate-vczgdVTa.js → conflict-gate-9mPVg7-5.js} +1 -1
- package/dist/dashboard/{conflict-gate-Bt-lLgYf.js → conflict-gate-CGQTcR0I.js} +3 -3
- package/dist/dashboard/{conflict-gate-Bt-lLgYf.js.map → conflict-gate-CGQTcR0I.js.map} +1 -1
- package/dist/dashboard/{conversation-compaction-CsdCbcQB.js → conversation-compaction-C7P6V8Iw.js} +5 -5
- package/dist/dashboard/{conversation-compaction-CsdCbcQB.js.map → conversation-compaction-C7P6V8Iw.js.map} +1 -1
- package/dist/dashboard/{conversation-compaction-D0zgWM1f.js → conversation-compaction-Cck5oi-V.js} +1 -1
- package/dist/dashboard/{conversation-service-6LaymUV-.js → conversation-service-CsOpwI9Y.js} +37 -5
- package/dist/dashboard/{conversation-service-6LaymUV-.js.map → conversation-service-CsOpwI9Y.js.map} +1 -1
- package/dist/dashboard/conversation-service-plOFkoMo.js +3 -0
- package/dist/dashboard/dashboard-db-worker.js +1 -1
- package/dist/dashboard/{deacon-CU47dU7U.js → deacon-B8oMMIgN.js} +62 -62
- package/dist/dashboard/{deacon-CU47dU7U.js.map → deacon-B8oMMIgN.js.map} +1 -1
- package/dist/dashboard/{deacon-DYsOa_ss.js → deacon-b7J57Svt.js} +2 -2
- package/dist/dashboard/{deacon-pending-lifecycle-ijGX8wLb.js → deacon-pending-lifecycle-3NIJ7ew5.js} +2 -2
- package/dist/dashboard/{deacon-pending-lifecycle-ijGX8wLb.js.map → deacon-pending-lifecycle-3NIJ7ew5.js.map} +1 -1
- package/dist/dashboard/deacon.js +5 -5
- package/dist/dashboard/{delivery-DMYxIE0J.js → delivery-lnI-gQKo.js} +1 -1
- package/dist/dashboard/{deploy-patrol-C4eXco1S.js → deploy-patrol-u3v2krg9.js} +2 -2
- package/dist/dashboard/{deploy-patrol-C4eXco1S.js.map → deploy-patrol-u3v2krg9.js.map} +1 -1
- package/dist/dashboard/{feedback-stuck-retirement-Dd5XNrMr.js → feedback-stuck-retirement-CoFNqjCc.js} +2 -2
- package/dist/dashboard/{feedback-stuck-retirement-Dd5XNrMr.js.map → feedback-stuck-retirement-CoFNqjCc.js.map} +1 -1
- package/dist/dashboard/{feedback-target-BzdJ2wIR.js → feedback-target-BBCh3RRq.js} +1 -1
- package/dist/dashboard/{feedback-target-BcsA_GRV.js → feedback-target-CeCq6EhW.js} +5 -5
- package/dist/dashboard/{feedback-target-BcsA_GRV.js.map → feedback-target-CeCq6EhW.js.map} +1 -1
- package/dist/dashboard/{flywheel-Is3w2lcT.js → flywheel-DKldI63J.js} +7 -7
- package/dist/dashboard/{flywheel-Is3w2lcT.js.map → flywheel-DKldI63J.js.map} +1 -1
- package/dist/dashboard/{flywheel-D0guNqkh.js → flywheel-DpRPLErh.js} +7 -7
- package/dist/dashboard/{flywheel-D0guNqkh.js.map → flywheel-DpRPLErh.js.map} +1 -1
- package/dist/dashboard/{flywheel-B34cdfbd.js → flywheel-jeZFYvm-.js} +1 -1
- package/dist/dashboard/{flywheel-merge-order-6HiPR2WG.js → flywheel-merge-order-0OnoosaO.js} +1 -1
- package/dist/dashboard/{flywheel-merge-order-BsNPMu0S.js → flywheel-merge-order-PG5op4j7.js} +2 -2
- package/dist/dashboard/{flywheel-merge-order-BsNPMu0S.js.map → flywheel-merge-order-PG5op4j7.js.map} +1 -1
- package/dist/dashboard/{harness-resolve-CzTFVZ5l.js → harness-resolve-C0HWj3H9.js} +2 -2
- package/dist/dashboard/{harness-resolve-CzTFVZ5l.js.map → harness-resolve-C0HWj3H9.js.map} +1 -1
- package/dist/dashboard/{identity-Dc7rQLln.js → identity-Cot1Hg4G.js} +2 -2
- package/dist/dashboard/{identity-Dc7rQLln.js.map → identity-Cot1Hg4G.js.map} +1 -1
- package/dist/dashboard/{inspect-agent-CP7Bu47O.js → inspect-agent-BDmLWbGx.js} +3 -3
- package/dist/dashboard/{inspect-agent-CP7Bu47O.js.map → inspect-agent-BDmLWbGx.js.map} +1 -1
- package/dist/dashboard/inspect-agent-BcOkA-hC.js +2 -0
- package/dist/dashboard/{issue-lifecycle-BPbczKyy.js → issue-lifecycle-1B_v8Rf5.js} +6 -6
- package/dist/dashboard/{issue-lifecycle-BPbczKyy.js.map → issue-lifecycle-1B_v8Rf5.js.map} +1 -1
- package/dist/dashboard/{issue-lifecycle-FaugTi39.js → issue-lifecycle-CIrfbIbj.js} +1 -1
- package/dist/dashboard/{issue-service-singleton-Dsad9NTt.js → issue-service-singleton-BVwPzjwF.js} +1 -1
- package/dist/dashboard/{issue-service-singleton-BrZQJLRI.js → issue-service-singleton-KcRrOiFD.js} +2 -2
- package/dist/dashboard/{issue-service-singleton-BrZQJLRI.js.map → issue-service-singleton-KcRrOiFD.js.map} +1 -1
- package/dist/dashboard/{jsonl-resolver-DQEe0DHM.js → jsonl-resolver-jxbif7MD.js} +3 -3
- package/dist/dashboard/{jsonl-resolver-DQEe0DHM.js.map → jsonl-resolver-jxbif7MD.js.map} +1 -1
- package/dist/dashboard/{kimi-code-Cx5YUJpS.js → kimi-code-BZh3NgcN.js} +1 -1
- package/dist/dashboard/{lifecycle-DZFHmpGI.js → lifecycle-CvcZ4_fA.js} +4 -4
- package/dist/dashboard/{lifecycle-DZFHmpGI.js.map → lifecycle-CvcZ4_fA.js.map} +1 -1
- package/dist/dashboard/{linear-mcp-auth-DylPJABZ.js → linear-mcp-auth-CZoj_-d7.js} +1 -1
- package/dist/dashboard/{linear-mcp-auth-BFlpMvWh.js → linear-mcp-auth-Dx74yCAY.js} +2 -2
- package/dist/dashboard/{linear-mcp-auth-BFlpMvWh.js.map → linear-mcp-auth-Dx74yCAY.js.map} +1 -1
- package/dist/dashboard/{memory-governor-B7uDWRo9.js → memory-governor-Bv3LAqk3.js} +5 -5
- package/dist/dashboard/{memory-governor-B7uDWRo9.js.map → memory-governor-Bv3LAqk3.js.map} +1 -1
- package/dist/dashboard/{merge-agent-ddEcZDZD.js → merge-agent-1zVLl6k_.js} +1 -1
- package/dist/dashboard/{merge-agent-ttRY053V.js → merge-agent-8zrQu48t.js} +8 -8
- package/dist/dashboard/{merge-agent-ttRY053V.js.map → merge-agent-8zrQu48t.js.map} +1 -1
- package/dist/dashboard/merge-ops-CFJaMPLu.js +2 -0
- package/dist/dashboard/{merge-train-f_un38UJ.js → merge-train-BYH_cF7G.js} +2 -2
- package/dist/dashboard/{merge-train-f_un38UJ.js.map → merge-train-BYH_cF7G.js.map} +1 -1
- package/dist/dashboard/{merge-train-deps-GPlHOjK6.js → merge-train-deps-BTfXM5AR.js} +2 -2
- package/dist/dashboard/{merge-train-deps-GPlHOjK6.js.map → merge-train-deps-BTfXM5AR.js.map} +1 -1
- package/dist/dashboard/{messaging-BasbftDu.js → messaging-Bk6vGsMw.js} +1 -1
- package/dist/dashboard/{orphan-proposed-reconciler-DFHdQSEg.js → orphan-proposed-reconciler-B898fk26.js} +6 -6
- package/dist/dashboard/{orphan-proposed-reconciler-DFHdQSEg.js.map → orphan-proposed-reconciler-B898fk26.js.map} +1 -1
- package/dist/dashboard/{orphan-proposed-reconciler-DzAxrM99.js → orphan-proposed-reconciler-Bx_aWS4B.js} +1 -1
- package/dist/dashboard/{parked-residue-DMtbxJml.js → parked-residue-q2kzrYSm.js} +9 -9
- package/dist/dashboard/{parked-residue-DMtbxJml.js.map → parked-residue-q2kzrYSm.js.map} +1 -1
- package/dist/dashboard/{post-merge-lifecycle-worker-jzN2g_EY.js → post-merge-lifecycle-worker-Cl7-uf4g.js} +2 -2
- package/dist/dashboard/{post-merge-lifecycle-worker-jzN2g_EY.js.map → post-merge-lifecycle-worker-Cl7-uf4g.js.map} +1 -1
- package/dist/dashboard/{project-resource-refresh-queue-cqOeJ0fB.js → project-resource-refresh-queue-O_dRfPHn.js} +1 -1
- package/dist/dashboard/{project-resource-refresh-queue-DebwjPPA.js → project-resource-refresh-queue-se3T9IYP.js} +4 -4
- package/dist/dashboard/{project-resource-refresh-queue-DebwjPPA.js.map → project-resource-refresh-queue-se3T9IYP.js.map} +1 -1
- package/dist/dashboard/{reconstruct-cache-Bb2Jg2DZ.js → reconstruct-cache-XpWC9L0F.js} +2 -2
- package/dist/dashboard/{reconstruct-cache-Bb2Jg2DZ.js.map → reconstruct-cache-XpWC9L0F.js.map} +1 -1
- package/dist/dashboard/{release-engine-78iCajIc.js → release-engine-BuzxOamf.js} +2 -2
- package/dist/dashboard/{release-engine-78iCajIc.js.map → release-engine-BuzxOamf.js.map} +1 -1
- package/dist/dashboard/{remote-completion-D5wzZCte.js → remote-completion-BCZgeKPS.js} +3 -3
- package/dist/dashboard/{remote-completion-D5wzZCte.js.map → remote-completion-BCZgeKPS.js.map} +1 -1
- package/dist/dashboard/{resolver-BGZh3lXA.js → resolver-BeNrqNou.js} +5 -5
- package/dist/dashboard/{resolver-BGZh3lXA.js.map → resolver-BeNrqNou.js.map} +1 -1
- package/dist/dashboard/{resource-pressure-patrol-Bg23rPV-.js → resource-pressure-patrol-Ccg_aCgO.js} +3 -3
- package/dist/dashboard/{resource-pressure-patrol-Bg23rPV-.js.map → resource-pressure-patrol-Ccg_aCgO.js.map} +1 -1
- package/dist/dashboard/{resume-BKyB4hA1.js → resume-KGCrn0DV.js} +1 -1
- package/dist/dashboard/{review-agent-ZdP-HmwY.js → review-agent-BmM6YMZW.js} +1 -1
- package/dist/dashboard/{review-agent-DHs-JngN.js → review-agent-DRWVU8fP.js} +13 -13
- package/dist/dashboard/{review-agent-DHs-JngN.js.map → review-agent-DRWVU8fP.js.map} +1 -1
- package/dist/dashboard/{review-convoy-liveness-BTMvU4CA.js → review-convoy-liveness-EvCDv8Q_.js} +3 -3
- package/dist/dashboard/{review-convoy-liveness-BTMvU4CA.js.map → review-convoy-liveness-EvCDv8Q_.js.map} +1 -1
- package/dist/dashboard/{review-run-recovery-BYalQzbh.js → review-run-recovery-Ctm48Snt.js} +1 -1
- package/dist/dashboard/{review-run-recovery-BvVG3oUr.js → review-run-recovery-DNDI58cM.js} +2 -2
- package/dist/dashboard/{review-run-recovery-BvVG3oUr.js.map → review-run-recovery-DNDI58cM.js.map} +1 -1
- package/dist/dashboard/{review-status-DXTFzCmR.js → review-status-FnlvQuPI.js} +1 -1
- package/dist/dashboard/{review-status-emit-C9YW6SQL.js → review-status-emit-CeMS31DX.js} +2 -2
- package/dist/dashboard/{review-status-emit-C9YW6SQL.js.map → review-status-emit-CeMS31DX.js.map} +1 -1
- package/dist/dashboard/{review-status-BegAr86G.js → review-status-yY5qt7Rl.js} +5 -5
- package/dist/dashboard/{review-status-BegAr86G.js.map → review-status-yY5qt7Rl.js.map} +1 -1
- package/dist/dashboard/{review-verdict-feedback-qlVBi19-.js → review-verdict-feedback-BNgRj1e3.js} +4 -4
- package/dist/dashboard/{review-verdict-feedback-qlVBi19-.js.map → review-verdict-feedback-BNgRj1e3.js.map} +1 -1
- package/dist/dashboard/{review-verdict-feedback-Dp139Lmv.js → review-verdict-feedback-D39cuSV1.js} +1 -1
- package/dist/dashboard/{review-verdict-writer-CJr_Ob0Y.js → review-verdict-writer-DvFfKAn-.js} +2 -2
- package/dist/dashboard/{review-verdict-writer-CJr_Ob0Y.js.map → review-verdict-writer-DvFfKAn-.js.map} +1 -1
- package/dist/dashboard/{review-verdict-writer-BVco3WoI.js → review-verdict-writer-PcGBkvJ4.js} +1 -1
- package/dist/dashboard/{sequence-io-iljWlslY.js → sequence-io-DZyschsf.js} +2 -2
- package/dist/dashboard/{sequence-io-iljWlslY.js.map → sequence-io-DZyschsf.js.map} +1 -1
- package/dist/dashboard/{sequencer-agent-BGGVKxtw.js → sequencer-agent-BXDw5cNx.js} +5 -5
- package/dist/dashboard/{sequencer-agent-BGGVKxtw.js.map → sequencer-agent-BXDw5cNx.js.map} +1 -1
- package/dist/dashboard/server.js +79 -72
- package/dist/dashboard/server.js.map +1 -1
- package/dist/dashboard/{service-kzhN0DLg.js → service-DP50Omvn.js} +33 -33
- package/dist/dashboard/{service-kzhN0DLg.js.map → service-DP50Omvn.js.map} +1 -1
- package/dist/dashboard/{smart-compaction-owKHJDbL.js → smart-compaction-944GL8PN.js} +1 -1
- package/dist/dashboard/{smart-compaction-C96F2aFQ.js → smart-compaction-BzDfF6yb.js} +2 -2
- package/dist/dashboard/{smart-compaction-C96F2aFQ.js.map → smart-compaction-BzDfF6yb.js.map} +1 -1
- package/dist/dashboard/{spawn-planning-session-CiJdOHTD.js → spawn-planning-session-BcVnHJjm.js} +1 -1
- package/dist/dashboard/{spawn-planning-session-FmJa6PCS.js → spawn-planning-session-CH8IYli7.js} +3 -3
- package/dist/dashboard/{spawn-planning-session-FmJa6PCS.js.map → spawn-planning-session-CH8IYli7.js.map} +1 -1
- package/dist/dashboard/{specialist-context-_ootmzn2.js → specialist-context-DhDTXVht.js} +3 -3
- package/dist/dashboard/{specialist-context-_ootmzn2.js.map → specialist-context-DhDTXVht.js.map} +1 -1
- package/dist/dashboard/{specialist-logs-BbAX221-.js → specialist-logs-C1bcnZ-G.js} +2 -2
- package/dist/dashboard/{specialist-logs-BbAX221-.js.map → specialist-logs-C1bcnZ-G.js.map} +1 -1
- package/dist/dashboard/{specialists-COZoYaiz.js → specialists-BKmReEWT.js} +53 -53
- package/dist/dashboard/{specialists-COZoYaiz.js.map → specialists-BKmReEWT.js.map} +1 -1
- package/dist/dashboard/{specialists-RPLJnYc1.js → specialists-Bvrvt0br.js} +12 -12
- package/dist/dashboard/{specialists-RPLJnYc1.js.map → specialists-Bvrvt0br.js.map} +1 -1
- package/dist/dashboard/{specialists-DTAOVZpU.js → specialists-CD6GEKXk.js} +1 -1
- package/dist/dashboard/{specialists-D8sYZnPb.js → specialists-eFWpJRBc.js} +1 -1
- package/dist/dashboard/{stall-sweeper-9bRBZhrQ.js → stall-sweeper-D3fZvg7O.js} +3 -3
- package/dist/dashboard/{stall-sweeper-9bRBZhrQ.js.map → stall-sweeper-D3fZvg7O.js.map} +1 -1
- package/dist/dashboard/{state-migrate-J3tFJnbd.js → state-migrate-KZ2goscQ.js} +2 -2
- package/dist/dashboard/{state-migrate-J3tFJnbd.js.map → state-migrate-KZ2goscQ.js.map} +1 -1
- package/dist/dashboard/{stuck-remediation-BvTK_NYN.js → stuck-remediation-Cb2V1roj.js} +1 -1
- package/dist/dashboard/{stuck-remediation-4Rf_xMEb.js → stuck-remediation-CnoV0kcv.js} +5 -5
- package/dist/dashboard/{stuck-remediation-4Rf_xMEb.js.map → stuck-remediation-CnoV0kcv.js.map} +1 -1
- package/dist/dashboard/{summary-fork-PLcckTRE.js → summary-fork-CxuNBM0F.js} +2 -2
- package/dist/dashboard/{summary-fork-D-cylknJ.js → summary-fork-lC2vMXly.js} +4 -4
- package/dist/dashboard/{summary-fork-D-cylknJ.js.map → summary-fork-lC2vMXly.js.map} +1 -1
- package/dist/dashboard/{teardown-workspace-CTL16rnG.js → teardown-workspace-C-9murBw.js} +4 -4
- package/dist/dashboard/{teardown-workspace-CTL16rnG.js.map → teardown-workspace-C-9murBw.js.map} +1 -1
- package/dist/dashboard/{test-agent-queue-CMgYZiR_.js → test-agent-queue-YCBRzaAB.js} +3 -3
- package/dist/dashboard/{test-agent-queue-CMgYZiR_.js.map → test-agent-queue-YCBRzaAB.js.map} +1 -1
- package/dist/dashboard/{uat-failure-feedback-DS6W9X3I.js → uat-failure-feedback-B-1mL8Zp.js} +3 -3
- package/dist/dashboard/{uat-failure-feedback-DS6W9X3I.js.map → uat-failure-feedback-B-1mL8Zp.js.map} +1 -1
- package/dist/dashboard/{uat-promote-verification-CRsIHE_q.js → uat-promote-verification-BEBPcpPg.js} +2 -2
- package/dist/dashboard/{uat-promote-verification-CRsIHE_q.js.map → uat-promote-verification-BEBPcpPg.js.map} +1 -1
- package/dist/dashboard/{uat-train-BoA9r6_I.js → uat-train-BFo3OQUB.js} +1 -1
- package/dist/dashboard/{uat-train-Cd8CJeNe.js → uat-train-COgoJomz.js} +8 -8
- package/dist/dashboard/{uat-train-Cd8CJeNe.js.map → uat-train-COgoJomz.js.map} +1 -1
- package/dist/dashboard/{validate-BdmvTIym.js → validate-069_N1e2.js} +2 -2
- package/dist/dashboard/{validate-BdmvTIym.js.map → validate-069_N1e2.js.map} +1 -1
- package/dist/dashboard/{verification-runner-BO0K3xNA.js → verification-runner-CQnZyC5A.js} +1 -1
- package/dist/dashboard/{verification-runner-fEY1Qj-l.js → verification-runner-fy3wNrWn.js} +4 -4
- package/dist/dashboard/{verification-runner-fEY1Qj-l.js.map → verification-runner-fy3wNrWn.js.map} +1 -1
- package/dist/dashboard/workflows-Bk6Kt0ZQ.js +2 -0
- package/dist/dashboard/{workflows-CxVnygYU.js → workflows-N4QMkDzN.js} +10 -10
- package/dist/dashboard/{workflows-CxVnygYU.js.map → workflows-N4QMkDzN.js.map} +1 -1
- package/dist/dashboard/{workspaces-Cpz0xJWQ.js → workspaces-DmoyfHoU.js} +33 -33
- package/dist/dashboard/{workspaces-Cpz0xJWQ.js.map → workspaces-DmoyfHoU.js.map} +1 -1
- package/dist/{lifecycle-C6k0HWEO.js → lifecycle-DCFcjg7y.js} +1 -1
- package/dist/{lifecycle-D5oRpvvB.js → lifecycle-GkaHQJNK.js} +2 -2
- package/dist/{lifecycle-D5oRpvvB.js.map → lifecycle-GkaHQJNK.js.map} +1 -1
- package/dist/{merge-agent-Drufc7tU.js → merge-agent-CogNFasY.js} +2 -2
- package/dist/{merge-agent-Drufc7tU.js.map → merge-agent-CogNFasY.js.map} +1 -1
- package/dist/{merge-agent-CBOVY_eC.js → merge-agent-eteKQ9Rb.js} +1 -1
- package/package.json +1 -1
- package/dist/build-info-BgrwLUy6.js +0 -2
- package/dist/dashboard/agent-state-Ci6PhjOE.js.map +0 -1
- package/dist/dashboard/build-info-CYlxvZSQ.js +0 -2
- package/dist/dashboard/cli-ZAS502uC.js +0 -2
- package/dist/dashboard/conversation-service-Dlks_hSS.js +0 -3
- package/dist/dashboard/inspect-agent-DTuSg95i.js +0 -2
- package/dist/dashboard/merge-ops-Bgc-EScO.js +0 -2
- package/dist/dashboard/workflows-CgGNyl1z.js +0 -2
package/dist/dashboard/{advancing-selfheal-Bq8V0QUa.js.map → advancing-selfheal-Dp5_Gai3.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"advancing-selfheal-Bq8V0QUa.js","names":["agents.getAgentStateSync","agents.saveAgentStateSync","agents.markAgentStoppedState"],"sources":["../../src/lib/cloister/advancing-selfheal.ts"],"sourcesContent":["import { Effect } from 'effect';\nimport * as agents from '../agents.js';\nimport type { AgentState } from '../agents.js';\nimport { logDeaconEventSync } from '../persistent-logger.js';\nimport {\n getReviewStatusSync,\n loadReviewStatuses,\n type ReviewStatus,\n} from '../review-status.js';\nimport { killSession, listSessionNames } from '../tmux.js';\nimport { selectMergedAdvancingSessions } from './reap-terminal-sessions.js';\n\nconst JOURNAL_RECONCILE_STATES = new Set([\n 'pending',\n 'reviewing',\n 'passed',\n 'failed',\n 'blocked',\n 'testing',\n 'skipped',\n 'dispatch_failed',\n]);\n\nexport interface AdvancingSelfHealDeps {\n loadReviewStatuses(): Record<string, ReviewStatus>;\n getReviewStatusSync(issueId: string): ReviewStatus | null;\n listSessionNames(): Promise<readonly string[]>;\n getAgentStateSync(session: string): AgentState | null;\n saveAgentStateSync(state: AgentState): void;\n markAgentStoppedState(state: AgentState): AgentState;\n warn(message: string): void;\n}\n\nconst defaultDeps: AdvancingSelfHealDeps = {\n loadReviewStatuses,\n getReviewStatusSync,\n listSessionNames: () => Effect.runPromise(listSessionNames()),\n getAgentStateSync: (session) => agents.getAgentStateSync(session),\n saveAgentStateSync: (state) => agents.saveAgentStateSync(state),\n markAgentStoppedState: (state) => agents.markAgentStoppedState(state),\n warn: (message) => console.warn(message),\n};\n\nfunction isReconciliableStatus(status: ReviewStatus): boolean {\n if (status.mergeStatus === 'merged') return false;\n return JOURNAL_RECONCILE_STATES.has(status.reviewStatus)\n && JOURNAL_RECONCILE_STATES.has(status.testStatus);\n}\n\nexport function parseAdvancingIssueId(sessionName: string): string | null {\n const match = sessionName.match(/^agent-([a-z0-9]+-\\d+)-(?:review|test|ship)(?:-.+)?$/i);\n return match ? match[1].toUpperCase() : null;\n}\n\nfunction statusChanged(before: ReviewStatus | null | undefined, after: ReviewStatus | null): boolean {\n return JSON.stringify(before ?? null) !== JSON.stringify(after ?? null);\n}\n\nfunction hasFailingChecks(status: ReviewStatus | null | undefined): boolean {\n return status?.blockerReasons?.some((blocker) => blocker.type === 'failing_checks') ?? false;\n}\n\n/**\n * Host-side sweep for journaled review/test verdicts whose HTTP status POST\n * failed. getReviewStatusSync owns the journal -> DB reconcile; this patrol\n * step makes sure in-flight and tmux-alive advancing issues are read by the\n * host even when the agent has gone idle.\n */\nexport async function reconcileInFlightJournals(\n deps: AdvancingSelfHealDeps = defaultDeps,\n): Promise<string[]> {\n const actions: string[] = [];\n const statuses = deps.loadReviewStatuses();\n const issueIds = new Set<string>();\n\n for (const [issueId, status] of Object.entries(statuses)) {\n if (!isReconciliableStatus(status)) continue;\n issueIds.add(issueId.toUpperCase());\n }\n\n let sessionNames: readonly string[] = [];\n try {\n sessionNames = await deps.listSessionNames();\n } catch (error) {\n deps.warn(`[deacon] reconcileInFlightJournals: failed to list tmux sessions: ${error instanceof Error ? error.message : String(error)}`);\n }\n\n for (const sessionName of sessionNames) {\n const issueId = parseAdvancingIssueId(sessionName);\n if (!issueId) continue;\n const status = statuses[issueId];\n if (status && !isReconciliableStatus(status)) continue;\n issueIds.add(issueId);\n }\n\n for (const issueId of issueIds) {\n const before = statuses[issueId] ?? null;\n try {\n const after = deps.getReviewStatusSync(issueId);\n if (!statusChanged(before, after)) continue;\n // A required-check failure is actionable blocker state, not advancing\n // pipeline progress. Keep reconciling the journal through the read door,\n // but do not emit a repeated no-op advancement action while CI is red.\n if (hasFailingChecks(after)) continue;\n actions.push(`Reconciled journaled advancing verdict for ${issueId}`);\n } catch (error) {\n deps.warn(`[deacon] reconcileInFlightJournals: failed to reconcile ${issueId}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n return actions;\n}\n\nexport function markAdvancingSessionStopped(\n session: string,\n deps: Pick<AdvancingSelfHealDeps, 'getAgentStateSync' | 'saveAgentStateSync' | 'markAgentStoppedState'> = defaultDeps,\n): boolean {\n const state = deps.getAgentStateSync(session);\n if (!state || state.status === 'stopped') return false;\n\n const stopped = deps.markAgentStoppedState(state);\n deps.saveAgentStateSync(stopped);\n return true;\n}\n\n/**\n * PAN-2341: Reap advancing-role sessions for already-merged issues.\n *\n * The warm-by-default lifecycle (PAN-2579) intentionally leaves review/test/ship\n * panes alive, but once the issue is MERGED those sessions have no remaining role\n * in the pipeline (close-out territory). Kill the tmux session and\n * mark the agents-table row stopped so countRunningAgents() frees the slot.\n */\nexport async function checkMergedAdvancingSessions(): Promise<string[]> {\n const actions: string[] = [];\n try {\n const statuses = loadReviewStatuses();\n const aliveSessions = await Effect.runPromise(listSessionNames());\n const toKill = selectMergedAdvancingSessions(statuses, [...aliveSessions]);\n\n for (const session of toKill) {\n try {\n await Effect.runPromise(killSession(session));\n } catch (err) {\n console.warn(`[deacon] Failed to reap merged advancing session ${session}: ${err instanceof Error ? err.message : String(err)}`);\n }\n const markedStopped = markAdvancingSessionStopped(session);\n actions.push(\n markedStopped\n ? `Reaped merged advancing session ${session} (issue merged, row stopped)`\n : `Reaped merged advancing session ${session} (issue merged)`,\n );\n console.log(`[deacon] Reaped merged advancing session ${session} (PAN-2341)`);\n logDeaconEventSync(`checkMergedAdvancingSessions: reaped ${session} — issue merged but advancing session alive (PAN-2341)`);\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error('[deacon] Error reaping merged advancing sessions:', msg);\n }\n return actions;\n}\n\nexport interface BootAdvancingSelfHealDeps {\n reconcileInFlightJournals(): Promise<string[]>;\n checkMergedAdvancingSessions(): Promise<string[]>;\n log(message: string): void;\n}\n\nconst defaultBootAdvancingSelfHealDeps: BootAdvancingSelfHealDeps = {\n reconcileInFlightJournals,\n checkMergedAdvancingSessions,\n log: logDeaconEventSync,\n};\n\nexport async function runBootAdvancingSelfHeal(\n deps: BootAdvancingSelfHealDeps = defaultBootAdvancingSelfHealDeps,\n): Promise<string[]> {\n const actions: string[] = [];\n const steps: Array<[string, () => Promise<string[]>]> = [\n ['reconcileInFlightJournals', deps.reconcileInFlightJournals],\n ['checkMergedAdvancingSessions', deps.checkMergedAdvancingSessions],\n ];\n\n for (const [name, step] of steps) {\n try {\n const stepActions = await step();\n actions.push(...stepActions);\n if (stepActions.length > 0) {\n deps.log(`startDeacon: ${name} boot self-heal actions: ${stepActions.join('; ')}`);\n }\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n deps.log(`startDeacon: ${name} boot self-heal failed: ${msg}`);\n }\n }\n\n return actions;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"advancing-selfheal-Dp5_Gai3.js","names":["agents.getAgentStateSync","agents.saveAgentStateSync","agents.markAgentStoppedState"],"sources":["../../src/lib/cloister/advancing-selfheal.ts"],"sourcesContent":["import { Effect } from 'effect';\nimport * as agents from '../agents.js';\nimport type { AgentState } from '../agents.js';\nimport { logDeaconEventSync } from '../persistent-logger.js';\nimport {\n getReviewStatusSync,\n loadReviewStatuses,\n type ReviewStatus,\n} from '../review-status.js';\nimport { killSession, listSessionNames } from '../tmux.js';\nimport { selectMergedAdvancingSessions } from './reap-terminal-sessions.js';\n\nconst JOURNAL_RECONCILE_STATES = new Set([\n 'pending',\n 'reviewing',\n 'passed',\n 'failed',\n 'blocked',\n 'testing',\n 'skipped',\n 'dispatch_failed',\n]);\n\nexport interface AdvancingSelfHealDeps {\n loadReviewStatuses(): Record<string, ReviewStatus>;\n getReviewStatusSync(issueId: string): ReviewStatus | null;\n listSessionNames(): Promise<readonly string[]>;\n getAgentStateSync(session: string): AgentState | null;\n saveAgentStateSync(state: AgentState): void;\n markAgentStoppedState(state: AgentState): AgentState;\n warn(message: string): void;\n}\n\nconst defaultDeps: AdvancingSelfHealDeps = {\n loadReviewStatuses,\n getReviewStatusSync,\n listSessionNames: () => Effect.runPromise(listSessionNames()),\n getAgentStateSync: (session) => agents.getAgentStateSync(session),\n saveAgentStateSync: (state) => agents.saveAgentStateSync(state),\n markAgentStoppedState: (state) => agents.markAgentStoppedState(state),\n warn: (message) => console.warn(message),\n};\n\nfunction isReconciliableStatus(status: ReviewStatus): boolean {\n if (status.mergeStatus === 'merged') return false;\n return JOURNAL_RECONCILE_STATES.has(status.reviewStatus)\n && JOURNAL_RECONCILE_STATES.has(status.testStatus);\n}\n\nexport function parseAdvancingIssueId(sessionName: string): string | null {\n const match = sessionName.match(/^agent-([a-z0-9]+-\\d+)-(?:review|test|ship)(?:-.+)?$/i);\n return match ? match[1].toUpperCase() : null;\n}\n\nfunction statusChanged(before: ReviewStatus | null | undefined, after: ReviewStatus | null): boolean {\n return JSON.stringify(before ?? null) !== JSON.stringify(after ?? null);\n}\n\nfunction hasFailingChecks(status: ReviewStatus | null | undefined): boolean {\n return status?.blockerReasons?.some((blocker) => blocker.type === 'failing_checks') ?? false;\n}\n\n/**\n * Host-side sweep for journaled review/test verdicts whose HTTP status POST\n * failed. getReviewStatusSync owns the journal -> DB reconcile; this patrol\n * step makes sure in-flight and tmux-alive advancing issues are read by the\n * host even when the agent has gone idle.\n */\nexport async function reconcileInFlightJournals(\n deps: AdvancingSelfHealDeps = defaultDeps,\n): Promise<string[]> {\n const actions: string[] = [];\n const statuses = deps.loadReviewStatuses();\n const issueIds = new Set<string>();\n\n for (const [issueId, status] of Object.entries(statuses)) {\n if (!isReconciliableStatus(status)) continue;\n issueIds.add(issueId.toUpperCase());\n }\n\n let sessionNames: readonly string[] = [];\n try {\n sessionNames = await deps.listSessionNames();\n } catch (error) {\n deps.warn(`[deacon] reconcileInFlightJournals: failed to list tmux sessions: ${error instanceof Error ? error.message : String(error)}`);\n }\n\n for (const sessionName of sessionNames) {\n const issueId = parseAdvancingIssueId(sessionName);\n if (!issueId) continue;\n const status = statuses[issueId];\n if (status && !isReconciliableStatus(status)) continue;\n issueIds.add(issueId);\n }\n\n for (const issueId of issueIds) {\n const before = statuses[issueId] ?? null;\n try {\n const after = deps.getReviewStatusSync(issueId);\n if (!statusChanged(before, after)) continue;\n // A required-check failure is actionable blocker state, not advancing\n // pipeline progress. Keep reconciling the journal through the read door,\n // but do not emit a repeated no-op advancement action while CI is red.\n if (hasFailingChecks(after)) continue;\n actions.push(`Reconciled journaled advancing verdict for ${issueId}`);\n } catch (error) {\n deps.warn(`[deacon] reconcileInFlightJournals: failed to reconcile ${issueId}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n return actions;\n}\n\nexport function markAdvancingSessionStopped(\n session: string,\n deps: Pick<AdvancingSelfHealDeps, 'getAgentStateSync' | 'saveAgentStateSync' | 'markAgentStoppedState'> = defaultDeps,\n): boolean {\n const state = deps.getAgentStateSync(session);\n if (!state || state.status === 'stopped') return false;\n\n const stopped = deps.markAgentStoppedState(state);\n deps.saveAgentStateSync(stopped);\n return true;\n}\n\n/**\n * PAN-2341: Reap advancing-role sessions for already-merged issues.\n *\n * The warm-by-default lifecycle (PAN-2579) intentionally leaves review/test/ship\n * panes alive, but once the issue is MERGED those sessions have no remaining role\n * in the pipeline (close-out territory). Kill the tmux session and\n * mark the agents-table row stopped so countRunningAgents() frees the slot.\n */\nexport async function checkMergedAdvancingSessions(): Promise<string[]> {\n const actions: string[] = [];\n try {\n const statuses = loadReviewStatuses();\n const aliveSessions = await Effect.runPromise(listSessionNames());\n const toKill = selectMergedAdvancingSessions(statuses, [...aliveSessions]);\n\n for (const session of toKill) {\n try {\n await Effect.runPromise(killSession(session));\n } catch (err) {\n console.warn(`[deacon] Failed to reap merged advancing session ${session}: ${err instanceof Error ? err.message : String(err)}`);\n }\n const markedStopped = markAdvancingSessionStopped(session);\n actions.push(\n markedStopped\n ? `Reaped merged advancing session ${session} (issue merged, row stopped)`\n : `Reaped merged advancing session ${session} (issue merged)`,\n );\n console.log(`[deacon] Reaped merged advancing session ${session} (PAN-2341)`);\n logDeaconEventSync(`checkMergedAdvancingSessions: reaped ${session} — issue merged but advancing session alive (PAN-2341)`);\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error('[deacon] Error reaping merged advancing sessions:', msg);\n }\n return actions;\n}\n\nexport interface BootAdvancingSelfHealDeps {\n reconcileInFlightJournals(): Promise<string[]>;\n checkMergedAdvancingSessions(): Promise<string[]>;\n log(message: string): void;\n}\n\nconst defaultBootAdvancingSelfHealDeps: BootAdvancingSelfHealDeps = {\n reconcileInFlightJournals,\n checkMergedAdvancingSessions,\n log: logDeaconEventSync,\n};\n\nexport async function runBootAdvancingSelfHeal(\n deps: BootAdvancingSelfHealDeps = defaultBootAdvancingSelfHealDeps,\n): Promise<string[]> {\n const actions: string[] = [];\n const steps: Array<[string, () => Promise<string[]>]> = [\n ['reconcileInFlightJournals', deps.reconcileInFlightJournals],\n ['checkMergedAdvancingSessions', deps.checkMergedAdvancingSessions],\n ];\n\n for (const [name, step] of steps) {\n try {\n const stepActions = await step();\n actions.push(...stepActions);\n if (stepActions.length > 0) {\n deps.log(`startDeacon: ${name} boot self-heal actions: ${stepActions.join('; ')}`);\n }\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n deps.log(`startDeacon: ${name} boot self-heal failed: ${msg}`);\n }\n }\n\n return actions;\n}\n"],"mappings":"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"}
|
|
@@ -2,9 +2,9 @@ import { Li as getOverdeckHome, On as resolveProjectFromIssueSync, Ri as init_pa
|
|
|
2
2
|
import { l as init_activity_logger, o as emitActivityEntrySync } from "./activity-logger-DNYDzAOU.js";
|
|
3
3
|
import { C as init_tmux, U as sessionExists } from "./tmux-l-yvNWhg.js";
|
|
4
4
|
import { c as init_agents, d as removeAgentRecordSync, f as tombstoneAgentRecordSync, u as listAllAgentsSync } from "./agents-CkngXhQr.js";
|
|
5
|
-
import { Gn as removeAgentStateDir, Hn as init_state_dir_removal, Un as listAgentStateFilesForRemoval, Vn as hasRetainedTranscriptsMarker, Wn as markRetainedTranscripts, _ as init_agent_state,
|
|
5
|
+
import { Gn as removeAgentStateDir, Hn as init_state_dir_removal, Sa as init_agents$1, Un as listAgentStateFilesForRemoval, Vn as hasRetainedTranscriptsMarker, Wn as markRetainedTranscripts, _ as init_agent_state, g as getAgentStateSync, xa as flushAgentPlaneWrites, ya as appendAgentPlaneLifecycle } from "./agent-state-B196fj1h.js";
|
|
6
6
|
import { c as resolveProjectReposForIssueSync, i as init_project_repos } from "./project-repos-J6jc42uD.js";
|
|
7
|
-
import { d as getReviewStatusSync, p as init_review_status } from "./review-status-
|
|
7
|
+
import { d as getReviewStatusSync, p as init_review_status } from "./review-status-yY5qt7Rl.js";
|
|
8
8
|
import { a as readLiveTrackerIssueState, n as init_issue_closed } from "./issue-closed-D7aMUeMq.js";
|
|
9
9
|
import { _ as init_gitlab_merge_requests, s as init_pipeline_membership_gather, u as listOpenPullRequestsSnapshot, v as listOpenGitLabMergeRequests } from "./pipeline-membership-gather-QYMqf_Wf.js";
|
|
10
10
|
import { join } from "node:path";
|
|
@@ -271,4 +271,4 @@ async function pruneTerminalStoppedAgents(agents = listAllAgentsSync(), deps = d
|
|
|
271
271
|
//#endregion
|
|
272
272
|
export { pruneTerminalStoppedAgents as n, pidsWithCwdUnder as r, pruneStoppedAgentsForIssue as t };
|
|
273
273
|
|
|
274
|
-
//# sourceMappingURL=agent-gc-
|
|
274
|
+
//# sourceMappingURL=agent-gc-JzoSs5Pi.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-gc-Coz8zQt_.js","names":[],"sources":["../../src/lib/process-cwd.ts","../../src/lib/cloister/agent-gc.ts"],"sourcesContent":["/**\n * Enumerate host PIDs whose current working directory is inside a given\n * directory tree, via /proc/<pid>/cwd.\n *\n * This is the safe selector for \"orphaned workspace processes\" (leftover vite\n * watchers, npm/vitest runners spawned in a workspace). It deliberately does\n * NOT use `lsof +D <dir>`: Bun installs node_modules as hardlinks from a\n * global cache, so long-lived platform processes (the dashboard server, every\n * conversation's PTY supervisor) mmap native addons (e.g. pty.node) whose\n * inode also lives inside every workspace's node_modules. `lsof +D` reports\n * them as holding files \"in\" the workspace, and killing that list takes down\n * the dashboard and all live conversations (2026-07-16 incident: `pan close\n * PAN-2532` killed the dashboard and an active operator conversation).\n */\nimport { readdir, readlink } from 'fs/promises';\n\nexport async function pidsWithCwdUnder(dir: string): Promise<string[]> {\n const prefix = dir.endsWith('/') ? dir : `${dir}/`;\n const pids: string[] = [];\n let entries: string[];\n try {\n entries = await readdir('/proc');\n } catch {\n return [];\n }\n for (const entry of entries) {\n if (!/^\\d+$/.test(entry)) continue;\n try {\n const cwd = await readlink(`/proc/${entry}/cwd`);\n if (cwd === dir || cwd.startsWith(prefix)) pids.push(entry);\n } catch {\n // Process exited, or belongs to another user — not killable by us anyway.\n }\n }\n return pids;\n}\n","import { join } from 'node:path';\n\nimport { Effect } from 'effect';\n\nimport {\n listAllAgentsSync,\n removeAgentRecordSync,\n RETAINED_TRANSCRIPTS_PHASE,\n tombstoneAgentRecordSync,\n} from '../overdeck/agents.js';\nimport {\n appendAgentPlaneLifecycle,\n flushAgentPlaneWrites,\n type AgentPlaneLifecycleEntry,\n type AgentPlaneTombstonePredicate,\n} from '../pan-dir/agents.js';\nimport { readIssueRecordForWorkspaceSync } from '../pan-dir/record.js';\nimport { getOverdeckHome } from '../paths.js';\nimport { emitActivityEntrySync } from '../activity-logger.js';\nimport { getAgentStateSync } from '../agents/agent-state.js';\nimport {\n hasRetainedTranscriptsMarker,\n listAgentStateFilesForRemoval,\n markRetainedTranscripts,\n removeAgentStateDir,\n type RemoveAgentStateDirResult,\n} from '../agents/state-dir-removal.js';\nimport { readLiveTrackerIssueState, type LiveTrackerIssueState } from './issue-closed.js';\nimport { sessionExists } from '../tmux.js';\nimport { getProjectSync, resolveProjectFromIssueSync } from '../projects.js';\nimport { resolveProjectReposForIssueSync } from '../project-repos.js';\nimport { listOpenPullRequestsSnapshot } from '../pipeline-membership-gather.js';\nimport { listOpenGitLabMergeRequests } from '../gitlab-merge-requests.js';\nimport { getReviewStatusSync } from '../review-status.js';\n\nexport interface AgentGcResult { removed: string[]; preserved: string[] }\nexport interface AgentGcRow {\n id: string;\n issueId: string;\n status: string;\n workspace?: string | null;\n phase?: string | null;\n role?: string | null;\n branch?: string | null;\n}\n\nexport interface AgentGcTerminalityDeps {\n hasClosedOutFlag: (agent: AgentGcRow) => boolean;\n readTrackerState: (issueId: string) => Promise<LiveTrackerIssueState>;\n hasLiveTmuxSession: (agentId: string) => Promise<boolean>;\n hasOpenChangeRequest: (agent: AgentGcRow) => Promise<boolean>;\n hasInFlightReviewOrTest: (agent: AgentGcRow) => boolean | Promise<boolean>;\n log: (message: string) => void;\n}\n\nexport type AgentGcTerminalityResult = boolean | AgentPlaneTombstonePredicate | null;\n\nexport interface AgentGcDeps {\n agentsDir: string;\n cleanStateDir: (dirPath: string, agentsDir: string) => Promise<RemoveAgentStateDirResult>;\n listFilesToRemove: (dirPath: string, agentsDir: string) => Promise<string[]>;\n hasRetainedMarker: (dirPath: string) => Promise<boolean>;\n markRetained: (dirPath: string) => Promise<void>;\n writeTombstone: (agent: AgentGcRow, entry: AgentPlaneLifecycleEntry) => Promise<void>;\n emitPruneEvent: (agent: AgentGcRow, entry: AgentPlaneLifecycleEntry) => void;\n removeRecord: (id: string) => void;\n tombstoneRecord: (id: string) => void;\n isTerminalAgent: (agent: AgentGcRow) => AgentGcTerminalityResult | Promise<AgentGcTerminalityResult>;\n log?: (message: string) => void;\n}\n\nfunction branchCandidates(agent: AgentGcRow, configuredBranch: string): Set<string> {\n return new Set([\n agent.branch,\n configuredBranch,\n `feature/${agent.issueId.toLowerCase()}`,\n `strike/${agent.issueId.toLowerCase()}`,\n ].filter((branch): branch is string => Boolean(branch)));\n}\n\nasync function hasOpenChangeRequest(agent: AgentGcRow): Promise<boolean> {\n const resolved = resolveProjectFromIssueSync(agent.issueId);\n if (!resolved) throw new Error(`No configured project resolves ${agent.issueId}`);\n const project = getProjectSync(resolved.projectKey);\n if (!project) throw new Error(`Project ${resolved.projectKey} is not configured`);\n const repos = resolveProjectReposForIssueSync(agent.issueId);\n if (!repos?.length) throw new Error(`No configured repositories resolve ${agent.issueId}`);\n\n const githubRepos = repos.filter((repo) => repo.forge === 'github');\n if (githubRepos.length > 0) {\n const [owner, repo] = project.github_repo?.split('/') ?? [];\n if (githubRepos.length !== 1 || !owner || !repo) {\n throw new Error(`Cannot safely resolve GitHub PR repository for ${agent.issueId}`);\n }\n const openPullRequests = await listOpenPullRequestsSnapshot(owner, repo);\n const candidates = branchCandidates(agent, githubRepos[0].sourceBranch);\n if (openPullRequests.some((pullRequest) => candidates.has(pullRequest.headRefName))) return true;\n }\n\n for (const repo of repos.filter((candidate) => candidate.forge === 'gitlab')) {\n const candidates = branchCandidates(agent, repo.sourceBranch);\n const openMergeRequests = await listOpenGitLabMergeRequests(repo.repoPath);\n if (openMergeRequests.some((mergeRequest) => candidates.has(mergeRequest.source_branch))) return true;\n }\n\n return false;\n}\n\nfunction hasInFlightReviewOrTest(agent: AgentGcRow): boolean {\n const status = getReviewStatusSync(agent.issueId);\n if (\n status?.reviewStatus === 'reviewing'\n || status?.testStatus === 'testing'\n || status?.verificationStatus === 'running'\n || (status?.reviewStatus === 'pending' && Boolean(status.reviewRequestedAt))\n ) return true;\n\n return listAllAgentsSync().some((candidate) =>\n candidate.issueId.toUpperCase() === agent.issueId.toUpperCase()\n && (candidate.role === 'review' || candidate.role === 'test')\n && ['starting', 'running', 'waiting', 'idle'].includes(candidate.status));\n}\n\nfunction defaultTerminalityDeps(): AgentGcTerminalityDeps {\n return {\n hasClosedOutFlag: (agent) => Boolean(agent.workspace\n && readIssueRecordForWorkspaceSync(agent.workspace, agent.issueId)?.pipeline?.closedOut === true),\n readTrackerState: readLiveTrackerIssueState,\n hasLiveTmuxSession: (agentId) => Effect.runPromise(sessionExists(agentId)),\n hasOpenChangeRequest,\n hasInFlightReviewOrTest,\n log: (message) => console.log(message),\n };\n}\n\n/**\n * Confirm every live fact required before periodic GC may remove agent state.\n * Any dependency failure is allowed to reject; the sweep catches it and\n * preserves the agent because uncertainty cannot authorize deletion.\n */\nexport async function resolveLiveAgentTerminalityEvidence(\n agent: AgentGcRow,\n deps: AgentGcTerminalityDeps = defaultTerminalityDeps(),\n): Promise<AgentPlaneTombstonePredicate | null> {\n if (agent.status !== 'stopped' || !agent.workspace) return null;\n const closedOutFlag = deps.hasClosedOutFlag(agent);\n if (!closedOutFlag) {\n deps.log(`[agent-gc] preserving ${agent.id}: issue record is not closed out`);\n return null;\n }\n\n const trackerState = await deps.readTrackerState(agent.issueId);\n if (trackerState !== 'closed') {\n deps.log(`[agent-gc] preserving ${agent.id}: live tracker state is ${trackerState}`);\n return null;\n }\n const liveTmux = await deps.hasLiveTmuxSession(agent.id);\n if (liveTmux) {\n deps.log(`[agent-gc] preserving ${agent.id}: tmux session is live`);\n return null;\n }\n const openChangeRequest = await deps.hasOpenChangeRequest(agent);\n if (openChangeRequest) {\n deps.log(`[agent-gc] preserving ${agent.id}: an open PR or MR still exists`);\n return null;\n }\n const inFlightReviewOrTest = await deps.hasInFlightReviewOrTest(agent);\n if (inFlightReviewOrTest) {\n deps.log(`[agent-gc] preserving ${agent.id}: review or test work is still in flight`);\n return null;\n }\n\n return {\n closedOutFlag,\n trackerState,\n liveTmux,\n openChangeRequest,\n inFlightReviewOrTest,\n };\n}\n\nexport async function confirmLiveAgentTerminality(\n agent: AgentGcRow,\n deps: AgentGcTerminalityDeps = defaultTerminalityDeps(),\n): Promise<boolean> {\n return (await resolveLiveAgentTerminalityEvidence(agent, deps)) !== null;\n}\n\nasync function persistAgentGcTombstone(\n agent: AgentGcRow,\n entry: AgentPlaneLifecycleEntry,\n): Promise<void> {\n const state = getAgentStateSync(agent.id);\n if (!state) {\n throw new Error(`local agent state is unavailable for durable tombstone ${agent.id}`);\n }\n // The GC owns the durability boundary below. Keep this concrete mutation in\n // the queue until its explicit flush can reconcile a concurrent remote\n // advance while the desired tombstone is still available.\n const written = await appendAgentPlaneLifecycle(state, entry, { deferCommit: true });\n if (!written) {\n throw new Error(`durable agent plane is unavailable for tombstone ${agent.id}`);\n }\n const flush = await flushAgentPlaneWrites(agent.issueId, agent.id);\n if (!flush || flush.errored || flush.pushed !== true) {\n throw new Error(\n `durable tombstone push failed for ${agent.id}: ${flush?.reason ?? 'no confirmed state-branch push'}`,\n );\n }\n}\n\nfunction emitAgentGcPruneEvent(\n agent: AgentGcRow,\n entry: AgentPlaneLifecycleEntry,\n): void {\n emitActivityEntrySync({\n source: 'cloister',\n level: 'info',\n status: 'completed',\n issueId: agent.issueId,\n message: `${agent.id} tombstoned before local agent-state cleanup`,\n details: JSON.stringify({\n predicate: entry.predicate,\n filesRemoved: entry.filesRemoved,\n }),\n });\n}\n\nfunction defaultAgentGcDeps(): AgentGcDeps {\n return {\n agentsDir: join(getOverdeckHome(), 'agents'),\n cleanStateDir: removeAgentStateDir,\n listFilesToRemove: listAgentStateFilesForRemoval,\n hasRetainedMarker: hasRetainedTranscriptsMarker,\n markRetained: markRetainedTranscripts,\n writeTombstone: persistAgentGcTombstone,\n emitPruneEvent: emitAgentGcPruneEvent,\n removeRecord: removeAgentRecordSync,\n tombstoneRecord: tombstoneAgentRecordSync,\n isTerminalAgent: (agent) => resolveLiveAgentTerminalityEvidence(agent),\n log: (message) => console.warn(message),\n };\n}\n\nfunction preverifiedCloseOutPredicate(): AgentPlaneTombstonePredicate {\n return {\n closedOutFlag: true,\n trackerState: 'closed-preverified-by-close-out',\n liveTmux: null,\n openChangeRequest: null,\n inFlightReviewOrTest: null,\n };\n}\n\nexport async function pruneAgentRowsAfterTranscriptCleanup(\n agents: readonly AgentGcRow[],\n deps: AgentGcDeps = defaultAgentGcDeps(),\n evidenceByAgent: ReadonlyMap<string, AgentPlaneTombstonePredicate> = new Map(),\n): Promise<AgentGcResult> {\n const removed: string[] = [];\n const preserved: string[] = [];\n for (const agent of agents) {\n try {\n const agentDir = join(deps.agentsDir, agent.id);\n if (await deps.hasRetainedMarker(agentDir)) {\n preserved.push(agent.id);\n continue;\n }\n const entry: AgentPlaneLifecycleEntry = {\n at: new Date().toISOString(),\n event: 'tombstoned',\n predicate: evidenceByAgent.get(agent.id) ?? preverifiedCloseOutPredicate(),\n filesRemoved: await deps.listFilesToRemove(agentDir, deps.agentsDir),\n };\n await deps.writeTombstone(agent, entry);\n deps.emitPruneEvent(agent, entry);\n const result = await deps.cleanStateDir(agentDir, deps.agentsDir);\n if (!result.removedDir) {\n await deps.markRetained(agentDir);\n deps.tombstoneRecord(agent.id);\n preserved.push(agent.id);\n continue;\n }\n deps.removeRecord(agent.id);\n removed.push(agent.id);\n } catch (error) {\n deps.log?.(\n `[agent-gc] preserving ${agent.id}: tombstone or cleanup failed: `\n + `${error instanceof Error ? error.message : String(error)}`,\n );\n preserved.push(agent.id);\n }\n }\n return { removed, preserved };\n}\n\n/**\n * Close-out-only pruning path. The lifecycle workflow has already positively\n * verified tracker terminality before it reaches this handoff, so it does not\n * repeat the periodic sweep's remote checks.\n */\nexport async function pruneStoppedAgentsForIssue(\n issueId: string,\n agents: AgentGcRow[] = listAllAgentsSync(),\n deps: AgentGcDeps = defaultAgentGcDeps(),\n): Promise<AgentGcResult> {\n const issue = issueId.toUpperCase();\n const scoped = agents.filter(agent => agent.issueId.toUpperCase() === issue);\n const terminal = scoped.filter(agent => agent.status === 'stopped');\n const live = scoped.filter(agent => agent.status !== 'stopped').map(agent => agent.id);\n const result = await pruneAgentRowsAfterTranscriptCleanup(terminal, deps);\n return { removed: result.removed, preserved: [...live, ...result.preserved] };\n}\n\nexport async function pruneTerminalStoppedAgents(\n agents: AgentGcRow[] = listAllAgentsSync(),\n deps: AgentGcDeps = defaultAgentGcDeps(),\n options: { dryRun?: boolean } = {},\n): Promise<AgentGcResult> {\n const candidates = agents.filter((agent) =>\n agent.phase !== RETAINED_TRANSCRIPTS_PHASE\n && agent.status === 'stopped'\n && Boolean(agent.workspace));\n const terminal: AgentGcRow[] = [];\n const evidenceByAgent = new Map<string, AgentPlaneTombstonePredicate>();\n const preserved: string[] = [];\n\n for (const agent of candidates) {\n try {\n const terminality = await deps.isTerminalAgent(agent);\n if (terminality) {\n terminal.push(agent);\n if (typeof terminality === 'object') {\n evidenceByAgent.set(agent.id, terminality);\n }\n } else preserved.push(agent.id);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n deps.log?.(`[agent-gc] preserving ${agent.id}: live terminality check failed: ${message}`);\n preserved.push(agent.id);\n }\n }\n\n if (options.dryRun) {\n return { removed: terminal.map((agent) => agent.id), preserved };\n }\n\n const result = await pruneAgentRowsAfterTranscriptCleanup(\n terminal,\n deps,\n evidenceByAgent,\n );\n return { removed: result.removed, preserved: [...preserved, ...result.preserved] };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent-gc-JzoSs5Pi.js","names":[],"sources":["../../src/lib/process-cwd.ts","../../src/lib/cloister/agent-gc.ts"],"sourcesContent":["/**\n * Enumerate host PIDs whose current working directory is inside a given\n * directory tree, via /proc/<pid>/cwd.\n *\n * This is the safe selector for \"orphaned workspace processes\" (leftover vite\n * watchers, npm/vitest runners spawned in a workspace). It deliberately does\n * NOT use `lsof +D <dir>`: Bun installs node_modules as hardlinks from a\n * global cache, so long-lived platform processes (the dashboard server, every\n * conversation's PTY supervisor) mmap native addons (e.g. pty.node) whose\n * inode also lives inside every workspace's node_modules. `lsof +D` reports\n * them as holding files \"in\" the workspace, and killing that list takes down\n * the dashboard and all live conversations (2026-07-16 incident: `pan close\n * PAN-2532` killed the dashboard and an active operator conversation).\n */\nimport { readdir, readlink } from 'fs/promises';\n\nexport async function pidsWithCwdUnder(dir: string): Promise<string[]> {\n const prefix = dir.endsWith('/') ? dir : `${dir}/`;\n const pids: string[] = [];\n let entries: string[];\n try {\n entries = await readdir('/proc');\n } catch {\n return [];\n }\n for (const entry of entries) {\n if (!/^\\d+$/.test(entry)) continue;\n try {\n const cwd = await readlink(`/proc/${entry}/cwd`);\n if (cwd === dir || cwd.startsWith(prefix)) pids.push(entry);\n } catch {\n // Process exited, or belongs to another user — not killable by us anyway.\n }\n }\n return pids;\n}\n","import { join } from 'node:path';\n\nimport { Effect } from 'effect';\n\nimport {\n listAllAgentsSync,\n removeAgentRecordSync,\n RETAINED_TRANSCRIPTS_PHASE,\n tombstoneAgentRecordSync,\n} from '../overdeck/agents.js';\nimport {\n appendAgentPlaneLifecycle,\n flushAgentPlaneWrites,\n type AgentPlaneLifecycleEntry,\n type AgentPlaneTombstonePredicate,\n} from '../pan-dir/agents.js';\nimport { readIssueRecordForWorkspaceSync } from '../pan-dir/record.js';\nimport { getOverdeckHome } from '../paths.js';\nimport { emitActivityEntrySync } from '../activity-logger.js';\nimport { getAgentStateSync } from '../agents/agent-state.js';\nimport {\n hasRetainedTranscriptsMarker,\n listAgentStateFilesForRemoval,\n markRetainedTranscripts,\n removeAgentStateDir,\n type RemoveAgentStateDirResult,\n} from '../agents/state-dir-removal.js';\nimport { readLiveTrackerIssueState, type LiveTrackerIssueState } from './issue-closed.js';\nimport { sessionExists } from '../tmux.js';\nimport { getProjectSync, resolveProjectFromIssueSync } from '../projects.js';\nimport { resolveProjectReposForIssueSync } from '../project-repos.js';\nimport { listOpenPullRequestsSnapshot } from '../pipeline-membership-gather.js';\nimport { listOpenGitLabMergeRequests } from '../gitlab-merge-requests.js';\nimport { getReviewStatusSync } from '../review-status.js';\n\nexport interface AgentGcResult { removed: string[]; preserved: string[] }\nexport interface AgentGcRow {\n id: string;\n issueId: string;\n status: string;\n workspace?: string | null;\n phase?: string | null;\n role?: string | null;\n branch?: string | null;\n}\n\nexport interface AgentGcTerminalityDeps {\n hasClosedOutFlag: (agent: AgentGcRow) => boolean;\n readTrackerState: (issueId: string) => Promise<LiveTrackerIssueState>;\n hasLiveTmuxSession: (agentId: string) => Promise<boolean>;\n hasOpenChangeRequest: (agent: AgentGcRow) => Promise<boolean>;\n hasInFlightReviewOrTest: (agent: AgentGcRow) => boolean | Promise<boolean>;\n log: (message: string) => void;\n}\n\nexport type AgentGcTerminalityResult = boolean | AgentPlaneTombstonePredicate | null;\n\nexport interface AgentGcDeps {\n agentsDir: string;\n cleanStateDir: (dirPath: string, agentsDir: string) => Promise<RemoveAgentStateDirResult>;\n listFilesToRemove: (dirPath: string, agentsDir: string) => Promise<string[]>;\n hasRetainedMarker: (dirPath: string) => Promise<boolean>;\n markRetained: (dirPath: string) => Promise<void>;\n writeTombstone: (agent: AgentGcRow, entry: AgentPlaneLifecycleEntry) => Promise<void>;\n emitPruneEvent: (agent: AgentGcRow, entry: AgentPlaneLifecycleEntry) => void;\n removeRecord: (id: string) => void;\n tombstoneRecord: (id: string) => void;\n isTerminalAgent: (agent: AgentGcRow) => AgentGcTerminalityResult | Promise<AgentGcTerminalityResult>;\n log?: (message: string) => void;\n}\n\nfunction branchCandidates(agent: AgentGcRow, configuredBranch: string): Set<string> {\n return new Set([\n agent.branch,\n configuredBranch,\n `feature/${agent.issueId.toLowerCase()}`,\n `strike/${agent.issueId.toLowerCase()}`,\n ].filter((branch): branch is string => Boolean(branch)));\n}\n\nasync function hasOpenChangeRequest(agent: AgentGcRow): Promise<boolean> {\n const resolved = resolveProjectFromIssueSync(agent.issueId);\n if (!resolved) throw new Error(`No configured project resolves ${agent.issueId}`);\n const project = getProjectSync(resolved.projectKey);\n if (!project) throw new Error(`Project ${resolved.projectKey} is not configured`);\n const repos = resolveProjectReposForIssueSync(agent.issueId);\n if (!repos?.length) throw new Error(`No configured repositories resolve ${agent.issueId}`);\n\n const githubRepos = repos.filter((repo) => repo.forge === 'github');\n if (githubRepos.length > 0) {\n const [owner, repo] = project.github_repo?.split('/') ?? [];\n if (githubRepos.length !== 1 || !owner || !repo) {\n throw new Error(`Cannot safely resolve GitHub PR repository for ${agent.issueId}`);\n }\n const openPullRequests = await listOpenPullRequestsSnapshot(owner, repo);\n const candidates = branchCandidates(agent, githubRepos[0].sourceBranch);\n if (openPullRequests.some((pullRequest) => candidates.has(pullRequest.headRefName))) return true;\n }\n\n for (const repo of repos.filter((candidate) => candidate.forge === 'gitlab')) {\n const candidates = branchCandidates(agent, repo.sourceBranch);\n const openMergeRequests = await listOpenGitLabMergeRequests(repo.repoPath);\n if (openMergeRequests.some((mergeRequest) => candidates.has(mergeRequest.source_branch))) return true;\n }\n\n return false;\n}\n\nfunction hasInFlightReviewOrTest(agent: AgentGcRow): boolean {\n const status = getReviewStatusSync(agent.issueId);\n if (\n status?.reviewStatus === 'reviewing'\n || status?.testStatus === 'testing'\n || status?.verificationStatus === 'running'\n || (status?.reviewStatus === 'pending' && Boolean(status.reviewRequestedAt))\n ) return true;\n\n return listAllAgentsSync().some((candidate) =>\n candidate.issueId.toUpperCase() === agent.issueId.toUpperCase()\n && (candidate.role === 'review' || candidate.role === 'test')\n && ['starting', 'running', 'waiting', 'idle'].includes(candidate.status));\n}\n\nfunction defaultTerminalityDeps(): AgentGcTerminalityDeps {\n return {\n hasClosedOutFlag: (agent) => Boolean(agent.workspace\n && readIssueRecordForWorkspaceSync(agent.workspace, agent.issueId)?.pipeline?.closedOut === true),\n readTrackerState: readLiveTrackerIssueState,\n hasLiveTmuxSession: (agentId) => Effect.runPromise(sessionExists(agentId)),\n hasOpenChangeRequest,\n hasInFlightReviewOrTest,\n log: (message) => console.log(message),\n };\n}\n\n/**\n * Confirm every live fact required before periodic GC may remove agent state.\n * Any dependency failure is allowed to reject; the sweep catches it and\n * preserves the agent because uncertainty cannot authorize deletion.\n */\nexport async function resolveLiveAgentTerminalityEvidence(\n agent: AgentGcRow,\n deps: AgentGcTerminalityDeps = defaultTerminalityDeps(),\n): Promise<AgentPlaneTombstonePredicate | null> {\n if (agent.status !== 'stopped' || !agent.workspace) return null;\n const closedOutFlag = deps.hasClosedOutFlag(agent);\n if (!closedOutFlag) {\n deps.log(`[agent-gc] preserving ${agent.id}: issue record is not closed out`);\n return null;\n }\n\n const trackerState = await deps.readTrackerState(agent.issueId);\n if (trackerState !== 'closed') {\n deps.log(`[agent-gc] preserving ${agent.id}: live tracker state is ${trackerState}`);\n return null;\n }\n const liveTmux = await deps.hasLiveTmuxSession(agent.id);\n if (liveTmux) {\n deps.log(`[agent-gc] preserving ${agent.id}: tmux session is live`);\n return null;\n }\n const openChangeRequest = await deps.hasOpenChangeRequest(agent);\n if (openChangeRequest) {\n deps.log(`[agent-gc] preserving ${agent.id}: an open PR or MR still exists`);\n return null;\n }\n const inFlightReviewOrTest = await deps.hasInFlightReviewOrTest(agent);\n if (inFlightReviewOrTest) {\n deps.log(`[agent-gc] preserving ${agent.id}: review or test work is still in flight`);\n return null;\n }\n\n return {\n closedOutFlag,\n trackerState,\n liveTmux,\n openChangeRequest,\n inFlightReviewOrTest,\n };\n}\n\nexport async function confirmLiveAgentTerminality(\n agent: AgentGcRow,\n deps: AgentGcTerminalityDeps = defaultTerminalityDeps(),\n): Promise<boolean> {\n return (await resolveLiveAgentTerminalityEvidence(agent, deps)) !== null;\n}\n\nasync function persistAgentGcTombstone(\n agent: AgentGcRow,\n entry: AgentPlaneLifecycleEntry,\n): Promise<void> {\n const state = getAgentStateSync(agent.id);\n if (!state) {\n throw new Error(`local agent state is unavailable for durable tombstone ${agent.id}`);\n }\n // The GC owns the durability boundary below. Keep this concrete mutation in\n // the queue until its explicit flush can reconcile a concurrent remote\n // advance while the desired tombstone is still available.\n const written = await appendAgentPlaneLifecycle(state, entry, { deferCommit: true });\n if (!written) {\n throw new Error(`durable agent plane is unavailable for tombstone ${agent.id}`);\n }\n const flush = await flushAgentPlaneWrites(agent.issueId, agent.id);\n if (!flush || flush.errored || flush.pushed !== true) {\n throw new Error(\n `durable tombstone push failed for ${agent.id}: ${flush?.reason ?? 'no confirmed state-branch push'}`,\n );\n }\n}\n\nfunction emitAgentGcPruneEvent(\n agent: AgentGcRow,\n entry: AgentPlaneLifecycleEntry,\n): void {\n emitActivityEntrySync({\n source: 'cloister',\n level: 'info',\n status: 'completed',\n issueId: agent.issueId,\n message: `${agent.id} tombstoned before local agent-state cleanup`,\n details: JSON.stringify({\n predicate: entry.predicate,\n filesRemoved: entry.filesRemoved,\n }),\n });\n}\n\nfunction defaultAgentGcDeps(): AgentGcDeps {\n return {\n agentsDir: join(getOverdeckHome(), 'agents'),\n cleanStateDir: removeAgentStateDir,\n listFilesToRemove: listAgentStateFilesForRemoval,\n hasRetainedMarker: hasRetainedTranscriptsMarker,\n markRetained: markRetainedTranscripts,\n writeTombstone: persistAgentGcTombstone,\n emitPruneEvent: emitAgentGcPruneEvent,\n removeRecord: removeAgentRecordSync,\n tombstoneRecord: tombstoneAgentRecordSync,\n isTerminalAgent: (agent) => resolveLiveAgentTerminalityEvidence(agent),\n log: (message) => console.warn(message),\n };\n}\n\nfunction preverifiedCloseOutPredicate(): AgentPlaneTombstonePredicate {\n return {\n closedOutFlag: true,\n trackerState: 'closed-preverified-by-close-out',\n liveTmux: null,\n openChangeRequest: null,\n inFlightReviewOrTest: null,\n };\n}\n\nexport async function pruneAgentRowsAfterTranscriptCleanup(\n agents: readonly AgentGcRow[],\n deps: AgentGcDeps = defaultAgentGcDeps(),\n evidenceByAgent: ReadonlyMap<string, AgentPlaneTombstonePredicate> = new Map(),\n): Promise<AgentGcResult> {\n const removed: string[] = [];\n const preserved: string[] = [];\n for (const agent of agents) {\n try {\n const agentDir = join(deps.agentsDir, agent.id);\n if (await deps.hasRetainedMarker(agentDir)) {\n preserved.push(agent.id);\n continue;\n }\n const entry: AgentPlaneLifecycleEntry = {\n at: new Date().toISOString(),\n event: 'tombstoned',\n predicate: evidenceByAgent.get(agent.id) ?? preverifiedCloseOutPredicate(),\n filesRemoved: await deps.listFilesToRemove(agentDir, deps.agentsDir),\n };\n await deps.writeTombstone(agent, entry);\n deps.emitPruneEvent(agent, entry);\n const result = await deps.cleanStateDir(agentDir, deps.agentsDir);\n if (!result.removedDir) {\n await deps.markRetained(agentDir);\n deps.tombstoneRecord(agent.id);\n preserved.push(agent.id);\n continue;\n }\n deps.removeRecord(agent.id);\n removed.push(agent.id);\n } catch (error) {\n deps.log?.(\n `[agent-gc] preserving ${agent.id}: tombstone or cleanup failed: `\n + `${error instanceof Error ? error.message : String(error)}`,\n );\n preserved.push(agent.id);\n }\n }\n return { removed, preserved };\n}\n\n/**\n * Close-out-only pruning path. The lifecycle workflow has already positively\n * verified tracker terminality before it reaches this handoff, so it does not\n * repeat the periodic sweep's remote checks.\n */\nexport async function pruneStoppedAgentsForIssue(\n issueId: string,\n agents: AgentGcRow[] = listAllAgentsSync(),\n deps: AgentGcDeps = defaultAgentGcDeps(),\n): Promise<AgentGcResult> {\n const issue = issueId.toUpperCase();\n const scoped = agents.filter(agent => agent.issueId.toUpperCase() === issue);\n const terminal = scoped.filter(agent => agent.status === 'stopped');\n const live = scoped.filter(agent => agent.status !== 'stopped').map(agent => agent.id);\n const result = await pruneAgentRowsAfterTranscriptCleanup(terminal, deps);\n return { removed: result.removed, preserved: [...live, ...result.preserved] };\n}\n\nexport async function pruneTerminalStoppedAgents(\n agents: AgentGcRow[] = listAllAgentsSync(),\n deps: AgentGcDeps = defaultAgentGcDeps(),\n options: { dryRun?: boolean } = {},\n): Promise<AgentGcResult> {\n const candidates = agents.filter((agent) =>\n agent.phase !== RETAINED_TRANSCRIPTS_PHASE\n && agent.status === 'stopped'\n && Boolean(agent.workspace));\n const terminal: AgentGcRow[] = [];\n const evidenceByAgent = new Map<string, AgentPlaneTombstonePredicate>();\n const preserved: string[] = [];\n\n for (const agent of candidates) {\n try {\n const terminality = await deps.isTerminalAgent(agent);\n if (terminality) {\n terminal.push(agent);\n if (typeof terminality === 'object') {\n evidenceByAgent.set(agent.id, terminality);\n }\n } else preserved.push(agent.id);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n deps.log?.(`[agent-gc] preserving ${agent.id}: live terminality check failed: ${message}`);\n preserved.push(agent.id);\n }\n }\n\n if (options.dryRun) {\n return { removed: terminal.map((agent) => agent.id), preserved };\n }\n\n const result = await pruneAgentRowsAfterTranscriptCleanup(\n terminal,\n deps,\n evidenceByAgent,\n );\n return { removed: result.removed, preserved: [...preserved, ...result.preserved] };\n}\n"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import { A as listPaneValuesSync, B as sendKeys, C as init_tmux, D as killSessio
|
|
|
3
3
|
import { c as getRuntimeBehavior, i as CLAUDE_CODE_BEHAVIOR } from "./src-tnFSfiXX.js";
|
|
4
4
|
import { o as getPricingSync, s as init_cost } from "./cost-ShD-G0cS.js";
|
|
5
5
|
import { t as init_behavior } from "./behavior-Bg3yC8jC.js";
|
|
6
|
-
import { A as saveAgentStateSync,
|
|
6
|
+
import { A as saveAgentStateSync, Di as materializeAcpContextFile, Ei as init_context, Fn as init_queries, In as listAgentStates, K as saveAgentRuntimeState, Lr as BRIDGE_TOKEN_HEADER, Or as init_delivery, Rr as init_bridge_token, Si as init_pi_fifo, W as getAgentRuntimeStateSync, Yi as determineModel, ai as materializeMuseContext, an as createOhmypiRuntimeSync, bi as waitForPromptReady, cn as spawnAgent, f as getAgentDir, g as getAgentStateSync, ga as resolvePtySupervisorScriptPath, gi as init_runtime_command, ha as init_pty_supervisor_locate, ii as init_muse_context, ma as writePtyToken, on as init_ohmypi, pa as init_pty_token, pn as createKimiCodeRuntimeSync, q as init_agents, vn as init_kimi_code, wr as deliverAgentMessage } from "./agent-state-B196fj1h.js";
|
|
7
7
|
import { C as generateLauncherScriptSync, E as resolveKimiNativeEffort, T as init_kimi_effort, w as init_launcher_generator } from "./auto-spawn-consent-CJeQM5e0.js";
|
|
8
8
|
import { _ as tmuxKillSession, g as tmuxCreateSession, h as init_tmux_cli, i as createCodexRuntimeSync, l as init_codex, v as tmuxSessionExists } from "./codex-pffr8qaN.js";
|
|
9
9
|
import { i as prepareHarnessLaunch, r as init_harness_binary } from "./harness-binary-DnRGvN6T.js";
|
|
@@ -894,4 +894,4 @@ function isAgentIdleForNudge(agentId, staleActiveThresholdMs = 300 * 1e3, now =
|
|
|
894
894
|
//#endregion
|
|
895
895
|
export { getRuntimeForAgent as i, getAgentWorkActivityMs as n, isAgentIdleForNudge as r, getAgentEffectiveLastActivityMs as t };
|
|
896
896
|
|
|
897
|
-
//# sourceMappingURL=agent-idle-
|
|
897
|
+
//# sourceMappingURL=agent-idle-D-Qy5BN_.js.map
|