@overdeck/desktop 0.49.1 → 0.49.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/server/{acceptance-criteria-Crw-xSJ3.js → acceptance-criteria-CHtDkHEL.js} +2 -2
- package/server/{active-dashboard-bundle-CLwfD-Om.js → active-dashboard-bundle-Byh6sP-q.js} +2 -2
- package/server/{activity-logger-BAVLrkR7.js → activity-logger-BWZhVphb.js} +22 -4
- package/server/activity-logger-Ck8qoluj.js +3 -0
- package/server/{advancing-selfheal-BQiJ7mIH.js → advancing-selfheal-65W4yUQi.js} +6 -6
- package/server/{agent-gc-5E0lgxI1.js → agent-gc-BNUudFnt.js} +10 -10
- package/server/agent-idle-ONBssBN_.js +745 -0
- package/server/{agent-state-Bb3UUxQm.js → agent-state-BJhGIJZe.js} +421 -135
- package/server/agent-state-CM8iVw5B.js +3 -0
- package/server/{agent-state-service-BFbttwRA.js → agent-state-service-CiIuwzIs.js} +5 -5
- package/server/{agent-state-service-keg-x1bT.js → agent-state-service-CzHfoqKQ.js} +1 -1
- package/server/agents-DpCuoF65.js +3 -0
- package/server/{agents-CqQJW75N.js → agents-jXgqpHca.js} +8 -8
- package/server/archive-planning-BW4MKNI7.js +2 -0
- package/server/{archive-planning-BwEhu9Oq.js → archive-planning-CGkU6UeL.js} +20 -135
- package/server/{artifact-index-jobs-C6Lg2rKm.js → artifact-index-jobs-Ck4NRRkY.js} +3 -3
- package/server/{assemble-DyTp2gSB.js → assemble-CyvEBmmq.js} +28 -9
- package/server/{auto-spawn-consent-BDfe4qz0.js → auto-spawn-consent-Dc4mtM-B.js} +8 -7
- package/server/{backlog-auto-trigger-DuOGpdDW.js → backlog-auto-trigger-CCEpr4YT.js} +3 -3
- package/server/{behavior-Bitko0mD.js → behavior-BiCQzqyT.js} +3 -3
- package/server/{bridge-pool-patrol-DiHEd13O.js → bridge-pool-patrol-Ce8rNPym.js} +2 -2
- package/server/{briefing-freshness-CDJcmHHZ.js → briefing-freshness-e_OEYZEe.js} +2 -2
- package/server/{build-info-DTX8JwVP.js → build-info-BRw4QlYO.js} +3 -3
- package/server/build-info-Bj2vQEMh.js +2 -0
- package/server/{checkpoint-manager-CKg1tn34.js → checkpoint-manager-CKr42Usw.js} +1 -1
- package/server/{checkpoint-manager-BlOOdzLF.js → checkpoint-manager-DOwRGFff.js} +26 -9
- package/server/checkpoint-worker.js +1 -1
- package/server/{checkpoints-DRALkfDS.js → checkpoints-Cb6CWT4S.js} +1 -1
- package/server/{checkpoints-BGfl0cHM.js → checkpoints-Cszp_0Np.js} +2 -2
- package/server/{claude-hooks-provision-B_tv3wzE.js → claude-hooks-provision-C5JHpxTS.js} +1 -1
- package/server/{claude-hooks-provision-BlGv6twJ.js → claude-hooks-provision-Cer2eFfj.js} +2 -2
- package/server/{claude-permissions-aHgDcZi5.js → claude-permissions-Bc5kjX1q.js} +2 -2
- package/server/{claude-settings-overlay-CYOvFE3A.js → claude-settings-overlay-C7rWsnya.js} +1 -1
- package/server/{claude-settings-overlay-T2LWLteV.js → claude-settings-overlay-m-VVZej1.js} +2 -2
- package/server/cli-BRuzUT_I.js +2 -0
- package/server/{cli-Do8UpLoI.js → cli-BmczsfD6.js} +11 -11
- package/server/{cliproxy-CX6jHRDP.js → cliproxy-BpYpkogS.js} +52 -17
- package/server/cliproxy-_yUU0HRY.js +3 -0
- package/server/{close-issue-J0_eWYT1.js → close-issue-CxvRD0UI.js} +5 -5
- package/server/{closed-issue-reaper-bFppuk6F.js → closed-issue-reaper-nMLRi5de.js} +13 -12
- package/server/{closed-issue-reaper-Cl2h9AfT.js → closed-issue-reaper-omOcUDBl.js} +1 -1
- package/server/{codex-icapA4om.js → codex-DZhFfcWu.js} +1 -1
- package/server/{codex-OOea7lXs.js → codex-KaSKE-R3.js} +16 -10
- package/server/{compaction-continuation-D5voR1ME.js → compaction-continuation-Bjfi70G-.js} +3 -3
- package/server/{config-Cjleh3_U.js → config-CH1AqqIQ.js} +1 -1
- package/server/{config-DC75T4Mr.js → config-Doq_tF-f.js} +2 -2
- package/server/{config-tucKBCCc.js → config-ZGjvuR6J.js} +2 -2
- package/server/{config-yaml-BwOEANMr.js → config-yaml-D9nfpEx1.js} +33 -8
- package/server/{conflict-gate-DlpWCMd7.js → conflict-gate-D4XCtrm2.js} +1 -1
- package/server/{conflict-gate-D2L1kZeL.js → conflict-gate-DcUTY4Gb.js} +4 -4
- package/server/{context-layers-CSPGc2Hb.js → context-layers-BBTKP-Y4.js} +3 -3
- package/server/context-layers-BGj2Y9l3.js +4 -0
- package/server/{continue-U3Af0jUq.js → continue-i7Revg8D.js} +3 -3
- package/server/{control-settings-5k6ixdFW.js → control-settings-BMoDHY1G.js} +6 -6
- package/server/{conversation-compaction-CSpVpxN6.js → conversation-compaction-D4VOmF7p.js} +8 -8
- package/server/{conversation-compaction-Ciit9O6k.js → conversation-compaction-DzIjYMfg.js} +1 -1
- package/server/{conversation-service-BxrB5lUT.js → conversation-service-CzZUJFEx.js} +1 -1
- package/server/{conversation-service-BteE4ELK.js → conversation-service-tQCIbBVZ.js} +6 -6
- package/server/{conversations-DhwxsOru.js → conversations-C75EFFjf.js} +12 -7
- package/server/conversations-bFDaD5YN.js +3 -0
- package/server/{cost-Bnf9NUC5.js → cost-BCWEkvro.js} +3 -3
- package/server/{cost-CQKI6OCu.js → cost-CiIwxH1D.js} +2 -2
- package/server/{cost-sync-B-ADeXKY.js → cost-sync-DOkdE_yB.js} +3 -3
- package/server/{dag-DI9LaK_q.js → dag-BPc74hwj.js} +6 -19
- package/server/{dangerous-git-ops-akhA3iyF.js → dangerous-git-ops-By9iguTP.js} +1 -1
- package/server/dashboard-db-worker.js +7 -7
- package/server/{deacon-TPYssFYt.js → deacon-B24dNzr8.js} +1774 -171
- package/server/deacon-CzSZMtb-.js +4 -0
- package/server/{deacon-canonical-state-DFYymrDw.js → deacon-canonical-state-CkvxRPck.js} +3 -3
- package/server/{deacon-event-client-Te5v10-b.js → deacon-event-client-BYIQBu0T.js} +1 -1
- package/server/{deacon-event-client-BKOL4AcL.js → deacon-event-client-Do6Z2gKl.js} +2 -2
- package/server/{deacon-nudge-log-BtlTWgWu.js → deacon-nudge-log-CzM9JA9t.js} +1 -1
- package/server/{deacon-pending-lifecycle-DVHjOLje.js → deacon-pending-lifecycle-BObEdT-L.js} +3 -3
- package/server/deacon.js +11 -11
- package/server/dead-end-trip-6V_CwveT.js +2 -0
- package/server/{dead-end-trip-P0IF1O0E.js → dead-end-trip-CnVmjnya.js} +3 -3
- package/server/delivery-gyce0vQ7.js +3 -0
- package/server/{deploy-patrol-BXjlvoV3.js → deploy-patrol-CEwwEYDM.js} +8 -8
- package/server/deploy-queue-CjLErpgw.js +2 -0
- package/server/{deploy-queue-o7shYg1j.js → deploy-queue-r96ojDI3.js} +2 -2
- package/server/{deploy-window-CNT6fOff.js → deploy-window-D_3hhfxt.js} +4 -4
- package/server/{deploy-window-BMk5_oX6.js → deploy-window-DeJK8mTK.js} +1 -1
- package/server/{dev-supervisor-SR1CLOAK.js → dev-supervisor-DZWwpENk.js} +2 -2
- package/server/{devcontainer-renderer-enMmNDFa.js → devcontainer-renderer-d-9dCV_2.js} +3 -3
- package/server/{dist-CPTO_zMR.js → dist-DsLAsFSh.js} +1 -1
- package/server/dist-fCA6y2bH.js +3 -0
- package/server/{docker-B7qUZptz.js → docker-B2mUBzGk.js} +3 -3
- package/server/{docker-KR3zSFKY.js → docker-CRPHBylA.js} +1 -1
- package/server/{dod-gK835UMf.js → dod-DWtilRLx.js} +1 -1
- package/server/{done-preflight-CksRvh49.js → done-preflight-BDVdWed5.js} +1 -1
- package/server/{done-preflight-Bk8aExAL.js → done-preflight-D4ukUf-S.js} +5 -5
- package/server/{driver-CmsY2RLl.js → driver-BtcFz-qu.js} +14 -3
- package/server/{durable-review-pipeline-DgYHucN2.js → durable-review-pipeline-B3OS2_He.js} +11 -2
- package/server/durable-review-pipeline-CaCbEJSt.js +3 -0
- package/server/{ensure-devcontainer-ojerEqQg.js → ensure-devcontainer-BUeBRjmm.js} +4 -4
- package/server/{ensure-devcontainer-BQ4YizSH.js → ensure-devcontainer-rGSh0JHK.js} +1 -1
- package/server/{esm-shims-1htPASWs.js → esm-shims-oAaKIa-a.js} +1 -1
- package/server/{event-store-D7qcJXuZ.js → event-store-BCSgMubf.js} +5 -5
- package/server/{event-store-BgEjNsvk.js → event-store-Db4w4YIY.js} +1 -1
- package/server/{event-store-provider-BKvk2rDj.js → event-store-provider-DlSQND3V.js} +1 -1
- package/server/{events-BIKGJZOT.js → events-B6zioJA_.js} +3 -3
- package/server/{dist-src-BM9eudEd.js → factory-BrdqXBeK.js} +714 -2
- package/server/{feature-registry-storage-ewNSIVsQ.js → feature-registry-storage-zh3ZXW6f.js} +3 -3
- package/server/{features-CGopJXdU.js → features-BGntOWdy.js} +2 -2
- package/server/{feedback-stuck-retirement-B8-fX7NA.js → feedback-stuck-retirement-DpA5u1kt.js} +2 -2
- package/server/{feedback-target-Ci6N5p4G.js → feedback-target-D7GxdUYG.js} +10 -10
- package/server/{feedback-target-CkyLYohm.js → feedback-target-Ddqk93NF.js} +1 -1
- package/server/{feedback-writer-D4ULO4qG.js → feedback-writer-C1gCLFmp.js} +5 -5
- package/server/{feedback-writer-DfuVjvH0.js → feedback-writer-CH2846DP.js} +1 -1
- package/server/{flywheel-C7yek87O.js → flywheel-CjW2L7BS.js} +79 -29
- package/server/{flywheel-DXI_WITn.js → flywheel-HJt7QdWP.js} +1 -1
- package/server/{flywheel-merge-order-C5m5bYBc.js → flywheel-merge-order-4fNRN2F2.js} +1 -1
- package/server/{flywheel-merge-order-CXfU4M6l.js → flywheel-merge-order-D_yyAlND.js} +7 -7
- package/server/{flywheel-BwYPDlhK.js → flywheel-v1cCOBx-.js} +14 -14
- package/server/{forge-DYX9sKzG.js → forge-RVTCK_5X.js} +2 -2
- package/server/forge-bvak6vXJ.js +2 -0
- package/server/{from-DAdMxC29.js → from-BnLgKYvw.js} +1 -1
- package/server/{fs-lock-cw25uO_E.js → fs-lock-C7J-ugIf.js} +2 -2
- package/server/{fts-operations-D_rzLxX5.js → fts-operations-CU0B5WUx.js} +3 -3
- package/server/git-info-BSrI9owC.js +148 -0
- package/server/{git-utils-Y0zG25ez.js → git-utils-CsKV0Dis.js} +1 -1
- package/server/{git-utils-DV4B9TRl.js → git-utils-DW8-jIUJ.js} +4 -4
- package/server/{github-app-4UX8VIr8.js → github-app-7ywLhuZO.js} +2 -2
- package/server/{github-app-C33lDk9Z.js → github-app-Oi5hdn1n.js} +1 -1
- package/server/{github-client-nPj5ckZO.js → github-client-Cy0fSj1a.js} +1 -1
- package/server/{github-client-DkJVR908.js → github-client-DAbuXLuk.js} +3 -3
- package/server/{github-pr-lookup-C9Vokb0W.js → github-pr-lookup-Dhh3ec1V.js} +2 -2
- package/server/{harness-binary-BgXYDo2Z.js → harness-binary-tMmgJfC1.js} +2 -2
- package/server/{harness-resolve-1NZcVx7n.js → harness-resolve-DusNpVEe.js} +4 -4
- package/server/{health-events-jMfxrElt.js → health-events-BYDZ9n2i.js} +1 -1
- package/server/{health-events-DlX_FVAB.js → health-events-DNw9Mzw9.js} +2 -2
- package/server/{hooks-W3REcb3h.js → hooks-B4wj32l2.js} +1 -1
- package/server/{hooks-NQ19vvlB.js → hooks-BjBjxqNh.js} +2 -2
- package/server/{hume-BFkid2PO.js → hume-BP9YbxaE.js} +2 -2
- package/server/hume-TYTb6fDU.js +3 -0
- package/server/{identity-Bwh6VGeL.js → identity-C23uY8dZ.js} +3 -3
- package/server/{idle-stack-reaper-BeU_KxWx.js → idle-stack-reaper-BSxb1bln.js} +4 -4
- package/server/{idle-stack-reaper-CHtCNpvd.js → idle-stack-reaper-Bw0rU9GC.js} +1 -1
- package/server/{in-flight-guard-pcwXKLGz.js → in-flight-guard-DuxabAHT.js} +1 -1
- package/server/{infra-KTp9KV9u.js → infra-CHIvOb9q.js} +30 -7
- package/server/{injection-67YyU6SC.js → injection-BYUt8ml1.js} +8 -8
- package/server/{injection-BxbZKPDh.js → injection-BviePcm3.js} +1 -1
- package/server/inspect-agent-JFEaYTRa.js +2 -0
- package/server/{inspect-agent-VHSihlb7.js → inspect-agent-sV_19NxZ.js} +12 -12
- package/server/{internal-token-B-z-sGBH.js → internal-token-BOtIRJU7.js} +1 -1
- package/server/{internal-token-zY75jrRJ.js → internal-token-DoVzb4b7.js} +2 -2
- package/server/{io-DfvO2xyh.js → io-DKrWd3gX.js} +5 -5
- package/server/{issue-closed-dvEWKO7Q.js → issue-closed-6RQsAjDX.js} +7 -7
- package/server/{issue-lifecycle-3N8XF7lP.js → issue-lifecycle-D9nLErvS.js} +206 -29
- package/server/{issue-lifecycle-BI6jAfp8.js → issue-lifecycle-DOPVv7xz.js} +1 -1
- package/server/{issue-service-singleton-BN_2MXp4.js → issue-service-singleton-B2xy-IS9.js} +124 -11
- package/server/{issue-service-singleton-CL6hESX2.js → issue-service-singleton-CvgNAWqK.js} +1 -1
- package/server/issue-title-fallback-DTSCQVu0.js +120 -0
- package/server/{issues-CkvUoAnq.js → issues-e_Ck1Ln2.js} +2 -2
- package/server/{jsonl-parser-CrEb2PWr.js → jsonl-parser-DqxVCZ1k.js} +3 -3
- package/server/jsonl-resolver-07OS3qOr.js +324 -0
- package/server/{kimi-code-C26gmGxM.js → kimi-code-BjtAHIz1.js} +14 -12
- package/server/{kimi-code-DoMoGqIu.js → kimi-code-vtXl2DR5.js} +1 -1
- package/server/{kimi-parser-Dmhy3UlR.js → kimi-parser-B1lgy2Vt.js} +2 -2
- package/server/{label-cleanup-X2lWfghH.js → label-cleanup-D2zUMasf.js} +3 -3
- package/server/{lifecycle-Bg44O-9x.js → lifecycle-0NOEzomy.js} +2 -2
- package/server/{lifecycle-B0rL38D3.js → lifecycle-DaCovZwn.js} +6 -6
- package/server/{lifecycle-io-CCBpRv5m.js → lifecycle-io-6WL46dsB.js} +5 -5
- package/server/{lifecycle-io-DQDU0apV.js → lifecycle-io-BBMTaP7S.js} +1 -1
- package/server/{linear-client-B0cIkTs4.js → linear-client-7fQThJTc.js} +3 -3
- package/server/{linear-client-6V2E-DSa.js → linear-client-BTGApNLo.js} +1 -1
- package/server/{linear-mcp-auth-LCo9AWUd.js → linear-mcp-auth-B8pYRsiU.js} +1 -1
- package/server/{linear-mcp-auth-Dsu9Io9r.js → linear-mcp-auth-Nk5s3L9M.js} +5 -5
- package/server/memory-fts-worker.js +1 -1
- package/server/{memory-governor-A4O6vI9d.js → memory-governor-Cqvbusr4.js} +14 -14
- package/server/{memory-pressure-patrol-BWlWywmA.js → memory-pressure-patrol-DPb8foam.js} +5 -5
- package/server/{merge-BGWcBxku.js → merge-BB_bjJ9a.js} +1 -1
- package/server/{merge-vz80RvSE.js → merge-FZ78_cEz.js} +3 -3
- package/server/{merge-agent-GWhmnxFk.js → merge-agent-B3jRrlS1.js} +37 -33
- package/server/{merge-agent-BRSz26Oh.js → merge-agent-BuoC_PRZ.js} +2 -2
- package/server/{merge-batch-CFMEtTxv.js → merge-batch-B8bVjFWS.js} +1 -1
- package/server/{merge-completeness-CP347umA.js → merge-completeness-DQt7Qa7i.js} +4 -4
- package/server/{merge-completeness-7ajHAIR-.js → merge-completeness-DkdabVch.js} +1 -1
- package/server/merge-ops-DabXHp2i.js +2 -0
- package/server/merge-rebase-CXq0qsgR.js +2 -0
- package/server/{merge-rebase-C5htyEEH.js → merge-rebase-qq40s91P.js} +2 -2
- package/server/{merge-set-DsGW8fmc.js → merge-set-BTNYvxM3.js} +1 -1
- package/server/{merge-set-eiE2nC6C.js → merge-set-BmRRflt0.js} +4 -4
- package/server/{merge-sync-CM2-myXu.js → merge-sync-0m2Q087q.js} +1 -1
- package/server/{merge-sync-Ct0-cxMX.js → merge-sync-CJpOa0cZ.js} +2 -2
- package/server/{merge-train-deps-LXHGK61n.js → merge-train-deps-CH5Mr3vN.js} +4 -4
- package/server/{merge-train-BOu3fN7O.js → merge-train-iwKqjtCF.js} +4 -4
- package/server/{merge-verification-BRp08IzI.js → merge-verification-JJc5GC2t.js} +6 -6
- package/server/{merged-docker-cleanup-worker-CwldDjHV.js → merged-docker-cleanup-worker-BOqWA373.js} +4 -4
- package/server/{merged-docker-cleanup-worker-C8eGn78a.js → merged-docker-cleanup-worker-CrhTdxZV.js} +1 -1
- package/server/messaging-nuwStbdQ.js +3 -0
- package/server/{multipart-parser-OAuW7824.js → multipart-parser-DxuW_rZV.js} +2 -2
- package/server/{no-resume-mode-MWI6pnrK.js → no-resume-mode-xuYLFhLw.js} +1 -1
- package/server/node_modules/.package-lock.json +11 -11
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/AGENTS.md +14 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/CLAUDE.md +14 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/README.md +10 -3
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/40_sql/10_basics.ts +175 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/40_sql/index.md +6 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/10_basics.ts +3 -1
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/20_testing.ts +100 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/fixtures/api/Users.ts +30 -14
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/fixtures/domain/User.ts +15 -6
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/fixtures/server/Authorization.ts +11 -10
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/fixtures/server/Users/http.ts +41 -32
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/fixtures/server/Users.ts +141 -20
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/70_cli/10_basics.ts +27 -3
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.d.ts.map +1 -1
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.js +10 -9
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.js.map +1 -1
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeSocketServer.js +4 -4
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeSocketServer.js.map +1 -1
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeStream.d.ts.map +1 -1
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeStream.js +10 -4
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeStream.js.map +1 -1
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/internal/nodeChildProcessSpawner.d.ts +4 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/internal/nodeChildProcessSpawner.d.ts.map +1 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/internal/nodeChildProcessSpawner.js +10 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/internal/nodeChildProcessSpawner.js.map +1 -0
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/package.json +4 -4
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/NodeChildProcessSpawner.ts +16 -11
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/NodeSocketServer.ts +4 -4
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/NodeStream.ts +10 -4
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/internal/nodeChildProcessSpawner.ts +16 -0
- package/server/node_modules/ansi-regex/index.js +3 -2
- package/server/node_modules/ansi-regex/package.json +1 -1
- package/server/node_modules/gaxios/build/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/server/node_modules/gaxios/build/esm/tsconfig.tsbuildinfo +1 -1
- package/server/node_modules/gaxios/package.json +3 -3
- package/server/{orphan-proposed-reconciler-cV3URUqk.js → orphan-proposed-reconciler-Dmk0kO_p.js} +24 -23
- package/server/{orphan-proposed-reconciler-BAE5AZ_e.js → orphan-proposed-reconciler-gf4TxfZb.js} +2 -2
- package/server/package-lock.json +12 -12
- package/server/package.json +1 -1
- package/server/{pan-dir-DDd91kMb.js → pan-dir-BMda7tQj.js} +5 -5
- package/server/{deacon-merge-BOGFEV8_.js → parked-residue-BiHb8cD7.js} +150 -35
- package/server/{paths-CRLnDgcI.js → paths-DEe9j-kw.js} +2 -2
- package/server/{pending-lifecycle-claim-CYgMiDAP.js → pending-lifecycle-claim-J5uIIJPu.js} +2 -2
- package/server/{pickup-BjJsSX12.js → pickup-D1UbSDPd.js} +1 -1
- package/server/{pipeline-agent-reader-BLc43dVJ.js → pipeline-agent-reader-D-6okryb.js} +5 -5
- package/server/{pipeline-membership-5qlRz5Qg.js → pipeline-membership-CCbgBzNC.js} +1 -1
- package/server/{pipeline-membership-BHZp_ShY.js → pipeline-membership-PGX3Pe8V.js} +1 -1
- package/server/{pipeline-membership-gather-CGFY1v-y.js → pipeline-membership-gather-BK4dzh0X.js} +17 -12
- package/server/{pipeline-membership-gather-WhRc1yke.js → pipeline-membership-gather-BRhU7XPx.js} +1 -1
- package/server/{pipeline-notifier-BmsLWM_2.js → pipeline-notifier-BNAV9kpa.js} +2 -2
- package/server/{pipeline-notifier-C4fZ2ito.js → pipeline-notifier-DvHLaXKb.js} +1 -1
- package/server/{post-merge-lifecycle-worker-KK1RTKRE.js → post-merge-lifecycle-worker-DAWgzXQA.js} +3 -3
- package/server/{post-merge-state-_Lj3LDLh.js → post-merge-state-DC2_0t12.js} +4 -4
- package/server/prd-locations-BbAvqQmT.js +124 -0
- package/server/{project-pipelines-CCkebHOu.js → project-pipelines-By_5WcT4.js} +2 -2
- package/server/{project-repos-B4MK48j4.js → project-repos--QeCg7yQ.js} +29 -3
- package/server/project-repos-3bI6t4fO.js +3 -0
- package/server/project-resource-refresh-queue-BaZC79S3.js +2 -0
- package/server/project-resource-refresh-queue-x-K9mvpP.js +865 -0
- package/server/{projects-DvPEAP18.js → projects-LftaVK99.js} +1 -1
- package/server/{prompts-BiS5I2tZ.js → prompts-BotGu-6W.js} +2 -2
- package/server/{providers-DrfK0Ip8.js → providers-BL1I66sM.js} +7 -7
- package/server/providers-Dqgz3MY5.js +3 -0
- package/server/public/assets/{chunk-BO2N2NFS-GtVe_o56.js → chunk-BO2N2NFS-D5Fz5jND.js} +4 -4
- package/server/public/assets/{diagram-OG6HWLK6-BvhcYYHc.js → diagram-OG6HWLK6-Eux0gWFq.js} +1 -1
- package/server/public/assets/{dist-D0ryefak.js → dist-C3zShwhA.js} +1 -1
- package/server/public/assets/{dist-CSmUXazd.js → dist-D-JX_u7m.js} +3 -3
- package/server/public/assets/{ganttDiagram-6RSMTGT7-BXA51DzM.js → ganttDiagram-6RSMTGT7-UH3aweia.js} +1 -1
- package/server/public/assets/{highlighted-body-OFNGDK62-mlV4EpWt.js → highlighted-body-OFNGDK62-ccIQ-WXS.js} +1 -1
- package/server/public/assets/index-2wV4ipy_.css +1 -0
- package/server/public/assets/index-BTVcdPve.js +860 -0
- package/server/public/assets/{linear-BPE7oswm.js → linear-Cnnu4YQy.js} +1 -1
- package/server/public/assets/mermaid-GHXKKRXX-Bjto8iJh.js +1 -0
- package/server/public/assets/{pieDiagram-4H26LBE5-BguGGV3S.js → pieDiagram-4H26LBE5-BD8-Tye6.js} +1 -1
- package/server/public/assets/{prod-aKDYUrXQ.js → prod-Ca6aKMts.js} +4 -4
- package/server/public/assets/{quadrantDiagram-W4KKPZXB-Bx3i4B6H.js → quadrantDiagram-W4KKPZXB-BmSrVyFD.js} +1 -1
- package/server/public/assets/{sankeyDiagram-5OEKKPKP-B5vuLjA4.js → sankeyDiagram-5OEKKPKP-CEGy8Das.js} +1 -1
- package/server/public/assets/{xychartDiagram-2RQKCTM6-HPlpkqsN.js → xychartDiagram-2RQKCTM6-VnQ8iY8s.js} +1 -1
- package/server/public/index.html +2 -2
- package/server/{pull-requests-BcHIsFJv.js → pull-requests-Cp_FDT8-.js} +3 -3
- package/server/pull-requests-jVGcVq5G.js +2 -0
- package/server/rally-CxhVgIQ6.js +3 -0
- package/server/{rally-api-ShZ4kvn0.js → rally-api-CqAIJ8RX.js} +2 -2
- package/server/{rally-api-u_vkr5c_.js → rally-api-Ij1Zt0NI.js} +1 -1
- package/server/{rally-B1OMtzch.js → rally-bQpBzUNf.js} +3 -3
- package/server/{rally-client-DgZvUZqX.js → rally-client-CN5vh4Ac.js} +1 -1
- package/server/{rally-client-D6Feq1Ka.js → rally-client-qKbCNRVW.js} +5 -5
- package/server/{reap-terminal-sessions-CRfiXLY0.js → reap-terminal-sessions-BaDSNR-k.js} +2 -2
- package/server/{reap-terminal-sessions-D7f3zSE9.js → reap-terminal-sessions-DgEIKMhH.js} +2 -2
- package/server/{rebuild-stack-DKxOnkpE.js → rebuild-stack-BNOMVh7C.js} +7 -7
- package/server/{rebuild-stack-CCwKHZb6.js → rebuild-stack-DrMyA_mA.js} +2 -2
- package/server/{reconstruct-cache-BP8UIKt7.js → reconstruct-cache-mxIYCnqs.js} +7 -7
- package/server/{record-By-wp6pg.js → record-Ug18Cp4V.js} +1 -1
- package/server/{record-update-ByGtIlUK.js → record-update-WyhsREoH.js} +1 -1
- package/server/{record-update-D23jPU6b.js → record-update-dBGxL9OC.js} +8 -6
- package/server/{recovery-trip-C4dTl8DO.js → recovery-trip-BKLrL6NX.js} +43 -10
- package/server/{recovery-trip-qloOYOFz.js → recovery-trip-wFAixKsg.js} +1 -1
- package/server/{release-engine-Crc0Tjx-.js → release-engine-D9gaCBn9.js} +5 -5
- package/server/{release-set-DDXwbIK7.js → release-set-DPHHzEGx.js} +3 -3
- package/server/{remote-CBpLi4Yy.js → remote-BU6ONLpv.js} +3 -3
- package/server/{remote-oEMfXlwT.js → remote-BUEeUic6.js} +3 -3
- package/server/{remote-agents-DQVGZVQ9.js → remote-agents-BVtASiOF.js} +1 -1
- package/server/{remote-agents-Bgtc2nOO.js → remote-agents-CSaTLi3u.js} +6 -6
- package/server/{remote-completion-DxUJ5HKR.js → remote-completion-CBV3b9TI.js} +13 -13
- package/server/{resolver-C8rooxoz.js → resolver-DvSMXty7.js} +31 -8
- package/server/{resolver-CuAULbLs.js → resolver-gxv97jsQ.js} +2 -2
- package/server/resume-DvHuF-bm.js +3 -0
- package/server/review-agent-DgkUPRx0.js +3 -0
- package/server/{review-agent-7C2w5CzU.js → review-agent-esZ0QXdY.js} +43 -55
- package/server/{review-artifacts-BJeEfm2r.js → review-artifacts-DGGEobLp.js} +6 -6
- package/server/{review-convoy-liveness-DfF9eXjI.js → review-convoy-liveness-DmO8dIBH.js} +20 -11
- package/server/{review-run-recovery-7BKt2Es0.js → review-run-recovery-Ct0q7FkE.js} +3 -3
- package/server/{review-run-recovery-ZjuDTNhZ.js → review-run-recovery-DHiiw7d8.js} +1 -1
- package/server/{review-status-CUnjjOUu.js → review-status-C_kQeeX0.js} +1 -1
- package/server/{review-status-emit-Cg4tOb8U.js → review-status-emit-BZz1Y_22.js} +3 -3
- package/server/{review-status-enrichment-D-rQshu6.js → review-status-enrichment-BWH0XW_m.js} +3 -3
- package/server/{review-status-source-DSn0glLa.js → review-status-source-D2PCWS6E.js} +1 -1
- package/server/{review-status-source-Ct912fv_.js → review-status-source-Jq0BXmn3.js} +1 -1
- package/server/{review-status-sync-B7V_Gg51.js → review-status-sync-2C9lk85r.js} +2 -2
- package/server/{review-status-sync-YthpOH_q.js → review-status-sync-Bq00Loey.js} +1 -1
- package/server/{review-status-DBnR5t4z.js → review-status-yOGD2MuK.js} +86 -27
- package/server/{review-verdict-feedback-DqXTuJk8.js → review-verdict-feedback-Brjaxoda.js} +1 -1
- package/server/{review-verdict-feedback-C-dBon_-.js → review-verdict-feedback-CE_tr2iQ.js} +8 -8
- package/server/{review-verdict-writer-jldSh3Bm.js → review-verdict-writer-CD-4kDVx.js} +1 -1
- package/server/{review-verdict-writer-CKaJWp75.js → review-verdict-writer-Ca2V7QSY.js} +7 -7
- package/server/{rollup-DZwH4CLs.js → rollup--g9ik1XQ.js} +1 -1
- package/server/{rollup-QCwYcBdP.js → rollup-B6g9Nr6L.js} +8 -8
- package/server/{scanner-2aHeLC3W.js → scanner-YxIv-fG1.js} +8 -8
- package/server/{search-DwHYaj66.js → search-DqMN4__-.js} +2 -2
- package/server/{secret-redaction-B5G1xZ3k.js → secret-redaction-DLZ-VqHq.js} +1 -1
- package/server/{sequence-io-POKWdusG.js → sequence-io--b3_PsWq.js} +4 -4
- package/server/{sequencer-agent-DS00KHVm.js → sequencer-agent-CqouKVZG.js} +6 -6
- package/server/server.js +1115 -1269
- package/server/{service-BLb_CyPL.js → service-CEp-3iow.js} +64 -63
- package/server/{session-fork-DcTzVwex.js → session-fork-GtoeCh2H.js} +2 -2
- package/server/{settings-Clw8UVNs.js → settings-CLQcdkoD.js} +2 -2
- package/server/{settings-B9-H2K_E.js → settings-Ch2pCVtt.js} +3 -3
- package/server/settings-DhtPDmmI.js +2 -0
- package/server/{shadow-engineering-C6oO_PiR.js → shadow-engineering-BxiFrIKv.js} +3 -3
- package/server/{shadow-state-CEGrrECe.js → shadow-state-CSA1vtxr.js} +2 -2
- package/server/{shadow-state-e7250VUx.js → shadow-state-nGhCNXT2.js} +1 -1
- package/server/{shadow-utils-xFk2Wusb.js → shadow-utils-7q5QDmMj.js} +2 -2
- package/server/{ship-log-7BnQHuKU.js → ship-log-ie0A_SqV.js} +1 -1
- package/server/{ship-record-CwUX6Afo.js → ship-record-BM3oVvnL.js} +7 -7
- package/server/{ship-record-BgUPnpT0.js → ship-record-DHWH1hLz.js} +1 -1
- package/server/{ship-status-Ce3_3edi.js → ship-status-BEkddXMT.js} +2 -2
- package/server/{smart-compaction-BmfIi3oL.js → smart-compaction-BkzjVpWL.js} +1 -1
- package/server/{smart-compaction-Dy0gw1VH.js → smart-compaction-D0TE1lBD.js} +7 -7
- package/server/{spawn-planning-session-nH3b4Drz.js → spawn-planning-session-CkGweSCC.js} +19 -19
- package/server/{spawn-planning-session-CfhxRJoY.js → spawn-planning-session-s406rw1N.js} +2 -2
- package/server/{specialist-completion-CC1XJbTx.js → specialist-completion-CTAjwH5j.js} +1 -1
- package/server/{specialist-context-cHwpcXSh.js → specialist-context-CKasRfYu.js} +5 -5
- package/server/{specialist-handoff-logger-GqnGSYoJ.js → specialist-handoff-logger-DrjrOmmn.js} +2 -2
- package/server/{specialist-logs-5OTnrV91.js → specialist-logs-Du6quZ0_.js} +3 -3
- package/server/{specialists-xXcJHAyg.js → specialists-B-4zyE4Y.js} +1 -1
- package/server/{specialists-8LcQi9Np.js → specialists-CuDWiNdB.js} +21 -272
- package/server/{specialists-DocAK-7A.js → specialists-b0dMMjWq.js} +148 -685
- package/server/specialists-registry-1y6Rt_F1.js +3 -0
- package/server/specialists-registry-BYjs04iK.js +277 -0
- package/server/specialists-x-kPMhrL.js +4 -0
- package/server/specs-IYsFlM-L.js +3 -0
- package/server/{src-DudQNYVw.js → src-CY2Wl8IX.js} +337 -6
- package/server/{src-C2TAxwki.js → src-CZsPs61V.js} +6 -6
- package/server/{src-DUVvEA8Q.js → src-DeQwpuh6.js} +3 -3
- package/server/{stack-health-DKT4ySnA.js → stack-health-BQFSJc0l.js} +3 -3
- package/server/{stack-health-CbyiYS9H.js → stack-health-ypIKtkbE.js} +1 -1
- package/server/{stale-task-claims-PzFee70R.js → stale-task-claims-C2e1zdMT.js} +5 -5
- package/server/{staleness-BjOAq9-d.js → staleness-CRDK6LFG.js} +1 -1
- package/server/{staleness-D8UTEXV5.js → staleness-Fzx_3_Hr.js} +1 -1
- package/server/{stall-sweeper-DOyIfeLR.js → stall-sweeper-QNk4h9m6.js} +8 -8
- package/server/{state-home-DhAZlk5k.js → state-home-DdG8erBI.js} +2 -2
- package/server/{state-mapping-BVSs84bO.js → state-mapping-D2yC81Vy.js} +1 -1
- package/server/{state-migrate-CJKEwpB0.js → state-migrate-C6H3jfHE.js} +6 -6
- package/server/{state-mirror-Do7pag7W.js → state-mirror-DF4Lfxm0.js} +3 -3
- package/server/stuck-remediation-BDa_tXgB.js +774 -0
- package/server/stuck-remediation-BVNd9txd.js +2 -0
- package/server/{substrate-bug-weights-service-BTNjHBnl.js → substrate-bug-weights-service-BbbCZEtJ.js} +3 -3
- package/server/{summary-fork-CZ88rhVx.js → summary-fork-BvcW6bq0.js} +113 -30
- package/server/{summary-fork-CvB7Oyq9.js → summary-fork-DIQmtOuV.js} +2 -2
- package/server/supervisor/{pane-composer-BaLLspSj.js → pane-composer-CoiVkGIt.js} +8 -1
- package/server/supervisor/{paths-D6XUcR_g.js → paths-DTGbtcaP.js} +8 -4
- package/server/supervisor/pty-supervisor.js +3 -3
- package/server/supervisor/{pty-token-DjjHxoCq.js → pty-token-GVqnvU3U.js} +2 -2
- package/server/{supervisor-D4v0WfiQ.js → supervisor-D3jC2c7A.js} +4 -4
- package/server/supervisor-v0cYN2Vp.js +2 -0
- package/server/{swarm-readiness-D8R-LWX5.js → swarm-readiness-CMWAQuWM.js} +3 -3
- package/server/{synthesis-verdict-B6wvLGcA.js → synthesis-verdict-C-pJOPsn.js} +1 -1
- package/server/{synthesis-verdict-N5Z11pg7.js → synthesis-verdict-DVlrLF9A.js} +2 -2
- package/server/{system-prerequisites-BbGZ_WHF.js → system-prerequisites-QKtIYXI2.js} +2 -2
- package/server/{teardown-workspace-CYend-KY.js → teardown-workspace-cJea1OLo.js} +16 -16
- package/server/{test-agent-queue-BUtWhNcc.js → test-agent-queue-C5DI_gWX.js} +6 -6
- package/server/{test-verdict-BWm3hgDj.js → test-verdict-C7kmd2_Y.js} +1 -1
- package/server/{test-verdict-BWtRmdiR.js → test-verdict-DUbDHqeD.js} +2 -2
- package/server/{tldr-daemon-CneJ24eL.js → tldr-daemon-BNQHwblU.js} +1 -1
- package/server/{tldr-daemon-CMVBT4kT.js → tldr-daemon-CO08YlfQ.js} +2 -2
- package/server/tmux-B8zsqD_6.js +4 -0
- package/server/{tmux-BqXzRuaH.js → tmux-DWEc4Ld9.js} +91 -19
- package/server/{token-CO3INKbh.js → token-Bez-qCB2.js} +2 -2
- package/server/{token-util-DyJJyX_B.js → token-util-Crcay9j_.js} +1 -1
- package/server/token-util-DfUS3Lpp.js +3 -0
- package/server/{tracker-config-DVzhaUxO.js → tracker-config-CJzPhSHv.js} +2 -2
- package/server/{tracker-utils-xnVJVrrO.js → tracker-utils-DJAOAuMN.js} +2 -2
- package/server/{traefik-connect-A5k54mCv.js → traefik-connect-D3H5I6b9.js} +1 -1
- package/server/{tunnel-DauSR-rs.js → tunnel-BSdKnW0U.js} +1 -1
- package/server/{tunnel-CwOnS-PB.js → tunnel-Cr3ctqxp.js} +3 -3
- package/server/{typed-errors-B-gfU2RB.js → typed-errors-CZ3GFBvo.js} +1 -1
- package/server/{typed-errors-DzC4zXbI.js → typed-errors-DXqf3RnP.js} +1 -1
- package/server/{types-DjpLVpsj.js → types-fzBp9cYi.js} +1 -1
- package/server/{types-DbxY2QB6.js → types-pLpbsNto.js} +1 -1
- package/server/{uat-failure-feedback-BVqsWlrr.js → uat-failure-feedback-IZQ-J8jt.js} +5 -5
- package/server/{uat-promote-verification-DmG097QS.js → uat-promote-verification-DXApKcc2.js} +5 -5
- package/server/{uat-train-COSy-vEX.js → uat-train-CycEzpbE.js} +1 -1
- package/server/{uat-train-DVUNW03P.js → uat-train-IIZlz7r3.js} +0 -0
- package/server/{validate-Dvv83iBx.js → validate-Ur4xH5bN.js} +3 -3
- package/server/{validation-BdCjzWLN.js → validation-CHovCoTT.js} +1 -1
- package/server/{validation-DlHafKzu.js → validation-Dr6V4PXx.js} +9 -6
- package/server/{verification-artifact-CaSbxUVg.js → verification-artifact-D3viYe_t.js} +1 -1
- package/server/{verification-artifact-0Zku8N-W.js → verification-artifact-k5Ftpg0c.js} +1 -1
- package/server/{verification-runner-C6wdZda2.js → verification-runner-BuqGwm2t.js} +1 -1
- package/server/{verification-runner-DwP2fUEF.js → verification-runner-Dl13mmsI.js} +53 -27
- package/server/{vtt-parser-luerJpYT.js → vtt-parser-BSnAB-Og.js} +1 -1
- package/server/work-agent-prompt-CJJ4tXci.js +3 -0
- package/server/{work-agent-prompt--9AWNYwZ.js → work-agent-prompt-CioeOuM4.js} +14 -14
- package/server/{work-agent-start-BNQO65W7.js → work-agent-start-B65Gqn9N.js} +2 -2
- package/server/{work-agent-start-DkzseQFl.js → work-agent-start-Ct1HVh6z.js} +1 -1
- package/server/{workflows-BYwR2aIN.js → workflows-AgFul1xc.js} +114 -41
- package/server/workflows-CfHm8lVd.js +2 -0
- package/server/{workspace-B-QJa3Ps.js → workspace-Cu3XlMXt.js} +1 -1
- package/server/{workspace-iTnTycOB.js → workspace-Cy4sDd3q.js} +3 -3
- package/server/{workspace-anchor-drift-DTt6h2Em.js → workspace-anchor-drift-BI0Hz6zI.js} +1 -1
- package/server/{workspace-anchor-drift-CHiGg8iu.js → workspace-anchor-drift-CMaqvizr.js} +4 -4
- package/server/{workspace-config-D0CavVtz.js → workspace-config-DRYDO7Zr.js} +1 -1
- package/server/{workspace-manager-W1OnbvU5.js → workspace-manager-CgovxDrO.js} +17 -17
- package/server/{workspace-manager-5BKPV6SY.js → workspace-manager-jfkKAEuO.js} +1 -1
- package/server/{workspace-metadata-tbbevEmP.js → workspace-metadata-BDqXzGGK.js} +1 -1
- package/server/{workspace-metadata-dJhXvZGQ.js → workspace-metadata-BNzODIv6.js} +2 -2
- package/server/{workspaces-BlpbOPZ7.js → workspaces-BJdPqx_J.js} +131 -127
- package/sync-sources/dev-skills/pan-style-guide/SKILL.md +90 -15
- package/sync-sources/hooks/linear-mcp-auth-hook +6 -1
- package/sync-sources/rules/handoff-isolate-cwd.md +4 -4
- package/sync-sources/rules/pan-handoff-focus-limit.md +12 -5
- package/sync-sources/rules/ste-writing.md +17 -0
- package/sync-sources/rules/work-agents-via-pan.md +2 -1
- package/sync-sources/rules/writing-style.md +3 -2
- package/sync-sources/skills/{skill-creator → claude-skill-creator}/SKILL.md +1 -1
- package/sync-sources/skills/{skill-creator → claude-skill-creator}/scripts/init_skill.py +1 -1
- package/sync-sources/skills/{skill-creator → claude-skill-creator}/scripts/package_skill.py +1 -1
- package/sync-sources/skills/pan-gauntlet-loop/SKILL.md +182 -0
- package/sync-sources/skills/pan-gauntlet-loop/assets/PROMPT.template.md +92 -0
- package/sync-sources/skills/pan-gauntlet-loop/assets/REFERENCE-BAR.template.md +53 -0
- package/sync-sources/skills/pan-gauntlet-loop/assets/STYLE.template.md +41 -0
- package/sync-sources/skills/pan-gauntlet-loop/assets/gauntlet-index.html +237 -0
- package/sync-sources/skills/pan-gauntlet-loop/references/domains.md +106 -0
- package/sync-sources/skills/pan-gauntlet-loop/references/lessons.md +60 -0
- package/sync-sources/skills/pan-handoff/SKILL.md +13 -6
- package/sync-sources/skills/pan-help/SKILL.md +1 -1
- package/sync-sources/skills/pan-peer-review/SKILL.md +3 -3
- package/sync-sources/skills/pan-restart/SKILL.md +6 -3
- package/sync-sources/skills/pan-start/SKILL.md +3 -0
- package/sync-sources/skills/pan-swarm/SKILL.md +32 -44
- package/sync-sources/skills/pan-sync/SKILL.md +1 -1
- package/server/activity-logger-BejO16Am.js +0 -3
- package/server/agent-state-DH_-Jkua.js +0 -3
- package/server/agents-megfmQHM.js +0 -3
- package/server/archive-planning-C-H9cM_J.js +0 -2
- package/server/build-info-PQlh_Rhb.js +0 -2
- package/server/cli-TaZspPHS.js +0 -2
- package/server/cliproxy-36ncAXlu.js +0 -3
- package/server/context-layers-CF6zHws4.js +0 -4
- package/server/conversations-AnGJ5rtX.js +0 -3
- package/server/deacon-BEH-IY0v.js +0 -5
- package/server/deacon-swarm-BHX-kR1b.js +0 -2
- package/server/deacon-swarm-BiLfNm_v.js +0 -1522
- package/server/dead-end-trip-BWpDg1Qd.js +0 -2
- package/server/delivery-cJM6zRjJ.js +0 -3
- package/server/deploy-queue-CmVBZEja.js +0 -2
- package/server/dist-VKBfkdi7.js +0 -3
- package/server/durable-review-pipeline-DgcVCYDL.js +0 -3
- package/server/factory-D4V2wd_V.js +0 -717
- package/server/forge-CrP1L3i6.js +0 -2
- package/server/hume-1ubD_6O7.js +0 -3
- package/server/inspect-agent-CfxERkNt.js +0 -2
- package/server/merge-ops-DtHx17Vd.js +0 -2
- package/server/merge-rebase-BvB4UuNS.js +0 -2
- package/server/project-repos-BJiShUsN.js +0 -3
- package/server/providers-CStNGwze.js +0 -3
- package/server/public/assets/index-BFEwfmqX.js +0 -860
- package/server/public/assets/index-_USwyTAT.css +0 -1
- package/server/public/assets/mermaid-GHXKKRXX-Dsln95SK.js +0 -1
- package/server/pull-requests-C1Cqp2yo.js +0 -2
- package/server/rally-CjayjUIl.js +0 -3
- package/server/resume-D7JuMCRQ.js +0 -3
- package/server/review-agent-BUNTVJK2.js +0 -2
- package/server/settings-DBWB1gsG.js +0 -2
- package/server/specialists-D8gsOCwh.js +0 -3
- package/server/specs-BqkrRnU9.js +0 -3
- package/server/stuck-remediation-Di5JYkoo.js +0 -1164
- package/server/stuck-remediation-TNM1VhZb.js +0 -2
- package/server/supervisor-DX8VsPnb.js +0 -2
- package/server/tmux-CqNapnrr.js +0 -4
- package/server/token-util-Bu8bPF9f.js +0 -3
- package/server/workflows-Cf4LAnhg.js +0 -2
|
@@ -0,0 +1,865 @@
|
|
|
1
|
+
import { On as resolveProjectFromIssueSync, fn as init_projects, vn as listProjectsSync } from "./config-yaml-D9nfpEx1.js";
|
|
2
|
+
import { o as init_resolver, u as listWorkspaces } from "./resolver-gxv97jsQ.js";
|
|
3
|
+
import { r as compareIssueIds, t as init_src } from "./src-CY2Wl8IX.js";
|
|
4
|
+
import { An as init_runtime_census, On as getRuntimeCensus, U as getAgentRuntimeState, q as init_agents } from "./agent-state-BJhGIJZe.js";
|
|
5
|
+
import { A as init_conversations, P as listConversations } from "./conversations-C75EFFjf.js";
|
|
6
|
+
import { a as PAN_DIRNAME, i as PAN_CONTINUE_FILENAME } from "./types-pLpbsNto.js";
|
|
7
|
+
import { C as init_specs, S as findSpecByIssue } from "./io-DKrWd3gX.js";
|
|
8
|
+
import { t as init_pan_dir } from "./pan-dir-BMda7tQj.js";
|
|
9
|
+
import { r as resolveMissingIssueTitles, t as init_issue_title_fallback } from "./issue-title-fallback-DTSCQVu0.js";
|
|
10
|
+
import { m as loadReadyForMergeFlags, p as init_review_status } from "./review-status-yOGD2MuK.js";
|
|
11
|
+
import { A as createSettledTtlPromiseCache, j as init_concurrency, k as createPromiseConcurrencyLimiter } from "./github-app-7ywLhuZO.js";
|
|
12
|
+
import { t as resolveAgentGitInfo } from "./git-info-BSrI9owC.js";
|
|
13
|
+
import { n as findDraftPrd } from "./prd-locations-BbAvqQmT.js";
|
|
14
|
+
import { a as gatherProjectLensSignals, g as parseIssueIdFromTextSync, h as init_resource_utils, n as PipelineMembershipUnavailableError, s as init_pipeline_membership_gather, u as listOpenPullRequestsSnapshot } from "./pipeline-membership-gather-BK4dzh0X.js";
|
|
15
|
+
import { n as init_pipeline_membership, r as resolvePipelineMembership } from "./pipeline-membership-PGX3Pe8V.js";
|
|
16
|
+
import { basename, join } from "node:path";
|
|
17
|
+
import { Effect } from "effect";
|
|
18
|
+
import { readdir, stat } from "node:fs/promises";
|
|
19
|
+
import { execFile } from "node:child_process";
|
|
20
|
+
import { promisify } from "node:util";
|
|
21
|
+
//#region services/resource-discovery-shared.ts
|
|
22
|
+
init_projects();
|
|
23
|
+
init_src();
|
|
24
|
+
init_conversations();
|
|
25
|
+
init_runtime_census();
|
|
26
|
+
const execFileAsync$1 = promisify(execFile);
|
|
27
|
+
async function loadTrackerIssues() {
|
|
28
|
+
const map = /* @__PURE__ */ new Map();
|
|
29
|
+
try {
|
|
30
|
+
const { getSharedIssueService } = await import("./issue-service-singleton-CvgNAWqK.js");
|
|
31
|
+
const issues = (await getSharedIssueService()).getIssues();
|
|
32
|
+
for (const issue of issues) if (issue.identifier) map.set(issue.identifier.toUpperCase(), issue);
|
|
33
|
+
} catch {}
|
|
34
|
+
return map;
|
|
35
|
+
}
|
|
36
|
+
async function loadDockerContainers() {
|
|
37
|
+
try {
|
|
38
|
+
const { stdout } = await execFileAsync$1("docker", [
|
|
39
|
+
"ps",
|
|
40
|
+
"--format",
|
|
41
|
+
"{{.Names}}"
|
|
42
|
+
], {
|
|
43
|
+
encoding: "utf-8",
|
|
44
|
+
timeout: 5e3
|
|
45
|
+
});
|
|
46
|
+
return stdout.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
47
|
+
} catch {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async function loadActiveRemoteAgentStates() {
|
|
52
|
+
try {
|
|
53
|
+
const { listActiveRemoteAgentStates } = await import("./remote-agents-BVtASiOF.js");
|
|
54
|
+
return listActiveRemoteAgentStates();
|
|
55
|
+
} catch {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function captureSharedResourceSignals() {
|
|
60
|
+
const [trackerIssues, runtimeCensus, dockerContainers, remoteAgentStates] = await Promise.all([
|
|
61
|
+
loadTrackerIssues(),
|
|
62
|
+
getRuntimeCensus(),
|
|
63
|
+
loadDockerContainers(),
|
|
64
|
+
loadActiveRemoteAgentStates()
|
|
65
|
+
]);
|
|
66
|
+
const tmuxSessions = [...runtimeCensus.sessionNames];
|
|
67
|
+
let conversations = [];
|
|
68
|
+
try {
|
|
69
|
+
conversations = listConversations();
|
|
70
|
+
} catch {}
|
|
71
|
+
return {
|
|
72
|
+
trackerIssues,
|
|
73
|
+
tmuxSessions,
|
|
74
|
+
dockerContainers,
|
|
75
|
+
conversations,
|
|
76
|
+
remoteAgentStates
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region review-status.ts
|
|
81
|
+
init_resolver();
|
|
82
|
+
init_specs();
|
|
83
|
+
init_pan_dir();
|
|
84
|
+
init_agents();
|
|
85
|
+
init_concurrency();
|
|
86
|
+
init_resource_utils();
|
|
87
|
+
init_pipeline_membership_gather();
|
|
88
|
+
init_pipeline_membership();
|
|
89
|
+
init_review_status();
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region services/pipeline-membership.ts
|
|
92
|
+
init_issue_title_fallback();
|
|
93
|
+
const PIPELINE_MEMBERSHIP_TTL_MS = 3e4;
|
|
94
|
+
function createPipelineMembershipService(deps = {
|
|
95
|
+
gather: gatherProjectLensSignals,
|
|
96
|
+
now: () => Date.now()
|
|
97
|
+
}) {
|
|
98
|
+
const cachedGather = createSettledTtlPromiseCache(PIPELINE_MEMBERSHIP_TTL_MS, deps.now);
|
|
99
|
+
const service = async (project) => cachedGather(project.path, () => deps.gather(project).then((signals) => signals.map(resolvePipelineMembership)));
|
|
100
|
+
service.invalidate = (projectPath) => cachedGather.invalidate(projectPath);
|
|
101
|
+
return service;
|
|
102
|
+
}
|
|
103
|
+
const getProjectPipelineMembership = createPipelineMembershipService();
|
|
104
|
+
const membershipSnapshots = /* @__PURE__ */ new Map();
|
|
105
|
+
const scheduleMembershipRefresh = createPromiseConcurrencyLimiter(3);
|
|
106
|
+
function refreshMembershipSnapshot(project, snapshot, getMembership, now) {
|
|
107
|
+
if (snapshot.refresh) return snapshot.refresh;
|
|
108
|
+
snapshot.refresh = scheduleMembershipRefresh(() => getMembership(project)).then((value) => {
|
|
109
|
+
snapshot.value = value;
|
|
110
|
+
snapshot.refreshedAt = now();
|
|
111
|
+
snapshot.lastError = void 0;
|
|
112
|
+
snapshot.lastErrorReason = void 0;
|
|
113
|
+
snapshot.lastErrorAt = void 0;
|
|
114
|
+
}).catch((error) => {
|
|
115
|
+
snapshot.lastError = error instanceof Error ? error.message : String(error);
|
|
116
|
+
snapshot.lastErrorReason = error instanceof PipelineMembershipUnavailableError ? error.reason : "gather_failed";
|
|
117
|
+
snapshot.lastErrorAt = now();
|
|
118
|
+
console.warn(`[pipeline-membership] refresh failed for ${project.name ?? project.path}; keeping last-good snapshot:`, snapshot.lastError);
|
|
119
|
+
}).finally(() => {
|
|
120
|
+
snapshot.refresh = void 0;
|
|
121
|
+
});
|
|
122
|
+
return snapshot.refresh;
|
|
123
|
+
}
|
|
124
|
+
/** Read the latest successful snapshots without scheduling tracker or git work. */
|
|
125
|
+
function readPipelineMembershipSnapshotsForProjects(projects) {
|
|
126
|
+
return projects.map((project) => {
|
|
127
|
+
const snapshot = membershipSnapshots.get(project.path);
|
|
128
|
+
if (snapshot?.refreshedAt) return {
|
|
129
|
+
project,
|
|
130
|
+
memberships: snapshot.value
|
|
131
|
+
};
|
|
132
|
+
return {
|
|
133
|
+
project,
|
|
134
|
+
error: /* @__PURE__ */ new Error(snapshot?.lastError ? `Pipeline membership refresh failed: ${snapshot.lastError}` : "Pipeline membership snapshot is loading"),
|
|
135
|
+
unavailableReason: snapshot?.lastErrorReason
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* PAN-2893 — event-driven refresh. Invalidate the per-project TTL cache and
|
|
141
|
+
* force a snapshot re-gather NOW for the given projects, so agent lifecycle
|
|
142
|
+
* changes reach membership consumers without waiting out the 5-minute TTL.
|
|
143
|
+
* Refresh failures keep the last good snapshot (same policy as TTL refreshes).
|
|
144
|
+
*/
|
|
145
|
+
async function refreshMembershipSnapshotsForProjects(projects, getMembership = getProjectPipelineMembership, now = () => Date.now()) {
|
|
146
|
+
await Promise.all(projects.map(async (project) => {
|
|
147
|
+
getMembership.invalidate(project.path);
|
|
148
|
+
const snapshot = membershipSnapshots.get(project.path) ?? {
|
|
149
|
+
value: [],
|
|
150
|
+
refreshedAt: 0
|
|
151
|
+
};
|
|
152
|
+
membershipSnapshots.set(project.path, snapshot);
|
|
153
|
+
const inFlight = snapshot.refresh;
|
|
154
|
+
if (inFlight) {
|
|
155
|
+
await inFlight;
|
|
156
|
+
getMembership.invalidate(project.path);
|
|
157
|
+
}
|
|
158
|
+
await refreshMembershipSnapshot(project, snapshot, getMembership, now);
|
|
159
|
+
}));
|
|
160
|
+
}
|
|
161
|
+
function summarizePipelineMembership(membership) {
|
|
162
|
+
return {
|
|
163
|
+
available: true,
|
|
164
|
+
inPipeline: membership.inPipeline,
|
|
165
|
+
bucket: membership.bucket,
|
|
166
|
+
labelDrift: membership.labelDrift
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function unavailablePipelineMembership() {
|
|
170
|
+
return {
|
|
171
|
+
available: false,
|
|
172
|
+
inPipeline: false,
|
|
173
|
+
bucket: "clean_terminal",
|
|
174
|
+
labelDrift: null
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
//#endregion
|
|
178
|
+
//#region services/resource-discovery.ts
|
|
179
|
+
init_pipeline_membership();
|
|
180
|
+
init_pipeline_membership_gather();
|
|
181
|
+
const execFileAsync = promisify(execFile);
|
|
182
|
+
const RECENT_ACTIVITY_WINDOW_MS = 5e3;
|
|
183
|
+
const projectResourceSnapshots = /* @__PURE__ */ new Map();
|
|
184
|
+
let cachedResourceIssues = null;
|
|
185
|
+
let cachedDetailedResourceIssues = null;
|
|
186
|
+
function projectPrefixes(project) {
|
|
187
|
+
const prefixes = /* @__PURE__ */ new Set();
|
|
188
|
+
if (project.config.issue_prefix) prefixes.add(project.config.issue_prefix.toUpperCase());
|
|
189
|
+
for (const prefix of project.config.issue_prefixes ?? []) prefixes.add(prefix.toUpperCase());
|
|
190
|
+
if (prefixes.size === 0) prefixes.add(project.key.toUpperCase().replace(/-/g, ""));
|
|
191
|
+
return [...prefixes];
|
|
192
|
+
}
|
|
193
|
+
function deriveStateLabel(issue, hasTmux, hasFreshHeartbeat, membership) {
|
|
194
|
+
const trackerState = issue.trackerState ?? "";
|
|
195
|
+
if (membership?.bucket === "post_merge_limbo") return "Merged — Needs Close-Out";
|
|
196
|
+
if (membership?.lenses.L3_issueOpen === false) return hasTmux ? "Closed" : "Done";
|
|
197
|
+
if (issue.readyForMerge) return "In Review";
|
|
198
|
+
if (trackerState === "done" || trackerState === "closed" || trackerState === "canceled") return hasTmux ? "Closed" : "Done";
|
|
199
|
+
if (trackerState === "in_review") return "In Review";
|
|
200
|
+
if (trackerState === "in_progress") return "In Progress";
|
|
201
|
+
if (hasTmux && (issue.agentStatus === "active" || hasFreshHeartbeat)) return "In Progress";
|
|
202
|
+
if (issue.agentStatus === "suspended") return "Suspended";
|
|
203
|
+
if (issue.hasPrd && !issue.hasState) return "Planning";
|
|
204
|
+
if (issue.hasState) return "Has Context";
|
|
205
|
+
if (issue.resourceSources.has("workspace") || issue.resourceSources.has("branch")) return "Allocated";
|
|
206
|
+
return "Idle";
|
|
207
|
+
}
|
|
208
|
+
function sortPullRequests(prs) {
|
|
209
|
+
return [...prs].sort((a, b) => {
|
|
210
|
+
if (a.isDraft !== b.isDraft) return a.isDraft ? 1 : -1;
|
|
211
|
+
return a.number - b.number;
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
function summarizeResourceDetails(details) {
|
|
215
|
+
return {
|
|
216
|
+
hasWorkspace: details.workspacePath !== null,
|
|
217
|
+
localBranchCount: details.localBranches.length,
|
|
218
|
+
remoteBranchCount: details.remoteBranches.length,
|
|
219
|
+
tmuxSessionCount: details.tmuxSessions.length,
|
|
220
|
+
prs: sortPullRequests(details.prs).map((pr) => ({
|
|
221
|
+
number: pr.number,
|
|
222
|
+
title: pr.title,
|
|
223
|
+
url: pr.url,
|
|
224
|
+
state: pr.state,
|
|
225
|
+
isDraft: pr.isDraft
|
|
226
|
+
})),
|
|
227
|
+
hasXbrief: details.xbriefPath !== null,
|
|
228
|
+
hasTasks: details.tasksPath !== null,
|
|
229
|
+
hasPrd: details.prdPath !== null,
|
|
230
|
+
dockerContainerCount: details.dockerContainers.length,
|
|
231
|
+
actualBranch: details.actualBranch,
|
|
232
|
+
branchDrifted: details.branchDrifted,
|
|
233
|
+
branchAheadOfMain: details.branchAheadOfMain,
|
|
234
|
+
workspaceMissing: details.workspaceMissing,
|
|
235
|
+
remoteAgent: details.remoteAgent,
|
|
236
|
+
conversations: details.conversations.map((conv) => ({
|
|
237
|
+
id: conv.id,
|
|
238
|
+
name: conv.name,
|
|
239
|
+
title: conv.title,
|
|
240
|
+
status: conv.status
|
|
241
|
+
}))
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
function summarizeResourceDetailIdentifiers(details) {
|
|
245
|
+
return {
|
|
246
|
+
workspacePaths: details.workspacePath ? [details.workspacePath] : [],
|
|
247
|
+
localBranchNames: [...details.localBranches].sort(),
|
|
248
|
+
remoteBranchNames: [...details.remoteBranches].sort(),
|
|
249
|
+
tmuxSessionNames: [...details.tmuxSessions].sort(),
|
|
250
|
+
prs: sortPullRequests(details.prs).map((pr) => ({
|
|
251
|
+
number: pr.number,
|
|
252
|
+
title: pr.title,
|
|
253
|
+
state: pr.state,
|
|
254
|
+
isDraft: pr.isDraft
|
|
255
|
+
})),
|
|
256
|
+
dockerContainerNames: [...details.dockerContainers].sort()
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
function hasRecentActivity(lastActivity) {
|
|
260
|
+
return lastActivity !== null && Number.isFinite(lastActivity) && Date.now() - lastActivity < RECENT_ACTIVITY_WINDOW_MS;
|
|
261
|
+
}
|
|
262
|
+
function isLiveResource(issue) {
|
|
263
|
+
return issue.resourceDetails.remoteAgent !== null || issue.resourceDetails.tmuxSessions.length > 0 || issue.resourceDetails.dockerContainers.length > 0 || hasOpenPr(issue);
|
|
264
|
+
}
|
|
265
|
+
function isActiveTrackerState(state) {
|
|
266
|
+
return state === "in_progress" || state === "in_review" || state === "started";
|
|
267
|
+
}
|
|
268
|
+
function isTerminalTrackerState(state) {
|
|
269
|
+
return state === "closed" || state === "done" || state === "canceled" || state === "completed";
|
|
270
|
+
}
|
|
271
|
+
function hasOpenPr(issue) {
|
|
272
|
+
return issue.resourceDetails.prs.some((pr) => pr.state === "OPEN" || pr.state === "open");
|
|
273
|
+
}
|
|
274
|
+
function shouldLoadReviewStatus(issue) {
|
|
275
|
+
return issue.resourceSources.size > 0 && (!isTerminalTrackerState(issue.trackerState) || hasOpenPr(issue)) && (isLiveResource(issue) || isActiveTrackerState(issue.trackerState) && issue.branch != null);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* tmux session-name prefixes that map a session to its issue in the Command Deck
|
|
279
|
+
* tree. `strike-` MUST be included (PAN-1682): strike sessions are named
|
|
280
|
+
* `strike-<issue>` and a strike issue is typically `todo` (not an active tracker
|
|
281
|
+
* state), so without registering the tmux resource the issue is filtered out of
|
|
282
|
+
* the tree entirely. Keep this list in sync with the agent-session prefixes the
|
|
283
|
+
* dashboard recognizes elsewhere (e.g. routes/agents.ts).
|
|
284
|
+
*/
|
|
285
|
+
const DISCOVERABLE_SESSION_PREFIXES = [
|
|
286
|
+
"agent-",
|
|
287
|
+
"planning-",
|
|
288
|
+
"specialist-",
|
|
289
|
+
"review-",
|
|
290
|
+
"strike-"
|
|
291
|
+
];
|
|
292
|
+
function isDiscoverableAgentSession(sessionName) {
|
|
293
|
+
return DISCOVERABLE_SESSION_PREFIXES.some((prefix) => sessionName.startsWith(prefix));
|
|
294
|
+
}
|
|
295
|
+
async function loadOpenPullRequests(projects) {
|
|
296
|
+
const pullRequests = /* @__PURE__ */ new Map();
|
|
297
|
+
await Promise.all(projects.map(async (project) => {
|
|
298
|
+
if (!project.config.github_repo) return;
|
|
299
|
+
const [owner, repo] = project.config.github_repo.split("/");
|
|
300
|
+
if (!owner || !repo) return;
|
|
301
|
+
try {
|
|
302
|
+
const prs = await listOpenPullRequestsSnapshot(owner, repo);
|
|
303
|
+
for (const row of prs) {
|
|
304
|
+
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;
|
|
305
|
+
const pr = {
|
|
306
|
+
number: row.number,
|
|
307
|
+
title: row.title,
|
|
308
|
+
url: row.url,
|
|
309
|
+
state: row.state,
|
|
310
|
+
isDraft: row.isDraft,
|
|
311
|
+
headRefName: row.headRefName,
|
|
312
|
+
baseRefName: row.baseRefName
|
|
313
|
+
};
|
|
314
|
+
const issueId = parseIssueIdFromTextSync(pr.headRefName);
|
|
315
|
+
if (!issueId) continue;
|
|
316
|
+
const existing = pullRequests.get(issueId) ?? [];
|
|
317
|
+
existing.push(pr);
|
|
318
|
+
pullRequests.set(issueId, existing);
|
|
319
|
+
}
|
|
320
|
+
} catch {}
|
|
321
|
+
}));
|
|
322
|
+
for (const [issueId, prs] of pullRequests) pullRequests.set(issueId, sortPullRequests(prs));
|
|
323
|
+
return pullRequests;
|
|
324
|
+
}
|
|
325
|
+
const PROJECT_BRANCH_PATTERNS = [
|
|
326
|
+
"refs/heads/feature/*",
|
|
327
|
+
"refs/remotes/origin/feature/*",
|
|
328
|
+
"refs/heads/bypass/*",
|
|
329
|
+
"refs/remotes/origin/bypass/*"
|
|
330
|
+
];
|
|
331
|
+
async function loadProjectBranchSnapshot(projectPath) {
|
|
332
|
+
const run = (extraArgs = []) => execFileAsync("git", [
|
|
333
|
+
"for-each-ref",
|
|
334
|
+
"--format=%(refname:short)",
|
|
335
|
+
...extraArgs,
|
|
336
|
+
...PROJECT_BRANCH_PATTERNS
|
|
337
|
+
], {
|
|
338
|
+
cwd: projectPath,
|
|
339
|
+
encoding: "utf-8",
|
|
340
|
+
timeout: 1e4
|
|
341
|
+
}).catch(() => ({ stdout: "" }));
|
|
342
|
+
const [allRefs, unmergedRefs] = await Promise.all([run(), run(["--no-merged=main"])]);
|
|
343
|
+
const branches = allRefs.stdout.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
344
|
+
const ahead = new Set(unmergedRefs.stdout.split("\n").map((line) => line.trim()).filter(Boolean));
|
|
345
|
+
return {
|
|
346
|
+
local: branches.filter((branch) => !branch.startsWith("origin/")),
|
|
347
|
+
remote: branches.filter((branch) => branch.startsWith("origin/")),
|
|
348
|
+
ahead
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
async function scanWorkspace(workspacesDir, workspaceName) {
|
|
352
|
+
const workspacePath = join(workspacesDir, workspaceName);
|
|
353
|
+
const projectRoot = join(workspacesDir, "..");
|
|
354
|
+
const workspaceEntries = new Set(await readdir(workspacePath).catch(() => []));
|
|
355
|
+
const panEntries = workspaceEntries.has(".pan") ? new Set(await readdir(join(workspacePath, PAN_DIRNAME)).catch(() => [])) : /* @__PURE__ */ new Set();
|
|
356
|
+
const issueMatch = workspaceName.match(/^feature-([a-z]+-\d+)$/i);
|
|
357
|
+
const issueId = issueMatch ? issueMatch[1].toUpperCase() : null;
|
|
358
|
+
const specEntry = issueId ? await Effect.runPromise(findSpecByIssue(projectRoot, issueId)).catch(() => null) : null;
|
|
359
|
+
const xbriefPath = specEntry ? specEntry.path : null;
|
|
360
|
+
let xbriefMtime = null;
|
|
361
|
+
if (xbriefPath) try {
|
|
362
|
+
xbriefMtime = (await stat(xbriefPath)).mtimeMs;
|
|
363
|
+
} catch {
|
|
364
|
+
xbriefMtime = null;
|
|
365
|
+
}
|
|
366
|
+
return {
|
|
367
|
+
workspacePath,
|
|
368
|
+
hasPlanning: workspaceEntries.has(PAN_DIRNAME),
|
|
369
|
+
hasPrd: panEntries.has("prd.md"),
|
|
370
|
+
hasState: panEntries.has(PAN_CONTINUE_FILENAME),
|
|
371
|
+
hasXbrief: xbriefPath !== null,
|
|
372
|
+
xbriefPath,
|
|
373
|
+
xbriefMtime,
|
|
374
|
+
hasTasks: xbriefPath !== null
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
async function computeResourceAllocatedIssues(projectConfigs, sharedSignals) {
|
|
378
|
+
const registeredProjects = listProjectsSync();
|
|
379
|
+
const projects = projectConfigs.map((config) => registeredProjects.find((entry) => entry.config.path === config.path) ?? {
|
|
380
|
+
key: config.name ?? config.path,
|
|
381
|
+
config
|
|
382
|
+
});
|
|
383
|
+
const { trackerIssues, tmuxSessions, dockerContainers, conversations, remoteAgentStates } = sharedSignals ?? await captureSharedResourceSignals();
|
|
384
|
+
const pullRequests = await loadOpenPullRequests(projects);
|
|
385
|
+
const issueMap = /* @__PURE__ */ new Map();
|
|
386
|
+
const projectByPrefix = /* @__PURE__ */ new Map();
|
|
387
|
+
for (const project of projects) for (const prefix of projectPrefixes(project)) projectByPrefix.set(prefix, project);
|
|
388
|
+
const projectRefFromResolved = (resolvedProject) => projects.find((project) => project.key === resolvedProject.projectKey || project.config.path === resolvedProject.projectPath) ?? null;
|
|
389
|
+
const resolveProjectRef = (issueId, preferredProject) => {
|
|
390
|
+
if (preferredProject) return preferredProject;
|
|
391
|
+
const resolvedProject = resolveProjectFromIssueSync(issueId);
|
|
392
|
+
if (resolvedProject) {
|
|
393
|
+
const project = projectRefFromResolved(resolvedProject);
|
|
394
|
+
if (project) return project;
|
|
395
|
+
}
|
|
396
|
+
const prefix = issueId.toUpperCase().match(/^([A-Z]+)-\d+$/)?.[1] ?? "";
|
|
397
|
+
return projectByPrefix.get(prefix) ?? null;
|
|
398
|
+
};
|
|
399
|
+
const ensureIssue = (issueId, preferredProject) => {
|
|
400
|
+
const upper = issueId.toUpperCase();
|
|
401
|
+
const existing = issueMap.get(upper);
|
|
402
|
+
if (existing) return existing;
|
|
403
|
+
const resolved = resolveProjectRef(upper, preferredProject);
|
|
404
|
+
if (!resolved) return null;
|
|
405
|
+
const tracker = trackerIssues.get(upper);
|
|
406
|
+
const created = {
|
|
407
|
+
issueId: upper,
|
|
408
|
+
title: tracker?.title?.trim() || upper,
|
|
409
|
+
projectName: resolved.config.name ?? resolved.key,
|
|
410
|
+
branch: `feature/${upper.toLowerCase()}`,
|
|
411
|
+
trackerState: typeof tracker?.state === "string" ? tracker.state : null,
|
|
412
|
+
rawTrackerState: tracker?.rawTrackerState,
|
|
413
|
+
isRally: tracker?.source === "rally",
|
|
414
|
+
hasPlanning: false,
|
|
415
|
+
hasPrd: false,
|
|
416
|
+
hasState: false,
|
|
417
|
+
isShadow: false,
|
|
418
|
+
agentStatus: null,
|
|
419
|
+
readyForMerge: false,
|
|
420
|
+
lastActivity: null,
|
|
421
|
+
resourceSources: /* @__PURE__ */ new Set(),
|
|
422
|
+
resourceDetails: {
|
|
423
|
+
tmuxSessions: [],
|
|
424
|
+
workspacePath: null,
|
|
425
|
+
localBranches: [],
|
|
426
|
+
remoteBranches: [],
|
|
427
|
+
prs: [],
|
|
428
|
+
xbriefPath: null,
|
|
429
|
+
xbriefMtime: null,
|
|
430
|
+
tasksPath: null,
|
|
431
|
+
prdPath: null,
|
|
432
|
+
dockerContainers: [],
|
|
433
|
+
actualBranch: null,
|
|
434
|
+
branchDrifted: false,
|
|
435
|
+
branchAheadOfMain: false,
|
|
436
|
+
workspaceMissing: false,
|
|
437
|
+
remoteAgent: null,
|
|
438
|
+
conversations: []
|
|
439
|
+
},
|
|
440
|
+
taskTotals: null
|
|
441
|
+
};
|
|
442
|
+
issueMap.set(upper, created);
|
|
443
|
+
return created;
|
|
444
|
+
};
|
|
445
|
+
for (const [issueId, tracker] of trackerIssues) {
|
|
446
|
+
const issue = ensureIssue(issueId);
|
|
447
|
+
if (!issue) continue;
|
|
448
|
+
issue.title = tracker.title?.trim() || issue.title;
|
|
449
|
+
issue.trackerState = typeof tracker.state === "string" ? tracker.state : issue.trackerState;
|
|
450
|
+
issue.rawTrackerState = tracker.rawTrackerState ?? issue.rawTrackerState;
|
|
451
|
+
issue.isRally = tracker.source === "rally";
|
|
452
|
+
issue.resourceSources.add("tracker");
|
|
453
|
+
}
|
|
454
|
+
for (const sessionName of tmuxSessions) {
|
|
455
|
+
if (!isDiscoverableAgentSession(sessionName)) continue;
|
|
456
|
+
const issueId = parseIssueIdFromTextSync(sessionName);
|
|
457
|
+
if (!issueId) continue;
|
|
458
|
+
const issue = ensureIssue(issueId);
|
|
459
|
+
if (!issue) continue;
|
|
460
|
+
issue.resourceSources.add("tmux");
|
|
461
|
+
if (!issue.resourceDetails.tmuxSessions.includes(sessionName)) issue.resourceDetails.tmuxSessions.push(sessionName);
|
|
462
|
+
}
|
|
463
|
+
for (const conv of conversations) {
|
|
464
|
+
if (!conv.issueId || conv.archivedAt) continue;
|
|
465
|
+
const issue = ensureIssue(conv.issueId);
|
|
466
|
+
if (!issue) continue;
|
|
467
|
+
issue.resourceSources.add("conversation");
|
|
468
|
+
issue.resourceDetails.conversations.push({
|
|
469
|
+
id: conv.id,
|
|
470
|
+
name: conv.name,
|
|
471
|
+
title: conv.title,
|
|
472
|
+
status: conv.status,
|
|
473
|
+
tmuxSession: conv.tmuxSession
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
for (const remoteState of remoteAgentStates) {
|
|
477
|
+
const issue = ensureIssue(remoteState.issueId);
|
|
478
|
+
if (!issue) continue;
|
|
479
|
+
issue.resourceSources.add("remote-agent");
|
|
480
|
+
issue.resourceDetails.remoteAgent = {
|
|
481
|
+
vmName: remoteState.vmName,
|
|
482
|
+
status: remoteState.status,
|
|
483
|
+
model: remoteState.model,
|
|
484
|
+
startedAt: remoteState.startedAt
|
|
485
|
+
};
|
|
486
|
+
if (!issue.agentStatus) issue.agentStatus = "active";
|
|
487
|
+
}
|
|
488
|
+
for (const containerName of dockerContainers) {
|
|
489
|
+
const issueId = parseIssueIdFromTextSync(containerName.replace(/feature\//g, "feature-"));
|
|
490
|
+
if (!issueId) continue;
|
|
491
|
+
const issue = ensureIssue(issueId);
|
|
492
|
+
if (!issue) continue;
|
|
493
|
+
issue.resourceSources.add("docker");
|
|
494
|
+
issue.resourceDetails.dockerContainers.push(containerName);
|
|
495
|
+
}
|
|
496
|
+
await Promise.all(projects.map(async (project) => {
|
|
497
|
+
const projectPath = project.config.path;
|
|
498
|
+
const workspacesDir = join(projectPath, "workspaces");
|
|
499
|
+
const resolverRows = listWorkspaces({
|
|
500
|
+
projectId: project.key,
|
|
501
|
+
kind: "issue"
|
|
502
|
+
});
|
|
503
|
+
const [workspaceCandidates, branches] = await Promise.all([resolverRows.length > 0 ? Promise.resolve(resolverRows.map((row) => ({
|
|
504
|
+
name: basename(row.path),
|
|
505
|
+
issueId: (row.issueId ?? basename(row.path).replace(/^feature-/, "")).toUpperCase()
|
|
506
|
+
}))) : readdir(workspacesDir, { withFileTypes: true }).then((entries) => entries.filter((entry) => entry.isDirectory() && entry.name.startsWith("feature-")).map((entry) => ({
|
|
507
|
+
name: entry.name,
|
|
508
|
+
issueId: entry.name.replace(/^feature-/, "").toUpperCase()
|
|
509
|
+
}))).catch(() => []), loadProjectBranchSnapshot(projectPath)]);
|
|
510
|
+
await Promise.all(workspaceCandidates.map(async ({ name, issueId }) => {
|
|
511
|
+
const issue = ensureIssue(issueId, project);
|
|
512
|
+
if (!issue) return;
|
|
513
|
+
const workspace = await scanWorkspace(workspacesDir, name);
|
|
514
|
+
issue.resourceSources.add("workspace");
|
|
515
|
+
issue.resourceDetails.workspacePath = workspace.workspacePath;
|
|
516
|
+
issue.hasPlanning = workspace.hasPlanning;
|
|
517
|
+
issue.hasPrd = workspace.hasPrd;
|
|
518
|
+
issue.hasState = workspace.hasState;
|
|
519
|
+
if (workspace.xbriefPath) {
|
|
520
|
+
issue.resourceSources.add("vbrief");
|
|
521
|
+
issue.resourceDetails.xbriefPath = workspace.xbriefPath;
|
|
522
|
+
issue.resourceDetails.xbriefMtime = workspace.xbriefMtime;
|
|
523
|
+
}
|
|
524
|
+
if (workspace.hasTasks) {
|
|
525
|
+
issue.resourceSources.add("tasks");
|
|
526
|
+
issue.resourceDetails.tasksPath = join(workspace.workspacePath, ".tasks");
|
|
527
|
+
}
|
|
528
|
+
const gitInfo = await resolveAgentGitInfo(workspace.workspacePath, issue.branch);
|
|
529
|
+
issue.resourceDetails.actualBranch = gitInfo.actualBranch;
|
|
530
|
+
issue.resourceDetails.branchDrifted = gitInfo.branchDrifted;
|
|
531
|
+
issue.resourceDetails.workspaceMissing = gitInfo.workspaceMissing;
|
|
532
|
+
}));
|
|
533
|
+
for (const [branch, key] of [...branches.local.map((b) => [b, "localBranches"]), ...branches.remote.map((b) => [b, "remoteBranches"])]) {
|
|
534
|
+
const issueId = parseIssueIdFromTextSync(branch);
|
|
535
|
+
if (!issueId) continue;
|
|
536
|
+
const issue = ensureIssue(issueId, project);
|
|
537
|
+
if (!issue) continue;
|
|
538
|
+
issue.resourceSources.add("branch");
|
|
539
|
+
if (!issue.resourceDetails[key].includes(branch)) issue.resourceDetails[key].push(branch);
|
|
540
|
+
if (branches.ahead.has(branch)) issue.resourceDetails.branchAheadOfMain = true;
|
|
541
|
+
}
|
|
542
|
+
}));
|
|
543
|
+
for (const [issueId, prs] of pullRequests) {
|
|
544
|
+
const issue = ensureIssue(issueId);
|
|
545
|
+
if (!issue) continue;
|
|
546
|
+
issue.resourceSources.add("pr");
|
|
547
|
+
issue.resourceDetails.prs = prs;
|
|
548
|
+
const bestTitle = prs.find((pr) => !pr.isDraft)?.title ?? prs[0]?.title;
|
|
549
|
+
issue.title = issue.title === issue.issueId && bestTitle ? bestTitle : issue.title;
|
|
550
|
+
}
|
|
551
|
+
await Promise.all([...issueMap.values()].map(async (issue) => {
|
|
552
|
+
if (issue.resourceDetails.tmuxSessions.length === 0) return;
|
|
553
|
+
const states = (await Promise.all(issue.resourceDetails.tmuxSessions.map((sessionName) => Effect.runPromise(getAgentRuntimeState(sessionName)).catch(() => null)))).filter((state) => state !== null);
|
|
554
|
+
if (states.length === 0) return;
|
|
555
|
+
issue.agentStatus = (states.find((state) => state.state === "active") ?? states.reduce((a, b) => Date.parse(a.lastActivity) >= Date.parse(b.lastActivity) ? a : b)).state;
|
|
556
|
+
const lastActivity = Math.max(...states.map((state) => Date.parse(state.lastActivity)).filter(Number.isFinite));
|
|
557
|
+
issue.lastActivity = Number.isFinite(lastActivity) ? lastActivity : null;
|
|
558
|
+
}));
|
|
559
|
+
const reviewStatusIssueIds = [...issueMap.values()].filter(shouldLoadReviewStatus).map((issue) => issue.issueId);
|
|
560
|
+
if (reviewStatusIssueIds.length > 0) {
|
|
561
|
+
const readyForMergeFlags = loadReadyForMergeFlags(reviewStatusIssueIds);
|
|
562
|
+
for (const issue of issueMap.values()) issue.readyForMerge = readyForMergeFlags.get(issue.issueId) ?? false;
|
|
563
|
+
}
|
|
564
|
+
const memberships = /* @__PURE__ */ new Map();
|
|
565
|
+
const unavailableProjects = /* @__PURE__ */ new Set();
|
|
566
|
+
const projectMemberships = readPipelineMembershipSnapshotsForProjects(projects.map((project) => project.config));
|
|
567
|
+
for (const result of projectMemberships) {
|
|
568
|
+
if (result.error) unavailableProjects.add(result.project.name);
|
|
569
|
+
for (const membership of result.memberships ?? []) {
|
|
570
|
+
ensureIssue(membership.issueId);
|
|
571
|
+
memberships.set(membership.issueId, membership);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
await Promise.all([...issueMap.values()].map(async (issue) => {
|
|
575
|
+
const project = resolveProjectRef(issue.issueId);
|
|
576
|
+
if (!project) return;
|
|
577
|
+
const draft = await Effect.runPromise(findDraftPrd(project.config.path, issue.issueId)).catch(() => null);
|
|
578
|
+
if (!draft) return;
|
|
579
|
+
issue.resourceSources.add("prd");
|
|
580
|
+
issue.resourceDetails.prdPath = draft.path;
|
|
581
|
+
issue.hasPrd = true;
|
|
582
|
+
}));
|
|
583
|
+
const untitledIssueIds = [...issueMap.values()].filter((issue) => issue.resourceSources.size > 0 && issue.title === issue.issueId).map((issue) => issue.issueId);
|
|
584
|
+
if (untitledIssueIds.length > 0) {
|
|
585
|
+
const fallbackTitles = await resolveMissingIssueTitles(untitledIssueIds).catch(() => /* @__PURE__ */ new Map());
|
|
586
|
+
for (const issue of issueMap.values()) {
|
|
587
|
+
const title = fallbackTitles.get(issue.issueId);
|
|
588
|
+
if (title && issue.title === issue.issueId) issue.title = title;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
return [...issueMap.values()].filter((issue) => issue.resourceSources.size > 0).filter((issue) => {
|
|
592
|
+
const membership = memberships.get(issue.issueId);
|
|
593
|
+
return membership?.inPipeline === true || membership?.bucket === "clean_terminal" && isLiveResource(issue) || !membership && unavailableProjects.has(issue.projectName) && isLiveResource(issue);
|
|
594
|
+
}).map((issue) => {
|
|
595
|
+
const membership = memberships.get(issue.issueId);
|
|
596
|
+
const hasTmux = issue.resourceDetails.tmuxSessions.length > 0;
|
|
597
|
+
const hasRecentHeartbeat = hasRecentActivity(issue.lastActivity);
|
|
598
|
+
const stateLabel = deriveStateLabel(issue, hasTmux, hasRecentHeartbeat, membership);
|
|
599
|
+
const isRemoteRunning = issue.resourceDetails.remoteAgent?.status === "running" || issue.resourceDetails.remoteAgent?.status === "starting";
|
|
600
|
+
const status = hasTmux && (issue.agentStatus === "active" || hasRecentHeartbeat) || isRemoteRunning ? "running" : issue.hasState ? "has_state" : "idle";
|
|
601
|
+
return {
|
|
602
|
+
issueId: issue.issueId,
|
|
603
|
+
title: issue.title,
|
|
604
|
+
projectName: issue.projectName,
|
|
605
|
+
branch: issue.branch,
|
|
606
|
+
status,
|
|
607
|
+
stateLabel,
|
|
608
|
+
agentStatus: issue.agentStatus,
|
|
609
|
+
hasPlanning: issue.hasPlanning,
|
|
610
|
+
hasPrd: issue.hasPrd,
|
|
611
|
+
hasState: issue.hasState,
|
|
612
|
+
isShadow: issue.isShadow,
|
|
613
|
+
isRally: issue.isRally,
|
|
614
|
+
childCount: trackerIssues.get(issue.issueId)?.totalChildCount,
|
|
615
|
+
completedCount: trackerIssues.get(issue.issueId)?.completedChildCount,
|
|
616
|
+
inProgressCount: trackerIssues.get(issue.issueId)?.inProgressChildCount,
|
|
617
|
+
readyForMerge: issue.readyForMerge,
|
|
618
|
+
rawTrackerState: issue.rawTrackerState,
|
|
619
|
+
resourceSources: new Set([...issue.resourceSources].sort()),
|
|
620
|
+
resourceDetails: issue.resourceDetails,
|
|
621
|
+
taskTotals: issue.taskTotals,
|
|
622
|
+
pipelineBucket: membership?.bucket,
|
|
623
|
+
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,
|
|
624
|
+
resourceDrift: membership ? !membership.inPipeline : void 0
|
|
625
|
+
};
|
|
626
|
+
}).sort((a, b) => compareIssueIds(a.issueId, b.issueId));
|
|
627
|
+
}
|
|
628
|
+
function toPublicResourceIssue(issue) {
|
|
629
|
+
return {
|
|
630
|
+
...issue,
|
|
631
|
+
resourceSources: [...issue.resourceSources],
|
|
632
|
+
resourceDetails: summarizeResourceDetails(issue.resourceDetails)
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
function rebuildCombinedResourceSnapshot() {
|
|
636
|
+
const detailed = [...projectResourceSnapshots.values()].flatMap((snapshot) => snapshot.detailed).sort((a, b) => compareIssueIds(a.issueId, b.issueId));
|
|
637
|
+
const publicIssues = detailed.map(toPublicResourceIssue);
|
|
638
|
+
cachedDetailedResourceIssues = detailed;
|
|
639
|
+
cachedResourceIssues = {
|
|
640
|
+
value: publicIssues,
|
|
641
|
+
computedAt: Math.max(0, ...[...projectResourceSnapshots.values()].map((snapshot) => snapshot.computedAt))
|
|
642
|
+
};
|
|
643
|
+
return publicIssues;
|
|
644
|
+
}
|
|
645
|
+
function publishProjectResourceSnapshot(project, issues) {
|
|
646
|
+
projectResourceSnapshots.set(project.path, {
|
|
647
|
+
detailed: issues,
|
|
648
|
+
public: issues.map(toPublicResourceIssue),
|
|
649
|
+
computedAt: Date.now()
|
|
650
|
+
});
|
|
651
|
+
rebuildCombinedResourceSnapshot();
|
|
652
|
+
}
|
|
653
|
+
/** Refresh only the requested projects, capturing fleet-wide signals once for the batch. */
|
|
654
|
+
async function refreshResourceAllocatedProjects(projects, options = {}) {
|
|
655
|
+
if (projects.length === 0) return cachedResourceIssues?.value ?? [];
|
|
656
|
+
const sharedSignals = await captureSharedResourceSignals();
|
|
657
|
+
const failures = [];
|
|
658
|
+
for (const project of projects) try {
|
|
659
|
+
if (options.refreshMembership !== false) await refreshMembershipSnapshotsForProjects([project]);
|
|
660
|
+
publishProjectResourceSnapshot(project, await computeResourceAllocatedIssues([project], sharedSignals));
|
|
661
|
+
} catch (error) {
|
|
662
|
+
const failure = error instanceof Error ? error : new Error(String(error));
|
|
663
|
+
failures.push(failure);
|
|
664
|
+
console.warn(`[resource-discovery] refresh failed for ${project.name ?? project.path}; keeping last-good snapshot:`, failure.message);
|
|
665
|
+
}
|
|
666
|
+
if (failures.length > 0) throw new AggregateError(failures, `${failures.length} project resource refresh(es) failed`);
|
|
667
|
+
return cachedResourceIssues?.value ?? [];
|
|
668
|
+
}
|
|
669
|
+
async function getCachedResourceAllocatedIssues() {
|
|
670
|
+
return cachedResourceIssues?.value ?? [];
|
|
671
|
+
}
|
|
672
|
+
function sanitizeResourceAllocatedIssues(issues) {
|
|
673
|
+
return issues.map((issue) => ({
|
|
674
|
+
...issue,
|
|
675
|
+
resourceDetails: {
|
|
676
|
+
hasWorkspace: issue.resourceDetails.hasWorkspace,
|
|
677
|
+
localBranchCount: issue.resourceDetails.localBranchCount,
|
|
678
|
+
remoteBranchCount: issue.resourceDetails.remoteBranchCount,
|
|
679
|
+
tmuxSessionCount: issue.resourceDetails.tmuxSessionCount,
|
|
680
|
+
prs: issue.resourceDetails.prs.map((pr) => ({
|
|
681
|
+
number: pr.number,
|
|
682
|
+
title: pr.title,
|
|
683
|
+
state: pr.state,
|
|
684
|
+
isDraft: pr.isDraft
|
|
685
|
+
})),
|
|
686
|
+
hasXbrief: issue.resourceDetails.hasXbrief,
|
|
687
|
+
hasTasks: issue.resourceDetails.hasTasks,
|
|
688
|
+
hasPrd: issue.resourceDetails.hasPrd,
|
|
689
|
+
dockerContainerCount: issue.resourceDetails.dockerContainerCount,
|
|
690
|
+
actualBranch: issue.resourceDetails.actualBranch,
|
|
691
|
+
branchDrifted: issue.resourceDetails.branchDrifted,
|
|
692
|
+
branchAheadOfMain: issue.resourceDetails.branchAheadOfMain,
|
|
693
|
+
workspaceMissing: issue.resourceDetails.workspaceMissing,
|
|
694
|
+
remoteAgent: issue.resourceDetails.remoteAgent ?? null,
|
|
695
|
+
conversations: issue.resourceDetails.conversations.map((conv) => ({
|
|
696
|
+
id: conv.id,
|
|
697
|
+
name: conv.name,
|
|
698
|
+
title: conv.title,
|
|
699
|
+
status: conv.status
|
|
700
|
+
}))
|
|
701
|
+
}
|
|
702
|
+
}));
|
|
703
|
+
}
|
|
704
|
+
function toPublicResourceDetailIdentifiers(details) {
|
|
705
|
+
return summarizeResourceDetailIdentifiers(details);
|
|
706
|
+
}
|
|
707
|
+
async function getResourceDetailIdentifiers(issueId) {
|
|
708
|
+
const normalizedIssueId = issueId.toUpperCase();
|
|
709
|
+
const cachedMatch = cachedDetailedResourceIssues?.find((entry) => entry.issueId === normalizedIssueId);
|
|
710
|
+
return cachedMatch ? toPublicResourceDetailIdentifiers(cachedMatch.resourceDetails) : null;
|
|
711
|
+
}
|
|
712
|
+
function groupResourceAllocatedIssuesByProject(issues) {
|
|
713
|
+
const projectTree = /* @__PURE__ */ new Map();
|
|
714
|
+
for (const issue of issues) {
|
|
715
|
+
const existing = projectTree.get(issue.projectName);
|
|
716
|
+
if (existing) {
|
|
717
|
+
existing.features.push(issue);
|
|
718
|
+
continue;
|
|
719
|
+
}
|
|
720
|
+
projectTree.set(issue.projectName, {
|
|
721
|
+
name: issue.projectName,
|
|
722
|
+
path: issue.projectName,
|
|
723
|
+
features: [issue]
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
return [...projectTree.values()].map((project) => ({
|
|
727
|
+
...project,
|
|
728
|
+
features: project.features.sort((a, b) => compareIssueIds(a.issueId, b.issueId))
|
|
729
|
+
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
730
|
+
}
|
|
731
|
+
//#endregion
|
|
732
|
+
//#region services/project-resource-refresh-queue.ts
|
|
733
|
+
init_projects();
|
|
734
|
+
const PROJECT_RESOURCE_REFRESH_DEBOUNCE_MS = 1e3;
|
|
735
|
+
const PROJECT_RESOURCE_CONVERGENCE_INTERVAL_MS = 5 * 6e4;
|
|
736
|
+
function createProjectResourceRefreshQueue(deps) {
|
|
737
|
+
const debounceMs = deps.debounceMs ?? 1e3;
|
|
738
|
+
const now = deps.now ?? Date.now;
|
|
739
|
+
const pending = /* @__PURE__ */ new Map();
|
|
740
|
+
const reasons = /* @__PURE__ */ new Map();
|
|
741
|
+
const idleWaiters = /* @__PURE__ */ new Set();
|
|
742
|
+
let activeProjectPaths = [];
|
|
743
|
+
let timer = null;
|
|
744
|
+
let running = false;
|
|
745
|
+
let stopped = false;
|
|
746
|
+
let lastStartedAt = null;
|
|
747
|
+
let lastCompletedAt = null;
|
|
748
|
+
let lastError = null;
|
|
749
|
+
const isIdle = () => !running && timer === null && pending.size === 0;
|
|
750
|
+
const resolveIdleWaiters = () => {
|
|
751
|
+
if (!isIdle()) return;
|
|
752
|
+
for (const resolve of idleWaiters) resolve();
|
|
753
|
+
idleWaiters.clear();
|
|
754
|
+
};
|
|
755
|
+
const drain = async () => {
|
|
756
|
+
timer = null;
|
|
757
|
+
if (running || stopped) return;
|
|
758
|
+
running = true;
|
|
759
|
+
try {
|
|
760
|
+
while (!stopped && pending.size > 0) {
|
|
761
|
+
const projects = [...pending.values()];
|
|
762
|
+
const reasonsByProjectPath = /* @__PURE__ */ new Map();
|
|
763
|
+
for (const project of projects) {
|
|
764
|
+
reasonsByProjectPath.set(project.path, new Set(reasons.get(project.path) ?? []));
|
|
765
|
+
reasons.delete(project.path);
|
|
766
|
+
}
|
|
767
|
+
pending.clear();
|
|
768
|
+
activeProjectPaths = projects.map((project) => project.path);
|
|
769
|
+
lastStartedAt = now();
|
|
770
|
+
try {
|
|
771
|
+
await deps.refreshProjects(projects, { reasonsByProjectPath });
|
|
772
|
+
lastError = null;
|
|
773
|
+
} catch (error) {
|
|
774
|
+
lastError = error instanceof Error ? error.message : String(error);
|
|
775
|
+
console.warn("[project-resource-refresh] batch failed:", lastError);
|
|
776
|
+
} finally {
|
|
777
|
+
activeProjectPaths = [];
|
|
778
|
+
lastCompletedAt = now();
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
} finally {
|
|
782
|
+
running = false;
|
|
783
|
+
resolveIdleWaiters();
|
|
784
|
+
}
|
|
785
|
+
};
|
|
786
|
+
const schedule = () => {
|
|
787
|
+
if (stopped || running || timer) return;
|
|
788
|
+
timer = setTimeout(() => void drain(), debounceMs);
|
|
789
|
+
timer.unref?.();
|
|
790
|
+
};
|
|
791
|
+
const enqueueProject = (project, reason) => {
|
|
792
|
+
if (stopped) return;
|
|
793
|
+
pending.set(project.path, project);
|
|
794
|
+
const projectReasons = reasons.get(project.path) ?? /* @__PURE__ */ new Set();
|
|
795
|
+
projectReasons.add(reason);
|
|
796
|
+
reasons.set(project.path, projectReasons);
|
|
797
|
+
schedule();
|
|
798
|
+
};
|
|
799
|
+
return {
|
|
800
|
+
enqueueProject,
|
|
801
|
+
enqueueProjects(projects, reason) {
|
|
802
|
+
for (const project of projects) enqueueProject(project, reason);
|
|
803
|
+
},
|
|
804
|
+
whenIdle() {
|
|
805
|
+
if (isIdle()) return Promise.resolve();
|
|
806
|
+
return new Promise((resolve) => idleWaiters.add(resolve));
|
|
807
|
+
},
|
|
808
|
+
getState() {
|
|
809
|
+
return {
|
|
810
|
+
running,
|
|
811
|
+
activeProjectPaths: [...activeProjectPaths],
|
|
812
|
+
pendingProjectPaths: [...pending.keys()],
|
|
813
|
+
lastStartedAt,
|
|
814
|
+
lastCompletedAt,
|
|
815
|
+
lastError
|
|
816
|
+
};
|
|
817
|
+
},
|
|
818
|
+
stop() {
|
|
819
|
+
stopped = true;
|
|
820
|
+
if (timer) clearTimeout(timer);
|
|
821
|
+
timer = null;
|
|
822
|
+
pending.clear();
|
|
823
|
+
reasons.clear();
|
|
824
|
+
resolveIdleWaiters();
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
}
|
|
828
|
+
const MEMBERSHIP_REFRESH_REASONS = new Set([
|
|
829
|
+
"boot-warm",
|
|
830
|
+
"periodic-convergence",
|
|
831
|
+
"issue.statusChanged:closed-out",
|
|
832
|
+
"pull_request:opened",
|
|
833
|
+
"pull_request:closed",
|
|
834
|
+
"pull_request:reopened"
|
|
835
|
+
]);
|
|
836
|
+
function shouldRefreshMembershipForResourceRefresh(context) {
|
|
837
|
+
return [...context.reasonsByProjectPath.values()].some((projectReasons) => [...projectReasons].some((reason) => MEMBERSHIP_REFRESH_REASONS.has(reason)));
|
|
838
|
+
}
|
|
839
|
+
const projectResourceRefreshQueue = createProjectResourceRefreshQueue({ refreshProjects: (projects, context) => refreshResourceAllocatedProjects(projects, { refreshMembership: shouldRefreshMembershipForResourceRefresh(context) }) });
|
|
840
|
+
function enqueueProjectResourceRefresh(project, reason) {
|
|
841
|
+
projectResourceRefreshQueue.enqueueProject(project, reason);
|
|
842
|
+
}
|
|
843
|
+
function enqueueProjectsResourceRefresh(projects, reason) {
|
|
844
|
+
projectResourceRefreshQueue.enqueueProjects(projects, reason);
|
|
845
|
+
}
|
|
846
|
+
function whenProjectResourceRefreshIdle() {
|
|
847
|
+
return projectResourceRefreshQueue.whenIdle();
|
|
848
|
+
}
|
|
849
|
+
function getProjectResourceRefreshQueueState() {
|
|
850
|
+
return projectResourceRefreshQueue.getState();
|
|
851
|
+
}
|
|
852
|
+
function stopProjectResourceRefreshQueue() {
|
|
853
|
+
projectResourceRefreshQueue.stop();
|
|
854
|
+
}
|
|
855
|
+
function startProjectResourceConvergence() {
|
|
856
|
+
const timer = setInterval(() => {
|
|
857
|
+
enqueueProjectsResourceRefresh(listProjectsSync().map((entry) => entry.config), "periodic-convergence");
|
|
858
|
+
}, PROJECT_RESOURCE_CONVERGENCE_INTERVAL_MS);
|
|
859
|
+
timer.unref?.();
|
|
860
|
+
return () => clearInterval(timer);
|
|
861
|
+
}
|
|
862
|
+
//#endregion
|
|
863
|
+
export { refreshMembershipSnapshotsForProjects as _, enqueueProjectsResourceRefresh as a, startProjectResourceConvergence as c, getCachedResourceAllocatedIssues as d, getResourceDetailIdentifiers as f, readPipelineMembershipSnapshotsForProjects as g, sanitizeResourceAllocatedIssues as h, enqueueProjectResourceRefresh as i, stopProjectResourceRefreshQueue as l, isDiscoverableAgentSession as m, PROJECT_RESOURCE_REFRESH_DEBOUNCE_MS as n, getProjectResourceRefreshQueueState as o, groupResourceAllocatedIssuesByProject as p, createProjectResourceRefreshQueue as r, shouldRefreshMembershipForResourceRefresh as s, PROJECT_RESOURCE_CONVERGENCE_INTERVAL_MS as t, whenProjectResourceRefreshIdle as u, summarizePipelineMembership as v, unavailablePipelineMembership as y };
|
|
864
|
+
|
|
865
|
+
//# sourceMappingURL=project-resource-refresh-queue-x-K9mvpP.js.map
|