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.
- package/client/dist/assets/ActivityFeedPage-ClpD5CFj.js +1 -0
- package/client/dist/assets/AgentBrowserCapture-CSPs9Ofc.js +1 -0
- package/client/dist/assets/AgentModeCodePane-DwcyklA5.js +2 -0
- package/client/dist/assets/AgentModeJobsPane-C69bqlMa.js +1 -0
- package/client/dist/assets/AgentsPage-pRiRr9-W.js +86 -0
- package/client/dist/assets/AnalyticsPage-C14exKsC.js +1 -0
- package/client/dist/assets/BarChart-nBOMNfiy.js +33 -0
- package/client/dist/assets/CodePage-CK76JKm9.js +2 -0
- package/client/dist/assets/DesktopAnalyticsPage-Cnv0f3XQ.js +1 -0
- package/client/dist/assets/DocsDialog-CHUm_Ym0.js +11 -0
- package/client/dist/assets/DocsPage-COI-oDok.js +11 -0
- package/client/dist/assets/ExportDropdown-BrtfWzEG.js +1 -0
- package/client/dist/assets/IntegrationsPage-Bs00_tl4.js +1 -0
- package/client/dist/assets/InteractiveJobComposer-CypM7R1F.js +19 -0
- package/client/dist/assets/JobDetailModal-B_W0H9dw.js +1 -0
- package/client/dist/assets/JobDetailPage-CeeXOoKS.js +1 -0
- package/client/dist/assets/JobsPage-CwhJG9jw.js +1 -0
- package/client/dist/assets/LoopBuilderPage-C51t1WOM.js +7 -0
- package/client/dist/assets/LoopPreviewModal-Y2HgtIJu.js +1 -0
- package/client/dist/assets/LoopsPage-Bvn1Kw5V.js +1 -0
- package/client/dist/assets/MinimizedChatsContext-DiFvZDPW.js +1 -0
- package/client/dist/assets/PluginsPage-BGPRJpdf.js +2 -0
- package/client/dist/assets/ProjectSettingsDialog-D_GTyGLc.js +1 -0
- package/client/dist/assets/TemplatePreviewModal-szwBhd7h.js +1 -0
- package/client/dist/assets/TicketDetailModal-9UEyK974.js +14 -0
- package/client/dist/assets/Trans-B_vKZ-Hb.js +1 -0
- package/client/dist/assets/activity-DiyjsgQV.js +1 -0
- package/client/dist/assets/addon-image-BRmmRHgQ.js +1 -0
- package/client/dist/assets/addon-ligatures-qIZUPvRV.js +2 -0
- package/client/dist/assets/{addon-webgl-DMbGeI_u.js → addon-webgl-C2d7lriQ.js} +3 -3
- package/client/dist/assets/addspec-Rw8uVBC1.js +1 -0
- package/client/dist/assets/agent-4rmXoo_p.js +1 -0
- package/client/dist/assets/agent-BxZuNGih.js +1 -0
- package/client/dist/assets/agent-C3uXOYv_.js +1 -0
- package/client/dist/assets/agent-CA8Y4wbw.js +1 -0
- package/client/dist/assets/agent-CASKrhG12.js +1 -0
- package/client/dist/assets/agent-Cv-jud5n2.js +1 -0
- package/client/dist/assets/agent-DitUxYh2.js +1 -0
- package/client/dist/assets/agent-Doow4X7o.js +1 -0
- package/client/dist/assets/agents-DhG7mg6-.js +1 -0
- package/client/dist/assets/agentstudio-BIUe1Im2.js +1 -0
- package/client/dist/assets/aiedit-iIjz2_Qk.js +1 -0
- package/client/dist/assets/analytics-DZ8Aoq3I.js +1 -0
- package/client/dist/assets/api-B2M7CtDw.js +1 -0
- package/client/dist/assets/arrow-left-CpIR4j7G.js +1 -0
- package/client/dist/assets/arrow-up-right-9DoMn7fD.js +1 -0
- package/client/dist/assets/attachments-B53PG733.js +1 -0
- package/client/dist/assets/brain-DI9lHkKY.js +1 -0
- package/client/dist/assets/browser-CXUcnTMI.js +1 -0
- package/client/dist/assets/button-BUIIBQPT.js +1 -0
- package/client/dist/assets/chat-BGD7MXAy.js +1 -0
- package/client/dist/assets/chevron-right-CViMxucY.js +1 -0
- package/client/dist/assets/chunk-KS7C4IRE-Cx5sqopX.js +3 -0
- package/client/dist/assets/circle-x-CMYsN4ZH.js +1 -0
- package/client/dist/assets/code-BDXEM4ml.js +1 -0
- package/client/dist/assets/commands-DyUZQ1FI.js +1 -0
- package/client/dist/assets/common-CD1QHriA2.js +1 -0
- package/client/dist/assets/common-CwwPaRxx.js +1 -0
- package/client/dist/assets/common-DVQuhs-m.js +1 -0
- package/client/dist/assets/common-Dg2jaX7d.js +1 -0
- package/client/dist/assets/common-DuBwj6tK.js +1 -0
- package/client/dist/assets/common-MRj9MHcc.js +1 -0
- package/client/dist/assets/common-O4ZpnMLp.js +1 -0
- package/client/dist/assets/common-fyeF0v7C2.js +1 -0
- package/client/dist/assets/createLucideIcon-Bjbbp_KS.js +1 -0
- package/client/dist/assets/{css.worker-Wv5dxAWO.js → css.worker-yKcq13f2.js} +13 -13
- package/client/dist/assets/{cssMode-DBHbkBvI.js → cssMode-BM4z9OX0.js} +1 -1
- package/client/dist/assets/dashboard-B_NkSHYm.js +1 -0
- package/client/dist/assets/dashboard-ClBb_3pq.js +1 -0
- package/client/dist/assets/dashboard-CpCmJvMB.js +1 -0
- package/client/dist/assets/dashboard-Czohu35O2.js +1 -0
- package/client/dist/assets/dashboard-DcjbD0UK.js +1 -0
- package/client/dist/assets/dashboard-Dvx5F3we.js +1 -0
- package/client/dist/assets/dashboard-R1bOPjBh2.js +1 -0
- package/client/dist/assets/dashboard-owcDucDi.js +1 -0
- package/client/dist/assets/dialog-CzIekCw0.js +45 -0
- package/client/dist/assets/dist-Cez5CRkX.js +1 -0
- package/client/dist/assets/dist-bVqfYmby.js +1 -0
- package/client/dist/assets/{dist-js-CgpP6tKI.js → dist-js-CcBCbb32.js} +1 -1
- package/client/dist/assets/{dist-js-DHiN-A_E.js → dist-js-VwztRkGj.js} +1 -1
- package/client/dist/assets/download-CFHyyHcw.js +1 -0
- package/client/dist/assets/editor.api2-4ndOupAA.js +872 -0
- package/client/dist/assets/{editor.main-C9J2ikJK.js → editor.main-DxrmGfoq.js} +2 -2
- package/client/dist/assets/editor.worker-tytyn86m.js +26 -0
- package/client/dist/assets/explore-DgBACn39.js +1 -0
- package/client/dist/assets/external-link-BcU5EWZp.js +1 -0
- package/client/dist/assets/file-text-CFT-xXKN.js +1 -0
- package/client/dist/assets/formatDistanceToNow-ByHIauTQ.js +1 -0
- package/client/dist/assets/{freemarker2-J5iIIIK-.js → freemarker2-CELlTDJ2.js} +1 -1
- package/client/dist/assets/getTimezoneOffsetInMilliseconds-BxHAksaU.js +1 -0
- package/client/dist/assets/git-branch-BRM0F5GN.js +1 -0
- package/client/dist/assets/{handlebars-DSw1l_tw.js → handlebars-NEjHJ7o_.js} +1 -1
- package/client/dist/assets/{html-h2-wE1Lj.js → html-CA10zN5A.js} +1 -1
- package/client/dist/assets/{html.worker-CQP8QQsS.js → html.worker-DSJ9zmd7.js} +12 -12
- package/client/dist/assets/{htmlMode-Cc_ij7lW.js → htmlMode-89rPYiyq.js} +1 -1
- package/client/dist/assets/i18n-CgaRxpII.js +2 -0
- package/client/dist/assets/index-BflYQpWm.css +2 -0
- package/client/dist/assets/index-C1_-BTXy.js +72 -0
- package/client/dist/assets/integrations-mB-7zoyT.js +1 -0
- package/client/dist/assets/{javascript-C1q3xv6N.js → javascript-B1gDmwzS.js} +1 -1
- package/client/dist/assets/jira-CmKWERE0.js +1 -0
- package/client/dist/assets/jira-api-BgFIr8eD.js +1 -0
- package/client/dist/assets/job-time-BCL7wee9.js +1 -0
- package/client/dist/assets/jobs-B-sDHEay2.js +1 -0
- package/client/dist/assets/jobs-BCtGfgUA.js +1 -0
- package/client/dist/assets/jobs-BHR_EnDI.js +1 -0
- package/client/dist/assets/jobs-BMbZJjJJ.js +1 -0
- package/client/dist/assets/jobs-CVFD8rar.js +1 -0
- package/client/dist/assets/jobs-DoSaFzAa.js +1 -0
- package/client/dist/assets/jobs-DzSIR8V62.js +1 -0
- package/client/dist/assets/jobs-lk1_Dq1U.js +1 -0
- package/client/dist/assets/json.worker-Oa9UrkKE.js +58 -0
- package/client/dist/assets/{jsonMode-CeaCdEhr.js → jsonMode-xHLMfzhF.js} +1 -1
- package/client/dist/assets/jsx-runtime-zu2_FqZY.js +1 -0
- package/client/dist/assets/lib-C7Mhm-gT.js +7 -0
- package/client/dist/assets/lib-CGdyxIWg.js +29 -0
- package/client/dist/assets/{liquid-eFsVK0V-.js → liquid-BY6hCUXG.js} +1 -1
- package/client/dist/assets/loader-circle-DcygOQpC.js +1 -0
- package/client/dist/assets/loops-BzfXWEwO.js +1 -0
- package/client/dist/assets/{lspLanguageFeatures-DT3-bbhn.js → lspLanguageFeatures-ira2aEJh.js} +1 -1
- package/client/dist/assets/mcp-uDkXYu4L.js +1 -0
- package/client/dist/assets/{mdx-Fuwnh1cX.js → mdx-BNx0xr3N.js} +1 -1
- package/client/dist/assets/monaco.contribution-Bt92R3Vw.js +2 -0
- package/client/dist/assets/nav-myFaXRHD.js +1 -0
- package/client/dist/assets/pencil-C9RkrIPZ.js +1 -0
- package/client/dist/assets/play-DNlrawbS.js +1 -0
- package/client/dist/assets/plus-CsnjfkmX.js +1 -0
- package/client/dist/assets/preload-helper-Czpn1I53.js +1 -0
- package/client/dist/assets/{python-BgoEs6Cj.js → python-DLdbtmNw.js} +1 -1
- package/client/dist/assets/{razor-CM1sPMMq.js → razor-B9gdhAbR.js} +1 -1
- package/client/dist/assets/react-dom-DiWzBDP9.js +1 -0
- package/client/dist/assets/rolldown-runtime-CNC7AqOf.js +1 -0
- package/client/dist/assets/save-28sIlCdr.js +1 -0
- package/client/dist/assets/search-Cq_gE3Ik.js +1 -0
- package/client/dist/assets/settings-B0ypw9uw.js +1 -0
- package/client/dist/assets/setup-CmK87LuS.js +1 -0
- package/client/dist/assets/sparkles-DrY8hb0X.js +1 -0
- package/client/dist/assets/specs-DII0C8gw.js +1 -0
- package/client/dist/assets/spending-C4p06nen.js +1 -0
- package/client/dist/assets/terminal-BFRZnMPP.js +1 -0
- package/client/dist/assets/tickets-B8BuAaj5.js +1 -0
- package/client/dist/assets/tickets-B_yh4qQk.js +1 -0
- package/client/dist/assets/tickets-Bs37scwY2.js +1 -0
- package/client/dist/assets/tickets-CFk2n2Or.js +1 -0
- package/client/dist/assets/tickets-DQp7JS2R2.js +1 -0
- package/client/dist/assets/tickets-D_yDquEw.js +1 -0
- package/client/dist/assets/tickets-DpmdE8tv2.js +1 -0
- package/client/dist/assets/tickets-pAUJkDTu.js +1 -0
- package/client/dist/assets/trash-2-BOU3WdZZ.js +1 -0
- package/client/dist/assets/triangle-alert-H9T4jAmh.js +1 -0
- package/client/dist/assets/{ts.worker-METxwbDZ.js → ts.worker-BtjBFNHX.js} +48 -33
- package/client/dist/assets/{tsMode-BmT8WogI.js → tsMode-DEjSThU9.js} +1 -1
- package/client/dist/assets/{typescript-CQrQPsoW.js → typescript-CRRnD2Ts.js} +1 -1
- package/client/dist/assets/upload-DYMjAQ6M.js +1 -0
- package/client/dist/assets/useBrowserCaptureSession-2OqX0vap.js +1 -0
- package/client/dist/assets/useDesktop-X8YB9xzv.js +1 -0
- package/client/dist/assets/useSharedWebSocket-DaPh7QBL.js +1 -0
- package/client/dist/assets/utils-BC4DHlz2.js +1 -0
- package/client/dist/assets/value-s-gzBeyF.js +1 -0
- package/client/dist/assets/{workers-U0UXyLUf.js → workers-uOo7WLaa.js} +1 -1
- package/client/dist/assets/x-CBMI9ejn.js +1 -0
- package/client/dist/assets/{xml-WRxJs8_I.js → xml-EDREH2X7.js} +1 -1
- package/client/dist/assets/{yaml-CjpSTjJU.js → yaml-BjaDVX1E.js} +1 -1
- package/client/dist/assets/zap-CHo3aCD1.js +1 -0
- package/client/dist/index.html +73 -32
- package/docs/guide/en/integrations/5-mcp-server.md +2 -2
- package/docs/internals/safe-pr-review-flow.md +190 -132
- package/docs/mcp.md +15 -5
- package/package.json +11 -7
- package/server/dist/active-pr-continuation.js +16 -1
- package/server/dist/agent-chat-manager.js +360 -181
- package/server/dist/agent-cwd-manager.js +52 -8
- package/server/dist/agent-generator.js +90 -48
- package/server/dist/agent-mcp-config.js +69 -36
- package/server/dist/agent-operator-prompt.js +3 -2
- package/server/dist/agent-refine-manager.js +47 -6
- package/server/dist/agent-tier.js +13 -11
- package/server/dist/artifact-registry.js +33 -2
- package/server/dist/auth.js +5 -4
- package/server/dist/browser-capture-manager.js +92 -29
- package/server/dist/chat-manager.js +302 -46
- package/server/dist/contract-refine-runner.js +19 -6
- package/server/dist/db.js +665 -8
- package/server/dist/desktop-router.js +1 -2
- package/server/dist/headroom-manager.js +1310 -121
- package/server/dist/headroom-routing.js +120 -2
- package/server/dist/index.js +48 -13
- package/server/dist/interactive-job-session.js +237 -82
- package/server/dist/jira/jira-adf.js +10 -0
- package/server/dist/jira/jira-db.js +15 -3
- package/server/dist/jira/jira-sync-manager.js +182 -13
- package/server/dist/job-listing.js +140 -0
- package/server/dist/job-spawn-idempotency.js +67 -0
- package/server/dist/loop-run-manager.js +508 -98
- package/server/dist/loop-runs-store.js +266 -13
- package/server/dist/mcp/agent-capability.js +71 -0
- package/server/dist/mcp/guide.js +5 -2
- package/server/dist/mcp/mcp-server.js +5 -10
- package/server/dist/mcp/mcp-token.js +5 -5
- package/server/dist/mcp/tools/jobs.js +20 -13
- package/server/dist/mcp/tools/types.js +20 -42
- package/server/dist/mobile/mobile-router.js +1 -1
- package/server/dist/pr-lifecycle.js +77 -0
- package/server/dist/pr-publisher.js +94 -27
- package/server/dist/process-admission.js +82 -0
- package/server/dist/project-registry.js +572 -174
- package/server/dist/project-router-git.js +13 -2
- package/server/dist/project-router-jobs.js +111 -55
- package/server/dist/project-router-tickets.js +32 -2
- package/server/dist/providers/claude-adapter.js +21 -13
- package/server/dist/queue-manager.js +2332 -623
- package/server/dist/rail-isolated-launch.js +1137 -290
- package/server/dist/rail-isolation.js +4 -2
- package/server/dist/rail-pr-decision.js +740 -266
- package/server/dist/rail-pr-delivery.js +2 -1
- package/server/dist/rail-pr-store.js +317 -18
- package/server/dist/rail-pr-ticket-effects.js +328 -0
- package/server/dist/rail-worktree-release.js +18 -2
- package/server/dist/rails-router.js +149 -119
- package/server/dist/rails-store.js +106 -3
- package/server/dist/ticket-store.js +23 -1
- package/server/dist/transient-children.js +13 -0
- package/server/dist/util/cli-prompt.js +42 -8
- package/server/dist/util/secure-token-file.js +84 -0
- package/server/dist/worktree-manager.js +6 -5
- package/client/dist/assets/ActivityFeedPage-D8RKRRoM.js +0 -1
- package/client/dist/assets/AgentBrowserCapture-BUHPHNSN.js +0 -1
- package/client/dist/assets/AgentModeCodePane-GZc8bNGT.js +0 -2
- package/client/dist/assets/AgentModeJobsPane-DWtQqj3k.js +0 -1
- package/client/dist/assets/AgentsPage-CKPtHkRP.js +0 -86
- package/client/dist/assets/AnalyticsPage-CZW8c77k.js +0 -1
- package/client/dist/assets/BarChart-DugEoe2q.js +0 -33
- package/client/dist/assets/CodePage-CQ-uKETG.js +0 -2
- package/client/dist/assets/DesktopAnalyticsPage-Bgo4SyCH.js +0 -1
- package/client/dist/assets/DocsDialog-DxpWw_La.js +0 -11
- package/client/dist/assets/DocsPage-CmcOkK19.js +0 -11
- package/client/dist/assets/ExportDropdown-DvTS2wc7.js +0 -1
- package/client/dist/assets/IntegrationsPage-B72WxJ3Z.js +0 -1
- package/client/dist/assets/InteractiveJobComposer-B5gh4Qoy.js +0 -19
- package/client/dist/assets/JobDetailModal-D-BeqsJ6.js +0 -1
- package/client/dist/assets/JobDetailPage-DwdozwLO.js +0 -1
- package/client/dist/assets/JobsPage-BDkinklt.js +0 -1
- package/client/dist/assets/LoopBuilderPage-CclJ3VZA.js +0 -7
- package/client/dist/assets/LoopPreviewModal-Dw4UgoLu.js +0 -1
- package/client/dist/assets/LoopsPage-D7ac4M24.js +0 -1
- package/client/dist/assets/PluginsPage-wdC-qa40.js +0 -2
- package/client/dist/assets/ProjectSettingsDialog-BlTlRtGI.js +0 -1
- package/client/dist/assets/TemplatePreviewModal-CeMx2Red.js +0 -1
- package/client/dist/assets/activity-Dbl71S-E.js +0 -1
- package/client/dist/assets/addon-image-CwoZj17F.js +0 -1
- package/client/dist/assets/addon-ligatures-CWDrED80.js +0 -2
- package/client/dist/assets/addspec-DrXqP8ip.js +0 -1
- package/client/dist/assets/agent-B8BXmlUQ2.js +0 -1
- package/client/dist/assets/agent-BEXYxDbs.js +0 -1
- package/client/dist/assets/agent-BYc3-6Ln2.js +0 -1
- package/client/dist/assets/agent-BbJorPdT.js +0 -1
- package/client/dist/assets/agent-CewFImgL.js +0 -1
- package/client/dist/assets/agent-DfhYoUmp.js +0 -1
- package/client/dist/assets/agent-TK_rrK4d.js +0 -1
- package/client/dist/assets/agent-bHjA9R_j2.js +0 -1
- package/client/dist/assets/agents-CGDn_3kB.js +0 -1
- package/client/dist/assets/agentstudio-Dxe_94PK.js +0 -1
- package/client/dist/assets/aiedit-DrfHQnlz.js +0 -1
- package/client/dist/assets/analytics-CxDYcBl9.js +0 -1
- package/client/dist/assets/attachments-DvxQbBTC.js +0 -1
- package/client/dist/assets/brain-C92rjjYP.js +0 -1
- package/client/dist/assets/browser-DM8G151q.js +0 -1
- package/client/dist/assets/chat-0dg5hOo_.js +0 -1
- package/client/dist/assets/chunk-BNv3lrIs.js +0 -1
- package/client/dist/assets/code-B62fClk-.js +0 -1
- package/client/dist/assets/commands-DCJ-R9E4.js +0 -1
- package/client/dist/assets/common-BM3LFLCE2.js +0 -1
- package/client/dist/assets/common-Bwafujnc2.js +0 -1
- package/client/dist/assets/common-C-vU-j-I.js +0 -1
- package/client/dist/assets/common-C5HKSbbz.js +0 -1
- package/client/dist/assets/common-DXrmj6WD.js +0 -1
- package/client/dist/assets/common-DhWTkocg.js +0 -1
- package/client/dist/assets/common-DiPTT7V_2.js +0 -1
- package/client/dist/assets/common-DmqBPwZG.js +0 -1
- package/client/dist/assets/dashboard-B5ang-ZS.js +0 -1
- package/client/dist/assets/dashboard-CHHcOWVL2.js +0 -1
- package/client/dist/assets/dashboard-DBD4wPGY2.js +0 -1
- package/client/dist/assets/dashboard-DBuLfWo9.js +0 -1
- package/client/dist/assets/dashboard-DSnztwWH.js +0 -1
- package/client/dist/assets/dashboard-D_aP_InU.js +0 -1
- package/client/dist/assets/dashboard-DmBcdl1B.js +0 -1
- package/client/dist/assets/dashboard-RIcUKY1Y2.js +0 -1
- package/client/dist/assets/editor.api2-C3B0tp2x.js +0 -872
- package/client/dist/assets/editor.worker-Bd9IXS8d.js +0 -26
- package/client/dist/assets/explore-_XyU5e7R.js +0 -1
- package/client/dist/assets/index-BVbgKXUu.css +0 -2
- package/client/dist/assets/index-DyY1QyIn.js +0 -158
- package/client/dist/assets/integrations-By80EBkf.js +0 -1
- package/client/dist/assets/jira-DeIjwCK3.js +0 -1
- package/client/dist/assets/jobs-1GV2-4zd2.js +0 -1
- package/client/dist/assets/jobs-26F9gGcE.js +0 -1
- package/client/dist/assets/jobs-BgQzB0Sx2.js +0 -1
- package/client/dist/assets/jobs-BqWui9_f.js +0 -1
- package/client/dist/assets/jobs-CE8qeIYj.js +0 -1
- package/client/dist/assets/jobs-DrYmsKy5.js +0 -1
- package/client/dist/assets/jobs-DzeuASRf.js +0 -1
- package/client/dist/assets/jobs-Wh7dn28q2.js +0 -1
- package/client/dist/assets/json.worker-DzV-CpCQ.js +0 -58
- package/client/dist/assets/lib-0PFDyMxJ.js +0 -7
- package/client/dist/assets/loops-CO6q75W8.js +0 -1
- package/client/dist/assets/mcp-HwBbQDk0.js +0 -1
- package/client/dist/assets/monaco.contribution-Desq7oq4.js +0 -2
- package/client/dist/assets/nav-BTg8s-cD.js +0 -1
- package/client/dist/assets/preload-helper-DSXbuxSR.js +0 -1
- package/client/dist/assets/settings-cJNynGIZ.js +0 -1
- package/client/dist/assets/setup-D2CmgAro.js +0 -1
- package/client/dist/assets/specs-PGIOzMtc.js +0 -1
- package/client/dist/assets/terminal-CFt56A5f.js +0 -1
- package/client/dist/assets/tickets-B7zT4IRf.js +0 -1
- package/client/dist/assets/tickets-BHv3ewvq.js +0 -1
- package/client/dist/assets/tickets-BoXom7l8.js +0 -1
- package/client/dist/assets/tickets-C3b8cHhd2.js +0 -1
- package/client/dist/assets/tickets-CFXnJsYF.js +0 -1
- package/client/dist/assets/tickets-CWYFvx1W2.js +0 -1
- package/client/dist/assets/tickets-DTHo9c3C.js +0 -1
- package/client/dist/assets/tickets-SuX_HkK4.js +0 -1
- package/client/dist/assets/upload-CmR4h9H1.js +0 -1
- package/client/dist/assets/value-JA3bf47v.js +0 -1
- /package/client/dist/assets/{abap-D0E4FfVW.js → abap-08VXUWAP.js} +0 -0
- /package/client/dist/assets/{activity--iN4Ad2R2.js → activity-B-rp4h_v.js} +0 -0
- /package/client/dist/assets/{activity-6hM_ZSg9.js → activity-C6kJpm9q2.js} +0 -0
- /package/client/dist/assets/{activity-CIOLxGvh.js → activity-CGx4kb_j.js} +0 -0
- /package/client/dist/assets/{activity-BZNfOdiS.js → activity-CnoX2bH7.js} +0 -0
- /package/client/dist/assets/{activity-BuVo5sPB.js → activity-DAyekdlt2.js} +0 -0
- /package/client/dist/assets/{activity-D2r2h3SE2.js → activity-DCxtpT7j.js} +0 -0
- /package/client/dist/assets/{activity-DtxrAUMo2.js → activity-JzwRaWPD.js} +0 -0
- /package/client/dist/assets/{addspec-BMtLZLW62.js → addspec-BXjvkh5q.js} +0 -0
- /package/client/dist/assets/{addspec-CRuvWn8d.js → addspec-C4bwrmpi.js} +0 -0
- /package/client/dist/assets/{addspec-D-JLDsUV.js → addspec-CArHXUDM.js} +0 -0
- /package/client/dist/assets/{addspec-mgPOt5q02.js → addspec-DTKJcXiR.js} +0 -0
- /package/client/dist/assets/{addspec-DfhDbg5c.js → addspec-DbNBbrha2.js} +0 -0
- /package/client/dist/assets/{addspec-CP0HRuxY.js → addspec-htHGZHOe2.js} +0 -0
- /package/client/dist/assets/{addspec-bsNDdqRm2.js → addspec-lr_LP6jk.js} +0 -0
- /package/client/dist/assets/{agents-78bTZGZh.js → agents-6ZOJXWVk2.js} +0 -0
- /package/client/dist/assets/{agents-DDtCJ5M02.js → agents-BZ0XQKjg.js} +0 -0
- /package/client/dist/assets/{agents-CWo-KyAB.js → agents-BqWklnHR.js} +0 -0
- /package/client/dist/assets/{agents-BUdEi3-N.js → agents-Bz-thHkB2.js} +0 -0
- /package/client/dist/assets/{agents-bvyRLczL.js → agents-CJclElx6.js} +0 -0
- /package/client/dist/assets/{agents-BpoUaoW92.js → agents-D_l9L0VA.js} +0 -0
- /package/client/dist/assets/{agents-BLhWCmDS2.js → agents-u_C0jPB5.js} +0 -0
- /package/client/dist/assets/{agentstudio-BMQxc_bz.js → agentstudio-BF19hbXj.js} +0 -0
- /package/client/dist/assets/{agentstudio-C_Jq8Tl4.js → agentstudio-BLGvxWBx2.js} +0 -0
- /package/client/dist/assets/{agentstudio-Dtq3dGYk.js → agentstudio-D9UKiWTj2.js} +0 -0
- /package/client/dist/assets/{agentstudio-CWgXG5W52.js → agentstudio-Drs37nIM.js} +0 -0
- /package/client/dist/assets/{agentstudio-sI27TpBu2.js → agentstudio-nEnKkcXM.js} +0 -0
- /package/client/dist/assets/{agentstudio-jKMTdT70.js → agentstudio-pyFcSBKy.js} +0 -0
- /package/client/dist/assets/{agentstudio-COZriimI2.js → agentstudio-zfTzQh3U.js} +0 -0
- /package/client/dist/assets/{aiedit-hknZlly82.js → aiedit-B0KUbpB6.js} +0 -0
- /package/client/dist/assets/{aiedit-eMN4eQPF.js → aiedit-BoG24nlg2.js} +0 -0
- /package/client/dist/assets/{aiedit-pc5JDUq1.js → aiedit-CjlSRQVP.js} +0 -0
- /package/client/dist/assets/{aiedit-B03pD_Na.js → aiedit-DCjA7jLJ.js} +0 -0
- /package/client/dist/assets/{aiedit-6CHdb_iv2.js → aiedit-DNXxq_Dr.js} +0 -0
- /package/client/dist/assets/{aiedit-igmw-ZoZ2.js → aiedit-DQ-0_pvE.js} +0 -0
- /package/client/dist/assets/{aiedit-BtRqRxML.js → aiedit-olnv3QSt2.js} +0 -0
- /package/client/dist/assets/{analytics-CCprAqk3.js → analytics-BC7mwR4s.js} +0 -0
- /package/client/dist/assets/{analytics-CR1TJqUi2.js → analytics-BiNg8edP.js} +0 -0
- /package/client/dist/assets/{analytics-Bj-SmKHa.js → analytics-C0s_T2GN.js} +0 -0
- /package/client/dist/assets/{analytics-C5dpiS0o.js → analytics-CdsAPAwZ2.js} +0 -0
- /package/client/dist/assets/{analytics-BWMUZ2Pq2.js → analytics-Cr1_q-lC.js} +0 -0
- /package/client/dist/assets/{analytics-DfNdXR0y2.js → analytics-IEsKZvpW2.js} +0 -0
- /package/client/dist/assets/{analytics-rmHuJv0V.js → analytics-SRPf84OT.js} +0 -0
- /package/client/dist/assets/{apex-D_X_8J4d.js → apex-BWPQTe0t.js} +0 -0
- /package/client/dist/assets/{atom-one-dark-BMDPFwRZ.js → atom-one-dark-qiGhVQxg.js} +0 -0
- /package/client/dist/assets/{attachments-BgBNSqQd.js → attachments-D0wXXt9T2.js} +0 -0
- /package/client/dist/assets/{attachments-C9GTTJsx2.js → attachments-DenIjuVI.js} +0 -0
- /package/client/dist/assets/{attachments-BjyMmrwE.js → attachments-DhO7LPfy.js} +0 -0
- /package/client/dist/assets/{attachments-DPCmkFZu2.js → attachments-DoH5w0x4.js} +0 -0
- /package/client/dist/assets/{attachments-DCZOL1RU.js → attachments-Q9yNtiEM.js} +0 -0
- /package/client/dist/assets/{attachments-rNn1ekRy2.js → attachments-V_WZAYXx2.js} +0 -0
- /package/client/dist/assets/{attachments-DL-bPy9E.js → attachments-eaeScpjM.js} +0 -0
- /package/client/dist/assets/{auth-DpZq5p1e.js → auth-D_5bQv5W.js} +0 -0
- /package/client/dist/assets/{azcli-PZLnZ3jH.js → azcli-Bc_sGQ0U.js} +0 -0
- /package/client/dist/assets/{bat-KlBOxpO4.js → bat-i0X4ZdIN.js} +0 -0
- /package/client/dist/assets/{bicep-CgG9oF3V.js → bicep-B5-_aFwp.js} +0 -0
- /package/client/dist/assets/{browser-BPkhILSJ.js → browser-C25DkQiO.js} +0 -0
- /package/client/dist/assets/{browser-BqLqJVVT.js → browser-CiJ7-L32.js} +0 -0
- /package/client/dist/assets/{browser-rWKj-RR_2.js → browser-CvgDySd9.js} +0 -0
- /package/client/dist/assets/{browser-Cvg-QHvd2.js → browser-CyR1Kp3m2.js} +0 -0
- /package/client/dist/assets/{browser-FRv8P02E.js → browser-DwZljcRh2.js} +0 -0
- /package/client/dist/assets/{browser-Cc0iDqUi.js → browser-DxP-alBK.js} +0 -0
- /package/client/dist/assets/{browser-BijVYG0Y2.js → browser-rRCwi7Y7.js} +0 -0
- /package/client/dist/assets/{cameligo-6R45j6Ph.js → cameligo-DMUM7wLl.js} +0 -0
- /package/client/dist/assets/{chat-Bom6bqK3.js → chat-2rIB8HhT.js} +0 -0
- /package/client/dist/assets/{chat-vylxqR0P2.js → chat-BR8oe53x2.js} +0 -0
- /package/client/dist/assets/{chat-Dnwg-NpQ.js → chat-Bua03tty.js} +0 -0
- /package/client/dist/assets/{chat-BgL3zv6x2.js → chat-CZpAQan1.js} +0 -0
- /package/client/dist/assets/{chat-DsbwJhus.js → chat-CdY5SGvS.js} +0 -0
- /package/client/dist/assets/{chat-Bh3NdgJs.js → chat-DZyu3ImY2.js} +0 -0
- /package/client/dist/assets/{chat-DdwZjT8K2.js → chat-D_I7nU5K.js} +0 -0
- /package/client/dist/assets/{clojure-CLAAMO7J.js → clojure-Cm7r79vr.js} +0 -0
- /package/client/dist/assets/{clsx-CNmW0Nip.js → clsx-CjueKrWZ.js} +0 -0
- /package/client/dist/assets/{code-UPVvmAKM2.js → code-76gS0IdL.js} +0 -0
- /package/client/dist/assets/{code-BRcDlze52.js → code-C1VwxlML.js} +0 -0
- /package/client/dist/assets/{code-CeQ0FZpC.js → code-CnMZyJpr.js} +0 -0
- /package/client/dist/assets/{code-DgeHz9CB.js → code-D20ef9Cf2.js} +0 -0
- /package/client/dist/assets/{code-DzC1rMk12.js → code-DdOXaWRY.js} +0 -0
- /package/client/dist/assets/{code-CwnBPPyA.js → code-Duohuf9l.js} +0 -0
- /package/client/dist/assets/{code-BdMy3Ffq.js → code-geHmknB92.js} +0 -0
- /package/client/dist/assets/{coffee-AruSygo-.js → coffee-Ba7i2nA0.js} +0 -0
- /package/client/dist/assets/{commands-DkU0qliq.js → commands-B9RZO4qS.js} +0 -0
- /package/client/dist/assets/{commands-u-4eEHCN.js → commands-BEwbAjtD2.js} +0 -0
- /package/client/dist/assets/{commands-JWMfGDmr.js → commands-Bbxu8kLU.js} +0 -0
- /package/client/dist/assets/{commands-C4Y3C-PF2.js → commands-CDU3qv68.js} +0 -0
- /package/client/dist/assets/{commands-xHDDGfcP2.js → commands-CzezgtQj.js} +0 -0
- /package/client/dist/assets/{commands-CSDs9q_2.js → commands-DTQBF_q52.js} +0 -0
- /package/client/dist/assets/{commands-RHOchN4n2.js → commands-hOtKuOXc.js} +0 -0
- /package/client/dist/assets/{cpp-DEE5r4Pw.js → cpp-C7h46wYY.js} +0 -0
- /package/client/dist/assets/{csharp-BVXJUvbK.js → csharp-BKxtCVv1.js} +0 -0
- /package/client/dist/assets/{csp-cXOF0JoV.js → csp-bTuwJoIa.js} +0 -0
- /package/client/dist/assets/{css-C_zQuAoy.js → css-DIMkf-bt.js} +0 -0
- /package/client/dist/assets/{cypher-t95m_Q-O.js → cypher-CVaqCwHa.js} +0 -0
- /package/client/dist/assets/{dart-B4r1Tg-e.js → dart-onAF5SnQ.js} +0 -0
- /package/client/dist/assets/{dockerfile-6mt7zHQw.js → dockerfile-DZFCIeNp.js} +0 -0
- /package/client/dist/assets/{ecl-DEY_Fz_Q.js → ecl-D05T4iGw.js} +0 -0
- /package/client/dist/assets/{elixir-R6-q1c5t.js → elixir-6RTg0lbw.js} +0 -0
- /package/client/dist/assets/{explore-B7fblXBb2.js → explore-BG99VGpL.js} +0 -0
- /package/client/dist/assets/{explore-CNBzrEPS.js → explore-C0TjprJW2.js} +0 -0
- /package/client/dist/assets/{explore-C0k8HrkN.js → explore-C2dgEo7q.js} +0 -0
- /package/client/dist/assets/{explore-BHtEpoNN2.js → explore-C8NDHbob.js} +0 -0
- /package/client/dist/assets/{explore-Dahc1lOx.js → explore-CWWgzQGR.js} +0 -0
- /package/client/dist/assets/{explore-D_mWBYCS2.js → explore-CcQXpdtS.js} +0 -0
- /package/client/dist/assets/{explore-UvW1jEMa.js → explore-DsXAgnmJ2.js} +0 -0
- /package/client/dist/assets/{flow9-CNQvHBOt.js → flow9-C5_-GSwl.js} +0 -0
- /package/client/dist/assets/{format-command-CuWuRvka.js → format-command-Dfa1o2d-.js} +0 -0
- /package/client/dist/assets/{fsharp-vPZkFXwv.js → fsharp-C8Ef5oNN.js} +0 -0
- /package/client/dist/assets/{go-KUzBMYJ_.js → go-C-y9NEjX.js} +0 -0
- /package/client/dist/assets/{graphql-C3W0rCsD.js → graphql-fmXr3nnJ.js} +0 -0
- /package/client/dist/assets/{hcl-BOOMFSNX.js → hcl-CpzslTdj.js} +0 -0
- /package/client/dist/assets/{ini-CFat1WJr.js → ini-sBoK_t0W.js} +0 -0
- /package/client/dist/assets/{integrations-TAcYNh0b.js → integrations-CH0zy1Mw2.js} +0 -0
- /package/client/dist/assets/{integrations-C1ThkTC52.js → integrations-CIAjhd7L.js} +0 -0
- /package/client/dist/assets/{integrations-2YcNyAl3.js → integrations-CZdwOe8A.js} +0 -0
- /package/client/dist/assets/{integrations-BXCvXUlG2.js → integrations-Ct7omMld.js} +0 -0
- /package/client/dist/assets/{integrations-Crk2rFhL2.js → integrations-D6MSxy3-.js} +0 -0
- /package/client/dist/assets/{integrations-Dn4JiGtW.js → integrations-DbZa-Zyc.js} +0 -0
- /package/client/dist/assets/{integrations-D9YrJ_Ep.js → integrations-b8pH-vfl2.js} +0 -0
- /package/client/dist/assets/{java-Dee-CNAM.js → java-BEtHBSE6.js} +0 -0
- /package/client/dist/assets/{jira-D5efgwp_.js → jira-BySfUuQZ.js} +0 -0
- /package/client/dist/assets/{jira-bDs7Im2C.js → jira-Byw2C0F8.js} +0 -0
- /package/client/dist/assets/{jira-BHAKtc4B.js → jira-CNeYi06w2.js} +0 -0
- /package/client/dist/assets/{jira-Be369RIR2.js → jira-D11gPhxz.js} +0 -0
- /package/client/dist/assets/{jira-CPpgA-5z2.js → jira-D38Gj7AT.js} +0 -0
- /package/client/dist/assets/{jira-uNH1gETL2.js → jira-gAvOyije.js} +0 -0
- /package/client/dist/assets/{jira-DS7ownDy.js → jira-pRaL7JQo2.js} +0 -0
- /package/client/dist/assets/{julia-CGNlLYuU.js → julia-Bri6UV-V.js} +0 -0
- /package/client/dist/assets/{kotlin-CY7lhknJ.js → kotlin-BOotOW0E.js} +0 -0
- /package/client/dist/assets/{less-D0KN7hfJ.js → less-B9JPFI3C.js} +0 -0
- /package/client/dist/assets/{lexon-CuRJufPs.js → lexon-CfSJPG6W.js} +0 -0
- /package/client/dist/assets/{loops-LIgO_-eM.js → loops-CPpgMapU.js} +0 -0
- /package/client/dist/assets/{loops-DJNhp17p2.js → loops-CWWbKuVL.js} +0 -0
- /package/client/dist/assets/{loops-D6D3XHjj.js → loops-Crc9It8o2.js} +0 -0
- /package/client/dist/assets/{loops-CvOWsi5r.js → loops-DH2hZcbK2.js} +0 -0
- /package/client/dist/assets/{loops-vhJdbcz92.js → loops-DS5TmvIU2.js} +0 -0
- /package/client/dist/assets/{loops-K5_HXfJa.js → loops-P2f0cN8-.js} +0 -0
- /package/client/dist/assets/{loops-BvqQ-bHR2.js → loops-fJV-9hH7.js} +0 -0
- /package/client/dist/assets/{lua-DHvH62Zf.js → lua-CsQS60Ue.js} +0 -0
- /package/client/dist/assets/{m3-tlthQ8Fo.js → m3-D-oSqn_W.js} +0 -0
- /package/client/dist/assets/{markdown-Dbx1LgUZ.js → markdown-Cimd5fb3.js} +0 -0
- /package/client/dist/assets/{mcp-Dcl-XxkR.js → mcp-Czd_iyp02.js} +0 -0
- /package/client/dist/assets/{mcp-XJNRfxVp2.js → mcp-D2pc5GGx.js} +0 -0
- /package/client/dist/assets/{mcp-sRmWE8WJ.js → mcp-D4ZjtIx32.js} +0 -0
- /package/client/dist/assets/{mcp-DtbxuH3V2.js → mcp-DIfBUv2D2.js} +0 -0
- /package/client/dist/assets/{mcp-H-gnQUdN.js → mcp-DsTwmjST.js} +0 -0
- /package/client/dist/assets/{mcp-N1nzp8oL.js → mcp-SMkn8boG.js} +0 -0
- /package/client/dist/assets/{mcp-CjVKXAhD2.js → mcp-fSfiVYAc.js} +0 -0
- /package/client/dist/assets/{mips-D_O3IUz_.js → mips-CIPQ_RoX.js} +0 -0
- /package/client/dist/assets/{msdax-C_ZmCnRt.js → msdax-DauUninz.js} +0 -0
- /package/client/dist/assets/{mysql-C-dCEYSX.js → mysql-SOo6toE5.js} +0 -0
- /package/client/dist/assets/{nav-BElxljIF2.js → nav-BRJBxaGt2.js} +0 -0
- /package/client/dist/assets/{nav-COu2E_-L.js → nav-CAGKv3_F.js} +0 -0
- /package/client/dist/assets/{nav-BXO7PJJG2.js → nav-CNskRJKQ2.js} +0 -0
- /package/client/dist/assets/{nav-CW9pxWfC2.js → nav-DY93irBL.js} +0 -0
- /package/client/dist/assets/{nav-CXHUA4uf.js → nav-DhjvYgqt.js} +0 -0
- /package/client/dist/assets/{nav-DdHF5VWJ.js → nav-Gb-r4wop.js} +0 -0
- /package/client/dist/assets/{nav-C8kOuGh8.js → nav-TvumAFD22.js} +0 -0
- /package/client/dist/assets/{objective-c-DZY9Aqxd.js → objective-c-FvmIjYaQ.js} +0 -0
- /package/client/dist/assets/{pascal-BVHLXoor.js → pascal-DrH0SRf2.js} +0 -0
- /package/client/dist/assets/{pascaligo-XdG_6u3k.js → pascaligo-D-ptJ9y-.js} +0 -0
- /package/client/dist/assets/{perl-b9QV0BcD.js → perl-oz_6vUea.js} +0 -0
- /package/client/dist/assets/{pgsql-Du5FDOgT.js → pgsql-DTj74zXo.js} +0 -0
- /package/client/dist/assets/{php-WJD0z2Z_.js → php-nr791fC2.js} +0 -0
- /package/client/dist/assets/{pla-CbciTf2w.js → pla-CopQ2nXW.js} +0 -0
- /package/client/dist/assets/{postiats-C1QxmvVq.js → postiats-43DmfD33.js} +0 -0
- /package/client/dist/assets/{powerquery-BEYDhPLZ.js → powerquery-D3hlyOfw.js} +0 -0
- /package/client/dist/assets/{powershell-CfaYw4XL.js → powershell-DmHpPYUd.js} +0 -0
- /package/client/dist/assets/{protobuf-pwZEDOYa.js → protobuf-C531GsRP.js} +0 -0
- /package/client/dist/assets/{pug-5ftqSPVe.js → pug-Z5eAx3Zn.js} +0 -0
- /package/client/dist/assets/{qsharp-uI6qZMq4.js → qsharp-DkqhCAOL.js} +0 -0
- /package/client/dist/assets/{r-BK54P1EG.js → r-BwWrilGY.js} +0 -0
- /package/client/dist/assets/{redis-DI0yd7kN.js → redis-ClamHrr6.js} +0 -0
- /package/client/dist/assets/{redshift-Dov26eyI.js → redshift-DT7zqm-g.js} +0 -0
- /package/client/dist/assets/{restructuredtext-QqJ_1dC-.js → restructuredtext-BYgofb2h.js} +0 -0
- /package/client/dist/assets/{ruby-5WjveeVb.js → ruby-DezsRK8O.js} +0 -0
- /package/client/dist/assets/{rust-BzVSfqFH.js → rust-DdL9SqIa.js} +0 -0
- /package/client/dist/assets/{sb-DMIUfT-3.js → sb-CcwsVR0C.js} +0 -0
- /package/client/dist/assets/{scala-CSKA7lqt.js → scala-DHpiXF5c.js} +0 -0
- /package/client/dist/assets/{scheme-CojOP2Qc.js → scheme-BeGwcela.js} +0 -0
- /package/client/dist/assets/{scss-DoBZGJG6.js → scss-gp-XZpBa.js} +0 -0
- /package/client/dist/assets/{settings-1w1O5Og82.js → settings-B9ilOSYO.js} +0 -0
- /package/client/dist/assets/{settings-Jc46vUhd.js → settings-BqlWHRHA.js} +0 -0
- /package/client/dist/assets/{settings-BSihkr0e.js → settings-D8dlqt4d.js} +0 -0
- /package/client/dist/assets/{settings-BiDOB3hV2.js → settings-DAZqjX2a2.js} +0 -0
- /package/client/dist/assets/{settings-DNL68KTE.js → settings-DRh39v1S2.js} +0 -0
- /package/client/dist/assets/{settings-BoubJhDP2.js → settings-Mj1OJbfd2.js} +0 -0
- /package/client/dist/assets/{settings-CB-EZ_W8.js → settings-lRReaSYm.js} +0 -0
- /package/client/dist/assets/{setup-D84y3wx-.js → setup-CGZjy2IF2.js} +0 -0
- /package/client/dist/assets/{setup-BuQNKztt2.js → setup-CXa0Sx16.js} +0 -0
- /package/client/dist/assets/{setup-BwMovM9z2.js → setup-D2ktKKMF2.js} +0 -0
- /package/client/dist/assets/{setup-DU0ULX8q2.js → setup-DG2H7ha5.js} +0 -0
- /package/client/dist/assets/{setup-BXpw07r-.js → setup-DK5bHDUq2.js} +0 -0
- /package/client/dist/assets/{setup-7J8TjG4O.js → setup-DrWlIQTZ.js} +0 -0
- /package/client/dist/assets/{setup-BiduSX9d.js → setup-rzHUVgAu.js} +0 -0
- /package/client/dist/assets/{shell-YOaE4udl.js → shell-CC2rA5mh.js} +0 -0
- /package/client/dist/assets/{solidity-l3jSyVLu.js → solidity-BEEn4gHE.js} +0 -0
- /package/client/dist/assets/{sophia-BhSGTaQJ.js → sophia-CRfGWb83.js} +0 -0
- /package/client/dist/assets/{sparql-qhk6QD9w.js → sparql-D_Lu-MrJ.js} +0 -0
- /package/client/dist/assets/{specs-CWtKcVDC.js → specs-BcyxaCwf2.js} +0 -0
- /package/client/dist/assets/{specs-DTplt2XM.js → specs-C1q9geAi.js} +0 -0
- /package/client/dist/assets/{specs-PozUNhqb.js → specs-CLZKysq-2.js} +0 -0
- /package/client/dist/assets/{specs-C9Sd7BhH2.js → specs-DZMS9o54.js} +0 -0
- /package/client/dist/assets/{specs-D2clrt2c2.js → specs-Dm6zUI-R.js} +0 -0
- /package/client/dist/assets/{specs-CBDvEYKv.js → specs-V3TvhKLX.js} +0 -0
- /package/client/dist/assets/{specs-CIPr9reA2.js → specs-dV3Mq5Mu2.js} +0 -0
- /package/client/dist/assets/{sql-DoO3y21-.js → sql-NEE52Syq.js} +0 -0
- /package/client/dist/assets/{st-ChZAY8oG.js → st-DbInun42.js} +0 -0
- /package/client/dist/assets/{swift-D290Tr7_.js → swift-Bxkupp3x.js} +0 -0
- /package/client/dist/assets/{systemverilog-DsxzgJ-o.js → systemverilog-Bz4Y3fRF.js} +0 -0
- /package/client/dist/assets/{tcl-BKDUHAAR.js → tcl-DISqw1ZD.js} +0 -0
- /package/client/dist/assets/{terminal-De2Brd23.js → terminal-BZiIu3rf.js} +0 -0
- /package/client/dist/assets/{terminal-cqfd3EDV.js → terminal-C2NAd7BW2.js} +0 -0
- /package/client/dist/assets/{terminal-WSAvHXoU.js → terminal-IahE4LW92.js} +0 -0
- /package/client/dist/assets/{terminal-Z7KsDM_n.js → terminal-QpXZU2Bn2.js} +0 -0
- /package/client/dist/assets/{terminal-xGbCZJHg.js → terminal-ScjyXNxQ.js} +0 -0
- /package/client/dist/assets/{terminal-BRm03iFA2.js → terminal-d7GadXbN.js} +0 -0
- /package/client/dist/assets/{terminal-DxQWCqSD2.js → terminal-tITa81iz.js} +0 -0
- /package/client/dist/assets/{twig-UpZQaM8G.js → twig-De2hgUGE.js} +0 -0
- /package/client/dist/assets/{typespec-DzaKvN8i.js → typespec-B8J7ngcE.js} +0 -0
- /package/client/dist/assets/{vb-CZpbb7tk.js → vb-DV3o63ZY.js} +0 -0
- /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
|
|
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
|
|
206
|
-
|
|
207
|
-
|
|
292
|
+
const agentCapability = (0, agent_capability_1.mintAgentCapability)({
|
|
293
|
+
conversationId,
|
|
294
|
+
projectId: conversation.pinned_project_id,
|
|
295
|
+
tierLevel,
|
|
296
|
+
});
|
|
208
297
|
try {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
mcpArgs =
|
|
218
|
-
mcpEnv =
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|
-
|
|
306
|
-
|
|
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
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
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
|
-
|
|
352
|
-
|
|
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
|
-
|
|
357
|
-
(0,
|
|
358
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
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
|
-
|
|
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
|
}
|