specrails-desktop 2.46.0 → 2.48.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 (259) hide show
  1. package/README.md +2 -0
  2. package/client/dist/assets/{ActivityFeedPage-CsHQPpvl.js → ActivityFeedPage-CGq6QhP5.js} +1 -1
  3. package/client/dist/assets/AgentBrowserCapture-C4GZ-kdf.js +1 -0
  4. package/client/dist/assets/AgentModeAnalyticsPane-_IPmL0ZS.js +2 -0
  5. package/client/dist/assets/AgentModeCodePane-B5WG5DOP.js +2 -0
  6. package/client/dist/assets/{AgentModeJobsPane-rnD-EPMd.js → AgentModeJobsPane-w1N_HIXh.js} +1 -1
  7. package/client/dist/assets/AgentsPage-CmwnnT46.js +87 -0
  8. package/client/dist/assets/AnalyticsPage-BUMsKtsJ.js +1 -0
  9. package/client/dist/assets/CodePage-PjgywJPS.js +3 -0
  10. package/client/dist/assets/DesktopAnalyticsPage-BXY1pH4y.js +1 -0
  11. package/client/dist/assets/DocsDialog-ccQETHKB.js +11 -0
  12. package/client/dist/assets/DocsPage-DzEgplB3.js +11 -0
  13. package/client/dist/assets/{ExportDropdown-pWZGYCv3.js → ExportDropdown-B8bBGopr.js} +1 -1
  14. package/client/dist/assets/InteractiveJobComposer-CEwGkJ8F.js +19 -0
  15. package/client/dist/assets/JobDetailModal-BYXmuTDe.js +1 -0
  16. package/client/dist/assets/JobDetailPage-CWp6MwJj.js +1 -0
  17. package/client/dist/assets/JobsPage-D1O1uyG8.js +1 -0
  18. package/client/dist/assets/{LoopBuilderPage-CtmOE4-b.js → LoopBuilderPage-DQE-7Vby.js} +2 -2
  19. package/client/dist/assets/{LoopPreviewModal-BYeLjQbr.js → LoopPreviewModal-Bk7zIXD5.js} +1 -1
  20. package/client/dist/assets/LoopsPage-CqG7mx56.js +1 -0
  21. package/client/dist/assets/MinimizedChatsContext-UpnqccPx.js +1 -0
  22. package/client/dist/assets/PluginsPage-CjgVvmpW.js +2 -0
  23. package/client/dist/assets/{ProjectSettingsDialog-DsCRIc4v.js → ProjectSettingsDialog-D6vBCoay.js} +1 -1
  24. package/client/dist/assets/{RepositoryDeliveries-BQm_3TO8.js → RepositoryDeliveries-C36ipKp_.js} +1 -1
  25. package/client/dist/assets/{RepositoryScopeSelector-DnAFtjTz.js → RepositoryScopeSelector-0Gz_fR1E.js} +1 -1
  26. package/client/dist/assets/ReviewPacketPage-Dr9RYs7q.js +1 -0
  27. package/client/dist/assets/TemplatePreviewModal-sCMHYFJo.js +1 -0
  28. package/client/dist/assets/TicketDetailModalContext-C5GgJlEt.js +14 -0
  29. package/client/dist/assets/{Trans-BwLgX6n7.js → Trans-9pHTy2fH.js} +1 -1
  30. package/client/dist/assets/{addspec-D2YIQ0GU.js → addspec-BOvgmcgk.js} +1 -1
  31. package/client/dist/assets/{addspec-B_TPJt-R.js → addspec-Clmyfn_R.js} +1 -1
  32. package/client/dist/assets/{addspec-A1lDQa4M.js → addspec-CsNaBpHp.js} +1 -1
  33. package/client/dist/assets/{addspec-CQBjzt24.js → addspec-D2tvWmmV.js} +1 -1
  34. package/client/dist/assets/{addspec-CLYLvaVP.js → addspec-D3nFwvD0.js} +1 -1
  35. package/client/dist/assets/{addspec-BPpZ_olp.js → addspec-DVLEhK3w.js} +1 -1
  36. package/client/dist/assets/{addspec-iFdQ6D99.js → addspec-DXbK-tb0.js} +1 -1
  37. package/client/dist/assets/{addspec-BHZd0N5F.js → addspec-OHG8DFEn.js} +1 -1
  38. package/client/dist/assets/agentRuntime-BUimiX__.js +1 -0
  39. package/client/dist/assets/agentRuntime-BcN97sAB.js +1 -0
  40. package/client/dist/assets/agentRuntime-Ckyg-ahT.js +1 -0
  41. package/client/dist/assets/agentRuntime-DJCwyX4t.js +1 -0
  42. package/client/dist/assets/agentRuntime-DVzPJOl0.js +1 -0
  43. package/client/dist/assets/agentRuntime-V9AZTG3c.js +1 -0
  44. package/client/dist/assets/agentRuntime-bAAjw1vw.js +1 -0
  45. package/client/dist/assets/agentRuntime-v4qKAYH-.js +1 -0
  46. package/client/dist/assets/{agents-45GbINfh.js → agents-CA5eT1d0.js} +1 -1
  47. package/client/dist/assets/{agents-DMKFStHL.js → agents-CAgy-5uS.js} +1 -1
  48. package/client/dist/assets/{agents-IUOgqT5t.js → agents-CNm6Qzlv.js} +1 -1
  49. package/client/dist/assets/{agents-ms7TwG16.js → agents-CTwbx-fb.js} +1 -1
  50. package/client/dist/assets/{agents-DaYcxAr1.js → agents-DEGV1Vao.js} +1 -1
  51. package/client/dist/assets/{agents-BHp0_FQt.js → agents-HsDF1aQU.js} +1 -1
  52. package/client/dist/assets/{agents-Bvyi3y6R.js → agents-IQjdA-z9.js} +1 -1
  53. package/client/dist/assets/{agents-rzPnqoBR.js → agents-RkGoteXh.js} +1 -1
  54. package/client/dist/assets/analytics-BNgZ1Nj7.js +1 -0
  55. package/client/dist/assets/analytics-BlypLLR6.js +1 -0
  56. package/client/dist/assets/analytics-CoEzWPx4.js +1 -0
  57. package/client/dist/assets/analytics-DFh5lSOl.js +1 -0
  58. package/client/dist/assets/analytics-DZp-DS2U.js +1 -0
  59. package/client/dist/assets/analytics-DjLlE7jS.js +1 -0
  60. package/client/dist/assets/analytics-jzCkOec3.js +1 -0
  61. package/client/dist/assets/analytics-nZIjjtCc.js +1 -0
  62. package/client/dist/assets/{dashboard-BK_mez-z.js → dashboard-C29Qwa-L.js} +1 -1
  63. package/client/dist/assets/{dashboard-BwkjxI6H.js → dashboard-CSJzf5OT.js} +1 -1
  64. package/client/dist/assets/{dashboard-C3bDKf7s.js → dashboard-CTfEtkqX.js} +1 -1
  65. package/client/dist/assets/{dashboard-Bt0cCzeG.js → dashboard-Cr4D8oMn.js} +1 -1
  66. package/client/dist/assets/{dashboard-fRrP0Kv0.js → dashboard-Csf1yGSN.js} +1 -1
  67. package/client/dist/assets/{dashboard-CdvjGfog.js → dashboard-D40HP2ks.js} +1 -1
  68. package/client/dist/assets/dashboard-DBAP2_SQ.js +1 -0
  69. package/client/dist/assets/{dashboard-B14uYXkG.js → dashboard-DMklepmz.js} +1 -1
  70. package/client/dist/assets/file-text-CFT-xXKN.js +1 -0
  71. package/client/dist/assets/{formatDistanceToNow-CeZv93iR.js → formatDistanceToNow-w_2U5pm0.js} +1 -1
  72. package/client/dist/assets/{getTimezoneOffsetInMilliseconds-DxAkjvJb.js → getTimezoneOffsetInMilliseconds-BRymg1Kk.js} +1 -1
  73. package/client/dist/assets/index-D0ScFZvR.css +2 -0
  74. package/client/dist/assets/index-DORCrgbI.js +77 -0
  75. package/client/dist/assets/jira-api-BqHbSdxK.js +1 -0
  76. package/client/dist/assets/jobs-C6qmvUAi.js +1 -0
  77. package/client/dist/assets/jobs-C9j2PuwW.js +1 -0
  78. package/client/dist/assets/jobs-DLHdDkHc.js +1 -0
  79. package/client/dist/assets/jobs-DSp9DoD_.js +1 -0
  80. package/client/dist/assets/jobs-DTQO08nJ.js +1 -0
  81. package/client/dist/assets/jobs-DoFaEl9g.js +1 -0
  82. package/client/dist/assets/jobs-Dpw6AEOP.js +1 -0
  83. package/client/dist/assets/jobs-DrF8Do8s.js +1 -0
  84. package/client/dist/assets/{narration-BSldQfjd.js → narration--hUhjM5v.js} +1 -1
  85. package/client/dist/assets/{narration-DKLjXIFI.js → narration-CHI06czm.js} +1 -1
  86. package/client/dist/assets/{narration-4OSg0b5-.js → narration-DjKB3pQZ.js} +1 -1
  87. package/client/dist/assets/{narration-BPMOQPFe.js → narration-DtCYvRLM.js} +1 -1
  88. package/client/dist/assets/{narration-D-e9ssxA.js → narration-DvLQBW9U.js} +1 -1
  89. package/client/dist/assets/{narration-DnrKC3mF.js → narration-eSx3gR0W.js} +1 -1
  90. package/client/dist/assets/{narration-Dypjxeel.js → narration-n3hOA7LY.js} +1 -1
  91. package/client/dist/assets/{narration-CvQdWdR5.js → narration-thJOeT2-.js} +1 -1
  92. package/client/dist/assets/packet-BNW8ODQw.js +1 -0
  93. package/client/dist/assets/packet-CXYvfdjy.js +1 -0
  94. package/client/dist/assets/packet-CtIlB8YE.js +1 -0
  95. package/client/dist/assets/packet-DA1SJkMH.js +1 -0
  96. package/client/dist/assets/packet-DYcWfBip.js +1 -0
  97. package/client/dist/assets/packet-DseX9yKC.js +1 -0
  98. package/client/dist/assets/packet-_m5aOy_d.js +1 -0
  99. package/client/dist/assets/packet-qOemUAm3.js +1 -0
  100. package/client/dist/assets/{project-repositories-BvBj9XH9.js → project-repositories-BsCs1PPA.js} +1 -1
  101. package/client/dist/assets/provider-capabilities-Vi1ZGvAK.js +1 -0
  102. package/client/dist/assets/settings-BsehKpty.js +1 -0
  103. package/client/dist/assets/settings-CQWob3SB.js +1 -0
  104. package/client/dist/assets/settings-CgCl0hzy.js +1 -0
  105. package/client/dist/assets/settings-DLRLd22L.js +1 -0
  106. package/client/dist/assets/settings-Dn5prAFl.js +1 -0
  107. package/client/dist/assets/settings-HZSu-K4l.js +1 -0
  108. package/client/dist/assets/{settings-DEgcA0jd.js → settings-p4OVIyRh.js} +1 -1
  109. package/client/dist/assets/settings-rddaldUp.js +1 -0
  110. package/client/dist/assets/setup-B5FHuxvB.js +1 -0
  111. package/client/dist/assets/setup-BihzXadx.js +1 -0
  112. package/client/dist/assets/setup-BtC6Hg4K.js +1 -0
  113. package/client/dist/assets/setup-C9Fy9PKQ.js +1 -0
  114. package/client/dist/assets/setup-CROyqD5N.js +1 -0
  115. package/client/dist/assets/setup-DpqzaEEA.js +1 -0
  116. package/client/dist/assets/setup-Dwzt5nO1.js +1 -0
  117. package/client/dist/assets/setup-zLEDnG7N.js +1 -0
  118. package/client/dist/assets/{spending-DNM6NAoA.js → spending-hcgxHP4O.js} +1 -1
  119. package/client/dist/assets/{useDesktop-mxHVQOdx.js → useDesktop-CAisjKWC.js} +1 -1
  120. package/client/dist/assets/{useSharedWebSocket-DnxHj8jP.js → useSharedWebSocket-BHIfW4QT.js} +2 -2
  121. package/client/dist/assets/wrench-BfmNO9Vw.js +1 -0
  122. package/client/dist/index.html +27 -26
  123. package/docs/guide/de/integrations/7-local-engines.md +37 -0
  124. package/docs/guide/en/integrations/7-local-engines.md +37 -0
  125. package/docs/guide/es/integrations/7-local-engines.md +37 -0
  126. package/docs/guide/fr/integrations/7-local-engines.md +37 -0
  127. package/docs/guide/it/integrations/7-local-engines.md +37 -0
  128. package/docs/guide/ja/integrations/7-local-engines.md +37 -0
  129. package/docs/guide/pt/integrations/7-local-engines.md +37 -0
  130. package/docs/guide/zh/integrations/7-local-engines.md +37 -0
  131. package/docs/internals/adding-a-provider.md +12 -0
  132. package/docs/internals/local-agent-runner.md +153 -0
  133. package/docs/internals/review-packet.md +8 -0
  134. package/docs/local-providers.md +215 -0
  135. package/docs/plans/implementation-efficiency-artifact.json +18 -0
  136. package/docs/plans/implementation-efficiency-evaluation.json +1817 -0
  137. package/docs/plans/implementation-efficiency-evaluation.md +41 -0
  138. package/docs/plans/implementation-efficiency-progress.md +48 -0
  139. package/docs/plans/implementation-efficiency-release.md +41 -0
  140. package/docs/plans/implementation-efficiency.md +124 -0
  141. package/local-runner/dist/specrails-local-runner.js +15815 -0
  142. package/package.json +7 -5
  143. package/server/dist/agent-chat-manager.js +8 -1
  144. package/server/dist/agent-chat-router.js +5 -2
  145. package/server/dist/agent-fence-promotion.js +53 -0
  146. package/server/dist/agent-mcp-config.js +4 -1
  147. package/server/dist/agent-runtime-bridge.js +35 -26
  148. package/server/dist/agent-runtime-controls-router.js +20 -1
  149. package/server/dist/agent-runtime-controls.js +94 -12
  150. package/server/dist/agent-runtime-effective-config.js +53 -0
  151. package/server/dist/agent-runtime-events.js +46 -0
  152. package/server/dist/agent-runtime-history.js +47 -0
  153. package/server/dist/agent-runtime-loader.js +84 -5
  154. package/server/dist/agent-runtime-metrics.js +77 -1
  155. package/server/dist/agent-runtime-package.js +205 -0
  156. package/server/dist/agent-runtime-settings-router.js +96 -5
  157. package/server/dist/agent-runtime-settings.js +163 -7
  158. package/server/dist/agent-spec-framing.js +10 -4
  159. package/server/dist/binary-probe.js +12 -0
  160. package/server/dist/blueprint-router.js +3 -2
  161. package/server/dist/chat-manager.js +5 -1
  162. package/server/dist/desktop-router.js +87 -4
  163. package/server/dist/index.js +13 -0
  164. package/server/dist/interactive-job-session.js +3 -1
  165. package/server/dist/local-engine-detection.js +118 -0
  166. package/server/dist/loop-executors.js +4 -3
  167. package/server/dist/loop-role-engines.js +129 -0
  168. package/server/dist/loop-run-manager.js +14 -6
  169. package/server/dist/mcp/tools/app-settings.js +30 -4
  170. package/server/dist/mcp/tools/rails.js +2 -1
  171. package/server/dist/pr-body.js +11 -2
  172. package/server/dist/pricing.js +15 -0
  173. package/server/dist/provider-detection.js +63 -1
  174. package/server/dist/provider-selection.js +26 -1
  175. package/server/dist/providers/index.js +4 -1
  176. package/server/dist/providers/local-adapter-registry.js +56 -0
  177. package/server/dist/providers/local-adapter.js +426 -0
  178. package/server/dist/providers/registry.js +39 -4
  179. package/server/dist/rail-isolated-launch.js +4 -3
  180. package/server/dist/rails-router.js +90 -8
  181. package/server/dist/result-event.js +17 -0
  182. package/server/dist/review-packet.js +1 -0
  183. package/server/dist/schemas/agent-runtime.schema.json +28 -3
  184. package/server/dist/schemas/fixtures/runtime-efficiency-summary.v1.json +790 -0
  185. package/server/dist/setup-manager.js +5 -1
  186. package/server/dist/spec-models.js +14 -2
  187. package/server/dist/worktree-node-modules.js +97 -65
  188. package/client/dist/assets/AgentBrowserCapture-BVcCK7x0.js +0 -1
  189. package/client/dist/assets/AgentModeAnalyticsPane-C5F3m29G.js +0 -2
  190. package/client/dist/assets/AgentModeCodePane-C5QuKsu0.js +0 -2
  191. package/client/dist/assets/AgentsPage-DiyJWZcU.js +0 -87
  192. package/client/dist/assets/AnalyticsPage-Dkmb0dnd.js +0 -1
  193. package/client/dist/assets/CodePage-C0dH99-t.js +0 -3
  194. package/client/dist/assets/DesktopAnalyticsPage-DuTjr2n8.js +0 -1
  195. package/client/dist/assets/DocsDialog-BVZJZHVR.js +0 -11
  196. package/client/dist/assets/DocsPage-D6KHTv8V.js +0 -11
  197. package/client/dist/assets/InteractiveJobComposer-Ck3PQxjN.js +0 -19
  198. package/client/dist/assets/JobDetailModal-DkoMH3ie.js +0 -1
  199. package/client/dist/assets/JobDetailPage-CBVivcl2.js +0 -1
  200. package/client/dist/assets/JobsPage-CzxEeca9.js +0 -1
  201. package/client/dist/assets/LoopsPage-6iW7g25k.js +0 -1
  202. package/client/dist/assets/MinimizedChatsContext-B6wVevPq.js +0 -1
  203. package/client/dist/assets/PluginsPage-Bf1z3WPF.js +0 -2
  204. package/client/dist/assets/ReviewPacketPage-CaXAwtR7.js +0 -1
  205. package/client/dist/assets/TemplatePreviewModal-9aRFpJ_J.js +0 -1
  206. package/client/dist/assets/TicketDetailModalContext-B1X5glzV.js +0 -14
  207. package/client/dist/assets/agentRuntime-BUagD2I_.js +0 -1
  208. package/client/dist/assets/agentRuntime-BkL70WtX.js +0 -1
  209. package/client/dist/assets/agentRuntime-CWXVqgqE.js +0 -1
  210. package/client/dist/assets/agentRuntime-CvNBdUAe.js +0 -1
  211. package/client/dist/assets/agentRuntime-D4RmeuNY.js +0 -1
  212. package/client/dist/assets/agentRuntime-DTidBWKg.js +0 -1
  213. package/client/dist/assets/agentRuntime-DhKYfyaU.js +0 -1
  214. package/client/dist/assets/agentRuntime-LL8_GLx9.js +0 -1
  215. package/client/dist/assets/analytics-47pYygtV.js +0 -1
  216. package/client/dist/assets/analytics-B0vt1g5U.js +0 -1
  217. package/client/dist/assets/analytics-BMzCvrCU.js +0 -1
  218. package/client/dist/assets/analytics-BlFN3Zwx.js +0 -1
  219. package/client/dist/assets/analytics-CZYzL-nR.js +0 -1
  220. package/client/dist/assets/analytics-DAsb9MJ8.js +0 -1
  221. package/client/dist/assets/analytics-FXQlQ2Yt.js +0 -1
  222. package/client/dist/assets/analytics-RnFCNkah.js +0 -1
  223. package/client/dist/assets/dashboard-BfBir_6o.js +0 -1
  224. package/client/dist/assets/file-text-BcLCfcWZ.js +0 -1
  225. package/client/dist/assets/index-Cfh9aaep.css +0 -2
  226. package/client/dist/assets/index-DYoyDWim.js +0 -76
  227. package/client/dist/assets/jira-api-ChjVGJx_.js +0 -1
  228. package/client/dist/assets/jobs-5PQJbdOf.js +0 -1
  229. package/client/dist/assets/jobs-B2B08Oy9.js +0 -1
  230. package/client/dist/assets/jobs-BJZtBbwb.js +0 -1
  231. package/client/dist/assets/jobs-BlWEsQb7.js +0 -1
  232. package/client/dist/assets/jobs-ConfD8xD.js +0 -1
  233. package/client/dist/assets/jobs-DMPU64ms.js +0 -1
  234. package/client/dist/assets/jobs-DojASiTp.js +0 -1
  235. package/client/dist/assets/jobs-kVHkNpB-.js +0 -1
  236. package/client/dist/assets/packet-BQ2tXfJI.js +0 -1
  237. package/client/dist/assets/packet-BdpOJ1Cy.js +0 -1
  238. package/client/dist/assets/packet-C3Ievb9R.js +0 -1
  239. package/client/dist/assets/packet-C4zJIG0Y.js +0 -1
  240. package/client/dist/assets/packet-Cx-zRuWn.js +0 -1
  241. package/client/dist/assets/packet-DUTGX52M.js +0 -1
  242. package/client/dist/assets/packet-DhsKtUPB.js +0 -1
  243. package/client/dist/assets/packet-z3LJ8Zyy.js +0 -1
  244. package/client/dist/assets/provider-capabilities-CXipwrXJ.js +0 -1
  245. package/client/dist/assets/settings-B3rWEwOx.js +0 -1
  246. package/client/dist/assets/settings-BcVoiMyw.js +0 -1
  247. package/client/dist/assets/settings-BlYvaQ7w.js +0 -1
  248. package/client/dist/assets/settings-CD5uEBiL.js +0 -1
  249. package/client/dist/assets/settings-CyhS0DLJ.js +0 -1
  250. package/client/dist/assets/settings-DCMFUGDs.js +0 -1
  251. package/client/dist/assets/settings-DmbYKyMJ.js +0 -1
  252. package/client/dist/assets/setup-2xGgu4Sk.js +0 -1
  253. package/client/dist/assets/setup-Ba11l2JA.js +0 -1
  254. package/client/dist/assets/setup-BzW4kMok.js +0 -1
  255. package/client/dist/assets/setup-COzwYhkJ.js +0 -1
  256. package/client/dist/assets/setup-CRVULhtF.js +0 -1
  257. package/client/dist/assets/setup-DgvlxwpE.js +0 -1
  258. package/client/dist/assets/setup-Dw_wYeEY.js +0 -1
  259. package/client/dist/assets/setup-ZPtEeJPW.js +0 -1
