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,6 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createLoopRun = createLoopRun;
|
|
4
|
+
exports.finishLoopRunAndJob = finishLoopRunAndJob;
|
|
5
|
+
exports.listPendingLoopTerminalRecoveries = listPendingLoopTerminalRecoveries;
|
|
6
|
+
exports.getLoopTerminalRecovery = getLoopTerminalRecovery;
|
|
7
|
+
exports.completeLoopTerminalRecovery = completeLoopTerminalRecovery;
|
|
8
|
+
exports.readLoopJobUsage = readLoopJobUsage;
|
|
9
|
+
exports.stageLoopStepRecovery = stageLoopStepRecovery;
|
|
10
|
+
exports.updateLoopStepEventCheckpoint = updateLoopStepEventCheckpoint;
|
|
11
|
+
exports.updateLoopStepActivityCheckpoint = updateLoopStepActivityCheckpoint;
|
|
12
|
+
exports.setLoopStepSettledResult = setLoopStepSettledResult;
|
|
13
|
+
exports.getLoopStepRecovery = getLoopStepRecovery;
|
|
14
|
+
exports.listLoopStepRecoveries = listLoopStepRecoveries;
|
|
15
|
+
exports.completeLoopStepRecovery = completeLoopStepRecovery;
|
|
4
16
|
exports.updateLoopRunCounters = updateLoopRunCounters;
|
|
5
17
|
exports.finishLoopRun = finishLoopRun;
|
|
6
18
|
exports.pauseLoopRun = pauseLoopRun;
|
|
@@ -16,11 +28,202 @@ function createLoopRun(db, input) {
|
|
|
16
28
|
db.prepare(`
|
|
17
29
|
INSERT INTO loop_runs (
|
|
18
30
|
id, project_id, loop_id, loop_name, rail_index, ticket_id, provider, model,
|
|
19
|
-
reasoning_effort,
|
|
20
|
-
|
|
21
|
-
|
|
31
|
+
reasoning_effort, ticket_ids_json, ticket_completion_status,
|
|
32
|
+
causal_ownership, status,
|
|
33
|
+
iteration_limit, started_at
|
|
34
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'running', ?, ?)
|
|
35
|
+
`).run(input.id, input.projectId, input.loopId, input.loopName ?? null, input.railIndex ?? null, input.ticketId ?? null, input.provider ?? null, input.model ?? null, input.reasoningEffort ?? null, JSON.stringify([...new Set(input.ticketIds ?? (input.ticketId == null ? [] : [input.ticketId]))]), input.ticketCompletionStatus ?? 'done', input.causalOwnership ? 1 : 0, input.iterationLimit, input.startedAt);
|
|
22
36
|
return getLoopRun(db, input.id);
|
|
23
37
|
}
|
|
38
|
+
function parseTicketIdsJson(raw) {
|
|
39
|
+
try {
|
|
40
|
+
const parsed = JSON.parse(raw ?? '[]');
|
|
41
|
+
if (!Array.isArray(parsed))
|
|
42
|
+
return [];
|
|
43
|
+
return [...new Set(parsed.filter((id) => Number.isSafeInteger(id) && id > 0))];
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Finalise the engine row, backing job and durable domain callback intent in
|
|
50
|
+
* one commit. A caller may crash anywhere after this returns; startup can still
|
|
51
|
+
* replay the exact launch ticket set without consulting an in-memory rail map. */
|
|
52
|
+
function finishLoopRunAndJob(db, id, opts) {
|
|
53
|
+
const tx = db.transaction(() => {
|
|
54
|
+
const run = getLoopRun(db, id);
|
|
55
|
+
if (!run)
|
|
56
|
+
return undefined;
|
|
57
|
+
updateLoopRunCounters(db, id, opts.counters);
|
|
58
|
+
db.prepare(`
|
|
59
|
+
UPDATE loop_runs
|
|
60
|
+
SET status = 'completed', final_outcome = ?, finished_at = ?
|
|
61
|
+
WHERE id = ?
|
|
62
|
+
`).run(opts.outcome, opts.finishedAt, id);
|
|
63
|
+
db.prepare(`
|
|
64
|
+
UPDATE jobs
|
|
65
|
+
SET exit_code = ?, status = ?, finished_at = ?,
|
|
66
|
+
total_cost_usd = CASE WHEN EXISTS (
|
|
67
|
+
SELECT 1 FROM loop_step_recovery WHERE run_id = ?
|
|
68
|
+
) THEN total_cost_usd ELSE ? END,
|
|
69
|
+
tokens_in = CASE WHEN EXISTS (
|
|
70
|
+
SELECT 1 FROM loop_step_recovery WHERE run_id = ?
|
|
71
|
+
) THEN tokens_in ELSE ? END,
|
|
72
|
+
tokens_out = CASE WHEN EXISTS (
|
|
73
|
+
SELECT 1 FROM loop_step_recovery WHERE run_id = ?
|
|
74
|
+
) THEN tokens_out ELSE ? END,
|
|
75
|
+
tokens_cache_read = CASE WHEN EXISTS (
|
|
76
|
+
SELECT 1 FROM loop_step_recovery WHERE run_id = ?
|
|
77
|
+
) THEN tokens_cache_read ELSE ? END,
|
|
78
|
+
tokens_cache_create = CASE WHEN EXISTS (
|
|
79
|
+
SELECT 1 FROM loop_step_recovery WHERE run_id = ?
|
|
80
|
+
) THEN tokens_cache_create ELSE ? END,
|
|
81
|
+
duration_ms = CASE WHEN EXISTS (
|
|
82
|
+
SELECT 1 FROM loop_step_recovery WHERE run_id = ?
|
|
83
|
+
) THEN duration_ms ELSE ? END,
|
|
84
|
+
num_turns = CASE WHEN EXISTS (
|
|
85
|
+
SELECT 1 FROM loop_step_recovery WHERE run_id = ?
|
|
86
|
+
) THEN num_turns ELSE ? END
|
|
87
|
+
WHERE id = ? AND owner = 'loop'
|
|
88
|
+
`).run(opts.job.exitCode, opts.job.status, opts.finishedAt, id, opts.job.totalCostUsd, id, opts.job.tokensIn, id, opts.job.tokensOut, id, opts.job.tokensCacheRead, id, opts.job.tokensCacheCreate, id, opts.job.durationMs, id, opts.job.numTurns, id);
|
|
89
|
+
const payload = {
|
|
90
|
+
version: 1,
|
|
91
|
+
runId: id,
|
|
92
|
+
projectId: run.project_id,
|
|
93
|
+
ticketIds: parseTicketIdsJson(run.ticket_ids_json),
|
|
94
|
+
railIndex: run.rail_index,
|
|
95
|
+
outcome: opts.callbackOutcome ?? opts.outcome,
|
|
96
|
+
jobStatus: opts.job.status,
|
|
97
|
+
ticketCompletionStatus: run.ticket_completion_status ?? 'done',
|
|
98
|
+
finishedAt: opts.finishedAt,
|
|
99
|
+
causalOwnership: run.causal_ownership === 1,
|
|
100
|
+
outcomeFinalized: opts.outcomeFinalized ?? true,
|
|
101
|
+
};
|
|
102
|
+
db.prepare(`
|
|
103
|
+
INSERT INTO loop_terminal_recovery (run_id, payload, callback_completed)
|
|
104
|
+
VALUES (?, ?, 0)
|
|
105
|
+
ON CONFLICT(run_id) DO UPDATE SET
|
|
106
|
+
payload = excluded.payload,
|
|
107
|
+
callback_completed = CASE
|
|
108
|
+
WHEN loop_terminal_recovery.callback_completed = 1 THEN 1 ELSE 0 END
|
|
109
|
+
`).run(id, JSON.stringify(payload));
|
|
110
|
+
return payload;
|
|
111
|
+
});
|
|
112
|
+
return tx();
|
|
113
|
+
}
|
|
114
|
+
function listPendingLoopTerminalRecoveries(db) {
|
|
115
|
+
return db.prepare(`
|
|
116
|
+
SELECT run_id, payload, callback_completed, created_at
|
|
117
|
+
FROM loop_terminal_recovery
|
|
118
|
+
WHERE callback_completed = 0
|
|
119
|
+
ORDER BY created_at, run_id
|
|
120
|
+
`).all();
|
|
121
|
+
}
|
|
122
|
+
function getLoopTerminalRecovery(db, runId) {
|
|
123
|
+
return db.prepare(`SELECT * FROM loop_terminal_recovery WHERE run_id = ?`).get(runId);
|
|
124
|
+
}
|
|
125
|
+
function completeLoopTerminalRecovery(db, runId) {
|
|
126
|
+
db.prepare(`UPDATE loop_terminal_recovery SET callback_completed = 1 WHERE run_id = ?`).run(runId);
|
|
127
|
+
db.prepare(`DELETE FROM loop_terminal_recovery WHERE run_id = ? AND callback_completed = 1`).run(runId);
|
|
128
|
+
}
|
|
129
|
+
function readLoopJobUsage(db, runId) {
|
|
130
|
+
const row = db.prepare(`
|
|
131
|
+
SELECT tokens_in, tokens_out, tokens_cache_read, tokens_cache_create,
|
|
132
|
+
total_cost_usd, num_turns
|
|
133
|
+
FROM jobs WHERE id = ?
|
|
134
|
+
`).get(runId);
|
|
135
|
+
return {
|
|
136
|
+
tokensIn: row?.tokens_in ?? 0,
|
|
137
|
+
tokensOut: row?.tokens_out ?? 0,
|
|
138
|
+
tokensCacheRead: row?.tokens_cache_read ?? 0,
|
|
139
|
+
tokensCacheCreate: row?.tokens_cache_create ?? 0,
|
|
140
|
+
totalCostUsd: row?.total_cost_usd ?? 0,
|
|
141
|
+
numTurns: row?.num_turns ?? 0,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function stageLoopStepRecovery(db, payload) {
|
|
145
|
+
db.prepare(`
|
|
146
|
+
INSERT INTO loop_step_recovery (run_id, step_key, invocation_id, payload)
|
|
147
|
+
VALUES (?, ?, ?, ?)
|
|
148
|
+
ON CONFLICT(run_id, step_key) DO NOTHING
|
|
149
|
+
`).run(payload.runId, payload.stepKey, payload.invocationId, JSON.stringify(payload));
|
|
150
|
+
}
|
|
151
|
+
function updateLoopStepEventCheckpoint(db, runId, stepKey, completedEventSeq, providerCostBaseline, providerTurnsBaseline, completedDurationMs) {
|
|
152
|
+
const row = db.prepare(`SELECT payload FROM loop_step_recovery WHERE run_id = ? AND step_key = ?`)
|
|
153
|
+
.get(runId, stepKey);
|
|
154
|
+
if (!row)
|
|
155
|
+
throw new Error(`Missing loop step checkpoint ${runId}/${stepKey}`);
|
|
156
|
+
const payload = JSON.parse(row.payload);
|
|
157
|
+
payload.completedEventSeq = Math.max(payload.completedEventSeq, completedEventSeq);
|
|
158
|
+
if (providerCostBaseline !== undefined)
|
|
159
|
+
payload.providerCostBaseline = providerCostBaseline;
|
|
160
|
+
if (providerTurnsBaseline !== undefined)
|
|
161
|
+
payload.providerTurnsBaseline = providerTurnsBaseline;
|
|
162
|
+
if (completedDurationMs !== undefined) {
|
|
163
|
+
payload.completedDurationMs = completedDurationMs;
|
|
164
|
+
// The completed duration now includes this turn. Leaving its active segment
|
|
165
|
+
// behind would make a later no-result recovery count it twice.
|
|
166
|
+
delete payload.activeTurnStartedAtMs;
|
|
167
|
+
delete payload.lastActivityAtMs;
|
|
168
|
+
}
|
|
169
|
+
db.prepare(`UPDATE loop_step_recovery SET payload = ? WHERE run_id = ? AND step_key = ?`)
|
|
170
|
+
.run(JSON.stringify(payload), runId, stepKey);
|
|
171
|
+
}
|
|
172
|
+
/** Persist the active turn's wall-clock bounds without advancing the raw-event
|
|
173
|
+
* frontier. A result checkpoint later clears this segment in the same update
|
|
174
|
+
* that commits completedDurationMs. */
|
|
175
|
+
function updateLoopStepActivityCheckpoint(db, runId, stepKey, turnStartedAtMs, activityAtMs) {
|
|
176
|
+
const row = db.prepare(`SELECT payload FROM loop_step_recovery WHERE run_id = ? AND step_key = ?`)
|
|
177
|
+
.get(runId, stepKey);
|
|
178
|
+
if (!row)
|
|
179
|
+
throw new Error(`Missing loop step checkpoint ${runId}/${stepKey}`);
|
|
180
|
+
const payload = JSON.parse(row.payload);
|
|
181
|
+
if (!Number.isFinite(activityAtMs))
|
|
182
|
+
throw new Error('Loop step activity timestamp must be finite');
|
|
183
|
+
const requestedStart = Number.isFinite(turnStartedAtMs)
|
|
184
|
+
? Math.max(0, Math.trunc(turnStartedAtMs))
|
|
185
|
+
: undefined;
|
|
186
|
+
const startedAt = requestedStart ?? payload.activeTurnStartedAtMs ?? Math.max(0, Math.trunc(activityAtMs));
|
|
187
|
+
const activityAt = Math.max(startedAt, Math.trunc(activityAtMs));
|
|
188
|
+
payload.activeTurnStartedAtMs = requestedStart ?? payload.activeTurnStartedAtMs ?? startedAt;
|
|
189
|
+
payload.lastActivityAtMs = Math.max(payload.lastActivityAtMs ?? startedAt, activityAt);
|
|
190
|
+
db.prepare(`UPDATE loop_step_recovery SET payload = ? WHERE run_id = ? AND step_key = ?`)
|
|
191
|
+
.run(JSON.stringify(payload), runId, stepKey);
|
|
192
|
+
}
|
|
193
|
+
function setLoopStepSettledResult(db, runId, stepKey, settledResult) {
|
|
194
|
+
const row = db.prepare(`SELECT payload FROM loop_step_recovery WHERE run_id = ? AND step_key = ?`)
|
|
195
|
+
.get(runId, stepKey);
|
|
196
|
+
if (!row)
|
|
197
|
+
throw new Error(`Missing loop step checkpoint ${runId}/${stepKey}`);
|
|
198
|
+
const payload = JSON.parse(row.payload);
|
|
199
|
+
payload.settledResult = settledResult;
|
|
200
|
+
db.prepare(`UPDATE loop_step_recovery SET payload = ? WHERE run_id = ? AND step_key = ?`)
|
|
201
|
+
.run(JSON.stringify(payload), runId, stepKey);
|
|
202
|
+
}
|
|
203
|
+
function getLoopStepRecovery(db, runId, stepKey) {
|
|
204
|
+
return db.prepare(`SELECT * FROM loop_step_recovery WHERE run_id = ? AND step_key = ?`)
|
|
205
|
+
.get(runId, stepKey);
|
|
206
|
+
}
|
|
207
|
+
function listLoopStepRecoveries(db) {
|
|
208
|
+
return db.prepare(`SELECT * FROM loop_step_recovery ORDER BY created_at, run_id, step_key`).all();
|
|
209
|
+
}
|
|
210
|
+
/** Execute the invocation insert and checkpoint removal under one SQLite
|
|
211
|
+
* transaction. If either statement fails, neither survives. */
|
|
212
|
+
function completeLoopStepRecovery(db, runId, stepKey, record) {
|
|
213
|
+
const tx = db.transaction(() => {
|
|
214
|
+
const row = getLoopStepRecovery(db, runId, stepKey);
|
|
215
|
+
if (!row)
|
|
216
|
+
return false;
|
|
217
|
+
const payload = JSON.parse(row.payload);
|
|
218
|
+
record(payload);
|
|
219
|
+
const removed = db.prepare(`DELETE FROM loop_step_recovery WHERE run_id = ? AND step_key = ?`)
|
|
220
|
+
.run(runId, stepKey);
|
|
221
|
+
if (removed.changes !== 1)
|
|
222
|
+
throw new Error(`loop step checkpoint ${runId}/${stepKey} was not removed`);
|
|
223
|
+
return true;
|
|
224
|
+
});
|
|
225
|
+
return tx();
|
|
226
|
+
}
|
|
24
227
|
// Column allow-list — counters are interpolated into the SET clause, so gate
|
|
25
228
|
// the keys to prevent any future caller injecting SQL via an object key.
|
|
26
229
|
const COUNTER_COLUMNS = {
|
|
@@ -126,14 +329,64 @@ function countRunningForLoop(db, loopId) {
|
|
|
126
329
|
}
|
|
127
330
|
/** Reconcile orphan runs at startup: any row still active belongs to a process
|
|
128
331
|
* that is now dead (server restart, or a run killed before it could settle), so
|
|
129
|
-
* mark it terminal (`completed` + outcome `failed`).
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
332
|
+
* mark it terminal (`completed` + outcome `failed`). Its loop-owned backing
|
|
333
|
+
* jobs row is failed in the SAME transaction. QueueManager deliberately does
|
|
334
|
+
* not sweep those rows: LoopRunManager is the sole invocation authority, so
|
|
335
|
+
* treating the accumulated step total as a second surface='job' invocation
|
|
336
|
+
* would double-count spend. A paused row is active too: its resumable context
|
|
337
|
+
* lived in the old process. Returns the number of loop rows reconciled. */
|
|
338
|
+
function reconcileOrphanLoopRuns(db, finishedAt,
|
|
339
|
+
/** Compatibility only for pre-migration rows whose exact launch ticket set
|
|
340
|
+
* was never persisted. New rows always use ticket_ids_json. */
|
|
341
|
+
legacyTicketIdsByRun) {
|
|
342
|
+
const reconcile = db.transaction(() => {
|
|
343
|
+
const active = db.prepare(`
|
|
344
|
+
SELECT * FROM loop_runs WHERE status IN ('running', 'paused')
|
|
345
|
+
`).all();
|
|
346
|
+
if (active.length === 0)
|
|
347
|
+
return 0;
|
|
348
|
+
const updateJob = db.prepare(`
|
|
349
|
+
UPDATE jobs
|
|
350
|
+
SET status = 'failed', exit_code = -1,
|
|
351
|
+
finished_at = COALESCE(finished_at, ?),
|
|
352
|
+
duration_ms = COALESCE(
|
|
353
|
+
(SELECT total_duration_ms FROM loop_runs WHERE loop_runs.id = jobs.id),
|
|
354
|
+
duration_ms
|
|
355
|
+
)
|
|
356
|
+
WHERE owner = 'loop' AND status = 'running' AND id = ?
|
|
357
|
+
`);
|
|
358
|
+
const updateRun = db.prepare(`
|
|
359
|
+
UPDATE loop_runs
|
|
360
|
+
SET status = 'completed', final_outcome = 'failed',
|
|
361
|
+
finished_at = COALESCE(finished_at, ?)
|
|
362
|
+
WHERE id = ? AND status IN ('running', 'paused')
|
|
363
|
+
`);
|
|
364
|
+
const insertIntent = db.prepare(`
|
|
365
|
+
INSERT INTO loop_terminal_recovery (run_id, payload, callback_completed)
|
|
366
|
+
VALUES (?, ?, 0)
|
|
367
|
+
ON CONFLICT(run_id) DO NOTHING
|
|
368
|
+
`);
|
|
369
|
+
for (const run of active) {
|
|
370
|
+
updateJob.run(finishedAt, run.id);
|
|
371
|
+
updateRun.run(finishedAt, run.id);
|
|
372
|
+
const persistedIds = parseTicketIdsJson(run.ticket_ids_json);
|
|
373
|
+
const legacyIds = legacyTicketIdsByRun?.get(run.id) ?? [];
|
|
374
|
+
const payload = {
|
|
375
|
+
version: 1,
|
|
376
|
+
runId: run.id,
|
|
377
|
+
projectId: run.project_id,
|
|
378
|
+
ticketIds: persistedIds.length > 0 ? persistedIds : [...new Set(legacyIds)],
|
|
379
|
+
railIndex: run.rail_index,
|
|
380
|
+
outcome: 'failed',
|
|
381
|
+
jobStatus: 'failed',
|
|
382
|
+
ticketCompletionStatus: run.ticket_completion_status ?? 'done',
|
|
383
|
+
finishedAt,
|
|
384
|
+
causalOwnership: run.causal_ownership === 1,
|
|
385
|
+
outcomeFinalized: true,
|
|
386
|
+
};
|
|
387
|
+
insertIntent.run(run.id, JSON.stringify(payload));
|
|
388
|
+
}
|
|
389
|
+
return active.length;
|
|
390
|
+
});
|
|
391
|
+
return reconcile();
|
|
139
392
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mintAgentCapability = mintAgentCapability;
|
|
4
|
+
exports.verifyAgentCapability = verifyAgentCapability;
|
|
5
|
+
exports.revokeAgentCapability = revokeAgentCapability;
|
|
6
|
+
exports._resetAgentCapabilitiesForTest = _resetAgentCapabilitiesForTest;
|
|
7
|
+
const crypto_1 = require("crypto");
|
|
8
|
+
const DEFAULT_TTL_MS = 6 * 60 * 60 * 1000;
|
|
9
|
+
const MAX_TTL_MS = DEFAULT_TTL_MS;
|
|
10
|
+
const CONVERSATION_ID_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
|
|
11
|
+
const capabilities = new Map();
|
|
12
|
+
function tokenHash(token) {
|
|
13
|
+
return (0, crypto_1.createHash)('sha256').update(token).digest('hex');
|
|
14
|
+
}
|
|
15
|
+
function pruneExpired(now = Date.now()) {
|
|
16
|
+
for (const [hash, capability] of capabilities) {
|
|
17
|
+
if (capability.expiresAt <= now)
|
|
18
|
+
capabilities.delete(hash);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function headerToken(value) {
|
|
22
|
+
const raw = Array.isArray(value) ? value[0] : value;
|
|
23
|
+
if (typeof raw !== 'string')
|
|
24
|
+
return null;
|
|
25
|
+
const token = raw.trim();
|
|
26
|
+
return token.length >= 32 && token.length <= 256 ? token : null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Mint an in-memory, per-turn capability. Only the hash is retained server-side;
|
|
30
|
+
* callers must revoke the returned secret when the owning AI process settles.
|
|
31
|
+
*/
|
|
32
|
+
function mintAgentCapability(input) {
|
|
33
|
+
if (!CONVERSATION_ID_RE.test(input.conversationId)) {
|
|
34
|
+
throw new Error(`unsafe agent conversation id: ${input.conversationId}`);
|
|
35
|
+
}
|
|
36
|
+
const ttl = Number.isFinite(input.ttlMs) && input.ttlMs > 0
|
|
37
|
+
? Math.min(Math.trunc(input.ttlMs), MAX_TTL_MS)
|
|
38
|
+
: DEFAULT_TTL_MS;
|
|
39
|
+
const now = Date.now();
|
|
40
|
+
pruneExpired(now);
|
|
41
|
+
const token = (0, crypto_1.randomBytes)(32).toString('base64url');
|
|
42
|
+
capabilities.set(tokenHash(token), {
|
|
43
|
+
conversationId: input.conversationId,
|
|
44
|
+
projectId: input.projectId?.trim() || null,
|
|
45
|
+
tierLevel: input.tierLevel,
|
|
46
|
+
expiresAt: now + ttl,
|
|
47
|
+
});
|
|
48
|
+
return token;
|
|
49
|
+
}
|
|
50
|
+
/** Resolve only capabilities minted by this process and still inside their TTL. */
|
|
51
|
+
function verifyAgentCapability(value) {
|
|
52
|
+
const token = headerToken(value);
|
|
53
|
+
if (!token)
|
|
54
|
+
return null;
|
|
55
|
+
const now = Date.now();
|
|
56
|
+
pruneExpired(now);
|
|
57
|
+
const found = capabilities.get(tokenHash(token));
|
|
58
|
+
if (!found || found.expiresAt <= now)
|
|
59
|
+
return null;
|
|
60
|
+
return { ...found };
|
|
61
|
+
}
|
|
62
|
+
/** Revoke a turn capability immediately; safe to call more than once. */
|
|
63
|
+
function revokeAgentCapability(token) {
|
|
64
|
+
if (!token)
|
|
65
|
+
return;
|
|
66
|
+
capabilities.delete(tokenHash(token));
|
|
67
|
+
}
|
|
68
|
+
/** Test seam: capabilities are process-local and must never bleed between cases. */
|
|
69
|
+
function _resetAgentCapabilitiesForTest() {
|
|
70
|
+
capabilities.clear();
|
|
71
|
+
}
|
package/server/dist/mcp/guide.js
CHANGED
|
@@ -150,8 +150,11 @@ heading inside the description); \`labels\`; \`priority\`. Spec content is Engli
|
|
|
150
150
|
slash-command job (e.g. \`/specrails:implement #5 --yes\`); \`queue\`, \`pause\`,
|
|
151
151
|
\`resume\`, \`reorder\`, \`priority\` manage the queue.
|
|
152
152
|
- Long-running shell commands launched with \`specrails_jobs(background_start)\`
|
|
153
|
-
create chat chips
|
|
154
|
-
|
|
153
|
+
create chat chips. Start/kill are destructive and available only to an
|
|
154
|
+
authenticated in-app Agent turn at Autonomous level after explicit user
|
|
155
|
+
confirmation; third-party MCP clients cannot invoke them. Use
|
|
156
|
+
\`specrails_jobs(background_logs, pid)\` to read bounded stdout/stderr tail
|
|
157
|
+
when a chip exits or fails.
|
|
155
158
|
|
|
156
159
|
## Async results (IMPORTANT)
|
|
157
160
|
|
|
@@ -12,6 +12,7 @@ const desktop_db_1 = require("../desktop-db");
|
|
|
12
12
|
const catalog_1 = require("./tools/catalog");
|
|
13
13
|
const types_1 = require("./tools/types");
|
|
14
14
|
const resources_1 = require("./resources");
|
|
15
|
+
const agent_capability_1 = require("./agent-capability");
|
|
15
16
|
function jsonRpcError(message, code = -32000) {
|
|
16
17
|
return { jsonrpc: '2.0', error: { code, message }, id: null };
|
|
17
18
|
}
|
|
@@ -89,16 +90,10 @@ class McpServerManager {
|
|
|
89
90
|
* carry the `mcp-session-id` header.
|
|
90
91
|
*/
|
|
91
92
|
async handleHttp(req, res) {
|
|
92
|
-
// The external Settings
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
// agent gets its MCP by default with zero config on a fresh install (the
|
|
97
|
-
// toggle defaults OFF). Third-party clients (no agent-tier header) still get
|
|
98
|
-
// 404 until the user explicitly opts in. Both paths already sit behind
|
|
99
|
-
// requireLoopback + requireMcpAuth (scoped token), so this is not an auth
|
|
100
|
-
// relaxation — only the enable-toggle is bypassed for the first-party agent.
|
|
101
|
-
const isFirstPartyAgent = Boolean(req.headers[agent_tier_1.AGENT_TIER_HEADER]);
|
|
93
|
+
// The external Settings toggle gates third-party clients. Only a live,
|
|
94
|
+
// server-minted per-turn capability identifies the in-app agent and may
|
|
95
|
+
// bypass it; caller-authored context headers grant no authority.
|
|
96
|
+
const isFirstPartyAgent = (0, agent_capability_1.verifyAgentCapability)(req.headers[agent_tier_1.AGENT_CAPABILITY_HEADER]) !== null;
|
|
102
97
|
if (!this.isEnabledSetting() && !isFirstPartyAgent) {
|
|
103
98
|
res.status(404).json(jsonRpcError('MCP is disabled. Enable it in the Specrails app under Settings ▸ MCP.', -32004));
|
|
104
99
|
return;
|
|
@@ -8,11 +8,11 @@ exports.getMcpToken = getMcpToken;
|
|
|
8
8
|
exports.regenerateMcpToken = regenerateMcpToken;
|
|
9
9
|
exports.requireMcpAuth = requireMcpAuth;
|
|
10
10
|
exports._resetMcpTokenForTest = _resetMcpTokenForTest;
|
|
11
|
-
const fs_1 = __importDefault(require("fs"));
|
|
12
11
|
const path_1 = __importDefault(require("path"));
|
|
13
12
|
const os_1 = __importDefault(require("os"));
|
|
14
13
|
const crypto_1 = require("crypto");
|
|
15
14
|
const auth_1 = require("../auth");
|
|
15
|
+
const secure_token_file_1 = require("../util/secure-token-file");
|
|
16
16
|
// ─── MCP-scoped token (design D3) ─────────────────────────────────────────────
|
|
17
17
|
//
|
|
18
18
|
// The MCP surface is authenticated by a token SEPARATE from the all-powerful
|
|
@@ -49,8 +49,9 @@ function loadOrGenerateMcpToken() {
|
|
|
49
49
|
if (_mcpToken)
|
|
50
50
|
return _mcpToken;
|
|
51
51
|
try {
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
const stored = (0, secure_token_file_1.readPrivateTextFile)(tokenPath());
|
|
53
|
+
if (stored !== null) {
|
|
54
|
+
const t = stored.trim();
|
|
54
55
|
if (t && t.length >= 32) {
|
|
55
56
|
_mcpToken = t;
|
|
56
57
|
return _mcpToken;
|
|
@@ -66,8 +67,7 @@ function loadOrGenerateMcpToken() {
|
|
|
66
67
|
}
|
|
67
68
|
function persist(token) {
|
|
68
69
|
try {
|
|
69
|
-
|
|
70
|
-
fs_1.default.writeFileSync(tokenPath(), token, { encoding: 'utf-8', mode: 0o600 });
|
|
70
|
+
(0, secure_token_file_1.writePrivateTextFile)(tokenPath(), token);
|
|
71
71
|
}
|
|
72
72
|
catch (err) {
|
|
73
73
|
console.warn('[mcp] could not persist mcp token to disk:', err);
|
|
@@ -17,6 +17,12 @@ function resolveBackgroundCwd(projectRoot, cwd) {
|
|
|
17
17
|
}
|
|
18
18
|
return resolved;
|
|
19
19
|
}
|
|
20
|
+
function requireFirstPartyConversation(ctx, action) {
|
|
21
|
+
if (!ctx.firstPartyAgent || !ctx.originConversationId) {
|
|
22
|
+
throw new Error(`${action} is available only to an authenticated in-app agent turn.`);
|
|
23
|
+
}
|
|
24
|
+
return ctx.originConversationId;
|
|
25
|
+
}
|
|
20
26
|
function backgroundHooks(broadcast) {
|
|
21
27
|
return {
|
|
22
28
|
onStarted: (process) => broadcast({
|
|
@@ -64,8 +70,8 @@ function jobsTools() {
|
|
|
64
70
|
title: 'Jobs & Queue',
|
|
65
71
|
description: 'Manage a project\'s AI-pipeline job queue and individual jobs. ' +
|
|
66
72
|
'Actions: list, get, queue, spawn (ai-spawn — enqueues an arbitrary slash-command job, returns {jobId,position}, async; from the in-app agent chat the engine defaults to your conversation\'s provider — pass aiEngine to override), ' +
|
|
67
|
-
'background_start (
|
|
68
|
-
'cancel (destructive —
|
|
73
|
+
'background_start (in-app-agent-only destructive shell command tied to the authenticated chat; requires confirmed:true after explicit user confirmation), background_logs, background_kill (in-app-agent-only destructive), ' +
|
|
74
|
+
'cancel (destructive — requests cancellation of a running/queued job; it does not delete terminal history), ' +
|
|
69
75
|
'purge (destructive — bulk-delete persisted job rows in a date range), ' +
|
|
70
76
|
'pause / resume (queue), reorder (queued-job order), priority (change a queued job\'s priority), ' +
|
|
71
77
|
'compare (two jobs side-by-side), export (up to 10k rows as JSON/CSV — inlines everything; prefer list/stats for token economy), ' +
|
|
@@ -77,9 +83,9 @@ function jobsTools() {
|
|
|
77
83
|
hintTier: 'read',
|
|
78
84
|
tier: (a) => {
|
|
79
85
|
const action = a.action;
|
|
80
|
-
if (['cancel', 'purge'].includes(action))
|
|
86
|
+
if (['cancel', 'purge', 'background_start', 'background_kill'].includes(action))
|
|
81
87
|
return 'destructive';
|
|
82
|
-
if (['spawn', 'interactive_turn'
|
|
88
|
+
if (['spawn', 'interactive_turn'].includes(action))
|
|
83
89
|
return 'ai-spawn';
|
|
84
90
|
if (['pause', 'resume', 'reorder', 'priority', 'finalize'].includes(action))
|
|
85
91
|
return 'write';
|
|
@@ -147,7 +153,7 @@ function jobsTools() {
|
|
|
147
153
|
.describe('reorder: exact set of currently-queued job ids in the desired order; compare: exactly 2 job ids'),
|
|
148
154
|
// ── interactive_turn ──
|
|
149
155
|
text: zod_1.z.string().optional().describe('Prompt text for interactive_turn'),
|
|
150
|
-
chatId: zod_1.z.string().optional().describe('
|
|
156
|
+
chatId: zod_1.z.string().optional().describe('Conversation id for background_logs ownership. background_start/background_kill ignore this field and use the authenticated in-app capability.'),
|
|
151
157
|
cwd: zod_1.z.string().optional().describe('Optional cwd for background_start; resolved inside the selected project root'),
|
|
152
158
|
pid: zod_1.z.number().optional().describe('Background process pid for background_logs/background_kill'),
|
|
153
159
|
confirmed: zod_1.z.boolean().optional().describe('background_start only: must be true after explicit user confirmation for this exact command'),
|
|
@@ -214,7 +220,7 @@ function jobsTools() {
|
|
|
214
220
|
const id = args.jobId;
|
|
215
221
|
if (!id)
|
|
216
222
|
throw new Error('cancel requires a "jobId".');
|
|
217
|
-
return (0, types_1.apiCall)(ctx, '
|
|
223
|
+
return (0, types_1.apiCall)(ctx, 'POST', `${base}/jobs/${encodeURIComponent(id)}/cancel`);
|
|
218
224
|
}
|
|
219
225
|
case 'purge':
|
|
220
226
|
return (0, types_1.apiCall)(ctx, 'DELETE', `${base}/jobs`, {
|
|
@@ -329,9 +335,7 @@ function jobsTools() {
|
|
|
329
335
|
throw new Error('background_start requires a "command".');
|
|
330
336
|
if (args.confirmed !== true)
|
|
331
337
|
throw new Error('background_start requires confirmed:true after explicit user confirmation for this exact command.');
|
|
332
|
-
const chatId =
|
|
333
|
-
if (!chatId || !chatId.trim())
|
|
334
|
-
throw new Error('background_start requires a "chatId".');
|
|
338
|
+
const chatId = requireFirstPartyConversation(ctx, 'background_start');
|
|
335
339
|
const projectCtx = (0, types_1.requireProject)(ctx, args.projectId);
|
|
336
340
|
const busyReason = backgroundStartBusyReason(projectCtx);
|
|
337
341
|
if (busyReason && args.allowWhileBusy !== true) {
|
|
@@ -345,9 +349,7 @@ function jobsTools() {
|
|
|
345
349
|
const pid = args.pid;
|
|
346
350
|
if (typeof pid !== 'number' || !Number.isFinite(pid))
|
|
347
351
|
throw new Error('background_kill requires a numeric "pid".');
|
|
348
|
-
const chatId =
|
|
349
|
-
if (!chatId || !chatId.trim())
|
|
350
|
-
throw new Error('background_kill requires a "chatId".');
|
|
352
|
+
const chatId = requireFirstPartyConversation(ctx, 'background_kill');
|
|
351
353
|
const projectCtx = (0, types_1.requireProject)(ctx, args.projectId);
|
|
352
354
|
const killed = (0, transient_children_1.killOwnedBackgroundProcess)(pid, { projectId: projectCtx.project.id, chatId: chatId.trim() });
|
|
353
355
|
if (!killed)
|
|
@@ -358,7 +360,12 @@ function jobsTools() {
|
|
|
358
360
|
const pid = args.pid;
|
|
359
361
|
if (typeof pid !== 'number' || !Number.isFinite(pid))
|
|
360
362
|
throw new Error('background_logs requires a numeric "pid".');
|
|
361
|
-
|
|
363
|
+
// A first-party turn is confined to its authenticated conversation
|
|
364
|
+
// for reads as well as start/kill. External read-tier clients still
|
|
365
|
+
// supply chatId explicitly because they have no agent capability.
|
|
366
|
+
const chatId = ctx.firstPartyAgent
|
|
367
|
+
? requireFirstPartyConversation(ctx, 'background_logs')
|
|
368
|
+
: args.chatId;
|
|
362
369
|
if (!chatId || !chatId.trim())
|
|
363
370
|
throw new Error('background_logs requires a "chatId".');
|
|
364
371
|
const projectCtx = (0, types_1.requireProject)(ctx, args.projectId);
|
|
@@ -11,9 +11,7 @@ const mcp_tiers_1 = require("../mcp-tiers");
|
|
|
11
11
|
const auth_1 = require("../../auth");
|
|
12
12
|
const agent_tier_1 = require("../../agent-tier");
|
|
13
13
|
const agent_store_1 = require("../../agent-store");
|
|
14
|
-
|
|
15
|
-
* rails-router validation so a sanitized id is never 400'd downstream. */
|
|
16
|
-
const ORIGIN_CONVERSATION_ID_RE = /^[A-Za-z0-9-]{1,64}$/;
|
|
14
|
+
const agent_capability_1 = require("../agent-capability");
|
|
17
15
|
/**
|
|
18
16
|
* Calls the app's own REST API over loopback using the MASTER token (held
|
|
19
17
|
* server-side, never exposed to the MCP client). This reuses every router's
|
|
@@ -51,7 +49,7 @@ function projectPath(ctx, projectId) {
|
|
|
51
49
|
}
|
|
52
50
|
/**
|
|
53
51
|
* Launch defaults derived from the LAUNCHING agent-chat conversation (the
|
|
54
|
-
* origin
|
|
52
|
+
* authenticated origin carried on `ctx.originConversationId`). When the in-app agent
|
|
55
53
|
* drives a rail launch / job spawn WITHOUT an explicit engine, the job must
|
|
56
54
|
* run on the CONVERSATION's provider — a codex conversation asking to
|
|
57
55
|
* implement must not silently launch claude via the router's fall-through to
|
|
@@ -91,16 +89,15 @@ function requireProject(ctx, projectId) {
|
|
|
91
89
|
}
|
|
92
90
|
// ── Active-project stickiness (per server process) ────────────────────────────
|
|
93
91
|
// The active project is a soft default; an explicit projectId always wins, and
|
|
94
|
-
// a per-request pin (ctx.requestProjectId, from the in-app
|
|
95
|
-
//
|
|
96
|
-
// `specrails_select_project
|
|
97
|
-
// per-turn pin) — request headers must never mutate this global.
|
|
92
|
+
// a per-request pin (ctx.requestProjectId, from the verified in-app capability)
|
|
93
|
+
// wins over the process-wide selection. `setActiveProject` remains for
|
|
94
|
+
// `specrails_select_project`; request context must never mutate this global.
|
|
98
95
|
let _activeProjectId = null;
|
|
99
96
|
function setActiveProject(id) {
|
|
100
97
|
_activeProjectId = id;
|
|
101
98
|
}
|
|
102
99
|
function getActiveProject(ctx) {
|
|
103
|
-
return ctx.requestProjectId
|
|
100
|
+
return ctx.requestProjectId !== undefined ? ctx.requestProjectId : _activeProjectId;
|
|
104
101
|
}
|
|
105
102
|
function tierAnnotations(tier) {
|
|
106
103
|
switch (tier) {
|
|
@@ -161,40 +158,21 @@ function registerTieredTool(server, ctx, spec) {
|
|
|
161
158
|
inputSchema: spec.inputSchema,
|
|
162
159
|
annotations: tierAnnotations(hintTier),
|
|
163
160
|
}, async (args, extra) => {
|
|
164
|
-
//
|
|
165
|
-
//
|
|
166
|
-
//
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
// Origin link (safe-pr-review-flow): the in-app agent's bridge forwards its
|
|
177
|
-
// conversation id so a rail launched by THIS CALL can be tagged with its
|
|
178
|
-
// origin. Same per-call copy discipline as the project header — and it must
|
|
179
|
-
// spread callCtx (not ctx) so a coexisting project pin is never dropped.
|
|
180
|
-
// Malformed ids sanitize to null (never throw — the launch degrades to
|
|
181
|
-
// untagged rather than failing the tool call).
|
|
182
|
-
const convHeader = extra?.requestInfo?.headers?.[agent_tier_1.AGENT_CONVERSATION_HEADER];
|
|
183
|
-
if (convHeader != null) {
|
|
184
|
-
const cid = Array.isArray(convHeader) ? convHeader[0] : convHeader;
|
|
185
|
-
const trimmed = typeof cid === 'string' ? cid.trim() : '';
|
|
186
|
-
callCtx = {
|
|
187
|
-
...callCtx,
|
|
188
|
-
originConversationId: trimmed && ORIGIN_CONVERSATION_ID_RE.test(trimmed) ? trimmed : null,
|
|
189
|
-
};
|
|
190
|
-
}
|
|
161
|
+
// Loopback identifies a machine, not a trusted caller. All first-party
|
|
162
|
+
// authority and context come from this unguessable, server-minted bearer;
|
|
163
|
+
// legacy tier/project/conversation headers are deliberately ignored.
|
|
164
|
+
const capability = (0, agent_capability_1.verifyAgentCapability)(extra?.requestInfo?.headers?.[agent_tier_1.AGENT_CAPABILITY_HEADER]);
|
|
165
|
+
const callCtx = capability
|
|
166
|
+
? {
|
|
167
|
+
...ctx,
|
|
168
|
+
requestProjectId: capability.projectId,
|
|
169
|
+
originConversationId: capability.conversationId,
|
|
170
|
+
firstPartyAgent: true,
|
|
171
|
+
}
|
|
172
|
+
: ctx;
|
|
191
173
|
const tier = typeof spec.tier === 'function' ? spec.tier(args ?? {}) : spec.tier;
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
// (design D4). Absent header → external client → unchanged Settings gate.
|
|
195
|
-
const agentLevel = (0, agent_tier_1.levelFromHeader)(extra?.requestInfo?.headers?.[agent_tier_1.AGENT_TIER_HEADER]);
|
|
196
|
-
if (agentLevel !== null) {
|
|
197
|
-
if (!(0, agent_tier_1.levelAllowsTier)(agentLevel, tier)) {
|
|
174
|
+
if (capability) {
|
|
175
|
+
if (!(0, agent_tier_1.levelAllowsTier)(capability.tierLevel, tier)) {
|
|
198
176
|
return errorResult((0, mcp_tiers_1.tierRefusalMessage)(tier));
|
|
199
177
|
}
|
|
200
178
|
}
|
|
@@ -232,7 +232,7 @@ function createMobileRouter(deps) {
|
|
|
232
232
|
const pid = seg(req.params.pid), jid = seg(req.params.jid);
|
|
233
233
|
if (!validate(res, [pid, PID_RE], [jid, JOBID_RE]))
|
|
234
234
|
return;
|
|
235
|
-
void forward(res, '
|
|
235
|
+
void forward(res, 'POST', `/api/projects/${encodeURIComponent(pid)}/jobs/${encodeURIComponent(jid)}/cancel`, '');
|
|
236
236
|
});
|
|
237
237
|
v1.post('/projects/:pid/queue/pause', (req, res) => {
|
|
238
238
|
const pid = seg(req.params.pid);
|