@overdeck/desktop 0.45.23 → 0.46.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.
Files changed (549) hide show
  1. package/drizzle/overdeck/0000_overdeck_init.sql +34 -0
  2. package/package.json +1 -1
  3. package/server/{acceptance-criteria-DOA0KgXx.js → acceptance-criteria-CCwFGICj.js} +2 -2
  4. package/server/activity-logger-CMthG6Vd.js +3 -0
  5. package/server/{activity-logger-DDlOIAML.js → activity-logger-CyteR4JO.js} +24 -13
  6. package/server/{advancing-selfheal-BBu6DSNm.js → advancing-selfheal-De1L-Sb4.js} +6 -6
  7. package/server/{agent-gc-BV1q_2EV.js → agent-gc-CBULruzm.js} +5 -5
  8. package/server/agent-state-VQk8fY9F.js +3 -0
  9. package/server/{agent-state-service-HoK8U4jW.js → agent-state-service-BlnSkRFA.js} +5 -5
  10. package/server/{agent-state-service-CnzFKSAQ.js → agent-state-service-hZpxIw1E.js} +1 -1
  11. package/server/agents-BKKkxKgK.js +3 -0
  12. package/server/{agents-B4Bjbkfv.js → agents-C5rWYhb6.js} +4 -4
  13. package/server/archive-planning-0FJ6Xd3b.js +2 -0
  14. package/server/{archive-planning-DYrYojxl.js → archive-planning-C0lAbNB_.js} +16 -24
  15. package/server/{artifact-index-jobs-C-xy7Z5v.js → artifact-index-jobs-ug6ZxIP5.js} +2 -2
  16. package/server/assemble-DnffNpOo.js +339 -0
  17. package/server/{backlog-auto-trigger-GtG71X8H.js → backlog-auto-trigger-Dh-i9PQf.js} +3 -3
  18. package/server/{behavior-B_-4EKF3.js → behavior-CfIg6pKp.js} +2 -2
  19. package/server/bridge-pool-patrol-CUFmjVDN.js +136 -0
  20. package/server/{briefing-freshness-DWdW7vUm.js → briefing-freshness-DHmCSLar.js} +2 -2
  21. package/server/{build-info-DgTqZkL5.js → build-info-BP160gU7.js} +1 -1
  22. package/server/{build-info-BT096lEl.js → build-info-CuFfxZxp.js} +5 -3
  23. package/server/{checkpoint-manager-DDqcGyu8.js → checkpoint-manager-DEWD82qK.js} +2 -2
  24. package/server/{checkpoint-manager-B7Bt29J0.js → checkpoint-manager-Dxh0FYsv.js} +1 -1
  25. package/server/checkpoint-worker.js +1 -1
  26. package/server/{checkpoints-C-AXLfYT.js → checkpoints-CZvbtLnr.js} +2 -2
  27. package/server/{checkpoints-CpgCjAlN.js → checkpoints-DMTgXuLG.js} +1 -1
  28. package/server/{claude-hooks-provision-C8wdRnN1.js → claude-hooks-provision-CN-xo-do.js} +1 -1
  29. package/server/{claude-hooks-provision-but-_qGY.js → claude-hooks-provision-fvy4RD2b.js} +13 -2
  30. package/server/{claude-permissions-H_5wHQZQ.js → claude-permissions-CN0cSCPp.js} +2 -2
  31. package/server/{claude-settings-overlay-CbSz0Dvb.js → claude-settings-overlay-CJn35FHQ.js} +2 -2
  32. package/server/{claude-settings-overlay-BTENVmYf.js → claude-settings-overlay-Dabi9slj.js} +1 -1
  33. package/server/cli-DmXETsw-.js +3 -0
  34. package/server/{cli-vBeXbPrq.js → cli-oCWYA1pE.js} +9 -9
  35. package/server/{cliproxy-Bgb2XCqi.js → cliproxy-C8mB3KuB.js} +2 -2
  36. package/server/{cliproxy-DW0V86F8.js → cliproxy-PGwTX_o8.js} +1 -1
  37. package/server/{close-issue-Dn_4c4G8.js → close-issue-D5MF5GqF.js} +5 -5
  38. package/server/{closed-issue-reaper-CWpY2uBw.js → closed-issue-reaper-CJ24u0Zt.js} +1 -1
  39. package/server/{closed-issue-reaper-hANY_ehE.js → closed-issue-reaper-Cltx86x5.js} +37 -16
  40. package/server/{codex-Dg7Is5yb.js → codex-BdEsUFWh.js} +1 -1
  41. package/server/{codex-TmSi-yTv.js → codex-Drlf5Xhf.js} +37 -8
  42. package/server/{codex-parser-C4gSH-IR.js → codex-parser-DpB89Vqa.js} +2 -2
  43. package/server/compaction-continuation-K2AxQX4H.js +200 -0
  44. package/server/{config-DjLOdbgT.js → config-B2IMcBxx.js} +4 -3
  45. package/server/{config-DUIhMN_T.js → config-DV-grfQc.js} +1 -1
  46. package/server/{config-CCvjQf27.js → config-Dr3pW6w6.js} +2 -2
  47. package/server/{config-yaml-DvyMuOle.js → config-yaml-CmOPzmBb.js} +290 -22
  48. package/server/{conflict-gate-CmrYpa47.js → conflict-gate-B9cN3SBi.js} +4 -4
  49. package/server/{conflict-gate-BSJkNTdp.js → conflict-gate-Dh754uyA.js} +1 -1
  50. package/server/context-layers-D6LZo3l1.js +4 -0
  51. package/server/context-layers-dR5YxHYB.js +37 -0
  52. package/server/{control-settings-aP1ANIlI.js → control-settings-C7DUehE1.js} +49 -19
  53. package/server/{conversation-compaction-CNbTLB86.js → conversation-compaction-BoqdDXWF.js} +8 -8
  54. package/server/{conversation-compaction-DiG5zWQq.js → conversation-compaction-Dj4FAKoZ.js} +1 -1
  55. package/server/{conversation-service-Du-MTNpJ.js → conversation-service-5aCnq1zR.js} +331 -20
  56. package/server/conversation-service-BCxl4f8Z.js +3 -0
  57. package/server/{conversations-DbOs1e9Q.js → conversations-BUpYsOZg.js} +5 -5
  58. package/server/{conversations-6mPANqvL.js → conversations-C34dyIb9.js} +1 -1
  59. package/server/{cost-Ca0YTWDw.js → cost-Bgcub5kW.js} +12 -2
  60. package/server/{cost-CW4WSe72.js → cost-CvxRrucd.js} +3 -3
  61. package/server/{cost-sync-C0VdGme1.js → cost-sync-Dv3LUaNW.js} +3 -3
  62. package/server/{dag-CdOjJVDT.js → dag-ombYYt4s.js} +2 -2
  63. package/server/{dangerous-git-ops-CT-IypG3.js → dangerous-git-ops-BcJPC5Rr.js} +1 -1
  64. package/server/dashboard-db-worker.js +7 -7
  65. package/server/deacon-DrXqT9LQ.js +4 -0
  66. package/server/{deacon-pRnyD5w9.js → deacon-hi9KLPLT.js} +2998 -2659
  67. package/server/{deacon-nudge-log-Bjg8U4Y9.js → deacon-nudge-log-BNBebzeL.js} +3 -3
  68. package/server/deacon-pending-lifecycle-Cpk0k7Hi.js +33 -0
  69. package/server/{deacon-swarm-DftYRDo8.js → deacon-swarm-DBxUaO-A.js} +13 -13
  70. package/server/deacon-swarm-I2JfX5Tg.js +2 -0
  71. package/server/deacon.js +14 -19
  72. package/server/dead-end-trip-CQcP70ND.js +13 -0
  73. package/server/delivery-Da0zEMY4.js +3 -0
  74. package/server/{deploy-patrol-Bjsho_ha.js → deploy-patrol-Df-Tmaq0.js} +69 -18
  75. package/server/deploy-queue-9SrhZR63.js +3 -0
  76. package/server/deploy-queue-UjKGYsDe.js +169 -0
  77. package/server/deploy-window-jOiPRHL0.js +3 -0
  78. package/server/{deploy-window-DeP_OIRk.js → deploy-window-rpqpWqHA.js} +40 -16
  79. package/server/{dev-supervisor-BpMoHlkR.js → dev-supervisor-CC46Ig8q.js} +2 -2
  80. package/server/{devcontainer-renderer-CtUgrVKW.js → devcontainer-renderer-68CSCRnu.js} +3 -3
  81. package/server/{dist-DyRx4cI7.js → dist-CJy72uEg.js} +1 -1
  82. package/server/dist-DSlxIU1H.js +3 -0
  83. package/server/{dist-src-BSoS7mkd.js → dist-src-Bik83hFi.js} +1 -1
  84. package/server/docker-BMVTSFL5.js +3 -0
  85. package/server/{docker-BK7HIcBj.js → docker-Dam7mbIB.js} +2 -2
  86. package/server/{dod-BrSfUHm0.js → dod-Dar-yheg.js} +8 -4
  87. package/server/durable-review-pipeline-CGZ5QBxh.js +17 -0
  88. package/server/durable-review-pipeline-jpgCJZFp.js +3 -0
  89. package/server/{ensure-devcontainer-DseivYEy.js → ensure-devcontainer-B057YA81.js} +4 -4
  90. package/server/{ensure-devcontainer-DRqaAkBR.js → ensure-devcontainer-C98V8yW-.js} +1 -1
  91. package/server/{esm-shims-CbI3BVkl.js → esm-shims-Br9BPdkR.js} +1 -1
  92. package/server/{event-store-Cr5PQwFC.js → event-store-ELqkVOn0.js} +1 -1
  93. package/server/{event-store-tdiY5eDZ.js → event-store-zY5MJHgF.js} +23 -4
  94. package/server/{events-CvvGK6LT.js → events-D6pyqhzM.js} +1 -1
  95. package/server/{events-CC1dgUpx.js → events-D9PR1IC0.js} +3 -3
  96. package/server/{factory-CynerjXO.js → factory-CRoOpGsF.js} +5 -5
  97. package/server/{feature-registry-population-B0pmAz0a.js → feature-registry-population--YUXU999.js} +4 -4
  98. package/server/{feature-registry-storage-_wUBRD3J.js → feature-registry-storage-BORBTo0y.js} +2 -2
  99. package/server/{features-Dhxz-wLc.js → features--nFkJY8v.js} +2 -2
  100. package/server/{feedback-target-iygZwmMc.js → feedback-target-C0ZzyHvU.js} +1 -1
  101. package/server/{feedback-target-CPS15Vte.js → feedback-target-Dt9BsapX.js} +8 -8
  102. package/server/{feedback-writer-C9b6ccN1.js → feedback-writer-BG0RUZiu.js} +5 -5
  103. package/server/{feedback-writer-qmiMbqTZ.js → feedback-writer-D1fm-5Z8.js} +1 -1
  104. package/server/flywheel-BekukH4i.js +2 -0
  105. package/server/flywheel-BiT3odRb.js +1092 -0
  106. package/server/flywheel-CLVB55Be.js +478 -0
  107. package/server/flywheel-merge-order-BJv1DZz1.js +462 -0
  108. package/server/flywheel-merge-order-BKw9o6ku.js +2 -0
  109. package/server/forge-CZbSg6Ds.js +383 -0
  110. package/server/forge-DK3blQb_.js +3 -0
  111. package/server/{from-CJ_aH5jD.js → from-D_4_dk7i.js} +1 -1
  112. package/server/{fts-db-CKgg0VKg.js → fts-db-BeOomFa-.js} +2 -2
  113. package/server/{fts-operations-BrL_VTRr.js → fts-operations-BdewJ_g9.js} +2 -2
  114. package/server/git-utils-CI6cwyyC.js +3 -0
  115. package/server/{git-utils-BVa07a4a.js → git-utils-ameCgDdy.js} +93 -3
  116. package/server/{github-app-CMBdIFBQ.js → github-app-CQ1Lo6LA.js} +19 -8
  117. package/server/{github-app-CPfoFAdV.js → github-app-DtAsvwzK.js} +1 -1
  118. package/server/{github-client--XVlDpwM.js → github-client-BfyDxuRN.js} +2 -2
  119. package/server/{github-client-B4QsdE-X.js → github-client-Cj0yl_07.js} +1 -1
  120. package/server/github-pr-lookup-BDq6Wznz.js +58 -0
  121. package/server/{harness-binary-CVio2m-u.js → harness-binary-DqkftwTb.js} +32 -6
  122. package/server/{harness-resolve-qHJBhy3Z.js → harness-resolve-CqMqM1Mb.js} +18 -9
  123. package/server/{health-events-C9B8y1Hm.js → health-events-CazRxJUS.js} +2 -2
  124. package/server/{health-events-CpfvuVmm.js → health-events-_xfTaOUs.js} +1 -1
  125. package/server/{hooks-DUXw8A0-.js → hooks-BO3QT1sn.js} +2 -2
  126. package/server/{hooks-ltecuFqZ.js → hooks-BnJsxlSq.js} +1 -1
  127. package/server/{hume-BEq0bUDg.js → hume-CDYJxqx-.js} +2 -2
  128. package/server/hume-Dq--7rOQ.js +3 -0
  129. package/server/{idle-stack-reaper-D7w9t3fE.js → idle-stack-reaper-BYqERdkE.js} +1 -1
  130. package/server/{idle-stack-reaper-w1ISSlhs.js → idle-stack-reaper-CnGx_PO_.js} +99 -6
  131. package/server/in-flight-guard-Bq3epG58.js +45 -0
  132. package/server/{infra-CzaSOgul.js → infra-BjuxvjdS.js} +80 -5
  133. package/server/{injection-oNZeoDhL.js → injection-DZxlV2al.js} +1 -1
  134. package/server/{injection-DZ0PfYa4.js → injection-UCf8EsjX.js} +191 -183
  135. package/server/{inspect-agent-DJKLWcVT.js → inspect-agent-6kylZnrm.js} +139 -82
  136. package/server/inspect-agent-BVwDrVrz.js +2 -0
  137. package/server/{internal-token-Bb4XeV2x.js → internal-token-DvMTQSOS.js} +2 -2
  138. package/server/{internal-token-DXdfprGr.js → internal-token-M9omeXM1.js} +1 -1
  139. package/server/{io-B3_AHDfr.js → io-VHvc0Ssp.js} +43 -26
  140. package/server/{issue-closed-zhdvQicO.js → issue-closed-B6KJkmHZ.js} +7 -7
  141. package/server/{issue-lifecycle-Dy4vd0Oa.js → issue-lifecycle-9gk3fnXN.js} +1 -1
  142. package/server/{issue-lifecycle-CreaCkjW.js → issue-lifecycle-C4Zj0WmE.js} +34 -28
  143. package/server/{issue-service-singleton-B5ushCvE.js → issue-service-singleton-DmCh7EHj.js} +10 -10
  144. package/server/{issue-service-singleton-DabvBWUp.js → issue-service-singleton-PMx8F1jr.js} +1 -1
  145. package/server/{issues-B6ToV6x1.js → issues-CgnQ1OGQ.js} +2 -2
  146. package/server/{jsonl-parser-Dhflo1SH.js → jsonl-parser-DJOH_O-w.js} +5 -4
  147. package/server/{label-cleanup-BKPJm4Hv.js → label-cleanup-Dv7AV_R1.js} +3 -3
  148. package/server/{label-reconciler-DdWbHEBu.js → label-reconciler--F85rufp.js} +4 -4
  149. package/server/{lifecycle-DfeyBDwA.js → lifecycle-CTdOWYMi.js} +2 -2
  150. package/server/{lifecycle-sycO16hj.js → lifecycle-DDN8ApVY.js} +6 -7
  151. package/server/{lifecycle-io-D8iNBcux.js → lifecycle-io-D-lGdzK3.js} +5 -5
  152. package/server/{lifecycle-io-Bsnr2K4F.js → lifecycle-io-D_zTLvP1.js} +1 -1
  153. package/server/{linear-client-D4zqMnX7.js → linear-client-BQU36QqE.js} +2 -2
  154. package/server/{linear-client-DqhDQO9k.js → linear-client-CY4O_Tu3.js} +1 -1
  155. package/server/linear-mcp-auth-BnU4TYfY.js +280 -0
  156. package/server/linear-mcp-auth-NYBq_oHZ.js +2 -0
  157. package/server/memory-fts-worker.js +1 -1
  158. package/server/{merge-C_ZEhbqI.js → merge-Bpx4jjht.js} +13 -11
  159. package/server/{merge-agent-XrB80vfT.js → merge-agent-DdMVSV2Y.js} +233 -83
  160. package/server/{merge-agent-BQM3a8z5.js → merge-agent-DrXa1CpW.js} +1 -1
  161. package/server/{merge-batch-Bwoyr8Je.js → merge-batch-C5q1c1GX.js} +1 -1
  162. package/server/merge-completeness-BMm8tMyZ.js +277 -0
  163. package/server/merge-completeness-D0ljXbk3.js +3 -0
  164. package/server/{merge-DK23JEdS.js → merge-idOG--29.js} +1 -1
  165. package/server/merge-ops-DdpTiEMt.js +2 -0
  166. package/server/merge-rebase-DGQpYJU3.js +2 -0
  167. package/server/{merge-rebase-C1KIVr0s.js → merge-rebase-xLnMlw5h.js} +3 -3
  168. package/server/merge-set-DH7ot3yz.js +89 -0
  169. package/server/merge-set-DzsOTBg5.js +3 -0
  170. package/server/{merge-sync-DZ9dojJn.js → merge-sync-CQ-LgZ1_.js} +406 -153
  171. package/server/merge-sync-Ca7F5JnQ.js +3 -0
  172. package/server/{merge-train-DxDfBTjr.js → merge-train-DTEMyIu4.js} +18 -8
  173. package/server/{merge-train-deps-CyYQUksx.js → merge-train-deps-CNPJzepw.js} +4 -4
  174. package/server/merge-verification-x3JO8Dtz.js +220 -0
  175. package/server/merged-docker-cleanup-worker-CTpC27Bs.js +107 -0
  176. package/server/merged-docker-cleanup-worker-Cdi9apm-.js +3 -0
  177. package/server/{multipart-parser-Dt8YPN5S.js → multipart-parser-IMSBfePV.js} +2 -2
  178. package/server/{no-resume-mode-Cx3K0hHi.js → no-resume-mode-C5ULAXwO.js} +1 -1
  179. package/server/node_modules/.package-lock.json +27 -27
  180. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/package.json +3 -3
  181. package/server/node_modules/@google-cloud/common/package.json +2 -2
  182. package/server/node_modules/gaxios/build/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  183. package/server/node_modules/gaxios/build/esm/tsconfig.tsbuildinfo +1 -1
  184. package/server/node_modules/gaxios/package.json +1 -1
  185. package/server/node_modules/google-auth-library/build/src/auth/googleauth.js +24 -19
  186. package/server/node_modules/google-auth-library/package.json +1 -1
  187. package/server/node_modules/google-gax/build/protos/google/api/auth.proto +2 -1
  188. package/server/node_modules/google-gax/build/protos/google/api/backend.proto +12 -1
  189. package/server/node_modules/google-gax/build/protos/google/api/billing.proto +1 -1
  190. package/server/node_modules/google-gax/build/protos/google/api/client.proto +165 -53
  191. package/server/node_modules/google-gax/build/protos/google/api/cloudquotas/v1/resources.proto +1 -1
  192. package/server/node_modules/google-gax/build/protos/google/api/cloudquotas/v1beta/quota_adjuster_settings.proto +7 -3
  193. package/server/node_modules/google-gax/build/protos/google/api/cloudquotas/v1beta/resources.proto +1 -1
  194. package/server/node_modules/google-gax/build/protos/google/api/config_change.proto +1 -1
  195. package/server/node_modules/google-gax/build/protos/google/api/context.proto +1 -1
  196. package/server/node_modules/google-gax/build/protos/google/api/control.proto +3 -3
  197. package/server/node_modules/google-gax/build/protos/google/api/distribution.proto +1 -1
  198. package/server/node_modules/google-gax/build/protos/google/api/documentation.proto +1 -1
  199. package/server/node_modules/google-gax/build/protos/google/api/endpoint.proto +1 -1
  200. package/server/node_modules/google-gax/build/protos/google/api/error_reason.proto +186 -1
  201. package/server/node_modules/google-gax/build/protos/google/api/expr/v1alpha1/checked.proto +31 -3
  202. package/server/node_modules/google-gax/build/protos/google/api/expr/v1alpha1/eval.proto +8 -9
  203. package/server/node_modules/google-gax/build/protos/google/api/expr/v1alpha1/explain.proto +1 -2
  204. package/server/node_modules/google-gax/build/protos/google/api/expr/v1alpha1/syntax.proto +20 -22
  205. package/server/node_modules/google-gax/build/protos/google/api/expr/v1alpha1/value.proto +2 -3
  206. package/server/node_modules/google-gax/build/protos/google/api/field_behavior.proto +1 -1
  207. package/server/node_modules/google-gax/build/protos/google/api/field_info.proto +1 -1
  208. package/server/node_modules/google-gax/build/protos/google/api/http.proto +1 -1
  209. package/server/node_modules/google-gax/build/protos/google/api/httpbody.proto +1 -1
  210. package/server/node_modules/google-gax/build/protos/google/api/label.proto +1 -1
  211. package/server/node_modules/google-gax/build/protos/google/api/launch_stage.proto +1 -1
  212. package/server/node_modules/google-gax/build/protos/google/api/log.proto +1 -1
  213. package/server/node_modules/google-gax/build/protos/google/api/logging.proto +1 -1
  214. package/server/node_modules/google-gax/build/protos/google/api/metric.proto +1 -1
  215. package/server/node_modules/google-gax/build/protos/google/api/monitored_resource.proto +1 -1
  216. package/server/node_modules/google-gax/build/protos/google/api/monitoring.proto +1 -1
  217. package/server/node_modules/google-gax/build/protos/google/api/policy.proto +1 -1
  218. package/server/node_modules/google-gax/build/protos/google/api/quota.proto +1 -1
  219. package/server/node_modules/google-gax/build/protos/google/api/resource.proto +1 -1
  220. package/server/node_modules/google-gax/build/protos/google/api/routing.proto +8 -4
  221. package/server/node_modules/google-gax/build/protos/google/api/service.proto +2 -3
  222. package/server/node_modules/google-gax/build/protos/google/api/source_info.proto +1 -1
  223. package/server/node_modules/google-gax/build/protos/google/api/system_parameter.proto +1 -1
  224. package/server/node_modules/google-gax/build/protos/google/api/usage.proto +7 -27
  225. package/server/node_modules/google-gax/build/protos/google/api/visibility.proto +1 -1
  226. package/server/node_modules/google-gax/build/protos/google/longrunning/operations.proto +20 -1
  227. package/server/node_modules/google-gax/build/protos/google/protobuf/any.proto +52 -108
  228. package/server/node_modules/google-gax/build/protos/google/protobuf/compiler/ruby/ruby_generated_code.proto +2 -0
  229. package/server/node_modules/google-gax/build/protos/google/protobuf/cpp_features.proto +21 -1
  230. package/server/node_modules/google-gax/build/protos/google/protobuf/cpp_file_options.proto +24 -0
  231. package/server/node_modules/google-gax/build/protos/google/protobuf/cpp_options.proto +15 -0
  232. package/server/node_modules/google-gax/build/protos/google/protobuf/descriptor.proto +118 -30
  233. package/server/node_modules/google-gax/build/protos/google/protobuf/field_mask.proto +16 -18
  234. package/server/node_modules/google-gax/build/protos/google/protobuf/internal_options.proto +8 -1
  235. package/server/node_modules/google-gax/build/protos/google/protobuf/json/json_enumval_custom_string.proto +26 -0
  236. package/server/node_modules/google-gax/build/protos/google/protobuf/json_enumvalue_options.proto +29 -0
  237. package/server/node_modules/google-gax/build/protos/google/protobuf/json_options.proto +14 -0
  238. package/server/node_modules/google-gax/build/protos/google/protobuf/struct.proto +38 -22
  239. package/server/node_modules/google-gax/build/protos/google/protobuf/test_protos/forced_micro_string.proto +3 -0
  240. package/server/node_modules/google-gax/build/protos/google/protobuf/test_protos/repeated_field_proxy_import_message.proto +14 -0
  241. package/server/node_modules/google-gax/build/protos/google/protobuf/timestamp.proto +9 -8
  242. package/server/node_modules/google-gax/build/protos/google/protobuf/util/json_format_proto3.proto +18 -0
  243. package/server/node_modules/google-gax/build/protos/google/rpc/code.proto +1 -1
  244. package/server/node_modules/google-gax/build/protos/google/rpc/context/attribute_context.proto +7 -2
  245. package/server/node_modules/google-gax/build/protos/google/rpc/context/audit_context.proto +1 -1
  246. package/server/node_modules/google-gax/build/protos/google/rpc/error_details.proto +5 -5
  247. package/server/node_modules/google-gax/build/protos/google/rpc/http.proto +1 -1
  248. package/server/node_modules/google-gax/build/protos/google/rpc/status.proto +1 -2
  249. package/server/node_modules/google-gax/build/protos/google/type/calendar_period.proto +1 -1
  250. package/server/node_modules/google-gax/build/protos/google/type/color.proto +9 -10
  251. package/server/node_modules/google-gax/build/protos/google/type/date.proto +11 -9
  252. package/server/node_modules/google-gax/build/protos/google/type/datetime.proto +17 -17
  253. package/server/node_modules/google-gax/build/protos/google/type/dayofweek.proto +1 -1
  254. package/server/node_modules/google-gax/build/protos/google/type/decimal.proto +11 -13
  255. package/server/node_modules/google-gax/build/protos/google/type/expr.proto +1 -1
  256. package/server/node_modules/google-gax/build/protos/google/type/fraction.proto +1 -1
  257. package/server/node_modules/google-gax/build/protos/google/type/interval.proto +1 -2
  258. package/server/node_modules/google-gax/build/protos/google/type/latlng.proto +4 -5
  259. package/server/node_modules/google-gax/build/protos/google/type/localized_text.proto +3 -3
  260. package/server/node_modules/google-gax/build/protos/google/type/money.proto +1 -2
  261. package/server/node_modules/google-gax/build/protos/google/type/month.proto +1 -1
  262. package/server/node_modules/google-gax/build/protos/google/type/phone_number.proto +20 -15
  263. package/server/node_modules/google-gax/build/protos/google/type/postal_address.proto +39 -39
  264. package/server/node_modules/google-gax/build/protos/google/type/quaternion.proto +4 -4
  265. package/server/node_modules/google-gax/build/protos/google/type/timeofday.proto +11 -8
  266. package/server/node_modules/google-gax/package.json +5 -5
  267. package/server/node_modules/retry-request/package.json +4 -4
  268. package/server/node_modules/teeny-request/package.json +5 -5
  269. package/server/node_modules/undici/README.md +5 -0
  270. package/server/node_modules/undici/docs/docs/api/Client.md +4 -0
  271. package/server/node_modules/undici/docs/docs/api/Dispatcher.md +6 -0
  272. package/server/node_modules/undici/docs/docs/api/Interceptors.md +59 -0
  273. package/server/node_modules/undici/docs/docs/api/MockAgent.md +27 -0
  274. package/server/node_modules/undici/docs/docs/api/MockPool.md +28 -1
  275. package/server/node_modules/undici/docs/docs/index.md +5 -0
  276. package/server/node_modules/undici/lib/cache/memory-cache-store.js +54 -9
  277. package/server/node_modules/undici/lib/cache/sqlite-cache-store.js +7 -1
  278. package/server/node_modules/undici/lib/core/request.js +13 -2
  279. package/server/node_modules/undici/lib/core/util.js +6 -1
  280. package/server/node_modules/undici/lib/dispatcher/agent.js +3 -3
  281. package/server/node_modules/undici/lib/dispatcher/client-h1.js +42 -8
  282. package/server/node_modules/undici/lib/dispatcher/client-h2.js +34 -43
  283. package/server/node_modules/undici/lib/global.js +36 -16
  284. package/server/node_modules/undici/lib/handler/cache-handler.js +269 -61
  285. package/server/node_modules/undici/lib/handler/cache-revalidation-handler.js +13 -3
  286. package/server/node_modules/undici/lib/handler/redirect-handler.js +5 -2
  287. package/server/node_modules/undici/lib/handler/retry-handler.js +30 -4
  288. package/server/node_modules/undici/lib/interceptor/cache.js +159 -52
  289. package/server/node_modules/undici/lib/interceptor/decompress.js +9 -2
  290. package/server/node_modules/undici/lib/mock/mock-interceptor.js +25 -7
  291. package/server/node_modules/undici/lib/mock/mock-utils.js +39 -10
  292. package/server/node_modules/undici/lib/util/cache.js +372 -68
  293. package/server/node_modules/undici/lib/util/date.js +23 -6
  294. package/server/node_modules/undici/lib/web/cookies/util.js +78 -8
  295. package/server/node_modules/undici/lib/web/fetch/body.js +2 -1
  296. package/server/node_modules/undici/lib/web/fetch/response.js +1 -3
  297. package/server/node_modules/undici/package.json +2 -2
  298. package/server/node_modules/undici/types/client.d.ts +2 -2
  299. package/server/node_modules/undici/types/dispatcher.d.ts +3 -3
  300. package/server/node_modules/undici/types/mock-interceptor.d.ts +5 -1
  301. package/server/{orphan-proposed-reconciler-BTkDrl4R.js → orphan-proposed-reconciler-CWmOdM9-.js} +1 -1
  302. package/server/{orphan-proposed-reconciler-neK8dHQk.js → orphan-proposed-reconciler-Dg6U4ADZ.js} +24 -15
  303. package/server/package-lock.json +28 -28
  304. package/server/package.json +1 -1
  305. package/server/{pan-dir-DeVUgwA7.js → pan-dir-ubraCiUg.js} +24 -10
  306. package/server/{paths-_zEts6wc.js → paths-cXmOwSbh.js} +2 -2
  307. package/server/pending-lifecycle-claim-DEteYdS9.js +110 -0
  308. package/server/{pickup-Dd0Znxxy.js → pickup-D8xtG1J2.js} +17 -16
  309. package/server/pipeline-membership-BGSvkT2M.js +3 -0
  310. package/server/pipeline-membership-CrAPLYtf.js +57 -0
  311. package/server/{pipeline-membership-0HaEGDlH.js → pipeline-membership-gather-CET40frr.js} +177 -109
  312. package/server/pipeline-membership-gather-DTfcgxLl.js +3 -0
  313. package/server/{pipeline-notifier-D0ykk59O.js → pipeline-notifier-BuQ0e4hF.js} +2 -2
  314. package/server/{pipeline-notifier-6iCJplFZ.js → pipeline-notifier-ImNXknf0.js} +1 -1
  315. package/server/post-merge-lifecycle-worker-DbO10pum.js +50 -0
  316. package/server/{project-pipelines-2sK1apsO.js → project-pipelines-Bim6bThI.js} +2 -2
  317. package/server/project-repos-C0nuoBGv.js +98 -0
  318. package/server/project-repos-CRE6Ykow.js +3 -0
  319. package/server/projects-B03Wr-xc.js +3 -0
  320. package/server/{prompts-Dp4Tpk39.js → prompts-BEx08AIu.js} +2 -2
  321. package/server/{providers-DKkBXhxU.js → providers-D7IluJe0.js} +1 -1
  322. package/server/{providers-DV7ec8l7.js → providers-evXhiQeg.js} +7 -7
  323. package/server/public/assets/{chunk-BO2N2NFS-CltymLRg.js → chunk-BO2N2NFS-D1s4-Sqp.js} +4 -4
  324. package/server/public/assets/{diagram-OG6HWLK6-D2f6pjgA.js → diagram-OG6HWLK6-1gdMoSF7.js} +1 -1
  325. package/server/public/assets/{dist-BWR4qFiV.js → dist-CxAOHbil.js} +1 -1
  326. package/server/public/assets/{dist-DEmlBBNQ.js → dist-DqDRYW6P.js} +3 -3
  327. package/server/public/assets/{ganttDiagram-6RSMTGT7-DnfiViPK.js → ganttDiagram-6RSMTGT7-BYex-Ec7.js} +1 -1
  328. package/server/public/assets/{highlighted-body-OFNGDK62-B8Wrmj9H.js → highlighted-body-OFNGDK62-DlVkiG0S.js} +1 -1
  329. package/server/public/assets/index-Cc7cnFC4.css +1 -0
  330. package/server/public/assets/index-K0hAYCgV.js +807 -0
  331. package/server/public/assets/{linear-C9zFQpkX.js → linear-B4cuEFmO.js} +1 -1
  332. package/server/public/assets/mermaid-GHXKKRXX-DyDHFXHV.js +1 -0
  333. package/server/public/assets/{pieDiagram-4H26LBE5-lR8H7Yjd.js → pieDiagram-4H26LBE5-CBHNBIJQ.js} +1 -1
  334. package/server/public/assets/{prod-B1jCQihw.js → prod-CN2nHBvX.js} +4 -4
  335. package/server/public/assets/{quadrantDiagram-W4KKPZXB-CVQ2guem.js → quadrantDiagram-W4KKPZXB-Bom87VOQ.js} +1 -1
  336. package/server/public/assets/{sankeyDiagram-5OEKKPKP-eD1RB4gm.js → sankeyDiagram-5OEKKPKP-UrBeyLxk.js} +1 -1
  337. package/server/public/assets/{xychartDiagram-2RQKCTM6-ChEC6dQn.js → xychartDiagram-2RQKCTM6-DhkbrIxR.js} +1 -1
  338. package/server/public/index.html +2 -2
  339. package/server/{pull-requests--Ib2jTgy.js → pull-requests-Cv7LxzUN.js} +1 -1
  340. package/server/{pull-requests-CXIhdCYD.js → pull-requests-DHWiKxo7.js} +19 -10
  341. package/server/{queries-6d7Cdtm7.js → queries-DHJm7bTd.js} +1134 -203
  342. package/server/{rally-B708-nZn.js → rally-B71M9f4o.js} +3 -3
  343. package/server/rally-YDjU513q.js +3 -0
  344. package/server/{rally-api-yjQ0TfHd.js → rally-api-D5uXN08-.js} +1 -1
  345. package/server/{rally-api-nY0ZANw3.js → rally-api-Dkqmok65.js} +2 -2
  346. package/server/{rally-client-B1EJhfV0.js → rally-client-Bfqm6XI4.js} +4 -4
  347. package/server/{rally-client-CULK2XAY.js → rally-client-CxsA6ExK.js} +1 -1
  348. package/server/{reap-terminal-sessions-MWnqdLCJ.js → reap-terminal-sessions-BQ23nriz.js} +2 -2
  349. package/server/{reap-terminal-sessions-N3BTkmX_.js → reap-terminal-sessions-CvmwaqKv.js} +2 -2
  350. package/server/{rebuild-stack-Dp4eLkt4.js → rebuild-stack-0EEYReVZ.js} +36 -36
  351. package/server/rebuild-stack-qeRqHZxH.js +4 -0
  352. package/server/{reconstruct-cache-uWbZfjms.js → reconstruct-cache-BbYFsqLa.js} +7 -6
  353. package/server/record-CtroO946.js +3 -0
  354. package/server/record-update-DH6dLJID.js +3 -0
  355. package/server/{record-update-Dq0t2uBG.js → record-update-Z0QCxmMp.js} +124 -34
  356. package/server/{recovery-trip-BJtIQuag.js → recovery-trip-eJe26h-f.js} +2 -2
  357. package/server/{release-engine-DZpmGGzb.js → release-engine-lPUp-MTd.js} +5 -5
  358. package/server/{release-set-hnXd_kga.js → release-set-BwGeyZKX.js} +3 -3
  359. package/server/{remote-Br-ZWVIP.js → remote-BCd02Es1.js} +3 -3
  360. package/server/{remote-4tiENDaI.js → remote-CVGUhXMV.js} +3 -3
  361. package/server/{remote-agents-CRCg1L4H.js → remote-agents-C1bssi41.js} +2 -2
  362. package/server/{remote-agents-nmty1mLu.js → remote-agents-C_VxssLU.js} +300 -46
  363. package/server/{remote-completion-BbWNd10K.js → remote-completion-DAB0P706.js} +12 -12
  364. package/server/resume-u9byntrq.js +3 -0
  365. package/server/{review-agent-DJRO8EG8.js → review-agent-CD4RCI0Y.js} +1 -1
  366. package/server/{review-agent-sKkE1FEL.js → review-agent-CHhI66UP.js} +61 -44
  367. package/server/{review-artifacts-BLbSC4ke.js → review-artifacts-DSMRIfuJ.js} +7 -6
  368. package/server/{review-context-BgX3lcCx.js → review-context-oFuBbiEE.js} +69 -25
  369. package/server/{in-flight-guard-aQ1IxeI3.js → review-convoy-liveness-CpzrcJ5F.js} +3 -44
  370. package/server/review-status-BZH8h-6W.js +3 -0
  371. package/server/review-status-emit-CUExtHd5.js +50 -0
  372. package/server/{review-status-enrichment-tbOn_A_u.js → review-status-enrichment-QV_hQkgS.js} +4 -4
  373. package/server/{review-status-source-CxuEjLGg.js → review-status-source-CpvJnvnQ.js} +24 -3
  374. package/server/review-status-source-ylw5QZUR.js +3 -0
  375. package/server/{review-status-sync-BhSQ0d0l.js → review-status-sync-483sujRo.js} +10 -5
  376. package/server/{review-status-sync-To3-iS-N.js → review-status-sync-NaWvI9Xf.js} +1 -1
  377. package/server/review-status-yljtTd-q.js +7521 -0
  378. package/server/{review-verdict-feedback-C1Kg8n7t.js → review-verdict-feedback-BPDn4li_.js} +1 -1
  379. package/server/{review-verdict-feedback-CTRNtzXO.js → review-verdict-feedback-CELeUinh.js} +48 -8
  380. package/server/{rollup-WA0VD-Rr.js → rollup-DTNvelz9.js} +8 -8
  381. package/server/{rollup-B53Y81xK.js → rollup-DYZfq1c4.js} +1 -1
  382. package/server/{scanner-D2743cp8.js → scanner-CV35oSn4.js} +42 -14
  383. package/server/{sequence-io-Cg0zYj_E.js → sequence-io-DF_8iuhV.js} +4 -4
  384. package/server/{sequencer-agent-BGY8gjg-.js → sequencer-agent-B2WeCtGi.js} +5 -5
  385. package/server/server.js +3899 -672
  386. package/server/{service-DCpB_SGd.js → service-Br9rpBNA.js} +83 -65
  387. package/server/{session-fork-BQ8_6H32.js → session-fork-D0LY152N.js} +2 -2
  388. package/server/{session-history-CVZDpS3c.js → session-history-BUyK29eq.js} +4 -4
  389. package/server/{settings-BZ5m1UCl.js → settings-Bse1Pdcj.js} +3 -3
  390. package/server/settings-CdvIF84R.js +2 -0
  391. package/server/{settings-ylxwqwQG.js → settings-CvVGqNEs.js} +3 -2
  392. package/server/{shadow-engineering-BlxG6Xye.js → shadow-engineering-BWLa8ODz.js} +2 -2
  393. package/server/{shadow-state-Dh-HzF2J.js → shadow-state-B4fpKxOO.js} +2 -2
  394. package/server/{shadow-state-C2_epgx2.js → shadow-state-FV6PHfEW.js} +1 -1
  395. package/server/{shadow-utils-4bvjn9b3.js → shadow-utils-D7asqxOZ.js} +2 -2
  396. package/server/{ship-log-ClSMIzZX.js → ship-log-xplJ8t75.js} +1 -1
  397. package/server/{smart-compaction-CHIxLr_d.js → smart-compaction-CPp2Ykf6.js} +1 -1
  398. package/server/{smart-compaction-r4pHQBIr.js → smart-compaction-D3U_79f-.js} +8 -7
  399. package/server/{spawn-planning-session-KC_UduxD.js → spawn-planning-session-1nFi3gfk.js} +1 -1
  400. package/server/{spawn-planning-session-DWAorh2B.js → spawn-planning-session-DGfZ5B8D.js} +30 -23
  401. package/server/{specialist-completion-BXhav38U.js → specialist-completion-Br48eiDP.js} +1 -1
  402. package/server/{specialist-context-DtrYvGJ-.js → specialist-context-cVbGnTa3.js} +5 -5
  403. package/server/{specialist-handoff-logger-C45ouoZ6.js → specialist-handoff-logger-DK-GTz4s.js} +2 -2
  404. package/server/{specialist-logs-DJ3RzKxW.js → specialist-logs-Cl5-hqT8.js} +3 -3
  405. package/server/{specialists-JVO00bs7.js → specialists-CNfYO3G2.js} +1634 -457
  406. package/server/{specialists-DyFeedjn.js → specialists-Cicieuzu.js} +21 -19
  407. package/server/{specialists-D5fRZXmN.js → specialists-JHsdU3pA.js} +1 -1
  408. package/server/{specialists-DVj0hvaL.js → specialists-Tdezg_6N.js} +1 -1
  409. package/server/specs-Bt7WJDoC.js +3 -0
  410. package/server/src-CRmCHlma.js +11408 -0
  411. package/server/{src-CG9mCkP6.js → src-Ck028hjO.js} +6 -6
  412. package/server/{src-CMTQGyCK.js → src-UWcGe0Ix.js} +5 -5
  413. package/server/stack-health-CJLMrLBl.js +3 -0
  414. package/server/{stack-health-puygdaMd.js → stack-health-DqSqx0zv.js} +68 -12
  415. package/server/{stale-task-claims-BbFwCTb0.js → stale-task-claims-CYFOUNlT.js} +4 -4
  416. package/server/{staleness-Cbl_w4Bw.js → staleness-BQ-0gMYK.js} +1 -1
  417. package/server/{staleness-Bpy41ngS.js → staleness-D47CUJok.js} +1 -1
  418. package/server/{state-home-CIGjwNfJ.js → state-home-BYV7qZTW.js} +2 -2
  419. package/server/{state-mapping-BL_-3Yt8.js → state-mapping-BVldLhBf.js} +1 -1
  420. package/server/{state-migrate-Dkzaxvny.js → state-migrate-CvvBtS0Y.js} +4 -4
  421. package/server/{stuck-remediation-sY_MHHgQ.js → stuck-remediation-Wt0UVvu1.js} +1 -1
  422. package/server/{stuck-remediation-CzEov_fq.js → stuck-remediation-mkLC6G_t.js} +360 -26
  423. package/server/{substrate-bug-weights-service-BH66lhm7.js → substrate-bug-weights-service-XfLAKnmK.js} +3 -3
  424. package/server/{summary-fork-D8bXjCr7.js → summary-fork-CD7GOts0.js} +2 -2
  425. package/server/{summary-fork-DHhJIsAL.js → summary-fork-xiXBnWG9.js} +78 -12
  426. package/server/supervisor/{injection-budget-C1iPirFS.js → injection-budget-B5SbvDx2.js} +2 -41
  427. package/server/supervisor/{paths-DehGY2Fj.js → paths-K3noE4N_.js} +1 -1
  428. package/server/supervisor/pty-supervisor.js +49 -2
  429. package/server/supervisor/pty-token-B7lp0ElT.js +43 -0
  430. package/server/{supervisor-BO-Zk_h-.js → supervisor-DL788vos.js} +3 -3
  431. package/server/supervisor-UWiQNK-y.js +2 -0
  432. package/server/{swarm-readiness-CQ_fwUWF.js → swarm-readiness-BV14DF5N.js} +3 -3
  433. package/server/{system-prerequisites-Bza0ffAh.js → system-prerequisites-pdWG6ZQs.js} +56 -29
  434. package/server/{teardown-workspace-CEgauF4U.js → teardown-workspace-l2F4_zim.js} +15 -16
  435. package/server/{test-agent-queue-DXDt0Xa-.js → test-agent-queue-qakFIIGz.js} +6 -6
  436. package/server/{test-verdict-CmUBK5cT.js → test-verdict-BJYDggMm.js} +1 -1
  437. package/server/{test-verdict-DFjjIHR5.js → test-verdict-Gw-btEfb.js} +1 -1
  438. package/server/{tldr-daemon-DL566HbH.js → tldr-daemon-BKOYB616.js} +1 -1
  439. package/server/{tldr-daemon-BDtLOIlO.js → tldr-daemon-CBaWkV9k.js} +2 -2
  440. package/server/{tmux-ftABRAmc.js → tmux-B1Wbxz5o.js} +3 -3
  441. package/server/{tmux-DoThH6aj.js → tmux-DQ6jB76i.js} +1 -1
  442. package/server/tmux-dedup-DbN6MGzM.js +892 -0
  443. package/server/{token-CsOhvw42.js → token-Cxbk023d.js} +2 -2
  444. package/server/{token-util-CTmczIfW.js → token-util-CLq2MmQt.js} +1 -1
  445. package/server/token-util-zlz9U0ki.js +3 -0
  446. package/server/{tracker-config-B4itFzDo.js → tracker-config-DZ8Zn2nQ.js} +2 -2
  447. package/server/{tracker-utils-tnxxqROg.js → tracker-utils-L0FKtjq2.js} +3 -3
  448. package/server/{traefik-connect-m73vGebA.js → traefik-connect-bNX6jKkb.js} +1 -1
  449. package/server/{tunnel-B2vxjx_b.js → tunnel-BAm1XgjG.js} +3 -3
  450. package/server/{tunnel-Cgj-IGIl.js → tunnel-CjSnHdTc.js} +1 -1
  451. package/server/{types-BBNjPcqU.js → types-q67TYYg5.js} +1 -1
  452. package/server/uat-promote-verification-CKB9ZrKC.js +92 -0
  453. package/server/uat-train-Cu-4nvbf.js +2 -0
  454. package/server/uat-train-D5UjcyAa.js +0 -0
  455. package/server/validate-Cxsx5Uz1.js +179 -0
  456. package/server/{validation-CIi6pnI2.js → validation-DEaTZafj.js} +1 -1
  457. package/server/{validation-B5JxoPUS.js → validation-VZgJxmqc.js} +4 -4
  458. package/server/{verification-artifact-C-lIHfUa.js → verification-artifact-C85cRTc_.js} +1 -1
  459. package/server/{verification-artifact-BcnIbigL.js → verification-artifact-g3yuxQDL.js} +1 -1
  460. package/server/{verification-runner-CDj4lD4t.js → verification-runner-DlZI8yhw.js} +1 -1
  461. package/server/{verification-runner-Br0S_Ous.js → verification-runner-KDZIsBj4.js} +114 -107
  462. package/server/{vtt-parser-DKpNNW5i.js → vtt-parser-Jr94BF3Y.js} +1 -1
  463. package/server/{work-agent-prompt-Yb2bd3Fq.js → work-agent-prompt-C-vuP3_J.js} +20 -9
  464. package/server/workflows-CHrx_hcW.js +2 -0
  465. package/server/{workflows-C9WmILql.js → workflows-D0oip4eV.js} +161 -78
  466. package/server/{workspace-DuUdndHe.js → workspace-BqFg__wH.js} +1 -1
  467. package/server/{workspace-BVl4rihN.js → workspace-C0fH3aek.js} +3 -3
  468. package/server/workspace-anchor-drift-B4gMRHl4.js +3 -0
  469. package/server/workspace-anchor-drift-CZKofakh.js +224 -0
  470. package/server/{workspace-config-cEGcO6UT.js → workspace-config-B123aZl-.js} +1 -1
  471. package/server/workspace-manager-CDTKjjdU.js +3 -0
  472. package/server/{workspace-manager-hLUv3ADC.js → workspace-manager-CwO-Hek7.js} +206 -116
  473. package/server/{workspace-metadata-CskwzzhL.js → workspace-metadata-CQv00QwK.js} +2 -2
  474. package/server/{workspace-metadata-DNpMixRq.js → workspace-metadata-D4M8BM4W.js} +1 -1
  475. package/server/{workspaces-hWvy9eKs.js → workspaces-j1e_6aAT.js} +736 -290
  476. package/sync-sources/dev-skills/pan-dashboard-restart/SKILL.md +34 -10
  477. package/sync-sources/hooks/linear-mcp-auth-hook +97 -0
  478. package/sync-sources/hooks/record-cost-event.js +6 -4
  479. package/sync-sources/rules/ask-user-question-self-contained.md +9 -0
  480. package/sync-sources/skills/okf/README.md +11 -3
  481. package/sync-sources/skills/okf/SKILL.md +12 -1
  482. package/sync-sources/skills/okf/docs/USAGE.md +15 -0
  483. package/sync-sources/skills/okf/references/overdeck.md +28 -0
  484. package/sync-sources/skills/pan-close/SKILL.md +5 -3
  485. package/sync-sources/skills/pan-flywheel/SKILL.md +18 -1
  486. package/sync-sources/skills/pan-knowledge/SKILL.md +10 -0
  487. package/sync-sources/skills/pan-orders/SKILL.md +33 -0
  488. package/sync-sources/skills/pan-peer-review/SKILL.md +195 -0
  489. package/sync-sources/skills/pan-reload/SKILL.md +3 -3
  490. package/sync-sources/skills/pan-restart/SKILL.md +5 -4
  491. package/sync-sources/skills/pan-review/SKILL.md +7 -1
  492. package/sync-sources/skills/pan-start/SKILL.md +4 -0
  493. package/sync-sources/skills/pan-sync-main/SKILL.md +9 -8
  494. package/sync-sources/skills/pipeline-status/SKILL.md +10 -1
  495. package/sync-sources/skills/workspace-add-repo/SKILL.md +16 -1
  496. package/sync-sources/templates/traefik/dynamic/overdeck.yml.template +10 -0
  497. package/server/activity-logger-OEUBdfZ8.js +0 -3
  498. package/server/agent-state-Bg0lhqwj.js +0 -3
  499. package/server/agents-FlIgQ3ql.js +0 -3
  500. package/server/archive-planning-zkJb3BeM.js +0 -3
  501. package/server/cli-BsVIHwzC.js +0 -3
  502. package/server/context-layers-B3Nt58jl.js +0 -4
  503. package/server/context-layers-ZYFcWiyc.js +0 -165
  504. package/server/conversation-service-Up7FEzIC.js +0 -3
  505. package/server/deacon-DYSEJb48.js +0 -4
  506. package/server/deacon-swarm-9jRLS5Ke.js +0 -2
  507. package/server/deploy-window-CM6W1-c6.js +0 -3
  508. package/server/dist-Bd3vn0Hw.js +0 -3
  509. package/server/flywheel-DMCUzDWg.js +0 -2
  510. package/server/flywheel-DSSpWmqF.js +0 -522
  511. package/server/flywheel-DcBkQvgE.js +0 -207
  512. package/server/flywheel-merge-order-C-6zRLvM.js +0 -2
  513. package/server/flywheel-merge-order-DxbQKE1d.js +0 -244
  514. package/server/forge-B-ZWyTRm.js +0 -2
  515. package/server/forge-Ch9gCFod.js +0 -270
  516. package/server/git-utils-Dry_Ka_D.js +0 -3
  517. package/server/github-pr-lookup-BRbDW-qk.js +0 -44
  518. package/server/hume-B_DbflNM.js +0 -3
  519. package/server/inspect-agent-ch-F-5Ci.js +0 -2
  520. package/server/launcher-generator-CHVm7bGT.js +0 -379
  521. package/server/layers-DzxSTGNA.js +0 -93
  522. package/server/merge-blockers-BsFjGrQ8.js +0 -41
  523. package/server/merge-ops-DlB1IM0Y.js +0 -2
  524. package/server/merge-set-DLz0MkGT.js +0 -139
  525. package/server/merge-set-DnSYdBEp.js +0 -3
  526. package/server/merge-sync-SSv3E-pl.js +0 -3
  527. package/server/merge-verification-CSizH3HY.js +0 -124
  528. package/server/projects-9SkRpES9.js +0 -3
  529. package/server/public/assets/index-CUr1xv8w.css +0 -1
  530. package/server/public/assets/index-CsSuZQBI.js +0 -802
  531. package/server/public/assets/mermaid-GHXKKRXX-BUAB8hqt.js +0 -1
  532. package/server/rally-njs_mJrt.js +0 -3
  533. package/server/rebuild-stack-kA7XngID.js +0 -3
  534. package/server/record-t6V-3Dcj.js +0 -3
  535. package/server/record-update-DACtKh6_.js +0 -3
  536. package/server/resume-CcKqnTvE.js +0 -3
  537. package/server/review-status-A7quS5KJ.js +0 -1454
  538. package/server/review-status-C6n6-9f_.js +0 -3
  539. package/server/settings-D0OSwos5.js +0 -2
  540. package/server/specs-nN45DG2X.js +0 -3
  541. package/server/src-U7_kTPEE.js +0 -4733
  542. package/server/stack-health-Df0YEZKa.js +0 -3
  543. package/server/supervisor-BPy-o1A8.js +0 -2
  544. package/server/token-util-DrHg8abn.js +0 -3
  545. package/server/tracker-utils-BePq_oj-.js +0 -3
  546. package/server/uat-train-CuEn0t9M.js +0 -2152
  547. package/server/uat-train-cKfM-_WW.js +0 -2
  548. package/server/workflows-D90rMOya.js +0 -2
  549. package/server/workspace-manager-ZTdJAy9M.js +0 -3
