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
package/server/dist/db.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.DEFAULT_ULTRACODE_PRE_PROMPT = void 0;
|
|
7
7
|
exports.initDb = initDb;
|
|
8
8
|
exports.createJob = createJob;
|
|
9
|
+
exports.markJobInteractive = markJobInteractive;
|
|
9
10
|
exports.accumulateInteractiveTurn = accumulateInteractiveTurn;
|
|
10
11
|
exports.finalizeInteractiveJob = finalizeInteractiveJob;
|
|
11
12
|
exports.finishJob = finishJob;
|
|
@@ -719,6 +720,87 @@ const MIGRATIONS = [
|
|
|
719
720
|
CREATE INDEX IF NOT EXISTS idx_rail_worktrees_rail ON rail_worktrees(rail_index);
|
|
720
721
|
`);
|
|
721
722
|
},
|
|
723
|
+
// Migration 36: rail_pr_deliveries — one row per isolated rail LAUNCH tracking
|
|
724
|
+
// the ask-first PR decision lifecycle (building → on_review → pr_draft →
|
|
725
|
+
// pr_ready → merged | discarded | pr_failed). The durable single source of
|
|
726
|
+
// truth both decision surfaces (rail row + agent chat) read and write, so a
|
|
727
|
+
// refresh/restart never loses a pending PR decision. `branches` captures the
|
|
728
|
+
// per-unit DeliverBranch records at build-settle (deferred deliverRailAsPr
|
|
729
|
+
// cannot be reconstructed without them); `worktree_ids` links the
|
|
730
|
+
// rail_worktrees ledger rows for discard cleanup. Additive + idempotent.
|
|
731
|
+
(db) => {
|
|
732
|
+
db.exec(`
|
|
733
|
+
CREATE TABLE IF NOT EXISTS rail_pr_deliveries (
|
|
734
|
+
id TEXT PRIMARY KEY,
|
|
735
|
+
rail_index INTEGER NOT NULL,
|
|
736
|
+
loop_id TEXT,
|
|
737
|
+
rail_key TEXT NOT NULL,
|
|
738
|
+
ticket_ids TEXT NOT NULL,
|
|
739
|
+
base_branch TEXT NOT NULL,
|
|
740
|
+
branch TEXT,
|
|
741
|
+
pr_url TEXT,
|
|
742
|
+
pr_number INTEGER,
|
|
743
|
+
pr_state TEXT NOT NULL DEFAULT 'none',
|
|
744
|
+
decision TEXT NOT NULL DEFAULT 'building',
|
|
745
|
+
branches TEXT NOT NULL DEFAULT '[]',
|
|
746
|
+
loop_name TEXT NOT NULL DEFAULT '',
|
|
747
|
+
worktree_ids TEXT NOT NULL DEFAULT '[]',
|
|
748
|
+
origin_surface TEXT NOT NULL DEFAULT 'dashboard',
|
|
749
|
+
origin_conversation_id TEXT,
|
|
750
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
751
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
752
|
+
);
|
|
753
|
+
CREATE INDEX IF NOT EXISTS idx_rail_pr_deliveries_rail ON rail_pr_deliveries(rail_index);
|
|
754
|
+
CREATE INDEX IF NOT EXISTS idx_rail_pr_deliveries_active ON rail_pr_deliveries(decision);
|
|
755
|
+
`);
|
|
756
|
+
},
|
|
757
|
+
// Migration 37: file_story_contributions — per-intervention "construction
|
|
758
|
+
// story" data for the Code/Files explorer. One row per file_provenance row
|
|
759
|
+
// that had a collectable patch: line stats (added/removed), a ~4KB patch
|
|
760
|
+
// excerpt (the full patch stays in file_provenance_diffs), and a nullable
|
|
761
|
+
// plain-language AI `summary` of what that spec contributed to the file
|
|
762
|
+
// (generated on demand, budget-gated — see file-story-manager.ts). Written
|
|
763
|
+
// inside recordProvenanceForJob's transaction so EVERY provenance producer
|
|
764
|
+
// (queue-manager jobs AND the loop-run seam) gets stats for free. Additive.
|
|
765
|
+
(db) => {
|
|
766
|
+
db.exec(`
|
|
767
|
+
CREATE TABLE IF NOT EXISTS file_story_contributions (
|
|
768
|
+
provenance_id INTEGER PRIMARY KEY,
|
|
769
|
+
job_id TEXT,
|
|
770
|
+
file_path TEXT NOT NULL,
|
|
771
|
+
added_lines INTEGER NOT NULL DEFAULT 0,
|
|
772
|
+
removed_lines INTEGER NOT NULL DEFAULT 0,
|
|
773
|
+
patch_excerpt TEXT,
|
|
774
|
+
summary TEXT,
|
|
775
|
+
summary_model TEXT,
|
|
776
|
+
summary_generated_at TEXT
|
|
777
|
+
);
|
|
778
|
+
CREATE INDEX IF NOT EXISTS idx_file_story_contributions_path ON file_story_contributions(file_path);
|
|
779
|
+
`);
|
|
780
|
+
},
|
|
781
|
+
// Migration 38: rail_pr_deliveries.run_ids — JSON string[] of the loop-run
|
|
782
|
+
// ids an isolated rail launch fanned out (order matches ticket order; a
|
|
783
|
+
// scope='all' launch has exactly one). Persisted right after allocation so
|
|
784
|
+
// the PR decision surfaces (agent-chat card + dashboard strip) can render a
|
|
785
|
+
// per-run "View log" chip with live vitals that survives refresh/restart.
|
|
786
|
+
// Additive + idempotent (guarded by PRAGMA table_info, mirroring 18–36).
|
|
787
|
+
(db) => {
|
|
788
|
+
const cols = db.prepare(`PRAGMA table_info(rail_pr_deliveries)`).all().map((r) => r.name);
|
|
789
|
+
if (!cols.includes('run_ids')) {
|
|
790
|
+
db.exec(`ALTER TABLE rail_pr_deliveries ADD COLUMN run_ids TEXT NOT NULL DEFAULT '[]'`);
|
|
791
|
+
}
|
|
792
|
+
},
|
|
793
|
+
// Migration 39: seed the three BASE rails (indices 0-2) into rail_meta.
|
|
794
|
+
// Dynamic rails make rail_meta the EXISTENCE authority (a rail exists iff it
|
|
795
|
+
// has a rail_meta identity row or leftover ticket rows) — seeding once here,
|
|
796
|
+
// instead of re-seeding on every read, lets a user genuinely delete a base
|
|
797
|
+
// rail (the router still guards: never the last one, never a non-empty or
|
|
798
|
+
// active one). INSERT OR IGNORE keeps any existing renamed-rail rows intact.
|
|
799
|
+
(db) => {
|
|
800
|
+
db.exec(`
|
|
801
|
+
INSERT OR IGNORE INTO rail_meta (rail_index, name) VALUES (0, NULL), (1, NULL), (2, NULL);
|
|
802
|
+
`);
|
|
803
|
+
},
|
|
722
804
|
];
|
|
723
805
|
function applyMigrations(db) {
|
|
724
806
|
// Ensure the migrations table exists (migration 1 creates it, but we need
|
|
@@ -783,6 +865,16 @@ function createJob(db, job) {
|
|
|
783
865
|
db.prepare('INSERT OR IGNORE INTO jobs (id, command, started_at, status, priority, depends_on_job_id, pipeline_id, interactive) VALUES (?, ?, ?, ?, ?, ?, ?, ?)').run(job.id, job.command, job.started_at, 'running', job.priority ?? 'normal', job.depends_on_job_id ?? null, job.pipeline_id ?? null, job.interactive ? 1 : 0);
|
|
784
866
|
db.prepare('UPDATE jobs SET status = ?, started_at = ?, interactive = ? WHERE id = ?').run('running', job.started_at, job.interactive ? 1 : 0, job.id);
|
|
785
867
|
}
|
|
868
|
+
/**
|
|
869
|
+
* Flip a job row's `interactive` flag AFTER creation. Used by the loop engine
|
|
870
|
+
* when an ai-step upgrades the run's backing job to a resident interactive
|
|
871
|
+
* session — the row was created at run start (before the step's provider
|
|
872
|
+
* capability/kill-switch gate is consulted), so the flag lands lazily at the
|
|
873
|
+
* first interactive step spawn. Idempotent.
|
|
874
|
+
*/
|
|
875
|
+
function markJobInteractive(db, jobId) {
|
|
876
|
+
db.prepare('UPDATE jobs SET interactive = 1 WHERE id = ?').run(jobId);
|
|
877
|
+
}
|
|
786
878
|
/**
|
|
787
879
|
* Add one completed interactive turn's REAL usage into the job row. Token/cost/
|
|
788
880
|
* turn columns accumulate (COALESCE so the first turn starts from a clean base);
|
|
@@ -1151,11 +1243,13 @@ function getProjectSettings(db) {
|
|
|
1151
1243
|
const modelRow = db.prepare(`SELECT value FROM queue_state WHERE key = 'config.orchestrator_model'`).get();
|
|
1152
1244
|
const prePromptRow = db.prepare(`SELECT value FROM queue_state WHERE key = 'config.pre_prompt'`).get();
|
|
1153
1245
|
const ultraPrePromptRow = db.prepare(`SELECT value FROM queue_state WHERE key = 'config.ultracode_pre_prompt'`).get();
|
|
1246
|
+
const integrationBranchRow = db.prepare(`SELECT value FROM queue_state WHERE key = 'config.integration_branch'`).get();
|
|
1154
1247
|
return {
|
|
1155
1248
|
pipelineTelemetryEnabled: telemetryRow?.value === 'true',
|
|
1156
1249
|
orchestratorModel: modelRow?.value ?? 'sonnet',
|
|
1157
1250
|
prePrompt: prePromptRow?.value ?? '',
|
|
1158
1251
|
ultraPrePrompt: ultraPrePromptRow?.value ?? '',
|
|
1252
|
+
integrationBranch: integrationBranchRow?.value ?? '',
|
|
1159
1253
|
};
|
|
1160
1254
|
}
|
|
1161
1255
|
/** Resolve the effective Ultracode pre-prompt: the per-project override when
|
|
@@ -1187,6 +1281,14 @@ function updateProjectSettings(db, patch) {
|
|
|
1187
1281
|
db.prepare(`INSERT OR REPLACE INTO queue_state (key, value) VALUES ('config.ultracode_pre_prompt', ?)`).run(patch.ultraPrePrompt);
|
|
1188
1282
|
}
|
|
1189
1283
|
}
|
|
1284
|
+
if (patch.integrationBranch !== undefined) {
|
|
1285
|
+
if (patch.integrationBranch.trim() === '') {
|
|
1286
|
+
db.prepare(`DELETE FROM queue_state WHERE key = 'config.integration_branch'`).run();
|
|
1287
|
+
}
|
|
1288
|
+
else {
|
|
1289
|
+
db.prepare(`INSERT OR REPLACE INTO queue_state (key, value) VALUES ('config.integration_branch', ?)`).run(patch.integrationBranch.trim());
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1190
1292
|
}
|
|
1191
1293
|
// ─── Explore Spec acceleration ────────────────────────────────────────────────
|
|
1192
1294
|
/**
|
|
@@ -3,11 +3,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.GIT_EXEC_ENV = void 0;
|
|
6
|
+
exports.STORY_EXCERPT_MAX_BYTES = exports.GIT_EXEC_ENV = void 0;
|
|
7
7
|
exports.resolveHeadSha = resolveHeadSha;
|
|
8
8
|
exports.listUntracked = listUntracked;
|
|
9
9
|
exports.snapshotWorkingTree = snapshotWorkingTree;
|
|
10
10
|
exports.diffAgainstSnapshot = diffAgainstSnapshot;
|
|
11
|
+
exports.computeDiffStats = computeDiffStats;
|
|
12
|
+
exports.excerptPatch = excerptPatch;
|
|
11
13
|
exports.collectDiffPatches = collectDiffPatches;
|
|
12
14
|
exports.recordProvenanceForJob = recordProvenanceForJob;
|
|
13
15
|
exports.getProvenanceDiff = getProvenanceDiff;
|
|
@@ -204,6 +206,37 @@ function diffAgainstSnapshot(cwd, snapshotRef, untrackedBefore, baseSha) {
|
|
|
204
206
|
}
|
|
205
207
|
return entries;
|
|
206
208
|
}
|
|
209
|
+
/** Upper bound on the patch excerpt stored per intervention in
|
|
210
|
+
* file_story_contributions (the full patch stays in file_provenance_diffs). */
|
|
211
|
+
exports.STORY_EXCERPT_MAX_BYTES = 4096;
|
|
212
|
+
/** Count added/removed lines in a unified diff. Skips the `+++`/`---` file
|
|
213
|
+
* headers and the `\ No newline` marker so stats reflect content lines only. */
|
|
214
|
+
function computeDiffStats(patch) {
|
|
215
|
+
let added = 0;
|
|
216
|
+
let removed = 0;
|
|
217
|
+
for (const line of patch.split('\n')) {
|
|
218
|
+
if (line.startsWith('+++') || line.startsWith('---'))
|
|
219
|
+
continue;
|
|
220
|
+
if (line.startsWith('+'))
|
|
221
|
+
added += 1;
|
|
222
|
+
else if (line.startsWith('-'))
|
|
223
|
+
removed += 1;
|
|
224
|
+
}
|
|
225
|
+
return { added, removed };
|
|
226
|
+
}
|
|
227
|
+
/** Cap a patch to STORY_EXCERPT_MAX_BYTES on a line boundary. */
|
|
228
|
+
function excerptPatch(patch, capBytes = exports.STORY_EXCERPT_MAX_BYTES) {
|
|
229
|
+
if (Buffer.byteLength(patch, 'utf8') <= capBytes)
|
|
230
|
+
return patch;
|
|
231
|
+
let out = '';
|
|
232
|
+
for (const line of patch.split('\n')) {
|
|
233
|
+
const candidate = out.length > 0 ? `${out}\n${line}` : line;
|
|
234
|
+
if (Buffer.byteLength(candidate, 'utf8') > capBytes)
|
|
235
|
+
break;
|
|
236
|
+
out = candidate;
|
|
237
|
+
}
|
|
238
|
+
return `${out}\n[specrails-desktop] excerpt truncated\n`;
|
|
239
|
+
}
|
|
207
240
|
function truncatePatch(patch) {
|
|
208
241
|
const bytes = Buffer.byteLength(patch, 'utf8');
|
|
209
242
|
if (bytes <= MAX_PATCH_BYTES)
|
|
@@ -325,6 +358,22 @@ function recordProvenanceForJob(db, projectId, jobId, ticketId, diff, atMs = Dat
|
|
|
325
358
|
catch {
|
|
326
359
|
insertPatch = null;
|
|
327
360
|
}
|
|
361
|
+
// Construction-story stats (migration 37): one row per provenance row that had
|
|
362
|
+
// a collectable patch — added/removed line counts + a ~4KB excerpt. Written in
|
|
363
|
+
// the SAME transaction so every provenance producer (queue-manager jobs and
|
|
364
|
+
// the loop-run seam in file-story.ts) records stats with no extra call. The
|
|
365
|
+
// prepare is guarded like insertPatch so a pre-migration DB degrades cleanly.
|
|
366
|
+
let insertContribution = null;
|
|
367
|
+
try {
|
|
368
|
+
insertContribution = db.prepare(`
|
|
369
|
+
INSERT OR REPLACE INTO file_story_contributions
|
|
370
|
+
(provenance_id, job_id, file_path, added_lines, removed_lines, patch_excerpt)
|
|
371
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
372
|
+
`);
|
|
373
|
+
}
|
|
374
|
+
catch {
|
|
375
|
+
insertContribution = null;
|
|
376
|
+
}
|
|
328
377
|
const inserted = [];
|
|
329
378
|
const tx = db.transaction((rows) => {
|
|
330
379
|
for (const r of rows) {
|
|
@@ -341,6 +390,10 @@ function recordProvenanceForJob(db, projectId, jobId, ticketId, diff, atMs = Dat
|
|
|
341
390
|
if (insertPatch && storedPatch) {
|
|
342
391
|
insertPatch.run(Number(result.lastInsertRowid), storedPatch.patch, storedPatch.truncated ? 1 : 0);
|
|
343
392
|
}
|
|
393
|
+
if (insertContribution && storedPatch) {
|
|
394
|
+
const stats = computeDiffStats(storedPatch.patch);
|
|
395
|
+
insertContribution.run(Number(result.lastInsertRowid), jobId, r.file_path, stats.added, stats.removed, excerptPatch(storedPatch.patch));
|
|
396
|
+
}
|
|
344
397
|
}
|
|
345
398
|
});
|
|
346
399
|
tx(pending);
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FileStoryManager = exports.STORY_SUMMARY_MAX_LENGTH = void 0;
|
|
4
|
+
exports.buildStorySystemPrompt = buildStorySystemPrompt;
|
|
5
|
+
/**
|
|
6
|
+
* FileStoryManager — on-demand, budget-gated generation of the plain-language
|
|
7
|
+
* "what this spec contributed to this file" paragraph shown on each card of
|
|
8
|
+
* the Code/Files construction story.
|
|
9
|
+
*
|
|
10
|
+
* Mirrors FileSummaryManager's cost discipline: the SAME monthly budget
|
|
11
|
+
* setting (`summary_monthly_budget_usd`) and the SAME ai_invocations surface
|
|
12
|
+
* (`'file-summary'`) — one budget covers the whole Code-section AI spend and
|
|
13
|
+
* analytics need no new surface. Generation is user-initiated (per-card
|
|
14
|
+
* "Explain" button), in-flight-deduped per provenanceId, and persists to
|
|
15
|
+
* `file_story_contributions.summary` (see file-story.ts / migration 37).
|
|
16
|
+
*/
|
|
17
|
+
const crypto_1 = require("crypto");
|
|
18
|
+
const ai_invocations_1 = require("./ai-invocations");
|
|
19
|
+
const file_story_1 = require("./file-story");
|
|
20
|
+
const STORY_PROMPT_EN = 'You are telling a non-developer how one part of an app was built. Below is one change made to a file: ' +
|
|
21
|
+
'the goal it implemented (a spec title) and the code changes (a diff). Write 1 to 3 sentences in plain ' +
|
|
22
|
+
'language describing what this specific change contributed to this file. No code, no jargon, no lists. ' +
|
|
23
|
+
'Output only the explanation, nothing else.';
|
|
24
|
+
const STORY_PROMPT_ES = 'Estás contando a una persona no desarrolladora cómo se construyó una parte de una app. Abajo hay un cambio ' +
|
|
25
|
+
'hecho a un archivo: el objetivo que implementó (el título de una spec) y los cambios de código (un diff). ' +
|
|
26
|
+
'Escribe entre 1 y 3 frases en lenguaje llano describiendo qué aportó este cambio concreto a este archivo. ' +
|
|
27
|
+
'Sin código, sin jerga, sin listas. Devuelve solo la explicación, nada más.';
|
|
28
|
+
function buildStorySystemPrompt(language) {
|
|
29
|
+
return language === 'es' ? STORY_PROMPT_ES : STORY_PROMPT_EN;
|
|
30
|
+
}
|
|
31
|
+
/** Bound on the generated paragraph (defensive, mirrors SUMMARY_MAX_LENGTH scale). */
|
|
32
|
+
exports.STORY_SUMMARY_MAX_LENGTH = 2000;
|
|
33
|
+
/** Bound on the diff excerpt fed to the model. */
|
|
34
|
+
const PROMPT_PATCH_MAX_CHARS = 12000;
|
|
35
|
+
class FileStoryManager {
|
|
36
|
+
deps;
|
|
37
|
+
/** In-flight dedupe: a second Explain for the same intervention rides the first. */
|
|
38
|
+
inFlight = new Map();
|
|
39
|
+
constructor(deps) {
|
|
40
|
+
this.deps = deps;
|
|
41
|
+
}
|
|
42
|
+
explain(req) {
|
|
43
|
+
const existing = this.inFlight.get(req.provenanceId);
|
|
44
|
+
if (existing)
|
|
45
|
+
return existing;
|
|
46
|
+
// Synchronous gates run BEFORE registering in-flight so a skip result is
|
|
47
|
+
// never cached in the dedupe map (a budget skip followed immediately by an
|
|
48
|
+
// override retry must not ride the stale skipped promise).
|
|
49
|
+
//
|
|
50
|
+
// Resolve the intervention: the provenance row must exist AND belong to
|
|
51
|
+
// the requested path (the router already guarded the path; this pins the id).
|
|
52
|
+
const prov = this._loadProvenance(req.provenanceId);
|
|
53
|
+
if (!prov || prov.file_path !== req.relPath)
|
|
54
|
+
return Promise.resolve('skipped:not-found');
|
|
55
|
+
// Budget gate — same monthly cap as file summaries; explicit override only.
|
|
56
|
+
if (!req.overrideBudget) {
|
|
57
|
+
const spend = this.deps.monthToDateSpend(req.projectId);
|
|
58
|
+
if (spend >= this.deps.monthlyBudgetUsd())
|
|
59
|
+
return Promise.resolve('skipped:budget');
|
|
60
|
+
}
|
|
61
|
+
const p = this._explainInner(req, prov);
|
|
62
|
+
this.inFlight.set(req.provenanceId, p);
|
|
63
|
+
void p.catch(() => undefined).finally(() => {
|
|
64
|
+
if (this.inFlight.get(req.provenanceId) === p)
|
|
65
|
+
this.inFlight.delete(req.provenanceId);
|
|
66
|
+
});
|
|
67
|
+
return p;
|
|
68
|
+
}
|
|
69
|
+
async _explainInner(req, prov) {
|
|
70
|
+
const startedIso = new Date((this.deps.now ?? Date.now)()).toISOString();
|
|
71
|
+
const lang = this.deps.language?.() ?? 'en';
|
|
72
|
+
// Compose the change description: spec title (live lookup, tolerant) +
|
|
73
|
+
// kind + the stored patch (full patch preferred, excerpt fallback,
|
|
74
|
+
// honest note when neither survived).
|
|
75
|
+
let ticketTitle = null;
|
|
76
|
+
if (prov.ticket_id != null) {
|
|
77
|
+
try {
|
|
78
|
+
ticketTitle = this.deps.getTicketSpec?.(prov.ticket_id)?.title ?? null;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
ticketTitle = null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const patch = this._loadPatch(req.provenanceId);
|
|
85
|
+
const parts = [];
|
|
86
|
+
parts.push(`Spec: ${ticketTitle ?? (prov.ticket_id != null ? `#${prov.ticket_id}` : 'unknown')}`);
|
|
87
|
+
parts.push(`Change kind: ${prov.kind}`);
|
|
88
|
+
parts.push(patch ? `Diff:\n${patch.slice(0, PROMPT_PATCH_MAX_CHARS)}` : 'Diff: (not stored for this change)');
|
|
89
|
+
try {
|
|
90
|
+
const out = await this.deps.generate({
|
|
91
|
+
relPath: req.relPath,
|
|
92
|
+
contents: parts.join('\n\n'),
|
|
93
|
+
truncated: (patch?.length ?? 0) > PROMPT_PATCH_MAX_CHARS,
|
|
94
|
+
language: lang,
|
|
95
|
+
});
|
|
96
|
+
const bounded = out.summary.length > exports.STORY_SUMMARY_MAX_LENGTH
|
|
97
|
+
? out.summary.slice(0, exports.STORY_SUMMARY_MAX_LENGTH)
|
|
98
|
+
: out.summary;
|
|
99
|
+
const persisted = (0, file_story_1.setContributionSummary)(this.deps.db, req.provenanceId, bounded, out.model, new Date((this.deps.now ?? Date.now)()).toISOString());
|
|
100
|
+
this._recordInvocation(req, startedIso, 'success', out);
|
|
101
|
+
this.deps.broadcast(this._storyMsg(req, persisted, persisted ? undefined : 'persist-failed'));
|
|
102
|
+
this.deps.broadcast({ type: 'spending.invalidated', projectId: req.projectId });
|
|
103
|
+
return persisted ? 'generated' : 'failed';
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
107
|
+
// Carry any partial usage the generator captured (mirrors FileSummaryManager).
|
|
108
|
+
const partial = err.partial;
|
|
109
|
+
this._recordInvocation(req, startedIso, 'failed', partial);
|
|
110
|
+
this.deps.broadcast(this._storyMsg(req, false, reason));
|
|
111
|
+
return 'failed';
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
_storyMsg(req, ok, reason) {
|
|
115
|
+
return {
|
|
116
|
+
type: 'file.story_updated',
|
|
117
|
+
projectId: req.projectId,
|
|
118
|
+
path: req.relPath,
|
|
119
|
+
provenanceId: req.provenanceId,
|
|
120
|
+
ok,
|
|
121
|
+
...(reason ? { reason } : {}),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
_loadProvenance(provenanceId) {
|
|
125
|
+
try {
|
|
126
|
+
const row = this.deps.db.prepare(`SELECT id, file_path, ticket_id, job_id, kind FROM file_provenance WHERE id = ?`).get(provenanceId);
|
|
127
|
+
return row ?? null;
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
_loadPatch(provenanceId) {
|
|
134
|
+
try {
|
|
135
|
+
const row = this.deps.db.prepare(`SELECT patch FROM file_provenance_diffs WHERE provenance_id = ?`).get(provenanceId);
|
|
136
|
+
if (row?.patch)
|
|
137
|
+
return row.patch;
|
|
138
|
+
}
|
|
139
|
+
catch { /* fall through to excerpt */ }
|
|
140
|
+
return (0, file_story_1.getContribution)(this.deps.db, provenanceId)?.patch_excerpt ?? null;
|
|
141
|
+
}
|
|
142
|
+
_recordInvocation(req, startedIso, status, out) {
|
|
143
|
+
try {
|
|
144
|
+
(0, ai_invocations_1.recordInvocation)(this.deps.db, {
|
|
145
|
+
id: (0, crypto_1.randomUUID)(),
|
|
146
|
+
project_id: req.projectId,
|
|
147
|
+
provider: out?.provider ?? this.deps.providerId?.() ?? 'claude',
|
|
148
|
+
surface: 'file-summary',
|
|
149
|
+
surface_ref_id: null,
|
|
150
|
+
ticket_id: this._loadProvenance(req.provenanceId)?.ticket_id ?? null,
|
|
151
|
+
status,
|
|
152
|
+
started_at: startedIso,
|
|
153
|
+
finished_at: new Date((this.deps.now ?? Date.now)()).toISOString(),
|
|
154
|
+
model: out?.model,
|
|
155
|
+
total_cost_usd: out?.costUsd ?? 0,
|
|
156
|
+
tokens_in: out?.tokensIn ?? 0,
|
|
157
|
+
tokens_out: out?.tokensOut ?? 0,
|
|
158
|
+
tokens_cache_read: out?.tokensCacheRead,
|
|
159
|
+
tokens_cache_create: out?.tokensCacheCreate,
|
|
160
|
+
duration_ms: out?.durationMs ?? 0,
|
|
161
|
+
num_turns: 1,
|
|
162
|
+
total_cost_usd_estimated: !!out?.costEstimated,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
console.error('[file-story] recordInvocation failed:', err);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
exports.FileStoryManager = FileStoryManager;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.recordLoopRunProvenance = recordLoopRunProvenance;
|
|
4
|
+
exports.getContribution = getContribution;
|
|
5
|
+
exports.setContributionSummary = setContributionSummary;
|
|
6
|
+
exports.getFileStory = getFileStory;
|
|
7
|
+
const feature_flags_1 = require("./feature-flags");
|
|
8
|
+
const file_provenance_1 = require("./file-provenance");
|
|
9
|
+
/** Warn threshold mirroring queue-manager's `provenance.large_job`. */
|
|
10
|
+
const LARGE_RUN_WARN_FILES = 50;
|
|
11
|
+
/**
|
|
12
|
+
* Record Code-Explorer provenance for a settled loop run. Single chokepoint:
|
|
13
|
+
* gated by the code-explorer flag, never throws (a provenance failure must
|
|
14
|
+
* never break a rail settle). Returns the number of provenance rows written.
|
|
15
|
+
*/
|
|
16
|
+
function recordLoopRunProvenance(input, io = {}) {
|
|
17
|
+
if (!(0, feature_flags_1.isCodeExplorerEnabled)())
|
|
18
|
+
return 0;
|
|
19
|
+
if (!input.snapshot)
|
|
20
|
+
return 0;
|
|
21
|
+
const diffFn = io.diff ?? file_provenance_1.diffAgainstSnapshot;
|
|
22
|
+
const patchesFn = io.patches ?? file_provenance_1.collectDiffPatches;
|
|
23
|
+
try {
|
|
24
|
+
const ref = input.snapshot.ref;
|
|
25
|
+
const diff = diffFn(input.repoDir, ref, input.snapshot.untracked, input.snapshot.headSha);
|
|
26
|
+
if (diff.length === 0)
|
|
27
|
+
return 0;
|
|
28
|
+
const patches = patchesFn(input.repoDir, ref, diff, input.snapshot.headSha);
|
|
29
|
+
if (diff.length > LARGE_RUN_WARN_FILES) {
|
|
30
|
+
console.warn(`[provenance.large_job] job=${input.runId} files=${diff.length}`);
|
|
31
|
+
}
|
|
32
|
+
const rows = (0, file_provenance_1.recordProvenanceForJob)(input.db, input.projectId, input.runId, input.ticketId, diff, Date.now(), patches);
|
|
33
|
+
for (const row of rows) {
|
|
34
|
+
try {
|
|
35
|
+
(0, file_provenance_1.broadcastProvenanceUpdated)(input.broadcast, input.projectId, row);
|
|
36
|
+
}
|
|
37
|
+
catch { /* non-fatal */ }
|
|
38
|
+
}
|
|
39
|
+
return rows.length;
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
console.warn(`[file-story] loop-run provenance recording failed: ${err.message}`);
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** Read one contribution row by provenance id (null when absent / pre-37 DB). */
|
|
47
|
+
function getContribution(db, provenanceId) {
|
|
48
|
+
try {
|
|
49
|
+
const row = db.prepare(`SELECT provenance_id, job_id, file_path, added_lines, removed_lines,
|
|
50
|
+
patch_excerpt, summary, summary_model, summary_generated_at
|
|
51
|
+
FROM file_story_contributions WHERE provenance_id = ?`).get(provenanceId);
|
|
52
|
+
return row ?? null;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** Persist the AI-generated contribution paragraph for one intervention.
|
|
59
|
+
* Inserts the row when the intervention pre-dates migration 37 / had no patch. */
|
|
60
|
+
function setContributionSummary(db, provenanceId, summary, model, generatedAtIso = new Date().toISOString()) {
|
|
61
|
+
try {
|
|
62
|
+
const updated = db.prepare(`UPDATE file_story_contributions
|
|
63
|
+
SET summary = ?, summary_model = ?, summary_generated_at = ?
|
|
64
|
+
WHERE provenance_id = ?`).run(summary, model, generatedAtIso, provenanceId);
|
|
65
|
+
if (updated.changes > 0)
|
|
66
|
+
return true;
|
|
67
|
+
// No stats row yet (historical touch without a stored patch) — create one
|
|
68
|
+
// carrying only the summary, keyed off the provenance row's identity.
|
|
69
|
+
const prov = db.prepare(`SELECT id, file_path, job_id FROM file_provenance WHERE id = ?`).get(provenanceId);
|
|
70
|
+
if (!prov)
|
|
71
|
+
return false;
|
|
72
|
+
db.prepare(`INSERT OR REPLACE INTO file_story_contributions
|
|
73
|
+
(provenance_id, job_id, file_path, added_lines, removed_lines, patch_excerpt, summary, summary_model, summary_generated_at)
|
|
74
|
+
VALUES (?, ?, ?, 0, 0, NULL, ?, ?, ?)`).run(provenanceId, prov.job_id, prov.file_path, summary, model, generatedAtIso);
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Assemble the chronological construction story for one file: every
|
|
83
|
+
* intervention (oldest first — a construction story reads forward in time),
|
|
84
|
+
* each carrying diff stats + the AI contribution when available, enriched
|
|
85
|
+
* with the spec's live title/status. Ticket lookups are failure-tolerant.
|
|
86
|
+
*/
|
|
87
|
+
function getFileStory(db, filePath, getTicketSpec) {
|
|
88
|
+
let rows;
|
|
89
|
+
try {
|
|
90
|
+
rows = db.prepare(`SELECT p.id, p.file_path, p.ticket_id, p.job_id, p.kind, p.at,
|
|
91
|
+
c.added_lines, c.removed_lines, c.patch_excerpt,
|
|
92
|
+
c.summary, c.summary_model, c.summary_generated_at,
|
|
93
|
+
(SELECT COUNT(*) FROM file_provenance_diffs d WHERE d.provenance_id = p.id) AS patch_count
|
|
94
|
+
FROM file_provenance p
|
|
95
|
+
LEFT JOIN file_story_contributions c ON c.provenance_id = p.id
|
|
96
|
+
WHERE p.file_path = ?
|
|
97
|
+
ORDER BY p.at ASC, p.id ASC`).all(filePath);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// Pre-migration-37 DB — degrade to the bare provenance rows (honest
|
|
101
|
+
// fallback story: kind + date + spec only).
|
|
102
|
+
rows = db.prepare(`SELECT id, ticket_id, job_id, kind, at FROM file_provenance WHERE file_path = ? ORDER BY at ASC, id ASC`).all(filePath).map((r) => ({
|
|
103
|
+
...r,
|
|
104
|
+
added_lines: null,
|
|
105
|
+
removed_lines: null,
|
|
106
|
+
patch_excerpt: null,
|
|
107
|
+
summary: null,
|
|
108
|
+
summary_model: null,
|
|
109
|
+
summary_generated_at: null,
|
|
110
|
+
patch_count: 0,
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
const ticketCache = new Map();
|
|
114
|
+
const resolveTicket = (ticketId) => {
|
|
115
|
+
if (ticketId == null)
|
|
116
|
+
return null;
|
|
117
|
+
if (ticketCache.has(ticketId))
|
|
118
|
+
return ticketCache.get(ticketId);
|
|
119
|
+
let resolved = null;
|
|
120
|
+
try {
|
|
121
|
+
const spec = getTicketSpec?.(ticketId);
|
|
122
|
+
if (spec) {
|
|
123
|
+
resolved = {
|
|
124
|
+
id: ticketId,
|
|
125
|
+
title: typeof spec.title === 'string' ? spec.title : null,
|
|
126
|
+
status: typeof spec.status === 'string' ? spec.status : null,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch { /* deleted ticket / unreadable store — degrade to null */ }
|
|
131
|
+
ticketCache.set(ticketId, resolved);
|
|
132
|
+
return resolved;
|
|
133
|
+
};
|
|
134
|
+
return rows.map((r) => ({
|
|
135
|
+
provenanceId: r.id,
|
|
136
|
+
jobId: r.job_id,
|
|
137
|
+
ticketId: r.ticket_id,
|
|
138
|
+
kind: r.kind,
|
|
139
|
+
at: r.at,
|
|
140
|
+
addedLines: r.added_lines,
|
|
141
|
+
removedLines: r.removed_lines,
|
|
142
|
+
hasPatch: r.patch_count > 0,
|
|
143
|
+
summary: r.summary,
|
|
144
|
+
summaryModel: r.summary_model,
|
|
145
|
+
summaryGeneratedAt: r.summary_generated_at,
|
|
146
|
+
ticket: resolveTicket(r.ticket_id),
|
|
147
|
+
}));
|
|
148
|
+
}
|
|
@@ -20,12 +20,12 @@ function buildSystemPrompt(language) {
|
|
|
20
20
|
/** Compose the single user-message body that goes to the model. The provider
|
|
21
21
|
* adapter decides whether the system prompt rides along via a flag or gets
|
|
22
22
|
* folded into this string (see `adapter.capabilities.systemPromptArg`). */
|
|
23
|
-
function buildUserPrompt(input, adapter) {
|
|
23
|
+
function buildUserPrompt(input, adapter, systemPromptFor) {
|
|
24
24
|
const body = `${input.relPath}\n${input.contents}`;
|
|
25
25
|
if (adapter.capabilities.systemPromptArg)
|
|
26
26
|
return body;
|
|
27
27
|
// Provider does not accept a system-prompt flag; fold the instruction inline.
|
|
28
|
-
return `${
|
|
28
|
+
return `${systemPromptFor(input.language)}\n\n${body}`;
|
|
29
29
|
}
|
|
30
30
|
/** Cheapest model per provider for summary generation. Codex MUST run
|
|
31
31
|
* `gpt-5.4-mini` (product decision: file summaries are non-critical and the
|
|
@@ -49,13 +49,14 @@ function createFileSummaryGenerator(opts) {
|
|
|
49
49
|
const model = opts.model ?? defaultModelFor(adapter);
|
|
50
50
|
const timeoutMs = opts.timeoutMs ?? GENERATE_TIMEOUT_MS;
|
|
51
51
|
const spawn = opts.spawn ?? cli_prompt_1.spawnAiCli;
|
|
52
|
+
const systemPromptFor = opts.systemPrompt ?? buildSystemPrompt;
|
|
52
53
|
return async function generate(input, signal) {
|
|
53
54
|
const startedAt = Date.now();
|
|
54
55
|
if (signal?.aborted)
|
|
55
56
|
throw new Error('file-summary generator aborted before start');
|
|
56
57
|
const args = adapter.buildArgs('spec-gen', {
|
|
57
|
-
prompt: buildUserPrompt(input, adapter),
|
|
58
|
-
systemPrompt: adapter.capabilities.systemPromptArg ?
|
|
58
|
+
prompt: buildUserPrompt(input, adapter, systemPromptFor),
|
|
59
|
+
systemPrompt: adapter.capabilities.systemPromptArg ? systemPromptFor(input.language) : undefined,
|
|
59
60
|
model,
|
|
60
61
|
maxTurns: 1,
|
|
61
62
|
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GitGuardrailError = void 0;
|
|
4
|
+
exports.isForcePush = isForcePush;
|
|
5
|
+
exports.pushesToBranch = pushesToBranch;
|
|
6
|
+
exports.assertGitAllowed = assertGitAllowed;
|
|
7
|
+
/**
|
|
8
|
+
* Git safety guardrails for the app-owned push/PR path (safe-pr-workflow).
|
|
9
|
+
*
|
|
10
|
+
* specrails must NEVER force-push and NEVER push directly to a project's
|
|
11
|
+
* integration branch — work always lands on a ticket/batch branch and reaches the
|
|
12
|
+
* integration branch only through a human-merged PR. This is a pure policy check
|
|
13
|
+
* wired into the sanctioned git/PR path (`pr-publisher`) as defense-in-depth: even
|
|
14
|
+
* a future bug that constructed a bad push is refused loudly.
|
|
15
|
+
*
|
|
16
|
+
* NOTE: this guards the APP's own git invocations. Blocking git issued by the AI
|
|
17
|
+
* agent *inside* a loop turn (e.g. a rogue `git push --force`) requires a
|
|
18
|
+
* per-worktree pre-push hook and is a documented follow-up.
|
|
19
|
+
*/
|
|
20
|
+
class GitGuardrailError extends Error {
|
|
21
|
+
constructor(message) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = 'GitGuardrailError';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.GitGuardrailError = GitGuardrailError;
|
|
27
|
+
const FORCE_FLAGS = new Set(['--force', '-f', '--force-with-lease']);
|
|
28
|
+
/** True when a `git push` arg list carries a force flag (incl. `--force-with-lease=…`). */
|
|
29
|
+
function isForcePush(args) {
|
|
30
|
+
return args[0] === 'push' && args.some((a) => FORCE_FLAGS.has(a) || a.startsWith('--force-with-lease='));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Does a `git push` arg list target the protected branch? Catches
|
|
34
|
+
* push <remote> <protected> (implicit same-name)
|
|
35
|
+
* push <remote> HEAD:<protected> (explicit dst refspec)
|
|
36
|
+
* push <remote> <src>:<protected>
|
|
37
|
+
* We only ever push the ticket/batch branch, so any of these is a bug.
|
|
38
|
+
*/
|
|
39
|
+
function pushesToBranch(args, branch) {
|
|
40
|
+
if (args[0] !== 'push' || !branch)
|
|
41
|
+
return false;
|
|
42
|
+
return args.slice(1).some((a) => {
|
|
43
|
+
if (a.startsWith('-'))
|
|
44
|
+
return false; // a flag, not a refspec
|
|
45
|
+
const dst = a.includes(':') ? a.slice(a.indexOf(':') + 1) : a;
|
|
46
|
+
return dst === branch || dst === `refs/heads/${branch}`;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Throw if a git command violates the guardrails. Only `push` is policed today;
|
|
51
|
+
* every other command is allowed through unchanged.
|
|
52
|
+
*/
|
|
53
|
+
function assertGitAllowed(cmd, args, opts = {}) {
|
|
54
|
+
if (cmd !== 'git' || args[0] !== 'push')
|
|
55
|
+
return;
|
|
56
|
+
if (isForcePush(args)) {
|
|
57
|
+
throw new GitGuardrailError('force-push is not allowed on the safe-PR path');
|
|
58
|
+
}
|
|
59
|
+
if (opts.protectedBranch && pushesToBranch(args, opts.protectedBranch)) {
|
|
60
|
+
throw new GitGuardrailError(`direct push to the integration branch "${opts.protectedBranch}" is not allowed`);
|
|
61
|
+
}
|
|
62
|
+
}
|
package/server/dist/index.js
CHANGED
|
@@ -26,6 +26,7 @@ const mobile_1 = require("./mobile");
|
|
|
26
26
|
const mcp_1 = require("./mcp");
|
|
27
27
|
const agent_chat_manager_1 = require("./agent-chat-manager");
|
|
28
28
|
const agent_chat_router_1 = require("./agent-chat-router");
|
|
29
|
+
const agent_chat_registry_1 = require("./agent-chat-registry");
|
|
29
30
|
const browser_playwright_1 = require("./browser-playwright");
|
|
30
31
|
const telemetry_receiver_1 = require("./telemetry-receiver");
|
|
31
32
|
const telemetry_compactor_1 = require("./telemetry-compactor");
|
|
@@ -542,6 +543,10 @@ function applyPtyWsRateLimiting(ws) {
|
|
|
542
543
|
// ─── App-global agent chat (drives the app via its own MCP) ────────────────
|
|
543
544
|
const agentChatManager = new agent_chat_manager_1.AgentChatManager(broadcast, registry.desktopDb, port);
|
|
544
545
|
_agentChatManager = agentChatManager;
|
|
546
|
+
// Publish the instance to the process-wide registry so the rails layer can
|
|
547
|
+
// post PR-decision cards (safe-pr-review-flow). Left null when agent chat is
|
|
548
|
+
// disabled — the rails callers are null-safe and simply skip the card.
|
|
549
|
+
(0, agent_chat_registry_1.setAgentChatManager)((0, agent_chat_router_1.isAgentChatEnabled)() ? agentChatManager : null);
|
|
545
550
|
app.use('/api/agent', (0, agent_chat_router_1.createAgentChatRouter)({ manager: agentChatManager, desktopDb: registry.desktopDb }));
|
|
546
551
|
// App-level routes. CRITICAL mount order: the desktop router is mounted at
|
|
547
552
|
// '/api' BEFORE the project router below so its exact routes (e.g.
|