@overdeck/desktop 0.47.0 → 0.48.0
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/drizzle/overdeck/0000_overdeck_init.sql +59 -0
- package/package.json +1 -1
- package/server/{acceptance-criteria-10Ur5Dne.js → acceptance-criteria-DmtLDbtt.js} +2 -2
- package/server/{activity-logger-CyteR4JO.js → activity-logger-Co5qljIj.js} +55 -4
- package/server/activity-logger-K7FYGF_z.js +3 -0
- package/server/{advancing-selfheal-BNwqxseD.js → advancing-selfheal-8AR68Asf.js} +6 -6
- package/server/{agent-gc-C3h9Or3a.js → agent-gc-BmYeT6eH.js} +5 -5
- package/server/agent-state-Dq3s84-P.js +3 -0
- package/server/{agent-state-service-C63p_ftq.js → agent-state-service-DK1Vay1E.js} +1 -1
- package/server/{agent-state-service-Ds6OeFvo.js → agent-state-service-rjnzpHDx.js} +6 -6
- package/server/agent-state-source-Ds968-j6.js +21 -0
- package/server/{agents-J5mEnekq.js → agents-Dls7tfJH.js} +5 -5
- package/server/agents-IPSa5kzn.js +3 -0
- package/server/{archive-planning-BwhxeP7C.js → archive-planning-Cq7cyinS.js} +51 -24
- package/server/archive-planning-MbkGCBIY.js +2 -0
- package/server/{artifact-index-jobs-D1q_vR3V.js → artifact-index-jobs-Dj_8kpTd.js} +3 -3
- package/server/{assemble-Bgwqv-Ro.js → assemble-BTCmbcfH.js} +20 -13
- package/server/{auto-spawn-consent-CQ9Bi9q6.js → auto-spawn-consent-lXqRJ1Dr.js} +304 -121
- package/server/{backlog-auto-trigger-n1lzPgN4.js → backlog-auto-trigger-Dn-amzt6.js} +3 -3
- package/server/{behavior-td6-xhQk.js → behavior-DIMQMRzs.js} +2 -2
- package/server/{boot-reconciled-stop-events-C7gGe3oB.js → boot-reconciled-stop-events-D6SeUTIr.js} +1 -1
- package/server/{bridge-pool-patrol-CYH2OLb5.js → bridge-pool-patrol-BEjt-xF3.js} +2 -2
- package/server/{briefing-freshness-DRqZ8lAz.js → briefing-freshness-3PNmL_p3.js} +2 -2
- package/server/{build-info-7yiEpl6u.js → build-info-CJg813Hm.js} +3 -3
- package/server/{build-info-CpG__c63.js → build-info-CXyeFsXu.js} +1 -1
- package/server/{checkpoint-manager-CkKmB0wZ.js → checkpoint-manager-9t7G5c1V.js} +1 -1
- package/server/{checkpoint-manager-DBcyNR8w.js → checkpoint-manager-B2G38R3p.js} +3 -3
- package/server/checkpoint-worker.js +1 -1
- package/server/{checkpoints-Wm963lm8.js → checkpoints-CuBgiXO-.js} +1 -1
- package/server/{checkpoints-D95apurL.js → checkpoints-VTZMd4Qm.js} +2 -2
- package/server/{claude-hooks-provision-Bjitl9aI.js → claude-hooks-provision-55SyQaPz.js} +2 -2
- package/server/{claude-hooks-provision-4RPxNkE8.js → claude-hooks-provision-CEUT-CZd.js} +1 -1
- package/server/{claude-permissions-CpbpvUQ2.js → claude-permissions-Cn0dIu2i.js} +2 -2
- package/server/{claude-settings-overlay-BzkHYDwR.js → claude-settings-overlay-B19hdzSA.js} +1 -1
- package/server/{claude-settings-overlay-_H9Yrzab.js → claude-settings-overlay-Yg_ANh81.js} +2 -2
- package/server/{cli-Cte9ZFGn.js → cli-C9S84iTy.js} +79 -22
- package/server/cli-M1cwZ__d.js +3 -0
- package/server/{cliproxy-C5fMJ7rY.js → cliproxy-CJq3KXU6.js} +2 -2
- package/server/{cliproxy-DaAbWMjC.js → cliproxy-DgEZlr7Y.js} +1 -1
- package/server/{close-issue-BPh1ARCF.js → close-issue-DPxRddGR.js} +5 -5
- package/server/{closed-issue-reaper-DoOZqGFK.js → closed-issue-reaper-C5Zn4GRS.js} +13 -13
- package/server/{closed-issue-reaper-DHRfRMrp.js → closed-issue-reaper-D-2B48Ri.js} +1 -1
- package/server/{codex-o8FJwzmy.js → codex-B3n_rkwn.js} +1 -1
- package/server/{codex-BzGDW_d3.js → codex-CjkD1PJu.js} +6 -6
- package/server/{codex-parser-Dt-ycU8L.js → codex-parser-DpB1Il-P.js} +2 -2
- package/server/{compaction-continuation-CvXpbZ4w.js → compaction-continuation-DZD9ukSE.js} +3 -3
- package/server/{config-CL3Gyvja.js → config-C5saf4Ja.js} +1 -1
- package/server/{config-BvLe652W.js → config-DnLJATZk.js} +2 -2
- package/server/{config-Bi3u1VK7.js → config-DvM8jtQK.js} +2 -2
- package/server/{config-yaml-CxdwhAIA.js → config-yaml-BSCqwmX0.js} +11299 -10972
- package/server/{conflict-gate-CX80JYYS.js → conflict-gate-DXa_L28t.js} +1 -1
- package/server/{conflict-gate-E4nt7ZeS.js → conflict-gate-WfVqgalf.js} +4 -4
- package/server/{context-layers-DAG83UZt.js → context-layers-D7UqH9Ab.js} +2 -2
- package/server/{context-layers-C_IIysnm.js → context-layers-Dpz3Vd6d.js} +3 -3
- package/server/{control-settings-CiqGxXnc.js → control-settings-DVf6pKyv.js} +4 -4
- package/server/{conversation-compaction-BE3CNtHF.js → conversation-compaction-5XuH6OBn.js} +1 -1
- package/server/{conversation-compaction-D6-yLtqt.js → conversation-compaction-COrbnX1J.js} +8 -8
- package/server/{conversation-service-DBxoYMDl.js → conversation-service-BufdtnZF.js} +169 -10
- package/server/{conversation-service-D_TS2b1r.js → conversation-service-DnUyIiLb.js} +1 -1
- package/server/{conversations-D0UEdLtk.js → conversations-B4rxz-Wl.js} +17 -10
- package/server/{conversations-BKDVpB-3.js → conversations-D1bwxQMy.js} +1 -1
- package/server/{cost-DpgYmYqR.js → cost-CpFDrJUS.js} +46 -2
- package/server/{cost-DS1s0DbG.js → cost-KLuwKCW9.js} +3 -3
- package/server/{cost-sync-tOCCGnEt.js → cost-sync-cesi9dp8.js} +3 -3
- package/server/{dag-BtkgLeqY.js → dag-BYiFMqpU.js} +2 -2
- package/server/{dangerous-git-ops-CFLykHWt.js → dangerous-git-ops-BKvd3-Hk.js} +1 -1
- package/server/dashboard-db-worker.js +7 -7
- package/server/{deacon-BIblC-WX.js → deacon-BbsWw8a6.js} +3 -3
- package/server/{deacon-pLRLbPvR.js → deacon-HdEh0Esp.js} +863 -214
- package/server/deacon-event-client-C93rvOT7.js +237 -0
- package/server/deacon-event-client-Ck5Ei7Mn.js +3 -0
- package/server/{deacon-nudge-log-B08gF0mh.js → deacon-nudge-log-BND_97Wo.js} +4 -3
- package/server/{deacon-pending-lifecycle-B-Io84AP.js → deacon-pending-lifecycle-CD3YsiQK.js} +3 -3
- package/server/deacon-swarm-DgWADWd_.js +2 -0
- package/server/{deacon-swarm-v5PMun-m.js → deacon-swarm-rqrl4TMs.js} +39 -18
- package/server/deacon.js +12 -210
- package/server/{dead-end-trip-D8A3msX9.js → dead-end-trip-DSF23CLX.js} +4 -3
- package/server/dead-end-trip-zKlS4v6f.js +2 -0
- package/server/delivery-CsbQdZkS.js +3 -0
- package/server/{deploy-patrol-sYgOxLeb.js → deploy-patrol-kARAkji4.js} +17 -21
- package/server/{deploy-queue-VfohaPN_.js → deploy-queue-Bj0HJT1i.js} +2 -2
- package/server/{deploy-queue-gHJBycaF.js → deploy-queue-rjTUy1RM.js} +1 -1
- package/server/{deploy-window-D4DQb8VP.js → deploy-window-B2IM-9G5.js} +10 -44
- package/server/{deploy-window-CFRZ0-kt.js → deploy-window-BNFWnA8D.js} +1 -1
- package/server/{dev-supervisor-DiOBDM1c.js → dev-supervisor-B1mZYXz4.js} +2 -2
- package/server/{devcontainer-renderer-BUOIlfgD.js → devcontainer-renderer-B-o68Z5B.js} +3 -3
- package/server/{dist-C3A8B8wM.js → dist-3W--cGMa.js} +1 -1
- package/server/dist-BR0QtwmS.js +3 -0
- package/server/{dist-src-C0adpegX.js → dist-src-C-Vk2jNk.js} +1 -1
- package/server/{docker-Y3PElJb0.js → docker-DH3jUYg1.js} +1 -1
- package/server/{docker-BJzlkqYB.js → docker-meuLKLzV.js} +27 -20
- package/server/{dod-DlNtcH6n.js → dod-D7-9dCOD.js} +1 -1
- package/server/{driver-CKVGi51s.js → driver-CmsY2RLl.js} +1 -1
- package/server/{durable-review-pipeline-DP6bIcOY.js → durable-review-pipeline-CStTgOAf.js} +1 -1
- package/server/{durable-review-pipeline-Cibps-Rg.js → durable-review-pipeline-Chq0lzjL.js} +1 -1
- package/server/{ensure-devcontainer-DMAbWqtQ.js → ensure-devcontainer-BE3llBWP.js} +1 -1
- package/server/{ensure-devcontainer-BAofzBPv.js → ensure-devcontainer-BXrY7C2Z.js} +4 -4
- package/server/{esm-shims-BeObUkaw.js → esm-shims-Bzy4ZzNU.js} +1 -1
- package/server/event-store-COd2tOx8.js +3 -0
- package/server/{event-store-CrHcVC5_.js → event-store-D_AR-Y78.js} +184 -11
- package/server/{events-CF8QDbuV.js → events-CCkFWa7X.js} +1 -1
- package/server/{events-BNrvchBg.js → events-zjDQozet.js} +3 -3
- package/server/{factory-Cmm9Hsho.js → factory-DhavwKVc.js} +5 -5
- package/server/{feature-registry-population-B6HpNWRy.js → feature-registry-population-DWGBKyWd.js} +4 -4
- package/server/{feature-registry-storage-DJEFx1Pf.js → feature-registry-storage-C5DkXmCM.js} +3 -3
- package/server/{features-D5km80UI.js → features-CC47YcCX.js} +2 -2
- package/server/{feedback-target-BJ5ZADsu.js → feedback-target-D9Tex35_.js} +1 -1
- package/server/{feedback-target-DSxEL6lP.js → feedback-target-DoRCR3L-.js} +18 -7
- package/server/{feedback-writer-CoB9Z6aU.js → feedback-writer-CTSuA6lw.js} +1 -1
- package/server/{feedback-writer-C27Hak8a.js → feedback-writer-DdsBdtNL.js} +5 -5
- package/server/{flywheel-DZZdtiOL.js → flywheel-DHWHzaYK.js} +1 -1
- package/server/{flywheel-f662Q-y2.js → flywheel-DJQa9az8.js} +14 -14
- package/server/{flywheel-BHx8XuMr.js → flywheel-TacAI9MA.js} +21 -17
- package/server/{flywheel-merge-order-Dil0LmdN.js → flywheel-merge-order-D2foPh88.js} +1 -1
- package/server/{flywheel-merge-order-D_xLMbJU.js → flywheel-merge-order-DRtex2Dt.js} +7 -7
- package/server/forge-CdlCG9aS.js +3 -0
- package/server/{forge-BaKGCya6.js → forge-c8LeC-tw.js} +2 -2
- package/server/{from-B3tZbB55.js → from-BogSwvr2.js} +1 -1
- package/server/{fs-lock-Bre3sGoz.js → fs-lock-D_GeJtXl.js} +3 -3
- package/server/{fts-operations-B9jG8wa3.js → fts-operations-DP9R-8Q3.js} +3 -3
- package/server/{git-utils-Xg4PFN45.js → git-utils-C31x1lpE.js} +1 -1
- package/server/{git-utils-CsvYfJU3.js → git-utils-xQ74FoSn.js} +5 -4
- package/server/{github-app-Bmg4R9mv.js → github-app-CpQSDlv8.js} +1 -1
- package/server/{github-app-CmNk0zLU.js → github-app-D2QuvZ3j.js} +3 -3
- package/server/{github-client-qazkPrg0.js → github-client-D9YvJX5D.js} +3 -3
- package/server/{github-client-B6KM9_wA.js → github-client-Tpi3PmKX.js} +1 -1
- package/server/{github-pr-lookup-DAcVeRLK.js → github-pr-lookup-DvBMv-IW.js} +2 -2
- package/server/{harness-binary-BSpiXaLw.js → harness-binary-BHxWf_sX.js} +7 -6
- package/server/{harness-resolve-BAJu5MX8.js → harness-resolve-bj9WMABA.js} +4 -4
- package/server/{health-events-BwX32k8d.js → health-events-bCDPn59Z.js} +2 -2
- package/server/{health-events-2Z6Wa9SM.js → health-events-qo7Ss34U.js} +1 -1
- package/server/{hooks-DbtbimEf.js → hooks-Dyxtg5fk.js} +2 -2
- package/server/{hooks-D1g1jKLI.js → hooks-X2XHBB2b.js} +1 -1
- package/server/{hume-DXNiu6nQ.js → hume-DrZEGpqc.js} +2 -2
- package/server/hume-YPsy4UA8.js +3 -0
- package/server/{idle-stack-reaper-Cy-dQzW4.js → idle-stack-reaper-CJ1ygW0p.js} +37 -7
- package/server/{idle-stack-reaper-CRA1e0jr.js → idle-stack-reaper-uJGOb-vu.js} +1 -1
- package/server/{in-flight-guard-D-sSkADM.js → in-flight-guard-CG2Eo-rr.js} +1 -1
- package/server/{infra-BDQDRopn.js → infra-CTrmVqc_.js} +111 -6
- package/server/{injection-Bl8d_jHZ.js → injection-BisQ0lpX.js} +1 -1
- package/server/{injection-6AGnXxlj.js → injection-C9sxqbc2.js} +73 -193
- package/server/{inspect-agent-nXdIptyh.js → inspect-agent-BoSO51YC.js} +12 -12
- package/server/inspect-agent-BykeOH4a.js +2 -0
- package/server/{internal-token-DzK385vD.js → internal-token-AvXePaQT.js} +2 -2
- package/server/{internal-token-Ias7N8Kg.js → internal-token-Djkj-yqK.js} +1 -1
- package/server/{io-B00PBNku.js → io-mxOWMZ7I.js} +6 -6
- package/server/{issue-closed-BehTG1be.js → issue-closed-Bj_bCv_0.js} +7 -7
- package/server/{issue-lifecycle-BqSuQvbn.js → issue-lifecycle-A5YIpDZE.js} +1 -1
- package/server/{issue-lifecycle-Birk-ifu.js → issue-lifecycle-BXUqaHzF.js} +32 -28
- package/server/{issue-service-singleton-C6ZduvuY.js → issue-service-singleton-BPNEXczv.js} +11 -11
- package/server/{issue-service-singleton-B2wXiIlw.js → issue-service-singleton-CcaHjKPR.js} +1 -1
- package/server/{issues-DQ5-LatB.js → issues-AX-YBeAQ.js} +2 -2
- package/server/{jsonl-parser-BDpnGFCl.js → jsonl-parser-CgYWQ20q.js} +7 -3
- package/server/kimi-code-BYbme0aV.js +579 -0
- package/server/kimi-code-D_Ppt82c.js +3 -0
- package/server/kimi-parser-B-JBg3Pv.js +147 -0
- package/server/{label-cleanup-Dwnky8FG.js → label-cleanup-sXUlgdM0.js} +3 -3
- package/server/{lifecycle-B4Xdb4cY.js → lifecycle-D2X3al0D.js} +2 -2
- package/server/{lifecycle-B3s4sM1G.js → lifecycle-DjlljAZ1.js} +6 -6
- package/server/{lifecycle-io-CzTHEooc.js → lifecycle-io-C5nVk55o.js} +1 -1
- package/server/{lifecycle-io-DCo6s6ks.js → lifecycle-io-NPm1YtIG.js} +5 -5
- package/server/{linear-client-CnbtHiic.js → linear-client--luYwCZg.js} +1 -1
- package/server/{linear-client-9uq7fhiV.js → linear-client-B8pLegW1.js} +3 -3
- package/server/{linear-mcp-auth-BxUOzswy.js → linear-mcp-auth-BQVWV0I3.js} +6 -6
- package/server/{linear-mcp-auth-D46fBCLf.js → linear-mcp-auth-Dx81Zl4G.js} +1 -1
- package/server/memory-fts-worker.js +1 -1
- package/server/{merge-DiW9RdSB.js → merge-Bx5Bh9pi.js} +3 -3
- package/server/{merge-sr8Nrnmi.js → merge-Dqmh_zja.js} +1 -1
- package/server/{merge-agent-BLUgRsz3.js → merge-agent-DP9AUY29.js} +33 -33
- package/server/{merge-agent-DQTXZk8z.js → merge-agent-DWd0KfiS.js} +1 -1
- package/server/{merge-batch-Cp_j9BGk.js → merge-batch-BdmvTEAC.js} +1 -1
- package/server/{merge-completeness-BLbB5-6n.js → merge-completeness-BfRwFjRx.js} +1 -1
- package/server/{merge-completeness-B46KqhtY.js → merge-completeness-C1FevcDT.js} +4 -4
- package/server/merge-ops-B98tKc1e.js +2 -0
- package/server/merge-rebase-BLykMwPO.js +2 -0
- package/server/{merge-rebase-DIkBjgwq.js → merge-rebase-BX1xKsrE.js} +2 -2
- package/server/{merge-set-CBgHfwM0.js → merge-set-DsLjjLEV.js} +4 -4
- package/server/{merge-set-DeUxFsC3.js → merge-set-H6epHOsw.js} +1 -1
- package/server/{merge-sync-kr4vqyjM.js → merge-sync-BEdfsQV4.js} +2 -2
- package/server/{merge-sync-CpGmk6Ch.js → merge-sync-BebcWWGA.js} +1 -1
- package/server/{merge-train-Dmrcus12.js → merge-train-D1I0lNOT.js} +4 -4
- package/server/{merge-train-deps-D_uGX91G.js → merge-train-deps-D_-C0Pk2.js} +4 -4
- package/server/{merge-verification-NvaAd8CZ.js → merge-verification-DN1Ov9bU.js} +6 -6
- package/server/{merged-docker-cleanup-worker-Y1R06TEl.js → merged-docker-cleanup-worker-CfXSr2pA.js} +4 -4
- package/server/{merged-docker-cleanup-worker-DH_hrGPI.js → merged-docker-cleanup-worker-ybsPyHjB.js} +1 -1
- package/server/{multipart-parser-R-oC8dQg.js → multipart-parser-CL5QG8iv.js} +2 -2
- package/server/{no-resume-mode-BgD0JUmM.js → no-resume-mode-DUR7Hi98.js} +1 -1
- package/server/node_modules/.package-lock.json +7 -7
- package/server/node_modules/brace-expansion/README.md +23 -1
- package/server/node_modules/brace-expansion/index.js +206 -85
- package/server/node_modules/brace-expansion/package.json +1 -1
- package/server/node_modules/msgpackr/dist/index-no-eval.cjs +34 -28
- package/server/node_modules/msgpackr/dist/index-no-eval.cjs.map +1 -1
- package/server/node_modules/msgpackr/dist/index-no-eval.min.js +1 -1
- package/server/node_modules/msgpackr/dist/index-no-eval.min.js.map +1 -1
- package/server/node_modules/msgpackr/dist/index.js +34 -28
- package/server/node_modules/msgpackr/dist/index.js.map +1 -1
- package/server/node_modules/msgpackr/dist/index.min.js +1 -1
- package/server/node_modules/msgpackr/dist/index.min.js.map +1 -1
- package/server/node_modules/msgpackr/dist/node.cjs +36 -29
- package/server/node_modules/msgpackr/dist/node.cjs.map +1 -1
- package/server/node_modules/msgpackr/dist/test.js +63 -32
- package/server/node_modules/msgpackr/dist/test.js.map +1 -1
- package/server/node_modules/msgpackr/dist/unpack-no-eval.cjs +34 -28
- package/server/node_modules/msgpackr/dist/unpack-no-eval.cjs.map +1 -1
- package/server/node_modules/msgpackr/package.json +1 -1
- package/server/node_modules/msgpackr/unpack.js +34 -28
- package/server/{orphan-proposed-reconciler-DcgTPPFY.js → orphan-proposed-reconciler-CEW1maPl.js} +1 -1
- package/server/{orphan-proposed-reconciler-B6vJHxtX.js → orphan-proposed-reconciler-DfqHZftT.js} +23 -22
- package/server/package-lock.json +8 -8
- package/server/package.json +1 -1
- package/server/{pan-dir-DMzF5wne.js → pan-dir-DhgKfO86.js} +21 -6
- package/server/{paths-sJBSb7Ul.js → paths-BUuhi6jM.js} +17 -17
- package/server/{pending-lifecycle-claim-DilzGfgk.js → pending-lifecycle-claim-DJlA1rTR.js} +2 -2
- package/server/{persistent-logger-H_VjuOu7.js → persistent-logger-s8cbpFNV.js} +2 -2
- package/server/{pickup-DWhqzliO.js → pickup-2AxtB3dW.js} +1 -1
- package/server/{pipeline-membership-C88VBnhJ.js → pipeline-membership-2_okL5bm.js} +1 -1
- package/server/{pipeline-membership-D9SBvItj.js → pipeline-membership-Dqv6_0ig.js} +1 -1
- package/server/{pipeline-membership-gather-4eR-7Tqy.js → pipeline-membership-gather-4F1-tXKI.js} +1 -1
- package/server/{pipeline-membership-gather-CeVGnNJ2.js → pipeline-membership-gather-CtJ_7aGf.js} +149 -17
- package/server/{pipeline-notifier-DT6xLFao.js → pipeline-notifier-CO9rxJgB.js} +1 -1
- package/server/{pipeline-notifier-D0ALV6Nw.js → pipeline-notifier-DDfVBJhJ.js} +2 -2
- package/server/{post-merge-lifecycle-worker-8HIeS_J6.js → post-merge-lifecycle-worker-DmSOkeNp.js} +3 -3
- package/server/{project-pipelines-9SKt2bEc.js → project-pipelines-72WE8GVK.js} +2 -2
- package/server/{project-repos-B5pIphKg.js → project-repos-BAqDwtvi.js} +16 -11
- package/server/project-repos-Df90Zw7Y.js +3 -0
- package/server/projects-WqMWCdpa.js +3 -0
- package/server/{prompts-CgzMBvQF.js → prompts-XkL10m8M.js} +2 -2
- package/server/{providers-BJQSnAAp.js → providers-ClGPGkQ8.js} +15 -12
- package/server/providers-DFUOed8u.js +3 -0
- package/server/public/assets/{chunk-BO2N2NFS-D_pGACYN.js → chunk-BO2N2NFS-CeQUdPxr.js} +4 -4
- package/server/public/assets/{diagram-OG6HWLK6-BO6fe3hH.js → diagram-OG6HWLK6-B7rgk4yT.js} +1 -1
- package/server/public/assets/{dist-5zingMiA.js → dist-2RPazfXY.js} +3 -3
- package/server/public/assets/{dist-CVxhbI2E.js → dist-B9NInrVZ.js} +1 -1
- package/server/public/assets/{ganttDiagram-6RSMTGT7-Bgj4A7kp.js → ganttDiagram-6RSMTGT7-Bxp0gV14.js} +1 -1
- package/server/public/assets/{highlighted-body-OFNGDK62-DNPK7_cm.js → highlighted-body-OFNGDK62-CzoRTVlC.js} +1 -1
- package/server/public/assets/index-Cml-kHo6.css +1 -0
- package/server/public/assets/{index-DEpY-D1O.js → index-CvN8cEgs.js} +216 -215
- package/server/public/assets/{linear-BB0jQT16.js → linear-CFEEl3ND.js} +1 -1
- package/server/public/assets/mermaid-GHXKKRXX-CpV7nCBM.js +1 -0
- package/server/public/assets/{pieDiagram-4H26LBE5-DeGIzzpZ.js → pieDiagram-4H26LBE5-BeR8R0cr.js} +1 -1
- package/server/public/assets/{prod-XBLvikex.js → prod-CYjzjCrn.js} +4 -4
- package/server/public/assets/{quadrantDiagram-W4KKPZXB-BV9SLeWz.js → quadrantDiagram-W4KKPZXB-BpcTkFuW.js} +1 -1
- package/server/public/assets/{sankeyDiagram-5OEKKPKP-Dwja0gj8.js → sankeyDiagram-5OEKKPKP-Bx2ETEV5.js} +1 -1
- package/server/public/assets/{xychartDiagram-2RQKCTM6-DCB4qvfw.js → xychartDiagram-2RQKCTM6-BKgEAFaj.js} +1 -1
- package/server/public/index.html +2 -2
- package/server/{pull-requests-7BgLDsIo.js → pull-requests-B-KrUph5.js} +3 -3
- package/server/{pull-requests-Dq0y6IxE.js → pull-requests-DK5k92B4.js} +1 -1
- package/server/{queries-C-MUZaIy.js → queries-DVpl1vsU.js} +1212 -193
- package/server/{rally-CPysR4T_.js → rally-DbE561hD.js} +3 -3
- package/server/rally-O_st_X7n.js +3 -0
- package/server/{rally-api-8Ptlp2os.js → rally-api-CZLeEd2C.js} +2 -2
- package/server/{rally-api-CgosKdKL.js → rally-api-DaHtn5QN.js} +1 -1
- package/server/{rally-client-CCX0hADj.js → rally-client-C-MAl8ur.js} +1 -1
- package/server/{rally-client-iYMHWQD7.js → rally-client-Ch3zRsBX.js} +5 -5
- package/server/{reap-terminal-sessions-Qf-9LVQc.js → reap-terminal-sessions-C1n0ALRb.js} +2 -2
- package/server/{reap-terminal-sessions-4Xg9NGA8.js → reap-terminal-sessions-DegFS2p1.js} +2 -2
- package/server/{rebuild-stack-CMdgaylx.js → rebuild-stack-C9Li44A3.js} +20 -10
- package/server/{rebuild-stack-DqcOVmJO.js → rebuild-stack-qC0jCNm6.js} +2 -2
- package/server/{reconstruct-cache-CMZJ_Vjq.js → reconstruct-cache-BHyiAg02.js} +7 -7
- package/server/record-aVzu-LGm.js +3 -0
- package/server/record-update-CZh46a2f.js +617 -0
- package/server/{record-update-DhI7eySG.js → record-update-DtdJK2Iw.js} +1 -1
- package/server/recovery-trip-CSNWSLDn.js +77 -0
- package/server/recovery-trip-_16hFKv4.js +3 -0
- package/server/{release-engine-B2X9AfFC.js → release-engine-Be5MX5GP.js} +5 -5
- package/server/{release-set-G4XKyQ8K.js → release-set-DJv_O6PS.js} +3 -3
- package/server/{remote-BXarMvqf.js → remote-BMM3uH2J.js} +3 -3
- package/server/{remote-CUhyqjXk.js → remote-C0xVTHA5.js} +3 -3
- package/server/{remote-agents-CLZB3Coc.js → remote-agents-BIIoc5pD.js} +1 -1
- package/server/{remote-agents-Bba-MgSA.js → remote-agents-EUiZ26bj.js} +7 -7
- package/server/{remote-completion-CwAp79EC.js → remote-completion-BS4tJUn8.js} +13 -13
- package/server/resolver-BvHd6RE4.js +163 -0
- package/server/resume-9thEqAQR.js +3 -0
- package/server/{review-agent--pOptAEV.js → review-agent-BHGaBoBu.js} +29 -29
- package/server/{review-agent-BTCNkq2h.js → review-agent-CD3RQ-tc.js} +1 -1
- package/server/{review-artifacts-BNmw8dWE.js → review-artifacts-DyhajWso.js} +6 -6
- package/server/{review-context-DFxYOOJW.js → review-context-B-dlsPnx.js} +9 -9
- package/server/{review-convoy-liveness-BgU_1jJf.js → review-convoy-liveness-D7M-s_nS.js} +2 -2
- package/server/{review-status-Dma9SFaN.js → review-status-B6wYcOtP.js} +1 -1
- package/server/{review-status-CGvlA4o_.js → review-status-CKLk5aZ-.js} +308 -58
- package/server/{review-status-emit-DURrmGYX.js → review-status-emit-CJ7UmEVU.js} +3 -3
- package/server/{review-status-enrichment-8NiNXi5W.js → review-status-enrichment-DJRgGX7-.js} +3 -3
- package/server/review-status-limits-4EJDCGHO.js +7 -0
- package/server/{review-status-source-DIk1JSow.js → review-status-source-7nU3Z2wL.js} +1 -1
- package/server/{review-status-source-BLx_1siH.js → review-status-source-BsDYGfyv.js} +1 -1
- package/server/{review-status-sync-muT-EBp2.js → review-status-sync-BLssMTEW.js} +1 -1
- package/server/{review-status-sync-0GxOqeqF.js → review-status-sync-BxBeHRde.js} +35 -11
- package/server/{review-verdict-feedback-xJNdqBnX.js → review-verdict-feedback-5jWuzgpc.js} +90 -16
- package/server/{review-verdict-feedback-HwF6ODFy.js → review-verdict-feedback-HRY9P4bN.js} +1 -1
- package/server/{rollup-BQaol5TX.js → rollup-BGIrCEkU.js} +79 -44
- package/server/rollup-CZB4UL9q.js +3 -0
- package/server/{scanner-C-D2cFdX.js → scanner-DydjXPrz.js} +16 -9
- package/server/search-DdtIjAiu.js +395 -0
- package/server/{sequence-io-Bmf1EZM5.js → sequence-io-Fw-cLyDs.js} +4 -4
- package/server/{sequencer-agent-CigMyKh2.js → sequencer-agent-BcpGMt5x.js} +15 -10
- package/server/server.js +1258 -438
- package/server/{service-CD0DvFvD.js → service-BFFkGsG4.js} +58 -58
- package/server/{session-fork-B6cQ5eya.js → session-fork-D0V-3e5P.js} +2 -2
- package/server/{session-history-3ON_IJjm.js → session-history-Bta5l9jY.js} +5 -5
- package/server/{settings-PilbFZAM.js → settings-Ce8B1daF.js} +2 -2
- package/server/{settings-VN0qOh4U.js → settings-E3FnEIUx.js} +3 -3
- package/server/settings-eOOJpxi_.js +2 -0
- package/server/{shadow-engineering-DXvx77oE.js → shadow-engineering-Mt9nJO4i.js} +3 -3
- package/server/{shadow-state-CZBp7pwq.js → shadow-state-Bzj_AZCV.js} +1 -1
- package/server/{shadow-state-BBk_zacw.js → shadow-state-DrkhoVSx.js} +2 -2
- package/server/{shadow-utils-DdZ05AJS.js → shadow-utils-H1GfqP06.js} +2 -2
- package/server/{ship-log-7kJfjUX2.js → ship-log-CFUIo4PR.js} +1 -1
- package/server/{smart-compaction-8fA5k5XN.js → smart-compaction-DSTq-Wua.js} +1 -1
- package/server/{smart-compaction-ByhL9cRS.js → smart-compaction-Hzp3KCJX.js} +7 -7
- package/server/{spawn-planning-session-vLUJoFjy.js → spawn-planning-session-C0uSA2SL.js} +2 -2
- package/server/{spawn-planning-session-pcF-YeFE.js → spawn-planning-session-DN4son31.js} +23 -21
- package/server/{specialist-completion-B07XjWD2.js → specialist-completion-Cf6tpIh1.js} +1 -1
- package/server/{specialist-context-DJ-zFyL3.js → specialist-context-DEUEkjIQ.js} +5 -5
- package/server/{specialist-handoff-logger-aKSxbIgD.js → specialist-handoff-logger-D_LmQDj3.js} +2 -2
- package/server/{specialist-logs-Dae-n52_.js → specialist-logs-7Ynue0R7.js} +3 -3
- package/server/{specialists-KR3pKulN.js → specialists-CQwBEGlD.js} +1 -1
- package/server/{specialists-6PWdtWcg.js → specialists-DAjPgYs_.js} +504 -238
- package/server/{specialists-DUiExaxb.js → specialists-Hr6iW9fU.js} +18 -18
- package/server/{specialists-Bz-wFT7R.js → specialists-MOoeB4A8.js} +1 -1
- package/server/specs-Dl88cbKY.js +3 -0
- package/server/{src-B948bGVR.js → src-BYdwL_n-.js} +668 -64
- package/server/{src-vHy2-oCv.js → src-DQnkPN2i.js} +3 -3
- package/server/{src-rac0Mepv.js → src-DhfDV0o4.js} +6 -6
- package/server/{stack-health-DqLTiEu4.js → stack-health-D_iKwNRg.js} +107 -16
- package/server/stack-health-deVSdDwn.js +3 -0
- package/server/{stale-task-claims-Cab_Fo_Z.js → stale-task-claims-BYJGqhLI.js} +5 -5
- package/server/{staleness-CGTZyp6V.js → staleness-CopBDKnA.js} +1 -1
- package/server/{staleness-C-a5rBxF.js → staleness-D8WeMUHd.js} +1 -1
- package/server/{state-home-722Dkx92.js → state-home-DjN8qduI.js} +24 -3
- package/server/{state-mapping-CybR81Uf.js → state-mapping-DlM7OYRW.js} +1 -1
- package/server/{state-migrate-2u8wIpoL.js → state-migrate-a2p1gtD7.js} +4 -4
- package/server/state-mirror-Cv_XgvT5.js +121 -0
- package/server/{stuck-remediation-r1TJu68G.js → stuck-remediation-CXJX_kki.js} +1 -1
- package/server/{stuck-remediation-CC6q3eqQ.js → stuck-remediation-CbCRSz1v.js} +31 -732
- package/server/{substrate-bug-weights-service-CzIyyWFT.js → substrate-bug-weights-service-DxpopNd9.js} +3 -3
- package/server/{summary-fork-BqgmgPDt.js → summary-fork-B61fjRJn.js} +2 -2
- package/server/{summary-fork-Df2WFijM.js → summary-fork-B9pszUJN.js} +91 -10
- package/server/supervisor/{injection-budget-Cg_KIb3o.js → injection-budget-Ar7hgyJq.js} +1 -1
- package/server/supervisor/pty-supervisor.js +12 -3
- package/server/supervisor/{pty-token-BbjwEUUM.js → pty-token-CXCFU0Z8.js} +1 -1
- package/server/{supervisor-BxqSpjcN.js → supervisor-BvnxbuuF.js} +6 -4
- package/server/supervisor-C69kpqvd.js +2 -0
- package/server/{swarm-readiness-DfFxa9-n.js → swarm-readiness-vTw1kqGa.js} +3 -3
- package/server/{system-prerequisites-ICLSkhhZ.js → system-prerequisites-LLzTEqsK.js} +3 -3
- package/server/{teardown-workspace-DRdi_CPa.js → teardown-workspace-CqKKVJr1.js} +15 -15
- package/server/{test-agent-queue-A_-p-i0I.js → test-agent-queue-CWMq7oyG.js} +8 -7
- package/server/{test-verdict-BHgTAwIG.js → test-verdict-NdtgRBuA.js} +1 -1
- package/server/{test-verdict-C4i9aqEP.js → test-verdict-diIWE6hz.js} +15 -3
- package/server/{tldr-daemon-CvWXBhX1.js → tldr-daemon-B1Jhrtc8.js} +1 -1
- package/server/{tldr-daemon-wvsU6bKv.js → tldr-daemon-Bpls1CJB.js} +2 -2
- package/server/{tmux-CfDHob9M.js → tmux-CImZaX4q.js} +10 -16
- package/server/tmux-Cjpx8L8u.js +4 -0
- package/server/{token-DrxwytsZ.js → token-Bgpjo3tE.js} +2 -2
- package/server/token-util-BsjFll-k.js +3 -0
- package/server/{token-util-B48BlCba.js → token-util-BymbpkJp.js} +1 -1
- package/server/{tracker-config-BcPMElRB.js → tracker-config-4DaKVTfc.js} +2 -2
- package/server/{tracker-utils-CJ6BHjcD.js → tracker-utils-BDeAXC-q.js} +2 -2
- package/server/{traefik-connect-DZ6nMYMj.js → traefik-connect-CC5FyxYj.js} +1 -1
- package/server/{tunnel-Bp-dRHZz.js → tunnel-CDWkeceJ.js} +1 -1
- package/server/{tunnel-DUbUPElU.js → tunnel-CPf5M-Pc.js} +3 -3
- package/server/{typed-errors-DyjseiB6.js → typed-errors-9K7Dq_Vn.js} +1 -1
- package/server/{typed-errors-CKeoDdU3.js → typed-errors-DrS5fb5z.js} +1 -1
- package/server/{types-Cm5ASJbq.js → types-DzlUKiuf.js} +4 -3
- package/server/{types-Di8wdakq.js → types-kI9ik8XO.js} +1 -1
- package/server/{uat-promote-verification-CoJuh7XO.js → uat-promote-verification-c_pxoxEc.js} +5 -5
- package/server/{uat-train-4Q0k06CQ.js → uat-train-CWGxBdJO.js} +0 -0
- package/server/{uat-train-Dewoatps.js → uat-train-CfCYd2ve.js} +1 -1
- package/server/{validate-B0C8p66t.js → validate-f3ItVCfm.js} +3 -3
- package/server/{validation-hVOwQk8T.js → validation-5G_wQtea.js} +1 -1
- package/server/{validation-B_kIRfNe.js → validation-7tSiCM82.js} +4 -4
- package/server/{verification-artifact-BxlxTiYK.js → verification-artifact-9h9dH8uX.js} +1 -1
- package/server/{verification-artifact-D70AtckY.js → verification-artifact-C_4WJnf6.js} +1 -1
- package/server/{verification-runner-Bc3cJvpC.js → verification-runner-BV5F6wrA.js} +1 -1
- package/server/{verification-runner-KZTz6u72.js → verification-runner-D58KmBhK.js} +18 -38
- package/server/{vtt-parser-CE_i3Bcw.js → vtt-parser-2iT9OHa9.js} +1 -1
- package/server/{work-agent-prompt-ByrPAzOy.js → work-agent-prompt-D03s4DD1.js} +9 -9
- package/server/{workflows-D0vP1WrK.js → workflows-BMBwLYPV.js} +281 -98
- package/server/workflows-BOmWGpIh.js +2 -0
- package/server/{workspace-DQkRPLlQ.js → workspace-BgflNCH0.js} +3 -3
- package/server/{workspace-COWvdibH.js → workspace-Cn9ywfSW.js} +1 -1
- package/server/{workspace-anchor-drift-pwz23TI1.js → workspace-anchor-drift-C8Fy3shi.js} +1 -1
- package/server/{workspace-anchor-drift-DXYIAHzr.js → workspace-anchor-drift-CMiNncwq.js} +5 -8
- package/server/{workspace-config-BdZM4PvZ.js → workspace-config-aUc2nIz6.js} +1 -1
- package/server/{workspace-manager-BPgTrG66.js → workspace-manager-Bem7ZBs9.js} +521 -292
- package/server/workspace-manager-C0CpNh3t.js +3 -0
- package/server/{workspace-metadata-CdjzAP8x.js → workspace-metadata-C5iSlPRo.js} +1 -1
- package/server/{workspace-metadata-DkO_iTLo.js → workspace-metadata-UKmTYmDQ.js} +2 -2
- package/server/{workspaces-CRBJikLp.js → workspaces-DqxgwDZ8.js} +143 -113
- package/sync-sources/hooks/notification-hook +12 -1
- package/sync-sources/hooks/pan-hook-lib.sh +226 -0
- package/sync-sources/hooks/session-start-hook +31 -4
- package/sync-sources/hooks/work-agent-stop-hook +23 -1
- package/sync-sources/skills/pan-memory/SKILL.md +19 -3
- package/sync-sources/skills/pan-projects/SKILL.md +9 -0
- package/sync-sources/skills/pan-restart/SKILL.md +26 -7
- package/sync-sources/skills/pan-workspace/SKILL.md +77 -0
- package/server/activity-logger-CMthG6Vd.js +0 -3
- package/server/agent-state-CYXJVG72.js +0 -3
- package/server/agents-ePFVoZbu.js +0 -3
- package/server/archive-planning-B2XplFzT.js +0 -2
- package/server/cli-CjOCSnfj.js +0 -3
- package/server/deacon-swarm-B1XkIvfr.js +0 -2
- package/server/delivery-BX9HR4wQ.js +0 -3
- package/server/dist-B3YPQa5A.js +0 -3
- package/server/event-store-5UKzh9Jf.js +0 -3
- package/server/forge-B5o319qI.js +0 -3
- package/server/fts-db-IVc4_M3f.js +0 -146
- package/server/hume-VUCNbTgn.js +0 -3
- package/server/inspect-agent-CUwVmr2h.js +0 -2
- package/server/merge-ops-1abz6O_P.js +0 -2
- package/server/merge-rebase-CJJVAJuz.js +0 -2
- package/server/node_modules/brace-expansion/.tap/coverage/8b906b8c-e21f-40b5-8c0d-214d8c2682c5.json +0 -757
- package/server/node_modules/brace-expansion/.tap/processinfo/8b906b8c-e21f-40b5-8c0d-214d8c2682c5.json +0 -719
- package/server/node_modules/brace-expansion/ADVISORY-CVE-2026-14257.md +0 -107
- package/server/node_modules/brace-expansion/dist/commonjs/index.d.ts +0 -8
- package/server/node_modules/brace-expansion/dist/commonjs/index.d.ts.map +0 -1
- package/server/node_modules/brace-expansion/dist/commonjs/index.js +0 -263
- package/server/node_modules/brace-expansion/dist/commonjs/index.js.map +0 -1
- package/server/node_modules/brace-expansion/dist/commonjs/package.json +0 -3
- package/server/node_modules/brace-expansion/dist/esm/index.d.ts +0 -8
- package/server/node_modules/brace-expansion/dist/esm/index.d.ts.map +0 -1
- package/server/node_modules/brace-expansion/dist/esm/index.js +0 -259
- package/server/node_modules/brace-expansion/dist/esm/index.js.map +0 -1
- package/server/node_modules/brace-expansion/dist/esm/package.json +0 -3
- package/server/project-repos-DPjOdfPa.js +0 -3
- package/server/projects-_n3Zui6K.js +0 -3
- package/server/providers-BI1mOBQ4.js +0 -3
- package/server/public/assets/index-Ddkcz3WT.css +0 -1
- package/server/public/assets/mermaid-GHXKKRXX-BzPfaQJ1.js +0 -1
- package/server/rally-D_VW4bJv.js +0 -3
- package/server/record-BTwWhtBb.js +0 -3
- package/server/record-update-DaOKS7Wb.js +0 -277
- package/server/recovery-trip-DDH-02ng.js +0 -44
- package/server/resume-mOREjlYu.js +0 -3
- package/server/rollup-BR4t_wck.js +0 -3
- package/server/settings-CVmWiJ-r.js +0 -2
- package/server/specs--enInima.js +0 -3
- package/server/stack-health-BikqHSjn.js +0 -3
- package/server/supervisor-B4anCCSm.js +0 -2
- package/server/tmux-Ctk6RV5l.js +0 -3
- package/server/token-util-D411CAq9.js +0 -3
- package/server/workflows-DtDX08ed.js +0 -2
- package/server/workspace-manager-C1F3XsnS.js +0 -3
|
@@ -1,66 +1,69 @@
|
|
|
1
1
|
import { i as __require, t as __commonJSMin } from "./rolldown-runtime-DNCzzKnI.js";
|
|
2
|
-
import {
|
|
3
|
-
import { n as init_build_info, t as getBuildInfo } from "./build-info-
|
|
4
|
-
import { n as getDashboardIdentity, t as recordDeaconNudge } from "./deacon-nudge-log-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { o as
|
|
15
|
-
import { n as
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import { i as
|
|
19
|
-
import {
|
|
20
|
-
import { i as
|
|
21
|
-
import {
|
|
22
|
-
import { f as
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import { a as
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import { n as
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import { a as
|
|
39
|
-
import {
|
|
40
|
-
import { a as
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
44
|
-
import { n as
|
|
45
|
-
import {
|
|
46
|
-
import { n as
|
|
47
|
-
import {
|
|
48
|
-
import { n as
|
|
49
|
-
import { r as
|
|
50
|
-
import { r as
|
|
51
|
-
import { t as
|
|
52
|
-
import {
|
|
53
|
-
import {
|
|
54
|
-
import {
|
|
2
|
+
import { Cn as resolveProjectPath, Hr as AGENTS_DIR, Ot as getMainDivergence, Q as readIssueRecordSync, Sn as resolveProjectFromIssueSync, St as init_auto_commit, Tt as reconcileStatePlaneDrift, Vr as init_errors, Zr as OVERDECK_HOME, b as DEFAULT_CONFIG$1, cn as init_projects, dn as listProjects, f as loadConfigSync, fn as listProjectsSync, hi as init_paths, kt as init_state_plane, mn as loadProjectsConfigSync, nn as getProjectSync, q as init_record, s as init_load, x as init_defaults, yi as sessionFilePath } from "./config-yaml-BSCqwmX0.js";
|
|
3
|
+
import { n as init_build_info, t as getBuildInfo } from "./build-info-CJg813Hm.js";
|
|
4
|
+
import { n as getDashboardIdentity, t as recordDeaconNudge } from "./deacon-nudge-log-BND_97Wo.js";
|
|
5
|
+
import { f as init_config, m as loadConfigSync$1, p as loadConfig$1 } from "./config-DnLJATZk.js";
|
|
6
|
+
import { a as emitActivityEntrySync, c as init_activity_logger, o as emitActivityTtsSync, r as emitActivityEntryOnce } from "./activity-logger-Co5qljIj.js";
|
|
7
|
+
import { a as recordLockPath, i as readOwner, n as init_fs_lock } from "./fs-lock-D_GeJtXl.js";
|
|
8
|
+
import { i as updateIssueRecord, r as init_record_update } from "./record-update-CZh46a2f.js";
|
|
9
|
+
import { C as init_tmux, E as killSession, F as querySessionSync, H as sessionExistsSync, M as listSessions, R as sendKeys, T as isPaneDead, V as sessionExists, j as listSessionNames, k as listPaneValues, r as capturePane, z as sendKeysAsync } from "./tmux-CImZaX4q.js";
|
|
10
|
+
import { a as init_event_store, i as initEventStore } from "./event-store-D_AR-Y78.js";
|
|
11
|
+
import { D as projectLegacySystemHealthSummary, t as init_src } from "./src-BYdwL_n-.js";
|
|
12
|
+
import { B as reviewGatesPassedSync, C as setReviewStatusSync, G as findWorkspaceVerdictConflicts, H as findBlockingFindings, J as readJournalStatusSync, K as init_review_status_record_sync, R as init_review_dispatch_decision, U as init_review_findings, W as drainWorkspaceVerdictFallback, Y as readWorkspaceVerdictFallback, d as getReviewStatusSync, h as loadReviewStatuses, p as init_review_status, z as needsReviewDispatch } from "./review-status-CKLk5aZ-.js";
|
|
13
|
+
import { n as logAgentLifecycleSync, r as logDeaconEventSync, t as init_persistent_logger } from "./persistent-logger-s8cbpFNV.js";
|
|
14
|
+
import { c as listAllAgentsSync, d as isTerminalIssueStage, o as init_agents, u as getIssueStageSync } from "./agents-Dls7tfJH.js";
|
|
15
|
+
import { At as countRunningAgents, Dt as init_termination, Er as markAgentRunningState, Ft as init_concurrency, Ir as setAgentPausedSync, It as releaseAdvancingSlot, Lr as setAgentYieldedSync, Mr as resetAgentFailureCount, Mt as describeRunningAgents, Nr as saveAgentState, Ot as stopAgent, Pr as saveAgentStateSync, Pt as getConcurrencyLimits, Rt as resetPatrolDispatchBudget, Ut as init_memory_verdict_cache, Vt as workResumeSlotsAvailable, Wt as setCachedMemoryVerdict, Yt as deliverInitialPromptWithRetry, _ as init_linux, a as listRunningAgentsSync, b as init_agents$1, br as getAgentStateSync, c as getRuntimeCensus, ci as init_codex_auth, ct as init_context_overflow, dt as init_messaging, ei as getAgentRuntimeState, er as buildResumeContinueMessage, ft as messageAgent, g as LINUX_MEMORY_PRESSURE_DEFAULTS, gr as getAgentDir, h as init_collector, i as listRunningAgents, kr as recordAgentFailure, li as paneShowsCodexAuthBurn, m as createHostHealthCollector, mr as clearYieldForResumeSync, n as init_queries, ni as init_runtime_state, nn as init_transcript_landing, oi as applyCodexAuthBurnFlag, pr as clearAgentTroubledSync, r as listAgentStates, ri as saveAgentRuntimeState, s as descendantPidsForSession, st as resumeAgent, ti as getAgentRuntimeStateSync, tn as captureTranscriptUserRecordSnapshot, u as init_runtime_census, ut as isContextOverflowTail, v as DARWIN_MEMORY_PRESSURE_DEFAULTS, vr as getAgentState, xr as init_agent_state, y as init_darwin, zt as tryReserveAdvancingSlot } from "./queries-DVpl1vsU.js";
|
|
16
|
+
import { o as getRuntimeSnapshot, s as init_agent_runtime_mirror } from "./session-history-Bta5l9jY.js";
|
|
17
|
+
import { n as resolveGitHubIssueSync, t as init_tracker_utils } from "./tracker-utils-BDeAXC-q.js";
|
|
18
|
+
import { i as ensureInternalTokenSync, o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-AvXePaQT.js";
|
|
19
|
+
import { c as init_review_status_sync, l as markWorkspaceStuck } from "./review-status-sync-BxBeHRde.js";
|
|
20
|
+
import { i as readReviewStatusMap, n as init_review_status_source, t as classifyAdvancingSessionLifecycle } from "./review-status-source-7nU3Z2wL.js";
|
|
21
|
+
import { d as PENDING_PROMOTION_FILENAME, f as WORKSPACE_RUNTIME_DIRNAME, m as init_types } from "./types-DzlUKiuf.js";
|
|
22
|
+
import { _ as markMerged, c as init_merge_sync, f as listActiveAutoMerges, m as listProblemAutoMerges, t as cancelPending } from "./merge-sync-BEdfsQV4.js";
|
|
23
|
+
import { i as init_merge_set, r as getMergeSetSync } from "./merge-set-DsLjjLEV.js";
|
|
24
|
+
import { C as init_specs, S as findSpecByIssue, f as readPlanSync, h as readWorkspacePlanSync, o as findWorkspaceDraftPlanSync, s as init_io } from "./io-mxOWMZ7I.js";
|
|
25
|
+
import { D as setSetting, O as stampBootReconciliation, _ as setBootReconciliationGrace, c as init_control_settings, g as setBootReconciliationDecision, o as getLastCleanShutdownAt, r as getBootReconciliationState, s as getSetting, u as isDeaconGloballyPaused } from "./control-settings-DVf6pKyv.js";
|
|
26
|
+
import { f as DockerStatsCollector, p as init_docker_stats } from "./stack-health-D_iKwNRg.js";
|
|
27
|
+
import { l as init_dag, o as getDispatchableItems } from "./dag-BYiFMqpU.js";
|
|
28
|
+
import { a as loadCloisterConfigSync, i as loadCloisterConfig, r as init_config$1 } from "./config-DvM8jtQK.js";
|
|
29
|
+
import { a as findRecreatedLegacyStatePaths, o as init_state_home } from "./state-home-DjN8qduI.js";
|
|
30
|
+
import { M as withConcurrencyLimit, j as init_concurrency$1 } from "./github-app-D2QuvZ3j.js";
|
|
31
|
+
import { n as __filename, r as init_esm_shims } from "./esm-shims-Bzy4ZzNU.js";
|
|
32
|
+
import { i as init_staleness, r as computeBuildStaleness } from "./staleness-D8WeMUHd.js";
|
|
33
|
+
import { a as isAgentIdleForNudge, t as checkStuckAgentRemediation } from "./stuck-remediation-CbCRSz1v.js";
|
|
34
|
+
import { a as pidsWithCwdUnder, i as sweepAutoCloseOutCache, n as pruneTerminalStoppedAgents, r as getAutoCloseOutCanonicalState } from "./agent-gc-BmYeT6eH.js";
|
|
35
|
+
import { n as init_issue_closed, r as isIssueClosed } from "./issue-closed-Bj_bCv_0.js";
|
|
36
|
+
import { n as getForgeAdapter, r as init_forge } from "./forge-c8LeC-tw.js";
|
|
37
|
+
import { a as observeForgeMergeState, i as init_merge_completeness } from "./merge-completeness-C1FevcDT.js";
|
|
38
|
+
import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-DdsBdtNL.js";
|
|
39
|
+
import { n as resolveIssueFeedbackTarget, r as surfaceIssueFeedbackNeedsYou, t as init_feedback_target } from "./feedback-target-DoRCR3L-.js";
|
|
40
|
+
import { a as init_review_monitor, i as REVIEW_SUB_ROLES, n as init_review_convoy_liveness, r as reviewTimestampMs, t as evaluateReviewConvoyLiveness } from "./review-convoy-liveness-D7M-s_nS.js";
|
|
41
|
+
import { J as parseReviewerSessionName, U as getTmuxSessionName, g as getAllProjectSpecialistStatuses, t as init_specialists } from "./specialists-Hr6iW9fU.js";
|
|
42
|
+
import { a as inferBranchFromWorkspace, i as findWorkspacePath } from "./archive-planning-Cq7cyinS.js";
|
|
43
|
+
import { n as init_merge_verification, r as shouldSkipDispatchAsMerged } from "./merge-verification-DN1Ov9bU.js";
|
|
44
|
+
import { a as findVerdictReportAsync, i as findVerdictReport, n as init_review_verdict_feedback, o as init_review_verdict_report, s as parseVerdictReport, t as deliverReviewVerdictFeedback } from "./review-verdict-feedback-5jWuzgpc.js";
|
|
45
|
+
import { _ as init_label_reconciler, a as gatherProjectLensSignals, s as init_pipeline_membership_gather, v as reconcilePipelineLabelsPatrol } from "./pipeline-membership-gather-CtJ_7aGf.js";
|
|
46
|
+
import { n as init_pipeline_membership, r as resolvePipelineMembership } from "./pipeline-membership-Dqv6_0ig.js";
|
|
47
|
+
import { i as init_conflict_gate, o as probeBranchConflictPaths } from "./conflict-gate-WfVqgalf.js";
|
|
48
|
+
import { n as reconcileTraefikNetworks, t as init_traefik_connect } from "./traefik-connect-CC5FyxYj.js";
|
|
49
|
+
import { g as decideAgentAutonomousRedrive, r as coordinateSwarmSlots, y as listFeatureWorkspaces } from "./deacon-swarm-rqrl4TMs.js";
|
|
50
|
+
import { i as recordRecoveryFailure, n as findRecoveryTrip, r as init_recovery_trip } from "./recovery-trip-CSNWSLDn.js";
|
|
51
|
+
import { n as isExplicitNoResumeRequest, t as init_no_resume_mode } from "./no-resume-mode-DUR7Hi98.js";
|
|
52
|
+
import { r as init_in_flight_guard, t as createInFlightGuard } from "./in-flight-guard-CG2Eo-rr.js";
|
|
53
|
+
import { r as reconcileClosedIssueAgents } from "./closed-issue-reaper-C5Zn4GRS.js";
|
|
54
|
+
import { t as recordDeadEndNeedsYou } from "./dead-end-trip-DSF23CLX.js";
|
|
55
|
+
import { a as spawnWorkAgentThroughAgentsEndpoint, i as reconcileOrphanProposedSpecs, o as triggerRebuildAndStart } from "./orphan-proposed-reconciler-DfqHZftT.js";
|
|
56
|
+
import { n as reconcileIdleWorkspaceStacks } from "./idle-stack-reaper-CJ1ygW0p.js";
|
|
57
|
+
import { a as recordUnsignaledTestEscalation, i as readTestVerdictArtifact, n as decideUnsignaledTestAction, r as init_test_verdict } from "./test-verdict-diIWE6hz.js";
|
|
55
58
|
import { createRequire } from "node:module";
|
|
56
|
-
import { join } from "node:path";
|
|
59
|
+
import { dirname, join } from "node:path";
|
|
57
60
|
import { Effect } from "effect";
|
|
58
61
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "fs";
|
|
59
62
|
import { basename as basename$1, dirname as dirname$1, join as join$1 } from "path";
|
|
60
63
|
import { cpus, loadavg } from "os";
|
|
61
64
|
import { freemem as freemem$1, homedir as homedir$1, platform as platform$1, totalmem as totalmem$1 } from "node:os";
|
|
62
65
|
import { closeSync as closeSync$1, existsSync as existsSync$1, openSync as openSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, unlinkSync as unlinkSync$1, writeFileSync as writeFileSync$1 } from "node:fs";
|
|
63
|
-
import { readFile } from "node:fs/promises";
|
|
66
|
+
import { mkdir, readFile, readdir, rename, rm, stat as stat$1, writeFile } from "node:fs/promises";
|
|
64
67
|
import { readFile as readFile$1, readdir as readdir$1, writeFile as writeFile$1 } from "fs/promises";
|
|
65
68
|
import { exec, execFile, execFileSync, spawn } from "node:child_process";
|
|
66
69
|
import { promisify } from "node:util";
|
|
@@ -70,11 +73,12 @@ import { layer } from "@effect/platform-node/NodeServices";
|
|
|
70
73
|
//#region ../../lib/agents/health.ts
|
|
71
74
|
init_paths();
|
|
72
75
|
init_errors();
|
|
73
|
-
init_activity_logger();
|
|
74
76
|
init_projects();
|
|
75
77
|
init_state_plane();
|
|
76
78
|
init_auto_commit();
|
|
77
79
|
init_record();
|
|
80
|
+
init_config();
|
|
81
|
+
init_activity_logger();
|
|
78
82
|
init_tmux();
|
|
79
83
|
init_src();
|
|
80
84
|
init_persistent_logger();
|
|
@@ -21785,7 +21789,6 @@ new ((/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
21785
21789
|
* stopSmeeProcess();
|
|
21786
21790
|
* isSmeeProcessRunning();
|
|
21787
21791
|
*/
|
|
21788
|
-
init_config();
|
|
21789
21792
|
const SMEE_URL_PATH = join(homedir$1(), ".overdeck", "github-app", "smee-url");
|
|
21790
21793
|
const SMEE_PID_PATH = join(homedir$1(), ".overdeck", "github-app", "smee.pid");
|
|
21791
21794
|
const SMEE_LOG_PATH = join(homedir$1(), ".overdeck", "logs", "smee.log");
|
|
@@ -23158,9 +23161,13 @@ async function assessMemoryPressure() {
|
|
|
23158
23161
|
}
|
|
23159
23162
|
//#endregion
|
|
23160
23163
|
//#region ../../lib/cloister/agent-grace.ts
|
|
23164
|
+
init_fs_lock();
|
|
23161
23165
|
init_record_update();
|
|
23162
23166
|
init_internal_token();
|
|
23167
|
+
init_types();
|
|
23163
23168
|
init_review_findings();
|
|
23169
|
+
init_specs();
|
|
23170
|
+
init_io();
|
|
23164
23171
|
init_control_settings();
|
|
23165
23172
|
const WORK_LAUNCHER_GRACE_MS = 12e4;
|
|
23166
23173
|
function isStartingWithinGrace(state, now = Date.now(), graceMs = WORK_LAUNCHER_GRACE_MS) {
|
|
@@ -23211,7 +23218,7 @@ async function checkInspectAgentTimeouts(now = /* @__PURE__ */ new Date()) {
|
|
|
23211
23218
|
console.warn(`[deacon] Failed to kill inspect session ${sessionName}: ${msg}`);
|
|
23212
23219
|
});
|
|
23213
23220
|
try {
|
|
23214
|
-
const { messageAgent } = await import("./agents-
|
|
23221
|
+
const { messageAgent } = await import("./agents-IPSa5kzn.js");
|
|
23215
23222
|
await messageAgent(`agent-${issueId.toLowerCase()}`, verdict, "deacon:inspect-watchdog");
|
|
23216
23223
|
} catch (err) {
|
|
23217
23224
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -23405,7 +23412,7 @@ async function maybeProactivelyCompactContext(sessionName, now) {
|
|
|
23405
23412
|
if (!agentState?.workspace || !sessionId || !agentState.model) return null;
|
|
23406
23413
|
let usage = null;
|
|
23407
23414
|
try {
|
|
23408
|
-
const { computeContextUsage } = await import("./conversation-service-
|
|
23415
|
+
const { computeContextUsage } = await import("./conversation-service-DnUyIiLb.js");
|
|
23409
23416
|
usage = await computeContextUsage(sessionFilePath(agentState.workspace, sessionId), agentState.model);
|
|
23410
23417
|
} catch {
|
|
23411
23418
|
return null;
|
|
@@ -23504,9 +23511,9 @@ async function checkApiErrorAgents() {
|
|
|
23504
23511
|
}
|
|
23505
23512
|
if (!tmuxOutput.includes("❯")) continue;
|
|
23506
23513
|
try {
|
|
23507
|
-
const { maybeContinueCompactedAgent } = await import("./compaction-continuation-
|
|
23508
|
-
const { findLastCompactBoundary } = await import("./conversation-service-
|
|
23509
|
-
const { deliverAgentMessage } = await import("./delivery-
|
|
23514
|
+
const { maybeContinueCompactedAgent } = await import("./compaction-continuation-DZD9ukSE.js");
|
|
23515
|
+
const { findLastCompactBoundary } = await import("./conversation-service-DnUyIiLb.js");
|
|
23516
|
+
const { deliverAgentMessage } = await import("./delivery-CsbQdZkS.js");
|
|
23510
23517
|
const continued = await maybeContinueCompactedAgent({
|
|
23511
23518
|
agentId: sessionName,
|
|
23512
23519
|
tmuxOutput,
|
|
@@ -23557,13 +23564,13 @@ async function checkApiErrorAgents() {
|
|
|
23557
23564
|
const st = getAgentStateSync(sessionName);
|
|
23558
23565
|
const sid = st?.sessionId ?? runtimeState?.claudeSessionId;
|
|
23559
23566
|
if (st?.workspace && sid && st.model) {
|
|
23560
|
-
const { computeContextUsage } = await import("./conversation-service-
|
|
23567
|
+
const { computeContextUsage } = await import("./conversation-service-DnUyIiLb.js");
|
|
23561
23568
|
const usage = await computeContextUsage(sessionFilePath(st.workspace, sid), st.model);
|
|
23562
23569
|
if (usage && usage.percentUsed < 85) recoveredPct = usage.percentUsed;
|
|
23563
23570
|
}
|
|
23564
23571
|
} catch {}
|
|
23565
23572
|
if (recoveredPct !== null) {
|
|
23566
|
-
const { clearWorkspaceStuck } = await import("./review-status-sync-
|
|
23573
|
+
const { clearWorkspaceStuck } = await import("./review-status-sync-BLssMTEW.js");
|
|
23567
23574
|
clearWorkspaceStuck(issueId);
|
|
23568
23575
|
stuckOverflowNativeRecoveryState.delete(sessionName);
|
|
23569
23576
|
actions.push(`Context overflow recovery: cleared stuck flag for ${sessionName} (context back to ${Math.round(recoveredPct)}%)`);
|
|
@@ -23579,7 +23586,7 @@ async function checkApiErrorAgents() {
|
|
|
23579
23586
|
rec.attempts += 1;
|
|
23580
23587
|
rec.lastAttempt = now;
|
|
23581
23588
|
stuckOverflowNativeRecoveryState.set(sessionName, rec);
|
|
23582
|
-
const { resumeAgent } = await import("./agents-
|
|
23589
|
+
const { resumeAgent } = await import("./agents-IPSa5kzn.js");
|
|
23583
23590
|
const recovered = await resumeAgent(sessionName, void 0, { compact: true });
|
|
23584
23591
|
if (recovered.success) {
|
|
23585
23592
|
stuckOverflowNativeRecoveryState.delete(sessionName);
|
|
@@ -23627,7 +23634,7 @@ async function checkApiErrorAgents() {
|
|
|
23627
23634
|
}
|
|
23628
23635
|
const compactAttempts = (ov?.compactAttempts ?? 0) + 1;
|
|
23629
23636
|
if (issueId !== null) {
|
|
23630
|
-
const { resumeAgent } = await import("./agents-
|
|
23637
|
+
const { resumeAgent } = await import("./agents-IPSa5kzn.js");
|
|
23631
23638
|
const resumeResult = await resumeAgent(sessionName, void 0, { compact: true });
|
|
23632
23639
|
contextOverflowRecoveryState.set(sessionName, {
|
|
23633
23640
|
lastAttempt: now,
|
|
@@ -23746,7 +23753,7 @@ function isStuckMergingState(status, now) {
|
|
|
23746
23753
|
}
|
|
23747
23754
|
async function readSpecStatus(projectPath, issueId) {
|
|
23748
23755
|
try {
|
|
23749
|
-
const { findSpecByIssue } = await import("./specs
|
|
23756
|
+
const { findSpecByIssue } = await import("./specs-Dl88cbKY.js");
|
|
23750
23757
|
return (await Effect.runPromise(findSpecByIssue(projectPath, issueId)))?.status;
|
|
23751
23758
|
} catch {
|
|
23752
23759
|
return;
|
|
@@ -23828,7 +23835,7 @@ async function reconcileStuckMergingStates() {
|
|
|
23828
23835
|
reviewGatesPassed: reviewGatesPassedSync,
|
|
23829
23836
|
setReviewStatus: setReviewStatusSync,
|
|
23830
23837
|
enqueuePostMerge: async (issueId, projectPath, branch) => {
|
|
23831
|
-
const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-
|
|
23838
|
+
const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-DmSOkeNp.js");
|
|
23832
23839
|
return enqueuePostMergeLifecycle(issueId, projectPath, branch);
|
|
23833
23840
|
},
|
|
23834
23841
|
warn: (message) => console.warn(message)
|
|
@@ -24073,7 +24080,7 @@ async function reconcileStaleMergeStatus() {
|
|
|
24073
24080
|
].includes(status.mergeStatus ?? "") || ["merging", "failed"].includes(mergeSet?.status ?? "");
|
|
24074
24081
|
let specStatus;
|
|
24075
24082
|
try {
|
|
24076
|
-
const { findSpecByIssue } = await import("./specs
|
|
24083
|
+
const { findSpecByIssue } = await import("./specs-Dl88cbKY.js");
|
|
24077
24084
|
const spec = await Effect.runPromise(findSpecByIssue(project.projectPath, issueId));
|
|
24078
24085
|
specStatus = spec?.status;
|
|
24079
24086
|
if (spec && (spec.status === "completed" || spec.status === "cancelled")) {
|
|
@@ -24083,7 +24090,7 @@ async function reconcileStaleMergeStatus() {
|
|
|
24083
24090
|
} catch {}
|
|
24084
24091
|
const branch = `feature/${issueId.toLowerCase()}`;
|
|
24085
24092
|
if (postMergeIncomplete) {
|
|
24086
|
-
const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-
|
|
24093
|
+
const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-DmSOkeNp.js");
|
|
24087
24094
|
const action = enqueuePostMergeLifecycle(issueId, project.projectPath, branch);
|
|
24088
24095
|
if (action) actions.push(action);
|
|
24089
24096
|
continue;
|
|
@@ -24095,7 +24102,7 @@ async function reconcileStaleMergeStatus() {
|
|
|
24095
24102
|
} catch {}
|
|
24096
24103
|
if (!isMerged) isMerged = (await observeGitHubBranchMerge(issueId, branch, project.projectPath)).merged;
|
|
24097
24104
|
if (shouldObserveForge && mergeRelevant) try {
|
|
24098
|
-
const observation = await (await import("./merge-completeness-
|
|
24105
|
+
const observation = await (await import("./merge-completeness-BfRwFjRx.js")).observeForgeMergeState(issueId);
|
|
24099
24106
|
const blocker = observation.repos.find((repo) => repo.state === "unverifiable");
|
|
24100
24107
|
if (blocker) {
|
|
24101
24108
|
console.warn(`[deacon] ${issueId}: forge merge state is unverifiable — ${blocker.reason}`);
|
|
@@ -24122,7 +24129,7 @@ async function reconcileStaleMergeStatus() {
|
|
|
24122
24129
|
const msg = `Reconciled stale mergeStatus for ${issueId} — branch ${branch} is merged to main`;
|
|
24123
24130
|
actions.push(msg);
|
|
24124
24131
|
console.log(`[deacon] ${msg}`);
|
|
24125
|
-
const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-
|
|
24132
|
+
const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-DmSOkeNp.js");
|
|
24126
24133
|
const action = enqueuePostMergeLifecycle(issueId, project.projectPath, branch);
|
|
24127
24134
|
if (action) actions.push(action);
|
|
24128
24135
|
}
|
|
@@ -24145,7 +24152,7 @@ const falseMergedReset = /* @__PURE__ */ new Set();
|
|
|
24145
24152
|
async function reconcileFalseMerged() {
|
|
24146
24153
|
const actions = [];
|
|
24147
24154
|
try {
|
|
24148
|
-
const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-
|
|
24155
|
+
const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CpQSDlv8.js");
|
|
24149
24156
|
if (!isGitHubAppConfigured()) return actions;
|
|
24150
24157
|
const statuses = loadReviewStatuses();
|
|
24151
24158
|
for (const [issueId, status] of Object.entries(statuses)) {
|
|
@@ -24190,7 +24197,7 @@ const CLOSED_PR_RECONCILE_COOLDOWN_MS = 600 * 1e3;
|
|
|
24190
24197
|
async function reconcileClosedPrReadyForMerge() {
|
|
24191
24198
|
const actions = [];
|
|
24192
24199
|
try {
|
|
24193
|
-
const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-
|
|
24200
|
+
const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CpQSDlv8.js");
|
|
24194
24201
|
if (!isGitHubAppConfigured()) return actions;
|
|
24195
24202
|
const statuses = loadReviewStatuses();
|
|
24196
24203
|
const now = Date.now();
|
|
@@ -24262,7 +24269,7 @@ const STALE_MERGE_BLOCKER_COOLDOWN_MS = 120 * 1e3;
|
|
|
24262
24269
|
async function reconcileStaleMergeBlockers() {
|
|
24263
24270
|
const actions = [];
|
|
24264
24271
|
try {
|
|
24265
|
-
const { resolveConflictGate, buildRealConflictGateDeps } = await import("./conflict-gate-
|
|
24272
|
+
const { resolveConflictGate, buildRealConflictGateDeps } = await import("./conflict-gate-DXa_L28t.js");
|
|
24266
24273
|
const statuses = loadReviewStatuses();
|
|
24267
24274
|
const now = Date.now();
|
|
24268
24275
|
const deps = buildRealConflictGateDeps();
|
|
@@ -24405,7 +24412,7 @@ async function checkFailedMergeRetry() {
|
|
|
24405
24412
|
if (ciEntry.count === 5) {
|
|
24406
24413
|
console.log(`[deacon] CI check failure for ${issueId} — retries exhausted, notifying work agent`);
|
|
24407
24414
|
const ciNotes = status.mergeNotes || "CI checks are failing on the PR";
|
|
24408
|
-
const { writeFeedbackFile } = await import("./feedback-writer-
|
|
24415
|
+
const { writeFeedbackFile } = await import("./feedback-writer-CTSuA6lw.js");
|
|
24409
24416
|
const ciFileResult = await Effect.runPromise(writeFeedbackFile({
|
|
24410
24417
|
issueId,
|
|
24411
24418
|
specialist: "merge-agent",
|
|
@@ -24437,7 +24444,7 @@ async function checkFailedMergeRetry() {
|
|
|
24437
24444
|
ciRetryMap.set(issueId, ciEntry);
|
|
24438
24445
|
console.log(`[deacon] CI check failure for ${issueId} — notifying agent to re-submit (attempt ${ciEntry.count}/5)`);
|
|
24439
24446
|
const ciNotes = status.mergeNotes || "CI checks are failing on the PR";
|
|
24440
|
-
const { writeFeedbackFile } = await import("./feedback-writer-
|
|
24447
|
+
const { writeFeedbackFile } = await import("./feedback-writer-CTSuA6lw.js");
|
|
24441
24448
|
const ciFileResult2 = await Effect.runPromise(writeFeedbackFile({
|
|
24442
24449
|
issueId,
|
|
24443
24450
|
specialist: "merge-agent",
|
|
@@ -24465,7 +24472,7 @@ async function checkFailedMergeRetry() {
|
|
|
24465
24472
|
const lastNudge = timeoutNudgeCooldowns.get(issueIdForFb);
|
|
24466
24473
|
if (!lastNudge || now - lastNudge >= TIMEOUT_NUDGE_COOLDOWN_MS) {
|
|
24467
24474
|
const timeoutNotes = status.mergeNotes;
|
|
24468
|
-
const { writeFeedbackFile } = await import("./feedback-writer-
|
|
24475
|
+
const { writeFeedbackFile } = await import("./feedback-writer-CTSuA6lw.js");
|
|
24469
24476
|
await Effect.runPromise(writeFeedbackFile({
|
|
24470
24477
|
issueId: issueIdForFb,
|
|
24471
24478
|
specialist: "merge-agent",
|
|
@@ -24570,7 +24577,7 @@ async function autoCloseOut(now = /* @__PURE__ */ new Date()) {
|
|
|
24570
24577
|
} } : {}
|
|
24571
24578
|
};
|
|
24572
24579
|
try {
|
|
24573
|
-
const { closeOut } = await import("./workflows-
|
|
24580
|
+
const { closeOut } = await import("./workflows-BOmWGpIh.js");
|
|
24574
24581
|
const result = await Effect.runPromise(closeOut(ctx));
|
|
24575
24582
|
if (!result.success) {
|
|
24576
24583
|
const failed = result.steps.find((step) => !step.success && !step.skipped);
|
|
@@ -24864,6 +24871,8 @@ init_concurrency();
|
|
|
24864
24871
|
const BLOCKED_REVIEW_MISSING_ANCHOR_LOG_INTERVAL_MS = 3600 * 1e3;
|
|
24865
24872
|
const blockedReviewMissingAnchorLogs = /* @__PURE__ */ new Map();
|
|
24866
24873
|
const blockedReviewDriftObservations = /* @__PURE__ */ new Map();
|
|
24874
|
+
const lastResetAnchors = /* @__PURE__ */ new Map();
|
|
24875
|
+
const resetLoopEscalated = /* @__PURE__ */ new Set();
|
|
24867
24876
|
function uniformReviewerVerdictAnchor(status) {
|
|
24868
24877
|
const verdicts = Object.values(status.reviewerVerdicts ?? {});
|
|
24869
24878
|
if (verdicts.length === 0) return void 0;
|
|
@@ -24883,12 +24892,14 @@ async function checkPostReviewCommits() {
|
|
|
24883
24892
|
const actions = [];
|
|
24884
24893
|
try {
|
|
24885
24894
|
const statuses = loadReviewStatuses();
|
|
24886
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
24895
|
+
const { resolveProjectFromIssueSync } = await import("./projects-WqMWCdpa.js");
|
|
24887
24896
|
for (const [issueId, status] of Object.entries(statuses)) {
|
|
24888
24897
|
const isBlocked = status.reviewStatus === "blocked";
|
|
24889
24898
|
if (!isBlocked) blockedReviewDriftObservations.delete(issueId);
|
|
24890
24899
|
if (status.mergeStatus === "merged") {
|
|
24891
24900
|
blockedReviewDriftObservations.delete(issueId);
|
|
24901
|
+
lastResetAnchors.delete(issueId);
|
|
24902
|
+
resetLoopEscalated.delete(issueId);
|
|
24892
24903
|
continue;
|
|
24893
24904
|
}
|
|
24894
24905
|
if (!isBlocked && status.reviewStatus !== "passed" && !status.readyForMerge) continue;
|
|
@@ -24913,8 +24924,8 @@ async function checkPostReviewCommits() {
|
|
|
24913
24924
|
if (!project) continue;
|
|
24914
24925
|
const workspacePath = join$1(project.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
|
|
24915
24926
|
if (!existsSync(workspacePath)) continue;
|
|
24916
|
-
const { formatAnchorShort, rehydrateHeadAnchor } = await import("./git-utils-
|
|
24917
|
-
const { evaluateWorkspaceAnchorDrift } = await import("./workspace-anchor-drift-
|
|
24927
|
+
const { formatAnchorShort, rehydrateHeadAnchor } = await import("./git-utils-C31x1lpE.js");
|
|
24928
|
+
const { evaluateWorkspaceAnchorDrift } = await import("./workspace-anchor-drift-C8Fy3shi.js");
|
|
24918
24929
|
const verdict = await evaluateWorkspaceAnchorDrift(issueId, workspacePath, rehydrateHeadAnchor(reviewedAnchor));
|
|
24919
24930
|
if (verdict.kind === "unreadable" || verdict.kind === "current") {
|
|
24920
24931
|
blockedReviewDriftObservations.delete(issueId);
|
|
@@ -24927,6 +24938,16 @@ async function checkPostReviewCommits() {
|
|
|
24927
24938
|
continue;
|
|
24928
24939
|
}
|
|
24929
24940
|
const currentHead = verdict.currentAnchor;
|
|
24941
|
+
if (lastResetAnchors.get(issueId) === currentHead) {
|
|
24942
|
+
if (!resetLoopEscalated.has(issueId)) {
|
|
24943
|
+
resetLoopEscalated.add(issueId);
|
|
24944
|
+
const message = `${issueId} — review reset suppressed: drift against ${formatAnchorShort(currentHead)} already caused a reset and the workspace has not moved since. This indicates an anchor-producer disagreement, not new commits; review will not re-dispatch until the workspace head actually changes.`;
|
|
24945
|
+
logDeaconEventSync(`checkPostReviewCommits: ${message}`);
|
|
24946
|
+
const { recordDeadEndNeedsYou } = await import("./dead-end-trip-zKlS4v6f.js");
|
|
24947
|
+
await recordDeadEndNeedsYou(issueId, "review-reset-loop", currentHead, message);
|
|
24948
|
+
}
|
|
24949
|
+
continue;
|
|
24950
|
+
}
|
|
24930
24951
|
if (isBlocked) {
|
|
24931
24952
|
const priorObservation = blockedReviewDriftObservations.get(issueId);
|
|
24932
24953
|
if (!priorObservation || priorObservation.reviewedAnchor !== reviewedAnchor || priorObservation.currentAnchor !== currentHead) {
|
|
@@ -24939,6 +24960,8 @@ async function checkPostReviewCommits() {
|
|
|
24939
24960
|
blockedReviewDriftObservations.delete(issueId);
|
|
24940
24961
|
}
|
|
24941
24962
|
console.log(`[deacon] Post-review commit detected for ${issueId}: was ${formatAnchorShort(reviewedAnchor)}, now ${formatAnchorShort(currentHead)} — resetting review`);
|
|
24963
|
+
lastResetAnchors.set(issueId, currentHead);
|
|
24964
|
+
resetLoopEscalated.delete(issueId);
|
|
24942
24965
|
if (isBlocked) setReviewStatusSync(issueId, {
|
|
24943
24966
|
reviewStatus: "pending",
|
|
24944
24967
|
readyForMerge: false,
|
|
@@ -24964,7 +24987,7 @@ async function checkPostReviewCommits() {
|
|
|
24964
24987
|
actions.push(`Deferred post-review re-dispatch for ${issueId} — advancing-role concurrency ceiling reached`);
|
|
24965
24988
|
logDeaconEventSync(`checkPostReviewCommits: deferred review for ${issueId} — advancing ceiling reached (PAN-1665) — ${describeRunningAgents()}`);
|
|
24966
24989
|
} else if (freshStatus?.reviewStatus === "pending") {
|
|
24967
|
-
const { spawnReviewRoleForIssue } = await import("./review-agent-
|
|
24990
|
+
const { spawnReviewRoleForIssue } = await import("./review-agent-CD3RQ-tc.js");
|
|
24968
24991
|
const branch = `feature/${issueId.toLowerCase()}`;
|
|
24969
24992
|
const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
|
|
24970
24993
|
issueId,
|
|
@@ -25345,7 +25368,7 @@ function reviewConvoyLiveness(issueId) {
|
|
|
25345
25368
|
*/
|
|
25346
25369
|
async function recoverUnhealthyTestStack(issueId, workspacePath) {
|
|
25347
25370
|
const key = issueId.toUpperCase();
|
|
25348
|
-
const { getWorkspaceStackHealth } = await import("./stack-health-
|
|
25371
|
+
const { getWorkspaceStackHealth } = await import("./stack-health-deVSdDwn.js");
|
|
25349
25372
|
const health = await Effect.runPromise(getWorkspaceStackHealth(issueId, { workspacePath }));
|
|
25350
25373
|
if (health.healthy) {
|
|
25351
25374
|
testStackRebuildState.delete(key);
|
|
@@ -25377,7 +25400,7 @@ async function recoverUnhealthyTestStack(issueId, workspacePath) {
|
|
|
25377
25400
|
record.attempts += 1;
|
|
25378
25401
|
testStackRebuildState.set(key, record);
|
|
25379
25402
|
console.log(`[deacon] Test stack for ${key} unhealthy (${health.reasons.join("; ")}) — rebuilding (attempt ${record.attempts}/${TEST_STACK_REBUILD_MAX_ATTEMPTS})`);
|
|
25380
|
-
const { rebuildWorkspaceStack } = await import("./rebuild-stack-
|
|
25403
|
+
const { rebuildWorkspaceStack } = await import("./rebuild-stack-qC0jCNm6.js");
|
|
25381
25404
|
const result = await Effect.runPromise(rebuildWorkspaceStack(issueId, { onProgress: (m) => console.log(`[deacon] ${key} stack rebuild: ${m}`) }));
|
|
25382
25405
|
if (!result.success) {
|
|
25383
25406
|
console.warn(`[deacon] Test stack rebuild failed for ${key}: ${result.error}`);
|
|
@@ -25545,7 +25568,7 @@ async function handleReviewCoordinatorDied(issueId, _sessionName, _reason) {
|
|
|
25545
25568
|
return actions;
|
|
25546
25569
|
}
|
|
25547
25570
|
try {
|
|
25548
|
-
const { spawnReviewRoleForIssue } = await import("./review-agent-
|
|
25571
|
+
const { spawnReviewRoleForIssue } = await import("./review-agent-CD3RQ-tc.js");
|
|
25549
25572
|
const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
|
|
25550
25573
|
issueId,
|
|
25551
25574
|
workspace,
|
|
@@ -25620,7 +25643,7 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
|
|
|
25620
25643
|
const issueLower = issueId.toLowerCase();
|
|
25621
25644
|
const workspace = getAgentStateSync(`agent-${issueLower}`)?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
|
|
25622
25645
|
if (workspace) try {
|
|
25623
|
-
if ((options.readWorkspaceHead ? await options.readWorkspaceHead(workspace) : await (await import("./git-utils-
|
|
25646
|
+
if ((options.readWorkspaceHead ? await options.readWorkspaceHead(workspace) : await (await import("./git-utils-C31x1lpE.js")).snapshotWorkspaceHeadsPromise(issueId, workspace)) === status.lastVerifiedCommit) {
|
|
25624
25647
|
setReviewStatusSync(issueId, {
|
|
25625
25648
|
reviewStatus: "pending",
|
|
25626
25649
|
reviewNotes: void 0
|
|
@@ -25642,7 +25665,7 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
|
|
|
25642
25665
|
if (project) {
|
|
25643
25666
|
const workspacePath = join$1(project.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
|
|
25644
25667
|
if (existsSync(workspacePath)) {
|
|
25645
|
-
const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-
|
|
25668
|
+
const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-C31x1lpE.js");
|
|
25646
25669
|
reviewUpdate["reviewedAtCommit"] = await snapshotWorkspaceHeadsPromise(issueId, workspacePath);
|
|
25647
25670
|
}
|
|
25648
25671
|
}
|
|
@@ -25697,7 +25720,7 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
|
|
|
25697
25720
|
const workspace = agentState?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
|
|
25698
25721
|
if (workspace && resolved && !tryReserveAdvancingSlot() && !await tryYieldForAdvancingDispatch("review", issueId)) actions.push(`Deferred review re-dispatch for ${issueId} — advancing-role concurrency ceiling reached`);
|
|
25699
25722
|
else if (workspace && resolved) try {
|
|
25700
|
-
const { spawnReviewRoleForIssue } = await import("./review-agent-
|
|
25723
|
+
const { spawnReviewRoleForIssue } = await import("./review-agent-CD3RQ-tc.js");
|
|
25701
25724
|
const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
|
|
25702
25725
|
issueId,
|
|
25703
25726
|
workspace,
|
|
@@ -25722,8 +25745,8 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
|
|
|
25722
25745
|
const workspace = agentState?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
|
|
25723
25746
|
if (workspace && resolved) {
|
|
25724
25747
|
const branch = `feature/${issueLower}`;
|
|
25725
|
-
const { spawnRun } = await import("./agents-
|
|
25726
|
-
const { buildTestRolePrompt } = await import("./test-agent-queue-
|
|
25748
|
+
const { spawnRun } = await import("./agents-IPSa5kzn.js");
|
|
25749
|
+
const { buildTestRolePrompt } = await import("./test-agent-queue-CWMq7oyG.js");
|
|
25727
25750
|
const stackRecovery = await recoverUnhealthyTestStack(issueId, workspace);
|
|
25728
25751
|
if (stackRecovery === "cooldown" || stackRecovery === "exhausted") {
|
|
25729
25752
|
setReviewStatusSync(issueId, { testStatus: "dispatch_failed" });
|
|
@@ -25862,7 +25885,7 @@ async function recoverStalledReviewConvoys(getCanonicalState = getAutoCloseOutCa
|
|
|
25862
25885
|
record.lastAttempt = now;
|
|
25863
25886
|
record.attempts += 1;
|
|
25864
25887
|
stalledReviewConvoyRecoveryState.set(key, record);
|
|
25865
|
-
const { spawnReviewRoleForIssue } = await import("./review-agent-
|
|
25888
|
+
const { spawnReviewRoleForIssue } = await import("./review-agent-CD3RQ-tc.js");
|
|
25866
25889
|
try {
|
|
25867
25890
|
const result = await Effect.runPromise(spawnReviewRoleForIssue({
|
|
25868
25891
|
issueId,
|
|
@@ -25933,7 +25956,7 @@ async function checkMissingReviewStatuses() {
|
|
|
25933
25956
|
continue;
|
|
25934
25957
|
}
|
|
25935
25958
|
try {
|
|
25936
|
-
const { spawnReviewRoleForIssue } = await import("./review-agent-
|
|
25959
|
+
const { spawnReviewRoleForIssue } = await import("./review-agent-CD3RQ-tc.js");
|
|
25937
25960
|
await Effect.runPromise(spawnReviewRoleForIssue({
|
|
25938
25961
|
issueId,
|
|
25939
25962
|
workspace,
|
|
@@ -25961,11 +25984,14 @@ async function checkMissingReviewStatuses() {
|
|
|
25961
25984
|
//#endregion
|
|
25962
25985
|
//#region ../../lib/cloister/deacon-review-unsignaled.ts
|
|
25963
25986
|
init_agents$1();
|
|
25987
|
+
init_activity_logger();
|
|
25964
25988
|
init_projects();
|
|
25965
25989
|
init_review_status();
|
|
25966
25990
|
init_specialists();
|
|
25967
25991
|
init_tmux();
|
|
25968
25992
|
init_review_convoy_liveness();
|
|
25993
|
+
init_review_verdict_feedback();
|
|
25994
|
+
init_review_verdict_report();
|
|
25969
25995
|
/**
|
|
25970
25996
|
* Detect issues stuck in `reviewing` status with no active review session.
|
|
25971
25997
|
*
|
|
@@ -25984,7 +26010,7 @@ async function checkStuckReviewing() {
|
|
|
25984
26010
|
const actions = [];
|
|
25985
26011
|
const REVIEW_STUCK_THRESHOLD_MS = 1800 * 1e3;
|
|
25986
26012
|
try {
|
|
25987
|
-
const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-
|
|
26013
|
+
const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-B6wYcOtP.js");
|
|
25988
26014
|
const statuses = loadReviewStatuses();
|
|
25989
26015
|
const now = Date.now();
|
|
25990
26016
|
const activeReviewIssues = /* @__PURE__ */ new Set();
|
|
@@ -26042,25 +26068,183 @@ async function checkStuckReviewing() {
|
|
|
26042
26068
|
* - Only nudges once per review cycle (tracked by runId in the review dir)
|
|
26043
26069
|
*/
|
|
26044
26070
|
const unsignaledReviewNudges = /* @__PURE__ */ new Map();
|
|
26045
|
-
|
|
26071
|
+
const pendingVerdictNudges = /* @__PURE__ */ new Map();
|
|
26072
|
+
function reviewAnchorFromContext(context) {
|
|
26073
|
+
if (context.repos) {
|
|
26074
|
+
if (context.repos.length === 0) return void 0;
|
|
26075
|
+
const heads = [];
|
|
26076
|
+
for (const repo of context.repos) {
|
|
26077
|
+
if (!repo.repoKey?.trim() || !repo.headSha?.trim()) return void 0;
|
|
26078
|
+
heads.push(`${repo.repoKey.trim()}@${repo.headSha.trim()}`);
|
|
26079
|
+
}
|
|
26080
|
+
return heads.join(" ");
|
|
26081
|
+
}
|
|
26082
|
+
return context.headSha?.trim() || void 0;
|
|
26083
|
+
}
|
|
26084
|
+
function shellQuote(value) {
|
|
26085
|
+
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
26086
|
+
}
|
|
26087
|
+
function buildReviewCompletionCommand(issueId, verdict, notes, runId) {
|
|
26088
|
+
let command = `pan admin specialists done review ${shellQuote(issueId)} --status ${shellQuote(verdict)}`;
|
|
26089
|
+
if (verdict === "blocked" || verdict === "failed") command += ` --notes ${shellQuote(notes)}`;
|
|
26090
|
+
return `${command} --run-id ${shellQuote(runId)}`;
|
|
26091
|
+
}
|
|
26092
|
+
function isReviewContextForActiveRun(context, status, reportMtimeMs) {
|
|
26046
26093
|
if (!status.reviewSpawnedAt) return true;
|
|
26047
26094
|
const spawnedAtMs = reviewTimestampMs(status.reviewSpawnedAt);
|
|
26048
26095
|
if (!Number.isFinite(spawnedAtMs)) return true;
|
|
26049
|
-
if (
|
|
26096
|
+
if (reportMtimeMs < spawnedAtMs) return false;
|
|
26097
|
+
if (context.generatedAt) {
|
|
26098
|
+
const generatedAtMs = Date.parse(context.generatedAt);
|
|
26099
|
+
if (Number.isFinite(generatedAtMs) && generatedAtMs < spawnedAtMs) return false;
|
|
26100
|
+
}
|
|
26101
|
+
const reviewedAnchor = reviewAnchorFromContext(context);
|
|
26102
|
+
return !status.lastVerifiedCommit || !reviewedAnchor || reviewedAnchor === status.lastVerifiedCommit;
|
|
26103
|
+
}
|
|
26104
|
+
function isSynthesisForActiveReviewRun(dirPath, status, synthesisMtimeMs) {
|
|
26105
|
+
if (!status.reviewSpawnedAt) return true;
|
|
26050
26106
|
const contextPath = join$1(dirPath, "context.json");
|
|
26051
26107
|
if (!existsSync(contextPath)) return false;
|
|
26052
|
-
let context;
|
|
26053
26108
|
try {
|
|
26054
|
-
|
|
26109
|
+
return isReviewContextForActiveRun(JSON.parse(readFileSync(contextPath, "utf8")), status, synthesisMtimeMs);
|
|
26055
26110
|
} catch {
|
|
26056
26111
|
return false;
|
|
26057
26112
|
}
|
|
26058
|
-
|
|
26059
|
-
|
|
26060
|
-
|
|
26113
|
+
}
|
|
26114
|
+
/**
|
|
26115
|
+
* Apply settled review verdicts that reached disk after their runtime status
|
|
26116
|
+
* was reset to pending. The live review parent gets one chance to signal the
|
|
26117
|
+
* verdict itself; a dead parent, or one still unsignaled after 30 minutes, is
|
|
26118
|
+
* reconciled directly through the review-status and feedback write doors.
|
|
26119
|
+
*/
|
|
26120
|
+
async function reconcileUnappliedReviewVerdicts() {
|
|
26121
|
+
const actions = [];
|
|
26122
|
+
const VERDICT_SETTLE_MS = 300 * 1e3;
|
|
26123
|
+
const NUDGE_GRACE_MS = 1800 * 1e3;
|
|
26124
|
+
try {
|
|
26125
|
+
const statuses = loadReviewStatuses();
|
|
26126
|
+
const now = Date.now();
|
|
26127
|
+
for (const [issueId, status] of Object.entries(statuses)) {
|
|
26128
|
+
if (status.reviewStatus !== "pending" || !status.reviewSpawnedAt) continue;
|
|
26129
|
+
try {
|
|
26130
|
+
const resolved = resolveProjectFromIssueSync(issueId);
|
|
26131
|
+
if (!resolved) continue;
|
|
26132
|
+
const wsPath = findWorkspacePath(resolved.projectPath, issueId.toLowerCase());
|
|
26133
|
+
if (!wsPath) continue;
|
|
26134
|
+
const reviewBaseDir = join$1(wsPath, ".pan", "review");
|
|
26135
|
+
let reviewEntries;
|
|
26136
|
+
try {
|
|
26137
|
+
reviewEntries = await readdir(reviewBaseDir);
|
|
26138
|
+
} catch {
|
|
26139
|
+
continue;
|
|
26140
|
+
}
|
|
26141
|
+
let latestDir = null;
|
|
26142
|
+
let latestReport = null;
|
|
26143
|
+
let latestContext = null;
|
|
26144
|
+
let latestMtime = 0;
|
|
26145
|
+
for (const entry of reviewEntries) {
|
|
26146
|
+
if (!entry.startsWith(`agent-${issueId.toLowerCase()}-review`)) continue;
|
|
26147
|
+
const dirPath = join$1(reviewBaseDir, entry);
|
|
26148
|
+
try {
|
|
26149
|
+
const report = await findVerdictReportAsync(dirPath);
|
|
26150
|
+
if (!report) continue;
|
|
26151
|
+
const [reportStat, contextContent] = await Promise.all([stat$1(report.path), readFile(join$1(dirPath, "context.json"), "utf8")]);
|
|
26152
|
+
const context = JSON.parse(contextContent);
|
|
26153
|
+
if (!isReviewContextForActiveRun(context, status, reportStat.mtimeMs)) continue;
|
|
26154
|
+
if (reportStat.mtimeMs > latestMtime) {
|
|
26155
|
+
latestDir = dirPath;
|
|
26156
|
+
latestReport = report;
|
|
26157
|
+
latestContext = context;
|
|
26158
|
+
latestMtime = reportStat.mtimeMs;
|
|
26159
|
+
}
|
|
26160
|
+
} catch (error) {
|
|
26161
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
26162
|
+
console.error(`[deacon] Error reading review run ${dirPath}:`, msg);
|
|
26163
|
+
}
|
|
26164
|
+
}
|
|
26165
|
+
if (!latestDir || !latestReport || !latestContext) continue;
|
|
26166
|
+
if (now - latestMtime < VERDICT_SETTLE_MS) continue;
|
|
26167
|
+
const requestedAtMs = status.reviewRequestedAt ? Date.parse(status.reviewRequestedAt) : NaN;
|
|
26168
|
+
if (Number.isFinite(requestedAtMs) && requestedAtMs > latestMtime) continue;
|
|
26169
|
+
let currentHead;
|
|
26170
|
+
let reviewedHead;
|
|
26171
|
+
try {
|
|
26172
|
+
const { rehydrateHeadAnchor, snapshotWorkspaceHeadsPromise } = await import("./git-utils-C31x1lpE.js");
|
|
26173
|
+
currentHead = await snapshotWorkspaceHeadsPromise(issueId, wsPath);
|
|
26174
|
+
const persistedAnchor = reviewAnchorFromContext(latestContext);
|
|
26175
|
+
reviewedHead = persistedAnchor ? rehydrateHeadAnchor(persistedAnchor) : void 0;
|
|
26176
|
+
} catch {
|
|
26177
|
+
continue;
|
|
26178
|
+
}
|
|
26179
|
+
if (!reviewedHead || currentHead !== reviewedHead) continue;
|
|
26180
|
+
let parsed;
|
|
26181
|
+
try {
|
|
26182
|
+
parsed = parseVerdictReport(await readFile(latestReport.path, "utf8"));
|
|
26183
|
+
} catch {
|
|
26184
|
+
continue;
|
|
26185
|
+
}
|
|
26186
|
+
if (!parsed) continue;
|
|
26187
|
+
const reviewSession = `agent-${issueId.toLowerCase()}-review`;
|
|
26188
|
+
const sessionAlive = sessionExistsSync(reviewSession);
|
|
26189
|
+
const paneDead = sessionAlive ? await Effect.runPromise(isPaneDead(reviewSession)).catch(() => true) : true;
|
|
26190
|
+
if (sessionAlive && !paneDead) {
|
|
26191
|
+
const lastNudged = pendingVerdictNudges.get(latestDir);
|
|
26192
|
+
if (!lastNudged) {
|
|
26193
|
+
const notes = parsed.topBlocker || `See ${latestReport.filename}`;
|
|
26194
|
+
const nudge = `Your review verdict is already written on disk but review status is still pending. Your ONLY remaining task is to execute this Bash command immediately — do not analyze, do not summarize, do not ask questions, just run it:\n\n${buildReviewCompletionCommand(issueId, parsed.verdict, notes, basename$1(latestDir))}\n\nRun this command NOW. Do not write any other response before executing it.`;
|
|
26195
|
+
try {
|
|
26196
|
+
const { messageAgent } = await import("./agents-IPSa5kzn.js");
|
|
26197
|
+
await messageAgent(reviewSession, nudge);
|
|
26198
|
+
pendingVerdictNudges.set(latestDir, now);
|
|
26199
|
+
const action = `Nudged ${reviewSession} to apply pending ${parsed.verdict} verdict from ${latestReport.filename}`;
|
|
26200
|
+
actions.push(action);
|
|
26201
|
+
console.log(`[deacon] ${action}`);
|
|
26202
|
+
} catch (err) {
|
|
26203
|
+
console.error(`[deacon] Failed to nudge ${reviewSession}:`, err instanceof Error ? err.message : String(err));
|
|
26204
|
+
}
|
|
26205
|
+
continue;
|
|
26206
|
+
}
|
|
26207
|
+
if (now - lastNudged < NUDGE_GRACE_MS) continue;
|
|
26208
|
+
}
|
|
26209
|
+
const attribution = `applied by deacon sweep from on-disk ${latestReport.filename}`;
|
|
26210
|
+
const reviewNotes = parsed.topBlocker ? `${parsed.topBlocker} — ${attribution}` : `Review ${parsed.verdict} ${attribution}`;
|
|
26211
|
+
setReviewStatusSync(issueId, {
|
|
26212
|
+
reviewStatus: parsed.verdict,
|
|
26213
|
+
reviewNotes,
|
|
26214
|
+
...(parsed.verdict === "passed" || parsed.verdict === "blocked") && currentHead ? { reviewedAtCommit: currentHead } : {}
|
|
26215
|
+
});
|
|
26216
|
+
if (parsed.verdict === "blocked") try {
|
|
26217
|
+
await Effect.runPromise(deliverReviewVerdictFeedback({
|
|
26218
|
+
issueId,
|
|
26219
|
+
verdict: "blocked",
|
|
26220
|
+
notes: parsed.topBlocker || reviewNotes,
|
|
26221
|
+
workspacePath: wsPath,
|
|
26222
|
+
prUrl: status.prUrl,
|
|
26223
|
+
runId: basename$1(latestDir)
|
|
26224
|
+
}));
|
|
26225
|
+
} catch (err) {
|
|
26226
|
+
console.error(`[deacon] Failed to deliver reconciled review verdict for ${issueId}:`, err instanceof Error ? err.message : String(err));
|
|
26227
|
+
}
|
|
26228
|
+
pendingVerdictNudges.delete(latestDir);
|
|
26229
|
+
const action = `reconcileUnappliedReviewVerdicts deacon sweep applied ${parsed.verdict} for ${issueId} from ${latestReport.filename}`;
|
|
26230
|
+
actions.push(action);
|
|
26231
|
+
emitActivityEntrySync({
|
|
26232
|
+
source: "cloister",
|
|
26233
|
+
level: "warn",
|
|
26234
|
+
message: action,
|
|
26235
|
+
issueId
|
|
26236
|
+
});
|
|
26237
|
+
console.log(`[deacon] ${action}`);
|
|
26238
|
+
} catch (error) {
|
|
26239
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
26240
|
+
console.error(`[deacon] Error reconciling unapplied review verdict for ${issueId}:`, msg);
|
|
26241
|
+
}
|
|
26242
|
+
}
|
|
26243
|
+
} catch (error) {
|
|
26244
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
26245
|
+
console.error("[deacon] Error reconciling unapplied review verdicts:", msg);
|
|
26061
26246
|
}
|
|
26062
|
-
|
|
26063
|
-
return true;
|
|
26247
|
+
return actions;
|
|
26064
26248
|
}
|
|
26065
26249
|
async function checkCompletedButUnsignaledReviews() {
|
|
26066
26250
|
const actions = [];
|
|
@@ -26077,20 +26261,22 @@ async function checkCompletedButUnsignaledReviews() {
|
|
|
26077
26261
|
const reviewBaseDir = join$1(wsPath, ".pan", "review");
|
|
26078
26262
|
if (!existsSync(reviewBaseDir)) continue;
|
|
26079
26263
|
let latestDir = null;
|
|
26264
|
+
let latestReport = null;
|
|
26080
26265
|
let latestMtime = 0;
|
|
26081
26266
|
for (const entry of readdirSync(reviewBaseDir)) {
|
|
26082
26267
|
if (!entry.startsWith(`agent-${issueId.toLowerCase()}-review`)) continue;
|
|
26083
26268
|
const dirPath = join$1(reviewBaseDir, entry);
|
|
26084
|
-
const
|
|
26085
|
-
if (!
|
|
26086
|
-
const mtime = statSync(
|
|
26269
|
+
const report = findVerdictReport(dirPath);
|
|
26270
|
+
if (!report) continue;
|
|
26271
|
+
const mtime = statSync(report.path).mtimeMs;
|
|
26087
26272
|
if (!isSynthesisForActiveReviewRun(dirPath, status, mtime)) continue;
|
|
26088
26273
|
if (mtime > latestMtime) {
|
|
26089
26274
|
latestMtime = mtime;
|
|
26090
26275
|
latestDir = dirPath;
|
|
26276
|
+
latestReport = report;
|
|
26091
26277
|
}
|
|
26092
26278
|
}
|
|
26093
|
-
if (!latestDir) continue;
|
|
26279
|
+
if (!latestDir || !latestReport) continue;
|
|
26094
26280
|
if (now - latestMtime < SYNTHESIS_SETTLE_MS) continue;
|
|
26095
26281
|
const lastNudged = unsignaledReviewNudges.get(latestDir);
|
|
26096
26282
|
if (lastNudged && now - lastNudged < 1800 * 1e3) continue;
|
|
@@ -26099,40 +26285,31 @@ async function checkCompletedButUnsignaledReviews() {
|
|
|
26099
26285
|
const paneDead = sessionAlive ? await Effect.runPromise(isPaneDead(reviewSession)).catch(() => true) : true;
|
|
26100
26286
|
const activeReviewState = sessionAlive && !paneDead ? getAgentStateSync(reviewSession) : null;
|
|
26101
26287
|
if (activeReviewState?.reviewRunId && latestDir !== join$1(reviewBaseDir, activeReviewState.reviewRunId)) continue;
|
|
26102
|
-
|
|
26103
|
-
let verdict = null;
|
|
26104
|
-
let topBlocker = "";
|
|
26288
|
+
let parsed;
|
|
26105
26289
|
try {
|
|
26106
|
-
|
|
26107
|
-
const verdictLine = content.match(/## Verdict:\s*(.+)/i);
|
|
26108
|
-
if (verdictLine) {
|
|
26109
|
-
const v = verdictLine[1].trim().toUpperCase();
|
|
26110
|
-
if (v === "PASSED") verdict = "passed";
|
|
26111
|
-
else if (v === "CHANGES REQUESTED") verdict = "blocked";
|
|
26112
|
-
else if (v === "FAILED") verdict = "failed";
|
|
26113
|
-
}
|
|
26114
|
-
const blockerMatch = content.match(/## Blocking Findings\s*\n\s*###\s*\[[^\]]+\]\s*(.+)/);
|
|
26115
|
-
if (blockerMatch) topBlocker = blockerMatch[1].slice(0, 120);
|
|
26290
|
+
parsed = parseVerdictReport(readFileSync(latestReport.path, "utf8"));
|
|
26116
26291
|
} catch {
|
|
26117
26292
|
continue;
|
|
26118
26293
|
}
|
|
26119
|
-
if (!
|
|
26294
|
+
if (!parsed) continue;
|
|
26295
|
+
const { verdict, topBlocker } = parsed;
|
|
26120
26296
|
if (sessionAlive && !paneDead) {
|
|
26121
26297
|
if (lastNudged) {
|
|
26122
26298
|
setReviewStatusSync(issueId, {
|
|
26123
26299
|
reviewStatus: verdict,
|
|
26124
|
-
reviewNotes: topBlocker || `Review auto-completed by deacon: ${verdict} (agent alive but unresponsive after nudge,
|
|
26300
|
+
reviewNotes: topBlocker || `Review auto-completed by deacon: ${verdict} (agent alive but unresponsive after nudge, ${latestReport.filename} exists)`
|
|
26125
26301
|
});
|
|
26126
|
-
actions.push(`Auto-completed review for ${issueId}: ${verdict} (alive but unresponsive after nudge,
|
|
26302
|
+
actions.push(`Auto-completed review for ${issueId}: ${verdict} (alive but unresponsive after nudge, ${latestReport.filename} written ${Math.round((now - latestMtime) / 6e4)}min ago)`);
|
|
26127
26303
|
console.log(`[deacon] Auto-completed review for ${issueId}: ${verdict} (alive but unresponsive after nudge)`);
|
|
26128
26304
|
continue;
|
|
26129
26305
|
}
|
|
26130
|
-
const
|
|
26306
|
+
const cmd = buildReviewCompletionCommand(issueId, verdict, topBlocker || `See ${latestReport.filename}`, basename$1(latestDir));
|
|
26307
|
+
const nudge = `Your review verdict in ${latestReport.filename} is already written and saved. Your ONLY remaining task is to execute this Bash command immediately — do not analyze, do not summarize, do not ask questions, just run it:\n\n${cmd}\n\nRun this command NOW. Do not write any other response before executing it.`;
|
|
26131
26308
|
try {
|
|
26132
|
-
const { messageAgent } = await import("./agents-
|
|
26309
|
+
const { messageAgent } = await import("./agents-IPSa5kzn.js");
|
|
26133
26310
|
await messageAgent(reviewSession, nudge);
|
|
26134
26311
|
unsignaledReviewNudges.set(latestDir, now);
|
|
26135
|
-
actions.push(`Nudged ${reviewSession} to signal ${verdict} (
|
|
26312
|
+
actions.push(`Nudged ${reviewSession} to signal ${verdict} (${latestReport.filename} written ${Math.round((now - latestMtime) / 6e4)}min ago)`);
|
|
26136
26313
|
console.log(`[deacon] Nudged ${reviewSession} to signal ${verdict}`);
|
|
26137
26314
|
} catch (err) {
|
|
26138
26315
|
console.error(`[deacon] Failed to nudge ${reviewSession}:`, err instanceof Error ? err.message : String(err));
|
|
@@ -26140,9 +26317,9 @@ async function checkCompletedButUnsignaledReviews() {
|
|
|
26140
26317
|
} else {
|
|
26141
26318
|
setReviewStatusSync(issueId, {
|
|
26142
26319
|
reviewStatus: verdict,
|
|
26143
|
-
reviewNotes: topBlocker || `Review auto-completed by deacon: ${verdict} (agent dead,
|
|
26320
|
+
reviewNotes: topBlocker || `Review auto-completed by deacon: ${verdict} (agent dead, ${latestReport.filename} exists)`
|
|
26144
26321
|
});
|
|
26145
|
-
actions.push(`Auto-completed review for ${issueId}: ${verdict} (dead agent,
|
|
26322
|
+
actions.push(`Auto-completed review for ${issueId}: ${verdict} (dead agent, ${latestReport.filename} written ${Math.round((now - latestMtime) / 6e4)}min ago)`);
|
|
26146
26323
|
console.log(`[deacon] Auto-completed review for ${issueId}: ${verdict} (dead agent)`);
|
|
26147
26324
|
}
|
|
26148
26325
|
}
|
|
@@ -26157,6 +26334,7 @@ async function checkCompletedButUnsignaledReviews() {
|
|
|
26157
26334
|
init_context_overflow();
|
|
26158
26335
|
init_agents$1();
|
|
26159
26336
|
init_review_verdict_feedback();
|
|
26337
|
+
init_review_verdict_report();
|
|
26160
26338
|
init_paths();
|
|
26161
26339
|
init_review_status();
|
|
26162
26340
|
init_persistent_logger();
|
|
@@ -26238,7 +26416,7 @@ async function respawnIdleReviewer(state, agentId) {
|
|
|
26238
26416
|
return false;
|
|
26239
26417
|
}
|
|
26240
26418
|
try {
|
|
26241
|
-
const { spawnReviewSubRoleForIssue } = await import("./review-agent-
|
|
26419
|
+
const { spawnReviewSubRoleForIssue } = await import("./review-agent-CD3RQ-tc.js");
|
|
26242
26420
|
const contextManifestPath = join$1(dirname$1(outputPath), "context.json");
|
|
26243
26421
|
const result = await Effect.runPromise(spawnReviewSubRoleForIssue({
|
|
26244
26422
|
issueId: state.issueId,
|
|
@@ -26276,7 +26454,7 @@ async function nudgeSynthesisForCompleteReviewerReports(states) {
|
|
|
26276
26454
|
const status = getReviewStatusSync(state.issueId);
|
|
26277
26455
|
if (!status || status.reviewStatus !== "reviewing") continue;
|
|
26278
26456
|
const reviewDir = join$1(state.workspace, ".pan", "review", state.reviewRunId);
|
|
26279
|
-
const synthesisAlreadyWritten =
|
|
26457
|
+
const synthesisAlreadyWritten = findVerdictReport(reviewDir) !== null;
|
|
26280
26458
|
const startedMs = Date.parse(state.startedAt);
|
|
26281
26459
|
const readyLines = [];
|
|
26282
26460
|
const reports = [];
|
|
@@ -26324,7 +26502,7 @@ async function nudgeSynthesisForCompleteReviewerReports(states) {
|
|
|
26324
26502
|
writeFileSync(join$1(reviewDir, "synthesis.md"), synthesis.body);
|
|
26325
26503
|
let fallbackHead;
|
|
26326
26504
|
try {
|
|
26327
|
-
const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-
|
|
26505
|
+
const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-C31x1lpE.js");
|
|
26328
26506
|
fallbackHead = await snapshotWorkspaceHeadsPromise(state.issueId, state.workspace);
|
|
26329
26507
|
} catch {}
|
|
26330
26508
|
const anchoredVerdicts = Object.fromEntries(Object.entries(synthesis.reviewerVerdicts).map(([subRole, v]) => [subRole, {
|
|
@@ -26363,7 +26541,7 @@ async function nudgeSynthesisForCompleteReviewerReports(states) {
|
|
|
26363
26541
|
"Read the four reports, write synthesis.md, then signal review status exactly as roles/review.md instructs."
|
|
26364
26542
|
].join("\n");
|
|
26365
26543
|
try {
|
|
26366
|
-
const { messageAgent } = await import("./agents-
|
|
26544
|
+
const { messageAgent } = await import("./agents-IPSa5kzn.js");
|
|
26367
26545
|
await messageAgent(state.id, message);
|
|
26368
26546
|
reviewReportsPresentNudges.set(nudgeKey, now);
|
|
26369
26547
|
const action = `Nudged ${state.id} to synthesize from ${REVIEW_SUB_ROLES.length} reviewer reports`;
|
|
@@ -26449,7 +26627,7 @@ async function monitorReviewConvoySignals() {
|
|
|
26449
26627
|
if (!signal) continue;
|
|
26450
26628
|
const message = signal === "ready" ? `REVIEWER_READY ${state.reviewSubRole} ${outputPath}` : signal === "timeout" ? `REVIEWER_TIMEOUT ${state.reviewSubRole} ${reason}` : `REVIEWER_FAILED ${state.reviewSubRole} ${reason}`;
|
|
26451
26629
|
try {
|
|
26452
|
-
const { messageAgent } = await import("./agents-
|
|
26630
|
+
const { messageAgent } = await import("./agents-IPSa5kzn.js");
|
|
26453
26631
|
await messageAgent(state.reviewSynthesisAgentId, message);
|
|
26454
26632
|
state.reviewMonitorSignaled = signal;
|
|
26455
26633
|
saveAgentStateSync(state);
|
|
@@ -26457,7 +26635,7 @@ async function monitorReviewConvoySignals() {
|
|
|
26457
26635
|
actions.push(action);
|
|
26458
26636
|
logDeaconEventSync(`monitorReviewConvoySignals: ${action}`);
|
|
26459
26637
|
if (signal === "ready") try {
|
|
26460
|
-
const { notifyPipelineSync } = await import("./pipeline-notifier-
|
|
26638
|
+
const { notifyPipelineSync } = await import("./pipeline-notifier-CO9rxJgB.js");
|
|
26461
26639
|
notifyPipelineSync({
|
|
26462
26640
|
type: "reviewer_completed",
|
|
26463
26641
|
issueId: state.issueId,
|
|
@@ -26465,7 +26643,7 @@ async function monitorReviewConvoySignals() {
|
|
|
26465
26643
|
});
|
|
26466
26644
|
} catch {}
|
|
26467
26645
|
else if (signal === "timeout") try {
|
|
26468
|
-
const { notifyPipelineSync } = await import("./pipeline-notifier-
|
|
26646
|
+
const { notifyPipelineSync } = await import("./pipeline-notifier-CO9rxJgB.js");
|
|
26469
26647
|
notifyPipelineSync({
|
|
26470
26648
|
type: "reviewer_timed_out",
|
|
26471
26649
|
issueId: state.issueId,
|
|
@@ -26565,7 +26743,7 @@ const FORK_CACHE_CHECK_DELAY_MS = 180 * 1e3;
|
|
|
26565
26743
|
async function checkStalledReviewDiscovery() {
|
|
26566
26744
|
const actions = [];
|
|
26567
26745
|
try {
|
|
26568
|
-
const { listAgentStates } = await import("./agents-
|
|
26746
|
+
const { listAgentStates } = await import("./agents-IPSa5kzn.js");
|
|
26569
26747
|
const states = listAgentStates();
|
|
26570
26748
|
const now = Date.now();
|
|
26571
26749
|
for (const state of states) {
|
|
@@ -26574,7 +26752,7 @@ async function checkStalledReviewDiscovery() {
|
|
|
26574
26752
|
const aged = Number.isFinite(startedMs) && now - startedMs > 48e4;
|
|
26575
26753
|
const dead = !await Effect.runPromise(sessionExists(state.id)).catch(() => false) || await Effect.runPromise(isPaneDead(state.id)).catch(() => true);
|
|
26576
26754
|
if (!aged && !dead) continue;
|
|
26577
|
-
const { handleReviewDiscoveryReady } = await import("./review-agent-
|
|
26755
|
+
const { handleReviewDiscoveryReady } = await import("./review-agent-CD3RQ-tc.js");
|
|
26578
26756
|
const result = await handleReviewDiscoveryReady(state.issueId, { source: dead ? "deacon-backstop (parent dead)" : "deacon-backstop (discovery timeout)" });
|
|
26579
26757
|
actions.push(result.message);
|
|
26580
26758
|
logDeaconEventSync(`checkStalledReviewDiscovery: ${result.message}`);
|
|
@@ -26597,8 +26775,8 @@ async function checkStalledReviewDiscovery() {
|
|
|
26597
26775
|
async function checkStalledReviewParents() {
|
|
26598
26776
|
const actions = [];
|
|
26599
26777
|
try {
|
|
26600
|
-
const { listAgentStates, markAgentStoppedState } = await import("./agents-
|
|
26601
|
-
const { PARENT_REVIEW_TIMEOUT_MS } = await import("./review-agent-
|
|
26778
|
+
const { listAgentStates, markAgentStoppedState } = await import("./agents-IPSa5kzn.js");
|
|
26779
|
+
const { PARENT_REVIEW_TIMEOUT_MS } = await import("./review-agent-CD3RQ-tc.js");
|
|
26602
26780
|
const states = listAgentStates();
|
|
26603
26781
|
const now = Date.now();
|
|
26604
26782
|
for (const state of states) {
|
|
@@ -26622,7 +26800,7 @@ async function checkStalledReviewParents() {
|
|
|
26622
26800
|
actions.push(message);
|
|
26623
26801
|
logDeaconEventSync(message);
|
|
26624
26802
|
try {
|
|
26625
|
-
const { emitActivityEntrySync } = await import("./activity-logger-
|
|
26803
|
+
const { emitActivityEntrySync } = await import("./activity-logger-K7FYGF_z.js");
|
|
26626
26804
|
emitActivityEntrySync({
|
|
26627
26805
|
source: "review",
|
|
26628
26806
|
level: "warn",
|
|
@@ -26647,9 +26825,9 @@ async function checkStalledReviewParents() {
|
|
|
26647
26825
|
async function checkReviewForkCacheMisses() {
|
|
26648
26826
|
const actions = [];
|
|
26649
26827
|
try {
|
|
26650
|
-
const { listAgentStates, saveAgentState } = await import("./agents-
|
|
26651
|
-
const { readEventsSync } = await import("./events-
|
|
26652
|
-
const { emitActivityEntrySync } = await import("./activity-logger-
|
|
26828
|
+
const { listAgentStates, saveAgentState } = await import("./agents-IPSa5kzn.js");
|
|
26829
|
+
const { readEventsSync } = await import("./events-CCkFWa7X.js");
|
|
26830
|
+
const { emitActivityEntrySync } = await import("./activity-logger-K7FYGF_z.js");
|
|
26653
26831
|
const states = listAgentStates();
|
|
26654
26832
|
const now = Date.now();
|
|
26655
26833
|
for (const parent of states) {
|
|
@@ -27118,7 +27296,6 @@ function startBootReconciliation(options = {}) {
|
|
|
27118
27296
|
}
|
|
27119
27297
|
//#endregion
|
|
27120
27298
|
//#region ../../lib/agents/pinned-launch.ts
|
|
27121
|
-
init_io();
|
|
27122
27299
|
init_dag();
|
|
27123
27300
|
init_agent_state();
|
|
27124
27301
|
function parseFlagValue(content, flag) {
|
|
@@ -27511,7 +27688,7 @@ async function nudgeStalledResumeWorkAgents() {
|
|
|
27511
27688
|
const message = buildStalledResumePrompt(state);
|
|
27512
27689
|
if (!message) continue;
|
|
27513
27690
|
try {
|
|
27514
|
-
const { messageAgent } = await import("./agents-
|
|
27691
|
+
const { messageAgent } = await import("./agents-IPSa5kzn.js");
|
|
27515
27692
|
await messageAgent(agentId, message);
|
|
27516
27693
|
recordCooldown(agentId, ".last-stalled-resume-nudge");
|
|
27517
27694
|
const action = `Re-sent stalled resume prompt to ${agentId} (${state.issueId})`;
|
|
@@ -27625,7 +27802,7 @@ async function nudgeIdleWorkAgentsWithOpenBeads() {
|
|
|
27625
27802
|
"Continue the per-item workflow without asking — claim it (`pan task claim <item-id>`), implement, commit, push, then complete it through `pan task done <item-id>`. Inspection is conditional on metadata.requiresInspection (default false; check the plan item before deciding to call `pan inspect`). Do NOT end your turn with a multi-paragraph summary; just advance to the next bead."
|
|
27626
27803
|
].join("\n");
|
|
27627
27804
|
try {
|
|
27628
|
-
const { messageAgent } = await import("./agents-
|
|
27805
|
+
const { messageAgent } = await import("./agents-IPSa5kzn.js");
|
|
27629
27806
|
await messageAgent(agentId, message);
|
|
27630
27807
|
writeFileSync(join$1(getAgentDir(agentId), ".last-bead-nudge"), String(Date.now()), "utf-8");
|
|
27631
27808
|
const action = `Nudged idle ${agentId} (${state.issueId}) — ${openTasks.length} ready task(s)`;
|
|
@@ -28055,6 +28232,290 @@ function shouldRunRecoveryJanitor(janitor, patrolCycle) {
|
|
|
28055
28232
|
return patrolCycle % (janitor === "feedback" ? 5 : 60) === 0;
|
|
28056
28233
|
}
|
|
28057
28234
|
//#endregion
|
|
28235
|
+
//#region ../../lib/cloister/pending-promotion-reconciler.ts
|
|
28236
|
+
init_activity_logger();
|
|
28237
|
+
init_internal_token();
|
|
28238
|
+
init_projects();
|
|
28239
|
+
init_io();
|
|
28240
|
+
init_issue_closed();
|
|
28241
|
+
const MARKER_GRACE_MS = 12e4;
|
|
28242
|
+
const MARKERLESS_SPEC_GRACE_MS = 5 * 6e4;
|
|
28243
|
+
const NEEDS_YOU_ATTEMPTS = 5;
|
|
28244
|
+
function normalizeIssueId(value) {
|
|
28245
|
+
return typeof value === "string" && /^[A-Za-z]+-\d+$/.test(value.trim()) ? value.trim().toUpperCase() : null;
|
|
28246
|
+
}
|
|
28247
|
+
function issueIdFromWorkspaceName(name) {
|
|
28248
|
+
const match = name.match(/^feature-([a-z]+-\d+)$/i);
|
|
28249
|
+
return match ? match[1].toUpperCase() : null;
|
|
28250
|
+
}
|
|
28251
|
+
function parseDate(value) {
|
|
28252
|
+
if (typeof value !== "string") return null;
|
|
28253
|
+
const parsed = Date.parse(value);
|
|
28254
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
28255
|
+
}
|
|
28256
|
+
function parseMarker(value, expectedIssueId) {
|
|
28257
|
+
if (!value || typeof value !== "object") return null;
|
|
28258
|
+
const marker = value;
|
|
28259
|
+
const issueId = normalizeIssueId(marker["issueId"]);
|
|
28260
|
+
if (marker["version"] !== "1" || issueId !== expectedIssueId) return null;
|
|
28261
|
+
if (typeof marker["canonicalFilename"] !== "string" || marker["canonicalFilename"].length === 0) return null;
|
|
28262
|
+
if (parseDate(marker["finalizedAt"]) === null) return null;
|
|
28263
|
+
return {
|
|
28264
|
+
version: "1",
|
|
28265
|
+
issueId,
|
|
28266
|
+
canonicalFilename: marker["canonicalFilename"],
|
|
28267
|
+
noPrd: marker["noPrd"] === true,
|
|
28268
|
+
autoSpawnRequested: marker["autoSpawnRequested"] === true,
|
|
28269
|
+
finalizedAt: marker["finalizedAt"],
|
|
28270
|
+
lastError: typeof marker["lastError"] === "string" ? marker["lastError"] : "complete-planning failed",
|
|
28271
|
+
lastAttemptAt: typeof marker["lastAttemptAt"] === "string" ? marker["lastAttemptAt"] : marker["finalizedAt"],
|
|
28272
|
+
patrolAttempts: Number.isInteger(marker["patrolAttempts"]) && Number(marker["patrolAttempts"]) >= 0 ? Number(marker["patrolAttempts"]) : 0
|
|
28273
|
+
};
|
|
28274
|
+
}
|
|
28275
|
+
async function readMarker(path, issueId) {
|
|
28276
|
+
try {
|
|
28277
|
+
return parseMarker(JSON.parse(await readFile(path, "utf-8")), issueId);
|
|
28278
|
+
} catch {
|
|
28279
|
+
return null;
|
|
28280
|
+
}
|
|
28281
|
+
}
|
|
28282
|
+
async function loadProjects(projects) {
|
|
28283
|
+
if (projects) return projects;
|
|
28284
|
+
return Effect.runPromise(listProjects().pipe(Effect.catch(() => Effect.succeed([]))));
|
|
28285
|
+
}
|
|
28286
|
+
async function defaultFindPromotedSpec(projectPath, issueId) {
|
|
28287
|
+
return Effect.runPromise(findSpecByIssue(projectPath, issueId).pipe(Effect.catch(() => Effect.succeed(null))));
|
|
28288
|
+
}
|
|
28289
|
+
function internalDashboardOrigin() {
|
|
28290
|
+
const port = Number.parseInt(process.env["API_PORT"] ?? process.env["PORT"] ?? "3011", 10);
|
|
28291
|
+
return process.env["OVERDECK_INTERNAL_DASHBOARD_URL"] ?? `http://127.0.0.1:${port}`;
|
|
28292
|
+
}
|
|
28293
|
+
function logDiagnostic(kind, info = {}) {
|
|
28294
|
+
console.debug(`[pending-promotion-reconciler] ${kind}`, info);
|
|
28295
|
+
}
|
|
28296
|
+
function markerPathForWorkspace(workspacePath) {
|
|
28297
|
+
return join(workspacePath, WORKSPACE_RUNTIME_DIRNAME, PENDING_PROMOTION_FILENAME);
|
|
28298
|
+
}
|
|
28299
|
+
function canonicalFilenameFromSpec(doc) {
|
|
28300
|
+
const filename = doc.plan.metadata?.canonicalFilename;
|
|
28301
|
+
return typeof filename === "string" && filename.length > 0 ? filename : null;
|
|
28302
|
+
}
|
|
28303
|
+
async function writeMarker(path, marker) {
|
|
28304
|
+
await mkdir(dirname(path), { recursive: true });
|
|
28305
|
+
const tmp = `${path}.tmp`;
|
|
28306
|
+
await writeFile(tmp, JSON.stringify(marker, null, 2) + "\n", "utf-8");
|
|
28307
|
+
await rename(tmp, path);
|
|
28308
|
+
}
|
|
28309
|
+
const defaultMarkerIo = {
|
|
28310
|
+
read: readMarker,
|
|
28311
|
+
write: writeMarker,
|
|
28312
|
+
remove: (path) => rm(path, { force: true })
|
|
28313
|
+
};
|
|
28314
|
+
async function findPendingPromotionCandidates(options = {}) {
|
|
28315
|
+
const projects = await loadProjects(options.projects);
|
|
28316
|
+
const now = (options.clock ?? (() => /* @__PURE__ */ new Date()))().getTime();
|
|
28317
|
+
const findPromotedSpec = options.findPromotedSpec ?? defaultFindPromotedSpec;
|
|
28318
|
+
const markerIo = options.markerIo ?? defaultMarkerIo;
|
|
28319
|
+
const candidates = [];
|
|
28320
|
+
for (const { key, config } of projects) {
|
|
28321
|
+
const workspacesDir = join(config.path, "workspaces");
|
|
28322
|
+
const workspaces = await readdir(workspacesDir, { withFileTypes: true }).catch(() => []);
|
|
28323
|
+
for (const workspace of workspaces) {
|
|
28324
|
+
if (!workspace.isDirectory() || workspace.name.endsWith("-strike")) continue;
|
|
28325
|
+
const issueId = issueIdFromWorkspaceName(workspace.name);
|
|
28326
|
+
if (!issueId) continue;
|
|
28327
|
+
const workspacePath = join(workspacesDir, workspace.name);
|
|
28328
|
+
const markerPath = markerPathForWorkspace(workspacePath);
|
|
28329
|
+
const marker = await markerIo.read(markerPath, issueId);
|
|
28330
|
+
const specPath = findWorkspaceDraftPlanSync(workspacePath);
|
|
28331
|
+
if (!specPath) continue;
|
|
28332
|
+
let spec;
|
|
28333
|
+
try {
|
|
28334
|
+
spec = readPlanSync(specPath);
|
|
28335
|
+
} catch {
|
|
28336
|
+
logDiagnostic("candidate-skipped", {
|
|
28337
|
+
issueId,
|
|
28338
|
+
reason: "spec-unreadable"
|
|
28339
|
+
});
|
|
28340
|
+
continue;
|
|
28341
|
+
}
|
|
28342
|
+
if (spec.plan.status !== "proposed" || normalizeIssueId(spec.plan.id) !== issueId) continue;
|
|
28343
|
+
if (marker) {
|
|
28344
|
+
candidates.push({
|
|
28345
|
+
projectKey: key,
|
|
28346
|
+
projectName: config.name,
|
|
28347
|
+
projectPath: config.path,
|
|
28348
|
+
workspacePath,
|
|
28349
|
+
issueId,
|
|
28350
|
+
specPath,
|
|
28351
|
+
markerPath,
|
|
28352
|
+
marker,
|
|
28353
|
+
canonicalFilename: marker.canonicalFilename,
|
|
28354
|
+
noPrd: marker.noPrd,
|
|
28355
|
+
autoSpawnRequested: marker.autoSpawnRequested,
|
|
28356
|
+
finalizedAt: marker.finalizedAt,
|
|
28357
|
+
patrolAttempts: marker.patrolAttempts
|
|
28358
|
+
});
|
|
28359
|
+
continue;
|
|
28360
|
+
}
|
|
28361
|
+
if (spec.plan.metadata?.promotionIntent === "manual") continue;
|
|
28362
|
+
const specInfo = await stat$1(specPath).catch(() => null);
|
|
28363
|
+
if (!specInfo || now - specInfo.mtimeMs < MARKERLESS_SPEC_GRACE_MS) continue;
|
|
28364
|
+
if (await findPromotedSpec(config.path, issueId)) continue;
|
|
28365
|
+
const canonicalFilename = canonicalFilenameFromSpec(spec);
|
|
28366
|
+
if (!canonicalFilename) {
|
|
28367
|
+
logDiagnostic("candidate-skipped", {
|
|
28368
|
+
issueId,
|
|
28369
|
+
reason: "canonical-filename-missing"
|
|
28370
|
+
});
|
|
28371
|
+
continue;
|
|
28372
|
+
}
|
|
28373
|
+
candidates.push({
|
|
28374
|
+
projectKey: key,
|
|
28375
|
+
projectName: config.name,
|
|
28376
|
+
projectPath: config.path,
|
|
28377
|
+
workspacePath,
|
|
28378
|
+
issueId,
|
|
28379
|
+
specPath,
|
|
28380
|
+
markerPath,
|
|
28381
|
+
marker: null,
|
|
28382
|
+
canonicalFilename,
|
|
28383
|
+
noPrd: false,
|
|
28384
|
+
autoSpawnRequested: false,
|
|
28385
|
+
finalizedAt: specInfo.mtime.toISOString(),
|
|
28386
|
+
patrolAttempts: 0
|
|
28387
|
+
});
|
|
28388
|
+
}
|
|
28389
|
+
}
|
|
28390
|
+
return candidates;
|
|
28391
|
+
}
|
|
28392
|
+
function parseResponseBody(text) {
|
|
28393
|
+
try {
|
|
28394
|
+
const parsed = JSON.parse(text);
|
|
28395
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
28396
|
+
} catch {
|
|
28397
|
+
return {};
|
|
28398
|
+
}
|
|
28399
|
+
}
|
|
28400
|
+
function responseError(status, body, text) {
|
|
28401
|
+
if (typeof body["error"] === "string") return body["error"];
|
|
28402
|
+
if (typeof body["message"] === "string") return body["message"];
|
|
28403
|
+
return text.slice(0, 200) || `complete-planning returned HTTP ${status}`;
|
|
28404
|
+
}
|
|
28405
|
+
function responseStillPending(status, body) {
|
|
28406
|
+
return status === 202 || body["inFlight"] === true || typeof body["skipped"] === "string";
|
|
28407
|
+
}
|
|
28408
|
+
async function reconcilePendingPromotions(options = {}) {
|
|
28409
|
+
const now = (options.clock ?? (() => /* @__PURE__ */ new Date()))();
|
|
28410
|
+
const nowMs = now.getTime();
|
|
28411
|
+
const fetchImpl = options.fetch ?? fetch;
|
|
28412
|
+
const dashboardOrigin = options.dashboardOrigin ?? internalDashboardOrigin();
|
|
28413
|
+
const internalToken = (options.getInternalToken ?? getInternalTokenSync)();
|
|
28414
|
+
const findPromotedSpec = options.findPromotedSpec ?? defaultFindPromotedSpec;
|
|
28415
|
+
const isClosed = options.isClosed ?? ((issueId) => isIssueClosed(issueId));
|
|
28416
|
+
const recordNeedsYou = options.recordNeedsYou ?? recordDeadEndNeedsYou;
|
|
28417
|
+
const emitActivity = options.emitActivity ?? emitActivityEntrySync;
|
|
28418
|
+
const markerIo = options.markerIo ?? defaultMarkerIo;
|
|
28419
|
+
const candidates = await findPendingPromotionCandidates({
|
|
28420
|
+
...options,
|
|
28421
|
+
clock: () => now,
|
|
28422
|
+
findPromotedSpec,
|
|
28423
|
+
markerIo
|
|
28424
|
+
});
|
|
28425
|
+
const actions = [];
|
|
28426
|
+
for (const candidate of candidates) {
|
|
28427
|
+
if (await isClosed(candidate.issueId)) {
|
|
28428
|
+
logDiagnostic("candidate-skipped", {
|
|
28429
|
+
issueId: candidate.issueId,
|
|
28430
|
+
reason: "closed"
|
|
28431
|
+
});
|
|
28432
|
+
continue;
|
|
28433
|
+
}
|
|
28434
|
+
if (await findPromotedSpec(candidate.projectPath, candidate.issueId)) {
|
|
28435
|
+
await markerIo.remove(candidate.markerPath);
|
|
28436
|
+
actions.push(`Cleared resolved pending-promotion marker for ${candidate.issueId}`);
|
|
28437
|
+
continue;
|
|
28438
|
+
}
|
|
28439
|
+
const finalizedAtMs = parseDate(candidate.finalizedAt);
|
|
28440
|
+
if (finalizedAtMs === null || nowMs - finalizedAtMs < MARKER_GRACE_MS) {
|
|
28441
|
+
logDiagnostic("candidate-skipped", {
|
|
28442
|
+
issueId: candidate.issueId,
|
|
28443
|
+
reason: "grace-window"
|
|
28444
|
+
});
|
|
28445
|
+
continue;
|
|
28446
|
+
}
|
|
28447
|
+
let response = null;
|
|
28448
|
+
let body = {};
|
|
28449
|
+
let error = null;
|
|
28450
|
+
try {
|
|
28451
|
+
response = await fetchImpl(new URL(`/api/issues/${encodeURIComponent(candidate.issueId)}/complete-planning`, dashboardOrigin), {
|
|
28452
|
+
method: "POST",
|
|
28453
|
+
headers: {
|
|
28454
|
+
"content-type": "application/json",
|
|
28455
|
+
origin: dashboardOrigin,
|
|
28456
|
+
...internalToken ? { [INTERNAL_TOKEN_HEADER]: internalToken } : {}
|
|
28457
|
+
},
|
|
28458
|
+
body: JSON.stringify({
|
|
28459
|
+
noPrd: candidate.noPrd,
|
|
28460
|
+
startedBy: "pending-promotion-reconciler"
|
|
28461
|
+
})
|
|
28462
|
+
});
|
|
28463
|
+
const text = await response.text();
|
|
28464
|
+
body = parseResponseBody(text);
|
|
28465
|
+
if (responseStillPending(response.status, body)) {
|
|
28466
|
+
logDiagnostic("promotion-deferred", {
|
|
28467
|
+
issueId: candidate.issueId,
|
|
28468
|
+
status: response.status,
|
|
28469
|
+
body
|
|
28470
|
+
});
|
|
28471
|
+
continue;
|
|
28472
|
+
}
|
|
28473
|
+
if (response.status !== 200 || !response.ok || body["success"] === false || body["ok"] === false) error = responseError(response.status, body, text);
|
|
28474
|
+
} catch (cause) {
|
|
28475
|
+
error = cause instanceof Error ? cause.message : String(cause);
|
|
28476
|
+
}
|
|
28477
|
+
if (!error && response?.status === 200) {
|
|
28478
|
+
await markerIo.remove(candidate.markerPath);
|
|
28479
|
+
const action = `Recovered pending planning promotion for ${candidate.issueId}`;
|
|
28480
|
+
actions.push(action);
|
|
28481
|
+
emitActivity({
|
|
28482
|
+
source: "cloister",
|
|
28483
|
+
level: "success",
|
|
28484
|
+
issueId: candidate.issueId,
|
|
28485
|
+
message: `${candidate.issueId} planning promotion recovered automatically`,
|
|
28486
|
+
details: JSON.stringify({
|
|
28487
|
+
issueId: candidate.issueId,
|
|
28488
|
+
workspacePath: candidate.workspacePath,
|
|
28489
|
+
reconciler: "pending-promotion",
|
|
28490
|
+
timestamp: now.toISOString()
|
|
28491
|
+
})
|
|
28492
|
+
});
|
|
28493
|
+
continue;
|
|
28494
|
+
}
|
|
28495
|
+
const nextAttempts = candidate.patrolAttempts + 1;
|
|
28496
|
+
const lastError = error ?? "complete-planning did not converge";
|
|
28497
|
+
await markerIo.write(candidate.markerPath, {
|
|
28498
|
+
version: "1",
|
|
28499
|
+
issueId: candidate.issueId,
|
|
28500
|
+
canonicalFilename: candidate.canonicalFilename,
|
|
28501
|
+
noPrd: candidate.noPrd,
|
|
28502
|
+
autoSpawnRequested: candidate.autoSpawnRequested,
|
|
28503
|
+
finalizedAt: candidate.finalizedAt,
|
|
28504
|
+
lastError,
|
|
28505
|
+
lastAttemptAt: now.toISOString(),
|
|
28506
|
+
patrolAttempts: nextAttempts
|
|
28507
|
+
});
|
|
28508
|
+
logDiagnostic("promotion-failed", {
|
|
28509
|
+
issueId: candidate.issueId,
|
|
28510
|
+
patrolAttempts: nextAttempts,
|
|
28511
|
+
error: lastError
|
|
28512
|
+
});
|
|
28513
|
+
actions.push(`Pending planning promotion for ${candidate.issueId} failed attempt ${nextAttempts}: ${lastError}`);
|
|
28514
|
+
if (nextAttempts >= NEEDS_YOU_ATTEMPTS) await recordNeedsYou(candidate.issueId, "pending-promotion", candidate.finalizedAt, `Planning promotion for ${candidate.issueId} has failed ${nextAttempts} patrol attempts. The finalized plan remains unpromoted. Run \`pan plan done ${candidate.issueId}\` to retry manually, then inspect the complete-planning error if it still fails.`);
|
|
28515
|
+
}
|
|
28516
|
+
return actions;
|
|
28517
|
+
}
|
|
28518
|
+
//#endregion
|
|
28058
28519
|
//#region ../../lib/cloister/test-status-green-ci-reconciler.ts
|
|
28059
28520
|
const terminalMergeStatuses = new Set([
|
|
28060
28521
|
"merged",
|
|
@@ -28554,6 +29015,175 @@ async function cleanupOrphanedInspectSessions() {
|
|
|
28554
29015
|
return actions;
|
|
28555
29016
|
}
|
|
28556
29017
|
//#endregion
|
|
29018
|
+
//#region ../../lib/cloister/deacon-verdict-fallback-sweep.ts
|
|
29019
|
+
init_test_verdict();
|
|
29020
|
+
init_review_status();
|
|
29021
|
+
init_review_status_record_sync();
|
|
29022
|
+
init_projects();
|
|
29023
|
+
init_recovery_trip();
|
|
29024
|
+
init_activity_logger();
|
|
29025
|
+
/**
|
|
29026
|
+
* Total time this sweep may spend waiting on warning delivery, across ALL issues.
|
|
29027
|
+
*
|
|
29028
|
+
* Bounding each request alone is not enough: the sweep visits issues serially,
|
|
29029
|
+
* so N stranded fallbacks against a stalled dashboard would cost N × the
|
|
29030
|
+
* per-request deadline — six would consume a whole 60s patrol interval and dozens
|
|
29031
|
+
* would hold it for many minutes, starving every later issue and later patrol
|
|
29032
|
+
* phase while the patrol heartbeat still reported healthy. The systemic
|
|
29033
|
+
* degradation that strands several verdicts at once is exactly the state that
|
|
29034
|
+
* makes every loopback request hit its deadline, so the budget is shared.
|
|
29035
|
+
*/
|
|
29036
|
+
const SWEEP_WARNING_BUDGET_MS = 30 * 1e3;
|
|
29037
|
+
/**
|
|
29038
|
+
* Resolve `attempt`, or give up at `deadlineMs` and report `failed`.
|
|
29039
|
+
*
|
|
29040
|
+
* Abandoning a warning is always safe: nothing is marked warned on `failed`, and
|
|
29041
|
+
* a later retry carries the same idempotency key, so a call that lands after we
|
|
29042
|
+
* stopped waiting returns `duplicate` rather than emitting a second warning.
|
|
29043
|
+
*/
|
|
29044
|
+
async function withWarningDeadline(attempt, deadlineMs) {
|
|
29045
|
+
let timer;
|
|
29046
|
+
try {
|
|
29047
|
+
return await Promise.race([attempt, new Promise((resolve) => {
|
|
29048
|
+
timer = setTimeout(() => {
|
|
29049
|
+
resolve("failed");
|
|
29050
|
+
}, deadlineMs);
|
|
29051
|
+
})]);
|
|
29052
|
+
} finally {
|
|
29053
|
+
if (timer) clearTimeout(timer);
|
|
29054
|
+
}
|
|
29055
|
+
}
|
|
29056
|
+
/**
|
|
29057
|
+
* Episodes already warned about in THIS process, keyed by recovery path + issue
|
|
29058
|
+
* + the fallback's own `updatedAt`.
|
|
29059
|
+
*
|
|
29060
|
+
* Only an optimisation, never the dedupe of record: it saves re-querying the
|
|
29061
|
+
* event log every patrol. Correctness across restarts comes from the two
|
|
29062
|
+
* durable planes — the open recovery trip, and `emitActivityEntryOnce`'s
|
|
29063
|
+
* event-log check on the episode id. An episode is added here only after the
|
|
29064
|
+
* warning is confirmed durable, so a failed append is retried rather than
|
|
29065
|
+
* suppressed, and entries are dropped once the trip lands.
|
|
29066
|
+
*/
|
|
29067
|
+
const warnedEpisodes = /* @__PURE__ */ new Set();
|
|
29068
|
+
/**
|
|
29069
|
+
* Describe a verdict conflict and the one action that reliably clears it.
|
|
29070
|
+
*
|
|
29071
|
+
* Deliberately does NOT hand out a `pan admin specialists done` command. That
|
|
29072
|
+
* command is not a general conflict resolver: `merge` takes passed|failed and
|
|
29073
|
+
* maps them to merged|failed (so the displayed `merged` is rejected), `inspect`
|
|
29074
|
+
* requires an `--item` this pipeline-level conflict cannot identify, `review`
|
|
29075
|
+
* does not accept `skipped`, verification has no specialist at all, and
|
|
29076
|
+
* re-signalling the value already in the journal writes no replacement fallback
|
|
29077
|
+
* — so the conflicting one survives and every later drain withholds it again.
|
|
29078
|
+
* A conflict can also span several gates, which one command cannot settle.
|
|
29079
|
+
*
|
|
29080
|
+
* A strictly newer review cycle is the only instruction correct for every gate
|
|
29081
|
+
* and every choice, so that is what the operator is told, along with what it
|
|
29082
|
+
* costs. A dedicated resolve-this-generation operation through the verdict write
|
|
29083
|
+
* door would let an operator adopt a specific written verdict instead; until
|
|
29084
|
+
* that exists, promising it here would be a lie.
|
|
29085
|
+
*/
|
|
29086
|
+
function conflictMessage(issueId, conflicts, ageMinutes) {
|
|
29087
|
+
const detail = conflicts.map((c) => `${c.gate} (the record holds "${c.journalValue}", the workspace fallback holds "${c.fallbackValue}")`).join("; ");
|
|
29088
|
+
return `${issueId} — two different verdicts have been written for ${conflicts.length === 1 ? "one gate" : `${conflicts.length} gates`} and Overdeck cannot tell which is newer, so it refuses to choose: ${detail}. This has been unresolved for ${ageMinutes}min and will NOT clear on its own: the fold is withheld on every patrol, by design, so that neither written verdict is destroyed. An operator must decide. The one action that reliably clears it for every gate is to dispatch a strictly newer review cycle for ${issueId} — that supersedes the stranded fallback and re-runs the gates, rather than adopting either of the verdicts already written. Overdeck has no command today that adopts one specific written verdict, so do not expect a re-signal of an existing value to clear this.`;
|
|
29089
|
+
}
|
|
29090
|
+
async function lockOwnerDescription(issueId) {
|
|
29091
|
+
try {
|
|
29092
|
+
const resolved = resolveProjectFromIssueSync(issueId);
|
|
29093
|
+
if (!resolved) return "unknown writer";
|
|
29094
|
+
const project = getProjectSync(resolved.projectKey);
|
|
29095
|
+
if (!project) return "unknown writer";
|
|
29096
|
+
return (await readOwner(recordLockPath(project, issueId))).description;
|
|
29097
|
+
} catch {
|
|
29098
|
+
return "unknown writer";
|
|
29099
|
+
}
|
|
29100
|
+
}
|
|
29101
|
+
/**
|
|
29102
|
+
* Drain every pending workspace verdict fallback, and surface the ones that stay
|
|
29103
|
+
* stuck. Returns one action line per drain or escalation, for the patrol log.
|
|
29104
|
+
*
|
|
29105
|
+
* `budgetMs` bounds the total time spent waiting on warning delivery. The deacon
|
|
29106
|
+
* derives it from the resolved patrol interval so a shortened interval cannot be
|
|
29107
|
+
* overrun by the sweep.
|
|
29108
|
+
*/
|
|
29109
|
+
async function sweepStrandedVerdictFallbacks(now = Date.now(), budgetMs = SWEEP_WARNING_BUDGET_MS) {
|
|
29110
|
+
const actions = [];
|
|
29111
|
+
let statuses;
|
|
29112
|
+
try {
|
|
29113
|
+
statuses = loadReviewStatuses();
|
|
29114
|
+
} catch {
|
|
29115
|
+
return actions;
|
|
29116
|
+
}
|
|
29117
|
+
const candidates = [];
|
|
29118
|
+
for (const [issueId, status] of Object.entries(statuses)) {
|
|
29119
|
+
if (status.mergeStatus === "merged" || status.closedOut) continue;
|
|
29120
|
+
try {
|
|
29121
|
+
const fallback = await readWorkspaceVerdictFallback(issueId);
|
|
29122
|
+
if (!fallback) continue;
|
|
29123
|
+
if (await drainWorkspaceVerdictFallback(issueId)) {
|
|
29124
|
+
actions.push(`Drained stranded verdict fallback for ${issueId}`);
|
|
29125
|
+
continue;
|
|
29126
|
+
}
|
|
29127
|
+
const ageMs = now - Date.parse(fallback.updatedAt);
|
|
29128
|
+
if (!Number.isFinite(ageMs) || ageMs < 6e5) continue;
|
|
29129
|
+
if (status.stuck || status.deaconIgnored) continue;
|
|
29130
|
+
const resolved = resolveProjectFromIssueSync(issueId);
|
|
29131
|
+
const workspacePath = resolved ? findWorkspacePath(resolved.projectPath, issueId.toLowerCase()) : null;
|
|
29132
|
+
if (!workspacePath) continue;
|
|
29133
|
+
const ageMinutes = Math.round(ageMs / 6e4);
|
|
29134
|
+
const conflicts = await findWorkspaceVerdictConflicts(issueId, fallback);
|
|
29135
|
+
const conflicted = conflicts.length > 0;
|
|
29136
|
+
const recoveryPath = conflicted ? "verdict-fallback-conflict" : "verdict-fallback-contention";
|
|
29137
|
+
const episode = `${recoveryPath}:${issueId}:${fallback.updatedAt}`;
|
|
29138
|
+
let message;
|
|
29139
|
+
let summary;
|
|
29140
|
+
if (conflicted) {
|
|
29141
|
+
message = conflictMessage(issueId, conflicts, ageMinutes);
|
|
29142
|
+
summary = `${issueId}: verdict conflict on ${conflicts.map((c) => c.gate).join(", ")} — needs operator adjudication`;
|
|
29143
|
+
} else {
|
|
29144
|
+
const owner = await lockOwnerDescription(issueId);
|
|
29145
|
+
message = `${issueId} — verdict fallback undrained for ${ageMinutes}min; the per-issue record lock is contended (current owner: ${owner}). The verdict is durable in the workspace fallback and folds automatically once the lock frees.`;
|
|
29146
|
+
summary = `${issueId}: verdict contended ${ageMinutes}min (lock owner: ${owner})`;
|
|
29147
|
+
}
|
|
29148
|
+
if ((await findRecoveryTrip(issueId, recoveryPath, fallback.updatedAt))?.open === true) {
|
|
29149
|
+
warnedEpisodes.delete(episode);
|
|
29150
|
+
continue;
|
|
29151
|
+
}
|
|
29152
|
+
candidates.push({
|
|
29153
|
+
issueId,
|
|
29154
|
+
workspacePath,
|
|
29155
|
+
recoveryPath,
|
|
29156
|
+
generation: fallback.updatedAt,
|
|
29157
|
+
episode,
|
|
29158
|
+
message,
|
|
29159
|
+
summary
|
|
29160
|
+
});
|
|
29161
|
+
} catch {}
|
|
29162
|
+
}
|
|
29163
|
+
const pending = candidates.filter((c) => !warnedEpisodes.has(c.episode));
|
|
29164
|
+
if (pending.length > 0) (await Promise.all(pending.map((candidate) => withWarningDeadline(emitActivityEntryOnce({
|
|
29165
|
+
id: `verdict-fallback:${candidate.episode}`,
|
|
29166
|
+
source: "cloister",
|
|
29167
|
+
level: "warn",
|
|
29168
|
+
issueId: candidate.issueId,
|
|
29169
|
+
message: candidate.message
|
|
29170
|
+
}), budgetMs).catch(() => "failed")))).forEach((outcome, index) => {
|
|
29171
|
+
const candidate = pending[index];
|
|
29172
|
+
if (outcome === "appended" || outcome === "duplicate") {
|
|
29173
|
+
warnedEpisodes.add(candidate.episode);
|
|
29174
|
+
if (outcome === "appended") actions.push(candidate.summary);
|
|
29175
|
+
} else actions.push(`${candidate.issueId}: verdict-fallback warning could not be confirmed — retrying next patrol`);
|
|
29176
|
+
});
|
|
29177
|
+
for (const candidate of candidates) try {
|
|
29178
|
+
const { emitNeedsYou } = await recordRecoveryFailure(candidate.workspacePath, candidate.issueId, candidate.recoveryPath, candidate.generation, 1);
|
|
29179
|
+
warnedEpisodes.delete(candidate.episode);
|
|
29180
|
+
if (emitNeedsYou) actions.push(`needs-you ${candidate.summary}`);
|
|
29181
|
+
} catch {
|
|
29182
|
+
actions.push(`${candidate.issueId}: ${candidate.recoveryPath} needs-you trip could not be recorded (record lock contended) — retrying next patrol`);
|
|
29183
|
+
}
|
|
29184
|
+
return actions;
|
|
29185
|
+
}
|
|
29186
|
+
//#endregion
|
|
28557
29187
|
//#region ../../lib/cloister/deacon.ts
|
|
28558
29188
|
/**
|
|
28559
29189
|
* Cloister Deacon - Health Monitor for Specialist Agents
|
|
@@ -28580,7 +29210,6 @@ init_specialists();
|
|
|
28580
29210
|
init_agents$1();
|
|
28581
29211
|
init_tmux();
|
|
28582
29212
|
init_issue_closed();
|
|
28583
|
-
init_test_verdict();
|
|
28584
29213
|
const execAsync = promisify$1(exec$1);
|
|
28585
29214
|
promisify$1(execFile$1);
|
|
28586
29215
|
/**
|
|
@@ -28843,8 +29472,8 @@ async function cleanupStaleAgentState() {
|
|
|
28843
29472
|
*/
|
|
28844
29473
|
async function cleanupAbandonedFeedback() {
|
|
28845
29474
|
const actions = [];
|
|
28846
|
-
const { getReviewStatusSync } = await import("./review-status-
|
|
28847
|
-
const { clearFeedbackFiles } = await import("./feedback-writer-
|
|
29475
|
+
const { getReviewStatusSync } = await import("./review-status-B6wYcOtP.js");
|
|
29476
|
+
const { clearFeedbackFiles } = await import("./feedback-writer-CTSuA6lw.js");
|
|
28848
29477
|
for (const { issueId, workspacePath } of listFeatureWorkspaces()) {
|
|
28849
29478
|
const panFeedbackDir = join$1(workspacePath, ".pan", "feedback");
|
|
28850
29479
|
if (!existsSync(panFeedbackDir)) continue;
|
|
@@ -28915,7 +29544,7 @@ async function handleOrphanReviewerSession(sessionName, sessions, creationTimes,
|
|
|
28915
29544
|
if (!issueId) return null;
|
|
28916
29545
|
const agentSession = `agent-${issueId.toLowerCase()}`;
|
|
28917
29546
|
if (sessions.includes(agentSession)) return null;
|
|
28918
|
-
const { getReviewStatusSync } = await import("./review-status-
|
|
29547
|
+
const { getReviewStatusSync } = await import("./review-status-B6wYcOtP.js");
|
|
28919
29548
|
try {
|
|
28920
29549
|
if (getReviewStatusSync(issueId)?.reviewStatus === "reviewing") return null;
|
|
28921
29550
|
} catch {}
|
|
@@ -29037,7 +29666,7 @@ async function checkOrphanedCompletions() {
|
|
|
29037
29666
|
async function checkPendingTestDispatch() {
|
|
29038
29667
|
const actions = [];
|
|
29039
29668
|
try {
|
|
29040
|
-
const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-
|
|
29669
|
+
const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-B6wYcOtP.js");
|
|
29041
29670
|
const statuses = loadReviewStatuses();
|
|
29042
29671
|
const now = Date.now();
|
|
29043
29672
|
for (const [issueId, status] of Object.entries(statuses)) {
|
|
@@ -29070,7 +29699,7 @@ async function checkPendingTestDispatch() {
|
|
|
29070
29699
|
console.log(`[deacon] ${issueId}: skipping test re-dispatch — issue is closed`);
|
|
29071
29700
|
continue;
|
|
29072
29701
|
}
|
|
29073
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
29702
|
+
const { resolveProjectFromIssueSync } = await import("./projects-WqMWCdpa.js");
|
|
29074
29703
|
const resolved = resolveProjectFromIssueSync(issueId);
|
|
29075
29704
|
if (!resolved) continue;
|
|
29076
29705
|
const issueLower = issueId.toLowerCase();
|
|
@@ -29085,8 +29714,8 @@ async function checkPendingTestDispatch() {
|
|
|
29085
29714
|
logDeaconEventSync(`checkPendingTestDispatch: deferred test for ${issueId} — advancing ceiling reached (PAN-1665) — ${describeRunningAgents()}`);
|
|
29086
29715
|
continue;
|
|
29087
29716
|
}
|
|
29088
|
-
const { spawnRun } = await import("./agents-
|
|
29089
|
-
const { buildTestRolePrompt } = await import("./test-agent-queue-
|
|
29717
|
+
const { spawnRun } = await import("./agents-IPSa5kzn.js");
|
|
29718
|
+
const { buildTestRolePrompt } = await import("./test-agent-queue-CWMq7oyG.js");
|
|
29090
29719
|
try {
|
|
29091
29720
|
const run = await spawnRun(issueId, "test", {
|
|
29092
29721
|
workspace,
|
|
@@ -29162,6 +29791,8 @@ async function checkPendingTestDispatch() {
|
|
|
29162
29791
|
* - Only honors an artifact newer than the current test dispatch (H3)
|
|
29163
29792
|
*/
|
|
29164
29793
|
const unsignaledTestNudges = /* @__PURE__ */ new Map();
|
|
29794
|
+
/** PAN-3092: test dispatch generations already escalated — never nudged again. */
|
|
29795
|
+
const unsignaledTestEscalations = /* @__PURE__ */ new Set();
|
|
29165
29796
|
async function checkCompletedButUnsignaledTests() {
|
|
29166
29797
|
const actions = [];
|
|
29167
29798
|
const TEST_SETTLE_MS = 300 * 1e3;
|
|
@@ -29184,13 +29815,13 @@ async function checkCompletedButUnsignaledTests() {
|
|
|
29184
29815
|
const paneDead = sessionAlive ? await Effect.runPromise(isPaneDead(testSession)).catch(() => true) : true;
|
|
29185
29816
|
const sessionLive = sessionAlive && !paneDead;
|
|
29186
29817
|
const idle = sessionLive ? isAgentIdleForNudge(testSession, TEST_SETTLE_MS, now) : false;
|
|
29187
|
-
const lastNudged = unsignaledTestNudges.get(testSession);
|
|
29188
|
-
const alreadyNudged = !!(lastNudged && now - lastNudged < NUDGE_DEDUP_MS);
|
|
29189
29818
|
const lastDispatchAt = status.history?.filter((h) => h.type === "test" && h.status === "testing").pop()?.timestamp;
|
|
29819
|
+
const lastNudged = unsignaledTestNudges.get(testSession);
|
|
29820
|
+
const escalationKey = `${testSession}:${lastDispatchAt ?? "unknown"}`;
|
|
29190
29821
|
const decision = decideUnsignaledTestAction({
|
|
29191
29822
|
sessionLive,
|
|
29192
29823
|
idle,
|
|
29193
|
-
alreadyNudged,
|
|
29824
|
+
alreadyNudged: unsignaledTestEscalations.has(escalationKey) || !!(lastNudged && now - lastNudged < NUDGE_DEDUP_MS),
|
|
29194
29825
|
artifact: readTestVerdictArtifact(wsPath, lastDispatchAt ? new Date(lastDispatchAt).getTime() : void 0)
|
|
29195
29826
|
});
|
|
29196
29827
|
switch (decision.action) {
|
|
@@ -29210,7 +29841,7 @@ async function checkCompletedButUnsignaledTests() {
|
|
|
29210
29841
|
const cmd = `pan admin specialists done test ${issueId} --status ${decision.status}${noteArg}`;
|
|
29211
29842
|
const nudge = `Your test verdict (${decision.status}) is already written to .pan/test/result.json. Your ONLY remaining task is to execute this Bash command immediately — do not analyze, do not summarize, do not ask questions, just run it:\n\n${cmd}\n\nRun this command NOW. Do not write any other response before executing it.`;
|
|
29212
29843
|
try {
|
|
29213
|
-
const { messageAgent } = await import("./agents-
|
|
29844
|
+
const { messageAgent } = await import("./agents-IPSa5kzn.js");
|
|
29214
29845
|
await messageAgent(testSession, nudge);
|
|
29215
29846
|
unsignaledTestNudges.set(testSession, now);
|
|
29216
29847
|
const msg = `Nudged ${testSession} to signal ${decision.status} (verdict artifact present)`;
|
|
@@ -29224,7 +29855,7 @@ async function checkCompletedButUnsignaledTests() {
|
|
|
29224
29855
|
case "nudge-write": {
|
|
29225
29856
|
const nudge = `Your test run for ${issueId} looks finished but no verdict was recorded. Decide the verdict from the gates/UAT you ran, then do BOTH of these now: (1) write the workspace file .pan/test/result.json as {"status":"passed"|"failed","notes":"<evidence>"}, and (2) run: pan admin specialists done test ${issueId} --status passed|failed. Do this immediately — do not summarize or ask questions, just write the file and run the command.`;
|
|
29226
29857
|
try {
|
|
29227
|
-
const { messageAgent } = await import("./agents-
|
|
29858
|
+
const { messageAgent } = await import("./agents-IPSa5kzn.js");
|
|
29228
29859
|
await messageAgent(testSession, nudge);
|
|
29229
29860
|
unsignaledTestNudges.set(testSession, now);
|
|
29230
29861
|
const msg = `Nudged ${testSession} to write+signal a test verdict (no artifact yet)`;
|
|
@@ -29235,6 +29866,15 @@ async function checkCompletedButUnsignaledTests() {
|
|
|
29235
29866
|
}
|
|
29236
29867
|
break;
|
|
29237
29868
|
}
|
|
29869
|
+
case "escalate": {
|
|
29870
|
+
unsignaledTestEscalations.add(escalationKey);
|
|
29871
|
+
const msg = await recordUnsignaledTestEscalation(wsPath, issueId, testSession, lastDispatchAt ?? "unknown");
|
|
29872
|
+
if (msg) {
|
|
29873
|
+
actions.push(msg);
|
|
29874
|
+
console.warn(`[deacon] ${msg}`);
|
|
29875
|
+
}
|
|
29876
|
+
break;
|
|
29877
|
+
}
|
|
29238
29878
|
default: break;
|
|
29239
29879
|
}
|
|
29240
29880
|
}
|
|
@@ -29247,8 +29887,8 @@ async function checkCompletedButUnsignaledTests() {
|
|
|
29247
29887
|
async function checkVerificationReviewContradiction() {
|
|
29248
29888
|
const actions = [];
|
|
29249
29889
|
try {
|
|
29250
|
-
const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-
|
|
29251
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
29890
|
+
const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-B6wYcOtP.js");
|
|
29891
|
+
const { resolveProjectFromIssueSync } = await import("./projects-WqMWCdpa.js");
|
|
29252
29892
|
const statuses = loadReviewStatuses();
|
|
29253
29893
|
for (const [issueId, status] of Object.entries(statuses)) if (status.verificationStatus === "passed" && status.reviewStatus === "reviewing" && status.stuckReason === "review_infrastructure_failure") {
|
|
29254
29894
|
let reviewedAtCommit;
|
|
@@ -29257,7 +29897,7 @@ async function checkVerificationReviewContradiction() {
|
|
|
29257
29897
|
if (project) {
|
|
29258
29898
|
const workspacePath = join$1(project.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
|
|
29259
29899
|
if (existsSync(workspacePath)) {
|
|
29260
|
-
const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-
|
|
29900
|
+
const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-C31x1lpE.js");
|
|
29261
29901
|
reviewedAtCommit = await snapshotWorkspaceHeadsPromise(issueId, workspacePath);
|
|
29262
29902
|
}
|
|
29263
29903
|
}
|
|
@@ -29353,7 +29993,7 @@ async function checkReadyForMergeStuck() {
|
|
|
29353
29993
|
const testStatusGreenCiReconcileCooldowns = /* @__PURE__ */ new Map();
|
|
29354
29994
|
const TEST_STATUS_GREEN_CI_RECONCILE_COOLDOWN_MS = 300 * 1e3;
|
|
29355
29995
|
async function reconcileTestStatusFromGreenCi() {
|
|
29356
|
-
const { getCiCheckRunsState, getPullRequestHeadState, isGitHubAppConfigured } = await import("./github-app-
|
|
29996
|
+
const { getCiCheckRunsState, getPullRequestHeadState, isGitHubAppConfigured } = await import("./github-app-CpQSDlv8.js");
|
|
29357
29997
|
return reconcileTestStatusFromGreenCiWithDeps({
|
|
29358
29998
|
isGitHubAppConfigured,
|
|
29359
29999
|
loadReviewStatuses,
|
|
@@ -29374,7 +30014,7 @@ async function reconcileTestStatusFromGreenCi() {
|
|
|
29374
30014
|
*/
|
|
29375
30015
|
async function clearStaleCiFeedback(issueId) {
|
|
29376
30016
|
const { readdir, rm } = await import("fs/promises");
|
|
29377
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
30017
|
+
const { resolveProjectFromIssueSync } = await import("./projects-WqMWCdpa.js");
|
|
29378
30018
|
const projectConfig = resolveProjectFromIssueSync(issueId);
|
|
29379
30019
|
if (!projectConfig) return;
|
|
29380
30020
|
const repoDir = projectConfig.projectPath;
|
|
@@ -29395,26 +30035,21 @@ async function clearStaleCiFeedback(issueId) {
|
|
|
29395
30035
|
const deadEndCooldowns = /* @__PURE__ */ new Map();
|
|
29396
30036
|
const DEAD_END_STALENESS_MS = 300 * 1e3;
|
|
29397
30037
|
const DEAD_END_COOLDOWN_MS = 600 * 1e3;
|
|
29398
|
-
|
|
29399
|
-
* Detect dead-end agents: review blocked, tests failed, or merge failed (CI)
|
|
29400
|
-
* but work agent is idle.
|
|
29401
|
-
*
|
|
29402
|
-
* This happens when:
|
|
29403
|
-
* - Review feedback was delivered with a wrong URL (now fixed, but old feedback persists)
|
|
29404
|
-
* - Agent forgot how to resubmit (context compaction lost instructions)
|
|
29405
|
-
* - Feedback delivery to tmux failed silently
|
|
29406
|
-
* - Merge failed due to CI checks (now handled in checkFailedMergeRetry by routing
|
|
29407
|
-
* to the work agent with feedback; dead-end catches cases where the agent is idle)
|
|
29408
|
-
*
|
|
29409
|
-
* Recovery: re-queue the review via the request-review API endpoint and
|
|
29410
|
-
* send the agent a nudge message with the correct resubmit command.
|
|
29411
|
-
* For CI-blocked merges: clear the stale merge failure and feedback files.
|
|
29412
|
-
*/
|
|
29413
|
-
async function checkDeadEndAgents() {
|
|
30038
|
+
async function checkDeadEndAgents(deps = {}) {
|
|
29414
30039
|
const actions = [];
|
|
30040
|
+
const readReviewStatuses = deps.loadReviewStatuses ?? loadReviewStatuses;
|
|
30041
|
+
const hasSession = deps.sessionExistsSync ?? sessionExistsSync;
|
|
30042
|
+
const readAgentState = deps.getAgentStateSync ?? getAgentStateSync;
|
|
30043
|
+
const resolveAgentDir = deps.getAgentDir ?? getAgentDir;
|
|
30044
|
+
const decideRedrive = deps.decideAgentAutonomousRedrive ?? decideAgentAutonomousRedrive;
|
|
30045
|
+
const recordNeedsYou = deps.recordDeadEndNeedsYou ?? recordDeadEndNeedsYou;
|
|
30046
|
+
const spawnWorkAgent = deps.spawnWorkAgentThroughAgentsEndpoint ?? spawnWorkAgentThroughAgentsEndpoint;
|
|
30047
|
+
const updateReviewStatus = deps.setReviewStatusSync ?? setReviewStatusSync;
|
|
30048
|
+
const clearAgentTroubled = deps.clearAgentTroubledSync ?? clearAgentTroubledSync;
|
|
30049
|
+
const saveAgentState = deps.saveAgentStateSync ?? saveAgentStateSync;
|
|
29415
30050
|
try {
|
|
29416
|
-
const statuses =
|
|
29417
|
-
const now = Date.now();
|
|
30051
|
+
const statuses = readReviewStatuses();
|
|
30052
|
+
const now = deps.now?.() ?? Date.now();
|
|
29418
30053
|
for (const [key, status] of Object.entries(statuses)) {
|
|
29419
30054
|
const isReviewBlocked = status.reviewStatus === "blocked" || status.reviewStatus === "failed";
|
|
29420
30055
|
const isVerificationFailed = status.verificationStatus === "failed";
|
|
@@ -29445,24 +30080,27 @@ async function checkDeadEndAgents() {
|
|
|
29445
30080
|
else if (isVerificationFailed) statusType = status.reviewStatus === "pending" ? "verification failed while review pending" : "verification failed";
|
|
29446
30081
|
else if (isTestFailed) statusType = "tests failed";
|
|
29447
30082
|
else statusType = "merge CI blocked";
|
|
29448
|
-
if (!
|
|
30083
|
+
if (!hasSession(agentSessionName)) {
|
|
29449
30084
|
if (isReviewBlocked || isVerificationFailed || isTestFailed) {
|
|
29450
|
-
const agentState =
|
|
29451
|
-
const gateDecision =
|
|
30085
|
+
const agentState = readAgentState(agentSessionName);
|
|
30086
|
+
const gateDecision = await decideRedrive(agentState ?? {}, resolveAgentDir(agentSessionName), true);
|
|
29452
30087
|
if (gateDecision.decision === "defer") {
|
|
29453
30088
|
console.log(`[deacon] PAN-2209: ${issueId} (${statusType}) re-drive deferred — ${gateDecision.reason}`);
|
|
29454
|
-
const
|
|
30089
|
+
const pendingOperatorDecision = gateDecision.reason.startsWith("agent is waiting on an operator decision");
|
|
30090
|
+
const recoveryPath = pendingOperatorDecision ? "pending-operator-decision" : "operator-stopped-rework";
|
|
30091
|
+
const needsYouMessage = pendingOperatorDecision ? `Dead-end recovery needs-you: ${issueId} ${gateDecision.reason}. Answer it with 'pan answer ${issueId}'.` : `Dead-end recovery needs-you: ${issueId} was explicitly stopped before handoff`;
|
|
30092
|
+
const trip = gateDecision.needsYou && await recordNeedsYou(issueId, recoveryPath, status.updatedAt ?? statusType, needsYouMessage);
|
|
29455
30093
|
if (trip) actions.push(trip);
|
|
29456
30094
|
} else {
|
|
29457
30095
|
if (gateDecision.gateDecision.clearStoppedByUser && agentState) {
|
|
29458
30096
|
delete agentState.stoppedByUser;
|
|
29459
|
-
|
|
30097
|
+
saveAgentState(agentState);
|
|
29460
30098
|
}
|
|
29461
30099
|
deadEndCooldowns.set(key, now);
|
|
29462
|
-
|
|
29463
|
-
|
|
30100
|
+
updateReviewStatus(issueId, { autoRequeueCount: autoRequeueCount + 1 });
|
|
30101
|
+
clearAgentTroubled(agentSessionName);
|
|
29464
30102
|
try {
|
|
29465
|
-
const spawn = await
|
|
30103
|
+
const spawn = await spawnWorkAgent(issueId);
|
|
29466
30104
|
if (spawn.spawned) {
|
|
29467
30105
|
actions.push(`Dead-end recovery (PAN-2209): respawned dead work agent for ${issueId} (${statusType}) to address feedback`);
|
|
29468
30106
|
console.log(`[deacon] PAN-2209: respawned dead work agent for ${issueId} (${statusType})`);
|
|
@@ -29618,7 +30256,7 @@ async function killOrphanedWorkspaceProcesses(workspacePath) {
|
|
|
29618
30256
|
async function checkWorkspaceContainerHealth(sharedState) {
|
|
29619
30257
|
const actions = [];
|
|
29620
30258
|
try {
|
|
29621
|
-
const { stdout } = await execAsync("docker ps -a --filter \"status=exited\" --filter \"name=
|
|
30259
|
+
const { stdout } = await execAsync("docker ps -a --filter \"status=exited\" --filter \"name=feature-\" --format \"{{.Names}}|{{.Status}}\" 2>/dev/null || true", {
|
|
29622
30260
|
encoding: "utf-8",
|
|
29623
30261
|
timeout: 1e4
|
|
29624
30262
|
});
|
|
@@ -29631,7 +30269,7 @@ async function checkWorkspaceContainerHealth(sharedState) {
|
|
|
29631
30269
|
for (const line of crashed) {
|
|
29632
30270
|
const [name, status] = line.split("|");
|
|
29633
30271
|
if (!name) continue;
|
|
29634
|
-
const match = name.match(/
|
|
30272
|
+
const match = name.match(/feature-((?:[a-z]+-\d+)|(?:(?:f|us|de|ta|tc)\d+))-(frontend|server)-\d+$/i);
|
|
29635
30273
|
if (!match) continue;
|
|
29636
30274
|
const exitMatch = status?.match(/Exited \((\d+)\)/);
|
|
29637
30275
|
if (exitMatch && exitMatch[1] === "0") continue;
|
|
@@ -29670,7 +30308,7 @@ async function checkWorkspaceContainerHealth(sharedState) {
|
|
|
29670
30308
|
}
|
|
29671
30309
|
}
|
|
29672
30310
|
try {
|
|
29673
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
30311
|
+
const { resolveProjectFromIssueSync } = await import("./projects-WqMWCdpa.js");
|
|
29674
30312
|
const resolved = resolveProjectFromIssueSync(issueLower.toUpperCase());
|
|
29675
30313
|
if (resolved) await killOrphanedWorkspaceProcesses(`${resolved.projectPath}/workspaces/feature-${issueLower}`);
|
|
29676
30314
|
} catch {}
|
|
@@ -29719,8 +30357,8 @@ async function checkWorkspaceContainerHealth(sharedState) {
|
|
|
29719
30357
|
async function checkMergedWorkSessions() {
|
|
29720
30358
|
const actions = [];
|
|
29721
30359
|
try {
|
|
29722
|
-
const { selectMergedWorkSessions } = await import("./reap-terminal-sessions-
|
|
29723
|
-
const { setAgentPaused } = await import("./agents-
|
|
30360
|
+
const { selectMergedWorkSessions } = await import("./reap-terminal-sessions-DegFS2p1.js");
|
|
30361
|
+
const { setAgentPaused } = await import("./agents-IPSa5kzn.js");
|
|
29724
30362
|
const toKill = selectMergedWorkSessions(loadReviewStatuses(), [...await Effect.runPromise(listSessionNames())]);
|
|
29725
30363
|
for (const session of toKill) try {
|
|
29726
30364
|
await Effect.runPromise(setAgentPaused(session, "merged — awaiting close-out (verify on main)", true));
|
|
@@ -29760,7 +30398,7 @@ const AWAITING_TEST_IDLE_REAP_MS = 600 * 1e3;
|
|
|
29760
30398
|
async function checkAwaitingTestWorkSessions() {
|
|
29761
30399
|
const actions = [];
|
|
29762
30400
|
try {
|
|
29763
|
-
const { selectAwaitingTestWorkSessions } = await import("./reap-terminal-sessions-
|
|
30401
|
+
const { selectAwaitingTestWorkSessions } = await import("./reap-terminal-sessions-DegFS2p1.js");
|
|
29764
30402
|
const candidates = selectAwaitingTestWorkSessions(loadReviewStatuses(), [...await Effect.runPromise(listSessionNames())]);
|
|
29765
30403
|
const now = Date.now();
|
|
29766
30404
|
for (const session of candidates) {
|
|
@@ -29813,32 +30451,37 @@ async function runPatrol() {
|
|
|
29813
30451
|
hasLoggedGlobalPauseSkip = false;
|
|
29814
30452
|
addLog("info", `Patrol cycle ${state.patrolCycle} — checking per-project specialists`, state.patrolCycle);
|
|
29815
30453
|
console.log(`[deacon] Patrol cycle ${state.patrolCycle} - checking per-project specialists`);
|
|
29816
|
-
for (const a of await (await import("./stale-task-claims-
|
|
30454
|
+
for (const a of await (await import("./stale-task-claims-BYJGqhLI.js")).patrolStaleTaskClaims()) {
|
|
29817
30455
|
actions.push(a);
|
|
29818
30456
|
addLog("action", a, state.patrolCycle);
|
|
29819
30457
|
}
|
|
29820
30458
|
const stuckRemediationActions = await checkStuckAgentRemediation();
|
|
29821
30459
|
actions.push(...stuckRemediationActions);
|
|
29822
30460
|
for (const a of stuckRemediationActions) addLog("action", a, state.patrolCycle);
|
|
29823
|
-
const { reconcileInFlightJournals } = await import("./advancing-selfheal-
|
|
30461
|
+
const { reconcileInFlightJournals } = await import("./advancing-selfheal-8AR68Asf.js");
|
|
29824
30462
|
const reconciledJournalActions = await reconcileInFlightJournals();
|
|
29825
30463
|
actions.push(...reconciledJournalActions);
|
|
29826
30464
|
for (const a of reconciledJournalActions) addLog("action", a, state.patrolCycle);
|
|
29827
30465
|
try {
|
|
29828
30466
|
const pendingFile = join$1(OVERDECK_HOME, "pending-post-merge.json");
|
|
29829
|
-
const { processPendingLifecycleForPatrol } = await import("./deacon-pending-lifecycle-
|
|
30467
|
+
const { processPendingLifecycleForPatrol } = await import("./deacon-pending-lifecycle-CD3YsiQK.js");
|
|
29830
30468
|
const action = await processPendingLifecycleForPatrol(pendingFile);
|
|
29831
30469
|
if (action) actions.push(action);
|
|
29832
30470
|
} catch (err) {
|
|
29833
30471
|
console.warn(`[deacon] Failed to process pending lifecycle: ${err.message}`);
|
|
29834
30472
|
}
|
|
29835
|
-
if (state.patrolCycle % 5 === 0) await (await import("./deploy-patrol-
|
|
30473
|
+
if (state.patrolCycle % 5 === 0) await (await import("./deploy-patrol-kARAkji4.js")).runScheduledDeployPatrol();
|
|
29836
30474
|
const livenessActions = await reconcileAgentLiveness();
|
|
29837
30475
|
actions.push(...livenessActions);
|
|
29838
30476
|
for (const a of livenessActions) addLog("action", a, state.patrolCycle);
|
|
29839
|
-
const
|
|
29840
|
-
|
|
29841
|
-
|
|
30477
|
+
for (const a of await reconcileOrphanProposedSpecs()) {
|
|
30478
|
+
actions.push(a);
|
|
30479
|
+
addLog("action", a, state.patrolCycle);
|
|
30480
|
+
}
|
|
30481
|
+
for (const a of await reconcilePendingPromotions()) {
|
|
30482
|
+
actions.push(a);
|
|
30483
|
+
addLog("action", a, state.patrolCycle);
|
|
30484
|
+
}
|
|
29842
30485
|
const closedIssueAgentActions = await reconcileClosedIssueAgents();
|
|
29843
30486
|
actions.push(...closedIssueAgentActions);
|
|
29844
30487
|
for (const a of closedIssueAgentActions) addLog("action", a, state.patrolCycle);
|
|
@@ -29848,7 +30491,7 @@ async function runPatrol() {
|
|
|
29848
30491
|
const idleStackActions = await reconcileIdleWorkspaceStacks();
|
|
29849
30492
|
actions.push(...idleStackActions);
|
|
29850
30493
|
for (const a of idleStackActions) addLog("action", a, state.patrolCycle);
|
|
29851
|
-
for (const a of await (await import("./bridge-pool-patrol-
|
|
30494
|
+
for (const a of await (await import("./bridge-pool-patrol-BEjt-xF3.js")).patrolDockerBridgePool()) {
|
|
29852
30495
|
actions.push(a);
|
|
29853
30496
|
addLog("action", a, state.patrolCycle);
|
|
29854
30497
|
}
|
|
@@ -29868,7 +30511,7 @@ async function runPatrol() {
|
|
|
29868
30511
|
actions.push(...suspendActions);
|
|
29869
30512
|
for (const a of suspendActions) addLog("action", a, state.patrolCycle);
|
|
29870
30513
|
try {
|
|
29871
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
30514
|
+
const { resolveProjectFromIssueSync } = await import("./projects-WqMWCdpa.js");
|
|
29872
30515
|
const allStatuses = loadReviewStatuses();
|
|
29873
30516
|
for (const [issueId, status] of Object.entries(allStatuses)) {
|
|
29874
30517
|
if (!status.readyForMerge || status.mergeStatus === "merged") continue;
|
|
@@ -29888,7 +30531,7 @@ async function runPatrol() {
|
|
|
29888
30531
|
} catch (err) {
|
|
29889
30532
|
console.warn(`[deacon] Failed to check workspace existence: ${err.message}`);
|
|
29890
30533
|
}
|
|
29891
|
-
const { checkMergedAdvancingSessions } = await import("./advancing-selfheal-
|
|
30534
|
+
const { checkMergedAdvancingSessions } = await import("./advancing-selfheal-8AR68Asf.js");
|
|
29892
30535
|
const reapedWorkActions = await checkMergedWorkSessions();
|
|
29893
30536
|
actions.push(...reapedWorkActions);
|
|
29894
30537
|
for (const a of reapedWorkActions) addLog("action", a, state.patrolCycle);
|
|
@@ -29896,7 +30539,7 @@ async function runPatrol() {
|
|
|
29896
30539
|
actions.push(...reapedMergedAdvancingActions);
|
|
29897
30540
|
for (const a of reapedMergedAdvancingActions) addLog("action", a, state.patrolCycle);
|
|
29898
30541
|
try {
|
|
29899
|
-
const { refreshClaudeCredentialsForActiveRemoteAgents } = await import("./remote-completion-
|
|
30542
|
+
const { refreshClaudeCredentialsForActiveRemoteAgents } = await import("./remote-completion-BS4tJUn8.js");
|
|
29900
30543
|
const remoteCredentialActions = await refreshClaudeCredentialsForActiveRemoteAgents();
|
|
29901
30544
|
actions.push(...remoteCredentialActions);
|
|
29902
30545
|
for (const a of remoteCredentialActions) addLog(a.includes("failed") ? "warn" : "action", a, state.patrolCycle);
|
|
@@ -29904,7 +30547,7 @@ async function runPatrol() {
|
|
|
29904
30547
|
addLog("warn", `Remote credential refresh patrol failed: ${err.message}`, state.patrolCycle);
|
|
29905
30548
|
}
|
|
29906
30549
|
try {
|
|
29907
|
-
const { refreshHostHeartbeatForEphemeralVms } = await import("./remote-agents-
|
|
30550
|
+
const { refreshHostHeartbeatForEphemeralVms } = await import("./remote-agents-BIIoc5pD.js");
|
|
29908
30551
|
const heartbeatActions = await refreshHostHeartbeatForEphemeralVms();
|
|
29909
30552
|
actions.push(...heartbeatActions);
|
|
29910
30553
|
for (const a of heartbeatActions) addLog(a.includes("failed") ? "warn" : "action", a, state.patrolCycle);
|
|
@@ -29912,7 +30555,7 @@ async function runPatrol() {
|
|
|
29912
30555
|
addLog("warn", `Remote heartbeat refresh patrol failed: ${err.message}`, state.patrolCycle);
|
|
29913
30556
|
}
|
|
29914
30557
|
try {
|
|
29915
|
-
const { reapCompletedRemoteAgents } = await import("./remote-completion-
|
|
30558
|
+
const { reapCompletedRemoteAgents } = await import("./remote-completion-BS4tJUn8.js");
|
|
29916
30559
|
const remoteReap = await reapCompletedRemoteAgents();
|
|
29917
30560
|
for (const r of remoteReap) if (r.status === "handed-off" || r.status === "error") {
|
|
29918
30561
|
const msg = `Remote reap ${r.issueId}: ${r.status} (${r.details.join("; ")})`;
|
|
@@ -29961,6 +30604,12 @@ async function runPatrol() {
|
|
|
29961
30604
|
const unsignaledReviewActions = await checkCompletedButUnsignaledReviews();
|
|
29962
30605
|
actions.push(...unsignaledReviewActions);
|
|
29963
30606
|
for (const a of unsignaledReviewActions) addLog("action", a, state.patrolCycle);
|
|
30607
|
+
const unappliedReviewActions = await reconcileUnappliedReviewVerdicts();
|
|
30608
|
+
actions.push(...unappliedReviewActions);
|
|
30609
|
+
for (const a of unappliedReviewActions) addLog("action", a, state.patrolCycle);
|
|
30610
|
+
const verdictFallbackActions = await sweepStrandedVerdictFallbacks(Date.now(), Math.max(1e3, Math.floor(config.patrolIntervalMs / 2)));
|
|
30611
|
+
actions.push(...verdictFallbackActions);
|
|
30612
|
+
for (const a of verdictFallbackActions) addLog("action", a, state.patrolCycle);
|
|
29964
30613
|
const verifContradictionActions = await checkVerificationReviewContradiction();
|
|
29965
30614
|
actions.push(...verifContradictionActions);
|
|
29966
30615
|
for (const a of verifContradictionActions) addLog("action", a, state.patrolCycle);
|
|
@@ -30105,7 +30754,7 @@ async function runPatrol() {
|
|
|
30105
30754
|
const issueId = runtimeState.currentIssue;
|
|
30106
30755
|
try {
|
|
30107
30756
|
if (getReviewStatusSync(issueId)?.mergeStatus === "merging") {
|
|
30108
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
30757
|
+
const { resolveProjectFromIssueSync } = await import("./projects-WqMWCdpa.js");
|
|
30109
30758
|
const resolved = resolveProjectFromIssueSync(issueId);
|
|
30110
30759
|
if (resolved) {
|
|
30111
30760
|
const branch = `feature/${issueId.toLowerCase()}`;
|
|
@@ -30119,7 +30768,7 @@ async function runPatrol() {
|
|
|
30119
30768
|
mergeStatus: "merged",
|
|
30120
30769
|
readyForMerge: false
|
|
30121
30770
|
});
|
|
30122
|
-
const { postMergeLifecycle } = await import("./merge-agent-
|
|
30771
|
+
const { postMergeLifecycle } = await import("./merge-agent-DWd0KfiS.js");
|
|
30123
30772
|
postMergeLifecycle(issueId, resolved.projectPath).catch((err) => console.warn(`[deacon] postMergeLifecycle failed for ${issueId}: ${err}`));
|
|
30124
30773
|
actions.push(`Auto-completed stale merge for ${issueId}`);
|
|
30125
30774
|
} else {
|
|
@@ -30299,7 +30948,7 @@ function startDeacon() {
|
|
|
30299
30948
|
logDeaconEventSync(`startDeacon: health monitor starting (patrol every ${config.patrolIntervalMs / 1e3}s)`);
|
|
30300
30949
|
(async () => {
|
|
30301
30950
|
await reconcileAgentLiveness();
|
|
30302
|
-
const { runBootAdvancingSelfHeal } = await import("./advancing-selfheal-
|
|
30951
|
+
const { runBootAdvancingSelfHeal } = await import("./advancing-selfheal-8AR68Asf.js");
|
|
30303
30952
|
await runBootAdvancingSelfHeal();
|
|
30304
30953
|
runScheduledPatrol("startup");
|
|
30305
30954
|
})().catch((err) => {
|
|
@@ -30369,6 +31018,6 @@ function assessDeaconPatrolFreshness(params) {
|
|
|
30369
31018
|
};
|
|
30370
31019
|
}
|
|
30371
31020
|
//#endregion
|
|
30372
|
-
export { checkStuckReviewing as $, reconcileTestStatusFromGreenCi as A,
|
|
31021
|
+
export { checkStuckReviewing as $, reconcileTestStatusFromGreenCi as A, WORK_LAUNCHER_GRACE_MS as At, isRapidPostResumeDeath as B, getSystemHealthSnapshot as Bt, handleAgentHeartbeatDeadEvent as C, contextOverflowRecoveryState as Ct, loadConfig as D, paneShowsClaudeBootBlockingScreen as Dt, isDeaconRunning as E, deliverOrchestratedCompact as Et, setAgentStoppedNotifier as F, getCurrentDockerStats as Ft, isAutoResumableRole as G, nudgeStalledResumeWorkAgents as H, startSmeeProcessSync as Ht, setMergeReadyNotifier as I, getAcceptedSystemHealthSnapshot as It, startBootReconciliation as J, isBootReconciliationCandidate as K, startDeacon as L, getDeployStaleness as Lt, runPatrol as M, getResourceStacks as Mt, saveState as N, formatUptime as Nt, loadState as O, INSPECT_TIMEOUT_MS as Ot, setAgentStatusChangedNotifier as P, getContainerHistory as Pt, checkCompletedButUnsignaledReviews as Q, stopDeacon as R, getResourceConfig as Rt, getLastPatrolResult as S, checkApiErrorAgents as St, handleAgentStoppedForOrphanReviewerSessions as T, stuckOverflowNativeRecoveryState as Tt, redeliverUndeliveredKickoffs as U, classifyAgentHealth as Ut, nudgeIdleWorkAgentsWithOpenBeads as V, isSmeeConfiguredSync as Vt, extendBootReconciliationGrace as W, monitorReviewConvoySignals as X, cleanupOrphanedReviewSessions as Y, synthesizeReviewFromReports as Z, cleanupOrphanedPlanningSessions as _, reconcileStaleMergeBlockers as _t, checkCompletedButUnsignaledTests as a, handleWorkCompleted as at, getDeaconLogs as b, reconcileAutoMergeRows as bt, checkMergedWorkSessions as c, stalledReviewConvoyRecoveryState as ct, checkReadyForMergeStuck as d, checkFailedMergeRetry as dt, isSynthesisForActiveReviewRun as et, checkStuckWorkAgents as f, checkFirstCompletionAgents as ft, cleanupOrphanReviewerSessions as g, reconcileMergedButReviewing as gt, cleanupAbandonedFeedback as h, reconcileFalseMerged as ht, checkAwaitingTestWorkSessions as i, handleReviewCoordinatorDied as it, resetPatrolHeartbeatForStartup as j, classifyMemoryPressure as jt, reconcileAgentLiveness as k, checkInspectAgentTimeouts as kt, checkOrphanedCompletions as l, checkPostReviewCommits as lt, checkWorkspaceContainerHealth as m, reconcileClosedPrReadyForMerge as mt, assessDeaconPatrolFreshness as n, checkMissingReviewStatuses as nt, checkDeadEndAgents as o, recoverStalledReviewConvoys as ot, checkVerificationReviewContradiction as p, ciRetryMap as pt, listBootReconciliationCandidates as q, checkAndSuspendIdleAgents as r, checkOrphanedReviewStatuses as rt, checkMassDeath as s, reviewConvoyLiveness as st, applyBootReconciliationDecision as t, reconcileUnappliedReviewVerdicts as tt, checkPendingTestDispatch as u, autoCloseOut as ut, cleanupStaleAgentState as v, reconcileStaleMergeStatus as vt, handleAgentStoppedEvent as w, contextProactiveCompactState as wt, getDeaconStatus as x, reconcileStuckMergingStates as xt, containerRestartBackoffMs as y, reconcileStuckReadyForMerge as yt, isPreKickoffLaunchDeath as z, getSystemHealthEvidenceSnapshot as zt };
|
|
30373
31022
|
|
|
30374
|
-
//# sourceMappingURL=deacon-
|
|
31023
|
+
//# sourceMappingURL=deacon-HdEh0Esp.js.map
|