specrails-desktop 2.21.0 → 2.23.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 (533) hide show
  1. package/README.md +3 -3
  2. package/client/dist/assets/{ActivityFeedPage-BPkf89Xk.js → ActivityFeedPage-Cq4UlyrP.js} +1 -1
  3. package/client/dist/assets/AgentBrowserCapture-BqGtoL0L.js +1 -0
  4. package/client/dist/assets/{AgentModeCodePane-DhVkOSdv.js → AgentModeCodePane-W7XIIcKj.js} +2 -2
  5. package/client/dist/assets/AgentModeJobsPane-CryUvMB9.js +1 -0
  6. package/client/dist/assets/AgentsPage-Re0K2JCa.js +86 -0
  7. package/client/dist/assets/AnalyticsPage-27FMsav_.js +1 -0
  8. package/client/dist/assets/{BarChart-9_p1-qtv.js → BarChart-BiFF8sw8.js} +1 -1
  9. package/client/dist/assets/CodePage-Ud12s91j.js +2 -0
  10. package/client/dist/assets/DesktopAnalyticsPage-BdjWlYgU.js +1 -0
  11. package/client/dist/assets/DocsDialog-DG_c7_6k.js +11 -0
  12. package/client/dist/assets/DocsPage-CDieUvMv.js +11 -0
  13. package/client/dist/assets/{ExportDropdown-Clt8DyCs.js → ExportDropdown-Cokk4zlC.js} +1 -1
  14. package/client/dist/assets/IntegrationsPage-oyvHxjdV.js +3 -0
  15. package/client/dist/assets/InteractiveJobComposer-C2w9yVm8.js +19 -0
  16. package/client/dist/assets/JobDetailModal-DEStK2P4.js +1 -0
  17. package/client/dist/assets/JobDetailPage-BqdQ1wOs.js +1 -0
  18. package/client/dist/assets/JobsPage-BH5pl9o_.js +1 -0
  19. package/client/dist/assets/LoopBuilderPage-B8QhQ4FV.js +7 -0
  20. package/client/dist/assets/LoopPreviewModal-CK58XIQ_.js +1 -0
  21. package/client/dist/assets/LoopsPage-C0aVmXxN.js +1 -0
  22. package/client/dist/assets/ProjectSettingsDialog-Bf_x-MSF.js +1 -0
  23. package/client/dist/assets/TemplatePreviewModal-Rtc2P5v3.js +1 -0
  24. package/client/dist/assets/agent-A0LpODvj2.js +1 -0
  25. package/client/dist/assets/agent-BCi1xJEH.js +1 -0
  26. package/client/dist/assets/agent-BmmZdeg7.js +1 -0
  27. package/client/dist/assets/agent-Bpm3uEw7.js +1 -0
  28. package/client/dist/assets/agent-BrmiC8zZ.js +1 -0
  29. package/client/dist/assets/agent-CBOOT08j2.js +1 -0
  30. package/client/dist/assets/agent-CZ7HdyTA.js +1 -0
  31. package/client/dist/assets/agent-DPGlEboi2.js +1 -0
  32. package/client/dist/assets/{upload-DPRq2dC-.js → brain-DDEGUEos.js} +1 -1
  33. package/client/dist/assets/{browser-DEEO-OSi.js → browser-BPkhILSJ.js} +1 -1
  34. package/client/dist/assets/{browser-BTivfZKE2.js → browser-BijVYG0Y2.js} +1 -1
  35. package/client/dist/assets/{browser-bpO3onlS.js → browser-BqLqJVVT.js} +1 -1
  36. package/client/dist/assets/{browser-DlSXtfu5.js → browser-Cc0iDqUi.js} +1 -1
  37. package/client/dist/assets/browser-CdS6O1Qb.js +1 -0
  38. package/client/dist/assets/{browser-BKP6hqQC2.js → browser-Cvg-QHvd2.js} +1 -1
  39. package/client/dist/assets/{browser-INCUyduh.js → browser-FRv8P02E.js} +1 -1
  40. package/client/dist/assets/{browser-DlKLfT612.js → browser-rWKj-RR_2.js} +1 -1
  41. package/client/dist/assets/code-BRcDlze52.js +1 -0
  42. package/client/dist/assets/code-BdMy3Ffq.js +1 -0
  43. package/client/dist/assets/code-CeQ0FZpC.js +1 -0
  44. package/client/dist/assets/code-CqCcRThR.js +1 -0
  45. package/client/dist/assets/code-DgeHz9CB.js +1 -0
  46. package/client/dist/assets/code-DzC1rMk12.js +1 -0
  47. package/client/dist/assets/code-UPVvmAKM2.js +1 -0
  48. package/client/dist/assets/code-thSEptMx.js +1 -0
  49. package/client/dist/assets/{common-QjVnq9XP2.js → common-BM3LFLCE2.js} +1 -1
  50. package/client/dist/assets/{common-CeQUwuHt2.js → common-Bwafujnc2.js} +1 -1
  51. package/client/dist/assets/{common-Bb64s3Bm.js → common-C-vU-j-I.js} +1 -1
  52. package/client/dist/assets/{common-KbQuTSGg.js → common-C5HKSbbz.js} +1 -1
  53. package/client/dist/assets/{common-BPQQkgJZ.js → common-CYaT2yHp.js} +1 -1
  54. package/client/dist/assets/{common-DPxotRK9.js → common-DhWTkocg.js} +1 -1
  55. package/client/dist/assets/{common-k5MTOHpn.js → common-DiPTT7V_2.js} +1 -1
  56. package/client/dist/assets/{common-C8ZD5upH2.js → common-DmqBPwZG.js} +1 -1
  57. package/client/dist/assets/{cssMode-DsArsSCT.js → cssMode-DBHbkBvI.js} +1 -1
  58. package/client/dist/assets/dashboard-4WX7agHF2.js +1 -0
  59. package/client/dist/assets/dashboard-5Z_esXIB.js +1 -0
  60. package/client/dist/assets/dashboard-DQ-po1MG2.js +1 -0
  61. package/client/dist/assets/dashboard-IbEztmJ52.js +1 -0
  62. package/client/dist/assets/dashboard-nc-Raovv.js +1 -0
  63. package/client/dist/assets/dashboard-ojWdDq6S.js +1 -0
  64. package/client/dist/assets/dashboard-oqS7VRrK.js +1 -0
  65. package/client/dist/assets/dashboard-zfoJcdFW.js +1 -0
  66. package/client/dist/assets/{dist-js-wMFtEMAw.js → dist-js-BP83ZCIg.js} +1 -1
  67. package/client/dist/assets/{dist-js-4mmVovCB.js → dist-js-Qk8DW7W3.js} +1 -1
  68. package/client/dist/assets/{editor.main-G3Sl9C67.js → editor.main-C9J2ikJK.js} +2 -2
  69. package/client/dist/assets/{freemarker2-pBzQNgFi.js → freemarker2-J5iIIIK-.js} +1 -1
  70. package/client/dist/assets/{handlebars-CtBTCnBI.js → handlebars-DSw1l_tw.js} +1 -1
  71. package/client/dist/assets/{html-Dx3DYBzY.js → html-h2-wE1Lj.js} +1 -1
  72. package/client/dist/assets/{htmlMode-In7frFOo.js → htmlMode-Cc_ij7lW.js} +1 -1
  73. package/client/dist/assets/index-BQbiBIg_.js +155 -0
  74. package/client/dist/assets/index-DPX6_xIC.css +2 -0
  75. package/client/dist/assets/{javascript-BKcn-YkN.js → javascript-C1q3xv6N.js} +1 -1
  76. package/client/dist/assets/jira-B3613-gj.js +1 -0
  77. package/client/dist/assets/jira-BHAKtc4B.js +1 -0
  78. package/client/dist/assets/jira-Be369RIR2.js +1 -0
  79. package/client/dist/assets/jira-CPpgA-5z2.js +1 -0
  80. package/client/dist/assets/jira-D5efgwp_.js +1 -0
  81. package/client/dist/assets/jira-DS7ownDy.js +1 -0
  82. package/client/dist/assets/jira-bDs7Im2C.js +1 -0
  83. package/client/dist/assets/jira-uNH1gETL2.js +1 -0
  84. package/client/dist/assets/jobs-1GV2-4zd2.js +1 -0
  85. package/client/dist/assets/jobs-26F9gGcE.js +1 -0
  86. package/client/dist/assets/jobs-BgQzB0Sx2.js +1 -0
  87. package/client/dist/assets/jobs-BqWui9_f.js +1 -0
  88. package/client/dist/assets/jobs-CE8qeIYj.js +1 -0
  89. package/client/dist/assets/jobs-D5sZzgLs.js +1 -0
  90. package/client/dist/assets/jobs-DzeuASRf.js +1 -0
  91. package/client/dist/assets/jobs-Wh7dn28q2.js +1 -0
  92. package/client/dist/assets/{jsonMode-jNREoQ3C.js → jsonMode-CeaCdEhr.js} +1 -1
  93. package/client/dist/assets/{lib-Cz65p1sn.js → lib-CtyGolSR.js} +1 -1
  94. package/client/dist/assets/{liquid-CtRkGqBu.js → liquid-eFsVK0V-.js} +1 -1
  95. package/client/dist/assets/loops-BvEenWBy.js +1 -0
  96. package/client/dist/assets/loops-CBiWd9Hf.js +1 -0
  97. package/client/dist/assets/loops-DNGiYKll2.js +1 -0
  98. package/client/dist/assets/{loops-Y3FQsUCh.js → loops-DjOtVXRo.js} +1 -1
  99. package/client/dist/assets/loops-HTHf-xu32.js +1 -0
  100. package/client/dist/assets/loops-YYV2bwjd.js +1 -0
  101. package/client/dist/assets/loops-hXgncEpF2.js +1 -0
  102. package/client/dist/assets/loops-kYbydDyN.js +1 -0
  103. package/client/dist/assets/{lspLanguageFeatures-Cl3gvD_W.js → lspLanguageFeatures-DT3-bbhn.js} +1 -1
  104. package/client/dist/assets/{mdx-B_nJldHz.js → mdx-Fuwnh1cX.js} +1 -1
  105. package/client/dist/assets/{monaco.contribution-PUeaZk8T.js → monaco.contribution-Desq7oq4.js} +2 -2
  106. package/client/dist/assets/{python-DS1Ce-A6.js → python-BgoEs6Cj.js} +1 -1
  107. package/client/dist/assets/{razor-L41Qg9OK.js → razor-CM1sPMMq.js} +1 -1
  108. package/client/dist/assets/setup-B590KsTX.js +1 -0
  109. package/client/dist/assets/setup-BkyGoby6.js +1 -0
  110. package/client/dist/assets/setup-CEj6uY3-2.js +1 -0
  111. package/client/dist/assets/setup-CbIerFGf2.js +1 -0
  112. package/client/dist/assets/setup-CmU6bTCV2.js +1 -0
  113. package/client/dist/assets/setup-D674kWQH.js +1 -0
  114. package/client/dist/assets/setup-VNqXyB6Y.js +1 -0
  115. package/client/dist/assets/setup-iY8vH8pB.js +1 -0
  116. package/client/dist/assets/specs-C9Sd7BhH2.js +1 -0
  117. package/client/dist/assets/specs-CBDvEYKv.js +1 -0
  118. package/client/dist/assets/specs-CIPr9reA2.js +1 -0
  119. package/client/dist/assets/specs-CWtKcVDC.js +1 -0
  120. package/client/dist/assets/specs-CmEZY57v.js +1 -0
  121. package/client/dist/assets/specs-D2clrt2c2.js +1 -0
  122. package/client/dist/assets/specs-DTplt2XM.js +1 -0
  123. package/client/dist/assets/specs-PozUNhqb.js +1 -0
  124. package/client/dist/assets/{tsMode-BC1g186U.js → tsMode-BmT8WogI.js} +1 -1
  125. package/client/dist/assets/{typescript-BGlRGvJW.js → typescript-CQrQPsoW.js} +1 -1
  126. package/client/dist/assets/upload-BOOCdPin.js +1 -0
  127. package/client/dist/assets/{value-DJMRojPA.js → value-BHbZ4o6V.js} +1 -1
  128. package/client/dist/assets/{workers-CXcXtO3b.js → workers-U0UXyLUf.js} +1 -1
  129. package/client/dist/assets/{xml-JdZZaIhJ.js → xml-WRxJs8_I.js} +1 -1
  130. package/client/dist/assets/{yaml-Cm82BVBt.js → yaml-CjpSTjJU.js} +1 -1
  131. package/client/dist/index.html +13 -13
  132. package/docs/customizing.md +2 -2
  133. package/docs/gemini.md +15 -4
  134. package/docs/guide/de/insights/3-code-explorer.md +6 -0
  135. package/docs/guide/de/integrations/3-jira-integration.md +1 -1
  136. package/docs/guide/de/integrations/6-agent-chat.md +5 -0
  137. package/docs/guide/de/pipeline/1-rails-and-jobs.md +6 -6
  138. package/docs/guide/de/pipeline/2-the-job-detail-view.md +27 -2
  139. package/docs/guide/de/pipeline/3-batch-implement-and-multi-feature.md +5 -4
  140. package/docs/guide/de/pipeline/5-the-loop-builder.md +1 -1
  141. package/docs/guide/de/specs/1-specs-and-the-backlog.md +3 -2
  142. package/docs/guide/en/insights/3-code-explorer.md +6 -0
  143. package/docs/guide/en/integrations/3-jira-integration.md +1 -1
  144. package/docs/guide/en/integrations/6-agent-chat.md +5 -0
  145. package/docs/guide/en/pipeline/1-rails-and-jobs.md +6 -6
  146. package/docs/guide/en/pipeline/2-the-job-detail-view.md +27 -2
  147. package/docs/guide/en/pipeline/3-batch-implement-and-multi-feature.md +5 -4
  148. package/docs/guide/en/pipeline/5-the-loop-builder.md +1 -1
  149. package/docs/guide/en/specs/1-specs-and-the-backlog.md +3 -2
  150. package/docs/guide/es/insights/3-code-explorer.md +6 -0
  151. package/docs/guide/es/integrations/3-jira-integration.md +1 -1
  152. package/docs/guide/es/integrations/6-agent-chat.md +5 -0
  153. package/docs/guide/es/pipeline/1-rails-and-jobs.md +6 -6
  154. package/docs/guide/es/pipeline/2-the-job-detail-view.md +27 -2
  155. package/docs/guide/es/pipeline/3-batch-implement-and-multi-feature.md +5 -4
  156. package/docs/guide/es/pipeline/5-the-loop-builder.md +1 -1
  157. package/docs/guide/es/specs/1-specs-and-the-backlog.md +3 -2
  158. package/docs/guide/fr/insights/3-code-explorer.md +6 -0
  159. package/docs/guide/fr/integrations/3-jira-integration.md +1 -1
  160. package/docs/guide/fr/integrations/6-agent-chat.md +5 -0
  161. package/docs/guide/fr/pipeline/1-rails-and-jobs.md +6 -6
  162. package/docs/guide/fr/pipeline/2-the-job-detail-view.md +27 -2
  163. package/docs/guide/fr/pipeline/3-batch-implement-and-multi-feature.md +5 -4
  164. package/docs/guide/fr/pipeline/5-the-loop-builder.md +1 -1
  165. package/docs/guide/fr/specs/1-specs-and-the-backlog.md +3 -2
  166. package/docs/guide/it/insights/3-code-explorer.md +6 -0
  167. package/docs/guide/it/integrations/3-jira-integration.md +1 -1
  168. package/docs/guide/it/integrations/6-agent-chat.md +5 -0
  169. package/docs/guide/it/pipeline/1-rails-and-jobs.md +6 -6
  170. package/docs/guide/it/pipeline/2-the-job-detail-view.md +27 -2
  171. package/docs/guide/it/pipeline/3-batch-implement-and-multi-feature.md +5 -4
  172. package/docs/guide/it/pipeline/5-the-loop-builder.md +1 -1
  173. package/docs/guide/it/specs/1-specs-and-the-backlog.md +3 -2
  174. package/docs/guide/ja/insights/3-code-explorer.md +6 -0
  175. package/docs/guide/ja/integrations/3-jira-integration.md +1 -1
  176. package/docs/guide/ja/integrations/6-agent-chat.md +5 -0
  177. package/docs/guide/ja/pipeline/1-rails-and-jobs.md +6 -6
  178. package/docs/guide/ja/pipeline/2-the-job-detail-view.md +27 -2
  179. package/docs/guide/ja/pipeline/3-batch-implement-and-multi-feature.md +5 -4
  180. package/docs/guide/ja/pipeline/5-the-loop-builder.md +1 -1
  181. package/docs/guide/ja/specs/1-specs-and-the-backlog.md +3 -2
  182. package/docs/guide/pt/insights/3-code-explorer.md +6 -0
  183. package/docs/guide/pt/integrations/3-jira-integration.md +1 -1
  184. package/docs/guide/pt/integrations/6-agent-chat.md +5 -0
  185. package/docs/guide/pt/pipeline/1-rails-and-jobs.md +6 -6
  186. package/docs/guide/pt/pipeline/2-the-job-detail-view.md +27 -2
  187. package/docs/guide/pt/pipeline/3-batch-implement-and-multi-feature.md +5 -4
  188. package/docs/guide/pt/pipeline/5-the-loop-builder.md +1 -1
  189. package/docs/guide/pt/specs/1-specs-and-the-backlog.md +3 -2
  190. package/docs/guide/zh/insights/3-code-explorer.md +6 -0
  191. package/docs/guide/zh/integrations/3-jira-integration.md +1 -1
  192. package/docs/guide/zh/integrations/6-agent-chat.md +5 -0
  193. package/docs/guide/zh/pipeline/1-rails-and-jobs.md +6 -6
  194. package/docs/guide/zh/pipeline/2-the-job-detail-view.md +27 -2
  195. package/docs/guide/zh/pipeline/3-batch-implement-and-multi-feature.md +5 -4
  196. package/docs/guide/zh/pipeline/5-the-loop-builder.md +1 -1
  197. package/docs/guide/zh/specs/1-specs-and-the-backlog.md +3 -2
  198. package/docs/internals/README.md +5 -0
  199. package/docs/internals/adding-a-provider.md +15 -3
  200. package/docs/internals/api-reference.md +6 -5
  201. package/docs/internals/browser-capture-performance.md +93 -0
  202. package/docs/internals/code-explorer-story.md +135 -0
  203. package/docs/internals/gemini-mcp-registration.md +53 -0
  204. package/docs/internals/interactive-jobs.md +212 -0
  205. package/docs/internals/loop-step-log-explorer.md +146 -0
  206. package/docs/internals/safe-pr-review-flow.md +382 -0
  207. package/docs/mcp.md +1 -1
  208. package/docs/running-pipelines.md +5 -3
  209. package/package.json +1 -1
  210. package/server/dist/agent-chat-manager.js +211 -0
  211. package/server/dist/agent-chat-registry.js +20 -0
  212. package/server/dist/agent-chat-router.js +22 -0
  213. package/server/dist/agent-mcp-config.js +45 -4
  214. package/server/dist/agent-operator-prompt.js +158 -56
  215. package/server/dist/agent-store.js +25 -0
  216. package/server/dist/agent-tier.js +6 -1
  217. package/server/dist/browser-capture-manager.js +184 -34
  218. package/server/dist/browser-playwright.js +98 -13
  219. package/server/dist/code-explorer-router.js +92 -0
  220. package/server/dist/db.js +92 -0
  221. package/server/dist/file-provenance.js +54 -1
  222. package/server/dist/file-story-manager.js +170 -0
  223. package/server/dist/file-story.js +148 -0
  224. package/server/dist/file-summary-generator.js +5 -4
  225. package/server/dist/index.js +5 -0
  226. package/server/dist/interactive-job-session.js +226 -18
  227. package/server/dist/jira/jira-adf.js +9 -0
  228. package/server/dist/jira/jira-materializer.js +27 -4
  229. package/server/dist/jira/jira-status-resolver.js +12 -4
  230. package/server/dist/jira/jira-sync-manager.js +130 -2
  231. package/server/dist/jira-router.js +1 -1
  232. package/server/dist/loop-executors.js +91 -28
  233. package/server/dist/loop-run-manager.js +354 -28
  234. package/server/dist/mcp/guide.js +18 -7
  235. package/server/dist/mcp/tools/jira.js +1 -1
  236. package/server/dist/mcp/tools/jobs.js +14 -5
  237. package/server/dist/mcp/tools/rails.js +137 -12
  238. package/server/dist/mcp/tools/specs.js +35 -9
  239. package/server/dist/mcp/tools/types.js +49 -0
  240. package/server/dist/mobile/mobile-ws.js +4 -0
  241. package/server/dist/path-resolver.js +46 -0
  242. package/server/dist/pr-body.js +240 -0
  243. package/server/dist/pr-naming.js +210 -0
  244. package/server/dist/project-registry.js +77 -17
  245. package/server/dist/project-router-jobs.js +53 -13
  246. package/server/dist/project-router-terminals.js +16 -0
  247. package/server/dist/project-router-tickets.js +57 -3
  248. package/server/dist/project-router.js +52 -13
  249. package/server/dist/queue-manager.js +261 -84
  250. package/server/dist/rail-isolated-launch.js +315 -66
  251. package/server/dist/rail-isolation.js +18 -5
  252. package/server/dist/rail-pr-decision.js +629 -0
  253. package/server/dist/rail-pr-delivery.js +21 -18
  254. package/server/dist/rail-pr-store.js +175 -0
  255. package/server/dist/rail-worktrees-store.js +18 -0
  256. package/server/dist/rails-router.js +234 -38
  257. package/server/dist/rails-store.js +78 -1
  258. package/server/dist/setup-prerequisites.js +105 -0
  259. package/server/dist/smash-runner.js +3 -1
  260. package/server/dist/ticket-store.js +7 -3
  261. package/server/dist/workspace-resolution.js +27 -0
  262. package/server/dist/worktree-manager.js +42 -7
  263. package/server/dist/worktree-overlay.js +261 -0
  264. package/client/dist/assets/AgentBrowserCapture-DkA8FLp8.js +0 -1
  265. package/client/dist/assets/AgentModeJobsPane-TLYCqNAw.js +0 -1
  266. package/client/dist/assets/AgentsPage-BKsPH-l1.js +0 -86
  267. package/client/dist/assets/AnalyticsPage-Da9pDQrq.js +0 -1
  268. package/client/dist/assets/CodePage-DlwvWKCo.js +0 -2
  269. package/client/dist/assets/DesktopAnalyticsPage-DpVVhXKF.js +0 -1
  270. package/client/dist/assets/DocsDialog-BSdgftgR.js +0 -11
  271. package/client/dist/assets/DocsPage-9SGL4_zz.js +0 -11
  272. package/client/dist/assets/IntegrationsPage-BW5mofSA.js +0 -3
  273. package/client/dist/assets/JobDetailPage-CqiJ9vwR.js +0 -1
  274. package/client/dist/assets/JobsPage-CVinOe6p.js +0 -1
  275. package/client/dist/assets/LogViewer-Cf6s1TDs.js +0 -16
  276. package/client/dist/assets/LoopBuilderPage-CqgUH5Vw.js +0 -7
  277. package/client/dist/assets/LoopsPage-C6h2gjPP.js +0 -1
  278. package/client/dist/assets/ProjectSettingsDialog-BU-JR7wI.js +0 -1
  279. package/client/dist/assets/agent-B7GdHP3Z.js +0 -1
  280. package/client/dist/assets/agent-BHmcgoJf.js +0 -1
  281. package/client/dist/assets/agent-BdY_fii4.js +0 -1
  282. package/client/dist/assets/agent-C32FOi9v.js +0 -1
  283. package/client/dist/assets/agent-CiFQxoaZ2.js +0 -1
  284. package/client/dist/assets/agent-CtAag7V6.js +0 -1
  285. package/client/dist/assets/agent-DE4Mp1fY2.js +0 -1
  286. package/client/dist/assets/agent-DK8qovyG2.js +0 -1
  287. package/client/dist/assets/browser-ZB1afzjZ.js +0 -1
  288. package/client/dist/assets/code-BFxE1Yt62.js +0 -1
  289. package/client/dist/assets/code-BefYOm5Q.js +0 -1
  290. package/client/dist/assets/code-BkXpJt99.js +0 -1
  291. package/client/dist/assets/code-C6Sq7_t8.js +0 -1
  292. package/client/dist/assets/code-CGj3w-2N.js +0 -1
  293. package/client/dist/assets/code-Dfsxc9o82.js +0 -1
  294. package/client/dist/assets/code-Y5urks5s2.js +0 -1
  295. package/client/dist/assets/code-wtcs0ivb.js +0 -1
  296. package/client/dist/assets/dashboard-B-AiVq5X.js +0 -1
  297. package/client/dist/assets/dashboard-BpYYrPl8.js +0 -1
  298. package/client/dist/assets/dashboard-Bunv-uon2.js +0 -1
  299. package/client/dist/assets/dashboard-CYciEbov.js +0 -1
  300. package/client/dist/assets/dashboard-CvFg-_JQ.js +0 -1
  301. package/client/dist/assets/dashboard-DAyPERCJ.js +0 -1
  302. package/client/dist/assets/dashboard-DJ-6T44N2.js +0 -1
  303. package/client/dist/assets/dashboard-DnBGqZkZ2.js +0 -1
  304. package/client/dist/assets/index-BHPbzyg6.css +0 -2
  305. package/client/dist/assets/index-D4R3rVF5.js +0 -152
  306. package/client/dist/assets/jira-BcZzX9122.js +0 -1
  307. package/client/dist/assets/jira-CTYs7LA12.js +0 -1
  308. package/client/dist/assets/jira-D2nN39e92.js +0 -1
  309. package/client/dist/assets/jira-DJxmIkyr.js +0 -1
  310. package/client/dist/assets/jira-DXMoAKWD.js +0 -1
  311. package/client/dist/assets/jira-IhC1ROIc.js +0 -1
  312. package/client/dist/assets/jira-Iw575fN8.js +0 -1
  313. package/client/dist/assets/jira-kbWZY7jH.js +0 -1
  314. package/client/dist/assets/jobs-BqF79kHz2.js +0 -1
  315. package/client/dist/assets/jobs-C1XM5urS.js +0 -1
  316. package/client/dist/assets/jobs-C5UjG0262.js +0 -1
  317. package/client/dist/assets/jobs-DBfaHTxC.js +0 -1
  318. package/client/dist/assets/jobs-DM4BDPdg.js +0 -1
  319. package/client/dist/assets/jobs-Da5OkZmf2.js +0 -1
  320. package/client/dist/assets/jobs-JJdnuQ03.js +0 -1
  321. package/client/dist/assets/jobs-SI34ML8I.js +0 -1
  322. package/client/dist/assets/loops-BR4FmOv12.js +0 -1
  323. package/client/dist/assets/loops-BgX_uudn.js +0 -1
  324. package/client/dist/assets/loops-Bpl2j2LP.js +0 -1
  325. package/client/dist/assets/loops-CQuuMlyZ.js +0 -1
  326. package/client/dist/assets/loops-DW8hSMdS2.js +0 -1
  327. package/client/dist/assets/loops-Q2muu8hW2.js +0 -1
  328. package/client/dist/assets/loops-q7CNDvfK.js +0 -1
  329. package/client/dist/assets/setup-CNMdCHHt2.js +0 -1
  330. package/client/dist/assets/setup-Cag4XrbL2.js +0 -1
  331. package/client/dist/assets/setup-D9IHGoWU.js +0 -1
  332. package/client/dist/assets/setup-Dg6Ba3JT.js +0 -1
  333. package/client/dist/assets/setup-DyK36RIW.js +0 -1
  334. package/client/dist/assets/setup-G4ZvDKxX.js +0 -1
  335. package/client/dist/assets/setup-aTlGxuwi2.js +0 -1
  336. package/client/dist/assets/setup-kWsoAeHQ.js +0 -1
  337. package/client/dist/assets/specs-BFSUPa122.js +0 -1
  338. package/client/dist/assets/specs-BMzip1WY2.js +0 -1
  339. package/client/dist/assets/specs-BYeAbIEy.js +0 -1
  340. package/client/dist/assets/specs-C-mtLcXw.js +0 -1
  341. package/client/dist/assets/specs-CAzpvADd2.js +0 -1
  342. package/client/dist/assets/specs-CyRIw_IR.js +0 -1
  343. package/client/dist/assets/specs-DMm7gB_l.js +0 -1
  344. package/client/dist/assets/specs-DuottM0Z.js +0 -1
  345. /package/client/dist/assets/{abap-CpHUwCVK.js → abap-D0E4FfVW.js} +0 -0
  346. /package/client/dist/assets/{activity-DemHQS7l.js → activity--iN4Ad2R2.js} +0 -0
  347. /package/client/dist/assets/{activity-B_71BWg3.js → activity-6hM_ZSg9.js} +0 -0
  348. /package/client/dist/assets/{activity-DHv2V5Oi.js → activity-BZNfOdiS.js} +0 -0
  349. /package/client/dist/assets/{activity-D0rfjQzT2.js → activity-BuVo5sPB.js} +0 -0
  350. /package/client/dist/assets/{activity-BpTTj_PH.js → activity-CIOLxGvh.js} +0 -0
  351. /package/client/dist/assets/{activity-D2e62vbV2.js → activity-D2r2h3SE2.js} +0 -0
  352. /package/client/dist/assets/{activity-Ch-wbr0C2.js → activity-DtxrAUMo2.js} +0 -0
  353. /package/client/dist/assets/{addon-image-Ba-TY3wr.js → addon-image-CwoZj17F.js} +0 -0
  354. /package/client/dist/assets/{addon-ligatures-T4ARLiuu.js → addon-ligatures-CWDrED80.js} +0 -0
  355. /package/client/dist/assets/{addon-webgl-Cd73n8eh.js → addon-webgl-DMbGeI_u.js} +0 -0
  356. /package/client/dist/assets/{addspec-xwRX_Pnf.js → addspec-BMtLZLW62.js} +0 -0
  357. /package/client/dist/assets/{addspec-l_zU5gla.js → addspec-CP0HRuxY.js} +0 -0
  358. /package/client/dist/assets/{addspec-Dio-H5z0.js → addspec-CRuvWn8d.js} +0 -0
  359. /package/client/dist/assets/{addspec-D6L4ZteP.js → addspec-D-JLDsUV.js} +0 -0
  360. /package/client/dist/assets/{addspec-CrEm6Fzr2.js → addspec-DfhDbg5c.js} +0 -0
  361. /package/client/dist/assets/{addspec-B6Ns8KU02.js → addspec-bsNDdqRm2.js} +0 -0
  362. /package/client/dist/assets/{addspec-qGyH7MHy2.js → addspec-mgPOt5q02.js} +0 -0
  363. /package/client/dist/assets/{agents-OzxCLVW1.js → agents-78bTZGZh.js} +0 -0
  364. /package/client/dist/assets/{agents-hv3sqmPm2.js → agents-BLhWCmDS2.js} +0 -0
  365. /package/client/dist/assets/{agents-CHgCudUV.js → agents-BUdEi3-N.js} +0 -0
  366. /package/client/dist/assets/{agents-Dumx4JiM2.js → agents-BpoUaoW92.js} +0 -0
  367. /package/client/dist/assets/{agents-CnaPeSyw.js → agents-CWo-KyAB.js} +0 -0
  368. /package/client/dist/assets/{agents-Xh-zYHUx2.js → agents-DDtCJ5M02.js} +0 -0
  369. /package/client/dist/assets/{agents-DuhLEaQ_.js → agents-bvyRLczL.js} +0 -0
  370. /package/client/dist/assets/{agentstudio-CCthUdzR.js → agentstudio-BMQxc_bz.js} +0 -0
  371. /package/client/dist/assets/{agentstudio-CcH8Ckql2.js → agentstudio-COZriimI2.js} +0 -0
  372. /package/client/dist/assets/{agentstudio-Bo91kfUd2.js → agentstudio-CWgXG5W52.js} +0 -0
  373. /package/client/dist/assets/{agentstudio-VJOa_NVO.js → agentstudio-C_Jq8Tl4.js} +0 -0
  374. /package/client/dist/assets/{agentstudio-BIxikDf_.js → agentstudio-Dtq3dGYk.js} +0 -0
  375. /package/client/dist/assets/{agentstudio-Bz8cP8_c.js → agentstudio-jKMTdT70.js} +0 -0
  376. /package/client/dist/assets/{agentstudio-DARgYg5Z2.js → agentstudio-sI27TpBu2.js} +0 -0
  377. /package/client/dist/assets/{aiedit-5ZXN4cep2.js → aiedit-6CHdb_iv2.js} +0 -0
  378. /package/client/dist/assets/{aiedit-B7gAJZVC.js → aiedit-B03pD_Na.js} +0 -0
  379. /package/client/dist/assets/{aiedit-D92V-kUW.js → aiedit-BtRqRxML.js} +0 -0
  380. /package/client/dist/assets/{aiedit-D9ualLVJ.js → aiedit-eMN4eQPF.js} +0 -0
  381. /package/client/dist/assets/{aiedit-h48tJU0V2.js → aiedit-hknZlly82.js} +0 -0
  382. /package/client/dist/assets/{aiedit-xkA_mR2a2.js → aiedit-igmw-ZoZ2.js} +0 -0
  383. /package/client/dist/assets/{aiedit-7B2dvCv-.js → aiedit-pc5JDUq1.js} +0 -0
  384. /package/client/dist/assets/{analytics-slx4X1mu2.js → analytics-BWMUZ2Pq2.js} +0 -0
  385. /package/client/dist/assets/{analytics-uRNP6yAJ.js → analytics-Bj-SmKHa.js} +0 -0
  386. /package/client/dist/assets/{analytics-WF1I49ln.js → analytics-C5dpiS0o.js} +0 -0
  387. /package/client/dist/assets/{analytics-CBvaxOId.js → analytics-CCprAqk3.js} +0 -0
  388. /package/client/dist/assets/{analytics-BakymH7Z2.js → analytics-CR1TJqUi2.js} +0 -0
  389. /package/client/dist/assets/{analytics-B7bPj6u_2.js → analytics-DfNdXR0y2.js} +0 -0
  390. /package/client/dist/assets/{analytics-DZ74aQ54.js → analytics-rmHuJv0V.js} +0 -0
  391. /package/client/dist/assets/{apex-DlD7oJX6.js → apex-D_X_8J4d.js} +0 -0
  392. /package/client/dist/assets/{atom-one-dark-BrRN8wBy.js → atom-one-dark-BMDPFwRZ.js} +0 -0
  393. /package/client/dist/assets/{attachments-C11tOKZ_.js → attachments-BgBNSqQd.js} +0 -0
  394. /package/client/dist/assets/{attachments-Bnbyj2PN.js → attachments-BjyMmrwE.js} +0 -0
  395. /package/client/dist/assets/{attachments-CIeLa8l12.js → attachments-C9GTTJsx2.js} +0 -0
  396. /package/client/dist/assets/{attachments-DslHfa-L.js → attachments-DCZOL1RU.js} +0 -0
  397. /package/client/dist/assets/{attachments-C-gyrCOb.js → attachments-DL-bPy9E.js} +0 -0
  398. /package/client/dist/assets/{attachments-Cxrs0pyL2.js → attachments-DPCmkFZu2.js} +0 -0
  399. /package/client/dist/assets/{attachments-TTPsc0a52.js → attachments-rNn1ekRy2.js} +0 -0
  400. /package/client/dist/assets/{azcli-CmXFAbc-.js → azcli-PZLnZ3jH.js} +0 -0
  401. /package/client/dist/assets/{bat-DdNJq4hH.js → bat-KlBOxpO4.js} +0 -0
  402. /package/client/dist/assets/{bicep-Bppz7WOA.js → bicep-CgG9oF3V.js} +0 -0
  403. /package/client/dist/assets/{cameligo-0MRMdSmg.js → cameligo-6R45j6Ph.js} +0 -0
  404. /package/client/dist/assets/{chat-BvHrebKC2.js → chat-BgL3zv6x2.js} +0 -0
  405. /package/client/dist/assets/{chat-CZyiLJvQ.js → chat-Bh3NdgJs.js} +0 -0
  406. /package/client/dist/assets/{chat-DKYP7NnC.js → chat-Bom6bqK3.js} +0 -0
  407. /package/client/dist/assets/{chat-5mdg_YIc2.js → chat-DdwZjT8K2.js} +0 -0
  408. /package/client/dist/assets/{chat-wkTIy9rX.js → chat-Dnwg-NpQ.js} +0 -0
  409. /package/client/dist/assets/{chat-BpYxnkr4.js → chat-DsbwJhus.js} +0 -0
  410. /package/client/dist/assets/{chat-BGax2nV62.js → chat-vylxqR0P2.js} +0 -0
  411. /package/client/dist/assets/{clojure-B5dKj863.js → clojure-CLAAMO7J.js} +0 -0
  412. /package/client/dist/assets/{clsx-1dnHRn8W.js → clsx-CNmW0Nip.js} +0 -0
  413. /package/client/dist/assets/{coffee-DSbWjzk7.js → coffee-AruSygo-.js} +0 -0
  414. /package/client/dist/assets/{commands-uz_uKT242.js → commands-C4Y3C-PF2.js} +0 -0
  415. /package/client/dist/assets/{commands-Bb7MnPqn2.js → commands-CSDs9q_2.js} +0 -0
  416. /package/client/dist/assets/{commands-C_7zZwJf.js → commands-DkU0qliq.js} +0 -0
  417. /package/client/dist/assets/{commands-D_6B8lfU.js → commands-JWMfGDmr.js} +0 -0
  418. /package/client/dist/assets/{commands-DBc5llLi2.js → commands-RHOchN4n2.js} +0 -0
  419. /package/client/dist/assets/{commands-CQkdthjF.js → commands-u-4eEHCN.js} +0 -0
  420. /package/client/dist/assets/{commands-DhZNhSbl.js → commands-xHDDGfcP2.js} +0 -0
  421. /package/client/dist/assets/{cpp-SBF8SAh9.js → cpp-DEE5r4Pw.js} +0 -0
  422. /package/client/dist/assets/{csharp-Lzuq_1t-.js → csharp-BVXJUvbK.js} +0 -0
  423. /package/client/dist/assets/{csp-BEzxZqi1.js → csp-cXOF0JoV.js} +0 -0
  424. /package/client/dist/assets/{css-C3D3PKln.js → css-C_zQuAoy.js} +0 -0
  425. /package/client/dist/assets/{cypher-CQ3dEPmv.js → cypher-t95m_Q-O.js} +0 -0
  426. /package/client/dist/assets/{dart-DCPmxolI.js → dart-B4r1Tg-e.js} +0 -0
  427. /package/client/dist/assets/{dockerfile-B_2_aaTO.js → dockerfile-6mt7zHQw.js} +0 -0
  428. /package/client/dist/assets/{ecl-rADUeXsV.js → ecl-DEY_Fz_Q.js} +0 -0
  429. /package/client/dist/assets/{editor.api2-T7u8kQWG.js → editor.api2-C3B0tp2x.js} +0 -0
  430. /package/client/dist/assets/{elixir-DOd-TuJO.js → elixir-R6-q1c5t.js} +0 -0
  431. /package/client/dist/assets/{explore-BHEhNekP2.js → explore-B7fblXBb2.js} +0 -0
  432. /package/client/dist/assets/{explore-DAsroA482.js → explore-BHtEpoNN2.js} +0 -0
  433. /package/client/dist/assets/{explore-UwHHj2ux.js → explore-C0k8HrkN.js} +0 -0
  434. /package/client/dist/assets/{explore-DaXiW9-6.js → explore-CNBzrEPS.js} +0 -0
  435. /package/client/dist/assets/{explore-CWlAXx0f2.js → explore-D_mWBYCS2.js} +0 -0
  436. /package/client/dist/assets/{explore-DG1CtYqT.js → explore-Dahc1lOx.js} +0 -0
  437. /package/client/dist/assets/{explore-DMSGAnhK.js → explore-UvW1jEMa.js} +0 -0
  438. /package/client/dist/assets/{flow9-Bf7zg_j0.js → flow9-CNQvHBOt.js} +0 -0
  439. /package/client/dist/assets/{format-command-BHymDa4r.js → format-command-CuWuRvka.js} +0 -0
  440. /package/client/dist/assets/{fsharp-BqROZjbA.js → fsharp-vPZkFXwv.js} +0 -0
  441. /package/client/dist/assets/{go-oQTP5uLe.js → go-KUzBMYJ_.js} +0 -0
  442. /package/client/dist/assets/{graphql-CSHfTU3q.js → graphql-C3W0rCsD.js} +0 -0
  443. /package/client/dist/assets/{hcl-CeG-RoFJ.js → hcl-BOOMFSNX.js} +0 -0
  444. /package/client/dist/assets/{ini-B2Dv4ohc.js → ini-CFat1WJr.js} +0 -0
  445. /package/client/dist/assets/{integrations-CAF21FbQ.js → integrations-4KZnYECp.js} +0 -0
  446. /package/client/dist/assets/{integrations-CHCgning2.js → integrations-7W266oqF2.js} +0 -0
  447. /package/client/dist/assets/{integrations-B-JVE1_D.js → integrations-BNuauK3o.js} +0 -0
  448. /package/client/dist/assets/{integrations-BAujIDoE.js → integrations-CHy8tnpV.js} +0 -0
  449. /package/client/dist/assets/{integrations-DS5FFMes.js → integrations-Cl_wD5AI.js} +0 -0
  450. /package/client/dist/assets/{integrations-axZN4--n2.js → integrations-Cy8nZ_dv2.js} +0 -0
  451. /package/client/dist/assets/{integrations-CtsOpq2D2.js → integrations-zMqY4VU12.js} +0 -0
  452. /package/client/dist/assets/{java-aUDDeufb.js → java-Dee-CNAM.js} +0 -0
  453. /package/client/dist/assets/{julia-C5LbruO5.js → julia-CGNlLYuU.js} +0 -0
  454. /package/client/dist/assets/{kotlin-C6mOuSKk.js → kotlin-CY7lhknJ.js} +0 -0
  455. /package/client/dist/assets/{less-D5qC3caW.js → less-D0KN7hfJ.js} +0 -0
  456. /package/client/dist/assets/{lexon-Dr2La-fj.js → lexon-CuRJufPs.js} +0 -0
  457. /package/client/dist/assets/{lua-Zy6u5z6Z.js → lua-DHvH62Zf.js} +0 -0
  458. /package/client/dist/assets/{m3-C7XHeDz_.js → m3-tlthQ8Fo.js} +0 -0
  459. /package/client/dist/assets/{markdown-PiF7r-2h.js → markdown-Dbx1LgUZ.js} +0 -0
  460. /package/client/dist/assets/{mcp-B_nWlxZa2.js → mcp-CjVKXAhD2.js} +0 -0
  461. /package/client/dist/assets/{mcp-B8omp_Cd.js → mcp-Dcl-XxkR.js} +0 -0
  462. /package/client/dist/assets/{mcp-DTCCrYHz2.js → mcp-DtbxuH3V2.js} +0 -0
  463. /package/client/dist/assets/{mcp-DytBbASZ.js → mcp-H-gnQUdN.js} +0 -0
  464. /package/client/dist/assets/{mcp-D_oPS6Zc.js → mcp-N1nzp8oL.js} +0 -0
  465. /package/client/dist/assets/{mcp-Cb2jtHP72.js → mcp-XJNRfxVp2.js} +0 -0
  466. /package/client/dist/assets/{mcp-DPqm2C8-.js → mcp-sRmWE8WJ.js} +0 -0
  467. /package/client/dist/assets/{mips-nn07GiyE.js → mips-D_O3IUz_.js} +0 -0
  468. /package/client/dist/assets/{msdax-DaKFVMST.js → msdax-C_ZmCnRt.js} +0 -0
  469. /package/client/dist/assets/{mysql-C6d6xrbU.js → mysql-C-dCEYSX.js} +0 -0
  470. /package/client/dist/assets/{nav-Cibp2KWF.js → nav-40HzpIFb.js} +0 -0
  471. /package/client/dist/assets/{nav-DtTnF9xd.js → nav-8yPhBn00.js} +0 -0
  472. /package/client/dist/assets/{nav-Danf5sRf2.js → nav-B6PkGfTk2.js} +0 -0
  473. /package/client/dist/assets/{nav-Bqhyfbcj2.js → nav-BHqMLrS72.js} +0 -0
  474. /package/client/dist/assets/{nav-CQb9y1km.js → nav-CGy4yx3C.js} +0 -0
  475. /package/client/dist/assets/{nav-BAsYcqdw2.js → nav-CXEDcRdv2.js} +0 -0
  476. /package/client/dist/assets/{nav-BRrNlZkr.js → nav-EI_OhEAo.js} +0 -0
  477. /package/client/dist/assets/{objective-c-B6KMtI-k.js → objective-c-DZY9Aqxd.js} +0 -0
  478. /package/client/dist/assets/{pascal-DYr8MPE7.js → pascal-BVHLXoor.js} +0 -0
  479. /package/client/dist/assets/{pascaligo-B3pd-jJ_.js → pascaligo-XdG_6u3k.js} +0 -0
  480. /package/client/dist/assets/{perl-z2xUzoaL.js → perl-b9QV0BcD.js} +0 -0
  481. /package/client/dist/assets/{pgsql-DUvT-09-.js → pgsql-Du5FDOgT.js} +0 -0
  482. /package/client/dist/assets/{php-CGyOmJfy.js → php-WJD0z2Z_.js} +0 -0
  483. /package/client/dist/assets/{pla-CMqgvyD0.js → pla-CbciTf2w.js} +0 -0
  484. /package/client/dist/assets/{postiats-Dx5LUn4Z.js → postiats-C1QxmvVq.js} +0 -0
  485. /package/client/dist/assets/{powerquery-DazYxvJ6.js → powerquery-BEYDhPLZ.js} +0 -0
  486. /package/client/dist/assets/{powershell-B3nwlDka.js → powershell-CfaYw4XL.js} +0 -0
  487. /package/client/dist/assets/{protobuf-BGuu2u2s.js → protobuf-pwZEDOYa.js} +0 -0
  488. /package/client/dist/assets/{pug-Dbte1MXA.js → pug-5ftqSPVe.js} +0 -0
  489. /package/client/dist/assets/{qsharp-DJLwBOvG.js → qsharp-uI6qZMq4.js} +0 -0
  490. /package/client/dist/assets/{r-DmGBRSHj.js → r-BK54P1EG.js} +0 -0
  491. /package/client/dist/assets/{redis-VvUYn0a4.js → redis-DI0yd7kN.js} +0 -0
  492. /package/client/dist/assets/{redshift-6GdDrxg3.js → redshift-Dov26eyI.js} +0 -0
  493. /package/client/dist/assets/{restructuredtext-CfAB8aRU.js → restructuredtext-QqJ_1dC-.js} +0 -0
  494. /package/client/dist/assets/{ruby-CIYK6MXY.js → ruby-5WjveeVb.js} +0 -0
  495. /package/client/dist/assets/{rust-CTHZfjj9.js → rust-BzVSfqFH.js} +0 -0
  496. /package/client/dist/assets/{sb-CkKTdkz_.js → sb-DMIUfT-3.js} +0 -0
  497. /package/client/dist/assets/{scala-Bx-Wr9TM.js → scala-CSKA7lqt.js} +0 -0
  498. /package/client/dist/assets/{scheme-Dcfi6f83.js → scheme-CojOP2Qc.js} +0 -0
  499. /package/client/dist/assets/{scss-ByL-7PFQ.js → scss-DoBZGJG6.js} +0 -0
  500. /package/client/dist/assets/{settings-D3rfdI1i.js → settings-BOHOmHkb.js} +0 -0
  501. /package/client/dist/assets/{settings-DoUJb93K2.js → settings-BlEA_7h02.js} +0 -0
  502. /package/client/dist/assets/{settings-CgjmTpR8.js → settings-BsJMsWGc.js} +0 -0
  503. /package/client/dist/assets/{settings-BbxrZlv7.js → settings-D6qY9_UI.js} +0 -0
  504. /package/client/dist/assets/{settings-BmA06FIJ.js → settings-DZJeXoRV.js} +0 -0
  505. /package/client/dist/assets/{settings-C2_QJA8f2.js → settings-TNga5gIF2.js} +0 -0
  506. /package/client/dist/assets/{settings-BJ6fj67y2.js → settings-lFoaYT-s2.js} +0 -0
  507. /package/client/dist/assets/{shell-Csnb9Yqd.js → shell-YOaE4udl.js} +0 -0
  508. /package/client/dist/assets/{solidity-Dbw5-0QP.js → solidity-l3jSyVLu.js} +0 -0
  509. /package/client/dist/assets/{sophia-ZQ3saZQx.js → sophia-BhSGTaQJ.js} +0 -0
  510. /package/client/dist/assets/{sparql-BEtOel8u.js → sparql-qhk6QD9w.js} +0 -0
  511. /package/client/dist/assets/{sql-DGPDbzB7.js → sql-DoO3y21-.js} +0 -0
  512. /package/client/dist/assets/{st-GeW2MOgh.js → st-ChZAY8oG.js} +0 -0
  513. /package/client/dist/assets/{swift-BVYTN8jq.js → swift-D290Tr7_.js} +0 -0
  514. /package/client/dist/assets/{systemverilog-Deg2a8Lr.js → systemverilog-DsxzgJ-o.js} +0 -0
  515. /package/client/dist/assets/{tcl-6DnLmROF.js → tcl-BKDUHAAR.js} +0 -0
  516. /package/client/dist/assets/{terminal-CDiOAmBd2.js → terminal-BRm03iFA2.js} +0 -0
  517. /package/client/dist/assets/{terminal-CJN-mQMc.js → terminal-De2Brd23.js} +0 -0
  518. /package/client/dist/assets/{terminal-CYB4TiAd.js → terminal-DxQWCqSD2.js} +0 -0
  519. /package/client/dist/assets/{terminal-DsaDTq5N2.js → terminal-WSAvHXoU.js} +0 -0
  520. /package/client/dist/assets/{terminal-DTQ_dPqi2.js → terminal-Z7KsDM_n.js} +0 -0
  521. /package/client/dist/assets/{terminal-58ReNaya.js → terminal-cqfd3EDV.js} +0 -0
  522. /package/client/dist/assets/{terminal-DawP8xNL.js → terminal-xGbCZJHg.js} +0 -0
  523. /package/client/dist/assets/{tickets-DoRTUYRT.js → tickets-B7zT4IRf.js} +0 -0
  524. /package/client/dist/assets/{tickets-DBfFePwk2.js → tickets-BoXom7l8.js} +0 -0
  525. /package/client/dist/assets/{tickets-DvohTziT2.js → tickets-C3b8cHhd2.js} +0 -0
  526. /package/client/dist/assets/{tickets-Da15iaRw.js → tickets-CFXnJsYF.js} +0 -0
  527. /package/client/dist/assets/{tickets-CujsZvkf.js → tickets-CWYFvx1W2.js} +0 -0
  528. /package/client/dist/assets/{tickets-Df6pee-O2.js → tickets-DTHo9c3C.js} +0 -0
  529. /package/client/dist/assets/{tickets-CNvIilmP.js → tickets-SuX_HkK4.js} +0 -0
  530. /package/client/dist/assets/{twig-XbbXW9Yz.js → twig-UpZQaM8G.js} +0 -0
  531. /package/client/dist/assets/{typespec-CRlV8GhI.js → typespec-DzaKvN8i.js} +0 -0
  532. /package/client/dist/assets/{vb-BHE2izPH.js → vb-CZpbb7tk.js} +0 -0
  533. /package/client/dist/assets/{wgsl-Bf5vkfmY.js → wgsl-CNt3OIvl.js} +0 -0
