specrails-desktop 2.36.0 → 2.42.2

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 (510) hide show
  1. package/README.md +94 -247
  2. package/client/dist/assets/ActivityFeedPage-DoEMumQS.js +1 -0
  3. package/client/dist/assets/AgentBrowserCapture-DIh4K0gh.js +1 -0
  4. package/client/dist/assets/AgentModeAnalyticsPane-mbq4WEoO.js +2 -0
  5. package/client/dist/assets/AgentModeCodePane-CKh7zuA4.js +2 -0
  6. package/client/dist/assets/AgentModeJobsPane-BDokPiLJ.js +1 -0
  7. package/client/dist/assets/AgentsPage-BFVAZbBj.js +87 -0
  8. package/client/dist/assets/AnalyticsPage-3Y9LuWwz.js +1 -0
  9. package/client/dist/assets/CodePage-C9KyuV_C.js +3 -0
  10. package/client/dist/assets/DesktopAnalyticsPage-Bhi54bXQ.js +1 -0
  11. package/client/dist/assets/{DocsDialog-C76VdBJC.js → DocsDialog-Dj6mt4ga.js} +2 -2
  12. package/client/dist/assets/{DocsPage-ziMlj6B6.js → DocsPage-24yWglNI.js} +1 -1
  13. package/client/dist/assets/ExportDropdown-ophapHrT.js +1 -0
  14. package/client/dist/assets/InteractiveJobComposer-C1ucmxQh.js +19 -0
  15. package/client/dist/assets/JobDetailModal-DNWmgVHD.js +1 -0
  16. package/client/dist/assets/JobDetailPage-BcajZyuu.js +1 -0
  17. package/client/dist/assets/JobsPage-B9nTZw6e.js +1 -0
  18. package/client/dist/assets/LoopBuilderPage-Oc48iOFW.js +7 -0
  19. package/client/dist/assets/LoopPreviewModal-ae0Fr6SU.js +1 -0
  20. package/client/dist/assets/LoopsPage-CUEqzUBI.js +1 -0
  21. package/client/dist/assets/MinimizedChatsContext-Deg39peL.js +1 -0
  22. package/client/dist/assets/PluginsPage-C1xtARIx.js +2 -0
  23. package/client/dist/assets/ProjectSettingsDialog-JZzrXFBN.js +1 -0
  24. package/client/dist/assets/RepositoryDeliveries-CSDsiVUz.js +5 -0
  25. package/client/dist/assets/RepositoryScopeSelector-D-RCaknl.js +1 -0
  26. package/client/dist/assets/ReviewPacketPage-x5EfGTiL.js +1 -0
  27. package/client/dist/assets/TemplatePreviewModal-BSyuZxGq.js +1 -0
  28. package/client/dist/assets/TicketDetailModalContext-DqyF0so-.js +14 -0
  29. package/client/dist/assets/Trans-SnMX4MhW.js +1 -0
  30. package/client/dist/assets/agent-BdT0SB1D.js +1 -0
  31. package/client/dist/assets/agent-Bh9K7iEt.js +1 -0
  32. package/client/dist/assets/agent-C4ibdFk9.js +1 -0
  33. package/client/dist/assets/agent-CSFY22Zo.js +1 -0
  34. package/client/dist/assets/agent-DAnqxUn8.js +1 -0
  35. package/client/dist/assets/agent-DTQiu0Mi.js +1 -0
  36. package/client/dist/assets/agent-T54WuR_Y.js +1 -0
  37. package/client/dist/assets/agent-i75WDZOA.js +1 -0
  38. package/client/dist/assets/browser-05vRDg_y.js +1 -0
  39. package/client/dist/assets/browser-Bulb-cB1.js +1 -0
  40. package/client/dist/assets/browser-C7f-Jsg1.js +1 -0
  41. package/client/dist/assets/browser-CG0PE1j_.js +1 -0
  42. package/client/dist/assets/browser-CMzaqAjo.js +1 -0
  43. package/client/dist/assets/browser-DMajYdNX.js +1 -0
  44. package/client/dist/assets/browser-DxcOHrdP.js +1 -0
  45. package/client/dist/assets/browser-ObE7xVo3.js +1 -0
  46. package/client/dist/assets/builder-765NeYTp.js +1 -0
  47. package/client/dist/assets/builder-8MG3V6ea.js +1 -0
  48. package/client/dist/assets/builder-B-1UBs5K.js +1 -0
  49. package/client/dist/assets/builder-BTiGnPT0.js +1 -0
  50. package/client/dist/assets/builder-Cx9Rz-7u.js +1 -0
  51. package/client/dist/assets/builder-DKFMELBl.js +1 -0
  52. package/client/dist/assets/builder-OcmKrC0h.js +1 -0
  53. package/client/dist/assets/builder-P9qVBXFZ.js +1 -0
  54. package/client/dist/assets/{button-CJqFnUOL.js → button-DCBqEaZl.js} +1 -1
  55. package/client/dist/assets/{code-CkUuW4m9.js → code-B37GRg9C.js} +1 -1
  56. package/client/dist/assets/{code-B0O8-p8k.js → code-BBOEZbf9.js} +1 -1
  57. package/client/dist/assets/{code-B1VLZDhS.js → code-BRm-jcyx.js} +1 -1
  58. package/client/dist/assets/{code-Bpj4Ddml.js → code-CF7w62CR.js} +1 -1
  59. package/client/dist/assets/{code-BykBZ5-e.js → code-CLuvJt2r.js} +1 -1
  60. package/client/dist/assets/{code-B86IMAfz.js → code-D0RCm59f.js} +1 -1
  61. package/client/dist/assets/code-DaZ-ZwCT.js +1 -0
  62. package/client/dist/assets/{code-cAqaqMTx.js → code-iIHkGaCL.js} +1 -1
  63. package/client/dist/assets/commands-0XjAftla.js +1 -0
  64. package/client/dist/assets/commands-BAWSYHjQ.js +1 -0
  65. package/client/dist/assets/commands-BBwowgiE.js +1 -0
  66. package/client/dist/assets/commands-BacjIZLN.js +1 -0
  67. package/client/dist/assets/commands-Bs62IAZ3.js +1 -0
  68. package/client/dist/assets/commands-CLPdh-Hh.js +1 -0
  69. package/client/dist/assets/commands-DlbFzgrp.js +1 -0
  70. package/client/dist/assets/commands-LjPSsi5F.js +1 -0
  71. package/client/dist/assets/common-B5AZNYMH.js +1 -0
  72. package/client/dist/assets/common-BFZ0c_vN.js +1 -0
  73. package/client/dist/assets/common-BrlwEnL7.js +1 -0
  74. package/client/dist/assets/common-BttQx3z4.js +1 -0
  75. package/client/dist/assets/common-CM65k_-e.js +1 -0
  76. package/client/dist/assets/common-D4mvFFlu.js +1 -0
  77. package/client/dist/assets/common-TZ9Ny96S.js +1 -0
  78. package/client/dist/assets/common-nFpSF4GC.js +1 -0
  79. package/client/dist/assets/dashboard-B14uYXkG.js +1 -0
  80. package/client/dist/assets/dashboard-BK_mez-z.js +1 -0
  81. package/client/dist/assets/dashboard-BfBir_6o.js +1 -0
  82. package/client/dist/assets/dashboard-Bt0cCzeG.js +1 -0
  83. package/client/dist/assets/dashboard-BwkjxI6H.js +1 -0
  84. package/client/dist/assets/{dashboard-C8WOEiPu.js → dashboard-C3bDKf7s.js} +1 -1
  85. package/client/dist/assets/dashboard-CdvjGfog.js +1 -0
  86. package/client/dist/assets/dashboard-fRrP0Kv0.js +1 -0
  87. package/client/dist/assets/dialog-SRw01_QU.js +45 -0
  88. package/client/dist/assets/dist-js-CJ_2XX1Y.js +1 -0
  89. package/client/dist/assets/formatDistanceToNow-DSj5DprF.js +1 -0
  90. package/client/dist/assets/getTimezoneOffsetInMilliseconds-YhD8rIEs.js +1 -0
  91. package/client/dist/assets/index-DwAmL7m5.css +2 -0
  92. package/client/dist/assets/index-EzrkUb8B.js +76 -0
  93. package/client/dist/assets/{jira-api-B1-MUehg.js → jira-api-CSCqGr-Q.js} +1 -1
  94. package/client/dist/assets/{jobs-CN_zv4Gr.js → jobs-B8rrzfyZ.js} +1 -1
  95. package/client/dist/assets/{jobs-DUlWSYq2.js → jobs-BS6RTurf.js} +1 -1
  96. package/client/dist/assets/{jobs-Bpks6doU.js → jobs-BTT0Bsks.js} +1 -1
  97. package/client/dist/assets/{jobs-Bgq-PZkC.js → jobs-CezU69AE.js} +1 -1
  98. package/client/dist/assets/{jobs-SwYS2M-B.js → jobs-ClFJae0s.js} +1 -1
  99. package/client/dist/assets/{jobs-BAls3bWq.js → jobs-DJSFIFVy.js} +1 -1
  100. package/client/dist/assets/{jobs-DhxKgWFq.js → jobs-DhgGr8vm.js} +1 -1
  101. package/client/dist/assets/{jobs-B_TeSQxb.js → jobs-DzMjUcaN.js} +1 -1
  102. package/client/dist/assets/mcp-6rMoZfEO.js +1 -0
  103. package/client/dist/assets/mcp-BD8sL5mP.js +1 -0
  104. package/client/dist/assets/mcp-BkcA3I5s.js +1 -0
  105. package/client/dist/assets/mcp-CCpSelOh.js +1 -0
  106. package/client/dist/assets/mcp-CUAN6ORK.js +1 -0
  107. package/client/dist/assets/mcp-CqbRxRTE.js +1 -0
  108. package/client/dist/assets/mcp-DP2YfVhO.js +1 -0
  109. package/client/dist/assets/mcp-DUVQamDz.js +1 -0
  110. package/client/dist/assets/narration-B-ynWTpn.js +1 -0
  111. package/client/dist/assets/narration-Bj_laZwg.js +1 -0
  112. package/client/dist/assets/narration-BxHpmMv_.js +1 -0
  113. package/client/dist/assets/narration-C1Px0-0j.js +1 -0
  114. package/client/dist/assets/narration-CAXhGbzM.js +1 -0
  115. package/client/dist/assets/narration-DQ1l_Kq6.js +1 -0
  116. package/client/dist/assets/narration-XISXwqZd.js +1 -0
  117. package/client/dist/assets/narration-kwzfglQo.js +1 -0
  118. package/client/dist/assets/nav-1-Hh2kOz.js +1 -0
  119. package/client/dist/assets/nav-B34QkESm.js +1 -0
  120. package/client/dist/assets/nav-Bap_UXAq.js +1 -0
  121. package/client/dist/assets/{nav-pYuXq7sf.js → nav-BwxXIB24.js} +1 -1
  122. package/client/dist/assets/nav-Ch-zHBG5.js +1 -0
  123. package/client/dist/assets/nav-CygC_WN-.js +1 -0
  124. package/client/dist/assets/{nav-iwjCg5FR.js → nav-KnnLQtOQ.js} +1 -1
  125. package/client/dist/assets/nav-m00uxYUG.js +1 -0
  126. package/client/dist/assets/packet-BQ2tXfJI.js +1 -0
  127. package/client/dist/assets/packet-BdpOJ1Cy.js +1 -0
  128. package/client/dist/assets/packet-C3Ievb9R.js +1 -0
  129. package/client/dist/assets/packet-C4zJIG0Y.js +1 -0
  130. package/client/dist/assets/packet-Cx-zRuWn.js +1 -0
  131. package/client/dist/assets/packet-DUTGX52M.js +1 -0
  132. package/client/dist/assets/packet-DhsKtUPB.js +1 -0
  133. package/client/dist/assets/packet-z3LJ8Zyy.js +1 -0
  134. package/client/dist/assets/project-repositories-DYhTvwQ1.js +1 -0
  135. package/client/dist/assets/provider-capabilities-B-wOHfLP.js +1 -0
  136. package/client/dist/assets/settings-BBt2xtDQ.js +1 -0
  137. package/client/dist/assets/settings-BJB9RKJj.js +1 -0
  138. package/client/dist/assets/settings-CHwQR2rB.js +1 -0
  139. package/client/dist/assets/settings-CrMi3kSi.js +1 -0
  140. package/client/dist/assets/settings-DKyhDGD1.js +1 -0
  141. package/client/dist/assets/settings-Deupji9c.js +1 -0
  142. package/client/dist/assets/settings-DqRMmwAM.js +1 -0
  143. package/client/dist/assets/settings-J4rj6vo-.js +1 -0
  144. package/client/dist/assets/setup-2xGgu4Sk.js +1 -0
  145. package/client/dist/assets/setup-Ba11l2JA.js +1 -0
  146. package/client/dist/assets/setup-BzW4kMok.js +1 -0
  147. package/client/dist/assets/setup-COzwYhkJ.js +1 -0
  148. package/client/dist/assets/setup-CRVULhtF.js +1 -0
  149. package/client/dist/assets/setup-DgvlxwpE.js +1 -0
  150. package/client/dist/assets/setup-Dw_wYeEY.js +1 -0
  151. package/client/dist/assets/setup-ZPtEeJPW.js +1 -0
  152. package/client/dist/assets/spending-BqbdPm_4.js +1 -0
  153. package/client/dist/assets/square-Ci-PFcFe.js +1 -0
  154. package/client/dist/assets/{terminal-BFRZnMPP.js → terminal-BAzpHtpY.js} +1 -1
  155. package/client/dist/assets/{terminal-IahE4LW9.js → terminal-C7dHeR3x.js} +1 -1
  156. package/client/dist/assets/{terminal-tITa81iz.js → terminal-CMla5Qsz.js} +1 -1
  157. package/client/dist/assets/{terminal-BZiIu3rf.js → terminal-CdNXH-n9.js} +1 -1
  158. package/client/dist/assets/{terminal-ScjyXNxQ.js → terminal-Cw5bZsmV.js} +1 -1
  159. package/client/dist/assets/{terminal-C2NAd7BW.js → terminal-DFUP4eNv.js} +1 -1
  160. package/client/dist/assets/{terminal-d7GadXbN.js → terminal-DGqljeK_.js} +1 -1
  161. package/client/dist/assets/{terminal-QpXZU2Bn.js → terminal-cU70NodO.js} +1 -1
  162. package/client/dist/assets/useDesktop-RSMTyy7V.js +1 -0
  163. package/client/dist/assets/useSharedWebSocket-BOdS5_Iz.js +2 -0
  164. package/client/dist/index.html +34 -35
  165. package/docs/README.md +3 -0
  166. package/docs/agent-live-steering.md +57 -0
  167. package/docs/ci-cd.md +57 -0
  168. package/docs/code-explorer.md +48 -0
  169. package/docs/codex.md +12 -1
  170. package/docs/features/detachable-mission-windows.md +59 -0
  171. package/docs/guide/de/integrations/5-mcp-server.md +13 -9
  172. package/docs/guide/de/integrations/6-agent-chat.md +1 -0
  173. package/docs/guide/en/integrations/5-mcp-server.md +13 -9
  174. package/docs/guide/en/integrations/6-agent-chat.md +1 -0
  175. package/docs/guide/es/integrations/5-mcp-server.md +13 -9
  176. package/docs/guide/es/integrations/6-agent-chat.md +1 -0
  177. package/docs/guide/fr/integrations/5-mcp-server.md +13 -9
  178. package/docs/guide/fr/integrations/6-agent-chat.md +1 -0
  179. package/docs/guide/it/integrations/5-mcp-server.md +13 -9
  180. package/docs/guide/it/integrations/6-agent-chat.md +1 -0
  181. package/docs/guide/ja/integrations/5-mcp-server.md +13 -9
  182. package/docs/guide/ja/integrations/6-agent-chat.md +1 -0
  183. package/docs/guide/pt/integrations/5-mcp-server.md +13 -9
  184. package/docs/guide/pt/integrations/6-agent-chat.md +1 -0
  185. package/docs/guide/zh/integrations/5-mcp-server.md +13 -9
  186. package/docs/guide/zh/integrations/6-agent-chat.md +1 -0
  187. package/docs/internals/README.md +1 -0
  188. package/docs/internals/browser-capture-performance.md +55 -3
  189. package/docs/internals/browser-login-popups.md +45 -0
  190. package/docs/internals/browser-native-retina-audit.md +39 -0
  191. package/docs/internals/ci-cd-audit.md +39 -0
  192. package/docs/internals/core-runtime-updates.md +68 -0
  193. package/docs/internals/embedded-browser-native-webview-evaluation.md +2 -0
  194. package/docs/internals/implementation-reliability-audit.md +93 -0
  195. package/docs/internals/interactive-jobs.md +110 -6
  196. package/docs/internals/mcp-mission-audit.md +76 -0
  197. package/docs/internals/project-builder.md +404 -42
  198. package/docs/internals/safe-pr-review-flow.md +52 -10
  199. package/docs/internals/startup-recovery-audit.md +58 -0
  200. package/docs/mcp.md +74 -41
  201. package/docs/mission-processes.md +59 -0
  202. package/docs/multi-repo-projects.md +51 -0
  203. package/docs/platforms/windows-parity.md +70 -0
  204. package/docs/platforms/windows.md +13 -11
  205. package/docs/running-pipelines.md +14 -0
  206. package/mcp-bridge/dist/specrails-mcp.js +7186 -0
  207. package/package.json +9 -4
  208. package/server/dist/agent-chat-manager.js +537 -68
  209. package/server/dist/agent-chat-router.js +87 -6
  210. package/server/dist/agent-context-resolver.js +129 -25
  211. package/server/dist/agent-defaults.js +19 -11
  212. package/server/dist/agent-input-store.js +206 -0
  213. package/server/dist/agent-mcp-config.js +54 -15
  214. package/server/dist/agent-operator-prompt.js +255 -65
  215. package/server/dist/agent-spec-framing.js +202 -0
  216. package/server/dist/agent-steering.js +218 -0
  217. package/server/dist/agent-store.js +153 -0
  218. package/server/dist/api-not-found.js +8 -0
  219. package/server/dist/background-process-control.js +164 -0
  220. package/server/dist/background-process-service.js +61 -0
  221. package/server/dist/background-process-store.js +242 -0
  222. package/server/dist/background-windows-bootstrap.js +238 -0
  223. package/server/dist/blueprint-chat-manager.js +476 -62
  224. package/server/dist/blueprint-commit.js +21 -1
  225. package/server/dist/blueprint-draft-parser.js +122 -17
  226. package/server/dist/blueprint-generation.js +238 -0
  227. package/server/dist/blueprint-operator-prompt.js +91 -63
  228. package/server/dist/blueprint-router.js +55 -3
  229. package/server/dist/blueprint-spec-fixtures.js +85 -0
  230. package/server/dist/blueprint-spec-quality.js +57 -16
  231. package/server/dist/blueprint-store.js +92 -1
  232. package/server/dist/browser-capture-manager.js +86 -30
  233. package/server/dist/browser-playwright.js +168 -45
  234. package/server/dist/browser-viewport.js +26 -0
  235. package/server/dist/chat-manager.js +23 -15
  236. package/server/dist/chromium-archive.cjs +83 -0
  237. package/server/dist/chromium-resolver.js +72 -64
  238. package/server/dist/code-activity.js +145 -0
  239. package/server/dist/code-explorer-router.js +714 -114
  240. package/server/dist/core-compat.js +28 -1
  241. package/server/dist/core-execution.js +111 -0
  242. package/server/dist/core-package.js +4 -16
  243. package/server/dist/core-runtime.js +202 -0
  244. package/server/dist/core-update-manager.js +161 -60
  245. package/server/dist/core-update-state.js +29 -0
  246. package/server/dist/db.js +66 -35
  247. package/server/dist/delivery-evidence.js +142 -39
  248. package/server/dist/desktop-db.js +239 -43
  249. package/server/dist/desktop-router.js +109 -9
  250. package/server/dist/dev-ports.js +8 -3
  251. package/server/dist/file-provenance.js +34 -22
  252. package/server/dist/file-story-manager.js +62 -64
  253. package/server/dist/file-story.js +118 -35
  254. package/server/dist/file-summary-generator.js +46 -5
  255. package/server/dist/file-summary-manager.js +355 -106
  256. package/server/dist/framework-manager.js +98 -110
  257. package/server/dist/framework-reseed.js +76 -10
  258. package/server/dist/git-diagnostics.js +2 -2
  259. package/server/dist/headroom-manager.js +38 -3
  260. package/server/dist/host-control.js +52 -0
  261. package/server/dist/index.js +43 -2
  262. package/server/dist/interactive-job-session.js +149 -16
  263. package/server/dist/internal-api.js +48 -0
  264. package/server/dist/jira/jira-materializer.js +1 -0
  265. package/server/dist/json-tolerant.js +174 -0
  266. package/server/dist/legacy-migration.js +4 -2
  267. package/server/dist/loop-command-catalog.js +83 -21
  268. package/server/dist/loop-constants.js +6 -1
  269. package/server/dist/loop-decider.js +11 -1
  270. package/server/dist/loop-executors.js +194 -45
  271. package/server/dist/loop-factory.js +11 -4
  272. package/server/dist/loop-graph.js +90 -4
  273. package/server/dist/loop-run-manager.js +301 -69
  274. package/server/dist/loop-shell-invocation.js +21 -0
  275. package/server/dist/loop-step-idle.js +55 -0
  276. package/server/dist/loop-templates.js +31 -7
  277. package/server/dist/mcp/agent-capability.js +37 -4
  278. package/server/dist/mcp/guide.js +149 -36
  279. package/server/dist/mcp/mcp-admin-router.js +20 -4
  280. package/server/dist/mcp/mcp-server.js +89 -43
  281. package/server/dist/mcp/mcp-tiers.js +6 -5
  282. package/server/dist/mcp/mcp-token.js +3 -1
  283. package/server/dist/mcp/resources.js +5 -4
  284. package/server/dist/mcp/tools/catalog.js +4 -0
  285. package/server/dist/mcp/tools/code.js +125 -14
  286. package/server/dist/mcp/tools/context.js +153 -0
  287. package/server/dist/mcp/tools/git.js +15 -5
  288. package/server/dist/mcp/tools/jobs.js +84 -71
  289. package/server/dist/mcp/tools/loops.js +17 -6
  290. package/server/dist/mcp/tools/meta.js +74 -27
  291. package/server/dist/mcp/tools/mission.js +29 -0
  292. package/server/dist/mcp/tools/projects.js +22 -6
  293. package/server/dist/mcp/tools/rails.js +48 -11
  294. package/server/dist/mcp/tools/specs.js +86 -14
  295. package/server/dist/mcp/tools/support.js +1 -1
  296. package/server/dist/mcp/tools/types.js +117 -43
  297. package/server/dist/mcp/tools/watch.js +144 -51
  298. package/server/dist/milestone-chain-store.js +164 -0
  299. package/server/dist/milestone-chain.js +487 -0
  300. package/server/dist/milestone-progress.js +348 -0
  301. package/server/dist/mobile/mobile-devices.js +10 -7
  302. package/server/dist/mobile/mobile-gateway.js +2 -0
  303. package/server/dist/mobile/mobile-missions.js +214 -0
  304. package/server/dist/mobile/mobile-redact.js +17 -3
  305. package/server/dist/mobile/mobile-router.js +46 -4
  306. package/server/dist/mobile/mobile-ws.js +49 -4
  307. package/server/dist/multi-repo-bases.js +56 -0
  308. package/server/dist/multi-repo-checkout.js +101 -0
  309. package/server/dist/multi-repo-delivery.js +100 -0
  310. package/server/dist/multi-repo-execution-store.js +65 -0
  311. package/server/dist/multi-repo-execution.js +453 -0
  312. package/server/dist/offline-assemble.js +10 -8
  313. package/server/dist/openspec-runtime-plugin-commands.json +18 -0
  314. package/server/dist/openspec-runtime-plugin.js +120 -0
  315. package/server/dist/plugins/codex-spawn.js +49 -0
  316. package/server/dist/plugins/serena/manifest.js +2 -2
  317. package/server/dist/plugins/serena/templates/instructions.md +16 -0
  318. package/server/dist/pr-publisher.js +1 -1
  319. package/server/dist/profiles-router.js +3 -18
  320. package/server/dist/project-code-discovery.js +142 -0
  321. package/server/dist/project-git.js +19 -21
  322. package/server/dist/project-registry.js +272 -20
  323. package/server/dist/project-repositories.js +157 -0
  324. package/server/dist/project-repository-provenance.js +31 -0
  325. package/server/dist/project-router-background-processes.js +105 -0
  326. package/server/dist/project-router-git.js +75 -16
  327. package/server/dist/project-router-jobs.js +2 -126
  328. package/server/dist/project-router-loop-runs.js +72 -2
  329. package/server/dist/project-router-tickets.js +53 -8
  330. package/server/dist/project-router.js +239 -38
  331. package/server/dist/provider-detection.js +18 -6
  332. package/server/dist/provider-limit.js +64 -0
  333. package/server/dist/providers/claude-adapter.js +26 -1
  334. package/server/dist/providers/claude-background-tasks.js +18 -0
  335. package/server/dist/providers/claude-live-session.js +383 -0
  336. package/server/dist/providers/codex-adapter.js +19 -0
  337. package/server/dist/providers/codex-live-session.js +545 -0
  338. package/server/dist/providers/gemini-adapter.js +1 -0
  339. package/server/dist/providers/live-session-types.js +12 -0
  340. package/server/dist/providers/live-session.js +13 -0
  341. package/server/dist/providers/terminal-result.js +24 -0
  342. package/server/dist/queue-manager.js +2 -0
  343. package/server/dist/rail-isolated-launch.js +141 -16
  344. package/server/dist/rail-pr-decision.js +364 -99
  345. package/server/dist/rail-pr-store.js +24 -10
  346. package/server/dist/rail-worktree-release.js +34 -2
  347. package/server/dist/rail-worktrees-store.js +4 -4
  348. package/server/dist/rails-router.js +249 -55
  349. package/server/dist/repo-lock.js +92 -17
  350. package/server/dist/review-packet.js +23 -13
  351. package/server/dist/schemas/file-summary.v1.json +59 -59
  352. package/server/dist/schemas/profile.v1.json +137 -137
  353. package/server/dist/setup-manager.js +52 -8
  354. package/server/dist/shell-integration/bash-shim.bash +45 -0
  355. package/server/dist/shell-integration/fish-shim.fish +36 -0
  356. package/server/dist/shell-integration/powershell-shim.ps1 +48 -0
  357. package/server/dist/shell-integration/zsh-shim.zsh +47 -0
  358. package/server/dist/smash-runner.js +1 -0
  359. package/server/dist/spawn-lifecycle.js +44 -27
  360. package/server/dist/spec-contract-prompt.js +143 -0
  361. package/server/dist/spec-draft-parser.js +6 -1
  362. package/server/dist/spec-models.js +1 -0
  363. package/server/dist/stuck-run-detector.js +1 -0
  364. package/server/dist/terminal-manager.js +21 -1
  365. package/server/dist/terminal-shell-integration.js +4 -1
  366. package/server/dist/transient-children.js +619 -230
  367. package/server/dist/util/cli-prompt.js +78 -5
  368. package/server/dist/util/sqlite-migrations.js +20 -0
  369. package/server/dist/util/win-spawn.js +18 -3
  370. package/server/dist/util/windows-provider-shell.js +29 -0
  371. package/server/dist/verification-sentinel.js +14 -0
  372. package/server/dist/vitest-setup.js +2 -0
  373. package/server/dist/windows-job-supervisor.js +133 -0
  374. package/server/dist/workspace-manager.js +9 -30
  375. package/server/dist/worktree-manager.js +17 -2
  376. package/server/dist/worktree-overlay.js +3 -1
  377. package/client/dist/assets/ActivityFeedPage-tAQcWs1R.js +0 -1
  378. package/client/dist/assets/AgentBrowserCapture-BX8BNae5.js +0 -1
  379. package/client/dist/assets/AgentModeAnalyticsPane-BVAqCL0K.js +0 -2
  380. package/client/dist/assets/AgentModeCodePane-9XfqQc9c.js +0 -2
  381. package/client/dist/assets/AgentModeJobsPane-BCjLsPhc.js +0 -1
  382. package/client/dist/assets/AgentsPage-C8J_42sm.js +0 -87
  383. package/client/dist/assets/AnalyticsPage-BtQuyfJm.js +0 -1
  384. package/client/dist/assets/CodePage-BZ2MwdCu.js +0 -2
  385. package/client/dist/assets/DesktopAnalyticsPage-Bh_29V4g.js +0 -1
  386. package/client/dist/assets/ExportDropdown-BrtfWzEG.js +0 -1
  387. package/client/dist/assets/InteractiveJobComposer-BCZiSfzc.js +0 -19
  388. package/client/dist/assets/JobDetailModal-NAJmuYIT.js +0 -1
  389. package/client/dist/assets/JobDetailPage-fE0ZycUX.js +0 -1
  390. package/client/dist/assets/JobsPage-z5M_HVJG.js +0 -1
  391. package/client/dist/assets/LoopBuilderPage-j1FQS47c.js +0 -7
  392. package/client/dist/assets/LoopPreviewModal-DhDJjdCe.js +0 -1
  393. package/client/dist/assets/LoopsPage-Ll7zORZb.js +0 -1
  394. package/client/dist/assets/MinimizedChatsContext-Bd3OqR_S.js +0 -1
  395. package/client/dist/assets/PluginsPage-DN4kGvJt.js +0 -2
  396. package/client/dist/assets/ProjectSettingsDialog-OgsgxjzF.js +0 -1
  397. package/client/dist/assets/ReviewPacketPage-DFog4sXn.js +0 -1
  398. package/client/dist/assets/TemplatePreviewModal-L2XxqiOD.js +0 -1
  399. package/client/dist/assets/TicketDetailModal-CsF-AWZX.js +0 -14
  400. package/client/dist/assets/Trans-Bsz9_gyq.js +0 -1
  401. package/client/dist/assets/agent-BQgKv_2F.js +0 -1
  402. package/client/dist/assets/agent-C1NRDJqL.js +0 -1
  403. package/client/dist/assets/agent-CLNleiy6.js +0 -1
  404. package/client/dist/assets/agent-CmceArkQ.js +0 -1
  405. package/client/dist/assets/agent-D3UxQ3SR.js +0 -1
  406. package/client/dist/assets/agent-DB1JeE64.js +0 -1
  407. package/client/dist/assets/agent-DXkHcQ-D.js +0 -1
  408. package/client/dist/assets/agent-DjJJJ2M8.js +0 -1
  409. package/client/dist/assets/auth-D_5bQv5W.js +0 -1
  410. package/client/dist/assets/ban-E4EaZe3a.js +0 -1
  411. package/client/dist/assets/bot-DzuuuC5R.js +0 -1
  412. package/client/dist/assets/browser-BgqHDMXP.js +0 -1
  413. package/client/dist/assets/browser-CsKJtrpv.js +0 -1
  414. package/client/dist/assets/browser-Cu58EpZU.js +0 -1
  415. package/client/dist/assets/browser-CvXOJm-j.js +0 -1
  416. package/client/dist/assets/browser-DOrFh1c7.js +0 -1
  417. package/client/dist/assets/browser-DQv_Jo7x.js +0 -1
  418. package/client/dist/assets/browser-LPgxvJu2.js +0 -1
  419. package/client/dist/assets/browser-eL-3MIEI.js +0 -1
  420. package/client/dist/assets/builder-0IWtosUm.js +0 -1
  421. package/client/dist/assets/builder-Bf2N6XWn.js +0 -1
  422. package/client/dist/assets/builder-BnqaaBkT.js +0 -1
  423. package/client/dist/assets/builder-BxxfGgAO.js +0 -1
  424. package/client/dist/assets/builder-C5IIgWsq.js +0 -1
  425. package/client/dist/assets/builder-CHuahItu.js +0 -1
  426. package/client/dist/assets/builder-CjWosXL_.js +0 -1
  427. package/client/dist/assets/builder-CpCIOoKj.js +0 -1
  428. package/client/dist/assets/code-CHPkOkDS.js +0 -1
  429. package/client/dist/assets/commands-6tYQih5m.js +0 -1
  430. package/client/dist/assets/commands-BK2QinXN.js +0 -1
  431. package/client/dist/assets/commands-C2Nca76h.js +0 -1
  432. package/client/dist/assets/commands-CKdLihNX.js +0 -1
  433. package/client/dist/assets/commands-CYIBTAlc.js +0 -1
  434. package/client/dist/assets/commands-CjUtYJIM.js +0 -1
  435. package/client/dist/assets/commands-Cq_u_8y9.js +0 -1
  436. package/client/dist/assets/commands-D_ZHYQug.js +0 -1
  437. package/client/dist/assets/common-6MLbD-jM.js +0 -1
  438. package/client/dist/assets/common-BKGEu4rm.js +0 -1
  439. package/client/dist/assets/common-BNbnv8cE.js +0 -1
  440. package/client/dist/assets/common-BqGWtDbt.js +0 -1
  441. package/client/dist/assets/common-DBtTzeYm.js +0 -1
  442. package/client/dist/assets/common-DEW3Nr8n.js +0 -1
  443. package/client/dist/assets/common-DHsv9N5d.js +0 -1
  444. package/client/dist/assets/common-mkrEcW-Y.js +0 -1
  445. package/client/dist/assets/dashboard-B9GhC5ku.js +0 -1
  446. package/client/dist/assets/dashboard-CBnv6zOI.js +0 -1
  447. package/client/dist/assets/dashboard-CaP0fU87.js +0 -1
  448. package/client/dist/assets/dashboard-D4ZZ4x84.js +0 -1
  449. package/client/dist/assets/dashboard-DmuTQBX8.js +0 -1
  450. package/client/dist/assets/dashboard-DynLYj3d.js +0 -1
  451. package/client/dist/assets/dashboard-zj4gGFJ1.js +0 -1
  452. package/client/dist/assets/dialog-CdWCb02j.js +0 -45
  453. package/client/dist/assets/dist-bVqfYmby.js +0 -1
  454. package/client/dist/assets/dist-js-CWeUdf5Z.js +0 -1
  455. package/client/dist/assets/formatDistanceToNow-DQCvMgUc.js +0 -1
  456. package/client/dist/assets/getTimezoneOffsetInMilliseconds-C16cxSe1.js +0 -1
  457. package/client/dist/assets/git-refresh-wTW0rO0Z.js +0 -1
  458. package/client/dist/assets/i18n-hnX2DPmo.js +0 -2
  459. package/client/dist/assets/index-DIhMEAVw.js +0 -66
  460. package/client/dist/assets/index-DwygcU7s.css +0 -2
  461. package/client/dist/assets/mcp-B8X8wBLu.js +0 -1
  462. package/client/dist/assets/mcp-C2AojZZN.js +0 -1
  463. package/client/dist/assets/mcp-D8BT78_L.js +0 -1
  464. package/client/dist/assets/mcp-Df5RWBNk.js +0 -1
  465. package/client/dist/assets/mcp-Dj7BgMQW.js +0 -1
  466. package/client/dist/assets/mcp-Q7iT7rcz.js +0 -1
  467. package/client/dist/assets/mcp-YlvNvJbW.js +0 -1
  468. package/client/dist/assets/mcp-mKFpTSRb.js +0 -1
  469. package/client/dist/assets/narration-4Z2VUhZw.js +0 -1
  470. package/client/dist/assets/narration-BGuiEDj3.js +0 -1
  471. package/client/dist/assets/narration-BuSoqRmv.js +0 -1
  472. package/client/dist/assets/narration-CB9t29fy.js +0 -1
  473. package/client/dist/assets/narration-CU3x8FHD.js +0 -1
  474. package/client/dist/assets/narration-CWeXhfP5.js +0 -1
  475. package/client/dist/assets/narration-DRaDnhT5.js +0 -1
  476. package/client/dist/assets/narration-DtEbQgCw.js +0 -1
  477. package/client/dist/assets/nav-ApJVg3xu.js +0 -1
  478. package/client/dist/assets/nav-BKNky1Bg.js +0 -1
  479. package/client/dist/assets/nav-C6vWWKYx.js +0 -1
  480. package/client/dist/assets/nav-CXJ6Aw89.js +0 -1
  481. package/client/dist/assets/nav-CsmFBIDf.js +0 -1
  482. package/client/dist/assets/nav-DjkmQJjd.js +0 -1
  483. package/client/dist/assets/packet-B1IxaL5f.js +0 -1
  484. package/client/dist/assets/packet-Bh5kkbiB.js +0 -1
  485. package/client/dist/assets/packet-By8fqYxW.js +0 -1
  486. package/client/dist/assets/packet-CZdvA44E.js +0 -1
  487. package/client/dist/assets/packet-CrjHRQCP.js +0 -1
  488. package/client/dist/assets/packet-Dwi2pTtx.js +0 -1
  489. package/client/dist/assets/packet-_-ZIa0IR.js +0 -1
  490. package/client/dist/assets/packet-n0W6E1Hn.js +0 -1
  491. package/client/dist/assets/play-DNlrawbS.js +0 -1
  492. package/client/dist/assets/provider-capabilities-Doej9lfa.js +0 -1
  493. package/client/dist/assets/settings-Bd0x4TBa.js +0 -1
  494. package/client/dist/assets/settings-C1-7cXzC.js +0 -1
  495. package/client/dist/assets/settings-CAFaT38b.js +0 -1
  496. package/client/dist/assets/settings-Ct3v1nW2.js +0 -1
  497. package/client/dist/assets/settings-DHh7_IF5.js +0 -1
  498. package/client/dist/assets/settings-DQXAmdcv.js +0 -1
  499. package/client/dist/assets/settings-guzlhpup.js +0 -1
  500. package/client/dist/assets/settings-sZfTPMEH.js +0 -1
  501. package/client/dist/assets/setup-3jWaoVUO.js +0 -1
  502. package/client/dist/assets/setup-BjgRneb2.js +0 -1
  503. package/client/dist/assets/setup-BzFIjv-f.js +0 -1
  504. package/client/dist/assets/setup-C4VfQsxE.js +0 -1
  505. package/client/dist/assets/setup-DfUkpDbN.js +0 -1
  506. package/client/dist/assets/setup-ECe90Pmu.js +0 -1
  507. package/client/dist/assets/setup-dlqC4Jmm.js +0 -1
  508. package/client/dist/assets/setup-jwfLMiM2.js +0 -1
  509. package/client/dist/assets/spending-EC9xqio-.js +0 -1
  510. package/client/dist/assets/useDesktop-BQVt8lFd.js +0 -1
