specrails-desktop 2.8.0 → 2.9.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 (326) hide show
  1. package/README.md +23 -19
  2. package/client/dist/assets/{ActivityFeedPage-LKqd18-G.js → ActivityFeedPage-DNqnf1fZ.js} +1 -1
  3. package/client/dist/assets/{AgentsPage-Cb-b-6Ot.js → AgentsPage-vmNIEbGM.js} +1 -1
  4. package/client/dist/assets/{AnalyticsPage-HVxQQ1wy.js → AnalyticsPage-CdfN0ofZ.js} +1 -1
  5. package/client/dist/assets/{BarChart-BOyHB0dw.js → BarChart-CIkopHjl.js} +1 -1
  6. package/client/dist/assets/{CodePage-DnOnwKGB.js → CodePage-DDRNU5FN.js} +1 -1
  7. package/client/dist/assets/{DesktopAnalyticsPage-D2auU39x.js → DesktopAnalyticsPage-Cl3sKKSG.js} +1 -1
  8. package/client/dist/assets/{DocsDialog-CTuDX3GK.js → DocsDialog-BGrBOfUr.js} +2 -2
  9. package/client/dist/assets/{DocsPage-DRyMmu0Z.js → DocsPage-CY-2SSzw.js} +2 -2
  10. package/client/dist/assets/{ExportDropdown-DO-GGiMh.js → ExportDropdown-BRHcvP0r.js} +1 -1
  11. package/client/dist/assets/{IntegrationsPage-BhbO4jFT.js → IntegrationsPage-nKdLB4Ub.js} +1 -1
  12. package/client/dist/assets/{JobDetailPage-DJooEg1s.js → JobDetailPage-Bf0A6WWQ.js} +1 -1
  13. package/client/dist/assets/{JobsPage-BbaC-YOg.js → JobsPage-Vg4nXPdL.js} +1 -1
  14. package/client/dist/assets/{dist-js-CiIVMsx3.js → dist-js-0i_klubI.js} +1 -1
  15. package/client/dist/assets/{dist-js-Xc2lRKp2.js → dist-js-CUs5GjwA.js} +1 -1
  16. package/client/dist/assets/{index-DK214dak.js → index-BXoHFtfG.js} +8 -8
  17. package/client/dist/assets/index-D6BaYRRU.css +2 -0
  18. package/client/dist/assets/{integrations-2C7MkGT0.js → integrations-7YyTBuU9.js} +1 -1
  19. package/client/dist/assets/{integrations-CX4p_bij.js → integrations-B9CEpNF0.js} +1 -1
  20. package/client/dist/assets/{integrations-C2jQtv-s.js → integrations-BlvAdewo.js} +1 -1
  21. package/client/dist/assets/{integrations-eQPHAYsE.js → integrations-Bw8UM9Xd.js} +1 -1
  22. package/client/dist/assets/{integrations-BDC670cg.js → integrations-C5SxNKnG.js} +1 -1
  23. package/client/dist/assets/{integrations-BqUmRUef.js → integrations-CJQKMmdW.js} +1 -1
  24. package/client/dist/assets/{integrations-CB98NeH5.js → integrations-DWz1eU_K.js} +1 -1
  25. package/client/dist/assets/{integrations-_SuVeQIG.js → integrations-DiPR8Fzp.js} +1 -1
  26. package/client/dist/assets/{lib-Bo5s6xpe.js → lib-D6M_MvoC.js} +1 -1
  27. package/client/dist/assets/setup-B6egeeTM.js +1 -0
  28. package/client/dist/assets/setup-BHroXlke.js +1 -0
  29. package/client/dist/assets/setup-BIXsWUp1.js +1 -0
  30. package/client/dist/assets/setup-BJRdg1iE.js +1 -0
  31. package/client/dist/assets/setup-C0rVGnCy.js +1 -0
  32. package/client/dist/assets/setup-Cpu17hJv.js +1 -0
  33. package/client/dist/assets/setup-D-1r0uSx.js +1 -0
  34. package/client/dist/assets/setup-Dn2-veYO.js +1 -0
  35. package/client/dist/assets/{useProjectCache-DVNypkmR.js → useProjectCache-BeyBSNpD.js} +1 -1
  36. package/client/dist/index.html +4 -4
  37. package/docs/README.md +5 -2
  38. package/docs/agy-cli-provider-study.md +78 -0
  39. package/docs/cli.md +23 -4
  40. package/docs/codex.md +116 -58
  41. package/docs/creating-specs.md +19 -5
  42. package/docs/customizing.md +27 -6
  43. package/docs/gemini.md +225 -73
  44. package/docs/getting-started.md +18 -9
  45. package/docs/guide/de/agents/1-meet-the-agents.md +38 -0
  46. package/docs/guide/de/agents/2-profiles-and-the-balanced-default.md +45 -0
  47. package/docs/guide/de/agents/3-customizing-models-per-agent.md +60 -0
  48. package/docs/guide/de/agents/4-custom-agents-catalog.md +43 -0
  49. package/docs/guide/de/getting-started/1-what-is-specrails.md +49 -0
  50. package/docs/guide/de/getting-started/2-installing-and-first-run.md +42 -0
  51. package/docs/guide/de/getting-started/3-adding-your-first-project.md +58 -0
  52. package/docs/guide/de/getting-started/4-the-dashboard-tour.md +53 -0
  53. package/docs/guide/de/insights/1-analytics-and-cost-tracking.md +78 -0
  54. package/docs/guide/de/insights/2-the-integrated-terminal.md +46 -0
  55. package/docs/guide/de/insights/3-code-explorer.md +50 -0
  56. package/docs/guide/de/integrations/1-ai-providers.md +64 -0
  57. package/docs/guide/de/integrations/2-plugins.md +44 -0
  58. package/docs/guide/de/integrations/3-jira-integration.md +71 -0
  59. package/docs/guide/de/integrations/4-mobile-companion.md +38 -0
  60. package/docs/guide/de/pipeline/1-rails-and-jobs.md +94 -0
  61. package/docs/guide/de/pipeline/2-the-job-detail-view.md +90 -0
  62. package/docs/guide/de/pipeline/3-batch-implement-and-multi-feature.md +78 -0
  63. package/docs/guide/de/pipeline/4-picking-an-engine-per-rail.md +60 -0
  64. package/docs/guide/de/settings/1-themes.md +37 -0
  65. package/docs/guide/de/settings/2-language.md +39 -0
  66. package/docs/guide/de/settings/3-pipeline-telemetry-and-diagnostics.md +46 -0
  67. package/docs/guide/de/settings/4-where-your-data-lives.md +48 -0
  68. package/docs/guide/de/specs/1-specs-and-the-backlog.md +52 -0
  69. package/docs/guide/de/specs/2-add-spec-quick-mode.md +45 -0
  70. package/docs/guide/de/specs/3-add-spec-explore-mode.md +68 -0
  71. package/docs/guide/de/specs/4-drafts-and-contract-layer.md +81 -0
  72. package/docs/guide/en/agents/1-meet-the-agents.md +38 -0
  73. package/docs/guide/en/agents/2-profiles-and-the-balanced-default.md +45 -0
  74. package/docs/guide/en/agents/3-customizing-models-per-agent.md +60 -0
  75. package/docs/guide/en/agents/4-custom-agents-catalog.md +43 -0
  76. package/docs/guide/en/getting-started/1-what-is-specrails.md +49 -0
  77. package/docs/guide/en/getting-started/2-installing-and-first-run.md +42 -0
  78. package/docs/guide/en/getting-started/3-adding-your-first-project.md +58 -0
  79. package/docs/guide/en/getting-started/4-the-dashboard-tour.md +53 -0
  80. package/docs/guide/en/insights/1-analytics-and-cost-tracking.md +78 -0
  81. package/docs/guide/en/insights/2-the-integrated-terminal.md +46 -0
  82. package/docs/guide/en/insights/3-code-explorer.md +50 -0
  83. package/docs/guide/en/integrations/1-ai-providers.md +64 -0
  84. package/docs/guide/en/integrations/2-plugins.md +44 -0
  85. package/docs/guide/en/integrations/3-jira-integration.md +71 -0
  86. package/docs/guide/en/integrations/4-mobile-companion.md +38 -0
  87. package/docs/guide/en/pipeline/1-rails-and-jobs.md +94 -0
  88. package/docs/guide/en/pipeline/2-the-job-detail-view.md +90 -0
  89. package/docs/guide/en/pipeline/3-batch-implement-and-multi-feature.md +78 -0
  90. package/docs/guide/en/pipeline/4-picking-an-engine-per-rail.md +60 -0
  91. package/docs/guide/en/settings/1-themes.md +37 -0
  92. package/docs/guide/en/settings/2-language.md +39 -0
  93. package/docs/guide/en/settings/3-pipeline-telemetry-and-diagnostics.md +46 -0
  94. package/docs/guide/en/settings/4-where-your-data-lives.md +48 -0
  95. package/docs/guide/en/specs/1-specs-and-the-backlog.md +52 -0
  96. package/docs/guide/en/specs/2-add-spec-quick-mode.md +45 -0
  97. package/docs/guide/en/specs/3-add-spec-explore-mode.md +68 -0
  98. package/docs/guide/en/specs/4-drafts-and-contract-layer.md +81 -0
  99. package/docs/guide/es/agents/1-meet-the-agents.md +38 -0
  100. package/docs/guide/es/agents/2-profiles-and-the-balanced-default.md +45 -0
  101. package/docs/guide/es/agents/3-customizing-models-per-agent.md +60 -0
  102. package/docs/guide/es/agents/4-custom-agents-catalog.md +43 -0
  103. package/docs/guide/es/getting-started/1-what-is-specrails.md +49 -0
  104. package/docs/guide/es/getting-started/2-installing-and-first-run.md +42 -0
  105. package/docs/guide/es/getting-started/3-adding-your-first-project.md +58 -0
  106. package/docs/guide/es/getting-started/4-the-dashboard-tour.md +53 -0
  107. package/docs/guide/es/insights/1-analytics-and-cost-tracking.md +78 -0
  108. package/docs/guide/es/insights/2-the-integrated-terminal.md +46 -0
  109. package/docs/guide/es/insights/3-code-explorer.md +50 -0
  110. package/docs/guide/es/integrations/1-ai-providers.md +64 -0
  111. package/docs/guide/es/integrations/2-plugins.md +44 -0
  112. package/docs/guide/es/integrations/3-jira-integration.md +71 -0
  113. package/docs/guide/es/integrations/4-mobile-companion.md +38 -0
  114. package/docs/guide/es/pipeline/1-rails-and-jobs.md +94 -0
  115. package/docs/guide/es/pipeline/2-the-job-detail-view.md +90 -0
  116. package/docs/guide/es/pipeline/3-batch-implement-and-multi-feature.md +78 -0
  117. package/docs/guide/es/pipeline/4-picking-an-engine-per-rail.md +60 -0
  118. package/docs/guide/es/settings/1-themes.md +37 -0
  119. package/docs/guide/es/settings/2-language.md +39 -0
  120. package/docs/guide/es/settings/3-pipeline-telemetry-and-diagnostics.md +46 -0
  121. package/docs/guide/es/settings/4-where-your-data-lives.md +48 -0
  122. package/docs/guide/es/specs/1-specs-and-the-backlog.md +52 -0
  123. package/docs/guide/es/specs/2-add-spec-quick-mode.md +45 -0
  124. package/docs/guide/es/specs/3-add-spec-explore-mode.md +68 -0
  125. package/docs/guide/es/specs/4-drafts-and-contract-layer.md +81 -0
  126. package/docs/guide/fr/agents/1-meet-the-agents.md +38 -0
  127. package/docs/guide/fr/agents/2-profiles-and-the-balanced-default.md +45 -0
  128. package/docs/guide/fr/agents/3-customizing-models-per-agent.md +60 -0
  129. package/docs/guide/fr/agents/4-custom-agents-catalog.md +43 -0
  130. package/docs/guide/fr/getting-started/1-what-is-specrails.md +49 -0
  131. package/docs/guide/fr/getting-started/2-installing-and-first-run.md +42 -0
  132. package/docs/guide/fr/getting-started/3-adding-your-first-project.md +58 -0
  133. package/docs/guide/fr/getting-started/4-the-dashboard-tour.md +53 -0
  134. package/docs/guide/fr/insights/1-analytics-and-cost-tracking.md +78 -0
  135. package/docs/guide/fr/insights/2-the-integrated-terminal.md +46 -0
  136. package/docs/guide/fr/insights/3-code-explorer.md +50 -0
  137. package/docs/guide/fr/integrations/1-ai-providers.md +64 -0
  138. package/docs/guide/fr/integrations/2-plugins.md +44 -0
  139. package/docs/guide/fr/integrations/3-jira-integration.md +71 -0
  140. package/docs/guide/fr/integrations/4-mobile-companion.md +38 -0
  141. package/docs/guide/fr/pipeline/1-rails-and-jobs.md +94 -0
  142. package/docs/guide/fr/pipeline/2-the-job-detail-view.md +90 -0
  143. package/docs/guide/fr/pipeline/3-batch-implement-and-multi-feature.md +78 -0
  144. package/docs/guide/fr/pipeline/4-picking-an-engine-per-rail.md +60 -0
  145. package/docs/guide/fr/settings/1-themes.md +37 -0
  146. package/docs/guide/fr/settings/2-language.md +39 -0
  147. package/docs/guide/fr/settings/3-pipeline-telemetry-and-diagnostics.md +46 -0
  148. package/docs/guide/fr/settings/4-where-your-data-lives.md +48 -0
  149. package/docs/guide/fr/specs/1-specs-and-the-backlog.md +52 -0
  150. package/docs/guide/fr/specs/2-add-spec-quick-mode.md +45 -0
  151. package/docs/guide/fr/specs/3-add-spec-explore-mode.md +68 -0
  152. package/docs/guide/fr/specs/4-drafts-and-contract-layer.md +81 -0
  153. package/docs/guide/it/agents/1-meet-the-agents.md +38 -0
  154. package/docs/guide/it/agents/2-profiles-and-the-balanced-default.md +45 -0
  155. package/docs/guide/it/agents/3-customizing-models-per-agent.md +60 -0
  156. package/docs/guide/it/agents/4-custom-agents-catalog.md +43 -0
  157. package/docs/guide/it/getting-started/1-what-is-specrails.md +49 -0
  158. package/docs/guide/it/getting-started/2-installing-and-first-run.md +42 -0
  159. package/docs/guide/it/getting-started/3-adding-your-first-project.md +58 -0
  160. package/docs/guide/it/getting-started/4-the-dashboard-tour.md +53 -0
  161. package/docs/guide/it/insights/1-analytics-and-cost-tracking.md +78 -0
  162. package/docs/guide/it/insights/2-the-integrated-terminal.md +46 -0
  163. package/docs/guide/it/insights/3-code-explorer.md +50 -0
  164. package/docs/guide/it/integrations/1-ai-providers.md +64 -0
  165. package/docs/guide/it/integrations/2-plugins.md +44 -0
  166. package/docs/guide/it/integrations/3-jira-integration.md +71 -0
  167. package/docs/guide/it/integrations/4-mobile-companion.md +38 -0
  168. package/docs/guide/it/pipeline/1-rails-and-jobs.md +94 -0
  169. package/docs/guide/it/pipeline/2-the-job-detail-view.md +90 -0
  170. package/docs/guide/it/pipeline/3-batch-implement-and-multi-feature.md +78 -0
  171. package/docs/guide/it/pipeline/4-picking-an-engine-per-rail.md +60 -0
  172. package/docs/guide/it/settings/1-themes.md +37 -0
  173. package/docs/guide/it/settings/2-language.md +39 -0
  174. package/docs/guide/it/settings/3-pipeline-telemetry-and-diagnostics.md +46 -0
  175. package/docs/guide/it/settings/4-where-your-data-lives.md +48 -0
  176. package/docs/guide/it/specs/1-specs-and-the-backlog.md +52 -0
  177. package/docs/guide/it/specs/2-add-spec-quick-mode.md +45 -0
  178. package/docs/guide/it/specs/3-add-spec-explore-mode.md +68 -0
  179. package/docs/guide/it/specs/4-drafts-and-contract-layer.md +81 -0
  180. package/docs/guide/ja/agents/1-meet-the-agents.md +38 -0
  181. package/docs/guide/ja/agents/2-profiles-and-the-balanced-default.md +45 -0
  182. package/docs/guide/ja/agents/3-customizing-models-per-agent.md +60 -0
  183. package/docs/guide/ja/agents/4-custom-agents-catalog.md +43 -0
  184. package/docs/guide/ja/getting-started/1-what-is-specrails.md +49 -0
  185. package/docs/guide/ja/getting-started/2-installing-and-first-run.md +42 -0
  186. package/docs/guide/ja/getting-started/3-adding-your-first-project.md +58 -0
  187. package/docs/guide/ja/getting-started/4-the-dashboard-tour.md +53 -0
  188. package/docs/guide/ja/insights/1-analytics-and-cost-tracking.md +78 -0
  189. package/docs/guide/ja/insights/2-the-integrated-terminal.md +46 -0
  190. package/docs/guide/ja/insights/3-code-explorer.md +50 -0
  191. package/docs/guide/ja/integrations/1-ai-providers.md +64 -0
  192. package/docs/guide/ja/integrations/2-plugins.md +44 -0
  193. package/docs/guide/ja/integrations/3-jira-integration.md +71 -0
  194. package/docs/guide/ja/integrations/4-mobile-companion.md +38 -0
  195. package/docs/guide/ja/pipeline/1-rails-and-jobs.md +94 -0
  196. package/docs/guide/ja/pipeline/2-the-job-detail-view.md +90 -0
  197. package/docs/guide/ja/pipeline/3-batch-implement-and-multi-feature.md +78 -0
  198. package/docs/guide/ja/pipeline/4-picking-an-engine-per-rail.md +60 -0
  199. package/docs/guide/ja/settings/1-themes.md +37 -0
  200. package/docs/guide/ja/settings/2-language.md +39 -0
  201. package/docs/guide/ja/settings/3-pipeline-telemetry-and-diagnostics.md +46 -0
  202. package/docs/guide/ja/settings/4-where-your-data-lives.md +48 -0
  203. package/docs/guide/ja/specs/1-specs-and-the-backlog.md +52 -0
  204. package/docs/guide/ja/specs/2-add-spec-quick-mode.md +45 -0
  205. package/docs/guide/ja/specs/3-add-spec-explore-mode.md +68 -0
  206. package/docs/guide/ja/specs/4-drafts-and-contract-layer.md +81 -0
  207. package/docs/guide/pt/agents/1-meet-the-agents.md +38 -0
  208. package/docs/guide/pt/agents/2-profiles-and-the-balanced-default.md +45 -0
  209. package/docs/guide/pt/agents/3-customizing-models-per-agent.md +60 -0
  210. package/docs/guide/pt/agents/4-custom-agents-catalog.md +43 -0
  211. package/docs/guide/pt/getting-started/1-what-is-specrails.md +49 -0
  212. package/docs/guide/pt/getting-started/2-installing-and-first-run.md +42 -0
  213. package/docs/guide/pt/getting-started/3-adding-your-first-project.md +58 -0
  214. package/docs/guide/pt/getting-started/4-the-dashboard-tour.md +53 -0
  215. package/docs/guide/pt/insights/1-analytics-and-cost-tracking.md +78 -0
  216. package/docs/guide/pt/insights/2-the-integrated-terminal.md +46 -0
  217. package/docs/guide/pt/insights/3-code-explorer.md +50 -0
  218. package/docs/guide/pt/integrations/1-ai-providers.md +64 -0
  219. package/docs/guide/pt/integrations/2-plugins.md +44 -0
  220. package/docs/guide/pt/integrations/3-jira-integration.md +71 -0
  221. package/docs/guide/pt/integrations/4-mobile-companion.md +38 -0
  222. package/docs/guide/pt/pipeline/1-rails-and-jobs.md +94 -0
  223. package/docs/guide/pt/pipeline/2-the-job-detail-view.md +90 -0
  224. package/docs/guide/pt/pipeline/3-batch-implement-and-multi-feature.md +78 -0
  225. package/docs/guide/pt/pipeline/4-picking-an-engine-per-rail.md +60 -0
  226. package/docs/guide/pt/settings/1-themes.md +37 -0
  227. package/docs/guide/pt/settings/2-language.md +39 -0
  228. package/docs/guide/pt/settings/3-pipeline-telemetry-and-diagnostics.md +46 -0
  229. package/docs/guide/pt/settings/4-where-your-data-lives.md +48 -0
  230. package/docs/guide/pt/specs/1-specs-and-the-backlog.md +52 -0
  231. package/docs/guide/pt/specs/2-add-spec-quick-mode.md +45 -0
  232. package/docs/guide/pt/specs/3-add-spec-explore-mode.md +68 -0
  233. package/docs/guide/pt/specs/4-drafts-and-contract-layer.md +81 -0
  234. package/docs/guide/zh/agents/1-meet-the-agents.md +38 -0
  235. package/docs/guide/zh/agents/2-profiles-and-the-balanced-default.md +45 -0
  236. package/docs/guide/zh/agents/3-customizing-models-per-agent.md +60 -0
  237. package/docs/guide/zh/agents/4-custom-agents-catalog.md +43 -0
  238. package/docs/guide/zh/getting-started/1-what-is-specrails.md +49 -0
  239. package/docs/guide/zh/getting-started/2-installing-and-first-run.md +42 -0
  240. package/docs/guide/zh/getting-started/3-adding-your-first-project.md +58 -0
  241. package/docs/guide/zh/getting-started/4-the-dashboard-tour.md +53 -0
  242. package/docs/guide/zh/insights/1-analytics-and-cost-tracking.md +78 -0
  243. package/docs/guide/zh/insights/2-the-integrated-terminal.md +46 -0
  244. package/docs/guide/zh/insights/3-code-explorer.md +50 -0
  245. package/docs/guide/zh/integrations/1-ai-providers.md +64 -0
  246. package/docs/guide/zh/integrations/2-plugins.md +44 -0
  247. package/docs/guide/zh/integrations/3-jira-integration.md +71 -0
  248. package/docs/guide/zh/integrations/4-mobile-companion.md +38 -0
  249. package/docs/guide/zh/pipeline/1-rails-and-jobs.md +94 -0
  250. package/docs/guide/zh/pipeline/2-the-job-detail-view.md +90 -0
  251. package/docs/guide/zh/pipeline/3-batch-implement-and-multi-feature.md +78 -0
  252. package/docs/guide/zh/pipeline/4-picking-an-engine-per-rail.md +60 -0
  253. package/docs/guide/zh/settings/1-themes.md +37 -0
  254. package/docs/guide/zh/settings/2-language.md +39 -0
  255. package/docs/guide/zh/settings/3-pipeline-telemetry-and-diagnostics.md +46 -0
  256. package/docs/guide/zh/settings/4-where-your-data-lives.md +48 -0
  257. package/docs/guide/zh/specs/1-specs-and-the-backlog.md +52 -0
  258. package/docs/guide/zh/specs/2-add-spec-quick-mode.md +45 -0
  259. package/docs/guide/zh/specs/3-add-spec-explore-mode.md +68 -0
  260. package/docs/guide/zh/specs/4-drafts-and-contract-layer.md +81 -0
  261. package/docs/internals/README.md +1 -1
  262. package/docs/internals/adding-a-provider.md +192 -59
  263. package/docs/internals/api-reference.md +130 -21
  264. package/docs/internals/architecture.md +22 -9
  265. package/docs/internals/bundled-framework-build-plan.md +264 -0
  266. package/docs/internals/configuration.md +33 -8
  267. package/docs/internals/global-artifacts-alignment-contract.md +486 -0
  268. package/docs/internals/global-artifacts-relocation-evaluation.md +294 -0
  269. package/docs/internals/operations-runbook.md +16 -5
  270. package/docs/internals/profiles.md +42 -14
  271. package/docs/platforms/macos.md +27 -8
  272. package/docs/platforms/windows.md +20 -6
  273. package/docs/running-pipelines.md +17 -9
  274. package/docs/terminal.md +9 -3
  275. package/docs/tracking-cost.md +17 -11
  276. package/package.json +1 -1
  277. package/server/dist/agent-refine-manager.js +20 -5
  278. package/server/dist/artifact-registry.js +468 -0
  279. package/server/dist/attachment-manager.js +5 -8
  280. package/server/dist/browser-capture-manager.js +4 -4
  281. package/server/dist/bundled-core.js +72 -0
  282. package/server/dist/bundled-openspec.js +58 -0
  283. package/server/dist/chat-manager.js +42 -5
  284. package/server/dist/code-explorer-router.js +10 -7
  285. package/server/dist/config.js +7 -2
  286. package/server/dist/context-budget.js +17 -6
  287. package/server/dist/context-scope.js +6 -2
  288. package/server/dist/contract-refine-runner.js +31 -9
  289. package/server/dist/desktop-router.js +24 -1
  290. package/server/dist/docs-router.js +210 -132
  291. package/server/dist/file-summary-manager.js +41 -16
  292. package/server/dist/framework-manager.js +248 -0
  293. package/server/dist/framework-migration.js +308 -0
  294. package/server/dist/index.js +30 -0
  295. package/server/dist/install-config-path.js +73 -0
  296. package/server/dist/jira/jira-sync-manager.js +23 -11
  297. package/server/dist/openspec-shim.js +153 -0
  298. package/server/dist/plugins-router.js +19 -8
  299. package/server/dist/profiles-router.js +38 -16
  300. package/server/dist/project-registry.js +101 -3
  301. package/server/dist/project-router-chat.js +1 -1
  302. package/server/dist/project-router-helpers.js +25 -12
  303. package/server/dist/project-router-jobs.js +3 -3
  304. package/server/dist/project-router-settings.js +8 -6
  305. package/server/dist/project-router-setup.js +27 -10
  306. package/server/dist/project-router-spending.js +6 -1
  307. package/server/dist/project-router-tickets.js +30 -10
  308. package/server/dist/project-router.js +16 -1
  309. package/server/dist/queue-manager.js +149 -18
  310. package/server/dist/setup-manager.js +131 -29
  311. package/server/dist/smash-runner.js +21 -6
  312. package/server/dist/ticket-store.js +6 -2
  313. package/server/dist/ticket-watcher.js +5 -1
  314. package/server/dist/vitest-setup.js +25 -0
  315. package/server/dist/workspace-manager.js +199 -0
  316. package/server/dist/workspace-resolution.js +147 -0
  317. package/client/dist/assets/index-DgKfQFcf.css +0 -2
  318. package/client/dist/assets/setup-BIIkb-_K.js +0 -1
  319. package/client/dist/assets/setup-BeQxu9kD.js +0 -1
  320. package/client/dist/assets/setup-CPa6GnlI.js +0 -1
  321. package/client/dist/assets/setup-CZl4OEJx.js +0 -1
  322. package/client/dist/assets/setup-ChpodNfn.js +0 -1
  323. package/client/dist/assets/setup-D_fjJH6u.js +0 -1
  324. package/client/dist/assets/setup-YzD8DX4O.js +0 -1
  325. package/client/dist/assets/setup-fRpDozmq.js +0 -1
  326. package/docs/adding-a-provider.md +0 -107
