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
|
@@ -27,7 +27,9 @@ const rail_worktree_release_1 = require("./rail-worktree-release");
|
|
|
27
27
|
const project_git_1 = require("./project-git");
|
|
28
28
|
const pr_publisher_1 = require("./pr-publisher");
|
|
29
29
|
const ids_1 = require("./ids");
|
|
30
|
+
const repo_lock_1 = require("./repo-lock");
|
|
30
31
|
const agent_chat_registry_1 = require("./agent-chat-registry");
|
|
32
|
+
const process_admission_1 = require("./process-admission");
|
|
31
33
|
const VALID_MODES = new Set(['implement', 'batch-implement', 'freestyle', 'loop']);
|
|
32
34
|
// Models the freestyle picker exposes (Claude aliases). Mirrors the client
|
|
33
35
|
// RailModelSelector options and the project-router orchestrator-model allow-list.
|
|
@@ -41,7 +43,8 @@ function prDeliveryContinuesTickets(delivery, ticketIds) {
|
|
|
41
43
|
if (!delivery.prUrl || !delivery.branch || delivery.prState !== 'pr-created')
|
|
42
44
|
return false;
|
|
43
45
|
const covered = new Set(delivery.ticketIds);
|
|
44
|
-
|
|
46
|
+
const requested = new Set(ticketIds);
|
|
47
|
+
return requested.size > 0 && requested.size === covered.size && [...requested].every((id) => covered.has(id));
|
|
45
48
|
}
|
|
46
49
|
function emitPrDeliveryUpdate(c, prDeliveryId) {
|
|
47
50
|
const row = (0, rail_pr_store_1.getPrDelivery)(c.db, prDeliveryId);
|
|
@@ -53,11 +56,6 @@ function emitPrDeliveryUpdate(c, prDeliveryId) {
|
|
|
53
56
|
(0, agent_chat_registry_1.getAgentChatManager)()?.updatePrDecisionCard(row.origin_conversation_id, (0, rail_pr_store_1.toPrDecisionCardEnvelope)(c.project.id, snap));
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
|
-
function reconcileAndEmitFailedPrDeliveries(c) {
|
|
57
|
-
for (const row of (0, rail_pr_store_1.reconcileFailedBuildingPrDeliveries)(c.db)) {
|
|
58
|
-
emitPrDeliveryUpdate(c, row.id);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
59
|
function createRailsRouter() {
|
|
62
60
|
const router = (0, express_1.Router)({ mergeParams: true });
|
|
63
61
|
function ctx(req) {
|
|
@@ -121,7 +119,6 @@ function createRailsRouter() {
|
|
|
121
119
|
// (non-terminal) delivery per rail slot, so a refreshed client re-renders
|
|
122
120
|
// the decision surface without waiting for a broadcast. The store lists
|
|
123
121
|
// newest-first within each rail — keep the first per index.
|
|
124
|
-
reconcileAndEmitFailedPrDeliveries(c);
|
|
125
122
|
const prDeliveries = {};
|
|
126
123
|
for (const row of (0, rail_pr_store_1.listActivePrDeliveries)(c.db)) {
|
|
127
124
|
if (!(row.rail_index in prDeliveries))
|
|
@@ -166,10 +163,11 @@ function createRailsRouter() {
|
|
|
166
163
|
res.status(500).json({ error: 'Failed to create rail' });
|
|
167
164
|
}
|
|
168
165
|
});
|
|
169
|
-
// DELETE /rails/:railIndex — remove a rail slot
|
|
170
|
-
//
|
|
171
|
-
//
|
|
172
|
-
//
|
|
166
|
+
// DELETE /rails/:railIndex — remove a rail slot and release its ticket
|
|
167
|
+
// assignments as one transaction. All rejection guards run before the
|
|
168
|
+
// delete, so a failed last/active/pending-PR deletion cannot strand tickets
|
|
169
|
+
// in an unassigned intermediate state. Indices are identity — deleting a
|
|
170
|
+
// middle rail leaves a gap (never re-numbered).
|
|
173
171
|
router.delete('/:railIndex', (req, res) => {
|
|
174
172
|
const railIndex = parseInt(req.params.railIndex, 10);
|
|
175
173
|
if (isNaN(railIndex) || railIndex < 0 || railIndex >= rails_store_1.MAX_RAILS) {
|
|
@@ -192,10 +190,6 @@ function createRailsRouter() {
|
|
|
192
190
|
res.status(409).json({ error: 'rail_active' });
|
|
193
191
|
return;
|
|
194
192
|
}
|
|
195
|
-
if ((0, rails_store_1.getRail)(c.db, railIndex).ticketIds.length > 0) {
|
|
196
|
-
res.status(409).json({ error: 'rail_not_empty' });
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
193
|
const pending = (0, rail_pr_store_1.getActivePrDeliveryByRail)(c.db, railIndex);
|
|
200
194
|
if (pending) {
|
|
201
195
|
res.status(409).json({ error: 'pr_decision_pending', prDeliveryId: pending.id });
|
|
@@ -405,6 +399,16 @@ function createRailsRouter() {
|
|
|
405
399
|
// capability) decides, so the launch no longer passes an explicit flag. A
|
|
406
400
|
// legacy `interactive` body param is accepted and ignored (wire compat).
|
|
407
401
|
const c = ctx(req);
|
|
402
|
+
try {
|
|
403
|
+
(0, process_admission_1.assertProcessAdmission)(c.project.id);
|
|
404
|
+
}
|
|
405
|
+
catch (err) {
|
|
406
|
+
if (err instanceof process_admission_1.ProcessAdmissionClosedError) {
|
|
407
|
+
res.status(409).json({ error: 'project_recovery_in_progress' });
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
throw err;
|
|
411
|
+
}
|
|
408
412
|
const rail = (0, rails_store_1.getRail)(c.db, railIndex);
|
|
409
413
|
if (rail.ticketIds.length === 0) {
|
|
410
414
|
res.status(400).json({ error: 'Rail has no tickets assigned' });
|
|
@@ -543,31 +547,47 @@ function createRailsRouter() {
|
|
|
543
547
|
// client so a silent fallback (no delivery row → no implementation
|
|
544
548
|
// cards) is diagnosable from the UI, not just the server log.
|
|
545
549
|
let isolationUnavailableDetail;
|
|
546
|
-
let
|
|
547
|
-
let fallbackPrDeliveryId = null;
|
|
550
|
+
let continuablePrDelivery = null;
|
|
548
551
|
// Read-only vs mutating is DERIVED from the loop's nodes (see loop-effect),
|
|
549
552
|
// not a user flag — a content-read-only loop (no ai-step/shell) never writes,
|
|
550
553
|
// so it is not isolated; anything that can write is.
|
|
551
554
|
const loopReadOnly = (0, loop_effect_1.classifyLoopEffect)(loopGraph) === 'read-only';
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
if ((
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
if (pendingSnapshot && !prDeliveryContinuesTickets(pendingSnapshot, rail.ticketIds)) {
|
|
562
|
-
res.status(409).json({ error: 'pr_decision_pending', prDeliveryId: pendingSnapshot.id });
|
|
563
|
-
return;
|
|
564
|
-
}
|
|
565
|
-
continuablePrDeliveryForFallback = pendingSnapshot;
|
|
555
|
+
// Relaunch collision (ask-first PR delivery): this guard must run even
|
|
556
|
+
// when the worktree kill-switch is off. Otherwise a published PR follow-
|
|
557
|
+
// up silently drops to shared cwd and can commit on the ambient branch.
|
|
558
|
+
if ((0, rail_isolation_1.isRailPrDeliveryEnabled)()) {
|
|
559
|
+
const pending = (0, rail_pr_store_1.getActivePrDeliveryByRail)(c.db, railIndex);
|
|
560
|
+
const pendingSnapshot = pending ? (0, rail_pr_store_1.toPrDeliverySnapshot)(pending) : null;
|
|
561
|
+
if (pendingSnapshot && !prDeliveryContinuesTickets(pendingSnapshot, rail.ticketIds)) {
|
|
562
|
+
res.status(409).json({ error: 'pr_decision_pending', prDeliveryId: pendingSnapshot.id });
|
|
563
|
+
return;
|
|
566
564
|
}
|
|
565
|
+
continuablePrDelivery = pendingSnapshot;
|
|
566
|
+
}
|
|
567
|
+
const useIsolation = (0, rail_isolation_1.isolationApplies)({
|
|
568
|
+
loopsEnabled: (0, feature_flags_1.isLoopsEnabled)(), scope, ticketCount: rail.ticketIds.length, readOnly: loopReadOnly,
|
|
569
|
+
});
|
|
570
|
+
if (continuablePrDelivery && !loopReadOnly && !useIsolation) {
|
|
571
|
+
res.status(409).json({
|
|
572
|
+
error: 'pr_continuation_isolation_required',
|
|
573
|
+
detail: `Cannot continue PR branch ${continuablePrDelivery.branch} while worktree isolation is disabled.`,
|
|
574
|
+
action: 'Enable rail worktrees and retry; PR continuations never run in the shared project checkout.',
|
|
575
|
+
});
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
if (useIsolation) {
|
|
567
579
|
// Worktree isolation needs a git repo WITH at least one commit (an
|
|
568
580
|
// unborn HEAD can't be branched). Fall back (with a message) otherwise.
|
|
569
581
|
const status = await (0, worktree_manager_1.repoIsolationStatus)(worktree_manager_1.defaultGitRunner, c.project.path);
|
|
570
582
|
if (status !== 'ok') {
|
|
583
|
+
if (continuablePrDelivery) {
|
|
584
|
+
res.status(409).json({
|
|
585
|
+
error: 'pr_continuation_isolation_required',
|
|
586
|
+
detail: `Cannot continue PR branch ${continuablePrDelivery.branch} because worktree isolation is unavailable (${status}).`,
|
|
587
|
+
action: 'Restore a git repository with a committed HEAD, ensure the PR branch is free for a dedicated worktree, then retry.',
|
|
588
|
+
});
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
571
591
|
isolationUnavailable = status; // 'no-git' | 'no-commits'
|
|
572
592
|
console.warn(`[rails-router] worktree isolation unavailable (${status}); running shared cwd`);
|
|
573
593
|
}
|
|
@@ -578,13 +598,36 @@ function createRailsRouter() {
|
|
|
578
598
|
provider: loopProvider, model: loopModel, effort, scope,
|
|
579
599
|
originSurface: originSurface ?? 'dashboard',
|
|
580
600
|
originConversationId: originConversationId ?? null,
|
|
581
|
-
|
|
582
|
-
|
|
601
|
+
...(continuablePrDelivery ? {
|
|
602
|
+
requiredPrContinuation: {
|
|
603
|
+
deliveryId: continuablePrDelivery.id,
|
|
604
|
+
decision: continuablePrDelivery.decision,
|
|
605
|
+
branch: continuablePrDelivery.branch,
|
|
606
|
+
prUrl: continuablePrDelivery.prUrl,
|
|
607
|
+
prNumber: continuablePrDelivery.prNumber,
|
|
608
|
+
},
|
|
609
|
+
} : {}),
|
|
583
610
|
});
|
|
584
611
|
res.status(202).json({ loopRunIds: ids, railIndex, mode, isolated: true });
|
|
585
612
|
return;
|
|
586
613
|
}
|
|
587
614
|
catch (err) {
|
|
615
|
+
if (err instanceof rail_pr_store_1.PrDeliveryGenerationConflict) {
|
|
616
|
+
res.status(409).json({
|
|
617
|
+
error: 'pr_delivery_generation_conflict',
|
|
618
|
+
prDeliveryId: err.currentId,
|
|
619
|
+
});
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
if (continuablePrDelivery || err instanceof rail_isolated_launch_1.PrContinuationIsolationError) {
|
|
623
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
624
|
+
res.status(409).json({
|
|
625
|
+
error: 'pr_continuation_isolation_required',
|
|
626
|
+
detail,
|
|
627
|
+
action: 'Ensure the PR branch is available for a dedicated git worktree, then retry.',
|
|
628
|
+
});
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
588
631
|
console.error('[rails-router] isolated launch failed; falling back to shared cwd:', err);
|
|
589
632
|
isolationUnavailable = 'error';
|
|
590
633
|
isolationUnavailableDetail = err instanceof Error ? err.message : String(err);
|
|
@@ -596,9 +639,9 @@ function createRailsRouter() {
|
|
|
596
639
|
// via SPECRAILS_REPO_DIR + `--add-dir` exactly like QueueManager.
|
|
597
640
|
const loopExec = (0, workspace_resolution_1.resolveProjectExecution)({ slug: c.project.slug, path: c.project.path });
|
|
598
641
|
const loopRunIds = [];
|
|
599
|
-
const
|
|
642
|
+
const loopTicketCompletionStatus = (0, rail_isolation_1.isRailPrDeliveryEnabled)() ? 'on_review' : 'done';
|
|
600
643
|
const launchLoopRun = (runId, ticketIds, spec) => {
|
|
601
|
-
c.railLoopRuns.set(runId, { railIndex, ticketIds });
|
|
644
|
+
c.railLoopRuns.set(runId, { railIndex, ticketIds, requiresTerminalIntent: true });
|
|
602
645
|
// Code-Explorer provenance for shared-cwd loop runs (isolated runs
|
|
603
646
|
// record inside rail-isolated-launch): snapshot the REPO before the
|
|
604
647
|
// run, diff + record at settle. Loop runs settle outside QueueManager,
|
|
@@ -641,6 +684,7 @@ function createRailsRouter() {
|
|
|
641
684
|
railIndex,
|
|
642
685
|
ticketId: ticketIds[0],
|
|
643
686
|
spec: spec ? { ...spec, ticketIds } : { ticketIds },
|
|
687
|
+
ticketCompletionStatus: loopTicketCompletionStatus,
|
|
644
688
|
constants: (0, loop_constants_1.loadConstantMap)(c.desktopDb),
|
|
645
689
|
provider: loopProvider,
|
|
646
690
|
model: loopModel,
|
|
@@ -657,7 +701,7 @@ function createRailsRouter() {
|
|
|
657
701
|
c.onLoopRunFinished(runId, 'failed');
|
|
658
702
|
return false;
|
|
659
703
|
});
|
|
660
|
-
|
|
704
|
+
void runPromise;
|
|
661
705
|
loopRunIds.push(runId);
|
|
662
706
|
try {
|
|
663
707
|
c.jiraSyncManager.onRailLaunch(ticketIds, runId);
|
|
@@ -675,53 +719,6 @@ function createRailsRouter() {
|
|
|
675
719
|
launchLoopRun((0, ids_1.newId)(), [ticketId], c.getTicketSpec(ticketId));
|
|
676
720
|
}
|
|
677
721
|
}
|
|
678
|
-
if (fallbackPrDeliveryId) {
|
|
679
|
-
const row = (0, rail_pr_store_1.getPrDelivery)(c.db, fallbackPrDeliveryId);
|
|
680
|
-
const isExistingPrIteration = row?.decision === 'building' && row.pr_state === 'pr-created' && Boolean(row.pr_url && row.branch);
|
|
681
|
-
if (isExistingPrIteration) {
|
|
682
|
-
if ((0, rail_pr_store_1.transitionDecision)(c.db, fallbackPrDeliveryId, 'building', 'building', { runIds: loopRunIds })) {
|
|
683
|
-
emitPrDeliveryUpdate(c, fallbackPrDeliveryId);
|
|
684
|
-
}
|
|
685
|
-
void Promise.allSettled(sharedRunSettles).then((settled) => {
|
|
686
|
-
void (async () => {
|
|
687
|
-
const current = (0, rail_pr_store_1.getPrDelivery)(c.db, fallbackPrDeliveryId);
|
|
688
|
-
if (current?.decision !== 'building')
|
|
689
|
-
return;
|
|
690
|
-
if (current.pr_state === 'pr-created' && current.pr_url && current.branch) {
|
|
691
|
-
const succeeded = settled.every((s) => s.status === 'fulfilled' && s.value === true);
|
|
692
|
-
if (!succeeded) {
|
|
693
|
-
if ((0, rail_pr_store_1.transitionDecision)(c.db, fallbackPrDeliveryId, 'building', 'implementation_failed')) {
|
|
694
|
-
emitPrDeliveryUpdate(c, fallbackPrDeliveryId);
|
|
695
|
-
}
|
|
696
|
-
return;
|
|
697
|
-
}
|
|
698
|
-
await (0, worktree_manager_1.commitWorktree)(worktree_manager_1.defaultGitRunner, c.project.path, `specrails: PR follow-up (${loopRunIds.join(', ')})`);
|
|
699
|
-
const pushed = await (0, pr_publisher_1.pushBranch)(pr_publisher_1.defaultExec, {
|
|
700
|
-
repoDir: c.project.path,
|
|
701
|
-
branch: current.branch,
|
|
702
|
-
baseBranch: current.base_branch,
|
|
703
|
-
});
|
|
704
|
-
if (pushed.state === 'local-only') {
|
|
705
|
-
if ((0, rail_pr_store_1.transitionDecision)(c.db, fallbackPrDeliveryId, 'building', 'pr_failed', { prState: 'local-only' })) {
|
|
706
|
-
emitPrDeliveryUpdate(c, fallbackPrDeliveryId);
|
|
707
|
-
}
|
|
708
|
-
return;
|
|
709
|
-
}
|
|
710
|
-
if ((0, rail_pr_store_1.transitionDecision)(c.db, fallbackPrDeliveryId, 'building', 'pr_ready', { prState: 'pr-created' })) {
|
|
711
|
-
emitPrDeliveryUpdate(c, fallbackPrDeliveryId);
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
})().catch((err) => {
|
|
715
|
-
console.error('[rails-router] existing PR fallback push failed:', err);
|
|
716
|
-
if (fallbackPrDeliveryId) {
|
|
717
|
-
if ((0, rail_pr_store_1.transitionDecision)(c.db, fallbackPrDeliveryId, 'building', 'pr_failed', { prState: 'local-only' })) {
|
|
718
|
-
emitPrDeliveryUpdate(c, fallbackPrDeliveryId);
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
});
|
|
722
|
-
});
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
722
|
res.status(202).json({
|
|
726
723
|
loopRunIds, railIndex, mode,
|
|
727
724
|
...(isolationUnavailable ? { isolationUnavailable } : {}),
|
|
@@ -883,7 +880,8 @@ function createRailsRouter() {
|
|
|
883
880
|
});
|
|
884
881
|
// POST /rails/pr-decision — the ONE decision action (safe-pr-review-flow) both
|
|
885
882
|
// surfaces (dashboard rail row + agent-chat card) call on a rail_pr_deliveries
|
|
886
|
-
// row: create-pr | publish | discard | poll
|
|
883
|
+
// row: create-pr | publish | discard/dismiss | poll/reopen | merge-local |
|
|
884
|
+
// acknowledge-no-changes, compare-and-set-guarded by
|
|
887
885
|
// expectedDecision (a raced concurrent answer loses with 409 stale_decision).
|
|
888
886
|
// Replaces the stateless v1 POST /rails/pr-review passthrough. The route only
|
|
889
887
|
// validates and delegates — the action logic lives in rail-pr-decision.ts.
|
|
@@ -896,7 +894,7 @@ function createRailsRouter() {
|
|
|
896
894
|
return;
|
|
897
895
|
}
|
|
898
896
|
if (!(0, rail_pr_decision_1.isPrDecisionAction)(action)) {
|
|
899
|
-
res.status(400).json({ error: "action must be 'create-pr', 'publish', 'discard'
|
|
897
|
+
res.status(400).json({ error: "action must be 'create-pr', 'publish', 'discard', 'dismiss', 'poll-merge', 'reopen', 'merge-local' or 'acknowledge-no-changes'" });
|
|
900
898
|
return;
|
|
901
899
|
}
|
|
902
900
|
if (typeof expectedDecision !== 'string' || !expectedDecision) {
|
|
@@ -904,17 +902,40 @@ function createRailsRouter() {
|
|
|
904
902
|
return;
|
|
905
903
|
}
|
|
906
904
|
try {
|
|
907
|
-
const
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
905
|
+
const admission = (0, process_admission_1.captureProcessAdmission)(c.project.id);
|
|
906
|
+
const execute = () => {
|
|
907
|
+
admission.assertCurrent();
|
|
908
|
+
return (0, rail_pr_decision_1.executePrDecision)({
|
|
909
|
+
db: c.db,
|
|
910
|
+
project: { id: c.project.id, slug: c.project.slug, path: c.project.path },
|
|
911
|
+
git: worktree_manager_1.defaultGitRunner,
|
|
912
|
+
exec: pr_publisher_1.defaultExec,
|
|
913
|
+
broadcast: c.broadcast,
|
|
914
|
+
jiraSyncManager: c.jiraSyncManager,
|
|
915
|
+
assertAdmission: () => admission.assertCurrent(),
|
|
916
|
+
}, { prDeliveryId, action, expectedDecision });
|
|
917
|
+
};
|
|
918
|
+
// Every decision that can touch refs/worktrees shares the same project
|
|
919
|
+
// mutex as startup reconciliation, launch allocation and checkout. Local
|
|
920
|
+
// merge already acquires it internally to keep its guarded read/advance
|
|
921
|
+
// sequence atomic, so avoid nesting that non-reentrant lock.
|
|
922
|
+
const result = action === 'merge-local'
|
|
923
|
+
? await execute()
|
|
924
|
+
: await (0, repo_lock_1.withRepoLock)(c.project.path, execute);
|
|
925
|
+
// The durable row is authoritative. Return its post-action snapshot even
|
|
926
|
+
// when the WebSocket broadcast is dropped or another surface won the
|
|
927
|
+
// race; clients can converge immediately without optimistic inference.
|
|
928
|
+
const current = (0, rail_pr_store_1.getPrDelivery)(c.db, prDeliveryId);
|
|
929
|
+
res.status(result.status).json({
|
|
930
|
+
...result.body,
|
|
931
|
+
...(current ? { snapshot: (0, rail_pr_store_1.toPrDeliverySnapshot)(current) } : {}),
|
|
932
|
+
});
|
|
916
933
|
}
|
|
917
934
|
catch (err) {
|
|
935
|
+
if (err instanceof process_admission_1.ProcessAdmissionClosedError) {
|
|
936
|
+
res.status(409).json({ error: 'project_recovery_in_progress' });
|
|
937
|
+
return;
|
|
938
|
+
}
|
|
918
939
|
console.error('[rails-router] pr-decision error:', err);
|
|
919
940
|
res.status(500).json({ error: 'pr-decision failed', detail: err.message });
|
|
920
941
|
}
|
|
@@ -931,6 +952,17 @@ function createRailsRouter() {
|
|
|
931
952
|
res.status(400).json({ error: 'prDeliveryId is required' });
|
|
932
953
|
return;
|
|
933
954
|
}
|
|
955
|
+
let admission;
|
|
956
|
+
try {
|
|
957
|
+
admission = (0, process_admission_1.captureProcessAdmission)(c.project.id);
|
|
958
|
+
}
|
|
959
|
+
catch (err) {
|
|
960
|
+
if (err instanceof process_admission_1.ProcessAdmissionClosedError) {
|
|
961
|
+
res.status(409).json({ error: 'project_recovery_in_progress' });
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
throw err;
|
|
965
|
+
}
|
|
934
966
|
const row = (0, rail_pr_store_1.getPrDelivery)(c.db, prDeliveryId);
|
|
935
967
|
if (!row) {
|
|
936
968
|
res.status(404).json({ error: 'Unknown prDeliveryId' });
|
|
@@ -942,27 +974,32 @@ function createRailsRouter() {
|
|
|
942
974
|
return;
|
|
943
975
|
}
|
|
944
976
|
try {
|
|
945
|
-
const
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
977
|
+
const outcome = await (0, repo_lock_1.withRepoLock)(c.project.path, async () => {
|
|
978
|
+
admission.assertCurrent();
|
|
979
|
+
const info = await (0, project_git_1.getProjectGitInfo)(c.project.path);
|
|
980
|
+
if (!info.git) {
|
|
981
|
+
return { ok: false, status: 409, error: 'checkout_unavailable', detail: 'project is not a git repository' };
|
|
982
|
+
}
|
|
983
|
+
if (info.dirty) {
|
|
984
|
+
return { ok: false, status: 409, error: 'checkout_dirty', detail: 'Working tree has uncommitted changes. Commit or stash them before checkout.' };
|
|
985
|
+
}
|
|
986
|
+
await (0, rail_worktree_release_1.releaseRailWorktrees)({
|
|
987
|
+
db: c.db,
|
|
988
|
+
git: worktree_manager_1.defaultGitRunner,
|
|
989
|
+
repoDir: c.project.path,
|
|
990
|
+
worktreeIds: snap.worktreeIds,
|
|
991
|
+
});
|
|
992
|
+
const checkedOut = await (0, project_git_1.checkoutProjectReviewBranch)(c.project.path, snap.branch);
|
|
993
|
+
if (!checkedOut.ok) {
|
|
994
|
+
return { ok: false, status: 409, error: 'checkout_failed', detail: checkedOut.error };
|
|
995
|
+
}
|
|
996
|
+
return { ok: true, git: await (0, project_git_1.getProjectGitInfo)(c.project.path) };
|
|
959
997
|
});
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
res.status(409).json({ error: 'checkout_failed', detail: result.error });
|
|
998
|
+
if (!outcome.ok) {
|
|
999
|
+
res.status(outcome.status).json({ error: outcome.error, detail: outcome.detail });
|
|
963
1000
|
return;
|
|
964
1001
|
}
|
|
965
|
-
res.json(
|
|
1002
|
+
res.json(outcome);
|
|
966
1003
|
}
|
|
967
1004
|
catch (err) {
|
|
968
1005
|
console.error('[rails-router] pr-checkout error:', err);
|
|
@@ -8,6 +8,10 @@ exports.railExists = railExists;
|
|
|
8
8
|
exports.getRails = getRails;
|
|
9
9
|
exports.getRail = getRail;
|
|
10
10
|
exports.setRailTickets = setRailTickets;
|
|
11
|
+
exports.claimRailTickets = claimRailTickets;
|
|
12
|
+
exports.claimTicketOutcomeOwners = claimTicketOutcomeOwners;
|
|
13
|
+
exports.ticketOutcomeOwner = ticketOutcomeOwner;
|
|
14
|
+
exports.releaseRailTicketsOwnedBy = releaseRailTicketsOwnedBy;
|
|
11
15
|
exports.setRailProfile = setRailProfile;
|
|
12
16
|
exports.setRailEngine = setRailEngine;
|
|
13
17
|
exports.createRail = createRail;
|
|
@@ -116,9 +120,107 @@ function setRailTickets(db, railIndex, ticketIds, mode, profileName, aiEngine) {
|
|
|
116
120
|
for (let i = 0; i < ticketIds.length; i++) {
|
|
117
121
|
insertStmt.run(railIndex, ticketIds[i], i, resolvedMode, resolvedProfile, resolvedEngine);
|
|
118
122
|
}
|
|
123
|
+
if (ticketIds.length === 0) {
|
|
124
|
+
db.prepare('DELETE FROM rail_ticket_ownership WHERE rail_index = ?').run(railIndex);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
const placeholders = ticketIds.map(() => '?').join(', ');
|
|
128
|
+
db.prepare(`DELETE FROM rail_ticket_ownership
|
|
129
|
+
WHERE rail_index = ? AND ticket_id NOT IN (${placeholders})`).run(railIndex, ...ticketIds);
|
|
130
|
+
}
|
|
119
131
|
})();
|
|
120
132
|
return { railIndex, ticketIds, mode: resolvedMode, profileName: resolvedProfile, aiEngine: resolvedEngine };
|
|
121
133
|
}
|
|
134
|
+
/** Claim the exact rail assignments for a concrete launch. Relaunching the
|
|
135
|
+
* same ticket advances its generation and replaces owner_id, so a delayed
|
|
136
|
+
* terminal replay from an older job/run cannot remove the new assignment. */
|
|
137
|
+
function claimRailTickets(db, railIndex, ticketIds, ownerId) {
|
|
138
|
+
const claim = db.prepare(`
|
|
139
|
+
INSERT INTO rail_ticket_ownership (
|
|
140
|
+
rail_index, ticket_id, owner_id, generation, claimed_at
|
|
141
|
+
) VALUES (?, ?, ?, 1, datetime('now'))
|
|
142
|
+
ON CONFLICT(rail_index, ticket_id) DO UPDATE SET
|
|
143
|
+
owner_id = excluded.owner_id,
|
|
144
|
+
generation = rail_ticket_ownership.generation + 1,
|
|
145
|
+
claimed_at = excluded.claimed_at
|
|
146
|
+
`);
|
|
147
|
+
db.transaction(() => {
|
|
148
|
+
for (const ticketId of [...new Set(ticketIds)]) {
|
|
149
|
+
claim.run(railIndex, ticketId, ownerId);
|
|
150
|
+
}
|
|
151
|
+
})();
|
|
152
|
+
}
|
|
153
|
+
/** Project-wide causal owner for ticket terminal effects. Unlike the JSON
|
|
154
|
+
* applied-effect marker, this claim participates in the same SQLite commit as
|
|
155
|
+
* queue/loop admission, so a hard crash cannot create a ghost filesystem owner
|
|
156
|
+
* or admit work without ownership. */
|
|
157
|
+
function claimTicketOutcomeOwners(db, ticketIds, ownerId) {
|
|
158
|
+
const claim = db.prepare(`
|
|
159
|
+
INSERT INTO ticket_outcome_ownership (
|
|
160
|
+
ticket_id, owner_id, generation, claimed_at
|
|
161
|
+
) VALUES (?, ?, 1, datetime('now'))
|
|
162
|
+
ON CONFLICT(ticket_id) DO UPDATE SET
|
|
163
|
+
owner_id = excluded.owner_id,
|
|
164
|
+
generation = ticket_outcome_ownership.generation + 1,
|
|
165
|
+
claimed_at = excluded.claimed_at
|
|
166
|
+
`);
|
|
167
|
+
for (const ticketId of [...new Set(ticketIds)])
|
|
168
|
+
claim.run(ticketId, ownerId);
|
|
169
|
+
}
|
|
170
|
+
function ticketOutcomeOwner(db, ticketId) {
|
|
171
|
+
try {
|
|
172
|
+
const row = db.prepare(`
|
|
173
|
+
SELECT owner_id FROM ticket_outcome_ownership WHERE ticket_id = ?
|
|
174
|
+
`).get(ticketId);
|
|
175
|
+
return row?.owner_id ?? null;
|
|
176
|
+
}
|
|
177
|
+
catch (err) {
|
|
178
|
+
// Compatibility only for isolated pre-migration schemas. Every other DB
|
|
179
|
+
// error must fail closed; treating corruption/closed handles as "legacy"
|
|
180
|
+
// would authorize a stale callback.
|
|
181
|
+
if (String(err?.message ?? err).includes('no such table: ticket_outcome_ownership')) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
throw err;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/** Release only assignments still owned by `ownerId`. `allowUnowned` exists
|
|
188
|
+
* solely for pre-migration live/recovery rows; new launches always claim and
|
|
189
|
+
* therefore fail closed when another generation has taken ownership. */
|
|
190
|
+
function releaseRailTicketsOwnedBy(db, ownerId, ticketIds, opts) {
|
|
191
|
+
const wanted = new Set(ticketIds);
|
|
192
|
+
if (wanted.size === 0)
|
|
193
|
+
return [];
|
|
194
|
+
const rails = opts?.railIndex == null ? getRails(db) : [getRail(db, opts.railIndex)];
|
|
195
|
+
const released = [];
|
|
196
|
+
db.transaction(() => {
|
|
197
|
+
for (const rail of rails) {
|
|
198
|
+
const removed = [];
|
|
199
|
+
for (const ticketId of rail.ticketIds) {
|
|
200
|
+
if (!wanted.has(ticketId))
|
|
201
|
+
continue;
|
|
202
|
+
const claim = db.prepare(`
|
|
203
|
+
SELECT owner_id FROM rail_ticket_ownership
|
|
204
|
+
WHERE rail_index = ? AND ticket_id = ?
|
|
205
|
+
`).get(rail.railIndex, ticketId);
|
|
206
|
+
if (claim?.owner_id === ownerId || (!claim && opts?.allowUnowned === true)) {
|
|
207
|
+
removed.push(ticketId);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (removed.length === 0)
|
|
211
|
+
continue;
|
|
212
|
+
const remaining = rail.ticketIds.filter((id) => !removed.includes(id));
|
|
213
|
+
const next = setRailTickets(db, rail.railIndex, remaining, rail.mode, rail.profileName, rail.aiEngine);
|
|
214
|
+
db.prepare(`
|
|
215
|
+
DELETE FROM rail_ticket_ownership
|
|
216
|
+
WHERE rail_index = ? AND owner_id = ?
|
|
217
|
+
AND ticket_id IN (${removed.map(() => '?').join(', ')})
|
|
218
|
+
`).run(rail.railIndex, ownerId, ...removed);
|
|
219
|
+
released.push({ rail: { ...next, name: rail.name }, releasedTicketIds: removed });
|
|
220
|
+
}
|
|
221
|
+
})();
|
|
222
|
+
return released;
|
|
223
|
+
}
|
|
122
224
|
/**
|
|
123
225
|
* Update only the profile for a rail, preserving tickets and mode.
|
|
124
226
|
* No-op (returns current state) when the rail has no tickets yet — the
|
|
@@ -167,14 +269,15 @@ function createRail(db, name) {
|
|
|
167
269
|
return { railIndex, ticketIds: [], mode: 'implement', profileName: null, aiEngine: null, name: value };
|
|
168
270
|
}
|
|
169
271
|
/**
|
|
170
|
-
* Delete a rail's identity + ticket
|
|
171
|
-
* the guards (rail exists,
|
|
172
|
-
* rail). Deleting a middle rail leaves a sparse index gap on purpose: indices
|
|
272
|
+
* Delete a rail's identity + ticket assignments atomically. Pure mechanism —
|
|
273
|
+
* the router enforces the guards (rail exists, idle, no pending PR decision,
|
|
274
|
+
* not the last rail) before calling it. Deleting a middle rail leaves a sparse index gap on purpose: indices
|
|
173
275
|
* are IDENTITY (metrics / pr-deliveries / worktree maps key by railIndex), so
|
|
174
276
|
* they are never compacted/re-numbered.
|
|
175
277
|
*/
|
|
176
278
|
function deleteRail(db, railIndex) {
|
|
177
279
|
db.transaction(() => {
|
|
280
|
+
db.prepare('DELETE FROM rail_ticket_ownership WHERE rail_index = ?').run(railIndex);
|
|
178
281
|
db.prepare('DELETE FROM rail_meta WHERE rail_index = ?').run(railIndex);
|
|
179
282
|
db.prepare('DELETE FROM rails WHERE rail_index = ?').run(railIndex);
|
|
180
283
|
})();
|
|
@@ -342,6 +342,25 @@ function applyJobOutcomeToTickets(store, ticketIds, outcome, now, opts) {
|
|
|
342
342
|
const ticket = store.tickets[String(tid)];
|
|
343
343
|
if (!ticket)
|
|
344
344
|
continue;
|
|
345
|
+
let effectState = ticket.metadata.specrails_outcome;
|
|
346
|
+
if (opts?.effectId) {
|
|
347
|
+
if (!effectState) {
|
|
348
|
+
effectState = {};
|
|
349
|
+
ticket.metadata.specrails_outcome = effectState;
|
|
350
|
+
}
|
|
351
|
+
// An exact replay is a no-op even if the user changed status afterwards.
|
|
352
|
+
if (effectState.applied_effect_id === opts.effectId)
|
|
353
|
+
continue;
|
|
354
|
+
// A newer launch owns the ticket. Never mutate that run's status. Keeping
|
|
355
|
+
// owner_id permanently (until the next launch replaces it) is O(1) and
|
|
356
|
+
// remains safe after arbitrarily many intervening executions.
|
|
357
|
+
if (!opts.causalOwnerConfirmed && effectState.owner_id && effectState.owner_id !== opts.effectId) {
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
// Legacy tickets have no owner; the first durable effect adopts them.
|
|
361
|
+
effectState.owner_id = opts.effectId;
|
|
362
|
+
effectState.applied_effect_id = opts.effectId;
|
|
363
|
+
}
|
|
345
364
|
if (outcome === 'completed') {
|
|
346
365
|
const promotable = ticket.status === 'todo' || ticket.status === 'in_progress';
|
|
347
366
|
const clearWarning = ticket.needs_review === true;
|
|
@@ -400,7 +419,10 @@ function extractTicketIdsFromCommand(command) {
|
|
|
400
419
|
const seen = new Set();
|
|
401
420
|
for (const match of command.matchAll(/#(\d+)/g)) {
|
|
402
421
|
const id = Number.parseInt(match[1], 10);
|
|
403
|
-
|
|
422
|
+
// Ticket ids are positive safe integers everywhere they cross the durable
|
|
423
|
+
// queue/recovery boundary. Reject 0 and overflow here so producers and
|
|
424
|
+
// replay validators can never disagree on the same command.
|
|
425
|
+
if (!Number.isSafeInteger(id) || id <= 0 || seen.has(id))
|
|
404
426
|
continue;
|
|
405
427
|
seen.add(id);
|
|
406
428
|
ids.push(id);
|
|
@@ -16,6 +16,7 @@ exports.killBackgroundProcessesForChat = killBackgroundProcessesForChat;
|
|
|
16
16
|
const tree_kill_1 = __importDefault(require("tree-kill"));
|
|
17
17
|
const child_process_1 = require("child_process");
|
|
18
18
|
const readline_1 = __importDefault(require("readline"));
|
|
19
|
+
const process_admission_1 = require("./process-admission");
|
|
19
20
|
/**
|
|
20
21
|
* Registry of fire-and-forget child processes that are NOT owned by a long-lived
|
|
21
22
|
* manager (QueueManager / ChatManager / SetupManager track their own). The Quick
|
|
@@ -58,6 +59,17 @@ function cloneLogLine(line) {
|
|
|
58
59
|
}
|
|
59
60
|
/** Track a child under a projectId; auto-removes itself on close. */
|
|
60
61
|
function trackTransientChild(projectId, child) {
|
|
62
|
+
try {
|
|
63
|
+
(0, process_admission_1.assertProcessAdmission)(projectId);
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
// A continuation may have spawned immediately before observing the closed
|
|
67
|
+
// project epoch. Never leave that child unowned simply because registration
|
|
68
|
+
// lost the teardown race.
|
|
69
|
+
if (child.pid)
|
|
70
|
+
treeKillSafe(child.pid, 'SIGTERM');
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
61
73
|
let set = byProject.get(projectId);
|
|
62
74
|
if (!set) {
|
|
63
75
|
set = new Set();
|
|
@@ -99,6 +111,7 @@ function killTransientChildren(projectId) {
|
|
|
99
111
|
}
|
|
100
112
|
}
|
|
101
113
|
function startBackgroundProcess(command, cwd, chatId, projectId, hooks) {
|
|
114
|
+
(0, process_admission_1.assertProcessAdmission)(projectId);
|
|
102
115
|
const child = (0, child_process_1.spawn)(command, {
|
|
103
116
|
cwd,
|
|
104
117
|
shell: true,
|