@@ -15,6 +15,7 @@ const fs_1 = __importDefault(require("fs"));
15
15
  const path_1 = __importDefault(require("path"));
16
16
  const setup_manager_1 = require("./setup-manager");
17
17
  const bundled_core_1 = require("./bundled-core");
18
+ const core_runtime_1 = require("./core-runtime");
18
19
  // Windows has no `which`; probe PATH via `where` instead.
19
20
  const WHICH_CMD = process.platform === 'win32' ? 'where' : 'which';
20
21
  // These must mirror KNOWN_VERBS in cli/specrails-desktop.ts
@@ -43,6 +44,21 @@ function isStringArray(value) {
43
44
  function isRenderedProviderContract(provider, value) {
44
45
  if (!isRecord(value))
45
46
  return false;
47
+ // Core 5 has a deterministic installer. Enrichment no longer exists and is
48
+ // therefore not evidence of provider availability on this contract shape.
49
+ if (value.initCommand === 'init' && value.updateCommand === 'update') {
50
+ if (!isRecord(value.cli) || !isRecord(value.workflows))
51
+ return false;
52
+ if (!isStringArray(value.cli.initArgs) || !isStringArray(value.cli.updateArgs)
53
+ || !value.cli.initArgs.includes('init') || !value.cli.updateArgs.includes('update'))
54
+ return false;
55
+ const workflows = value.workflows;
56
+ if (!['implement', 'batch-implement', 'retry'].every(name => typeof workflows[name] === 'string' && workflows[name]))
57
+ return false;
58
+ return provider !== 'kimi' || (value.cli.providerBinary === 'kimi'
59
+ && value.cli.skillRunner === '.kimi-code/specrails/run-skill.mjs'
60
+ && isStringArray(value.cli.workflowArgs) && value.cli.workflowArgs.includes(value.cli.skillRunner));
61
+ }
46
62
  if (typeof value.enrichCommand !== 'string' ||
47
63
  value.enrichCommand.length === 0 ||
48
64
  !isStringArray(value.enrichArgs) ||
@@ -63,6 +79,14 @@ function isRenderedProviderContract(provider, value) {
63
79
  cli.enrichArgs.includes(skillRunner);
64
80
  }
65
81
  async function findCoreContract() {
82
+ const selected = (0, core_runtime_1.getCoreRuntimeStatus)();
83
+ if (selected.runtime) {
84
+ const contract = path_1.default.join(selected.runtime.root, 'integration-contract.json');
85
+ return fs_1.default.existsSync(contract) ? contract : null;
86
+ }
87
+ // A broken selected runtime must not advertise a different package's contract.
88
+ if (selected.error)
89
+ return null;
66
90
  // Strategy 1: the packaged Desktop's bundled Core is authoritative.
67
91
  const bundledRoot = (0, bundled_core_1.getBundledCoreRoot)();
68
92
  if (bundledRoot) {
@@ -208,7 +232,10 @@ async function checkCoreCompat() {
208
232
  ? Object.keys(contract.checkpoints)
209
233
  : []);
210
234
  const missingCheckpoints = contractCheckpoints.filter((c) => !desktopCheckpointKeys.includes(c));
211
- const extraCheckpoints = desktopCheckpointKeys.filter((k) => !contractCheckpoints.includes(k));
235
+ const deterministic = contract.lifecycle?.mode === 'deterministic' && contract.lifecycle.requiresEnrich === false;
236
+ // Supporting legacy installation checkpoints is compatible with Core 5;
237
+ // demanding them from a deterministic installer would recreate enrich.
238
+ const extraCheckpoints = deterministic ? [] : desktopCheckpointKeys.filter((k) => !contractCheckpoints.includes(k));
212
239
  // v3 dropped the `commands` field from the contract — when absent, the
213
240
  // command-set check is a no-op (cannot prove drift either way).
214
241
  const contractCommands = Array.isArray(contract.commands) ? contract.commands : [];
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.prepareCoreExecution = prepareCoreExecution;
4
+ exports.coreVerificationContext = coreVerificationContext;
5
+ const node_child_process_1 = require("node:child_process");
6
+ const node_fs_1 = require("node:fs");
7
+ const node_path_1 = require("node:path");
8
+ const path_resolver_1 = require("./path-resolver");
9
+ const core_update_state_1 = require("./core-update-state");
10
+ const SAFE_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
11
+ // Resolve existing ancestors too: the tickets file may not exist yet, and macOS
12
+ // exposes temporary directories through both /var and /private/var.
13
+ function canonicalPath(path) {
14
+ try {
15
+ return (0, node_fs_1.realpathSync)(path);
16
+ }
17
+ catch (error) {
18
+ if (error.code !== 'ENOENT')
19
+ throw error;
20
+ const parent = (0, node_path_1.dirname)(path);
21
+ if (parent === path)
22
+ throw error;
23
+ return (0, node_path_1.join)(canonicalPath(parent), (0, node_path_1.basename)(path));
24
+ }
25
+ }
26
+ /** Stable run identity and frozen inputs are shared by every provider and retry.
27
+ * No cwd/global singleton: two rails in the same workspace get separate files.
28
+ */
29
+ function prepareCoreExecution(input) {
30
+ const { run, manifest } = input;
31
+ if (!SAFE_ID.test(run.runId))
32
+ throw new Error('Invalid Core execution run id');
33
+ const cwd = (0, node_fs_1.realpathSync)(input.cwd);
34
+ (0, core_update_state_1.assertWorkspaceCoreReady)(cwd);
35
+ const repositories = manifest
36
+ ? manifest.repositories.map(repo => ({ id: repo.repositoryId, name: repo.name, path: (0, node_fs_1.realpathSync)(repo.worktreePath), baseSha: repo.baseSha }))
37
+ : [{ id: run.repositoryId ?? (run.spec?.repositoryIds?.length === 1 ? run.spec.repositoryIds[0] : 'primary'), name: (0, node_path_1.basename)(input.repoDir ?? cwd), path: (0, node_fs_1.realpathSync)(input.repoDir ?? cwd) }];
38
+ if (!repositories.length || repositories.some(repo => !SAFE_ID.test(repo.id)))
39
+ throw new Error('Invalid Core repository scope');
40
+ const artifactRepositoryId = manifest?.artifactRepositoryId ?? repositories[0].id;
41
+ const artifactRepo = repositories.find(repo => repo.id === artifactRepositoryId);
42
+ if (!artifactRepo)
43
+ throw new Error('Core artifact repository is outside the run scope');
44
+ const rawTickets = run.spec?.tickets?.length ? run.spec.tickets : run.spec ? [{
45
+ id: run.spec.id ?? run.spec.ticketIds?.[0] ?? 'goal', title: run.spec.title,
46
+ description: run.spec.description, repositoryIds: run.spec.repositoryIds,
47
+ }] : run.goal ? [{ id: 'goal', title: 'Loop goal', description: run.goal }] : [];
48
+ const specs = rawTickets.map(ticket => ({
49
+ id: ticket.id, title: ticket.title ?? '', description: ticket.description ?? '',
50
+ ...(ticket.repositoryIds ? { repositoryIds: [...ticket.repositoryIds] } : {}),
51
+ }));
52
+ if (specs.some(spec => spec.repositoryIds?.some(id => !repositories.some(repo => repo.id === id)))) {
53
+ throw new Error('Frozen spec selects a repository outside the execution scope');
54
+ }
55
+ const backlogPath = canonicalPath(input.env.SPECRAILS_TICKETS_PATH
56
+ ? (0, node_path_1.resolve)(input.env.SPECRAILS_TICKETS_PATH) : (0, node_path_1.join)(cwd, '.specrails', 'local-tickets.json'));
57
+ const backlogRoot = (0, node_fs_1.realpathSync)((0, node_path_1.dirname)((0, node_path_1.dirname)(backlogPath)));
58
+ const context = {
59
+ schemaVersion: 1, runId: run.runId, backlogRoot,
60
+ backlogPath, artifactRoot: artifactRepo.path,
61
+ artifactRepositoryId, repositories,
62
+ ownership: { git: input.env.SPECRAILS_GIT_AUTO === 'false' ? 'host' : 'core', backlog: 'host', worktrees: 'host' }, specs,
63
+ };
64
+ const directory = (0, node_path_1.join)(backlogRoot, '.specrails', 'pipeline', run.runId);
65
+ (0, node_fs_1.mkdirSync)(directory, { recursive: true, mode: 0o700 });
66
+ // Core owns context.json and may normalize/add fields there. Keep Desktop's
67
+ // immutable admission snapshot separate so the next rail step can reuse it.
68
+ const contextPath = (0, node_path_1.join)(directory, 'desktop-context.json');
69
+ const serialized = JSON.stringify(context, null, 2) + '\n';
70
+ try {
71
+ (0, node_fs_1.writeFileSync)(contextPath, serialized, { flag: 'wx', mode: 0o600 });
72
+ }
73
+ catch (error) {
74
+ if (error.code !== 'EEXIST')
75
+ throw error;
76
+ if ((0, node_fs_1.readFileSync)(contextPath, 'utf8') !== serialized)
77
+ throw new Error('Core execution context changed during an active run; start a new run for changed scope');
78
+ }
79
+ const env = { ...input.env, SPECRAILS_EXECUTION_CONTEXT: contextPath };
80
+ const promptPrefix = run.verificationStep ? coreVerificationContext(contextPath, cwd, env, run.runId) : '';
81
+ return { env, contextPath, promptPrefix };
82
+ }
83
+ /** Ask the installed Core runtime to validate its own receipts. Desktop never
84
+ * treats an agent-authored summary or a JSON 'pass' field as verification.
85
+ * Missing/old runtimes simply leave the normal verification path enabled.
86
+ */
87
+ function coreVerificationContext(contextPath, cwd, env, runId) {
88
+ const helper = (0, node_path_1.join)(cwd, '.specrails', 'runtime', 'pipeline.mjs');
89
+ if (!(0, node_fs_1.existsSync)(helper))
90
+ return '';
91
+ try {
92
+ const stdout = (0, node_child_process_1.execFileSync)((0, path_resolver_1.resolveBundledNodeExe)() ?? process.execPath, [helper, 'status', '--context', contextPath], {
93
+ cwd, env, encoding: 'utf8', timeout: 15_000, maxBuffer: 4 * 1024 * 1024, stdio: ['ignore', 'pipe', 'pipe'],
94
+ });
95
+ const status = JSON.parse(stdout);
96
+ if (status.schemaVersion !== 1 || status.runId !== runId || status.verification?.valid !== true
97
+ || status.verification.receipt?.kind !== 'full' || status.phases?.reviewer?.status !== 'done')
98
+ return '';
99
+ const commands = status.verification.receipt.commands;
100
+ if (!commands?.length || commands.some(command => command.exitCode !== 0))
101
+ return '';
102
+ return [
103
+ 'Core verified evidence for this exact run (validated by its installed runtime at step start):',
104
+ JSON.stringify({ receiptId: status.verification.receipt.id, commands: commands.map(({ repositoryId, command, args, cwd }) => ({ repositoryId, command, args, cwd })) }),
105
+ 'You may reuse these successful commands while inspecting every acceptance criterion and cross-repository contract. Before reporting PASS, validate again with the installed pipeline runtime status using SPECRAILS_EXECUTION_CONTEXT. If you edit files, change configuration/environment, need uncovered behavioral checks, or the receipt is no longer valid, run the affected checks and refresh the full receipt. Do not repeat an unchanged complete verification merely because a new loop step started.',
106
+ ].join('\n');
107
+ }
108
+ catch {
109
+ return '';
110
+ }
111
+ }
@@ -1,19 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CORE_PACKAGE_SPEC = void 0;
4
- /**
5
- * Single source of truth for the specrails-core npm package spec the app
6
- * installs and probes (H5). Pinned to the current major range so a future
7
- * specrails-core 5.x with breaking changes never lands on every user the
8
- * minute it is published — adopting a new major is a deliberate one-line
9
- * bump here, shipped through the app's own release pipeline.
10
- *
11
- * Floor bumped to 4.12.0 — the version that ships the Kimi provider target
12
- * (`.kimi-code/` skills + roles). It also changes the `npx` package-spec string,
13
- * which invalidates any stale `_npx` exec cache that npx would otherwise reuse
14
- * for the old `^4.6.0` range (so users actually resolve the newer core).
15
- *
16
- * `SPECRAILS_CORE_BIN` remains the escape hatch for local/linked builds
17
- * (see getCoreCommand in setup-manager.ts).
18
- */
19
- exports.CORE_PACKAGE_SPEC = 'specrails-core@^4.12.0';
4
+ /** Online fallback selects the supported Core 5 lifecycle. Bundled Core 4 remains
5
+ * readable for installed apps; the runtime resolver selects the newest usable
6
+ * compatible package and never downgrades a newer activated framework. */
7
+ exports.CORE_PACKAGE_SPEC = 'specrails-core@^5.0.0';
@@ -0,0 +1,202 @@
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.managedCoreRoot = managedCoreRoot;
7
+ exports.frameworkRoot = frameworkRoot;
8
+ exports.readCurrentFrameworkVersion = readCurrentFrameworkVersion;
9
+ exports.readCoreRuntime = readCoreRuntime;
10
+ exports.discoverExternalCoreRuntimes = discoverExternalCoreRuntimes;
11
+ exports.resolveCoreRuntime = resolveCoreRuntime;
12
+ exports.getCoreRuntimeStatus = getCoreRuntimeStatus;
13
+ exports.readProjectCoreVersion = readProjectCoreVersion;
14
+ const fs_1 = __importDefault(require("fs"));
15
+ const path_1 = __importDefault(require("path"));
16
+ const artifact_registry_1 = require("./artifact-registry");
17
+ const bundled_core_1 = require("./bundled-core");
18
+ const semver_lite_1 = require("./semver-lite");
19
+ const VERSION = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
20
+ function managedCoreRoot(home) {
21
+ return path_1.default.join((0, artifact_registry_1.resolveHome)(home), '.specrails', 'core');
22
+ }
23
+ function frameworkRoot(home) {
24
+ return path_1.default.join((0, artifact_registry_1.resolveHome)(home), '.specrails', 'framework');
25
+ }
26
+ function readCurrentFrameworkVersion(home) {
27
+ const current = path_1.default.join(frameworkRoot(home), 'current');
28
+ try {
29
+ // realpath also rejects dangling pointers; a pathname alone is not an install.
30
+ const link = fs_1.default.lstatSync(current);
31
+ const target = link.isSymbolicLink() ? fs_1.default.readlinkSync(current) : current;
32
+ const resolved = fs_1.default.realpathSync(path_1.default.isAbsolute(target) ? target : path_1.default.resolve(frameworkRoot(home), target));
33
+ const name = path_1.default.basename(resolved);
34
+ if (VERSION.test(name))
35
+ return name;
36
+ const versions = new Set();
37
+ for (const file of fs_1.default.readdirSync(resolved)) {
38
+ if (!/^\.framework-stamp.*\.json$/.test(file))
39
+ continue;
40
+ const value = JSON.parse(fs_1.default.readFileSync(path_1.default.join(resolved, file), 'utf8')).version;
41
+ if (typeof value === 'string' && VERSION.test(value))
42
+ versions.add(value);
43
+ }
44
+ return versions.size === 1 ? [...versions][0] : null;
45
+ }
46
+ catch {
47
+ return null;
48
+ }
49
+ }
50
+ function readCoreRuntime(root, source) {
51
+ try {
52
+ const realRoot = fs_1.default.realpathSync(root);
53
+ const pkg = JSON.parse(fs_1.default.readFileSync(path_1.default.join(realRoot, 'package.json'), 'utf8'));
54
+ if (pkg.name && pkg.name !== 'specrails-core')
55
+ return null;
56
+ if (typeof pkg.version !== 'string' || !VERSION.test(pkg.version))
57
+ return null;
58
+ const cli = fs_1.default.realpathSync(path_1.default.join(realRoot, 'dist', 'installer', 'cli.js'));
59
+ if (!fs_1.default.statSync(cli).isFile())
60
+ return null;
61
+ return { root: realRoot, cli, version: pkg.version, source };
62
+ }
63
+ catch {
64
+ return null;
65
+ }
66
+ }
67
+ function packageForBinary(binary, source) {
68
+ const candidates = path_1.default.isAbsolute(binary) || /[/\\]/.test(binary)
69
+ ? [path_1.default.resolve(binary)]
70
+ : (process.env.PATH ?? '').split(path_1.default.delimiter).filter(Boolean).flatMap(dir => process.platform === 'win32'
71
+ ? ['', '.cmd', '.exe', '.bat'].map(ext => path_1.default.join(dir, binary + ext))
72
+ : [path_1.default.join(dir, binary)]);
73
+ for (const candidate of candidates) {
74
+ try {
75
+ let directory = path_1.default.dirname(fs_1.default.realpathSync(candidate));
76
+ // npm's Windows shim is beside node_modules, not inside the package.
77
+ const adjacent = readCoreRuntime(path_1.default.join(directory, 'node_modules', 'specrails-core'), source);
78
+ if (adjacent)
79
+ return adjacent;
80
+ for (let depth = 0; depth < 6; depth++) {
81
+ const runtime = readCoreRuntime(directory, source);
82
+ if (runtime)
83
+ return runtime;
84
+ const parent = path_1.default.dirname(directory);
85
+ if (directory === parent)
86
+ break;
87
+ directory = parent;
88
+ }
89
+ }
90
+ catch { /* missing PATH entry */ }
91
+ }
92
+ return null;
93
+ }
94
+ /** Read-only package discovery. No npm downloads and no execution of a PATH shim. */
95
+ function discoverExternalCoreRuntimes() {
96
+ const result = [];
97
+ try {
98
+ const pkg = require.resolve('specrails-core/package.json');
99
+ const local = readCoreRuntime(path_1.default.dirname(pkg), 'local');
100
+ if (local)
101
+ result.push(local);
102
+ }
103
+ catch { /* not a local dependency */ }
104
+ const global = packageForBinary('specrails-core', 'global');
105
+ if (global)
106
+ result.push(global);
107
+ return result;
108
+ }
109
+ /** A caller supplying an isolated home can also supply its isolated external inventory. */
110
+ function resolveCoreRuntime(home, external) {
111
+ const current = readCurrentFrameworkVersion(home);
112
+ const override = process.env.SPECRAILS_CORE_BIN;
113
+ if (override) {
114
+ const runtime = packageForBinary(override, 'override');
115
+ if (!runtime)
116
+ throw new Error('SPECRAILS_CORE_BIN does not resolve to a usable specrails-core package.');
117
+ if (![4, 5].includes(Number(runtime.version.split('.')[0])))
118
+ throw new Error('The explicit Core package is not compatible with this Desktop. Supported Core majors: 4 and 5.');
119
+ if (current && (0, semver_lite_1.compareVersions)(runtime.version, current) < 0)
120
+ throw new Error(`The explicit Core ${runtime.version} is older than active framework ${current}; Desktop will not downgrade it.`);
121
+ return runtime;
122
+ }
123
+ const candidates = [];
124
+ const bundled = (0, bundled_core_1.getBundledCoreRoot)();
125
+ if (bundled) {
126
+ const runtime = readCoreRuntime(bundled, 'bundled');
127
+ if (runtime)
128
+ candidates.push(runtime);
129
+ }
130
+ // Only activated managed packages are candidates. Failed staged updates must
131
+ // not become active simply because their directory exists after a restart.
132
+ if (current) {
133
+ const managed = readCoreRuntime(path_1.default.join(managedCoreRoot(home), current, 'node_modules', 'specrails-core'), 'managed');
134
+ if (managed && managed.version === current)
135
+ candidates.push(managed);
136
+ }
137
+ candidates.push(...(external ?? (home === undefined ? discoverExternalCoreRuntimes() : [])));
138
+ const compatible = candidates.filter(candidate => {
139
+ const major = Number(candidate.version.split('.')[0]);
140
+ return major >= 4 && major <= 5;
141
+ }).sort((a, b) => (0, semver_lite_1.compareVersions)(b.version, a.version));
142
+ const selected = compatible[0] ?? null;
143
+ if (current && (!selected || (0, semver_lite_1.compareVersions)(selected.version, current) < 0)) {
144
+ throw new Error(`Core framework ${current} is installed, but its runtime package is unavailable. Reinstall Core ${current} or a newer compatible version; Desktop will not downgrade it.`);
145
+ }
146
+ return selected;
147
+ }
148
+ function getCoreRuntimeStatus(home) {
149
+ try {
150
+ return { runtime: resolveCoreRuntime(home), error: null };
151
+ }
152
+ catch (error) {
153
+ return { runtime: null, error: error instanceof Error ? error.message : String(error) };
154
+ }
155
+ }
156
+ /** Actual provider links outrank an old workspace seed marker. Never attribute
157
+ * global current to a copied or deliberately pinned project. */
158
+ function readProjectCoreVersion(root, repoPath, home) {
159
+ const providerVersions = {};
160
+ let recordedVersion = null;
161
+ for (const marker of [path_1.default.join(root, '.specrails', 'specrails-version'), path_1.default.join(repoPath, '.specrails-version')]) {
162
+ try {
163
+ const value = fs_1.default.readFileSync(marker, 'utf8').trim();
164
+ if (VERSION.test(value)) {
165
+ recordedVersion = value;
166
+ break;
167
+ }
168
+ }
169
+ catch { /* no legacy marker */ }
170
+ }
171
+ let framework = frameworkRoot(home);
172
+ try {
173
+ framework = fs_1.default.realpathSync(framework);
174
+ }
175
+ catch { /* no managed framework */ }
176
+ for (const [provider, directory] of Object.entries({ claude: '.claude', codex: '.codex', gemini: '.gemini', kimi: '.kimi-code' })) {
177
+ const versions = new Set();
178
+ const inspect = (entry, depth) => {
179
+ try {
180
+ const resolved = fs_1.default.realpathSync(entry);
181
+ const relative = path_1.default.relative(framework, resolved);
182
+ const version = relative.split(path_1.default.sep)[0];
183
+ if (!path_1.default.isAbsolute(relative) && !relative.startsWith('..') && VERSION.test(version)) {
184
+ versions.add(version);
185
+ return;
186
+ }
187
+ if (depth > 0 && fs_1.default.statSync(entry).isDirectory()) {
188
+ for (const child of fs_1.default.readdirSync(entry))
189
+ inspect(path_1.default.join(entry, child), depth - 1);
190
+ }
191
+ }
192
+ catch { /* provider absent or dangling */ }
193
+ };
194
+ inspect(path_1.default.join(root, directory), 2);
195
+ if (versions.size === 1)
196
+ providerVersions[provider] = [...versions][0];
197
+ }
198
+ const versions = new Set(Object.values(providerVersions));
199
+ const linked = versions.size === 1 ? [...versions][0] : null;
200
+ const mixed = fs_1.default.existsSync(path_1.default.join(root, '.specrails', 'core-update-pending.json')) || versions.size > 1 || Boolean(linked && recordedVersion && linked !== recordedVersion);
201
+ return { version: mixed ? null : linked ?? recordedVersion, providerVersions, recordedVersion, mixed };
202
+ }