@overdeck/desktop 0.49.1 → 0.49.2
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-Crw-xSJ3.js → acceptance-criteria-CHtDkHEL.js} +2 -2
- package/server/{active-dashboard-bundle-CLwfD-Om.js → active-dashboard-bundle-Byh6sP-q.js} +2 -2
- package/server/{activity-logger-BAVLrkR7.js → activity-logger-BWZhVphb.js} +22 -4
- package/server/activity-logger-Ck8qoluj.js +3 -0
- package/server/{advancing-selfheal-BQiJ7mIH.js → advancing-selfheal-65W4yUQi.js} +6 -6
- package/server/{agent-gc-5E0lgxI1.js → agent-gc-BNUudFnt.js} +10 -10
- package/server/agent-idle-ONBssBN_.js +745 -0
- package/server/{agent-state-Bb3UUxQm.js → agent-state-BJhGIJZe.js} +421 -135
- package/server/agent-state-CM8iVw5B.js +3 -0
- package/server/{agent-state-service-BFbttwRA.js → agent-state-service-CiIuwzIs.js} +5 -5
- package/server/{agent-state-service-keg-x1bT.js → agent-state-service-CzHfoqKQ.js} +1 -1
- package/server/agents-DpCuoF65.js +3 -0
- package/server/{agents-CqQJW75N.js → agents-jXgqpHca.js} +8 -8
- package/server/archive-planning-BW4MKNI7.js +2 -0
- package/server/{archive-planning-BwEhu9Oq.js → archive-planning-CGkU6UeL.js} +20 -135
- package/server/{artifact-index-jobs-C6Lg2rKm.js → artifact-index-jobs-Ck4NRRkY.js} +3 -3
- package/server/{assemble-DyTp2gSB.js → assemble-CyvEBmmq.js} +28 -9
- package/server/{auto-spawn-consent-BDfe4qz0.js → auto-spawn-consent-Dc4mtM-B.js} +8 -7
- package/server/{backlog-auto-trigger-DuOGpdDW.js → backlog-auto-trigger-CCEpr4YT.js} +3 -3
- package/server/{behavior-Bitko0mD.js → behavior-BiCQzqyT.js} +3 -3
- package/server/{bridge-pool-patrol-DiHEd13O.js → bridge-pool-patrol-Ce8rNPym.js} +2 -2
- package/server/{briefing-freshness-CDJcmHHZ.js → briefing-freshness-e_OEYZEe.js} +2 -2
- package/server/{build-info-DTX8JwVP.js → build-info-BRw4QlYO.js} +3 -3
- package/server/build-info-Bj2vQEMh.js +2 -0
- package/server/{checkpoint-manager-CKg1tn34.js → checkpoint-manager-CKr42Usw.js} +1 -1
- package/server/{checkpoint-manager-BlOOdzLF.js → checkpoint-manager-DOwRGFff.js} +26 -9
- package/server/checkpoint-worker.js +1 -1
- package/server/{checkpoints-DRALkfDS.js → checkpoints-Cb6CWT4S.js} +1 -1
- package/server/{checkpoints-BGfl0cHM.js → checkpoints-Cszp_0Np.js} +2 -2
- package/server/{claude-hooks-provision-B_tv3wzE.js → claude-hooks-provision-C5JHpxTS.js} +1 -1
- package/server/{claude-hooks-provision-BlGv6twJ.js → claude-hooks-provision-Cer2eFfj.js} +2 -2
- package/server/{claude-permissions-aHgDcZi5.js → claude-permissions-Bc5kjX1q.js} +2 -2
- package/server/{claude-settings-overlay-CYOvFE3A.js → claude-settings-overlay-C7rWsnya.js} +1 -1
- package/server/{claude-settings-overlay-T2LWLteV.js → claude-settings-overlay-m-VVZej1.js} +2 -2
- package/server/cli-BRuzUT_I.js +2 -0
- package/server/{cli-Do8UpLoI.js → cli-BmczsfD6.js} +11 -11
- package/server/{cliproxy-CX6jHRDP.js → cliproxy-BpYpkogS.js} +52 -17
- package/server/cliproxy-_yUU0HRY.js +3 -0
- package/server/{close-issue-J0_eWYT1.js → close-issue-CxvRD0UI.js} +5 -5
- package/server/{closed-issue-reaper-bFppuk6F.js → closed-issue-reaper-nMLRi5de.js} +13 -12
- package/server/{closed-issue-reaper-Cl2h9AfT.js → closed-issue-reaper-omOcUDBl.js} +1 -1
- package/server/{codex-icapA4om.js → codex-DZhFfcWu.js} +1 -1
- package/server/{codex-OOea7lXs.js → codex-KaSKE-R3.js} +16 -10
- package/server/{compaction-continuation-D5voR1ME.js → compaction-continuation-Bjfi70G-.js} +3 -3
- package/server/{config-Cjleh3_U.js → config-CH1AqqIQ.js} +1 -1
- package/server/{config-DC75T4Mr.js → config-Doq_tF-f.js} +2 -2
- package/server/{config-tucKBCCc.js → config-ZGjvuR6J.js} +2 -2
- package/server/{config-yaml-BwOEANMr.js → config-yaml-D9nfpEx1.js} +33 -8
- package/server/{conflict-gate-DlpWCMd7.js → conflict-gate-D4XCtrm2.js} +1 -1
- package/server/{conflict-gate-D2L1kZeL.js → conflict-gate-DcUTY4Gb.js} +4 -4
- package/server/{context-layers-CSPGc2Hb.js → context-layers-BBTKP-Y4.js} +3 -3
- package/server/context-layers-BGj2Y9l3.js +4 -0
- package/server/{continue-U3Af0jUq.js → continue-i7Revg8D.js} +3 -3
- package/server/{control-settings-5k6ixdFW.js → control-settings-BMoDHY1G.js} +6 -6
- package/server/{conversation-compaction-CSpVpxN6.js → conversation-compaction-D4VOmF7p.js} +8 -8
- package/server/{conversation-compaction-Ciit9O6k.js → conversation-compaction-DzIjYMfg.js} +1 -1
- package/server/{conversation-service-BxrB5lUT.js → conversation-service-CzZUJFEx.js} +1 -1
- package/server/{conversation-service-BteE4ELK.js → conversation-service-tQCIbBVZ.js} +6 -6
- package/server/{conversations-DhwxsOru.js → conversations-C75EFFjf.js} +12 -7
- package/server/conversations-bFDaD5YN.js +3 -0
- package/server/{cost-Bnf9NUC5.js → cost-BCWEkvro.js} +3 -3
- package/server/{cost-CQKI6OCu.js → cost-CiIwxH1D.js} +2 -2
- package/server/{cost-sync-B-ADeXKY.js → cost-sync-DOkdE_yB.js} +3 -3
- package/server/{dag-DI9LaK_q.js → dag-BPc74hwj.js} +6 -19
- package/server/{dangerous-git-ops-akhA3iyF.js → dangerous-git-ops-By9iguTP.js} +1 -1
- package/server/dashboard-db-worker.js +7 -7
- package/server/{deacon-TPYssFYt.js → deacon-B24dNzr8.js} +1774 -171
- package/server/deacon-CzSZMtb-.js +4 -0
- package/server/{deacon-canonical-state-DFYymrDw.js → deacon-canonical-state-CkvxRPck.js} +3 -3
- package/server/{deacon-event-client-Te5v10-b.js → deacon-event-client-BYIQBu0T.js} +1 -1
- package/server/{deacon-event-client-BKOL4AcL.js → deacon-event-client-Do6Z2gKl.js} +2 -2
- package/server/{deacon-nudge-log-BtlTWgWu.js → deacon-nudge-log-CzM9JA9t.js} +1 -1
- package/server/{deacon-pending-lifecycle-DVHjOLje.js → deacon-pending-lifecycle-BObEdT-L.js} +3 -3
- package/server/deacon.js +11 -11
- package/server/dead-end-trip-6V_CwveT.js +2 -0
- package/server/{dead-end-trip-P0IF1O0E.js → dead-end-trip-CnVmjnya.js} +3 -3
- package/server/delivery-gyce0vQ7.js +3 -0
- package/server/{deploy-patrol-BXjlvoV3.js → deploy-patrol-CEwwEYDM.js} +8 -8
- package/server/deploy-queue-CjLErpgw.js +2 -0
- package/server/{deploy-queue-o7shYg1j.js → deploy-queue-r96ojDI3.js} +2 -2
- package/server/{deploy-window-CNT6fOff.js → deploy-window-D_3hhfxt.js} +4 -4
- package/server/{deploy-window-BMk5_oX6.js → deploy-window-DeJK8mTK.js} +1 -1
- package/server/{dev-supervisor-SR1CLOAK.js → dev-supervisor-DZWwpENk.js} +2 -2
- package/server/{devcontainer-renderer-enMmNDFa.js → devcontainer-renderer-d-9dCV_2.js} +3 -3
- package/server/{dist-CPTO_zMR.js → dist-DsLAsFSh.js} +1 -1
- package/server/dist-fCA6y2bH.js +3 -0
- package/server/{docker-B7qUZptz.js → docker-B2mUBzGk.js} +3 -3
- package/server/{docker-KR3zSFKY.js → docker-CRPHBylA.js} +1 -1
- package/server/{dod-gK835UMf.js → dod-DWtilRLx.js} +1 -1
- package/server/{done-preflight-CksRvh49.js → done-preflight-BDVdWed5.js} +1 -1
- package/server/{done-preflight-Bk8aExAL.js → done-preflight-D4ukUf-S.js} +5 -5
- package/server/{driver-CmsY2RLl.js → driver-BtcFz-qu.js} +14 -3
- package/server/{durable-review-pipeline-DgYHucN2.js → durable-review-pipeline-B3OS2_He.js} +11 -2
- package/server/durable-review-pipeline-CaCbEJSt.js +3 -0
- package/server/{ensure-devcontainer-ojerEqQg.js → ensure-devcontainer-BUeBRjmm.js} +4 -4
- package/server/{ensure-devcontainer-BQ4YizSH.js → ensure-devcontainer-rGSh0JHK.js} +1 -1
- package/server/{esm-shims-1htPASWs.js → esm-shims-oAaKIa-a.js} +1 -1
- package/server/{event-store-D7qcJXuZ.js → event-store-BCSgMubf.js} +5 -5
- package/server/{event-store-BgEjNsvk.js → event-store-Db4w4YIY.js} +1 -1
- package/server/{event-store-provider-BKvk2rDj.js → event-store-provider-DlSQND3V.js} +1 -1
- package/server/{events-BIKGJZOT.js → events-B6zioJA_.js} +3 -3
- package/server/{dist-src-BM9eudEd.js → factory-BrdqXBeK.js} +714 -2
- package/server/{feature-registry-storage-ewNSIVsQ.js → feature-registry-storage-zh3ZXW6f.js} +3 -3
- package/server/{features-CGopJXdU.js → features-BGntOWdy.js} +2 -2
- package/server/{feedback-stuck-retirement-B8-fX7NA.js → feedback-stuck-retirement-DpA5u1kt.js} +2 -2
- package/server/{feedback-target-Ci6N5p4G.js → feedback-target-D7GxdUYG.js} +10 -10
- package/server/{feedback-target-CkyLYohm.js → feedback-target-Ddqk93NF.js} +1 -1
- package/server/{feedback-writer-D4ULO4qG.js → feedback-writer-C1gCLFmp.js} +5 -5
- package/server/{feedback-writer-DfuVjvH0.js → feedback-writer-CH2846DP.js} +1 -1
- package/server/{flywheel-C7yek87O.js → flywheel-CjW2L7BS.js} +79 -29
- package/server/{flywheel-DXI_WITn.js → flywheel-HJt7QdWP.js} +1 -1
- package/server/{flywheel-merge-order-C5m5bYBc.js → flywheel-merge-order-4fNRN2F2.js} +1 -1
- package/server/{flywheel-merge-order-CXfU4M6l.js → flywheel-merge-order-D_yyAlND.js} +7 -7
- package/server/{flywheel-BwYPDlhK.js → flywheel-v1cCOBx-.js} +14 -14
- package/server/{forge-DYX9sKzG.js → forge-RVTCK_5X.js} +2 -2
- package/server/forge-bvak6vXJ.js +2 -0
- package/server/{from-DAdMxC29.js → from-BnLgKYvw.js} +1 -1
- package/server/{fs-lock-cw25uO_E.js → fs-lock-C7J-ugIf.js} +2 -2
- package/server/{fts-operations-D_rzLxX5.js → fts-operations-CU0B5WUx.js} +3 -3
- package/server/git-info-BSrI9owC.js +148 -0
- package/server/{git-utils-Y0zG25ez.js → git-utils-CsKV0Dis.js} +1 -1
- package/server/{git-utils-DV4B9TRl.js → git-utils-DW8-jIUJ.js} +4 -4
- package/server/{github-app-4UX8VIr8.js → github-app-7ywLhuZO.js} +2 -2
- package/server/{github-app-C33lDk9Z.js → github-app-Oi5hdn1n.js} +1 -1
- package/server/{github-client-nPj5ckZO.js → github-client-Cy0fSj1a.js} +1 -1
- package/server/{github-client-DkJVR908.js → github-client-DAbuXLuk.js} +3 -3
- package/server/{github-pr-lookup-C9Vokb0W.js → github-pr-lookup-Dhh3ec1V.js} +2 -2
- package/server/{harness-binary-BgXYDo2Z.js → harness-binary-tMmgJfC1.js} +2 -2
- package/server/{harness-resolve-1NZcVx7n.js → harness-resolve-DusNpVEe.js} +4 -4
- package/server/{health-events-jMfxrElt.js → health-events-BYDZ9n2i.js} +1 -1
- package/server/{health-events-DlX_FVAB.js → health-events-DNw9Mzw9.js} +2 -2
- package/server/{hooks-W3REcb3h.js → hooks-B4wj32l2.js} +1 -1
- package/server/{hooks-NQ19vvlB.js → hooks-BjBjxqNh.js} +2 -2
- package/server/{hume-BFkid2PO.js → hume-BP9YbxaE.js} +2 -2
- package/server/hume-TYTb6fDU.js +3 -0
- package/server/{identity-Bwh6VGeL.js → identity-C23uY8dZ.js} +3 -3
- package/server/{idle-stack-reaper-BeU_KxWx.js → idle-stack-reaper-BSxb1bln.js} +4 -4
- package/server/{idle-stack-reaper-CHtCNpvd.js → idle-stack-reaper-Bw0rU9GC.js} +1 -1
- package/server/{in-flight-guard-pcwXKLGz.js → in-flight-guard-DuxabAHT.js} +1 -1
- package/server/{infra-KTp9KV9u.js → infra-CHIvOb9q.js} +30 -7
- package/server/{injection-67YyU6SC.js → injection-BYUt8ml1.js} +8 -8
- package/server/{injection-BxbZKPDh.js → injection-BviePcm3.js} +1 -1
- package/server/inspect-agent-JFEaYTRa.js +2 -0
- package/server/{inspect-agent-VHSihlb7.js → inspect-agent-sV_19NxZ.js} +12 -12
- package/server/{internal-token-B-z-sGBH.js → internal-token-BOtIRJU7.js} +1 -1
- package/server/{internal-token-zY75jrRJ.js → internal-token-DoVzb4b7.js} +2 -2
- package/server/{io-DfvO2xyh.js → io-DKrWd3gX.js} +5 -5
- package/server/{issue-closed-dvEWKO7Q.js → issue-closed-6RQsAjDX.js} +7 -7
- package/server/{issue-lifecycle-3N8XF7lP.js → issue-lifecycle-D9nLErvS.js} +206 -29
- package/server/{issue-lifecycle-BI6jAfp8.js → issue-lifecycle-DOPVv7xz.js} +1 -1
- package/server/{issue-service-singleton-BN_2MXp4.js → issue-service-singleton-B2xy-IS9.js} +124 -11
- package/server/{issue-service-singleton-CL6hESX2.js → issue-service-singleton-CvgNAWqK.js} +1 -1
- package/server/issue-title-fallback-DTSCQVu0.js +120 -0
- package/server/{issues-CkvUoAnq.js → issues-e_Ck1Ln2.js} +2 -2
- package/server/{jsonl-parser-CrEb2PWr.js → jsonl-parser-DqxVCZ1k.js} +3 -3
- package/server/jsonl-resolver-07OS3qOr.js +324 -0
- package/server/{kimi-code-C26gmGxM.js → kimi-code-BjtAHIz1.js} +14 -12
- package/server/{kimi-code-DoMoGqIu.js → kimi-code-vtXl2DR5.js} +1 -1
- package/server/{kimi-parser-Dmhy3UlR.js → kimi-parser-B1lgy2Vt.js} +2 -2
- package/server/{label-cleanup-X2lWfghH.js → label-cleanup-D2zUMasf.js} +3 -3
- package/server/{lifecycle-Bg44O-9x.js → lifecycle-0NOEzomy.js} +2 -2
- package/server/{lifecycle-B0rL38D3.js → lifecycle-DaCovZwn.js} +6 -6
- package/server/{lifecycle-io-CCBpRv5m.js → lifecycle-io-6WL46dsB.js} +5 -5
- package/server/{lifecycle-io-DQDU0apV.js → lifecycle-io-BBMTaP7S.js} +1 -1
- package/server/{linear-client-B0cIkTs4.js → linear-client-7fQThJTc.js} +3 -3
- package/server/{linear-client-6V2E-DSa.js → linear-client-BTGApNLo.js} +1 -1
- package/server/{linear-mcp-auth-LCo9AWUd.js → linear-mcp-auth-B8pYRsiU.js} +1 -1
- package/server/{linear-mcp-auth-Dsu9Io9r.js → linear-mcp-auth-Nk5s3L9M.js} +5 -5
- package/server/memory-fts-worker.js +1 -1
- package/server/{memory-governor-A4O6vI9d.js → memory-governor-Cqvbusr4.js} +14 -14
- package/server/{memory-pressure-patrol-BWlWywmA.js → memory-pressure-patrol-DPb8foam.js} +5 -5
- package/server/{merge-BGWcBxku.js → merge-BB_bjJ9a.js} +1 -1
- package/server/{merge-vz80RvSE.js → merge-FZ78_cEz.js} +3 -3
- package/server/{merge-agent-GWhmnxFk.js → merge-agent-B3jRrlS1.js} +37 -33
- package/server/{merge-agent-BRSz26Oh.js → merge-agent-BuoC_PRZ.js} +2 -2
- package/server/{merge-batch-CFMEtTxv.js → merge-batch-B8bVjFWS.js} +1 -1
- package/server/{merge-completeness-CP347umA.js → merge-completeness-DQt7Qa7i.js} +4 -4
- package/server/{merge-completeness-7ajHAIR-.js → merge-completeness-DkdabVch.js} +1 -1
- package/server/merge-ops-DabXHp2i.js +2 -0
- package/server/merge-rebase-CXq0qsgR.js +2 -0
- package/server/{merge-rebase-C5htyEEH.js → merge-rebase-qq40s91P.js} +2 -2
- package/server/{merge-set-DsGW8fmc.js → merge-set-BTNYvxM3.js} +1 -1
- package/server/{merge-set-eiE2nC6C.js → merge-set-BmRRflt0.js} +4 -4
- package/server/{merge-sync-CM2-myXu.js → merge-sync-0m2Q087q.js} +1 -1
- package/server/{merge-sync-Ct0-cxMX.js → merge-sync-CJpOa0cZ.js} +2 -2
- package/server/{merge-train-deps-LXHGK61n.js → merge-train-deps-CH5Mr3vN.js} +4 -4
- package/server/{merge-train-BOu3fN7O.js → merge-train-iwKqjtCF.js} +4 -4
- package/server/{merge-verification-BRp08IzI.js → merge-verification-JJc5GC2t.js} +6 -6
- package/server/{merged-docker-cleanup-worker-CwldDjHV.js → merged-docker-cleanup-worker-BOqWA373.js} +4 -4
- package/server/{merged-docker-cleanup-worker-C8eGn78a.js → merged-docker-cleanup-worker-CrhTdxZV.js} +1 -1
- package/server/messaging-nuwStbdQ.js +3 -0
- package/server/{multipart-parser-OAuW7824.js → multipart-parser-DxuW_rZV.js} +2 -2
- package/server/{no-resume-mode-MWI6pnrK.js → no-resume-mode-xuYLFhLw.js} +1 -1
- package/server/node_modules/.package-lock.json +11 -11
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/AGENTS.md +14 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/CLAUDE.md +14 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/README.md +10 -3
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/40_sql/10_basics.ts +175 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/40_sql/index.md +6 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/10_basics.ts +3 -1
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/20_testing.ts +100 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/fixtures/api/Users.ts +30 -14
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/fixtures/domain/User.ts +15 -6
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/fixtures/server/Authorization.ts +11 -10
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/fixtures/server/Users/http.ts +41 -32
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/fixtures/server/Users.ts +141 -20
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/70_cli/10_basics.ts +27 -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 +10 -9
- 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/dist/NodeSocketServer.js +4 -4
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeSocketServer.js.map +1 -1
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeStream.d.ts.map +1 -1
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeStream.js +10 -4
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeStream.js.map +1 -1
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/internal/nodeChildProcessSpawner.d.ts +4 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/internal/nodeChildProcessSpawner.d.ts.map +1 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/internal/nodeChildProcessSpawner.js +10 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/internal/nodeChildProcessSpawner.js.map +1 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/package.json +4 -4
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/NodeChildProcessSpawner.ts +16 -11
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/NodeSocketServer.ts +4 -4
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/NodeStream.ts +10 -4
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/internal/nodeChildProcessSpawner.ts +16 -0
- package/server/node_modules/ansi-regex/index.js +3 -2
- package/server/node_modules/ansi-regex/package.json +1 -1
- package/server/node_modules/gaxios/build/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/server/node_modules/gaxios/build/esm/tsconfig.tsbuildinfo +1 -1
- package/server/node_modules/gaxios/package.json +3 -3
- package/server/{orphan-proposed-reconciler-cV3URUqk.js → orphan-proposed-reconciler-Dmk0kO_p.js} +24 -23
- package/server/{orphan-proposed-reconciler-BAE5AZ_e.js → orphan-proposed-reconciler-gf4TxfZb.js} +2 -2
- package/server/package-lock.json +12 -12
- package/server/package.json +1 -1
- package/server/{pan-dir-DDd91kMb.js → pan-dir-BMda7tQj.js} +5 -5
- package/server/{deacon-merge-BOGFEV8_.js → parked-residue-BiHb8cD7.js} +150 -35
- package/server/{paths-CRLnDgcI.js → paths-DEe9j-kw.js} +2 -2
- package/server/{pending-lifecycle-claim-CYgMiDAP.js → pending-lifecycle-claim-J5uIIJPu.js} +2 -2
- package/server/{pickup-BjJsSX12.js → pickup-D1UbSDPd.js} +1 -1
- package/server/{pipeline-agent-reader-BLc43dVJ.js → pipeline-agent-reader-D-6okryb.js} +5 -5
- package/server/{pipeline-membership-5qlRz5Qg.js → pipeline-membership-CCbgBzNC.js} +1 -1
- package/server/{pipeline-membership-BHZp_ShY.js → pipeline-membership-PGX3Pe8V.js} +1 -1
- package/server/{pipeline-membership-gather-CGFY1v-y.js → pipeline-membership-gather-BK4dzh0X.js} +17 -12
- package/server/{pipeline-membership-gather-WhRc1yke.js → pipeline-membership-gather-BRhU7XPx.js} +1 -1
- package/server/{pipeline-notifier-BmsLWM_2.js → pipeline-notifier-BNAV9kpa.js} +2 -2
- package/server/{pipeline-notifier-C4fZ2ito.js → pipeline-notifier-DvHLaXKb.js} +1 -1
- package/server/{post-merge-lifecycle-worker-KK1RTKRE.js → post-merge-lifecycle-worker-DAWgzXQA.js} +3 -3
- package/server/{post-merge-state-_Lj3LDLh.js → post-merge-state-DC2_0t12.js} +4 -4
- package/server/prd-locations-BbAvqQmT.js +124 -0
- package/server/{project-pipelines-CCkebHOu.js → project-pipelines-By_5WcT4.js} +2 -2
- package/server/{project-repos-B4MK48j4.js → project-repos--QeCg7yQ.js} +29 -3
- package/server/project-repos-3bI6t4fO.js +3 -0
- package/server/project-resource-refresh-queue-BaZC79S3.js +2 -0
- package/server/project-resource-refresh-queue-x-K9mvpP.js +865 -0
- package/server/{projects-DvPEAP18.js → projects-LftaVK99.js} +1 -1
- package/server/{prompts-BiS5I2tZ.js → prompts-BotGu-6W.js} +2 -2
- package/server/{providers-DrfK0Ip8.js → providers-BL1I66sM.js} +7 -7
- package/server/providers-Dqgz3MY5.js +3 -0
- package/server/public/assets/{chunk-BO2N2NFS-GtVe_o56.js → chunk-BO2N2NFS-D5Fz5jND.js} +4 -4
- package/server/public/assets/{diagram-OG6HWLK6-BvhcYYHc.js → diagram-OG6HWLK6-Eux0gWFq.js} +1 -1
- package/server/public/assets/{dist-D0ryefak.js → dist-C3zShwhA.js} +1 -1
- package/server/public/assets/{dist-CSmUXazd.js → dist-D-JX_u7m.js} +3 -3
- package/server/public/assets/{ganttDiagram-6RSMTGT7-BXA51DzM.js → ganttDiagram-6RSMTGT7-UH3aweia.js} +1 -1
- package/server/public/assets/{highlighted-body-OFNGDK62-mlV4EpWt.js → highlighted-body-OFNGDK62-ccIQ-WXS.js} +1 -1
- package/server/public/assets/index-2wV4ipy_.css +1 -0
- package/server/public/assets/index-BTVcdPve.js +860 -0
- package/server/public/assets/{linear-BPE7oswm.js → linear-Cnnu4YQy.js} +1 -1
- package/server/public/assets/mermaid-GHXKKRXX-Bjto8iJh.js +1 -0
- package/server/public/assets/{pieDiagram-4H26LBE5-BguGGV3S.js → pieDiagram-4H26LBE5-BD8-Tye6.js} +1 -1
- package/server/public/assets/{prod-aKDYUrXQ.js → prod-Ca6aKMts.js} +4 -4
- package/server/public/assets/{quadrantDiagram-W4KKPZXB-Bx3i4B6H.js → quadrantDiagram-W4KKPZXB-BmSrVyFD.js} +1 -1
- package/server/public/assets/{sankeyDiagram-5OEKKPKP-B5vuLjA4.js → sankeyDiagram-5OEKKPKP-CEGy8Das.js} +1 -1
- package/server/public/assets/{xychartDiagram-2RQKCTM6-HPlpkqsN.js → xychartDiagram-2RQKCTM6-VnQ8iY8s.js} +1 -1
- package/server/public/index.html +2 -2
- package/server/{pull-requests-BcHIsFJv.js → pull-requests-Cp_FDT8-.js} +3 -3
- package/server/pull-requests-jVGcVq5G.js +2 -0
- package/server/rally-CxhVgIQ6.js +3 -0
- package/server/{rally-api-ShZ4kvn0.js → rally-api-CqAIJ8RX.js} +2 -2
- package/server/{rally-api-u_vkr5c_.js → rally-api-Ij1Zt0NI.js} +1 -1
- package/server/{rally-B1OMtzch.js → rally-bQpBzUNf.js} +3 -3
- package/server/{rally-client-DgZvUZqX.js → rally-client-CN5vh4Ac.js} +1 -1
- package/server/{rally-client-D6Feq1Ka.js → rally-client-qKbCNRVW.js} +5 -5
- package/server/{reap-terminal-sessions-CRfiXLY0.js → reap-terminal-sessions-BaDSNR-k.js} +2 -2
- package/server/{reap-terminal-sessions-D7f3zSE9.js → reap-terminal-sessions-DgEIKMhH.js} +2 -2
- package/server/{rebuild-stack-DKxOnkpE.js → rebuild-stack-BNOMVh7C.js} +7 -7
- package/server/{rebuild-stack-CCwKHZb6.js → rebuild-stack-DrMyA_mA.js} +2 -2
- package/server/{reconstruct-cache-BP8UIKt7.js → reconstruct-cache-mxIYCnqs.js} +7 -7
- package/server/{record-By-wp6pg.js → record-Ug18Cp4V.js} +1 -1
- package/server/{record-update-ByGtIlUK.js → record-update-WyhsREoH.js} +1 -1
- package/server/{record-update-D23jPU6b.js → record-update-dBGxL9OC.js} +8 -6
- package/server/{recovery-trip-C4dTl8DO.js → recovery-trip-BKLrL6NX.js} +43 -10
- package/server/{recovery-trip-qloOYOFz.js → recovery-trip-wFAixKsg.js} +1 -1
- package/server/{release-engine-Crc0Tjx-.js → release-engine-D9gaCBn9.js} +5 -5
- package/server/{release-set-DDXwbIK7.js → release-set-DPHHzEGx.js} +3 -3
- package/server/{remote-CBpLi4Yy.js → remote-BU6ONLpv.js} +3 -3
- package/server/{remote-oEMfXlwT.js → remote-BUEeUic6.js} +3 -3
- package/server/{remote-agents-DQVGZVQ9.js → remote-agents-BVtASiOF.js} +1 -1
- package/server/{remote-agents-Bgtc2nOO.js → remote-agents-CSaTLi3u.js} +6 -6
- package/server/{remote-completion-DxUJ5HKR.js → remote-completion-CBV3b9TI.js} +13 -13
- package/server/{resolver-C8rooxoz.js → resolver-DvSMXty7.js} +31 -8
- package/server/{resolver-CuAULbLs.js → resolver-gxv97jsQ.js} +2 -2
- package/server/resume-DvHuF-bm.js +3 -0
- package/server/review-agent-DgkUPRx0.js +3 -0
- package/server/{review-agent-7C2w5CzU.js → review-agent-esZ0QXdY.js} +43 -55
- package/server/{review-artifacts-BJeEfm2r.js → review-artifacts-DGGEobLp.js} +6 -6
- package/server/{review-convoy-liveness-DfF9eXjI.js → review-convoy-liveness-DmO8dIBH.js} +20 -11
- package/server/{review-run-recovery-7BKt2Es0.js → review-run-recovery-Ct0q7FkE.js} +3 -3
- package/server/{review-run-recovery-ZjuDTNhZ.js → review-run-recovery-DHiiw7d8.js} +1 -1
- package/server/{review-status-CUnjjOUu.js → review-status-C_kQeeX0.js} +1 -1
- package/server/{review-status-emit-Cg4tOb8U.js → review-status-emit-BZz1Y_22.js} +3 -3
- package/server/{review-status-enrichment-D-rQshu6.js → review-status-enrichment-BWH0XW_m.js} +3 -3
- package/server/{review-status-source-DSn0glLa.js → review-status-source-D2PCWS6E.js} +1 -1
- package/server/{review-status-source-Ct912fv_.js → review-status-source-Jq0BXmn3.js} +1 -1
- package/server/{review-status-sync-B7V_Gg51.js → review-status-sync-2C9lk85r.js} +2 -2
- package/server/{review-status-sync-YthpOH_q.js → review-status-sync-Bq00Loey.js} +1 -1
- package/server/{review-status-DBnR5t4z.js → review-status-yOGD2MuK.js} +86 -27
- package/server/{review-verdict-feedback-DqXTuJk8.js → review-verdict-feedback-Brjaxoda.js} +1 -1
- package/server/{review-verdict-feedback-C-dBon_-.js → review-verdict-feedback-CE_tr2iQ.js} +8 -8
- package/server/{review-verdict-writer-jldSh3Bm.js → review-verdict-writer-CD-4kDVx.js} +1 -1
- package/server/{review-verdict-writer-CKaJWp75.js → review-verdict-writer-Ca2V7QSY.js} +7 -7
- package/server/{rollup-DZwH4CLs.js → rollup--g9ik1XQ.js} +1 -1
- package/server/{rollup-QCwYcBdP.js → rollup-B6g9Nr6L.js} +8 -8
- package/server/{scanner-2aHeLC3W.js → scanner-YxIv-fG1.js} +8 -8
- package/server/{search-DwHYaj66.js → search-DqMN4__-.js} +2 -2
- package/server/{secret-redaction-B5G1xZ3k.js → secret-redaction-DLZ-VqHq.js} +1 -1
- package/server/{sequence-io-POKWdusG.js → sequence-io--b3_PsWq.js} +4 -4
- package/server/{sequencer-agent-DS00KHVm.js → sequencer-agent-CqouKVZG.js} +6 -6
- package/server/server.js +1115 -1269
- package/server/{service-BLb_CyPL.js → service-CEp-3iow.js} +64 -63
- package/server/{session-fork-DcTzVwex.js → session-fork-GtoeCh2H.js} +2 -2
- package/server/{settings-Clw8UVNs.js → settings-CLQcdkoD.js} +2 -2
- package/server/{settings-B9-H2K_E.js → settings-Ch2pCVtt.js} +3 -3
- package/server/settings-DhtPDmmI.js +2 -0
- package/server/{shadow-engineering-C6oO_PiR.js → shadow-engineering-BxiFrIKv.js} +3 -3
- package/server/{shadow-state-CEGrrECe.js → shadow-state-CSA1vtxr.js} +2 -2
- package/server/{shadow-state-e7250VUx.js → shadow-state-nGhCNXT2.js} +1 -1
- package/server/{shadow-utils-xFk2Wusb.js → shadow-utils-7q5QDmMj.js} +2 -2
- package/server/{ship-log-7BnQHuKU.js → ship-log-ie0A_SqV.js} +1 -1
- package/server/{ship-record-CwUX6Afo.js → ship-record-BM3oVvnL.js} +7 -7
- package/server/{ship-record-BgUPnpT0.js → ship-record-DHWH1hLz.js} +1 -1
- package/server/{ship-status-Ce3_3edi.js → ship-status-BEkddXMT.js} +2 -2
- package/server/{smart-compaction-BmfIi3oL.js → smart-compaction-BkzjVpWL.js} +1 -1
- package/server/{smart-compaction-Dy0gw1VH.js → smart-compaction-D0TE1lBD.js} +7 -7
- package/server/{spawn-planning-session-nH3b4Drz.js → spawn-planning-session-CkGweSCC.js} +19 -19
- package/server/{spawn-planning-session-CfhxRJoY.js → spawn-planning-session-s406rw1N.js} +2 -2
- package/server/{specialist-completion-CC1XJbTx.js → specialist-completion-CTAjwH5j.js} +1 -1
- package/server/{specialist-context-cHwpcXSh.js → specialist-context-CKasRfYu.js} +5 -5
- package/server/{specialist-handoff-logger-GqnGSYoJ.js → specialist-handoff-logger-DrjrOmmn.js} +2 -2
- package/server/{specialist-logs-5OTnrV91.js → specialist-logs-Du6quZ0_.js} +3 -3
- package/server/{specialists-xXcJHAyg.js → specialists-B-4zyE4Y.js} +1 -1
- package/server/{specialists-8LcQi9Np.js → specialists-CuDWiNdB.js} +21 -272
- package/server/{specialists-DocAK-7A.js → specialists-b0dMMjWq.js} +148 -685
- package/server/specialists-registry-1y6Rt_F1.js +3 -0
- package/server/specialists-registry-BYjs04iK.js +277 -0
- package/server/specialists-x-kPMhrL.js +4 -0
- package/server/specs-IYsFlM-L.js +3 -0
- package/server/{src-DudQNYVw.js → src-CY2Wl8IX.js} +337 -6
- package/server/{src-C2TAxwki.js → src-CZsPs61V.js} +6 -6
- package/server/{src-DUVvEA8Q.js → src-DeQwpuh6.js} +3 -3
- package/server/{stack-health-DKT4ySnA.js → stack-health-BQFSJc0l.js} +3 -3
- package/server/{stack-health-CbyiYS9H.js → stack-health-ypIKtkbE.js} +1 -1
- package/server/{stale-task-claims-PzFee70R.js → stale-task-claims-C2e1zdMT.js} +5 -5
- package/server/{staleness-BjOAq9-d.js → staleness-CRDK6LFG.js} +1 -1
- package/server/{staleness-D8UTEXV5.js → staleness-Fzx_3_Hr.js} +1 -1
- package/server/{stall-sweeper-DOyIfeLR.js → stall-sweeper-QNk4h9m6.js} +8 -8
- package/server/{state-home-DhAZlk5k.js → state-home-DdG8erBI.js} +2 -2
- package/server/{state-mapping-BVSs84bO.js → state-mapping-D2yC81Vy.js} +1 -1
- package/server/{state-migrate-CJKEwpB0.js → state-migrate-C6H3jfHE.js} +6 -6
- package/server/{state-mirror-Do7pag7W.js → state-mirror-DF4Lfxm0.js} +3 -3
- package/server/stuck-remediation-BDa_tXgB.js +774 -0
- package/server/stuck-remediation-BVNd9txd.js +2 -0
- package/server/{substrate-bug-weights-service-BTNjHBnl.js → substrate-bug-weights-service-BbbCZEtJ.js} +3 -3
- package/server/{summary-fork-CZ88rhVx.js → summary-fork-BvcW6bq0.js} +113 -30
- package/server/{summary-fork-CvB7Oyq9.js → summary-fork-DIQmtOuV.js} +2 -2
- package/server/supervisor/{pane-composer-BaLLspSj.js → pane-composer-CoiVkGIt.js} +8 -1
- package/server/supervisor/{paths-D6XUcR_g.js → paths-DTGbtcaP.js} +8 -4
- package/server/supervisor/pty-supervisor.js +3 -3
- package/server/supervisor/{pty-token-DjjHxoCq.js → pty-token-GVqnvU3U.js} +2 -2
- package/server/{supervisor-D4v0WfiQ.js → supervisor-D3jC2c7A.js} +4 -4
- package/server/supervisor-v0cYN2Vp.js +2 -0
- package/server/{swarm-readiness-D8R-LWX5.js → swarm-readiness-CMWAQuWM.js} +3 -3
- package/server/{synthesis-verdict-B6wvLGcA.js → synthesis-verdict-C-pJOPsn.js} +1 -1
- package/server/{synthesis-verdict-N5Z11pg7.js → synthesis-verdict-DVlrLF9A.js} +2 -2
- package/server/{system-prerequisites-BbGZ_WHF.js → system-prerequisites-QKtIYXI2.js} +2 -2
- package/server/{teardown-workspace-CYend-KY.js → teardown-workspace-cJea1OLo.js} +16 -16
- package/server/{test-agent-queue-BUtWhNcc.js → test-agent-queue-C5DI_gWX.js} +6 -6
- package/server/{test-verdict-BWm3hgDj.js → test-verdict-C7kmd2_Y.js} +1 -1
- package/server/{test-verdict-BWtRmdiR.js → test-verdict-DUbDHqeD.js} +2 -2
- package/server/{tldr-daemon-CneJ24eL.js → tldr-daemon-BNQHwblU.js} +1 -1
- package/server/{tldr-daemon-CMVBT4kT.js → tldr-daemon-CO08YlfQ.js} +2 -2
- package/server/tmux-B8zsqD_6.js +4 -0
- package/server/{tmux-BqXzRuaH.js → tmux-DWEc4Ld9.js} +91 -19
- package/server/{token-CO3INKbh.js → token-Bez-qCB2.js} +2 -2
- package/server/{token-util-DyJJyX_B.js → token-util-Crcay9j_.js} +1 -1
- package/server/token-util-DfUS3Lpp.js +3 -0
- package/server/{tracker-config-DVzhaUxO.js → tracker-config-CJzPhSHv.js} +2 -2
- package/server/{tracker-utils-xnVJVrrO.js → tracker-utils-DJAOAuMN.js} +2 -2
- package/server/{traefik-connect-A5k54mCv.js → traefik-connect-D3H5I6b9.js} +1 -1
- package/server/{tunnel-DauSR-rs.js → tunnel-BSdKnW0U.js} +1 -1
- package/server/{tunnel-CwOnS-PB.js → tunnel-Cr3ctqxp.js} +3 -3
- package/server/{typed-errors-B-gfU2RB.js → typed-errors-CZ3GFBvo.js} +1 -1
- package/server/{typed-errors-DzC4zXbI.js → typed-errors-DXqf3RnP.js} +1 -1
- package/server/{types-DjpLVpsj.js → types-fzBp9cYi.js} +1 -1
- package/server/{types-DbxY2QB6.js → types-pLpbsNto.js} +1 -1
- package/server/{uat-failure-feedback-BVqsWlrr.js → uat-failure-feedback-IZQ-J8jt.js} +5 -5
- package/server/{uat-promote-verification-DmG097QS.js → uat-promote-verification-DXApKcc2.js} +5 -5
- package/server/{uat-train-COSy-vEX.js → uat-train-CycEzpbE.js} +1 -1
- package/server/{uat-train-DVUNW03P.js → uat-train-IIZlz7r3.js} +0 -0
- package/server/{validate-Dvv83iBx.js → validate-Ur4xH5bN.js} +3 -3
- package/server/{validation-BdCjzWLN.js → validation-CHovCoTT.js} +1 -1
- package/server/{validation-DlHafKzu.js → validation-Dr6V4PXx.js} +9 -6
- package/server/{verification-artifact-CaSbxUVg.js → verification-artifact-D3viYe_t.js} +1 -1
- package/server/{verification-artifact-0Zku8N-W.js → verification-artifact-k5Ftpg0c.js} +1 -1
- package/server/{verification-runner-C6wdZda2.js → verification-runner-BuqGwm2t.js} +1 -1
- package/server/{verification-runner-DwP2fUEF.js → verification-runner-Dl13mmsI.js} +53 -27
- package/server/{vtt-parser-luerJpYT.js → vtt-parser-BSnAB-Og.js} +1 -1
- package/server/work-agent-prompt-CJJ4tXci.js +3 -0
- package/server/{work-agent-prompt--9AWNYwZ.js → work-agent-prompt-CioeOuM4.js} +14 -14
- package/server/{work-agent-start-BNQO65W7.js → work-agent-start-B65Gqn9N.js} +2 -2
- package/server/{work-agent-start-DkzseQFl.js → work-agent-start-Ct1HVh6z.js} +1 -1
- package/server/{workflows-BYwR2aIN.js → workflows-AgFul1xc.js} +114 -41
- package/server/workflows-CfHm8lVd.js +2 -0
- package/server/{workspace-B-QJa3Ps.js → workspace-Cu3XlMXt.js} +1 -1
- package/server/{workspace-iTnTycOB.js → workspace-Cy4sDd3q.js} +3 -3
- package/server/{workspace-anchor-drift-DTt6h2Em.js → workspace-anchor-drift-BI0Hz6zI.js} +1 -1
- package/server/{workspace-anchor-drift-CHiGg8iu.js → workspace-anchor-drift-CMaqvizr.js} +4 -4
- package/server/{workspace-config-D0CavVtz.js → workspace-config-DRYDO7Zr.js} +1 -1
- package/server/{workspace-manager-W1OnbvU5.js → workspace-manager-CgovxDrO.js} +17 -17
- package/server/{workspace-manager-5BKPV6SY.js → workspace-manager-jfkKAEuO.js} +1 -1
- package/server/{workspace-metadata-tbbevEmP.js → workspace-metadata-BDqXzGGK.js} +1 -1
- package/server/{workspace-metadata-dJhXvZGQ.js → workspace-metadata-BNzODIv6.js} +2 -2
- package/server/{workspaces-BlpbOPZ7.js → workspaces-BJdPqx_J.js} +131 -127
- package/sync-sources/dev-skills/pan-style-guide/SKILL.md +90 -15
- package/sync-sources/hooks/linear-mcp-auth-hook +6 -1
- package/sync-sources/rules/handoff-isolate-cwd.md +4 -4
- package/sync-sources/rules/pan-handoff-focus-limit.md +12 -5
- package/sync-sources/rules/ste-writing.md +17 -0
- package/sync-sources/rules/work-agents-via-pan.md +2 -1
- package/sync-sources/rules/writing-style.md +3 -2
- package/sync-sources/skills/{skill-creator → claude-skill-creator}/SKILL.md +1 -1
- package/sync-sources/skills/{skill-creator → claude-skill-creator}/scripts/init_skill.py +1 -1
- package/sync-sources/skills/{skill-creator → claude-skill-creator}/scripts/package_skill.py +1 -1
- package/sync-sources/skills/pan-gauntlet-loop/SKILL.md +182 -0
- package/sync-sources/skills/pan-gauntlet-loop/assets/PROMPT.template.md +92 -0
- package/sync-sources/skills/pan-gauntlet-loop/assets/REFERENCE-BAR.template.md +53 -0
- package/sync-sources/skills/pan-gauntlet-loop/assets/STYLE.template.md +41 -0
- package/sync-sources/skills/pan-gauntlet-loop/assets/gauntlet-index.html +237 -0
- package/sync-sources/skills/pan-gauntlet-loop/references/domains.md +106 -0
- package/sync-sources/skills/pan-gauntlet-loop/references/lessons.md +60 -0
- package/sync-sources/skills/pan-handoff/SKILL.md +13 -6
- package/sync-sources/skills/pan-help/SKILL.md +1 -1
- package/sync-sources/skills/pan-peer-review/SKILL.md +3 -3
- package/sync-sources/skills/pan-restart/SKILL.md +6 -3
- package/sync-sources/skills/pan-start/SKILL.md +3 -0
- package/sync-sources/skills/pan-swarm/SKILL.md +32 -44
- package/sync-sources/skills/pan-sync/SKILL.md +1 -1
- package/server/activity-logger-BejO16Am.js +0 -3
- package/server/agent-state-DH_-Jkua.js +0 -3
- package/server/agents-megfmQHM.js +0 -3
- package/server/archive-planning-C-H9cM_J.js +0 -2
- package/server/build-info-PQlh_Rhb.js +0 -2
- package/server/cli-TaZspPHS.js +0 -2
- package/server/cliproxy-36ncAXlu.js +0 -3
- package/server/context-layers-CF6zHws4.js +0 -4
- package/server/conversations-AnGJ5rtX.js +0 -3
- package/server/deacon-BEH-IY0v.js +0 -5
- package/server/deacon-swarm-BHX-kR1b.js +0 -2
- package/server/deacon-swarm-BiLfNm_v.js +0 -1522
- package/server/dead-end-trip-BWpDg1Qd.js +0 -2
- package/server/delivery-cJM6zRjJ.js +0 -3
- package/server/deploy-queue-CmVBZEja.js +0 -2
- package/server/dist-VKBfkdi7.js +0 -3
- package/server/durable-review-pipeline-DgcVCYDL.js +0 -3
- package/server/factory-D4V2wd_V.js +0 -717
- package/server/forge-CrP1L3i6.js +0 -2
- package/server/hume-1ubD_6O7.js +0 -3
- package/server/inspect-agent-CfxERkNt.js +0 -2
- package/server/merge-ops-DtHx17Vd.js +0 -2
- package/server/merge-rebase-BvB4UuNS.js +0 -2
- package/server/project-repos-BJiShUsN.js +0 -3
- package/server/providers-CStNGwze.js +0 -3
- package/server/public/assets/index-BFEwfmqX.js +0 -860
- package/server/public/assets/index-_USwyTAT.css +0 -1
- package/server/public/assets/mermaid-GHXKKRXX-Dsln95SK.js +0 -1
- package/server/pull-requests-C1Cqp2yo.js +0 -2
- package/server/rally-CjayjUIl.js +0 -3
- package/server/resume-D7JuMCRQ.js +0 -3
- package/server/review-agent-BUNTVJK2.js +0 -2
- package/server/settings-DBWB1gsG.js +0 -2
- package/server/specialists-D8gsOCwh.js +0 -3
- package/server/specs-BqkrRnU9.js +0 -3
- package/server/stuck-remediation-Di5JYkoo.js +0 -1164
- package/server/stuck-remediation-TNM1VhZb.js +0 -2
- package/server/supervisor-DX8VsPnb.js +0 -2
- package/server/tmux-CqNapnrr.js +0 -4
- package/server/token-util-Bu8bPF9f.js +0 -3
- package/server/workflows-Cf4LAnhg.js +0 -2
|
@@ -0,0 +1,774 @@
|
|
|
1
|
+
import { Li as getOverdeckHome, Ri as init_paths, Ui as sessionFilePath } from "./config-yaml-D9nfpEx1.js";
|
|
2
|
+
import { A as listPaneValuesSync, C as init_tmux, D as killSessionSync, E as killSession, W as sessionExistsSync, i as capturePaneSync, l as detectTerminalApiErrorSync, z as sendEscapeKeyAsync } from "./tmux-DWEc4Ld9.js";
|
|
3
|
+
import { _ as logDeaconEventSync, h as init_persistent_logger } from "./agents-jXgqpHca.js";
|
|
4
|
+
import { $t as init_activity, C as markAgentTroubled, Ft as resumeAgent, Ut as messageAgent, W as getAgentRuntimeStateSync, en as resolveLatestSessionIdSync, q as init_agents, wt as init_agent_enrichment, yn as listRunningAgentsSync, yt as countPendingAskUserQuestionsForAgent } from "./agent-state-BJhGIJZe.js";
|
|
5
|
+
import { c as init_control_settings, i as getFlywheelActiveRunId, p as isFlywheelGloballyPaused } from "./control-settings-BMoDHY1G.js";
|
|
6
|
+
import { h as readWorkspacePlanSync, s as init_io } from "./io-DKrWd3gX.js";
|
|
7
|
+
import { a as getDispatchableItems, c as init_dag } from "./dag-BPc74hwj.js";
|
|
8
|
+
import { a as loadCloisterConfigSync, r as init_config, t as DEFAULT_CLOISTER_CONFIG } from "./config-Doq_tF-f.js";
|
|
9
|
+
import { d as getReviewStatusSync, p as init_review_status } from "./review-status-yOGD2MuK.js";
|
|
10
|
+
import { n as getAgentWorkActivityMs, r as isAgentIdleForNudge, t as getAgentEffectiveLastActivityMs } from "./agent-idle-ONBssBN_.js";
|
|
11
|
+
import { i as recordRecoveryFailure, r as init_recovery_trip } from "./recovery-trip-BKLrL6NX.js";
|
|
12
|
+
import { Effect } from "effect";
|
|
13
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "fs";
|
|
14
|
+
import { join } from "path";
|
|
15
|
+
//#region ../../lib/cloister/agent-death.ts
|
|
16
|
+
init_persistent_logger();
|
|
17
|
+
init_config();
|
|
18
|
+
init_activity();
|
|
19
|
+
init_agent_enrichment();
|
|
20
|
+
init_agents();
|
|
21
|
+
init_review_status();
|
|
22
|
+
/**
|
|
23
|
+
* Agent death diagnostics (PAN-2108).
|
|
24
|
+
*
|
|
25
|
+
* When an ohmypi/pi agent process dies, the launcher records its exit code +
|
|
26
|
+
* timestamp to `<agentDir>/exit-status` (see buildOhmypiCommand in
|
|
27
|
+
* launcher-generator.ts), and omp's stdout/stderr is captured to
|
|
28
|
+
* `<agentDir>/output.log`. This module turns those into a one-line death reason
|
|
29
|
+
* the deacon can log, replacing the opaque "session is dead" with an actual
|
|
30
|
+
* cause — the gap that made the flywheel orchestrator's silent death
|
|
31
|
+
* undiagnosable in RUN-30.
|
|
32
|
+
*/
|
|
33
|
+
init_paths();
|
|
34
|
+
init_tmux();
|
|
35
|
+
function agentDir(agentId) {
|
|
36
|
+
return join(getOverdeckHome(), "agents", agentId);
|
|
37
|
+
}
|
|
38
|
+
/** Read the launcher-recorded exit code + UTC timestamp, or null if absent. */
|
|
39
|
+
function readAgentExitStatus(agentId) {
|
|
40
|
+
try {
|
|
41
|
+
const p = join(agentDir(agentId), "exit-status");
|
|
42
|
+
if (!existsSync(p)) return null;
|
|
43
|
+
const raw = readFileSync(p, "utf-8").trim();
|
|
44
|
+
if (!raw) return null;
|
|
45
|
+
const [code, at = ""] = raw.split(/\s+/);
|
|
46
|
+
return {
|
|
47
|
+
code: code ?? "?",
|
|
48
|
+
at
|
|
49
|
+
};
|
|
50
|
+
} catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Best-effort one-line description of why an agent process died: the
|
|
56
|
+
* launcher-recorded exit status (preferred), the tmux pane exit status (fallback
|
|
57
|
+
* when the dead pane corpse still exists), and the tail of output.log.
|
|
58
|
+
*/
|
|
59
|
+
function describeAgentDeath(agentId) {
|
|
60
|
+
const parts = [];
|
|
61
|
+
const exit = readAgentExitStatus(agentId);
|
|
62
|
+
if (exit) parts.push(`exit=${exit.code}${exit.at ? ` at ${exit.at}` : ""}`);
|
|
63
|
+
else if (sessionExistsSync(agentId)) {
|
|
64
|
+
const paneExit = listPaneValuesSync(agentId, "#{pane_exit_status}").find((v) => v !== "");
|
|
65
|
+
if (paneExit) parts.push(`pane_exit=${paneExit}`);
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
const logPath = join(agentDir(agentId), "output.log");
|
|
69
|
+
if (existsSync(logPath)) {
|
|
70
|
+
const tail = readFileSync(logPath, "utf-8").slice(-1500).trim().split("\n").slice(-6).join(" | ").trim();
|
|
71
|
+
if (tail) parts.push(`output.log tail: ${tail}`);
|
|
72
|
+
}
|
|
73
|
+
} catch {}
|
|
74
|
+
return parts.length ? parts.join("; ") : "no exit trace (exit-status + output.log empty)";
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region ../../lib/cloister/stuck-remediation-state.ts
|
|
78
|
+
init_control_settings();
|
|
79
|
+
init_paths();
|
|
80
|
+
function agentStateDir(agentId) {
|
|
81
|
+
return join(getOverdeckHome(), "agents", agentId);
|
|
82
|
+
}
|
|
83
|
+
function statePath(agentId) {
|
|
84
|
+
return join(agentStateDir(agentId), "stuck-remediation.json");
|
|
85
|
+
}
|
|
86
|
+
function readStuckRemediationState(agentId) {
|
|
87
|
+
const filePath = statePath(agentId);
|
|
88
|
+
if (!existsSync(filePath)) return null;
|
|
89
|
+
try {
|
|
90
|
+
return JSON.parse(readFileSync(filePath, "utf-8"));
|
|
91
|
+
} catch (error) {
|
|
92
|
+
console.warn(`Failed to read stuck-remediation state for ${agentId}:`, error);
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function writeStuckRemediationState(agentId, state) {
|
|
97
|
+
mkdirSync(agentStateDir(agentId), { recursive: true });
|
|
98
|
+
writeFileSync(statePath(agentId), `${JSON.stringify(state, null, 2)}\n`, "utf-8");
|
|
99
|
+
}
|
|
100
|
+
function clearStuckRemediationState(agentId) {
|
|
101
|
+
const filePath = statePath(agentId);
|
|
102
|
+
if (!existsSync(filePath)) return;
|
|
103
|
+
unlinkSync(filePath);
|
|
104
|
+
}
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region ../../lib/cloister/planning-wedge.ts
|
|
107
|
+
init_io();
|
|
108
|
+
init_dag();
|
|
109
|
+
init_recovery_trip();
|
|
110
|
+
/**
|
|
111
|
+
* PAN-3677: positive transcript proof of the planning background-task wedge.
|
|
112
|
+
*
|
|
113
|
+
* The incident: planning sessions (planning-min-888 / planning-min-889) hung on
|
|
114
|
+
* the provider call that followed their background Explore children reaching a
|
|
115
|
+
* terminal state — one run with both children finished, one with a child dead
|
|
116
|
+
* from the 262,144-token model limit while its sibling finished. The mirror
|
|
117
|
+
* stayed 'active' (the Stop hook never fired), the pane kept repainting its
|
|
118
|
+
* spinner, and queued `pan tell` messages were never processed.
|
|
119
|
+
*
|
|
120
|
+
* Stuck-remediation must NEVER interrupt a turn it cannot prove is wedged: a
|
|
121
|
+
* healthy long reasoning turn is also mirror-'active' with no tool calls for
|
|
122
|
+
* a while. This module supplies the positive signature from the authoritative
|
|
123
|
+
* source — the session JSONL:
|
|
124
|
+
*
|
|
125
|
+
* 1. the parent launched at least one background child IN THE CURRENT TURN
|
|
126
|
+
* (Agent tool result: "Async agent launched successfully. … agentId: X");
|
|
127
|
+
* 2. EVERY child launched since that boundary is proven terminal, via either
|
|
128
|
+
* - a task-notification queue-operation carrying a terminal
|
|
129
|
+
* `<status>` (completed / failed / cancelled / killed), or
|
|
130
|
+
* - a TaskOutput tool result for that task id with a terminal `<status>`.
|
|
131
|
+
*
|
|
132
|
+
* TURN SCOPING: at each genuine prompt boundary — a `user` entry with
|
|
133
|
+
* string/text content (kickoff, recovery-resume seed) or a queue-operation
|
|
134
|
+
* `remove` of a non-task-notification message (a consumed `pan tell`) —
|
|
135
|
+
* children already proven TERMINAL are retired from the evidence; a closed
|
|
136
|
+
* explorer batch from earlier in the session can never keep `wedged` true
|
|
137
|
+
* through a later healthy turn (historical poisoning). Children NOT yet
|
|
138
|
+
* terminal carry across the boundary, because real background tasks outlive
|
|
139
|
+
* user turns: in the MIN-888 transcript the operator's `pan tell` was consumed
|
|
140
|
+
* while the API explorer was still running, and the wedge formed only after
|
|
141
|
+
* that child finished. `user` entries carrying tool_result parts are turn
|
|
142
|
+
* machinery, never boundaries.
|
|
143
|
+
*
|
|
144
|
+
* If proof is missing — no background children since the boundary, or any
|
|
145
|
+
* child without terminal proof — the answer is NOT wedged and the caller must
|
|
146
|
+
* not interrupt. The detector is deliberately blind to everything else
|
|
147
|
+
* (model, prompt, wall clock): those judgments live in the remediation
|
|
148
|
+
* ladder.
|
|
149
|
+
*
|
|
150
|
+
* Known limitation: a task id can notify more than once (a finished child can
|
|
151
|
+
* be resumed and run again within the same turn). Re-resume is rare in
|
|
152
|
+
* planning flows and the ladder's one-stage-per-episode guard bounds the cost
|
|
153
|
+
* of a stale read; if it ever false-fires, the interrupt is an Escape —
|
|
154
|
+
* recoverable, transcript-safe.
|
|
155
|
+
*/
|
|
156
|
+
init_paths();
|
|
157
|
+
/** Terminal background-task statuses recognized in notifications / TaskOutput results. */
|
|
158
|
+
const TERMINAL_TASK_STATUSES = new Set([
|
|
159
|
+
"completed",
|
|
160
|
+
"failed",
|
|
161
|
+
"cancelled",
|
|
162
|
+
"killed",
|
|
163
|
+
"error"
|
|
164
|
+
]);
|
|
165
|
+
function extractText(content) {
|
|
166
|
+
if (typeof content === "string") return content;
|
|
167
|
+
if (Array.isArray(content)) return content.map((part) => {
|
|
168
|
+
if (part && typeof part === "object") {
|
|
169
|
+
const p = part;
|
|
170
|
+
if (p.type === "text" && typeof p.text === "string") return p.text;
|
|
171
|
+
if (p.type === "tool_result") return extractText(p.content);
|
|
172
|
+
}
|
|
173
|
+
return "";
|
|
174
|
+
}).join("\n");
|
|
175
|
+
return "";
|
|
176
|
+
}
|
|
177
|
+
function parseTaskNotification(content) {
|
|
178
|
+
if (!content.includes("<task-notification>")) return null;
|
|
179
|
+
const taskId = /<task-id>\s*([a-z0-9]+)\s*<\/task-id>/.exec(content)?.[1];
|
|
180
|
+
if (!taskId) return null;
|
|
181
|
+
return {
|
|
182
|
+
taskId,
|
|
183
|
+
status: /<status>\s*([a-z_-]+)\s*<\/status>/i.exec(content)?.[1]?.toLowerCase() ?? null
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* True when a JSONL entry opens a new genuine user turn: a `user` entry with
|
|
188
|
+
* string or text-only content (the kickoff prompt, a recovery-resume seed),
|
|
189
|
+
* or a queue-operation `remove` of a NON-task-notification message (a
|
|
190
|
+
* consumed operator `pan tell` — the harness folds it into context at that
|
|
191
|
+
* point without writing a user entry). `user` entries made of tool_result
|
|
192
|
+
* parts are turn machinery and NEVER boundaries; task-notification
|
|
193
|
+
* queue-operations are the wedge evidence itself, also never boundaries.
|
|
194
|
+
*/
|
|
195
|
+
function isPromptBoundary(e) {
|
|
196
|
+
if (e.type === "queue-operation") {
|
|
197
|
+
const content = typeof e.content === "string" ? e.content : "";
|
|
198
|
+
return e.operation === "remove" && !content.includes("<task-notification>");
|
|
199
|
+
}
|
|
200
|
+
if (e.type !== "user") return false;
|
|
201
|
+
const content = e.message?.content;
|
|
202
|
+
if (typeof content === "string") return content.trim().length > 0;
|
|
203
|
+
if (Array.isArray(content)) {
|
|
204
|
+
const hasToolResult = content.some((p) => p && typeof p === "object" && p.type === "tool_result");
|
|
205
|
+
return content.some((p) => p && typeof p === "object" && p.type === "text") && !hasToolResult;
|
|
206
|
+
}
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Parse one session's JSONL entries (already-parsed JSON objects, in file
|
|
211
|
+
* order) into the wedge evidence. At every genuine prompt boundary (see
|
|
212
|
+
* isPromptBoundary), children already proven terminal are RETIRED — only
|
|
213
|
+
* still-running children carry into the new turn, because real background
|
|
214
|
+
* tasks outlive user turns. Unknown/malformed lines are ignored — a parser
|
|
215
|
+
* miss always degrades to "not wedged", never to a false positive.
|
|
216
|
+
*/
|
|
217
|
+
function parseBackgroundTaskWedge(entries) {
|
|
218
|
+
let launched = [];
|
|
219
|
+
let terminal = /* @__PURE__ */ new Map();
|
|
220
|
+
let consumedNotifications = /* @__PURE__ */ new Set();
|
|
221
|
+
for (const entry of entries) {
|
|
222
|
+
if (!entry || typeof entry !== "object") continue;
|
|
223
|
+
const e = entry;
|
|
224
|
+
if (isPromptBoundary(e)) {
|
|
225
|
+
launched = launched.filter((id) => !terminal.has(id));
|
|
226
|
+
terminal = new Map([...terminal].filter(([id]) => launched.includes(id)));
|
|
227
|
+
consumedNotifications = new Set([...consumedNotifications].filter((id) => launched.includes(id)));
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
if (e.type === "queue-operation") {
|
|
231
|
+
const notification = parseTaskNotification(typeof e.content === "string" ? e.content : "");
|
|
232
|
+
if (!notification) continue;
|
|
233
|
+
if (e.operation === "remove") consumedNotifications.add(notification.taskId);
|
|
234
|
+
if (notification.status && TERMINAL_TASK_STATUSES.has(notification.status)) terminal.set(notification.taskId, notification.status);
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
const content = e.message?.content;
|
|
238
|
+
if (!Array.isArray(content)) continue;
|
|
239
|
+
for (const part of content) {
|
|
240
|
+
if (!part || typeof part !== "object") continue;
|
|
241
|
+
const p = part;
|
|
242
|
+
if (p.type !== "tool_result") continue;
|
|
243
|
+
const text = extractText(p.content);
|
|
244
|
+
if (text.includes("Async agent launched successfully")) {
|
|
245
|
+
const agentId = /agentId:\s*([a-z0-9]+)/.exec(text)?.[1];
|
|
246
|
+
if (agentId && !launched.includes(agentId)) launched.push(agentId);
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
if (text.includes("<retrieval_status>")) {
|
|
250
|
+
const taskId = /<task_id>\s*([a-z0-9]+)\s*<\/task_id>/.exec(text)?.[1];
|
|
251
|
+
const status = /<status>\s*([a-z_-]+)\s*<\/status>/i.exec(text)?.[1]?.toLowerCase();
|
|
252
|
+
if (taskId && status && TERMINAL_TASK_STATUSES.has(status)) {
|
|
253
|
+
terminal.set(taskId, status);
|
|
254
|
+
consumedNotifications.add(taskId);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
const terminalTaskIds = launched.filter((id) => terminal.has(id));
|
|
260
|
+
const nonTerminalTaskIds = launched.filter((id) => !terminal.has(id));
|
|
261
|
+
const unconsumedTerminalTaskIds = terminalTaskIds.filter((id) => !consumedNotifications.has(id));
|
|
262
|
+
return {
|
|
263
|
+
launchedTaskIds: launched,
|
|
264
|
+
terminalTaskIds,
|
|
265
|
+
nonTerminalTaskIds,
|
|
266
|
+
unconsumedTerminalTaskIds,
|
|
267
|
+
wedged: launched.length > 0 && nonTerminalTaskIds.length === 0
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Read a session JSONL and return its wedge evidence, or null when the file
|
|
272
|
+
* cannot be read/parsed — callers treat null as "not proven", never as wedged.
|
|
273
|
+
*/
|
|
274
|
+
function readBackgroundTaskWedgeEvidence(sessionPath) {
|
|
275
|
+
let raw;
|
|
276
|
+
try {
|
|
277
|
+
raw = readFileSync(sessionPath, "utf-8");
|
|
278
|
+
} catch {
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
const entries = [];
|
|
282
|
+
for (const line of raw.split("\n")) {
|
|
283
|
+
if (!line.trim()) continue;
|
|
284
|
+
try {
|
|
285
|
+
entries.push(JSON.parse(line));
|
|
286
|
+
} catch {}
|
|
287
|
+
}
|
|
288
|
+
return parseBackgroundTaskWedge(entries);
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Resolve an agent's CURRENT session through the production resolver
|
|
292
|
+
* (resolveLatestSessionIdSync — the same door resumeAgent uses) and parse its
|
|
293
|
+
* live JSONL. Returns null when there is no resumable session or no readable
|
|
294
|
+
* transcript — always degrading to "not proven".
|
|
295
|
+
*/
|
|
296
|
+
function readAgentBackgroundTaskWedgeEvidence(agentId, workspace) {
|
|
297
|
+
const sessionId = resolveLatestSessionIdSync(agentId).sessionId;
|
|
298
|
+
if (!sessionId) return null;
|
|
299
|
+
return readBackgroundTaskWedgeEvidence(sessionFilePath(workspace, sessionId));
|
|
300
|
+
}
|
|
301
|
+
//#endregion
|
|
302
|
+
//#region ../../lib/cloister/stuck-remediation.ts
|
|
303
|
+
init_tmux();
|
|
304
|
+
function issueIdForAgent(agent) {
|
|
305
|
+
return agent.issueId || agent.id.replace(/^agent-/, "").toUpperCase();
|
|
306
|
+
}
|
|
307
|
+
function shouldSkipReviewStatus(status) {
|
|
308
|
+
if (!status) return false;
|
|
309
|
+
if (status.stuck || status.deaconIgnored || status.mergeStatus === "merged" || status.readyForMerge) return true;
|
|
310
|
+
if (status.reviewStatus === "blocked" || status.reviewStatus === "failed") return true;
|
|
311
|
+
if (status.verificationStatus === "failed" || status.testStatus === "failed") return true;
|
|
312
|
+
if (status.reviewStatus === "reviewing" || status.reviewStatus === "passed") return true;
|
|
313
|
+
return status.reviewStatus === "pending" && !!status.reviewRequestedAt;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* PAN-2581 (FR-2, residual): phase gate for the health-check poke loop
|
|
317
|
+
* (service.ts pokeAgent → pokeAgentWithEscalation → idle-alive pause), the
|
|
318
|
+
* SECOND independent idleness consumer besides stuck-remediation. A warm-idle
|
|
319
|
+
* work agent on a pipeline-owned issue — and a warm-idle review/test agent
|
|
320
|
+
* after its verdict — must never be poked ("are you stuck?") or idle-alive
|
|
321
|
+
* paused: the poke spends tokens re-explaining the wait, and the pause
|
|
322
|
+
* manufactures the paused-delivery-target deadlock PAN-2461 exists to undo.
|
|
323
|
+
* A genuinely stalled mid-review parent is covered by the PAN-2584 liveness
|
|
324
|
+
* deadline, not pokes. Owed-rework agents (review blocked/failed, tests
|
|
325
|
+
* failed) are ALSO skipped here by design: shouldSkipReviewStatus returns
|
|
326
|
+
* true for those because the PAN-2519 wedged-rework path owns their
|
|
327
|
+
* escalation — the health-check poke loop must not double-drive them.
|
|
328
|
+
* Roles outside work/review/test (plan, strike, flywheel, sequencer) keep
|
|
329
|
+
* their existing idleness semantics.
|
|
330
|
+
*/
|
|
331
|
+
function shouldSkipIdlePokeForAgent(agent, readStatus = getReviewStatusSync) {
|
|
332
|
+
if (!agent) return false;
|
|
333
|
+
if (agent.role !== "work" && agent.role !== "review" && agent.role !== "test") return false;
|
|
334
|
+
return shouldSkipReviewStatus(readStatus((agent.issueId || agent.id.replace(/^agent-/, "").replace(/-(review|test|ship)(-.*)?$/, "").replace(/-slot-\d+$/, "")).toUpperCase()));
|
|
335
|
+
}
|
|
336
|
+
function hasPendingRework(status) {
|
|
337
|
+
if (!status) return false;
|
|
338
|
+
if (status.stuck || status.deaconIgnored || status.mergeStatus === "merged" || status.readyForMerge) return false;
|
|
339
|
+
return status.reviewStatus === "blocked" || status.reviewStatus === "failed" || status.verificationStatus === "failed" || status.testStatus === "failed";
|
|
340
|
+
}
|
|
341
|
+
const STUCK_KILL_REQUEUE_CEILING = 25;
|
|
342
|
+
async function evaluateWedgedReworkAgent(agent, config, now, actions) {
|
|
343
|
+
const agentId = agent.id;
|
|
344
|
+
if (agent.role !== "work" || !agent.workspace) return false;
|
|
345
|
+
const issueId = issueIdForAgent(agent);
|
|
346
|
+
const status = getReviewStatusSync(issueId);
|
|
347
|
+
if (!hasPendingRework(status)) return false;
|
|
348
|
+
const lastActivityMs = getAgentEffectiveLastActivityMs(agentId);
|
|
349
|
+
if (lastActivityMs === null || !Number.isFinite(lastActivityMs)) return false;
|
|
350
|
+
const stuckState = readStuckRemediationState(agentId);
|
|
351
|
+
if (stuckState) {
|
|
352
|
+
const firstStuckMs = new Date(stuckState.firstStuckAt).getTime();
|
|
353
|
+
if (Number.isFinite(firstStuckMs) && lastActivityMs > firstStuckMs) {
|
|
354
|
+
clearStuckRemediationState(agentId);
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
const idleMinutes = Math.floor((now - lastActivityMs) / 6e4);
|
|
359
|
+
const lastStage = stuckState?.lastStage ?? 0;
|
|
360
|
+
if (idleMinutes < config.stage3_minutes || lastStage >= 3) return false;
|
|
361
|
+
const firstStuck = firstStuckAt(new Date(lastActivityMs).toISOString(), stuckState);
|
|
362
|
+
if ((status?.autoRequeueCount ?? 0) >= STUCK_KILL_REQUEUE_CEILING) {
|
|
363
|
+
markAgentTroubled(agentId);
|
|
364
|
+
writeStuckRemediationState(agentId, stageState(3, now, firstStuck));
|
|
365
|
+
logAction(actions, transitionAction(3, issueId, idleMinutes, "rework-wedge-troubled"));
|
|
366
|
+
await surfaceStuckNeedsYou(agent, issueId, firstStuck, actions);
|
|
367
|
+
return true;
|
|
368
|
+
}
|
|
369
|
+
killSessionSync(agentId);
|
|
370
|
+
writeStuckRemediationState(agentId, stageState(3, now, firstStuck));
|
|
371
|
+
logAction(actions, transitionAction(3, issueId, idleMinutes, "killed-for-respawn"));
|
|
372
|
+
return true;
|
|
373
|
+
}
|
|
374
|
+
function shouldCheckReadyBeadsForAgent(agent, now) {
|
|
375
|
+
const agentId = agent.id;
|
|
376
|
+
if (!agentId) return false;
|
|
377
|
+
if (agent.status !== "running") return false;
|
|
378
|
+
if (agent.role !== "work") return false;
|
|
379
|
+
if (!agent.workspace) return false;
|
|
380
|
+
const completedAt = agent.completedAt;
|
|
381
|
+
if (agent.paused || agent.troubled || completedAt) return false;
|
|
382
|
+
if (!sessionExistsSync(agentId)) return false;
|
|
383
|
+
if (shouldSkipReviewStatus(getReviewStatusSync(issueIdForAgent(agent)))) return false;
|
|
384
|
+
return isAgentIdleForNudge(agentId, 300 * 1e3, now);
|
|
385
|
+
}
|
|
386
|
+
function firstStuckAt(runtimeLastActivity, stuckState) {
|
|
387
|
+
return stuckState?.firstStuckAt ?? runtimeLastActivity;
|
|
388
|
+
}
|
|
389
|
+
function stageState(stage, now, firstStuck, prev) {
|
|
390
|
+
return {
|
|
391
|
+
lastStage: stage,
|
|
392
|
+
lastStageAt: new Date(now).toISOString(),
|
|
393
|
+
firstStuckAt: firstStuck,
|
|
394
|
+
...prev?.respawnCount !== void 0 ? { respawnCount: prev.respawnCount } : {},
|
|
395
|
+
...prev?.lastRespawnAt !== void 0 ? { lastRespawnAt: prev.lastRespawnAt } : {}
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
function transitionAction(stage, issueId, idleMinutes, action) {
|
|
399
|
+
return `[deacon] stuck-remediation stage=${stage} issue=${issueId} idleMin=${idleMinutes} action=${action}`;
|
|
400
|
+
}
|
|
401
|
+
function logAction(actions, action) {
|
|
402
|
+
actions.push(action);
|
|
403
|
+
console.log(action);
|
|
404
|
+
logDeaconEventSync(action);
|
|
405
|
+
}
|
|
406
|
+
async function surfaceStuckNeedsYou(agent, issueId, generation, actions) {
|
|
407
|
+
if (!agent.workspace) return;
|
|
408
|
+
if ((await recordRecoveryFailure(agent.workspace, issueId, "stuck-remediation", generation, 1)).emitNeedsYou) logAction(actions, `[deacon] needs-you ${issueId}: stuck remediation exhausted`);
|
|
409
|
+
}
|
|
410
|
+
async function evaluateAgent(agent, config, now, actions) {
|
|
411
|
+
const agentId = agent.id;
|
|
412
|
+
if (!agentId) return;
|
|
413
|
+
if (agent.status !== "running") return;
|
|
414
|
+
const completedAt = agent.completedAt;
|
|
415
|
+
if (agent.paused || agent.troubled || completedAt) return;
|
|
416
|
+
if (agent.role === "flywheel") {
|
|
417
|
+
await evaluateFlywheelOrchestrator(agent, config, now, actions);
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
if (!sessionExistsSync(agentId)) return;
|
|
421
|
+
if (agent.role === "plan") {
|
|
422
|
+
await evaluatePlanningAgent(agent, config, now, actions);
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
if (await evaluateWedgedReworkAgent(agent, config, now, actions)) return;
|
|
426
|
+
if (!shouldCheckReadyBeadsForAgent(agent, now)) return;
|
|
427
|
+
if (!agent.workspace) return;
|
|
428
|
+
const issueId = issueIdForAgent(agent);
|
|
429
|
+
const plan = readWorkspacePlanSync(agent.workspace);
|
|
430
|
+
if (!plan) return;
|
|
431
|
+
if (getDispatchableItems(plan, /* @__PURE__ */ new Set()).length > 0) return;
|
|
432
|
+
const lastActivityMs = getAgentEffectiveLastActivityMs(agentId);
|
|
433
|
+
if (lastActivityMs === null) return;
|
|
434
|
+
if (!Number.isFinite(lastActivityMs)) return;
|
|
435
|
+
const lastActivity = new Date(lastActivityMs).toISOString();
|
|
436
|
+
const stuckState = readStuckRemediationState(agentId);
|
|
437
|
+
if (stuckState) {
|
|
438
|
+
const firstStuckMs = new Date(stuckState.firstStuckAt).getTime();
|
|
439
|
+
if (Number.isFinite(firstStuckMs) && lastActivityMs > firstStuckMs) {
|
|
440
|
+
clearStuckRemediationState(agentId);
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
const idleMinutes = Math.floor((now - lastActivityMs) / 6e4);
|
|
445
|
+
const lastStage = stuckState?.lastStage ?? 0;
|
|
446
|
+
const firstStuck = firstStuckAt(lastActivity, stuckState);
|
|
447
|
+
const terminalProviderError = detectTerminalApiErrorSync(capturePaneSync(agentId, 80));
|
|
448
|
+
if (terminalProviderError) {
|
|
449
|
+
markAgentTroubled(agentId);
|
|
450
|
+
writeStuckRemediationState(agentId, stageState(3, now, firstStuck));
|
|
451
|
+
logAction(actions, `${agentId} provider-terminal: ${terminalProviderError.summary}`);
|
|
452
|
+
await surfaceStuckNeedsYou(agent, issueId, firstStuck, actions);
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
if (idleMinutes >= config.stage3_minutes && lastStage < 3) {
|
|
456
|
+
markAgentTroubled(agentId);
|
|
457
|
+
writeStuckRemediationState(agentId, stageState(3, now, firstStuck));
|
|
458
|
+
logAction(actions, transitionAction(3, issueId, idleMinutes, "marked-troubled"));
|
|
459
|
+
await surfaceStuckNeedsYou(agent, issueId, firstStuck, actions);
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
if (idleMinutes >= config.stage2_minutes && lastStage < 2) {
|
|
463
|
+
if ((await resumeAgent(agentId, `Resuming after auto-detected stall (${idleMinutes} min idle). Review your last work and decide whether to continue or signal done with \`pan done ${issueId}\`.`)).success) {
|
|
464
|
+
writeStuckRemediationState(agentId, stageState(2, now, firstStuck));
|
|
465
|
+
logAction(actions, transitionAction(2, issueId, idleMinutes, "resumed"));
|
|
466
|
+
} else {
|
|
467
|
+
const action = `${transitionAction(2, issueId, idleMinutes, "resume-failed")} — death: ${describeAgentDeath(agentId)}`;
|
|
468
|
+
console.warn(action);
|
|
469
|
+
logDeaconEventSync(action);
|
|
470
|
+
}
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
if (idleMinutes >= config.stage1_minutes && lastStage < 1) {
|
|
474
|
+
await messageAgent(agentId, `You appear stuck — no tool calls for ${idleMinutes} min. If your implementation is complete, run \`pan done ${issueId}\`. Otherwise reply with a one-line summary of what you're waiting on, then continue.`);
|
|
475
|
+
writeStuckRemediationState(agentId, stageState(1, now, firstStuck));
|
|
476
|
+
logAction(actions, transitionAction(1, issueId, idleMinutes, "poked"));
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
function decidePlanningWedgeRemediation(opts) {
|
|
480
|
+
const { mirrorState, pendingQuestions, wedgeProven, workActivityMs, lastStage, now, config } = opts;
|
|
481
|
+
if (pendingQuestions > 0) return { kind: "none" };
|
|
482
|
+
if (mirrorState !== "active") return { kind: "none" };
|
|
483
|
+
if (!wedgeProven) return { kind: "none" };
|
|
484
|
+
if (workActivityMs === null || !Number.isFinite(workActivityMs)) return { kind: "none" };
|
|
485
|
+
const idleMinutes = Math.floor((now - workActivityMs) / 6e4);
|
|
486
|
+
if (idleMinutes >= config.stage3_minutes) {
|
|
487
|
+
if (lastStage >= 3) return { kind: "none" };
|
|
488
|
+
return {
|
|
489
|
+
kind: "troubled",
|
|
490
|
+
idleMinutes
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
if (idleMinutes >= config.stage2_minutes) {
|
|
494
|
+
if (lastStage >= 2) return { kind: "none" };
|
|
495
|
+
return {
|
|
496
|
+
kind: "kill-resume",
|
|
497
|
+
idleMinutes
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
if (idleMinutes >= config.stage1_minutes) {
|
|
501
|
+
if (lastStage >= 1) return { kind: "none" };
|
|
502
|
+
return {
|
|
503
|
+
kind: "interrupt-nudge",
|
|
504
|
+
idleMinutes
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
return { kind: "none" };
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Episode-clear rule for the planning wedge path, keyed on WORK activity only
|
|
511
|
+
* (never pane repaints — the spinner would "clear" a still-wedged episode and
|
|
512
|
+
* re-fire stage 1 every tick): work flowing after the episode opened means the
|
|
513
|
+
* recovery worked.
|
|
514
|
+
*/
|
|
515
|
+
function shouldClearPlanningWedgeEpisode(stuckState, workActivityMs) {
|
|
516
|
+
if (!stuckState) return false;
|
|
517
|
+
const firstStuckMs = new Date(stuckState.firstStuckAt).getTime();
|
|
518
|
+
return Number.isFinite(firstStuckMs) && workActivityMs > firstStuckMs;
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Execute one wedge-ladder decision. Ordering is the contract: stage 1 sends
|
|
522
|
+
* Escape BEFORE queueing its single nudge (the interrupt returns the prompt;
|
|
523
|
+
* the nudge — and any queued operator messages — are processed after). Stage 2
|
|
524
|
+
* kills the session and plain-resumes the SAME saved session id, so the
|
|
525
|
+
* transcript (and every explorer's findings) survives — unlike the
|
|
526
|
+
* compact-respawn path that lost conversation-only survey notes in the manual
|
|
527
|
+
* MIN-889 recovery.
|
|
528
|
+
*/
|
|
529
|
+
async function executePlanningWedgeDecision(agentId, issueId, decision, firstStuck, now, deps) {
|
|
530
|
+
if (decision.kind === "interrupt-nudge") {
|
|
531
|
+
try {
|
|
532
|
+
await deps.sendEscape(agentId);
|
|
533
|
+
} catch (err) {
|
|
534
|
+
console.error(`[deacon] Failed to interrupt wedged planning session ${agentId}:`, err);
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
const message = `Your previous turn stalled for ${decision.idleMinutes} min with no progress and was interrupted (a hung provider call). Process any queued operator messages first. Then collect background-task results NON-blocking (TaskOutput with block:false) — every child that reached a terminal state already has its result or error available; do NOT re-enter a blocking wait. Continue planning now: write the PRD/xBRIEF artifacts and proceed to your instructed stopping point.`;
|
|
538
|
+
let deliveryError = null;
|
|
539
|
+
try {
|
|
540
|
+
await deps.message(agentId, message);
|
|
541
|
+
} catch (err) {
|
|
542
|
+
deliveryError = err instanceof Error ? err.message : String(err);
|
|
543
|
+
}
|
|
544
|
+
deps.writeState(agentId, stageState(1, now, firstStuck));
|
|
545
|
+
deps.log(deliveryError ? `${transitionAction(1, issueId, decision.idleMinutes, "interrupted-wedged-turn")} — nudge delivery failed: ${deliveryError}` : transitionAction(1, issueId, decision.idleMinutes, "interrupted-wedged-turn"));
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
if (decision.kind === "kill-resume") {
|
|
549
|
+
try {
|
|
550
|
+
await deps.killSession(agentId);
|
|
551
|
+
} catch {}
|
|
552
|
+
const message = `Resuming after an automated stall recovery (${decision.idleMinutes} min with no progress). Your transcript is intact — continue planning from where you left off. Collect background-task results NON-blocking (TaskOutput with block:false) and proceed.`;
|
|
553
|
+
const result = await deps.resume(agentId, message);
|
|
554
|
+
if (result.success) {
|
|
555
|
+
deps.writeState(agentId, stageState(2, now, firstStuck));
|
|
556
|
+
deps.log(transitionAction(2, issueId, decision.idleMinutes, "kill-resumed-wedged-planning"));
|
|
557
|
+
} else {
|
|
558
|
+
deps.markTroubled(agentId);
|
|
559
|
+
deps.writeState(agentId, stageState(3, now, firstStuck));
|
|
560
|
+
deps.log(`${transitionAction(3, issueId, decision.idleMinutes, "kill-resume-failed-troubled")} — ${result.error ?? "unknown"}`);
|
|
561
|
+
await deps.surfaceNeedsYou();
|
|
562
|
+
}
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
deps.markTroubled(agentId);
|
|
566
|
+
deps.writeState(agentId, stageState(3, now, firstStuck));
|
|
567
|
+
deps.log(transitionAction(3, issueId, decision.idleMinutes, "wedged-planning-troubled"));
|
|
568
|
+
await deps.surfaceNeedsYou();
|
|
569
|
+
}
|
|
570
|
+
async function evaluatePlanningAgent(agent, config, now, actions) {
|
|
571
|
+
const agentId = agent.id;
|
|
572
|
+
const issueId = issueIdForAgent(agent);
|
|
573
|
+
const pendingQuestions = await Effect.runPromise(countPendingAskUserQuestionsForAgent(agentId));
|
|
574
|
+
if (pendingQuestions > 0) {
|
|
575
|
+
if (!isAgentIdleForNudge(agentId, 300 * 1e3, now)) return;
|
|
576
|
+
if (agent.auto !== true) return;
|
|
577
|
+
const lastActivityMs = getAgentEffectiveLastActivityMs(agentId);
|
|
578
|
+
if (lastActivityMs === null || !Number.isFinite(lastActivityMs)) return;
|
|
579
|
+
const lastActivity = new Date(lastActivityMs).toISOString();
|
|
580
|
+
const stuckState = readStuckRemediationState(agentId);
|
|
581
|
+
if (stuckState) {
|
|
582
|
+
const firstStuckMs = new Date(stuckState.firstStuckAt).getTime();
|
|
583
|
+
if (Number.isFinite(firstStuckMs) && lastActivityMs > firstStuckMs) {
|
|
584
|
+
clearStuckRemediationState(agentId);
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
const idleMinutes = Math.floor((now - lastActivityMs) / 6e4);
|
|
589
|
+
const lastStage = stuckState?.lastStage ?? 0;
|
|
590
|
+
if (idleMinutes < config.stage1_minutes || lastStage >= 1) return;
|
|
591
|
+
await messageAgent(agentId, `This planning session was launched with \`pan plan ${issueId} --auto\`, so do not wait for operator input. Proceed with the most defensible default from the issue/PRD/comments, record the choice in \`plan.autoDecisions[]\` with rationale, and continue to \`pan plan finalize\`. Only halt for a genuine contradiction between authoritative inputs.`);
|
|
592
|
+
writeStuckRemediationState(agentId, stageState(1, now, firstStuckAt(lastActivity, stuckState)));
|
|
593
|
+
logAction(actions, transitionAction(1, issueId, idleMinutes, "auto-planning-default"));
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
const workActivityMs = getAgentWorkActivityMs(agentId);
|
|
597
|
+
if (workActivityMs === null || !Number.isFinite(workActivityMs)) return;
|
|
598
|
+
const stuckState = readStuckRemediationState(agentId);
|
|
599
|
+
if (shouldClearPlanningWedgeEpisode(stuckState, workActivityMs)) {
|
|
600
|
+
clearStuckRemediationState(agentId);
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
const mirrorState = getAgentRuntimeStateSync(agentId)?.state ?? null;
|
|
604
|
+
if (mirrorState !== "active") return;
|
|
605
|
+
if (Math.floor((now - workActivityMs) / 6e4) < config.stage1_minutes) return;
|
|
606
|
+
const decision = decidePlanningWedgeRemediation({
|
|
607
|
+
mirrorState,
|
|
608
|
+
pendingQuestions,
|
|
609
|
+
wedgeProven: agent.workspace ? readAgentBackgroundTaskWedgeEvidence(agentId, agent.workspace)?.wedged === true : false,
|
|
610
|
+
workActivityMs,
|
|
611
|
+
lastStage: stuckState?.lastStage ?? 0,
|
|
612
|
+
now,
|
|
613
|
+
config
|
|
614
|
+
});
|
|
615
|
+
if (decision.kind === "none") return;
|
|
616
|
+
await executePlanningWedgeDecision(agentId, issueId, decision, firstStuckAt(new Date(workActivityMs).toISOString(), stuckState), now, {
|
|
617
|
+
sendEscape: (id) => sendEscapeKeyAsync(id),
|
|
618
|
+
message: (id, msg) => messageAgent(id, msg),
|
|
619
|
+
killSession: (id) => Effect.runPromise(killSession(id)),
|
|
620
|
+
resume: (id, msg) => resumeAgent(id, msg),
|
|
621
|
+
markTroubled: (id) => markAgentTroubled(id),
|
|
622
|
+
writeState: (id, state) => writeStuckRemediationState(id, state),
|
|
623
|
+
surfaceNeedsYou: () => surfaceStuckNeedsYou(agent, issueId, firstStuckAt(new Date(workActivityMs).toISOString(), stuckState), actions),
|
|
624
|
+
log: (msg) => logAction(actions, msg)
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
const FLYWHEEL_RESPAWN_WINDOW_MS = 1800 * 1e3;
|
|
628
|
+
const FLYWHEEL_MAX_RESPAWNS = 3;
|
|
629
|
+
const FLYWHEEL_ORCHESTRATOR_AGENT_ID = "flywheel-orchestrator";
|
|
630
|
+
/**
|
|
631
|
+
* Pure decision for recovering a dead or wedged flywheel orchestrator (no I/O —
|
|
632
|
+
* side effects live in remediateFlywheelOrchestrator). The respawn cap
|
|
633
|
+
* (FLYWHEEL_MAX_RESPAWNS within FLYWHEEL_RESPAWN_WINDOW_MS) stops an infinite
|
|
634
|
+
* relaunch loop: past the cap, escalate to paused+troubled. `hasActiveRun` false
|
|
635
|
+
* ⇒ the operator stopped the flywheel deliberately ⇒ do not resurrect.
|
|
636
|
+
*/
|
|
637
|
+
function decideFlywheelRemediation(opts) {
|
|
638
|
+
if (!opts.hasActiveRun) return { kind: "noop" };
|
|
639
|
+
const lastRespawnMs = opts.prev?.lastRespawnAt ? new Date(opts.prev.lastRespawnAt).getTime() : 0;
|
|
640
|
+
const respawnCount = Number.isFinite(lastRespawnMs) && opts.now - lastRespawnMs < FLYWHEEL_RESPAWN_WINDOW_MS ? opts.prev?.respawnCount ?? 0 : 0;
|
|
641
|
+
if (respawnCount >= FLYWHEEL_MAX_RESPAWNS) return {
|
|
642
|
+
kind: "escalate",
|
|
643
|
+
respawnCount
|
|
644
|
+
};
|
|
645
|
+
return {
|
|
646
|
+
kind: "relaunch",
|
|
647
|
+
respawnCount: respawnCount + 1
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
/** True when the orchestrator's process is actually gone (session missing or dead pane). */
|
|
651
|
+
function isFlywheelOrchestratorDead(agentId) {
|
|
652
|
+
if (!sessionExistsSync(agentId)) return true;
|
|
653
|
+
return listPaneValuesSync(agentId, "#{pane_dead}").some((v) => v === "1");
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* Recover a dead or wedged flywheel orchestrator: relaunch (capped) or, past the
|
|
657
|
+
* cap, pause+trouble. `reason` describes why recovery fired (death vs wedge) for
|
|
658
|
+
* the deacon log. NO_RESUME is intentionally NOT consulted (see header comment) —
|
|
659
|
+
* the operator gate is the active run (`pan flywheel stop`) / patrol freeze.
|
|
660
|
+
*/
|
|
661
|
+
async function remediateFlywheelOrchestrator(agentId, now, actions, reason) {
|
|
662
|
+
const decision = decideFlywheelRemediation({
|
|
663
|
+
hasActiveRun: Boolean(getFlywheelActiveRunId()),
|
|
664
|
+
prev: readStuckRemediationState(agentId),
|
|
665
|
+
now
|
|
666
|
+
});
|
|
667
|
+
if (decision.kind === "noop") return;
|
|
668
|
+
const { resumeFlywheel, pauseFlywheel } = await import("./flywheel-HJt7QdWP.js");
|
|
669
|
+
const prev = readStuckRemediationState(agentId);
|
|
670
|
+
const nowIso = new Date(now).toISOString();
|
|
671
|
+
if (decision.kind === "escalate") {
|
|
672
|
+
await pauseFlywheel();
|
|
673
|
+
markAgentTroubled(agentId);
|
|
674
|
+
writeStuckRemediationState(agentId, {
|
|
675
|
+
lastStage: 3,
|
|
676
|
+
lastStageAt: nowIso,
|
|
677
|
+
firstStuckAt: prev?.firstStuckAt ?? nowIso,
|
|
678
|
+
respawnCount: decision.respawnCount,
|
|
679
|
+
lastRespawnAt: prev?.lastRespawnAt
|
|
680
|
+
});
|
|
681
|
+
logAction(actions, `[deacon] FLYWHEEL orchestrator ${reason} and exceeded ${FLYWHEEL_MAX_RESPAWNS} relaunches in ${FLYWHEEL_RESPAWN_WINDOW_MS / 6e4}min — paused + troubled; operator needed`);
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
try {
|
|
685
|
+
killSessionSync(agentId);
|
|
686
|
+
} catch {}
|
|
687
|
+
try {
|
|
688
|
+
await resumeFlywheel({ resumeCause: "system" });
|
|
689
|
+
writeStuckRemediationState(agentId, {
|
|
690
|
+
lastStage: 0,
|
|
691
|
+
lastStageAt: nowIso,
|
|
692
|
+
firstStuckAt: nowIso,
|
|
693
|
+
respawnCount: decision.respawnCount,
|
|
694
|
+
lastRespawnAt: nowIso
|
|
695
|
+
});
|
|
696
|
+
logAction(actions, `[deacon] FLYWHEEL orchestrator ${reason} — fresh-launched (relaunch ${decision.respawnCount}/${FLYWHEEL_MAX_RESPAWNS})`);
|
|
697
|
+
} catch (error) {
|
|
698
|
+
logAction(actions, `[deacon] FLYWHEEL orchestrator ${reason} — relaunch FAILED: ${error instanceof Error ? error.message : String(error)}`);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
async function evaluateFlywheelOrchestrator(agent, config, now, actions) {
|
|
702
|
+
const agentId = agent.id;
|
|
703
|
+
if (isFlywheelOrchestratorDead(agentId)) {
|
|
704
|
+
await remediateFlywheelOrchestrator(agentId, now, actions, `DIED (${describeAgentDeath(agentId)})`);
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
if (!isAgentIdleForNudge(agentId, 300 * 1e3, now)) return;
|
|
708
|
+
const runtime = getAgentRuntimeStateSync(agentId);
|
|
709
|
+
if (!runtime?.lastActivity) return;
|
|
710
|
+
const lastActivityMs = new Date(runtime.lastActivity).getTime();
|
|
711
|
+
if (!Number.isFinite(lastActivityMs)) return;
|
|
712
|
+
const stuckState = readStuckRemediationState(agentId);
|
|
713
|
+
if (stuckState) {
|
|
714
|
+
const firstStuckMs = new Date(stuckState.firstStuckAt).getTime();
|
|
715
|
+
if (Number.isFinite(firstStuckMs) && lastActivityMs > firstStuckMs) {
|
|
716
|
+
clearStuckRemediationState(agentId);
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
const idleMinutes = Math.floor((now - lastActivityMs) / 6e4);
|
|
721
|
+
const lastStage = stuckState?.lastStage ?? 0;
|
|
722
|
+
const firstStuck = firstStuckAt(runtime.lastActivity, stuckState);
|
|
723
|
+
if (idleMinutes >= config.flywheel_stage3_minutes && lastStage < 3) {
|
|
724
|
+
await remediateFlywheelOrchestrator(agentId, now, actions, `wedged (idle ${idleMinutes}min)`);
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
if (idleMinutes >= config.flywheel_stage2_minutes && lastStage < 2) {
|
|
728
|
+
await messageAgent(agentId, `Stage 2: idle ${idleMinutes} min — run a FULL flywheel tick NOW: inventory -> diagnose -> suggest -> launch ready work -> \`pan flywheel emit-status\`. Then call ScheduleWakeup(delaySeconds:1000) to arm the next tick. Do NOT ask the operator a question, do NOT wait, and do NOT just emit a stale status or pause.`);
|
|
729
|
+
writeStuckRemediationState(agentId, stageState(2, now, firstStuck, stuckState));
|
|
730
|
+
logAction(actions, transitionAction(2, "FLYWHEEL", idleMinutes, "escalated-nudge"));
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
if (idleMinutes >= config.flywheel_stage1_minutes && lastStage < 1) {
|
|
734
|
+
await messageAgent(agentId, `You appear stuck — ${idleMinutes} min since your last tick. Run a FULL flywheel tick NOW: inventory -> diagnose -> suggest -> launch ready work -> \`pan flywheel emit-status\`. Then call ScheduleWakeup(delaySeconds:1000) to arm the next tick. Do NOT ask the operator a question, do NOT wait, and do NOT just emit a stale status or pause.`);
|
|
735
|
+
writeStuckRemediationState(agentId, stageState(1, now, firstStuck, stuckState));
|
|
736
|
+
logAction(actions, transitionAction(1, "FLYWHEEL", idleMinutes, "poked"));
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
async function reconcileActiveFlywheelWithoutRunningAgent(now, actions) {
|
|
740
|
+
if (!getFlywheelActiveRunId()) return;
|
|
741
|
+
if (isFlywheelGloballyPaused()) return;
|
|
742
|
+
if (sessionExistsSync(FLYWHEEL_ORCHESTRATOR_AGENT_ID)) return;
|
|
743
|
+
await remediateFlywheelOrchestrator(FLYWHEEL_ORCHESTRATOR_AGENT_ID, now, actions, `DIED (${describeAgentDeath(FLYWHEEL_ORCHESTRATOR_AGENT_ID)})`);
|
|
744
|
+
}
|
|
745
|
+
async function checkStuckAgentRemediation(opts = {}) {
|
|
746
|
+
const config = loadCloisterConfigSync().stuck_remediation ?? DEFAULT_CLOISTER_CONFIG.stuck_remediation;
|
|
747
|
+
if (!config.enabled) return [];
|
|
748
|
+
const actions = [];
|
|
749
|
+
const now = opts.now ?? Date.now();
|
|
750
|
+
const runningAgents = listRunningAgentsSync();
|
|
751
|
+
let sawFlywheelOrchestrator = false;
|
|
752
|
+
for (const agent of runningAgents) {
|
|
753
|
+
if (agent.id === FLYWHEEL_ORCHESTRATOR_AGENT_ID || agent.role === "flywheel") sawFlywheelOrchestrator = true;
|
|
754
|
+
try {
|
|
755
|
+
await evaluateAgent(agent, config, now, actions);
|
|
756
|
+
} catch (error) {
|
|
757
|
+
const message = `[deacon] stuck-remediation agent=${agent.id || "(unknown)"} error=${error instanceof Error ? error.message : String(error)}`;
|
|
758
|
+
console.error(message, error);
|
|
759
|
+
logDeaconEventSync(message);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
if (!sawFlywheelOrchestrator) try {
|
|
763
|
+
await reconcileActiveFlywheelWithoutRunningAgent(now, actions);
|
|
764
|
+
} catch (error) {
|
|
765
|
+
const message = `[deacon] stuck-remediation agent=${FLYWHEEL_ORCHESTRATOR_AGENT_ID} error=${error instanceof Error ? error.message : String(error)}`;
|
|
766
|
+
console.error(message, error);
|
|
767
|
+
logDeaconEventSync(message);
|
|
768
|
+
}
|
|
769
|
+
return actions;
|
|
770
|
+
}
|
|
771
|
+
//#endregion
|
|
772
|
+
export { shouldClearPlanningWedgeEpisode as a, executePlanningWedgeDecision as i, decideFlywheelRemediation as n, shouldSkipIdlePokeForAgent as o, decidePlanningWedgeRemediation as r, shouldSkipReviewStatus as s, checkStuckAgentRemediation as t };
|
|
773
|
+
|
|
774
|
+
//# sourceMappingURL=stuck-remediation-BDa_tXgB.js.map
|