specrails-desktop 2.30.2 → 2.31.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 (462) hide show
  1. package/README.md +28 -24
  2. package/client/dist/assets/{ActivityFeedPage-9DZOvIcY.js → ActivityFeedPage-CAhFRUO4.js} +1 -1
  3. package/client/dist/assets/{AgentBrowserCapture-DqyHbzk7.js → AgentBrowserCapture-Ct4G5lsE.js} +1 -1
  4. package/client/dist/assets/AgentModeCodePane-DQt9WIvu.js +2 -0
  5. package/client/dist/assets/{AgentModeJobsPane-CTIHMUKN.js → AgentModeJobsPane-podaJVl9.js} +1 -1
  6. package/client/dist/assets/AgentsPage-DTZdbW80.js +87 -0
  7. package/client/dist/assets/AnalyticsPage-BskgGPm0.js +1 -0
  8. package/client/dist/assets/CodePage-CvtYo1DU.js +2 -0
  9. package/client/dist/assets/{DesktopAnalyticsPage-CkXUFj3F.js → DesktopAnalyticsPage-Dnf99E8e.js} +1 -1
  10. package/client/dist/assets/{DocsDialog-PhdCJNVj.js → DocsDialog-DHi36rZ4.js} +1 -1
  11. package/client/dist/assets/{DocsPage-BY-wDthx.js → DocsPage-DIdVrQz1.js} +1 -1
  12. package/client/dist/assets/{InteractiveJobComposer-C9I0A4KR.js → InteractiveJobComposer-BHeB2inv.js} +1 -1
  13. package/client/dist/assets/{JobDetailModal-I_RoQJV4.js → JobDetailModal-CF1SKUHH.js} +1 -1
  14. package/client/dist/assets/JobDetailPage-De3rY18h.js +1 -0
  15. package/client/dist/assets/{JobsPage-DcllM4Ip.js → JobsPage-CfAqqJTx.js} +1 -1
  16. package/client/dist/assets/{LoopBuilderPage-DGm_iuff.js → LoopBuilderPage-DSBMuTb3.js} +2 -2
  17. package/client/dist/assets/{LoopPreviewModal-BC-TeFdD.js → LoopPreviewModal-B-c37kA0.js} +1 -1
  18. package/client/dist/assets/LoopsPage-DjnNXdmm.js +1 -0
  19. package/client/dist/assets/{MinimizedChatsContext-Cs34FPTz.js → MinimizedChatsContext-DIsnQMVz.js} +1 -1
  20. package/client/dist/assets/PluginsPage-DA5pQ_6u.js +2 -0
  21. package/client/dist/assets/{ProjectSettingsDialog-nEs-ENrE.js → ProjectSettingsDialog-DA23PSi6.js} +1 -1
  22. package/client/dist/assets/{TemplatePreviewModal-D4qW-J9B.js → TemplatePreviewModal-Cp7IQ-g2.js} +1 -1
  23. package/client/dist/assets/TicketDetailModal-BPD2i_0R.js +14 -0
  24. package/client/dist/assets/{Trans-CPISVji8.js → Trans-cWtExGkC.js} +1 -1
  25. package/client/dist/assets/addspec-4WmLJmBG.js +1 -0
  26. package/client/dist/assets/addspec-BRlk8jON.js +1 -0
  27. package/client/dist/assets/addspec-C7XRejU4.js +1 -0
  28. package/client/dist/assets/addspec-CHW9xf_X.js +1 -0
  29. package/client/dist/assets/addspec-DTmRrWrF.js +1 -0
  30. package/client/dist/assets/addspec-DhmnXER8.js +1 -0
  31. package/client/dist/assets/addspec-Di41DpYV.js +1 -0
  32. package/client/dist/assets/addspec-x3mizDxc.js +1 -0
  33. package/client/dist/assets/agent-BKsuIgIT.js +1 -0
  34. package/client/dist/assets/agent-Bs9NilfI.js +1 -0
  35. package/client/dist/assets/agent-C23h684q.js +1 -0
  36. package/client/dist/assets/agent-CqEjy3Z2.js +1 -0
  37. package/client/dist/assets/agent-D5DZTks1.js +1 -0
  38. package/client/dist/assets/agent-DE8hUYPl.js +1 -0
  39. package/client/dist/assets/agent-DsTuJGSc.js +1 -0
  40. package/client/dist/assets/agent-DwZM05-x.js +1 -0
  41. package/client/dist/assets/agents-45GbINfh.js +1 -0
  42. package/client/dist/assets/agents-BHp0_FQt.js +1 -0
  43. package/client/dist/assets/agents-Bvyi3y6R.js +1 -0
  44. package/client/dist/assets/agents-DMKFStHL.js +1 -0
  45. package/client/dist/assets/agents-DaYcxAr1.js +1 -0
  46. package/client/dist/assets/agents-IUOgqT5t.js +1 -0
  47. package/client/dist/assets/agents-ms7TwG16.js +1 -0
  48. package/client/dist/assets/agents-rzPnqoBR.js +1 -0
  49. package/client/dist/assets/agentstudio-8TQqBenW.js +1 -0
  50. package/client/dist/assets/agentstudio-B8Z_mmEX.js +1 -0
  51. package/client/dist/assets/agentstudio-BZR9YmLs.js +1 -0
  52. package/client/dist/assets/agentstudio-Bge9pAWb.js +1 -0
  53. package/client/dist/assets/agentstudio-Bz169Vzt.js +1 -0
  54. package/client/dist/assets/agentstudio-D6L2jpNi.js +1 -0
  55. package/client/dist/assets/agentstudio-K2-Z7CL0.js +1 -0
  56. package/client/dist/assets/agentstudio-Zmgzthv8.js +1 -0
  57. package/client/dist/assets/analytics-B8Qtptbl.js +1 -0
  58. package/client/dist/assets/analytics-BHqUazhP.js +1 -0
  59. package/client/dist/assets/analytics-BPptRY4f.js +1 -0
  60. package/client/dist/assets/analytics-BxDGOIwf.js +1 -0
  61. package/client/dist/assets/analytics-C9RaQcE3.js +1 -0
  62. package/client/dist/assets/analytics-CJIwqrEl.js +1 -0
  63. package/client/dist/assets/analytics-D_OZdQ9O.js +1 -0
  64. package/client/dist/assets/analytics-We6lUMI8.js +1 -0
  65. package/client/dist/assets/builder-3bygQtZi.js +1 -0
  66. package/client/dist/assets/builder-BiUG9Z5K.js +1 -0
  67. package/client/dist/assets/builder-CGRz_-zP.js +1 -0
  68. package/client/dist/assets/builder-CWYPw7Cw.js +1 -0
  69. package/client/dist/assets/builder-CX1437hF.js +1 -0
  70. package/client/dist/assets/{builder-CwA4T7gP.js → builder-Cowk9jtL.js} +1 -1
  71. package/client/dist/assets/builder-DwDexYRE.js +1 -0
  72. package/client/dist/assets/builder-skfnZ1uC.js +1 -0
  73. package/client/dist/assets/code-B0O8-p8k.js +1 -0
  74. package/client/dist/assets/code-B1VLZDhS.js +1 -0
  75. package/client/dist/assets/code-B86IMAfz.js +1 -0
  76. package/client/dist/assets/code-Bpj4Ddml.js +1 -0
  77. package/client/dist/assets/code-BykBZ5-e.js +1 -0
  78. package/client/dist/assets/code-CHPkOkDS.js +1 -0
  79. package/client/dist/assets/code-CkUuW4m9.js +1 -0
  80. package/client/dist/assets/code-cAqaqMTx.js +1 -0
  81. package/client/dist/assets/{dashboard-Dy2Um-US.js → dashboard-BVq6kRJe.js} +1 -1
  82. package/client/dist/assets/{dashboard-CHCEkds4.js → dashboard-BaKPPmLH.js} +1 -1
  83. package/client/dist/assets/{dashboard-CrlTV1ms.js → dashboard-Bm8e4zYG.js} +1 -1
  84. package/client/dist/assets/{dashboard-WhzOQw1S.js → dashboard-Bt6IesnM.js} +1 -1
  85. package/client/dist/assets/{dashboard-Cslu_GCH.js → dashboard-C_NQZle_.js} +1 -1
  86. package/client/dist/assets/{dashboard-DweT3Y4R.js → dashboard-CyZKoGoI.js} +1 -1
  87. package/client/dist/assets/{dashboard-DUU8-_Rg.js → dashboard-HIUdUBQ0.js} +1 -1
  88. package/client/dist/assets/{dashboard-Cqmmbh3l.js → dashboard-pm4Mr229.js} +1 -1
  89. package/client/dist/assets/{dist-js-jwoXo0YD.js → dist-js-BaP-xLOy.js} +1 -1
  90. package/client/dist/assets/{dist-js-Dj72W6qo.js → dist-js-CLlgOa5a.js} +1 -1
  91. package/client/dist/assets/format-command-C0D9IPmV.js +1 -0
  92. package/client/dist/assets/{formatDistanceToNow-ByKli7Q_.js → formatDistanceToNow-DUyzS4rr.js} +1 -1
  93. package/client/dist/assets/{getTimezoneOffsetInMilliseconds-qrcBaLW1.js → getTimezoneOffsetInMilliseconds-BCIwmmTj.js} +1 -1
  94. package/client/dist/assets/{i18n-Bf9Ckd10.js → i18n-D21Pr8Sj.js} +2 -2
  95. package/client/dist/assets/index-BdSDUFnA.css +2 -0
  96. package/client/dist/assets/index-Ci4-JKDr.js +77 -0
  97. package/client/dist/assets/{jobs-CVFD8rar.js → jobs-BAls3bWq.js} +1 -1
  98. package/client/dist/assets/{jobs-DoSaFzAa.js → jobs-B_TeSQxb.js} +1 -1
  99. package/client/dist/assets/jobs-Bgq-PZkC.js +1 -0
  100. package/client/dist/assets/jobs-Bpks6doU.js +1 -0
  101. package/client/dist/assets/jobs-CN_zv4Gr.js +1 -0
  102. package/client/dist/assets/jobs-DUlWSYq2.js +1 -0
  103. package/client/dist/assets/{jobs-B-sDHEay.js → jobs-DhxKgWFq.js} +1 -1
  104. package/client/dist/assets/{jobs-lk1_Dq1U.js → jobs-SwYS2M-B.js} +1 -1
  105. package/client/dist/assets/nav-BHDiSIVu.js +1 -0
  106. package/client/dist/assets/nav-CMiYAq4i.js +1 -0
  107. package/client/dist/assets/nav-CqS7NrDW.js +1 -0
  108. package/client/dist/assets/nav-D-0M7xfv.js +1 -0
  109. package/client/dist/assets/nav-D65O6u9I.js +1 -0
  110. package/client/dist/assets/nav-D_LKYvBr.js +1 -0
  111. package/client/dist/assets/nav-FDTJmU79.js +1 -0
  112. package/client/dist/assets/nav-VaB-C4k5.js +1 -0
  113. package/client/dist/assets/provider-capabilities-BvoExILy.js +1 -0
  114. package/client/dist/assets/settings-BveOJoaI.js +1 -0
  115. package/client/dist/assets/settings-Cj1C6F5k.js +1 -0
  116. package/client/dist/assets/settings-CuVwOpe0.js +1 -0
  117. package/client/dist/assets/settings-D5X4DfRc.js +1 -0
  118. package/client/dist/assets/settings-DXwxe-BW.js +1 -0
  119. package/client/dist/assets/settings-Di81Ba_V.js +1 -0
  120. package/client/dist/assets/settings-jbLjCYC_.js +1 -0
  121. package/client/dist/assets/settings-wIZNPFnn.js +1 -0
  122. package/client/dist/assets/setup-BBiHEO7h.js +1 -0
  123. package/client/dist/assets/setup-BlTWhNIQ.js +1 -0
  124. package/client/dist/assets/setup-Bp2L_oiP.js +1 -0
  125. package/client/dist/assets/setup-CInYXp1-.js +1 -0
  126. package/client/dist/assets/{setup-CITtPjed.js → setup-CYH3bP6K.js} +1 -1
  127. package/client/dist/assets/setup-DwcQ921P.js +1 -0
  128. package/client/dist/assets/setup-PBLjuDSs.js +1 -0
  129. package/client/dist/assets/setup-bx6FtoBp.js +1 -0
  130. package/client/dist/assets/{spending-DMnCXy84.js → spending-BCyUxoOI.js} +1 -1
  131. package/client/dist/assets/{tickets-B8BuAaj5.js → tickets-BL9r1G0e.js} +1 -1
  132. package/client/dist/assets/{tickets-DpmdE8tv.js → tickets-B_NyHJ8f.js} +1 -1
  133. package/client/dist/assets/{tickets-B_yh4qQk.js → tickets-BarF1wuG.js} +1 -1
  134. package/client/dist/assets/{tickets-pAUJkDTu.js → tickets-CclVhpQA.js} +1 -1
  135. package/client/dist/assets/{tickets-D_yDquEw.js → tickets-CqqOHbli.js} +1 -1
  136. package/client/dist/assets/{tickets-CFk2n2Or.js → tickets-DCkFSiqt.js} +1 -1
  137. package/client/dist/assets/{tickets-DQp7JS2R.js → tickets-Djn3ccfT.js} +1 -1
  138. package/client/dist/assets/{tickets-Bs37scwY.js → tickets-MiHBPsy_.js} +1 -1
  139. package/client/dist/assets/{useBrowserCaptureSession-CkBJShUw.js → useBrowserCaptureSession-CkVCDzer.js} +1 -1
  140. package/client/dist/assets/{useDesktop-B4pSBIDd.js → useDesktop-DCP_MHp9.js} +1 -1
  141. package/client/dist/index.html +25 -24
  142. package/docs/README.md +7 -3
  143. package/docs/cli.md +3 -3
  144. package/docs/codex.md +51 -64
  145. package/docs/creating-specs.md +36 -4
  146. package/docs/customizing.md +5 -5
  147. package/docs/gemini.md +35 -47
  148. package/docs/getting-started.md +15 -9
  149. package/docs/guide/de/agents/2-profiles-and-the-balanced-default.md +5 -1
  150. package/docs/guide/de/agents/4-custom-agents-catalog.md +7 -4
  151. package/docs/guide/de/getting-started/1-what-is-specrails.md +1 -0
  152. package/docs/guide/de/getting-started/2-installing-and-first-run.md +1 -0
  153. package/docs/guide/de/getting-started/4-the-dashboard-tour.md +4 -4
  154. package/docs/guide/de/integrations/1-ai-providers.md +29 -18
  155. package/docs/guide/de/integrations/2-plugins.md +3 -3
  156. package/docs/guide/de/integrations/6-agent-chat.md +8 -1
  157. package/docs/guide/de/pipeline/1-rails-and-jobs.md +9 -6
  158. package/docs/guide/de/pipeline/2-the-job-detail-view.md +3 -1
  159. package/docs/guide/de/pipeline/3-batch-implement-and-multi-feature.md +1 -1
  160. package/docs/guide/de/pipeline/4-picking-an-engine-per-rail.md +13 -13
  161. package/docs/guide/de/pipeline/5-the-loop-builder.md +6 -2
  162. package/docs/guide/de/specs/2-add-spec-quick-mode.md +6 -1
  163. package/docs/guide/en/agents/2-profiles-and-the-balanced-default.md +7 -1
  164. package/docs/guide/en/agents/4-custom-agents-catalog.md +17 -4
  165. package/docs/guide/en/getting-started/1-what-is-specrails.md +2 -1
  166. package/docs/guide/en/getting-started/2-installing-and-first-run.md +2 -1
  167. package/docs/guide/en/getting-started/4-the-dashboard-tour.md +5 -5
  168. package/docs/guide/en/insights/3-code-explorer.md +5 -0
  169. package/docs/guide/en/integrations/1-ai-providers.md +63 -22
  170. package/docs/guide/en/integrations/2-plugins.md +3 -3
  171. package/docs/guide/en/integrations/6-agent-chat.md +14 -2
  172. package/docs/guide/en/pipeline/1-rails-and-jobs.md +19 -7
  173. package/docs/guide/en/pipeline/2-the-job-detail-view.md +3 -1
  174. package/docs/guide/en/pipeline/3-batch-implement-and-multi-feature.md +1 -1
  175. package/docs/guide/en/pipeline/4-picking-an-engine-per-rail.md +25 -11
  176. package/docs/guide/en/pipeline/5-the-loop-builder.md +7 -2
  177. package/docs/guide/en/specs/2-add-spec-quick-mode.md +10 -1
  178. package/docs/guide/es/agents/2-profiles-and-the-balanced-default.md +5 -1
  179. package/docs/guide/es/agents/4-custom-agents-catalog.md +7 -4
  180. package/docs/guide/es/getting-started/1-what-is-specrails.md +1 -0
  181. package/docs/guide/es/getting-started/2-installing-and-first-run.md +1 -0
  182. package/docs/guide/es/getting-started/4-the-dashboard-tour.md +4 -4
  183. package/docs/guide/es/integrations/1-ai-providers.md +30 -18
  184. package/docs/guide/es/integrations/2-plugins.md +3 -3
  185. package/docs/guide/es/integrations/6-agent-chat.md +8 -1
  186. package/docs/guide/es/pipeline/1-rails-and-jobs.md +9 -6
  187. package/docs/guide/es/pipeline/2-the-job-detail-view.md +3 -1
  188. package/docs/guide/es/pipeline/3-batch-implement-and-multi-feature.md +1 -1
  189. package/docs/guide/es/pipeline/4-picking-an-engine-per-rail.md +15 -13
  190. package/docs/guide/es/pipeline/5-the-loop-builder.md +6 -2
  191. package/docs/guide/es/specs/2-add-spec-quick-mode.md +6 -1
  192. package/docs/guide/fr/agents/2-profiles-and-the-balanced-default.md +5 -1
  193. package/docs/guide/fr/agents/4-custom-agents-catalog.md +7 -4
  194. package/docs/guide/fr/getting-started/1-what-is-specrails.md +1 -0
  195. package/docs/guide/fr/getting-started/2-installing-and-first-run.md +1 -0
  196. package/docs/guide/fr/getting-started/4-the-dashboard-tour.md +4 -4
  197. package/docs/guide/fr/integrations/1-ai-providers.md +29 -18
  198. package/docs/guide/fr/integrations/2-plugins.md +3 -3
  199. package/docs/guide/fr/integrations/6-agent-chat.md +8 -1
  200. package/docs/guide/fr/pipeline/1-rails-and-jobs.md +9 -6
  201. package/docs/guide/fr/pipeline/2-the-job-detail-view.md +3 -1
  202. package/docs/guide/fr/pipeline/3-batch-implement-and-multi-feature.md +1 -1
  203. package/docs/guide/fr/pipeline/4-picking-an-engine-per-rail.md +15 -13
  204. package/docs/guide/fr/pipeline/5-the-loop-builder.md +6 -2
  205. package/docs/guide/fr/specs/2-add-spec-quick-mode.md +6 -1
  206. package/docs/guide/it/agents/2-profiles-and-the-balanced-default.md +5 -1
  207. package/docs/guide/it/agents/4-custom-agents-catalog.md +7 -4
  208. package/docs/guide/it/getting-started/1-what-is-specrails.md +1 -0
  209. package/docs/guide/it/getting-started/2-installing-and-first-run.md +1 -0
  210. package/docs/guide/it/getting-started/4-the-dashboard-tour.md +4 -4
  211. package/docs/guide/it/integrations/1-ai-providers.md +28 -18
  212. package/docs/guide/it/integrations/2-plugins.md +3 -3
  213. package/docs/guide/it/integrations/6-agent-chat.md +8 -1
  214. package/docs/guide/it/pipeline/1-rails-and-jobs.md +9 -6
  215. package/docs/guide/it/pipeline/2-the-job-detail-view.md +3 -1
  216. package/docs/guide/it/pipeline/3-batch-implement-and-multi-feature.md +1 -1
  217. package/docs/guide/it/pipeline/4-picking-an-engine-per-rail.md +13 -13
  218. package/docs/guide/it/pipeline/5-the-loop-builder.md +6 -2
  219. package/docs/guide/it/specs/2-add-spec-quick-mode.md +6 -1
  220. package/docs/guide/ja/agents/2-profiles-and-the-balanced-default.md +6 -1
  221. package/docs/guide/ja/agents/4-custom-agents-catalog.md +7 -4
  222. package/docs/guide/ja/getting-started/1-what-is-specrails.md +1 -0
  223. package/docs/guide/ja/getting-started/2-installing-and-first-run.md +1 -0
  224. package/docs/guide/ja/getting-started/4-the-dashboard-tour.md +4 -4
  225. package/docs/guide/ja/integrations/1-ai-providers.md +28 -18
  226. package/docs/guide/ja/integrations/2-plugins.md +3 -3
  227. package/docs/guide/ja/integrations/6-agent-chat.md +7 -1
  228. package/docs/guide/ja/pipeline/1-rails-and-jobs.md +9 -6
  229. package/docs/guide/ja/pipeline/2-the-job-detail-view.md +3 -1
  230. package/docs/guide/ja/pipeline/3-batch-implement-and-multi-feature.md +1 -1
  231. package/docs/guide/ja/pipeline/4-picking-an-engine-per-rail.md +14 -13
  232. package/docs/guide/ja/pipeline/5-the-loop-builder.md +6 -2
  233. package/docs/guide/ja/specs/2-add-spec-quick-mode.md +6 -1
  234. package/docs/guide/pt/agents/2-profiles-and-the-balanced-default.md +5 -1
  235. package/docs/guide/pt/agents/4-custom-agents-catalog.md +7 -4
  236. package/docs/guide/pt/getting-started/1-what-is-specrails.md +1 -0
  237. package/docs/guide/pt/getting-started/2-installing-and-first-run.md +1 -0
  238. package/docs/guide/pt/getting-started/4-the-dashboard-tour.md +4 -4
  239. package/docs/guide/pt/integrations/1-ai-providers.md +28 -18
  240. package/docs/guide/pt/integrations/2-plugins.md +3 -3
  241. package/docs/guide/pt/integrations/6-agent-chat.md +7 -1
  242. package/docs/guide/pt/pipeline/1-rails-and-jobs.md +9 -6
  243. package/docs/guide/pt/pipeline/2-the-job-detail-view.md +2 -1
  244. package/docs/guide/pt/pipeline/3-batch-implement-and-multi-feature.md +1 -1
  245. package/docs/guide/pt/pipeline/4-picking-an-engine-per-rail.md +14 -13
  246. package/docs/guide/pt/pipeline/5-the-loop-builder.md +6 -2
  247. package/docs/guide/pt/specs/2-add-spec-quick-mode.md +6 -1
  248. package/docs/guide/zh/agents/2-profiles-and-the-balanced-default.md +4 -1
  249. package/docs/guide/zh/agents/4-custom-agents-catalog.md +7 -4
  250. package/docs/guide/zh/getting-started/1-what-is-specrails.md +1 -0
  251. package/docs/guide/zh/getting-started/2-installing-and-first-run.md +1 -0
  252. package/docs/guide/zh/getting-started/4-the-dashboard-tour.md +4 -4
  253. package/docs/guide/zh/integrations/1-ai-providers.md +26 -18
  254. package/docs/guide/zh/integrations/2-plugins.md +3 -3
  255. package/docs/guide/zh/integrations/6-agent-chat.md +6 -1
  256. package/docs/guide/zh/pipeline/1-rails-and-jobs.md +9 -6
  257. package/docs/guide/zh/pipeline/2-the-job-detail-view.md +2 -1
  258. package/docs/guide/zh/pipeline/3-batch-implement-and-multi-feature.md +1 -1
  259. package/docs/guide/zh/pipeline/4-picking-an-engine-per-rail.md +12 -12
  260. package/docs/guide/zh/pipeline/5-the-loop-builder.md +6 -2
  261. package/docs/guide/zh/specs/2-add-spec-quick-mode.md +6 -1
  262. package/docs/internals/README.md +4 -1
  263. package/docs/internals/adding-a-provider.md +32 -28
  264. package/docs/internals/api-reference.md +37 -13
  265. package/docs/internals/architecture.md +5 -5
  266. package/docs/internals/bundled-framework-build-plan.md +3 -3
  267. package/docs/internals/code-explorer-story.md +4 -0
  268. package/docs/internals/configuration.md +17 -5
  269. package/docs/internals/global-artifacts-alignment-contract.md +1 -1
  270. package/docs/internals/operations-runbook.md +1 -1
  271. package/docs/internals/profiles.md +37 -45
  272. package/docs/internals/project-builder.md +16 -0
  273. package/docs/kimi.md +291 -0
  274. package/docs/mcp.md +9 -2
  275. package/docs/platforms/macos.md +17 -7
  276. package/docs/platforms/windows.md +9 -4
  277. package/docs/running-pipelines.md +46 -12
  278. package/docs/terminal.md +1 -1
  279. package/docs/tracking-cost.md +25 -6
  280. package/package.json +4 -2
  281. package/server/dist/agent-chat-manager.js +74 -32
  282. package/server/dist/agent-chat-router.js +40 -17
  283. package/server/dist/agent-cwd-manager.js +14 -7
  284. package/server/dist/agent-generator.js +69 -85
  285. package/server/dist/agent-mcp-config.js +17 -11
  286. package/server/dist/agent-operator-prompt.js +29 -20
  287. package/server/dist/agent-refine-manager.js +58 -38
  288. package/server/dist/ai-invocations.js +65 -20
  289. package/server/dist/attachment-manager.js +49 -15
  290. package/server/dist/blueprint-chat-manager.js +41 -16
  291. package/server/dist/blueprint-router.js +40 -6
  292. package/server/dist/chat-manager.js +165 -89
  293. package/server/dist/code-explorer-router.js +26 -7
  294. package/server/dist/contract-refine-runner.js +146 -113
  295. package/server/dist/core-compat.js +57 -2
  296. package/server/dist/core-package.js +3 -3
  297. package/server/dist/core-update-manager.js +17 -1
  298. package/server/dist/db.js +60 -5
  299. package/server/dist/desktop-analytics.js +44 -6
  300. package/server/dist/desktop-router.js +127 -11
  301. package/server/dist/explore-cwd-manager.js +19 -3
  302. package/server/dist/feature-flags.js +1 -1
  303. package/server/dist/file-story-manager.js +3 -3
  304. package/server/dist/file-summary-generator.js +21 -15
  305. package/server/dist/file-summary-manager.js +6 -6
  306. package/server/dist/framework-manager.js +19 -2
  307. package/server/dist/framework-migration.js +27 -12
  308. package/server/dist/install-config-path.js +1 -1
  309. package/server/dist/interactive-job-session.js +8 -6
  310. package/server/dist/loop-command-catalog.js +27 -10
  311. package/server/dist/loop-executors.js +59 -27
  312. package/server/dist/loop-factory.js +2 -2
  313. package/server/dist/loop-run-manager.js +100 -39
  314. package/server/dist/loops-router.js +1 -1
  315. package/server/dist/mcp/guide.js +23 -16
  316. package/server/dist/mcp/tools/agents.js +47 -41
  317. package/server/dist/mcp/tools/analytics.js +2 -2
  318. package/server/dist/mcp/tools/loops.js +2 -2
  319. package/server/dist/mcp/tools/plugins.js +14 -9
  320. package/server/dist/mcp/tools/rails.js +12 -13
  321. package/server/dist/mcp/tools/support.js +1 -1
  322. package/server/dist/mobile/mobile-router.js +5 -1
  323. package/server/dist/offline-assemble.js +13 -1
  324. package/server/dist/path-resolver.js +2 -2
  325. package/server/dist/plugin-manager.js +391 -106
  326. package/server/dist/plugins/claude-md-mutation.js +5 -4
  327. package/server/dist/plugins/drift.js +32 -29
  328. package/server/dist/plugins/rail-integration.js +13 -2
  329. package/server/dist/plugins/serena/install.js +25 -17
  330. package/server/dist/plugins/serena/manifest.js +22 -5
  331. package/server/dist/plugins/serena/verify.js +46 -16
  332. package/server/dist/plugins-router.js +59 -8
  333. package/server/dist/profile-manager.js +148 -36
  334. package/server/dist/profiles-router.js +311 -82
  335. package/server/dist/project-registry.js +2 -2
  336. package/server/dist/project-router-chat.js +17 -8
  337. package/server/dist/project-router-helpers.js +93 -5
  338. package/server/dist/project-router-jobs.js +76 -12
  339. package/server/dist/project-router-loop-runs.js +42 -14
  340. package/server/dist/project-router-settings.js +31 -10
  341. package/server/dist/project-router-setup.js +4 -5
  342. package/server/dist/project-router-spending.js +15 -3
  343. package/server/dist/project-router-tickets.js +187 -181
  344. package/server/dist/project-router.js +1 -0
  345. package/server/dist/proposal-manager.js +125 -85
  346. package/server/dist/providers/claude-adapter.js +14 -0
  347. package/server/dist/providers/codex-adapter.js +20 -0
  348. package/server/dist/providers/gemini-adapter.js +14 -0
  349. package/server/dist/providers/index.js +18 -1
  350. package/server/dist/providers/kimi-adapter.js +361 -0
  351. package/server/dist/providers/kimi-skill-prompt.js +332 -0
  352. package/server/dist/providers/runtime.js +137 -0
  353. package/server/dist/queue-manager.js +103 -78
  354. package/server/dist/rail-isolated-launch.js +1 -1
  355. package/server/dist/rails-router.js +51 -38
  356. package/server/dist/result-event.js +5 -0
  357. package/server/dist/schemas/profile.v1.json +3 -4
  358. package/server/dist/setup-manager.js +222 -101
  359. package/server/dist/setup-prerequisites.js +7 -1
  360. package/server/dist/smash-runner.js +104 -57
  361. package/server/dist/spawn-lifecycle.js +18 -14
  362. package/server/dist/spec-launcher-manager.js +66 -54
  363. package/server/dist/spec-models.js +15 -6
  364. package/server/dist/spending.js +110 -17
  365. package/server/dist/util/cli-prompt.js +142 -5
  366. package/server/dist/util/stream-display.js +46 -0
  367. package/server/dist/workspace-manager.js +100 -37
  368. package/server/dist/worktree-manager.js +4 -0
  369. package/server/dist/worktree-overlay.js +12 -3
  370. package/client/dist/assets/AgentModeCodePane-BAYyFRmY.js +0 -2
  371. package/client/dist/assets/AgentsPage-DuyJuaFs.js +0 -86
  372. package/client/dist/assets/AnalyticsPage-BY7gtCx6.js +0 -1
  373. package/client/dist/assets/CodePage-vyQr40Vl.js +0 -2
  374. package/client/dist/assets/JobDetailPage-CU4FEnUC.js +0 -1
  375. package/client/dist/assets/LoopsPage-SqglnXlp.js +0 -1
  376. package/client/dist/assets/PluginsPage-B89S8o1a.js +0 -2
  377. package/client/dist/assets/TicketDetailModal-CI47Dq9E.js +0 -14
  378. package/client/dist/assets/addspec-BXjvkh5q.js +0 -1
  379. package/client/dist/assets/addspec-C4bwrmpi.js +0 -1
  380. package/client/dist/assets/addspec-CArHXUDM.js +0 -1
  381. package/client/dist/assets/addspec-DTKJcXiR.js +0 -1
  382. package/client/dist/assets/addspec-DbNBbrha.js +0 -1
  383. package/client/dist/assets/addspec-Rw8uVBC1.js +0 -1
  384. package/client/dist/assets/addspec-htHGZHOe.js +0 -1
  385. package/client/dist/assets/addspec-lr_LP6jk.js +0 -1
  386. package/client/dist/assets/agent-BABjRt0P.js +0 -1
  387. package/client/dist/assets/agent-BuUpgqVx.js +0 -1
  388. package/client/dist/assets/agent-CCDZesgU.js +0 -1
  389. package/client/dist/assets/agent-CVn64zWH.js +0 -1
  390. package/client/dist/assets/agent-CWeOny0E.js +0 -1
  391. package/client/dist/assets/agent-DOysmad_.js +0 -1
  392. package/client/dist/assets/agent-DSsjTBhn.js +0 -1
  393. package/client/dist/assets/agent-DlZMxfM9.js +0 -1
  394. package/client/dist/assets/agents-6ZOJXWVk.js +0 -1
  395. package/client/dist/assets/agents-BZ0XQKjg.js +0 -1
  396. package/client/dist/assets/agents-BqWklnHR.js +0 -1
  397. package/client/dist/assets/agents-Bz-thHkB.js +0 -1
  398. package/client/dist/assets/agents-CJclElx6.js +0 -1
  399. package/client/dist/assets/agents-D_l9L0VA.js +0 -1
  400. package/client/dist/assets/agents-DhG7mg6-.js +0 -1
  401. package/client/dist/assets/agents-u_C0jPB5.js +0 -1
  402. package/client/dist/assets/agentstudio-BF19hbXj.js +0 -1
  403. package/client/dist/assets/agentstudio-BIUe1Im2.js +0 -1
  404. package/client/dist/assets/agentstudio-BLGvxWBx.js +0 -1
  405. package/client/dist/assets/agentstudio-D9UKiWTj.js +0 -1
  406. package/client/dist/assets/agentstudio-Drs37nIM.js +0 -1
  407. package/client/dist/assets/agentstudio-nEnKkcXM.js +0 -1
  408. package/client/dist/assets/agentstudio-pyFcSBKy.js +0 -1
  409. package/client/dist/assets/agentstudio-zfTzQh3U.js +0 -1
  410. package/client/dist/assets/analytics-BC7mwR4s.js +0 -1
  411. package/client/dist/assets/analytics-BiNg8edP.js +0 -1
  412. package/client/dist/assets/analytics-C0s_T2GN.js +0 -1
  413. package/client/dist/assets/analytics-CdsAPAwZ.js +0 -1
  414. package/client/dist/assets/analytics-Cr1_q-lC.js +0 -1
  415. package/client/dist/assets/analytics-DZ8Aoq3I.js +0 -1
  416. package/client/dist/assets/analytics-IEsKZvpW.js +0 -1
  417. package/client/dist/assets/analytics-SRPf84OT.js +0 -1
  418. package/client/dist/assets/builder-BH8Fua-g.js +0 -1
  419. package/client/dist/assets/builder-BoV7DgKd.js +0 -1
  420. package/client/dist/assets/builder-Cc_Lf79C.js +0 -1
  421. package/client/dist/assets/builder-CwZ7Bme2.js +0 -1
  422. package/client/dist/assets/builder-CxW-JFsR.js +0 -1
  423. package/client/dist/assets/builder-D94lrV7x.js +0 -1
  424. package/client/dist/assets/builder-cqHpCyGa.js +0 -1
  425. package/client/dist/assets/code-76gS0IdL.js +0 -1
  426. package/client/dist/assets/code-BDXEM4ml.js +0 -1
  427. package/client/dist/assets/code-C1VwxlML.js +0 -1
  428. package/client/dist/assets/code-CnMZyJpr.js +0 -1
  429. package/client/dist/assets/code-D20ef9Cf.js +0 -1
  430. package/client/dist/assets/code-DdOXaWRY.js +0 -1
  431. package/client/dist/assets/code-Duohuf9l.js +0 -1
  432. package/client/dist/assets/code-geHmknB9.js +0 -1
  433. package/client/dist/assets/format-command-Dfa1o2d-.js +0 -1
  434. package/client/dist/assets/index-Dh9i4CnN.css +0 -2
  435. package/client/dist/assets/index-F9r8mWP_.js +0 -76
  436. package/client/dist/assets/jobs-BCtGfgUA.js +0 -1
  437. package/client/dist/assets/jobs-BHR_EnDI.js +0 -1
  438. package/client/dist/assets/jobs-BMbZJjJJ.js +0 -1
  439. package/client/dist/assets/jobs-DzSIR8V6.js +0 -1
  440. package/client/dist/assets/nav-BRJBxaGt.js +0 -1
  441. package/client/dist/assets/nav-CAGKv3_F.js +0 -1
  442. package/client/dist/assets/nav-CNskRJKQ.js +0 -1
  443. package/client/dist/assets/nav-DY93irBL.js +0 -1
  444. package/client/dist/assets/nav-DhjvYgqt.js +0 -1
  445. package/client/dist/assets/nav-Gb-r4wop.js +0 -1
  446. package/client/dist/assets/nav-TvumAFD2.js +0 -1
  447. package/client/dist/assets/nav-myFaXRHD.js +0 -1
  448. package/client/dist/assets/settings-B0ypw9uw.js +0 -1
  449. package/client/dist/assets/settings-B9ilOSYO.js +0 -1
  450. package/client/dist/assets/settings-BqlWHRHA.js +0 -1
  451. package/client/dist/assets/settings-D8dlqt4d.js +0 -1
  452. package/client/dist/assets/settings-DAZqjX2a.js +0 -1
  453. package/client/dist/assets/settings-DRh39v1S.js +0 -1
  454. package/client/dist/assets/settings-Mj1OJbfd.js +0 -1
  455. package/client/dist/assets/settings-lRReaSYm.js +0 -1
  456. package/client/dist/assets/setup-3832BJCo.js +0 -1
  457. package/client/dist/assets/setup-B8J-gECe.js +0 -1
  458. package/client/dist/assets/setup-BCIOxVsc.js +0 -1
  459. package/client/dist/assets/setup-BciLj_tU.js +0 -1
  460. package/client/dist/assets/setup-CTkE3cfh.js +0 -1
  461. package/client/dist/assets/setup-ajB4rYm-.js +0 -1
  462. package/client/dist/assets/setup-xFO1wNl0.js +0 -1
