specrails-desktop 2.20.1 → 2.22.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 (540) hide show
  1. package/README.md +3 -2
  2. package/client/dist/assets/{ActivityFeedPage-3WSqRYVx.js → ActivityFeedPage-roDyKGuv.js} +1 -1
  3. package/client/dist/assets/AgentBrowserCapture-BsXnWa4j.js +1 -0
  4. package/client/dist/assets/{AgentModeCodePane-Cnsea6eZ.js → AgentModeCodePane-o97EJvbJ.js} +2 -2
  5. package/client/dist/assets/AgentModeJobsPane-CLtpPxPM.js +1 -0
  6. package/client/dist/assets/AgentsPage-eNSo_ZcC.js +86 -0
  7. package/client/dist/assets/AnalyticsPage-cAJ60_Ex.js +1 -0
  8. package/client/dist/assets/{BarChart-C6If656N.js → BarChart-NLtK7xAY.js} +1 -1
  9. package/client/dist/assets/CodePage-B5rum8ZB.js +2 -0
  10. package/client/dist/assets/DesktopAnalyticsPage-DSuvG6Tq.js +1 -0
  11. package/client/dist/assets/DocsDialog-Bo38G3Yc.js +11 -0
  12. package/client/dist/assets/DocsPage-BNkiBBrC.js +11 -0
  13. package/client/dist/assets/{ExportDropdown-CezTK0EX.js → ExportDropdown-DCV8PN4-.js} +1 -1
  14. package/client/dist/assets/IntegrationsPage-BMJOzpPz.js +3 -0
  15. package/client/dist/assets/InteractiveJobComposer-aLduNs5R.js +19 -0
  16. package/client/dist/assets/JobDetailModal-kpkUWJIS.js +1 -0
  17. package/client/dist/assets/JobDetailPage-CFeqlrPU.js +1 -0
  18. package/client/dist/assets/JobsPage-fuwhXy2I.js +1 -0
  19. package/client/dist/assets/LoopBuilderPage-DP66322C.js +7 -0
  20. package/client/dist/assets/LoopPreviewModal-CpmBhE31.js +1 -0
  21. package/client/dist/assets/LoopsPage-CvQ18VUx.js +1 -0
  22. package/client/dist/assets/ProjectSettingsDialog-Deq4pwvq.js +1 -0
  23. package/client/dist/assets/TemplatePreviewModal-DziOj2Ct.js +1 -0
  24. package/client/dist/assets/agent-Csh4kP2S.js +1 -0
  25. package/client/dist/assets/agent-Cz_jgQX32.js +1 -0
  26. package/client/dist/assets/agent-D3vcIvaz2.js +1 -0
  27. package/client/dist/assets/agent-Dnbt0V4e.js +1 -0
  28. package/client/dist/assets/agent-HolR7QrZ.js +1 -0
  29. package/client/dist/assets/agent-Ka0rRWJy.js +1 -0
  30. package/client/dist/assets/agent-Te3yysMd.js +1 -0
  31. package/client/dist/assets/agent-vM4_iLDk2.js +1 -0
  32. package/client/dist/assets/{upload-CRtTj4Co.js → brain-kFJuEDNH.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-BaStj_a_.js +1 -0
  59. package/client/dist/assets/dashboard-Bi6ugu5Q.js +1 -0
  60. package/client/dist/assets/dashboard-BmqTn3L02.js +1 -0
  61. package/client/dist/assets/dashboard-CvT8lOCT.js +1 -0
  62. package/client/dist/assets/dashboard-D7Pmeavq2.js +1 -0
  63. package/client/dist/assets/dashboard-DAnWdAac2.js +1 -0
  64. package/client/dist/assets/dashboard-JnYy2WLg.js +1 -0
  65. package/client/dist/assets/dashboard-L47YsFS_.js +1 -0
  66. package/client/dist/assets/{dist-js-BQn4yxaw.js → dist-js-BZSiJDbG.js} +1 -1
  67. package/client/dist/assets/{dist-js-BAWSqVtr.js → dist-js-DKpmIJlQ.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-DM6heiGa.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-C-g8QbZl.js → lib-B2nCKzmA.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/{settings-BPq9nCJm.js → settings-BOHOmHkb.js} +1 -1
  109. package/client/dist/assets/{settings-r8Qq2Gzp2.js → settings-BlEA_7h02.js} +1 -1
  110. package/client/dist/assets/{settings-C-m3yEZ2.js → settings-BsJMsWGc.js} +1 -1
  111. package/client/dist/assets/{settings-zZr7NzuB.js → settings-D6qY9_UI.js} +1 -1
  112. package/client/dist/assets/{settings-VgCsjaYf.js → settings-DZJeXoRV.js} +1 -1
  113. package/client/dist/assets/settings-Mr7MnJbf.js +1 -0
  114. package/client/dist/assets/{settings-BWHGtmU12.js → settings-TNga5gIF2.js} +1 -1
  115. package/client/dist/assets/{settings-DZj7Uqy32.js → settings-lFoaYT-s2.js} +1 -1
  116. package/client/dist/assets/setup-B590KsTX.js +1 -0
  117. package/client/dist/assets/setup-BkyGoby6.js +1 -0
  118. package/client/dist/assets/setup-CEj6uY3-2.js +1 -0
  119. package/client/dist/assets/setup-CbIerFGf2.js +1 -0
  120. package/client/dist/assets/setup-CmU6bTCV2.js +1 -0
  121. package/client/dist/assets/setup-D674kWQH.js +1 -0
  122. package/client/dist/assets/setup-VNqXyB6Y.js +1 -0
  123. package/client/dist/assets/setup-iY8vH8pB.js +1 -0
  124. package/client/dist/assets/specs-C9Sd7BhH2.js +1 -0
  125. package/client/dist/assets/specs-CBDvEYKv.js +1 -0
  126. package/client/dist/assets/specs-CIPr9reA2.js +1 -0
  127. package/client/dist/assets/specs-CWtKcVDC.js +1 -0
  128. package/client/dist/assets/specs-CmEZY57v.js +1 -0
  129. package/client/dist/assets/specs-D2clrt2c2.js +1 -0
  130. package/client/dist/assets/specs-DTplt2XM.js +1 -0
  131. package/client/dist/assets/specs-PozUNhqb.js +1 -0
  132. package/client/dist/assets/{tsMode-BC1g186U.js → tsMode-BmT8WogI.js} +1 -1
  133. package/client/dist/assets/{typescript-BGlRGvJW.js → typescript-CQrQPsoW.js} +1 -1
  134. package/client/dist/assets/upload-CLAzW1mS.js +1 -0
  135. package/client/dist/assets/{value-D9aLbxw-.js → value-DSwzyyWR.js} +1 -1
  136. package/client/dist/assets/{workers-CXcXtO3b.js → workers-U0UXyLUf.js} +1 -1
  137. package/client/dist/assets/{xml-JdZZaIhJ.js → xml-WRxJs8_I.js} +1 -1
  138. package/client/dist/assets/{yaml-Cm82BVBt.js → yaml-CjpSTjJU.js} +1 -1
  139. package/client/dist/index.html +14 -14
  140. package/docs/customizing.md +2 -2
  141. package/docs/gemini.md +15 -4
  142. package/docs/guide/de/insights/3-code-explorer.md +6 -0
  143. package/docs/guide/de/integrations/3-jira-integration.md +1 -1
  144. package/docs/guide/de/integrations/6-agent-chat.md +5 -0
  145. package/docs/guide/de/pipeline/1-rails-and-jobs.md +6 -6
  146. package/docs/guide/de/pipeline/2-the-job-detail-view.md +27 -2
  147. package/docs/guide/de/pipeline/3-batch-implement-and-multi-feature.md +9 -5
  148. package/docs/guide/de/pipeline/5-the-loop-builder.md +1 -1
  149. package/docs/guide/de/specs/1-specs-and-the-backlog.md +3 -2
  150. package/docs/guide/en/insights/3-code-explorer.md +6 -0
  151. package/docs/guide/en/integrations/3-jira-integration.md +1 -1
  152. package/docs/guide/en/integrations/6-agent-chat.md +5 -0
  153. package/docs/guide/en/pipeline/1-rails-and-jobs.md +6 -6
  154. package/docs/guide/en/pipeline/2-the-job-detail-view.md +27 -2
  155. package/docs/guide/en/pipeline/3-batch-implement-and-multi-feature.md +10 -4
  156. package/docs/guide/en/pipeline/5-the-loop-builder.md +1 -1
  157. package/docs/guide/en/specs/1-specs-and-the-backlog.md +3 -2
  158. package/docs/guide/es/insights/3-code-explorer.md +6 -0
  159. package/docs/guide/es/integrations/3-jira-integration.md +1 -1
  160. package/docs/guide/es/integrations/6-agent-chat.md +5 -0
  161. package/docs/guide/es/pipeline/1-rails-and-jobs.md +6 -6
  162. package/docs/guide/es/pipeline/2-the-job-detail-view.md +27 -2
  163. package/docs/guide/es/pipeline/3-batch-implement-and-multi-feature.md +9 -5
  164. package/docs/guide/es/pipeline/5-the-loop-builder.md +1 -1
  165. package/docs/guide/es/specs/1-specs-and-the-backlog.md +3 -2
  166. package/docs/guide/fr/insights/3-code-explorer.md +6 -0
  167. package/docs/guide/fr/integrations/3-jira-integration.md +1 -1
  168. package/docs/guide/fr/integrations/6-agent-chat.md +5 -0
  169. package/docs/guide/fr/pipeline/1-rails-and-jobs.md +6 -6
  170. package/docs/guide/fr/pipeline/2-the-job-detail-view.md +27 -2
  171. package/docs/guide/fr/pipeline/3-batch-implement-and-multi-feature.md +9 -5
  172. package/docs/guide/fr/pipeline/5-the-loop-builder.md +1 -1
  173. package/docs/guide/fr/specs/1-specs-and-the-backlog.md +3 -2
  174. package/docs/guide/it/insights/3-code-explorer.md +6 -0
  175. package/docs/guide/it/integrations/3-jira-integration.md +1 -1
  176. package/docs/guide/it/integrations/6-agent-chat.md +5 -0
  177. package/docs/guide/it/pipeline/1-rails-and-jobs.md +6 -6
  178. package/docs/guide/it/pipeline/2-the-job-detail-view.md +27 -2
  179. package/docs/guide/it/pipeline/3-batch-implement-and-multi-feature.md +10 -6
  180. package/docs/guide/it/pipeline/5-the-loop-builder.md +1 -1
  181. package/docs/guide/it/specs/1-specs-and-the-backlog.md +3 -2
  182. package/docs/guide/ja/insights/3-code-explorer.md +6 -0
  183. package/docs/guide/ja/integrations/3-jira-integration.md +1 -1
  184. package/docs/guide/ja/integrations/6-agent-chat.md +5 -0
  185. package/docs/guide/ja/pipeline/1-rails-and-jobs.md +6 -6
  186. package/docs/guide/ja/pipeline/2-the-job-detail-view.md +27 -2
  187. package/docs/guide/ja/pipeline/3-batch-implement-and-multi-feature.md +9 -5
  188. package/docs/guide/ja/pipeline/5-the-loop-builder.md +1 -1
  189. package/docs/guide/ja/specs/1-specs-and-the-backlog.md +3 -2
  190. package/docs/guide/pt/insights/3-code-explorer.md +6 -0
  191. package/docs/guide/pt/integrations/3-jira-integration.md +1 -1
  192. package/docs/guide/pt/integrations/6-agent-chat.md +5 -0
  193. package/docs/guide/pt/pipeline/1-rails-and-jobs.md +6 -6
  194. package/docs/guide/pt/pipeline/2-the-job-detail-view.md +27 -2
  195. package/docs/guide/pt/pipeline/3-batch-implement-and-multi-feature.md +9 -5
  196. package/docs/guide/pt/pipeline/5-the-loop-builder.md +1 -1
  197. package/docs/guide/pt/specs/1-specs-and-the-backlog.md +3 -2
  198. package/docs/guide/zh/insights/3-code-explorer.md +6 -0
  199. package/docs/guide/zh/integrations/3-jira-integration.md +1 -1
  200. package/docs/guide/zh/integrations/6-agent-chat.md +5 -0
  201. package/docs/guide/zh/pipeline/1-rails-and-jobs.md +6 -6
  202. package/docs/guide/zh/pipeline/2-the-job-detail-view.md +27 -2
  203. package/docs/guide/zh/pipeline/3-batch-implement-and-multi-feature.md +10 -6
  204. package/docs/guide/zh/pipeline/5-the-loop-builder.md +1 -1
  205. package/docs/guide/zh/specs/1-specs-and-the-backlog.md +3 -2
  206. package/docs/internals/README.md +5 -0
  207. package/docs/internals/adding-a-provider.md +15 -3
  208. package/docs/internals/api-reference.md +6 -5
  209. package/docs/internals/browser-capture-performance.md +93 -0
  210. package/docs/internals/code-explorer-story.md +135 -0
  211. package/docs/internals/gemini-mcp-registration.md +53 -0
  212. package/docs/internals/interactive-jobs.md +212 -0
  213. package/docs/internals/loop-step-log-explorer.md +146 -0
  214. package/docs/internals/safe-pr-review-flow.md +367 -0
  215. package/docs/mcp.md +1 -1
  216. package/docs/running-pipelines.md +6 -2
  217. package/package.json +1 -1
  218. package/server/dist/agent-chat-manager.js +211 -0
  219. package/server/dist/agent-chat-registry.js +20 -0
  220. package/server/dist/agent-chat-router.js +22 -0
  221. package/server/dist/agent-mcp-config.js +45 -4
  222. package/server/dist/agent-operator-prompt.js +149 -56
  223. package/server/dist/agent-store.js +25 -0
  224. package/server/dist/agent-tier.js +6 -1
  225. package/server/dist/browser-capture-manager.js +184 -34
  226. package/server/dist/browser-playwright.js +98 -13
  227. package/server/dist/code-explorer-router.js +92 -0
  228. package/server/dist/db.js +102 -0
  229. package/server/dist/file-provenance.js +54 -1
  230. package/server/dist/file-story-manager.js +170 -0
  231. package/server/dist/file-story.js +148 -0
  232. package/server/dist/file-summary-generator.js +5 -4
  233. package/server/dist/git-guardrails.js +62 -0
  234. package/server/dist/index.js +5 -0
  235. package/server/dist/integration-branch.js +63 -0
  236. package/server/dist/interactive-job-session.js +226 -18
  237. package/server/dist/jira/jira-adf.js +9 -0
  238. package/server/dist/jira/jira-materializer.js +27 -4
  239. package/server/dist/jira/jira-status-resolver.js +12 -4
  240. package/server/dist/jira/jira-sync-manager.js +130 -2
  241. package/server/dist/jira-router.js +1 -1
  242. package/server/dist/loop-effect.js +12 -0
  243. package/server/dist/loop-executors.js +92 -22
  244. package/server/dist/loop-run-manager.js +354 -28
  245. package/server/dist/mcp/guide.js +18 -7
  246. package/server/dist/mcp/tools/jira.js +1 -1
  247. package/server/dist/mcp/tools/jobs.js +14 -5
  248. package/server/dist/mcp/tools/rails.js +137 -12
  249. package/server/dist/mcp/tools/specs.js +35 -9
  250. package/server/dist/mcp/tools/types.js +49 -0
  251. package/server/dist/mobile/mobile-ws.js +4 -0
  252. package/server/dist/path-resolver.js +46 -0
  253. package/server/dist/pr-body.js +240 -0
  254. package/server/dist/pr-naming.js +210 -0
  255. package/server/dist/pr-publisher.js +68 -0
  256. package/server/dist/project-registry.js +77 -17
  257. package/server/dist/project-router-jobs.js +53 -13
  258. package/server/dist/project-router-settings.js +33 -0
  259. package/server/dist/project-router-terminals.js +16 -0
  260. package/server/dist/project-router-tickets.js +57 -3
  261. package/server/dist/project-router.js +52 -13
  262. package/server/dist/queue-manager.js +268 -83
  263. package/server/dist/rail-isolated-launch.js +324 -34
  264. package/server/dist/rail-isolation.js +32 -5
  265. package/server/dist/rail-pr-decision.js +519 -0
  266. package/server/dist/rail-pr-delivery.js +75 -0
  267. package/server/dist/rail-pr-store.js +175 -0
  268. package/server/dist/rail-worktrees-store.js +18 -0
  269. package/server/dist/rails-router.js +241 -17
  270. package/server/dist/rails-store.js +78 -1
  271. package/server/dist/setup-prerequisites.js +105 -0
  272. package/server/dist/smash-runner.js +3 -1
  273. package/server/dist/ticket-store.js +7 -3
  274. package/server/dist/workspace-resolution.js +27 -0
  275. package/server/dist/worktree-manager.js +42 -7
  276. package/server/dist/worktree-overlay.js +261 -0
  277. package/client/dist/assets/AgentBrowserCapture-BlGDZahz.js +0 -1
  278. package/client/dist/assets/AgentModeJobsPane-CyNR-9BO.js +0 -1
  279. package/client/dist/assets/AgentsPage-dNsEsY_x.js +0 -86
  280. package/client/dist/assets/AnalyticsPage-BAxmR0HQ.js +0 -1
  281. package/client/dist/assets/CodePage-Crc4BBQN.js +0 -2
  282. package/client/dist/assets/DesktopAnalyticsPage-IXSnbCce.js +0 -1
  283. package/client/dist/assets/DocsDialog-Bc4hx7oW.js +0 -11
  284. package/client/dist/assets/DocsPage-bEU4t9c6.js +0 -11
  285. package/client/dist/assets/IntegrationsPage-wq2CezEL.js +0 -3
  286. package/client/dist/assets/JobDetailPage-BBcPk3j8.js +0 -1
  287. package/client/dist/assets/JobsPage-DXrSPlwa.js +0 -1
  288. package/client/dist/assets/LogViewer-BoYbwvbU.js +0 -16
  289. package/client/dist/assets/LoopBuilderPage-CiUMAuWz.js +0 -7
  290. package/client/dist/assets/LoopsPage-Xrp6W5XW.js +0 -1
  291. package/client/dist/assets/ProjectSettingsDialog-BU98L5JD.js +0 -1
  292. package/client/dist/assets/agent-B7GdHP3Z.js +0 -1
  293. package/client/dist/assets/agent-BHmcgoJf.js +0 -1
  294. package/client/dist/assets/agent-BdY_fii4.js +0 -1
  295. package/client/dist/assets/agent-C32FOi9v.js +0 -1
  296. package/client/dist/assets/agent-CiFQxoaZ2.js +0 -1
  297. package/client/dist/assets/agent-CtAag7V6.js +0 -1
  298. package/client/dist/assets/agent-DE4Mp1fY2.js +0 -1
  299. package/client/dist/assets/agent-DK8qovyG2.js +0 -1
  300. package/client/dist/assets/browser-ZB1afzjZ.js +0 -1
  301. package/client/dist/assets/code-BFxE1Yt62.js +0 -1
  302. package/client/dist/assets/code-BefYOm5Q.js +0 -1
  303. package/client/dist/assets/code-BkXpJt99.js +0 -1
  304. package/client/dist/assets/code-C6Sq7_t8.js +0 -1
  305. package/client/dist/assets/code-CGj3w-2N.js +0 -1
  306. package/client/dist/assets/code-Dfsxc9o82.js +0 -1
  307. package/client/dist/assets/code-Y5urks5s2.js +0 -1
  308. package/client/dist/assets/code-wtcs0ivb.js +0 -1
  309. package/client/dist/assets/dashboard-B8032psZ.js +0 -1
  310. package/client/dist/assets/dashboard-BHGKtxty2.js +0 -1
  311. package/client/dist/assets/dashboard-CXnoUgN22.js +0 -1
  312. package/client/dist/assets/dashboard-Ccyxqy7d.js +0 -1
  313. package/client/dist/assets/dashboard-CoED_41r.js +0 -1
  314. package/client/dist/assets/dashboard-Dc5ZAgMN.js +0 -1
  315. package/client/dist/assets/dashboard-JMY8ueD3.js +0 -1
  316. package/client/dist/assets/dashboard-tkWr1aHD2.js +0 -1
  317. package/client/dist/assets/index-BHPbzyg6.css +0 -2
  318. package/client/dist/assets/index-n2PmJGF6.js +0 -152
  319. package/client/dist/assets/jira-BcZzX9122.js +0 -1
  320. package/client/dist/assets/jira-CTYs7LA12.js +0 -1
  321. package/client/dist/assets/jira-D2nN39e92.js +0 -1
  322. package/client/dist/assets/jira-DJxmIkyr.js +0 -1
  323. package/client/dist/assets/jira-DXMoAKWD.js +0 -1
  324. package/client/dist/assets/jira-IhC1ROIc.js +0 -1
  325. package/client/dist/assets/jira-Iw575fN8.js +0 -1
  326. package/client/dist/assets/jira-kbWZY7jH.js +0 -1
  327. package/client/dist/assets/jobs-BqF79kHz2.js +0 -1
  328. package/client/dist/assets/jobs-C1XM5urS.js +0 -1
  329. package/client/dist/assets/jobs-C5UjG0262.js +0 -1
  330. package/client/dist/assets/jobs-DBfaHTxC.js +0 -1
  331. package/client/dist/assets/jobs-DM4BDPdg.js +0 -1
  332. package/client/dist/assets/jobs-Da5OkZmf2.js +0 -1
  333. package/client/dist/assets/jobs-JJdnuQ03.js +0 -1
  334. package/client/dist/assets/jobs-SI34ML8I.js +0 -1
  335. package/client/dist/assets/loops-BR4FmOv12.js +0 -1
  336. package/client/dist/assets/loops-BgX_uudn.js +0 -1
  337. package/client/dist/assets/loops-Bpl2j2LP.js +0 -1
  338. package/client/dist/assets/loops-CQuuMlyZ.js +0 -1
  339. package/client/dist/assets/loops-DW8hSMdS2.js +0 -1
  340. package/client/dist/assets/loops-Q2muu8hW2.js +0 -1
  341. package/client/dist/assets/loops-q7CNDvfK.js +0 -1
  342. package/client/dist/assets/settings-CY8udi0e.js +0 -1
  343. package/client/dist/assets/setup-CNMdCHHt2.js +0 -1
  344. package/client/dist/assets/setup-Cag4XrbL2.js +0 -1
  345. package/client/dist/assets/setup-D9IHGoWU.js +0 -1
  346. package/client/dist/assets/setup-Dg6Ba3JT.js +0 -1
  347. package/client/dist/assets/setup-DyK36RIW.js +0 -1
  348. package/client/dist/assets/setup-G4ZvDKxX.js +0 -1
  349. package/client/dist/assets/setup-aTlGxuwi2.js +0 -1
  350. package/client/dist/assets/setup-kWsoAeHQ.js +0 -1
  351. package/client/dist/assets/specs-BFSUPa122.js +0 -1
  352. package/client/dist/assets/specs-BMzip1WY2.js +0 -1
  353. package/client/dist/assets/specs-BYeAbIEy.js +0 -1
  354. package/client/dist/assets/specs-C-mtLcXw.js +0 -1
  355. package/client/dist/assets/specs-CAzpvADd2.js +0 -1
  356. package/client/dist/assets/specs-CyRIw_IR.js +0 -1
  357. package/client/dist/assets/specs-DMm7gB_l.js +0 -1
  358. package/client/dist/assets/specs-DuottM0Z.js +0 -1
  359. /package/client/dist/assets/{abap-CpHUwCVK.js → abap-D0E4FfVW.js} +0 -0
  360. /package/client/dist/assets/{activity-DemHQS7l.js → activity--iN4Ad2R2.js} +0 -0
  361. /package/client/dist/assets/{activity-B_71BWg3.js → activity-6hM_ZSg9.js} +0 -0
  362. /package/client/dist/assets/{activity-DHv2V5Oi.js → activity-BZNfOdiS.js} +0 -0
  363. /package/client/dist/assets/{activity-D0rfjQzT2.js → activity-BuVo5sPB.js} +0 -0
  364. /package/client/dist/assets/{activity-BpTTj_PH.js → activity-CIOLxGvh.js} +0 -0
  365. /package/client/dist/assets/{activity-D2e62vbV2.js → activity-D2r2h3SE2.js} +0 -0
  366. /package/client/dist/assets/{activity-Ch-wbr0C2.js → activity-DtxrAUMo2.js} +0 -0
  367. /package/client/dist/assets/{addon-image-Ba-TY3wr.js → addon-image-CwoZj17F.js} +0 -0
  368. /package/client/dist/assets/{addon-ligatures-T4ARLiuu.js → addon-ligatures-CWDrED80.js} +0 -0
  369. /package/client/dist/assets/{addon-webgl-Cd73n8eh.js → addon-webgl-DMbGeI_u.js} +0 -0
  370. /package/client/dist/assets/{addspec-xwRX_Pnf.js → addspec-BMtLZLW62.js} +0 -0
  371. /package/client/dist/assets/{addspec-l_zU5gla.js → addspec-CP0HRuxY.js} +0 -0
  372. /package/client/dist/assets/{addspec-Dio-H5z0.js → addspec-CRuvWn8d.js} +0 -0
  373. /package/client/dist/assets/{addspec-D6L4ZteP.js → addspec-D-JLDsUV.js} +0 -0
  374. /package/client/dist/assets/{addspec-CrEm6Fzr2.js → addspec-DfhDbg5c.js} +0 -0
  375. /package/client/dist/assets/{addspec-B6Ns8KU02.js → addspec-bsNDdqRm2.js} +0 -0
  376. /package/client/dist/assets/{addspec-qGyH7MHy2.js → addspec-mgPOt5q02.js} +0 -0
  377. /package/client/dist/assets/{agents-OzxCLVW1.js → agents-78bTZGZh.js} +0 -0
  378. /package/client/dist/assets/{agents-hv3sqmPm2.js → agents-BLhWCmDS2.js} +0 -0
  379. /package/client/dist/assets/{agents-CHgCudUV.js → agents-BUdEi3-N.js} +0 -0
  380. /package/client/dist/assets/{agents-Dumx4JiM2.js → agents-BpoUaoW92.js} +0 -0
  381. /package/client/dist/assets/{agents-CnaPeSyw.js → agents-CWo-KyAB.js} +0 -0
  382. /package/client/dist/assets/{agents-Xh-zYHUx2.js → agents-DDtCJ5M02.js} +0 -0
  383. /package/client/dist/assets/{agents-DuhLEaQ_.js → agents-bvyRLczL.js} +0 -0
  384. /package/client/dist/assets/{agentstudio-CCthUdzR.js → agentstudio-BMQxc_bz.js} +0 -0
  385. /package/client/dist/assets/{agentstudio-CcH8Ckql2.js → agentstudio-COZriimI2.js} +0 -0
  386. /package/client/dist/assets/{agentstudio-Bo91kfUd2.js → agentstudio-CWgXG5W52.js} +0 -0
  387. /package/client/dist/assets/{agentstudio-VJOa_NVO.js → agentstudio-C_Jq8Tl4.js} +0 -0
  388. /package/client/dist/assets/{agentstudio-BIxikDf_.js → agentstudio-Dtq3dGYk.js} +0 -0
  389. /package/client/dist/assets/{agentstudio-Bz8cP8_c.js → agentstudio-jKMTdT70.js} +0 -0
  390. /package/client/dist/assets/{agentstudio-DARgYg5Z2.js → agentstudio-sI27TpBu2.js} +0 -0
  391. /package/client/dist/assets/{aiedit-5ZXN4cep2.js → aiedit-6CHdb_iv2.js} +0 -0
  392. /package/client/dist/assets/{aiedit-B7gAJZVC.js → aiedit-B03pD_Na.js} +0 -0
  393. /package/client/dist/assets/{aiedit-D92V-kUW.js → aiedit-BtRqRxML.js} +0 -0
  394. /package/client/dist/assets/{aiedit-D9ualLVJ.js → aiedit-eMN4eQPF.js} +0 -0
  395. /package/client/dist/assets/{aiedit-h48tJU0V2.js → aiedit-hknZlly82.js} +0 -0
  396. /package/client/dist/assets/{aiedit-xkA_mR2a2.js → aiedit-igmw-ZoZ2.js} +0 -0
  397. /package/client/dist/assets/{aiedit-7B2dvCv-.js → aiedit-pc5JDUq1.js} +0 -0
  398. /package/client/dist/assets/{analytics-slx4X1mu2.js → analytics-BWMUZ2Pq2.js} +0 -0
  399. /package/client/dist/assets/{analytics-uRNP6yAJ.js → analytics-Bj-SmKHa.js} +0 -0
  400. /package/client/dist/assets/{analytics-WF1I49ln.js → analytics-C5dpiS0o.js} +0 -0
  401. /package/client/dist/assets/{analytics-CBvaxOId.js → analytics-CCprAqk3.js} +0 -0
  402. /package/client/dist/assets/{analytics-BakymH7Z2.js → analytics-CR1TJqUi2.js} +0 -0
  403. /package/client/dist/assets/{analytics-B7bPj6u_2.js → analytics-DfNdXR0y2.js} +0 -0
  404. /package/client/dist/assets/{analytics-DZ74aQ54.js → analytics-rmHuJv0V.js} +0 -0
  405. /package/client/dist/assets/{apex-DlD7oJX6.js → apex-D_X_8J4d.js} +0 -0
  406. /package/client/dist/assets/{atom-one-dark-BrRN8wBy.js → atom-one-dark-BMDPFwRZ.js} +0 -0
  407. /package/client/dist/assets/{attachments-C11tOKZ_.js → attachments-BgBNSqQd.js} +0 -0
  408. /package/client/dist/assets/{attachments-Bnbyj2PN.js → attachments-BjyMmrwE.js} +0 -0
  409. /package/client/dist/assets/{attachments-CIeLa8l12.js → attachments-C9GTTJsx2.js} +0 -0
  410. /package/client/dist/assets/{attachments-DslHfa-L.js → attachments-DCZOL1RU.js} +0 -0
  411. /package/client/dist/assets/{attachments-C-gyrCOb.js → attachments-DL-bPy9E.js} +0 -0
  412. /package/client/dist/assets/{attachments-Cxrs0pyL2.js → attachments-DPCmkFZu2.js} +0 -0
  413. /package/client/dist/assets/{attachments-TTPsc0a52.js → attachments-rNn1ekRy2.js} +0 -0
  414. /package/client/dist/assets/{azcli-CmXFAbc-.js → azcli-PZLnZ3jH.js} +0 -0
  415. /package/client/dist/assets/{bat-DdNJq4hH.js → bat-KlBOxpO4.js} +0 -0
  416. /package/client/dist/assets/{bicep-Bppz7WOA.js → bicep-CgG9oF3V.js} +0 -0
  417. /package/client/dist/assets/{cameligo-0MRMdSmg.js → cameligo-6R45j6Ph.js} +0 -0
  418. /package/client/dist/assets/{chat-BvHrebKC2.js → chat-BgL3zv6x2.js} +0 -0
  419. /package/client/dist/assets/{chat-CZyiLJvQ.js → chat-Bh3NdgJs.js} +0 -0
  420. /package/client/dist/assets/{chat-DKYP7NnC.js → chat-Bom6bqK3.js} +0 -0
  421. /package/client/dist/assets/{chat-5mdg_YIc2.js → chat-DdwZjT8K2.js} +0 -0
  422. /package/client/dist/assets/{chat-wkTIy9rX.js → chat-Dnwg-NpQ.js} +0 -0
  423. /package/client/dist/assets/{chat-BpYxnkr4.js → chat-DsbwJhus.js} +0 -0
  424. /package/client/dist/assets/{chat-BGax2nV62.js → chat-vylxqR0P2.js} +0 -0
  425. /package/client/dist/assets/{clojure-B5dKj863.js → clojure-CLAAMO7J.js} +0 -0
  426. /package/client/dist/assets/{clsx-1dnHRn8W.js → clsx-CNmW0Nip.js} +0 -0
  427. /package/client/dist/assets/{coffee-DSbWjzk7.js → coffee-AruSygo-.js} +0 -0
  428. /package/client/dist/assets/{commands-uz_uKT242.js → commands-C4Y3C-PF2.js} +0 -0
  429. /package/client/dist/assets/{commands-Bb7MnPqn2.js → commands-CSDs9q_2.js} +0 -0
  430. /package/client/dist/assets/{commands-C_7zZwJf.js → commands-DkU0qliq.js} +0 -0
  431. /package/client/dist/assets/{commands-D_6B8lfU.js → commands-JWMfGDmr.js} +0 -0
  432. /package/client/dist/assets/{commands-DBc5llLi2.js → commands-RHOchN4n2.js} +0 -0
  433. /package/client/dist/assets/{commands-CQkdthjF.js → commands-u-4eEHCN.js} +0 -0
  434. /package/client/dist/assets/{commands-DhZNhSbl.js → commands-xHDDGfcP2.js} +0 -0
  435. /package/client/dist/assets/{cpp-SBF8SAh9.js → cpp-DEE5r4Pw.js} +0 -0
  436. /package/client/dist/assets/{csharp-Lzuq_1t-.js → csharp-BVXJUvbK.js} +0 -0
  437. /package/client/dist/assets/{csp-BEzxZqi1.js → csp-cXOF0JoV.js} +0 -0
  438. /package/client/dist/assets/{css-C3D3PKln.js → css-C_zQuAoy.js} +0 -0
  439. /package/client/dist/assets/{cypher-CQ3dEPmv.js → cypher-t95m_Q-O.js} +0 -0
  440. /package/client/dist/assets/{dart-DCPmxolI.js → dart-B4r1Tg-e.js} +0 -0
  441. /package/client/dist/assets/{dockerfile-B_2_aaTO.js → dockerfile-6mt7zHQw.js} +0 -0
  442. /package/client/dist/assets/{ecl-rADUeXsV.js → ecl-DEY_Fz_Q.js} +0 -0
  443. /package/client/dist/assets/{editor.api2-T7u8kQWG.js → editor.api2-C3B0tp2x.js} +0 -0
  444. /package/client/dist/assets/{elixir-DOd-TuJO.js → elixir-R6-q1c5t.js} +0 -0
  445. /package/client/dist/assets/{explore-BHEhNekP2.js → explore-B7fblXBb2.js} +0 -0
  446. /package/client/dist/assets/{explore-DAsroA482.js → explore-BHtEpoNN2.js} +0 -0
  447. /package/client/dist/assets/{explore-UwHHj2ux.js → explore-C0k8HrkN.js} +0 -0
  448. /package/client/dist/assets/{explore-DaXiW9-6.js → explore-CNBzrEPS.js} +0 -0
  449. /package/client/dist/assets/{explore-CWlAXx0f2.js → explore-D_mWBYCS2.js} +0 -0
  450. /package/client/dist/assets/{explore-DG1CtYqT.js → explore-Dahc1lOx.js} +0 -0
  451. /package/client/dist/assets/{explore-DMSGAnhK.js → explore-UvW1jEMa.js} +0 -0
  452. /package/client/dist/assets/{flow9-Bf7zg_j0.js → flow9-CNQvHBOt.js} +0 -0
  453. /package/client/dist/assets/{format-command-BHymDa4r.js → format-command-CuWuRvka.js} +0 -0
  454. /package/client/dist/assets/{fsharp-BqROZjbA.js → fsharp-vPZkFXwv.js} +0 -0
  455. /package/client/dist/assets/{go-oQTP5uLe.js → go-KUzBMYJ_.js} +0 -0
  456. /package/client/dist/assets/{graphql-CSHfTU3q.js → graphql-C3W0rCsD.js} +0 -0
  457. /package/client/dist/assets/{hcl-CeG-RoFJ.js → hcl-BOOMFSNX.js} +0 -0
  458. /package/client/dist/assets/{ini-B2Dv4ohc.js → ini-CFat1WJr.js} +0 -0
  459. /package/client/dist/assets/{integrations-CAF21FbQ.js → integrations-4KZnYECp.js} +0 -0
  460. /package/client/dist/assets/{integrations-CHCgning2.js → integrations-7W266oqF2.js} +0 -0
  461. /package/client/dist/assets/{integrations-B-JVE1_D.js → integrations-BNuauK3o.js} +0 -0
  462. /package/client/dist/assets/{integrations-BAujIDoE.js → integrations-CHy8tnpV.js} +0 -0
  463. /package/client/dist/assets/{integrations-DS5FFMes.js → integrations-Cl_wD5AI.js} +0 -0
  464. /package/client/dist/assets/{integrations-axZN4--n2.js → integrations-Cy8nZ_dv2.js} +0 -0
  465. /package/client/dist/assets/{integrations-CtsOpq2D2.js → integrations-zMqY4VU12.js} +0 -0
  466. /package/client/dist/assets/{java-aUDDeufb.js → java-Dee-CNAM.js} +0 -0
  467. /package/client/dist/assets/{julia-C5LbruO5.js → julia-CGNlLYuU.js} +0 -0
  468. /package/client/dist/assets/{kotlin-C6mOuSKk.js → kotlin-CY7lhknJ.js} +0 -0
  469. /package/client/dist/assets/{less-D5qC3caW.js → less-D0KN7hfJ.js} +0 -0
  470. /package/client/dist/assets/{lexon-Dr2La-fj.js → lexon-CuRJufPs.js} +0 -0
  471. /package/client/dist/assets/{lua-Zy6u5z6Z.js → lua-DHvH62Zf.js} +0 -0
  472. /package/client/dist/assets/{m3-C7XHeDz_.js → m3-tlthQ8Fo.js} +0 -0
  473. /package/client/dist/assets/{markdown-PiF7r-2h.js → markdown-Dbx1LgUZ.js} +0 -0
  474. /package/client/dist/assets/{mcp-B_nWlxZa2.js → mcp-CjVKXAhD2.js} +0 -0
  475. /package/client/dist/assets/{mcp-B8omp_Cd.js → mcp-Dcl-XxkR.js} +0 -0
  476. /package/client/dist/assets/{mcp-DTCCrYHz2.js → mcp-DtbxuH3V2.js} +0 -0
  477. /package/client/dist/assets/{mcp-DytBbASZ.js → mcp-H-gnQUdN.js} +0 -0
  478. /package/client/dist/assets/{mcp-D_oPS6Zc.js → mcp-N1nzp8oL.js} +0 -0
  479. /package/client/dist/assets/{mcp-Cb2jtHP72.js → mcp-XJNRfxVp2.js} +0 -0
  480. /package/client/dist/assets/{mcp-DPqm2C8-.js → mcp-sRmWE8WJ.js} +0 -0
  481. /package/client/dist/assets/{mips-nn07GiyE.js → mips-D_O3IUz_.js} +0 -0
  482. /package/client/dist/assets/{msdax-DaKFVMST.js → msdax-C_ZmCnRt.js} +0 -0
  483. /package/client/dist/assets/{mysql-C6d6xrbU.js → mysql-C-dCEYSX.js} +0 -0
  484. /package/client/dist/assets/{nav-Cibp2KWF.js → nav-40HzpIFb.js} +0 -0
  485. /package/client/dist/assets/{nav-DtTnF9xd.js → nav-8yPhBn00.js} +0 -0
  486. /package/client/dist/assets/{nav-Danf5sRf2.js → nav-B6PkGfTk2.js} +0 -0
  487. /package/client/dist/assets/{nav-Bqhyfbcj2.js → nav-BHqMLrS72.js} +0 -0
  488. /package/client/dist/assets/{nav-CQb9y1km.js → nav-CGy4yx3C.js} +0 -0
  489. /package/client/dist/assets/{nav-BAsYcqdw2.js → nav-CXEDcRdv2.js} +0 -0
  490. /package/client/dist/assets/{nav-BRrNlZkr.js → nav-EI_OhEAo.js} +0 -0
  491. /package/client/dist/assets/{objective-c-B6KMtI-k.js → objective-c-DZY9Aqxd.js} +0 -0
  492. /package/client/dist/assets/{pascal-DYr8MPE7.js → pascal-BVHLXoor.js} +0 -0
  493. /package/client/dist/assets/{pascaligo-B3pd-jJ_.js → pascaligo-XdG_6u3k.js} +0 -0
  494. /package/client/dist/assets/{perl-z2xUzoaL.js → perl-b9QV0BcD.js} +0 -0
  495. /package/client/dist/assets/{pgsql-DUvT-09-.js → pgsql-Du5FDOgT.js} +0 -0
  496. /package/client/dist/assets/{php-CGyOmJfy.js → php-WJD0z2Z_.js} +0 -0
  497. /package/client/dist/assets/{pla-CMqgvyD0.js → pla-CbciTf2w.js} +0 -0
  498. /package/client/dist/assets/{postiats-Dx5LUn4Z.js → postiats-C1QxmvVq.js} +0 -0
  499. /package/client/dist/assets/{powerquery-DazYxvJ6.js → powerquery-BEYDhPLZ.js} +0 -0
  500. /package/client/dist/assets/{powershell-B3nwlDka.js → powershell-CfaYw4XL.js} +0 -0
  501. /package/client/dist/assets/{protobuf-BGuu2u2s.js → protobuf-pwZEDOYa.js} +0 -0
  502. /package/client/dist/assets/{pug-Dbte1MXA.js → pug-5ftqSPVe.js} +0 -0
  503. /package/client/dist/assets/{qsharp-DJLwBOvG.js → qsharp-uI6qZMq4.js} +0 -0
  504. /package/client/dist/assets/{r-DmGBRSHj.js → r-BK54P1EG.js} +0 -0
  505. /package/client/dist/assets/{redis-VvUYn0a4.js → redis-DI0yd7kN.js} +0 -0
  506. /package/client/dist/assets/{redshift-6GdDrxg3.js → redshift-Dov26eyI.js} +0 -0
  507. /package/client/dist/assets/{restructuredtext-CfAB8aRU.js → restructuredtext-QqJ_1dC-.js} +0 -0
  508. /package/client/dist/assets/{ruby-CIYK6MXY.js → ruby-5WjveeVb.js} +0 -0
  509. /package/client/dist/assets/{rust-CTHZfjj9.js → rust-BzVSfqFH.js} +0 -0
  510. /package/client/dist/assets/{sb-CkKTdkz_.js → sb-DMIUfT-3.js} +0 -0
  511. /package/client/dist/assets/{scala-Bx-Wr9TM.js → scala-CSKA7lqt.js} +0 -0
  512. /package/client/dist/assets/{scheme-Dcfi6f83.js → scheme-CojOP2Qc.js} +0 -0
  513. /package/client/dist/assets/{scss-ByL-7PFQ.js → scss-DoBZGJG6.js} +0 -0
  514. /package/client/dist/assets/{shell-Csnb9Yqd.js → shell-YOaE4udl.js} +0 -0
  515. /package/client/dist/assets/{solidity-Dbw5-0QP.js → solidity-l3jSyVLu.js} +0 -0
  516. /package/client/dist/assets/{sophia-ZQ3saZQx.js → sophia-BhSGTaQJ.js} +0 -0
  517. /package/client/dist/assets/{sparql-BEtOel8u.js → sparql-qhk6QD9w.js} +0 -0
  518. /package/client/dist/assets/{sql-DGPDbzB7.js → sql-DoO3y21-.js} +0 -0
  519. /package/client/dist/assets/{st-GeW2MOgh.js → st-ChZAY8oG.js} +0 -0
  520. /package/client/dist/assets/{swift-BVYTN8jq.js → swift-D290Tr7_.js} +0 -0
  521. /package/client/dist/assets/{systemverilog-Deg2a8Lr.js → systemverilog-DsxzgJ-o.js} +0 -0
  522. /package/client/dist/assets/{tcl-6DnLmROF.js → tcl-BKDUHAAR.js} +0 -0
  523. /package/client/dist/assets/{terminal-CDiOAmBd2.js → terminal-BRm03iFA2.js} +0 -0
  524. /package/client/dist/assets/{terminal-CJN-mQMc.js → terminal-De2Brd23.js} +0 -0
  525. /package/client/dist/assets/{terminal-CYB4TiAd.js → terminal-DxQWCqSD2.js} +0 -0
  526. /package/client/dist/assets/{terminal-DsaDTq5N2.js → terminal-WSAvHXoU.js} +0 -0
  527. /package/client/dist/assets/{terminal-DTQ_dPqi2.js → terminal-Z7KsDM_n.js} +0 -0
  528. /package/client/dist/assets/{terminal-58ReNaya.js → terminal-cqfd3EDV.js} +0 -0
  529. /package/client/dist/assets/{terminal-DawP8xNL.js → terminal-xGbCZJHg.js} +0 -0
  530. /package/client/dist/assets/{tickets-DoRTUYRT.js → tickets-B7zT4IRf.js} +0 -0
  531. /package/client/dist/assets/{tickets-DBfFePwk2.js → tickets-BoXom7l8.js} +0 -0
  532. /package/client/dist/assets/{tickets-DvohTziT2.js → tickets-C3b8cHhd2.js} +0 -0
  533. /package/client/dist/assets/{tickets-Da15iaRw.js → tickets-CFXnJsYF.js} +0 -0
  534. /package/client/dist/assets/{tickets-CujsZvkf.js → tickets-CWYFvx1W2.js} +0 -0
  535. /package/client/dist/assets/{tickets-Df6pee-O2.js → tickets-DTHo9c3C.js} +0 -0
  536. /package/client/dist/assets/{tickets-CNvIilmP.js → tickets-SuX_HkK4.js} +0 -0
  537. /package/client/dist/assets/{twig-XbbXW9Yz.js → twig-UpZQaM8G.js} +0 -0
  538. /package/client/dist/assets/{typespec-CRlV8GhI.js → typespec-DzaKvN8i.js} +0 -0
  539. /package/client/dist/assets/{vb-BHE2izPH.js → vb-CZpbb7tk.js} +0 -0
  540. /package/client/dist/assets/{wgsl-Bf5vkfmY.js → wgsl-CNt3OIvl.js} +0 -0
@@ -0,0 +1,367 @@
1
+ # Safe PR review flow (ask-first) — as-built record
2
+
3
+ > Successor to the shipped `safe-pr-workflow` (#486–#500). That change made every repo-mutating
4
+ > rail isolate in worktrees off the integration branch and **auto-deliver** a draft PR at settle,
5
+ > surfaced by a one-shot toast. This change replaces the auto-delivery half with an explicit,
6
+ > durable, **ask-first** flow: at settle the work stays on its isolated branches and the user
7
+ > decides — from the dashboard rail row or from the launching agent-chat conversation — whether a
8
+ > PR is created at all. specrails remains a PR producer, never a merge authority.
9
+
10
+ ## The single source of truth
11
+
12
+ One durable row per rail **launch** in `rail_pr_deliveries` (per-project `jobs.sqlite`,
13
+ migration 36; CRUD in `server/rail-pr-store.ts`). Grain is the launch, not the ticket: a delivery
14
+ is one PR for the whole launch, keyed internally by `rail_key = ${railIndex}-${loopId}`; the row
15
+ is keyed by uuid because a rail slot can be relaunched.
16
+
17
+ Columns beyond the obvious: `ticket_ids` (JSON `number[]`), `base_branch` (the resolved
18
+ integration branch — the "against `<base>`" in the question), `branches` (JSON
19
+ `DeliverBranchRecord[]` — per-unit `{ticketId, branch, succeeded}` captured at build-settle),
20
+ `worktree_ids` (JSON `string[]` of `rail_worktrees` ledger ids), `loop_name` (PR title/body),
21
+ `pr_url`/`pr_number`, `pr_state` (`none | local-only | pushed | pr-created` — the pr-publisher
22
+ degradation ladder, independent of `decision`), `origin_surface` (`dashboard | agent-chat`),
23
+ `origin_conversation_id` (soft cross-DB reference to `agent_conversations.id` in
24
+ `desktop.sqlite`; no FK is possible across SQLite files).
25
+
26
+ The `branches` + `worktree_ids` columns exist because PR creation is **deferred**: nothing about
27
+ the settle survives in memory by the time the user clicks, so `create-pr` and `discard`
28
+ reconstruct all their inputs from the row.
29
+
30
+ ## State machine (`decision`)
31
+
32
+ ```
33
+ building ──(settle, ≥1 succeeded unit)──▶ on_review [patch branches/worktree_ids]
34
+ building ──(settle, 0 succeeded)────────▶ discarded (terminal auto-close; per-run settle already reverted tickets)
35
+ on_review | pr_failed ──[Create PR]────▶ pr_draft (delivered) | pr_failed (assembly-failed / throw)
36
+ pr_draft (pr_url != null) ──[Publish]──▶ pr_ready (gh pr ready — opens the draft for team review)
37
+ pr_draft | pr_ready ──[Check merge]────▶ merged (gh pr view reports MERGED; else 200 no-op)
38
+ on_review | pr_draft | pr_ready | pr_failed ──[Discard]─▶ discarded
39
+ ```
40
+
41
+ `merged` / `discarded` are terminal. A **degraded** draft (`pr_state` `pushed`/`local-only`,
42
+ `pr_url = null`) offers no Publish — only retry (`create-pr` is legal from a `pr_draft` whose
43
+ `pr_url` is null) or Discard. Every transition is the compare-and-set
44
+ `transitionDecision(db, id, expected, next, patch)` — one atomic
45
+ `UPDATE … WHERE id = ? AND decision = ?` — so two surfaces racing on the same delivery cannot
46
+ both win; the loser's `false` return maps to **409 `stale_decision`**.
47
+
48
+ ## Launch wiring (`server/rail-isolated-launch.ts`)
49
+
50
+ - `prMode = isRailPrDeliveryEnabled()` is captured **once at launch entry** — a mid-flight env
51
+ flip can never split one launch across the two delivery paths.
52
+ - In PR mode the row is INSERTed **up front** (`decision='building'`) so the origin link is
53
+ persisted before any await can drop it and late-joining clients hydrate mid-build via
54
+ `GET /rails`. Worktree-allocation failure transitions the row to `discarded` (kept for audit,
55
+ never deleted) so a wedged `building` row can never block the slot.
56
+ - Isolation units: `scope='per-ticket'` → one worktree/run per ticket; `scope='all'`
57
+ (implement/batch — one pipeline invocation covers all tickets) → **one** worktree/run covering
58
+ every ticket. `isolationApplies` (`server/rail-isolation.ts`) isolates per-ticket rails always
59
+ and `all`-scoped rails **only when PR delivery is on** (kill-switch off ⇒ byte-identical
60
+ legacy shared-cwd).
61
+ - Per-run settle: `ctx.onLoopRunFinished(runId, outcome, { ticketCompletionStatus })` —
62
+ `'on_review'` in PR mode, `'done'` otherwise (`applyJobOutcomeToTickets` gains the analogous
63
+ `{ completedStatus }` option; explicit `'done'` / kill-switch off is byte-identical legacy).
64
+ When the caller passes NO opts (shared-cwd rail runs, standalone loop runs,
65
+ isolation-unavailable fallbacks) the default now derives from `isRailPrDeliveryEnabled()` —
66
+ read once per settle and reused for the Jira split, so one settle can never split across the
67
+ two paths (universal ask-first; the explicit isolated-rail opts are idempotent with it).
68
+ Failures ignore the field (revert `in_progress → todo` as always). In PR mode the completed
69
+ path calls `jiraSyncManager.onRailReview` instead of the done-flavoured `onJobOutcome`.
70
+ - All-settle in PR mode: patch `branches` + `worktree_ids`, transition `building →`
71
+ `on_review` (≥1 succeeded) or `discarded` (0 succeeded), broadcast, and — when
72
+ `origin_conversation_id` is set — post the inline decision card into the conversation.
73
+ The legacy merge-back **never runs** in PR mode. Kill-switch off: no row, no `on_review`,
74
+ legacy local merge-back exactly as before.
75
+
76
+ ## Per-run worktree overlay (`server/worktree-overlay.ts`)
77
+
78
+ `git worktree add` materializes only TRACKED files — so a RELOCATED project's framework
79
+ surface (`.claude/commands/specrails/*.md`, sr-* agents, skills, rules, `.mcp.json`, the
80
+ seeded instruction file), which lives in `~/.specrails/projects/<slug>/workspace/`, was
81
+ absent from the worktree: the claude CLI reported `Unknown command: /specrails:implement`
82
+ and the loop "succeeded" through verify/fix without implementing (live evidence: run
83
+ 01f41203). Legacy projects have the sibling gap for their UNTRACKED on-disk `.claude`
84
+ entries. Each allocated worktree therefore gets `applyWorktreeOverlay(...)` at launch:
85
+
86
+ - **Source root** = the project's effective artifact root, resolved once per launch via
87
+ `resolveProjectExecution`: the workspace when relocated, else the repo itself.
88
+ - **Merge-only symlinks** under `<worktree>/<providerDir>/`: dir links where a dir is
89
+ wholly absent, per-file/per-child where the checkout is partially present; checkout
90
+ content is NEVER overwritten. `agent-memory` is linked (all runs share memory — the
91
+ pre-isolation shared-cwd semantics, deliberate). The providerDir root and the source's
92
+ `worktrees/` entry are never linked (nested pipeline worktrees stay local). `.mcp.json`
93
+ and the instruction file (CLAUDE.md/AGENTS.md/GEMINI.md per provider) are COPIED when
94
+ the checkout lacks them. Windows: junction → dereferencing-copy fallback.
95
+ - **Never on the PR**: every overlay-owned path lands in a worktree-local manifest
96
+ (`.sr-rail-overlay.json`, unioned across passes so a RESUMED worktree keeps prior
97
+ entries claimed) and is excluded from `commitWorktree`'s stage via `:(exclude)`
98
+ pathspecs. Excluded paths are untracked by construction, so no real work can be lost;
99
+ a no-op overlay keeps the byte-identical `git add -A`. Worktree removal (`git worktree
100
+ remove --force`) deletes the symlinks as entries without following them.
101
+ - **Degrade, don't abort**: entry-level failures produce `warnings` — surfaced as a
102
+ server log line plus the project-scoped `rail.overlay_degraded` WS event — and the
103
+ spawn proceeds (a partial surface beats an aborted rail). `applyWorktreeOverlay` never
104
+ throws.
105
+ - **Env correctness**: `SPECRAILS_REPO_DIR` = the WORKTREE per run (loop-executors
106
+ `aiStepEnv` — writes/git land in the worktree, never the live repo), while the
107
+ relocated workspace artifact indirection (`SPECRAILS_TICKETS_PATH` /
108
+ `SPECRAILS_BACKLOG_CONFIG_PATH` / `SPECRAILS_PROFILES_DIR` / `SPECRAILS_STATE_DIR` /
109
+ `SPECRAILS_WORKSPACE_DIR`) rides the executors' lazily-resolved base env
110
+ (`workspace-resolution.ts` `resolveLoopBaseEnv`, wired per project in
111
+ `project-registry.ts`) — the worktree's cwd-relative `${ENV:-legacy}` defaults would
112
+ otherwise resolve to nothing. Legacy projects keep `process.env` untouched.
113
+
114
+ ## The one decision endpoint
115
+
116
+ `POST /rails/pr-decision` `{ prDeliveryId, action, expectedDecision }` (replaces the stateless
117
+ v1 `POST /rails/pr-review`). The route validates and delegates to
118
+ `server/rail-pr-decision.ts` `executePrDecision` (deps injected — db/git/exec/broadcast/jira/
119
+ agent-chat — so the whole matrix unit-tests without git/gh/network).
120
+
121
+ - **create-pr** — deferred `deliverRailAsPr` (`server/rail-pr-delivery.ts`: 1 unit → its
122
+ branch; N → assembled onto the conventional batch branch off the integration branch, one PR
123
+ covering every ticket). The PR **title and canonical body are composed here** (see "Branch
124
+ naming & PR content" below) from the ticket store + `jira_links` + the branch diffs — all
125
+ failure-tolerant. Retry hazard handled first: a prior degraded delivery leaves the batch
126
+ branch behind and `deliverRailAsPr` assembles with `worktree add -b`, so the stale batch branch
127
+ is defensively `-D`'d (never the integration branch); inside `deliverRailAsPr` the batch name
128
+ additionally collide-suffixes `-2`… against the live branch listing. Delivered → `pr_draft`
129
+ (+`pr_url`/`pr_number` when `pr-created`; null when degraded); assembly-failed or a thrown
130
+ guardrail → `pr_failed` (retryable). Tickets stay `on_review` — a draft PR still awaits the
131
+ merge.
132
+ - **publish** — `gh pr ready <url>` → `pr_ready` (the draft opens for the team's normal review).
133
+ Requires a real `pr_url`.
134
+ - **discard** — best-effort `gh pr close <url> --delete-branch`; remove the launch's worktrees
135
+ (ledger rows closed as `failed`); delete every referenced branch (per-unit sources, assembled
136
+ head, and the possibly-stale batch branch recomputed from the same ticket data create-pr names
137
+ it from — the integration branch is NEVER deleted); → `discarded`; revert
138
+ still-`on_review` tickets → `todo` (a manually re-triaged spec is respected) + Jira
139
+ `onRailDiscard`.
140
+ - **poll-merge** — on-demand `gh pr view <url> --json state,mergedAt`; `MERGED` → `merged` +
141
+ tickets → `done` + Jira `onRailMerged` (with a "PR merged: `<url>`" comment); anything else is
142
+ an observation-only 200. There is no background poller (loopback server, no webhooks) —
143
+ detection is click-driven.
144
+
145
+ `gh` failures return 502 `gh_failed` with **no transition**. Illegal action for the current
146
+ state → 409 (`stale_decision` + `reason: 'illegal_action'`).
147
+
148
+ ## Branch naming & PR content (pr-naming.ts / pr-body.ts)
149
+
150
+ Conventional, open-source-style naming for everything the user sees on GitHub. All pure string
151
+ logic in `server/pr-naming.ts` (branches + titles) and `server/pr-body.ts` (canonical body +
152
+ diff collection), fully unit-tested.
153
+
154
+ - **`<ref>`** — the ticket's Jira key when Jira-linked, else the local ticket number. **JIRA
155
+ ALWAYS PREVAILS**, resolved per ticket at naming/body time with no HTTP: the authoritative
156
+ `jira_links` row (`getLinkByLocalId`, tombstoned links ignored) wins over the ticket's
157
+ `jira_key` field; a missing link degrades to the local id.
158
+ - **`<type>` heuristic** (labels checked before the title; first match wins): bug|bugfix|fix|
159
+ hotfix → `fix`; chore|refactor|cleanup → `chore`; docs|documentation → `docs`; else `feat`.
160
+ Batch type = `feat` unless ALL tickets map to the same other type.
161
+ - **Per-unit branch** — `<type>/<ref>-<kebab-title>` (e.g. `feat/SKILLS-101-add-dark-mode`,
162
+ `fix/37-crash-on-save`). The kebab is ascii-folded (NFKD, diacritics stripped, `ß`→`ss`),
163
+ capped ~40 chars at a word boundary, never a leading/trailing dash; emoji-only titles fold to
164
+ nothing (`<type>/<ref>`). Every generated name passes `isValidBranchName`.
165
+ - **Batch branch** (N>1 assembled delivery) — `<type>/<primary-ref>-batch-<n>-tickets`.
166
+ - **Collisions** — bounded suffixing `-2`, `-3`… (20 attempts). At worktree allocation
167
+ (`rail-isolated-launch`) a branch that a PRIOR rail run allocated for the SAME ticket (per the
168
+ `rail_worktrees` ledger) is **resumed**, not suffixed — preserving the stop/relaunch resume
169
+ semantics; exhaustion falls back to the legacy `sr/<slug>/ticket-<id>`. The **integration
170
+ branch is never used** (reserved in the resolver + asserted in tests). `createWorktree` stays
171
+ generic: an optional preferred `branch` input with the legacy fallback when absent.
172
+ - **PR title** — `[<ref>]<type> - <change>` (e.g. `[SKILLS-101]feat - darkmode added`); the
173
+ `<change>` clause is the ticket title, control-stripped, trailing-period-free and
174
+ first-letter-lowercased unless it reads as an acronym/CamelCase. Batch:
175
+ `[<primary-ref> +<n-1>]<type> - <loop summary>` (e.g. `[SKILLS-101 +2]feat - implement batch
176
+ of 3 tickets`). The per-ticket type matches its branch type.
177
+ - **PR body** (`buildCanonicalPrBody`, composed at create-pr time) — one summary paragraph
178
+ (loop, N tickets, base branch), then per ticket `## <ref> — <title>` (Jira key verbatim,
179
+ `#<id>` for local) with **Problem** (the spec's leading narrative / problem-ish heading;
180
+ omitted when missing), **Solution** (a tight digest of the solution-ish sections; overflow in
181
+ a collapsed `<details>` block — never a full spec dump; the Contract Layer appendix is
182
+ stripped first), and **Tests** (HONEST: touched `*.test.*`/`*.spec.*`/`__tests__/` files from
183
+ `git diff --name-status <base>...<branch>`; "No test files changed in this diff." when none;
184
+ an explicit unavailable note when the diff failed — never invented). A final `## Changes`
185
+ section lists the per-branch diffstat (`git diff --shortstat`), omitted entirely when git
186
+ fails — diff problems can only degrade the body, NEVER block PR creation. The v1
187
+ `buildBatchPrBody` and its "_Draft PR produced by specrails — the engineer owns the merge._"
188
+ footer are gone.
189
+
190
+ ## The sync contract (two surfaces, zero desync)
191
+
192
+ Neither surface holds authoritative state; both render the last snapshot they received and POST
193
+ the same endpoint with the `expectedDecision` they rendered.
194
+
195
+ - **Durable WS event `rail.pr_state`** (project-scoped, full snapshot — replaces the retired
196
+ one-shot `rail.pr_delivered`): broadcast at row INSERT (`building`), build-settle, and every
197
+ decision mutation. **`GET /rails`** returns `prDeliveries: Record<railIndex, snapshot>`
198
+ (newest non-terminal row per slot) for late-join hydration.
199
+ - **Option A — dashboard.** `client/src/context/RailPrDecisionContext.tsx` (registerHandler on
200
+ the shared socket + `GET /rails` seed) feeds `RailPrDecisionStrip` on `RailRow` (both density
201
+ branches): on_review → Create PR / Discard; pr_draft → Open PR + Publish / Discard (degraded →
202
+ retry); pr_ready → Check merge / Discard; pr_failed → Retry / Discard. Buttons disable in
203
+ flight and reconcile to the next broadcast; Discard confirms first.
204
+ - **Option B — agent chat.** When the row carries `origin_conversation_id`, settle posts a
205
+ **persisted inline card**: a `'system'`-role `agent_messages` row (role is unconstrained TEXT —
206
+ no migration; TS unions widened) whose content is the `PrDecisionCardEnvelope` JSON.
207
+ `AgentChatManager.postPrDecisionCard` / `updatePrDecisionCard` (update-in-place on every
208
+ transition, so cold-load shows terminal states correctly) are reached from rails code via the
209
+ process-wide `server/agent-chat-registry.ts` singleton (null-safe: tests/disabled builds).
210
+ Live updates ride the app-global `agent_pr_decision` WS event; the client renders
211
+ `AgentPrDecisionCard` and POSTs the same project-scoped `/rails/pr-decision`.
212
+ - **Race:** the second answer arrives with a stale `expectedDecision` → 409; the client shows a
213
+ neutral "already resolved" toast and reconciles to the broadcast.
214
+
215
+ ## Relaunch guard
216
+
217
+ `POST /rails/:i/launch` returns **409 `{ error: 'pr_decision_pending', prDeliveryId }`** when an
218
+ active (non-terminal) delivery exists for the slot AND the launch would take the isolated PR
219
+ path — a relaunch would append new commits to the undecided branches (worktree creation resumes
220
+ existing branches). Legacy / non-isolated launches are unaffected.
221
+
222
+ ## Ticket lifecycle — `on_review`
223
+
224
+ New status in `TicketStatus` / `VALID_STATUSES` (`server/ticket-store.ts`), between
225
+ `in_progress` and `done`. Pipeline-owned:
226
+
227
+ **Universal ask-first (both completion chokepoints).** Under the default-on PR-delivery flag
228
+ EVERY completed job/run promotes its tickets `todo|in_progress → on_review`, never `done`:
229
+
230
+ - **Loop runs** (`project-registry.ts` `onLoopRunFinished`): explicit `ticketCompletionStatus`
231
+ from `launchIsolatedRail` (launch-captured `prMode`); absent opts default to the flag (see
232
+ "Per-run settle" above) — covering shared-cwd rail launches, standalone loop runs, and the
233
+ isolation-unavailable fallback.
234
+ - **QueueManager jobs** (`project-registry.ts` `onJobFinished`): bare-mode launches, MCP
235
+ `/spawn` jobs, ultracode Finalize, interactive auto-settles. `QueueManager._startJob` reads
236
+ `isRailPrDeliveryEnabled()` ONCE per job at spawn — the SAME read that injects
237
+ `SPECRAILS_GIT_AUTO=false` — records it in the in-memory `_jobPrDelivery` map (restart-durable
238
+ by construction, like the interactive gate: a queued job surviving a restart recomputes at its
239
+ own spawn), and both settle paths (`_onJobExit` / `_settleInteractiveJob`) consume it and
240
+ thread `{ ticketCompletionStatus }` into `onJobFinished` on COMPLETED exits (failure statuses
241
+ keep the legacy 3-arg call shape). A mid-flight env flip can never split one job between the
242
+ spawn-env methodology and the settle parking. The Jira write-back splits identically:
243
+ completed + on_review → `onRailReview(changedIds, jobId)`; failed/canceled/zombie → the
244
+ legacy done-flavoured `onJobOutcome`.
245
+
246
+ `done` is reachable ONLY via the PR-decision `poll-merge`, a manual context-menu move, or the
247
+ kill-switch-off legacy path. The `needs_review`-clearing and failure-revert branches of
248
+ `applyJobOutcomeToTickets` are byte-identical to legacy.
249
+
250
+ - Board: lives in the ToDo bucket with an accent-warning "On review" pill
251
+ (`TicketStatusIndicator` et al.); auto-stripped from rails; not draggable onto rails; a rail
252
+ containing one cannot launch.
253
+ - Users can move OUT of it manually (`todo`/`done` via the ticket context menu) but never INTO
254
+ it. Explore "Continue Editing" excludes it (Jira-mirror specs keep their any-column rule).
255
+ `validatePriorityForStatus` unchanged (priority null only for `draft`).
256
+ - Merge → `done`; discard → `todo`; both applied only to tickets still sitting at `on_review`.
257
+
258
+ ## Jira mapping
259
+
260
+ - `SpecLogicalState` gains `on_review` (server `server/jira/types.ts` + client `jira-api.ts`);
261
+ `sanitizeStatusMap` accepts the new key (it silently dropped unknown keys before); the connect
262
+ **wizard** and the **connected card** both expose a `statusMap.on_review` editor.
263
+ - Resolver (`jira-status-resolver.ts`): explicit `statusMap.on_review` first, else
264
+ `statusCategory` fallback `indeterminate`. **Same-category-walk fix:** when an explicit target
265
+ is configured and the current status *name* differs, the walk transitions even if both statuses
266
+ share a category (previously a same-category no-op made e.g. In Progress → In Review
267
+ impossible). Unconfigured `statusMap.on_review` still no-ops (issue stays In Progress).
268
+ - Materializer (`jira-materializer.ts`): an inbound issue whose status name equals the mapped
269
+ `on_review` status (case-insensitive) materializes as `on_review` instead of being reverted by
270
+ the `indeterminate` category ~one poll after the outbox drained.
271
+ - Hooks (`jira-sync-manager.ts`, all outbox-only — the local cache write belongs to the caller):
272
+ `onRailReview(ticketIds, refId)` at PR-mode settle; `onRailMerged(ticketIds, refId, prUrl)`
273
+ (Done transition + "PR merged" comment — NOT `onJobOutcome`, whose completion comment assumes
274
+ cost/duration); `onRailDiscard(ticketIds, refId)` (configured `discardStatus`, else logical
275
+ todo).
276
+
277
+ ## Origin link (as-built)
278
+
279
+ Persisted end state: `rail_pr_deliveries.origin_surface` + `origin_conversation_id`, written at
280
+ the launch INSERT. As-built:
281
+
282
+ - `POST /rails/:i/launch` accepts `originConversationId` (validated `/^[A-Za-z0-9-]{1,64}$/`) and
283
+ `originSurface` (`'dashboard' | 'agent-chat'`), threaded into `launchIsolatedRail`.
284
+ Dashboard launches default to `origin_surface='dashboard'`, `origin_conversation_id=NULL`.
285
+ - **The MCP auto-attach chain (shipped)** — four hops, so an agent-launched rail tags itself
286
+ end-to-end with no manager change (`AgentChatManager` already passes `conversationId` into
287
+ `prepareAgentMcp`):
288
+ 1. `agent-mcp-config.ts` `buildSpecrailsMcpEntry` gained `conversationId` in its opts
289
+ (validated against the same launch regex; malformed ⇒ silently omitted) and sets
290
+ `SPECRAILS_AGENT_CONVERSATION` in `entry.env` — threaded at both internal call sites
291
+ (`prepareAgentMcp` and `buildAgentMcpArgs`), so the claude `--mcp-config` file, the codex
292
+ inline `-c mcp_servers.specrails.env.*` overrides and the gemini cwd `.mcp.json` all carry
293
+ it automatically. `mergeSpecrailsIntoWorkspaceMcp` (Part A workspace wiring) deliberately
294
+ stays conversation-less.
295
+ 2. `mcp-bridge` forwards the env as the `x-specrails-agent-conversation` header
296
+ (`agentForwardHeaders` in `bridge.ts`, alongside the tier/project forwards). The staged
297
+ bundle `src-tauri/binaries/specrails-mcp.js` must be regenerated via
298
+ `npm run build:mcp-bridge` whenever the bridge source changes — a stale bundle silently
299
+ drops the header (origin degrades to NULL with no error).
300
+ 3. `registerTieredTool` (`server/mcp/tools/types.ts`) reads the header into the per-call
301
+ `ctx.originConversationId` next to the project pin (same per-call ctx-copy discipline;
302
+ malformed ⇒ `null`, never throws — the launch degrades to untagged).
303
+ 4. `specrails_rails(launch)` (`server/mcp/tools/rails.ts`) adds
304
+ `originConversationId` + `originSurface:'agent-chat'` to the POST body when the ctx
305
+ carries an id (`apiCall` forwards no custom headers, so the id rides the JSON body).
306
+ External MCP clients (Claude Desktop, Cursor, …) spawn the bridge without any
307
+ `SPECRAILS_AGENT_*` env → no header → untagged launches, by design. Covered end-to-end by
308
+ `server/mcp/tools/rails-origin.test.ts` (header → ctx → body → route → persisted row →
309
+ settle fires `postPrDecisionCard` for that conversation).
310
+
311
+ ## Decisions (D1–D11, condensed)
312
+
313
+ - **D1 — three extra columns** (`branches`, `loop_name`, `worktree_ids`) on migration 36:
314
+ deferred create-pr/discard must be reconstructible from the row; nothing survives in memory
315
+ after settle.
316
+ - **D2 — the on_review divert intercepts `onLoopRunFinished`**, not `onJobFinished`: isolated
317
+ rails settle per-run through `rail-isolated-launch`, and an opt-in
318
+ `ticketCompletionStatus`/`completedStatus` option keeps the default path byte-identical.
319
+ **Superseded (universal ask-first):** the divert now lives in BOTH chokepoints — the
320
+ `onLoopRunFinished` default derives from the flag when opts are absent, and `onJobFinished`
321
+ receives the spawn-captured flag from QueueManager — see "Ticket lifecycle" above. The opt-in
322
+ option shape survives unchanged; only its defaults moved from hardcoded `'done'` to
323
+ flag-derived.
324
+ - **D3 — state machine**: 0-succeeded settles auto-close to `discarded`; degraded drafts
325
+ (`pr_url` null) have no Publish, only retry/discard; `pr_state` records delivery degradation
326
+ independent of `decision`.
327
+ - **D4 — create-pr reconstructs deliverRailAsPr inputs from the row** and defensively deletes a
328
+ stale batch branch first (retry after a degraded delivery would die on "branch already
329
+ exists"); never the integration branch.
330
+ - **D5 — relaunch collision** = 409 `pr_decision_pending` only on the isolated PR path.
331
+ - **D6 — `rail.pr_delivered` retired**, replaced by the durable `rail.pr_state` + the
332
+ `GET /rails` `prDeliveries` hydration; `Map<railIndex, …>` on the client keyed to the newest
333
+ active row.
334
+ - **D7 — no SQL migration for the `'system'` role** (`agent_messages.role` is unconstrained
335
+ TEXT); the card is a system-role row updated in place; rails code reaches the manager via the
336
+ new `agent-chat-registry` (no circular import of `index.ts`).
337
+ - **D8 — origin rides the rails launch only**; the `jobs.ts /spawn` hop is dropped (QueueManager
338
+ jobs have no delivery row — the id would go nowhere). The full MCP auto-attach chain is
339
+ shipped — see "Origin link" above.
340
+ - **D9 — Jira**: two real bug fixes (sanitizeStatusMap whitelist, same-category walk) plus
341
+ inbound preservation and the three outbox hooks.
342
+ - **D10 — on_review everywhere**: server union + every client `Record<TicketStatus, …>` map,
343
+ board bucketing (ToDo tab), drag/launch guards, context-menu out-only, pill, i18n ×8.
344
+ - **D11 — premium decision UI**: disable-on-click reconciled to the broadcast, tooltips (base
345
+ branch, PR url), designed degraded/failed states, 409 → neutral "already resolved" toast;
346
+ English source strings, all 8 locales, locale-parity green.
347
+
348
+ ## Kill-switch
349
+
350
+ `SPECRAILS_RAIL_DELIVER_PR` (default ON; `0`/`false`/`off` disables) — off means: no
351
+ `rail_pr_deliveries` rows, no `on_review` (completed jobs/runs promote straight to `done` with
352
+ the done-flavoured Jira `onJobOutcome` — byte-identical legacy at BOTH chokepoints), no
353
+ decision surfaces, `all`-scope rails fall back to the shared cwd, and the legacy local
354
+ merge-back runs — byte-identical pre-change behaviour. Capture grain: once per isolated LAUNCH
355
+ (`launchIsolatedRail` entry), once per JOB at spawn (`QueueManager._startJob`), once per
356
+ shared-cwd run SETTLE (`onLoopRunFinished` default) — a mid-flight flip only affects
357
+ lifecycles that start (or, for the settle-grain default, finish) after it.
358
+ PR mode also injects `SPECRAILS_GIT_AUTO=false` into rail spawns (loop-executors +
359
+ queue-manager); bundled specrails-core ≥ 4.11.0 honours it, so implement no longer self-ships.
360
+
361
+ ## Deferred by this change
362
+
363
+ - A background merge poller for `pr_draft`/`pr_ready` rows (`poll-merge` is on-demand only).
364
+ - An origin hop for QueueManager `/spawn` jobs (no delivery row exists at job grain).
365
+
366
+ (The relocation per-run workspace overlay — formerly on this list — has SHIPPED; see
367
+ "Per-run worktree overlay" above.)
package/docs/mcp.md CHANGED
@@ -38,7 +38,7 @@ reading one description. The tools are:
38
38
  |---|---|
39
39
  | `specrails_projects` | List / resolve projects; unregister (destructive) |
40
40
  | `specrails_specs` | The spec/ticket backlog: list, get, create, update, delete, drafts, AI generate, AI-edit, Contract Refine, SMASH, per-ticket spend |
41
- | `specrails_rails` | Assign tickets to a rail, configure it, and launch the pipeline |
41
+ | `specrails_rails` | Assign tickets to a rail, configure it, and launch the pipeline — rails are dynamic (`create_rail`, up to 12) and `launch_all` starts every ready rail in parallel (worktree-isolated) |
42
42
  | `specrails_jobs` | Inspect, stream, and stop pipeline jobs |
43
43
  | `specrails_chat` | Explore / sidebar chat conversations and turns |
44
44
  | `specrails_agents` | Agent profiles and the agents catalog (Claude-only features) |
@@ -55,7 +55,7 @@ Beyond the built-ins, the **Loops** section (left sidebar, above the project lis
55
55
 
56
56
  Each run is bounded by **max iterations**, a wall-clock **timeout**, and an optional **cost cap** (USD, checked between steps). The builder also has live validation, a dry-run preview (resolve every step's exact text without spawning), import/export to JSON, and copy/paste of steps across loops. **Fork** a built-in to start from a working graph, then **Publish** to make a loop selectable on any rail.
57
57
 
58
- > Loop runs stream live in the Jobs view exactly like a normal rail job. Provider/model/effort are governed by the **rail**, not the loop's steps.
58
+ > Loop runs stream live in the Jobs view like any rail job — and the Job Detail view groups a loop's log **by step**: a live chip map of the graph on top, one collapsible section per step below, with follow mode tracking the running step. Provider/model/effort are governed by the **rail**, not the loop's steps.
59
59
 
60
60
  ### Pipeline phases
61
61
 
@@ -76,6 +76,8 @@ Each phase is a specialised agent invoked by the rail's engine (Claude, Codex, o
76
76
 
77
77
  In plain terms: the project's **agent profile** decides which AI agent handles each phase. The baseline trio (`sr-architect`, `sr-developer`, `sr-reviewer`) is always present; a profile's routing rules can add extra agents or swap which one runs a phase. The phase progress bar only renders when the command defines phases. For the full format, see [internals/profiles.md](internals/profiles.md).
78
78
 
79
+ **How the work is delivered (ask-first).** By default (`SPECRAILS_RAIL_DELIVER_PR` on — set `0`/`false`/`off` to disable) a rail runs in isolated git worktree(s) off your project's designated integration branch (*Settings → Integration branch*, defaults to the repo default branch). When the run finishes, **nothing is pushed and no PR is opened yet**: the work stays committed on its isolated branches, the specs move to a new **On Review** status, and the app asks you what to do — a persistent decision bar appears on the rail with **Create PR** and **Discard**. **Create PR** assembles the branches into **one draft pull request** — combined across every spec on the rail, with per-ticket commit history preserved; you can then **Approve** it (promote to ready-for-review) and later **Check merge** — once a human merges it in GitHub, the specs flip to Done. **Discard** cleans up the worktrees and branches and returns the specs to the backlog. specrails never merges and never modifies your working tree; a human owns the merge. Creating the PR needs `gh` authenticated + a remote; otherwise the work is still committed to a branch you can PR from yourself (the bar offers a retry). When the flow is disabled, the rail integrates its branches locally instead (the legacy behaviour) and no decision is asked. This is desktop-owned: specrails-core's `implement` is told to skip its own shipping (`SPECRAILS_GIT_AUTO=false`) so it never opens a second, uncoordinated PR.
80
+
79
81
  ### Freestyle
80
82
 
81
83
  `Freestyle` (mode value `ultracode` on the API — its original name) is a Claude-only loop that skips the Architect → Developer → Reviewer → Ship pipeline entirely. Instead of orchestrating the agent chain, it hands Claude a configurable pre-prompt plus the full spec text and lets it work autonomously with its native tools.
@@ -84,7 +86,7 @@ In plain terms: the project's **agent profile** decides which AI agent handles e
84
86
  - **Variable cost.** Because the run is open-ended, pressing Play opens a confirmation dialog before anything spawns.
85
87
  - **Model picker.** A per-rail control lets you pick **Haiku / Sonnet / Opus** (default Sonnet) for the Freestyle run.
86
88
  - **Claude only.** The Freestyle loop and its model picker are offered only when the rail's engine is Claude. Codex and Gemini rails can't run Freestyle, and agent profiles don't apply to Freestyle rails.
87
- - **Interactive (optional).** An `Interactive` toggle next to the Freestyle launch turns the run into a back-and-forth session: you can chat with the running job, send follow-up prompts, and click **Finalize** when you're done. Without it, the job runs to completion on its own. (Available when the rail is idle; can be disabled server-side via `SPECRAILS_INTERACTIVE_JOBS=false`.)
89
+ - **Interactive by default.** Like every Claude job, a Freestyle run is a live session: chat with the running job and send follow-up prompts from the Job Detail composer. What's special about Freestyle is the ending — the session stays open until **you** click **Finalize** (other jobs wrap up on their own once a turn finishes with nothing queued). Can be disabled server-side via `SPECRAILS_INTERACTIVE_JOBS=false`.
88
90
 
89
91
  You can customise the Freestyle pre-prompt per project on the [Settings page](customizing.md#freestyle-pre-prompt).
90
92
 
@@ -121,6 +123,8 @@ Two panels sit above the streaming log:
121
123
 
122
124
  Below: the full streaming log with auto-scroll, search, and copy.
123
125
 
126
+ **Talk to the running job.** Every Claude job (and every Claude AI step in a loop run) is an interactive session by default: a chat composer sits at the bottom of the Job Detail page — and of the job modal in mission mode — so you can ask the running agent a question or steer it mid-run. Messages sent while the model is streaming queue up and run next; the job keeps following its plan. The composer shows a live `N turns · $X` line summed from each completed turn's real usage (still no estimates). Most jobs finish on their own the moment a turn completes with nothing queued — a subtle **Wrap up now** ends them early; Freestyle jobs instead wait for your explicit **Finalize**. During a loop run your messages reach the currently running AI step (between steps the composer shows a short waiting state, and **Settle this step** advances the loop). Codex and Gemini jobs run one-shot as before. Server kill switch: `SPECRAILS_INTERACTIVE_JOBS=false`.
127
+
124
128
  ### Cancelling a job
125
129
 
126
130
  Click **Stop** on the rail header. The app sends `SIGTERM` to the subprocess, waits **5 s**, then `SIGKILL`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specrails-desktop",
3
- "version": "2.20.1",
3
+ "version": "2.22.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",