specrails-desktop 2.29.0 → 2.29.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 (545) hide show
  1. package/client/dist/assets/ActivityFeedPage-ClpD5CFj.js +1 -0
  2. package/client/dist/assets/AgentBrowserCapture-CSPs9Ofc.js +1 -0
  3. package/client/dist/assets/AgentModeCodePane-DwcyklA5.js +2 -0
  4. package/client/dist/assets/AgentModeJobsPane-C69bqlMa.js +1 -0
  5. package/client/dist/assets/AgentsPage-pRiRr9-W.js +86 -0
  6. package/client/dist/assets/AnalyticsPage-C14exKsC.js +1 -0
  7. package/client/dist/assets/BarChart-nBOMNfiy.js +33 -0
  8. package/client/dist/assets/CodePage-CK76JKm9.js +2 -0
  9. package/client/dist/assets/DesktopAnalyticsPage-Cnv0f3XQ.js +1 -0
  10. package/client/dist/assets/DocsDialog-CHUm_Ym0.js +11 -0
  11. package/client/dist/assets/DocsPage-COI-oDok.js +11 -0
  12. package/client/dist/assets/ExportDropdown-BrtfWzEG.js +1 -0
  13. package/client/dist/assets/IntegrationsPage-Bs00_tl4.js +1 -0
  14. package/client/dist/assets/InteractiveJobComposer-CypM7R1F.js +19 -0
  15. package/client/dist/assets/JobDetailModal-B_W0H9dw.js +1 -0
  16. package/client/dist/assets/JobDetailPage-CeeXOoKS.js +1 -0
  17. package/client/dist/assets/JobsPage-CwhJG9jw.js +1 -0
  18. package/client/dist/assets/LoopBuilderPage-C51t1WOM.js +7 -0
  19. package/client/dist/assets/LoopPreviewModal-Y2HgtIJu.js +1 -0
  20. package/client/dist/assets/LoopsPage-Bvn1Kw5V.js +1 -0
  21. package/client/dist/assets/MinimizedChatsContext-DiFvZDPW.js +1 -0
  22. package/client/dist/assets/PluginsPage-BGPRJpdf.js +2 -0
  23. package/client/dist/assets/ProjectSettingsDialog-D_GTyGLc.js +1 -0
  24. package/client/dist/assets/TemplatePreviewModal-szwBhd7h.js +1 -0
  25. package/client/dist/assets/TicketDetailModal-9UEyK974.js +14 -0
  26. package/client/dist/assets/Trans-B_vKZ-Hb.js +1 -0
  27. package/client/dist/assets/activity-DiyjsgQV.js +1 -0
  28. package/client/dist/assets/addon-image-BRmmRHgQ.js +1 -0
  29. package/client/dist/assets/addon-ligatures-qIZUPvRV.js +2 -0
  30. package/client/dist/assets/{addon-webgl-DMbGeI_u.js → addon-webgl-C2d7lriQ.js} +3 -3
  31. package/client/dist/assets/addspec-Rw8uVBC1.js +1 -0
  32. package/client/dist/assets/agent-4rmXoo_p.js +1 -0
  33. package/client/dist/assets/agent-BxZuNGih.js +1 -0
  34. package/client/dist/assets/agent-C3uXOYv_.js +1 -0
  35. package/client/dist/assets/agent-CA8Y4wbw.js +1 -0
  36. package/client/dist/assets/agent-CASKrhG12.js +1 -0
  37. package/client/dist/assets/agent-Cv-jud5n2.js +1 -0
  38. package/client/dist/assets/agent-DitUxYh2.js +1 -0
  39. package/client/dist/assets/agent-Doow4X7o.js +1 -0
  40. package/client/dist/assets/agents-DhG7mg6-.js +1 -0
  41. package/client/dist/assets/agentstudio-BIUe1Im2.js +1 -0
  42. package/client/dist/assets/aiedit-iIjz2_Qk.js +1 -0
  43. package/client/dist/assets/analytics-DZ8Aoq3I.js +1 -0
  44. package/client/dist/assets/api-B2M7CtDw.js +1 -0
  45. package/client/dist/assets/arrow-left-CpIR4j7G.js +1 -0
  46. package/client/dist/assets/arrow-up-right-9DoMn7fD.js +1 -0
  47. package/client/dist/assets/attachments-B53PG733.js +1 -0
  48. package/client/dist/assets/brain-DI9lHkKY.js +1 -0
  49. package/client/dist/assets/browser-CXUcnTMI.js +1 -0
  50. package/client/dist/assets/button-BUIIBQPT.js +1 -0
  51. package/client/dist/assets/chat-BGD7MXAy.js +1 -0
  52. package/client/dist/assets/chevron-right-CViMxucY.js +1 -0
  53. package/client/dist/assets/chunk-KS7C4IRE-Cx5sqopX.js +3 -0
  54. package/client/dist/assets/circle-x-CMYsN4ZH.js +1 -0
  55. package/client/dist/assets/code-BDXEM4ml.js +1 -0
  56. package/client/dist/assets/commands-DyUZQ1FI.js +1 -0
  57. package/client/dist/assets/common-CD1QHriA2.js +1 -0
  58. package/client/dist/assets/common-CwwPaRxx.js +1 -0
  59. package/client/dist/assets/common-DVQuhs-m.js +1 -0
  60. package/client/dist/assets/common-Dg2jaX7d.js +1 -0
  61. package/client/dist/assets/common-DuBwj6tK.js +1 -0
  62. package/client/dist/assets/common-MRj9MHcc.js +1 -0
  63. package/client/dist/assets/common-O4ZpnMLp.js +1 -0
  64. package/client/dist/assets/common-fyeF0v7C2.js +1 -0
  65. package/client/dist/assets/createLucideIcon-Bjbbp_KS.js +1 -0
  66. package/client/dist/assets/{css.worker-Wv5dxAWO.js → css.worker-yKcq13f2.js} +13 -13
  67. package/client/dist/assets/{cssMode-DBHbkBvI.js → cssMode-BM4z9OX0.js} +1 -1
  68. package/client/dist/assets/dashboard-B_NkSHYm.js +1 -0
  69. package/client/dist/assets/dashboard-ClBb_3pq.js +1 -0
  70. package/client/dist/assets/dashboard-CpCmJvMB.js +1 -0
  71. package/client/dist/assets/dashboard-Czohu35O2.js +1 -0
  72. package/client/dist/assets/dashboard-DcjbD0UK.js +1 -0
  73. package/client/dist/assets/dashboard-Dvx5F3we.js +1 -0
  74. package/client/dist/assets/dashboard-R1bOPjBh2.js +1 -0
  75. package/client/dist/assets/dashboard-owcDucDi.js +1 -0
  76. package/client/dist/assets/dialog-CzIekCw0.js +45 -0
  77. package/client/dist/assets/dist-Cez5CRkX.js +1 -0
  78. package/client/dist/assets/dist-bVqfYmby.js +1 -0
  79. package/client/dist/assets/{dist-js-UjXbEWhN.js → dist-js-CcBCbb32.js} +1 -1
  80. package/client/dist/assets/{dist-js-BTAcxhPb.js → dist-js-VwztRkGj.js} +1 -1
  81. package/client/dist/assets/download-CFHyyHcw.js +1 -0
  82. package/client/dist/assets/editor.api2-4ndOupAA.js +872 -0
  83. package/client/dist/assets/{editor.main-C9J2ikJK.js → editor.main-DxrmGfoq.js} +2 -2
  84. package/client/dist/assets/editor.worker-tytyn86m.js +26 -0
  85. package/client/dist/assets/explore-DgBACn39.js +1 -0
  86. package/client/dist/assets/external-link-BcU5EWZp.js +1 -0
  87. package/client/dist/assets/file-text-CFT-xXKN.js +1 -0
  88. package/client/dist/assets/formatDistanceToNow-ByHIauTQ.js +1 -0
  89. package/client/dist/assets/{freemarker2-J5iIIIK-.js → freemarker2-CELlTDJ2.js} +1 -1
  90. package/client/dist/assets/getTimezoneOffsetInMilliseconds-BxHAksaU.js +1 -0
  91. package/client/dist/assets/git-branch-BRM0F5GN.js +1 -0
  92. package/client/dist/assets/{handlebars-DSw1l_tw.js → handlebars-NEjHJ7o_.js} +1 -1
  93. package/client/dist/assets/{html-h2-wE1Lj.js → html-CA10zN5A.js} +1 -1
  94. package/client/dist/assets/{html.worker-CQP8QQsS.js → html.worker-DSJ9zmd7.js} +12 -12
  95. package/client/dist/assets/{htmlMode-Cc_ij7lW.js → htmlMode-89rPYiyq.js} +1 -1
  96. package/client/dist/assets/i18n-CgaRxpII.js +2 -0
  97. package/client/dist/assets/index-BflYQpWm.css +2 -0
  98. package/client/dist/assets/index-C1_-BTXy.js +72 -0
  99. package/client/dist/assets/integrations-mB-7zoyT.js +1 -0
  100. package/client/dist/assets/{javascript-C1q3xv6N.js → javascript-B1gDmwzS.js} +1 -1
  101. package/client/dist/assets/jira-CmKWERE0.js +1 -0
  102. package/client/dist/assets/jira-api-BgFIr8eD.js +1 -0
  103. package/client/dist/assets/job-time-BCL7wee9.js +1 -0
  104. package/client/dist/assets/jobs-B-sDHEay2.js +1 -0
  105. package/client/dist/assets/jobs-BCtGfgUA.js +1 -0
  106. package/client/dist/assets/jobs-BHR_EnDI.js +1 -0
  107. package/client/dist/assets/jobs-BMbZJjJJ.js +1 -0
  108. package/client/dist/assets/jobs-CVFD8rar.js +1 -0
  109. package/client/dist/assets/jobs-DoSaFzAa.js +1 -0
  110. package/client/dist/assets/jobs-DzSIR8V62.js +1 -0
  111. package/client/dist/assets/jobs-lk1_Dq1U.js +1 -0
  112. package/client/dist/assets/json.worker-Oa9UrkKE.js +58 -0
  113. package/client/dist/assets/{jsonMode-CeaCdEhr.js → jsonMode-xHLMfzhF.js} +1 -1
  114. package/client/dist/assets/jsx-runtime-zu2_FqZY.js +1 -0
  115. package/client/dist/assets/lib-C7Mhm-gT.js +7 -0
  116. package/client/dist/assets/lib-CGdyxIWg.js +29 -0
  117. package/client/dist/assets/{liquid-eFsVK0V-.js → liquid-BY6hCUXG.js} +1 -1
  118. package/client/dist/assets/loader-circle-DcygOQpC.js +1 -0
  119. package/client/dist/assets/loops-BzfXWEwO.js +1 -0
  120. package/client/dist/assets/{lspLanguageFeatures-DT3-bbhn.js → lspLanguageFeatures-ira2aEJh.js} +1 -1
  121. package/client/dist/assets/mcp-uDkXYu4L.js +1 -0
  122. package/client/dist/assets/{mdx-Fuwnh1cX.js → mdx-BNx0xr3N.js} +1 -1
  123. package/client/dist/assets/monaco.contribution-Bt92R3Vw.js +2 -0
  124. package/client/dist/assets/nav-myFaXRHD.js +1 -0
  125. package/client/dist/assets/pencil-C9RkrIPZ.js +1 -0
  126. package/client/dist/assets/play-DNlrawbS.js +1 -0
  127. package/client/dist/assets/plus-CsnjfkmX.js +1 -0
  128. package/client/dist/assets/preload-helper-Czpn1I53.js +1 -0
  129. package/client/dist/assets/{python-BgoEs6Cj.js → python-DLdbtmNw.js} +1 -1
  130. package/client/dist/assets/{razor-CM1sPMMq.js → razor-B9gdhAbR.js} +1 -1
  131. package/client/dist/assets/react-dom-DiWzBDP9.js +1 -0
  132. package/client/dist/assets/rolldown-runtime-CNC7AqOf.js +1 -0
  133. package/client/dist/assets/save-28sIlCdr.js +1 -0
  134. package/client/dist/assets/search-Cq_gE3Ik.js +1 -0
  135. package/client/dist/assets/settings-B0ypw9uw.js +1 -0
  136. package/client/dist/assets/{settings-Bp24JHlv2.js → settings-B9ilOSYO.js} +1 -1
  137. package/client/dist/assets/{settings-Bx2ObkTR2.js → settings-BqlWHRHA.js} +1 -1
  138. package/client/dist/assets/{settings-C_T0-j9d.js → settings-D8dlqt4d.js} +1 -1
  139. package/client/dist/assets/{settings-DhaFKpcw2.js → settings-DAZqjX2a2.js} +1 -1
  140. package/client/dist/assets/{settings-B_v3zgJf.js → settings-DRh39v1S2.js} +1 -1
  141. package/client/dist/assets/{settings-BemR_e3F.js → settings-Mj1OJbfd2.js} +1 -1
  142. package/client/dist/assets/{settings-BvIwQ3A1.js → settings-lRReaSYm.js} +1 -1
  143. package/client/dist/assets/setup-CmK87LuS.js +1 -0
  144. package/client/dist/assets/sparkles-DrY8hb0X.js +1 -0
  145. package/client/dist/assets/specs-DII0C8gw.js +1 -0
  146. package/client/dist/assets/spending-C4p06nen.js +1 -0
  147. package/client/dist/assets/terminal-BFRZnMPP.js +1 -0
  148. package/client/dist/assets/tickets-B8BuAaj5.js +1 -0
  149. package/client/dist/assets/tickets-B_yh4qQk.js +1 -0
  150. package/client/dist/assets/tickets-Bs37scwY2.js +1 -0
  151. package/client/dist/assets/tickets-CFk2n2Or.js +1 -0
  152. package/client/dist/assets/tickets-DQp7JS2R2.js +1 -0
  153. package/client/dist/assets/tickets-D_yDquEw.js +1 -0
  154. package/client/dist/assets/tickets-DpmdE8tv2.js +1 -0
  155. package/client/dist/assets/tickets-pAUJkDTu.js +1 -0
  156. package/client/dist/assets/trash-2-BOU3WdZZ.js +1 -0
  157. package/client/dist/assets/triangle-alert-H9T4jAmh.js +1 -0
  158. package/client/dist/assets/{ts.worker-METxwbDZ.js → ts.worker-BtjBFNHX.js} +48 -33
  159. package/client/dist/assets/{tsMode-BmT8WogI.js → tsMode-DEjSThU9.js} +1 -1
  160. package/client/dist/assets/{typescript-CQrQPsoW.js → typescript-CRRnD2Ts.js} +1 -1
  161. package/client/dist/assets/upload-DYMjAQ6M.js +1 -0
  162. package/client/dist/assets/useBrowserCaptureSession-2OqX0vap.js +1 -0
  163. package/client/dist/assets/useDesktop-X8YB9xzv.js +1 -0
  164. package/client/dist/assets/useSharedWebSocket-DaPh7QBL.js +1 -0
  165. package/client/dist/assets/utils-BC4DHlz2.js +1 -0
  166. package/client/dist/assets/value-s-gzBeyF.js +1 -0
  167. package/client/dist/assets/{workers-U0UXyLUf.js → workers-uOo7WLaa.js} +1 -1
  168. package/client/dist/assets/x-CBMI9ejn.js +1 -0
  169. package/client/dist/assets/{xml-WRxJs8_I.js → xml-EDREH2X7.js} +1 -1
  170. package/client/dist/assets/{yaml-CjpSTjJU.js → yaml-BjaDVX1E.js} +1 -1
  171. package/client/dist/assets/zap-CHo3aCD1.js +1 -0
  172. package/client/dist/index.html +73 -32
  173. package/docs/guide/en/integrations/5-mcp-server.md +2 -2
  174. package/docs/internals/safe-pr-review-flow.md +190 -132
  175. package/docs/mcp.md +15 -5
  176. package/package.json +11 -7
  177. package/server/dist/active-pr-continuation.js +16 -1
  178. package/server/dist/agent-chat-manager.js +360 -181
  179. package/server/dist/agent-cwd-manager.js +52 -8
  180. package/server/dist/agent-generator.js +90 -48
  181. package/server/dist/agent-mcp-config.js +69 -36
  182. package/server/dist/agent-operator-prompt.js +3 -2
  183. package/server/dist/agent-refine-manager.js +47 -6
  184. package/server/dist/agent-tier.js +13 -11
  185. package/server/dist/artifact-registry.js +33 -2
  186. package/server/dist/auth.js +5 -4
  187. package/server/dist/browser-capture-manager.js +92 -29
  188. package/server/dist/chat-manager.js +302 -46
  189. package/server/dist/contract-refine-runner.js +19 -6
  190. package/server/dist/db.js +665 -8
  191. package/server/dist/desktop-router.js +1 -2
  192. package/server/dist/headroom-manager.js +1310 -121
  193. package/server/dist/headroom-routing.js +120 -2
  194. package/server/dist/index.js +48 -13
  195. package/server/dist/interactive-job-session.js +237 -82
  196. package/server/dist/jira/jira-adf.js +10 -0
  197. package/server/dist/jira/jira-db.js +15 -3
  198. package/server/dist/jira/jira-sync-manager.js +182 -13
  199. package/server/dist/job-listing.js +140 -0
  200. package/server/dist/job-spawn-idempotency.js +67 -0
  201. package/server/dist/loop-run-manager.js +508 -98
  202. package/server/dist/loop-runs-store.js +266 -13
  203. package/server/dist/mcp/agent-capability.js +71 -0
  204. package/server/dist/mcp/guide.js +5 -2
  205. package/server/dist/mcp/mcp-server.js +5 -10
  206. package/server/dist/mcp/mcp-token.js +5 -5
  207. package/server/dist/mcp/tools/jobs.js +20 -13
  208. package/server/dist/mcp/tools/types.js +20 -42
  209. package/server/dist/mobile/mobile-router.js +1 -1
  210. package/server/dist/pr-lifecycle.js +77 -0
  211. package/server/dist/pr-publisher.js +94 -27
  212. package/server/dist/process-admission.js +82 -0
  213. package/server/dist/project-registry.js +572 -174
  214. package/server/dist/project-router-git.js +13 -2
  215. package/server/dist/project-router-jobs.js +111 -55
  216. package/server/dist/project-router-tickets.js +32 -2
  217. package/server/dist/providers/claude-adapter.js +21 -13
  218. package/server/dist/queue-manager.js +2332 -623
  219. package/server/dist/rail-isolated-launch.js +1141 -280
  220. package/server/dist/rail-isolation.js +4 -2
  221. package/server/dist/rail-pr-decision.js +756 -270
  222. package/server/dist/rail-pr-delivery.js +2 -1
  223. package/server/dist/rail-pr-store.js +317 -18
  224. package/server/dist/rail-pr-ticket-effects.js +328 -0
  225. package/server/dist/rail-worktree-release.js +28 -6
  226. package/server/dist/rails-router.js +149 -112
  227. package/server/dist/rails-store.js +106 -3
  228. package/server/dist/ticket-store.js +23 -1
  229. package/server/dist/transient-children.js +13 -0
  230. package/server/dist/util/cli-prompt.js +42 -8
  231. package/server/dist/util/secure-token-file.js +84 -0
  232. package/server/dist/worktree-manager.js +70 -21
  233. package/client/dist/assets/ActivityFeedPage-Be-6L0Ld.js +0 -1
  234. package/client/dist/assets/AgentBrowserCapture-CpZ-dd8O.js +0 -1
  235. package/client/dist/assets/AgentIntegrationsModal-DO1pN_Ez.js +0 -1
  236. package/client/dist/assets/AgentModeCodePane-DLltTOqp.js +0 -2
  237. package/client/dist/assets/AgentModeJobsPane-Dp5YvmW0.js +0 -1
  238. package/client/dist/assets/AgentsPage-ehHuVUds.js +0 -86
  239. package/client/dist/assets/AnalyticsPage-C4Ik95FX.js +0 -1
  240. package/client/dist/assets/BarChart-DVZgrhJd.js +0 -33
  241. package/client/dist/assets/CodePage-D4OCMfxL.js +0 -2
  242. package/client/dist/assets/DesktopAnalyticsPage-2Xf-52x2.js +0 -1
  243. package/client/dist/assets/DocsDialog-CHihLjWd.js +0 -11
  244. package/client/dist/assets/DocsPage-1vEk7XbH.js +0 -11
  245. package/client/dist/assets/ExportDropdown-DLHFQxVn.js +0 -1
  246. package/client/dist/assets/IntegrationsPage-CCb2YuyJ.js +0 -1
  247. package/client/dist/assets/InteractiveJobComposer-CxJJEnjw.js +0 -19
  248. package/client/dist/assets/JobDetailModal-CJI7qRkm.js +0 -1
  249. package/client/dist/assets/JobDetailPage-DwA9bbwx.js +0 -1
  250. package/client/dist/assets/JobsPage-BDIyFfd5.js +0 -1
  251. package/client/dist/assets/LoopBuilderPage-CpBaW59t.js +0 -7
  252. package/client/dist/assets/LoopPreviewModal-CwpKcv0Y.js +0 -1
  253. package/client/dist/assets/LoopsPage-BO0Pa8oz.js +0 -1
  254. package/client/dist/assets/PluginsPage-BBGTBpGh.js +0 -2
  255. package/client/dist/assets/ProjectSettingsDialog-M9zGQo0l.js +0 -1
  256. package/client/dist/assets/TemplatePreviewModal-eBI0zL5P.js +0 -1
  257. package/client/dist/assets/activity-Dbl71S-E.js +0 -1
  258. package/client/dist/assets/addon-image-CwoZj17F.js +0 -1
  259. package/client/dist/assets/addon-ligatures-CWDrED80.js +0 -2
  260. package/client/dist/assets/addspec-DrXqP8ip.js +0 -1
  261. package/client/dist/assets/agent-BEXYxDbs.js +0 -1
  262. package/client/dist/assets/agent-BoXSzaBk2.js +0 -1
  263. package/client/dist/assets/agent-C2-rROL52.js +0 -1
  264. package/client/dist/assets/agent-CeRTdGT12.js +0 -1
  265. package/client/dist/assets/agent-DZ8zTrQT.js +0 -1
  266. package/client/dist/assets/agent-DqyzT33X.js +0 -1
  267. package/client/dist/assets/agent-fQI_6tsA.js +0 -1
  268. package/client/dist/assets/agent-tJdAobaM.js +0 -1
  269. package/client/dist/assets/agents-CGDn_3kB.js +0 -1
  270. package/client/dist/assets/agentstudio-Dxe_94PK.js +0 -1
  271. package/client/dist/assets/aiedit-DrfHQnlz.js +0 -1
  272. package/client/dist/assets/analytics-CxDYcBl9.js +0 -1
  273. package/client/dist/assets/attachments-DvxQbBTC.js +0 -1
  274. package/client/dist/assets/brain-DecvjjPU.js +0 -1
  275. package/client/dist/assets/browser-DM8G151q.js +0 -1
  276. package/client/dist/assets/chat-0dg5hOo_.js +0 -1
  277. package/client/dist/assets/chunk-BNv3lrIs.js +0 -1
  278. package/client/dist/assets/code-B62fClk-.js +0 -1
  279. package/client/dist/assets/commands-DCJ-R9E4.js +0 -1
  280. package/client/dist/assets/common-BfQD173j.js +0 -1
  281. package/client/dist/assets/common-CF8iGXrG.js +0 -1
  282. package/client/dist/assets/common-Cfmwcrl52.js +0 -1
  283. package/client/dist/assets/common-D2cimsul.js +0 -1
  284. package/client/dist/assets/common-DH7fjyL1.js +0 -1
  285. package/client/dist/assets/common-DXrmj6WD.js +0 -1
  286. package/client/dist/assets/common-DZbXlmq72.js +0 -1
  287. package/client/dist/assets/common-DtXmzX2o2.js +0 -1
  288. package/client/dist/assets/dashboard-5C2FOZQX.js +0 -1
  289. package/client/dist/assets/dashboard-B6iQ-IL_.js +0 -1
  290. package/client/dist/assets/dashboard-BFfnCtq52.js +0 -1
  291. package/client/dist/assets/dashboard-BIC8KtRf2.js +0 -1
  292. package/client/dist/assets/dashboard-CEgg9NAr.js +0 -1
  293. package/client/dist/assets/dashboard-CiOyDh9L.js +0 -1
  294. package/client/dist/assets/dashboard-D6x5OnNj2.js +0 -1
  295. package/client/dist/assets/dashboard-DBuLfWo9.js +0 -1
  296. package/client/dist/assets/editor.api2-C3B0tp2x.js +0 -872
  297. package/client/dist/assets/editor.worker-Bd9IXS8d.js +0 -26
  298. package/client/dist/assets/explore-_XyU5e7R.js +0 -1
  299. package/client/dist/assets/index-BVbgKXUu.css +0 -2
  300. package/client/dist/assets/index-OBDI7bHm.js +0 -158
  301. package/client/dist/assets/integrations-By80EBkf.js +0 -1
  302. package/client/dist/assets/jira-DeIjwCK3.js +0 -1
  303. package/client/dist/assets/jobs-BFIdeDTw.js +0 -1
  304. package/client/dist/assets/jobs-BJ-Gcao22.js +0 -1
  305. package/client/dist/assets/jobs-DAGiPVIS2.js +0 -1
  306. package/client/dist/assets/jobs-DAU8C_tZ.js +0 -1
  307. package/client/dist/assets/jobs-Da0GaaSc.js +0 -1
  308. package/client/dist/assets/jobs-DrYmsKy5.js +0 -1
  309. package/client/dist/assets/jobs-P3unxtxo2.js +0 -1
  310. package/client/dist/assets/jobs-p360zdf1.js +0 -1
  311. package/client/dist/assets/json.worker-DzV-CpCQ.js +0 -58
  312. package/client/dist/assets/lib-C5ZxrPSR.js +0 -7
  313. package/client/dist/assets/loops-CO6q75W8.js +0 -1
  314. package/client/dist/assets/mcp-HwBbQDk0.js +0 -1
  315. package/client/dist/assets/monaco.contribution-Desq7oq4.js +0 -2
  316. package/client/dist/assets/nav-BTg8s-cD.js +0 -1
  317. package/client/dist/assets/preload-helper-DSXbuxSR.js +0 -1
  318. package/client/dist/assets/settings-BYCMtxOz.js +0 -1
  319. package/client/dist/assets/setup-D2CmgAro.js +0 -1
  320. package/client/dist/assets/specs-PGIOzMtc.js +0 -1
  321. package/client/dist/assets/terminal-CFt56A5f.js +0 -1
  322. package/client/dist/assets/tickets-BHv3ewvq.js +0 -1
  323. package/client/dist/assets/tickets-BIxU86j12.js +0 -1
  324. package/client/dist/assets/tickets-C2BhwzwR.js +0 -1
  325. package/client/dist/assets/tickets-D1IeX2EW.js +0 -1
  326. package/client/dist/assets/tickets-DZut8Ryt.js +0 -1
  327. package/client/dist/assets/tickets-LfK6LzKl2.js +0 -1
  328. package/client/dist/assets/tickets-dQfsc7Ph.js +0 -1
  329. package/client/dist/assets/tickets-sVun0I6v.js +0 -1
  330. package/client/dist/assets/upload-lgjKJgrl.js +0 -1
  331. package/client/dist/assets/value-Bc0_jlJA.js +0 -1
  332. /package/client/dist/assets/{abap-D0E4FfVW.js → abap-08VXUWAP.js} +0 -0
  333. /package/client/dist/assets/{activity-BbWiDfn-2.js → activity-B-rp4h_v.js} +0 -0
  334. /package/client/dist/assets/{activity-DvECTYGt.js → activity-C6kJpm9q2.js} +0 -0
  335. /package/client/dist/assets/{activity-D3Ic-HTS.js → activity-CGx4kb_j.js} +0 -0
  336. /package/client/dist/assets/{activity-BZZlEG3a.js → activity-CnoX2bH7.js} +0 -0
  337. /package/client/dist/assets/{activity-DtzRy92x.js → activity-DAyekdlt2.js} +0 -0
  338. /package/client/dist/assets/{activity-FleOlK0l2.js → activity-DCxtpT7j.js} +0 -0
  339. /package/client/dist/assets/{activity-DFbvNqhE2.js → activity-JzwRaWPD.js} +0 -0
  340. /package/client/dist/assets/{addspec-CFxGvmJR2.js → addspec-BXjvkh5q.js} +0 -0
  341. /package/client/dist/assets/{addspec-NBbcTbLc.js → addspec-C4bwrmpi.js} +0 -0
  342. /package/client/dist/assets/{addspec-BKrH2Ucz.js → addspec-CArHXUDM.js} +0 -0
  343. /package/client/dist/assets/{addspec-CR8MB5Fr2.js → addspec-DTKJcXiR.js} +0 -0
  344. /package/client/dist/assets/{addspec-B_LQMHW3.js → addspec-DbNBbrha2.js} +0 -0
  345. /package/client/dist/assets/{addspec-DaA-CbTt.js → addspec-htHGZHOe2.js} +0 -0
  346. /package/client/dist/assets/{addspec-Bw_YQwo62.js → addspec-lr_LP6jk.js} +0 -0
  347. /package/client/dist/assets/{agents-BHgn--3j.js → agents-6ZOJXWVk2.js} +0 -0
  348. /package/client/dist/assets/{agents-VsyFhGOS2.js → agents-BZ0XQKjg.js} +0 -0
  349. /package/client/dist/assets/{agents-HFCqQH0Z.js → agents-BqWklnHR.js} +0 -0
  350. /package/client/dist/assets/{agents-B_qGaB0F.js → agents-Bz-thHkB2.js} +0 -0
  351. /package/client/dist/assets/{agents-CP8_ezYG.js → agents-CJclElx6.js} +0 -0
  352. /package/client/dist/assets/{agents-B9pFSJQI2.js → agents-D_l9L0VA.js} +0 -0
  353. /package/client/dist/assets/{agents-CV-_xBvX2.js → agents-u_C0jPB5.js} +0 -0
  354. /package/client/dist/assets/{agentstudio-BEp7Sb46.js → agentstudio-BF19hbXj.js} +0 -0
  355. /package/client/dist/assets/{agentstudio-Br3WD7Xs.js → agentstudio-BLGvxWBx2.js} +0 -0
  356. /package/client/dist/assets/{agentstudio-BOjG6tgJ.js → agentstudio-D9UKiWTj2.js} +0 -0
  357. /package/client/dist/assets/{agentstudio-D2A5peWV2.js → agentstudio-Drs37nIM.js} +0 -0
  358. /package/client/dist/assets/{agentstudio-CuTt3ZGe2.js → agentstudio-nEnKkcXM.js} +0 -0
  359. /package/client/dist/assets/{agentstudio-RsxnZtUA.js → agentstudio-pyFcSBKy.js} +0 -0
  360. /package/client/dist/assets/{agentstudio-RfZavULt2.js → agentstudio-zfTzQh3U.js} +0 -0
  361. /package/client/dist/assets/{aiedit-DnBzjlVz2.js → aiedit-B0KUbpB6.js} +0 -0
  362. /package/client/dist/assets/{aiedit-D0Syl-mC.js → aiedit-BoG24nlg2.js} +0 -0
  363. /package/client/dist/assets/{aiedit-CcugGPbS.js → aiedit-CjlSRQVP.js} +0 -0
  364. /package/client/dist/assets/{aiedit-DrIjSojo.js → aiedit-DCjA7jLJ.js} +0 -0
  365. /package/client/dist/assets/{aiedit-CV520D4W2.js → aiedit-DNXxq_Dr.js} +0 -0
  366. /package/client/dist/assets/{aiedit-26p5A_HY2.js → aiedit-DQ-0_pvE.js} +0 -0
  367. /package/client/dist/assets/{aiedit-a-Z-g5iC.js → aiedit-olnv3QSt2.js} +0 -0
  368. /package/client/dist/assets/{analytics-DEe5BMz8.js → analytics-BC7mwR4s.js} +0 -0
  369. /package/client/dist/assets/{analytics-4HvXb0Vn2.js → analytics-BiNg8edP.js} +0 -0
  370. /package/client/dist/assets/{analytics-CpSTNfui.js → analytics-C0s_T2GN.js} +0 -0
  371. /package/client/dist/assets/{analytics-4-eskbtX.js → analytics-CdsAPAwZ2.js} +0 -0
  372. /package/client/dist/assets/{analytics-Bpe41fnX2.js → analytics-Cr1_q-lC.js} +0 -0
  373. /package/client/dist/assets/{analytics-DcOITHla2.js → analytics-IEsKZvpW2.js} +0 -0
  374. /package/client/dist/assets/{analytics-Bd9rHGjV.js → analytics-SRPf84OT.js} +0 -0
  375. /package/client/dist/assets/{apex-D_X_8J4d.js → apex-BWPQTe0t.js} +0 -0
  376. /package/client/dist/assets/{atom-one-dark-BMDPFwRZ.js → atom-one-dark-qiGhVQxg.js} +0 -0
  377. /package/client/dist/assets/{attachments-CgOQ9K-6.js → attachments-D0wXXt9T2.js} +0 -0
  378. /package/client/dist/assets/{attachments-DlEQu56g2.js → attachments-DenIjuVI.js} +0 -0
  379. /package/client/dist/assets/{attachments-CA2f3qL3.js → attachments-DhO7LPfy.js} +0 -0
  380. /package/client/dist/assets/{attachments-D2jwJXQ42.js → attachments-DoH5w0x4.js} +0 -0
  381. /package/client/dist/assets/{attachments-CHDbhKeH.js → attachments-Q9yNtiEM.js} +0 -0
  382. /package/client/dist/assets/{attachments-CKAY5aYG2.js → attachments-V_WZAYXx2.js} +0 -0
  383. /package/client/dist/assets/{attachments-jVdKzAXn.js → attachments-eaeScpjM.js} +0 -0
  384. /package/client/dist/assets/{auth-DpZq5p1e.js → auth-D_5bQv5W.js} +0 -0
  385. /package/client/dist/assets/{azcli-PZLnZ3jH.js → azcli-Bc_sGQ0U.js} +0 -0
  386. /package/client/dist/assets/{bat-KlBOxpO4.js → bat-i0X4ZdIN.js} +0 -0
  387. /package/client/dist/assets/{bicep-CgG9oF3V.js → bicep-B5-_aFwp.js} +0 -0
  388. /package/client/dist/assets/{browser-Cl-FwPXs.js → browser-C25DkQiO.js} +0 -0
  389. /package/client/dist/assets/{browser-JsiohNmW.js → browser-CiJ7-L32.js} +0 -0
  390. /package/client/dist/assets/{browser-BbJ_q_OT2.js → browser-CvgDySd9.js} +0 -0
  391. /package/client/dist/assets/{browser-BQFDxrRq.js → browser-CyR1Kp3m2.js} +0 -0
  392. /package/client/dist/assets/{browser-Do2jf8_N.js → browser-DwZljcRh2.js} +0 -0
  393. /package/client/dist/assets/{browser-C4VJ5CW12.js → browser-DxP-alBK.js} +0 -0
  394. /package/client/dist/assets/{browser-kA31eYhu2.js → browser-rRCwi7Y7.js} +0 -0
  395. /package/client/dist/assets/{cameligo-6R45j6Ph.js → cameligo-DMUM7wLl.js} +0 -0
  396. /package/client/dist/assets/{chat-BalviUAD.js → chat-2rIB8HhT.js} +0 -0
  397. /package/client/dist/assets/{chat-Ds8GvCnv.js → chat-BR8oe53x2.js} +0 -0
  398. /package/client/dist/assets/{chat-D5xEtsf3.js → chat-Bua03tty.js} +0 -0
  399. /package/client/dist/assets/{chat-SaG-ng1x2.js → chat-CZpAQan1.js} +0 -0
  400. /package/client/dist/assets/{chat-CJddjN3D2.js → chat-CdY5SGvS.js} +0 -0
  401. /package/client/dist/assets/{chat-n43nZGvn.js → chat-DZyu3ImY2.js} +0 -0
  402. /package/client/dist/assets/{chat-BMWD_Rx12.js → chat-D_I7nU5K.js} +0 -0
  403. /package/client/dist/assets/{clojure-CLAAMO7J.js → clojure-Cm7r79vr.js} +0 -0
  404. /package/client/dist/assets/{clsx-CNmW0Nip.js → clsx-CjueKrWZ.js} +0 -0
  405. /package/client/dist/assets/{code-C9U6M5-e2.js → code-76gS0IdL.js} +0 -0
  406. /package/client/dist/assets/{code-BotxM43N2.js → code-C1VwxlML.js} +0 -0
  407. /package/client/dist/assets/{code-HDK4P6Rx.js → code-CnMZyJpr.js} +0 -0
  408. /package/client/dist/assets/{code-DUe1Bouz.js → code-D20ef9Cf2.js} +0 -0
  409. /package/client/dist/assets/{code-Bit_z2Xd2.js → code-DdOXaWRY.js} +0 -0
  410. /package/client/dist/assets/{code-F_KjccGf.js → code-Duohuf9l.js} +0 -0
  411. /package/client/dist/assets/{code-CIPmDEd0.js → code-geHmknB92.js} +0 -0
  412. /package/client/dist/assets/{coffee-AruSygo-.js → coffee-Ba7i2nA0.js} +0 -0
  413. /package/client/dist/assets/{commands-BFQZc9AG.js → commands-B9RZO4qS.js} +0 -0
  414. /package/client/dist/assets/{commands-BMkC5-ki.js → commands-BEwbAjtD2.js} +0 -0
  415. /package/client/dist/assets/{commands-KBbhsnw8.js → commands-Bbxu8kLU.js} +0 -0
  416. /package/client/dist/assets/{commands-CzFSoIiq2.js → commands-CDU3qv68.js} +0 -0
  417. /package/client/dist/assets/{commands-CWX9WmDX2.js → commands-CzezgtQj.js} +0 -0
  418. /package/client/dist/assets/{commands-BllkJauO.js → commands-DTQBF_q52.js} +0 -0
  419. /package/client/dist/assets/{commands-cKTaLwwV2.js → commands-hOtKuOXc.js} +0 -0
  420. /package/client/dist/assets/{cpp-DEE5r4Pw.js → cpp-C7h46wYY.js} +0 -0
  421. /package/client/dist/assets/{csharp-BVXJUvbK.js → csharp-BKxtCVv1.js} +0 -0
  422. /package/client/dist/assets/{csp-cXOF0JoV.js → csp-bTuwJoIa.js} +0 -0
  423. /package/client/dist/assets/{css-C_zQuAoy.js → css-DIMkf-bt.js} +0 -0
  424. /package/client/dist/assets/{cypher-t95m_Q-O.js → cypher-CVaqCwHa.js} +0 -0
  425. /package/client/dist/assets/{dart-B4r1Tg-e.js → dart-onAF5SnQ.js} +0 -0
  426. /package/client/dist/assets/{dockerfile-6mt7zHQw.js → dockerfile-DZFCIeNp.js} +0 -0
  427. /package/client/dist/assets/{ecl-DEY_Fz_Q.js → ecl-D05T4iGw.js} +0 -0
  428. /package/client/dist/assets/{elixir-R6-q1c5t.js → elixir-6RTg0lbw.js} +0 -0
  429. /package/client/dist/assets/{explore-CAc8Qzu32.js → explore-BG99VGpL.js} +0 -0
  430. /package/client/dist/assets/{explore-BO_OinBD.js → explore-C0TjprJW2.js} +0 -0
  431. /package/client/dist/assets/{explore-Bhy7WWXv.js → explore-C2dgEo7q.js} +0 -0
  432. /package/client/dist/assets/{explore-ELbrSZyQ2.js → explore-C8NDHbob.js} +0 -0
  433. /package/client/dist/assets/{explore-DW_YTkQh.js → explore-CWWgzQGR.js} +0 -0
  434. /package/client/dist/assets/{explore-DCZL9gRN2.js → explore-CcQXpdtS.js} +0 -0
  435. /package/client/dist/assets/{explore-BEpIs343.js → explore-DsXAgnmJ2.js} +0 -0
  436. /package/client/dist/assets/{flow9-CNQvHBOt.js → flow9-C5_-GSwl.js} +0 -0
  437. /package/client/dist/assets/{format-command-Db1viey1.js → format-command-Dfa1o2d-.js} +0 -0
  438. /package/client/dist/assets/{fsharp-vPZkFXwv.js → fsharp-C8Ef5oNN.js} +0 -0
  439. /package/client/dist/assets/{go-KUzBMYJ_.js → go-C-y9NEjX.js} +0 -0
  440. /package/client/dist/assets/{graphql-C3W0rCsD.js → graphql-fmXr3nnJ.js} +0 -0
  441. /package/client/dist/assets/{hcl-BOOMFSNX.js → hcl-CpzslTdj.js} +0 -0
  442. /package/client/dist/assets/{ini-CFat1WJr.js → ini-sBoK_t0W.js} +0 -0
  443. /package/client/dist/assets/{integrations-CG2dp3Kd.js → integrations-CH0zy1Mw2.js} +0 -0
  444. /package/client/dist/assets/{integrations-CUNe3t9l2.js → integrations-CIAjhd7L.js} +0 -0
  445. /package/client/dist/assets/{integrations-CWjh5VRk.js → integrations-CZdwOe8A.js} +0 -0
  446. /package/client/dist/assets/{integrations-RJfzXkPx2.js → integrations-Ct7omMld.js} +0 -0
  447. /package/client/dist/assets/{integrations-CAjq5tdW2.js → integrations-D6MSxy3-.js} +0 -0
  448. /package/client/dist/assets/{integrations-JOHSCvB3.js → integrations-DbZa-Zyc.js} +0 -0
  449. /package/client/dist/assets/{integrations-CP_aiV_8.js → integrations-b8pH-vfl2.js} +0 -0
  450. /package/client/dist/assets/{java-Dee-CNAM.js → java-BEtHBSE6.js} +0 -0
  451. /package/client/dist/assets/{jira-CQ7mrZde.js → jira-BySfUuQZ.js} +0 -0
  452. /package/client/dist/assets/{jira-DIRkZk9U.js → jira-Byw2C0F8.js} +0 -0
  453. /package/client/dist/assets/{jira-C5UjxHE4.js → jira-CNeYi06w2.js} +0 -0
  454. /package/client/dist/assets/{jira-ZdKb-50F2.js → jira-D11gPhxz.js} +0 -0
  455. /package/client/dist/assets/{jira-DTYu3hJi2.js → jira-D38Gj7AT.js} +0 -0
  456. /package/client/dist/assets/{jira-B5wszJ1-2.js → jira-gAvOyije.js} +0 -0
  457. /package/client/dist/assets/{jira-DtZpokjJ.js → jira-pRaL7JQo2.js} +0 -0
  458. /package/client/dist/assets/{julia-CGNlLYuU.js → julia-Bri6UV-V.js} +0 -0
  459. /package/client/dist/assets/{kotlin-CY7lhknJ.js → kotlin-BOotOW0E.js} +0 -0
  460. /package/client/dist/assets/{less-D0KN7hfJ.js → less-B9JPFI3C.js} +0 -0
  461. /package/client/dist/assets/{lexon-CuRJufPs.js → lexon-CfSJPG6W.js} +0 -0
  462. /package/client/dist/assets/{loops-DKzYFcq6.js → loops-CPpgMapU.js} +0 -0
  463. /package/client/dist/assets/{loops-Du-bNVpc2.js → loops-CWWbKuVL.js} +0 -0
  464. /package/client/dist/assets/{loops-DDs4KPu_.js → loops-Crc9It8o2.js} +0 -0
  465. /package/client/dist/assets/{loops-Bi4ywYGn.js → loops-DH2hZcbK2.js} +0 -0
  466. /package/client/dist/assets/{loops-DvGbSfxw2.js → loops-DS5TmvIU2.js} +0 -0
  467. /package/client/dist/assets/{loops-D3wdUkZV.js → loops-P2f0cN8-.js} +0 -0
  468. /package/client/dist/assets/{loops-BjK8lmoZ2.js → loops-fJV-9hH7.js} +0 -0
  469. /package/client/dist/assets/{lua-DHvH62Zf.js → lua-CsQS60Ue.js} +0 -0
  470. /package/client/dist/assets/{m3-tlthQ8Fo.js → m3-D-oSqn_W.js} +0 -0
  471. /package/client/dist/assets/{markdown-Dbx1LgUZ.js → markdown-Cimd5fb3.js} +0 -0
  472. /package/client/dist/assets/{mcp-DfmzoT5t.js → mcp-Czd_iyp02.js} +0 -0
  473. /package/client/dist/assets/{mcp-BG-OCJca2.js → mcp-D2pc5GGx.js} +0 -0
  474. /package/client/dist/assets/{mcp-CrWdq5db.js → mcp-D4ZjtIx32.js} +0 -0
  475. /package/client/dist/assets/{mcp-CbJ04oFS2.js → mcp-DIfBUv2D2.js} +0 -0
  476. /package/client/dist/assets/{mcp-Dd844F5_.js → mcp-DsTwmjST.js} +0 -0
  477. /package/client/dist/assets/{mcp-zSJ2TsJj.js → mcp-SMkn8boG.js} +0 -0
  478. /package/client/dist/assets/{mcp-DyULurYS2.js → mcp-fSfiVYAc.js} +0 -0
  479. /package/client/dist/assets/{mips-D_O3IUz_.js → mips-CIPQ_RoX.js} +0 -0
  480. /package/client/dist/assets/{msdax-C_ZmCnRt.js → msdax-DauUninz.js} +0 -0
  481. /package/client/dist/assets/{mysql-C-dCEYSX.js → mysql-SOo6toE5.js} +0 -0
  482. /package/client/dist/assets/{nav-DUuw9VIU2.js → nav-BRJBxaGt2.js} +0 -0
  483. /package/client/dist/assets/{nav-D0Erv9ZJ2.js → nav-CAGKv3_F.js} +0 -0
  484. /package/client/dist/assets/{nav-BY_4EWRv.js → nav-CNskRJKQ2.js} +0 -0
  485. /package/client/dist/assets/{nav-CVXtv0wX2.js → nav-DY93irBL.js} +0 -0
  486. /package/client/dist/assets/{nav-B2_ToNqS.js → nav-DhjvYgqt.js} +0 -0
  487. /package/client/dist/assets/{nav-S4HM94vW.js → nav-Gb-r4wop.js} +0 -0
  488. /package/client/dist/assets/{nav-BAMkVEId.js → nav-TvumAFD22.js} +0 -0
  489. /package/client/dist/assets/{objective-c-DZY9Aqxd.js → objective-c-FvmIjYaQ.js} +0 -0
  490. /package/client/dist/assets/{pascal-BVHLXoor.js → pascal-DrH0SRf2.js} +0 -0
  491. /package/client/dist/assets/{pascaligo-XdG_6u3k.js → pascaligo-D-ptJ9y-.js} +0 -0
  492. /package/client/dist/assets/{perl-b9QV0BcD.js → perl-oz_6vUea.js} +0 -0
  493. /package/client/dist/assets/{pgsql-Du5FDOgT.js → pgsql-DTj74zXo.js} +0 -0
  494. /package/client/dist/assets/{php-WJD0z2Z_.js → php-nr791fC2.js} +0 -0
  495. /package/client/dist/assets/{pla-CbciTf2w.js → pla-CopQ2nXW.js} +0 -0
  496. /package/client/dist/assets/{postiats-C1QxmvVq.js → postiats-43DmfD33.js} +0 -0
  497. /package/client/dist/assets/{powerquery-BEYDhPLZ.js → powerquery-D3hlyOfw.js} +0 -0
  498. /package/client/dist/assets/{powershell-CfaYw4XL.js → powershell-DmHpPYUd.js} +0 -0
  499. /package/client/dist/assets/{protobuf-pwZEDOYa.js → protobuf-C531GsRP.js} +0 -0
  500. /package/client/dist/assets/{pug-5ftqSPVe.js → pug-Z5eAx3Zn.js} +0 -0
  501. /package/client/dist/assets/{qsharp-uI6qZMq4.js → qsharp-DkqhCAOL.js} +0 -0
  502. /package/client/dist/assets/{r-BK54P1EG.js → r-BwWrilGY.js} +0 -0
  503. /package/client/dist/assets/{redis-DI0yd7kN.js → redis-ClamHrr6.js} +0 -0
  504. /package/client/dist/assets/{redshift-Dov26eyI.js → redshift-DT7zqm-g.js} +0 -0
  505. /package/client/dist/assets/{restructuredtext-QqJ_1dC-.js → restructuredtext-BYgofb2h.js} +0 -0
  506. /package/client/dist/assets/{ruby-5WjveeVb.js → ruby-DezsRK8O.js} +0 -0
  507. /package/client/dist/assets/{rust-BzVSfqFH.js → rust-DdL9SqIa.js} +0 -0
  508. /package/client/dist/assets/{sb-DMIUfT-3.js → sb-CcwsVR0C.js} +0 -0
  509. /package/client/dist/assets/{scala-CSKA7lqt.js → scala-DHpiXF5c.js} +0 -0
  510. /package/client/dist/assets/{scheme-CojOP2Qc.js → scheme-BeGwcela.js} +0 -0
  511. /package/client/dist/assets/{scss-DoBZGJG6.js → scss-gp-XZpBa.js} +0 -0
  512. /package/client/dist/assets/{setup-JeBwoXoM.js → setup-CGZjy2IF2.js} +0 -0
  513. /package/client/dist/assets/{setup-1vN48B-m2.js → setup-CXa0Sx16.js} +0 -0
  514. /package/client/dist/assets/{setup-BmJ0Kx16.js → setup-D2ktKKMF2.js} +0 -0
  515. /package/client/dist/assets/{setup-T_ApeQDV2.js → setup-DG2H7ha5.js} +0 -0
  516. /package/client/dist/assets/{setup-DQWsu2TR.js → setup-DK5bHDUq2.js} +0 -0
  517. /package/client/dist/assets/{setup-q0wRHUp1.js → setup-DrWlIQTZ.js} +0 -0
  518. /package/client/dist/assets/{setup-mXnzww4f.js → setup-rzHUVgAu.js} +0 -0
  519. /package/client/dist/assets/{shell-YOaE4udl.js → shell-CC2rA5mh.js} +0 -0
  520. /package/client/dist/assets/{solidity-l3jSyVLu.js → solidity-BEEn4gHE.js} +0 -0
  521. /package/client/dist/assets/{sophia-BhSGTaQJ.js → sophia-CRfGWb83.js} +0 -0
  522. /package/client/dist/assets/{sparql-qhk6QD9w.js → sparql-D_Lu-MrJ.js} +0 -0
  523. /package/client/dist/assets/{specs-BGRKhM8t.js → specs-BcyxaCwf2.js} +0 -0
  524. /package/client/dist/assets/{specs-GkiL-snY.js → specs-C1q9geAi.js} +0 -0
  525. /package/client/dist/assets/{specs-DbtIzV8a.js → specs-CLZKysq-2.js} +0 -0
  526. /package/client/dist/assets/{specs-Ce5y2iFc2.js → specs-DZMS9o54.js} +0 -0
  527. /package/client/dist/assets/{specs-CT8exGOy2.js → specs-Dm6zUI-R.js} +0 -0
  528. /package/client/dist/assets/{specs-C6J2zrLM.js → specs-V3TvhKLX.js} +0 -0
  529. /package/client/dist/assets/{specs-DZDoZsDq.js → specs-dV3Mq5Mu2.js} +0 -0
  530. /package/client/dist/assets/{sql-DoO3y21-.js → sql-NEE52Syq.js} +0 -0
  531. /package/client/dist/assets/{st-ChZAY8oG.js → st-DbInun42.js} +0 -0
  532. /package/client/dist/assets/{swift-D290Tr7_.js → swift-Bxkupp3x.js} +0 -0
  533. /package/client/dist/assets/{systemverilog-DsxzgJ-o.js → systemverilog-Bz4Y3fRF.js} +0 -0
  534. /package/client/dist/assets/{tcl-BKDUHAAR.js → tcl-DISqw1ZD.js} +0 -0
  535. /package/client/dist/assets/{terminal-BTpE7iki.js → terminal-BZiIu3rf.js} +0 -0
  536. /package/client/dist/assets/{terminal-DEyt0prF.js → terminal-C2NAd7BW2.js} +0 -0
  537. /package/client/dist/assets/{terminal-a6Uq8B0p.js → terminal-IahE4LW92.js} +0 -0
  538. /package/client/dist/assets/{terminal-DDk_bTw0.js → terminal-QpXZU2Bn2.js} +0 -0
  539. /package/client/dist/assets/{terminal-BNSg2lR7.js → terminal-ScjyXNxQ.js} +0 -0
  540. /package/client/dist/assets/{terminal-Cvabyzm42.js → terminal-d7GadXbN.js} +0 -0
  541. /package/client/dist/assets/{terminal-D0z12_sJ2.js → terminal-tITa81iz.js} +0 -0
  542. /package/client/dist/assets/{twig-UpZQaM8G.js → twig-De2hgUGE.js} +0 -0
  543. /package/client/dist/assets/{typespec-DzaKvN8i.js → typespec-B8J7ngcE.js} +0 -0
  544. /package/client/dist/assets/{vb-CZpbb7tk.js → vb-DV3o63ZY.js} +0 -0
  545. /package/client/dist/assets/{wgsl-CNt3OIvl.js → wgsl-DpFanUEy.js} +0 -0