@@ -0,0 +1,629 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.PR_DECISION_ACTIONS = void 0;
37
+ exports.isPrDecisionAction = isPrDecisionAction;
38
+ exports.executePrDecision = executePrDecision;
39
+ /**
40
+ * Execute a user's ask-first PR decision (safe-pr-review-flow) against its
41
+ * authoritative `rail_pr_deliveries` row: the FOUR actions both decision
42
+ * surfaces (the dashboard rail row and the launching agent-chat card) POST to
43
+ * `/rails/pr-decision`.
44
+ *
45
+ * create-pr → deferred deliverRailAsPr, reconstructed from the row's durable
46
+ * columns (nothing survives in memory after build-settle). The
47
+ * PR title/body are composed HERE (canonical OSS style — see
48
+ * pr-naming/pr-body) from the ticket store + jira_links + the
49
+ * branch diffs, all failure-tolerant.
50
+ * publish → `gh pr ready` opens the draft for team review.
51
+ * discard → close the PR, sweep the launch's worktrees + branches, revert
52
+ * the on_review tickets to todo.
53
+ * poll-merge → `gh pr view` — MERGED promotes the tickets to done.
54
+ * merge-local→ the REMOTE-LESS acceptance path: merge the delivered branches
55
+ * into the integration branch directly in the user's checkout
56
+ * (guarded: correct branch checked out + clean tree, abort on
57
+ * conflict). Without it, a repo with no GitHub remote wedges
58
+ * forever in retry(local-only)/discard — no way to ACCEPT work.
59
+ *
60
+ * Every mutation rides the compare-and-set `transitionDecision` (a raced
61
+ * concurrent decision loses with a 409) and re-broadcasts the durable
62
+ * `rail.pr_state` snapshot so both surfaces converge; agent-chat-originated
63
+ * rows also update their inline decision card in place. Deps are injected
64
+ * (db/git/exec/broadcast/jira/agent-chat) so the whole matrix is unit-testable
65
+ * without git/gh/net — the route in rails-router validates and delegates here.
66
+ */
67
+ const path = __importStar(require("path"));
68
+ const artifact_registry_1 = require("./artifact-registry");
69
+ const worktree_manager_1 = require("./worktree-manager");
70
+ const rail_pr_delivery_1 = require("./rail-pr-delivery");
71
+ const pr_naming_1 = require("./pr-naming");
72
+ const pr_body_1 = require("./pr-body");
73
+ const jira_db_1 = require("./jira/jira-db");
74
+ const rail_pr_store_1 = require("./rail-pr-store");
75
+ const rail_worktrees_store_1 = require("./rail-worktrees-store");
76
+ const ticket_store_1 = require("./ticket-store");
77
+ const workspace_resolution_1 = require("./workspace-resolution");
78
+ const agent_chat_registry_1 = require("./agent-chat-registry");
79
+ exports.PR_DECISION_ACTIONS = ['create-pr', 'publish', 'discard', 'poll-merge', 'merge-local'];
80
+ function isPrDecisionAction(v) {
81
+ return typeof v === 'string' && exports.PR_DECISION_ACTIONS.includes(v);
82
+ }
83
+ function staleDecision(current) {
84
+ return { status: 409, body: { error: 'stale_decision', current } };
85
+ }
86
+ function illegalAction(current) {
87
+ return { status: 409, body: { error: 'stale_decision', current, reason: 'illegal_action' } };
88
+ }
89
+ function ghFailed(r) {
90
+ const detail = (r.stderr.trim() || r.stdout.trim()).split('\n')[0] || `exit ${r.code}`;
91
+ return { status: 502, body: { error: 'gh_failed', detail } };
92
+ }
93
+ /**
94
+ * The D3 state machine's action legality. `create-pr` is also the RETRY path:
95
+ * from a retryable pr_failed, or from a pr_draft whose delivery degraded before
96
+ * a PR existed (pushed/local-only → pr_url null). Publish/poll require a real
97
+ * PR URL — a degraded draft only offers retry or discard.
98
+ */
99
+ function actionAllowed(action, row) {
100
+ switch (action) {
101
+ case 'create-pr':
102
+ return row.decision === 'on_review' || row.decision === 'pr_failed' ||
103
+ (row.decision === 'pr_draft' && row.pr_url === null);
104
+ case 'publish':
105
+ return row.decision === 'pr_draft' && row.pr_url !== null;
106
+ case 'discard':
107
+ return row.decision === 'on_review' || row.decision === 'pr_draft' ||
108
+ row.decision === 'pr_ready' || row.decision === 'pr_failed';
109
+ case 'poll-merge':
110
+ return (row.decision === 'pr_draft' || row.decision === 'pr_ready') && row.pr_url !== null;
111
+ case 'merge-local':
112
+ // Remote-less acceptance ONLY: once a real PR exists (pr_url), GitHub is
113
+ // the merge authority — merging under an open PR would leave it dangling.
114
+ return row.pr_url === null &&
115
+ (row.decision === 'on_review' || row.decision === 'pr_failed' || row.decision === 'pr_draft');
116
+ }
117
+ }
118
+ async function executePrDecision(deps, input) {
119
+ const row = (0, rail_pr_store_1.getPrDelivery)(deps.db, input.prDeliveryId);
120
+ if (!row)
121
+ return { status: 404, body: { error: 'Unknown prDeliveryId' } };
122
+ // Compare-and-set pre-check: the caller decided against a snapshot — if the
123
+ // row moved on (the other surface answered first), it must reconcile, not act.
124
+ if (row.decision !== input.expectedDecision)
125
+ return staleDecision(row.decision);
126
+ if (!actionAllowed(input.action, row))
127
+ return illegalAction(row.decision);
128
+ switch (input.action) {
129
+ case 'create-pr': return runCreatePr(deps, row);
130
+ case 'publish': return runPublish(deps, row);
131
+ case 'discard': return runDiscard(deps, row);
132
+ case 'poll-merge': return runPollMerge(deps, row);
133
+ case 'merge-local': return runMergeLocal(deps, row);
134
+ }
135
+ }
136
+ /**
137
+ * Atomic CAS transition; a `false` return means a concurrent mutation raced us
138
+ * between the pre-check and here — surface the same 409 with the fresh state.
139
+ */
140
+ function casTransition(deps, row, next, patch = {}) {
141
+ if ((0, rail_pr_store_1.transitionDecision)(deps.db, row.id, row.decision, next, patch))
142
+ return null;
143
+ const current = (0, rail_pr_store_1.getPrDelivery)(deps.db, row.id);
144
+ return staleDecision(current?.decision ?? row.decision);
145
+ }
146
+ /**
147
+ * Post-transition fan-out: re-broadcast the durable rail.pr_state snapshot
148
+ * (both surfaces converge on it) and, for agent-chat-originated launches,
149
+ * update the persisted inline card in place.
150
+ */
151
+ function finalizeTransition(deps, id) {
152
+ const row = (0, rail_pr_store_1.getPrDelivery)(deps.db, id);
153
+ if (!row)
154
+ return undefined;
155
+ const snap = (0, rail_pr_store_1.toPrDeliverySnapshot)(row);
156
+ deps.broadcast((0, rail_pr_store_1.toRailPrStateMessage)(deps.project.id, snap));
157
+ if (row.origin_conversation_id) {
158
+ const agent = (deps.agentChat ?? agent_chat_registry_1.getAgentChatManager)();
159
+ // Shared mapper (rail-pr-store.toPrDecisionCardEnvelope) — the SAME shape
160
+ // rail-isolated-launch's origin-card sync posts, so the two card-writing
161
+ // sites (incl. the runIds chip data) can never drift.
162
+ agent?.updatePrDecisionCard(row.origin_conversation_id, (0, rail_pr_store_1.toPrDecisionCardEnvelope)(deps.project.id, snap));
163
+ }
164
+ return snap;
165
+ }
166
+ function parsePrNumber(prUrl) {
167
+ const m = /\/pull\/(\d+)/.exec(prUrl);
168
+ return m ? parseInt(m[1], 10) : null;
169
+ }
170
+ function batchWorktreeRoot(slug) {
171
+ // Mirrors rail-isolated-launch's worktreesRoot — derivable, never stored.
172
+ return path.join((0, artifact_registry_1.resolveHome)(), '.specrails', 'projects', slug, 'worktrees');
173
+ }
174
+ /**
175
+ * Load the PR's ticket data (title/labels/description) from the ticket store,
176
+ * with the Jira key resolved PER TICKET: the authoritative `jira_links` row
177
+ * prevails over the ticket's `jira_key` field (JIRA ALWAYS PREVAILS), no HTTP.
178
+ * Tolerant of a missing/corrupt store or link table — degrades to bare local
179
+ * ids, never throws, never blocks PR creation.
180
+ */
181
+ function loadPrTicketData(deps, ticketIds) {
182
+ let tickets = {};
183
+ try {
184
+ tickets = (0, ticket_store_1.readStore)(resolveTicketFile(deps)).tickets;
185
+ }
186
+ catch {
187
+ /* tolerated — the PR falls back to bare ticket refs */
188
+ }
189
+ return ticketIds.map((id) => {
190
+ const t = tickets[String(id)];
191
+ let jiraKey = t?.jira_key ?? null;
192
+ try {
193
+ const link = (0, jira_db_1.getLinkByLocalId)(deps.db, id);
194
+ if (link && !link.tombstoned && link.jiraKey)
195
+ jiraKey = link.jiraKey;
196
+ }
197
+ catch {
198
+ /* tolerated — fall back to the ticket field */
199
+ }
200
+ return {
201
+ ticketId: id,
202
+ title: t?.title ?? null,
203
+ labels: t?.labels ?? null,
204
+ description: t?.description ?? null,
205
+ jiraKey,
206
+ };
207
+ });
208
+ }
209
+ /** True when the branch exists as a local ref in the base repo. */
210
+ async function branchExists(deps, branch) {
211
+ const r = await deps.git.run(['rev-parse', '--verify', '--quiet', `refs/heads/${branch}`], deps.project.path);
212
+ return r.code === 0;
213
+ }
214
+ /**
215
+ * Recovery for a recorded unit branch that no longer exists (the wedged
216
+ * local-only retry: the settled record drifted from the branch that really
217
+ * carries the commits, or the branch was deleted externally). Scan the ticket's
218
+ * rail_worktrees ledger (newest first) for ANY other branch a rail allocated
219
+ * for the same ticket that still exists AND has commits ahead of the base —
220
+ * that branch is the real carrier of the work. Null when nothing recoverable.
221
+ */
222
+ async function findRecoverableBranch(deps, unit, baseBranch) {
223
+ let candidates = [];
224
+ try {
225
+ candidates = (0, rail_worktrees_store_1.listRailWorktreesForTicket)(deps.db, unit.ticketId);
226
+ }
227
+ catch {
228
+ return null;
229
+ }
230
+ for (const wt of candidates) {
231
+ if (!wt.branch || wt.branch === unit.branch || wt.branch === baseBranch)
232
+ continue;
233
+ if (!(await branchExists(deps, wt.branch)))
234
+ continue;
235
+ const ahead = await deps.git.run(['rev-list', '--count', `${baseBranch}..${wt.branch}`], deps.project.path);
236
+ const n = ahead.code === 0 ? parseInt(ahead.stdout.trim(), 10) : NaN;
237
+ if (Number.isFinite(n) && n > 0)
238
+ return wt.branch;
239
+ }
240
+ return null;
241
+ }
242
+ async function runCreatePr(deps, row) {
243
+ const snap = (0, rail_pr_store_1.toPrDeliverySnapshot)(row);
244
+ // Pre-flight: every succeeded unit branch must actually exist before we push
245
+ // it — a missing ref can only degrade to local-only again, so a retry on a
246
+ // wedged row would loop forever. When a recorded branch is gone, recover the
247
+ // REAL branch from the ticket's worktree ledger (see findRecoverableBranch)
248
+ // and persist the substitution on the row; unrecoverable → honest pr_failed.
249
+ let effectiveBranches = snap.branches;
250
+ let branchesRecovered = false;
251
+ for (const unit of snap.branches) {
252
+ if (!unit.succeeded)
253
+ continue;
254
+ if (await branchExists(deps, unit.branch))
255
+ continue;
256
+ const real = await findRecoverableBranch(deps, unit, row.base_branch);
257
+ if (!real) {
258
+ const detail = `branch '${unit.branch}' (ticket #${unit.ticketId}) no longer exists locally and no other rail branch for the ticket holds commits — nothing to deliver`;
259
+ const conflict = casTransition(deps, row, 'pr_failed');
260
+ if (conflict)
261
+ return conflict;
262
+ finalizeTransition(deps, row.id);
263
+ return { status: 200, body: { ok: true, decision: 'pr_failed', detail } };
264
+ }
265
+ console.warn(`[rail-pr-decision] recorded branch '${unit.branch}' missing — recovered '${real}' from the ticket ${unit.ticketId} worktree ledger`);
266
+ effectiveBranches = effectiveBranches.map((b) => (b === unit ? { ...b, branch: real } : b));
267
+ branchesRecovered = true;
268
+ }
269
+ // Succeeded COVERED tickets for the PR title/body: a single unit covers every
270
+ // launch ticket (scope='all'), per-ticket units cover exactly their own.
271
+ const succeededUnits = effectiveBranches.filter((b) => b.succeeded);
272
+ const succeededTicketIds = effectiveBranches.length === 1 && succeededUnits.length === 1
273
+ ? snap.ticketIds
274
+ : succeededUnits.map((b) => b.ticketId);
275
+ const ticketData = loadPrTicketData(deps, succeededTicketIds);
276
+ // The batch name is derived ONLY for multi-unit deliveries — the single-ticket
277
+ // path delivers straight from its unit branch and must never even compute one.
278
+ const batchPreferred = succeededUnits.length > 1 ? (0, pr_naming_1.batchBranchNameFor)(ticketData) : null;
279
+ // Retry hazard: deliverRailAsPr assembles with `worktree add -b` (no -B) and a
280
+ // prior degraded delivery KEEPS the batch branch — so a retry would die on
281
+ // "branch already exists". Defensively drop the stale batch branch first
282
+ // (batch deliveries only). HARD GUARDS: NEVER a branch present in the row's
283
+ // unit records (deleting one would destroy the commits about to be delivered)
284
+ // and NEVER the integration branch; a missing branch is tolerated.
285
+ const unitBranches = new Set(effectiveBranches.map((b) => b.branch));
286
+ if (batchPreferred && batchPreferred !== row.base_branch && !unitBranches.has(batchPreferred)) {
287
+ await deps.git.run(['branch', '-D', batchPreferred], deps.project.path).catch(() => { });
288
+ }
289
+ // Per-ticket covering branch for the body's honest Tests digest: per-ticket
290
+ // units map 1:1; a single 'all'-scope unit covers every launch ticket.
291
+ const branchFor = (ticketId) => {
292
+ const unit = succeededUnits.find((b) => b.ticketId === ticketId);
293
+ if (unit)
294
+ return unit.branch;
295
+ return succeededUnits.length === 1 ? succeededUnits[0].branch : null;
296
+ };
297
+ // Diffstats are best-effort: a git failure degrades the body (section
298
+ // omitted / "diff unavailable" note), never blocks the PR.
299
+ let changes = null;
300
+ try {
301
+ changes = await (0, pr_body_1.collectBranchChanges)(deps.git, deps.project.path, row.base_branch, succeededUnits.map((b) => b.branch));
302
+ }
303
+ catch {
304
+ changes = null;
305
+ }
306
+ const title = (0, pr_naming_1.buildPrTitle)(ticketData, { loopName: row.loop_name });
307
+ const body = (0, pr_body_1.buildCanonicalPrBody)({
308
+ loopName: row.loop_name,
309
+ baseBranch: row.base_branch,
310
+ tickets: ticketData.map((t) => ({ ...t, branch: branchFor(t.ticketId) })),
311
+ changes,
312
+ });
313
+ let next;
314
+ // Underlying git/gh failure detail for a degraded or failed delivery —
315
+ // relayed on the response body so the decision surfaces can say WHY instead
316
+ // of a bare "retry". Never persisted (the durable columns stay state-only).
317
+ let detail = null;
318
+ const patch = {};
319
+ // Persist any pre-flight substitution so the row records the branch that
320
+ // actually carries the commits — the next retry/discard works from reality.
321
+ if (branchesRecovered)
322
+ patch.branches = effectiveBranches;
323
+ try {
324
+ const result = await (0, rail_pr_delivery_1.deliverRailAsPr)(deps.git, deps.exec, {
325
+ baseRepo: deps.project.path,
326
+ integrationBranch: row.base_branch,
327
+ railKey: row.rail_key,
328
+ batchBranch: batchPreferred ?? undefined,
329
+ batchWorktreeRoot: batchWorktreeRoot(deps.project.slug),
330
+ branches: effectiveBranches,
331
+ title,
332
+ body,
333
+ });
334
+ if (result.state === 'delivered') {
335
+ next = 'pr_draft';
336
+ patch.branch = result.branch;
337
+ patch.prState = result.pr.state;
338
+ if (result.pr.state === 'pr-created' && result.pr.prUrl) {
339
+ patch.prUrl = result.pr.prUrl;
340
+ patch.prNumber = parsePrNumber(result.pr.prUrl);
341
+ }
342
+ else {
343
+ // Degraded (pushed / local-only): no PR exists — only retry or discard.
344
+ patch.prUrl = null;
345
+ patch.prNumber = null;
346
+ detail = result.pr.reason ?? null;
347
+ }
348
+ }
349
+ else {
350
+ // 'assembly-failed' (or an unexpected 'no-op' — settle guarantees ≥1
351
+ // succeeded unit, but a wedged row must not 500) → retryable failure.
352
+ next = 'pr_failed';
353
+ detail = result.reason;
354
+ }
355
+ }
356
+ catch (err) {
357
+ // publishDraftPr can propagate GitGuardrailError — a guardrail violation is
358
+ // a retryable delivery failure, never a crash.
359
+ console.error('[rail-pr-decision] create-pr delivery failed:', err);
360
+ next = 'pr_failed';
361
+ detail = err instanceof Error ? err.message : String(err);
362
+ }
363
+ const conflict = casTransition(deps, row, next, patch);
364
+ if (conflict)
365
+ return conflict;
366
+ const after = finalizeTransition(deps, row.id);
367
+ // Tickets stay on_review — a draft PR is still awaiting the engineer's merge.
368
+ return {
369
+ status: 200,
370
+ body: {
371
+ ok: true,
372
+ decision: next,
373
+ prUrl: after?.prUrl ?? null,
374
+ prState: after?.prState ?? row.pr_state,
375
+ ...(detail ? { detail } : {}),
376
+ },
377
+ };
378
+ }
379
+ async function runPublish(deps, row) {
380
+ const r = await deps.exec.run('gh', ['pr', 'ready', row.pr_url], deps.project.path);
381
+ if (r.code !== 0)
382
+ return ghFailed(r); // no transition — the draft is still a draft
383
+ const conflict = casTransition(deps, row, 'pr_ready');
384
+ if (conflict)
385
+ return conflict;
386
+ finalizeTransition(deps, row.id);
387
+ return { status: 200, body: { ok: true, decision: 'pr_ready', prUrl: row.pr_url } };
388
+ }
389
+ async function runDiscard(deps, row) {
390
+ const snap = (0, rail_pr_store_1.toPrDeliverySnapshot)(row);
391
+ // 1. Close the PR (drops its head branch) when one exists. Best-effort — a
392
+ // gh failure must never leave the discard half-done.
393
+ if (row.pr_url) {
394
+ try {
395
+ const r = await deps.exec.run('gh', ['pr', 'close', row.pr_url, '--delete-branch'], deps.project.path);
396
+ if (r.code !== 0) {
397
+ console.warn(`[rail-pr-decision] gh pr close failed (continuing discard): ${(r.stderr.trim() || r.stdout.trim()).split('\n')[0]}`);
398
+ }
399
+ }
400
+ catch (err) {
401
+ console.warn('[rail-pr-decision] gh pr close threw (continuing discard):', err);
402
+ }
403
+ }
404
+ // 2. Remove the launch's worktrees (still on disk unless a restart already
405
+ // swept them) and close their ledger rows — the reconcile-style removal,
406
+ // branch deletion deferred to step 3 (a checked-out branch can't be -D'd).
407
+ const branchSet = new Set(snap.branches.map((b) => b.branch));
408
+ for (const wtId of snap.worktreeIds) {
409
+ const wt = (0, rail_worktrees_store_1.getRailWorktree)(deps.db, wtId);
410
+ if (!wt)
411
+ continue;
412
+ branchSet.add(wt.branch);
413
+ await (0, worktree_manager_1.removeWorktree)(deps.git, {
414
+ repoDir: deps.project.path, worktreePath: wt.worktree_path, branch: wt.branch, deleteBranch: false,
415
+ }).catch(() => { });
416
+ if (!(0, rail_worktrees_store_1.isTerminalMergeState)(wt.merge_state))
417
+ (0, rail_worktrees_store_1.updateRailWorktreeState)(deps.db, wt.id, 'failed');
418
+ }
419
+ // 3. Delete every branch the delivery references: per-unit source branches,
420
+ // the assembled head and the (possibly stale) batch branch — recomputed
421
+ // best-effort from the same ticket data the create-pr path names it from
422
+ // (the delivered head is already covered by row.branch). Missing branches
423
+ // are tolerated; the integration branch is NEVER deleted.
424
+ if (row.branch)
425
+ branchSet.add(row.branch);
426
+ const succeededUnits = snap.branches.filter((b) => b.succeeded);
427
+ if (succeededUnits.length > 1) {
428
+ try {
429
+ branchSet.add((0, pr_naming_1.batchBranchNameFor)(loadPrTicketData(deps, succeededUnits.map((b) => b.ticketId))));
430
+ }
431
+ catch {
432
+ /* best-effort defense-in-depth only */
433
+ }
434
+ }
435
+ for (const branch of branchSet) {
436
+ if (!branch || branch === row.base_branch)
437
+ continue;
438
+ await deps.git.run(['branch', '-D', branch], deps.project.path).catch(() => { });
439
+ }
440
+ const conflict = casTransition(deps, row, 'discarded');
441
+ if (conflict)
442
+ return conflict;
443
+ finalizeTransition(deps, row.id);
444
+ // 4. Revert the parked tickets to the backlog + mirror to Jira (outbox-only;
445
+ // the local write above is ours).
446
+ const changed = applyTicketTransition(deps, snap.ticketIds, 'todo');
447
+ try {
448
+ deps.jiraSyncManager?.onRailDiscard(changed, row.id);
449
+ }
450
+ catch (err) {
451
+ console.error('[rail-pr-decision] jira onRailDiscard failed:', err);
452
+ }
453
+ return { status: 200, body: { ok: true, decision: 'discarded' } };
454
+ }
455
+ async function runPollMerge(deps, row) {
456
+ const r = await deps.exec.run('gh', ['pr', 'view', row.pr_url, '--json', 'state,mergedAt'], deps.project.path);
457
+ if (r.code !== 0)
458
+ return ghFailed(r); // no transition
459
+ let state;
460
+ try {
461
+ state = JSON.parse(r.stdout).state;
462
+ }
463
+ catch {
464
+ return { status: 502, body: { error: 'gh_failed', detail: 'unparseable gh pr view output' } };
465
+ }
466
+ if (state !== 'MERGED') {
467
+ // Not merged (OPEN/CLOSED/unknown) → observation only, nothing changes.
468
+ return { status: 200, body: { ok: true, decision: row.decision, merged: false } };
469
+ }
470
+ const conflict = casTransition(deps, row, 'merged');
471
+ if (conflict)
472
+ return conflict;
473
+ finalizeTransition(deps, row.id);
474
+ const snap = (0, rail_pr_store_1.toPrDeliverySnapshot)(row);
475
+ const changed = applyTicketTransition(deps, snap.ticketIds, 'done');
476
+ try {
477
+ deps.jiraSyncManager?.onRailMerged(changed, row.id, row.pr_url);
478
+ }
479
+ catch (err) {
480
+ console.error('[rail-pr-decision] jira onRailMerged failed:', err);
481
+ }
482
+ return { status: 200, body: { ok: true, decision: 'merged', merged: true, prUrl: row.pr_url } };
483
+ }
484
+ /**
485
+ * Remote-less acceptance: merge the delivery's branches into the integration
486
+ * branch DIRECTLY in the user's checkout. This is the one decision that touches
487
+ * the user's working tree, so it is triple-guarded and transactional-ish:
488
+ *
489
+ * - The checkout must have the integration branch checked out (a branch can
490
+ * only be checked out in one worktree — merging via a temp worktree is
491
+ * impossible while the user holds it) → 409 `merge_local_blocked` otherwise.
492
+ * - The working tree must be CLEAN → 409 `merge_local_blocked` otherwise.
493
+ * - Merge = the assembled head when one exists (row.branch), else each
494
+ * succeeded unit branch sequentially, `--no-ff --no-edit`. Any conflict →
495
+ * `merge --abort` + 502 `merge_failed`, NO transition (retry or discard).
496
+ *
497
+ * Success mirrors poll-merge's MERGED arm: decision → merged (prUrl stays
498
+ * null), worktrees/branches swept, tickets → done, Jira onRailMerged(null).
499
+ */
500
+ async function runMergeLocal(deps, row) {
501
+ const snap = (0, rail_pr_store_1.toPrDeliverySnapshot)(row);
502
+ // Guards on the user's checkout.
503
+ const head = await deps.git.run(['rev-parse', '--abbrev-ref', 'HEAD'], deps.project.path);
504
+ const currentBranch = head.code === 0 ? head.stdout.trim() : '';
505
+ if (currentBranch !== row.base_branch) {
506
+ return {
507
+ status: 409,
508
+ body: { error: 'merge_local_blocked', reason: 'wrong_branch', current: currentBranch || null, base: row.base_branch },
509
+ };
510
+ }
511
+ const status = await deps.git.run(['status', '--porcelain'], deps.project.path);
512
+ if (status.code !== 0 || status.stdout.trim() !== '') {
513
+ return { status: 409, body: { error: 'merge_local_blocked', reason: 'dirty', base: row.base_branch } };
514
+ }
515
+ // What to merge: the assembled head carries every unit already; without one
516
+ // (straight from on_review) merge each succeeded unit branch in order.
517
+ let toMerge;
518
+ if (row.branch && (await branchExists(deps, row.branch))) {
519
+ toMerge = [row.branch];
520
+ }
521
+ else {
522
+ toMerge = [];
523
+ for (const unit of snap.branches.filter((b) => b.succeeded)) {
524
+ let branch = unit.branch;
525
+ if (!(await branchExists(deps, branch)))
526
+ branch = await findRecoverableBranch(deps, unit, row.base_branch);
527
+ if (!branch) {
528
+ return {
529
+ status: 502,
530
+ body: { error: 'merge_failed', detail: `branch '${unit.branch}' (ticket #${unit.ticketId}) no longer exists locally — nothing to merge` },
531
+ };
532
+ }
533
+ toMerge.push(branch);
534
+ }
535
+ }
536
+ if (toMerge.length === 0) {
537
+ return { status: 502, body: { error: 'merge_failed', detail: 'no succeeded branch to merge' } };
538
+ }
539
+ for (const branch of toMerge) {
540
+ const r = await deps.git.run(['merge', '--no-ff', '--no-edit', branch], deps.project.path);
541
+ if (r.code !== 0) {
542
+ await deps.git.run(['merge', '--abort'], deps.project.path).catch(() => { });
543
+ const detail = (r.stderr.trim() || r.stdout.trim()).split('\n')[0] || `exit ${r.code}`;
544
+ return { status: 502, body: { error: 'merge_failed', detail: `merging '${branch}': ${detail}` } };
545
+ }
546
+ }
547
+ // Post-merge sweep (same shape as discard steps 2-3): the work now lives on
548
+ // the integration branch, so the launch's worktrees + branches are spent.
549
+ const branchSet = new Set(toMerge);
550
+ for (const b of snap.branches)
551
+ branchSet.add(b.branch);
552
+ if (row.branch)
553
+ branchSet.add(row.branch);
554
+ for (const wtId of snap.worktreeIds) {
555
+ const wt = (0, rail_worktrees_store_1.getRailWorktree)(deps.db, wtId);
556
+ if (!wt)
557
+ continue;
558
+ branchSet.add(wt.branch);
559
+ await (0, worktree_manager_1.removeWorktree)(deps.git, {
560
+ repoDir: deps.project.path, worktreePath: wt.worktree_path, branch: wt.branch, deleteBranch: false,
561
+ }).catch(() => { });
562
+ if (!(0, rail_worktrees_store_1.isTerminalMergeState)(wt.merge_state))
563
+ (0, rail_worktrees_store_1.updateRailWorktreeState)(deps.db, wt.id, 'merged');
564
+ }
565
+ for (const branch of branchSet) {
566
+ if (!branch || branch === row.base_branch)
567
+ continue;
568
+ await deps.git.run(['branch', '-D', branch], deps.project.path).catch(() => { });
569
+ }
570
+ const conflict = casTransition(deps, row, 'merged');
571
+ if (conflict)
572
+ return conflict;
573
+ finalizeTransition(deps, row.id);
574
+ const changed = applyTicketTransition(deps, snap.ticketIds, 'done');
575
+ try {
576
+ deps.jiraSyncManager?.onRailMerged(changed, row.id, null);
577
+ }
578
+ catch (err) {
579
+ console.error('[rail-pr-decision] jira onRailMerged (local) failed:', err);
580
+ }
581
+ return { status: 200, body: { ok: true, decision: 'merged', merged: true, local: true } };
582
+ }
583
+ function resolveTicketFile(deps) {
584
+ if (deps.ticketFile)
585
+ return deps.ticketFile;
586
+ const exec = (0, workspace_resolution_1.resolveProjectExecution)({ slug: deps.project.slug, path: deps.project.path });
587
+ return exec.relocated ? exec.ticketsPath : (0, ticket_store_1.resolveTicketStoragePath)(deps.project.path);
588
+ }
589
+ /**
590
+ * Move the launch's on_review tickets to `todo` (discard) or `done` (merged),
591
+ * broadcasting ticket_updated per changed spec — mirroring onLoopRunFinished's
592
+ * revert style in project-registry. ONLY tickets still parked at on_review move
593
+ * (a manually re-triaged spec is respected). Best-effort: a ticket-store
594
+ * failure is logged, never fatal (the decision row already transitioned).
595
+ */
596
+ function applyTicketTransition(deps, ticketIds, to) {
597
+ const changed = [];
598
+ if (ticketIds.length === 0)
599
+ return changed;
600
+ try {
601
+ const ticketFile = resolveTicketFile(deps);
602
+ const now = new Date().toISOString();
603
+ const store = (0, ticket_store_1.mutateStore)(ticketFile, (s) => {
604
+ for (const tid of ticketIds) {
605
+ const ticket = s.tickets[String(tid)];
606
+ if (!ticket || ticket.status !== 'on_review')
607
+ continue;
608
+ ticket.status = to;
609
+ ticket.updated_at = now;
610
+ changed.push(tid);
611
+ }
612
+ });
613
+ for (const tid of changed) {
614
+ const ticket = store.tickets[String(tid)];
615
+ if (!ticket)
616
+ continue;
617
+ deps.broadcast({
618
+ type: 'ticket_updated',
619
+ ticket: ticket,
620
+ projectId: deps.project.id,
621
+ timestamp: ticket.updated_at,
622
+ });
623
+ }
624
+ }
625
+ catch (err) {
626
+ console.error('[rail-pr-decision] failed to apply ticket transition:', err);
627
+ }
628
+ return changed;
629
+ }