specweave 0.4.0 ā 0.6.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/.claude-plugin/README.md +325 -0
- package/.claude-plugin/marketplace.json +210 -0
- package/CLAUDE.md +1000 -252
- package/README.md +273 -180
- package/bin/install-agents.sh +1 -1
- package/bin/install-commands.sh +66 -14
- package/bin/install-hooks.sh +1 -1
- package/bin/install-skills.sh +1 -1
- package/bin/specweave.js +18 -0
- package/dist/adapters/adapter-base.d.ts +21 -0
- package/dist/adapters/adapter-base.d.ts.map +1 -1
- package/dist/adapters/adapter-base.js +28 -0
- package/dist/adapters/adapter-base.js.map +1 -1
- package/dist/adapters/adapter-interface.d.ts +41 -0
- package/dist/adapters/adapter-interface.d.ts.map +1 -1
- package/dist/adapters/claude/adapter.d.ts +85 -11
- package/dist/adapters/claude/adapter.d.ts.map +1 -1
- package/dist/adapters/claude/adapter.js +305 -37
- package/dist/adapters/claude/adapter.js.map +1 -1
- package/dist/adapters/copilot/adapter.d.ts +45 -2
- package/dist/adapters/copilot/adapter.d.ts.map +1 -1
- package/dist/adapters/copilot/adapter.js +226 -4
- package/dist/adapters/copilot/adapter.js.map +1 -1
- package/dist/adapters/cursor/adapter.d.ts +54 -0
- package/dist/adapters/cursor/adapter.d.ts.map +1 -1
- package/dist/adapters/cursor/adapter.js +192 -0
- package/dist/adapters/cursor/adapter.js.map +1 -1
- package/dist/adapters/generic/adapter.d.ts +43 -0
- package/dist/adapters/generic/adapter.d.ts.map +1 -1
- package/dist/adapters/generic/adapter.js +163 -0
- package/dist/adapters/generic/adapter.js.map +1 -1
- package/dist/cli/commands/init.d.ts +1 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +392 -123
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/install.d.ts +2 -0
- package/dist/cli/commands/install.d.ts.map +1 -1
- package/dist/cli/commands/install.js +28 -25
- package/dist/cli/commands/install.js.map +1 -1
- package/dist/cli/commands/list.d.ts +2 -0
- package/dist/cli/commands/list.d.ts.map +1 -1
- package/dist/cli/commands/list.js +26 -24
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/plugin.d.ts +43 -0
- package/dist/cli/commands/plugin.d.ts.map +1 -0
- package/dist/cli/commands/plugin.js +307 -0
- package/dist/cli/commands/plugin.js.map +1 -0
- package/dist/core/i18n/language-detector.d.ts +29 -0
- package/dist/core/i18n/language-detector.d.ts.map +1 -0
- package/dist/core/i18n/language-detector.js +143 -0
- package/dist/core/i18n/language-detector.js.map +1 -0
- package/dist/core/i18n/language-manager.d.ts +101 -0
- package/dist/core/i18n/language-manager.d.ts.map +1 -0
- package/dist/core/i18n/language-manager.js +232 -0
- package/dist/core/i18n/language-manager.js.map +1 -0
- package/dist/core/i18n/language-registry.d.ts +44 -0
- package/dist/core/i18n/language-registry.d.ts.map +1 -0
- package/dist/core/i18n/language-registry.js +234 -0
- package/dist/core/i18n/language-registry.js.map +1 -0
- package/dist/core/i18n/locale-manager.d.ts +62 -0
- package/dist/core/i18n/locale-manager.d.ts.map +1 -0
- package/dist/core/i18n/locale-manager.js +137 -0
- package/dist/core/i18n/locale-manager.js.map +1 -0
- package/dist/core/i18n/system-prompt-injector.d.ts +33 -0
- package/dist/core/i18n/system-prompt-injector.d.ts.map +1 -0
- package/dist/core/i18n/system-prompt-injector.js +131 -0
- package/dist/core/i18n/system-prompt-injector.js.map +1 -0
- package/dist/core/i18n/types.d.ts +151 -0
- package/dist/core/i18n/types.d.ts.map +1 -0
- package/dist/core/i18n/types.js +11 -0
- package/dist/core/i18n/types.js.map +1 -0
- package/dist/core/increment-status.d.ts +72 -0
- package/dist/core/increment-status.d.ts.map +1 -0
- package/dist/core/increment-status.js +227 -0
- package/dist/core/increment-status.js.map +1 -0
- package/dist/core/plugin-detector.d.ts +96 -0
- package/dist/core/plugin-detector.d.ts.map +1 -0
- package/dist/core/plugin-detector.js +349 -0
- package/dist/core/plugin-detector.js.map +1 -0
- package/dist/core/plugin-loader.d.ts +131 -0
- package/dist/core/plugin-loader.d.ts.map +1 -0
- package/dist/core/plugin-loader.js +421 -0
- package/dist/core/plugin-loader.js.map +1 -0
- package/dist/core/plugin-manager.d.ts +144 -0
- package/dist/core/plugin-manager.d.ts.map +1 -0
- package/dist/core/plugin-manager.js +393 -0
- package/dist/core/plugin-manager.js.map +1 -0
- package/dist/core/schemas/plugin-manifest.schema.json +253 -0
- package/dist/core/types/config.d.ts +51 -0
- package/dist/core/types/config.d.ts.map +1 -0
- package/dist/core/types/config.js +21 -0
- package/dist/core/types/config.js.map +1 -0
- package/dist/core/types/plugin.d.ts +283 -0
- package/dist/core/types/plugin.d.ts.map +1 -0
- package/dist/core/types/plugin.js +49 -0
- package/dist/core/types/plugin.js.map +1 -0
- package/dist/hooks/lib/sync-living-docs.d.ts +27 -0
- package/dist/hooks/lib/sync-living-docs.d.ts.map +1 -0
- package/dist/hooks/lib/sync-living-docs.js +116 -0
- package/dist/hooks/lib/sync-living-docs.js.map +1 -0
- package/dist/hooks/lib/translate-living-docs.d.ts +13 -0
- package/dist/hooks/lib/translate-living-docs.d.ts.map +1 -0
- package/dist/hooks/lib/translate-living-docs.js +166 -0
- package/dist/hooks/lib/translate-living-docs.js.map +1 -0
- package/dist/hooks/lib/update-tasks-md.d.ts +29 -0
- package/dist/hooks/lib/update-tasks-md.d.ts.map +1 -0
- package/dist/hooks/lib/update-tasks-md.js +203 -0
- package/dist/hooks/lib/update-tasks-md.js.map +1 -0
- package/dist/integrations/jira/jira-incremental-mapper.js.map +1 -1
- package/dist/integrations/jira/jira-mapper.d.ts +2 -2
- package/dist/integrations/jira/jira-mapper.js +2 -2
- package/dist/integrations/jira/jira-mapper.js.map +1 -1
- package/dist/locales/de/.gitkeep +0 -0
- package/dist/locales/de/cli.json +108 -0
- package/dist/locales/en/cli.json +269 -0
- package/dist/locales/en/errors.json +7 -0
- package/dist/locales/en/templates.json +6 -0
- package/dist/locales/es/.gitkeep +0 -0
- package/dist/locales/es/cli.json +41 -0
- package/dist/locales/fr/.gitkeep +0 -0
- package/dist/locales/fr/cli.json +108 -0
- package/dist/locales/ja/.gitkeep +0 -0
- package/dist/locales/ja/cli.json +108 -0
- package/dist/locales/ko/.gitkeep +0 -0
- package/dist/locales/ko/cli.json +108 -0
- package/dist/locales/pt/.gitkeep +0 -0
- package/dist/locales/pt/cli.json +108 -0
- package/dist/locales/ru/.gitkeep +0 -0
- package/dist/locales/ru/cli.json +269 -0
- package/dist/locales/zh/.gitkeep +0 -0
- package/dist/locales/zh/cli.json +108 -0
- package/dist/plugins/specweave-github/lib/github-client.d.ts +86 -0
- package/dist/plugins/specweave-github/lib/github-client.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/github-client.js +275 -0
- package/dist/plugins/specweave-github/lib/github-client.js.map +1 -0
- package/dist/plugins/specweave-github/lib/index.d.ts +10 -0
- package/dist/plugins/specweave-github/lib/index.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/index.js +10 -0
- package/dist/plugins/specweave-github/lib/index.js.map +1 -0
- package/dist/plugins/specweave-github/lib/subtask-sync.d.ts +51 -0
- package/dist/plugins/specweave-github/lib/subtask-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/subtask-sync.js +147 -0
- package/dist/plugins/specweave-github/lib/subtask-sync.js.map +1 -0
- package/dist/plugins/specweave-github/lib/task-parser.d.ts +37 -0
- package/dist/plugins/specweave-github/lib/task-parser.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/task-parser.js +211 -0
- package/dist/plugins/specweave-github/lib/task-parser.js.map +1 -0
- package/dist/plugins/specweave-github/lib/task-sync.d.ts +51 -0
- package/dist/plugins/specweave-github/lib/task-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/task-sync.js +332 -0
- package/dist/plugins/specweave-github/lib/task-sync.js.map +1 -0
- package/dist/plugins/specweave-github/lib/types.d.ts +80 -0
- package/dist/plugins/specweave-github/lib/types.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/types.js +5 -0
- package/dist/plugins/specweave-github/lib/types.js.map +1 -0
- package/dist/utils/agents-md-compiler.d.ts +68 -0
- package/dist/utils/agents-md-compiler.d.ts.map +1 -0
- package/dist/utils/agents-md-compiler.js +420 -0
- package/dist/utils/agents-md-compiler.js.map +1 -0
- package/dist/utils/generate-skills-index.js +4 -4
- package/dist/utils/generate-skills-index.js.map +1 -1
- package/package.json +24 -21
- package/plugins/specweave-ado/.claude-plugin/plugin.json +8 -0
- package/plugins/specweave-alternatives/.claude-plugin/plugin.json +8 -0
- package/plugins/specweave-alternatives/skills/bmad-method-expert/SKILL.md +626 -0
- package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/analyze-project.js +318 -0
- package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/check-setup.js +208 -0
- package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/generate-template.js +1149 -0
- package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/validate-documents.js +340 -0
- package/plugins/specweave-alternatives/skills/spec-kit-expert/SKILL.md +1010 -0
- package/plugins/specweave-backend/.claude-plugin/plugin.json +8 -0
- package/plugins/specweave-core/.claude-plugin/plugin.json +25 -0
- package/{src ā plugins/specweave-core}/agents/pm/AGENT.md +80 -0
- package/plugins/specweave-core/agents/translator/AGENT.md +282 -0
- package/{src ā plugins/specweave-core}/commands/README.md +11 -11
- package/{src ā plugins/specweave-core}/commands/specweave.costs.md +7 -7
- package/{src ā plugins/specweave-core}/commands/specweave.do.md +34 -7
- package/{src ā plugins/specweave-core}/commands/specweave.increment.md +131 -22
- package/{src ā plugins/specweave-core}/commands/specweave.md +49 -17
- package/{src ā plugins/specweave-core}/commands/specweave.sync-docs.md +5 -5
- package/plugins/specweave-core/commands/specweave.translate.md +425 -0
- package/{src ā plugins/specweave-core}/commands/specweave.validate.md +1 -1
- package/plugins/specweave-core/hooks/hooks.json +13 -0
- package/plugins/specweave-core/hooks/post-increment-plugin-detect.sh +142 -0
- package/plugins/specweave-core/hooks/post-task-completion.sh +265 -0
- package/plugins/specweave-core/hooks/pre-task-plugin-detect.sh +96 -0
- package/plugins/specweave-core/skills/SKILLS-INDEX.md +229 -0
- package/{src ā plugins/specweave-core}/skills/brownfield-analyzer/SKILL.md +66 -24
- package/{src ā plugins/specweave-core}/skills/context-loader/SKILL.md +1 -1
- package/plugins/specweave-core/skills/context-optimizer/SKILL.md +588 -0
- package/plugins/specweave-core/skills/docs-updater/SKILL.md +0 -0
- package/{src ā plugins/specweave-core}/skills/increment-planner/SKILL.md +81 -4
- package/plugins/specweave-core/skills/plugin-detector/SKILL.md +211 -0
- package/{src ā plugins/specweave-core}/skills/project-kickstarter/SKILL.md +7 -7
- package/plugins/specweave-core/skills/rfc-generator/SKILL.md +369 -0
- package/{src ā plugins/specweave-core}/skills/specweave-detector/SKILL.md +2 -2
- package/plugins/specweave-core/skills/specweave-framework/SKILL.md +498 -0
- package/plugins/specweave-core/skills/specweave-framework/test-cases/test-1-increment-naming.yaml +11 -0
- package/plugins/specweave-core/skills/specweave-framework/test-cases/test-2-source-of-truth.yaml +11 -0
- package/plugins/specweave-core/skills/specweave-framework/test-cases/test-3-increment-discipline.yaml +12 -0
- package/plugins/specweave-core/skills/specweave-framework/test-cases/test-4-file-placement.yaml +11 -0
- package/{src ā plugins/specweave-core}/skills/tdd-workflow/SKILL.md +20 -20
- package/plugins/specweave-core/skills/translator/SKILL.md +172 -0
- package/plugins/specweave-cost-optimizer/.claude-plugin/plugin.json +8 -0
- package/plugins/specweave-diagrams/.claude-plugin/plugin.json +8 -0
- package/plugins/specweave-docs/.claude-plugin/plugin.json +8 -0
- package/plugins/specweave-docs/skills/docusaurus/SKILL.md +526 -0
- package/plugins/specweave-figma/.claude-plugin/.mcp.json +12 -0
- package/plugins/specweave-figma/.claude-plugin/plugin.json +8 -0
- package/plugins/specweave-figma/ARCHITECTURE.md +453 -0
- package/plugins/specweave-figma/README.md +728 -0
- package/plugins/specweave-figma/skills/figma-to-code/SKILL.md +632 -0
- package/plugins/specweave-figma/skills/figma-to-code/test-1-token-generation.yaml +29 -0
- package/plugins/specweave-figma/skills/figma-to-code/test-2-component-generation.yaml +27 -0
- package/plugins/specweave-figma/skills/figma-to-code/test-3-typescript-generation.yaml +28 -0
- package/plugins/specweave-frontend/.claude-plugin/plugin.json +8 -0
- package/plugins/specweave-github/.claude-plugin/plugin.json +8 -0
- package/plugins/specweave-github/agents/github-manager/AGENT.md +651 -0
- package/plugins/specweave-github/commands/github-close-issue.md +418 -0
- package/plugins/specweave-github/commands/github-create-issue.md +307 -0
- package/plugins/specweave-github/commands/github-status.md +533 -0
- package/plugins/specweave-github/commands/github-sync-tasks.md +530 -0
- package/plugins/specweave-github/commands/github-sync.md +443 -0
- package/plugins/specweave-github/lib/github-client.ts +330 -0
- package/plugins/specweave-github/lib/index.ts +10 -0
- package/plugins/specweave-github/lib/subtask-sync.ts +225 -0
- package/plugins/specweave-github/lib/task-parser.ts +246 -0
- package/plugins/specweave-github/lib/task-sync.ts +402 -0
- package/plugins/specweave-github/lib/types.ts +86 -0
- package/plugins/specweave-github/skills/github-issue-tracker/SKILL.md +497 -0
- package/plugins/specweave-github/skills/github-sync/SKILL.md +461 -0
- package/plugins/specweave-infrastructure/.claude-plugin/plugin.json +8 -0
- package/plugins/specweave-jira/.claude-plugin/plugin.json +8 -0
- package/{src ā plugins/specweave-jira}/commands/specweave.sync-jira.md +18 -18
- package/plugins/specweave-kubernetes/.claude-plugin/plugin.json +8 -0
- package/plugins/specweave-ml/.claude-plugin/plugin.json +39 -0
- package/plugins/specweave-ml/README.md +885 -0
- package/plugins/specweave-ml/agents/ml-engineer/AGENT.md +402 -0
- package/plugins/specweave-ml/commands/ml-deploy.md +116 -0
- package/plugins/specweave-ml/commands/ml-evaluate.md +87 -0
- package/plugins/specweave-ml/commands/ml-explain.md +83 -0
- package/plugins/specweave-ml/skills/anomaly-detector/SKILL.md +559 -0
- package/plugins/specweave-ml/skills/automl-optimizer/SKILL.md +485 -0
- package/plugins/specweave-ml/skills/cv-pipeline-builder/SKILL.md +157 -0
- package/plugins/specweave-ml/skills/data-visualizer/SKILL.md +521 -0
- package/plugins/specweave-ml/skills/experiment-tracker/SKILL.md +535 -0
- package/plugins/specweave-ml/skills/feature-engineer/SKILL.md +566 -0
- package/plugins/specweave-ml/skills/ml-deployment-helper/SKILL.md +345 -0
- package/plugins/specweave-ml/skills/ml-pipeline-orchestrator/SKILL.md +518 -0
- package/plugins/specweave-ml/skills/model-evaluator/SKILL.md +155 -0
- package/plugins/specweave-ml/skills/model-explainer/SKILL.md +227 -0
- package/plugins/specweave-ml/skills/model-registry/SKILL.md +541 -0
- package/plugins/specweave-ml/skills/nlp-pipeline-builder/SKILL.md +180 -0
- package/plugins/specweave-ml/skills/time-series-forecaster/SKILL.md +569 -0
- package/plugins/specweave-payments/.claude-plugin/plugin.json +8 -0
- package/plugins/specweave-testing/.claude-plugin/plugin.json +8 -0
- package/plugins/specweave-tooling/.claude-plugin/plugin.json +8 -0
- package/plugins/specweave-ui/.claude-plugin/plugin.json +106 -0
- package/plugins/specweave-ui/.mcp.json +14 -0
- package/plugins/specweave-ui/README.md +386 -0
- package/src/adapters/adapter-base.ts +33 -0
- package/src/adapters/adapter-interface.ts +46 -0
- package/src/adapters/claude/adapter.ts +350 -39
- package/src/adapters/copilot/adapter.ts +267 -4
- package/src/adapters/cursor/adapter.ts +229 -0
- package/src/adapters/generic/adapter.ts +196 -0
- package/src/templates/AGENTS.md.template +170 -1
- package/src/templates/CLAUDE.md.template +122 -24
- package/src/templates/tasks.md.template +261 -0
- package/src/agents/ml-engineer/AGENT.md +0 -150
- package/src/commands/specweave.sync-github.md +0 -269
- package/src/hooks/post-task-completion.sh +0 -79
- package/src/skills/SKILLS-INDEX.md +0 -444
- package/src/skills/github-sync/SKILL.md +0 -234
- /package/{src ā plugins/specweave-ado}/skills/ado-sync/README.md +0 -0
- /package/{src ā plugins/specweave-ado}/skills/ado-sync/SKILL.md +0 -0
- /package/{src ā plugins/specweave-ado}/skills/specweave-ado-mapper/SKILL.md +0 -0
- /package/{src ā plugins/specweave-backend}/agents/database-optimizer/AGENT.md +0 -0
- /package/{src ā plugins/specweave-backend}/skills/dotnet-backend/SKILL.md +0 -0
- /package/{src ā plugins/specweave-backend}/skills/nodejs-backend/SKILL.md +0 -0
- /package/{src ā plugins/specweave-backend}/skills/python-backend/SKILL.md +0 -0
- /package/{src ā plugins/specweave-core}/agents/architect/AGENT.md +0 -0
- /package/{src ā plugins/specweave-core}/agents/code-reviewer.md +0 -0
- /package/{src ā plugins/specweave-core}/agents/docs-writer/AGENT.md +0 -0
- /package/{src ā plugins/specweave-core}/agents/performance/AGENT.md +0 -0
- /package/{src ā plugins/specweave-core}/agents/qa-lead/AGENT.md +0 -0
- /package/{src ā plugins/specweave-core}/agents/security/AGENT.md +0 -0
- /package/{src ā plugins/specweave-core}/agents/tdd-orchestrator/AGENT.md +0 -0
- /package/{src ā plugins/specweave-core}/agents/tech-lead/AGENT.md +0 -0
- /package/{src ā plugins/specweave-core}/commands/specweave.done.md +0 -0
- /package/{src ā plugins/specweave-core}/commands/specweave.inc.md +0 -0
- /package/{src ā plugins/specweave-core}/commands/specweave.list-increments.md +0 -0
- /package/{src ā plugins/specweave-core}/commands/specweave.next.md +0 -0
- /package/{src ā plugins/specweave-core}/commands/specweave.progress.md +0 -0
- /package/{src ā plugins/specweave-core}/commands/specweave.tdd-cycle.md +0 -0
- /package/{src ā plugins/specweave-core}/commands/specweave.tdd-green.md +0 -0
- /package/{src ā plugins/specweave-core}/commands/specweave.tdd-red.md +0 -0
- /package/{src ā plugins/specweave-core}/commands/specweave.tdd-refactor.md +0 -0
- /package/{src ā plugins/specweave-core}/hooks/README.md +0 -0
- /package/{src ā plugins/specweave-core}/hooks/docs-changed.sh +0 -0
- /package/{src ā plugins/specweave-core}/hooks/human-input-required.sh +0 -0
- /package/{src ā plugins/specweave-core}/hooks/pre-implementation.sh +0 -0
- /package/{src ā plugins/specweave-core}/skills/brownfield-onboarder/SKILL.md +0 -0
- /package/{src ā plugins/specweave-core}/skills/docs-updater/README.md +0 -0
- /package/{src ā plugins/specweave-core}/skills/increment-planner/scripts/feature-utils.js +0 -0
- /package/{src ā plugins/specweave-core}/skills/increment-quality-judge/SKILL.md +0 -0
- /package/{src ā plugins/specweave-core}/skills/project-kickstarter/test-cases/test-1-high-confidence-full-product.yaml +0 -0
- /package/{src ā plugins/specweave-core}/skills/project-kickstarter/test-cases/test-2-medium-confidence-partial.yaml +0 -0
- /package/{src ā plugins/specweave-core}/skills/project-kickstarter/test-cases/test-3-low-confidence-technical-question.yaml +0 -0
- /package/{src ā plugins/specweave-core}/skills/project-kickstarter/test-cases/test-4-opt-out-explicit.yaml +0 -0
- /package/{src ā plugins/specweave-core}/skills/role-orchestrator/README.md +0 -0
- /package/{src ā plugins/specweave-core}/skills/role-orchestrator/SKILL.md +0 -0
- /package/{src ā plugins/specweave-core}/skills/task-builder/README.md +0 -0
- /package/{src ā plugins/specweave-cost-optimizer}/skills/cost-optimizer/SKILL.md +0 -0
- /package/{src ā plugins/specweave-diagrams}/agents/diagrams-architect/AGENT.md +0 -0
- /package/{src ā plugins/specweave-diagrams}/agents/diagrams-architect/templates/c4-component-template.mmd +0 -0
- /package/{src ā plugins/specweave-diagrams}/agents/diagrams-architect/templates/c4-container-template.mmd +0 -0
- /package/{src ā plugins/specweave-diagrams}/agents/diagrams-architect/templates/c4-context-template.mmd +0 -0
- /package/{src ā plugins/specweave-diagrams}/agents/diagrams-architect/templates/deployment-template.mmd +0 -0
- /package/{src ā plugins/specweave-diagrams}/agents/diagrams-architect/templates/er-diagram-template.mmd +0 -0
- /package/{src ā plugins/specweave-diagrams}/agents/diagrams-architect/templates/sequence-template.mmd +0 -0
- /package/{src ā plugins/specweave-diagrams}/agents/diagrams-architect/test-cases/test-1-c4-context.yaml +0 -0
- /package/{src ā plugins/specweave-diagrams}/agents/diagrams-architect/test-cases/test-2-sequence.yaml +0 -0
- /package/{src ā plugins/specweave-diagrams}/agents/diagrams-architect/test-cases/test-3-er-diagram.yaml +0 -0
- /package/{src ā plugins/specweave-diagrams}/skills/diagrams-architect/SKILL.md +0 -0
- /package/{src ā plugins/specweave-diagrams}/skills/diagrams-generator/SKILL.md +0 -0
- /package/{src ā plugins/specweave-docs}/skills/spec-driven-brainstorming/README.md +0 -0
- /package/{src ā plugins/specweave-docs}/skills/spec-driven-brainstorming/SKILL.md +0 -0
- /package/{src ā plugins/specweave-docs}/skills/spec-driven-debugging/README.md +0 -0
- /package/{src ā plugins/specweave-docs}/skills/spec-driven-debugging/SKILL.md +0 -0
- /package/{src ā plugins/specweave-frontend}/skills/design-system-architect/SKILL.md +0 -0
- /package/{src ā plugins/specweave-frontend}/skills/frontend/SKILL.md +0 -0
- /package/{src ā plugins/specweave-frontend}/skills/nextjs/SKILL.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/devops/AGENT.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/network-engineer/AGENT.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/observability-engineer/AGENT.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/performance-engineer/AGENT.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/AGENT.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/modules/backend-diagnostics.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/modules/database-diagnostics.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/modules/infrastructure.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/modules/monitoring.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/modules/security-incidents.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/modules/ui-diagnostics.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/playbooks/01-high-cpu-usage.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/playbooks/02-database-deadlock.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/playbooks/03-memory-leak.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/playbooks/04-slow-api-response.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/playbooks/05-ddos-attack.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/playbooks/06-disk-full.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/playbooks/07-service-down.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/playbooks/08-data-corruption.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/playbooks/09-cascade-failure.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/playbooks/10-rate-limit-exceeded.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/scripts/health-check.sh +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/scripts/log-analyzer.py +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/scripts/metrics-collector.sh +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/scripts/trace-analyzer.js +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/templates/incident-report.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/templates/mitigation-plan.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/templates/post-mortem.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/agents/sre/templates/runbook-template.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/commands/specweave.monitor-setup.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/commands/specweave.slo-implement.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/skills/distributed-tracing/SKILL.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/skills/grafana-dashboards/SKILL.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/skills/hetzner-provisioner/README.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/skills/hetzner-provisioner/SKILL.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/skills/prometheus-configuration/SKILL.md +0 -0
- /package/{src ā plugins/specweave-infrastructure}/skills/slo-implementation/SKILL.md +0 -0
- /package/{src ā plugins/specweave-jira}/skills/jira-sync/README.md +0 -0
- /package/{src ā plugins/specweave-jira}/skills/jira-sync/SKILL.md +0 -0
- /package/{src ā plugins/specweave-jira}/skills/specweave-jira-mapper/SKILL.md +0 -0
- /package/{src ā plugins/specweave-kubernetes}/agents/kubernetes-architect/AGENT.md +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/gitops-workflow/SKILL.md +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/gitops-workflow/references/argocd-setup.md +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/gitops-workflow/references/sync-policies.md +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/helm-chart-scaffolding/SKILL.md +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/helm-chart-scaffolding/assets/Chart.yaml.template +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/helm-chart-scaffolding/assets/values.yaml.template +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/helm-chart-scaffolding/references/chart-structure.md +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/helm-chart-scaffolding/scripts/validate-chart.sh +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/k8s-manifest-generator/SKILL.md +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/k8s-manifest-generator/assets/configmap-template.yaml +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/k8s-manifest-generator/assets/deployment-template.yaml +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/k8s-manifest-generator/assets/service-template.yaml +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/k8s-manifest-generator/references/deployment-spec.md +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/k8s-manifest-generator/references/service-spec.md +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/k8s-security-policies/SKILL.md +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/k8s-security-policies/assets/network-policy-template.yaml +0 -0
- /package/{src ā plugins/specweave-kubernetes}/skills/k8s-security-policies/references/rbac-patterns.md +0 -0
- /package/{src ā plugins/specweave-ml}/agents/data-scientist/AGENT.md +0 -0
- /package/{src ā plugins/specweave-ml}/agents/mlops-engineer/AGENT.md +0 -0
- /package/{src ā plugins/specweave-ml}/commands/specweave.ml-pipeline.md +0 -0
- /package/{src ā plugins/specweave-ml}/skills/ml-pipeline-workflow/SKILL.md +0 -0
- /package/{src ā plugins/specweave-payments}/agents/payment-integration/AGENT.md +0 -0
- /package/{src ā plugins/specweave-payments}/skills/billing-automation/SKILL.md +0 -0
- /package/{src ā plugins/specweave-payments}/skills/paypal-integration/SKILL.md +0 -0
- /package/{src ā plugins/specweave-payments}/skills/pci-compliance/SKILL.md +0 -0
- /package/{src ā plugins/specweave-payments}/skills/stripe-integration/SKILL.md +0 -0
- /package/{src ā plugins/specweave-testing}/skills/e2e-playwright/README.md +0 -0
- /package/{src ā plugins/specweave-testing}/skills/e2e-playwright/SKILL.md +0 -0
- /package/{src ā plugins/specweave-testing}/skills/e2e-playwright/execute.js +0 -0
- /package/{src ā plugins/specweave-testing}/skills/e2e-playwright/lib/utils.js +0 -0
- /package/{src ā plugins/specweave-testing}/skills/e2e-playwright/package.json +0 -0
- /package/{src ā plugins/specweave-tooling}/skills/skill-creator/LICENSE.txt +0 -0
- /package/{src ā plugins/specweave-tooling}/skills/skill-creator/SKILL.md +0 -0
- /package/{src ā plugins/specweave-tooling}/skills/skill-creator/scripts/init_skill.py +0 -0
- /package/{src ā plugins/specweave-tooling}/skills/skill-creator/scripts/package_skill.py +0 -0
- /package/{src ā plugins/specweave-tooling}/skills/skill-creator/scripts/quick_validate.py +0 -0
- /package/{src ā plugins/specweave-tooling}/skills/skill-router/SKILL.md +0 -0
|
@@ -9,9 +9,24 @@ import { ClaudeMdGenerator } from '../../adapters/claude-md-generator.js';
|
|
|
9
9
|
import { AgentsMdGenerator } from '../../adapters/agents-md-generator.js';
|
|
10
10
|
import { getDirname } from '../../utils/esm-helpers.js';
|
|
11
11
|
import { generateSkillsIndex } from '../../utils/generate-skills-index.js';
|
|
12
|
+
import { LanguageManager, isLanguageSupported, getSupportedLanguages, getSystemPromptForLanguage } from '../../core/i18n/language-manager.js';
|
|
13
|
+
import { getLocaleManager } from '../../core/i18n/locale-manager.js';
|
|
12
14
|
const __dirname = getDirname(import.meta.url);
|
|
13
15
|
export async function initCommand(projectName, options = {}) {
|
|
14
|
-
|
|
16
|
+
// Validate and normalize language option
|
|
17
|
+
const language = options.language?.toLowerCase() || 'en';
|
|
18
|
+
// Validate language if provided
|
|
19
|
+
if (options.language && !isLanguageSupported(language)) {
|
|
20
|
+
const locale = getLocaleManager('en'); // Use English for error messages about invalid language
|
|
21
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.invalidLanguage', { language: options.language })}`));
|
|
22
|
+
console.error(chalk.yellow(`${locale.t('cli', 'init.errors.supportedLanguages', { languages: getSupportedLanguages().join(', ') })}\n`));
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
// Initialize LanguageManager and LocaleManager
|
|
26
|
+
const i18n = new LanguageManager({ defaultLanguage: language });
|
|
27
|
+
const locale = getLocaleManager(language);
|
|
28
|
+
// Display welcome message in user's language
|
|
29
|
+
console.log(chalk.blue.bold(`\n${locale.t('cli', 'init.welcome')}\n`));
|
|
15
30
|
let targetDir;
|
|
16
31
|
let finalProjectName;
|
|
17
32
|
let usedDotNotation = false;
|
|
@@ -22,7 +37,7 @@ export async function initCommand(projectName, options = {}) {
|
|
|
22
37
|
const dirName = path.basename(targetDir);
|
|
23
38
|
// Validate directory name is suitable for project name
|
|
24
39
|
if (!/^[a-z0-9-]+$/.test(dirName)) {
|
|
25
|
-
console.log(chalk.yellow(`\n
|
|
40
|
+
console.log(chalk.yellow(`\n${locale.t('cli', 'init.warnings.invalidDirName', { dirName })}`));
|
|
26
41
|
const suggestedName = dirName.toLowerCase().replace(/[^a-z0-9-]/g, '-');
|
|
27
42
|
const { name } = await inquirer.prompt([
|
|
28
43
|
{
|
|
@@ -46,7 +61,7 @@ export async function initCommand(projectName, options = {}) {
|
|
|
46
61
|
const allFiles = fs.readdirSync(targetDir);
|
|
47
62
|
const existingFiles = allFiles.filter(f => !f.startsWith('.')); // Ignore hidden files
|
|
48
63
|
if (existingFiles.length > 0) {
|
|
49
|
-
console.log(chalk.yellow(`\n
|
|
64
|
+
console.log(chalk.yellow(`\n${locale.t('cli', 'init.warnings.directoryNotEmpty', { count: existingFiles.length, plural: existingFiles.length === 1 ? '' : 's' })}`));
|
|
50
65
|
const { confirm } = await inquirer.prompt([
|
|
51
66
|
{
|
|
52
67
|
type: 'confirm',
|
|
@@ -56,7 +71,7 @@ export async function initCommand(projectName, options = {}) {
|
|
|
56
71
|
},
|
|
57
72
|
]);
|
|
58
73
|
if (!confirm) {
|
|
59
|
-
console.log(chalk.yellow('
|
|
74
|
+
console.log(chalk.yellow(locale.t('cli', 'init.errors.cancelled')));
|
|
60
75
|
process.exit(0);
|
|
61
76
|
}
|
|
62
77
|
}
|
|
@@ -71,7 +86,7 @@ export async function initCommand(projectName, options = {}) {
|
|
|
71
86
|
},
|
|
72
87
|
]);
|
|
73
88
|
if (!overwrite) {
|
|
74
|
-
console.log(chalk.yellow('
|
|
89
|
+
console.log(chalk.yellow(locale.t('cli', 'init.errors.cancelled')));
|
|
75
90
|
process.exit(0);
|
|
76
91
|
}
|
|
77
92
|
fs.removeSync(path.join(targetDir, '.specweave'));
|
|
@@ -112,7 +127,7 @@ export async function initCommand(projectName, options = {}) {
|
|
|
112
127
|
},
|
|
113
128
|
]);
|
|
114
129
|
if (!overwrite) {
|
|
115
|
-
console.log(chalk.yellow('
|
|
130
|
+
console.log(chalk.yellow(locale.t('cli', 'init.errors.cancelled')));
|
|
116
131
|
process.exit(0);
|
|
117
132
|
}
|
|
118
133
|
fs.emptyDirSync(targetDir);
|
|
@@ -121,9 +136,29 @@ export async function initCommand(projectName, options = {}) {
|
|
|
121
136
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
122
137
|
}
|
|
123
138
|
}
|
|
139
|
+
// 3. Check for nested .specweave/ (CRITICAL: prevent nested folders)
|
|
140
|
+
const parentSpecweave = detectNestedSpecweave(targetDir);
|
|
141
|
+
if (parentSpecweave) {
|
|
142
|
+
console.log('');
|
|
143
|
+
console.log(chalk.red.bold(locale.t('cli', 'init.errors.nestedNotSupported')));
|
|
144
|
+
console.log('');
|
|
145
|
+
console.log(chalk.yellow(` ${locale.t('cli', 'init.errors.parentFound')}`));
|
|
146
|
+
console.log(chalk.white(` ${parentSpecweave}`));
|
|
147
|
+
console.log('');
|
|
148
|
+
console.log(chalk.cyan(` ${locale.t('cli', 'init.info.nestedEnforcement')}`));
|
|
149
|
+
console.log(chalk.gray(` ${locale.t('cli', 'init.info.nestedBullet1')}`));
|
|
150
|
+
console.log(chalk.gray(` ${locale.t('cli', 'init.info.nestedBullet2')}`));
|
|
151
|
+
console.log(chalk.gray(` ${locale.t('cli', 'init.info.nestedBullet3')}`));
|
|
152
|
+
console.log('');
|
|
153
|
+
console.log(chalk.cyan(` ${locale.t('cli', 'init.info.nestedToFix')}`));
|
|
154
|
+
console.log(chalk.white(` ${locale.t('cli', 'init.nestedCdCommand', { path: parentSpecweave })}`));
|
|
155
|
+
console.log(chalk.white(` ${locale.t('cli', 'init.nestedIncCommand')}`));
|
|
156
|
+
console.log('');
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
124
159
|
const spinner = ora('Creating SpecWeave project...').start();
|
|
125
160
|
try {
|
|
126
|
-
//
|
|
161
|
+
// 4. Detect or select tool
|
|
127
162
|
const adapterLoader = new AdapterLoader();
|
|
128
163
|
let toolName;
|
|
129
164
|
if (options.adapter) {
|
|
@@ -140,54 +175,72 @@ export async function initCommand(projectName, options = {}) {
|
|
|
140
175
|
// 4. Create directory structure (same for all)
|
|
141
176
|
createDirectoryStructure(targetDir);
|
|
142
177
|
spinner.text = 'Directory structure created...';
|
|
143
|
-
// 5. Copy
|
|
178
|
+
// 5. Copy plugin marketplace (for Claude Code auto-registration)
|
|
179
|
+
if (toolName === 'claude') {
|
|
180
|
+
try {
|
|
181
|
+
const sourceMarketplace = findSourceDir('.claude-plugin');
|
|
182
|
+
const targetMarketplace = path.join(targetDir, '.claude-plugin');
|
|
183
|
+
if (fs.existsSync(sourceMarketplace)) {
|
|
184
|
+
fs.copySync(sourceMarketplace, targetMarketplace, {
|
|
185
|
+
overwrite: true,
|
|
186
|
+
errorOnExist: false
|
|
187
|
+
});
|
|
188
|
+
spinner.text = 'Plugin marketplace copied...';
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
// Non-critical - plugins can still be installed manually
|
|
193
|
+
console.warn(chalk.yellow(`\n${locale.t('cli', 'init.warnings.marketplaceCopyFailed')}`));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// 6. Copy base templates (config, README, CLAUDE.md - same for all)
|
|
144
197
|
const templatesDir = findSourceDir('templates');
|
|
145
|
-
await copyTemplates(templatesDir, targetDir, finalProjectName);
|
|
198
|
+
await copyTemplates(templatesDir, targetDir, finalProjectName, language);
|
|
146
199
|
spinner.text = 'Base templates copied...';
|
|
147
200
|
// 6. Install based on tool
|
|
148
201
|
if (toolName === 'claude') {
|
|
149
202
|
// DEFAULT: Native Claude Code installation (no adapter needed!)
|
|
150
203
|
spinner.text = 'Installing Claude Code components...';
|
|
151
204
|
try {
|
|
152
|
-
copyCommands('', path.join(targetDir, '.claude/commands'));
|
|
205
|
+
copyCommands('', path.join(targetDir, '.claude/commands'), language);
|
|
153
206
|
spinner.text = 'Slash commands installed...';
|
|
154
207
|
}
|
|
155
208
|
catch (error) {
|
|
156
209
|
spinner.fail('Failed to copy commands');
|
|
157
|
-
console.error(chalk.red(`\n
|
|
210
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.commandsCopyFailed', { error: error.message })}`));
|
|
158
211
|
throw error;
|
|
159
212
|
}
|
|
160
213
|
try {
|
|
161
|
-
copyAgents('', path.join(targetDir, '.claude/agents'));
|
|
214
|
+
copyAgents('', path.join(targetDir, '.claude/agents'), language);
|
|
162
215
|
spinner.text = 'Agents installed...';
|
|
163
216
|
}
|
|
164
217
|
catch (error) {
|
|
165
218
|
spinner.fail('Failed to copy agents');
|
|
166
|
-
console.error(chalk.red(`\n
|
|
219
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.agentsCopyFailed', { error: error.message })}`));
|
|
167
220
|
throw error;
|
|
168
221
|
}
|
|
169
222
|
try {
|
|
170
|
-
copySkills('', path.join(targetDir, '.claude/skills'));
|
|
223
|
+
copySkills('', path.join(targetDir, '.claude/skills'), language);
|
|
171
224
|
spinner.text = 'Skills installed...';
|
|
172
225
|
}
|
|
173
226
|
catch (error) {
|
|
174
227
|
spinner.fail('Failed to copy skills');
|
|
175
|
-
console.error(chalk.red(`\n
|
|
228
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.skillsCopyFailed', { error: error.message })}`));
|
|
176
229
|
throw error;
|
|
177
230
|
}
|
|
178
231
|
try {
|
|
179
|
-
copyHooks('', path.join(targetDir, '.claude/hooks'));
|
|
232
|
+
copyHooks('', path.join(targetDir, '.claude/hooks'), language);
|
|
180
233
|
spinner.text = 'Hooks installed...';
|
|
181
234
|
}
|
|
182
235
|
catch (error) {
|
|
183
236
|
spinner.fail('Failed to copy hooks');
|
|
184
|
-
console.error(chalk.red(`\n
|
|
237
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.hooksCopyFailed', { error: error.message })}`));
|
|
185
238
|
throw error;
|
|
186
239
|
}
|
|
187
240
|
try {
|
|
188
241
|
spinner.text = 'Generating skills index...';
|
|
189
|
-
// Generate skills index and copy to target
|
|
190
|
-
const sourceIndexPath = path.join(__dirname, '../../../
|
|
242
|
+
// Generate skills index and copy to target (root-level after v0.5.0)
|
|
243
|
+
const sourceIndexPath = path.join(__dirname, '../../../skills/SKILLS-INDEX.md');
|
|
191
244
|
await generateSkillsIndex(sourceIndexPath);
|
|
192
245
|
// Copy index to target .claude/skills/
|
|
193
246
|
const targetIndexPath = path.join(targetDir, '.claude/skills/SKILLS-INDEX.md');
|
|
@@ -196,11 +249,11 @@ export async function initCommand(projectName, options = {}) {
|
|
|
196
249
|
}
|
|
197
250
|
catch (error) {
|
|
198
251
|
// Non-critical error - don't fail installation
|
|
199
|
-
console.warn(chalk.yellow(`\n
|
|
200
|
-
console.warn(chalk.yellow('
|
|
252
|
+
console.warn(chalk.yellow(`\n${locale.t('cli', 'init.warnings.skillsIndexWarning', { error: error.message })}`));
|
|
253
|
+
console.warn(chalk.yellow(` ${locale.t('cli', 'init.warnings.skillsIndexNote')}`));
|
|
201
254
|
}
|
|
202
|
-
console.log('
|
|
203
|
-
console.log('
|
|
255
|
+
console.log(`\n${locale.t('cli', 'init.claudeNativeComplete')}`);
|
|
256
|
+
console.log(` ${locale.t('cli', 'init.claudeNativeBenefits')}`);
|
|
204
257
|
}
|
|
205
258
|
else {
|
|
206
259
|
// Use adapter for non-Claude tools
|
|
@@ -241,7 +294,54 @@ export async function initCommand(projectName, options = {}) {
|
|
|
241
294
|
spinner.text = 'Using existing Git repository...';
|
|
242
295
|
}
|
|
243
296
|
spinner.succeed('SpecWeave project created successfully!');
|
|
244
|
-
// 11.
|
|
297
|
+
// 11. Auto-detect and suggest plugins (T-018)
|
|
298
|
+
console.log('');
|
|
299
|
+
const pluginSpinner = ora('Detecting plugins...').start();
|
|
300
|
+
try {
|
|
301
|
+
const { PluginDetector } = await import('../../core/plugin-detector.js');
|
|
302
|
+
const { PluginManager } = await import('../../core/plugin-manager.js');
|
|
303
|
+
const detector = new PluginDetector();
|
|
304
|
+
const detectionResults = await detector.detectFromProject(targetDir);
|
|
305
|
+
const suggestedPlugins = detectionResults.map(r => r.pluginName);
|
|
306
|
+
pluginSpinner.succeed(`Detected ${suggestedPlugins.length} suggested plugins`);
|
|
307
|
+
if (suggestedPlugins.length > 0) {
|
|
308
|
+
console.log(chalk.cyan(`\n${locale.t('cli', 'init.info.suggestedPlugins')}`));
|
|
309
|
+
for (const pluginName of suggestedPlugins) {
|
|
310
|
+
console.log(` ⢠${chalk.white(pluginName)}`);
|
|
311
|
+
}
|
|
312
|
+
const { enablePlugins } = await inquirer.prompt([
|
|
313
|
+
{
|
|
314
|
+
type: 'confirm',
|
|
315
|
+
name: 'enablePlugins',
|
|
316
|
+
message: 'Enable suggested plugins now?',
|
|
317
|
+
default: true
|
|
318
|
+
}
|
|
319
|
+
]);
|
|
320
|
+
if (enablePlugins) {
|
|
321
|
+
const adapter = adapterLoader.getAdapter(toolName);
|
|
322
|
+
if (!adapter) {
|
|
323
|
+
throw new Error(`Adapter not found for tool: ${toolName}`);
|
|
324
|
+
}
|
|
325
|
+
const manager = new PluginManager(targetDir);
|
|
326
|
+
const enableSpinner = ora('Enabling plugins...').start();
|
|
327
|
+
for (const pluginName of suggestedPlugins) {
|
|
328
|
+
try {
|
|
329
|
+
await manager.loadPlugin(pluginName, adapter, { skipDependencies: false });
|
|
330
|
+
enableSpinner.text = `Enabled ${pluginName}`;
|
|
331
|
+
}
|
|
332
|
+
catch (error) {
|
|
333
|
+
enableSpinner.warn(`Failed to enable ${pluginName}: ${error instanceof Error ? error.message : error}`);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
enableSpinner.succeed('Plugins enabled');
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
catch (error) {
|
|
341
|
+
pluginSpinner.warn('Plugin detection skipped');
|
|
342
|
+
console.log(chalk.gray(` ${locale.t('cli', 'init.pluginEnableLater')}`));
|
|
343
|
+
}
|
|
344
|
+
// 12. Show tool-specific next steps
|
|
245
345
|
if (toolName !== 'claude') {
|
|
246
346
|
const adapter = adapterLoader.getAdapter(toolName);
|
|
247
347
|
if (adapter) {
|
|
@@ -253,11 +353,23 @@ export async function initCommand(projectName, options = {}) {
|
|
|
253
353
|
});
|
|
254
354
|
}
|
|
255
355
|
}
|
|
256
|
-
|
|
356
|
+
// 13. Create config.json with language setting
|
|
357
|
+
createConfigFile(targetDir, finalProjectName, toolName, language);
|
|
358
|
+
// 14. Setup Claude Code plugin auto-registration (if Claude detected)
|
|
359
|
+
if (toolName === 'claude') {
|
|
360
|
+
try {
|
|
361
|
+
setupClaudePluginAutoRegistration(targetDir, language);
|
|
362
|
+
}
|
|
363
|
+
catch (error) {
|
|
364
|
+
// Non-critical - show manual instructions in next steps
|
|
365
|
+
console.warn(chalk.yellow(`\n${locale.t('cli', 'init.warnings.pluginAutoSetupFailed')}`));
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
showNextSteps(finalProjectName, toolName, language, usedDotNotation);
|
|
257
369
|
}
|
|
258
370
|
catch (error) {
|
|
259
371
|
spinner.fail('Failed to create project');
|
|
260
|
-
console.error(chalk.red('
|
|
372
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.genericError')}`), error);
|
|
261
373
|
process.exit(1);
|
|
262
374
|
}
|
|
263
375
|
}
|
|
@@ -282,18 +394,19 @@ function createDirectoryStructure(targetDir) {
|
|
|
282
394
|
fs.mkdirSync(path.join(targetDir, dir), { recursive: true });
|
|
283
395
|
});
|
|
284
396
|
}
|
|
285
|
-
async function copyTemplates(templatesDir, targetDir, projectName) {
|
|
397
|
+
async function copyTemplates(templatesDir, targetDir, projectName, language = 'en') {
|
|
398
|
+
const locale = getLocaleManager(language);
|
|
286
399
|
// Verify templates directory exists
|
|
287
400
|
if (!fs.existsSync(templatesDir)) {
|
|
288
|
-
console.error(chalk.red(`\n
|
|
401
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.templatesNotFound', { path: templatesDir })}`));
|
|
289
402
|
const packageRoot = findPackageRoot(__dirname);
|
|
290
403
|
if (packageRoot) {
|
|
291
|
-
console.error(chalk.red(`
|
|
292
|
-
console.error(chalk.red(`
|
|
404
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.packageRoot', { root: packageRoot })}`));
|
|
405
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.tryingAlternate')}`));
|
|
293
406
|
// Try src/templates as fallback
|
|
294
407
|
const altPath = path.join(packageRoot, 'src', 'templates');
|
|
295
408
|
if (fs.existsSync(altPath)) {
|
|
296
|
-
console.error(chalk.yellow(`
|
|
409
|
+
console.error(chalk.yellow(` ${locale.t('cli', 'init.errors.foundTemplatesAt', { path: altPath })}`));
|
|
297
410
|
templatesDir = altPath;
|
|
298
411
|
}
|
|
299
412
|
else {
|
|
@@ -344,6 +457,33 @@ async function copyTemplates(templatesDir, targetDir, projectName) {
|
|
|
344
457
|
fs.copyFileSync(gitignoreTemplate, path.join(targetDir, '.gitignore'));
|
|
345
458
|
}
|
|
346
459
|
}
|
|
460
|
+
/**
|
|
461
|
+
* Detect if a parent directory contains a .specweave/ folder
|
|
462
|
+
* SpecWeave ONLY supports root-level .specweave/ folders
|
|
463
|
+
* Nested .specweave/ folders are NOT supported
|
|
464
|
+
*
|
|
465
|
+
* @param targetDir - Directory where user wants to initialize
|
|
466
|
+
* @returns Path to parent .specweave/ folder, or null if none found
|
|
467
|
+
*/
|
|
468
|
+
function detectNestedSpecweave(targetDir) {
|
|
469
|
+
// Start from parent of target directory
|
|
470
|
+
let currentDir = path.dirname(path.resolve(targetDir));
|
|
471
|
+
const root = path.parse(currentDir).root;
|
|
472
|
+
// Walk up the directory tree
|
|
473
|
+
while (currentDir !== root) {
|
|
474
|
+
const specweavePath = path.join(currentDir, '.specweave');
|
|
475
|
+
// Check if .specweave/ exists at this level
|
|
476
|
+
if (fs.existsSync(specweavePath)) {
|
|
477
|
+
return currentDir; // Found parent .specweave/
|
|
478
|
+
}
|
|
479
|
+
// Move up one level
|
|
480
|
+
const parentDir = path.dirname(currentDir);
|
|
481
|
+
if (parentDir === currentDir)
|
|
482
|
+
break; // Reached root
|
|
483
|
+
currentDir = parentDir;
|
|
484
|
+
}
|
|
485
|
+
return null; // No parent .specweave/ found
|
|
486
|
+
}
|
|
347
487
|
/**
|
|
348
488
|
* Find the package root by walking up the directory tree looking for package.json
|
|
349
489
|
* This works reliably on all platforms including Windows with UNC paths
|
|
@@ -416,63 +556,71 @@ function findSourceDir(relativePath) {
|
|
|
416
556
|
// If nothing found, return the first path and let the caller handle the error
|
|
417
557
|
return possiblePaths[0];
|
|
418
558
|
}
|
|
419
|
-
function copyCommands(commandsDir, targetCommandsDir) {
|
|
559
|
+
function copyCommands(commandsDir, targetCommandsDir, language) {
|
|
560
|
+
const locale = getLocaleManager(language);
|
|
420
561
|
const sourceDir = findSourceDir('commands');
|
|
421
562
|
if (!fs.existsSync(sourceDir)) {
|
|
422
|
-
console.error(chalk.red(`\n
|
|
423
|
-
console.error(chalk.red(`
|
|
424
|
-
console.error(chalk.red(`
|
|
563
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.sourceNotFound', { type: 'commands' })}`));
|
|
564
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.expectedAt', { path: sourceDir })}`));
|
|
565
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.dirname', { path: __dirname })}`));
|
|
425
566
|
const packageRoot = findPackageRoot(__dirname);
|
|
426
567
|
if (packageRoot) {
|
|
427
|
-
console.error(chalk.red(`
|
|
568
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.packageRoot', { root: packageRoot })}`));
|
|
428
569
|
}
|
|
429
570
|
else {
|
|
430
|
-
console.error(chalk.red(`
|
|
571
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.couldNotFindRoot')}`));
|
|
431
572
|
}
|
|
432
573
|
throw new Error('Failed to locate source commands directory. This may be a Windows path resolution issue.');
|
|
433
574
|
}
|
|
434
575
|
// Validate source directory contains files
|
|
435
576
|
const sourceFiles = fs.readdirSync(sourceDir).filter(f => f.endsWith('.md'));
|
|
436
577
|
if (sourceFiles.length === 0) {
|
|
437
|
-
console.error(chalk.red(`\n
|
|
438
|
-
console.error(chalk.red(`
|
|
439
|
-
console.error(chalk.red(`
|
|
578
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.sourceEmpty', { type: 'commands' })}`));
|
|
579
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.directory', { path: sourceDir })}`));
|
|
580
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.installationIssue')}`));
|
|
440
581
|
throw new Error('Source commands directory exists but contains no .md files');
|
|
441
582
|
}
|
|
442
583
|
try {
|
|
443
584
|
// Ensure target directory exists
|
|
444
585
|
fs.ensureDirSync(targetCommandsDir);
|
|
445
|
-
// Copy
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
586
|
+
// Copy each command file and inject system prompts if needed
|
|
587
|
+
for (const file of sourceFiles) {
|
|
588
|
+
const sourcePath = path.join(sourceDir, file);
|
|
589
|
+
const targetPath = path.join(targetCommandsDir, file);
|
|
590
|
+
// Read, potentially inject, and write
|
|
591
|
+
const content = fs.readFileSync(sourcePath, 'utf-8');
|
|
592
|
+
const modifiedContent = language !== 'en'
|
|
593
|
+
? injectSystemPromptForInit(content, language)
|
|
594
|
+
: content;
|
|
595
|
+
fs.writeFileSync(targetPath, modifiedContent, 'utf-8');
|
|
596
|
+
}
|
|
450
597
|
// Validate files were copied
|
|
451
598
|
const copiedFiles = fs.readdirSync(targetCommandsDir).filter(f => f.endsWith('.md'));
|
|
452
599
|
if (copiedFiles.length === 0) {
|
|
453
600
|
throw new Error(`Copy completed but no files found in target directory: ${targetCommandsDir}`);
|
|
454
601
|
}
|
|
455
|
-
console.log(chalk.gray(`
|
|
602
|
+
console.log(chalk.gray(` ${locale.t('cli', 'init.info.copiedFiles', { count: copiedFiles.length })}`));
|
|
456
603
|
}
|
|
457
604
|
catch (error) {
|
|
458
|
-
console.error(chalk.red(`\n
|
|
459
|
-
console.error(chalk.red(`
|
|
460
|
-
console.error(chalk.red(`
|
|
605
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.errorCopying', { type: 'commands', error: error.message })}`));
|
|
606
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.source', { path: sourceDir })}`));
|
|
607
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.target', { path: targetCommandsDir })}`));
|
|
461
608
|
throw error;
|
|
462
609
|
}
|
|
463
610
|
}
|
|
464
|
-
function copyAgents(agentsDir, targetAgentsDir) {
|
|
611
|
+
function copyAgents(agentsDir, targetAgentsDir, language) {
|
|
612
|
+
const locale = getLocaleManager(language);
|
|
465
613
|
const sourceDir = findSourceDir('agents');
|
|
466
614
|
if (!fs.existsSync(sourceDir)) {
|
|
467
|
-
console.error(chalk.red(`\n
|
|
468
|
-
console.error(chalk.red(`
|
|
469
|
-
console.error(chalk.red(`
|
|
615
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.sourceNotFound', { type: 'agents' })}`));
|
|
616
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.expectedAt', { path: sourceDir })}`));
|
|
617
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.dirname', { path: __dirname })}`));
|
|
470
618
|
const packageRoot = findPackageRoot(__dirname);
|
|
471
619
|
if (packageRoot) {
|
|
472
|
-
console.error(chalk.red(`
|
|
620
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.packageRoot', { root: packageRoot })}`));
|
|
473
621
|
}
|
|
474
622
|
else {
|
|
475
|
-
console.error(chalk.red(`
|
|
623
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.couldNotFindRoot')}`));
|
|
476
624
|
}
|
|
477
625
|
throw new Error('Failed to locate source agents directory. This may be a Windows path resolution issue.');
|
|
478
626
|
}
|
|
@@ -480,46 +628,81 @@ function copyAgents(agentsDir, targetAgentsDir) {
|
|
|
480
628
|
const agentDirs = fs.readdirSync(sourceDir, { withFileTypes: true })
|
|
481
629
|
.filter(dirent => dirent.isDirectory());
|
|
482
630
|
if (agentDirs.length === 0) {
|
|
483
|
-
console.error(chalk.red(`\n
|
|
484
|
-
console.error(chalk.red(`
|
|
485
|
-
console.error(chalk.red(`
|
|
631
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.sourceEmpty', { type: 'agents' })}`));
|
|
632
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.directory', { path: sourceDir })}`));
|
|
633
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.installationIssue')}`));
|
|
486
634
|
throw new Error('Source agents directory exists but contains no agent subdirectories');
|
|
487
635
|
}
|
|
488
636
|
try {
|
|
489
637
|
// Ensure target directory exists
|
|
490
638
|
fs.ensureDirSync(targetAgentsDir);
|
|
491
|
-
// Copy
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
639
|
+
// Copy each agent directory and inject system prompts if needed
|
|
640
|
+
for (const agentDir of agentDirs) {
|
|
641
|
+
const sourcePath = path.join(sourceDir, agentDir.name);
|
|
642
|
+
const targetPath = path.join(targetAgentsDir, agentDir.name);
|
|
643
|
+
// Copy entire agent directory first
|
|
644
|
+
fs.copySync(sourcePath, targetPath, {
|
|
645
|
+
overwrite: true,
|
|
646
|
+
errorOnExist: false
|
|
647
|
+
});
|
|
648
|
+
// Then inject system prompt into AGENT.md if language !== 'en'
|
|
649
|
+
if (language !== 'en') {
|
|
650
|
+
const agentMdPath = path.join(targetPath, 'AGENT.md');
|
|
651
|
+
if (fs.existsSync(agentMdPath)) {
|
|
652
|
+
const content = fs.readFileSync(agentMdPath, 'utf-8');
|
|
653
|
+
const modifiedContent = injectSystemPromptForInit(content, language);
|
|
654
|
+
fs.writeFileSync(agentMdPath, modifiedContent, 'utf-8');
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
496
658
|
// Validate subdirectories were copied
|
|
497
659
|
const copiedDirs = fs.readdirSync(targetAgentsDir, { withFileTypes: true })
|
|
498
660
|
.filter(dirent => dirent.isDirectory());
|
|
499
661
|
if (copiedDirs.length === 0) {
|
|
500
662
|
throw new Error(`Copy completed but no agent directories found in target: ${targetAgentsDir}`);
|
|
501
663
|
}
|
|
502
|
-
console.log(chalk.gray(`
|
|
664
|
+
console.log(chalk.gray(` ${locale.t('cli', 'init.info.copiedAgents', { count: copiedDirs.length })}`));
|
|
503
665
|
}
|
|
504
666
|
catch (error) {
|
|
505
|
-
console.error(chalk.red(`\n
|
|
506
|
-
console.error(chalk.red(`
|
|
507
|
-
console.error(chalk.red(`
|
|
667
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.errorCopying', { type: 'agents', error: error.message })}`));
|
|
668
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.source', { path: sourceDir })}`));
|
|
669
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.target', { path: targetAgentsDir })}`));
|
|
508
670
|
throw error;
|
|
509
671
|
}
|
|
510
672
|
}
|
|
511
|
-
|
|
673
|
+
/**
|
|
674
|
+
* Inject system prompt for non-English languages
|
|
675
|
+
*/
|
|
676
|
+
function injectSystemPromptForInit(content, language) {
|
|
677
|
+
if (language === 'en') {
|
|
678
|
+
return content; // No changes for English
|
|
679
|
+
}
|
|
680
|
+
const systemPrompt = getSystemPromptForLanguage(language);
|
|
681
|
+
// Inject after YAML frontmatter if present
|
|
682
|
+
if (content.startsWith('---')) {
|
|
683
|
+
const endOfFrontmatter = content.indexOf('---', 3);
|
|
684
|
+
if (endOfFrontmatter !== -1) {
|
|
685
|
+
const frontmatter = content.substring(0, endOfFrontmatter + 3);
|
|
686
|
+
const body = content.substring(endOfFrontmatter + 3);
|
|
687
|
+
return `${frontmatter}\n\n${systemPrompt}\n${body}`;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
// No frontmatter - inject at the top
|
|
691
|
+
return `${systemPrompt}\n\n${content}`;
|
|
692
|
+
}
|
|
693
|
+
function copySkills(skillsDir, targetSkillsDir, language) {
|
|
694
|
+
const locale = getLocaleManager(language);
|
|
512
695
|
const sourceDir = findSourceDir('skills');
|
|
513
696
|
if (!fs.existsSync(sourceDir)) {
|
|
514
|
-
console.error(chalk.red(`\n
|
|
515
|
-
console.error(chalk.red(`
|
|
516
|
-
console.error(chalk.red(`
|
|
697
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.sourceNotFound', { type: 'skills' })}`));
|
|
698
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.expectedAt', { path: sourceDir })}`));
|
|
699
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.dirname', { path: __dirname })}`));
|
|
517
700
|
const packageRoot = findPackageRoot(__dirname);
|
|
518
701
|
if (packageRoot) {
|
|
519
|
-
console.error(chalk.red(`
|
|
702
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.packageRoot', { root: packageRoot })}`));
|
|
520
703
|
}
|
|
521
704
|
else {
|
|
522
|
-
console.error(chalk.red(`
|
|
705
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.couldNotFindRoot')}`));
|
|
523
706
|
}
|
|
524
707
|
throw new Error('Failed to locate source skills directory. This may be a Windows path resolution issue.');
|
|
525
708
|
}
|
|
@@ -527,55 +710,70 @@ function copySkills(skillsDir, targetSkillsDir) {
|
|
|
527
710
|
const skillDirs = fs.readdirSync(sourceDir, { withFileTypes: true })
|
|
528
711
|
.filter(dirent => dirent.isDirectory());
|
|
529
712
|
if (skillDirs.length === 0) {
|
|
530
|
-
console.error(chalk.red(`\n
|
|
531
|
-
console.error(chalk.red(`
|
|
532
|
-
console.error(chalk.red(`
|
|
713
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.sourceEmpty', { type: 'skills' })}`));
|
|
714
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.directory', { path: sourceDir })}`));
|
|
715
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.installationIssue')}`));
|
|
533
716
|
throw new Error('Source skills directory exists but contains no skill subdirectories');
|
|
534
717
|
}
|
|
535
718
|
try {
|
|
536
719
|
// Ensure target directory exists
|
|
537
720
|
fs.ensureDirSync(targetSkillsDir);
|
|
538
|
-
// Copy
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
721
|
+
// Copy each skill directory and inject system prompts if needed
|
|
722
|
+
for (const skillDir of skillDirs) {
|
|
723
|
+
const sourcePath = path.join(sourceDir, skillDir.name);
|
|
724
|
+
const targetPath = path.join(targetSkillsDir, skillDir.name);
|
|
725
|
+
// Copy entire skill directory first
|
|
726
|
+
fs.copySync(sourcePath, targetPath, {
|
|
727
|
+
overwrite: true,
|
|
728
|
+
errorOnExist: false
|
|
729
|
+
});
|
|
730
|
+
// Then inject system prompt into SKILL.md if language !== 'en'
|
|
731
|
+
if (language !== 'en') {
|
|
732
|
+
const skillMdPath = path.join(targetPath, 'SKILL.md');
|
|
733
|
+
if (fs.existsSync(skillMdPath)) {
|
|
734
|
+
const content = fs.readFileSync(skillMdPath, 'utf-8');
|
|
735
|
+
const modifiedContent = injectSystemPromptForInit(content, language);
|
|
736
|
+
fs.writeFileSync(skillMdPath, modifiedContent, 'utf-8');
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
543
740
|
// Validate subdirectories were copied
|
|
544
741
|
const copiedDirs = fs.readdirSync(targetSkillsDir, { withFileTypes: true })
|
|
545
742
|
.filter(dirent => dirent.isDirectory());
|
|
546
743
|
if (copiedDirs.length === 0) {
|
|
547
744
|
throw new Error(`Copy completed but no skill directories found in target: ${targetSkillsDir}`);
|
|
548
745
|
}
|
|
549
|
-
console.log(chalk.gray(`
|
|
746
|
+
console.log(chalk.gray(` ${locale.t('cli', 'init.info.copiedSkills', { count: copiedDirs.length })}`));
|
|
550
747
|
}
|
|
551
748
|
catch (error) {
|
|
552
|
-
console.error(chalk.red(`\n
|
|
553
|
-
console.error(chalk.red(`
|
|
554
|
-
console.error(chalk.red(`
|
|
749
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.errorCopying', { type: 'skills', error: error.message })}`));
|
|
750
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.source', { path: sourceDir })}`));
|
|
751
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.target', { path: targetSkillsDir })}`));
|
|
555
752
|
throw error;
|
|
556
753
|
}
|
|
557
754
|
}
|
|
558
|
-
function copyHooks(hooksDir, targetHooksDir) {
|
|
755
|
+
function copyHooks(hooksDir, targetHooksDir, language = 'en') {
|
|
756
|
+
const locale = getLocaleManager(language);
|
|
559
757
|
const sourceDir = findSourceDir('hooks');
|
|
560
758
|
if (!fs.existsSync(sourceDir)) {
|
|
561
|
-
console.error(chalk.red(`\n
|
|
562
|
-
console.error(chalk.red(`
|
|
563
|
-
console.error(chalk.red(`
|
|
759
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.sourceNotFound', { type: 'hooks' })}`));
|
|
760
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.expectedAt', { path: sourceDir })}`));
|
|
761
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.dirname', { path: __dirname })}`));
|
|
564
762
|
const packageRoot = findPackageRoot(__dirname);
|
|
565
763
|
if (packageRoot) {
|
|
566
|
-
console.error(chalk.red(`
|
|
764
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.packageRoot', { root: packageRoot })}`));
|
|
567
765
|
}
|
|
568
766
|
else {
|
|
569
|
-
console.error(chalk.red(`
|
|
767
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.couldNotFindRoot')}`));
|
|
570
768
|
}
|
|
571
769
|
throw new Error('Failed to locate source hooks directory. This may be a Windows path resolution issue.');
|
|
572
770
|
}
|
|
573
771
|
// Validate source directory contains hook files
|
|
574
772
|
const hookFiles = fs.readdirSync(sourceDir).filter(f => f.endsWith('.sh') || f === 'README.md');
|
|
575
773
|
if (hookFiles.length === 0) {
|
|
576
|
-
console.error(chalk.red(`\n
|
|
577
|
-
console.error(chalk.red(`
|
|
578
|
-
console.error(chalk.red(`
|
|
774
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.sourceEmpty', { type: 'hooks' })}`));
|
|
775
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.directory', { path: sourceDir })}`));
|
|
776
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.installationIssue')}`));
|
|
579
777
|
throw new Error('Source hooks directory exists but contains no hook files');
|
|
580
778
|
}
|
|
581
779
|
try {
|
|
@@ -591,65 +789,136 @@ function copyHooks(hooksDir, targetHooksDir) {
|
|
|
591
789
|
if (copiedFiles.length === 0) {
|
|
592
790
|
throw new Error(`Copy completed but no hook files found in target: ${targetHooksDir}`);
|
|
593
791
|
}
|
|
594
|
-
console.log(chalk.gray(`
|
|
792
|
+
console.log(chalk.gray(` ${locale.t('cli', 'init.info.copiedHooks', { count: copiedFiles.length })}`));
|
|
595
793
|
}
|
|
596
794
|
catch (error) {
|
|
597
|
-
console.error(chalk.red(`\n
|
|
598
|
-
console.error(chalk.red(`
|
|
599
|
-
console.error(chalk.red(`
|
|
795
|
+
console.error(chalk.red(`\n${locale.t('cli', 'init.errors.errorCopying', { type: 'hooks', error: error.message })}`));
|
|
796
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.source', { path: sourceDir })}`));
|
|
797
|
+
console.error(chalk.red(` ${locale.t('cli', 'init.errors.target', { path: targetHooksDir })}`));
|
|
600
798
|
throw error;
|
|
601
799
|
}
|
|
602
800
|
}
|
|
603
|
-
|
|
801
|
+
/**
|
|
802
|
+
* Create .specweave/config.json with project settings
|
|
803
|
+
*/
|
|
804
|
+
function createConfigFile(targetDir, projectName, adapter, language) {
|
|
805
|
+
const configPath = path.join(targetDir, '.specweave', 'config.json');
|
|
806
|
+
const config = {
|
|
807
|
+
project: {
|
|
808
|
+
name: projectName,
|
|
809
|
+
version: '0.1.0',
|
|
810
|
+
},
|
|
811
|
+
adapters: {
|
|
812
|
+
default: adapter,
|
|
813
|
+
},
|
|
814
|
+
// Only include language if non-English
|
|
815
|
+
...(language !== 'en' && {
|
|
816
|
+
language,
|
|
817
|
+
translation: {
|
|
818
|
+
method: 'in-session',
|
|
819
|
+
autoTranslateLivingDocs: false,
|
|
820
|
+
keepFrameworkTerms: true,
|
|
821
|
+
keepTechnicalTerms: true,
|
|
822
|
+
translateCodeComments: true,
|
|
823
|
+
translateVariableNames: false,
|
|
824
|
+
},
|
|
825
|
+
}),
|
|
826
|
+
};
|
|
827
|
+
fs.writeJsonSync(configPath, config, { spaces: 2 });
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* Setup Claude Code automatic plugin registration
|
|
831
|
+
* Creates .claude/settings.json with extraKnownMarketplaces
|
|
832
|
+
* This triggers Claude's native auto-install when users trust the folder
|
|
833
|
+
*/
|
|
834
|
+
function setupClaudePluginAutoRegistration(targetDir, language) {
|
|
835
|
+
const locale = getLocaleManager(language);
|
|
836
|
+
const settingsPath = path.join(targetDir, '.claude', 'settings.json');
|
|
837
|
+
// Check if marketplace files exist
|
|
838
|
+
const marketplacePath = path.join(targetDir, '.claude-plugin', 'marketplace.json');
|
|
839
|
+
if (!fs.existsSync(marketplacePath)) {
|
|
840
|
+
console.log(chalk.yellow(`\n${locale.t('cli', 'init.warnings.marketplaceNotFound')}`));
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
// Create settings.json with marketplace registration
|
|
844
|
+
const settings = {
|
|
845
|
+
extraKnownMarketplaces: {
|
|
846
|
+
specweave: {
|
|
847
|
+
source: {
|
|
848
|
+
source: 'local',
|
|
849
|
+
path: './.claude-plugin'
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
};
|
|
854
|
+
try {
|
|
855
|
+
fs.writeJsonSync(settingsPath, settings, { spaces: 2 });
|
|
856
|
+
console.log(chalk.green(`\nā
${locale.t('cli', 'init.success.pluginAutoSetup')}`));
|
|
857
|
+
console.log(chalk.gray(` ${locale.t('cli', 'init.info.pluginAutoSetupDetails')}`));
|
|
858
|
+
}
|
|
859
|
+
catch (error) {
|
|
860
|
+
throw new Error(`Failed to create .claude/settings.json: ${error.message}`);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
function showNextSteps(projectName, adapterName, language, usedDotNotation = false) {
|
|
864
|
+
const locale = getLocaleManager(language);
|
|
604
865
|
console.log('');
|
|
605
|
-
console.log(chalk.cyan.bold('
|
|
866
|
+
console.log(chalk.cyan.bold(locale.t('cli', 'init.nextSteps.header')));
|
|
606
867
|
console.log('');
|
|
607
868
|
let stepNumber = 1;
|
|
608
869
|
// Only show "cd" step if we created a subdirectory
|
|
609
870
|
if (!usedDotNotation) {
|
|
610
|
-
console.log(` ${stepNumber}. ${chalk.white(
|
|
871
|
+
console.log(` ${stepNumber}. ${chalk.white(locale.t('cli', 'init.nextSteps.cd', { projectName }))}`);
|
|
611
872
|
console.log('');
|
|
612
873
|
stepNumber++;
|
|
613
874
|
}
|
|
614
875
|
// Adapter-specific instructions
|
|
615
876
|
if (adapterName === 'claude') {
|
|
616
|
-
console.log(` ${stepNumber}. ${chalk.white('
|
|
617
|
-
console.log(
|
|
877
|
+
console.log(` ${stepNumber}. ${chalk.white(locale.t('cli', 'init.nextSteps.claude.step1'))}`);
|
|
878
|
+
console.log('');
|
|
879
|
+
// CRITICAL STEP: Install core plugin (highlighted)
|
|
880
|
+
console.log(` ${stepNumber + 1}. ${chalk.yellow.bold('ā ļø ' + locale.t('cli', 'init.nextSteps.claude.step2'))}`);
|
|
881
|
+
console.log(` ${chalk.cyan.bold(locale.t('cli', 'init.nextSteps.claude.installCore'))}`);
|
|
882
|
+
console.log(` ${chalk.gray('ā Required for slash commands like /specweave:inc')}`);
|
|
883
|
+
console.log('');
|
|
884
|
+
console.log(` ${stepNumber + 2}. ${chalk.white(locale.t('cli', 'init.nextSteps.claude.step3'))}`);
|
|
885
|
+
console.log(` ${chalk.gray(locale.t('cli', 'init.nextSteps.claude.installGitHub'))}`);
|
|
886
|
+
console.log(` ${chalk.gray(locale.t('cli', 'init.nextSteps.claude.installFrontend'))}`);
|
|
887
|
+
console.log(` ${chalk.gray('...or let SpecWeave suggest plugins automatically')}`);
|
|
618
888
|
console.log('');
|
|
619
|
-
console.log(` ${stepNumber +
|
|
620
|
-
console.log('
|
|
621
|
-
console.log('
|
|
622
|
-
console.log(' ⢠Build implementation');
|
|
889
|
+
console.log(` ${stepNumber + 3}. ${chalk.white(locale.t('cli', 'init.nextSteps.claude.step4'))}`);
|
|
890
|
+
console.log(` ${chalk.cyan(locale.t('cli', 'init.nextSteps.claude.example'))}`);
|
|
891
|
+
console.log(` ${chalk.gray(locale.t('cli', 'init.nextSteps.claude.autoActivate'))}`);
|
|
623
892
|
}
|
|
624
893
|
else if (adapterName === 'cursor') {
|
|
625
|
-
console.log(` ${stepNumber}. ${chalk.white('
|
|
894
|
+
console.log(` ${stepNumber}. ${chalk.white(locale.t('cli', 'init.nextSteps.cursor.step1'))}`);
|
|
626
895
|
console.log('');
|
|
627
|
-
console.log(` ${stepNumber + 1}. ${chalk.white('
|
|
628
|
-
console.log(`
|
|
896
|
+
console.log(` ${stepNumber + 1}. ${chalk.white(locale.t('cli', 'init.nextSteps.cursor.step2'))}`);
|
|
897
|
+
console.log(` ${locale.t('cli', 'init.nextSteps.cursor.guide')}`);
|
|
629
898
|
console.log('');
|
|
630
|
-
console.log(` ${stepNumber + 2}. ${chalk.white('
|
|
631
|
-
console.log(`
|
|
899
|
+
console.log(` ${stepNumber + 2}. ${chalk.white(locale.t('cli', 'init.nextSteps.cursor.step3'))}`);
|
|
900
|
+
console.log(` ${locale.t('cli', 'init.nextSteps.cursor.shortcuts')}`);
|
|
632
901
|
}
|
|
633
902
|
else if (adapterName === 'copilot') {
|
|
634
|
-
console.log(` ${stepNumber}. ${chalk.white('
|
|
903
|
+
console.log(` ${stepNumber}. ${chalk.white(locale.t('cli', 'init.nextSteps.copilot.step1'))}`);
|
|
635
904
|
console.log('');
|
|
636
|
-
console.log(` ${stepNumber + 1}. ${chalk.white('
|
|
637
|
-
console.log(`
|
|
905
|
+
console.log(` ${stepNumber + 1}. ${chalk.white(locale.t('cli', 'init.nextSteps.copilot.step2'))}`);
|
|
906
|
+
console.log(` ${locale.t('cli', 'init.nextSteps.copilot.action')}`);
|
|
638
907
|
console.log('');
|
|
639
|
-
console.log(` ${stepNumber + 2}. ${chalk.white('
|
|
640
|
-
console.log(`
|
|
908
|
+
console.log(` ${stepNumber + 2}. ${chalk.white(locale.t('cli', 'init.nextSteps.copilot.step3'))}`);
|
|
909
|
+
console.log(` ${locale.t('cli', 'init.nextSteps.copilot.example')}`);
|
|
641
910
|
}
|
|
642
911
|
else if (adapterName === 'generic') {
|
|
643
|
-
console.log(` ${stepNumber}. ${chalk.white('
|
|
912
|
+
console.log(` ${stepNumber}. ${chalk.white(locale.t('cli', 'init.nextSteps.generic.step1'))}`);
|
|
644
913
|
console.log('');
|
|
645
|
-
console.log(` ${stepNumber + 1}. ${chalk.white('
|
|
646
|
-
console.log(`
|
|
914
|
+
console.log(` ${stepNumber + 1}. ${chalk.white(locale.t('cli', 'init.nextSteps.generic.step2'))}`);
|
|
915
|
+
console.log(` ${locale.t('cli', 'init.nextSteps.generic.compatibility')}`);
|
|
647
916
|
}
|
|
648
917
|
console.log('');
|
|
649
|
-
console.log(chalk.green.bold('
|
|
918
|
+
console.log(chalk.green.bold(locale.t('cli', 'init.nextSteps.footer')));
|
|
650
919
|
console.log('');
|
|
651
|
-
console.log(chalk.gray('
|
|
652
|
-
console.log(chalk.gray('
|
|
920
|
+
console.log(chalk.gray(locale.t('cli', 'init.nextSteps.docsLink')));
|
|
921
|
+
console.log(chalk.gray(locale.t('cli', 'init.nextSteps.githubLink')));
|
|
653
922
|
console.log('');
|
|
654
923
|
}
|
|
655
924
|
//# sourceMappingURL=init.js.map
|