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
|
@@ -31,12 +31,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
31
31
|
exports.InteractiveJobSession = exports.UNKNOWN_COMMAND_RE = void 0;
|
|
32
32
|
exports.isModelWorkEvent = isModelWorkEvent;
|
|
33
33
|
exports.isZeroWorkSettle = isZeroWorkSettle;
|
|
34
|
+
const node_crypto_1 = require("node:crypto");
|
|
34
35
|
const node_readline_1 = require("node:readline");
|
|
35
36
|
const cli_prompt_1 = require("./util/cli-prompt");
|
|
37
|
+
const win_spawn_1 = require("./util/win-spawn");
|
|
36
38
|
const explore_stdin_session_1 = require("./explore-stdin-session");
|
|
37
39
|
const result_event_1 = require("./result-event");
|
|
38
40
|
const db_1 = require("./db");
|
|
39
41
|
const stream_display_1 = require("./util/stream-display");
|
|
42
|
+
/** Claude's stream-json result frames do not carry a turn id. Hash a canonical
|
|
43
|
+
* representation of the real frame instead: an exact/semantic retransmission
|
|
44
|
+
* remains identifiable even after the next stdin turn has been armed, while a
|
|
45
|
+
* genuine later result differs through its cumulative/session/result fields. */
|
|
46
|
+
function canonicalJson(value) {
|
|
47
|
+
if (value === null || typeof value !== 'object')
|
|
48
|
+
return JSON.stringify(value) ?? 'null';
|
|
49
|
+
if (Array.isArray(value))
|
|
50
|
+
return `[${value.map(canonicalJson).join(',')}]`;
|
|
51
|
+
const record = value;
|
|
52
|
+
return `{${Object.keys(record)
|
|
53
|
+
.sort()
|
|
54
|
+
.map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`)
|
|
55
|
+
.join(',')}}`;
|
|
56
|
+
}
|
|
57
|
+
function resultFrameSignature(frame) {
|
|
58
|
+
return (0, node_crypto_1.createHash)('sha256').update(canonicalJson(frame)).digest('hex');
|
|
59
|
+
}
|
|
40
60
|
/** The claude CLI's synthetic no-op marker: the result text of a frame emitted
|
|
41
61
|
* for a command the CLI could not resolve (nothing was sent to the model). */
|
|
42
62
|
exports.UNKNOWN_COMMAND_RE = /^Unknown command:/;
|
|
@@ -100,18 +120,22 @@ class InteractiveJobSession {
|
|
|
100
120
|
_settleMode;
|
|
101
121
|
_zombieTimeoutMs;
|
|
102
122
|
_nextEventSeq;
|
|
123
|
+
_persistTurnUsage;
|
|
124
|
+
_persistTurnActivity;
|
|
103
125
|
_spawn;
|
|
126
|
+
_killTree;
|
|
104
127
|
_child = null;
|
|
105
128
|
_stdoutReader = null;
|
|
106
129
|
_stderrReader = null;
|
|
107
130
|
_eventSeq = 0;
|
|
131
|
+
_lastPersistedEventSeq = -1;
|
|
108
132
|
_streaming = false;
|
|
109
133
|
/** True between writing a turn to stdin and receiving its `result` event.
|
|
110
134
|
* Guards _onTurnResult against double-counting a duplicate `result` frame. */
|
|
111
135
|
_awaitingResult = false;
|
|
112
|
-
/** Monotonic id assigned to each turn
|
|
113
|
-
*
|
|
114
|
-
*
|
|
136
|
+
/** Monotonic id assigned to each delivered turn. It gates one accepted result
|
|
137
|
+
* per active turn; canonical result signatures provide the cross-turn replay
|
|
138
|
+
* barrier because Claude's protocol does not expose a turn id. */
|
|
115
139
|
_turnSeq = 0;
|
|
116
140
|
/** The turn-id currently awaiting a `result` (== _turnSeq while streaming). */
|
|
117
141
|
_activeTurnId = 0;
|
|
@@ -120,6 +144,10 @@ class InteractiveJobSession {
|
|
|
120
144
|
_lastSettledTurnId = 0;
|
|
121
145
|
_pending = [];
|
|
122
146
|
_turnEvents = [];
|
|
147
|
+
/** Accepted result-frame signatures for this resident child. The protocol has
|
|
148
|
+
* no turn id, so this is the durable-in-process correlation barrier that keeps
|
|
149
|
+
* a retransmitted prior result out of a newly-armed turn. */
|
|
150
|
+
_acceptedResultSignatures = new Set();
|
|
123
151
|
_accum = zeroUsage();
|
|
124
152
|
_model = null;
|
|
125
153
|
_sessionId = null;
|
|
@@ -148,6 +176,12 @@ class InteractiveJobSession {
|
|
|
148
176
|
_finalizing = false;
|
|
149
177
|
_settled = false;
|
|
150
178
|
_disposed = false;
|
|
179
|
+
/** `ChildProcess.killed` only means a signal was sent. This tracks the real
|
|
180
|
+
* lifecycle event used to decide whether SIGKILL escalation is still needed. */
|
|
181
|
+
_childClosed = false;
|
|
182
|
+
_stdinFailed = false;
|
|
183
|
+
_terminationStarted = false;
|
|
184
|
+
_terminationReason = null;
|
|
151
185
|
_killTimer = null;
|
|
152
186
|
/** Auto-mode wedge detector (see InteractiveJobSessionDeps.zombieTimeoutMs). */
|
|
153
187
|
_zombieTimer = null;
|
|
@@ -161,7 +195,10 @@ class InteractiveJobSession {
|
|
|
161
195
|
this._settleMode = deps.settleMode ?? 'finalize';
|
|
162
196
|
this._zombieTimeoutMs = deps.zombieTimeoutMs ?? 0;
|
|
163
197
|
this._nextEventSeq = deps.nextEventSeq ?? null;
|
|
198
|
+
this._persistTurnUsage = deps.persistTurnUsage ?? null;
|
|
199
|
+
this._persistTurnActivity = deps.persistTurnActivity ?? null;
|
|
164
200
|
this._spawn = deps.spawn ?? cli_prompt_1.spawnAiCli;
|
|
201
|
+
this._killTree = deps.killTree ?? win_spawn_1.treeKillSafe;
|
|
165
202
|
}
|
|
166
203
|
/** Spawn the resident child and run the first turn (the freestyle prompt). */
|
|
167
204
|
start(spec, firstPrompt) {
|
|
@@ -172,6 +209,10 @@ class InteractiveJobSession {
|
|
|
172
209
|
cwd: spec.cwd,
|
|
173
210
|
});
|
|
174
211
|
this._child = child;
|
|
212
|
+
this._childClosed = false;
|
|
213
|
+
this._stdinFailed = false;
|
|
214
|
+
this._terminationStarted = false;
|
|
215
|
+
this._terminationReason = null;
|
|
175
216
|
// Absorb spawn 'error' (e.g. ENOENT) so it does not crash the process; the
|
|
176
217
|
// 'close' that follows settles the job as crashed through _handleClose.
|
|
177
218
|
child.on('error', (err) => {
|
|
@@ -185,7 +226,22 @@ class InteractiveJobSession {
|
|
|
185
226
|
this._stderrReader = (0, node_readline_1.createInterface)({ input: child.stderr, crlfDelay: Infinity });
|
|
186
227
|
this._stderrReader.on('line', (line) => this._handleStderrLine(line));
|
|
187
228
|
}
|
|
188
|
-
child.on('close', (code) =>
|
|
229
|
+
child.on('close', (code) => {
|
|
230
|
+
this._childClosed = true;
|
|
231
|
+
this._clearKillTimer();
|
|
232
|
+
this._handleClose(code);
|
|
233
|
+
});
|
|
234
|
+
// A buffered write can fail asynchronously (typically EPIPE after the child
|
|
235
|
+
// exits). `try/catch` around write() cannot observe that event, and an
|
|
236
|
+
// unhandled Writable 'error' terminates Node. Install this BEFORE the first
|
|
237
|
+
// `send()` below so even the initial frame is protected.
|
|
238
|
+
child.stdin?.on('error', (err) => {
|
|
239
|
+
this._stdinFailed = true;
|
|
240
|
+
console.error(`[interactive-job] stdin failed for ${this._jobId}: ${err.message}`);
|
|
241
|
+
if (this._disposed || this._settled)
|
|
242
|
+
return;
|
|
243
|
+
this._terminateChildTree(this._finalizing ? 'finalized' : 'crashed');
|
|
244
|
+
});
|
|
189
245
|
// Auto-mode wedge detector: reset on ANY raw output ('data' — synchronous
|
|
190
246
|
// under fake timers, mirroring the one-shot path's zombie timer) and fire
|
|
191
247
|
// when the child stays silent for the whole budget. Finalize mode never
|
|
@@ -222,7 +278,7 @@ class InteractiveJobSession {
|
|
|
222
278
|
const note = `⚠️ Could not deliver your message — the agent's input channel is closed.`;
|
|
223
279
|
this._persistLog('stderr', note);
|
|
224
280
|
this._emitLog('stderr', note);
|
|
225
|
-
this.
|
|
281
|
+
this._terminateChildTree('crashed');
|
|
226
282
|
return false;
|
|
227
283
|
}
|
|
228
284
|
// Surface the user turn in the transcript via the existing `log` channel so
|
|
@@ -262,27 +318,7 @@ class InteractiveJobSession {
|
|
|
262
318
|
return;
|
|
263
319
|
this._finalizing = true;
|
|
264
320
|
this._clearZombieTimer();
|
|
265
|
-
|
|
266
|
-
if (!child || child.killed || !child.pid) {
|
|
267
|
-
this._settle('finalized');
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
try {
|
|
271
|
-
child.kill('SIGTERM');
|
|
272
|
-
}
|
|
273
|
-
catch { /* already gone */ }
|
|
274
|
-
this._killTimer = setTimeout(() => {
|
|
275
|
-
try {
|
|
276
|
-
if (this._child && !this._child.killed)
|
|
277
|
-
this._child.kill('SIGKILL');
|
|
278
|
-
}
|
|
279
|
-
catch { /* gone */ }
|
|
280
|
-
// Hard-deadline fallback: if the child never emits 'close' (D-state /
|
|
281
|
-
// uninterruptible / signal-swallowing), _handleClose never runs and the slot
|
|
282
|
-
// would leak forever. Force the settle here so the queue always drains. If
|
|
283
|
-
// 'close' does fire, _settle is idempotent so this is a no-op.
|
|
284
|
-
this._settle('finalized');
|
|
285
|
-
}, FINALIZE_KILL_GRACE_MS);
|
|
321
|
+
this._terminateChildTree('finalized');
|
|
286
322
|
}
|
|
287
323
|
/** Programmatic teardown that SETTLES 'crashed' after folding any in-flight
|
|
288
324
|
* turn (loop step timeout / run cancel). Unlike dispose(), the onSettle
|
|
@@ -298,39 +334,16 @@ class InteractiveJobSession {
|
|
|
298
334
|
this._persistLog('stderr', note);
|
|
299
335
|
this._emitLog('stderr', note);
|
|
300
336
|
}
|
|
301
|
-
|
|
302
|
-
try {
|
|
303
|
-
if (child && !child.killed)
|
|
304
|
-
child.kill('SIGTERM');
|
|
305
|
-
}
|
|
306
|
-
catch { /* gone */ }
|
|
307
|
-
// Escalate to SIGKILL after the grace window if the child survives SIGTERM.
|
|
308
|
-
// NOT stored in _killTimer — _settle below clears that slot, and this
|
|
309
|
-
// escalation must outlive the settle. unref'd so it never holds the process.
|
|
310
|
-
const escalate = setTimeout(() => {
|
|
311
|
-
try {
|
|
312
|
-
if (this._child && !this._child.killed)
|
|
313
|
-
this._child.kill('SIGKILL');
|
|
314
|
-
}
|
|
315
|
-
catch { /* gone */ }
|
|
316
|
-
}, FINALIZE_KILL_GRACE_MS);
|
|
317
|
-
if (typeof escalate.unref === 'function')
|
|
318
|
-
escalate.unref();
|
|
319
|
-
this._settle('crashed');
|
|
337
|
+
this._terminateChildTree('crashed');
|
|
320
338
|
}
|
|
321
339
|
/** Teardown without settling (project removal / shutdown). */
|
|
322
340
|
dispose() {
|
|
323
341
|
if (this._disposed)
|
|
324
342
|
return;
|
|
325
343
|
this._disposed = true;
|
|
326
|
-
this._clearKillTimer();
|
|
327
344
|
this._clearZombieTimer();
|
|
328
345
|
this._closeReaders();
|
|
329
|
-
|
|
330
|
-
if (this._child && !this._child.killed)
|
|
331
|
-
this._child.kill('SIGTERM');
|
|
332
|
-
}
|
|
333
|
-
catch { /* gone */ }
|
|
346
|
+
this._terminateChildTree(null);
|
|
334
347
|
this._child = null;
|
|
335
348
|
}
|
|
336
349
|
// ─── internals ─────────────────────────────────────────────────────────────
|
|
@@ -339,8 +352,20 @@ class InteractiveJobSession {
|
|
|
339
352
|
* caller must NOT treat an unconfirmed turn as accepted. */
|
|
340
353
|
_writeTurn(text) {
|
|
341
354
|
const child = this._child;
|
|
342
|
-
if (!child || !child.stdin || child.stdin.destroyed)
|
|
355
|
+
if (!child || !child.stdin || child.stdin.destroyed || this._stdinFailed)
|
|
343
356
|
return false;
|
|
357
|
+
const turnStartedAtMs = Date.now();
|
|
358
|
+
if (this._persistTurnActivity) {
|
|
359
|
+
try {
|
|
360
|
+
// Commit the start BEFORE stdin delivery. If this fails, the provider
|
|
361
|
+
// never receives work that startup recovery cannot time/account.
|
|
362
|
+
this._persistTurnActivity(turnStartedAtMs, turnStartedAtMs);
|
|
363
|
+
}
|
|
364
|
+
catch (err) {
|
|
365
|
+
this._failStopPersistence('turn-start checkpoint', err);
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
344
369
|
try {
|
|
345
370
|
child.stdin.write((0, explore_stdin_session_1.frameStreamJsonUserMessage)(text));
|
|
346
371
|
}
|
|
@@ -348,16 +373,15 @@ class InteractiveJobSession {
|
|
|
348
373
|
console.error('[interactive-job] stdin write failed:', err);
|
|
349
374
|
return false;
|
|
350
375
|
}
|
|
351
|
-
//
|
|
352
|
-
//
|
|
353
|
-
// has begun, so it can never inflate the next turn's totals.
|
|
376
|
+
// Arm exactly one result for this delivered turn. Cross-turn retransmissions
|
|
377
|
+
// are rejected by the canonical-signature barrier in _handleStdoutLine.
|
|
354
378
|
this._turnSeq += 1;
|
|
355
379
|
this._activeTurnId = this._turnSeq;
|
|
356
380
|
this._streaming = true;
|
|
357
381
|
this._awaitingResult = true;
|
|
358
382
|
this._turnEvents = [];
|
|
359
383
|
// Start the active-duration segment for this turn (LOW-15).
|
|
360
|
-
this._turnStartMs =
|
|
384
|
+
this._turnStartMs = turnStartedAtMs;
|
|
361
385
|
return true;
|
|
362
386
|
}
|
|
363
387
|
_handleStdoutLine(line) {
|
|
@@ -366,6 +390,19 @@ class InteractiveJobSession {
|
|
|
366
390
|
parsed = JSON.parse(line);
|
|
367
391
|
}
|
|
368
392
|
catch { /* plain text */ }
|
|
393
|
+
// A late retransmission can arrive after the next queued prompt has already
|
|
394
|
+
// been written. Drop it BEFORE adapter parsing and event persistence: adding
|
|
395
|
+
// it to the next turn's event buffer corrupts live totals, while persisting
|
|
396
|
+
// it beyond the prior checkpoint would make crash recovery count it again.
|
|
397
|
+
if (parsed?.type === 'result') {
|
|
398
|
+
// A terminal frame with no active turn is causally unassignable. Drop it
|
|
399
|
+
// before adapter parsing/persistence so raw recovery cannot count it.
|
|
400
|
+
if (!this._awaitingResult)
|
|
401
|
+
return;
|
|
402
|
+
const signature = resultFrameSignature(parsed);
|
|
403
|
+
if (this._acceptedResultSignatures.has(signature))
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
369
406
|
const adapterEv = this._adapter.parseStreamLine(line);
|
|
370
407
|
if (adapterEv) {
|
|
371
408
|
this._turnEvents.push(adapterEv);
|
|
@@ -374,7 +411,11 @@ class InteractiveJobSession {
|
|
|
374
411
|
}
|
|
375
412
|
if (parsed) {
|
|
376
413
|
const eventType = parsed.type ?? 'unknown';
|
|
377
|
-
const seq = this._persistEvent(eventType, line);
|
|
414
|
+
const { seq, persisted } = this._persistEvent(eventType, line);
|
|
415
|
+
if (!persisted)
|
|
416
|
+
return;
|
|
417
|
+
if (eventType !== 'result' && !this._checkpointRawActivity())
|
|
418
|
+
return;
|
|
378
419
|
this._broadcast({
|
|
379
420
|
type: 'event',
|
|
380
421
|
jobId: this._jobId,
|
|
@@ -385,7 +426,7 @@ class InteractiveJobSession {
|
|
|
385
426
|
seq,
|
|
386
427
|
});
|
|
387
428
|
if (eventType === 'result') {
|
|
388
|
-
this._onTurnResult(parsed);
|
|
429
|
+
this._onTurnResult(parsed, seq, resultFrameSignature(parsed));
|
|
389
430
|
}
|
|
390
431
|
const displayText = (0, stream_display_1.extractDisplayText)(parsed);
|
|
391
432
|
if (displayText !== null) {
|
|
@@ -405,20 +446,47 @@ class InteractiveJobSession {
|
|
|
405
446
|
}
|
|
406
447
|
_handleStderrLine(line) {
|
|
407
448
|
this._persistLog('stderr', line);
|
|
449
|
+
if (!this._checkpointRawActivity())
|
|
450
|
+
return;
|
|
408
451
|
this._emitLog('stderr', line);
|
|
409
452
|
}
|
|
410
|
-
|
|
453
|
+
/** Update the active wall segment on raw activity. Failure is terminal: the
|
|
454
|
+
* raw event/log is already durable while the completed-event frontier remains
|
|
455
|
+
* unchanged, so startup can replay the turn exactly once. */
|
|
456
|
+
_checkpointRawActivity() {
|
|
457
|
+
if (!this._persistTurnActivity || this._turnStartMs === null)
|
|
458
|
+
return true;
|
|
459
|
+
try {
|
|
460
|
+
this._persistTurnActivity(this._turnStartMs, Date.now());
|
|
461
|
+
return true;
|
|
462
|
+
}
|
|
463
|
+
catch (err) {
|
|
464
|
+
this._failStopPersistence('raw-activity checkpoint', err);
|
|
465
|
+
return false;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
_failStopPersistence(context, err) {
|
|
469
|
+
console.error(`[interactive-job] ${context} failed; stopping session:`, err);
|
|
470
|
+
if (this._disposed || this._settled)
|
|
471
|
+
return;
|
|
472
|
+
// Block send()/auto-settle immediately while the child termination is in
|
|
473
|
+
// flight. `_terminationReason` remains crashed even though `_finalizing`
|
|
474
|
+
// also serves as the admission gate.
|
|
475
|
+
this._finalizing = true;
|
|
476
|
+
this._terminateChildTree('crashed');
|
|
477
|
+
}
|
|
478
|
+
_onTurnResult(parsed, resultEventSeq, resultSignature) {
|
|
411
479
|
// Count a result only for the in-flight turn, exactly once (BUG-INTJOB-03).
|
|
412
480
|
// `_awaitingResult` alone is insufficient: after a turn settles, the next
|
|
413
481
|
// queued prompt re-arms `_awaitingResult`, so a stray/duplicate result for the
|
|
414
|
-
// PRIOR turn would be folded into the new turn's (reset) events.
|
|
415
|
-
//
|
|
416
|
-
//
|
|
417
|
-
// already been settled.
|
|
482
|
+
// PRIOR turn would be folded into the new turn's (reset) events. The active
|
|
483
|
+
// sequence gates one result per delivery; _handleStdoutLine rejects any
|
|
484
|
+
// previously accepted canonical frame before it reaches this method.
|
|
418
485
|
if (!this._awaitingResult)
|
|
419
486
|
return;
|
|
420
487
|
if (this._activeTurnId <= this._lastSettledTurnId)
|
|
421
488
|
return;
|
|
489
|
+
this._acceptedResultSignatures.add(resultSignature);
|
|
422
490
|
this._lastSettledTurnId = this._activeTurnId;
|
|
423
491
|
this._awaitingResult = false;
|
|
424
492
|
this._streaming = false;
|
|
@@ -462,20 +530,39 @@ class InteractiveJobSession {
|
|
|
462
530
|
if (normalised.session_id)
|
|
463
531
|
this._sessionId = normalised.session_id;
|
|
464
532
|
if (this._db) {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
533
|
+
const usage = {
|
|
534
|
+
tokens_in: normalised.tokens_in ?? 0,
|
|
535
|
+
tokens_out: normalised.tokens_out ?? 0,
|
|
536
|
+
tokens_cache_read: normalised.tokens_cache_read ?? 0,
|
|
537
|
+
tokens_cache_create: normalised.tokens_cache_create ?? 0,
|
|
538
|
+
total_cost_usd: costDelta,
|
|
539
|
+
num_turns: turnsDelta,
|
|
540
|
+
model: normalised.model,
|
|
541
|
+
session_id: normalised.session_id,
|
|
542
|
+
};
|
|
543
|
+
if (this._persistTurnUsage) {
|
|
544
|
+
try {
|
|
545
|
+
this._persistTurnUsage(usage, resultEventSeq, {
|
|
546
|
+
cost: this._baselineCost,
|
|
547
|
+
turns: this._baselineTurns,
|
|
548
|
+
activeDurationMs: this._activeDurationMs,
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
catch (err) {
|
|
552
|
+
// The result row is already durable, but its frontier did not commit.
|
|
553
|
+
// Stop before turn_done/next-prompt/auto-finalize; onSettle or startup
|
|
554
|
+
// recovery consumes the retained turn exactly once.
|
|
555
|
+
this._failStopPersistence('turn usage checkpoint', err);
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
476
558
|
}
|
|
477
|
-
|
|
478
|
-
|
|
559
|
+
else {
|
|
560
|
+
try {
|
|
561
|
+
(0, db_1.accumulateInteractiveTurn)(this._db, this._jobId, usage);
|
|
562
|
+
}
|
|
563
|
+
catch (err) {
|
|
564
|
+
console.error('[interactive-job] accumulate turn failed:', err);
|
|
565
|
+
}
|
|
479
566
|
}
|
|
480
567
|
}
|
|
481
568
|
this._broadcast({
|
|
@@ -500,7 +587,7 @@ class InteractiveJobSession {
|
|
|
500
587
|
const note = `⚠️ Could not deliver a queued message — the agent's input channel is closed.`;
|
|
501
588
|
this._persistLog('stderr', note);
|
|
502
589
|
this._emitLog('stderr', note);
|
|
503
|
-
this.
|
|
590
|
+
this._terminateChildTree('crashed');
|
|
504
591
|
}
|
|
505
592
|
});
|
|
506
593
|
}
|
|
@@ -530,18 +617,24 @@ class InteractiveJobSession {
|
|
|
530
617
|
_persistEvent(eventType, payload) {
|
|
531
618
|
const seq = this._takeSeq();
|
|
532
619
|
if (!this._db)
|
|
533
|
-
return seq;
|
|
620
|
+
return { seq, persisted: true };
|
|
534
621
|
try {
|
|
535
622
|
(0, db_1.appendEvent)(this._db, this._jobId, seq, {
|
|
536
623
|
event_type: eventType,
|
|
537
624
|
source: 'stdout',
|
|
538
625
|
payload,
|
|
539
626
|
});
|
|
627
|
+
this._lastPersistedEventSeq = Math.max(this._lastPersistedEventSeq, seq);
|
|
628
|
+
return { seq, persisted: true };
|
|
540
629
|
}
|
|
541
630
|
catch (err) {
|
|
542
631
|
console.error('[interactive-job] persist event failed:', err);
|
|
632
|
+
// Every DB-backed session now relies on raw rows for crash recovery.
|
|
633
|
+
// Continuing would let a later result/frontier certify provider work that
|
|
634
|
+
// cannot be reconstructed after process death.
|
|
635
|
+
this._failStopPersistence('raw event persistence', err);
|
|
636
|
+
return { seq, persisted: false };
|
|
543
637
|
}
|
|
544
|
-
return seq;
|
|
545
638
|
}
|
|
546
639
|
_persistLog(source, line) {
|
|
547
640
|
const seq = this._takeSeq();
|
|
@@ -604,7 +697,7 @@ class InteractiveJobSession {
|
|
|
604
697
|
this._sessionId = partial.session_id;
|
|
605
698
|
if (this._db) {
|
|
606
699
|
try {
|
|
607
|
-
|
|
700
|
+
const usage = {
|
|
608
701
|
tokens_in: partial.tokens_in ?? 0,
|
|
609
702
|
tokens_out: partial.tokens_out ?? 0,
|
|
610
703
|
tokens_cache_read: partial.tokens_cache_read ?? 0,
|
|
@@ -616,7 +709,14 @@ class InteractiveJobSession {
|
|
|
616
709
|
// Mark the jobs row estimated when this folded turn was priced from the
|
|
617
710
|
// rate card (no terminal `result` frame) — keeps Job Detail honest.
|
|
618
711
|
estimated: partialCost > 0 && estimated,
|
|
619
|
-
}
|
|
712
|
+
};
|
|
713
|
+
if (this._persistTurnUsage) {
|
|
714
|
+
this._persistTurnUsage(usage, this._lastPersistedEventSeq, {
|
|
715
|
+
activeDurationMs: this._activeDurationMs,
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
else
|
|
719
|
+
(0, db_1.accumulateInteractiveTurn)(this._db, this._jobId, usage);
|
|
620
720
|
}
|
|
621
721
|
catch (err) {
|
|
622
722
|
console.error('[interactive-job] fold in-flight turn failed:', err);
|
|
@@ -642,7 +742,7 @@ class InteractiveJobSession {
|
|
|
642
742
|
_handleClose(_code) {
|
|
643
743
|
if (this._disposed || this._settled)
|
|
644
744
|
return;
|
|
645
|
-
this._settle(this._finalizing ? 'finalized' : 'crashed');
|
|
745
|
+
this._settle(this._terminationReason ?? (this._finalizing ? 'finalized' : 'crashed'));
|
|
646
746
|
}
|
|
647
747
|
// ─── Auto-mode wedge detector ────────────────────────────────────────────────
|
|
648
748
|
_resetZombieTimer() {
|
|
@@ -727,6 +827,61 @@ class InteractiveJobSession {
|
|
|
727
827
|
zeroWork,
|
|
728
828
|
});
|
|
729
829
|
}
|
|
830
|
+
/**
|
|
831
|
+
* Shared teardown for finalize / abort / dispose. Signal the WHOLE process
|
|
832
|
+
* tree, then escalate only when the child has not emitted a real `close`.
|
|
833
|
+
* `ChildProcess.killed` is deliberately ignored: Node flips it as soon as a
|
|
834
|
+
* signal is sent, even when the process survives that signal.
|
|
835
|
+
*
|
|
836
|
+
* Finalize/abort settle on close. A child that never closes is force-settled
|
|
837
|
+
* only after SIGKILL has actually been requested, preserving queue liveness
|
|
838
|
+
* without releasing the slot after a mere SIGTERM attempt. Dispose never
|
|
839
|
+
* settles because its owner already flushed/reconciles the job separately.
|
|
840
|
+
*/
|
|
841
|
+
_terminateChildTree(reason) {
|
|
842
|
+
if (reason !== null && this._terminationReason === null)
|
|
843
|
+
this._terminationReason = reason;
|
|
844
|
+
const child = this._child;
|
|
845
|
+
if (!child || this._childClosed || !child.pid) {
|
|
846
|
+
if (reason !== null && !this._disposed)
|
|
847
|
+
this._settle(reason);
|
|
848
|
+
return;
|
|
849
|
+
}
|
|
850
|
+
if (this._terminationStarted)
|
|
851
|
+
return;
|
|
852
|
+
this._terminationStarted = true;
|
|
853
|
+
const pid = child.pid;
|
|
854
|
+
// Arm before SIGTERM: an injected/synchronous terminator may cause `close`
|
|
855
|
+
// immediately, and that close must be able to cancel the escalation.
|
|
856
|
+
this._killTimer = setTimeout(() => {
|
|
857
|
+
this._killTimer = null;
|
|
858
|
+
if (this._childClosed)
|
|
859
|
+
return;
|
|
860
|
+
try {
|
|
861
|
+
this._killTree(pid, 'SIGKILL', (err) => {
|
|
862
|
+
if (err)
|
|
863
|
+
console.error(`[interactive-job] SIGKILL failed for ${this._jobId}: ${err.message}`);
|
|
864
|
+
});
|
|
865
|
+
}
|
|
866
|
+
catch (err) {
|
|
867
|
+
console.error(`[interactive-job] SIGKILL failed for ${this._jobId}: ${err.message}`);
|
|
868
|
+
}
|
|
869
|
+
// Hard deadline: the OS may never deliver `close` for an uninterruptible
|
|
870
|
+
// child. The tree has now received SIGKILL, so release an awaiting owner.
|
|
871
|
+
if (reason !== null && !this._disposed)
|
|
872
|
+
this._settle(reason);
|
|
873
|
+
}, FINALIZE_KILL_GRACE_MS);
|
|
874
|
+
this._killTimer.unref?.();
|
|
875
|
+
try {
|
|
876
|
+
this._killTree(pid, 'SIGTERM', (err) => {
|
|
877
|
+
if (err)
|
|
878
|
+
console.error(`[interactive-job] SIGTERM failed for ${this._jobId}: ${err.message}`);
|
|
879
|
+
});
|
|
880
|
+
}
|
|
881
|
+
catch (err) {
|
|
882
|
+
console.error(`[interactive-job] SIGTERM failed for ${this._jobId}: ${err.message}`);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
730
885
|
_clearKillTimer() {
|
|
731
886
|
if (this._killTimer !== null) {
|
|
732
887
|
clearTimeout(this._killTimer);
|
|
@@ -12,6 +12,8 @@ exports.bodyForDeployment = bodyForDeployment;
|
|
|
12
12
|
exports.commentMarker = commentMarker;
|
|
13
13
|
exports.discardCommentMarker = discardCommentMarker;
|
|
14
14
|
exports.prMergedCommentMarker = prMergedCommentMarker;
|
|
15
|
+
exports.railCompletedCommentMarker = railCompletedCommentMarker;
|
|
16
|
+
exports.railRefinedCommentMarker = railRefinedCommentMarker;
|
|
15
17
|
exports.railReviewCommentMarker = railReviewCommentMarker;
|
|
16
18
|
exports.bodyContainsMarker = bodyContainsMarker;
|
|
17
19
|
exports.commentHasMarker = commentHasMarker;
|
|
@@ -243,6 +245,14 @@ function discardCommentMarker(ticketId, nonce) {
|
|
|
243
245
|
function prMergedCommentMarker(refId, ticketId) {
|
|
244
246
|
return `[specrails:pr-merged=${refId}:ticket=${ticketId}]`;
|
|
245
247
|
}
|
|
248
|
+
/** Idempotency marker for accepting a fresh no-change delivery as complete. */
|
|
249
|
+
function railCompletedCommentMarker(refId, ticketId) {
|
|
250
|
+
return `[specrails:rail-completed=${refId}:ticket=${ticketId}]`;
|
|
251
|
+
}
|
|
252
|
+
/** Idempotency marker for returning a fresh no-change delivery to refinement. */
|
|
253
|
+
function railRefinedCommentMarker(refId, ticketId) {
|
|
254
|
+
return `[specrails:rail-refined=${refId}:ticket=${ticketId}]`;
|
|
255
|
+
}
|
|
246
256
|
/**
|
|
247
257
|
* Idempotency marker for the "ready for review" comment posted when an isolated
|
|
248
258
|
* rail parks a Jira-linked ticket on_review awaiting the PR decision.
|
|
@@ -281,9 +281,21 @@ function enqueueMany(db, ops) {
|
|
|
281
281
|
function claimDrainable(db, limit, nowIso = new Date().toISOString()) {
|
|
282
282
|
const tx = db.transaction((max) => {
|
|
283
283
|
const rows = db
|
|
284
|
-
.prepare(`SELECT
|
|
285
|
-
WHERE state = 'pending'
|
|
286
|
-
|
|
284
|
+
.prepare(`SELECT candidate.* FROM jira_outbox AS candidate
|
|
285
|
+
WHERE candidate.state = 'pending'
|
|
286
|
+
AND (candidate.next_attempt_at IS NULL OR candidate.next_attempt_at <= ?)
|
|
287
|
+
AND NOT EXISTS (
|
|
288
|
+
SELECT 1 FROM jira_outbox AS prior
|
|
289
|
+
WHERE prior.jira_issue_id = candidate.jira_issue_id
|
|
290
|
+
AND prior.id < candidate.id
|
|
291
|
+
AND prior.state IN ('pending', 'inflight')
|
|
292
|
+
)
|
|
293
|
+
AND NOT EXISTS (
|
|
294
|
+
SELECT 1 FROM jira_outbox AS active
|
|
295
|
+
WHERE active.jira_issue_id = candidate.jira_issue_id
|
|
296
|
+
AND active.state = 'inflight'
|
|
297
|
+
)
|
|
298
|
+
ORDER BY candidate.id ASC`)
|
|
287
299
|
.all(nowIso);
|
|
288
300
|
const claimed = [];
|
|
289
301
|
const seenIssues = new Set();
|