@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
|
@@ -1,1164 +0,0 @@
|
|
|
1
|
-
import { Fi as init_paths, Pi as getOverdeckHome, Ri as packageRoot, oi as init_errors } from "./config-yaml-BwOEANMr.js";
|
|
2
|
-
import { E as killSessionSync, L as sendKeys, S as init_tmux, V as sessionExistsSync, c as detectTerminalApiErrorSync, i as capturePaneSync, k as listPaneValuesSync } from "./tmux-BqXzRuaH.js";
|
|
3
|
-
import { c as getRuntimeBehavior, i as CLAUDE_CODE_BEHAVIOR } from "./src-DudQNYVw.js";
|
|
4
|
-
import { _ as logDeaconEventSync, h as init_persistent_logger } from "./agents-CqQJW75N.js";
|
|
5
|
-
import { $r as determineModel, $t as spawnAgent, G as init_agents, H as getAgentRuntimeStateSync, Jr as materializeAcpContextFile, Nt as resumeAgent, O as saveAgentStateSync, Rt as messageAgent, St as init_agent_enrichment, Ur as init_pi_fifo, W as saveAgentRuntimeState, Xt as createOhmypiRuntimeSync, Zt as init_ohmypi, _t as countPendingAskUserQuestionsForAgent, cn as listAgentStates, cr as init_bridge_token, m as getAgentStateSync, qr as init_context, sn as init_queries, sr as BRIDGE_TOKEN_HEADER, u as getAgentDir, un as listRunningAgentsSync, x as markAgentTroubled } from "./agent-state-Bb3UUxQm.js";
|
|
6
|
-
import { t as init_behavior } from "./behavior-Bitko0mD.js";
|
|
7
|
-
import { w as init_launcher_generator } from "./auto-spawn-consent-BDfe4qz0.js";
|
|
8
|
-
import { _ as tmuxKillSession, g as tmuxCreateSession, h as init_tmux_cli, i as createCodexRuntimeSync, l as init_codex, v as tmuxSessionExists } from "./codex-OOea7lXs.js";
|
|
9
|
-
import { i as prepareHarnessLaunch, r as init_harness_binary } from "./harness-binary-BgXYDo2Z.js";
|
|
10
|
-
import { c as init_control_settings, i as getFlywheelActiveRunId, p as isFlywheelGloballyPaused } from "./control-settings-5k6ixdFW.js";
|
|
11
|
-
import { h as readWorkspacePlanSync, s as init_io } from "./io-DfvO2xyh.js";
|
|
12
|
-
import { l as init_dag, o as getDispatchableItems } from "./dag-DI9LaK_q.js";
|
|
13
|
-
import { a as loadCloisterConfigSync, r as init_config, t as DEFAULT_CLOISTER_CONFIG } from "./config-DC75T4Mr.js";
|
|
14
|
-
import { d as getReviewStatusSync, p as init_review_status } from "./review-status-DBnR5t4z.js";
|
|
15
|
-
import { a as init_jsonl_parser, i as getSessionFilesSync, r as getProjectDirsSync, s as parseClaudeSessionSync } from "./jsonl-parser-CrEb2PWr.js";
|
|
16
|
-
import { i as createKimiCodeRuntimeSync, l as init_kimi_code } from "./kimi-code-C26gmGxM.js";
|
|
17
|
-
import { i as recordRecoveryFailure, r as init_recovery_trip } from "./recovery-trip-C4dTl8DO.js";
|
|
18
|
-
import { join } from "node:path";
|
|
19
|
-
import { Effect } from "effect";
|
|
20
|
-
import { existsSync, mkdirSync, readFileSync, statSync, unlinkSync, writeFileSync } from "fs";
|
|
21
|
-
import { join as join$1 } from "path";
|
|
22
|
-
import { homedir } from "os";
|
|
23
|
-
import "node:os";
|
|
24
|
-
import { existsSync as existsSync$1, readFileSync as readFileSync$1, rmSync as rmSync$1, statSync as statSync$1 } from "node:fs";
|
|
25
|
-
import "node:crypto";
|
|
26
|
-
import { exec } from "node:child_process";
|
|
27
|
-
import { promisify } from "node:util";
|
|
28
|
-
import { request } from "node:http";
|
|
29
|
-
//#region ../../lib/runtimes/claude-code.ts
|
|
30
|
-
init_paths();
|
|
31
|
-
init_persistent_logger();
|
|
32
|
-
init_harness_binary();
|
|
33
|
-
init_launcher_generator();
|
|
34
|
-
init_io();
|
|
35
|
-
init_bridge_token();
|
|
36
|
-
init_config();
|
|
37
|
-
init_queries();
|
|
38
|
-
init_agent_enrichment();
|
|
39
|
-
init_review_status();
|
|
40
|
-
/**
|
|
41
|
-
* Claude Code Runtime Implementation
|
|
42
|
-
*
|
|
43
|
-
* Implements AgentRuntime for Claude Code CLI.
|
|
44
|
-
*
|
|
45
|
-
* Session storage: ~/.claude/projects/<workspace-hash>/<session-id>.jsonl
|
|
46
|
-
* Session index: ~/.claude/projects/<workspace-hash>/sessions-index.json
|
|
47
|
-
*/
|
|
48
|
-
init_behavior();
|
|
49
|
-
init_agents();
|
|
50
|
-
init_tmux();
|
|
51
|
-
init_jsonl_parser();
|
|
52
|
-
init_errors();
|
|
53
|
-
const CLAUDE_PROJECTS_DIR = join$1(homedir(), ".claude", "projects");
|
|
54
|
-
/**
|
|
55
|
-
* Claude Code Runtime implementation
|
|
56
|
-
*/
|
|
57
|
-
var ClaudeCodeRuntimeSync = class {
|
|
58
|
-
name = "claude-code";
|
|
59
|
-
getHarnessBehavior() {
|
|
60
|
-
return CLAUDE_CODE_BEHAVIOR;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Get the project directory for a workspace
|
|
64
|
-
*
|
|
65
|
-
* Claude Code hashes the workspace path to create project directories.
|
|
66
|
-
* We need to find the project directory that contains sessions for this workspace.
|
|
67
|
-
*/
|
|
68
|
-
getProjectDirForWorkspace(workspace) {
|
|
69
|
-
if (!existsSync(CLAUDE_PROJECTS_DIR)) return null;
|
|
70
|
-
const projectDirs = getProjectDirsSync();
|
|
71
|
-
for (const projectDir of projectDirs) {
|
|
72
|
-
const indexPath = join$1(projectDir, "sessions-index.json");
|
|
73
|
-
if (existsSync(indexPath)) try {
|
|
74
|
-
if (readFileSync(indexPath, "utf-8").includes(workspace)) return projectDir;
|
|
75
|
-
} catch {}
|
|
76
|
-
}
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Get the active session ID for an agent from the sessions index
|
|
81
|
-
*/
|
|
82
|
-
getActiveSessionId(projectDir) {
|
|
83
|
-
const indexPath = join$1(projectDir, "sessions-index.json");
|
|
84
|
-
if (!existsSync(indexPath)) return null;
|
|
85
|
-
try {
|
|
86
|
-
const indexContent = readFileSync(indexPath, "utf-8");
|
|
87
|
-
const index = JSON.parse(indexContent);
|
|
88
|
-
if (index.sessions && Array.isArray(index.sessions)) {
|
|
89
|
-
const sessions = index.sessions;
|
|
90
|
-
if (sessions.length === 0) return null;
|
|
91
|
-
return sessions.sort((a, b) => {
|
|
92
|
-
return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();
|
|
93
|
-
})[0].sessionId;
|
|
94
|
-
}
|
|
95
|
-
} catch {}
|
|
96
|
-
return null;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Get the most recent JSONL file for a project
|
|
100
|
-
*/
|
|
101
|
-
getMostRecentJSONL(projectDir) {
|
|
102
|
-
const files = getSessionFilesSync(projectDir);
|
|
103
|
-
return files.length > 0 ? files[0] : null;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Get the session path for an agent
|
|
107
|
-
*/
|
|
108
|
-
getSessionPath(agentId) {
|
|
109
|
-
const state = getAgentStateSync(agentId);
|
|
110
|
-
if (!state) return null;
|
|
111
|
-
const projectDir = this.getProjectDirForWorkspace(state.workspace);
|
|
112
|
-
if (!projectDir) return null;
|
|
113
|
-
const sessionId = this.getActiveSessionId(projectDir);
|
|
114
|
-
if (sessionId) {
|
|
115
|
-
const sessionPath = join$1(projectDir, `${sessionId}.jsonl`);
|
|
116
|
-
if (existsSync(sessionPath)) return sessionPath;
|
|
117
|
-
}
|
|
118
|
-
return this.getMostRecentJSONL(projectDir);
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Get last activity timestamp for an agent
|
|
122
|
-
*
|
|
123
|
-
* Uses passive detection via JSONL file modification time.
|
|
124
|
-
*/
|
|
125
|
-
getLastActivity(agentId) {
|
|
126
|
-
const sessionPath = this.getSessionPath(agentId);
|
|
127
|
-
if (!sessionPath || !existsSync(sessionPath)) return null;
|
|
128
|
-
try {
|
|
129
|
-
return statSync(sessionPath).mtime;
|
|
130
|
-
} catch {
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Read active heartbeat file if it exists
|
|
136
|
-
*/
|
|
137
|
-
getActiveHeartbeat(agentId) {
|
|
138
|
-
const heartbeatPath = join$1(homedir(), ".overdeck", "heartbeats", `${agentId}.json`);
|
|
139
|
-
if (!existsSync(heartbeatPath)) return null;
|
|
140
|
-
try {
|
|
141
|
-
const content = readFileSync(heartbeatPath, "utf-8");
|
|
142
|
-
const data = JSON.parse(content);
|
|
143
|
-
const timestamp = new Date(data.timestamp);
|
|
144
|
-
if ((/* @__PURE__ */ new Date()).getTime() - timestamp.getTime() > 300 * 1e3) return null;
|
|
145
|
-
return {
|
|
146
|
-
timestamp,
|
|
147
|
-
agentId: data.agent_id || agentId,
|
|
148
|
-
source: "active-heartbeat",
|
|
149
|
-
confidence: "high",
|
|
150
|
-
toolName: data.tool_name,
|
|
151
|
-
lastAction: data.last_action,
|
|
152
|
-
currentTask: data.current_task,
|
|
153
|
-
gitBranch: data.git_branch,
|
|
154
|
-
workspace: data.workspace,
|
|
155
|
-
pid: data.pid,
|
|
156
|
-
sessionId: data.session_id
|
|
157
|
-
};
|
|
158
|
-
} catch {
|
|
159
|
-
return null;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Get passive heartbeat from file timestamps
|
|
164
|
-
*/
|
|
165
|
-
getPassiveHeartbeat(agentId) {
|
|
166
|
-
const lastActivity = this.getLastActivity(agentId);
|
|
167
|
-
if (!lastActivity) return null;
|
|
168
|
-
return {
|
|
169
|
-
timestamp: lastActivity,
|
|
170
|
-
agentId,
|
|
171
|
-
source: "jsonl",
|
|
172
|
-
confidence: "medium"
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Get heartbeat for an agent
|
|
177
|
-
*
|
|
178
|
-
* Tries active heartbeat first (if hooks configured), falls back to passive.
|
|
179
|
-
*/
|
|
180
|
-
getHeartbeat(agentId) {
|
|
181
|
-
const activeHeartbeat = this.getActiveHeartbeat(agentId);
|
|
182
|
-
if (activeHeartbeat) return activeHeartbeat;
|
|
183
|
-
return this.getPassiveHeartbeat(agentId);
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Get token usage for an agent's current session
|
|
187
|
-
*/
|
|
188
|
-
getTokenUsage(agentId) {
|
|
189
|
-
const sessionPath = this.getSessionPath(agentId);
|
|
190
|
-
if (!sessionPath) return null;
|
|
191
|
-
const sessionUsage = parseClaudeSessionSync(sessionPath);
|
|
192
|
-
if (!sessionUsage) return null;
|
|
193
|
-
return sessionUsage.usage;
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Get cost breakdown for an agent's current session
|
|
197
|
-
*/
|
|
198
|
-
getSessionCost(agentId) {
|
|
199
|
-
const sessionPath = this.getSessionPath(agentId);
|
|
200
|
-
if (!sessionPath) return null;
|
|
201
|
-
const sessionUsage = parseClaudeSessionSync(sessionPath);
|
|
202
|
-
if (!sessionUsage) return null;
|
|
203
|
-
const inputPrice = 3 / 1e6;
|
|
204
|
-
const outputPrice = 15 / 1e6;
|
|
205
|
-
const cacheReadPrice = .3 / 1e6;
|
|
206
|
-
const cacheWritePrice = 3.75 / 1e6;
|
|
207
|
-
const usage = sessionUsage.usage;
|
|
208
|
-
const inputCost = usage.inputTokens * inputPrice;
|
|
209
|
-
const outputCost = usage.outputTokens * outputPrice;
|
|
210
|
-
const cacheReadCost = (usage.cacheReadTokens || 0) * cacheReadPrice;
|
|
211
|
-
const cacheWriteCost = (usage.cacheWriteTokens || 0) * cacheWritePrice;
|
|
212
|
-
return {
|
|
213
|
-
inputCost,
|
|
214
|
-
outputCost,
|
|
215
|
-
cacheReadCost,
|
|
216
|
-
cacheWriteCost,
|
|
217
|
-
totalCost: inputCost + outputCost + cacheReadCost + cacheWriteCost,
|
|
218
|
-
currency: "USD"
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Send a message to a running agent
|
|
223
|
-
*/
|
|
224
|
-
async sendMessage(agentId, message) {
|
|
225
|
-
if (!sessionExistsSync(agentId)) throw new Error(`Agent ${agentId} is not running`);
|
|
226
|
-
await Effect.runPromise(sendKeys(agentId, message));
|
|
227
|
-
const mailDir = join$1(getAgentDir(agentId), "mail");
|
|
228
|
-
mkdirSync(mailDir, { recursive: true });
|
|
229
|
-
writeFileSync(join$1(mailDir, `${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.md`), `# Message\n\n${message}\n`);
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* Kill an agent
|
|
233
|
-
*/
|
|
234
|
-
killAgent(agentId) {
|
|
235
|
-
if (!sessionExistsSync(agentId)) throw new Error(`Agent ${agentId} is not running`);
|
|
236
|
-
killSessionSync(agentId);
|
|
237
|
-
saveAgentRuntimeState(agentId, {
|
|
238
|
-
state: "idle",
|
|
239
|
-
lastActivity: (/* @__PURE__ */ new Date()).toISOString()
|
|
240
|
-
});
|
|
241
|
-
const state = getAgentStateSync(agentId);
|
|
242
|
-
if (state) {
|
|
243
|
-
state.status = "stopped";
|
|
244
|
-
saveAgentStateSync(state);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Spawn a new agent
|
|
249
|
-
*/
|
|
250
|
-
async spawnAgent(config) {
|
|
251
|
-
const state = await spawnAgent({
|
|
252
|
-
issueId: config.agentId.replace(/^agent-/, ""),
|
|
253
|
-
workspace: config.workspace,
|
|
254
|
-
harness: "claude-code",
|
|
255
|
-
model: determineModel({
|
|
256
|
-
model: config.model,
|
|
257
|
-
role: "work",
|
|
258
|
-
spawnKey: `work:${config.agentId.replace(/^agent-/, "")}`
|
|
259
|
-
}),
|
|
260
|
-
role: "work",
|
|
261
|
-
prompt: config.prompt,
|
|
262
|
-
startedBy: config.env?.["OVERDECK_AGENT_STARTED_BY"] ?? "runtime:claude-code"
|
|
263
|
-
});
|
|
264
|
-
const projectDir = this.getProjectDirForWorkspace(config.workspace);
|
|
265
|
-
const sessionId = projectDir ? this.getActiveSessionId(projectDir) : void 0;
|
|
266
|
-
return {
|
|
267
|
-
id: state.id,
|
|
268
|
-
sessionId: sessionId || "unknown",
|
|
269
|
-
runtime: "claude-code",
|
|
270
|
-
model: state.model,
|
|
271
|
-
workspace: state.workspace,
|
|
272
|
-
startedAt: new Date(state.startedAt)
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* List all sessions for this runtime
|
|
277
|
-
*/
|
|
278
|
-
listSessions(workspace) {
|
|
279
|
-
const sessions = [];
|
|
280
|
-
if (workspace) {
|
|
281
|
-
const projectDir = this.getProjectDirForWorkspace(workspace);
|
|
282
|
-
if (projectDir) {
|
|
283
|
-
const files = getSessionFilesSync(projectDir);
|
|
284
|
-
for (const file of files) {
|
|
285
|
-
const session = this.parseSessionFile(file, workspace);
|
|
286
|
-
if (session) sessions.push(session);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
} else {
|
|
290
|
-
const projectDirs = getProjectDirsSync();
|
|
291
|
-
for (const projectDir of projectDirs) {
|
|
292
|
-
const files = getSessionFilesSync(projectDir);
|
|
293
|
-
for (const file of files) {
|
|
294
|
-
const session = this.parseSessionFile(file);
|
|
295
|
-
if (session) sessions.push(session);
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
return sessions;
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Parse a session file into a Session object
|
|
303
|
-
*/
|
|
304
|
-
parseSessionFile(file, workspace) {
|
|
305
|
-
const sessionUsage = parseClaudeSessionSync(file);
|
|
306
|
-
if (!sessionUsage) return null;
|
|
307
|
-
const stat = statSync(file);
|
|
308
|
-
return {
|
|
309
|
-
id: sessionUsage.sessionId,
|
|
310
|
-
agentId: "unknown",
|
|
311
|
-
workspace: workspace || "unknown",
|
|
312
|
-
model: sessionUsage.model,
|
|
313
|
-
startedAt: new Date(sessionUsage.startTime),
|
|
314
|
-
lastActivity: stat.mtime,
|
|
315
|
-
tokenUsage: sessionUsage.usage
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
/**
|
|
319
|
-
* Check if an agent is running
|
|
320
|
-
*/
|
|
321
|
-
isRunning(agentId) {
|
|
322
|
-
return sessionExistsSync(agentId);
|
|
323
|
-
}
|
|
324
|
-
};
|
|
325
|
-
/**
|
|
326
|
-
* Create a Claude Code runtime instance
|
|
327
|
-
*/
|
|
328
|
-
function createClaudeCodeRuntimeSync() {
|
|
329
|
-
return new ClaudeCodeRuntimeSync();
|
|
330
|
-
}
|
|
331
|
-
//#endregion
|
|
332
|
-
//#region ../../lib/cost-parsers/pi-parser.ts
|
|
333
|
-
init_errors();
|
|
334
|
-
//#endregion
|
|
335
|
-
//#region ../../lib/runtimes/pi.ts
|
|
336
|
-
init_behavior();
|
|
337
|
-
init_tmux();
|
|
338
|
-
init_pi_fifo();
|
|
339
|
-
init_errors();
|
|
340
|
-
promisify(exec);
|
|
341
|
-
//#endregion
|
|
342
|
-
//#region ../../lib/runtimes/acp.ts
|
|
343
|
-
init_codex();
|
|
344
|
-
init_ohmypi();
|
|
345
|
-
init_context();
|
|
346
|
-
init_harness_binary();
|
|
347
|
-
init_paths();
|
|
348
|
-
init_behavior();
|
|
349
|
-
init_tmux_cli();
|
|
350
|
-
const execAsync = promisify(exec);
|
|
351
|
-
const HOST_REQUEST_TIMEOUT_MS = 5e3;
|
|
352
|
-
const SPAWN_READY_TIMEOUT_MS = 3e4;
|
|
353
|
-
const POLL_INTERVAL_MS = 100;
|
|
354
|
-
var AcpSpawnTimeout = class extends Error {
|
|
355
|
-
code = "ACP_SPAWN_TIMEOUT";
|
|
356
|
-
constructor(agentId) {
|
|
357
|
-
super(`ACP agent ${agentId} did not write acp-session-id within ${SPAWN_READY_TIMEOUT_MS}ms`);
|
|
358
|
-
this.name = "AcpSpawnTimeout";
|
|
359
|
-
}
|
|
360
|
-
};
|
|
361
|
-
var AcpRuntimeSync = class {
|
|
362
|
-
name = "acp";
|
|
363
|
-
provider;
|
|
364
|
-
overdeckHome;
|
|
365
|
-
execCommand;
|
|
366
|
-
prepareLaunch;
|
|
367
|
-
resolveAgentStates;
|
|
368
|
-
constructor(options = {}) {
|
|
369
|
-
this.provider = options.provider ?? "kimi";
|
|
370
|
-
this.overdeckHome = options.overdeckHome;
|
|
371
|
-
this.execCommand = options.execCommand ?? execAsync;
|
|
372
|
-
this.prepareLaunch = options.prepareLaunch ?? (() => prepareHarnessLaunch("acp"));
|
|
373
|
-
this.resolveAgentStates = options.listAgentStates ?? (() => listAgentStates());
|
|
374
|
-
}
|
|
375
|
-
getHarnessBehavior() {
|
|
376
|
-
return getRuntimeBehavior("acp");
|
|
377
|
-
}
|
|
378
|
-
getSessionPath(agentId) {
|
|
379
|
-
return join(this.home(), "agents", agentId, "acp-session.jsonl");
|
|
380
|
-
}
|
|
381
|
-
getLastActivity(agentId) {
|
|
382
|
-
try {
|
|
383
|
-
return statSync$1(this.getSessionPath(agentId)).mtime;
|
|
384
|
-
} catch {
|
|
385
|
-
return null;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
getHeartbeat(agentId) {
|
|
389
|
-
const lastActivity = this.getLastActivity(agentId);
|
|
390
|
-
if (!lastActivity) return null;
|
|
391
|
-
return {
|
|
392
|
-
timestamp: lastActivity,
|
|
393
|
-
agentId,
|
|
394
|
-
source: "jsonl",
|
|
395
|
-
confidence: "medium"
|
|
396
|
-
};
|
|
397
|
-
}
|
|
398
|
-
getTokenUsage(_agentId) {
|
|
399
|
-
return null;
|
|
400
|
-
}
|
|
401
|
-
getSessionCost(_agentId) {
|
|
402
|
-
return null;
|
|
403
|
-
}
|
|
404
|
-
async sendMessage(agentId, message) {
|
|
405
|
-
const socketPath = this.socketPath(agentId);
|
|
406
|
-
if (!existsSync$1(socketPath)) throw new Error(`ACP agent ${agentId}: host socket is not available`);
|
|
407
|
-
const token = this.readToken(agentId);
|
|
408
|
-
if (!token) throw new Error(`ACP agent ${agentId}: missing acp-token`);
|
|
409
|
-
await postUnixSocketJson(socketPath, token, {
|
|
410
|
-
op: "message",
|
|
411
|
-
content: message
|
|
412
|
-
}, HOST_REQUEST_TIMEOUT_MS);
|
|
413
|
-
}
|
|
414
|
-
async killAgent(agentId) {
|
|
415
|
-
const socketPath = this.socketPath(agentId);
|
|
416
|
-
const token = this.readToken(agentId);
|
|
417
|
-
if (existsSync$1(socketPath) && token) try {
|
|
418
|
-
await postUnixSocketJson(socketPath, token, { op: "interrupt" }, HOST_REQUEST_TIMEOUT_MS);
|
|
419
|
-
} catch {}
|
|
420
|
-
if (await pollUntilSessionGone(agentId, 2e3)) return;
|
|
421
|
-
let panePid = null;
|
|
422
|
-
try {
|
|
423
|
-
const { stdout } = await this.execCommand(`tmux -L overdeck list-panes -t ${shellQuote(agentId)} -F '#{pane_pid}' 2>/dev/null`);
|
|
424
|
-
panePid = stdout.trim() || null;
|
|
425
|
-
if (panePid) await this.execCommand(`kill -TERM -- -${panePid} 2>/dev/null || kill -TERM ${panePid} 2>/dev/null || true`);
|
|
426
|
-
} catch {}
|
|
427
|
-
if (await pollUntilSessionGone(agentId, 5e3)) return;
|
|
428
|
-
if (panePid) try {
|
|
429
|
-
await this.execCommand(`kill -KILL -- -${panePid} 2>/dev/null || kill -KILL ${panePid} 2>/dev/null || true`);
|
|
430
|
-
} catch {}
|
|
431
|
-
if (await tmuxSessionExists(agentId)) await tmuxKillSession(agentId);
|
|
432
|
-
}
|
|
433
|
-
async spawnAgent(config) {
|
|
434
|
-
const provider = config.provider ?? this.provider;
|
|
435
|
-
const { binaryPath } = await this.prepareLaunch();
|
|
436
|
-
const contextFile = materializeAcpContextFile(join(this.home(), "agents", config.agentId), config.workspace);
|
|
437
|
-
const command = [
|
|
438
|
-
"node",
|
|
439
|
-
shellQuote(join(packageRoot, "dist", "acp-host.js")),
|
|
440
|
-
"--agent",
|
|
441
|
-
shellQuote(config.agentId),
|
|
442
|
-
"--provider",
|
|
443
|
-
shellQuote(provider),
|
|
444
|
-
"--workspace",
|
|
445
|
-
shellQuote(config.workspace),
|
|
446
|
-
"--binary-path",
|
|
447
|
-
shellQuote(binaryPath),
|
|
448
|
-
"--context-file",
|
|
449
|
-
shellQuote(contextFile)
|
|
450
|
-
];
|
|
451
|
-
if (config.sessionId) command.push("--resume", shellQuote(config.sessionId));
|
|
452
|
-
if (config.model) command.push("--model", shellQuote(config.model));
|
|
453
|
-
rmSync$1(this.agentPath(config.agentId, "acp-session-id"), { force: true });
|
|
454
|
-
rmSync$1(this.agentPath(config.agentId, "acp-launch-error"), { force: true });
|
|
455
|
-
await tmuxCreateSession(config.agentId, config.workspace, command.join(" "), {
|
|
456
|
-
...config.env,
|
|
457
|
-
OVERDECK_AGENT_ID: config.agentId
|
|
458
|
-
});
|
|
459
|
-
try {
|
|
460
|
-
const sessionId = await this.waitForSessionId(config.agentId);
|
|
461
|
-
if (!sessionId) throw new AcpSpawnTimeout(config.agentId);
|
|
462
|
-
if (config.prompt) await this.sendMessage(config.agentId, config.prompt);
|
|
463
|
-
return {
|
|
464
|
-
id: config.agentId,
|
|
465
|
-
sessionId,
|
|
466
|
-
runtime: "acp",
|
|
467
|
-
model: config.model ?? "",
|
|
468
|
-
workspace: config.workspace,
|
|
469
|
-
startedAt: /* @__PURE__ */ new Date()
|
|
470
|
-
};
|
|
471
|
-
} catch (error) {
|
|
472
|
-
if (await tmuxSessionExists(config.agentId)) await tmuxKillSession(config.agentId);
|
|
473
|
-
throw error;
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
listSessions(workspace) {
|
|
477
|
-
const sessions = [];
|
|
478
|
-
for (const state of this.resolveAgentStates()) {
|
|
479
|
-
if (state.harness !== "acp") continue;
|
|
480
|
-
if (workspace && state.workspace !== workspace) continue;
|
|
481
|
-
const sessionId = this.readSessionId(state.id);
|
|
482
|
-
if (!sessionId) continue;
|
|
483
|
-
const sessionPath = this.getSessionPath(state.id);
|
|
484
|
-
let lastActivity;
|
|
485
|
-
try {
|
|
486
|
-
lastActivity = statSync$1(sessionPath).mtime;
|
|
487
|
-
} catch {
|
|
488
|
-
try {
|
|
489
|
-
lastActivity = statSync$1(this.agentPath(state.id, "acp-session-id")).mtime;
|
|
490
|
-
} catch {
|
|
491
|
-
continue;
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
sessions.push({
|
|
495
|
-
id: sessionId,
|
|
496
|
-
agentId: state.id,
|
|
497
|
-
workspace: state.workspace,
|
|
498
|
-
model: state.model ?? "",
|
|
499
|
-
startedAt: new Date(state.startedAt),
|
|
500
|
-
lastActivity,
|
|
501
|
-
tokenUsage: {
|
|
502
|
-
inputTokens: 0,
|
|
503
|
-
outputTokens: 0
|
|
504
|
-
}
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
return sessions;
|
|
508
|
-
}
|
|
509
|
-
async isRunning(agentId) {
|
|
510
|
-
return tmuxSessionExists(agentId);
|
|
511
|
-
}
|
|
512
|
-
home() {
|
|
513
|
-
return this.overdeckHome ?? getOverdeckHome();
|
|
514
|
-
}
|
|
515
|
-
agentPath(agentId, file) {
|
|
516
|
-
return join(this.home(), "agents", agentId, file);
|
|
517
|
-
}
|
|
518
|
-
socketPath(agentId) {
|
|
519
|
-
return join(this.home(), "sockets", `acp-${agentId}.sock`);
|
|
520
|
-
}
|
|
521
|
-
readToken(agentId) {
|
|
522
|
-
try {
|
|
523
|
-
return readFileSync$1(this.agentPath(agentId, "acp-token"), "utf8").trim() || null;
|
|
524
|
-
} catch {
|
|
525
|
-
return null;
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
readLaunchError(agentId) {
|
|
529
|
-
try {
|
|
530
|
-
return readFileSync$1(this.agentPath(agentId, "acp-launch-error"), "utf8").trim() || null;
|
|
531
|
-
} catch {
|
|
532
|
-
return null;
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
readSessionId(agentId) {
|
|
536
|
-
try {
|
|
537
|
-
return readFileSync$1(this.agentPath(agentId, "acp-session-id"), "utf8").trim() || null;
|
|
538
|
-
} catch {
|
|
539
|
-
return null;
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
async waitForSessionId(agentId) {
|
|
543
|
-
const deadline = Date.now() + SPAWN_READY_TIMEOUT_MS;
|
|
544
|
-
while (Date.now() < deadline) {
|
|
545
|
-
const launchError = this.readLaunchError(agentId);
|
|
546
|
-
if (launchError) throw new Error(`ACP host ${agentId} failed to start: ${launchError}`);
|
|
547
|
-
const sessionId = this.readSessionId(agentId);
|
|
548
|
-
if (sessionId) return sessionId;
|
|
549
|
-
await delay(POLL_INTERVAL_MS);
|
|
550
|
-
}
|
|
551
|
-
return null;
|
|
552
|
-
}
|
|
553
|
-
};
|
|
554
|
-
async function pollUntilSessionGone(agentId, timeoutMs) {
|
|
555
|
-
const deadline = Date.now() + timeoutMs;
|
|
556
|
-
while (Date.now() < deadline) {
|
|
557
|
-
if (!await tmuxSessionExists(agentId)) return true;
|
|
558
|
-
await delay(POLL_INTERVAL_MS);
|
|
559
|
-
}
|
|
560
|
-
return false;
|
|
561
|
-
}
|
|
562
|
-
function delay(ms) {
|
|
563
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
564
|
-
}
|
|
565
|
-
function shellQuote(value) {
|
|
566
|
-
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
567
|
-
}
|
|
568
|
-
function postUnixSocketJson(socketPath, token, body, timeoutMs) {
|
|
569
|
-
return new Promise((resolve, reject) => {
|
|
570
|
-
let settled = false;
|
|
571
|
-
let timeout;
|
|
572
|
-
const finish = (callback) => {
|
|
573
|
-
if (settled) return;
|
|
574
|
-
settled = true;
|
|
575
|
-
if (timeout) clearTimeout(timeout);
|
|
576
|
-
callback();
|
|
577
|
-
};
|
|
578
|
-
const client = request({
|
|
579
|
-
socketPath,
|
|
580
|
-
path: "/",
|
|
581
|
-
method: "POST",
|
|
582
|
-
headers: {
|
|
583
|
-
"content-type": "application/json",
|
|
584
|
-
[BRIDGE_TOKEN_HEADER]: token
|
|
585
|
-
}
|
|
586
|
-
}, (response) => {
|
|
587
|
-
const chunks = [];
|
|
588
|
-
response.on("data", (chunk) => chunks.push(chunk));
|
|
589
|
-
response.on("end", () => {
|
|
590
|
-
const responseBody = Buffer.concat(chunks).toString("utf8");
|
|
591
|
-
const status = response.statusCode ?? 0;
|
|
592
|
-
if (status < 200 || status >= 300) {
|
|
593
|
-
finish(() => reject(/* @__PURE__ */ new Error(`ACP host returned HTTP ${status}: ${responseBody}`)));
|
|
594
|
-
return;
|
|
595
|
-
}
|
|
596
|
-
finish(() => resolve({
|
|
597
|
-
status,
|
|
598
|
-
body: responseBody
|
|
599
|
-
}));
|
|
600
|
-
});
|
|
601
|
-
});
|
|
602
|
-
if (timeoutMs !== void 0) {
|
|
603
|
-
timeout = setTimeout(() => {
|
|
604
|
-
client.destroy(/* @__PURE__ */ new Error(`ACP host request timed out after ${timeoutMs}ms`));
|
|
605
|
-
}, timeoutMs);
|
|
606
|
-
timeout.unref?.();
|
|
607
|
-
}
|
|
608
|
-
client.once("error", (error) => finish(() => reject(error)));
|
|
609
|
-
client.end(JSON.stringify(body));
|
|
610
|
-
});
|
|
611
|
-
}
|
|
612
|
-
function createAcpRuntimeSync(options = {}) {
|
|
613
|
-
return new AcpRuntimeSync(options);
|
|
614
|
-
}
|
|
615
|
-
//#endregion
|
|
616
|
-
//#region ../../lib/runtimes/index.ts
|
|
617
|
-
init_behavior();
|
|
618
|
-
init_kimi_code();
|
|
619
|
-
init_agents();
|
|
620
|
-
/**
|
|
621
|
-
* Runtime registry implementation
|
|
622
|
-
*
|
|
623
|
-
* Manages multiple runtime adapters and provides lookup by agent ID.
|
|
624
|
-
*/
|
|
625
|
-
var RuntimeRegistry = class {
|
|
626
|
-
runtimes = /* @__PURE__ */ new Map();
|
|
627
|
-
/**
|
|
628
|
-
* Register a runtime adapter
|
|
629
|
-
*/
|
|
630
|
-
register(runtime) {
|
|
631
|
-
this.runtimes.set(runtime.name, runtime);
|
|
632
|
-
}
|
|
633
|
-
/**
|
|
634
|
-
* Get a runtime by name
|
|
635
|
-
*/
|
|
636
|
-
get(name) {
|
|
637
|
-
return this.runtimes.get(name);
|
|
638
|
-
}
|
|
639
|
-
/**
|
|
640
|
-
* Get all registered runtimes
|
|
641
|
-
*/
|
|
642
|
-
getAll() {
|
|
643
|
-
return Array.from(this.runtimes.values());
|
|
644
|
-
}
|
|
645
|
-
/**
|
|
646
|
-
* Get the runtime for a specific agent.
|
|
647
|
-
*
|
|
648
|
-
* Reads the agent's state file and dispatches by `state.harness`. When
|
|
649
|
-
* the harness field is missing or carries a legacy value (e.g. 'claude'
|
|
650
|
-
* from pre-PAN-636 wire format), we fall back to the claude-code runtime
|
|
651
|
-
* to preserve back-compat (PAN-636 ac2).
|
|
652
|
-
*/
|
|
653
|
-
getRuntimeForAgent(agentId) {
|
|
654
|
-
const state = getAgentStateSync(agentId);
|
|
655
|
-
if (!state) return null;
|
|
656
|
-
const harness = state.harness;
|
|
657
|
-
if (harness === "ohmypi" || harness === "pi") return this.get("ohmypi") ?? null;
|
|
658
|
-
if (harness === "codex") return this.get("codex") ?? null;
|
|
659
|
-
if (harness === "acp") return this.get("acp") ?? null;
|
|
660
|
-
if (harness === "kimi-code") return this.get("kimi-code") ?? null;
|
|
661
|
-
return this.get("claude-code") ?? null;
|
|
662
|
-
}
|
|
663
|
-
};
|
|
664
|
-
/**
|
|
665
|
-
* Global runtime registry instance
|
|
666
|
-
*/
|
|
667
|
-
let globalRegistry = null;
|
|
668
|
-
/**
|
|
669
|
-
* Get the global runtime registry
|
|
670
|
-
*
|
|
671
|
-
* Creates a new registry if one doesn't exist.
|
|
672
|
-
* Registers Claude Code runtime by default.
|
|
673
|
-
*/
|
|
674
|
-
function getGlobalRegistry() {
|
|
675
|
-
if (!globalRegistry) {
|
|
676
|
-
globalRegistry = new RuntimeRegistry();
|
|
677
|
-
globalRegistry.register(createClaudeCodeRuntimeSync());
|
|
678
|
-
globalRegistry.register(createOhmypiRuntimeSync());
|
|
679
|
-
globalRegistry.register(createCodexRuntimeSync());
|
|
680
|
-
globalRegistry.register(createAcpRuntimeSync());
|
|
681
|
-
globalRegistry.register(createKimiCodeRuntimeSync());
|
|
682
|
-
}
|
|
683
|
-
return globalRegistry;
|
|
684
|
-
}
|
|
685
|
-
/**
|
|
686
|
-
* Helper to get the runtime for an agent from the global registry
|
|
687
|
-
*/
|
|
688
|
-
function getRuntimeForAgent(agentId) {
|
|
689
|
-
return getGlobalRegistry().getRuntimeForAgent(agentId);
|
|
690
|
-
}
|
|
691
|
-
//#endregion
|
|
692
|
-
//#region ../../lib/cloister/agent-idle.ts
|
|
693
|
-
init_agents();
|
|
694
|
-
init_tmux();
|
|
695
|
-
function getAgentEffectiveLastActivityMs(agentId) {
|
|
696
|
-
const candidates = [];
|
|
697
|
-
const runtimeState = getAgentRuntimeStateSync(agentId);
|
|
698
|
-
const runtimeMs = runtimeState?.lastActivity ? new Date(runtimeState.lastActivity).getTime() : NaN;
|
|
699
|
-
if (Number.isFinite(runtimeMs)) candidates.push(runtimeMs);
|
|
700
|
-
try {
|
|
701
|
-
const tmuxActivity = listPaneValuesSync(agentId, "#{window_activity}").map((value) => Number.parseInt(value.trim(), 10) * 1e3).filter(Number.isFinite);
|
|
702
|
-
candidates.push(...tmuxActivity);
|
|
703
|
-
} catch {}
|
|
704
|
-
try {
|
|
705
|
-
const heartbeat = getRuntimeForAgent(agentId)?.getHeartbeat(agentId);
|
|
706
|
-
if (heartbeat?.timestamp) {
|
|
707
|
-
const heartbeatMs = heartbeat.timestamp.getTime();
|
|
708
|
-
if (Number.isFinite(heartbeatMs)) candidates.push(heartbeatMs);
|
|
709
|
-
}
|
|
710
|
-
} catch {}
|
|
711
|
-
return candidates.length > 0 ? Math.max(...candidates) : null;
|
|
712
|
-
}
|
|
713
|
-
function isAgentIdleForNudge(agentId, staleActiveThresholdMs = 300 * 1e3, now = Date.now()) {
|
|
714
|
-
const runtimeState = getAgentRuntimeStateSync(agentId);
|
|
715
|
-
const effectiveLastActivityMs = getAgentEffectiveLastActivityMs(agentId);
|
|
716
|
-
if (!runtimeState) {
|
|
717
|
-
if (effectiveLastActivityMs === null) {
|
|
718
|
-
console.log(`[deacon] ${agentId}: no runtime.json — skipping (hook not yet fired)`);
|
|
719
|
-
return false;
|
|
720
|
-
}
|
|
721
|
-
return now - effectiveLastActivityMs > staleActiveThresholdMs;
|
|
722
|
-
}
|
|
723
|
-
if (runtimeState.state === "suspended" || runtimeState.state === "stopped") return false;
|
|
724
|
-
if (runtimeState.state === "waiting-on-human") return false;
|
|
725
|
-
if (runtimeState.state === "idle") return true;
|
|
726
|
-
return now - (effectiveLastActivityMs ?? new Date(runtimeState.lastActivity).getTime()) > staleActiveThresholdMs;
|
|
727
|
-
}
|
|
728
|
-
//#endregion
|
|
729
|
-
//#region ../../lib/cloister/agent-death.ts
|
|
730
|
-
/**
|
|
731
|
-
* Agent death diagnostics (PAN-2108).
|
|
732
|
-
*
|
|
733
|
-
* When an ohmypi/pi agent process dies, the launcher records its exit code +
|
|
734
|
-
* timestamp to `<agentDir>/exit-status` (see buildOhmypiCommand in
|
|
735
|
-
* launcher-generator.ts), and omp's stdout/stderr is captured to
|
|
736
|
-
* `<agentDir>/output.log`. This module turns those into a one-line death reason
|
|
737
|
-
* the deacon can log, replacing the opaque "session is dead" with an actual
|
|
738
|
-
* cause — the gap that made the flywheel orchestrator's silent death
|
|
739
|
-
* undiagnosable in RUN-30.
|
|
740
|
-
*/
|
|
741
|
-
init_paths();
|
|
742
|
-
init_tmux();
|
|
743
|
-
function agentDir(agentId) {
|
|
744
|
-
return join$1(getOverdeckHome(), "agents", agentId);
|
|
745
|
-
}
|
|
746
|
-
/** Read the launcher-recorded exit code + UTC timestamp, or null if absent. */
|
|
747
|
-
function readAgentExitStatus(agentId) {
|
|
748
|
-
try {
|
|
749
|
-
const p = join$1(agentDir(agentId), "exit-status");
|
|
750
|
-
if (!existsSync(p)) return null;
|
|
751
|
-
const raw = readFileSync(p, "utf-8").trim();
|
|
752
|
-
if (!raw) return null;
|
|
753
|
-
const [code, at = ""] = raw.split(/\s+/);
|
|
754
|
-
return {
|
|
755
|
-
code: code ?? "?",
|
|
756
|
-
at
|
|
757
|
-
};
|
|
758
|
-
} catch {
|
|
759
|
-
return null;
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
/**
|
|
763
|
-
* Best-effort one-line description of why an agent process died: the
|
|
764
|
-
* launcher-recorded exit status (preferred), the tmux pane exit status (fallback
|
|
765
|
-
* when the dead pane corpse still exists), and the tail of output.log.
|
|
766
|
-
*/
|
|
767
|
-
function describeAgentDeath(agentId) {
|
|
768
|
-
const parts = [];
|
|
769
|
-
const exit = readAgentExitStatus(agentId);
|
|
770
|
-
if (exit) parts.push(`exit=${exit.code}${exit.at ? ` at ${exit.at}` : ""}`);
|
|
771
|
-
else if (sessionExistsSync(agentId)) {
|
|
772
|
-
const paneExit = listPaneValuesSync(agentId, "#{pane_exit_status}").find((v) => v !== "");
|
|
773
|
-
if (paneExit) parts.push(`pane_exit=${paneExit}`);
|
|
774
|
-
}
|
|
775
|
-
try {
|
|
776
|
-
const logPath = join$1(agentDir(agentId), "output.log");
|
|
777
|
-
if (existsSync(logPath)) {
|
|
778
|
-
const tail = readFileSync(logPath, "utf-8").slice(-1500).trim().split("\n").slice(-6).join(" | ").trim();
|
|
779
|
-
if (tail) parts.push(`output.log tail: ${tail}`);
|
|
780
|
-
}
|
|
781
|
-
} catch {}
|
|
782
|
-
return parts.length ? parts.join("; ") : "no exit trace (exit-status + output.log empty)";
|
|
783
|
-
}
|
|
784
|
-
//#endregion
|
|
785
|
-
//#region ../../lib/cloister/stuck-remediation-state.ts
|
|
786
|
-
init_control_settings();
|
|
787
|
-
init_paths();
|
|
788
|
-
function agentStateDir(agentId) {
|
|
789
|
-
return join$1(getOverdeckHome(), "agents", agentId);
|
|
790
|
-
}
|
|
791
|
-
function statePath(agentId) {
|
|
792
|
-
return join$1(agentStateDir(agentId), "stuck-remediation.json");
|
|
793
|
-
}
|
|
794
|
-
function readStuckRemediationState(agentId) {
|
|
795
|
-
const filePath = statePath(agentId);
|
|
796
|
-
if (!existsSync(filePath)) return null;
|
|
797
|
-
try {
|
|
798
|
-
return JSON.parse(readFileSync(filePath, "utf-8"));
|
|
799
|
-
} catch (error) {
|
|
800
|
-
console.warn(`Failed to read stuck-remediation state for ${agentId}:`, error);
|
|
801
|
-
return null;
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
function writeStuckRemediationState(agentId, state) {
|
|
805
|
-
mkdirSync(agentStateDir(agentId), { recursive: true });
|
|
806
|
-
writeFileSync(statePath(agentId), `${JSON.stringify(state, null, 2)}\n`, "utf-8");
|
|
807
|
-
}
|
|
808
|
-
function clearStuckRemediationState(agentId) {
|
|
809
|
-
const filePath = statePath(agentId);
|
|
810
|
-
if (!existsSync(filePath)) return;
|
|
811
|
-
unlinkSync(filePath);
|
|
812
|
-
}
|
|
813
|
-
//#endregion
|
|
814
|
-
//#region ../../lib/cloister/stuck-remediation.ts
|
|
815
|
-
init_agents();
|
|
816
|
-
init_tmux();
|
|
817
|
-
init_dag();
|
|
818
|
-
init_recovery_trip();
|
|
819
|
-
function issueIdForAgent(agent) {
|
|
820
|
-
return agent.issueId || agent.id.replace(/^agent-/, "").toUpperCase();
|
|
821
|
-
}
|
|
822
|
-
function shouldSkipReviewStatus(status) {
|
|
823
|
-
if (!status) return false;
|
|
824
|
-
if (status.stuck || status.deaconIgnored || status.mergeStatus === "merged" || status.readyForMerge) return true;
|
|
825
|
-
if (status.reviewStatus === "blocked" || status.reviewStatus === "failed") return true;
|
|
826
|
-
if (status.verificationStatus === "failed" || status.testStatus === "failed") return true;
|
|
827
|
-
if (status.reviewStatus === "reviewing" || status.reviewStatus === "passed") return true;
|
|
828
|
-
return status.reviewStatus === "pending" && !!status.reviewRequestedAt;
|
|
829
|
-
}
|
|
830
|
-
/**
|
|
831
|
-
* PAN-2581 (FR-2, residual): phase gate for the health-check poke loop
|
|
832
|
-
* (service.ts pokeAgent → pokeAgentWithEscalation → idle-alive pause), the
|
|
833
|
-
* SECOND independent idleness consumer besides stuck-remediation. A warm-idle
|
|
834
|
-
* work agent on a pipeline-owned issue — and a warm-idle review/test agent
|
|
835
|
-
* after its verdict — must never be poked ("are you stuck?") or idle-alive
|
|
836
|
-
* paused: the poke spends tokens re-explaining the wait, and the pause
|
|
837
|
-
* manufactures the paused-delivery-target deadlock PAN-2461 exists to undo.
|
|
838
|
-
* A genuinely stalled mid-review parent is covered by the PAN-2584 liveness
|
|
839
|
-
* deadline, not pokes. Owed-rework agents (review blocked/failed, tests
|
|
840
|
-
* failed) are ALSO skipped here by design: shouldSkipReviewStatus returns
|
|
841
|
-
* true for those because the PAN-2519 wedged-rework path owns their
|
|
842
|
-
* escalation — the health-check poke loop must not double-drive them.
|
|
843
|
-
* Roles outside work/review/test (plan, strike, flywheel, sequencer) keep
|
|
844
|
-
* their existing idleness semantics.
|
|
845
|
-
*/
|
|
846
|
-
function shouldSkipIdlePokeForAgent(agent, readStatus = getReviewStatusSync) {
|
|
847
|
-
if (!agent) return false;
|
|
848
|
-
if (agent.role !== "work" && agent.role !== "review" && agent.role !== "test") return false;
|
|
849
|
-
return shouldSkipReviewStatus(readStatus((agent.issueId || agent.id.replace(/^agent-/, "").replace(/-(review|test|ship)(-.*)?$/, "").replace(/-slot-\d+$/, "")).toUpperCase()));
|
|
850
|
-
}
|
|
851
|
-
function hasPendingRework(status) {
|
|
852
|
-
if (!status) return false;
|
|
853
|
-
if (status.stuck || status.deaconIgnored || status.mergeStatus === "merged" || status.readyForMerge) return false;
|
|
854
|
-
return status.reviewStatus === "blocked" || status.reviewStatus === "failed" || status.verificationStatus === "failed" || status.testStatus === "failed";
|
|
855
|
-
}
|
|
856
|
-
const STUCK_KILL_REQUEUE_CEILING = 25;
|
|
857
|
-
async function evaluateWedgedReworkAgent(agent, config, now, actions) {
|
|
858
|
-
const agentId = agent.id;
|
|
859
|
-
if (agent.role !== "work" || !agent.workspace) return false;
|
|
860
|
-
const issueId = issueIdForAgent(agent);
|
|
861
|
-
const status = getReviewStatusSync(issueId);
|
|
862
|
-
if (!hasPendingRework(status)) return false;
|
|
863
|
-
const lastActivityMs = getAgentEffectiveLastActivityMs(agentId);
|
|
864
|
-
if (lastActivityMs === null || !Number.isFinite(lastActivityMs)) return false;
|
|
865
|
-
const stuckState = readStuckRemediationState(agentId);
|
|
866
|
-
if (stuckState) {
|
|
867
|
-
const firstStuckMs = new Date(stuckState.firstStuckAt).getTime();
|
|
868
|
-
if (Number.isFinite(firstStuckMs) && lastActivityMs > firstStuckMs) {
|
|
869
|
-
clearStuckRemediationState(agentId);
|
|
870
|
-
return false;
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
const idleMinutes = Math.floor((now - lastActivityMs) / 6e4);
|
|
874
|
-
const lastStage = stuckState?.lastStage ?? 0;
|
|
875
|
-
if (idleMinutes < config.stage3_minutes || lastStage >= 3) return false;
|
|
876
|
-
const firstStuck = firstStuckAt(new Date(lastActivityMs).toISOString(), stuckState);
|
|
877
|
-
if ((status?.autoRequeueCount ?? 0) >= STUCK_KILL_REQUEUE_CEILING) {
|
|
878
|
-
markAgentTroubled(agentId);
|
|
879
|
-
writeStuckRemediationState(agentId, stageState(3, now, firstStuck));
|
|
880
|
-
logAction(actions, transitionAction(3, issueId, idleMinutes, "rework-wedge-troubled"));
|
|
881
|
-
await surfaceStuckNeedsYou(agent, issueId, firstStuck, actions);
|
|
882
|
-
return true;
|
|
883
|
-
}
|
|
884
|
-
killSessionSync(agentId);
|
|
885
|
-
writeStuckRemediationState(agentId, stageState(3, now, firstStuck));
|
|
886
|
-
logAction(actions, transitionAction(3, issueId, idleMinutes, "killed-for-respawn"));
|
|
887
|
-
return true;
|
|
888
|
-
}
|
|
889
|
-
function shouldCheckReadyBeadsForAgent(agent, now) {
|
|
890
|
-
const agentId = agent.id;
|
|
891
|
-
if (!agentId) return false;
|
|
892
|
-
if (agent.status !== "running") return false;
|
|
893
|
-
if (agent.role !== "work") return false;
|
|
894
|
-
if (!agent.workspace) return false;
|
|
895
|
-
const completedAt = agent.completedAt;
|
|
896
|
-
if (agent.paused || agent.troubled || completedAt) return false;
|
|
897
|
-
if (!sessionExistsSync(agentId)) return false;
|
|
898
|
-
if (shouldSkipReviewStatus(getReviewStatusSync(issueIdForAgent(agent)))) return false;
|
|
899
|
-
return isAgentIdleForNudge(agentId, 300 * 1e3, now);
|
|
900
|
-
}
|
|
901
|
-
function firstStuckAt(runtimeLastActivity, stuckState) {
|
|
902
|
-
return stuckState?.firstStuckAt ?? runtimeLastActivity;
|
|
903
|
-
}
|
|
904
|
-
function stageState(stage, now, firstStuck, prev) {
|
|
905
|
-
return {
|
|
906
|
-
lastStage: stage,
|
|
907
|
-
lastStageAt: new Date(now).toISOString(),
|
|
908
|
-
firstStuckAt: firstStuck,
|
|
909
|
-
...prev?.respawnCount !== void 0 ? { respawnCount: prev.respawnCount } : {},
|
|
910
|
-
...prev?.lastRespawnAt !== void 0 ? { lastRespawnAt: prev.lastRespawnAt } : {}
|
|
911
|
-
};
|
|
912
|
-
}
|
|
913
|
-
function transitionAction(stage, issueId, idleMinutes, action) {
|
|
914
|
-
return `[deacon] stuck-remediation stage=${stage} issue=${issueId} idleMin=${idleMinutes} action=${action}`;
|
|
915
|
-
}
|
|
916
|
-
function logAction(actions, action) {
|
|
917
|
-
actions.push(action);
|
|
918
|
-
console.log(action);
|
|
919
|
-
logDeaconEventSync(action);
|
|
920
|
-
}
|
|
921
|
-
async function surfaceStuckNeedsYou(agent, issueId, generation, actions) {
|
|
922
|
-
if (!agent.workspace) return;
|
|
923
|
-
if ((await recordRecoveryFailure(agent.workspace, issueId, "stuck-remediation", generation, 1)).emitNeedsYou) logAction(actions, `[deacon] needs-you ${issueId}: stuck remediation exhausted`);
|
|
924
|
-
}
|
|
925
|
-
async function evaluateAgent(agent, config, now, actions) {
|
|
926
|
-
const agentId = agent.id;
|
|
927
|
-
if (!agentId) return;
|
|
928
|
-
if (agent.status !== "running") return;
|
|
929
|
-
const completedAt = agent.completedAt;
|
|
930
|
-
if (agent.paused || agent.troubled || completedAt) return;
|
|
931
|
-
if (agent.role === "flywheel") {
|
|
932
|
-
await evaluateFlywheelOrchestrator(agent, config, now, actions);
|
|
933
|
-
return;
|
|
934
|
-
}
|
|
935
|
-
if (!sessionExistsSync(agentId)) return;
|
|
936
|
-
if (agent.role === "plan" && agent.auto === true) {
|
|
937
|
-
await evaluateAutoPlanningAgent(agent, config, now, actions);
|
|
938
|
-
return;
|
|
939
|
-
}
|
|
940
|
-
if (await evaluateWedgedReworkAgent(agent, config, now, actions)) return;
|
|
941
|
-
if (!shouldCheckReadyBeadsForAgent(agent, now)) return;
|
|
942
|
-
if (!agent.workspace) return;
|
|
943
|
-
const issueId = issueIdForAgent(agent);
|
|
944
|
-
const plan = readWorkspacePlanSync(agent.workspace);
|
|
945
|
-
if (!plan) return;
|
|
946
|
-
if (getDispatchableItems(plan, /* @__PURE__ */ new Set()).length > 0) return;
|
|
947
|
-
const lastActivityMs = getAgentEffectiveLastActivityMs(agentId);
|
|
948
|
-
if (lastActivityMs === null) return;
|
|
949
|
-
if (!Number.isFinite(lastActivityMs)) return;
|
|
950
|
-
const lastActivity = new Date(lastActivityMs).toISOString();
|
|
951
|
-
const stuckState = readStuckRemediationState(agentId);
|
|
952
|
-
if (stuckState) {
|
|
953
|
-
const firstStuckMs = new Date(stuckState.firstStuckAt).getTime();
|
|
954
|
-
if (Number.isFinite(firstStuckMs) && lastActivityMs > firstStuckMs) {
|
|
955
|
-
clearStuckRemediationState(agentId);
|
|
956
|
-
return;
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
const idleMinutes = Math.floor((now - lastActivityMs) / 6e4);
|
|
960
|
-
const lastStage = stuckState?.lastStage ?? 0;
|
|
961
|
-
const firstStuck = firstStuckAt(lastActivity, stuckState);
|
|
962
|
-
const terminalProviderError = detectTerminalApiErrorSync(capturePaneSync(agentId, 80));
|
|
963
|
-
if (terminalProviderError) {
|
|
964
|
-
markAgentTroubled(agentId);
|
|
965
|
-
writeStuckRemediationState(agentId, stageState(3, now, firstStuck));
|
|
966
|
-
logAction(actions, `${agentId} provider-terminal: ${terminalProviderError.summary}`);
|
|
967
|
-
await surfaceStuckNeedsYou(agent, issueId, firstStuck, actions);
|
|
968
|
-
return;
|
|
969
|
-
}
|
|
970
|
-
if (idleMinutes >= config.stage3_minutes && lastStage < 3) {
|
|
971
|
-
markAgentTroubled(agentId);
|
|
972
|
-
writeStuckRemediationState(agentId, stageState(3, now, firstStuck));
|
|
973
|
-
logAction(actions, transitionAction(3, issueId, idleMinutes, "marked-troubled"));
|
|
974
|
-
await surfaceStuckNeedsYou(agent, issueId, firstStuck, actions);
|
|
975
|
-
return;
|
|
976
|
-
}
|
|
977
|
-
if (idleMinutes >= config.stage2_minutes && lastStage < 2) {
|
|
978
|
-
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) {
|
|
979
|
-
writeStuckRemediationState(agentId, stageState(2, now, firstStuck));
|
|
980
|
-
logAction(actions, transitionAction(2, issueId, idleMinutes, "resumed"));
|
|
981
|
-
} else {
|
|
982
|
-
const action = `${transitionAction(2, issueId, idleMinutes, "resume-failed")} — death: ${describeAgentDeath(agentId)}`;
|
|
983
|
-
console.warn(action);
|
|
984
|
-
logDeaconEventSync(action);
|
|
985
|
-
}
|
|
986
|
-
return;
|
|
987
|
-
}
|
|
988
|
-
if (idleMinutes >= config.stage1_minutes && lastStage < 1) {
|
|
989
|
-
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.`);
|
|
990
|
-
writeStuckRemediationState(agentId, stageState(1, now, firstStuck));
|
|
991
|
-
logAction(actions, transitionAction(1, issueId, idleMinutes, "poked"));
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
async function evaluateAutoPlanningAgent(agent, config, now, actions) {
|
|
995
|
-
const agentId = agent.id;
|
|
996
|
-
if (!isAgentIdleForNudge(agentId, 300 * 1e3, now)) return;
|
|
997
|
-
if (await Effect.runPromise(countPendingAskUserQuestionsForAgent(agentId)) === 0) return;
|
|
998
|
-
const lastActivityMs = getAgentEffectiveLastActivityMs(agentId);
|
|
999
|
-
if (lastActivityMs === null || !Number.isFinite(lastActivityMs)) return;
|
|
1000
|
-
const lastActivity = new Date(lastActivityMs).toISOString();
|
|
1001
|
-
const stuckState = readStuckRemediationState(agentId);
|
|
1002
|
-
if (stuckState) {
|
|
1003
|
-
const firstStuckMs = new Date(stuckState.firstStuckAt).getTime();
|
|
1004
|
-
if (Number.isFinite(firstStuckMs) && lastActivityMs > firstStuckMs) {
|
|
1005
|
-
clearStuckRemediationState(agentId);
|
|
1006
|
-
return;
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
const idleMinutes = Math.floor((now - lastActivityMs) / 6e4);
|
|
1010
|
-
const lastStage = stuckState?.lastStage ?? 0;
|
|
1011
|
-
if (idleMinutes < config.stage1_minutes || lastStage >= 1) return;
|
|
1012
|
-
const issueId = issueIdForAgent(agent);
|
|
1013
|
-
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.`);
|
|
1014
|
-
writeStuckRemediationState(agentId, stageState(1, now, firstStuckAt(lastActivity, stuckState)));
|
|
1015
|
-
logAction(actions, transitionAction(1, issueId, idleMinutes, "auto-planning-default"));
|
|
1016
|
-
}
|
|
1017
|
-
const FLYWHEEL_RESPAWN_WINDOW_MS = 1800 * 1e3;
|
|
1018
|
-
const FLYWHEEL_MAX_RESPAWNS = 3;
|
|
1019
|
-
const FLYWHEEL_ORCHESTRATOR_AGENT_ID = "flywheel-orchestrator";
|
|
1020
|
-
/**
|
|
1021
|
-
* Pure decision for recovering a dead or wedged flywheel orchestrator (no I/O —
|
|
1022
|
-
* side effects live in remediateFlywheelOrchestrator). The respawn cap
|
|
1023
|
-
* (FLYWHEEL_MAX_RESPAWNS within FLYWHEEL_RESPAWN_WINDOW_MS) stops an infinite
|
|
1024
|
-
* relaunch loop: past the cap, escalate to paused+troubled. `hasActiveRun` false
|
|
1025
|
-
* ⇒ the operator stopped the flywheel deliberately ⇒ do not resurrect.
|
|
1026
|
-
*/
|
|
1027
|
-
function decideFlywheelRemediation(opts) {
|
|
1028
|
-
if (!opts.hasActiveRun) return { kind: "noop" };
|
|
1029
|
-
const lastRespawnMs = opts.prev?.lastRespawnAt ? new Date(opts.prev.lastRespawnAt).getTime() : 0;
|
|
1030
|
-
const respawnCount = Number.isFinite(lastRespawnMs) && opts.now - lastRespawnMs < FLYWHEEL_RESPAWN_WINDOW_MS ? opts.prev?.respawnCount ?? 0 : 0;
|
|
1031
|
-
if (respawnCount >= FLYWHEEL_MAX_RESPAWNS) return {
|
|
1032
|
-
kind: "escalate",
|
|
1033
|
-
respawnCount
|
|
1034
|
-
};
|
|
1035
|
-
return {
|
|
1036
|
-
kind: "relaunch",
|
|
1037
|
-
respawnCount: respawnCount + 1
|
|
1038
|
-
};
|
|
1039
|
-
}
|
|
1040
|
-
/** True when the orchestrator's process is actually gone (session missing or dead pane). */
|
|
1041
|
-
function isFlywheelOrchestratorDead(agentId) {
|
|
1042
|
-
if (!sessionExistsSync(agentId)) return true;
|
|
1043
|
-
return listPaneValuesSync(agentId, "#{pane_dead}").some((v) => v === "1");
|
|
1044
|
-
}
|
|
1045
|
-
/**
|
|
1046
|
-
* Recover a dead or wedged flywheel orchestrator: relaunch (capped) or, past the
|
|
1047
|
-
* cap, pause+trouble. `reason` describes why recovery fired (death vs wedge) for
|
|
1048
|
-
* the deacon log. NO_RESUME is intentionally NOT consulted (see header comment) —
|
|
1049
|
-
* the operator gate is the active run (`pan flywheel stop`) / patrol freeze.
|
|
1050
|
-
*/
|
|
1051
|
-
async function remediateFlywheelOrchestrator(agentId, now, actions, reason) {
|
|
1052
|
-
const decision = decideFlywheelRemediation({
|
|
1053
|
-
hasActiveRun: Boolean(getFlywheelActiveRunId()),
|
|
1054
|
-
prev: readStuckRemediationState(agentId),
|
|
1055
|
-
now
|
|
1056
|
-
});
|
|
1057
|
-
if (decision.kind === "noop") return;
|
|
1058
|
-
const { resumeFlywheel, pauseFlywheel } = await import("./flywheel-DXI_WITn.js");
|
|
1059
|
-
const prev = readStuckRemediationState(agentId);
|
|
1060
|
-
const nowIso = new Date(now).toISOString();
|
|
1061
|
-
if (decision.kind === "escalate") {
|
|
1062
|
-
await pauseFlywheel();
|
|
1063
|
-
markAgentTroubled(agentId);
|
|
1064
|
-
writeStuckRemediationState(agentId, {
|
|
1065
|
-
lastStage: 3,
|
|
1066
|
-
lastStageAt: nowIso,
|
|
1067
|
-
firstStuckAt: prev?.firstStuckAt ?? nowIso,
|
|
1068
|
-
respawnCount: decision.respawnCount,
|
|
1069
|
-
lastRespawnAt: prev?.lastRespawnAt
|
|
1070
|
-
});
|
|
1071
|
-
logAction(actions, `[deacon] FLYWHEEL orchestrator ${reason} and exceeded ${FLYWHEEL_MAX_RESPAWNS} relaunches in ${FLYWHEEL_RESPAWN_WINDOW_MS / 6e4}min — paused + troubled; operator needed`);
|
|
1072
|
-
return;
|
|
1073
|
-
}
|
|
1074
|
-
try {
|
|
1075
|
-
killSessionSync(agentId);
|
|
1076
|
-
} catch {}
|
|
1077
|
-
try {
|
|
1078
|
-
await resumeFlywheel({ resumeCause: "system" });
|
|
1079
|
-
writeStuckRemediationState(agentId, {
|
|
1080
|
-
lastStage: 0,
|
|
1081
|
-
lastStageAt: nowIso,
|
|
1082
|
-
firstStuckAt: nowIso,
|
|
1083
|
-
respawnCount: decision.respawnCount,
|
|
1084
|
-
lastRespawnAt: nowIso
|
|
1085
|
-
});
|
|
1086
|
-
logAction(actions, `[deacon] FLYWHEEL orchestrator ${reason} — fresh-launched (relaunch ${decision.respawnCount}/${FLYWHEEL_MAX_RESPAWNS})`);
|
|
1087
|
-
} catch (error) {
|
|
1088
|
-
logAction(actions, `[deacon] FLYWHEEL orchestrator ${reason} — relaunch FAILED: ${error instanceof Error ? error.message : String(error)}`);
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
async function evaluateFlywheelOrchestrator(agent, config, now, actions) {
|
|
1092
|
-
const agentId = agent.id;
|
|
1093
|
-
if (isFlywheelOrchestratorDead(agentId)) {
|
|
1094
|
-
await remediateFlywheelOrchestrator(agentId, now, actions, `DIED (${describeAgentDeath(agentId)})`);
|
|
1095
|
-
return;
|
|
1096
|
-
}
|
|
1097
|
-
if (!isAgentIdleForNudge(agentId, 300 * 1e3, now)) return;
|
|
1098
|
-
const runtime = getAgentRuntimeStateSync(agentId);
|
|
1099
|
-
if (!runtime?.lastActivity) return;
|
|
1100
|
-
const lastActivityMs = new Date(runtime.lastActivity).getTime();
|
|
1101
|
-
if (!Number.isFinite(lastActivityMs)) return;
|
|
1102
|
-
const stuckState = readStuckRemediationState(agentId);
|
|
1103
|
-
if (stuckState) {
|
|
1104
|
-
const firstStuckMs = new Date(stuckState.firstStuckAt).getTime();
|
|
1105
|
-
if (Number.isFinite(firstStuckMs) && lastActivityMs > firstStuckMs) {
|
|
1106
|
-
clearStuckRemediationState(agentId);
|
|
1107
|
-
return;
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
const idleMinutes = Math.floor((now - lastActivityMs) / 6e4);
|
|
1111
|
-
const lastStage = stuckState?.lastStage ?? 0;
|
|
1112
|
-
const firstStuck = firstStuckAt(runtime.lastActivity, stuckState);
|
|
1113
|
-
if (idleMinutes >= config.flywheel_stage3_minutes && lastStage < 3) {
|
|
1114
|
-
await remediateFlywheelOrchestrator(agentId, now, actions, `wedged (idle ${idleMinutes}min)`);
|
|
1115
|
-
return;
|
|
1116
|
-
}
|
|
1117
|
-
if (idleMinutes >= config.flywheel_stage2_minutes && lastStage < 2) {
|
|
1118
|
-
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.`);
|
|
1119
|
-
writeStuckRemediationState(agentId, stageState(2, now, firstStuck, stuckState));
|
|
1120
|
-
logAction(actions, transitionAction(2, "FLYWHEEL", idleMinutes, "escalated-nudge"));
|
|
1121
|
-
return;
|
|
1122
|
-
}
|
|
1123
|
-
if (idleMinutes >= config.flywheel_stage1_minutes && lastStage < 1) {
|
|
1124
|
-
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.`);
|
|
1125
|
-
writeStuckRemediationState(agentId, stageState(1, now, firstStuck, stuckState));
|
|
1126
|
-
logAction(actions, transitionAction(1, "FLYWHEEL", idleMinutes, "poked"));
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
async function reconcileActiveFlywheelWithoutRunningAgent(now, actions) {
|
|
1130
|
-
if (!getFlywheelActiveRunId()) return;
|
|
1131
|
-
if (isFlywheelGloballyPaused()) return;
|
|
1132
|
-
if (sessionExistsSync(FLYWHEEL_ORCHESTRATOR_AGENT_ID)) return;
|
|
1133
|
-
await remediateFlywheelOrchestrator(FLYWHEEL_ORCHESTRATOR_AGENT_ID, now, actions, `DIED (${describeAgentDeath(FLYWHEEL_ORCHESTRATOR_AGENT_ID)})`);
|
|
1134
|
-
}
|
|
1135
|
-
async function checkStuckAgentRemediation(opts = {}) {
|
|
1136
|
-
const config = loadCloisterConfigSync().stuck_remediation ?? DEFAULT_CLOISTER_CONFIG.stuck_remediation;
|
|
1137
|
-
if (!config.enabled) return [];
|
|
1138
|
-
const actions = [];
|
|
1139
|
-
const now = opts.now ?? Date.now();
|
|
1140
|
-
const runningAgents = listRunningAgentsSync();
|
|
1141
|
-
let sawFlywheelOrchestrator = false;
|
|
1142
|
-
for (const agent of runningAgents) {
|
|
1143
|
-
if (agent.id === FLYWHEEL_ORCHESTRATOR_AGENT_ID || agent.role === "flywheel") sawFlywheelOrchestrator = true;
|
|
1144
|
-
try {
|
|
1145
|
-
await evaluateAgent(agent, config, now, actions);
|
|
1146
|
-
} catch (error) {
|
|
1147
|
-
const message = `[deacon] stuck-remediation agent=${agent.id || "(unknown)"} error=${error instanceof Error ? error.message : String(error)}`;
|
|
1148
|
-
console.error(message, error);
|
|
1149
|
-
logDeaconEventSync(message);
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
if (!sawFlywheelOrchestrator) try {
|
|
1153
|
-
await reconcileActiveFlywheelWithoutRunningAgent(now, actions);
|
|
1154
|
-
} catch (error) {
|
|
1155
|
-
const message = `[deacon] stuck-remediation agent=${FLYWHEEL_ORCHESTRATOR_AGENT_ID} error=${error instanceof Error ? error.message : String(error)}`;
|
|
1156
|
-
console.error(message, error);
|
|
1157
|
-
logDeaconEventSync(message);
|
|
1158
|
-
}
|
|
1159
|
-
return actions;
|
|
1160
|
-
}
|
|
1161
|
-
//#endregion
|
|
1162
|
-
export { getAgentEffectiveLastActivityMs as a, shouldSkipReviewStatus as i, decideFlywheelRemediation as n, isAgentIdleForNudge as o, shouldSkipIdlePokeForAgent as r, getRuntimeForAgent as s, checkStuckAgentRemediation as t };
|
|
1163
|
-
|
|
1164
|
-
//# sourceMappingURL=stuck-remediation-Di5JYkoo.js.map
|