@overdeck/desktop 0.45.24 → 0.47.0
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/drizzle/overdeck/0000_overdeck_init.sql +36 -1
- package/package.json +1 -1
- package/server/{acceptance-criteria-DDCnXF58.js → acceptance-criteria-10Ur5Dne.js} +2 -2
- package/server/activity-logger-CMthG6Vd.js +3 -0
- package/server/{activity-logger-DDlOIAML.js → activity-logger-CyteR4JO.js} +24 -13
- package/server/{advancing-selfheal-BVwW4qRn.js → advancing-selfheal-BNwqxseD.js} +6 -6
- package/server/{agent-gc-CHcnvonI.js → agent-gc-C3h9Or3a.js} +5 -5
- package/server/agent-state-CYXJVG72.js +3 -0
- package/server/agent-state-service-C63p_ftq.js +2 -0
- package/server/{agent-state-service-BsgWxZuB.js → agent-state-service-Ds6OeFvo.js} +15 -9
- package/server/{agents-EbI0zCJl.js → agents-J5mEnekq.js} +23 -16
- package/server/agents-ePFVoZbu.js +3 -0
- package/server/archive-planning-B2XplFzT.js +2 -0
- package/server/{archive-planning-Du25Jtst.js → archive-planning-BwhxeP7C.js} +22 -26
- package/server/{artifact-index-jobs-CbEDfCDu.js → artifact-index-jobs-D1q_vR3V.js} +2 -2
- package/server/{assemble-J2ZZ2C15.js → assemble-Bgwqv-Ro.js} +2 -2
- package/server/auto-spawn-consent-CQ9Bi9q6.js +1141 -0
- package/server/{backlog-auto-trigger-2R2jog7n.js → backlog-auto-trigger-n1lzPgN4.js} +3 -3
- package/server/{behavior-B3exJ42O.js → behavior-td6-xhQk.js} +2 -2
- package/server/boot-reconciled-stop-events-C7gGe3oB.js +44 -0
- package/server/bridge-pool-patrol-CYH2OLb5.js +136 -0
- package/server/{briefing-freshness-D1wzUIWv.js → briefing-freshness-DRqZ8lAz.js} +2 -2
- package/server/{build-info-Ie_D0_BT.js → build-info-7yiEpl6u.js} +5 -3
- package/server/{build-info-CZk_TITh.js → build-info-CpG__c63.js} +1 -1
- package/server/{checkpoint-manager-DwbQoqrC.js → checkpoint-manager-CkKmB0wZ.js} +1 -1
- package/server/{checkpoint-manager-BI1Wxoku.js → checkpoint-manager-DBcyNR8w.js} +2 -2
- package/server/checkpoint-worker.js +1 -1
- package/server/{checkpoints-CQB1h765.js → checkpoints-D95apurL.js} +2 -2
- package/server/{checkpoints-BJIs5QIA.js → checkpoints-Wm963lm8.js} +1 -1
- package/server/{claude-hooks-provision-8Ngo8TpT.js → claude-hooks-provision-4RPxNkE8.js} +1 -1
- package/server/{claude-hooks-provision-D8GXF3_s.js → claude-hooks-provision-Bjitl9aI.js} +13 -2
- package/server/{claude-permissions-DNWEVV6z.js → claude-permissions-CpbpvUQ2.js} +2 -2
- package/server/{claude-settings-overlay-DWy-Bb4Y.js → claude-settings-overlay-BzkHYDwR.js} +1 -1
- package/server/{claude-settings-overlay-CEdaqpWI.js → claude-settings-overlay-_H9Yrzab.js} +2 -2
- package/server/cli-CjOCSnfj.js +3 -0
- package/server/{cli-RoOx5DUf.js → cli-Cte9ZFGn.js} +9 -9
- package/server/{cliproxy-C8a1vtTU.js → cliproxy-C5fMJ7rY.js} +2 -2
- package/server/{cliproxy-fHfIeiGd.js → cliproxy-DaAbWMjC.js} +1 -1
- package/server/{close-issue-DoOifFIK.js → close-issue-BPh1ARCF.js} +5 -5
- package/server/{closed-issue-reaper-CktPXo8m.js → closed-issue-reaper-DHRfRMrp.js} +1 -1
- package/server/{closed-issue-reaper-Bk3SU4RC.js → closed-issue-reaper-DoOZqGFK.js} +88 -17
- package/server/{codex-BZXGhUVB.js → codex-BzGDW_d3.js} +36 -7
- package/server/{codex-GcHuUF-k.js → codex-o8FJwzmy.js} +1 -1
- package/server/{codex-parser-CFZ1_1Jl.js → codex-parser-Dt-ycU8L.js} +2 -2
- package/server/compaction-continuation-CvXpbZ4w.js +200 -0
- package/server/{config-CKxYiCmX.js → config-Bi3u1VK7.js} +4 -3
- package/server/{config-BZ0sHTju.js → config-BvLe652W.js} +2 -2
- package/server/{config-DzV30TOm.js → config-CL3Gyvja.js} +1 -1
- package/server/{config-yaml-DySPNmKN.js → config-yaml-CxdwhAIA.js} +276 -14
- package/server/conflict-gate-CX80JYYS.js +3 -0
- package/server/{conflict-gate-BaCVrH-N.js → conflict-gate-E4nt7ZeS.js} +60 -14
- package/server/{context-layers-igZ4FI4_.js → context-layers-C_IIysnm.js} +3 -3
- package/server/{context-layers-BrPmE__h.js → context-layers-DAG83UZt.js} +2 -2
- package/server/{control-settings-BQp7_4uD.js → control-settings-CiqGxXnc.js} +56 -19
- package/server/{conversation-compaction-eQB5CkOe.js → conversation-compaction-BE3CNtHF.js} +1 -1
- package/server/{conversation-compaction-CgrR8YYp.js → conversation-compaction-D6-yLtqt.js} +8 -8
- package/server/{conversation-service-DPJ71F33.js → conversation-service-DBxoYMDl.js} +10 -8
- package/server/conversation-service-D_TS2b1r.js +3 -0
- package/server/{conversations-CAsJF9kh.js → conversations-BKDVpB-3.js} +1 -1
- package/server/{conversations-6AfUfbwc.js → conversations-D0UEdLtk.js} +4 -4
- package/server/{cost-R-m6Yi-W.js → cost-DS1s0DbG.js} +3 -3
- package/server/{cost-B2ddP6wq.js → cost-DpgYmYqR.js} +12 -2
- package/server/{cost-sync-BsN6ER0n.js → cost-sync-tOCCGnEt.js} +3 -3
- package/server/{dag-B1ucnjDU.js → dag-BtkgLeqY.js} +2 -2
- package/server/{dangerous-git-ops-BXqeWVSf.js → dangerous-git-ops-CFLykHWt.js} +1 -1
- package/server/dashboard-db-worker.js +7 -7
- package/server/deacon-BIblC-WX.js +4 -0
- package/server/{deacon-nudge-log-6wVqAaqz.js → deacon-nudge-log-B08gF0mh.js} +3 -3
- package/server/{deacon-CU_cAYSR.js → deacon-pLRLbPvR.js} +3308 -2707
- package/server/deacon-pending-lifecycle-B-Io84AP.js +33 -0
- package/server/deacon-swarm-B1XkIvfr.js +2 -0
- package/server/{deacon-swarm-BXZZ1Z2-.js → deacon-swarm-v5PMun-m.js} +15 -14
- package/server/deacon.js +14 -19
- package/server/dead-end-trip-D8A3msX9.js +13 -0
- package/server/delivery-BX9HR4wQ.js +3 -0
- package/server/{deploy-patrol-AiFoP8dw.js → deploy-patrol-sYgOxLeb.js} +69 -18
- package/server/deploy-queue-VfohaPN_.js +169 -0
- package/server/deploy-queue-gHJBycaF.js +3 -0
- package/server/deploy-window-CFRZ0-kt.js +3 -0
- package/server/{deploy-window-C3F-tihF.js → deploy-window-D4DQb8VP.js} +40 -16
- package/server/{dev-supervisor-bcOWqdQE.js → dev-supervisor-DiOBDM1c.js} +2 -2
- package/server/{devcontainer-renderer-_d6XhyND.js → devcontainer-renderer-BUOIlfgD.js} +3 -3
- package/server/dist-B3YPQa5A.js +3 -0
- package/server/{dist-Cb_0uvpS.js → dist-C3A8B8wM.js} +1 -1
- package/server/{dist-src-BSoS7mkd.js → dist-src-C0adpegX.js} +1 -1
- package/server/{docker-DcMTFTUC.js → docker-BJzlkqYB.js} +2 -2
- package/server/docker-Y3PElJb0.js +3 -0
- package/server/dod-DlNtcH6n.js +91 -0
- package/server/durable-review-pipeline-Cibps-Rg.js +20 -0
- package/server/durable-review-pipeline-DP6bIcOY.js +3 -0
- package/server/{ensure-devcontainer-DNi-ono3.js → ensure-devcontainer-BAofzBPv.js} +4 -4
- package/server/{ensure-devcontainer-BZgOhRo7.js → ensure-devcontainer-DMAbWqtQ.js} +1 -1
- package/server/{esm-shims-OSHAYaS1.js → esm-shims-BeObUkaw.js} +1 -1
- package/server/{event-store-EV2cMiXj.js → event-store-5UKzh9Jf.js} +1 -1
- package/server/{event-store-CQL6NeqB.js → event-store-CrHcVC5_.js} +23 -4
- package/server/{events-DTfAe4My.js → events-BNrvchBg.js} +3 -3
- package/server/{events-BTdrdEq8.js → events-CF8QDbuV.js} +1 -1
- package/server/{factory-CFibJuaw.js → factory-Cmm9Hsho.js} +5 -5
- package/server/{feature-registry-population-DKZFMbFt.js → feature-registry-population-B6HpNWRy.js} +4 -4
- package/server/{feature-registry-storage-BdPuLcBX.js → feature-registry-storage-DJEFx1Pf.js} +2 -2
- package/server/{features-ez2271oH.js → features-D5km80UI.js} +2 -2
- package/server/{feedback-target-CoFDHiM8.js → feedback-target-BJ5ZADsu.js} +1 -1
- package/server/{feedback-target-7mqqwrX6.js → feedback-target-DSxEL6lP.js} +8 -8
- package/server/{feedback-writer-CY5L1lB7.js → feedback-writer-C27Hak8a.js} +5 -5
- package/server/{feedback-writer-D3a22RCd.js → feedback-writer-CoB9Z6aU.js} +1 -1
- package/server/{flywheel-DHrgCphM.js → flywheel-BHx8XuMr.js} +47 -20
- package/server/{flywheel-SVF02Jpq.js → flywheel-DZZdtiOL.js} +1 -1
- package/server/{flywheel-DzGtWnJ1.js → flywheel-f662Q-y2.js} +16 -15
- package/server/flywheel-merge-order-D_xLMbJU.js +462 -0
- package/server/flywheel-merge-order-Dil0LmdN.js +2 -0
- package/server/forge-B5o319qI.js +3 -0
- package/server/forge-BaKGCya6.js +383 -0
- package/server/{from-kNxT0bZC.js → from-B3tZbB55.js} +1 -1
- package/server/fs-lock-Bre3sGoz.js +130 -0
- package/server/{fts-db-CE46vDkZ.js → fts-db-IVc4_M3f.js} +2 -2
- package/server/{fts-operations-CqY6zl-i.js → fts-operations-B9jG8wa3.js} +2 -2
- package/server/{git-utils-CRw2zLPC.js → git-utils-CsvYfJU3.js} +30 -5
- package/server/git-utils-Xg4PFN45.js +3 -0
- package/server/{github-app-ClZ2lk8D.js → github-app-Bmg4R9mv.js} +1 -1
- package/server/{github-app-C3QrAUd0.js → github-app-CmNk0zLU.js} +3 -3
- package/server/{github-client-DfQYVUaw.js → github-client-B6KM9_wA.js} +1 -1
- package/server/{github-client-BnIsSrEN.js → github-client-qazkPrg0.js} +3 -3
- package/server/github-pr-lookup-DAcVeRLK.js +58 -0
- package/server/{harness-binary-DPUi-Pv8.js → harness-binary-BSpiXaLw.js} +2 -2
- package/server/{harness-resolve-3lNZkyT4.js → harness-resolve-BAJu5MX8.js} +4 -4
- package/server/{health-events-BDOHby5Q.js → health-events-2Z6Wa9SM.js} +1 -1
- package/server/{health-events-BBcTYQKU.js → health-events-BwX32k8d.js} +2 -2
- package/server/{hooks-DPVX1rwQ.js → hooks-D1g1jKLI.js} +1 -1
- package/server/{hooks-CKZgXlJb.js → hooks-DbtbimEf.js} +2 -2
- package/server/{hume-Cz8igP9E.js → hume-DXNiu6nQ.js} +2 -2
- package/server/hume-VUCNbTgn.js +3 -0
- package/server/{idle-stack-reaper-CuLF0j2H.js → idle-stack-reaper-CRA1e0jr.js} +1 -1
- package/server/{idle-stack-reaper-DDIRwxUY.js → idle-stack-reaper-Cy-dQzW4.js} +99 -6
- package/server/in-flight-guard-D-sSkADM.js +45 -0
- package/server/{infra-BEqFxlJc.js → infra-BDQDRopn.js} +81 -5
- package/server/{injection-C8aiVJrF.js → injection-6AGnXxlj.js} +7 -7
- package/server/{injection-CPUIqNhI.js → injection-Bl8d_jHZ.js} +1 -1
- package/server/inspect-agent-CUwVmr2h.js +2 -0
- package/server/{inspect-agent-BLuJ1AkT.js → inspect-agent-nXdIptyh.js} +26 -25
- package/server/{internal-token-s0-oKybJ.js → internal-token-DzK385vD.js} +2 -2
- package/server/{internal-token-BrcU6qfe.js → internal-token-Ias7N8Kg.js} +1 -1
- package/server/{io-C9kF1wtJ.js → io-B00PBNku.js} +44 -27
- package/server/{issue-closed-CDJk4pIp.js → issue-closed-BehTG1be.js} +8 -8
- package/server/{issue-lifecycle-ojZAzDBP.js → issue-lifecycle-Birk-ifu.js} +42 -30
- package/server/{issue-lifecycle-B8sZHVHh.js → issue-lifecycle-BqSuQvbn.js} +1 -1
- package/server/{issue-service-singleton-BvJ09SaR.js → issue-service-singleton-B2wXiIlw.js} +1 -1
- package/server/{issue-service-singleton-Yx5DdmVJ.js → issue-service-singleton-C6ZduvuY.js} +10 -10
- package/server/{issues-BMmP_77e.js → issues-DQ5-LatB.js} +2 -2
- package/server/{jsonl-parser-BXSlHwEh.js → jsonl-parser-BDpnGFCl.js} +5 -4
- package/server/{label-cleanup-B0UJwnv5.js → label-cleanup-Dwnky8FG.js} +3 -3
- package/server/{lifecycle-xmBfK2GJ.js → lifecycle-B3s4sM1G.js} +6 -7
- package/server/{lifecycle-yPd___5E.js → lifecycle-B4Xdb4cY.js} +2 -2
- package/server/{lifecycle-io-DPo7x11I.js → lifecycle-io-CzTHEooc.js} +1 -1
- package/server/{lifecycle-io-BREGpnLk.js → lifecycle-io-DCo6s6ks.js} +5 -5
- package/server/{linear-client-BsuUvkdA.js → linear-client-9uq7fhiV.js} +3 -3
- package/server/{linear-client-CTskEeT_.js → linear-client-CnbtHiic.js} +1 -1
- package/server/linear-mcp-auth-BxUOzswy.js +280 -0
- package/server/linear-mcp-auth-D46fBCLf.js +2 -0
- package/server/memory-fts-worker.js +1 -1
- package/server/{merge-CefQNAnq.js → merge-DiW9RdSB.js} +13 -11
- package/server/{merge-agent-4WOWlSYA.js → merge-agent-BLUgRsz3.js} +234 -84
- package/server/{merge-agent-CKkgIBPB.js → merge-agent-DQTXZk8z.js} +1 -1
- package/server/{merge-batch-ClFn2T-y.js → merge-batch-Cp_j9BGk.js} +1 -1
- package/server/merge-completeness-B46KqhtY.js +277 -0
- package/server/merge-completeness-BLbB5-6n.js +3 -0
- package/server/merge-ops-1abz6O_P.js +2 -0
- package/server/merge-rebase-CJJVAJuz.js +2 -0
- package/server/{merge-rebase-BfaTyXsw.js → merge-rebase-DIkBjgwq.js} +3 -3
- package/server/{merge-set-DJ8-UErs.js → merge-set-CBgHfwM0.js} +11 -5
- package/server/merge-set-DeUxFsC3.js +3 -0
- package/server/{merge-B1DiziGU.js → merge-sr8Nrnmi.js} +1 -1
- package/server/merge-sync-CpGmk6Ch.js +3 -0
- package/server/{merge-sync-VPV28g0g.js → merge-sync-kr4vqyjM.js} +409 -153
- package/server/{merge-train-CHopycP0.js → merge-train-Dmrcus12.js} +18 -8
- package/server/{merge-train-deps-D1cOZzy2.js → merge-train-deps-D_uGX91G.js} +21 -15
- package/server/merge-verification-NvaAd8CZ.js +220 -0
- package/server/merged-docker-cleanup-worker-DH_hrGPI.js +3 -0
- package/server/merged-docker-cleanup-worker-Y1R06TEl.js +107 -0
- package/server/{multipart-parser-duPAfSBw.js → multipart-parser-R-oC8dQg.js} +2 -2
- package/server/{no-resume-mode-Nw29vaFb.js → no-resume-mode-BgD0JUmM.js} +1 -1
- package/server/node_modules/.package-lock.json +30 -30
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/package.json +3 -3
- package/server/node_modules/@google-cloud/common/package.json +2 -2
- package/server/node_modules/@types/node/README.md +1 -1
- package/server/node_modules/@types/node/crypto.d.ts +1 -1
- package/server/node_modules/@types/node/package.json +2 -2
- 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 +1 -1
- package/server/node_modules/google-auth-library/build/src/auth/googleauth.js +24 -19
- package/server/node_modules/google-auth-library/package.json +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/auth.proto +2 -1
- package/server/node_modules/google-gax/build/protos/google/api/backend.proto +12 -1
- package/server/node_modules/google-gax/build/protos/google/api/billing.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/client.proto +165 -53
- package/server/node_modules/google-gax/build/protos/google/api/cloudquotas/v1/resources.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/cloudquotas/v1beta/quota_adjuster_settings.proto +7 -3
- package/server/node_modules/google-gax/build/protos/google/api/cloudquotas/v1beta/resources.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/config_change.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/context.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/control.proto +3 -3
- package/server/node_modules/google-gax/build/protos/google/api/distribution.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/documentation.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/endpoint.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/error_reason.proto +186 -1
- package/server/node_modules/google-gax/build/protos/google/api/expr/v1alpha1/checked.proto +31 -3
- package/server/node_modules/google-gax/build/protos/google/api/expr/v1alpha1/eval.proto +8 -9
- package/server/node_modules/google-gax/build/protos/google/api/expr/v1alpha1/explain.proto +1 -2
- package/server/node_modules/google-gax/build/protos/google/api/expr/v1alpha1/syntax.proto +20 -22
- package/server/node_modules/google-gax/build/protos/google/api/expr/v1alpha1/value.proto +2 -3
- package/server/node_modules/google-gax/build/protos/google/api/field_behavior.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/field_info.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/http.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/httpbody.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/label.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/launch_stage.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/log.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/logging.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/metric.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/monitored_resource.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/monitoring.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/policy.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/quota.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/resource.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/routing.proto +8 -4
- package/server/node_modules/google-gax/build/protos/google/api/service.proto +2 -3
- package/server/node_modules/google-gax/build/protos/google/api/source_info.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/system_parameter.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/usage.proto +7 -27
- package/server/node_modules/google-gax/build/protos/google/api/visibility.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/longrunning/operations.proto +20 -1
- package/server/node_modules/google-gax/build/protos/google/protobuf/any.proto +52 -108
- package/server/node_modules/google-gax/build/protos/google/protobuf/compiler/ruby/ruby_generated_code.proto +2 -0
- package/server/node_modules/google-gax/build/protos/google/protobuf/cpp_features.proto +21 -1
- package/server/node_modules/google-gax/build/protos/google/protobuf/cpp_file_options.proto +24 -0
- package/server/node_modules/google-gax/build/protos/google/protobuf/cpp_options.proto +15 -0
- package/server/node_modules/google-gax/build/protos/google/protobuf/descriptor.proto +118 -30
- package/server/node_modules/google-gax/build/protos/google/protobuf/field_mask.proto +16 -18
- package/server/node_modules/google-gax/build/protos/google/protobuf/internal_options.proto +8 -1
- package/server/node_modules/google-gax/build/protos/google/protobuf/json/json_enumval_custom_string.proto +26 -0
- package/server/node_modules/google-gax/build/protos/google/protobuf/json_enumvalue_options.proto +29 -0
- package/server/node_modules/google-gax/build/protos/google/protobuf/json_options.proto +14 -0
- package/server/node_modules/google-gax/build/protos/google/protobuf/struct.proto +38 -22
- package/server/node_modules/google-gax/build/protos/google/protobuf/test_protos/forced_micro_string.proto +3 -0
- package/server/node_modules/google-gax/build/protos/google/protobuf/test_protos/repeated_field_proxy_import_message.proto +14 -0
- package/server/node_modules/google-gax/build/protos/google/protobuf/timestamp.proto +9 -8
- package/server/node_modules/google-gax/build/protos/google/protobuf/util/json_format_proto3.proto +18 -0
- package/server/node_modules/google-gax/build/protos/google/rpc/code.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/rpc/context/attribute_context.proto +7 -2
- package/server/node_modules/google-gax/build/protos/google/rpc/context/audit_context.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/rpc/error_details.proto +5 -5
- package/server/node_modules/google-gax/build/protos/google/rpc/http.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/rpc/status.proto +1 -2
- package/server/node_modules/google-gax/build/protos/google/type/calendar_period.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/type/color.proto +9 -10
- package/server/node_modules/google-gax/build/protos/google/type/date.proto +11 -9
- package/server/node_modules/google-gax/build/protos/google/type/datetime.proto +17 -17
- package/server/node_modules/google-gax/build/protos/google/type/dayofweek.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/type/decimal.proto +11 -13
- package/server/node_modules/google-gax/build/protos/google/type/expr.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/type/fraction.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/type/interval.proto +1 -2
- package/server/node_modules/google-gax/build/protos/google/type/latlng.proto +4 -5
- package/server/node_modules/google-gax/build/protos/google/type/localized_text.proto +3 -3
- package/server/node_modules/google-gax/build/protos/google/type/money.proto +1 -2
- package/server/node_modules/google-gax/build/protos/google/type/month.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/type/phone_number.proto +20 -15
- package/server/node_modules/google-gax/build/protos/google/type/postal_address.proto +39 -39
- package/server/node_modules/google-gax/build/protos/google/type/quaternion.proto +4 -4
- package/server/node_modules/google-gax/build/protos/google/type/timeofday.proto +11 -8
- package/server/node_modules/google-gax/package.json +5 -5
- package/server/node_modules/retry-request/package.json +4 -4
- package/server/node_modules/teeny-request/package.json +5 -5
- package/server/node_modules/undici/lib/cache/memory-cache-store.js +54 -9
- package/server/node_modules/undici/lib/cache/sqlite-cache-store.js +7 -1
- package/server/node_modules/undici/lib/core/request.js +12 -1
- package/server/node_modules/undici/lib/dispatcher/client-h1.js +11 -2
- package/server/node_modules/undici/lib/global.js +36 -16
- package/server/node_modules/undici/lib/handler/cache-handler.js +236 -116
- package/server/node_modules/undici/lib/handler/cache-revalidation-handler.js +3 -3
- package/server/node_modules/undici/lib/handler/retry-handler.js +24 -0
- package/server/node_modules/undici/lib/interceptor/cache.js +152 -62
- package/server/node_modules/undici/lib/interceptor/decompress.js +5 -2
- package/server/node_modules/undici/lib/util/cache.js +328 -66
- package/server/node_modules/undici/lib/util/date.js +23 -6
- package/server/node_modules/undici/lib/web/cookies/util.js +78 -8
- package/server/node_modules/undici/package.json +1 -1
- package/server/{orphan-proposed-reconciler-BvKkWMJQ.js → orphan-proposed-reconciler-B6vJHxtX.js} +242 -34
- package/server/{orphan-proposed-reconciler-CTSGcK8p.js → orphan-proposed-reconciler-DcgTPPFY.js} +1 -1
- package/server/package-lock.json +31 -31
- package/server/package.json +1 -1
- package/server/{pan-dir-B0c3w0Ya.js → pan-dir-DMzF5wne.js} +25 -11
- package/server/{paths-D-xWGHdh.js → paths-sJBSb7Ul.js} +2 -2
- package/server/pending-lifecycle-claim-DilzGfgk.js +110 -0
- package/server/persistent-logger-H_VjuOu7.js +57 -0
- package/server/{pickup-DUCLWrJY.js → pickup-DWhqzliO.js} +4 -3
- package/server/pipeline-membership-C88VBnhJ.js +3 -0
- package/server/pipeline-membership-D9SBvItj.js +57 -0
- package/server/pipeline-membership-gather-4eR-7Tqy.js +3 -0
- package/server/pipeline-membership-gather-CeVGnNJ2.js +593 -0
- package/server/{pipeline-notifier-BXkJzDC4.js → pipeline-notifier-D0ALV6Nw.js} +2 -2
- package/server/{pipeline-notifier-BJr8gQX6.js → pipeline-notifier-DT6xLFao.js} +1 -1
- package/server/post-merge-lifecycle-worker-8HIeS_J6.js +50 -0
- package/server/{project-pipelines-C0MWUeCU.js → project-pipelines-9SKt2bEc.js} +2 -2
- package/server/{project-repos-B6GycDh9.js → project-repos-B5pIphKg.js} +7 -3
- package/server/project-repos-DPjOdfPa.js +3 -0
- package/server/projects-_n3Zui6K.js +3 -0
- package/server/{prompts-DxzFXuLl.js → prompts-CgzMBvQF.js} +2 -2
- package/server/{providers-u4Ga0jOr.js → providers-BI1mOBQ4.js} +1 -1
- package/server/{providers-qQAwGQDW.js → providers-BJQSnAAp.js} +7 -7
- package/server/public/assets/{chunk-BO2N2NFS-BamJdinX.js → chunk-BO2N2NFS-D_pGACYN.js} +4 -4
- package/server/public/assets/{diagram-OG6HWLK6-DfOB8-w4.js → diagram-OG6HWLK6-BO6fe3hH.js} +1 -1
- package/server/public/assets/{dist-ByIuzMQW.js → dist-5zingMiA.js} +3 -3
- package/server/public/assets/{dist-D7zYSEA6.js → dist-CVxhbI2E.js} +1 -1
- package/server/public/assets/{ganttDiagram-6RSMTGT7-EdmRyXL3.js → ganttDiagram-6RSMTGT7-Bgj4A7kp.js} +1 -1
- package/server/public/assets/{highlighted-body-OFNGDK62-MerOfTX8.js → highlighted-body-OFNGDK62-DNPK7_cm.js} +1 -1
- package/server/public/assets/index-DEpY-D1O.js +807 -0
- package/server/public/assets/index-Ddkcz3WT.css +1 -0
- package/server/public/assets/{linear-BBbArIcK.js → linear-BB0jQT16.js} +1 -1
- package/server/public/assets/mermaid-GHXKKRXX-BzPfaQJ1.js +1 -0
- package/server/public/assets/{pieDiagram-4H26LBE5-BKIddiJN.js → pieDiagram-4H26LBE5-DeGIzzpZ.js} +1 -1
- package/server/public/assets/{prod-B8vYiu52.js → prod-XBLvikex.js} +4 -4
- package/server/public/assets/{quadrantDiagram-W4KKPZXB-D6RtoULk.js → quadrantDiagram-W4KKPZXB-BV9SLeWz.js} +1 -1
- package/server/public/assets/{sankeyDiagram-5OEKKPKP-CLrCedZX.js → sankeyDiagram-5OEKKPKP-Dwja0gj8.js} +1 -1
- package/server/public/assets/{xychartDiagram-2RQKCTM6-hznR8DYl.js → xychartDiagram-2RQKCTM6-DCB4qvfw.js} +1 -1
- package/server/public/index.html +2 -2
- package/server/{pull-requests-_lHueOHW.js → pull-requests-7BgLDsIo.js} +19 -10
- package/server/{pull-requests-7N8WKseP.js → pull-requests-Dq0y6IxE.js} +1 -1
- package/server/{queries-CjNIf-Ub.js → queries-C-MUZaIy.js} +824 -192
- package/server/{rally-CyWT_lNO.js → rally-CPysR4T_.js} +3 -3
- package/server/rally-D_VW4bJv.js +3 -0
- package/server/{rally-api-C8e_1JRi.js → rally-api-8Ptlp2os.js} +2 -2
- package/server/{rally-api-ClOSd-Tt.js → rally-api-CgosKdKL.js} +1 -1
- package/server/{rally-client-sgtVqzNU.js → rally-client-CCX0hADj.js} +1 -1
- package/server/{rally-client-lc-nokqr.js → rally-client-iYMHWQD7.js} +5 -5
- package/server/{reap-terminal-sessions-7KeHv1R1.js → reap-terminal-sessions-4Xg9NGA8.js} +2 -2
- package/server/{reap-terminal-sessions-BtHPo6Xc.js → reap-terminal-sessions-Qf-9LVQc.js} +2 -2
- package/server/{rebuild-stack-lwtsW0GO.js → rebuild-stack-CMdgaylx.js} +16 -7
- package/server/{rebuild-stack-CFvcBHsS.js → rebuild-stack-DqcOVmJO.js} +2 -2
- package/server/{reconstruct-cache-C3Ui7ojV.js → reconstruct-cache-CMZJ_Vjq.js} +9 -7
- package/server/record-BTwWhtBb.js +3 -0
- package/server/{record-update-dE1Aw83j.js → record-update-DaOKS7Wb.js} +124 -157
- package/server/record-update-DhI7eySG.js +3 -0
- package/server/{recovery-trip-BvRWfUXM.js → recovery-trip-DDH-02ng.js} +2 -2
- package/server/{release-engine-Cx48W7z8.js → release-engine-B2X9AfFC.js} +5 -5
- package/server/{release-set-CQfuN9-v.js → release-set-G4XKyQ8K.js} +3 -3
- package/server/{remote-C_2hasl7.js → remote-BXarMvqf.js} +3 -3
- package/server/{remote-ChgimyYa.js → remote-CUhyqjXk.js} +3 -3
- package/server/{remote-agents-By1ige5O.js → remote-agents-Bba-MgSA.js} +311 -48
- package/server/{remote-agents-CA3Ihlxj.js → remote-agents-CLZB3Coc.js} +2 -2
- package/server/{remote-completion-fVe9e_3u.js → remote-completion-CwAp79EC.js} +13 -13
- package/server/resume-mOREjlYu.js +3 -0
- package/server/{review-agent-CIGOQYBD.js → review-agent--pOptAEV.js} +65 -50
- package/server/{review-agent-DNboMyW4.js → review-agent-BTCNkq2h.js} +1 -1
- package/server/{review-artifacts-nRDPuMxd.js → review-artifacts-BNmw8dWE.js} +7 -6
- package/server/{review-context-2uj-YQ8J.js → review-context-DFxYOOJW.js} +9 -9
- package/server/{in-flight-guard-CAAkqPLu.js → review-convoy-liveness-BgU_1jJf.js} +3 -44
- package/server/review-status-CGvlA4o_.js +7737 -0
- package/server/review-status-Dma9SFaN.js +3 -0
- package/server/review-status-emit-DURrmGYX.js +50 -0
- package/server/{review-status-enrichment-Dci-ZwEt.js → review-status-enrichment-8NiNXi5W.js} +4 -4
- package/server/review-status-source-BLx_1siH.js +3 -0
- package/server/{review-status-source-CxuEjLGg.js → review-status-source-DIk1JSow.js} +24 -3
- package/server/{review-status-sync-BTOpxtTC.js → review-status-sync-0GxOqeqF.js} +11 -6
- package/server/{review-status-sync-DSDK3OMy.js → review-status-sync-muT-EBp2.js} +1 -1
- package/server/{review-verdict-feedback-CTd4QMBu.js → review-verdict-feedback-HwF6ODFy.js} +1 -1
- package/server/{review-verdict-feedback-CCjVA7Uk.js → review-verdict-feedback-xJNdqBnX.js} +65 -11
- package/server/{rollup-FGsKki9R.js → rollup-BQaol5TX.js} +8 -8
- package/server/{rollup-BKQC7jp4.js → rollup-BR4t_wck.js} +1 -1
- package/server/{scanner-CnqEZeDy.js → scanner-C-D2cFdX.js} +8 -7
- package/server/{sequence-io-D909zgeH.js → sequence-io-Bmf1EZM5.js} +4 -4
- package/server/{sequencer-agent-CzkcK6P5.js → sequencer-agent-CigMyKh2.js} +7 -6
- package/server/server.js +2005 -614
- package/server/{service-CLeAoU6G.js → service-CD0DvFvD.js} +114 -68
- package/server/{session-fork-CHI1XvL9.js → session-fork-B6cQ5eya.js} +2 -2
- package/server/{session-history-BT3IvqhC.js → session-history-3ON_IJjm.js} +7 -55
- package/server/settings-CVmWiJ-r.js +2 -0
- package/server/{settings-C0zgxOGf.js → settings-PilbFZAM.js} +3 -2
- package/server/{settings-BTMvpNFU.js → settings-VN0qOh4U.js} +3 -3
- package/server/{shadow-engineering-BJfgm-hX.js → shadow-engineering-DXvx77oE.js} +3 -3
- package/server/{shadow-state-7a-524T8.js → shadow-state-BBk_zacw.js} +2 -2
- package/server/{shadow-state-DnDyjujH.js → shadow-state-CZBp7pwq.js} +1 -1
- package/server/{shadow-utils-Db3oroFG.js → shadow-utils-DdZ05AJS.js} +2 -2
- package/server/{ship-log-D9MlVzYU.js → ship-log-7kJfjUX2.js} +1 -1
- package/server/{smart-compaction-CV2ukKND.js → smart-compaction-8fA5k5XN.js} +1 -1
- package/server/{smart-compaction-KCYScAU1.js → smart-compaction-ByhL9cRS.js} +8 -7
- package/server/{spawn-planning-session-DKpdFyOC.js → spawn-planning-session-pcF-YeFE.js} +38 -50
- package/server/spawn-planning-session-vLUJoFjy.js +3 -0
- package/server/{specialist-completion-Ky9wCDpb.js → specialist-completion-B07XjWD2.js} +1 -1
- package/server/{specialist-context-Bn3dCGS2.js → specialist-context-DJ-zFyL3.js} +5 -5
- package/server/{specialist-handoff-logger-CMEwYxa2.js → specialist-handoff-logger-aKSxbIgD.js} +2 -2
- package/server/{specialist-logs-C5p8G7tx.js → specialist-logs-Dae-n52_.js} +3 -3
- package/server/{specialists-CC4r-c2s.js → specialists-6PWdtWcg.js} +1177 -311
- package/server/{specialists-DM6bWjsi.js → specialists-Bz-wFT7R.js} +1 -1
- package/server/{specialists-jiuuyVkp.js → specialists-DUiExaxb.js} +18 -18
- package/server/{specialists-CShuVGWT.js → specialists-KR3pKulN.js} +1 -1
- package/server/specs--enInima.js +3 -0
- package/server/src-B948bGVR.js +11452 -0
- package/server/{src-CXmtj0im.js → src-rac0Mepv.js} +6 -6
- package/server/{src-CdmnTM2m.js → src-vHy2-oCv.js} +3 -3
- package/server/{stack-health-Bn3o8FBX.js → stack-health-BikqHSjn.js} +1 -1
- package/server/{stack-health-DxSdG9cW.js → stack-health-DqLTiEu4.js} +7 -5
- package/server/{stale-task-claims-KJKxxiiQ.js → stale-task-claims-Cab_Fo_Z.js} +5 -4
- package/server/{staleness-DPm7ClwA.js → staleness-C-a5rBxF.js} +1 -1
- package/server/{staleness-CT34nwr9.js → staleness-CGTZyp6V.js} +1 -1
- package/server/{state-home-Cn_Qu8IX.js → state-home-722Dkx92.js} +2 -2
- package/server/{state-mapping-BL_-3Yt8.js → state-mapping-CybR81Uf.js} +1 -1
- package/server/{state-migrate-BGg2ZaOt.js → state-migrate-2u8wIpoL.js} +4 -4
- package/server/{stuck-remediation-DYuPRYYw.js → stuck-remediation-CC6q3eqQ.js} +84 -26
- package/server/{stuck-remediation-s9_2qfi6.js → stuck-remediation-r1TJu68G.js} +1 -1
- package/server/{substrate-bug-weights-service-B-FwCs5V.js → substrate-bug-weights-service-CzIyyWFT.js} +3 -3
- package/server/{summary-fork-DpcxN9tf.js → summary-fork-BqgmgPDt.js} +2 -2
- package/server/{summary-fork-D1RAk9rJ.js → summary-fork-Df2WFijM.js} +8 -8
- package/server/supervisor/{injection-budget-Csw5tqfJ.js → injection-budget-Cg_KIb3o.js} +1 -1
- package/server/supervisor/{paths-DehGY2Fj.js → paths-BBOnCYlO.js} +10 -2
- package/server/supervisor/pty-supervisor.js +50 -4
- package/server/supervisor/{pty-token-x-ea28Us.js → pty-token-BbjwEUUM.js} +3 -3
- package/server/supervisor-B4anCCSm.js +2 -0
- package/server/{supervisor-wM4ooB5O.js → supervisor-BxqSpjcN.js} +3 -3
- package/server/{swarm-readiness-DlP_UjHq.js → swarm-readiness-DfFxa9-n.js} +3 -3
- package/server/{system-prerequisites-DUDj1YHf.js → system-prerequisites-ICLSkhhZ.js} +2 -2
- package/server/{teardown-workspace-DeTTImn-.js → teardown-workspace-DRdi_CPa.js} +15 -16
- package/server/{test-agent-queue-MbxX5vqq.js → test-agent-queue-A_-p-i0I.js} +8 -7
- package/server/{test-verdict-gscuksPv.js → test-verdict-BHgTAwIG.js} +1 -1
- package/server/{test-verdict-bWYBtqBg.js → test-verdict-C4i9aqEP.js} +1 -1
- package/server/{tldr-daemon-BYFkts95.js → tldr-daemon-CvWXBhX1.js} +1 -1
- package/server/{tldr-daemon-C-69c3OI.js → tldr-daemon-wvsU6bKv.js} +2 -2
- package/server/{tmux-R7N7y-Mh.js → tmux-CfDHob9M.js} +174 -4
- package/server/{tmux-B6z7h_vZ.js → tmux-Ctk6RV5l.js} +1 -1
- package/server/{token-BK6t8BIT.js → token-DrxwytsZ.js} +2 -2
- package/server/{token-util-DxXu-vd1.js → token-util-B48BlCba.js} +1 -1
- package/server/token-util-D411CAq9.js +3 -0
- package/server/{tracker-config-G6latr8C.js → tracker-config-BcPMElRB.js} +2 -2
- package/server/{tracker-utils-DHv5pSDT.js → tracker-utils-CJ6BHjcD.js} +3 -3
- package/server/{traefik-connect-Df2uXPsQ.js → traefik-connect-DZ6nMYMj.js} +1 -1
- package/server/{tunnel-DGdUkGoZ.js → tunnel-Bp-dRHZz.js} +1 -1
- package/server/{tunnel-CDVKJpRv.js → tunnel-DUbUPElU.js} +3 -3
- package/server/{typed-errors-BHhE85Ul.js → typed-errors-CKeoDdU3.js} +1 -1
- package/server/{typed-errors-2BTMxkZq.js → typed-errors-DyjseiB6.js} +1 -1
- package/server/{types-hraoaQIp.js → types-Cm5ASJbq.js} +1 -1
- package/server/{types-5M0lupud.js → types-Di8wdakq.js} +1 -1
- package/server/uat-promote-verification-CoJuh7XO.js +92 -0
- package/server/uat-train-4Q0k06CQ.js +0 -0
- package/server/uat-train-Dewoatps.js +2 -0
- package/server/{validate-IfDGkaVR.js → validate-B0C8p66t.js} +8 -6
- package/server/{validation-Dw1pzDzr.js → validation-B_kIRfNe.js} +4 -4
- package/server/{validation-CC9OPqJZ.js → validation-hVOwQk8T.js} +1 -1
- package/server/{verification-artifact-B3itKTxu.js → verification-artifact-BxlxTiYK.js} +1 -1
- package/server/{verification-artifact-TVFSz_q1.js → verification-artifact-D70AtckY.js} +1 -1
- package/server/{verification-runner-BW4HOKAz.js → verification-runner-Bc3cJvpC.js} +1 -1
- package/server/{verification-runner-CkgX6EtI.js → verification-runner-KZTz6u72.js} +40 -18
- package/server/{vtt-parser-DYPbKcIJ.js → vtt-parser-CE_i3Bcw.js} +1 -1
- package/server/{work-agent-prompt-Du8Vh2aJ.js → work-agent-prompt-ByrPAzOy.js} +20 -9
- package/server/{workflows-mbQzh6mQ.js → workflows-D0vP1WrK.js} +252 -99
- package/server/workflows-DtDX08ed.js +2 -0
- package/server/{workspace--8tnhDI0.js → workspace-COWvdibH.js} +1 -1
- package/server/{workspace-BPUws1-_.js → workspace-DQkRPLlQ.js} +3 -3
- package/server/workspace-anchor-drift-DXYIAHzr.js +224 -0
- package/server/workspace-anchor-drift-pwz23TI1.js +3 -0
- package/server/{workspace-config-CIVWZOQr.js → workspace-config-BdZM4PvZ.js} +1 -1
- package/server/{workspace-manager-CBhNdzE4.js → workspace-manager-BPgTrG66.js} +157 -118
- package/server/workspace-manager-C1F3XsnS.js +3 -0
- package/server/{workspace-metadata-BzHnwwX4.js → workspace-metadata-CdjzAP8x.js} +1 -1
- package/server/{workspace-metadata-_WygnyoX.js → workspace-metadata-DkO_iTLo.js} +2 -2
- package/server/{workspaces-Do_9J0LQ.js → workspaces-CRBJikLp.js} +749 -299
- package/sync-sources/dev-skills/pan-dashboard-restart/SKILL.md +34 -10
- package/sync-sources/hooks/linear-mcp-auth-hook +97 -0
- package/sync-sources/rules/ask-user-question-self-contained.md +9 -0
- package/sync-sources/skills/pan-close/SKILL.md +5 -3
- package/sync-sources/skills/pan-merge/SKILL.md +7 -5
- package/sync-sources/skills/pan-peer-review/SKILL.md +195 -0
- package/sync-sources/skills/pan-release/SKILL.md +57 -0
- package/sync-sources/skills/pan-reload/SKILL.md +3 -3
- package/sync-sources/skills/pan-restart/SKILL.md +5 -4
- package/sync-sources/skills/pan-review/SKILL.md +7 -1
- package/sync-sources/skills/pan-sync-main/SKILL.md +9 -8
- package/sync-sources/skills/pipeline-status/SKILL.md +10 -1
- package/sync-sources/skills/workspace-add-repo/SKILL.md +16 -1
- package/server/activity-logger-OEUBdfZ8.js +0 -3
- package/server/agent-state-Bc3tzUC8.js +0 -3
- package/server/agent-state-service-D5UGKIJL.js +0 -2
- package/server/agents-wi9NWzs2.js +0 -3
- package/server/archive-planning-BZDgzoEj.js +0 -3
- package/server/cli-B86rejVV.js +0 -3
- package/server/conflict-gate-BhAY7TUd.js +0 -3
- package/server/conversation-service-BLd3MYsG.js +0 -3
- package/server/deacon-kiQrb4ZT.js +0 -4
- package/server/deacon-swarm-C-GwfjJy.js +0 -2
- package/server/deploy-window-DkZraDyj.js +0 -3
- package/server/dist-Bzy0y69j.js +0 -3
- package/server/dod-C6n9RV3G.js +0 -66
- package/server/flywheel-merge-order-UU0tiUld.js +0 -245
- package/server/flywheel-merge-order-UUcsCDb6.js +0 -2
- package/server/forge-CNFnyqps.js +0 -270
- package/server/forge-DXnS_YFH.js +0 -2
- package/server/git-utils-D0_yhCgF.js +0 -3
- package/server/github-pr-lookup-D16NGsSO.js +0 -44
- package/server/hume-ccTf4wTX.js +0 -3
- package/server/inspect-agent-Brtz0URj.js +0 -2
- package/server/label-reconciler-B4iOAjlC.js +0 -113
- package/server/launcher-generator-BBWG_SiS.js +0 -473
- package/server/merge-ops-CR44oU9-.js +0 -2
- package/server/merge-set-bUqbm3yc.js +0 -3
- package/server/merge-sync-BJYeOODr.js +0 -3
- package/server/merge-verification-BkaOqPsw.js +0 -124
- package/server/pipeline-membership-mY3GprlK.js +0 -420
- package/server/project-repos-DXKQsc_m.js +0 -3
- package/server/projects-vjjcmiN8.js +0 -3
- package/server/public/assets/index-CWeMerGO.js +0 -804
- package/server/public/assets/index-CenuJ3Cw.css +0 -1
- package/server/public/assets/mermaid-GHXKKRXX-CpPWAFwE.js +0 -1
- package/server/rally-zhhtXuDP.js +0 -3
- package/server/record-CN0pj4_5.js +0 -3
- package/server/record-update-bLJxAXH4.js +0 -3
- package/server/resume-BFv1PGpA.js +0 -3
- package/server/review-status-btEYlaxA.js +0 -3
- package/server/review-status-kZj_KyCk.js +0 -1470
- package/server/settings-66A6uvIA.js +0 -2
- package/server/spawn-planning-session-qUC2VWu3.js +0 -2
- package/server/specs-C8Wsn2XO.js +0 -3
- package/server/src-DtcUOZCq.js +0 -4826
- package/server/supervisor-FTJAIsAK.js +0 -2
- package/server/token-util-DuPuNriz.js +0 -3
- package/server/tracker-utils-B4ylXZQK.js +0 -3
- package/server/uat-train-B05BWkp-.js +0 -2
- package/server/uat-train-DDSrSoV1.js +0 -2152
- package/server/workflows-BQu4RFQ-.js +0 -2
- package/server/workspace-manager-CWT55qeI.js +0 -3
|
@@ -1,44 +1,49 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { d as getOverdeckDatabaseSync, f as init_infra } from "./infra-
|
|
5
|
-
import {
|
|
6
|
-
import { a as init_event_store, n as getEventStore } from "./event-store-
|
|
7
|
-
import { _ as
|
|
8
|
-
import { _ as
|
|
9
|
-
import { o as getPricingSync, s as init_cost, t as calculateCostSync } from "./cost-
|
|
10
|
-
import {
|
|
11
|
-
import { f as CostWriter, l as CostDoorLive } from "./service-
|
|
12
|
-
import { a as init_tracker_config, t as getGitHubConfig } from "./tracker-config-
|
|
13
|
-
import {
|
|
14
|
-
import { o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import { a as
|
|
25
|
-
import {
|
|
26
|
-
import { r as
|
|
27
|
-
import {
|
|
28
|
-
import { r as
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import { n as
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import { t as
|
|
1
|
+
import { An as extractTeamPrefix, Er as GitError, Fr as init_errors, Gn as init_projects, Pn as findProjectByTeamSync, Tr as FsError, Yn as listProjectsSync, ar as resolveProjectFromIssueSync, br as resolveIssueIdSync, ci as getOverdeckHome, gn as isStatePlaneOnlyStatus, gr as init_issue_id, hn as init_state_plane, hr as extractPrefixSync, li as init_paths, mr as extractNumberSync, t as init_config_yaml, ti as encodeClaudeProjectDir, tt as resolveModel, vr as parseIssueIdSync, zn as getProjectSync } from "./config-yaml-CxdwhAIA.js";
|
|
2
|
+
import { At as jsonResponse, Ot as httpHandler, ct as spawnPanCli, n as _serverManagedMerges, nt as isInternalAgentRequest, ot as getWorkAgentLifecycleStateSync, rt as resolveRequestedStartedBy, wt as getHeaderFromMap, xt as rejectUnsafeDashboardMutationRequest, yt as rejectUnauthorizedDashboardRequest } from "./specialists-6PWdtWcg.js";
|
|
3
|
+
import { o as init_activity_logger, r as emitActivityEntrySync } from "./activity-logger-CyteR4JO.js";
|
|
4
|
+
import { d as getOverdeckDatabaseSync, f as init_infra } from "./infra-BDQDRopn.js";
|
|
5
|
+
import { H as sessionExists, M as listSessionNames, at as buildChildEnvWithoutTmuxSync, i as capturePane, ot as init_child_env, w as init_tmux } from "./tmux-CfDHob9M.js";
|
|
6
|
+
import { a as init_event_store, n as getEventStore } from "./event-store-CrHcVC5_.js";
|
|
7
|
+
import { C as setReviewStatusSync, _ as markWorkspaceStuck, b as setAutoMerge, d as getReviewStatusSync, h as loadReviewStatuses, p as init_review_status, r as clearFeedbackDeliveryStuck, x as setDeaconIgnored } from "./review-status-CGvlA4o_.js";
|
|
8
|
+
import { _ as findPositionInQueueSync, a as EventStoreService, g as computeQueuePositionFromStatusSync, s as init_domain_services, v as init_queue_position } from "./issue-lifecycle-Birk-ifu.js";
|
|
9
|
+
import { o as getPricingSync, s as init_cost, t as calculateCostSync } from "./cost-DpgYmYqR.js";
|
|
10
|
+
import { Br as saveAgentRuntimeState, Qn as decideResumeGate, Rr as getAgentRuntimeStateSync, X as messageAgent, Zn as clearYieldForResumeSync, Zt as transitionIssueToInReview, _r as saveAgentStateSync, b as init_agents, er as getAgentResumeGateBlockReason, i as listRunningAgents, ir as init_agent_state, rr as getAgentStateSync, tr as getAgentState, ut as spawnAgent } from "./queries-C-MUZaIy.js";
|
|
11
|
+
import { f as CostWriter, l as CostDoorLive } from "./service-CD0DvFvD.js";
|
|
12
|
+
import { a as init_tracker_config, t as getGitHubConfig } from "./tracker-config-BcPMElRB.js";
|
|
13
|
+
import { n as resolveGitHubIssueSync, t as init_tracker_utils } from "./tracker-utils-CJ6BHjcD.js";
|
|
14
|
+
import { o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-DzK385vD.js";
|
|
15
|
+
import { r as notifyPipelineSync, t as init_pipeline_notifier } from "./pipeline-notifier-D0ALV6Nw.js";
|
|
16
|
+
import { a as PAN_DIRNAME, i as PAN_CONTINUE_FILENAME, p as init_types } from "./types-Cm5ASJbq.js";
|
|
17
|
+
import { a as getAllActiveQueues, c as init_merge_sync } from "./merge-sync-kr4vqyjM.js";
|
|
18
|
+
import { l as resolveWorkspaceRepoRootsSync, r as init_project_repos } from "./project-repos-B5pIphKg.js";
|
|
19
|
+
import { O as findXBriefByIssue, _ as XBRIEF_INSPECTION_POLICIES, c as mergeRecordStatusOverrides, g as serializeXBriefDocument, j as readXBriefDocument, k as init_xbrief_index, o as init_io, r as findPlan, s as isPlanningComplete, u as readPlan, v as init_types$1 } from "./io-B00PBNku.js";
|
|
20
|
+
import { it as findConversationForCostSessionSync, k as init_conversations } from "./conversations-D0UEdLtk.js";
|
|
21
|
+
import { E as normalizeModelOverrideSync, T as init_model_validation } from "./auto-spawn-consent-CQ9Bi9q6.js";
|
|
22
|
+
import { f as init_config, m as loadConfigSync$1 } from "./config-BvLe652W.js";
|
|
23
|
+
import { a as getWorkspaceStackHealth, n as collectDockerContainerLifecycleSnapshot, r as composeProjectNameForWorkspace, s as init_stack_health } from "./stack-health-DqLTiEu4.js";
|
|
24
|
+
import { a as criticalPath, l as init_dag, t as actionableDoc } from "./dag-BtkgLeqY.js";
|
|
25
|
+
import { E as verifyAppCanMerge, M as withConcurrencyLimit, f as init_github_app, j as init_concurrency, m as isIntegrationPermissionError } from "./github-app-CmNk0zLU.js";
|
|
26
|
+
import { a as readEventsFromLineSync, i as init_events, l as init_wal, o as readEventsSync, r as getLastEventMetadataSync, t as appendCostEventSync } from "./events-BNrvchBg.js";
|
|
27
|
+
import { n as getContainersReferencingWorkspacePath, r as init_workspace_manager } from "./workspace-manager-BPgTrG66.js";
|
|
28
|
+
import { r as init_devcontainer_renderer, t as DEVCONTAINER_DIRNAME } from "./devcontainer-renderer-BUOIlfgD.js";
|
|
29
|
+
import { a as init_jsonl_parser, t as getActiveSessionModelSync } from "./jsonl-parser-BDpnGFCl.js";
|
|
30
|
+
import { i as findWorkspacePath } from "./archive-planning-BwhxeP7C.js";
|
|
31
|
+
import { n as init_merge_verification, t as handlePostRebaseVerificationDeferral } from "./merge-verification-NvaAd8CZ.js";
|
|
32
|
+
import { i as init_conflict_gate, r as getCachedConflictGateMergeability } from "./conflict-gate-E4nt7ZeS.js";
|
|
33
|
+
import { r as init_in_flight_guard, t as createInFlightGuard } from "./in-flight-guard-D-sSkADM.js";
|
|
34
|
+
import { a as loadWorkspaceMetadataSync, i as listWorkspaceMetadataSync } from "./workspace-metadata-DkO_iTLo.js";
|
|
35
|
+
import { n as enrichReviewStatusFromSessions } from "./review-status-enrichment-8NiNXi5W.js";
|
|
36
|
+
import { n as generateDailySummary, r as init_cli } from "./cli-Cte9ZFGn.js";
|
|
37
|
+
import { a as getDiffStat, i as getDiffBase, o as init_review_context, r as getChangedFiles } from "./review-context-DFxYOOJW.js";
|
|
38
|
+
import { n as getTldrDaemonServiceSync, r as init_tldr_daemon } from "./tldr-daemon-wvsU6bKv.js";
|
|
39
|
+
import { C as init_operations, S as gitPush, T as listGitOperationsSync, a as init_merge_agent, w as init_git_activity, x as MainDivergedError, y as syncMainIntoWorkspace } from "./merge-agent-BLUgRsz3.js";
|
|
40
|
+
import { F as enqueueMerge, I as getAllActiveQueues$1, L as getCurrentMerge, P as dequeueMerge, z as markMergeProcessing } from "./merge-DiW9RdSB.js";
|
|
41
|
+
import { t as rebaseFeatureBranch } from "./merge-rebase-DIkBjgwq.js";
|
|
42
|
+
import { n as init_release_set, t as getReleaseSetSync } from "./release-set-G4XKyQ8K.js";
|
|
43
|
+
import { r as runVerificationForIssue } from "./verification-runner-KZTz6u72.js";
|
|
44
|
+
import { n as init_durable_review_pipeline, r as registerDurableReviewPipelineHandler } from "./durable-review-pipeline-Cibps-Rg.js";
|
|
45
|
+
import { t as teardownWorkspace } from "./teardown-workspace-DRdi_CPa.js";
|
|
46
|
+
import { t as init_rebuild_stack } from "./rebuild-stack-CMdgaylx.js";
|
|
42
47
|
import { basename, dirname, join, resolve, sep } from "node:path";
|
|
43
48
|
import { Effect, Layer, Option, Stream } from "effect";
|
|
44
49
|
import { closeSync, existsSync, fstatSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, renameSync, writeFileSync } from "fs";
|
|
@@ -97,7 +102,7 @@ async function captureInterestedAgent(state, agentId) {
|
|
|
97
102
|
try {
|
|
98
103
|
const remoteState = await readFile(join(homedir$1(), ".overdeck", "agents", agentId, "remote-state.json"), "utf-8").then((text) => JSON.parse(text)).catch(() => null);
|
|
99
104
|
if (remoteState?.location === "remote" && remoteState?.vmName) {
|
|
100
|
-
const { getRemoteAgentOutput } = await import("./remote-agents-
|
|
105
|
+
const { getRemoteAgentOutput } = await import("./remote-agents-CLZB3Coc.js");
|
|
101
106
|
stdout = await getRemoteAgentOutput(agentId, remoteState.vmName, 50);
|
|
102
107
|
} else stdout = await Effect.runPromise(capturePane(agentId, 50));
|
|
103
108
|
} catch {
|
|
@@ -340,7 +345,7 @@ async function processPendingFeedbackDeliveries(options) {
|
|
|
340
345
|
const staleThresholdMs = options?.staleThresholdMs ?? STALE_THRESHOLD_MS;
|
|
341
346
|
const now = options?.now ?? Date.now();
|
|
342
347
|
const deliver = options?._deliver ?? messageAgent;
|
|
343
|
-
const getAgentState = options?._getAgentState ?? ((agentId) => Effect.runPromise(getAgentState(agentId)));
|
|
348
|
+
const getAgentState$1 = options?._getAgentState ?? ((agentId) => Effect.runPromise(getAgentState(agentId)));
|
|
344
349
|
const loadStatuses = options?._loadStatuses ?? loadReviewStatuses;
|
|
345
350
|
const getStatus = options?._getStatus ?? getReviewStatusSync;
|
|
346
351
|
if (!existsSync$1(filePath)) return;
|
|
@@ -355,7 +360,7 @@ async function processPendingFeedbackDeliveries(options) {
|
|
|
355
360
|
const createdAt = Date.parse(delivery.createdAt);
|
|
356
361
|
if (Number.isFinite(createdAt) && now - createdAt > staleThresholdMs) continue;
|
|
357
362
|
if (!isDeliveryStillRelevant(delivery, statuses[delivery.issueId] ?? getStatus(delivery.issueId))) continue;
|
|
358
|
-
if (!await getAgentState(delivery.agentId)) {
|
|
363
|
+
if (!await getAgentState$1(delivery.agentId)) {
|
|
359
364
|
remaining.push(delivery);
|
|
360
365
|
continue;
|
|
361
366
|
}
|
|
@@ -390,7 +395,7 @@ var DatabaseProvisionerError = class extends Error {
|
|
|
390
395
|
};
|
|
391
396
|
//#endregion
|
|
392
397
|
//#region ../../lib/db-provisioners/flyway-postgres.ts
|
|
393
|
-
const execAsync$
|
|
398
|
+
const execAsync$9 = promisify(exec);
|
|
394
399
|
function shellQuote(value) {
|
|
395
400
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
396
401
|
}
|
|
@@ -463,7 +468,7 @@ async function cleanFile(filePath) {
|
|
|
463
468
|
async function repairFlywayIfNeeded$1(issueId, pgContainer, dbName, projectConfig, workspacePath, log) {
|
|
464
469
|
const emit = log || ((msg) => console.log(`[flyway-repair] ${msg}`));
|
|
465
470
|
try {
|
|
466
|
-
await execAsync$
|
|
471
|
+
await execAsync$9(`docker exec "${pgContainer}" pg_isready -U postgres`, {
|
|
467
472
|
encoding: "utf-8",
|
|
468
473
|
timeout: 5e3
|
|
469
474
|
});
|
|
@@ -475,7 +480,7 @@ async function repairFlywayIfNeeded$1(issueId, pgContainer, dbName, projectConfi
|
|
|
475
480
|
}
|
|
476
481
|
let rowCount = 0;
|
|
477
482
|
try {
|
|
478
|
-
const { stdout } = await execAsync$
|
|
483
|
+
const { stdout } = await execAsync$9(`docker exec "${pgContainer}" psql -U postgres -d ${dbName} -t -A -c "SELECT count(*) FROM flyway_schema_history;"`, {
|
|
479
484
|
encoding: "utf-8",
|
|
480
485
|
timeout: 1e4
|
|
481
486
|
});
|
|
@@ -499,7 +504,7 @@ async function repairFlywayIfNeeded$1(issueId, pgContainer, dbName, projectConfi
|
|
|
499
504
|
message: `Flyway baseline not found: ${flywayFile}`
|
|
500
505
|
};
|
|
501
506
|
emit(`Loading Flyway baseline from ${flywayFile}`);
|
|
502
|
-
await execAsync$
|
|
507
|
+
await execAsync$9(`docker exec -i "${pgContainer}" psql -U postgres -d ${dbName} < "${flywayFile}"`, {
|
|
503
508
|
encoding: "utf-8",
|
|
504
509
|
timeout: 6e4
|
|
505
510
|
});
|
|
@@ -523,7 +528,7 @@ async function repairFlywayIfNeeded$1(issueId, pgContainer, dbName, projectConfi
|
|
|
523
528
|
const tmpSql = `/tmp/flyway-checksum-sync-${Date.now()}.sql`;
|
|
524
529
|
await writeFile(tmpSql, updates.join("\n"));
|
|
525
530
|
try {
|
|
526
|
-
const { stdout } = await execAsync$
|
|
531
|
+
const { stdout } = await execAsync$9(`docker exec -i "${pgContainer}" psql -U postgres -d ${dbName} < "${tmpSql}"`, {
|
|
527
532
|
encoding: "utf-8",
|
|
528
533
|
timeout: 3e4
|
|
529
534
|
});
|
|
@@ -538,7 +543,7 @@ async function repairFlywayIfNeeded$1(issueId, pgContainer, dbName, projectConfi
|
|
|
538
543
|
}
|
|
539
544
|
}
|
|
540
545
|
try {
|
|
541
|
-
const { stdout } = await execAsync$
|
|
546
|
+
const { stdout } = await execAsync$9(`docker exec "${pgContainer}" psql -U postgres -d ${dbName} -t -A -c "SELECT count(*) FROM flyway_schema_history;"`, {
|
|
542
547
|
encoding: "utf-8",
|
|
543
548
|
timeout: 1e4
|
|
544
549
|
});
|
|
@@ -565,34 +570,34 @@ const flywayPostgresProvisioner = {
|
|
|
565
570
|
const logger = requireLogger(ctx.logger, "[refresh-db]");
|
|
566
571
|
logger.log(`Starting DB refresh for ${ctx.issueId}`);
|
|
567
572
|
try {
|
|
568
|
-
await execAsync$
|
|
573
|
+
await execAsync$9(`docker stop "${ctx.apiContainer}"`, {
|
|
569
574
|
encoding: "utf-8",
|
|
570
575
|
timeout: 3e4
|
|
571
576
|
});
|
|
572
577
|
} catch {
|
|
573
578
|
logger.log("API container not running or already stopped");
|
|
574
579
|
}
|
|
575
|
-
await execAsync$
|
|
580
|
+
await execAsync$9(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d postgres -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '${sqlString(ctx.databaseName)}' AND pid <> pg_backend_pid();"`, {
|
|
576
581
|
encoding: "utf-8",
|
|
577
582
|
timeout: 1e4
|
|
578
583
|
});
|
|
579
|
-
await execAsync$
|
|
584
|
+
await execAsync$9(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d postgres -c "DROP DATABASE IF EXISTS ${sqlIdentifier(ctx.databaseName)};"`, {
|
|
580
585
|
encoding: "utf-8",
|
|
581
586
|
timeout: 1e4
|
|
582
587
|
});
|
|
583
|
-
await execAsync$
|
|
588
|
+
await execAsync$9(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d postgres -c "CREATE DATABASE ${sqlIdentifier(ctx.databaseName)} OWNER postgres;"`, {
|
|
584
589
|
encoding: "utf-8",
|
|
585
590
|
timeout: 1e4
|
|
586
591
|
});
|
|
587
592
|
logger.log(`Loading seed file: ${ctx.seedFile}`);
|
|
588
|
-
await execAsync$
|
|
593
|
+
await execAsync$9(`docker exec -i ${shellQuote(ctx.pgContainer)} psql -U postgres -d ${shellQuote(ctx.databaseName)} < ${shellQuote(ctx.seedFile)}`, {
|
|
589
594
|
encoding: "utf-8",
|
|
590
595
|
timeout: 6e5
|
|
591
596
|
});
|
|
592
597
|
const repairResult = await repairFlywayIfNeeded$1(ctx.issueId, ctx.pgContainer, ctx.databaseName, ctx.projectConfig, ctx.workspacePath, (msg) => logger.log(msg));
|
|
593
598
|
logger.log(`Flyway setup: ${repairResult.message}`);
|
|
594
599
|
try {
|
|
595
|
-
await execAsync$
|
|
600
|
+
await execAsync$9(`docker start "${ctx.apiContainer}"`, {
|
|
596
601
|
encoding: "utf-8",
|
|
597
602
|
timeout: 3e4
|
|
598
603
|
});
|
|
@@ -601,7 +606,7 @@ const flywayPostgresProvisioner = {
|
|
|
601
606
|
}
|
|
602
607
|
let seedVerifyResult;
|
|
603
608
|
if (ctx.seedVerifyQuery) try {
|
|
604
|
-
const { stdout } = await execAsync$
|
|
609
|
+
const { stdout } = await execAsync$9(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d ${shellQuote(ctx.databaseName)} -t -A -c ${shellQuote(ctx.seedVerifyQuery)}`, {
|
|
605
610
|
encoding: "utf-8",
|
|
606
611
|
timeout: 1e4
|
|
607
612
|
});
|
|
@@ -614,7 +619,7 @@ const flywayPostgresProvisioner = {
|
|
|
614
619
|
const logger = requireLogger(ctx.logger, "[db-seed]");
|
|
615
620
|
logger.setText(`Finding database container ${ctx.pgContainer}...`);
|
|
616
621
|
try {
|
|
617
|
-
const { stdout } = await execAsync$
|
|
622
|
+
const { stdout } = await execAsync$9(`docker ps --filter "name=${ctx.pgContainer}" --format "{{.Names}}"`);
|
|
618
623
|
if (!stdout.trim()) {
|
|
619
624
|
logger.fail(`Database container not running: ${ctx.pgContainer}`);
|
|
620
625
|
logger.log("\nStart the workspace containers first:");
|
|
@@ -626,7 +631,7 @@ const flywayPostgresProvisioner = {
|
|
|
626
631
|
return;
|
|
627
632
|
}
|
|
628
633
|
if (!ctx.force) try {
|
|
629
|
-
const { stdout } = await execAsync$
|
|
634
|
+
const { stdout } = await execAsync$9(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d ${shellQuote(ctx.databaseName)} -c "SELECT count(*) FROM flyway_schema_history" -t 2>/dev/null`);
|
|
630
635
|
const count = parseInt(stdout.trim(), 10);
|
|
631
636
|
if (count > 0) {
|
|
632
637
|
logger.info(`Database already seeded (${count} migrations). Use --force to reseed.`);
|
|
@@ -636,16 +641,16 @@ const flywayPostgresProvisioner = {
|
|
|
636
641
|
if (ctx.force) {
|
|
637
642
|
logger.setText("Dropping existing database...");
|
|
638
643
|
try {
|
|
639
|
-
await execAsync$
|
|
644
|
+
await execAsync$9(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -c "DROP DATABASE IF EXISTS ${sqlIdentifier(ctx.databaseName)}; CREATE DATABASE ${sqlIdentifier(ctx.databaseName)};"`);
|
|
640
645
|
} catch (error) {
|
|
641
646
|
logger.warn(`Could not drop database: ${error instanceof Error ? error.message : String(error)}`);
|
|
642
647
|
}
|
|
643
648
|
}
|
|
644
649
|
logger.setText("Copying seed file to container...");
|
|
645
|
-
await execAsync$
|
|
650
|
+
await execAsync$9(`docker cp ${shellQuote(ctx.seedFile)} ${shellQuote(`${ctx.pgContainer}:/tmp/seed.sql`)}`);
|
|
646
651
|
logger.setText("Executing seed...");
|
|
647
652
|
try {
|
|
648
|
-
await execAsync$
|
|
653
|
+
await execAsync$9(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d ${shellQuote(ctx.databaseName)} -f /tmp/seed.sql`, { timeout: 6e5 });
|
|
649
654
|
} catch (error) {
|
|
650
655
|
const message = error instanceof Error ? error.message : String(error);
|
|
651
656
|
if (message.includes("ERROR")) {
|
|
@@ -653,10 +658,10 @@ const flywayPostgresProvisioner = {
|
|
|
653
658
|
return;
|
|
654
659
|
}
|
|
655
660
|
}
|
|
656
|
-
await execAsync$
|
|
661
|
+
await execAsync$9(`docker exec ${shellQuote(ctx.pgContainer)} rm /tmp/seed.sql`);
|
|
657
662
|
logger.succeed("Database seeded successfully");
|
|
658
663
|
try {
|
|
659
|
-
const { stdout } = await execAsync$
|
|
664
|
+
const { stdout } = await execAsync$9(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d ${shellQuote(ctx.databaseName)} -c "SELECT version, description FROM flyway_schema_history ORDER BY installed_rank DESC LIMIT 3" -t`);
|
|
660
665
|
logger.log("\nRecent migrations:");
|
|
661
666
|
stdout.trim().split("\n").forEach((line) => logger.log(` ${line.trim()}`));
|
|
662
667
|
} catch {}
|
|
@@ -675,7 +680,7 @@ const flywayPostgresProvisioner = {
|
|
|
675
680
|
if (!snapshotCmd) throw new DatabaseProvisionerError("No snapshot configuration found");
|
|
676
681
|
const fullCmd = `${snapshotCmd} > "${outputPath}" 2>&1`;
|
|
677
682
|
try {
|
|
678
|
-
await execAsync$
|
|
683
|
+
await execAsync$9(fullCmd, { timeout: 3e5 });
|
|
679
684
|
} catch (error) {
|
|
680
685
|
const message = error instanceof Error ? error.message : String(error);
|
|
681
686
|
if (existsSync$1(outputPath)) if (readFileSync$1(outputPath, "utf-8").includes("PostgreSQL database dump")) {
|
|
@@ -692,7 +697,7 @@ const flywayPostgresProvisioner = {
|
|
|
692
697
|
if (ctx.sanitize && ctx.dbConfig.seed_command) {
|
|
693
698
|
logger.setText("Running sanitization...");
|
|
694
699
|
try {
|
|
695
|
-
await execAsync$
|
|
700
|
+
await execAsync$9(ctx.dbConfig.seed_command, { cwd: ctx.projectConfig.path });
|
|
696
701
|
} catch (error) {
|
|
697
702
|
logger.warn(`Sanitization warning: ${error instanceof Error ? error.message : String(error)}`);
|
|
698
703
|
}
|
|
@@ -747,7 +752,7 @@ const flywayPostgresProvisioner = {
|
|
|
747
752
|
async status(ctx) {
|
|
748
753
|
const logger = requireLogger(ctx.logger, "[db-status]");
|
|
749
754
|
logger.setText(`Checking container ${ctx.pgContainer}...`);
|
|
750
|
-
const { stdout: containerStatus } = await execAsync$
|
|
755
|
+
const { stdout: containerStatus } = await execAsync$9(`docker ps --filter "name=${ctx.pgContainer}" --format "{{.Status}}"`);
|
|
751
756
|
if (!containerStatus.trim()) {
|
|
752
757
|
logger.fail(`Container not running: ${ctx.pgContainer}`);
|
|
753
758
|
return;
|
|
@@ -755,18 +760,18 @@ const flywayPostgresProvisioner = {
|
|
|
755
760
|
logger.succeed(`Container: ${ctx.pgContainer}`);
|
|
756
761
|
logger.log(` Status: ${containerStatus.trim()}`);
|
|
757
762
|
try {
|
|
758
|
-
const { stdout: version } = await execAsync$
|
|
763
|
+
const { stdout: version } = await execAsync$9(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d ${shellQuote(ctx.databaseName)} -c "SELECT version, description FROM flyway_schema_history ORDER BY installed_rank DESC LIMIT 1" -t`);
|
|
759
764
|
const [ver, desc] = version.trim().split("|").map((s) => s.trim());
|
|
760
765
|
logger.log(` Flyway: V${ver} - ${desc}`);
|
|
761
766
|
} catch {
|
|
762
767
|
logger.warn(" Flyway: Not initialized");
|
|
763
768
|
}
|
|
764
769
|
try {
|
|
765
|
-
const { stdout: tableCount } = await execAsync$
|
|
770
|
+
const { stdout: tableCount } = await execAsync$9(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d ${shellQuote(ctx.databaseName)} -c "SELECT count(*) FROM information_schema.tables WHERE table_schema = 'public'" -t`);
|
|
766
771
|
logger.log(` Tables: ${tableCount.trim()}`);
|
|
767
772
|
} catch {}
|
|
768
773
|
try {
|
|
769
|
-
const { stdout: dbSize } = await execAsync$
|
|
774
|
+
const { stdout: dbSize } = await execAsync$9(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d ${shellQuote(ctx.databaseName)} -c "SELECT pg_size_pretty(pg_database_size('${sqlString(ctx.databaseName)}'))" -t`);
|
|
770
775
|
logger.log(` Size: ${dbSize.trim()}`);
|
|
771
776
|
} catch {}
|
|
772
777
|
}
|
|
@@ -798,7 +803,7 @@ init_issue_id();
|
|
|
798
803
|
init_cli();
|
|
799
804
|
init_projects();
|
|
800
805
|
init_devcontainer_renderer();
|
|
801
|
-
const execAsync$
|
|
806
|
+
const execAsync$8 = promisify(exec);
|
|
802
807
|
function requireDatabaseName(dbConfig) {
|
|
803
808
|
if (!dbConfig) throw new Error("No database configuration found in projects.yaml");
|
|
804
809
|
const name = dbConfig.name?.trim();
|
|
@@ -814,7 +819,7 @@ const postWorkspaceContainerizeRoute = HttpRouter.add("POST", "/api/workspaces/:
|
|
|
814
819
|
const workspacePath = join(projectPath, "workspaces", `feature-${issueLower}`);
|
|
815
820
|
if (existsSync$1(join(workspacePath, ".devcontainer"))) return jsonResponse({ error: "Workspace is already containerized" }, { status: 400 });
|
|
816
821
|
try {
|
|
817
|
-
yield* Effect.promise(() => execAsync$
|
|
822
|
+
yield* Effect.promise(() => execAsync$8("docker info >/dev/null 2>&1", { encoding: "utf-8" }));
|
|
818
823
|
} catch {
|
|
819
824
|
return jsonResponse({ error: "Docker is not running. Start Docker Desktop first." }, { status: 400 });
|
|
820
825
|
}
|
|
@@ -931,7 +936,7 @@ const postWorkspaceContainerActionRoute = HttpRouter.add("POST", "/api/workspace
|
|
|
931
936
|
}
|
|
932
937
|
if (!workspacePath) return jsonResponse({ error: `Workspace not found for ${issueId}` }, { status: 404 });
|
|
933
938
|
if (!composeFile && ["start", "restart"].includes(action)) {
|
|
934
|
-
const { ensureDevcontainerSync } = yield* Effect.promise(() => import("./ensure-devcontainer-
|
|
939
|
+
const { ensureDevcontainerSync } = yield* Effect.promise(() => import("./ensure-devcontainer-DMAbWqtQ.js"));
|
|
935
940
|
if (ensureDevcontainerSync({
|
|
936
941
|
workspacePath,
|
|
937
942
|
issueId
|
|
@@ -948,7 +953,7 @@ const postWorkspaceContainerActionRoute = HttpRouter.add("POST", "/api/workspace
|
|
|
948
953
|
}
|
|
949
954
|
if (!composeFile) return jsonResponse({ error: `No docker-compose file found in workspace` }, { status: 404 });
|
|
950
955
|
try {
|
|
951
|
-
yield* Effect.promise(() => execAsync$
|
|
956
|
+
yield* Effect.promise(() => execAsync$8("docker info >/dev/null 2>&1", { encoding: "utf-8" }));
|
|
952
957
|
} catch {
|
|
953
958
|
return jsonResponse({ error: "Docker is not running. Start Docker Desktop first." }, { status: 400 });
|
|
954
959
|
}
|
|
@@ -962,7 +967,7 @@ const postWorkspaceContainerActionRoute = HttpRouter.add("POST", "/api/workspace
|
|
|
962
967
|
};
|
|
963
968
|
const serviceNames = serviceMap[containerName.toLowerCase()];
|
|
964
969
|
if (!serviceNames) return jsonResponse({ error: `Unknown container: ${containerName}. Valid: ${Object.keys(serviceMap).join(", ")}` }, { status: 400 });
|
|
965
|
-
const { stdout: projectNameOut } = yield* Effect.promise(() => execAsync$
|
|
970
|
+
const { stdout: projectNameOut } = yield* Effect.promise(() => execAsync$8(`docker compose -f "${composeFile}" config --format json 2>/dev/null | jq -r '.name // empty'`, { encoding: "utf-8" }));
|
|
966
971
|
const projectName = projectNameOut.trim();
|
|
967
972
|
if (containerName.toLowerCase() === "api" && ["start", "restart"].includes(action)) {
|
|
968
973
|
const tPrefix = extractTeamPrefix(issueId);
|
|
@@ -991,7 +996,7 @@ const postWorkspaceContainerActionRoute = HttpRouter.add("POST", "/api/workspace
|
|
|
991
996
|
for (const serviceName of serviceNames) try {
|
|
992
997
|
const cmd = `docker compose -f "${composeFile}" ${projectName ? `--project-name "${projectName}"` : ""} ${action} ${serviceName}`;
|
|
993
998
|
console.log(`[container-control] Running: ${cmd}`);
|
|
994
|
-
yield* Effect.promise(() => execAsync$
|
|
999
|
+
yield* Effect.promise(() => execAsync$8(cmd, {
|
|
995
1000
|
encoding: "utf-8",
|
|
996
1001
|
timeout: 3e4
|
|
997
1002
|
}));
|
|
@@ -1052,7 +1057,7 @@ const postWorkspaceRefreshDbRoute = HttpRouter.add("POST", "/api/workspaces/:iss
|
|
|
1052
1057
|
break;
|
|
1053
1058
|
}
|
|
1054
1059
|
if (!composeFile) return jsonResponse({ error: "No docker-compose file found in workspace" }, { status: 404 });
|
|
1055
|
-
const { stdout: projectNameOut } = yield* Effect.promise(() => execAsync$
|
|
1060
|
+
const { stdout: projectNameOut } = yield* Effect.promise(() => execAsync$8(`docker compose -f "${composeFile}" config --format json 2>/dev/null | jq -r '.name // empty'`, { encoding: "utf-8" }));
|
|
1056
1061
|
const projectName = projectNameOut.trim();
|
|
1057
1062
|
if (!projectName) return jsonResponse({ error: "Could not determine docker compose project name" }, { status: 500 });
|
|
1058
1063
|
const pgContainer = `${projectName}-postgres-1`;
|
|
@@ -1086,7 +1091,7 @@ const containerOpsRouteLayer = Layer.mergeAll(postWorkspaceContainerizeRoute, po
|
|
|
1086
1091
|
//#endregion
|
|
1087
1092
|
//#region ../../lib/stashes.ts
|
|
1088
1093
|
init_errors();
|
|
1089
|
-
const execAsync$
|
|
1094
|
+
const execAsync$7 = promisify(exec);
|
|
1090
1095
|
const ISO_STASH_TIMESTAMP_PATTERN = "(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2}))";
|
|
1091
1096
|
const ISSUE_ID_PATTERN = "([A-Z]+(?:-[A-Z]+)*-\\d+)";
|
|
1092
1097
|
const ISSUE_ID_REGEX = new RegExp(`^${ISSUE_ID_PATTERN}$`);
|
|
@@ -1162,16 +1167,22 @@ function parseStashListLine(line) {
|
|
|
1162
1167
|
};
|
|
1163
1168
|
}
|
|
1164
1169
|
async function listStashesPromise(repoPath) {
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1170
|
+
let stdout;
|
|
1171
|
+
try {
|
|
1172
|
+
({stdout} = await execAsync$7("git stash list --format=\"%gd%x09%H%x09%cI%x09%gs\"", {
|
|
1173
|
+
cwd: repoPath,
|
|
1174
|
+
encoding: "utf-8"
|
|
1175
|
+
}));
|
|
1176
|
+
} catch (error) {
|
|
1177
|
+
if ((error instanceof Error ? error.message : String(error)).includes("not a git repository")) return [];
|
|
1178
|
+
throw error;
|
|
1179
|
+
}
|
|
1169
1180
|
return stdout.split("\n").map((line) => parseStashListLine(line)).filter((entry) => entry !== null);
|
|
1170
1181
|
}
|
|
1171
1182
|
async function resolveStashOperationRef(repoPath, ref, stackRef) {
|
|
1172
1183
|
const candidateRef = /^stash@\{\d+\}$/.test(ref) ? ref : stackRef;
|
|
1173
1184
|
if (candidateRef) {
|
|
1174
|
-
const { stdout: resolvedSha } = await execAsync$
|
|
1185
|
+
const { stdout: resolvedSha } = await execAsync$7(`git rev-parse --verify ${JSON.stringify(candidateRef)}`, {
|
|
1175
1186
|
cwd: repoPath,
|
|
1176
1187
|
encoding: "utf-8"
|
|
1177
1188
|
});
|
|
@@ -1180,7 +1191,7 @@ async function resolveStashOperationRef(repoPath, ref, stackRef) {
|
|
|
1180
1191
|
}
|
|
1181
1192
|
const matchingEntry = (await Effect.runPromise(listStashes(repoPath))).find((entry) => entry.ref === ref);
|
|
1182
1193
|
if (!matchingEntry?.stackRef) throw new Error(`Stash ${ref} not found`);
|
|
1183
|
-
const { stdout: resolvedSha } = await execAsync$
|
|
1194
|
+
const { stdout: resolvedSha } = await execAsync$7(`git rev-parse --verify ${JSON.stringify(matchingEntry.stackRef)}`, {
|
|
1184
1195
|
cwd: repoPath,
|
|
1185
1196
|
encoding: "utf-8"
|
|
1186
1197
|
});
|
|
@@ -1189,7 +1200,7 @@ async function resolveStashOperationRef(repoPath, ref, stackRef) {
|
|
|
1189
1200
|
}
|
|
1190
1201
|
async function dropStashPromise(repoPath, ref, stackRef) {
|
|
1191
1202
|
const operationRef = await resolveStashOperationRef(repoPath, ref, stackRef);
|
|
1192
|
-
await execAsync$
|
|
1203
|
+
await execAsync$7(`git stash drop ${JSON.stringify(operationRef)}`, {
|
|
1193
1204
|
cwd: repoPath,
|
|
1194
1205
|
encoding: "utf-8"
|
|
1195
1206
|
});
|
|
@@ -1197,7 +1208,7 @@ async function dropStashPromise(repoPath, ref, stackRef) {
|
|
|
1197
1208
|
async function createRecoveryBranchFromStashPromise(repoPath, stashRef, issueId, shortDescription, stackRef) {
|
|
1198
1209
|
const operationRef = await resolveStashOperationRef(repoPath, stashRef, stackRef);
|
|
1199
1210
|
const branchName = `recovery/${validateIssueId(issueId)}-${sanitizeShortDescription(shortDescription)}`;
|
|
1200
|
-
await execAsync$
|
|
1211
|
+
await execAsync$7(`git branch ${JSON.stringify(branchName)} ${JSON.stringify(operationRef)}`, {
|
|
1201
1212
|
cwd: repoPath,
|
|
1202
1213
|
encoding: "utf-8"
|
|
1203
1214
|
});
|
|
@@ -2762,12 +2773,80 @@ const internalEventsRouteLayer = Layer.mergeAll(internalEventsRoute, internalEve
|
|
|
2762
2773
|
//#endregion
|
|
2763
2774
|
//#region routes/workspaces/merge-strike.ts
|
|
2764
2775
|
init_agents();
|
|
2776
|
+
init_agent_state();
|
|
2777
|
+
init_tmux();
|
|
2778
|
+
const execAsync$6 = promisify(exec);
|
|
2765
2779
|
function mergeVerificationOptions(request) {
|
|
2766
2780
|
return {
|
|
2767
2781
|
syncTargetBranch: false,
|
|
2768
2782
|
...request.kind === "strike" ? { skipPlanChecklist: true } : {}
|
|
2769
2783
|
};
|
|
2770
2784
|
}
|
|
2785
|
+
/**
|
|
2786
|
+
* PAN-3067: the PAN-2487 CI-green skip bypasses the verification runner — which
|
|
2787
|
+
* is what records verificationStatus on local runs — and that skip is the exact
|
|
2788
|
+
* path every strike merge takes (its CI is already green). Record the verdict
|
|
2789
|
+
* here so DoD row 3 has evidence and close-out can proceed.
|
|
2790
|
+
*/
|
|
2791
|
+
async function recordCiGreenVerificationVerdict(issueId, workspacePath) {
|
|
2792
|
+
try {
|
|
2793
|
+
const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-Xg4PFN45.js");
|
|
2794
|
+
const verifiedAnchor = await snapshotWorkspaceHeadsPromise(issueId, workspacePath).catch(() => void 0);
|
|
2795
|
+
const { setReviewStatusSync } = await import("./review-status-Dma9SFaN.js");
|
|
2796
|
+
setReviewStatusSync(issueId, {
|
|
2797
|
+
verificationStatus: "passed",
|
|
2798
|
+
verificationNotes: "merge-verify: CI green on the merged tip (PAN-2487 local-gate skip)",
|
|
2799
|
+
...verifiedAnchor ? { lastVerifiedCommit: verifiedAnchor } : {}
|
|
2800
|
+
});
|
|
2801
|
+
} catch (recordErr) {
|
|
2802
|
+
const message = recordErr instanceof Error ? recordErr.message : String(recordErr);
|
|
2803
|
+
console.warn(`[merge] Could not record CI-green verification verdict for ${issueId}: ${message}`);
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
/**
|
|
2807
|
+
* PAN-3120: resume the work agent for a merge-requested rebase and narrate it to
|
|
2808
|
+
* the operator (Awaiting Merge tracker + ship log), so a scheduler-yielded agent
|
|
2809
|
+
* shows as "Preparing work agent" rather than a silent step or a dead end.
|
|
2810
|
+
* Status writes go through the caller's `setStatus` to keep this module free of
|
|
2811
|
+
* the workspaces-route import cycle.
|
|
2812
|
+
*/
|
|
2813
|
+
async function prepareWorkAgentForRebase(opts) {
|
|
2814
|
+
const { appendShipLog } = await import("./ship-log-7kJfjUX2.js");
|
|
2815
|
+
opts.setStatus({
|
|
2816
|
+
mergeStep: "preparing-work-agent",
|
|
2817
|
+
mergeNotes: `Preparing work agent ${opts.agentId} to rebase ${opts.scopeNote}…`
|
|
2818
|
+
});
|
|
2819
|
+
appendShipLog(opts.issueId, `Preparing work agent ${opts.agentId} for rebase…`, "rebasing");
|
|
2820
|
+
try {
|
|
2821
|
+
const recovery = await ensureAgentReadyForMerge(opts.issueId, opts.workspacePath, opts.rebaseMsg, {
|
|
2822
|
+
agentId: opts.agentId,
|
|
2823
|
+
...opts.allowFreshStart === void 0 ? {} : { allowFreshStart: opts.allowFreshStart }
|
|
2824
|
+
});
|
|
2825
|
+
opts.setStatus({
|
|
2826
|
+
mergeStep: "rebasing",
|
|
2827
|
+
mergeNotes: `${recovery.detail} Waiting for ${opts.scopeNote} to be rebased and pushed.`
|
|
2828
|
+
});
|
|
2829
|
+
appendShipLog(opts.issueId, `✓ ${recovery.detail}`, "rebasing");
|
|
2830
|
+
console.log(`[merge] ${recovery.detail}`);
|
|
2831
|
+
return {
|
|
2832
|
+
ok: true,
|
|
2833
|
+
detail: recovery.detail
|
|
2834
|
+
};
|
|
2835
|
+
} catch (prepError) {
|
|
2836
|
+
const message = prepError instanceof Error ? prepError.message : String(prepError);
|
|
2837
|
+
const error = `Work agent ${opts.agentId} could not be prepared for the rebase: ${message}`;
|
|
2838
|
+
opts.setStatus(opts.deferFailureStatus ? { mergeNotes: error } : {
|
|
2839
|
+
mergeStatus: "failed",
|
|
2840
|
+
readyForMerge: false,
|
|
2841
|
+
mergeNotes: error
|
|
2842
|
+
});
|
|
2843
|
+
appendShipLog(opts.issueId, `✗ ${error}`, "rebasing");
|
|
2844
|
+
return {
|
|
2845
|
+
ok: false,
|
|
2846
|
+
error
|
|
2847
|
+
};
|
|
2848
|
+
}
|
|
2849
|
+
}
|
|
2771
2850
|
function parseStrikeMergeRequest(raw) {
|
|
2772
2851
|
if (!raw || typeof raw !== "object") return null;
|
|
2773
2852
|
const request = raw;
|
|
@@ -2830,23 +2909,55 @@ async function validateStrikeMergeRequest(issueId, request, status, deps) {
|
|
|
2830
2909
|
}
|
|
2831
2910
|
return null;
|
|
2832
2911
|
}
|
|
2912
|
+
/**
|
|
2913
|
+
* PAN-3120: clear whatever gate would stop THIS merge from reaching the work
|
|
2914
|
+
* agent. The preemptive scheduler yields idle work agents to free slots, so the
|
|
2915
|
+
* agent a merge needs is routinely paused by the system itself — and a paused
|
|
2916
|
+
* agent silently diverts `messageAgent` into a mail queue nothing drains, which
|
|
2917
|
+
* the merge then waits 30 minutes on. Returns a human-readable note when a gate
|
|
2918
|
+
* was cleared so the operator sees why the agent came back.
|
|
2919
|
+
*/
|
|
2920
|
+
async function clearMergePreparationGate(agentId) {
|
|
2921
|
+
const state = getAgentStateSync(agentId);
|
|
2922
|
+
if (!state) return null;
|
|
2923
|
+
const decision = decideResumeGate(getAgentResumeGateBlockReason(state), "merge-preparation");
|
|
2924
|
+
if (decision.decision === "block") throw new Error(decision.reason);
|
|
2925
|
+
if (decision.decision !== "proceed") return null;
|
|
2926
|
+
if (decision.clearYield) {
|
|
2927
|
+
clearYieldForResumeSync(agentId);
|
|
2928
|
+
return `cleared scheduler yield (${state.pausedReason ?? "yielded"})`;
|
|
2929
|
+
}
|
|
2930
|
+
if (decision.clearStoppedByUser) {
|
|
2931
|
+
delete state.stoppedByUser;
|
|
2932
|
+
saveAgentStateSync(state);
|
|
2933
|
+
return "cleared operator-stop gate for the requested merge";
|
|
2934
|
+
}
|
|
2935
|
+
return null;
|
|
2936
|
+
}
|
|
2937
|
+
/** A message diverted to the mail queue never reaches the agent — treat it as a failure, not a resume. */
|
|
2938
|
+
function assertDelivered(agentId, outcome) {
|
|
2939
|
+
if (outcome.delivered) return;
|
|
2940
|
+
throw new Error(`Merge preparation request for ${agentId} was not delivered${outcome.reason ? ` (${outcome.reason})` : ""}${outcome.queuedToMail ? " — it went to the mail queue, so no rebase would ever happen" : ""}.`);
|
|
2941
|
+
}
|
|
2833
2942
|
async function ensureAgentReadyForMerge(issueId, workspacePath, rebaseMsg, options) {
|
|
2834
2943
|
const agentId = options?.agentId ?? `agent-${issueId.toLowerCase()}`;
|
|
2944
|
+
const gateNote = await clearMergePreparationGate(agentId);
|
|
2945
|
+
const gateSuffix = gateNote ? ` (${gateNote})` : "";
|
|
2835
2946
|
const lifecycle = getWorkAgentLifecycleStateSync(agentId);
|
|
2836
2947
|
if (lifecycle.hasLiveTmuxSession) {
|
|
2837
|
-
await messageAgent(agentId, rebaseMsg);
|
|
2948
|
+
assertDelivered(agentId, await messageAgent(agentId, rebaseMsg));
|
|
2838
2949
|
return {
|
|
2839
2950
|
recovered: true,
|
|
2840
2951
|
agentId,
|
|
2841
|
-
detail:
|
|
2952
|
+
detail: `Work agent already running; sent merge preparation request${gateSuffix}.`
|
|
2842
2953
|
};
|
|
2843
2954
|
}
|
|
2844
2955
|
if (await Effect.runPromise(getAgentState(agentId))) try {
|
|
2845
|
-
await messageAgent(agentId, rebaseMsg);
|
|
2956
|
+
assertDelivered(agentId, await messageAgent(agentId, rebaseMsg));
|
|
2846
2957
|
return {
|
|
2847
2958
|
recovered: true,
|
|
2848
2959
|
agentId,
|
|
2849
|
-
detail: getWorkAgentLifecycleStateSync(agentId).canResumeSession ? "Resumed
|
|
2960
|
+
detail: `${getWorkAgentLifecycleStateSync(agentId).canResumeSession ? "Resumed" : "Restarted"} work agent and sent merge preparation request${gateSuffix}.`
|
|
2850
2961
|
};
|
|
2851
2962
|
} catch (error) {
|
|
2852
2963
|
if (!lifecycle.canStartFresh) throw error;
|
|
@@ -2859,10 +2970,102 @@ async function ensureAgentReadyForMerge(issueId, workspacePath, rebaseMsg, optio
|
|
|
2859
2970
|
issueId,
|
|
2860
2971
|
workspace: workspacePath,
|
|
2861
2972
|
role: "work",
|
|
2862
|
-
prompt: rebaseMsg
|
|
2973
|
+
prompt: rebaseMsg,
|
|
2974
|
+
startedBy: "merge-strike"
|
|
2863
2975
|
})).id} and sent merge preparation request.`
|
|
2864
2976
|
};
|
|
2865
2977
|
}
|
|
2978
|
+
async function rebaseWithAgentFallback(options) {
|
|
2979
|
+
const { issueId, workspacePath, branchName, targetBranch, agentId, rebaseMsg, allowFreshStart, setStatus } = options;
|
|
2980
|
+
let serverRebaseReason;
|
|
2981
|
+
let conflictFiles = [];
|
|
2982
|
+
if (existsSync$1(workspacePath)) try {
|
|
2983
|
+
const result = await Effect.runPromise(rebaseFeatureBranch(workspacePath, branchName, targetBranch, issueId));
|
|
2984
|
+
console.log(`[merge] Server-side rebase completed for ${issueId}`);
|
|
2985
|
+
return {
|
|
2986
|
+
success: true,
|
|
2987
|
+
newHead: result.newHead
|
|
2988
|
+
};
|
|
2989
|
+
} catch (error) {
|
|
2990
|
+
const detail = error;
|
|
2991
|
+
conflictFiles = Array.isArray(detail.conflictedFiles) ? detail.conflictedFiles.filter((file) => typeof file === "string") : [];
|
|
2992
|
+
const message = error instanceof Error ? error.message : typeof detail.message === "string" ? detail.message : void 0;
|
|
2993
|
+
serverRebaseReason = conflictFiles.length > 0 ? `Rebase conflicts in: ${conflictFiles.join(", ")}` : message || "Server-side rebase failed";
|
|
2994
|
+
console.warn(`[merge] ${serverRebaseReason} — escalating to the work agent for ${issueId}`);
|
|
2995
|
+
}
|
|
2996
|
+
try {
|
|
2997
|
+
const preparation = await prepareWorkAgentForRebase({
|
|
2998
|
+
issueId,
|
|
2999
|
+
workspacePath,
|
|
3000
|
+
agentId,
|
|
3001
|
+
rebaseMsg,
|
|
3002
|
+
allowFreshStart,
|
|
3003
|
+
scopeNote: branchName,
|
|
3004
|
+
setStatus,
|
|
3005
|
+
deferFailureStatus: true
|
|
3006
|
+
});
|
|
3007
|
+
if (!preparation.ok) throw new Error(preparation.error);
|
|
3008
|
+
const { stdout: headBefore } = await execAsync$6(`git rev-parse origin/${branchName} 2>/dev/null || echo NONE`, {
|
|
3009
|
+
cwd: workspacePath,
|
|
3010
|
+
encoding: "utf-8",
|
|
3011
|
+
timeout: 1e4
|
|
3012
|
+
});
|
|
3013
|
+
const timeoutMs = 1800 * 1e3;
|
|
3014
|
+
const startTime = Date.now();
|
|
3015
|
+
let newHead = null;
|
|
3016
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
3017
|
+
await new Promise((resolve) => setTimeout(resolve, 5e3));
|
|
3018
|
+
try {
|
|
3019
|
+
await execAsync$6("git fetch origin", {
|
|
3020
|
+
cwd: workspacePath,
|
|
3021
|
+
encoding: "utf-8",
|
|
3022
|
+
timeout: 15e3
|
|
3023
|
+
});
|
|
3024
|
+
const { stdout: headNow } = await execAsync$6(`git rev-parse origin/${branchName}`, {
|
|
3025
|
+
cwd: workspacePath,
|
|
3026
|
+
encoding: "utf-8",
|
|
3027
|
+
timeout: 5e3
|
|
3028
|
+
});
|
|
3029
|
+
if (headNow.trim() !== headBefore.trim()) {
|
|
3030
|
+
newHead = headNow.trim();
|
|
3031
|
+
console.log(`[merge] Work agent pushed rebased branch for ${issueId} (new HEAD: ${newHead.slice(0, 8)})`);
|
|
3032
|
+
break;
|
|
3033
|
+
}
|
|
3034
|
+
} catch {}
|
|
3035
|
+
if (!await Effect.runPromise(sessionExists(agentId))) {
|
|
3036
|
+
console.log(`[merge] Work agent ${agentId} stopped during rebase`);
|
|
3037
|
+
break;
|
|
3038
|
+
}
|
|
3039
|
+
}
|
|
3040
|
+
if (newHead) return {
|
|
3041
|
+
success: true,
|
|
3042
|
+
newHead
|
|
3043
|
+
};
|
|
3044
|
+
if (!await Effect.runPromise(sessionExists(agentId))) {
|
|
3045
|
+
const agentReason = `Work agent ${agentId} stopped before completing the rebase onto ${targetBranch}`;
|
|
3046
|
+
return {
|
|
3047
|
+
success: false,
|
|
3048
|
+
reason: serverRebaseReason ? `${serverRebaseReason}; ${agentReason}` : agentReason,
|
|
3049
|
+
conflictFiles,
|
|
3050
|
+
retryable: conflictFiles.length === 0
|
|
3051
|
+
};
|
|
3052
|
+
}
|
|
3053
|
+
return {
|
|
3054
|
+
success: false,
|
|
3055
|
+
reason: `Work agent did not push the rebased branch within ${timeoutMs / 6e4} minutes`,
|
|
3056
|
+
conflictFiles,
|
|
3057
|
+
retryable: conflictFiles.length === 0
|
|
3058
|
+
};
|
|
3059
|
+
} catch (error) {
|
|
3060
|
+
const agentReason = error instanceof Error ? error.message : `Work agent ${agentId} could not be prepared for merge`;
|
|
3061
|
+
return {
|
|
3062
|
+
success: false,
|
|
3063
|
+
reason: serverRebaseReason ? `${serverRebaseReason}; ${agentReason}` : agentReason,
|
|
3064
|
+
conflictFiles,
|
|
3065
|
+
retryable: conflictFiles.length === 0
|
|
3066
|
+
};
|
|
3067
|
+
}
|
|
3068
|
+
}
|
|
2866
3069
|
//#endregion
|
|
2867
3070
|
//#region routes/workspaces/internal-strike-merge.ts
|
|
2868
3071
|
init_issue_id();
|
|
@@ -2916,6 +3119,7 @@ function internalStrikeMergeRoute(triggerMerge) {
|
|
|
2916
3119
|
* stay owned by ../workspaces.js and are imported here.
|
|
2917
3120
|
*/
|
|
2918
3121
|
init_merge_agent();
|
|
3122
|
+
init_merge_verification();
|
|
2919
3123
|
init_operations();
|
|
2920
3124
|
init_git_activity();
|
|
2921
3125
|
init_issue_id();
|
|
@@ -2928,7 +3132,7 @@ init_tracker_utils();
|
|
|
2928
3132
|
init_tmux();
|
|
2929
3133
|
init_domain_services();
|
|
2930
3134
|
const execAsync$5 = promisify(exec);
|
|
2931
|
-
const execFileAsync$
|
|
3135
|
+
const execFileAsync$4 = promisify(execFile);
|
|
2932
3136
|
const shouldBlockApproveForDirtyStatus = (status) => status.trim() !== "" && !isStatePlaneOnlyStatus(status);
|
|
2933
3137
|
/**
|
|
2934
3138
|
* Check whether origin/branchName already contains origin/targetBranch.
|
|
@@ -2936,7 +3140,7 @@ const shouldBlockApproveForDirtyStatus = (status) => status.trim() !== "" && !is
|
|
|
2936
3140
|
*/
|
|
2937
3141
|
async function isBranchAlreadyRebased(workspacePath, branchName, targetBranch) {
|
|
2938
3142
|
try {
|
|
2939
|
-
await Promise.all([execFileAsync$
|
|
3143
|
+
await Promise.all([execFileAsync$4("git", [
|
|
2940
3144
|
"fetch",
|
|
2941
3145
|
"origin",
|
|
2942
3146
|
targetBranch
|
|
@@ -2944,7 +3148,7 @@ async function isBranchAlreadyRebased(workspacePath, branchName, targetBranch) {
|
|
|
2944
3148
|
cwd: workspacePath,
|
|
2945
3149
|
encoding: "utf-8",
|
|
2946
3150
|
timeout: 15e3
|
|
2947
|
-
}), execFileAsync$
|
|
3151
|
+
}), execFileAsync$4("git", [
|
|
2948
3152
|
"fetch",
|
|
2949
3153
|
"origin",
|
|
2950
3154
|
branchName
|
|
@@ -2953,7 +3157,7 @@ async function isBranchAlreadyRebased(workspacePath, branchName, targetBranch) {
|
|
|
2953
3157
|
encoding: "utf-8",
|
|
2954
3158
|
timeout: 15e3
|
|
2955
3159
|
})]);
|
|
2956
|
-
await execFileAsync$
|
|
3160
|
+
await execFileAsync$4("git", [
|
|
2957
3161
|
"merge-base",
|
|
2958
3162
|
"--is-ancestor",
|
|
2959
3163
|
`origin/${targetBranch}`,
|
|
@@ -2963,7 +3167,7 @@ async function isBranchAlreadyRebased(workspacePath, branchName, targetBranch) {
|
|
|
2963
3167
|
encoding: "utf-8",
|
|
2964
3168
|
timeout: 5e3
|
|
2965
3169
|
});
|
|
2966
|
-
const { stdout: currentHead } = await execFileAsync$
|
|
3170
|
+
const { stdout: currentHead } = await execFileAsync$4("git", ["rev-parse", `origin/${branchName}`], {
|
|
2967
3171
|
cwd: workspacePath,
|
|
2968
3172
|
encoding: "utf-8",
|
|
2969
3173
|
timeout: 5e3
|
|
@@ -2972,7 +3176,8 @@ async function isBranchAlreadyRebased(workspacePath, branchName, targetBranch) {
|
|
|
2972
3176
|
alreadyRebased: true,
|
|
2973
3177
|
currentHead: currentHead.trim()
|
|
2974
3178
|
};
|
|
2975
|
-
} catch {
|
|
3179
|
+
} catch (error) {
|
|
3180
|
+
console.warn(`[merge] Could not determine whether ${branchName} contains origin/${targetBranch}: ${error instanceof Error ? error.message : String(error)}`);
|
|
2976
3181
|
return { alreadyRebased: false };
|
|
2977
3182
|
}
|
|
2978
3183
|
}
|
|
@@ -2991,7 +3196,7 @@ async function reconcileGitHubMergeStatus(issueId, status) {
|
|
|
2991
3196
|
const prRef = parseGitHubPullRequestUrl(status.prUrl);
|
|
2992
3197
|
if (!prRef) return false;
|
|
2993
3198
|
try {
|
|
2994
|
-
const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-
|
|
3199
|
+
const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-Bmg4R9mv.js");
|
|
2995
3200
|
if (!isGitHubAppConfigured()) return false;
|
|
2996
3201
|
const prState = await Effect.runPromise(getPullRequestState(prRef.owner, prRef.repo, prRef.number));
|
|
2997
3202
|
console.log(`[merge] reconcileGitHubMergeStatus: ${issueId} PR #${prRef.number} merged=${prState.merged} state=${prState.state}`);
|
|
@@ -3043,7 +3248,7 @@ async function ensurePRExists(issueId, options) {
|
|
|
3043
3248
|
if (options?.cwd) execOptions.cwd = options.cwd;
|
|
3044
3249
|
let existingOut = "";
|
|
3045
3250
|
try {
|
|
3046
|
-
const { stdout } = await execFileAsync$
|
|
3251
|
+
const { stdout } = await execFileAsync$4("gh", [
|
|
3047
3252
|
"pr",
|
|
3048
3253
|
"view",
|
|
3049
3254
|
branchName,
|
|
@@ -3066,7 +3271,7 @@ async function ensurePRExists(issueId, options) {
|
|
|
3066
3271
|
const bodyFile = pathJoin(tmpdir(), `pan-pr-body-${issueId}-${Date.now()}.md`);
|
|
3067
3272
|
await writeFileAsync(bodyFile, prBody, "utf-8");
|
|
3068
3273
|
try {
|
|
3069
|
-
const { stdout: rawOut } = await execFileAsync$
|
|
3274
|
+
const { stdout: rawOut } = await execFileAsync$4("gh", [
|
|
3070
3275
|
"pr",
|
|
3071
3276
|
"create",
|
|
3072
3277
|
"--head",
|
|
@@ -3137,20 +3342,23 @@ const postWorkspaceSyncMainRoute = HttpRouter.add("POST", "/api/issues/:issueId/
|
|
|
3137
3342
|
if (result.alreadyUpToDate) return jsonResponse({
|
|
3138
3343
|
success: true,
|
|
3139
3344
|
alreadyUpToDate: true,
|
|
3140
|
-
message: "Already up to date with main"
|
|
3345
|
+
message: "Already up to date with main",
|
|
3346
|
+
repos: result.repos
|
|
3141
3347
|
});
|
|
3142
3348
|
return jsonResponse({
|
|
3143
3349
|
success: true,
|
|
3144
3350
|
commitCount: result.commitCount || 0,
|
|
3145
3351
|
changedFiles: result.changedFiles || [],
|
|
3146
|
-
message: `Synced ${result.commitCount || 0} commit(s) from main
|
|
3352
|
+
message: `Synced ${result.commitCount || 0} commit(s) from main`,
|
|
3353
|
+
repos: result.repos
|
|
3147
3354
|
});
|
|
3148
3355
|
} else {
|
|
3149
3356
|
const status = result.reason?.includes("uncommitted") ? 400 : 500;
|
|
3150
3357
|
return jsonResponse({
|
|
3151
3358
|
success: false,
|
|
3152
3359
|
error: result.reason || "Sync failed",
|
|
3153
|
-
conflictFiles: result.conflictFiles
|
|
3360
|
+
conflictFiles: result.conflictFiles,
|
|
3361
|
+
repos: result.repos
|
|
3154
3362
|
}, { status });
|
|
3155
3363
|
}
|
|
3156
3364
|
})));
|
|
@@ -3180,7 +3388,7 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
3180
3388
|
};
|
|
3181
3389
|
const strikeError = await validateStrikeMergeRequest(issueId, request, reviewStatus, {
|
|
3182
3390
|
projectPath: getProjectPath(void 0, extractPrefixSync(issueId) ?? issueId.split("-")[0]),
|
|
3183
|
-
git: async (args, cwd) => (await execFileAsync$
|
|
3391
|
+
git: async (args, cwd) => (await execFileAsync$4("git", args, {
|
|
3184
3392
|
cwd,
|
|
3185
3393
|
encoding: "utf-8"
|
|
3186
3394
|
})).stdout.trim()
|
|
@@ -3248,7 +3456,7 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
3248
3456
|
const normalizedMergeId = issueId.toUpperCase();
|
|
3249
3457
|
_serverManagedMerges.add(normalizedMergeId);
|
|
3250
3458
|
setPendingOperation(issueId, "merge");
|
|
3251
|
-
let queueAdvanced = false;
|
|
3459
|
+
let queueAdvanced = false, preserveQueue = false;
|
|
3252
3460
|
const advanceQueue = () => {
|
|
3253
3461
|
if (queueAdvanced) return;
|
|
3254
3462
|
queueAdvanced = true;
|
|
@@ -3258,8 +3466,8 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
3258
3466
|
try {
|
|
3259
3467
|
if (request.kind === "normal" && workspaceInfo.isRemote && workspaceInfo.vmName) {
|
|
3260
3468
|
console.log(`[merge] Remote workspace detected for ${issueId}, using review artifact merge...`);
|
|
3261
|
-
const { getMergeSetSync, ensureMergeSetForIssueSync } = await import("./merge-set-
|
|
3262
|
-
const { getForgeAdapter } = await import("./forge-
|
|
3469
|
+
const { getMergeSetSync, ensureMergeSetForIssueSync } = await import("./merge-set-DeUxFsC3.js");
|
|
3470
|
+
const { getForgeAdapter } = await import("./forge-B5o319qI.js");
|
|
3263
3471
|
const remotePrimaryRepo = (getMergeSetSync(issueId) || ensureMergeSetForIssueSync(issueId))?.repos[0];
|
|
3264
3472
|
const remoteTargetBranch = remotePrimaryRepo?.targetBranch || "main";
|
|
3265
3473
|
const remoteForge = remotePrimaryRepo?.forge || "github";
|
|
@@ -3295,7 +3503,7 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
3295
3503
|
...mergeCompletionStatus(request)
|
|
3296
3504
|
});
|
|
3297
3505
|
completePendingOperation(issueId, null);
|
|
3298
|
-
const { postMergeLifecycle } = await import("./merge-agent-
|
|
3506
|
+
const { postMergeLifecycle } = await import("./merge-agent-DQTXZk8z.js");
|
|
3299
3507
|
await postMergeLifecycle(issueId, projectPath);
|
|
3300
3508
|
return {
|
|
3301
3509
|
success: true,
|
|
@@ -3321,21 +3529,30 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
3321
3529
|
};
|
|
3322
3530
|
}
|
|
3323
3531
|
}
|
|
3532
|
+
const projectConfig = findProjectByTeamSync(issuePrefix);
|
|
3533
|
+
const isPolyrepo = projectConfig?.workspace?.type === "polyrepo";
|
|
3324
3534
|
if (!existsSync$1(workspacePath)) {
|
|
3325
|
-
|
|
3535
|
+
const error = "Workspace does not exist";
|
|
3536
|
+
const retryable = request.kind === "normal" && !workspaceInfo.isRemote && !isPolyrepo;
|
|
3537
|
+
if (retryable) setReviewStatus(issueId, {
|
|
3538
|
+
mergeStatus: "queued",
|
|
3539
|
+
mergeNotes: error
|
|
3540
|
+
});
|
|
3541
|
+
completePendingOperation(issueId, error);
|
|
3326
3542
|
return {
|
|
3327
3543
|
success: false,
|
|
3328
|
-
statusCode: 400,
|
|
3329
|
-
error
|
|
3544
|
+
statusCode: retryable ? 500 : 400,
|
|
3545
|
+
error,
|
|
3546
|
+
...retryable ? { retryable: true } : {}
|
|
3330
3547
|
};
|
|
3331
3548
|
}
|
|
3332
|
-
|
|
3333
|
-
if (projectConfig?.workspace?.type === "polyrepo" && projectConfig?.workspace?.repos) {
|
|
3549
|
+
if (isPolyrepo && projectConfig?.workspace?.repos) {
|
|
3334
3550
|
console.log(`[merge] Polyrepo detected for ${issueId}, coordinating merge set...`);
|
|
3335
|
-
const { getMergeSetSync, ensureMergeSetForIssueSync, upsertMergeSetSync, withRepoStateSync } = await import("./merge-set-
|
|
3336
|
-
const { runQualityGates } = await import("./validation-
|
|
3337
|
-
const {
|
|
3338
|
-
const {
|
|
3551
|
+
const { getMergeSetSync, ensureMergeSetForIssueSync, upsertMergeSetSync, withRepoStateSync } = await import("./merge-set-DeUxFsC3.js");
|
|
3552
|
+
const { runQualityGates } = await import("./validation-hVOwQk8T.js");
|
|
3553
|
+
const { reconcileStrandedRepos } = await import("./merge-completeness-BLbB5-6n.js");
|
|
3554
|
+
const { getForgeAdapter } = await import("./forge-B5o319qI.js");
|
|
3555
|
+
const { messageAgent } = await import("./agents-ePFVoZbu.js");
|
|
3339
3556
|
let mergeSet = getMergeSetSync(issueId) || ensureMergeSetForIssueSync(issueId);
|
|
3340
3557
|
if (!mergeSet) {
|
|
3341
3558
|
const error = `No merge set found for ${issueId}`;
|
|
@@ -3351,21 +3568,59 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
3351
3568
|
error
|
|
3352
3569
|
};
|
|
3353
3570
|
}
|
|
3354
|
-
const
|
|
3355
|
-
|
|
3356
|
-
|
|
3571
|
+
const reconciliation = await reconcileStrandedRepos(mergeSet);
|
|
3572
|
+
mergeSet = reconciliation.mergeSet;
|
|
3573
|
+
if (reconciliation.blockers.length > 0) {
|
|
3574
|
+
const error = reconciliation.blockers.map((blocker) => blocker.reason).join("; ");
|
|
3575
|
+
mergeSet = {
|
|
3576
|
+
...mergeSet,
|
|
3577
|
+
status: "failed",
|
|
3578
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3579
|
+
};
|
|
3580
|
+
upsertMergeSetSync(mergeSet);
|
|
3357
3581
|
setReviewStatus(issueId, {
|
|
3358
3582
|
mergeStatus: "failed",
|
|
3359
3583
|
readyForMerge: false,
|
|
3360
|
-
mergeNotes: error
|
|
3584
|
+
mergeNotes: error,
|
|
3585
|
+
blockerReasons: reconciliation.blockers.map((blocker) => ({
|
|
3586
|
+
type: "unmerged_sibling_repo",
|
|
3587
|
+
summary: blocker.reason,
|
|
3588
|
+
detectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3589
|
+
}))
|
|
3361
3590
|
});
|
|
3362
3591
|
completePendingOperation(issueId, error);
|
|
3363
3592
|
return {
|
|
3364
3593
|
success: false,
|
|
3365
|
-
statusCode:
|
|
3594
|
+
statusCode: 409,
|
|
3366
3595
|
error
|
|
3367
3596
|
};
|
|
3368
3597
|
}
|
|
3598
|
+
const activeRepos = mergeSet.repos.filter((repo) => repo.mergeStatus !== "skipped" && repo.mergeStatus !== "merged" && !!repo.artifactUrl).sort((a, b) => a.mergeOrder - b.mergeOrder);
|
|
3599
|
+
if (activeRepos.length === 0) {
|
|
3600
|
+
mergeSet = {
|
|
3601
|
+
...mergeSet,
|
|
3602
|
+
status: "merged",
|
|
3603
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3604
|
+
};
|
|
3605
|
+
upsertMergeSetSync(mergeSet);
|
|
3606
|
+
setReviewStatus(issueId, {
|
|
3607
|
+
mergeStatus: "merged",
|
|
3608
|
+
mergeNotes: void 0,
|
|
3609
|
+
readyForMerge: false,
|
|
3610
|
+
...mergeCompletionStatus(request)
|
|
3611
|
+
});
|
|
3612
|
+
completePendingOperation(issueId, null);
|
|
3613
|
+
const { postMergeLifecycle } = await import("./merge-agent-DQTXZk8z.js");
|
|
3614
|
+
advanceQueue();
|
|
3615
|
+
await postMergeLifecycle(issueId, projectPath);
|
|
3616
|
+
return {
|
|
3617
|
+
success: true,
|
|
3618
|
+
statusCode: 200,
|
|
3619
|
+
message: `No changed repos remain for ${issueId}`,
|
|
3620
|
+
mergeStatus: "merged",
|
|
3621
|
+
repos: []
|
|
3622
|
+
};
|
|
3623
|
+
}
|
|
3369
3624
|
const agentId = `agent-${issueId.toLowerCase()}`;
|
|
3370
3625
|
mergeSet = {
|
|
3371
3626
|
...mergeSet,
|
|
@@ -3428,21 +3683,24 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
3428
3683
|
};
|
|
3429
3684
|
}
|
|
3430
3685
|
const reposNeedingRebase = activeRepos.filter((repo) => !alreadyRebased.has(repo.repoKey));
|
|
3431
|
-
if (reposNeedingRebase.length > 0
|
|
3432
|
-
const
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3686
|
+
if (reposNeedingRebase.length > 0) {
|
|
3687
|
+
const prep = await prepareWorkAgentForRebase({
|
|
3688
|
+
issueId,
|
|
3689
|
+
workspacePath,
|
|
3690
|
+
agentId,
|
|
3691
|
+
rebaseMsg: `MERGE REQUESTED: The human has clicked MERGE for ${issueId}. Rebase and push every affected repo in this merge set:\n\n${reposNeedingRebase.map((repo, index) => `${index + 1}. cd ${repo.repoKey}\n git fetch origin ${repo.targetBranch}\n git rebase origin/${repo.targetBranch}\n git push --force-with-lease`).join("\n")}\n\nResolve any conflicts in the workspaces above, complete every rebase, and push all affected branches. Do NOT merge PRs/MRs yourself.`,
|
|
3692
|
+
scopeNote: `${reposNeedingRebase.length} repo(s)`,
|
|
3693
|
+
setStatus: (u) => setReviewStatus(issueId, u)
|
|
3437
3694
|
});
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3695
|
+
if (!prep.ok) {
|
|
3696
|
+
completePendingOperation(issueId, prep.error);
|
|
3697
|
+
return {
|
|
3698
|
+
success: false,
|
|
3699
|
+
statusCode: 400,
|
|
3700
|
+
error: prep.error
|
|
3701
|
+
};
|
|
3702
|
+
}
|
|
3444
3703
|
}
|
|
3445
|
-
if (reposNeedingRebase.length > 0) await messageAgent(agentId, `MERGE REQUESTED: The human has clicked MERGE for ${issueId}. Rebase and push every affected repo in this merge set:\n\n${reposNeedingRebase.map((repo, index) => `${index + 1}. cd ${repo.repoKey}\n git fetch origin ${repo.targetBranch}\n git rebase origin/${repo.targetBranch}\n git push --force-with-lease`).join("\n")}\n\nResolve any conflicts in the workspaces above, complete every rebase, and push all affected branches. Do NOT merge PRs/MRs yourself.`);
|
|
3446
3704
|
const REBASE_TIMEOUT_MS = 1800 * 1e3;
|
|
3447
3705
|
const POLL_INTERVAL_MS = 5e3;
|
|
3448
3706
|
const pushedRepos = new Set(alreadyRebased);
|
|
@@ -3606,7 +3864,7 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
3606
3864
|
...mergeCompletionStatus(request)
|
|
3607
3865
|
});
|
|
3608
3866
|
completePendingOperation(issueId, null);
|
|
3609
|
-
const { postMergeLifecycle } = await import("./merge-agent-
|
|
3867
|
+
const { postMergeLifecycle } = await import("./merge-agent-DQTXZk8z.js");
|
|
3610
3868
|
advanceQueue();
|
|
3611
3869
|
await postMergeLifecycle(issueId, projectPath);
|
|
3612
3870
|
return {
|
|
@@ -3617,8 +3875,8 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
3617
3875
|
repos: mergeResults
|
|
3618
3876
|
};
|
|
3619
3877
|
}
|
|
3620
|
-
const { getMergeSetSync, ensureMergeSetForIssueSync } = await import("./merge-set-
|
|
3621
|
-
const { getForgeAdapter } = await import("./forge-
|
|
3878
|
+
const { getMergeSetSync, ensureMergeSetForIssueSync } = await import("./merge-set-DeUxFsC3.js");
|
|
3879
|
+
const { getForgeAdapter } = await import("./forge-B5o319qI.js");
|
|
3622
3880
|
const primaryRepo = (getMergeSetSync(issueId) || ensureMergeSetForIssueSync(issueId))?.repos[0];
|
|
3623
3881
|
const targetBranch = primaryRepo?.targetBranch || "main";
|
|
3624
3882
|
const primaryForge = primaryRepo?.forge || "github";
|
|
@@ -3659,10 +3917,12 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
3659
3917
|
error
|
|
3660
3918
|
};
|
|
3661
3919
|
}
|
|
3920
|
+
let preMergePrState;
|
|
3662
3921
|
if (githubPrRef) try {
|
|
3663
|
-
const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-
|
|
3922
|
+
const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-Bmg4R9mv.js");
|
|
3664
3923
|
if (isGitHubAppConfigured()) {
|
|
3665
3924
|
const prState = await Effect.runPromise(getPullRequestState(githubPrRef.owner, githubPrRef.repo, githubPrRef.number));
|
|
3925
|
+
preMergePrState = prState;
|
|
3666
3926
|
if (prState.state !== "OPEN" && !prState.merged) {
|
|
3667
3927
|
const error = `PR #${githubPrRef.number} is ${prState.state} (not OPEN). Overdeck state is out of sync — likely a cancel-flow left a stale prUrl. Re-open the work agent to create a fresh PR, or reset review state.`;
|
|
3668
3928
|
console.error(`[merge] ${error}`);
|
|
@@ -3722,7 +3982,7 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
3722
3982
|
...mergeCompletionStatus(request)
|
|
3723
3983
|
});
|
|
3724
3984
|
completePendingOperation(issueId, null);
|
|
3725
|
-
const { postMergeLifecycle } = await import("./merge-agent-
|
|
3985
|
+
const { postMergeLifecycle } = await import("./merge-agent-DQTXZk8z.js");
|
|
3726
3986
|
await postMergeLifecycle(issueId, projectPath, branchName);
|
|
3727
3987
|
return {
|
|
3728
3988
|
success: true,
|
|
@@ -3736,83 +3996,56 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
3736
3996
|
} catch (prStateErr) {
|
|
3737
3997
|
console.warn(`[merge] Pre-merge PR state check failed for ${issueId}: ${prStateErr.message} — proceeding (check is best-effort)`);
|
|
3738
3998
|
}
|
|
3739
|
-
const { postMergeLifecycle } = await import("./merge-agent-
|
|
3740
|
-
const
|
|
3741
|
-
const rebaseMsg = request.kind === "strike" ? `STRIKE LANDING REQUEST: Rebase ${branchName} onto ${targetBranch}, resolve conflicts, run the full quality gates, push ${branchName}, then run pan strike-ready ${issueId} to persist the new HEAD. Do NOT merge or push main.` : `MERGE REQUESTED: The human has clicked MERGE for ${issueId}. Please rebase onto ${targetBranch} and push:\n\n1. git fetch origin ${targetBranch}\n2. git rebase origin/${targetBranch}\n3. If conflicts: resolve them, git add, git rebase --continue\n4. git push --force-with-lease\n\nAfter pushing, the server will handle verification and merge automatically. Do NOT run gh pr merge yourself.`;
|
|
3742
|
-
setReviewStatus(issueId, { mergeStep: "rebasing" });
|
|
3743
|
-
console.log(`[merge] Rebasing ${branchName} onto ${targetBranch} for ${issueId} (agent=${await Effect.runPromise(sessionExists(agentId)) ? "running" : "stopped"})...`);
|
|
3744
|
-
{
|
|
3745
|
-
const { beginShipLog, appendShipLog } = await import("./ship-log-D9MlVzYU.js");
|
|
3746
|
-
beginShipLog(issueId);
|
|
3747
|
-
appendShipLog(issueId, `Ship started: rebasing ${branchName} onto ${targetBranch}…`, "rebasing");
|
|
3748
|
-
}
|
|
3999
|
+
const { postMergeLifecycle } = await import("./merge-agent-DQTXZk8z.js");
|
|
4000
|
+
const { beginShipLog, appendShipLog } = await import("./ship-log-7kJfjUX2.js");
|
|
3749
4001
|
let rebaseResult;
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
console.log(`[merge] ${branchName} already contains origin/${targetBranch} — skipping rebase request for ${issueId}`);
|
|
4002
|
+
if (preMergePrState?.mergeable === true && preMergePrState.mergeableState === "clean" && !preMergePrState.checksFailed && !preMergePrState.checksPending && !preMergePrState.draft && !preMergePrState.merged) {
|
|
4003
|
+
console.log(`[merge] PR is CLEAN — merging directly without rebase for ${issueId}`);
|
|
3753
4004
|
rebaseResult = {
|
|
3754
4005
|
success: true,
|
|
3755
|
-
newHead:
|
|
4006
|
+
newHead: preMergePrState.headSha
|
|
3756
4007
|
};
|
|
3757
|
-
} else
|
|
3758
|
-
const
|
|
4008
|
+
} else {
|
|
4009
|
+
const agentId = request.kind === "strike" ? request.recoveryTarget : `agent-${issueId.toLowerCase()}`;
|
|
4010
|
+
const rebaseMsg = request.kind === "strike" ? `STRIKE LANDING REQUEST: Rebase ${branchName} onto ${targetBranch}, resolve conflicts, run the full quality gates, push ${branchName}, then run pan strike-ready ${issueId} to persist the new HEAD. Do NOT merge or push main.` : `MERGE REQUESTED: The human has clicked MERGE for ${issueId}. Please rebase onto ${targetBranch} and push:\n\n1. git fetch origin ${targetBranch}\n2. git rebase origin/${targetBranch}\n3. If conflicts: resolve them, git add, git rebase --continue\n4. git push --force-with-lease\n\nAfter pushing, the server will handle verification and merge automatically. Do NOT run gh pr merge yourself.`;
|
|
4011
|
+
setReviewStatus(issueId, { mergeStep: "rebasing" });
|
|
4012
|
+
console.log(`[merge] Rebasing ${branchName} onto ${targetBranch} for ${issueId} (agent=${await Effect.runPromise(sessionExists(agentId)) ? "running" : "stopped"})...`);
|
|
4013
|
+
beginShipLog(issueId);
|
|
4014
|
+
appendShipLog(issueId, `Ship started: rebasing ${branchName} onto ${targetBranch}…`, "rebasing");
|
|
4015
|
+
const { alreadyRebased, currentHead } = await isBranchAlreadyRebased(workspacePath, branchName, targetBranch);
|
|
4016
|
+
if (alreadyRebased && currentHead) {
|
|
4017
|
+
console.log(`[merge] ${branchName} already contains origin/${targetBranch} — skipping rebase request for ${issueId}`);
|
|
4018
|
+
rebaseResult = {
|
|
4019
|
+
success: true,
|
|
4020
|
+
newHead: currentHead
|
|
4021
|
+
};
|
|
4022
|
+
} else rebaseResult = await rebaseWithAgentFallback({
|
|
4023
|
+
issueId,
|
|
4024
|
+
workspacePath,
|
|
4025
|
+
branchName,
|
|
4026
|
+
targetBranch,
|
|
3759
4027
|
agentId,
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
const { stdout: headBefore } = await execAsync$5(`git rev-parse origin/${branchName} 2>/dev/null || echo NONE`, {
|
|
3764
|
-
cwd: workspacePath,
|
|
3765
|
-
encoding: "utf-8",
|
|
3766
|
-
timeout: 1e4
|
|
4028
|
+
rebaseMsg,
|
|
4029
|
+
allowFreshStart: request.kind !== "strike",
|
|
4030
|
+
setStatus: (update) => setReviewStatus(issueId, update)
|
|
3767
4031
|
});
|
|
3768
|
-
const REBASE_TIMEOUT_MS = 1800 * 1e3;
|
|
3769
|
-
const POLL_INTERVAL_MS = 5e3;
|
|
3770
|
-
const startTime = Date.now();
|
|
3771
|
-
let newHead = null;
|
|
3772
|
-
while (Date.now() - startTime < REBASE_TIMEOUT_MS) {
|
|
3773
|
-
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
3774
|
-
try {
|
|
3775
|
-
await execAsync$5("git fetch origin", {
|
|
3776
|
-
cwd: workspacePath,
|
|
3777
|
-
encoding: "utf-8",
|
|
3778
|
-
timeout: 15e3
|
|
3779
|
-
});
|
|
3780
|
-
const { stdout: headNow } = await execAsync$5(`git rev-parse origin/${branchName}`, {
|
|
3781
|
-
cwd: workspacePath,
|
|
3782
|
-
encoding: "utf-8",
|
|
3783
|
-
timeout: 5e3
|
|
3784
|
-
});
|
|
3785
|
-
if (headNow.trim() !== headBefore.trim()) {
|
|
3786
|
-
newHead = headNow.trim();
|
|
3787
|
-
console.log(`[merge] Work agent pushed rebased branch for ${issueId} (new HEAD: ${newHead.slice(0, 8)})`);
|
|
3788
|
-
break;
|
|
3789
|
-
}
|
|
3790
|
-
} catch {}
|
|
3791
|
-
if (!await Effect.runPromise(sessionExists(agentId))) {
|
|
3792
|
-
console.log(`[merge] Work agent ${agentId} stopped during rebase`);
|
|
3793
|
-
break;
|
|
3794
|
-
}
|
|
3795
|
-
}
|
|
3796
|
-
if (newHead) rebaseResult = {
|
|
3797
|
-
success: true,
|
|
3798
|
-
newHead
|
|
3799
|
-
};
|
|
3800
|
-
else if (!await Effect.runPromise(sessionExists(agentId))) rebaseResult = {
|
|
3801
|
-
success: false,
|
|
3802
|
-
reason: `Work agent ${agentId} stopped before completing the rebase onto ${targetBranch}`
|
|
3803
|
-
};
|
|
3804
|
-
else rebaseResult = {
|
|
3805
|
-
success: false,
|
|
3806
|
-
reason: `Work agent did not push the rebased branch within ${REBASE_TIMEOUT_MS / 6e4} minutes`
|
|
3807
|
-
};
|
|
3808
|
-
} catch (recoveryErr) {
|
|
3809
|
-
rebaseResult = {
|
|
3810
|
-
success: false,
|
|
3811
|
-
reason: recoveryErr.message || `Work agent ${agentId} could not be prepared for merge`
|
|
3812
|
-
};
|
|
3813
4032
|
}
|
|
4033
|
+
if (!rebaseResult) throw new Error(`Rebase escalation produced no result for ${issueId}`);
|
|
3814
4034
|
if (!rebaseResult.success) {
|
|
3815
4035
|
const error = rebaseResult.reason || "Rebase failed";
|
|
4036
|
+
if (rebaseResult.retryable) {
|
|
4037
|
+
setReviewStatus(issueId, {
|
|
4038
|
+
mergeStatus: "queued",
|
|
4039
|
+
mergeNotes: error
|
|
4040
|
+
});
|
|
4041
|
+
completePendingOperation(issueId, error);
|
|
4042
|
+
return {
|
|
4043
|
+
success: false,
|
|
4044
|
+
statusCode: 500,
|
|
4045
|
+
error,
|
|
4046
|
+
retryable: true
|
|
4047
|
+
};
|
|
4048
|
+
}
|
|
3816
4049
|
setReviewStatus(issueId, {
|
|
3817
4050
|
mergeStatus: "failed",
|
|
3818
4051
|
mergeNotes: error,
|
|
@@ -3873,7 +4106,7 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
3873
4106
|
});
|
|
3874
4107
|
let skipLocalVerification = false;
|
|
3875
4108
|
if (primaryForge === "github" && artifactUrl) try {
|
|
3876
|
-
const { parsePullRequestRef, getCiCheckRunsStatePromise, isGitHubAppConfigured } = await import("./github-app-
|
|
4109
|
+
const { parsePullRequestRef, getCiCheckRunsStatePromise, isGitHubAppConfigured } = await import("./github-app-Bmg4R9mv.js");
|
|
3877
4110
|
if (isGitHubAppConfigured()) {
|
|
3878
4111
|
const ref = parsePullRequestRef({ url: artifactUrl });
|
|
3879
4112
|
if (ref) {
|
|
@@ -3894,17 +4127,27 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
3894
4127
|
} catch (ciErr) {
|
|
3895
4128
|
console.warn(`[merge] CI-state check failed (${ciErr.message?.slice(0, 120)}) — falling back to local verification for ${issueId}`);
|
|
3896
4129
|
}
|
|
3897
|
-
const { appendShipLog } = await import("./ship-log-D9MlVzYU.js");
|
|
3898
4130
|
if (skipLocalVerification) appendShipLog(issueId, "✓ Local verification skipped — CI already green on this exact commit", "verifying");
|
|
3899
4131
|
const verifyResult = skipLocalVerification ? { outcome: "passed" } : await (async () => {
|
|
3900
4132
|
console.log(`[merge] Running post-rebase verification for ${issueId}...`);
|
|
3901
4133
|
appendShipLog(issueId, "Running post-rebase verification (full quality-gate suite)…", "verifying");
|
|
3902
|
-
const { runVerificationForIssue } = await import("./verification-runner-
|
|
4134
|
+
const { runVerificationForIssue } = await import("./verification-runner-Bc3cJvpC.js");
|
|
3903
4135
|
return Effect.runPromise(runVerificationForIssue(issueId, workspacePath, { isRemote: false }, "merge-verify", {
|
|
3904
4136
|
...mergeVerificationOptions(request),
|
|
3905
4137
|
onGateLog: (line) => appendShipLog(issueId, line, "verifying")
|
|
3906
4138
|
}));
|
|
3907
4139
|
})();
|
|
4140
|
+
const verificationDeferral = handlePostRebaseVerificationDeferral(issueId, verifyResult, reviewStatus, {
|
|
4141
|
+
appendShipLog,
|
|
4142
|
+
setReviewStatus,
|
|
4143
|
+
completePendingOperation
|
|
4144
|
+
});
|
|
4145
|
+
if (verificationDeferral) {
|
|
4146
|
+
markMergeProcessing(projectKey, normalizedId, false);
|
|
4147
|
+
_serverManagedMerges.delete(normalizedMergeId);
|
|
4148
|
+
preserveQueue = true;
|
|
4149
|
+
return verificationDeferral;
|
|
4150
|
+
}
|
|
3908
4151
|
if (verifyResult.outcome === "failed") {
|
|
3909
4152
|
const error = `Post-rebase verification failed at ${verifyResult.failedCheck}`;
|
|
3910
4153
|
console.log(`[merge] ${error}`);
|
|
@@ -3930,9 +4173,10 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
3930
4173
|
};
|
|
3931
4174
|
}
|
|
3932
4175
|
console.log(`[merge] Post-rebase verification ${verifyResult.outcome} for ${issueId}`);
|
|
4176
|
+
if (skipLocalVerification) await recordCiGreenVerificationVerdict(issueId, workspacePath);
|
|
3933
4177
|
setReviewStatus(issueId, { mergeStep: "reporting-statuses" });
|
|
3934
4178
|
try {
|
|
3935
|
-
const { getPullRequestState, isGitHubAppConfigured, reportCommitStatus } = await import("./github-app-
|
|
4179
|
+
const { getPullRequestState, isGitHubAppConfigured, reportCommitStatus } = await import("./github-app-Bmg4R9mv.js");
|
|
3936
4180
|
if (githubPrRef && isGitHubAppConfigured()) {
|
|
3937
4181
|
const sha = (await Effect.runPromise(getPullRequestState(githubPrRef.owner, githubPrRef.repo, githubPrRef.number))).headSha.trim();
|
|
3938
4182
|
if (sha) {
|
|
@@ -3960,7 +4204,7 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
3960
4204
|
} catch (prMergeErr) {
|
|
3961
4205
|
console.error(`[merge] Review artifact merge threw for ${issueId}:`, prMergeErr);
|
|
3962
4206
|
try {
|
|
3963
|
-
const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-
|
|
4207
|
+
const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-Bmg4R9mv.js");
|
|
3964
4208
|
if (githubPrRef && isGitHubAppConfigured()) {
|
|
3965
4209
|
artifactMerged = (await Effect.runPromise(getPullRequestState(githubPrRef.owner, githubPrRef.repo, githubPrRef.number))).merged;
|
|
3966
4210
|
if (artifactMerged) console.log(`[merge] Race-detected: PR #${githubPrRef.number} for ${issueId} was already merged despite thrown error; proceeding`);
|
|
@@ -4055,7 +4299,7 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
|
|
|
4055
4299
|
error: error.message
|
|
4056
4300
|
};
|
|
4057
4301
|
} finally {
|
|
4058
|
-
advanceQueue();
|
|
4302
|
+
if (!preserveQueue) advanceQueue();
|
|
4059
4303
|
}
|
|
4060
4304
|
}
|
|
4061
4305
|
setMergeQueueTriggerHandler(triggerMerge);
|
|
@@ -4079,8 +4323,8 @@ const postForgeApproveRoute = HttpRouter.add("POST", "/api/issues/:issueId/forge
|
|
|
4079
4323
|
if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
4080
4324
|
if (!/^[A-Z]+-\d+$/i.test(issueId)) return jsonResponse({ error: "Invalid issue ID format" }, { status: 400 });
|
|
4081
4325
|
return yield* Effect.promise(async () => {
|
|
4082
|
-
const { getMergeSetSync, upsertMergeSetSync, withRepoArtifactUrlSync, withRepoStateSync } = await import("./merge-set-
|
|
4083
|
-
const { getForgeAdapter } = await import("./forge-
|
|
4326
|
+
const { getMergeSetSync, upsertMergeSetSync, withRepoArtifactUrlSync, withRepoStateSync } = await import("./merge-set-DeUxFsC3.js");
|
|
4327
|
+
const { getForgeAdapter } = await import("./forge-B5o319qI.js");
|
|
4084
4328
|
let mergeSet = getMergeSetSync(issueId);
|
|
4085
4329
|
if (!mergeSet) return jsonResponse({ error: `No merge set found for ${issueId}` }, { status: 404 });
|
|
4086
4330
|
const results = [];
|
|
@@ -4141,7 +4385,7 @@ const postForgeApproveRoute = HttpRouter.add("POST", "/api/issues/:issueId/forge
|
|
|
4141
4385
|
}
|
|
4142
4386
|
}
|
|
4143
4387
|
if (results.filter((r) => r.approved).length > 0) {
|
|
4144
|
-
const { emitActivityEntrySync, emitActivityTtsSync } = await import("./activity-logger-
|
|
4388
|
+
const { emitActivityEntrySync, emitActivityTtsSync } = await import("./activity-logger-CMthG6Vd.js");
|
|
4145
4389
|
emitActivityEntrySync({
|
|
4146
4390
|
source: "dashboard",
|
|
4147
4391
|
level: "success",
|
|
@@ -4168,8 +4412,9 @@ const postForgeMergeRoute = HttpRouter.add("POST", "/api/issues/:issueId/forge-m
|
|
|
4168
4412
|
if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
4169
4413
|
if (!/^[A-Z]+-\d+$/i.test(issueId)) return jsonResponse({ error: "Invalid issue ID format" }, { status: 400 });
|
|
4170
4414
|
return yield* Effect.promise(async () => {
|
|
4171
|
-
const { getMergeSetSync, upsertMergeSetSync, withRepoArtifactUrlSync, withRepoStateSync } = await import("./merge-set-
|
|
4172
|
-
const { getForgeAdapter } = await import("./forge-
|
|
4415
|
+
const { getMergeSetSync, upsertMergeSetSync, withRepoArtifactUrlSync, withRepoStateSync } = await import("./merge-set-DeUxFsC3.js");
|
|
4416
|
+
const { getForgeAdapter } = await import("./forge-B5o319qI.js");
|
|
4417
|
+
const { assessRepoMergeCompleteness } = await import("./merge-completeness-BLbB5-6n.js");
|
|
4173
4418
|
let mergeSet = getMergeSetSync(issueId);
|
|
4174
4419
|
if (!mergeSet) return jsonResponse({ error: `No merge set found for ${issueId}` }, { status: 404 });
|
|
4175
4420
|
const results = [];
|
|
@@ -4185,34 +4430,44 @@ const postForgeMergeRoute = HttpRouter.add("POST", "/api/issues/:issueId/forge-m
|
|
|
4185
4430
|
const workspacePath = mergeSet.workspaceType === "polyrepo" ? join(mergeSet.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`, repo.repoKey) : join(mergeSet.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
|
|
4186
4431
|
let artifactUrl = repo.artifactUrl;
|
|
4187
4432
|
let artifactId = repo.artifactId;
|
|
4188
|
-
if (!artifactUrl && !artifactId)
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
artifactUrl = discovered
|
|
4195
|
-
artifactId = discovered
|
|
4433
|
+
if (!artifactUrl && !artifactId) {
|
|
4434
|
+
try {
|
|
4435
|
+
const discovered = await adapter.discoverArtifact({
|
|
4436
|
+
sourceBranch: repo.sourceBranch,
|
|
4437
|
+
cwd: existsSync$1(workspacePath) ? workspacePath : repo.repoPath
|
|
4438
|
+
});
|
|
4439
|
+
artifactUrl = discovered?.url;
|
|
4440
|
+
artifactId = discovered?.id;
|
|
4441
|
+
} catch {}
|
|
4442
|
+
if (artifactUrl || artifactId) {
|
|
4196
4443
|
mergeSet = withRepoArtifactUrlSync(mergeSet, repo.repoKey, artifactUrl ?? "", artifactId);
|
|
4197
4444
|
upsertMergeSetSync(mergeSet);
|
|
4198
4445
|
console.log(`[forge-merge] Discovered artifact for ${issueId}/${repo.repoKey}: ${artifactUrl}`);
|
|
4199
4446
|
} else {
|
|
4200
|
-
|
|
4447
|
+
const classification = await assessRepoMergeCompleteness(repo);
|
|
4448
|
+
if (classification.state === "merged") {
|
|
4449
|
+
mergeSet = withRepoStateSync(mergeSet, repo.repoKey, { mergeStatus: "merged" });
|
|
4450
|
+
results.push({
|
|
4451
|
+
repoKey: repo.repoKey,
|
|
4452
|
+
merged: true
|
|
4453
|
+
});
|
|
4454
|
+
} else if (classification.state === "no-changes") {
|
|
4455
|
+
mergeSet = withRepoStateSync(mergeSet, repo.repoKey, { mergeStatus: "skipped" });
|
|
4456
|
+
results.push({
|
|
4457
|
+
repoKey: repo.repoKey,
|
|
4458
|
+
merged: true
|
|
4459
|
+
});
|
|
4460
|
+
} else {
|
|
4461
|
+
mergeSet = withRepoStateSync(mergeSet, repo.repoKey, { mergeStatus: "blocked" });
|
|
4462
|
+
results.push({
|
|
4463
|
+
repoKey: repo.repoKey,
|
|
4464
|
+
merged: false,
|
|
4465
|
+
error: classification.reason
|
|
4466
|
+
});
|
|
4467
|
+
}
|
|
4201
4468
|
upsertMergeSetSync(mergeSet);
|
|
4202
|
-
results.push({
|
|
4203
|
-
repoKey: repo.repoKey,
|
|
4204
|
-
merged: true
|
|
4205
|
-
});
|
|
4206
4469
|
continue;
|
|
4207
4470
|
}
|
|
4208
|
-
} catch {
|
|
4209
|
-
mergeSet = withRepoStateSync(mergeSet, repo.repoKey, { mergeStatus: "skipped" });
|
|
4210
|
-
upsertMergeSetSync(mergeSet);
|
|
4211
|
-
results.push({
|
|
4212
|
-
repoKey: repo.repoKey,
|
|
4213
|
-
merged: true
|
|
4214
|
-
});
|
|
4215
|
-
continue;
|
|
4216
4471
|
}
|
|
4217
4472
|
try {
|
|
4218
4473
|
await adapter.mergeReviewArtifact({
|
|
@@ -4237,7 +4492,7 @@ const postForgeMergeRoute = HttpRouter.add("POST", "/api/issues/:issueId/forge-m
|
|
|
4237
4492
|
}
|
|
4238
4493
|
}
|
|
4239
4494
|
if (results.filter((r) => r.merged).length > 0) {
|
|
4240
|
-
const { emitActivityEntrySync, emitActivityTtsSync } = await import("./activity-logger-
|
|
4495
|
+
const { emitActivityEntrySync, emitActivityTtsSync } = await import("./activity-logger-CMthG6Vd.js");
|
|
4241
4496
|
emitActivityEntrySync({
|
|
4242
4497
|
source: "dashboard",
|
|
4243
4498
|
level: "success",
|
|
@@ -4362,7 +4617,7 @@ const postWorkspaceApproveRoute = HttpRouter.add("POST", "/api/issues/:issueId/a
|
|
|
4362
4617
|
console.log(`[approve] Starting role pipeline for ${issueId}...`);
|
|
4363
4618
|
let reviewResult;
|
|
4364
4619
|
try {
|
|
4365
|
-
const { spawnReviewRoleForIssue } = await import("./review-agent-
|
|
4620
|
+
const { spawnReviewRoleForIssue } = await import("./review-agent-BTCNkq2h.js");
|
|
4366
4621
|
reviewResult = await Effect.runPromise(spawnReviewRoleForIssue({
|
|
4367
4622
|
issueId,
|
|
4368
4623
|
workspace: workspacePath,
|
|
@@ -4409,7 +4664,7 @@ const postWorkspaceApproveRoute = HttpRouter.add("POST", "/api/issues/:issueId/a
|
|
|
4409
4664
|
}
|
|
4410
4665
|
console.log(`[approve] Step 3/3: Running server-side rebase for ${issueId}...`);
|
|
4411
4666
|
try {
|
|
4412
|
-
const { rebaseFeatureBranch } = await import("./merge-rebase-
|
|
4667
|
+
const { rebaseFeatureBranch } = await import("./merge-rebase-CJJVAJuz.js");
|
|
4413
4668
|
const workspacePathForRebase = join(projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
|
|
4414
4669
|
const rebaseResult = await Effect.runPromise(rebaseFeatureBranch(workspacePathForRebase, branchName, "main", issueId));
|
|
4415
4670
|
if (!rebaseResult.success) {
|
|
@@ -4429,7 +4684,7 @@ const postWorkspaceApproveRoute = HttpRouter.add("POST", "/api/issues/:issueId/a
|
|
|
4429
4684
|
completePendingOperation(issueId, pushResult.error);
|
|
4430
4685
|
return jsonResponse({ error: pushResult.error }, { status: pushResult.httpStatus });
|
|
4431
4686
|
}
|
|
4432
|
-
const { approve: lifecycleApprove } = await import("./lifecycle-
|
|
4687
|
+
const { approve: lifecycleApprove } = await import("./lifecycle-B3s4sM1G.js");
|
|
4433
4688
|
const ghResolved = resolveGitHubIssueSync(issueId);
|
|
4434
4689
|
const isGitHubIssueFlag = ghResolved.isGitHub;
|
|
4435
4690
|
const lifecycleCtx = {
|
|
@@ -4463,7 +4718,7 @@ const getMergeQueueRoute = HttpRouter.add("GET", "/api/merge-queue", httpHandler
|
|
|
4463
4718
|
})));
|
|
4464
4719
|
const postInternalPipelineNotifyRoute = HttpRouter.add("POST", "/api/internal/pipeline/notify", httpHandler(Effect.gen(function* () {
|
|
4465
4720
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
4466
|
-
const { INTERNAL_TOKEN_HEADER, getInternalTokenSync } = yield* Effect.promise(() => import("./internal-token-
|
|
4721
|
+
const { INTERNAL_TOKEN_HEADER, getInternalTokenSync } = yield* Effect.promise(() => import("./internal-token-Ias7N8Kg.js"));
|
|
4467
4722
|
const expected = getInternalTokenSync();
|
|
4468
4723
|
if (!expected) return jsonResponse({
|
|
4469
4724
|
ok: false,
|
|
@@ -4477,7 +4732,7 @@ const postInternalPipelineNotifyRoute = HttpRouter.add("POST", "/api/internal/pi
|
|
|
4477
4732
|
}, 403);
|
|
4478
4733
|
const event = yield* readJsonBody;
|
|
4479
4734
|
const type = event.type;
|
|
4480
|
-
const { notifyPipelineSync } = yield* Effect.promise(() => import("./pipeline-notifier-
|
|
4735
|
+
const { notifyPipelineSync } = yield* Effect.promise(() => import("./pipeline-notifier-DT6xLFao.js"));
|
|
4481
4736
|
switch (type) {
|
|
4482
4737
|
case "status_changed": {
|
|
4483
4738
|
const issueId = event.issueId;
|
|
@@ -4645,7 +4900,7 @@ init_types$1();
|
|
|
4645
4900
|
init_review_context();
|
|
4646
4901
|
init_tldr_daemon();
|
|
4647
4902
|
const execAsync$4 = promisify(exec);
|
|
4648
|
-
const execFileAsync$
|
|
4903
|
+
const execFileAsync$3 = promisify(execFile);
|
|
4649
4904
|
function getWorkspaceLocation(issueId) {
|
|
4650
4905
|
try {
|
|
4651
4906
|
const meta = loadWorkspaceMetadataSync(issueId);
|
|
@@ -4704,7 +4959,7 @@ async function getRepoGitStatusAsync(workspacePath) {
|
|
|
4704
4959
|
}
|
|
4705
4960
|
async function getMrUrlAsync(issueId, workspacePath) {
|
|
4706
4961
|
try {
|
|
4707
|
-
const { stdout } = await execFileAsync$
|
|
4962
|
+
const { stdout } = await execFileAsync$3("gh", [
|
|
4708
4963
|
"pr",
|
|
4709
4964
|
"view",
|
|
4710
4965
|
`feature/${issueId.toLowerCase()}`,
|
|
@@ -5252,7 +5507,7 @@ const patchWorkspaceTieredExecutionRoute = HttpRouter.add("PATCH", "/api/workspa
|
|
|
5252
5507
|
if (override !== "on" && override !== "off" && override !== null && override !== void 0) return jsonResponse({ error: "Invalid tiered-execution override" }, { status: 400 });
|
|
5253
5508
|
const project = getProjectSync(extractPrefixSync(issueId) ?? issueId.split("-")[0]);
|
|
5254
5509
|
if (!project) return jsonResponse({ error: "Project not found" }, { status: 404 });
|
|
5255
|
-
yield* Effect.promise(() => import("./record-
|
|
5510
|
+
yield* Effect.promise(() => import("./record-BTwWhtBb.js").then((m) => m.writeRecordTieredExecutionOverride(project, issueId, override)));
|
|
5256
5511
|
const projectPath = project.path;
|
|
5257
5512
|
const location = yield* resolvePlanLocation(projectPath, issueId);
|
|
5258
5513
|
if (!location) return jsonResponse({ error: "No xBRIEF plan found for this workspace" }, { status: 404 });
|
|
@@ -5540,6 +5795,48 @@ const postWorkspaceCleanRoute = HttpRouter.add("POST", "/api/workspaces/:issueId
|
|
|
5540
5795
|
})));
|
|
5541
5796
|
const stashCleanRouteLayer = Layer.mergeAll(getWorkspaceStashesRoute, postWorkspaceRecoverStashRoute, deleteWorkspaceStashRoute, getWorkspaceCleanPreviewRoute, postWorkspaceCleanRoute);
|
|
5542
5797
|
//#endregion
|
|
5798
|
+
//#region ../../lib/cloister/review-branch-push.ts
|
|
5799
|
+
init_project_repos();
|
|
5800
|
+
const execFileAsync$2 = promisify(execFile);
|
|
5801
|
+
const REVIEW_PUSH_TIMEOUT_MS = 3e4;
|
|
5802
|
+
async function runReviewGit(args, options) {
|
|
5803
|
+
await execFileAsync$2("git", args, options);
|
|
5804
|
+
}
|
|
5805
|
+
function reviewGitOptions(cwd) {
|
|
5806
|
+
return {
|
|
5807
|
+
cwd,
|
|
5808
|
+
timeout: REVIEW_PUSH_TIMEOUT_MS,
|
|
5809
|
+
killSignal: "SIGKILL",
|
|
5810
|
+
env: {
|
|
5811
|
+
...process.env,
|
|
5812
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
5813
|
+
GIT_ASKPASS: "true",
|
|
5814
|
+
SSH_ASKPASS: "true"
|
|
5815
|
+
}
|
|
5816
|
+
};
|
|
5817
|
+
}
|
|
5818
|
+
async function pushLocalReviewBranches(issueId, workspacePath, dependencies = {}) {
|
|
5819
|
+
const roots = (dependencies.resolveRoots ?? resolveWorkspaceRepoRootsSync)(issueId, workspacePath);
|
|
5820
|
+
const runGit = dependencies.runGit ?? runReviewGit;
|
|
5821
|
+
for (const root of roots) {
|
|
5822
|
+
try {
|
|
5823
|
+
await runGit([
|
|
5824
|
+
"rev-parse",
|
|
5825
|
+
"--verify",
|
|
5826
|
+
"--quiet",
|
|
5827
|
+
`refs/heads/${root.sourceBranch}`
|
|
5828
|
+
], reviewGitOptions(root.dir));
|
|
5829
|
+
} catch {
|
|
5830
|
+
continue;
|
|
5831
|
+
}
|
|
5832
|
+
await runGit([
|
|
5833
|
+
"push",
|
|
5834
|
+
"origin",
|
|
5835
|
+
root.sourceBranch
|
|
5836
|
+
], reviewGitOptions(root.dir));
|
|
5837
|
+
}
|
|
5838
|
+
}
|
|
5839
|
+
//#endregion
|
|
5543
5840
|
//#region ../../lib/cloister/request-review-pipeline.ts
|
|
5544
5841
|
init_in_flight_guard();
|
|
5545
5842
|
/**
|
|
@@ -5560,6 +5857,10 @@ function createRequestReviewPipeline() {
|
|
|
5560
5857
|
await deps.onVerificationError(outcome);
|
|
5561
5858
|
return;
|
|
5562
5859
|
}
|
|
5860
|
+
if (outcome.outcome === "deferred") {
|
|
5861
|
+
await deps.onVerificationDeferred?.(outcome);
|
|
5862
|
+
return;
|
|
5863
|
+
}
|
|
5563
5864
|
await deps.pushBranch();
|
|
5564
5865
|
await deps.dispatchReview();
|
|
5565
5866
|
}, deps.onError);
|
|
@@ -5569,6 +5870,92 @@ function createRequestReviewPipeline() {
|
|
|
5569
5870
|
}
|
|
5570
5871
|
};
|
|
5571
5872
|
}
|
|
5873
|
+
/** Shared host-side pipeline so HTTP requests and durable intent recovery coalesce. */
|
|
5874
|
+
const requestReviewPipeline = createRequestReviewPipeline();
|
|
5875
|
+
//#endregion
|
|
5876
|
+
//#region services/durable-review-pipeline.ts
|
|
5877
|
+
init_durable_review_pipeline();
|
|
5878
|
+
init_projects();
|
|
5879
|
+
async function startDashboardDurableReviewPipeline(input, dependencies) {
|
|
5880
|
+
const { issueId, prUrl, setReviewPending, dispatchReview } = input;
|
|
5881
|
+
const resolved = dependencies.resolveWorkspace(issueId);
|
|
5882
|
+
if (!resolved) return false;
|
|
5883
|
+
const { workspacePath, workspaceInfo, branchName } = resolved;
|
|
5884
|
+
return requestReviewPipeline.start(issueId, {
|
|
5885
|
+
verify: () => dependencies.verify ? dependencies.verify(issueId, workspacePath, workspaceInfo) : Effect.runPromise(runVerificationForIssue(issueId, workspacePath, workspaceInfo, "durable-review")),
|
|
5886
|
+
onVerificationFailed: (outcome) => {
|
|
5887
|
+
setReviewPending({
|
|
5888
|
+
reviewStatus: "pending",
|
|
5889
|
+
reviewNotes: `Verification failed at ${outcome.failedCheck} — fix and resubmit`
|
|
5890
|
+
});
|
|
5891
|
+
},
|
|
5892
|
+
onVerificationError: (outcome) => {
|
|
5893
|
+
setReviewPending({
|
|
5894
|
+
reviewStatus: "pending",
|
|
5895
|
+
reviewNotes: `Verification infrastructure error: ${outcome.message}`
|
|
5896
|
+
});
|
|
5897
|
+
},
|
|
5898
|
+
onVerificationDeferred: (outcome) => {
|
|
5899
|
+
setReviewPending({
|
|
5900
|
+
reviewStatus: "pending",
|
|
5901
|
+
reviewNotes: outcome.reason
|
|
5902
|
+
});
|
|
5903
|
+
console.log(`[review-status] durable review verification deferred for ${issueId}: ${outcome.reason}`);
|
|
5904
|
+
},
|
|
5905
|
+
pushBranch: () => dependencies.pushBranch(resolved),
|
|
5906
|
+
dispatchReview: async () => {
|
|
5907
|
+
const result = await dispatchReview({
|
|
5908
|
+
issueId,
|
|
5909
|
+
workspace: workspacePath,
|
|
5910
|
+
branch: branchName,
|
|
5911
|
+
...prUrl ? { prUrl } : {}
|
|
5912
|
+
});
|
|
5913
|
+
if (!result.success) {
|
|
5914
|
+
setReviewPending({
|
|
5915
|
+
reviewStatus: "pending",
|
|
5916
|
+
reviewNotes: result.error || result.message || "Failed to dispatch review"
|
|
5917
|
+
});
|
|
5918
|
+
return;
|
|
5919
|
+
}
|
|
5920
|
+
const message = result.message?.startsWith("Review already in progress") ? "already in progress — no-op" : "auto-dispatched from durable journal intent";
|
|
5921
|
+
console.log(`[review-status] review dispatch for ${issueId}: ${message} (host-side)`);
|
|
5922
|
+
},
|
|
5923
|
+
onError: (error) => {
|
|
5924
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
5925
|
+
setReviewPending({
|
|
5926
|
+
reviewStatus: "pending",
|
|
5927
|
+
reviewNotes: `Review pipeline error: ${detail}`
|
|
5928
|
+
});
|
|
5929
|
+
console.warn(`[review-status] host-side durable review pipeline for ${issueId} failed (non-fatal): ${detail}`);
|
|
5930
|
+
}
|
|
5931
|
+
});
|
|
5932
|
+
}
|
|
5933
|
+
async function pushDashboardReviewBranch(workspace, dependencies) {
|
|
5934
|
+
if (workspace.workspaceInfo.isRemote && workspace.workspaceInfo.vmName) {
|
|
5935
|
+
await dependencies.pushRemote(workspace.workspaceInfo.vmName, workspace.workspacePath, workspace.branchName);
|
|
5936
|
+
return;
|
|
5937
|
+
}
|
|
5938
|
+
await pushLocalReviewBranches(workspace.issueId, workspace.workspacePath);
|
|
5939
|
+
}
|
|
5940
|
+
function registerDashboardDurableReviewPipeline(dependencies) {
|
|
5941
|
+
registerDurableReviewPipelineHandler((input) => startDashboardDurableReviewPipeline(input, {
|
|
5942
|
+
resolveWorkspace: (issueId) => {
|
|
5943
|
+
const workspaceInfo = dependencies.getWorkspaceInfo(issueId);
|
|
5944
|
+
if (!workspaceInfo.exists) return null;
|
|
5945
|
+
const resolved = resolveProjectFromIssueSync(issueId);
|
|
5946
|
+
if (!resolved) return null;
|
|
5947
|
+
const workspacePath = workspaceInfo.isRemote ? workspaceInfo.remotePath : workspaceInfo.localPath || join(resolved.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
|
|
5948
|
+
if (!workspacePath) return null;
|
|
5949
|
+
return {
|
|
5950
|
+
issueId,
|
|
5951
|
+
workspacePath,
|
|
5952
|
+
workspaceInfo,
|
|
5953
|
+
branchName: `feature/${issueId.toLowerCase()}`
|
|
5954
|
+
};
|
|
5955
|
+
},
|
|
5956
|
+
pushBranch: (workspace) => pushDashboardReviewBranch(workspace, dependencies)
|
|
5957
|
+
}));
|
|
5958
|
+
}
|
|
5572
5959
|
//#endregion
|
|
5573
5960
|
//#region routes/workspaces/review-pipeline.ts
|
|
5574
5961
|
/**
|
|
@@ -5596,7 +5983,16 @@ init_conflict_gate();
|
|
|
5596
5983
|
init_agents();
|
|
5597
5984
|
const execAsync$2 = promisify(exec);
|
|
5598
5985
|
const MAX_AUTO_REQUEUE = 25;
|
|
5599
|
-
const
|
|
5986
|
+
const pushRemoteReviewBranch = async (vmName, workspacePath, branchName) => {
|
|
5987
|
+
await execAsync$2(flyExecCmd(vmName, `cd ${workspacePath} && GIT_TERMINAL_PROMPT=0 GIT_ASKPASS=true SSH_ASKPASS=true git push origin ${branchName}`), {
|
|
5988
|
+
encoding: "utf-8",
|
|
5989
|
+
timeout: 3e4
|
|
5990
|
+
});
|
|
5991
|
+
};
|
|
5992
|
+
registerDashboardDurableReviewPipeline({
|
|
5993
|
+
getWorkspaceInfo: getWorkspaceInfoForIssue,
|
|
5994
|
+
pushRemote: pushRemoteReviewBranch
|
|
5995
|
+
});
|
|
5600
5996
|
/** Safe `.message` read for caught values of unknown shape. */
|
|
5601
5997
|
const errorMessage = (e) => e instanceof Error ? e.message : void 0;
|
|
5602
5998
|
/**
|
|
@@ -5610,21 +6006,7 @@ const errorMessage = (e) => e instanceof Error ? e.message : void 0;
|
|
|
5610
6006
|
* the workspace path, preserving the previous behavior.
|
|
5611
6007
|
*/
|
|
5612
6008
|
async function pushFeatureBranches(issueId, workspacePath) {
|
|
5613
|
-
|
|
5614
|
-
for (const root of resolveWorkspaceRepoRootsSync(issueId, workspacePath)) {
|
|
5615
|
-
try {
|
|
5616
|
-
await execAsync$2(`git rev-parse --verify --quiet refs/heads/${root.sourceBranch}`, {
|
|
5617
|
-
cwd: root.dir,
|
|
5618
|
-
encoding: "utf-8"
|
|
5619
|
-
});
|
|
5620
|
-
} catch {
|
|
5621
|
-
continue;
|
|
5622
|
-
}
|
|
5623
|
-
await execAsync$2(`git push origin ${root.sourceBranch}`, {
|
|
5624
|
-
cwd: root.dir,
|
|
5625
|
-
encoding: "utf-8"
|
|
5626
|
-
});
|
|
5627
|
-
}
|
|
6009
|
+
await pushLocalReviewBranches(issueId, workspacePath);
|
|
5628
6010
|
}
|
|
5629
6011
|
function shouldTreatAsRerun(status) {
|
|
5630
6012
|
if (!status) return false;
|
|
@@ -5742,7 +6124,7 @@ const postWorkspaceReviewRoute = HttpRouter.add("POST", "/api/review/:issueId/tr
|
|
|
5742
6124
|
console.log(`Feature branch push note: ${errorMessage(pushErr)}`);
|
|
5743
6125
|
}
|
|
5744
6126
|
try {
|
|
5745
|
-
const { createReviewArtifactsForIssue } = await import("./review-artifacts-
|
|
6127
|
+
const { createReviewArtifactsForIssue } = await import("./review-artifacts-BNmw8dWE.js");
|
|
5746
6128
|
const artifactResult = await Effect.runPromise(createReviewArtifactsForIssue(issueId, workspacePath));
|
|
5747
6129
|
const primaryArtifact = artifactResult.mergeSet?.repos.find((repo) => !!repo.artifactUrl);
|
|
5748
6130
|
artifactResult.mergeSet?.repos.find((repo) => repo.mergeStatus !== "skipped")?.targetBranch;
|
|
@@ -5797,7 +6179,12 @@ const postWorkspaceReviewRoute = HttpRouter.add("POST", "/api/review/:issueId/tr
|
|
|
5797
6179
|
} catch {}
|
|
5798
6180
|
return;
|
|
5799
6181
|
}
|
|
5800
|
-
|
|
6182
|
+
if (verifyOutcome.outcome === "deferred") {
|
|
6183
|
+
console.log(`[review] Verification deferred for ${issueId}: ${verifyOutcome.reason}`);
|
|
6184
|
+
completePendingOperation(issueId, verifyOutcome.reason);
|
|
6185
|
+
return;
|
|
6186
|
+
}
|
|
6187
|
+
const { spawnReviewRoleForIssue } = await import("./review-agent-BTCNkq2h.js");
|
|
5801
6188
|
const prUrl = getReviewStatusSync(issueId)?.prUrl;
|
|
5802
6189
|
const reviewResult = await Effect.runPromise(spawnReviewRoleForIssue({
|
|
5803
6190
|
issueId,
|
|
@@ -5933,7 +6320,7 @@ const postWorkspaceRequestReviewRoute = HttpRouter.add("POST", "/api/review/:iss
|
|
|
5933
6320
|
console.log(`[request-review] Feature branch push note: ${errorMessage(pushErr)}`);
|
|
5934
6321
|
}
|
|
5935
6322
|
const prUrl = getReviewStatusSync(issueId)?.prUrl;
|
|
5936
|
-
const { spawnReviewRoleForIssue } = await import("./review-agent-
|
|
6323
|
+
const { spawnReviewRoleForIssue } = await import("./review-agent-BTCNkq2h.js");
|
|
5937
6324
|
const result = await Effect.runPromise(spawnReviewRoleForIssue({
|
|
5938
6325
|
issueId,
|
|
5939
6326
|
workspace: workspacePathRerun,
|
|
@@ -5983,7 +6370,7 @@ const postWorkspaceRequestReviewRoute = HttpRouter.add("POST", "/api/review/:iss
|
|
|
5983
6370
|
});
|
|
5984
6371
|
} else {
|
|
5985
6372
|
const workspacePath = join(resolved.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
|
|
5986
|
-
const { spawnRun } = yield* Effect.promise(() => import("./agents-
|
|
6373
|
+
const { spawnRun } = yield* Effect.promise(() => import("./agents-ePFVoZbu.js"));
|
|
5987
6374
|
try {
|
|
5988
6375
|
const testRun = yield* Effect.promise(() => spawnRun(issueId, "test", { workspace: workspacePath }));
|
|
5989
6376
|
setReviewStatus(issueId, { testStatus: "testing" });
|
|
@@ -6060,6 +6447,7 @@ const postWorkspaceRequestReviewRoute = HttpRouter.add("POST", "/api/review/:iss
|
|
|
6060
6447
|
verificationStatus: "pending",
|
|
6061
6448
|
reviewNotes
|
|
6062
6449
|
});
|
|
6450
|
+
clearFeedbackDeliveryStuck(canonicalIssueId);
|
|
6063
6451
|
if (!requestReviewPipeline.start(canonicalIssueId, {
|
|
6064
6452
|
verify: () => Effect.runPromise(runVerificationForIssue(issueId, workspacePath, workspaceInfo, "request-review")),
|
|
6065
6453
|
onVerificationFailed: (outcome) => {
|
|
@@ -6078,9 +6466,17 @@ const postWorkspaceRequestReviewRoute = HttpRouter.add("POST", "/api/review/:iss
|
|
|
6078
6466
|
autoRequeueCount: currentCount
|
|
6079
6467
|
});
|
|
6080
6468
|
},
|
|
6469
|
+
onVerificationDeferred: (outcome) => {
|
|
6470
|
+
console.log(`[request-review] Verification deferred for ${issueId}: ${outcome.reason}`);
|
|
6471
|
+
completePendingOperation(issueId, outcome.reason);
|
|
6472
|
+
},
|
|
6081
6473
|
pushBranch: async () => {
|
|
6082
|
-
|
|
6083
|
-
|
|
6474
|
+
await pushDashboardReviewBranch({
|
|
6475
|
+
issueId,
|
|
6476
|
+
workspacePath,
|
|
6477
|
+
workspaceInfo,
|
|
6478
|
+
branchName
|
|
6479
|
+
}, { pushRemote: pushRemoteReviewBranch });
|
|
6084
6480
|
console.log(`[request-review] Pushed verified branch ${branchName} for ${issueId}`);
|
|
6085
6481
|
},
|
|
6086
6482
|
dispatchReview: async () => {
|
|
@@ -6089,7 +6485,7 @@ const postWorkspaceRequestReviewRoute = HttpRouter.add("POST", "/api/review/:iss
|
|
|
6089
6485
|
testStatus: "pending",
|
|
6090
6486
|
reviewNotes
|
|
6091
6487
|
});
|
|
6092
|
-
const { spawnReviewRoleForIssue } = await import("./review-agent-
|
|
6488
|
+
const { spawnReviewRoleForIssue } = await import("./review-agent-BTCNkq2h.js");
|
|
6093
6489
|
const result = await Effect.runPromise(spawnReviewRoleForIssue({
|
|
6094
6490
|
issueId,
|
|
6095
6491
|
workspace: workspacePath,
|
|
@@ -6176,12 +6572,12 @@ const reviewPipelineRouteLayer = Layer.mergeAll(postWorkspaceReviewRoute, postWo
|
|
|
6176
6572
|
* stay owned by ../workspaces.js.
|
|
6177
6573
|
*/
|
|
6178
6574
|
init_issue_id();
|
|
6179
|
-
init_archive_planning();
|
|
6180
6575
|
init_projects();
|
|
6181
6576
|
init_review_status();
|
|
6182
6577
|
init_agents();
|
|
6183
6578
|
init_model_validation();
|
|
6184
6579
|
init_config_yaml();
|
|
6580
|
+
init_pipeline_notifier();
|
|
6185
6581
|
const execAsync$1 = promisify(exec);
|
|
6186
6582
|
function resolveConfiguredReviewModel() {
|
|
6187
6583
|
try {
|
|
@@ -6191,6 +6587,32 @@ function resolveConfiguredReviewModel() {
|
|
|
6191
6587
|
}
|
|
6192
6588
|
}
|
|
6193
6589
|
/**
|
|
6590
|
+
* Read and re-emit canonical review status without mutating it. This is the
|
|
6591
|
+
* operator escape hatch for PAN-2988-style lost review.status_changed events.
|
|
6592
|
+
*/
|
|
6593
|
+
function processResyncReviewStatus(issueId) {
|
|
6594
|
+
const status = getReviewStatusSync(issueId);
|
|
6595
|
+
if (!status) return {
|
|
6596
|
+
httpStatus: 404,
|
|
6597
|
+
body: {
|
|
6598
|
+
ok: false,
|
|
6599
|
+
error: `no review status found for ${issueId}`
|
|
6600
|
+
}
|
|
6601
|
+
};
|
|
6602
|
+
notifyPipelineSync({
|
|
6603
|
+
type: "status_changed",
|
|
6604
|
+
issueId,
|
|
6605
|
+
status
|
|
6606
|
+
});
|
|
6607
|
+
return {
|
|
6608
|
+
httpStatus: 200,
|
|
6609
|
+
body: {
|
|
6610
|
+
ok: true,
|
|
6611
|
+
status
|
|
6612
|
+
}
|
|
6613
|
+
};
|
|
6614
|
+
}
|
|
6615
|
+
/**
|
|
6194
6616
|
* Core logic for POST /api/review/:issueId/reset (synchronous, testable).
|
|
6195
6617
|
*
|
|
6196
6618
|
* Resets the specialist pipeline state (review / test / merge / verification) for
|
|
@@ -6338,7 +6760,8 @@ function processUnstickRequest(issueId, workspaceExists, currentStatus, gitRepai
|
|
|
6338
6760
|
stuckDetails: void 0,
|
|
6339
6761
|
reviewedAtCommit: void 0,
|
|
6340
6762
|
reviewRetryCount: 0,
|
|
6341
|
-
recoveryStartedAt: void 0
|
|
6763
|
+
recoveryStartedAt: void 0,
|
|
6764
|
+
...currentStatus.stuckReason === "review-not-converging" && { reviewCycleHistory: void 0 }
|
|
6342
6765
|
});
|
|
6343
6766
|
console.log(`[unstick] Cleared stuck flag and reset lifecycle for ${issueId} (was: ${currentStatus.stuckReason ?? "unknown"})`);
|
|
6344
6767
|
return {
|
|
@@ -6398,7 +6821,7 @@ const postWorkspaceResetReviewRoute = HttpRouter.add("POST", "/api/review/:issue
|
|
|
6398
6821
|
const result = processResetReviewPipeline(issueId, resetWorkspace.exists);
|
|
6399
6822
|
if (result.httpStatus !== 200) return jsonResponse(result.body, { status: result.httpStatus });
|
|
6400
6823
|
try {
|
|
6401
|
-
const { resetPostMergeState } = yield* Effect.promise(() => import("./merge-agent-
|
|
6824
|
+
const { resetPostMergeState } = yield* Effect.promise(() => import("./merge-agent-DQTXZk8z.js"));
|
|
6402
6825
|
resetPostMergeState(issueId);
|
|
6403
6826
|
} catch (err) {
|
|
6404
6827
|
console.warn(`[reset-review] resetPostMergeState best-effort failed for ${issueId}:`, err);
|
|
@@ -6407,7 +6830,7 @@ const postWorkspaceResetReviewRoute = HttpRouter.add("POST", "/api/review/:issue
|
|
|
6407
6830
|
const rerun = body?.rerun === true;
|
|
6408
6831
|
if (rerun) try {
|
|
6409
6832
|
yield* Effect.promise(async () => {
|
|
6410
|
-
const { spawnReviewRoleForIssue } = await import("./review-agent-
|
|
6833
|
+
const { spawnReviewRoleForIssue } = await import("./review-agent-BTCNkq2h.js");
|
|
6411
6834
|
const dispatchArgs = buildReviewRedispatchArgs(issueId, resetWorkspace, workspaceInfo, resolved);
|
|
6412
6835
|
if (dispatchArgs) {
|
|
6413
6836
|
const result = await Effect.runPromise(spawnReviewRoleForIssue({
|
|
@@ -6433,10 +6856,16 @@ const postWorkspaceResetReviewRoute = HttpRouter.add("POST", "/api/review/:issue
|
|
|
6433
6856
|
rerun
|
|
6434
6857
|
});
|
|
6435
6858
|
})));
|
|
6859
|
+
const postReviewResyncRoute = HttpRouter.add("POST", "/api/review/:issueId/resync", httpHandler(Effect.gen(function* () {
|
|
6860
|
+
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
6861
|
+
if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
6862
|
+
const result = processResyncReviewStatus(issueId.toUpperCase());
|
|
6863
|
+
return jsonResponse(result.body, { status: result.httpStatus });
|
|
6864
|
+
})));
|
|
6436
6865
|
const postWorkspaceReviewPurgeRoute = HttpRouter.add("POST", "/api/review/:issueId/purge", httpHandler(Effect.gen(function* () {
|
|
6437
6866
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
6438
6867
|
if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
6439
|
-
const { purgeReviewAgentsForIssue } = yield* Effect.promise(() => import("./review-agent-
|
|
6868
|
+
const { purgeReviewAgentsForIssue } = yield* Effect.promise(() => import("./review-agent-BTCNkq2h.js"));
|
|
6440
6869
|
const projectKey = resolveProjectFromIssueSync(issueId)?.projectKey;
|
|
6441
6870
|
const purge = yield* Effect.promise(() => purgeReviewAgentsForIssue(projectKey, issueId));
|
|
6442
6871
|
const workspaceInfo = getWorkspaceInfoForIssue(issueId);
|
|
@@ -6466,8 +6895,8 @@ const postWorkspaceAbortReviewRoute = HttpRouter.add("POST", "/api/review/:issue
|
|
|
6466
6895
|
success: false,
|
|
6467
6896
|
error: "Workspace does not exist"
|
|
6468
6897
|
}, { status: 400 });
|
|
6469
|
-
const { resolveProjectFromIssueSync } = yield* Effect.promise(() => import("./projects-
|
|
6470
|
-
const { killAllReviewerSessions } = yield* Effect.promise(() => import("./review-agent-
|
|
6898
|
+
const { resolveProjectFromIssueSync } = yield* Effect.promise(() => import("./projects-_n3Zui6K.js"));
|
|
6899
|
+
const { killAllReviewerSessions } = yield* Effect.promise(() => import("./review-agent-BTCNkq2h.js"));
|
|
6471
6900
|
const { killed, failed } = yield* killAllReviewerSessions(resolveProjectFromIssueSync(issueId)?.projectKey, issueId);
|
|
6472
6901
|
setReviewStatus(issueId, {
|
|
6473
6902
|
reviewStatus: "pending",
|
|
@@ -6539,8 +6968,8 @@ const getReviewConfigRoute = HttpRouter.add("GET", "/api/review/:issueId/config"
|
|
|
6539
6968
|
const issueId = ((yield* HttpRouter.params)["issueId"] ?? "").toUpperCase();
|
|
6540
6969
|
if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
6541
6970
|
return jsonResponse(yield* Effect.promise(async () => {
|
|
6542
|
-
const { readIssueRecordSync, resolveProjectForIssue } = await import("./record-
|
|
6543
|
-
const { resolveReviewMode, resolveReReviewScope } = await import("./review-agent-
|
|
6971
|
+
const { readIssueRecordSync, resolveProjectForIssue } = await import("./record-BTwWhtBb.js");
|
|
6972
|
+
const { resolveReviewMode, resolveReReviewScope } = await import("./review-agent-BTCNkq2h.js");
|
|
6544
6973
|
const project = resolveProjectForIssue(issueId);
|
|
6545
6974
|
const record = project ? readIssueRecordSync(project, issueId) : null;
|
|
6546
6975
|
return {
|
|
@@ -6575,9 +7004,9 @@ const postReviewConfigRoute = HttpRouter.add("POST", "/api/review/:issueId/confi
|
|
|
6575
7004
|
return jsonResponse({ error: error instanceof Error ? error.message : String(error) }, { status: 400 });
|
|
6576
7005
|
}
|
|
6577
7006
|
return jsonResponse(yield* Effect.promise(async () => {
|
|
6578
|
-
const { resolveProjectForIssue } = await import("./record-
|
|
6579
|
-
const { updateIssueRecord } = await import("./record-update-
|
|
6580
|
-
const { resolveReviewMode, resolveReReviewScope } = await import("./review-agent-
|
|
7007
|
+
const { resolveProjectForIssue } = await import("./record-BTwWhtBb.js");
|
|
7008
|
+
const { updateIssueRecord } = await import("./record-update-DhI7eySG.js");
|
|
7009
|
+
const { resolveReviewMode, resolveReReviewScope } = await import("./review-agent-BTCNkq2h.js");
|
|
6581
7010
|
const record = await updateIssueRecord(resolveProjectForIssue(issueId), issueId, (current) => {
|
|
6582
7011
|
if (hasMode) if (body.reviewMode === null) delete current.reviewMode;
|
|
6583
7012
|
else current.reviewMode = body.reviewMode;
|
|
@@ -6602,7 +7031,7 @@ const postReviewConfigRoute = HttpRouter.add("POST", "/api/review/:issueId/confi
|
|
|
6602
7031
|
};
|
|
6603
7032
|
}));
|
|
6604
7033
|
})));
|
|
6605
|
-
const reviewControlRouteLayer = Layer.mergeAll(postWorkspaceResetReviewRoute, postWorkspaceReviewPurgeRoute, postWorkspaceAbortReviewRoute, postWorkspaceUnstickRoute, postWorkspaceDeaconIgnoreRoute, postWorkspaceAutoMergeRoute, deleteWorkspacePendingRoute, getReviewConfigRoute, postReviewConfigRoute);
|
|
7034
|
+
const reviewControlRouteLayer = Layer.mergeAll(postWorkspaceResetReviewRoute, postReviewResyncRoute, postWorkspaceReviewPurgeRoute, postWorkspaceAbortReviewRoute, postWorkspaceUnstickRoute, postWorkspaceDeaconIgnoreRoute, postWorkspaceAutoMergeRoute, deleteWorkspacePendingRoute, getReviewConfigRoute, postReviewConfigRoute);
|
|
6606
7035
|
//#endregion
|
|
6607
7036
|
//#region routes/workspaces/uat-stack-actions.ts
|
|
6608
7037
|
init_activity_logger();
|
|
@@ -7010,7 +7439,7 @@ async function readWorkspacePlanningMarkdown(issueId, fileName) {
|
|
|
7010
7439
|
*/
|
|
7011
7440
|
async function readWorkspaceContinueFile(_projectPath, workspacePath, issueId) {
|
|
7012
7441
|
try {
|
|
7013
|
-
const { readRecordContinueViewSync, getProjectConfigFromWorkspacePath, resolveProjectForIssue } = await import("./record-
|
|
7442
|
+
const { readRecordContinueViewSync, getProjectConfigFromWorkspacePath, resolveProjectForIssue } = await import("./record-BTwWhtBb.js");
|
|
7014
7443
|
const recordView = readRecordContinueViewSync(resolveProjectForIssue(issueId) ?? getProjectConfigFromWorkspacePath(workspacePath), issueId);
|
|
7015
7444
|
return recordView ? JSON.stringify(recordView, null, 2) : null;
|
|
7016
7445
|
} catch {
|
|
@@ -7208,7 +7637,11 @@ function spawnPanCommand(args, description, cwd, options) {
|
|
|
7208
7637
|
"ignore",
|
|
7209
7638
|
"pipe",
|
|
7210
7639
|
"pipe"
|
|
7211
|
-
]
|
|
7640
|
+
],
|
|
7641
|
+
env: {
|
|
7642
|
+
...process.env,
|
|
7643
|
+
...options?.env
|
|
7644
|
+
}
|
|
7212
7645
|
});
|
|
7213
7646
|
attachPanOutputStreams(child, activityId);
|
|
7214
7647
|
child.on("close", (code) => {
|
|
@@ -7227,7 +7660,11 @@ function spawnPanCommand(args, description, cwd, options) {
|
|
|
7227
7660
|
"ignore",
|
|
7228
7661
|
"pipe",
|
|
7229
7662
|
"pipe"
|
|
7230
|
-
]
|
|
7663
|
+
],
|
|
7664
|
+
env: {
|
|
7665
|
+
...process.env,
|
|
7666
|
+
...options?.env
|
|
7667
|
+
}
|
|
7231
7668
|
});
|
|
7232
7669
|
attachPanOutputStreams(next, activityId);
|
|
7233
7670
|
next.on("close", (nextCode) => finalize(nextCode, `pan ${chain.args.join(" ")}`));
|
|
@@ -7525,7 +7962,16 @@ const postWorkspaceRebuildRoute = HttpRouter.add("POST", "/api/workspaces/:issue
|
|
|
7525
7962
|
});
|
|
7526
7963
|
})));
|
|
7527
7964
|
const postWorkspaceRebuildAndStartRoute = HttpRouter.add("POST", "/api/workspaces/:issueId/rebuild-and-start", httpHandler(Effect.gen(function* () {
|
|
7965
|
+
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
7528
7966
|
const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
|
|
7967
|
+
const body = yield* readJsonBody;
|
|
7968
|
+
const internalRequest = yield* Effect.promise(() => isInternalAgentRequest(request));
|
|
7969
|
+
let startedBy;
|
|
7970
|
+
try {
|
|
7971
|
+
startedBy = resolveRequestedStartedBy(body?.startedBy, internalRequest);
|
|
7972
|
+
} catch (error) {
|
|
7973
|
+
return jsonResponse({ error: error instanceof Error ? error.message : String(error) }, { status: 400 });
|
|
7974
|
+
}
|
|
7529
7975
|
if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
7530
7976
|
const projectPath = getProjectPath(void 0, extractPrefixSync(issueId) ?? issueId.split("-")[0]);
|
|
7531
7977
|
const activityId = spawnPanCommand([
|
|
@@ -7538,6 +7984,10 @@ const postWorkspaceRebuildAndStartRoute = HttpRouter.add("POST", "/api/workspace
|
|
|
7538
7984
|
chainOnSuccess: {
|
|
7539
7985
|
args: ["start", issueId],
|
|
7540
7986
|
phaseLabel: `Stack rebuilt — starting agent for ${issueId.toUpperCase()}`
|
|
7987
|
+
},
|
|
7988
|
+
env: {
|
|
7989
|
+
OVERDECK_AGENT_STARTED_BY: startedBy,
|
|
7990
|
+
OVERDECK_AUTO_SPAWN_CONSENT_REQUIRED: internalRequest && body?.autoSpawnConsentRequired === true ? "1" : "0"
|
|
7541
7991
|
}
|
|
7542
7992
|
});
|
|
7543
7993
|
return jsonResponse({
|
|
@@ -7769,7 +8219,7 @@ const getWorkspaceReviewStatusRoute = HttpRouter.add("GET", "/api/review/:issueI
|
|
|
7769
8219
|
if (queuePosition === null) try {
|
|
7770
8220
|
const resolved = resolveProjectFromIssueSync(issueId);
|
|
7771
8221
|
if (resolved) {
|
|
7772
|
-
const { getQueueForProject } = yield* Effect.promise(() => import("./merge-
|
|
8222
|
+
const { getQueueForProject } = yield* Effect.promise(() => import("./merge-sr8Nrnmi.js"));
|
|
7773
8223
|
const mergePos = findPositionInQueueSync(issueId, getQueueForProject(resolved.projectKey).map((e) => ({
|
|
7774
8224
|
id: String(e.id),
|
|
7775
8225
|
type: "task",
|
|
@@ -7807,10 +8257,10 @@ const postWorkspaceReviewStatusRoute = HttpRouter.add("POST", "/api/review/:issu
|
|
|
7807
8257
|
const workspaceInfo = getWorkspaceInfoForIssue(issueId);
|
|
7808
8258
|
if (workspaceInfo.exists && workspaceInfo.localPath) {
|
|
7809
8259
|
const localPath = workspaceInfo.localPath;
|
|
7810
|
-
const {
|
|
8260
|
+
const { snapshotWorkspaceHeadsPromise } = yield* Effect.promise(() => import("./git-utils-Xg4PFN45.js"));
|
|
7811
8261
|
try {
|
|
7812
|
-
const
|
|
7813
|
-
if (
|
|
8262
|
+
const headAnchor = yield* Effect.promise(() => snapshotWorkspaceHeadsPromise(issueId, localPath));
|
|
8263
|
+
if (headAnchor) update.reviewedAtCommit = headAnchor;
|
|
7814
8264
|
} catch {}
|
|
7815
8265
|
}
|
|
7816
8266
|
}
|
|
@@ -7822,7 +8272,7 @@ const postWorkspaceReviewStatusRoute = HttpRouter.add("POST", "/api/review/:issu
|
|
|
7822
8272
|
if (verificationStatus) update.verificationStatus = verificationStatus;
|
|
7823
8273
|
if (readyForMerge !== void 0) update.readyForMerge = readyForMerge;
|
|
7824
8274
|
const status = setReviewStatus(issueId, update);
|
|
7825
|
-
const { getTmuxSessionName } = yield* Effect.promise(() => import("./specialists-
|
|
8275
|
+
const { getTmuxSessionName } = yield* Effect.promise(() => import("./specialists-Bz-wFT7R.js"));
|
|
7826
8276
|
const projectKey = resolveProjectFromIssueSync(issueId)?.projectKey;
|
|
7827
8277
|
if (reviewStatus && [
|
|
7828
8278
|
"passed",
|
|
@@ -7840,7 +8290,7 @@ const postWorkspaceReviewStatusRoute = HttpRouter.add("POST", "/api/review/:issu
|
|
|
7840
8290
|
const agentId = `agent-${issueId.toLowerCase()}`;
|
|
7841
8291
|
const feedbackBody = `CODE REVIEW ${reviewStatus.toUpperCase()} for ${issueId}:\n\n${reviewNotes}\n\n## REQUIRED: Fix ALL issues above, then invoke the /rebase-and-submit skill\n\n1. Read each blocking issue carefully\n2. Fix the code for EVERY issue listed\n3. Run tests locally to verify your fixes\n4. Commit every change\n5. Invoke the /rebase-and-submit skill for ${issueId} — this is an atomic task that runs pan done (which handles rebase + push + re-submit internally)\n\nDo NOT stop between steps. Do NOT run git push manually — the skill handles it. Do NOT stop until pan done has completed successfully.`;
|
|
7842
8292
|
try {
|
|
7843
|
-
const { writeFeedbackFile } = yield* Effect.promise(() => import("./feedback-writer-
|
|
8293
|
+
const { writeFeedbackFile } = yield* Effect.promise(() => import("./feedback-writer-CoB9Z6aU.js"));
|
|
7844
8294
|
const wsInfo = getWorkspaceInfoForIssue(issueId);
|
|
7845
8295
|
const fileResult = yield* Effect.promise(() => writeFeedbackFile({
|
|
7846
8296
|
issueId,
|
|
@@ -7904,7 +8354,7 @@ const postWorkspaceReviewStatusRoute = HttpRouter.add("POST", "/api/review/:issu
|
|
|
7904
8354
|
const agentId = `agent-${issueId.toLowerCase()}`;
|
|
7905
8355
|
const feedbackBody = `TESTS FAILED for ${issueId}:\n\n${testNotes}\n\n## REQUIRED: Fix ALL test failures, then invoke the /rebase-and-submit skill\n\n1. Read each test failure carefully\n2. Fix the code causing EVERY failure\n3. Run the test suite locally to verify your fixes pass\n4. Commit every change\n5. Invoke the /rebase-and-submit skill for ${issueId} — this is an atomic task that runs pan done (which handles rebase + push + re-submit internally)\n\nDo NOT stop between steps. Do NOT run git push manually — the skill handles it. Do NOT stop until pan done has completed successfully.`;
|
|
7906
8356
|
try {
|
|
7907
|
-
const { writeFeedbackFile } = yield* Effect.promise(() => import("./feedback-writer-
|
|
8357
|
+
const { writeFeedbackFile } = yield* Effect.promise(() => import("./feedback-writer-CoB9Z6aU.js"));
|
|
7908
8358
|
const wsInfo = getWorkspaceInfoForIssue(issueId);
|
|
7909
8359
|
const fileResult = yield* Effect.promise(() => writeFeedbackFile({
|
|
7910
8360
|
issueId,
|
|
@@ -7937,14 +8387,14 @@ const postWorkspaceReviewStatusRoute = HttpRouter.add("POST", "/api/review/:issu
|
|
|
7937
8387
|
});
|
|
7938
8388
|
yield* Effect.promise(async () => {
|
|
7939
8389
|
try {
|
|
7940
|
-
const { resolveProjectFromIssueSync, getProjectSync } = await import("./projects-
|
|
8390
|
+
const { resolveProjectFromIssueSync, getProjectSync } = await import("./projects-_n3Zui6K.js");
|
|
7941
8391
|
const project = resolveProjectFromIssueSync(issueId);
|
|
7942
8392
|
const repo = (project ? getProjectSync(project.projectKey) : null)?.github_repo;
|
|
7943
8393
|
if (!repo || !repo.includes("/")) return;
|
|
7944
8394
|
const [owner, name] = repo.split("/");
|
|
7945
8395
|
const wsInfo = getWorkspaceInfoForIssue(issueId);
|
|
7946
8396
|
if (!wsInfo?.localPath) return;
|
|
7947
|
-
const { postOverdeckTestsStatus } = await import("./github-app-
|
|
8397
|
+
const { postOverdeckTestsStatus } = await import("./github-app-Bmg4R9mv.js");
|
|
7948
8398
|
await postOverdeckTestsStatus(wsInfo.localPath, owner, name, "success", "Test specialist passed");
|
|
7949
8399
|
} catch (err) {
|
|
7950
8400
|
console.warn(`[review-status] Failed to post overdeck/tests for ${issueId}: ${err.message}`);
|
|
@@ -7986,7 +8436,7 @@ const postWorkspaceRefreshTokenRoute = HttpRouter.add("POST", "/api/workspaces/:
|
|
|
7986
8436
|
if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
|
|
7987
8437
|
const issueLower = issueId.toLowerCase();
|
|
7988
8438
|
const workspacePath = join(getProjectPath(void 0, extractPrefixSync(issueId) ?? issueId.split("-")[0]), "workspaces", `feature-${issueLower}`);
|
|
7989
|
-
const { refreshWorkspaceToken, isGitHubAppConfigured } = yield* Effect.promise(() => import("./github-app-
|
|
8439
|
+
const { refreshWorkspaceToken, isGitHubAppConfigured } = yield* Effect.promise(() => import("./github-app-Bmg4R9mv.js"));
|
|
7990
8440
|
if (!isGitHubAppConfigured()) return jsonResponse({
|
|
7991
8441
|
success: false,
|
|
7992
8442
|
error: "GitHub App not configured"
|
|
@@ -8001,4 +8451,4 @@ const workspacesRouteLayer = Layer.mergeAll(workspaceDataRouteLayer, postWorkspa
|
|
|
8001
8451
|
//#endregion
|
|
8002
8452
|
export { getWorkspacePathForIssue as C, stopAgentOutputService as E, resolveIssueHeadlineCost as S, startAgentOutputService as T, getCostsForIssueSync as _, pushApproveMain as a, processPendingFeedbackDeliveries as b, triggerMerge as c, resumeQueuedMerges as d, syncWalFromAllProjects as f, migrateAllSessionsSync as g, reclassifyUnknownCostEventsSync as h, mergeOpsRouteLayer as i, internalEventsRouteLayer as l, reconcilePiTranscripts as m, buildRichPRBody as n, reconcileGitHubMergeStatus as o, reconcile as p, isBranchAlreadyRebased as r, shouldBlockApproveForDirtyStatus as s, workspacesRouteLayer as t, eventsRouteLayer as u, rebuildCacheSync as v, retainAgentOutputInterest as w, getCachedRunningAgents as x, syncCacheSync as y };
|
|
8003
8453
|
|
|
8004
|
-
//# sourceMappingURL=workspaces-
|
|
8454
|
+
//# sourceMappingURL=workspaces-CRBJikLp.js.map
|