@@ -11,8 +11,10 @@ const cli_prompt_1 = require("./util/cli-prompt");
11
11
  const db_1 = require("./db");
12
12
  const command_resolver_1 = require("./command-resolver");
13
13
  const providers_1 = require("./providers");
14
+ const runtime_1 = require("./providers/runtime");
14
15
  const result_event_1 = require("./result-event");
15
16
  const ai_invocations_1 = require("./ai-invocations");
17
+ const workspace_resolution_1 = require("./workspace-resolution");
16
18
  // ─── ProposalManager ──────────────────────────────────────────────────────────
17
19
  class ProposalManager {
18
20
  _broadcast;
@@ -34,16 +36,56 @@ class ProposalManager {
34
36
  * HIGH-6). Optional so pre-wiring call sites keep compiling; recording only
35
37
  * fires when present (the DB is always available on this manager). */
36
38
  _projectId;
37
- /** claude adapter — the proposal flows only ever spawn claude. */
38
- _adapter = (0, providers_1.getAdapter)('claude');
39
- constructor(broadcast, db, cwd, projectId) {
39
+ _projectSlug;
40
+ _adapter;
41
+ constructor(broadcast, db, cwd, projectId, providerId = 'claude', projectSlug) {
40
42
  this._broadcast = broadcast;
41
43
  this._db = db;
42
44
  this._cwd = cwd;
43
45
  this._projectId = projectId;
46
+ this._projectSlug = projectSlug;
47
+ this._adapter = (0, providers_1.getAdapter)(providerId);
44
48
  this._activeProcesses = new Map();
45
49
  this._buffers = new Map();
46
50
  }
51
+ /** Resolve lazily because a project context is created before Core may
52
+ * populate its relocated workspace during setup. */
53
+ _execution() {
54
+ return (0, workspace_resolution_1.resolveProjectExecution)({ slug: this._projectSlug, path: this._cwd });
55
+ }
56
+ /**
57
+ * Synchronous route preflight for `/propose`. It deliberately uses the same
58
+ * provider-aware command resolution and lazy execution cwd as the real spawn:
59
+ * Claude resolves installed command markdown, Codex rewrites its native
60
+ * prompt invocation, and Kimi materializes the direct-child SKILL.md.
61
+ */
62
+ canStartExploration() {
63
+ const execution = this._execution();
64
+ const rawCommand = '/specrails:propose-feature test';
65
+ try {
66
+ const resolved = this._adapter.capabilities.materializeHeadlessSkills
67
+ ? rawCommand
68
+ : (0, command_resolver_1.resolveCommand)(rawCommand, execution.cwd);
69
+ const prompt = resolved === rawCommand
70
+ ? (0, runtime_1.formatProviderCommand)(this._adapter, rawCommand, execution.cwd)
71
+ : resolved;
72
+ return prompt !== rawCommand;
73
+ }
74
+ catch {
75
+ return false;
76
+ }
77
+ }
78
+ _spawnOptions(execution, options) {
79
+ if (!execution.relocated)
80
+ return options;
81
+ return {
82
+ ...options,
83
+ extraArgs: [
84
+ ...(options.extraArgs ?? []),
85
+ ...(0, runtime_1.buildProviderRepoAccessArgs)(this._adapter, [execution.repoDir]),
86
+ ],
87
+ };
88
+ }
47
89
  /**
48
90
  * Persist one surface='proposal' ai_invocations row per spawn (exploration,
49
91
  * each refinement turn, and issue creation are all separate billable claude
@@ -56,8 +98,10 @@ class ProposalManager {
56
98
  if (!this._projectId)
57
99
  return;
58
100
  try {
101
+ const finishedAt = new Date().toISOString();
59
102
  const { result, estimated } = (0, result_event_1.finaliseInvocationResult)(this._adapter, events, {
60
103
  fallbackModel: this._adapter.defaultModel(),
104
+ durationMs: Math.max(0, Date.parse(finishedAt) - Date.parse(startedAtIso)),
61
105
  });
62
106
  (0, ai_invocations_1.recordInvocation)(this._db, {
63
107
  id: (0, crypto_1.randomUUID)(),
@@ -67,7 +111,7 @@ class ProposalManager {
67
111
  surface_ref_id: proposalId,
68
112
  status,
69
113
  started_at: startedAtIso,
70
- finished_at: new Date().toISOString(),
114
+ finished_at: finishedAt,
71
115
  total_cost_usd_estimated: estimated,
72
116
  ...result,
73
117
  });
@@ -132,22 +176,35 @@ class ProposalManager {
132
176
  return;
133
177
  }
134
178
  // Resolve the command file — error if not installed
179
+ const execution = this._execution();
135
180
  const rawCommand = `/specrails:propose-feature ${idea}`;
136
- const prompt = (0, command_resolver_1.resolveCommand)(rawCommand, this._cwd);
181
+ const resolved = this._adapter.capabilities.materializeHeadlessSkills
182
+ ? rawCommand
183
+ : (0, command_resolver_1.resolveCommand)(rawCommand, execution.cwd);
184
+ let prompt;
185
+ try {
186
+ prompt = resolved === rawCommand
187
+ ? (0, runtime_1.formatProviderCommand)(this._adapter, rawCommand, execution.cwd)
188
+ : resolved;
189
+ }
190
+ catch (error) {
191
+ (0, db_1.updateProposal)(this._db, proposalId, { status: 'cancelled' });
192
+ this._broadcastError(proposalId, error instanceof Error ? error.message : String(error));
193
+ return;
194
+ }
137
195
  if (prompt === rawCommand) {
138
196
  (0, db_1.updateProposal)(this._db, proposalId, { status: 'cancelled' });
139
197
  this._broadcastError(proposalId, 'This project does not have the /specrails:propose-feature command installed. Run "npx specrails-core@latest" to update.');
140
198
  return;
141
199
  }
142
200
  (0, db_1.updateProposal)(this._db, proposalId, { status: 'exploring' });
143
- const args = [
144
- '--dangerously-skip-permissions',
145
- '--tools', 'default',
146
- '--output-format', 'stream-json',
147
- '--verbose',
148
- '-p', prompt,
149
- ];
150
- await this._runProcess(proposalId, args, (fullText, sessionId) => {
201
+ const spawnOptions = this._spawnOptions(execution, {
202
+ prompt,
203
+ model: this._adapter.defaultModel(),
204
+ toolPolicy: 'default',
205
+ });
206
+ const args = this._adapter.buildArgs('spec-gen', spawnOptions);
207
+ await this._runProcess(proposalId, args, spawnOptions, execution, (fullText, sessionId) => {
151
208
  (0, db_1.updateProposal)(this._db, proposalId, {
152
209
  status: 'review',
153
210
  result_markdown: fullText,
@@ -160,9 +217,9 @@ class ProposalManager {
160
217
  markdown: fullText,
161
218
  timestamp: new Date().toISOString(),
162
219
  });
163
- }, () => {
220
+ }, (error) => {
164
221
  (0, db_1.updateProposal)(this._db, proposalId, { status: 'input' });
165
- this._broadcastError(proposalId, 'Exploration failed');
222
+ this._broadcastError(proposalId, error ?? 'Exploration failed');
166
223
  });
167
224
  }
168
225
  async sendRefinement(proposalId, feedback) {
@@ -176,15 +233,15 @@ class ProposalManager {
176
233
  return;
177
234
  }
178
235
  (0, db_1.updateProposal)(this._db, proposalId, { status: 'refining' });
179
- const args = [
180
- '--dangerously-skip-permissions',
181
- '--tools', 'default',
182
- '--output-format', 'stream-json',
183
- '--verbose',
184
- '--resume', proposal.session_id,
185
- '-p', feedback,
186
- ];
187
- await this._runProcess(proposalId, args, (fullText, sessionId) => {
236
+ const execution = this._execution();
237
+ const spawnOptions = this._spawnOptions(execution, {
238
+ prompt: feedback,
239
+ model: this._adapter.defaultModel(),
240
+ sessionId: proposal.session_id,
241
+ toolPolicy: 'default',
242
+ });
243
+ const args = this._adapter.buildArgs('chat-resume', spawnOptions);
244
+ await this._runProcess(proposalId, args, spawnOptions, execution, (fullText, sessionId) => {
188
245
  (0, db_1.updateProposal)(this._db, proposalId, {
189
246
  status: 'review',
190
247
  result_markdown: fullText,
@@ -197,9 +254,9 @@ class ProposalManager {
197
254
  markdown: fullText,
198
255
  timestamp: new Date().toISOString(),
199
256
  });
200
- }, () => {
257
+ }, (error) => {
201
258
  (0, db_1.updateProposal)(this._db, proposalId, { status: 'review' });
202
- this._broadcastError(proposalId, 'Refinement failed');
259
+ this._broadcastError(proposalId, error ?? 'Refinement failed');
203
260
  });
204
261
  }
205
262
  async createIssue(proposalId) {
@@ -215,15 +272,15 @@ class ProposalManager {
215
272
  (0, db_1.updateProposal)(this._db, proposalId, { status: 'refining' });
216
273
  const prompt = "Based on the proposal above, create a GitHub Issue with the label 'user-proposed'. " +
217
274
  "Output only the URL of the created issue on the last line of your response.";
218
- const args = [
219
- '--dangerously-skip-permissions',
220
- '--tools', 'default',
221
- '--output-format', 'stream-json',
222
- '--verbose',
223
- '--resume', proposal.session_id,
224
- '-p', prompt,
225
- ];
226
- await this._runProcess(proposalId, args, (fullText, sessionId) => {
275
+ const execution = this._execution();
276
+ const spawnOptions = this._spawnOptions(execution, {
277
+ prompt,
278
+ model: this._adapter.defaultModel(),
279
+ sessionId: proposal.session_id,
280
+ toolPolicy: 'default',
281
+ });
282
+ const args = this._adapter.buildArgs('chat-resume', spawnOptions);
283
+ await this._runProcess(proposalId, args, spawnOptions, execution, (fullText, sessionId) => {
227
284
  const match = fullText.match(/https:\/\/github\.com\/[^\s]+\/issues\/\d+/);
228
285
  const issueUrl = match ? match[0] : null;
229
286
  if (issueUrl) {
@@ -244,9 +301,9 @@ class ProposalManager {
244
301
  (0, db_1.updateProposal)(this._db, proposalId, { status: 'review' });
245
302
  this._broadcastError(proposalId, 'Issue creation failed — GitHub CLI may not be available or not authenticated');
246
303
  }
247
- }, () => {
304
+ }, (error) => {
248
305
  (0, db_1.updateProposal)(this._db, proposalId, { status: 'review' });
249
- this._broadcastError(proposalId, 'Issue creation failed');
306
+ this._broadcastError(proposalId, error ?? 'Issue creation failed');
250
307
  });
251
308
  }
252
309
  cancel(proposalId) {
@@ -267,12 +324,14 @@ class ProposalManager {
267
324
  });
268
325
  }
269
326
  // ─── Private helpers ───────────────────────────────────────────────────────
270
- async _runProcess(proposalId, args, onSuccess, onError) {
271
- // spawnClaude reroutes multi-line argv values through stdin on Windows.
272
- const child = (0, cli_prompt_1.spawnClaude)(args, {
273
- env: process.env,
327
+ async _runProcess(proposalId, args, spawnOptions, execution, onSuccess, onError) {
328
+ const child = (0, cli_prompt_1.spawnAiCli)(this._adapter.binary, args, {
329
+ env: (0, runtime_1.buildProviderEnv)(this._adapter, spawnOptions, {
330
+ ...process.env,
331
+ ...execution.env,
332
+ }),
274
333
  stdio: ['ignore', 'pipe', 'pipe'],
275
- cwd: this._cwd,
334
+ cwd: execution.cwd,
276
335
  });
277
336
  this._activeProcesses.set(proposalId, child);
278
337
  this._buffers.set(proposalId, '');
@@ -283,33 +342,17 @@ class ProposalManager {
283
342
  const turnStartedAt = new Date().toISOString();
284
343
  const stdoutReader = (0, readline_1.createInterface)({ input: child.stdout, crlfDelay: Infinity });
285
344
  stdoutReader.on('line', (line) => {
286
- if (this._projectId) {
287
- const ev = this._adapter.parseStreamLine(line);
288
- if (ev)
289
- adapterEvents.push(ev);
290
- }
291
- let parsed = null;
292
- try {
293
- parsed = JSON.parse(line);
294
- }
295
- catch { /* skip non-JSON */ }
296
- if (!parsed)
297
- return;
298
- const eventType = parsed.type;
299
- if (eventType === 'result') {
300
- const sid = parsed.session_id;
301
- if (sid)
302
- capturedSessionId = sid;
303
- }
304
- if (eventType === 'assistant') {
305
- const msg = parsed.message;
306
- const blocks = msg?.content ?? [];
307
- // Extract text from text blocks (skip thinking blocks)
308
- const texts = blocks
309
- .filter((c) => c.type === 'text')
310
- .map((c) => c.text ?? '');
311
- const newText = texts.join('');
312
- if (newText) {
345
+ for (const ev of (0, runtime_1.parseStreamEvents)(this._adapter, line)) {
346
+ adapterEvents.push(ev);
347
+ if (ev.kind === 'session-started')
348
+ capturedSessionId = ev.sessionId;
349
+ if (ev.kind === 'result') {
350
+ const sid = ev.payload.session_id;
351
+ if (sid)
352
+ capturedSessionId = sid;
353
+ }
354
+ if (ev.kind === 'text-delta') {
355
+ const newText = ev.text;
313
356
  const prev = this._buffers.get(proposalId) ?? '';
314
357
  this._buffers.set(proposalId, prev + newText);
315
358
  this._broadcast({
@@ -320,17 +363,14 @@ class ProposalManager {
320
363
  timestamp: new Date().toISOString(),
321
364
  });
322
365
  }
323
- // Broadcast tool_use activity so the UI can show "reading codebase..."
324
- for (const block of blocks) {
325
- if (block.type === 'tool_use' && block.name) {
326
- this._broadcast({
327
- type: 'proposal_stream',
328
- projectId: '',
329
- proposalId,
330
- delta: `<!--tool:${block.name}-->`,
331
- timestamp: new Date().toISOString(),
332
- });
333
- }
366
+ else if (ev.kind === 'tool-use') {
367
+ this._broadcast({
368
+ type: 'proposal_stream',
369
+ projectId: '',
370
+ proposalId,
371
+ delta: `<!--tool:${ev.name}-->`,
372
+ timestamp: new Date().toISOString(),
373
+ });
334
374
  }
335
375
  }
336
376
  });
@@ -357,8 +397,7 @@ class ProposalManager {
357
397
  resolve();
358
398
  return;
359
399
  } // M12: project removed mid-flight; DB closing
360
- this._broadcastError(proposalId, `Failed to launch claude: ${err.message}`);
361
- onError();
400
+ onError(`Failed to launch ${this._adapter.binary}: ${err.message}`);
362
401
  resolve();
363
402
  });
364
403
  /* c8 ignore stop */
@@ -368,12 +407,13 @@ class ProposalManager {
368
407
  this._activeProcesses.delete(proposalId);
369
408
  this._buffers.delete(proposalId);
370
409
  const wasCancelled = this._cancelledIds.delete(proposalId);
410
+ const providerError = adapterEvents.find((event) => event.kind === 'error')?.message;
371
411
  // Record the spend regardless of cancel/done outcome (the tokens were
372
412
  // burned either way) — but NOT when the project is being torn down, since
373
413
  // its DB is closing (recordInvocation would throw). Cancel/kill → aborted;
374
414
  // non-zero exit → failed; clean exit → success (HIGH-6).
375
415
  if (!this._disposed) {
376
- const status = wasCancelled ? 'aborted' : code === 0 ? 'success' : 'failed';
416
+ const status = wasCancelled ? 'aborted' : code === 0 && !providerError ? 'success' : 'failed';
377
417
  this._recordInvocation(proposalId, adapterEvents, status, turnStartedAt);
378
418
  }
379
419
  // A cancel() killed this child intentionally; its non-zero exit must NOT
@@ -386,11 +426,11 @@ class ProposalManager {
386
426
  resolve();
387
427
  return;
388
428
  } // M12: project removed mid-flight; DB closing
389
- if (code === 0) {
429
+ if (code === 0 && !providerError) {
390
430
  onSuccess(fullText, capturedSessionId);
391
431
  }
392
432
  else {
393
- onError();
433
+ onError(providerError);
394
434
  }
395
435
  resolve();
396
436
  });
@@ -6,10 +6,14 @@
6
6
  // later tasks (see openspec/changes/add-multi-provider-support/tasks.md §2.x).
7
7
  //
8
8
  // Spec: openspec/specs/multi-provider-architecture/spec.md
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
9
12
  Object.defineProperty(exports, "__esModule", { value: true });
10
13
  exports.claudeAdapter = void 0;
11
14
  exports._normaliseClaudeModel = normaliseModel;
12
15
  const child_process_1 = require("child_process");
16
+ const path_1 = __importDefault(require("path"));
13
17
  const WHICH_CMD = process.platform === 'win32' ? 'where' : 'which';
14
18
  const CLAUDE_MODELS = [
15
19
  { value: 'sonnet', label: 'Claude Sonnet', default: true },
@@ -398,12 +402,22 @@ exports.claudeAdapter = {
398
402
  supportsReasoningEffort: true,
399
403
  reasoningEfforts: ['low', 'medium', 'high', 'xhigh'], // claude-code --effort tiers
400
404
  supportsImageInput: true, // images ride as `@<abs-path>` prompt refs
405
+ structuredActions: true,
406
+ toolPolicies: ['none', 'read-only'],
407
+ profiles: true,
408
+ customRoles: true,
409
+ freestyle: true,
410
+ userMcp: true,
401
411
  },
402
412
  modelCatalog: () => CLAUDE_MODELS,
403
413
  defaultModel: () => 'sonnet',
404
414
  buildArgs: buildClaudeArgs,
405
415
  parseStreamLine: parseClaudeStreamLine,
406
416
  extractResult: extractClaudeResult,
417
+ formatCoreCommand: (command) => command,
418
+ buildRepoAccessArgs: (paths) => paths.flatMap((repoPath) => ['--add-dir', repoPath]),
419
+ projectMcpPath: (root) => path_1.default.join(root, '.mcp.json'),
420
+ customRolePath: (root, roleId) => path_1.default.join(root, '.claude', 'agents', `${roleId}.md`),
407
421
  baselineAgents: () => ['sr-architect', 'sr-developer', 'sr-reviewer'],
408
422
  detectInstalled: detectClaudeInstalled,
409
423
  };
@@ -25,10 +25,14 @@
25
25
  // synthesised by server/codex-otel-bridge.ts.
26
26
  //
27
27
  // Spec: openspec/specs/multi-provider-architecture/spec.md
28
+ var __importDefault = (this && this.__importDefault) || function (mod) {
29
+ return (mod && mod.__esModule) ? mod : { "default": mod };
30
+ };
28
31
  Object.defineProperty(exports, "__esModule", { value: true });
29
32
  exports._CODEX_MIN_VERSION = exports.codexAdapter = void 0;
30
33
  exports._compareSemver = compareSemver;
31
34
  const child_process_1 = require("child_process");
35
+ const path_1 = __importDefault(require("path"));
32
36
  const WHICH_CMD = process.platform === 'win32' ? 'where' : 'which';
33
37
  const CODEX_MIN_VERSION = '0.128.0';
34
38
  exports._CODEX_MIN_VERSION = CODEX_MIN_VERSION;
@@ -348,12 +352,28 @@ exports.codexAdapter = {
348
352
  // tiers); ultra is Sol-only upstream — codex validates the combo itself.
349
353
  reasoningEfforts: ['minimal', 'low', 'medium', 'high', 'xhigh', 'max', 'ultra'],
350
354
  supportsImageInput: true, // codex-cli `-i/--image <FILE>...` (verified 0.141)
355
+ structuredActions: false,
356
+ // Codex has an enforced read-only sandbox, but no true "no tools" mode in
357
+ // this adapter (workspace-write is not an output-only boundary).
358
+ toolPolicies: ['read-only'],
359
+ profiles: false,
360
+ customRoles: false,
361
+ freestyle: false,
362
+ userMcp: false,
351
363
  },
352
364
  modelCatalog: () => CODEX_MODELS,
353
365
  defaultModel: () => 'gpt-5.5',
354
366
  buildArgs: buildCodexArgs,
355
367
  parseStreamLine: parseCodexStreamLine,
356
368
  extractResult: extractCodexResult,
369
+ formatCoreCommand: (command) => command.replace(/^\/(?:specrails|sr):([\w-]+)/, '$$$1'),
370
+ buildRepoAccessArgs: (paths) => paths.length === 0
371
+ ? []
372
+ : [
373
+ '-c',
374
+ `sandbox_workspace_write.writable_roots=[${paths.map((repoPath) => JSON.stringify(repoPath)).join(', ')}]`,
375
+ ],
376
+ customRolePath: (root, roleId) => path_1.default.join(root, '.codex', 'skills', 'rails', roleId, 'SKILL.md'),
357
377
  baselineAgents: () => ['sr-architect', 'sr-developer', 'sr-reviewer'],
358
378
  detectInstalled: detectCodexInstalled,
359
379
  };