@@ -0,0 +1,294 @@
1
+ # Evaluación arquitectónica: reubicar TODOS los artefactos fuera de los repos importados
2
+
3
+ > Documento de decisión técnica. Audiencia: arquitectos de `specrails-core` + `specrails-desktop`.
4
+ > Objetivo evaluado: que `specrails-core` instale y que `specrails-desktop` lea **todos** los
5
+ > artefactos de Specrails desde `$HOME/.specrails`, y todos los artefactos de los CLIs
6
+ > (claude/gemini/codex) desde `$HOME/.claude`, `$HOME/.gemini`, `$HOME/.codex`, de modo que
7
+ > **los repos importados NUNCA se modifiquen** (cero `.specrails/.claude/.codex/.gemini` en el repo,
8
+ > cero mutaciones de `.gitignore`, cero archivos de instrucciones).
9
+
10
+ ---
11
+
12
+ ## 1. Resumen ejecutivo
13
+
14
+ El objetivo es **parcialmente alcanzable, no plenamente**, y la frontera entre lo alcanzable y lo irreductible es nítida y está bien fundamentada en la evidencia. La pieza maestra es un hecho confirmado en código y en los CLIs vivos: **los tres CLIs (claude, codex, gemini) anclan su "project scope" — agentes, comandos, skills, settings, archivo de instrucciones, `.mcp.json` — al directorio de trabajo (CWD), no al repo de git.** No existe ningún `--project-dir` en ninguno de los tres. Por tanto, si cada spawn se ejecuta desde un directorio anclado en `$HOME` (con el repo accesible mediante un symlink hijo `./project`), ese directorio pasa a ser el "proyecto" para el CLI y **cero archivos de config aterrizan en el repo**. Este patrón ya está probado y en producción en `server/explore-cwd-manager.ts`.
15
+
16
+ La recomendación es **adoptar el "workspace gestionado por la app" (Opción 1) como modelo arquitectónico de destino**, porque convierte la inmunidad a colisiones en una **propiedad estructural** (no en supresión por-flag), pero **ejecutarlo por fases empezando por el alcance de la Opción 3 (Híbrido Pragmático)** para los flujos de lectura/interactivos, que ya son relocalizables hoy con cambios solo en desktop y cero cambios en contratos congelados. El panel de jueces se reparte de forma honesta: **la lente de feasibilidad CLI y la de goal-fit/UX eligen la Opción 1** (es la única que usa el único mecanismo universal, CWD-relocation, sin depender de flags que el CLI no soporta); **la lente de blast-radius/contratos elige la Opción 3** (menor superficie de cambio, cero contratos en riesgo).
17
+
18
+ El techo honesto es **"repo git-limpio", no "repo file-limpio"** para proyectos que ejecutan rails de `implement`: dos artefactos son irreductiblemente repo-bound — `openspec/changes/` (entregable versionado, escrito por el binario externo `@fission-ai/openspec`, leído como working tree repo-relativo por los agentes) y los git worktrees de aislamiento (`.claude/worktrees/`, deben compartir el `.git`/object-store del repo para el merge-back). Ningún flag de ningún CLI los reubica. Para proyectos de **solo lectura** (Explore, quick-spec, chat, ai-edit) el objetivo literal de "cero archivos en el repo" **sí se cumple por completo**.
19
+
20
+ ---
21
+
22
+ ## 2. El problema hoy
23
+
24
+ Cuando `specrails-desktop` importa un repo, su setup wizard ejecuta `npx specrails-core` (tier `quick`), que corre `scaffoldInstallation()` con `repoRoot = project.path` (la ruta del repo del usuario). Esto **escribe directamente dentro del repo del usuario** a través de cuatro raíces de destino, y además **muta archivos preexistentes del usuario**. El daño concreto, según el inventario de evidencia:
25
+
26
+ - **Pollution de directorios completos en el repo**: `.specrails/**` (manifest, version pin, `setup-templates/` staging, `install-config.yaml`, opcionalmente `profiles/`) y `<providerDir>/**` donde `providerDir` es `.claude` / `.codex` / `.gemini` según el provider (`scaffold.ts:251-275`, ~40 callsites con `path.join(input.repoRoot, providerDir, ...)`).
27
+
28
+ - **Mutación de `.gitignore` del usuario**: `ensureGitignore` añade un bloque `# specrails` con `.claude/agent-memory/` y `.specrails/` (y `.gemini/agent-memory/` en gemini) — `scaffold.ts:277-280, 1226-1242`.
29
+
30
+ - **Mutación quirúrgica de archivos de instrucciones preexistentes**: para codex, `AGENTS.md` raíz por sentinel-block upsert; para gemini, `GEMINI.md` raíz por sentinel + `.gemini/settings.json` por `deepMergeJson`. Preservan contenido fuera del bloque gestionado, pero **escriben en un archivo que el usuario ya tenía** (`scaffold.ts:1038-1071, 723-757`). (Nota: para claude NO se escribe `CLAUDE.md` en el flujo de desktop; eso es tarea del pass de IA `/specrails:enrich`, que el desktop nunca ejecuta en tier quick.)
31
+
32
+ - **Sobrescritura DESTRUCTIVA de archivos propios del usuario**: `placeQuickTierArtefacts()` escribe `sr-architect.md` / `sr-developer.md` / `sr-reviewer.md` con `writeFileLf` **sin guarda de existencia** (`scaffold.ts:951-956`). Si el usuario ya tenía un `.claude/agents/sr-architect.md` propio, **se clobberea**. El contrato `RESERVED_PATHS` solo protege dos prefijos (`.specrails/profiles/`, `.claude/agents/custom-`) — no protege los `sr-*`, ni el `CLAUDE.md`/`AGENTS.md`/`GEMINI.md` del usuario, ni `.mcp.json`, ni `openspec/`.
33
+
34
+ - **Escritura delegada fuera del control de core**: `npx @fission-ai/openspec init --tools <provider> <repoRoot>` escribe `openspec/**` y dirs de comandos de provider (`.claude/commands/opsx`) en el repo, con su propia lógica (`init.ts:128, 202-218`).
35
+
36
+ - **Borrados dentro del repo en cada run**: `pruneLegacyArtifacts()` hace `rmSync` recursivo de varias rutas repo-relativas en cada init (`scaffold.ts:784-814`).
37
+
38
+ El dolor: ruido de git, riesgo de clobber de config propia del usuario, mutaciones de `.gitignore`/`AGENTS.md`/`GEMINI.md` que el usuario no pidió, y una violación del principio "el repo importado es del usuario, no nuestro". El único precedente sano ya existente es que gemini escribe su índice de acknowledgments **fuera del repo** en `~/.gemini/acknowledgments/agents.json` (`scaffold.ts:676-699`) — la prueba de concepto del patrón `$HOME`.
39
+
40
+ ---
41
+
42
+ ## 3. Inventario completo de artefactos
43
+
44
+ | Grupo de artefacto | Dónde se escribe HOY | Quién lo escribe | ¿Committed o gitignored? | ¿Reubicable a `$HOME` y cómo? |
45
+ |---|---|---|---|---|
46
+ | `specrails-manifest.json` + `specrails-version` | `<repo>/.specrails/` | core | gitignored (`.specrails/`) | **Sí** vía nuevo `--workspace-dir`/`artifactRoot` en core. Nombres FROZEN (desktop los regex-matchea); solo cambia la ruta base. |
47
+ | `setup-templates/**` (staging de templates) | `<repo>/.specrails/setup-templates/` | core | gitignored | **Sí**, requiere param base-dir en core + subdir por-proyecto (colisionaría entre proyectos si fuera `$HOME` plano). |
48
+ | `install-config.yaml` | `<repo>/.specrails/` | TUI bin / desktop | gitignored | **Sí (moderado)**: core ya acepta `--from-config <path>`; desktop **ya** copia a `tmpdir` para el spawn (`setup-manager.ts:122,754`). El pin en `integration-contract.json` es nominal. |
49
+ | `profiles/*.json` + `.user-preferred.json` | `<repo>/.specrails/profiles/` | desktop / usuario | **committed (team asset)** | **Sí pero**: app-owned, desktop controla todas las lecturas. Mover a `$HOME` **pierde la propiedad "committable team asset"** — decisión de producto, no solo de ruta. |
50
+ | `plugins/state.json` + `snapshots/` | `<repo>/.specrails/plugins/` | desktop | gitignored | **Sí (moderado)**: app-owned; el snapshot `$HOME/.../jobs/<jobId>/plugins.json` ya existe. |
51
+ | `file-summaries/<hash>.json` | `<repo>/.specrails/file-summaries/` | desktop | gitignored (línea auto-añadida) | **Sí (moderado)**: app-owned. Quita el append a `.gitignore` y la propiedad de team-share. |
52
+ | `local-tickets.json` (spec store canónico) | `<repo>/.specrails/` | desktop (RW) + core (R) | gitignored | **BLOQUEADO sin cambio de core**: contrato de lectura congelado; core + cada persona de agente referencian la ruta repo-relativa; el contrato Jira "zero core changes" lo asume repo-relativo. |
53
+ | `backlog-config.json` (switch read-only de Jira) | `<repo>/.specrails/` | desktop | gitignored | **BLOQUEADO**: core lo lee en ruta fija para entrar en su rama read-only. |
54
+ | `.claude/{agents,commands,skills,rules}` + `agent-memory/` | `<repo>/.claude/` | core | parcialmente gitignored (`agent-memory/`) | **Sí vía CWD-relocation** (CLI auto-discover desde CWD). Bloqueado si CWD debe ser el repo. |
55
+ | `.codex/{config.toml,skills}` + `AGENTS.md` raíz | `<repo>/.codex/`, `<repo>/AGENTS.md` | core | committed / git-noise | **Sí**: `CODEX_HOME` (ya usado per-project) cubre config.toml+MCP+skills+AGENTS.md global, **o** CWD-relocation. |
56
+ | `.gemini/{settings.json,agents,commands}` + `GEMINI.md` raíz | `<repo>/.gemini/`, `<repo>/GEMINI.md` | core | committed / git-noise | **Sí**: CWD-relocation (project scope cwd-anchored), `GEMINI_SYSTEM_MD` para instrucciones, user-scope settings para MCP. |
57
+ | `.mcp.json` (entradas MCP de plugins) | `<repo>/.mcp.json` | desktop (merge quirúrgico) | committed | **Sí (moderado)**: `--mcp-config <abs>` (mecanismo ya usado para `user-mcp.json`) **o** CWD-relocation. |
58
+ | `custom-<plugin>.md` fragmentos | `<repo>/.claude/agents/` | desktop | committed | **Sí vía CWD-relocation** (misma constraint de discovery). |
59
+ | `CLAUDE.md` raíz | NO escrito por desktop quick-tier (solo full-tier enrich) | core (full-tier) | committed | **Trivial**: nada lo escribe en el path de desktop; Explore ya lo evita vía explore-cwd. |
60
+ | `agent-memory/` (explanations, failures) | `<repo>/.claude/agent-memory/` | core (runtime, prompt MD) | gitignored | **Sí pero requiere NUEVO soporte de core** (`SPECRAILS_STATE_DIR` en templates de prompt). |
61
+ | `pipeline-state/`, `health-history/`, `compat-snapshots/`, `.dry-run/`, `backlog-cache.json` | `<repo>/.claude/...` | core (runtime, prompt MD) | gitignored | **Sí pero requiere NUEVO soporte de core** (mismo `SPECRAILS_STATE_DIR`). |
62
+ | `openspec/changes/**` (entregable de spec) | `<repo>/openspec/` | `@fission-ai/openspec` (delegado) | **git-TRACKED (committed, el producto)** | **BLOQUEADO**: binario externo, working tree repo-relativo, entregable versionado por diseño. |
63
+ | `.claude/worktrees/agent-<id>/` (git worktrees) | `<repo>/.claude/worktrees/` | Claude Code Task `isolation:worktree` | gitignored | **BLOQUEADO**: worktree real, debe compartir `.git`/object-store del repo para merge-back. |
64
+ | `~/.gemini/acknowledgments/agents.json` | `$HOME/.gemini/` (ya global) | core | n/a (global) | **Trivial (ya global)**: merge-safe, keyed por `repoRoot`. Re-keying si `.gemini/agents` se mueve. |
65
+ | `~/.specrails/doctor.log` | `$HOME/.specrails/` (ya global) | core (doctor) | n/a | **Trivial (ya global)**. |
66
+ | `.gitignore` (bloque `# specrails`) | `<repo>/.gitignore` | core | n/a | **Trivial de eliminar**: si los artefactos salen del repo, `ensureGitignore` es un no-op. |
67
+
68
+ **Precedente `$HOME` ya existente y amplio** (la base de la relocalización): desktop ya guarda `jobs.sqlite`, `jobs/<jobId>/{profile,plugins}.json`, telemetry, terminals shims, `explore-cwd`, `codex-home`, `browser-profile`, `attachments`, `user-mcp.json`, todo bajo `$HOME/.specrails/projects/<slug>/`. El snapshot `SPECRAILS_PROFILE_PATH` y `SPECRAILS_PLUGINS_*` ya apuntan a `$HOME`.
69
+
70
+ ---
71
+
72
+ ## 4. La restricción dura: cómo resuelven la config los CLIs
73
+
74
+ Esta es la sección make-or-break. El hallazgo maestro, confirmado por la evidencia y los CLIs vivos: **ninguno de los tres CLIs permite apuntar agents/commands de project-scope a un directorio arbitrario SIN mover el CWD. No existe `--project-dir`.** De ahí se deriva todo.
75
+
76
+ ### 4.1 Claude
77
+
78
+ - **Project scope (`.claude/settings.json`, `.claude/agents`, `.claude/commands`, `CLAUDE.md`, `.mcp.json`) está ESTRICTAMENTE anclado al CWD.** No hay flag/env para cargarlo desde un directorio no-CWD arbitrario (docs oficiales; feature-requests abiertas #25762 y #28808 piden exactamente esto, confirmando que no existe).
79
+ - **`CLAUDE_CONFIG_DIR` reubica SOLO el user-scope `~/.claude` (global a todos los proyectos), NO el `.claude` por-proyecto.**
80
+ - **Escape hatches por-invocación (sin archivo en el repo):** `--settings <file-or-json>` (ruta arbitraria), `--mcp-config <files...>` (+ `--strict-mcp-config` para ignorar el `.mcp.json` del repo), `--agents <json>` (agentes inline), `--add-dir`, `--system-prompt`/`--append-system-prompt`, `--plugin-dir`/`--plugin-url`.
81
+ - **`--setting-sources` es enum-only `{user, project, local}`** — selecciona qué scopes cargar, no dónde viven.
82
+ - **PARED dura (solo si CWD debe ser el repo):** no hay forma de cargar agents/commands/settings/`CLAUDE.md` de project-scope desde un directorio arbitrario manteniendo CWD en el repo. **`--add-dir` está documentado como "(CLAUDE.md dirs)"** — carga `CLAUDE.md`/memory desde un dir añadido pero **NO registra los subagentes `sr-*` de project-scope** que el snapshot de profile referencia. Esta es la falla fatal de la inyección de framework en rails de la Opción 3. Tampoco hay `--commands-dir`: los `/specrails:*` requieren `--plugin-dir` o `CLAUDE_CONFIG_DIR/commands`.
83
+ - **Esta pared se DISUELVE en el momento en que el CWD se reubica** a un dir `$HOME`: entonces `.claude/agents`, `.claude/commands`, `CLAUDE.md`, `.mcp.json` cargan nativamente desde ese CWD, sin flags.
84
+
85
+ ### 4.2 Codex
86
+
87
+ - **`AGENTS.md` se resuelve en DOS scopes:** project (walk de git-root→cwd) Y global `CODEX_HOME/AGENTS.md` (con precedencia `AGENTS.override.md`). Un `AGENTS.md` no-repo está nativamente soportado vía `CODEX_HOME` — **sin truco de CWD para las instrucciones**.
88
+ - **`CODEX_HOME` reubica `config.toml` (model/sandbox/approval), definiciones MCP, auth Y skills/custom-prompts a un dir por-proyecto.** Desktop ya usa `CODEX_HOME` por-proyecto para MCP.
89
+ - **Project config (`.codex/config.toml`, `.codex/skills`) se descubre caminando desde el CWD hasta el project root** (marker por defecto `.git`); `project_root_markers` (settable a `[]`) controla esto.
90
+ - **PARED suave:** no hay env/flag para apuntar `AGENTS.md` a un FILE arbitrario más allá de project `.codex`, `CODEX_HOME` o `project_doc_fallback_filenames`. Pero `CODEX_HOME` cubre el caso completo. `-c key=value` override per-invocación, `-p profile`, `--ignore-user-config`, `-C/--cd`.
91
+ - **Riesgo de re-discovery:** con CWD=repo, codex **camina git-root→cwd buscando `AGENTS.md` y NO hay flag para deshabilitar ese walk** (confirmado ausente en codex 0.139.0 `--help`). Un `AGENTS.md` preexistente del usuario se concatena aditivamente. Solo "limpio" para repos vírgenes. Con CWD-relocation fuera del repo, el walk no encuentra nada del repo.
92
+
93
+ ### 4.3 Gemini
94
+
95
+ - **`settings.json` carga de system, user (`~/.gemini/settings.json`) y project (`.gemini/settings.json` en CWD).** Project scope estrictamente cwd-anchored. `mcpServers` viven en `settings.json` en cualquier scope — un CWD `$HOME` o user-scope settings proveen MCP sin archivo en el repo.
96
+ - **`GEMINI_SYSTEM_MD` reemplaza el system prompt built-in con un archivo en ruta arbitraria** (abs/rel, `~` expandido) — escape hatch de instrucciones totalmente no-repo, independiente del discovery de `GEMINI.md`.
97
+ - **`GEMINI_CLI_HOME` reubica el dir user-level (`~/.gemini`, global). NINGÚN env reubica el `.gemini` de PROJECT** a ruta arbitraria — debe estar en CWD. `XDG_CONFIG_HOME` no se honra.
98
+ - **El walk de `GEMINI.md` para en el TRUSTED ROOT (frontera del workspace), no en git-root.** Un CWD `$HOME` que no sea ancestro del repo no re-descubre un `GEMINI.md` repo-side. `GEMINI_CLI_TRUST_WORKSPACE=true` (ya inyectado hoy) ancla el trusted root al workspace.
99
+ - **`--include-directories` + `context.loadMemoryFromIncludeDirectories=true`** carga sus `GEMINI.md`. `--policy`/`--admin-policy` cargan policy de rutas arbitrarias.
100
+ - **PARED suave:** project commands/agents son cwd-bound; necesitan CWD-relocation para salir del repo. MCP, instrucciones y policy tienen hatches no-CWD.
101
+
102
+ ### 4.4 Síntesis de la restricción
103
+
104
+ | Tipo de artefacto | claude | codex | gemini |
105
+ |---|---|---|---|
106
+ | Instrucciones (`CLAUDE/AGENTS/GEMINI.md`) | `--append-system-prompt` / CWD | `CODEX_HOME/AGENTS.md` / CWD | `GEMINI_SYSTEM_MD` / CWD |
107
+ | MCP (`.mcp.json` / settings) | `--mcp-config` + `--strict-mcp-config` / CWD | `CODEX_HOME` config.toml | user-scope settings / CWD |
108
+ | Settings | `--settings` / CWD | `-c` + `CODEX_HOME` / CWD | `GEMINI_CLI_HOME` (user) / CWD (project) |
109
+ | **Agents (project-scope)** | **solo CWD** (o `--agents` inline) | **solo CWD/`CODEX_HOME`** (sin file flag) | **solo CWD** (sin env por-project) |
110
+ | **Commands (project-scope)** | **solo CWD** (o `--plugin-dir`; **NO hay `--commands-dir`**) | `CODEX_HOME/skills` / CWD | **solo CWD** |
111
+
112
+ **La conclusión que decide la arquitectura:** las paredes duras (agents/commands de project-scope) **solo existen si se insiste en mantener CWD=repo**. **Todas se disuelven con CWD-relocation** — el único mecanismo universal a los tres CLIs, ya probado en `explore-cwd-manager.ts`.
113
+
114
+ ---
115
+
116
+ ## 5. Opciones de arquitectura
117
+
118
+ ### Opción 1 — Workspace gestionado por la app (generalizar explore-cwd)
119
+
120
+ CWD = `$HOME/.specrails/projects/<slug>/workspace/` para **todos** los spawns (excepto terminales). El workspace contiene TODOS los artefactos (`.claude/.codex/.gemini`, instrucciones, `.mcp.json`, `.specrails/`); el repo se alcanza vía symlink `./project`. Core gana un único `--workspace-dir`/`SPECRAILS_WORKSPACE_DIR` que separa `artifactRoot` de `codeRoot` (default unset ⇒ `artifactRoot=codeRoot`, legacy byte-idéntico). Runtime state vía nuevo `SPECRAILS_STATE_DIR`; worktrees repo-bound vía nuevo `SPECRAILS_REPO_DIR`.
121
+
122
+ - **Trade-offs:** inmunidad a colisiones **estructural** (no per-flag); claude carga agents/commands/`CLAUDE.md`/`.mcp.json` nativamente sin flags frágiles. **Coste:** XL, el grueso en core (~40 callsites de scaffold + 7+ templates de prompt); rails corren CWD=workspace (no el repo), así que toda ruta relativa de edición/git/openspec debe re-apuntar al repo real vía `SPECRAILS_REPO_DIR`/symlink — riesgo de corrección amplio. Requiere release lockstep de dos repos + core-version gate.
123
+ - **Scores del panel:** Feasibilidad CLI **8** (top pick), Goal-fit/UX **8** (top pick), Blast-radius/contratos **4**.
124
+
125
+ ### Opción 2 — Globales `$HOME` reales + inyección por-invocación (CWD=repo)
126
+
127
+ Los artefactos viven en dirs `$HOME` reales por-proyecto; los spawns mantienen CWD=repo y alcanzan la config solo vía env vars + flags. claude: `CLAUDE_CONFIG_DIR` + `--setting-sources user` + `--strict-mcp-config` + `--mcp-config` + `--agents`/`--plugin-dir` + `--append-system-prompt`. codex: `CODEX_HOME`. gemini: `GEMINI_CLI_HOME` + `GEMINI_SYSTEM_MD` + `--include-directories`.
128
+
129
+ - **Trade-offs:** CWD=repo resuelve git/rutas relativas nativamente (única ventaja). **Pero** se sitúa exactamente en la configuración que la evidencia marca con MÁS paredes duras. codex/gemini project skills/agents **no tienen loader no-CWD** ⇒ "user-scope enmascarando project-scope". codex concatena aditivamente cualquier `AGENTS.md` preexistente del usuario (**sin flag para deshabilitar el walk**). claude no tiene `--commands-dir` ⇒ `/specrails:*` requieren ensamblaje `--plugin-dir` por-proyecto (maquinaria nueva no verificada). Además relocaliza `local-tickets.json`, el read-cache FROZEN de core (contrato Jira "zero core changes") — **el peor riesgo de contrato** para un resultado aún PARCIAL.
130
+ - **Scores del panel:** Feasibilidad CLI **4**, Goal-fit/UX **4**, Blast-radius/contratos **3** (el peor en las tres lentes).
131
+
132
+ ### Opción 3 — Híbrido Pragmático (CWD-relocation para lectura, `--add-dir` para rails, gitignore el residuo)
133
+
134
+ Flujos de lectura/interactivos (Explore, quick-spec, contract-refine, sidebar chat, agent-refine, terminal "Open AI CLI") → CWD-relocation a `$HOME/.../cli-cwd/` (reusando/generalizando `ensureExploreCwd`): **cero archivos en el repo, hoy mismo**. Rail/implement → CWD=repo (inevitable), inyectando framework vía `--add-dir`/`--include-directories`/`CODEX_HOME` + `--strict-mcp-config`, y dejando el residuo irreductible (openspec/changes, worktrees, runtime state) **git-limpio** (ya está en el bloque gitignore de core).
135
+
136
+ - **Trade-offs:** **menor blast radius** (Medium, ~70% desktop, core OPCIONAL/cero); **cero contratos congelados tocados**; reusa el patrón explore-cwd ya en producción. **Pero** el rail-path es el punto débil honesto: `--add-dir` está documentado como "(CLAUDE.md dirs)" y **puede NO registrar los subagentes `sr-*`** ⇒ fallback a `--agents` inline regenerado por-spawn, con riesgo de drift respecto al snapshot de profile. No alcanza "cero archivos" para proyectos que corren rails (solo git-limpio).
137
+ - **Scores del panel:** Feasibilidad CLI **5**, Goal-fit/UX **6**, Blast-radius/contratos **8** (top pick).
138
+
139
+ ---
140
+
141
+ ## 6. Recomendación
142
+
143
+ **Adoptar la Opción 1 (workspace) como modelo de destino, implementada por fases empezando con el alcance de la Opción 3 para los flujos de lectura.** Esto es un **graft** deliberado:
144
+
145
+ 1. **Fase A (alcance Opción 3, solo desktop, cero cambios de core, cero contratos en riesgo):** generalizar `explore-cwd-manager.ts` en un `CliCwdManager` compartido y enrutar **todos los flujos de lectura/interactivos** (Explore, quick-spec, contract-refine, agent-refine, sidebar chat, terminal "Open AI CLI") a CWD = `$HOME/.../cli-cwd/`. Para estos flujos, el objetivo "cero archivos en el repo" **se cumple por completo, hoy**, con la inmunidad-a-colisiones estructural de la Opción 1. Repointar los sitios app-owned (`ticket-store`, `profile-manager`, `plugins/paths`, `file-summary`, `jira-backlog-config`, `context-scope`) a `$HOME` donde sea seguro.
146
+
147
+ 2. **Fase B (alcance Opción 1, cambio de core, release lockstep):** introducir `--workspace-dir`/`SPECRAILS_WORKSPACE_DIR` + `SPECRAILS_STATE_DIR` + `SPECRAILS_REPO_DIR` en core, y mover **el flujo de rails** al workspace, con worktrees/openspec como las excepciones repo-bound documentadas. Gate por core-version (espejo del gate `>= 4.1.0` de profiles).
148
+
149
+ **Por qué este graft y no Opción 2/3 puras:** las dos lentes que importan para "que funcione de verdad" (feasibilidad CLI y goal-fit) eligen la Opción 1 porque es la única que descansa **exclusivamente** en CWD-relocation — el único mecanismo universal y no-mágico. La Opción 2 muere en las paredes duras (codex sin loader no-CWD + leak de `AGENTS.md` no suprimible + relocación de `local-tickets.json` que toca un contrato congelado). La Opción 3 hereda la inmunidad de la Opción 1 en lectura pero su rail-path descansa en `--add-dir`, que `claude --help` documenta como "(CLAUDE.md dirs)" — **no registra subagentes de project-scope**. El graft captura lo mejor de ambas: la Opción 3 entrega valor real e inmediato con riesgo mínimo, y la Opción 1 completa el objetivo donde más importa (rails) con la garantía arquitectónica.
150
+
151
+ ### Layout de destino bajo `$HOME`
152
+
153
+ ```
154
+ ~/.specrails/projects/<slug>/
155
+ workspace/ # CWD universal (generaliza explore-cwd) — Fase B
156
+ CLAUDE.md | AGENTS.md | GEMINI.md # instrucciones app/core-owned (por provider)
157
+ .mcp.json # entradas MCP de plugins (+ opcional project MCP)
158
+ .claude/{agents,commands,skills,rules,agent-memory}/
159
+ .codex/{config.toml,skills}/ # codex (también cubierto por CODEX_HOME)
160
+ .gemini/{settings.json,agents,commands,agent-memory}/
161
+ .specrails/
162
+ specrails-manifest.json specrails-version # nombres FROZEN, ahora aquí
163
+ install-config.yaml
164
+ setup-templates/{agents,commands,skills,rules,personas,claude-md,settings}/
165
+ profiles/*.json .user-preferred.json # app-owned (pierde "committable")
166
+ plugins/{state.json,snapshots/}
167
+ file-summaries/<hash>.json
168
+ local-tickets.json # read-cache de specs (vía core env pointer)
169
+ backlog-config.json # switch read-only de Jira
170
+ pipeline-state/ health-history/ compat-snapshots/ dry-run/ agent-memory/ backlog-cache.json
171
+ # ^ runtime state, redirigido vía SPECRAILS_STATE_DIR (nuevo env de core)
172
+ project -> <project.path> # symlink/junction (project-path.txt fallback)
173
+ cli-cwd/ # CWD para flujos de lectura — Fase A (ya existe como explore-cwd)
174
+ jobs.sqlite codex-home/ telemetry/ terminals/ user-mcp.json attachments/ ... # ya en $HOME
175
+ ```
176
+
177
+ Lo único que permanece en el repo: `workspace/project` (symlink), `openspec/changes/` (entregable versionado, intencional) y los worktrees git-bound (gitignored).
178
+
179
+ ### Receta de spawn por provider (Fase B, CWD = workspace)
180
+
181
+ - **claude** (rails, chat, agent-refine, quick-spec, contract-refine): `cwd=<workspace>`. Auto-descubre `.claude/{agents,commands,skills}`, `CLAUDE.md`, `.mcp.json` desde el CWD — **sin flags nuevos en el happy path**. `--add-dir <workspace>/project` para que las tools alcancen archivos del repo por ruta absoluta. `--mcp-config <$HOME user-mcp.json>` para user-MCP sin cambios. `--setting-sources project,local` para aislar de globales del usuario.
182
+ - **codex**: `cwd=<workspace>` + mantener `CODEX_HOME=$HOME/.specrails/projects/<slug>/codex-home`. `-c project_root_markers=[]` (defensivo) para que trate el workspace como root y no camine ancestros. `AGENTS.md` en `<workspace>/AGENTS.md` o `CODEX_HOME/AGENTS.md`.
183
+ - **gemini**: `cwd=<workspace>`. Project `.gemini/{settings.json,agents,commands}` + `GEMINI.md` cwd-discovered. `GEMINI_CLI_TRUST_WORKSPACE=true` (ya inyectado) ancla el trusted root al workspace ⇒ ningún `GEMINI.md` repo-side se re-descubre. Opcional `GEMINI_SYSTEM_MD=<workspace>/GEMINI.md`. Re-keying del writer `~/.gemini/acknowledgments/agents.json` de `project.path` al workspace, hasheando `<workspace>/.gemini/agents/*.md`.
184
+
185
+ Para los tres, el env `$HOME` ya existente (`SPECRAILS_PROFILE_PATH`, `SPECRAILS_PLUGINS_*`, `OTEL_*`/`CLAUDE_CODE_ENABLE_TELEMETRY`) no cambia. **Terminales mantienen `cwd=project.path`** — el usuario espera una shell en su repo real. **Git provenance mantiene `cwd=project.path`** — git es repo-bound.
186
+
187
+ ---
188
+
189
+ ## 7. Plan de migración
190
+
191
+ ### Proyectos ya importados
192
+
193
+ Migración **no-destructiva por diseño** (honra "no modificar el repo"): al cargar el registry (o en el primer job tras el upgrade), `migrateProjectArtifactsToHome(slug)`:
194
+
195
+ 1. Detecta `.specrails/`, `.claude/`, `.codex/`, `.gemini/`, `AGENTS.md`/`GEMINI.md`/`CLAUDE.md` raíz, `.mcp.json` repo-residentes.
196
+ 2. **Copia (no mueve — deja el repo intacto)** el subconjunto app-owned al nuevo `cli-cwd`/`workspace`: `local-tickets.json`, `profiles/`, `plugins/state.json`, `file-summaries/`, `install-config.yaml`, los `sr-*` agents/commands.
197
+ 3. Para el workspace (Fase B), re-ejecuta `npx specrails-core init --root-dir <project.path> --workspace-dir <workspace>` para regenerar artefactos canónicos en `$HOME`.
198
+ 4. Setea un flag en `desktop-db` para que las lecturas siguientes usen `$HOME`.
199
+ 5. Los archivos repo-residentes de instalaciones previas se **dejan en disco** (no se borran automáticamente) e inertes; se ofrece una affordance manual "limpiar archivos antiguos de Specrails" — que el usuario ejecuta explícitamente (eso sí modifica el repo, nunca automático).
200
+
201
+ ### Cambios en `init`/`update` de core
202
+
203
+ - **Fase A:** **cero cambios de core.** Desktop ya pasa `--from-config <abs tmpdir path>` (`setup-manager.ts:754`), así que el pin `configSchema.file` es nominal. Se ejecuta `init` con `cwd` = el dir staging `$HOME` (no `project.path`).
204
+ - **Fase B:** nuevo `--workspace-dir`/`SPECRAILS_WORKSPACE_DIR` que resuelve `artifactRoot = workspaceDir ?? repoRoot`. Threading de `artifactRoot` a través de ~40 callsites de `scaffold.ts`. `ensureGitignore()` y `pruneLegacyArtifacts()` operan sobre `artifactRoot` (no-op/seguro cuando `artifactRoot !== codeRoot`). Delegado openspec recibe el workspace como target (verificar PoC). Runtime: `SPECRAILS_STATE_DIR` honrado por `implement.md`/`retry.md`/`health-check.md`/`compat-check.md`/`sr-*.md`/`why.md`/`memory-inspect.md` (default unset ⇒ `.claude/...`, legacy). Worktrees repo-bound vía `SPECRAILS_REPO_DIR`. Sentinels `init complete`/`update complete` y nombres de manifest **byte-estables**.
205
+
206
+ ### Backward-compat y kill-switch / rollback
207
+
208
+ - **Default unset ⇒ legacy byte-idéntico:** todo `npx specrails-core init` standalone (no-desktop) se comporta exactamente igual; `--workspace-dir` solo lo pasa desktop.
209
+ - **Core-version gate** (espejo del `>= 4.1.0` de profiles): un desktop nuevo contra un core viejo (sin `--workspace-dir`) **caería de vuelta al comportamiento in-repo** en lugar de mis-targetear silenciosamente. **Este gate es load-bearing** — sin él, un desktop nuevo + core viejo vuelca artefactos en el repo.
210
+ - **Rollback:** desactivar el flag de workspace por-proyecto en `desktop-db` revierte a CWD=repo. Los archivos `$HOME` permanecen (limpiables manualmente). Ningún dato se pierde.
211
+
212
+ ---
213
+
214
+ ## 8. Esfuerzo e impacto por repo
215
+
216
+ ### specrails-core
217
+
218
+ - **Fase A:** **cero cambios.**
219
+ - **Fase B (esfuerzo: el grueso, XL del total):**
220
+ - `init.ts`/`update.ts`/`doctor.ts`: nuevo flag `--workspace-dir` + env, resolver `artifactRoot`.
221
+ - `scaffold.ts`: split de `artifactRoot`/`codeRoot` en ~40 callsites de `path.join(input.repoRoot, providerDir, ...)`. **Mecánico pero debe ser exhaustivo** — un solo literal `.claude/...` perdido aterriza en el repo y viola el requisito en silencio.
222
+ - `ensureGitignore()` no-op cuando `artifactRoot !== codeRoot`; `pruneLegacyArtifacts()` sobre `artifactRoot`.
223
+ - Templates de prompt runtime: `SPECRAILS_STATE_DIR` en ~7-8 archivos MD, default `.claude/...`.
224
+ - Worktrees: `SPECRAILS_REPO_DIR` para ops git/worktree distintas del CWD.
225
+ - `integration-contract.json`: bump de `schemaVersion`; documentar el contrato workspace-dir.
226
+
227
+ ### specrails-desktop
228
+
229
+ - **Fase A (esfuerzo: Medium, ~70% del trabajo de Fase A):**
230
+ - Generalizar `explore-cwd-manager.ts` → `CliCwdManager` compartido (reusar symlink + `project-path.txt` fallback + cleanup que ya existen).
231
+ - Repointar `chat-manager`, `contract-refine-runner`, `agent-refine-manager`, `project-router-tickets` (quick-spec, ai-edit) a `cli-cwd`.
232
+ - `setup-manager`: ejecutar `init` con `cwd` = dir staging `$HOME`.
233
+ - Repointar `ticket-store.resolveTicketStoragePath`, `profile-manager.profilesDir`, `plugins/paths.*`, `file-summary-manager.SUMMARIES_REL`, `jira-backlog-config`, `context-scope` readers a `$HOME`.
234
+ - Re-keying de `gemini-agent-ack`.
235
+ - **Fase B (esfuerzo: Medium-Large):**
236
+ - `queue-manager`: cambiar rail-job `cwd` a workspace; inyectar `SPECRAILS_STATE_DIR=<workspace>` + `SPECRAILS_REPO_DIR=<project.path>`. Provenance mantiene `cwd=project.path`.
237
+ - `terminal-manager`: **mantener `cwd=project.path`** (intencional).
238
+ - Migración + core-version gate.
239
+
240
+ ### Riesgos para contratos congelados
241
+
242
+ | Contrato congelado | ¿En riesgo? | Notas |
243
+ |---|---|---|
244
+ | Mobile wire (`specrailshub`, `hub.*`, `hubInstanceId`, `hub_daily_budget_exceeded`) | **No** | Strings de identidad/wire, ortogonales a ubicación de archivos. |
245
+ | Bundle id `sh.specrails.hub` | **No** | Identidad de app-data/updater; sin relación con repo-vs-HOME. |
246
+ | core↔desktop schema identity (`$id`) | **No** | `profile.v1.json` de desktop ya es derivativo con su propio `$id` (línea 3). Mover profiles a `$HOME` no cambia el `$id`. |
247
+ | `RESERVED_PATHS` (`.specrails/profiles/`, `.claude/agents/custom-`) | **No** (semántica), **Sí** producto | Semántica preservada relativa a `artifactRoot`. Mover profiles a `$HOME` pierde "committable team asset" — decisión de producto. |
248
+ | Sentinels `init complete`/`update complete` | **No** (si byte-estables) | Deben permanecer byte-idénticos; solo cambia su ruta base. |
249
+ | `integration-contract.json` `configSchema.file='.specrails/install-config.yaml'` | **Bajo** | Pin nominal; desktop ya pasa `--from-config <abs>`. Fase B puede bumpear `schemaVersion`. |
250
+ | Coverage gates (80% server, 80% client, 70% global) | **No** (alcanzables) | Path funcs puras + symlink manager + DB reads en el harness `:memory:` existente son altamente testeables. Requiere volumen de tests nuevo, no bajar thresholds. |
251
+
252
+ ---
253
+
254
+ ## 9. Riesgos y preguntas abiertas
255
+
256
+ 1. **[SPIKE OBLIGATORIO ANTES DE FASE B] ¿`--add-dir` registra subagentes de project-scope?** `claude --help` documenta `--add-dir` como "(CLAUDE.md dirs)". Si la Opción 1 funciona (CWD=workspace, los agents viven en `<workspace>/.claude/agents` y cargan nativamente desde el CWD) esto **no es problema para la Fase B**. Pero **es la falla fatal de cualquier rail-path con CWD=repo** (Opción 3 pura). Validar que con CWD=workspace los `sr-*` se registran nativamente — es la suposición load-bearing de la recomendación.
257
+
258
+ 2. **[SPIKE OBLIGATORIO] ¿`@fission-ai/openspec init` acepta un target out-of-repo / sin `.git`?** Si lo exige, `openspec/changes/` debe quedar como la **única** excepción repo-residente y "cero archivos" es PARCIAL para rails. Probar: init de openspec contra el workspace sin `.git`; si falla, evaluar inicializar un `.git` throwaway en el workspace o aceptar openspec como excepción documentada.
259
+
260
+ 3. **[SPIKE] Worktrees repo-bound desde CWD=workspace.** Los worktrees deben compartir el `.git`/object-store del repo y mergear de vuelta. Validar que `SPECRAILS_REPO_DIR` + `git -C <repo>` worktree-add funcionan cuando el CWD del proceso es el workspace. Un error aquí **corrompe o falla merges de multi-feature rails silenciosamente**.
261
+
262
+ 4. **Exhaustividad de los ~40 callsites de scaffold + ~8 templates de prompt.** Un solo literal `.claude/...`/`path.join(repoRoot,...)` perdido aterriza en el repo sin error. Mitigación: test que asserta el working tree del repo **byte-inalterado** tras un ciclo completo setup+job.
263
+
264
+ 5. **codex/gemini ancestor-walk re-discovery.** Si el workspace se coloca dentro del repo (o el symlink se sigue durante discovery), un `AGENTS.md`/`GEMINI.md` repo-side se filtra. Mitigación: workspace estrictamente fuera del repo + `project_root_markers=[]`/`TRUST_WORKSPACE`. Verificar por versión de CLI.
265
+
266
+ 6. **Disciplina de rutas en rails (CWD=workspace).** Toda ruta relativa que deba resolver en el REPO debe ir por `SPECRAILS_REPO_DIR`/symlink. Si una tool resuelve relativa al CWD, escribe en el workspace por error. Mitigación: `--add-dir <workspace>/project` + disciplina auditada en prompts.
267
+
268
+ 7. **Profiles/file-summaries pierden "committable team asset".** Regresión de producto, no solo de ruta. Posible affordance opt-in "exportar profiles al repo" / "commit profiles".
269
+
270
+ 8. **`--strict-mcp-config` en rails** deshabilita el `.mcp.json` committed del repo — puede romper a un usuario que dependa legítimamente de un MCP server repo-committed fuera del sistema de plugins. Necesita escape hatch por-proyecto.
271
+
272
+ 9. **GAP ortogonal (no causado por esta migración, pero a corregir/flag en la rework de spawn-env):** `gemini-adapter` declara `nativeOtelEnv:true` pero `buildTelemetryEnv` no emite vars `GEMINI_TELEMETRY_*`; si gemini honra los `OTEL_*` genéricos está sin verificar.
273
+
274
+ 10. **Release lockstep de dos repos.** Un desktop con `--workspace-dir` contra un core sin el flag vuelca artefactos en el repo. El core-version gate es load-bearing.
275
+
276
+ ---
277
+
278
+ ## 10. Veredicto final
279
+
280
+ **GO-WITH-CAVEATS.**
281
+
282
+ - **Para flujos de lectura/interactivos (Explore, quick-spec, contract-refine, chat, ai-edit): GO inmediato.** Fase A es solo-desktop, cero cambios de core, cero contratos congelados en riesgo, y reusa el patrón explore-cwd ya en producción. El objetivo literal "cero archivos en el repo" **se cumple por completo** para estos flujos. Entrega valor real con riesgo mínimo.
283
+
284
+ - **Para el flujo de rails/implement: GO con la advertencia honesta de que el techo es "repo git-limpio", no "repo file-limpio".** `openspec/changes/` (entregable versionado intencional) y los git worktrees (deben compartir el `.git` del repo) son **irreductiblemente repo-bound en las tres opciones** — ningún flag de ningún CLI los reubica. Todo lo demás (framework dirs, instrucciones, `.mcp.json`, manifest, version, profiles, plugins, file-summaries, runtime state) se mueve limpiamente al workspace dado el flag de core + `SPECRAILS_STATE_DIR`.
285
+
286
+ - **NO-GO para la Opción 2 (globales `$HOME` con CWD=repo):** es la peor en las tres lentes del panel; choca con paredes duras no suprimibles (codex sin loader no-CWD, leak de `AGENTS.md`, sin `--commands-dir`) y pone en riesgo el contrato congelado `local-tickets.json` para un resultado aún parcial.
287
+
288
+ ### Lo más importante a validar PRIMERO
289
+
290
+ **Un PoC que confirme la doble suposición load-bearing de la Fase B antes de comprometer el cambio de core:**
291
+
292
+ > Con CWD = un workspace `$HOME` fuera del repo, conteniendo `<workspace>/.claude/agents/sr-*.md` + `.mcp.json` + `CLAUDE.md`, y el repo en `<workspace>/project` (symlink): **(a)** ¿claude **registra y ejecuta** los subagentes `sr-*` de project-scope nativamente desde el CWD?, y **(b)** ¿el agente developer puede **editar source, correr tests y manejar git** en el repo real vía `--add-dir <workspace>/project` / `SPECRAILS_REPO_DIR` sin que ninguna tool escriba por error en el workspace?
293
+
294
+ Si (a) y (b) pasan, la Opción 1 es sólida y el resto es ingeniería exhaustiva. Si (a) falla (claude no registra agents desde el CWD del workspace cuando hay un symlink de por medio, o el discovery se confunde), la arquitectura de rails necesita repensarse antes de tocar core — y ese es exactamente el riesgo que hunde la inyección por-flag de las otras opciones.
@@ -14,7 +14,7 @@ specrails-desktop start
14
14
  specrails-desktop --port 5000 start
15
15
  ```
16
16
 
17
- `start` writes the server PID to `~/.specrails/manager.pid` and appends the server's stdout/stderr to `~/.specrails/desktop.log`. The default port is `4200`.
17
+ `start` daemonizes the server, which then writes its own PID to `~/.specrails/manager.pid` and appends its stdout/stderr to `~/.specrails/desktop.log`. The default port is `4200`.
18
18
 
19
19
  ## Stopping the app
20
20
 
@@ -35,14 +35,16 @@ specrails-desktop status
35
35
  # Same, against a custom port
36
36
  specrails-desktop --port 5000 status
37
37
 
38
- # One-line manager status (also usable as a script-friendly probe)
38
+ # Terser manager status (script-friendly probe)
39
39
  specrails-desktop --status
40
40
  ```
41
41
 
42
- `status` prints `server: running (pid <n>) on http://127.0.0.1:<port>`, the project count, and each project name. It exits non-zero when the app is not running.
42
+ The two forms print different output. The `status` **subcommand** prints `server: running (pid <n>) on http://127.0.0.1:<port>`, the project count, and each project name. The `--status` **flag** prints a shorter `manager: running (v<version>)` / `mode: super` / `projects: <count>` block (no PID, no project names) — handy as a scripted up/down probe. Both exit non-zero when the app is not running.
43
43
 
44
44
  > `specrails-desktop --jobs` is **not** functional against the running server — the server does not expose a cross-project `/api/jobs` route, so the command prints a message that jobs history requires a manager with SQLite persistence and exits `1`. Browse job history per project in the app's **Jobs** page instead.
45
45
 
46
+ > **Offline CLI fallback.** When you run a command and no manager is up, the CLI prints `manager not running — invoking claude directly` and spawns a local `claude` process to handle it. This fallback **always uses `claude`** — it never spawns `codex` or `gemini`, regardless of a project's primary provider — and it writes **nothing** to Analytics (no `ai_invocations` row; cost/tokens are only echoed to your terminal). Start the manager (`specrails-desktop start`) to route through your project's real provider and capture the run.
47
+
46
48
  ## App data location
47
49
 
48
50
  All app data lives under `~/.specrails/` (the path is hardcoded to your home directory — there is no override env var):
@@ -60,7 +62,7 @@ All app data lives under `~/.specrails/` (the path is hardcoded to your home dir
60
62
 
61
63
  See [Configuration](configuration.md#specrails-directory-structure) for the complete per-project subtree (telemetry blobs, explore-cwd, terminals, attachments, etc.) and how the `<slug>` is derived.
62
64
 
63
- > **Auth token caveat.** `~/.specrails/desktop.token` gates every `/api/*` request and WebSocket upgrade. Deleting it (or doing a full `rm -rf ~/.specrails`) regenerates a fresh token on the next start, which can leave an already-open browser tab or CLI on the old token — reload the app after a token reset. See [Configuration → Authentication](configuration.md#authentication).
65
+ > **Auth token caveat.** `~/.specrails/desktop.token` gates every `/api/*` request and WebSocket upgrade, except the two public bootstrap routes (`GET /api/health` and `GET /api/token`) that `requireAuth` is mounted after, so the local client can fetch its token. Deleting the token file (or doing a full `rm -rf ~/.specrails`) regenerates a fresh token on the next start, which can leave an already-open browser tab or CLI on the old token — reload the app after a token reset. See [Configuration → Authentication](configuration.md#authentication).
64
66
 
65
67
  ## Log files
66
68
 
@@ -121,7 +123,7 @@ specrails-desktop start
121
123
  # Back up first, then reset
122
124
  cp ~/.specrails/desktop.sqlite ~/.specrails/desktop.sqlite.bak
123
125
  specrails-desktop stop
124
- rm -f ~/.specrails/desktop.sqlite* # the glob also clears the WAL/SHM sidecars
126
+ rm -f ~/.specrails/desktop.sqlite* # the * also removes the write-ahead-log sidecar files (desktop.sqlite-wal, desktop.sqlite-shm)
125
127
  specrails-desktop start # re-creates an empty registry
126
128
 
127
129
  # Re-register each project
@@ -129,6 +131,15 @@ specrails-desktop add /path/to/project-a
129
131
  specrails-desktop add /path/to/project-b
130
132
  ```
131
133
 
134
+ ### Disable a misbehaving provider or feature (recovery levers)
135
+
136
+ If a single provider or feature is breaking the app, you can turn it off with an environment variable and restart — no reinstall, no data loss. Set the var in the environment the server starts in, then `specrails-desktop stop && specrails-desktop start`.
137
+
138
+ - **Disable a provider** (it disappears from Add Project / engine pickers): `SPECRAILS_CODEX_BETA=0` or `SPECRAILS_GEMINI_BETA=0`. Both are enabled by default and only the **exact string `0`** disables them (`1` / `true` / unset all keep the provider on).
139
+ - **Disable a spec-enrichment feature**: `SPECRAILS_EXPLORE_CONTRACT_REFINE` (Contract Refine) and `SPECRAILS_SMASH` (SMASH) are kill switches that turn off on `0`, `false`, or `off`.
140
+
141
+ These are the most common ops escape hatches; see [Configuration → Environment variables](configuration.md#environment-variables) for the complete list of gates and flags.
142
+
132
143
  ### Per-project reset (keeps the registration)
133
144
 
134
145
  To clear one project's job history, invocations, and telemetry pointers while keeping it registered, delete just that project's `jobs.sqlite` with the app stopped:
@@ -19,7 +19,8 @@ From any project, click **Agents** in the right sidebar (next to
19
19
  Dashboard/Jobs/Analytics/Settings).
20
20
 
21
21
  - **Profiles** tab — create and edit profiles.
22
- - **Usage** tab — see which profiles are actually being used.
22
+ - **Usage** tab — see which profiles are actually being used (backed by
23
+ the `/analytics` endpoint covered in section 8).
23
24
  - **Catalog** tab — read the upstream `sr-*` agents or author custom
24
25
  `custom-*` ones via the Studio.
25
26
 
@@ -30,7 +31,13 @@ points:
30
31
  `.claude/agents/` frontmatter models and creates a `default` profile
31
32
  mirroring today's behavior (zero-loss). It requires the baseline trio
32
33
  `sr-architect`, `sr-developer`, and `sr-reviewer` to be present — the
33
- server rejects the migration if any is missing.
34
+ server rejects the migration if any is missing. On a project whose
35
+ primary provider is **not** Claude (Codex or Gemini), the frontmatter
36
+ model aliases aren't in that provider's catalog, so the migration stamps
37
+ the project's `provider` onto the profile and substitutes that provider's
38
+ default model — the resulting `default` profile still validates and is
39
+ ready to edit (though it only takes effect on Claude rails — see
40
+ [Multi-provider rails](#multi-provider-rails-claude-codex-and-gemini)).
34
41
  - **Blank profile** — start from scratch.
35
42
 
36
43
  ## 2. Saved profiles vs selection
@@ -64,13 +71,28 @@ wizard. Each rail header has a compact profile dropdown
64
71
  The "No profile" option is always available — use it to run a
65
72
  rail exactly as it did pre-4.1.0.
66
73
 
67
- ### Codex / multi-provider
74
+ ### Multi-provider rails (Claude, Codex, and Gemini)
68
75
 
69
- Agent profiles are a **Claude-only** feature. When a rail's AI engine is
70
- Codex, the app force-nulls the profile and runs the rail in legacy mode —
71
- Codex has no agent-profile concept. The profile selector is hidden for
72
- Codex rails, so a profile picked on one engine never silently applies to
73
- the other.
76
+ **Profiles apply only to Claude rails.** specrails-desktop supports three
77
+ interchangeable AI providers Claude, Codex, and Gemini but agent
78
+ profiles are a Claude-only concept (Codex and Gemini have no equivalent).
79
+
80
+ When a rail's AI engine is **anything other than Claude** (Codex or
81
+ Gemini), the app force-nulls the profile and runs the rail in legacy mode.
82
+ The rails router enforces this server-side for *any* non-Claude engine, so
83
+ no profile env var is ever injected on a Codex or Gemini rail regardless of
84
+ what the UI shows.
85
+
86
+ > **Known UI limitation.** The client currently only hides the profile
87
+ > selector for **Codex** rails. On a **Gemini** rail the selector can still
88
+ > appear — but the server ignores any profile you pick there (it always
89
+ > falls back to legacy mode). Picking a profile on a Gemini rail therefore
90
+ > has no effect; treat it as a no-op until the selector is hidden for all
91
+ > non-Claude engines.
92
+
93
+ Provider availability itself is gated separately (both default-enabled): set
94
+ `SPECRAILS_CODEX_BETA=0` or `SPECRAILS_GEMINI_BETA=0` to disable a provider
95
+ app-wide. See [../codex.md](../codex.md) and [../gemini.md](../gemini.md).
74
96
 
75
97
  ## 4. Author a custom agent (Agent Studio)
76
98
 
@@ -96,15 +118,17 @@ see output, token count, and duration inline.
96
118
 
97
119
  - A **profile badge** (themed with the `accent-primary` color) appears on
98
120
  each job row showing which profile it ran under.
99
- - The **Usage** tab shows usage per profile for the last 7/30/90 days:
100
- jobs, success rate, avg duration, avg tokens, and avg cost.
121
+ - The **Usage** tab (the same `/analytics` data from section 8) shows
122
+ usage per profile for the last 7/30/90 days: jobs, success rate, avg
123
+ duration, avg tokens, and avg cost.
101
124
  - The **diagnostic ZIP export** on a job includes `profile.json` with
102
125
  the exact snapshot that rail used.
103
126
 
104
127
  ## 6. Troubleshooting
105
128
 
106
- - **Upgrade banner on Agents page** — `npx specrails-core@latest update`
107
- in the project to bring it to ≥ 4.1.0.
129
+ - **Upgrade banner on Agents page** — run
130
+ `npx specrails-core@^4.8.0 update` in the project to bring it up to date
131
+ (profiles need ≥ 4.1.0; the version the app installs is `^4.8.0`).
108
132
  - **Save disabled with "N issues to resolve"** — the live validator
109
133
  enforces the baseline trio (`sr-architect`, `sr-developer`, `sr-reviewer`)
110
134
  and routing ordering. Among the rules: a `default: true` routing rule (if
@@ -115,7 +139,8 @@ see output, token count, and duration inline.
115
139
  - **The whole Agents section is missing** — it can be disabled server-side
116
140
  with `SPECRAILS_AGENTS_SECTION=false`, which 404s the entire
117
141
  `/profiles` router. Unset it (or leave it at its default) to restore the
118
- section.
142
+ section. This flag is read **once at server startup**, so changing it
143
+ takes effect only after a server restart.
119
144
 
120
145
  ## 7. Reserved paths
121
146
 
@@ -136,7 +161,10 @@ A few internals worth knowing if you're working on this surface:
136
161
  `projectSupportsProfiles()` (`server/queue-manager.ts`), which reads the
137
162
  project's `.specrails/specrails-version` and requires
138
163
  `specrails-core >= 4.1.0`. Below that, the rail spawns in legacy mode and
139
- no profile env var is injected.
164
+ no profile env var is injected. The same is true on any non-Claude rail:
165
+ the rails router force-nulls the profile for Codex/Gemini engines, so the
166
+ `SPECRAILS_PROFILE_PATH` injection below only ever takes effect on a
167
+ Claude rail.
140
168
  - **Snapshot per job.** When a rail launches with a profile, the resolved
141
169
  profile is written to
142
170
  `~/.specrails/projects/<slug>/jobs/<jobId>/profile.json` (chmod `400`, so
@@ -43,9 +43,19 @@ You only need this once per build. It does not apply to the notarized installers
43
43
  When you add a project, the app checks for the tools it needs and surfaces them in a **prerequisites panel** (in the `Add Project` dialog and the setup wizard). It checks:
44
44
 
45
45
  - **Bundled tools** — `node`, `npm`, `npx`, `git`.
46
- - **Provider CLIs** — **Claude Code** and **Codex**. These are always probed via your system `PATH` (never bundled). **At least one provider must be installed and working** before Add Project is enabled — if neither is usable the panel blocks the dialog.
46
+ - **Provider CLIs** — **Claude Code**, **Codex**, and **Gemini CLI**. All three are always probed via your system `PATH` (never bundled). **At least one of the three must be installed and working** before Add Project is enabled — if none is usable the panel blocks the dialog.
47
47
 
48
- When everything is in order, the panel collapses to a single line: **All required tools detected** (no per-tool rows, no version numbers). The detailed per-tool list — with versions, and including the Claude/Codex provider rows — only renders when something is **missing**, below its minimum version, or broken.
48
+ You don't need all three providers. Install whichever you prefer:
49
+
50
+ | Provider | Install | Minimum CLI | Auth |
51
+ |---|---|---|---|
52
+ | **Claude Code** | from [claude.com/download](https://claude.com/download) | none pinned | `claude login` |
53
+ | **Codex** | `brew install codex` | `0.128.0` | `codex login` |
54
+ | **Gemini CLI** | `npm i -g @google/gemini-cli` | `0.11.0` | set `GEMINI_API_KEY` (a paid key from Google AI Studio) |
55
+
56
+ After installing a provider CLI, quit and relaunch Specrails so the new `PATH` is picked up (see [Verifying manually](#verifying-manually)). For full provider setup, see the [Codex guide](../codex.md) and the [Gemini guide](../gemini.md).
57
+
58
+ When everything is in order, the panel collapses to a single line: **All required tools detected** (no per-tool rows, no version numbers). The detailed per-tool list — with versions, and including the Claude / Codex / Gemini provider rows (one row per provider you've installed) — only renders when something is **missing**, below its minimum version, or broken.
49
59
 
50
60
  ## PATH resolution
51
61
 
@@ -53,13 +63,13 @@ GUI apps on macOS inherit a minimal `PATH` from launchd when launched from Finde
53
63
 
54
64
  ### Desktop app (the default for `.dmg` users)
55
65
 
56
- The shipped desktop app bundles its own Node and Git runtimes. When those bundled binaries are present, the Tauri host sets `SPECRAILS_IS_DESKTOP=1` and `SPECRAILS_BUNDLED_RUNTIMES_PATH` before spawning the embedded server (`src-tauri/src/lib.rs`). In that mode `resolveStartupPath()` (in `server/path-resolver.ts`):
66
+ The shipped desktop app bundles its own Node and Git runtimes. When **both** the bundled `node` and `git` bin directories are present, the Tauri host sets `SPECRAILS_IS_DESKTOP=1` and `SPECRAILS_BUNDLED_RUNTIMES_PATH` before spawning the embedded server (`src-tauri/src/lib.rs`). In that mode `resolveStartupPath()` (in `server/path-resolver.ts`):
57
67
 
58
68
  - Prepends the **bundled** `node` and `git` bin directories to the front of `process.env.PATH`. A system Homebrew or nvm-managed `node`/`git` can never shadow them.
59
69
  - **Skips** the Homebrew fast-path prepend entirely.
60
70
  - **Skips** the login-shell merge — `augmentPathFromLoginShell()` is a no-op so it cannot reorder system tools ahead of the bundled ones (`loginShellStatus: "skipped"`).
61
71
 
62
- If a build ships **without** the bundled runtimes (or has a partial/botched extraction), the desktop app does **not** dead-end: it falls through to the same system discovery described below, so a system-installed `node`/`git` still satisfies the requirement.
72
+ If a build ships **without** the bundled runtimes or has only a partial bundle (just one of the two directories present, or a botched extraction) the desktop app does **not** dead-end: it falls through to the same system discovery described below, so a system-installed `node`/`git` still satisfies the requirement.
63
73
 
64
74
  ### Server / non-bundled fallback
65
75
 
@@ -88,7 +98,7 @@ This points you at the actual fix (remove the stale link) instead of sending you
88
98
 
89
99
  ## Diagnostic endpoint
90
100
 
91
- `GET /api/setup-prerequisites?diagnostic=1` returns the standard payload plus a `diagnostic` block. Example (illustrative real payloads also carry `pathSources: "bundled"` segments in desktop mode):
101
+ `GET /api/setup-prerequisites?diagnostic=1` returns the standard payload plus a `diagnostic` block. The example below is a **non-desktop / server run** (e.g. `npm run dev:server`), where `PATH` is reconstructed via the fast path + inherited entries:
92
102
 
93
103
  ```jsonc
94
104
  {
@@ -102,7 +112,8 @@ This points you at the actual fix (remove the stale link) instead of sending you
102
112
  "npx": "/opt/homebrew/bin/npx",
103
113
  "git": "/usr/bin/git",
104
114
  "claude": "/opt/homebrew/bin/claude",
105
- "codex": null
115
+ "codex": null,
116
+ "gemini": null
106
117
  },
107
118
  "nodeEnv": "production",
108
119
  "platform": "darwin"
@@ -110,7 +121,15 @@ This points you at the actual fix (remove the stale link) instead of sending you
110
121
  }
111
122
  ```
112
123
 
113
- `whichResults` is keyed by command name for **every** prerequisite the panel checks, so it includes `claude`/`codex` (and `uv` when probed) on top of the four bundled tools.
124
+ In the **shipped desktop app** the first segments come from the bundled runtimes instead, so the leading `pathSources` entries read `"bundled"` and `loginShellStatus` is `"skipped"`:
125
+
126
+ ```jsonc
127
+ "pathSegments": ["/Applications/Specrails.app/.../runtimes/node/bin", "/Applications/Specrails.app/.../runtimes/git/bin", "..."],
128
+ "pathSources": ["bundled", "bundled", "..."],
129
+ "loginShellStatus": "skipped"
130
+ ```
131
+
132
+ `whichResults` is keyed by command name for **every** prerequisite the panel checks, so it includes `claude`/`codex`/`gemini` (and `uv` when probed) on top of the four bundled tools. A `null` value means that command was not found on `PATH` — in the example above, only Claude Code is installed.
114
133
 
115
134
  The install-instructions modal exposes a **Copy diagnostics** button that fetches this endpoint and copies the JSON to the clipboard for bug reports. The base endpoint (no `?diagnostic=1`) omits the `diagnostic` field, keeping the regular UI poll small.
116
135
 
@@ -125,6 +144,6 @@ After installing or reinstalling Node (or a provider CLI):
125
144
 
126
145
  ## Known limitations
127
146
 
128
- - **Provider requirement**: at least one of Claude Code or Codex must be installed and on `PATH`; otherwise Add Project stays disabled.
147
+ - **Provider requirement**: at least one provider CLI — Claude Code, Codex, or Gemini must be installed and on `PATH`; otherwise Add Project stays disabled. (Gemini is enabled by default; to disable it set `SPECRAILS_GEMINI_BETA=0`.)
129
148
  - **Port 4200** must be free on launch. The app binds `127.0.0.1:4200` for its API + WebSocket; if another process holds the port, the server cannot start.
130
149
  - **Terminal panel**: the bottom terminal panel spawns `$SHELL -l -i`, so your `.zshrc` / `.bashrc` loads as it would in a normal login shell. Per-session shell selection is not yet exposed in the UI — set `SHELL` to override the default.