@@ -106,6 +106,14 @@ holds no optimistic state; a raced answer surfaces the neutral
106
106
  agent-chat PR card. Both keep their precise git actions.
107
107
  - Layout is an inverted pyramid: verdict + confidence + cost + verbs above the
108
108
  fold; the sections are progressive disclosure below.
109
+
110
+ The "What you asked" / "What was done" slots are spec markdown and render
111
+ through `PacketMarkdown` (react-markdown + GFM, raw HTML skipped, images
112
+ dropped, inline code as quiet chips). `solution` is the tight digest; when
113
+ the composer clamps it, `solutionOverflow` carries the full text and the
114
+ page shows it behind a "Read the full solution" disclosure. The server
115
+ digests each headed section as `**Label**` + a blank line + the content, so
116
+ a numbered journey survives as a list in the packet AND in the PR body.
109
117
  - "Discuss this delivery" deliberately routes into the existing agent chat
110
118
  rather than adding a second Q&A brain (see the change's design D5).
111
119
 
@@ -0,0 +1,215 @@
1
+ # Local AI engines (OpenAI-compatible endpoints)
2
+
3
+ Specrails Desktop can run on models you host yourself — Ollama, llama.cpp,
4
+ LM Studio, vLLM, LocalAI, or any server that speaks the OpenAI
5
+ `/v1/chat/completions` API. A configured endpoint is a **first-class AI
6
+ engine**: it appears in every engine selector (rail header, Add Spec Quick /
7
+ Explore, sidebar chat, agent missions) exactly like Claude, Codex, Gemini or
8
+ Kimi, and rails run their Architect → Developer → Reviewer pipeline on it.
9
+
10
+ ## Add a connection
11
+
12
+ 1. Open **Settings ▸ Specrails Agents ▸ Provider connections**.
13
+ 2. **Add local engine**. Give it an id (`local`, `lan-box`, …), the base URL
14
+ (`http://127.0.0.1:11434/v1`, `http://192.168.1.20:8080/v1`), and — when the
15
+ server needs a key — the **name of the environment variable** that holds it
16
+ (for example `LOCAL_OLLAMA_API_KEY`). The key itself is never stored by
17
+ Specrails; it is read from the app process environment at spawn time.
18
+ 3. **Test connection**. Specrails calls `GET <baseUrl>/models`, shows the
19
+ reachability pill and lists the discovered models. Pick a default model.
20
+ 4. **Save**. The engine is registered immediately: open a rail header or Add
21
+ Spec and it is selectable without a restart.
22
+
23
+ Optional per connection:
24
+
25
+ - **Rates** (USD per 1M input / output tokens). Without rates, cost is reported
26
+ as *unknown* — never `$0`. With rates the cost badge shows an **estimate**.
27
+ - **Reasoning effort**: only switch it on when the server accepts the OpenAI
28
+ `reasoning_effort` request field (Ollama with reasoning models, vLLM, LM
29
+ Studio). When on, every call carries the role's configured effort, and the
30
+ Compact architect raises it to `high` while writing the plan — models that
31
+ "think privately and answer tersely" plan far better that way. Off ⇒ the
32
+ field is never sent.
33
+
34
+ ### The API key comes from the environment
35
+
36
+ `apiKeyEnv` names a variable that must exist in the process that runs the
37
+ Desktop server. When you launch the app from Finder/Dock or the Windows Start
38
+ menu, shell-only exports (`~/.zshrc`) are **not** inherited. The connection card
39
+ warns with *"not set in the app process"* when that is the case. Fixes: set it
40
+ system-wide (`launchctl setenv`, Windows user environment variables), or
41
+ launch the app from a terminal that has it. Local servers that need no key work
42
+ without any of this.
43
+
44
+ ## What runs where
45
+
46
+ | Surface | How the local engine executes |
47
+ |---|---|
48
+ | Rails: implement / batch / custom loops | specrails-core's programmatic runtime, all three roles on the connection (`OpenAICompatibleExecutor`) |
49
+ | Rails: freestyle, verify / fix / decider steps, loop ai-steps | the bundled **local agent runner** |
50
+ | Add Spec Quick + Explore, sidebar chat | the local agent runner (read-only tool set for Explore) |
51
+ | Agent chat / missions | the local agent runner with the Specrails MCP bridge + your enabled external MCP servers |
52
+ | Project Builder (day-0 blueprint chat) | the local agent runner in pure-output mode (no tools); expect a capable model — the blueprint contract is strict |
53
+
54
+ ### Local-only machines
55
+
56
+ Nothing has to be selected by hand. Provider availability is a machine
57
+ property: every surface offers the engines the app can actually run, and the
58
+ default follows the same rule everywhere — a detected CLI in the fixed order
59
+ (Claude → Codex → Gemini → Kimi), else the first reachable local engine.
60
+
61
+ - Project surfaces (rails, Add Spec, sidebar chat) already derive the
62
+ project's primary from the detected set, so with one local engine the
63
+ selectors stay hidden and everything runs on it.
64
+ - **Agent missions and the Project Builder** start a fresh conversation on that
65
+ same machine default (server `defaultMachineProvider`, client
66
+ `preferredProvider`), so a local-only machine composes on its local engine
67
+ instead of an uninstalled Claude. Existing conversations keep the provider
68
+ they were created on — the selector still lets you switch.
69
+ - A local engine counts as *available* only while its endpoint answers the
70
+ bounded `GET /models` probe. `/api/available-providers` (the gate the Agent
71
+ composer and the Builder read) reports local ids from that probe, never from
72
+ the PATH lookup of the bundled node that runs them — an endpoint that is
73
+ down leaves the engine out of the list instead of failing the first turn.
74
+ - Selectors show the connection's **label** (or its id when unlabeled).
75
+
76
+ The runner is a small process shipped inside the app (`specrails-local-runner`)
77
+ that performs the streaming tool loop (Read / Grep / Glob / Bash / Write / Edit),
78
+ keeps resumable sessions under `~/.specrails/local-runner/sessions/`, and
79
+ speaks the same event stream the Claude CLI does, so every Desktop surface
80
+ treats it like one more CLI. Details: `docs/internals/local-agent-runner.md`.
81
+
82
+ ## Quick setup for small models
83
+
84
+ Each local connection card has a **Recommended for small models** button. One
85
+ click sets the Compact agent loop, forwards the reasoning effort and a 32k
86
+ context window (a larger configured window is kept) — the combination
87
+ validated with 7–14B models. Every field stays editable afterwards. When the
88
+ effort switch is off, the card notes that the rail header hides the effort
89
+ selector for that engine.
90
+
91
+ ## Agent loop: Compact vs Free
92
+
93
+ Each local connection has an **Agent loop** setting that decides how the
94
+ implement pipeline drives the model:
95
+
96
+ - **Compact** (default). The host drives the Architect as a short sequence of
97
+ structured calls — inventory → proposal → design → specs → tasks — each with
98
+ a tiny tool set (or none) and a JSON schema answer; the host renders the
99
+ OpenSpec artifacts from that JSON. The Developer runs one bounded mini-loop
100
+ per task with a tool-call budget; the Reviewer answers the review schema
101
+ directly. Old tool results are compacted before the context window fills.
102
+ Fewer, shorter model calls; works with 7–14B models.
103
+ - **Free.** One agentic loop per role, exactly like a CLI provider. Needs a
104
+ ~30B+ model with reliable tool calling. Guardrails (repetition detection,
105
+ argument repair, empty-reply nudge, context compaction) apply here too.
106
+
107
+ Planning steps (proposal, design, specs, tasks, review) are sent with generic
108
+ OpenAI generation controls — `temperature 0.2` and a wide `max_tokens` — so any
109
+ small model answers literally and is never truncated; developer tool turns keep
110
+ the server defaults. Specrails also checks the plan itself: every requirement of
111
+ the spec must be covered by a task, tasks must be sentences of work (not file
112
+ names) in at least two groups, and nothing may target the frozen `openspec/`
113
+ folder; a plan that fails is sent back once with the exact reason. None of this
114
+ names a model: it is the host validating results, so it holds for any server.
115
+
116
+ Set **Context window (tokens)** to the server's real context size
117
+ (`n_ctx` / `num_ctx`, default 32768) so compaction triggers before the server
118
+ rejects the request. Both fields are sent to specrails-core only when the paired
119
+ core supports them (`capabilities.compactAgentLoop`); older cores never see them.
120
+
121
+ ## Hybrid setups: one engine per role
122
+
123
+ You do not have to run everything on one model. Each role can have its own engine — cloud or local, mixed freely — and the rail launches with the **Roles** engine to use them:
124
+
125
+ | Role | Where it runs | Configure in |
126
+ |---|---|---|
127
+ | Architect | Core runtime | Settings ▸ Specrails Agents ▸ runtime (per-role provider + model + effort) |
128
+ | Developer | Core runtime | same |
129
+ | Reviewer | Core runtime | same |
130
+ | Fixer (correction rounds after a failed verification or a rejected review) | Core runtime | same — **Inherit developer** by default, or its own engine |
131
+ | Verifier (verify / fix and any custom loop ai-step) | the loop | Settings ▸ Specrails Agents ▸ **Loop roles** |
132
+ | Decider (the Loop Decider) | the loop | same |
133
+
134
+ A sensible split for a local setup: **architect on a cloud model** (judgement and planning), **developer on the local coder** (volume), **fixer on a stronger model** (repairs are few and precise — this is where a cloud model pays off most), **reviewer on a cloud model**, **verifier local**, **decider on the cheapest fast model you have**.
135
+
136
+ The correction loop is verification ⇄ fixer: the host runs your test command, a failure goes to the fixer with the exact output and the offending lines already read, and only a green verification reaches the reviewer. A rejected review also goes to the fixer.
137
+
138
+ How it works:
139
+
140
+ - In the rail header pick **Roles** as the engine. The rail hides its model/effort/profile selectors (they belong to each role now) and shows a *Roles* chip.
141
+ - The launch carries no provider override, so Core keeps the per-role runtime settings. The loop's own steps use the verifier role; the Loop Decider uses the decider role.
142
+ - A loop role that is not set inherits the project's primary engine. A role whose provider is not detected any more falls back to the primary engine instead of blocking the launch; a stale model falls back to the provider's default; an effort the engine cannot honour is dropped.
143
+ - Freestyle has no roles — it is one autonomous agent — so a Roles rail cannot launch in freestyle mode (`400 roles_engine_unsupported_mode`).
144
+ - REST: `GET/PUT /api/projects/<id>/agent-runtime/loop-roles` with `{ roles: { verifier?: { provider, model?, effort? }, decider?: {…} } }`. Stored in `<workspace>/.specrails/loop-role-engines.json`. MCP: `specrails_rails(set_engine, aiEngine: "roles")` / `launch(aiEngine: "roles")`.
145
+
146
+ ## Guardrails (tuning the process)
147
+
148
+ The compact loop wraps a local model in process rules so a small model does not derail: a validated plan, frozen planning artifacts, one test file per module, evidence before a task is ticked, a host that repairs the environment, a silence timeout that stops hanging tests, a per-group check (the repository's test command runs after every task group and a failure is fixed in place before moving on — a lightweight TDD loop), and more. They are all **on by default** and listed in **Project settings ▸ Agent engine ▸ Guardrails**, grouped by phase (architect · developer · host), each with what it does and why it exists. Switch one off only to tune the process for an experiment; the setting is per project and persists as `guardrails: { "<id>": false }` in the project's `agent-runtime.json`. CLI providers are never affected. Pure correctness fixes are not listed — they cannot be switched off.
149
+
150
+ ## Which models work
151
+
152
+ The wiring is model-agnostic; quality is not. The pipeline relies on **reliable
153
+ tool calling** and long-context instruction following:
154
+
155
+ - Recommended: tool-calling-tuned coder models ≥ 30B (Qwen3-Coder, Devstral,
156
+ GLM-4.x-class, DeepSeek-Coder-V2/V3 quantised) on a server that advertises
157
+ `tools` support.
158
+ - Usable for chat / Explore / Quick spec: 7–14B instruct models.
159
+ - Not recommended for rails: models without native tool calling (they emit
160
+ malformed calls the runner has to bounce back).
161
+
162
+ Start with **Freestyle** or an Explore session before trusting a full implement
163
+ rail to a new model.
164
+
165
+ ## Capability matrix
166
+
167
+ | Capability | Local engine |
168
+ |---|---|
169
+ | Rails, freestyle, loops, chat, Explore, Quick spec, missions | ✅ |
170
+ | Persistent multi-turn (interactive jobs, Explore fast path) | ✅ |
171
+ | Resume by session id | ✅ |
172
+ | Read-only / no-tools boundaries (Explore, deciders) | ✅ native runner policies |
173
+ | MCP servers in missions | ✅ (`--mcp-config`, tools as `mcp__<server>__<tool>`) |
174
+ | Agent profiles / custom roles / Agent Studio AI | ❌ |
175
+ | SMASH, Contract Layer, Project Builder generation | ❌ (need structured-action guarantees) |
176
+ | Native cost | ❌ — unknown unless you set rates |
177
+ | OTEL pipeline telemetry | ❌ |
178
+ | Images / attachments | ❌ |
179
+
180
+ ## Analytics
181
+
182
+ Every invocation records `provider = <connection id>`, the raw model id, and
183
+ real token counts from the server's `usage` block. Cost is `NULL` (rendered as
184
+ *cost unknown (local engine)*) unless rates are configured, in which case it is
185
+ flagged **estimated**. The engine filter on the Analytics page lists local
186
+ engines once they have rows.
187
+
188
+ ## Kill switch
189
+
190
+ `SPECRAILS_LOCAL_ENGINES=false` (or `0`/`off`) disables the feature: no adapter
191
+ is registered, connections are not probed, engine selectors show CLIs only, and
192
+ the runner is never spawned. Connections stay editable and remain valid as
193
+ per-role providers of the programmatic runtime. `VITE_FEATURE_LOCAL_ENGINES=false`
194
+ hides the test / models UI of the connection card.
195
+
196
+ ## Troubleshooting
197
+
198
+ - **Engine missing from selectors** — the last probe failed. Test the
199
+ connection; probes run every 60 s and are bounded at 3 s.
200
+ - **`401` / "not authorized" pill** — the key env var is unset in the app
201
+ process or wrong. See *The API key comes from the environment*.
202
+ - **Rail fails with `Unknown command: /specrails:implement`** — the project
203
+ workspace has no command files for the runner to read; re-run Add Project
204
+ assembly (Settings ▸ Projects) so the framework surface is materialised.
205
+ - **Mission / chat turn fails with `exceeds the available context size`** — the
206
+ server's context window is too small for the agent surfaces. A mission turn
207
+ carries the operator prompt plus the Specrails MCP tool schemas (≈ 20–30k
208
+ tokens before the model says a word); Explore/Quick specs need less. Raise
209
+ the window on the server: Ollama `OLLAMA_CONTEXT_LENGTH=65536` (or `num_ctx`
210
+ in the Modelfile), llama.cpp `-c 65536`, LM Studio *Context Length*. 64k+
211
+ is the comfortable floor for missions; 32k works for chat and Explore.
212
+ - **Turn ends with a context-length error** — the runner evicts old tool
213
+ results and retries once; a second failure surfaces the server message. Use
214
+ a larger context window or a smaller spec.
215
+ - **Cost shows `—`** — expected without rates. Configure rates for an estimate.
@@ -0,0 +1,18 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "name": "specrails-core",
4
+ "version": "5.3.0",
5
+ "sha": "2427141bf61ea38785b3741cd1f66270743a476b",
6
+ "filename": "specrails-core-5.3.0.tgz",
7
+ "integrity": "sha512-pi0GRKWv7QbygU16i1AJVWme/IJ3vVrpSh80huGLE1yusHxGvLDN+ugy2REkdBlxreICbgXzR6lkaAEGQUMPWA==",
8
+ "developmentOnly": true,
9
+ "sourceCommitDescribes": "Uncommitted development tree based on this commit; use package integrity for artifact identity.",
10
+ "runtimeIdentity": {
11
+ "apiVersion": 1,
12
+ "packageVersion": "5.3.0",
13
+ "workflowVersion": "5",
14
+ "instructionsVersion": "7",
15
+ "packageIntegrity": "sha256:6a3005a4e0eb16a42da74b7fa39a5a7d694b1782ee73a2d64bc0872fb51bc340"
16
+ },
17
+ "artifactPath": "/tmp/specrails-core-efficiency-ready/specrails-core-5.3.0.tgz"
18
+ }