@@ -25,10 +25,14 @@
25
25
  // fixtures before the gate is removed. Parsing is tolerant of missing fields.
26
26
  //
27
27
  // Spec: openspec/specs/multi-provider-architecture/spec.md
28
+ var __importDefault = (this && this.__importDefault) || function (mod) {
29
+ return (mod && mod.__esModule) ? mod : { "default": mod };
30
+ };
28
31
  Object.defineProperty(exports, "__esModule", { value: true });
29
32
  exports._GEMINI_MIN_VERSION = exports.geminiAdapter = void 0;
30
33
  exports._compareSemver = compareSemver;
31
34
  const child_process_1 = require("child_process");
35
+ const path_1 = __importDefault(require("path"));
32
36
  const win_spawn_1 = require("../util/win-spawn");
33
37
  const gemini_agent_ack_1 = require("./gemini-agent-ack");
34
38
  const WHICH_CMD = process.platform === 'win32' ? 'where' : 'which';
@@ -245,12 +249,22 @@ exports.geminiAdapter = {
245
249
  // No dedicated image flag; `@path` in the prompt is unverified for vision
246
250
  // under `-p`. Disabled until a live smoke-test passes (design D22).
247
251
  supportsImageInput: false,
252
+ structuredActions: false,
253
+ // Gemini plan approval mode is verified read-only; its existing `none`
254
+ // path maps to --yolo and therefore is not an output-only boundary.
255
+ toolPolicies: ['read-only'],
256
+ profiles: false,
257
+ customRoles: false,
258
+ freestyle: false,
259
+ userMcp: false,
248
260
  },