@@ -1,44 +1,49 @@
1
- import { $n as resolveIssueIdSync, Br as getOverdeckHome, Jn as extractPrefixSync, Nr as encodeClaudeProjectDir, Tn as init_projects, Vr as init_paths, Xt as isStatePlaneOnlyStatus, Yn as init_issue_id, Yt as init_state_plane, Zn as parseIssueIdSync, ar as GitError, ir as FsError, kn as listProjectsSync, mn as findProjectByTeamSync, mr as init_errors, qn as extractNumberSync, t as init_config_yaml, tt as resolveModel, un as extractTeamPrefix, yn as getProjectSync, zn as resolveProjectFromIssueSync } from "./config-yaml-DvyMuOle.js";
2
- import { d as rejectUnsafeDashboardMutationRequest, ht as getHeaderFromMap, it as getWorkAgentLifecycleStateSync, l as rejectUnauthorizedDashboardRequest, n as _serverManagedMerges, ot as spawnPanCli, xt as jsonResponse, yt as httpHandler } from "./specialists-JVO00bs7.js";
3
- import { a as init_activity_logger, n as emitActivityEntrySync } from "./activity-logger-DDlOIAML.js";
4
- import { d as getOverdeckDatabaseSync, f as init_infra } from "./infra-CzaSOgul.js";
5
- import { $ as init_child_env, H as sessionExists, M as listSessionNames, Q as buildChildEnvWithoutTmuxSync, i as capturePane, w as init_tmux } from "./tmux-ftABRAmc.js";
6
- import { a as init_event_store, n as getEventStore } from "./event-store-tdiY5eDZ.js";
7
- import { _ as setAutoMerge, b as setReviewStatusSync, c as getReviewStatusSync, d as loadReviewStatuses, l as init_review_status, p as markWorkspaceStuck, v as setDeaconIgnored } from "./review-status-A7quS5KJ.js";
8
- import { _ as init_queue_position, a as EventStoreService, g as findPositionInQueueSync, h as computeQueuePositionFromStatusSync, s as init_domain_services } from "./issue-lifecycle-CreaCkjW.js";
9
- import { o as getPricingSync, s as init_cost, t as calculateCostSync } from "./cost-Ca0YTWDw.js";
10
- import { Cr as getAgentRuntimeStateSync, Hn as getAgentState, Kt as transitionIssueToInReview, Tr as saveAgentRuntimeState, X as messageAgent, b as init_agents, i as listRunningAgents, lt as spawnAgent } from "./queries-6d7Cdtm7.js";
11
- import { f as CostWriter, l as CostDoorLive } from "./service-DCpB_SGd.js";
12
- import { a as init_tracker_config, t as getGitHubConfig } from "./tracker-config-B4itFzDo.js";
13
- import { i as resolveGitHubIssueSync, n as init_tracker_utils } from "./tracker-utils-tnxxqROg.js";
14
- import { o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-Bb4XeV2x.js";
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 init_paths, ei as encodeClaudeProjectDir, gn as isStatePlaneOnlyStatus, gr as init_issue_id, hn as init_state_plane, hr as extractPrefixSync, mr as extractNumberSync, si as getOverdeckHome, t as init_config_yaml, tt as resolveModel, vr as parseIssueIdSync, zn as getProjectSync } from "./config-yaml-CmOPzmBb.js";
2
+ import { Et as httpHandler, Ot as jsonResponse, St as getHeaderFromMap, _t as rejectUnauthorizedDashboardRequest, it as getWorkAgentLifecycleStateSync, n as _serverManagedMerges, ot as spawnPanCli, yt as rejectUnsafeDashboardMutationRequest } from "./specialists-CNfYO3G2.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-BjuxvjdS.js";
5
+ import { H as sessionExists, M as listSessionNames, et as buildChildEnvWithoutTmuxSync, i as capturePane, tt as init_child_env, w as init_tmux } from "./tmux-B1Wbxz5o.js";
6
+ import { a as init_event_store, n as getEventStore } from "./event-store-zY5MJHgF.js";
7
+ import { S as setReviewStatusSync, b as setDeaconIgnored, f as init_review_status, g as markWorkspaceStuck, m as loadReviewStatuses, r as clearFeedbackDeliveryStuck, u as getReviewStatusSync, y as setAutoMerge } from "./review-status-yljtTd-q.js";
8
+ import { _ as findPositionInQueueSync, a as EventStoreService, g as computeQueuePositionFromStatusSync, s as init_domain_services, v as init_queue_position } from "./issue-lifecycle-C4Zj0WmE.js";
9
+ import { o as getPricingSync, s as init_cost, t as calculateCostSync } from "./cost-Bgcub5kW.js";
10
+ import { Ir as getAgentRuntimeStateSync, Qn as decideResumeGate, Rr as saveAgentRuntimeState, 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-DHJm7bTd.js";
11
+ import { f as CostWriter, l as CostDoorLive } from "./service-Br9rpBNA.js";
12
+ import { a as init_tracker_config, t as getGitHubConfig } from "./tracker-config-DZ8Zn2nQ.js";
13
+ import { n as resolveGitHubIssueSync, t as init_tracker_utils } from "./tracker-utils-L0FKtjq2.js";
14
+ import { o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-DvMTQSOS.js";
15
+ import { r as notifyPipelineSync, t as init_pipeline_notifier } from "./pipeline-notifier-BuQ0e4hF.js";
15
16
  import { a as PAN_DIRNAME, i as PAN_CONTINUE_FILENAME, p as init_types } from "./types-hraoaQIp.js";
16
- import { o as init_merge_sync, r as getAllActiveQueues } from "./merge-sync-DZ9dojJn.js";
17
- import { A as init_xbrief_index, M as readXBriefDocument, _ as XBRIEF_INSPECTION_POLICIES, c as mergeRecordStatusOverrides, g as serializeXBriefDocument, k as findXBriefByIssue, o as init_io, r as findPlan, s as isPlanningComplete, u as readPlan, v as init_types$1 } from "./io-B3_AHDfr.js";
18
- import { it as findConversationForCostSessionSync, k as init_conversations } from "./conversations-DbOs1e9Q.js";
19
- import { i as normalizeModelOverrideSync, r as init_model_validation } from "./launcher-generator-CHVm7bGT.js";
20
- import { f as init_config, m as loadConfigSync$1 } from "./config-CCvjQf27.js";
21
- import { a as init_stack_health, i as getWorkspaceStackHealth, n as collectDockerContainerLifecycleSnapshot } from "./stack-health-puygdaMd.js";
22
- import { a as criticalPath, l as init_dag, t as actionableDoc } from "./dag-CdOjJVDT.js";
23
- import { A as withConcurrencyLimit, E as verifyAppCanMerge, f as init_github_app, k as init_concurrency, m as isIntegrationPermissionError } from "./github-app-CMBdIFBQ.js";
24
- import { a as readEventsFromLineSync, i as init_events, l as init_wal, o as readEventsSync, r as getLastEventMetadataSync, t as appendCostEventSync } from "./events-CC1dgUpx.js";
25
- import { n as getContainersReferencingWorkspacePath, r as init_workspace_manager } from "./workspace-manager-hLUv3ADC.js";
26
- import { r as init_devcontainer_renderer, t as DEVCONTAINER_DIRNAME } from "./devcontainer-renderer-CtUgrVKW.js";
27
- import { a as init_jsonl_parser, t as getActiveSessionModelSync } from "./jsonl-parser-Dhflo1SH.js";
28
- import { r as init_in_flight_guard, t as createInFlightGuard } from "./in-flight-guard-aQ1IxeI3.js";
29
- import { i as findWorkspacePath, o as init_archive_planning } from "./archive-planning-DYrYojxl.js";
30
- import { a as loadWorkspaceMetadataSync, i as listWorkspaceMetadataSync } from "./workspace-metadata-CskwzzhL.js";
31
- import { n as enrichReviewStatusFromSessions } from "./review-status-enrichment-tbOn_A_u.js";
32
- import { n as generateDailySummary, r as init_cli } from "./cli-vBeXbPrq.js";
33
- import { a as getDiffStat, i as getDiffBase, o as init_review_context, r as getChangedFiles } from "./review-context-BgX3lcCx.js";
34
- import { n as getTldrDaemonServiceSync, r as init_tldr_daemon } from "./tldr-daemon-BDtLOIlO.js";
35
- 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-XrB80vfT.js";
36
- import { F as enqueueMerge, I as getAllActiveQueues$1, L as getCurrentMerge, P as dequeueMerge, z as markMergeProcessing } from "./merge-C_ZEhbqI.js";
37
- import { n as init_release_set, t as getReleaseSetSync } from "./release-set-hnXd_kga.js";
38
- import { i as init_conflict_gate, r as getCachedConflictGateMergeability } from "./conflict-gate-CmrYpa47.js";
39
- import { r as runVerificationForIssue } from "./verification-runner-Br0S_Ous.js";
40
- import { t as teardownWorkspace } from "./teardown-workspace-CEgauF4U.js";
41
- import { n as init_rebuild_stack, t as composeProjectNameForWorkspace } from "./rebuild-stack-Dp4eLkt4.js";
17
+ import { i as getAllActiveQueues, s as init_merge_sync } from "./merge-sync-CQ-LgZ1_.js";
18
+ import { l as resolveWorkspaceRepoRootsSync, r as init_project_repos } from "./project-repos-C0nuoBGv.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-VHvc0Ssp.js";
20
+ import { it as findConversationForCostSessionSync, k as init_conversations } from "./conversations-BUpYsOZg.js";
21
+ import { h as normalizeModelOverrideSync, m as init_model_validation } from "./tmux-dedup-DbN6MGzM.js";
22
+ import { f as init_config, m as loadConfigSync$1 } from "./config-Dr3pW6w6.js";
23
+ import { a as getWorkspaceStackHealth, n as collectDockerContainerLifecycleSnapshot, r as composeProjectNameForWorkspace, s as init_stack_health } from "./stack-health-DqSqx0zv.js";
24
+ import { a as criticalPath, l as init_dag, t as actionableDoc } from "./dag-ombYYt4s.js";
25
+ import { E as verifyAppCanMerge, M as withConcurrencyLimit, f as init_github_app, j as init_concurrency, m as isIntegrationPermissionError } from "./github-app-CQ1Lo6LA.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-D9PR1IC0.js";
27
+ import { n as getContainersReferencingWorkspacePath, r as init_workspace_manager } from "./workspace-manager-CwO-Hek7.js";
28
+ import { r as init_devcontainer_renderer, t as DEVCONTAINER_DIRNAME } from "./devcontainer-renderer-68CSCRnu.js";
29
+ import { a as init_jsonl_parser, t as getActiveSessionModelSync } from "./jsonl-parser-DJOH_O-w.js";
30
+ import { i as findWorkspacePath } from "./archive-planning-C0lAbNB_.js";
31
+ import { n as init_merge_verification, t as handlePostRebaseVerificationDeferral } from "./merge-verification-x3JO8Dtz.js";
32
+ import { r as init_in_flight_guard, t as createInFlightGuard } from "./in-flight-guard-Bq3epG58.js";
33
+ import { a as loadWorkspaceMetadataSync, i as listWorkspaceMetadataSync } from "./workspace-metadata-CQv00QwK.js";
34
+ import { n as enrichReviewStatusFromSessions } from "./review-status-enrichment-QV_hQkgS.js";
35
+ import { n as generateDailySummary, r as init_cli } from "./cli-oCWYA1pE.js";
36
+ import { a as getDiffStat, i as getDiffBase, o as init_review_context, r as getChangedFiles } from "./review-context-oFuBbiEE.js";
37
+ import { n as getTldrDaemonServiceSync, r as init_tldr_daemon } from "./tldr-daemon-CBaWkV9k.js";
38
+ 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-DdMVSV2Y.js";
39
+ import { F as enqueueMerge, I as getAllActiveQueues$1, L as getCurrentMerge, P as dequeueMerge, z as markMergeProcessing } from "./merge-Bpx4jjht.js";
40
+ import { t as rebaseFeatureBranch } from "./merge-rebase-xLnMlw5h.js";
41
+ import { n as init_release_set, t as getReleaseSetSync } from "./release-set-BwGeyZKX.js";
42
+ import { i as init_conflict_gate, r as getCachedConflictGateMergeability } from "./conflict-gate-B9cN3SBi.js";
43
+ import { r as runVerificationForIssue } from "./verification-runner-KDZIsBj4.js";
44
+ import { n as registerDurableReviewPipelineHandler, t as init_durable_review_pipeline } from "./durable-review-pipeline-CGZ5QBxh.js";
45
+ import { t as teardownWorkspace } from "./teardown-workspace-l2F4_zim.js";
46
+ import { t as init_rebuild_stack } from "./rebuild-stack-0EEYReVZ.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-CRCg1L4H.js");
105
+ const { getRemoteAgentOutput } = await import("./remote-agents-C1bssi41.js");
101
106
  stdout = await getRemoteAgentOutput(agentId, remoteState.vmName, 50);
102
107
  } else stdout = await Effect.runPromise(capturePane(agentId, 50));
