specrails-desktop 2.29.0 → 2.29.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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-UjXbEWhN.js → dist-js-CcBCbb32.js} +1 -1
- package/client/dist/assets/{dist-js-BTAcxhPb.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/{settings-Bp24JHlv2.js → settings-B9ilOSYO.js} +1 -1
- package/client/dist/assets/{settings-Bx2ObkTR2.js → settings-BqlWHRHA.js} +1 -1
- package/client/dist/assets/{settings-C_T0-j9d.js → settings-D8dlqt4d.js} +1 -1
- package/client/dist/assets/{settings-DhaFKpcw2.js → settings-DAZqjX2a2.js} +1 -1
- package/client/dist/assets/{settings-B_v3zgJf.js → settings-DRh39v1S2.js} +1 -1
- package/client/dist/assets/{settings-BemR_e3F.js → settings-Mj1OJbfd2.js} +1 -1
- package/client/dist/assets/{settings-BvIwQ3A1.js → settings-lRReaSYm.js} +1 -1
- 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 +1141 -280
- package/server/dist/rail-isolation.js +4 -2
- package/server/dist/rail-pr-decision.js +756 -270
- 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 +28 -6
- package/server/dist/rails-router.js +149 -112
- 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 +70 -21
- package/client/dist/assets/ActivityFeedPage-Be-6L0Ld.js +0 -1
- package/client/dist/assets/AgentBrowserCapture-CpZ-dd8O.js +0 -1
- package/client/dist/assets/AgentIntegrationsModal-DO1pN_Ez.js +0 -1
- package/client/dist/assets/AgentModeCodePane-DLltTOqp.js +0 -2
- package/client/dist/assets/AgentModeJobsPane-Dp5YvmW0.js +0 -1
- package/client/dist/assets/AgentsPage-ehHuVUds.js +0 -86
- package/client/dist/assets/AnalyticsPage-C4Ik95FX.js +0 -1
- package/client/dist/assets/BarChart-DVZgrhJd.js +0 -33
- package/client/dist/assets/CodePage-D4OCMfxL.js +0 -2
- package/client/dist/assets/DesktopAnalyticsPage-2Xf-52x2.js +0 -1
- package/client/dist/assets/DocsDialog-CHihLjWd.js +0 -11
- package/client/dist/assets/DocsPage-1vEk7XbH.js +0 -11
- package/client/dist/assets/ExportDropdown-DLHFQxVn.js +0 -1
- package/client/dist/assets/IntegrationsPage-CCb2YuyJ.js +0 -1
- package/client/dist/assets/InteractiveJobComposer-CxJJEnjw.js +0 -19
- package/client/dist/assets/JobDetailModal-CJI7qRkm.js +0 -1
- package/client/dist/assets/JobDetailPage-DwA9bbwx.js +0 -1
- package/client/dist/assets/JobsPage-BDIyFfd5.js +0 -1
- package/client/dist/assets/LoopBuilderPage-CpBaW59t.js +0 -7
- package/client/dist/assets/LoopPreviewModal-CwpKcv0Y.js +0 -1
- package/client/dist/assets/LoopsPage-BO0Pa8oz.js +0 -1
- package/client/dist/assets/PluginsPage-BBGTBpGh.js +0 -2
- package/client/dist/assets/ProjectSettingsDialog-M9zGQo0l.js +0 -1
- package/client/dist/assets/TemplatePreviewModal-eBI0zL5P.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-BEXYxDbs.js +0 -1
- package/client/dist/assets/agent-BoXSzaBk2.js +0 -1
- package/client/dist/assets/agent-C2-rROL52.js +0 -1
- package/client/dist/assets/agent-CeRTdGT12.js +0 -1
- package/client/dist/assets/agent-DZ8zTrQT.js +0 -1
- package/client/dist/assets/agent-DqyzT33X.js +0 -1
- package/client/dist/assets/agent-fQI_6tsA.js +0 -1
- package/client/dist/assets/agent-tJdAobaM.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-DecvjjPU.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-BfQD173j.js +0 -1
- package/client/dist/assets/common-CF8iGXrG.js +0 -1
- package/client/dist/assets/common-Cfmwcrl52.js +0 -1
- package/client/dist/assets/common-D2cimsul.js +0 -1
- package/client/dist/assets/common-DH7fjyL1.js +0 -1
- package/client/dist/assets/common-DXrmj6WD.js +0 -1
- package/client/dist/assets/common-DZbXlmq72.js +0 -1
- package/client/dist/assets/common-DtXmzX2o2.js +0 -1
- package/client/dist/assets/dashboard-5C2FOZQX.js +0 -1
- package/client/dist/assets/dashboard-B6iQ-IL_.js +0 -1
- package/client/dist/assets/dashboard-BFfnCtq52.js +0 -1
- package/client/dist/assets/dashboard-BIC8KtRf2.js +0 -1
- package/client/dist/assets/dashboard-CEgg9NAr.js +0 -1
- package/client/dist/assets/dashboard-CiOyDh9L.js +0 -1
- package/client/dist/assets/dashboard-D6x5OnNj2.js +0 -1
- package/client/dist/assets/dashboard-DBuLfWo9.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-OBDI7bHm.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-BFIdeDTw.js +0 -1
- package/client/dist/assets/jobs-BJ-Gcao22.js +0 -1
- package/client/dist/assets/jobs-DAGiPVIS2.js +0 -1
- package/client/dist/assets/jobs-DAU8C_tZ.js +0 -1
- package/client/dist/assets/jobs-Da0GaaSc.js +0 -1
- package/client/dist/assets/jobs-DrYmsKy5.js +0 -1
- package/client/dist/assets/jobs-P3unxtxo2.js +0 -1
- package/client/dist/assets/jobs-p360zdf1.js +0 -1
- package/client/dist/assets/json.worker-DzV-CpCQ.js +0 -58
- package/client/dist/assets/lib-C5ZxrPSR.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-BYCMtxOz.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-BHv3ewvq.js +0 -1
- package/client/dist/assets/tickets-BIxU86j12.js +0 -1
- package/client/dist/assets/tickets-C2BhwzwR.js +0 -1
- package/client/dist/assets/tickets-D1IeX2EW.js +0 -1
- package/client/dist/assets/tickets-DZut8Ryt.js +0 -1
- package/client/dist/assets/tickets-LfK6LzKl2.js +0 -1
- package/client/dist/assets/tickets-dQfsc7Ph.js +0 -1
- package/client/dist/assets/tickets-sVun0I6v.js +0 -1
- package/client/dist/assets/upload-lgjKJgrl.js +0 -1
- package/client/dist/assets/value-Bc0_jlJA.js +0 -1
- /package/client/dist/assets/{abap-D0E4FfVW.js → abap-08VXUWAP.js} +0 -0
- /package/client/dist/assets/{activity-BbWiDfn-2.js → activity-B-rp4h_v.js} +0 -0
- /package/client/dist/assets/{activity-DvECTYGt.js → activity-C6kJpm9q2.js} +0 -0
- /package/client/dist/assets/{activity-D3Ic-HTS.js → activity-CGx4kb_j.js} +0 -0
- /package/client/dist/assets/{activity-BZZlEG3a.js → activity-CnoX2bH7.js} +0 -0
- /package/client/dist/assets/{activity-DtzRy92x.js → activity-DAyekdlt2.js} +0 -0
- /package/client/dist/assets/{activity-FleOlK0l2.js → activity-DCxtpT7j.js} +0 -0
- /package/client/dist/assets/{activity-DFbvNqhE2.js → activity-JzwRaWPD.js} +0 -0
- /package/client/dist/assets/{addspec-CFxGvmJR2.js → addspec-BXjvkh5q.js} +0 -0
- /package/client/dist/assets/{addspec-NBbcTbLc.js → addspec-C4bwrmpi.js} +0 -0
- /package/client/dist/assets/{addspec-BKrH2Ucz.js → addspec-CArHXUDM.js} +0 -0
- /package/client/dist/assets/{addspec-CR8MB5Fr2.js → addspec-DTKJcXiR.js} +0 -0
- /package/client/dist/assets/{addspec-B_LQMHW3.js → addspec-DbNBbrha2.js} +0 -0
- /package/client/dist/assets/{addspec-DaA-CbTt.js → addspec-htHGZHOe2.js} +0 -0
- /package/client/dist/assets/{addspec-Bw_YQwo62.js → addspec-lr_LP6jk.js} +0 -0
- /package/client/dist/assets/{agents-BHgn--3j.js → agents-6ZOJXWVk2.js} +0 -0
- /package/client/dist/assets/{agents-VsyFhGOS2.js → agents-BZ0XQKjg.js} +0 -0
- /package/client/dist/assets/{agents-HFCqQH0Z.js → agents-BqWklnHR.js} +0 -0
- /package/client/dist/assets/{agents-B_qGaB0F.js → agents-Bz-thHkB2.js} +0 -0
- /package/client/dist/assets/{agents-CP8_ezYG.js → agents-CJclElx6.js} +0 -0
- /package/client/dist/assets/{agents-B9pFSJQI2.js → agents-D_l9L0VA.js} +0 -0
- /package/client/dist/assets/{agents-CV-_xBvX2.js → agents-u_C0jPB5.js} +0 -0
- /package/client/dist/assets/{agentstudio-BEp7Sb46.js → agentstudio-BF19hbXj.js} +0 -0
- /package/client/dist/assets/{agentstudio-Br3WD7Xs.js → agentstudio-BLGvxWBx2.js} +0 -0
- /package/client/dist/assets/{agentstudio-BOjG6tgJ.js → agentstudio-D9UKiWTj2.js} +0 -0
- /package/client/dist/assets/{agentstudio-D2A5peWV2.js → agentstudio-Drs37nIM.js} +0 -0
- /package/client/dist/assets/{agentstudio-CuTt3ZGe2.js → agentstudio-nEnKkcXM.js} +0 -0
- /package/client/dist/assets/{agentstudio-RsxnZtUA.js → agentstudio-pyFcSBKy.js} +0 -0
- /package/client/dist/assets/{agentstudio-RfZavULt2.js → agentstudio-zfTzQh3U.js} +0 -0
- /package/client/dist/assets/{aiedit-DnBzjlVz2.js → aiedit-B0KUbpB6.js} +0 -0
- /package/client/dist/assets/{aiedit-D0Syl-mC.js → aiedit-BoG24nlg2.js} +0 -0
- /package/client/dist/assets/{aiedit-CcugGPbS.js → aiedit-CjlSRQVP.js} +0 -0
- /package/client/dist/assets/{aiedit-DrIjSojo.js → aiedit-DCjA7jLJ.js} +0 -0
- /package/client/dist/assets/{aiedit-CV520D4W2.js → aiedit-DNXxq_Dr.js} +0 -0
- /package/client/dist/assets/{aiedit-26p5A_HY2.js → aiedit-DQ-0_pvE.js} +0 -0
- /package/client/dist/assets/{aiedit-a-Z-g5iC.js → aiedit-olnv3QSt2.js} +0 -0
- /package/client/dist/assets/{analytics-DEe5BMz8.js → analytics-BC7mwR4s.js} +0 -0
- /package/client/dist/assets/{analytics-4HvXb0Vn2.js → analytics-BiNg8edP.js} +0 -0
- /package/client/dist/assets/{analytics-CpSTNfui.js → analytics-C0s_T2GN.js} +0 -0
- /package/client/dist/assets/{analytics-4-eskbtX.js → analytics-CdsAPAwZ2.js} +0 -0
- /package/client/dist/assets/{analytics-Bpe41fnX2.js → analytics-Cr1_q-lC.js} +0 -0
- /package/client/dist/assets/{analytics-DcOITHla2.js → analytics-IEsKZvpW2.js} +0 -0
- /package/client/dist/assets/{analytics-Bd9rHGjV.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-CgOQ9K-6.js → attachments-D0wXXt9T2.js} +0 -0
- /package/client/dist/assets/{attachments-DlEQu56g2.js → attachments-DenIjuVI.js} +0 -0
- /package/client/dist/assets/{attachments-CA2f3qL3.js → attachments-DhO7LPfy.js} +0 -0
- /package/client/dist/assets/{attachments-D2jwJXQ42.js → attachments-DoH5w0x4.js} +0 -0
- /package/client/dist/assets/{attachments-CHDbhKeH.js → attachments-Q9yNtiEM.js} +0 -0
- /package/client/dist/assets/{attachments-CKAY5aYG2.js → attachments-V_WZAYXx2.js} +0 -0
- /package/client/dist/assets/{attachments-jVdKzAXn.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-Cl-FwPXs.js → browser-C25DkQiO.js} +0 -0
- /package/client/dist/assets/{browser-JsiohNmW.js → browser-CiJ7-L32.js} +0 -0
- /package/client/dist/assets/{browser-BbJ_q_OT2.js → browser-CvgDySd9.js} +0 -0
- /package/client/dist/assets/{browser-BQFDxrRq.js → browser-CyR1Kp3m2.js} +0 -0
- /package/client/dist/assets/{browser-Do2jf8_N.js → browser-DwZljcRh2.js} +0 -0
- /package/client/dist/assets/{browser-C4VJ5CW12.js → browser-DxP-alBK.js} +0 -0
- /package/client/dist/assets/{browser-kA31eYhu2.js → browser-rRCwi7Y7.js} +0 -0
- /package/client/dist/assets/{cameligo-6R45j6Ph.js → cameligo-DMUM7wLl.js} +0 -0
- /package/client/dist/assets/{chat-BalviUAD.js → chat-2rIB8HhT.js} +0 -0
- /package/client/dist/assets/{chat-Ds8GvCnv.js → chat-BR8oe53x2.js} +0 -0
- /package/client/dist/assets/{chat-D5xEtsf3.js → chat-Bua03tty.js} +0 -0
- /package/client/dist/assets/{chat-SaG-ng1x2.js → chat-CZpAQan1.js} +0 -0
- /package/client/dist/assets/{chat-CJddjN3D2.js → chat-CdY5SGvS.js} +0 -0
- /package/client/dist/assets/{chat-n43nZGvn.js → chat-DZyu3ImY2.js} +0 -0
- /package/client/dist/assets/{chat-BMWD_Rx12.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-C9U6M5-e2.js → code-76gS0IdL.js} +0 -0
- /package/client/dist/assets/{code-BotxM43N2.js → code-C1VwxlML.js} +0 -0
- /package/client/dist/assets/{code-HDK4P6Rx.js → code-CnMZyJpr.js} +0 -0
- /package/client/dist/assets/{code-DUe1Bouz.js → code-D20ef9Cf2.js} +0 -0
- /package/client/dist/assets/{code-Bit_z2Xd2.js → code-DdOXaWRY.js} +0 -0
- /package/client/dist/assets/{code-F_KjccGf.js → code-Duohuf9l.js} +0 -0
- /package/client/dist/assets/{code-CIPmDEd0.js → code-geHmknB92.js} +0 -0
- /package/client/dist/assets/{coffee-AruSygo-.js → coffee-Ba7i2nA0.js} +0 -0
- /package/client/dist/assets/{commands-BFQZc9AG.js → commands-B9RZO4qS.js} +0 -0
- /package/client/dist/assets/{commands-BMkC5-ki.js → commands-BEwbAjtD2.js} +0 -0
- /package/client/dist/assets/{commands-KBbhsnw8.js → commands-Bbxu8kLU.js} +0 -0
- /package/client/dist/assets/{commands-CzFSoIiq2.js → commands-CDU3qv68.js} +0 -0
- /package/client/dist/assets/{commands-CWX9WmDX2.js → commands-CzezgtQj.js} +0 -0
- /package/client/dist/assets/{commands-BllkJauO.js → commands-DTQBF_q52.js} +0 -0
- /package/client/dist/assets/{commands-cKTaLwwV2.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-CAc8Qzu32.js → explore-BG99VGpL.js} +0 -0
- /package/client/dist/assets/{explore-BO_OinBD.js → explore-C0TjprJW2.js} +0 -0
- /package/client/dist/assets/{explore-Bhy7WWXv.js → explore-C2dgEo7q.js} +0 -0
- /package/client/dist/assets/{explore-ELbrSZyQ2.js → explore-C8NDHbob.js} +0 -0
- /package/client/dist/assets/{explore-DW_YTkQh.js → explore-CWWgzQGR.js} +0 -0
- /package/client/dist/assets/{explore-DCZL9gRN2.js → explore-CcQXpdtS.js} +0 -0
- /package/client/dist/assets/{explore-BEpIs343.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-Db1viey1.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-CG2dp3Kd.js → integrations-CH0zy1Mw2.js} +0 -0
- /package/client/dist/assets/{integrations-CUNe3t9l2.js → integrations-CIAjhd7L.js} +0 -0
- /package/client/dist/assets/{integrations-CWjh5VRk.js → integrations-CZdwOe8A.js} +0 -0
- /package/client/dist/assets/{integrations-RJfzXkPx2.js → integrations-Ct7omMld.js} +0 -0
- /package/client/dist/assets/{integrations-CAjq5tdW2.js → integrations-D6MSxy3-.js} +0 -0
- /package/client/dist/assets/{integrations-JOHSCvB3.js → integrations-DbZa-Zyc.js} +0 -0
- /package/client/dist/assets/{integrations-CP_aiV_8.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-CQ7mrZde.js → jira-BySfUuQZ.js} +0 -0
- /package/client/dist/assets/{jira-DIRkZk9U.js → jira-Byw2C0F8.js} +0 -0
- /package/client/dist/assets/{jira-C5UjxHE4.js → jira-CNeYi06w2.js} +0 -0
- /package/client/dist/assets/{jira-ZdKb-50F2.js → jira-D11gPhxz.js} +0 -0
- /package/client/dist/assets/{jira-DTYu3hJi2.js → jira-D38Gj7AT.js} +0 -0
- /package/client/dist/assets/{jira-B5wszJ1-2.js → jira-gAvOyije.js} +0 -0
- /package/client/dist/assets/{jira-DtZpokjJ.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-DKzYFcq6.js → loops-CPpgMapU.js} +0 -0
- /package/client/dist/assets/{loops-Du-bNVpc2.js → loops-CWWbKuVL.js} +0 -0
- /package/client/dist/assets/{loops-DDs4KPu_.js → loops-Crc9It8o2.js} +0 -0
- /package/client/dist/assets/{loops-Bi4ywYGn.js → loops-DH2hZcbK2.js} +0 -0
- /package/client/dist/assets/{loops-DvGbSfxw2.js → loops-DS5TmvIU2.js} +0 -0
- /package/client/dist/assets/{loops-D3wdUkZV.js → loops-P2f0cN8-.js} +0 -0
- /package/client/dist/assets/{loops-BjK8lmoZ2.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-DfmzoT5t.js → mcp-Czd_iyp02.js} +0 -0
- /package/client/dist/assets/{mcp-BG-OCJca2.js → mcp-D2pc5GGx.js} +0 -0
- /package/client/dist/assets/{mcp-CrWdq5db.js → mcp-D4ZjtIx32.js} +0 -0
- /package/client/dist/assets/{mcp-CbJ04oFS2.js → mcp-DIfBUv2D2.js} +0 -0
- /package/client/dist/assets/{mcp-Dd844F5_.js → mcp-DsTwmjST.js} +0 -0
- /package/client/dist/assets/{mcp-zSJ2TsJj.js → mcp-SMkn8boG.js} +0 -0
- /package/client/dist/assets/{mcp-DyULurYS2.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-DUuw9VIU2.js → nav-BRJBxaGt2.js} +0 -0
- /package/client/dist/assets/{nav-D0Erv9ZJ2.js → nav-CAGKv3_F.js} +0 -0
- /package/client/dist/assets/{nav-BY_4EWRv.js → nav-CNskRJKQ2.js} +0 -0
- /package/client/dist/assets/{nav-CVXtv0wX2.js → nav-DY93irBL.js} +0 -0
- /package/client/dist/assets/{nav-B2_ToNqS.js → nav-DhjvYgqt.js} +0 -0
- /package/client/dist/assets/{nav-S4HM94vW.js → nav-Gb-r4wop.js} +0 -0
- /package/client/dist/assets/{nav-BAMkVEId.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/{setup-JeBwoXoM.js → setup-CGZjy2IF2.js} +0 -0
- /package/client/dist/assets/{setup-1vN48B-m2.js → setup-CXa0Sx16.js} +0 -0
- /package/client/dist/assets/{setup-BmJ0Kx16.js → setup-D2ktKKMF2.js} +0 -0
- /package/client/dist/assets/{setup-T_ApeQDV2.js → setup-DG2H7ha5.js} +0 -0
- /package/client/dist/assets/{setup-DQWsu2TR.js → setup-DK5bHDUq2.js} +0 -0
- /package/client/dist/assets/{setup-q0wRHUp1.js → setup-DrWlIQTZ.js} +0 -0
- /package/client/dist/assets/{setup-mXnzww4f.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-BGRKhM8t.js → specs-BcyxaCwf2.js} +0 -0
- /package/client/dist/assets/{specs-GkiL-snY.js → specs-C1q9geAi.js} +0 -0
- /package/client/dist/assets/{specs-DbtIzV8a.js → specs-CLZKysq-2.js} +0 -0
- /package/client/dist/assets/{specs-Ce5y2iFc2.js → specs-DZMS9o54.js} +0 -0
- /package/client/dist/assets/{specs-CT8exGOy2.js → specs-Dm6zUI-R.js} +0 -0
- /package/client/dist/assets/{specs-C6J2zrLM.js → specs-V3TvhKLX.js} +0 -0
- /package/client/dist/assets/{specs-DZDoZsDq.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-BTpE7iki.js → terminal-BZiIu3rf.js} +0 -0
- /package/client/dist/assets/{terminal-DEyt0prF.js → terminal-C2NAd7BW2.js} +0 -0
- /package/client/dist/assets/{terminal-a6Uq8B0p.js → terminal-IahE4LW92.js} +0 -0
- /package/client/dist/assets/{terminal-DDk_bTw0.js → terminal-QpXZU2Bn2.js} +0 -0
- /package/client/dist/assets/{terminal-BNSg2lR7.js → terminal-ScjyXNxQ.js} +0 -0
- /package/client/dist/assets/{terminal-Cvabyzm42.js → terminal-d7GadXbN.js} +0 -0
- /package/client/dist/assets/{terminal-D0z12_sJ2.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
|
@@ -44,6 +44,9 @@ class AgentRefineManager {
|
|
|
44
44
|
_cancelledIds = new Set();
|
|
45
45
|
/** Pending SIGKILL escalation timers, keyed by refine id (BUG-LONGTAIL-02). */
|
|
46
46
|
_killTimers = new Map();
|
|
47
|
+
/** Provider evidence retained outside the awaiting stack so shutdown can
|
|
48
|
+
* account it while the project DB is still open. */
|
|
49
|
+
_liveAccounting = new Map();
|
|
47
50
|
constructor(broadcast, db, projectPath, projectId, provider) {
|
|
48
51
|
this._broadcast = broadcast;
|
|
49
52
|
this._db = db;
|
|
@@ -93,7 +96,13 @@ class AgentRefineManager {
|
|
|
93
96
|
* orphaned refine child. Idempotent.
|
|
94
97
|
*/
|
|
95
98
|
shutdown() {
|
|
99
|
+
if (this._disposed)
|
|
100
|
+
return;
|
|
96
101
|
this._disposed = true;
|
|
102
|
+
for (const [refineId, live] of this._liveAccounting) {
|
|
103
|
+
this._recordRefineInvocation(refineId, live.events, live.model, 'aborted', live.startedAt);
|
|
104
|
+
}
|
|
105
|
+
this._liveAccounting.clear();
|
|
97
106
|
for (const [refineId, child] of this._activeProcesses) {
|
|
98
107
|
if (child.pid)
|
|
99
108
|
this._killWithEscalation(refineId, child.pid);
|
|
@@ -103,6 +112,7 @@ class AgentRefineManager {
|
|
|
103
112
|
}
|
|
104
113
|
/** Start a new refine session for the given custom agent. */
|
|
105
114
|
async startRefine(opts) {
|
|
115
|
+
this._assertActive();
|
|
106
116
|
if (!CUSTOM_PREFIX.test(opts.agentId)) {
|
|
107
117
|
throw new Error('not_a_custom_agent');
|
|
108
118
|
}
|
|
@@ -128,6 +138,7 @@ class AgentRefineManager {
|
|
|
128
138
|
}
|
|
129
139
|
/** Send a follow-up instruction on an existing session. */
|
|
130
140
|
async sendTurn(opts) {
|
|
141
|
+
this._assertActive();
|
|
131
142
|
const session = (0, agent_refine_db_1.getRefineSession)(this._db, opts.refineId);
|
|
132
143
|
if (!session)
|
|
133
144
|
throw new Error('session_not_found');
|
|
@@ -140,6 +151,7 @@ class AgentRefineManager {
|
|
|
140
151
|
}
|
|
141
152
|
/** Cancel an in-flight session. Idempotent. */
|
|
142
153
|
cancel(refineId) {
|
|
154
|
+
this._assertActive();
|
|
143
155
|
const child = this._activeProcesses.get(refineId);
|
|
144
156
|
if (child?.pid) {
|
|
145
157
|
// Mark intentionally-cancelled BEFORE killing so the spawn's settle path
|
|
@@ -161,6 +173,7 @@ class AgentRefineManager {
|
|
|
161
173
|
}
|
|
162
174
|
/** Toggle auto-test for a session. */
|
|
163
175
|
toggleAutoTest(refineId, enabled) {
|
|
176
|
+
this._assertActive();
|
|
164
177
|
const session = (0, agent_refine_db_1.getRefineSession)(this._db, refineId);
|
|
165
178
|
if (!session)
|
|
166
179
|
throw new Error('session_not_found');
|
|
@@ -168,6 +181,7 @@ class AgentRefineManager {
|
|
|
168
181
|
}
|
|
169
182
|
/** Apply the current draft_body to disk through the standard write path. */
|
|
170
183
|
apply(opts) {
|
|
184
|
+
this._assertActive();
|
|
171
185
|
const session = (0, agent_refine_db_1.getRefineSession)(this._db, opts.refineId);
|
|
172
186
|
if (!session)
|
|
173
187
|
return { ok: false, reason: 'session_not_found' };
|
|
@@ -206,10 +220,15 @@ class AgentRefineManager {
|
|
|
206
220
|
}
|
|
207
221
|
/** Hard-delete a session (used by cleanup/admin paths). */
|
|
208
222
|
destroy(refineId) {
|
|
223
|
+
this._assertActive();
|
|
209
224
|
this.cancel(refineId);
|
|
210
225
|
(0, agent_refine_db_1.deleteRefineSession)(this._db, refineId);
|
|
211
226
|
}
|
|
212
227
|
// ─── Private ──────────────────────────────────────────────────────────────
|
|
228
|
+
_assertActive() {
|
|
229
|
+
if (this._disposed)
|
|
230
|
+
throw new Error('manager_disposed');
|
|
231
|
+
}
|
|
213
232
|
_agentFile(agentId) {
|
|
214
233
|
// Per-provider on-disk layout:
|
|
215
234
|
// claude → <root>/.claude/agents/<agentId>.md
|
|
@@ -259,15 +278,22 @@ class AgentRefineManager {
|
|
|
259
278
|
? 'chat-resume'
|
|
260
279
|
: 'agent-refine';
|
|
261
280
|
const refineModel = this._adapter.defaultModel();
|
|
262
|
-
const
|
|
281
|
+
const buildOpts = {
|
|
263
282
|
prompt,
|
|
264
283
|
model: refineModel,
|
|
265
284
|
sessionId: session.session_id ?? undefined,
|
|
266
|
-
|
|
285
|
+
// The model receives the complete current agent body in its prompt and
|
|
286
|
+
// must only return a replacement body. Repo tools cannot improve this
|
|
287
|
+
// contract and would turn prompt text into filesystem authority.
|
|
288
|
+
toolPolicy: 'none',
|
|
289
|
+
};
|
|
290
|
+
const args = this._adapter.buildArgs(action, buildOpts);
|
|
267
291
|
let drafted = false;
|
|
268
292
|
this._bodyBuffers.set(refineId, '');
|
|
269
293
|
const turnStartedAt = new Date().toISOString();
|
|
270
294
|
const spawnState = { err: null };
|
|
295
|
+
const liveAccounting = { events: [], model: refineModel, startedAt: turnStartedAt };
|
|
296
|
+
this._liveAccounting.set(refineId, liveAccounting);
|
|
271
297
|
// Spawn / stream / settlement is owned by the shared spawn-lifecycle; the
|
|
272
298
|
// refine-specific draft buffering, accounting, validation and history all
|
|
273
299
|
// stay here unchanged.
|
|
@@ -277,13 +303,17 @@ class AgentRefineManager {
|
|
|
277
303
|
const refineEnv = refineExec.relocated ? { ...process.env, ...refineExec.env } : undefined;
|
|
278
304
|
const run = await (0, spawn_lifecycle_1.runAiCliInvocation)({
|
|
279
305
|
adapter: this._adapter,
|
|
280
|
-
|
|
281
|
-
|
|
306
|
+
// Pass the already-policy-bound argv so first turns and native resumes
|
|
307
|
+
// cannot diverge if the lifecycle rebuilds options later.
|
|
308
|
+
argv: args,
|
|
282
309
|
cwd: refineExec.cwd,
|
|
283
310
|
env: refineEnv,
|
|
284
311
|
onSpawn: (child) => this._activeProcesses.set(refineId, child),
|
|
285
312
|
onSpawnError: (err) => { spawnState.err = err; },
|
|
286
313
|
onEvent: (ev) => {
|
|
314
|
+
if (this._disposed)
|
|
315
|
+
return;
|
|
316
|
+
liveAccounting.events.push(ev);
|
|
287
317
|
switch (ev.kind) {
|
|
288
318
|
case 'text-delta': {
|
|
289
319
|
if (!drafted) {
|
|
@@ -320,6 +350,7 @@ class AgentRefineManager {
|
|
|
320
350
|
});
|
|
321
351
|
this._clearKillTimer(refineId);
|
|
322
352
|
this._activeProcesses.delete(refineId);
|
|
353
|
+
this._liveAccounting.delete(refineId);
|
|
323
354
|
const fullDraft = this._bodyBuffers.get(refineId) ?? '';
|
|
324
355
|
this._bodyBuffers.delete(refineId);
|
|
325
356
|
// A cancel() killed this child intentionally; its non-zero exit must NOT
|
|
@@ -329,9 +360,13 @@ class AgentRefineManager {
|
|
|
329
360
|
// adapter events) BEFORE short-circuiting — otherwise the cancel path loses
|
|
330
361
|
// 100% of its spend (MED-12). No status overwrite, no failure emit.
|
|
331
362
|
const wasCancelled = this._cancelledIds.delete(refineId);
|
|
332
|
-
|
|
363
|
+
// shutdown() already flushed this live run synchronously while the DB was
|
|
364
|
+
// open. A cancel racing with project removal must not insert it twice.
|
|
365
|
+
if (this._disposed)
|
|
366
|
+
return;
|
|
367
|
+
if (wasCancelled) {
|
|
333
368
|
this._recordRefineInvocation(refineId, run.events, refineModel, 'aborted', turnStartedAt);
|
|
334
|
-
return; // cancel (BUG-LONGTAIL-01)
|
|
369
|
+
return; // cancel (BUG-LONGTAIL-01)
|
|
335
370
|
}
|
|
336
371
|
if (run.spawnFailed) {
|
|
337
372
|
this._emitError(refineId, `Failed to launch claude: ${spawnState.err?.message ?? 'spawn error'}`);
|
|
@@ -427,6 +462,8 @@ class AgentRefineManager {
|
|
|
427
462
|
}
|
|
428
463
|
}
|
|
429
464
|
async _runAutoTest(refineId, agentId, draftBody, draftHash) {
|
|
465
|
+
if (this._disposed)
|
|
466
|
+
return;
|
|
430
467
|
(0, agent_refine_db_1.updateRefineSession)(this._db, refineId, { phase: 'testing' });
|
|
431
468
|
this._emitPhase(refineId, 'testing');
|
|
432
469
|
const sampleTask = pickSampleTask(this._db, agentId);
|
|
@@ -440,6 +477,8 @@ class AgentRefineManager {
|
|
|
440
477
|
? { db: this._db, projectId: this._projectId, surfaceRefId: refineId, broadcast: this._broadcast }
|
|
441
478
|
: undefined,
|
|
442
479
|
});
|
|
480
|
+
if (this._disposed)
|
|
481
|
+
return;
|
|
443
482
|
this._db.prepare(`INSERT INTO agent_tests (agent_name, draft_hash, sample_task_id, tokens, duration_ms, output, created_at)
|
|
444
483
|
VALUES (?, ?, ?, ?, ?, ?, ?)`).run(agentId, result.draftHash, null, result.tokens, result.durationMs, result.output, Date.now());
|
|
445
484
|
(0, agent_refine_db_1.updateRefineSession)(this._db, refineId, {
|
|
@@ -462,6 +501,8 @@ class AgentRefineManager {
|
|
|
462
501
|
});
|
|
463
502
|
}
|
|
464
503
|
catch (err) {
|
|
504
|
+
if (this._disposed)
|
|
505
|
+
return;
|
|
465
506
|
this._emitError(refineId, `Auto-test failed: ${err.message}`);
|
|
466
507
|
(0, agent_refine_db_1.updateRefineSession)(this._db, refineId, { phase: 'done' });
|
|
467
508
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AGENT_CONVERSATION_ENV = exports.AGENT_CONVERSATION_HEADER = exports.AGENT_PROJECT_ENV = exports.AGENT_PROJECT_HEADER = exports.AGENT_TIER_ENV = exports.AGENT_TIER_HEADER = exports.AGENT_TIER_NAMES = void 0;
|
|
3
|
+
exports.AGENT_CAPABILITY_FILE_ENV = exports.AGENT_CAPABILITY_HEADER = exports.AGENT_CONVERSATION_ENV = exports.AGENT_CONVERSATION_HEADER = exports.AGENT_PROJECT_ENV = exports.AGENT_PROJECT_HEADER = exports.AGENT_TIER_ENV = exports.AGENT_TIER_HEADER = exports.AGENT_TIER_NAMES = void 0;
|
|
4
4
|
exports.tierNameForLevel = tierNameForLevel;
|
|
5
5
|
exports.levelForTierName = levelForTierName;
|
|
6
6
|
exports.normalizeLevel = normalizeLevel;
|
|
@@ -14,19 +14,22 @@ exports.AGENT_TIER_NAMES = [
|
|
|
14
14
|
'operate',
|
|
15
15
|
'autonomous',
|
|
16
16
|
];
|
|
17
|
-
/**
|
|
17
|
+
/** @deprecated Untrusted legacy header retained for compatibility/negative tests. */
|
|
18
18
|
exports.AGENT_TIER_HEADER = 'x-specrails-agent-tier';
|
|
19
|
-
/**
|
|
19
|
+
/** @deprecated Untrusted legacy env var; the bridge deliberately ignores it. */
|
|
20
20
|
exports.AGENT_TIER_ENV = 'SPECRAILS_AGENT_TIER';
|
|
21
|
-
/**
|
|
21
|
+
/** @deprecated Untrusted legacy header retained for compatibility/negative tests. */
|
|
22
22
|
exports.AGENT_PROJECT_HEADER = 'x-specrails-active-project';
|
|
23
|
-
/**
|
|
23
|
+
/** @deprecated Untrusted legacy env var; the bridge deliberately ignores it. */
|
|
24
24
|
exports.AGENT_PROJECT_ENV = 'SPECRAILS_ACTIVE_PROJECT';
|
|
25
|
-
/**
|
|
26
|
-
* origin link) so an MCP-launched rail can be tagged with its origin. */
|
|
25
|
+
/** @deprecated Untrusted legacy header retained for compatibility/negative tests. */
|
|
27
26
|
exports.AGENT_CONVERSATION_HEADER = 'x-specrails-agent-conversation';
|
|
28
|
-
/**
|
|
27
|
+
/** @deprecated Untrusted legacy env var; the bridge deliberately ignores it. */
|
|
29
28
|
exports.AGENT_CONVERSATION_ENV = 'SPECRAILS_AGENT_CONVERSATION';
|
|
29
|
+
/** Bearer-like proof that an MCP request belongs to a live in-app agent turn. */
|
|
30
|
+
exports.AGENT_CAPABILITY_HEADER = 'x-specrails-agent-capability';
|
|
31
|
+
/** 0600 file path read by the bridge; the secret itself never appears in argv. */
|
|
32
|
+
exports.AGENT_CAPABILITY_FILE_ENV = 'SPECRAILS_AGENT_CAPABILITY_FILE';
|
|
30
33
|
/** Which MCP tiers a given ladder level unlocks (cumulative). */
|
|
31
34
|
const TIERS_BY_LEVEL = {
|
|
32
35
|
0: new Set(['read']),
|
|
@@ -64,9 +67,8 @@ function levelAllowsTier(level, tier) {
|
|
|
64
67
|
return TIERS_BY_LEVEL[level].has(tier);
|
|
65
68
|
}
|
|
66
69
|
/**
|
|
67
|
-
* Parse
|
|
68
|
-
*
|
|
69
|
-
* numeric level; anything else yields null (→ fall back to Settings tiers).
|
|
70
|
+
* Parse a legacy tier value. Retained for UI/storage compatibility only: MCP
|
|
71
|
+
* request authorization MUST use a verified server-minted capability instead.
|
|
70
72
|
*/
|
|
71
73
|
function levelFromHeader(headerValue) {
|
|
72
74
|
if (headerValue == null)
|
|
@@ -38,13 +38,16 @@ exports.readRegistryOrEmpty = readRegistryOrEmpty;
|
|
|
38
38
|
exports.atomicWrite = atomicWrite;
|
|
39
39
|
exports.refreshLockHeartbeat = refreshLockHeartbeat;
|
|
40
40
|
exports.withFileLock = withFileLock;
|
|
41
|
+
exports.mirrorProjectEntryWithPrevious = mirrorProjectEntryWithPrevious;
|
|
41
42
|
exports.mirrorProjectEntry = mirrorProjectEntry;
|
|
42
43
|
exports.resolveArtifacts = resolveArtifacts;
|
|
43
44
|
exports.removeRegistryEntry = removeRegistryEntry;
|
|
45
|
+
exports.restoreRegistryEntry = restoreRegistryEntry;
|
|
44
46
|
exports.reconcileFromProjects = reconcileFromProjects;
|
|
45
47
|
const fs_1 = require("fs");
|
|
46
48
|
const os_1 = __importDefault(require("os"));
|
|
47
49
|
const path_1 = __importDefault(require("path"));
|
|
50
|
+
const util_1 = require("util");
|
|
48
51
|
/** Registry schema version. A reader that sees a higher value MUST treat all
|
|
49
52
|
* entries as absent (legacy fallback), never mis-parse. */
|
|
50
53
|
exports.REGISTRY_SCHEMA_VERSION = 1;
|
|
@@ -458,7 +461,7 @@ function buildMirroredEntry(existing, canon, desiredSlug, input, now, touchInsta
|
|
|
458
461
|
*
|
|
459
462
|
* Runs under the file lock with a re-read so concurrent writers serialise.
|
|
460
463
|
*/
|
|
461
|
-
function
|
|
464
|
+
function mirrorProjectEntryWithPrevious(input, home) {
|
|
462
465
|
const canon = canonicalizeRepoPath(input.repoPath);
|
|
463
466
|
const key = normalizeKey(canon);
|
|
464
467
|
const { providers, primaryProvider } = normalizeProviders(input.providers, input.primaryProvider);
|
|
@@ -480,9 +483,12 @@ function mirrorProjectEntry(input, home) {
|
|
|
480
483
|
reg.generator = 'specrails-desktop';
|
|
481
484
|
reg.updatedAt = now;
|
|
482
485
|
atomicWrite(registryPath(home), JSON.stringify(reg, null, 2) + '\n');
|
|
483
|
-
return entry;
|
|
486
|
+
return { entry, previousEntry: existing };
|
|
484
487
|
});
|
|
485
488
|
}
|
|
489
|
+
function mirrorProjectEntry(input, home) {
|
|
490
|
+
return mirrorProjectEntryWithPrevious(input, home).entry;
|
|
491
|
+
}
|
|
486
492
|
/**
|
|
487
493
|
* Resolve a repo's artifact locations from the registry (read-only). Returns a
|
|
488
494
|
* legacy (repo-relative) resolution when no entry exists, so callers can treat
|
|
@@ -541,6 +547,31 @@ function removeRegistryEntry(repoPath, home) {
|
|
|
541
547
|
atomicWrite(registryPath(home), JSON.stringify(reg, null, 2) + '\n');
|
|
542
548
|
});
|
|
543
549
|
}
|
|
550
|
+
/** Restore a repo's exact pre-mirror entry, or remove the newly-created entry
|
|
551
|
+
* when no entry existed before the mirror. Used only to roll back a failed
|
|
552
|
+
* higher-level project registration after the mirror itself succeeded. */
|
|
553
|
+
function restoreRegistryEntry(repoPath, previousEntry, expectedCurrentEntry, home) {
|
|
554
|
+
const canon = canonicalizeRepoPath(repoPath);
|
|
555
|
+
const key = normalizeKey(canon);
|
|
556
|
+
return withFileLock(home, () => {
|
|
557
|
+
const reg = readRegistryOrEmpty(home);
|
|
558
|
+
// Hydration happens after the mirror lock is released. If core or another
|
|
559
|
+
// desktop process updated this repo meanwhile, that newer entry is no
|
|
560
|
+
// longer our mutation to undo. Leave it intact instead of restoring stale
|
|
561
|
+
// state over a lock-respecting concurrent writer.
|
|
562
|
+
if (!(0, util_1.isDeepStrictEqual)(reg.projects[key], expectedCurrentEntry))
|
|
563
|
+
return false;
|
|
564
|
+
if (previousEntry)
|
|
565
|
+
reg.projects[key] = previousEntry;
|
|
566
|
+
else
|
|
567
|
+
delete reg.projects[key];
|
|
568
|
+
reg.schemaVersion = exports.REGISTRY_SCHEMA_VERSION;
|
|
569
|
+
reg.generator = 'specrails-desktop';
|
|
570
|
+
reg.updatedAt = new Date().toISOString();
|
|
571
|
+
atomicWrite(registryPath(home), JSON.stringify(reg, null, 2) + '\n');
|
|
572
|
+
return true;
|
|
573
|
+
});
|
|
574
|
+
}
|
|
544
575
|
/**
|
|
545
576
|
* MERGE-upsert one entry per desktop project, leaving entries NOT owned by
|
|
546
577
|
* desktop (`source:'core-standalone'` for repos desktop doesn't track)
|
package/server/dist/auth.js
CHANGED
|
@@ -18,6 +18,7 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
18
18
|
const path_1 = __importDefault(require("path"));
|
|
19
19
|
const os_1 = __importDefault(require("os"));
|
|
20
20
|
const crypto_1 = require("crypto");
|
|
21
|
+
const secure_token_file_1 = require("./util/secure-token-file");
|
|
21
22
|
const TOKEN_DIR = path_1.default.join(os_1.default.homedir(), '.specrails');
|
|
22
23
|
const TOKEN_PATH = path_1.default.join(TOKEN_DIR, 'desktop.token');
|
|
23
24
|
// Legacy (pre-rebrand) token filename — referenced by the one-time migration
|
|
@@ -58,8 +59,9 @@ function loadOrGenerateToken() {
|
|
|
58
59
|
return _token;
|
|
59
60
|
migrateLegacyTokenFile();
|
|
60
61
|
try {
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
const stored = (0, secure_token_file_1.readPrivateTextFile)(TOKEN_PATH);
|
|
63
|
+
if (stored !== null) {
|
|
64
|
+
const t = stored.trim();
|
|
63
65
|
if (t && t.length >= 32) {
|
|
64
66
|
_token = t;
|
|
65
67
|
return _token;
|
|
@@ -71,8 +73,7 @@ function loadOrGenerateToken() {
|
|
|
71
73
|
}
|
|
72
74
|
_token = (0, crypto_1.randomUUID)().replace(/-/g, '') + (0, crypto_1.randomUUID)().replace(/-/g, '');
|
|
73
75
|
try {
|
|
74
|
-
|
|
75
|
-
fs_1.default.writeFileSync(TOKEN_PATH, _token, { encoding: 'utf-8', mode: 0o600 });
|
|
76
|
+
(0, secure_token_file_1.writePrivateTextFile)(TOKEN_PATH, _token);
|
|
76
77
|
}
|
|
77
78
|
catch (err) {
|
|
78
79
|
console.warn('[auth] could not persist token to disk:', err);
|
|
@@ -19,6 +19,8 @@ function isTargetClosedError(err) {
|
|
|
19
19
|
return /target page, context or browser has been closed|target closed|has been closed/i.test(msg);
|
|
20
20
|
}
|
|
21
21
|
const MAX_SESSIONS_PER_PROJECT = 4;
|
|
22
|
+
const DEFAULT_SESSION_IDLE_TTL_MS = 10 * 60_000;
|
|
23
|
+
const DEFAULT_SESSION_SWEEP_INTERVAL_MS = 60_000;
|
|
22
24
|
const DOM_HTML_BYTE_CAP = 100_000;
|
|
23
25
|
const LAST_URL_KEY = 'config.browser_last_url';
|
|
24
26
|
/** Conflation threshold for the screencast fan-out: skip sending a frame to a
|
|
@@ -52,6 +54,9 @@ class BrowserCaptureManager {
|
|
|
52
54
|
/** When set, pages are opened in this app-wide shared context (global cookies)
|
|
53
55
|
* and this manager never owns/closes the context — only its own pages. */
|
|
54
56
|
contextPool;
|
|
57
|
+
now;
|
|
58
|
+
sessionIdleTtlMs;
|
|
59
|
+
idleSweepTimer = null;
|
|
55
60
|
context = null;
|
|
56
61
|
contextPromise = null;
|
|
57
62
|
sessions = new Map();
|
|
@@ -67,9 +72,20 @@ class BrowserCaptureManager {
|
|
|
67
72
|
this.launcher = opts.launcher ?? (0, browser_playwright_1.createPlaywrightLauncher)();
|
|
68
73
|
this.attachments = opts.attachments ?? attachment_manager_1.attachmentManager;
|
|
69
74
|
this.contextPool = opts.contextPool ?? null;
|
|
75
|
+
this.now = opts.now ?? Date.now;
|
|
76
|
+
const requestedIdleTtlMs = opts.sessionIdleTtlMs;
|
|
77
|
+
this.sessionIdleTtlMs = typeof requestedIdleTtlMs === 'number' && Number.isFinite(requestedIdleTtlMs) && requestedIdleTtlMs > 0
|
|
78
|
+
? requestedIdleTtlMs
|
|
79
|
+
: DEFAULT_SESSION_IDLE_TTL_MS;
|
|
70
80
|
this.profileDir =
|
|
71
81
|
opts.profileDir ??
|
|
72
82
|
path_1.default.join(opts.homeDir ?? os_1.default.homedir(), '.specrails', 'projects', opts.projectSlug, 'browser-profile');
|
|
83
|
+
const requestedSweepIntervalMs = opts.sessionSweepIntervalMs;
|
|
84
|
+
const sweepIntervalMs = typeof requestedSweepIntervalMs === 'number' && Number.isFinite(requestedSweepIntervalMs) && requestedSweepIntervalMs > 0
|
|
85
|
+
? requestedSweepIntervalMs
|
|
86
|
+
: Math.min(DEFAULT_SESSION_SWEEP_INTERVAL_MS, this.sessionIdleTtlMs);
|
|
87
|
+
this.idleSweepTimer = setInterval(() => { void this.sweepIdleSessions(); }, sweepIntervalMs);
|
|
88
|
+
this.idleSweepTimer.unref?.();
|
|
73
89
|
}
|
|
74
90
|
// ─── Last-URL persistence (reuses the queue_state key/value table) ───────────
|
|
75
91
|
getLastUrl() {
|
|
@@ -138,6 +154,20 @@ class BrowserCaptureManager {
|
|
|
138
154
|
const s = this.sessions.get(sessionId);
|
|
139
155
|
return s && !s.closed ? s : undefined;
|
|
140
156
|
}
|
|
157
|
+
getSessionForActivity(sessionId) {
|
|
158
|
+
const s = this.getSession(sessionId);
|
|
159
|
+
if (s)
|
|
160
|
+
s.lastActivityAt = this.now();
|
|
161
|
+
return s;
|
|
162
|
+
}
|
|
163
|
+
beginOperation(s) {
|
|
164
|
+
s.lastActivityAt = this.now();
|
|
165
|
+
s.activeOperations += 1;
|
|
166
|
+
}
|
|
167
|
+
endOperation(s) {
|
|
168
|
+
s.activeOperations = Math.max(0, s.activeOperations - 1);
|
|
169
|
+
s.lastActivityAt = this.now();
|
|
170
|
+
}
|
|
141
171
|
async create(opts) {
|
|
142
172
|
// Reserve the slot SYNCHRONOUSLY before any await so N concurrent creates can't
|
|
143
173
|
// all observe `< MAX` and race past the cap (BUG-BROWSER-02). `_reserved`
|
|
@@ -170,6 +200,7 @@ class BrowserCaptureManager {
|
|
|
170
200
|
throw new browser_capture_types_1.BrowserLimitExceededError(MAX_SESSIONS_PER_PROJECT);
|
|
171
201
|
}
|
|
172
202
|
const id = (0, ids_1.newId)();
|
|
203
|
+
const activityAt = this.now();
|
|
173
204
|
const session = {
|
|
174
205
|
id,
|
|
175
206
|
projectId: this.projectId,
|
|
@@ -181,7 +212,9 @@ class BrowserCaptureManager {
|
|
|
181
212
|
url: null,
|
|
182
213
|
title: null,
|
|
183
214
|
viewport: { ...DEFAULT_VIEWPORT },
|
|
184
|
-
createdAt: opts?.createdAtMs ??
|
|
215
|
+
createdAt: opts?.createdAtMs ?? activityAt,
|
|
216
|
+
lastActivityAt: activityAt,
|
|
217
|
+
activeOperations: 0,
|
|
185
218
|
screencastPage: null,
|
|
186
219
|
screencastDesired: false,
|
|
187
220
|
screencastOp: null,
|
|
@@ -302,7 +335,7 @@ class BrowserCaptureManager {
|
|
|
302
335
|
/** Switch the viewed page between the root page and the top popup ("back to
|
|
303
336
|
* page" / "show login window"). Returns false for an unknown session. */
|
|
304
337
|
setPopupView(sessionId, target) {
|
|
305
|
-
const s = this.
|
|
338
|
+
const s = this.getSessionForActivity(sessionId);
|
|
306
339
|
if (!s)
|
|
307
340
|
return false;
|
|
308
341
|
s.popupView = target === 'popup' && s.popups.length > 0;
|
|
@@ -314,7 +347,7 @@ class BrowserCaptureManager {
|
|
|
314
347
|
async attach(sessionId, ws) {
|
|
315
348
|
if (this.disposed)
|
|
316
349
|
return null;
|
|
317
|
-
const s = this.
|
|
350
|
+
const s = this.getSessionForActivity(sessionId);
|
|
318
351
|
if (!s)
|
|
319
352
|
return null;
|
|
320
353
|
s.clients.add(ws);
|
|
@@ -336,6 +369,7 @@ class BrowserCaptureManager {
|
|
|
336
369
|
if (!s)
|
|
337
370
|
return;
|
|
338
371
|
s.clients.delete(ws);
|
|
372
|
+
s.lastActivityAt = this.now();
|
|
339
373
|
if (s.clients.size === 0 && !s.closed) {
|
|
340
374
|
s.screencastDesired = false;
|
|
341
375
|
void this.applyScreencast(s);
|
|
@@ -406,7 +440,7 @@ class BrowserCaptureManager {
|
|
|
406
440
|
async probeElement(sessionId, point) {
|
|
407
441
|
if (this.disposed)
|
|
408
442
|
return null;
|
|
409
|
-
const s = this.
|
|
443
|
+
const s = this.getSessionForActivity(sessionId);
|
|
410
444
|
if (!s)
|
|
411
445
|
return null;
|
|
412
446
|
return s.page.probeElementAt(point);
|
|
@@ -415,7 +449,7 @@ class BrowserCaptureManager {
|
|
|
415
449
|
async navigateElement(sessionId, selector, direction) {
|
|
416
450
|
if (this.disposed)
|
|
417
451
|
return null;
|
|
418
|
-
const s = this.
|
|
452
|
+
const s = this.getSessionForActivity(sessionId);
|
|
419
453
|
if (!s)
|
|
420
454
|
return null;
|
|
421
455
|
return (await s.page.navigateElement?.(selector, direction)) ?? null;
|
|
@@ -423,7 +457,7 @@ class BrowserCaptureManager {
|
|
|
423
457
|
async handleInput(sessionId, event) {
|
|
424
458
|
if (this.disposed)
|
|
425
459
|
return;
|
|
426
|
-
const s = this.
|
|
460
|
+
const s = this.getSessionForActivity(sessionId);
|
|
427
461
|
if (!s)
|
|
428
462
|
return;
|
|
429
463
|
if (event.type === 'resize') {
|
|
@@ -449,30 +483,36 @@ class BrowserCaptureManager {
|
|
|
449
483
|
async navigate(sessionId, action, url) {
|
|
450
484
|
if (this.disposed)
|
|
451
485
|
return null;
|
|
452
|
-
const s = this.
|
|
486
|
+
const s = this.getSessionForActivity(sessionId);
|
|
453
487
|
if (!s)
|
|
454
488
|
return null;
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
result
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
489
|
+
this.beginOperation(s);
|
|
490
|
+
try {
|
|
491
|
+
let result;
|
|
492
|
+
if (action === 'goto')
|
|
493
|
+
result = await s.page.goto(url ?? 'about:blank');
|
|
494
|
+
else if (action === 'back')
|
|
495
|
+
result = await s.page.goBack();
|
|
496
|
+
else if (action === 'forward')
|
|
497
|
+
result = await s.page.goForward();
|
|
498
|
+
else
|
|
499
|
+
result = await s.page.reload();
|
|
500
|
+
s.url = result.url;
|
|
501
|
+
s.title = result.title;
|
|
502
|
+
if (result.url && result.url !== 'about:blank')
|
|
503
|
+
this.setLastUrl(result.url);
|
|
504
|
+
this.broadcastControl(s, { type: 'nav', url: result.url, title: result.title });
|
|
505
|
+
return result;
|
|
506
|
+
}
|
|
507
|
+
finally {
|
|
508
|
+
this.endOperation(s);
|
|
509
|
+
}
|
|
470
510
|
}
|
|
471
511
|
// ─── Capture: screenshot + rich DOM → attachments ───────────────────────────
|
|
472
512
|
async capture(sessionId, rect, pendingSpecId, opts) {
|
|
473
513
|
if (this.disposed)
|
|
474
514
|
return null;
|
|
475
|
-
const s = this.
|
|
515
|
+
const s = this.getSessionForActivity(sessionId);
|
|
476
516
|
if (!s)
|
|
477
517
|
return null;
|
|
478
518
|
const safeRect = {
|
|
@@ -483,6 +523,7 @@ class BrowserCaptureManager {
|
|
|
483
523
|
};
|
|
484
524
|
let png;
|
|
485
525
|
let dom;
|
|
526
|
+
this.beginOperation(s);
|
|
486
527
|
try {
|
|
487
528
|
;
|
|
488
529
|
[png, dom] = await Promise.all([
|
|
@@ -500,6 +541,9 @@ class BrowserCaptureManager {
|
|
|
500
541
|
}
|
|
501
542
|
throw err;
|
|
502
543
|
}
|
|
544
|
+
finally {
|
|
545
|
+
this.endOperation(s);
|
|
546
|
+
}
|
|
503
547
|
// Snapshot the recent network requests into the DOM payload (rides the same
|
|
504
548
|
// JSON attachment → spec prompt). ON unless the spec explicitly disabled it.
|
|
505
549
|
if (opts?.captureNetwork !== false) {
|
|
@@ -546,7 +590,7 @@ class BrowserCaptureManager {
|
|
|
546
590
|
async clipboard(sessionId, action, text) {
|
|
547
591
|
if (this.disposed)
|
|
548
592
|
return null;
|
|
549
|
-
const s = this.
|
|
593
|
+
const s = this.getSessionForActivity(sessionId);
|
|
550
594
|
if (!s)
|
|
551
595
|
return null;
|
|
552
596
|
// Clipboard follows the viewed page: pasting credentials into an OAuth
|
|
@@ -575,12 +619,13 @@ class BrowserCaptureManager {
|
|
|
575
619
|
async captureBreakpoints(sessionId, rect, anchorPoint, pendingSpecId, dims) {
|
|
576
620
|
if (this.disposed)
|
|
577
621
|
return null;
|
|
578
|
-
const s = this.
|
|
622
|
+
const s = this.getSessionForActivity(sessionId);
|
|
579
623
|
if (!s)
|
|
580
624
|
return null;
|
|
581
625
|
const order = Object.keys(dims);
|
|
582
626
|
if (order.length === 0)
|
|
583
627
|
return null;
|
|
628
|
+
this.beginOperation(s);
|
|
584
629
|
const stashed = { ...s.viewport };
|
|
585
630
|
let selector = null;
|
|
586
631
|
try {
|
|
@@ -640,6 +685,7 @@ class BrowserCaptureManager {
|
|
|
640
685
|
}
|
|
641
686
|
catch { /* ignore */ }
|
|
642
687
|
s.viewport = stashed;
|
|
688
|
+
this.endOperation(s);
|
|
643
689
|
}
|
|
644
690
|
const stamp = this.now();
|
|
645
691
|
const breakpoints = {};
|
|
@@ -673,6 +719,23 @@ class BrowserCaptureManager {
|
|
|
673
719
|
};
|
|
674
720
|
}
|
|
675
721
|
// ─── Teardown ───────────────────────────────────────────────────────────────
|
|
722
|
+
/** Reap sessions abandoned by clients. A connected socket or page-dependent
|
|
723
|
+
* operation is authoritative activity and prevents expiry. `kill()` removes
|
|
724
|
+
* the map entry synchronously, so an attach cannot race between the final
|
|
725
|
+
* eligibility check and teardown on this event loop. */
|
|
726
|
+
async sweepIdleSessions() {
|
|
727
|
+
if (this.disposed)
|
|
728
|
+
return 0;
|
|
729
|
+
const expiresBefore = this.now() - this.sessionIdleTtlMs;
|
|
730
|
+
let reaped = 0;
|
|
731
|
+
for (const [id, s] of this.sessions) {
|
|
732
|
+
if (s.closed || s.clients.size > 0 || s.activeOperations > 0 || s.lastActivityAt > expiresBefore)
|
|
733
|
+
continue;
|
|
734
|
+
if (await this.kill(id))
|
|
735
|
+
reaped += 1;
|
|
736
|
+
}
|
|
737
|
+
return reaped;
|
|
738
|
+
}
|
|
676
739
|
async kill(sessionId) {
|
|
677
740
|
const s = this.sessions.get(sessionId);
|
|
678
741
|
if (!s)
|
|
@@ -709,6 +772,10 @@ class BrowserCaptureManager {
|
|
|
709
772
|
return true;
|
|
710
773
|
}
|
|
711
774
|
async shutdown() {
|
|
775
|
+
if (this.idleSweepTimer) {
|
|
776
|
+
clearInterval(this.idleSweepTimer);
|
|
777
|
+
this.idleSweepTimer = null;
|
|
778
|
+
}
|
|
712
779
|
if (this.disposed)
|
|
713
780
|
return;
|
|
714
781
|
this.disposed = true;
|
|
@@ -757,9 +824,5 @@ class BrowserCaptureManager {
|
|
|
757
824
|
sessionCount() {
|
|
758
825
|
return [...this.sessions.values()].filter((s) => !s.closed).length;
|
|
759
826
|
}
|
|
760
|
-
// Wall-clock indirection so tests can stay deterministic if needed.
|
|
761
|
-
now() {
|
|
762
|
-
return Date.now();
|
|
763
|
-
}
|
|
764
827
|
}
|
|
765
828
|
exports.BrowserCaptureManager = BrowserCaptureManager;
|