249
261
  modelCatalog: () => GEMINI_MODELS,
250
262
  defaultModel: () => 'gemini-3.5-flash',
251
263
  buildArgs: buildGeminiArgs,
252
264
  parseStreamLine: parseGeminiStreamLine,
253
265
  extractResult: extractGeminiResult,
266
+ projectMcpPath: (root) => path_1.default.join(root, '.gemini', 'settings.json'),
267
+ customRolePath: (root, roleId) => path_1.default.join(root, '.gemini', 'agents', `${roleId}.md`),
254
268
  baselineAgents: () => ['sr-architect', 'sr-developer', 'sr-reviewer'],
255
269
  detectInstalled: detectGeminiInstalled,
256
270
  // Pre-acknowledge the project's custom subagents so they load in headless
@@ -7,7 +7,7 @@
7
7
  //
8
8
  // Spec: openspec/specs/multi-provider-architecture/spec.md
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.UnknownProviderError = exports.geminiAdapter = exports.codexAdapter = exports.claudeAdapter = exports.listAdapters = exports.hasAdapter = exports.getAdapter = void 0;
10
+ exports.UnknownProviderError = exports.CUSTOM_MODEL_ALIAS_MAX_LENGTH = exports.isSafeCustomModelAlias = exports.isModelAvailableForAdapter = exports.isReasoningEffortValidForModel = exports.defaultReasoningEffortForModel = exports.reasoningEffortsForModel = exports.requireToolPolicy = exports.pureOutputToolPolicy = exports.supportsToolPolicy = exports.parseStreamEvents = exports.buildProviderRepoAccessArgs = exports.formatProviderCommand = exports.buildProviderEnv = exports.kimiAdapter = exports.geminiAdapter = exports.codexAdapter = exports.claudeAdapter = exports.listAdapters = exports.hasAdapter = exports.getAdapter = void 0;
11
11
  const registry_1 = require("./registry");
