bmad-method 5.1.2 → 6.0.0-alpha.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/.github/FUNDING.yaml +2 -2
- package/.github/ISSUE_TEMPLATE/config.yaml +1 -0
- package/.github/ISSUE_TEMPLATE/idea_submission.md +109 -0
- package/.github/workflows/discord.yaml +1 -10
- package/.github/workflows/format-check.yaml +3 -2
- package/.github/workflows/manual-release.yaml +2 -2
- package/.nvmrc +1 -0
- package/.vscode/settings.json +34 -9
- package/CHANGELOG.md +211 -577
- package/CONTRIBUTING.md +130 -60
- package/LICENSE +6 -1
- package/docs/codebase-flattener.md +19 -0
- package/docs/ide-info/auggie.md +31 -0
- package/docs/ide-info/claude-code.md +25 -0
- package/docs/ide-info/cline.md +31 -0
- package/docs/ide-info/codex.md +32 -0
- package/docs/ide-info/crush.md +30 -0
- package/docs/ide-info/cursor.md +25 -0
- package/docs/ide-info/gemini.md +25 -0
- package/docs/ide-info/github-copilot.md +26 -0
- package/docs/ide-info/iflow.md +33 -0
- package/docs/ide-info/kilo.md +24 -0
- package/docs/ide-info/qwen.md +25 -0
- package/docs/ide-info/roo.md +27 -0
- package/docs/ide-info/trae.md +25 -0
- package/docs/ide-info/windsurf.md +22 -0
- package/docs/installers-bundlers/ide-injections.md +196 -0
- package/docs/installers-bundlers/installers-modules-platforms-reference.md +355 -0
- package/docs/installers-bundlers/web-bundler-usage.md +54 -0
- package/eslint.config.mjs +17 -7
- package/package.json +26 -35
- package/prettier.config.mjs +1 -1
- package/readme.md +216 -0
- package/src/core/_module-installer/install-menu-config.yaml +24 -0
- package/src/core/_module-installer/installer.js +68 -0
- package/src/core/agents/bmad-master.md +27 -0
- package/src/core/agents/bmad-web-orchestrator.md +71 -0
- package/src/core/tasks/adv-elicit-methods.csv +39 -0
- package/src/core/tasks/adv-elicit.md +109 -0
- package/src/core/tasks/index-docs.md +69 -0
- package/src/core/tasks/shard-doc.md +57 -0
- package/src/core/tasks/validate-workflow.md +92 -0
- package/src/core/tasks/workflow.md +141 -0
- package/src/core/workflows/bmad-init/instructions.md +79 -0
- package/src/core/workflows/bmad-init/workflow.yaml +24 -0
- package/src/core/workflows/party-mode/instructions.md +181 -0
- package/src/core/workflows/party-mode/workflow.yaml +24 -0
- package/src/modules/bmb/_module-installer/install-menu-config.yaml +16 -0
- package/src/modules/bmb/agents/bmad-builder.md +30 -0
- package/src/modules/bmb/workflows/convert-legacy/README.md +262 -0
- package/src/modules/bmb/workflows/convert-legacy/checklist.md +204 -0
- package/src/modules/bmb/workflows/convert-legacy/instructions.md +328 -0
- package/src/modules/bmb/workflows/convert-legacy/workflow.yaml +35 -0
- package/src/modules/bmb/workflows/create-agent/README.md +268 -0
- package/src/modules/bmb/workflows/create-agent/agent-architecture.md +412 -0
- package/src/modules/bmb/workflows/create-agent/agent-command-patterns.md +757 -0
- package/src/modules/bmb/workflows/create-agent/agent-types.md +177 -0
- package/src/modules/bmb/workflows/create-agent/brainstorm-context.md +174 -0
- package/src/modules/bmb/workflows/create-agent/checklist.md +134 -0
- package/src/modules/bmb/workflows/create-agent/communication-styles.md +240 -0
- package/src/modules/bmb/workflows/create-agent/instructions.md +340 -0
- package/src/modules/bmb/workflows/create-agent/workflow.yaml +39 -0
- package/src/modules/bmb/workflows/create-module/README.md +218 -0
- package/src/modules/bmb/workflows/create-module/brainstorm-context.md +137 -0
- package/src/modules/bmb/workflows/create-module/checklist.md +245 -0
- package/src/modules/bmb/workflows/create-module/installer-templates/install-module-config.yaml +132 -0
- package/src/modules/bmb/workflows/create-module/installer-templates/installer.js +231 -0
- package/src/modules/bmb/workflows/create-module/instructions.md +509 -0
- package/src/modules/bmb/workflows/create-module/module-structure.md +310 -0
- package/src/modules/bmb/workflows/create-module/workflow.yaml +47 -0
- package/src/modules/bmb/workflows/create-workflow/README.md +216 -0
- package/src/modules/bmb/workflows/create-workflow/brainstorm-context.md +197 -0
- package/src/modules/bmb/workflows/create-workflow/checklist.md +72 -0
- package/src/modules/bmb/workflows/create-workflow/instructions.md +267 -0
- package/src/modules/bmb/workflows/create-workflow/workflow-creation-guide.md +456 -0
- package/src/modules/bmb/workflows/create-workflow/workflow-template/checklist.md +24 -0
- package/src/modules/bmb/workflows/create-workflow/workflow-template/instructions.md +12 -0
- package/src/modules/bmb/workflows/create-workflow/workflow-template/template.md +9 -0
- package/src/modules/bmb/workflows/create-workflow/workflow-template/workflow.yaml +35 -0
- package/src/modules/bmb/workflows/create-workflow/workflow.yaml +42 -0
- package/src/modules/bmb/workflows/edit-workflow/README.md +63 -0
- package/src/modules/bmb/workflows/edit-workflow/checklist.md +70 -0
- package/src/modules/bmb/workflows/edit-workflow/instructions.md +170 -0
- package/src/modules/bmb/workflows/edit-workflow/workflow.yaml +34 -0
- package/src/modules/bmb/workflows/module-brief/README.md +264 -0
- package/src/modules/bmb/workflows/module-brief/checklist.md +116 -0
- package/src/modules/bmb/workflows/module-brief/instructions.md +265 -0
- package/src/modules/bmb/workflows/module-brief/template.md +275 -0
- package/src/modules/bmb/workflows/module-brief/workflow.yaml +30 -0
- package/src/modules/bmb/workflows/redoc/README.md +87 -0
- package/src/modules/bmb/workflows/redoc/checklist.md +99 -0
- package/src/modules/bmb/workflows/redoc/instructions.md +255 -0
- package/src/modules/bmb/workflows/redoc/workflow.yaml +33 -0
- package/src/modules/bmm/_module-installer/assets/bmm-kb.md +1 -0
- package/src/modules/bmm/_module-installer/assets/technical-decisions-template.md +30 -0
- package/src/modules/bmm/_module-installer/install-menu-config.yaml +49 -0
- package/src/modules/bmm/_module-installer/installer.js +131 -0
- package/src/modules/bmm/_module-installer/platform-specifics/claude-code.js +35 -0
- package/src/modules/bmm/_module-installer/platform-specifics/windsurf.js +32 -0
- package/src/modules/bmm/agents/analyst.md +26 -0
- package/src/modules/bmm/agents/architect.md +29 -0
- package/src/modules/bmm/agents/dev.md +61 -0
- package/src/modules/bmm/agents/game-architect.md +26 -0
- package/src/modules/bmm/agents/game-designer.md +27 -0
- package/src/modules/bmm/agents/game-dev.md +28 -0
- package/src/modules/bmm/agents/pm.md +26 -0
- package/src/modules/bmm/agents/po.md +25 -0
- package/src/modules/bmm/agents/sm.md +29 -0
- package/src/modules/bmm/agents/tea.md +32 -0
- package/src/modules/bmm/agents/ux-expert.md +24 -0
- package/src/modules/bmm/sub-modules/claude-code/config.yaml +5 -0
- package/src/modules/bmm/sub-modules/claude-code/injections.yaml +242 -0
- package/src/modules/bmm/sub-modules/claude-code/readme.md +87 -0
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/api-documenter.md +85 -0
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/codebase-analyzer.md +64 -0
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/data-analyst.md +84 -0
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/dependency-mapper.md +67 -0
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/document-reviewer.md +85 -0
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/epic-optimizer.md +66 -0
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/market-researcher.md +34 -0
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/pattern-detector.md +67 -0
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/requirements-analyst.md +61 -0
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/tech-debt-auditor.md +89 -0
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/technical-decisions-curator.md +146 -0
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/technical-evaluator.md +51 -0
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/test-coverage-analyzer.md +91 -0
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/trend-spotter.md +99 -0
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/user-journey-mapper.md +101 -0
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/user-researcher.md +56 -0
- package/src/modules/bmm/tasks/daily-standup.md +91 -0
- package/src/modules/bmm/tasks/retrospective.md +110 -0
- package/src/modules/bmm/teams/team-all.yaml +7 -0
- package/src/modules/bmm/teams/team-dev.yaml +14 -0
- package/src/modules/bmm/teams/team-gamedev.yaml +9 -0
- package/src/modules/bmm/testarch/atdd.md +40 -0
- package/src/modules/bmm/testarch/automate.md +38 -0
- package/src/modules/bmm/testarch/ci.md +39 -0
- package/src/modules/bmm/testarch/framework.md +41 -0
- package/src/modules/bmm/testarch/nfr-assess.md +38 -0
- package/src/modules/bmm/testarch/risk-profile.md +38 -0
- package/src/modules/bmm/testarch/tea-commands.csv +11 -0
- package/src/modules/bmm/testarch/tea-gate.md +38 -0
- package/src/modules/bmm/testarch/tea-knowledge.md +275 -0
- package/src/modules/bmm/testarch/test-design.md +39 -0
- package/{bmad-core/data → src/modules/bmm/testarch}/test-levels-framework.md +2 -0
- package/{bmad-core/data → src/modules/bmm/testarch}/test-priorities-matrix.md +2 -0
- package/src/modules/bmm/testarch/trace-requirements.md +38 -0
- package/src/modules/bmm/workflows/1-analysis/brainstorm-game/game-brain-methods.csv +26 -0
- package/src/modules/bmm/workflows/1-analysis/brainstorm-game/game-context.md +115 -0
- package/src/modules/bmm/workflows/1-analysis/brainstorm-game/instructions.md +47 -0
- package/src/modules/bmm/workflows/1-analysis/brainstorm-game/workflow.yaml +22 -0
- package/src/modules/bmm/workflows/1-analysis/brainstorm-project/instructions.md +38 -0
- package/src/modules/bmm/workflows/1-analysis/brainstorm-project/project-context.md +25 -0
- package/src/modules/bmm/workflows/1-analysis/brainstorm-project/workflow.yaml +21 -0
- package/src/modules/bmm/workflows/1-analysis/game-brief/README.md +221 -0
- package/src/modules/bmm/workflows/1-analysis/game-brief/checklist.md +128 -0
- package/src/modules/bmm/workflows/1-analysis/game-brief/instructions.md +517 -0
- package/src/modules/bmm/workflows/1-analysis/game-brief/template.md +205 -0
- package/src/modules/bmm/workflows/1-analysis/game-brief/workflow.yaml +34 -0
- package/src/modules/bmm/workflows/1-analysis/product-brief/README.md +180 -0
- package/src/modules/bmm/workflows/1-analysis/product-brief/checklist.md +115 -0
- package/src/modules/bmm/workflows/1-analysis/product-brief/instructions.md +353 -0
- package/src/modules/bmm/workflows/1-analysis/product-brief/template.md +165 -0
- package/src/modules/bmm/workflows/1-analysis/product-brief/workflow.yaml +33 -0
- package/src/modules/bmm/workflows/1-analysis/research/README.md +454 -0
- package/src/modules/bmm/workflows/1-analysis/research/checklist.md +202 -0
- package/src/modules/bmm/workflows/1-analysis/research/claude-code/injections.yaml +114 -0
- package/src/modules/bmm/workflows/1-analysis/research/claude-code/sub-agents/bmm-competitor-analyzer.md +259 -0
- package/src/modules/bmm/workflows/1-analysis/research/claude-code/sub-agents/bmm-data-analyst.md +190 -0
- package/src/modules/bmm/workflows/1-analysis/research/claude-code/sub-agents/bmm-market-researcher.md +337 -0
- package/src/modules/bmm/workflows/1-analysis/research/claude-code/sub-agents/bmm-trend-spotter.md +107 -0
- package/src/modules/bmm/workflows/1-analysis/research/claude-code/sub-agents/bmm-user-researcher.md +329 -0
- package/src/modules/bmm/workflows/1-analysis/research/instructions-deep-prompt.md +370 -0
- package/src/modules/bmm/workflows/1-analysis/research/instructions-market.md +553 -0
- package/src/modules/bmm/workflows/1-analysis/research/instructions-router.md +91 -0
- package/src/modules/bmm/workflows/1-analysis/research/instructions-technical.md +442 -0
- package/src/modules/bmm/workflows/1-analysis/research/template-deep-prompt.md +94 -0
- package/src/modules/bmm/workflows/1-analysis/research/template-market.md +311 -0
- package/src/modules/bmm/workflows/1-analysis/research/template-technical.md +210 -0
- package/src/modules/bmm/workflows/1-analysis/research/workflow.yaml +149 -0
- package/src/modules/bmm/workflows/2-plan/README.md +203 -0
- package/src/modules/bmm/workflows/2-plan/checklist.md +369 -0
- package/src/modules/bmm/workflows/2-plan/gdd/README.md +222 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/action-platformer.md +45 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/adventure.md +84 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/card-game.md +76 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/fighting.md +89 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/horror.md +86 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/idle-incremental.md +78 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/metroidvania.md +87 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/moba.md +74 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/party-game.md +79 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/puzzle.md +58 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/racing.md +88 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/rhythm.md +79 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/roguelike.md +69 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/rpg.md +70 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/sandbox.md +79 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/shooter.md +62 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/simulation.md +73 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/sports.md +75 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/strategy.md +71 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/survival.md +79 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/text-based.md +91 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/tower-defense.md +79 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/turn-based-tactics.md +88 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types/visual-novel.md +89 -0
- package/src/modules/bmm/workflows/2-plan/gdd/game-types.csv +25 -0
- package/src/modules/bmm/workflows/2-plan/gdd/gdd-template.md +159 -0
- package/src/modules/bmm/workflows/2-plan/gdd/instructions-gdd.md +480 -0
- package/src/modules/bmm/workflows/2-plan/instructions-router.md +222 -0
- package/src/modules/bmm/workflows/2-plan/narrative/instructions-narrative.md +517 -0
- package/src/modules/bmm/workflows/2-plan/narrative/narrative-template.md +195 -0
- package/src/modules/bmm/workflows/2-plan/prd/analysis-template.md +53 -0
- package/src/modules/bmm/workflows/2-plan/prd/epics-template.md +18 -0
- package/src/modules/bmm/workflows/2-plan/prd/instructions-lg.md +267 -0
- package/src/modules/bmm/workflows/2-plan/prd/instructions-med.md +251 -0
- package/src/modules/bmm/workflows/2-plan/prd/prd-template.md +73 -0
- package/src/modules/bmm/workflows/2-plan/tech-spec/instructions-sm.md +137 -0
- package/src/modules/bmm/workflows/2-plan/tech-spec/tech-spec-template.md +59 -0
- package/src/modules/bmm/workflows/2-plan/ux/instructions-ux.md +360 -0
- package/src/modules/bmm/workflows/2-plan/ux/ux-spec-template.md +162 -0
- package/src/modules/bmm/workflows/2-plan/workflow.yaml +60 -0
- package/src/modules/bmm/workflows/3-solutioning/ADR-template.md +74 -0
- package/src/modules/bmm/workflows/3-solutioning/README.md +565 -0
- package/src/modules/bmm/workflows/3-solutioning/checklist.md +170 -0
- package/src/modules/bmm/workflows/3-solutioning/instructions.md +661 -0
- package/src/modules/bmm/workflows/3-solutioning/project-types/backend-questions.md +490 -0
- package/src/modules/bmm/workflows/3-solutioning/project-types/cli-questions.md +337 -0
- package/src/modules/bmm/workflows/3-solutioning/project-types/data-questions.md +472 -0
- package/src/modules/bmm/workflows/3-solutioning/project-types/desktop-questions.md +299 -0
- package/src/modules/bmm/workflows/3-solutioning/project-types/embedded-questions.md +118 -0
- package/src/modules/bmm/workflows/3-solutioning/project-types/extension-questions.md +374 -0
- package/src/modules/bmm/workflows/3-solutioning/project-types/game-questions.md +133 -0
- package/src/modules/bmm/workflows/3-solutioning/project-types/infra-questions.md +484 -0
- package/src/modules/bmm/workflows/3-solutioning/project-types/library-questions.md +146 -0
- package/src/modules/bmm/workflows/3-solutioning/project-types/mobile-questions.md +110 -0
- package/src/modules/bmm/workflows/3-solutioning/project-types/project-types.csv +12 -0
- package/src/modules/bmm/workflows/3-solutioning/project-types/web-questions.md +136 -0
- package/src/modules/bmm/workflows/3-solutioning/tech-spec/README.md +195 -0
- package/src/modules/bmm/workflows/3-solutioning/tech-spec/checklist.md +17 -0
- package/src/modules/bmm/workflows/3-solutioning/tech-spec/instructions.md +73 -0
- package/src/modules/bmm/workflows/3-solutioning/tech-spec/template.md +76 -0
- package/src/modules/bmm/workflows/3-solutioning/tech-spec/workflow.yaml +51 -0
- package/src/modules/bmm/workflows/3-solutioning/templates/backend-service-architecture.md +66 -0
- package/src/modules/bmm/workflows/3-solutioning/templates/cli-tool-architecture.md +66 -0
- package/src/modules/bmm/workflows/3-solutioning/templates/data-pipeline-architecture.md +66 -0
- package/src/modules/bmm/workflows/3-solutioning/templates/desktop-app-architecture.md +66 -0
- package/src/modules/bmm/workflows/3-solutioning/templates/embedded-firmware-architecture.md +66 -0
- package/src/modules/bmm/workflows/3-solutioning/templates/game-engine-architecture.md +244 -0
- package/src/modules/bmm/workflows/3-solutioning/templates/game-engine-godot-guide.md +428 -0
- package/src/modules/bmm/workflows/3-solutioning/templates/game-engine-unity-guide.md +333 -0
- package/src/modules/bmm/workflows/3-solutioning/templates/game-engine-web-guide.md +528 -0
- package/src/modules/bmm/workflows/3-solutioning/templates/infrastructure-architecture.md +66 -0
- package/src/modules/bmm/workflows/3-solutioning/templates/library-package-architecture.md +66 -0
- package/src/modules/bmm/workflows/3-solutioning/templates/mobile-app-architecture.md +66 -0
- package/src/modules/bmm/workflows/3-solutioning/templates/registry.csv +172 -0
- package/src/modules/bmm/workflows/3-solutioning/templates/web-api-architecture.md +66 -0
- package/src/modules/bmm/workflows/3-solutioning/templates/web-fullstack-architecture.md +277 -0
- package/src/modules/bmm/workflows/3-solutioning/workflow.yaml +65 -0
- package/src/modules/bmm/workflows/4-implementation/correct-course/checklist.md +279 -0
- package/src/modules/bmm/workflows/4-implementation/correct-course/instructions.md +190 -0
- package/src/modules/bmm/workflows/4-implementation/correct-course/workflow.yaml +35 -0
- package/src/modules/bmm/workflows/4-implementation/create-story/README.md +42 -0
- package/src/modules/bmm/workflows/4-implementation/create-story/checklist.md +39 -0
- package/src/modules/bmm/workflows/4-implementation/create-story/instructions.md +81 -0
- package/src/modules/bmm/workflows/4-implementation/create-story/template.md +57 -0
- package/src/modules/bmm/workflows/4-implementation/create-story/workflow.yaml +72 -0
- package/src/modules/bmm/workflows/4-implementation/dev-story/README.md +84 -0
- package/src/modules/bmm/workflows/4-implementation/dev-story/checklist.md +38 -0
- package/src/modules/bmm/workflows/4-implementation/dev-story/instructions.md +87 -0
- package/src/modules/bmm/workflows/4-implementation/dev-story/workflow.yaml +53 -0
- package/src/modules/bmm/workflows/4-implementation/retrospective/instructions.md +391 -0
- package/src/modules/bmm/workflows/4-implementation/retrospective/workflow.yaml +41 -0
- package/src/modules/bmm/workflows/4-implementation/review-story/README.md +72 -0
- package/src/modules/bmm/workflows/4-implementation/review-story/backlog_template.md +12 -0
- package/src/modules/bmm/workflows/4-implementation/review-story/checklist.md +22 -0
- package/src/modules/bmm/workflows/4-implementation/review-story/instructions.md +176 -0
- package/src/modules/bmm/workflows/4-implementation/review-story/workflow.yaml +99 -0
- package/src/modules/bmm/workflows/4-implementation/story-context/README.md +234 -0
- package/src/modules/bmm/workflows/4-implementation/story-context/checklist.md +16 -0
- package/src/modules/bmm/workflows/4-implementation/story-context/context-template.xml +34 -0
- package/src/modules/bmm/workflows/4-implementation/story-context/instructions.md +76 -0
- package/src/modules/bmm/workflows/4-implementation/story-context/workflow.yaml +56 -0
- package/src/modules/cis/_module-installer/install-menu-config.yaml +14 -0
- package/src/modules/cis/_module-installer/installer.js +92 -0
- package/src/modules/cis/agents/README.md +104 -0
- package/src/modules/cis/agents/brainstorming-coach.md +24 -0
- package/src/modules/cis/agents/creative-problem-solver.md +24 -0
- package/src/modules/cis/agents/design-thinking-coach.md +24 -0
- package/src/modules/cis/agents/innovation-strategist.md +24 -0
- package/src/modules/cis/agents/storyteller.md +24 -0
- package/src/modules/cis/readme.md +86 -0
- package/src/modules/cis/teams/creative-squad.yaml +6 -0
- package/src/modules/cis/workflows/README.md +67 -0
- package/src/modules/cis/workflows/brainstorming/README.md +271 -0
- package/src/modules/cis/workflows/brainstorming/brain-methods.csv +36 -0
- package/src/modules/cis/workflows/brainstorming/instructions.md +310 -0
- package/src/modules/cis/workflows/brainstorming/template.md +102 -0
- package/src/modules/cis/workflows/brainstorming/workflow.yaml +30 -0
- package/src/modules/cis/workflows/design-thinking/README.md +56 -0
- package/src/modules/cis/workflows/design-thinking/design-methods.csv +31 -0
- package/src/modules/cis/workflows/design-thinking/instructions.md +200 -0
- package/src/modules/cis/workflows/design-thinking/template.md +111 -0
- package/src/modules/cis/workflows/design-thinking/workflow.yaml +29 -0
- package/src/modules/cis/workflows/innovation-strategy/README.md +56 -0
- package/src/modules/cis/workflows/innovation-strategy/innovation-frameworks.csv +31 -0
- package/src/modules/cis/workflows/innovation-strategy/instructions.md +274 -0
- package/src/modules/cis/workflows/innovation-strategy/template.md +189 -0
- package/src/modules/cis/workflows/innovation-strategy/workflow.yaml +29 -0
- package/src/modules/cis/workflows/problem-solving/README.md +56 -0
- package/src/modules/cis/workflows/problem-solving/instructions.md +250 -0
- package/src/modules/cis/workflows/problem-solving/solving-methods.csv +31 -0
- package/src/modules/cis/workflows/problem-solving/template.md +165 -0
- package/src/modules/cis/workflows/problem-solving/workflow.yaml +29 -0
- package/src/modules/cis/workflows/storytelling/README.md +58 -0
- package/src/modules/cis/workflows/storytelling/instructions.md +275 -0
- package/src/modules/cis/workflows/storytelling/story-types.csv +26 -0
- package/src/modules/cis/workflows/storytelling/template.md +113 -0
- package/src/modules/cis/workflows/storytelling/workflow.yaml +29 -0
- package/src/utility/models/agent-activation-ide.xml +51 -0
- package/src/utility/models/agent-config-template.md +23 -0
- package/tools/cli/bmad-cli.js +42 -0
- package/tools/cli/bundlers/bundle-web.js +157 -0
- package/tools/cli/bundlers/test-analyst.js +28 -0
- package/tools/cli/bundlers/test-bundler.js +118 -0
- package/tools/cli/bundlers/web-bundler.js +880 -0
- package/tools/cli/commands/install.js +41 -0
- package/tools/cli/commands/list.js +28 -0
- package/tools/cli/commands/status.js +47 -0
- package/tools/cli/commands/uninstall.js +44 -0
- package/tools/cli/commands/update.js +28 -0
- package/tools/cli/installers/lib/core/config-collector.js +383 -0
- package/tools/cli/installers/lib/core/dependency-resolver.js +721 -0
- package/tools/cli/installers/lib/core/detector.js +208 -0
- package/tools/cli/installers/lib/core/installer.js +1070 -0
- package/tools/cli/installers/lib/core/manifest-generator.js +385 -0
- package/tools/cli/installers/lib/core/manifest.js +484 -0
- package/tools/cli/installers/lib/ide/_base-ide.js +281 -0
- package/tools/cli/installers/lib/ide/auggie.js +271 -0
- package/tools/cli/installers/lib/ide/claude-code.js +625 -0
- package/tools/cli/installers/lib/ide/cline.js +301 -0
- package/tools/cli/installers/lib/ide/codex.js +267 -0
- package/tools/cli/installers/lib/ide/crush.js +204 -0
- package/tools/cli/installers/lib/ide/cursor.js +224 -0
- package/tools/cli/installers/lib/ide/gemini.js +160 -0
- package/tools/cli/installers/lib/ide/github-copilot.js +289 -0
- package/tools/cli/installers/lib/ide/iflow.js +142 -0
- package/tools/cli/installers/lib/ide/kilo.js +171 -0
- package/tools/cli/installers/lib/ide/manager.js +203 -0
- package/tools/cli/installers/lib/ide/qwen.js +188 -0
- package/tools/cli/installers/lib/ide/roo.js +288 -0
- package/tools/cli/installers/lib/ide/trae.js +182 -0
- package/tools/cli/installers/lib/ide/windsurf.js +149 -0
- package/tools/cli/installers/lib/ide/workflow-command-generator.js +162 -0
- package/tools/cli/installers/lib/ide/workflow-command-template.md +11 -0
- package/tools/cli/installers/lib/modules/manager.js +452 -0
- package/tools/cli/lib/agent-party-generator.js +206 -0
- package/tools/cli/lib/cli-utils.js +208 -0
- package/tools/cli/lib/config.js +210 -0
- package/tools/cli/lib/file-ops.js +204 -0
- package/tools/cli/lib/platform-codes.js +116 -0
- package/tools/cli/lib/project-root.js +71 -0
- package/tools/cli/lib/replace-project-root.js +239 -0
- package/tools/cli/lib/ui.js +516 -0
- package/tools/cli/lib/xml-handler.js +183 -0
- package/tools/cli/lib/xml-to-markdown.js +82 -0
- package/tools/{yaml-format.js → cli/lib/yaml-format.js} +3 -10
- package/tools/cli/regenerate-manifests.js +28 -0
- package/tools/flattener/ignoreRules.js +2 -6
- package/tools/flattener/main.js +31 -121
- package/tools/flattener/projectRoot.js +3 -8
- package/tools/flattener/stats.helpers.js +8 -35
- package/tools/flattener/stats.js +1 -6
- package/tools/flattener/test-matrix.js +1 -5
- package/tools/platform-codes.yaml +127 -0
- package/tools/test-agents/captain-kirk-commander.md +110 -0
- package/tools/test-agents/data-operations-android.md +123 -0
- package/tools/test-agents/geordi-chief-engineer.md +135 -0
- package/tools/test-agents/isabella-martinez-ethicist.md +109 -0
- package/tools/test-agents/marcus-thompson-security.md +109 -0
- package/tools/test-agents/maya-patel-pragmatist.md +82 -0
- package/tools/test-agents/picard-diplomat-captain.md +134 -0
- package/tools/test-agents/spock-science-officer.md +124 -0
- package/tools/test-agents/william-smithers-technocrat.md +71 -0
- package/tools/test-agents/zara-chen-designer.md +94 -0
- package/tools/validate-bundles.js +87 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -22
- package/README.md +0 -221
- package/bmad-core/agent-teams/team-all.yaml +0 -14
- package/bmad-core/agent-teams/team-fullstack.yaml +0 -18
- package/bmad-core/agent-teams/team-ide-minimal.yaml +0 -10
- package/bmad-core/agent-teams/team-no-ui.yaml +0 -13
- package/bmad-core/agents/analyst.md +0 -81
- package/bmad-core/agents/architect.md +0 -83
- package/bmad-core/agents/bmad-master.md +0 -107
- package/bmad-core/agents/bmad-orchestrator.md +0 -149
- package/bmad-core/agents/dev.md +0 -75
- package/bmad-core/agents/pm.md +0 -81
- package/bmad-core/agents/po.md +0 -76
- package/bmad-core/agents/qa.md +0 -88
- package/bmad-core/agents/sm.md +0 -62
- package/bmad-core/agents/ux-expert.md +0 -66
- package/bmad-core/checklists/architect-checklist.md +0 -438
- package/bmad-core/checklists/change-checklist.md +0 -182
- package/bmad-core/checklists/pm-checklist.md +0 -370
- package/bmad-core/checklists/po-master-checklist.md +0 -432
- package/bmad-core/checklists/story-dod-checklist.md +0 -94
- package/bmad-core/checklists/story-draft-checklist.md +0 -153
- package/bmad-core/core-config.yaml +0 -20
- package/bmad-core/data/bmad-kb.md +0 -806
- package/bmad-core/data/brainstorming-techniques.md +0 -36
- package/bmad-core/data/elicitation-methods.md +0 -154
- package/bmad-core/data/technical-preferences.md +0 -3
- package/bmad-core/tasks/advanced-elicitation.md +0 -117
- package/bmad-core/tasks/brownfield-create-epic.md +0 -160
- package/bmad-core/tasks/brownfield-create-story.md +0 -147
- package/bmad-core/tasks/correct-course.md +0 -70
- package/bmad-core/tasks/create-brownfield-story.md +0 -312
- package/bmad-core/tasks/create-deep-research-prompt.md +0 -278
- package/bmad-core/tasks/create-next-story.md +0 -112
- package/bmad-core/tasks/document-project.md +0 -343
- package/bmad-core/tasks/facilitate-brainstorming-session.md +0 -136
- package/bmad-core/tasks/generate-ai-frontend-prompt.md +0 -51
- package/bmad-core/tasks/index-docs.md +0 -173
- package/bmad-core/tasks/kb-mode-interaction.md +0 -75
- package/bmad-core/tasks/nfr-assess.md +0 -343
- package/bmad-core/tasks/qa-gate.md +0 -159
- package/bmad-core/tasks/review-story.md +0 -314
- package/bmad-core/tasks/risk-profile.md +0 -353
- package/bmad-core/tasks/shard-doc.md +0 -185
- package/bmad-core/tasks/test-design.md +0 -174
- package/bmad-core/tasks/trace-requirements.md +0 -264
- package/bmad-core/tasks/validate-next-story.md +0 -134
- package/bmad-core/templates/architecture-tmpl.yaml +0 -650
- package/bmad-core/templates/brainstorming-output-tmpl.yaml +0 -156
- package/bmad-core/templates/brownfield-architecture-tmpl.yaml +0 -476
- package/bmad-core/templates/brownfield-prd-tmpl.yaml +0 -280
- package/bmad-core/templates/competitor-analysis-tmpl.yaml +0 -306
- package/bmad-core/templates/front-end-architecture-tmpl.yaml +0 -218
- package/bmad-core/templates/front-end-spec-tmpl.yaml +0 -349
- package/bmad-core/templates/fullstack-architecture-tmpl.yaml +0 -823
- package/bmad-core/templates/market-research-tmpl.yaml +0 -252
- package/bmad-core/templates/prd-tmpl.yaml +0 -202
- package/bmad-core/templates/project-brief-tmpl.yaml +0 -221
- package/bmad-core/templates/qa-gate-tmpl.yaml +0 -102
- package/bmad-core/templates/story-tmpl.yaml +0 -137
- package/bmad-core/workflows/brownfield-fullstack.yaml +0 -297
- package/bmad-core/workflows/brownfield-service.yaml +0 -187
- package/bmad-core/workflows/brownfield-ui.yaml +0 -197
- package/bmad-core/workflows/greenfield-fullstack.yaml +0 -240
- package/bmad-core/workflows/greenfield-service.yaml +0 -206
- package/bmad-core/workflows/greenfield-ui.yaml +0 -235
- package/common/tasks/create-doc.md +0 -101
- package/common/tasks/execute-checklist.md +0 -86
- package/common/utils/bmad-doc-template.md +0 -325
- package/common/utils/workflow-management.md +0 -69
- package/dist/agents/analyst.txt +0 -2889
- package/dist/agents/architect.txt +0 -3552
- package/dist/agents/bmad-master.txt +0 -8769
- package/dist/agents/bmad-orchestrator.txt +0 -1513
- package/dist/agents/dev.txt +0 -414
- package/dist/agents/pm.txt +0 -2204
- package/dist/agents/po.txt +0 -1346
- package/dist/agents/qa.txt +0 -1987
- package/dist/agents/sm.txt +0 -658
- package/dist/agents/ux-expert.txt +0 -694
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.txt +0 -2371
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.txt +0 -1620
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.txt +0 -815
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/teams/phaser-2d-nodejs-game-team.txt +0 -10952
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-architect.txt +0 -4012
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.txt +0 -3698
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.txt +0 -450
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-sm.txt +0 -973
- package/dist/expansion-packs/bmad-2d-unity-game-dev/teams/unity-2d-game-team.txt +0 -15376
- package/dist/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.txt +0 -2075
- package/dist/teams/team-all.txt +0 -12682
- package/dist/teams/team-fullstack.txt +0 -10421
- package/dist/teams/team-ide-minimal.txt +0 -5103
- package/dist/teams/team-no-ui.txt +0 -8980
- package/docs/GUIDING-PRINCIPLES.md +0 -91
- package/docs/core-architecture.md +0 -219
- package/docs/enhanced-ide-development-workflow.md +0 -248
- package/docs/expansion-packs.md +0 -280
- package/docs/how-to-contribute-with-pull-requests.md +0 -158
- package/docs/user-guide.md +0 -504
- package/docs/versioning-and-releases.md +0 -147
- package/docs/versions.md +0 -48
- package/docs/working-in-the-brownfield.md +0 -597
- package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/Complete AI Agent System - Flowchart.svg +0 -102
- package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.1 Google Cloud Project Setup/1.1.1 - Initial Project Configuration - bash copy.txt +0 -13
- package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.1 Google Cloud Project Setup/1.1.1 - Initial Project Configuration - bash.txt +0 -13
- package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.2 Agent Development Kit Installation/1.2.2 - Basic Project Structure - txt.txt +0 -25
- package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.3 Core Configuration Files/1.3.1 - settings.py +0 -34
- package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.3 Core Configuration Files/1.3.2 - main.py - Base Application.py +0 -70
- package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.4 Deployment Configuration/1.4.2 - cloudbuild.yaml +0 -26
- package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/README.md +0 -109
- package/expansion-packs/README.md +0 -3
- package/expansion-packs/bmad-2d-phaser-game-dev/agent-teams/phaser-2d-nodejs-game-team.yaml +0 -13
- package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.md +0 -71
- package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.md +0 -78
- package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.md +0 -64
- package/expansion-packs/bmad-2d-phaser-game-dev/checklists/game-design-checklist.md +0 -201
- package/expansion-packs/bmad-2d-phaser-game-dev/checklists/game-story-dod-checklist.md +0 -160
- package/expansion-packs/bmad-2d-phaser-game-dev/config.yaml +0 -8
- package/expansion-packs/bmad-2d-phaser-game-dev/data/bmad-kb.md +0 -250
- package/expansion-packs/bmad-2d-phaser-game-dev/data/development-guidelines.md +0 -647
- package/expansion-packs/bmad-2d-phaser-game-dev/tasks/advanced-elicitation.md +0 -110
- package/expansion-packs/bmad-2d-phaser-game-dev/tasks/create-game-story.md +0 -216
- package/expansion-packs/bmad-2d-phaser-game-dev/tasks/game-design-brainstorming.md +0 -290
- package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-architecture-tmpl.yaml +0 -613
- package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-brief-tmpl.yaml +0 -356
- package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-design-doc-tmpl.yaml +0 -343
- package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-story-tmpl.yaml +0 -253
- package/expansion-packs/bmad-2d-phaser-game-dev/templates/level-design-doc-tmpl.yaml +0 -484
- package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-dev-greenfield.yaml +0 -183
- package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-prototype.yaml +0 -175
- package/expansion-packs/bmad-2d-unity-game-dev/agent-teams/unity-2d-game-team.yaml +0 -14
- package/expansion-packs/bmad-2d-unity-game-dev/agents/game-architect.md +0 -80
- package/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.md +0 -77
- package/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.md +0 -78
- package/expansion-packs/bmad-2d-unity-game-dev/agents/game-sm.md +0 -65
- package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-architect-checklist.md +0 -391
- package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-change-checklist.md +0 -203
- package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-design-checklist.md +0 -201
- package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-story-dod-checklist.md +0 -124
- package/expansion-packs/bmad-2d-unity-game-dev/config.yaml +0 -6
- package/expansion-packs/bmad-2d-unity-game-dev/data/bmad-kb.md +0 -769
- package/expansion-packs/bmad-2d-unity-game-dev/data/development-guidelines.md +0 -586
- package/expansion-packs/bmad-2d-unity-game-dev/tasks/advanced-elicitation.md +0 -110
- package/expansion-packs/bmad-2d-unity-game-dev/tasks/correct-course-game.md +0 -141
- package/expansion-packs/bmad-2d-unity-game-dev/tasks/create-game-story.md +0 -184
- package/expansion-packs/bmad-2d-unity-game-dev/tasks/game-design-brainstorming.md +0 -290
- package/expansion-packs/bmad-2d-unity-game-dev/tasks/validate-game-story.md +0 -200
- package/expansion-packs/bmad-2d-unity-game-dev/templates/game-architecture-tmpl.yaml +0 -1030
- package/expansion-packs/bmad-2d-unity-game-dev/templates/game-brief-tmpl.yaml +0 -356
- package/expansion-packs/bmad-2d-unity-game-dev/templates/game-design-doc-tmpl.yaml +0 -705
- package/expansion-packs/bmad-2d-unity-game-dev/templates/game-story-tmpl.yaml +0 -256
- package/expansion-packs/bmad-2d-unity-game-dev/templates/level-design-doc-tmpl.yaml +0 -484
- package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-dev-greenfield.yaml +0 -183
- package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-prototype.yaml +0 -175
- package/expansion-packs/bmad-infrastructure-devops/README.md +0 -147
- package/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.md +0 -71
- package/expansion-packs/bmad-infrastructure-devops/checklists/infrastructure-checklist.md +0 -484
- package/expansion-packs/bmad-infrastructure-devops/config.yaml +0 -9
- package/expansion-packs/bmad-infrastructure-devops/data/bmad-kb.md +0 -305
- package/expansion-packs/bmad-infrastructure-devops/tasks/review-infrastructure.md +0 -159
- package/expansion-packs/bmad-infrastructure-devops/tasks/validate-infrastructure.md +0 -153
- package/expansion-packs/bmad-infrastructure-devops/templates/infrastructure-architecture-tmpl.yaml +0 -424
- package/expansion-packs/bmad-infrastructure-devops/templates/infrastructure-platform-from-arch-tmpl.yaml +0 -629
- package/release_notes.md +0 -32
- package/tools/bmad-npx-wrapper.js +0 -39
- package/tools/builders/web-builder.js +0 -675
- package/tools/bump-all-versions.js +0 -115
- package/tools/bump-expansion-version.js +0 -90
- package/tools/cli.js +0 -152
- package/tools/installer/README.md +0 -8
- package/tools/installer/bin/bmad.js +0 -585
- package/tools/installer/config/ide-agent-config.yaml +0 -58
- package/tools/installer/config/install.config.yaml +0 -123
- package/tools/installer/lib/config-loader.js +0 -257
- package/tools/installer/lib/file-manager.js +0 -389
- package/tools/installer/lib/ide-base-setup.js +0 -228
- package/tools/installer/lib/ide-setup.js +0 -1441
- package/tools/installer/lib/installer.js +0 -1995
- package/tools/installer/lib/memory-profiler.js +0 -225
- package/tools/installer/lib/module-manager.js +0 -114
- package/tools/installer/lib/resource-locator.js +0 -308
- package/tools/installer/package.json +0 -44
- package/tools/lib/dependency-resolver.js +0 -175
- package/tools/lib/yaml-utils.js +0 -29
- package/tools/md-assets/web-agent-startup-instructions.md +0 -39
- package/tools/preview-release-notes.js +0 -66
- package/tools/shared/bannerArt.js +0 -105
- package/tools/sync-installer-version.js +0 -32
- package/tools/update-expansion-version.js +0 -53
- package/tools/upgraders/v3-to-v4-upgrader.js +0 -672
- package/tools/version-bump.js +0 -94
|
@@ -0,0 +1,1070 @@
|
|
|
1
|
+
const path = require('node:path');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const ora = require('ora');
|
|
5
|
+
const { Detector } = require('./detector');
|
|
6
|
+
const { Manifest } = require('./manifest');
|
|
7
|
+
const { ModuleManager } = require('../modules/manager');
|
|
8
|
+
const { IdeManager } = require('../ide/manager');
|
|
9
|
+
const { FileOps } = require('../../../lib/file-ops');
|
|
10
|
+
const { Config } = require('../../../lib/config');
|
|
11
|
+
const { XmlHandler } = require('../../../lib/xml-handler');
|
|
12
|
+
const { DependencyResolver } = require('./dependency-resolver');
|
|
13
|
+
const { ConfigCollector } = require('./config-collector');
|
|
14
|
+
// processInstallation no longer needed - LLMs understand {project-root}
|
|
15
|
+
const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
|
|
16
|
+
const { AgentPartyGenerator } = require('../../../lib/agent-party-generator');
|
|
17
|
+
const { CLIUtils } = require('../../../lib/cli-utils');
|
|
18
|
+
const { ManifestGenerator } = require('./manifest-generator');
|
|
19
|
+
|
|
20
|
+
class Installer {
|
|
21
|
+
constructor() {
|
|
22
|
+
this.detector = new Detector();
|
|
23
|
+
this.manifest = new Manifest();
|
|
24
|
+
this.moduleManager = new ModuleManager();
|
|
25
|
+
this.ideManager = new IdeManager();
|
|
26
|
+
this.fileOps = new FileOps();
|
|
27
|
+
this.config = new Config();
|
|
28
|
+
this.xmlHandler = new XmlHandler();
|
|
29
|
+
this.dependencyResolver = new DependencyResolver();
|
|
30
|
+
this.configCollector = new ConfigCollector();
|
|
31
|
+
this.installedFiles = []; // Track all installed files
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Collect Tool/IDE configurations after module configuration
|
|
36
|
+
* @param {string} projectDir - Project directory
|
|
37
|
+
* @param {Array} selectedModules - Selected modules from configuration
|
|
38
|
+
* @returns {Object} Tool/IDE selection and configurations
|
|
39
|
+
*/
|
|
40
|
+
async collectToolConfigurations(projectDir, selectedModules) {
|
|
41
|
+
// Prompt for tool selection
|
|
42
|
+
const { UI } = require('../../../lib/ui');
|
|
43
|
+
const ui = new UI();
|
|
44
|
+
const toolConfig = await ui.promptToolSelection(projectDir, selectedModules);
|
|
45
|
+
|
|
46
|
+
// Collect IDE-specific configurations if any were selected
|
|
47
|
+
const ideConfigurations = {};
|
|
48
|
+
const bmadDir = path.join(projectDir, 'bmad');
|
|
49
|
+
|
|
50
|
+
if (!toolConfig.skipIde && toolConfig.ides && toolConfig.ides.length > 0) {
|
|
51
|
+
console.log('\n'); // Add spacing before IDE questions
|
|
52
|
+
|
|
53
|
+
for (const ide of toolConfig.ides) {
|
|
54
|
+
// List of IDEs that have interactive prompts
|
|
55
|
+
const needsPrompts = ['claude-code', 'github-copilot', 'roo', 'cline', 'auggie', 'codex', 'qwen', 'gemini'].includes(ide);
|
|
56
|
+
|
|
57
|
+
if (needsPrompts) {
|
|
58
|
+
// Get IDE handler and collect configuration
|
|
59
|
+
try {
|
|
60
|
+
// Dynamically load the IDE setup module
|
|
61
|
+
const ideModule = require(`../ide/${ide}`);
|
|
62
|
+
|
|
63
|
+
// Get the setup class (handle different export formats)
|
|
64
|
+
let SetupClass;
|
|
65
|
+
const className =
|
|
66
|
+
ide
|
|
67
|
+
.split('-')
|
|
68
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
69
|
+
.join('') + 'Setup';
|
|
70
|
+
|
|
71
|
+
if (ideModule[className]) {
|
|
72
|
+
SetupClass = ideModule[className];
|
|
73
|
+
} else if (ideModule.default) {
|
|
74
|
+
SetupClass = ideModule.default;
|
|
75
|
+
} else {
|
|
76
|
+
// Skip if no setup class found
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const ideSetup = new SetupClass();
|
|
81
|
+
|
|
82
|
+
// Check if this IDE has a collectConfiguration method
|
|
83
|
+
if (typeof ideSetup.collectConfiguration === 'function') {
|
|
84
|
+
console.log(chalk.cyan(`\nConfiguring ${ide}...`));
|
|
85
|
+
ideConfigurations[ide] = await ideSetup.collectConfiguration({
|
|
86
|
+
selectedModules: selectedModules || [],
|
|
87
|
+
projectDir,
|
|
88
|
+
bmadDir,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
} catch {
|
|
92
|
+
// IDE doesn't have a setup file or collectConfiguration method
|
|
93
|
+
console.warn(chalk.yellow(`Warning: Could not load configuration for ${ide}`));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
ides: toolConfig.ides,
|
|
101
|
+
skipIde: toolConfig.skipIde,
|
|
102
|
+
configurations: ideConfigurations,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Main installation method
|
|
108
|
+
* @param {Object} config - Installation configuration
|
|
109
|
+
* @param {string} config.directory - Target directory
|
|
110
|
+
* @param {boolean} config.installCore - Whether to install core
|
|
111
|
+
* @param {string[]} config.modules - Modules to install
|
|
112
|
+
* @param {string[]} config.ides - IDEs to configure
|
|
113
|
+
* @param {boolean} config.skipIde - Skip IDE configuration
|
|
114
|
+
*/
|
|
115
|
+
async install(config) {
|
|
116
|
+
// Display BMAD logo
|
|
117
|
+
CLIUtils.displayLogo();
|
|
118
|
+
|
|
119
|
+
// Display welcome message
|
|
120
|
+
CLIUtils.displaySection('BMAD™ Installation', 'Version ' + require(path.join(getProjectRoot(), 'package.json')).version);
|
|
121
|
+
|
|
122
|
+
// Preflight: Block legacy BMAD v4 footprints before any prompts/writes
|
|
123
|
+
const projectDir = path.resolve(config.directory);
|
|
124
|
+
const legacyV4 = await this.detector.detectLegacyV4(projectDir);
|
|
125
|
+
if (legacyV4.hasLegacyV4) {
|
|
126
|
+
const error = this.createLegacyV4Error(legacyV4);
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// If core config was pre-collected (from interactive mode), use it
|
|
131
|
+
if (config.coreConfig) {
|
|
132
|
+
this.configCollector.collectedConfig.core = config.coreConfig;
|
|
133
|
+
// Also store in allAnswers for cross-referencing
|
|
134
|
+
this.configCollector.allAnswers = {};
|
|
135
|
+
for (const [key, value] of Object.entries(config.coreConfig)) {
|
|
136
|
+
this.configCollector.allAnswers[`core_${key}`] = value;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Collect configurations for modules (core was already collected in UI.promptInstall if interactive)
|
|
141
|
+
const moduleConfigs = await this.configCollector.collectAllConfigurations(config.modules || [], path.resolve(config.directory));
|
|
142
|
+
|
|
143
|
+
const toolSelection = await this.collectToolConfigurations(path.resolve(config.directory), config.modules);
|
|
144
|
+
|
|
145
|
+
// Merge tool selection into config
|
|
146
|
+
config.ides = toolSelection.ides;
|
|
147
|
+
config.skipIde = toolSelection.skipIde;
|
|
148
|
+
const ideConfigurations = toolSelection.configurations;
|
|
149
|
+
|
|
150
|
+
const spinner = ora('Preparing installation...').start();
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
// Resolve target directory (path.resolve handles platform differences)
|
|
154
|
+
const projectDir = path.resolve(config.directory);
|
|
155
|
+
|
|
156
|
+
// Create a project directory if it doesn't exist (user already confirmed)
|
|
157
|
+
if (!(await fs.pathExists(projectDir))) {
|
|
158
|
+
spinner.text = 'Creating installation directory...';
|
|
159
|
+
try {
|
|
160
|
+
// fs.ensureDir handles platform-specific directory creation
|
|
161
|
+
// It will recursively create all necessary parent directories
|
|
162
|
+
await fs.ensureDir(projectDir);
|
|
163
|
+
} catch (error) {
|
|
164
|
+
spinner.fail('Failed to create installation directory');
|
|
165
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
166
|
+
// More detailed error for common issues
|
|
167
|
+
if (error.code === 'EACCES') {
|
|
168
|
+
console.error(chalk.red('Permission denied. Check parent directory permissions.'));
|
|
169
|
+
} else if (error.code === 'ENOSPC') {
|
|
170
|
+
console.error(chalk.red('No space left on device.'));
|
|
171
|
+
}
|
|
172
|
+
throw new Error(`Cannot create directory: ${projectDir}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const bmadDir = path.join(projectDir, 'bmad');
|
|
177
|
+
|
|
178
|
+
// Check existing installation
|
|
179
|
+
spinner.text = 'Checking for existing installation...';
|
|
180
|
+
const existingInstall = await this.detector.detect(bmadDir);
|
|
181
|
+
|
|
182
|
+
if (existingInstall.installed && !config.force) {
|
|
183
|
+
spinner.stop();
|
|
184
|
+
|
|
185
|
+
console.log(chalk.yellow('\n⚠️ Existing BMAD installation detected'));
|
|
186
|
+
console.log(chalk.dim(` Location: ${bmadDir}`));
|
|
187
|
+
console.log(chalk.dim(` Version: ${existingInstall.version}`));
|
|
188
|
+
|
|
189
|
+
// TODO: Handle update scenario
|
|
190
|
+
const { action } = await this.promptUpdateAction();
|
|
191
|
+
if (action === 'cancel') {
|
|
192
|
+
console.log('Installation cancelled.');
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Create bmad directory structure
|
|
198
|
+
spinner.text = 'Creating directory structure...';
|
|
199
|
+
await this.createDirectoryStructure(bmadDir);
|
|
200
|
+
|
|
201
|
+
// Resolve dependencies for selected modules
|
|
202
|
+
spinner.text = 'Resolving dependencies...';
|
|
203
|
+
const projectRoot = getProjectRoot();
|
|
204
|
+
const modulesToInstall = config.installCore ? ['core', ...config.modules] : config.modules;
|
|
205
|
+
|
|
206
|
+
// For dependency resolution, we need to pass the project root
|
|
207
|
+
const resolution = await this.dependencyResolver.resolve(projectRoot, config.modules || [], { verbose: config.verbose });
|
|
208
|
+
|
|
209
|
+
if (config.verbose) {
|
|
210
|
+
spinner.succeed('Dependencies resolved');
|
|
211
|
+
} else {
|
|
212
|
+
spinner.succeed('Dependencies resolved');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Install core if requested or if dependencies require it
|
|
216
|
+
if (config.installCore || resolution.byModule.core) {
|
|
217
|
+
spinner.start('Installing BMAD core...');
|
|
218
|
+
await this.installCoreWithDependencies(bmadDir, resolution.byModule.core);
|
|
219
|
+
spinner.succeed('Core installed');
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Install modules with their dependencies
|
|
223
|
+
if (config.modules && config.modules.length > 0) {
|
|
224
|
+
for (const moduleName of config.modules) {
|
|
225
|
+
spinner.start(`Installing module: ${moduleName}...`);
|
|
226
|
+
await this.installModuleWithDependencies(moduleName, bmadDir, resolution.byModule[moduleName]);
|
|
227
|
+
spinner.succeed(`Module installed: ${moduleName}`);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Install partial modules (only dependencies)
|
|
231
|
+
for (const [module, files] of Object.entries(resolution.byModule)) {
|
|
232
|
+
if (!config.modules.includes(module) && module !== 'core') {
|
|
233
|
+
const totalFiles = files.agents.length + files.tasks.length + files.templates.length + files.data.length + files.other.length;
|
|
234
|
+
if (totalFiles > 0) {
|
|
235
|
+
spinner.start(`Installing ${module} dependencies...`);
|
|
236
|
+
await this.installPartialModule(module, bmadDir, files);
|
|
237
|
+
spinner.succeed(`${module} dependencies installed`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Generate clean config.yaml files for each installed module
|
|
244
|
+
spinner.start('Generating module configurations...');
|
|
245
|
+
await this.generateModuleConfigs(bmadDir, moduleConfigs);
|
|
246
|
+
spinner.succeed('Module configurations generated');
|
|
247
|
+
|
|
248
|
+
// Create agent configuration files
|
|
249
|
+
spinner.start('Creating agent configurations...');
|
|
250
|
+
// Get user info from collected config if available
|
|
251
|
+
const userInfo = {
|
|
252
|
+
userName: moduleConfigs.core?.['user_name'] || null,
|
|
253
|
+
responseLanguage: moduleConfigs.core?.['communication_language'] || null,
|
|
254
|
+
};
|
|
255
|
+
const agentConfigResult = await this.createAgentConfigs(bmadDir, userInfo);
|
|
256
|
+
if (agentConfigResult.skipped > 0) {
|
|
257
|
+
spinner.succeed(`Agent configurations: ${agentConfigResult.created} created, ${agentConfigResult.skipped} preserved`);
|
|
258
|
+
} else {
|
|
259
|
+
spinner.succeed(`Agent configurations created: ${agentConfigResult.created}`);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Generate CSV manifests for workflows, agents, and tasks BEFORE IDE setup
|
|
263
|
+
spinner.start('Generating workflow and agent manifests...');
|
|
264
|
+
const manifestGen = new ManifestGenerator();
|
|
265
|
+
const manifestStats = await manifestGen.generateManifests(bmadDir, config.modules || []);
|
|
266
|
+
spinner.succeed(
|
|
267
|
+
`Manifests generated: ${manifestStats.workflows} workflows, ${manifestStats.agents} agents, ${manifestStats.tasks} tasks`,
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
// Configure IDEs and copy documentation
|
|
271
|
+
if (!config.skipIde && config.ides && config.ides.length > 0) {
|
|
272
|
+
spinner.start('Configuring IDEs...');
|
|
273
|
+
|
|
274
|
+
// Temporarily suppress console output if not verbose
|
|
275
|
+
const originalLog = console.log;
|
|
276
|
+
if (!config.verbose) {
|
|
277
|
+
console.log = () => {};
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
for (const ide of config.ides) {
|
|
281
|
+
spinner.text = `Configuring ${ide}...`;
|
|
282
|
+
|
|
283
|
+
// Pass pre-collected configuration to avoid re-prompting
|
|
284
|
+
await this.ideManager.setup(ide, projectDir, bmadDir, {
|
|
285
|
+
selectedModules: config.modules || [],
|
|
286
|
+
preCollectedConfig: ideConfigurations[ide] || null,
|
|
287
|
+
verbose: config.verbose,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Restore console.log
|
|
292
|
+
console.log = originalLog;
|
|
293
|
+
|
|
294
|
+
spinner.succeed(`Configured ${config.ides.length} IDE${config.ides.length > 1 ? 's' : ''}`);
|
|
295
|
+
|
|
296
|
+
// Copy IDE-specific documentation
|
|
297
|
+
spinner.start('Copying IDE documentation...');
|
|
298
|
+
await this.copyIdeDocumentation(config.ides, bmadDir);
|
|
299
|
+
spinner.succeed('IDE documentation copied');
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Run module-specific installers after IDE setup
|
|
303
|
+
spinner.start('Running module-specific installers...');
|
|
304
|
+
|
|
305
|
+
// Run core module installer if core was installed
|
|
306
|
+
if (config.installCore || resolution.byModule.core) {
|
|
307
|
+
spinner.text = 'Running core module installer...';
|
|
308
|
+
|
|
309
|
+
await this.moduleManager.runModuleInstaller('core', bmadDir, {
|
|
310
|
+
installedIDEs: config.ides || [],
|
|
311
|
+
moduleConfig: moduleConfigs.core || {},
|
|
312
|
+
logger: {
|
|
313
|
+
log: (msg) => console.log(msg),
|
|
314
|
+
error: (msg) => console.error(msg),
|
|
315
|
+
warn: (msg) => console.warn(msg),
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Run installers for user-selected modules
|
|
321
|
+
if (config.modules && config.modules.length > 0) {
|
|
322
|
+
for (const moduleName of config.modules) {
|
|
323
|
+
spinner.text = `Running ${moduleName} module installer...`;
|
|
324
|
+
|
|
325
|
+
// Pass installed IDEs and module config to module installer
|
|
326
|
+
await this.moduleManager.runModuleInstaller(moduleName, bmadDir, {
|
|
327
|
+
installedIDEs: config.ides || [],
|
|
328
|
+
moduleConfig: moduleConfigs[moduleName] || {},
|
|
329
|
+
logger: {
|
|
330
|
+
log: (msg) => console.log(msg),
|
|
331
|
+
error: (msg) => console.error(msg),
|
|
332
|
+
warn: (msg) => console.warn(msg),
|
|
333
|
+
},
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
spinner.succeed('Module-specific installers completed');
|
|
339
|
+
|
|
340
|
+
// Create manifest
|
|
341
|
+
spinner.start('Creating installation manifest...');
|
|
342
|
+
const manifestResult = await this.manifest.create(
|
|
343
|
+
bmadDir,
|
|
344
|
+
{
|
|
345
|
+
version: require(path.join(getProjectRoot(), 'package.json')).version,
|
|
346
|
+
installDate: new Date().toISOString(),
|
|
347
|
+
core: config.installCore,
|
|
348
|
+
modules: config.modules || [],
|
|
349
|
+
ides: config.ides || [],
|
|
350
|
+
language: config.language || null,
|
|
351
|
+
},
|
|
352
|
+
this.installedFiles,
|
|
353
|
+
);
|
|
354
|
+
spinner.succeed(`Manifest created (${manifestResult.filesTracked} files tracked)`);
|
|
355
|
+
|
|
356
|
+
spinner.stop();
|
|
357
|
+
|
|
358
|
+
// Display completion message
|
|
359
|
+
const { UI } = require('../../../lib/ui');
|
|
360
|
+
const ui = new UI();
|
|
361
|
+
ui.showInstallSummary({
|
|
362
|
+
path: bmadDir,
|
|
363
|
+
modules: config.modules,
|
|
364
|
+
ides: config.ides,
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
return { success: true, path: bmadDir, modules: config.modules, ides: config.ides };
|
|
368
|
+
} catch (error) {
|
|
369
|
+
spinner.fail('Installation failed');
|
|
370
|
+
throw error;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Update existing installation
|
|
376
|
+
*/
|
|
377
|
+
async update(config) {
|
|
378
|
+
const spinner = ora('Checking installation...').start();
|
|
379
|
+
|
|
380
|
+
try {
|
|
381
|
+
const bmadDir = path.join(path.resolve(config.directory), 'bmad');
|
|
382
|
+
const existingInstall = await this.detector.detect(bmadDir);
|
|
383
|
+
|
|
384
|
+
if (!existingInstall.installed) {
|
|
385
|
+
spinner.fail('No BMAD installation found');
|
|
386
|
+
throw new Error(`No BMAD installation found at ${bmadDir}`);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
spinner.text = 'Analyzing update requirements...';
|
|
390
|
+
|
|
391
|
+
// Compare versions and determine what needs updating
|
|
392
|
+
const currentVersion = existingInstall.version;
|
|
393
|
+
const newVersion = require(path.join(getProjectRoot(), 'package.json')).version;
|
|
394
|
+
|
|
395
|
+
if (config.dryRun) {
|
|
396
|
+
spinner.stop();
|
|
397
|
+
console.log(chalk.cyan('\n🔍 Update Preview (Dry Run)\n'));
|
|
398
|
+
console.log(chalk.bold('Current version:'), currentVersion);
|
|
399
|
+
console.log(chalk.bold('New version:'), newVersion);
|
|
400
|
+
console.log(chalk.bold('Core:'), existingInstall.hasCore ? 'Will be updated' : 'Not installed');
|
|
401
|
+
|
|
402
|
+
if (existingInstall.modules.length > 0) {
|
|
403
|
+
console.log(chalk.bold('\nModules to update:'));
|
|
404
|
+
for (const mod of existingInstall.modules) {
|
|
405
|
+
console.log(` - ${mod.id}`);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// Perform actual update
|
|
412
|
+
if (existingInstall.hasCore) {
|
|
413
|
+
spinner.text = 'Updating core...';
|
|
414
|
+
await this.updateCore(bmadDir, config.force);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
for (const module of existingInstall.modules) {
|
|
418
|
+
spinner.text = `Updating module: ${module.id}...`;
|
|
419
|
+
await this.moduleManager.update(module.id, bmadDir, config.force);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// Update manifest
|
|
423
|
+
spinner.text = 'Updating manifest...';
|
|
424
|
+
await this.manifest.update(bmadDir, {
|
|
425
|
+
version: newVersion,
|
|
426
|
+
updateDate: new Date().toISOString(),
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
spinner.succeed('Update complete');
|
|
430
|
+
return { success: true };
|
|
431
|
+
} catch (error) {
|
|
432
|
+
spinner.fail('Update failed');
|
|
433
|
+
throw error;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Get installation status
|
|
439
|
+
*/
|
|
440
|
+
async getStatus(directory) {
|
|
441
|
+
const bmadDir = path.join(path.resolve(directory), 'bmad');
|
|
442
|
+
return await this.detector.detect(bmadDir);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Get available modules
|
|
447
|
+
*/
|
|
448
|
+
async getAvailableModules() {
|
|
449
|
+
return await this.moduleManager.listAvailable();
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Uninstall BMAD
|
|
454
|
+
*/
|
|
455
|
+
async uninstall(directory) {
|
|
456
|
+
const bmadDir = path.join(path.resolve(directory), 'bmad');
|
|
457
|
+
|
|
458
|
+
if (await fs.pathExists(bmadDir)) {
|
|
459
|
+
await fs.remove(bmadDir);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Clean up IDE configurations
|
|
463
|
+
await this.ideManager.cleanup(path.resolve(directory));
|
|
464
|
+
|
|
465
|
+
return { success: true };
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Private: Create directory structure
|
|
470
|
+
*/
|
|
471
|
+
async createDirectoryStructure(bmadDir) {
|
|
472
|
+
await fs.ensureDir(bmadDir);
|
|
473
|
+
await fs.ensureDir(path.join(bmadDir, '_cfg'));
|
|
474
|
+
await fs.ensureDir(path.join(bmadDir, '_cfg', 'agents'));
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Generate clean config.yaml files for each installed module
|
|
479
|
+
* @param {string} bmadDir - BMAD installation directory
|
|
480
|
+
* @param {Object} moduleConfigs - Collected configuration values
|
|
481
|
+
*/
|
|
482
|
+
async generateModuleConfigs(bmadDir, moduleConfigs) {
|
|
483
|
+
const yaml = require('js-yaml');
|
|
484
|
+
|
|
485
|
+
// Extract core config values to share with other modules
|
|
486
|
+
const coreConfig = moduleConfigs.core || {};
|
|
487
|
+
|
|
488
|
+
// Get all installed module directories
|
|
489
|
+
const entries = await fs.readdir(bmadDir, { withFileTypes: true });
|
|
490
|
+
const installedModules = entries
|
|
491
|
+
.filter((entry) => entry.isDirectory() && entry.name !== '_cfg' && entry.name !== 'docs')
|
|
492
|
+
.map((entry) => entry.name);
|
|
493
|
+
|
|
494
|
+
// Generate config.yaml for each installed module
|
|
495
|
+
for (const moduleName of installedModules) {
|
|
496
|
+
const modulePath = path.join(bmadDir, moduleName);
|
|
497
|
+
|
|
498
|
+
// Get module-specific config or use empty object if none
|
|
499
|
+
const config = moduleConfigs[moduleName] || {};
|
|
500
|
+
|
|
501
|
+
if (await fs.pathExists(modulePath)) {
|
|
502
|
+
const configPath = path.join(modulePath, 'config.yaml');
|
|
503
|
+
|
|
504
|
+
// Create header
|
|
505
|
+
const packageJson = require(path.join(getProjectRoot(), 'package.json'));
|
|
506
|
+
const header = `# ${moduleName.toUpperCase()} Module Configuration
|
|
507
|
+
# Generated by BMAD installer
|
|
508
|
+
# Version: ${packageJson.version}
|
|
509
|
+
# Date: ${new Date().toISOString()}
|
|
510
|
+
|
|
511
|
+
`;
|
|
512
|
+
|
|
513
|
+
// For non-core modules, add core config values directly
|
|
514
|
+
let finalConfig = { ...config };
|
|
515
|
+
let coreSection = '';
|
|
516
|
+
|
|
517
|
+
if (moduleName !== 'core' && coreConfig && Object.keys(coreConfig).length > 0) {
|
|
518
|
+
// Add core values directly to the module config
|
|
519
|
+
// These will be available for reference in the module
|
|
520
|
+
finalConfig = {
|
|
521
|
+
...config,
|
|
522
|
+
...coreConfig, // Spread core config values directly into the module config
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
// Create a comment section to identify core values
|
|
526
|
+
coreSection = '\n# Core Configuration Values\n';
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// Convert config to YAML
|
|
530
|
+
let yamlContent = yaml.dump(finalConfig, {
|
|
531
|
+
indent: 2,
|
|
532
|
+
lineWidth: -1,
|
|
533
|
+
noRefs: true,
|
|
534
|
+
sortKeys: false,
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
// If we have core values, reorganize the YAML to group them with their comment
|
|
538
|
+
if (coreSection && moduleName !== 'core') {
|
|
539
|
+
// Split the YAML into lines
|
|
540
|
+
const lines = yamlContent.split('\n');
|
|
541
|
+
const moduleConfigLines = [];
|
|
542
|
+
const coreConfigLines = [];
|
|
543
|
+
|
|
544
|
+
// Separate module-specific and core config lines
|
|
545
|
+
for (const line of lines) {
|
|
546
|
+
const key = line.split(':')[0].trim();
|
|
547
|
+
if (Object.prototype.hasOwnProperty.call(coreConfig, key)) {
|
|
548
|
+
coreConfigLines.push(line);
|
|
549
|
+
} else {
|
|
550
|
+
moduleConfigLines.push(line);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// Rebuild YAML with module config first, then core config with comment
|
|
555
|
+
yamlContent = moduleConfigLines.join('\n');
|
|
556
|
+
if (coreConfigLines.length > 0) {
|
|
557
|
+
yamlContent += coreSection + coreConfigLines.join('\n');
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// Write the clean config file
|
|
562
|
+
await fs.writeFile(configPath, header + yamlContent, 'utf8');
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Install core with resolved dependencies
|
|
569
|
+
* @param {string} bmadDir - BMAD installation directory
|
|
570
|
+
* @param {Object} coreFiles - Core files to install
|
|
571
|
+
*/
|
|
572
|
+
async installCoreWithDependencies(bmadDir, coreFiles) {
|
|
573
|
+
const sourcePath = getModulePath('core');
|
|
574
|
+
const targetPath = path.join(bmadDir, 'core');
|
|
575
|
+
|
|
576
|
+
// Install full core
|
|
577
|
+
await this.installCore(bmadDir);
|
|
578
|
+
|
|
579
|
+
// If there are specific dependency files, ensure they're included
|
|
580
|
+
if (coreFiles) {
|
|
581
|
+
// Already handled by installCore for core module
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Install module with resolved dependencies
|
|
587
|
+
* @param {string} moduleName - Module name
|
|
588
|
+
* @param {string} bmadDir - BMAD installation directory
|
|
589
|
+
* @param {Object} moduleFiles - Module files to install
|
|
590
|
+
*/
|
|
591
|
+
async installModuleWithDependencies(moduleName, bmadDir, moduleFiles) {
|
|
592
|
+
// Use existing module manager for full installation with file tracking
|
|
593
|
+
// Note: Module-specific installers are called separately after IDE setup
|
|
594
|
+
await this.moduleManager.install(
|
|
595
|
+
moduleName,
|
|
596
|
+
bmadDir,
|
|
597
|
+
(filePath) => {
|
|
598
|
+
this.installedFiles.push(filePath);
|
|
599
|
+
},
|
|
600
|
+
{
|
|
601
|
+
skipModuleInstaller: true, // We'll run it later after IDE setup
|
|
602
|
+
},
|
|
603
|
+
);
|
|
604
|
+
|
|
605
|
+
// Dependencies are already included in full module install
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* Install partial module (only dependencies needed by other modules)
|
|
610
|
+
*/
|
|
611
|
+
async installPartialModule(moduleName, bmadDir, files) {
|
|
612
|
+
const sourceBase = getModulePath(moduleName);
|
|
613
|
+
const targetBase = path.join(bmadDir, moduleName);
|
|
614
|
+
|
|
615
|
+
// Create module directory
|
|
616
|
+
await fs.ensureDir(targetBase);
|
|
617
|
+
|
|
618
|
+
// Copy only the required dependency files
|
|
619
|
+
if (files.agents && files.agents.length > 0) {
|
|
620
|
+
const agentsDir = path.join(targetBase, 'agents');
|
|
621
|
+
await fs.ensureDir(agentsDir);
|
|
622
|
+
|
|
623
|
+
for (const agentPath of files.agents) {
|
|
624
|
+
const fileName = path.basename(agentPath);
|
|
625
|
+
const sourcePath = path.join(sourceBase, 'agents', fileName);
|
|
626
|
+
const targetPath = path.join(agentsDir, fileName);
|
|
627
|
+
|
|
628
|
+
if (await fs.pathExists(sourcePath)) {
|
|
629
|
+
await fs.copy(sourcePath, targetPath);
|
|
630
|
+
this.installedFiles.push(targetPath);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
if (files.tasks && files.tasks.length > 0) {
|
|
636
|
+
const tasksDir = path.join(targetBase, 'tasks');
|
|
637
|
+
await fs.ensureDir(tasksDir);
|
|
638
|
+
|
|
639
|
+
for (const taskPath of files.tasks) {
|
|
640
|
+
const fileName = path.basename(taskPath);
|
|
641
|
+
const sourcePath = path.join(sourceBase, 'tasks', fileName);
|
|
642
|
+
const targetPath = path.join(tasksDir, fileName);
|
|
643
|
+
|
|
644
|
+
if (await fs.pathExists(sourcePath)) {
|
|
645
|
+
await fs.copy(sourcePath, targetPath);
|
|
646
|
+
this.installedFiles.push(targetPath);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
if (files.templates && files.templates.length > 0) {
|
|
652
|
+
const templatesDir = path.join(targetBase, 'templates');
|
|
653
|
+
await fs.ensureDir(templatesDir);
|
|
654
|
+
|
|
655
|
+
for (const templatePath of files.templates) {
|
|
656
|
+
const fileName = path.basename(templatePath);
|
|
657
|
+
const sourcePath = path.join(sourceBase, 'templates', fileName);
|
|
658
|
+
const targetPath = path.join(templatesDir, fileName);
|
|
659
|
+
|
|
660
|
+
if (await fs.pathExists(sourcePath)) {
|
|
661
|
+
await fs.copy(sourcePath, targetPath);
|
|
662
|
+
this.installedFiles.push(targetPath);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
if (files.data && files.data.length > 0) {
|
|
668
|
+
for (const dataPath of files.data) {
|
|
669
|
+
// Preserve directory structure for data files
|
|
670
|
+
const relative = path.relative(sourceBase, dataPath);
|
|
671
|
+
const targetPath = path.join(targetBase, relative);
|
|
672
|
+
|
|
673
|
+
await fs.ensureDir(path.dirname(targetPath));
|
|
674
|
+
|
|
675
|
+
if (await fs.pathExists(dataPath)) {
|
|
676
|
+
await fs.copy(dataPath, targetPath);
|
|
677
|
+
this.installedFiles.push(targetPath);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// Create a marker file to indicate this is a partial installation
|
|
683
|
+
const markerPath = path.join(targetBase, '.partial');
|
|
684
|
+
await fs.writeFile(
|
|
685
|
+
markerPath,
|
|
686
|
+
`This module contains only dependencies required by other modules.\nInstalled: ${new Date().toISOString()}\n`,
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* Private: Install core
|
|
692
|
+
* @param {string} bmadDir - BMAD installation directory
|
|
693
|
+
*/
|
|
694
|
+
async installCore(bmadDir) {
|
|
695
|
+
const sourcePath = getModulePath('core');
|
|
696
|
+
const targetPath = path.join(bmadDir, 'core');
|
|
697
|
+
|
|
698
|
+
// Copy core files with filtering for localskip agents
|
|
699
|
+
await this.copyDirectoryWithFiltering(sourcePath, targetPath);
|
|
700
|
+
|
|
701
|
+
// Process agent files to inject activation block
|
|
702
|
+
await this.processAgentFiles(targetPath, 'core');
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* Copy directory with filtering for localskip agents
|
|
707
|
+
* @param {string} sourcePath - Source directory path
|
|
708
|
+
* @param {string} targetPath - Target directory path
|
|
709
|
+
*/
|
|
710
|
+
async copyDirectoryWithFiltering(sourcePath, targetPath) {
|
|
711
|
+
// Get all files in source directory
|
|
712
|
+
const files = await this.getFileList(sourcePath);
|
|
713
|
+
|
|
714
|
+
for (const file of files) {
|
|
715
|
+
// Skip config.yaml templates - we'll generate clean ones with actual values
|
|
716
|
+
if (file === 'config.yaml' || file.endsWith('/config.yaml')) {
|
|
717
|
+
continue;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
const sourceFile = path.join(sourcePath, file);
|
|
721
|
+
const targetFile = path.join(targetPath, file);
|
|
722
|
+
|
|
723
|
+
// Check if this is an agent file
|
|
724
|
+
if (file.includes('agents/') && file.endsWith('.md')) {
|
|
725
|
+
// Read the file to check for localskip
|
|
726
|
+
const content = await fs.readFile(sourceFile, 'utf8');
|
|
727
|
+
|
|
728
|
+
// Check for localskip="true" in the agent tag
|
|
729
|
+
const agentMatch = content.match(/<agent[^>]*\slocalskip="true"[^>]*>/);
|
|
730
|
+
if (agentMatch) {
|
|
731
|
+
console.log(chalk.dim(` Skipping web-only agent: ${path.basename(file)}`));
|
|
732
|
+
continue; // Skip this agent
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// Copy the file
|
|
737
|
+
await fs.ensureDir(path.dirname(targetFile));
|
|
738
|
+
await fs.copy(sourceFile, targetFile, { overwrite: true });
|
|
739
|
+
|
|
740
|
+
// Track the installed file
|
|
741
|
+
this.installedFiles.push(targetFile);
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/**
|
|
746
|
+
* Get list of all files in a directory recursively
|
|
747
|
+
* @param {string} dir - Directory path
|
|
748
|
+
* @param {string} baseDir - Base directory for relative paths
|
|
749
|
+
* @returns {Array} List of relative file paths
|
|
750
|
+
*/
|
|
751
|
+
async getFileList(dir, baseDir = dir) {
|
|
752
|
+
const files = [];
|
|
753
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
754
|
+
|
|
755
|
+
for (const entry of entries) {
|
|
756
|
+
const fullPath = path.join(dir, entry.name);
|
|
757
|
+
|
|
758
|
+
if (entry.isDirectory()) {
|
|
759
|
+
// Skip _module-installer directories
|
|
760
|
+
if (entry.name === '_module-installer') {
|
|
761
|
+
continue;
|
|
762
|
+
}
|
|
763
|
+
const subFiles = await this.getFileList(fullPath, baseDir);
|
|
764
|
+
files.push(...subFiles);
|
|
765
|
+
} else {
|
|
766
|
+
files.push(path.relative(baseDir, fullPath));
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
return files;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/**
|
|
774
|
+
* Process agent files to inject activation block
|
|
775
|
+
* @param {string} modulePath - Path to module
|
|
776
|
+
* @param {string} moduleName - Module name
|
|
777
|
+
*/
|
|
778
|
+
async processAgentFiles(modulePath, moduleName) {
|
|
779
|
+
const agentsPath = path.join(modulePath, 'agents');
|
|
780
|
+
|
|
781
|
+
// Check if agents directory exists
|
|
782
|
+
if (!(await fs.pathExists(agentsPath))) {
|
|
783
|
+
return; // No agents to process
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// Get all agent files
|
|
787
|
+
const agentFiles = await fs.readdir(agentsPath);
|
|
788
|
+
|
|
789
|
+
for (const agentFile of agentFiles) {
|
|
790
|
+
if (!agentFile.endsWith('.md')) continue;
|
|
791
|
+
|
|
792
|
+
const agentPath = path.join(agentsPath, agentFile);
|
|
793
|
+
let content = await fs.readFile(agentPath, 'utf8');
|
|
794
|
+
|
|
795
|
+
// Check if content has agent XML and no activation block
|
|
796
|
+
if (content.includes('<agent') && !content.includes('<activation')) {
|
|
797
|
+
// Inject the activation block using XML handler
|
|
798
|
+
content = this.xmlHandler.injectActivationSimple(content);
|
|
799
|
+
await fs.writeFile(agentPath, content, 'utf8');
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/**
|
|
805
|
+
* Private: Update core
|
|
806
|
+
*/
|
|
807
|
+
async updateCore(bmadDir, force = false) {
|
|
808
|
+
const sourcePath = getModulePath('core');
|
|
809
|
+
const targetPath = path.join(bmadDir, 'core');
|
|
810
|
+
|
|
811
|
+
if (force) {
|
|
812
|
+
await fs.remove(targetPath);
|
|
813
|
+
await this.installCore(bmadDir);
|
|
814
|
+
} else {
|
|
815
|
+
// Selective update - preserve user modifications
|
|
816
|
+
await this.fileOps.syncDirectory(sourcePath, targetPath);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
/**
|
|
821
|
+
* Private: Prompt for update action
|
|
822
|
+
*/
|
|
823
|
+
async promptUpdateAction() {
|
|
824
|
+
const inquirer = require('inquirer');
|
|
825
|
+
return await inquirer.prompt([
|
|
826
|
+
{
|
|
827
|
+
type: 'list',
|
|
828
|
+
name: 'action',
|
|
829
|
+
message: 'What would you like to do?',
|
|
830
|
+
choices: [
|
|
831
|
+
{ name: 'Update existing installation', value: 'update' },
|
|
832
|
+
{ name: 'Remove and reinstall', value: 'reinstall' },
|
|
833
|
+
{ name: 'Cancel', value: 'cancel' },
|
|
834
|
+
],
|
|
835
|
+
},
|
|
836
|
+
]);
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Private: Create formatted error for legacy BMAD v4 detection
|
|
841
|
+
* @param {Object} legacyV4 - Legacy V4 detection result with offenders array
|
|
842
|
+
* @returns {Error} Formatted error with fullMessage property
|
|
843
|
+
*/
|
|
844
|
+
createLegacyV4Error(legacyV4) {
|
|
845
|
+
const error = new Error('Legacy BMAD v4 artefacts detected in project. Remove them to continue.');
|
|
846
|
+
|
|
847
|
+
// Build the complete formatted message using template literals
|
|
848
|
+
const headerMessage = `
|
|
849
|
+
${chalk.red.bold('Blocked: Legacy BMAD v4 detected')}
|
|
850
|
+
The installer found legacy artefacts in your project.`;
|
|
851
|
+
|
|
852
|
+
const offendersMessage = `
|
|
853
|
+
Offending paths:
|
|
854
|
+
${legacyV4.offenders.map((p) => ` - ${p}`).join('\n')}
|
|
855
|
+
|
|
856
|
+
Cleanup commands you can copy/paste:
|
|
857
|
+
${chalk.cyan('macOS/Linux:')}
|
|
858
|
+
${legacyV4.offenders.map((p) => ` rm -rf '${p}'`).join('\n')}
|
|
859
|
+
${chalk.cyan('Windows:')}
|
|
860
|
+
${legacyV4.offenders.map((p) => ` rmdir /S /Q "${p}"`).join('\n')}`;
|
|
861
|
+
|
|
862
|
+
const footerMessage = `
|
|
863
|
+
Remove the listed paths (case sensitive) and rerun install.
|
|
864
|
+
Note: You may also want to remove other BMAD-related v4 files/folders left over in this project. If you have customizations, back them up or migrate them before deleting.`;
|
|
865
|
+
|
|
866
|
+
// Attach the complete formatted message
|
|
867
|
+
error.fullMessage = headerMessage + offendersMessage + footerMessage;
|
|
868
|
+
|
|
869
|
+
return error;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* Private: Create agent configuration files
|
|
874
|
+
* @param {string} bmadDir - BMAD installation directory
|
|
875
|
+
* @param {Object} userInfo - User information including name and language
|
|
876
|
+
*/
|
|
877
|
+
async createAgentConfigs(bmadDir, userInfo = null) {
|
|
878
|
+
const agentConfigDir = path.join(bmadDir, '_cfg', 'agents');
|
|
879
|
+
await fs.ensureDir(agentConfigDir);
|
|
880
|
+
|
|
881
|
+
// Get all agents from all modules
|
|
882
|
+
const agents = [];
|
|
883
|
+
const agentDetails = []; // For manifest generation
|
|
884
|
+
|
|
885
|
+
// Check modules for agents (including core)
|
|
886
|
+
const entries = await fs.readdir(bmadDir, { withFileTypes: true });
|
|
887
|
+
for (const entry of entries) {
|
|
888
|
+
if (entry.isDirectory() && entry.name !== '_cfg') {
|
|
889
|
+
const moduleAgentsPath = path.join(bmadDir, entry.name, 'agents');
|
|
890
|
+
if (await fs.pathExists(moduleAgentsPath)) {
|
|
891
|
+
const agentFiles = await fs.readdir(moduleAgentsPath);
|
|
892
|
+
for (const agentFile of agentFiles) {
|
|
893
|
+
if (agentFile.endsWith('.md')) {
|
|
894
|
+
const agentPath = path.join(moduleAgentsPath, agentFile);
|
|
895
|
+
const agentContent = await fs.readFile(agentPath, 'utf8');
|
|
896
|
+
|
|
897
|
+
// Skip agents with localskip="true"
|
|
898
|
+
const hasLocalSkip = agentContent.match(/<agent[^>]*\slocalskip="true"[^>]*>/);
|
|
899
|
+
if (hasLocalSkip) {
|
|
900
|
+
continue; // Skip this agent - it should not have been installed
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
const agentName = path.basename(agentFile, '.md');
|
|
904
|
+
|
|
905
|
+
// Extract any nodes with agentConfig="true"
|
|
906
|
+
const agentConfigNodes = this.extractAgentConfigNodes(agentContent);
|
|
907
|
+
|
|
908
|
+
agents.push({
|
|
909
|
+
name: agentName,
|
|
910
|
+
module: entry.name,
|
|
911
|
+
agentConfigNodes: agentConfigNodes,
|
|
912
|
+
});
|
|
913
|
+
|
|
914
|
+
// Use shared AgentPartyGenerator to extract details
|
|
915
|
+
let details = AgentPartyGenerator.extractAgentDetails(agentContent, entry.name, agentName);
|
|
916
|
+
|
|
917
|
+
// Apply config overrides if they exist
|
|
918
|
+
if (details) {
|
|
919
|
+
const configPath = path.join(agentConfigDir, `${entry.name}-${agentName}.md`);
|
|
920
|
+
if (await fs.pathExists(configPath)) {
|
|
921
|
+
const configContent = await fs.readFile(configPath, 'utf8');
|
|
922
|
+
details = AgentPartyGenerator.applyConfigOverrides(details, configContent);
|
|
923
|
+
}
|
|
924
|
+
agentDetails.push(details);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
// Create config file for each agent
|
|
933
|
+
let createdCount = 0;
|
|
934
|
+
let skippedCount = 0;
|
|
935
|
+
|
|
936
|
+
// Load agent config template
|
|
937
|
+
const templatePath = getSourcePath('utility', 'models', 'agent-config-template.md');
|
|
938
|
+
const templateContent = await fs.readFile(templatePath, 'utf8');
|
|
939
|
+
|
|
940
|
+
for (const agent of agents) {
|
|
941
|
+
const configPath = path.join(agentConfigDir, `${agent.module}-${agent.name}.md`);
|
|
942
|
+
|
|
943
|
+
// Skip if config file already exists (preserve custom configurations)
|
|
944
|
+
if (await fs.pathExists(configPath)) {
|
|
945
|
+
skippedCount++;
|
|
946
|
+
continue;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
// Build config content header
|
|
950
|
+
let configContent = `# Agent Config: ${agent.name}\n\n`;
|
|
951
|
+
|
|
952
|
+
// Process template and add agent-specific config nodes
|
|
953
|
+
let processedTemplate = templateContent;
|
|
954
|
+
|
|
955
|
+
// Replace {core:user_name} placeholder with actual user name if available
|
|
956
|
+
if (userInfo && userInfo.userName) {
|
|
957
|
+
processedTemplate = processedTemplate.replaceAll('{core:user_name}', userInfo.userName);
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
// Replace {core:communication_language} placeholder with actual language if available
|
|
961
|
+
if (userInfo && userInfo.responseLanguage) {
|
|
962
|
+
processedTemplate = processedTemplate.replaceAll('{core:communication_language}', userInfo.responseLanguage);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
// If this agent has agentConfig nodes, add them after the existing comment
|
|
966
|
+
if (agent.agentConfigNodes && agent.agentConfigNodes.length > 0) {
|
|
967
|
+
// Find the agent-specific configuration nodes comment
|
|
968
|
+
const commentPattern = /(\s*<!-- Agent-specific configuration nodes -->)/;
|
|
969
|
+
const commentMatch = processedTemplate.match(commentPattern);
|
|
970
|
+
|
|
971
|
+
if (commentMatch) {
|
|
972
|
+
// Add nodes right after the comment
|
|
973
|
+
let agentSpecificNodes = '';
|
|
974
|
+
for (const node of agent.agentConfigNodes) {
|
|
975
|
+
agentSpecificNodes += `\n ${node}`;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
processedTemplate = processedTemplate.replace(commentPattern, `$1${agentSpecificNodes}`);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
configContent += processedTemplate;
|
|
983
|
+
|
|
984
|
+
await fs.writeFile(configPath, configContent, 'utf8');
|
|
985
|
+
createdCount++;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
// Generate agent manifest with overrides applied
|
|
989
|
+
await this.generateAgentManifest(bmadDir, agentDetails);
|
|
990
|
+
|
|
991
|
+
return { total: agents.length, created: createdCount, skipped: skippedCount };
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
/**
|
|
995
|
+
* Generate agent manifest XML file
|
|
996
|
+
* @param {string} bmadDir - BMAD installation directory
|
|
997
|
+
* @param {Array} agentDetails - Array of agent details
|
|
998
|
+
*/
|
|
999
|
+
async generateAgentManifest(bmadDir, agentDetails) {
|
|
1000
|
+
const manifestPath = path.join(bmadDir, '_cfg', 'agent-party.xml');
|
|
1001
|
+
await AgentPartyGenerator.writeAgentParty(manifestPath, agentDetails, { forWeb: false });
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/**
|
|
1005
|
+
* Extract nodes with agentConfig="true" from agent content
|
|
1006
|
+
* @param {string} content - Agent file content
|
|
1007
|
+
* @returns {Array} Array of XML nodes that should be added to agent config
|
|
1008
|
+
*/
|
|
1009
|
+
extractAgentConfigNodes(content) {
|
|
1010
|
+
const nodes = [];
|
|
1011
|
+
|
|
1012
|
+
try {
|
|
1013
|
+
// Find all XML nodes with agentConfig="true"
|
|
1014
|
+
// Match self-closing tags and tags with content
|
|
1015
|
+
const selfClosingPattern = /<([a-zA-Z][a-zA-Z0-9_-]*)\s+[^>]*agentConfig="true"[^>]*\/>/g;
|
|
1016
|
+
const withContentPattern = /<([a-zA-Z][a-zA-Z0-9_-]*)\s+[^>]*agentConfig="true"[^>]*>([\s\S]*?)<\/\1>/g;
|
|
1017
|
+
|
|
1018
|
+
// Extract self-closing tags
|
|
1019
|
+
let match;
|
|
1020
|
+
while ((match = selfClosingPattern.exec(content)) !== null) {
|
|
1021
|
+
// Extract just the tag without children (structure only)
|
|
1022
|
+
const tagMatch = match[0].match(/<([a-zA-Z][a-zA-Z0-9_-]*)([^>]*)\/>/);
|
|
1023
|
+
if (tagMatch) {
|
|
1024
|
+
const tagName = tagMatch[1];
|
|
1025
|
+
const attributes = tagMatch[2].replace(/\s*agentConfig="true"/, ''); // Remove agentConfig attribute
|
|
1026
|
+
nodes.push(`<${tagName}${attributes}></${tagName}>`);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
// Extract tags with content
|
|
1031
|
+
while ((match = withContentPattern.exec(content)) !== null) {
|
|
1032
|
+
const fullMatch = match[0];
|
|
1033
|
+
const tagName = match[1];
|
|
1034
|
+
|
|
1035
|
+
// Extract opening tag with attributes (removing agentConfig="true")
|
|
1036
|
+
const openingTagMatch = fullMatch.match(new RegExp(`<${tagName}([^>]*)>`));
|
|
1037
|
+
if (openingTagMatch) {
|
|
1038
|
+
const attributes = openingTagMatch[1].replace(/\s*agentConfig="true"/, '');
|
|
1039
|
+
// Add empty node structure (no children)
|
|
1040
|
+
nodes.push(`<${tagName}${attributes}></${tagName}>`);
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
} catch (error) {
|
|
1044
|
+
console.error('Error extracting agentConfig nodes:', error);
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
return nodes;
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
/**
|
|
1051
|
+
* Copy IDE-specific documentation to BMAD docs
|
|
1052
|
+
* @param {Array} ides - List of selected IDEs
|
|
1053
|
+
* @param {string} bmadDir - BMAD installation directory
|
|
1054
|
+
*/
|
|
1055
|
+
async copyIdeDocumentation(ides, bmadDir) {
|
|
1056
|
+
const docsDir = path.join(bmadDir, 'docs');
|
|
1057
|
+
await fs.ensureDir(docsDir);
|
|
1058
|
+
|
|
1059
|
+
for (const ide of ides) {
|
|
1060
|
+
const sourceDocPath = path.join(getProjectRoot(), 'docs', 'ide-info', `${ide}.md`);
|
|
1061
|
+
const targetDocPath = path.join(docsDir, `${ide}-instructions.md`);
|
|
1062
|
+
|
|
1063
|
+
if (await fs.pathExists(sourceDocPath)) {
|
|
1064
|
+
await fs.copy(sourceDocPath, targetDocPath, { overwrite: true });
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
module.exports = { Installer };
|