specrails-desktop 2.8.0 → 2.9.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 +23 -19
- package/client/dist/assets/{ActivityFeedPage-LKqd18-G.js → ActivityFeedPage-DNqnf1fZ.js} +1 -1
- package/client/dist/assets/{AgentsPage-Cb-b-6Ot.js → AgentsPage-vmNIEbGM.js} +1 -1
- package/client/dist/assets/{AnalyticsPage-HVxQQ1wy.js → AnalyticsPage-CdfN0ofZ.js} +1 -1
- package/client/dist/assets/{BarChart-BOyHB0dw.js → BarChart-CIkopHjl.js} +1 -1
- package/client/dist/assets/{CodePage-DnOnwKGB.js → CodePage-DDRNU5FN.js} +1 -1
- package/client/dist/assets/{DesktopAnalyticsPage-D2auU39x.js → DesktopAnalyticsPage-Cl3sKKSG.js} +1 -1
- package/client/dist/assets/{DocsDialog-CTuDX3GK.js → DocsDialog-BGrBOfUr.js} +2 -2
- package/client/dist/assets/{DocsPage-DRyMmu0Z.js → DocsPage-CY-2SSzw.js} +2 -2
- package/client/dist/assets/{ExportDropdown-DO-GGiMh.js → ExportDropdown-BRHcvP0r.js} +1 -1
- package/client/dist/assets/{IntegrationsPage-BhbO4jFT.js → IntegrationsPage-nKdLB4Ub.js} +1 -1
- package/client/dist/assets/{JobDetailPage-DJooEg1s.js → JobDetailPage-Bf0A6WWQ.js} +1 -1
- package/client/dist/assets/{JobsPage-BbaC-YOg.js → JobsPage-Vg4nXPdL.js} +1 -1
- package/client/dist/assets/{dist-js-CiIVMsx3.js → dist-js-0i_klubI.js} +1 -1
- package/client/dist/assets/{dist-js-Xc2lRKp2.js → dist-js-CUs5GjwA.js} +1 -1
- package/client/dist/assets/{index-DK214dak.js → index-BXoHFtfG.js} +8 -8
- package/client/dist/assets/index-D6BaYRRU.css +2 -0
- package/client/dist/assets/{integrations-2C7MkGT0.js → integrations-7YyTBuU9.js} +1 -1
- package/client/dist/assets/{integrations-CX4p_bij.js → integrations-B9CEpNF0.js} +1 -1
- package/client/dist/assets/{integrations-C2jQtv-s.js → integrations-BlvAdewo.js} +1 -1
- package/client/dist/assets/{integrations-eQPHAYsE.js → integrations-Bw8UM9Xd.js} +1 -1
- package/client/dist/assets/{integrations-BDC670cg.js → integrations-C5SxNKnG.js} +1 -1
- package/client/dist/assets/{integrations-BqUmRUef.js → integrations-CJQKMmdW.js} +1 -1
- package/client/dist/assets/{integrations-CB98NeH5.js → integrations-DWz1eU_K.js} +1 -1
- package/client/dist/assets/{integrations-_SuVeQIG.js → integrations-DiPR8Fzp.js} +1 -1
- package/client/dist/assets/{lib-Bo5s6xpe.js → lib-D6M_MvoC.js} +1 -1
- package/client/dist/assets/setup-B6egeeTM.js +1 -0
- package/client/dist/assets/setup-BHroXlke.js +1 -0
- package/client/dist/assets/setup-BIXsWUp1.js +1 -0
- package/client/dist/assets/setup-BJRdg1iE.js +1 -0
- package/client/dist/assets/setup-C0rVGnCy.js +1 -0
- package/client/dist/assets/setup-Cpu17hJv.js +1 -0
- package/client/dist/assets/setup-D-1r0uSx.js +1 -0
- package/client/dist/assets/setup-Dn2-veYO.js +1 -0
- package/client/dist/assets/{useProjectCache-DVNypkmR.js → useProjectCache-BeyBSNpD.js} +1 -1
- package/client/dist/index.html +4 -4
- package/docs/README.md +5 -2
- package/docs/agy-cli-provider-study.md +78 -0
- package/docs/cli.md +23 -4
- package/docs/codex.md +116 -58
- package/docs/creating-specs.md +19 -5
- package/docs/customizing.md +27 -6
- package/docs/gemini.md +225 -73
- package/docs/getting-started.md +18 -9
- package/docs/guide/de/agents/1-meet-the-agents.md +38 -0
- package/docs/guide/de/agents/2-profiles-and-the-balanced-default.md +45 -0
- package/docs/guide/de/agents/3-customizing-models-per-agent.md +60 -0
- package/docs/guide/de/agents/4-custom-agents-catalog.md +43 -0
- package/docs/guide/de/getting-started/1-what-is-specrails.md +49 -0
- package/docs/guide/de/getting-started/2-installing-and-first-run.md +42 -0
- package/docs/guide/de/getting-started/3-adding-your-first-project.md +58 -0
- package/docs/guide/de/getting-started/4-the-dashboard-tour.md +53 -0
- package/docs/guide/de/insights/1-analytics-and-cost-tracking.md +78 -0
- package/docs/guide/de/insights/2-the-integrated-terminal.md +46 -0
- package/docs/guide/de/insights/3-code-explorer.md +50 -0
- package/docs/guide/de/integrations/1-ai-providers.md +64 -0
- package/docs/guide/de/integrations/2-plugins.md +44 -0
- package/docs/guide/de/integrations/3-jira-integration.md +71 -0
- package/docs/guide/de/integrations/4-mobile-companion.md +38 -0
- package/docs/guide/de/pipeline/1-rails-and-jobs.md +94 -0
- package/docs/guide/de/pipeline/2-the-job-detail-view.md +90 -0
- package/docs/guide/de/pipeline/3-batch-implement-and-multi-feature.md +78 -0
- package/docs/guide/de/pipeline/4-picking-an-engine-per-rail.md +60 -0
- package/docs/guide/de/settings/1-themes.md +37 -0
- package/docs/guide/de/settings/2-language.md +39 -0
- package/docs/guide/de/settings/3-pipeline-telemetry-and-diagnostics.md +46 -0
- package/docs/guide/de/settings/4-where-your-data-lives.md +48 -0
- package/docs/guide/de/specs/1-specs-and-the-backlog.md +52 -0
- package/docs/guide/de/specs/2-add-spec-quick-mode.md +45 -0
- package/docs/guide/de/specs/3-add-spec-explore-mode.md +68 -0
- package/docs/guide/de/specs/4-drafts-and-contract-layer.md +81 -0
- package/docs/guide/en/agents/1-meet-the-agents.md +38 -0
- package/docs/guide/en/agents/2-profiles-and-the-balanced-default.md +45 -0
- package/docs/guide/en/agents/3-customizing-models-per-agent.md +60 -0
- package/docs/guide/en/agents/4-custom-agents-catalog.md +43 -0
- package/docs/guide/en/getting-started/1-what-is-specrails.md +49 -0
- package/docs/guide/en/getting-started/2-installing-and-first-run.md +42 -0
- package/docs/guide/en/getting-started/3-adding-your-first-project.md +58 -0
- package/docs/guide/en/getting-started/4-the-dashboard-tour.md +53 -0
- package/docs/guide/en/insights/1-analytics-and-cost-tracking.md +78 -0
- package/docs/guide/en/insights/2-the-integrated-terminal.md +46 -0
- package/docs/guide/en/insights/3-code-explorer.md +50 -0
- package/docs/guide/en/integrations/1-ai-providers.md +64 -0
- package/docs/guide/en/integrations/2-plugins.md +44 -0
- package/docs/guide/en/integrations/3-jira-integration.md +71 -0
- package/docs/guide/en/integrations/4-mobile-companion.md +38 -0
- package/docs/guide/en/pipeline/1-rails-and-jobs.md +94 -0
- package/docs/guide/en/pipeline/2-the-job-detail-view.md +90 -0
- package/docs/guide/en/pipeline/3-batch-implement-and-multi-feature.md +78 -0
- package/docs/guide/en/pipeline/4-picking-an-engine-per-rail.md +60 -0
- package/docs/guide/en/settings/1-themes.md +37 -0
- package/docs/guide/en/settings/2-language.md +39 -0
- package/docs/guide/en/settings/3-pipeline-telemetry-and-diagnostics.md +46 -0
- package/docs/guide/en/settings/4-where-your-data-lives.md +48 -0
- package/docs/guide/en/specs/1-specs-and-the-backlog.md +52 -0
- package/docs/guide/en/specs/2-add-spec-quick-mode.md +45 -0
- package/docs/guide/en/specs/3-add-spec-explore-mode.md +68 -0
- package/docs/guide/en/specs/4-drafts-and-contract-layer.md +81 -0
- package/docs/guide/es/agents/1-meet-the-agents.md +38 -0
- package/docs/guide/es/agents/2-profiles-and-the-balanced-default.md +45 -0
- package/docs/guide/es/agents/3-customizing-models-per-agent.md +60 -0
- package/docs/guide/es/agents/4-custom-agents-catalog.md +43 -0
- package/docs/guide/es/getting-started/1-what-is-specrails.md +49 -0
- package/docs/guide/es/getting-started/2-installing-and-first-run.md +42 -0
- package/docs/guide/es/getting-started/3-adding-your-first-project.md +58 -0
- package/docs/guide/es/getting-started/4-the-dashboard-tour.md +53 -0
- package/docs/guide/es/insights/1-analytics-and-cost-tracking.md +78 -0
- package/docs/guide/es/insights/2-the-integrated-terminal.md +46 -0
- package/docs/guide/es/insights/3-code-explorer.md +50 -0
- package/docs/guide/es/integrations/1-ai-providers.md +64 -0
- package/docs/guide/es/integrations/2-plugins.md +44 -0
- package/docs/guide/es/integrations/3-jira-integration.md +71 -0
- package/docs/guide/es/integrations/4-mobile-companion.md +38 -0
- package/docs/guide/es/pipeline/1-rails-and-jobs.md +94 -0
- package/docs/guide/es/pipeline/2-the-job-detail-view.md +90 -0
- package/docs/guide/es/pipeline/3-batch-implement-and-multi-feature.md +78 -0
- package/docs/guide/es/pipeline/4-picking-an-engine-per-rail.md +60 -0
- package/docs/guide/es/settings/1-themes.md +37 -0
- package/docs/guide/es/settings/2-language.md +39 -0
- package/docs/guide/es/settings/3-pipeline-telemetry-and-diagnostics.md +46 -0
- package/docs/guide/es/settings/4-where-your-data-lives.md +48 -0
- package/docs/guide/es/specs/1-specs-and-the-backlog.md +52 -0
- package/docs/guide/es/specs/2-add-spec-quick-mode.md +45 -0
- package/docs/guide/es/specs/3-add-spec-explore-mode.md +68 -0
- package/docs/guide/es/specs/4-drafts-and-contract-layer.md +81 -0
- package/docs/guide/fr/agents/1-meet-the-agents.md +38 -0
- package/docs/guide/fr/agents/2-profiles-and-the-balanced-default.md +45 -0
- package/docs/guide/fr/agents/3-customizing-models-per-agent.md +60 -0
- package/docs/guide/fr/agents/4-custom-agents-catalog.md +43 -0
- package/docs/guide/fr/getting-started/1-what-is-specrails.md +49 -0
- package/docs/guide/fr/getting-started/2-installing-and-first-run.md +42 -0
- package/docs/guide/fr/getting-started/3-adding-your-first-project.md +58 -0
- package/docs/guide/fr/getting-started/4-the-dashboard-tour.md +53 -0
- package/docs/guide/fr/insights/1-analytics-and-cost-tracking.md +78 -0
- package/docs/guide/fr/insights/2-the-integrated-terminal.md +46 -0
- package/docs/guide/fr/insights/3-code-explorer.md +50 -0
- package/docs/guide/fr/integrations/1-ai-providers.md +64 -0
- package/docs/guide/fr/integrations/2-plugins.md +44 -0
- package/docs/guide/fr/integrations/3-jira-integration.md +71 -0
- package/docs/guide/fr/integrations/4-mobile-companion.md +38 -0
- package/docs/guide/fr/pipeline/1-rails-and-jobs.md +94 -0
- package/docs/guide/fr/pipeline/2-the-job-detail-view.md +90 -0
- package/docs/guide/fr/pipeline/3-batch-implement-and-multi-feature.md +78 -0
- package/docs/guide/fr/pipeline/4-picking-an-engine-per-rail.md +60 -0
- package/docs/guide/fr/settings/1-themes.md +37 -0
- package/docs/guide/fr/settings/2-language.md +39 -0
- package/docs/guide/fr/settings/3-pipeline-telemetry-and-diagnostics.md +46 -0
- package/docs/guide/fr/settings/4-where-your-data-lives.md +48 -0
- package/docs/guide/fr/specs/1-specs-and-the-backlog.md +52 -0
- package/docs/guide/fr/specs/2-add-spec-quick-mode.md +45 -0
- package/docs/guide/fr/specs/3-add-spec-explore-mode.md +68 -0
- package/docs/guide/fr/specs/4-drafts-and-contract-layer.md +81 -0
- package/docs/guide/it/agents/1-meet-the-agents.md +38 -0
- package/docs/guide/it/agents/2-profiles-and-the-balanced-default.md +45 -0
- package/docs/guide/it/agents/3-customizing-models-per-agent.md +60 -0
- package/docs/guide/it/agents/4-custom-agents-catalog.md +43 -0
- package/docs/guide/it/getting-started/1-what-is-specrails.md +49 -0
- package/docs/guide/it/getting-started/2-installing-and-first-run.md +42 -0
- package/docs/guide/it/getting-started/3-adding-your-first-project.md +58 -0
- package/docs/guide/it/getting-started/4-the-dashboard-tour.md +53 -0
- package/docs/guide/it/insights/1-analytics-and-cost-tracking.md +78 -0
- package/docs/guide/it/insights/2-the-integrated-terminal.md +46 -0
- package/docs/guide/it/insights/3-code-explorer.md +50 -0
- package/docs/guide/it/integrations/1-ai-providers.md +64 -0
- package/docs/guide/it/integrations/2-plugins.md +44 -0
- package/docs/guide/it/integrations/3-jira-integration.md +71 -0
- package/docs/guide/it/integrations/4-mobile-companion.md +38 -0
- package/docs/guide/it/pipeline/1-rails-and-jobs.md +94 -0
- package/docs/guide/it/pipeline/2-the-job-detail-view.md +90 -0
- package/docs/guide/it/pipeline/3-batch-implement-and-multi-feature.md +78 -0
- package/docs/guide/it/pipeline/4-picking-an-engine-per-rail.md +60 -0
- package/docs/guide/it/settings/1-themes.md +37 -0
- package/docs/guide/it/settings/2-language.md +39 -0
- package/docs/guide/it/settings/3-pipeline-telemetry-and-diagnostics.md +46 -0
- package/docs/guide/it/settings/4-where-your-data-lives.md +48 -0
- package/docs/guide/it/specs/1-specs-and-the-backlog.md +52 -0
- package/docs/guide/it/specs/2-add-spec-quick-mode.md +45 -0
- package/docs/guide/it/specs/3-add-spec-explore-mode.md +68 -0
- package/docs/guide/it/specs/4-drafts-and-contract-layer.md +81 -0
- package/docs/guide/ja/agents/1-meet-the-agents.md +38 -0
- package/docs/guide/ja/agents/2-profiles-and-the-balanced-default.md +45 -0
- package/docs/guide/ja/agents/3-customizing-models-per-agent.md +60 -0
- package/docs/guide/ja/agents/4-custom-agents-catalog.md +43 -0
- package/docs/guide/ja/getting-started/1-what-is-specrails.md +49 -0
- package/docs/guide/ja/getting-started/2-installing-and-first-run.md +42 -0
- package/docs/guide/ja/getting-started/3-adding-your-first-project.md +58 -0
- package/docs/guide/ja/getting-started/4-the-dashboard-tour.md +53 -0
- package/docs/guide/ja/insights/1-analytics-and-cost-tracking.md +78 -0
- package/docs/guide/ja/insights/2-the-integrated-terminal.md +46 -0
- package/docs/guide/ja/insights/3-code-explorer.md +50 -0
- package/docs/guide/ja/integrations/1-ai-providers.md +64 -0
- package/docs/guide/ja/integrations/2-plugins.md +44 -0
- package/docs/guide/ja/integrations/3-jira-integration.md +71 -0
- package/docs/guide/ja/integrations/4-mobile-companion.md +38 -0
- package/docs/guide/ja/pipeline/1-rails-and-jobs.md +94 -0
- package/docs/guide/ja/pipeline/2-the-job-detail-view.md +90 -0
- package/docs/guide/ja/pipeline/3-batch-implement-and-multi-feature.md +78 -0
- package/docs/guide/ja/pipeline/4-picking-an-engine-per-rail.md +60 -0
- package/docs/guide/ja/settings/1-themes.md +37 -0
- package/docs/guide/ja/settings/2-language.md +39 -0
- package/docs/guide/ja/settings/3-pipeline-telemetry-and-diagnostics.md +46 -0
- package/docs/guide/ja/settings/4-where-your-data-lives.md +48 -0
- package/docs/guide/ja/specs/1-specs-and-the-backlog.md +52 -0
- package/docs/guide/ja/specs/2-add-spec-quick-mode.md +45 -0
- package/docs/guide/ja/specs/3-add-spec-explore-mode.md +68 -0
- package/docs/guide/ja/specs/4-drafts-and-contract-layer.md +81 -0
- package/docs/guide/pt/agents/1-meet-the-agents.md +38 -0
- package/docs/guide/pt/agents/2-profiles-and-the-balanced-default.md +45 -0
- package/docs/guide/pt/agents/3-customizing-models-per-agent.md +60 -0
- package/docs/guide/pt/agents/4-custom-agents-catalog.md +43 -0
- package/docs/guide/pt/getting-started/1-what-is-specrails.md +49 -0
- package/docs/guide/pt/getting-started/2-installing-and-first-run.md +42 -0
- package/docs/guide/pt/getting-started/3-adding-your-first-project.md +58 -0
- package/docs/guide/pt/getting-started/4-the-dashboard-tour.md +53 -0
- package/docs/guide/pt/insights/1-analytics-and-cost-tracking.md +78 -0
- package/docs/guide/pt/insights/2-the-integrated-terminal.md +46 -0
- package/docs/guide/pt/insights/3-code-explorer.md +50 -0
- package/docs/guide/pt/integrations/1-ai-providers.md +64 -0
- package/docs/guide/pt/integrations/2-plugins.md +44 -0
- package/docs/guide/pt/integrations/3-jira-integration.md +71 -0
- package/docs/guide/pt/integrations/4-mobile-companion.md +38 -0
- package/docs/guide/pt/pipeline/1-rails-and-jobs.md +94 -0
- package/docs/guide/pt/pipeline/2-the-job-detail-view.md +90 -0
- package/docs/guide/pt/pipeline/3-batch-implement-and-multi-feature.md +78 -0
- package/docs/guide/pt/pipeline/4-picking-an-engine-per-rail.md +60 -0
- package/docs/guide/pt/settings/1-themes.md +37 -0
- package/docs/guide/pt/settings/2-language.md +39 -0
- package/docs/guide/pt/settings/3-pipeline-telemetry-and-diagnostics.md +46 -0
- package/docs/guide/pt/settings/4-where-your-data-lives.md +48 -0
- package/docs/guide/pt/specs/1-specs-and-the-backlog.md +52 -0
- package/docs/guide/pt/specs/2-add-spec-quick-mode.md +45 -0
- package/docs/guide/pt/specs/3-add-spec-explore-mode.md +68 -0
- package/docs/guide/pt/specs/4-drafts-and-contract-layer.md +81 -0
- package/docs/guide/zh/agents/1-meet-the-agents.md +38 -0
- package/docs/guide/zh/agents/2-profiles-and-the-balanced-default.md +45 -0
- package/docs/guide/zh/agents/3-customizing-models-per-agent.md +60 -0
- package/docs/guide/zh/agents/4-custom-agents-catalog.md +43 -0
- package/docs/guide/zh/getting-started/1-what-is-specrails.md +49 -0
- package/docs/guide/zh/getting-started/2-installing-and-first-run.md +42 -0
- package/docs/guide/zh/getting-started/3-adding-your-first-project.md +58 -0
- package/docs/guide/zh/getting-started/4-the-dashboard-tour.md +53 -0
- package/docs/guide/zh/insights/1-analytics-and-cost-tracking.md +78 -0
- package/docs/guide/zh/insights/2-the-integrated-terminal.md +46 -0
- package/docs/guide/zh/insights/3-code-explorer.md +50 -0
- package/docs/guide/zh/integrations/1-ai-providers.md +64 -0
- package/docs/guide/zh/integrations/2-plugins.md +44 -0
- package/docs/guide/zh/integrations/3-jira-integration.md +71 -0
- package/docs/guide/zh/integrations/4-mobile-companion.md +38 -0
- package/docs/guide/zh/pipeline/1-rails-and-jobs.md +94 -0
- package/docs/guide/zh/pipeline/2-the-job-detail-view.md +90 -0
- package/docs/guide/zh/pipeline/3-batch-implement-and-multi-feature.md +78 -0
- package/docs/guide/zh/pipeline/4-picking-an-engine-per-rail.md +60 -0
- package/docs/guide/zh/settings/1-themes.md +37 -0
- package/docs/guide/zh/settings/2-language.md +39 -0
- package/docs/guide/zh/settings/3-pipeline-telemetry-and-diagnostics.md +46 -0
- package/docs/guide/zh/settings/4-where-your-data-lives.md +48 -0
- package/docs/guide/zh/specs/1-specs-and-the-backlog.md +52 -0
- package/docs/guide/zh/specs/2-add-spec-quick-mode.md +45 -0
- package/docs/guide/zh/specs/3-add-spec-explore-mode.md +68 -0
- package/docs/guide/zh/specs/4-drafts-and-contract-layer.md +81 -0
- package/docs/internals/README.md +1 -1
- package/docs/internals/adding-a-provider.md +192 -59
- package/docs/internals/api-reference.md +130 -21
- package/docs/internals/architecture.md +22 -9
- package/docs/internals/bundled-framework-build-plan.md +264 -0
- package/docs/internals/configuration.md +33 -8
- package/docs/internals/global-artifacts-alignment-contract.md +486 -0
- package/docs/internals/global-artifacts-relocation-evaluation.md +294 -0
- package/docs/internals/operations-runbook.md +16 -5
- package/docs/internals/profiles.md +42 -14
- package/docs/platforms/macos.md +27 -8
- package/docs/platforms/windows.md +20 -6
- package/docs/running-pipelines.md +17 -9
- package/docs/terminal.md +9 -3
- package/docs/tracking-cost.md +17 -11
- package/package.json +1 -1
- package/server/dist/agent-refine-manager.js +20 -5
- package/server/dist/artifact-registry.js +468 -0
- package/server/dist/attachment-manager.js +5 -8
- package/server/dist/browser-capture-manager.js +4 -4
- package/server/dist/bundled-core.js +72 -0
- package/server/dist/bundled-openspec.js +58 -0
- package/server/dist/chat-manager.js +42 -5
- package/server/dist/code-explorer-router.js +10 -7
- package/server/dist/config.js +7 -2
- package/server/dist/context-budget.js +17 -6
- package/server/dist/context-scope.js +6 -2
- package/server/dist/contract-refine-runner.js +31 -9
- package/server/dist/desktop-router.js +24 -1
- package/server/dist/docs-router.js +210 -132
- package/server/dist/file-summary-manager.js +41 -16
- package/server/dist/framework-manager.js +248 -0
- package/server/dist/framework-migration.js +308 -0
- package/server/dist/index.js +30 -0
- package/server/dist/install-config-path.js +73 -0
- package/server/dist/jira/jira-sync-manager.js +23 -11
- package/server/dist/openspec-shim.js +153 -0
- package/server/dist/plugins-router.js +19 -8
- package/server/dist/profiles-router.js +38 -16
- package/server/dist/project-registry.js +101 -3
- package/server/dist/project-router-chat.js +1 -1
- package/server/dist/project-router-helpers.js +25 -12
- package/server/dist/project-router-jobs.js +3 -3
- package/server/dist/project-router-settings.js +8 -6
- package/server/dist/project-router-setup.js +27 -10
- package/server/dist/project-router-spending.js +6 -1
- package/server/dist/project-router-tickets.js +30 -10
- package/server/dist/project-router.js +16 -1
- package/server/dist/queue-manager.js +149 -18
- package/server/dist/setup-manager.js +131 -29
- package/server/dist/smash-runner.js +21 -6
- package/server/dist/ticket-store.js +6 -2
- package/server/dist/ticket-watcher.js +5 -1
- package/server/dist/vitest-setup.js +25 -0
- package/server/dist/workspace-manager.js +199 -0
- package/server/dist/workspace-resolution.js +147 -0
- package/client/dist/assets/index-DgKfQFcf.css +0 -2
- package/client/dist/assets/setup-BIIkb-_K.js +0 -1
- package/client/dist/assets/setup-BeQxu9kD.js +0 -1
- package/client/dist/assets/setup-CPa6GnlI.js +0 -1
- package/client/dist/assets/setup-CZl4OEJx.js +0 -1
- package/client/dist/assets/setup-ChpodNfn.js +0 -1
- package/client/dist/assets/setup-D_fjJH6u.js +0 -1
- package/client/dist/assets/setup-YzD8DX4O.js +0 -1
- package/client/dist/assets/setup-fRpDozmq.js +0 -1
- package/docs/adding-a-provider.md +0 -107
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# Evaluación arquitectónica: reubicar TODOS los artefactos fuera de los repos importados
|
|
2
|
+
|
|
3
|
+
> Documento de decisión técnica. Audiencia: arquitectos de `specrails-core` + `specrails-desktop`.
|
|
4
|
+
> Objetivo evaluado: que `specrails-core` instale y que `specrails-desktop` lea **todos** los
|
|
5
|
+
> artefactos de Specrails desde `$HOME/.specrails`, y todos los artefactos de los CLIs
|
|
6
|
+
> (claude/gemini/codex) desde `$HOME/.claude`, `$HOME/.gemini`, `$HOME/.codex`, de modo que
|
|
7
|
+
> **los repos importados NUNCA se modifiquen** (cero `.specrails/.claude/.codex/.gemini` en el repo,
|
|
8
|
+
> cero mutaciones de `.gitignore`, cero archivos de instrucciones).
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. Resumen ejecutivo
|
|
13
|
+
|
|
14
|
+
El objetivo es **parcialmente alcanzable, no plenamente**, y la frontera entre lo alcanzable y lo irreductible es nítida y está bien fundamentada en la evidencia. La pieza maestra es un hecho confirmado en código y en los CLIs vivos: **los tres CLIs (claude, codex, gemini) anclan su "project scope" — agentes, comandos, skills, settings, archivo de instrucciones, `.mcp.json` — al directorio de trabajo (CWD), no al repo de git.** No existe ningún `--project-dir` en ninguno de los tres. Por tanto, si cada spawn se ejecuta desde un directorio anclado en `$HOME` (con el repo accesible mediante un symlink hijo `./project`), ese directorio pasa a ser el "proyecto" para el CLI y **cero archivos de config aterrizan en el repo**. Este patrón ya está probado y en producción en `server/explore-cwd-manager.ts`.
|
|
15
|
+
|
|
16
|
+
La recomendación es **adoptar el "workspace gestionado por la app" (Opción 1) como modelo arquitectónico de destino**, porque convierte la inmunidad a colisiones en una **propiedad estructural** (no en supresión por-flag), pero **ejecutarlo por fases empezando por el alcance de la Opción 3 (Híbrido Pragmático)** para los flujos de lectura/interactivos, que ya son relocalizables hoy con cambios solo en desktop y cero cambios en contratos congelados. El panel de jueces se reparte de forma honesta: **la lente de feasibilidad CLI y la de goal-fit/UX eligen la Opción 1** (es la única que usa el único mecanismo universal, CWD-relocation, sin depender de flags que el CLI no soporta); **la lente de blast-radius/contratos elige la Opción 3** (menor superficie de cambio, cero contratos en riesgo).
|
|
17
|
+
|
|
18
|
+
El techo honesto es **"repo git-limpio", no "repo file-limpio"** para proyectos que ejecutan rails de `implement`: dos artefactos son irreductiblemente repo-bound — `openspec/changes/` (entregable versionado, escrito por el binario externo `@fission-ai/openspec`, leído como working tree repo-relativo por los agentes) y los git worktrees de aislamiento (`.claude/worktrees/`, deben compartir el `.git`/object-store del repo para el merge-back). Ningún flag de ningún CLI los reubica. Para proyectos de **solo lectura** (Explore, quick-spec, chat, ai-edit) el objetivo literal de "cero archivos en el repo" **sí se cumple por completo**.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 2. El problema hoy
|
|
23
|
+
|
|
24
|
+
Cuando `specrails-desktop` importa un repo, su setup wizard ejecuta `npx specrails-core` (tier `quick`), que corre `scaffoldInstallation()` con `repoRoot = project.path` (la ruta del repo del usuario). Esto **escribe directamente dentro del repo del usuario** a través de cuatro raíces de destino, y además **muta archivos preexistentes del usuario**. El daño concreto, según el inventario de evidencia:
|
|
25
|
+
|
|
26
|
+
- **Pollution de directorios completos en el repo**: `.specrails/**` (manifest, version pin, `setup-templates/` staging, `install-config.yaml`, opcionalmente `profiles/`) y `<providerDir>/**` donde `providerDir` es `.claude` / `.codex` / `.gemini` según el provider (`scaffold.ts:251-275`, ~40 callsites con `path.join(input.repoRoot, providerDir, ...)`).
|
|
27
|
+
|
|
28
|
+
- **Mutación de `.gitignore` del usuario**: `ensureGitignore` añade un bloque `# specrails` con `.claude/agent-memory/` y `.specrails/` (y `.gemini/agent-memory/` en gemini) — `scaffold.ts:277-280, 1226-1242`.
|
|
29
|
+
|
|
30
|
+
- **Mutación quirúrgica de archivos de instrucciones preexistentes**: para codex, `AGENTS.md` raíz por sentinel-block upsert; para gemini, `GEMINI.md` raíz por sentinel + `.gemini/settings.json` por `deepMergeJson`. Preservan contenido fuera del bloque gestionado, pero **escriben en un archivo que el usuario ya tenía** (`scaffold.ts:1038-1071, 723-757`). (Nota: para claude NO se escribe `CLAUDE.md` en el flujo de desktop; eso es tarea del pass de IA `/specrails:enrich`, que el desktop nunca ejecuta en tier quick.)
|
|
31
|
+
|
|
32
|
+
- **Sobrescritura DESTRUCTIVA de archivos propios del usuario**: `placeQuickTierArtefacts()` escribe `sr-architect.md` / `sr-developer.md` / `sr-reviewer.md` con `writeFileLf` **sin guarda de existencia** (`scaffold.ts:951-956`). Si el usuario ya tenía un `.claude/agents/sr-architect.md` propio, **se clobberea**. El contrato `RESERVED_PATHS` solo protege dos prefijos (`.specrails/profiles/`, `.claude/agents/custom-`) — no protege los `sr-*`, ni el `CLAUDE.md`/`AGENTS.md`/`GEMINI.md` del usuario, ni `.mcp.json`, ni `openspec/`.
|
|
33
|
+
|
|
34
|
+
- **Escritura delegada fuera del control de core**: `npx @fission-ai/openspec init --tools <provider> <repoRoot>` escribe `openspec/**` y dirs de comandos de provider (`.claude/commands/opsx`) en el repo, con su propia lógica (`init.ts:128, 202-218`).
|
|
35
|
+
|
|
36
|
+
- **Borrados dentro del repo en cada run**: `pruneLegacyArtifacts()` hace `rmSync` recursivo de varias rutas repo-relativas en cada init (`scaffold.ts:784-814`).
|
|
37
|
+
|
|
38
|
+
El dolor: ruido de git, riesgo de clobber de config propia del usuario, mutaciones de `.gitignore`/`AGENTS.md`/`GEMINI.md` que el usuario no pidió, y una violación del principio "el repo importado es del usuario, no nuestro". El único precedente sano ya existente es que gemini escribe su índice de acknowledgments **fuera del repo** en `~/.gemini/acknowledgments/agents.json` (`scaffold.ts:676-699`) — la prueba de concepto del patrón `$HOME`.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 3. Inventario completo de artefactos
|
|
43
|
+
|
|
44
|
+
| Grupo de artefacto | Dónde se escribe HOY | Quién lo escribe | ¿Committed o gitignored? | ¿Reubicable a `$HOME` y cómo? |
|
|
45
|
+
|---|---|---|---|---|
|
|
46
|
+
| `specrails-manifest.json` + `specrails-version` | `<repo>/.specrails/` | core | gitignored (`.specrails/`) | **Sí** vía nuevo `--workspace-dir`/`artifactRoot` en core. Nombres FROZEN (desktop los regex-matchea); solo cambia la ruta base. |
|
|
47
|
+
| `setup-templates/**` (staging de templates) | `<repo>/.specrails/setup-templates/` | core | gitignored | **Sí**, requiere param base-dir en core + subdir por-proyecto (colisionaría entre proyectos si fuera `$HOME` plano). |
|
|
48
|
+
| `install-config.yaml` | `<repo>/.specrails/` | TUI bin / desktop | gitignored | **Sí (moderado)**: core ya acepta `--from-config <path>`; desktop **ya** copia a `tmpdir` para el spawn (`setup-manager.ts:122,754`). El pin en `integration-contract.json` es nominal. |
|
|
49
|
+
| `profiles/*.json` + `.user-preferred.json` | `<repo>/.specrails/profiles/` | desktop / usuario | **committed (team asset)** | **Sí pero**: app-owned, desktop controla todas las lecturas. Mover a `$HOME` **pierde la propiedad "committable team asset"** — decisión de producto, no solo de ruta. |
|
|
50
|
+
| `plugins/state.json` + `snapshots/` | `<repo>/.specrails/plugins/` | desktop | gitignored | **Sí (moderado)**: app-owned; el snapshot `$HOME/.../jobs/<jobId>/plugins.json` ya existe. |
|
|
51
|
+
| `file-summaries/<hash>.json` | `<repo>/.specrails/file-summaries/` | desktop | gitignored (línea auto-añadida) | **Sí (moderado)**: app-owned. Quita el append a `.gitignore` y la propiedad de team-share. |
|
|
52
|
+
| `local-tickets.json` (spec store canónico) | `<repo>/.specrails/` | desktop (RW) + core (R) | gitignored | **BLOQUEADO sin cambio de core**: contrato de lectura congelado; core + cada persona de agente referencian la ruta repo-relativa; el contrato Jira "zero core changes" lo asume repo-relativo. |
|
|
53
|
+
| `backlog-config.json` (switch read-only de Jira) | `<repo>/.specrails/` | desktop | gitignored | **BLOQUEADO**: core lo lee en ruta fija para entrar en su rama read-only. |
|
|
54
|
+
| `.claude/{agents,commands,skills,rules}` + `agent-memory/` | `<repo>/.claude/` | core | parcialmente gitignored (`agent-memory/`) | **Sí vía CWD-relocation** (CLI auto-discover desde CWD). Bloqueado si CWD debe ser el repo. |
|
|
55
|
+
| `.codex/{config.toml,skills}` + `AGENTS.md` raíz | `<repo>/.codex/`, `<repo>/AGENTS.md` | core | committed / git-noise | **Sí**: `CODEX_HOME` (ya usado per-project) cubre config.toml+MCP+skills+AGENTS.md global, **o** CWD-relocation. |
|
|
56
|
+
| `.gemini/{settings.json,agents,commands}` + `GEMINI.md` raíz | `<repo>/.gemini/`, `<repo>/GEMINI.md` | core | committed / git-noise | **Sí**: CWD-relocation (project scope cwd-anchored), `GEMINI_SYSTEM_MD` para instrucciones, user-scope settings para MCP. |
|
|
57
|
+
| `.mcp.json` (entradas MCP de plugins) | `<repo>/.mcp.json` | desktop (merge quirúrgico) | committed | **Sí (moderado)**: `--mcp-config <abs>` (mecanismo ya usado para `user-mcp.json`) **o** CWD-relocation. |
|
|
58
|
+
| `custom-<plugin>.md` fragmentos | `<repo>/.claude/agents/` | desktop | committed | **Sí vía CWD-relocation** (misma constraint de discovery). |
|
|
59
|
+
| `CLAUDE.md` raíz | NO escrito por desktop quick-tier (solo full-tier enrich) | core (full-tier) | committed | **Trivial**: nada lo escribe en el path de desktop; Explore ya lo evita vía explore-cwd. |
|
|
60
|
+
| `agent-memory/` (explanations, failures) | `<repo>/.claude/agent-memory/` | core (runtime, prompt MD) | gitignored | **Sí pero requiere NUEVO soporte de core** (`SPECRAILS_STATE_DIR` en templates de prompt). |
|
|
61
|
+
| `pipeline-state/`, `health-history/`, `compat-snapshots/`, `.dry-run/`, `backlog-cache.json` | `<repo>/.claude/...` | core (runtime, prompt MD) | gitignored | **Sí pero requiere NUEVO soporte de core** (mismo `SPECRAILS_STATE_DIR`). |
|
|
62
|
+
| `openspec/changes/**` (entregable de spec) | `<repo>/openspec/` | `@fission-ai/openspec` (delegado) | **git-TRACKED (committed, el producto)** | **BLOQUEADO**: binario externo, working tree repo-relativo, entregable versionado por diseño. |
|
|
63
|
+
| `.claude/worktrees/agent-<id>/` (git worktrees) | `<repo>/.claude/worktrees/` | Claude Code Task `isolation:worktree` | gitignored | **BLOQUEADO**: worktree real, debe compartir `.git`/object-store del repo para merge-back. |
|
|
64
|
+
| `~/.gemini/acknowledgments/agents.json` | `$HOME/.gemini/` (ya global) | core | n/a (global) | **Trivial (ya global)**: merge-safe, keyed por `repoRoot`. Re-keying si `.gemini/agents` se mueve. |
|
|
65
|
+
| `~/.specrails/doctor.log` | `$HOME/.specrails/` (ya global) | core (doctor) | n/a | **Trivial (ya global)**. |
|
|
66
|
+
| `.gitignore` (bloque `# specrails`) | `<repo>/.gitignore` | core | n/a | **Trivial de eliminar**: si los artefactos salen del repo, `ensureGitignore` es un no-op. |
|
|
67
|
+
|
|
68
|
+
**Precedente `$HOME` ya existente y amplio** (la base de la relocalización): desktop ya guarda `jobs.sqlite`, `jobs/<jobId>/{profile,plugins}.json`, telemetry, terminals shims, `explore-cwd`, `codex-home`, `browser-profile`, `attachments`, `user-mcp.json`, todo bajo `$HOME/.specrails/projects/<slug>/`. El snapshot `SPECRAILS_PROFILE_PATH` y `SPECRAILS_PLUGINS_*` ya apuntan a `$HOME`.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 4. La restricción dura: cómo resuelven la config los CLIs
|
|
73
|
+
|
|
74
|
+
Esta es la sección make-or-break. El hallazgo maestro, confirmado por la evidencia y los CLIs vivos: **ninguno de los tres CLIs permite apuntar agents/commands de project-scope a un directorio arbitrario SIN mover el CWD. No existe `--project-dir`.** De ahí se deriva todo.
|
|
75
|
+
|
|
76
|
+
### 4.1 Claude
|
|
77
|
+
|
|
78
|
+
- **Project scope (`.claude/settings.json`, `.claude/agents`, `.claude/commands`, `CLAUDE.md`, `.mcp.json`) está ESTRICTAMENTE anclado al CWD.** No hay flag/env para cargarlo desde un directorio no-CWD arbitrario (docs oficiales; feature-requests abiertas #25762 y #28808 piden exactamente esto, confirmando que no existe).
|
|
79
|
+
- **`CLAUDE_CONFIG_DIR` reubica SOLO el user-scope `~/.claude` (global a todos los proyectos), NO el `.claude` por-proyecto.**
|
|
80
|
+
- **Escape hatches por-invocación (sin archivo en el repo):** `--settings <file-or-json>` (ruta arbitraria), `--mcp-config <files...>` (+ `--strict-mcp-config` para ignorar el `.mcp.json` del repo), `--agents <json>` (agentes inline), `--add-dir`, `--system-prompt`/`--append-system-prompt`, `--plugin-dir`/`--plugin-url`.
|
|
81
|
+
- **`--setting-sources` es enum-only `{user, project, local}`** — selecciona qué scopes cargar, no dónde viven.
|
|
82
|
+
- **PARED dura (solo si CWD debe ser el repo):** no hay forma de cargar agents/commands/settings/`CLAUDE.md` de project-scope desde un directorio arbitrario manteniendo CWD en el repo. **`--add-dir` está documentado como "(CLAUDE.md dirs)"** — carga `CLAUDE.md`/memory desde un dir añadido pero **NO registra los subagentes `sr-*` de project-scope** que el snapshot de profile referencia. Esta es la falla fatal de la inyección de framework en rails de la Opción 3. Tampoco hay `--commands-dir`: los `/specrails:*` requieren `--plugin-dir` o `CLAUDE_CONFIG_DIR/commands`.
|
|
83
|
+
- **Esta pared se DISUELVE en el momento en que el CWD se reubica** a un dir `$HOME`: entonces `.claude/agents`, `.claude/commands`, `CLAUDE.md`, `.mcp.json` cargan nativamente desde ese CWD, sin flags.
|
|
84
|
+
|
|
85
|
+
### 4.2 Codex
|
|
86
|
+
|
|
87
|
+
- **`AGENTS.md` se resuelve en DOS scopes:** project (walk de git-root→cwd) Y global `CODEX_HOME/AGENTS.md` (con precedencia `AGENTS.override.md`). Un `AGENTS.md` no-repo está nativamente soportado vía `CODEX_HOME` — **sin truco de CWD para las instrucciones**.
|
|
88
|
+
- **`CODEX_HOME` reubica `config.toml` (model/sandbox/approval), definiciones MCP, auth Y skills/custom-prompts a un dir por-proyecto.** Desktop ya usa `CODEX_HOME` por-proyecto para MCP.
|
|
89
|
+
- **Project config (`.codex/config.toml`, `.codex/skills`) se descubre caminando desde el CWD hasta el project root** (marker por defecto `.git`); `project_root_markers` (settable a `[]`) controla esto.
|
|
90
|
+
- **PARED suave:** no hay env/flag para apuntar `AGENTS.md` a un FILE arbitrario más allá de project `.codex`, `CODEX_HOME` o `project_doc_fallback_filenames`. Pero `CODEX_HOME` cubre el caso completo. `-c key=value` override per-invocación, `-p profile`, `--ignore-user-config`, `-C/--cd`.
|
|
91
|
+
- **Riesgo de re-discovery:** con CWD=repo, codex **camina git-root→cwd buscando `AGENTS.md` y NO hay flag para deshabilitar ese walk** (confirmado ausente en codex 0.139.0 `--help`). Un `AGENTS.md` preexistente del usuario se concatena aditivamente. Solo "limpio" para repos vírgenes. Con CWD-relocation fuera del repo, el walk no encuentra nada del repo.
|
|
92
|
+
|
|
93
|
+
### 4.3 Gemini
|
|
94
|
+
|
|
95
|
+
- **`settings.json` carga de system, user (`~/.gemini/settings.json`) y project (`.gemini/settings.json` en CWD).** Project scope estrictamente cwd-anchored. `mcpServers` viven en `settings.json` en cualquier scope — un CWD `$HOME` o user-scope settings proveen MCP sin archivo en el repo.
|
|
96
|
+
- **`GEMINI_SYSTEM_MD` reemplaza el system prompt built-in con un archivo en ruta arbitraria** (abs/rel, `~` expandido) — escape hatch de instrucciones totalmente no-repo, independiente del discovery de `GEMINI.md`.
|
|
97
|
+
- **`GEMINI_CLI_HOME` reubica el dir user-level (`~/.gemini`, global). NINGÚN env reubica el `.gemini` de PROJECT** a ruta arbitraria — debe estar en CWD. `XDG_CONFIG_HOME` no se honra.
|
|
98
|
+
- **El walk de `GEMINI.md` para en el TRUSTED ROOT (frontera del workspace), no en git-root.** Un CWD `$HOME` que no sea ancestro del repo no re-descubre un `GEMINI.md` repo-side. `GEMINI_CLI_TRUST_WORKSPACE=true` (ya inyectado hoy) ancla el trusted root al workspace.
|
|
99
|
+
- **`--include-directories` + `context.loadMemoryFromIncludeDirectories=true`** carga sus `GEMINI.md`. `--policy`/`--admin-policy` cargan policy de rutas arbitrarias.
|
|
100
|
+
- **PARED suave:** project commands/agents son cwd-bound; necesitan CWD-relocation para salir del repo. MCP, instrucciones y policy tienen hatches no-CWD.
|
|
101
|
+
|
|
102
|
+
### 4.4 Síntesis de la restricción
|
|
103
|
+
|
|
104
|
+
| Tipo de artefacto | claude | codex | gemini |
|
|
105
|
+
|---|---|---|---|
|
|
106
|
+
| Instrucciones (`CLAUDE/AGENTS/GEMINI.md`) | `--append-system-prompt` / CWD | `CODEX_HOME/AGENTS.md` / CWD | `GEMINI_SYSTEM_MD` / CWD |
|
|
107
|
+
| MCP (`.mcp.json` / settings) | `--mcp-config` + `--strict-mcp-config` / CWD | `CODEX_HOME` config.toml | user-scope settings / CWD |
|
|
108
|
+
| Settings | `--settings` / CWD | `-c` + `CODEX_HOME` / CWD | `GEMINI_CLI_HOME` (user) / CWD (project) |
|
|
109
|
+
| **Agents (project-scope)** | **solo CWD** (o `--agents` inline) | **solo CWD/`CODEX_HOME`** (sin file flag) | **solo CWD** (sin env por-project) |
|
|
110
|
+
| **Commands (project-scope)** | **solo CWD** (o `--plugin-dir`; **NO hay `--commands-dir`**) | `CODEX_HOME/skills` / CWD | **solo CWD** |
|
|
111
|
+
|
|
112
|
+
**La conclusión que decide la arquitectura:** las paredes duras (agents/commands de project-scope) **solo existen si se insiste en mantener CWD=repo**. **Todas se disuelven con CWD-relocation** — el único mecanismo universal a los tres CLIs, ya probado en `explore-cwd-manager.ts`.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## 5. Opciones de arquitectura
|
|
117
|
+
|
|
118
|
+
### Opción 1 — Workspace gestionado por la app (generalizar explore-cwd)
|
|
119
|
+
|
|
120
|
+
CWD = `$HOME/.specrails/projects/<slug>/workspace/` para **todos** los spawns (excepto terminales). El workspace contiene TODOS los artefactos (`.claude/.codex/.gemini`, instrucciones, `.mcp.json`, `.specrails/`); el repo se alcanza vía symlink `./project`. Core gana un único `--workspace-dir`/`SPECRAILS_WORKSPACE_DIR` que separa `artifactRoot` de `codeRoot` (default unset ⇒ `artifactRoot=codeRoot`, legacy byte-idéntico). Runtime state vía nuevo `SPECRAILS_STATE_DIR`; worktrees repo-bound vía nuevo `SPECRAILS_REPO_DIR`.
|
|
121
|
+
|
|
122
|
+
- **Trade-offs:** inmunidad a colisiones **estructural** (no per-flag); claude carga agents/commands/`CLAUDE.md`/`.mcp.json` nativamente sin flags frágiles. **Coste:** XL, el grueso en core (~40 callsites de scaffold + 7+ templates de prompt); rails corren CWD=workspace (no el repo), así que toda ruta relativa de edición/git/openspec debe re-apuntar al repo real vía `SPECRAILS_REPO_DIR`/symlink — riesgo de corrección amplio. Requiere release lockstep de dos repos + core-version gate.
|
|
123
|
+
- **Scores del panel:** Feasibilidad CLI **8** (top pick), Goal-fit/UX **8** (top pick), Blast-radius/contratos **4**.
|
|
124
|
+
|
|
125
|
+
### Opción 2 — Globales `$HOME` reales + inyección por-invocación (CWD=repo)
|
|
126
|
+
|
|
127
|
+
Los artefactos viven en dirs `$HOME` reales por-proyecto; los spawns mantienen CWD=repo y alcanzan la config solo vía env vars + flags. claude: `CLAUDE_CONFIG_DIR` + `--setting-sources user` + `--strict-mcp-config` + `--mcp-config` + `--agents`/`--plugin-dir` + `--append-system-prompt`. codex: `CODEX_HOME`. gemini: `GEMINI_CLI_HOME` + `GEMINI_SYSTEM_MD` + `--include-directories`.
|
|
128
|
+
|
|
129
|
+
- **Trade-offs:** CWD=repo resuelve git/rutas relativas nativamente (única ventaja). **Pero** se sitúa exactamente en la configuración que la evidencia marca con MÁS paredes duras. codex/gemini project skills/agents **no tienen loader no-CWD** ⇒ "user-scope enmascarando project-scope". codex concatena aditivamente cualquier `AGENTS.md` preexistente del usuario (**sin flag para deshabilitar el walk**). claude no tiene `--commands-dir` ⇒ `/specrails:*` requieren ensamblaje `--plugin-dir` por-proyecto (maquinaria nueva no verificada). Además relocaliza `local-tickets.json`, el read-cache FROZEN de core (contrato Jira "zero core changes") — **el peor riesgo de contrato** para un resultado aún PARCIAL.
|
|
130
|
+
- **Scores del panel:** Feasibilidad CLI **4**, Goal-fit/UX **4**, Blast-radius/contratos **3** (el peor en las tres lentes).
|
|
131
|
+
|
|
132
|
+
### Opción 3 — Híbrido Pragmático (CWD-relocation para lectura, `--add-dir` para rails, gitignore el residuo)
|
|
133
|
+
|
|
134
|
+
Flujos de lectura/interactivos (Explore, quick-spec, contract-refine, sidebar chat, agent-refine, terminal "Open AI CLI") → CWD-relocation a `$HOME/.../cli-cwd/` (reusando/generalizando `ensureExploreCwd`): **cero archivos en el repo, hoy mismo**. Rail/implement → CWD=repo (inevitable), inyectando framework vía `--add-dir`/`--include-directories`/`CODEX_HOME` + `--strict-mcp-config`, y dejando el residuo irreductible (openspec/changes, worktrees, runtime state) **git-limpio** (ya está en el bloque gitignore de core).
|
|
135
|
+
|
|
136
|
+
- **Trade-offs:** **menor blast radius** (Medium, ~70% desktop, core OPCIONAL/cero); **cero contratos congelados tocados**; reusa el patrón explore-cwd ya en producción. **Pero** el rail-path es el punto débil honesto: `--add-dir` está documentado como "(CLAUDE.md dirs)" y **puede NO registrar los subagentes `sr-*`** ⇒ fallback a `--agents` inline regenerado por-spawn, con riesgo de drift respecto al snapshot de profile. No alcanza "cero archivos" para proyectos que corren rails (solo git-limpio).
|
|
137
|
+
- **Scores del panel:** Feasibilidad CLI **5**, Goal-fit/UX **6**, Blast-radius/contratos **8** (top pick).
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## 6. Recomendación
|
|
142
|
+
|
|
143
|
+
**Adoptar la Opción 1 (workspace) como modelo de destino, implementada por fases empezando con el alcance de la Opción 3 para los flujos de lectura.** Esto es un **graft** deliberado:
|
|
144
|
+
|
|
145
|
+
1. **Fase A (alcance Opción 3, solo desktop, cero cambios de core, cero contratos en riesgo):** generalizar `explore-cwd-manager.ts` en un `CliCwdManager` compartido y enrutar **todos los flujos de lectura/interactivos** (Explore, quick-spec, contract-refine, agent-refine, sidebar chat, terminal "Open AI CLI") a CWD = `$HOME/.../cli-cwd/`. Para estos flujos, el objetivo "cero archivos en el repo" **se cumple por completo, hoy**, con la inmunidad-a-colisiones estructural de la Opción 1. Repointar los sitios app-owned (`ticket-store`, `profile-manager`, `plugins/paths`, `file-summary`, `jira-backlog-config`, `context-scope`) a `$HOME` donde sea seguro.
|
|
146
|
+
|
|
147
|
+
2. **Fase B (alcance Opción 1, cambio de core, release lockstep):** introducir `--workspace-dir`/`SPECRAILS_WORKSPACE_DIR` + `SPECRAILS_STATE_DIR` + `SPECRAILS_REPO_DIR` en core, y mover **el flujo de rails** al workspace, con worktrees/openspec como las excepciones repo-bound documentadas. Gate por core-version (espejo del gate `>= 4.1.0` de profiles).
|
|
148
|
+
|
|
149
|
+
**Por qué este graft y no Opción 2/3 puras:** las dos lentes que importan para "que funcione de verdad" (feasibilidad CLI y goal-fit) eligen la Opción 1 porque es la única que descansa **exclusivamente** en CWD-relocation — el único mecanismo universal y no-mágico. La Opción 2 muere en las paredes duras (codex sin loader no-CWD + leak de `AGENTS.md` no suprimible + relocación de `local-tickets.json` que toca un contrato congelado). La Opción 3 hereda la inmunidad de la Opción 1 en lectura pero su rail-path descansa en `--add-dir`, que `claude --help` documenta como "(CLAUDE.md dirs)" — **no registra subagentes de project-scope**. El graft captura lo mejor de ambas: la Opción 3 entrega valor real e inmediato con riesgo mínimo, y la Opción 1 completa el objetivo donde más importa (rails) con la garantía arquitectónica.
|
|
150
|
+
|
|
151
|
+
### Layout de destino bajo `$HOME`
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
~/.specrails/projects/<slug>/
|
|
155
|
+
workspace/ # CWD universal (generaliza explore-cwd) — Fase B
|
|
156
|
+
CLAUDE.md | AGENTS.md | GEMINI.md # instrucciones app/core-owned (por provider)
|
|
157
|
+
.mcp.json # entradas MCP de plugins (+ opcional project MCP)
|
|
158
|
+
.claude/{agents,commands,skills,rules,agent-memory}/
|
|
159
|
+
.codex/{config.toml,skills}/ # codex (también cubierto por CODEX_HOME)
|
|
160
|
+
.gemini/{settings.json,agents,commands,agent-memory}/
|
|
161
|
+
.specrails/
|
|
162
|
+
specrails-manifest.json specrails-version # nombres FROZEN, ahora aquí
|
|
163
|
+
install-config.yaml
|
|
164
|
+
setup-templates/{agents,commands,skills,rules,personas,claude-md,settings}/
|
|
165
|
+
profiles/*.json .user-preferred.json # app-owned (pierde "committable")
|
|
166
|
+
plugins/{state.json,snapshots/}
|
|
167
|
+
file-summaries/<hash>.json
|
|
168
|
+
local-tickets.json # read-cache de specs (vía core env pointer)
|
|
169
|
+
backlog-config.json # switch read-only de Jira
|
|
170
|
+
pipeline-state/ health-history/ compat-snapshots/ dry-run/ agent-memory/ backlog-cache.json
|
|
171
|
+
# ^ runtime state, redirigido vía SPECRAILS_STATE_DIR (nuevo env de core)
|
|
172
|
+
project -> <project.path> # symlink/junction (project-path.txt fallback)
|
|
173
|
+
cli-cwd/ # CWD para flujos de lectura — Fase A (ya existe como explore-cwd)
|
|
174
|
+
jobs.sqlite codex-home/ telemetry/ terminals/ user-mcp.json attachments/ ... # ya en $HOME
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Lo único que permanece en el repo: `workspace/project` (symlink), `openspec/changes/` (entregable versionado, intencional) y los worktrees git-bound (gitignored).
|
|
178
|
+
|
|
179
|
+
### Receta de spawn por provider (Fase B, CWD = workspace)
|
|
180
|
+
|
|
181
|
+
- **claude** (rails, chat, agent-refine, quick-spec, contract-refine): `cwd=<workspace>`. Auto-descubre `.claude/{agents,commands,skills}`, `CLAUDE.md`, `.mcp.json` desde el CWD — **sin flags nuevos en el happy path**. `--add-dir <workspace>/project` para que las tools alcancen archivos del repo por ruta absoluta. `--mcp-config <$HOME user-mcp.json>` para user-MCP sin cambios. `--setting-sources project,local` para aislar de globales del usuario.
|
|
182
|
+
- **codex**: `cwd=<workspace>` + mantener `CODEX_HOME=$HOME/.specrails/projects/<slug>/codex-home`. `-c project_root_markers=[]` (defensivo) para que trate el workspace como root y no camine ancestros. `AGENTS.md` en `<workspace>/AGENTS.md` o `CODEX_HOME/AGENTS.md`.
|
|
183
|
+
- **gemini**: `cwd=<workspace>`. Project `.gemini/{settings.json,agents,commands}` + `GEMINI.md` cwd-discovered. `GEMINI_CLI_TRUST_WORKSPACE=true` (ya inyectado) ancla el trusted root al workspace ⇒ ningún `GEMINI.md` repo-side se re-descubre. Opcional `GEMINI_SYSTEM_MD=<workspace>/GEMINI.md`. Re-keying del writer `~/.gemini/acknowledgments/agents.json` de `project.path` al workspace, hasheando `<workspace>/.gemini/agents/*.md`.
|
|
184
|
+
|
|
185
|
+
Para los tres, el env `$HOME` ya existente (`SPECRAILS_PROFILE_PATH`, `SPECRAILS_PLUGINS_*`, `OTEL_*`/`CLAUDE_CODE_ENABLE_TELEMETRY`) no cambia. **Terminales mantienen `cwd=project.path`** — el usuario espera una shell en su repo real. **Git provenance mantiene `cwd=project.path`** — git es repo-bound.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## 7. Plan de migración
|
|
190
|
+
|
|
191
|
+
### Proyectos ya importados
|
|
192
|
+
|
|
193
|
+
Migración **no-destructiva por diseño** (honra "no modificar el repo"): al cargar el registry (o en el primer job tras el upgrade), `migrateProjectArtifactsToHome(slug)`:
|
|
194
|
+
|
|
195
|
+
1. Detecta `.specrails/`, `.claude/`, `.codex/`, `.gemini/`, `AGENTS.md`/`GEMINI.md`/`CLAUDE.md` raíz, `.mcp.json` repo-residentes.
|
|
196
|
+
2. **Copia (no mueve — deja el repo intacto)** el subconjunto app-owned al nuevo `cli-cwd`/`workspace`: `local-tickets.json`, `profiles/`, `plugins/state.json`, `file-summaries/`, `install-config.yaml`, los `sr-*` agents/commands.
|
|
197
|
+
3. Para el workspace (Fase B), re-ejecuta `npx specrails-core init --root-dir <project.path> --workspace-dir <workspace>` para regenerar artefactos canónicos en `$HOME`.
|
|
198
|
+
4. Setea un flag en `desktop-db` para que las lecturas siguientes usen `$HOME`.
|
|
199
|
+
5. Los archivos repo-residentes de instalaciones previas se **dejan en disco** (no se borran automáticamente) e inertes; se ofrece una affordance manual "limpiar archivos antiguos de Specrails" — que el usuario ejecuta explícitamente (eso sí modifica el repo, nunca automático).
|
|
200
|
+
|
|
201
|
+
### Cambios en `init`/`update` de core
|
|
202
|
+
|
|
203
|
+
- **Fase A:** **cero cambios de core.** Desktop ya pasa `--from-config <abs tmpdir path>` (`setup-manager.ts:754`), así que el pin `configSchema.file` es nominal. Se ejecuta `init` con `cwd` = el dir staging `$HOME` (no `project.path`).
|
|
204
|
+
- **Fase B:** nuevo `--workspace-dir`/`SPECRAILS_WORKSPACE_DIR` que resuelve `artifactRoot = workspaceDir ?? repoRoot`. Threading de `artifactRoot` a través de ~40 callsites de `scaffold.ts`. `ensureGitignore()` y `pruneLegacyArtifacts()` operan sobre `artifactRoot` (no-op/seguro cuando `artifactRoot !== codeRoot`). Delegado openspec recibe el workspace como target (verificar PoC). Runtime: `SPECRAILS_STATE_DIR` honrado por `implement.md`/`retry.md`/`health-check.md`/`compat-check.md`/`sr-*.md`/`why.md`/`memory-inspect.md` (default unset ⇒ `.claude/...`, legacy). Worktrees repo-bound vía `SPECRAILS_REPO_DIR`. Sentinels `init complete`/`update complete` y nombres de manifest **byte-estables**.
|
|
205
|
+
|
|
206
|
+
### Backward-compat y kill-switch / rollback
|
|
207
|
+
|
|
208
|
+
- **Default unset ⇒ legacy byte-idéntico:** todo `npx specrails-core init` standalone (no-desktop) se comporta exactamente igual; `--workspace-dir` solo lo pasa desktop.
|
|
209
|
+
- **Core-version gate** (espejo del `>= 4.1.0` de profiles): un desktop nuevo contra un core viejo (sin `--workspace-dir`) **caería de vuelta al comportamiento in-repo** en lugar de mis-targetear silenciosamente. **Este gate es load-bearing** — sin él, un desktop nuevo + core viejo vuelca artefactos en el repo.
|
|
210
|
+
- **Rollback:** desactivar el flag de workspace por-proyecto en `desktop-db` revierte a CWD=repo. Los archivos `$HOME` permanecen (limpiables manualmente). Ningún dato se pierde.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## 8. Esfuerzo e impacto por repo
|
|
215
|
+
|
|
216
|
+
### specrails-core
|
|
217
|
+
|
|
218
|
+
- **Fase A:** **cero cambios.**
|
|
219
|
+
- **Fase B (esfuerzo: el grueso, XL del total):**
|
|
220
|
+
- `init.ts`/`update.ts`/`doctor.ts`: nuevo flag `--workspace-dir` + env, resolver `artifactRoot`.
|
|
221
|
+
- `scaffold.ts`: split de `artifactRoot`/`codeRoot` en ~40 callsites de `path.join(input.repoRoot, providerDir, ...)`. **Mecánico pero debe ser exhaustivo** — un solo literal `.claude/...` perdido aterriza en el repo y viola el requisito en silencio.
|
|
222
|
+
- `ensureGitignore()` no-op cuando `artifactRoot !== codeRoot`; `pruneLegacyArtifacts()` sobre `artifactRoot`.
|
|
223
|
+
- Templates de prompt runtime: `SPECRAILS_STATE_DIR` en ~7-8 archivos MD, default `.claude/...`.
|
|
224
|
+
- Worktrees: `SPECRAILS_REPO_DIR` para ops git/worktree distintas del CWD.
|
|
225
|
+
- `integration-contract.json`: bump de `schemaVersion`; documentar el contrato workspace-dir.
|
|
226
|
+
|
|
227
|
+
### specrails-desktop
|
|
228
|
+
|
|
229
|
+
- **Fase A (esfuerzo: Medium, ~70% del trabajo de Fase A):**
|
|
230
|
+
- Generalizar `explore-cwd-manager.ts` → `CliCwdManager` compartido (reusar symlink + `project-path.txt` fallback + cleanup que ya existen).
|
|
231
|
+
- Repointar `chat-manager`, `contract-refine-runner`, `agent-refine-manager`, `project-router-tickets` (quick-spec, ai-edit) a `cli-cwd`.
|
|
232
|
+
- `setup-manager`: ejecutar `init` con `cwd` = dir staging `$HOME`.
|
|
233
|
+
- Repointar `ticket-store.resolveTicketStoragePath`, `profile-manager.profilesDir`, `plugins/paths.*`, `file-summary-manager.SUMMARIES_REL`, `jira-backlog-config`, `context-scope` readers a `$HOME`.
|
|
234
|
+
- Re-keying de `gemini-agent-ack`.
|
|
235
|
+
- **Fase B (esfuerzo: Medium-Large):**
|
|
236
|
+
- `queue-manager`: cambiar rail-job `cwd` a workspace; inyectar `SPECRAILS_STATE_DIR=<workspace>` + `SPECRAILS_REPO_DIR=<project.path>`. Provenance mantiene `cwd=project.path`.
|
|
237
|
+
- `terminal-manager`: **mantener `cwd=project.path`** (intencional).
|
|
238
|
+
- Migración + core-version gate.
|
|
239
|
+
|
|
240
|
+
### Riesgos para contratos congelados
|
|
241
|
+
|
|
242
|
+
| Contrato congelado | ¿En riesgo? | Notas |
|
|
243
|
+
|---|---|---|
|
|
244
|
+
| Mobile wire (`specrailshub`, `hub.*`, `hubInstanceId`, `hub_daily_budget_exceeded`) | **No** | Strings de identidad/wire, ortogonales a ubicación de archivos. |
|
|
245
|
+
| Bundle id `sh.specrails.hub` | **No** | Identidad de app-data/updater; sin relación con repo-vs-HOME. |
|
|
246
|
+
| core↔desktop schema identity (`$id`) | **No** | `profile.v1.json` de desktop ya es derivativo con su propio `$id` (línea 3). Mover profiles a `$HOME` no cambia el `$id`. |
|
|
247
|
+
| `RESERVED_PATHS` (`.specrails/profiles/`, `.claude/agents/custom-`) | **No** (semántica), **Sí** producto | Semántica preservada relativa a `artifactRoot`. Mover profiles a `$HOME` pierde "committable team asset" — decisión de producto. |
|
|
248
|
+
| Sentinels `init complete`/`update complete` | **No** (si byte-estables) | Deben permanecer byte-idénticos; solo cambia su ruta base. |
|
|
249
|
+
| `integration-contract.json` `configSchema.file='.specrails/install-config.yaml'` | **Bajo** | Pin nominal; desktop ya pasa `--from-config <abs>`. Fase B puede bumpear `schemaVersion`. |
|
|
250
|
+
| Coverage gates (80% server, 80% client, 70% global) | **No** (alcanzables) | Path funcs puras + symlink manager + DB reads en el harness `:memory:` existente son altamente testeables. Requiere volumen de tests nuevo, no bajar thresholds. |
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## 9. Riesgos y preguntas abiertas
|
|
255
|
+
|
|
256
|
+
1. **[SPIKE OBLIGATORIO ANTES DE FASE B] ¿`--add-dir` registra subagentes de project-scope?** `claude --help` documenta `--add-dir` como "(CLAUDE.md dirs)". Si la Opción 1 funciona (CWD=workspace, los agents viven en `<workspace>/.claude/agents` y cargan nativamente desde el CWD) esto **no es problema para la Fase B**. Pero **es la falla fatal de cualquier rail-path con CWD=repo** (Opción 3 pura). Validar que con CWD=workspace los `sr-*` se registran nativamente — es la suposición load-bearing de la recomendación.
|
|
257
|
+
|
|
258
|
+
2. **[SPIKE OBLIGATORIO] ¿`@fission-ai/openspec init` acepta un target out-of-repo / sin `.git`?** Si lo exige, `openspec/changes/` debe quedar como la **única** excepción repo-residente y "cero archivos" es PARCIAL para rails. Probar: init de openspec contra el workspace sin `.git`; si falla, evaluar inicializar un `.git` throwaway en el workspace o aceptar openspec como excepción documentada.
|
|
259
|
+
|
|
260
|
+
3. **[SPIKE] Worktrees repo-bound desde CWD=workspace.** Los worktrees deben compartir el `.git`/object-store del repo y mergear de vuelta. Validar que `SPECRAILS_REPO_DIR` + `git -C <repo>` worktree-add funcionan cuando el CWD del proceso es el workspace. Un error aquí **corrompe o falla merges de multi-feature rails silenciosamente**.
|
|
261
|
+
|
|
262
|
+
4. **Exhaustividad de los ~40 callsites de scaffold + ~8 templates de prompt.** Un solo literal `.claude/...`/`path.join(repoRoot,...)` perdido aterriza en el repo sin error. Mitigación: test que asserta el working tree del repo **byte-inalterado** tras un ciclo completo setup+job.
|
|
263
|
+
|
|
264
|
+
5. **codex/gemini ancestor-walk re-discovery.** Si el workspace se coloca dentro del repo (o el symlink se sigue durante discovery), un `AGENTS.md`/`GEMINI.md` repo-side se filtra. Mitigación: workspace estrictamente fuera del repo + `project_root_markers=[]`/`TRUST_WORKSPACE`. Verificar por versión de CLI.
|
|
265
|
+
|
|
266
|
+
6. **Disciplina de rutas en rails (CWD=workspace).** Toda ruta relativa que deba resolver en el REPO debe ir por `SPECRAILS_REPO_DIR`/symlink. Si una tool resuelve relativa al CWD, escribe en el workspace por error. Mitigación: `--add-dir <workspace>/project` + disciplina auditada en prompts.
|
|
267
|
+
|
|
268
|
+
7. **Profiles/file-summaries pierden "committable team asset".** Regresión de producto, no solo de ruta. Posible affordance opt-in "exportar profiles al repo" / "commit profiles".
|
|
269
|
+
|
|
270
|
+
8. **`--strict-mcp-config` en rails** deshabilita el `.mcp.json` committed del repo — puede romper a un usuario que dependa legítimamente de un MCP server repo-committed fuera del sistema de plugins. Necesita escape hatch por-proyecto.
|
|
271
|
+
|
|
272
|
+
9. **GAP ortogonal (no causado por esta migración, pero a corregir/flag en la rework de spawn-env):** `gemini-adapter` declara `nativeOtelEnv:true` pero `buildTelemetryEnv` no emite vars `GEMINI_TELEMETRY_*`; si gemini honra los `OTEL_*` genéricos está sin verificar.
|
|
273
|
+
|
|
274
|
+
10. **Release lockstep de dos repos.** Un desktop con `--workspace-dir` contra un core sin el flag vuelca artefactos en el repo. El core-version gate es load-bearing.
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## 10. Veredicto final
|
|
279
|
+
|
|
280
|
+
**GO-WITH-CAVEATS.**
|
|
281
|
+
|
|
282
|
+
- **Para flujos de lectura/interactivos (Explore, quick-spec, contract-refine, chat, ai-edit): GO inmediato.** Fase A es solo-desktop, cero cambios de core, cero contratos congelados en riesgo, y reusa el patrón explore-cwd ya en producción. El objetivo literal "cero archivos en el repo" **se cumple por completo** para estos flujos. Entrega valor real con riesgo mínimo.
|
|
283
|
+
|
|
284
|
+
- **Para el flujo de rails/implement: GO con la advertencia honesta de que el techo es "repo git-limpio", no "repo file-limpio".** `openspec/changes/` (entregable versionado intencional) y los git worktrees (deben compartir el `.git` del repo) son **irreductiblemente repo-bound en las tres opciones** — ningún flag de ningún CLI los reubica. Todo lo demás (framework dirs, instrucciones, `.mcp.json`, manifest, version, profiles, plugins, file-summaries, runtime state) se mueve limpiamente al workspace dado el flag de core + `SPECRAILS_STATE_DIR`.
|
|
285
|
+
|
|
286
|
+
- **NO-GO para la Opción 2 (globales `$HOME` con CWD=repo):** es la peor en las tres lentes del panel; choca con paredes duras no suprimibles (codex sin loader no-CWD, leak de `AGENTS.md`, sin `--commands-dir`) y pone en riesgo el contrato congelado `local-tickets.json` para un resultado aún parcial.
|
|
287
|
+
|
|
288
|
+
### Lo más importante a validar PRIMERO
|
|
289
|
+
|
|
290
|
+
**Un PoC que confirme la doble suposición load-bearing de la Fase B antes de comprometer el cambio de core:**
|
|
291
|
+
|
|
292
|
+
> Con CWD = un workspace `$HOME` fuera del repo, conteniendo `<workspace>/.claude/agents/sr-*.md` + `.mcp.json` + `CLAUDE.md`, y el repo en `<workspace>/project` (symlink): **(a)** ¿claude **registra y ejecuta** los subagentes `sr-*` de project-scope nativamente desde el CWD?, y **(b)** ¿el agente developer puede **editar source, correr tests y manejar git** en el repo real vía `--add-dir <workspace>/project` / `SPECRAILS_REPO_DIR` sin que ninguna tool escriba por error en el workspace?
|
|
293
|
+
|
|
294
|
+
Si (a) y (b) pasan, la Opción 1 es sólida y el resto es ingeniería exhaustiva. Si (a) falla (claude no registra agents desde el CWD del workspace cuando hay un symlink de por medio, o el discovery se confunde), la arquitectura de rails necesita repensarse antes de tocar core — y ese es exactamente el riesgo que hunde la inyección por-flag de las otras opciones.
|
|
@@ -14,7 +14,7 @@ specrails-desktop start
|
|
|
14
14
|
specrails-desktop --port 5000 start
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
`start`
|
|
17
|
+
`start` daemonizes the server, which then writes its own PID to `~/.specrails/manager.pid` and appends its stdout/stderr to `~/.specrails/desktop.log`. The default port is `4200`.
|
|
18
18
|
|
|
19
19
|
## Stopping the app
|
|
20
20
|
|
|
@@ -35,14 +35,16 @@ specrails-desktop status
|
|
|
35
35
|
# Same, against a custom port
|
|
36
36
|
specrails-desktop --port 5000 status
|
|
37
37
|
|
|
38
|
-
#
|
|
38
|
+
# Terser manager status (script-friendly probe)
|
|
39
39
|
specrails-desktop --status
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
`status` prints `server: running (pid <n>) on http://127.0.0.1:<port>`, the project count, and each project name.
|
|
42
|
+
The two forms print different output. The `status` **subcommand** prints `server: running (pid <n>) on http://127.0.0.1:<port>`, the project count, and each project name. The `--status` **flag** prints a shorter `manager: running (v<version>)` / `mode: super` / `projects: <count>` block (no PID, no project names) — handy as a scripted up/down probe. Both exit non-zero when the app is not running.
|
|
43
43
|
|
|
44
44
|
> `specrails-desktop --jobs` is **not** functional against the running server — the server does not expose a cross-project `/api/jobs` route, so the command prints a message that jobs history requires a manager with SQLite persistence and exits `1`. Browse job history per project in the app's **Jobs** page instead.
|
|
45
45
|
|
|
46
|
+
> **Offline CLI fallback.** When you run a command and no manager is up, the CLI prints `manager not running — invoking claude directly` and spawns a local `claude` process to handle it. This fallback **always uses `claude`** — it never spawns `codex` or `gemini`, regardless of a project's primary provider — and it writes **nothing** to Analytics (no `ai_invocations` row; cost/tokens are only echoed to your terminal). Start the manager (`specrails-desktop start`) to route through your project's real provider and capture the run.
|
|
47
|
+
|
|
46
48
|
## App data location
|
|
47
49
|
|
|
48
50
|
All app data lives under `~/.specrails/` (the path is hardcoded to your home directory — there is no override env var):
|
|
@@ -60,7 +62,7 @@ All app data lives under `~/.specrails/` (the path is hardcoded to your home dir
|
|
|
60
62
|
|
|
61
63
|
See [Configuration](configuration.md#specrails-directory-structure) for the complete per-project subtree (telemetry blobs, explore-cwd, terminals, attachments, etc.) and how the `<slug>` is derived.
|
|
62
64
|
|
|
63
|
-
> **Auth token caveat.** `~/.specrails/desktop.token` gates every `/api/*` request and WebSocket upgrade. Deleting
|
|
65
|
+
> **Auth token caveat.** `~/.specrails/desktop.token` gates every `/api/*` request and WebSocket upgrade, except the two public bootstrap routes (`GET /api/health` and `GET /api/token`) that `requireAuth` is mounted after, so the local client can fetch its token. Deleting the token file (or doing a full `rm -rf ~/.specrails`) regenerates a fresh token on the next start, which can leave an already-open browser tab or CLI on the old token — reload the app after a token reset. See [Configuration → Authentication](configuration.md#authentication).
|
|
64
66
|
|
|
65
67
|
## Log files
|
|
66
68
|
|
|
@@ -121,7 +123,7 @@ specrails-desktop start
|
|
|
121
123
|
# Back up first, then reset
|
|
122
124
|
cp ~/.specrails/desktop.sqlite ~/.specrails/desktop.sqlite.bak
|
|
123
125
|
specrails-desktop stop
|
|
124
|
-
rm -f ~/.specrails/desktop.sqlite* # the
|
|
126
|
+
rm -f ~/.specrails/desktop.sqlite* # the * also removes the write-ahead-log sidecar files (desktop.sqlite-wal, desktop.sqlite-shm)
|
|
125
127
|
specrails-desktop start # re-creates an empty registry
|
|
126
128
|
|
|
127
129
|
# Re-register each project
|
|
@@ -129,6 +131,15 @@ specrails-desktop add /path/to/project-a
|
|
|
129
131
|
specrails-desktop add /path/to/project-b
|
|
130
132
|
```
|
|
131
133
|
|
|
134
|
+
### Disable a misbehaving provider or feature (recovery levers)
|
|
135
|
+
|
|
136
|
+
If a single provider or feature is breaking the app, you can turn it off with an environment variable and restart — no reinstall, no data loss. Set the var in the environment the server starts in, then `specrails-desktop stop && specrails-desktop start`.
|
|
137
|
+
|
|
138
|
+
- **Disable a provider** (it disappears from Add Project / engine pickers): `SPECRAILS_CODEX_BETA=0` or `SPECRAILS_GEMINI_BETA=0`. Both are enabled by default and only the **exact string `0`** disables them (`1` / `true` / unset all keep the provider on).
|
|
139
|
+
- **Disable a spec-enrichment feature**: `SPECRAILS_EXPLORE_CONTRACT_REFINE` (Contract Refine) and `SPECRAILS_SMASH` (SMASH) are kill switches that turn off on `0`, `false`, or `off`.
|
|
140
|
+
|
|
141
|
+
These are the most common ops escape hatches; see [Configuration → Environment variables](configuration.md#environment-variables) for the complete list of gates and flags.
|
|
142
|
+
|
|
132
143
|
### Per-project reset (keeps the registration)
|
|
133
144
|
|
|
134
145
|
To clear one project's job history, invocations, and telemetry pointers while keeping it registered, delete just that project's `jobs.sqlite` with the app stopped:
|
|
@@ -19,7 +19,8 @@ From any project, click **Agents** in the right sidebar (next to
|
|
|
19
19
|
Dashboard/Jobs/Analytics/Settings).
|
|
20
20
|
|
|
21
21
|
- **Profiles** tab — create and edit profiles.
|
|
22
|
-
- **Usage** tab — see which profiles are actually being used
|
|
22
|
+
- **Usage** tab — see which profiles are actually being used (backed by
|
|
23
|
+
the `/analytics` endpoint covered in section 8).
|
|
23
24
|
- **Catalog** tab — read the upstream `sr-*` agents or author custom
|
|
24
25
|
`custom-*` ones via the Studio.
|
|
25
26
|
|
|
@@ -30,7 +31,13 @@ points:
|
|
|
30
31
|
`.claude/agents/` frontmatter models and creates a `default` profile
|
|
31
32
|
mirroring today's behavior (zero-loss). It requires the baseline trio
|
|
32
33
|
`sr-architect`, `sr-developer`, and `sr-reviewer` to be present — the
|
|
33
|
-
server rejects the migration if any is missing.
|
|
34
|
+
server rejects the migration if any is missing. On a project whose
|
|
35
|
+
primary provider is **not** Claude (Codex or Gemini), the frontmatter
|
|
36
|
+
model aliases aren't in that provider's catalog, so the migration stamps
|
|
37
|
+
the project's `provider` onto the profile and substitutes that provider's
|
|
38
|
+
default model — the resulting `default` profile still validates and is
|
|
39
|
+
ready to edit (though it only takes effect on Claude rails — see
|
|
40
|
+
[Multi-provider rails](#multi-provider-rails-claude-codex-and-gemini)).
|
|
34
41
|
- **Blank profile** — start from scratch.
|
|
35
42
|
|
|
36
43
|
## 2. Saved profiles vs selection
|
|
@@ -64,13 +71,28 @@ wizard. Each rail header has a compact profile dropdown
|
|
|
64
71
|
The "No profile" option is always available — use it to run a
|
|
65
72
|
rail exactly as it did pre-4.1.0.
|
|
66
73
|
|
|
67
|
-
### Codex
|
|
74
|
+
### Multi-provider rails (Claude, Codex, and Gemini)
|
|
68
75
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
**Profiles apply only to Claude rails.** specrails-desktop supports three
|
|
77
|
+
interchangeable AI providers — Claude, Codex, and Gemini — but agent
|
|
78
|
+
profiles are a Claude-only concept (Codex and Gemini have no equivalent).
|
|
79
|
+
|
|
80
|
+
When a rail's AI engine is **anything other than Claude** (Codex or
|
|
81
|
+
Gemini), the app force-nulls the profile and runs the rail in legacy mode.
|
|
82
|
+
The rails router enforces this server-side for *any* non-Claude engine, so
|
|
83
|
+
no profile env var is ever injected on a Codex or Gemini rail regardless of
|
|
84
|
+
what the UI shows.
|
|
85
|
+
|
|
86
|
+
> **Known UI limitation.** The client currently only hides the profile
|
|
87
|
+
> selector for **Codex** rails. On a **Gemini** rail the selector can still
|
|
88
|
+
> appear — but the server ignores any profile you pick there (it always
|
|
89
|
+
> falls back to legacy mode). Picking a profile on a Gemini rail therefore
|
|
90
|
+
> has no effect; treat it as a no-op until the selector is hidden for all
|
|
91
|
+
> non-Claude engines.
|
|
92
|
+
|
|
93
|
+
Provider availability itself is gated separately (both default-enabled): set
|
|
94
|
+
`SPECRAILS_CODEX_BETA=0` or `SPECRAILS_GEMINI_BETA=0` to disable a provider
|
|
95
|
+
app-wide. See [../codex.md](../codex.md) and [../gemini.md](../gemini.md).
|
|
74
96
|
|
|
75
97
|
## 4. Author a custom agent (Agent Studio)
|
|
76
98
|
|
|
@@ -96,15 +118,17 @@ see output, token count, and duration inline.
|
|
|
96
118
|
|
|
97
119
|
- A **profile badge** (themed with the `accent-primary` color) appears on
|
|
98
120
|
each job row showing which profile it ran under.
|
|
99
|
-
- The **Usage** tab
|
|
100
|
-
|
|
121
|
+
- The **Usage** tab (the same `/analytics` data from section 8) shows
|
|
122
|
+
usage per profile for the last 7/30/90 days: jobs, success rate, avg
|
|
123
|
+
duration, avg tokens, and avg cost.
|
|
101
124
|
- The **diagnostic ZIP export** on a job includes `profile.json` with
|
|
102
125
|
the exact snapshot that rail used.
|
|
103
126
|
|
|
104
127
|
## 6. Troubleshooting
|
|
105
128
|
|
|
106
|
-
- **Upgrade banner on Agents page** —
|
|
107
|
-
in the project to bring it to
|
|
129
|
+
- **Upgrade banner on Agents page** — run
|
|
130
|
+
`npx specrails-core@^4.8.0 update` in the project to bring it up to date
|
|
131
|
+
(profiles need ≥ 4.1.0; the version the app installs is `^4.8.0`).
|
|
108
132
|
- **Save disabled with "N issues to resolve"** — the live validator
|
|
109
133
|
enforces the baseline trio (`sr-architect`, `sr-developer`, `sr-reviewer`)
|
|
110
134
|
and routing ordering. Among the rules: a `default: true` routing rule (if
|
|
@@ -115,7 +139,8 @@ see output, token count, and duration inline.
|
|
|
115
139
|
- **The whole Agents section is missing** — it can be disabled server-side
|
|
116
140
|
with `SPECRAILS_AGENTS_SECTION=false`, which 404s the entire
|
|
117
141
|
`/profiles` router. Unset it (or leave it at its default) to restore the
|
|
118
|
-
section.
|
|
142
|
+
section. This flag is read **once at server startup**, so changing it
|
|
143
|
+
takes effect only after a server restart.
|
|
119
144
|
|
|
120
145
|
## 7. Reserved paths
|
|
121
146
|
|
|
@@ -136,7 +161,10 @@ A few internals worth knowing if you're working on this surface:
|
|
|
136
161
|
`projectSupportsProfiles()` (`server/queue-manager.ts`), which reads the
|
|
137
162
|
project's `.specrails/specrails-version` and requires
|
|
138
163
|
`specrails-core >= 4.1.0`. Below that, the rail spawns in legacy mode and
|
|
139
|
-
no profile env var is injected.
|
|
164
|
+
no profile env var is injected. The same is true on any non-Claude rail:
|
|
165
|
+
the rails router force-nulls the profile for Codex/Gemini engines, so the
|
|
166
|
+
`SPECRAILS_PROFILE_PATH` injection below only ever takes effect on a
|
|
167
|
+
Claude rail.
|
|
140
168
|
- **Snapshot per job.** When a rail launches with a profile, the resolved
|
|
141
169
|
profile is written to
|
|
142
170
|
`~/.specrails/projects/<slug>/jobs/<jobId>/profile.json` (chmod `400`, so
|
package/docs/platforms/macos.md
CHANGED
|
@@ -43,9 +43,19 @@ You only need this once per build. It does not apply to the notarized installers
|
|
|
43
43
|
When you add a project, the app checks for the tools it needs and surfaces them in a **prerequisites panel** (in the `Add Project` dialog and the setup wizard). It checks:
|
|
44
44
|
|
|
45
45
|
- **Bundled tools** — `node`, `npm`, `npx`, `git`.
|
|
46
|
-
- **Provider CLIs** — **Claude Code** and **
|
|
46
|
+
- **Provider CLIs** — **Claude Code**, **Codex**, and **Gemini CLI**. All three are always probed via your system `PATH` (never bundled). **At least one of the three must be installed and working** before Add Project is enabled — if none is usable the panel blocks the dialog.
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
You don't need all three providers. Install whichever you prefer:
|
|
49
|
+
|
|
50
|
+
| Provider | Install | Minimum CLI | Auth |
|
|
51
|
+
|---|---|---|---|
|
|
52
|
+
| **Claude Code** | from [claude.com/download](https://claude.com/download) | none pinned | `claude login` |
|
|
53
|
+
| **Codex** | `brew install codex` | `0.128.0` | `codex login` |
|
|
54
|
+
| **Gemini CLI** | `npm i -g @google/gemini-cli` | `0.11.0` | set `GEMINI_API_KEY` (a paid key from Google AI Studio) |
|
|
55
|
+
|
|
56
|
+
After installing a provider CLI, quit and relaunch Specrails so the new `PATH` is picked up (see [Verifying manually](#verifying-manually)). For full provider setup, see the [Codex guide](../codex.md) and the [Gemini guide](../gemini.md).
|
|
57
|
+
|
|
58
|
+
When everything is in order, the panel collapses to a single line: **All required tools detected** (no per-tool rows, no version numbers). The detailed per-tool list — with versions, and including the Claude / Codex / Gemini provider rows (one row per provider you've installed) — only renders when something is **missing**, below its minimum version, or broken.
|
|
49
59
|
|
|
50
60
|
## PATH resolution
|
|
51
61
|
|
|
@@ -53,13 +63,13 @@ GUI apps on macOS inherit a minimal `PATH` from launchd when launched from Finde
|
|
|
53
63
|
|
|
54
64
|
### Desktop app (the default for `.dmg` users)
|
|
55
65
|
|
|
56
|
-
The shipped desktop app bundles its own Node and Git runtimes. When
|
|
66
|
+
The shipped desktop app bundles its own Node and Git runtimes. When **both** the bundled `node` and `git` bin directories are present, the Tauri host sets `SPECRAILS_IS_DESKTOP=1` and `SPECRAILS_BUNDLED_RUNTIMES_PATH` before spawning the embedded server (`src-tauri/src/lib.rs`). In that mode `resolveStartupPath()` (in `server/path-resolver.ts`):
|
|
57
67
|
|
|
58
68
|
- Prepends the **bundled** `node` and `git` bin directories to the front of `process.env.PATH`. A system Homebrew or nvm-managed `node`/`git` can never shadow them.
|
|
59
69
|
- **Skips** the Homebrew fast-path prepend entirely.
|
|
60
70
|
- **Skips** the login-shell merge — `augmentPathFromLoginShell()` is a no-op so it cannot reorder system tools ahead of the bundled ones (`loginShellStatus: "skipped"`).
|
|
61
71
|
|
|
62
|
-
If a build ships **without** the bundled runtimes
|
|
72
|
+
If a build ships **without** the bundled runtimes — or has only a partial bundle (just one of the two directories present, or a botched extraction) — the desktop app does **not** dead-end: it falls through to the same system discovery described below, so a system-installed `node`/`git` still satisfies the requirement.
|
|
63
73
|
|
|
64
74
|
### Server / non-bundled fallback
|
|
65
75
|
|
|
@@ -88,7 +98,7 @@ This points you at the actual fix (remove the stale link) instead of sending you
|
|
|
88
98
|
|
|
89
99
|
## Diagnostic endpoint
|
|
90
100
|
|
|
91
|
-
`GET /api/setup-prerequisites?diagnostic=1` returns the standard payload plus a `diagnostic` block.
|
|
101
|
+
`GET /api/setup-prerequisites?diagnostic=1` returns the standard payload plus a `diagnostic` block. The example below is a **non-desktop / server run** (e.g. `npm run dev:server`), where `PATH` is reconstructed via the fast path + inherited entries:
|
|
92
102
|
|
|
93
103
|
```jsonc
|
|
94
104
|
{
|
|
@@ -102,7 +112,8 @@ This points you at the actual fix (remove the stale link) instead of sending you
|
|
|
102
112
|
"npx": "/opt/homebrew/bin/npx",
|
|
103
113
|
"git": "/usr/bin/git",
|
|
104
114
|
"claude": "/opt/homebrew/bin/claude",
|
|
105
|
-
"codex": null
|
|
115
|
+
"codex": null,
|
|
116
|
+
"gemini": null
|
|
106
117
|
},
|
|
107
118
|
"nodeEnv": "production",
|
|
108
119
|
"platform": "darwin"
|
|
@@ -110,7 +121,15 @@ This points you at the actual fix (remove the stale link) instead of sending you
|
|
|
110
121
|
}
|
|
111
122
|
```
|
|
112
123
|
|
|
113
|
-
|
|
124
|
+
In the **shipped desktop app** the first segments come from the bundled runtimes instead, so the leading `pathSources` entries read `"bundled"` and `loginShellStatus` is `"skipped"`:
|
|
125
|
+
|
|
126
|
+
```jsonc
|
|
127
|
+
"pathSegments": ["/Applications/Specrails.app/.../runtimes/node/bin", "/Applications/Specrails.app/.../runtimes/git/bin", "..."],
|
|
128
|
+
"pathSources": ["bundled", "bundled", "..."],
|
|
129
|
+
"loginShellStatus": "skipped"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`whichResults` is keyed by command name for **every** prerequisite the panel checks, so it includes `claude`/`codex`/`gemini` (and `uv` when probed) on top of the four bundled tools. A `null` value means that command was not found on `PATH` — in the example above, only Claude Code is installed.
|
|
114
133
|
|
|
115
134
|
The install-instructions modal exposes a **Copy diagnostics** button that fetches this endpoint and copies the JSON to the clipboard for bug reports. The base endpoint (no `?diagnostic=1`) omits the `diagnostic` field, keeping the regular UI poll small.
|
|
116
135
|
|
|
@@ -125,6 +144,6 @@ After installing or reinstalling Node (or a provider CLI):
|
|
|
125
144
|
|
|
126
145
|
## Known limitations
|
|
127
146
|
|
|
128
|
-
- **Provider requirement**: at least one
|
|
147
|
+
- **Provider requirement**: at least one provider CLI — Claude Code, Codex, or Gemini — must be installed and on `PATH`; otherwise Add Project stays disabled. (Gemini is enabled by default; to disable it set `SPECRAILS_GEMINI_BETA=0`.)
|
|
129
148
|
- **Port 4200** must be free on launch. The app binds `127.0.0.1:4200` for its API + WebSocket; if another process holds the port, the server cannot start.
|
|
130
149
|
- **Terminal panel**: the bottom terminal panel spawns `$SHELL -l -i`, so your `.zshrc` / `.bashrc` loads as it would in a normal login shell. Per-session shell selection is not yet exposed in the UI — set `SHELL` to override the default.
|