12
12
  const claude_adapter_1 = require("./claude-adapter");
13
13
  Object.defineProperty(exports, "claudeAdapter", { enumerable: true, get: function () { return claude_adapter_1.claudeAdapter; } });
@@ -15,12 +15,29 @@ const codex_adapter_1 = require("./codex-adapter");
15
15
  Object.defineProperty(exports, "codexAdapter", { enumerable: true, get: function () { return codex_adapter_1.codexAdapter; } });
16
16
  const gemini_adapter_1 = require("./gemini-adapter");
17
17
  Object.defineProperty(exports, "geminiAdapter", { enumerable: true, get: function () { return gemini_adapter_1.geminiAdapter; } });
18
+ const kimi_adapter_1 = require("./kimi-adapter");
19
+ Object.defineProperty(exports, "kimiAdapter", { enumerable: true, get: function () { return kimi_adapter_1.kimiAdapter; } });
18
20
  (0, registry_1.register)(claude_adapter_1.claudeAdapter);
19
21
  (0, registry_1.register)(codex_adapter_1.codexAdapter);
20
22
  (0, registry_1.register)(gemini_adapter_1.geminiAdapter);
23
+ (0, registry_1.register)(kimi_adapter_1.kimiAdapter);
21
24
  var registry_2 = require("./registry");
