specrails-desktop 2.20.1 → 2.22.0
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/README.md +3 -2
- package/client/dist/assets/{ActivityFeedPage-3WSqRYVx.js → ActivityFeedPage-roDyKGuv.js} +1 -1
- package/client/dist/assets/AgentBrowserCapture-BsXnWa4j.js +1 -0
- package/client/dist/assets/{AgentModeCodePane-Cnsea6eZ.js → AgentModeCodePane-o97EJvbJ.js} +2 -2
- package/client/dist/assets/AgentModeJobsPane-CLtpPxPM.js +1 -0
- package/client/dist/assets/AgentsPage-eNSo_ZcC.js +86 -0
- package/client/dist/assets/AnalyticsPage-cAJ60_Ex.js +1 -0
- package/client/dist/assets/{BarChart-C6If656N.js → BarChart-NLtK7xAY.js} +1 -1
- package/client/dist/assets/CodePage-B5rum8ZB.js +2 -0
- package/client/dist/assets/DesktopAnalyticsPage-DSuvG6Tq.js +1 -0
- package/client/dist/assets/DocsDialog-Bo38G3Yc.js +11 -0
- package/client/dist/assets/DocsPage-BNkiBBrC.js +11 -0
- package/client/dist/assets/{ExportDropdown-CezTK0EX.js → ExportDropdown-DCV8PN4-.js} +1 -1
- package/client/dist/assets/IntegrationsPage-BMJOzpPz.js +3 -0
- package/client/dist/assets/InteractiveJobComposer-aLduNs5R.js +19 -0
- package/client/dist/assets/JobDetailModal-kpkUWJIS.js +1 -0
- package/client/dist/assets/JobDetailPage-CFeqlrPU.js +1 -0
- package/client/dist/assets/JobsPage-fuwhXy2I.js +1 -0
- package/client/dist/assets/LoopBuilderPage-DP66322C.js +7 -0
- package/client/dist/assets/LoopPreviewModal-CpmBhE31.js +1 -0
- package/client/dist/assets/LoopsPage-CvQ18VUx.js +1 -0
- package/client/dist/assets/ProjectSettingsDialog-Deq4pwvq.js +1 -0
- package/client/dist/assets/TemplatePreviewModal-DziOj2Ct.js +1 -0
- package/client/dist/assets/agent-Csh4kP2S.js +1 -0
- package/client/dist/assets/agent-Cz_jgQX32.js +1 -0
- package/client/dist/assets/agent-D3vcIvaz2.js +1 -0
- package/client/dist/assets/agent-Dnbt0V4e.js +1 -0
- package/client/dist/assets/agent-HolR7QrZ.js +1 -0
- package/client/dist/assets/agent-Ka0rRWJy.js +1 -0
- package/client/dist/assets/agent-Te3yysMd.js +1 -0
- package/client/dist/assets/agent-vM4_iLDk2.js +1 -0
- package/client/dist/assets/{upload-CRtTj4Co.js → brain-kFJuEDNH.js} +1 -1
- package/client/dist/assets/{browser-DEEO-OSi.js → browser-BPkhILSJ.js} +1 -1
- package/client/dist/assets/{browser-BTivfZKE2.js → browser-BijVYG0Y2.js} +1 -1
- package/client/dist/assets/{browser-bpO3onlS.js → browser-BqLqJVVT.js} +1 -1
- package/client/dist/assets/{browser-DlSXtfu5.js → browser-Cc0iDqUi.js} +1 -1
- package/client/dist/assets/browser-CdS6O1Qb.js +1 -0
- package/client/dist/assets/{browser-BKP6hqQC2.js → browser-Cvg-QHvd2.js} +1 -1
- package/client/dist/assets/{browser-INCUyduh.js → browser-FRv8P02E.js} +1 -1
- package/client/dist/assets/{browser-DlKLfT612.js → browser-rWKj-RR_2.js} +1 -1
- package/client/dist/assets/code-BRcDlze52.js +1 -0
- package/client/dist/assets/code-BdMy3Ffq.js +1 -0
- package/client/dist/assets/code-CeQ0FZpC.js +1 -0
- package/client/dist/assets/code-CqCcRThR.js +1 -0
- package/client/dist/assets/code-DgeHz9CB.js +1 -0
- package/client/dist/assets/code-DzC1rMk12.js +1 -0
- package/client/dist/assets/code-UPVvmAKM2.js +1 -0
- package/client/dist/assets/code-thSEptMx.js +1 -0
- package/client/dist/assets/{common-QjVnq9XP2.js → common-BM3LFLCE2.js} +1 -1
- package/client/dist/assets/{common-CeQUwuHt2.js → common-Bwafujnc2.js} +1 -1
- package/client/dist/assets/{common-Bb64s3Bm.js → common-C-vU-j-I.js} +1 -1
- package/client/dist/assets/{common-KbQuTSGg.js → common-C5HKSbbz.js} +1 -1
- package/client/dist/assets/{common-BPQQkgJZ.js → common-CYaT2yHp.js} +1 -1
- package/client/dist/assets/{common-DPxotRK9.js → common-DhWTkocg.js} +1 -1
- package/client/dist/assets/{common-k5MTOHpn.js → common-DiPTT7V_2.js} +1 -1
- package/client/dist/assets/{common-C8ZD5upH2.js → common-DmqBPwZG.js} +1 -1
- package/client/dist/assets/{cssMode-DsArsSCT.js → cssMode-DBHbkBvI.js} +1 -1
- package/client/dist/assets/dashboard-BaStj_a_.js +1 -0
- package/client/dist/assets/dashboard-Bi6ugu5Q.js +1 -0
- package/client/dist/assets/dashboard-BmqTn3L02.js +1 -0
- package/client/dist/assets/dashboard-CvT8lOCT.js +1 -0
- package/client/dist/assets/dashboard-D7Pmeavq2.js +1 -0
- package/client/dist/assets/dashboard-DAnWdAac2.js +1 -0
- package/client/dist/assets/dashboard-JnYy2WLg.js +1 -0
- package/client/dist/assets/dashboard-L47YsFS_.js +1 -0
- package/client/dist/assets/{dist-js-BQn4yxaw.js → dist-js-BZSiJDbG.js} +1 -1
- package/client/dist/assets/{dist-js-BAWSqVtr.js → dist-js-DKpmIJlQ.js} +1 -1
- package/client/dist/assets/{editor.main-G3Sl9C67.js → editor.main-C9J2ikJK.js} +2 -2
- package/client/dist/assets/{freemarker2-pBzQNgFi.js → freemarker2-J5iIIIK-.js} +1 -1
- package/client/dist/assets/{handlebars-CtBTCnBI.js → handlebars-DSw1l_tw.js} +1 -1
- package/client/dist/assets/{html-Dx3DYBzY.js → html-h2-wE1Lj.js} +1 -1
- package/client/dist/assets/{htmlMode-In7frFOo.js → htmlMode-Cc_ij7lW.js} +1 -1
- package/client/dist/assets/index-DM6heiGa.js +155 -0
- package/client/dist/assets/index-DPX6_xIC.css +2 -0
- package/client/dist/assets/{javascript-BKcn-YkN.js → javascript-C1q3xv6N.js} +1 -1
- package/client/dist/assets/jira-B3613-gj.js +1 -0
- package/client/dist/assets/jira-BHAKtc4B.js +1 -0
- package/client/dist/assets/jira-Be369RIR2.js +1 -0
- package/client/dist/assets/jira-CPpgA-5z2.js +1 -0
- package/client/dist/assets/jira-D5efgwp_.js +1 -0
- package/client/dist/assets/jira-DS7ownDy.js +1 -0
- package/client/dist/assets/jira-bDs7Im2C.js +1 -0
- package/client/dist/assets/jira-uNH1gETL2.js +1 -0
- package/client/dist/assets/jobs-1GV2-4zd2.js +1 -0
- package/client/dist/assets/jobs-26F9gGcE.js +1 -0
- package/client/dist/assets/jobs-BgQzB0Sx2.js +1 -0
- package/client/dist/assets/jobs-BqWui9_f.js +1 -0
- package/client/dist/assets/jobs-CE8qeIYj.js +1 -0
- package/client/dist/assets/jobs-D5sZzgLs.js +1 -0
- package/client/dist/assets/jobs-DzeuASRf.js +1 -0
- package/client/dist/assets/jobs-Wh7dn28q2.js +1 -0
- package/client/dist/assets/{jsonMode-jNREoQ3C.js → jsonMode-CeaCdEhr.js} +1 -1
- package/client/dist/assets/{lib-C-g8QbZl.js → lib-B2nCKzmA.js} +1 -1
- package/client/dist/assets/{liquid-CtRkGqBu.js → liquid-eFsVK0V-.js} +1 -1
- package/client/dist/assets/loops-BvEenWBy.js +1 -0
- package/client/dist/assets/loops-CBiWd9Hf.js +1 -0
- package/client/dist/assets/loops-DNGiYKll2.js +1 -0
- package/client/dist/assets/{loops-Y3FQsUCh.js → loops-DjOtVXRo.js} +1 -1
- package/client/dist/assets/loops-HTHf-xu32.js +1 -0
- package/client/dist/assets/loops-YYV2bwjd.js +1 -0
- package/client/dist/assets/loops-hXgncEpF2.js +1 -0
- package/client/dist/assets/loops-kYbydDyN.js +1 -0
- package/client/dist/assets/{lspLanguageFeatures-Cl3gvD_W.js → lspLanguageFeatures-DT3-bbhn.js} +1 -1
- package/client/dist/assets/{mdx-B_nJldHz.js → mdx-Fuwnh1cX.js} +1 -1
- package/client/dist/assets/{monaco.contribution-PUeaZk8T.js → monaco.contribution-Desq7oq4.js} +2 -2
- package/client/dist/assets/{python-DS1Ce-A6.js → python-BgoEs6Cj.js} +1 -1
- package/client/dist/assets/{razor-L41Qg9OK.js → razor-CM1sPMMq.js} +1 -1
- package/client/dist/assets/{settings-BPq9nCJm.js → settings-BOHOmHkb.js} +1 -1
- package/client/dist/assets/{settings-r8Qq2Gzp2.js → settings-BlEA_7h02.js} +1 -1
- package/client/dist/assets/{settings-C-m3yEZ2.js → settings-BsJMsWGc.js} +1 -1
- package/client/dist/assets/{settings-zZr7NzuB.js → settings-D6qY9_UI.js} +1 -1
- package/client/dist/assets/{settings-VgCsjaYf.js → settings-DZJeXoRV.js} +1 -1
- package/client/dist/assets/settings-Mr7MnJbf.js +1 -0
- package/client/dist/assets/{settings-BWHGtmU12.js → settings-TNga5gIF2.js} +1 -1
- package/client/dist/assets/{settings-DZj7Uqy32.js → settings-lFoaYT-s2.js} +1 -1
- package/client/dist/assets/setup-B590KsTX.js +1 -0
- package/client/dist/assets/setup-BkyGoby6.js +1 -0
- package/client/dist/assets/setup-CEj6uY3-2.js +1 -0
- package/client/dist/assets/setup-CbIerFGf2.js +1 -0
- package/client/dist/assets/setup-CmU6bTCV2.js +1 -0
- package/client/dist/assets/setup-D674kWQH.js +1 -0
- package/client/dist/assets/setup-VNqXyB6Y.js +1 -0
- package/client/dist/assets/setup-iY8vH8pB.js +1 -0
- package/client/dist/assets/specs-C9Sd7BhH2.js +1 -0
- package/client/dist/assets/specs-CBDvEYKv.js +1 -0
- package/client/dist/assets/specs-CIPr9reA2.js +1 -0
- package/client/dist/assets/specs-CWtKcVDC.js +1 -0
- package/client/dist/assets/specs-CmEZY57v.js +1 -0
- package/client/dist/assets/specs-D2clrt2c2.js +1 -0
- package/client/dist/assets/specs-DTplt2XM.js +1 -0
- package/client/dist/assets/specs-PozUNhqb.js +1 -0
- package/client/dist/assets/{tsMode-BC1g186U.js → tsMode-BmT8WogI.js} +1 -1
- package/client/dist/assets/{typescript-BGlRGvJW.js → typescript-CQrQPsoW.js} +1 -1
- package/client/dist/assets/upload-CLAzW1mS.js +1 -0
- package/client/dist/assets/{value-D9aLbxw-.js → value-DSwzyyWR.js} +1 -1
- package/client/dist/assets/{workers-CXcXtO3b.js → workers-U0UXyLUf.js} +1 -1
- package/client/dist/assets/{xml-JdZZaIhJ.js → xml-WRxJs8_I.js} +1 -1
- package/client/dist/assets/{yaml-Cm82BVBt.js → yaml-CjpSTjJU.js} +1 -1
- package/client/dist/index.html +14 -14
- package/docs/customizing.md +2 -2
- package/docs/gemini.md +15 -4
- package/docs/guide/de/insights/3-code-explorer.md +6 -0
- package/docs/guide/de/integrations/3-jira-integration.md +1 -1
- package/docs/guide/de/integrations/6-agent-chat.md +5 -0
- package/docs/guide/de/pipeline/1-rails-and-jobs.md +6 -6
- package/docs/guide/de/pipeline/2-the-job-detail-view.md +27 -2
- package/docs/guide/de/pipeline/3-batch-implement-and-multi-feature.md +9 -5
- package/docs/guide/de/pipeline/5-the-loop-builder.md +1 -1
- package/docs/guide/de/specs/1-specs-and-the-backlog.md +3 -2
- package/docs/guide/en/insights/3-code-explorer.md +6 -0
- package/docs/guide/en/integrations/3-jira-integration.md +1 -1
- package/docs/guide/en/integrations/6-agent-chat.md +5 -0
- package/docs/guide/en/pipeline/1-rails-and-jobs.md +6 -6
- package/docs/guide/en/pipeline/2-the-job-detail-view.md +27 -2
- package/docs/guide/en/pipeline/3-batch-implement-and-multi-feature.md +10 -4
- package/docs/guide/en/pipeline/5-the-loop-builder.md +1 -1
- package/docs/guide/en/specs/1-specs-and-the-backlog.md +3 -2
- package/docs/guide/es/insights/3-code-explorer.md +6 -0
- package/docs/guide/es/integrations/3-jira-integration.md +1 -1
- package/docs/guide/es/integrations/6-agent-chat.md +5 -0
- package/docs/guide/es/pipeline/1-rails-and-jobs.md +6 -6
- package/docs/guide/es/pipeline/2-the-job-detail-view.md +27 -2
- package/docs/guide/es/pipeline/3-batch-implement-and-multi-feature.md +9 -5
- package/docs/guide/es/pipeline/5-the-loop-builder.md +1 -1
- package/docs/guide/es/specs/1-specs-and-the-backlog.md +3 -2
- package/docs/guide/fr/insights/3-code-explorer.md +6 -0
- package/docs/guide/fr/integrations/3-jira-integration.md +1 -1
- package/docs/guide/fr/integrations/6-agent-chat.md +5 -0
- package/docs/guide/fr/pipeline/1-rails-and-jobs.md +6 -6
- package/docs/guide/fr/pipeline/2-the-job-detail-view.md +27 -2
- package/docs/guide/fr/pipeline/3-batch-implement-and-multi-feature.md +9 -5
- package/docs/guide/fr/pipeline/5-the-loop-builder.md +1 -1
- package/docs/guide/fr/specs/1-specs-and-the-backlog.md +3 -2
- package/docs/guide/it/insights/3-code-explorer.md +6 -0
- package/docs/guide/it/integrations/3-jira-integration.md +1 -1
- package/docs/guide/it/integrations/6-agent-chat.md +5 -0
- package/docs/guide/it/pipeline/1-rails-and-jobs.md +6 -6
- package/docs/guide/it/pipeline/2-the-job-detail-view.md +27 -2
- package/docs/guide/it/pipeline/3-batch-implement-and-multi-feature.md +10 -6
- package/docs/guide/it/pipeline/5-the-loop-builder.md +1 -1
- package/docs/guide/it/specs/1-specs-and-the-backlog.md +3 -2
- package/docs/guide/ja/insights/3-code-explorer.md +6 -0
- package/docs/guide/ja/integrations/3-jira-integration.md +1 -1
- package/docs/guide/ja/integrations/6-agent-chat.md +5 -0
- package/docs/guide/ja/pipeline/1-rails-and-jobs.md +6 -6
- package/docs/guide/ja/pipeline/2-the-job-detail-view.md +27 -2
- package/docs/guide/ja/pipeline/3-batch-implement-and-multi-feature.md +9 -5
- package/docs/guide/ja/pipeline/5-the-loop-builder.md +1 -1
- package/docs/guide/ja/specs/1-specs-and-the-backlog.md +3 -2
- package/docs/guide/pt/insights/3-code-explorer.md +6 -0
- package/docs/guide/pt/integrations/3-jira-integration.md +1 -1
- package/docs/guide/pt/integrations/6-agent-chat.md +5 -0
- package/docs/guide/pt/pipeline/1-rails-and-jobs.md +6 -6
- package/docs/guide/pt/pipeline/2-the-job-detail-view.md +27 -2
- package/docs/guide/pt/pipeline/3-batch-implement-and-multi-feature.md +9 -5
- package/docs/guide/pt/pipeline/5-the-loop-builder.md +1 -1
- package/docs/guide/pt/specs/1-specs-and-the-backlog.md +3 -2
- package/docs/guide/zh/insights/3-code-explorer.md +6 -0
- package/docs/guide/zh/integrations/3-jira-integration.md +1 -1
- package/docs/guide/zh/integrations/6-agent-chat.md +5 -0
- package/docs/guide/zh/pipeline/1-rails-and-jobs.md +6 -6
- package/docs/guide/zh/pipeline/2-the-job-detail-view.md +27 -2
- package/docs/guide/zh/pipeline/3-batch-implement-and-multi-feature.md +10 -6
- package/docs/guide/zh/pipeline/5-the-loop-builder.md +1 -1
- package/docs/guide/zh/specs/1-specs-and-the-backlog.md +3 -2
- package/docs/internals/README.md +5 -0
- package/docs/internals/adding-a-provider.md +15 -3
- package/docs/internals/api-reference.md +6 -5
- package/docs/internals/browser-capture-performance.md +93 -0
- package/docs/internals/code-explorer-story.md +135 -0
- package/docs/internals/gemini-mcp-registration.md +53 -0
- package/docs/internals/interactive-jobs.md +212 -0
- package/docs/internals/loop-step-log-explorer.md +146 -0
- package/docs/internals/safe-pr-review-flow.md +367 -0
- package/docs/mcp.md +1 -1
- package/docs/running-pipelines.md +6 -2
- package/package.json +1 -1
- package/server/dist/agent-chat-manager.js +211 -0
- package/server/dist/agent-chat-registry.js +20 -0
- package/server/dist/agent-chat-router.js +22 -0
- package/server/dist/agent-mcp-config.js +45 -4
- package/server/dist/agent-operator-prompt.js +149 -56
- package/server/dist/agent-store.js +25 -0
- package/server/dist/agent-tier.js +6 -1
- package/server/dist/browser-capture-manager.js +184 -34
- package/server/dist/browser-playwright.js +98 -13
- package/server/dist/code-explorer-router.js +92 -0
- package/server/dist/db.js +102 -0
- package/server/dist/file-provenance.js +54 -1
- package/server/dist/file-story-manager.js +170 -0
- package/server/dist/file-story.js +148 -0
- package/server/dist/file-summary-generator.js +5 -4
- package/server/dist/git-guardrails.js +62 -0
- package/server/dist/index.js +5 -0
- package/server/dist/integration-branch.js +63 -0
- package/server/dist/interactive-job-session.js +226 -18
- package/server/dist/jira/jira-adf.js +9 -0
- package/server/dist/jira/jira-materializer.js +27 -4
- package/server/dist/jira/jira-status-resolver.js +12 -4
- package/server/dist/jira/jira-sync-manager.js +130 -2
- package/server/dist/jira-router.js +1 -1
- package/server/dist/loop-effect.js +12 -0
- package/server/dist/loop-executors.js +92 -22
- package/server/dist/loop-run-manager.js +354 -28
- package/server/dist/mcp/guide.js +18 -7
- package/server/dist/mcp/tools/jira.js +1 -1
- package/server/dist/mcp/tools/jobs.js +14 -5
- package/server/dist/mcp/tools/rails.js +137 -12
- package/server/dist/mcp/tools/specs.js +35 -9
- package/server/dist/mcp/tools/types.js +49 -0
- package/server/dist/mobile/mobile-ws.js +4 -0
- package/server/dist/path-resolver.js +46 -0
- package/server/dist/pr-body.js +240 -0
- package/server/dist/pr-naming.js +210 -0
- package/server/dist/pr-publisher.js +68 -0
- package/server/dist/project-registry.js +77 -17
- package/server/dist/project-router-jobs.js +53 -13
- package/server/dist/project-router-settings.js +33 -0
- package/server/dist/project-router-terminals.js +16 -0
- package/server/dist/project-router-tickets.js +57 -3
- package/server/dist/project-router.js +52 -13
- package/server/dist/queue-manager.js +268 -83
- package/server/dist/rail-isolated-launch.js +324 -34
- package/server/dist/rail-isolation.js +32 -5
- package/server/dist/rail-pr-decision.js +519 -0
- package/server/dist/rail-pr-delivery.js +75 -0
- package/server/dist/rail-pr-store.js +175 -0
- package/server/dist/rail-worktrees-store.js +18 -0
- package/server/dist/rails-router.js +241 -17
- package/server/dist/rails-store.js +78 -1
- package/server/dist/setup-prerequisites.js +105 -0
- package/server/dist/smash-runner.js +3 -1
- package/server/dist/ticket-store.js +7 -3
- package/server/dist/workspace-resolution.js +27 -0
- package/server/dist/worktree-manager.js +42 -7
- package/server/dist/worktree-overlay.js +261 -0
- package/client/dist/assets/AgentBrowserCapture-BlGDZahz.js +0 -1
- package/client/dist/assets/AgentModeJobsPane-CyNR-9BO.js +0 -1
- package/client/dist/assets/AgentsPage-dNsEsY_x.js +0 -86
- package/client/dist/assets/AnalyticsPage-BAxmR0HQ.js +0 -1
- package/client/dist/assets/CodePage-Crc4BBQN.js +0 -2
- package/client/dist/assets/DesktopAnalyticsPage-IXSnbCce.js +0 -1
- package/client/dist/assets/DocsDialog-Bc4hx7oW.js +0 -11
- package/client/dist/assets/DocsPage-bEU4t9c6.js +0 -11
- package/client/dist/assets/IntegrationsPage-wq2CezEL.js +0 -3
- package/client/dist/assets/JobDetailPage-BBcPk3j8.js +0 -1
- package/client/dist/assets/JobsPage-DXrSPlwa.js +0 -1
- package/client/dist/assets/LogViewer-BoYbwvbU.js +0 -16
- package/client/dist/assets/LoopBuilderPage-CiUMAuWz.js +0 -7
- package/client/dist/assets/LoopsPage-Xrp6W5XW.js +0 -1
- package/client/dist/assets/ProjectSettingsDialog-BU98L5JD.js +0 -1
- package/client/dist/assets/agent-B7GdHP3Z.js +0 -1
- package/client/dist/assets/agent-BHmcgoJf.js +0 -1
- package/client/dist/assets/agent-BdY_fii4.js +0 -1
- package/client/dist/assets/agent-C32FOi9v.js +0 -1
- package/client/dist/assets/agent-CiFQxoaZ2.js +0 -1
- package/client/dist/assets/agent-CtAag7V6.js +0 -1
- package/client/dist/assets/agent-DE4Mp1fY2.js +0 -1
- package/client/dist/assets/agent-DK8qovyG2.js +0 -1
- package/client/dist/assets/browser-ZB1afzjZ.js +0 -1
- package/client/dist/assets/code-BFxE1Yt62.js +0 -1
- package/client/dist/assets/code-BefYOm5Q.js +0 -1
- package/client/dist/assets/code-BkXpJt99.js +0 -1
- package/client/dist/assets/code-C6Sq7_t8.js +0 -1
- package/client/dist/assets/code-CGj3w-2N.js +0 -1
- package/client/dist/assets/code-Dfsxc9o82.js +0 -1
- package/client/dist/assets/code-Y5urks5s2.js +0 -1
- package/client/dist/assets/code-wtcs0ivb.js +0 -1
- package/client/dist/assets/dashboard-B8032psZ.js +0 -1
- package/client/dist/assets/dashboard-BHGKtxty2.js +0 -1
- package/client/dist/assets/dashboard-CXnoUgN22.js +0 -1
- package/client/dist/assets/dashboard-Ccyxqy7d.js +0 -1
- package/client/dist/assets/dashboard-CoED_41r.js +0 -1
- package/client/dist/assets/dashboard-Dc5ZAgMN.js +0 -1
- package/client/dist/assets/dashboard-JMY8ueD3.js +0 -1
- package/client/dist/assets/dashboard-tkWr1aHD2.js +0 -1
- package/client/dist/assets/index-BHPbzyg6.css +0 -2
- package/client/dist/assets/index-n2PmJGF6.js +0 -152
- package/client/dist/assets/jira-BcZzX9122.js +0 -1
- package/client/dist/assets/jira-CTYs7LA12.js +0 -1
- package/client/dist/assets/jira-D2nN39e92.js +0 -1
- package/client/dist/assets/jira-DJxmIkyr.js +0 -1
- package/client/dist/assets/jira-DXMoAKWD.js +0 -1
- package/client/dist/assets/jira-IhC1ROIc.js +0 -1
- package/client/dist/assets/jira-Iw575fN8.js +0 -1
- package/client/dist/assets/jira-kbWZY7jH.js +0 -1
- package/client/dist/assets/jobs-BqF79kHz2.js +0 -1
- package/client/dist/assets/jobs-C1XM5urS.js +0 -1
- package/client/dist/assets/jobs-C5UjG0262.js +0 -1
- package/client/dist/assets/jobs-DBfaHTxC.js +0 -1
- package/client/dist/assets/jobs-DM4BDPdg.js +0 -1
- package/client/dist/assets/jobs-Da5OkZmf2.js +0 -1
- package/client/dist/assets/jobs-JJdnuQ03.js +0 -1
- package/client/dist/assets/jobs-SI34ML8I.js +0 -1
- package/client/dist/assets/loops-BR4FmOv12.js +0 -1
- package/client/dist/assets/loops-BgX_uudn.js +0 -1
- package/client/dist/assets/loops-Bpl2j2LP.js +0 -1
- package/client/dist/assets/loops-CQuuMlyZ.js +0 -1
- package/client/dist/assets/loops-DW8hSMdS2.js +0 -1
- package/client/dist/assets/loops-Q2muu8hW2.js +0 -1
- package/client/dist/assets/loops-q7CNDvfK.js +0 -1
- package/client/dist/assets/settings-CY8udi0e.js +0 -1
- package/client/dist/assets/setup-CNMdCHHt2.js +0 -1
- package/client/dist/assets/setup-Cag4XrbL2.js +0 -1
- package/client/dist/assets/setup-D9IHGoWU.js +0 -1
- package/client/dist/assets/setup-Dg6Ba3JT.js +0 -1
- package/client/dist/assets/setup-DyK36RIW.js +0 -1
- package/client/dist/assets/setup-G4ZvDKxX.js +0 -1
- package/client/dist/assets/setup-aTlGxuwi2.js +0 -1
- package/client/dist/assets/setup-kWsoAeHQ.js +0 -1
- package/client/dist/assets/specs-BFSUPa122.js +0 -1
- package/client/dist/assets/specs-BMzip1WY2.js +0 -1
- package/client/dist/assets/specs-BYeAbIEy.js +0 -1
- package/client/dist/assets/specs-C-mtLcXw.js +0 -1
- package/client/dist/assets/specs-CAzpvADd2.js +0 -1
- package/client/dist/assets/specs-CyRIw_IR.js +0 -1
- package/client/dist/assets/specs-DMm7gB_l.js +0 -1
- package/client/dist/assets/specs-DuottM0Z.js +0 -1
- /package/client/dist/assets/{abap-CpHUwCVK.js → abap-D0E4FfVW.js} +0 -0
- /package/client/dist/assets/{activity-DemHQS7l.js → activity--iN4Ad2R2.js} +0 -0
- /package/client/dist/assets/{activity-B_71BWg3.js → activity-6hM_ZSg9.js} +0 -0
- /package/client/dist/assets/{activity-DHv2V5Oi.js → activity-BZNfOdiS.js} +0 -0
- /package/client/dist/assets/{activity-D0rfjQzT2.js → activity-BuVo5sPB.js} +0 -0
- /package/client/dist/assets/{activity-BpTTj_PH.js → activity-CIOLxGvh.js} +0 -0
- /package/client/dist/assets/{activity-D2e62vbV2.js → activity-D2r2h3SE2.js} +0 -0
- /package/client/dist/assets/{activity-Ch-wbr0C2.js → activity-DtxrAUMo2.js} +0 -0
- /package/client/dist/assets/{addon-image-Ba-TY3wr.js → addon-image-CwoZj17F.js} +0 -0
- /package/client/dist/assets/{addon-ligatures-T4ARLiuu.js → addon-ligatures-CWDrED80.js} +0 -0
- /package/client/dist/assets/{addon-webgl-Cd73n8eh.js → addon-webgl-DMbGeI_u.js} +0 -0
- /package/client/dist/assets/{addspec-xwRX_Pnf.js → addspec-BMtLZLW62.js} +0 -0
- /package/client/dist/assets/{addspec-l_zU5gla.js → addspec-CP0HRuxY.js} +0 -0
- /package/client/dist/assets/{addspec-Dio-H5z0.js → addspec-CRuvWn8d.js} +0 -0
- /package/client/dist/assets/{addspec-D6L4ZteP.js → addspec-D-JLDsUV.js} +0 -0
- /package/client/dist/assets/{addspec-CrEm6Fzr2.js → addspec-DfhDbg5c.js} +0 -0
- /package/client/dist/assets/{addspec-B6Ns8KU02.js → addspec-bsNDdqRm2.js} +0 -0
- /package/client/dist/assets/{addspec-qGyH7MHy2.js → addspec-mgPOt5q02.js} +0 -0
- /package/client/dist/assets/{agents-OzxCLVW1.js → agents-78bTZGZh.js} +0 -0
- /package/client/dist/assets/{agents-hv3sqmPm2.js → agents-BLhWCmDS2.js} +0 -0
- /package/client/dist/assets/{agents-CHgCudUV.js → agents-BUdEi3-N.js} +0 -0
- /package/client/dist/assets/{agents-Dumx4JiM2.js → agents-BpoUaoW92.js} +0 -0
- /package/client/dist/assets/{agents-CnaPeSyw.js → agents-CWo-KyAB.js} +0 -0
- /package/client/dist/assets/{agents-Xh-zYHUx2.js → agents-DDtCJ5M02.js} +0 -0
- /package/client/dist/assets/{agents-DuhLEaQ_.js → agents-bvyRLczL.js} +0 -0
- /package/client/dist/assets/{agentstudio-CCthUdzR.js → agentstudio-BMQxc_bz.js} +0 -0
- /package/client/dist/assets/{agentstudio-CcH8Ckql2.js → agentstudio-COZriimI2.js} +0 -0
- /package/client/dist/assets/{agentstudio-Bo91kfUd2.js → agentstudio-CWgXG5W52.js} +0 -0
- /package/client/dist/assets/{agentstudio-VJOa_NVO.js → agentstudio-C_Jq8Tl4.js} +0 -0
- /package/client/dist/assets/{agentstudio-BIxikDf_.js → agentstudio-Dtq3dGYk.js} +0 -0
- /package/client/dist/assets/{agentstudio-Bz8cP8_c.js → agentstudio-jKMTdT70.js} +0 -0
- /package/client/dist/assets/{agentstudio-DARgYg5Z2.js → agentstudio-sI27TpBu2.js} +0 -0
- /package/client/dist/assets/{aiedit-5ZXN4cep2.js → aiedit-6CHdb_iv2.js} +0 -0
- /package/client/dist/assets/{aiedit-B7gAJZVC.js → aiedit-B03pD_Na.js} +0 -0
- /package/client/dist/assets/{aiedit-D92V-kUW.js → aiedit-BtRqRxML.js} +0 -0
- /package/client/dist/assets/{aiedit-D9ualLVJ.js → aiedit-eMN4eQPF.js} +0 -0
- /package/client/dist/assets/{aiedit-h48tJU0V2.js → aiedit-hknZlly82.js} +0 -0
- /package/client/dist/assets/{aiedit-xkA_mR2a2.js → aiedit-igmw-ZoZ2.js} +0 -0
- /package/client/dist/assets/{aiedit-7B2dvCv-.js → aiedit-pc5JDUq1.js} +0 -0
- /package/client/dist/assets/{analytics-slx4X1mu2.js → analytics-BWMUZ2Pq2.js} +0 -0
- /package/client/dist/assets/{analytics-uRNP6yAJ.js → analytics-Bj-SmKHa.js} +0 -0
- /package/client/dist/assets/{analytics-WF1I49ln.js → analytics-C5dpiS0o.js} +0 -0
- /package/client/dist/assets/{analytics-CBvaxOId.js → analytics-CCprAqk3.js} +0 -0
- /package/client/dist/assets/{analytics-BakymH7Z2.js → analytics-CR1TJqUi2.js} +0 -0
- /package/client/dist/assets/{analytics-B7bPj6u_2.js → analytics-DfNdXR0y2.js} +0 -0
- /package/client/dist/assets/{analytics-DZ74aQ54.js → analytics-rmHuJv0V.js} +0 -0
- /package/client/dist/assets/{apex-DlD7oJX6.js → apex-D_X_8J4d.js} +0 -0
- /package/client/dist/assets/{atom-one-dark-BrRN8wBy.js → atom-one-dark-BMDPFwRZ.js} +0 -0
- /package/client/dist/assets/{attachments-C11tOKZ_.js → attachments-BgBNSqQd.js} +0 -0
- /package/client/dist/assets/{attachments-Bnbyj2PN.js → attachments-BjyMmrwE.js} +0 -0
- /package/client/dist/assets/{attachments-CIeLa8l12.js → attachments-C9GTTJsx2.js} +0 -0
- /package/client/dist/assets/{attachments-DslHfa-L.js → attachments-DCZOL1RU.js} +0 -0
- /package/client/dist/assets/{attachments-C-gyrCOb.js → attachments-DL-bPy9E.js} +0 -0
- /package/client/dist/assets/{attachments-Cxrs0pyL2.js → attachments-DPCmkFZu2.js} +0 -0
- /package/client/dist/assets/{attachments-TTPsc0a52.js → attachments-rNn1ekRy2.js} +0 -0
- /package/client/dist/assets/{azcli-CmXFAbc-.js → azcli-PZLnZ3jH.js} +0 -0
- /package/client/dist/assets/{bat-DdNJq4hH.js → bat-KlBOxpO4.js} +0 -0
- /package/client/dist/assets/{bicep-Bppz7WOA.js → bicep-CgG9oF3V.js} +0 -0
- /package/client/dist/assets/{cameligo-0MRMdSmg.js → cameligo-6R45j6Ph.js} +0 -0
- /package/client/dist/assets/{chat-BvHrebKC2.js → chat-BgL3zv6x2.js} +0 -0
- /package/client/dist/assets/{chat-CZyiLJvQ.js → chat-Bh3NdgJs.js} +0 -0
- /package/client/dist/assets/{chat-DKYP7NnC.js → chat-Bom6bqK3.js} +0 -0
- /package/client/dist/assets/{chat-5mdg_YIc2.js → chat-DdwZjT8K2.js} +0 -0
- /package/client/dist/assets/{chat-wkTIy9rX.js → chat-Dnwg-NpQ.js} +0 -0
- /package/client/dist/assets/{chat-BpYxnkr4.js → chat-DsbwJhus.js} +0 -0
- /package/client/dist/assets/{chat-BGax2nV62.js → chat-vylxqR0P2.js} +0 -0
- /package/client/dist/assets/{clojure-B5dKj863.js → clojure-CLAAMO7J.js} +0 -0
- /package/client/dist/assets/{clsx-1dnHRn8W.js → clsx-CNmW0Nip.js} +0 -0
- /package/client/dist/assets/{coffee-DSbWjzk7.js → coffee-AruSygo-.js} +0 -0
- /package/client/dist/assets/{commands-uz_uKT242.js → commands-C4Y3C-PF2.js} +0 -0
- /package/client/dist/assets/{commands-Bb7MnPqn2.js → commands-CSDs9q_2.js} +0 -0
- /package/client/dist/assets/{commands-C_7zZwJf.js → commands-DkU0qliq.js} +0 -0
- /package/client/dist/assets/{commands-D_6B8lfU.js → commands-JWMfGDmr.js} +0 -0
- /package/client/dist/assets/{commands-DBc5llLi2.js → commands-RHOchN4n2.js} +0 -0
- /package/client/dist/assets/{commands-CQkdthjF.js → commands-u-4eEHCN.js} +0 -0
- /package/client/dist/assets/{commands-DhZNhSbl.js → commands-xHDDGfcP2.js} +0 -0
- /package/client/dist/assets/{cpp-SBF8SAh9.js → cpp-DEE5r4Pw.js} +0 -0
- /package/client/dist/assets/{csharp-Lzuq_1t-.js → csharp-BVXJUvbK.js} +0 -0
- /package/client/dist/assets/{csp-BEzxZqi1.js → csp-cXOF0JoV.js} +0 -0
- /package/client/dist/assets/{css-C3D3PKln.js → css-C_zQuAoy.js} +0 -0
- /package/client/dist/assets/{cypher-CQ3dEPmv.js → cypher-t95m_Q-O.js} +0 -0
- /package/client/dist/assets/{dart-DCPmxolI.js → dart-B4r1Tg-e.js} +0 -0
- /package/client/dist/assets/{dockerfile-B_2_aaTO.js → dockerfile-6mt7zHQw.js} +0 -0
- /package/client/dist/assets/{ecl-rADUeXsV.js → ecl-DEY_Fz_Q.js} +0 -0
- /package/client/dist/assets/{editor.api2-T7u8kQWG.js → editor.api2-C3B0tp2x.js} +0 -0
- /package/client/dist/assets/{elixir-DOd-TuJO.js → elixir-R6-q1c5t.js} +0 -0
- /package/client/dist/assets/{explore-BHEhNekP2.js → explore-B7fblXBb2.js} +0 -0
- /package/client/dist/assets/{explore-DAsroA482.js → explore-BHtEpoNN2.js} +0 -0
- /package/client/dist/assets/{explore-UwHHj2ux.js → explore-C0k8HrkN.js} +0 -0
- /package/client/dist/assets/{explore-DaXiW9-6.js → explore-CNBzrEPS.js} +0 -0
- /package/client/dist/assets/{explore-CWlAXx0f2.js → explore-D_mWBYCS2.js} +0 -0
- /package/client/dist/assets/{explore-DG1CtYqT.js → explore-Dahc1lOx.js} +0 -0
- /package/client/dist/assets/{explore-DMSGAnhK.js → explore-UvW1jEMa.js} +0 -0
- /package/client/dist/assets/{flow9-Bf7zg_j0.js → flow9-CNQvHBOt.js} +0 -0
- /package/client/dist/assets/{format-command-BHymDa4r.js → format-command-CuWuRvka.js} +0 -0
- /package/client/dist/assets/{fsharp-BqROZjbA.js → fsharp-vPZkFXwv.js} +0 -0
- /package/client/dist/assets/{go-oQTP5uLe.js → go-KUzBMYJ_.js} +0 -0
- /package/client/dist/assets/{graphql-CSHfTU3q.js → graphql-C3W0rCsD.js} +0 -0
- /package/client/dist/assets/{hcl-CeG-RoFJ.js → hcl-BOOMFSNX.js} +0 -0
- /package/client/dist/assets/{ini-B2Dv4ohc.js → ini-CFat1WJr.js} +0 -0
- /package/client/dist/assets/{integrations-CAF21FbQ.js → integrations-4KZnYECp.js} +0 -0
- /package/client/dist/assets/{integrations-CHCgning2.js → integrations-7W266oqF2.js} +0 -0
- /package/client/dist/assets/{integrations-B-JVE1_D.js → integrations-BNuauK3o.js} +0 -0
- /package/client/dist/assets/{integrations-BAujIDoE.js → integrations-CHy8tnpV.js} +0 -0
- /package/client/dist/assets/{integrations-DS5FFMes.js → integrations-Cl_wD5AI.js} +0 -0
- /package/client/dist/assets/{integrations-axZN4--n2.js → integrations-Cy8nZ_dv2.js} +0 -0
- /package/client/dist/assets/{integrations-CtsOpq2D2.js → integrations-zMqY4VU12.js} +0 -0
- /package/client/dist/assets/{java-aUDDeufb.js → java-Dee-CNAM.js} +0 -0
- /package/client/dist/assets/{julia-C5LbruO5.js → julia-CGNlLYuU.js} +0 -0
- /package/client/dist/assets/{kotlin-C6mOuSKk.js → kotlin-CY7lhknJ.js} +0 -0
- /package/client/dist/assets/{less-D5qC3caW.js → less-D0KN7hfJ.js} +0 -0
- /package/client/dist/assets/{lexon-Dr2La-fj.js → lexon-CuRJufPs.js} +0 -0
- /package/client/dist/assets/{lua-Zy6u5z6Z.js → lua-DHvH62Zf.js} +0 -0
- /package/client/dist/assets/{m3-C7XHeDz_.js → m3-tlthQ8Fo.js} +0 -0
- /package/client/dist/assets/{markdown-PiF7r-2h.js → markdown-Dbx1LgUZ.js} +0 -0
- /package/client/dist/assets/{mcp-B_nWlxZa2.js → mcp-CjVKXAhD2.js} +0 -0
- /package/client/dist/assets/{mcp-B8omp_Cd.js → mcp-Dcl-XxkR.js} +0 -0
- /package/client/dist/assets/{mcp-DTCCrYHz2.js → mcp-DtbxuH3V2.js} +0 -0
- /package/client/dist/assets/{mcp-DytBbASZ.js → mcp-H-gnQUdN.js} +0 -0
- /package/client/dist/assets/{mcp-D_oPS6Zc.js → mcp-N1nzp8oL.js} +0 -0
- /package/client/dist/assets/{mcp-Cb2jtHP72.js → mcp-XJNRfxVp2.js} +0 -0
- /package/client/dist/assets/{mcp-DPqm2C8-.js → mcp-sRmWE8WJ.js} +0 -0
- /package/client/dist/assets/{mips-nn07GiyE.js → mips-D_O3IUz_.js} +0 -0
- /package/client/dist/assets/{msdax-DaKFVMST.js → msdax-C_ZmCnRt.js} +0 -0
- /package/client/dist/assets/{mysql-C6d6xrbU.js → mysql-C-dCEYSX.js} +0 -0
- /package/client/dist/assets/{nav-Cibp2KWF.js → nav-40HzpIFb.js} +0 -0
- /package/client/dist/assets/{nav-DtTnF9xd.js → nav-8yPhBn00.js} +0 -0
- /package/client/dist/assets/{nav-Danf5sRf2.js → nav-B6PkGfTk2.js} +0 -0
- /package/client/dist/assets/{nav-Bqhyfbcj2.js → nav-BHqMLrS72.js} +0 -0
- /package/client/dist/assets/{nav-CQb9y1km.js → nav-CGy4yx3C.js} +0 -0
- /package/client/dist/assets/{nav-BAsYcqdw2.js → nav-CXEDcRdv2.js} +0 -0
- /package/client/dist/assets/{nav-BRrNlZkr.js → nav-EI_OhEAo.js} +0 -0
- /package/client/dist/assets/{objective-c-B6KMtI-k.js → objective-c-DZY9Aqxd.js} +0 -0
- /package/client/dist/assets/{pascal-DYr8MPE7.js → pascal-BVHLXoor.js} +0 -0
- /package/client/dist/assets/{pascaligo-B3pd-jJ_.js → pascaligo-XdG_6u3k.js} +0 -0
- /package/client/dist/assets/{perl-z2xUzoaL.js → perl-b9QV0BcD.js} +0 -0
- /package/client/dist/assets/{pgsql-DUvT-09-.js → pgsql-Du5FDOgT.js} +0 -0
- /package/client/dist/assets/{php-CGyOmJfy.js → php-WJD0z2Z_.js} +0 -0
- /package/client/dist/assets/{pla-CMqgvyD0.js → pla-CbciTf2w.js} +0 -0
- /package/client/dist/assets/{postiats-Dx5LUn4Z.js → postiats-C1QxmvVq.js} +0 -0
- /package/client/dist/assets/{powerquery-DazYxvJ6.js → powerquery-BEYDhPLZ.js} +0 -0
- /package/client/dist/assets/{powershell-B3nwlDka.js → powershell-CfaYw4XL.js} +0 -0
- /package/client/dist/assets/{protobuf-BGuu2u2s.js → protobuf-pwZEDOYa.js} +0 -0
- /package/client/dist/assets/{pug-Dbte1MXA.js → pug-5ftqSPVe.js} +0 -0
- /package/client/dist/assets/{qsharp-DJLwBOvG.js → qsharp-uI6qZMq4.js} +0 -0
- /package/client/dist/assets/{r-DmGBRSHj.js → r-BK54P1EG.js} +0 -0
- /package/client/dist/assets/{redis-VvUYn0a4.js → redis-DI0yd7kN.js} +0 -0
- /package/client/dist/assets/{redshift-6GdDrxg3.js → redshift-Dov26eyI.js} +0 -0
- /package/client/dist/assets/{restructuredtext-CfAB8aRU.js → restructuredtext-QqJ_1dC-.js} +0 -0
- /package/client/dist/assets/{ruby-CIYK6MXY.js → ruby-5WjveeVb.js} +0 -0
- /package/client/dist/assets/{rust-CTHZfjj9.js → rust-BzVSfqFH.js} +0 -0
- /package/client/dist/assets/{sb-CkKTdkz_.js → sb-DMIUfT-3.js} +0 -0
- /package/client/dist/assets/{scala-Bx-Wr9TM.js → scala-CSKA7lqt.js} +0 -0
- /package/client/dist/assets/{scheme-Dcfi6f83.js → scheme-CojOP2Qc.js} +0 -0
- /package/client/dist/assets/{scss-ByL-7PFQ.js → scss-DoBZGJG6.js} +0 -0
- /package/client/dist/assets/{shell-Csnb9Yqd.js → shell-YOaE4udl.js} +0 -0
- /package/client/dist/assets/{solidity-Dbw5-0QP.js → solidity-l3jSyVLu.js} +0 -0
- /package/client/dist/assets/{sophia-ZQ3saZQx.js → sophia-BhSGTaQJ.js} +0 -0
- /package/client/dist/assets/{sparql-BEtOel8u.js → sparql-qhk6QD9w.js} +0 -0
- /package/client/dist/assets/{sql-DGPDbzB7.js → sql-DoO3y21-.js} +0 -0
- /package/client/dist/assets/{st-GeW2MOgh.js → st-ChZAY8oG.js} +0 -0
- /package/client/dist/assets/{swift-BVYTN8jq.js → swift-D290Tr7_.js} +0 -0
- /package/client/dist/assets/{systemverilog-Deg2a8Lr.js → systemverilog-DsxzgJ-o.js} +0 -0
- /package/client/dist/assets/{tcl-6DnLmROF.js → tcl-BKDUHAAR.js} +0 -0
- /package/client/dist/assets/{terminal-CDiOAmBd2.js → terminal-BRm03iFA2.js} +0 -0
- /package/client/dist/assets/{terminal-CJN-mQMc.js → terminal-De2Brd23.js} +0 -0
- /package/client/dist/assets/{terminal-CYB4TiAd.js → terminal-DxQWCqSD2.js} +0 -0
- /package/client/dist/assets/{terminal-DsaDTq5N2.js → terminal-WSAvHXoU.js} +0 -0
- /package/client/dist/assets/{terminal-DTQ_dPqi2.js → terminal-Z7KsDM_n.js} +0 -0
- /package/client/dist/assets/{terminal-58ReNaya.js → terminal-cqfd3EDV.js} +0 -0
- /package/client/dist/assets/{terminal-DawP8xNL.js → terminal-xGbCZJHg.js} +0 -0
- /package/client/dist/assets/{tickets-DoRTUYRT.js → tickets-B7zT4IRf.js} +0 -0
- /package/client/dist/assets/{tickets-DBfFePwk2.js → tickets-BoXom7l8.js} +0 -0
- /package/client/dist/assets/{tickets-DvohTziT2.js → tickets-C3b8cHhd2.js} +0 -0
- /package/client/dist/assets/{tickets-Da15iaRw.js → tickets-CFXnJsYF.js} +0 -0
- /package/client/dist/assets/{tickets-CujsZvkf.js → tickets-CWYFvx1W2.js} +0 -0
- /package/client/dist/assets/{tickets-Df6pee-O2.js → tickets-DTHo9c3C.js} +0 -0
- /package/client/dist/assets/{tickets-CNvIilmP.js → tickets-SuX_HkK4.js} +0 -0
- /package/client/dist/assets/{twig-XbbXW9Yz.js → twig-UpZQaM8G.js} +0 -0
- /package/client/dist/assets/{typespec-CRlV8GhI.js → typespec-DzaKvN8i.js} +0 -0
- /package/client/dist/assets/{vb-BHE2izPH.js → vb-CZpbb7tk.js} +0 -0
- /package/client/dist/assets/{wgsl-Bf5vkfmY.js → wgsl-CNt3OIvl.js} +0 -0
|
@@ -35,6 +35,7 @@ const jira_sync_manager_1 = require("./jira/jira-sync-manager");
|
|
|
35
35
|
const loop_run_manager_1 = require("./loop-run-manager");
|
|
36
36
|
const loop_executors_1 = require("./loop-executors");
|
|
37
37
|
const rail_isolated_launch_1 = require("./rail-isolated-launch");
|
|
38
|
+
const rail_isolation_1 = require("./rail-isolation");
|
|
38
39
|
const loop_runs_store_1 = require("./loop-runs-store");
|
|
39
40
|
const rails_store_1 = require("./rails-store");
|
|
40
41
|
const desktop_db_1 = require("./desktop-db");
|
|
@@ -162,6 +163,13 @@ class ProjectRegistry {
|
|
|
162
163
|
ctx.chatManager.shutdown();
|
|
163
164
|
}
|
|
164
165
|
catch { /* ignore */ }
|
|
166
|
+
// Loop engine teardown: dispose any resident interactive step sessions
|
|
167
|
+
// (SIGTERM, no settle) + kill in-flight one-shot loop children — BEFORE
|
|
168
|
+
// db.close() so a late close handler can't write to the closed handle.
|
|
169
|
+
try {
|
|
170
|
+
ctx.loopRunManager.shutdown();
|
|
171
|
+
}
|
|
172
|
+
catch { /* ignore */ }
|
|
165
173
|
try {
|
|
166
174
|
ctx.setupManager.abort(id);
|
|
167
175
|
}
|
|
@@ -310,6 +318,12 @@ class ProjectRegistry {
|
|
|
310
318
|
ctx.chatManager.shutdown();
|
|
311
319
|
}
|
|
312
320
|
catch { /* ignore */ }
|
|
321
|
+
// Loop engine: dispose resident interactive step sessions + kill in-flight
|
|
322
|
+
// one-shot loop children so a quit mid-run doesn't orphan claude processes.
|
|
323
|
+
try {
|
|
324
|
+
ctx.loopRunManager.shutdown();
|
|
325
|
+
}
|
|
326
|
+
catch { /* ignore */ }
|
|
313
327
|
// Install/enrich wizard children + the 3s install poll interval are NOT
|
|
314
328
|
// torn down by the spawner shutdowns above — mirror removeProject()'s
|
|
315
329
|
// setupManager.abort() so a quit mid-wizard doesn't orphan them.
|
|
@@ -428,7 +442,7 @@ class ProjectRegistry {
|
|
|
428
442
|
}
|
|
429
443
|
catch { /* best-effort */ }
|
|
430
444
|
},
|
|
431
|
-
onJobFinished: (jobId, status, costUsd) => {
|
|
445
|
+
onJobFinished: (jobId, status, costUsd, opts) => {
|
|
432
446
|
const jobRow = db.prepare('SELECT command, duration_ms FROM jobs WHERE id = ?').get(jobId);
|
|
433
447
|
const event = status === 'completed' ? 'job.completed' : status === 'canceled' ? 'job.canceled' : 'job.failed';
|
|
434
448
|
webhookManager.deliver(project.id, event, {
|
|
@@ -452,10 +466,20 @@ class ProjectRegistry {
|
|
|
452
466
|
completedTicketIds = matches.map((m) => parseInt(m.slice(1), 10));
|
|
453
467
|
}
|
|
454
468
|
// Apply the job outcome to its tickets. Success promotes todo/in_progress
|
|
455
|
-
// → done (→ Specs Done)
|
|
469
|
+
// → done (→ Specs Done) — or → on_review under the ask-first PR-delivery
|
|
470
|
+
// methodology (below); failure/cancel/zombie reverts in_progress → todo
|
|
456
471
|
// (→ Specs) or flags an already-done spec for review. zombie_terminated is
|
|
457
472
|
// treated as a failure here (and is included in the _onJobExit callback
|
|
458
473
|
// guard) so a timed-out rail releases its specs instead of stranding them.
|
|
474
|
+
//
|
|
475
|
+
// Ask-first methodology (safe-pr-workflow, universal): QueueManager
|
|
476
|
+
// captures the PR-delivery flag ONCE at this job's spawn and threads it
|
|
477
|
+
// here as `opts.ticketCompletionStatus` — so a mid-flight env flip can't
|
|
478
|
+
// split one job's behavior. Under the flag a COMPLETED job parks its
|
|
479
|
+
// tickets at on_review (the human decides done via PR merge or a manual
|
|
480
|
+
// move), never done. Absent opts (legacy callers / never-spawned failure
|
|
481
|
+
// paths) ⇒ 'done', byte-identical to the pre-change promotion.
|
|
482
|
+
const completedStatus = opts?.ticketCompletionStatus ?? 'done';
|
|
459
483
|
if (completedTicketIds.length > 0 &&
|
|
460
484
|
(status === 'completed' || status === 'failed' || status === 'canceled' || status === 'zombie_terminated')) {
|
|
461
485
|
try {
|
|
@@ -468,7 +492,7 @@ class ProjectRegistry {
|
|
|
468
492
|
const now = new Date().toISOString();
|
|
469
493
|
let changedIds = [];
|
|
470
494
|
const store = (0, ticket_store_1.mutateStore)(ticketFile, (s) => {
|
|
471
|
-
changedIds = (0, ticket_store_1.applyJobOutcomeToTickets)(s, completedTicketIds, status, now);
|
|
495
|
+
changedIds = (0, ticket_store_1.applyJobOutcomeToTickets)(s, completedTicketIds, status, now, { completedStatus });
|
|
472
496
|
});
|
|
473
497
|
for (const tid of changedIds) {
|
|
474
498
|
const ticket = store.tickets[String(tid)];
|
|
@@ -487,15 +511,24 @@ class ProjectRegistry {
|
|
|
487
511
|
// wrapped so a Jira failure can never break the job-exit handler.
|
|
488
512
|
if (status === 'completed' || status === 'failed' || status === 'canceled' || status === 'zombie_terminated') {
|
|
489
513
|
try {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
514
|
+
if (status === 'completed' && completedStatus === 'on_review') {
|
|
515
|
+
// Under review, not done — enqueue the Jira on_review
|
|
516
|
+
// transition instead of the done-flavoured completion
|
|
517
|
+
// (comment + Done). Mirrors onLoopRunFinished's split; the
|
|
518
|
+
// Done transition rides the later PR-merge / manual move.
|
|
519
|
+
jiraSyncManager.onRailReview(changedIds, jobId);
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
const needsReviewIds = completedTicketIds.filter((tid) => store.tickets[String(tid)]?.needs_review === true);
|
|
523
|
+
jiraSyncManager.onJobOutcome({
|
|
524
|
+
ticketIds: completedTicketIds,
|
|
525
|
+
status,
|
|
526
|
+
jobId,
|
|
527
|
+
costUsd: costUsd ?? null,
|
|
528
|
+
durationMs: jobRow?.duration_ms ?? null,
|
|
529
|
+
needsReviewIds,
|
|
530
|
+
});
|
|
531
|
+
}
|
|
499
532
|
}
|
|
500
533
|
catch (err) {
|
|
501
534
|
console.error('[project-registry] jira onJobOutcome failed:', err);
|
|
@@ -650,7 +683,16 @@ class ProjectRegistry {
|
|
|
650
683
|
.then((n) => { if (n > 0)
|
|
651
684
|
console.log(`[loops] reconciled ${n} orphan worktree(s) for ${project.slug}`); })
|
|
652
685
|
.catch(() => { });
|
|
653
|
-
|
|
686
|
+
// Loop executors resolve their base env LAZILY per step: a RELOCATED project
|
|
687
|
+
// injects core's env-first artifact indirection (tickets/backlog/profiles/
|
|
688
|
+
// state → the workspace) so an ISOLATED worktree run — whose cwd-relative
|
|
689
|
+
// `${ENV:-legacy}` defaults resolve inside the worktree, where only tracked
|
|
690
|
+
// files exist — still reads the real project state. SPECRAILS_REPO_DIR stays
|
|
691
|
+
// per-run (the worktree for isolated runs). Legacy projects keep process.env
|
|
692
|
+
// byte-identical. See resolveLoopBaseEnv.
|
|
693
|
+
const loopRunManager = new loop_run_manager_1.LoopRunManager(db, boundBroadcast, (0, loop_executors_1.createLoopExecutors)({
|
|
694
|
+
env: () => (0, workspace_resolution_1.resolveLoopBaseEnv)({ slug: project.slug, path: project.path }),
|
|
695
|
+
}));
|
|
654
696
|
const getTicketSpec = (ticketId) => {
|
|
655
697
|
try {
|
|
656
698
|
const exec = (0, workspace_resolution_1.resolveProjectExecution)({ slug: project.slug, path: project.path });
|
|
@@ -677,7 +719,7 @@ class ProjectRegistry {
|
|
|
677
719
|
// Releases a finished loop run's tickets + rail slots. The engine already
|
|
678
720
|
// emitted loop.run_completed; this mirrors onJobFinished's ticket/rail
|
|
679
721
|
// release (kept separate so the critical job path is untouched).
|
|
680
|
-
const onLoopRunFinished = (runId, outcome) => {
|
|
722
|
+
const onLoopRunFinished = (runId, outcome, opts) => {
|
|
681
723
|
const meta = railLoopRuns.get(runId);
|
|
682
724
|
if (!meta)
|
|
683
725
|
return;
|
|
@@ -686,13 +728,23 @@ class ProjectRegistry {
|
|
|
686
728
|
if (ticketIds.length === 0)
|
|
687
729
|
return;
|
|
688
730
|
const status = outcome === 'success' ? 'completed' : outcome === 'stopped' ? 'canceled' : 'failed';
|
|
731
|
+
// Ask-first PR delivery parks a completed run's tickets at on_review (the
|
|
732
|
+
// user decides done vs discard via the PR decision flow / a manual move).
|
|
733
|
+
// Explicit opts (the isolated-rail launch passes its launch-captured
|
|
734
|
+
// prMode) always win — idempotent with the default. ABSENT opts
|
|
735
|
+
// (shared-cwd rail runs, standalone loop runs, isolation-unavailable
|
|
736
|
+
// fallbacks) derive the default from the PR-delivery flag, read ONCE here
|
|
737
|
+
// and reused by the Jira split below so one settle can never split across
|
|
738
|
+
// the two paths. Kill-switch off ⇒ 'done', the legacy promotion
|
|
739
|
+
// byte-identical; failures ignore the field.
|
|
740
|
+
const completedStatus = opts?.ticketCompletionStatus ?? ((0, rail_isolation_1.isRailPrDeliveryEnabled)() ? 'on_review' : 'done');
|
|
689
741
|
try {
|
|
690
742
|
const exec = (0, workspace_resolution_1.resolveProjectExecution)({ slug: project.slug, path: project.path });
|
|
691
743
|
const ticketFile = exec.relocated ? exec.ticketsPath : (0, ticket_store_1.resolveTicketStoragePath)(project.path);
|
|
692
744
|
const now = new Date().toISOString();
|
|
693
745
|
let changedIds = [];
|
|
694
746
|
const store = (0, ticket_store_1.mutateStore)(ticketFile, (s) => {
|
|
695
|
-
changedIds = (0, ticket_store_1.applyJobOutcomeToTickets)(s, ticketIds, status, now);
|
|
747
|
+
changedIds = (0, ticket_store_1.applyJobOutcomeToTickets)(s, ticketIds, status, now, { completedStatus });
|
|
696
748
|
});
|
|
697
749
|
for (const tid of changedIds) {
|
|
698
750
|
const ticket = store.tickets[String(tid)];
|
|
@@ -706,8 +758,16 @@ class ProjectRegistry {
|
|
|
706
758
|
});
|
|
707
759
|
}
|
|
708
760
|
try {
|
|
709
|
-
|
|
710
|
-
|
|
761
|
+
if (status === 'completed' && completedStatus === 'on_review') {
|
|
762
|
+
// Under review, not done — enqueue the Jira on_review transition
|
|
763
|
+
// instead of the done-flavoured completion (comment + Done). The
|
|
764
|
+
// Done transition rides the later PR-merge / manual move.
|
|
765
|
+
jiraSyncManager.onRailReview(changedIds, runId);
|
|
766
|
+
}
|
|
767
|
+
else {
|
|
768
|
+
const needsReviewIds = ticketIds.filter((tid) => store.tickets[String(tid)]?.needs_review === true);
|
|
769
|
+
jiraSyncManager.onJobOutcome({ ticketIds, status, jobId: runId, costUsd: null, durationMs: null, needsReviewIds });
|
|
770
|
+
}
|
|
711
771
|
}
|
|
712
772
|
catch (err) {
|
|
713
773
|
console.error('[project-registry] jira loop onJobOutcome failed:', err);
|
|
@@ -9,6 +9,7 @@ const hooks_1 = require("./hooks");
|
|
|
9
9
|
const explore_smash_1 = require("./explore-smash");
|
|
10
10
|
const spec_models_1 = require("./spec-models");
|
|
11
11
|
const provider_selection_1 = require("./provider-selection");
|
|
12
|
+
const loop_runs_store_1 = require("./loop-runs-store");
|
|
12
13
|
const metrics_1 = require("./metrics");
|
|
13
14
|
const ticket_store_1 = require("./ticket-store");
|
|
14
15
|
const project_router_helpers_1 = require("./project-router-helpers");
|
|
@@ -117,6 +118,16 @@ function registerJobsRoutes(deps) {
|
|
|
117
118
|
}
|
|
118
119
|
catch (err) {
|
|
119
120
|
if (err instanceof queue_manager_1.JobNotFoundError) {
|
|
121
|
+
// STANDALONE loop runs (railIndex=null, POST /loop-runs) never enter
|
|
122
|
+
// railLoopRuns, so they fall through to the queue and land here while
|
|
123
|
+
// the loop is still executing — cancel through the engine instead of
|
|
124
|
+
// 404ing with a live child (the mission-modal "cancel did nothing" bug).
|
|
125
|
+
const loopRun = (0, loop_runs_store_1.getLoopRun)(c.db, id);
|
|
126
|
+
if (loopRun && loopRun.status === 'running' && c.loopRunManager) {
|
|
127
|
+
c.loopRunManager.cancel(id);
|
|
128
|
+
res.json({ ok: true, status: 'canceling' });
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
120
131
|
res.status(404).json({ error: 'Job not found' });
|
|
121
132
|
}
|
|
122
133
|
else if (err instanceof queue_manager_1.JobAlreadyTerminalError) {
|
|
@@ -134,10 +145,14 @@ function registerJobsRoutes(deps) {
|
|
|
134
145
|
}
|
|
135
146
|
}
|
|
136
147
|
});
|
|
137
|
-
// ─── Interactive
|
|
148
|
+
// ─── Interactive jobs (manager-agnostic) ───────────────────────────────────
|
|
138
149
|
// Send one more user prompt to a running interactive job (queued behind the
|
|
139
|
-
// active turn — see InteractiveJobSession).
|
|
140
|
-
//
|
|
150
|
+
// active turn — see InteractiveJobSession). The job row may be owned by
|
|
151
|
+
// EITHER manager: QueueManager (rail/ultracode/spawned jobs) or
|
|
152
|
+
// LoopRunManager (a loop run's job row, addressed by its ACTIVE step
|
|
153
|
+
// session). Try the queue first, then the loop engine. 202 = accepted;
|
|
154
|
+
// 409 = neither manager has an active interactive session for the id
|
|
155
|
+
// (unknown / non-interactive / finalized / between loop steps).
|
|
141
156
|
router.post('/:projectId/jobs/:id/messages', (req, res) => {
|
|
142
157
|
if (!(0, feature_flags_1.isInteractiveJobsEnabled)()) {
|
|
143
158
|
res.status(403).json({ error: 'Interactive jobs are disabled on this server' });
|
|
@@ -148,9 +163,10 @@ function registerJobsRoutes(deps) {
|
|
|
148
163
|
res.status(400).json({ error: 'text is required' });
|
|
149
164
|
return;
|
|
150
165
|
}
|
|
151
|
-
const
|
|
166
|
+
const c = ctx(req);
|
|
152
167
|
const jobId = req.params.id;
|
|
153
|
-
const accepted = queueManager.sendInteractiveTurn(jobId, text)
|
|
168
|
+
const accepted = c.queueManager.sendInteractiveTurn(jobId, text)
|
|
169
|
+
|| (c.loopRunManager?.sendInteractiveTurn(jobId, text) ?? false);
|
|
154
170
|
if (!accepted) {
|
|
155
171
|
res.status(409).json({ error: 'Job is not an active interactive session' });
|
|
156
172
|
return;
|
|
@@ -158,22 +174,25 @@ function registerJobsRoutes(deps) {
|
|
|
158
174
|
res.status(202).json({ ok: true });
|
|
159
175
|
});
|
|
160
176
|
// Finalize a running interactive job: SIGTERM the resident child; the summed
|
|
161
|
-
// token/cost totals +
|
|
177
|
+
// token/cost totals + terminal status are stamped asynchronously when the
|
|
162
178
|
// child closes (the client also learns the final state via the job.finalized
|
|
163
|
-
// WS broadcast).
|
|
179
|
+
// WS broadcast). On a QueueManager job this completes the JOB; on a loop
|
|
180
|
+
// run's job it settles the ACTIVE STEP now — the loop advances with what the
|
|
181
|
+
// step produced. 202 = finalize scheduled; 409 = not an active interactive job.
|
|
164
182
|
router.post('/:projectId/jobs/:id/finalize', (req, res) => {
|
|
165
183
|
if (!(0, feature_flags_1.isInteractiveJobsEnabled)()) {
|
|
166
184
|
res.status(403).json({ error: 'Interactive jobs are disabled on this server' });
|
|
167
185
|
return;
|
|
168
186
|
}
|
|
169
|
-
const
|
|
187
|
+
const c = ctx(req);
|
|
170
188
|
const jobId = req.params.id;
|
|
171
|
-
const scheduled = queueManager.finalizeInteractive(jobId)
|
|
189
|
+
const scheduled = c.queueManager.finalizeInteractive(jobId)
|
|
190
|
+
|| (c.loopRunManager?.finalizeInteractive(jobId) ?? false);
|
|
172
191
|
if (!scheduled) {
|
|
173
192
|
res.status(409).json({ error: 'Job is not an active interactive session' });
|
|
174
193
|
return;
|
|
175
194
|
}
|
|
176
|
-
res.status(202).json({ ok: true, job: (0, db_1.getJob)(db, jobId) ?? null });
|
|
195
|
+
res.status(202).json({ ok: true, job: (0, db_1.getJob)(c.db, jobId) ?? null });
|
|
177
196
|
});
|
|
178
197
|
router.patch('/:projectId/jobs/:id/priority', (req, res) => {
|
|
179
198
|
const { priority } = req.body ?? {};
|
|
@@ -367,7 +386,8 @@ function registerJobsRoutes(deps) {
|
|
|
367
386
|
res.json({ jobs: rows });
|
|
368
387
|
});
|
|
369
388
|
router.get('/:projectId/jobs/:id', (req, res) => {
|
|
370
|
-
const
|
|
389
|
+
const c = ctx(req);
|
|
390
|
+
const { db, queueManager, project } = c;
|
|
371
391
|
const jobId = req.params.id;
|
|
372
392
|
const job = (0, db_1.getJob)(db, jobId);
|
|
373
393
|
if (!job) {
|
|
@@ -405,13 +425,33 @@ function registerJobsRoutes(deps) {
|
|
|
405
425
|
};
|
|
406
426
|
const phaseDefinitions = queueManager.phasesForCommand(synthetic.command);
|
|
407
427
|
const tickets = (0, ticket_store_1.resolveTicketsFromCommand)(project.path, synthetic.command, ticketPath(req));
|
|
408
|
-
|
|
428
|
+
// Queued ⇒ no resident session yet; the client refetches on the
|
|
429
|
+
// queued→running flip to learn the real interactive surface state.
|
|
430
|
+
res.json({
|
|
431
|
+
job: { ...synthetic, hasTelemetry: false, tickets, interactiveSettleMode: null, interactiveAcceptingTurns: false },
|
|
432
|
+
events: [],
|
|
433
|
+
phaseDefinitions,
|
|
434
|
+
});
|
|
409
435
|
return;
|
|
410
436
|
}
|
|
411
437
|
const events = (0, db_1.getJobEvents)(db, jobId);
|
|
412
438
|
const phaseDefinitions = queueManager.phasesForCommand(job.command);
|
|
413
439
|
const tickets = (0, ticket_store_1.resolveTicketsFromCommand)(project.path, job.command, ticketPath(req));
|
|
414
|
-
|
|
440
|
+
// Interactive surface state (S3): the settle mode of the resident session
|
|
441
|
+
// plus whether it is accepting turns RIGHT NOW. A QueueManager job's session
|
|
442
|
+
// lives for the whole run; a loop run's ACTIVE ai-step owns it (absent
|
|
443
|
+
// between steps / decider / shell nodes — POST /messages would 409 there).
|
|
444
|
+
// A between-steps loop GET still reports 'auto' via its loop_runs row so the
|
|
445
|
+
// composer can phrase the waiting state truthfully instead of guessing.
|
|
446
|
+
let interactiveSettleMode = null;
|
|
447
|
+
let interactiveAcceptingTurns = false;
|
|
448
|
+
if ((0, feature_flags_1.isInteractiveJobsEnabled)() && job.interactive && job.status === 'running') {
|
|
449
|
+
const qmMode = queueManager.getInteractiveSettleMode?.(jobId) ?? null;
|
|
450
|
+
const loopStepActive = c.loopRunManager?.isInteractiveJob?.(jobId) ?? false;
|
|
451
|
+
interactiveAcceptingTurns = qmMode !== null || loopStepActive;
|
|
452
|
+
interactiveSettleMode = qmMode ?? ((loopStepActive || (0, loop_runs_store_1.getLoopRun)(db, jobId)) ? 'auto' : null);
|
|
453
|
+
}
|
|
454
|
+
const annotated = { ...job, hasTelemetry: (0, db_1.hasJobTelemetry)(db, jobId), tickets, interactiveSettleMode, interactiveAcceptingTurns };
|
|
415
455
|
res.json({ job: annotated, events, phaseDefinitions });
|
|
416
456
|
});
|
|
417
457
|
router.delete('/:projectId/jobs', (req, res) => {
|
|
@@ -10,6 +10,8 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
10
10
|
const path_1 = __importDefault(require("path"));
|
|
11
11
|
const db_1 = require("./db");
|
|
12
12
|
const telemetry_export_1 = require("./telemetry-export");
|
|
13
|
+
const integration_branch_1 = require("./integration-branch");
|
|
14
|
+
const worktree_manager_1 = require("./worktree-manager");
|
|
13
15
|
const context_budget_1 = require("./context-budget");
|
|
14
16
|
const context_scope_1 = require("./context-scope");
|
|
15
17
|
const terminal_settings_1 = require("./terminal-settings");
|
|
@@ -101,6 +103,20 @@ function registerSettingsRoutes(deps) {
|
|
|
101
103
|
}
|
|
102
104
|
patch.ultraPrePrompt = ultraPrePrompt;
|
|
103
105
|
}
|
|
106
|
+
if (req.body?.integrationBranch !== undefined) {
|
|
107
|
+
const ib = req.body.integrationBranch;
|
|
108
|
+
if (typeof ib !== 'string') {
|
|
109
|
+
res.status(400).json({ error: 'integrationBranch must be a string' });
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
// Empty = clear (auto-resolve). A non-empty value flows into `git worktree
|
|
113
|
+
// add … <base>`, so it must be a safe branch name (no arg-injection).
|
|
114
|
+
if (ib.trim() !== '' && !(0, integration_branch_1.isValidBranchName)(ib)) {
|
|
115
|
+
res.status(400).json({ error: 'integrationBranch is not a valid branch name' });
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
patch.integrationBranch = ib;
|
|
119
|
+
}
|
|
104
120
|
try {
|
|
105
121
|
(0, db_1.updateProjectSettings)(ctx(req).db, patch);
|
|
106
122
|
res.json({ ok: true, settings: (0, db_1.getProjectSettings)(ctx(req).db) });
|
|
@@ -110,6 +126,23 @@ function registerSettingsRoutes(deps) {
|
|
|
110
126
|
res.status(500).json({ error: 'Failed to update settings' });
|
|
111
127
|
}
|
|
112
128
|
});
|
|
129
|
+
// Resolve the effective integration branch (configured value + what it resolves
|
|
130
|
+
// to right now + provenance) so the client can show the base before launch.
|
|
131
|
+
router.get('/:projectId/integration-branch', async (req, res) => {
|
|
132
|
+
const { project, db } = ctx(req);
|
|
133
|
+
const configured = (0, db_1.getProjectSettings)(db).integrationBranch;
|
|
134
|
+
try {
|
|
135
|
+
const resolved = await (0, integration_branch_1.resolveIntegrationBranch)(worktree_manager_1.defaultGitRunner, {
|
|
136
|
+
repoDir: project.path,
|
|
137
|
+
projectSetting: configured,
|
|
138
|
+
});
|
|
139
|
+
res.json({ configured, branch: resolved.branch, source: resolved.source });
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
console.error('[project-router] integration-branch resolve failed:', err);
|
|
143
|
+
res.status(500).json({ error: 'failed to resolve integration branch' });
|
|
144
|
+
}
|
|
145
|
+
});
|
|
113
146
|
// ─── Agent models ────────────────────────────────────────────────────────────
|
|
114
147
|
router.get('/:projectId/agent-models', (req, res) => {
|
|
115
148
|
const { project } = ctx(req);
|
|
@@ -300,6 +300,22 @@ function registerTerminalsRoutes(deps) {
|
|
|
300
300
|
res.status(500).json({ error: 'Failed clipboard op' });
|
|
301
301
|
}
|
|
302
302
|
});
|
|
303
|
+
// Switch the viewed page between the root page and the top popup (OAuth login
|
|
304
|
+
// window). Low-rate UI action → REST, not the WS control channel.
|
|
305
|
+
router.post('/:projectId/browser/sessions/:id/popup-view', requireBrowserCaptureEnabled, (req, res) => {
|
|
306
|
+
const mgr = ctx(req).browserCaptureManager;
|
|
307
|
+
const target = req.body?.target;
|
|
308
|
+
if (target !== 'root' && target !== 'popup') {
|
|
309
|
+
res.status(400).json({ error: 'target must be root | popup' });
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const ok = mgr.setPopupView(req.params.id, target);
|
|
313
|
+
if (!ok) {
|
|
314
|
+
res.status(404).json({ error: 'browser_session_not_found' });
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
res.json({ ok: true });
|
|
318
|
+
});
|
|
303
319
|
router.delete('/:projectId/browser/sessions/:id', requireBrowserCaptureEnabled, async (req, res) => {
|
|
304
320
|
const mgr = ctx(req).browserCaptureManager;
|
|
305
321
|
const ok = await mgr.kill(req.params.id);
|
|
@@ -1034,6 +1034,41 @@ function registerTicketsRoutes(deps) {
|
|
|
1034
1034
|
else if (conversationId && created && convoProvider && convoProvider !== 'claude') {
|
|
1035
1035
|
console.log(`[project-router] from-draft contract refine skipped for ${convoProvider} conversation (ticket #${created.id})`);
|
|
1036
1036
|
}
|
|
1037
|
+
else if (!conversationId && draftTicketId === null && created && body.contractRefine === true) {
|
|
1038
|
+
// Conversation-less commits (the in-app operator agent's commit_draft
|
|
1039
|
+
// path — a spec authored in the agent conversation, no Explore origin):
|
|
1040
|
+
// `contractRefine: true` on the body opts the fresh spec into the SAME
|
|
1041
|
+
// post-persist Contract Layer enrichment the Quick path runs (no
|
|
1042
|
+
// --resume; seeded with the just-inserted spec body). Default OFF at
|
|
1043
|
+
// this layer so Explore-client payloads stay byte-identical — the MCP
|
|
1044
|
+
// specs facade defaults it ON for agent-authored commit_drafts. The
|
|
1045
|
+
// kill switch is checked inside the runner; Claude-only because the
|
|
1046
|
+
// refine spawn hardcodes the `claude` binary.
|
|
1047
|
+
const projectProviders = Array.isArray(project.providers) && project.providers.length > 0
|
|
1048
|
+
? project.providers
|
|
1049
|
+
: [project.provider].filter((p) => typeof p === 'string');
|
|
1050
|
+
if (projectProviders.includes('claude')) {
|
|
1051
|
+
const refineTicketId = created.id;
|
|
1052
|
+
const refineTitle = created.title;
|
|
1053
|
+
const refineDescription = created.description;
|
|
1054
|
+
console.log(`[project-router] from-draft hook: scheduling quick-style refine for agent-authored ticket=${refineTicketId}`);
|
|
1055
|
+
process.nextTick(() => {
|
|
1056
|
+
void (0, contract_refine_runner_1.runContractRefineForQuick)({
|
|
1057
|
+
db: ctx(req).db,
|
|
1058
|
+
projectId: project.id,
|
|
1059
|
+
projectSlug: project.slug,
|
|
1060
|
+
projectPath: project.path,
|
|
1061
|
+
projectName: project.name,
|
|
1062
|
+
broadcast: broadcast,
|
|
1063
|
+
}, refineTicketId, refineTitle, refineDescription, null).catch((err) => {
|
|
1064
|
+
console.error('[project-router] from-draft runContractRefineForQuick error:', err);
|
|
1065
|
+
});
|
|
1066
|
+
});
|
|
1067
|
+
}
|
|
1068
|
+
else {
|
|
1069
|
+
console.log(`[project-router] from-draft contract refine skipped (ticket #${created.id}): claude not installed on project`);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1037
1072
|
}
|
|
1038
1073
|
catch (err) {
|
|
1039
1074
|
console.error('[project-router] from-draft create error:', err);
|
|
@@ -1166,7 +1201,26 @@ function registerTicketsRoutes(deps) {
|
|
|
1166
1201
|
return;
|
|
1167
1202
|
}
|
|
1168
1203
|
if (!ticket.origin_conversation_id) {
|
|
1169
|
-
|
|
1204
|
+
// No Explore origin (agent-authored commit_draft / Quick spec that
|
|
1205
|
+
// skipped the refine): fall back to the Quick-style refine, seeded
|
|
1206
|
+
// with the ticket's user-authored body (existing Contract Layer
|
|
1207
|
+
// stripped so a re-run is seeded clean — the writer replaces any
|
|
1208
|
+
// prior layer idempotently anyway).
|
|
1209
|
+
const seedBody = (0, explore_contract_refine_1.splitDescriptionAtContractLayer)(ticket.description ?? '').user;
|
|
1210
|
+
const seedTitle = ticket.title;
|
|
1211
|
+
res.status(202).json({ scheduled: true, mode: 'quick' });
|
|
1212
|
+
process.nextTick(() => {
|
|
1213
|
+
void (0, contract_refine_runner_1.runContractRefineForQuick)({
|
|
1214
|
+
db,
|
|
1215
|
+
projectId: project.id,
|
|
1216
|
+
projectSlug: project.slug,
|
|
1217
|
+
projectPath: project.path,
|
|
1218
|
+
projectName: project.name,
|
|
1219
|
+
broadcast: broadcast,
|
|
1220
|
+
}, ticketId, seedTitle, seedBody, null).catch((err) => {
|
|
1221
|
+
console.error('[project-router] retry runContractRefineForQuick error:', err);
|
|
1222
|
+
});
|
|
1223
|
+
});
|
|
1170
1224
|
return;
|
|
1171
1225
|
}
|
|
1172
1226
|
const convoId = ticket.origin_conversation_id;
|
|
@@ -1322,7 +1376,7 @@ function registerTicketsRoutes(deps) {
|
|
|
1322
1376
|
return;
|
|
1323
1377
|
}
|
|
1324
1378
|
if (status !== undefined && !(0, ticket_store_1.isValidStatus)(status)) {
|
|
1325
|
-
res.status(400).json({ error: 'status must be one of: draft, todo, in_progress, done, cancelled' });
|
|
1379
|
+
res.status(400).json({ error: 'status must be one of: draft, todo, in_progress, on_review, done, cancelled' });
|
|
1326
1380
|
return;
|
|
1327
1381
|
}
|
|
1328
1382
|
const finalStatus = (status ?? 'todo');
|
|
@@ -1382,7 +1436,7 @@ function registerTicketsRoutes(deps) {
|
|
|
1382
1436
|
}
|
|
1383
1437
|
const { title, description, status, priority, labels, assignee, prerequisites, metadata, acceptanceCriteria, short_summary } = req.body ?? {};
|
|
1384
1438
|
if (status !== undefined && !(0, ticket_store_1.isValidStatus)(status)) {
|
|
1385
|
-
res.status(400).json({ error: 'status must be one of: draft, todo, in_progress, done, cancelled' });
|
|
1439
|
+
res.status(400).json({ error: 'status must be one of: draft, todo, in_progress, on_review, done, cancelled' });
|
|
1386
1440
|
return;
|
|
1387
1441
|
}
|
|
1388
1442
|
if (priority !== undefined && priority !== null && !(0, ticket_store_1.isValidPriority)(priority)) {
|
|
@@ -11,6 +11,10 @@ const code_explorer_router_1 = require("./code-explorer-router");
|
|
|
11
11
|
const jira_router_1 = require("./jira-router");
|
|
12
12
|
const ticket_store_1 = require("./ticket-store");
|
|
13
13
|
const workspace_resolution_1 = require("./workspace-resolution");
|
|
14
|
+
const file_story_manager_1 = require("./file-story-manager");
|
|
15
|
+
const file_summary_generator_1 = require("./file-summary-generator");
|
|
16
|
+
const providers_1 = require("./providers");
|
|
17
|
+
const desktop_db_1 = require("./desktop-db");
|
|
14
18
|
const project_router_jobs_1 = require("./project-router-jobs");
|
|
15
19
|
const project_router_spending_1 = require("./project-router-spending");
|
|
16
20
|
const project_router_chat_1 = require("./project-router-chat");
|
|
@@ -85,19 +89,54 @@ function createProjectRouter(registry) {
|
|
|
85
89
|
const codeRouterByCtx = new WeakMap();
|
|
86
90
|
router.use('/:projectId/code', (req, res, next) => {
|
|
87
91
|
const projectCtx = ctx(req);
|
|
88
|
-
const codeRouter = memoizedSubRouter(codeRouterByCtx, projectCtx, () =>
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
92
|
+
const codeRouter = memoizedSubRouter(codeRouterByCtx, projectCtx, () => {
|
|
93
|
+
// Construction-story contribution generator — per-ctx (memoized with the
|
|
94
|
+
// router). Reuses the file-summary spawn skeleton with the story prompt,
|
|
95
|
+
// and the SAME monthly budget setting + ai_invocations surface, so the
|
|
96
|
+
// whole Code-section AI spend rides one budget (see file-story-manager).
|
|
97
|
+
const storyAdapter = (0, providers_1.getAdapter)(projectCtx.project.provider ?? 'claude');
|
|
98
|
+
const fileStoryManager = new file_story_manager_1.FileStoryManager({
|
|
99
|
+
db: projectCtx.db,
|
|
100
|
+
broadcast: projectCtx.broadcast,
|
|
101
|
+
generate: (0, file_summary_generator_1.createFileSummaryGenerator)({
|
|
102
|
+
adapter: storyAdapter,
|
|
103
|
+
cwd: projectCtx.project.path,
|
|
104
|
+
systemPrompt: file_story_manager_1.buildStorySystemPrompt,
|
|
105
|
+
}),
|
|
106
|
+
monthToDateSpend: (projectId) => {
|
|
107
|
+
const row = projectCtx.db.prepare(`SELECT COALESCE(SUM(total_cost_usd), 0) AS total FROM ai_invocations
|
|
108
|
+
WHERE project_id = ? AND surface = 'file-summary'
|
|
109
|
+
AND started_at >= strftime('%Y-%m-01', 'now')`).get(projectId);
|
|
110
|
+
return row?.total ?? 0;
|
|
111
|
+
},
|
|
112
|
+
monthlyBudgetUsd: () => {
|
|
113
|
+
const raw = (0, desktop_db_1.getDesktopSetting)(projectCtx.desktopDb, 'summary_monthly_budget_usd');
|
|
114
|
+
const n = parseFloat(raw ?? '5.00');
|
|
115
|
+
return isNaN(n) ? 5.0 : n;
|
|
116
|
+
},
|
|
117
|
+
language: () => {
|
|
118
|
+
const raw = (0, desktop_db_1.getDesktopSetting)(projectCtx.desktopDb, 'summary_language');
|
|
119
|
+
return raw === 'es' ? 'es' : 'en';
|
|
120
|
+
},
|
|
121
|
+
providerId: () => storyAdapter.id,
|
|
122
|
+
getTicketSpec: projectCtx.getTicketSpec,
|
|
123
|
+
});
|
|
124
|
+
return (0, code_explorer_router_1.createCodeExplorerRouter)({
|
|
125
|
+
db: projectCtx.db,
|
|
126
|
+
projectPath: projectCtx.project.path,
|
|
127
|
+
projectId: projectCtx.project.id,
|
|
128
|
+
broadcast: projectCtx.broadcast,
|
|
129
|
+
fileSummaryManager: projectCtx.fileSummaryManager,
|
|
130
|
+
getTicketSpec: projectCtx.getTicketSpec,
|
|
131
|
+
fileStoryManager,
|
|
132
|
+
// Relocate-artifacts: summary JSON OUTPUTS live in the workspace when
|
|
133
|
+
// relocated (source tree still read from project.path). Resolved per-call.
|
|
134
|
+
resolveSummaryRoot: () => {
|
|
135
|
+
const exec = (0, workspace_resolution_1.resolveProjectExecution)({ slug: projectCtx.project.slug, path: projectCtx.project.path });
|
|
136
|
+
return exec.relocated && exec.workspaceDir ? exec.workspaceDir : projectCtx.project.path;
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
});
|
|
101
140
|
codeRouter(req, res, next);
|
|
102
141
|
});
|
|
103
142
|
// Relocate-artifacts gate (single chokepoint for ALL project-router ticket
|