specrails-desktop 2.0.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 (455) hide show
  1. package/.claude/commands/specrails/batch-implement.md +287 -0
  2. package/.claude/commands/specrails/compat-check.md +271 -0
  3. package/.claude/commands/specrails/doctor.md +62 -0
  4. package/.claude/commands/specrails/enrich.md +1635 -0
  5. package/.claude/commands/specrails/explore-spec.md +173 -0
  6. package/.claude/commands/specrails/health-check.md +527 -0
  7. package/.claude/commands/specrails/implement.md +1457 -0
  8. package/.claude/commands/specrails/memory-inspect.md +259 -0
  9. package/.claude/commands/specrails/opsx-diff.md +419 -0
  10. package/.claude/commands/specrails/propose-spec.md +102 -0
  11. package/.claude/commands/specrails/reconfig.md +89 -0
  12. package/.claude/commands/specrails/refactor-recommender.md +212 -0
  13. package/.claude/commands/specrails/retry.md +363 -0
  14. package/.claude/commands/specrails/telemetry.md +552 -0
  15. package/.claude/commands/specrails/why.md +96 -0
  16. package/LICENSE +21 -0
  17. package/README.md +290 -0
  18. package/cli/dist/specrails-desktop.js +1098 -0
  19. package/client/dist/assets/ActivityFeedPage-Gy4x8dBt.js +1 -0
  20. package/client/dist/assets/AgentsPage-CPgu--Fb.js +86 -0
  21. package/client/dist/assets/AnalyticsPage-B5sJEee2.js +1 -0
  22. package/client/dist/assets/BarChart-7IMQ8HY1.js +33 -0
  23. package/client/dist/assets/CodePage-CBdFvbwe.js +2 -0
  24. package/client/dist/assets/DesktopAnalyticsPage-w0rdTq4w.js +1 -0
  25. package/client/dist/assets/DocsDialog-BZUYM7wm.js +11 -0
  26. package/client/dist/assets/DocsPage-9QglWl46.js +11 -0
  27. package/client/dist/assets/ExportDropdown-BLZFXtNi.js +1 -0
  28. package/client/dist/assets/IntegrationsPage-BxBE4y99.js +3 -0
  29. package/client/dist/assets/JobDetailPage-DydWx_5S.js +16 -0
  30. package/client/dist/assets/JobsPage-20ibw0IO.js +1 -0
  31. package/client/dist/assets/abap-Bw6f2wDG.js +1 -0
  32. package/client/dist/assets/activity-BEIp_Y1A.js +1 -0
  33. package/client/dist/assets/activity-BdrPln96.js +1 -0
  34. package/client/dist/assets/activity-CpkRS8Sx.js +1 -0
  35. package/client/dist/assets/activity-DKCpESPt.js +1 -0
  36. package/client/dist/assets/activity-DOUVEjJi.js +1 -0
  37. package/client/dist/assets/activity-DRwkql_y.js +1 -0
  38. package/client/dist/assets/activity-DcDQ7tjw.js +1 -0
  39. package/client/dist/assets/activity-Dv6H7wEr.js +1 -0
  40. package/client/dist/assets/addon-image-3WCl5Vhd.js +1 -0
  41. package/client/dist/assets/addon-ligatures-C5OdliKs.js +2 -0
  42. package/client/dist/assets/addon-webgl-BbX6pSjl.js +44 -0
  43. package/client/dist/assets/addspec-B5yl4Loj.js +1 -0
  44. package/client/dist/assets/addspec-BEeF5-zc.js +1 -0
  45. package/client/dist/assets/addspec-D33ocMxf.js +1 -0
  46. package/client/dist/assets/addspec-DFswZ0jK.js +1 -0
  47. package/client/dist/assets/addspec-DRE-jZv7.js +1 -0
  48. package/client/dist/assets/addspec-DVZ15Jp8.js +1 -0
  49. package/client/dist/assets/addspec-Fkv91Opc.js +1 -0
  50. package/client/dist/assets/addspec-GWm4ffKl.js +1 -0
  51. package/client/dist/assets/agents-1nCDWRmP.js +1 -0
  52. package/client/dist/assets/agents-Bm9rPqnt.js +1 -0
  53. package/client/dist/assets/agents-CMxtJMLD.js +1 -0
  54. package/client/dist/assets/agents-DK-Dlc0i.js +1 -0
  55. package/client/dist/assets/agents-Q6Ldfpxx.js +1 -0
  56. package/client/dist/assets/agents-TeOSy-ax.js +1 -0
  57. package/client/dist/assets/agents-iTqjRajS.js +1 -0
  58. package/client/dist/assets/agents-s87sMGzL.js +1 -0
  59. package/client/dist/assets/agentstudio-B6Wb59E7.js +1 -0
  60. package/client/dist/assets/agentstudio-BADhZ41e.js +1 -0
  61. package/client/dist/assets/agentstudio-BSnWLR63.js +1 -0
  62. package/client/dist/assets/agentstudio-BdidyBzZ.js +1 -0
  63. package/client/dist/assets/agentstudio-CxlUllqI.js +1 -0
  64. package/client/dist/assets/agentstudio-D3I62TLJ.js +1 -0
  65. package/client/dist/assets/agentstudio-DuH9TogZ.js +1 -0
  66. package/client/dist/assets/agentstudio-Kw88_dUF.js +1 -0
  67. package/client/dist/assets/aiedit-BWxHGsYA.js +1 -0
  68. package/client/dist/assets/aiedit-D2ji6Qy0.js +1 -0
  69. package/client/dist/assets/aiedit-DAhZTvtk.js +1 -0
  70. package/client/dist/assets/aiedit-DJMny-D5.js +1 -0
  71. package/client/dist/assets/aiedit-DOcxERkU.js +1 -0
  72. package/client/dist/assets/aiedit-DvrcbwGv.js +1 -0
  73. package/client/dist/assets/aiedit-TTwzL1TS.js +1 -0
  74. package/client/dist/assets/aiedit-WBSjT_C1.js +1 -0
  75. package/client/dist/assets/analytics-BIdr0YfL.js +1 -0
  76. package/client/dist/assets/analytics-C6EzgtdE.js +1 -0
  77. package/client/dist/assets/analytics-C9Zc-rkM.js +1 -0
  78. package/client/dist/assets/analytics-CVx3YOc0.js +1 -0
  79. package/client/dist/assets/analytics-CYj0tfj7.js +1 -0
  80. package/client/dist/assets/analytics-CnY4kNG3.js +1 -0
  81. package/client/dist/assets/analytics-CrPCZRJ-.js +1 -0
  82. package/client/dist/assets/analytics-DMCto-TF.js +1 -0
  83. package/client/dist/assets/apex-Cw8_REBo.js +1 -0
  84. package/client/dist/assets/atom-one-dark-B-oHczHB.css +1 -0
  85. package/client/dist/assets/attachments-BIsSSnHJ.js +1 -0
  86. package/client/dist/assets/attachments-BW4L3l2L.js +1 -0
  87. package/client/dist/assets/attachments-Bcf6BG6V.js +1 -0
  88. package/client/dist/assets/attachments-Bke8sCU4.js +1 -0
  89. package/client/dist/assets/attachments-COcrGRFz.js +1 -0
  90. package/client/dist/assets/attachments-DYHGA2Dj.js +1 -0
  91. package/client/dist/assets/attachments-Dd92KpUH.js +1 -0
  92. package/client/dist/assets/attachments-DzdU6DV6.js +1 -0
  93. package/client/dist/assets/azcli-Cz6HAoOw.js +1 -0
  94. package/client/dist/assets/bat-CcJ-xyqL.js +1 -0
  95. package/client/dist/assets/bicep-z1WDCKYz.js +2 -0
  96. package/client/dist/assets/browser-5ErDlJoR.js +1 -0
  97. package/client/dist/assets/browser-Bc-YdlVg.js +1 -0
  98. package/client/dist/assets/browser-BlYF4OOq.js +1 -0
  99. package/client/dist/assets/browser-CT-ReZGt.js +1 -0
  100. package/client/dist/assets/browser-DGITz3fC.js +1 -0
  101. package/client/dist/assets/browser-JsAIGCEW.js +1 -0
  102. package/client/dist/assets/browser-M5-rbPlw.js +1 -0
  103. package/client/dist/assets/browser-Qya9cARy.js +1 -0
  104. package/client/dist/assets/cameligo-BRewOpfa.js +1 -0
  105. package/client/dist/assets/chat-BEGuC03z.js +1 -0
  106. package/client/dist/assets/chat-BEW60P_u.js +1 -0
  107. package/client/dist/assets/chat-BQNMD0PL.js +1 -0
  108. package/client/dist/assets/chat-BsbNGPW9.js +1 -0
  109. package/client/dist/assets/chat-CboQguCi.js +1 -0
  110. package/client/dist/assets/chat-DRCa9pOt.js +1 -0
  111. package/client/dist/assets/chat-DwUm6W9z.js +1 -0
  112. package/client/dist/assets/chat-yoXwguQu.js +1 -0
  113. package/client/dist/assets/chunk-CilyBKbf.js +1 -0
  114. package/client/dist/assets/clojure-DBjRWN6g.js +1 -0
  115. package/client/dist/assets/clsx-DnqN-uhr.js +1 -0
  116. package/client/dist/assets/code-AL1rVIMb.js +1 -0
  117. package/client/dist/assets/code-C0BKpkht.js +1 -0
  118. package/client/dist/assets/code-C0FTS3ew.js +1 -0
  119. package/client/dist/assets/code-CPcHxzxw.js +1 -0
  120. package/client/dist/assets/code-D3ryDniw.js +1 -0
  121. package/client/dist/assets/code-D3zVVQTj.js +1 -0
  122. package/client/dist/assets/code-PCmfS3dn.js +1 -0
  123. package/client/dist/assets/code-exI0G5Wd.js +1 -0
  124. package/client/dist/assets/codicon-ngg6Pgfi.ttf +0 -0
  125. package/client/dist/assets/coffee-Cfk_XHGR.js +1 -0
  126. package/client/dist/assets/commands-B772IyDa.js +1 -0
  127. package/client/dist/assets/commands-BDDp6xFG.js +1 -0
  128. package/client/dist/assets/commands-CJxCry-o.js +1 -0
  129. package/client/dist/assets/commands-CfgY-_of.js +1 -0
  130. package/client/dist/assets/commands-DLrvnPNg.js +1 -0
  131. package/client/dist/assets/commands-IXMOKBYt.js +1 -0
  132. package/client/dist/assets/commands-UD1NzmwX.js +1 -0
  133. package/client/dist/assets/commands-sqrqsxyE.js +1 -0
  134. package/client/dist/assets/common-DCr6VzJ7.js +1 -0
  135. package/client/dist/assets/common-Dard9UNH.js +1 -0
  136. package/client/dist/assets/common-DeDELLZJ.js +1 -0
  137. package/client/dist/assets/common-DltqHaAe.js +1 -0
  138. package/client/dist/assets/common-Dmm1GhdD.js +1 -0
  139. package/client/dist/assets/common-DnjcgkPH.js +1 -0
  140. package/client/dist/assets/common-GbpxfPG8.js +1 -0
  141. package/client/dist/assets/common-wA36jmj1.js +1 -0
  142. package/client/dist/assets/cpp-BVob6BaP.js +1 -0
  143. package/client/dist/assets/csharp-C4fbRuOu.js +1 -0
  144. package/client/dist/assets/csp-DthFP_vT.js +1 -0
  145. package/client/dist/assets/css-CGMH0hcW.js +3 -0
  146. package/client/dist/assets/css.worker-Wv5dxAWO.js +89 -0
  147. package/client/dist/assets/cssMode-Cc6ozl-J.js +1 -0
  148. package/client/dist/assets/cypher-Pnf68BRV.js +1 -0
  149. package/client/dist/assets/dart-PMMOtxZX.js +1 -0
  150. package/client/dist/assets/dashboard-B4ixDVk8.js +1 -0
  151. package/client/dist/assets/dashboard-BZBADHSj.js +1 -0
  152. package/client/dist/assets/dashboard-C1MfeUHs.js +1 -0
  153. package/client/dist/assets/dashboard-C7SK6xu5.js +1 -0
  154. package/client/dist/assets/dashboard-CB6Le1yN.js +1 -0
  155. package/client/dist/assets/dashboard-CoTpMOBM.js +1 -0
  156. package/client/dist/assets/dashboard-Duo4DDCW.js +1 -0
  157. package/client/dist/assets/dashboard-I19DXBxw.js +1 -0
  158. package/client/dist/assets/dist-js-BY-Fv_fg.js +1 -0
  159. package/client/dist/assets/dist-js-Bakc4uxT.js +1 -0
  160. package/client/dist/assets/dockerfile-di1nsJCc.js +1 -0
  161. package/client/dist/assets/ecl-D_WVcB5M.js +1 -0
  162. package/client/dist/assets/editor-Br_kD0ds.css +1 -0
  163. package/client/dist/assets/editor.api2-XLGzZfbc.js +872 -0
  164. package/client/dist/assets/editor.main-CfXxHimg.js +6 -0
  165. package/client/dist/assets/editor.worker-Bd9IXS8d.js +26 -0
  166. package/client/dist/assets/elixir-OAdJEMOn.js +1 -0
  167. package/client/dist/assets/explore-4mFpnrKU.js +1 -0
  168. package/client/dist/assets/explore-A8Ltoblq.js +1 -0
  169. package/client/dist/assets/explore-B9A3iN2W.js +1 -0
  170. package/client/dist/assets/explore-BV5Xxlsn.js +1 -0
  171. package/client/dist/assets/explore-BrBJvfjP.js +1 -0
  172. package/client/dist/assets/explore-C3FSE42C.js +1 -0
  173. package/client/dist/assets/explore-D2EFgt8J.js +1 -0
  174. package/client/dist/assets/explore-hFc3HFcp.js +1 -0
  175. package/client/dist/assets/flow9-D3QEZjgn.js +1 -0
  176. package/client/dist/assets/format-command-CwGuwzGA.js +1 -0
  177. package/client/dist/assets/freemarker2-DP7J1gG3.js +3 -0
  178. package/client/dist/assets/fsharp-BF0k_8N8.js +1 -0
  179. package/client/dist/assets/go-BAQO5Jsz.js +1 -0
  180. package/client/dist/assets/graphql-hdFVFkiV.js +1 -0
  181. package/client/dist/assets/handlebars-BjRlucw6.js +1 -0
  182. package/client/dist/assets/hcl-DWnl1o-X.js +1 -0
  183. package/client/dist/assets/html-OumBQJ-U.js +1 -0
  184. package/client/dist/assets/html.worker-CQP8QQsS.js +502 -0
  185. package/client/dist/assets/htmlMode-CStc3zXM.js +1 -0
  186. package/client/dist/assets/index-CimDRRi7.css +2 -0
  187. package/client/dist/assets/index-XGZaKl_u.js +142 -0
  188. package/client/dist/assets/ini-CB-6OVu3.js +1 -0
  189. package/client/dist/assets/integrations-C3p12Ms6.js +1 -0
  190. package/client/dist/assets/integrations-Cr6hH7XR.js +1 -0
  191. package/client/dist/assets/integrations-Cublz3m6.js +1 -0
  192. package/client/dist/assets/integrations-D28q1kF6.js +1 -0
  193. package/client/dist/assets/integrations-DRdbki5W.js +1 -0
  194. package/client/dist/assets/integrations-DaC4SzzL.js +1 -0
  195. package/client/dist/assets/integrations-DmQYCUvN.js +1 -0
  196. package/client/dist/assets/integrations-HIlUxXVs.js +1 -0
  197. package/client/dist/assets/java-d1CmfiHX.js +1 -0
  198. package/client/dist/assets/javascript-CMk--e7g.js +1 -0
  199. package/client/dist/assets/jobs-BE1siB0M.js +1 -0
  200. package/client/dist/assets/jobs-BHcQ_Faf.js +1 -0
  201. package/client/dist/assets/jobs-CFfc2dNX.js +1 -0
  202. package/client/dist/assets/jobs-CSi5n8X_.js +1 -0
  203. package/client/dist/assets/jobs-Dc3X86PY.js +1 -0
  204. package/client/dist/assets/jobs-De5tASex.js +1 -0
  205. package/client/dist/assets/jobs-DsoXEdo7.js +1 -0
  206. package/client/dist/assets/jobs-Wl-ApPMb.js +1 -0
  207. package/client/dist/assets/json.worker-DzV-CpCQ.js +58 -0
  208. package/client/dist/assets/jsonMode-C2h3ZcjZ.js +7 -0
  209. package/client/dist/assets/julia-Bgv08lKa.js +1 -0
  210. package/client/dist/assets/kotlin-u98kaVTf.js +1 -0
  211. package/client/dist/assets/less-CjYwpgg5.js +2 -0
  212. package/client/dist/assets/lexon-YTjaAFBB.js +1 -0
  213. package/client/dist/assets/lib-CPxTMOAq.js +7 -0
  214. package/client/dist/assets/liquid-mI3KJrBE.js +1 -0
  215. package/client/dist/assets/lspLanguageFeatures-DU09ggWi.js +4 -0
  216. package/client/dist/assets/lua-BzmkWv27.js +1 -0
  217. package/client/dist/assets/m3-CFwk9fw0.js +1 -0
  218. package/client/dist/assets/markdown-CR5iMpSZ.js +1 -0
  219. package/client/dist/assets/mdx-C41VDTR_.js +1 -0
  220. package/client/dist/assets/mips-CcEalc17.js +1 -0
  221. package/client/dist/assets/monaco.contribution-CPObAXMC.js +2 -0
  222. package/client/dist/assets/msdax-BQbkawnr.js +1 -0
  223. package/client/dist/assets/mysql-GTlaaW_P.js +1 -0
  224. package/client/dist/assets/nav-0fwkrgHt.js +1 -0
  225. package/client/dist/assets/nav-BEL3MTwK.js +1 -0
  226. package/client/dist/assets/nav-B_G-TJDW.js +1 -0
  227. package/client/dist/assets/nav-C2YXcbZS.js +1 -0
  228. package/client/dist/assets/nav-ClzOE4mA.js +1 -0
  229. package/client/dist/assets/nav-CtYwmMgu.js +1 -0
  230. package/client/dist/assets/nav-D2bOGSEg.js +1 -0
  231. package/client/dist/assets/nav-iH1V5j6o.js +1 -0
  232. package/client/dist/assets/objective-c-Byu1T5if.js +1 -0
  233. package/client/dist/assets/pascal-BrfzBfRm.js +1 -0
  234. package/client/dist/assets/pascaligo-BXXKFUeo.js +1 -0
  235. package/client/dist/assets/perl-B3OikKq-.js +1 -0
  236. package/client/dist/assets/pgsql-CTsa0Acc.js +1 -0
  237. package/client/dist/assets/php-DiQh3FUW.js +1 -0
  238. package/client/dist/assets/pla-92uH8Fzm.js +1 -0
  239. package/client/dist/assets/postiats-BbeWkKUr.js +1 -0
  240. package/client/dist/assets/powerquery-DgDMzpsm.js +1 -0
  241. package/client/dist/assets/powershell-BfdUUzaG.js +1 -0
  242. package/client/dist/assets/preload-helper-DSXbuxSR.js +1 -0
  243. package/client/dist/assets/protobuf-BojW2ftW.js +2 -0
  244. package/client/dist/assets/pug-BxqTg3IU.js +1 -0
  245. package/client/dist/assets/python-Y27rKQtk.js +1 -0
  246. package/client/dist/assets/qsharp-BX_A-MW9.js +1 -0
  247. package/client/dist/assets/r-D9BMnxvJ.js +1 -0
  248. package/client/dist/assets/razor-Cd5-q9Bp.js +1 -0
  249. package/client/dist/assets/redis-5cJqEQJJ.js +1 -0
  250. package/client/dist/assets/redshift-d8BBqiwb.js +1 -0
  251. package/client/dist/assets/restructuredtext-C8a6yIcZ.js +1 -0
  252. package/client/dist/assets/ruby-egeh-6KX.js +1 -0
  253. package/client/dist/assets/rust-a3r9IInB.js +1 -0
  254. package/client/dist/assets/sb-y8iRIDei.js +1 -0
  255. package/client/dist/assets/scala-BPDK2AmK.js +1 -0
  256. package/client/dist/assets/scheme-BIWUEoOs.js +1 -0
  257. package/client/dist/assets/scss-CA-PSzwg.js +3 -0
  258. package/client/dist/assets/settings-55oDcbSh.js +1 -0
  259. package/client/dist/assets/settings-Bd4Tq1RB.js +1 -0
  260. package/client/dist/assets/settings-CCSM-Fhn.js +1 -0
  261. package/client/dist/assets/settings-D3e_bDoW.js +1 -0
  262. package/client/dist/assets/settings-DKbTkbn7.js +1 -0
  263. package/client/dist/assets/settings-Dxpo6_w7.js +1 -0
  264. package/client/dist/assets/settings-bt84e3Aa.js +1 -0
  265. package/client/dist/assets/settings-nu68QukM.js +1 -0
  266. package/client/dist/assets/setup-BMqwfbW9.js +1 -0
  267. package/client/dist/assets/setup-Bb5LcG28.js +1 -0
  268. package/client/dist/assets/setup-BeEx2_da.js +1 -0
  269. package/client/dist/assets/setup-CCCrB53Q.js +1 -0
  270. package/client/dist/assets/setup-CJA0ATmd.js +1 -0
  271. package/client/dist/assets/setup-CeiDbZcb.js +1 -0
  272. package/client/dist/assets/setup-Cus7TApA.js +1 -0
  273. package/client/dist/assets/setup-D9qOs2Xo.js +1 -0
  274. package/client/dist/assets/shell--LiT1Bja.js +1 -0
  275. package/client/dist/assets/solidity-DdqZccZg.js +1 -0
  276. package/client/dist/assets/sophia-S6-YxNG_.js +1 -0
  277. package/client/dist/assets/sparql-BSf5kMp2.js +1 -0
  278. package/client/dist/assets/specs-BFfu3u-a.js +1 -0
  279. package/client/dist/assets/specs-B__C8-8a.js +1 -0
  280. package/client/dist/assets/specs-CZ1PsXsC.js +1 -0
  281. package/client/dist/assets/specs-D2FzlLn9.js +1 -0
  282. package/client/dist/assets/specs-DaUTrNF9.js +1 -0
  283. package/client/dist/assets/specs-Dyc5hYeE.js +1 -0
  284. package/client/dist/assets/specs-cKEh2LXt.js +1 -0
  285. package/client/dist/assets/specs-k0PyLDVt.js +1 -0
  286. package/client/dist/assets/sql-D7KgjR8G.js +1 -0
  287. package/client/dist/assets/st-BnoDa-Ml.js +1 -0
  288. package/client/dist/assets/swift-DEUHTkUX.js +1 -0
  289. package/client/dist/assets/systemverilog-Tqb_KPnW.js +1 -0
  290. package/client/dist/assets/tcl-BmBFS2qq.js +1 -0
  291. package/client/dist/assets/terminal-80yDMgMF.js +1 -0
  292. package/client/dist/assets/terminal-Bje4ziIa.js +1 -0
  293. package/client/dist/assets/terminal-C2WYcFHF.js +1 -0
  294. package/client/dist/assets/terminal-CSONJOex.js +1 -0
  295. package/client/dist/assets/terminal-DEqzGtcr.js +1 -0
  296. package/client/dist/assets/terminal-DeWzh6ys.js +1 -0
  297. package/client/dist/assets/terminal-YOlsJCQj.js +1 -0
  298. package/client/dist/assets/terminal-lkZYR4wJ.js +1 -0
  299. package/client/dist/assets/tickets-CB7N30gm.js +1 -0
  300. package/client/dist/assets/tickets-CF2PYelu.js +1 -0
  301. package/client/dist/assets/tickets-DNOANUXr.js +1 -0
  302. package/client/dist/assets/tickets-DU1aqsbr.js +1 -0
  303. package/client/dist/assets/tickets-DYvafSaY.js +1 -0
  304. package/client/dist/assets/tickets-DlpC_iTg.js +1 -0
  305. package/client/dist/assets/tickets-DucYgtdl.js +1 -0
  306. package/client/dist/assets/tickets-clefmXLv.js +1 -0
  307. package/client/dist/assets/ts.worker-METxwbDZ.js +67719 -0
  308. package/client/dist/assets/tsMode-B0y_xEci.js +11 -0
  309. package/client/dist/assets/twig-BQV8igWC.js +1 -0
  310. package/client/dist/assets/typescript-BzK0OgwW.js +1 -0
  311. package/client/dist/assets/typespec-DlFroUGY.js +1 -0
  312. package/client/dist/assets/useProjectCache-DSaiGFjV.js +1 -0
  313. package/client/dist/assets/vb-BlrJpIMX.js +1 -0
  314. package/client/dist/assets/wgsl-BWgIc6FZ.js +298 -0
  315. package/client/dist/assets/workers-rt--R2Qy.js +1 -0
  316. package/client/dist/assets/xml-eX9QXAmI.js +1 -0
  317. package/client/dist/assets/yaml-fcsNkpOt.js +1 -0
  318. package/client/dist/index.html +246 -0
  319. package/docs/README.md +54 -0
  320. package/docs/cli.md +198 -0
  321. package/docs/codex.md +210 -0
  322. package/docs/creating-specs.md +197 -0
  323. package/docs/customizing.md +197 -0
  324. package/docs/getting-started.md +140 -0
  325. package/docs/internals/README.md +25 -0
  326. package/docs/internals/adding-a-provider.md +238 -0
  327. package/docs/internals/api-reference.md +634 -0
  328. package/docs/internals/architecture.md +332 -0
  329. package/docs/internals/configuration.md +172 -0
  330. package/docs/internals/openspec-workflow.md +282 -0
  331. package/docs/internals/operations-runbook.md +198 -0
  332. package/docs/internals/profiles.md +152 -0
  333. package/docs/platforms/macos.md +130 -0
  334. package/docs/platforms/windows.md +81 -0
  335. package/docs/running-pipelines.md +240 -0
  336. package/docs/terminal.md +138 -0
  337. package/docs/tracking-cost.md +155 -0
  338. package/package.json +82 -0
  339. package/server/dist/agent-generator.js +232 -0
  340. package/server/dist/agent-refine-db.js +124 -0
  341. package/server/dist/agent-refine-manager.js +526 -0
  342. package/server/dist/ai-invocations.js +111 -0
  343. package/server/dist/attachment-manager.js +299 -0
  344. package/server/dist/auth.js +207 -0
  345. package/server/dist/binary-probe.js +35 -0
  346. package/server/dist/browser-capture-manager.js +576 -0
  347. package/server/dist/browser-capture-types.js +28 -0
  348. package/server/dist/browser-network.js +149 -0
  349. package/server/dist/browser-playwright.js +888 -0
  350. package/server/dist/build-dirs.js +44 -0
  351. package/server/dist/changes-reader.js +120 -0
  352. package/server/dist/chat-manager.js +1060 -0
  353. package/server/dist/chromium-resolver.js +311 -0
  354. package/server/dist/code-explorer-router.js +788 -0
  355. package/server/dist/codex-otel-bridge.js +235 -0
  356. package/server/dist/command-resolver.js +102 -0
  357. package/server/dist/config.js +306 -0
  358. package/server/dist/context-budget.js +113 -0
  359. package/server/dist/context-scope.js +279 -0
  360. package/server/dist/contract-refine-runner.js +521 -0
  361. package/server/dist/core-compat.js +207 -0
  362. package/server/dist/core-package.js +14 -0
  363. package/server/dist/db.js +1034 -0
  364. package/server/dist/desktop-analytics.js +156 -0
  365. package/server/dist/desktop-db.js +456 -0
  366. package/server/dist/desktop-router.js +735 -0
  367. package/server/dist/docs-router.js +207 -0
  368. package/server/dist/explore-contract-refine.js +421 -0
  369. package/server/dist/explore-cwd-manager.js +242 -0
  370. package/server/dist/explore-draft-title.js +47 -0
  371. package/server/dist/explore-smash.js +450 -0
  372. package/server/dist/feature-flags.js +17 -0
  373. package/server/dist/file-provenance.js +382 -0
  374. package/server/dist/file-summary-generator.js +221 -0
  375. package/server/dist/file-summary-manager.js +689 -0
  376. package/server/dist/hooks.js +102 -0
  377. package/server/dist/ids.js +7 -0
  378. package/server/dist/index.js +586 -0
  379. package/server/dist/metrics.js +136 -0
  380. package/server/dist/mobile/index.js +16 -0
  381. package/server/dist/mobile/mobile-admin-router.js +84 -0
  382. package/server/dist/mobile/mobile-auth.js +67 -0
  383. package/server/dist/mobile/mobile-devices.js +80 -0
  384. package/server/dist/mobile/mobile-event-bus.js +39 -0
  385. package/server/dist/mobile/mobile-gateway.js +285 -0
  386. package/server/dist/mobile/mobile-mdns.js +81 -0
  387. package/server/dist/mobile/mobile-pairing.js +179 -0
  388. package/server/dist/mobile/mobile-redact.js +53 -0
  389. package/server/dist/mobile/mobile-router.js +411 -0
  390. package/server/dist/mobile/mobile-tls.js +86 -0
  391. package/server/dist/mobile/mobile-types.js +9 -0
  392. package/server/dist/mobile/mobile-ws.js +275 -0
  393. package/server/dist/path-resolver.js +298 -0
  394. package/server/dist/plugin-manager.js +617 -0
  395. package/server/dist/plugins/claude-approval.js +179 -0
  396. package/server/dist/plugins/claude-md-mutation.js +146 -0
  397. package/server/dist/plugins/codex-mcp.js +108 -0
  398. package/server/dist/plugins/contributors.js +72 -0
  399. package/server/dist/plugins/drift.js +58 -0
  400. package/server/dist/plugins/index.js +14 -0
  401. package/server/dist/plugins/json-mutation.js +120 -0
  402. package/server/dist/plugins/manager.js +32 -0
  403. package/server/dist/plugins/ownership.js +86 -0
  404. package/server/dist/plugins/paths.js +37 -0
  405. package/server/dist/plugins/prereq-installer.js +104 -0
  406. package/server/dist/plugins/rail-integration.js +79 -0
  407. package/server/dist/plugins/serena/index.js +13 -0
  408. package/server/dist/plugins/serena/install.js +91 -0
  409. package/server/dist/plugins/serena/instructions-content.js +21 -0
  410. package/server/dist/plugins/serena/manifest.js +111 -0
  411. package/server/dist/plugins/serena/verify.js +78 -0
  412. package/server/dist/plugins-router.js +215 -0
  413. package/server/dist/pricing.js +89 -0
  414. package/server/dist/profile-manager.js +310 -0
  415. package/server/dist/profiles-router.js +759 -0
  416. package/server/dist/project-registry.js +443 -0
  417. package/server/dist/project-router.js +4016 -0
  418. package/server/dist/proposal-manager.js +291 -0
  419. package/server/dist/provider-selection.js +69 -0
  420. package/server/dist/providers/claude-adapter.js +281 -0
  421. package/server/dist/providers/codex-adapter.js +264 -0
  422. package/server/dist/providers/index.js +23 -0
  423. package/server/dist/providers/registry.js +37 -0
  424. package/server/dist/providers/types.js +22 -0
  425. package/server/dist/queue-manager.js +1511 -0
  426. package/server/dist/rails-router.js +362 -0
  427. package/server/dist/rails-store.js +116 -0
  428. package/server/dist/result-event.js +106 -0
  429. package/server/dist/schemas/profile.v1.json +151 -0
  430. package/server/dist/setup-manager.js +1165 -0
  431. package/server/dist/setup-prerequisites.js +372 -0
  432. package/server/dist/smash-runner.js +663 -0
  433. package/server/dist/spec-draft-parser.js +133 -0
  434. package/server/dist/spec-launcher-manager.js +174 -0
  435. package/server/dist/spec-models.js +32 -0
  436. package/server/dist/specrails-tech-client.js +82 -0
  437. package/server/dist/spending.js +448 -0
  438. package/server/dist/telemetry-compactor.js +180 -0
  439. package/server/dist/telemetry-export.js +317 -0
  440. package/server/dist/telemetry-receiver.js +224 -0
  441. package/server/dist/terminal-manager.js +633 -0
  442. package/server/dist/terminal-marks-store.js +117 -0
  443. package/server/dist/terminal-osc-parser.js +159 -0
  444. package/server/dist/terminal-settings.js +282 -0
  445. package/server/dist/terminal-shell-integration.js +196 -0
  446. package/server/dist/ticket-broadcast.js +47 -0
  447. package/server/dist/ticket-store.js +397 -0
  448. package/server/dist/ticket-watcher.js +117 -0
  449. package/server/dist/types.js +10 -0
  450. package/server/dist/user-mcp-config.js +117 -0
  451. package/server/dist/util/cli-prompt.js +181 -0
  452. package/server/dist/util/secure-fs.js +50 -0
  453. package/server/dist/util/win-spawn.js +43 -0
  454. package/server/dist/webhook-manager.js +89 -0
  455. package/server/dist/ws-routing.js +47 -0