@@ -44,6 +44,9 @@ class AgentRefineManager {
44
44
  _cancelledIds = new Set();
45
45
  /** Pending SIGKILL escalation timers, keyed by refine id (BUG-LONGTAIL-02). */
46
46
  _killTimers = new Map();
47
+ /** Provider evidence retained outside the awaiting stack so shutdown can
48
+ * account it while the project DB is still open. */
49
+ _liveAccounting = new Map();
47
50
  constructor(broadcast, db, projectPath, projectId, provider) {
48
51
  this._broadcast = broadcast;
49
52
  this._db = db;
@@ -93,7 +96,13 @@ class AgentRefineManager {
93
96
  * orphaned refine child. Idempotent.
94
97
  */
95
98
  shutdown() {
99
+ if (this._disposed)
100
+ return;
96
101
  this._disposed = true;
102
+ for (const [refineId, live] of this._liveAccounting) {
103
+ this._recordRefineInvocation(refineId, live.events, live.model, 'aborted', live.startedAt);
104
+ }
105
+ this._liveAccounting.clear();
97
106
  for (const [refineId, child] of this._activeProcesses) {
98
107
  if (child.pid)
99
108
  this._killWithEscalation(refineId, child.pid);
@@ -103,6 +112,7 @@ class AgentRefineManager {
103
112
  }
104
113
  /** Start a new refine session for the given custom agent. */
105
114
  async startRefine(opts) {
115
+ this._assertActive();
106
116
  if (!CUSTOM_PREFIX.test(opts.agentId)) {
107
117
  throw new Error('not_a_custom_agent');
108
118
  }
@@ -128,6 +138,7 @@ class AgentRefineManager {
128
138
  }
129
139
  /** Send a follow-up instruction on an existing session. */
130
140
  async sendTurn(opts) {
141
+ this._assertActive();
131
142
  const session = (0, agent_refine_db_1.getRefineSession)(this._db, opts.refineId);
132
143
  if (!session)
133
144
  throw new Error('session_not_found');
@@ -140,6 +151,7 @@ class AgentRefineManager {
140
151
  }
141
152
  /** Cancel an in-flight session. Idempotent. */
142
153
  cancel(refineId) {
154
+ this._assertActive();
143
155
  const child = this._activeProcesses.get(refineId);
144
156
  if (child?.pid) {
145
157
  // Mark intentionally-cancelled BEFORE killing so the spawn's settle path
@@ -161,6 +173,7 @@ class AgentRefineManager {
161
173
  }
162
174
  /** Toggle auto-test for a session. */
163
175
  toggleAutoTest(refineId, enabled) {
176
+ this._assertActive();
164
177
  const session = (0, agent_refine_db_1.getRefineSession)(this._db, refineId);
165
178
  if (!session)
166
179
  throw new Error('session_not_found');
@@ -168,6 +181,7 @@ class AgentRefineManager {
168
181
  }
169
182
  /** Apply the current draft_body to disk through the standard write path. */
170
183
  apply(opts) {
184
+ this._assertActive();
171
185
  const session = (0, agent_refine_db_1.getRefineSession)(this._db, opts.refineId);
172
186
  if (!session)
173
187
  return { ok: false, reason: 'session_not_found' };
@@ -206,10 +220,15 @@ class AgentRefineManager {
206
220
  }
207
221
  /** Hard-delete a session (used by cleanup/admin paths). */
208
222
  destroy(refineId) {
223
+ this._assertActive();
209
224
  this.cancel(refineId);
210
225
  (0, agent_refine_db_1.deleteRefineSession)(this._db, refineId);
211
226
  }
212
227
  // ─── Private ──────────────────────────────────────────────────────────────
228
+ _assertActive() {
229
+ if (this._disposed)
230
+ throw new Error('manager_disposed');
231
+ }
213
232
  _agentFile(agentId) {
214
233
  // Per-provider on-disk layout:
215
234
  // claude → <root>/.claude/agents/<agentId>.md
@@ -259,15 +278,22 @@ class AgentRefineManager {
259
278
  ? 'chat-resume'
260
279
  : 'agent-refine';
261
280
  const refineModel = this._adapter.defaultModel();
262
- const args = this._adapter.buildArgs(action, {
281
+ const buildOpts = {
263
282
  prompt,
264
283
  model: refineModel,
265
284
  sessionId: session.session_id ?? undefined,
266
- });
285
+ // The model receives the complete current agent body in its prompt and
286
+ // must only return a replacement body. Repo tools cannot improve this
287
+ // contract and would turn prompt text into filesystem authority.
288
+ toolPolicy: 'none',
289
+ };
290
+ const args = this._adapter.buildArgs(action, buildOpts);
267
291
  let drafted = false;
268
292
  this._bodyBuffers.set(refineId, '');
269
293
  const turnStartedAt = new Date().toISOString();
270
294
  const spawnState = { err: null };
295
+ const liveAccounting = { events: [], model: refineModel, startedAt: turnStartedAt };
296
+ this._liveAccounting.set(refineId, liveAccounting);
271
297
  // Spawn / stream / settlement is owned by the shared spawn-lifecycle; the
272
298
  // refine-specific draft buffering, accounting, validation and history all
273
299
  // stay here unchanged.
@@ -277,13 +303,17 @@ class AgentRefineManager {
277
303
  const refineEnv = refineExec.relocated ? { ...process.env, ...refineExec.env } : undefined;
278
304
  const run = await (0, spawn_lifecycle_1.runAiCliInvocation)({
279
305
  adapter: this._adapter,
280
- action,
281
- buildOpts: { prompt, model: refineModel, sessionId: session.session_id ?? undefined },
306
+ // Pass the already-policy-bound argv so first turns and native resumes
307
+ // cannot diverge if the lifecycle rebuilds options later.
308
+ argv: args,
282
309
  cwd: refineExec.cwd,
283
310
  env: refineEnv,
284
311
  onSpawn: (child) => this._activeProcesses.set(refineId, child),
285
312
  onSpawnError: (err) => { spawnState.err = err; },
286
313
  onEvent: (ev) => {
314
+ if (this._disposed)
315
+ return;
316
+ liveAccounting.events.push(ev);
287
317
  switch (ev.kind) {
288
318
  case 'text-delta': {
289
319
  if (!drafted) {
@@ -320,6 +350,7 @@ class AgentRefineManager {
320
350
  });
321
351
  this._clearKillTimer(refineId);
322
352
  this._activeProcesses.delete(refineId);
353
+ this._liveAccounting.delete(refineId);
323
354
  const fullDraft = this._bodyBuffers.get(refineId) ?? '';
324
355
  this._bodyBuffers.delete(refineId);
325
356
  // A cancel() killed this child intentionally; its non-zero exit must NOT
@@ -329,9 +360,13 @@ class AgentRefineManager {
329
360
  // adapter events) BEFORE short-circuiting — otherwise the cancel path loses
330
361
  // 100% of its spend (MED-12). No status overwrite, no failure emit.
331
362
  const wasCancelled = this._cancelledIds.delete(refineId);
332
- if (wasCancelled || this._disposed) {
363
+ // shutdown() already flushed this live run synchronously while the DB was
364
+ // open. A cancel racing with project removal must not insert it twice.
365
+ if (this._disposed)
366
+ return;
367
+ if (wasCancelled) {
333
368
  this._recordRefineInvocation(refineId, run.events, refineModel, 'aborted', turnStartedAt);
334
- return; // cancel (BUG-LONGTAIL-01) / M12 dispose: project removed mid-flight
369
+ return; // cancel (BUG-LONGTAIL-01)
335
370
  }
336
371
  if (run.spawnFailed) {
337
372
  this._emitError(refineId, `Failed to launch claude: ${spawnState.err?.message ?? 'spawn error'}`);
@@ -427,6 +462,8 @@ class AgentRefineManager {
427
462
  }
428
463
  }
429
464
  async _runAutoTest(refineId, agentId, draftBody, draftHash) {
465
+ if (this._disposed)
466
+ return;
430
467
  (0, agent_refine_db_1.updateRefineSession)(this._db, refineId, { phase: 'testing' });
431
468
  this._emitPhase(refineId, 'testing');
432
469
  const sampleTask = pickSampleTask(this._db, agentId);
@@ -440,6 +477,8 @@ class AgentRefineManager {
440
477
  ? { db: this._db, projectId: this._projectId, surfaceRefId: refineId, broadcast: this._broadcast }
441
478
  : undefined,
442
479
  });
480
+ if (this._disposed)
481
+ return;
443
482
  this._db.prepare(`INSERT INTO agent_tests (agent_name, draft_hash, sample_task_id, tokens, duration_ms, output, created_at)
444
483
  VALUES (?, ?, ?, ?, ?, ?, ?)`).run(agentId, result.draftHash, null, result.tokens, result.durationMs, result.output, Date.now());
445
484
  (0, agent_refine_db_1.updateRefineSession)(this._db, refineId, {
@@ -462,6 +501,8 @@ class AgentRefineManager {
462
501
  });
463
502
  }
464
503
  catch (err) {
504
+ if (this._disposed)
505
+ return;
465
506
  this._emitError(refineId, `Auto-test failed: ${err.message}`);
466
507
  (0, agent_refine_db_1.updateRefineSession)(this._db, refineId, { phase: 'done' });
467
508
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AGENT_CONVERSATION_ENV = exports.AGENT_CONVERSATION_HEADER = exports.AGENT_PROJECT_ENV = exports.AGENT_PROJECT_HEADER = exports.AGENT_TIER_ENV = exports.AGENT_TIER_HEADER = exports.AGENT_TIER_NAMES = void 0;
3
+ exports.AGENT_CAPABILITY_FILE_ENV = exports.AGENT_CAPABILITY_HEADER = exports.AGENT_CONVERSATION_ENV = exports.AGENT_CONVERSATION_HEADER = exports.AGENT_PROJECT_ENV = exports.AGENT_PROJECT_HEADER = exports.AGENT_TIER_ENV = exports.AGENT_TIER_HEADER = exports.AGENT_TIER_NAMES = void 0;
4
4
  exports.tierNameForLevel = tierNameForLevel;
5
5
  exports.levelForTierName = levelForTierName;
6
6
  exports.normalizeLevel = normalizeLevel;
@@ -14,19 +14,22 @@ exports.AGENT_TIER_NAMES = [
14
14
  'operate',
15
15
  'autonomous',
16
16
  ];
17
- /** The HTTP header the agent's MCP bridge sets so the tool guard can read the level. */
17
+ /** @deprecated Untrusted legacy header retained for compatibility/negative tests. */
18
18
  exports.AGENT_TIER_HEADER = 'x-specrails-agent-tier';
19
- /** Env var the AgentChatManager sets on the bridge spawn; the bridge forwards it as the header. */
19
+ /** @deprecated Untrusted legacy env var; the bridge deliberately ignores it. */
20
20
  exports.AGENT_TIER_ENV = 'SPECRAILS_AGENT_TIER';
21
- /** Header carrying the pinned project id so tools resolve it per-request. */
21
+ /** @deprecated Untrusted legacy header retained for compatibility/negative tests. */
22
22
  exports.AGENT_PROJECT_HEADER = 'x-specrails-active-project';
23
- /** Env var the manager sets on the bridge spawn; the bridge forwards it as the project header. */
23
+ /** @deprecated Untrusted legacy env var; the bridge deliberately ignores it. */
24
24
  exports.AGENT_PROJECT_ENV = 'SPECRAILS_ACTIVE_PROJECT';
25
- /** Header carrying the launching agent-chat conversation id (safe-pr-review-flow
26
- * origin link) so an MCP-launched rail can be tagged with its origin. */
25
+ /** @deprecated Untrusted legacy header retained for compatibility/negative tests. */
27
26
  exports.AGENT_CONVERSATION_HEADER = 'x-specrails-agent-conversation';
28
- /** Env var set on the bridge spawn; the bridge forwards it as the conversation header. */
27
+ /** @deprecated Untrusted legacy env var; the bridge deliberately ignores it. */
29
28
  exports.AGENT_CONVERSATION_ENV = 'SPECRAILS_AGENT_CONVERSATION';
29
+ /** Bearer-like proof that an MCP request belongs to a live in-app agent turn. */
30
+ exports.AGENT_CAPABILITY_HEADER = 'x-specrails-agent-capability';
31
+ /** 0600 file path read by the bridge; the secret itself never appears in argv. */
32
+ exports.AGENT_CAPABILITY_FILE_ENV = 'SPECRAILS_AGENT_CAPABILITY_FILE';
30
33
  /** Which MCP tiers a given ladder level unlocks (cumulative). */
31
34
  const TIERS_BY_LEVEL = {
32
35
  0: new Set(['read']),
@@ -64,9 +67,8 @@ function levelAllowsTier(level, tier) {
64
67
  return TIERS_BY_LEVEL[level].has(tier);
65
68
  }
66
69
  /**
67
- * Parse the agent-tier header value into a level, or null when absent/invalid.
68
- * The header carries the tier NAME (observe/edit/operate/autonomous) or the
69
- * numeric level; anything else yields null (→ fall back to Settings tiers).
70
+ * Parse a legacy tier value. Retained for UI/storage compatibility only: MCP
71
+ * request authorization MUST use a verified server-minted capability instead.
70
72
  */
71
73
  function levelFromHeader(headerValue) {
72
74
  if (headerValue == null)
@@ -38,13 +38,16 @@ exports.readRegistryOrEmpty = readRegistryOrEmpty;
38
38
  exports.atomicWrite = atomicWrite;
39
39
  exports.refreshLockHeartbeat = refreshLockHeartbeat;
40
40
  exports.withFileLock = withFileLock;
41
+ exports.mirrorProjectEntryWithPrevious = mirrorProjectEntryWithPrevious;
41
42
  exports.mirrorProjectEntry = mirrorProjectEntry;
42
43
  exports.resolveArtifacts = resolveArtifacts;
43
44
  exports.removeRegistryEntry = removeRegistryEntry;
45
+ exports.restoreRegistryEntry = restoreRegistryEntry;
44
46
  exports.reconcileFromProjects = reconcileFromProjects;
45
47
  const fs_1 = require("fs");
46
48
  const os_1 = __importDefault(require("os"));
47
49
  const path_1 = __importDefault(require("path"));
50
+ const util_1 = require("util");
48
51
  /** Registry schema version. A reader that sees a higher value MUST treat all
49
52
  * entries as absent (legacy fallback), never mis-parse. */
50
53
  exports.REGISTRY_SCHEMA_VERSION = 1;
@@ -458,7 +461,7 @@ function buildMirroredEntry(existing, canon, desiredSlug, input, now, touchInsta
458
461
  *
459
462
  * Runs under the file lock with a re-read so concurrent writers serialise.
460
463
  */
461
- function mirrorProjectEntry(input, home) {
464
+ function mirrorProjectEntryWithPrevious(input, home) {
462
465
  const canon = canonicalizeRepoPath(input.repoPath);
463
466
  const key = normalizeKey(canon);
464
467
  const { providers, primaryProvider } = normalizeProviders(input.providers, input.primaryProvider);
@@ -480,9 +483,12 @@ function mirrorProjectEntry(input, home) {
480
483
  reg.generator = 'specrails-desktop';
481
484
  reg.updatedAt = now;
482
485
  atomicWrite(registryPath(home), JSON.stringify(reg, null, 2) + '\n');
483
- return entry;
486
+ return { entry, previousEntry: existing };
484
487
  });
485
488
  }
489
+ function mirrorProjectEntry(input, home) {
490
+ return mirrorProjectEntryWithPrevious(input, home).entry;
491
+ }
486
492
  /**
487
493
  * Resolve a repo's artifact locations from the registry (read-only). Returns a
488
494
  * legacy (repo-relative) resolution when no entry exists, so callers can treat
@@ -541,6 +547,31 @@ function removeRegistryEntry(repoPath, home) {
541
547
  atomicWrite(registryPath(home), JSON.stringify(reg, null, 2) + '\n');
542
548
  });
543
549
  }
550
+ /** Restore a repo's exact pre-mirror entry, or remove the newly-created entry
551
+ * when no entry existed before the mirror. Used only to roll back a failed
552
+ * higher-level project registration after the mirror itself succeeded. */
553
+ function restoreRegistryEntry(repoPath, previousEntry, expectedCurrentEntry, home) {
554
+ const canon = canonicalizeRepoPath(repoPath);
555
+ const key = normalizeKey(canon);
556
+ return withFileLock(home, () => {
557
+ const reg = readRegistryOrEmpty(home);
558
+ // Hydration happens after the mirror lock is released. If core or another
559
+ // desktop process updated this repo meanwhile, that newer entry is no
560
+ // longer our mutation to undo. Leave it intact instead of restoring stale
561
+ // state over a lock-respecting concurrent writer.
562
+ if (!(0, util_1.isDeepStrictEqual)(reg.projects[key], expectedCurrentEntry))
563
+ return false;
564
+ if (previousEntry)
565
+ reg.projects[key] = previousEntry;
566
+ else
567
+ delete reg.projects[key];
568
+ reg.schemaVersion = exports.REGISTRY_SCHEMA_VERSION;
569
+ reg.generator = 'specrails-desktop';
570
+ reg.updatedAt = new Date().toISOString();
571
+ atomicWrite(registryPath(home), JSON.stringify(reg, null, 2) + '\n');
572
+ return true;
573
+ });
574
+ }
544
575
  /**
545
576
  * MERGE-upsert one entry per desktop project, leaving entries NOT owned by
546
577
  * desktop (`source:'core-standalone'` for repos desktop doesn't track)
@@ -18,6 +18,7 @@ const fs_1 = __importDefault(require("fs"));
18
18
  const path_1 = __importDefault(require("path"));
19
19
  const os_1 = __importDefault(require("os"));
20
20
  const crypto_1 = require("crypto");
21
+ const secure_token_file_1 = require("./util/secure-token-file");
21
22
  const TOKEN_DIR = path_1.default.join(os_1.default.homedir(), '.specrails');
22
23
  const TOKEN_PATH = path_1.default.join(TOKEN_DIR, 'desktop.token');
23
24
  // Legacy (pre-rebrand) token filename — referenced by the one-time migration
@@ -58,8 +59,9 @@ function loadOrGenerateToken() {
58
59
  return _token;
59
60
  migrateLegacyTokenFile();
60
61
  try {
61
- if (fs_1.default.existsSync(TOKEN_PATH)) {
62
- const t = fs_1.default.readFileSync(TOKEN_PATH, 'utf-8').trim();
62
+ const stored = (0, secure_token_file_1.readPrivateTextFile)(TOKEN_PATH);
63
+ if (stored !== null) {
64
+ const t = stored.trim();
63
65
  if (t && t.length >= 32) {
64
66
  _token = t;
65
67
  return _token;
@@ -71,8 +73,7 @@ function loadOrGenerateToken() {
71
73
  }
72
74
  _token = (0, crypto_1.randomUUID)().replace(/-/g, '') + (0, crypto_1.randomUUID)().replace(/-/g, '');
73
75
  try {
74
- fs_1.default.mkdirSync(TOKEN_DIR, { recursive: true });
75
- fs_1.default.writeFileSync(TOKEN_PATH, _token, { encoding: 'utf-8', mode: 0o600 });
76
+ (0, secure_token_file_1.writePrivateTextFile)(TOKEN_PATH, _token);
76
77
  }
77
78
  catch (err) {
78
79
  console.warn('[auth] could not persist token to disk:', err);
@@ -19,6 +19,8 @@ function isTargetClosedError(err) {
19
19
  return /target page, context or browser has been closed|target closed|has been closed/i.test(msg);
20
20
  }
21
21
  const MAX_SESSIONS_PER_PROJECT = 4;
22
+ const DEFAULT_SESSION_IDLE_TTL_MS = 10 * 60_000;
23
+ const DEFAULT_SESSION_SWEEP_INTERVAL_MS = 60_000;
22
24
  const DOM_HTML_BYTE_CAP = 100_000;
23
25
  const LAST_URL_KEY = 'config.browser_last_url';
24
26
  /** Conflation threshold for the screencast fan-out: skip sending a frame to a
@@ -52,6 +54,9 @@ class BrowserCaptureManager {
52
54
  /** When set, pages are opened in this app-wide shared context (global cookies)
53
55
  * and this manager never owns/closes the context — only its own pages. */
54
56
  contextPool;
57
+ now;
58
+ sessionIdleTtlMs;
59
+ idleSweepTimer = null;
55
60
  context = null;
56
61
  contextPromise = null;
57
62
  sessions = new Map();
@@ -67,9 +72,20 @@ class BrowserCaptureManager {
67
72
  this.launcher = opts.launcher ?? (0, browser_playwright_1.createPlaywrightLauncher)();
68
73
  this.attachments = opts.attachments ?? attachment_manager_1.attachmentManager;
69
74
  this.contextPool = opts.contextPool ?? null;
75
+ this.now = opts.now ?? Date.now;
76
+ const requestedIdleTtlMs = opts.sessionIdleTtlMs;
77
+ this.sessionIdleTtlMs = typeof requestedIdleTtlMs === 'number' && Number.isFinite(requestedIdleTtlMs) && requestedIdleTtlMs > 0
78
+ ? requestedIdleTtlMs
79
+ : DEFAULT_SESSION_IDLE_TTL_MS;
70
80
  this.profileDir =
71
81
  opts.profileDir ??
72
82
  path_1.default.join(opts.homeDir ?? os_1.default.homedir(), '.specrails', 'projects', opts.projectSlug, 'browser-profile');
83
+ const requestedSweepIntervalMs = opts.sessionSweepIntervalMs;
84
+ const sweepIntervalMs = typeof requestedSweepIntervalMs === 'number' && Number.isFinite(requestedSweepIntervalMs) && requestedSweepIntervalMs > 0
85
+ ? requestedSweepIntervalMs
86
+ : Math.min(DEFAULT_SESSION_SWEEP_INTERVAL_MS, this.sessionIdleTtlMs);
87
+ this.idleSweepTimer = setInterval(() => { void this.sweepIdleSessions(); }, sweepIntervalMs);
88
+ this.idleSweepTimer.unref?.();
73
89
  }
74
90
  // ─── Last-URL persistence (reuses the queue_state key/value table) ───────────
75
91
  getLastUrl() {
@@ -138,6 +154,20 @@ class BrowserCaptureManager {
138
154
  const s = this.sessions.get(sessionId);
139
155
  return s && !s.closed ? s : undefined;
140
156
  }
157
+ getSessionForActivity(sessionId) {
158
+ const s = this.getSession(sessionId);
159
+ if (s)
160
+ s.lastActivityAt = this.now();
161
+ return s;
162
+ }
163
+ beginOperation(s) {
164
+ s.lastActivityAt = this.now();
165
+ s.activeOperations += 1;
166
+ }
167
+ endOperation(s) {
168
+ s.activeOperations = Math.max(0, s.activeOperations - 1);
169
+ s.lastActivityAt = this.now();
170
+ }
141
171
  async create(opts) {
142
172
  // Reserve the slot SYNCHRONOUSLY before any await so N concurrent creates can't
143
173
  // all observe `< MAX` and race past the cap (BUG-BROWSER-02). `_reserved`
@@ -170,6 +200,7 @@ class BrowserCaptureManager {
170
200
  throw new browser_capture_types_1.BrowserLimitExceededError(MAX_SESSIONS_PER_PROJECT);
171
201
  }
172
202
  const id = (0, ids_1.newId)();
203
+ const activityAt = this.now();
173
204
  const session = {
174
205
  id,
175
206
  projectId: this.projectId,
@@ -181,7 +212,9 @@ class BrowserCaptureManager {
181
212
  url: null,
182
213
  title: null,
183
214
  viewport: { ...DEFAULT_VIEWPORT },
184
- createdAt: opts?.createdAtMs ?? this.now(),
215
+ createdAt: opts?.createdAtMs ?? activityAt,
216
+ lastActivityAt: activityAt,
217
+ activeOperations: 0,
185
218
  screencastPage: null,
186
219
  screencastDesired: false,
187
220
  screencastOp: null,
@@ -302,7 +335,7 @@ class BrowserCaptureManager {
302
335
  /** Switch the viewed page between the root page and the top popup ("back to
303
336
  * page" / "show login window"). Returns false for an unknown session. */
304
337
  setPopupView(sessionId, target) {
305
- const s = this.getSession(sessionId);
338
+ const s = this.getSessionForActivity(sessionId);
306
339
  if (!s)
307
340
  return false;
308
341
  s.popupView = target === 'popup' && s.popups.length > 0;
@@ -314,7 +347,7 @@ class BrowserCaptureManager {
314
347
  async attach(sessionId, ws) {
315
348
  if (this.disposed)
316
349
  return null;
317
- const s = this.getSession(sessionId);
350
+ const s = this.getSessionForActivity(sessionId);
318
351
  if (!s)
319
352
  return null;
320
353
  s.clients.add(ws);
@@ -336,6 +369,7 @@ class BrowserCaptureManager {
336
369
  if (!s)
337
370
  return;
338
371
  s.clients.delete(ws);
372
+ s.lastActivityAt = this.now();
339
373
  if (s.clients.size === 0 && !s.closed) {
340
374
  s.screencastDesired = false;
341
375
  void this.applyScreencast(s);
@@ -406,7 +440,7 @@ class BrowserCaptureManager {
406
440
  async probeElement(sessionId, point) {
407
441
  if (this.disposed)
408
442
  return null;
409
- const s = this.getSession(sessionId);
443
+ const s = this.getSessionForActivity(sessionId);
410
444
  if (!s)
411
445
  return null;
412
446
  return s.page.probeElementAt(point);
@@ -415,7 +449,7 @@ class BrowserCaptureManager {
415
449
  async navigateElement(sessionId, selector, direction) {
416
450
  if (this.disposed)
417
451
  return null;
418
- const s = this.getSession(sessionId);
452
+ const s = this.getSessionForActivity(sessionId);
419
453
  if (!s)
420
454
  return null;
421
455
  return (await s.page.navigateElement?.(selector, direction)) ?? null;
@@ -423,7 +457,7 @@ class BrowserCaptureManager {
423
457
  async handleInput(sessionId, event) {
424
458
  if (this.disposed)
425
459
  return;
426
- const s = this.getSession(sessionId);
460
+ const s = this.getSessionForActivity(sessionId);
427
461
  if (!s)
428
462
  return;
429
463
  if (event.type === 'resize') {
@@ -449,30 +483,36 @@ class BrowserCaptureManager {
449
483
  async navigate(sessionId, action, url) {
450
484
  if (this.disposed)
451
485
  return null;
452
- const s = this.getSession(sessionId);
486
+ const s = this.getSessionForActivity(sessionId);
453
487
  if (!s)
454
488
  return null;
455
- let result;
456
- if (action === 'goto')
457
- result = await s.page.goto(url ?? 'about:blank');
458
- else if (action === 'back')
459
- result = await s.page.goBack();
460
- else if (action === 'forward')
461
- result = await s.page.goForward();
462
- else
463
- result = await s.page.reload();
464
- s.url = result.url;
465
- s.title = result.title;
466
- if (result.url && result.url !== 'about:blank')
467
- this.setLastUrl(result.url);
468
- this.broadcastControl(s, { type: 'nav', url: result.url, title: result.title });
469
- return result;
489
+ this.beginOperation(s);
490
+ try {
491
+ let result;
492
+ if (action === 'goto')
493
+ result = await s.page.goto(url ?? 'about:blank');
494
+ else if (action === 'back')
495
+ result = await s.page.goBack();
496
+ else if (action === 'forward')
497
+ result = await s.page.goForward();
498
+ else
499
+ result = await s.page.reload();
500
+ s.url = result.url;
501
+ s.title = result.title;
502
+ if (result.url && result.url !== 'about:blank')
503
+ this.setLastUrl(result.url);
504
+ this.broadcastControl(s, { type: 'nav', url: result.url, title: result.title });
505
+ return result;
506
+ }
507
+ finally {
508
+ this.endOperation(s);
509
+ }
470
510
  }
471
511
  // ─── Capture: screenshot + rich DOM → attachments ───────────────────────────
472
512
  async capture(sessionId, rect, pendingSpecId, opts) {
473
513
  if (this.disposed)
474
514
  return null;
475
- const s = this.getSession(sessionId);
515
+ const s = this.getSessionForActivity(sessionId);
476
516
  if (!s)
477
517
  return null;
478
518
  const safeRect = {
@@ -483,6 +523,7 @@ class BrowserCaptureManager {
483
523
  };
484
524
  let png;
485
525
  let dom;
526
+ this.beginOperation(s);
486
527
  try {
487
528
  ;
488
529
  [png, dom] = await Promise.all([
@@ -500,6 +541,9 @@ class BrowserCaptureManager {
500
541
  }
501
542
  throw err;
502
543
  }
544
+ finally {
545
+ this.endOperation(s);
546
+ }
503
547
  // Snapshot the recent network requests into the DOM payload (rides the same
504
548
  // JSON attachment → spec prompt). ON unless the spec explicitly disabled it.
505
549
  if (opts?.captureNetwork !== false) {
@@ -546,7 +590,7 @@ class BrowserCaptureManager {
546
590
  async clipboard(sessionId, action, text) {
547
591
  if (this.disposed)
548
592
  return null;
549
- const s = this.getSession(sessionId);
593
+ const s = this.getSessionForActivity(sessionId);
550
594
  if (!s)
551
595
  return null;
552
596
  // Clipboard follows the viewed page: pasting credentials into an OAuth
@@ -575,12 +619,13 @@ class BrowserCaptureManager {
575
619
  async captureBreakpoints(sessionId, rect, anchorPoint, pendingSpecId, dims) {
576
620
  if (this.disposed)
577
621
  return null;
578
- const s = this.getSession(sessionId);
622
+ const s = this.getSessionForActivity(sessionId);
579
623
  if (!s)
580
624
  return null;
581
625
  const order = Object.keys(dims);
582
626
  if (order.length === 0)
583
627
  return null;
628
+ this.beginOperation(s);
584
629
  const stashed = { ...s.viewport };
585
630
  let selector = null;
586
631
  try {
@@ -640,6 +685,7 @@ class BrowserCaptureManager {
640
685
  }
641
686
  catch { /* ignore */ }
642
687
  s.viewport = stashed;
688
+ this.endOperation(s);
643
689
  }
644
690
  const stamp = this.now();
645
691
  const breakpoints = {};
@@ -673,6 +719,23 @@ class BrowserCaptureManager {
673
719
  };
674
720
  }
675
721
  // ─── Teardown ───────────────────────────────────────────────────────────────
722
+ /** Reap sessions abandoned by clients. A connected socket or page-dependent
723
+ * operation is authoritative activity and prevents expiry. `kill()` removes
724
+ * the map entry synchronously, so an attach cannot race between the final
725
+ * eligibility check and teardown on this event loop. */
726
+ async sweepIdleSessions() {
727
+ if (this.disposed)
728
+ return 0;
729
+ const expiresBefore = this.now() - this.sessionIdleTtlMs;
730
+ let reaped = 0;
731
+ for (const [id, s] of this.sessions) {
732
+ if (s.closed || s.clients.size > 0 || s.activeOperations > 0 || s.lastActivityAt > expiresBefore)
733
+ continue;
734
+ if (await this.kill(id))
735
+ reaped += 1;
736
+ }
737
+ return reaped;
738
+ }
676
739
  async kill(sessionId) {
677
740
  const s = this.sessions.get(sessionId);
678
741
  if (!s)
@@ -709,6 +772,10 @@ class BrowserCaptureManager {
709
772
  return true;
710
773
  }
711
774
  async shutdown() {
775
+ if (this.idleSweepTimer) {
776
+ clearInterval(this.idleSweepTimer);
777
+ this.idleSweepTimer = null;
778
+ }
712
779
  if (this.disposed)
713
780
  return;
714
781
  this.disposed = true;
@@ -757,9 +824,5 @@ class BrowserCaptureManager {
757
824
  sessionCount() {
758
825
  return [...this.sessions.values()].filter((s) => !s.closed).length;
759
826
  }
760
- // Wall-clock indirection so tests can stay deterministic if needed.
761
- now() {
762
- return Date.now();
763
- }
764
827
  }
765
828
  exports.BrowserCaptureManager = BrowserCaptureManager;