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,291 @@
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.ProposalManager = void 0;
7
+ const readline_1 = require("readline");
8
+ const tree_kill_1 = __importDefault(require("tree-kill"));
9
+ const cli_prompt_1 = require("./util/cli-prompt");
10
+ const db_1 = require("./db");
11
+ const command_resolver_1 = require("./command-resolver");
12
+ // ─── ProposalManager ──────────────────────────────────────────────────────────
13
+ class ProposalManager {
14
+ _broadcast;
15
+ _db;
16
+ _cwd;
17
+ _activeProcesses;
18
+ _buffers;
19
+ _disposed = false;
20
+ constructor(broadcast, db, cwd) {
21
+ this._broadcast = broadcast;
22
+ this._db = db;
23
+ this._cwd = cwd;
24
+ this._activeProcesses = new Map();
25
+ this._buffers = new Map();
26
+ }
27
+ isActive(proposalId) {
28
+ return this._activeProcesses.has(proposalId);
29
+ }
30
+ /**
31
+ * Tear down before the project's DB is closed (M12). Disposes so in-flight
32
+ * close/error handlers skip their updateProposal DB writes (which would throw
33
+ * on the closed connection and crash the app), and SIGTERMs orphaned children.
34
+ */
35
+ shutdown() {
36
+ this._disposed = true;
37
+ for (const child of this._activeProcesses.values()) {
38
+ if (child.pid) {
39
+ try {
40
+ (0, tree_kill_1.default)(child.pid, 'SIGTERM');
41
+ }
42
+ catch { /* ignore */ }
43
+ }
44
+ }
45
+ this._activeProcesses.clear();
46
+ this._buffers.clear();
47
+ }
48
+ async startExploration(proposalId, idea) {
49
+ const proposal = (0, db_1.getProposal)(this._db, proposalId);
50
+ if (!proposal) {
51
+ this._broadcastError(proposalId, 'Proposal not found');
52
+ return;
53
+ }
54
+ // Resolve the command file — error if not installed
55
+ const rawCommand = `/specrails:propose-feature ${idea}`;
56
+ const prompt = (0, command_resolver_1.resolveCommand)(rawCommand, this._cwd);
57
+ if (prompt === rawCommand) {
58
+ (0, db_1.updateProposal)(this._db, proposalId, { status: 'cancelled' });
59
+ this._broadcastError(proposalId, 'This project does not have the /specrails:propose-feature command installed. Run "npx specrails-core@latest" to update.');
60
+ return;
61
+ }
62
+ (0, db_1.updateProposal)(this._db, proposalId, { status: 'exploring' });
63
+ const args = [
64
+ '--dangerously-skip-permissions',
65
+ '--tools', 'default',
66
+ '--output-format', 'stream-json',
67
+ '--verbose',
68
+ '-p', prompt,
69
+ ];
70
+ await this._runProcess(proposalId, args, (fullText, sessionId) => {
71
+ (0, db_1.updateProposal)(this._db, proposalId, {
72
+ status: 'review',
73
+ result_markdown: fullText,
74
+ ...(sessionId ? { session_id: sessionId } : {}),
75
+ });
76
+ this._broadcast({
77
+ type: 'proposal_ready',
78
+ projectId: '',
79
+ proposalId,
80
+ markdown: fullText,
81
+ timestamp: new Date().toISOString(),
82
+ });
83
+ }, () => {
84
+ (0, db_1.updateProposal)(this._db, proposalId, { status: 'input' });
85
+ this._broadcastError(proposalId, 'Exploration failed');
86
+ });
87
+ }
88
+ async sendRefinement(proposalId, feedback) {
89
+ const proposal = (0, db_1.getProposal)(this._db, proposalId);
90
+ if (!proposal) {
91
+ this._broadcastError(proposalId, 'Proposal not found');
92
+ return;
93
+ }
94
+ if (!proposal.session_id) {
95
+ this._broadcastError(proposalId, 'No session available for refinement');
96
+ return;
97
+ }
98
+ (0, db_1.updateProposal)(this._db, proposalId, { status: 'refining' });
99
+ const args = [
100
+ '--dangerously-skip-permissions',
101
+ '--tools', 'default',
102
+ '--output-format', 'stream-json',
103
+ '--verbose',
104
+ '--resume', proposal.session_id,
105
+ '-p', feedback,
106
+ ];
107
+ await this._runProcess(proposalId, args, (fullText, sessionId) => {
108
+ (0, db_1.updateProposal)(this._db, proposalId, {
109
+ status: 'review',
110
+ result_markdown: fullText,
111
+ ...(sessionId ? { session_id: sessionId } : {}),
112
+ });
113
+ this._broadcast({
114
+ type: 'proposal_refined',
115
+ projectId: '',
116
+ proposalId,
117
+ markdown: fullText,
118
+ timestamp: new Date().toISOString(),
119
+ });
120
+ }, () => {
121
+ (0, db_1.updateProposal)(this._db, proposalId, { status: 'review' });
122
+ this._broadcastError(proposalId, 'Refinement failed');
123
+ });
124
+ }
125
+ async createIssue(proposalId) {
126
+ const proposal = (0, db_1.getProposal)(this._db, proposalId);
127
+ if (!proposal) {
128
+ this._broadcastError(proposalId, 'Proposal not found');
129
+ return;
130
+ }
131
+ if (!proposal.session_id) {
132
+ this._broadcastError(proposalId, 'No session available for issue creation');
133
+ return;
134
+ }
135
+ (0, db_1.updateProposal)(this._db, proposalId, { status: 'refining' });
136
+ const prompt = "Based on the proposal above, create a GitHub Issue with the label 'user-proposed'. " +
137
+ "Output only the URL of the created issue on the last line of your response.";
138
+ const args = [
139
+ '--dangerously-skip-permissions',
140
+ '--tools', 'default',
141
+ '--output-format', 'stream-json',
142
+ '--verbose',
143
+ '--resume', proposal.session_id,
144
+ '-p', prompt,
145
+ ];
146
+ await this._runProcess(proposalId, args, (fullText, sessionId) => {
147
+ const match = fullText.match(/https:\/\/github\.com\/[^\s]+\/issues\/\d+/);
148
+ const issueUrl = match ? match[0] : null;
149
+ if (issueUrl) {
150
+ (0, db_1.updateProposal)(this._db, proposalId, {
151
+ status: 'created',
152
+ issue_url: issueUrl,
153
+ ...(sessionId ? { session_id: sessionId } : {}),
154
+ });
155
+ this._broadcast({
156
+ type: 'proposal_issue_created',
157
+ projectId: '',
158
+ proposalId,
159
+ issueUrl,
160
+ timestamp: new Date().toISOString(),
161
+ });
162
+ }
163
+ else {
164
+ (0, db_1.updateProposal)(this._db, proposalId, { status: 'review' });
165
+ this._broadcastError(proposalId, 'Issue creation failed — GitHub CLI may not be available or not authenticated');
166
+ }
167
+ }, () => {
168
+ (0, db_1.updateProposal)(this._db, proposalId, { status: 'review' });
169
+ this._broadcastError(proposalId, 'Issue creation failed');
170
+ });
171
+ }
172
+ cancel(proposalId) {
173
+ const child = this._activeProcesses.get(proposalId);
174
+ if (child?.pid) {
175
+ (0, tree_kill_1.default)(child.pid, 'SIGTERM');
176
+ }
177
+ (0, db_1.updateProposal)(this._db, proposalId, { status: 'cancelled' });
178
+ this._broadcast({
179
+ type: 'proposal_error',
180
+ projectId: '',
181
+ proposalId,
182
+ error: 'cancelled',
183
+ timestamp: new Date().toISOString(),
184
+ });
185
+ }
186
+ // ─── Private helpers ───────────────────────────────────────────────────────
187
+ async _runProcess(proposalId, args, onSuccess, onError) {
188
+ // spawnClaude reroutes multi-line argv values through stdin on Windows.
189
+ const child = (0, cli_prompt_1.spawnClaude)(args, {
190
+ env: process.env,
191
+ stdio: ['ignore', 'pipe', 'pipe'],
192
+ cwd: this._cwd,
193
+ });
194
+ this._activeProcesses.set(proposalId, child);
195
+ this._buffers.set(proposalId, '');
196
+ let capturedSessionId = null;
197
+ const stdoutReader = (0, readline_1.createInterface)({ input: child.stdout, crlfDelay: Infinity });
198
+ stdoutReader.on('line', (line) => {
199
+ let parsed = null;
200
+ try {
201
+ parsed = JSON.parse(line);
202
+ }
203
+ catch { /* skip non-JSON */ }
204
+ if (!parsed)
205
+ return;
206
+ const eventType = parsed.type;
207
+ if (eventType === 'result') {
208
+ const sid = parsed.session_id;
209
+ if (sid)
210
+ capturedSessionId = sid;
211
+ }
212
+ if (eventType === 'assistant') {
213
+ const msg = parsed.message;
214
+ const blocks = msg?.content ?? [];
215
+ // Extract text from text blocks (skip thinking blocks)
216
+ const texts = blocks
217
+ .filter((c) => c.type === 'text')
218
+ .map((c) => c.text ?? '');
219
+ const newText = texts.join('');
220
+ if (newText) {
221
+ const prev = this._buffers.get(proposalId) ?? '';
222
+ this._buffers.set(proposalId, prev + newText);
223
+ this._broadcast({
224
+ type: 'proposal_stream',
225
+ projectId: '',
226
+ proposalId,
227
+ delta: newText,
228
+ timestamp: new Date().toISOString(),
229
+ });
230
+ }
231
+ // Broadcast tool_use activity so the UI can show "reading codebase..."
232
+ for (const block of blocks) {
233
+ if (block.type === 'tool_use' && block.name) {
234
+ this._broadcast({
235
+ type: 'proposal_stream',
236
+ projectId: '',
237
+ proposalId,
238
+ delta: `<!--tool:${block.name}-->`,
239
+ timestamp: new Date().toISOString(),
240
+ });
241
+ }
242
+ }
243
+ }
244
+ });
245
+ return new Promise((resolve) => {
246
+ // Without this handler an ENOENT on spawn (e.g. `claude` not on
247
+ // PATH) propagates as an unhandled 'error' event and crashes the
248
+ // entire app process. Surface to the user instead.
249
+ /* c8 ignore start -- spawn-failure path; exercised manually, not in CI */
250
+ child.on('error', (err) => {
251
+ console.error(`[ProposalManager] spawn failed for ${proposalId}: ${err.message}`);
252
+ this._activeProcesses.delete(proposalId);
253
+ this._buffers.delete(proposalId);
254
+ if (this._disposed) {
255
+ resolve();
256
+ return;
257
+ } // M12: project removed mid-flight; DB closing
258
+ this._broadcastError(proposalId, `Failed to launch claude: ${err.message}`);
259
+ onError();
260
+ resolve();
261
+ });
262
+ /* c8 ignore stop */
263
+ child.on('close', (code) => {
264
+ const fullText = this._buffers.get(proposalId) ?? '';
265
+ this._activeProcesses.delete(proposalId);
266
+ this._buffers.delete(proposalId);
267
+ if (this._disposed) {
268
+ resolve();
269
+ return;
270
+ } // M12: project removed mid-flight; DB closing
271
+ if (code === 0) {
272
+ onSuccess(fullText, capturedSessionId);
273
+ }
274
+ else {
275
+ onError();
276
+ }
277
+ resolve();
278
+ });
279
+ });
280
+ }
281
+ _broadcastError(proposalId, error) {
282
+ this._broadcast({
283
+ type: 'proposal_error',
284
+ projectId: '',
285
+ proposalId,
286
+ error,
287
+ timestamp: new Date().toISOString(),
288
+ });
289
+ }
290
+ }
291
+ exports.ProposalManager = ProposalManager;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ // Per-invocation provider selection for multi-provider projects.
3
+ //
4
+ // A project carries a primary `provider` (single source for single-provider
5
+ // projects, and the fallback default) plus a `providers` list of every
6
+ // installed provider. Add Spec, rails and the terminal can request a specific
7
+ // engine per invocation; these helpers resolve and validate that request
8
+ // against what the project actually has installed.
9
+ //
10
+ // Invariant: when `providers.length === 1` every helper collapses to the single
11
+ // provider, so single-provider projects behave exactly as before.
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.isProviderEnabled = isProviderEnabled;
14
+ exports.isMultiProvider = isMultiProvider;
15
+ exports.resolveProvider = resolveProvider;
16
+ exports.validateRequestedProvider = validateRequestedProvider;
17
+ /**
18
+ * Normalised installed-provider list. `getProject` always populates
19
+ * `providers`, but this tolerates a row where it is missing/empty (legacy or
20
+ * hand-built rows) by falling back to the primary provider.
21
+ */
22
+ function installedProviders(project) {
23
+ if (Array.isArray(project.providers) && project.providers.length > 0)
24
+ return project.providers;
25
+ return [project.provider ?? 'claude'];
26
+ }
27
+ /** True when `id` is one of the providers installed on the project. */
28
+ function isProviderEnabled(project, id) {
29
+ if (!id)
30
+ return false;
31
+ return installedProviders(project).includes(id);
32
+ }
33
+ /** True when the project offers a choice of engines (more than one installed). */
34
+ function isMultiProvider(project) {
35
+ return installedProviders(project).length > 1;
36
+ }
37
+ /**
38
+ * Resolve the effective provider for a per-invocation request.
39
+ * Returns the requested provider when it is installed on the project; otherwise
40
+ * falls back to the project's primary provider. Never throws — callers that
41
+ * want strict validation should use `validateRequestedProvider` first.
42
+ */
43
+ function resolveProvider(project, requested) {
44
+ if (isProviderEnabled(project, requested))
45
+ return requested;
46
+ return project.provider ?? installedProviders(project)[0];
47
+ }
48
+ /**
49
+ * Strict validation for route handlers. Returns the resolved provider when the
50
+ * request is acceptable, or an `error` string when an explicit, non-empty
51
+ * provider was requested that the project does not have installed. Omitting the
52
+ * provider (undefined/null/empty) is always acceptable and resolves to primary.
53
+ */
54
+ function validateRequestedProvider(project, requested) {
55
+ const installed = installedProviders(project);
56
+ if (requested === undefined || requested === null || requested === '') {
57
+ return { ok: true, provider: project.provider ?? installed[0] };
58
+ }
59
+ if (typeof requested !== 'string') {
60
+ return { ok: false, error: 'provider must be a string' };
61
+ }
62
+ if (!isProviderEnabled(project, requested)) {
63
+ return {
64
+ ok: false,
65
+ error: `provider '${requested}' is not installed for this project (installed: ${installed.join(', ')})`,
66
+ };
67
+ }
68
+ return { ok: true, provider: requested };
69
+ }
@@ -0,0 +1,281 @@
1
+ "use strict";
2
+ // Claude adapter. Ports the existing claude spawn / stream / result logic from
3
+ // chat-manager.ts, queue-manager.ts, agent-refine-manager.ts,
4
+ // project-router.ts (generate-spec), setup-manager.ts, and result-event.ts
5
+ // without behaviour change. Managers will migrate to consume this adapter in
6
+ // later tasks (see openspec/changes/add-multi-provider-support/tasks.md §2.x).
7
+ //
8
+ // Spec: openspec/specs/multi-provider-architecture/spec.md
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.claudeAdapter = void 0;
11
+ exports._normaliseClaudeModel = normaliseModel;
12
+ const child_process_1 = require("child_process");
13
+ const WHICH_CMD = process.platform === 'win32' ? 'where' : 'which';
14
+ const CLAUDE_MODELS = [
15
+ { value: 'sonnet', label: 'Claude Sonnet', default: true },
16
+ { value: 'opus', label: 'Claude Opus' },
17
+ { value: 'haiku', label: 'Claude Haiku' },
18
+ ];
19
+ /** Mirror of ChatManager.normalizeClaudeCodeModel — pinned model strings the
20
+ * CLI accepts collapse to the short alias. */
21
+ function normaliseModel(model) {
22
+ switch (model) {
23
+ case 'claude-sonnet-4-6':
24
+ case 'claude-sonnet-4-5':
25
+ case 'claude-sonnet-4-0':
26
+ case 'claude-sonnet-4-20250514':
27
+ return 'sonnet';
28
+ case 'claude-opus-4-8':
29
+ case 'claude-opus-4-5':
30
+ case 'claude-opus-4-1-20250805':
31
+ case 'claude-opus-4-20250514':
32
+ return 'opus';
33
+ case 'claude-haiku-4-5-20251001':
34
+ case 'claude-3-5-haiku-20241022':
35
+ case 'claude-3-5-haiku-latest':
36
+ return 'haiku';
37
+ default:
38
+ return model || 'sonnet';
39
+ }
40
+ }
41
+ /** Default arg block every claude spawn shares. */
42
+ const COMMON_FLAGS = [
43
+ '--dangerously-skip-permissions',
44
+ '--tools', 'default',
45
+ '--output-format', 'stream-json',
46
+ '--verbose',
47
+ // Isolate app-spawned claude from the *user's* global Claude config. Without
48
+ // this, the child loads ~/.claude (user CLAUDE.md memory, plugins like
49
+ // claude-mem, SessionStart hooks). That bled cross-project memory into
50
+ // Explore turns (e.g. an unrelated "fighting game" surfaced for a fresh
51
+ // project) and inflated spec-gen tool usage past --max-turns. `project,local`
52
+ // still loads the target repo's own .claude settings + CLAUDE.md, which is
53
+ // exactly the context an app run should see.
54
+ '--setting-sources', 'project,local',
55
+ ];
56
+ function buildClaudeArgs(action, opts) {
57
+ const args = [];
58
+ const model = normaliseModel(opts.model);
59
+ switch (action) {
60
+ case 'chat-turn': {
61
+ args.push('--model', model);
62
+ args.push(...COMMON_FLAGS);
63
+ if (opts.systemPrompt)
64
+ args.push('--system-prompt', opts.systemPrompt);
65
+ args.push('-p', opts.prompt);
66
+ if (opts.maxTurns != null)
67
+ args.push('--max-turns', String(opts.maxTurns));
68
+ if (opts.extraArgs)
69
+ args.push(...opts.extraArgs);
70
+ return args;
71
+ }
72
+ case 'chat-resume': {
73
+ if (!opts.sessionId) {
74
+ throw new Error('chat-resume requires sessionId');
75
+ }
76
+ args.push('--model', model);
77
+ args.push(...COMMON_FLAGS);
78
+ if (opts.systemPrompt)
79
+ args.push('--system-prompt', opts.systemPrompt);
80
+ args.push('--resume', opts.sessionId);
81
+ args.push('-p', opts.prompt);
82
+ if (opts.maxTurns != null)
83
+ args.push('--max-turns', String(opts.maxTurns));
84
+ if (opts.extraArgs)
85
+ args.push(...opts.extraArgs);
86
+ return args;
87
+ }
88
+ case 'rail-job': {
89
+ // QueueManager spawns with `--append-system-prompt` (not `--system-prompt`)
90
+ // because the slash command in the prompt brings its own system prompt;
91
+ // we ADD to it rather than overwrite.
92
+ args.push(...COMMON_FLAGS);
93
+ args.push('--model', model);
94
+ if (opts.systemPrompt)
95
+ args.push('--append-system-prompt', opts.systemPrompt);
96
+ args.push('-p', opts.prompt);
97
+ if (opts.extraArgs)
98
+ args.push(...opts.extraArgs);
99
+ return args;
100
+ }
101
+ case 'spec-gen': {
102
+ args.push(...COMMON_FLAGS);
103
+ args.push('--model', model);
104
+ if (opts.maxTurns != null)
105
+ args.push('--max-turns', String(opts.maxTurns));
106
+ // Caller passes --tools override via extraArgs when scoped; otherwise
107
+ // 'default' from COMMON_FLAGS applies.
108
+ if (opts.systemPrompt)
109
+ args.push('--system-prompt', opts.systemPrompt);
110
+ args.push('-p', opts.prompt);
111
+ if (opts.extraArgs)
112
+ args.push(...opts.extraArgs);
113
+ return args;
114
+ }
115
+ case 'agent-refine': {
116
+ args.push(...COMMON_FLAGS);
117
+ if (opts.sessionId)
118
+ args.push('--resume', opts.sessionId);
119
+ args.push('-p', opts.prompt);
120
+ if (opts.extraArgs)
121
+ args.push(...opts.extraArgs);
122
+ return args;
123
+ }
124
+ case 'setup-enrich': {
125
+ args.push('-p', opts.prompt);
126
+ args.push(...COMMON_FLAGS);
127
+ if (opts.extraArgs)
128
+ args.push(...opts.extraArgs);
129
+ return args;
130
+ }
131
+ case 'setup-enrich-resume': {
132
+ if (!opts.sessionId) {
133
+ throw new Error('setup-enrich-resume requires sessionId');
134
+ }
135
+ args.push('--resume', opts.sessionId);
136
+ args.push(...COMMON_FLAGS);
137
+ args.push('-p', opts.prompt);
138
+ if (opts.extraArgs)
139
+ args.push(...opts.extraArgs);
140
+ return args;
141
+ }
142
+ case 'auto-title': {
143
+ args.push(...COMMON_FLAGS);
144
+ args.push('-p', opts.prompt);
145
+ return args;
146
+ }
147
+ }
148
+ }
149
+ function parseClaudeStreamLine(line) {
150
+ if (line.length === 0)
151
+ return null;
152
+ let parsed;
153
+ try {
154
+ parsed = JSON.parse(line);
155
+ }
156
+ catch {
157
+ return null;
158
+ }
159
+ const type = parsed.type;
160
+ if (!type)
161
+ return { kind: 'other', type: '<missing>', raw: parsed };
162
+ if (type === 'system' || type === 'init') {
163
+ const sid = parsed.session_id ??
164
+ (parsed.session?.id ?? undefined);
165
+ if (sid)
166
+ return { kind: 'session-started', sessionId: sid };
167
+ return { kind: 'other', type, raw: parsed };
168
+ }
169
+ if (type === 'result') {
170
+ return { kind: 'result', payload: parsed };
171
+ }
172
+ if (type === 'assistant') {
173
+ const msg = parsed.message;
174
+ const blocks = msg?.content ?? [];
175
+ // Concatenate all text blocks; tool_use blocks are surfaced separately as a
176
+ // tool-use event. For simplicity we synthesise the first text block here
177
+ // and let callers consume tool_use from a fan-out (matching current
178
+ // chat-manager behaviour).
179
+ const text = blocks
180
+ .filter((b) => b.type === 'text')
181
+ .map((b) => b.text ?? '')
182
+ .join('');
183
+ if (text)
184
+ return { kind: 'text-delta', text };
185
+ // Surface a single tool-use (the historical pattern only emitted one per
186
+ // assistant frame anyway).
187
+ const tool = blocks.find((b) => b.type === 'tool_use');
188
+ if (tool?.name) {
189
+ const input = JSON.stringify(parsed.message?.content?.[0]?.input ?? {});
190
+ return { kind: 'tool-use', name: tool.name, inputPreview: input.slice(0, 200) };
191
+ }
192
+ return { kind: 'other', type, raw: parsed };
193
+ }
194
+ if (type === 'tool_use') {
195
+ const name = parsed.name ?? '<unnamed>';
196
+ const input = JSON.stringify(parsed.input ?? {});
197
+ return { kind: 'tool-use', name, inputPreview: input.slice(0, 200) };
198
+ }
199
+ return { kind: 'other', type, raw: parsed };
200
+ }
201
+ function extractClaudeResult(events) {
202
+ // Find the latest `result` event and the latest `session-started` event.
203
+ let resultPayload = null;
204
+ let sessionId;
205
+ for (const ev of events) {
206
+ if (ev.kind === 'result')
207
+ resultPayload = ev.payload;
208
+ else if (ev.kind === 'session-started')
209
+ sessionId = ev.sessionId;
210
+ }
211
+ if (!resultPayload)
212
+ return { session_id: sessionId };
213
+ const usage = resultPayload.usage;
214
+ // result event may also carry session_id directly — prefer that over the
215
+ // earlier captured one (it's authoritative for the final state).
216
+ const finalSessionId = resultPayload.session_id ?? sessionId;
217
+ return {
218
+ tokens_in: usage?.input_tokens,
219
+ tokens_out: usage?.output_tokens,
220
+ tokens_cache_read: usage?.cache_read_input_tokens,
221
+ tokens_cache_create: usage?.cache_creation_input_tokens,
222
+ total_cost_usd: resultPayload.total_cost_usd,
223
+ num_turns: resultPayload.num_turns,
224
+ model: resultPayload.model,
225
+ duration_ms: resultPayload.duration_ms,
226
+ duration_api_ms: resultPayload.api_duration_ms,
227
+ session_id: finalSessionId,
228
+ };
229
+ }
230
+ async function detectClaudeInstalled() {
231
+ let installed = false;
232
+ try {
233
+ (0, child_process_1.execSync)(`${WHICH_CMD} claude`, { stdio: 'ignore' });
234
+ installed = true;
235
+ }
236
+ catch {
237
+ return { installed: false, executable: false };
238
+ }
239
+ // Probe version for executability + reporting.
240
+ try {
241
+ const raw = (0, child_process_1.execSync)('claude --version', {
242
+ encoding: 'utf-8',
243
+ stdio: ['pipe', 'pipe', 'ignore'],
244
+ timeout: 3000,
245
+ }).trim();
246
+ const match = raw.match(/\d+\.\d+\.\d+[\w.-]*/);
247
+ return {
248
+ installed,
249
+ executable: true,
250
+ version: match ? match[0] : raw,
251
+ meetsMinimum: true, // claude has no pinned minimum in this adapter
252
+ };
253
+ }
254
+ catch {
255
+ return { installed, executable: false };
256
+ }
257
+ }
258
+ exports.claudeAdapter = {
259
+ id: 'claude',
260
+ displayName: 'Claude Code',
261
+ binary: 'claude',
262
+ minCliVersion: null,
263
+ projectDirName: '.claude',
264
+ instructionsFilename: 'CLAUDE.md',
265
+ mcpRegistration: 'project-json',
266
+ capabilities: {
267
+ nativeResume: true,
268
+ nativeStreamJson: true,
269
+ nativeCostUsd: true,
270
+ nativeOtelEnv: true,
271
+ profileEnvSupport: true,
272
+ systemPromptArg: true,
273
+ },
274
+ modelCatalog: () => CLAUDE_MODELS,
275
+ defaultModel: () => 'sonnet',
276
+ buildArgs: buildClaudeArgs,
277
+ parseStreamLine: parseClaudeStreamLine,
278
+ extractResult: extractClaudeResult,
279
+ baselineAgents: () => ['sr-architect', 'sr-developer', 'sr-reviewer'],
280
+ detectInstalled: detectClaudeInstalled,
281
+ };