22
25
  Object.defineProperty(exports, "getAdapter", { enumerable: true, get: function () { return registry_2.getAdapter; } });
23
26
  Object.defineProperty(exports, "hasAdapter", { enumerable: true, get: function () { return registry_2.hasAdapter; } });
24
27
  Object.defineProperty(exports, "listAdapters", { enumerable: true, get: function () { return registry_2.listAdapters; } });
28
+ var runtime_1 = require("./runtime");
29
+ Object.defineProperty(exports, "buildProviderEnv", { enumerable: true, get: function () { return runtime_1.buildProviderEnv; } });
30
+ Object.defineProperty(exports, "formatProviderCommand", { enumerable: true, get: function () { return runtime_1.formatProviderCommand; } });
31
+ Object.defineProperty(exports, "buildProviderRepoAccessArgs", { enumerable: true, get: function () { return runtime_1.buildProviderRepoAccessArgs; } });
32
+ Object.defineProperty(exports, "parseStreamEvents", { enumerable: true, get: function () { return runtime_1.parseStreamEvents; } });
33
+ Object.defineProperty(exports, "supportsToolPolicy", { enumerable: true, get: function () { return runtime_1.supportsToolPolicy; } });
34
+ Object.defineProperty(exports, "pureOutputToolPolicy", { enumerable: true, get: function () { return runtime_1.pureOutputToolPolicy; } });
35
+ Object.defineProperty(exports, "requireToolPolicy", { enumerable: true, get: function () { return runtime_1.requireToolPolicy; } });
36
+ Object.defineProperty(exports, "reasoningEffortsForModel", { enumerable: true, get: function () { return runtime_1.reasoningEffortsForModel; } });
37
+ Object.defineProperty(exports, "defaultReasoningEffortForModel", { enumerable: true, get: function () { return runtime_1.defaultReasoningEffortForModel; } });
38
+ Object.defineProperty(exports, "isReasoningEffortValidForModel", { enumerable: true, get: function () { return runtime_1.isReasoningEffortValidForModel; } });
39
+ Object.defineProperty(exports, "isModelAvailableForAdapter", { enumerable: true, get: function () { return runtime_1.isModelAvailableForAdapter; } });
40
+ Object.defineProperty(exports, "isSafeCustomModelAlias", { enumerable: true, get: function () { return runtime_1.isSafeCustomModelAlias; } });
41
+ Object.defineProperty(exports, "CUSTOM_MODEL_ALIAS_MAX_LENGTH", { enumerable: true, get: function () { return runtime_1.CUSTOM_MODEL_ALIAS_MAX_LENGTH; } });
25
42
  var types_1 = require("./types");
26
43
  Object.defineProperty(exports, "UnknownProviderError", { enumerable: true, get: function () { return types_1.UnknownProviderError; } });