@overdeck/desktop 0.45.21 → 0.45.23
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/package.json +1 -1
- package/server/{acceptance-criteria-CJIFA8Vg.js → acceptance-criteria-DOA0KgXx.js} +5 -5
- package/server/{advancing-selfheal-CPOBO5ZS.js → advancing-selfheal-BBu6DSNm.js} +6 -6
- package/server/{agent-gc-D6PUckBB.js → agent-gc-BV1q_2EV.js} +4 -4
- package/server/agent-state-Bg0lhqwj.js +3 -0
- package/server/{agent-state-service-DHwemt96.js → agent-state-service-CnzFKSAQ.js} +1 -1
- package/server/{agent-state-service-6MFQqnFy.js → agent-state-service-HoK8U4jW.js} +5 -5
- package/server/{agents-DbrHWunF.js → agents-B4Bjbkfv.js} +4 -4
- package/server/agents-FlIgQ3ql.js +3 -0
- package/server/{archive-planning-BOnwJq8M.js → archive-planning-DYrYojxl.js} +31 -7
- package/server/{archive-planning-MPpvQJL4.js → archive-planning-zkJb3BeM.js} +1 -1
- package/server/{artifact-index-jobs-BOoySTKD.js → artifact-index-jobs-C-xy7Z5v.js} +2 -2
- package/server/{backlog-auto-trigger-BUaFI44J.js → backlog-auto-trigger-GtG71X8H.js} +3 -3
- package/server/{behavior-Dg-D8eBG.js → behavior-B_-4EKF3.js} +2 -2
- package/server/{briefing-freshness-OouGbJ7d.js → briefing-freshness-DWdW7vUm.js} +2 -2
- package/server/{build-info-27NlbKhV.js → build-info-BT096lEl.js} +3 -3
- package/server/{build-info-Cv6CI7Gu.js → build-info-DgTqZkL5.js} +1 -1
- package/server/{checkpoint-manager-C7mFCY_E.js → checkpoint-manager-B7Bt29J0.js} +1 -1
- package/server/{checkpoint-manager-D64fCC4p.js → checkpoint-manager-DDqcGyu8.js} +2 -2
- package/server/checkpoint-worker.js +1 -1
- package/server/{checkpoints-Vh-J15ge.js → checkpoints-C-AXLfYT.js} +2 -2
- package/server/{checkpoints-DwZqT2qQ.js → checkpoints-CpgCjAlN.js} +1 -1
- package/server/{claude-hooks-provision-CS5W_dhI.js → claude-hooks-provision-C8wdRnN1.js} +1 -1
- package/server/{claude-hooks-provision-BVLGfHrv.js → claude-hooks-provision-but-_qGY.js} +2 -2
- package/server/{claude-permissions-C2OrLYKL.js → claude-permissions-H_5wHQZQ.js} +2 -2
- package/server/{claude-settings-overlay-DWXjafJh.js → claude-settings-overlay-BTENVmYf.js} +1 -1
- package/server/{claude-settings-overlay-DX-fMFpC.js → claude-settings-overlay-CbSz0Dvb.js} +2 -2
- package/server/cli-BsVIHwzC.js +3 -0
- package/server/{cli-mvpEOb3w.js → cli-vBeXbPrq.js} +9 -9
- package/server/{cliproxy-Dvsr4ZkW.js → cliproxy-Bgb2XCqi.js} +2 -2
- package/server/{cliproxy-7g1nObvB.js → cliproxy-DW0V86F8.js} +1 -1
- package/server/{close-issue-8F6uawYj.js → close-issue-Dn_4c4G8.js} +5 -5
- package/server/{closed-issue-reaper-BhV-r-tC.js → closed-issue-reaper-CWpY2uBw.js} +1 -1
- package/server/{closed-issue-reaper-BaYQYF6w.js → closed-issue-reaper-hANY_ehE.js} +9 -9
- package/server/codex-Dg7Is5yb.js +3 -0
- package/server/{codex-D_UBEOwL.js → codex-TmSi-yTv.js} +30 -8
- package/server/{codex-parser-BTzlOZiV.js → codex-parser-C4gSH-IR.js} +2 -2
- package/server/{config-CrduXs4a.js → config-CCvjQf27.js} +2 -2
- package/server/{config-nAB_F-Gp.js → config-DUIhMN_T.js} +1 -1
- package/server/{config-G1TOMJZA.js → config-DjLOdbgT.js} +2 -2
- package/server/{config-yaml-Ciyp2mYe.js → config-yaml-DvyMuOle.js} +177 -211
- package/server/{conflict-gate-BKalpcjL.js → conflict-gate-BSJkNTdp.js} +1 -1
- package/server/{conflict-gate-BLUNMs1i.js → conflict-gate-CmrYpa47.js} +3 -3
- package/server/{context-layers-YNpf6Q_I.js → context-layers-B3Nt58jl.js} +2 -2
- package/server/{context-layers-Cg9ZgVfx.js → context-layers-ZYFcWiyc.js} +3 -3
- package/server/{control-settings-D_79A6gp.js → control-settings-aP1ANIlI.js} +4 -4
- package/server/{conversation-compaction-DiuZbIUB.js → conversation-compaction-CNbTLB86.js} +8 -8
- package/server/{conversation-compaction-CMIeWW4_.js → conversation-compaction-DiG5zWQq.js} +1 -1
- package/server/{conversation-service-DQybSPUK.js → conversation-service-Du-MTNpJ.js} +6 -6
- package/server/{conversation-service-CWk8mEym.js → conversation-service-Up7FEzIC.js} +1 -1
- package/server/{conversations-BJ-t3BRm.js → conversations-6mPANqvL.js} +1 -1
- package/server/{conversations-BUgGvqVL.js → conversations-DbOs1e9Q.js} +4 -4
- package/server/{cost-jJ2cgDcG.js → cost-CW4WSe72.js} +3 -3
- package/server/{cost-Drm7qeD5.js → cost-Ca0YTWDw.js} +18 -2
- package/server/{cost-sync-DzHP6zaR.js → cost-sync-C0VdGme1.js} +3 -3
- package/server/{dag-DIji6O2b.js → dag-CdOjJVDT.js} +9 -9
- package/server/{dangerous-git-ops-BebB-61h.js → dangerous-git-ops-CT-IypG3.js} +1 -1
- package/server/dashboard-db-worker.js +7 -7
- package/server/{deacon-pleYrvIm.js → deacon-DYSEJb48.js} +3 -3
- package/server/{deacon-nudge-log-C5VCKtyi.js → deacon-nudge-log-Bjg8U4Y9.js} +3 -3
- package/server/{deacon-1s7bM5zn.js → deacon-pRnyD5w9.js} +1133 -474
- package/server/deacon-swarm-9jRLS5Ke.js +2 -0
- package/server/{deacon-swarm-DmA3rJ7k.js → deacon-swarm-DftYRDo8.js} +17 -17
- package/server/deacon.js +8 -8
- package/server/{deploy-patrol-DmM6F-yw.js → deploy-patrol-Bjsho_ha.js} +136 -19
- package/server/{deploy-window-ClLq1RYf.js → deploy-window-CM6W1-c6.js} +1 -1
- package/server/{deploy-window-jw4S_Y-c.js → deploy-window-DeP_OIRk.js} +77 -10
- package/server/{dev-supervisor-Do2Stz49.js → dev-supervisor-BpMoHlkR.js} +2 -2
- package/server/{devcontainer-renderer-D8ylupco.js → devcontainer-renderer-CtUgrVKW.js} +3 -3
- package/server/dist-Bd3vn0Hw.js +3 -0
- package/server/{dist-yfR7G1BL.js → dist-DyRx4cI7.js} +1 -1
- package/server/{docker-ClwPQaba.js → docker-BK7HIcBj.js} +2 -2
- package/server/{dod-BLphkhjs.js → dod-BrSfUHm0.js} +1 -1
- package/server/{ensure-devcontainer-BA3bICoY.js → ensure-devcontainer-DRqaAkBR.js} +1 -1
- package/server/{ensure-devcontainer-CFpQatOc.js → ensure-devcontainer-DseivYEy.js} +4 -4
- package/server/{esm-shims-BZw-fTQ6.js → esm-shims-CbI3BVkl.js} +1 -1
- package/server/{event-store-DABarGNz.js → event-store-Cr5PQwFC.js} +1 -1
- package/server/{event-store-BVnON3vf.js → event-store-tdiY5eDZ.js} +3 -3
- package/server/{events-CmERlnwn.js → events-CC1dgUpx.js} +3 -3
- package/server/{events-LGeUehYW.js → events-CvvGK6LT.js} +1 -1
- package/server/{factory-CQNprtHe.js → factory-CynerjXO.js} +50 -13
- package/server/{feature-registry-population-D9Z3tYSa.js → feature-registry-population-B0pmAz0a.js} +4 -4
- package/server/{feature-registry-storage-BWymOgXE.js → feature-registry-storage-_wUBRD3J.js} +2 -2
- package/server/{features--fOza5g5.js → features-Dhxz-wLc.js} +2 -2
- package/server/{feedback-target-Dqik2WTe.js → feedback-target-CPS15Vte.js} +7 -7
- package/server/{feedback-target-Dn9vfPpz.js → feedback-target-iygZwmMc.js} +1 -1
- package/server/{feedback-writer-Wlq5-qgS.js → feedback-writer-C9b6ccN1.js} +6 -5
- package/server/{feedback-writer-DDQNV8uc.js → feedback-writer-qmiMbqTZ.js} +1 -1
- package/server/{flywheel-Q-38YhZG.js → flywheel-DMCUzDWg.js} +1 -1
- package/server/{flywheel-1Wd8WDlh.js → flywheel-DSSpWmqF.js} +13 -13
- package/server/{flywheel-DPUc8r3V.js → flywheel-DcBkQvgE.js} +14 -14
- package/server/{flywheel-merge-order-CeBuX0EJ.js → flywheel-merge-order-C-6zRLvM.js} +1 -1
- package/server/{flywheel-merge-order-4SqOXFAr.js → flywheel-merge-order-DxbQKE1d.js} +8 -8
- package/server/forge-B-ZWyTRm.js +2 -0
- package/server/{forge-DBbDpiYc.js → forge-Ch9gCFod.js} +2 -2
- package/server/{from-hh6vTBGl.js → from-CJ_aH5jD.js} +1 -1
- package/server/{fts-db-6ponMie2.js → fts-db-CKgg0VKg.js} +2 -2
- package/server/{fts-operations-KIRK165y.js → fts-operations-BrL_VTRr.js} +2 -2
- package/server/git-utils-BVa07a4a.js +198 -0
- package/server/{git-utils-DmF5xkj8.js → git-utils-Dry_Ka_D.js} +1 -1
- package/server/{github-app-B3yfECo8.js → github-app-CMBdIFBQ.js} +11 -3
- package/server/{github-app-CeSVFL6C.js → github-app-CPfoFAdV.js} +1 -1
- package/server/{github-client-Dslipypz.js → github-client--XVlDpwM.js} +2 -2
- package/server/{github-client-4A6FgA8O.js → github-client-B4QsdE-X.js} +1 -1
- package/server/{github-pr-lookup-DBP0YHMr.js → github-pr-lookup-BRbDW-qk.js} +2 -2
- package/server/harness-binary-CVio2m-u.js +106 -0
- package/server/{harness-resolve-BGpO-OVM.js → harness-resolve-qHJBhy3Z.js} +9 -15
- package/server/{health-events-CZGZ5I-A.js → health-events-C9B8y1Hm.js} +2 -2
- package/server/{health-events-CnwV_SSz.js → health-events-CpfvuVmm.js} +1 -1
- package/server/{hooks-CoNscX84.js → hooks-DUXw8A0-.js} +2 -2
- package/server/{hooks-DvX33gY_.js → hooks-ltecuFqZ.js} +1 -1
- package/server/{hume-DSJt5eA_.js → hume-BEq0bUDg.js} +2 -2
- package/server/hume-B_DbflNM.js +3 -0
- package/server/{idle-stack-reaper-5DVRoY6P.js → idle-stack-reaper-D7w9t3fE.js} +1 -1
- package/server/{idle-stack-reaper-BfL8HqYy.js → idle-stack-reaper-w1ISSlhs.js} +2 -2
- package/server/{in-flight-guard-tVGiI5ee.js → in-flight-guard-aQ1IxeI3.js} +2 -2
- package/server/{infra-DN2wSxle.js → infra-CzaSOgul.js} +4 -4
- package/server/{injection-DtlT8Akv.js → injection-DZ0PfYa4.js} +7 -7
- package/server/{injection-DK9zh_HL.js → injection-oNZeoDhL.js} +1 -1
- package/server/{inspect-agent-DKByUS_F.js → inspect-agent-DJKLWcVT.js} +15 -11
- package/server/inspect-agent-ch-F-5Ci.js +2 -0
- package/server/{internal-token-DhfFiwW7.js → internal-token-Bb4XeV2x.js} +2 -2
- package/server/{internal-token-7bYL5v6K.js → internal-token-DXdfprGr.js} +1 -1
- package/server/{io-BiM-7Zsx.js → io-B3_AHDfr.js} +160 -184
- package/server/{issue-closed-Dfw3QDyZ.js → issue-closed-zhdvQicO.js} +7 -7
- package/server/{issue-lifecycle-B7HZWnTA.js → issue-lifecycle-CreaCkjW.js} +22 -22
- package/server/{issue-lifecycle-ytsEdDlK.js → issue-lifecycle-Dy4vd0Oa.js} +1 -1
- package/server/{issue-service-singleton-CPESc4Or.js → issue-service-singleton-B5ushCvE.js} +8 -8
- package/server/{issue-service-singleton-D5EB5eYr.js → issue-service-singleton-DabvBWUp.js} +1 -1
- package/server/{issues-XYtFMxrH.js → issues-B6ToV6x1.js} +2 -2
- package/server/{jsonl-parser-DJV2eZUP.js → jsonl-parser-Dhflo1SH.js} +3 -3
- package/server/{label-cleanup-CJ4m8iRU.js → label-cleanup-BKPJm4Hv.js} +3 -3
- package/server/{label-reconciler-CNf3Ylm3.js → label-reconciler-DdWbHEBu.js} +4 -4
- package/server/{launcher-generator-5DJRiovn.js → launcher-generator-CHVm7bGT.js} +10 -9
- package/server/{layers-cZx7ibtV.js → layers-DzxSTGNA.js} +2 -2
- package/server/lifecycle-DfeyBDwA.js +121 -0
- package/server/lifecycle-io-Bsnr2K4F.js +3 -0
- package/server/{lifecycle-io-DMurK4oM.js → lifecycle-io-D8iNBcux.js} +37 -37
- package/server/{lifecycle-CE7619Xw.js → lifecycle-sycO16hj.js} +6 -6
- package/server/{linear-client-BLyN-NiP.js → linear-client-D4zqMnX7.js} +2 -2
- package/server/{linear-client-Bj1l4FOA.js → linear-client-DqhDQO9k.js} +1 -1
- package/server/memory-fts-worker.js +1 -1
- package/server/{merge-hSC2BENe.js → merge-C_ZEhbqI.js} +3 -3
- package/server/{merge-CwX2_AWm.js → merge-DK23JEdS.js} +1 -1
- package/server/{merge-agent-CnORPiri.js → merge-agent-BQM3a8z5.js} +1 -1
- package/server/{merge-agent-DnBsms_V.js → merge-agent-XrB80vfT.js} +369 -213
- package/server/{merge-batch-C2w2U2eK.js → merge-batch-Bwoyr8Je.js} +1 -1
- package/server/{merge-blockers-DhRgh76x.js → merge-blockers-BsFjGrQ8.js} +2 -2
- package/server/merge-ops-DlB1IM0Y.js +2 -0
- package/server/{merge-rebase-CE-ZyOMY.js → merge-rebase-C1KIVr0s.js} +2 -2
- package/server/{merge-set-D7YNU1ZB.js → merge-set-DLz0MkGT.js} +3 -3
- package/server/{merge-set-DHkzPCJU.js → merge-set-DnSYdBEp.js} +1 -1
- package/server/{merge-sync-De1FYva5.js → merge-sync-DZ9dojJn.js} +2 -2
- package/server/{merge-sync-CpGA9Kg7.js → merge-sync-SSv3E-pl.js} +1 -1
- package/server/{merge-train-SvkRJZ-k.js → merge-train-DxDfBTjr.js} +3 -3
- package/server/{merge-train-deps-CECJTElu.js → merge-train-deps-CyYQUksx.js} +4 -4
- package/server/{merge-verification-B3meGcXF.js → merge-verification-CSizH3HY.js} +4 -4
- package/server/{multipart-parser-ByTMgYV5.js → multipart-parser-Dt8YPN5S.js} +2 -2
- package/server/{no-resume-mode-BnInAFKs.js → no-resume-mode-Cx3K0hHi.js} +11 -8
- package/server/node_modules/.package-lock.json +5 -5
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/README.md +3 -3
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.d.ts.map +1 -1
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.js +2 -2
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.js.map +1 -1
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/package.json +5 -5
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/NodeChildProcessSpawner.ts +6 -8
- package/server/{orphan-proposed-reconciler-CAfuWTA1.js → orphan-proposed-reconciler-BTkDrl4R.js} +1 -1
- package/server/{orphan-proposed-reconciler-AxAGUouN.js → orphan-proposed-reconciler-neK8dHQk.js} +23 -14
- package/server/package-lock.json +6 -6
- package/server/package.json +1 -1
- package/server/{pan-dir-Rw17YjT1.js → pan-dir-DeVUgwA7.js} +78 -58
- package/server/{paths-FP8v3lTz.js → paths-_zEts6wc.js} +2 -2
- package/server/{pickup-xi3KTLaJ.js → pickup-Dd0Znxxy.js} +2 -2
- package/server/{pipeline-membership-BtKMNY7v.js → pipeline-membership-0HaEGDlH.js} +190 -68
- package/server/{pipeline-notifier-dQ-U4NSb.js → pipeline-notifier-6iCJplFZ.js} +1 -1
- package/server/{pipeline-notifier-BM2HLF7B.js → pipeline-notifier-D0ykk59O.js} +2 -2
- package/server/{project-pipelines-B59NfN44.js → project-pipelines-2sK1apsO.js} +2 -2
- package/server/projects-9SkRpES9.js +3 -0
- package/server/{prompts-CbqaVjbe.js → prompts-Dp4Tpk39.js} +2 -2
- package/server/providers-DKkBXhxU.js +3 -0
- package/server/{providers-d3pwXGVE.js → providers-DV7ec8l7.js} +7 -7
- package/server/public/assets/{chunk-BO2N2NFS-BxYSL7J-.js → chunk-BO2N2NFS-CltymLRg.js} +4 -4
- package/server/public/assets/{diagram-OG6HWLK6-C_F9Q2as.js → diagram-OG6HWLK6-D2f6pjgA.js} +1 -1
- package/server/public/assets/{dist-DQNg4CiF.js → dist-BWR4qFiV.js} +1 -1
- package/server/public/assets/{dist-CLSlc6cV.js → dist-DEmlBBNQ.js} +3 -3
- package/server/public/assets/{ganttDiagram-6RSMTGT7-Cq0my-0C.js → ganttDiagram-6RSMTGT7-DnfiViPK.js} +1 -1
- package/server/public/assets/{highlighted-body-OFNGDK62-eZC03dGh.js → highlighted-body-OFNGDK62-B8Wrmj9H.js} +1 -1
- package/server/public/assets/index-CUr1xv8w.css +1 -0
- package/server/public/assets/{index-SLYGA8AQ.js → index-CsSuZQBI.js} +148 -145
- package/server/public/assets/{linear-6Fi3qnGg.js → linear-C9zFQpkX.js} +1 -1
- package/server/public/assets/mermaid-GHXKKRXX-BUAB8hqt.js +1 -0
- package/server/public/assets/{pieDiagram-4H26LBE5-Dpmc6xsv.js → pieDiagram-4H26LBE5-lR8H7Yjd.js} +1 -1
- package/server/public/assets/{prod-ojHllFvN.js → prod-B1jCQihw.js} +4 -4
- package/server/public/assets/{quadrantDiagram-W4KKPZXB-Ulr9gON5.js → quadrantDiagram-W4KKPZXB-CVQ2guem.js} +1 -1
- package/server/public/assets/{sankeyDiagram-5OEKKPKP-CwdHGXfL.js → sankeyDiagram-5OEKKPKP-eD1RB4gm.js} +1 -1
- package/server/public/assets/{xychartDiagram-2RQKCTM6-r-bEDzJh.js → xychartDiagram-2RQKCTM6-ChEC6dQn.js} +1 -1
- package/server/public/index.html +54 -10
- package/server/{pull-requests-D3N6HQzI.js → pull-requests--Ib2jTgy.js} +1 -1
- package/server/{pull-requests-CjjPj7v6.js → pull-requests-CXIhdCYD.js} +13 -11
- package/server/{queries-B5hl7lMQ.js → queries-6d7Cdtm7.js} +723 -110
- package/server/{rally-Dp0Gb1DN.js → rally-B708-nZn.js} +3 -3
- package/server/{rally-api-DGaFz5L5.js → rally-api-nY0ZANw3.js} +2 -2
- package/server/{rally-api-CKr0O4DJ.js → rally-api-yjQ0TfHd.js} +1 -1
- package/server/{rally-client-SVbjGvqj.js → rally-client-B1EJhfV0.js} +4 -4
- package/server/{rally-client-Cqf6EX_r.js → rally-client-CULK2XAY.js} +1 -1
- package/server/rally-njs_mJrt.js +3 -0
- package/server/reap-terminal-sessions-MWnqdLCJ.js +4 -0
- package/server/{reap-terminal-sessions-CjqRAGw7.js → reap-terminal-sessions-N3BTkmX_.js} +11 -28
- package/server/{rebuild-stack-DHqCLvLX.js → rebuild-stack-Dp4eLkt4.js} +6 -6
- package/server/{rebuild-stack-DjdpALr1.js → rebuild-stack-kA7XngID.js} +1 -1
- package/server/{reconstruct-cache-BqrCQt0o.js → reconstruct-cache-uWbZfjms.js} +6 -6
- package/server/record-t6V-3Dcj.js +3 -0
- package/server/{record-update-BlB8mpKO.js → record-update-DACtKh6_.js} +1 -1
- package/server/record-update-Dq0t2uBG.js +310 -0
- package/server/{recovery-trip-l1Hsi37x.js → recovery-trip-BJtIQuag.js} +2 -2
- package/server/{release-engine-CSI4K6Oj.js → release-engine-DZpmGGzb.js} +5 -5
- package/server/{release-set-BywwggrE.js → release-set-hnXd_kga.js} +3 -3
- package/server/{remote-DYziAkiZ.js → remote-4tiENDaI.js} +3 -3
- package/server/{remote-cnoeuDWn.js → remote-Br-ZWVIP.js} +3 -3
- package/server/{remote-agents-BNORDWAX.js → remote-agents-CRCg1L4H.js} +1 -1
- package/server/{remote-agents-CZ2rc8I0.js → remote-agents-nmty1mLu.js} +6 -6
- package/server/{remote-completion-W67FNQ-A.js → remote-completion-BbWNd10K.js} +13 -13
- package/server/resume-CcKqnTvE.js +3 -0
- package/server/{review-agent-CSswH985.js → review-agent-DJRO8EG8.js} +1 -1
- package/server/{review-agent-CqSqSHkU.js → review-agent-sKkE1FEL.js} +23 -23
- package/server/{review-artifacts-BBgnd5df.js → review-artifacts-BLbSC4ke.js} +5 -5
- package/server/{review-context-Ctp9BdNJ.js → review-context-BgX3lcCx.js} +9 -9
- package/server/{review-status-CCgPVK1h.js → review-status-A7quS5KJ.js} +56 -39
- package/server/review-status-C6n6-9f_.js +3 -0
- package/server/{review-status-enrichment-DtDRGpst.js → review-status-enrichment-tbOn_A_u.js} +3 -3
- package/server/review-status-source-CxuEjLGg.js +39 -0
- package/server/{review-status-sync-jnLgd04F.js → review-status-sync-BhSQ0d0l.js} +2 -2
- package/server/{review-status-sync-C792ksoJ.js → review-status-sync-To3-iS-N.js} +1 -1
- package/server/{review-verdict-feedback-D5lW0o3k.js → review-verdict-feedback-C1Kg8n7t.js} +1 -1
- package/server/{review-verdict-feedback-CMsIpTpy.js → review-verdict-feedback-CTRNtzXO.js} +7 -7
- package/server/{rollup-B3kQmNpl.js → rollup-B53Y81xK.js} +1 -1
- package/server/{rollup-CLj_AK9f.js → rollup-WA0VD-Rr.js} +8 -8
- package/server/{scanner-C4NeC4FE.js → scanner-D2743cp8.js} +11 -7
- package/server/{sequence-io-Ce-6grIY.js → sequence-io-Cg0zYj_E.js} +4 -4
- package/server/{sequencer-agent-Bpz0yGmG.js → sequencer-agent-BGY8gjg-.js} +5 -5
- package/server/server.js +1348 -963
- package/server/{service-CqAY8Kmk.js → service-DCpB_SGd.js} +154 -51
- package/server/{session-fork-uNo4rMRA.js → session-fork-BQ8_6H32.js} +2 -2
- package/server/{session-history-DUehL3KN.js → session-history-CVZDpS3c.js} +4 -4
- package/server/{settings-DP2OYLXL.js → settings-BZ5m1UCl.js} +3 -3
- package/server/settings-D0OSwos5.js +2 -0
- package/server/{settings-D9grjmaP.js → settings-ylxwqwQG.js} +2 -2
- package/server/{shadow-engineering-Bi_oIMtF.js → shadow-engineering-BlxG6Xye.js} +3 -3
- package/server/{shadow-state-CDxEuPlE.js → shadow-state-C2_epgx2.js} +1 -1
- package/server/{shadow-state-a_ztFBJe.js → shadow-state-Dh-HzF2J.js} +2 -2
- package/server/{shadow-utils-CyOg6_Xq.js → shadow-utils-4bvjn9b3.js} +2 -2
- package/server/{ship-log-DDcueaIR.js → ship-log-ClSMIzZX.js} +1 -1
- package/server/{smart-compaction-C1_VVLEd.js → smart-compaction-CHIxLr_d.js} +1 -1
- package/server/{smart-compaction--Oj65Uov.js → smart-compaction-r4pHQBIr.js} +7 -7
- package/server/{spawn-planning-session-AiUSsBnH.js → spawn-planning-session-DWAorh2B.js} +25 -20
- package/server/{spawn-planning-session-LFtK2QCE.js → spawn-planning-session-KC_UduxD.js} +1 -1
- package/server/{specialist-completion-qOgqdqXH.js → specialist-completion-BXhav38U.js} +1 -1
- package/server/{specialist-context-gjj8Z4Ii.js → specialist-context-DtrYvGJ-.js} +5 -5
- package/server/{specialist-handoff-logger-BsBNvVZv.js → specialist-handoff-logger-C45ouoZ6.js} +2 -2
- package/server/{specialist-logs-CSLtvPx6.js → specialist-logs-DJ3RzKxW.js} +3 -3
- package/server/{specialists-D0VBf8g_.js → specialists-D5fRZXmN.js} +1 -1
- package/server/specialists-DVj0hvaL.js +3 -0
- package/server/{specialists-CYRwELzc.js → specialists-DyFeedjn.js} +66 -76
- package/server/{specialists-DAegTvRt.js → specialists-JVO00bs7.js} +374 -220
- package/server/specs-nN45DG2X.js +3 -0
- package/server/{src-OLoJhUiJ.js → src-CG9mCkP6.js} +6 -6
- package/server/{src-BqTcrfO_.js → src-CMTQGyCK.js} +3 -3
- package/server/{src-Dpq1yFIl.js → src-U7_kTPEE.js} +338 -4
- package/server/{stack-health-I713ELld.js → stack-health-Df0YEZKa.js} +1 -1
- package/server/{stack-health-DV_f-lK0.js → stack-health-puygdaMd.js} +2 -2
- package/server/{stale-task-claims-CQSKZVq0.js → stale-task-claims-BbFwCTb0.js} +4 -4
- package/server/{staleness-BbsGxmF2.js → staleness-Bpy41ngS.js} +15 -3
- package/server/{staleness-zGp4P1hd.js → staleness-Cbl_w4Bw.js} +1 -1
- package/server/{state-home-DixkE-up.js → state-home-CIGjwNfJ.js} +119 -54
- package/server/state-migrate-Dkzaxvny.js +487 -0
- package/server/{stuck-remediation-BWkK_O7A.js → stuck-remediation-CzEov_fq.js} +27 -21
- package/server/{stuck-remediation-CTPRC2S5.js → stuck-remediation-sY_MHHgQ.js} +1 -1
- package/server/{substrate-bug-weights-service-DXd0ID83.js → substrate-bug-weights-service-BH66lhm7.js} +3 -3
- package/server/{summary-fork-CdLn8Chr.js → summary-fork-D8bXjCr7.js} +2 -2
- package/server/{summary-fork-f3DpgjXh.js → summary-fork-DHhJIsAL.js} +8 -8
- package/server/{supervisor-Ch8CDuoF.js → supervisor-BO-Zk_h-.js} +3 -3
- package/server/supervisor-BPy-o1A8.js +2 -0
- package/server/{swarm-readiness-C9P2iPap.js → swarm-readiness-CQ_fwUWF.js} +4 -4
- package/server/{system-prerequisites-DkoQBn1q.js → system-prerequisites-Bza0ffAh.js} +24 -44
- package/server/{teardown-workspace-D-5yMyit.js → teardown-workspace-CEgauF4U.js} +15 -15
- package/server/{test-agent-queue-BwpUpu-o.js → test-agent-queue-DXDt0Xa-.js} +7 -7
- package/server/{test-verdict-BRiSu7eW.js → test-verdict-CmUBK5cT.js} +1 -1
- package/server/{test-verdict-BQ1yx7d4.js → test-verdict-DFjjIHR5.js} +1 -1
- package/server/{tldr-daemon-DjxP5g6Y.js → tldr-daemon-BDtLOIlO.js} +2 -2
- package/server/{tldr-daemon-BJA7TkqS.js → tldr-daemon-DL566HbH.js} +1 -1
- package/server/tmux-DoThH6aj.js +3 -0
- package/server/{tmux-y1blSxks.js → tmux-ftABRAmc.js} +76 -44
- package/server/{token-LUrbM9sU.js → token-CsOhvw42.js} +2 -2
- package/server/{token-util-BZaDAQ8S.js → token-util-CTmczIfW.js} +1 -1
- package/server/token-util-DrHg8abn.js +3 -0
- package/server/{tracker-config-DSFZBdXP.js → tracker-config-B4itFzDo.js} +2 -2
- package/server/{tracker-utils-WtP_V-yn.js → tracker-utils-BePq_oj-.js} +1 -1
- package/server/{tracker-utils-DiceZN3a.js → tracker-utils-tnxxqROg.js} +2 -2
- package/server/{traefik-connect-BXqfOP4-.js → traefik-connect-m73vGebA.js} +1 -1
- package/server/{tunnel-DTng1rfQ.js → tunnel-B2vxjx_b.js} +3 -3
- package/server/{tunnel-WcJImbAC.js → tunnel-Cgj-IGIl.js} +1 -1
- package/server/{types-BjaZ1oqH.js → types-BBNjPcqU.js} +1 -1
- package/server/{types-DqeBMmJN.js → types-hraoaQIp.js} +1 -1
- package/server/{uat-train-BpLnp7Cx.js → uat-train-CuEn0t9M.js} +28 -28
- package/server/{uat-train-Wismge7h.js → uat-train-cKfM-_WW.js} +1 -1
- package/server/{validation-BA4e5EGm.js → validation-B5JxoPUS.js} +259 -9
- package/server/{validation-CUWamZ4X.js → validation-CIi6pnI2.js} +1 -1
- package/server/{verification-artifact-Dr_0g9nb.js → verification-artifact-BcnIbigL.js} +1 -1
- package/server/{verification-artifact-CrbI4tJE.js → verification-artifact-C-lIHfUa.js} +1 -1
- package/server/{verification-runner-gAzh3cVD.js → verification-runner-Br0S_Ous.js} +103 -37
- package/server/{verification-runner-Dcksl_P-.js → verification-runner-CDj4lD4t.js} +1 -1
- package/server/{vtt-parser-3VZKsmSm.js → vtt-parser-DKpNNW5i.js} +1 -1
- package/server/{work-agent-prompt-ULdcANl5.js → work-agent-prompt-Yb2bd3Fq.js} +16 -15
- package/server/{workflows-B8ROFlfw.js → workflows-C9WmILql.js} +39 -77
- package/server/workflows-D90rMOya.js +2 -0
- package/server/{workspace-DhTDA8nB.js → workspace-BVl4rihN.js} +3 -3
- package/server/{workspace-DSjUJaJN.js → workspace-DuUdndHe.js} +1 -1
- package/server/{workspace-config-BAAsAv-o.js → workspace-config-cEGcO6UT.js} +1 -1
- package/server/{workspace-manager-CcujONCR.js → workspace-manager-ZTdJAy9M.js} +1 -1
- package/server/{workspace-manager-DsN52IMG.js → workspace-manager-hLUv3ADC.js} +23 -16
- package/server/{workspace-metadata-DIL5_U4c.js → workspace-metadata-CskwzzhL.js} +2 -2
- package/server/{workspace-metadata-CftOpNLs.js → workspace-metadata-DNpMixRq.js} +1 -1
- package/server/{workspaces-Dmlh1YXm.js → workspaces-hWvy9eKs.js} +276 -110
- package/sync-sources/agents/pan-inspect-agent.md +1 -1
- package/sync-sources/agents/pan-merge-agent.md +1 -1
- package/sync-sources/agents/pan-planning-agent.md +4 -4
- package/sync-sources/agents/pan-work-agent.md +1 -1
- package/sync-sources/dev-skills/pan-commit/SKILL.md +1 -1
- package/sync-sources/dev-skills/test-specialist-workflow/SKILL.md +1 -1
- package/sync-sources/hooks/record-cost-event.js +363 -71
- package/sync-sources/hooks/session-start-hook +7 -0
- package/sync-sources/hooks/work-agent-stop-hook +1 -1
- package/sync-sources/rules/per-bead-durability.md +1 -1
- package/sync-sources/rules/prd-authoring.md +1 -1
- package/sync-sources/skills/feature-work/SKILL.md +1 -1
- package/sync-sources/skills/pan/SKILL.md +2 -2
- package/sync-sources/skills/pan-admin-config/SKILL.md +1 -0
- package/sync-sources/skills/pan-approve/SKILL.md +1 -1
- package/sync-sources/skills/pan-close/SKILL.md +1 -1
- package/sync-sources/skills/pan-doctor/SKILL.md +1 -1
- package/sync-sources/skills/pan-new-project/SKILL.md +9 -11
- package/sync-sources/skills/pan-oversee/SKILL.md +5 -5
- package/sync-sources/skills/pan-plan/SKILL.md +6 -6
- package/sync-sources/skills/pan-quickstart/SKILL.md +1 -1
- package/sync-sources/skills/pan-recap/SKILL.md +2 -2
- package/sync-sources/skills/pan-review/SKILL.md +1 -1
- package/sync-sources/skills/pan-start/SKILL.md +26 -3
- package/sync-sources/skills/pan-swarm/SKILL.md +1 -1
- package/sync-sources/skills/pan-sync/SKILL.md +1 -1
- package/sync-sources/skills/pan-task/SKILL.md +2 -2
- package/sync-sources/skills/pan-wipe/SKILL.md +2 -2
- package/sync-sources/skills/pipeline-list/SKILL.md +1 -1
- package/sync-sources/skills/pipeline-status/SKILL.md +2 -2
- package/sync-sources/skills/plan/SKILL.md +11 -11
- package/sync-sources/skills/write-vbrief/SKILL.md +7 -282
- package/sync-sources/skills/write-xbrief/SKILL.md +295 -0
- package/sync-sources/templates/claude-md/sections/warnings.md +1 -1
- package/server/agent-state-BV_6RHnO.js +0 -3
- package/server/agents-Czz6R57Z.js +0 -3
- package/server/cli-ChErG518.js +0 -3
- package/server/codex-BBeZ8c3s.js +0 -3
- package/server/deacon-swarm-uudlSCLM.js +0 -2
- package/server/dist-BEDL2alY.js +0 -3
- package/server/forge-DbhJyH6u.js +0 -2
- package/server/git-utils-Bkxzr1Xf.js +0 -129
- package/server/hume-BrA1tUuk.js +0 -3
- package/server/inspect-agent-CyXNo9fM.js +0 -2
- package/server/lifecycle-io-CUpsxG0p.js +0 -3
- package/server/merge-ops-BpTtuO8x.js +0 -2
- package/server/projects-IRHJIPYC.js +0 -3
- package/server/providers-BqCdTryq.js +0 -3
- package/server/public/assets/index-C6NLz_1S.css +0 -1
- package/server/public/assets/mermaid-GHXKKRXX-BNwFoQsf.js +0 -1
- package/server/rally-DGimSRBQ.js +0 -3
- package/server/reap-terminal-sessions-C1mfzoZo.js +0 -3
- package/server/record-update-RviRDSNs.js +0 -168
- package/server/record-us0YECMO.js +0 -3
- package/server/resume-OyN3dEXE.js +0 -3
- package/server/review-status-DXeqFpk5.js +0 -3
- package/server/settings-BaPXXJsT.js +0 -2
- package/server/specialists-C6WkeKFK.js +0 -3
- package/server/specs-BsNcum0h.js +0 -3
- package/server/state-migrate-_zJJ6XKE.js +0 -362
- package/server/supervisor-Qy1QecAs.js +0 -2
- package/server/tmux-HQLgwo_C.js +0 -3
- package/server/token-util-Cg-QnowA.js +0 -3
- package/server/workflows-C5c-RPsY.js +0 -2
|
@@ -1,62 +1,183 @@
|
|
|
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-
|
|
2
|
+
import { Gr as sessionFilePath, Gt as reconcileStatePlaneDrift, Jt as getMainDivergence, Nt as readIssueRecordSync, Ot as init_record, Tn as init_projects, Ut as init_auto_commit, Vr as init_paths, Yt as init_state_plane, Zt as isStatePlanePath, b as DEFAULT_CONFIG$1, f as loadConfigSync, hr as AGENTS_DIR, kn as listProjectsSync, mr as init_errors, qt as STATE_PLANE_PATHS, s as init_load, wr as OVERDECK_HOME, x as init_defaults, yn as getProjectSync, zn as resolveProjectFromIssueSync } from "./config-yaml-DvyMuOle.js";
|
|
3
|
+
import { n as init_build_info, t as getBuildInfo } from "./build-info-BT096lEl.js";
|
|
4
|
+
import { n as getDashboardIdentity, t as recordDeaconNudge } from "./deacon-nudge-log-Bjg8U4Y9.js";
|
|
5
5
|
import { a as init_activity_logger, n as emitActivityEntrySync, r as emitActivityTtsSync } from "./activity-logger-DDlOIAML.js";
|
|
6
|
-
import { n as updateIssueRecord, t as init_record_update } from "./record-update-
|
|
7
|
-
import {
|
|
8
|
-
import { a as init_event_store, i as initEventStore } from "./event-store-
|
|
9
|
-
import {
|
|
10
|
-
import { c as
|
|
11
|
-
import {
|
|
12
|
-
import { c as
|
|
13
|
-
import {
|
|
14
|
-
import { i as
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import { l as
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import { a as
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import { a as
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import { a as
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import { n as
|
|
36
|
-
import { n as
|
|
37
|
-
import {
|
|
38
|
-
import { t as
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import { n as
|
|
42
|
-
import {
|
|
43
|
-
import { n as
|
|
44
|
-
import {
|
|
6
|
+
import { n as updateIssueRecord, t as init_record_update } from "./record-update-Dq0t2uBG.js";
|
|
7
|
+
import { A as listPaneValues, B as sendKeysAsync, D as killSession, E as isPaneDead, H as sessionExists, I as querySessionSync, M as listSessionNames, N as listSessions, U as sessionExistsSync, i as capturePane, w as init_tmux, z as sendKeys } from "./tmux-ftABRAmc.js";
|
|
8
|
+
import { a as init_event_store, i as initEventStore } from "./event-store-tdiY5eDZ.js";
|
|
9
|
+
import { C as projectLegacySystemHealthSummary, t as init_src } from "./src-U7_kTPEE.js";
|
|
10
|
+
import { C as needsReviewDispatch, S as init_review_dispatch_decision, b as setReviewStatusSync, c as getReviewStatusSync, d as loadReviewStatuses, g as reviewGatesPassedSync, l as init_review_status } from "./review-status-A7quS5KJ.js";
|
|
11
|
+
import { c as listAllAgentsSync, d as isTerminalIssueStage, o as init_agents, u as getIssueStageSync } from "./agents-B4Bjbkfv.js";
|
|
12
|
+
import { $n as recordAgentFailure, Ar as init_codex_auth, Bn as getAgentDir, Cr as getAgentRuntimeStateSync, Ct as tryReserveAdvancingSlot, Dt as init_memory_verdict_cache, En as buildDefaultResumeContinueMessage, Ft as init_transcript_landing, G as resumeAgent, Gn as init_agent_state, Hn as getAgentState, J as isContextOverflowTail, K as init_context_overflow, Ln as clearAgentTroubledSync, Or as applyCodexAuthBurnFlag, Ot as setCachedMemoryVerdict, Pt as captureTranscriptUserRecordSnapshot, Rn as clearYieldForResumeSync, Sr as getAgentRuntimeState, St as resetPatrolDispatchBudget, Tr as saveAgentRuntimeState, Tt as workResumeSlotsAvailable, Wn as getAgentStateSync, X as messageAgent, Xn as markAgentRunningState, Y as init_messaging, _ as init_linux, a as listRunningAgentsSync, b as init_agents$1, bt as releaseAdvancingSlot, c as getRuntimeCensus, dt as init_termination, ft as stopAgent, g as LINUX_MEMORY_PRESSURE_DEFAULTS, gt as describeRunningAgents, h as init_collector, i as listRunningAgents, ir as saveAgentStateSync, jr as paneShowsCodexAuthBurn, jt as deliverInitialPromptWithRetry, m as createHostHealthCollector, mt as countRunningAgents, n as init_queries, nr as resetAgentFailureCount, or as setAgentPausedSync, r as listAgentStates, rr as saveAgentState, s as descendantPidsForSession, sr as setAgentYieldedSync, u as init_runtime_census, v as DARWIN_MEMORY_PRESSURE_DEFAULTS, vt as getConcurrencyLimits, wr as init_runtime_state, y as init_darwin, yt as init_concurrency } from "./queries-6d7Cdtm7.js";
|
|
13
|
+
import { c as logDeaconEventSync, l as getRuntimeSnapshot, o as init_persistent_logger, s as logAgentLifecycleSync, u as init_agent_runtime_mirror } from "./session-history-CVZDpS3c.js";
|
|
14
|
+
import { i as resolveGitHubIssueSync, n as init_tracker_utils } from "./tracker-utils-tnxxqROg.js";
|
|
15
|
+
import { i as ensureInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-Bb4XeV2x.js";
|
|
16
|
+
import { c as init_review_status_sync, l as markWorkspaceStuck } from "./review-status-sync-BhSQ0d0l.js";
|
|
17
|
+
import { i as readReviewStatusMap, n as init_review_status_source, t as classifyAdvancingSessionLifecycle } from "./review-status-source-CxuEjLGg.js";
|
|
18
|
+
import { m as readWorkspacePlanSync, o as init_io } from "./io-B3_AHDfr.js";
|
|
19
|
+
import { f as init_config, m as loadConfigSync$1, p as loadConfig$1 } from "./config-CCvjQf27.js";
|
|
20
|
+
import { T as stampBootReconciliation, h as setBootReconciliationDecision, l as isDeaconGloballyPaused, r as getBootReconciliationState, s as init_control_settings } from "./control-settings-aP1ANIlI.js";
|
|
21
|
+
import { c as init_docker_stats, s as DockerStatsCollector } from "./stack-health-puygdaMd.js";
|
|
22
|
+
import { l as init_dag, o as getDispatchableItems } from "./dag-CdOjJVDT.js";
|
|
23
|
+
import { a as loadCloisterConfigSync, i as loadCloisterConfig, r as init_config$1 } from "./config-DjLOdbgT.js";
|
|
24
|
+
import { a as findRecreatedLegacyStatePaths, o as init_state_home } from "./state-home-CIGjwNfJ.js";
|
|
25
|
+
import { A as withConcurrencyLimit, k as init_concurrency$1 } from "./github-app-CMBdIFBQ.js";
|
|
26
|
+
import { a as isAgentIdleForNudge, t as checkStuckAgentRemediation } from "./stuck-remediation-CzEov_fq.js";
|
|
27
|
+
import { n as __filename, r as init_esm_shims } from "./esm-shims-CbI3BVkl.js";
|
|
28
|
+
import { i as init_staleness, r as computeBuildStaleness } from "./staleness-Bpy41ngS.js";
|
|
29
|
+
import { a as pidsWithCwdUnder, i as sweepAutoCloseOutCache, n as pruneTerminalStoppedAgents, r as getAutoCloseOutCanonicalState } from "./agent-gc-BV1q_2EV.js";
|
|
30
|
+
import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-C9b6ccN1.js";
|
|
31
|
+
import { r as surfaceIssueFeedbackNeedsYou, t as init_feedback_target } from "./feedback-target-CPS15Vte.js";
|
|
32
|
+
import { a as init_review_convoy_liveness, c as init_review_monitor, i as evaluateReviewConvoyLiveness, o as reviewTimestampMs, r as init_in_flight_guard, s as REVIEW_SUB_ROLES, t as createInFlightGuard } from "./in-flight-guard-aQ1IxeI3.js";
|
|
33
|
+
import { J as parseReviewerSessionName, U as getTmuxSessionName, g as getAllProjectSpecialistStatuses, t as init_specialists } from "./specialists-DyFeedjn.js";
|
|
34
|
+
import { a as inferBranchFromWorkspace, i as findWorkspacePath, o as init_archive_planning } from "./archive-planning-DYrYojxl.js";
|
|
35
|
+
import { n as init_issue_closed, r as isIssueClosed } from "./issue-closed-zhdvQicO.js";
|
|
36
|
+
import { n as shouldSkipDispatchAsMerged, t as init_merge_verification } from "./merge-verification-CSizH3HY.js";
|
|
37
|
+
import { n as init_review_verdict_feedback, t as deliverReviewVerdictFeedback } from "./review-verdict-feedback-CTRNtzXO.js";
|
|
38
|
+
import { n as reconcileTraefikNetworks, t as init_traefik_connect } from "./traefik-connect-m73vGebA.js";
|
|
39
|
+
import { g as decideAgentAutonomousRedrive, r as coordinateSwarmSlots, y as listFeatureWorkspaces } from "./deacon-swarm-DftYRDo8.js";
|
|
40
|
+
import { t as recordRecoveryFailure } from "./recovery-trip-BJtIQuag.js";
|
|
41
|
+
import { n as isExplicitNoResumeRequest, t as init_no_resume_mode } from "./no-resume-mode-Cx3K0hHi.js";
|
|
42
|
+
import { n as reconcileClosedIssueAgents } from "./closed-issue-reaper-hANY_ehE.js";
|
|
43
|
+
import { n as init_label_reconciler, r as reconcilePipelineLabelsPatrol } from "./label-reconciler-DdWbHEBu.js";
|
|
44
|
+
import { a as spawnWorkAgentThroughAgentsEndpoint, i as reconcileOrphanProposedSpecs, o as triggerRebuildAndStart } from "./orphan-proposed-reconciler-neK8dHQk.js";
|
|
45
|
+
import { n as reconcileIdleWorkspaceStacks } from "./idle-stack-reaper-w1ISSlhs.js";
|
|
46
|
+
import { i as readTestVerdictArtifact, n as decideUnsignaledTestAction, r as init_test_verdict } from "./test-verdict-CmUBK5cT.js";
|
|
45
47
|
import { createRequire } from "node:module";
|
|
46
48
|
import { join } from "node:path";
|
|
47
49
|
import { Effect } from "effect";
|
|
48
50
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "fs";
|
|
49
51
|
import { dirname as dirname$1, join as join$1 } from "path";
|
|
50
52
|
import { cpus, loadavg } from "os";
|
|
51
|
-
import {
|
|
53
|
+
import { freemem as freemem$1, homedir as homedir$1, platform as platform$1, totalmem as totalmem$1 } from "node:os";
|
|
52
54
|
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";
|
|
53
|
-
import {
|
|
55
|
+
import { readFile } from "node:fs/promises";
|
|
54
56
|
import { readFile as readFile$1, readdir as readdir$1, writeFile as writeFile$1 } from "fs/promises";
|
|
55
57
|
import { exec, execFile, spawn } from "node:child_process";
|
|
56
58
|
import { promisify } from "node:util";
|
|
57
59
|
import { exec as exec$1, execFile as execFile$1, spawn as spawn$1 } from "child_process";
|
|
58
60
|
import { promisify as promisify$1 } from "util";
|
|
59
61
|
import { layer } from "@effect/platform-node/NodeServices";
|
|
62
|
+
//#region ../../lib/agents/health.ts
|
|
63
|
+
init_paths();
|
|
64
|
+
init_errors();
|
|
65
|
+
init_activity_logger();
|
|
66
|
+
init_projects();
|
|
67
|
+
init_state_plane();
|
|
68
|
+
init_auto_commit();
|
|
69
|
+
init_record();
|
|
70
|
+
init_record_update();
|
|
71
|
+
init_tmux();
|
|
72
|
+
init_src();
|
|
73
|
+
init_agents();
|
|
74
|
+
init_agent_runtime_mirror();
|
|
75
|
+
init_persistent_logger();
|
|
76
|
+
init_internal_token();
|
|
77
|
+
init_review_status_sync();
|
|
78
|
+
init_review_status_source();
|
|
79
|
+
init_review_dispatch_decision();
|
|
80
|
+
init_review_status();
|
|
81
|
+
init_codex_auth();
|
|
82
|
+
init_runtime_state();
|
|
83
|
+
init_agent_state();
|
|
84
|
+
init_transcript_landing();
|
|
85
|
+
init_config$1();
|
|
86
|
+
init_memory_verdict_cache();
|
|
87
|
+
init_concurrency();
|
|
88
|
+
init_termination();
|
|
89
|
+
init_messaging();
|
|
90
|
+
init_context_overflow();
|
|
91
|
+
init_agents$1();
|
|
92
|
+
init_darwin();
|
|
93
|
+
init_linux();
|
|
94
|
+
init_collector();
|
|
95
|
+
init_runtime_census();
|
|
96
|
+
init_queries();
|
|
97
|
+
const STARTUP_GRACE_MS = 300 * 1e3;
|
|
98
|
+
const ACTIVITY_WARNING_MS = 900 * 1e3;
|
|
99
|
+
const ACTIVITY_STALLED_MS = 1800 * 1e3;
|
|
100
|
+
function reason$1(code, severity, message) {
|
|
101
|
+
return {
|
|
102
|
+
code,
|
|
103
|
+
domain: "agent",
|
|
104
|
+
severity,
|
|
105
|
+
message
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function validTimestamp(value) {
|
|
109
|
+
if (!value) return null;
|
|
110
|
+
const timestamp = Date.parse(value);
|
|
111
|
+
return Number.isFinite(timestamp) ? timestamp : null;
|
|
112
|
+
}
|
|
113
|
+
function latestActivity(persisted, runtime) {
|
|
114
|
+
const candidates = [persisted.lastActivity, runtime?.lastActivity].map((value) => ({
|
|
115
|
+
value,
|
|
116
|
+
timestamp: validTimestamp(value)
|
|
117
|
+
})).filter((entry) => entry.value !== void 0 && entry.timestamp !== null);
|
|
118
|
+
if (candidates.length === 0) return void 0;
|
|
119
|
+
return candidates.reduce((latest, entry) => entry.timestamp > latest.timestamp ? entry : latest).value;
|
|
120
|
+
}
|
|
121
|
+
function agentKind(role) {
|
|
122
|
+
if (role === "work") return "work";
|
|
123
|
+
if (role === "plan") return "planning";
|
|
124
|
+
if (role === "review" || role === "test" || role === "ship") return "specialist";
|
|
125
|
+
return "other";
|
|
126
|
+
}
|
|
127
|
+
function intentionalInactive(state) {
|
|
128
|
+
return state.status === "stopped" || state.status === "completed" || state.paused === true || state.stoppedByUser === true || state.stoppedByPause === true;
|
|
129
|
+
}
|
|
130
|
+
function lifecycleFor(input, state) {
|
|
131
|
+
if (input.reviewLifecycle === "warm" || input.reviewLifecycle === "orphaned") return input.reviewLifecycle;
|
|
132
|
+
if (input.liveSessions.has(input.agentId) && !intentionalInactive(state)) return "active";
|
|
133
|
+
return input.reviewLifecycle ?? "unknown";
|
|
134
|
+
}
|
|
135
|
+
function buildSnapshot(input, state, status, reasons) {
|
|
136
|
+
const lastActivityAt = latestActivity(state, input.runtime);
|
|
137
|
+
const observations = input.observations;
|
|
138
|
+
return {
|
|
139
|
+
id: input.agentId,
|
|
140
|
+
...state.issueId ? { issueId: state.issueId } : {},
|
|
141
|
+
...state.role ? { role: state.role } : {},
|
|
142
|
+
kind: agentKind(state.role),
|
|
143
|
+
status,
|
|
144
|
+
lifecycle: lifecycleFor(input, state),
|
|
145
|
+
tmuxActive: input.liveSessions.has(input.agentId),
|
|
146
|
+
...lastActivityAt ? { lastActivityAt } : {},
|
|
147
|
+
...observations?.consecutiveFailures !== void 0 ? { consecutiveFailures: observations.consecutiveFailures } : state.consecutiveFailures !== void 0 ? { consecutiveFailures: state.consecutiveFailures } : {},
|
|
148
|
+
...observations?.killCount !== void 0 ? { killCount: observations.killCount } : {},
|
|
149
|
+
...observations && Object.prototype.hasOwnProperty.call(observations, "contextPercent") ? { contextPercent: observations.contextPercent ?? null } : {},
|
|
150
|
+
reasons
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Classifies one resolved agent snapshot. The function is intentionally free of
|
|
155
|
+
* filesystem, tmux, review-status, and runtime-store imports so every caller
|
|
156
|
+
* supplies one coherent set of evidence and cycle-prone dashboard code remains
|
|
157
|
+
* a thin resolver adapter.
|
|
158
|
+
*/
|
|
159
|
+
function classifyAgentHealth(input) {
|
|
160
|
+
if (input.persisted.status === "unavailable") return buildSnapshot(input, {}, "unavailable", [reason$1("agent.persisted_state.unavailable", "warning", input.persisted.reason)]);
|
|
161
|
+
const state = input.persisted.value;
|
|
162
|
+
if (input.runtime?.contextSaturatedAt) return buildSnapshot(input, state, "wedged", [reason$1("agent.context.saturated", "critical", "Context window exhausted; recovery is required.")]);
|
|
163
|
+
const startedAt = validTimestamp(state.startedAt);
|
|
164
|
+
const startupGraceElapsed = startedAt !== null && input.nowMs - startedAt >= STARTUP_GRACE_MS;
|
|
165
|
+
const expectsLiveSession = state.status === "running" || state.status === "starting";
|
|
166
|
+
if (!input.liveSessions.has(input.agentId) && expectsLiveSession && startupGraceElapsed) return buildSnapshot(input, state, "dead", [reason$1("agent.tmux.missing", "critical", "The persisted agent is running but its tmux session is missing.")]);
|
|
167
|
+
if (state.role === "work" && state.status === "running" && state.kickoffDelivered === false && startupGraceElapsed) return buildSnapshot(input, state, "stalled", [reason$1("agent.kickoff.not_delivered", "warning", "Work agent running with no kickoff delivered since spawn")]);
|
|
168
|
+
if (input.runtime?.state === "waiting-on-human") return buildSnapshot(input, state, "waiting", [reason$1("agent.runtime.waiting_on_human", "info", "The agent is waiting for operator input.")]);
|
|
169
|
+
if (input.reviewLifecycle === "warm" || input.reviewLifecycle === "orphaned" || input.runtime?.state === "idle" || input.runtime?.state === "suspended" || input.runtime?.state === "stopped" || intentionalInactive(state)) return buildSnapshot(input, state, "idle", []);
|
|
170
|
+
if (input.runtime?.state === "active") {
|
|
171
|
+
const lastActivityMs = validTimestamp(latestActivity(state, input.runtime));
|
|
172
|
+
if (lastActivityMs !== null) {
|
|
173
|
+
const inactivityMs = Math.max(0, input.nowMs - lastActivityMs);
|
|
174
|
+
if (inactivityMs >= ACTIVITY_STALLED_MS) return buildSnapshot(input, state, "stalled", [reason$1("agent.runtime.inactive.stalled", "warning", `The active agent has produced no activity for ${Math.round(inactivityMs / 6e4)} minutes.`)]);
|
|
175
|
+
if (inactivityMs >= ACTIVITY_WARNING_MS) return buildSnapshot(input, state, "warning", [reason$1("agent.runtime.inactive.warning", "warning", `The active agent has produced no activity for ${Math.round(inactivityMs / 6e4)} minutes.`)]);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return buildSnapshot(input, state, "healthy", []);
|
|
179
|
+
}
|
|
180
|
+
//#endregion
|
|
60
181
|
//#region ../../../node_modules/.bun/undici@7.25.0/node_modules/undici/lib/core/symbols.js
|
|
61
182
|
var require_symbols = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
62
183
|
module.exports = {
|
|
@@ -21468,9 +21589,7 @@ var require_eventsource = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
21468
21589
|
defaultReconnectionTime
|
|
21469
21590
|
};
|
|
21470
21591
|
}));
|
|
21471
|
-
|
|
21472
|
-
//#region ../../../node_modules/.bun/undici@7.25.0/node_modules/undici/index.js
|
|
21473
|
-
var require_undici = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
21592
|
+
new ((/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
21474
21593
|
init_esm_shims();
|
|
21475
21594
|
const Client = require_client();
|
|
21476
21595
|
const Dispatcher = require_dispatcher();
|
|
@@ -21636,37 +21755,7 @@ var require_undici = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
21636
21755
|
globalThis.EventSource = module.exports.EventSource;
|
|
21637
21756
|
}
|
|
21638
21757
|
module.exports.install = install;
|
|
21639
|
-
}));
|
|
21640
|
-
//#endregion
|
|
21641
|
-
//#region ../../../node_modules/.bun/smee-client@5.0.0/node_modules/smee-client/index.js
|
|
21642
|
-
init_paths();
|
|
21643
|
-
init_errors();
|
|
21644
|
-
init_activity_logger();
|
|
21645
|
-
init_projects();
|
|
21646
|
-
init_state_plane();
|
|
21647
|
-
init_auto_commit();
|
|
21648
|
-
init_record();
|
|
21649
|
-
init_record_update();
|
|
21650
|
-
init_tmux();
|
|
21651
|
-
init_agents();
|
|
21652
|
-
init_persistent_logger();
|
|
21653
|
-
init_internal_token();
|
|
21654
|
-
init_review_status_sync();
|
|
21655
|
-
init_review_dispatch_decision();
|
|
21656
|
-
init_review_status();
|
|
21657
|
-
init_codex_auth();
|
|
21658
|
-
init_runtime_state();
|
|
21659
|
-
init_agent_state();
|
|
21660
|
-
init_transcript_landing();
|
|
21661
|
-
init_config$1();
|
|
21662
|
-
init_memory_verdict_cache();
|
|
21663
|
-
init_concurrency();
|
|
21664
|
-
init_termination();
|
|
21665
|
-
init_messaging();
|
|
21666
|
-
init_context_overflow();
|
|
21667
|
-
init_agents$1();
|
|
21668
|
-
init_queries();
|
|
21669
|
-
new (require_undici()).EnvHttpProxyAgent();
|
|
21758
|
+
})))()).EnvHttpProxyAgent();
|
|
21670
21759
|
//#endregion
|
|
21671
21760
|
//#region ../../lib/smee.ts
|
|
21672
21761
|
/**
|
|
@@ -21849,35 +21938,486 @@ function startSmeeProcessSync() {
|
|
|
21849
21938
|
console.log(`[smee] Started process (PID ${child.pid}) relaying to ${target}`);
|
|
21850
21939
|
}
|
|
21851
21940
|
//#endregion
|
|
21852
|
-
//#region
|
|
21853
|
-
init_docker_stats();
|
|
21941
|
+
//#region ../../lib/system-health/config.ts
|
|
21854
21942
|
init_build_info();
|
|
21855
|
-
|
|
21943
|
+
init_docker_stats();
|
|
21944
|
+
init_defaults();
|
|
21945
|
+
init_load();
|
|
21946
|
+
const GIB$2 = 1024 ** 3;
|
|
21947
|
+
const SYSTEM_HEALTH_DEFAULTS = Object.freeze({
|
|
21948
|
+
pollSeconds: 15,
|
|
21949
|
+
memoryWarnGb: DEFAULT_CONFIG$1.resources.memoryWarnGb,
|
|
21950
|
+
memoryBlockGb: DEFAULT_CONFIG$1.resources.memoryBlockGb,
|
|
21951
|
+
agentWarnCount: DEFAULT_CONFIG$1.resources.agentWarnCount,
|
|
21952
|
+
agentBlockCount: DEFAULT_CONFIG$1.resources.agentBlockCount,
|
|
21953
|
+
swapUsedWarningPercent: 20,
|
|
21954
|
+
swapUsedCriticalPercent: 50,
|
|
21955
|
+
cpuLoadWarningPerCore: 1,
|
|
21956
|
+
cpuLoadCriticalPerCore: 1.5,
|
|
21957
|
+
overcommitWarningPercent: 150,
|
|
21958
|
+
overcommitCriticalPercent: 200
|
|
21959
|
+
});
|
|
21960
|
+
function finiteNonnegative(value) {
|
|
21961
|
+
if (value === "" || value == null) return null;
|
|
21962
|
+
const parsed = typeof value === "number" ? value : Number(value);
|
|
21963
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : null;
|
|
21964
|
+
}
|
|
21965
|
+
/**
|
|
21966
|
+
* Normalizes every health threshold in one pass. Any invalid value or reversed
|
|
21967
|
+
* pair falls back to its named defaults, and the caller receives one warning
|
|
21968
|
+
* describing the complete fallback rather than one warning per field.
|
|
21969
|
+
*/
|
|
21970
|
+
function normalizeSystemHealthThresholds(input, warn = console.warn) {
|
|
21971
|
+
const invalid = [];
|
|
21972
|
+
const scalar = (name, fallback, minimum = 0) => {
|
|
21973
|
+
const value = finiteNonnegative(input[name]);
|
|
21974
|
+
if (value == null || value < minimum) {
|
|
21975
|
+
invalid.push(String(name));
|
|
21976
|
+
return fallback;
|
|
21977
|
+
}
|
|
21978
|
+
return value;
|
|
21979
|
+
};
|
|
21980
|
+
const increasingPair = (warningName, criticalName, warningDefault, criticalDefault) => {
|
|
21981
|
+
const warning = finiteNonnegative(input[warningName]);
|
|
21982
|
+
const critical = finiteNonnegative(input[criticalName]);
|
|
21983
|
+
if (warning == null || critical == null || warning > critical) {
|
|
21984
|
+
invalid.push(`${String(warningName)}/${String(criticalName)}`);
|
|
21985
|
+
return [warningDefault, criticalDefault];
|
|
21986
|
+
}
|
|
21987
|
+
return [warning, critical];
|
|
21988
|
+
};
|
|
21989
|
+
const decreasingPair = (warningName, criticalName, warningDefault, criticalDefault) => {
|
|
21990
|
+
const warning = finiteNonnegative(input[warningName]);
|
|
21991
|
+
const critical = finiteNonnegative(input[criticalName]);
|
|
21992
|
+
if (warning == null || critical == null || warning < critical) {
|
|
21993
|
+
invalid.push(`${String(warningName)}/${String(criticalName)}`);
|
|
21994
|
+
return [warningDefault, criticalDefault];
|
|
21995
|
+
}
|
|
21996
|
+
return [warning, critical];
|
|
21997
|
+
};
|
|
21998
|
+
const [memoryWarnGb, memoryBlockGb] = decreasingPair("memoryWarnGb", "memoryBlockGb", SYSTEM_HEALTH_DEFAULTS.memoryWarnGb, SYSTEM_HEALTH_DEFAULTS.memoryBlockGb);
|
|
21999
|
+
const [agentWarnCountValue, agentBlockCountValue] = increasingPair("agentWarnCount", "agentBlockCount", SYSTEM_HEALTH_DEFAULTS.agentWarnCount, SYSTEM_HEALTH_DEFAULTS.agentBlockCount);
|
|
22000
|
+
const [swapUsedWarningPercent, swapUsedCriticalPercent] = increasingPair("swapUsedWarningPercent", "swapUsedCriticalPercent", SYSTEM_HEALTH_DEFAULTS.swapUsedWarningPercent, SYSTEM_HEALTH_DEFAULTS.swapUsedCriticalPercent);
|
|
22001
|
+
const [cpuLoadWarningPerCore, cpuLoadCriticalPerCore] = increasingPair("cpuLoadWarningPerCore", "cpuLoadCriticalPerCore", SYSTEM_HEALTH_DEFAULTS.cpuLoadWarningPerCore, SYSTEM_HEALTH_DEFAULTS.cpuLoadCriticalPerCore);
|
|
22002
|
+
const [overcommitWarningPercent, overcommitCriticalPercent] = increasingPair("overcommitWarningPercent", "overcommitCriticalPercent", SYSTEM_HEALTH_DEFAULTS.overcommitWarningPercent, SYSTEM_HEALTH_DEFAULTS.overcommitCriticalPercent);
|
|
22003
|
+
const pollSeconds = scalar("pollSeconds", SYSTEM_HEALTH_DEFAULTS.pollSeconds, 1);
|
|
22004
|
+
const agentWarnCount = Math.max(1, Math.floor(agentWarnCountValue));
|
|
22005
|
+
const agentBlockCount = Math.max(1, Math.floor(agentBlockCountValue));
|
|
22006
|
+
if (invalid.length > 0) warn(`[system-health] Invalid thresholds (${invalid.join(", ")}); using named defaults.`);
|
|
22007
|
+
return {
|
|
22008
|
+
pollSeconds: Math.max(1, Math.floor(pollSeconds)),
|
|
22009
|
+
resources: {
|
|
22010
|
+
memoryWarnGb,
|
|
22011
|
+
memoryBlockGb,
|
|
22012
|
+
agentWarnCount,
|
|
22013
|
+
agentBlockCount
|
|
22014
|
+
},
|
|
22015
|
+
thresholds: {
|
|
22016
|
+
memoryAvailableWarningBytes: memoryWarnGb * GIB$2,
|
|
22017
|
+
memoryAvailableCriticalBytes: memoryBlockGb * GIB$2,
|
|
22018
|
+
swapUsedWarningPercent,
|
|
22019
|
+
swapUsedCriticalPercent,
|
|
22020
|
+
cpuLoadWarningPerCore,
|
|
22021
|
+
cpuLoadCriticalPerCore,
|
|
22022
|
+
overcommitWarningPercent,
|
|
22023
|
+
overcommitCriticalPercent
|
|
22024
|
+
}
|
|
22025
|
+
};
|
|
22026
|
+
}
|
|
22027
|
+
function resolveSystemHealthConfig(options = {}) {
|
|
22028
|
+
const resources = options.resources ?? loadConfigSync().config.resources;
|
|
22029
|
+
const env = options.env ?? process.env;
|
|
22030
|
+
return normalizeSystemHealthThresholds({
|
|
22031
|
+
pollSeconds: env["PAN_HEALTH_POLL_SECONDS"] ?? SYSTEM_HEALTH_DEFAULTS.pollSeconds,
|
|
22032
|
+
memoryWarnGb: env["PAN_MEMORY_WARN_GB"] ?? resources.memoryWarnGb,
|
|
22033
|
+
memoryBlockGb: env["PAN_MEMORY_BLOCK_GB"] ?? resources.memoryBlockGb,
|
|
22034
|
+
agentWarnCount: env["PAN_AGENT_WARN_COUNT"] ?? resources.agentWarnCount,
|
|
22035
|
+
agentBlockCount: env["PAN_AGENT_BLOCK_COUNT"] ?? resources.agentBlockCount,
|
|
22036
|
+
swapUsedWarningPercent: env["PAN_HEALTH_SWAP_WARN_PERCENT"] ?? SYSTEM_HEALTH_DEFAULTS.swapUsedWarningPercent,
|
|
22037
|
+
swapUsedCriticalPercent: env["PAN_HEALTH_SWAP_CRITICAL_PERCENT"] ?? SYSTEM_HEALTH_DEFAULTS.swapUsedCriticalPercent,
|
|
22038
|
+
cpuLoadWarningPerCore: env["PAN_HEALTH_LOAD_WARN_PER_CORE"] ?? SYSTEM_HEALTH_DEFAULTS.cpuLoadWarningPerCore,
|
|
22039
|
+
cpuLoadCriticalPerCore: env["PAN_HEALTH_LOAD_CRITICAL_PER_CORE"] ?? SYSTEM_HEALTH_DEFAULTS.cpuLoadCriticalPerCore,
|
|
22040
|
+
overcommitWarningPercent: env["PAN_HEALTH_OVERCOMMIT_WARN_PERCENT"] ?? SYSTEM_HEALTH_DEFAULTS.overcommitWarningPercent,
|
|
22041
|
+
overcommitCriticalPercent: env["PAN_HEALTH_OVERCOMMIT_CRITICAL_PERCENT"] ?? SYSTEM_HEALTH_DEFAULTS.overcommitCriticalPercent
|
|
22042
|
+
}, options.warn);
|
|
22043
|
+
}
|
|
22044
|
+
//#endregion
|
|
22045
|
+
//#region ../../lib/system-health/evaluate.ts
|
|
22046
|
+
function value(signal) {
|
|
22047
|
+
return signal.status === "available" ? signal.value : null;
|
|
22048
|
+
}
|
|
22049
|
+
function reason(code, domain, severity, message, metric, observed, threshold) {
|
|
22050
|
+
return {
|
|
22051
|
+
code,
|
|
22052
|
+
domain,
|
|
22053
|
+
severity,
|
|
22054
|
+
message,
|
|
22055
|
+
metric,
|
|
22056
|
+
observed,
|
|
22057
|
+
threshold
|
|
22058
|
+
};
|
|
22059
|
+
}
|
|
22060
|
+
function evaluateAdmission(sample, thresholds) {
|
|
22061
|
+
const availableMemoryBytes = value(sample.availableMemoryBytes);
|
|
22062
|
+
if (availableMemoryBytes == null) return {
|
|
22063
|
+
state: "unavailable",
|
|
22064
|
+
availableMemoryBytes: null,
|
|
22065
|
+
reasons: [{
|
|
22066
|
+
code: "admission.memory_available.unavailable",
|
|
22067
|
+
domain: "admission",
|
|
22068
|
+
severity: "info",
|
|
22069
|
+
message: "Available memory could not be measured, so admission capacity is unavailable.",
|
|
22070
|
+
metric: "availableMemoryBytes"
|
|
22071
|
+
}]
|
|
22072
|
+
};
|
|
22073
|
+
if (availableMemoryBytes <= thresholds.memoryAvailableCriticalBytes) return {
|
|
22074
|
+
state: "blocked",
|
|
22075
|
+
availableMemoryBytes,
|
|
22076
|
+
reasons: [reason("admission.memory_available.blocked", "admission", "critical", "Available memory is at or below the critical admission reserve.", "availableMemoryBytes", availableMemoryBytes, thresholds.memoryAvailableCriticalBytes)]
|
|
22077
|
+
};
|
|
22078
|
+
if (availableMemoryBytes <= thresholds.memoryAvailableWarningBytes) return {
|
|
22079
|
+
state: "soft",
|
|
22080
|
+
availableMemoryBytes,
|
|
22081
|
+
reasons: [reason("admission.memory_available.soft", "admission", "warning", "Available memory is at or below the warning admission reserve.", "availableMemoryBytes", availableMemoryBytes, thresholds.memoryAvailableWarningBytes)]
|
|
22082
|
+
};
|
|
22083
|
+
return {
|
|
22084
|
+
state: "open",
|
|
22085
|
+
availableMemoryBytes,
|
|
22086
|
+
reasons: []
|
|
22087
|
+
};
|
|
22088
|
+
}
|
|
22089
|
+
function diagnostics(sample, thresholds) {
|
|
22090
|
+
const results = [];
|
|
22091
|
+
const swapUsedPercent = value(sample.swapUsedPercent);
|
|
22092
|
+
if (swapUsedPercent != null && swapUsedPercent > 0) results.push(reason("host.diagnostic.swap_occupancy", "host", "info", "Swap occupancy is historical context and does not represent current pressure.", "swapUsedPercent", swapUsedPercent, thresholds.swapUsedWarningPercent));
|
|
22093
|
+
const virtualCommitmentPercent = value(sample.virtualCommitmentPercent);
|
|
22094
|
+
if (virtualCommitmentPercent != null) results.push(reason("host.diagnostic.virtual_commitment", "host", "info", "Virtual memory commitment is diagnostic and does not represent current pressure.", "virtualCommitmentPercent", virtualCommitmentPercent, thresholds.overcommitWarningPercent));
|
|
22095
|
+
return results;
|
|
22096
|
+
}
|
|
22097
|
+
function linuxPressureReasons(sample, admission) {
|
|
22098
|
+
const results = [];
|
|
22099
|
+
const some = value(sample.memoryPressureSomeAvg10);
|
|
22100
|
+
const full = value(sample.memoryPressureFullAvg10);
|
|
22101
|
+
const swapActivity = value(sample.swapActivityBytesPerMinute);
|
|
22102
|
+
if (admission.state === "blocked") {
|
|
22103
|
+
if (full != null && full >= LINUX_MEMORY_PRESSURE_DEFAULTS.fullCriticalAvg10) results.push(reason("host.linux.psi_full.critical", "host", "critical", "Linux memory PSI full stalls reached the critical band while memory was below reserve.", "memoryPressureFullAvg10", full, LINUX_MEMORY_PRESSURE_DEFAULTS.fullCriticalAvg10));
|
|
22104
|
+
if (swapActivity != null && swapActivity >= LINUX_MEMORY_PRESSURE_DEFAULTS.swapActivityCriticalBytesPerMinute) results.push(reason("host.linux.swap_activity.critical", "host", "critical", "Linux swap activity reached the critical band while memory was below reserve.", "swapActivityBytesPerMinute", swapActivity, LINUX_MEMORY_PRESSURE_DEFAULTS.swapActivityCriticalBytesPerMinute));
|
|
22105
|
+
}
|
|
22106
|
+
if (admission.state === "soft" || admission.state === "blocked") {
|
|
22107
|
+
if (some != null && some >= LINUX_MEMORY_PRESSURE_DEFAULTS.someWarningAvg10) results.push(reason("host.linux.psi_some.warning", "host", "warning", "Linux memory PSI some stalls reached the warning band while memory was below reserve.", "memoryPressureSomeAvg10", some, LINUX_MEMORY_PRESSURE_DEFAULTS.someWarningAvg10));
|
|
22108
|
+
if (swapActivity != null && swapActivity >= LINUX_MEMORY_PRESSURE_DEFAULTS.swapActivityWarningBytesPerMinute && !(admission.state === "blocked" && swapActivity >= LINUX_MEMORY_PRESSURE_DEFAULTS.swapActivityCriticalBytesPerMinute)) results.push(reason("host.linux.swap_activity.warning", "host", "warning", "Linux swap activity reached the warning band while memory was below reserve.", "swapActivityBytesPerMinute", swapActivity, LINUX_MEMORY_PRESSURE_DEFAULTS.swapActivityWarningBytesPerMinute));
|
|
22109
|
+
}
|
|
22110
|
+
return results;
|
|
22111
|
+
}
|
|
22112
|
+
function darwinPressureReasons(sample) {
|
|
22113
|
+
const freePercent = value(sample.memoryPressureFreePercent);
|
|
22114
|
+
if (freePercent == null) return [];
|
|
22115
|
+
if (freePercent <= DARWIN_MEMORY_PRESSURE_DEFAULTS.criticalFreePercent) return [reason("host.darwin.memory_pressure.critical", "host", "critical", "macOS memory pressure free percentage reached the critical band.", "memoryPressureFreePercent", freePercent, DARWIN_MEMORY_PRESSURE_DEFAULTS.criticalFreePercent)];
|
|
22116
|
+
if (freePercent <= DARWIN_MEMORY_PRESSURE_DEFAULTS.warningFreePercent) return [reason("host.darwin.memory_pressure.warning", "host", "warning", "macOS memory pressure free percentage reached the warning band.", "memoryPressureFreePercent", freePercent, DARWIN_MEMORY_PRESSURE_DEFAULTS.warningFreePercent)];
|
|
22117
|
+
return [];
|
|
22118
|
+
}
|
|
22119
|
+
function hasCurrentPressureSignal(sample) {
|
|
22120
|
+
if (sample.platform === "linux") return value(sample.memoryPressureSomeAvg10) != null || value(sample.memoryPressureFullAvg10) != null || value(sample.swapActivityBytesPerMinute) != null;
|
|
22121
|
+
if (sample.platform === "darwin") return value(sample.memoryPressureFreePercent) != null;
|
|
22122
|
+
return false;
|
|
22123
|
+
}
|
|
22124
|
+
function evaluateHostPressure(sample, thresholds) {
|
|
22125
|
+
const admission = evaluateAdmission(sample, thresholds);
|
|
22126
|
+
const diagnosticReasons = diagnostics(sample, thresholds);
|
|
22127
|
+
if (!hasCurrentPressureSignal(sample)) return {
|
|
22128
|
+
state: "unavailable",
|
|
22129
|
+
reasons: [{
|
|
22130
|
+
code: "host.current_pressure.unavailable",
|
|
22131
|
+
domain: "host",
|
|
22132
|
+
severity: "info",
|
|
22133
|
+
message: "The platform collector could not measure a current-pressure signal."
|
|
22134
|
+
}, ...diagnosticReasons],
|
|
22135
|
+
diagnostics: diagnosticReasons,
|
|
22136
|
+
admission
|
|
22137
|
+
};
|
|
22138
|
+
const pressureReasons = sample.platform === "linux" ? linuxPressureReasons(sample, admission) : darwinPressureReasons(sample);
|
|
22139
|
+
return {
|
|
22140
|
+
state: pressureReasons.some((entry) => entry.severity === "critical") ? "critical" : pressureReasons.some((entry) => entry.severity === "warning") ? "warning" : "healthy",
|
|
22141
|
+
reasons: [...pressureReasons, ...diagnosticReasons],
|
|
22142
|
+
diagnostics: diagnosticReasons,
|
|
22143
|
+
admission
|
|
22144
|
+
};
|
|
22145
|
+
}
|
|
22146
|
+
//#endregion
|
|
22147
|
+
//#region ../../lib/system-health/sampler.ts
|
|
22148
|
+
const DEFAULT_WARMUP_INTERVAL_MS = 1e3;
|
|
22149
|
+
const DEFAULT_WARMUP_SAMPLES = 3;
|
|
22150
|
+
const REQUIRED_CONSECUTIVE_SAMPLES = 3;
|
|
22151
|
+
function createMeasuringState(metrics, observedAt) {
|
|
22152
|
+
return {
|
|
22153
|
+
accepted: {
|
|
22154
|
+
state: "measuring",
|
|
22155
|
+
reasons: [{
|
|
22156
|
+
code: "host.sampler.measuring",
|
|
22157
|
+
domain: "host",
|
|
22158
|
+
severity: "info",
|
|
22159
|
+
message: "System health is collecting the initial three samples."
|
|
22160
|
+
}],
|
|
22161
|
+
metrics,
|
|
22162
|
+
sampledAt: observedAt,
|
|
22163
|
+
freshness: {
|
|
22164
|
+
status: "measuring",
|
|
22165
|
+
observedAt
|
|
22166
|
+
},
|
|
22167
|
+
transitionVersion: 0
|
|
22168
|
+
},
|
|
22169
|
+
candidate: null,
|
|
22170
|
+
candidateCount: 0
|
|
22171
|
+
};
|
|
22172
|
+
}
|
|
22173
|
+
function accept(previous, assessment) {
|
|
22174
|
+
const changed = previous.state !== assessment.state;
|
|
22175
|
+
const transitionVersion = changed ? previous.transitionVersion + 1 : previous.transitionVersion;
|
|
22176
|
+
return {
|
|
22177
|
+
state: {
|
|
22178
|
+
accepted: {
|
|
22179
|
+
...assessment,
|
|
22180
|
+
freshness: {
|
|
22181
|
+
status: "fresh",
|
|
22182
|
+
observedAt: assessment.sampledAt
|
|
22183
|
+
},
|
|
22184
|
+
transitionVersion
|
|
22185
|
+
},
|
|
22186
|
+
candidate: null,
|
|
22187
|
+
candidateCount: 0
|
|
22188
|
+
},
|
|
22189
|
+
transition: changed ? {
|
|
22190
|
+
version: transitionVersion,
|
|
22191
|
+
previousState: previous.state,
|
|
22192
|
+
state: assessment.state,
|
|
22193
|
+
reasonCodes: assessment.reasons.map((entry) => entry.code),
|
|
22194
|
+
acceptedAt: assessment.sampledAt
|
|
22195
|
+
} : null
|
|
22196
|
+
};
|
|
22197
|
+
}
|
|
22198
|
+
/**
|
|
22199
|
+
* Applies symmetric three-sample hysteresis to one atomic assessment. Metrics
|
|
22200
|
+
* and reasons move with their state only when that complete assessment is
|
|
22201
|
+
* accepted, so readers never observe a new state paired with old evidence.
|
|
22202
|
+
*/
|
|
22203
|
+
function transitionAcceptedAssessment(previous, raw) {
|
|
22204
|
+
if (raw.status === "invalid") return {
|
|
22205
|
+
state: {
|
|
22206
|
+
accepted: {
|
|
22207
|
+
...previous.accepted,
|
|
22208
|
+
freshness: {
|
|
22209
|
+
status: "stale",
|
|
22210
|
+
observedAt: raw.sampledAt,
|
|
22211
|
+
reason: raw.reason
|
|
22212
|
+
}
|
|
22213
|
+
},
|
|
22214
|
+
candidate: null,
|
|
22215
|
+
candidateCount: 0
|
|
22216
|
+
},
|
|
22217
|
+
transition: null
|
|
22218
|
+
};
|
|
22219
|
+
const assessment = raw.assessment;
|
|
22220
|
+
if (assessment.state === previous.accepted.state) return accept(previous.accepted, assessment);
|
|
22221
|
+
const candidateCount = previous.candidate?.state === assessment.state ? previous.candidateCount + 1 : 1;
|
|
22222
|
+
if (candidateCount >= REQUIRED_CONSECUTIVE_SAMPLES) return accept(previous.accepted, assessment);
|
|
22223
|
+
return {
|
|
22224
|
+
state: {
|
|
22225
|
+
accepted: previous.accepted,
|
|
22226
|
+
candidate: assessment,
|
|
22227
|
+
candidateCount
|
|
22228
|
+
},
|
|
22229
|
+
transition: null
|
|
22230
|
+
};
|
|
22231
|
+
}
|
|
22232
|
+
function resolveMeasuringMetrics(value) {
|
|
22233
|
+
return typeof value === "function" ? value() : value;
|
|
22234
|
+
}
|
|
22235
|
+
function createSystemHealthSampler(options) {
|
|
22236
|
+
const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
22237
|
+
const warmupIntervalMs = options.warmupIntervalMs ?? DEFAULT_WARMUP_INTERVAL_MS;
|
|
22238
|
+
const warmupSamples = options.warmupSamples ?? DEFAULT_WARMUP_SAMPLES;
|
|
22239
|
+
let state = createMeasuringState(resolveMeasuringMetrics(options.measuringMetrics), now());
|
|
22240
|
+
let timer = null;
|
|
22241
|
+
let started = false;
|
|
22242
|
+
let stopped = false;
|
|
22243
|
+
let samplesAttempted = 0;
|
|
22244
|
+
const schedule = () => {
|
|
22245
|
+
if (stopped) return;
|
|
22246
|
+
const delay = samplesAttempted < warmupSamples ? warmupIntervalMs : options.pollIntervalMs;
|
|
22247
|
+
timer = setTimeout(() => {
|
|
22248
|
+
collectOnce();
|
|
22249
|
+
}, delay);
|
|
22250
|
+
};
|
|
22251
|
+
const collectOnce = async () => {
|
|
22252
|
+
if (stopped) return;
|
|
22253
|
+
let raw;
|
|
22254
|
+
try {
|
|
22255
|
+
raw = await options.collect();
|
|
22256
|
+
} catch (error) {
|
|
22257
|
+
raw = {
|
|
22258
|
+
status: "invalid",
|
|
22259
|
+
sampledAt: now(),
|
|
22260
|
+
reason: {
|
|
22261
|
+
code: "host.sampler.collection_failed",
|
|
22262
|
+
domain: "host",
|
|
22263
|
+
severity: "info",
|
|
22264
|
+
message: error instanceof Error ? error.message : "System health collection failed."
|
|
22265
|
+
}
|
|
22266
|
+
};
|
|
22267
|
+
}
|
|
22268
|
+
samplesAttempted++;
|
|
22269
|
+
const result = transitionAcceptedAssessment(state, raw);
|
|
22270
|
+
state = result.state;
|
|
22271
|
+
if (result.transition && options.onTransition) try {
|
|
22272
|
+
await options.onTransition(result.transition);
|
|
22273
|
+
} catch (error) {
|
|
22274
|
+
console.error("[system-health] Failed to publish accepted transition:", error);
|
|
22275
|
+
}
|
|
22276
|
+
schedule();
|
|
22277
|
+
};
|
|
22278
|
+
const start = () => {
|
|
22279
|
+
if (started || stopped) return;
|
|
22280
|
+
started = true;
|
|
22281
|
+
collectOnce();
|
|
22282
|
+
};
|
|
22283
|
+
return {
|
|
22284
|
+
getSnapshot() {
|
|
22285
|
+
start();
|
|
22286
|
+
return state.accepted;
|
|
22287
|
+
},
|
|
22288
|
+
stop() {
|
|
22289
|
+
stopped = true;
|
|
22290
|
+
if (timer) clearTimeout(timer);
|
|
22291
|
+
timer = null;
|
|
22292
|
+
}
|
|
22293
|
+
};
|
|
22294
|
+
}
|
|
22295
|
+
//#endregion
|
|
22296
|
+
//#region services/system-health-v2.ts
|
|
21856
22297
|
init_event_store();
|
|
22298
|
+
init_staleness();
|
|
22299
|
+
function runtimeHealthState(runtime) {
|
|
22300
|
+
if (!runtime) return null;
|
|
22301
|
+
switch (runtime.activity) {
|
|
22302
|
+
case "working":
|
|
22303
|
+
case "thinking": return {
|
|
22304
|
+
state: "active",
|
|
22305
|
+
lastActivity: runtime.lastActivity,
|
|
22306
|
+
contextSaturatedAt: runtime.contextSaturatedAt
|
|
22307
|
+
};
|
|
22308
|
+
case "waiting": return {
|
|
22309
|
+
state: "waiting-on-human",
|
|
22310
|
+
lastActivity: runtime.lastActivity,
|
|
22311
|
+
contextSaturatedAt: runtime.contextSaturatedAt
|
|
22312
|
+
};
|
|
22313
|
+
case "idle": return {
|
|
22314
|
+
state: "idle",
|
|
22315
|
+
lastActivity: runtime.lastActivity,
|
|
22316
|
+
contextSaturatedAt: runtime.contextSaturatedAt
|
|
22317
|
+
};
|
|
22318
|
+
case "stopped": return {
|
|
22319
|
+
state: "stopped",
|
|
22320
|
+
lastActivity: runtime.lastActivity,
|
|
22321
|
+
contextSaturatedAt: runtime.contextSaturatedAt
|
|
22322
|
+
};
|
|
22323
|
+
}
|
|
22324
|
+
}
|
|
22325
|
+
function agentLifecycle(role, issueId, tmuxActive, statuses) {
|
|
22326
|
+
if (role !== "review" && role !== "test" && role !== "ship") return "unknown";
|
|
22327
|
+
return classifyAdvancingSessionLifecycle(role, statuses.get(issueId.toUpperCase()), tmuxActive);
|
|
22328
|
+
}
|
|
22329
|
+
function stateToLegacySeverity(state) {
|
|
22330
|
+
return state === "critical" ? "critical" : state === "warning" ? "warning" : "normal";
|
|
22331
|
+
}
|
|
22332
|
+
function signalValue(signal) {
|
|
22333
|
+
return signal.status === "available" ? signal.value : null;
|
|
22334
|
+
}
|
|
22335
|
+
function hostMetrics(sample) {
|
|
22336
|
+
return {
|
|
22337
|
+
cpuPercent: signalValue(sample.cpuPercent),
|
|
22338
|
+
loadAverage1m: signalValue(sample.loadAverage1m),
|
|
22339
|
+
loadPerCore1m: signalValue(sample.loadPerCore1m),
|
|
22340
|
+
totalMemoryBytes: signalValue(sample.totalMemoryBytes),
|
|
22341
|
+
usedMemoryBytes: signalValue(sample.usedMemoryBytes),
|
|
22342
|
+
availableMemoryBytes: signalValue(sample.availableMemoryBytes),
|
|
22343
|
+
memoryUsedPercent: signalValue(sample.memoryUsedPercent),
|
|
22344
|
+
memoryPressureSomeAvg10: signalValue(sample.memoryPressureSomeAvg10),
|
|
22345
|
+
memoryPressureFullAvg10: signalValue(sample.memoryPressureFullAvg10),
|
|
22346
|
+
memoryPressureFreePercent: signalValue(sample.memoryPressureFreePercent),
|
|
22347
|
+
swapTotalBytes: signalValue(sample.swapTotalBytes),
|
|
22348
|
+
swapUsedBytes: signalValue(sample.swapUsedBytes),
|
|
22349
|
+
swapUsedPercent: signalValue(sample.swapUsedPercent),
|
|
22350
|
+
swapActivityBytesPerMinute: signalValue(sample.swapActivityBytesPerMinute),
|
|
22351
|
+
committedMemoryBytes: signalValue(sample.committedMemoryBytes),
|
|
22352
|
+
commitLimitBytes: signalValue(sample.commitLimitBytes),
|
|
22353
|
+
virtualCommitmentPercent: signalValue(sample.virtualCommitmentPercent)
|
|
22354
|
+
};
|
|
22355
|
+
}
|
|
22356
|
+
function serviceHealth(smeeRelay) {
|
|
22357
|
+
if (smeeRelay.status === "running") return [{
|
|
22358
|
+
id: "smee-relay",
|
|
22359
|
+
label: "Webhook relay",
|
|
22360
|
+
required: false,
|
|
22361
|
+
status: "running",
|
|
22362
|
+
message: smeeRelay.message,
|
|
22363
|
+
reasons: []
|
|
22364
|
+
}];
|
|
22365
|
+
if (smeeRelay.status === "not_configured") return [{
|
|
22366
|
+
id: "smee-relay",
|
|
22367
|
+
label: "Webhook relay",
|
|
22368
|
+
required: false,
|
|
22369
|
+
status: "not_configured",
|
|
22370
|
+
message: smeeRelay.message,
|
|
22371
|
+
reasons: []
|
|
22372
|
+
}];
|
|
22373
|
+
const unavailable = smeeRelay.status === "unknown";
|
|
22374
|
+
return [{
|
|
22375
|
+
id: "smee-relay",
|
|
22376
|
+
label: "Webhook relay",
|
|
22377
|
+
required: false,
|
|
22378
|
+
status: unavailable ? "unavailable" : "stopped",
|
|
22379
|
+
message: smeeRelay.message,
|
|
22380
|
+
reasons: [{
|
|
22381
|
+
code: unavailable ? "service.smee_relay.unavailable" : "service.smee_relay.stopped",
|
|
22382
|
+
domain: "service",
|
|
22383
|
+
severity: unavailable ? "info" : "warning",
|
|
22384
|
+
message: smeeRelay.message
|
|
22385
|
+
}]
|
|
22386
|
+
}];
|
|
22387
|
+
}
|
|
22388
|
+
function overallHealthState(hostState, agents, services) {
|
|
22389
|
+
if (hostState === "critical" || agents.some((agent) => agent.status === "dead" || agent.status === "wedged")) return "critical";
|
|
22390
|
+
if (hostState === "warning" || agents.some((agent) => agent.status === "warning" || agent.status === "stalled") || services.some((service) => service.status === "degraded" || service.status === "stopped")) return "warning";
|
|
22391
|
+
if (hostState === "measuring") return "measuring";
|
|
22392
|
+
if (hostState === "unavailable" || agents.some((agent) => agent.status === "unavailable") || services.some((service) => service.status === "unavailable")) return "unavailable";
|
|
22393
|
+
return "healthy";
|
|
22394
|
+
}
|
|
22395
|
+
function acceptedReasons(state, hostReasons, agents, services) {
|
|
22396
|
+
const reasons = [
|
|
22397
|
+
...hostReasons,
|
|
22398
|
+
...agents.flatMap((agent) => agent.reasons),
|
|
22399
|
+
...services.flatMap((service) => service.reasons)
|
|
22400
|
+
];
|
|
22401
|
+
if (state === "measuring" && reasons.length === 0) return [{
|
|
22402
|
+
code: "host.sampler.measuring",
|
|
22403
|
+
domain: "host",
|
|
22404
|
+
severity: "info",
|
|
22405
|
+
message: "System health is collecting the initial three samples."
|
|
22406
|
+
}];
|
|
22407
|
+
return reasons;
|
|
22408
|
+
}
|
|
22409
|
+
//#endregion
|
|
22410
|
+
//#region services/system-health-service.ts
|
|
22411
|
+
init_review_status_source();
|
|
21857
22412
|
const execAsync$4 = promisify(exec);
|
|
21858
|
-
const DEFAULT_HEALTH_POLL_SECONDS = 15;
|
|
21859
|
-
const DEFAULT_RESOURCE_CONFIG = {
|
|
21860
|
-
memoryWarnGb: 4,
|
|
21861
|
-
memoryBlockGb: 2,
|
|
21862
|
-
agentWarnCount: 8,
|
|
21863
|
-
agentBlockCount: 10
|
|
21864
|
-
};
|
|
21865
22413
|
const KB = 1024;
|
|
21866
22414
|
const GIB$1 = 1024 ** 3;
|
|
21867
|
-
const GLOBAL_CONFIG_PATH = join(homedir$1(), ".overdeck", "config.yaml");
|
|
21868
22415
|
let dockerStatsCollector$1 = null;
|
|
21869
|
-
|
|
21870
|
-
let
|
|
21871
|
-
let
|
|
21872
|
-
let cacheExpiresAt = 0;
|
|
21873
|
-
let inflightRefresh = null;
|
|
21874
|
-
let previousSeverity = null;
|
|
21875
|
-
let candidateSeverity = null;
|
|
21876
|
-
let candidateCount = 0;
|
|
21877
|
-
const HYSTERESIS_POLLS = 3;
|
|
22416
|
+
const hostHealthCollector = createHostHealthCollector();
|
|
22417
|
+
let previousHostMetricSample;
|
|
22418
|
+
let systemHealthSampler = null;
|
|
21878
22419
|
let eventStorePromise = null;
|
|
21879
|
-
let
|
|
21880
|
-
let cachedPollSeconds = DEFAULT_HEALTH_POLL_SECONDS;
|
|
22420
|
+
let cachedSystemHealthConfig = null;
|
|
21881
22421
|
let resourceConfigLoadedAt = 0;
|
|
21882
22422
|
let resourceConfigInflight = null;
|
|
21883
22423
|
let cachedDeployStaleness = null;
|
|
@@ -21911,9 +22451,17 @@ function getDockerStatsCollector() {
|
|
|
21911
22451
|
function bytesToGb(bytes) {
|
|
21912
22452
|
return Math.round(bytes / GIB$1 * 100) / 100;
|
|
21913
22453
|
}
|
|
21914
|
-
|
|
21915
|
-
|
|
21916
|
-
return
|
|
22454
|
+
const AGENT_STARTUP_GRACE_MS = 300 * 1e3;
|
|
22455
|
+
function countAdmittedWorkAgents(agents, nowMs = Date.now()) {
|
|
22456
|
+
return agents.filter((agent) => {
|
|
22457
|
+
if (agent.role !== "work") return false;
|
|
22458
|
+
if (agent.status !== "running" && agent.status !== "starting") return false;
|
|
22459
|
+
if (agent.tmuxActive) return true;
|
|
22460
|
+
if (agent.status !== "starting" || !agent.startedAt) return false;
|
|
22461
|
+
const startedAtMs = Date.parse(agent.startedAt);
|
|
22462
|
+
const ageMs = nowMs - startedAtMs;
|
|
22463
|
+
return Number.isFinite(startedAtMs) && ageMs >= 0 && ageMs < AGENT_STARTUP_GRACE_MS;
|
|
22464
|
+
}).length;
|
|
21917
22465
|
}
|
|
21918
22466
|
function classifyAgentKind(agentId, role) {
|
|
21919
22467
|
if (agentId.startsWith("planning-")) return "planning";
|
|
@@ -21925,41 +22473,13 @@ function classifyAgentKind(agentId, role) {
|
|
|
21925
22473
|
if (agentId.endsWith("-agent")) return "specialist";
|
|
21926
22474
|
return "other";
|
|
21927
22475
|
}
|
|
21928
|
-
function resolveFiniteNumber(value, fallback) {
|
|
21929
|
-
if (value == null || value.trim() === "") return fallback;
|
|
21930
|
-
const parsed = Number(value);
|
|
21931
|
-
return Number.isFinite(parsed) ? parsed : fallback;
|
|
21932
|
-
}
|
|
21933
22476
|
async function readGlobalResourceConfig() {
|
|
21934
|
-
|
|
21935
|
-
try {
|
|
21936
|
-
await access(GLOBAL_CONFIG_PATH);
|
|
21937
|
-
const raw = await readFile(GLOBAL_CONFIG_PATH, "utf-8");
|
|
21938
|
-
const memoryWarnMatch = raw.match(/^\s*memory_warn_gb:\s*(\d+(?:\.\d+)?)\s*$/m);
|
|
21939
|
-
const memoryBlockMatch = raw.match(/^\s*memory_block_gb:\s*(\d+(?:\.\d+)?)\s*$/m);
|
|
21940
|
-
const agentWarnMatch = raw.match(/^\s*agent_warn_count:\s*(\d+(?:\.\d+)?)\s*$/m);
|
|
21941
|
-
const agentBlockMatch = raw.match(/^\s*agent_block_count:\s*(\d+(?:\.\d+)?)\s*$/m);
|
|
21942
|
-
const pollSecondsMatch = raw.match(/^\s*poll_seconds:\s*(\d+(?:\.\d+)?)\s*$/m);
|
|
21943
|
-
next = {
|
|
21944
|
-
memoryWarnGb: resolveFiniteNumber(memoryWarnMatch?.[1], DEFAULT_RESOURCE_CONFIG.memoryWarnGb),
|
|
21945
|
-
memoryBlockGb: resolveFiniteNumber(memoryBlockMatch?.[1], DEFAULT_RESOURCE_CONFIG.memoryBlockGb),
|
|
21946
|
-
agentWarnCount: Math.max(1, Math.floor(resolveFiniteNumber(agentWarnMatch?.[1], DEFAULT_RESOURCE_CONFIG.agentWarnCount))),
|
|
21947
|
-
agentBlockCount: Math.max(1, Math.floor(resolveFiniteNumber(agentBlockMatch?.[1], DEFAULT_RESOURCE_CONFIG.agentBlockCount)))
|
|
21948
|
-
};
|
|
21949
|
-
cachedPollSeconds = Math.max(1, Math.floor(resolveFiniteNumber(process.env["PAN_HEALTH_POLL_SECONDS"], resolveFiniteNumber(pollSecondsMatch?.[1], DEFAULT_HEALTH_POLL_SECONDS))));
|
|
21950
|
-
} catch {
|
|
21951
|
-
cachedPollSeconds = Math.max(1, Math.floor(resolveFiniteNumber(process.env["PAN_HEALTH_POLL_SECONDS"], DEFAULT_HEALTH_POLL_SECONDS)));
|
|
21952
|
-
}
|
|
21953
|
-
cachedResourceConfig = {
|
|
21954
|
-
memoryWarnGb: resolveFiniteNumber(process.env["PAN_MEMORY_WARN_GB"], next.memoryWarnGb),
|
|
21955
|
-
memoryBlockGb: resolveFiniteNumber(process.env["PAN_MEMORY_BLOCK_GB"], next.memoryBlockGb),
|
|
21956
|
-
agentWarnCount: Math.max(1, Math.floor(resolveFiniteNumber(process.env["PAN_AGENT_WARN_COUNT"], next.agentWarnCount))),
|
|
21957
|
-
agentBlockCount: Math.max(1, Math.floor(resolveFiniteNumber(process.env["PAN_AGENT_BLOCK_COUNT"], next.agentBlockCount)))
|
|
21958
|
-
};
|
|
22477
|
+
cachedSystemHealthConfig = resolveSystemHealthConfig();
|
|
21959
22478
|
resourceConfigLoadedAt = Date.now();
|
|
21960
22479
|
}
|
|
21961
22480
|
async function ensureResourceConfigLoaded() {
|
|
21962
|
-
const
|
|
22481
|
+
const pollSeconds = cachedSystemHealthConfig?.pollSeconds ?? SYSTEM_HEALTH_DEFAULTS.pollSeconds;
|
|
22482
|
+
const ttl = Math.max(5e3, pollSeconds * 1e3);
|
|
21963
22483
|
if (resourceConfigLoadedAt > 0 && Date.now() - resourceConfigLoadedAt < ttl) return;
|
|
21964
22484
|
if (!resourceConfigInflight) resourceConfigInflight = readGlobalResourceConfig().finally(() => {
|
|
21965
22485
|
resourceConfigInflight = null;
|
|
@@ -21967,23 +22487,8 @@ async function ensureResourceConfigLoaded() {
|
|
|
21967
22487
|
await resourceConfigInflight;
|
|
21968
22488
|
}
|
|
21969
22489
|
function getResourceConfig() {
|
|
21970
|
-
|
|
21971
|
-
|
|
21972
|
-
function getHealthPollTtlMs() {
|
|
21973
|
-
return Math.max(1, cachedPollSeconds) * 1e3;
|
|
21974
|
-
}
|
|
21975
|
-
function defaultThresholds() {
|
|
21976
|
-
const resources = getResourceConfig();
|
|
21977
|
-
return {
|
|
21978
|
-
memoryAvailableWarningBytes: resources.memoryWarnGb * GIB$1,
|
|
21979
|
-
memoryAvailableCriticalBytes: resources.memoryBlockGb * GIB$1,
|
|
21980
|
-
swapUsedWarningPercent: Number(process.env["PAN_HEALTH_SWAP_WARN_PERCENT"] ?? 20),
|
|
21981
|
-
swapUsedCriticalPercent: Number(process.env["PAN_HEALTH_SWAP_CRITICAL_PERCENT"] ?? 50),
|
|
21982
|
-
cpuLoadWarningPerCore: Number(process.env["PAN_HEALTH_LOAD_WARN_PER_CORE"] ?? 1),
|
|
21983
|
-
cpuLoadCriticalPerCore: Number(process.env["PAN_HEALTH_LOAD_CRITICAL_PER_CORE"] ?? 1.5),
|
|
21984
|
-
overcommitWarningPercent: Number(process.env["PAN_HEALTH_OVERCOMMIT_WARN_PERCENT"] ?? 150),
|
|
21985
|
-
overcommitCriticalPercent: Number(process.env["PAN_HEALTH_OVERCOMMIT_CRITICAL_PERCENT"] ?? 200)
|
|
21986
|
-
};
|
|
22490
|
+
cachedSystemHealthConfig ??= resolveSystemHealthConfig();
|
|
22491
|
+
return cachedSystemHealthConfig.resources;
|
|
21987
22492
|
}
|
|
21988
22493
|
async function readProcMemoryLinux() {
|
|
21989
22494
|
const content = await readFile("/proc/meminfo", "utf-8");
|
|
@@ -22049,119 +22554,13 @@ async function readProcMemoryDarwin() {
|
|
|
22049
22554
|
async function readProcMemory() {
|
|
22050
22555
|
return platform$1() === "darwin" ? readProcMemoryDarwin() : readProcMemoryLinux();
|
|
22051
22556
|
}
|
|
22052
|
-
|
|
22053
|
-
|
|
22054
|
-
|
|
22055
|
-
|
|
22056
|
-
|
|
22057
|
-
const content = await readFile("/proc/loadavg", "utf-8");
|
|
22058
|
-
const load = Number((content.trim().split(/\s+/)[0] ?? "0").trim());
|
|
22059
|
-
return Number.isFinite(load) ? load : 0;
|
|
22060
|
-
}
|
|
22061
|
-
async function readCpuPercent() {
|
|
22062
|
-
if (platform$1() === "darwin") {
|
|
22063
|
-
const coreCount = Math.max(cpus$1().length, 1);
|
|
22064
|
-
const load = loadavg$1()[0] ?? 0;
|
|
22065
|
-
return Math.round(Math.min(load / coreCount, 1) * 1e3) / 10;
|
|
22066
|
-
}
|
|
22067
|
-
const cpuLine = (await readFile("/proc/stat", "utf-8")).split("\n").find((line) => line.startsWith("cpu "));
|
|
22068
|
-
if (!cpuLine) return 0;
|
|
22069
|
-
const values = cpuLine.trim().split(/\s+/).slice(1).map((value) => Number(value));
|
|
22070
|
-
const current = {
|
|
22071
|
-
idle: (values[3] ?? 0) + (values[4] ?? 0),
|
|
22072
|
-
total: values.reduce((sum, value) => sum + value, 0)
|
|
22073
|
-
};
|
|
22074
|
-
const now = Date.now();
|
|
22075
|
-
if (!previousCpuSample || previousCpuSampleAt > 0 && now - previousCpuSampleAt > getHealthPollTtlMs() * 2) {
|
|
22076
|
-
previousCpuSample = current;
|
|
22077
|
-
previousCpuSampleAt = now;
|
|
22078
|
-
const coreCount = Math.max(cpus$1().length, 1);
|
|
22079
|
-
const fallback = Math.min(await readLoadAverage() / coreCount, 1) * 100;
|
|
22080
|
-
return Math.round(fallback * 10) / 10;
|
|
22081
|
-
}
|
|
22082
|
-
const totalDelta = current.total - previousCpuSample.total;
|
|
22083
|
-
const idleDelta = current.idle - previousCpuSample.idle;
|
|
22084
|
-
previousCpuSample = current;
|
|
22085
|
-
previousCpuSampleAt = now;
|
|
22086
|
-
if (totalDelta <= 0) return 0;
|
|
22087
|
-
return Math.round((totalDelta - idleDelta) / totalDelta * 1e3) / 10;
|
|
22088
|
-
}
|
|
22089
|
-
async function readProcessTable() {
|
|
22090
|
-
const { stdout } = await execAsync$4("ps -eo pid=,ppid=,rss=,args=", {
|
|
22091
|
-
encoding: "utf-8",
|
|
22092
|
-
timeout: 1e4
|
|
22093
|
-
});
|
|
22094
|
-
const rows = /* @__PURE__ */ new Map();
|
|
22095
|
-
for (const line of stdout.split("\n")) {
|
|
22096
|
-
const trimmed = line.trim();
|
|
22097
|
-
if (!trimmed) continue;
|
|
22098
|
-
const match = trimmed.match(/^(\d+)\s+(\d+)\s+(\d+)\s+(.+)$/);
|
|
22099
|
-
if (!match) continue;
|
|
22100
|
-
const pid = Number(match[1]);
|
|
22101
|
-
const ppid = Number(match[2]);
|
|
22102
|
-
const rssKb = Number(match[3]);
|
|
22103
|
-
const command = match[4] ?? "";
|
|
22104
|
-
if (!Number.isFinite(pid) || !Number.isFinite(ppid) || !Number.isFinite(rssKb)) continue;
|
|
22105
|
-
rows.set(pid, {
|
|
22106
|
-
pid,
|
|
22107
|
-
ppid,
|
|
22108
|
-
rssKb,
|
|
22109
|
-
command
|
|
22110
|
-
});
|
|
22111
|
-
}
|
|
22112
|
-
return rows;
|
|
22113
|
-
}
|
|
22114
|
-
function getDescendantPids(rootPid, processes) {
|
|
22115
|
-
const descendants = /* @__PURE__ */ new Set();
|
|
22116
|
-
const queue = [rootPid];
|
|
22117
|
-
while (queue.length > 0) {
|
|
22118
|
-
const pid = queue.shift();
|
|
22119
|
-
if (!pid || descendants.has(pid)) continue;
|
|
22120
|
-
descendants.add(pid);
|
|
22121
|
-
for (const process of processes.values()) if (process.ppid === pid && !descendants.has(process.pid)) queue.push(process.pid);
|
|
22122
|
-
}
|
|
22123
|
-
return descendants;
|
|
22124
|
-
}
|
|
22125
|
-
function sumProcessMemory(descendants, processes) {
|
|
22126
|
-
let totalRssKb = 0;
|
|
22127
|
-
for (const pid of descendants) totalRssKb += processes.get(pid)?.rssKb ?? 0;
|
|
22128
|
-
return totalRssKb * KB;
|
|
22129
|
-
}
|
|
22130
|
-
function buildLeakedSpecialists(snapshot, runningAgents) {
|
|
22131
|
-
if (!snapshot) return [];
|
|
22132
|
-
const activeWorkIssues = new Set(runningAgents.filter((agent) => agent.kind === "work" && agent.status !== "stopped" && agent.tmuxActive).map((agent) => agent.issueId.toUpperCase()));
|
|
22133
|
-
return snapshot.specialists.filter((specialist) => specialist.isRunning && !!specialist.currentIssue).filter((specialist) => !activeWorkIssues.has((specialist.currentIssue ?? "").toUpperCase())).map((specialist) => ({
|
|
22134
|
-
name: specialist.name ?? "",
|
|
22135
|
-
currentIssue: specialist.currentIssue ?? "",
|
|
22136
|
-
reason: `Specialist is active for ${specialist.currentIssue} but no running work agent exists for that issue.`
|
|
22557
|
+
function buildLeakedSpecialists(agents) {
|
|
22558
|
+
return agents.filter((agent) => agent.kind === "specialist" && agent.lifecycle === "orphaned").map((agent) => ({
|
|
22559
|
+
name: agent.id,
|
|
22560
|
+
currentIssue: agent.currentIssue ?? agent.issueId,
|
|
22561
|
+
reason: `Advancing session remains live after ${agent.issueId} merged.`
|
|
22137
22562
|
}));
|
|
22138
22563
|
}
|
|
22139
|
-
function evaluateSeverity(thresholds, data) {
|
|
22140
|
-
const criticalReasons = [];
|
|
22141
|
-
const warningReasons = [];
|
|
22142
|
-
if (data.availableMemoryBytes < thresholds.memoryAvailableCriticalBytes) criticalReasons.push(`Available RAM is low (${bytesToGb(data.availableMemoryBytes)} GB).`);
|
|
22143
|
-
else if (data.availableMemoryBytes < thresholds.memoryAvailableWarningBytes) warningReasons.push(`Available RAM is tight (${bytesToGb(data.availableMemoryBytes)} GB).`);
|
|
22144
|
-
if (data.swapUsedPercent >= thresholds.swapUsedCriticalPercent) criticalReasons.push(`Swap usage is high (${data.swapUsedPercent}%).`);
|
|
22145
|
-
else if (data.swapUsedPercent >= thresholds.swapUsedWarningPercent) warningReasons.push(`Swap usage is elevated (${data.swapUsedPercent}%).`);
|
|
22146
|
-
if (data.loadPerCore1m >= thresholds.cpuLoadCriticalPerCore) criticalReasons.push(`CPU load is high (${data.loadPerCore1m.toFixed(2)} per core).`);
|
|
22147
|
-
else if (data.loadPerCore1m >= thresholds.cpuLoadWarningPerCore) warningReasons.push(`CPU load is elevated (${data.loadPerCore1m.toFixed(2)} per core).`);
|
|
22148
|
-
if (data.overcommitPercent >= thresholds.overcommitCriticalPercent) criticalReasons.push(`Committed memory exceeds the safe limit (${data.overcommitPercent}%).`);
|
|
22149
|
-
else if (data.overcommitPercent >= thresholds.overcommitWarningPercent) warningReasons.push(`Committed memory is near the limit (${data.overcommitPercent}%).`);
|
|
22150
|
-
if (data.leakedSpecialistCount > 0) warningReasons.push(`${data.leakedSpecialistCount} leaked specialist session${data.leakedSpecialistCount === 1 ? "" : "s"} detected.`);
|
|
22151
|
-
if (data.smeeRelay.configured && !data.smeeRelay.running) warningReasons.push("smee-client webhook relay is configured but not running.");
|
|
22152
|
-
if (criticalReasons.length > 0) return {
|
|
22153
|
-
severity: "critical",
|
|
22154
|
-
reasons: criticalReasons.concat(warningReasons)
|
|
22155
|
-
};
|
|
22156
|
-
if (warningReasons.length > 0) return {
|
|
22157
|
-
severity: "warning",
|
|
22158
|
-
reasons: warningReasons
|
|
22159
|
-
};
|
|
22160
|
-
return {
|
|
22161
|
-
severity: "normal",
|
|
22162
|
-
reasons: []
|
|
22163
|
-
};
|
|
22164
|
-
}
|
|
22165
22564
|
function collectSmeeRelayHealth() {
|
|
22166
22565
|
try {
|
|
22167
22566
|
if (!isSmeeConfiguredSync()) return {
|
|
@@ -22190,32 +22589,74 @@ function collectSmeeRelayHealth() {
|
|
|
22190
22589
|
};
|
|
22191
22590
|
}
|
|
22192
22591
|
}
|
|
22592
|
+
function reviewStatusMap() {
|
|
22593
|
+
return new Map(Object.entries(readReviewStatusMap() ?? {}));
|
|
22594
|
+
}
|
|
22193
22595
|
async function collectAgentProcesses() {
|
|
22194
|
-
const
|
|
22195
|
-
const
|
|
22196
|
-
|
|
22197
|
-
|
|
22198
|
-
|
|
22199
|
-
|
|
22200
|
-
|
|
22201
|
-
|
|
22596
|
+
const registeredAgents = await Effect.runPromise(listRunningAgents());
|
|
22597
|
+
const nowMs = Date.now();
|
|
22598
|
+
const admittedWorkAgentCount = countAdmittedWorkAgents(registeredAgents, nowMs);
|
|
22599
|
+
const activeAgents = registeredAgents.filter((agent) => agent.status !== "stopped");
|
|
22600
|
+
const liveSessions = new Set(registeredAgents.filter((agent) => agent.tmuxActive).map((agent) => agent.id));
|
|
22601
|
+
const runtimeCensus = await getRuntimeCensus();
|
|
22602
|
+
const reviewStatuses = reviewStatusMap();
|
|
22603
|
+
const collected = await Promise.all(activeAgents.map(async (agent) => {
|
|
22604
|
+
const [runtimeState, runtimeSnapshot] = await Promise.all([Effect.runPromise(getAgentRuntimeState(agent.id)).catch(() => null), Effect.runPromise(getRuntimeSnapshot(agent.id)).catch(() => null)]);
|
|
22605
|
+
const memoryBytes = [...descendantPidsForSession(runtimeCensus, agent.id)].reduce((sum, pid) => sum + (runtimeCensus.processesByPid.get(pid)?.rssBytes ?? 0), 0);
|
|
22606
|
+
const lifecycle = agentLifecycle(agent.role, agent.issueId, agent.tmuxActive, reviewStatuses);
|
|
22202
22607
|
return {
|
|
22203
|
-
|
|
22204
|
-
|
|
22205
|
-
|
|
22206
|
-
|
|
22207
|
-
|
|
22208
|
-
|
|
22209
|
-
|
|
22210
|
-
|
|
22608
|
+
process: {
|
|
22609
|
+
id: agent.id,
|
|
22610
|
+
issueId: agent.issueId,
|
|
22611
|
+
role: agent.role,
|
|
22612
|
+
kind: classifyAgentKind(agent.id, agent.role),
|
|
22613
|
+
status: agent.status,
|
|
22614
|
+
lifecycle,
|
|
22615
|
+
tmuxActive: agent.tmuxActive,
|
|
22616
|
+
memoryBytes,
|
|
22617
|
+
memoryGb: bytesToGb(memoryBytes),
|
|
22618
|
+
currentIssue: runtimeState?.currentIssue
|
|
22619
|
+
},
|
|
22620
|
+
health: {
|
|
22621
|
+
...classifyAgentHealth({
|
|
22622
|
+
agentId: agent.id,
|
|
22623
|
+
persisted: {
|
|
22624
|
+
status: "available",
|
|
22625
|
+
value: {
|
|
22626
|
+
id: agent.id,
|
|
22627
|
+
issueId: agent.issueId,
|
|
22628
|
+
role: agent.role,
|
|
22629
|
+
status: agent.status,
|
|
22630
|
+
startedAt: agent.startedAt,
|
|
22631
|
+
lastActivity: agent.lastActivity,
|
|
22632
|
+
kickoffDelivered: agent.kickoffDelivered,
|
|
22633
|
+
paused: agent.paused,
|
|
22634
|
+
stoppedByUser: agent.stoppedByUser,
|
|
22635
|
+
stoppedByPause: agent.stoppedByPause,
|
|
22636
|
+
consecutiveFailures: agent.consecutiveFailures
|
|
22637
|
+
}
|
|
22638
|
+
},
|
|
22639
|
+
runtime: runtimeHealthState(runtimeSnapshot),
|
|
22640
|
+
liveSessions,
|
|
22641
|
+
reviewLifecycle: lifecycle,
|
|
22642
|
+
nowMs
|
|
22643
|
+
}),
|
|
22644
|
+
memoryBytes,
|
|
22645
|
+
memoryGb: bytesToGb(memoryBytes),
|
|
22646
|
+
...runtimeState?.currentIssue ? { currentIssue: runtimeState.currentIssue } : {}
|
|
22647
|
+
}
|
|
22211
22648
|
};
|
|
22212
22649
|
}));
|
|
22650
|
+
return {
|
|
22651
|
+
agents: collected.map((entry) => entry.process),
|
|
22652
|
+
healthAgents: collected.map((entry) => entry.health),
|
|
22653
|
+
admittedWorkAgentCount
|
|
22654
|
+
};
|
|
22213
22655
|
}
|
|
22214
|
-
function buildTopConsumers(agents, containers
|
|
22215
|
-
const leakedByName = new Map(leakedSpecialists.map((item) => [item.name, item]));
|
|
22656
|
+
function buildTopConsumers(agents, containers) {
|
|
22216
22657
|
const agentConsumers = agents.map((agent) => {
|
|
22217
22658
|
const isSpecialist = agent.kind === "specialist";
|
|
22218
|
-
const leaked =
|
|
22659
|
+
const leaked = agent.lifecycle === "orphaned";
|
|
22219
22660
|
const currentIssue = agent.currentIssue ?? agent.issueId;
|
|
22220
22661
|
const resolved = currentIssue ? resolveProjectFromIssueSync(currentIssue) : null;
|
|
22221
22662
|
const specialistType = isSpecialist ? agent.id.startsWith("specialist-") ? agent.id.replace(/^specialist-/, "") : agent.id : void 0;
|
|
@@ -22251,122 +22692,215 @@ function buildTopConsumers(agents, containers, leakedSpecialists) {
|
|
|
22251
22692
|
containerId: container.id
|
|
22252
22693
|
}
|
|
22253
22694
|
}));
|
|
22254
|
-
return [...agentConsumers, ...containerConsumers].sort((a, b) => b.memoryBytes - a.memoryBytes)
|
|
22695
|
+
return [...agentConsumers, ...containerConsumers].sort((a, b) => b.memoryBytes - a.memoryBytes);
|
|
22696
|
+
}
|
|
22697
|
+
function createMeasuringSnapshot() {
|
|
22698
|
+
cachedSystemHealthConfig ??= resolveSystemHealthConfig();
|
|
22699
|
+
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
22700
|
+
const smeeRelay = collectSmeeRelayHealth();
|
|
22701
|
+
const services = serviceHealth(smeeRelay);
|
|
22702
|
+
const base = {
|
|
22703
|
+
version: 2,
|
|
22704
|
+
state: "measuring",
|
|
22705
|
+
updatedAt,
|
|
22706
|
+
nextPollMs: cachedSystemHealthConfig.pollSeconds * 1e3,
|
|
22707
|
+
host: {
|
|
22708
|
+
state: "measuring",
|
|
22709
|
+
platform: hostHealthCollector.platform,
|
|
22710
|
+
reasons: [{
|
|
22711
|
+
code: "host.sampler.measuring",
|
|
22712
|
+
domain: "host",
|
|
22713
|
+
severity: "info",
|
|
22714
|
+
message: "System health is collecting the initial three samples."
|
|
22715
|
+
}],
|
|
22716
|
+
metrics: {
|
|
22717
|
+
cpuPercent: null,
|
|
22718
|
+
loadAverage1m: null,
|
|
22719
|
+
loadPerCore1m: null,
|
|
22720
|
+
totalMemoryBytes: null,
|
|
22721
|
+
usedMemoryBytes: null,
|
|
22722
|
+
availableMemoryBytes: null,
|
|
22723
|
+
memoryUsedPercent: null,
|
|
22724
|
+
memoryPressureSomeAvg10: null,
|
|
22725
|
+
memoryPressureFullAvg10: null,
|
|
22726
|
+
memoryPressureFreePercent: null,
|
|
22727
|
+
swapTotalBytes: null,
|
|
22728
|
+
swapUsedBytes: null,
|
|
22729
|
+
swapUsedPercent: null,
|
|
22730
|
+
swapActivityBytesPerMinute: null,
|
|
22731
|
+
committedMemoryBytes: null,
|
|
22732
|
+
commitLimitBytes: null,
|
|
22733
|
+
virtualCommitmentPercent: null
|
|
22734
|
+
}
|
|
22735
|
+
},
|
|
22736
|
+
admission: {
|
|
22737
|
+
state: "unavailable",
|
|
22738
|
+
availableMemoryBytes: null,
|
|
22739
|
+
admittedWorkAgentCount: 0,
|
|
22740
|
+
reasons: [{
|
|
22741
|
+
code: "admission.sampler.measuring",
|
|
22742
|
+
domain: "admission",
|
|
22743
|
+
severity: "info",
|
|
22744
|
+
message: "Admission capacity is unavailable until the initial health sample is accepted."
|
|
22745
|
+
}]
|
|
22746
|
+
},
|
|
22747
|
+
agents: [],
|
|
22748
|
+
services,
|
|
22749
|
+
topConsumers: []
|
|
22750
|
+
};
|
|
22751
|
+
const accepted = {
|
|
22752
|
+
...base,
|
|
22753
|
+
summary: projectLegacySystemHealthSummary(base)
|
|
22754
|
+
};
|
|
22755
|
+
return {
|
|
22756
|
+
accepted,
|
|
22757
|
+
compatibility: {
|
|
22758
|
+
severity: "normal",
|
|
22759
|
+
updatedAt,
|
|
22760
|
+
admission: { admittedWorkAgentCount: 0 },
|
|
22761
|
+
summary: accepted.summary,
|
|
22762
|
+
thresholds: cachedSystemHealthConfig.thresholds,
|
|
22763
|
+
reasons: accepted.host.reasons.map((reason) => reason.message),
|
|
22764
|
+
agents: [],
|
|
22765
|
+
leakedSpecialists: [],
|
|
22766
|
+
topConsumers: [],
|
|
22767
|
+
smeeRelay,
|
|
22768
|
+
deployStaleness: null
|
|
22769
|
+
}
|
|
22770
|
+
};
|
|
22255
22771
|
}
|
|
22256
|
-
async function
|
|
22772
|
+
async function collectSystemHealth() {
|
|
22257
22773
|
await ensureResourceConfigLoaded();
|
|
22258
|
-
const [
|
|
22259
|
-
|
|
22260
|
-
readLoadAverage(),
|
|
22261
|
-
readCpuPercent(),
|
|
22774
|
+
const [sample, agentProcesses, containers, deployStaleness] = await Promise.all([
|
|
22775
|
+
hostHealthCollector.sample(previousHostMetricSample),
|
|
22262
22776
|
collectAgentProcesses(),
|
|
22263
|
-
Promise.resolve(getDockerStatsCollector().getStats())
|
|
22777
|
+
Promise.resolve(getDockerStatsCollector().getStats()),
|
|
22778
|
+
getDeployStaleness()
|
|
22264
22779
|
]);
|
|
22265
|
-
|
|
22780
|
+
previousHostMetricSample = sample;
|
|
22781
|
+
const config = cachedSystemHealthConfig;
|
|
22782
|
+
const host = evaluateHostPressure(sample, config.thresholds);
|
|
22266
22783
|
const smeeRelay = collectSmeeRelayHealth();
|
|
22267
|
-
const
|
|
22268
|
-
const
|
|
22269
|
-
const
|
|
22270
|
-
const
|
|
22271
|
-
const
|
|
22272
|
-
const
|
|
22273
|
-
|
|
22274
|
-
|
|
22275
|
-
|
|
22276
|
-
|
|
22277
|
-
|
|
22278
|
-
|
|
22279
|
-
|
|
22280
|
-
|
|
22281
|
-
|
|
22282
|
-
|
|
22283
|
-
|
|
22284
|
-
|
|
22285
|
-
|
|
22286
|
-
const overdeckMemoryBytes = agents.reduce((sum, agent) => sum + agent.memoryBytes, 0) + containerMemoryBytes;
|
|
22287
|
-
const overdeckMemoryPercent = toPercent(overdeckMemoryBytes, memory.memTotal);
|
|
22288
|
-
const sortedAgents = [...agents].sort((a, b) => b.memoryBytes - a.memoryBytes);
|
|
22289
|
-
const deployStaleness = await getDeployStaleness();
|
|
22290
|
-
let effectiveSeverity;
|
|
22291
|
-
if (previousSeverity == null) effectiveSeverity = evaluation.severity;
|
|
22292
|
-
else if (evaluation.severity === previousSeverity) {
|
|
22293
|
-
candidateSeverity = null;
|
|
22294
|
-
candidateCount = 0;
|
|
22295
|
-
effectiveSeverity = previousSeverity;
|
|
22296
|
-
} else if (evaluation.severity === candidateSeverity) {
|
|
22297
|
-
candidateCount++;
|
|
22298
|
-
effectiveSeverity = candidateCount >= HYSTERESIS_POLLS ? evaluation.severity : previousSeverity;
|
|
22299
|
-
if (effectiveSeverity !== previousSeverity) {
|
|
22300
|
-
candidateSeverity = null;
|
|
22301
|
-
candidateCount = 0;
|
|
22302
|
-
}
|
|
22303
|
-
} else {
|
|
22304
|
-
candidateSeverity = evaluation.severity;
|
|
22305
|
-
candidateCount = 1;
|
|
22306
|
-
effectiveSeverity = previousSeverity;
|
|
22307
|
-
}
|
|
22308
|
-
const result = {
|
|
22309
|
-
severity: effectiveSeverity,
|
|
22310
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22311
|
-
summary: {
|
|
22312
|
-
cpuPercent,
|
|
22313
|
-
loadAverage1m,
|
|
22314
|
-
loadPerCore1m,
|
|
22315
|
-
totalMemoryBytes: memory.memTotal,
|
|
22316
|
-
usedMemoryBytes,
|
|
22317
|
-
availableMemoryBytes: memory.memAvailable,
|
|
22318
|
-
memoryUsedPercent: toPercent(usedMemoryBytes, memory.memTotal),
|
|
22319
|
-
swapTotalBytes: memory.swapTotal,
|
|
22320
|
-
swapUsedBytes,
|
|
22321
|
-
swapUsedPercent,
|
|
22322
|
-
overcommitPercent,
|
|
22323
|
-
agentCount: agents.length,
|
|
22324
|
-
workAgentCount,
|
|
22325
|
-
planningAgentCount,
|
|
22326
|
-
specialistSessionCount,
|
|
22327
|
-
leakedSpecialistCount: leakedSpecialists.length,
|
|
22328
|
-
containerCount: containers.length,
|
|
22329
|
-
containerMemoryBytes,
|
|
22330
|
-
overdeckMemoryBytes,
|
|
22331
|
-
overdeckMemoryPercent
|
|
22784
|
+
const services = serviceHealth(smeeRelay);
|
|
22785
|
+
const consumers = buildTopConsumers(agentProcesses.agents, containers);
|
|
22786
|
+
const state = overallHealthState(host.state, agentProcesses.healthAgents, services);
|
|
22787
|
+
const reasons = acceptedReasons(state, host.reasons, agentProcesses.healthAgents, services);
|
|
22788
|
+
const updatedAt = new Date(sample.sampledAtMs).toISOString();
|
|
22789
|
+
const base = {
|
|
22790
|
+
version: 2,
|
|
22791
|
+
state,
|
|
22792
|
+
updatedAt,
|
|
22793
|
+
nextPollMs: config.pollSeconds * 1e3,
|
|
22794
|
+
host: {
|
|
22795
|
+
state: host.state,
|
|
22796
|
+
platform: sample.platform,
|
|
22797
|
+
reasons: host.reasons,
|
|
22798
|
+
metrics: hostMetrics(sample)
|
|
22799
|
+
},
|
|
22800
|
+
admission: {
|
|
22801
|
+
...host.admission,
|
|
22802
|
+
admittedWorkAgentCount: agentProcesses.admittedWorkAgentCount
|
|
22332
22803
|
},
|
|
22333
|
-
|
|
22334
|
-
|
|
22335
|
-
|
|
22336
|
-
|
|
22337
|
-
|
|
22338
|
-
|
|
22339
|
-
|
|
22340
|
-
};
|
|
22341
|
-
|
|
22804
|
+
agents: agentProcesses.healthAgents,
|
|
22805
|
+
services,
|
|
22806
|
+
topConsumers: consumers
|
|
22807
|
+
};
|
|
22808
|
+
const accepted = {
|
|
22809
|
+
...base,
|
|
22810
|
+
summary: projectLegacySystemHealthSummary(base)
|
|
22811
|
+
};
|
|
22812
|
+
const sortedAgents = [...agentProcesses.agents].sort((left, right) => right.memoryBytes - left.memoryBytes);
|
|
22813
|
+
const leakedSpecialists = buildLeakedSpecialists(sortedAgents);
|
|
22814
|
+
return {
|
|
22815
|
+
accepted,
|
|
22816
|
+
compatibility: {
|
|
22817
|
+
severity: stateToLegacySeverity(state),
|
|
22818
|
+
updatedAt,
|
|
22819
|
+
admission: { admittedWorkAgentCount: agentProcesses.admittedWorkAgentCount },
|
|
22820
|
+
summary: accepted.summary,
|
|
22821
|
+
thresholds: config.thresholds,
|
|
22822
|
+
reasons: reasons.map((reason) => reason.message),
|
|
22823
|
+
agents: sortedAgents,
|
|
22824
|
+
leakedSpecialists,
|
|
22825
|
+
topConsumers: consumers.slice(0, 10),
|
|
22826
|
+
smeeRelay,
|
|
22827
|
+
deployStaleness
|
|
22828
|
+
}
|
|
22829
|
+
};
|
|
22830
|
+
}
|
|
22831
|
+
async function collectRawSystemHealth() {
|
|
22832
|
+
const bundle = await collectSystemHealth();
|
|
22833
|
+
const reasons = acceptedReasons(bundle.accepted.state, bundle.accepted.host.reasons, bundle.accepted.agents, bundle.accepted.services);
|
|
22834
|
+
return {
|
|
22835
|
+
status: "valid",
|
|
22836
|
+
assessment: {
|
|
22837
|
+
state: bundle.accepted.state,
|
|
22838
|
+
reasons,
|
|
22839
|
+
metrics: bundle,
|
|
22840
|
+
sampledAt: bundle.accepted.updatedAt
|
|
22841
|
+
}
|
|
22842
|
+
};
|
|
22843
|
+
}
|
|
22844
|
+
function buildSystemHealthTransitionPayload(transition, leakedSpecialistCount) {
|
|
22845
|
+
return {
|
|
22846
|
+
version: 2,
|
|
22847
|
+
transitionVersion: transition.version,
|
|
22848
|
+
previousSeverity: stateToLegacySeverity(transition.previousState),
|
|
22849
|
+
severity: stateToLegacySeverity(transition.state),
|
|
22850
|
+
previousState: transition.previousState,
|
|
22851
|
+
state: transition.state,
|
|
22852
|
+
reasons: transition.reasonCodes,
|
|
22853
|
+
reasonCodes: transition.reasonCodes,
|
|
22854
|
+
acceptedAt: transition.acceptedAt,
|
|
22855
|
+
leakedSpecialistCount
|
|
22856
|
+
};
|
|
22857
|
+
}
|
|
22858
|
+
async function publishSystemHealthTransition(transition) {
|
|
22859
|
+
const accepted = systemHealthSampler?.getSnapshot();
|
|
22860
|
+
try {
|
|
22342
22861
|
await (await (eventStorePromise ??= initEventStore())).appendAsync({
|
|
22343
22862
|
type: "system.health_severity_changed",
|
|
22344
|
-
timestamp:
|
|
22345
|
-
payload:
|
|
22346
|
-
previousSeverity,
|
|
22347
|
-
severity: result.severity,
|
|
22348
|
-
reasons: result.reasons,
|
|
22349
|
-
leakedSpecialistCount: leakedSpecialists.length
|
|
22350
|
-
}
|
|
22863
|
+
timestamp: transition.acceptedAt,
|
|
22864
|
+
payload: buildSystemHealthTransitionPayload(transition, accepted?.metrics.accepted.summary.leakedSpecialistCount ?? 0)
|
|
22351
22865
|
});
|
|
22352
22866
|
} catch (err) {
|
|
22353
|
-
console.error("[system-health] Failed to append
|
|
22867
|
+
console.error("[system-health] Failed to append accepted transition event:", err);
|
|
22354
22868
|
}
|
|
22355
|
-
previousSeverity = result.severity;
|
|
22356
|
-
cachedHealth = result;
|
|
22357
|
-
cacheExpiresAt = Date.now() + getHealthPollTtlMs();
|
|
22358
|
-
return result;
|
|
22359
22869
|
}
|
|
22360
|
-
|
|
22361
|
-
if (
|
|
22362
|
-
|
|
22363
|
-
|
|
22364
|
-
|
|
22365
|
-
|
|
22870
|
+
function getSystemHealthSampler() {
|
|
22871
|
+
if (!systemHealthSampler) {
|
|
22872
|
+
const config = cachedSystemHealthConfig ?? resolveSystemHealthConfig();
|
|
22873
|
+
cachedSystemHealthConfig = config;
|
|
22874
|
+
systemHealthSampler = createSystemHealthSampler({
|
|
22875
|
+
collect: collectRawSystemHealth,
|
|
22876
|
+
measuringMetrics: createMeasuringSnapshot,
|
|
22877
|
+
pollIntervalMs: config.pollSeconds * 1e3,
|
|
22878
|
+
onTransition: publishSystemHealthTransition
|
|
22879
|
+
});
|
|
22880
|
+
}
|
|
22881
|
+
return systemHealthSampler;
|
|
22882
|
+
}
|
|
22883
|
+
async function getSystemHealthEvidenceSnapshot() {
|
|
22884
|
+
const assessment = getSystemHealthSampler().getSnapshot();
|
|
22885
|
+
return {
|
|
22886
|
+
accepted: assessment.metrics.accepted,
|
|
22887
|
+
compatibility: {
|
|
22888
|
+
...assessment.metrics.compatibility,
|
|
22889
|
+
state: assessment.state,
|
|
22890
|
+
structuredReasons: assessment.reasons,
|
|
22891
|
+
freshness: assessment.freshness,
|
|
22892
|
+
transitionVersion: assessment.transitionVersion
|
|
22893
|
+
}
|
|
22894
|
+
};
|
|
22895
|
+
}
|
|
22896
|
+
async function getAcceptedSystemHealthSnapshot() {
|
|
22897
|
+
return (await getSystemHealthEvidenceSnapshot()).accepted;
|
|
22898
|
+
}
|
|
22899
|
+
async function getSystemHealthSnapshot() {
|
|
22900
|
+
return (await getSystemHealthEvidenceSnapshot()).compatibility;
|
|
22366
22901
|
}
|
|
22367
22902
|
//#endregion
|
|
22368
22903
|
//#region routes/resources/shared.ts
|
|
22369
|
-
init_load();
|
|
22370
22904
|
init_docker_stats();
|
|
22371
22905
|
function getCurrentDockerStats() {
|
|
22372
22906
|
return [];
|
|
@@ -22467,6 +23001,7 @@ function roundOne(value) {
|
|
|
22467
23001
|
}
|
|
22468
23002
|
//#endregion
|
|
22469
23003
|
//#region ../../lib/cloister/memory-governor.ts
|
|
23004
|
+
init_load();
|
|
22470
23005
|
init_projects();
|
|
22471
23006
|
promisify(execFile);
|
|
22472
23007
|
const GIB = 1024 ** 3;
|
|
@@ -22535,9 +23070,18 @@ async function assessMemoryPressure() {
|
|
|
22535
23070
|
return verdict;
|
|
22536
23071
|
}
|
|
22537
23072
|
//#endregion
|
|
23073
|
+
//#region ../../lib/cloister/agent-grace.ts
|
|
23074
|
+
init_tracker_utils();
|
|
23075
|
+
init_concurrency$1();
|
|
23076
|
+
const WORK_LAUNCHER_GRACE_MS = 12e4;
|
|
23077
|
+
function isStartingWithinGrace(state, now = Date.now(), graceMs = WORK_LAUNCHER_GRACE_MS) {
|
|
23078
|
+
if (state.status !== "starting") return false;
|
|
23079
|
+
const startedMs = Date.parse(state.startedAt ?? "");
|
|
23080
|
+
return Number.isFinite(startedMs) && now - startedMs < graceMs;
|
|
23081
|
+
}
|
|
23082
|
+
//#endregion
|
|
22538
23083
|
//#region ../../lib/cloister/deacon-inspect.ts
|
|
22539
23084
|
init_review_status();
|
|
22540
|
-
init_tmux();
|
|
22541
23085
|
/**
|
|
22542
23086
|
* Inspect prompts state a 10-minute budget. Deacon gives the agent a small
|
|
22543
23087
|
* grace window beyond that, then fails loud so the parent work agent never waits
|
|
@@ -22578,7 +23122,7 @@ async function checkInspectAgentTimeouts(now = /* @__PURE__ */ new Date()) {
|
|
|
22578
23122
|
console.warn(`[deacon] Failed to kill inspect session ${sessionName}: ${msg}`);
|
|
22579
23123
|
});
|
|
22580
23124
|
try {
|
|
22581
|
-
const { messageAgent } = await import("./agents-
|
|
23125
|
+
const { messageAgent } = await import("./agents-FlIgQ3ql.js");
|
|
22582
23126
|
await messageAgent(`agent-${issueId.toLowerCase()}`, verdict, "deacon:inspect-watchdog");
|
|
22583
23127
|
} catch (err) {
|
|
22584
23128
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -22631,8 +23175,50 @@ async function handleKnownAgentModal(agentId, deps = defaultDeps$1, initialPane)
|
|
|
22631
23175
|
await deps.settle();
|
|
22632
23176
|
return modal.matches(await deps.capturePane(agentId)) ? "needs-you" : "handled";
|
|
22633
23177
|
}
|
|
23178
|
+
const ORCHESTRATED_COMPACTION_CONTINUE_MESSAGE = "Compaction complete. Continue from the compacted summary now. Re-read your current xBRIEF item and latest feedback file if needed, then resume work; do not wait for further input.";
|
|
23179
|
+
const orchestratedCompactionContinuations = /* @__PURE__ */ new Map();
|
|
23180
|
+
function scheduleOrchestratedCompactionContinuation(sessionName, requestedAt = Date.now()) {
|
|
23181
|
+
orchestratedCompactionContinuations.set(sessionName, {
|
|
23182
|
+
requestedAt,
|
|
23183
|
+
observedBusy: false
|
|
23184
|
+
});
|
|
23185
|
+
}
|
|
23186
|
+
function cancelOrchestratedCompactionContinuation(sessionName) {
|
|
23187
|
+
orchestratedCompactionContinuations.delete(sessionName);
|
|
23188
|
+
}
|
|
23189
|
+
function hasOrchestratedCompactionContinuation(sessionName) {
|
|
23190
|
+
return orchestratedCompactionContinuations.has(sessionName);
|
|
23191
|
+
}
|
|
23192
|
+
async function deliverOrchestratedCompact(sessionName, deliver) {
|
|
23193
|
+
scheduleOrchestratedCompactionContinuation(sessionName);
|
|
23194
|
+
try {
|
|
23195
|
+
await deliver();
|
|
23196
|
+
} catch (error) {
|
|
23197
|
+
cancelOrchestratedCompactionContinuation(sessionName);
|
|
23198
|
+
throw error;
|
|
23199
|
+
}
|
|
23200
|
+
}
|
|
23201
|
+
async function maybeContinueOrchestratedCompaction(args) {
|
|
23202
|
+
const pending = orchestratedCompactionContinuations.get(args.sessionName);
|
|
23203
|
+
if (!pending) return false;
|
|
23204
|
+
const elapsed = (args.now ?? Date.now()) - pending.requestedAt;
|
|
23205
|
+
if (!args.tmuxOutput.includes("❯")) {
|
|
23206
|
+
pending.observedBusy = true;
|
|
23207
|
+
if (elapsed >= 15e4) orchestratedCompactionContinuations.delete(args.sessionName);
|
|
23208
|
+
return false;
|
|
23209
|
+
}
|
|
23210
|
+
if (isContextOverflowTail(args.tmuxOutput)) {
|
|
23211
|
+
if (elapsed >= 15e4) orchestratedCompactionContinuations.delete(args.sessionName);
|
|
23212
|
+
return false;
|
|
23213
|
+
}
|
|
23214
|
+
if (!pending.observedBusy && elapsed < 3e4) return false;
|
|
23215
|
+
await args.send(args.sessionName, ORCHESTRATED_COMPACTION_CONTINUE_MESSAGE);
|
|
23216
|
+
orchestratedCompactionContinuations.delete(args.sessionName);
|
|
23217
|
+
return true;
|
|
23218
|
+
}
|
|
22634
23219
|
//#endregion
|
|
22635
23220
|
//#region ../../lib/cloister/deacon-api-recovery.ts
|
|
23221
|
+
init_context_overflow();
|
|
22636
23222
|
init_agents$1();
|
|
22637
23223
|
init_review_status();
|
|
22638
23224
|
init_tmux();
|
|
@@ -22730,13 +23316,13 @@ async function maybeProactivelyCompactContext(sessionName, now) {
|
|
|
22730
23316
|
if (!agentState?.workspace || !sessionId || !agentState.model) return null;
|
|
22731
23317
|
let usage = null;
|
|
22732
23318
|
try {
|
|
22733
|
-
const { computeContextUsage } = await import("./conversation-service-
|
|
23319
|
+
const { computeContextUsage } = await import("./conversation-service-Up7FEzIC.js");
|
|
22734
23320
|
usage = await computeContextUsage(sessionFilePath(agentState.workspace, sessionId), agentState.model);
|
|
22735
23321
|
} catch {
|
|
22736
23322
|
return null;
|
|
22737
23323
|
}
|
|
22738
23324
|
if (!usage || usage.percentUsed < 85) return null;
|
|
22739
|
-
await Effect.runPromise(sendKeys(sessionName, "/compact"));
|
|
23325
|
+
await deliverOrchestratedCompact(sessionName, () => Effect.runPromise(sendKeys(sessionName, "/compact")));
|
|
22740
23326
|
contextProactiveCompactState.set(sessionName, { lastAttempt: now });
|
|
22741
23327
|
try {
|
|
22742
23328
|
await writeFile$1(join$1(getAgentDir(sessionName), PROACTIVE_COMPACT_STAMP_FILE), new Date(now).toISOString(), "utf-8");
|
|
@@ -22766,10 +23352,11 @@ async function checkApiErrorAgents() {
|
|
|
22766
23352
|
} catch {
|
|
22767
23353
|
return actions;
|
|
22768
23354
|
}
|
|
22769
|
-
const
|
|
22770
|
-
for (const sessionName of
|
|
23355
|
+
const sessionsToInspect = sessionNames.filter((name) => name.startsWith("agent-") || name.startsWith("specialist-") || name.startsWith("planning-")).filter((name) => !/^agent-.*-review-(?:security|correctness|performance|requirements)$/.test(name) || hasOrchestratedCompactionContinuation(name));
|
|
23356
|
+
for (const sessionName of sessionsToInspect) {
|
|
23357
|
+
const compactionPendingAtStart = hasOrchestratedCompactionContinuation(sessionName);
|
|
22771
23358
|
const recovery = apiErrorRecoveryState.get(sessionName);
|
|
22772
|
-
if (recovery && now - recovery.lastAttempt < API_ERROR_RECOVERY_COOLDOWN_MS) continue;
|
|
23359
|
+
if (!compactionPendingAtStart && recovery && now - recovery.lastAttempt < API_ERROR_RECOVERY_COOLDOWN_MS) continue;
|
|
22773
23360
|
let tmuxOutput;
|
|
22774
23361
|
try {
|
|
22775
23362
|
tmuxOutput = await Effect.runPromise(capturePane(sessionName, 100));
|
|
@@ -22809,6 +23396,23 @@ async function checkApiErrorAgents() {
|
|
|
22809
23396
|
continue;
|
|
22810
23397
|
}
|
|
22811
23398
|
}
|
|
23399
|
+
if (compactionPendingAtStart || hasOrchestratedCompactionContinuation(sessionName)) {
|
|
23400
|
+
try {
|
|
23401
|
+
if (await maybeContinueOrchestratedCompaction({
|
|
23402
|
+
sessionName,
|
|
23403
|
+
tmuxOutput,
|
|
23404
|
+
now,
|
|
23405
|
+
send: (target, message) => Effect.runPromise(sendKeys(target, message))
|
|
23406
|
+
})) {
|
|
23407
|
+
contextOverflowRecoveryState.delete(sessionName);
|
|
23408
|
+
actions.push(`Context compaction recovery: resumed ${sessionName} after compaction`);
|
|
23409
|
+
continue;
|
|
23410
|
+
}
|
|
23411
|
+
} catch (err) {
|
|
23412
|
+
console.error(`[deacon] Failed to resume ${sessionName} after orchestrated compaction:`, err);
|
|
23413
|
+
}
|
|
23414
|
+
if (hasOrchestratedCompactionContinuation(sessionName)) continue;
|
|
23415
|
+
}
|
|
22812
23416
|
if (!tmuxOutput.includes("❯")) continue;
|
|
22813
23417
|
{
|
|
22814
23418
|
const issueId = sessionName.startsWith("agent-") ? sessionName.replace("agent-", "").toUpperCase() : null;
|
|
@@ -22840,13 +23444,13 @@ async function checkApiErrorAgents() {
|
|
|
22840
23444
|
const st = getAgentStateSync(sessionName);
|
|
22841
23445
|
const sid = st?.sessionId ?? runtimeState?.claudeSessionId;
|
|
22842
23446
|
if (st?.workspace && sid && st.model) {
|
|
22843
|
-
const { computeContextUsage } = await import("./conversation-service-
|
|
23447
|
+
const { computeContextUsage } = await import("./conversation-service-Up7FEzIC.js");
|
|
22844
23448
|
const usage = await computeContextUsage(sessionFilePath(st.workspace, sid), st.model);
|
|
22845
23449
|
if (usage && usage.percentUsed < 85) recoveredPct = usage.percentUsed;
|
|
22846
23450
|
}
|
|
22847
23451
|
} catch {}
|
|
22848
23452
|
if (recoveredPct !== null) {
|
|
22849
|
-
const { clearWorkspaceStuck } = await import("./review-status-sync-
|
|
23453
|
+
const { clearWorkspaceStuck } = await import("./review-status-sync-To3-iS-N.js");
|
|
22850
23454
|
clearWorkspaceStuck(issueId);
|
|
22851
23455
|
stuckOverflowNativeRecoveryState.delete(sessionName);
|
|
22852
23456
|
actions.push(`Context overflow recovery: cleared stuck flag for ${sessionName} (context back to ${Math.round(recoveredPct)}%)`);
|
|
@@ -22862,7 +23466,7 @@ async function checkApiErrorAgents() {
|
|
|
22862
23466
|
rec.attempts += 1;
|
|
22863
23467
|
rec.lastAttempt = now;
|
|
22864
23468
|
stuckOverflowNativeRecoveryState.set(sessionName, rec);
|
|
22865
|
-
const { resumeAgent } = await import("./agents-
|
|
23469
|
+
const { resumeAgent } = await import("./agents-FlIgQ3ql.js");
|
|
22866
23470
|
const recovered = await resumeAgent(sessionName, void 0, { compact: true });
|
|
22867
23471
|
if (recovered.success) {
|
|
22868
23472
|
stuckOverflowNativeRecoveryState.delete(sessionName);
|
|
@@ -22910,7 +23514,7 @@ async function checkApiErrorAgents() {
|
|
|
22910
23514
|
}
|
|
22911
23515
|
const compactAttempts = (ov?.compactAttempts ?? 0) + 1;
|
|
22912
23516
|
if (issueId !== null) {
|
|
22913
|
-
const { resumeAgent } = await import("./agents-
|
|
23517
|
+
const { resumeAgent } = await import("./agents-FlIgQ3ql.js");
|
|
22914
23518
|
const resumeResult = await resumeAgent(sessionName, void 0, { compact: true });
|
|
22915
23519
|
contextOverflowRecoveryState.set(sessionName, {
|
|
22916
23520
|
lastAttempt: now,
|
|
@@ -22939,7 +23543,7 @@ async function checkApiErrorAgents() {
|
|
|
22939
23543
|
continue;
|
|
22940
23544
|
}
|
|
22941
23545
|
try {
|
|
22942
|
-
await Effect.runPromise(sendKeys(sessionName, "/compact"));
|
|
23546
|
+
await deliverOrchestratedCompact(sessionName, () => Effect.runPromise(sendKeys(sessionName, "/compact")));
|
|
22943
23547
|
contextOverflowRecoveryState.set(sessionName, {
|
|
22944
23548
|
lastAttempt: now,
|
|
22945
23549
|
compactAttempts,
|
|
@@ -23433,7 +24037,7 @@ function reviewConvoyLiveness(issueId) {
|
|
|
23433
24037
|
*/
|
|
23434
24038
|
async function recoverUnhealthyTestStack(issueId, workspacePath) {
|
|
23435
24039
|
const key = issueId.toUpperCase();
|
|
23436
|
-
const { getWorkspaceStackHealth } = await import("./stack-health-
|
|
24040
|
+
const { getWorkspaceStackHealth } = await import("./stack-health-Df0YEZKa.js");
|
|
23437
24041
|
const health = await Effect.runPromise(getWorkspaceStackHealth(issueId, { workspacePath }));
|
|
23438
24042
|
if (health.healthy) {
|
|
23439
24043
|
testStackRebuildState.delete(key);
|
|
@@ -23465,7 +24069,7 @@ async function recoverUnhealthyTestStack(issueId, workspacePath) {
|
|
|
23465
24069
|
record.attempts += 1;
|
|
23466
24070
|
testStackRebuildState.set(key, record);
|
|
23467
24071
|
console.log(`[deacon] Test stack for ${key} unhealthy (${health.reasons.join("; ")}) — rebuilding (attempt ${record.attempts}/${TEST_STACK_REBUILD_MAX_ATTEMPTS})`);
|
|
23468
|
-
const { rebuildWorkspaceStack } = await import("./rebuild-stack-
|
|
24072
|
+
const { rebuildWorkspaceStack } = await import("./rebuild-stack-kA7XngID.js");
|
|
23469
24073
|
const result = await Effect.runPromise(rebuildWorkspaceStack(issueId, { onProgress: (m) => console.log(`[deacon] ${key} stack rebuild: ${m}`) }));
|
|
23470
24074
|
if (!result.success) {
|
|
23471
24075
|
console.warn(`[deacon] Test stack rebuild failed for ${key}: ${result.error}`);
|
|
@@ -23633,7 +24237,7 @@ async function handleReviewCoordinatorDied(issueId, _sessionName, _reason) {
|
|
|
23633
24237
|
return actions;
|
|
23634
24238
|
}
|
|
23635
24239
|
try {
|
|
23636
|
-
const { spawnReviewRoleForIssue } = await import("./review-agent-
|
|
24240
|
+
const { spawnReviewRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
|
|
23637
24241
|
const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
|
|
23638
24242
|
issueId,
|
|
23639
24243
|
workspace,
|
|
@@ -23785,7 +24389,7 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
|
|
|
23785
24389
|
const workspace = agentState?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
|
|
23786
24390
|
if (workspace && resolved && !tryReserveAdvancingSlot() && !await tryYieldForAdvancingDispatch("review", issueId)) actions.push(`Deferred review re-dispatch for ${issueId} — advancing-role concurrency ceiling reached`);
|
|
23787
24391
|
else if (workspace && resolved) try {
|
|
23788
|
-
const { spawnReviewRoleForIssue } = await import("./review-agent-
|
|
24392
|
+
const { spawnReviewRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
|
|
23789
24393
|
const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
|
|
23790
24394
|
issueId,
|
|
23791
24395
|
workspace,
|
|
@@ -23810,8 +24414,8 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
|
|
|
23810
24414
|
const workspace = agentState?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
|
|
23811
24415
|
if (workspace && resolved) {
|
|
23812
24416
|
const branch = `feature/${issueLower}`;
|
|
23813
|
-
const { spawnRun } = await import("./agents-
|
|
23814
|
-
const { buildTestRolePrompt } = await import("./test-agent-queue-
|
|
24417
|
+
const { spawnRun } = await import("./agents-FlIgQ3ql.js");
|
|
24418
|
+
const { buildTestRolePrompt } = await import("./test-agent-queue-DXDt0Xa-.js");
|
|
23815
24419
|
const stackRecovery = await recoverUnhealthyTestStack(issueId, workspace);
|
|
23816
24420
|
if (stackRecovery === "cooldown" || stackRecovery === "exhausted") {
|
|
23817
24421
|
setReviewStatusSync(issueId, { testStatus: "dispatch_failed" });
|
|
@@ -23949,7 +24553,7 @@ async function recoverStalledReviewConvoys(getCanonicalState = getAutoCloseOutCa
|
|
|
23949
24553
|
record.lastAttempt = now;
|
|
23950
24554
|
record.attempts += 1;
|
|
23951
24555
|
stalledReviewConvoyRecoveryState.set(key, record);
|
|
23952
|
-
const { spawnReviewRoleForIssue } = await import("./review-agent-
|
|
24556
|
+
const { spawnReviewRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
|
|
23953
24557
|
try {
|
|
23954
24558
|
const result = await Effect.runPromise(spawnReviewRoleForIssue({
|
|
23955
24559
|
issueId,
|
|
@@ -24020,7 +24624,7 @@ async function checkMissingReviewStatuses() {
|
|
|
24020
24624
|
continue;
|
|
24021
24625
|
}
|
|
24022
24626
|
try {
|
|
24023
|
-
const { spawnReviewRoleForIssue } = await import("./review-agent-
|
|
24627
|
+
const { spawnReviewRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
|
|
24024
24628
|
await Effect.runPromise(spawnReviewRoleForIssue({
|
|
24025
24629
|
issueId,
|
|
24026
24630
|
workspace,
|
|
@@ -24047,7 +24651,6 @@ async function checkMissingReviewStatuses() {
|
|
|
24047
24651
|
}
|
|
24048
24652
|
//#endregion
|
|
24049
24653
|
//#region ../../lib/cloister/deacon-review-unsignaled.ts
|
|
24050
|
-
init_tracker_utils();
|
|
24051
24654
|
init_agents$1();
|
|
24052
24655
|
init_projects();
|
|
24053
24656
|
init_review_status();
|
|
@@ -24073,7 +24676,7 @@ async function checkStuckReviewing() {
|
|
|
24073
24676
|
const actions = [];
|
|
24074
24677
|
const REVIEW_STUCK_THRESHOLD_MS = 1800 * 1e3;
|
|
24075
24678
|
try {
|
|
24076
|
-
const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-
|
|
24679
|
+
const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-C6n6-9f_.js");
|
|
24077
24680
|
const statuses = loadReviewStatuses();
|
|
24078
24681
|
const now = Date.now();
|
|
24079
24682
|
const activeReviewIssues = /* @__PURE__ */ new Set();
|
|
@@ -24218,7 +24821,7 @@ async function checkCompletedButUnsignaledReviews() {
|
|
|
24218
24821
|
}
|
|
24219
24822
|
const nudge = `Your review synthesis 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${`pan admin specialists done review ${issueId} --status ${verdict}${verdict === "blocked" || verdict === "failed" ? ` --notes "${topBlocker || "See synthesis.md"}"` : ""}`}\n\nRun this command NOW. Do not write any other response before executing it.`;
|
|
24220
24823
|
try {
|
|
24221
|
-
const { messageAgent } = await import("./agents-
|
|
24824
|
+
const { messageAgent } = await import("./agents-FlIgQ3ql.js");
|
|
24222
24825
|
await messageAgent(reviewSession, nudge);
|
|
24223
24826
|
unsignaledReviewNudges.set(latestDir, now);
|
|
24224
24827
|
actions.push(`Nudged ${reviewSession} to signal ${verdict} (synthesis written ${Math.round((now - latestMtime) / 6e4)}min ago)`);
|
|
@@ -24340,7 +24943,7 @@ async function respawnIdleReviewer(state, agentId) {
|
|
|
24340
24943
|
return false;
|
|
24341
24944
|
}
|
|
24342
24945
|
try {
|
|
24343
|
-
const { spawnReviewSubRoleForIssue } = await import("./review-agent-
|
|
24946
|
+
const { spawnReviewSubRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
|
|
24344
24947
|
const contextManifestPath = join$1(dirname$1(outputPath), "context.json");
|
|
24345
24948
|
const result = await Effect.runPromise(spawnReviewSubRoleForIssue({
|
|
24346
24949
|
issueId: state.issueId,
|
|
@@ -24469,7 +25072,7 @@ async function nudgeSynthesisForCompleteReviewerReports(states) {
|
|
|
24469
25072
|
"Read the four reports, write synthesis.md, then signal review status exactly as roles/review.md instructs."
|
|
24470
25073
|
].join("\n");
|
|
24471
25074
|
try {
|
|
24472
|
-
const { messageAgent } = await import("./agents-
|
|
25075
|
+
const { messageAgent } = await import("./agents-FlIgQ3ql.js");
|
|
24473
25076
|
await messageAgent(state.id, message);
|
|
24474
25077
|
reviewReportsPresentNudges.set(nudgeKey, now);
|
|
24475
25078
|
const action = `Nudged ${state.id} to synthesize from ${REVIEW_SUB_ROLES.length} reviewer reports`;
|
|
@@ -24555,7 +25158,7 @@ async function monitorReviewConvoySignals() {
|
|
|
24555
25158
|
if (!signal) continue;
|
|
24556
25159
|
const message = signal === "ready" ? `REVIEWER_READY ${state.reviewSubRole} ${outputPath}` : signal === "timeout" ? `REVIEWER_TIMEOUT ${state.reviewSubRole} ${reason}` : `REVIEWER_FAILED ${state.reviewSubRole} ${reason}`;
|
|
24557
25160
|
try {
|
|
24558
|
-
const { messageAgent } = await import("./agents-
|
|
25161
|
+
const { messageAgent } = await import("./agents-FlIgQ3ql.js");
|
|
24559
25162
|
await messageAgent(state.reviewSynthesisAgentId, message);
|
|
24560
25163
|
state.reviewMonitorSignaled = signal;
|
|
24561
25164
|
saveAgentStateSync(state);
|
|
@@ -24563,7 +25166,7 @@ async function monitorReviewConvoySignals() {
|
|
|
24563
25166
|
actions.push(action);
|
|
24564
25167
|
logDeaconEventSync(`monitorReviewConvoySignals: ${action}`);
|
|
24565
25168
|
if (signal === "ready") try {
|
|
24566
|
-
const { notifyPipelineSync } = await import("./pipeline-notifier-
|
|
25169
|
+
const { notifyPipelineSync } = await import("./pipeline-notifier-6iCJplFZ.js");
|
|
24567
25170
|
notifyPipelineSync({
|
|
24568
25171
|
type: "reviewer_completed",
|
|
24569
25172
|
issueId: state.issueId,
|
|
@@ -24571,7 +25174,7 @@ async function monitorReviewConvoySignals() {
|
|
|
24571
25174
|
});
|
|
24572
25175
|
} catch {}
|
|
24573
25176
|
else if (signal === "timeout") try {
|
|
24574
|
-
const { notifyPipelineSync } = await import("./pipeline-notifier-
|
|
25177
|
+
const { notifyPipelineSync } = await import("./pipeline-notifier-6iCJplFZ.js");
|
|
24575
25178
|
notifyPipelineSync({
|
|
24576
25179
|
type: "reviewer_timed_out",
|
|
24577
25180
|
issueId: state.issueId,
|
|
@@ -24671,7 +25274,7 @@ const FORK_CACHE_CHECK_DELAY_MS = 180 * 1e3;
|
|
|
24671
25274
|
async function checkStalledReviewDiscovery() {
|
|
24672
25275
|
const actions = [];
|
|
24673
25276
|
try {
|
|
24674
|
-
const { listAgentStates } = await import("./agents-
|
|
25277
|
+
const { listAgentStates } = await import("./agents-FlIgQ3ql.js");
|
|
24675
25278
|
const states = listAgentStates();
|
|
24676
25279
|
const now = Date.now();
|
|
24677
25280
|
for (const state of states) {
|
|
@@ -24680,7 +25283,7 @@ async function checkStalledReviewDiscovery() {
|
|
|
24680
25283
|
const aged = Number.isFinite(startedMs) && now - startedMs > 48e4;
|
|
24681
25284
|
const dead = !await Effect.runPromise(sessionExists(state.id)).catch(() => false) || await Effect.runPromise(isPaneDead(state.id)).catch(() => true);
|
|
24682
25285
|
if (!aged && !dead) continue;
|
|
24683
|
-
const { handleReviewDiscoveryReady } = await import("./review-agent-
|
|
25286
|
+
const { handleReviewDiscoveryReady } = await import("./review-agent-DJRO8EG8.js");
|
|
24684
25287
|
const result = await handleReviewDiscoveryReady(state.issueId, { source: dead ? "deacon-backstop (parent dead)" : "deacon-backstop (discovery timeout)" });
|
|
24685
25288
|
actions.push(result.message);
|
|
24686
25289
|
logDeaconEventSync(`checkStalledReviewDiscovery: ${result.message}`);
|
|
@@ -24703,8 +25306,8 @@ async function checkStalledReviewDiscovery() {
|
|
|
24703
25306
|
async function checkStalledReviewParents() {
|
|
24704
25307
|
const actions = [];
|
|
24705
25308
|
try {
|
|
24706
|
-
const { listAgentStates, markAgentStoppedState } = await import("./agents-
|
|
24707
|
-
const { PARENT_REVIEW_TIMEOUT_MS } = await import("./review-agent-
|
|
25309
|
+
const { listAgentStates, markAgentStoppedState } = await import("./agents-FlIgQ3ql.js");
|
|
25310
|
+
const { PARENT_REVIEW_TIMEOUT_MS } = await import("./review-agent-DJRO8EG8.js");
|
|
24708
25311
|
const states = listAgentStates();
|
|
24709
25312
|
const now = Date.now();
|
|
24710
25313
|
for (const state of states) {
|
|
@@ -24753,8 +25356,8 @@ async function checkStalledReviewParents() {
|
|
|
24753
25356
|
async function checkReviewForkCacheMisses() {
|
|
24754
25357
|
const actions = [];
|
|
24755
25358
|
try {
|
|
24756
|
-
const { listAgentStates, saveAgentState } = await import("./agents-
|
|
24757
|
-
const { readEventsSync } = await import("./events-
|
|
25359
|
+
const { listAgentStates, saveAgentState } = await import("./agents-FlIgQ3ql.js");
|
|
25360
|
+
const { readEventsSync } = await import("./events-CvvGK6LT.js");
|
|
24758
25361
|
const { emitActivityEntrySync } = await import("./activity-logger-OEUBdfZ8.js");
|
|
24759
25362
|
const states = listAgentStates();
|
|
24760
25363
|
const now = Date.now();
|
|
@@ -24805,7 +25408,6 @@ async function checkReviewForkCacheMisses() {
|
|
|
24805
25408
|
init_paths();
|
|
24806
25409
|
init_activity_logger();
|
|
24807
25410
|
init_agents$1();
|
|
24808
|
-
init_concurrency$1();
|
|
24809
25411
|
init_review_status();
|
|
24810
25412
|
init_projects();
|
|
24811
25413
|
init_tmux();
|
|
@@ -24890,7 +25492,7 @@ async function reconcileStaleMergeStatus() {
|
|
|
24890
25492
|
if (!project) continue;
|
|
24891
25493
|
let specStatus;
|
|
24892
25494
|
try {
|
|
24893
|
-
const { findSpecByIssue } = await import("./specs-
|
|
25495
|
+
const { findSpecByIssue } = await import("./specs-nN45DG2X.js");
|
|
24894
25496
|
const spec = await Effect.runPromise(findSpecByIssue(project.projectPath, issueId));
|
|
24895
25497
|
specStatus = spec?.status;
|
|
24896
25498
|
if (spec && (spec.status === "completed" || spec.status === "cancelled")) {
|
|
@@ -24905,7 +25507,7 @@ async function reconcileStaleMergeStatus() {
|
|
|
24905
25507
|
if (branchTip.stdout.trim() === mainTip.stdout.trim()) console.log(`[deacon] ${issueId}: branch ${branch} points at main; not treating zero-commit branch as merged`);
|
|
24906
25508
|
} catch {}
|
|
24907
25509
|
if (!isMerged) {
|
|
24908
|
-
const { resolveGitHubIssueSync: _resolveGitHubIssue } = await import("./tracker-utils-
|
|
25510
|
+
const { resolveGitHubIssueSync: _resolveGitHubIssue } = await import("./tracker-utils-BePq_oj-.js");
|
|
24909
25511
|
const ghResolved = _resolveGitHubIssue(issueId);
|
|
24910
25512
|
if (ghResolved.isGitHub) try {
|
|
24911
25513
|
const { stdout } = await execFileAsync$4("gh", [
|
|
@@ -24942,7 +25544,7 @@ async function reconcileStaleMergeStatus() {
|
|
|
24942
25544
|
actions.push(msg);
|
|
24943
25545
|
console.log(`[deacon] ${msg}`);
|
|
24944
25546
|
try {
|
|
24945
|
-
const { postMergeLifecycle } = await import("./merge-agent-
|
|
25547
|
+
const { postMergeLifecycle } = await import("./merge-agent-BQM3a8z5.js");
|
|
24946
25548
|
postMergeLifecycle(issueId, project.projectPath, branch, { skipDeploy: true }).catch((err) => console.warn(`[deacon] postMergeLifecycle (reconcile) failed for ${issueId}: ${err}`));
|
|
24947
25549
|
} catch (err) {
|
|
24948
25550
|
console.warn(`[deacon] Could not import postMergeLifecycle: ${err}`);
|
|
@@ -24967,7 +25569,7 @@ const falseMergedReset = /* @__PURE__ */ new Set();
|
|
|
24967
25569
|
async function reconcileFalseMerged() {
|
|
24968
25570
|
const actions = [];
|
|
24969
25571
|
try {
|
|
24970
|
-
const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-
|
|
25572
|
+
const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CPfoFAdV.js");
|
|
24971
25573
|
if (!isGitHubAppConfigured()) return actions;
|
|
24972
25574
|
const statuses = loadReviewStatuses();
|
|
24973
25575
|
for (const [issueId, status] of Object.entries(statuses)) {
|
|
@@ -25012,7 +25614,7 @@ const CLOSED_PR_RECONCILE_COOLDOWN_MS = 600 * 1e3;
|
|
|
25012
25614
|
async function reconcileClosedPrReadyForMerge() {
|
|
25013
25615
|
const actions = [];
|
|
25014
25616
|
try {
|
|
25015
|
-
const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-
|
|
25617
|
+
const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CPfoFAdV.js");
|
|
25016
25618
|
if (!isGitHubAppConfigured()) return actions;
|
|
25017
25619
|
const statuses = loadReviewStatuses();
|
|
25018
25620
|
const now = Date.now();
|
|
@@ -25084,7 +25686,7 @@ const STALE_MERGE_BLOCKER_COOLDOWN_MS = 120 * 1e3;
|
|
|
25084
25686
|
async function reconcileStaleMergeBlockers() {
|
|
25085
25687
|
const actions = [];
|
|
25086
25688
|
try {
|
|
25087
|
-
const { resolveConflictGate, buildRealConflictGateDeps } = await import("./conflict-gate-
|
|
25689
|
+
const { resolveConflictGate, buildRealConflictGateDeps } = await import("./conflict-gate-BSJkNTdp.js");
|
|
25088
25690
|
const statuses = loadReviewStatuses();
|
|
25089
25691
|
const now = Date.now();
|
|
25090
25692
|
const deps = buildRealConflictGateDeps();
|
|
@@ -25227,7 +25829,7 @@ async function checkFailedMergeRetry() {
|
|
|
25227
25829
|
if (ciEntry.count === 5) {
|
|
25228
25830
|
console.log(`[deacon] CI check failure for ${issueId} — retries exhausted, notifying work agent`);
|
|
25229
25831
|
const ciNotes = status.mergeNotes || "CI checks are failing on the PR";
|
|
25230
|
-
const { writeFeedbackFile } = await import("./feedback-writer-
|
|
25832
|
+
const { writeFeedbackFile } = await import("./feedback-writer-qmiMbqTZ.js");
|
|
25231
25833
|
const ciFileResult = await Effect.runPromise(writeFeedbackFile({
|
|
25232
25834
|
issueId,
|
|
25233
25835
|
specialist: "merge-agent",
|
|
@@ -25259,7 +25861,7 @@ async function checkFailedMergeRetry() {
|
|
|
25259
25861
|
ciRetryMap.set(issueId, ciEntry);
|
|
25260
25862
|
console.log(`[deacon] CI check failure for ${issueId} — notifying agent to re-submit (attempt ${ciEntry.count}/5)`);
|
|
25261
25863
|
const ciNotes = status.mergeNotes || "CI checks are failing on the PR";
|
|
25262
|
-
const { writeFeedbackFile } = await import("./feedback-writer-
|
|
25864
|
+
const { writeFeedbackFile } = await import("./feedback-writer-qmiMbqTZ.js");
|
|
25263
25865
|
const ciFileResult2 = await Effect.runPromise(writeFeedbackFile({
|
|
25264
25866
|
issueId,
|
|
25265
25867
|
specialist: "merge-agent",
|
|
@@ -25287,7 +25889,7 @@ async function checkFailedMergeRetry() {
|
|
|
25287
25889
|
const lastNudge = timeoutNudgeCooldowns.get(issueIdForFb);
|
|
25288
25890
|
if (!lastNudge || now - lastNudge >= TIMEOUT_NUDGE_COOLDOWN_MS) {
|
|
25289
25891
|
const timeoutNotes = status.mergeNotes;
|
|
25290
|
-
const { writeFeedbackFile } = await import("./feedback-writer-
|
|
25892
|
+
const { writeFeedbackFile } = await import("./feedback-writer-qmiMbqTZ.js");
|
|
25291
25893
|
await Effect.runPromise(writeFeedbackFile({
|
|
25292
25894
|
issueId: issueIdForFb,
|
|
25293
25895
|
specialist: "merge-agent",
|
|
@@ -25392,7 +25994,7 @@ async function autoCloseOut(now = /* @__PURE__ */ new Date()) {
|
|
|
25392
25994
|
} } : {}
|
|
25393
25995
|
};
|
|
25394
25996
|
try {
|
|
25395
|
-
const { closeOut } = await import("./workflows-
|
|
25997
|
+
const { closeOut } = await import("./workflows-D90rMOya.js");
|
|
25396
25998
|
const result = await Effect.runPromise(closeOut(ctx));
|
|
25397
25999
|
if (!result.success) {
|
|
25398
26000
|
const failed = result.steps.find((step) => !step.success && !step.skipped);
|
|
@@ -25511,16 +26113,8 @@ async function checkFirstCompletionAgents() {
|
|
|
25511
26113
|
return actions;
|
|
25512
26114
|
}
|
|
25513
26115
|
//#endregion
|
|
25514
|
-
//#region ../../lib/cloister/agent-grace.ts
|
|
25515
|
-
init_traefik_connect();
|
|
25516
|
-
const WORK_LAUNCHER_GRACE_MS = 12e4;
|
|
25517
|
-
function isStartingWithinGrace(state, now = Date.now(), graceMs = WORK_LAUNCHER_GRACE_MS) {
|
|
25518
|
-
if (state.status !== "starting") return false;
|
|
25519
|
-
const startedMs = Date.parse(state.startedAt ?? "");
|
|
25520
|
-
return Number.isFinite(startedMs) && now - startedMs < graceMs;
|
|
25521
|
-
}
|
|
25522
|
-
//#endregion
|
|
25523
26116
|
//#region ../../lib/cloister/boot-reconciliation-outcomes.ts
|
|
26117
|
+
init_traefik_connect();
|
|
25524
26118
|
function resumedBootReconciliationOutcome(agent) {
|
|
25525
26119
|
return {
|
|
25526
26120
|
id: agent.id,
|
|
@@ -25688,9 +26282,71 @@ function startBootReconciliation(options = {}) {
|
|
|
25688
26282
|
};
|
|
25689
26283
|
}
|
|
25690
26284
|
//#endregion
|
|
25691
|
-
//#region ../../lib/
|
|
26285
|
+
//#region ../../lib/agents/pinned-launch.ts
|
|
25692
26286
|
init_io();
|
|
25693
26287
|
init_dag();
|
|
26288
|
+
init_agent_state();
|
|
26289
|
+
function parseFlagValue(content, flag) {
|
|
26290
|
+
const escapedFlag = flag.replace("-", "\\-");
|
|
26291
|
+
const quoted = content.match(new RegExp(`${escapedFlag}\\s+'([^']+)'`)) ?? content.match(new RegExp(`${escapedFlag}\\s+"([^"]+)"`));
|
|
26292
|
+
if (quoted?.[1]) return quoted[1];
|
|
26293
|
+
return content.match(new RegExp(`${escapedFlag}\\s+([^\\s'"\\\\]+)`))?.[1] ?? null;
|
|
26294
|
+
}
|
|
26295
|
+
function parsePinnedAgentLaunch(launcher, sessionId) {
|
|
26296
|
+
const pinnedSessionId = sessionId.trim();
|
|
26297
|
+
if (!pinnedSessionId) return null;
|
|
26298
|
+
const harness = launcher.includes("codex-app-server-host.js") || /(?:^|\s)(?:exec\s+)?codex(?:\s|$)/m.test(launcher) ? "codex" : /(?:^|\s)(?:exec\s+)?omp\s+--mode\s+rpc(?:\s|$)/m.test(launcher) ? "ohmypi" : /(?:^|\s)claude(?:\s|$)/m.test(launcher) ? "claude-code" : null;
|
|
26299
|
+
const model = parseFlagValue(launcher, "--model") ?? parseFlagValue(launcher, "-m");
|
|
26300
|
+
if (!harness || !model || model.startsWith("pending-")) return null;
|
|
26301
|
+
return {
|
|
26302
|
+
sessionId: pinnedSessionId,
|
|
26303
|
+
model,
|
|
26304
|
+
harness
|
|
26305
|
+
};
|
|
26306
|
+
}
|
|
26307
|
+
function readPinnedAgentLaunchSync(agentId) {
|
|
26308
|
+
const agentDir = getAgentDir(agentId);
|
|
26309
|
+
const launcherPath = join(agentDir, "launcher.sh");
|
|
26310
|
+
const sessionIdPath = join(agentDir, "session.id");
|
|
26311
|
+
if (!existsSync$1(launcherPath) || !existsSync$1(sessionIdPath)) return null;
|
|
26312
|
+
try {
|
|
26313
|
+
return parsePinnedAgentLaunch(readFileSync$1(launcherPath, "utf8"), readFileSync$1(sessionIdPath, "utf8"));
|
|
26314
|
+
} catch {
|
|
26315
|
+
return null;
|
|
26316
|
+
}
|
|
26317
|
+
}
|
|
26318
|
+
//#endregion
|
|
26319
|
+
//#region ../../lib/agents/placeholder-reconciliation.ts
|
|
26320
|
+
init_persistent_logger();
|
|
26321
|
+
init_agent_state();
|
|
26322
|
+
function defaultPlaceholderReconciliationDeps() {
|
|
26323
|
+
return {
|
|
26324
|
+
readPinnedLaunch: readPinnedAgentLaunchSync,
|
|
26325
|
+
markRunning: markAgentRunningState,
|
|
26326
|
+
saveState: (state) => Effect.runPromise(saveAgentState(state)),
|
|
26327
|
+
logDeacon: logDeaconEventSync,
|
|
26328
|
+
logAgent: logAgentLifecycleSync
|
|
26329
|
+
};
|
|
26330
|
+
}
|
|
26331
|
+
async function reconcileLiveWorkSpawnPlaceholder(state, notifyStatusChanged, deps) {
|
|
26332
|
+
if (state.model !== "pending-work-spawn") return null;
|
|
26333
|
+
const resolvedDeps = deps ?? defaultPlaceholderReconciliationDeps();
|
|
26334
|
+
const pinnedLaunch = resolvedDeps.readPinnedLaunch(state.id);
|
|
26335
|
+
if (!pinnedLaunch) return null;
|
|
26336
|
+
const previousStatus = state.status;
|
|
26337
|
+
state.model = pinnedLaunch.model;
|
|
26338
|
+
state.harness = pinnedLaunch.harness;
|
|
26339
|
+
state.sessionId = pinnedLaunch.sessionId;
|
|
26340
|
+
resolvedDeps.markRunning(state);
|
|
26341
|
+
await resolvedDeps.saveState(state);
|
|
26342
|
+
notifyStatusChanged(state, previousStatus, true);
|
|
26343
|
+
const message = `Reconciled ${state.id} placeholder to running (${pinnedLaunch.harness}/${pinnedLaunch.model})`;
|
|
26344
|
+
resolvedDeps.logDeacon(`handleAgentHeartbeatDeadEvent: ${message}`);
|
|
26345
|
+
resolvedDeps.logAgent(state.id, message);
|
|
26346
|
+
return message;
|
|
26347
|
+
}
|
|
26348
|
+
//#endregion
|
|
26349
|
+
//#region ../../lib/cloister/confirmed-session-query.ts
|
|
25694
26350
|
init_tmux();
|
|
25695
26351
|
const consecutiveMisses = /* @__PURE__ */ new Map();
|
|
25696
26352
|
function queryConfirmedSession(agentId) {
|
|
@@ -25832,7 +26488,10 @@ async function handleAgentHeartbeatDeadEvent$1(agentId, context, deps) {
|
|
|
25832
26488
|
} catch {
|
|
25833
26489
|
return [];
|
|
25834
26490
|
}
|
|
25835
|
-
else
|
|
26491
|
+
else {
|
|
26492
|
+
const action = await reconcileLiveWorkSpawnPlaceholder(state, deps.notifyAgentStatusChanged);
|
|
26493
|
+
return action ? [action] : [];
|
|
26494
|
+
}
|
|
25836
26495
|
else if (state.status === "starting") {
|
|
25837
26496
|
if (isStartingWithinGrace(state)) return [];
|
|
25838
26497
|
}
|
|
@@ -25990,7 +26649,7 @@ async function nudgeStalledResumeWorkAgents() {
|
|
|
25990
26649
|
const message = buildStalledResumePrompt(state);
|
|
25991
26650
|
if (!message) continue;
|
|
25992
26651
|
try {
|
|
25993
|
-
const { messageAgent } = await import("./agents-
|
|
26652
|
+
const { messageAgent } = await import("./agents-FlIgQ3ql.js");
|
|
25994
26653
|
await messageAgent(agentId, message);
|
|
25995
26654
|
recordCooldown(agentId, ".last-stalled-resume-nudge");
|
|
25996
26655
|
const action = `Re-sent stalled resume prompt to ${agentId} (${state.issueId})`;
|
|
@@ -26099,12 +26758,12 @@ async function nudgeIdleWorkAgentsWithOpenBeads() {
|
|
|
26099
26758
|
``,
|
|
26100
26759
|
`Next ready task: ${firstTask}`,
|
|
26101
26760
|
``,
|
|
26102
|
-
`If you don't already have your full brief for ${state.issueId} in context (work-agent role instructions, the
|
|
26761
|
+
`If you don't already have your full brief for ${state.issueId} in context (work-agent role instructions, the xBRIEF plan, recorded decisions & hazards), re-read it now — it is on disk at ${briefPath}, plus .pan/continue.json and .pan/spec.vbrief.json in your workspace. Startup kickoff delivery can silently fail on large briefs, so do not assume you received it.`,
|
|
26103
26762
|
``,
|
|
26104
26763
|
"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."
|
|
26105
26764
|
].join("\n");
|
|
26106
26765
|
try {
|
|
26107
|
-
const { messageAgent } = await import("./agents-
|
|
26766
|
+
const { messageAgent } = await import("./agents-FlIgQ3ql.js");
|
|
26108
26767
|
await messageAgent(agentId, message);
|
|
26109
26768
|
writeFileSync(join$1(getAgentDir(agentId), ".last-bead-nudge"), String(Date.now()), "utf-8");
|
|
26110
26769
|
const action = `Nudged idle ${agentId} (${state.issueId}) — ${openTasks.length} ready task(s)`;
|
|
@@ -27373,8 +28032,8 @@ async function cleanupStaleAgentState() {
|
|
|
27373
28032
|
*/
|
|
27374
28033
|
async function cleanupAbandonedFeedback() {
|
|
27375
28034
|
const actions = [];
|
|
27376
|
-
const { getReviewStatusSync } = await import("./review-status-
|
|
27377
|
-
const { clearFeedbackFiles } = await import("./feedback-writer-
|
|
28035
|
+
const { getReviewStatusSync } = await import("./review-status-C6n6-9f_.js");
|
|
28036
|
+
const { clearFeedbackFiles } = await import("./feedback-writer-qmiMbqTZ.js");
|
|
27378
28037
|
for (const { issueId, workspacePath } of listFeatureWorkspaces()) {
|
|
27379
28038
|
const panFeedbackDir = join$1(workspacePath, ".pan", "feedback");
|
|
27380
28039
|
if (!existsSync(panFeedbackDir)) continue;
|
|
@@ -27445,7 +28104,7 @@ async function handleOrphanReviewerSession(sessionName, sessions, creationTimes,
|
|
|
27445
28104
|
if (!issueId) return null;
|
|
27446
28105
|
const agentSession = `agent-${issueId.toLowerCase()}`;
|
|
27447
28106
|
if (sessions.includes(agentSession)) return null;
|
|
27448
|
-
const { getReviewStatusSync } = await import("./review-status-
|
|
28107
|
+
const { getReviewStatusSync } = await import("./review-status-C6n6-9f_.js");
|
|
27449
28108
|
try {
|
|
27450
28109
|
if (getReviewStatusSync(issueId)?.reviewStatus === "reviewing") return null;
|
|
27451
28110
|
} catch {}
|
|
@@ -27567,7 +28226,7 @@ async function checkOrphanedCompletions() {
|
|
|
27567
28226
|
async function checkPendingTestDispatch() {
|
|
27568
28227
|
const actions = [];
|
|
27569
28228
|
try {
|
|
27570
|
-
const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-
|
|
28229
|
+
const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-C6n6-9f_.js");
|
|
27571
28230
|
const statuses = loadReviewStatuses();
|
|
27572
28231
|
const now = Date.now();
|
|
27573
28232
|
for (const [issueId, status] of Object.entries(statuses)) {
|
|
@@ -27600,7 +28259,7 @@ async function checkPendingTestDispatch() {
|
|
|
27600
28259
|
console.log(`[deacon] ${issueId}: skipping test re-dispatch — issue is closed`);
|
|
27601
28260
|
continue;
|
|
27602
28261
|
}
|
|
27603
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
28262
|
+
const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
|
|
27604
28263
|
const resolved = resolveProjectFromIssueSync(issueId);
|
|
27605
28264
|
if (!resolved) continue;
|
|
27606
28265
|
const issueLower = issueId.toLowerCase();
|
|
@@ -27615,8 +28274,8 @@ async function checkPendingTestDispatch() {
|
|
|
27615
28274
|
logDeaconEventSync(`checkPendingTestDispatch: deferred test for ${issueId} — advancing ceiling reached (PAN-1665) — ${describeRunningAgents()}`);
|
|
27616
28275
|
continue;
|
|
27617
28276
|
}
|
|
27618
|
-
const { spawnRun } = await import("./agents-
|
|
27619
|
-
const { buildTestRolePrompt } = await import("./test-agent-queue-
|
|
28277
|
+
const { spawnRun } = await import("./agents-FlIgQ3ql.js");
|
|
28278
|
+
const { buildTestRolePrompt } = await import("./test-agent-queue-DXDt0Xa-.js");
|
|
27620
28279
|
try {
|
|
27621
28280
|
const run = await spawnRun(issueId, "test", {
|
|
27622
28281
|
workspace,
|
|
@@ -27739,7 +28398,7 @@ async function checkCompletedButUnsignaledTests() {
|
|
|
27739
28398
|
const cmd = `pan admin specialists done test ${issueId} --status ${decision.status}${noteArg}`;
|
|
27740
28399
|
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.`;
|
|
27741
28400
|
try {
|
|
27742
|
-
const { messageAgent } = await import("./agents-
|
|
28401
|
+
const { messageAgent } = await import("./agents-FlIgQ3ql.js");
|
|
27743
28402
|
await messageAgent(testSession, nudge);
|
|
27744
28403
|
unsignaledTestNudges.set(testSession, now);
|
|
27745
28404
|
const msg = `Nudged ${testSession} to signal ${decision.status} (verdict artifact present)`;
|
|
@@ -27753,7 +28412,7 @@ async function checkCompletedButUnsignaledTests() {
|
|
|
27753
28412
|
case "nudge-write": {
|
|
27754
28413
|
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.`;
|
|
27755
28414
|
try {
|
|
27756
|
-
const { messageAgent } = await import("./agents-
|
|
28415
|
+
const { messageAgent } = await import("./agents-FlIgQ3ql.js");
|
|
27757
28416
|
await messageAgent(testSession, nudge);
|
|
27758
28417
|
unsignaledTestNudges.set(testSession, now);
|
|
27759
28418
|
const msg = `Nudged ${testSession} to write+signal a test verdict (no artifact yet)`;
|
|
@@ -27776,8 +28435,8 @@ async function checkCompletedButUnsignaledTests() {
|
|
|
27776
28435
|
async function checkVerificationReviewContradiction() {
|
|
27777
28436
|
const actions = [];
|
|
27778
28437
|
try {
|
|
27779
|
-
const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-
|
|
27780
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
28438
|
+
const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-C6n6-9f_.js");
|
|
28439
|
+
const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
|
|
27781
28440
|
const statuses = loadReviewStatuses();
|
|
27782
28441
|
for (const [issueId, status] of Object.entries(statuses)) if (status.verificationStatus === "passed" && status.reviewStatus === "reviewing" && status.stuckReason === "review_infrastructure_failure") {
|
|
27783
28442
|
let reviewedAtCommit;
|
|
@@ -27826,7 +28485,7 @@ async function checkPostReviewCommits() {
|
|
|
27826
28485
|
const actions = [];
|
|
27827
28486
|
try {
|
|
27828
28487
|
const statuses = loadReviewStatuses();
|
|
27829
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
28488
|
+
const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
|
|
27830
28489
|
for (const [issueId, status] of Object.entries(statuses)) {
|
|
27831
28490
|
if (status.mergeStatus === "merged") continue;
|
|
27832
28491
|
if (!status.reviewedAtCommit) continue;
|
|
@@ -27881,7 +28540,7 @@ async function checkPostReviewCommits() {
|
|
|
27881
28540
|
actions.push(`Deferred post-review re-dispatch for ${issueId} — advancing-role concurrency ceiling reached`);
|
|
27882
28541
|
logDeaconEventSync(`checkPostReviewCommits: deferred review for ${issueId} — advancing ceiling reached (PAN-1665) — ${describeRunningAgents()}`);
|
|
27883
28542
|
} else if (freshStatus?.reviewStatus === "pending") {
|
|
27884
|
-
const { spawnReviewRoleForIssue } = await import("./review-agent-
|
|
28543
|
+
const { spawnReviewRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
|
|
27885
28544
|
const branch = `feature/${issueId.toLowerCase()}`;
|
|
27886
28545
|
const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
|
|
27887
28546
|
issueId,
|
|
@@ -27981,7 +28640,7 @@ async function checkReadyForMergeStuck() {
|
|
|
27981
28640
|
const testStatusGreenCiReconcileCooldowns = /* @__PURE__ */ new Map();
|
|
27982
28641
|
const TEST_STATUS_GREEN_CI_RECONCILE_COOLDOWN_MS = 300 * 1e3;
|
|
27983
28642
|
async function reconcileTestStatusFromGreenCi() {
|
|
27984
|
-
const { getCiCheckRunsState, getPullRequestHeadState, isGitHubAppConfigured } = await import("./github-app-
|
|
28643
|
+
const { getCiCheckRunsState, getPullRequestHeadState, isGitHubAppConfigured } = await import("./github-app-CPfoFAdV.js");
|
|
27985
28644
|
return reconcileTestStatusFromGreenCiWithDeps({
|
|
27986
28645
|
isGitHubAppConfigured,
|
|
27987
28646
|
loadReviewStatuses,
|
|
@@ -28002,7 +28661,7 @@ async function reconcileTestStatusFromGreenCi() {
|
|
|
28002
28661
|
*/
|
|
28003
28662
|
async function clearStaleCiFeedback(issueId) {
|
|
28004
28663
|
const { readdir, rm } = await import("fs/promises");
|
|
28005
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
28664
|
+
const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
|
|
28006
28665
|
const projectConfig = resolveProjectFromIssueSync(issueId);
|
|
28007
28666
|
if (!projectConfig) return;
|
|
28008
28667
|
const repoDir = projectConfig.projectPath;
|
|
@@ -28298,7 +28957,7 @@ async function checkWorkspaceContainerHealth(sharedState) {
|
|
|
28298
28957
|
}
|
|
28299
28958
|
}
|
|
28300
28959
|
try {
|
|
28301
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
28960
|
+
const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
|
|
28302
28961
|
const resolved = resolveProjectFromIssueSync(issueLower.toUpperCase());
|
|
28303
28962
|
if (resolved) await killOrphanedWorkspaceProcesses(`${resolved.projectPath}/workspaces/feature-${issueLower}`);
|
|
28304
28963
|
} catch {}
|
|
@@ -28347,8 +29006,8 @@ async function checkWorkspaceContainerHealth(sharedState) {
|
|
|
28347
29006
|
async function checkMergedWorkSessions() {
|
|
28348
29007
|
const actions = [];
|
|
28349
29008
|
try {
|
|
28350
|
-
const { selectMergedWorkSessions } = await import("./reap-terminal-sessions-
|
|
28351
|
-
const { setAgentPaused } = await import("./agents-
|
|
29009
|
+
const { selectMergedWorkSessions } = await import("./reap-terminal-sessions-MWnqdLCJ.js");
|
|
29010
|
+
const { setAgentPaused } = await import("./agents-FlIgQ3ql.js");
|
|
28352
29011
|
const toKill = selectMergedWorkSessions(loadReviewStatuses(), [...await Effect.runPromise(listSessionNames())]);
|
|
28353
29012
|
for (const session of toKill) try {
|
|
28354
29013
|
await Effect.runPromise(setAgentPaused(session, "merged — awaiting close-out (verify on main)", true));
|
|
@@ -28388,7 +29047,7 @@ const AWAITING_TEST_IDLE_REAP_MS = 600 * 1e3;
|
|
|
28388
29047
|
async function checkAwaitingTestWorkSessions() {
|
|
28389
29048
|
const actions = [];
|
|
28390
29049
|
try {
|
|
28391
|
-
const { selectAwaitingTestWorkSessions } = await import("./reap-terminal-sessions-
|
|
29050
|
+
const { selectAwaitingTestWorkSessions } = await import("./reap-terminal-sessions-MWnqdLCJ.js");
|
|
28392
29051
|
const candidates = selectAwaitingTestWorkSessions(loadReviewStatuses(), [...await Effect.runPromise(listSessionNames())]);
|
|
28393
29052
|
const now = Date.now();
|
|
28394
29053
|
for (const session of candidates) {
|
|
@@ -28441,14 +29100,14 @@ async function runPatrol() {
|
|
|
28441
29100
|
hasLoggedGlobalPauseSkip = false;
|
|
28442
29101
|
addLog("info", `Patrol cycle ${state.patrolCycle} — checking per-project specialists`, state.patrolCycle);
|
|
28443
29102
|
console.log(`[deacon] Patrol cycle ${state.patrolCycle} - checking per-project specialists`);
|
|
28444
|
-
for (const a of await (await import("./stale-task-claims-
|
|
29103
|
+
for (const a of await (await import("./stale-task-claims-BbFwCTb0.js")).patrolStaleTaskClaims()) {
|
|
28445
29104
|
actions.push(a);
|
|
28446
29105
|
addLog("action", a, state.patrolCycle);
|
|
28447
29106
|
}
|
|
28448
29107
|
const stuckRemediationActions = await checkStuckAgentRemediation();
|
|
28449
29108
|
actions.push(...stuckRemediationActions);
|
|
28450
29109
|
for (const a of stuckRemediationActions) addLog("action", a, state.patrolCycle);
|
|
28451
|
-
const { reconcileInFlightJournals } = await import("./advancing-selfheal-
|
|
29110
|
+
const { reconcileInFlightJournals } = await import("./advancing-selfheal-BBu6DSNm.js");
|
|
28452
29111
|
const reconciledJournalActions = await reconcileInFlightJournals();
|
|
28453
29112
|
actions.push(...reconciledJournalActions);
|
|
28454
29113
|
for (const a of reconciledJournalActions) addLog("action", a, state.patrolCycle);
|
|
@@ -28460,7 +29119,7 @@ async function runPatrol() {
|
|
|
28460
29119
|
const age = Date.now() - (pending.timestamp ?? 0);
|
|
28461
29120
|
if (age < 3600 * 1e3) {
|
|
28462
29121
|
console.log(`[deacon] Processing pending post-merge lifecycle for ${pending.issueId} (age: ${Math.round(age / 1e3)}s)`);
|
|
28463
|
-
const { postMergeLifecycle } = await import("./merge-agent-
|
|
29122
|
+
const { postMergeLifecycle } = await import("./merge-agent-BQM3a8z5.js");
|
|
28464
29123
|
const { unlinkSync } = await import("fs");
|
|
28465
29124
|
unlinkSync(pendingFile);
|
|
28466
29125
|
await postMergeLifecycle(pending.issueId, pending.projectPath, pending.sourceBranch, { skipDeploy: true });
|
|
@@ -28474,7 +29133,7 @@ async function runPatrol() {
|
|
|
28474
29133
|
} catch (err) {
|
|
28475
29134
|
console.warn(`[deacon] Failed to process pending lifecycle: ${err.message}`);
|
|
28476
29135
|
}
|
|
28477
|
-
if (state.patrolCycle % 5 === 0) await (await import("./deploy-patrol-
|
|
29136
|
+
if (state.patrolCycle % 5 === 0) await (await import("./deploy-patrol-Bjsho_ha.js")).runScheduledDeployPatrol();
|
|
28478
29137
|
const livenessActions = await reconcileAgentLiveness();
|
|
28479
29138
|
actions.push(...livenessActions);
|
|
28480
29139
|
for (const a of livenessActions) addLog("action", a, state.patrolCycle);
|
|
@@ -28506,7 +29165,7 @@ async function runPatrol() {
|
|
|
28506
29165
|
actions.push(...suspendActions);
|
|
28507
29166
|
for (const a of suspendActions) addLog("action", a, state.patrolCycle);
|
|
28508
29167
|
try {
|
|
28509
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
29168
|
+
const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
|
|
28510
29169
|
const allStatuses = loadReviewStatuses();
|
|
28511
29170
|
for (const [issueId, status] of Object.entries(allStatuses)) {
|
|
28512
29171
|
if (!status.readyForMerge || status.mergeStatus === "merged") continue;
|
|
@@ -28526,7 +29185,7 @@ async function runPatrol() {
|
|
|
28526
29185
|
} catch (err) {
|
|
28527
29186
|
console.warn(`[deacon] Failed to check workspace existence: ${err.message}`);
|
|
28528
29187
|
}
|
|
28529
|
-
const { checkMergedAdvancingSessions } = await import("./advancing-selfheal-
|
|
29188
|
+
const { checkMergedAdvancingSessions } = await import("./advancing-selfheal-BBu6DSNm.js");
|
|
28530
29189
|
const reapedWorkActions = await checkMergedWorkSessions();
|
|
28531
29190
|
actions.push(...reapedWorkActions);
|
|
28532
29191
|
for (const a of reapedWorkActions) addLog("action", a, state.patrolCycle);
|
|
@@ -28534,7 +29193,7 @@ async function runPatrol() {
|
|
|
28534
29193
|
actions.push(...reapedMergedAdvancingActions);
|
|
28535
29194
|
for (const a of reapedMergedAdvancingActions) addLog("action", a, state.patrolCycle);
|
|
28536
29195
|
try {
|
|
28537
|
-
const { refreshClaudeCredentialsForActiveRemoteAgents } = await import("./remote-completion-
|
|
29196
|
+
const { refreshClaudeCredentialsForActiveRemoteAgents } = await import("./remote-completion-BbWNd10K.js");
|
|
28538
29197
|
const remoteCredentialActions = await refreshClaudeCredentialsForActiveRemoteAgents();
|
|
28539
29198
|
actions.push(...remoteCredentialActions);
|
|
28540
29199
|
for (const a of remoteCredentialActions) addLog(a.includes("failed") ? "warn" : "action", a, state.patrolCycle);
|
|
@@ -28542,7 +29201,7 @@ async function runPatrol() {
|
|
|
28542
29201
|
addLog("warn", `Remote credential refresh patrol failed: ${err.message}`, state.patrolCycle);
|
|
28543
29202
|
}
|
|
28544
29203
|
try {
|
|
28545
|
-
const { refreshHostHeartbeatForEphemeralVms } = await import("./remote-agents-
|
|
29204
|
+
const { refreshHostHeartbeatForEphemeralVms } = await import("./remote-agents-CRCg1L4H.js");
|
|
28546
29205
|
const heartbeatActions = await refreshHostHeartbeatForEphemeralVms();
|
|
28547
29206
|
actions.push(...heartbeatActions);
|
|
28548
29207
|
for (const a of heartbeatActions) addLog(a.includes("failed") ? "warn" : "action", a, state.patrolCycle);
|
|
@@ -28550,7 +29209,7 @@ async function runPatrol() {
|
|
|
28550
29209
|
addLog("warn", `Remote heartbeat refresh patrol failed: ${err.message}`, state.patrolCycle);
|
|
28551
29210
|
}
|
|
28552
29211
|
try {
|
|
28553
|
-
const { reapCompletedRemoteAgents } = await import("./remote-completion-
|
|
29212
|
+
const { reapCompletedRemoteAgents } = await import("./remote-completion-BbWNd10K.js");
|
|
28554
29213
|
const remoteReap = await reapCompletedRemoteAgents();
|
|
28555
29214
|
for (const r of remoteReap) if (r.status === "handed-off" || r.status === "error") {
|
|
28556
29215
|
const msg = `Remote reap ${r.issueId}: ${r.status} (${r.details.join("; ")})`;
|
|
@@ -28735,7 +29394,7 @@ async function runPatrol() {
|
|
|
28735
29394
|
const issueId = runtimeState.currentIssue;
|
|
28736
29395
|
try {
|
|
28737
29396
|
if (getReviewStatusSync(issueId)?.mergeStatus === "merging") {
|
|
28738
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
29397
|
+
const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
|
|
28739
29398
|
const resolved = resolveProjectFromIssueSync(issueId);
|
|
28740
29399
|
if (resolved) {
|
|
28741
29400
|
const branch = `feature/${issueId.toLowerCase()}`;
|
|
@@ -28749,7 +29408,7 @@ async function runPatrol() {
|
|
|
28749
29408
|
mergeStatus: "merged",
|
|
28750
29409
|
readyForMerge: false
|
|
28751
29410
|
});
|
|
28752
|
-
const { postMergeLifecycle } = await import("./merge-agent-
|
|
29411
|
+
const { postMergeLifecycle } = await import("./merge-agent-BQM3a8z5.js");
|
|
28753
29412
|
postMergeLifecycle(issueId, resolved.projectPath).catch((err) => console.warn(`[deacon] postMergeLifecycle failed for ${issueId}: ${err}`));
|
|
28754
29413
|
actions.push(`Auto-completed stale merge for ${issueId}`);
|
|
28755
29414
|
} else {
|
|
@@ -28929,7 +29588,7 @@ function startDeacon() {
|
|
|
28929
29588
|
logDeaconEventSync(`startDeacon: health monitor starting (patrol every ${config.patrolIntervalMs / 1e3}s)`);
|
|
28930
29589
|
(async () => {
|
|
28931
29590
|
await reconcileAgentLiveness();
|
|
28932
|
-
const { runBootAdvancingSelfHeal } = await import("./advancing-selfheal-
|
|
29591
|
+
const { runBootAdvancingSelfHeal } = await import("./advancing-selfheal-BBu6DSNm.js");
|
|
28933
29592
|
await runBootAdvancingSelfHeal();
|
|
28934
29593
|
runScheduledPatrol("startup");
|
|
28935
29594
|
})().catch((err) => {
|
|
@@ -28999,6 +29658,6 @@ function assessDeaconPatrolFreshness(params) {
|
|
|
28999
29658
|
};
|
|
29000
29659
|
}
|
|
29001
29660
|
//#endregion
|
|
29002
|
-
export {
|
|
29661
|
+
export { reconcileClosedPrReadyForMerge as $, reconcileAgentLiveness as A, getContainerHistory as At, recordDeadEndNeedsYou as B, getLastPatrolResult as C, paneShowsClaudeBootBlockingScreen as Ct, isDeaconRunning as D, classifyMemoryPressure as Dt, handleAgentStoppedForOrphanReviewerSessions as E, WORK_LAUNCHER_GRACE_MS as Et, setAgentStatusChangedNotifier as F, getSystemHealthEvidenceSnapshot as Ft, redeliverUndeliveredKickoffs as G, isRapidPostResumeDeath as H, setAgentStoppedNotifier as I, getSystemHealthSnapshot as It, startBootReconciliation as J, isBootReconciliationCandidate as K, setMergeReadyNotifier as L, isSmeeConfiguredSync as Lt, resetPatrolHeartbeatForStartup as M, getAcceptedSystemHealthSnapshot as Mt, runPatrol as N, getDeployStaleness as Nt, loadConfig as O, getResourceStacks as Ot, saveState as P, getResourceConfig as Pt, ciRetryMap as Q, startDeacon as R, startSmeeProcessSync as Rt, getDeaconStatus as S, deliverOrchestratedCompact as St, handleAgentStoppedEvent as T, checkInspectAgentTimeouts as Tt, nudgeIdleWorkAgentsWithOpenBeads as U, isPreKickoffLaunchDeath as V, nudgeStalledResumeWorkAgents as W, checkFailedMergeRetry as X, autoCloseOut as Y, checkFirstCompletionAgents as Z, cleanupOrphanReviewerSessions as _, stalledReviewConvoyRecoveryState as _t, checkCompletedButUnsignaledTests as a, cleanupOrphanedReviewSessions as at, containerRestartBackoffMs as b, contextProactiveCompactState as bt, checkMergedWorkSessions as c, checkCompletedButUnsignaledReviews as ct, checkPostReviewCommits as d, checkMissingReviewStatuses as dt, reconcileFalseMerged as et, checkReadyForMergeStuck as f, checkOrphanedReviewStatuses as ft, cleanupAbandonedFeedback as g, reviewConvoyLiveness as gt, checkWorkspaceContainerHealth as h, recoverStalledReviewConvoys as ht, checkAwaitingTestWorkSessions as i, reconcileStuckReadyForMerge as it, reconcileTestStatusFromGreenCi as j, getCurrentDockerStats as jt, loadState as k, formatUptime as kt, checkOrphanedCompletions as l, checkStuckReviewing as lt, checkVerificationReviewContradiction as m, handleWorkCompleted as mt, assessDeaconPatrolFreshness as n, reconcileStaleMergeBlockers as nt, checkDeadEndAgents as o, monitorReviewConvoySignals as ot, checkStuckWorkAgents as p, handleReviewCoordinatorDied as pt, listBootReconciliationCandidates as q, checkAndSuspendIdleAgents as r, reconcileStaleMergeStatus as rt, checkMassDeath as s, synthesizeReviewFromReports as st, applyBootReconciliationDecision as t, reconcileMergedButReviewing as tt, checkPendingTestDispatch as u, isSynthesisForActiveReviewRun as ut, cleanupOrphanedPlanningSessions as v, checkApiErrorAgents as vt, handleAgentHeartbeatDeadEvent as w, INSPECT_TIMEOUT_MS as wt, getDeaconLogs as x, stuckOverflowNativeRecoveryState as xt, cleanupStaleAgentState as y, contextOverflowRecoveryState as yt, stopDeacon as z, classifyAgentHealth as zt };
|
|
29003
29662
|
|
|
29004
|
-
//# sourceMappingURL=deacon-
|
|
29663
|
+
//# sourceMappingURL=deacon-pRnyD5w9.js.map
|