@@ -0,0 +1,372 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MIN_VERSIONS = void 0;
7
+ exports.parseSemver = parseSemver;
8
+ exports.compareVersions = compareVersions;
9
+ exports.getSetupPrerequisitesStatus = getSetupPrerequisitesStatus;
10
+ exports.__resetSetupPrerequisitesCacheForTest = __resetSetupPrerequisitesCacheForTest;
11
+ exports.formatMissingSetupPrerequisites = formatMissingSetupPrerequisites;
12
+ const child_process_1 = require("child_process");
13
+ const fs_1 = __importDefault(require("fs"));
14
+ const path_1 = __importDefault(require("path"));
15
+ const providers_1 = require("./providers");
16
+ const WHICH_CMD = process.platform === 'win32' ? 'where' : 'which';
17
+ exports.MIN_VERSIONS = {
18
+ node: '18.0.0',
19
+ npm: '9.0.0',
20
+ git: '2.20.0',
21
+ uv: '0.1.0',
22
+ };
23
+ function locateCommand(command) {
24
+ const result = (0, child_process_1.spawnSync)(WHICH_CMD, [command], {
25
+ env: process.env,
26
+ shell: process.platform === 'win32',
27
+ encoding: 'utf-8',
28
+ });
29
+ if (result.error || (result.status ?? 1) !== 0)
30
+ return { found: false };
31
+ const resolvedPath = `${result.stdout ?? ''}`.trim().split(/\r?\n/)[0]?.trim() || undefined;
32
+ return { found: true, resolvedPath };
33
+ }
34
+ function probeVersion(command, resolvedPath) {
35
+ // IMPORTANT: prefer the absolute path returned by `which`. When the server is
36
+ // bundled with `pkg`, calling spawn with the bare command name `'node'` is
37
+ // intercepted by pkg's child_process patch and redirected to `process.execPath`
38
+ // (the server binary itself) — the child then crashes with
39
+ // `Cannot find module '/--version'` from pkg/prelude/bootstrap.js. Passing
40
+ // an absolute path bypasses this interception.
41
+ const target = resolvedPath || command;
42
+ // On Windows we must use `shell: true` to execute `.cmd` shims (npm, npx) — Node
43
+ // refuses to spawn them directly since CVE-2024-27980. But cmd.exe splits the
44
+ // command line on whitespace, so an absolute path like
45
+ // `C:\Program Files\Git\cmd\git.exe` becomes `C:\Program` + arg `Files\Git\...`.
46
+ // Wrap the target in double quotes when it contains a space.
47
+ const isWin = process.platform === 'win32';
48
+ const quotedTarget = isWin && /\s/.test(target) ? `"${target}"` : target;
49
+ const result = (0, child_process_1.spawnSync)(quotedTarget, ['--version'], {
50
+ env: process.env,
51
+ shell: isWin,
52
+ encoding: 'utf-8',
53
+ timeout: 5_000,
54
+ });
55
+ if (result.error) {
56
+ const err = result.error;
57
+ return { executed: false, error: `${err.code ?? 'ERR'}: ${err.message}` };
58
+ }
59
+ if ((result.status ?? 1) !== 0) {
60
+ const stderr = `${result.stderr ?? ''}`.trim().slice(0, 400);
61
+ const signal = result.signal ? ` signal=${result.signal}` : '';
62
+ return { executed: false, error: `exit=${result.status ?? '?'}${signal}${stderr ? ` stderr=${stderr}` : ''}` };
63
+ }
64
+ const output = `${result.stdout ?? result.stderr ?? ''}`.trim();
65
+ const version = output.split(/\r?\n/)[0]?.trim() || undefined;
66
+ return { executed: true, version };
67
+ }
68
+ /** Extracts the first `major.minor.patch` triple from a version string.
69
+ * Tolerates prefixes like `v`, `git version `, `node `. */
70
+ function parseSemver(raw) {
71
+ if (!raw)
72
+ return null;
73
+ const match = raw.match(/(\d+)\.(\d+)\.(\d+)/);
74
+ if (!match)
75
+ return null;
76
+ return [Number(match[1]), Number(match[2]), Number(match[3])];
77
+ }
78
+ function compareVersions(a, b) {
79
+ const pa = parseSemver(a);
80
+ const pb = parseSemver(b);
81
+ if (!pa || !pb)
82
+ return 0;
83
+ for (let i = 0; i < 3; i++) {
84
+ if (pa[i] !== pb[i])
85
+ return pa[i] - pb[i];
86
+ }
87
+ return 0;
88
+ }
89
+ function meetsMinimumVersion(version, minVersion) {
90
+ if (!minVersion)
91
+ return true;
92
+ if (!version)
93
+ return false;
94
+ return compareVersions(version, minVersion) >= 0;
95
+ }
96
+ function brokenSymlinkHint(label, command, resolvedPath) {
97
+ const where = resolvedPath ? ` at ${resolvedPath}` : '';
98
+ return `${label} found${where} but failed to execute — possibly a broken symlink or a stale install. Reinstall ${command} or remove the stale link${resolvedPath ? ` at ${resolvedPath}` : ''}.`;
99
+ }
100
+ const BUNDLED_TOOL_KEYS = new Set(['node', 'npm', 'npx', 'git']);
101
+ function isBundledTool(key) {
102
+ return BUNDLED_TOOL_KEYS.has(key);
103
+ }
104
+ /** Candidate absolute paths for a bundled tool, in priority order. Windows git
105
+ * ships the real binary at git/cmd/git.exe with a redirector at git/bin/git.exe
106
+ * — we accept either so a layout shift in the PortableGit extractor degrades to
107
+ * a working alternate rather than a false "corrupted-bundle". */
108
+ function getBundledToolCandidates(runtimesBase, tool) {
109
+ if (process.platform === 'win32') {
110
+ const map = {
111
+ node: [path_1.default.join(runtimesBase, 'node', 'node.exe')],
112
+ npm: [path_1.default.join(runtimesBase, 'node', 'npm.cmd')],
113
+ npx: [path_1.default.join(runtimesBase, 'node', 'npx.cmd')],
114
+ git: [path_1.default.join(runtimesBase, 'git', 'cmd', 'git.exe'), path_1.default.join(runtimesBase, 'git', 'bin', 'git.exe')],
115
+ };
116
+ return map[tool];
117
+ }
118
+ const map = {
119
+ node: [path_1.default.join(runtimesBase, 'node', 'bin', 'node')],
120
+ npm: [path_1.default.join(runtimesBase, 'node', 'bin', 'npm')],
121
+ npx: [path_1.default.join(runtimesBase, 'node', 'bin', 'npx')],
122
+ git: [path_1.default.join(runtimesBase, 'git', 'bin', 'git')],
123
+ };
124
+ return map[tool];
125
+ }
126
+ function fileExists(p) {
127
+ try {
128
+ return fs_1.default.existsSync(p);
129
+ }
130
+ catch {
131
+ return false;
132
+ }
133
+ }
134
+ // Short-lived memo: probing involves up to ~12 synchronous spawnSync calls that
135
+ // block the single Express event loop. The endpoint only fires from low-freq
136
+ // setup flows, so a 30s TTL eliminates repeated probe storms (cold-cache
137
+ // client, window-focus rechecks) without masking real PATH changes.
138
+ let _statusCache = null;
139
+ const STATUS_CACHE_TTL_MS = 30_000;
140
+ function getSetupPrerequisitesStatus(options = {}) {
141
+ const key = options.includeUv ? 'uv' : 'base';
142
+ const now = Date.now();
143
+ if (_statusCache && _statusCache.key === key && now - _statusCache.at < STATUS_CACHE_TTL_MS) {
144
+ return _statusCache.value;
145
+ }
146
+ const value = computeSetupPrerequisitesStatus(options);
147
+ _statusCache = { key, at: now, value };
148
+ return value;
149
+ }
150
+ /** Test-only: clear the short-lived prerequisites memo so each test re-probes. */
151
+ function __resetSetupPrerequisitesCacheForTest() {
152
+ _statusCache = null;
153
+ }
154
+ function computeSetupPrerequisitesStatus(options = {}) {
155
+ const isDesktop = process.env.SPECRAILS_IS_DESKTOP === '1';
156
+ const runtimesBase = process.env.SPECRAILS_BUNDLED_RUNTIMES_PATH ?? '';
157
+ const platform = process.platform === 'darwin'
158
+ ? 'darwin'
159
+ : process.platform === 'win32'
160
+ ? 'win32'
161
+ : 'linux';
162
+ const definitions = [
163
+ {
164
+ key: 'node',
165
+ kind: 'tool',
166
+ label: 'Node.js',
167
+ command: 'node',
168
+ required: true,
169
+ minVersion: exports.MIN_VERSIONS.node,
170
+ installUrl: 'https://nodejs.org/en/download',
171
+ installHint: process.platform === 'win32'
172
+ ? 'Install Node.js LTS, then restart Specrails so Windows refreshes PATH.'
173
+ : 'Install Node.js LTS, then restart Specrails so PATH is refreshed.',
174
+ },
175
+ {
176
+ key: 'npm',
177
+ kind: 'tool',
178
+ label: 'npm',
179
+ command: 'npm',
180
+ required: true,
181
+ minVersion: exports.MIN_VERSIONS.npm,
182
+ installUrl: 'https://nodejs.org/en/download',
183
+ installHint: 'npm ships with Node.js LTS.',
184
+ },
185
+ {
186
+ key: 'npx',
187
+ kind: 'tool',
188
+ label: 'npx',
189
+ command: 'npx',
190
+ required: true,
191
+ installUrl: 'https://nodejs.org/en/download',
192
+ installHint: 'npx ships with npm and is required to run specrails-core.',
193
+ },
194
+ {
195
+ key: 'git',
196
+ kind: 'tool',
197
+ label: 'Git',
198
+ command: 'git',
199
+ required: true,
200
+ minVersion: exports.MIN_VERSIONS.git,
201
+ installUrl: process.platform === 'win32'
202
+ ? 'https://git-scm.com/download/win'
203
+ : 'https://git-scm.com/downloads',
204
+ installHint: process.platform === 'win32'
205
+ ? 'Install Git for Windows and enable the option that adds Git to PATH, then restart Specrails.'
206
+ : 'Install Git and restart Specrails if PATH changed.',
207
+ },
208
+ ];
209
+ // Provider CLIs (one entry per registered adapter). Individually `required:
210
+ // false` — the "at least one provider" rule is enforced at the bottom of
211
+ // this function, not via `required`.
212
+ for (const adapter of (0, providers_1.listAdapters)()) {
213
+ definitions.push({
214
+ key: adapter.id,
215
+ kind: 'provider',
216
+ label: adapter.displayName,
217
+ command: adapter.binary,
218
+ required: false,
219
+ minVersion: adapter.minCliVersion ?? undefined,
220
+ installUrl: providerInstallUrl(adapter.id),
221
+ installHint: providerInstallHint(adapter.id, process.platform),
222
+ });
223
+ }
224
+ if (options.includeUv) {
225
+ definitions.push({
226
+ key: 'uv',
227
+ kind: 'tool',
228
+ label: 'uv',
229
+ command: 'uv',
230
+ required: false,
231
+ minVersion: exports.MIN_VERSIONS.uv,
232
+ installUrl: 'https://docs.astral.sh/uv/getting-started/installation/',
233
+ installHint: process.platform === 'win32'
234
+ ? 'Install uv via winget (`winget install astral-sh.uv`) or PowerShell installer, then restart Specrails.'
235
+ : process.platform === 'darwin'
236
+ ? 'Install uv via Homebrew (`brew install uv`) or the curl installer, then restart Specrails.'
237
+ : 'Install uv via the curl installer (`curl -LsSf https://astral.sh/uv/install.sh | sh`), then restart Specrails.',
238
+ });
239
+ }
240
+ const prerequisites = definitions.map((definition) => {
241
+ // Desktop mode: probe bundled absolute paths for node/npm/npx/git.
242
+ // Provider CLIs (claude, codex) are always probed via system PATH regardless of mode.
243
+ if (isDesktop && definition.kind === 'tool' && isBundledTool(definition.key)) {
244
+ const candidates = getBundledToolCandidates(runtimesBase, definition.key);
245
+ const bundledPath = candidates.find(fileExists);
246
+ // Only treat as bundled when the binary FILE actually exists. A missing
247
+ // file means this build never shipped runtimes for this platform/arch
248
+ // (e.g. a runtimes-less Windows ARM64 build, or a partial CI extraction)
249
+ // — fall through to the system probe so a system-installed tool still
250
+ // satisfies the requirement, instead of dead-ending Add Project with a
251
+ // futile "reinstall the app" message. 'corrupted-bundle' is reserved for
252
+ // the case where the file EXISTS but fails its --version probe.
253
+ if (bundledPath) {
254
+ const probe = probeVersion(definition.key, bundledPath);
255
+ if (!probe.executed) {
256
+ return {
257
+ ...definition,
258
+ installed: true,
259
+ executable: false,
260
+ bundled: true,
261
+ error: 'corrupted-bundle',
262
+ resolvedPath: bundledPath,
263
+ executionError: probe.error,
264
+ meetsMinimum: false,
265
+ installHint: 'Bundle corrupted — reinstall the Specrails app.',
266
+ };
267
+ }
268
+ return {
269
+ ...definition,
270
+ installed: true,
271
+ executable: true,
272
+ bundled: true,
273
+ version: probe.version,
274
+ resolvedPath: bundledPath,
275
+ meetsMinimum: meetsMinimumVersion(probe.version, definition.minVersion),
276
+ installHint: '',
277
+ };
278
+ }
279
+ // bundledPath not found → fall through to the system probe below.
280
+ }
281
+ // Non-desktop (or provider CLI in any mode, or desktop with bundle absent): system probe.
282
+ const lookup = locateCommand(definition.command);
283
+ const installed = lookup.found;
284
+ let executable = false;
285
+ let version;
286
+ let executionError;
287
+ if (installed) {
288
+ const probe = probeVersion(definition.command, lookup.resolvedPath);
289
+ executable = probe.executed;
290
+ version = probe.version;
291
+ executionError = probe.error;
292
+ }
293
+ const meetsMinimum = installed && executable && meetsMinimumVersion(version, definition.minVersion);
294
+ const installHint = installed && !executable
295
+ ? brokenSymlinkHint(definition.label, definition.command, lookup.resolvedPath)
296
+ : definition.installHint;
297
+ return {
298
+ ...definition,
299
+ installed,
300
+ executable,
301
+ version,
302
+ resolvedPath: lookup.resolvedPath,
303
+ executionError,
304
+ meetsMinimum,
305
+ installHint,
306
+ };
307
+ });
308
+ // A required tool counts as missing if not installed, not executable, or below its minimum version.
309
+ const missingRequired = prerequisites.filter((item) => item.required && (!item.installed || !item.executable || !item.meetsMinimum));
310
+ // At-least-one provider rule: if no provider entry is usable, surface a
311
+ // synthetic "missing required" entry so the UI blocks Add Project.
312
+ const providers = prerequisites.filter((p) => p.kind === 'provider');
313
+ const anyProviderUsable = providers.some((p) => p.installed && p.executable && p.meetsMinimum);
314
+ if (providers.length > 0 && !anyProviderUsable) {
315
+ // Mark all provider rows as missingRequired so PrerequisitesPanel renders
316
+ // them visibly. They keep `required: false` so the type still matches the
317
+ // tool semantics; the panel inspects `kind === 'provider'` for grouping.
318
+ for (const p of providers)
319
+ missingRequired.push(p);
320
+ }
321
+ return {
322
+ ok: missingRequired.length === 0,
323
+ platform,
324
+ prerequisites,
325
+ missingRequired,
326
+ };
327
+ }
328
+ // ─── Provider install hints ────────────────────────────────────────────────
329
+ function providerInstallUrl(id) {
330
+ switch (id) {
331
+ case 'claude':
332
+ return 'https://claude.com/download';
333
+ case 'codex':
334
+ return 'https://developers.openai.com/codex';
335
+ default:
336
+ return 'https://github.com';
337
+ }
338
+ }
339
+ function providerInstallHint(id, platform) {
340
+ switch (id) {
341
+ case 'claude':
342
+ return 'Install Claude Code from https://claude.com/download, run `claude login`, then restart Specrails.';
343
+ case 'codex':
344
+ return platform === 'darwin'
345
+ ? 'Install Codex CLI via `brew install codex` (or follow https://developers.openai.com/codex), authenticate with `codex login`, then restart Specrails.'
346
+ : platform === 'win32'
347
+ ? 'Install Codex CLI from https://developers.openai.com/codex, authenticate with `codex login`, then restart Specrails.'
348
+ : 'Install Codex CLI from https://developers.openai.com/codex (or `pipx install codex-cli`), authenticate with `codex login`, then restart Specrails.';
349
+ default:
350
+ return `Install the ${id} CLI and restart Specrails.`;
351
+ }
352
+ }
353
+ function formatMissingSetupPrerequisites(status = getSetupPrerequisitesStatus()) {
354
+ if (status.ok)
355
+ return null;
356
+ return [
357
+ 'SpecRails setup needs a few developer tools before it can install this project.',
358
+ '',
359
+ ...status.missingRequired.map((item) => {
360
+ if (!item.installed) {
361
+ return `- ${item.label} (${item.command}) is not on PATH. ${item.installHint}`;
362
+ }
363
+ if (!item.executable) {
364
+ return `- ${item.installHint}`;
365
+ }
366
+ // installed and executable but below minimum version
367
+ return `- ${item.label} ${item.version ?? '?'} found, but version ${item.minVersion}+ is required. ${item.installHint}`;
368
+ }),
369
+ '',
370
+ 'Install the missing tools, restart Specrails, then retry setup.',
371
+ ].join('\n');
372
+ }