@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
package/server/server.js
CHANGED
|
@@ -1,120 +1,121 @@
|
|
|
1
1
|
import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM, r as __exportAll, t as __commonJSMin } from "./rolldown-runtime-DNCzzKnI.js";
|
|
2
|
-
import { $n as
|
|
3
|
-
import { i as shouldRefuseHostDashboardPort, n as isNonPrimaryCheckoutRoot, r as readHostDashboardApiPort, t as getDashboardIdentity } from "./identity-
|
|
4
|
-
import { $ as
|
|
5
|
-
import { h as loadConfigSync$1, p as init_config, s as getDashboardApiUrlSync } from "./config-
|
|
6
|
-
import {
|
|
7
|
-
import { A as init_paths$1, O as OVERDECK_MIGRATION_PATH, f as init_infra, i as DbLive, k as getOverdeckDatabasePath, u as TmuxLive } from "./infra-
|
|
8
|
-
import { n as openDatabase, t as init_driver } from "./driver-
|
|
9
|
-
import { a as updateIssueRecord, i as init_record_update, r as clearRecordPipelineClosedOutSync } from "./record-update-
|
|
10
|
-
import {
|
|
11
|
-
import { a as getWorkspaceForIssue, c as listProjectTargets, f as resolveWorkspaceForCwd, i as getWorkspaceById, l as listProjects$1, o as init_resolver, s as listPinnedDocs, u as listWorkspaces } from "./resolver-
|
|
12
|
-
import { a as init_event_store, i as initEventStore, n as getEventStore } from "./event-store-
|
|
13
|
-
import { A as AgentRuntimeSnapshot, C as FlywheelStatus, E as SystemHealthSnapshot, M as ReviewStatusSnapshot, O as MemoryObservation, S as FlywheelRunId, T as DomainEvent, b as PanRpcGroup, j as AgentSnapshot, l as ContextLayerSaveRequest, n as COMPOSER_COMMAND_MANIFEST, p as FlywheelStats, r as compareIssueIds, s as getHarnessBehavior, t as init_src, u as ContextPreviewRequest, w as EDITORS, x as WS_METHODS, y as PanRpcError } from "./src-
|
|
14
|
-
import { a as EventStoreServiceLive, c as
|
|
15
|
-
import { c as init_agents, g as logAgentLifecycleSync, h as init_persistent_logger, n as AgentsResolverLive, u as listAllAgentsSync } from "./agents-
|
|
16
|
-
import { c as resolveMemoryRoot, d as resolveRagRunsFile, i as init_paths$2, l as resolveObservationsFile, m as resolveWorkspaceMemoryRoot, r as ensureParentDir, s as resolveMemoryBase, t as assertMemorySafeSegment } from "./paths-
|
|
17
|
-
import { i as recordBriefingSessionStart, n as ensureSessionContextBriefingFile, r as init_briefing_freshness, t as appendFreshBriefingUpdate } from "./briefing-freshness-
|
|
18
|
-
import { n as listFeatureRegistryEntries, t as init_feature_registry_storage } from "./feature-registry-storage-
|
|
19
|
-
import { a as diffAgainstMain, c as diffCheckpoints, d as diffPatchSinceCommit, f as findCommitAtTime,
|
|
20
|
-
import {
|
|
21
|
-
import { t as init_behavior } from "./behavior-
|
|
22
|
-
import { a as getCostForIssueAggregateSync, c as getDailyTrendsSync, d as init_cost_sync, l as getModelRollupSync, n as getBackgroundCostBySourceSync, p as queryCostEventsSync, r as getCavemanExperimentDataSync, s as getCostsByIssueSync, u as getTodayCostSync } from "./cost-sync-
|
|
23
|
-
import { a as generateHealthSummary, c as CostDoorLive, d as CostWriter, l as CostResolver, n as readCloisterStateFile, o as getAgentHealth, s as getAgentsNeedingAttention, t as getCloisterService, u as CostResolverLive } from "./service-
|
|
24
|
-
import { n as isBackgroundFeatureEnabled, t as init_features } from "./features-
|
|
25
|
-
import { i as init_settings, r as getMemoryWorkerConcurrency, t as areMemoryObservationsEnabled } from "./settings-
|
|
26
|
-
import { i as updateMemoryHealth, n as extractWithProviderPolicy, r as init_health, t as init_providers$1 } from "./providers-
|
|
27
|
-
import { C as
|
|
28
|
-
import { i as ensureInternalTokenSync, o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-
|
|
29
|
-
import { $ as
|
|
30
|
-
import { C as generateLauncherScriptSync, D as normalizeModelOverrideSync, E as init_model_validation, O as requireModelOverrideSync, T as MODEL_ID_PATTERN, w as init_launcher_generator } from "./auto-spawn-consent-
|
|
31
|
-
import { a as init_claude_permissions, r as getClaudePermissionFlagsStringSync } from "./claude-permissions-
|
|
32
|
-
import { C as
|
|
33
|
-
import { l as init_codex, s as findRolloutPath } from "./codex-
|
|
34
|
-
import { i as prepareHarnessLaunch, r as init_harness_binary } from "./harness-binary-
|
|
35
|
-
import { D as setSetting, E as setMergeTrainEnabled, S as setFlywheelAutoPickupBacklog, T as setLastCleanShutdownAt, b as setDeaconGloballyPausedSync, c as init_control_settings, d as isDeaconGloballyPausedSync, f as isFlywheelAutoPickupBacklog, g as setBootReconciliationDecision, h as isMergeTrainEnabled, l as isCloisterSpawnsPausedSync, m as isFlywheelRequireUatBeforeMerge, n as FLYWHEEL_GLOBAL_PAUSE_KEY, p as isFlywheelGloballyPaused, r as getBootReconciliationState, s as getSetting, t as FLYWHEEL_ACTIVE_RUN_ID_KEY, v as setCloisterSpawnsPausedSync, w as setFlywheelRequireUatBeforeMerge } from "./control-settings-
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import { a as
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import { a as
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
44
|
-
import { a as
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
47
|
-
import { n as
|
|
48
|
-
import {
|
|
49
|
-
import { r as
|
|
50
|
-
import { r as
|
|
51
|
-
import { r as
|
|
52
|
-
import { n as
|
|
53
|
-
import { a as
|
|
54
|
-
import { a as
|
|
55
|
-
import {
|
|
56
|
-
import {
|
|
57
|
-
import {
|
|
58
|
-
import { a as
|
|
59
|
-
import {
|
|
60
|
-
import {
|
|
61
|
-
import {
|
|
62
|
-
import {
|
|
63
|
-
import {
|
|
64
|
-
import { a as enrichSessions, c as searchSessions, i as CostThresholdError, l as embed, n as getSessionsFeedFacets, o as embedSessions, r as listSessionsFeed, s as parseRelativeTime, t as scan } from "./scanner-
|
|
65
|
-
import { c as tailEventsSync, n as deduplicateEventsSync, s as readEventsSync } from "./events-
|
|
66
|
-
import { n as recordBackgroundAiCost, t as init_cost } from "./cost-
|
|
67
|
-
import { a as getByIssueId, i as parseFlywheelStatsWindow, n as derivePipelineRunStatsInputs, o as markFixed, r as computeFlywheelStats, s as upsert, t as listSubstrateBugWeights } from "./substrate-bug-weights-service-
|
|
68
|
-
import { n as writeSequenceMd, t as parseSequenceMd } from "./sequence-io
|
|
69
|
-
import { _ as normalizeGate, d as computeEpicGroups, f as computeLanes, h as init_pickup, l as classifyIssue, m as computeWaves, p as computeStats, u as computeCohort, v as selectNeedsPlanning } from "./pickup-
|
|
70
|
-
import { C as readCurrentLatestFlywheelStatus, D as writeFlywheelLaunchMetadata, E as subscribeLatestFlywheelStatus, F as setItemRequirements, G as liveOrderIssueLookup, H as getBook, I as setSettings, L as setStatus, M as moveItem, N as removeItem, O as writeLatestFlywheelStatus, P as renameBook, R as backlogCandidates, S as nextFlywheelRunId, T as resolveLiveFlywheelRunId, U as getBookAsync, W as listBooks, a as isFlywheelDevcontainerRuntime, b as isFlywheelRunId, f as spawnFlywheelAgent, g as abortFlywheelRun, j as createBook, k as addItems, p as buildClassifyLookups, s as loadResumeSessionId, t as FLYWHEEL_ORCHESTRATOR_AGENT_ID, u as saveResumeSessionId, v as getFlywheelRunDetail, w as readFlywheelLaunchMetadata, x as listFlywheelRuns, z as computeBookProgress } from "./flywheel-
|
|
71
|
-
import {
|
|
72
|
-
import {
|
|
73
|
-
import {
|
|
74
|
-
import {
|
|
75
|
-
import {
|
|
76
|
-
import {
|
|
77
|
-
import {
|
|
78
|
-
import {
|
|
79
|
-
import "./
|
|
80
|
-
import
|
|
81
|
-
import {
|
|
82
|
-
import {
|
|
83
|
-
import {
|
|
84
|
-
import {
|
|
85
|
-
import {
|
|
86
|
-
import {
|
|
87
|
-
import {
|
|
88
|
-
import {
|
|
89
|
-
import {
|
|
90
|
-
import { a as loadWorkspaceMetadataSync } from "./workspace-metadata-
|
|
91
|
-
import { d as killRemoteAgent, m as loadRemoteAgentState, o as getRemoteAgentOutput, r as checkRemoteSpendCap, s as init_remote_agents, v as sendToRemoteAgent, y as spawnRemoteAgent } from "./remote-agents-
|
|
92
|
-
import {
|
|
93
|
-
import { r as
|
|
94
|
-
import {
|
|
95
|
-
import { n as
|
|
96
|
-
import { n as
|
|
97
|
-
import {
|
|
98
|
-
import {
|
|
99
|
-
import {
|
|
100
|
-
import {
|
|
101
|
-
import {
|
|
102
|
-
import { t as
|
|
103
|
-
import {
|
|
104
|
-
import {
|
|
105
|
-
import {
|
|
106
|
-
import { a as
|
|
107
|
-
import {
|
|
108
|
-
import { t as
|
|
109
|
-
import {
|
|
110
|
-
import {
|
|
111
|
-
import { i as
|
|
112
|
-
import { n as
|
|
113
|
-
import "./
|
|
114
|
-
import
|
|
115
|
-
import {
|
|
116
|
-
import {
|
|
117
|
-
import { r as
|
|
2
|
+
import { $n as updateProjectsConfigText, $r as GitHubApiError, $t as findProjectByPathSync, A as validateTieredExecutionConfig, An as resolveProjectKeyForCwdAsync, Ar as MODEL_DEPRECATIONS, Bi as isDevMode, Cn as registerProjectSync, Cr as DEFAULT_ROLES, Ct as flushAllPendingAutoCommits, D as resolveTieredExecutionBlock, Di as activeDeploymentRepoRoot, Dn as resolveProjectFromIssue, E as init_tier_table, En as resolveInfraRepo, Fr as modelSupportsImagesSync, Gr as COMPLIANCE_MODES, Hn as validateVersionSyncConfig, Ht as init_state_read_home, Ii as getLegacyHome, In as setProjectMergeTrain, Ir as resolveModelIdSync, Jt as PROJECTS_CONFIG_FILE, Kn as extractPrefixSync, Kr as PARENT_MODEL_REF, Kt as init_project_key, Li as getOverdeckHome, Mi as getDocsDisableStatePath, Mr as getModelEffortLevelsSync, Ni as getDocsIndexPath, Nr as hasModelCapabilitySync, O as resolveTieredExecutionEnabled, On as resolveProjectFromIssueSync, Or as resolveModel, Pi as getDocsTelemetryPath, Pn as setProjectAutoMergeDefault, Pr as init_model_capabilities, Qn as init_projects_config_write, Ri as init_paths, Rn as setProjectSwarmPolicy, Sr as init_registry, T as TieredExecutionConfigError, Ti as SYNC_SOURCES, Tr as computeModelOrigin, Tt as init_auto_commit, Ui as sessionFilePath, Un as init_projects_cache_events, Ut as resolveStateReadHomeAsync, Vi as packageRoot, Wn as subscribeProjectsConfigInvalidation, Wt as resolveStateReadHomeSync, Y as init_record, Yn as parseIssueIdSync, Yt as ProjectRenameError, Zr as FsError, Zt as extractTeamPrefix, _ as mergeConfigs, _i as LOGS_DIR, _n as listProjectsAsync, b as mergeTtsDaemonConfigs, bn as loadProjectsConfigSync, br as init_openai_compatible_proxy, c as init_load, ci as init_errors, d as isTldrEnabledSync, er as require_dist$1, f as loadConfigNoMigration, fn as init_projects, fr as getProviderForModelSync, g as jsYaml, gn as listProjects, h as init_js_yaml, hn as invalidateProjectsConfigCache, i as getConversationsConfig, ii as ProcessSpawnError, ji as getDocsBudgetStatePath, jn as resolveProjectPath, ki as encodeClaudeProjectDir, kr as MODEL_CAPABILITIES, lr as getBuiltInDefaultHarness, m as updateConversationsConfig, mi as CLAUDE_DIR, n as clearConfigCache, o as getGlobalConfigPath, oi as TrackerError, on as getProjectSync, p as loadConfigSync, pr as init_providers, q as getIssueWorkspacePath, qn as init_issue_id, qr as ROLE_EFFORTS, qt as projectKey, r as getConversationSearchConfigSync, rn as getIssuePrefix, rr as init_harness_policy, s as getOpenInEditorCommand, sr as UnknownModelError, t as init_config_yaml, tn as findProjectByTeamSync, tr as canUseHarnessSync, tt as readIssueRecordSync, ur as getKimiAnthropicBaseUrl, v as getDefaultDocsConfig, vi as OVERDECK_HOME, vn as listProjectsSync, wn as renameProject, wr as DEFAULT_WORKHORSES, wt as flushAutoCommits, x as DEFAULT_CONFIG$1, xr as defaultBackgroundAiFeatures, y as getDefaultTtsDaemonConfig, yr as getDashScopeUpstreamBaseUrl, zi as isDeploymentGenerationRoot } from "./config-yaml-D9nfpEx1.js";
|
|
3
|
+
import { i as shouldRefuseHostDashboardPort, n as isNonPrimaryCheckoutRoot, r as readHostDashboardApiPort, t as getDashboardIdentity } from "./identity-C23uY8dZ.js";
|
|
4
|
+
import { $ as ComposerCommandParseError, A as isInsideGitWorkTree, B as cleanupConversationAttachments, C as handleConversationClearForkState, Ct as jsonResponse, D as handleConversationResume, E as handleConversationRestartAll, F as startConversationModelBackfill, G as getConversationAttachmentsRoot, H as cleanupUnreferencedConversationAttachments, I as stopConversationRuntime, J as removeConversationAttachment, K as hasConversationAttachment, L as tmuxSessionExists, M as resolveRegisteredProject, N as shouldReportUnresolvedLiveSession, O as handleConversationStop, P as spawnConversationSession, Q as resolvePolicy, R as waitForPiTuiReady, S as conversationSessionAliveFromState, St as getDefaultCwd, T as handleConversationDelete, U as ensureConversationAttachmentDir, V as cleanupOrphanedConversationAttachments, W as extractConversationAttachmentPaths, X as composerCommandResultHttpStatus, Y as runInBatches, Z as handleComposerCommandMessage, _ as isPiControlChannelHarness, _t as getHeaderFromMap, a as agentsRouteLayer, at as resolveRequestedStartedBy, b as validateConversationControlAckOrigin, bt as validateOriginHeaders, c as codexConversationPendingInput, d as handleConversationCodexApproval, dt as hasDashboardInternalToken, et as ComposerCommandConfirmationError, f as handleConversationCompact, ft as rejectUnauthorizedDashboardRequest, g as handleConversationThinkingLevel, gt as waitForSessionRespawn, h as handleConversationPlanAction, ht as isRespawnPending, it as isInternalAgentRequest, j as resolveAllowedHarness, k as handleConversationSwitchModel, l as deliverConversationViaControlChannel, lt as dashboardCsrfToken, m as handleConversationDeliveryMethod, mt as rejectUnsafeDashboardMutationRequest, nt as evaluateSpawnGuardrails, o as saveAgentStateAndEmitEvent, p as handleConversationControlAck, pt as rejectUnauthorizedDashboardSessionMintRequest, q as isManagedConversationAttachmentPath, rt as invalidateAgentsCache, s as saveAgentStateAndEmitEventProgram, st as panCliInvocation, t as specialistsRouteLayer, tt as composerCommandConfirmationFromBody, u as handleConversationAbort, ut as dashboardSessionCookieHeader, v as pickDeliverAs, vt as isTrustedOriginForHost, w as handleConversationCreate, wt as jsonStringResponse, x as conversationNeedsRunningRepair, xt as httpHandler, y as resolveConversationDeliveryMethod, yt as validateOrigin$1, z as waitForTmuxSession$1 } from "./specialists-b0dMMjWq.js";
|
|
5
|
+
import { h as loadConfigSync$1, p as init_config, s as getDashboardApiUrlSync } from "./config-ZGjvuR6J.js";
|
|
6
|
+
import { c as emitDashboardLifecycleSync, l as init_activity_logger, o as emitActivityEntrySync, s as emitActivityTtsSync, t as appendDomainEventAsync } from "./activity-logger-BWZhVphb.js";
|
|
7
|
+
import { A as init_paths$1, O as OVERDECK_MIGRATION_PATH, f as init_infra, i as DbLive, k as getOverdeckDatabasePath, u as TmuxLive } from "./infra-CHIvOb9q.js";
|
|
8
|
+
import { n as openDatabase, t as init_driver } from "./driver-BtcFz-qu.js";
|
|
9
|
+
import { a as updateIssueRecord, i as init_record_update, r as clearRecordPipelineClosedOutSync } from "./record-update-dBGxL9OC.js";
|
|
10
|
+
import { B as sendKeys, C as init_tmux, E as killSession, L as resizeWindow, S as getWindowDimensions, T as isPaneDead, U as sessionExists, V as sendKeysAsync, X as deliveryVerifyLine, Y as activeComposerRegion, Z as init_pane_composer, a as capturePaneText, dt as init_child_env, j as listSessionNames, lt as buildChildEnvSync, o as capturePaneViewport, ot as init_ui_theme, r as capturePane, s as createSession, st as setUiTheme, t as buildTmuxArgs, u as ensureManagedTmuxContextOnce, ut as buildChildEnvWithoutTmuxSync, w as isHarnessProcessAlive } from "./tmux-DWEc4Ld9.js";
|
|
11
|
+
import { a as getWorkspaceForIssue, c as listProjectTargets, f as resolveWorkspaceForCwd, i as getWorkspaceById, l as listProjects$1, o as init_resolver, s as listPinnedDocs, u as listWorkspaces } from "./resolver-gxv97jsQ.js";
|
|
12
|
+
import { a as init_event_store, i as initEventStore, n as getEventStore } from "./event-store-BCSgMubf.js";
|
|
13
|
+
import { A as AgentRuntimeSnapshot, C as FlywheelStatus, E as SystemHealthSnapshot, M as ReviewStatusSnapshot, O as MemoryObservation, S as FlywheelRunId, T as DomainEvent, b as PanRpcGroup, j as AgentSnapshot, l as ContextLayerSaveRequest, n as COMPOSER_COMMAND_MANIFEST, p as FlywheelStats, r as compareIssueIds, s as getHarnessBehavior, t as init_src, u as ContextPreviewRequest, w as EDITORS, x as WS_METHODS, y as PanRpcError } from "./src-CY2Wl8IX.js";
|
|
14
|
+
import { a as EventStoreServiceLive, c as ReadModelService, f as toAgentResolution, i as EventStoreService, l as ReadModelServiceLive, m as toRole, n as IssueLifecycleLive, o as startProjectCiRefillAfterProjectionReady, p as toAgentStatus, s as resolveDefaultBranchHead, t as IssueLifecycle, u as activityEntriesFromStoredEvents } from "./issue-lifecycle-D9nLErvS.js";
|
|
15
|
+
import { c as init_agents, g as logAgentLifecycleSync, h as init_persistent_logger, n as AgentsResolverLive, u as listAllAgentsSync } from "./agents-jXgqpHca.js";
|
|
16
|
+
import { c as resolveMemoryRoot, d as resolveRagRunsFile, i as init_paths$2, l as resolveObservationsFile, m as resolveWorkspaceMemoryRoot, r as ensureParentDir, s as resolveMemoryBase, t as assertMemorySafeSegment } from "./paths-DEe9j-kw.js";
|
|
17
|
+
import { i as recordBriefingSessionStart, n as ensureSessionContextBriefingFile, r as init_briefing_freshness, t as appendFreshBriefingUpdate } from "./briefing-freshness-e_OEYZEe.js";
|
|
18
|
+
import { n as listFeatureRegistryEntries, t as init_feature_registry_storage } from "./feature-registry-storage-zh3ZXW6f.js";
|
|
19
|
+
import { a as diffAgainstMain, c as diffCheckpoints, d as diffPatchSinceCommit, f as findCommitAtTime, h as listCheckpoints, l as diffFilesAgainstHead, o as diffAgainstMainFiles, s as diffCheckpointFiles, t as captureCheckpoint, u as diffPatchFilesAgainstHead } from "./checkpoint-manager-DOwRGFff.js";
|
|
20
|
+
import { $ as deliverCommitForReview, A as saveAgentStateSync, An as init_runtime_census, At as init_agent_input_detection, Dt as scanPendingInputsPromise, Et as isInteractiveRoleAgent, Gn as init_concurrency, H as waitForReadySignal, Ht as init_messaging, Ii as init_agent_record_sync, It as answerSessionPaneChoice, Jr as injectPiConversationMemory, Kt as init_operator_interventions, Li as readAgentHarnessModelRecordSync, Lt as captureSessionPaneChoice, Mn as refreshRuntimeCensus, Mr as resolveImplicitStaffing, Nn as runtimeCensusHasHarnessProcess, On as getRuntimeCensus, Ot as detectAwaitingInputForAgent, Rt as init_session_pane_choice, U as getAgentRuntimeState, Un as emergencyBrake, Ut as messageAgent, W as getAgentRuntimeStateSync, Wr as getProviderAuthMode, _n as listAgentStates, ai as init_claude_auth, ar as deliverAgentMessage, br as checkCodexAuthStatus, bt as getAgentJsonlMtime, et as init_tier_supervisor, f as getAgentDir, g as getAgentStateSync, gn as init_queries, hi as init_openai_auth, hr as probeTranscriptSince, ii as getClaudeAuthStatus, it as supervisorAgentId, jn as panePidsForSession, jr as init_staffing, kn as getRuntimeCensusSnapshot, kt as detectAwaitingInputFromPaneSync, li as getProviderEnvForModel, m as getAgentState, mi as getOpenAIAuthStatus, mr as init_transcript_landing, pr as captureTranscriptUserRecordSnapshot, q as init_agents$1, qt as operatorInterventionEvent, vn as listRunningAgents, vt as computeAgentEnrichment, wt as init_agent_enrichment, xr as init_codex_auth, yn as listRunningAgentsSync, yt as countPendingAskUserQuestionsForAgent, z as normalizeAgentId, zi as init_agent_runtime_mirror } from "./agent-state-BJhGIJZe.js";
|
|
21
|
+
import { t as init_behavior } from "./behavior-BiCQzqyT.js";
|
|
22
|
+
import { a as getCostForIssueAggregateSync, c as getDailyTrendsSync, d as init_cost_sync, l as getModelRollupSync, n as getBackgroundCostBySourceSync, p as queryCostEventsSync, r as getCavemanExperimentDataSync, s as getCostsByIssueSync, u as getTodayCostSync } from "./cost-sync-DOkdE_yB.js";
|
|
23
|
+
import { a as generateHealthSummary, c as CostDoorLive, d as CostWriter, l as CostResolver, n as readCloisterStateFile, o as getAgentHealth, s as getAgentsNeedingAttention, t as getCloisterService, u as CostResolverLive } from "./service-CEp-3iow.js";
|
|
24
|
+
import { n as isBackgroundFeatureEnabled, t as init_features } from "./features-BGntOWdy.js";
|
|
25
|
+
import { i as init_settings, r as getMemoryWorkerConcurrency, t as areMemoryObservationsEnabled } from "./settings-Ch2pCVtt.js";
|
|
26
|
+
import { i as updateMemoryHealth, n as extractWithProviderPolicy, r as init_health, t as init_providers$1 } from "./providers-BL1I66sM.js";
|
|
27
|
+
import { C as isCliproxyRunning, D as restartCliproxy, E as readPidFile, O as startCliproxy, S as isCliproxyInstalled, b as init_cliproxy, k as stopCliproxy, o as bridgeCodexAuthToCliproxy, p as getCliproxyAuthDir, x as installCliproxy } from "./cliproxy-BpYpkogS.js";
|
|
28
|
+
import { i as ensureInternalTokenSync, o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-DoVzb4b7.js";
|
|
29
|
+
import { $ as unarchiveConversation, A as init_conversations, C as getConversationByName, E as getStuckForks, F as listFavoritedIds, G as setConversationClaudeSessionId, H as removeFavorite, I as markConversationActive, L as markConversationEnded, N as listArchivedConversationsWithEnrichment, O as importLegacyConversation, P as listConversations, Q as setImportedConversationLinks, R as markConversationRunning, S as getConversationById, St as init_discovered_sessions, T as getConversationLedgerCosts, V as recordConversationHandoff, W as setClearedToConvId, X as setFavorite, Y as setConversationProjectKey, Z as setForkRequest, _ as canRefineTitle, _t as getDiscoveredSessionById, b as createConversation, bt as getDiscoveredStats, ct as aggregateDiscoveredSessionCost, dt as countDiscoveredSessions, et as updateConversationCost, h as archiveConversation, ht as findDiscoveredSessions, it as updateForkStatus, j as isAgentConversationName, k as incrementForkRetryCount, lt as aggregateDiscoveredSessionCostBy, nt as updateConversationForkFallbackReason, rt as updateConversationTitle, v as canReplaceTitle, w as getConversationByTmuxSession, x as getConversationByClaudeSessionId, yt as getDiscoveredSessionBySessionId } from "./conversations-C75EFFjf.js";
|
|
30
|
+
import { C as generateLauncherScriptSync, D as normalizeModelOverrideSync, E as init_model_validation, O as requireModelOverrideSync, T as MODEL_ID_PATTERN, w as init_launcher_generator } from "./auto-spawn-consent-Dc4mtM-B.js";
|
|
31
|
+
import { a as init_claude_permissions, r as getClaudePermissionFlagsStringSync } from "./claude-permissions-Bc5kjX1q.js";
|
|
32
|
+
import { C as codexGlobalContextFile, D as init_layers, E as globalContextFile$1, F as resolveWorkspaceContextFile, L as workspaceContextFile, P as resolveProjectContextFile, b as renderForHarness, c as hasManagedRegion, f as userContentOutsideRegion, i as workspaceContextWithoutProjectLayer, l as init_render, r as init_assemble, s as configDisabledRuleNames, w as ensureProjectLayer, x as validateTemplate, y as init_harness } from "./assemble-CyvEBmmq.js";
|
|
33
|
+
import { l as init_codex, s as findRolloutPath } from "./codex-KaSKE-R3.js";
|
|
34
|
+
import { i as prepareHarnessLaunch, r as init_harness_binary } from "./harness-binary-tMmgJfC1.js";
|
|
35
|
+
import { D as setSetting, E as setMergeTrainEnabled, S as setFlywheelAutoPickupBacklog, T as setLastCleanShutdownAt, b as setDeaconGloballyPausedSync, c as init_control_settings, d as isDeaconGloballyPausedSync, f as isFlywheelAutoPickupBacklog, g as setBootReconciliationDecision, h as isMergeTrainEnabled, l as isCloisterSpawnsPausedSync, m as isFlywheelRequireUatBeforeMerge, n as FLYWHEEL_GLOBAL_PAUSE_KEY, p as isFlywheelGloballyPaused, r as getBootReconciliationState, s as getSetting, t as FLYWHEEL_ACTIVE_RUN_ID_KEY, v as setCloisterSpawnsPausedSync, w as setFlywheelRequireUatBeforeMerge } from "./control-settings-BMoDHY1G.js";
|
|
36
|
+
import { n as init_review_status_source, t as classifyAdvancingSessionLifecycle } from "./review-status-source-Jq0BXmn3.js";
|
|
37
|
+
import { a as PAN_DIRNAME, d as PENDING_PROMOTION_FILENAME, f as WORKSPACE_RUNTIME_DIRNAME, i as PAN_CONTINUE_FILENAME, m as init_types, p as asPanSpecDocument } from "./types-pLpbsNto.js";
|
|
38
|
+
import { C as init_specs, D as writeSpecDocument, N as getProjectPanPaths, O as writeSpecForIssue, P as init_paths$3, S as findSpecByIssue, a as findWorkspaceDraftPlan, b as subItemsOf, c as isPlanningComplete, d as readPlan, h as readWorkspacePlanSync, m as readWorkspacePlan, r as findPlan, s as init_io, y as init_types$1 } from "./io-DKrWd3gX.js";
|
|
39
|
+
import { n as resolveHarness, t as init_harness_resolve } from "./harness-resolve-DusNpVEe.js";
|
|
40
|
+
import { a as loadCloisterConfigSync, o as saveCloisterConfigSync, r as init_config$1, s as shouldAutoStart } from "./config-Doq_tF-f.js";
|
|
41
|
+
import { a as init_state_home, c as isStateMigrated, i as ensureStateWorktree, r as clearStateMigrationCache, s as inspectStateMigration } from "./state-home-DdG8erBI.js";
|
|
42
|
+
import { i as checkPrdGateSync, s as promoteWorkspacePrdDraft, t as init_pan_dir } from "./pan-dir-BMda7tQj.js";
|
|
43
|
+
import { a as init_lifecycle_io, t as appendContinueSessionEntryForIssue } from "./lifecycle-io-6WL46dsB.js";
|
|
44
|
+
import { a as init_tracker_config, i as initTrackerConfigCache, n as getLinearApiKey, r as getRallyConfig, t as getGitHubConfig } from "./tracker-config-CJzPhSHv.js";
|
|
45
|
+
import { r as init_swarm_readiness, t as analyzeSwarmReadiness } from "./swarm-readiness-CMWAQuWM.js";
|
|
46
|
+
import { n as AgentStateServiceLive } from "./agent-state-service-CiIuwzIs.js";
|
|
47
|
+
import { i as PlanEmpty, l as WorkspaceCreateError, n as AgentStartError, s as TrackerApiError, t as AgentAlreadyRunning, u as WorkspaceNotFound } from "./typed-errors-DXqf3RnP.js";
|
|
48
|
+
import { r as LinearClientOptionalLive, t as LinearClient } from "./linear-client-7fQThJTc.js";
|
|
49
|
+
import { r as GitHubClientOptionalLive, t as GitHubClient } from "./github-client-DAbuXLuk.js";
|
|
50
|
+
import { r as RallyClientOptionalLive, t as RallyClient } from "./rally-client-qKbCNRVW.js";
|
|
51
|
+
import { n as resolveGitHubIssueSync, r as resolveTrackerTypeSync, t as init_tracker_utils } from "./tracker-utils-DJAOAuMN.js";
|
|
52
|
+
import { a as startSharedIssueService, c as parseIntegerHeader, i as issue_service_singleton_exports, n as init_issue_service_singleton, o as CacheService, s as init_cache_service, t as getSharedIssueService } from "./issue-service-singleton-B2xy-IS9.js";
|
|
53
|
+
import { a as setPipelineHandlerSync, t as init_pipeline_notifier } from "./pipeline-notifier-BNAV9kpa.js";
|
|
54
|
+
import { a as getMergeBlockerReconcileCandidates, l as init_review_status_sync } from "./review-status-sync-2C9lk85r.js";
|
|
55
|
+
import { S as requeueToPending, T as transitionToMerging, _ as markMerged, c as init_merge_sync, f as listActiveAutoMerges, g as markFailed, h as markBlocked, i as getActionableAutoMerge, j as listUatGenerationsSync, l as isFlywheelGloballyPaused$1, m as listProblemAutoMerges, n as countActionableAutoMerges, p as listDuePendingAutoMerges, t as cancelPending, v as markMergingBlocked, w as scheduleAutoMergeWithResult } from "./merge-sync-CJpOa0cZ.js";
|
|
56
|
+
import { C as setReviewStatus, F as init_install_id, I as init_config$2, L as resolveTelemetryEnabled, M as init_service, N as synchronizeAnalyticsServices, P as getOrCreateInstallId, R as telemetryEnvironmentForcesOff, _ as markWorkspaceStuck, a as clearStuckMergeStatuses, c as fixStuckCommentedReviews, d as getReviewStatusSync, h as loadReviewStatuses, i as clearReviewStatus, j as getAnalyticsService, l as fixStuckReadyForMerge, p as init_review_status, u as getReviewStatus, w as setReviewStatusSync } from "./review-status-yOGD2MuK.js";
|
|
57
|
+
import { a as clearQueryExpansionCache, i as resolveKnowledgeBundleRoot, n as init_injection, o as init_query_expansion, r as injectPromptTimeMemory } from "./injection-BYUt8ml1.js";
|
|
58
|
+
import { a as init_fts_db, i as closeMemoryFtsDatabases, n as init_search, o as runMemoryFtsStatement, s as runMemoryFtsTransaction, t as buildMatchQuery } from "./search-DqMN4__-.js";
|
|
59
|
+
import { n as require_auth_errors, r as require_token_error, t as require_token_util } from "./token-util-Crcay9j_.js";
|
|
60
|
+
import { D as init_advisory_checks, E as verifyAppCanMerge, M as withConcurrencyLimit, O as isAdvisoryCheckName, d as getPullRequestState, f as init_github_app, j as init_concurrency$1, l as getMergeBackendStatus, p as isGitHubAppConfigured } from "./github-app-7ywLhuZO.js";
|
|
61
|
+
import { C as resolveIssueHeadlineCost, D as stopAgentOutputService, E as startAgentOutputService, S as getCachedRunningAgents, T as retainAgentOutputInterest, _ as migrateAllSessionsSync, b as syncCacheSync, d as eventsRouteLayer, f as resumeQueuedMerges, g as reclassifyUnknownCostEventsSync, h as reconcilePiTranscripts, m as reconcile$1, p as syncWalFromAllProjects, t as workspacesRouteLayer, u as internalEventsRouteLayer, v as getCostsForIssueSync, w as getWorkspacePathForIssue, x as processPendingFeedbackDeliveries, y as rebuildCacheSync } from "./workspaces-BJdPqx_J.js";
|
|
62
|
+
import { S as parseAcpConversationMessages, _ as isOhmypiSessionFile, a as contextUsageFromParseResult, b as parseCodexConversationMessages, c as parseEntireConversation, d as init_kimi_conversation_parser, f as parseKimiConversationMessages, g as init_ohmypi_conversation_parser, h as parsePiConversationMessages, i as computeContextUsage, l as parseFromLastCompactBoundary, m as isPiSessionFile, n as gateSnapshotEmission, o as summarizeConversationActivity, p as init_pi_conversation_parser, r as watchConversation, s as parseConversationMessages, t as init_conversation_service, v as parseOhmypiConversationMessages, x as init_acp_conversation_parser, y as init_codex_conversation_parser } from "./conversation-service-tQCIbBVZ.js";
|
|
63
|
+
import { a as resolveClaudeSessionId, c as resolveKimiWirePath, i as resolveAgentHarness, l as resolvePiSessionPath, n as readLauncherPinnedSessionId, o as resolveCodexRolloutPath, r as resolveAcpTranscriptPath, s as resolveJsonlPath, t as init_jsonl_resolver } from "./jsonl-resolver-07OS3qOr.js";
|
|
64
|
+
import { a as enrichSessions, c as searchSessions, i as CostThresholdError, l as embed, n as getSessionsFeedFacets, o as embedSessions, r as listSessionsFeed, s as parseRelativeTime, t as scan } from "./scanner-YxIv-fG1.js";
|
|
65
|
+
import { c as tailEventsSync, n as deduplicateEventsSync, s as readEventsSync } from "./events-B6zioJA_.js";
|
|
66
|
+
import { n as recordBackgroundAiCost, t as init_cost } from "./cost-BCWEkvro.js";
|
|
67
|
+
import { a as getByIssueId, i as parseFlywheelStatsWindow, n as derivePipelineRunStatsInputs, o as markFixed, r as computeFlywheelStats, s as upsert, t as listSubstrateBugWeights } from "./substrate-bug-weights-service-BbbCZEtJ.js";
|
|
68
|
+
import { n as writeSequenceMd, t as parseSequenceMd } from "./sequence-io--b3_PsWq.js";
|
|
69
|
+
import { _ as normalizeGate, d as computeEpicGroups, f as computeLanes, h as init_pickup, l as classifyIssue, m as computeWaves, p as computeStats, u as computeCohort, v as selectNeedsPlanning } from "./pickup-D1UbSDPd.js";
|
|
70
|
+
import { C as readCurrentLatestFlywheelStatus, D as writeFlywheelLaunchMetadata, E as subscribeLatestFlywheelStatus, F as setItemRequirements, G as liveOrderIssueLookup, H as getBook, I as setSettings, K as normalizeOrderIssueId, L as setStatus, M as moveItem, N as removeItem, O as writeLatestFlywheelStatus, P as renameBook, R as backlogCandidates, S as nextFlywheelRunId, T as resolveLiveFlywheelRunId, U as getBookAsync, W as listBooks, a as isFlywheelDevcontainerRuntime, b as isFlywheelRunId, f as spawnFlywheelAgent, g as abortFlywheelRun, j as createBook, k as addItems, p as buildClassifyLookups, s as loadResumeSessionId, t as FLYWHEEL_ORCHESTRATOR_AGENT_ID, u as saveResumeSessionId, v as getFlywheelRunDetail, w as readFlywheelLaunchMetadata, x as listFlywheelRuns, z as computeBookProgress } from "./flywheel-CjW2L7BS.js";
|
|
71
|
+
import { n as resolveConversationGitInfo } from "./git-info-BSrI9owC.js";
|
|
72
|
+
import { a as getResourceStacks, c as getCurrentDockerStats, f as getSystemHealthEvidenceSnapshot, g as classifyAgentHealth, h as startSmeeProcessSync, l as getAcceptedSystemHealthSnapshot, m as isSmeeConfiguredSync, o as formatUptime, s as getContainerHistory, u as getDeployStaleness } from "./memory-governor-Cqvbusr4.js";
|
|
73
|
+
import { D as detectPlatform, E as validateFeatureName, O as init_platform, S as init_worktree_ops, _ as updateWorkspaceLayout, b as readWorkspaceIdentity, c as installGitHooksInDir, d as init_writer, f as relocateWorkspace, g as unarchiveWorkspace, h as touchWorkspaceAccessed, l as archiveWorkspace, m as setWorkspaceRunCommand, p as setWorkspaceFavorite, s as init_git_hooks, u as createWorkspace, v as upsertProjectFromConfig, x as writeWorkspaceIdentity, y as init_identity_record } from "./workspace-manager-CgovxDrO.js";
|
|
74
|
+
import { n as init_workspace_config, t as getDefaultWorkspaceConfigSync } from "./workspace-config-DRYDO7Zr.js";
|
|
75
|
+
import { B as cleanupClosedIssueAgentDirectories, F as setAgentStatusChangedNotifier, I as setAgentStoppedNotifier, J as isBootReconciliationCandidate, K as extendBootReconciliationGrace, L as setMergeReadyNotifier, O as loadConfig, X as startBootReconciliation, Y as listBootReconciliationCandidates, Z as resolveSwarmPolicy, gt as paneShowsClaudeBootBlockingScreen, k as loadState, n as applyBootReconciliationDecision, q as isAutoResumableRole, r as assessDeaconPatrolFreshness, x as getDeaconLogs } from "./deacon-B24dNzr8.js";
|
|
76
|
+
import { i as getRuntimeForAgent } from "./agent-idle-ONBssBN_.js";
|
|
77
|
+
import { a as getShadowState, s as init_shadow_state } from "./shadow-state-CSA1vtxr.js";
|
|
78
|
+
import { n as init_issue_closed, t as clearIssueClosedCache } from "./issue-closed-6RQsAjDX.js";
|
|
79
|
+
import { r as parseArtifactRef } from "./forge-RVTCK_5X.js";
|
|
80
|
+
import "./parked-residue-BiHb8cD7.js";
|
|
81
|
+
import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-C1gCLFmp.js";
|
|
82
|
+
import { t as init_specialists } from "./specialists-CuDWiNdB.js";
|
|
83
|
+
import { a as getReviewerSessionName } from "./specialists-registry-BYjs04iK.js";
|
|
84
|
+
import { a as readPrdContent, r as findPrdAnywhereSync } from "./prd-locations-BbAvqQmT.js";
|
|
85
|
+
import { i as resolveBootGates, r as formatBootGateState } from "./no-resume-mode-xuYLFhLw.js";
|
|
86
|
+
import { t as createInFlightGuard } from "./in-flight-guard-DuxabAHT.js";
|
|
87
|
+
import { A as removeIssueParkedLabel, C as applyIssueParkedLabel, D as init_label_ops, E as applyIssueVetoedLabel, M as removeIssueReleasedLabel, N as removeIssueVetoedLabel, O as removeIssueBlocksMainLabel, S as applyIssueObjectionLabel, T as applyIssueReleasedLabel, g as parseIssueIdFromTextSync, h as init_resource_utils, j as removeIssueReadyLabel, k as removeIssueObjectionLabel, w as applyIssueReadyLabel, x as applyIssueBlocksMainLabel } from "./pipeline-membership-gather-BK4dzh0X.js";
|
|
88
|
+
import { a as spawnPlanningSession, r as resolveAutoSpawnOnFinalize } from "./spawn-planning-session-CkGweSCC.js";
|
|
89
|
+
import { r as computeMergeQueueFromCandidates, s as listEligibleCandidatesByProject } from "./flywheel-merge-order-D_yyAlND.js";
|
|
90
|
+
import { a as loadWorkspaceMetadataSync } from "./workspace-metadata-BNzODIv6.js";
|
|
91
|
+
import { d as killRemoteAgent, m as loadRemoteAgentState, o as getRemoteAgentOutput, r as checkRemoteSpendCap, s as init_remote_agents, v as sendToRemoteAgent, y as spawnRemoteAgent } from "./remote-agents-CSaTLi3u.js";
|
|
92
|
+
import { _ as refreshMembershipSnapshotsForProjects, a as enqueueProjectsResourceRefresh, c as startProjectResourceConvergence, d as getCachedResourceAllocatedIssues, f as getResourceDetailIdentifiers, g as readPipelineMembershipSnapshotsForProjects, h as sanitizeResourceAllocatedIssues, l as stopProjectResourceRefreshQueue, m as isDiscoverableAgentSession, o as getProjectResourceRefreshQueueState, p as groupResourceAllocatedIssuesByProject, u as whenProjectResourceRefreshIdle, v as summarizePipelineMembership, y as unavailablePipelineMembership } from "./project-resource-refresh-queue-x-K9mvpP.js";
|
|
93
|
+
import { r as spawnInspectAgent } from "./inspect-agent-sV_19NxZ.js";
|
|
94
|
+
import { r as lookupPullRequestNumberForBranch, t as githubPrLookupSource } from "./github-pr-lookup-Dhh3ec1V.js";
|
|
95
|
+
import { a as fetchIssuePullRequestDiff, c as getCachedIssuePrTabResponse, i as fetchIssuePullRequestDetails, l as getIssuePrTabCacheGeneration, n as fetchIssueCheckRuns, r as fetchIssuePullRequest, s as bumpIssuePrTabCacheGeneration, u as setCachedIssuePrTabResponse } from "./pull-requests-Cp_FDT8-.js";
|
|
96
|
+
import { n as DOD_ROWS } from "./dod-DWtilRLx.js";
|
|
97
|
+
import { n as resolveParkedPopulation, r as summarizeParked } from "./resolver-DvSMXty7.js";
|
|
98
|
+
import { a as readCurrentStatus, l as maybeTriggerStatusRollup, s as readRecentObservations, u as writePendingTurn } from "./rollup-B6g9Nr6L.js";
|
|
99
|
+
import { r as isExtendedReviewEnabled } from "./review-agent-esZ0QXdY.js";
|
|
100
|
+
import { n as getTldrDaemonServiceSync, r as init_tldr_daemon } from "./tldr-daemon-CO08YlfQ.js";
|
|
101
|
+
import { S as ensureSyncGitQuiescent, x as listGitOperationsSync } from "./merge-agent-B3jRrlS1.js";
|
|
102
|
+
import { t as readVerificationArtifact } from "./verification-artifact-k5Ftpg0c.js";
|
|
103
|
+
import { t as getAgentCommandSync } from "./settings-CLQcdkoD.js";
|
|
104
|
+
import { r as isRemoteAvailable, t as createFlyProviderFromConfig } from "./remote-BU6ONLpv.js";
|
|
105
|
+
import { n as init_claude_settings_overlay, t as detectProviderEnvConflicts } from "./claude-settings-overlay-m-VVZej1.js";
|
|
106
|
+
import { _ as init_transcript_adapter, a as generateFallbackSummary, c as handoffPreconditionFallbackReason, d as prependFallbackFocus, f as requestHandoffFromAgent, g as getTranscriptAdapter, i as copySessionFromCompactBoundary, l as init_summary_fork, o as generateSummaryForFork, p as reserveSummaryForkSession, r as authorHandoffExternal, s as handoffFailureReason, u as logHandoffFallback } from "./summary-fork-BvcW6bq0.js";
|
|
107
|
+
import { a as init_conversation_compaction, c as shouldInterceptManualCompact, n as compactConversationNative, o as isCompacting } from "./conversation-compaction-D4VOmF7p.js";
|
|
108
|
+
import { n as loadShipRecords, r as publicShipStatus, t as aggregateGenerationShipStatus } from "./ship-status-BEkddXMT.js";
|
|
109
|
+
import { t as init_context_layers } from "./context-layers-BBTKP-Y4.js";
|
|
110
|
+
import { a as appendLinearMcpAuthHealthyEvent, r as appendLinearMcpAuthCallbackRelayedEvent, u as resolveLinearMcpAuthIntervention } from "./linear-mcp-auth-Nk5s3L9M.js";
|
|
111
|
+
import { i as getMergeBlockersPayload, n as hasOrderIssuePrd, r as validateBookForStart, t as createOrderPrdLookup } from "./validate-Ur4xH5bN.js";
|
|
112
|
+
import { i as spawnSequencerAgent, n as clearFinishedSequencerRun, r as getSequencerRunStatus, t as SEQUENCER_AGENT_ID } from "./sequencer-agent-CqouKVZG.js";
|
|
113
|
+
import { n as sameCanonicalReviewStatus, t as emitReviewStatusChanged } from "./review-status-emit-BZz1Y_22.js";
|
|
114
|
+
import "./supervisor-D3jC2c7A.js";
|
|
115
|
+
import { l as startUatTrainReconciler, u as stopUatTrainReconciler } from "./uat-train-IIZlz7r3.js";
|
|
116
|
+
import { n as settlePendingLifecycleClaim, t as claimPendingLifecycleFile } from "./pending-lifecycle-claim-J5uIIJPu.js";
|
|
117
|
+
import { i as listTranscriptCheckpoints, r as getTranscriptCheckpoint$1 } from "./checkpoints-Cszp_0Np.js";
|
|
118
|
+
import { r as readPendingDeploy } from "./deploy-queue-r96ojDI3.js";
|
|
118
119
|
import { createRequire } from "node:module";
|
|
119
120
|
import { basename, delimiter, dirname, extname, isAbsolute, join, normalize, posix, relative, resolve, sep, win32 } from "node:path";
|
|
120
121
|
import { Cause, Context, Data, Duration, Effect, Exit, Fiber, FileSystem, Layer, Option, Path, Queue, Result, Schedule, Schema, Stream } from "effect";
|
|
@@ -404,6 +405,7 @@ init_harness_policy();
|
|
|
404
405
|
var import_dist = /* @__PURE__ */ __toESM(require_dist$1(), 1);
|
|
405
406
|
init_projects_config_write();
|
|
406
407
|
init_issue_id();
|
|
408
|
+
init_projects_cache_events();
|
|
407
409
|
init_projects();
|
|
408
410
|
init_project_key();
|
|
409
411
|
init_state_read_home();
|
|
@@ -419,6 +421,7 @@ init_paths$1();
|
|
|
419
421
|
init_driver();
|
|
420
422
|
init_record_update();
|
|
421
423
|
init_ui_theme();
|
|
424
|
+
init_pane_composer();
|
|
422
425
|
init_infra();
|
|
423
426
|
init_persistent_logger();
|
|
424
427
|
init_agents();
|
|
@@ -721,7 +724,7 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
|
|
|
721
724
|
if (!existsSync$1(workspacePath)) throw new WorkspaceNotFound({ id: issueId });
|
|
722
725
|
const plan = readWorkspacePlanSync(workspacePath);
|
|
723
726
|
if (!plan || plan.plan.items.length === 0) throw new PlanEmpty({ id: issueId });
|
|
724
|
-
const { getAgentState, spawnAgent, normalizeAgentId } = await import("./agents-
|
|
727
|
+
const { getAgentState, spawnAgent, normalizeAgentId } = await import("./agents-DpCuoF65.js");
|
|
725
728
|
const normalizedId = normalizeAgentId(issueId);
|
|
726
729
|
if ((await Effect.runPromise(getAgentState(normalizedId)))?.status === "running") throw new AgentAlreadyRunning({ id: issueId });
|
|
727
730
|
return {
|
|
@@ -753,7 +756,7 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
|
|
|
753
756
|
const { workspacePath, projectPath, issue } = opts;
|
|
754
757
|
if (!existsSync$1(workspacePath)) throw new WorkspaceNotFound({ id: issueId });
|
|
755
758
|
const sessionName = opts.sessionName ?? `planning-${issueId.toLowerCase()}`;
|
|
756
|
-
const { spawnPlanningSession } = await import("./spawn-planning-session-
|
|
759
|
+
const { spawnPlanningSession } = await import("./spawn-planning-session-s406rw1N.js");
|
|
757
760
|
const result = await spawnPlanningSession({
|
|
758
761
|
issue: {
|
|
759
762
|
id: issue.id,
|
|
@@ -787,14 +790,14 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
|
|
|
787
790
|
}),
|
|
788
791
|
kill: (agentId) => Effect.tryPromise({
|
|
789
792
|
try: async () => {
|
|
790
|
-
const { stopAgent } = await import("./agents-
|
|
793
|
+
const { stopAgent } = await import("./agents-DpCuoF65.js");
|
|
791
794
|
await Effect.runPromise(stopAgent(agentId));
|
|
792
795
|
},
|
|
793
796
|
catch: () => void 0
|
|
794
797
|
}).pipe(Effect.ignore),
|
|
795
798
|
message: (agentId, msg) => Effect.tryPromise({
|
|
796
799
|
try: async () => {
|
|
797
|
-
const { messageAgent } = await import("./agents-
|
|
800
|
+
const { messageAgent } = await import("./agents-DpCuoF65.js");
|
|
798
801
|
await messageAgent(agentId, msg);
|
|
799
802
|
},
|
|
800
803
|
catch: (err) => new AgentStartError({
|
|
@@ -805,8 +808,8 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
|
|
|
805
808
|
}),
|
|
806
809
|
deepWipe: (issueId, opts) => Effect.tryPromise({
|
|
807
810
|
try: async () => {
|
|
808
|
-
const { deepWipe } = await import("./workflows-
|
|
809
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
811
|
+
const { deepWipe } = await import("./workflows-CfHm8lVd.js");
|
|
812
|
+
const { resolveProjectFromIssueSync } = await import("./projects-LftaVK99.js");
|
|
810
813
|
const project = resolveProjectFromIssueSync(issueId);
|
|
811
814
|
const projectPath = project?.projectPath ?? process.cwd();
|
|
812
815
|
await Effect.runPromise(deepWipe({
|
|
@@ -865,8 +868,8 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
|
|
|
865
868
|
const { workspacePath, branch } = getWorkspacePath(issueId);
|
|
866
869
|
const issueLower = issueId.toLowerCase();
|
|
867
870
|
if (existsSync$1(workspacePath)) return workspacePath;
|
|
868
|
-
const { createWorkspace } = await import("./workspace-manager-
|
|
869
|
-
const { loadProjectsConfigSync } = await import("./projects-
|
|
871
|
+
const { createWorkspace } = await import("./workspace-manager-jfkKAEuO.js");
|
|
872
|
+
const { loadProjectsConfigSync } = await import("./projects-LftaVK99.js");
|
|
870
873
|
const { projects } = loadProjectsConfigSync();
|
|
871
874
|
const project = resolveProjectFromIssueSync(issueId);
|
|
872
875
|
if (!project) throw new WorkspaceCreateError({
|
|
@@ -901,7 +904,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
|
|
|
901
904
|
const { workspacePath } = getWorkspacePath(issueId);
|
|
902
905
|
const issueLower = issueId.toLowerCase();
|
|
903
906
|
if (!existsSync$1(workspacePath)) throw new WorkspaceNotFound({ id: issueId });
|
|
904
|
-
const { removeWorkspace } = await import("./workspace-manager-
|
|
907
|
+
const { removeWorkspace } = await import("./workspace-manager-jfkKAEuO.js");
|
|
905
908
|
const project = resolveProjectFromIssueSync(issueId);
|
|
906
909
|
if (!project) throw new WorkspaceCreateError({
|
|
907
910
|
id: issueId,
|
|
@@ -932,7 +935,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
|
|
|
932
935
|
try: async () => {
|
|
933
936
|
const { workspacePath } = getWorkspacePath(issueId);
|
|
934
937
|
const issueLower = issueId.toLowerCase();
|
|
935
|
-
const { stopWorkspaceDocker } = await import("./workspace-manager-
|
|
938
|
+
const { stopWorkspaceDocker } = await import("./workspace-manager-jfkKAEuO.js");
|
|
936
939
|
await Effect.runPromise(stopWorkspaceDocker(workspacePath, issueLower));
|
|
937
940
|
},
|
|
938
941
|
catch: () => void 0
|
|
@@ -1001,7 +1004,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
|
|
|
1001
1004
|
join(workspacePath, ".devcontainer", "docker-compose.devcontainer.yml")
|
|
1002
1005
|
];
|
|
1003
1006
|
if (!composePaths.find((p) => existsSync$1(p))) {
|
|
1004
|
-
const { ensureDevcontainerSync } = await import("./ensure-devcontainer-
|
|
1007
|
+
const { ensureDevcontainerSync } = await import("./ensure-devcontainer-rGSh0JHK.js");
|
|
1005
1008
|
const ensure = ensureDevcontainerSync({
|
|
1006
1009
|
workspacePath,
|
|
1007
1010
|
issueId
|
|
@@ -4870,7 +4873,7 @@ init_cliproxy();
|
|
|
4870
4873
|
init_tmux();
|
|
4871
4874
|
const reauthSessions = /* @__PURE__ */ new Map();
|
|
4872
4875
|
const SESSION_MAX_AGE_MS = 3600 * 1e3;
|
|
4873
|
-
const readJsonBody$
|
|
4876
|
+
const readJsonBody$22 = Effect.gen(function* () {
|
|
4874
4877
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
4875
4878
|
return text ? JSON.parse(text) : {};
|
|
4876
4879
|
});
|
|
@@ -4978,7 +4981,7 @@ const postCodexReauthRoute = HttpRouter.add("POST", "/api/settings/codex-reauth"
|
|
|
4978
4981
|
const postCodexReauthStatusRoute = HttpRouter.add("POST", "/api/settings/codex-reauth/status", httpHandler(Effect.gen(function* () {
|
|
4979
4982
|
const originError = rejectInvalidOrigin$1(yield* HttpServerRequest.HttpServerRequest);
|
|
4980
4983
|
if (originError) return originError;
|
|
4981
|
-
const body = yield* readJsonBody$
|
|
4984
|
+
const body = yield* readJsonBody$22;
|
|
4982
4985
|
const sessionName = typeof body.session === "string" ? body.session : "";
|
|
4983
4986
|
const token = typeof body.token === "string" ? body.token : "";
|
|
4984
4987
|
const session = getLiveReauthSession(sessionName);
|
|
@@ -17270,7 +17273,7 @@ var require_get_vercel_oidc_token = /* @__PURE__ */ __commonJSMin(((exports, mod
|
|
|
17270
17273
|
err = error;
|
|
17271
17274
|
}
|
|
17272
17275
|
try {
|
|
17273
|
-
const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([await import("./token-util-
|
|
17276
|
+
const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([await import("./token-util-DfUS3Lpp.js").then((m) => /* @__PURE__ */ __toESM(m.default)), await import("./token-Bez-qCB2.js").then((m) => /* @__PURE__ */ __toESM(m.default))]);
|
|
17274
17277
|
if (!token || isExpired(getTokenPayload(token), options?.expirationBufferMs)) {
|
|
17275
17278
|
await refreshToken(options);
|
|
17276
17279
|
token = getVercelOidcTokenSync();
|
|
@@ -29587,7 +29590,7 @@ var GoogleCloudTranscription = class {
|
|
|
29587
29590
|
}
|
|
29588
29591
|
async start(apiKey, model) {
|
|
29589
29592
|
try {
|
|
29590
|
-
const { SpeechClient } = await import("./src-
|
|
29593
|
+
const { SpeechClient } = await import("./src-CZsPs61V.js").then((m) => /* @__PURE__ */ __toESM(m.default, 1)).then((module) => module.v1p1beta1 ?? module.v1);
|
|
29591
29594
|
if (this.closed) return;
|
|
29592
29595
|
const stream = new SpeechClient({ apiKey }).streamingRecognize({
|
|
29593
29596
|
config: {
|
|
@@ -29851,7 +29854,7 @@ const DEFAULT_VOICE_SETTINGS = {
|
|
|
29851
29854
|
model: "gpt-4.1-mini"
|
|
29852
29855
|
}
|
|
29853
29856
|
};
|
|
29854
|
-
const readJsonBody$
|
|
29857
|
+
const readJsonBody$21 = Effect.gen(function* () {
|
|
29855
29858
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
29856
29859
|
const contentLength = Number(request.headers["content-length"] ?? 0);
|
|
29857
29860
|
if (Number.isFinite(contentLength) && contentLength > MAX_VOICE_SETTINGS_BODY_BYTES) return {
|
|
@@ -29974,7 +29977,7 @@ const getVoiceSettingsRoute = HttpRouter.add("GET", "/api/voice/settings", httpH
|
|
|
29974
29977
|
const putVoiceSettingsRoute = HttpRouter.add("PUT", "/api/voice/settings", httpHandler(Effect.gen(function* () {
|
|
29975
29978
|
const originError = requireTrustedOrigin$2(yield* HttpServerRequest.HttpServerRequest);
|
|
29976
29979
|
if (originError) return originError;
|
|
29977
|
-
const parsed = yield* readJsonBody$
|
|
29980
|
+
const parsed = yield* readJsonBody$21;
|
|
29978
29981
|
if (!parsed.ok) return jsonResponse({ error: parsed.error }, { status: 413 });
|
|
29979
29982
|
const body = parsed.body;
|
|
29980
29983
|
if (!isVoiceSettings(body)) return jsonResponse({ error: "Invalid voice settings payload" }, { status: 400 });
|
|
@@ -30268,12 +30271,16 @@ function streamAgentOutput(eventStore, agentId) {
|
|
|
30268
30271
|
}
|
|
30269
30272
|
//#endregion
|
|
30270
30273
|
//#region services/dashboard-db-task.ts
|
|
30274
|
+
init_agent_input_detection();
|
|
30275
|
+
init_tracker_config();
|
|
30276
|
+
init_agent_enrichment();
|
|
30271
30277
|
init_acp_conversation_parser();
|
|
30272
30278
|
init_codex_conversation_parser();
|
|
30273
30279
|
init_ohmypi_conversation_parser();
|
|
30274
30280
|
init_pi_conversation_parser();
|
|
30275
30281
|
init_kimi_conversation_parser();
|
|
30276
30282
|
init_conversation_service();
|
|
30283
|
+
init_jsonl_resolver();
|
|
30277
30284
|
init_control_settings();
|
|
30278
30285
|
const MAX_PENDING_JOBS = 32;
|
|
30279
30286
|
const SEMANTIC_SEARCH_TIMEOUT_MS = Number.parseInt(process.env["OVERDECK_SEMANTIC_SEARCH_TIMEOUT_MS"] ?? "15000", 10);
|
|
@@ -30414,15 +30421,15 @@ async function runInline$1(operation, payload, onProgress) {
|
|
|
30414
30421
|
});
|
|
30415
30422
|
}
|
|
30416
30423
|
case "getArtifactBySlug": {
|
|
30417
|
-
const { getArtifactBySlugJob } = await import("./artifact-index-jobs-
|
|
30424
|
+
const { getArtifactBySlugJob } = await import("./artifact-index-jobs-Ck4NRRkY.js");
|
|
30418
30425
|
return getArtifactBySlugJob(payload);
|
|
30419
30426
|
}
|
|
30420
30427
|
case "listArtifactsForWorkspaceOrIssue": {
|
|
30421
|
-
const { listArtifactsForWorkspaceOrIssueJob } = await import("./artifact-index-jobs-
|
|
30428
|
+
const { listArtifactsForWorkspaceOrIssueJob } = await import("./artifact-index-jobs-Ck4NRRkY.js");
|
|
30422
30429
|
return listArtifactsForWorkspaceOrIssueJob(payload);
|
|
30423
30430
|
}
|
|
30424
30431
|
case "unshareArtifactBySlug": {
|
|
30425
|
-
const { unshareArtifactBySlugJob } = await import("./artifact-index-jobs-
|
|
30432
|
+
const { unshareArtifactBySlugJob } = await import("./artifact-index-jobs-Ck4NRRkY.js");
|
|
30426
30433
|
return unshareArtifactBySlugJob(payload);
|
|
30427
30434
|
}
|
|
30428
30435
|
}
|
|
@@ -31533,6 +31540,7 @@ const PanRpcLayer = PanRpcGroup.toLayer(Effect.gen(function* () {
|
|
|
31533
31540
|
}), (unsubscribe) => Effect.sync(() => unsubscribe()))),
|
|
31534
31541
|
[WS_METHODS.subscribeIssueEvents]: (input) => {
|
|
31535
31542
|
console.log(`[ws-rpc] subscribeIssueEvents invoked issueId=${input.issueId}`);
|
|
31543
|
+
import("./issue-service-singleton-CvgNAWqK.js").then(({ getSharedIssueService }) => getSharedIssueService().backfillIssue(input.issueId)).catch(() => {});
|
|
31536
31544
|
return eventStore.streamEvents.pipe(Stream.filter(shouldBroadcastDashboardEvent), Stream.map(storedToDomainEvent), Stream.filter(passesDomainEventSchema), Stream.mapEffect((event) => getCachedAgentIssueLookup(readModel).pipe(Effect.map((lookup) => filterDomainEventForIssue(event, input.issueId, lookup)))), Stream.filter((event) => event !== null));
|
|
31537
31545
|
},
|
|
31538
31546
|
[WS_METHODS.subscribeTerminal]: (input) => terminalService.streamSession(input.sessionName, input.cols, input.rows),
|
|
@@ -31848,9 +31856,6 @@ const websocketRpcRouteLayer = Layer.unwrap(Effect.gen(function* () {
|
|
|
31848
31856
|
init_internal_token();
|
|
31849
31857
|
init_state_home();
|
|
31850
31858
|
init_pan_dir();
|
|
31851
|
-
init_agent_input_detection();
|
|
31852
|
-
init_tracker_config();
|
|
31853
|
-
init_agent_enrichment();
|
|
31854
31859
|
init_tracker_utils();
|
|
31855
31860
|
init_cache_service();
|
|
31856
31861
|
init_pipeline_notifier();
|
|
@@ -32204,781 +32209,8 @@ function assertPlanQuality(doc, options = {}) {
|
|
|
32204
32209
|
return issues;
|
|
32205
32210
|
}
|
|
32206
32211
|
//#endregion
|
|
32207
|
-
//#region services/resource-discovery-shared.ts
|
|
32208
|
-
init_conversations();
|
|
32209
|
-
init_runtime_census();
|
|
32210
|
-
const execFileAsync$20 = promisify(execFile);
|
|
32211
|
-
async function loadTrackerIssues() {
|
|
32212
|
-
const map = /* @__PURE__ */ new Map();
|
|
32213
|
-
try {
|
|
32214
|
-
const { getSharedIssueService } = await import("./issue-service-singleton-CL6hESX2.js");
|
|
32215
|
-
const issues = (await getSharedIssueService()).getIssues();
|
|
32216
|
-
for (const issue of issues) if (issue.identifier) map.set(issue.identifier.toUpperCase(), issue);
|
|
32217
|
-
} catch {}
|
|
32218
|
-
return map;
|
|
32219
|
-
}
|
|
32220
|
-
async function loadDockerContainers() {
|
|
32221
|
-
try {
|
|
32222
|
-
const { stdout } = await execFileAsync$20("docker", [
|
|
32223
|
-
"ps",
|
|
32224
|
-
"--format",
|
|
32225
|
-
"{{.Names}}"
|
|
32226
|
-
], {
|
|
32227
|
-
encoding: "utf-8",
|
|
32228
|
-
timeout: 5e3
|
|
32229
|
-
});
|
|
32230
|
-
return stdout.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
32231
|
-
} catch {
|
|
32232
|
-
return [];
|
|
32233
|
-
}
|
|
32234
|
-
}
|
|
32235
|
-
async function loadActiveRemoteAgentStates() {
|
|
32236
|
-
try {
|
|
32237
|
-
const { listActiveRemoteAgentStates } = await import("./remote-agents-DQVGZVQ9.js");
|
|
32238
|
-
return listActiveRemoteAgentStates();
|
|
32239
|
-
} catch {
|
|
32240
|
-
return [];
|
|
32241
|
-
}
|
|
32242
|
-
}
|
|
32243
|
-
async function captureSharedResourceSignals() {
|
|
32244
|
-
const [trackerIssues, runtimeCensus, dockerContainers, remoteAgentStates] = await Promise.all([
|
|
32245
|
-
loadTrackerIssues(),
|
|
32246
|
-
getRuntimeCensus(),
|
|
32247
|
-
loadDockerContainers(),
|
|
32248
|
-
loadActiveRemoteAgentStates()
|
|
32249
|
-
]);
|
|
32250
|
-
const tmuxSessions = [...runtimeCensus.sessionNames];
|
|
32251
|
-
let conversations = [];
|
|
32252
|
-
try {
|
|
32253
|
-
conversations = listConversations();
|
|
32254
|
-
} catch {}
|
|
32255
|
-
return {
|
|
32256
|
-
trackerIssues,
|
|
32257
|
-
tmuxSessions,
|
|
32258
|
-
dockerContainers,
|
|
32259
|
-
conversations,
|
|
32260
|
-
remoteAgentStates
|
|
32261
|
-
};
|
|
32262
|
-
}
|
|
32263
|
-
//#endregion
|
|
32264
|
-
//#region review-status.ts
|
|
32265
|
-
init_factory();
|
|
32266
|
-
init_concurrency$1();
|
|
32267
|
-
init_advisory_checks();
|
|
32268
|
-
init_github_app();
|
|
32269
|
-
init_resource_utils();
|
|
32270
|
-
init_pipeline_membership_gather();
|
|
32271
|
-
init_pipeline_membership();
|
|
32272
|
-
//#endregion
|
|
32273
|
-
//#region services/issue-title-fallback.ts
|
|
32274
|
-
/**
|
|
32275
|
-
* Titles for issues that have aged out of the tracker sync window.
|
|
32276
|
-
*
|
|
32277
|
-
* The resource tree surfaces any issue that still owns local resources
|
|
32278
|
-
* (workspaces, agent sessions, records, planning artifacts) — including
|
|
32279
|
-
* issues closed long ago, which the shared issue service no longer syncs.
|
|
32280
|
-
* Without a tracker row, discovery falls back to the bare identifier as the
|
|
32281
|
-
* row title, so the tree renders "MIN-852 — MIN-852" (PAN-3337).
|
|
32282
|
-
*
|
|
32283
|
-
* Resolve those titles per issue on demand through the tracker's own
|
|
32284
|
-
* getIssue door. Successes are memoized for the process lifetime (titles of
|
|
32285
|
-
* closed issues do not churn); failures are memoized briefly so a broken or
|
|
32286
|
-
* unconfigured tracker cannot be hammered by the discovery refresh loop.
|
|
32287
|
-
*/
|
|
32288
|
-
const FAILURE_RETRY_MS = 600 * 1e3;
|
|
32289
|
-
const LOOKUP_TIMEOUT = "10 seconds";
|
|
32290
|
-
/** Per-pass cap so one discovery pass cannot fan out unbounded tracker calls. */
|
|
32291
|
-
const MAX_LOOKUPS_PER_PASS = 8;
|
|
32292
|
-
const resolvedTitles = /* @__PURE__ */ new Map();
|
|
32293
|
-
const failedLookupsAt = /* @__PURE__ */ new Map();
|
|
32294
|
-
const inFlight$3 = /* @__PURE__ */ new Map();
|
|
32295
|
-
async function lookupTitle(issueId) {
|
|
32296
|
-
const trackerType = resolveTrackerTypeSync(issueId);
|
|
32297
|
-
if (!trackerType) return null;
|
|
32298
|
-
const tracker = createTracker({ type: trackerType });
|
|
32299
|
-
const title = (await Effect.runPromise(tracker.getIssue(issueId).pipe(Effect.timeout(LOOKUP_TIMEOUT)))).title?.trim();
|
|
32300
|
-
return title && title.toUpperCase() !== issueId.toUpperCase() ? title : null;
|
|
32301
|
-
}
|
|
32302
|
-
/**
|
|
32303
|
-
* Resolve titles for issues the tracker snapshot missed. Returns only the
|
|
32304
|
-
* identifiers that resolved to a real title (memoized or freshly fetched).
|
|
32305
|
-
*/
|
|
32306
|
-
async function resolveMissingIssueTitles(issueIds) {
|
|
32307
|
-
const result = /* @__PURE__ */ new Map();
|
|
32308
|
-
const toFetch = [];
|
|
32309
|
-
const now = Date.now();
|
|
32310
|
-
for (const raw of issueIds) {
|
|
32311
|
-
const issueId = raw.toUpperCase();
|
|
32312
|
-
const memoized = resolvedTitles.get(issueId);
|
|
32313
|
-
if (memoized) {
|
|
32314
|
-
result.set(issueId, memoized);
|
|
32315
|
-
continue;
|
|
32316
|
-
}
|
|
32317
|
-
const failedAt = failedLookupsAt.get(issueId);
|
|
32318
|
-
if (failedAt !== void 0 && now - failedAt < FAILURE_RETRY_MS) continue;
|
|
32319
|
-
if (toFetch.length < MAX_LOOKUPS_PER_PASS) toFetch.push(issueId);
|
|
32320
|
-
}
|
|
32321
|
-
await Promise.all(toFetch.map(async (issueId) => {
|
|
32322
|
-
let pending = inFlight$3.get(issueId);
|
|
32323
|
-
if (!pending) {
|
|
32324
|
-
pending = lookupTitle(issueId).catch(() => null).finally(() => inFlight$3.delete(issueId));
|
|
32325
|
-
inFlight$3.set(issueId, pending);
|
|
32326
|
-
}
|
|
32327
|
-
const title = await pending;
|
|
32328
|
-
if (title) {
|
|
32329
|
-
resolvedTitles.set(issueId, title);
|
|
32330
|
-
failedLookupsAt.delete(issueId);
|
|
32331
|
-
result.set(issueId, title);
|
|
32332
|
-
} else failedLookupsAt.set(issueId, Date.now());
|
|
32333
|
-
}));
|
|
32334
|
-
return result;
|
|
32335
|
-
}
|
|
32336
|
-
//#endregion
|
|
32337
|
-
//#region services/pipeline-membership.ts
|
|
32338
|
-
const PIPELINE_MEMBERSHIP_TTL_MS = 3e4;
|
|
32339
|
-
function createPipelineMembershipService(deps = {
|
|
32340
|
-
gather: gatherProjectLensSignals,
|
|
32341
|
-
now: () => Date.now()
|
|
32342
|
-
}) {
|
|
32343
|
-
const cachedGather = createSettledTtlPromiseCache(PIPELINE_MEMBERSHIP_TTL_MS, deps.now);
|
|
32344
|
-
const service = async (project) => cachedGather(project.path, () => deps.gather(project).then((signals) => signals.map(resolvePipelineMembership)));
|
|
32345
|
-
service.invalidate = (projectPath) => cachedGather.invalidate(projectPath);
|
|
32346
|
-
return service;
|
|
32347
|
-
}
|
|
32348
|
-
const getProjectPipelineMembership = createPipelineMembershipService();
|
|
32349
|
-
const membershipSnapshots = /* @__PURE__ */ new Map();
|
|
32350
|
-
const scheduleMembershipRefresh = createPromiseConcurrencyLimiter(3);
|
|
32351
|
-
function refreshMembershipSnapshot(project, snapshot, getMembership, now) {
|
|
32352
|
-
if (snapshot.refresh) return snapshot.refresh;
|
|
32353
|
-
snapshot.refresh = scheduleMembershipRefresh(() => getMembership(project)).then((value) => {
|
|
32354
|
-
snapshot.value = value;
|
|
32355
|
-
snapshot.refreshedAt = now();
|
|
32356
|
-
snapshot.lastError = void 0;
|
|
32357
|
-
snapshot.lastErrorReason = void 0;
|
|
32358
|
-
snapshot.lastErrorAt = void 0;
|
|
32359
|
-
}).catch((error) => {
|
|
32360
|
-
snapshot.lastError = error instanceof Error ? error.message : String(error);
|
|
32361
|
-
snapshot.lastErrorReason = error instanceof PipelineMembershipUnavailableError ? error.reason : "gather_failed";
|
|
32362
|
-
snapshot.lastErrorAt = now();
|
|
32363
|
-
console.warn(`[pipeline-membership] refresh failed for ${project.name ?? project.path}; keeping last-good snapshot:`, snapshot.lastError);
|
|
32364
|
-
}).finally(() => {
|
|
32365
|
-
snapshot.refresh = void 0;
|
|
32366
|
-
});
|
|
32367
|
-
return snapshot.refresh;
|
|
32368
|
-
}
|
|
32369
|
-
/** Read the latest successful snapshots without scheduling tracker or git work. */
|
|
32370
|
-
function readPipelineMembershipSnapshotsForProjects(projects) {
|
|
32371
|
-
return projects.map((project) => {
|
|
32372
|
-
const snapshot = membershipSnapshots.get(project.path);
|
|
32373
|
-
if (snapshot?.refreshedAt) return {
|
|
32374
|
-
project,
|
|
32375
|
-
memberships: snapshot.value
|
|
32376
|
-
};
|
|
32377
|
-
return {
|
|
32378
|
-
project,
|
|
32379
|
-
error: /* @__PURE__ */ new Error(snapshot?.lastError ? `Pipeline membership refresh failed: ${snapshot.lastError}` : "Pipeline membership snapshot is loading"),
|
|
32380
|
-
unavailableReason: snapshot?.lastErrorReason
|
|
32381
|
-
};
|
|
32382
|
-
});
|
|
32383
|
-
}
|
|
32384
|
-
/**
|
|
32385
|
-
* PAN-2893 — event-driven refresh. Invalidate the per-project TTL cache and
|
|
32386
|
-
* force a snapshot re-gather NOW for the given projects, so agent lifecycle
|
|
32387
|
-
* changes reach membership consumers without waiting out the 5-minute TTL.
|
|
32388
|
-
* Refresh failures keep the last good snapshot (same policy as TTL refreshes).
|
|
32389
|
-
*/
|
|
32390
|
-
async function refreshMembershipSnapshotsForProjects(projects, getMembership = getProjectPipelineMembership, now = () => Date.now()) {
|
|
32391
|
-
await Promise.all(projects.map(async (project) => {
|
|
32392
|
-
getMembership.invalidate(project.path);
|
|
32393
|
-
const snapshot = membershipSnapshots.get(project.path) ?? {
|
|
32394
|
-
value: [],
|
|
32395
|
-
refreshedAt: 0
|
|
32396
|
-
};
|
|
32397
|
-
membershipSnapshots.set(project.path, snapshot);
|
|
32398
|
-
const inFlight = snapshot.refresh;
|
|
32399
|
-
if (inFlight) {
|
|
32400
|
-
await inFlight;
|
|
32401
|
-
getMembership.invalidate(project.path);
|
|
32402
|
-
}
|
|
32403
|
-
await refreshMembershipSnapshot(project, snapshot, getMembership, now);
|
|
32404
|
-
}));
|
|
32405
|
-
}
|
|
32406
|
-
function summarizePipelineMembership(membership) {
|
|
32407
|
-
return {
|
|
32408
|
-
available: true,
|
|
32409
|
-
inPipeline: membership.inPipeline,
|
|
32410
|
-
bucket: membership.bucket,
|
|
32411
|
-
labelDrift: membership.labelDrift
|
|
32412
|
-
};
|
|
32413
|
-
}
|
|
32414
|
-
function unavailablePipelineMembership() {
|
|
32415
|
-
return {
|
|
32416
|
-
available: false,
|
|
32417
|
-
inPipeline: false,
|
|
32418
|
-
bucket: "clean_terminal",
|
|
32419
|
-
labelDrift: null
|
|
32420
|
-
};
|
|
32421
|
-
}
|
|
32422
|
-
//#endregion
|
|
32423
|
-
//#region services/resource-discovery.ts
|
|
32424
|
-
init_src();
|
|
32425
|
-
init_projects();
|
|
32426
|
-
init_pipeline_membership();
|
|
32427
|
-
init_pipeline_membership_gather();
|
|
32428
|
-
const execFileAsync$19 = promisify(execFile);
|
|
32429
|
-
const RECENT_ACTIVITY_WINDOW_MS = 5e3;
|
|
32430
|
-
const projectResourceSnapshots = /* @__PURE__ */ new Map();
|
|
32431
|
-
let cachedResourceIssues = null;
|
|
32432
|
-
let cachedDetailedResourceIssues = null;
|
|
32433
|
-
function projectPrefixes(project) {
|
|
32434
|
-
const prefixes = /* @__PURE__ */ new Set();
|
|
32435
|
-
if (project.config.issue_prefix) prefixes.add(project.config.issue_prefix.toUpperCase());
|
|
32436
|
-
for (const prefix of project.config.issue_prefixes ?? []) prefixes.add(prefix.toUpperCase());
|
|
32437
|
-
if (prefixes.size === 0) prefixes.add(project.key.toUpperCase().replace(/-/g, ""));
|
|
32438
|
-
return [...prefixes];
|
|
32439
|
-
}
|
|
32440
|
-
function deriveStateLabel(issue, hasTmux, hasFreshHeartbeat, membership) {
|
|
32441
|
-
const trackerState = issue.trackerState ?? "";
|
|
32442
|
-
if (membership?.bucket === "post_merge_limbo") return "Merged — Needs Close-Out";
|
|
32443
|
-
if (membership?.lenses.L3_issueOpen === false) return hasTmux ? "Closed" : "Done";
|
|
32444
|
-
if (issue.readyForMerge) return "In Review";
|
|
32445
|
-
if (trackerState === "done" || trackerState === "closed" || trackerState === "canceled") return hasTmux ? "Closed" : "Done";
|
|
32446
|
-
if (trackerState === "in_review") return "In Review";
|
|
32447
|
-
if (trackerState === "in_progress") return "In Progress";
|
|
32448
|
-
if (hasTmux && (issue.agentStatus === "active" || hasFreshHeartbeat)) return "In Progress";
|
|
32449
|
-
if (issue.agentStatus === "suspended") return "Suspended";
|
|
32450
|
-
if (issue.hasPrd && !issue.hasState) return "Planning";
|
|
32451
|
-
if (issue.hasState) return "Has Context";
|
|
32452
|
-
if (issue.resourceSources.has("workspace") || issue.resourceSources.has("branch")) return "Allocated";
|
|
32453
|
-
return "Idle";
|
|
32454
|
-
}
|
|
32455
|
-
function sortPullRequests(prs) {
|
|
32456
|
-
return [...prs].sort((a, b) => {
|
|
32457
|
-
if (a.isDraft !== b.isDraft) return a.isDraft ? 1 : -1;
|
|
32458
|
-
return a.number - b.number;
|
|
32459
|
-
});
|
|
32460
|
-
}
|
|
32461
|
-
function summarizeResourceDetails(details) {
|
|
32462
|
-
return {
|
|
32463
|
-
hasWorkspace: details.workspacePath !== null,
|
|
32464
|
-
localBranchCount: details.localBranches.length,
|
|
32465
|
-
remoteBranchCount: details.remoteBranches.length,
|
|
32466
|
-
tmuxSessionCount: details.tmuxSessions.length,
|
|
32467
|
-
prs: sortPullRequests(details.prs).map((pr) => ({
|
|
32468
|
-
number: pr.number,
|
|
32469
|
-
title: pr.title,
|
|
32470
|
-
url: pr.url,
|
|
32471
|
-
state: pr.state,
|
|
32472
|
-
isDraft: pr.isDraft
|
|
32473
|
-
})),
|
|
32474
|
-
hasXbrief: details.xbriefPath !== null,
|
|
32475
|
-
hasTasks: details.tasksPath !== null,
|
|
32476
|
-
hasPrd: details.prdPath !== null,
|
|
32477
|
-
dockerContainerCount: details.dockerContainers.length,
|
|
32478
|
-
actualBranch: details.actualBranch,
|
|
32479
|
-
branchDrifted: details.branchDrifted,
|
|
32480
|
-
branchAheadOfMain: details.branchAheadOfMain,
|
|
32481
|
-
workspaceMissing: details.workspaceMissing,
|
|
32482
|
-
remoteAgent: details.remoteAgent,
|
|
32483
|
-
conversations: details.conversations.map((conv) => ({
|
|
32484
|
-
id: conv.id,
|
|
32485
|
-
name: conv.name,
|
|
32486
|
-
title: conv.title,
|
|
32487
|
-
status: conv.status
|
|
32488
|
-
}))
|
|
32489
|
-
};
|
|
32490
|
-
}
|
|
32491
|
-
function summarizeResourceDetailIdentifiers(details) {
|
|
32492
|
-
return {
|
|
32493
|
-
workspacePaths: details.workspacePath ? [details.workspacePath] : [],
|
|
32494
|
-
localBranchNames: [...details.localBranches].sort(),
|
|
32495
|
-
remoteBranchNames: [...details.remoteBranches].sort(),
|
|
32496
|
-
tmuxSessionNames: [...details.tmuxSessions].sort(),
|
|
32497
|
-
prs: sortPullRequests(details.prs).map((pr) => ({
|
|
32498
|
-
number: pr.number,
|
|
32499
|
-
title: pr.title,
|
|
32500
|
-
state: pr.state,
|
|
32501
|
-
isDraft: pr.isDraft
|
|
32502
|
-
})),
|
|
32503
|
-
dockerContainerNames: [...details.dockerContainers].sort()
|
|
32504
|
-
};
|
|
32505
|
-
}
|
|
32506
|
-
function hasRecentActivity(lastActivity) {
|
|
32507
|
-
return lastActivity !== null && Number.isFinite(lastActivity) && Date.now() - lastActivity < RECENT_ACTIVITY_WINDOW_MS;
|
|
32508
|
-
}
|
|
32509
|
-
function isLiveResource(issue) {
|
|
32510
|
-
return issue.resourceDetails.remoteAgent !== null || issue.resourceDetails.tmuxSessions.length > 0 || issue.resourceDetails.dockerContainers.length > 0 || hasOpenPr(issue);
|
|
32511
|
-
}
|
|
32512
|
-
function isActiveTrackerState(state) {
|
|
32513
|
-
return state === "in_progress" || state === "in_review" || state === "started";
|
|
32514
|
-
}
|
|
32515
|
-
function isTerminalTrackerState(state) {
|
|
32516
|
-
return state === "closed" || state === "done" || state === "canceled" || state === "completed";
|
|
32517
|
-
}
|
|
32518
|
-
function hasOpenPr(issue) {
|
|
32519
|
-
return issue.resourceDetails.prs.some((pr) => pr.state === "OPEN" || pr.state === "open");
|
|
32520
|
-
}
|
|
32521
|
-
function shouldLoadReviewStatus(issue) {
|
|
32522
|
-
return issue.resourceSources.size > 0 && (!isTerminalTrackerState(issue.trackerState) || hasOpenPr(issue)) && (isLiveResource(issue) || isActiveTrackerState(issue.trackerState) && issue.branch != null);
|
|
32523
|
-
}
|
|
32524
|
-
/**
|
|
32525
|
-
* tmux session-name prefixes that map a session to its issue in the Command Deck
|
|
32526
|
-
* tree. `strike-` MUST be included (PAN-1682): strike sessions are named
|
|
32527
|
-
* `strike-<issue>` and a strike issue is typically `todo` (not an active tracker
|
|
32528
|
-
* state), so without registering the tmux resource the issue is filtered out of
|
|
32529
|
-
* the tree entirely. Keep this list in sync with the agent-session prefixes the
|
|
32530
|
-
* dashboard recognizes elsewhere (e.g. routes/agents.ts).
|
|
32531
|
-
*/
|
|
32532
|
-
const DISCOVERABLE_SESSION_PREFIXES = [
|
|
32533
|
-
"agent-",
|
|
32534
|
-
"planning-",
|
|
32535
|
-
"specialist-",
|
|
32536
|
-
"review-",
|
|
32537
|
-
"strike-"
|
|
32538
|
-
];
|
|
32539
|
-
function isDiscoverableAgentSession(sessionName) {
|
|
32540
|
-
return DISCOVERABLE_SESSION_PREFIXES.some((prefix) => sessionName.startsWith(prefix));
|
|
32541
|
-
}
|
|
32542
|
-
async function loadOpenPullRequests(projects) {
|
|
32543
|
-
const pullRequests = /* @__PURE__ */ new Map();
|
|
32544
|
-
await Promise.all(projects.map(async (project) => {
|
|
32545
|
-
if (!project.config.github_repo) return;
|
|
32546
|
-
const [owner, repo] = project.config.github_repo.split("/");
|
|
32547
|
-
if (!owner || !repo) return;
|
|
32548
|
-
try {
|
|
32549
|
-
const prs = await listOpenPullRequestsSnapshot(owner, repo);
|
|
32550
|
-
for (const row of prs) {
|
|
32551
|
-
if (row.number === void 0 || row.title === void 0 || row.url === void 0 || row.state === void 0 || row.isDraft === void 0 || row.baseRefName === void 0) continue;
|
|
32552
|
-
const pr = {
|
|
32553
|
-
number: row.number,
|
|
32554
|
-
title: row.title,
|
|
32555
|
-
url: row.url,
|
|
32556
|
-
state: row.state,
|
|
32557
|
-
isDraft: row.isDraft,
|
|
32558
|
-
headRefName: row.headRefName,
|
|
32559
|
-
baseRefName: row.baseRefName
|
|
32560
|
-
};
|
|
32561
|
-
const issueId = parseIssueIdFromTextSync(pr.headRefName);
|
|
32562
|
-
if (!issueId) continue;
|
|
32563
|
-
const existing = pullRequests.get(issueId) ?? [];
|
|
32564
|
-
existing.push(pr);
|
|
32565
|
-
pullRequests.set(issueId, existing);
|
|
32566
|
-
}
|
|
32567
|
-
} catch {}
|
|
32568
|
-
}));
|
|
32569
|
-
for (const [issueId, prs] of pullRequests) pullRequests.set(issueId, sortPullRequests(prs));
|
|
32570
|
-
return pullRequests;
|
|
32571
|
-
}
|
|
32572
|
-
const PROJECT_BRANCH_PATTERNS = [
|
|
32573
|
-
"refs/heads/feature/*",
|
|
32574
|
-
"refs/remotes/origin/feature/*",
|
|
32575
|
-
"refs/heads/bypass/*",
|
|
32576
|
-
"refs/remotes/origin/bypass/*"
|
|
32577
|
-
];
|
|
32578
|
-
async function loadProjectBranchSnapshot(projectPath) {
|
|
32579
|
-
const run = (extraArgs = []) => execFileAsync$19("git", [
|
|
32580
|
-
"for-each-ref",
|
|
32581
|
-
"--format=%(refname:short)",
|
|
32582
|
-
...extraArgs,
|
|
32583
|
-
...PROJECT_BRANCH_PATTERNS
|
|
32584
|
-
], {
|
|
32585
|
-
cwd: projectPath,
|
|
32586
|
-
encoding: "utf-8",
|
|
32587
|
-
timeout: 1e4
|
|
32588
|
-
}).catch(() => ({ stdout: "" }));
|
|
32589
|
-
const [allRefs, unmergedRefs] = await Promise.all([run(), run(["--no-merged=main"])]);
|
|
32590
|
-
const branches = allRefs.stdout.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
32591
|
-
const ahead = new Set(unmergedRefs.stdout.split("\n").map((line) => line.trim()).filter(Boolean));
|
|
32592
|
-
return {
|
|
32593
|
-
local: branches.filter((branch) => !branch.startsWith("origin/")),
|
|
32594
|
-
remote: branches.filter((branch) => branch.startsWith("origin/")),
|
|
32595
|
-
ahead
|
|
32596
|
-
};
|
|
32597
|
-
}
|
|
32598
|
-
async function scanWorkspace(workspacesDir, workspaceName) {
|
|
32599
|
-
const workspacePath = join(workspacesDir, workspaceName);
|
|
32600
|
-
const projectRoot = join(workspacesDir, "..");
|
|
32601
|
-
const workspaceEntries = new Set(await readdir(workspacePath).catch(() => []));
|
|
32602
|
-
const panEntries = workspaceEntries.has(".pan") ? new Set(await readdir(join(workspacePath, PAN_DIRNAME)).catch(() => [])) : /* @__PURE__ */ new Set();
|
|
32603
|
-
const issueMatch = workspaceName.match(/^feature-([a-z]+-\d+)$/i);
|
|
32604
|
-
const issueId = issueMatch ? issueMatch[1].toUpperCase() : null;
|
|
32605
|
-
const specEntry = issueId ? await Effect.runPromise(findSpecByIssue(projectRoot, issueId)).catch(() => null) : null;
|
|
32606
|
-
const xbriefPath = specEntry ? specEntry.path : null;
|
|
32607
|
-
let xbriefMtime = null;
|
|
32608
|
-
if (xbriefPath) try {
|
|
32609
|
-
xbriefMtime = (await stat(xbriefPath)).mtimeMs;
|
|
32610
|
-
} catch {
|
|
32611
|
-
xbriefMtime = null;
|
|
32612
|
-
}
|
|
32613
|
-
return {
|
|
32614
|
-
workspacePath,
|
|
32615
|
-
hasPlanning: workspaceEntries.has(PAN_DIRNAME),
|
|
32616
|
-
hasPrd: panEntries.has("prd.md"),
|
|
32617
|
-
hasState: panEntries.has(PAN_CONTINUE_FILENAME),
|
|
32618
|
-
hasXbrief: xbriefPath !== null,
|
|
32619
|
-
xbriefPath,
|
|
32620
|
-
xbriefMtime,
|
|
32621
|
-
hasTasks: xbriefPath !== null
|
|
32622
|
-
};
|
|
32623
|
-
}
|
|
32624
|
-
async function computeResourceAllocatedIssues(projectConfigs, sharedSignals) {
|
|
32625
|
-
const registeredProjects = listProjectsSync();
|
|
32626
|
-
const projects = projectConfigs.map((config) => registeredProjects.find((entry) => entry.config.path === config.path) ?? {
|
|
32627
|
-
key: config.name ?? config.path,
|
|
32628
|
-
config
|
|
32629
|
-
});
|
|
32630
|
-
const { trackerIssues, tmuxSessions, dockerContainers, conversations, remoteAgentStates } = sharedSignals ?? await captureSharedResourceSignals();
|
|
32631
|
-
const pullRequests = await loadOpenPullRequests(projects);
|
|
32632
|
-
const issueMap = /* @__PURE__ */ new Map();
|
|
32633
|
-
const projectByPrefix = /* @__PURE__ */ new Map();
|
|
32634
|
-
for (const project of projects) for (const prefix of projectPrefixes(project)) projectByPrefix.set(prefix, project);
|
|
32635
|
-
const projectRefFromResolved = (resolvedProject) => projects.find((project) => project.key === resolvedProject.projectKey || project.config.path === resolvedProject.projectPath) ?? null;
|
|
32636
|
-
const resolveProjectRef = (issueId, preferredProject) => {
|
|
32637
|
-
if (preferredProject) return preferredProject;
|
|
32638
|
-
const resolvedProject = resolveProjectFromIssueSync(issueId);
|
|
32639
|
-
if (resolvedProject) {
|
|
32640
|
-
const project = projectRefFromResolved(resolvedProject);
|
|
32641
|
-
if (project) return project;
|
|
32642
|
-
}
|
|
32643
|
-
const prefix = issueId.toUpperCase().match(/^([A-Z]+)-\d+$/)?.[1] ?? "";
|
|
32644
|
-
return projectByPrefix.get(prefix) ?? null;
|
|
32645
|
-
};
|
|
32646
|
-
const ensureIssue = (issueId, preferredProject) => {
|
|
32647
|
-
const upper = issueId.toUpperCase();
|
|
32648
|
-
const existing = issueMap.get(upper);
|
|
32649
|
-
if (existing) return existing;
|
|
32650
|
-
const resolved = resolveProjectRef(upper, preferredProject);
|
|
32651
|
-
if (!resolved) return null;
|
|
32652
|
-
const tracker = trackerIssues.get(upper);
|
|
32653
|
-
const created = {
|
|
32654
|
-
issueId: upper,
|
|
32655
|
-
title: tracker?.title?.trim() || upper,
|
|
32656
|
-
projectName: resolved.config.name ?? resolved.key,
|
|
32657
|
-
branch: `feature/${upper.toLowerCase()}`,
|
|
32658
|
-
trackerState: typeof tracker?.state === "string" ? tracker.state : null,
|
|
32659
|
-
rawTrackerState: tracker?.rawTrackerState,
|
|
32660
|
-
isRally: tracker?.source === "rally",
|
|
32661
|
-
hasPlanning: false,
|
|
32662
|
-
hasPrd: false,
|
|
32663
|
-
hasState: false,
|
|
32664
|
-
isShadow: false,
|
|
32665
|
-
agentStatus: null,
|
|
32666
|
-
readyForMerge: false,
|
|
32667
|
-
lastActivity: null,
|
|
32668
|
-
resourceSources: /* @__PURE__ */ new Set(),
|
|
32669
|
-
resourceDetails: {
|
|
32670
|
-
tmuxSessions: [],
|
|
32671
|
-
workspacePath: null,
|
|
32672
|
-
localBranches: [],
|
|
32673
|
-
remoteBranches: [],
|
|
32674
|
-
prs: [],
|
|
32675
|
-
xbriefPath: null,
|
|
32676
|
-
xbriefMtime: null,
|
|
32677
|
-
tasksPath: null,
|
|
32678
|
-
prdPath: null,
|
|
32679
|
-
dockerContainers: [],
|
|
32680
|
-
actualBranch: null,
|
|
32681
|
-
branchDrifted: false,
|
|
32682
|
-
branchAheadOfMain: false,
|
|
32683
|
-
workspaceMissing: false,
|
|
32684
|
-
remoteAgent: null,
|
|
32685
|
-
conversations: []
|
|
32686
|
-
},
|
|
32687
|
-
taskTotals: null
|
|
32688
|
-
};
|
|
32689
|
-
issueMap.set(upper, created);
|
|
32690
|
-
return created;
|
|
32691
|
-
};
|
|
32692
|
-
for (const [issueId, tracker] of trackerIssues) {
|
|
32693
|
-
const issue = ensureIssue(issueId);
|
|
32694
|
-
if (!issue) continue;
|
|
32695
|
-
issue.title = tracker.title?.trim() || issue.title;
|
|
32696
|
-
issue.trackerState = typeof tracker.state === "string" ? tracker.state : issue.trackerState;
|
|
32697
|
-
issue.rawTrackerState = tracker.rawTrackerState ?? issue.rawTrackerState;
|
|
32698
|
-
issue.isRally = tracker.source === "rally";
|
|
32699
|
-
issue.resourceSources.add("tracker");
|
|
32700
|
-
}
|
|
32701
|
-
for (const sessionName of tmuxSessions) {
|
|
32702
|
-
if (!isDiscoverableAgentSession(sessionName)) continue;
|
|
32703
|
-
const issueId = parseIssueIdFromTextSync(sessionName);
|
|
32704
|
-
if (!issueId) continue;
|
|
32705
|
-
const issue = ensureIssue(issueId);
|
|
32706
|
-
if (!issue) continue;
|
|
32707
|
-
issue.resourceSources.add("tmux");
|
|
32708
|
-
if (!issue.resourceDetails.tmuxSessions.includes(sessionName)) issue.resourceDetails.tmuxSessions.push(sessionName);
|
|
32709
|
-
}
|
|
32710
|
-
for (const conv of conversations) {
|
|
32711
|
-
if (!conv.issueId || conv.archivedAt) continue;
|
|
32712
|
-
const issue = ensureIssue(conv.issueId);
|
|
32713
|
-
if (!issue) continue;
|
|
32714
|
-
issue.resourceSources.add("conversation");
|
|
32715
|
-
issue.resourceDetails.conversations.push({
|
|
32716
|
-
id: conv.id,
|
|
32717
|
-
name: conv.name,
|
|
32718
|
-
title: conv.title,
|
|
32719
|
-
status: conv.status,
|
|
32720
|
-
tmuxSession: conv.tmuxSession
|
|
32721
|
-
});
|
|
32722
|
-
}
|
|
32723
|
-
for (const remoteState of remoteAgentStates) {
|
|
32724
|
-
const issue = ensureIssue(remoteState.issueId);
|
|
32725
|
-
if (!issue) continue;
|
|
32726
|
-
issue.resourceSources.add("remote-agent");
|
|
32727
|
-
issue.resourceDetails.remoteAgent = {
|
|
32728
|
-
vmName: remoteState.vmName,
|
|
32729
|
-
status: remoteState.status,
|
|
32730
|
-
model: remoteState.model,
|
|
32731
|
-
startedAt: remoteState.startedAt
|
|
32732
|
-
};
|
|
32733
|
-
if (!issue.agentStatus) issue.agentStatus = "active";
|
|
32734
|
-
}
|
|
32735
|
-
for (const containerName of dockerContainers) {
|
|
32736
|
-
const issueId = parseIssueIdFromTextSync(containerName.replace(/feature\//g, "feature-"));
|
|
32737
|
-
if (!issueId) continue;
|
|
32738
|
-
const issue = ensureIssue(issueId);
|
|
32739
|
-
if (!issue) continue;
|
|
32740
|
-
issue.resourceSources.add("docker");
|
|
32741
|
-
issue.resourceDetails.dockerContainers.push(containerName);
|
|
32742
|
-
}
|
|
32743
|
-
await Promise.all(projects.map(async (project) => {
|
|
32744
|
-
const projectPath = project.config.path;
|
|
32745
|
-
const workspacesDir = join(projectPath, "workspaces");
|
|
32746
|
-
const resolverRows = listWorkspaces({
|
|
32747
|
-
projectId: project.key,
|
|
32748
|
-
kind: "issue"
|
|
32749
|
-
});
|
|
32750
|
-
const [workspaceCandidates, branches] = await Promise.all([resolverRows.length > 0 ? Promise.resolve(resolverRows.map((row) => ({
|
|
32751
|
-
name: basename(row.path),
|
|
32752
|
-
issueId: (row.issueId ?? basename(row.path).replace(/^feature-/, "")).toUpperCase()
|
|
32753
|
-
}))) : readdir(workspacesDir, { withFileTypes: true }).then((entries) => entries.filter((entry) => entry.isDirectory() && entry.name.startsWith("feature-")).map((entry) => ({
|
|
32754
|
-
name: entry.name,
|
|
32755
|
-
issueId: entry.name.replace(/^feature-/, "").toUpperCase()
|
|
32756
|
-
}))).catch(() => []), loadProjectBranchSnapshot(projectPath)]);
|
|
32757
|
-
await Promise.all(workspaceCandidates.map(async ({ name, issueId }) => {
|
|
32758
|
-
const issue = ensureIssue(issueId, project);
|
|
32759
|
-
if (!issue) return;
|
|
32760
|
-
const workspace = await scanWorkspace(workspacesDir, name);
|
|
32761
|
-
issue.resourceSources.add("workspace");
|
|
32762
|
-
issue.resourceDetails.workspacePath = workspace.workspacePath;
|
|
32763
|
-
issue.hasPlanning = workspace.hasPlanning;
|
|
32764
|
-
issue.hasPrd = workspace.hasPrd;
|
|
32765
|
-
issue.hasState = workspace.hasState;
|
|
32766
|
-
if (workspace.xbriefPath) {
|
|
32767
|
-
issue.resourceSources.add("vbrief");
|
|
32768
|
-
issue.resourceDetails.xbriefPath = workspace.xbriefPath;
|
|
32769
|
-
issue.resourceDetails.xbriefMtime = workspace.xbriefMtime;
|
|
32770
|
-
}
|
|
32771
|
-
if (workspace.hasTasks) {
|
|
32772
|
-
issue.resourceSources.add("tasks");
|
|
32773
|
-
issue.resourceDetails.tasksPath = join(workspace.workspacePath, ".tasks");
|
|
32774
|
-
}
|
|
32775
|
-
const gitInfo = await resolveAgentGitInfo(workspace.workspacePath, issue.branch);
|
|
32776
|
-
issue.resourceDetails.actualBranch = gitInfo.actualBranch;
|
|
32777
|
-
issue.resourceDetails.branchDrifted = gitInfo.branchDrifted;
|
|
32778
|
-
issue.resourceDetails.workspaceMissing = gitInfo.workspaceMissing;
|
|
32779
|
-
}));
|
|
32780
|
-
for (const [branch, key] of [...branches.local.map((b) => [b, "localBranches"]), ...branches.remote.map((b) => [b, "remoteBranches"])]) {
|
|
32781
|
-
const issueId = parseIssueIdFromTextSync(branch);
|
|
32782
|
-
if (!issueId) continue;
|
|
32783
|
-
const issue = ensureIssue(issueId, project);
|
|
32784
|
-
if (!issue) continue;
|
|
32785
|
-
issue.resourceSources.add("branch");
|
|
32786
|
-
if (!issue.resourceDetails[key].includes(branch)) issue.resourceDetails[key].push(branch);
|
|
32787
|
-
if (branches.ahead.has(branch)) issue.resourceDetails.branchAheadOfMain = true;
|
|
32788
|
-
}
|
|
32789
|
-
}));
|
|
32790
|
-
for (const [issueId, prs] of pullRequests) {
|
|
32791
|
-
const issue = ensureIssue(issueId);
|
|
32792
|
-
if (!issue) continue;
|
|
32793
|
-
issue.resourceSources.add("pr");
|
|
32794
|
-
issue.resourceDetails.prs = prs;
|
|
32795
|
-
const bestTitle = prs.find((pr) => !pr.isDraft)?.title ?? prs[0]?.title;
|
|
32796
|
-
issue.title = issue.title === issue.issueId && bestTitle ? bestTitle : issue.title;
|
|
32797
|
-
}
|
|
32798
|
-
await Promise.all([...issueMap.values()].map(async (issue) => {
|
|
32799
|
-
if (issue.resourceDetails.tmuxSessions.length === 0) return;
|
|
32800
|
-
const states = (await Promise.all(issue.resourceDetails.tmuxSessions.map((sessionName) => Effect.runPromise(getAgentRuntimeState(sessionName)).catch(() => null)))).filter((state) => state !== null);
|
|
32801
|
-
if (states.length === 0) return;
|
|
32802
|
-
issue.agentStatus = (states.find((state) => state.state === "active") ?? states.reduce((a, b) => Date.parse(a.lastActivity) >= Date.parse(b.lastActivity) ? a : b)).state;
|
|
32803
|
-
const lastActivity = Math.max(...states.map((state) => Date.parse(state.lastActivity)).filter(Number.isFinite));
|
|
32804
|
-
issue.lastActivity = Number.isFinite(lastActivity) ? lastActivity : null;
|
|
32805
|
-
}));
|
|
32806
|
-
const reviewStatusIssueIds = [...issueMap.values()].filter(shouldLoadReviewStatus).map((issue) => issue.issueId);
|
|
32807
|
-
if (reviewStatusIssueIds.length > 0) {
|
|
32808
|
-
const readyForMergeFlags = loadReadyForMergeFlags(reviewStatusIssueIds);
|
|
32809
|
-
for (const issue of issueMap.values()) issue.readyForMerge = readyForMergeFlags.get(issue.issueId) ?? false;
|
|
32810
|
-
}
|
|
32811
|
-
const memberships = /* @__PURE__ */ new Map();
|
|
32812
|
-
const unavailableProjects = /* @__PURE__ */ new Set();
|
|
32813
|
-
const projectMemberships = readPipelineMembershipSnapshotsForProjects(projects.map((project) => project.config));
|
|
32814
|
-
for (const result of projectMemberships) {
|
|
32815
|
-
if (result.error) unavailableProjects.add(result.project.name);
|
|
32816
|
-
for (const membership of result.memberships ?? []) {
|
|
32817
|
-
ensureIssue(membership.issueId);
|
|
32818
|
-
memberships.set(membership.issueId, membership);
|
|
32819
|
-
}
|
|
32820
|
-
}
|
|
32821
|
-
await Promise.all([...issueMap.values()].map(async (issue) => {
|
|
32822
|
-
const project = resolveProjectRef(issue.issueId);
|
|
32823
|
-
if (!project) return;
|
|
32824
|
-
const draft = await Effect.runPromise(findDraftPrd(project.config.path, issue.issueId)).catch(() => null);
|
|
32825
|
-
if (!draft) return;
|
|
32826
|
-
issue.resourceSources.add("prd");
|
|
32827
|
-
issue.resourceDetails.prdPath = draft.path;
|
|
32828
|
-
issue.hasPrd = true;
|
|
32829
|
-
}));
|
|
32830
|
-
const untitledIssueIds = [...issueMap.values()].filter((issue) => issue.resourceSources.size > 0 && issue.title === issue.issueId).map((issue) => issue.issueId);
|
|
32831
|
-
if (untitledIssueIds.length > 0) {
|
|
32832
|
-
const fallbackTitles = await resolveMissingIssueTitles(untitledIssueIds).catch(() => /* @__PURE__ */ new Map());
|
|
32833
|
-
for (const issue of issueMap.values()) {
|
|
32834
|
-
const title = fallbackTitles.get(issue.issueId);
|
|
32835
|
-
if (title && issue.title === issue.issueId) issue.title = title;
|
|
32836
|
-
}
|
|
32837
|
-
}
|
|
32838
|
-
return [...issueMap.values()].filter((issue) => issue.resourceSources.size > 0).filter((issue) => {
|
|
32839
|
-
const membership = memberships.get(issue.issueId);
|
|
32840
|
-
return membership?.inPipeline === true || membership?.bucket === "clean_terminal" && isLiveResource(issue) || !membership && unavailableProjects.has(issue.projectName) && isLiveResource(issue);
|
|
32841
|
-
}).map((issue) => {
|
|
32842
|
-
const membership = memberships.get(issue.issueId);
|
|
32843
|
-
const hasTmux = issue.resourceDetails.tmuxSessions.length > 0;
|
|
32844
|
-
const hasRecentHeartbeat = hasRecentActivity(issue.lastActivity);
|
|
32845
|
-
const stateLabel = deriveStateLabel(issue, hasTmux, hasRecentHeartbeat, membership);
|
|
32846
|
-
const isRemoteRunning = issue.resourceDetails.remoteAgent?.status === "running" || issue.resourceDetails.remoteAgent?.status === "starting";
|
|
32847
|
-
const status = hasTmux && (issue.agentStatus === "active" || hasRecentHeartbeat) || isRemoteRunning ? "running" : issue.hasState ? "has_state" : "idle";
|
|
32848
|
-
return {
|
|
32849
|
-
issueId: issue.issueId,
|
|
32850
|
-
title: issue.title,
|
|
32851
|
-
projectName: issue.projectName,
|
|
32852
|
-
branch: issue.branch,
|
|
32853
|
-
status,
|
|
32854
|
-
stateLabel,
|
|
32855
|
-
agentStatus: issue.agentStatus,
|
|
32856
|
-
hasPlanning: issue.hasPlanning,
|
|
32857
|
-
hasPrd: issue.hasPrd,
|
|
32858
|
-
hasState: issue.hasState,
|
|
32859
|
-
isShadow: issue.isShadow,
|
|
32860
|
-
isRally: issue.isRally,
|
|
32861
|
-
childCount: trackerIssues.get(issue.issueId)?.totalChildCount,
|
|
32862
|
-
completedCount: trackerIssues.get(issue.issueId)?.completedChildCount,
|
|
32863
|
-
inProgressCount: trackerIssues.get(issue.issueId)?.inProgressChildCount,
|
|
32864
|
-
readyForMerge: issue.readyForMerge,
|
|
32865
|
-
rawTrackerState: issue.rawTrackerState,
|
|
32866
|
-
resourceSources: new Set([...issue.resourceSources].sort()),
|
|
32867
|
-
resourceDetails: issue.resourceDetails,
|
|
32868
|
-
taskTotals: issue.taskTotals,
|
|
32869
|
-
pipelineBucket: membership?.bucket,
|
|
32870
|
-
specOnlyPlanned: membership ? membership.bucket === "planned_backlog" && membership.reasons.includes("open issue with an xBRIEF spec but no branch/PR — planned work whose plan encodes code paths that age; needs starting or re-planning") : void 0,
|
|
32871
|
-
resourceDrift: membership ? !membership.inPipeline : void 0
|
|
32872
|
-
};
|
|
32873
|
-
}).sort((a, b) => compareIssueIds(a.issueId, b.issueId));
|
|
32874
|
-
}
|
|
32875
|
-
function toPublicResourceIssue(issue) {
|
|
32876
|
-
return {
|
|
32877
|
-
...issue,
|
|
32878
|
-
resourceSources: [...issue.resourceSources],
|
|
32879
|
-
resourceDetails: summarizeResourceDetails(issue.resourceDetails)
|
|
32880
|
-
};
|
|
32881
|
-
}
|
|
32882
|
-
function rebuildCombinedResourceSnapshot() {
|
|
32883
|
-
const detailed = [...projectResourceSnapshots.values()].flatMap((snapshot) => snapshot.detailed).sort((a, b) => compareIssueIds(a.issueId, b.issueId));
|
|
32884
|
-
const publicIssues = detailed.map(toPublicResourceIssue);
|
|
32885
|
-
cachedDetailedResourceIssues = detailed;
|
|
32886
|
-
cachedResourceIssues = {
|
|
32887
|
-
value: publicIssues,
|
|
32888
|
-
computedAt: Math.max(0, ...[...projectResourceSnapshots.values()].map((snapshot) => snapshot.computedAt))
|
|
32889
|
-
};
|
|
32890
|
-
return publicIssues;
|
|
32891
|
-
}
|
|
32892
|
-
function publishProjectResourceSnapshot(project, issues) {
|
|
32893
|
-
projectResourceSnapshots.set(project.path, {
|
|
32894
|
-
detailed: issues,
|
|
32895
|
-
public: issues.map(toPublicResourceIssue),
|
|
32896
|
-
computedAt: Date.now()
|
|
32897
|
-
});
|
|
32898
|
-
rebuildCombinedResourceSnapshot();
|
|
32899
|
-
}
|
|
32900
|
-
/** Refresh only the requested projects, capturing fleet-wide signals once for the batch. */
|
|
32901
|
-
async function refreshResourceAllocatedProjects(projects, options = {}) {
|
|
32902
|
-
if (projects.length === 0) return cachedResourceIssues?.value ?? [];
|
|
32903
|
-
const sharedSignals = await captureSharedResourceSignals();
|
|
32904
|
-
const failures = [];
|
|
32905
|
-
for (const project of projects) try {
|
|
32906
|
-
if (options.refreshMembership !== false) await refreshMembershipSnapshotsForProjects([project]);
|
|
32907
|
-
publishProjectResourceSnapshot(project, await computeResourceAllocatedIssues([project], sharedSignals));
|
|
32908
|
-
} catch (error) {
|
|
32909
|
-
const failure = error instanceof Error ? error : new Error(String(error));
|
|
32910
|
-
failures.push(failure);
|
|
32911
|
-
console.warn(`[resource-discovery] refresh failed for ${project.name ?? project.path}; keeping last-good snapshot:`, failure.message);
|
|
32912
|
-
}
|
|
32913
|
-
if (failures.length > 0) throw new AggregateError(failures, `${failures.length} project resource refresh(es) failed`);
|
|
32914
|
-
return cachedResourceIssues?.value ?? [];
|
|
32915
|
-
}
|
|
32916
|
-
async function getCachedResourceAllocatedIssues() {
|
|
32917
|
-
return cachedResourceIssues?.value ?? [];
|
|
32918
|
-
}
|
|
32919
|
-
function sanitizeResourceAllocatedIssues(issues) {
|
|
32920
|
-
return issues.map((issue) => ({
|
|
32921
|
-
...issue,
|
|
32922
|
-
resourceDetails: {
|
|
32923
|
-
hasWorkspace: issue.resourceDetails.hasWorkspace,
|
|
32924
|
-
localBranchCount: issue.resourceDetails.localBranchCount,
|
|
32925
|
-
remoteBranchCount: issue.resourceDetails.remoteBranchCount,
|
|
32926
|
-
tmuxSessionCount: issue.resourceDetails.tmuxSessionCount,
|
|
32927
|
-
prs: issue.resourceDetails.prs.map((pr) => ({
|
|
32928
|
-
number: pr.number,
|
|
32929
|
-
title: pr.title,
|
|
32930
|
-
state: pr.state,
|
|
32931
|
-
isDraft: pr.isDraft
|
|
32932
|
-
})),
|
|
32933
|
-
hasXbrief: issue.resourceDetails.hasXbrief,
|
|
32934
|
-
hasTasks: issue.resourceDetails.hasTasks,
|
|
32935
|
-
hasPrd: issue.resourceDetails.hasPrd,
|
|
32936
|
-
dockerContainerCount: issue.resourceDetails.dockerContainerCount,
|
|
32937
|
-
actualBranch: issue.resourceDetails.actualBranch,
|
|
32938
|
-
branchDrifted: issue.resourceDetails.branchDrifted,
|
|
32939
|
-
branchAheadOfMain: issue.resourceDetails.branchAheadOfMain,
|
|
32940
|
-
workspaceMissing: issue.resourceDetails.workspaceMissing,
|
|
32941
|
-
remoteAgent: issue.resourceDetails.remoteAgent ?? null,
|
|
32942
|
-
conversations: issue.resourceDetails.conversations.map((conv) => ({
|
|
32943
|
-
id: conv.id,
|
|
32944
|
-
name: conv.name,
|
|
32945
|
-
title: conv.title,
|
|
32946
|
-
status: conv.status
|
|
32947
|
-
}))
|
|
32948
|
-
}
|
|
32949
|
-
}));
|
|
32950
|
-
}
|
|
32951
|
-
function toPublicResourceDetailIdentifiers(details) {
|
|
32952
|
-
return summarizeResourceDetailIdentifiers(details);
|
|
32953
|
-
}
|
|
32954
|
-
async function getResourceDetailIdentifiers(issueId) {
|
|
32955
|
-
const normalizedIssueId = issueId.toUpperCase();
|
|
32956
|
-
const cachedMatch = cachedDetailedResourceIssues?.find((entry) => entry.issueId === normalizedIssueId);
|
|
32957
|
-
return cachedMatch ? toPublicResourceDetailIdentifiers(cachedMatch.resourceDetails) : null;
|
|
32958
|
-
}
|
|
32959
|
-
function groupResourceAllocatedIssuesByProject(issues) {
|
|
32960
|
-
const projectTree = /* @__PURE__ */ new Map();
|
|
32961
|
-
for (const issue of issues) {
|
|
32962
|
-
const existing = projectTree.get(issue.projectName);
|
|
32963
|
-
if (existing) {
|
|
32964
|
-
existing.features.push(issue);
|
|
32965
|
-
continue;
|
|
32966
|
-
}
|
|
32967
|
-
projectTree.set(issue.projectName, {
|
|
32968
|
-
name: issue.projectName,
|
|
32969
|
-
path: issue.projectName,
|
|
32970
|
-
features: [issue]
|
|
32971
|
-
});
|
|
32972
|
-
}
|
|
32973
|
-
return [...projectTree.values()].map((project) => ({
|
|
32974
|
-
...project,
|
|
32975
|
-
features: project.features.sort((a, b) => compareIssueIds(a.issueId, b.issueId))
|
|
32976
|
-
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
32977
|
-
}
|
|
32978
|
-
//#endregion
|
|
32979
32212
|
//#region ../../lib/overdeck/issue-reads.ts
|
|
32980
32213
|
init_projects();
|
|
32981
|
-
init_tracker_utils();
|
|
32982
32214
|
init_io();
|
|
32983
32215
|
function isGitHubIssue$6(issueId) {
|
|
32984
32216
|
const resolved = resolveGitHubIssueSync(issueId);
|
|
@@ -33271,10 +32503,7 @@ function getIssueResourceDetails(rawId) {
|
|
|
33271
32503
|
//#endregion
|
|
33272
32504
|
//#region ../../lib/overdeck/planning-promotion.ts
|
|
33273
32505
|
init_tracker_config();
|
|
33274
|
-
init_agents$1();
|
|
33275
|
-
init_pan_dir();
|
|
33276
32506
|
init_projects();
|
|
33277
|
-
init_review_status();
|
|
33278
32507
|
init_remote_agents();
|
|
33279
32508
|
init_tracker_utils();
|
|
33280
32509
|
init_tmux();
|
|
@@ -34105,7 +33334,7 @@ async function closeIssuePullRequest(issueId, reason = "Canceled via Overdeck")
|
|
|
34105
33334
|
timeout: 15e3
|
|
34106
33335
|
});
|
|
34107
33336
|
try {
|
|
34108
|
-
const { setReviewStatusSync } = await import("./review-status-
|
|
33337
|
+
const { setReviewStatusSync } = await import("./review-status-C_kQeeX0.js");
|
|
34109
33338
|
setReviewStatusSync(issueId.toUpperCase(), { prUrl: void 0 });
|
|
34110
33339
|
} catch {}
|
|
34111
33340
|
return [`Closed PR #${prNumber} on ${githubCheck.owner}/${githubCheck.repo}`];
|
|
@@ -34159,7 +33388,7 @@ async function runDestructiveIssueLifecycle(id, mode, opts = {}) {
|
|
|
34159
33388
|
const { ctx, projectConfig } = buildLifecycleContext(id, getIssueDataService$8().getIssueSource(id) ?? void 0);
|
|
34160
33389
|
const deleteWorkspace = opts.deleteWorkspace ?? true;
|
|
34161
33390
|
cleanupLog.push(...await closeIssuePullRequest(id, mode === "cancel" ? "Canceled via Overdeck" : "Reset to Todo via Overdeck"));
|
|
34162
|
-
const { resetToTodo, cancelIssueWorkflow } = await import("./lifecycle-
|
|
33391
|
+
const { resetToTodo, cancelIssueWorkflow } = await import("./lifecycle-DaCovZwn.js");
|
|
34163
33392
|
const workflow = mode === "cancel" ? cancelIssueWorkflow : resetToTodo;
|
|
34164
33393
|
const result = await Effect.runPromise(workflow(ctx, {
|
|
34165
33394
|
deleteWorkspace,
|
|
@@ -34174,7 +33403,7 @@ async function runDestructiveIssueLifecycle(id, mode, opts = {}) {
|
|
|
34174
33403
|
}));
|
|
34175
33404
|
cleanupLog.push(...result.steps.flatMap((step) => step.details || [step.error].filter(Boolean)));
|
|
34176
33405
|
if (mode === "cancel") try {
|
|
34177
|
-
const { transitionXBriefOnMain } = await import("./lifecycle-io-
|
|
33406
|
+
const { transitionXBriefOnMain } = await import("./lifecycle-io-BBMTaP7S.js");
|
|
34178
33407
|
const tx = await Effect.runPromise(transitionXBriefOnMain(ctx.projectPath, id, "cancelled", "cancelled", `scope: cancel ${id.toUpperCase()} xBRIEF`));
|
|
34179
33408
|
if (tx.moved) cleanupLog.push(`xBRIEF moved ${tx.fromDir} → cancelled`);
|
|
34180
33409
|
if (tx.committed) cleanupLog.push(`Committed xBRIEF cancellation on main`);
|
|
@@ -34182,8 +33411,8 @@ async function runDestructiveIssueLifecycle(id, mode, opts = {}) {
|
|
|
34182
33411
|
cleanupLog.push(`xBRIEF cancel transition failed (non-fatal): ${err?.message ?? err}`);
|
|
34183
33412
|
}
|
|
34184
33413
|
try {
|
|
34185
|
-
const { killAllReviewerSessions } = await import("./review-agent-
|
|
34186
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
33414
|
+
const { killAllReviewerSessions } = await import("./review-agent-DgkUPRx0.js");
|
|
33415
|
+
const { resolveProjectFromIssueSync } = await import("./projects-LftaVK99.js");
|
|
34187
33416
|
const projectKey = resolveProjectFromIssueSync(id)?.projectKey;
|
|
34188
33417
|
if (projectKey) {
|
|
34189
33418
|
const { killed } = await Effect.runPromise(killAllReviewerSessions(projectKey, id.toUpperCase()));
|
|
@@ -34197,7 +33426,7 @@ async function runDestructiveIssueLifecycle(id, mode, opts = {}) {
|
|
|
34197
33426
|
cleanupLog.push("Cleared review status");
|
|
34198
33427
|
} catch {}
|
|
34199
33428
|
try {
|
|
34200
|
-
const { resetPostMergeState } = await import("./merge-agent-
|
|
33429
|
+
const { resetPostMergeState } = await import("./merge-agent-BuoC_PRZ.js");
|
|
34201
33430
|
resetPostMergeState(id);
|
|
34202
33431
|
resetPostMergeState(id.toUpperCase());
|
|
34203
33432
|
cleanupLog.push("Cleared merge state");
|
|
@@ -34217,7 +33446,7 @@ function closeIssueTransition(options) {
|
|
|
34217
33446
|
const { issueId, body, eventStore } = options;
|
|
34218
33447
|
const { reason } = body;
|
|
34219
33448
|
const projectPath = getProjectPath$3(void 0, extractPrefixSync(issueId) ?? issueId.split("-")[0]);
|
|
34220
|
-
const { close: closeWorkflow } = yield* Effect.promise(() => import("./lifecycle-
|
|
33449
|
+
const { close: closeWorkflow } = yield* Effect.promise(() => import("./lifecycle-DaCovZwn.js"));
|
|
34221
33450
|
const githubCheck = isGitHubIssue$4(issueId);
|
|
34222
33451
|
const issueDataService = getIssueDataService$8();
|
|
34223
33452
|
const issueSource = issueDataService.getIssueSource(issueId);
|
|
@@ -34484,7 +33713,7 @@ function reopenIssueTransition(options) {
|
|
|
34484
33713
|
else clearReviewStatus(id.toUpperCase());
|
|
34485
33714
|
} catch {}
|
|
34486
33715
|
try {
|
|
34487
|
-
const { resetPostMergeState } = await import("./merge-agent-
|
|
33716
|
+
const { resetPostMergeState } = await import("./merge-agent-BuoC_PRZ.js");
|
|
34488
33717
|
resetPostMergeState(id);
|
|
34489
33718
|
resetPostMergeState(id.toUpperCase());
|
|
34490
33719
|
} catch {}
|
|
@@ -34548,7 +33777,7 @@ function moveIssueStatus(options) {
|
|
|
34548
33777
|
"done"
|
|
34549
33778
|
];
|
|
34550
33779
|
if (!targetStatus || !validStatuses.includes(targetStatus)) return jsonResponse({ error: `Invalid targetStatus. Must be one of: ${validStatuses.join(", ")}` }, { status: 400 });
|
|
34551
|
-
const { updateShadowState } = yield* Effect.promise(() => import("./shadow-state-
|
|
33780
|
+
const { updateShadowState } = yield* Effect.promise(() => import("./shadow-state-nGhCNXT2.js"));
|
|
34552
33781
|
const issueState = {
|
|
34553
33782
|
backlog: "open",
|
|
34554
33783
|
todo: "open",
|
|
@@ -34611,7 +33840,6 @@ function moveIssueStatus(options) {
|
|
|
34611
33840
|
init_issue_service_singleton();
|
|
34612
33841
|
init_issue_id();
|
|
34613
33842
|
init_agents$1();
|
|
34614
|
-
init_resolver();
|
|
34615
33843
|
init_writer();
|
|
34616
33844
|
const execAsync$8 = promisify(exec);
|
|
34617
33845
|
/**
|
|
@@ -34792,7 +34020,7 @@ async function copySettingsToWorkspace(id) {
|
|
|
34792
34020
|
success: false,
|
|
34793
34021
|
error: "Workspace not found"
|
|
34794
34022
|
}, { status: 404 });
|
|
34795
|
-
const { copyOverdeckSettingsToWorkspaceSync } = await import("./workspace-manager-
|
|
34023
|
+
const { copyOverdeckSettingsToWorkspaceSync } = await import("./workspace-manager-jfkKAEuO.js");
|
|
34796
34024
|
const result = copyOverdeckSettingsToWorkspaceSync(workspacePath);
|
|
34797
34025
|
return jsonResponse({
|
|
34798
34026
|
success: result.errors.length === 0 || result.copied.length > 0,
|
|
@@ -34802,8 +34030,11 @@ async function copySettingsToWorkspace(id) {
|
|
|
34802
34030
|
}
|
|
34803
34031
|
//#endregion
|
|
34804
34032
|
//#region ../../lib/overdeck/task-generation.ts
|
|
34033
|
+
init_concurrency$1();
|
|
34805
34034
|
init_identity_record();
|
|
34806
34035
|
init_shadow_state();
|
|
34036
|
+
init_advisory_checks();
|
|
34037
|
+
init_github_app();
|
|
34807
34038
|
init_io();
|
|
34808
34039
|
function buildChildStoriesFromRally(children) {
|
|
34809
34040
|
return children.map((c) => ({
|
|
@@ -35295,7 +34526,7 @@ function restartFromPlan(options) {
|
|
|
35295
34526
|
});
|
|
35296
34527
|
const resetResult = yield* Effect.promise(async () => {
|
|
35297
34528
|
try {
|
|
35298
|
-
const { runGitResetHard } = await import("./dangerous-git-ops-
|
|
34529
|
+
const { runGitResetHard } = await import("./dangerous-git-ops-By9iguTP.js");
|
|
35299
34530
|
async function findPlanningCommit(grep, label) {
|
|
35300
34531
|
try {
|
|
35301
34532
|
const { stdout } = await execAsync$7(`git log --grep="${grep.replace(/"/g, "\\\"")}" --format=%H -1`, {
|
|
@@ -35648,7 +34879,6 @@ async function fetchIssueDiscussions(issueId, deps = {}) {
|
|
|
35648
34879
|
//#region ../../lib/overdeck/issue-close-out.ts
|
|
35649
34880
|
init_issue_service_singleton();
|
|
35650
34881
|
init_tracker_config();
|
|
35651
|
-
init_concurrency$1();
|
|
35652
34882
|
init_agents$1();
|
|
35653
34883
|
init_projects();
|
|
35654
34884
|
init_tracker_utils();
|
|
@@ -35743,7 +34973,7 @@ function closeOutIssue(id, opts = {}) {
|
|
|
35743
34973
|
}
|
|
35744
34974
|
const closeOutResult = yield* Effect.promise(async () => {
|
|
35745
34975
|
try {
|
|
35746
|
-
const { closeOut } = await import("./lifecycle-
|
|
34976
|
+
const { closeOut } = await import("./lifecycle-DaCovZwn.js");
|
|
35747
34977
|
return {
|
|
35748
34978
|
ok: true,
|
|
35749
34979
|
result: await Effect.runPromise(closeOut(ctx, {
|
|
@@ -35833,7 +35063,7 @@ function bulkCloseOut(body) {
|
|
|
35833
35063
|
const invalidIds = issueIds.filter((id) => !isValidIssueId(id));
|
|
35834
35064
|
if (invalidIds.length > 0) return jsonResponse({ error: `Invalid issue ID format: ${invalidIds.join(", ")}` }, { status: 400 });
|
|
35835
35065
|
const eventStore = yield* EventStoreService;
|
|
35836
|
-
const { closeOut } = yield* Effect.promise(() => import("./lifecycle-
|
|
35066
|
+
const { closeOut } = yield* Effect.promise(() => import("./lifecycle-DaCovZwn.js"));
|
|
35837
35067
|
const issueDataService = getIssueDataService$5();
|
|
35838
35068
|
const tasks = [];
|
|
35839
35069
|
const agentChecks = yield* withConcurrencyLimit(issueIds.map((id) => Effect.promise(async () => {
|
|
@@ -36000,7 +35230,7 @@ const execFileAsync$15 = promisify(execFile);
|
|
|
36000
35230
|
function getIssueDataService$4() {
|
|
36001
35231
|
return getSharedIssueService();
|
|
36002
35232
|
}
|
|
36003
|
-
const readJsonBody$
|
|
35233
|
+
const readJsonBody$20 = Effect.gen(function* () {
|
|
36004
35234
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
36005
35235
|
try {
|
|
36006
35236
|
return text ? JSON.parse(text) : {};
|
|
@@ -36058,8 +35288,8 @@ const getIssueShipLogRoute = HttpRouter.add("GET", "/api/issues/:id/ship-log", h
|
|
|
36058
35288
|
const id = (yield* HttpRouter.params)["id"] ?? "";
|
|
36059
35289
|
if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
36060
35290
|
return yield* Effect.promise(async () => {
|
|
36061
|
-
const { getShipLog } = await import("./ship-log-
|
|
36062
|
-
const { getReviewStatusSync } = await import("./review-status-
|
|
35291
|
+
const { getShipLog } = await import("./ship-log-ie0A_SqV.js");
|
|
35292
|
+
const { getReviewStatusSync } = await import("./review-status-C_kQeeX0.js");
|
|
36063
35293
|
const log = getShipLog(id);
|
|
36064
35294
|
const rs = getReviewStatusSync(id);
|
|
36065
35295
|
return jsonResponse({
|
|
@@ -36074,8 +35304,8 @@ const getIssueVerificationRoute = HttpRouter.add("GET", "/api/issues/:id/verific
|
|
|
36074
35304
|
const id = (yield* HttpRouter.params)["id"] ?? "";
|
|
36075
35305
|
if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
36076
35306
|
return yield* Effect.promise(async () => {
|
|
36077
|
-
const { readVerificationArtifact } = await import("./verification-artifact-
|
|
36078
|
-
const { getReviewStatusSync } = await import("./review-status-
|
|
35307
|
+
const { readVerificationArtifact } = await import("./verification-artifact-D3viYe_t.js");
|
|
35308
|
+
const { getReviewStatusSync } = await import("./review-status-C_kQeeX0.js");
|
|
36079
35309
|
const { join } = await import("node:path");
|
|
36080
35310
|
const resolved = resolveProjectFromIssueSync(id);
|
|
36081
35311
|
const workspacePath = resolved ? join(resolved.projectPath, "workspaces", `feature-${id.toLowerCase()}`) : null;
|
|
@@ -36093,7 +35323,7 @@ const postIssueCloseRoute = HttpRouter.add("POST", "/api/issues/:issueId/close",
|
|
|
36093
35323
|
if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
36094
35324
|
return yield* closeIssueTransition({
|
|
36095
35325
|
issueId,
|
|
36096
|
-
body: yield* readJsonBody$
|
|
35326
|
+
body: yield* readJsonBody$20,
|
|
36097
35327
|
eventStore: yield* EventStoreService
|
|
36098
35328
|
});
|
|
36099
35329
|
})));
|
|
@@ -36101,7 +35331,7 @@ const postIssueStartPlanningRoute = HttpRouter.add("POST", "/api/issues/:id/star
|
|
|
36101
35331
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
36102
35332
|
const id = (yield* HttpRouter.params)["id"] ?? "";
|
|
36103
35333
|
if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
36104
|
-
const body = yield* readJsonBody$
|
|
35334
|
+
const body = yield* readJsonBody$20;
|
|
36105
35335
|
const eventStore = yield* EventStoreService;
|
|
36106
35336
|
const linear = yield* LinearClient;
|
|
36107
35337
|
const github = yield* GitHubClient;
|
|
@@ -36129,7 +35359,7 @@ const postIssueAbortPlanningRoute = HttpRouter.add("POST", "/api/issues/:id/abor
|
|
|
36129
35359
|
if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
36130
35360
|
return yield* abortPlanningForIssue({
|
|
36131
35361
|
id,
|
|
36132
|
-
body: yield* readJsonBody$
|
|
35362
|
+
body: yield* readJsonBody$20,
|
|
36133
35363
|
lifecycle: yield* IssueLifecycle,
|
|
36134
35364
|
linear: yield* LinearClient,
|
|
36135
35365
|
eventStore: yield* EventStoreService
|
|
@@ -36139,7 +35369,7 @@ const postIssueCompletePlanningRoute = HttpRouter.add("POST", "/api/issues/:id/c
|
|
|
36139
35369
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
36140
35370
|
const id = (yield* HttpRouter.params)["id"] ?? "";
|
|
36141
35371
|
if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
36142
|
-
const body = yield* readJsonBody$
|
|
35372
|
+
const body = yield* readJsonBody$20;
|
|
36143
35373
|
const eventStore = yield* EventStoreService;
|
|
36144
35374
|
const linear = yield* LinearClient;
|
|
36145
35375
|
const lifecycle = yield* IssueLifecycle;
|
|
@@ -36165,7 +35395,7 @@ const postIssueResetRoute = HttpRouter.add("POST", "/api/issues/:id/reset", http
|
|
|
36165
35395
|
if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
36166
35396
|
return yield* resetIssueTransition({
|
|
36167
35397
|
id,
|
|
36168
|
-
body: yield* readJsonBody$
|
|
35398
|
+
body: yield* readJsonBody$20,
|
|
36169
35399
|
eventStore: yield* EventStoreService
|
|
36170
35400
|
});
|
|
36171
35401
|
})));
|
|
@@ -36189,7 +35419,7 @@ const postIssueCancelRoute = HttpRouter.add("POST", "/api/issues/:id/cancel", ht
|
|
|
36189
35419
|
if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
36190
35420
|
return yield* cancelIssueTransition({
|
|
36191
35421
|
id,
|
|
36192
|
-
body: yield* readJsonBody$
|
|
35422
|
+
body: yield* readJsonBody$20,
|
|
36193
35423
|
eventStore: yield* EventStoreService
|
|
36194
35424
|
});
|
|
36195
35425
|
})));
|
|
@@ -36200,7 +35430,7 @@ const postIssueReopenRoute = HttpRouter.add("POST", "/api/issues/:id/reopen", ht
|
|
|
36200
35430
|
if (authError) return authError;
|
|
36201
35431
|
return yield* reopenIssueTransition({
|
|
36202
35432
|
id,
|
|
36203
|
-
body: yield* readJsonBody$
|
|
35433
|
+
body: yield* readJsonBody$20,
|
|
36204
35434
|
lifecycle: yield* IssueLifecycle,
|
|
36205
35435
|
linear: yield* LinearClient,
|
|
36206
35436
|
eventStore: yield* EventStoreService
|
|
@@ -36220,7 +35450,7 @@ const postIssueMoveStatusRoute = HttpRouter.add("POST", "/api/issues/:id/move-st
|
|
|
36220
35450
|
if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
36221
35451
|
return yield* moveIssueStatus({
|
|
36222
35452
|
id,
|
|
36223
|
-
body: yield* readJsonBody$
|
|
35453
|
+
body: yield* readJsonBody$20,
|
|
36224
35454
|
eventStore: yield* EventStoreService,
|
|
36225
35455
|
lifecycle: yield* IssueLifecycle
|
|
36226
35456
|
});
|
|
@@ -36232,7 +35462,7 @@ const postIssueCleanupWorkspaceRoute = HttpRouter.add("POST", "/api/issues/:id/c
|
|
|
36232
35462
|
})));
|
|
36233
35463
|
const postIssueDeepWipeRoute = HttpRouter.add("POST", "/api/issues/:id/deep-wipe", httpHandler(Effect.gen(function* () {
|
|
36234
35464
|
const id = (yield* HttpRouter.params)["id"] ?? "";
|
|
36235
|
-
const body = yield* readJsonBody$
|
|
35465
|
+
const body = yield* readJsonBody$20;
|
|
36236
35466
|
const eventStore = yield* EventStoreService;
|
|
36237
35467
|
return yield* Effect.promise(() => deepWipeIssue(id, body, eventStore));
|
|
36238
35468
|
})));
|
|
@@ -36293,7 +35523,7 @@ const postIssueTaskInspectRoute = HttpRouter.add("POST", "/api/issues/:id/tasks/
|
|
|
36293
35523
|
return yield* inspectIssueTask({
|
|
36294
35524
|
id: (params["id"] ?? "").toUpperCase(),
|
|
36295
35525
|
itemId: params["itemId"] ?? "",
|
|
36296
|
-
body: yield* readJsonBody$
|
|
35526
|
+
body: yield* readJsonBody$20
|
|
36297
35527
|
});
|
|
36298
35528
|
})));
|
|
36299
35529
|
const getIssuePlanningStateRoute = HttpRouter.add("GET", "/api/issues/:id/planning-state", httpHandler(Effect.gen(function* () {
|
|
@@ -37271,7 +36501,7 @@ async function readMemoryPhase(workspace) {
|
|
|
37271
36501
|
* `!== false` default then read as "apply the mutation" instead of rejecting
|
|
37272
36502
|
* the request.
|
|
37273
36503
|
*/
|
|
37274
|
-
const readJsonBody$
|
|
36504
|
+
const readJsonBody$19 = Effect.gen(function* () {
|
|
37275
36505
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
37276
36506
|
if (!text) return {};
|
|
37277
36507
|
try {
|
|
@@ -37329,14 +36559,14 @@ const getWorkspaceRegistryProjectTargetsRoute = HttpRouter.add("GET", "/api/work
|
|
|
37329
36559
|
const postWorkspaceRegistryResolveRoute = HttpRouter.add("POST", "/api/workspace-registry/resolve", httpHandler(Effect.gen(function* () {
|
|
37330
36560
|
const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
|
|
37331
36561
|
if (authError) return authError;
|
|
37332
|
-
const body = yield* readJsonBody$
|
|
36562
|
+
const body = yield* readJsonBody$19;
|
|
37333
36563
|
if (body === void 0) return jsonResponse({ error: "Malformed JSON body" }, { status: 400 });
|
|
37334
36564
|
return jsonResponse(yield* Effect.promise(() => resolveWorkspaceCreateIntent(toCreateInput(body))));
|
|
37335
36565
|
})));
|
|
37336
36566
|
const postWorkspaceRegistryCreateRoute = HttpRouter.add("POST", "/api/workspace-registry", httpHandler(Effect.gen(function* () {
|
|
37337
36567
|
const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
|
|
37338
36568
|
if (authError) return authError;
|
|
37339
|
-
const body = yield* readJsonBody$
|
|
36569
|
+
const body = yield* readJsonBody$19;
|
|
37340
36570
|
if (body === void 0) return jsonResponse({ error: "Malformed JSON body" }, { status: 400 });
|
|
37341
36571
|
const intent = yield* Effect.promise(() => resolveWorkspaceCreateIntent({
|
|
37342
36572
|
...toCreateInput(body),
|
|
@@ -37358,7 +36588,7 @@ const postWorkspaceRegistryRelocateRoute = HttpRouter.add("POST", "/api/workspac
|
|
|
37358
36588
|
if (authError) return authError;
|
|
37359
36589
|
const id = (yield* HttpRouter.params)["id"] ?? "";
|
|
37360
36590
|
if (!getWorkspaceById(id)) return jsonResponse({ error: `Workspace not found: ${id}` }, { status: 404 });
|
|
37361
|
-
const body = yield* readJsonBody$
|
|
36591
|
+
const body = yield* readJsonBody$19;
|
|
37362
36592
|
if (body === void 0) return jsonResponse({ error: "Malformed JSON body" }, { status: 400 });
|
|
37363
36593
|
if (typeof body.path !== "string" || !body.path) return jsonResponse({ error: "path is required" }, { status: 400 });
|
|
37364
36594
|
const failure = yield* Effect.promise(() => relocateWorkspace(id, body.path, { force: body.force === true }).then(() => null).catch((err) => err instanceof Error ? err.message : String(err)));
|
|
@@ -37547,7 +36777,7 @@ const putWorkspaceRegistryRunCommandRoute = HttpRouter.add("PUT", "/api/workspac
|
|
|
37547
36777
|
const id = (yield* HttpRouter.params)["id"] ?? "";
|
|
37548
36778
|
const workspace = getWorkspaceById(id);
|
|
37549
36779
|
if (!workspace) return jsonResponse({ error: `Workspace not found: ${id}` }, { status: 404 });
|
|
37550
|
-
const body = yield* readJsonBody$
|
|
36780
|
+
const body = yield* readJsonBody$19;
|
|
37551
36781
|
if (body === void 0) return jsonResponse({ error: "Malformed JSON body" }, { status: 400 });
|
|
37552
36782
|
if (body.command !== null && typeof body.command !== "string") return jsonResponse({ error: "command must be a string or null" }, { status: 400 });
|
|
37553
36783
|
const trimmed = typeof body.command === "string" ? body.command.trim() : null;
|
|
@@ -37600,7 +36830,7 @@ const postWorkspaceRegistryOpenRoute = HttpRouter.add("POST", "/api/workspace-re
|
|
|
37600
36830
|
const id = (yield* HttpRouter.params)["id"] ?? "";
|
|
37601
36831
|
const workspace = getWorkspaceById(id);
|
|
37602
36832
|
if (!workspace) return jsonResponse({ error: `Workspace not found: ${id}` }, { status: 404 });
|
|
37603
|
-
const body = yield* readJsonBody$
|
|
36833
|
+
const body = yield* readJsonBody$19;
|
|
37604
36834
|
if (body === void 0) return jsonResponse({ error: "Malformed JSON body" }, { status: 400 });
|
|
37605
36835
|
const target = body.target;
|
|
37606
36836
|
if (target !== "file-manager" && target !== "editor") return jsonResponse({ error: "target must be 'file-manager' or 'editor'" }, { status: 400 });
|
|
@@ -37636,7 +36866,7 @@ const postWorkspaceRegistryArchiveRoute = HttpRouter.add("POST", "/api/workspace
|
|
|
37636
36866
|
const id = (yield* HttpRouter.params)["id"] ?? "";
|
|
37637
36867
|
const workspace = getWorkspaceById(id);
|
|
37638
36868
|
if (!workspace) return jsonResponse({ error: `Workspace not found: ${id}` }, { status: 404 });
|
|
37639
|
-
const body = yield* readJsonBody$
|
|
36869
|
+
const body = yield* readJsonBody$19;
|
|
37640
36870
|
if (body === void 0) return jsonResponse({ error: "Malformed JSON body" }, { status: 400 });
|
|
37641
36871
|
if (body.archived === false) unarchiveWorkspace(id);
|
|
37642
36872
|
else yield* Effect.promise(() => archiveWorkspace(id));
|
|
@@ -37648,7 +36878,7 @@ const postWorkspaceRegistryFavoriteRoute = HttpRouter.add("POST", "/api/workspac
|
|
|
37648
36878
|
const id = (yield* HttpRouter.params)["id"] ?? "";
|
|
37649
36879
|
const workspace = getWorkspaceById(id);
|
|
37650
36880
|
if (!workspace) return jsonResponse({ error: `Workspace not found: ${id}` }, { status: 404 });
|
|
37651
|
-
const body = yield* readJsonBody$
|
|
36881
|
+
const body = yield* readJsonBody$19;
|
|
37652
36882
|
if (body === void 0) return jsonResponse({ error: "Malformed JSON body" }, { status: 400 });
|
|
37653
36883
|
setWorkspaceFavorite(id, body.favorite !== false);
|
|
37654
36884
|
return jsonResponse(toListRow(getWorkspaceById(id) ?? workspace));
|
|
@@ -37659,7 +36889,7 @@ const putWorkspaceRegistryLayoutRoute = HttpRouter.add("PUT", "/api/workspace-re
|
|
|
37659
36889
|
const id = (yield* HttpRouter.params)["id"] ?? "";
|
|
37660
36890
|
const workspace = getWorkspaceById(id);
|
|
37661
36891
|
if (!workspace) return jsonResponse({ error: `Workspace not found: ${id}` }, { status: 404 });
|
|
37662
|
-
const body = yield* readJsonBody$
|
|
36892
|
+
const body = yield* readJsonBody$19;
|
|
37663
36893
|
if (body === void 0) return jsonResponse({ error: "Malformed JSON body" }, { status: 400 });
|
|
37664
36894
|
if (body.layout === void 0) return jsonResponse({ error: "layout is required" }, { status: 400 });
|
|
37665
36895
|
updateWorkspaceLayout(id, JSON.stringify(body.layout));
|
|
@@ -38202,7 +37432,7 @@ function reloadDurableCloisterConfig(deps = {}) {
|
|
|
38202
37432
|
*/
|
|
38203
37433
|
init_config$1();
|
|
38204
37434
|
init_agents$1();
|
|
38205
|
-
const readJsonBody$
|
|
37435
|
+
const readJsonBody$18 = Effect.gen(function* () {
|
|
38206
37436
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
38207
37437
|
try {
|
|
38208
37438
|
return text ? JSON.parse(text) : {};
|
|
@@ -38305,7 +37535,7 @@ const getCloisterConfigRoute = HttpRouter.add("GET", "/api/cloister/config", htt
|
|
|
38305
37535
|
catch: (err) => new Error(err instanceof Error ? err.message : String(err))
|
|
38306
37536
|
})));
|
|
38307
37537
|
const putCloisterConfigRoute = HttpRouter.add("PUT", "/api/cloister/config", httpHandler(Effect.gen(function* () {
|
|
38308
|
-
const updates = yield* readJsonBody$
|
|
37538
|
+
const updates = yield* readJsonBody$18;
|
|
38309
37539
|
yield* Effect.try({
|
|
38310
37540
|
try: () => {
|
|
38311
37541
|
saveCloisterConfigSync(updates);
|
|
@@ -39669,7 +38899,7 @@ const getStackTeardownEstimateRoute = HttpRouter.add("GET", "/api/resources/stac
|
|
|
39669
38899
|
})));
|
|
39670
38900
|
const postStackTeardownRoute = HttpRouter.add("POST", "/api/resources/stacks/:issueId/teardown", httpHandler(Effect.gen(function* () {
|
|
39671
38901
|
const params = yield* HttpRouter.params;
|
|
39672
|
-
const body = yield* readJsonBody$
|
|
38902
|
+
const body = yield* readJsonBody$17;
|
|
39673
38903
|
return yield* postStackTeardownEffect(params["issueId"] ?? "", body);
|
|
39674
38904
|
})));
|
|
39675
38905
|
function getStackTeardownEstimateEffect(issue) {
|
|
@@ -39843,7 +39073,7 @@ function lines(value) {
|
|
|
39843
39073
|
function isDockerIdentifier(value) {
|
|
39844
39074
|
return /^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,127}$/.test(value);
|
|
39845
39075
|
}
|
|
39846
|
-
const readJsonBody$
|
|
39076
|
+
const readJsonBody$17 = Effect.gen(function* () {
|
|
39847
39077
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
39848
39078
|
try {
|
|
39849
39079
|
return text ? JSON.parse(text) : {};
|
|
@@ -41101,6 +40331,7 @@ function normalizeAgentStatus(status) {
|
|
|
41101
40331
|
*/
|
|
41102
40332
|
init_agents$1();
|
|
41103
40333
|
init_specialists();
|
|
40334
|
+
init_jsonl_resolver();
|
|
41104
40335
|
init_tmux();
|
|
41105
40336
|
const CONVOY_REVIEWER_ROLES = [
|
|
41106
40337
|
"correctness",
|
|
@@ -41253,12 +40484,14 @@ async function buildReviewerNodes(opts) {
|
|
|
41253
40484
|
if (!isExtendedReviewEnabled(opts.issueId)) return [];
|
|
41254
40485
|
const agentsRoot = opts.agentsDirOverride ?? join(homedir$1(), ".overdeck", "agents");
|
|
41255
40486
|
const latestReviewRunDir = await findLatestReviewRunDir(opts.workspacePath, opts.issueId);
|
|
41256
|
-
return await Promise.all(CONVOY_REVIEWER_ROLES.map(async (role) => {
|
|
40487
|
+
return (await Promise.all(CONVOY_REVIEWER_ROLES.map(async (role) => {
|
|
41257
40488
|
const sessionId = getReviewerSessionName(role, opts.projectKey, opts.issueId);
|
|
41258
40489
|
const isLive = opts.tmuxSessionNames.has(sessionId);
|
|
41259
40490
|
const roundMetadata = await readReviewerRounds(sessionId, agentsRoot);
|
|
40491
|
+
const hasStateRow = existsSync$1(join(agentsRoot, sessionId, "state.json"));
|
|
41260
40492
|
const jsonlPath = await resolveJsonlPath(sessionId, opts.workspacePath ?? opts.projectPath, { agentsDirOverride: opts.agentsDirOverride });
|
|
41261
40493
|
const latestRunOutputExists = latestReviewRunDir ? existsSync$1(join(latestReviewRunDir, `${role}.md`)) : false;
|
|
40494
|
+
if (!(isLive || hasStateRow || roundMetadata !== void 0 || jsonlPath !== null || latestRunOutputExists)) return null;
|
|
41262
40495
|
const inProgressThisRound = isLive && latestReviewRunDir !== null && !latestRunOutputExists;
|
|
41263
40496
|
const isWarmIdle = isLive && existsSync$1(join(agentsRoot, sessionId, "reviewer-signaled"));
|
|
41264
40497
|
const latestRoundDone = roundMetadata?.latestStatus === "completed" || roundMetadata?.latestStatus === "failed";
|
|
@@ -41296,7 +40529,7 @@ async function buildReviewerNodes(opts) {
|
|
|
41296
40529
|
};
|
|
41297
40530
|
if (roundMetadata) node.roundMetadata = roundMetadata;
|
|
41298
40531
|
return node;
|
|
41299
|
-
}));
|
|
40532
|
+
}))).filter((node) => node !== null);
|
|
41300
40533
|
}
|
|
41301
40534
|
//#endregion
|
|
41302
40535
|
//#region routes/command-deck.ts
|
|
@@ -41320,6 +40553,7 @@ init_issue_id();
|
|
|
41320
40553
|
init_tracker_config();
|
|
41321
40554
|
init_config_yaml();
|
|
41322
40555
|
init_issue_service_singleton();
|
|
40556
|
+
init_jsonl_resolver();
|
|
41323
40557
|
init_types();
|
|
41324
40558
|
init_io();
|
|
41325
40559
|
const execAsync$5 = promisify(exec);
|
|
@@ -41376,7 +40610,7 @@ function getProjectPath$1(issuePrefix) {
|
|
|
41376
40610
|
}
|
|
41377
40611
|
return setProjectPathCache(issuePrefix, join(homedir$1(), "Projects"));
|
|
41378
40612
|
}
|
|
41379
|
-
const readJsonBody$
|
|
40613
|
+
const readJsonBody$16 = Effect.gen(function* () {
|
|
41380
40614
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
41381
40615
|
try {
|
|
41382
40616
|
return text ? JSON.parse(text) : {};
|
|
@@ -42070,7 +41304,7 @@ Be specific: reference actual file names, function names, requirement text, disc
|
|
|
42070
41304
|
const { command: cliCmd, args: cliArgs } = getAgentCommandSync(statusModelId);
|
|
42071
41305
|
const modelFlag = cliArgs.length > 0 ? ` ${cliArgs.join(" ")}` : "";
|
|
42072
41306
|
const promptFile = join(planningDir, ".status-review-prompt.tmp");
|
|
42073
|
-
const { getProviderForModelSync, getProviderEnvSync } = await import("./providers-
|
|
41307
|
+
const { getProviderForModelSync, getProviderEnvSync } = await import("./providers-Dqgz3MY5.js");
|
|
42074
41308
|
let providerEnvStr = "";
|
|
42075
41309
|
let providerEnv = {};
|
|
42076
41310
|
const statusProvider = getProviderForModelSync(statusModelId);
|
|
@@ -42145,7 +41379,7 @@ ${issueContext ? `## Issue Tracker Data\n${issueContext}\n` : ""}---
|
|
|
42145
41379
|
}
|
|
42146
41380
|
const postMissionControlUploadRoute = HttpRouter.add("POST", "/api/command-deck/planning/:issueId/upload", httpHandler(Effect.gen(function* () {
|
|
42147
41381
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
42148
|
-
const { type, filename, content } = yield* readJsonBody$
|
|
41382
|
+
const { type, filename, content } = yield* readJsonBody$16;
|
|
42149
41383
|
const issueLower = issueId.toLowerCase();
|
|
42150
41384
|
const issuePrefix = extractPrefixSync(issueId) ?? issueId.split("-")[0];
|
|
42151
41385
|
if (!type || !filename || !content) return jsonResponse({ error: "type, filename, and content are required" }, { status: 400 });
|
|
@@ -42153,7 +41387,7 @@ const postMissionControlUploadRoute = HttpRouter.add("POST", "/api/command-deck/
|
|
|
42153
41387
|
let safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
42154
41388
|
let processedContent = content;
|
|
42155
41389
|
if (safeName.endsWith(".vtt")) {
|
|
42156
|
-
const { vttToMarkdown } = yield* Effect.promise(() => import("./vtt-parser-
|
|
41390
|
+
const { vttToMarkdown } = yield* Effect.promise(() => import("./vtt-parser-BSnAB-Og.js"));
|
|
42157
41391
|
processedContent = vttToMarkdown(content);
|
|
42158
41392
|
safeName = safeName.replace(/\.vtt$/, ".md");
|
|
42159
41393
|
}
|
|
@@ -42174,7 +41408,7 @@ const postMissionControlUploadRoute = HttpRouter.add("POST", "/api/command-deck/
|
|
|
42174
41408
|
const postMissionControlSyncDiscussionsRoute = HttpRouter.add("POST", "/api/command-deck/planning/:issueId/sync-discussions", httpHandler(Effect.gen(function* () {
|
|
42175
41409
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
42176
41410
|
if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue id: " + issueId }, { status: 400 });
|
|
42177
|
-
const body = yield* readJsonBody$
|
|
41411
|
+
const body = yield* readJsonBody$16;
|
|
42178
41412
|
const linear = yield* LinearClient;
|
|
42179
41413
|
const { tracker } = body;
|
|
42180
41414
|
const issueLower = issueId.toLowerCase();
|
|
@@ -42320,7 +41554,7 @@ const postMissionControlSyncDiscussionsRoute = HttpRouter.add("POST", "/api/comm
|
|
|
42320
41554
|
})));
|
|
42321
41555
|
const postMissionControlPlanningInitRoute = HttpRouter.add("POST", "/api/command-deck/planning/:issueId/init", httpHandler(Effect.gen(function* () {
|
|
42322
41556
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
42323
|
-
const body = yield* readJsonBody$
|
|
41557
|
+
const body = yield* readJsonBody$16;
|
|
42324
41558
|
const eventStore = yield* EventStoreService;
|
|
42325
41559
|
const { shadow } = body;
|
|
42326
41560
|
const issueLower = issueId.toLowerCase();
|
|
@@ -42404,7 +41638,7 @@ async function listRemoteWorkspaceMetadata() {
|
|
|
42404
41638
|
}
|
|
42405
41639
|
return workspaces;
|
|
42406
41640
|
}
|
|
42407
|
-
const readJsonBody$
|
|
41641
|
+
const readJsonBody$15 = Effect.gen(function* () {
|
|
42408
41642
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
42409
41643
|
try {
|
|
42410
41644
|
return text ? JSON.parse(text) : {};
|
|
@@ -42519,7 +41753,7 @@ const stopRemoteWorkspaceRoute = HttpRouter.add("POST", "/api/remote/workspaces/
|
|
|
42519
41753
|
})));
|
|
42520
41754
|
const startRemoteAgentRoute = HttpRouter.add("POST", "/api/remote/workspaces/:issueId/agent/start", httpHandler(Effect.gen(function* () {
|
|
42521
41755
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
42522
|
-
const body = yield* readJsonBody$
|
|
41756
|
+
const body = yield* readJsonBody$15;
|
|
42523
41757
|
const eventStore = yield* EventStoreService;
|
|
42524
41758
|
const { prompt, model } = body;
|
|
42525
41759
|
const metadata = yield* Effect.promise(() => loadRemoteWorkspaceMetadata(issueId));
|
|
@@ -42584,7 +41818,7 @@ const getRemoteAgentOutputRoute = HttpRouter.add("GET", "/api/remote/workspaces/
|
|
|
42584
41818
|
})));
|
|
42585
41819
|
const tellRemoteAgentRoute = HttpRouter.add("POST", "/api/remote/workspaces/:issueId/agent/tell", httpHandler(Effect.gen(function* () {
|
|
42586
41820
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
42587
|
-
const { message } = yield* readJsonBody$
|
|
41821
|
+
const { message } = yield* readJsonBody$15;
|
|
42588
41822
|
if (!message) return jsonResponse({ error: "Message is required" }, { status: 400 });
|
|
42589
41823
|
const metadata = yield* Effect.promise(() => loadRemoteWorkspaceMetadata(issueId));
|
|
42590
41824
|
if (!metadata) return jsonResponse({ error: "Remote workspace not found" }, { status: 404 });
|
|
@@ -45274,7 +44508,7 @@ function consumeReindexConfirmationNonce(nonce, estimatedUsd) {
|
|
|
45274
44508
|
reindexConfirmationNonces.delete(nonce);
|
|
45275
44509
|
return !!entry && entry.expiresAt > Date.now() && Math.abs(entry.estimatedUsd - estimatedUsd) < 1e-6;
|
|
45276
44510
|
}
|
|
45277
|
-
const readJsonBody$
|
|
44511
|
+
const readJsonBody$14 = Effect.gen(function* () {
|
|
45278
44512
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
45279
44513
|
try {
|
|
45280
44514
|
return text ? JSON.parse(text) : {};
|
|
@@ -45351,7 +44585,7 @@ const getOpenAIAuthRoute = HttpRouter.add("GET", "/api/settings/openai-auth", ht
|
|
|
45351
44585
|
return jsonResponse(yield* getOpenAIAuthStatus());
|
|
45352
44586
|
})));
|
|
45353
44587
|
const postTestApiKeyRoute = HttpRouter.add("POST", "/api/settings/test-api-key", httpHandler(Effect.gen(function* () {
|
|
45354
|
-
const { provider, apiKey, model } = yield* readJsonBody$
|
|
44588
|
+
const { provider, apiKey, model } = yield* readJsonBody$14;
|
|
45355
44589
|
if (!provider || !apiKey) return jsonResponse({ error: "Provider and apiKey are required" }, { status: 400 });
|
|
45356
44590
|
return yield* Effect.promise(async () => {
|
|
45357
44591
|
let success = false;
|
|
@@ -45661,7 +44895,7 @@ const postTestApiKeyRoute = HttpRouter.add("POST", "/api/settings/test-api-key",
|
|
|
45661
44895
|
});
|
|
45662
44896
|
})));
|
|
45663
44897
|
const postValidateApiKeyRoute = HttpRouter.add("POST", "/api/settings/validate-api-key", httpHandler(Effect.gen(function* () {
|
|
45664
|
-
const { provider, apiKey } = yield* readJsonBody$
|
|
44898
|
+
const { provider, apiKey } = yield* readJsonBody$14;
|
|
45665
44899
|
if (!provider || !apiKey) return jsonResponse({ error: "Provider and apiKey are required" }, { status: 400 });
|
|
45666
44900
|
if (![
|
|
45667
44901
|
"openai",
|
|
@@ -45897,7 +45131,7 @@ const getConversationSearchReindexEstimateRoute = HttpRouter.add("GET", "/api/se
|
|
|
45897
45131
|
const postConversationSearchReindexRoute = HttpRouter.add("POST", "/api/settings/conversation-search/reindex", httpHandler(Effect.gen(function* () {
|
|
45898
45132
|
const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
|
|
45899
45133
|
if (authError) return authError;
|
|
45900
|
-
const body = yield* readJsonBody$
|
|
45134
|
+
const body = yield* readJsonBody$14;
|
|
45901
45135
|
return yield* Effect.promise(async () => {
|
|
45902
45136
|
if (activeConversationSearchReindex) return jsonResponse({ error: "Conversation search reindex already in progress" }, { status: 409 });
|
|
45903
45137
|
const job = (async () => {
|
|
@@ -45947,7 +45181,7 @@ const getConversationSearchReindexProgressRoute = HttpRouter.add("GET", "/api/se
|
|
|
45947
45181
|
return jsonResponse(conversationReindexProgress);
|
|
45948
45182
|
})));
|
|
45949
45183
|
const putSettingsRoute = HttpRouter.add("PUT", "/api/settings", httpHandler(Effect.gen(function* () {
|
|
45950
|
-
const body = yield* readJsonBody$
|
|
45184
|
+
const body = yield* readJsonBody$14;
|
|
45951
45185
|
return yield* Effect.promise(async () => {
|
|
45952
45186
|
try {
|
|
45953
45187
|
const newSettings = body;
|
|
@@ -45968,7 +45202,7 @@ const putSettingsRoute = HttpRouter.add("PUT", "/api/settings", httpHandler(Effe
|
|
|
45968
45202
|
});
|
|
45969
45203
|
})));
|
|
45970
45204
|
const putUiThemeRoute = HttpRouter.add("PUT", "/api/settings/ui-theme", httpHandler(Effect.gen(function* () {
|
|
45971
|
-
const body = yield* readJsonBody$
|
|
45205
|
+
const body = yield* readJsonBody$14;
|
|
45972
45206
|
return yield* Effect.promise(async () => {
|
|
45973
45207
|
const theme = body?.theme;
|
|
45974
45208
|
if (theme !== "light" && theme !== "dark") return jsonResponse({ error: "theme must be 'light' or 'dark'" }, { status: 400 });
|
|
@@ -45979,7 +45213,7 @@ const putUiThemeRoute = HttpRouter.add("PUT", "/api/settings/ui-theme", httpHand
|
|
|
45979
45213
|
const putDesignLanguageRoute = HttpRouter.add("PUT", "/api/settings/design-language", httpHandler(Effect.gen(function* () {
|
|
45980
45214
|
const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
|
|
45981
45215
|
if (authError) return authError;
|
|
45982
|
-
const body = yield* readJsonBody$
|
|
45216
|
+
const body = yield* readJsonBody$14;
|
|
45983
45217
|
return yield* Effect.promise(async () => {
|
|
45984
45218
|
const theme = body?.theme;
|
|
45985
45219
|
if (theme !== "ledger" && theme !== "broadsheet") return jsonResponse({ error: "theme must be 'ledger' or 'broadsheet'" }, { status: 400 });
|
|
@@ -45994,7 +45228,7 @@ const getOpenRouterModelsRoute = HttpRouter.add("GET", "/api/settings/openrouter
|
|
|
45994
45228
|
});
|
|
45995
45229
|
})));
|
|
45996
45230
|
const putOpenRouterFavoritesRoute = HttpRouter.add("PUT", "/api/settings/openrouter/favorites", httpHandler(Effect.gen(function* () {
|
|
45997
|
-
const { favorites } = yield* readJsonBody$
|
|
45231
|
+
const { favorites } = yield* readJsonBody$14;
|
|
45998
45232
|
if (!Array.isArray(favorites)) return jsonResponse({ error: "favorites must be an array of model IDs" }, { status: 400 });
|
|
45999
45233
|
const modelIds = favorites.filter((f) => typeof f === "string");
|
|
46000
45234
|
return yield* Effect.promise(async () => {
|
|
@@ -46010,7 +45244,7 @@ const putOpenRouterFavoritesRoute = HttpRouter.add("PUT", "/api/settings/openrou
|
|
|
46010
45244
|
});
|
|
46011
45245
|
})));
|
|
46012
45246
|
const putOpenRouterApiKeyRoute = HttpRouter.add("PUT", "/api/settings/openrouter/api-key", httpHandler(Effect.gen(function* () {
|
|
46013
|
-
const { apiKey } = yield* readJsonBody$
|
|
45247
|
+
const { apiKey } = yield* readJsonBody$14;
|
|
46014
45248
|
if (apiKey !== void 0 && typeof apiKey !== "string") return jsonResponse({ error: "apiKey must be a string when provided" }, { status: 400 });
|
|
46015
45249
|
return yield* Effect.promise(async () => {
|
|
46016
45250
|
try {
|
|
@@ -46025,7 +45259,7 @@ const putOpenRouterApiKeyRoute = HttpRouter.add("PUT", "/api/settings/openrouter
|
|
|
46025
45259
|
});
|
|
46026
45260
|
})));
|
|
46027
45261
|
const postOpenRouterTestKeyRoute = HttpRouter.add("POST", "/api/settings/openrouter/test-key", httpHandler(Effect.gen(function* () {
|
|
46028
|
-
const { apiKey } = yield* readJsonBody$
|
|
45262
|
+
const { apiKey } = yield* readJsonBody$14;
|
|
46029
45263
|
if (!apiKey) return jsonResponse({ error: "apiKey is required" }, { status: 400 });
|
|
46030
45264
|
return jsonResponse(yield* (yield* OpenRouterService).validateApiKey(apiKey));
|
|
46031
45265
|
})));
|
|
@@ -46076,7 +45310,7 @@ const getLegacyImportPreviewRoute = HttpRouter.add("GET", "/api/settings/legacy-
|
|
|
46076
45310
|
const postLegacyImportRoute = HttpRouter.add("POST", "/api/settings/legacy-import/conversations", httpHandler(Effect.gen(function* () {
|
|
46077
45311
|
const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
|
|
46078
45312
|
if (authError) return authError;
|
|
46079
|
-
const body = yield* readJsonBody$
|
|
45313
|
+
const body = yield* readJsonBody$14;
|
|
46080
45314
|
return yield* Effect.try({
|
|
46081
45315
|
try: () => {
|
|
46082
45316
|
const { path, names } = body;
|
|
@@ -46088,7 +45322,7 @@ const postLegacyImportRoute = HttpRouter.add("POST", "/api/settings/legacy-impor
|
|
|
46088
45322
|
const settingsRouteLayer = Layer.mergeAll(getSettingsRoute, getAvailableModelsRoute, getOptimalDefaultsRoute, getMiniMaxDefaultsRoute, getClaudeAuthRoute, getOpenAIAuthRoute, postTestApiKeyRoute, postValidateApiKeyRoute, getConversationSearchStatusRoute, getConversationSearchReindexEstimateRoute, postConversationSearchReindexRoute, getConversationSearchReindexProgressRoute, putSettingsRoute, putUiThemeRoute, putDesignLanguageRoute, getOpenRouterModelsRoute, putOpenRouterFavoritesRoute, putOpenRouterApiKeyRoute, postOpenRouterTestKeyRoute, getHarnessPolicyRoute, getProviderEnvConflictsRoute, getLegacyImportPreviewRoute, postLegacyImportRoute);
|
|
46089
45323
|
//#endregion
|
|
46090
45324
|
//#region routes/autopreso.ts
|
|
46091
|
-
const readJsonBody$
|
|
45325
|
+
const readJsonBody$13 = Effect.gen(function* () {
|
|
46092
45326
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
46093
45327
|
const contentLength = Number(request.headers["content-length"] ?? 0);
|
|
46094
45328
|
if (Number.isFinite(contentLength) && contentLength > 256e3) return {
|
|
@@ -46119,7 +45353,7 @@ function requireTrustedOrigin$1(request) {
|
|
|
46119
45353
|
const startRoute = HttpRouter.add("POST", "/api/autopreso/start", httpHandler(Effect.gen(function* () {
|
|
46120
45354
|
const originError = requireTrustedOrigin$1(yield* HttpServerRequest.HttpServerRequest);
|
|
46121
45355
|
if (originError) return originError;
|
|
46122
|
-
const parsed = yield* readJsonBody$
|
|
45356
|
+
const parsed = yield* readJsonBody$13;
|
|
46123
45357
|
if (!parsed.ok) return jsonResponse({ error: parsed.error }, { status: 413 });
|
|
46124
45358
|
const elements = readElementLikes(parsed.body);
|
|
46125
45359
|
const validation = validateAutoPresoCanvasElements(elements);
|
|
@@ -46317,7 +45551,7 @@ const metricsRouteLayer = Layer.mergeAll(getMetricsSummaryRoute, getMetricsCosts
|
|
|
46317
45551
|
//#region routes/boot-reconciliation.ts
|
|
46318
45552
|
init_tmux();
|
|
46319
45553
|
init_control_settings();
|
|
46320
|
-
const readJsonBody$
|
|
45554
|
+
const readJsonBody$12 = Effect.gen(function* () {
|
|
46321
45555
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
46322
45556
|
try {
|
|
46323
45557
|
return text ? JSON.parse(text) : {};
|
|
@@ -46392,7 +45626,7 @@ function parsePerAgentMap(value) {
|
|
|
46392
45626
|
return parsed;
|
|
46393
45627
|
}
|
|
46394
45628
|
const postBootReconciliationDecisionRoute = HttpRouter.add("POST", "/api/boot-reconciliation/decision", httpHandler(Effect.gen(function* () {
|
|
46395
|
-
const body = yield* readJsonBody$
|
|
45629
|
+
const body = yield* readJsonBody$12;
|
|
46396
45630
|
if (!isBootReconciliationDecision(body.decision)) return jsonResponse({
|
|
46397
45631
|
ok: false,
|
|
46398
45632
|
error: "Body must include decision resume_all, hold_all, or per_agent"
|
|
@@ -46489,7 +45723,7 @@ function getGitHubLocalPaths() {
|
|
|
46489
45723
|
}
|
|
46490
45724
|
return out;
|
|
46491
45725
|
}
|
|
46492
|
-
const readJsonBody$
|
|
45726
|
+
const readJsonBody$11 = Effect.gen(function* () {
|
|
46493
45727
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
46494
45728
|
try {
|
|
46495
45729
|
return text ? JSON.parse(text) : {};
|
|
@@ -46501,7 +45735,7 @@ const readJsonBody$10 = Effect.gen(function* () {
|
|
|
46501
45735
|
//#region routes/misc/project-mappings.ts
|
|
46502
45736
|
const getProjectMappingsRoute = HttpRouter.add("GET", "/api/project-mappings", httpHandler(Effect.promise(() => getProjectMappings().then((m) => jsonResponse(m)))));
|
|
46503
45737
|
const putProjectMappingsRoute = HttpRouter.add("PUT", "/api/project-mappings", Effect.gen(function* () {
|
|
46504
|
-
const mappings = yield* readJsonBody$
|
|
45738
|
+
const mappings = yield* readJsonBody$11;
|
|
46505
45739
|
if (!Array.isArray(mappings)) return jsonResponse({ error: "Expected array of mappings" }, { status: 400 });
|
|
46506
45740
|
yield* Effect.promise(() => saveProjectMappings(mappings));
|
|
46507
45741
|
return jsonResponse({
|
|
@@ -46510,7 +45744,7 @@ const putProjectMappingsRoute = HttpRouter.add("PUT", "/api/project-mappings", E
|
|
|
46510
45744
|
});
|
|
46511
45745
|
}));
|
|
46512
45746
|
const postProjectMappingsRoute = HttpRouter.add("POST", "/api/project-mappings", Effect.gen(function* () {
|
|
46513
|
-
const { linearProjectId, linearProjectName, linearPrefix, localPath } = yield* readJsonBody$
|
|
45747
|
+
const { linearProjectId, linearProjectName, linearPrefix, localPath } = yield* readJsonBody$11;
|
|
46514
45748
|
if (!linearProjectId || !localPath) return jsonResponse({ error: "linearProjectId and localPath required" }, { status: 400 });
|
|
46515
45749
|
return yield* Effect.promise(async () => {
|
|
46516
45750
|
try {
|
|
@@ -46617,14 +45851,14 @@ const getTrackerStatusRoute = HttpRouter.add("GET", "/api/tracker-status", Effec
|
|
|
46617
45851
|
}
|
|
46618
45852
|
}));
|
|
46619
45853
|
const postRallyValidateRoute = HttpRouter.add("POST", "/api/rally/validate", Effect.gen(function* () {
|
|
46620
|
-
const { apiKey, server, workspace, project } = yield* readJsonBody$
|
|
45854
|
+
const { apiKey, server, workspace, project } = yield* readJsonBody$11;
|
|
46621
45855
|
if (!apiKey) return jsonResponse({
|
|
46622
45856
|
valid: false,
|
|
46623
45857
|
error: "API key is required"
|
|
46624
45858
|
}, { status: 400 });
|
|
46625
45859
|
return yield* Effect.promise(async () => {
|
|
46626
45860
|
try {
|
|
46627
|
-
const { RallyRestApi } = await import("./rally-api-
|
|
45861
|
+
const { RallyRestApi } = await import("./rally-api-Ij1Zt0NI.js");
|
|
46628
45862
|
const api = new RallyRestApi({
|
|
46629
45863
|
apiKey,
|
|
46630
45864
|
server: server || "https://rally1.rallydev.com"
|
|
@@ -46965,7 +46199,7 @@ const getDeaconPauseRoute = HttpRouter.add("GET", "/api/deacon/pause", Effect.tr
|
|
|
46965
46199
|
* Persists to `app_settings` so the flag survives dashboard restarts.
|
|
46966
46200
|
*/
|
|
46967
46201
|
const postDeaconPauseRoute = HttpRouter.add("POST", "/api/deacon/pause", httpHandler(Effect.gen(function* () {
|
|
46968
|
-
const body = yield* readJsonBody$
|
|
46202
|
+
const body = yield* readJsonBody$11;
|
|
46969
46203
|
if (typeof body.paused !== "boolean") return jsonResponse({ error: "Body must include { paused: boolean }" }, { status: 400 });
|
|
46970
46204
|
setDeaconGloballyPausedSync(body.paused);
|
|
46971
46205
|
console.log(`[deacon] Global pause flag set to ${body.paused}`);
|
|
@@ -47008,7 +46242,7 @@ const getPlanningStatusRoute = HttpRouter.add("GET", "/api/planning/:issueId/sta
|
|
|
47008
46242
|
const remoteState = loadRemoteAgentState(sessionName);
|
|
47009
46243
|
const isRemote = !!remoteState;
|
|
47010
46244
|
const vmName = remoteState?.vmName ?? "";
|
|
47011
|
-
const { getAgentStateSync } = await import("./agents-
|
|
46245
|
+
const { getAgentStateSync } = await import("./agents-DpCuoF65.js");
|
|
47012
46246
|
const agentStarting = getAgentStateSync(sessionName)?.status === "starting";
|
|
47013
46247
|
let tmuxSessionAlive = false;
|
|
47014
46248
|
if (!isRemote) try {
|
|
@@ -47060,7 +46294,7 @@ const postPlanningMessageRoute = HttpRouter.add("POST", "/api/planning/:issueId/
|
|
|
47060
46294
|
const issueId = new URL(request.url, "http://localhost").pathname.split("/")[3] || "";
|
|
47061
46295
|
const sessionName = `planning-${issueId.toLowerCase()}`;
|
|
47062
46296
|
const issueLower = issueId.toLowerCase();
|
|
47063
|
-
const { message } = yield* readJsonBody$
|
|
46297
|
+
const { message } = yield* readJsonBody$11;
|
|
47064
46298
|
const eventStore = yield* EventStoreService;
|
|
47065
46299
|
if (!message) return jsonResponse({ error: "Message required" }, { status: 400 });
|
|
47066
46300
|
return yield* Effect.promise(async () => {
|
|
@@ -47152,7 +46386,7 @@ Continue the PLANNING session. Do NOT implement anything.
|
|
|
47152
46386
|
const agentCwd = workspacePath;
|
|
47153
46387
|
const harnessLaunch = await prepareHarnessLaunch("claude-code");
|
|
47154
46388
|
if (existsSync$1(outputFile)) await rename(outputFile, join(planningDir, `output-${Date.now()}.jsonl`));
|
|
47155
|
-
const { getAgentCommandSync } = await import("./settings-
|
|
46389
|
+
const { getAgentCommandSync } = await import("./settings-DhtPDmmI.js");
|
|
47156
46390
|
let msgPlanningModel = "claude-sonnet-5";
|
|
47157
46391
|
try {
|
|
47158
46392
|
msgPlanningModel = resolveModel("plan", void 0, loadConfigSync().config);
|
|
@@ -47275,7 +46509,7 @@ async function getIndexStats(rootPath, isMain) {
|
|
|
47275
46509
|
}
|
|
47276
46510
|
const getTldrStatusRoute = HttpRouter.add("GET", "/api/services/tldr/status", Effect.promise(async () => {
|
|
47277
46511
|
try {
|
|
47278
|
-
const { getTldrDaemonServiceSync } = await import("./tldr-daemon-
|
|
46512
|
+
const { getTldrDaemonServiceSync } = await import("./tldr-daemon-BNQHwblU.js");
|
|
47279
46513
|
const projectRoot = process.cwd();
|
|
47280
46514
|
const venvPath = join(projectRoot, ".venv");
|
|
47281
46515
|
const results = [];
|
|
@@ -47320,7 +46554,7 @@ const getTldrStatusRoute = HttpRouter.add("GET", "/api/services/tldr/status", Ef
|
|
|
47320
46554
|
}));
|
|
47321
46555
|
const postTldrStartRoute = HttpRouter.add("POST", "/api/services/tldr/start", Effect.promise(async () => {
|
|
47322
46556
|
try {
|
|
47323
|
-
const { getTldrDaemonServiceSync } = await import("./tldr-daemon-
|
|
46557
|
+
const { getTldrDaemonServiceSync } = await import("./tldr-daemon-BNQHwblU.js");
|
|
47324
46558
|
const projectRoot = process.cwd();
|
|
47325
46559
|
const venvPath = join(projectRoot, ".venv");
|
|
47326
46560
|
if (!existsSync$1(venvPath)) return jsonResponse({ error: "No .venv found in project root" }, { status: 404 });
|
|
@@ -47337,7 +46571,7 @@ const postTldrStartRoute = HttpRouter.add("POST", "/api/services/tldr/start", Ef
|
|
|
47337
46571
|
}));
|
|
47338
46572
|
const postTldrStopRoute = HttpRouter.add("POST", "/api/services/tldr/stop", Effect.promise(async () => {
|
|
47339
46573
|
try {
|
|
47340
|
-
const { getTldrDaemonServiceSync } = await import("./tldr-daemon-
|
|
46574
|
+
const { getTldrDaemonServiceSync } = await import("./tldr-daemon-BNQHwblU.js");
|
|
47341
46575
|
const projectRoot = process.cwd();
|
|
47342
46576
|
const venvPath = join(projectRoot, ".venv");
|
|
47343
46577
|
if (!existsSync$1(venvPath)) return jsonResponse({ error: "No .venv found in project root" }, { status: 404 });
|
|
@@ -47354,7 +46588,7 @@ const postTldrStopRoute = HttpRouter.add("POST", "/api/services/tldr/stop", Effe
|
|
|
47354
46588
|
}));
|
|
47355
46589
|
const postTldrReloadRoute = HttpRouter.add("POST", "/api/services/tldr/reload", Effect.promise(async () => {
|
|
47356
46590
|
try {
|
|
47357
|
-
const { getTldrDaemonServiceSync } = await import("./tldr-daemon-
|
|
46591
|
+
const { getTldrDaemonServiceSync } = await import("./tldr-daemon-BNQHwblU.js");
|
|
47358
46592
|
const enabled = isTldrEnabledSync();
|
|
47359
46593
|
const projectRoot = process.cwd();
|
|
47360
46594
|
const targets = [];
|
|
@@ -47401,6 +46635,458 @@ const postTldrReloadRoute = HttpRouter.add("POST", "/api/services/tldr/reload",
|
|
|
47401
46635
|
}));
|
|
47402
46636
|
const tldrRouteLayer = Layer.mergeAll(getTldrStatusRoute, postTldrStartRoute, postTldrStopRoute, postTldrReloadRoute);
|
|
47403
46637
|
//#endregion
|
|
46638
|
+
//#region services/restart-gate.ts
|
|
46639
|
+
/**
|
|
46640
|
+
* Restart Gate (PAN-3729) — operator approval for voluntary dashboard restarts.
|
|
46641
|
+
*
|
|
46642
|
+
* A *voluntary* restart is one a requester asks for: the post-merge deploy
|
|
46643
|
+
* script, `pan reload`, or bare `pan restart`. An *involuntary* restart (crash
|
|
46644
|
+
* recovery, watchdog respawn, the supervisor's own `POST /restart-dashboard`)
|
|
46645
|
+
* is never gated — gating it would deadlock the mechanism an approved restart
|
|
46646
|
+
* uses to actually restart.
|
|
46647
|
+
*
|
|
46648
|
+
* Requesters register through `POST /api/restart-gate/requests` every 5s and
|
|
46649
|
+
* block until the operator approves. One approval opens one *epoch*: the
|
|
46650
|
+
* snapshot of request ids taken at approval. Exactly one requester in that
|
|
46651
|
+
* epoch *claims* the restart; every other member is *satisfied* by it once the
|
|
46652
|
+
* fresh server boots.
|
|
46653
|
+
*
|
|
46654
|
+
* ── Doors ──────────────────────────────────────────────────────────────────
|
|
46655
|
+
* This module is the ONE read door and the ONE write door for gate state. No
|
|
46656
|
+
* route handler, CLI, or script reads or writes `restart-gate.json` directly.
|
|
46657
|
+
* The gate is runtime-plane state — the same plane as
|
|
46658
|
+
* `~/.overdeck/dashboard-restarting.json` — so it is NOT canonical, NOT
|
|
46659
|
+
* mirrored to git, and NOT persisted to the event log. It is a single JSON
|
|
46660
|
+
* file that survives exactly one restart, which is all the protocol needs.
|
|
46661
|
+
*
|
|
46662
|
+
* ── Expiry rules ───────────────────────────────────────────────────────────
|
|
46663
|
+
* - A pending request not refreshed for 20s expires (a poll IS the refresh).
|
|
46664
|
+
* - A claim not completed within 5 minutes lapses; the epoch falls back to
|
|
46665
|
+
* `approved` and the next poller may claim it. This covers a claimant that
|
|
46666
|
+
* died between claiming and restarting.
|
|
46667
|
+
* - An unclaimed epoch whose members have ALL expired is dropped, so the gate
|
|
46668
|
+
* cannot wedge in `approved` forever with nobody left to claim it. This is
|
|
46669
|
+
* the post-approval twin of "approve when every request has already expired
|
|
46670
|
+
* → clear the gate, restart nothing". That drop records `lastOutcome` on the
|
|
46671
|
+
* projection for 15s so the banner can say the approval restarted nothing
|
|
46672
|
+
* instead of silently vanishing (PAN-3731).
|
|
46673
|
+
* - Satisfied ids are served to polls for 10 minutes after boot, then pruned.
|
|
46674
|
+
*/
|
|
46675
|
+
init_paths();
|
|
46676
|
+
/** A pending request not refreshed within this window expires. */
|
|
46677
|
+
const REQUEST_TTL_MS = 2e4;
|
|
46678
|
+
/** A claim not completed within this window lapses back to `approved`. */
|
|
46679
|
+
const CLAIM_LAPSE_MS = 5 * 6e4;
|
|
46680
|
+
/** Satisfied requester ids are served to late polls for this long. */
|
|
46681
|
+
const SATISFIED_TTL_MS = 10 * 6e4;
|
|
46682
|
+
/** How often the server prunes expired requests so the banner self-clears. */
|
|
46683
|
+
const SWEEP_INTERVAL_MS = 5e3;
|
|
46684
|
+
const RESTART_GATE_FILE = join(OVERDECK_HOME, "restart-gate.json");
|
|
46685
|
+
function emptyRestartGateState() {
|
|
46686
|
+
return {
|
|
46687
|
+
version: 1,
|
|
46688
|
+
pending: [],
|
|
46689
|
+
epoch: null,
|
|
46690
|
+
satisfied: []
|
|
46691
|
+
};
|
|
46692
|
+
}
|
|
46693
|
+
function millis(iso) {
|
|
46694
|
+
const parsed = Date.parse(iso);
|
|
46695
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
46696
|
+
}
|
|
46697
|
+
/** True while the epoch's claim is held and has not lapsed. */
|
|
46698
|
+
function hasLiveClaim(epoch, nowMs) {
|
|
46699
|
+
if (!epoch?.claimedBy || !epoch.claimedAt) return false;
|
|
46700
|
+
return nowMs - millis(epoch.claimedAt) < CLAIM_LAPSE_MS;
|
|
46701
|
+
}
|
|
46702
|
+
/**
|
|
46703
|
+
* Drops everything the clock has invalidated. Called on EVERY read and every
|
|
46704
|
+
* mutation, so a caller never has to remember to prune first.
|
|
46705
|
+
*/
|
|
46706
|
+
function pruneRestartGateState(state, nowMs) {
|
|
46707
|
+
const pending = state.pending.filter((request) => nowMs - millis(request.lastSeenAt) < REQUEST_TTL_MS);
|
|
46708
|
+
const satisfied = state.satisfied.filter((entry) => nowMs - millis(entry.satisfiedAt) < SATISFIED_TTL_MS);
|
|
46709
|
+
let lastOutcome = state.lastOutcome;
|
|
46710
|
+
if (lastOutcome && nowMs - millis(lastOutcome.at) >= 15e3) lastOutcome = void 0;
|
|
46711
|
+
let epoch = state.epoch;
|
|
46712
|
+
if (epoch && !hasLiveClaim(epoch, nowMs)) {
|
|
46713
|
+
const livePending = new Set(pending.map((request) => request.requesterId));
|
|
46714
|
+
if (!epoch.requesterIds.some((id) => livePending.has(id))) {
|
|
46715
|
+
epoch = null;
|
|
46716
|
+
lastOutcome = {
|
|
46717
|
+
type: "pruned-unclaimed",
|
|
46718
|
+
at: new Date(nowMs).toISOString()
|
|
46719
|
+
};
|
|
46720
|
+
}
|
|
46721
|
+
}
|
|
46722
|
+
return {
|
|
46723
|
+
version: state.version,
|
|
46724
|
+
pending,
|
|
46725
|
+
satisfied,
|
|
46726
|
+
epoch,
|
|
46727
|
+
...lastOutcome === void 0 ? {} : { lastOutcome }
|
|
46728
|
+
};
|
|
46729
|
+
}
|
|
46730
|
+
/** The single place gate status is derived — used by every read and mutation. */
|
|
46731
|
+
function deriveRestartGateStatus(state, nowMs) {
|
|
46732
|
+
if (state.epoch) return hasLiveClaim(state.epoch, nowMs) ? "claimed" : "approved";
|
|
46733
|
+
return state.pending.length > 0 ? "pending" : "idle";
|
|
46734
|
+
}
|
|
46735
|
+
/** The operator-facing projection — identical to the `GET /api/restart-gate` body. */
|
|
46736
|
+
function toRestartGateSnapshot(state, nowMs) {
|
|
46737
|
+
return {
|
|
46738
|
+
status: deriveRestartGateStatus(state, nowMs),
|
|
46739
|
+
pending: state.pending.map((request) => ({
|
|
46740
|
+
requesterId: request.requesterId,
|
|
46741
|
+
kind: request.kind,
|
|
46742
|
+
reason: request.reason,
|
|
46743
|
+
...request.builtSha === void 0 ? {} : { builtSha: request.builtSha },
|
|
46744
|
+
requestedAt: request.requestedAt
|
|
46745
|
+
})),
|
|
46746
|
+
...state.lastOutcome === void 0 ? {} : { lastOutcome: state.lastOutcome }
|
|
46747
|
+
};
|
|
46748
|
+
}
|
|
46749
|
+
/**
|
|
46750
|
+
* Upsert + poll + TTL refresh in one step.
|
|
46751
|
+
*
|
|
46752
|
+
* A requester already marked satisfied is answered without being re-added:
|
|
46753
|
+
* its restart happened, so it must exit rather than start a new cycle.
|
|
46754
|
+
*/
|
|
46755
|
+
function upsertRestartRequest(state, input, nowMs) {
|
|
46756
|
+
const pruned = pruneRestartGateState(state, nowMs);
|
|
46757
|
+
const nowIso = new Date(nowMs).toISOString();
|
|
46758
|
+
if (pruned.satisfied.some((entry) => entry.requesterId === input.requesterId)) return {
|
|
46759
|
+
state: pruned,
|
|
46760
|
+
result: {
|
|
46761
|
+
status: "satisfied",
|
|
46762
|
+
mayClaim: false,
|
|
46763
|
+
pendingCount: pruned.pending.length
|
|
46764
|
+
}
|
|
46765
|
+
};
|
|
46766
|
+
const existing = pruned.pending.find((request) => request.requesterId === input.requesterId);
|
|
46767
|
+
const upserted = {
|
|
46768
|
+
requesterId: input.requesterId,
|
|
46769
|
+
kind: input.kind,
|
|
46770
|
+
reason: input.reason,
|
|
46771
|
+
...input.builtSha === void 0 ? {} : { builtSha: input.builtSha },
|
|
46772
|
+
requestedAt: existing?.requestedAt ?? nowIso,
|
|
46773
|
+
lastSeenAt: nowIso
|
|
46774
|
+
};
|
|
46775
|
+
const pending = existing ? pruned.pending.map((request) => request.requesterId === input.requesterId ? upserted : request) : [...pruned.pending, upserted];
|
|
46776
|
+
const next = {
|
|
46777
|
+
...pruned,
|
|
46778
|
+
pending
|
|
46779
|
+
};
|
|
46780
|
+
const gateStatus = deriveRestartGateStatus(next, nowMs);
|
|
46781
|
+
if (!(next.epoch?.requesterIds.includes(input.requesterId) ?? false)) return {
|
|
46782
|
+
state: next,
|
|
46783
|
+
result: {
|
|
46784
|
+
status: "pending",
|
|
46785
|
+
mayClaim: false,
|
|
46786
|
+
pendingCount: pending.length
|
|
46787
|
+
}
|
|
46788
|
+
};
|
|
46789
|
+
if (gateStatus === "claimed") return {
|
|
46790
|
+
state: next,
|
|
46791
|
+
result: {
|
|
46792
|
+
status: "claimed",
|
|
46793
|
+
mayClaim: next.epoch?.claimedBy === input.requesterId,
|
|
46794
|
+
pendingCount: pending.length
|
|
46795
|
+
}
|
|
46796
|
+
};
|
|
46797
|
+
return {
|
|
46798
|
+
state: next,
|
|
46799
|
+
result: {
|
|
46800
|
+
status: "approved",
|
|
46801
|
+
mayClaim: true,
|
|
46802
|
+
pendingCount: pending.length
|
|
46803
|
+
}
|
|
46804
|
+
};
|
|
46805
|
+
}
|
|
46806
|
+
/**
|
|
46807
|
+
* Operator approval. Opens one epoch over every live request.
|
|
46808
|
+
*
|
|
46809
|
+
* When every request has already expired there is nothing to restart for, so
|
|
46810
|
+
* the gate is simply cleared — approving must never trigger a bare restart.
|
|
46811
|
+
* Re-approving an open epoch is a no-op so a double-click cannot widen it.
|
|
46812
|
+
*/
|
|
46813
|
+
function approveRestartGate(state, nowMs) {
|
|
46814
|
+
const pruned = pruneRestartGateState(state, nowMs);
|
|
46815
|
+
if (pruned.epoch) return {
|
|
46816
|
+
state: pruned,
|
|
46817
|
+
result: {
|
|
46818
|
+
approved: true,
|
|
46819
|
+
pendingCount: pruned.pending.length
|
|
46820
|
+
}
|
|
46821
|
+
};
|
|
46822
|
+
if (pruned.pending.length === 0) return {
|
|
46823
|
+
state: {
|
|
46824
|
+
...pruned,
|
|
46825
|
+
epoch: null
|
|
46826
|
+
},
|
|
46827
|
+
result: {
|
|
46828
|
+
approved: true,
|
|
46829
|
+
pendingCount: 0
|
|
46830
|
+
}
|
|
46831
|
+
};
|
|
46832
|
+
const nowIso = new Date(nowMs).toISOString();
|
|
46833
|
+
const epoch = {
|
|
46834
|
+
id: `epoch-${nowMs}`,
|
|
46835
|
+
requesterIds: pruned.pending.map((request) => request.requesterId),
|
|
46836
|
+
approvedAt: nowIso
|
|
46837
|
+
};
|
|
46838
|
+
return {
|
|
46839
|
+
state: {
|
|
46840
|
+
...pruned,
|
|
46841
|
+
epoch
|
|
46842
|
+
},
|
|
46843
|
+
result: {
|
|
46844
|
+
approved: true,
|
|
46845
|
+
pendingCount: pruned.pending.length
|
|
46846
|
+
}
|
|
46847
|
+
};
|
|
46848
|
+
}
|
|
46849
|
+
/**
|
|
46850
|
+
* Grant the exclusive right to perform the restart.
|
|
46851
|
+
*
|
|
46852
|
+
* Atomic by construction: the state transition is synchronous, so two
|
|
46853
|
+
* concurrent claims are serialized by the event loop and exactly one wins.
|
|
46854
|
+
* A claimant re-claiming its own live claim is granted again, so a retry after
|
|
46855
|
+
* a dropped response is safe.
|
|
46856
|
+
*/
|
|
46857
|
+
function claimRestartGate(state, requesterId, nowMs) {
|
|
46858
|
+
const pruned = pruneRestartGateState(state, nowMs);
|
|
46859
|
+
const epoch = pruned.epoch;
|
|
46860
|
+
if (!epoch || !epoch.requesterIds.includes(requesterId)) return {
|
|
46861
|
+
state: pruned,
|
|
46862
|
+
result: {
|
|
46863
|
+
granted: false,
|
|
46864
|
+
status: deriveRestartGateStatus(pruned, nowMs)
|
|
46865
|
+
}
|
|
46866
|
+
};
|
|
46867
|
+
if (hasLiveClaim(epoch, nowMs) && epoch.claimedBy !== requesterId) return {
|
|
46868
|
+
state: pruned,
|
|
46869
|
+
result: {
|
|
46870
|
+
granted: false,
|
|
46871
|
+
status: "claimed"
|
|
46872
|
+
}
|
|
46873
|
+
};
|
|
46874
|
+
const claimed = {
|
|
46875
|
+
...epoch,
|
|
46876
|
+
claimedBy: requesterId,
|
|
46877
|
+
claimedAt: new Date(nowMs).toISOString()
|
|
46878
|
+
};
|
|
46879
|
+
return {
|
|
46880
|
+
state: {
|
|
46881
|
+
...pruned,
|
|
46882
|
+
epoch: claimed
|
|
46883
|
+
},
|
|
46884
|
+
result: {
|
|
46885
|
+
granted: true,
|
|
46886
|
+
status: "claimed"
|
|
46887
|
+
}
|
|
46888
|
+
};
|
|
46889
|
+
}
|
|
46890
|
+
/**
|
|
46891
|
+
* The dashboard's own restart button is implicit approval (PAN-3729 §2.4).
|
|
46892
|
+
*
|
|
46893
|
+
* Every live request is folded into an epoch claimed by the UI, so the boot
|
|
46894
|
+
* that follows marks them satisfied and unblocks the requesters instead of
|
|
46895
|
+
* leaving them waiting for an approval that already happened.
|
|
46896
|
+
*/
|
|
46897
|
+
function satisfyRestartGateForDirectRestart(state, nowMs, claimedBy) {
|
|
46898
|
+
const pruned = pruneRestartGateState(state, nowMs);
|
|
46899
|
+
const nowIso = new Date(nowMs).toISOString();
|
|
46900
|
+
return {
|
|
46901
|
+
...pruned,
|
|
46902
|
+
epoch: {
|
|
46903
|
+
id: `epoch-${nowMs}`,
|
|
46904
|
+
requesterIds: pruned.pending.map((request) => request.requesterId),
|
|
46905
|
+
approvedAt: nowIso,
|
|
46906
|
+
claimedBy,
|
|
46907
|
+
claimedAt: nowIso
|
|
46908
|
+
}
|
|
46909
|
+
};
|
|
46910
|
+
}
|
|
46911
|
+
/**
|
|
46912
|
+
* Boot-time epoch resolution: this process starting IS the restart completing.
|
|
46913
|
+
*
|
|
46914
|
+
* A persisted epoch in `claimed` state means the previous server died to
|
|
46915
|
+
* perform an approved restart, so every member of that epoch got what it asked
|
|
46916
|
+
* for. An approved-but-unclaimed epoch is left alone — nobody performed a
|
|
46917
|
+
* restart for it, so its members keep waiting and can still claim.
|
|
46918
|
+
*/
|
|
46919
|
+
function resolveRestartGateBoot(state, nowMs) {
|
|
46920
|
+
if (!state.epoch?.claimedBy) return {
|
|
46921
|
+
state: pruneRestartGateState(state, nowMs),
|
|
46922
|
+
satisfiedIds: []
|
|
46923
|
+
};
|
|
46924
|
+
const satisfiedAt = new Date(nowMs).toISOString();
|
|
46925
|
+
const satisfiedIds = state.epoch.requesterIds;
|
|
46926
|
+
const satisfied = [...state.satisfied.filter((entry) => !satisfiedIds.includes(entry.requesterId)), ...satisfiedIds.map((requesterId) => ({
|
|
46927
|
+
requesterId,
|
|
46928
|
+
satisfiedAt
|
|
46929
|
+
}))];
|
|
46930
|
+
return {
|
|
46931
|
+
state: pruneRestartGateState({
|
|
46932
|
+
...state,
|
|
46933
|
+
pending: [],
|
|
46934
|
+
epoch: null,
|
|
46935
|
+
satisfied
|
|
46936
|
+
}, nowMs),
|
|
46937
|
+
satisfiedIds
|
|
46938
|
+
};
|
|
46939
|
+
}
|
|
46940
|
+
function emitThroughEventStore(snapshot) {
|
|
46941
|
+
(async () => {
|
|
46942
|
+
try {
|
|
46943
|
+
const { getEventStore } = await import("./event-store-Db4w4YIY.js");
|
|
46944
|
+
getEventStore().emitOnly({
|
|
46945
|
+
type: "restart_gate.changed",
|
|
46946
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
46947
|
+
payload: snapshot
|
|
46948
|
+
});
|
|
46949
|
+
} catch {}
|
|
46950
|
+
})();
|
|
46951
|
+
}
|
|
46952
|
+
function createRestartGate(deps = {}) {
|
|
46953
|
+
const filePath = deps.filePath ?? RESTART_GATE_FILE;
|
|
46954
|
+
const now = deps.now ?? (() => Date.now());
|
|
46955
|
+
const emit = deps.emit ?? emitThroughEventStore;
|
|
46956
|
+
let state = null;
|
|
46957
|
+
let loading = null;
|
|
46958
|
+
let writing = Promise.resolve();
|
|
46959
|
+
let lastPublished = null;
|
|
46960
|
+
async function loadState() {
|
|
46961
|
+
let parsed;
|
|
46962
|
+
try {
|
|
46963
|
+
const raw = await readFile(filePath, "utf-8");
|
|
46964
|
+
const candidate = JSON.parse(raw);
|
|
46965
|
+
parsed = {
|
|
46966
|
+
version: 1,
|
|
46967
|
+
pending: Array.isArray(candidate.pending) ? candidate.pending : [],
|
|
46968
|
+
epoch: candidate.epoch ?? null,
|
|
46969
|
+
satisfied: Array.isArray(candidate.satisfied) ? candidate.satisfied : [],
|
|
46970
|
+
...candidate.lastOutcome === void 0 ? {} : { lastOutcome: candidate.lastOutcome }
|
|
46971
|
+
};
|
|
46972
|
+
} catch {
|
|
46973
|
+
parsed = emptyRestartGateState();
|
|
46974
|
+
}
|
|
46975
|
+
const resolved = resolveRestartGateBoot(parsed, now());
|
|
46976
|
+
state = resolved.state;
|
|
46977
|
+
if (resolved.satisfiedIds.length > 0) {
|
|
46978
|
+
console.log(`[restart-gate] Boot completed an approved restart — satisfied ${resolved.satisfiedIds.length} request(s): ${resolved.satisfiedIds.join(", ")}`);
|
|
46979
|
+
await persist();
|
|
46980
|
+
}
|
|
46981
|
+
}
|
|
46982
|
+
function ensureLoaded() {
|
|
46983
|
+
if (!loading) loading = loadState();
|
|
46984
|
+
return loading;
|
|
46985
|
+
}
|
|
46986
|
+
/** Atomic tmp+rename so a crash mid-write cannot leave a truncated gate. */
|
|
46987
|
+
async function persist() {
|
|
46988
|
+
const current = state;
|
|
46989
|
+
if (!current) return;
|
|
46990
|
+
const body = JSON.stringify(current, null, 2);
|
|
46991
|
+
writing = writing.then(async () => {
|
|
46992
|
+
try {
|
|
46993
|
+
await mkdir(dirname(filePath), { recursive: true });
|
|
46994
|
+
const tmp = `${filePath}.tmp`;
|
|
46995
|
+
await writeFile(tmp, body, "utf-8");
|
|
46996
|
+
await rename(tmp, filePath);
|
|
46997
|
+
} catch (error) {
|
|
46998
|
+
console.error("[restart-gate] Failed to persist gate state:", error);
|
|
46999
|
+
}
|
|
47000
|
+
});
|
|
47001
|
+
await writing;
|
|
47002
|
+
}
|
|
47003
|
+
function publish() {
|
|
47004
|
+
const snapshot = toRestartGateSnapshot(state ?? emptyRestartGateState(), now());
|
|
47005
|
+
const serialized = JSON.stringify(snapshot);
|
|
47006
|
+
if (serialized !== lastPublished) {
|
|
47007
|
+
lastPublished = serialized;
|
|
47008
|
+
emit(snapshot);
|
|
47009
|
+
}
|
|
47010
|
+
return snapshot;
|
|
47011
|
+
}
|
|
47012
|
+
async function mutate(apply) {
|
|
47013
|
+
await ensureLoaded();
|
|
47014
|
+
const { state: next, result } = apply(state ?? emptyRestartGateState(), now());
|
|
47015
|
+
state = next;
|
|
47016
|
+
await persist();
|
|
47017
|
+
publish();
|
|
47018
|
+
return result;
|
|
47019
|
+
}
|
|
47020
|
+
return {
|
|
47021
|
+
request: (input) => mutate((current, nowMs) => upsertRestartRequest(current, input, nowMs)),
|
|
47022
|
+
claim: (requesterId) => mutate((current, nowMs) => claimRestartGate(current, requesterId, nowMs)),
|
|
47023
|
+
approve: () => mutate((current, nowMs) => approveRestartGate(current, nowMs)),
|
|
47024
|
+
read: async () => {
|
|
47025
|
+
await ensureLoaded();
|
|
47026
|
+
state = pruneRestartGateState(state ?? emptyRestartGateState(), now());
|
|
47027
|
+
return publish();
|
|
47028
|
+
},
|
|
47029
|
+
satisfyForDirectRestart: (claimedBy) => mutate((current, nowMs) => ({
|
|
47030
|
+
state: satisfyRestartGateForDirectRestart(current, nowMs, claimedBy),
|
|
47031
|
+
result: void 0
|
|
47032
|
+
})),
|
|
47033
|
+
sweep: async () => {
|
|
47034
|
+
await ensureLoaded();
|
|
47035
|
+
const before = state ?? emptyRestartGateState();
|
|
47036
|
+
const after = pruneRestartGateState(before, now());
|
|
47037
|
+
state = after;
|
|
47038
|
+
if (after.pending.length !== before.pending.length || after.epoch !== before.epoch) await persist();
|
|
47039
|
+
return publish();
|
|
47040
|
+
}
|
|
47041
|
+
};
|
|
47042
|
+
}
|
|
47043
|
+
let sharedGate = null;
|
|
47044
|
+
let sweepTimer = null;
|
|
47045
|
+
/** The one gate instance every route and boot step shares. */
|
|
47046
|
+
function getRestartGate() {
|
|
47047
|
+
if (!sharedGate) sharedGate = createRestartGate();
|
|
47048
|
+
return sharedGate;
|
|
47049
|
+
}
|
|
47050
|
+
/**
|
|
47051
|
+
* Prune expired requests on a timer.
|
|
47052
|
+
*
|
|
47053
|
+
* Reads alone cannot clear the banner: a requester that dies simply stops
|
|
47054
|
+
* polling, so without this nothing would ever re-publish the shrunken
|
|
47055
|
+
* projection to the dashboard.
|
|
47056
|
+
*/
|
|
47057
|
+
function startRestartGateSweep(gate, deps = {}) {
|
|
47058
|
+
const timer = (deps.setIntervalFn ?? setInterval)(() => {
|
|
47059
|
+
gate.sweep().catch((error) => {
|
|
47060
|
+
console.error("[restart-gate] Sweep failed:", error);
|
|
47061
|
+
});
|
|
47062
|
+
}, SWEEP_INTERVAL_MS);
|
|
47063
|
+
timer.unref?.();
|
|
47064
|
+
return timer;
|
|
47065
|
+
}
|
|
47066
|
+
/**
|
|
47067
|
+
* Resolve the persisted epoch and start the sweep.
|
|
47068
|
+
*
|
|
47069
|
+
* Boot resolution is lazy inside the gate too, so a requester polling a
|
|
47070
|
+
* still-booting server gets the same answer this call produces — there is no
|
|
47071
|
+
* window where a poll races ahead of startup.
|
|
47072
|
+
*/
|
|
47073
|
+
async function initRestartGate(deps = {}) {
|
|
47074
|
+
const gate = getRestartGate();
|
|
47075
|
+
await gate.read();
|
|
47076
|
+
if (sweepTimer) return;
|
|
47077
|
+
sweepTimer = startRestartGateSweep(gate, deps);
|
|
47078
|
+
}
|
|
47079
|
+
//#endregion
|
|
47080
|
+
//#region ../../lib/restart-gate-client.ts
|
|
47081
|
+
init_config();
|
|
47082
|
+
/**
|
|
47083
|
+
* Set on any `pan restart` child spawned by a requester that has already
|
|
47084
|
+
* cleared the gate for that restart — the post-merge deploy script does exactly
|
|
47085
|
+
* that. Without it the child registers a second request and waits for a second
|
|
47086
|
+
* approval, so one deploy would cost the operator two clicks.
|
|
47087
|
+
*/
|
|
47088
|
+
const RESTART_GATE_CLAIMED_ENV = "OVERDECK_RESTART_GATE_CLAIMED";
|
|
47089
|
+
//#endregion
|
|
47404
47090
|
//#region ../../lib/sync-startup-gate.ts
|
|
47405
47091
|
var sync_startup_gate_exports = /* @__PURE__ */ __exportAll({
|
|
47406
47092
|
isStartupSyncNeededSync: () => isStartupSyncNeededSync,
|
|
@@ -47542,7 +47228,7 @@ const getVersionRoute = HttpRouter.add("GET", "/api/version", Effect.promise(asy
|
|
|
47542
47228
|
const version = await getOverdeckVersion();
|
|
47543
47229
|
let supervisorUrl = null;
|
|
47544
47230
|
try {
|
|
47545
|
-
const { getSupervisorUrlSync } = await import("./supervisor-
|
|
47231
|
+
const { getSupervisorUrlSync } = await import("./supervisor-v0cYN2Vp.js");
|
|
47546
47232
|
supervisorUrl = getSupervisorUrlSync();
|
|
47547
47233
|
} catch {}
|
|
47548
47234
|
return jsonResponse({
|
|
@@ -47552,11 +47238,11 @@ const getVersionRoute = HttpRouter.add("GET", "/api/version", Effect.promise(asy
|
|
|
47552
47238
|
});
|
|
47553
47239
|
}));
|
|
47554
47240
|
const getPrerequisitesRoute = HttpRouter.add("GET", "/api/prerequisites", Effect.promise(async () => {
|
|
47555
|
-
const { checkSystemPrerequisites } = await import("./system-prerequisites-
|
|
47241
|
+
const { checkSystemPrerequisites } = await import("./system-prerequisites-QKtIYXI2.js");
|
|
47556
47242
|
return jsonResponse(await checkSystemPrerequisites());
|
|
47557
47243
|
}));
|
|
47558
47244
|
const getSetupDiagnosticsRoute = HttpRouter.add("GET", "/api/diagnostics/setup", Effect.promise(async () => {
|
|
47559
|
-
const { collectSetupDiagnostics } = await import("./system-prerequisites-
|
|
47245
|
+
const { collectSetupDiagnostics } = await import("./system-prerequisites-QKtIYXI2.js");
|
|
47560
47246
|
return jsonResponse(await collectSetupDiagnostics(await getOverdeckVersion()));
|
|
47561
47247
|
}));
|
|
47562
47248
|
const getSyncStatusRoute = HttpRouter.add("GET", "/api/sync-status", Effect.sync(() => {
|
|
@@ -47600,7 +47286,7 @@ const getConfirmationsRoute = HttpRouter.add("GET", "/api/confirmations", Effect
|
|
|
47600
47286
|
const postConfirmationRespondRoute = HttpRouter.add("POST", "/api/confirmations/:id/respond", Effect.gen(function* () {
|
|
47601
47287
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
47602
47288
|
const id = new URL(request.url, "http://localhost").pathname.split("/")[3] || "";
|
|
47603
|
-
const { confirmed } = yield* readJsonBody$
|
|
47289
|
+
const { confirmed } = yield* readJsonBody$11;
|
|
47604
47290
|
const confirmationRequest = pendingConfirmations.get(id);
|
|
47605
47291
|
if (!confirmationRequest) return jsonResponse({ error: "Confirmation request not found" }, { status: 404 });
|
|
47606
47292
|
return yield* Effect.promise(async () => {
|
|
@@ -47736,7 +47422,7 @@ const postShadowMonitorRoute = HttpRouter.add("POST", "/api/shadow/:issueId/moni
|
|
|
47736
47422
|
const projectPath = await getProjectPath(issuePrefix);
|
|
47737
47423
|
const workspacePath = join(projectPath, "workspaces", `feature-${issueLower}`);
|
|
47738
47424
|
if (!existsSync$1(workspacePath)) return jsonResponse({ error: "Workspace not found" }, { status: 404 });
|
|
47739
|
-
const { gatherArtifacts, generateBasicInference, updateInferenceDocumentSync } = await import("./shadow-engineering-
|
|
47425
|
+
const { gatherArtifacts, generateBasicInference, updateInferenceDocumentSync } = await import("./shadow-engineering-BxiFrIKv.js");
|
|
47740
47426
|
const config = {
|
|
47741
47427
|
issueId,
|
|
47742
47428
|
workspacePath,
|
|
@@ -47758,7 +47444,7 @@ const postShadowObserveRoute = HttpRouter.add("POST", "/api/shadow/:issueId/obse
|
|
|
47758
47444
|
const issueId = new URL(request.url, "http://localhost").pathname.split("/")[3] || "";
|
|
47759
47445
|
const issueLower = issueId.toLowerCase();
|
|
47760
47446
|
const issuePrefix = extractPrefixSync(issueId) ?? issueId.split("-")[0];
|
|
47761
|
-
const { mode } = yield* readJsonBody$
|
|
47447
|
+
const { mode } = yield* readJsonBody$11;
|
|
47762
47448
|
return yield* Effect.promise(async () => {
|
|
47763
47449
|
try {
|
|
47764
47450
|
const projectPath = await getProjectPath(issuePrefix);
|
|
@@ -47766,7 +47452,7 @@ const postShadowObserveRoute = HttpRouter.add("POST", "/api/shadow/:issueId/obse
|
|
|
47766
47452
|
if (!existsSync$1(workspacePath)) return jsonResponse({ error: "Workspace not found" }, { status: 404 });
|
|
47767
47453
|
const ghConfig = getGitHubConfig();
|
|
47768
47454
|
if (!ghConfig) return jsonResponse({ error: "GitHub not configured - Observer requires GitHub" }, { status: 400 });
|
|
47769
|
-
const { runObserverCycle } = await import("./shadow-engineering-
|
|
47455
|
+
const { runObserverCycle } = await import("./shadow-engineering-BxiFrIKv.js");
|
|
47770
47456
|
const firstRepo = ghConfig.repos[0];
|
|
47771
47457
|
const config = {
|
|
47772
47458
|
issueId,
|
|
@@ -47812,12 +47498,21 @@ const postDevRebuildRoute = HttpRouter.add("POST", "/api/dev/rebuild", Effect.ge
|
|
|
47812
47498
|
}
|
|
47813
47499
|
});
|
|
47814
47500
|
}));
|
|
47815
|
-
const postRestartDashboardRoute = HttpRouter.add("POST", "/api/system/restart-dashboard", Effect.
|
|
47501
|
+
const postRestartDashboardRoute = HttpRouter.add("POST", "/api/system/restart-dashboard", Effect.promise(async () => {
|
|
47502
|
+
try {
|
|
47503
|
+
await getRestartGate().satisfyForDirectRestart(`dashboard-ui:${process.pid}`);
|
|
47504
|
+
} catch (error) {
|
|
47505
|
+
console.error("[restart-dashboard] restart-gate implicit approval failed:", error);
|
|
47506
|
+
}
|
|
47816
47507
|
try {
|
|
47817
47508
|
const invocation = panCliInvocation(["restart", "--dashboard"]);
|
|
47818
47509
|
const child = spawn(invocation.command, invocation.args, {
|
|
47819
47510
|
detached: true,
|
|
47820
|
-
stdio: "ignore"
|
|
47511
|
+
stdio: "ignore",
|
|
47512
|
+
env: {
|
|
47513
|
+
...process.env,
|
|
47514
|
+
[RESTART_GATE_CLAIMED_ENV]: "1"
|
|
47515
|
+
}
|
|
47821
47516
|
});
|
|
47822
47517
|
child.on("error", (err) => {
|
|
47823
47518
|
console.error("[restart-dashboard] pan restart spawn failed:", err);
|
|
@@ -49535,6 +49230,7 @@ init_summary_fork();
|
|
|
49535
49230
|
init_conversation_compaction();
|
|
49536
49231
|
init_conversations();
|
|
49537
49232
|
init_behavior();
|
|
49233
|
+
init_session_pane_choice();
|
|
49538
49234
|
function isClaudeCodeConversation(conv) {
|
|
49539
49235
|
return getHarnessBehavior(conv.harness).transcriptKind === "claude-jsonl";
|
|
49540
49236
|
}
|
|
@@ -49586,6 +49282,109 @@ async function handleConversationPaneChoiceAnswer(rawId, body, deps = {}) {
|
|
|
49586
49282
|
}
|
|
49587
49283
|
}
|
|
49588
49284
|
//#endregion
|
|
49285
|
+
//#region ../../lib/overdeck/claude-session-file-search.ts
|
|
49286
|
+
/**
|
|
49287
|
+
* By-id search for Claude Code transcripts under ~/.claude/projects/.
|
|
49288
|
+
*
|
|
49289
|
+
* Claude keys session files by the cwd AT RUNTIME, so when a repo directory is
|
|
49290
|
+
* renamed (e.g. Projects/panopticon-cli → Projects/overdeck) a conversation's
|
|
49291
|
+
* recorded cwd goes stale and the deterministic sessionFilePath(cwd, id)
|
|
49292
|
+
* points at a dir that no longer exists, while the JSONL itself lives under
|
|
49293
|
+
* the new encoded dir. A by-id search recovers it. The conversation-search
|
|
49294
|
+
* indexer also catalogs subagent transcripts
|
|
49295
|
+
* (<session-dir>/subagents/agent-<id>.jsonl), so palette hits arrive carrying
|
|
49296
|
+
* bare agent ids that only a one-level-deeper sweep can resolve.
|
|
49297
|
+
*/
|
|
49298
|
+
const SAFE_SESSION_ID_PATTERN$1 = /^[a-zA-Z0-9_-]{1,128}$/;
|
|
49299
|
+
const SAFE_DIR_PATTERN = /^[a-zA-Z0-9_.-]+$/;
|
|
49300
|
+
const STAT_BATCH_SIZE = 50;
|
|
49301
|
+
const sessionFileByIdCache$1 = /* @__PURE__ */ new Map();
|
|
49302
|
+
const SESSION_FILE_MISS_TTL_MS$1 = 6e4;
|
|
49303
|
+
function cachedLookup(id) {
|
|
49304
|
+
const cached = sessionFileByIdCache$1.get(id);
|
|
49305
|
+
if (!cached) return void 0;
|
|
49306
|
+
if (cached.path) {
|
|
49307
|
+
if (existsSync$1(cached.path)) return cached.path;
|
|
49308
|
+
sessionFileByIdCache$1.delete(id);
|
|
49309
|
+
return;
|
|
49310
|
+
}
|
|
49311
|
+
if (Date.now() - cached.ts < SESSION_FILE_MISS_TTL_MS$1) return null;
|
|
49312
|
+
}
|
|
49313
|
+
async function firstExisting(candidates) {
|
|
49314
|
+
for (let i = 0; i < candidates.length; i += STAT_BATCH_SIZE) {
|
|
49315
|
+
const batch = candidates.slice(i, i + STAT_BATCH_SIZE);
|
|
49316
|
+
const found = (await Promise.all(batch.map(async (candidate) => {
|
|
49317
|
+
try {
|
|
49318
|
+
await stat(candidate);
|
|
49319
|
+
return candidate;
|
|
49320
|
+
} catch {
|
|
49321
|
+
return null;
|
|
49322
|
+
}
|
|
49323
|
+
}))).find((c) => c !== null);
|
|
49324
|
+
if (found) return found;
|
|
49325
|
+
}
|
|
49326
|
+
return null;
|
|
49327
|
+
}
|
|
49328
|
+
/** Find a main-session JSONL `<project-dir>/<session-id>.jsonl` by session id. */
|
|
49329
|
+
async function findClaudeSessionFileById$1(sessionId) {
|
|
49330
|
+
if (!SAFE_SESSION_ID_PATTERN$1.test(sessionId)) return null;
|
|
49331
|
+
const cached = cachedLookup(sessionId);
|
|
49332
|
+
if (cached !== void 0) return cached;
|
|
49333
|
+
try {
|
|
49334
|
+
const claudeProjects = join(homedir$1(), ".claude", "projects");
|
|
49335
|
+
const found = await firstExisting((await readdir(claudeProjects)).filter((dir) => SAFE_DIR_PATTERN.test(dir)).map((dir) => join(claudeProjects, dir, `${sessionId}.jsonl`)));
|
|
49336
|
+
if (found) {
|
|
49337
|
+
sessionFileByIdCache$1.set(sessionId, {
|
|
49338
|
+
path: found,
|
|
49339
|
+
ts: Date.now()
|
|
49340
|
+
});
|
|
49341
|
+
return found;
|
|
49342
|
+
}
|
|
49343
|
+
} catch {}
|
|
49344
|
+
sessionFileByIdCache$1.set(sessionId, {
|
|
49345
|
+
path: null,
|
|
49346
|
+
ts: Date.now()
|
|
49347
|
+
});
|
|
49348
|
+
return null;
|
|
49349
|
+
}
|
|
49350
|
+
/**
|
|
49351
|
+
* Find a subagent transcript `<session-dir>/subagents/agent-<id>.jsonl` by its
|
|
49352
|
+
* agent id, searching every session dir of every project dir. Same
|
|
49353
|
+
* memoization contract as findClaudeSessionFileById: the sweep readdir+stats
|
|
49354
|
+
* one level deeper, so a miss is cached for the TTL and a found path is
|
|
49355
|
+
* re-verified with one existsSync.
|
|
49356
|
+
*/
|
|
49357
|
+
async function findSubagentTranscriptById(agentId) {
|
|
49358
|
+
if (!SAFE_SESSION_ID_PATTERN$1.test(agentId)) return null;
|
|
49359
|
+
const cached = cachedLookup(agentId);
|
|
49360
|
+
if (cached !== void 0) return cached;
|
|
49361
|
+
try {
|
|
49362
|
+
const claudeProjects = join(homedir$1(), ".claude", "projects");
|
|
49363
|
+
const projectDirs = (await readdir(claudeProjects)).filter((dir) => SAFE_DIR_PATTERN.test(dir));
|
|
49364
|
+
for (const projectDir of projectDirs) {
|
|
49365
|
+
let sessionDirs;
|
|
49366
|
+
try {
|
|
49367
|
+
sessionDirs = await readdir(join(claudeProjects, projectDir));
|
|
49368
|
+
} catch {
|
|
49369
|
+
continue;
|
|
49370
|
+
}
|
|
49371
|
+
const found = await firstExisting(sessionDirs.filter((entry) => SAFE_DIR_PATTERN.test(entry) && !entry.endsWith(".jsonl")).map((entry) => join(claudeProjects, projectDir, entry, "subagents", `${agentId}.jsonl`)));
|
|
49372
|
+
if (found) {
|
|
49373
|
+
sessionFileByIdCache$1.set(agentId, {
|
|
49374
|
+
path: found,
|
|
49375
|
+
ts: Date.now()
|
|
49376
|
+
});
|
|
49377
|
+
return found;
|
|
49378
|
+
}
|
|
49379
|
+
}
|
|
49380
|
+
} catch {}
|
|
49381
|
+
sessionFileByIdCache$1.set(agentId, {
|
|
49382
|
+
path: null,
|
|
49383
|
+
ts: Date.now()
|
|
49384
|
+
});
|
|
49385
|
+
return null;
|
|
49386
|
+
}
|
|
49387
|
+
//#endregion
|
|
49589
49388
|
//#region ../../lib/overdeck/conversation-reads.ts
|
|
49590
49389
|
init_concurrency$1();
|
|
49591
49390
|
init_agent_enrichment();
|
|
@@ -49600,6 +49399,7 @@ init_conversation_service();
|
|
|
49600
49399
|
init_pi_conversation_parser();
|
|
49601
49400
|
init_ohmypi_conversation_parser();
|
|
49602
49401
|
init_codex_conversation_parser();
|
|
49402
|
+
init_jsonl_resolver();
|
|
49603
49403
|
init_kimi_conversation_parser();
|
|
49604
49404
|
function result(body, status) {
|
|
49605
49405
|
return status === void 0 ? { body } : {
|
|
@@ -49623,61 +49423,20 @@ const SAFE_SESSION_ID_PATTERN = /^[a-zA-Z0-9_-]{1,128}$/;
|
|
|
49623
49423
|
* allowed to trigger it.
|
|
49624
49424
|
*/
|
|
49625
49425
|
const CLAUDE_SESSION_UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
49626
|
-
/** The transcript of an indexed-but-unregistered Claude session, or null. */
|
|
49627
|
-
async function resolveUnregisteredClaudeSessionFile(name) {
|
|
49628
|
-
if (!CLAUDE_SESSION_UUID_PATTERN.test(name)) return null;
|
|
49629
|
-
return findClaudeSessionFileById$1(name);
|
|
49630
|
-
}
|
|
49631
49426
|
/**
|
|
49632
|
-
*
|
|
49633
|
-
*
|
|
49634
|
-
*
|
|
49635
|
-
*
|
|
49636
|
-
*
|
|
49637
|
-
*
|
|
49638
|
-
*
|
|
49639
|
-
* uses below.
|
|
49427
|
+
* A Claude Code subagent transcript id, as used to name
|
|
49428
|
+
* `<session-dir>/subagents/agent-<id>.jsonl`. The search indexer recurses into
|
|
49429
|
+
* subagents dirs, so those transcripts appear in palette results with the bare
|
|
49430
|
+
* agent id as their sessionId; clicking one arrives here. Like the UUID shape,
|
|
49431
|
+
* only this exact shape may trigger the by-id sweep — and the 10-hex floor
|
|
49432
|
+
* keeps Overdeck's own short `agent-<digits>` work-agent names out of it
|
|
49433
|
+
* (those resolve through resolveSpecialistSessionFile above, or nowhere).
|
|
49640
49434
|
*/
|
|
49641
|
-
const
|
|
49642
|
-
|
|
49643
|
-
async function
|
|
49644
|
-
if (
|
|
49645
|
-
|
|
49646
|
-
if (cached) {
|
|
49647
|
-
if (cached.path) {
|
|
49648
|
-
if (existsSync$1(cached.path)) return cached.path;
|
|
49649
|
-
sessionFileByIdCache$1.delete(sessionId);
|
|
49650
|
-
} else if (Date.now() - cached.ts < SESSION_FILE_MISS_TTL_MS$1) return null;
|
|
49651
|
-
}
|
|
49652
|
-
try {
|
|
49653
|
-
const claudeProjects = join(homedir$1(), ".claude", "projects");
|
|
49654
|
-
const dirs = await readdir(claudeProjects);
|
|
49655
|
-
const SAFE_DIR_PATTERN = /^[a-zA-Z0-9_.-]+$/;
|
|
49656
|
-
const candidates = dirs.filter((dir) => SAFE_DIR_PATTERN.test(dir)).map((dir) => join(claudeProjects, dir, `${sessionId}.jsonl`));
|
|
49657
|
-
const STAT_BATCH_SIZE = 50;
|
|
49658
|
-
for (let i = 0; i < candidates.length; i += STAT_BATCH_SIZE) {
|
|
49659
|
-
const batch = candidates.slice(i, i + STAT_BATCH_SIZE);
|
|
49660
|
-
const found = (await Promise.all(batch.map(async (candidate) => {
|
|
49661
|
-
try {
|
|
49662
|
-
await stat(candidate);
|
|
49663
|
-
return candidate;
|
|
49664
|
-
} catch {
|
|
49665
|
-
return null;
|
|
49666
|
-
}
|
|
49667
|
-
}))).find((c) => c !== null);
|
|
49668
|
-
if (found) {
|
|
49669
|
-
sessionFileByIdCache$1.set(sessionId, {
|
|
49670
|
-
path: found,
|
|
49671
|
-
ts: Date.now()
|
|
49672
|
-
});
|
|
49673
|
-
return found;
|
|
49674
|
-
}
|
|
49675
|
-
}
|
|
49676
|
-
} catch {}
|
|
49677
|
-
sessionFileByIdCache$1.set(sessionId, {
|
|
49678
|
-
path: null,
|
|
49679
|
-
ts: Date.now()
|
|
49680
|
-
});
|
|
49435
|
+
const SUBAGENT_TRANSCRIPT_ID_PATTERN = /^agent-[0-9a-f]{10,20}$/i;
|
|
49436
|
+
/** The transcript of an indexed-but-unregistered Claude session, or null. */
|
|
49437
|
+
async function resolveUnregisteredClaudeSessionFile(name) {
|
|
49438
|
+
if (CLAUDE_SESSION_UUID_PATTERN.test(name)) return findClaudeSessionFileById$1(name);
|
|
49439
|
+
if (SUBAGENT_TRANSCRIPT_ID_PATTERN.test(name)) return findSubagentTranscriptById(name);
|
|
49681
49440
|
return null;
|
|
49682
49441
|
}
|
|
49683
49442
|
async function resolveSessionFile(conv) {
|
|
@@ -51048,6 +50807,66 @@ function isInGraphQLCooldown() {
|
|
|
51048
50807
|
return Date.now() - cooldownStartedAt < GRAPHQL_COOLDOWN_MS;
|
|
51049
50808
|
}
|
|
51050
50809
|
//#endregion
|
|
50810
|
+
//#region ../../lib/ci/project-ci-observation.ts
|
|
50811
|
+
init_projects();
|
|
50812
|
+
let projectByRepo = null;
|
|
50813
|
+
let projectLookupExpiresAt = 0;
|
|
50814
|
+
const PROJECT_LOOKUP_TTL_MS = 300 * 1e3;
|
|
50815
|
+
subscribeProjectsConfigInvalidation(() => {
|
|
50816
|
+
projectByRepo = null;
|
|
50817
|
+
projectLookupExpiresAt = 0;
|
|
50818
|
+
});
|
|
50819
|
+
function buildProjectLookup(projects) {
|
|
50820
|
+
const lookup = /* @__PURE__ */ new Map();
|
|
50821
|
+
for (const project of projects) {
|
|
50822
|
+
const repo = project.config.github_repo;
|
|
50823
|
+
if (!repo) continue;
|
|
50824
|
+
lookup.set(repo.toLowerCase(), {
|
|
50825
|
+
projectKey: project.key,
|
|
50826
|
+
repo,
|
|
50827
|
+
branch: project.config.workspace?.default_branch ?? "main"
|
|
50828
|
+
});
|
|
50829
|
+
}
|
|
50830
|
+
return lookup;
|
|
50831
|
+
}
|
|
50832
|
+
/** Resolve "owner/repo" from the invalidation-aware project registry cache. */
|
|
50833
|
+
function resolveProjectForRepo(fullName, projects) {
|
|
50834
|
+
if (!fullName) return null;
|
|
50835
|
+
let lookup;
|
|
50836
|
+
if (projects) lookup = buildProjectLookup(projects);
|
|
50837
|
+
else {
|
|
50838
|
+
const now = Date.now();
|
|
50839
|
+
if (!projectByRepo || now >= projectLookupExpiresAt) {
|
|
50840
|
+
projectByRepo = buildProjectLookup(listProjectsSync());
|
|
50841
|
+
projectLookupExpiresAt = now + PROJECT_LOOKUP_TTL_MS;
|
|
50842
|
+
}
|
|
50843
|
+
lookup = projectByRepo;
|
|
50844
|
+
}
|
|
50845
|
+
return lookup.get(fullName.toLowerCase()) ?? null;
|
|
50846
|
+
}
|
|
50847
|
+
/** Map a check_suite webhook payload only when its SHA was independently
|
|
50848
|
+
* verified as the current default-branch head. */
|
|
50849
|
+
function observationFromCheckSuite(payload, now, projects, authoritativeHeadSha) {
|
|
50850
|
+
const project = resolveProjectForRepo(payload.repository?.full_name, projects);
|
|
50851
|
+
const suite = payload.check_suite;
|
|
50852
|
+
if (!project || !suite) return null;
|
|
50853
|
+
if (suite.app?.slug !== "github-actions") return null;
|
|
50854
|
+
if (suite.head_branch !== project.branch) return null;
|
|
50855
|
+
if (!suite.head_sha || suite.id == null) return null;
|
|
50856
|
+
if (suite.head_sha !== authoritativeHeadSha) return null;
|
|
50857
|
+
return {
|
|
50858
|
+
projectKey: project.projectKey,
|
|
50859
|
+
repo: project.repo,
|
|
50860
|
+
branch: project.branch,
|
|
50861
|
+
headSha: suite.head_sha,
|
|
50862
|
+
suiteId: String(suite.id),
|
|
50863
|
+
status: suite.status ?? "queued",
|
|
50864
|
+
conclusion: suite.conclusion ?? null,
|
|
50865
|
+
observedAt: suite.updated_at ?? now,
|
|
50866
|
+
authoritativeHead: true
|
|
50867
|
+
};
|
|
50868
|
+
}
|
|
50869
|
+
//#endregion
|
|
51051
50870
|
//#region ../../lib/webhook-handlers.ts
|
|
51052
50871
|
/**
|
|
51053
50872
|
* GitHub webhook event handlers (PAN-905)
|
|
@@ -51059,6 +50878,7 @@ function isInGraphQLCooldown() {
|
|
|
51059
50878
|
init_review_status();
|
|
51060
50879
|
init_tracker_config();
|
|
51061
50880
|
init_errors();
|
|
50881
|
+
init_activity_logger();
|
|
51062
50882
|
function issueIdFromBranch(ref) {
|
|
51063
50883
|
const match = ref.match(/(?:feature|strike|bypass)\/([a-z]+-\d+)$/i);
|
|
51064
50884
|
return match ? match[1].toUpperCase() : null;
|
|
@@ -51189,7 +51009,7 @@ async function refreshMergeStateFromGitHub(issueId, repo, prNumber) {
|
|
|
51189
51009
|
let mergeState;
|
|
51190
51010
|
let isDraft;
|
|
51191
51011
|
let checksFailed;
|
|
51192
|
-
const { isGitHubAppConfigured, getPullRequestState } = await import("./github-app-
|
|
51012
|
+
const { isGitHubAppConfigured, getPullRequestState } = await import("./github-app-Oi5hdn1n.js");
|
|
51193
51013
|
if (isGitHubAppConfigured()) {
|
|
51194
51014
|
const prState = await Effect.runPromise(getPullRequestState(owner, repoName, prNumber));
|
|
51195
51015
|
mergeable = prState.mergeable === null ? "UNKNOWN" : prState.mergeable ? "MERGEABLE" : "CONFLICTING";
|
|
@@ -51265,6 +51085,19 @@ async function refreshMergeStateFromGitHub(issueId, repo, prNumber) {
|
|
|
51265
51085
|
}
|
|
51266
51086
|
}
|
|
51267
51087
|
async function handleCheckSuitePromise(payload) {
|
|
51088
|
+
const project = resolveProjectForRepo(payload.repository?.full_name);
|
|
51089
|
+
const projectSuite = payload.check_suite;
|
|
51090
|
+
if (project && projectSuite?.app?.slug === "github-actions" && projectSuite.head_branch === project.branch && projectSuite.head_sha && projectSuite.id != null) try {
|
|
51091
|
+
const authoritativeHead = await resolveDefaultBranchHead(project.repo, project.branch);
|
|
51092
|
+
const observation = observationFromCheckSuite(payload, (/* @__PURE__ */ new Date()).toISOString(), void 0, authoritativeHead);
|
|
51093
|
+
if (observation) await appendDomainEventAsync({
|
|
51094
|
+
type: "project.ci_suite_observed",
|
|
51095
|
+
timestamp: observation.observedAt,
|
|
51096
|
+
payload: observation
|
|
51097
|
+
});
|
|
51098
|
+
} catch (error) {
|
|
51099
|
+
console.warn("[webhook] Could not verify project CI branch head:", error);
|
|
51100
|
+
}
|
|
51268
51101
|
if (!isTrackedRepositorySync(payload.repository?.full_name)) return;
|
|
51269
51102
|
const suite = payload.check_suite;
|
|
51270
51103
|
if (!suite) return;
|
|
@@ -51339,9 +51172,24 @@ async function handlePullRequestPromise(payload) {
|
|
|
51339
51172
|
if (!issueId) return;
|
|
51340
51173
|
bumpIssuePrTabCacheGeneration(issueId);
|
|
51341
51174
|
const repo = payload.repository.full_name;
|
|
51175
|
+
if ([
|
|
51176
|
+
"opened",
|
|
51177
|
+
"closed",
|
|
51178
|
+
"reopened"
|
|
51179
|
+
].includes(payload.action ?? "")) try {
|
|
51180
|
+
const { listProjectsSync, resolveProjectFromIssueSync } = await import("./projects-LftaVK99.js");
|
|
51181
|
+
const resolved = resolveProjectFromIssueSync(issueId);
|
|
51182
|
+
const project = resolved ? listProjectsSync().find((entry) => entry.key === resolved.projectKey)?.config : void 0;
|
|
51183
|
+
if (project) {
|
|
51184
|
+
const { enqueueProjectResourceRefresh } = await import("./project-resource-refresh-queue-BaZC79S3.js");
|
|
51185
|
+
enqueueProjectResourceRefresh(project, `pull_request:${payload.action}`);
|
|
51186
|
+
}
|
|
51187
|
+
} catch (err) {
|
|
51188
|
+
console.warn(`[webhook] Failed to enqueue membership refresh for ${issueId}: ${err?.message ?? err}`);
|
|
51189
|
+
}
|
|
51342
51190
|
if (payload.action === "closed" && pr.merged === true) try {
|
|
51343
|
-
const { postMergeLifecycle } = await import("./merge-agent-
|
|
51344
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
51191
|
+
const { postMergeLifecycle } = await import("./merge-agent-BuoC_PRZ.js");
|
|
51192
|
+
const { resolveProjectFromIssueSync } = await import("./projects-LftaVK99.js");
|
|
51345
51193
|
const project = resolveProjectFromIssueSync(issueId);
|
|
51346
51194
|
if (project) {
|
|
51347
51195
|
const branchName = pr.head.ref;
|
|
@@ -51647,6 +51495,7 @@ init_providers();
|
|
|
51647
51495
|
init_paths();
|
|
51648
51496
|
init_behavior();
|
|
51649
51497
|
init_tmux();
|
|
51498
|
+
init_jsonl_resolver();
|
|
51650
51499
|
const execFileAsync$4 = promisify(execFile);
|
|
51651
51500
|
const SAFE_MODEL_PATTERN = MODEL_ID_PATTERN;
|
|
51652
51501
|
const SESSION_FILE_MISS_TTL_MS = 2e3;
|
|
@@ -51748,11 +51597,11 @@ function parseSummaryForkFocus(value) {
|
|
|
51748
51597
|
ok: true,
|
|
51749
51598
|
focus: void 0
|
|
51750
51599
|
};
|
|
51751
|
-
if (focus.length >
|
|
51600
|
+
if (focus.length > 1e4) return {
|
|
51752
51601
|
ok: false,
|
|
51753
|
-
error: "focus must be
|
|
51602
|
+
error: "focus must be 10000 characters or fewer"
|
|
51754
51603
|
};
|
|
51755
|
-
if (/[\x00-\x1f\x7f]/u.test(focus)) return {
|
|
51604
|
+
if (/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/u.test(focus)) return {
|
|
51756
51605
|
ok: false,
|
|
51757
51606
|
error: "focus must not contain control characters"
|
|
51758
51607
|
};
|
|
@@ -51865,13 +51714,21 @@ async function injectForkSummary(conv, summary, caller) {
|
|
|
51865
51714
|
if (outcome === "accepted") return "submitted";
|
|
51866
51715
|
const normalizePaneVerification = (value) => value.replace(/[─-╿]/g, "").replace(/\s+/g, "");
|
|
51867
51716
|
const verify = normalizePaneVerification(deliveryVerifyLine(summary).slice(0, 40));
|
|
51717
|
+
const composerStillHoldsPayload = async () => {
|
|
51718
|
+
if (verify.length < 3) return false;
|
|
51719
|
+
const viewport = await capturePaneViewport(conv.tmuxSession);
|
|
51720
|
+
if (viewport) {
|
|
51721
|
+
const composer = activeComposerRegion(viewport);
|
|
51722
|
+
if (composer !== null) return normalizePaneVerification(composer).includes(verify);
|
|
51723
|
+
}
|
|
51724
|
+
return normalizePaneVerification(await capturePaneText(conv.tmuxSession, 40)).includes(verify);
|
|
51725
|
+
};
|
|
51868
51726
|
for (let nudge = 1; nudge <= 2; nudge++) {
|
|
51869
|
-
|
|
51870
|
-
if (!(verify.length >= 3 && normalizePaneVerification(pane).includes(verify))) return outcome === "unknown" ? "submitted" : "stranded";
|
|
51727
|
+
if (!await composerStillHoldsPayload()) return outcome === "unknown" ? "submitted" : "stranded";
|
|
51871
51728
|
console.warn(`[${caller}] ${conv.name} still has the delivered summary in its composer — sending standalone Enter (${nudge}/2)`);
|
|
51872
51729
|
await sendKeysAsync(conv.tmuxSession, "C-m", `${caller}:enter-nudge`);
|
|
51873
51730
|
if (await confirmForkPromptAccepted(conv.tmuxSession, 8e3) === "accepted") return "submitted";
|
|
51874
|
-
if (!
|
|
51731
|
+
if (!await composerStillHoldsPayload()) return "submitted";
|
|
51875
51732
|
}
|
|
51876
51733
|
return "stranded";
|
|
51877
51734
|
}
|
|
@@ -51904,7 +51761,7 @@ async function runForkPipeline(convName, parentConv, sessionId, summaryModel, fo
|
|
|
51904
51761
|
let forkFallbackReason = null;
|
|
51905
51762
|
const buildSummary = async () => {
|
|
51906
51763
|
if (localSummaryOnly) try {
|
|
51907
|
-
return await Effect.runPromise(generateFallbackSummary(parentSessionFile));
|
|
51764
|
+
return await Effect.runPromise(generateFallbackSummary(parentSessionFile, parentConv.harness ?? void 0));
|
|
51908
51765
|
} catch (error) {
|
|
51909
51766
|
console.warn(`[fork-pipeline] Heuristic fallback summary failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
51910
51767
|
return "";
|
|
@@ -51915,7 +51772,7 @@ async function runForkPipeline(convName, parentConv, sessionId, summaryModel, fo
|
|
|
51915
51772
|
if (!forkFallbackReason) forkFallbackReason = `LLM summary failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
51916
51773
|
console.warn(`[fork-pipeline] LLM summary failed, falling back to heuristic: ${error instanceof Error ? error.message : String(error)}`);
|
|
51917
51774
|
try {
|
|
51918
|
-
return await Effect.runPromise(generateFallbackSummary(parentSessionFile));
|
|
51775
|
+
return await Effect.runPromise(generateFallbackSummary(parentSessionFile, parentConv.harness ?? void 0));
|
|
51919
51776
|
} catch (heuristicError) {
|
|
51920
51777
|
console.warn(`[fork-pipeline] Heuristic fallback also failed: ${heuristicError instanceof Error ? heuristicError.message : String(heuristicError)}`);
|
|
51921
51778
|
return "";
|
|
@@ -52206,7 +52063,7 @@ startConversationModelBackfill(resolveSessionFile);
|
|
|
52206
52063
|
function conversationReadJson(response) {
|
|
52207
52064
|
return jsonResponse(response.body, response.status === void 0 ? void 0 : { status: response.status });
|
|
52208
52065
|
}
|
|
52209
|
-
const readJsonBody$
|
|
52066
|
+
const readJsonBody$10 = Effect.gen(function* () {
|
|
52210
52067
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
52211
52068
|
try {
|
|
52212
52069
|
return text ? JSON.parse(text) : {};
|
|
@@ -52266,7 +52123,7 @@ const postConversationRoute = HttpRouter.add("POST", "/api/conversations", Effec
|
|
|
52266
52123
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
52267
52124
|
const originCheck = validateOrigin$1(request);
|
|
52268
52125
|
if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
|
|
52269
|
-
const body = yield* readJsonBody$
|
|
52126
|
+
const body = yield* readJsonBody$10;
|
|
52270
52127
|
const reqOrigin = getHeader(request, "origin") ?? "none";
|
|
52271
52128
|
const reqReferer = getHeader(request, "referer") ?? "none";
|
|
52272
52129
|
const reqUserAgent = getHeader(request, "user-agent") ?? "none";
|
|
@@ -52281,18 +52138,24 @@ const postConversationStopRoute = HttpRouter.add("POST", "/api/conversations/:na
|
|
|
52281
52138
|
const name = (yield* HttpRouter.params)["name"] ?? "";
|
|
52282
52139
|
return yield* Effect.promise(async () => handleConversationStop(name, { resolveSessionFileForCleanup: (conv) => conv.sessionFile ?? null }));
|
|
52283
52140
|
}));
|
|
52141
|
+
const postConversationClearForkStateRoute = HttpRouter.add("POST", "/api/conversations/:name/clear-fork-state", Effect.gen(function* () {
|
|
52142
|
+
const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
|
|
52143
|
+
if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
|
|
52144
|
+
const params = yield* HttpRouter.params;
|
|
52145
|
+
return yield* Effect.promise(() => handleConversationClearForkState(params["name"] ?? ""));
|
|
52146
|
+
}));
|
|
52284
52147
|
const postConversationResumeRoute = HttpRouter.add("POST", "/api/conversations/:name/resume", Effect.gen(function* () {
|
|
52285
52148
|
const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
|
|
52286
52149
|
if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
|
|
52287
52150
|
const name = (yield* HttpRouter.params)["name"] ?? "";
|
|
52288
|
-
const body = yield* readJsonBody$
|
|
52151
|
+
const body = yield* readJsonBody$10;
|
|
52289
52152
|
return yield* Effect.promise(async () => handleConversationResume(name, body, { resolveSessionFile }));
|
|
52290
52153
|
}));
|
|
52291
52154
|
const postConversationSwitchModelRoute = HttpRouter.add("POST", "/api/conversations/:name/switch-model", Effect.gen(function* () {
|
|
52292
52155
|
const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
|
|
52293
52156
|
if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
|
|
52294
52157
|
const name = (yield* HttpRouter.params)["name"] ?? "";
|
|
52295
|
-
const body = yield* readJsonBody$
|
|
52158
|
+
const body = yield* readJsonBody$10;
|
|
52296
52159
|
return yield* Effect.promise(async () => {
|
|
52297
52160
|
try {
|
|
52298
52161
|
return await handleConversationSwitchModel(name, body);
|
|
@@ -52307,7 +52170,7 @@ const postConversationThinkingLevelRoute = HttpRouter.add("POST", "/api/conversa
|
|
|
52307
52170
|
const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
|
|
52308
52171
|
if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
|
|
52309
52172
|
const name = (yield* HttpRouter.params)["name"] ?? "";
|
|
52310
|
-
const body = yield* readJsonBody$
|
|
52173
|
+
const body = yield* readJsonBody$10;
|
|
52311
52174
|
return yield* Effect.promise(async () => {
|
|
52312
52175
|
try {
|
|
52313
52176
|
return await handleConversationThinkingLevel(name, body);
|
|
@@ -52404,7 +52267,7 @@ const postConversationDeleteImageRoute = HttpRouter.add("POST", "/api/conversati
|
|
|
52404
52267
|
const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
|
|
52405
52268
|
if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
|
|
52406
52269
|
const name = (yield* HttpRouter.params)["name"] ?? "";
|
|
52407
|
-
const body = yield* readJsonBody$
|
|
52270
|
+
const body = yield* readJsonBody$10;
|
|
52408
52271
|
return yield* Effect.promise(async () => {
|
|
52409
52272
|
try {
|
|
52410
52273
|
return await handleConversationImageDelete(name, body);
|
|
@@ -52419,7 +52282,7 @@ const postConversationMessageRoute = HttpRouter.add("POST", "/api/conversations/
|
|
|
52419
52282
|
const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
|
|
52420
52283
|
if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
|
|
52421
52284
|
const name = (yield* HttpRouter.params)["name"] ?? "";
|
|
52422
|
-
const body = yield* readJsonBody$
|
|
52285
|
+
const body = yield* readJsonBody$10;
|
|
52423
52286
|
return yield* Effect.promise(async () => {
|
|
52424
52287
|
try {
|
|
52425
52288
|
return await handleConversationMessage(name, body, conversationMessageDependencies);
|
|
@@ -52439,14 +52302,14 @@ const postConversationCodexApprovalRoute = HttpRouter.add("POST", "/api/conversa
|
|
|
52439
52302
|
const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
|
|
52440
52303
|
if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
|
|
52441
52304
|
const rawId = (yield* HttpRouter.params)["id"] ?? "";
|
|
52442
|
-
const body = yield* readJsonBody$
|
|
52305
|
+
const body = yield* readJsonBody$10;
|
|
52443
52306
|
return yield* Effect.promise(() => handleConversationCodexApproval(rawId, body));
|
|
52444
52307
|
}));
|
|
52445
52308
|
const postConversationPaneChoiceRoute = HttpRouter.add("POST", "/api/conversations/:id/pane-choice", Effect.gen(function* () {
|
|
52446
52309
|
const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
|
|
52447
52310
|
if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
|
|
52448
52311
|
const rawId = (yield* HttpRouter.params)["id"] ?? "";
|
|
52449
|
-
const body = yield* readJsonBody$
|
|
52312
|
+
const body = yield* readJsonBody$10;
|
|
52450
52313
|
return yield* Effect.promise(async () => {
|
|
52451
52314
|
const result = await handleConversationPaneChoiceAnswer(rawId, body);
|
|
52452
52315
|
return jsonResponse(result.body, { status: result.status });
|
|
@@ -52456,7 +52319,7 @@ const postConversationDeliveryMethodRoute = HttpRouter.add("POST", "/api/convers
|
|
|
52456
52319
|
const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
|
|
52457
52320
|
if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
|
|
52458
52321
|
const name = (yield* HttpRouter.params)["name"] ?? "";
|
|
52459
|
-
const body = yield* readJsonBody$
|
|
52322
|
+
const body = yield* readJsonBody$10;
|
|
52460
52323
|
return yield* Effect.promise(async () => {
|
|
52461
52324
|
try {
|
|
52462
52325
|
return await handleConversationDeliveryMethod(name, body);
|
|
@@ -52471,7 +52334,7 @@ const postConversationControlAckRoute = HttpRouter.add("POST", "/api/conversatio
|
|
|
52471
52334
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
52472
52335
|
const originCheck = validateConversationControlAckOrigin(request.headers, request.method);
|
|
52473
52336
|
if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
|
|
52474
|
-
const body = yield* readJsonBody$
|
|
52337
|
+
const body = yield* readJsonBody$10;
|
|
52475
52338
|
return yield* Effect.promise(async () => {
|
|
52476
52339
|
try {
|
|
52477
52340
|
const result = handleConversationControlAck(body);
|
|
@@ -52487,7 +52350,7 @@ const patchConversationRoute = HttpRouter.add("PATCH", "/api/conversations/:name
|
|
|
52487
52350
|
const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
|
|
52488
52351
|
if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
|
|
52489
52352
|
const name = (yield* HttpRouter.params)["name"] ?? "";
|
|
52490
|
-
const body = yield* readJsonBody$
|
|
52353
|
+
const body = yield* readJsonBody$10;
|
|
52491
52354
|
return yield* Effect.promise(async () => {
|
|
52492
52355
|
try {
|
|
52493
52356
|
const result = patchConversationTitle(name, body);
|
|
@@ -52504,7 +52367,7 @@ const patchConversationMoveRoute = HttpRouter.add("PATCH", "/api/conversations/:
|
|
|
52504
52367
|
if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
|
|
52505
52368
|
const params = yield* HttpRouter.params;
|
|
52506
52369
|
const name = decodeURIComponent(params["name"] ?? "");
|
|
52507
|
-
const body = yield* readJsonBody$
|
|
52370
|
+
const body = yield* readJsonBody$10;
|
|
52508
52371
|
return yield* Effect.promise(async () => {
|
|
52509
52372
|
try {
|
|
52510
52373
|
const result = await handleConversationMove(name, body, { invalidateListEnrichmentCache: invalidateConversationListEnrichmentCache });
|
|
@@ -52591,14 +52454,14 @@ const postConversationSummaryForkRoute = HttpRouter.add("POST", "/api/conversati
|
|
|
52591
52454
|
if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
|
|
52592
52455
|
const params = yield* HttpRouter.params;
|
|
52593
52456
|
const name = decodeURIComponent(params["name"] ?? "");
|
|
52594
|
-
const body = yield* readJsonBody$
|
|
52457
|
+
const body = yield* readJsonBody$10;
|
|
52595
52458
|
return yield* Effect.promise(() => handleConversationSummaryFork(name, body));
|
|
52596
52459
|
}));
|
|
52597
52460
|
const postConversationPlanActionRoute = HttpRouter.add("POST", "/api/conversations/:name/plan-action", Effect.gen(function* () {
|
|
52598
52461
|
const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
|
|
52599
52462
|
if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
|
|
52600
52463
|
const name = (yield* HttpRouter.params)["name"] ?? "";
|
|
52601
|
-
const body = yield* readJsonBody$
|
|
52464
|
+
const body = yield* readJsonBody$10;
|
|
52602
52465
|
return yield* Effect.promise(() => handleConversationPlanAction(name, body));
|
|
52603
52466
|
}));
|
|
52604
52467
|
const conversationDiffDependencies = {
|
|
@@ -52653,7 +52516,7 @@ const getConversationAboutRoute = HttpRouter.add("GET", "/api/conversations/:nam
|
|
|
52653
52516
|
return conversationReadJson(await getConversationAbout(name, new URL(request.url, "http://localhost").searchParams.get("refresh") === "1", conversationReadDependencies));
|
|
52654
52517
|
});
|
|
52655
52518
|
}));
|
|
52656
|
-
const conversationsRouteLayer = Layer.mergeAll(getConversationsRoute, getConversationsPendingInputRoute, getArchivedConversationsRoute, getConversationRoute, getConversationHandoffDocRoute, postConversationRoute, patchConversationRoute, patchConversationMoveRoute, deleteConversationRoute, postConversationStopRoute, postConversationResumeRoute, postConversationSwitchModelRoute, postConversationThinkingLevelRoute, postConversationCompactRoute, postConversationAbortRoute, postConversationRestartAllRoute, postConversationArchiveRoute, postConversationUnarchiveRoute, getConversationMessagesRoute, getConversationMessageLocatorRoute, postConversationUploadImageRoute, postConversationDeleteImageRoute, postConversationMessageRoute, postConversationCodexApprovalRoute, postConversationPaneChoiceRoute, postConversationDeliveryMethodRoute, postConversationControlAckRoute, postConversationFavoriteRoute, deleteConversationFavoriteRoute, postConversationSummaryForkRoute, postConversationPlanActionRoute, getConversationDiffsRoute, getConversationDiffFullRoute, getConversationDiffTurnRoute, postConversationRetitleRoute, getConversationAboutRoute);
|
|
52519
|
+
const conversationsRouteLayer = Layer.mergeAll(getConversationsRoute, getConversationsPendingInputRoute, getArchivedConversationsRoute, getConversationRoute, getConversationHandoffDocRoute, postConversationRoute, patchConversationRoute, patchConversationMoveRoute, deleteConversationRoute, postConversationStopRoute, postConversationClearForkStateRoute, postConversationResumeRoute, postConversationSwitchModelRoute, postConversationThinkingLevelRoute, postConversationCompactRoute, postConversationAbortRoute, postConversationRestartAllRoute, postConversationArchiveRoute, postConversationUnarchiveRoute, getConversationMessagesRoute, getConversationMessageLocatorRoute, postConversationUploadImageRoute, postConversationDeleteImageRoute, postConversationMessageRoute, postConversationCodexApprovalRoute, postConversationPaneChoiceRoute, postConversationDeliveryMethodRoute, postConversationControlAckRoute, postConversationFavoriteRoute, deleteConversationFavoriteRoute, postConversationSummaryForkRoute, postConversationPlanActionRoute, getConversationDiffsRoute, getConversationDiffFullRoute, getConversationDiffTurnRoute, postConversationRetitleRoute, getConversationAboutRoute);
|
|
52657
52520
|
//#endregion
|
|
52658
52521
|
//#region routes/show.ts
|
|
52659
52522
|
/**
|
|
@@ -52700,7 +52563,7 @@ const showRouteLayer = Layer.mergeAll(getShowRoute, getShowShadowRoute, getShowH
|
|
|
52700
52563
|
//#endregion
|
|
52701
52564
|
//#region routes/project-rename.ts
|
|
52702
52565
|
init_projects();
|
|
52703
|
-
const readJsonBody$
|
|
52566
|
+
const readJsonBody$9 = Effect.gen(function* () {
|
|
52704
52567
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
52705
52568
|
try {
|
|
52706
52569
|
return text ? JSON.parse(text) : {};
|
|
@@ -52712,7 +52575,7 @@ const postProjectRenameRoute = HttpRouter.add("POST", "/api/projects/:projectKey
|
|
|
52712
52575
|
const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
|
|
52713
52576
|
if (authError) return authError;
|
|
52714
52577
|
const projectIdentifier = (yield* HttpRouter.params)["projectKey"] ?? "";
|
|
52715
|
-
const body = yield* readJsonBody$
|
|
52578
|
+
const body = yield* readJsonBody$9;
|
|
52716
52579
|
if (typeof body.name !== "string") return jsonResponse({ error: "Project name must be a string" }, { status: 400 });
|
|
52717
52580
|
const result = yield* Effect.result(renameProject(projectIdentifier, body.name));
|
|
52718
52581
|
if (Result$1.isFailure(result)) {
|
|
@@ -52860,7 +52723,7 @@ async function registerProjectFromPath(opts) {
|
|
|
52860
52723
|
registerProjectSync(key, projectConfig);
|
|
52861
52724
|
const seededContextLayer = ensureProjectLayer(fullPath);
|
|
52862
52725
|
try {
|
|
52863
|
-
const { preTrustDirectorySync } = await import("./workspace-manager-
|
|
52726
|
+
const { preTrustDirectorySync } = await import("./workspace-manager-jfkKAEuO.js");
|
|
52864
52727
|
preTrustDirectorySync(fullPath);
|
|
52865
52728
|
} catch {}
|
|
52866
52729
|
let hooksInstalled = 0;
|
|
@@ -52880,6 +52743,7 @@ init_render();
|
|
|
52880
52743
|
init_assemble();
|
|
52881
52744
|
init_agents$1();
|
|
52882
52745
|
init_projects();
|
|
52746
|
+
init_jsonl_resolver();
|
|
52883
52747
|
function awaitingInputFromProjection(agentId, agentSnapshotsById) {
|
|
52884
52748
|
const agent = agentSnapshotsById?.get(agentId);
|
|
52885
52749
|
if (!agent) return void 0;
|
|
@@ -52998,7 +52862,6 @@ async function buildSpecialistSessionNodes(options) {
|
|
|
52998
52862
|
}
|
|
52999
52863
|
//#endregion
|
|
53000
52864
|
//#region ../../lib/overdeck/specs.ts
|
|
53001
|
-
init_specs();
|
|
53002
52865
|
const findSpecByIssueThroughOverdeck = findSpecByIssue;
|
|
53003
52866
|
//#endregion
|
|
53004
52867
|
//#region routes/projects.ts
|
|
@@ -53015,6 +52878,7 @@ init_concurrency$1();
|
|
|
53015
52878
|
init_src();
|
|
53016
52879
|
init_agents$1();
|
|
53017
52880
|
init_agent_input_detection();
|
|
52881
|
+
init_jsonl_resolver();
|
|
53018
52882
|
init_pan_dir();
|
|
53019
52883
|
init_io();
|
|
53020
52884
|
init_specs();
|
|
@@ -53022,7 +52886,7 @@ init_paths();
|
|
|
53022
52886
|
init_resource_utils();
|
|
53023
52887
|
const execAsync$3 = promisify(exec);
|
|
53024
52888
|
async function getIssueDataService() {
|
|
53025
|
-
const { getSharedIssueService } = await import("./issue-service-singleton-
|
|
52889
|
+
const { getSharedIssueService } = await import("./issue-service-singleton-CvgNAWqK.js");
|
|
53026
52890
|
return getSharedIssueService();
|
|
53027
52891
|
}
|
|
53028
52892
|
/** Returns true if the path exists (any type). */
|
|
@@ -53424,7 +53288,7 @@ const getProjectReleaseStatusRoute = HttpRouter.add("GET", "/api/projects/:proje
|
|
|
53424
53288
|
const projectKey = (yield* HttpRouter.params)["projectKey"] ?? "";
|
|
53425
53289
|
return jsonResponse(yield* Effect.tryPromise({
|
|
53426
53290
|
try: async () => {
|
|
53427
|
-
const { fetchProjectReleaseStatus } = await import("./project-pipelines-
|
|
53291
|
+
const { fetchProjectReleaseStatus } = await import("./project-pipelines-By_5WcT4.js");
|
|
53428
53292
|
return fetchProjectReleaseStatus(projectKey);
|
|
53429
53293
|
},
|
|
53430
53294
|
catch: (err) => new Error(err instanceof Error ? err.message : String(err))
|
|
@@ -53735,7 +53599,7 @@ init_projects();
|
|
|
53735
53599
|
const getProjectMergeTrainRoute = HttpRouter.add("GET", "/api/projects/:projectKey/merge-train", httpHandler(Effect.gen(function* () {
|
|
53736
53600
|
const config = getProjectSync((yield* HttpRouter.params)["projectKey"] ?? "");
|
|
53737
53601
|
if (!config) return jsonResponse({ error: "Project not found" }, { status: 404 });
|
|
53738
|
-
const { isMergeTrainEnabledForProject } = yield* Effect.promise(() => import("./merge-sync-
|
|
53602
|
+
const { isMergeTrainEnabledForProject } = yield* Effect.promise(() => import("./merge-sync-0m2Q087q.js"));
|
|
53739
53603
|
return jsonResponse({
|
|
53740
53604
|
value: config.merge_train ?? null,
|
|
53741
53605
|
effective: isMergeTrainEnabledForProject(config)
|
|
@@ -53749,7 +53613,7 @@ const postProjectMergeTrainRoute = HttpRouter.add("POST", "/api/projects/:projec
|
|
|
53749
53613
|
if (!project) return jsonResponse({ error: "Project not found" }, { status: 404 });
|
|
53750
53614
|
const v = (yield* readProjectJsonBody).value;
|
|
53751
53615
|
if (v !== "enabled" && v !== "disabled" && v !== null) return jsonResponse({ error: "value must be 'enabled', 'disabled', or null" }, { status: 400 });
|
|
53752
|
-
const { isMergeTrainEnabledForProject } = yield* Effect.promise(() => import("./merge-sync-
|
|
53616
|
+
const { isMergeTrainEnabledForProject } = yield* Effect.promise(() => import("./merge-sync-0m2Q087q.js"));
|
|
53753
53617
|
yield* Effect.promise(() => setProjectMergeTrain(key, v));
|
|
53754
53618
|
const updated = { ...project };
|
|
53755
53619
|
if (v === null) delete updated.merge_train;
|
|
@@ -53827,7 +53691,7 @@ async function queueEntryForProject(key, config, enabled) {
|
|
|
53827
53691
|
* not blank the whole response, so a failed project reports an empty queue.
|
|
53828
53692
|
*/
|
|
53829
53693
|
async function getMergeTrainQueuesPayload() {
|
|
53830
|
-
const { isMergeTrainEnabledForProject } = await import("./merge-sync-
|
|
53694
|
+
const { isMergeTrainEnabledForProject } = await import("./merge-sync-0m2Q087q.js");
|
|
53831
53695
|
const projects = listProjectsSync();
|
|
53832
53696
|
return (await Promise.allSettled(projects.map(({ key, config }) => queueEntryForProject(key, config, isMergeTrainEnabledForProject(config))))).flatMap((outcome, i) => {
|
|
53833
53697
|
if (outcome.status === "fulfilled") return [outcome.value];
|
|
@@ -53845,8 +53709,8 @@ async function getMergeTrainQueuesPayload() {
|
|
|
53845
53709
|
}
|
|
53846
53710
|
/** PAN-1696 AC2: per-project generation chains across every tracked project. */
|
|
53847
53711
|
async function getMergeTrainGenerationsPayload() {
|
|
53848
|
-
const { isMergeTrainEnabledForProject } = await import("./merge-sync-
|
|
53849
|
-
const { getUatGenerationsPayload } = await import("./uat-train-
|
|
53712
|
+
const { isMergeTrainEnabledForProject } = await import("./merge-sync-0m2Q087q.js");
|
|
53713
|
+
const { getUatGenerationsPayload } = await import("./uat-train-CycEzpbE.js");
|
|
53850
53714
|
return (await Promise.allSettled(listProjectsSync().map(async ({ key, config }) => ({
|
|
53851
53715
|
projectKey: key,
|
|
53852
53716
|
projectName: config.name,
|
|
@@ -53860,7 +53724,7 @@ async function defaultOrderedIssueIdsForProject(projectPath) {
|
|
|
53860
53724
|
return (await Effect.runPromise(computeMergeQueueFromCandidates(candidates, projectPath).pipe(Effect.provide(layer)))).map((item) => item.issueId);
|
|
53861
53725
|
}
|
|
53862
53726
|
async function defaultMergeOne(issueId) {
|
|
53863
|
-
const { triggerMerge } = await import("./merge-ops-
|
|
53727
|
+
const { triggerMerge } = await import("./merge-ops-DabXHp2i.js");
|
|
53864
53728
|
const r = await triggerMerge(issueId);
|
|
53865
53729
|
return r.success ? { ok: true } : {
|
|
53866
53730
|
ok: false,
|
|
@@ -53888,13 +53752,13 @@ async function postMergeTrainMergeNextPayload(payload, deps = {}) {
|
|
|
53888
53752
|
status: 404,
|
|
53889
53753
|
body: { error: `Unknown project key: ${projectKey}` }
|
|
53890
53754
|
};
|
|
53891
|
-
const { isMergeTrainEnabledForProject } = await import("./merge-sync-
|
|
53755
|
+
const { isMergeTrainEnabledForProject } = await import("./merge-sync-0m2Q087q.js");
|
|
53892
53756
|
if (!isMergeTrainEnabledForProject(config)) return {
|
|
53893
53757
|
status: 409,
|
|
53894
53758
|
body: { error: `merge-train is disabled for project ${projectKey}` }
|
|
53895
53759
|
};
|
|
53896
53760
|
const issueIds = (await (deps.getOrderedIssueIds ?? defaultOrderedIssueIdsForProject)(resolve(config.path))).slice(0, n);
|
|
53897
|
-
const { shipMergeBatch } = await import("./merge-batch-
|
|
53761
|
+
const { shipMergeBatch } = await import("./merge-batch-B8bVjFWS.js");
|
|
53898
53762
|
return {
|
|
53899
53763
|
status: 200,
|
|
53900
53764
|
body: {
|
|
@@ -53924,7 +53788,7 @@ async function postMergeTrainAssemblePayload(payload) {
|
|
|
53924
53788
|
status: 404,
|
|
53925
53789
|
body: { error: `Unknown project key: ${projectKey}` }
|
|
53926
53790
|
};
|
|
53927
|
-
const { runUatTrainReconcile } = await import("./uat-train-
|
|
53791
|
+
const { runUatTrainReconcile } = await import("./uat-train-CycEzpbE.js");
|
|
53928
53792
|
return {
|
|
53929
53793
|
status: 200,
|
|
53930
53794
|
body: { projects: [{
|
|
@@ -53936,7 +53800,7 @@ async function postMergeTrainAssemblePayload(payload) {
|
|
|
53936
53800
|
}] }
|
|
53937
53801
|
};
|
|
53938
53802
|
}
|
|
53939
|
-
const { runUatTrainReconcileAllProjects } = await import("./uat-train-
|
|
53803
|
+
const { runUatTrainReconcileAllProjects } = await import("./uat-train-CycEzpbE.js");
|
|
53940
53804
|
return {
|
|
53941
53805
|
status: 200,
|
|
53942
53806
|
body: { projects: await runUatTrainReconcileAllProjects({ force: true }) }
|
|
@@ -53952,13 +53816,13 @@ function uatGenerationNameFromParam(param) {
|
|
|
53952
53816
|
return decoded.startsWith("uat/") ? decoded : `uat/${decoded}`;
|
|
53953
53817
|
}
|
|
53954
53818
|
async function postMergeTrainGenerationShipPayload(name, version) {
|
|
53955
|
-
const { getUatGenerationSync } = await import("./merge-sync-
|
|
53819
|
+
const { getUatGenerationSync } = await import("./merge-sync-0m2Q087q.js");
|
|
53956
53820
|
const generation = getUatGenerationSync(name);
|
|
53957
53821
|
if (!generation) return {
|
|
53958
53822
|
status: 404,
|
|
53959
53823
|
body: { error: `No UAT generation named ${name}` }
|
|
53960
53824
|
};
|
|
53961
|
-
const { shipPromotedBatch, ShipPromotedBatchError } = await import("./ship-record-
|
|
53825
|
+
const { shipPromotedBatch, ShipPromotedBatchError } = await import("./ship-record-DHWH1hLz.js");
|
|
53962
53826
|
try {
|
|
53963
53827
|
return {
|
|
53964
53828
|
status: 200,
|
|
@@ -53986,7 +53850,7 @@ const postMergeTrainGenerationStackRoute = HttpRouter.add("POST", "/api/merge-tr
|
|
|
53986
53850
|
const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
|
|
53987
53851
|
if (authError) return authError;
|
|
53988
53852
|
const name = uatGenerationNameFromParam((yield* HttpRouter.params)["name"] ?? "");
|
|
53989
|
-
const { postUatGenerationStackPayload } = yield* Effect.promise(() => import("./uat-train-
|
|
53853
|
+
const { postUatGenerationStackPayload } = yield* Effect.promise(() => import("./uat-train-CycEzpbE.js"));
|
|
53990
53854
|
const result = yield* Effect.promise(() => postUatGenerationStackPayload(name));
|
|
53991
53855
|
if (!result.ok) return jsonResponse({ error: result.error }, { status: result.status });
|
|
53992
53856
|
return jsonResponse({
|
|
@@ -54003,8 +53867,8 @@ const postMergeTrainGenerationPromoteRoute = HttpRouter.add("POST", "/api/merge-
|
|
|
54003
53867
|
const rawShipVersion = parsed.body["shipVersion"];
|
|
54004
53868
|
if (rawShipVersion !== void 0 && (typeof rawShipVersion !== "string" || !/^\d+\.\d+\.\d+$/.test(rawShipVersion))) return jsonResponse({ error: "shipVersion must look like 48.8.0" }, { status: 400 });
|
|
54005
53869
|
const name = uatGenerationNameFromParam((yield* HttpRouter.params)["name"] ?? "");
|
|
54006
|
-
const { postUatGenerationPromotePayload } = yield* Effect.promise(() => import("./uat-train-
|
|
54007
|
-
const { firePostMergeLifecycle } = yield* Effect.promise(() => import("./specialists-
|
|
53870
|
+
const { postUatGenerationPromotePayload } = yield* Effect.promise(() => import("./uat-train-CycEzpbE.js"));
|
|
53871
|
+
const { firePostMergeLifecycle } = yield* Effect.promise(() => import("./specialists-B-4zyE4Y.js"));
|
|
54008
53872
|
const result = yield* Effect.promise(() => postUatGenerationPromotePayload(name, firePostMergeLifecycle, rawShipVersion));
|
|
54009
53873
|
if (!result.success) return jsonResponse(result, { status: result.reason === "not-found" ? 404 : result.reason === "merge-failed" ? 500 : 409 });
|
|
54010
53874
|
return jsonResponse(result);
|
|
@@ -54276,8 +54140,9 @@ function parseRule(raw) {
|
|
|
54276
54140
|
}
|
|
54277
54141
|
async function renderBundledRulesAsync(harness) {
|
|
54278
54142
|
const includeDev = isDevMode();
|
|
54143
|
+
const disabled = configDisabledRuleNames();
|
|
54279
54144
|
const entries = await readdir(SYNC_SOURCES.rules, { withFileTypes: true }).catch(() => []);
|
|
54280
|
-
const rendered = (await Promise.all(entries.filter((entry) => entry.isFile() && entry.name.endsWith(".md")).sort((a, b) => a.name.localeCompare(b.name)).map(async (entry) => {
|
|
54145
|
+
const rendered = (await Promise.all(entries.filter((entry) => entry.isFile() && entry.name.endsWith(".md")).filter((entry) => !disabled.has(entry.name.replace(/\.md$/, ""))).sort((a, b) => a.name.localeCompare(b.name)).map(async (entry) => {
|
|
54281
54146
|
const file = join(SYNC_SOURCES.rules, entry.name);
|
|
54282
54147
|
assertPathInside(SYNC_SOURCES.rules, file);
|
|
54283
54148
|
const rule = parseRule(await readFile(file, "utf-8"));
|
|
@@ -54443,7 +54308,7 @@ function issueIdFromWorkspacePath(workspacePath) {
|
|
|
54443
54308
|
const match = /(?:^|[^a-z0-9])([a-z]+-\d+)(?:[^a-z0-9]|$)/i.exec(workspacePath);
|
|
54444
54309
|
return match ? match[1].toUpperCase() : null;
|
|
54445
54310
|
}
|
|
54446
|
-
function readJsonBody$
|
|
54311
|
+
function readJsonBody$8() {
|
|
54447
54312
|
return Effect.gen(function* () {
|
|
54448
54313
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
54449
54314
|
return text ? JSON.parse(text) : {};
|
|
@@ -54457,7 +54322,7 @@ const getContextLayersRoute = HttpRouter.add("GET", "/api/context/layers", httpH
|
|
|
54457
54322
|
return jsonResponse(yield* Effect.promise(() => loadContextLayers(projects)));
|
|
54458
54323
|
})));
|
|
54459
54324
|
const postContextPreviewRoute = HttpRouter.add("POST", "/api/context/preview", httpHandler(Effect.gen(function* () {
|
|
54460
|
-
const body = yield* readJsonBody$
|
|
54325
|
+
const body = yield* readJsonBody$8();
|
|
54461
54326
|
const parsed = yield* Effect.try({
|
|
54462
54327
|
try: () => decodePreviewRequest(body),
|
|
54463
54328
|
catch: (error) => new Error(error instanceof Error ? error.message : String(error))
|
|
@@ -54466,7 +54331,7 @@ const postContextPreviewRoute = HttpRouter.add("POST", "/api/context/preview", h
|
|
|
54466
54331
|
return jsonResponse(yield* Effect.promise(() => previewContextLayers(projects, parsed)));
|
|
54467
54332
|
})));
|
|
54468
54333
|
const putContextLayerRoute = HttpRouter.add("PUT", "/api/context/layers", httpHandler(Effect.gen(function* () {
|
|
54469
|
-
const body = yield* readJsonBody$
|
|
54334
|
+
const body = yield* readJsonBody$8();
|
|
54470
54335
|
const parsed = yield* Effect.try({
|
|
54471
54336
|
try: () => decodeSaveRequest(body),
|
|
54472
54337
|
catch: (error) => new Error(error instanceof Error ? error.message : String(error))
|
|
@@ -54833,7 +54698,7 @@ async function installOx() {
|
|
|
54833
54698
|
* GET /api/prereqs/:feature — check which tools are missing for a feature
|
|
54834
54699
|
* POST /api/prereqs/install — install a specific tool by name
|
|
54835
54700
|
*/
|
|
54836
|
-
const readJsonBody$
|
|
54701
|
+
const readJsonBody$7 = Effect.gen(function* () {
|
|
54837
54702
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
54838
54703
|
try {
|
|
54839
54704
|
return text ? JSON.parse(text) : {};
|
|
@@ -54870,7 +54735,7 @@ const checkFeatureRoute = HttpRouter.add("GET", "/api/prereqs/:feature", httpHan
|
|
|
54870
54735
|
});
|
|
54871
54736
|
})));
|
|
54872
54737
|
const installToolRoute = HttpRouter.add("POST", "/api/prereqs/install", httpHandler(Effect.gen(function* () {
|
|
54873
|
-
const tool = (yield* readJsonBody$
|
|
54738
|
+
const tool = (yield* readJsonBody$7).tool;
|
|
54874
54739
|
if (!tool) return jsonResponse({ error: "Missing 'tool' in request body" }, { status: 400 });
|
|
54875
54740
|
if (!INSTALLABLE_TOOLS.some((t) => t === tool)) return jsonResponse({ error: `Tool '${tool}' is not auto-installable` }, { status: 400 });
|
|
54876
54741
|
const result = yield* Effect.promise(() => installTool(tool));
|
|
@@ -55678,7 +55543,7 @@ function getCheckpointWorker() {
|
|
|
55678
55543
|
return worker;
|
|
55679
55544
|
}
|
|
55680
55545
|
async function runInline(operation, payload) {
|
|
55681
|
-
const { claimTranscriptRange, commitTranscriptRange, releaseTranscriptRange, getTranscriptCheckpoint, listTranscriptCheckpoints } = await import("./checkpoints-
|
|
55546
|
+
const { claimTranscriptRange, commitTranscriptRange, releaseTranscriptRange, getTranscriptCheckpoint, listTranscriptCheckpoints } = await import("./checkpoints-Cb6CWT4S.js");
|
|
55682
55547
|
switch (operation) {
|
|
55683
55548
|
case "claimTranscriptRange": return claimTranscriptRange(payload);
|
|
55684
55549
|
case "commitTranscriptRange": return commitTranscriptRange(payload);
|
|
@@ -56840,7 +56705,7 @@ function buildPendingTurn(input, fromOffset, toOffset, compressed) {
|
|
|
56840
56705
|
};
|
|
56841
56706
|
}
|
|
56842
56707
|
async function emitMemoryObservationCreated(observation, timestamp) {
|
|
56843
|
-
const { initEventStore } = await import("./event-store-
|
|
56708
|
+
const { initEventStore } = await import("./event-store-Db4w4YIY.js");
|
|
56844
56709
|
await (await initEventStore()).appendAsync({
|
|
56845
56710
|
type: "memory.observation_created",
|
|
56846
56711
|
timestamp,
|
|
@@ -58585,8 +58450,9 @@ const diffsRouteLayer = Layer.mergeAll(getDiffsRoute, getTurnDiffRoute, getFullD
|
|
|
58585
58450
|
//#endregion
|
|
58586
58451
|
//#region routes/linear-mcp-auth.ts
|
|
58587
58452
|
init_issue_service_singleton();
|
|
58453
|
+
init_conversations();
|
|
58588
58454
|
const LINEAR_MCP_AUTH_CALLBACK_COPY_PREFIX = "The operator completed the Linear OAuth authorization in their browser. Finish the flow now: call mcp__linear__complete_authentication with callback_url set to exactly this URL:";
|
|
58589
|
-
const readJsonBody$
|
|
58455
|
+
const readJsonBody$6 = Effect.gen(function* () {
|
|
58590
58456
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
58591
58457
|
return text ? JSON.parse(text) : {};
|
|
58592
58458
|
});
|
|
@@ -58631,13 +58497,42 @@ function withIssueUrls(intervention) {
|
|
|
58631
58497
|
}))
|
|
58632
58498
|
};
|
|
58633
58499
|
}
|
|
58500
|
+
/**
|
|
58501
|
+
* Attach each blocked conversation's canonical dashboard URL — /conv/<rowid>,
|
|
58502
|
+
* the DB row id, which is how conversations are displayed everywhere else in
|
|
58503
|
+
* the dashboard. Resolved through the conversations read door by name.
|
|
58504
|
+
* Best-effort: an unresolvable conversation falls back to null and the banner
|
|
58505
|
+
* renders the id as plain text.
|
|
58506
|
+
*/
|
|
58507
|
+
function withConversationUrls(intervention) {
|
|
58508
|
+
return {
|
|
58509
|
+
...intervention,
|
|
58510
|
+
blockedAgents: intervention.blockedAgents.map((agent) => {
|
|
58511
|
+
if (!agent.agentId.startsWith("conv-")) return {
|
|
58512
|
+
...agent,
|
|
58513
|
+
conversationUrl: null
|
|
58514
|
+
};
|
|
58515
|
+
let conversationUrl = null;
|
|
58516
|
+
try {
|
|
58517
|
+
const conversation = getConversationByName(agent.agentId);
|
|
58518
|
+
conversationUrl = conversation === null ? null : `/conv/${conversation.id}`;
|
|
58519
|
+
} catch {
|
|
58520
|
+
conversationUrl = null;
|
|
58521
|
+
}
|
|
58522
|
+
return {
|
|
58523
|
+
...agent,
|
|
58524
|
+
conversationUrl
|
|
58525
|
+
};
|
|
58526
|
+
})
|
|
58527
|
+
};
|
|
58528
|
+
}
|
|
58634
58529
|
const getLinearMcpAuthRoute = HttpRouter.add("GET", "/api/linear-mcp-auth", httpHandler(Effect.gen(function* () {
|
|
58635
|
-
return jsonResponse(withIssueUrls(yield* Effect.promise(() => resolveLinearMcpAuthIntervention())));
|
|
58530
|
+
return jsonResponse(withConversationUrls(withIssueUrls(yield* Effect.promise(() => resolveLinearMcpAuthIntervention()))));
|
|
58636
58531
|
})));
|
|
58637
58532
|
const postLinearMcpAuthCallbackRoute = HttpRouter.add("POST", "/api/linear-mcp-auth/callback", httpHandler(Effect.gen(function* () {
|
|
58638
58533
|
const originError = rejectInvalidOrigin(yield* HttpServerRequest.HttpServerRequest);
|
|
58639
58534
|
if (originError) return originError;
|
|
58640
|
-
const body = yield* readJsonBody$
|
|
58535
|
+
const body = yield* readJsonBody$6;
|
|
58641
58536
|
const callbackUrl = typeof body["callbackUrl"] === "string" ? body["callbackUrl"] : "";
|
|
58642
58537
|
if (!isValidLinearMcpCallbackUrl(callbackUrl)) return jsonResponse({
|
|
58643
58538
|
success: false,
|
|
@@ -58685,7 +58580,7 @@ const linearMcpAuthRouteLayer = Layer.mergeAll(getLinearMcpAuthRoute, postLinear
|
|
|
58685
58580
|
* folded into that RPC surface.
|
|
58686
58581
|
*/
|
|
58687
58582
|
init_tmux();
|
|
58688
|
-
const readJsonBody$
|
|
58583
|
+
const readJsonBody$5 = Effect.gen(function* () {
|
|
58689
58584
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
58690
58585
|
return text ? JSON.parse(text) : {};
|
|
58691
58586
|
});
|
|
@@ -58709,7 +58604,7 @@ function generateTerminalSessionName() {
|
|
|
58709
58604
|
const postTerminalRoute = HttpRouter.add("POST", "/api/terminals", httpHandler(Effect.gen(function* () {
|
|
58710
58605
|
const authError = rejectUnauthorized(yield* HttpServerRequest.HttpServerRequest);
|
|
58711
58606
|
if (authError) return authError;
|
|
58712
|
-
const cwd = resolveCwd((yield* readJsonBody$
|
|
58607
|
+
const cwd = resolveCwd((yield* readJsonBody$5).cwd);
|
|
58713
58608
|
const sessionName = generateTerminalSessionName();
|
|
58714
58609
|
yield* createSession(sessionName, cwd, void 0, { env: { PATH: process.env.PATH || "" } });
|
|
58715
58610
|
return jsonResponse({
|
|
@@ -59608,12 +59503,12 @@ async function pauseFlywheelRunForDashboard() {
|
|
|
59608
59503
|
if (before.activeRunId) try {
|
|
59609
59504
|
const { readFile } = await import("node:fs/promises");
|
|
59610
59505
|
const { join } = await import("node:path");
|
|
59611
|
-
const { getAgentDir } = await import("./agents-
|
|
59506
|
+
const { getAgentDir } = await import("./agents-DpCuoF65.js");
|
|
59612
59507
|
const sessionId = (await readFile(join(getAgentDir(FLYWHEEL_ORCHESTRATOR_AGENT_ID), "session.id"), "utf-8")).trim();
|
|
59613
59508
|
if (sessionId) await saveResumeSessionId(before.activeRunId, sessionId);
|
|
59614
59509
|
} catch {}
|
|
59615
59510
|
await setPaused(true);
|
|
59616
|
-
await import("./agents-
|
|
59511
|
+
await import("./agents-DpCuoF65.js").then(({ stopAgent }) => Effect.runPromise(stopAgent(FLYWHEEL_ORCHESTRATOR_AGENT_ID, "operator")));
|
|
59617
59512
|
return {
|
|
59618
59513
|
before,
|
|
59619
59514
|
after: await readGateSnapshot(),
|
|
@@ -59623,7 +59518,7 @@ async function pauseFlywheelRunForDashboard() {
|
|
|
59623
59518
|
async function abortFlywheelRunForDashboard() {
|
|
59624
59519
|
const candidate = await getActiveRunId();
|
|
59625
59520
|
if (!candidate) return { aborted: await resolveLiveFlywheelRunId() ?? null };
|
|
59626
|
-
const { stopAgent } = await import("./agents-
|
|
59521
|
+
const { stopAgent } = await import("./agents-DpCuoF65.js");
|
|
59627
59522
|
await Effect.runPromise(stopAgent(FLYWHEEL_ORCHESTRATOR_AGENT_ID, "operator"));
|
|
59628
59523
|
await abortFlywheelRun(candidate);
|
|
59629
59524
|
return { aborted: candidate };
|
|
@@ -60076,7 +59971,7 @@ async function assertWritePathInsideRoot(projectRoot, candidate) {
|
|
|
60076
59971
|
}
|
|
60077
59972
|
return { ok: true };
|
|
60078
59973
|
}
|
|
60079
|
-
const readJsonBody$
|
|
59974
|
+
const readJsonBody$4 = Effect.gen(function* () {
|
|
60080
59975
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
60081
59976
|
try {
|
|
60082
59977
|
return {
|
|
@@ -60302,7 +60197,7 @@ async function getFlywheelConversationPayload() {
|
|
|
60302
60197
|
};
|
|
60303
60198
|
}
|
|
60304
60199
|
async function postFlywheelReportPayload() {
|
|
60305
|
-
const { flywheelReportCommand } = await import("./flywheel-
|
|
60200
|
+
const { flywheelReportCommand } = await import("./flywheel-v1cCOBx-.js");
|
|
60306
60201
|
await flywheelReportCommand({ cwd: process.cwd() });
|
|
60307
60202
|
return {
|
|
60308
60203
|
status: 200,
|
|
@@ -60577,7 +60472,7 @@ const getFlywheelBriefRoute = HttpRouter.add("GET", "/api/flywheel/brief", httpH
|
|
|
60577
60472
|
const postFlywheelBriefRoute = HttpRouter.add("POST", "/api/flywheel/brief", httpHandler(Effect.gen(function* () {
|
|
60578
60473
|
const authError = rejectUnauthorizedDashboardRequest(yield* HttpServerRequest.HttpServerRequest);
|
|
60579
60474
|
if (authError) return authError;
|
|
60580
|
-
const parsed = yield* readJsonBody$
|
|
60475
|
+
const parsed = yield* readJsonBody$4;
|
|
60581
60476
|
if (!parsed.ok) return jsonResponse({ error: parsed.error }, { status: 400 });
|
|
60582
60477
|
const body = parsed.body;
|
|
60583
60478
|
if (typeof body.content !== "string") return jsonResponse({ error: "content must be a string" }, { status: 400 });
|
|
@@ -60597,7 +60492,7 @@ const postFlywheelBriefRoute = HttpRouter.add("POST", "/api/flywheel/brief", htt
|
|
|
60597
60492
|
});
|
|
60598
60493
|
})));
|
|
60599
60494
|
const getUatCandidateRoute = HttpRouter.add("GET", "/api/flywheel/uat-candidate", httpHandler(Effect.gen(function* () {
|
|
60600
|
-
const { getUatCandidatePayload } = yield* Effect.promise(() => import("./uat-train-
|
|
60495
|
+
const { getUatCandidatePayload } = yield* Effect.promise(() => import("./uat-train-CycEzpbE.js"));
|
|
60601
60496
|
return jsonResponse(yield* Effect.promise(() => getUatCandidatePayload()));
|
|
60602
60497
|
})));
|
|
60603
60498
|
const getFlywheelStateRoute = HttpRouter.add("GET", "/api/flywheel/state", httpHandler(Effect.gen(function* () {
|
|
@@ -60808,7 +60703,7 @@ function previewBrief(book) {
|
|
|
60808
60703
|
return `${lines.join("\n")}\n`;
|
|
60809
60704
|
}
|
|
60810
60705
|
async function defaultStartOrderBook(book, project) {
|
|
60811
|
-
const { startFlywheelRun } = await import("./flywheel-
|
|
60706
|
+
const { startFlywheelRun } = await import("./flywheel-v1cCOBx-.js");
|
|
60812
60707
|
return startFlywheelRun({
|
|
60813
60708
|
cwd: resolveProjectPath(project),
|
|
60814
60709
|
orders: book.id
|
|
@@ -60895,8 +60790,9 @@ async function deleteOrderItemPayload(bookId, issueId, deps = {}, projectKey) {
|
|
|
60895
60790
|
async function patchOrderItemPayload(bookId, issueId, body, deps = {}, projectKey) {
|
|
60896
60791
|
return routeResult(async () => {
|
|
60897
60792
|
const { stateRoot } = resolveOrdersStateRoot(deps, projectKey);
|
|
60898
|
-
const
|
|
60899
|
-
|
|
60793
|
+
const canonicalIssue = normalizeOrderIssueId(stateRoot, issueId).toUpperCase();
|
|
60794
|
+
const existing = requireBook(stateRoot, bookId).items.find((item) => item.issue.toUpperCase() === canonicalIssue);
|
|
60795
|
+
if (!existing) throw new Error(`Issue ${canonicalIssue} is not in order book ${bookId}`);
|
|
60900
60796
|
let changed = false;
|
|
60901
60797
|
if (body["lane"] !== void 0 || body["order"] !== void 0) {
|
|
60902
60798
|
await moveItem(stateRoot, bookId, issueId, lane(body["lane"], existing.lane), positiveInteger(body["order"], "order", existing.order));
|
|
@@ -60962,7 +60858,7 @@ async function getPreviewBriefPayload(bookId, deps = {}, projectKey) {
|
|
|
60962
60858
|
};
|
|
60963
60859
|
});
|
|
60964
60860
|
}
|
|
60965
|
-
const readJsonBody$
|
|
60861
|
+
const readJsonBody$3 = Effect.gen(function* () {
|
|
60966
60862
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
60967
60863
|
if (!text) return {
|
|
60968
60864
|
ok: true,
|
|
@@ -61009,7 +60905,7 @@ function makeOrdersRouteLayer(deps = {}) {
|
|
|
61009
60905
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
61010
60906
|
const authError = mutationAuth(request);
|
|
61011
60907
|
if (authError) return authError;
|
|
61012
|
-
const parsed = yield* readJsonBody$
|
|
60908
|
+
const parsed = yield* readJsonBody$3;
|
|
61013
60909
|
if (!parsed.ok) return jsonResponse({ error: "Request body must be a JSON object" }, { status: 400 });
|
|
61014
60910
|
return resultResponse(yield* Effect.promise(() => postOrderPayload(parsed.body, deps, projectParam(request))));
|
|
61015
60911
|
})));
|
|
@@ -61022,7 +60918,7 @@ function makeOrdersRouteLayer(deps = {}) {
|
|
|
61022
60918
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
61023
60919
|
const authError = mutationAuth(request);
|
|
61024
60920
|
if (authError) return authError;
|
|
61025
|
-
const parsed = yield* readJsonBody$
|
|
60921
|
+
const parsed = yield* readJsonBody$3;
|
|
61026
60922
|
if (!parsed.ok) return jsonResponse({ error: "Request body must be a JSON object" }, { status: 400 });
|
|
61027
60923
|
const id = (yield* HttpRouter.params)["id"] ?? "";
|
|
61028
60924
|
return resultResponse(yield* Effect.promise(() => patchOrderPayload(id, parsed.body, deps, projectParam(request))));
|
|
@@ -61031,7 +60927,7 @@ function makeOrdersRouteLayer(deps = {}) {
|
|
|
61031
60927
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
61032
60928
|
const authError = mutationAuth(request);
|
|
61033
60929
|
if (authError) return authError;
|
|
61034
|
-
const parsed = yield* readJsonBody$
|
|
60930
|
+
const parsed = yield* readJsonBody$3;
|
|
61035
60931
|
if (!parsed.ok) return jsonResponse({ error: "Request body must be a JSON object" }, { status: 400 });
|
|
61036
60932
|
const id = (yield* HttpRouter.params)["id"] ?? "";
|
|
61037
60933
|
return resultResponse(yield* Effect.promise(() => postOrderItemsPayload(id, parsed.body, deps, projectParam(request))));
|
|
@@ -61047,7 +60943,7 @@ function makeOrdersRouteLayer(deps = {}) {
|
|
|
61047
60943
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
61048
60944
|
const authError = mutationAuth(request);
|
|
61049
60945
|
if (authError) return authError;
|
|
61050
|
-
const parsed = yield* readJsonBody$
|
|
60946
|
+
const parsed = yield* readJsonBody$3;
|
|
61051
60947
|
if (!parsed.ok) return jsonResponse({ error: "Request body must be a JSON object" }, { status: 400 });
|
|
61052
60948
|
const params = yield* HttpRouter.params;
|
|
61053
60949
|
return resultResponse(yield* Effect.promise(() => patchOrderItemPayload(params["id"] ?? "", params["issue"] ?? "", parsed.body, deps, projectParam(request))));
|
|
@@ -63348,7 +63244,8 @@ function getBacklogSequence(projectKey) {
|
|
|
63348
63244
|
//#region routes/backlog.ts
|
|
63349
63245
|
init_review_status();
|
|
63350
63246
|
init_control_settings();
|
|
63351
|
-
|
|
63247
|
+
init_jsonl_resolver();
|
|
63248
|
+
const readJsonBody$2 = Effect.gen(function* () {
|
|
63352
63249
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
63353
63250
|
try {
|
|
63354
63251
|
return text ? JSON.parse(text) : {};
|
|
@@ -63424,7 +63321,7 @@ const getBacklogSequenceRoute = HttpRouter.add("GET", "/api/backlog/sequence", h
|
|
|
63424
63321
|
const postBacklogRegenerateRoute = HttpRouter.add("POST", "/api/backlog/sequence/regenerate", httpHandler(Effect.gen(function* () {
|
|
63425
63322
|
const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
|
|
63426
63323
|
if (authError) return authError;
|
|
63427
|
-
const body = yield* readJsonBody$
|
|
63324
|
+
const body = yield* readJsonBody$2;
|
|
63428
63325
|
const projectRoot = process.cwd();
|
|
63429
63326
|
const passRaw = body["pass"];
|
|
63430
63327
|
const pass = typeof passRaw === "string" && new Set([
|
|
@@ -63459,7 +63356,7 @@ const postBacklogRegenerateRoute = HttpRouter.add("POST", "/api/backlog/sequence
|
|
|
63459
63356
|
const postBacklogGateRoute = HttpRouter.add("POST", "/api/backlog/sequence/gate", httpHandler(Effect.gen(function* () {
|
|
63460
63357
|
const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
|
|
63461
63358
|
if (authError) return authError;
|
|
63462
|
-
const body = yield* readJsonBody$
|
|
63359
|
+
const body = yield* readJsonBody$2;
|
|
63463
63360
|
const issueId = String(body["issueId"] ?? "");
|
|
63464
63361
|
const rawGate = String(body["gate"] ?? "");
|
|
63465
63362
|
if (!issueId) return yield* Effect.fail(/* @__PURE__ */ new Error("issueId is required"));
|
|
@@ -63494,7 +63391,7 @@ const postBacklogGateRoute = HttpRouter.add("POST", "/api/backlog/sequence/gate"
|
|
|
63494
63391
|
const postBacklogPlanningRoute = HttpRouter.add("POST", "/api/backlog/sequence/planning", httpHandler(Effect.gen(function* () {
|
|
63495
63392
|
const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
|
|
63496
63393
|
if (authError) return authError;
|
|
63497
|
-
const body = yield* readJsonBody$
|
|
63394
|
+
const body = yield* readJsonBody$2;
|
|
63498
63395
|
const issueId = String(body["issueId"] ?? "");
|
|
63499
63396
|
const planning = String(body["planning"] ?? "");
|
|
63500
63397
|
if (!issueId) return yield* Effect.fail(/* @__PURE__ */ new Error("issueId is required"));
|
|
@@ -63610,7 +63507,7 @@ const getBacklogForecastRoute = HttpRouter.add("GET", "/api/backlog/forecast", h
|
|
|
63610
63507
|
const postBacklogLabelsRoute = HttpRouter.add("POST", "/api/backlog/sequence/labels", httpHandler(Effect.gen(function* () {
|
|
63611
63508
|
const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
|
|
63612
63509
|
if (authError) return authError;
|
|
63613
|
-
const body = yield* readJsonBody$
|
|
63510
|
+
const body = yield* readJsonBody$2;
|
|
63614
63511
|
const issueId = String(body["issueId"] ?? "");
|
|
63615
63512
|
if (!issueId) return yield* Effect.fail(/* @__PURE__ */ new Error("issueId is required"));
|
|
63616
63513
|
return yield* Effect.promise(async () => {
|
|
@@ -63899,7 +63796,7 @@ async function handleTieredCallout(rawBody, deps = {}) {
|
|
|
63899
63796
|
}
|
|
63900
63797
|
};
|
|
63901
63798
|
}
|
|
63902
|
-
const readJsonBody = Effect.gen(function* () {
|
|
63799
|
+
const readJsonBody$1 = Effect.gen(function* () {
|
|
63903
63800
|
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
63904
63801
|
try {
|
|
63905
63802
|
return text ? JSON.parse(text) : {};
|
|
@@ -63908,12 +63805,72 @@ const readJsonBody = Effect.gen(function* () {
|
|
|
63908
63805
|
}
|
|
63909
63806
|
});
|
|
63910
63807
|
const postTieredCalloutsRoute = HttpRouter.add("POST", "/api/tiered/callouts", httpHandler(Effect.gen(function* () {
|
|
63911
|
-
const body = yield* readJsonBody;
|
|
63808
|
+
const body = yield* readJsonBody$1;
|
|
63912
63809
|
const result = yield* Effect.promise(() => handleTieredCallout(body));
|
|
63913
63810
|
return jsonResponse(result.body, { status: result.status });
|
|
63914
63811
|
})));
|
|
63915
63812
|
const tieredCalloutsRouteLayer = Layer.mergeAll(postTieredCalloutsRoute);
|
|
63916
63813
|
//#endregion
|
|
63814
|
+
//#region routes/restart-gate.ts
|
|
63815
|
+
/**
|
|
63816
|
+
* Restart-gate routes (PAN-3729) — the pinned wire contract for voluntary
|
|
63817
|
+
* dashboard restarts.
|
|
63818
|
+
*
|
|
63819
|
+
* POST /api/restart-gate/requests upsert + poll + TTL refresh (every 5s)
|
|
63820
|
+
* POST /api/restart-gate/claim take the exclusive right to restart
|
|
63821
|
+
* POST /api/restart-gate/approve operator approval (banner, `pan restart approve`)
|
|
63822
|
+
* GET /api/restart-gate read door for the current gate
|
|
63823
|
+
*
|
|
63824
|
+
* These handlers are deliberately thin: every state transition happens inside
|
|
63825
|
+
* `services/restart-gate.ts`, the one writer for gate state. Nothing here
|
|
63826
|
+
* touches the gate file.
|
|
63827
|
+
*
|
|
63828
|
+
* A requester that gets 404 from these paths is talking to a server built
|
|
63829
|
+
* before this feature and proceeds ungated — that compat rule is what lets the
|
|
63830
|
+
* gate itself be deployed through an ungated restart.
|
|
63831
|
+
*/
|
|
63832
|
+
const VALID_KINDS = [
|
|
63833
|
+
"deploy",
|
|
63834
|
+
"reload",
|
|
63835
|
+
"restart"
|
|
63836
|
+
];
|
|
63837
|
+
const readJsonBody = Effect.gen(function* () {
|
|
63838
|
+
const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
|
|
63839
|
+
try {
|
|
63840
|
+
return text ? JSON.parse(text) : {};
|
|
63841
|
+
} catch {
|
|
63842
|
+
return {};
|
|
63843
|
+
}
|
|
63844
|
+
});
|
|
63845
|
+
const postRequestRoute = HttpRouter.add("POST", "/api/restart-gate/requests", httpHandler(Effect.gen(function* () {
|
|
63846
|
+
const body = yield* readJsonBody;
|
|
63847
|
+
const requesterId = typeof body["requesterId"] === "string" ? body["requesterId"].trim() : "";
|
|
63848
|
+
const kind = body["kind"];
|
|
63849
|
+
const reason = typeof body["reason"] === "string" ? body["reason"] : "";
|
|
63850
|
+
const builtSha = typeof body["builtSha"] === "string" ? body["builtSha"] : void 0;
|
|
63851
|
+
if (!requesterId) return jsonResponse({ error: "requesterId is required" }, { status: 400 });
|
|
63852
|
+
if (typeof kind !== "string" || !VALID_KINDS.includes(kind)) return jsonResponse({ error: `kind must be one of: ${VALID_KINDS.join(", ")}` }, { status: 400 });
|
|
63853
|
+
return jsonResponse(yield* Effect.promise(() => getRestartGate().request({
|
|
63854
|
+
requesterId,
|
|
63855
|
+
kind,
|
|
63856
|
+
reason,
|
|
63857
|
+
...builtSha === void 0 ? {} : { builtSha }
|
|
63858
|
+
})));
|
|
63859
|
+
})));
|
|
63860
|
+
const postClaimRoute = HttpRouter.add("POST", "/api/restart-gate/claim", httpHandler(Effect.gen(function* () {
|
|
63861
|
+
const body = yield* readJsonBody;
|
|
63862
|
+
const requesterId = typeof body["requesterId"] === "string" ? body["requesterId"].trim() : "";
|
|
63863
|
+
if (!requesterId) return jsonResponse({ error: "requesterId is required" }, { status: 400 });
|
|
63864
|
+
return jsonResponse(yield* Effect.promise(() => getRestartGate().claim(requesterId)));
|
|
63865
|
+
})));
|
|
63866
|
+
const postApproveRoute = HttpRouter.add("POST", "/api/restart-gate/approve", httpHandler(Effect.gen(function* () {
|
|
63867
|
+
return jsonResponse(yield* Effect.promise(() => getRestartGate().approve()));
|
|
63868
|
+
})));
|
|
63869
|
+
const getRestartGateRoute = HttpRouter.add("GET", "/api/restart-gate", httpHandler(Effect.gen(function* () {
|
|
63870
|
+
return jsonResponse(yield* Effect.promise(() => getRestartGate().read()));
|
|
63871
|
+
})));
|
|
63872
|
+
const restartGateRouteLayer = Layer.mergeAll(postRequestRoute, postClaimRoute, postApproveRoute, getRestartGateRoute);
|
|
63873
|
+
//#endregion
|
|
63917
63874
|
//#region server-bind.ts
|
|
63918
63875
|
function isAddressInUseError(error) {
|
|
63919
63876
|
if (!error || typeof error !== "object") return false;
|
|
@@ -64049,7 +64006,7 @@ const staticRouteLayer = HttpRouter.add("GET", "*", Effect.gen(function* () {
|
|
|
64049
64006
|
if (filePath.endsWith("index.html")) return HttpServerResponse.setHeader(res, "Cache-Control", "no-cache, no-store, must-revalidate");
|
|
64050
64007
|
return res;
|
|
64051
64008
|
}));
|
|
64052
|
-
const makeRoutesLayer = Layer.mergeAll(healthRouteLayer, dashboardSessionPreflightRouteLayer, dashboardSessionRouteLayer, websocketRpcRouteLayer, issuesRouteLayer, pipelineMembershipRouteLayer, parkedRouteLayer, velocityRouteLayer, agentsRouteLayer, workspacesRouteLayer, workspaceRegistryRouteLayer, specialistsRouteLayer, costsRouteLayer, cloisterRouteLayer, resourcesRouteLayer, commandDeckRouteLayer, remoteRouteLayer, settingsRouteLayer, voiceRouteLayer, autopresoRouteLayer, metricsRouteLayer, miscRouteLayer, paletteRouteLayer, conversationsRouteLayer, eventsRouteLayer, showRouteLayer, projectsRouteLayer, projectsMergeTrainRouteLayer, mergeTrainRouteLayer, contextRouteLayer, commandsRouteLayer, adminRouteLayer, prereqsRouteLayer, cliproxyRouteLayer, ttsRouteLayer, webhooksRouteLayer, hooksRouteLayer, diffsRouteLayer, codexAuthRouteLayer, linearMcpAuthRouteLayer, terminalsRouteLayer, discoveredSessionsRouteLayer, flywheelRouteLayer, ordersRouteLayer, artifactsRouteLayer, featureRegistryRouteLayer, fsRouteLayer, tieredCalloutsRouteLayer, backlogRouteLayer, internalEventsRouteLayer, knowledgeViewerRouteLayer, staticRouteLayer);
|
|
64009
|
+
const makeRoutesLayer = Layer.mergeAll(healthRouteLayer, dashboardSessionPreflightRouteLayer, dashboardSessionRouteLayer, websocketRpcRouteLayer, issuesRouteLayer, pipelineMembershipRouteLayer, parkedRouteLayer, velocityRouteLayer, agentsRouteLayer, workspacesRouteLayer, workspaceRegistryRouteLayer, specialistsRouteLayer, costsRouteLayer, cloisterRouteLayer, resourcesRouteLayer, commandDeckRouteLayer, remoteRouteLayer, settingsRouteLayer, voiceRouteLayer, autopresoRouteLayer, metricsRouteLayer, miscRouteLayer, paletteRouteLayer, conversationsRouteLayer, eventsRouteLayer, showRouteLayer, projectsRouteLayer, projectsMergeTrainRouteLayer, mergeTrainRouteLayer, contextRouteLayer, commandsRouteLayer, adminRouteLayer, prereqsRouteLayer, cliproxyRouteLayer, ttsRouteLayer, webhooksRouteLayer, hooksRouteLayer, diffsRouteLayer, codexAuthRouteLayer, linearMcpAuthRouteLayer, terminalsRouteLayer, discoveredSessionsRouteLayer, flywheelRouteLayer, ordersRouteLayer, artifactsRouteLayer, featureRegistryRouteLayer, fsRouteLayer, tieredCalloutsRouteLayer, backlogRouteLayer, internalEventsRouteLayer, restartGateRouteLayer, knowledgeViewerRouteLayer, staticRouteLayer);
|
|
64053
64010
|
const OverdeckAgentsResolverLive = AgentsResolverLive.pipe(Layer.provide(Layer.mergeAll(DbLive, TmuxLive)));
|
|
64054
64011
|
const OverdeckCostResolverLive = CostResolverLive.pipe(Layer.provide(DbLive));
|
|
64055
64012
|
const ReadModelWithOverdeckLive = ReadModelServiceLive.pipe(Layer.provide(OverdeckAgentsResolverLive));
|
|
@@ -64491,123 +64448,6 @@ function startReviewStatusReconcileService() {
|
|
|
64491
64448
|
return true;
|
|
64492
64449
|
}
|
|
64493
64450
|
//#endregion
|
|
64494
|
-
//#region services/project-resource-refresh-queue.ts
|
|
64495
|
-
init_projects();
|
|
64496
|
-
const PROJECT_RESOURCE_CONVERGENCE_INTERVAL_MS = 5 * 6e4;
|
|
64497
|
-
function createProjectResourceRefreshQueue(deps) {
|
|
64498
|
-
const debounceMs = deps.debounceMs ?? 1e3;
|
|
64499
|
-
const now = deps.now ?? Date.now;
|
|
64500
|
-
const pending = /* @__PURE__ */ new Map();
|
|
64501
|
-
const reasons = /* @__PURE__ */ new Map();
|
|
64502
|
-
const idleWaiters = /* @__PURE__ */ new Set();
|
|
64503
|
-
let activeProjectPaths = [];
|
|
64504
|
-
let timer = null;
|
|
64505
|
-
let running = false;
|
|
64506
|
-
let stopped = false;
|
|
64507
|
-
let lastStartedAt = null;
|
|
64508
|
-
let lastCompletedAt = null;
|
|
64509
|
-
let lastError = null;
|
|
64510
|
-
const isIdle = () => !running && timer === null && pending.size === 0;
|
|
64511
|
-
const resolveIdleWaiters = () => {
|
|
64512
|
-
if (!isIdle()) return;
|
|
64513
|
-
for (const resolve of idleWaiters) resolve();
|
|
64514
|
-
idleWaiters.clear();
|
|
64515
|
-
};
|
|
64516
|
-
const drain = async () => {
|
|
64517
|
-
timer = null;
|
|
64518
|
-
if (running || stopped) return;
|
|
64519
|
-
running = true;
|
|
64520
|
-
try {
|
|
64521
|
-
while (!stopped && pending.size > 0) {
|
|
64522
|
-
const projects = [...pending.values()];
|
|
64523
|
-
const reasonsByProjectPath = /* @__PURE__ */ new Map();
|
|
64524
|
-
for (const project of projects) {
|
|
64525
|
-
reasonsByProjectPath.set(project.path, new Set(reasons.get(project.path) ?? []));
|
|
64526
|
-
reasons.delete(project.path);
|
|
64527
|
-
}
|
|
64528
|
-
pending.clear();
|
|
64529
|
-
activeProjectPaths = projects.map((project) => project.path);
|
|
64530
|
-
lastStartedAt = now();
|
|
64531
|
-
try {
|
|
64532
|
-
await deps.refreshProjects(projects, { reasonsByProjectPath });
|
|
64533
|
-
lastError = null;
|
|
64534
|
-
} catch (error) {
|
|
64535
|
-
lastError = error instanceof Error ? error.message : String(error);
|
|
64536
|
-
console.warn("[project-resource-refresh] batch failed:", lastError);
|
|
64537
|
-
} finally {
|
|
64538
|
-
activeProjectPaths = [];
|
|
64539
|
-
lastCompletedAt = now();
|
|
64540
|
-
}
|
|
64541
|
-
}
|
|
64542
|
-
} finally {
|
|
64543
|
-
running = false;
|
|
64544
|
-
resolveIdleWaiters();
|
|
64545
|
-
}
|
|
64546
|
-
};
|
|
64547
|
-
const schedule = () => {
|
|
64548
|
-
if (stopped || running || timer) return;
|
|
64549
|
-
timer = setTimeout(() => void drain(), debounceMs);
|
|
64550
|
-
timer.unref?.();
|
|
64551
|
-
};
|
|
64552
|
-
const enqueueProject = (project, reason) => {
|
|
64553
|
-
if (stopped) return;
|
|
64554
|
-
pending.set(project.path, project);
|
|
64555
|
-
const projectReasons = reasons.get(project.path) ?? /* @__PURE__ */ new Set();
|
|
64556
|
-
projectReasons.add(reason);
|
|
64557
|
-
reasons.set(project.path, projectReasons);
|
|
64558
|
-
schedule();
|
|
64559
|
-
};
|
|
64560
|
-
return {
|
|
64561
|
-
enqueueProject,
|
|
64562
|
-
enqueueProjects(projects, reason) {
|
|
64563
|
-
for (const project of projects) enqueueProject(project, reason);
|
|
64564
|
-
},
|
|
64565
|
-
whenIdle() {
|
|
64566
|
-
if (isIdle()) return Promise.resolve();
|
|
64567
|
-
return new Promise((resolve) => idleWaiters.add(resolve));
|
|
64568
|
-
},
|
|
64569
|
-
getState() {
|
|
64570
|
-
return {
|
|
64571
|
-
running,
|
|
64572
|
-
activeProjectPaths: [...activeProjectPaths],
|
|
64573
|
-
pendingProjectPaths: [...pending.keys()],
|
|
64574
|
-
lastStartedAt,
|
|
64575
|
-
lastCompletedAt,
|
|
64576
|
-
lastError
|
|
64577
|
-
};
|
|
64578
|
-
},
|
|
64579
|
-
stop() {
|
|
64580
|
-
stopped = true;
|
|
64581
|
-
if (timer) clearTimeout(timer);
|
|
64582
|
-
timer = null;
|
|
64583
|
-
pending.clear();
|
|
64584
|
-
reasons.clear();
|
|
64585
|
-
resolveIdleWaiters();
|
|
64586
|
-
}
|
|
64587
|
-
};
|
|
64588
|
-
}
|
|
64589
|
-
const MEMBERSHIP_REFRESH_REASONS = new Set(["boot-warm", "periodic-convergence"]);
|
|
64590
|
-
const projectResourceRefreshQueue = createProjectResourceRefreshQueue({ refreshProjects: (projects, context) => refreshResourceAllocatedProjects(projects, { refreshMembership: [...context.reasonsByProjectPath.values()].some((projectReasons) => [...projectReasons].some((reason) => MEMBERSHIP_REFRESH_REASONS.has(reason))) }) });
|
|
64591
|
-
function enqueueProjectsResourceRefresh(projects, reason) {
|
|
64592
|
-
projectResourceRefreshQueue.enqueueProjects(projects, reason);
|
|
64593
|
-
}
|
|
64594
|
-
function whenProjectResourceRefreshIdle() {
|
|
64595
|
-
return projectResourceRefreshQueue.whenIdle();
|
|
64596
|
-
}
|
|
64597
|
-
function getProjectResourceRefreshQueueState() {
|
|
64598
|
-
return projectResourceRefreshQueue.getState();
|
|
64599
|
-
}
|
|
64600
|
-
function stopProjectResourceRefreshQueue() {
|
|
64601
|
-
projectResourceRefreshQueue.stop();
|
|
64602
|
-
}
|
|
64603
|
-
function startProjectResourceConvergence() {
|
|
64604
|
-
const timer = setInterval(() => {
|
|
64605
|
-
enqueueProjectsResourceRefresh(listProjectsSync().map((entry) => entry.config), "periodic-convergence");
|
|
64606
|
-
}, PROJECT_RESOURCE_CONVERGENCE_INTERVAL_MS);
|
|
64607
|
-
timer.unref?.();
|
|
64608
|
-
return () => clearInterval(timer);
|
|
64609
|
-
}
|
|
64610
|
-
//#endregion
|
|
64611
64451
|
//#region services/resource-refresh-triggers.ts
|
|
64612
64452
|
init_agents$1();
|
|
64613
64453
|
init_projects();
|
|
@@ -64617,7 +64457,8 @@ const TRIGGER_EVENT_TYPES = new Set([
|
|
|
64617
64457
|
"agent.started",
|
|
64618
64458
|
"agent.stopped",
|
|
64619
64459
|
"agent.completed",
|
|
64620
|
-
"agent.heartbeat_dead"
|
|
64460
|
+
"agent.heartbeat_dead",
|
|
64461
|
+
"issue.statusChanged"
|
|
64621
64462
|
]);
|
|
64622
64463
|
function createResourceRefreshTriggers(deps) {
|
|
64623
64464
|
const warn = deps.warn ?? ((message) => console.warn(message));
|
|
@@ -64635,7 +64476,8 @@ function createResourceRefreshTriggers(deps) {
|
|
|
64635
64476
|
warn(`[resource-refresh] skipped ${event.type}: affected project could not be resolved`);
|
|
64636
64477
|
return;
|
|
64637
64478
|
}
|
|
64638
|
-
|
|
64479
|
+
const reason = event.type === "issue.statusChanged" && Array.isArray(payload?.labels) && payload.labels.some((label) => String(label).toLowerCase() === "closed-out") ? "issue.statusChanged:closed-out" : event.type;
|
|
64480
|
+
deps.enqueueProjects([project], reason);
|
|
64639
64481
|
});
|
|
64640
64482
|
}
|
|
64641
64483
|
function startResourceRefreshTriggers() {
|
|
@@ -66179,7 +66021,7 @@ const RESTART_MARKER = join$1(homedir(), ".overdeck", "dashboard-restarting.json
|
|
|
66179
66021
|
* loads new content-hashed chunk filenames (no ERR_MODULE_NOT_FOUND after rebuild).
|
|
66180
66022
|
*/
|
|
66181
66023
|
async function defaultLifecycleRunner(pending) {
|
|
66182
|
-
const { postMergeLifecycle, notifyTldrDaemon } = await import("./merge-agent-
|
|
66024
|
+
const { postMergeLifecycle, notifyTldrDaemon } = await import("./merge-agent-BuoC_PRZ.js");
|
|
66183
66025
|
await postMergeLifecycle(pending.issueId, pending.projectPath, pending.sourceBranch, { skipDeploy: true });
|
|
66184
66026
|
if (pending.sourceBranch) await notifyTldrDaemon(pending.projectPath, pending.sourceBranch);
|
|
66185
66027
|
}
|
|
@@ -66376,7 +66218,7 @@ function failureReason(result) {
|
|
|
66376
66218
|
return result.error ?? result.message ?? `merge returned status ${result.statusCode ?? "unknown"}`;
|
|
66377
66219
|
}
|
|
66378
66220
|
async function defaultMergeIssue(issueId) {
|
|
66379
|
-
const { triggerMerge } = await import("./merge-ops-
|
|
66221
|
+
const { triggerMerge } = await import("./merge-ops-DabXHp2i.js");
|
|
66380
66222
|
return triggerMerge(issueId);
|
|
66381
66223
|
}
|
|
66382
66224
|
function defaultAnnounceFailure(issueId, reason) {
|
|
@@ -66879,7 +66721,7 @@ const defaultDependencies = {
|
|
|
66879
66721
|
inspect: inspectStateMigration,
|
|
66880
66722
|
ensureWorktree: ensureStateWorktree,
|
|
66881
66723
|
migrate: async (projectKey, project, signal) => {
|
|
66882
|
-
const { migrateProjectState } = await import("./state-migrate-
|
|
66724
|
+
const { migrateProjectState } = await import("./state-migrate-C6H3jfHE.js");
|
|
66883
66725
|
await migrateProjectState(projectKey, { signal }, project);
|
|
66884
66726
|
},
|
|
66885
66727
|
clearCache: clearStateMigrationCache,
|
|
@@ -67091,7 +66933,7 @@ if (shouldStartStaleCheckRetriggerService()) {
|
|
|
67091
66933
|
}
|
|
67092
66934
|
if (process.env.OVERDECK_MODE === "desktop") (async () => {
|
|
67093
66935
|
try {
|
|
67094
|
-
const { provisionClaudeHooks } = await import("./claude-hooks-provision-
|
|
66936
|
+
const { provisionClaudeHooks } = await import("./claude-hooks-provision-C5JHpxTS.js");
|
|
67095
66937
|
const result = await provisionClaudeHooks();
|
|
67096
66938
|
if (!result.ok) console.warn(`[overdeck] Claude hook provisioning skipped: ${result.reason}`);
|
|
67097
66939
|
else if (result.changed) console.log(`[overdeck] Claude hooks provisioned: ${result.binariesSynced} scripts, registered ${result.registered.length} hook(s)${result.pruned.length ? `, pruned ${result.pruned.length} stale` : ""}`);
|
|
@@ -67436,7 +67278,7 @@ const handleShutdownSignal = async (signal) => {
|
|
|
67436
67278
|
await stopAllKnowledgeViewers().catch((err) => console.warn("[knowledge-viewer] shutdown failed:", err?.message ?? err));
|
|
67437
67279
|
await stopDeaconChild().catch((err) => console.warn("[deacon-supervisor] child shutdown failed:", err?.message ?? err));
|
|
67438
67280
|
try {
|
|
67439
|
-
const { killAllGateProcessGroups } = await import("./validation-
|
|
67281
|
+
const { killAllGateProcessGroups } = await import("./validation-CHovCoTT.js");
|
|
67440
67282
|
const reaped = killAllGateProcessGroups();
|
|
67441
67283
|
if (reaped > 0) console.log(`[overdeck] reaped ${reaped} in-flight gate process group(s)`);
|
|
67442
67284
|
} catch (err) {
|
|
@@ -67490,8 +67332,9 @@ reconcileStaleGitHubBlockers().then((n) => {
|
|
|
67490
67332
|
});
|
|
67491
67333
|
}
|
|
67492
67334
|
}).catch((err) => console.warn(`[overdeck] Startup blocker reconciliation failed: ${err.message}`));
|
|
67335
|
+
await startProjectCiRefillAfterProjectionReady(900 * 1e3);
|
|
67493
67336
|
try {
|
|
67494
|
-
const { resetProcessingToQueued, requeueOrphanedMergingAutoMerges } = await import("./merge-sync-
|
|
67337
|
+
const { resetProcessingToQueued, requeueOrphanedMergingAutoMerges } = await import("./merge-sync-0m2Q087q.js");
|
|
67495
67338
|
const resetCount = resetProcessingToQueued();
|
|
67496
67339
|
if (resetCount > 0) {
|
|
67497
67340
|
console.log(`[overdeck] Reset ${resetCount} stuck merge queue entries to queued`);
|
|
@@ -67516,13 +67359,16 @@ try {
|
|
|
67516
67359
|
}
|
|
67517
67360
|
await processPendingLifecycle();
|
|
67518
67361
|
await processPendingFeedbackDeliveries();
|
|
67362
|
+
await initRestartGate().catch((err) => {
|
|
67363
|
+
console.warn(`[overdeck] Restart gate init failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
67364
|
+
});
|
|
67519
67365
|
if (process.env.OVERDECK_DISABLE_AUTO_MERGE === "1") console.log("[overdeck] Auto-merge executor SKIPPED (OVERDECK_DISABLE_AUTO_MERGE=1)");
|
|
67520
67366
|
else {
|
|
67521
67367
|
startAutoMergeExecutor();
|
|
67522
67368
|
console.log("[overdeck] Auto-merge executor started");
|
|
67523
67369
|
}
|
|
67524
67370
|
try {
|
|
67525
|
-
const { reconcileInterruptedVerifications } = await import("./verification-runner-
|
|
67371
|
+
const { reconcileInterruptedVerifications } = await import("./verification-runner-BuqGwm2t.js");
|
|
67526
67372
|
const interrupted = reconcileInterruptedVerifications();
|
|
67527
67373
|
if (interrupted > 0) console.log(`[overdeck] recovered ${interrupted} orphaned verification worker(s)`);
|
|
67528
67374
|
} catch (err) {
|