103
108
  } catch {
@@ -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$8 = promisify(exec);
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$8(`docker exec "${pgContainer}" pg_isready -U postgres`, {
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$8(`docker exec "${pgContainer}" psql -U postgres -d ${dbName} -t -A -c "SELECT count(*) FROM flyway_schema_history;"`, {
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$8(`docker exec -i "${pgContainer}" psql -U postgres -d ${dbName} < "${flywayFile}"`, {
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$8(`docker exec -i "${pgContainer}" psql -U postgres -d ${dbName} < "${tmpSql}"`, {
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$8(`docker exec "${pgContainer}" psql -U postgres -d ${dbName} -t -A -c "SELECT count(*) FROM flyway_schema_history;"`, {
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$8(`docker stop "${ctx.apiContainer}"`, {
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$8(`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();"`, {
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$8(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d postgres -c "DROP DATABASE IF EXISTS ${sqlIdentifier(ctx.databaseName)};"`, {
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$8(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d postgres -c "CREATE DATABASE ${sqlIdentifier(ctx.databaseName)} OWNER postgres;"`, {
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$8(`docker exec -i ${shellQuote(ctx.pgContainer)} psql -U postgres -d ${shellQuote(ctx.databaseName)} < ${shellQuote(ctx.seedFile)}`, {
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$8(`docker start "${ctx.apiContainer}"`, {
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$8(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d ${shellQuote(ctx.databaseName)} -t -A -c ${shellQuote(ctx.seedVerifyQuery)}`, {
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$8(`docker ps --filter "name=${ctx.pgContainer}" --format "{{.Names}}"`);
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$8(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d ${shellQuote(ctx.databaseName)} -c "SELECT count(*) FROM flyway_schema_history" -t 2>/dev/null`);
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$8(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -c "DROP DATABASE IF EXISTS ${sqlIdentifier(ctx.databaseName)}; CREATE DATABASE ${sqlIdentifier(ctx.databaseName)};"`);
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$8(`docker cp ${shellQuote(ctx.seedFile)} ${shellQuote(`${ctx.pgContainer}:/tmp/seed.sql`)}`);
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$8(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d ${shellQuote(ctx.databaseName)} -f /tmp/seed.sql`, { timeout: 6e5 });
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$8(`docker exec ${shellQuote(ctx.pgContainer)} rm /tmp/seed.sql`);
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$8(`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`);
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$8(fullCmd, { timeout: 3e5 });
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$8(ctx.dbConfig.seed_command, { cwd: ctx.projectConfig.path });
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$8(`docker ps --filter "name=${ctx.pgContainer}" --format "{{.Status}}"`);
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$8(`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`);
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$8(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d ${shellQuote(ctx.databaseName)} -c "SELECT count(*) FROM information_schema.tables WHERE table_schema = 'public'" -t`);
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$8(`docker exec ${shellQuote(ctx.pgContainer)} psql -U postgres -d ${shellQuote(ctx.databaseName)} -c "SELECT pg_size_pretty(pg_database_size('${sqlString(ctx.databaseName)}'))" -t`);
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$7 = promisify(exec);
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$7("docker info >/dev/null 2>&1", { encoding: "utf-8" }));
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-DRqaAkBR.js"));
939
+ const { ensureDevcontainerSync } = yield* Effect.promise(() => import("./ensure-devcontainer-C98V8yW-.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$7("docker info >/dev/null 2>&1", { encoding: "utf-8" }));
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$7(`docker compose -f "${composeFile}" config --format json 2>/dev/null | jq -r '.name // empty'`, { encoding: "utf-8" }));
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$7(cmd, {
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$7(`docker compose -f "${composeFile}" config --format json 2>/dev/null | jq -r '.name // empty'`, { encoding: "utf-8" }));
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$6 = promisify(exec);
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
- const { stdout } = await execAsync$6("git stash list --format=\"%gd%x09%H%x09%cI%x09%gs\"", {
1166
- cwd: repoPath,
1167
- encoding: "utf-8"
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$6(`git rev-parse --verify ${JSON.stringify(candidateRef)}`, {
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$6(`git rev-parse --verify ${JSON.stringify(matchingEntry.stackRef)}`, {
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$6(`git stash drop ${JSON.stringify(operationRef)}`, {
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$6(`git branch ${JSON.stringify(branchName)} ${JSON.stringify(operationRef)}`, {
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-CI6cwyyC.js");
2794
+ const verifiedAnchor = await snapshotWorkspaceHeadsPromise(issueId, workspacePath).catch(() => void 0);
2795
+ const { setReviewStatusSync } = await import("./review-status-BZH8h-6W.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-xplJ8t75.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;
@@ -2777,7 +2856,9 @@ function mergeCompletionStatus(request) {
2777
2856
  return request.kind === "strike" ? {
2778
2857
  strikeLandingState: "landed",
2779
2858
  strikeReadyHead: void 0,
2780
- strikeReadyAt: void 0
2859
+ strikeReadyAt: void 0,
2860
+ strikeTransportRetryCount: void 0,
2861
+ strikeNextAttemptAt: void 0
2781
2862
  } : {};
2782
2863
  }
2783
2864
  function activeStrikeMerge(currentMerge, pendingOperation) {
@@ -2828,23 +2909,55 @@ async function validateStrikeMergeRequest(issueId, request, status, deps) {
2828
2909
  }
2829
2910
  return null;
2830
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
+ }
2831
2942
  async function ensureAgentReadyForMerge(issueId, workspacePath, rebaseMsg, options) {
2832
2943
  const agentId = options?.agentId ?? `agent-${issueId.toLowerCase()}`;
2944
+ const gateNote = await clearMergePreparationGate(agentId);
2945
+ const gateSuffix = gateNote ? ` (${gateNote})` : "";
2833
2946
  const lifecycle = getWorkAgentLifecycleStateSync(agentId);
2834
2947
  if (lifecycle.hasLiveTmuxSession) {
2835
- await messageAgent(agentId, rebaseMsg);
2948
+ assertDelivered(agentId, await messageAgent(agentId, rebaseMsg));
2836
2949
  return {
2837
2950
  recovered: true,
2838
2951
  agentId,
2839
- detail: "Work agent already running; sent merge preparation request."
2952
+ detail: `Work agent already running; sent merge preparation request${gateSuffix}.`
2840
2953
  };
2841
2954
  }
2842
2955
  if (await Effect.runPromise(getAgentState(agentId))) try {
2843
- await messageAgent(agentId, rebaseMsg);
2956
+ assertDelivered(agentId, await messageAgent(agentId, rebaseMsg));
2844
2957
  return {
2845
2958
  recovered: true,
2846
2959
  agentId,
2847
- detail: getWorkAgentLifecycleStateSync(agentId).canResumeSession ? "Resumed work agent and sent merge preparation request." : "Restarted work agent and sent merge preparation request."
2960
+ detail: `${getWorkAgentLifecycleStateSync(agentId).canResumeSession ? "Resumed" : "Restarted"} work agent and sent merge preparation request${gateSuffix}.`
2848
2961
  };
2849
2962
  } catch (error) {
2850
2963
  if (!lifecycle.canStartFresh) throw error;
@@ -2861,6 +2974,97 @@ async function ensureAgentReadyForMerge(issueId, workspacePath, rebaseMsg, optio
2861
2974
  })).id} and sent merge preparation request.`
2862
2975
  };
2863
2976
  }
2977
+ async function rebaseWithAgentFallback(options) {
2978
+ const { issueId, workspacePath, branchName, targetBranch, agentId, rebaseMsg, allowFreshStart, setStatus } = options;
2979
+ let serverRebaseReason;
2980
+ let conflictFiles = [];
2981
+ if (existsSync$1(workspacePath)) try {
2982
+ const result = await Effect.runPromise(rebaseFeatureBranch(workspacePath, branchName, targetBranch, issueId));
2983
+ console.log(`[merge] Server-side rebase completed for ${issueId}`);
2984
+ return {
2985
+ success: true,
2986
+ newHead: result.newHead
2987
+ };
2988
+ } catch (error) {
2989
+ const detail = error;
2990
+ conflictFiles = Array.isArray(detail.conflictedFiles) ? detail.conflictedFiles.filter((file) => typeof file === "string") : [];
2991
+ const message = error instanceof Error ? error.message : typeof detail.message === "string" ? detail.message : void 0;
2992
+ serverRebaseReason = conflictFiles.length > 0 ? `Rebase conflicts in: ${conflictFiles.join(", ")}` : message || "Server-side rebase failed";
2993
+ console.warn(`[merge] ${serverRebaseReason} — escalating to the work agent for ${issueId}`);
2994
+ }
2995
+ try {
2996
+ const preparation = await prepareWorkAgentForRebase({
2997
+ issueId,
2998
+ workspacePath,
2999
+ agentId,
3000
+ rebaseMsg,
3001
+ allowFreshStart,
3002
+ scopeNote: branchName,
3003
+ setStatus,
3004
+ deferFailureStatus: true
3005
+ });
3006
+ if (!preparation.ok) throw new Error(preparation.error);
3007
+ const { stdout: headBefore } = await execAsync$6(`git rev-parse origin/${branchName} 2>/dev/null || echo NONE`, {
3008
+ cwd: workspacePath,
3009
+ encoding: "utf-8",
3010
+ timeout: 1e4
3011
+ });
3012
+ const timeoutMs = 1800 * 1e3;
3013
+ const startTime = Date.now();
3014
+ let newHead = null;
3015
+ while (Date.now() - startTime < timeoutMs) {
3016
+ await new Promise((resolve) => setTimeout(resolve, 5e3));
3017
+ try {
3018
+ await execAsync$6("git fetch origin", {
3019
+ cwd: workspacePath,
3020
+ encoding: "utf-8",
3021
+ timeout: 15e3
3022
+ });
3023
+ const { stdout: headNow } = await execAsync$6(`git rev-parse origin/${branchName}`, {
3024
+ cwd: workspacePath,
3025
+ encoding: "utf-8",
3026
+ timeout: 5e3
3027
+ });
3028
+ if (headNow.trim() !== headBefore.trim()) {
3029
+ newHead = headNow.trim();
3030
+ console.log(`[merge] Work agent pushed rebased branch for ${issueId} (new HEAD: ${newHead.slice(0, 8)})`);
3031
+ break;
3032
+ }
3033
+ } catch {}
3034
+ if (!await Effect.runPromise(sessionExists(agentId))) {
3035
+ console.log(`[merge] Work agent ${agentId} stopped during rebase`);
3036
+ break;
3037
+ }
3038
+ }
3039
+ if (newHead) return {
3040
+ success: true,
3041
+ newHead
3042
+ };
3043
+ if (!await Effect.runPromise(sessionExists(agentId))) {
3044
+ const agentReason = `Work agent ${agentId} stopped before completing the rebase onto ${targetBranch}`;
3045
+ return {
3046
+ success: false,
3047
+ reason: serverRebaseReason ? `${serverRebaseReason}; ${agentReason}` : agentReason,
3048
+ conflictFiles,
3049
+ retryable: conflictFiles.length === 0
3050
+ };
3051
+ }
3052
+ return {
3053
+ success: false,
3054
+ reason: `Work agent did not push the rebased branch within ${timeoutMs / 6e4} minutes`,
3055
+ conflictFiles,
3056
+ retryable: conflictFiles.length === 0
3057
+ };
3058
+ } catch (error) {
3059
+ const agentReason = error instanceof Error ? error.message : `Work agent ${agentId} could not be prepared for merge`;
3060
+ return {
3061
+ success: false,
3062
+ reason: serverRebaseReason ? `${serverRebaseReason}; ${agentReason}` : agentReason,
3063
+ conflictFiles,
3064
+ retryable: conflictFiles.length === 0
3065
+ };
3066
+ }
3067
+ }
2864
3068
  //#endregion
2865
3069
  //#region routes/workspaces/internal-strike-merge.ts
2866
3070
  init_issue_id();
@@ -2914,6 +3118,7 @@ function internalStrikeMergeRoute(triggerMerge) {
2914
3118
  * stay owned by ../workspaces.js and are imported here.
2915
3119
  */
2916
3120
  init_merge_agent();
3121
+ init_merge_verification();
2917
3122
  init_operations();
2918
3123
  init_git_activity();
2919
3124
  init_issue_id();
@@ -2926,7 +3131,7 @@ init_tracker_utils();
2926
3131
  init_tmux();
2927
3132
  init_domain_services();
2928
3133
  const execAsync$5 = promisify(exec);
2929
- const execFileAsync$3 = promisify(execFile);
3134
+ const execFileAsync$4 = promisify(execFile);
2930
3135
  const shouldBlockApproveForDirtyStatus = (status) => status.trim() !== "" && !isStatePlaneOnlyStatus(status);
2931
3136
  /**
2932
3137
  * Check whether origin/branchName already contains origin/targetBranch.
@@ -2934,7 +3139,7 @@ const shouldBlockApproveForDirtyStatus = (status) => status.trim() !== "" && !is
2934
3139
  */
2935
3140
  async function isBranchAlreadyRebased(workspacePath, branchName, targetBranch) {
2936
3141
  try {
2937
- await Promise.all([execFileAsync$3("git", [
3142
+ await Promise.all([execFileAsync$4("git", [
2938
3143
  "fetch",
2939
3144
  "origin",
2940
3145
  targetBranch
@@ -2942,7 +3147,7 @@ async function isBranchAlreadyRebased(workspacePath, branchName, targetBranch) {
2942
3147
  cwd: workspacePath,
2943
3148
  encoding: "utf-8",
2944
3149
  timeout: 15e3
2945
- }), execFileAsync$3("git", [
3150
+ }), execFileAsync$4("git", [
2946
3151
  "fetch",
2947
3152
  "origin",
2948
3153
  branchName
@@ -2951,7 +3156,7 @@ async function isBranchAlreadyRebased(workspacePath, branchName, targetBranch) {
2951
3156
  encoding: "utf-8",
2952
3157
  timeout: 15e3
2953
3158
  })]);
2954
- await execFileAsync$3("git", [
3159
+ await execFileAsync$4("git", [
2955
3160
  "merge-base",
2956
3161
  "--is-ancestor",
2957
3162
  `origin/${targetBranch}`,
@@ -2961,7 +3166,7 @@ async function isBranchAlreadyRebased(workspacePath, branchName, targetBranch) {
2961
3166
  encoding: "utf-8",
2962
3167
  timeout: 5e3
2963
3168
  });
2964
- const { stdout: currentHead } = await execFileAsync$3("git", ["rev-parse", `origin/${branchName}`], {
3169
+ const { stdout: currentHead } = await execFileAsync$4("git", ["rev-parse", `origin/${branchName}`], {
2965
3170
  cwd: workspacePath,
2966
3171
  encoding: "utf-8",
2967
3172
  timeout: 5e3
@@ -2970,7 +3175,8 @@ async function isBranchAlreadyRebased(workspacePath, branchName, targetBranch) {
2970
3175
  alreadyRebased: true,
2971
3176
  currentHead: currentHead.trim()
2972
3177
  };
2973
- } catch {
3178
+ } catch (error) {
3179
+ console.warn(`[merge] Could not determine whether ${branchName} contains origin/${targetBranch}: ${error instanceof Error ? error.message : String(error)}`);
2974
3180
  return { alreadyRebased: false };
2975
3181
  }
2976
3182
  }
@@ -2989,7 +3195,7 @@ async function reconcileGitHubMergeStatus(issueId, status) {
2989
3195
  const prRef = parseGitHubPullRequestUrl(status.prUrl);
2990
3196
  if (!prRef) return false;
2991
3197
  try {
2992
- const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CPfoFAdV.js");
3198
+ const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-DtAsvwzK.js");
2993
3199
  if (!isGitHubAppConfigured()) return false;
2994
3200
  const prState = await Effect.runPromise(getPullRequestState(prRef.owner, prRef.repo, prRef.number));
2995
3201
  console.log(`[merge] reconcileGitHubMergeStatus: ${issueId} PR #${prRef.number} merged=${prState.merged} state=${prState.state}`);
@@ -3041,7 +3247,7 @@ async function ensurePRExists(issueId, options) {
3041
3247
  if (options?.cwd) execOptions.cwd = options.cwd;
3042
3248
  let existingOut = "";
3043
3249
  try {
3044
- const { stdout } = await execFileAsync$3("gh", [
3250
+ const { stdout } = await execFileAsync$4("gh", [
3045
3251
  "pr",
3046
3252
  "view",
3047
3253
  branchName,
@@ -3064,7 +3270,7 @@ async function ensurePRExists(issueId, options) {
3064
3270
  const bodyFile = pathJoin(tmpdir(), `pan-pr-body-${issueId}-${Date.now()}.md`);
3065
3271
  await writeFileAsync(bodyFile, prBody, "utf-8");
3066
3272
  try {
3067
- const { stdout: rawOut } = await execFileAsync$3("gh", [
3273
+ const { stdout: rawOut } = await execFileAsync$4("gh", [
3068
3274
  "pr",
3069
3275
  "create",
3070
3276
  "--head",
@@ -3135,20 +3341,23 @@ const postWorkspaceSyncMainRoute = HttpRouter.add("POST", "/api/issues/:issueId/
3135
3341
  if (result.alreadyUpToDate) return jsonResponse({
3136
3342
  success: true,
3137
3343
  alreadyUpToDate: true,
3138
- message: "Already up to date with main"
3344
+ message: "Already up to date with main",
3345
+ repos: result.repos
3139
3346
  });
3140
3347
  return jsonResponse({
3141
3348
  success: true,
3142
3349
  commitCount: result.commitCount || 0,
3143
3350
  changedFiles: result.changedFiles || [],
3144
- message: `Synced ${result.commitCount || 0} commit(s) from main`
3351
+ message: `Synced ${result.commitCount || 0} commit(s) from main`,
3352
+ repos: result.repos
3145
3353
  });
3146
3354
  } else {
3147
3355
  const status = result.reason?.includes("uncommitted") ? 400 : 500;
3148
3356
  return jsonResponse({
3149
3357
  success: false,
3150
3358
  error: result.reason || "Sync failed",
3151
- conflictFiles: result.conflictFiles
3359
+ conflictFiles: result.conflictFiles,
3360
+ repos: result.repos
3152
3361
  }, { status });
3153
3362
  }
3154
3363
  })));
@@ -3178,7 +3387,7 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
3178
3387
  };
3179
3388
  const strikeError = await validateStrikeMergeRequest(issueId, request, reviewStatus, {
3180
3389
  projectPath: getProjectPath(void 0, extractPrefixSync(issueId) ?? issueId.split("-")[0]),
3181
- git: async (args, cwd) => (await execFileAsync$3("git", args, {
3390
+ git: async (args, cwd) => (await execFileAsync$4("git", args, {
3182
3391
  cwd,
3183
3392
  encoding: "utf-8"
3184
3393
  })).stdout.trim()
@@ -3246,7 +3455,7 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
3246
3455
  const normalizedMergeId = issueId.toUpperCase();
3247
3456
  _serverManagedMerges.add(normalizedMergeId);
3248
3457
  setPendingOperation(issueId, "merge");
3249
- let queueAdvanced = false;
3458
+ let queueAdvanced = false, preserveQueue = false;
3250
3459
  const advanceQueue = () => {
3251
3460
  if (queueAdvanced) return;
3252
3461
  queueAdvanced = true;
@@ -3256,8 +3465,8 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
3256
3465
  try {
3257
3466
  if (request.kind === "normal" && workspaceInfo.isRemote && workspaceInfo.vmName) {
3258
3467
  console.log(`[merge] Remote workspace detected for ${issueId}, using review artifact merge...`);
3259
- const { getMergeSetSync, ensureMergeSetForIssueSync } = await import("./merge-set-DnSYdBEp.js");
3260
- const { getForgeAdapter } = await import("./forge-B-ZWyTRm.js");
3468
+ const { getMergeSetSync, ensureMergeSetForIssueSync } = await import("./merge-set-DzsOTBg5.js");
3469
+ const { getForgeAdapter } = await import("./forge-DK3blQb_.js");
3261
3470
  const remotePrimaryRepo = (getMergeSetSync(issueId) || ensureMergeSetForIssueSync(issueId))?.repos[0];
3262
3471
  const remoteTargetBranch = remotePrimaryRepo?.targetBranch || "main";
3263
3472
  const remoteForge = remotePrimaryRepo?.forge || "github";
@@ -3293,7 +3502,7 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
3293
3502
  ...mergeCompletionStatus(request)
3294
3503
  });
3295
3504
  completePendingOperation(issueId, null);
3296
- const { postMergeLifecycle } = await import("./merge-agent-BQM3a8z5.js");
3505
+ const { postMergeLifecycle } = await import("./merge-agent-DrXa1CpW.js");
3297
3506
  await postMergeLifecycle(issueId, projectPath);
3298
3507
  return {
3299
3508
  success: true,
@@ -3319,21 +3528,30 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
3319
3528
  };
3320
3529
  }
3321
3530
  }
3531
+ const projectConfig = findProjectByTeamSync(issuePrefix);
3532
+ const isPolyrepo = projectConfig?.workspace?.type === "polyrepo";
3322
3533
  if (!existsSync$1(workspacePath)) {
3323
- completePendingOperation(issueId, "Workspace does not exist");
3534
+ const error = "Workspace does not exist";
3535
+ const retryable = request.kind === "normal" && !workspaceInfo.isRemote && !isPolyrepo;
3536
+ if (retryable) setReviewStatus(issueId, {
3537
+ mergeStatus: "queued",
3538
+ mergeNotes: error
3539
+ });
3540
+ completePendingOperation(issueId, error);
3324
3541
  return {
3325
3542
  success: false,
3326
- statusCode: 400,
3327
- error: "Workspace does not exist"
3543
+ statusCode: retryable ? 500 : 400,
3544
+ error,
3545
+ ...retryable ? { retryable: true } : {}
3328
3546
  };
3329
3547
  }
3330
- const projectConfig = findProjectByTeamSync(issuePrefix);
3331
- if (projectConfig?.workspace?.type === "polyrepo" && projectConfig?.workspace?.repos) {
3548
+ if (isPolyrepo && projectConfig?.workspace?.repos) {
3332
3549
  console.log(`[merge] Polyrepo detected for ${issueId}, coordinating merge set...`);
3333
- const { getMergeSetSync, ensureMergeSetForIssueSync, upsertMergeSetSync, withRepoStateSync } = await import("./merge-set-DnSYdBEp.js");
3334
- const { runQualityGates } = await import("./validation-CIi6pnI2.js");
3335
- const { getForgeAdapter } = await import("./forge-B-ZWyTRm.js");
3336
- const { messageAgent } = await import("./agents-FlIgQ3ql.js");
3550
+ const { getMergeSetSync, ensureMergeSetForIssueSync, upsertMergeSetSync, withRepoStateSync } = await import("./merge-set-DzsOTBg5.js");
3551
+ const { runQualityGates } = await import("./validation-DEaTZafj.js");
3552
+ const { reconcileStrandedRepos } = await import("./merge-completeness-D0ljXbk3.js");
3553
+ const { getForgeAdapter } = await import("./forge-DK3blQb_.js");
3554
+ const { messageAgent } = await import("./agents-BKKkxKgK.js");
3337
3555
  let mergeSet = getMergeSetSync(issueId) || ensureMergeSetForIssueSync(issueId);
3338
3556
  if (!mergeSet) {
3339
3557
  const error = `No merge set found for ${issueId}`;
@@ -3349,21 +3567,59 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
3349
3567
  error
3350
3568
  };
3351
3569
  }
3352
- const activeRepos = mergeSet.repos.filter((repo) => repo.mergeStatus !== "skipped" && !!repo.artifactUrl).sort((a, b) => a.mergeOrder - b.mergeOrder);
3353
- if (activeRepos.length === 0) {
3354
- const error = `No changed repos are marked ready for coordinated merge in ${issueId}`;
3570
+ const reconciliation = await reconcileStrandedRepos(mergeSet);
3571
+ mergeSet = reconciliation.mergeSet;
3572
+ if (reconciliation.blockers.length > 0) {
3573
+ const error = reconciliation.blockers.map((blocker) => blocker.reason).join("; ");
3574
+ mergeSet = {
3575
+ ...mergeSet,
3576
+ status: "failed",
3577
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
3578
+ };
3579
+ upsertMergeSetSync(mergeSet);
3355
3580
  setReviewStatus(issueId, {
3356
3581
  mergeStatus: "failed",
3357
3582
  readyForMerge: false,
3358
- mergeNotes: error
3583
+ mergeNotes: error,
3584
+ blockerReasons: reconciliation.blockers.map((blocker) => ({
3585
+ type: "unmerged_sibling_repo",
3586
+ summary: blocker.reason,
3587
+ detectedAt: (/* @__PURE__ */ new Date()).toISOString()
3588
+ }))
3359
3589
  });
3360
3590
  completePendingOperation(issueId, error);
3361
3591
  return {
3362
3592
  success: false,
3363
- statusCode: 400,
3593
+ statusCode: 409,
3364
3594
  error
3365
3595
  };
3366
3596
  }
3597
+ const activeRepos = mergeSet.repos.filter((repo) => repo.mergeStatus !== "skipped" && repo.mergeStatus !== "merged" && !!repo.artifactUrl).sort((a, b) => a.mergeOrder - b.mergeOrder);
3598
+ if (activeRepos.length === 0) {
3599
+ mergeSet = {
3600
+ ...mergeSet,
3601
+ status: "merged",
3602
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
3603
+ };
3604
+ upsertMergeSetSync(mergeSet);
3605
+ setReviewStatus(issueId, {
3606
+ mergeStatus: "merged",
3607
+ mergeNotes: void 0,
3608
+ readyForMerge: false,
3609
+ ...mergeCompletionStatus(request)
3610
+ });
3611
+ completePendingOperation(issueId, null);
3612
+ const { postMergeLifecycle } = await import("./merge-agent-DrXa1CpW.js");
3613
+ advanceQueue();
3614
+ await postMergeLifecycle(issueId, projectPath);
3615
+ return {
3616
+ success: true,
3617
+ statusCode: 200,
3618
+ message: `No changed repos remain for ${issueId}`,
3619
+ mergeStatus: "merged",
3620
+ repos: []
3621
+ };
3622
+ }
3367
3623
  const agentId = `agent-${issueId.toLowerCase()}`;
3368
3624
  mergeSet = {
3369
3625
  ...mergeSet,
@@ -3426,21 +3682,24 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
3426
3682
  };
3427
3683
  }
3428
3684
  const reposNeedingRebase = activeRepos.filter((repo) => !alreadyRebased.has(repo.repoKey));
3429
- if (reposNeedingRebase.length > 0 && !await Effect.runPromise(sessionExists(agentId))) {
3430
- const error = `Work agent ${agentId} is not running. Polyrepo merge requires the work agent to rebase every affected repo and push.`;
3431
- setReviewStatus(issueId, {
3432
- mergeStatus: "failed",
3433
- readyForMerge: false,
3434
- mergeNotes: error
3685
+ if (reposNeedingRebase.length > 0) {
3686
+ const prep = await prepareWorkAgentForRebase({
3687
+ issueId,
3688
+ workspacePath,
3689
+ agentId,
3690
+ 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.`,
3691
+ scopeNote: `${reposNeedingRebase.length} repo(s)`,
3692
+ setStatus: (u) => setReviewStatus(issueId, u)
3435
3693
  });
3436
- completePendingOperation(issueId, error);
3437
- return {
3438
- success: false,
3439
- statusCode: 400,
3440
- error
3441
- };
3694
+ if (!prep.ok) {
3695
+ completePendingOperation(issueId, prep.error);
3696
+ return {
3697
+ success: false,
3698
+ statusCode: 400,
3699
+ error: prep.error
3700
+ };
3701
+ }
3442
3702
  }
3443
- 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.`);
3444
3703
  const REBASE_TIMEOUT_MS = 1800 * 1e3;
3445
3704
  const POLL_INTERVAL_MS = 5e3;
3446
3705
  const pushedRepos = new Set(alreadyRebased);
@@ -3604,7 +3863,7 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
3604
3863
  ...mergeCompletionStatus(request)
3605
3864
  });
3606
3865
  completePendingOperation(issueId, null);
3607
- const { postMergeLifecycle } = await import("./merge-agent-BQM3a8z5.js");
3866
+ const { postMergeLifecycle } = await import("./merge-agent-DrXa1CpW.js");
3608
3867
  advanceQueue();
3609
3868
  await postMergeLifecycle(issueId, projectPath);
3610
3869
  return {
@@ -3615,8 +3874,8 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
3615
3874
  repos: mergeResults
3616
3875
  };
3617
3876
  }
3618
- const { getMergeSetSync, ensureMergeSetForIssueSync } = await import("./merge-set-DnSYdBEp.js");
3619
- const { getForgeAdapter } = await import("./forge-B-ZWyTRm.js");
3877
+ const { getMergeSetSync, ensureMergeSetForIssueSync } = await import("./merge-set-DzsOTBg5.js");
3878
+ const { getForgeAdapter } = await import("./forge-DK3blQb_.js");
3620
3879
  const primaryRepo = (getMergeSetSync(issueId) || ensureMergeSetForIssueSync(issueId))?.repos[0];
3621
3880
  const targetBranch = primaryRepo?.targetBranch || "main";
3622
3881
  const primaryForge = primaryRepo?.forge || "github";
@@ -3657,10 +3916,12 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
3657
3916
  error
3658
3917
  };
3659
3918
  }
3919
+ let preMergePrState;
3660
3920
  if (githubPrRef) try {
3661
- const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CPfoFAdV.js");
3921
+ const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-DtAsvwzK.js");
3662
3922
  if (isGitHubAppConfigured()) {
3663
3923
  const prState = await Effect.runPromise(getPullRequestState(githubPrRef.owner, githubPrRef.repo, githubPrRef.number));
3924
+ preMergePrState = prState;
3664
3925
  if (prState.state !== "OPEN" && !prState.merged) {
3665
3926
  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.`;
3666
3927
  console.error(`[merge] ${error}`);
@@ -3720,7 +3981,7 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
3720
3981
  ...mergeCompletionStatus(request)
3721
3982
  });
3722
3983
  completePendingOperation(issueId, null);
3723
- const { postMergeLifecycle } = await import("./merge-agent-BQM3a8z5.js");
3984
+ const { postMergeLifecycle } = await import("./merge-agent-DrXa1CpW.js");
3724
3985
  await postMergeLifecycle(issueId, projectPath, branchName);
3725
3986
  return {
3726
3987
  success: true,
@@ -3734,83 +3995,56 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
3734
3995
  } catch (prStateErr) {
3735
3996
  console.warn(`[merge] Pre-merge PR state check failed for ${issueId}: ${prStateErr.message} — proceeding (check is best-effort)`);
3736
3997
  }
3737
- const { postMergeLifecycle } = await import("./merge-agent-BQM3a8z5.js");
3738
- const agentId = request.kind === "strike" ? request.recoveryTarget : `agent-${issueId.toLowerCase()}`;
3739
- 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.`;
3740
- setReviewStatus(issueId, { mergeStep: "rebasing" });
3741
- console.log(`[merge] Rebasing ${branchName} onto ${targetBranch} for ${issueId} (agent=${await Effect.runPromise(sessionExists(agentId)) ? "running" : "stopped"})...`);
3742
- {
3743
- const { beginShipLog, appendShipLog } = await import("./ship-log-ClSMIzZX.js");
3744
- beginShipLog(issueId);
3745
- appendShipLog(issueId, `Ship started: rebasing ${branchName} onto ${targetBranch}…`, "rebasing");
3746
- }
3998
+ const { postMergeLifecycle } = await import("./merge-agent-DrXa1CpW.js");
3999
+ const { beginShipLog, appendShipLog } = await import("./ship-log-xplJ8t75.js");
3747
4000
  let rebaseResult;
3748
- const { alreadyRebased, currentHead } = await isBranchAlreadyRebased(workspacePath, branchName, targetBranch);
3749
- if (alreadyRebased && currentHead) {
3750
- console.log(`[merge] ${branchName} already contains origin/${targetBranch} — skipping rebase request for ${issueId}`);
4001
+ if (preMergePrState?.mergeable === true && preMergePrState.mergeableState === "clean" && !preMergePrState.checksFailed && !preMergePrState.checksPending && !preMergePrState.draft && !preMergePrState.merged) {
4002
+ console.log(`[merge] PR is CLEAN — merging directly without rebase for ${issueId}`);
3751
4003
  rebaseResult = {
3752
4004
  success: true,
3753
- newHead: currentHead
4005
+ newHead: preMergePrState.headSha
3754
4006
  };
3755
- } else try {
3756
- const recovery = await ensureAgentReadyForMerge(issueId, workspacePath, rebaseMsg, {
4007
+ } else {
4008
+ const agentId = request.kind === "strike" ? request.recoveryTarget : `agent-${issueId.toLowerCase()}`;
4009
+ 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.`;
4010
+ setReviewStatus(issueId, { mergeStep: "rebasing" });
4011
+ console.log(`[merge] Rebasing ${branchName} onto ${targetBranch} for ${issueId} (agent=${await Effect.runPromise(sessionExists(agentId)) ? "running" : "stopped"})...`);
4012
+ beginShipLog(issueId);
4013
+ appendShipLog(issueId, `Ship started: rebasing ${branchName} onto ${targetBranch}…`, "rebasing");
4014
+ const { alreadyRebased, currentHead } = await isBranchAlreadyRebased(workspacePath, branchName, targetBranch);
4015
+ if (alreadyRebased && currentHead) {
4016
+ console.log(`[merge] ${branchName} already contains origin/${targetBranch} — skipping rebase request for ${issueId}`);
4017
+ rebaseResult = {
4018
+ success: true,
4019
+ newHead: currentHead
4020
+ };
4021
+ } else rebaseResult = await rebaseWithAgentFallback({
4022
+ issueId,
4023
+ workspacePath,
4024
+ branchName,
4025
+ targetBranch,
3757
4026
  agentId,
3758
- allowFreshStart: request.kind !== "strike"
4027
+ rebaseMsg,
4028
+ allowFreshStart: request.kind !== "strike",
4029
+ setStatus: (update) => setReviewStatus(issueId, update)
3759
4030
  });
3760
- console.log(`[merge] ${recovery.detail}`);
3761
- const { stdout: headBefore } = await execAsync$5(`git rev-parse origin/${branchName} 2>/dev/null || echo NONE`, {
3762
- cwd: workspacePath,
3763
- encoding: "utf-8",
3764
- timeout: 1e4
3765
- });
3766
- const REBASE_TIMEOUT_MS = 1800 * 1e3;
3767
- const POLL_INTERVAL_MS = 5e3;
3768
- const startTime = Date.now();
3769
- let newHead = null;
3770
- while (Date.now() - startTime < REBASE_TIMEOUT_MS) {
3771
- await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
3772
- try {
3773
- await execAsync$5("git fetch origin", {
3774
- cwd: workspacePath,
3775
- encoding: "utf-8",
3776
- timeout: 15e3
3777
- });
3778
- const { stdout: headNow } = await execAsync$5(`git rev-parse origin/${branchName}`, {
3779
- cwd: workspacePath,
3780
- encoding: "utf-8",
3781
- timeout: 5e3
3782
- });
3783
- if (headNow.trim() !== headBefore.trim()) {
3784
- newHead = headNow.trim();
3785
- console.log(`[merge] Work agent pushed rebased branch for ${issueId} (new HEAD: ${newHead.slice(0, 8)})`);
3786
- break;
3787
- }
3788
- } catch {}
3789
- if (!await Effect.runPromise(sessionExists(agentId))) {
3790
- console.log(`[merge] Work agent ${agentId} stopped during rebase`);
3791
- break;
3792
- }
3793
- }
3794
- if (newHead) rebaseResult = {
3795
- success: true,
3796
- newHead
3797
- };
3798
- else if (!await Effect.runPromise(sessionExists(agentId))) rebaseResult = {
3799
- success: false,
3800
- reason: `Work agent ${agentId} stopped before completing the rebase onto ${targetBranch}`
3801
- };
3802
- else rebaseResult = {
3803
- success: false,
3804
- reason: `Work agent did not push the rebased branch within ${REBASE_TIMEOUT_MS / 6e4} minutes`
3805
- };
3806
- } catch (recoveryErr) {
3807
- rebaseResult = {
3808
- success: false,
3809
- reason: recoveryErr.message || `Work agent ${agentId} could not be prepared for merge`
3810
- };
3811
4031
  }
4032
+ if (!rebaseResult) throw new Error(`Rebase escalation produced no result for ${issueId}`);
3812
4033
  if (!rebaseResult.success) {
3813
4034
  const error = rebaseResult.reason || "Rebase failed";
4035
+ if (rebaseResult.retryable) {
4036
+ setReviewStatus(issueId, {
4037
+ mergeStatus: "queued",
4038
+ mergeNotes: error
4039
+ });
4040
+ completePendingOperation(issueId, error);
4041
+ return {
4042
+ success: false,
4043
+ statusCode: 500,
4044
+ error,
4045
+ retryable: true
4046
+ };
4047
+ }
3814
4048
  setReviewStatus(issueId, {
3815
4049
  mergeStatus: "failed",
3816
4050
  mergeNotes: error,
@@ -3871,7 +4105,7 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
3871
4105
  });
3872
4106
  let skipLocalVerification = false;
3873
4107
  if (primaryForge === "github" && artifactUrl) try {
3874
- const { parsePullRequestRef, getCiCheckRunsStatePromise, isGitHubAppConfigured } = await import("./github-app-CPfoFAdV.js");
4108
+ const { parsePullRequestRef, getCiCheckRunsStatePromise, isGitHubAppConfigured } = await import("./github-app-DtAsvwzK.js");
3875
4109
  if (isGitHubAppConfigured()) {
3876
4110
  const ref = parsePullRequestRef({ url: artifactUrl });
3877
4111
  if (ref) {
@@ -3892,17 +4126,27 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
3892
4126
  } catch (ciErr) {
3893
4127
  console.warn(`[merge] CI-state check failed (${ciErr.message?.slice(0, 120)}) — falling back to local verification for ${issueId}`);
3894
4128
  }
3895
- const { appendShipLog } = await import("./ship-log-ClSMIzZX.js");
3896
4129
  if (skipLocalVerification) appendShipLog(issueId, "✓ Local verification skipped — CI already green on this exact commit", "verifying");
3897
4130
  const verifyResult = skipLocalVerification ? { outcome: "passed" } : await (async () => {
3898
4131
  console.log(`[merge] Running post-rebase verification for ${issueId}...`);
3899
4132
  appendShipLog(issueId, "Running post-rebase verification (full quality-gate suite)…", "verifying");
3900
- const { runVerificationForIssue } = await import("./verification-runner-CDj4lD4t.js");
4133
+ const { runVerificationForIssue } = await import("./verification-runner-DlZI8yhw.js");
3901
4134
  return Effect.runPromise(runVerificationForIssue(issueId, workspacePath, { isRemote: false }, "merge-verify", {
3902
4135
  ...mergeVerificationOptions(request),
3903
4136
  onGateLog: (line) => appendShipLog(issueId, line, "verifying")
3904
4137
  }));
3905
4138
  })();
4139
+ const verificationDeferral = handlePostRebaseVerificationDeferral(issueId, verifyResult, reviewStatus, {
4140
+ appendShipLog,
4141
+ setReviewStatus,
4142
+ completePendingOperation
4143
+ });
4144
+ if (verificationDeferral) {
4145
+ markMergeProcessing(projectKey, normalizedId, false);
4146
+ _serverManagedMerges.delete(normalizedMergeId);
4147
+ preserveQueue = true;
4148
+ return verificationDeferral;
4149
+ }
3906
4150
  if (verifyResult.outcome === "failed") {
3907
4151
  const error = `Post-rebase verification failed at ${verifyResult.failedCheck}`;
3908
4152
  console.log(`[merge] ${error}`);
@@ -3928,9 +4172,10 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
3928
4172
  };
3929
4173
  }
3930
4174
  console.log(`[merge] Post-rebase verification ${verifyResult.outcome} for ${issueId}`);
4175
+ if (skipLocalVerification) await recordCiGreenVerificationVerdict(issueId, workspacePath);
3931
4176
  setReviewStatus(issueId, { mergeStep: "reporting-statuses" });
3932
4177
  try {
3933
- const { getPullRequestState, isGitHubAppConfigured, reportCommitStatus } = await import("./github-app-CPfoFAdV.js");
4178
+ const { getPullRequestState, isGitHubAppConfigured, reportCommitStatus } = await import("./github-app-DtAsvwzK.js");
3934
4179
  if (githubPrRef && isGitHubAppConfigured()) {
3935
4180
  const sha = (await Effect.runPromise(getPullRequestState(githubPrRef.owner, githubPrRef.repo, githubPrRef.number))).headSha.trim();
3936
4181
  if (sha) {
@@ -3958,7 +4203,7 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
3958
4203
  } catch (prMergeErr) {
3959
4204
  console.error(`[merge] Review artifact merge threw for ${issueId}:`, prMergeErr);
3960
4205
  try {
3961
- const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CPfoFAdV.js");
4206
+ const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-DtAsvwzK.js");
3962
4207
  if (githubPrRef && isGitHubAppConfigured()) {
3963
4208
  artifactMerged = (await Effect.runPromise(getPullRequestState(githubPrRef.owner, githubPrRef.repo, githubPrRef.number))).merged;
3964
4209
  if (artifactMerged) console.log(`[merge] Race-detected: PR #${githubPrRef.number} for ${issueId} was already merged despite thrown error; proceeding`);
@@ -4053,7 +4298,7 @@ async function triggerMerge(issueId, request = { kind: "normal" }) {
4053
4298
  error: error.message
4054
4299
  };
4055
4300
  } finally {
4056
- advanceQueue();
4301
+ if (!preserveQueue) advanceQueue();
4057
4302
  }
4058
4303
  }
4059
4304
  setMergeQueueTriggerHandler(triggerMerge);
@@ -4077,8 +4322,8 @@ const postForgeApproveRoute = HttpRouter.add("POST", "/api/issues/:issueId/forge
4077
4322
  if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
4078
4323
  if (!/^[A-Z]+-\d+$/i.test(issueId)) return jsonResponse({ error: "Invalid issue ID format" }, { status: 400 });
4079
4324
  return yield* Effect.promise(async () => {
4080
- const { getMergeSetSync, upsertMergeSetSync, withRepoArtifactUrlSync, withRepoStateSync } = await import("./merge-set-DnSYdBEp.js");
4081
- const { getForgeAdapter } = await import("./forge-B-ZWyTRm.js");
4325
+ const { getMergeSetSync, upsertMergeSetSync, withRepoArtifactUrlSync, withRepoStateSync } = await import("./merge-set-DzsOTBg5.js");
4326
+ const { getForgeAdapter } = await import("./forge-DK3blQb_.js");
4082
4327
  let mergeSet = getMergeSetSync(issueId);
4083
4328
  if (!mergeSet) return jsonResponse({ error: `No merge set found for ${issueId}` }, { status: 404 });
4084
4329
  const results = [];
@@ -4139,7 +4384,7 @@ const postForgeApproveRoute = HttpRouter.add("POST", "/api/issues/:issueId/forge
4139
4384
  }
4140
4385
  }
4141
4386
  if (results.filter((r) => r.approved).length > 0) {
4142
- const { emitActivityEntrySync, emitActivityTtsSync } = await import("./activity-logger-OEUBdfZ8.js");
4387
+ const { emitActivityEntrySync, emitActivityTtsSync } = await import("./activity-logger-CMthG6Vd.js");
4143
4388
  emitActivityEntrySync({
4144
4389
  source: "dashboard",
4145
4390
  level: "success",
@@ -4166,8 +4411,9 @@ const postForgeMergeRoute = HttpRouter.add("POST", "/api/issues/:issueId/forge-m
4166
4411
  if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
4167
4412
  if (!/^[A-Z]+-\d+$/i.test(issueId)) return jsonResponse({ error: "Invalid issue ID format" }, { status: 400 });
4168
4413
  return yield* Effect.promise(async () => {
4169
- const { getMergeSetSync, upsertMergeSetSync, withRepoArtifactUrlSync, withRepoStateSync } = await import("./merge-set-DnSYdBEp.js");
4170
- const { getForgeAdapter } = await import("./forge-B-ZWyTRm.js");
4414
+ const { getMergeSetSync, upsertMergeSetSync, withRepoArtifactUrlSync, withRepoStateSync } = await import("./merge-set-DzsOTBg5.js");
4415
+ const { getForgeAdapter } = await import("./forge-DK3blQb_.js");
4416
+ const { assessRepoMergeCompleteness } = await import("./merge-completeness-D0ljXbk3.js");
4171
4417
  let mergeSet = getMergeSetSync(issueId);
4172
4418
  if (!mergeSet) return jsonResponse({ error: `No merge set found for ${issueId}` }, { status: 404 });
4173
4419
  const results = [];
@@ -4183,34 +4429,44 @@ const postForgeMergeRoute = HttpRouter.add("POST", "/api/issues/:issueId/forge-m
4183
4429
  const workspacePath = mergeSet.workspaceType === "polyrepo" ? join(mergeSet.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`, repo.repoKey) : join(mergeSet.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
4184
4430
  let artifactUrl = repo.artifactUrl;
4185
4431
  let artifactId = repo.artifactId;
4186
- if (!artifactUrl && !artifactId) try {
4187
- const discovered = await adapter.discoverArtifact({
4188
- sourceBranch: repo.sourceBranch,
4189
- cwd: existsSync$1(workspacePath) ? workspacePath : repo.repoPath
4190
- });
4191
- if (discovered?.url || discovered?.id) {
4192
- artifactUrl = discovered.url;
4193
- artifactId = discovered.id;
4432
+ if (!artifactUrl && !artifactId) {
4433
+ try {
4434
+ const discovered = await adapter.discoverArtifact({
4435
+ sourceBranch: repo.sourceBranch,
4436
+ cwd: existsSync$1(workspacePath) ? workspacePath : repo.repoPath
4437
+ });
4438
+ artifactUrl = discovered?.url;
4439
+ artifactId = discovered?.id;
4440
+ } catch {}
4441
+ if (artifactUrl || artifactId) {
4194
4442
  mergeSet = withRepoArtifactUrlSync(mergeSet, repo.repoKey, artifactUrl ?? "", artifactId);
4195
4443
  upsertMergeSetSync(mergeSet);
4196
4444
  console.log(`[forge-merge] Discovered artifact for ${issueId}/${repo.repoKey}: ${artifactUrl}`);
4197
4445
  } else {
4198
- mergeSet = withRepoStateSync(mergeSet, repo.repoKey, { mergeStatus: "skipped" });
4446
+ const classification = await assessRepoMergeCompleteness(repo);
4447
+ if (classification.state === "merged") {
4448
+ mergeSet = withRepoStateSync(mergeSet, repo.repoKey, { mergeStatus: "merged" });
4449
+ results.push({
4450
+ repoKey: repo.repoKey,
4451
+ merged: true
4452
+ });
4453
+ } else if (classification.state === "no-changes") {
4454
+ mergeSet = withRepoStateSync(mergeSet, repo.repoKey, { mergeStatus: "skipped" });
4455
+ results.push({
4456
+ repoKey: repo.repoKey,
4457
+ merged: true
4458
+ });
4459
+ } else {
4460
+ mergeSet = withRepoStateSync(mergeSet, repo.repoKey, { mergeStatus: "blocked" });
4461
+ results.push({
4462
+ repoKey: repo.repoKey,
4463
+ merged: false,
4464
+ error: classification.reason
4465
+ });
4466
+ }
4199
4467
  upsertMergeSetSync(mergeSet);
4200
- results.push({
4201
- repoKey: repo.repoKey,
4202
- merged: true
4203
- });
4204
4468
  continue;
4205
4469
  }
4206
- } catch {
4207
- mergeSet = withRepoStateSync(mergeSet, repo.repoKey, { mergeStatus: "skipped" });
4208
- upsertMergeSetSync(mergeSet);
4209
- results.push({
4210
- repoKey: repo.repoKey,
4211
- merged: true
4212
- });
4213
- continue;
4214
4470
  }
4215
4471
  try {
4216
4472
  await adapter.mergeReviewArtifact({
@@ -4235,7 +4491,7 @@ const postForgeMergeRoute = HttpRouter.add("POST", "/api/issues/:issueId/forge-m
4235
4491
  }
4236
4492
  }
4237
4493
  if (results.filter((r) => r.merged).length > 0) {
4238
- const { emitActivityEntrySync, emitActivityTtsSync } = await import("./activity-logger-OEUBdfZ8.js");
4494
+ const { emitActivityEntrySync, emitActivityTtsSync } = await import("./activity-logger-CMthG6Vd.js");
4239
4495
  emitActivityEntrySync({
4240
4496
  source: "dashboard",
4241
4497
  level: "success",
@@ -4360,7 +4616,7 @@ const postWorkspaceApproveRoute = HttpRouter.add("POST", "/api/issues/:issueId/a
4360
4616
  console.log(`[approve] Starting role pipeline for ${issueId}...`);
4361
4617
  let reviewResult;
4362
4618
  try {
4363
- const { spawnReviewRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
4619
+ const { spawnReviewRoleForIssue } = await import("./review-agent-CD4RCI0Y.js");
4364
4620
  reviewResult = await Effect.runPromise(spawnReviewRoleForIssue({
4365
4621
  issueId,
4366
4622
  workspace: workspacePath,
@@ -4407,7 +4663,7 @@ const postWorkspaceApproveRoute = HttpRouter.add("POST", "/api/issues/:issueId/a
4407
4663
  }
4408
4664
  console.log(`[approve] Step 3/3: Running server-side rebase for ${issueId}...`);
4409
4665
  try {
4410
- const { rebaseFeatureBranch } = await import("./merge-rebase-C1KIVr0s.js");
4666
+ const { rebaseFeatureBranch } = await import("./merge-rebase-DGQpYJU3.js");
4411
4667
  const workspacePathForRebase = join(projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
4412
4668
  const rebaseResult = await Effect.runPromise(rebaseFeatureBranch(workspacePathForRebase, branchName, "main", issueId));
4413
4669
  if (!rebaseResult.success) {
@@ -4427,7 +4683,7 @@ const postWorkspaceApproveRoute = HttpRouter.add("POST", "/api/issues/:issueId/a
4427
4683
  completePendingOperation(issueId, pushResult.error);
4428
4684
  return jsonResponse({ error: pushResult.error }, { status: pushResult.httpStatus });
4429
4685
  }
4430
- const { approve: lifecycleApprove } = await import("./lifecycle-sycO16hj.js");
4686
+ const { approve: lifecycleApprove } = await import("./lifecycle-DDN8ApVY.js");
4431
4687
  const ghResolved = resolveGitHubIssueSync(issueId);
4432
4688
  const isGitHubIssueFlag = ghResolved.isGitHub;
4433
4689
  const lifecycleCtx = {
@@ -4461,7 +4717,7 @@ const getMergeQueueRoute = HttpRouter.add("GET", "/api/merge-queue", httpHandler
4461
4717
  })));
4462
4718
  const postInternalPipelineNotifyRoute = HttpRouter.add("POST", "/api/internal/pipeline/notify", httpHandler(Effect.gen(function* () {
4463
4719
  const request = yield* HttpServerRequest.HttpServerRequest;
4464
- const { INTERNAL_TOKEN_HEADER, getInternalTokenSync } = yield* Effect.promise(() => import("./internal-token-DXdfprGr.js"));
4720
+ const { INTERNAL_TOKEN_HEADER, getInternalTokenSync } = yield* Effect.promise(() => import("./internal-token-M9omeXM1.js"));
4465
4721
  const expected = getInternalTokenSync();
4466
4722
  if (!expected) return jsonResponse({
4467
4723
  ok: false,
@@ -4475,7 +4731,7 @@ const postInternalPipelineNotifyRoute = HttpRouter.add("POST", "/api/internal/pi
4475
4731
  }, 403);
4476
4732
  const event = yield* readJsonBody;
4477
4733
  const type = event.type;
4478
- const { notifyPipelineSync } = yield* Effect.promise(() => import("./pipeline-notifier-6iCJplFZ.js"));
4734
+ const { notifyPipelineSync } = yield* Effect.promise(() => import("./pipeline-notifier-ImNXknf0.js"));
4479
4735
  switch (type) {
4480
4736
  case "status_changed": {
4481
4737
  const issueId = event.issueId;
@@ -4643,7 +4899,7 @@ init_types$1();
4643
4899
  init_review_context();
4644
4900
  init_tldr_daemon();
4645
4901
  const execAsync$4 = promisify(exec);
4646
- const execFileAsync$2 = promisify(execFile);
4902
+ const execFileAsync$3 = promisify(execFile);
4647
4903
  function getWorkspaceLocation(issueId) {
4648
4904
  try {
4649
4905
  const meta = loadWorkspaceMetadataSync(issueId);
@@ -4702,7 +4958,7 @@ async function getRepoGitStatusAsync(workspacePath) {
4702
4958
  }
4703
4959
  async function getMrUrlAsync(issueId, workspacePath) {
4704
4960
  try {
4705
- const { stdout } = await execFileAsync$2("gh", [
4961
+ const { stdout } = await execFileAsync$3("gh", [
4706
4962
  "pr",
4707
4963
  "view",
4708
4964
  `feature/${issueId.toLowerCase()}`,
@@ -5250,7 +5506,7 @@ const patchWorkspaceTieredExecutionRoute = HttpRouter.add("PATCH", "/api/workspa
5250
5506
  if (override !== "on" && override !== "off" && override !== null && override !== void 0) return jsonResponse({ error: "Invalid tiered-execution override" }, { status: 400 });
5251
5507
  const project = getProjectSync(extractPrefixSync(issueId) ?? issueId.split("-")[0]);
5252
5508
  if (!project) return jsonResponse({ error: "Project not found" }, { status: 404 });
5253
- yield* Effect.promise(() => import("./record-t6V-3Dcj.js").then((m) => m.writeRecordTieredExecutionOverride(project, issueId, override)));
5509
+ yield* Effect.promise(() => import("./record-CtroO946.js").then((m) => m.writeRecordTieredExecutionOverride(project, issueId, override)));
5254
5510
  const projectPath = project.path;
5255
5511
  const location = yield* resolvePlanLocation(projectPath, issueId);
5256
5512
  if (!location) return jsonResponse({ error: "No xBRIEF plan found for this workspace" }, { status: 404 });
@@ -5538,6 +5794,48 @@ const postWorkspaceCleanRoute = HttpRouter.add("POST", "/api/workspaces/:issueId
5538
5794
  })));
5539
5795
  const stashCleanRouteLayer = Layer.mergeAll(getWorkspaceStashesRoute, postWorkspaceRecoverStashRoute, deleteWorkspaceStashRoute, getWorkspaceCleanPreviewRoute, postWorkspaceCleanRoute);
5540
5796
  //#endregion
5797
+ //#region ../../lib/cloister/review-branch-push.ts
5798
+ init_project_repos();
5799
+ const execFileAsync$2 = promisify(execFile);
5800
+ const REVIEW_PUSH_TIMEOUT_MS = 3e4;
5801
+ async function runReviewGit(args, options) {
5802
+ await execFileAsync$2("git", args, options);
5803
+ }
5804
+ function reviewGitOptions(cwd) {
5805
+ return {
5806
+ cwd,
5807
+ timeout: REVIEW_PUSH_TIMEOUT_MS,
5808
+ killSignal: "SIGKILL",
5809
+ env: {
5810
+ ...process.env,
5811
+ GIT_TERMINAL_PROMPT: "0",
5812
+ GIT_ASKPASS: "true",
5813
+ SSH_ASKPASS: "true"
5814
+ }
5815
+ };
5816
+ }
5817
+ async function pushLocalReviewBranches(issueId, workspacePath, dependencies = {}) {
5818
+ const roots = (dependencies.resolveRoots ?? resolveWorkspaceRepoRootsSync)(issueId, workspacePath);
5819
+ const runGit = dependencies.runGit ?? runReviewGit;
5820
+ for (const root of roots) {
5821
+ try {
5822
+ await runGit([
5823
+ "rev-parse",
5824
+ "--verify",
5825
+ "--quiet",
5826
+ `refs/heads/${root.sourceBranch}`
5827
+ ], reviewGitOptions(root.dir));
5828
+ } catch {
5829
+ continue;
5830
+ }
5831
+ await runGit([
5832
+ "push",
5833
+ "origin",
5834
+ root.sourceBranch
5835
+ ], reviewGitOptions(root.dir));
5836
+ }
5837
+ }
5838
+ //#endregion
5541
5839
  //#region ../../lib/cloister/request-review-pipeline.ts
5542
5840
  init_in_flight_guard();
5543
5841
  /**
@@ -5558,6 +5856,10 @@ function createRequestReviewPipeline() {
5558
5856
  await deps.onVerificationError(outcome);
5559
5857
  return;
5560
5858
  }
5859
+ if (outcome.outcome === "deferred") {
5860
+ await deps.onVerificationDeferred?.(outcome);
5861
+ return;
5862
+ }
5561
5863
  await deps.pushBranch();
5562
5864
  await deps.dispatchReview();
5563
5865
  }, deps.onError);
@@ -5567,6 +5869,92 @@ function createRequestReviewPipeline() {
5567
5869
  }
5568
5870
  };
5569
5871
  }
5872
+ /** Shared host-side pipeline so HTTP requests and durable intent recovery coalesce. */
5873
+ const requestReviewPipeline = createRequestReviewPipeline();
5874
+ //#endregion
5875
+ //#region services/durable-review-pipeline.ts
5876
+ init_durable_review_pipeline();
5877
+ init_projects();
5878
+ async function startDashboardDurableReviewPipeline(input, dependencies) {
5879
+ const { issueId, prUrl, setReviewPending, dispatchReview } = input;
5880
+ const resolved = dependencies.resolveWorkspace(issueId);
5881
+ if (!resolved) return false;
5882
+ const { workspacePath, workspaceInfo, branchName } = resolved;
5883
+ return requestReviewPipeline.start(issueId, {
5884
+ verify: () => dependencies.verify ? dependencies.verify(issueId, workspacePath, workspaceInfo) : Effect.runPromise(runVerificationForIssue(issueId, workspacePath, workspaceInfo, "durable-review")),
5885
+ onVerificationFailed: (outcome) => {
5886
+ setReviewPending({
5887
+ reviewStatus: "pending",
5888
+ reviewNotes: `Verification failed at ${outcome.failedCheck} — fix and resubmit`
5889
+ });
5890
+ },
5891
+ onVerificationError: (outcome) => {
5892
+ setReviewPending({
5893
+ reviewStatus: "pending",
5894
+ reviewNotes: `Verification infrastructure error: ${outcome.message}`
5895
+ });
5896
+ },
5897
+ onVerificationDeferred: (outcome) => {
5898
+ setReviewPending({
5899
+ reviewStatus: "pending",
5900
+ reviewNotes: outcome.reason
5901
+ });
5902
+ console.log(`[review-status] durable review verification deferred for ${issueId}: ${outcome.reason}`);
5903
+ },
5904
+ pushBranch: () => dependencies.pushBranch(resolved),
5905
+ dispatchReview: async () => {
5906
+ const result = await dispatchReview({
5907
+ issueId,
5908
+ workspace: workspacePath,
5909
+ branch: branchName,
5910
+ ...prUrl ? { prUrl } : {}
5911
+ });
5912
+ if (!result.success) {
5913
+ setReviewPending({
5914
+ reviewStatus: "pending",
5915
+ reviewNotes: result.error || result.message || "Failed to dispatch review"
5916
+ });
5917
+ return;
5918
+ }
5919
+ const message = result.message?.startsWith("Review already in progress") ? "already in progress — no-op" : "auto-dispatched from durable journal intent";
5920
+ console.log(`[review-status] review dispatch for ${issueId}: ${message} (host-side)`);
5921
+ },
5922
+ onError: (error) => {
5923
+ const detail = error instanceof Error ? error.message : String(error);
5924
+ setReviewPending({
5925
+ reviewStatus: "pending",
5926
+ reviewNotes: `Review pipeline error: ${detail}`
5927
+ });
5928
+ console.warn(`[review-status] host-side durable review pipeline for ${issueId} failed (non-fatal): ${detail}`);
5929
+ }
5930
+ });
5931
+ }
5932
+ async function pushDashboardReviewBranch(workspace, dependencies) {
5933
+ if (workspace.workspaceInfo.isRemote && workspace.workspaceInfo.vmName) {
5934
+ await dependencies.pushRemote(workspace.workspaceInfo.vmName, workspace.workspacePath, workspace.branchName);
5935
+ return;
5936
+ }
5937
+ await pushLocalReviewBranches(workspace.issueId, workspace.workspacePath);
5938
+ }
5939
+ function registerDashboardDurableReviewPipeline(dependencies) {
5940
+ registerDurableReviewPipelineHandler((input) => startDashboardDurableReviewPipeline(input, {
5941
+ resolveWorkspace: (issueId) => {
5942
+ const workspaceInfo = dependencies.getWorkspaceInfo(issueId);
5943
+ if (!workspaceInfo.exists) return null;
5944
+ const resolved = resolveProjectFromIssueSync(issueId);
5945
+ if (!resolved) return null;
5946
+ const workspacePath = workspaceInfo.isRemote ? workspaceInfo.remotePath : workspaceInfo.localPath || join(resolved.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
5947
+ if (!workspacePath) return null;
5948
+ return {
5949
+ issueId,
5950
+ workspacePath,
5951
+ workspaceInfo,
5952
+ branchName: `feature/${issueId.toLowerCase()}`
5953
+ };
5954
+ },
5955
+ pushBranch: (workspace) => pushDashboardReviewBranch(workspace, dependencies)
5956
+ }));
5957
+ }
5570
5958
  //#endregion
5571
5959
  //#region routes/workspaces/review-pipeline.ts
5572
5960
  /**
@@ -5594,9 +5982,31 @@ init_conflict_gate();
5594
5982
  init_agents();
5595
5983
  const execAsync$2 = promisify(exec);
5596
5984
  const MAX_AUTO_REQUEUE = 25;
5597
- const requestReviewPipeline = createRequestReviewPipeline();
5985
+ const pushRemoteReviewBranch = async (vmName, workspacePath, branchName) => {
5986
+ await execAsync$2(flyExecCmd(vmName, `cd ${workspacePath} && GIT_TERMINAL_PROMPT=0 GIT_ASKPASS=true SSH_ASKPASS=true git push origin ${branchName}`), {
5987
+ encoding: "utf-8",
5988
+ timeout: 3e4
5989
+ });
5990
+ };
5991
+ registerDashboardDurableReviewPipeline({
5992
+ getWorkspaceInfo: getWorkspaceInfoForIssue,
5993
+ pushRemote: pushRemoteReviewBranch
5994
+ });
5598
5995
  /** Safe `.message` read for caught values of unknown shape. */
5599
5996
  const errorMessage = (e) => e instanceof Error ? e.message : void 0;
5997
+ /**
5998
+ * Push the feature branch of every repo in the workspace (PAN-2948).
5999
+ *
6000
+ * A polyrepo workspace root is a one-commit wrapper repo with no remote and no
6001
+ * feature branch — pushing there fails and, on the verified-dispatch path,
6002
+ * kills the whole re-review pipeline. Loop the resolved repo roots instead
6003
+ * (mirrors rebase-helper.ts), skipping repos whose feature branch doesn't
6004
+ * exist locally (untouched sub-repos). Monorepo resolves to a single root at
6005
+ * the workspace path, preserving the previous behavior.
6006
+ */
6007
+ async function pushFeatureBranches(issueId, workspacePath) {
6008
+ await pushLocalReviewBranches(issueId, workspacePath);
6009
+ }
5600
6010
  function shouldTreatAsRerun(status) {
5601
6011
  if (!status) return false;
5602
6012
  return status.readyForMerge === true || status.reviewStatus === "passed" || status.testStatus === "passed" || status.mergeStatus === "failed";
@@ -5708,15 +6118,12 @@ const postWorkspaceReviewRoute = HttpRouter.add("POST", "/api/review/:issueId/tr
5708
6118
  console.warn(`[review] Could not transition ${issueId} to in_review: ${errorMessage(err)}`);
5709
6119
  });
5710
6120
  try {
5711
- await execAsync$2(`git push origin ${branchName}`, {
5712
- cwd: workspacePath,
5713
- encoding: "utf-8"
5714
- });
6121
+ await pushFeatureBranches(issueId, workspacePath);
5715
6122
  } catch (pushErr) {
5716
6123
  console.log(`Feature branch push note: ${errorMessage(pushErr)}`);
5717
6124
  }
5718
6125
  try {
5719
- const { createReviewArtifactsForIssue } = await import("./review-artifacts-BLbSC4ke.js");
6126
+ const { createReviewArtifactsForIssue } = await import("./review-artifacts-DSMRIfuJ.js");
5720
6127
  const artifactResult = await Effect.runPromise(createReviewArtifactsForIssue(issueId, workspacePath));
5721
6128
  const primaryArtifact = artifactResult.mergeSet?.repos.find((repo) => !!repo.artifactUrl);
5722
6129
  artifactResult.mergeSet?.repos.find((repo) => repo.mergeStatus !== "skipped")?.targetBranch;
@@ -5771,7 +6178,12 @@ const postWorkspaceReviewRoute = HttpRouter.add("POST", "/api/review/:issueId/tr
5771
6178
  } catch {}
5772
6179
  return;
5773
6180
  }
5774
- const { spawnReviewRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
6181
+ if (verifyOutcome.outcome === "deferred") {
6182
+ console.log(`[review] Verification deferred for ${issueId}: ${verifyOutcome.reason}`);
6183
+ completePendingOperation(issueId, verifyOutcome.reason);
6184
+ return;
6185
+ }
6186
+ const { spawnReviewRoleForIssue } = await import("./review-agent-CD4RCI0Y.js");
5775
6187
  const prUrl = getReviewStatusSync(issueId)?.prUrl;
5776
6188
  const reviewResult = await Effect.runPromise(spawnReviewRoleForIssue({
5777
6189
  issueId,
@@ -5902,15 +6314,12 @@ const postWorkspaceRequestReviewRoute = HttpRouter.add("POST", "/api/review/:iss
5902
6314
  console.warn(`[request-review] Could not transition ${issueId} to in_review: ${errorMessage(err)}`);
5903
6315
  });
5904
6316
  try {
5905
- await execAsync$2(`git push origin ${branchNameRerun}`, {
5906
- cwd: workspacePathRerun,
5907
- encoding: "utf-8"
5908
- });
6317
+ await pushFeatureBranches(issueId, workspacePathRerun);
5909
6318
  } catch (pushErr) {
5910
6319
  console.log(`[request-review] Feature branch push note: ${errorMessage(pushErr)}`);
5911
6320
  }
5912
6321
  const prUrl = getReviewStatusSync(issueId)?.prUrl;
5913
- const { spawnReviewRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
6322
+ const { spawnReviewRoleForIssue } = await import("./review-agent-CD4RCI0Y.js");
5914
6323
  const result = await Effect.runPromise(spawnReviewRoleForIssue({
5915
6324
  issueId,
5916
6325
  workspace: workspacePathRerun,
@@ -5960,7 +6369,7 @@ const postWorkspaceRequestReviewRoute = HttpRouter.add("POST", "/api/review/:iss
5960
6369
  });
5961
6370
  } else {
5962
6371
  const workspacePath = join(resolved.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
5963
- const { spawnRun } = yield* Effect.promise(() => import("./agents-FlIgQ3ql.js"));
6372
+ const { spawnRun } = yield* Effect.promise(() => import("./agents-BKKkxKgK.js"));
5964
6373
  try {
5965
6374
  const testRun = yield* Effect.promise(() => spawnRun(issueId, "test", { workspace: workspacePath }));
5966
6375
  setReviewStatus(issueId, { testStatus: "testing" });
@@ -6037,6 +6446,7 @@ const postWorkspaceRequestReviewRoute = HttpRouter.add("POST", "/api/review/:iss
6037
6446
  verificationStatus: "pending",
6038
6447
  reviewNotes
6039
6448
  });
6449
+ clearFeedbackDeliveryStuck(canonicalIssueId);
6040
6450
  if (!requestReviewPipeline.start(canonicalIssueId, {
6041
6451
  verify: () => Effect.runPromise(runVerificationForIssue(issueId, workspacePath, workspaceInfo, "request-review")),
6042
6452
  onVerificationFailed: (outcome) => {
@@ -6055,13 +6465,17 @@ const postWorkspaceRequestReviewRoute = HttpRouter.add("POST", "/api/review/:iss
6055
6465
  autoRequeueCount: currentCount
6056
6466
  });
6057
6467
  },
6468
+ onVerificationDeferred: (outcome) => {
6469
+ console.log(`[request-review] Verification deferred for ${issueId}: ${outcome.reason}`);
6470
+ completePendingOperation(issueId, outcome.reason);
6471
+ },
6058
6472
  pushBranch: async () => {
6059
- const pushCommand = `git push origin ${branchName}`;
6060
- if (workspaceInfo.isRemote && workspaceInfo.vmName) await execAsync$2(flyExecCmd(workspaceInfo.vmName, `cd ${workspacePath} && ${pushCommand}`), { encoding: "utf-8" });
6061
- else await execAsync$2(pushCommand, {
6062
- cwd: workspacePath,
6063
- encoding: "utf-8"
6064
- });
6473
+ await pushDashboardReviewBranch({
6474
+ issueId,
6475
+ workspacePath,
6476
+ workspaceInfo,
6477
+ branchName
6478
+ }, { pushRemote: pushRemoteReviewBranch });
6065
6479
  console.log(`[request-review] Pushed verified branch ${branchName} for ${issueId}`);
6066
6480
  },
6067
6481
  dispatchReview: async () => {
@@ -6070,7 +6484,7 @@ const postWorkspaceRequestReviewRoute = HttpRouter.add("POST", "/api/review/:iss
6070
6484
  testStatus: "pending",
6071
6485
  reviewNotes
6072
6486
  });
6073
- const { spawnReviewRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
6487
+ const { spawnReviewRoleForIssue } = await import("./review-agent-CD4RCI0Y.js");
6074
6488
  const result = await Effect.runPromise(spawnReviewRoleForIssue({
6075
6489
  issueId,
6076
6490
  workspace: workspacePath,
@@ -6157,12 +6571,12 @@ const reviewPipelineRouteLayer = Layer.mergeAll(postWorkspaceReviewRoute, postWo
6157
6571
  * stay owned by ../workspaces.js.
6158
6572
  */
6159
6573
  init_issue_id();
6160
- init_archive_planning();
6161
6574
  init_projects();
6162
6575
  init_review_status();
6163
6576
  init_agents();
6164
6577
  init_model_validation();
6165
6578
  init_config_yaml();
6579
+ init_pipeline_notifier();
6166
6580
  const execAsync$1 = promisify(exec);
6167
6581
  function resolveConfiguredReviewModel() {
6168
6582
  try {
@@ -6172,6 +6586,32 @@ function resolveConfiguredReviewModel() {
6172
6586
  }
6173
6587
  }
6174
6588
  /**
6589
+ * Read and re-emit canonical review status without mutating it. This is the
6590
+ * operator escape hatch for PAN-2988-style lost review.status_changed events.
6591
+ */
6592
+ function processResyncReviewStatus(issueId) {
6593
+ const status = getReviewStatusSync(issueId);
6594
+ if (!status) return {
6595
+ httpStatus: 404,
6596
+ body: {
6597
+ ok: false,
6598
+ error: `no review status found for ${issueId}`
6599
+ }
6600
+ };
6601
+ notifyPipelineSync({
6602
+ type: "status_changed",
6603
+ issueId,
6604
+ status
6605
+ });
6606
+ return {
6607
+ httpStatus: 200,
6608
+ body: {
6609
+ ok: true,
6610
+ status
6611
+ }
6612
+ };
6613
+ }
6614
+ /**
6175
6615
  * Core logic for POST /api/review/:issueId/reset (synchronous, testable).
6176
6616
  *
6177
6617
  * Resets the specialist pipeline state (review / test / merge / verification) for
@@ -6379,7 +6819,7 @@ const postWorkspaceResetReviewRoute = HttpRouter.add("POST", "/api/review/:issue
6379
6819
  const result = processResetReviewPipeline(issueId, resetWorkspace.exists);
6380
6820
  if (result.httpStatus !== 200) return jsonResponse(result.body, { status: result.httpStatus });
6381
6821
  try {
6382
- const { resetPostMergeState } = yield* Effect.promise(() => import("./merge-agent-BQM3a8z5.js"));
6822
+ const { resetPostMergeState } = yield* Effect.promise(() => import("./merge-agent-DrXa1CpW.js"));
6383
6823
  resetPostMergeState(issueId);
6384
6824
  } catch (err) {
6385
6825
  console.warn(`[reset-review] resetPostMergeState best-effort failed for ${issueId}:`, err);
@@ -6388,7 +6828,7 @@ const postWorkspaceResetReviewRoute = HttpRouter.add("POST", "/api/review/:issue
6388
6828
  const rerun = body?.rerun === true;
6389
6829
  if (rerun) try {
6390
6830
  yield* Effect.promise(async () => {
6391
- const { spawnReviewRoleForIssue } = await import("./review-agent-DJRO8EG8.js");
6831
+ const { spawnReviewRoleForIssue } = await import("./review-agent-CD4RCI0Y.js");
6392
6832
  const dispatchArgs = buildReviewRedispatchArgs(issueId, resetWorkspace, workspaceInfo, resolved);
6393
6833
  if (dispatchArgs) {
6394
6834
  const result = await Effect.runPromise(spawnReviewRoleForIssue({
@@ -6414,10 +6854,16 @@ const postWorkspaceResetReviewRoute = HttpRouter.add("POST", "/api/review/:issue
6414
6854
  rerun
6415
6855
  });
6416
6856
  })));
6857
+ const postReviewResyncRoute = HttpRouter.add("POST", "/api/review/:issueId/resync", httpHandler(Effect.gen(function* () {
6858
+ const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
6859
+ if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
6860
+ const result = processResyncReviewStatus(issueId.toUpperCase());
6861
+ return jsonResponse(result.body, { status: result.httpStatus });
6862
+ })));
6417
6863
  const postWorkspaceReviewPurgeRoute = HttpRouter.add("POST", "/api/review/:issueId/purge", httpHandler(Effect.gen(function* () {
6418
6864
  const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
6419
6865
  if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
6420
- const { purgeReviewAgentsForIssue } = yield* Effect.promise(() => import("./review-agent-DJRO8EG8.js"));
6866
+ const { purgeReviewAgentsForIssue } = yield* Effect.promise(() => import("./review-agent-CD4RCI0Y.js"));
6421
6867
  const projectKey = resolveProjectFromIssueSync(issueId)?.projectKey;
6422
6868
  const purge = yield* Effect.promise(() => purgeReviewAgentsForIssue(projectKey, issueId));
6423
6869
  const workspaceInfo = getWorkspaceInfoForIssue(issueId);
@@ -6447,8 +6893,8 @@ const postWorkspaceAbortReviewRoute = HttpRouter.add("POST", "/api/review/:issue
6447
6893
  success: false,
6448
6894
  error: "Workspace does not exist"
6449
6895
  }, { status: 400 });
6450
- const { resolveProjectFromIssueSync } = yield* Effect.promise(() => import("./projects-9SkRpES9.js"));
6451
- const { killAllReviewerSessions } = yield* Effect.promise(() => import("./review-agent-DJRO8EG8.js"));
6896
+ const { resolveProjectFromIssueSync } = yield* Effect.promise(() => import("./projects-B03Wr-xc.js"));
6897
+ const { killAllReviewerSessions } = yield* Effect.promise(() => import("./review-agent-CD4RCI0Y.js"));
6452
6898
  const { killed, failed } = yield* killAllReviewerSessions(resolveProjectFromIssueSync(issueId)?.projectKey, issueId);
6453
6899
  setReviewStatus(issueId, {
6454
6900
  reviewStatus: "pending",
@@ -6520,8 +6966,8 @@ const getReviewConfigRoute = HttpRouter.add("GET", "/api/review/:issueId/config"
6520
6966
  const issueId = ((yield* HttpRouter.params)["issueId"] ?? "").toUpperCase();
6521
6967
  if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
6522
6968
  return jsonResponse(yield* Effect.promise(async () => {
6523
- const { readIssueRecordSync, resolveProjectForIssue } = await import("./record-t6V-3Dcj.js");
6524
- const { resolveReviewMode, resolveReReviewScope } = await import("./review-agent-DJRO8EG8.js");
6969
+ const { readIssueRecordSync, resolveProjectForIssue } = await import("./record-CtroO946.js");
6970
+ const { resolveReviewMode, resolveReReviewScope } = await import("./review-agent-CD4RCI0Y.js");
6525
6971
  const project = resolveProjectForIssue(issueId);
6526
6972
  const record = project ? readIssueRecordSync(project, issueId) : null;
6527
6973
  return {
@@ -6556,9 +7002,9 @@ const postReviewConfigRoute = HttpRouter.add("POST", "/api/review/:issueId/confi
6556
7002
  return jsonResponse({ error: error instanceof Error ? error.message : String(error) }, { status: 400 });
6557
7003
  }
6558
7004
  return jsonResponse(yield* Effect.promise(async () => {
6559
- const { resolveProjectForIssue } = await import("./record-t6V-3Dcj.js");
6560
- const { updateIssueRecord } = await import("./record-update-DACtKh6_.js");
6561
- const { resolveReviewMode, resolveReReviewScope } = await import("./review-agent-DJRO8EG8.js");
7005
+ const { resolveProjectForIssue } = await import("./record-CtroO946.js");
7006
+ const { updateIssueRecord } = await import("./record-update-DH6dLJID.js");
7007
+ const { resolveReviewMode, resolveReReviewScope } = await import("./review-agent-CD4RCI0Y.js");
6562
7008
  const record = await updateIssueRecord(resolveProjectForIssue(issueId), issueId, (current) => {
6563
7009
  if (hasMode) if (body.reviewMode === null) delete current.reviewMode;
6564
7010
  else current.reviewMode = body.reviewMode;
@@ -6583,7 +7029,7 @@ const postReviewConfigRoute = HttpRouter.add("POST", "/api/review/:issueId/confi
6583
7029
  };
6584
7030
  }));
6585
7031
  })));
6586
- const reviewControlRouteLayer = Layer.mergeAll(postWorkspaceResetReviewRoute, postWorkspaceReviewPurgeRoute, postWorkspaceAbortReviewRoute, postWorkspaceUnstickRoute, postWorkspaceDeaconIgnoreRoute, postWorkspaceAutoMergeRoute, deleteWorkspacePendingRoute, getReviewConfigRoute, postReviewConfigRoute);
7032
+ const reviewControlRouteLayer = Layer.mergeAll(postWorkspaceResetReviewRoute, postReviewResyncRoute, postWorkspaceReviewPurgeRoute, postWorkspaceAbortReviewRoute, postWorkspaceUnstickRoute, postWorkspaceDeaconIgnoreRoute, postWorkspaceAutoMergeRoute, deleteWorkspacePendingRoute, getReviewConfigRoute, postReviewConfigRoute);
6587
7033
  //#endregion
6588
7034
  //#region routes/workspaces/uat-stack-actions.ts
6589
7035
  init_activity_logger();
@@ -6991,7 +7437,7 @@ async function readWorkspacePlanningMarkdown(issueId, fileName) {
6991
7437
  */
6992
7438
  async function readWorkspaceContinueFile(_projectPath, workspacePath, issueId) {
6993
7439
  try {
6994
- const { readRecordContinueViewSync, getProjectConfigFromWorkspacePath, resolveProjectForIssue } = await import("./record-t6V-3Dcj.js");
7440
+ const { readRecordContinueViewSync, getProjectConfigFromWorkspacePath, resolveProjectForIssue } = await import("./record-CtroO946.js");
6995
7441
  const recordView = readRecordContinueViewSync(resolveProjectForIssue(issueId) ?? getProjectConfigFromWorkspacePath(workspacePath), issueId);
6996
7442
  return recordView ? JSON.stringify(recordView, null, 2) : null;
6997
7443
  } catch {
@@ -7750,7 +8196,7 @@ const getWorkspaceReviewStatusRoute = HttpRouter.add("GET", "/api/review/:issueI
7750
8196
  if (queuePosition === null) try {
7751
8197
  const resolved = resolveProjectFromIssueSync(issueId);
7752
8198
  if (resolved) {
7753
- const { getQueueForProject } = yield* Effect.promise(() => import("./merge-DK23JEdS.js"));
8199
+ const { getQueueForProject } = yield* Effect.promise(() => import("./merge-idOG--29.js"));
7754
8200
  const mergePos = findPositionInQueueSync(issueId, getQueueForProject(resolved.projectKey).map((e) => ({
7755
8201
  id: String(e.id),
7756
8202
  type: "task",
@@ -7788,10 +8234,10 @@ const postWorkspaceReviewStatusRoute = HttpRouter.add("POST", "/api/review/:issu
7788
8234
  const workspaceInfo = getWorkspaceInfoForIssue(issueId);
7789
8235
  if (workspaceInfo.exists && workspaceInfo.localPath) {
7790
8236
  const localPath = workspaceInfo.localPath;
7791
- const { getWorkspaceGitInfo } = yield* Effect.promise(() => import("./git-utils-Dry_Ka_D.js"));
8237
+ const { snapshotWorkspaceHeadsPromise } = yield* Effect.promise(() => import("./git-utils-CI6cwyyC.js"));
7792
8238
  try {
7793
- const gitInfo = yield* getWorkspaceGitInfo(localPath);
7794
- if (gitInfo.HEAD) update.reviewedAtCommit = gitInfo.HEAD;
8239
+ const headAnchor = yield* Effect.promise(() => snapshotWorkspaceHeadsPromise(issueId, localPath));
8240
+ if (headAnchor) update.reviewedAtCommit = headAnchor;
7795
8241
  } catch {}
7796
8242
  }
7797
8243
  }
@@ -7803,7 +8249,7 @@ const postWorkspaceReviewStatusRoute = HttpRouter.add("POST", "/api/review/:issu
7803
8249
  if (verificationStatus) update.verificationStatus = verificationStatus;
7804
8250
  if (readyForMerge !== void 0) update.readyForMerge = readyForMerge;
7805
8251
  const status = setReviewStatus(issueId, update);
7806
- const { getTmuxSessionName } = yield* Effect.promise(() => import("./specialists-DVj0hvaL.js"));
8252
+ const { getTmuxSessionName } = yield* Effect.promise(() => import("./specialists-Tdezg_6N.js"));
7807
8253
  const projectKey = resolveProjectFromIssueSync(issueId)?.projectKey;
7808
8254
  if (reviewStatus && [
7809
8255
  "passed",
@@ -7821,7 +8267,7 @@ const postWorkspaceReviewStatusRoute = HttpRouter.add("POST", "/api/review/:issu
7821
8267
  const agentId = `agent-${issueId.toLowerCase()}`;
7822
8268
  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.`;
7823
8269
  try {
7824
- const { writeFeedbackFile } = yield* Effect.promise(() => import("./feedback-writer-qmiMbqTZ.js"));
8270
+ const { writeFeedbackFile } = yield* Effect.promise(() => import("./feedback-writer-D1fm-5Z8.js"));
7825
8271
  const wsInfo = getWorkspaceInfoForIssue(issueId);
7826
8272
  const fileResult = yield* Effect.promise(() => writeFeedbackFile({
7827
8273
  issueId,
@@ -7885,7 +8331,7 @@ const postWorkspaceReviewStatusRoute = HttpRouter.add("POST", "/api/review/:issu
7885
8331
  const agentId = `agent-${issueId.toLowerCase()}`;
7886
8332
  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.`;
7887
8333
  try {
7888
- const { writeFeedbackFile } = yield* Effect.promise(() => import("./feedback-writer-qmiMbqTZ.js"));
8334
+ const { writeFeedbackFile } = yield* Effect.promise(() => import("./feedback-writer-D1fm-5Z8.js"));
7889
8335
  const wsInfo = getWorkspaceInfoForIssue(issueId);
7890
8336
  const fileResult = yield* Effect.promise(() => writeFeedbackFile({
7891
8337
  issueId,
@@ -7918,14 +8364,14 @@ const postWorkspaceReviewStatusRoute = HttpRouter.add("POST", "/api/review/:issu
7918
8364
  });
7919
8365
  yield* Effect.promise(async () => {
7920
8366
  try {
7921
- const { resolveProjectFromIssueSync, getProjectSync } = await import("./projects-9SkRpES9.js");
8367
+ const { resolveProjectFromIssueSync, getProjectSync } = await import("./projects-B03Wr-xc.js");
7922
8368
  const project = resolveProjectFromIssueSync(issueId);
7923
8369
  const repo = (project ? getProjectSync(project.projectKey) : null)?.github_repo;
7924
8370
  if (!repo || !repo.includes("/")) return;
7925
8371
  const [owner, name] = repo.split("/");
7926
8372
  const wsInfo = getWorkspaceInfoForIssue(issueId);
7927
8373
  if (!wsInfo?.localPath) return;
7928
- const { postOverdeckTestsStatus } = await import("./github-app-CPfoFAdV.js");
8374
+ const { postOverdeckTestsStatus } = await import("./github-app-DtAsvwzK.js");
7929
8375
  await postOverdeckTestsStatus(wsInfo.localPath, owner, name, "success", "Test specialist passed");
7930
8376
  } catch (err) {
7931
8377
  console.warn(`[review-status] Failed to post overdeck/tests for ${issueId}: ${err.message}`);
@@ -7967,7 +8413,7 @@ const postWorkspaceRefreshTokenRoute = HttpRouter.add("POST", "/api/workspaces/:
7967
8413
  if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
7968
8414
  const issueLower = issueId.toLowerCase();
7969
8415
  const workspacePath = join(getProjectPath(void 0, extractPrefixSync(issueId) ?? issueId.split("-")[0]), "workspaces", `feature-${issueLower}`);
7970
- const { refreshWorkspaceToken, isGitHubAppConfigured } = yield* Effect.promise(() => import("./github-app-CPfoFAdV.js"));
8416
+ const { refreshWorkspaceToken, isGitHubAppConfigured } = yield* Effect.promise(() => import("./github-app-DtAsvwzK.js"));
7971
8417
  if (!isGitHubAppConfigured()) return jsonResponse({
7972
8418
  success: false,
7973
8419
  error: "GitHub App not configured"
@@ -7982,4 +8428,4 @@ const workspacesRouteLayer = Layer.mergeAll(workspaceDataRouteLayer, postWorkspa
7982
8428
  //#endregion
7983
8429
  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 };
7984
8430
 
7985
- //# sourceMappingURL=workspaces-hWvy9eKs.js.map
8431
+ //# sourceMappingURL=workspaces-j1e_6aAT.js.map