specrails-desktop 2.29.1 → 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 (544) 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-CgpP6tKI.js → dist-js-CcBCbb32.js} +1 -1
  80. package/client/dist/assets/{dist-js-DHiN-A_E.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/setup-CmK87LuS.js +1 -0
  137. package/client/dist/assets/sparkles-DrY8hb0X.js +1 -0
  138. package/client/dist/assets/specs-DII0C8gw.js +1 -0
  139. package/client/dist/assets/spending-C4p06nen.js +1 -0
  140. package/client/dist/assets/terminal-BFRZnMPP.js +1 -0
  141. package/client/dist/assets/tickets-B8BuAaj5.js +1 -0
  142. package/client/dist/assets/tickets-B_yh4qQk.js +1 -0
  143. package/client/dist/assets/tickets-Bs37scwY2.js +1 -0
  144. package/client/dist/assets/tickets-CFk2n2Or.js +1 -0
  145. package/client/dist/assets/tickets-DQp7JS2R2.js +1 -0
  146. package/client/dist/assets/tickets-D_yDquEw.js +1 -0
  147. package/client/dist/assets/tickets-DpmdE8tv2.js +1 -0
  148. package/client/dist/assets/tickets-pAUJkDTu.js +1 -0
  149. package/client/dist/assets/trash-2-BOU3WdZZ.js +1 -0
  150. package/client/dist/assets/triangle-alert-H9T4jAmh.js +1 -0
  151. package/client/dist/assets/{ts.worker-METxwbDZ.js → ts.worker-BtjBFNHX.js} +48 -33
  152. package/client/dist/assets/{tsMode-BmT8WogI.js → tsMode-DEjSThU9.js} +1 -1
  153. package/client/dist/assets/{typescript-CQrQPsoW.js → typescript-CRRnD2Ts.js} +1 -1
  154. package/client/dist/assets/upload-DYMjAQ6M.js +1 -0
  155. package/client/dist/assets/useBrowserCaptureSession-2OqX0vap.js +1 -0
  156. package/client/dist/assets/useDesktop-X8YB9xzv.js +1 -0
  157. package/client/dist/assets/useSharedWebSocket-DaPh7QBL.js +1 -0
  158. package/client/dist/assets/utils-BC4DHlz2.js +1 -0
  159. package/client/dist/assets/value-s-gzBeyF.js +1 -0
  160. package/client/dist/assets/{workers-U0UXyLUf.js → workers-uOo7WLaa.js} +1 -1
  161. package/client/dist/assets/x-CBMI9ejn.js +1 -0
  162. package/client/dist/assets/{xml-WRxJs8_I.js → xml-EDREH2X7.js} +1 -1
  163. package/client/dist/assets/{yaml-CjpSTjJU.js → yaml-BjaDVX1E.js} +1 -1
  164. package/client/dist/assets/zap-CHo3aCD1.js +1 -0
  165. package/client/dist/index.html +73 -32
  166. package/docs/guide/en/integrations/5-mcp-server.md +2 -2
  167. package/docs/internals/safe-pr-review-flow.md +190 -132
  168. package/docs/mcp.md +15 -5
  169. package/package.json +11 -7
  170. package/server/dist/active-pr-continuation.js +16 -1
  171. package/server/dist/agent-chat-manager.js +360 -181
  172. package/server/dist/agent-cwd-manager.js +52 -8
  173. package/server/dist/agent-generator.js +90 -48
  174. package/server/dist/agent-mcp-config.js +69 -36
  175. package/server/dist/agent-operator-prompt.js +3 -2
  176. package/server/dist/agent-refine-manager.js +47 -6
  177. package/server/dist/agent-tier.js +13 -11
  178. package/server/dist/artifact-registry.js +33 -2
  179. package/server/dist/auth.js +5 -4
  180. package/server/dist/browser-capture-manager.js +92 -29
  181. package/server/dist/chat-manager.js +302 -46
  182. package/server/dist/contract-refine-runner.js +19 -6
  183. package/server/dist/db.js +665 -8
  184. package/server/dist/desktop-router.js +1 -2
  185. package/server/dist/headroom-manager.js +1310 -121
  186. package/server/dist/headroom-routing.js +120 -2
  187. package/server/dist/index.js +48 -13
  188. package/server/dist/interactive-job-session.js +237 -82
  189. package/server/dist/jira/jira-adf.js +10 -0
  190. package/server/dist/jira/jira-db.js +15 -3
  191. package/server/dist/jira/jira-sync-manager.js +182 -13
  192. package/server/dist/job-listing.js +140 -0
  193. package/server/dist/job-spawn-idempotency.js +67 -0
  194. package/server/dist/loop-run-manager.js +508 -98
  195. package/server/dist/loop-runs-store.js +266 -13
  196. package/server/dist/mcp/agent-capability.js +71 -0
  197. package/server/dist/mcp/guide.js +5 -2
  198. package/server/dist/mcp/mcp-server.js +5 -10
  199. package/server/dist/mcp/mcp-token.js +5 -5
  200. package/server/dist/mcp/tools/jobs.js +20 -13
  201. package/server/dist/mcp/tools/types.js +20 -42
  202. package/server/dist/mobile/mobile-router.js +1 -1
  203. package/server/dist/pr-lifecycle.js +77 -0
  204. package/server/dist/pr-publisher.js +94 -27
  205. package/server/dist/process-admission.js +82 -0
  206. package/server/dist/project-registry.js +572 -174
  207. package/server/dist/project-router-git.js +13 -2
  208. package/server/dist/project-router-jobs.js +111 -55
  209. package/server/dist/project-router-tickets.js +32 -2
  210. package/server/dist/providers/claude-adapter.js +21 -13
  211. package/server/dist/queue-manager.js +2332 -623
  212. package/server/dist/rail-isolated-launch.js +1137 -290
  213. package/server/dist/rail-isolation.js +4 -2
  214. package/server/dist/rail-pr-decision.js +740 -266
  215. package/server/dist/rail-pr-delivery.js +2 -1
  216. package/server/dist/rail-pr-store.js +317 -18
  217. package/server/dist/rail-pr-ticket-effects.js +328 -0
  218. package/server/dist/rail-worktree-release.js +18 -2
  219. package/server/dist/rails-router.js +149 -119
  220. package/server/dist/rails-store.js +106 -3
  221. package/server/dist/ticket-store.js +23 -1
  222. package/server/dist/transient-children.js +13 -0
  223. package/server/dist/util/cli-prompt.js +42 -8
  224. package/server/dist/util/secure-token-file.js +84 -0
  225. package/server/dist/worktree-manager.js +6 -5
  226. package/client/dist/assets/ActivityFeedPage-D8RKRRoM.js +0 -1
  227. package/client/dist/assets/AgentBrowserCapture-BUHPHNSN.js +0 -1
  228. package/client/dist/assets/AgentModeCodePane-GZc8bNGT.js +0 -2
  229. package/client/dist/assets/AgentModeJobsPane-DWtQqj3k.js +0 -1
  230. package/client/dist/assets/AgentsPage-CKPtHkRP.js +0 -86
  231. package/client/dist/assets/AnalyticsPage-CZW8c77k.js +0 -1
  232. package/client/dist/assets/BarChart-DugEoe2q.js +0 -33
  233. package/client/dist/assets/CodePage-CQ-uKETG.js +0 -2
  234. package/client/dist/assets/DesktopAnalyticsPage-Bgo4SyCH.js +0 -1
  235. package/client/dist/assets/DocsDialog-DxpWw_La.js +0 -11
  236. package/client/dist/assets/DocsPage-CmcOkK19.js +0 -11
  237. package/client/dist/assets/ExportDropdown-DvTS2wc7.js +0 -1
  238. package/client/dist/assets/IntegrationsPage-B72WxJ3Z.js +0 -1
  239. package/client/dist/assets/InteractiveJobComposer-B5gh4Qoy.js +0 -19
  240. package/client/dist/assets/JobDetailModal-D-BeqsJ6.js +0 -1
  241. package/client/dist/assets/JobDetailPage-DwdozwLO.js +0 -1
  242. package/client/dist/assets/JobsPage-BDkinklt.js +0 -1
  243. package/client/dist/assets/LoopBuilderPage-CclJ3VZA.js +0 -7
  244. package/client/dist/assets/LoopPreviewModal-Dw4UgoLu.js +0 -1
  245. package/client/dist/assets/LoopsPage-D7ac4M24.js +0 -1
  246. package/client/dist/assets/PluginsPage-wdC-qa40.js +0 -2
  247. package/client/dist/assets/ProjectSettingsDialog-BlTlRtGI.js +0 -1
  248. package/client/dist/assets/TemplatePreviewModal-CeMx2Red.js +0 -1
  249. package/client/dist/assets/activity-Dbl71S-E.js +0 -1
  250. package/client/dist/assets/addon-image-CwoZj17F.js +0 -1
  251. package/client/dist/assets/addon-ligatures-CWDrED80.js +0 -2
  252. package/client/dist/assets/addspec-DrXqP8ip.js +0 -1
  253. package/client/dist/assets/agent-B8BXmlUQ2.js +0 -1
  254. package/client/dist/assets/agent-BEXYxDbs.js +0 -1
  255. package/client/dist/assets/agent-BYc3-6Ln2.js +0 -1
  256. package/client/dist/assets/agent-BbJorPdT.js +0 -1
  257. package/client/dist/assets/agent-CewFImgL.js +0 -1
  258. package/client/dist/assets/agent-DfhYoUmp.js +0 -1
  259. package/client/dist/assets/agent-TK_rrK4d.js +0 -1
  260. package/client/dist/assets/agent-bHjA9R_j2.js +0 -1
  261. package/client/dist/assets/agents-CGDn_3kB.js +0 -1
  262. package/client/dist/assets/agentstudio-Dxe_94PK.js +0 -1
  263. package/client/dist/assets/aiedit-DrfHQnlz.js +0 -1
  264. package/client/dist/assets/analytics-CxDYcBl9.js +0 -1
  265. package/client/dist/assets/attachments-DvxQbBTC.js +0 -1
  266. package/client/dist/assets/brain-C92rjjYP.js +0 -1
  267. package/client/dist/assets/browser-DM8G151q.js +0 -1
  268. package/client/dist/assets/chat-0dg5hOo_.js +0 -1
  269. package/client/dist/assets/chunk-BNv3lrIs.js +0 -1
  270. package/client/dist/assets/code-B62fClk-.js +0 -1
  271. package/client/dist/assets/commands-DCJ-R9E4.js +0 -1
  272. package/client/dist/assets/common-BM3LFLCE2.js +0 -1
  273. package/client/dist/assets/common-Bwafujnc2.js +0 -1
  274. package/client/dist/assets/common-C-vU-j-I.js +0 -1
  275. package/client/dist/assets/common-C5HKSbbz.js +0 -1
  276. package/client/dist/assets/common-DXrmj6WD.js +0 -1
  277. package/client/dist/assets/common-DhWTkocg.js +0 -1
  278. package/client/dist/assets/common-DiPTT7V_2.js +0 -1
  279. package/client/dist/assets/common-DmqBPwZG.js +0 -1
  280. package/client/dist/assets/dashboard-B5ang-ZS.js +0 -1
  281. package/client/dist/assets/dashboard-CHHcOWVL2.js +0 -1
  282. package/client/dist/assets/dashboard-DBD4wPGY2.js +0 -1
  283. package/client/dist/assets/dashboard-DBuLfWo9.js +0 -1
  284. package/client/dist/assets/dashboard-DSnztwWH.js +0 -1
  285. package/client/dist/assets/dashboard-D_aP_InU.js +0 -1
  286. package/client/dist/assets/dashboard-DmBcdl1B.js +0 -1
  287. package/client/dist/assets/dashboard-RIcUKY1Y2.js +0 -1
  288. package/client/dist/assets/editor.api2-C3B0tp2x.js +0 -872
  289. package/client/dist/assets/editor.worker-Bd9IXS8d.js +0 -26
  290. package/client/dist/assets/explore-_XyU5e7R.js +0 -1
  291. package/client/dist/assets/index-BVbgKXUu.css +0 -2
  292. package/client/dist/assets/index-DyY1QyIn.js +0 -158
  293. package/client/dist/assets/integrations-By80EBkf.js +0 -1
  294. package/client/dist/assets/jira-DeIjwCK3.js +0 -1
  295. package/client/dist/assets/jobs-1GV2-4zd2.js +0 -1
  296. package/client/dist/assets/jobs-26F9gGcE.js +0 -1
  297. package/client/dist/assets/jobs-BgQzB0Sx2.js +0 -1
  298. package/client/dist/assets/jobs-BqWui9_f.js +0 -1
  299. package/client/dist/assets/jobs-CE8qeIYj.js +0 -1
  300. package/client/dist/assets/jobs-DrYmsKy5.js +0 -1
  301. package/client/dist/assets/jobs-DzeuASRf.js +0 -1
  302. package/client/dist/assets/jobs-Wh7dn28q2.js +0 -1
  303. package/client/dist/assets/json.worker-DzV-CpCQ.js +0 -58
  304. package/client/dist/assets/lib-0PFDyMxJ.js +0 -7
  305. package/client/dist/assets/loops-CO6q75W8.js +0 -1
  306. package/client/dist/assets/mcp-HwBbQDk0.js +0 -1
  307. package/client/dist/assets/monaco.contribution-Desq7oq4.js +0 -2
  308. package/client/dist/assets/nav-BTg8s-cD.js +0 -1
  309. package/client/dist/assets/preload-helper-DSXbuxSR.js +0 -1
  310. package/client/dist/assets/settings-cJNynGIZ.js +0 -1
  311. package/client/dist/assets/setup-D2CmgAro.js +0 -1
  312. package/client/dist/assets/specs-PGIOzMtc.js +0 -1
  313. package/client/dist/assets/terminal-CFt56A5f.js +0 -1
  314. package/client/dist/assets/tickets-B7zT4IRf.js +0 -1
  315. package/client/dist/assets/tickets-BHv3ewvq.js +0 -1
  316. package/client/dist/assets/tickets-BoXom7l8.js +0 -1
  317. package/client/dist/assets/tickets-C3b8cHhd2.js +0 -1
  318. package/client/dist/assets/tickets-CFXnJsYF.js +0 -1
  319. package/client/dist/assets/tickets-CWYFvx1W2.js +0 -1
  320. package/client/dist/assets/tickets-DTHo9c3C.js +0 -1
  321. package/client/dist/assets/tickets-SuX_HkK4.js +0 -1
  322. package/client/dist/assets/upload-CmR4h9H1.js +0 -1
  323. package/client/dist/assets/value-JA3bf47v.js +0 -1
  324. /package/client/dist/assets/{abap-D0E4FfVW.js → abap-08VXUWAP.js} +0 -0
  325. /package/client/dist/assets/{activity--iN4Ad2R2.js → activity-B-rp4h_v.js} +0 -0
  326. /package/client/dist/assets/{activity-6hM_ZSg9.js → activity-C6kJpm9q2.js} +0 -0
  327. /package/client/dist/assets/{activity-CIOLxGvh.js → activity-CGx4kb_j.js} +0 -0
  328. /package/client/dist/assets/{activity-BZNfOdiS.js → activity-CnoX2bH7.js} +0 -0
  329. /package/client/dist/assets/{activity-BuVo5sPB.js → activity-DAyekdlt2.js} +0 -0
  330. /package/client/dist/assets/{activity-D2r2h3SE2.js → activity-DCxtpT7j.js} +0 -0
  331. /package/client/dist/assets/{activity-DtxrAUMo2.js → activity-JzwRaWPD.js} +0 -0
  332. /package/client/dist/assets/{addspec-BMtLZLW62.js → addspec-BXjvkh5q.js} +0 -0
  333. /package/client/dist/assets/{addspec-CRuvWn8d.js → addspec-C4bwrmpi.js} +0 -0
  334. /package/client/dist/assets/{addspec-D-JLDsUV.js → addspec-CArHXUDM.js} +0 -0
  335. /package/client/dist/assets/{addspec-mgPOt5q02.js → addspec-DTKJcXiR.js} +0 -0
  336. /package/client/dist/assets/{addspec-DfhDbg5c.js → addspec-DbNBbrha2.js} +0 -0
  337. /package/client/dist/assets/{addspec-CP0HRuxY.js → addspec-htHGZHOe2.js} +0 -0
  338. /package/client/dist/assets/{addspec-bsNDdqRm2.js → addspec-lr_LP6jk.js} +0 -0
  339. /package/client/dist/assets/{agents-78bTZGZh.js → agents-6ZOJXWVk2.js} +0 -0
  340. /package/client/dist/assets/{agents-DDtCJ5M02.js → agents-BZ0XQKjg.js} +0 -0
  341. /package/client/dist/assets/{agents-CWo-KyAB.js → agents-BqWklnHR.js} +0 -0
  342. /package/client/dist/assets/{agents-BUdEi3-N.js → agents-Bz-thHkB2.js} +0 -0
  343. /package/client/dist/assets/{agents-bvyRLczL.js → agents-CJclElx6.js} +0 -0
  344. /package/client/dist/assets/{agents-BpoUaoW92.js → agents-D_l9L0VA.js} +0 -0
  345. /package/client/dist/assets/{agents-BLhWCmDS2.js → agents-u_C0jPB5.js} +0 -0
  346. /package/client/dist/assets/{agentstudio-BMQxc_bz.js → agentstudio-BF19hbXj.js} +0 -0
  347. /package/client/dist/assets/{agentstudio-C_Jq8Tl4.js → agentstudio-BLGvxWBx2.js} +0 -0
  348. /package/client/dist/assets/{agentstudio-Dtq3dGYk.js → agentstudio-D9UKiWTj2.js} +0 -0
  349. /package/client/dist/assets/{agentstudio-CWgXG5W52.js → agentstudio-Drs37nIM.js} +0 -0
  350. /package/client/dist/assets/{agentstudio-sI27TpBu2.js → agentstudio-nEnKkcXM.js} +0 -0
  351. /package/client/dist/assets/{agentstudio-jKMTdT70.js → agentstudio-pyFcSBKy.js} +0 -0
  352. /package/client/dist/assets/{agentstudio-COZriimI2.js → agentstudio-zfTzQh3U.js} +0 -0
  353. /package/client/dist/assets/{aiedit-hknZlly82.js → aiedit-B0KUbpB6.js} +0 -0
  354. /package/client/dist/assets/{aiedit-eMN4eQPF.js → aiedit-BoG24nlg2.js} +0 -0
  355. /package/client/dist/assets/{aiedit-pc5JDUq1.js → aiedit-CjlSRQVP.js} +0 -0
  356. /package/client/dist/assets/{aiedit-B03pD_Na.js → aiedit-DCjA7jLJ.js} +0 -0
  357. /package/client/dist/assets/{aiedit-6CHdb_iv2.js → aiedit-DNXxq_Dr.js} +0 -0
  358. /package/client/dist/assets/{aiedit-igmw-ZoZ2.js → aiedit-DQ-0_pvE.js} +0 -0
  359. /package/client/dist/assets/{aiedit-BtRqRxML.js → aiedit-olnv3QSt2.js} +0 -0
  360. /package/client/dist/assets/{analytics-CCprAqk3.js → analytics-BC7mwR4s.js} +0 -0
  361. /package/client/dist/assets/{analytics-CR1TJqUi2.js → analytics-BiNg8edP.js} +0 -0
  362. /package/client/dist/assets/{analytics-Bj-SmKHa.js → analytics-C0s_T2GN.js} +0 -0
  363. /package/client/dist/assets/{analytics-C5dpiS0o.js → analytics-CdsAPAwZ2.js} +0 -0
  364. /package/client/dist/assets/{analytics-BWMUZ2Pq2.js → analytics-Cr1_q-lC.js} +0 -0
  365. /package/client/dist/assets/{analytics-DfNdXR0y2.js → analytics-IEsKZvpW2.js} +0 -0
  366. /package/client/dist/assets/{analytics-rmHuJv0V.js → analytics-SRPf84OT.js} +0 -0
  367. /package/client/dist/assets/{apex-D_X_8J4d.js → apex-BWPQTe0t.js} +0 -0
  368. /package/client/dist/assets/{atom-one-dark-BMDPFwRZ.js → atom-one-dark-qiGhVQxg.js} +0 -0
  369. /package/client/dist/assets/{attachments-BgBNSqQd.js → attachments-D0wXXt9T2.js} +0 -0
  370. /package/client/dist/assets/{attachments-C9GTTJsx2.js → attachments-DenIjuVI.js} +0 -0
  371. /package/client/dist/assets/{attachments-BjyMmrwE.js → attachments-DhO7LPfy.js} +0 -0
  372. /package/client/dist/assets/{attachments-DPCmkFZu2.js → attachments-DoH5w0x4.js} +0 -0
  373. /package/client/dist/assets/{attachments-DCZOL1RU.js → attachments-Q9yNtiEM.js} +0 -0
  374. /package/client/dist/assets/{attachments-rNn1ekRy2.js → attachments-V_WZAYXx2.js} +0 -0
  375. /package/client/dist/assets/{attachments-DL-bPy9E.js → attachments-eaeScpjM.js} +0 -0
  376. /package/client/dist/assets/{auth-DpZq5p1e.js → auth-D_5bQv5W.js} +0 -0
  377. /package/client/dist/assets/{azcli-PZLnZ3jH.js → azcli-Bc_sGQ0U.js} +0 -0
  378. /package/client/dist/assets/{bat-KlBOxpO4.js → bat-i0X4ZdIN.js} +0 -0
  379. /package/client/dist/assets/{bicep-CgG9oF3V.js → bicep-B5-_aFwp.js} +0 -0
  380. /package/client/dist/assets/{browser-BPkhILSJ.js → browser-C25DkQiO.js} +0 -0
  381. /package/client/dist/assets/{browser-BqLqJVVT.js → browser-CiJ7-L32.js} +0 -0
  382. /package/client/dist/assets/{browser-rWKj-RR_2.js → browser-CvgDySd9.js} +0 -0
  383. /package/client/dist/assets/{browser-Cvg-QHvd2.js → browser-CyR1Kp3m2.js} +0 -0
  384. /package/client/dist/assets/{browser-FRv8P02E.js → browser-DwZljcRh2.js} +0 -0
  385. /package/client/dist/assets/{browser-Cc0iDqUi.js → browser-DxP-alBK.js} +0 -0
  386. /package/client/dist/assets/{browser-BijVYG0Y2.js → browser-rRCwi7Y7.js} +0 -0
  387. /package/client/dist/assets/{cameligo-6R45j6Ph.js → cameligo-DMUM7wLl.js} +0 -0
  388. /package/client/dist/assets/{chat-Bom6bqK3.js → chat-2rIB8HhT.js} +0 -0
  389. /package/client/dist/assets/{chat-vylxqR0P2.js → chat-BR8oe53x2.js} +0 -0
  390. /package/client/dist/assets/{chat-Dnwg-NpQ.js → chat-Bua03tty.js} +0 -0
  391. /package/client/dist/assets/{chat-BgL3zv6x2.js → chat-CZpAQan1.js} +0 -0
  392. /package/client/dist/assets/{chat-DsbwJhus.js → chat-CdY5SGvS.js} +0 -0
  393. /package/client/dist/assets/{chat-Bh3NdgJs.js → chat-DZyu3ImY2.js} +0 -0
  394. /package/client/dist/assets/{chat-DdwZjT8K2.js → chat-D_I7nU5K.js} +0 -0
  395. /package/client/dist/assets/{clojure-CLAAMO7J.js → clojure-Cm7r79vr.js} +0 -0
  396. /package/client/dist/assets/{clsx-CNmW0Nip.js → clsx-CjueKrWZ.js} +0 -0
  397. /package/client/dist/assets/{code-UPVvmAKM2.js → code-76gS0IdL.js} +0 -0
  398. /package/client/dist/assets/{code-BRcDlze52.js → code-C1VwxlML.js} +0 -0
  399. /package/client/dist/assets/{code-CeQ0FZpC.js → code-CnMZyJpr.js} +0 -0
  400. /package/client/dist/assets/{code-DgeHz9CB.js → code-D20ef9Cf2.js} +0 -0
  401. /package/client/dist/assets/{code-DzC1rMk12.js → code-DdOXaWRY.js} +0 -0
  402. /package/client/dist/assets/{code-CwnBPPyA.js → code-Duohuf9l.js} +0 -0
  403. /package/client/dist/assets/{code-BdMy3Ffq.js → code-geHmknB92.js} +0 -0
  404. /package/client/dist/assets/{coffee-AruSygo-.js → coffee-Ba7i2nA0.js} +0 -0
  405. /package/client/dist/assets/{commands-DkU0qliq.js → commands-B9RZO4qS.js} +0 -0
  406. /package/client/dist/assets/{commands-u-4eEHCN.js → commands-BEwbAjtD2.js} +0 -0
  407. /package/client/dist/assets/{commands-JWMfGDmr.js → commands-Bbxu8kLU.js} +0 -0
  408. /package/client/dist/assets/{commands-C4Y3C-PF2.js → commands-CDU3qv68.js} +0 -0
  409. /package/client/dist/assets/{commands-xHDDGfcP2.js → commands-CzezgtQj.js} +0 -0
  410. /package/client/dist/assets/{commands-CSDs9q_2.js → commands-DTQBF_q52.js} +0 -0
  411. /package/client/dist/assets/{commands-RHOchN4n2.js → commands-hOtKuOXc.js} +0 -0
  412. /package/client/dist/assets/{cpp-DEE5r4Pw.js → cpp-C7h46wYY.js} +0 -0
  413. /package/client/dist/assets/{csharp-BVXJUvbK.js → csharp-BKxtCVv1.js} +0 -0
  414. /package/client/dist/assets/{csp-cXOF0JoV.js → csp-bTuwJoIa.js} +0 -0
  415. /package/client/dist/assets/{css-C_zQuAoy.js → css-DIMkf-bt.js} +0 -0
  416. /package/client/dist/assets/{cypher-t95m_Q-O.js → cypher-CVaqCwHa.js} +0 -0
  417. /package/client/dist/assets/{dart-B4r1Tg-e.js → dart-onAF5SnQ.js} +0 -0
  418. /package/client/dist/assets/{dockerfile-6mt7zHQw.js → dockerfile-DZFCIeNp.js} +0 -0
  419. /package/client/dist/assets/{ecl-DEY_Fz_Q.js → ecl-D05T4iGw.js} +0 -0
  420. /package/client/dist/assets/{elixir-R6-q1c5t.js → elixir-6RTg0lbw.js} +0 -0
  421. /package/client/dist/assets/{explore-B7fblXBb2.js → explore-BG99VGpL.js} +0 -0
  422. /package/client/dist/assets/{explore-CNBzrEPS.js → explore-C0TjprJW2.js} +0 -0
  423. /package/client/dist/assets/{explore-C0k8HrkN.js → explore-C2dgEo7q.js} +0 -0
  424. /package/client/dist/assets/{explore-BHtEpoNN2.js → explore-C8NDHbob.js} +0 -0
  425. /package/client/dist/assets/{explore-Dahc1lOx.js → explore-CWWgzQGR.js} +0 -0
  426. /package/client/dist/assets/{explore-D_mWBYCS2.js → explore-CcQXpdtS.js} +0 -0
  427. /package/client/dist/assets/{explore-UvW1jEMa.js → explore-DsXAgnmJ2.js} +0 -0
  428. /package/client/dist/assets/{flow9-CNQvHBOt.js → flow9-C5_-GSwl.js} +0 -0
  429. /package/client/dist/assets/{format-command-CuWuRvka.js → format-command-Dfa1o2d-.js} +0 -0
  430. /package/client/dist/assets/{fsharp-vPZkFXwv.js → fsharp-C8Ef5oNN.js} +0 -0
  431. /package/client/dist/assets/{go-KUzBMYJ_.js → go-C-y9NEjX.js} +0 -0
  432. /package/client/dist/assets/{graphql-C3W0rCsD.js → graphql-fmXr3nnJ.js} +0 -0
  433. /package/client/dist/assets/{hcl-BOOMFSNX.js → hcl-CpzslTdj.js} +0 -0
  434. /package/client/dist/assets/{ini-CFat1WJr.js → ini-sBoK_t0W.js} +0 -0
  435. /package/client/dist/assets/{integrations-TAcYNh0b.js → integrations-CH0zy1Mw2.js} +0 -0
  436. /package/client/dist/assets/{integrations-C1ThkTC52.js → integrations-CIAjhd7L.js} +0 -0
  437. /package/client/dist/assets/{integrations-2YcNyAl3.js → integrations-CZdwOe8A.js} +0 -0
  438. /package/client/dist/assets/{integrations-BXCvXUlG2.js → integrations-Ct7omMld.js} +0 -0
  439. /package/client/dist/assets/{integrations-Crk2rFhL2.js → integrations-D6MSxy3-.js} +0 -0
  440. /package/client/dist/assets/{integrations-Dn4JiGtW.js → integrations-DbZa-Zyc.js} +0 -0
  441. /package/client/dist/assets/{integrations-D9YrJ_Ep.js → integrations-b8pH-vfl2.js} +0 -0
  442. /package/client/dist/assets/{java-Dee-CNAM.js → java-BEtHBSE6.js} +0 -0
  443. /package/client/dist/assets/{jira-D5efgwp_.js → jira-BySfUuQZ.js} +0 -0
  444. /package/client/dist/assets/{jira-bDs7Im2C.js → jira-Byw2C0F8.js} +0 -0
  445. /package/client/dist/assets/{jira-BHAKtc4B.js → jira-CNeYi06w2.js} +0 -0
  446. /package/client/dist/assets/{jira-Be369RIR2.js → jira-D11gPhxz.js} +0 -0
  447. /package/client/dist/assets/{jira-CPpgA-5z2.js → jira-D38Gj7AT.js} +0 -0
  448. /package/client/dist/assets/{jira-uNH1gETL2.js → jira-gAvOyije.js} +0 -0
  449. /package/client/dist/assets/{jira-DS7ownDy.js → jira-pRaL7JQo2.js} +0 -0
  450. /package/client/dist/assets/{julia-CGNlLYuU.js → julia-Bri6UV-V.js} +0 -0
  451. /package/client/dist/assets/{kotlin-CY7lhknJ.js → kotlin-BOotOW0E.js} +0 -0
  452. /package/client/dist/assets/{less-D0KN7hfJ.js → less-B9JPFI3C.js} +0 -0
  453. /package/client/dist/assets/{lexon-CuRJufPs.js → lexon-CfSJPG6W.js} +0 -0
  454. /package/client/dist/assets/{loops-LIgO_-eM.js → loops-CPpgMapU.js} +0 -0
  455. /package/client/dist/assets/{loops-DJNhp17p2.js → loops-CWWbKuVL.js} +0 -0
  456. /package/client/dist/assets/{loops-D6D3XHjj.js → loops-Crc9It8o2.js} +0 -0
  457. /package/client/dist/assets/{loops-CvOWsi5r.js → loops-DH2hZcbK2.js} +0 -0
  458. /package/client/dist/assets/{loops-vhJdbcz92.js → loops-DS5TmvIU2.js} +0 -0
  459. /package/client/dist/assets/{loops-K5_HXfJa.js → loops-P2f0cN8-.js} +0 -0
  460. /package/client/dist/assets/{loops-BvqQ-bHR2.js → loops-fJV-9hH7.js} +0 -0
  461. /package/client/dist/assets/{lua-DHvH62Zf.js → lua-CsQS60Ue.js} +0 -0
  462. /package/client/dist/assets/{m3-tlthQ8Fo.js → m3-D-oSqn_W.js} +0 -0
  463. /package/client/dist/assets/{markdown-Dbx1LgUZ.js → markdown-Cimd5fb3.js} +0 -0
  464. /package/client/dist/assets/{mcp-Dcl-XxkR.js → mcp-Czd_iyp02.js} +0 -0
  465. /package/client/dist/assets/{mcp-XJNRfxVp2.js → mcp-D2pc5GGx.js} +0 -0
  466. /package/client/dist/assets/{mcp-sRmWE8WJ.js → mcp-D4ZjtIx32.js} +0 -0
  467. /package/client/dist/assets/{mcp-DtbxuH3V2.js → mcp-DIfBUv2D2.js} +0 -0
  468. /package/client/dist/assets/{mcp-H-gnQUdN.js → mcp-DsTwmjST.js} +0 -0
  469. /package/client/dist/assets/{mcp-N1nzp8oL.js → mcp-SMkn8boG.js} +0 -0
  470. /package/client/dist/assets/{mcp-CjVKXAhD2.js → mcp-fSfiVYAc.js} +0 -0
  471. /package/client/dist/assets/{mips-D_O3IUz_.js → mips-CIPQ_RoX.js} +0 -0
  472. /package/client/dist/assets/{msdax-C_ZmCnRt.js → msdax-DauUninz.js} +0 -0
  473. /package/client/dist/assets/{mysql-C-dCEYSX.js → mysql-SOo6toE5.js} +0 -0
  474. /package/client/dist/assets/{nav-BElxljIF2.js → nav-BRJBxaGt2.js} +0 -0
  475. /package/client/dist/assets/{nav-COu2E_-L.js → nav-CAGKv3_F.js} +0 -0
  476. /package/client/dist/assets/{nav-BXO7PJJG2.js → nav-CNskRJKQ2.js} +0 -0
  477. /package/client/dist/assets/{nav-CW9pxWfC2.js → nav-DY93irBL.js} +0 -0
  478. /package/client/dist/assets/{nav-CXHUA4uf.js → nav-DhjvYgqt.js} +0 -0
  479. /package/client/dist/assets/{nav-DdHF5VWJ.js → nav-Gb-r4wop.js} +0 -0
  480. /package/client/dist/assets/{nav-C8kOuGh8.js → nav-TvumAFD22.js} +0 -0
  481. /package/client/dist/assets/{objective-c-DZY9Aqxd.js → objective-c-FvmIjYaQ.js} +0 -0
  482. /package/client/dist/assets/{pascal-BVHLXoor.js → pascal-DrH0SRf2.js} +0 -0
  483. /package/client/dist/assets/{pascaligo-XdG_6u3k.js → pascaligo-D-ptJ9y-.js} +0 -0
  484. /package/client/dist/assets/{perl-b9QV0BcD.js → perl-oz_6vUea.js} +0 -0
  485. /package/client/dist/assets/{pgsql-Du5FDOgT.js → pgsql-DTj74zXo.js} +0 -0
  486. /package/client/dist/assets/{php-WJD0z2Z_.js → php-nr791fC2.js} +0 -0
  487. /package/client/dist/assets/{pla-CbciTf2w.js → pla-CopQ2nXW.js} +0 -0
  488. /package/client/dist/assets/{postiats-C1QxmvVq.js → postiats-43DmfD33.js} +0 -0
  489. /package/client/dist/assets/{powerquery-BEYDhPLZ.js → powerquery-D3hlyOfw.js} +0 -0
  490. /package/client/dist/assets/{powershell-CfaYw4XL.js → powershell-DmHpPYUd.js} +0 -0
  491. /package/client/dist/assets/{protobuf-pwZEDOYa.js → protobuf-C531GsRP.js} +0 -0
  492. /package/client/dist/assets/{pug-5ftqSPVe.js → pug-Z5eAx3Zn.js} +0 -0
  493. /package/client/dist/assets/{qsharp-uI6qZMq4.js → qsharp-DkqhCAOL.js} +0 -0
  494. /package/client/dist/assets/{r-BK54P1EG.js → r-BwWrilGY.js} +0 -0
  495. /package/client/dist/assets/{redis-DI0yd7kN.js → redis-ClamHrr6.js} +0 -0
  496. /package/client/dist/assets/{redshift-Dov26eyI.js → redshift-DT7zqm-g.js} +0 -0
  497. /package/client/dist/assets/{restructuredtext-QqJ_1dC-.js → restructuredtext-BYgofb2h.js} +0 -0
  498. /package/client/dist/assets/{ruby-5WjveeVb.js → ruby-DezsRK8O.js} +0 -0
  499. /package/client/dist/assets/{rust-BzVSfqFH.js → rust-DdL9SqIa.js} +0 -0
  500. /package/client/dist/assets/{sb-DMIUfT-3.js → sb-CcwsVR0C.js} +0 -0
  501. /package/client/dist/assets/{scala-CSKA7lqt.js → scala-DHpiXF5c.js} +0 -0
  502. /package/client/dist/assets/{scheme-CojOP2Qc.js → scheme-BeGwcela.js} +0 -0
  503. /package/client/dist/assets/{scss-DoBZGJG6.js → scss-gp-XZpBa.js} +0 -0
  504. /package/client/dist/assets/{settings-1w1O5Og82.js → settings-B9ilOSYO.js} +0 -0
  505. /package/client/dist/assets/{settings-Jc46vUhd.js → settings-BqlWHRHA.js} +0 -0
  506. /package/client/dist/assets/{settings-BSihkr0e.js → settings-D8dlqt4d.js} +0 -0
  507. /package/client/dist/assets/{settings-BiDOB3hV2.js → settings-DAZqjX2a2.js} +0 -0
  508. /package/client/dist/assets/{settings-DNL68KTE.js → settings-DRh39v1S2.js} +0 -0
  509. /package/client/dist/assets/{settings-BoubJhDP2.js → settings-Mj1OJbfd2.js} +0 -0
  510. /package/client/dist/assets/{settings-CB-EZ_W8.js → settings-lRReaSYm.js} +0 -0
  511. /package/client/dist/assets/{setup-D84y3wx-.js → setup-CGZjy2IF2.js} +0 -0
  512. /package/client/dist/assets/{setup-BuQNKztt2.js → setup-CXa0Sx16.js} +0 -0
  513. /package/client/dist/assets/{setup-BwMovM9z2.js → setup-D2ktKKMF2.js} +0 -0
  514. /package/client/dist/assets/{setup-DU0ULX8q2.js → setup-DG2H7ha5.js} +0 -0
  515. /package/client/dist/assets/{setup-BXpw07r-.js → setup-DK5bHDUq2.js} +0 -0
  516. /package/client/dist/assets/{setup-7J8TjG4O.js → setup-DrWlIQTZ.js} +0 -0
  517. /package/client/dist/assets/{setup-BiduSX9d.js → setup-rzHUVgAu.js} +0 -0
  518. /package/client/dist/assets/{shell-YOaE4udl.js → shell-CC2rA5mh.js} +0 -0
  519. /package/client/dist/assets/{solidity-l3jSyVLu.js → solidity-BEEn4gHE.js} +0 -0
  520. /package/client/dist/assets/{sophia-BhSGTaQJ.js → sophia-CRfGWb83.js} +0 -0
  521. /package/client/dist/assets/{sparql-qhk6QD9w.js → sparql-D_Lu-MrJ.js} +0 -0
  522. /package/client/dist/assets/{specs-CWtKcVDC.js → specs-BcyxaCwf2.js} +0 -0
  523. /package/client/dist/assets/{specs-DTplt2XM.js → specs-C1q9geAi.js} +0 -0
  524. /package/client/dist/assets/{specs-PozUNhqb.js → specs-CLZKysq-2.js} +0 -0
  525. /package/client/dist/assets/{specs-C9Sd7BhH2.js → specs-DZMS9o54.js} +0 -0
  526. /package/client/dist/assets/{specs-D2clrt2c2.js → specs-Dm6zUI-R.js} +0 -0
  527. /package/client/dist/assets/{specs-CBDvEYKv.js → specs-V3TvhKLX.js} +0 -0
  528. /package/client/dist/assets/{specs-CIPr9reA2.js → specs-dV3Mq5Mu2.js} +0 -0
  529. /package/client/dist/assets/{sql-DoO3y21-.js → sql-NEE52Syq.js} +0 -0
  530. /package/client/dist/assets/{st-ChZAY8oG.js → st-DbInun42.js} +0 -0
  531. /package/client/dist/assets/{swift-D290Tr7_.js → swift-Bxkupp3x.js} +0 -0
  532. /package/client/dist/assets/{systemverilog-DsxzgJ-o.js → systemverilog-Bz4Y3fRF.js} +0 -0
  533. /package/client/dist/assets/{tcl-BKDUHAAR.js → tcl-DISqw1ZD.js} +0 -0
  534. /package/client/dist/assets/{terminal-De2Brd23.js → terminal-BZiIu3rf.js} +0 -0
  535. /package/client/dist/assets/{terminal-cqfd3EDV.js → terminal-C2NAd7BW2.js} +0 -0
  536. /package/client/dist/assets/{terminal-WSAvHXoU.js → terminal-IahE4LW92.js} +0 -0
  537. /package/client/dist/assets/{terminal-Z7KsDM_n.js → terminal-QpXZU2Bn2.js} +0 -0
  538. /package/client/dist/assets/{terminal-xGbCZJHg.js → terminal-ScjyXNxQ.js} +0 -0
  539. /package/client/dist/assets/{terminal-BRm03iFA2.js → terminal-d7GadXbN.js} +0 -0
  540. /package/client/dist/assets/{terminal-DxQWCqSD2.js → terminal-tITa81iz.js} +0 -0
  541. /package/client/dist/assets/{twig-UpZQaM8G.js → twig-De2hgUGE.js} +0 -0
  542. /package/client/dist/assets/{typespec-DzaKvN8i.js → typespec-B8J7ngcE.js} +0 -0
  543. /package/client/dist/assets/{vb-CZpbb7tk.js → vb-DV3o63ZY.js} +0 -0
  544. /package/client/dist/assets/{wgsl-CNt3OIvl.js → wgsl-DpFanUEy.js} +0 -0
@@ -1,10 +1,14 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.AgentChatManager = void 0;
4
7
  exports.sanitizeAgentTitle = sanitizeAgentTitle;
5
8
  const crypto_1 = require("crypto");
6
9
  const readline_1 = require("readline");
7
10
  const os_1 = require("os");
11
+ const tree_kill_1 = __importDefault(require("tree-kill"));
8
12
  const providers_1 = require("./providers");
9
13
  const spawn_lifecycle_1 = require("./spawn-lifecycle");
10
14
  const cli_prompt_1 = require("./util/cli-prompt");
@@ -14,11 +18,11 @@ const agent_cwd_manager_1 = require("./agent-cwd-manager");
14
18
  const agent_operator_prompt_1 = require("./agent-operator-prompt");
15
19
  const agent_mcp_config_1 = require("./agent-mcp-config");
16
20
  const agent_tier_1 = require("./agent-tier");
21
+ const agent_capability_1 = require("./mcp/agent-capability");
17
22
  const attachment_manager_1 = require("./attachment-manager");
18
23
  const agent_context_resolver_1 = require("./agent-context-resolver");
19
24
  const agent_store_1 = require("./agent-store");
20
25
  const explore_draft_title_1 = require("./explore-draft-title");
21
- const types_1 = require("./mcp/tools/types");
22
26
  class AgentChatManager {
23
27
  _broadcast;
24
28
  _db;
@@ -39,19 +43,89 @@ class AgentChatManager {
39
43
  * shutdown() can tree-kill them instead of orphaning them. Self-removed on
40
44
  * 'close'/'error'. */
41
45
  _auxProcesses = new Set();
46
+ _auxReaders = new Map();
47
+ _terminationTimers = new Map();
48
+ /** Permanent lifecycle gate: the app DB may be closed immediately after
49
+ * shutdown, so no delayed turn/title/card callback may touch it afterwards. */
50
+ _disposed = false;
51
+ _resolveDisposed;
52
+ _disposedSignal = new Promise((resolve) => {
53
+ this._resolveDisposed = resolve;
54
+ });
42
55
  constructor(broadcast, db, port, registry) {
43
56
  this._broadcast = broadcast;
44
57
  this._db = db;
45
58
  this._port = port;
46
59
  this._registry = registry ?? null;
47
60
  }
61
+ async _awaitWhileLive(work) {
62
+ if (this._disposed)
63
+ return { disposed: true };
64
+ return Promise.race([
65
+ work.then((value) => ({ disposed: false, value })),
66
+ this._disposedSignal.then(() => ({ disposed: true })),
67
+ ]);
68
+ }
69
+ /** Own a dedicated POSIX process group so descendants remain killable after
70
+ * the root CLI exits. Windows tree termination is provided by taskkill /T /F. */
71
+ _spawnOwned(binary, args, options = {}) {
72
+ if (process.platform === 'win32')
73
+ return (0, cli_prompt_1.spawnAiCli)(binary, args, options);
74
+ return (0, cli_prompt_1.spawnAiCli)(binary, args, { ...options, detached: true });
75
+ }
76
+ _terminate(child) {
77
+ if (this._terminationTimers.has(child))
78
+ return;
79
+ try {
80
+ if (!child.pid) {
81
+ child.kill('SIGTERM');
82
+ return;
83
+ }
84
+ const pid = child.pid;
85
+ (0, tree_kill_1.default)(pid, 'SIGTERM');
86
+ const timer = setTimeout(() => {
87
+ this._terminationTimers.delete(child);
88
+ if (process.platform !== 'win32') {
89
+ try {
90
+ process.kill(-pid, 'SIGKILL');
91
+ }
92
+ catch { /* group already gone */ }
93
+ }
94
+ else {
95
+ try {
96
+ (0, tree_kill_1.default)(pid, 'SIGKILL', () => { });
97
+ }
98
+ catch { /* gone */ }
99
+ }
100
+ }, 2000);
101
+ timer.unref?.();
102
+ this._terminationTimers.set(child, timer);
103
+ }
104
+ catch {
105
+ /* already gone */
106
+ }
107
+ }
108
+ _closeChildIo(child) {
109
+ try {
110
+ child.stdin?.destroy();
111
+ }
112
+ catch { /* best-effort */ }
113
+ try {
114
+ child.stdout?.destroy();
115
+ }
116
+ catch { /* best-effort */ }
117
+ try {
118
+ child.stderr?.destroy();
119
+ }
120
+ catch { /* best-effort */ }
121
+ }
48
122
  /** True while a turn is streaming for this conversation. */
49
123
  isStreaming(conversationId) {
50
- return this._active.has(conversationId);
124
+ return !this._disposed && this._active.has(conversationId);
51
125
  }
52
126
  /** True while a turn is in flight (spawned or reserved) — a send now queues. */
53
127
  isBusy(conversationId) {
54
- return this._active.has(conversationId) || this._reserved.has(conversationId);
128
+ return !this._disposed && (this._active.has(conversationId) || this._reserved.has(conversationId));
55
129
  }
56
130
  /**
57
131
  * Runs one agent turn: persists the user message, spawns the AI CLI pointed at
@@ -64,6 +138,8 @@ class AgentChatManager {
64
138
  * Queued turns drain FIFO after the current turn settles; abort discards them.
65
139
  */
66
140
  async sendMessage(conversationId, userText, options = {}) {
141
+ if (this._disposed)
142
+ return;
67
143
  const conversation = (0, agent_store_1.getAgentConversation)(this._db, conversationId);
68
144
  if (!conversation) {
69
145
  this._emitError(conversationId, 'Unknown conversation');
@@ -91,6 +167,8 @@ class AgentChatManager {
91
167
  // Drain messages queued while we were running. Each drained turn re-reads
92
168
  // the conversation row so a mid-flight tier/provider/model change applies.
93
169
  for (;;) {
170
+ if (this._disposed)
171
+ break;
94
172
  const pending = this._queue.get(conversationId);
95
173
  const next = pending?.shift();
96
174
  if (!next)
@@ -100,6 +178,8 @@ class AgentChatManager {
100
178
  const conv = (0, agent_store_1.getAgentConversation)(this._db, conversationId);
101
179
  if (!conv)
102
180
  break; // deleted mid-drain (abort() already cleared the queue)
181
+ if (this._disposed)
182
+ break;
103
183
  this._broadcast({
104
184
  type: 'agent_dequeued',
105
185
  conversationId,
@@ -123,11 +203,15 @@ class AgentChatManager {
123
203
  await this._runTurn(conversation, userText, options);
124
204
  }
125
205
  catch (err) {
206
+ if (this._disposed)
207
+ return;
126
208
  console.error(`[agent-chat] turn failed (${conversation.id}):`, err);
127
209
  this._emitError(conversation.id, err instanceof Error ? err.message : 'The agent turn failed.');
128
210
  }
129
211
  }
130
212
  async _runTurn(conversation, userText, options) {
213
+ if (this._disposed)
214
+ return;
131
215
  const conversationId = conversation.id;
132
216
  const tierLevel = (0, agent_tier_1.normalizeLevel)(options.tierLevel ?? conversation.tier_level);
133
217
  const adapter = (0, providers_1.getAdapter)(conversation.provider);
@@ -146,10 +230,6 @@ class AgentChatManager {
146
230
  const reasoningEffort = efforts.length
147
231
  ? (storedEffort && efforts.includes(storedEffort) ? storedEffort : 'medium')
148
232
  : undefined;
149
- // Make the pinned project (Cursor-style selector) the MCP active project for
150
- // this turn, so project-scoped tools resolve without the agent having to call
151
- // specrails_select_project. Home (null) clears it → app-global mode.
152
- (0, types_1.setActiveProject)(conversation.pinned_project_id ?? null);
153
233
  // Resolve attachments (conversation-keyed) into extracted text blocks +
154
234
  // absolute image paths. Extraction failure degrades to a text-only turn.
155
235
  const attachmentIds = options.attachmentIds ?? [];
@@ -158,7 +238,10 @@ class AgentChatManager {
158
238
  let hasAttachments = false;
159
239
  if (attachmentIds.length > 0) {
160
240
  try {
161
- const resolved = await attachment_manager_1.attachmentManager.getClaudeArgsAgent(conversationId, attachmentIds);
241
+ const attachmentResult = await this._awaitWhileLive(attachment_manager_1.attachmentManager.getClaudeArgsAgent(conversationId, attachmentIds));
242
+ if (attachmentResult.disposed)
243
+ return;
244
+ const resolved = attachmentResult.value;
162
245
  if (resolved.textBlocks.length > 0) {
163
246
  userWithAttachments = `${userText}\n\n## Attached Resources\n\n${resolved.textBlocks.join('\n\n')}`;
164
247
  hasAttachments = true;
@@ -166,9 +249,13 @@ class AgentChatManager {
166
249
  imagePaths = resolved.imagePaths;
167
250
  }
168
251
  catch (err) {
252
+ if (this._disposed)
253
+ return;
169
254
  console.error(`[agent-chat] attachment extraction failed (${conversationId}):`, err);
170
255
  }
171
256
  }
257
+ if (this._disposed)
258
+ return;
172
259
  const contextBlock = (0, agent_context_resolver_1.buildResolvedAgentContextBlock)(options.contextRefs ?? [], {
173
260
  desktopDb: this._db,
174
261
  registry: this._registry,
@@ -202,142 +289,169 @@ class AgentChatManager {
202
289
  // Only pass native image paths to providers that can vision-load them (codex
203
290
  // `--image`); claude/gemini already have the `@path` ref folded into prompt.
204
291
  const spawnImagePaths = adapter.capabilities.supportsImageInput ? imagePaths : undefined;
205
- const cwd = (0, agent_cwd_manager_1.ensureAgentCwd)();
206
- let mcpArgs = [];
207
- let mcpEnv = {};
292
+ const agentCapability = (0, agent_capability_1.mintAgentCapability)({
293
+ conversationId,
294
+ projectId: conversation.pinned_project_id,
295
+ tierLevel,
296
+ });
208
297
  try {
209
- const wiring = (0, agent_mcp_config_1.prepareAgentMcp)({
210
- adapterId: adapter.id,
211
- conversationId,
212
- cwd,
213
- port: this._port,
214
- tierLevel,
215
- activeProjectId: conversation.pinned_project_id,
216
- });
217
- mcpArgs = wiring.extraArgs;
218
- mcpEnv = wiring.env;
219
- }
220
- catch (err) {
221
- // A bad conversation id or fs failure shouldn't poison the chat — run tool-less.
222
- console.error('[agent-chat] failed to prepare mcp:', err);
223
- }
224
- const timestamp = () => new Date().toISOString();
225
- const invoke = async (useResume) => {
226
- const action = useResume ? 'chat-resume' : 'chat-turn';
227
- const startedAt = new Date().toISOString();
228
- let streamed = '';
229
- let capturedSessionId = useResume ? conversation.session_id ?? null : null;
230
- let capturedError = null;
231
- console.log(`[agent-chat] turn start conv=${conversationId} provider=${adapter.id} binary=${adapter.binary} ` +
232
- `action=${action} model=${model} cwd=${cwd} mcp=${mcpArgs.length ? 'mcp-config' : Object.keys(mcpEnv).join(',') || 'none'}`);
233
- const result = await (0, spawn_lifecycle_1.runAiCliInvocation)({
234
- adapter,
235
- action,
236
- cwd,
237
- env: { ...process.env, ...mcpEnv },
238
- buildOpts: {
239
- prompt,
240
- systemPrompt: adapter.capabilities.systemPromptArg ? systemPrompt : undefined,
241
- model,
242
- sessionId: useResume ? conversation.session_id ?? undefined : undefined,
243
- extraArgs: mcpArgs,
244
- imagePaths: spawnImagePaths,
245
- reasoning_effort: reasoningEffort,
246
- },
247
- onSpawn: (child) => {
248
- this._active.set(conversationId, child);
249
- },
250
- onEvent: (ev) => {
251
- switch (ev.kind) {
252
- case 'text-delta':
253
- streamed += ev.text;
254
- // A killed child (abort / conversation DELETE) keeps flushing its
255
- // buffered stdout — suppress the broadcasts once it left _active
256
- // so stragglers can't resurrect client-side streaming state.
257
- if (this._active.has(conversationId)) {
258
- this._broadcast({ type: 'agent_stream', conversationId, delta: ev.text, timestamp: timestamp() });
259
- }
260
- break;
261
- case 'tool-use':
262
- if (this._active.has(conversationId)) {
263
- this._broadcast({ type: 'agent_tool', conversationId, tool: ev.name, timestamp: timestamp() });
264
- }
265
- break;
266
- case 'session-started':
267
- if (ev.sessionId)
268
- capturedSessionId = ev.sessionId;
269
- break;
270
- case 'result': {
271
- const sid = ev.payload.session_id;
272
- if (sid)
273
- capturedSessionId = sid;
274
- break;
275
- }
276
- case 'error':
277
- capturedError = ev.message;
278
- break;
279
- case 'other':
280
- break;
281
- }
282
- },
283
- });
284
- this._active.delete(conversationId);
285
- const text = streamed.trim();
286
- console.log(`[agent-chat] turn end conv=${conversationId} provider=${adapter.id} code=${result.code} ` +
287
- `spawnFailed=${result.spawnFailed} chars=${text.length} err=${capturedError ?? ''}`);
288
- if (result.stderrTail && (result.spawnFailed || (result.code ?? 0) !== 0 || !text)) {
289
- console.error(`[agent-chat] ${adapter.id} stderr:\n${result.stderrTail}`);
290
- }
291
- return { text, sessionId: capturedSessionId, error: capturedError, code: result.code, spawnFailed: result.spawnFailed, stderrTail: result.stderrTail, events: result.events, startedAt };
292
- };
293
- // Conversation CONFIG (provider/model/tier) is owned by the PATCH route —
294
- // never write turn-START snapshots back at settle, or a mid-turn provider
295
- // switch would be silently reverted and a queued turn drained onto the old
296
- // provider. Only the session id persists, and only while the row's provider
297
- // is still the one this turn actually ran on (a foreign session id must not
298
- // pollute the new provider's freshly-reset state).
299
- const persistSession = (sessionId) => {
300
- const fresh = (0, agent_store_1.getAgentConversation)(this._db, conversationId);
301
- if (fresh && fresh.provider === conversation.provider) {
302
- (0, agent_store_1.updateAgentConversation)(this._db, conversationId, { session_id: sessionId });
298
+ // Gemini discovers MCP registration from project files under cwd. A
299
+ // shared cwd would let two concurrent conversations race on `.mcp.json`
300
+ // / `.gemini/settings.json` and launch with the other's capability.
301
+ // Claude and Codex keep their historical global cwd and explicit MCP
302
+ // registration mechanisms unchanged.
303
+ const cwd = adapter.id === 'gemini'
304
+ ? (0, agent_cwd_manager_1.ensureAgentConversationCwd)(conversationId)
305
+ : (0, agent_cwd_manager_1.ensureAgentCwd)();
306
+ let mcpArgs = [];
307
+ let mcpEnv = {};
308
+ try {
309
+ const wiring = (0, agent_mcp_config_1.prepareAgentMcp)({
310
+ adapterId: adapter.id,
311
+ conversationId,
312
+ cwd,
313
+ port: this._port,
314
+ capability: agentCapability,
315
+ });
316
+ mcpArgs = wiring.extraArgs;
317
+ mcpEnv = wiring.env;
303
318
  }
304
- };
305
- const settleAborted = (r) => {
306
- // Deliberate user Stop: keep any partial text (it was already streamed to
307
- // the client), never auto-heal, never surface an error.
308
- if (r.text && (0, agent_store_1.getAgentConversation)(this._db, conversationId)) {
309
- (0, agent_store_1.addAgentMessage)(this._db, { conversationId, role: 'assistant', content: r.text });
310
- persistSession(r.sessionId);
311
- this._broadcast({ type: 'agent_done', conversationId, fullText: r.text, timestamp: timestamp() });
319
+ catch (err) {
320
+ // A bad conversation id or fs failure shouldn't poison the chat — run tool-less.
321
+ console.error('[agent-chat] failed to prepare mcp:', err);
312
322
  }
313
- };
314
- // Cost accounting (HIGH-3): exactly one row per settled turn, whichever
315
- // terminal branch we exit through. `pinned_project_id` is captured at turn
316
- // start (NULL = Home / app-global).
317
- const record = (outcome, status) => {
318
- this._recordTurn(conversation, adapter, model, outcome, status);
319
- };
320
- const canResume = !!conversation.session_id && adapter.capabilities.nativeResume;
321
- let r = await invoke(canResume);
322
- // Deleted mid-turn (DELETE aborts the child and drops the row): stop here —
323
- // no auto-heal respawn, no FK-violating assistant INSERT. The spawn still
324
- // billed, so record it (aborted) before returning.
325
- if (!(0, agent_store_1.getAgentConversation)(this._db, conversationId)) {
326
- record(r, 'aborted');
327
- return;
328
- }
329
- if (this._abortedTurns.delete(conversationId)) {
330
- settleAborted(r);
331
- record(r, 'aborted');
332
- return;
333
- }
334
- // Auto-heal a stale/foreign session: a resume that produced no text (e.g. a
335
- // provider switch leaving another provider's session id, or codex
336
- // "no rollout found for thread id") retries once as a fresh turn.
337
- if (canResume && !r.spawnFailed && !r.text) {
338
- console.log(`[agent-chat] resume produced no text — retrying fresh conv=${conversationId}`);
339
- (0, agent_store_1.updateAgentConversation)(this._db, conversationId, { session_id: null });
340
- r = await invoke(false);
323
+ const timestamp = () => new Date().toISOString();
324
+ const invoke = async (useResume) => {
325
+ const action = useResume ? 'chat-resume' : 'chat-turn';
326
+ const startedAt = new Date().toISOString();
327
+ let streamed = '';
328
+ let capturedSessionId = useResume ? conversation.session_id ?? null : null;
329
+ let capturedError = null;
330
+ console.log(`[agent-chat] turn start conv=${conversationId} provider=${adapter.id} binary=${adapter.binary} ` +
331
+ `action=${action} model=${model} cwd=${cwd} mcp=${mcpArgs.length ? 'mcp-config' : Object.keys(mcpEnv).join(',') || 'none'}`);
332
+ const invocation = this._awaitWhileLive((0, spawn_lifecycle_1.runAiCliInvocation)({
333
+ adapter,
334
+ action,
335
+ cwd,
336
+ env: { ...process.env, ...mcpEnv },
337
+ spawn: this._spawnOwned.bind(this),
338
+ buildOpts: {
339
+ prompt,
340
+ systemPrompt: adapter.capabilities.systemPromptArg ? systemPrompt : undefined,
341
+ model,
342
+ sessionId: useResume ? conversation.session_id ?? undefined : undefined,
343
+ extraArgs: mcpArgs,
344
+ imagePaths: spawnImagePaths,
345
+ reasoning_effort: reasoningEffort,
346
+ },
347
+ onSpawn: (child) => {
348
+ if (this._disposed) {
349
+ this._terminate(child);
350
+ return;
351
+ }
352
+ this._active.set(conversationId, child);
353
+ },
354
+ onEvent: (ev) => {
355
+ if (this._disposed)
356
+ return;
357
+ switch (ev.kind) {
358
+ case 'text-delta':
359
+ streamed += ev.text;
360
+ // A killed child (abort / conversation DELETE) keeps flushing its
361
+ // buffered stdout — suppress the broadcasts once it left _active
362
+ // so stragglers can't resurrect client-side streaming state.
363
+ if (this._active.has(conversationId)) {
364
+ this._broadcast({ type: 'agent_stream', conversationId, delta: ev.text, timestamp: timestamp() });
365
+ }
366
+ break;
367
+ case 'tool-use':
368
+ if (this._active.has(conversationId)) {
369
+ this._broadcast({ type: 'agent_tool', conversationId, tool: ev.name, timestamp: timestamp() });
370
+ }
371
+ break;
372
+ case 'session-started':
373
+ if (ev.sessionId)
374
+ capturedSessionId = ev.sessionId;
375
+ break;
376
+ case 'result': {
377
+ const sid = ev.payload.session_id;
378
+ if (sid)
379
+ capturedSessionId = sid;
380
+ break;
381
+ }
382
+ case 'error':
383
+ capturedError = ev.message;
384
+ break;
385
+ case 'other':
386
+ break;
387
+ }
388
+ },
389
+ }));
390
+ const invocationResult = await invocation;
391
+ if (invocationResult.disposed) {
392
+ this._active.delete(conversationId);
393
+ return {
394
+ disposed: true,
395
+ text: '',
396
+ sessionId: capturedSessionId,
397
+ error: null,
398
+ code: null,
399
+ spawnFailed: false,
400
+ stderrTail: '',
401
+ events: [],
402
+ startedAt,
403
+ };
404
+ }
405
+ const result = invocationResult.value;
406
+ this._active.delete(conversationId);
407
+ const text = streamed.trim();
408
+ console.log(`[agent-chat] turn end conv=${conversationId} provider=${adapter.id} code=${result.code} ` +
409
+ `spawnFailed=${result.spawnFailed} chars=${text.length} err=${capturedError ?? ''}`);
410
+ if (result.stderrTail && (result.spawnFailed || (result.code ?? 0) !== 0 || !text)) {
411
+ console.error(`[agent-chat] ${adapter.id} stderr:\n${result.stderrTail}`);
412
+ }
413
+ return { disposed: false, text, sessionId: capturedSessionId, error: capturedError, code: result.code, spawnFailed: result.spawnFailed, stderrTail: result.stderrTail, events: result.events, startedAt };
414
+ };
415
+ // Conversation CONFIG (provider/model/tier) is owned by the PATCH route —
416
+ // never write turn-START snapshots back at settle, or a mid-turn provider
417
+ // switch would be silently reverted and a queued turn drained onto the old
418
+ // provider. Only the session id persists, and only while the row's provider
419
+ // is still the one this turn actually ran on (a foreign session id must not
420
+ // pollute the new provider's freshly-reset state).
421
+ const persistSession = (sessionId) => {
422
+ if (this._disposed)
423
+ return;
424
+ const fresh = (0, agent_store_1.getAgentConversation)(this._db, conversationId);
425
+ if (fresh && fresh.provider === conversation.provider) {
426
+ (0, agent_store_1.updateAgentConversation)(this._db, conversationId, { session_id: sessionId });
427
+ }
428
+ };
429
+ const settleAborted = (r) => {
430
+ if (this._disposed)
431
+ return;
432
+ // Deliberate user Stop: keep any partial text (it was already streamed to
433
+ // the client), never auto-heal, never surface an error.
434
+ if (r.text && (0, agent_store_1.getAgentConversation)(this._db, conversationId)) {
435
+ (0, agent_store_1.addAgentMessage)(this._db, { conversationId, role: 'assistant', content: r.text });
436
+ persistSession(r.sessionId);
437
+ this._broadcast({ type: 'agent_done', conversationId, fullText: r.text, timestamp: timestamp() });
438
+ }
439
+ };
440
+ // Cost accounting (HIGH-3): exactly one row per settled turn, whichever
441
+ // terminal branch we exit through. `pinned_project_id` is captured at turn
442
+ // start (NULL = Home / app-global).
443
+ const record = (outcome, status) => {
444
+ if (this._disposed || outcome.disposed)
445
+ return;
446
+ this._recordTurn(conversation, adapter, model, outcome, status);
447
+ };
448
+ const canResume = !!conversation.session_id && adapter.capabilities.nativeResume;
449
+ let r = await invoke(canResume);
450
+ if (this._disposed || r.disposed)
451
+ return;
452
+ // Deleted mid-turn (DELETE aborts the child and drops the row): stop here —
453
+ // no auto-heal respawn, no FK-violating assistant INSERT. The spawn still
454
+ // billed, so record it (aborted) before returning.
341
455
  if (!(0, agent_store_1.getAgentConversation)(this._db, conversationId)) {
342
456
  record(r, 'aborted');
343
457
  return;
@@ -347,31 +461,54 @@ class AgentChatManager {
347
461
  record(r, 'aborted');
348
462
  return;
349
463
  }
350
- }
351
- if (r.spawnFailed) {
352
- this._emitError(conversationId, `Failed to launch ${adapter.binary}. Is it installed and on PATH?`);
464
+ // Auto-heal a stale/foreign session: a resume that produced no text (e.g. a
465
+ // provider switch leaving another provider's session id, or codex
466
+ // "no rollout found for thread id") retries once as a fresh turn.
467
+ if (canResume && !r.spawnFailed && !r.text) {
468
+ console.log(`[agent-chat] resume produced no text — retrying fresh conv=${conversationId}`);
469
+ (0, agent_store_1.updateAgentConversation)(this._db, conversationId, { session_id: null });
470
+ r = await invoke(false);
471
+ if (this._disposed || r.disposed)
472
+ return;
473
+ if (!(0, agent_store_1.getAgentConversation)(this._db, conversationId)) {
474
+ record(r, 'aborted');
475
+ return;
476
+ }
477
+ if (this._abortedTurns.delete(conversationId)) {
478
+ settleAborted(r);
479
+ record(r, 'aborted');
480
+ return;
481
+ }
482
+ }
483
+ if (r.spawnFailed) {
484
+ this._emitError(conversationId, `Failed to launch ${adapter.binary}. Is it installed and on PATH?`);
485
+ record(r, 'failed');
486
+ return;
487
+ }
488
+ if (r.text) {
489
+ (0, agent_store_1.addAgentMessage)(this._db, { conversationId, role: 'assistant', content: r.text });
490
+ persistSession(r.sessionId);
491
+ this._broadcast({ type: 'agent_done', conversationId, fullText: r.text, timestamp: timestamp() });
492
+ record(r, 'success');
493
+ // AI title after the FIRST completed turn (industry standard — ChatGPT /
494
+ // Claude.ai), on the conversation's own provider. The deterministic title
495
+ // set at send stays the instant fallback; this upgrades it a moment later.
496
+ this._maybeAiTitle(conversation, userText, r.text);
497
+ return;
498
+ }
499
+ // Failure: reset the session so the NEXT turn starts fresh, and surface the
500
+ // real reason instead of silently doing nothing.
501
+ persistSession(null);
502
+ const reason = r.error ||
503
+ (r.stderrTail ? r.stderrTail.split('\n').filter(Boolean).slice(-3).join(' ').slice(0, 300) : '') ||
504
+ (r.code !== 0 ? `${adapter.binary} exited with code ${r.code}` : 'The agent returned no output.');
505
+ this._emitError(conversationId, reason);
353
506
  record(r, 'failed');
354
- return;
355
507
  }
356
- if (r.text) {
357
- (0, agent_store_1.addAgentMessage)(this._db, { conversationId, role: 'assistant', content: r.text });
358
- persistSession(r.sessionId);
359
- this._broadcast({ type: 'agent_done', conversationId, fullText: r.text, timestamp: timestamp() });
360
- record(r, 'success');
361
- // AI title after the FIRST completed turn (industry standard — ChatGPT /
362
- // Claude.ai), on the conversation's own provider. The deterministic title
363
- // set at send stays the instant fallback; this upgrades it a moment later.
364
- this._maybeAiTitle(conversation, userText, r.text);
365
- return;
508
+ finally {
509
+ (0, agent_capability_1.revokeAgentCapability)(agentCapability);
510
+ (0, agent_mcp_config_1.removeAgentCapabilityFile)(conversationId);
366
511
  }
367
- // Failure: reset the session so the NEXT turn starts fresh, and surface the
368
- // real reason instead of silently doing nothing.
369
- persistSession(null);
370
- const reason = r.error ||
371
- (r.stderrTail ? r.stderrTail.split('\n').filter(Boolean).slice(-3).join(' ').slice(0, 300) : '') ||
372
- (r.code !== 0 ? `${adapter.binary} exited with code ${r.code}` : 'The agent returned no output.');
373
- this._emitError(conversationId, reason);
374
- record(r, 'failed');
375
512
  }
376
513
  /**
377
514
  * Finalise one agent-chat turn's billable accounting (COST-ACCOUNTING-AUDIT
@@ -383,6 +520,8 @@ class AgentChatManager {
383
520
  * turns carry no projectId, so no per-project dashboard to invalidate).
384
521
  */
385
522
  _recordTurn(conversation, adapter, model, outcome, status) {
523
+ if (this._disposed)
524
+ return;
386
525
  try {
387
526
  const { result, estimated } = (0, result_event_1.finaliseInvocationResult)(adapter, outcome.events, {
388
527
  fallbackModel: model,
@@ -414,6 +553,8 @@ class AgentChatManager {
414
553
  * `agent_title` so the sidebar list updates live.
415
554
  */
416
555
  _autoTitle(conversationId, currentTitle) {
556
+ if (this._disposed)
557
+ return;
417
558
  try {
418
559
  const userMsgs = (0, agent_store_1.listAgentMessages)(this._db, conversationId).filter((m) => m.role === 'user');
419
560
  if (userMsgs.length === 0 || userMsgs.length > 2)
@@ -440,6 +581,8 @@ class AgentChatManager {
440
581
  * so the cheap spawn is skipped when it would be pointless.
441
582
  */
442
583
  _maybeAiTitle(conversation, firstUserMsg, firstResponse) {
584
+ if (this._disposed)
585
+ return;
443
586
  try {
444
587
  const conversationId = conversation.id;
445
588
  const assistantCount = (0, agent_store_1.listAgentMessages)(this._db, conversationId).filter((m) => m.role === 'assistant').length;
@@ -466,6 +609,8 @@ class AgentChatManager {
466
609
  * into the turn path — title generation failing must not surface an error.
467
610
  */
468
611
  _aiTitle(conversation, firstUserMsg, firstResponse) {
612
+ if (this._disposed)
613
+ return;
469
614
  try {
470
615
  const conversationId = conversation.id;
471
616
  const adapter = (0, providers_1.getAdapter)(conversation.provider);
@@ -474,7 +619,7 @@ class AgentChatManager {
474
619
  'Output ONLY the title text — no quotes, no punctuation, no markdown, no preamble.\n\n' +
475
620
  `User: ${firstUserMsg.slice(0, 240)}\nAssistant: ${firstResponse.slice(0, 320)}`;
476
621
  const args = adapter.buildArgs('auto-title', { prompt, model });
477
- const child = (0, cli_prompt_1.spawnAiCli)(adapter.binary, args, {
622
+ const child = this._spawnOwned(adapter.binary, args, {
478
623
  env: process.env,
479
624
  stdio: ['ignore', 'pipe', 'pipe'],
480
625
  cwd: (0, os_1.tmpdir)(),
@@ -484,7 +629,10 @@ class AgentChatManager {
484
629
  const events = [];
485
630
  const startedAt = new Date().toISOString();
486
631
  const reader = (0, readline_1.createInterface)({ input: child.stdout, crlfDelay: Infinity });
632
+ this._auxReaders.set(child, reader);
487
633
  reader.on('line', (line) => {
634
+ if (this._disposed)
635
+ return;
488
636
  const ev = adapter.parseStreamLine(line);
489
637
  if (!ev)
490
638
  return;
@@ -494,9 +642,21 @@ class AgentChatManager {
494
642
  });
495
643
  child.on('error', () => {
496
644
  this._auxProcesses.delete(child);
645
+ this._auxReaders.delete(child);
646
+ try {
647
+ reader.close();
648
+ }
649
+ catch { /* best-effort */ }
497
650
  });
498
651
  child.on('close', (code) => {
499
652
  this._auxProcesses.delete(child);
653
+ this._auxReaders.delete(child);
654
+ try {
655
+ reader.close();
656
+ }
657
+ catch { /* best-effort */ }
658
+ if (this._disposed)
659
+ return;
500
660
  const fresh = (0, agent_store_1.getAgentConversation)(this._db, conversationId);
501
661
  if (!fresh)
502
662
  return; // deleted mid-generation — FK-safe: skip record + update
@@ -529,6 +689,8 @@ class AgentChatManager {
529
689
  * NEVER throws — it runs inside rail settle paths.
530
690
  */
531
691
  postPrDecisionCard(conversationId, envelope) {
692
+ if (this._disposed)
693
+ return;
532
694
  try {
533
695
  if (!(0, agent_store_1.getAgentConversation)(this._db, conversationId)) {
534
696
  console.log(`[agent-chat] pr-decision card skipped — conversation gone (${conversationId})`);
@@ -549,6 +711,8 @@ class AgentChatManager {
549
711
  * conversation delete/restore). NEVER throws — it runs inside decision paths.
550
712
  */
551
713
  updatePrDecisionCard(conversationId, envelope) {
714
+ if (this._disposed)
715
+ return;
552
716
  try {
553
717
  const existing = (0, agent_store_1.findAgentSystemMessage)(this._db, conversationId, (content) => {
554
718
  try {
@@ -563,7 +727,14 @@ class AgentChatManager {
563
727
  this.postPrDecisionCard(conversationId, envelope);
564
728
  return;
565
729
  }
566
- (0, agent_store_1.updateAgentMessageContent)(this._db, existing.id, JSON.stringify(envelope));
730
+ const serialized = JSON.stringify(envelope);
731
+ // Startup recovery may inspect historical deliveries to heal a card that
732
+ // missed its terminal update. Identical projection is not new activity:
733
+ // avoid a redundant DB write and, crucially, do not broadcast an unread
734
+ // event for an old card on every app launch.
735
+ if (existing.content === serialized)
736
+ return;
737
+ (0, agent_store_1.updateAgentMessageContent)(this._db, existing.id, serialized);
567
738
  this._broadcastPrDecision(conversationId, envelope);
568
739
  }
569
740
  catch (err) {
@@ -586,6 +757,8 @@ class AgentChatManager {
586
757
  * Success broadcasts `agent_queue_edited` so every open window updates its chip.
587
758
  */
588
759
  editQueued(conversationId, queueId, text) {
760
+ if (this._disposed)
761
+ return false;
589
762
  const pending = this._queue.get(conversationId);
590
763
  const item = pending?.find((q) => q.queueId === queueId);
591
764
  if (!item)
@@ -606,18 +779,15 @@ class AgentChatManager {
606
779
  * and the settling turn is marked aborted so the stale-session auto-heal
607
780
  * can never resurrect the stopped prompt as a fresh spawn. */
608
781
  abort(conversationId) {
782
+ if (this._disposed)
783
+ return false;
609
784
  this._clearQueue(conversationId);
610
785
  if (this.isBusy(conversationId))
611
786
  this._abortedTurns.add(conversationId);
612
787
  const child = this._active.get(conversationId);
613
788
  if (!child)
614
789
  return false;
615
- try {
616
- child.kill('SIGTERM');
617
- }
618
- catch {
619
- /* ignore */
620
- }
790
+ this._terminate(child);
621
791
  this._active.delete(conversationId);
622
792
  return true;
623
793
  }
@@ -630,27 +800,36 @@ class AgentChatManager {
630
800
  }
631
801
  /** Kills all active turns (graceful shutdown). */
632
802
  async shutdown() {
803
+ if (this._disposed)
804
+ return;
805
+ this._disposed = true;
806
+ this._resolveDisposed();
633
807
  this._queue.clear();
808
+ this._reserved.clear();
809
+ this._abortedTurns.clear();
634
810
  for (const [, child] of this._active) {
635
- try {
636
- child.kill('SIGTERM');
637
- }
638
- catch {
639
- /* ignore */
640
- }
811
+ this._terminate(child);
812
+ // runAiCliInvocation owns readline listeners and an unbounded event
813
+ // accumulator. Cut the pipes now so an uncooperative child cannot keep
814
+ // feeding that detached invocation during the SIGTERM grace window.
815
+ this._closeChildIo(child);
641
816
  }
642
817
  this._active.clear();
643
818
  for (const child of this._auxProcesses) {
819
+ const reader = this._auxReaders.get(child);
644
820
  try {
645
- child.kill('SIGTERM');
646
- }
647
- catch {
648
- /* ignore */
821
+ reader?.close();
649
822
  }
823
+ catch { /* best-effort */ }
824
+ this._terminate(child);
825
+ this._closeChildIo(child);
650
826
  }
827
+ this._auxReaders.clear();
651
828
  this._auxProcesses.clear();
652
829
  }
653
830
  _emitError(conversationId, error) {
831
+ if (this._disposed)
832
+ return;
654
833
  this._broadcast({ type: 'agent_error', conversationId, error, timestamp: new Date().toISOString() });
655
834
  }
656
835
  }