specrails-desktop 2.30.2 → 2.31.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 +28 -24
- package/client/dist/assets/{ActivityFeedPage-9DZOvIcY.js → ActivityFeedPage-CAhFRUO4.js} +1 -1
- package/client/dist/assets/{AgentBrowserCapture-DqyHbzk7.js → AgentBrowserCapture-Ct4G5lsE.js} +1 -1
- package/client/dist/assets/AgentModeCodePane-DQt9WIvu.js +2 -0
- package/client/dist/assets/{AgentModeJobsPane-CTIHMUKN.js → AgentModeJobsPane-podaJVl9.js} +1 -1
- package/client/dist/assets/AgentsPage-DTZdbW80.js +87 -0
- package/client/dist/assets/AnalyticsPage-BskgGPm0.js +1 -0
- package/client/dist/assets/CodePage-CvtYo1DU.js +2 -0
- package/client/dist/assets/{DesktopAnalyticsPage-CkXUFj3F.js → DesktopAnalyticsPage-Dnf99E8e.js} +1 -1
- package/client/dist/assets/{DocsDialog-PhdCJNVj.js → DocsDialog-DHi36rZ4.js} +1 -1
- package/client/dist/assets/{DocsPage-BY-wDthx.js → DocsPage-DIdVrQz1.js} +1 -1
- package/client/dist/assets/{InteractiveJobComposer-C9I0A4KR.js → InteractiveJobComposer-BHeB2inv.js} +1 -1
- package/client/dist/assets/{JobDetailModal-I_RoQJV4.js → JobDetailModal-CF1SKUHH.js} +1 -1
- package/client/dist/assets/JobDetailPage-De3rY18h.js +1 -0
- package/client/dist/assets/{JobsPage-DcllM4Ip.js → JobsPage-CfAqqJTx.js} +1 -1
- package/client/dist/assets/{LoopBuilderPage-DGm_iuff.js → LoopBuilderPage-DSBMuTb3.js} +2 -2
- package/client/dist/assets/{LoopPreviewModal-BC-TeFdD.js → LoopPreviewModal-B-c37kA0.js} +1 -1
- package/client/dist/assets/LoopsPage-DjnNXdmm.js +1 -0
- package/client/dist/assets/{MinimizedChatsContext-Cs34FPTz.js → MinimizedChatsContext-DIsnQMVz.js} +1 -1
- package/client/dist/assets/PluginsPage-DA5pQ_6u.js +2 -0
- package/client/dist/assets/{ProjectSettingsDialog-nEs-ENrE.js → ProjectSettingsDialog-DA23PSi6.js} +1 -1
- package/client/dist/assets/{TemplatePreviewModal-D4qW-J9B.js → TemplatePreviewModal-Cp7IQ-g2.js} +1 -1
- package/client/dist/assets/TicketDetailModal-BPD2i_0R.js +14 -0
- package/client/dist/assets/{Trans-CPISVji8.js → Trans-cWtExGkC.js} +1 -1
- package/client/dist/assets/addspec-4WmLJmBG.js +1 -0
- package/client/dist/assets/addspec-BRlk8jON.js +1 -0
- package/client/dist/assets/addspec-C7XRejU4.js +1 -0
- package/client/dist/assets/addspec-CHW9xf_X.js +1 -0
- package/client/dist/assets/addspec-DTmRrWrF.js +1 -0
- package/client/dist/assets/addspec-DhmnXER8.js +1 -0
- package/client/dist/assets/addspec-Di41DpYV.js +1 -0
- package/client/dist/assets/addspec-x3mizDxc.js +1 -0
- package/client/dist/assets/agent-BKsuIgIT.js +1 -0
- package/client/dist/assets/agent-Bs9NilfI.js +1 -0
- package/client/dist/assets/agent-C23h684q.js +1 -0
- package/client/dist/assets/agent-CqEjy3Z2.js +1 -0
- package/client/dist/assets/agent-D5DZTks1.js +1 -0
- package/client/dist/assets/agent-DE8hUYPl.js +1 -0
- package/client/dist/assets/agent-DsTuJGSc.js +1 -0
- package/client/dist/assets/agent-DwZM05-x.js +1 -0
- package/client/dist/assets/agents-45GbINfh.js +1 -0
- package/client/dist/assets/agents-BHp0_FQt.js +1 -0
- package/client/dist/assets/agents-Bvyi3y6R.js +1 -0
- package/client/dist/assets/agents-DMKFStHL.js +1 -0
- package/client/dist/assets/agents-DaYcxAr1.js +1 -0
- package/client/dist/assets/agents-IUOgqT5t.js +1 -0
- package/client/dist/assets/agents-ms7TwG16.js +1 -0
- package/client/dist/assets/agents-rzPnqoBR.js +1 -0
- package/client/dist/assets/agentstudio-8TQqBenW.js +1 -0
- package/client/dist/assets/agentstudio-B8Z_mmEX.js +1 -0
- package/client/dist/assets/agentstudio-BZR9YmLs.js +1 -0
- package/client/dist/assets/agentstudio-Bge9pAWb.js +1 -0
- package/client/dist/assets/agentstudio-Bz169Vzt.js +1 -0
- package/client/dist/assets/agentstudio-D6L2jpNi.js +1 -0
- package/client/dist/assets/agentstudio-K2-Z7CL0.js +1 -0
- package/client/dist/assets/agentstudio-Zmgzthv8.js +1 -0
- package/client/dist/assets/analytics-B8Qtptbl.js +1 -0
- package/client/dist/assets/analytics-BHqUazhP.js +1 -0
- package/client/dist/assets/analytics-BPptRY4f.js +1 -0
- package/client/dist/assets/analytics-BxDGOIwf.js +1 -0
- package/client/dist/assets/analytics-C9RaQcE3.js +1 -0
- package/client/dist/assets/analytics-CJIwqrEl.js +1 -0
- package/client/dist/assets/analytics-D_OZdQ9O.js +1 -0
- package/client/dist/assets/analytics-We6lUMI8.js +1 -0
- package/client/dist/assets/builder-3bygQtZi.js +1 -0
- package/client/dist/assets/builder-BiUG9Z5K.js +1 -0
- package/client/dist/assets/builder-CGRz_-zP.js +1 -0
- package/client/dist/assets/builder-CWYPw7Cw.js +1 -0
- package/client/dist/assets/builder-CX1437hF.js +1 -0
- package/client/dist/assets/{builder-CwA4T7gP.js → builder-Cowk9jtL.js} +1 -1
- package/client/dist/assets/builder-DwDexYRE.js +1 -0
- package/client/dist/assets/builder-skfnZ1uC.js +1 -0
- package/client/dist/assets/code-B0O8-p8k.js +1 -0
- package/client/dist/assets/code-B1VLZDhS.js +1 -0
- package/client/dist/assets/code-B86IMAfz.js +1 -0
- package/client/dist/assets/code-Bpj4Ddml.js +1 -0
- package/client/dist/assets/code-BykBZ5-e.js +1 -0
- package/client/dist/assets/code-CHPkOkDS.js +1 -0
- package/client/dist/assets/code-CkUuW4m9.js +1 -0
- package/client/dist/assets/code-cAqaqMTx.js +1 -0
- package/client/dist/assets/{dashboard-Dy2Um-US.js → dashboard-BVq6kRJe.js} +1 -1
- package/client/dist/assets/{dashboard-CHCEkds4.js → dashboard-BaKPPmLH.js} +1 -1
- package/client/dist/assets/{dashboard-CrlTV1ms.js → dashboard-Bm8e4zYG.js} +1 -1
- package/client/dist/assets/{dashboard-WhzOQw1S.js → dashboard-Bt6IesnM.js} +1 -1
- package/client/dist/assets/{dashboard-Cslu_GCH.js → dashboard-C_NQZle_.js} +1 -1
- package/client/dist/assets/{dashboard-DweT3Y4R.js → dashboard-CyZKoGoI.js} +1 -1
- package/client/dist/assets/{dashboard-DUU8-_Rg.js → dashboard-HIUdUBQ0.js} +1 -1
- package/client/dist/assets/{dashboard-Cqmmbh3l.js → dashboard-pm4Mr229.js} +1 -1
- package/client/dist/assets/{dist-js-jwoXo0YD.js → dist-js-BaP-xLOy.js} +1 -1
- package/client/dist/assets/{dist-js-Dj72W6qo.js → dist-js-CLlgOa5a.js} +1 -1
- package/client/dist/assets/format-command-C0D9IPmV.js +1 -0
- package/client/dist/assets/{formatDistanceToNow-ByKli7Q_.js → formatDistanceToNow-DUyzS4rr.js} +1 -1
- package/client/dist/assets/{getTimezoneOffsetInMilliseconds-qrcBaLW1.js → getTimezoneOffsetInMilliseconds-BCIwmmTj.js} +1 -1
- package/client/dist/assets/{i18n-Bf9Ckd10.js → i18n-D21Pr8Sj.js} +2 -2
- package/client/dist/assets/index-BdSDUFnA.css +2 -0
- package/client/dist/assets/index-Ci4-JKDr.js +77 -0
- package/client/dist/assets/{jobs-CVFD8rar.js → jobs-BAls3bWq.js} +1 -1
- package/client/dist/assets/{jobs-DoSaFzAa.js → jobs-B_TeSQxb.js} +1 -1
- package/client/dist/assets/jobs-Bgq-PZkC.js +1 -0
- package/client/dist/assets/jobs-Bpks6doU.js +1 -0
- package/client/dist/assets/jobs-CN_zv4Gr.js +1 -0
- package/client/dist/assets/jobs-DUlWSYq2.js +1 -0
- package/client/dist/assets/{jobs-B-sDHEay.js → jobs-DhxKgWFq.js} +1 -1
- package/client/dist/assets/{jobs-lk1_Dq1U.js → jobs-SwYS2M-B.js} +1 -1
- package/client/dist/assets/nav-BHDiSIVu.js +1 -0
- package/client/dist/assets/nav-CMiYAq4i.js +1 -0
- package/client/dist/assets/nav-CqS7NrDW.js +1 -0
- package/client/dist/assets/nav-D-0M7xfv.js +1 -0
- package/client/dist/assets/nav-D65O6u9I.js +1 -0
- package/client/dist/assets/nav-D_LKYvBr.js +1 -0
- package/client/dist/assets/nav-FDTJmU79.js +1 -0
- package/client/dist/assets/nav-VaB-C4k5.js +1 -0
- package/client/dist/assets/provider-capabilities-BvoExILy.js +1 -0
- package/client/dist/assets/settings-BveOJoaI.js +1 -0
- package/client/dist/assets/settings-Cj1C6F5k.js +1 -0
- package/client/dist/assets/settings-CuVwOpe0.js +1 -0
- package/client/dist/assets/settings-D5X4DfRc.js +1 -0
- package/client/dist/assets/settings-DXwxe-BW.js +1 -0
- package/client/dist/assets/settings-Di81Ba_V.js +1 -0
- package/client/dist/assets/settings-jbLjCYC_.js +1 -0
- package/client/dist/assets/settings-wIZNPFnn.js +1 -0
- package/client/dist/assets/setup-BBiHEO7h.js +1 -0
- package/client/dist/assets/setup-BlTWhNIQ.js +1 -0
- package/client/dist/assets/setup-Bp2L_oiP.js +1 -0
- package/client/dist/assets/setup-CInYXp1-.js +1 -0
- package/client/dist/assets/{setup-CITtPjed.js → setup-CYH3bP6K.js} +1 -1
- package/client/dist/assets/setup-DwcQ921P.js +1 -0
- package/client/dist/assets/setup-PBLjuDSs.js +1 -0
- package/client/dist/assets/setup-bx6FtoBp.js +1 -0
- package/client/dist/assets/{spending-DMnCXy84.js → spending-BCyUxoOI.js} +1 -1
- package/client/dist/assets/{tickets-B8BuAaj5.js → tickets-BL9r1G0e.js} +1 -1
- package/client/dist/assets/{tickets-DpmdE8tv.js → tickets-B_NyHJ8f.js} +1 -1
- package/client/dist/assets/{tickets-B_yh4qQk.js → tickets-BarF1wuG.js} +1 -1
- package/client/dist/assets/{tickets-pAUJkDTu.js → tickets-CclVhpQA.js} +1 -1
- package/client/dist/assets/{tickets-D_yDquEw.js → tickets-CqqOHbli.js} +1 -1
- package/client/dist/assets/{tickets-CFk2n2Or.js → tickets-DCkFSiqt.js} +1 -1
- package/client/dist/assets/{tickets-DQp7JS2R.js → tickets-Djn3ccfT.js} +1 -1
- package/client/dist/assets/{tickets-Bs37scwY.js → tickets-MiHBPsy_.js} +1 -1
- package/client/dist/assets/{useBrowserCaptureSession-CkBJShUw.js → useBrowserCaptureSession-CkVCDzer.js} +1 -1
- package/client/dist/assets/{useDesktop-B4pSBIDd.js → useDesktop-DCP_MHp9.js} +1 -1
- package/client/dist/index.html +25 -24
- package/docs/README.md +7 -3
- package/docs/cli.md +3 -3
- package/docs/codex.md +51 -64
- package/docs/creating-specs.md +36 -4
- package/docs/customizing.md +5 -5
- package/docs/gemini.md +35 -47
- package/docs/getting-started.md +15 -9
- package/docs/guide/de/agents/2-profiles-and-the-balanced-default.md +5 -1
- package/docs/guide/de/agents/4-custom-agents-catalog.md +7 -4
- package/docs/guide/de/getting-started/1-what-is-specrails.md +1 -0
- package/docs/guide/de/getting-started/2-installing-and-first-run.md +1 -0
- package/docs/guide/de/getting-started/4-the-dashboard-tour.md +4 -4
- package/docs/guide/de/integrations/1-ai-providers.md +29 -18
- package/docs/guide/de/integrations/2-plugins.md +3 -3
- package/docs/guide/de/integrations/6-agent-chat.md +8 -1
- package/docs/guide/de/pipeline/1-rails-and-jobs.md +9 -6
- package/docs/guide/de/pipeline/2-the-job-detail-view.md +3 -1
- package/docs/guide/de/pipeline/3-batch-implement-and-multi-feature.md +1 -1
- package/docs/guide/de/pipeline/4-picking-an-engine-per-rail.md +13 -13
- package/docs/guide/de/pipeline/5-the-loop-builder.md +6 -2
- package/docs/guide/de/specs/2-add-spec-quick-mode.md +6 -1
- package/docs/guide/en/agents/2-profiles-and-the-balanced-default.md +7 -1
- package/docs/guide/en/agents/4-custom-agents-catalog.md +17 -4
- package/docs/guide/en/getting-started/1-what-is-specrails.md +2 -1
- package/docs/guide/en/getting-started/2-installing-and-first-run.md +2 -1
- package/docs/guide/en/getting-started/4-the-dashboard-tour.md +5 -5
- package/docs/guide/en/insights/3-code-explorer.md +5 -0
- package/docs/guide/en/integrations/1-ai-providers.md +63 -22
- package/docs/guide/en/integrations/2-plugins.md +3 -3
- package/docs/guide/en/integrations/6-agent-chat.md +14 -2
- package/docs/guide/en/pipeline/1-rails-and-jobs.md +19 -7
- package/docs/guide/en/pipeline/2-the-job-detail-view.md +3 -1
- package/docs/guide/en/pipeline/3-batch-implement-and-multi-feature.md +1 -1
- package/docs/guide/en/pipeline/4-picking-an-engine-per-rail.md +25 -11
- package/docs/guide/en/pipeline/5-the-loop-builder.md +7 -2
- package/docs/guide/en/specs/2-add-spec-quick-mode.md +10 -1
- package/docs/guide/es/agents/2-profiles-and-the-balanced-default.md +5 -1
- package/docs/guide/es/agents/4-custom-agents-catalog.md +7 -4
- package/docs/guide/es/getting-started/1-what-is-specrails.md +1 -0
- package/docs/guide/es/getting-started/2-installing-and-first-run.md +1 -0
- package/docs/guide/es/getting-started/4-the-dashboard-tour.md +4 -4
- package/docs/guide/es/integrations/1-ai-providers.md +30 -18
- package/docs/guide/es/integrations/2-plugins.md +3 -3
- package/docs/guide/es/integrations/6-agent-chat.md +8 -1
- package/docs/guide/es/pipeline/1-rails-and-jobs.md +9 -6
- package/docs/guide/es/pipeline/2-the-job-detail-view.md +3 -1
- package/docs/guide/es/pipeline/3-batch-implement-and-multi-feature.md +1 -1
- package/docs/guide/es/pipeline/4-picking-an-engine-per-rail.md +15 -13
- package/docs/guide/es/pipeline/5-the-loop-builder.md +6 -2
- package/docs/guide/es/specs/2-add-spec-quick-mode.md +6 -1
- package/docs/guide/fr/agents/2-profiles-and-the-balanced-default.md +5 -1
- package/docs/guide/fr/agents/4-custom-agents-catalog.md +7 -4
- package/docs/guide/fr/getting-started/1-what-is-specrails.md +1 -0
- package/docs/guide/fr/getting-started/2-installing-and-first-run.md +1 -0
- package/docs/guide/fr/getting-started/4-the-dashboard-tour.md +4 -4
- package/docs/guide/fr/integrations/1-ai-providers.md +29 -18
- package/docs/guide/fr/integrations/2-plugins.md +3 -3
- package/docs/guide/fr/integrations/6-agent-chat.md +8 -1
- package/docs/guide/fr/pipeline/1-rails-and-jobs.md +9 -6
- package/docs/guide/fr/pipeline/2-the-job-detail-view.md +3 -1
- package/docs/guide/fr/pipeline/3-batch-implement-and-multi-feature.md +1 -1
- package/docs/guide/fr/pipeline/4-picking-an-engine-per-rail.md +15 -13
- package/docs/guide/fr/pipeline/5-the-loop-builder.md +6 -2
- package/docs/guide/fr/specs/2-add-spec-quick-mode.md +6 -1
- package/docs/guide/it/agents/2-profiles-and-the-balanced-default.md +5 -1
- package/docs/guide/it/agents/4-custom-agents-catalog.md +7 -4
- package/docs/guide/it/getting-started/1-what-is-specrails.md +1 -0
- package/docs/guide/it/getting-started/2-installing-and-first-run.md +1 -0
- package/docs/guide/it/getting-started/4-the-dashboard-tour.md +4 -4
- package/docs/guide/it/integrations/1-ai-providers.md +28 -18
- package/docs/guide/it/integrations/2-plugins.md +3 -3
- package/docs/guide/it/integrations/6-agent-chat.md +8 -1
- package/docs/guide/it/pipeline/1-rails-and-jobs.md +9 -6
- package/docs/guide/it/pipeline/2-the-job-detail-view.md +3 -1
- package/docs/guide/it/pipeline/3-batch-implement-and-multi-feature.md +1 -1
- package/docs/guide/it/pipeline/4-picking-an-engine-per-rail.md +13 -13
- package/docs/guide/it/pipeline/5-the-loop-builder.md +6 -2
- package/docs/guide/it/specs/2-add-spec-quick-mode.md +6 -1
- package/docs/guide/ja/agents/2-profiles-and-the-balanced-default.md +6 -1
- package/docs/guide/ja/agents/4-custom-agents-catalog.md +7 -4
- package/docs/guide/ja/getting-started/1-what-is-specrails.md +1 -0
- package/docs/guide/ja/getting-started/2-installing-and-first-run.md +1 -0
- package/docs/guide/ja/getting-started/4-the-dashboard-tour.md +4 -4
- package/docs/guide/ja/integrations/1-ai-providers.md +28 -18
- package/docs/guide/ja/integrations/2-plugins.md +3 -3
- package/docs/guide/ja/integrations/6-agent-chat.md +7 -1
- package/docs/guide/ja/pipeline/1-rails-and-jobs.md +9 -6
- package/docs/guide/ja/pipeline/2-the-job-detail-view.md +3 -1
- package/docs/guide/ja/pipeline/3-batch-implement-and-multi-feature.md +1 -1
- package/docs/guide/ja/pipeline/4-picking-an-engine-per-rail.md +14 -13
- package/docs/guide/ja/pipeline/5-the-loop-builder.md +6 -2
- package/docs/guide/ja/specs/2-add-spec-quick-mode.md +6 -1
- package/docs/guide/pt/agents/2-profiles-and-the-balanced-default.md +5 -1
- package/docs/guide/pt/agents/4-custom-agents-catalog.md +7 -4
- package/docs/guide/pt/getting-started/1-what-is-specrails.md +1 -0
- package/docs/guide/pt/getting-started/2-installing-and-first-run.md +1 -0
- package/docs/guide/pt/getting-started/4-the-dashboard-tour.md +4 -4
- package/docs/guide/pt/integrations/1-ai-providers.md +28 -18
- package/docs/guide/pt/integrations/2-plugins.md +3 -3
- package/docs/guide/pt/integrations/6-agent-chat.md +7 -1
- package/docs/guide/pt/pipeline/1-rails-and-jobs.md +9 -6
- package/docs/guide/pt/pipeline/2-the-job-detail-view.md +2 -1
- package/docs/guide/pt/pipeline/3-batch-implement-and-multi-feature.md +1 -1
- package/docs/guide/pt/pipeline/4-picking-an-engine-per-rail.md +14 -13
- package/docs/guide/pt/pipeline/5-the-loop-builder.md +6 -2
- package/docs/guide/pt/specs/2-add-spec-quick-mode.md +6 -1
- package/docs/guide/zh/agents/2-profiles-and-the-balanced-default.md +4 -1
- package/docs/guide/zh/agents/4-custom-agents-catalog.md +7 -4
- package/docs/guide/zh/getting-started/1-what-is-specrails.md +1 -0
- package/docs/guide/zh/getting-started/2-installing-and-first-run.md +1 -0
- package/docs/guide/zh/getting-started/4-the-dashboard-tour.md +4 -4
- package/docs/guide/zh/integrations/1-ai-providers.md +26 -18
- package/docs/guide/zh/integrations/2-plugins.md +3 -3
- package/docs/guide/zh/integrations/6-agent-chat.md +6 -1
- package/docs/guide/zh/pipeline/1-rails-and-jobs.md +9 -6
- package/docs/guide/zh/pipeline/2-the-job-detail-view.md +2 -1
- package/docs/guide/zh/pipeline/3-batch-implement-and-multi-feature.md +1 -1
- package/docs/guide/zh/pipeline/4-picking-an-engine-per-rail.md +12 -12
- package/docs/guide/zh/pipeline/5-the-loop-builder.md +6 -2
- package/docs/guide/zh/specs/2-add-spec-quick-mode.md +6 -1
- package/docs/internals/README.md +4 -1
- package/docs/internals/adding-a-provider.md +32 -28
- package/docs/internals/api-reference.md +37 -13
- package/docs/internals/architecture.md +5 -5
- package/docs/internals/bundled-framework-build-plan.md +3 -3
- package/docs/internals/code-explorer-story.md +4 -0
- package/docs/internals/configuration.md +17 -5
- package/docs/internals/global-artifacts-alignment-contract.md +1 -1
- package/docs/internals/operations-runbook.md +1 -1
- package/docs/internals/profiles.md +37 -45
- package/docs/internals/project-builder.md +16 -0
- package/docs/kimi.md +291 -0
- package/docs/mcp.md +9 -2
- package/docs/platforms/macos.md +17 -7
- package/docs/platforms/windows.md +9 -4
- package/docs/running-pipelines.md +46 -12
- package/docs/terminal.md +1 -1
- package/docs/tracking-cost.md +25 -6
- package/package.json +4 -2
- package/server/dist/agent-chat-manager.js +74 -32
- package/server/dist/agent-chat-router.js +40 -17
- package/server/dist/agent-cwd-manager.js +14 -7
- package/server/dist/agent-generator.js +69 -85
- package/server/dist/agent-mcp-config.js +17 -11
- package/server/dist/agent-operator-prompt.js +29 -20
- package/server/dist/agent-refine-manager.js +58 -38
- package/server/dist/ai-invocations.js +65 -20
- package/server/dist/attachment-manager.js +49 -15
- package/server/dist/blueprint-chat-manager.js +41 -16
- package/server/dist/blueprint-router.js +40 -6
- package/server/dist/chat-manager.js +165 -89
- package/server/dist/code-explorer-router.js +26 -7
- package/server/dist/contract-refine-runner.js +146 -113
- package/server/dist/core-compat.js +57 -2
- package/server/dist/core-package.js +3 -3
- package/server/dist/core-update-manager.js +17 -1
- package/server/dist/db.js +60 -5
- package/server/dist/desktop-analytics.js +44 -6
- package/server/dist/desktop-router.js +127 -11
- package/server/dist/explore-cwd-manager.js +19 -3
- package/server/dist/feature-flags.js +1 -1
- package/server/dist/file-story-manager.js +3 -3
- package/server/dist/file-summary-generator.js +21 -15
- package/server/dist/file-summary-manager.js +6 -6
- package/server/dist/framework-manager.js +19 -2
- package/server/dist/framework-migration.js +27 -12
- package/server/dist/install-config-path.js +1 -1
- package/server/dist/interactive-job-session.js +8 -6
- package/server/dist/loop-command-catalog.js +27 -10
- package/server/dist/loop-executors.js +59 -27
- package/server/dist/loop-factory.js +2 -2
- package/server/dist/loop-run-manager.js +100 -39
- package/server/dist/loops-router.js +1 -1
- package/server/dist/mcp/guide.js +23 -16
- package/server/dist/mcp/tools/agents.js +47 -41
- package/server/dist/mcp/tools/analytics.js +2 -2
- package/server/dist/mcp/tools/loops.js +2 -2
- package/server/dist/mcp/tools/plugins.js +14 -9
- package/server/dist/mcp/tools/rails.js +12 -13
- package/server/dist/mcp/tools/support.js +1 -1
- package/server/dist/mobile/mobile-router.js +5 -1
- package/server/dist/offline-assemble.js +13 -1
- package/server/dist/path-resolver.js +2 -2
- package/server/dist/plugin-manager.js +391 -106
- package/server/dist/plugins/claude-md-mutation.js +5 -4
- package/server/dist/plugins/drift.js +32 -29
- package/server/dist/plugins/rail-integration.js +13 -2
- package/server/dist/plugins/serena/install.js +25 -17
- package/server/dist/plugins/serena/manifest.js +22 -5
- package/server/dist/plugins/serena/verify.js +46 -16
- package/server/dist/plugins-router.js +59 -8
- package/server/dist/profile-manager.js +148 -36
- package/server/dist/profiles-router.js +311 -82
- package/server/dist/project-registry.js +2 -2
- package/server/dist/project-router-chat.js +17 -8
- package/server/dist/project-router-helpers.js +93 -5
- package/server/dist/project-router-jobs.js +76 -12
- package/server/dist/project-router-loop-runs.js +42 -14
- package/server/dist/project-router-settings.js +31 -10
- package/server/dist/project-router-setup.js +4 -5
- package/server/dist/project-router-spending.js +15 -3
- package/server/dist/project-router-tickets.js +187 -181
- package/server/dist/project-router.js +1 -0
- package/server/dist/proposal-manager.js +125 -85
- package/server/dist/providers/claude-adapter.js +14 -0
- package/server/dist/providers/codex-adapter.js +20 -0
- package/server/dist/providers/gemini-adapter.js +14 -0
- package/server/dist/providers/index.js +18 -1
- package/server/dist/providers/kimi-adapter.js +361 -0
- package/server/dist/providers/kimi-skill-prompt.js +332 -0
- package/server/dist/providers/runtime.js +137 -0
- package/server/dist/queue-manager.js +103 -78
- package/server/dist/rail-isolated-launch.js +1 -1
- package/server/dist/rails-router.js +51 -38
- package/server/dist/result-event.js +5 -0
- package/server/dist/schemas/profile.v1.json +3 -4
- package/server/dist/setup-manager.js +222 -101
- package/server/dist/setup-prerequisites.js +7 -1
- package/server/dist/smash-runner.js +104 -57
- package/server/dist/spawn-lifecycle.js +18 -14
- package/server/dist/spec-launcher-manager.js +66 -54
- package/server/dist/spec-models.js +15 -6
- package/server/dist/spending.js +110 -17
- package/server/dist/util/cli-prompt.js +142 -5
- package/server/dist/util/stream-display.js +46 -0
- package/server/dist/workspace-manager.js +100 -37
- package/server/dist/worktree-manager.js +4 -0
- package/server/dist/worktree-overlay.js +12 -3
- package/client/dist/assets/AgentModeCodePane-BAYyFRmY.js +0 -2
- package/client/dist/assets/AgentsPage-DuyJuaFs.js +0 -86
- package/client/dist/assets/AnalyticsPage-BY7gtCx6.js +0 -1
- package/client/dist/assets/CodePage-vyQr40Vl.js +0 -2
- package/client/dist/assets/JobDetailPage-CU4FEnUC.js +0 -1
- package/client/dist/assets/LoopsPage-SqglnXlp.js +0 -1
- package/client/dist/assets/PluginsPage-B89S8o1a.js +0 -2
- package/client/dist/assets/TicketDetailModal-CI47Dq9E.js +0 -14
- package/client/dist/assets/addspec-BXjvkh5q.js +0 -1
- package/client/dist/assets/addspec-C4bwrmpi.js +0 -1
- package/client/dist/assets/addspec-CArHXUDM.js +0 -1
- package/client/dist/assets/addspec-DTKJcXiR.js +0 -1
- package/client/dist/assets/addspec-DbNBbrha.js +0 -1
- package/client/dist/assets/addspec-Rw8uVBC1.js +0 -1
- package/client/dist/assets/addspec-htHGZHOe.js +0 -1
- package/client/dist/assets/addspec-lr_LP6jk.js +0 -1
- package/client/dist/assets/agent-BABjRt0P.js +0 -1
- package/client/dist/assets/agent-BuUpgqVx.js +0 -1
- package/client/dist/assets/agent-CCDZesgU.js +0 -1
- package/client/dist/assets/agent-CVn64zWH.js +0 -1
- package/client/dist/assets/agent-CWeOny0E.js +0 -1
- package/client/dist/assets/agent-DOysmad_.js +0 -1
- package/client/dist/assets/agent-DSsjTBhn.js +0 -1
- package/client/dist/assets/agent-DlZMxfM9.js +0 -1
- package/client/dist/assets/agents-6ZOJXWVk.js +0 -1
- package/client/dist/assets/agents-BZ0XQKjg.js +0 -1
- package/client/dist/assets/agents-BqWklnHR.js +0 -1
- package/client/dist/assets/agents-Bz-thHkB.js +0 -1
- package/client/dist/assets/agents-CJclElx6.js +0 -1
- package/client/dist/assets/agents-D_l9L0VA.js +0 -1
- package/client/dist/assets/agents-DhG7mg6-.js +0 -1
- package/client/dist/assets/agents-u_C0jPB5.js +0 -1
- package/client/dist/assets/agentstudio-BF19hbXj.js +0 -1
- package/client/dist/assets/agentstudio-BIUe1Im2.js +0 -1
- package/client/dist/assets/agentstudio-BLGvxWBx.js +0 -1
- package/client/dist/assets/agentstudio-D9UKiWTj.js +0 -1
- package/client/dist/assets/agentstudio-Drs37nIM.js +0 -1
- package/client/dist/assets/agentstudio-nEnKkcXM.js +0 -1
- package/client/dist/assets/agentstudio-pyFcSBKy.js +0 -1
- package/client/dist/assets/agentstudio-zfTzQh3U.js +0 -1
- package/client/dist/assets/analytics-BC7mwR4s.js +0 -1
- package/client/dist/assets/analytics-BiNg8edP.js +0 -1
- package/client/dist/assets/analytics-C0s_T2GN.js +0 -1
- package/client/dist/assets/analytics-CdsAPAwZ.js +0 -1
- package/client/dist/assets/analytics-Cr1_q-lC.js +0 -1
- package/client/dist/assets/analytics-DZ8Aoq3I.js +0 -1
- package/client/dist/assets/analytics-IEsKZvpW.js +0 -1
- package/client/dist/assets/analytics-SRPf84OT.js +0 -1
- package/client/dist/assets/builder-BH8Fua-g.js +0 -1
- package/client/dist/assets/builder-BoV7DgKd.js +0 -1
- package/client/dist/assets/builder-Cc_Lf79C.js +0 -1
- package/client/dist/assets/builder-CwZ7Bme2.js +0 -1
- package/client/dist/assets/builder-CxW-JFsR.js +0 -1
- package/client/dist/assets/builder-D94lrV7x.js +0 -1
- package/client/dist/assets/builder-cqHpCyGa.js +0 -1
- package/client/dist/assets/code-76gS0IdL.js +0 -1
- package/client/dist/assets/code-BDXEM4ml.js +0 -1
- package/client/dist/assets/code-C1VwxlML.js +0 -1
- package/client/dist/assets/code-CnMZyJpr.js +0 -1
- package/client/dist/assets/code-D20ef9Cf.js +0 -1
- package/client/dist/assets/code-DdOXaWRY.js +0 -1
- package/client/dist/assets/code-Duohuf9l.js +0 -1
- package/client/dist/assets/code-geHmknB9.js +0 -1
- package/client/dist/assets/format-command-Dfa1o2d-.js +0 -1
- package/client/dist/assets/index-Dh9i4CnN.css +0 -2
- package/client/dist/assets/index-F9r8mWP_.js +0 -76
- package/client/dist/assets/jobs-BCtGfgUA.js +0 -1
- package/client/dist/assets/jobs-BHR_EnDI.js +0 -1
- package/client/dist/assets/jobs-BMbZJjJJ.js +0 -1
- package/client/dist/assets/jobs-DzSIR8V6.js +0 -1
- package/client/dist/assets/nav-BRJBxaGt.js +0 -1
- package/client/dist/assets/nav-CAGKv3_F.js +0 -1
- package/client/dist/assets/nav-CNskRJKQ.js +0 -1
- package/client/dist/assets/nav-DY93irBL.js +0 -1
- package/client/dist/assets/nav-DhjvYgqt.js +0 -1
- package/client/dist/assets/nav-Gb-r4wop.js +0 -1
- package/client/dist/assets/nav-TvumAFD2.js +0 -1
- package/client/dist/assets/nav-myFaXRHD.js +0 -1
- package/client/dist/assets/settings-B0ypw9uw.js +0 -1
- package/client/dist/assets/settings-B9ilOSYO.js +0 -1
- package/client/dist/assets/settings-BqlWHRHA.js +0 -1
- package/client/dist/assets/settings-D8dlqt4d.js +0 -1
- package/client/dist/assets/settings-DAZqjX2a.js +0 -1
- package/client/dist/assets/settings-DRh39v1S.js +0 -1
- package/client/dist/assets/settings-Mj1OJbfd.js +0 -1
- package/client/dist/assets/settings-lRReaSYm.js +0 -1
- package/client/dist/assets/setup-3832BJCo.js +0 -1
- package/client/dist/assets/setup-B8J-gECe.js +0 -1
- package/client/dist/assets/setup-BCIOxVsc.js +0 -1
- package/client/dist/assets/setup-BciLj_tU.js +0 -1
- package/client/dist/assets/setup-CTkE3cfh.js +0 -1
- package/client/dist/assets/setup-ajB4rYm-.js +0 -1
- package/client/dist/assets/setup-xFO1wNl0.js +0 -1
|
@@ -37,6 +37,11 @@ function finaliseInvocationResult(adapter, events, opts = {}) {
|
|
|
37
37
|
if (!cloned.model && opts.fallbackModel) {
|
|
38
38
|
cloned.model = opts.fallbackModel;
|
|
39
39
|
}
|
|
40
|
+
if (cloned.duration_ms == null &&
|
|
41
|
+
typeof opts.durationMs === 'number' &&
|
|
42
|
+
Number.isFinite(opts.durationMs)) {
|
|
43
|
+
cloned.duration_ms = Math.max(0, opts.durationMs);
|
|
44
|
+
}
|
|
40
45
|
let estimated = false;
|
|
41
46
|
// Guard: when the breakdown carries NO billable usage (every token field
|
|
42
47
|
// undefined/0 — e.g. a codex/gemini turn aborted/crashed before its
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"provider": {
|
|
27
27
|
"type": "string",
|
|
28
28
|
"pattern": "^[a-z0-9][a-z0-9-]*$",
|
|
29
|
-
"description": "Optional provider id (
|
|
29
|
+
"description": "Optional registered provider id (for example `claude`, `codex`, `gemini`, or `kimi`). When set, the profile's model values are validated according to that provider adapter: normally against its catalog, while adapters that support configured aliases (such as Kimi) accept any schema-valid non-empty alias. When omitted, validation falls back to the project's resolved provider."
|
|
30
30
|
},
|
|
31
31
|
"orchestrator": {
|
|
32
32
|
"type": "object",
|
|
@@ -82,8 +82,7 @@
|
|
|
82
82
|
"modelAlias": {
|
|
83
83
|
"type": "string",
|
|
84
84
|
"minLength": 1,
|
|
85
|
-
"
|
|
86
|
-
"description": "Accepted model alias. JSON schema accepts any non-empty string; provider-specific catalog enforcement runs at runtime (see profile-manager.validateStructural)."
|
|
85
|
+
"description": "Accepted model alias. JSON schema accepts any non-empty string without truncating provider-configured aliases; provider-specific catalog enforcement runs at runtime (see profile-manager.validateStructural)."
|
|
87
86
|
},
|
|
88
87
|
"agentEntry": {
|
|
89
88
|
"type": "object",
|
|
@@ -93,7 +92,7 @@
|
|
|
93
92
|
"id": {
|
|
94
93
|
"type": "string",
|
|
95
94
|
"pattern": "^(sr|custom)-[a-z0-9][a-z0-9-]*$",
|
|
96
|
-
"description": "Agent identifier. MUST correspond to
|
|
95
|
+
"description": "Agent identifier. MUST correspond to the selected provider's provider-native role artifact. File-based providers use their own agents catalog (for example `.claude/agents/<id>.md`); Kimi uses the directly discoverable `.kimi-code/skills/<id>/SKILL.md` layout."
|
|
97
96
|
},
|
|
98
97
|
"model": {
|
|
99
98
|
"$ref": "#/$defs/modelAlias",
|
|
@@ -20,6 +20,7 @@ const win_spawn_1 = require("./util/win-spawn");
|
|
|
20
20
|
const setup_prerequisites_1 = require("./setup-prerequisites");
|
|
21
21
|
const core_package_1 = require("./core-package");
|
|
22
22
|
const providers_1 = require("./providers");
|
|
23
|
+
const runtime_1 = require("./providers/runtime");
|
|
23
24
|
const result_event_1 = require("./result-event");
|
|
24
25
|
const ai_invocations_1 = require("./ai-invocations");
|
|
25
26
|
const crypto_1 = require("crypto");
|
|
@@ -240,21 +241,29 @@ exports.QUICK_CHECKPOINTS = [
|
|
|
240
241
|
{ key: 'base_install', name: 'Base installation' },
|
|
241
242
|
{ key: 'quick_complete', name: 'Quick install complete' },
|
|
242
243
|
];
|
|
243
|
-
function checkFilesystem(projectPath) {
|
|
244
|
-
const
|
|
244
|
+
function checkFilesystem(projectPath, provider = 'claude') {
|
|
245
|
+
const adapter = (0, providers_1.hasAdapter)(provider) ? (0, providers_1.getAdapter)(provider) : (0, providers_1.getAdapter)('claude');
|
|
246
|
+
const dir = adapter.projectDirName;
|
|
247
|
+
const artifactState = setupArtifactState(projectPath, 'full', provider);
|
|
245
248
|
const hasBaseInstall = (0, fs_1.existsSync)((0, path_1.join)(projectPath, '.specrails', 'specrails-version')) ||
|
|
246
249
|
(0, fs_1.existsSync)((0, path_1.join)(projectPath, '.specrails-version'));
|
|
247
250
|
const hasSetupTemplates = (0, fs_1.existsSync)((0, path_1.join)(projectPath, '.specrails', 'setup-templates')) ||
|
|
248
251
|
(0, fs_1.existsSync)((0, path_1.join)(projectPath, dir, 'setup-templates'));
|
|
249
252
|
const hasRules = (0, fs_1.existsSync)((0, path_1.join)(projectPath, dir, 'rules')) &&
|
|
250
253
|
hasFiles((0, path_1.join)(projectPath, dir, 'rules'), /\.md$/);
|
|
251
|
-
const hasPersonas =
|
|
252
|
-
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
254
|
+
const hasPersonas = artifactState.hasPersonas;
|
|
255
|
+
const hasAgents = artifactState.hasAgents;
|
|
256
|
+
const hasCommands = artifactState.hasCommands;
|
|
257
|
+
const instructionCandidates = [(0, path_1.join)(projectPath, adapter.instructionsFilename)];
|
|
258
|
+
// Older Core releases sometimes placed a top-level instructions filename
|
|
259
|
+
// inside the provider directory. Preserve that compatibility only for
|
|
260
|
+
// actual filenames: Kimi's adapter already declares the provider-relative
|
|
261
|
+
// `.kimi-code/AGENTS.md` path, so prefixing projectDirName again would probe
|
|
262
|
+
// the nonsensical `.kimi-code/.kimi-code/AGENTS.md`.
|
|
263
|
+
if (adapter.instructionsFilename === (0, path_1.basename)(adapter.instructionsFilename)) {
|
|
264
|
+
instructionCandidates.push((0, path_1.join)(projectPath, dir, adapter.instructionsFilename));
|
|
265
|
+
}
|
|
266
|
+
const hasInstructions = instructionCandidates.some((candidate) => (0, fs_1.existsSync)(candidate));
|
|
258
267
|
const hasInstallConfig = (0, fs_1.existsSync)((0, path_1.join)(projectPath, '.specrails', 'install-config.yaml')) ||
|
|
259
268
|
(0, fs_1.existsSync)((0, path_1.join)(projectPath, dir, 'install-config.yaml'));
|
|
260
269
|
const hasAgentConfig = (0, fs_1.existsSync)((0, path_1.join)(projectPath, dir, 'agents.yaml'));
|
|
@@ -264,7 +273,7 @@ function checkFilesystem(projectPath) {
|
|
|
264
273
|
// Back-compat filesystem signals from older cores are translated to the
|
|
265
274
|
// current integration-contract checkpoint keys.
|
|
266
275
|
agent_selection: hasInstallConfig || hasAgentConfig || hasBacklogConfig || hasAgents || hasCommands,
|
|
267
|
-
codebase_analysis: hasBaseInstall && (
|
|
276
|
+
codebase_analysis: hasBaseInstall && (hasInstructions || hasSetupTemplates),
|
|
268
277
|
vpc_discovery: hasPersonas,
|
|
269
278
|
persona_synthesis: hasPersonas,
|
|
270
279
|
agent_generation: hasAgents,
|
|
@@ -355,19 +364,19 @@ function detectCheckpointFromText(text) {
|
|
|
355
364
|
if (/\/agents\/sr-[^/]+\.md/.test(text)) {
|
|
356
365
|
hits.push({ key: 'agent_generation', detail: 'Writing agents...' });
|
|
357
366
|
}
|
|
358
|
-
//
|
|
359
|
-
//
|
|
360
|
-
//
|
|
361
|
-
if (/\.codex\/skills\/sr-[^/]+\/SKILL\.md/.test(text)) {
|
|
367
|
+
// Provider-native rail skills. Kimi's upstream discovery contract scans only
|
|
368
|
+
// direct children of `.kimi-code/skills`, so its roles are top-level
|
|
369
|
+
// `.kimi-code/skills/sr-*/SKILL.md` entries. Codex may also use `rails/`.
|
|
370
|
+
if (/\.(?:codex|kimi-code)\/skills\/(?:rails\/)?sr-[^/]+\/SKILL\.md/.test(text)) {
|
|
362
371
|
hits.push({ key: 'agent_generation', detail: 'Writing agent skills...' });
|
|
363
372
|
}
|
|
364
373
|
if ((text.includes('/commands/sr/') || text.includes('/commands/specrails/')) && text.includes('.md')) {
|
|
365
374
|
hits.push({ key: 'command_generation', detail: 'Writing commands...' });
|
|
366
375
|
}
|
|
367
|
-
//
|
|
376
|
+
// Provider-native enrich/doctor skills (the non-rail commands) also indicate
|
|
368
377
|
// command_generation progress.
|
|
369
|
-
if (/\.codex\/skills\/(enrich|doctor)\/SKILL\.md/.test(text)) {
|
|
370
|
-
hits.push({ key: 'command_generation', detail: 'Writing
|
|
378
|
+
if (/\.(?:codex|kimi-code)\/skills\/(?:specrails-)?(?:enrich|doctor)\/SKILL\.md/.test(text)) {
|
|
379
|
+
hits.push({ key: 'command_generation', detail: 'Writing provider command skills...' });
|
|
371
380
|
}
|
|
372
381
|
if (text.includes('/rules/') && text.includes('.md')) {
|
|
373
382
|
hits.push({ key: 'command_generation', detail: 'Writing conventions...' });
|
|
@@ -456,24 +465,33 @@ function computeSummary(projectPath, tier, provider = 'claude') {
|
|
|
456
465
|
let specrailsCommands = 0;
|
|
457
466
|
let opsxCommands = 0;
|
|
458
467
|
try {
|
|
459
|
-
if (provider === 'codex') {
|
|
460
|
-
// Codex layout: every artefact ships as a SKILL under
|
|
468
|
+
if (provider === 'codex' || provider === 'kimi') {
|
|
469
|
+
// Codex/Kimi layout: every artefact ships as a SKILL under the provider's
|
|
470
|
+
// `skills/` root.
|
|
461
471
|
// - agents = rail personas (`skills/rails/sr-*/SKILL.md`) + orchestrator
|
|
462
|
-
// skills at the root with an `sr-` prefix
|
|
463
|
-
// sr
|
|
472
|
+
// skills at the root with an `sr-` prefix. Kimi roles MUST be
|
|
473
|
+
// direct children (`skills/sr-*/SKILL.md`) because upstream
|
|
474
|
+
// Kimi discovery is intentionally one level deep.
|
|
464
475
|
// - opsxCommands = `skills/openspec-*/SKILL.md`
|
|
465
476
|
// - specrailsCommands = everything else under `skills/` (ported claude
|
|
466
477
|
// slash commands like propose-spec, explore-spec, retry, doctor,
|
|
467
478
|
// enrich, vpc-drift, …)
|
|
468
|
-
// - personas =
|
|
469
|
-
|
|
479
|
+
// - personas = Kimi's provider-local `.kimi-code/personas/*.md`; Codex
|
|
480
|
+
// keeps its legacy nested skill representation.
|
|
481
|
+
const skillsDir = (0, path_1.join)(projectPath, provider === 'kimi' ? '.kimi-code' : '.codex', 'skills');
|
|
470
482
|
if ((0, fs_1.existsSync)(skillsDir)) {
|
|
471
|
-
// Rails
|
|
483
|
+
// Codex retains its nested Rails catalog. Kimi cannot: nested skills
|
|
484
|
+
// are not discoverable by the Kimi CLI.
|
|
472
485
|
const railsDir = (0, path_1.join)(skillsDir, 'rails');
|
|
473
|
-
if ((0, fs_1.existsSync)(railsDir)) {
|
|
486
|
+
if (provider === 'codex' && (0, fs_1.existsSync)(railsDir)) {
|
|
474
487
|
for (const entry of (0, fs_1.readdirSync)(railsDir)) {
|
|
475
|
-
if (
|
|
488
|
+
if (entry === 'personas') {
|
|
489
|
+
const personasDir = (0, path_1.join)(railsDir, entry);
|
|
490
|
+
personas = (0, fs_1.readdirSync)(personasDir).filter((persona) => (0, fs_1.existsSync)((0, path_1.join)(personasDir, persona, 'SKILL.md'))).length;
|
|
491
|
+
}
|
|
492
|
+
else if ((0, fs_1.existsSync)((0, path_1.join)(railsDir, entry, 'SKILL.md'))) {
|
|
476
493
|
agents++;
|
|
494
|
+
}
|
|
477
495
|
}
|
|
478
496
|
}
|
|
479
497
|
// Top-level skill dirs.
|
|
@@ -490,6 +508,14 @@ function computeSummary(projectPath, tier, provider = 'claude') {
|
|
|
490
508
|
specrailsCommands++;
|
|
491
509
|
}
|
|
492
510
|
}
|
|
511
|
+
if (provider === 'kimi') {
|
|
512
|
+
const personasDir = (0, path_1.join)(projectPath, '.kimi-code', 'personas');
|
|
513
|
+
if ((0, fs_1.existsSync)(personasDir)) {
|
|
514
|
+
personas = (0, fs_1.readdirSync)(personasDir)
|
|
515
|
+
.filter((entry) => entry.endsWith('.md'))
|
|
516
|
+
.length;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
493
519
|
}
|
|
494
520
|
else {
|
|
495
521
|
// Claude / Gemini layout: agents at `<dir>/agents/sr-*.md`, slash commands
|
|
@@ -510,10 +536,18 @@ function computeSummary(projectPath, tier, provider = 'claude') {
|
|
|
510
536
|
}
|
|
511
537
|
}
|
|
512
538
|
const commandsDirSpecrails = (0, path_1.join)(projectPath, dir, 'commands', 'specrails');
|
|
539
|
+
const commandsDirLegacySr = (0, path_1.join)(projectPath, dir, 'commands', 'sr');
|
|
513
540
|
const commandsDirOpsx = (0, path_1.join)(projectPath, dir, 'commands', 'opsx');
|
|
514
541
|
if ((0, fs_1.existsSync)(commandsDirSpecrails)) {
|
|
515
542
|
specrailsCommands = (0, fs_1.readdirSync)(commandsDirSpecrails).filter((f) => f.endsWith(commandExt)).length;
|
|
516
543
|
}
|
|
544
|
+
if (specrailsCommands === 0 && (0, fs_1.existsSync)(commandsDirLegacySr)) {
|
|
545
|
+
// Core <=4.1 used commands/sr. Count it only when the canonical
|
|
546
|
+
// specrails tree has no commands so a transition install is never
|
|
547
|
+
// doubled but an empty pre-created directory cannot hide real legacy
|
|
548
|
+
// artefacts.
|
|
549
|
+
specrailsCommands = (0, fs_1.readdirSync)(commandsDirLegacySr).filter((f) => f.endsWith(commandExt)).length;
|
|
550
|
+
}
|
|
517
551
|
if ((0, fs_1.existsSync)(commandsDirOpsx)) {
|
|
518
552
|
opsxCommands = (0, fs_1.readdirSync)(commandsDirOpsx).filter((f) => f.endsWith(commandExt)).length;
|
|
519
553
|
}
|
|
@@ -524,6 +558,35 @@ function computeSummary(projectPath, tier, provider = 'claude') {
|
|
|
524
558
|
}
|
|
525
559
|
return { agents, specrailsCommands, opsxCommands, personas, legacySrRemoved: 0, tier, provider };
|
|
526
560
|
}
|
|
561
|
+
/**
|
|
562
|
+
* Resolve completion against the selected provider's real filesystem layout.
|
|
563
|
+
* A legacy `.claude` fallback remains intentional only for Codex/Gemini:
|
|
564
|
+
* older Core releases scaffolded Claude artefacts for those selections.
|
|
565
|
+
* Kimi never had such a released legacy Core target; accepting a mixed
|
|
566
|
+
* project's `.claude` tree would falsely report a missing `.kimi-code` setup
|
|
567
|
+
* as complete.
|
|
568
|
+
*/
|
|
569
|
+
function setupArtifactState(projectPath, tier, provider) {
|
|
570
|
+
const nativeSummary = computeSummary(projectPath, tier, provider);
|
|
571
|
+
const supportsLegacyClaudeFallback = provider === 'codex' || provider === 'gemini';
|
|
572
|
+
const legacySummary = supportsLegacyClaudeFallback
|
|
573
|
+
? computeSummary(projectPath, tier, 'claude')
|
|
574
|
+
: nativeSummary;
|
|
575
|
+
const nativeHasCommands = nativeSummary.specrailsCommands + nativeSummary.opsxCommands > 0;
|
|
576
|
+
const legacyHasCommands = legacySummary.specrailsCommands + legacySummary.opsxCommands > 0;
|
|
577
|
+
const nativeComplete = nativeSummary.agents > 0 && nativeHasCommands;
|
|
578
|
+
const legacyComplete = legacySummary.agents > 0 && legacyHasCommands;
|
|
579
|
+
const selected = nativeComplete || !legacyComplete ? nativeSummary : legacySummary;
|
|
580
|
+
return {
|
|
581
|
+
// Preserve the actual selected provider for UI labels even when the
|
|
582
|
+
// artefacts came from the legacy Claude compatibility tree.
|
|
583
|
+
summary: { ...selected, provider },
|
|
584
|
+
hasAgents: nativeSummary.agents > 0 || legacySummary.agents > 0,
|
|
585
|
+
hasCommands: nativeHasCommands || legacyHasCommands,
|
|
586
|
+
hasPersonas: nativeSummary.personas > 0 || legacySummary.personas > 0,
|
|
587
|
+
complete: nativeComplete || legacyComplete,
|
|
588
|
+
};
|
|
589
|
+
}
|
|
527
590
|
/**
|
|
528
591
|
* Deletes the deprecated `.claude/commands/sr/` directory (if present) and returns
|
|
529
592
|
* the number of `.md` files that were removed. Safe to call even if the directory
|
|
@@ -934,16 +997,22 @@ class SetupManager {
|
|
|
934
997
|
this._projectNames.set(projectId, projectName);
|
|
935
998
|
this._projectTiers.set(projectId, 'full');
|
|
936
999
|
this._initCheckpoints(projectId);
|
|
1000
|
+
// Resolve the relocated artifact workspace before touching any provider
|
|
1001
|
+
// directories. The imported source repo must remain pristine.
|
|
1002
|
+
const enrichSlug = (0, artifact_registry_1.resolveArtifacts)(projectPath).entry?.slug;
|
|
1003
|
+
if (enrichSlug)
|
|
1004
|
+
this._projectSlugs.set(projectId, enrichSlug);
|
|
1005
|
+
const enrichRoot = this._artifactRoot(projectId, projectPath);
|
|
937
1006
|
// Pre-create the directory structure that /specrails:enrich will write to.
|
|
938
1007
|
// Claude Code's Write tool does not create parent directories automatically —
|
|
939
1008
|
// if a target directory doesn't exist the write fails and Claude reports a
|
|
940
1009
|
// misleading "write permissions aren't enabled" error. Creating the dirs
|
|
941
1010
|
// here ensures enrich runs transparently without any user intervention.
|
|
942
1011
|
try {
|
|
943
|
-
(0, fs_1.mkdirSync)((0, path_1.join)(
|
|
944
|
-
(0, fs_1.mkdirSync)((0, path_1.join)(
|
|
945
|
-
(0, fs_1.mkdirSync)((0, path_1.join)(
|
|
946
|
-
(0, fs_1.mkdirSync)((0, path_1.join)(
|
|
1012
|
+
(0, fs_1.mkdirSync)((0, path_1.join)(enrichRoot, SPECRAILS_DIR, 'agents', 'personas'), { recursive: true });
|
|
1013
|
+
(0, fs_1.mkdirSync)((0, path_1.join)(enrichRoot, SPECRAILS_DIR, 'commands', 'sr'), { recursive: true });
|
|
1014
|
+
(0, fs_1.mkdirSync)((0, path_1.join)(enrichRoot, SPECRAILS_DIR, 'commands', 'specrails'), { recursive: true });
|
|
1015
|
+
(0, fs_1.mkdirSync)((0, path_1.join)(enrichRoot, SPECRAILS_DIR, 'rules'), { recursive: true });
|
|
947
1016
|
}
|
|
948
1017
|
catch (err) {
|
|
949
1018
|
console.warn(`[SetupManager] Failed to pre-create enrich directories: ${err}`);
|
|
@@ -952,7 +1021,6 @@ class SetupManager {
|
|
|
952
1021
|
// The slug was allocated at addProject and mirrored into the shared registry
|
|
953
1022
|
// before/at install time, so resolve it from there (legacy full-flow path —
|
|
954
1023
|
// not exercised by the app's quick flow).
|
|
955
|
-
const enrichSlug = (0, artifact_registry_1.resolveArtifacts)(projectPath).entry?.slug;
|
|
956
1024
|
const configPath = (0, install_config_path_1.installConfigPath)({ slug: enrichSlug, path: projectPath });
|
|
957
1025
|
const hasConfig = (0, fs_1.existsSync)(configPath);
|
|
958
1026
|
const enrichCmd = hasConfig ? '/specrails:enrich --from-config' : '/specrails:enrich';
|
|
@@ -1034,8 +1102,10 @@ class SetupManager {
|
|
|
1034
1102
|
if (!db)
|
|
1035
1103
|
return;
|
|
1036
1104
|
try {
|
|
1105
|
+
const finishedAt = new Date().toISOString();
|
|
1037
1106
|
const { result, estimated } = (0, result_event_1.finaliseInvocationResult)(adapter, events, {
|
|
1038
1107
|
fallbackModel: adapter.defaultModel(),
|
|
1108
|
+
durationMs: Math.max(0, Date.parse(finishedAt) - Date.parse(startedAtIso)),
|
|
1039
1109
|
});
|
|
1040
1110
|
(0, ai_invocations_1.recordInvocation)(db, {
|
|
1041
1111
|
id: (0, crypto_1.randomUUID)(),
|
|
@@ -1045,7 +1115,7 @@ class SetupManager {
|
|
|
1045
1115
|
surface_ref_id: projectId,
|
|
1046
1116
|
status,
|
|
1047
1117
|
started_at: startedAtIso,
|
|
1048
|
-
finished_at:
|
|
1118
|
+
finished_at: finishedAt,
|
|
1049
1119
|
total_cost_usd_estimated: estimated,
|
|
1050
1120
|
...result,
|
|
1051
1121
|
});
|
|
@@ -1068,37 +1138,64 @@ class SetupManager {
|
|
|
1068
1138
|
console.warn('[SetupManager] No AI CLI detected. Falling back to claude.');
|
|
1069
1139
|
}
|
|
1070
1140
|
const adapter = (0, providers_1.getAdapter)(resolvedProvider ?? 'claude');
|
|
1141
|
+
const execution = (0, workspace_resolution_1.resolveProjectExecution)({
|
|
1142
|
+
slug: this._projectSlugs.get(projectId),
|
|
1143
|
+
path: projectPath,
|
|
1144
|
+
});
|
|
1071
1145
|
// Provider-aware prompt resolution:
|
|
1072
1146
|
// - claude: pass the slash command unresolved so the CLI looks up
|
|
1073
1147
|
// `.claude/commands/specrails/enrich.md` natively. Honours the
|
|
1074
1148
|
// skills-resolution priority over CLAUDE.md.
|
|
1075
1149
|
// - codex: no slash-command support; fold the enrich.md content into
|
|
1076
1150
|
// the prompt with the PROJECT context header so codex knows the cwd.
|
|
1077
|
-
let effectivePrompt
|
|
1078
|
-
|
|
1151
|
+
let effectivePrompt;
|
|
1152
|
+
try {
|
|
1153
|
+
effectivePrompt = adapter.formatCoreCommand?.(opts.prompt, execution.cwd) ?? opts.prompt;
|
|
1154
|
+
}
|
|
1155
|
+
catch (error) {
|
|
1156
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1157
|
+
console.error(`[SetupManager] provider command resolution failed for ${projectId}: ${message}`);
|
|
1158
|
+
this._stopFilesystemPoll(projectId);
|
|
1159
|
+
this._broadcast({
|
|
1160
|
+
type: 'setup_error',
|
|
1161
|
+
projectId,
|
|
1162
|
+
error: message,
|
|
1163
|
+
});
|
|
1164
|
+
return;
|
|
1165
|
+
}
|
|
1166
|
+
if (adapter.id === 'codex' &&
|
|
1167
|
+
!adapter.capabilities.systemPromptArg &&
|
|
1079
1168
|
(opts.prompt === '/specrails:enrich' || opts.prompt === '/specrails:enrich --from-config')) {
|
|
1080
|
-
const enrichContent = readEnrichMdContent(
|
|
1169
|
+
const enrichContent = readEnrichMdContent(execution.cwd);
|
|
1081
1170
|
if (enrichContent) {
|
|
1082
1171
|
const projectName = this._projectNames.get(projectId);
|
|
1172
|
+
const cwdContext = execution.relocated
|
|
1173
|
+
? `CWD: ${execution.cwd}\nREPOSITORY: ${execution.repoDir}`
|
|
1174
|
+
: `CWD: ${projectPath}`;
|
|
1083
1175
|
effectivePrompt = projectName
|
|
1084
|
-
? `PROJECT: ${projectName}\
|
|
1176
|
+
? `PROJECT: ${projectName}\n${cwdContext}\n\n---\n\n${enrichContent}`
|
|
1085
1177
|
: enrichContent;
|
|
1086
1178
|
}
|
|
1087
1179
|
else {
|
|
1088
1180
|
console.warn(`[SetupManager] Could not read enrich.md or setup.md — falling back to literal prompt`);
|
|
1089
1181
|
}
|
|
1090
1182
|
}
|
|
1091
|
-
const
|
|
1183
|
+
const repoAccessArgs = execution.relocated
|
|
1184
|
+
? (0, runtime_1.buildProviderRepoAccessArgs)(adapter, [execution.repoDir])
|
|
1185
|
+
: [];
|
|
1186
|
+
const spawnOpts = {
|
|
1092
1187
|
prompt: effectivePrompt,
|
|
1093
1188
|
model: adapter.defaultModel(),
|
|
1094
1189
|
sessionId: opts.sessionId,
|
|
1095
|
-
|
|
1190
|
+
extraArgs: repoAccessArgs,
|
|
1191
|
+
};
|
|
1192
|
+
const args = adapter.buildArgs(opts.action, spawnOpts);
|
|
1096
1193
|
// No OTEL env injection here — SetupManager spawns drive the initial project
|
|
1097
1194
|
// setup wizard, not repeatable pipeline jobs. Telemetry is scoped to
|
|
1098
1195
|
// QueueManager pipeline runs only.
|
|
1099
1196
|
const child = (0, cli_prompt_1.spawnAiCli)(adapter.binary, args, {
|
|
1100
|
-
cwd:
|
|
1101
|
-
env: process.env,
|
|
1197
|
+
cwd: execution.cwd,
|
|
1198
|
+
env: (0, runtime_1.buildProviderEnv)(adapter, spawnOpts, { ...process.env, ...execution.env }),
|
|
1102
1199
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
1103
1200
|
});
|
|
1104
1201
|
this._setupProcesses.set(projectId, child);
|
|
@@ -1122,65 +1219,71 @@ class SetupManager {
|
|
|
1122
1219
|
// Start periodic filesystem polling for checkpoint detection
|
|
1123
1220
|
this._startFilesystemPoll(projectId, projectPath);
|
|
1124
1221
|
let capturedSessionId = null;
|
|
1222
|
+
let providerError = null;
|
|
1125
1223
|
const stdoutReader = (0, readline_1.createInterface)({ input: child.stdout, crlfDelay: Infinity });
|
|
1126
1224
|
const stderrReader = (0, readline_1.createInterface)({ input: child.stderr, crlfDelay: Infinity });
|
|
1127
1225
|
stdoutReader.on('line', (line) => {
|
|
1128
|
-
const
|
|
1129
|
-
if (
|
|
1130
|
-
adapterEvents.push(ev);
|
|
1131
|
-
if (!ev) {
|
|
1226
|
+
const parsedEvents = (0, runtime_1.parseStreamEvents)(adapter, line);
|
|
1227
|
+
if (parsedEvents.length === 0) {
|
|
1132
1228
|
// Non-parseable line — emit as raw log.
|
|
1133
1229
|
if (line)
|
|
1134
1230
|
this._broadcast({ type: 'setup_log', projectId, line, stream: 'stdout' });
|
|
1135
1231
|
return;
|
|
1136
1232
|
}
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1233
|
+
for (const ev of parsedEvents) {
|
|
1234
|
+
adapterEvents.push(ev);
|
|
1235
|
+
switch (ev.kind) {
|
|
1236
|
+
case 'session-started': {
|
|
1237
|
+
if (!capturedSessionId) {
|
|
1238
|
+
capturedSessionId = ev.sessionId;
|
|
1239
|
+
this._onSessionCaptured?.(projectId, ev.sessionId);
|
|
1240
|
+
}
|
|
1241
|
+
break;
|
|
1142
1242
|
}
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1243
|
+
case 'text-delta': {
|
|
1244
|
+
// Run checkpoint detection over the assistant text and surface it
|
|
1245
|
+
// both to the collapsible log viewer and the wizard chat panel.
|
|
1246
|
+
this._broadcast({ type: 'setup_log', projectId, line: ev.text, stream: 'stdout' });
|
|
1247
|
+
this._broadcast({ type: 'setup_chat', projectId, text: ev.text, role: 'assistant' });
|
|
1248
|
+
const hits = detectCheckpointFromText(ev.text);
|
|
1249
|
+
for (const hit of hits) {
|
|
1250
|
+
this._advanceCheckpoint(projectId, hit.key, hit.detail);
|
|
1251
|
+
}
|
|
1252
|
+
// Also sync filesystem (cheap mtime/exists checks, see helper).
|
|
1253
|
+
this._syncFilesystemCheckpoints(projectId, projectPath);
|
|
1254
|
+
break;
|
|
1153
1255
|
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
for (const hit of hits) {
|
|
1166
|
-
this._advanceCheckpoint(projectId, hit.key, hit.detail);
|
|
1256
|
+
case 'tool-use': {
|
|
1257
|
+
this._broadcast({ type: 'setup_log', projectId, line: `[tool] ${ev.name}`, stream: 'stdout' });
|
|
1258
|
+
// Tool inputs commonly mention the paths being written — feed the
|
|
1259
|
+
// input preview into the checkpoint detector so writes to
|
|
1260
|
+
// .claude/agents/sr-*.md or .codex/skills/sr-*/SKILL.md advance
|
|
1261
|
+
// the checkpoint state immediately.
|
|
1262
|
+
const hits = detectCheckpointFromText(ev.inputPreview);
|
|
1263
|
+
for (const hit of hits) {
|
|
1264
|
+
this._advanceCheckpoint(projectId, hit.key, hit.detail);
|
|
1265
|
+
}
|
|
1266
|
+
break;
|
|
1167
1267
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1268
|
+
case 'result': {
|
|
1269
|
+
// Claude's `result` event also carries session_id; use it as a
|
|
1270
|
+
// backstop if `session-started` wasn't observed earlier.
|
|
1271
|
+
const sid = ev.payload.session_id;
|
|
1272
|
+
if (sid && !capturedSessionId) {
|
|
1273
|
+
capturedSessionId = sid;
|
|
1274
|
+
this._onSessionCaptured?.(projectId, sid);
|
|
1275
|
+
}
|
|
1276
|
+
break;
|
|
1177
1277
|
}
|
|
1178
|
-
|
|
1278
|
+
case 'error':
|
|
1279
|
+
providerError = ev.message;
|
|
1280
|
+
this._broadcast({ type: 'setup_log', projectId, line: ev.message, stream: 'stderr' });
|
|
1281
|
+
break;
|
|
1282
|
+
case 'other':
|
|
1283
|
+
// Other event types (system progress markers) — already broadcast
|
|
1284
|
+
// implicitly through the line itself if useful. Skip.
|
|
1285
|
+
break;
|
|
1179
1286
|
}
|
|
1180
|
-
case 'other':
|
|
1181
|
-
// Other event types (system progress markers) — already broadcast
|
|
1182
|
-
// implicitly through the line itself if useful. Skip.
|
|
1183
|
-
break;
|
|
1184
1287
|
}
|
|
1185
1288
|
});
|
|
1186
1289
|
stderrReader.on('line', (line) => {
|
|
@@ -1198,25 +1301,29 @@ class SetupManager {
|
|
|
1198
1301
|
}
|
|
1199
1302
|
// Record the completed setup turn's spend (success on clean exit, failed
|
|
1200
1303
|
// otherwise). LOW-2.
|
|
1201
|
-
|
|
1304
|
+
const providerReportedFailure = providerError !== null;
|
|
1305
|
+
this._recordSetupInvocation(projectId, adapter, adapterEvents, code === 0 && !providerReportedFailure ? 'success' : 'failed', turnStartedAt);
|
|
1202
1306
|
// Final filesystem sync
|
|
1203
1307
|
this._syncFilesystemCheckpoints(projectId, projectPath);
|
|
1204
|
-
if (code === 0) {
|
|
1308
|
+
if (code === 0 && !providerReportedFailure) {
|
|
1205
1309
|
// Sync filesystem checkpoints
|
|
1206
1310
|
this._syncFilesystemCheckpoints(projectId, projectPath);
|
|
1207
1311
|
// Relocated installs write artifacts to the workspace, not the repo —
|
|
1208
1312
|
// resolve the has-agents/has-commands gate + summary against it.
|
|
1209
1313
|
const artifactRoot = this._artifactRoot(projectId, projectPath);
|
|
1210
|
-
// Check
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
const
|
|
1214
|
-
|
|
1215
|
-
const
|
|
1314
|
+
// Check completion against the selected provider's native artefacts.
|
|
1315
|
+
// In particular, Kimi rail roles are direct-child SKILL.md files under
|
|
1316
|
+
// `.kimi-code/skills/`, not Markdown agents/commands in `.claude`.
|
|
1317
|
+
const tier = this._projectTiers.get(projectId) ?? 'full';
|
|
1318
|
+
const provider = this._projectProviders.get(projectId) ?? 'claude';
|
|
1319
|
+
const artifactState = setupArtifactState(artifactRoot, tier, provider);
|
|
1320
|
+
const isComplete = artifactState.complete;
|
|
1216
1321
|
if (isComplete) {
|
|
1217
1322
|
const legacySrRemoved = sweepLegacySrCommands(artifactRoot);
|
|
1218
|
-
const
|
|
1219
|
-
|
|
1323
|
+
const summary = {
|
|
1324
|
+
...artifactState.summary,
|
|
1325
|
+
legacySrRemoved,
|
|
1326
|
+
};
|
|
1220
1327
|
this._onSetupDone?.(projectId);
|
|
1221
1328
|
this._broadcast({
|
|
1222
1329
|
type: 'setup_complete',
|
|
@@ -1240,7 +1347,7 @@ class SetupManager {
|
|
|
1240
1347
|
this._broadcast({
|
|
1241
1348
|
type: 'setup_error',
|
|
1242
1349
|
projectId,
|
|
1243
|
-
error: `${adapter.binary} enrich exited with code ${code ?? 'unknown'}`,
|
|
1350
|
+
error: providerError ?? `${adapter.binary} enrich exited with code ${code ?? 'unknown'}`,
|
|
1244
1351
|
});
|
|
1245
1352
|
}
|
|
1246
1353
|
});
|
|
@@ -1306,8 +1413,6 @@ class SetupManager {
|
|
|
1306
1413
|
* known or the project isn't relocated. */
|
|
1307
1414
|
_artifactRoot(projectId, projectPath) {
|
|
1308
1415
|
const slug = this._projectSlugs.get(projectId);
|
|
1309
|
-
if (!slug)
|
|
1310
|
-
return projectPath;
|
|
1311
1416
|
try {
|
|
1312
1417
|
return (0, workspace_resolution_1.resolveProjectExecution)({ slug, path: projectPath }).cwd;
|
|
1313
1418
|
}
|
|
@@ -1319,7 +1424,7 @@ class SetupManager {
|
|
|
1319
1424
|
const statuses = this._checkpoints.get(projectId);
|
|
1320
1425
|
if (!statuses)
|
|
1321
1426
|
return;
|
|
1322
|
-
const fsChecks = checkFilesystem(this._artifactRoot(projectId, projectPath));
|
|
1427
|
+
const fsChecks = checkFilesystem(this._artifactRoot(projectId, projectPath), this._projectProviders.get(projectId) ?? 'claude');
|
|
1323
1428
|
for (const [key, exists] of Object.entries(fsChecks)) {
|
|
1324
1429
|
if (!exists)
|
|
1325
1430
|
continue;
|
|
@@ -1426,7 +1531,23 @@ class SetupManager {
|
|
|
1426
1531
|
catch {
|
|
1427
1532
|
// Missing install-config — stay on claude default.
|
|
1428
1533
|
}
|
|
1429
|
-
|
|
1534
|
+
// Relocated installs intentionally keep the imported repository pristine:
|
|
1535
|
+
// provider artefacts live in the populated workspace. The immediate install
|
|
1536
|
+
// completion path already uses `_artifactRoot`; a later GET after reopening
|
|
1537
|
+
// must resolve the same root or Kimi (and every relocated provider) is
|
|
1538
|
+
// incorrectly summarised as 0 agents / 0 commands.
|
|
1539
|
+
let artifactRoot = project.path;
|
|
1540
|
+
try {
|
|
1541
|
+
artifactRoot = (0, workspace_resolution_1.resolveProjectExecution)({
|
|
1542
|
+
slug: project.slug,
|
|
1543
|
+
path: project.path,
|
|
1544
|
+
}).cwd;
|
|
1545
|
+
}
|
|
1546
|
+
catch {
|
|
1547
|
+
// Registry/workspace resolution is fail-open by contract. Legacy projects
|
|
1548
|
+
// continue to read their in-repo artefacts.
|
|
1549
|
+
}
|
|
1550
|
+
return computeSummary(artifactRoot, tier, provider);
|
|
1430
1551
|
}
|
|
1431
1552
|
}
|
|
1432
1553
|
exports.SetupManager = SetupManager;
|
|
@@ -42,7 +42,7 @@ function runVersionSpawn(cmd, args, timeoutMs = 5_000) {
|
|
|
42
42
|
// budget; the `where`/`which` LOCATE probe stays fast (5s) since it's a builtin.
|
|
43
43
|
const VERSION_PROBE_TIMEOUT_MS = process.platform === 'win32' ? 20_000 : 8_000;
|
|
44
44
|
exports.MIN_VERSIONS = {
|
|
45
|
-
node: '
|
|
45
|
+
node: '20.19.0',
|
|
46
46
|
npm: '9.0.0',
|
|
47
47
|
git: '2.20.0',
|
|
48
48
|
uv: '0.1.0',
|
|
@@ -518,6 +518,8 @@ function providerInstallUrl(id) {
|
|
|
518
518
|
return 'https://developers.openai.com/codex';
|
|
519
519
|
case 'gemini':
|
|
520
520
|
return 'https://github.com/google-gemini/gemini-cli';
|
|
521
|
+
case 'kimi':
|
|
522
|
+
return 'https://www.kimi.com/code/docs/en/';
|
|
521
523
|
default:
|
|
522
524
|
return 'https://github.com';
|
|
523
525
|
}
|
|
@@ -534,6 +536,10 @@ function providerInstallHint(id, platform) {
|
|
|
534
536
|
: 'Install Codex CLI from https://developers.openai.com/codex (or `pipx install codex-cli`), authenticate with `codex login`, then restart Specrails.';
|
|
535
537
|
case 'gemini':
|
|
536
538
|
return 'Install Gemini CLI via `npm i -g @google/gemini-cli` (or see https://github.com/google-gemini/gemini-cli), set GEMINI_API_KEY, then restart Specrails.';
|
|
539
|
+
case 'kimi':
|
|
540
|
+
return platform === 'win32'
|
|
541
|
+
? 'Install Kimi Code from https://www.kimi.com/code/docs/en/, run `kimi login`, then restart Specrails so Windows refreshes PATH.'
|
|
542
|
+
: 'Install Kimi Code from https://www.kimi.com/code/docs/en/, run `kimi login`, then restart Specrails.';
|
|
537
543
|
default:
|
|
538
544
|
return `Install the ${id} CLI and restart Specrails.`;
|
|
539
545
|
}
|