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,140 @@
1
+ # Getting started
2
+
3
+ This guide walks you from "I just heard about specrails-desktop" to "I just shipped my first AI-driven change" in about ten minutes. No prior knowledge of specrails-core required — the app installs it for you.
4
+
5
+ ## What you'll need
6
+
7
+ - **An AI CLI signed in** — either [Claude Code](https://claude.com/claude-code) (via Claude subscription login or an `ANTHROPIC_API_KEY`) or the Codex CLI. You can use one or both — see [Codex](codex.md).
8
+ - A project you want to work on (any Git repository works)
9
+
10
+ If you install with **npm** (Option 2 below) you'll also need **Node.js 20+** and **`git`** on your PATH. The **desktop app** bundles its own Node and Git runtimes, so you don't need those installed separately.
11
+
12
+ That's it. specrails-desktop will install specrails-core in your project on first run if it isn't there yet.
13
+
14
+ ## Install
15
+
16
+ Two options:
17
+
18
+ ### Option 1 — Desktop app (recommended)
19
+
20
+ Download a signed build for your OS from `https://specrails.dev/downloads/specrails-desktop/latest/`:
21
+
22
+ - **macOS** — `specrails-desktop-<version>-aarch64.dmg` (Apple Silicon, notarised)
23
+ - **Windows** — `specrails-desktop-<version>-x64-setup.exe` (NSIS) or `.msi`
24
+
25
+ Open the installer, drag to Applications (macOS) or click through the wizard (Windows). The app bundles the server, so you don't need a separate process. macOS handles all the Homebrew/Volta/nvm PATH gymnastics for you — see [platforms/macos.md](platforms/macos.md) if anything looks off.
26
+
27
+ > First Windows launch shows a SmartScreen warning until the installer is code-signed. Click **More info → Run anyway**. Details and hash-verification steps in [platforms/windows.md](platforms/windows.md).
28
+
29
+ ### Option 2 — npm
30
+
31
+ ```bash
32
+ npm install -g specrails-desktop
33
+ specrails-desktop start
34
+ ```
35
+
36
+ By default the app binds to `http://127.0.0.1:4200`. Open it in your browser.
37
+
38
+ ## Add a project
39
+
40
+ There are two ways. Pick whichever feels natural.
41
+
42
+ **From the dashboard:**
43
+
44
+ 1. Click **+** in the left sidebar.
45
+ 2. Enter the absolute path to your project (e.g. `/Users/you/repos/my-app`).
46
+ 3. Pick your **AI providers**. Check **Claude**, **Codex**, or both — when you select both, the first one becomes the project default. The provider set is fixed once the project is created.
47
+ 4. The prerequisites panel verifies `node`, `npm`, `npx`, `git`. If anything's missing, the panel surfaces OS-aware install commands you can copy.
48
+ 5. Click **Add**.
49
+
50
+ **From the CLI:**
51
+
52
+ ```bash
53
+ specrails-desktop add /path/to/your/project
54
+ specrails-desktop list # verify
55
+ ```
56
+
57
+ ### If the project doesn't have specrails-core yet
58
+
59
+ The setup wizard runs automatically. Three steps:
60
+
61
+ 1. **Configure** — choose which agents to install (the baseline trio `sr-architect`, `sr-developer`, `sr-reviewer` is always selected; optional agents like Test Writer or Security Reviewer are opt-in). Pick a model preset (Balanced / Budget / Max) and optionally override the model per agent.
62
+ 2. **Install** — the app runs the installer (`npx specrails-core@latest init --yes --from-config <config>`) non-interactively and streams the output live.
63
+ 3. **Done** — a summary tells you how many agents and commands landed. Click **Continue to project**.
64
+
65
+ That's the whole onboarding. No tier picker, no second wizard. You can manage agents and their per-agent models later from the **Agents** page (Profiles tab).
66
+
67
+ ## Your first spec
68
+
69
+ A "spec" is a description of work you want done. specrails-desktop gives you two ways to author them.
70
+
71
+ ### Quick mode — one-shot generation
72
+
73
+ When you already know what you want:
74
+
75
+ 1. On the Dashboard, click **+ Add Spec → Quick**.
76
+ 2. Type a one-line title (e.g. *"Add a webhook retry with exponential backoff"*).
77
+ 3. (Optional) toggle **Enrich with Contract Layer** to get a structured block of names, data shapes, invariants, and a file touch list appended to the description.
78
+ 4. Hit Enter.
79
+
80
+ Your AI CLI generates the full spec in one turn. A small toast at the bottom right shows the project, the spec title, and live elapsed time ("Generating… 0:12") — it turns into a success or failure toast (with a **View** action) when generation finishes.
81
+
82
+ ### Explore mode — converse with the AI
83
+
84
+ When the spec needs shaping:
85
+
86
+ 1. Click **+ Add Spec → Explore**.
87
+ 2. (Optional) pick a context preset from the slider — `Minimal` (just your message) up to `Desktop` (the full codebase + Contract Layer enrichment + project and user-approved MCPs).
88
+ 3. Type a starting message. The AI responds with a live draft below.
89
+ 4. Iterate. Each turn updates the draft.
90
+ 5. Click **Save as Draft** to come back later, or **Create Spec** when the draft looks right.
91
+
92
+ The committed spec lands on your board with status `todo`.
93
+
94
+ ## Run your first pipeline
95
+
96
+ The right pane of the Dashboard is your **Rails** — execution lanes:
97
+
98
+ 1. Drag a spec card from the left pane onto a Rail.
99
+ 2. (Optional) pick an **agent profile** from the rail header. This picker only appears once the project has profiles (create them on the **Agents** page); otherwise the rail runs in legacy mode (single orchestrator, no per-agent overrides).
100
+ 3. Press **▶ Play** on the rail.
101
+
102
+ The rail flips to running. The Jobs page (right sidebar) streams the AI's output live. When the slash command defines them, you'll see the pipeline phases progress: Architect → Developer → Reviewer → Ship.
103
+
104
+ Token usage, duration, and cost are tracked per turn and surface in:
105
+
106
+ - **Jobs page** — each job has a status panel with live counters and a `JobTicketHeader` chip for every ticket the job touched (click to open).
107
+ - **Analytics page** — burn rate, top tickets, daily timeline (see [Tracking cost](tracking-cost.md)).
108
+ - **The spec's detail modal** — a one-line spending summary linking back to Analytics filtered by that ticket.
109
+
110
+ ## What's next?
111
+
112
+ - **[Creating specs](creating-specs.md)** — drafts, SMASH (decompose epics), Continue Editing (refine specs in place), Compare (side-by-side review).
113
+ - **[Running pipelines](running-pipelines.md)** — agent profiles, plugins (Serena), telemetry export.
114
+ - **[Tracking cost](tracking-cost.md)** — analytics deep dive and CSV exports.
115
+ - **[Codex](codex.md)** — using the Codex CLI as a provider, alongside or instead of Claude.
116
+ - **[Terminal panel](terminal.md)** — the built-in per-project terminal (toggle with `Cmd/Ctrl+J`).
117
+ - **[Customising the app](customizing.md)** — themes, terminal settings, kill switches.
118
+ - **[CLI reference](cli.md)** — drive specrails-desktop from the terminal.
119
+
120
+ ## Troubleshooting
121
+
122
+ **"Port 4200 already in use" on start**
123
+
124
+ ```bash
125
+ specrails-desktop stop # stops the running server cleanly
126
+ # or kill the process holding the port
127
+ lsof -i :4200 # macOS / Linux
128
+ ```
129
+
130
+ **The `claude` command isn't found inside the app**
131
+
132
+ On macOS, this usually means the app was launched from Finder/Dock and didn't pick up Homebrew/Volta paths. The app fixes this at startup automatically, but if it still fails, see [platforms/macos.md](platforms/macos.md).
133
+
134
+ **The setup wizard fails on `npx specrails-core@latest init`**
135
+
136
+ Most likely Node is missing from the shell environment that launched the app, or your AI CLI isn't authenticated (sign in to the `claude` CLI or set `ANTHROPIC_API_KEY`; for Codex, sign in to the `codex` CLI). Click **Copy diagnostics** in the install-instructions modal — that prints the resolved PATH, where the app found each tool, and login-shell status. Paste it into a bug report if you can't figure it out.
137
+
138
+ **More**
139
+
140
+ Operational issues (port conflicts, stale PID files, database corruption) are covered in the [Operations runbook](internals/operations-runbook.md).
@@ -0,0 +1,25 @@
1
+ # Internals
2
+
3
+ These docs are primarily for contributors and people building on the app's API. They mostly describe how the app works under the hood — though a couple (like the profiles quick start) double as practical how-tos.
4
+
5
+ If you're a user looking for **how do I do X?** docs, head back to the [user guides](../README.md).
6
+
7
+ ## Contents
8
+
9
+ | Doc | What it covers |
10
+ |-----|----------------|
11
+ | [architecture.md](architecture.md) | Server modules, client layout, WebSocket protocol, process spawning, security model |
12
+ | [api-reference.md](api-reference.md) | REST endpoint catalogue under `/api/*` and `/api/projects/:projectId/*` |
13
+ | [configuration.md](configuration.md) | Settings, env vars, kill switches, advanced flags |
14
+ | [operations-runbook.md](operations-runbook.md) | Start/stop, port conflicts, recovery procedures, backups |
15
+ | [openspec-workflow.md](openspec-workflow.md) | `opsx:*` change lifecycle — used by the app itself for structured change management |
16
+ | [adding-a-provider.md](adding-a-provider.md) | How to add a new AI CLI: one adapter file plus one entry in the registry |
17
+ | [profiles.md](profiles.md) | Agent profiles quick start: open the Agents section, pick a profile per rail at launch, author custom agents in Agent Studio. For the true file-format and snapshotting internals, read `server/profile-manager.ts` and the profile-manager section of `CLAUDE.md` |
18
+
19
+ **See also:** [`../codex.md`](../codex.md) for the multi-provider model (Claude Code + Codex CLI as first-class engines).
20
+
21
+ ## Contributing
22
+
23
+ For coding conventions, file naming, the coverage policy, and how WebSocket handlers are expected to be wired, see [`CLAUDE.md`](../../CLAUDE.md) at the repo root. That file is the authoritative source for project-wide rules.
24
+
25
+ When adding a feature, follow the OpenSpec workflow: `/opsx:new → /opsx:ff → /opsx:apply → /opsx:verify → /opsx:archive`. The `/opsx:*` invocations resolve to command files under `.claude/commands/opsx/*.md` (the related skills under `.claude/skills/` are named `openspec-*`).
@@ -0,0 +1,238 @@
1
+ # Adding a new AI provider to Specrails
2
+
3
+ The app is provider-agnostic by design. Every manager that spawns an AI
4
+ CLI consumes a `ProviderAdapter` rather than branching on a hardcoded
5
+ `if (provider === 'claude')`. Adding a new provider is mostly one adapter
6
+ file plus one entry in the registry — but the codebase still carries a
7
+ handful of `'claude' | 'codex'` type unions and two hardcoded provider
8
+ lists that you must widen by hand today. Those are tracked in the
9
+ **Type-union widening** and **Manual wiring still required** sections
10
+ below.
11
+
12
+ If you find yourself wanting to write `if (this._provider === 'X')` in
13
+ a manager, **the design has drifted** — find the capability you're
14
+ gating on, add a flag to `ProviderCapabilities`, and branch on the
15
+ flag instead.
16
+
17
+ ## The recipe
18
+
19
+ ### 1. Implement the adapter
20
+
21
+ Create `server/providers/<id>-adapter.ts` exporting a `const` of type
22
+ `ProviderAdapter`:
23
+
24
+ ```ts
25
+ import type { ProviderAdapter, SpawnAction, SpawnOptions, AdapterEvent, NormalisedResult, DetectionResult } from './types'
26
+
27
+ const MODELS = [
28
+ { value: 'flagship', label: 'Provider X Flagship', default: true as const },
29
+ { value: 'fast', label: 'Provider X Fast' },
30
+ ] as const
31
+
32
+ export const exampleAdapter: ProviderAdapter = {
33
+ id: 'example',
34
+ displayName: 'Example CLI',
35
+ binary: 'example',
36
+ minCliVersion: '1.0.0',
37
+ projectDirName: '.example',
38
+ instructionsFilename: 'EXAMPLE.md',
39
+ mcpRegistration: 'cli-add', // or 'project-json'
40
+ capabilities: {
41
+ nativeResume: true,
42
+ nativeStreamJson: true,
43
+ nativeCostUsd: false, // if false, add the provider:model entries to server/pricing.ts
44
+ nativeOtelEnv: false, // if false, the app will synthesise OTEL via the bridge
45
+ profileEnvSupport: true,
46
+ systemPromptArg: false,
47
+ },
48
+ modelCatalog: () => MODELS,
49
+ defaultModel: () => 'flagship',
50
+ buildArgs: (action: SpawnAction, opts: SpawnOptions): string[] => { /* per-action argv */ },
51
+ parseStreamLine: (line: string): AdapterEvent | null => { /* line → canonical event */ },
52
+ extractResult: (events): NormalisedResult => { /* events → tokens/cost/session */ },
53
+ baselineAgents: () => ['sr-architect', 'sr-developer', 'sr-reviewer'],
54
+ detectInstalled: async (): Promise<DetectionResult> => { /* `which` + `--version` */ },
55
+ }
56
+ ```
57
+
58
+ The `ProviderAdapter` interface is documented in
59
+ `server/providers/types.ts`. Read the existing
60
+ `server/providers/{claude,codex}-adapter.ts` for the patterns —
61
+ `SpawnAction` shapes per provider, `text-delta` event normalisation
62
+ across native JSONL formats, etc. Note the shipped baseline is the
63
+ three-agent trio `['sr-architect', 'sr-developer', 'sr-reviewer']`;
64
+ `ProfileManager` validation requires exactly your `baselineAgents()` to
65
+ be present in every profile chain, so don't add agents your scaffold
66
+ won't actually create.
67
+
68
+ `parseStreamLine` returns `null` for empty input lines **and** for lines
69
+ that fail `JSON.parse` (see `server/providers/codex-adapter.ts`); unknown
70
+ JSON event types resolve to `{ kind: 'other' }`. Write your tests
71
+ accordingly — don't assume null-only-on-empty.
72
+
73
+ ### 2. Register it
74
+
75
+ Append the import to `server/providers/index.ts`:
76
+
77
+ ```ts
78
+ import { register } from './registry'
79
+ import { claudeAdapter } from './claude-adapter'
80
+ import { codexAdapter } from './codex-adapter'
81
+ import { exampleAdapter } from './example-adapter' // ← add this
82
+
83
+ register(claudeAdapter)
84
+ register(codexAdapter)
85
+ register(exampleAdapter) // ← and this
86
+ ```
87
+
88
+ **Truly automatic** (these walk the registry, so they pick up the new
89
+ provider with zero edits):
90
+
91
+ - `getAdapter` / `listAdapters` / `hasAdapter` (`server/providers/registry.ts`).
92
+ - `detectAvailableCLIs` (`server/core-compat.ts`).
93
+ - `POST /api/projects` provider validation (`server/desktop-router.ts`,
94
+ via `hasAdapter` / `listAdapters`).
95
+ - `setup-prerequisites` provider rows (`server/setup-prerequisites.ts`,
96
+ iterates `listAdapters()`).
97
+ - Analytics `byProvider` (`server/spending.ts`) and the
98
+ `ProviderBreakdownCard` (`client/src/components/analytics/ProviderBreakdownCard.tsx`).
99
+
100
+ **Manual wiring still required** (these hardcode `claude` / `codex`
101
+ today and will NOT surface a 4th provider until edited):
102
+
103
+ - `GET /api/available-providers` (`server/desktop-router.ts`) returns a
104
+ literal `{ claude, codex }` shape — add your key.
105
+ - `AddProjectDialog` (`client/src/components/AddProjectDialog.tsx`)
106
+ hardcodes `PROVIDER_ORDER = ['claude', 'codex']` and reads
107
+ `data.claude` / `data.codex` explicitly. Without editing it the
108
+ provider won't appear in the Add Project UI.
109
+ - `providerInstallUrl` / `providerInstallHint`
110
+ (`server/setup-prerequisites.ts`) have generic `default:` fallbacks so
111
+ nothing crashes, but a good install hint needs a `case` for your id.
112
+
113
+ ### Type-union widening
114
+
115
+ A 4th provider is a **compile-time blocker** until you widen the
116
+ `'claude' | 'codex'` unions still scattered across the server. The build
117
+ fails until they're widened (or migrated to a shared `ProviderId`):
118
+
119
+ - `CliProvider` (`server/desktop-db.ts`) — the canonical project-row provider type.
120
+ - `SpecProvider` (`server/spec-models.ts`).
121
+ - The inline `'claude' | 'codex'` unions in `server/queue-manager.ts`
122
+ (`EnqueueOptions.provider`, `_jobProviderSelection`),
123
+ `server/chat-manager.ts`, `server/agent-refine-manager.ts`, and
124
+ `server/project-registry.ts`.
125
+
126
+ Expect to widen roughly eight unions. The long-term goal is to delete
127
+ them in favour of a single `ProviderId` derived from the registry — if
128
+ you add a new hardcoded site instead of widening the existing ones, file
129
+ an OpenSpec change first (see the closing section).
130
+
131
+ ### 3. (If `nativeCostUsd === false`) add pricing entries
132
+
133
+ For providers that don't report `total_cost_usd` in their terminal
134
+ event, append the rate card to `server/pricing.ts`:
135
+
136
+ ```ts
137
+ 'example:flagship': { inputPer1M: 5.00, outputPer1M: 15.00, cacheReadPer1M: 0.50, lastReviewedAt: '2026-05-18' },
138
+ 'example:fast': { inputPer1M: 0.50, outputPer1M: 1.50, cacheReadPer1M: 0.05, lastReviewedAt: '2026-05-18' },
139
+ ```
140
+
141
+ The `finaliseInvocationResult` flow in `server/result-event.ts` falls
142
+ back to this table automatically and returns an `estimated` flag that
143
+ `recordInvocation` (`server/ai-invocations.ts`) persists as
144
+ `total_cost_usd_estimated = 1` on the `ai_invocations` row, which in
145
+ turn lights up the `~` tilde + Hero footnote on the AnalyticsPage.
146
+
147
+ ### 4. (If `nativeOtelEnv === false`) confirm the OTEL bridge works
148
+
149
+ The synthetic OTEL bridge at `server/codex-otel-bridge.ts` is
150
+ provider-neutral despite its name — it consumes the canonical
151
+ `AdapterEvent` stream. As long as your adapter's `parseStreamLine`
152
+ emits `text-delta`, `tool-use`, `session-started`, and `result` events,
153
+ the bridge will synthesise traces / metrics / logs for free. The
154
+ exported factory is still named `createCodexOtelBridge`; if that bugs
155
+ you, renaming it to `createSyntheticOtelBridge` (and updating callers)
156
+ is safe — same logic.
157
+
158
+ ### 5. (If `mcpRegistration === 'cli-add'`) wire the plugin install path
159
+
160
+ The codex MCP integration lives at `server/plugins/codex-mcp.ts`.
161
+ Mirror that file for a new `<provider>-mcp.ts` if your provider has a
162
+ similar `<binary> mcp add/remove/list` subcommand. Then update
163
+ `server/plugins/serena/install.ts`, which routes to the CLI-add helper
164
+ whenever `getAdapter(providerId).mcpRegistration === 'cli-add'`. The
165
+ app-level `PluginManager` already threads `providerId` through every
166
+ relevant method.
167
+
168
+ For `mcpRegistration === 'project-json'` providers, the existing
169
+ `.mcp.json` surgical-merge path applies — nothing to add.
170
+
171
+ ## Known gotchas
172
+
173
+ - **Legacy result path.** `normaliseResultEvent(event, provider)`
174
+ (`server/result-event.ts`) is still live for any callsite not yet
175
+ migrated to `finaliseInvocationResult`. It only special-cases
176
+ `provider === 'claude'`; everything else falls into the non-claude
177
+ (codex-shaped) branch. A 4th provider hitting that path would be
178
+ silently parsed as codex — migrate the callsite or extend the branch.
179
+ - **Rail slash-command translation is provider-specific.** In
180
+ `server/queue-manager.ts` the rail prompt builder rewrites
181
+ `/specrails:<name>` → `$<name>` for codex (so codex picks up the
182
+ matching `.codex/skills/<name>/SKILL.md`), while claude passes the
183
+ command verbatim. A new adapter falls through to the claude branch
184
+ (verbatim). If your CLI needs a different invocation syntax, add a
185
+ branch keyed on a capability, not on the provider id.
186
+
187
+ ## Drop a fixture set
188
+
189
+ Add a JSONL capture of a real `<binary> exec --json` (or whatever your
190
+ CLI's JSONL flag is) under
191
+ `server/providers/__fixtures__/<id>/<minCliVersion>/`. The adapter's
192
+ test suite consumes these so future CLI-version bumps surface schema
193
+ drift loudly instead of silently.
194
+
195
+ ## Write the tests
196
+
197
+ Mirror the test layout under `server/providers/<id>-adapter.test.ts`.
198
+ Required coverage:
199
+
200
+ - Identity: id / binary / projectDirName / instructionsFilename /
201
+ mcpRegistration / capability flags / model catalog.
202
+ - `buildArgs` for every `SpawnAction` the manager flow uses (today:
203
+ `chat-turn`, `chat-resume`, `rail-job`, `spec-gen`, `agent-refine`,
204
+ `setup-enrich`, `setup-enrich-resume`, `auto-title`).
205
+ - `parseStreamLine` per event type, including an "unknown type maps
206
+ to kind: 'other'" defensive test and a "returns null on empty input
207
+ and on unparseable JSON" test.
208
+ - `extractResult` from a fixture-derived event sequence.
209
+ - `detectInstalled` happy / missing / non-zero-exit paths.
210
+
211
+ ## Verify
212
+
213
+ ```bash
214
+ npm run typecheck
215
+ npx vitest run server/providers server/pricing server/result-event server/plugin-manager
216
+ ```
217
+
218
+ `npm run typecheck` runs `tsc --noEmit` for both the server and the
219
+ client — important here, because the type-union widening above touches
220
+ types both halves import, and a missed union surfaces only on the side
221
+ you didn't check.
222
+
223
+ Then a manual smoke test: register a project via the UI with the new
224
+ provider, run a chat turn, run a rail, confirm tokens + cost land on
225
+ the AnalyticsPage.
226
+
227
+ ## Don't break the principle
228
+
229
+ The drift inventory above — the two hardcoded provider lists, the ~8
230
+ `'claude' | 'codex'` unions, the legacy `normaliseResultEvent` branch,
231
+ and the provider-specific rail rewrite — is the current debt. The
232
+ long-term goal is to delete every one of those sites in favour of a
233
+ registry-derived `ProviderId` so that adding a fifth provider really is
234
+ just the adapter file plus the registry entry. If you find a NEW
235
+ hardcoded `if (provider === 'X')` site that this guide doesn't list,
236
+ **the architecture has drifted further** — file an OpenSpec change at
237
+ `openspec/changes/<your-change-name>/` and capture the drift before
238
+ papering over it with another manager-level branch.