bmad-method 6.0.0-alpha.2 → 6.0.0-alpha.20
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/.coderabbit.yaml +40 -0
- package/.github/CODE_OF_CONDUCT.md +128 -0
- package/.github/ISSUE_TEMPLATE/idea_submission.md +2 -2
- package/.github/scripts/discord-helpers.sh +34 -0
- package/.github/workflows/bundle-latest.yaml +329 -0
- package/.github/workflows/discord.yaml +302 -8
- package/.github/workflows/docs.yaml +72 -0
- package/.github/workflows/manual-release.yaml +35 -18
- package/.github/workflows/quality.yaml +94 -0
- package/.husky/pre-commit +4 -0
- package/.markdownlint-cli2.yaml +42 -0
- package/.prettierignore +7 -0
- package/.vscode/settings.json +4 -2
- package/CHANGELOG.md +678 -13
- package/CONTRIBUTING.md +2 -16
- package/LICENSE +1 -1
- package/README.md +159 -177
- package/docs/BUNDLE_DISTRIBUTION_SETUP.md +95 -0
- package/docs/agent-customization-guide.md +208 -0
- package/docs/custom-content-installation.md +149 -0
- package/docs/custom-content.md +122 -0
- package/docs/document-sharding-guide.md +449 -0
- package/docs/getting-started/installation.md +76 -0
- package/docs/ide-info/crush.md +1 -1
- package/docs/ide-info/cursor.md +7 -7
- package/docs/ide-info/iflow.md +3 -3
- package/docs/ide-info/index.md +24 -0
- package/docs/ide-info/opencode.md +1 -1
- package/docs/ide-info/rovo-dev.md +22 -0
- package/docs/index.md +143 -0
- package/docs/v4-to-v6-upgrade.md +38 -36
- package/docs/web-bundles-gemini-gpt-guide.md +21 -0
- package/eslint.config.mjs +23 -2
- package/package.json +24 -9
- package/samples/sample-custom-modules/README.md +11 -0
- package/samples/sample-custom-modules/sample-unitary-module/README.md +8 -0
- package/samples/sample-custom-modules/sample-unitary-module/agents/commit-poet/commit-poet.agent.yaml +129 -0
- package/samples/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith-sidecar/instructions.md +70 -0
- package/samples/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith-sidecar/knowledge/bundlers.md +111 -0
- package/samples/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith-sidecar/knowledge/deploy.md +70 -0
- package/samples/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith-sidecar/knowledge/docs.md +114 -0
- package/samples/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith-sidecar/knowledge/installers.md +134 -0
- package/samples/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith-sidecar/knowledge/modules.md +161 -0
- package/samples/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith-sidecar/knowledge/tests.md +103 -0
- package/samples/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith-sidecar/memories.md +17 -0
- package/samples/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith.agent.yaml +109 -0
- package/samples/sample-custom-modules/sample-unitary-module/module.yaml +8 -0
- package/samples/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-01-init.md +168 -0
- package/samples/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-02-q1.md +155 -0
- package/samples/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-03-q2.md +89 -0
- package/samples/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-04-q3.md +36 -0
- package/samples/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-05-q4.md +36 -0
- package/samples/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-06-q5.md +36 -0
- package/samples/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-07-q6.md +36 -0
- package/samples/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-08-q7.md +36 -0
- package/samples/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-09-q8.md +36 -0
- package/samples/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-10-q9.md +36 -0
- package/samples/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-11-q10.md +36 -0
- package/samples/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-12-results.md +150 -0
- package/samples/sample-custom-modules/sample-unitary-module/workflows/quiz-master/templates/csv-headers.template +1 -0
- package/samples/sample-custom-modules/sample-unitary-module/workflows/quiz-master/workflow.md +54 -0
- package/samples/sample-custom-modules/sample-unitary-module/workflows/wassup/workflow.md +26 -0
- package/samples/sample-custom-modules/sample-wellness-module/README.md +6 -0
- package/samples/sample-custom-modules/sample-wellness-module/agents/meditation-guide.agent.yaml +136 -0
- package/samples/sample-custom-modules/sample-wellness-module/agents/wellness-companion/foo.md +3 -0
- package/samples/sample-custom-modules/sample-wellness-module/agents/wellness-companion/wellness-companion-sidecar/addition1.md +1 -0
- package/samples/sample-custom-modules/sample-wellness-module/agents/wellness-companion/wellness-companion-sidecar/insights.md +13 -0
- package/samples/sample-custom-modules/sample-wellness-module/agents/wellness-companion/wellness-companion-sidecar/instructions.md +30 -0
- package/samples/sample-custom-modules/sample-wellness-module/agents/wellness-companion/wellness-companion-sidecar/memories.md +13 -0
- package/samples/sample-custom-modules/sample-wellness-module/agents/wellness-companion/wellness-companion-sidecar/patterns.md +17 -0
- package/samples/sample-custom-modules/sample-wellness-module/agents/wellness-companion/wellness-companion.agent.yaml +120 -0
- package/samples/sample-custom-modules/sample-wellness-module/module.yaml +17 -0
- package/samples/sample-custom-modules/sample-wellness-module/workflows/daily-checkin/README.md +32 -0
- package/samples/sample-custom-modules/sample-wellness-module/workflows/daily-checkin/workflow.md +45 -0
- package/samples/sample-custom-modules/sample-wellness-module/workflows/guided-meditation/README.md +31 -0
- package/samples/sample-custom-modules/sample-wellness-module/workflows/guided-meditation/workflow.md +45 -0
- package/samples/sample-custom-modules/sample-wellness-module/workflows/wellness-journal/README.md +31 -0
- package/samples/sample-custom-modules/sample-wellness-module/workflows/wellness-journal/workflow.md +45 -0
- package/src/core/_module-installer/installer.js +1 -9
- package/src/core/agents/bmad-master.agent.yaml +6 -11
- package/src/core/module.yaml +25 -0
- package/src/core/resources/excalidraw/README.md +160 -0
- package/src/core/resources/excalidraw/excalidraw-helpers.md +127 -0
- package/src/core/resources/excalidraw/library-loader.md +50 -0
- package/src/core/resources/excalidraw/validate-json-instructions.md +79 -0
- package/src/core/tasks/advanced-elicitation-methods.csv +51 -0
- package/src/core/tasks/advanced-elicitation.xml +116 -0
- package/src/core/tasks/index-docs.xml +1 -1
- package/src/core/tasks/review-adversarial-general.xml +41 -0
- package/src/core/tasks/validate-workflow.xml +1 -1
- package/src/core/tasks/workflow.xml +126 -57
- package/src/core/tools/shard-doc.xml +53 -44
- package/src/core/workflows/brainstorming/brain-methods.csv +62 -36
- package/src/core/workflows/brainstorming/steps/step-01-session-setup.md +196 -0
- package/src/core/workflows/brainstorming/steps/step-01b-continue.md +121 -0
- package/src/core/workflows/brainstorming/steps/step-02a-user-selected.md +224 -0
- package/src/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +236 -0
- package/src/core/workflows/brainstorming/steps/step-02c-random-selection.md +208 -0
- package/src/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +263 -0
- package/src/core/workflows/brainstorming/steps/step-03-technique-execution.md +339 -0
- package/src/core/workflows/brainstorming/steps/step-04-idea-organization.md +302 -0
- package/src/core/workflows/brainstorming/template.md +13 -100
- package/src/core/workflows/brainstorming/workflow.md +51 -0
- package/src/core/workflows/party-mode/steps/step-01-agent-loading.md +138 -0
- package/src/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +203 -0
- package/src/core/workflows/party-mode/steps/step-03-graceful-exit.md +158 -0
- package/src/core/workflows/party-mode/workflow.md +206 -0
- package/src/modules/bmb/README.md +12 -119
- package/src/modules/bmb/agents/bmad-builder.agent.yaml +77 -41
- package/src/modules/bmb/docs/agents/agent-compilation.md +340 -0
- package/src/modules/bmb/docs/agents/agent-menu-patterns.md +523 -0
- package/src/modules/bmb/docs/agents/expert-agent-architecture.md +363 -0
- package/src/modules/bmb/docs/agents/index.md +55 -0
- package/src/modules/bmb/docs/agents/kb.csv +0 -0
- package/src/modules/bmb/docs/agents/simple-agent-architecture.md +257 -0
- package/src/modules/bmb/docs/agents/understanding-agent-types.md +184 -0
- package/src/modules/bmb/docs/index.md +247 -0
- package/src/modules/bmb/docs/workflows/architecture.md +220 -0
- package/src/modules/bmb/docs/workflows/common-workflow-tools.csv +19 -0
- package/src/modules/bmb/docs/workflows/csv-data-file-standards.md +206 -0
- package/src/modules/bmb/docs/workflows/index.md +45 -0
- package/src/modules/bmb/docs/workflows/intent-vs-prescriptive-spectrum.md +220 -0
- package/src/modules/bmb/docs/workflows/kb.csv +0 -0
- package/src/modules/bmb/docs/workflows/templates/step-01-init-continuable-template.md +241 -0
- package/src/modules/bmb/docs/workflows/templates/step-1b-template.md +223 -0
- package/src/modules/bmb/docs/workflows/templates/step-file.md +139 -0
- package/src/modules/bmb/docs/workflows/templates/step-template.md +290 -0
- package/src/modules/bmb/docs/workflows/templates/workflow-template.md +104 -0
- package/src/modules/bmb/docs/workflows/templates/workflow.md +58 -0
- package/src/modules/bmb/docs/workflows/terms.md +97 -0
- package/src/modules/bmb/module.yaml +16 -0
- package/src/modules/bmb/reference/README.md +3 -0
- package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/README.md +242 -0
- package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/breakthroughs.md +24 -0
- package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/instructions.md +108 -0
- package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/memories.md +46 -0
- package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/mood-patterns.md +39 -0
- package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper.agent.yaml +152 -0
- package/src/modules/bmb/reference/agents/module-examples/README.md +49 -0
- package/src/modules/bmb/reference/agents/module-examples/security-engineer.agent.yaml +53 -0
- package/src/modules/bmb/reference/agents/module-examples/trend-analyst.agent.yaml +57 -0
- package/src/modules/bmb/reference/agents/simple-examples/README.md +223 -0
- package/src/modules/bmb/reference/agents/simple-examples/commit-poet.agent.yaml +126 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/data/dietary-restrictions.csv +18 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/data/macro-calculator.csv +16 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/data/recipe-database.csv +28 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-01-init.md +176 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-01b-continue.md +120 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-02-profile.md +164 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-03-assessment.md +153 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-04-strategy.md +182 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md +167 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-06-prep-schedule.md +194 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/templates/assessment-section.md +25 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/templates/nutrition-plan.md +68 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/templates/prep-schedule-section.md +29 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/templates/profile-section.md +47 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/templates/shopping-section.md +37 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/templates/strategy-section.md +18 -0
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/workflow.md +58 -0
- package/src/modules/bmb/workflows/create-agent/data/agent-validation-checklist.md +174 -0
- package/src/modules/bmb/workflows/create-agent/data/brainstorm-context.md +153 -0
- package/src/modules/bmb/workflows/create-agent/data/communication-presets.csv +61 -0
- package/src/modules/bmb/workflows/create-agent/data/info-and-installation-guide.md +29 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/README.md +3 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/agents/expert-examples/journal-keeper/README.md +242 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/breakthroughs.md +24 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/instructions.md +108 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/memories.md +46 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/mood-patterns.md +39 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/agents/expert-examples/journal-keeper/journal-keeper.agent.yaml +152 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/agents/module-examples/README.md +48 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/agents/module-examples/security-engineer.agent.yaml +53 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/agents/module-examples/trend-analyst.agent.yaml +57 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/agents/simple-examples/README.md +223 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/agents/simple-examples/commit-poet.agent.yaml +126 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/data/dietary-restrictions.csv +18 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/data/macro-calculator.csv +16 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/data/recipe-database.csv +28 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-01-init.md +177 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-01b-continue.md +150 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-02-profile.md +164 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-03-assessment.md +152 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-04-strategy.md +182 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md +167 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-06-prep-schedule.md +194 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/templates/assessment-section.md +25 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/templates/nutrition-plan.md +68 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/templates/prep-schedule-section.md +29 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/templates/profile-section.md +47 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/templates/shopping-section.md +37 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/templates/strategy-section.md +18 -0
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/workflow.md +58 -0
- package/src/modules/bmb/workflows/create-agent/data/validation-complete.md +305 -0
- package/src/modules/bmb/workflows/create-agent/steps/step-01-brainstorm.md +145 -0
- package/src/modules/bmb/workflows/create-agent/steps/step-02-discover.md +206 -0
- package/src/modules/bmb/workflows/create-agent/steps/step-03-persona.md +260 -0
- package/src/modules/bmb/workflows/create-agent/steps/step-04-commands.md +237 -0
- package/src/modules/bmb/workflows/create-agent/steps/step-05-name.md +232 -0
- package/src/modules/bmb/workflows/create-agent/steps/step-06-build.md +186 -0
- package/src/modules/bmb/workflows/create-agent/steps/step-07-validate.md +234 -0
- package/src/modules/bmb/workflows/create-agent/steps/step-08-celebrate.md +218 -0
- package/src/modules/bmb/workflows/create-agent/templates/agent-plan.template.md +3 -0
- package/src/modules/bmb/workflows/create-agent/templates/expert-agent.template.md +364 -0
- package/src/modules/bmb/workflows/create-agent/templates/simple-agent.template.md +257 -0
- package/src/modules/bmb/workflows/create-agent/workflow.md +58 -0
- package/src/modules/bmb/workflows/create-module/steps/step-01-init.md +155 -0
- package/src/modules/bmb/workflows/create-module/steps/step-01b-continue.md +169 -0
- package/src/modules/bmb/workflows/create-module/steps/step-02-concept.md +217 -0
- package/src/modules/bmb/workflows/create-module/steps/step-03-components.md +267 -0
- package/src/modules/bmb/workflows/create-module/steps/step-04-structure.md +228 -0
- package/src/modules/bmb/workflows/create-module/steps/step-05-config.md +233 -0
- package/src/modules/bmb/workflows/create-module/steps/step-06-agents.md +296 -0
- package/src/modules/bmb/workflows/create-module/steps/step-07-workflows.md +228 -0
- package/src/modules/bmb/workflows/create-module/steps/step-08-installer.md +186 -0
- package/src/modules/bmb/workflows/create-module/steps/step-09-documentation.md +309 -0
- package/src/modules/bmb/workflows/create-module/steps/step-10-roadmap.md +337 -0
- package/src/modules/bmb/workflows/create-module/steps/step-11-validate.md +335 -0
- package/src/modules/bmb/workflows/create-module/templates/agent.template.md +313 -0
- package/src/modules/bmb/workflows/create-module/templates/installer.template.js +47 -0
- package/src/modules/bmb/workflows/create-module/templates/module-plan.template.md +5 -0
- package/src/modules/bmb/workflows/create-module/templates/module.template.yaml +53 -0
- package/src/modules/bmb/workflows/create-module/templates/workflow-plan-template.md +23 -0
- package/src/modules/bmb/workflows/create-module/validation.md +126 -0
- package/src/modules/bmb/workflows/create-module/workflow.md +55 -0
- package/src/modules/bmb/workflows/create-workflow/steps/step-01-init.md +157 -0
- package/src/modules/bmb/workflows/create-workflow/steps/step-02-gather.md +211 -0
- package/src/modules/bmb/workflows/create-workflow/steps/step-03-tools-configuration.md +250 -0
- package/src/modules/bmb/workflows/create-workflow/steps/step-04-plan-review.md +216 -0
- package/src/modules/bmb/workflows/create-workflow/steps/step-05-output-format-design.md +289 -0
- package/src/modules/bmb/workflows/create-workflow/steps/step-06-design.md +271 -0
- package/src/modules/bmb/workflows/create-workflow/steps/step-07-build.md +308 -0
- package/src/modules/bmb/workflows/create-workflow/steps/step-08-review.md +284 -0
- package/src/modules/bmb/workflows/create-workflow/steps/step-09-complete.md +187 -0
- package/src/modules/bmb/workflows/create-workflow/workflow.md +58 -0
- package/src/modules/bmb/workflows/edit-agent/steps/step-01-discover-intent.md +134 -0
- package/src/modules/bmb/workflows/edit-agent/steps/step-02-analyze-agent.md +202 -0
- package/src/modules/bmb/workflows/edit-agent/steps/step-03-propose-changes.md +157 -0
- package/src/modules/bmb/workflows/edit-agent/steps/step-04-apply-changes.md +150 -0
- package/src/modules/bmb/workflows/edit-agent/steps/step-05-validate.md +150 -0
- package/src/modules/bmb/workflows/edit-agent/workflow.md +58 -0
- package/src/modules/bmb/workflows/edit-workflow/steps/step-01-analyze.md +217 -0
- package/src/modules/bmb/workflows/edit-workflow/steps/step-02-discover.md +253 -0
- package/src/modules/bmb/workflows/edit-workflow/steps/step-03-improve.md +217 -0
- package/src/modules/bmb/workflows/edit-workflow/steps/step-04-validate.md +193 -0
- package/src/modules/bmb/workflows/edit-workflow/steps/step-05-compliance-check.md +245 -0
- package/src/modules/bmb/workflows/edit-workflow/templates/completion-summary.md +75 -0
- package/src/modules/bmb/workflows/edit-workflow/templates/improvement-goals.md +68 -0
- package/src/modules/bmb/workflows/edit-workflow/templates/improvement-log.md +40 -0
- package/src/modules/bmb/workflows/edit-workflow/templates/validation-results.md +51 -0
- package/src/modules/bmb/workflows/edit-workflow/templates/workflow-analysis.md +56 -0
- package/src/modules/bmb/workflows/edit-workflow/workflow.md +58 -0
- package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-01-validate-goal.md +152 -0
- package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-02-workflow-validation.md +243 -0
- package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-03-step-validation.md +274 -0
- package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-04-file-validation.md +295 -0
- package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-05-intent-spectrum-validation.md +264 -0
- package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-06-web-subprocess-validation.md +360 -0
- package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-07-holistic-analysis.md +258 -0
- package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-08-generate-report.md +301 -0
- package/src/modules/bmb/workflows/workflow-compliance-check/templates/compliance-report.md +140 -0
- package/src/modules/bmb/workflows/workflow-compliance-check/workflow.md +58 -0
- package/src/modules/bmb/workflows-legacy/edit-module/README.md +171 -0
- package/src/modules/bmb/workflows-legacy/edit-module/checklist.md +163 -0
- package/src/modules/bmb/workflows-legacy/edit-module/instructions.md +340 -0
- package/src/modules/bmb/workflows-legacy/edit-module/workflow.yaml +34 -0
- package/src/modules/bmb/workflows-legacy/module-brief/README.md +264 -0
- package/src/modules/bmb/workflows-legacy/module-brief/checklist.md +116 -0
- package/src/modules/bmb/workflows-legacy/module-brief/instructions.md +268 -0
- package/src/modules/bmb/workflows-legacy/module-brief/workflow.yaml +36 -0
- package/src/modules/bmgd/_module-installer/installer.js +160 -0
- package/src/modules/bmgd/_module-installer/platform-specifics/claude-code.js +23 -0
- package/src/modules/bmgd/_module-installer/platform-specifics/windsurf.js +18 -0
- package/src/modules/bmgd/agents/game-architect.agent.yaml +52 -0
- package/src/modules/bmgd/agents/game-designer.agent.yaml +60 -0
- package/src/modules/bmgd/agents/game-dev.agent.yaml +56 -0
- package/src/modules/bmgd/agents/game-qa.agent.yaml +64 -0
- package/src/modules/bmgd/agents/game-scrum-master.agent.yaml +63 -0
- package/src/modules/bmgd/agents/game-solo-dev.agent.yaml +56 -0
- package/src/modules/bmgd/docs/agents-guide.md +407 -0
- package/src/modules/bmgd/docs/game-types-guide.md +503 -0
- package/src/modules/bmgd/docs/glossary.md +294 -0
- package/src/modules/bmgd/docs/index.md +180 -0
- package/src/modules/bmgd/docs/quick-flow-guide.md +288 -0
- package/src/modules/bmgd/docs/quick-start.md +250 -0
- package/src/modules/bmgd/docs/troubleshooting.md +259 -0
- package/src/modules/bmgd/docs/workflow-overview.jpg +0 -0
- package/src/modules/bmgd/docs/workflows-guide.md +463 -0
- package/src/modules/bmgd/gametest/knowledge/balance-testing.md +220 -0
- package/src/modules/bmgd/gametest/knowledge/certification-testing.md +319 -0
- package/src/modules/bmgd/gametest/knowledge/compatibility-testing.md +228 -0
- package/src/modules/bmgd/gametest/knowledge/godot-testing.md +376 -0
- package/src/modules/bmgd/gametest/knowledge/input-testing.md +315 -0
- package/src/modules/bmgd/gametest/knowledge/localization-testing.md +304 -0
- package/src/modules/bmgd/gametest/knowledge/multiplayer-testing.md +322 -0
- package/src/modules/bmgd/gametest/knowledge/performance-testing.md +204 -0
- package/src/modules/bmgd/gametest/knowledge/playtesting.md +384 -0
- package/src/modules/bmgd/gametest/knowledge/qa-automation.md +190 -0
- package/src/modules/bmgd/gametest/knowledge/regression-testing.md +280 -0
- package/src/modules/bmgd/gametest/knowledge/save-testing.md +280 -0
- package/src/modules/bmgd/gametest/knowledge/smoke-testing.md +404 -0
- package/src/modules/bmgd/gametest/knowledge/test-priorities.md +271 -0
- package/src/modules/bmgd/gametest/knowledge/unity-testing.md +383 -0
- package/src/modules/bmgd/gametest/knowledge/unreal-testing.md +388 -0
- package/src/modules/bmgd/gametest/qa-index.csv +17 -0
- package/src/modules/bmgd/module.yaml +64 -0
- package/src/modules/bmgd/teams/default-party.csv +12 -0
- package/src/modules/bmgd/teams/team-gamedev.yaml +29 -0
- package/src/modules/bmgd/workflows/1-preproduction/brainstorm-game/instructions.md +130 -0
- package/src/modules/bmgd/workflows/1-preproduction/brainstorm-game/steps/step-01-init.md +164 -0
- package/src/modules/bmgd/workflows/1-preproduction/brainstorm-game/steps/step-02-context.md +210 -0
- package/src/modules/bmgd/workflows/1-preproduction/brainstorm-game/steps/step-03-ideation.md +289 -0
- package/src/modules/bmgd/workflows/1-preproduction/brainstorm-game/steps/step-04-complete.md +275 -0
- package/src/modules/bmgd/workflows/1-preproduction/brainstorm-game/workflow.md +49 -0
- package/src/modules/bmgd/workflows/1-preproduction/brainstorm-game/workflow.yaml +62 -0
- package/src/modules/bmgd/workflows/1-preproduction/game-brief/instructions.md +373 -0
- package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-01-init.md +223 -0
- package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-01b-continue.md +151 -0
- package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-02-vision.md +218 -0
- package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-03-market.md +218 -0
- package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-04-fundamentals.md +231 -0
- package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-05-scope.md +242 -0
- package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-06-references.md +224 -0
- package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-07-content.md +282 -0
- package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-08-complete.md +296 -0
- package/src/modules/bmgd/workflows/1-preproduction/game-brief/workflow.md +62 -0
- package/src/modules/bmgd/workflows/1-preproduction/game-brief/workflow.yaml +67 -0
- package/src/modules/bmgd/workflows/2-design/gdd/steps/step-01-init.md +248 -0
- package/src/modules/bmgd/workflows/2-design/gdd/steps/step-01b-continue.md +173 -0
- package/src/modules/bmgd/workflows/2-design/gdd/steps/step-02-context.md +332 -0
- package/src/modules/bmgd/workflows/2-design/gdd/steps/step-03-platforms.md +245 -0
- package/src/modules/bmgd/workflows/2-design/gdd/steps/step-04-vision.md +229 -0
- package/src/modules/bmgd/workflows/2-design/gdd/steps/step-05-core-gameplay.md +258 -0
- package/src/modules/bmgd/workflows/2-design/gdd/steps/step-06-mechanics.md +249 -0
- package/src/modules/bmgd/workflows/2-design/gdd/steps/step-07-game-type.md +266 -0
- package/src/modules/bmgd/workflows/2-design/gdd/steps/step-08-progression.md +272 -0
- package/src/modules/bmgd/workflows/2-design/gdd/steps/step-09-levels.md +264 -0
- package/src/modules/bmgd/workflows/2-design/gdd/steps/step-10-art-audio.md +255 -0
- package/src/modules/bmgd/workflows/2-design/gdd/steps/step-11-technical.md +275 -0
- package/src/modules/bmgd/workflows/2-design/gdd/steps/step-12-epics.md +284 -0
- package/src/modules/bmgd/workflows/2-design/gdd/steps/step-13-metrics.md +250 -0
- package/src/modules/bmgd/workflows/2-design/gdd/steps/step-14-complete.md +335 -0
- package/src/modules/bmgd/workflows/2-design/gdd/workflow.md +61 -0
- package/src/modules/bmgd/workflows/2-design/gdd/workflow.yaml +101 -0
- package/src/modules/bmgd/workflows/2-design/narrative/instructions-narrative.md +604 -0
- package/src/modules/bmgd/workflows/2-design/narrative/steps/step-01-init.md +228 -0
- package/src/modules/bmgd/workflows/2-design/narrative/steps/step-01b-continue.md +163 -0
- package/src/modules/bmgd/workflows/2-design/narrative/steps/step-02-foundation.md +262 -0
- package/src/modules/bmgd/workflows/2-design/narrative/steps/step-03-story.md +238 -0
- package/src/modules/bmgd/workflows/2-design/narrative/steps/step-04-characters.md +297 -0
- package/src/modules/bmgd/workflows/2-design/narrative/steps/step-05-world.md +262 -0
- package/src/modules/bmgd/workflows/2-design/narrative/steps/step-06-dialogue.md +250 -0
- package/src/modules/bmgd/workflows/2-design/narrative/steps/step-07-environmental.md +244 -0
- package/src/modules/bmgd/workflows/2-design/narrative/steps/step-08-delivery.md +264 -0
- package/src/modules/bmgd/workflows/2-design/narrative/steps/step-09-integration.md +254 -0
- package/src/modules/bmgd/workflows/2-design/narrative/steps/step-10-production.md +262 -0
- package/src/modules/bmgd/workflows/2-design/narrative/steps/step-11-complete.md +331 -0
- package/src/modules/bmgd/workflows/2-design/narrative/workflow.md +57 -0
- package/src/modules/bmgd/workflows/2-design/narrative/workflow.yaml +77 -0
- package/src/modules/bmgd/workflows/3-technical/game-architecture/architecture-patterns.yaml +321 -0
- package/src/modules/bmgd/workflows/3-technical/game-architecture/checklist.md +240 -0
- package/src/modules/bmgd/workflows/3-technical/game-architecture/instructions.md +701 -0
- package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-01-init.md +223 -0
- package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-01b-continue.md +153 -0
- package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-02-context.md +262 -0
- package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-03-starter.md +290 -0
- package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-04-decisions.md +300 -0
- package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-05-crosscutting.md +319 -0
- package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-06-structure.md +304 -0
- package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-07-patterns.md +349 -0
- package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-08-validation.md +293 -0
- package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-09-complete.md +356 -0
- package/src/modules/bmgd/workflows/3-technical/game-architecture/templates/architecture-template.md +103 -0
- package/src/modules/bmgd/workflows/3-technical/game-architecture/workflow.md +55 -0
- package/src/modules/bmgd/workflows/3-technical/game-architecture/workflow.yaml +98 -0
- package/src/modules/bmgd/workflows/3-technical/generate-project-context/project-context-template.md +20 -0
- package/src/modules/bmgd/workflows/3-technical/generate-project-context/steps/step-01-discover.md +201 -0
- package/src/modules/bmgd/workflows/3-technical/generate-project-context/steps/step-02-generate.md +373 -0
- package/src/modules/bmgd/workflows/3-technical/generate-project-context/steps/step-03-complete.md +279 -0
- package/src/modules/bmgd/workflows/3-technical/generate-project-context/workflow.md +48 -0
- package/src/modules/bmgd/workflows/4-production/code-review/checklist.md +23 -0
- package/src/modules/bmgd/workflows/4-production/code-review/instructions.xml +225 -0
- package/src/modules/bmgd/workflows/4-production/code-review/workflow.yaml +64 -0
- package/src/modules/bmgd/workflows/4-production/correct-course/checklist.md +279 -0
- package/src/modules/bmgd/workflows/4-production/correct-course/instructions.md +206 -0
- package/src/modules/bmgd/workflows/4-production/correct-course/workflow.yaml +63 -0
- package/src/modules/bmgd/workflows/4-production/create-story/checklist.md +358 -0
- package/src/modules/bmgd/workflows/4-production/create-story/instructions.xml +298 -0
- package/src/modules/bmgd/workflows/4-production/create-story/template.md +49 -0
- package/src/modules/bmgd/workflows/4-production/create-story/workflow.yaml +79 -0
- package/src/modules/bmgd/workflows/4-production/dev-story/checklist.md +80 -0
- package/src/modules/bmgd/workflows/4-production/dev-story/instructions.xml +409 -0
- package/src/modules/bmgd/workflows/4-production/dev-story/workflow.yaml +68 -0
- package/src/modules/bmgd/workflows/4-production/retrospective/instructions.md +1443 -0
- package/src/modules/bmgd/workflows/4-production/retrospective/workflow.yaml +62 -0
- package/src/modules/bmgd/workflows/4-production/sprint-planning/checklist.md +33 -0
- package/src/modules/bmgd/workflows/4-production/sprint-planning/instructions.md +234 -0
- package/src/modules/bmgd/workflows/4-production/sprint-planning/sprint-status-template.yaml +55 -0
- package/src/modules/bmgd/workflows/4-production/sprint-planning/workflow.yaml +56 -0
- package/src/modules/bmgd/workflows/4-production/sprint-status/instructions.md +229 -0
- package/src/modules/bmgd/workflows/4-production/sprint-status/workflow.yaml +35 -0
- package/src/modules/bmgd/workflows/bmgd-quick-flow/create-tech-spec/instructions.md +140 -0
- package/src/modules/bmgd/workflows/bmgd-quick-flow/create-tech-spec/workflow.yaml +27 -0
- package/src/modules/bmgd/workflows/bmgd-quick-flow/quick-dev/checklist.md +37 -0
- package/src/modules/bmgd/workflows/bmgd-quick-flow/quick-dev/instructions.md +220 -0
- package/src/modules/bmgd/workflows/bmgd-quick-flow/quick-dev/workflow.yaml +45 -0
- package/src/modules/bmgd/workflows/bmgd-quick-flow/quick-prototype/checklist.md +26 -0
- package/src/modules/bmgd/workflows/bmgd-quick-flow/quick-prototype/instructions.md +156 -0
- package/src/modules/bmgd/workflows/bmgd-quick-flow/quick-prototype/workflow.yaml +36 -0
- package/src/modules/bmgd/workflows/gametest/automate/checklist.md +93 -0
- package/src/modules/bmgd/workflows/gametest/automate/instructions.md +317 -0
- package/src/modules/bmgd/workflows/gametest/automate/workflow.yaml +50 -0
- package/src/modules/bmgd/workflows/gametest/performance/checklist.md +96 -0
- package/src/modules/bmgd/workflows/gametest/performance/instructions.md +323 -0
- package/src/modules/bmgd/workflows/gametest/performance/performance-template.md +256 -0
- package/src/modules/bmgd/workflows/gametest/performance/workflow.yaml +48 -0
- package/src/modules/bmgd/workflows/gametest/playtest-plan/checklist.md +93 -0
- package/src/modules/bmgd/workflows/gametest/playtest-plan/instructions.md +297 -0
- package/src/modules/bmgd/workflows/gametest/playtest-plan/playtest-template.md +208 -0
- package/src/modules/bmgd/workflows/gametest/playtest-plan/workflow.yaml +59 -0
- package/src/modules/bmgd/workflows/gametest/test-design/checklist.md +98 -0
- package/src/modules/bmgd/workflows/gametest/test-design/instructions.md +280 -0
- package/src/modules/bmgd/workflows/gametest/test-design/test-design-template.md +205 -0
- package/src/modules/bmgd/workflows/gametest/test-design/workflow.yaml +47 -0
- package/src/modules/bmgd/workflows/gametest/test-framework/checklist.md +103 -0
- package/src/modules/bmgd/workflows/gametest/test-framework/instructions.md +348 -0
- package/src/modules/bmgd/workflows/gametest/test-framework/workflow.yaml +48 -0
- package/src/modules/bmgd/workflows/gametest/test-review/checklist.md +87 -0
- package/src/modules/bmgd/workflows/gametest/test-review/instructions.md +272 -0
- package/src/modules/bmgd/workflows/gametest/test-review/test-review-template.md +203 -0
- package/src/modules/bmgd/workflows/gametest/test-review/workflow.yaml +48 -0
- package/src/modules/bmgd/workflows/workflow-status/init/instructions.md +299 -0
- package/src/modules/bmgd/workflows/workflow-status/init/workflow.yaml +29 -0
- package/src/modules/bmgd/workflows/workflow-status/instructions.md +395 -0
- package/src/modules/bmgd/workflows/workflow-status/paths/gamedev-brownfield.yaml +65 -0
- package/src/modules/bmgd/workflows/workflow-status/paths/gamedev-greenfield.yaml +71 -0
- package/src/modules/bmgd/workflows/workflow-status/paths/quickflow-brownfield.yaml +29 -0
- package/src/modules/bmgd/workflows/workflow-status/paths/quickflow-greenfield.yaml +39 -0
- package/src/modules/bmgd/workflows/workflow-status/project-levels.yaml +63 -0
- package/src/modules/bmgd/workflows/workflow-status/workflow-status-template.yaml +24 -0
- package/src/modules/bmgd/workflows/workflow-status/workflow.yaml +30 -0
- package/src/modules/bmm/README.md +78 -92
- package/src/modules/bmm/_module-installer/installer.js +3 -3
- package/src/modules/bmm/_module-installer/platform-specifics/claude-code.js +1 -1
- package/src/modules/bmm/_module-installer/platform-specifics/windsurf.js +1 -1
- package/src/modules/bmm/agents/analyst.agent.yaml +32 -23
- package/src/modules/bmm/agents/architect.agent.yaml +32 -25
- package/src/modules/bmm/agents/dev.agent.yaml +32 -27
- package/src/modules/bmm/agents/pm.agent.yaml +30 -30
- package/src/modules/bmm/agents/quick-flow-solo-dev.agent.yaml +27 -0
- package/src/modules/bmm/agents/sm.agent.yaml +35 -44
- package/src/modules/bmm/agents/tea.agent.yaml +31 -20
- package/src/modules/bmm/agents/tech-writer.agent.yaml +67 -0
- package/src/modules/bmm/agents/ux-designer.agent.yaml +35 -20
- package/src/modules/bmm/data/README.md +29 -0
- package/src/modules/bmm/data/documentation-standards.md +262 -0
- package/src/modules/bmm/data/project-context-template.md +40 -0
- package/src/modules/bmm/docs/agents-guide.md +144 -0
- package/src/modules/bmm/docs/bmad-quick-flow.md +506 -0
- package/src/modules/bmm/docs/brownfield-guide.md +748 -0
- package/src/modules/bmm/docs/enterprise-agentic-development.md +686 -0
- package/src/modules/bmm/docs/faq.md +542 -0
- package/src/modules/bmm/docs/glossary.md +306 -0
- package/src/modules/bmm/docs/images/README.md +37 -0
- package/src/modules/bmm/docs/images/workflow-method-greenfield.excalidraw +5034 -0
- package/src/modules/bmm/docs/images/workflow-method-greenfield.svg +4 -0
- package/src/modules/bmm/docs/index.md +168 -0
- package/src/modules/bmm/docs/party-mode.md +224 -0
- package/src/modules/bmm/docs/quick-flow-solo-dev.md +337 -0
- package/src/modules/bmm/docs/quick-spec-flow.md +638 -0
- package/src/modules/bmm/docs/quick-start.md +366 -0
- package/src/modules/bmm/docs/scale-adaptive-system.md +618 -0
- package/src/modules/bmm/docs/test-architecture.md +455 -0
- package/src/modules/bmm/docs/troubleshooting.md +661 -0
- package/src/modules/bmm/docs/workflow-architecture-reference.md +366 -0
- package/src/modules/bmm/docs/workflow-document-project-reference.md +489 -0
- package/src/modules/bmm/docs/workflows-analysis.md +266 -0
- package/src/modules/bmm/docs/workflows-implementation.md +210 -0
- package/src/modules/bmm/docs/workflows-planning.md +451 -0
- package/src/modules/bmm/docs/workflows-solutioning.md +509 -0
- package/src/modules/bmm/module.yaml +56 -0
- package/src/modules/bmm/teams/default-party.csv +21 -0
- package/src/modules/bmm/teams/team-fullstack.yaml +1 -0
- package/src/modules/bmm/testarch/knowledge/api-request.md +303 -0
- package/src/modules/bmm/testarch/knowledge/auth-session.md +356 -0
- package/src/modules/bmm/testarch/knowledge/burn-in.md +273 -0
- package/src/modules/bmm/testarch/knowledge/ci-burn-in.md +1 -1
- package/src/modules/bmm/testarch/knowledge/file-utils.md +260 -0
- package/src/modules/bmm/testarch/knowledge/fixtures-composition.md +382 -0
- package/src/modules/bmm/testarch/knowledge/intercept-network-call.md +280 -0
- package/src/modules/bmm/testarch/knowledge/log.md +294 -0
- package/src/modules/bmm/testarch/knowledge/network-error-monitor.md +272 -0
- package/src/modules/bmm/testarch/knowledge/network-recorder.md +265 -0
- package/src/modules/bmm/testarch/knowledge/overview.md +283 -0
- package/src/modules/bmm/testarch/knowledge/recurse.md +296 -0
- package/src/modules/bmm/testarch/tea-index.csv +11 -0
- package/src/modules/bmm/workflows/1-analysis/create-product-brief/product-brief.template.md +10 -0
- package/src/modules/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +192 -0
- package/src/modules/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +165 -0
- package/src/modules/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +203 -0
- package/src/modules/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +206 -0
- package/src/modules/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +209 -0
- package/src/modules/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +223 -0
- package/src/modules/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +198 -0
- package/src/modules/bmm/workflows/1-analysis/create-product-brief/workflow.md +58 -0
- package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +136 -0
- package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +228 -0
- package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +237 -0
- package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +205 -0
- package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +233 -0
- package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +442 -0
- package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +181 -0
- package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +236 -0
- package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-02-customer-insights.md +199 -0
- package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +248 -0
- package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +258 -0
- package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +176 -0
- package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +474 -0
- package/src/modules/bmm/workflows/1-analysis/research/research.template.md +29 -0
- package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +136 -0
- package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +238 -0
- package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +247 -0
- package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +201 -0
- package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +238 -0
- package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +485 -0
- package/src/modules/bmm/workflows/1-analysis/research/workflow.md +173 -0
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01-init.md +159 -0
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +126 -0
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +189 -0
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +215 -0
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +218 -0
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +233 -0
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +251 -0
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +253 -0
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +223 -0
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +223 -0
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +240 -0
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +247 -0
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +236 -0
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +263 -0
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +226 -0
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +6 -138
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +57 -0
- package/src/modules/bmm/workflows/2-plan-workflows/prd/domain-complexity.csv +13 -0
- package/src/modules/bmm/workflows/2-plan-workflows/prd/prd-template.md +12 -58
- package/src/modules/bmm/workflows/2-plan-workflows/prd/project-types.csv +11 -0
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-01-init.md +243 -0
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-01b-continue.md +165 -0
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-02-discovery.md +420 -0
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-03-success.md +289 -0
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-04-journeys.md +290 -0
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-05-domain.md +270 -0
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-06-innovation.md +261 -0
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-07-project-type.md +257 -0
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-08-scoping.md +298 -0
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-09-functional.md +269 -0
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-10-nonfunctional.md +293 -0
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-11-complete.md +223 -0
- package/src/modules/bmm/workflows/2-plan-workflows/prd/workflow.md +61 -0
- package/src/modules/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +189 -0
- package/src/modules/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +177 -0
- package/src/modules/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +178 -0
- package/src/modules/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +138 -0
- package/src/modules/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +251 -0
- package/src/modules/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +132 -0
- package/src/modules/bmm/workflows/3-solutioning/check-implementation-readiness/templates/readiness-report-template.md +4 -0
- package/src/modules/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +54 -0
- package/src/modules/bmm/workflows/3-solutioning/create-architecture/architecture-decision-template.md +12 -0
- package/src/modules/bmm/workflows/3-solutioning/create-architecture/data/domain-complexity.csv +11 -0
- package/src/modules/bmm/workflows/3-solutioning/create-architecture/data/project-types.csv +7 -0
- package/src/modules/bmm/workflows/3-solutioning/create-architecture/steps/step-01-init.md +182 -0
- package/src/modules/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +163 -0
- package/src/modules/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +223 -0
- package/src/modules/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +330 -0
- package/src/modules/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +317 -0
- package/src/modules/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +358 -0
- package/src/modules/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +378 -0
- package/src/modules/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +358 -0
- package/src/modules/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +351 -0
- package/src/modules/bmm/workflows/3-solutioning/create-architecture/workflow.md +49 -0
- package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +258 -0
- package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +232 -0
- package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +271 -0
- package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +144 -0
- package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -0
- package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +58 -0
- package/src/modules/bmm/workflows/4-implementation/code-review/checklist.md +2 -1
- package/src/modules/bmm/workflows/4-implementation/code-review/instructions.xml +225 -0
- package/src/modules/bmm/workflows/4-implementation/code-review/workflow.yaml +34 -36
- package/src/modules/bmm/workflows/4-implementation/correct-course/checklist.md +1 -1
- package/src/modules/bmm/workflows/4-implementation/correct-course/instructions.md +7 -2
- package/src/modules/bmm/workflows/4-implementation/correct-course/workflow.yaml +42 -27
- package/src/modules/bmm/workflows/4-implementation/create-story/checklist.md +332 -214
- package/src/modules/bmm/workflows/4-implementation/create-story/instructions.xml +344 -0
- package/src/modules/bmm/workflows/4-implementation/create-story/template.md +3 -5
- package/src/modules/bmm/workflows/4-implementation/create-story/workflow.yaml +38 -27
- package/src/modules/bmm/workflows/4-implementation/dev-story/checklist.md +65 -23
- package/src/modules/bmm/workflows/4-implementation/dev-story/instructions.xml +409 -0
- package/src/modules/bmm/workflows/4-implementation/dev-story/workflow.yaml +9 -10
- package/src/modules/bmm/workflows/4-implementation/retrospective/instructions.md +1208 -244
- package/src/modules/bmm/workflows/4-implementation/retrospective/workflow.yaml +38 -26
- package/src/modules/bmm/workflows/4-implementation/sprint-planning/instructions.md +59 -55
- package/src/modules/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +14 -14
- package/src/modules/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +21 -8
- package/src/modules/bmm/workflows/4-implementation/sprint-status/instructions.md +229 -0
- package/src/modules/bmm/workflows/4-implementation/sprint-status/workflow.yaml +36 -0
- package/src/modules/bmm/workflows/bmad-quick-flow/create-tech-spec/instructions.md +115 -0
- package/src/modules/bmm/workflows/bmad-quick-flow/create-tech-spec/workflow.yaml +28 -0
- package/src/modules/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +156 -0
- package/src/modules/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +120 -0
- package/src/modules/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +113 -0
- package/src/modules/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +113 -0
- package/src/modules/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +106 -0
- package/src/modules/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-06-resolve-findings.md +140 -0
- package/src/modules/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +51 -0
- package/src/modules/bmm/workflows/document-project/checklist.md +1 -1
- package/src/modules/bmm/workflows/document-project/instructions.md +31 -32
- package/src/modules/bmm/workflows/document-project/workflow.yaml +4 -10
- package/src/modules/bmm/workflows/document-project/workflows/deep-dive-instructions.md +6 -6
- package/src/modules/bmm/workflows/document-project/workflows/deep-dive.yaml +5 -5
- package/src/modules/bmm/workflows/document-project/workflows/full-scan-instructions.md +13 -13
- package/src/modules/bmm/workflows/document-project/workflows/full-scan.yaml +5 -5
- package/src/modules/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-library.json +90 -0
- package/src/modules/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-templates.yaml +127 -0
- package/src/modules/bmm/workflows/excalidraw-diagrams/create-dataflow/checklist.md +39 -0
- package/src/modules/bmm/workflows/excalidraw-diagrams/create-dataflow/instructions.md +130 -0
- package/src/modules/bmm/workflows/excalidraw-diagrams/create-dataflow/workflow.yaml +27 -0
- package/src/modules/bmm/workflows/excalidraw-diagrams/create-diagram/checklist.md +43 -0
- package/src/modules/bmm/workflows/excalidraw-diagrams/create-diagram/instructions.md +141 -0
- package/src/modules/bmm/workflows/excalidraw-diagrams/create-diagram/workflow.yaml +27 -0
- package/src/modules/bmm/workflows/excalidraw-diagrams/create-flowchart/checklist.md +49 -0
- package/src/modules/bmm/workflows/excalidraw-diagrams/create-flowchart/instructions.md +241 -0
- package/src/modules/bmm/workflows/excalidraw-diagrams/create-flowchart/workflow.yaml +27 -0
- package/src/modules/bmm/workflows/excalidraw-diagrams/create-wireframe/checklist.md +38 -0
- package/src/modules/bmm/workflows/excalidraw-diagrams/create-wireframe/instructions.md +133 -0
- package/src/modules/bmm/workflows/excalidraw-diagrams/create-wireframe/workflow.yaml +27 -0
- package/src/modules/bmm/workflows/generate-project-context/project-context-template.md +21 -0
- package/src/modules/bmm/workflows/generate-project-context/steps/step-01-discover.md +183 -0
- package/src/modules/bmm/workflows/generate-project-context/steps/step-02-generate.md +317 -0
- package/src/modules/bmm/workflows/generate-project-context/steps/step-03-complete.md +277 -0
- package/src/modules/bmm/workflows/generate-project-context/workflow.md +48 -0
- package/src/modules/bmm/workflows/testarch/atdd/atdd-checklist-template.md +10 -9
- package/src/modules/bmm/workflows/testarch/atdd/checklist.md +1 -0
- package/src/modules/bmm/workflows/testarch/atdd/instructions.md +26 -5
- package/src/modules/bmm/workflows/testarch/atdd/workflow.yaml +2 -9
- package/src/modules/bmm/workflows/testarch/automate/checklist.md +2 -0
- package/src/modules/bmm/workflows/testarch/automate/instructions.md +25 -4
- package/src/modules/bmm/workflows/testarch/automate/workflow.yaml +2 -11
- package/src/modules/bmm/workflows/testarch/ci/checklist.md +7 -5
- package/src/modules/bmm/workflows/testarch/ci/github-actions-template.yaml +36 -3
- package/src/modules/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +25 -4
- package/src/modules/bmm/workflows/testarch/ci/instructions.md +23 -4
- package/src/modules/bmm/workflows/testarch/ci/workflow.yaml +2 -10
- package/src/modules/bmm/workflows/testarch/framework/checklist.md +4 -4
- package/src/modules/bmm/workflows/testarch/framework/instructions.md +28 -2
- package/src/modules/bmm/workflows/testarch/framework/workflow.yaml +2 -8
- package/src/modules/bmm/workflows/testarch/nfr-assess/checklist.md +2 -0
- package/src/modules/bmm/workflows/testarch/nfr-assess/instructions.md +1 -1
- package/src/modules/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +2 -0
- package/src/modules/bmm/workflows/testarch/nfr-assess/workflow.yaml +2 -11
- package/src/modules/bmm/workflows/testarch/test-design/checklist.md +7 -6
- package/src/modules/bmm/workflows/testarch/test-design/instructions.md +182 -15
- package/src/modules/bmm/workflows/testarch/test-design/test-design-template.md +13 -4
- package/src/modules/bmm/workflows/testarch/test-design/workflow.yaml +13 -11
- package/src/modules/bmm/workflows/testarch/test-review/checklist.md +2 -0
- package/src/modules/bmm/workflows/testarch/test-review/instructions.md +29 -9
- package/src/modules/bmm/workflows/testarch/test-review/test-review-template.md +2 -0
- package/src/modules/bmm/workflows/testarch/test-review/workflow.yaml +2 -9
- package/src/modules/bmm/workflows/testarch/trace/checklist.md +1 -0
- package/src/modules/bmm/workflows/testarch/trace/instructions.md +11 -9
- package/src/modules/bmm/workflows/testarch/trace/trace-template.md +2 -0
- package/src/modules/bmm/workflows/testarch/trace/workflow.yaml +2 -13
- package/src/modules/bmm/workflows/workflow-status/init/instructions.md +259 -210
- package/src/modules/bmm/workflows/workflow-status/init/workflow.yaml +6 -5
- package/src/modules/bmm/workflows/workflow-status/instructions.md +188 -117
- package/src/modules/bmm/workflows/workflow-status/paths/enterprise-brownfield.yaml +122 -0
- package/src/modules/bmm/workflows/workflow-status/paths/enterprise-greenfield.yaml +110 -0
- package/src/modules/bmm/workflows/workflow-status/paths/method-brownfield.yaml +106 -0
- package/src/modules/bmm/workflows/workflow-status/paths/method-greenfield.yaml +96 -0
- package/src/modules/bmm/workflows/workflow-status/project-levels.yaml +1 -1
- package/src/modules/bmm/workflows/workflow-status/workflow-status-template.yaml +24 -0
- package/src/modules/bmm/workflows/workflow-status/workflow.yaml +7 -5
- package/src/modules/cis/_module-installer/installer.js +1 -1
- package/src/modules/cis/agents/brainstorming-coach.agent.yaml +15 -9
- package/src/modules/cis/agents/creative-problem-solver.agent.yaml +14 -8
- package/src/modules/cis/agents/design-thinking-coach.agent.yaml +14 -8
- package/src/modules/cis/agents/innovation-strategist.agent.yaml +14 -8
- package/src/modules/cis/agents/presentation-master.agent.yaml +61 -0
- package/src/modules/cis/agents/storyteller/storyteller-sidecar/stories-told.md +7 -0
- package/src/modules/cis/agents/storyteller/storyteller-sidecar/story-preferences.md +7 -0
- package/src/modules/cis/agents/storyteller/storyteller.agent.yaml +34 -0
- package/src/modules/cis/docs/index.md +149 -0
- package/src/modules/cis/module.yaml +11 -0
- package/src/modules/cis/teams/creative-squad.yaml +1 -0
- package/src/modules/cis/teams/default-party.csv +12 -0
- package/src/modules/cis/workflows/README.md +102 -30
- package/src/modules/cis/workflows/design-thinking/instructions.md +4 -2
- package/src/modules/cis/workflows/design-thinking/workflow.yaml +7 -12
- package/src/modules/cis/workflows/innovation-strategy/instructions.md +7 -5
- package/src/modules/cis/workflows/innovation-strategy/template.md +3 -3
- package/src/modules/cis/workflows/innovation-strategy/workflow.yaml +7 -12
- package/src/modules/cis/workflows/problem-solving/instructions.md +4 -2
- package/src/modules/cis/workflows/problem-solving/workflow.yaml +7 -12
- package/src/modules/cis/workflows/storytelling/instructions.md +14 -4
- package/src/modules/cis/workflows/storytelling/workflow.yaml +7 -12
- package/src/utility/agent-components/activation-rules.txt +7 -0
- package/src/utility/agent-components/activation-steps.txt +13 -0
- package/src/utility/agent-components/agent-command-header.md +1 -0
- package/src/utility/agent-components/agent.customize.template.yaml +41 -0
- package/src/utility/agent-components/handler-action.txt +4 -0
- package/src/utility/agent-components/handler-exec.txt +6 -0
- package/src/utility/agent-components/handler-multi.txt +14 -0
- package/src/utility/agent-components/handler-tmpl.txt +5 -0
- package/src/utility/agent-components/handler-validate-workflow.txt +7 -0
- package/src/utility/agent-components/handler-workflow.txt +10 -0
- package/src/utility/agent-components/menu-handlers.txt +6 -0
- package/test/README.md +2 -2
- package/test/fixtures/agent-schema/invalid/menu-triggers/compound-invalid-format.agent.yaml +24 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/compound-mismatched-kebab.agent.yaml +24 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/compound-wrong-shortcut.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/menu-commands/all-command-types.agent.yaml +1 -3
- package/test/fixtures/agent-schema/valid/menu-triggers/compound-triggers.agent.yaml +30 -0
- package/test/test-agent-schema.js +2 -2
- package/test/test-installation-components.js +214 -0
- package/tools/build-docs.js +630 -0
- package/tools/cli/README.md +1 -588
- package/tools/cli/commands/install.js +61 -20
- package/tools/cli/installers/install-messages.yaml +52 -0
- package/tools/cli/installers/lib/core/config-collector.js +595 -98
- package/tools/cli/installers/lib/core/custom-module-cache.js +259 -0
- package/tools/cli/installers/lib/core/dependency-resolver.js +2 -2
- package/tools/cli/installers/lib/core/detector.js +75 -16
- package/tools/cli/installers/lib/core/ide-config-manager.js +12 -8
- package/tools/cli/installers/lib/core/installer.js +1277 -722
- package/tools/cli/installers/lib/core/manifest-generator.js +285 -142
- package/tools/cli/installers/lib/core/manifest.js +74 -20
- package/tools/cli/installers/lib/custom/handler.js +363 -0
- package/tools/cli/installers/lib/ide/_base-ide.js +94 -12
- package/tools/cli/installers/lib/ide/antigravity.js +507 -0
- package/tools/cli/installers/lib/ide/auggie.js +148 -240
- package/tools/cli/installers/lib/ide/claude-code.js +92 -32
- package/tools/cli/installers/lib/ide/cline.js +64 -18
- package/tools/cli/installers/lib/ide/codex.js +226 -72
- package/tools/cli/installers/lib/ide/crush.js +79 -55
- package/tools/cli/installers/lib/ide/cursor.js +144 -20
- package/tools/cli/installers/lib/ide/gemini.js +180 -35
- package/tools/cli/installers/lib/ide/github-copilot.js +154 -57
- package/tools/cli/installers/lib/ide/iflow.js +79 -30
- package/tools/cli/installers/lib/ide/kilo.js +94 -16
- package/tools/cli/installers/lib/ide/kiro-cli.js +327 -0
- package/tools/cli/installers/lib/ide/manager.js +50 -0
- package/tools/cli/installers/lib/ide/opencode.js +66 -22
- package/tools/cli/installers/lib/ide/qwen.js +93 -11
- package/tools/cli/installers/lib/ide/roo.js +158 -176
- package/tools/cli/installers/lib/ide/rovo-dev.js +290 -0
- package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +96 -0
- package/tools/cli/installers/lib/ide/shared/bmad-artifacts.js +34 -19
- package/tools/cli/installers/lib/ide/shared/module-injections.js +2 -2
- package/tools/cli/installers/lib/ide/shared/task-tool-command-generator.js +119 -0
- package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +241 -0
- package/tools/cli/installers/lib/ide/templates/agent-command-template.md +14 -0
- package/tools/cli/installers/lib/ide/templates/gemini-agent-command.toml +14 -0
- package/tools/cli/installers/lib/ide/templates/gemini-task-command.toml +12 -0
- package/tools/cli/installers/lib/ide/templates/workflow-command-template.md +13 -0
- package/tools/cli/installers/lib/ide/templates/workflow-commander.md +5 -0
- package/tools/cli/installers/lib/ide/trae.js +67 -32
- package/tools/cli/installers/lib/ide/windsurf.js +65 -8
- package/tools/cli/installers/lib/message-loader.js +85 -0
- package/tools/cli/installers/lib/modules/manager.js +785 -97
- package/tools/cli/lib/activation-builder.js +8 -13
- package/tools/cli/lib/agent/compiler.js +564 -0
- package/tools/cli/lib/agent/installer.js +716 -0
- package/tools/cli/lib/agent/template-engine.js +152 -0
- package/tools/cli/lib/agent-analyzer.js +48 -20
- package/tools/cli/lib/agent-party-generator.js +5 -17
- package/tools/cli/lib/cli-utils.js +65 -46
- package/tools/cli/lib/config.js +7 -4
- package/tools/cli/lib/platform-codes.js +2 -2
- package/tools/cli/lib/ui.js +1132 -81
- package/tools/cli/lib/xml-handler.js +4 -55
- package/tools/cli/lib/yaml-format.js +6 -7
- package/tools/cli/lib/yaml-xml-builder.js +196 -56
- package/tools/flattener/ignoreRules.js +1 -1
- package/tools/flattener/xml.js +1 -7
- package/tools/lib/xml-utils.js +13 -0
- package/tools/maintainer/review-pr-README.md +55 -0
- package/tools/maintainer/review-pr.md +242 -0
- package/tools/migrate-custom-module-paths.js +124 -0
- package/tools/platform-codes.yaml +12 -0
- package/tools/schema/agent.js +304 -23
- package/tools/validate-agent-schema.js +2 -2
- package/tools/validate-svg-changes.sh +356 -0
- package/website/css/custom.css +52 -0
- package/website/docusaurus.config.js +179 -0
- package/website/sidebars.js +157 -0
- package/website/src/pages/downloads.md +81 -0
- package/website/src/pages/index.js +50 -0
- package/website/static/favicon.ico +0 -0
- package/website/static/img/logo.svg +4 -0
- package/website/static/robots.txt +37 -0
- package/.claude/commands/bmad/bmb/agents/bmad-builder.md +0 -70
- package/.claude/commands/bmad/bmb/workflows/README.md +0 -67
- package/.claude/commands/bmad/bmb/workflows/audit-workflow.md +0 -15
- package/.claude/commands/bmad/bmb/workflows/convert-legacy.md +0 -15
- package/.claude/commands/bmad/bmb/workflows/create-agent.md +0 -15
- package/.claude/commands/bmad/bmb/workflows/create-module.md +0 -15
- package/.claude/commands/bmad/bmb/workflows/create-workflow.md +0 -15
- package/.claude/commands/bmad/bmb/workflows/edit-agent.md +0 -15
- package/.claude/commands/bmad/bmb/workflows/edit-module.md +0 -15
- package/.claude/commands/bmad/bmb/workflows/edit-workflow.md +0 -15
- package/.claude/commands/bmad/bmb/workflows/module-brief.md +0 -15
- package/.claude/commands/bmad/bmb/workflows/redoc.md +0 -15
- package/.claude/commands/bmad/bmd/agents/cli-chief.md +0 -108
- package/.claude/commands/bmad/bmd/agents/doc-keeper.md +0 -115
- package/.claude/commands/bmad/bmd/agents/release-chief.md +0 -109
- package/.claude/commands/bmad/core/agents/bmad-master.md +0 -71
- package/.claude/commands/bmad/core/tasks/index-docs.md +0 -9
- package/.claude/commands/bmad/core/tools/shard-doc.md +0 -9
- package/.claude/commands/bmad/core/workflows/README.md +0 -27
- package/.claude/commands/bmad/core/workflows/brainstorming.md +0 -15
- package/.claude/commands/bmad/core/workflows/party-mode.md +0 -15
- package/.claude/hooks/bmad-tts-injector.sh +0 -415
- package/.claude/hooks/bmad-voice-manager.sh +0 -511
- package/.claude/hooks/check-output-style.sh +0 -112
- package/.claude/hooks/download-extra-voices.sh +0 -244
- package/.claude/hooks/github-star-reminder.sh +0 -154
- package/.claude/hooks/language-manager.sh +0 -392
- package/.claude/hooks/learn-manager.sh +0 -475
- package/.claude/hooks/personality-manager.sh +0 -438
- package/.claude/hooks/piper-download-voices.sh +0 -165
- package/.claude/hooks/piper-installer.sh +0 -178
- package/.claude/hooks/piper-multispeaker-registry.sh +0 -165
- package/.claude/hooks/piper-voice-manager.sh +0 -293
- package/.claude/hooks/play-tts-elevenlabs.sh +0 -404
- package/.claude/hooks/play-tts-piper.sh +0 -338
- package/.claude/hooks/play-tts.sh +0 -100
- package/.claude/hooks/provider-commands.sh +0 -540
- package/.claude/hooks/provider-manager.sh +0 -298
- package/.claude/hooks/replay-target-audio.sh +0 -95
- package/.claude/hooks/sentiment-manager.sh +0 -201
- package/.claude/hooks/speed-manager.sh +0 -291
- package/.claude/hooks/voice-manager.sh +0 -594
- package/.claude/hooks/voices-config.sh +0 -70
- package/.claude/settings.local.json +0 -41
- package/.github/workflows/lint.yaml +0 -61
- package/bmad/_cfg/agent-manifest.csv +0 -7
- package/bmad/_cfg/agents/bmb-bmad-builder.customize.yaml +0 -42
- package/bmad/_cfg/agents/bmd-cli-chief.customize.yaml +0 -32
- package/bmad/_cfg/agents/bmd-doc-keeper.customize.yaml +0 -42
- package/bmad/_cfg/agents/bmd-release-chief.customize.yaml +0 -42
- package/bmad/_cfg/agents/core-bmad-master.customize.yaml +0 -42
- package/bmad/_cfg/files-manifest.csv +0 -83
- package/bmad/_cfg/manifest.yaml +0 -12
- package/bmad/_cfg/task-manifest.csv +0 -5
- package/bmad/_cfg/tool-manifest.csv +0 -2
- package/bmad/_cfg/workflow-manifest.csv +0 -15
- package/bmad/bmb/README.md +0 -132
- package/bmad/bmb/agents/bmad-builder.md +0 -70
- package/bmad/bmb/config.yaml +0 -14
- package/bmad/bmb/workflows/audit-workflow/checklist.md +0 -143
- package/bmad/bmb/workflows/audit-workflow/instructions.md +0 -341
- package/bmad/bmb/workflows/audit-workflow/template.md +0 -118
- package/bmad/bmb/workflows/audit-workflow/workflow.yaml +0 -23
- package/bmad/bmb/workflows/audit-workflow/workflow.yaml.bak +0 -21
- package/bmad/bmb/workflows/convert-legacy/README.md +0 -262
- package/bmad/bmb/workflows/convert-legacy/checklist.md +0 -205
- package/bmad/bmb/workflows/convert-legacy/instructions.md +0 -377
- package/bmad/bmb/workflows/convert-legacy/workflow.yaml +0 -32
- package/bmad/bmb/workflows/create-agent/README.md +0 -320
- package/bmad/bmb/workflows/create-agent/agent-architecture.md +0 -419
- package/bmad/bmb/workflows/create-agent/agent-architecture.md.bak +0 -412
- package/bmad/bmb/workflows/create-agent/agent-command-patterns.md +0 -759
- package/bmad/bmb/workflows/create-agent/agent-command-patterns.md.bak +0 -759
- package/bmad/bmb/workflows/create-agent/agent-types.md +0 -292
- package/bmad/bmb/workflows/create-agent/brainstorm-context.md +0 -174
- package/bmad/bmb/workflows/create-agent/checklist.md +0 -62
- package/bmad/bmb/workflows/create-agent/communication-styles.md +0 -202
- package/bmad/bmb/workflows/create-agent/instructions.md +0 -430
- package/bmad/bmb/workflows/create-agent/workflow.yaml +0 -37
- package/bmad/bmb/workflows/create-module/README.md +0 -220
- package/bmad/bmb/workflows/create-module/README.md.bak +0 -218
- package/bmad/bmb/workflows/create-module/brainstorm-context.md +0 -137
- package/bmad/bmb/workflows/create-module/checklist.md +0 -244
- package/bmad/bmb/workflows/create-module/checklist.md.bak +0 -245
- package/bmad/bmb/workflows/create-module/installer-templates/install-config.yaml +0 -92
- package/bmad/bmb/workflows/create-module/installer-templates/installer.js +0 -231
- package/bmad/bmb/workflows/create-module/installer-templates/installer.js.bak +0 -231
- package/bmad/bmb/workflows/create-module/instructions.md +0 -581
- package/bmad/bmb/workflows/create-module/instructions.md.bak +0 -521
- package/bmad/bmb/workflows/create-module/module-structure.md +0 -366
- package/bmad/bmb/workflows/create-module/module-structure.md.bak +0 -310
- package/bmad/bmb/workflows/create-module/workflow.yaml +0 -42
- package/bmad/bmb/workflows/create-module/workflow.yaml.bak +0 -40
- package/bmad/bmb/workflows/create-workflow/README.md +0 -277
- package/bmad/bmb/workflows/create-workflow/brainstorm-context.md +0 -197
- package/bmad/bmb/workflows/create-workflow/checklist.md +0 -94
- package/bmad/bmb/workflows/create-workflow/instructions.md +0 -716
- package/bmad/bmb/workflows/create-workflow/workflow-creation-guide.md +0 -1150
- package/bmad/bmb/workflows/create-workflow/workflow-template/checklist.md +0 -24
- package/bmad/bmb/workflows/create-workflow/workflow-template/instructions.md +0 -13
- package/bmad/bmb/workflows/create-workflow/workflow-template/template.md +0 -9
- package/bmad/bmb/workflows/create-workflow/workflow-template/workflow.yaml +0 -39
- package/bmad/bmb/workflows/create-workflow/workflow-template/workflow.yaml.bak +0 -39
- package/bmad/bmb/workflows/create-workflow/workflow.yaml +0 -40
- package/bmad/bmb/workflows/create-workflow/workflow.yaml.bak +0 -38
- package/bmad/bmb/workflows/edit-agent/README.md +0 -112
- package/bmad/bmb/workflows/edit-agent/checklist.md +0 -112
- package/bmad/bmb/workflows/edit-agent/instructions.md +0 -290
- package/bmad/bmb/workflows/edit-agent/workflow.yaml +0 -33
- package/bmad/bmb/workflows/edit-module/README.md +0 -187
- package/bmad/bmb/workflows/edit-module/checklist.md +0 -165
- package/bmad/bmb/workflows/edit-module/instructions.md +0 -339
- package/bmad/bmb/workflows/edit-module/workflow.yaml +0 -34
- package/bmad/bmb/workflows/edit-workflow/README.md +0 -119
- package/bmad/bmb/workflows/edit-workflow/checklist.md +0 -70
- package/bmad/bmb/workflows/edit-workflow/instructions.md +0 -342
- package/bmad/bmb/workflows/edit-workflow/workflow.yaml +0 -27
- package/bmad/bmb/workflows/edit-workflow/workflow.yaml.bak +0 -25
- package/bmad/bmb/workflows/module-brief/README.md +0 -264
- package/bmad/bmb/workflows/module-brief/checklist.md +0 -116
- package/bmad/bmb/workflows/module-brief/instructions.md +0 -267
- package/bmad/bmb/workflows/module-brief/workflow.yaml +0 -29
- package/bmad/bmb/workflows/module-brief/workflow.yaml.bak +0 -27
- package/bmad/bmb/workflows/redoc/README.md +0 -87
- package/bmad/bmb/workflows/redoc/checklist.md +0 -99
- package/bmad/bmb/workflows/redoc/instructions.md +0 -265
- package/bmad/bmb/workflows/redoc/workflow.yaml +0 -32
- package/bmad/bmb/workflows/redoc/workflow.yaml.bak +0 -31
- package/bmad/bmd/README.md +0 -193
- package/bmad/bmd/README.md.bak +0 -193
- package/bmad/bmd/agents/cli-chief-sidecar/instructions.md +0 -102
- package/bmad/bmd/agents/cli-chief-sidecar/instructions.md.bak +0 -102
- package/bmad/bmd/agents/cli-chief-sidecar/knowledge/README.md +0 -68
- package/bmad/bmd/agents/cli-chief-sidecar/knowledge/README.md.bak +0 -68
- package/bmad/bmd/agents/cli-chief-sidecar/knowledge/cli-reference.md +0 -123
- package/bmad/bmd/agents/cli-chief-sidecar/knowledge/cli-reference.md.bak +0 -123
- package/bmad/bmd/agents/cli-chief-sidecar/memories.md +0 -53
- package/bmad/bmd/agents/cli-chief-sidecar/memories.md.bak +0 -53
- package/bmad/bmd/agents/cli-chief.md +0 -108
- package/bmad/bmd/agents/cli-chief.md.bak +0 -108
- package/bmad/bmd/agents/doc-keeper-sidecar/instructions.md +0 -177
- package/bmad/bmd/agents/doc-keeper-sidecar/instructions.md.bak +0 -177
- package/bmad/bmd/agents/doc-keeper-sidecar/knowledge/README.md +0 -81
- package/bmad/bmd/agents/doc-keeper-sidecar/knowledge/README.md.bak +0 -81
- package/bmad/bmd/agents/doc-keeper-sidecar/memories.md +0 -88
- package/bmad/bmd/agents/doc-keeper-sidecar/memories.md.bak +0 -88
- package/bmad/bmd/agents/doc-keeper.md +0 -115
- package/bmad/bmd/agents/doc-keeper.md.bak +0 -115
- package/bmad/bmd/agents/release-chief-sidecar/instructions.md +0 -164
- package/bmad/bmd/agents/release-chief-sidecar/instructions.md.bak +0 -164
- package/bmad/bmd/agents/release-chief-sidecar/knowledge/README.md +0 -82
- package/bmad/bmd/agents/release-chief-sidecar/knowledge/README.md.bak +0 -82
- package/bmad/bmd/agents/release-chief-sidecar/memories.md +0 -73
- package/bmad/bmd/agents/release-chief-sidecar/memories.md.bak +0 -73
- package/bmad/bmd/agents/release-chief.md +0 -109
- package/bmad/bmd/agents/release-chief.md.bak +0 -109
- package/bmad/bmd/config.yaml +0 -10
- package/bmad/core/agents/bmad-master.md +0 -71
- package/bmad/core/agents/bmad-web-orchestrator.agent.xml +0 -122
- package/bmad/core/config.yaml +0 -9
- package/bmad/core/tasks/adv-elicit-methods.csv +0 -39
- package/bmad/core/tasks/adv-elicit.xml +0 -104
- package/bmad/core/tasks/index-docs.xml +0 -65
- package/bmad/core/tasks/validate-workflow.xml +0 -89
- package/bmad/core/tasks/workflow.xml +0 -174
- package/bmad/core/tools/shard-doc.xml +0 -100
- package/bmad/core/workflows/brainstorming/README.md +0 -271
- package/bmad/core/workflows/brainstorming/brain-methods.csv +0 -36
- package/bmad/core/workflows/brainstorming/instructions.md +0 -314
- package/bmad/core/workflows/brainstorming/template.md +0 -102
- package/bmad/core/workflows/brainstorming/workflow.yaml +0 -43
- package/bmad/core/workflows/party-mode/instructions.md +0 -188
- package/bmad/core/workflows/party-mode/workflow.yaml +0 -23
- package/bmad/docs/claude-code-instructions.md +0 -25
- package/bmad/docs/codex-instructions.md +0 -21
- package/bmd/README.md +0 -193
- package/bmd/agents/cli-chief-sidecar/instructions.md +0 -102
- package/bmd/agents/cli-chief-sidecar/knowledge/README.md +0 -68
- package/bmd/agents/cli-chief-sidecar/knowledge/cli-reference.md +0 -123
- package/bmd/agents/cli-chief-sidecar/memories.md +0 -53
- package/bmd/agents/cli-chief.agent.yaml +0 -126
- package/bmd/agents/doc-keeper-sidecar/instructions.md +0 -177
- package/bmd/agents/doc-keeper-sidecar/knowledge/README.md +0 -81
- package/bmd/agents/doc-keeper-sidecar/memories.md +0 -88
- package/bmd/agents/doc-keeper.agent.yaml +0 -137
- package/bmd/agents/release-chief-sidecar/instructions.md +0 -164
- package/bmd/agents/release-chief-sidecar/knowledge/README.md +0 -82
- package/bmd/agents/release-chief-sidecar/memories.md +0 -73
- package/bmd/agents/release-chief.agent.yaml +0 -127
- package/bmd/bmad-custom-module-installer-plan.md +0 -1176
- package/bmd/config.yaml +0 -12
- package/docs/bmad-brownfield-guide.md +0 -1260
- package/docs/conversion-report-shard-doc-2025-10-26.md +0 -188
- package/docs/installers-bundlers/ide-injections.md +0 -186
- package/docs/installers-bundlers/installers-modules-platforms-reference.md +0 -327
- package/docs/installers-bundlers/web-bundler-usage.md +0 -54
- package/src/core/_module-installer/install-config.yaml +0 -28
- package/src/core/agents/bmad-web-orchestrator.agent.xml +0 -122
- package/src/core/tasks/adv-elicit-methods.csv +0 -39
- package/src/core/tasks/adv-elicit.xml +0 -104
- package/src/core/workflows/brainstorming/README.md +0 -271
- package/src/core/workflows/brainstorming/instructions.md +0 -314
- package/src/core/workflows/brainstorming/workflow.yaml +0 -43
- package/src/core/workflows/party-mode/instructions.md +0 -188
- package/src/core/workflows/party-mode/workflow.yaml +0 -23
- package/src/modules/bmb/_module-installer/install-config.yaml +0 -26
- package/src/modules/bmb/workflows/audit-workflow/checklist.md +0 -143
- package/src/modules/bmb/workflows/audit-workflow/instructions.md +0 -341
- package/src/modules/bmb/workflows/audit-workflow/template.md +0 -118
- package/src/modules/bmb/workflows/audit-workflow/workflow.yaml +0 -25
- package/src/modules/bmb/workflows/convert-legacy/README.md +0 -262
- package/src/modules/bmb/workflows/convert-legacy/checklist.md +0 -205
- package/src/modules/bmb/workflows/convert-legacy/instructions.md +0 -377
- package/src/modules/bmb/workflows/convert-legacy/workflow.yaml +0 -34
- package/src/modules/bmb/workflows/create-agent/README.md +0 -320
- package/src/modules/bmb/workflows/create-agent/agent-architecture.md +0 -419
- package/src/modules/bmb/workflows/create-agent/agent-command-patterns.md +0 -759
- package/src/modules/bmb/workflows/create-agent/agent-types.md +0 -292
- package/src/modules/bmb/workflows/create-agent/brainstorm-context.md +0 -174
- package/src/modules/bmb/workflows/create-agent/checklist.md +0 -62
- package/src/modules/bmb/workflows/create-agent/communication-styles.md +0 -202
- package/src/modules/bmb/workflows/create-agent/instructions.md +0 -430
- package/src/modules/bmb/workflows/create-agent/workflow.yaml +0 -49
- package/src/modules/bmb/workflows/create-module/README.md +0 -220
- package/src/modules/bmb/workflows/create-module/brainstorm-context.md +0 -137
- package/src/modules/bmb/workflows/create-module/checklist.md +0 -244
- package/src/modules/bmb/workflows/create-module/installer-templates/install-config.yaml +0 -92
- package/src/modules/bmb/workflows/create-module/installer-templates/installer.js +0 -231
- package/src/modules/bmb/workflows/create-module/instructions.md +0 -581
- package/src/modules/bmb/workflows/create-module/module-structure.md +0 -366
- package/src/modules/bmb/workflows/create-module/workflow.yaml +0 -44
- package/src/modules/bmb/workflows/create-workflow/README.md +0 -277
- package/src/modules/bmb/workflows/create-workflow/brainstorm-context.md +0 -197
- package/src/modules/bmb/workflows/create-workflow/checklist.md +0 -94
- package/src/modules/bmb/workflows/create-workflow/instructions.md +0 -716
- package/src/modules/bmb/workflows/create-workflow/workflow-creation-guide.md +0 -1150
- package/src/modules/bmb/workflows/create-workflow/workflow-template/checklist.md +0 -24
- package/src/modules/bmb/workflows/create-workflow/workflow-template/instructions.md +0 -13
- package/src/modules/bmb/workflows/create-workflow/workflow-template/template.md +0 -9
- package/src/modules/bmb/workflows/create-workflow/workflow-template/workflow.yaml +0 -65
- package/src/modules/bmb/workflows/create-workflow/workflow.yaml +0 -42
- package/src/modules/bmb/workflows/edit-agent/README.md +0 -112
- package/src/modules/bmb/workflows/edit-agent/checklist.md +0 -112
- package/src/modules/bmb/workflows/edit-agent/instructions.md +0 -290
- package/src/modules/bmb/workflows/edit-agent/workflow.yaml +0 -35
- package/src/modules/bmb/workflows/edit-module/README.md +0 -187
- package/src/modules/bmb/workflows/edit-module/checklist.md +0 -165
- package/src/modules/bmb/workflows/edit-module/instructions.md +0 -339
- package/src/modules/bmb/workflows/edit-module/workflow.yaml +0 -36
- package/src/modules/bmb/workflows/edit-workflow/README.md +0 -119
- package/src/modules/bmb/workflows/edit-workflow/checklist.md +0 -70
- package/src/modules/bmb/workflows/edit-workflow/instructions.md +0 -342
- package/src/modules/bmb/workflows/edit-workflow/workflow.yaml +0 -29
- package/src/modules/bmb/workflows/module-brief/README.md +0 -264
- package/src/modules/bmb/workflows/module-brief/checklist.md +0 -116
- package/src/modules/bmb/workflows/module-brief/instructions.md +0 -267
- package/src/modules/bmb/workflows/module-brief/template.md +0 -275
- package/src/modules/bmb/workflows/module-brief/workflow.yaml +0 -31
- package/src/modules/bmb/workflows/redoc/README.md +0 -87
- package/src/modules/bmb/workflows/redoc/checklist.md +0 -99
- package/src/modules/bmb/workflows/redoc/instructions.md +0 -265
- package/src/modules/bmb/workflows/redoc/workflow.yaml +0 -34
- package/src/modules/bmm/_module-installer/assets/bmm-kb.md +0 -1
- package/src/modules/bmm/_module-installer/assets/technical-decisions.md +0 -30
- package/src/modules/bmm/_module-installer/install-config.yaml +0 -74
- package/src/modules/bmm/agents/game-architect.agent.yaml +0 -35
- package/src/modules/bmm/agents/game-designer.agent.yaml +0 -47
- package/src/modules/bmm/agents/game-dev.agent.yaml +0 -39
- package/src/modules/bmm/sub-modules/claude-code/config.yaml +0 -5
- package/src/modules/bmm/sub-modules/claude-code/injections.yaml +0 -242
- package/src/modules/bmm/sub-modules/claude-code/readme.md +0 -87
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/bmad-analysis/api-documenter.md +0 -102
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/bmad-analysis/codebase-analyzer.md +0 -82
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/bmad-analysis/data-analyst.md +0 -101
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/bmad-analysis/pattern-detector.md +0 -84
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/bmad-planning/dependency-mapper.md +0 -83
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/bmad-planning/epic-optimizer.md +0 -81
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/bmad-planning/requirements-analyst.md +0 -61
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/bmad-planning/technical-decisions-curator.md +0 -168
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/bmad-planning/trend-spotter.md +0 -115
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/bmad-planning/user-journey-mapper.md +0 -123
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/bmad-planning/user-researcher.md +0 -72
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/bmad-research/market-researcher.md +0 -51
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/bmad-research/tech-debt-auditor.md +0 -106
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/bmad-review/document-reviewer.md +0 -102
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/bmad-review/technical-evaluator.md +0 -68
- package/src/modules/bmm/sub-modules/claude-code/sub-agents/bmad-review/test-coverage-analyzer.md +0 -108
- package/src/modules/bmm/tasks/daily-standup.xml +0 -85
- package/src/modules/bmm/tasks/retrospective.xml +0 -104
- package/src/modules/bmm/teams/team-gamedev.yaml +0 -14
- package/src/modules/bmm/testarch/README.md +0 -311
- package/src/modules/bmm/workflows/1-analysis/brainstorm-game/README.md +0 -38
- package/src/modules/bmm/workflows/1-analysis/brainstorm-game/instructions.md +0 -109
- package/src/modules/bmm/workflows/1-analysis/brainstorm-game/workflow.yaml +0 -41
- package/src/modules/bmm/workflows/1-analysis/brainstorm-project/README.md +0 -29
- package/src/modules/bmm/workflows/1-analysis/brainstorm-project/instructions.md +0 -91
- package/src/modules/bmm/workflows/1-analysis/brainstorm-project/project-context.md +0 -25
- package/src/modules/bmm/workflows/1-analysis/brainstorm-project/workflow.yaml +0 -39
- package/src/modules/bmm/workflows/1-analysis/game-brief/README.md +0 -221
- package/src/modules/bmm/workflows/1-analysis/game-brief/instructions.md +0 -357
- package/src/modules/bmm/workflows/1-analysis/game-brief/workflow.yaml +0 -44
- package/src/modules/bmm/workflows/1-analysis/product-brief/README.md +0 -180
- package/src/modules/bmm/workflows/1-analysis/product-brief/checklist.md +0 -115
- package/src/modules/bmm/workflows/1-analysis/product-brief/instructions.md +0 -321
- package/src/modules/bmm/workflows/1-analysis/product-brief/template.md +0 -165
- package/src/modules/bmm/workflows/1-analysis/product-brief/workflow.yaml +0 -43
- package/src/modules/bmm/workflows/1-analysis/research/README.md +0 -454
- package/src/modules/bmm/workflows/1-analysis/research/checklist.md +0 -202
- package/src/modules/bmm/workflows/1-analysis/research/claude-code/injections.yaml +0 -114
- package/src/modules/bmm/workflows/1-analysis/research/claude-code/sub-agents/bmm-competitor-analyzer.md +0 -259
- package/src/modules/bmm/workflows/1-analysis/research/claude-code/sub-agents/bmm-data-analyst.md +0 -190
- package/src/modules/bmm/workflows/1-analysis/research/claude-code/sub-agents/bmm-market-researcher.md +0 -337
- package/src/modules/bmm/workflows/1-analysis/research/claude-code/sub-agents/bmm-trend-spotter.md +0 -107
- package/src/modules/bmm/workflows/1-analysis/research/claude-code/sub-agents/bmm-user-researcher.md +0 -329
- package/src/modules/bmm/workflows/1-analysis/research/instructions-deep-prompt.md +0 -433
- package/src/modules/bmm/workflows/1-analysis/research/instructions-market.md +0 -613
- package/src/modules/bmm/workflows/1-analysis/research/instructions-router.md +0 -125
- package/src/modules/bmm/workflows/1-analysis/research/instructions-technical.md +0 -501
- package/src/modules/bmm/workflows/1-analysis/research/template-deep-prompt.md +0 -94
- package/src/modules/bmm/workflows/1-analysis/research/template-market.md +0 -311
- package/src/modules/bmm/workflows/1-analysis/research/template-technical.md +0 -210
- package/src/modules/bmm/workflows/1-analysis/research/workflow.yaml +0 -49
- package/src/modules/bmm/workflows/2-plan-workflows/README.md +0 -258
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/checklist.md +0 -310
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/instructions.md +0 -1283
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/workflow.yaml +0 -42
- package/src/modules/bmm/workflows/2-plan-workflows/gdd/README.md +0 -222
- package/src/modules/bmm/workflows/2-plan-workflows/gdd/instructions-gdd.md +0 -475
- package/src/modules/bmm/workflows/2-plan-workflows/gdd/workflow.yaml +0 -67
- package/src/modules/bmm/workflows/2-plan-workflows/narrative/instructions-narrative.md +0 -557
- package/src/modules/bmm/workflows/2-plan-workflows/narrative/workflow.yaml +0 -38
- package/src/modules/bmm/workflows/2-plan-workflows/prd/checklist.md +0 -117
- package/src/modules/bmm/workflows/2-plan-workflows/prd/epics-template.md +0 -63
- package/src/modules/bmm/workflows/2-plan-workflows/prd/instructions.md +0 -449
- package/src/modules/bmm/workflows/2-plan-workflows/prd/workflow.yaml +0 -46
- package/src/modules/bmm/workflows/2-plan-workflows/tech-spec/checklist.md +0 -107
- package/src/modules/bmm/workflows/2-plan-workflows/tech-spec/epics-template.md +0 -11
- package/src/modules/bmm/workflows/2-plan-workflows/tech-spec/instructions-level0-story.md +0 -167
- package/src/modules/bmm/workflows/2-plan-workflows/tech-spec/instructions-level1-stories.md +0 -278
- package/src/modules/bmm/workflows/2-plan-workflows/tech-spec/instructions.md +0 -269
- package/src/modules/bmm/workflows/2-plan-workflows/tech-spec/tech-spec-template.md +0 -55
- package/src/modules/bmm/workflows/2-plan-workflows/tech-spec/user-story-template.md +0 -56
- package/src/modules/bmm/workflows/2-plan-workflows/tech-spec/workflow.yaml +0 -52
- package/src/modules/bmm/workflows/3-solutioning/README.md +0 -1
- package/src/modules/bmm/workflows/3-solutioning/architecture/architecture-patterns.yaml +0 -347
- package/src/modules/bmm/workflows/3-solutioning/architecture/architecture-template.md +0 -103
- package/src/modules/bmm/workflows/3-solutioning/architecture/checklist.md +0 -244
- package/src/modules/bmm/workflows/3-solutioning/architecture/instructions.md +0 -703
- package/src/modules/bmm/workflows/3-solutioning/architecture/readme.md +0 -318
- package/src/modules/bmm/workflows/3-solutioning/architecture/workflow.yaml +0 -54
- package/src/modules/bmm/workflows/3-solutioning/solutioning-gate-check/README.md +0 -177
- package/src/modules/bmm/workflows/3-solutioning/solutioning-gate-check/checklist.md +0 -175
- package/src/modules/bmm/workflows/3-solutioning/solutioning-gate-check/instructions.md +0 -273
- package/src/modules/bmm/workflows/3-solutioning/solutioning-gate-check/template.md +0 -146
- package/src/modules/bmm/workflows/3-solutioning/solutioning-gate-check/validation-criteria.yaml +0 -189
- package/src/modules/bmm/workflows/3-solutioning/solutioning-gate-check/workflow.yaml +0 -40
- package/src/modules/bmm/workflows/4-implementation/README.md +0 -221
- package/src/modules/bmm/workflows/4-implementation/code-review/README.md +0 -69
- package/src/modules/bmm/workflows/4-implementation/code-review/instructions.md +0 -391
- package/src/modules/bmm/workflows/4-implementation/correct-course/README.md +0 -73
- package/src/modules/bmm/workflows/4-implementation/create-story/README.md +0 -129
- package/src/modules/bmm/workflows/4-implementation/create-story/instructions.md +0 -252
- package/src/modules/bmm/workflows/4-implementation/dev-story/AUDIT-REPORT.md +0 -367
- package/src/modules/bmm/workflows/4-implementation/dev-story/README.md +0 -206
- package/src/modules/bmm/workflows/4-implementation/dev-story/instructions.md +0 -262
- package/src/modules/bmm/workflows/4-implementation/epic-tech-context/README.md +0 -195
- package/src/modules/bmm/workflows/4-implementation/epic-tech-context/checklist.md +0 -17
- package/src/modules/bmm/workflows/4-implementation/epic-tech-context/instructions.md +0 -160
- package/src/modules/bmm/workflows/4-implementation/epic-tech-context/template.md +0 -76
- package/src/modules/bmm/workflows/4-implementation/epic-tech-context/workflow.yaml +0 -34
- package/src/modules/bmm/workflows/4-implementation/retrospective/README.md +0 -77
- package/src/modules/bmm/workflows/4-implementation/sprint-planning/README.md +0 -156
- package/src/modules/bmm/workflows/4-implementation/story-context/README.md +0 -234
- package/src/modules/bmm/workflows/4-implementation/story-context/checklist.md +0 -16
- package/src/modules/bmm/workflows/4-implementation/story-context/context-template.xml +0 -34
- package/src/modules/bmm/workflows/4-implementation/story-context/instructions.md +0 -201
- package/src/modules/bmm/workflows/4-implementation/story-context/workflow.yaml +0 -32
- package/src/modules/bmm/workflows/4-implementation/story-done/instructions.md +0 -111
- package/src/modules/bmm/workflows/4-implementation/story-done/workflow.yaml +0 -27
- package/src/modules/bmm/workflows/4-implementation/story-ready/instructions.md +0 -117
- package/src/modules/bmm/workflows/4-implementation/story-ready/workflow.yaml +0 -27
- package/src/modules/bmm/workflows/README.md +0 -577
- package/src/modules/bmm/workflows/document-project/README.md +0 -444
- package/src/modules/bmm/workflows/document-project/templates/README.md +0 -38
- package/src/modules/bmm/workflows/testarch/README.md +0 -26
- package/src/modules/bmm/workflows/testarch/atdd/README.md +0 -672
- package/src/modules/bmm/workflows/testarch/automate/README.md +0 -869
- package/src/modules/bmm/workflows/testarch/ci/README.md +0 -493
- package/src/modules/bmm/workflows/testarch/framework/README.md +0 -340
- package/src/modules/bmm/workflows/testarch/nfr-assess/README.md +0 -469
- package/src/modules/bmm/workflows/testarch/test-design/README.md +0 -493
- package/src/modules/bmm/workflows/testarch/test-review/README.md +0 -775
- package/src/modules/bmm/workflows/testarch/trace/README.md +0 -802
- package/src/modules/bmm/workflows/workflow-status/README.md +0 -241
- package/src/modules/bmm/workflows/workflow-status/paths/brownfield-level-0.yaml +0 -54
- package/src/modules/bmm/workflows/workflow-status/paths/brownfield-level-1.yaml +0 -58
- package/src/modules/bmm/workflows/workflow-status/paths/brownfield-level-2.yaml +0 -76
- package/src/modules/bmm/workflows/workflow-status/paths/brownfield-level-3.yaml +0 -95
- package/src/modules/bmm/workflows/workflow-status/paths/brownfield-level-4.yaml +0 -88
- package/src/modules/bmm/workflows/workflow-status/paths/game-design.yaml +0 -75
- package/src/modules/bmm/workflows/workflow-status/paths/greenfield-level-0.yaml +0 -45
- package/src/modules/bmm/workflows/workflow-status/paths/greenfield-level-1.yaml +0 -49
- package/src/modules/bmm/workflows/workflow-status/paths/greenfield-level-2.yaml +0 -78
- package/src/modules/bmm/workflows/workflow-status/paths/greenfield-level-3.yaml +0 -73
- package/src/modules/bmm/workflows/workflow-status/paths/greenfield-level-4.yaml +0 -75
- package/src/modules/bmm/workflows/workflow-status/workflow-status-template.md +0 -30
- package/src/modules/cis/_module-installer/install-config.yaml +0 -14
- package/src/modules/cis/agents/README.md +0 -104
- package/src/modules/cis/agents/storyteller.agent.yaml +0 -23
- package/src/modules/cis/readme.md +0 -86
- package/src/utility/models/agent-activation-ide.xml +0 -51
- package/src/utility/models/agent-activation-web.xml +0 -60
- package/src/utility/models/agent-config-template.md +0 -23
- package/src/utility/models/agent-in-team-activation.xml +0 -3
- package/src/utility/models/fragments/activation-rules.xml +0 -8
- package/src/utility/models/fragments/activation-steps.xml +0 -15
- package/src/utility/models/fragments/handler-action.xml +0 -4
- package/src/utility/models/fragments/handler-exec.xml +0 -5
- package/src/utility/models/fragments/handler-tmpl.xml +0 -5
- package/src/utility/models/fragments/handler-validate-workflow.xml +0 -7
- package/src/utility/models/fragments/handler-workflow.xml +0 -9
- package/src/utility/models/fragments/menu-handlers.xml +0 -6
- package/src/utility/models/fragments/web-bundle-activation-steps.xml +0 -32
- package/src/utility/templates/agent.customize.template.yaml +0 -42
- package/test/fixtures/agent-schema/invalid/persona/principles-as-string.agent.yaml +0 -23
- package/tools/cli/bundlers/bundle-web.js +0 -179
- package/tools/cli/bundlers/test-analyst.js +0 -28
- package/tools/cli/bundlers/test-bundler.js +0 -118
- package/tools/cli/bundlers/web-bundler.js +0 -1479
- package/tools/cli/commands/build.js +0 -458
- package/tools/cli/commands/list.js +0 -28
- package/tools/cli/commands/status.js +0 -47
- package/tools/cli/commands/uninstall.js +0 -44
- package/tools/cli/commands/update.js +0 -28
- package/tools/cli/installers/lib/ide/task-tool-command-generator.js +0 -119
- package/tools/cli/installers/lib/ide/workflow-command-generator.js +0 -235
- package/tools/cli/installers/lib/ide/workflow-command-template.md +0 -15
- package/tools/cli/lib/replace-project-root.js +0 -239
- package/tools/cli/regenerate-manifests.js +0 -28
- package/tools/cli/test-yaml-builder.js +0 -43
- package/tools/validate-bundles.js +0 -87
- package/v6-open-items.md +0 -23
- /package/{bmad/bmb/workflows → src/modules/bmb/workflows-legacy}/module-brief/template.md +0 -0
- /package/src/modules/{bmm/workflows/1-analysis → bmgd/workflows/1-preproduction}/brainstorm-game/game-brain-methods.csv +0 -0
- /package/src/modules/{bmm/workflows/1-analysis → bmgd/workflows/1-preproduction}/brainstorm-game/game-context.md +0 -0
- /package/src/modules/{bmm/workflows/1-analysis → bmgd/workflows/1-preproduction}/game-brief/checklist.md +0 -0
- /package/src/modules/{bmm/workflows/1-analysis/game-brief/template.md → bmgd/workflows/1-preproduction/game-brief/templates/game-brief-template.md} +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/checklist.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/action-platformer.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/adventure.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/card-game.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/fighting.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/horror.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/idle-incremental.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/metroidvania.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/moba.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/party-game.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/puzzle.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/racing.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/rhythm.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/roguelike.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/rpg.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/sandbox.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/shooter.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/simulation.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/sports.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/strategy.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/survival.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/text-based.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/tower-defense.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/turn-based-tactics.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types/visual-novel.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/gdd/game-types.csv +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows/gdd → bmgd/workflows/2-design/gdd/templates}/gdd-template.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows → bmgd/workflows/2-design}/narrative/checklist.md +0 -0
- /package/src/modules/{bmm/workflows/2-plan-workflows/narrative → bmgd/workflows/2-design/narrative/templates}/narrative-template.md +0 -0
- /package/src/modules/{bmm/workflows/3-solutioning/architecture → bmgd/workflows/3-technical/game-architecture}/decision-catalog.yaml +0 -0
- /package/src/modules/{bmm/workflows/3-solutioning/architecture → bmgd/workflows/3-technical/game-architecture}/pattern-categories.csv +0 -0
- /package/src/modules/{bmm/workflows/4-implementation/code-review/backlog_template.md → bmgd/workflows/4-production/code-review/backlog-template.md} +0 -0
- /package/src/utility/{models/fragments/handler-data.xml → agent-components/handler-data.txt} +0 -0
|
@@ -2,6 +2,7 @@ const path = require('node:path');
|
|
|
2
2
|
const fs = require('fs-extra');
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
const ora = require('ora');
|
|
5
|
+
const inquirer = require('inquirer');
|
|
5
6
|
const { Detector } = require('./detector');
|
|
6
7
|
const { Manifest } = require('./manifest');
|
|
7
8
|
const { ModuleManager } = require('../modules/manager');
|
|
@@ -11,12 +12,14 @@ const { Config } = require('../../../lib/config');
|
|
|
11
12
|
const { XmlHandler } = require('../../../lib/xml-handler');
|
|
12
13
|
const { DependencyResolver } = require('./dependency-resolver');
|
|
13
14
|
const { ConfigCollector } = require('./config-collector');
|
|
14
|
-
// processInstallation no longer needed - LLMs understand {project-root}
|
|
15
15
|
const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
|
|
16
|
-
const { AgentPartyGenerator } = require('../../../lib/agent-party-generator');
|
|
17
16
|
const { CLIUtils } = require('../../../lib/cli-utils');
|
|
18
17
|
const { ManifestGenerator } = require('./manifest-generator');
|
|
19
18
|
const { IdeConfigManager } = require('./ide-config-manager');
|
|
19
|
+
const { CustomHandler } = require('../custom/handler');
|
|
20
|
+
|
|
21
|
+
// BMAD installation folder name - this is constant and should never change
|
|
22
|
+
const BMAD_FOLDER_NAME = '_bmad';
|
|
20
23
|
|
|
21
24
|
class Installer {
|
|
22
25
|
constructor() {
|
|
@@ -30,7 +33,206 @@ class Installer {
|
|
|
30
33
|
this.dependencyResolver = new DependencyResolver();
|
|
31
34
|
this.configCollector = new ConfigCollector();
|
|
32
35
|
this.ideConfigManager = new IdeConfigManager();
|
|
33
|
-
this.installedFiles =
|
|
36
|
+
this.installedFiles = new Set(); // Track all installed files
|
|
37
|
+
this.ttsInjectedFiles = []; // Track files with TTS injection applied
|
|
38
|
+
this.bmadFolderName = BMAD_FOLDER_NAME;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Find the bmad installation directory in a project
|
|
43
|
+
* Always uses the standard _bmad folder name
|
|
44
|
+
* Also checks for legacy _cfg folder for migration
|
|
45
|
+
* @param {string} projectDir - Project directory
|
|
46
|
+
* @returns {Promise<Object>} { bmadDir: string, hasLegacyCfg: boolean }
|
|
47
|
+
*/
|
|
48
|
+
async findBmadDir(projectDir) {
|
|
49
|
+
const bmadDir = path.join(projectDir, BMAD_FOLDER_NAME);
|
|
50
|
+
|
|
51
|
+
// Check if project directory exists
|
|
52
|
+
if (!(await fs.pathExists(projectDir))) {
|
|
53
|
+
// Project doesn't exist yet, return default
|
|
54
|
+
return { bmadDir, hasLegacyCfg: false };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Check for legacy _cfg folder if bmad directory exists
|
|
58
|
+
let hasLegacyCfg = false;
|
|
59
|
+
if (await fs.pathExists(bmadDir)) {
|
|
60
|
+
const legacyCfgPath = path.join(bmadDir, '_cfg');
|
|
61
|
+
if (await fs.pathExists(legacyCfgPath)) {
|
|
62
|
+
hasLegacyCfg = true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return { bmadDir, hasLegacyCfg };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @function copyFileWithPlaceholderReplacement
|
|
71
|
+
* @intent Copy files from BMAD source to installation directory with dynamic content transformation
|
|
72
|
+
* @why Enables installation-time customization: _bmad replacement + optional AgentVibes TTS injection
|
|
73
|
+
* @param {string} sourcePath - Absolute path to source file in BMAD repository
|
|
74
|
+
* @param {string} targetPath - Absolute path to destination file in user's project
|
|
75
|
+
* @param {string} bmadFolderName - User's chosen bmad folder name (default: 'bmad')
|
|
76
|
+
* @returns {Promise<void>} Resolves when file copy and transformation complete
|
|
77
|
+
* @sideeffects Writes transformed file to targetPath, creates parent directories if needed
|
|
78
|
+
* @edgecases Binary files bypass transformation, falls back to raw copy if UTF-8 read fails
|
|
79
|
+
* @calledby installCore(), installModule(), IDE installers during file vendoring
|
|
80
|
+
* @calls processTTSInjectionPoints(), fs.readFile(), fs.writeFile(), fs.copy()
|
|
81
|
+
*
|
|
82
|
+
* The injection point processing enables loose coupling between BMAD and TTS providers:
|
|
83
|
+
* - BMAD source contains injection markers (not actual TTS code)
|
|
84
|
+
* - At install-time, markers are replaced OR removed based on user preference
|
|
85
|
+
* - Result: Clean installs for users without TTS, working TTS for users with it
|
|
86
|
+
*
|
|
87
|
+
* PATTERN: Adding New Injection Points
|
|
88
|
+
* =====================================
|
|
89
|
+
* 1. Add HTML comment marker in BMAD source file:
|
|
90
|
+
* <!-- TTS_INJECTION:feature-name -->
|
|
91
|
+
*
|
|
92
|
+
* 2. Add replacement logic in processTTSInjectionPoints():
|
|
93
|
+
* if (enableAgentVibes) {
|
|
94
|
+
* content = content.replace(/<!-- TTS_INJECTION:feature-name -->/g, 'actual code');
|
|
95
|
+
* } else {
|
|
96
|
+
* content = content.replace(/<!-- TTS_INJECTION:feature-name -->\n?/g, '');
|
|
97
|
+
* }
|
|
98
|
+
*
|
|
99
|
+
* 3. Document marker in instructions.md (if applicable)
|
|
100
|
+
*/
|
|
101
|
+
async copyFileWithPlaceholderReplacement(sourcePath, targetPath) {
|
|
102
|
+
// List of text file extensions that should have placeholder replacement
|
|
103
|
+
const textExtensions = ['.md', '.yaml', '.yml', '.txt', '.json', '.js', '.ts', '.html', '.css', '.sh', '.bat', '.csv', '.xml'];
|
|
104
|
+
const ext = path.extname(sourcePath).toLowerCase();
|
|
105
|
+
|
|
106
|
+
// Check if this is a text file that might contain placeholders
|
|
107
|
+
if (textExtensions.includes(ext)) {
|
|
108
|
+
try {
|
|
109
|
+
// Read the file content
|
|
110
|
+
let content = await fs.readFile(sourcePath, 'utf8');
|
|
111
|
+
|
|
112
|
+
// Process AgentVibes injection points (pass targetPath for tracking)
|
|
113
|
+
content = this.processTTSInjectionPoints(content, targetPath);
|
|
114
|
+
|
|
115
|
+
// Write to target with replaced content
|
|
116
|
+
await fs.ensureDir(path.dirname(targetPath));
|
|
117
|
+
await fs.writeFile(targetPath, content, 'utf8');
|
|
118
|
+
} catch {
|
|
119
|
+
// If reading as text fails (might be binary despite extension), fall back to regular copy
|
|
120
|
+
await fs.copy(sourcePath, targetPath, { overwrite: true });
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
// Binary file or other file type - just copy directly
|
|
124
|
+
await fs.copy(sourcePath, targetPath, { overwrite: true });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* @function processTTSInjectionPoints
|
|
130
|
+
* @intent Transform TTS injection markers based on user's installation choice
|
|
131
|
+
* @why Enables optional TTS integration without tight coupling between BMAD and TTS providers
|
|
132
|
+
* @param {string} content - Raw file content containing potential injection markers
|
|
133
|
+
* @returns {string} Transformed content with markers replaced (if enabled) or stripped (if disabled)
|
|
134
|
+
* @sideeffects None - pure transformation function
|
|
135
|
+
* @edgecases Returns content unchanged if no markers present, safe to call on all files
|
|
136
|
+
* @calledby copyFileWithPlaceholderReplacement() during every file copy operation
|
|
137
|
+
* @calls String.replace() with regex patterns for each injection point type
|
|
138
|
+
*
|
|
139
|
+
* AI NOTE: This implements the injection point pattern for TTS integration.
|
|
140
|
+
* Key architectural decisions:
|
|
141
|
+
*
|
|
142
|
+
* 1. **Why Injection Points vs Direct Integration?**
|
|
143
|
+
* - BMAD and TTS providers are separate projects with different maintainers
|
|
144
|
+
* - Users may install BMAD without TTS support (and vice versa)
|
|
145
|
+
* - Hard-coding TTS calls would break BMAD for non-TTS users
|
|
146
|
+
* - Injection points allow conditional feature inclusion at install-time
|
|
147
|
+
*
|
|
148
|
+
* 2. **How It Works:**
|
|
149
|
+
* - BMAD source contains markers: <!-- TTS_INJECTION:feature-name -->
|
|
150
|
+
* - During installation, user is prompted: "Enable AgentVibes TTS?"
|
|
151
|
+
* - If YES: markers → replaced with actual bash TTS calls
|
|
152
|
+
* - If NO: markers → stripped cleanly from installed files
|
|
153
|
+
*
|
|
154
|
+
* 3. **State Management:**
|
|
155
|
+
* - this.enableAgentVibes set in install() method from config.enableAgentVibes
|
|
156
|
+
* - config.enableAgentVibes comes from ui.promptAgentVibes() user choice
|
|
157
|
+
* - Flag persists for entire installation, all files get same treatment
|
|
158
|
+
*
|
|
159
|
+
* CURRENT INJECTION POINTS:
|
|
160
|
+
* ==========================
|
|
161
|
+
* - party-mode: Injects TTS calls after each agent speaks in party mode
|
|
162
|
+
* Location: src/core/workflows/party-mode/instructions.md
|
|
163
|
+
* Marker: <!-- TTS_INJECTION:party-mode -->
|
|
164
|
+
* Replacement: Bash call to .claude/hooks/bmad-speak.sh with agent name and dialogue
|
|
165
|
+
*
|
|
166
|
+
* - agent-tts: Injects TTS rule for individual agent conversations
|
|
167
|
+
* Location: src/modules/bmm/agents/*.md (all agent files)
|
|
168
|
+
* Marker: <!-- TTS_INJECTION:agent-tts -->
|
|
169
|
+
* Replacement: Rule instructing agent to call bmad-speak.sh with agent ID and response
|
|
170
|
+
*
|
|
171
|
+
* ADDING NEW INJECTION POINTS:
|
|
172
|
+
* =============================
|
|
173
|
+
* 1. Add new case in this function:
|
|
174
|
+
* content = content.replace(
|
|
175
|
+
* /<!-- TTS_INJECTION:new-feature -->/g,
|
|
176
|
+
* `code to inject when enabled`
|
|
177
|
+
* );
|
|
178
|
+
*
|
|
179
|
+
* 2. Add marker to BMAD source file at injection location
|
|
180
|
+
*
|
|
181
|
+
* 3. Test both enabled and disabled flows
|
|
182
|
+
*
|
|
183
|
+
* RELATED:
|
|
184
|
+
* ========
|
|
185
|
+
* - GitHub Issue: paulpreibisch/AgentVibes#36
|
|
186
|
+
* - User Prompt: tools/cli/lib/ui.js::promptAgentVibes()
|
|
187
|
+
* - Marker Locations:
|
|
188
|
+
* - src/core/workflows/party-mode/instructions.md:101
|
|
189
|
+
* - src/modules/bmm/agents/*.md (rules sections)
|
|
190
|
+
* - TTS Hook: .claude/hooks/bmad-speak.sh (in AgentVibes repo)
|
|
191
|
+
*/
|
|
192
|
+
processTTSInjectionPoints(content, targetPath = null) {
|
|
193
|
+
// Check if AgentVibes is enabled (set during installation configuration)
|
|
194
|
+
const enableAgentVibes = this.enableAgentVibes || false;
|
|
195
|
+
|
|
196
|
+
// Check if content contains any TTS injection markers
|
|
197
|
+
const hasPartyMode = content.includes('<!-- TTS_INJECTION:party-mode -->');
|
|
198
|
+
const hasAgentTTS = content.includes('<!-- TTS_INJECTION:agent-tts -->');
|
|
199
|
+
|
|
200
|
+
if (enableAgentVibes) {
|
|
201
|
+
// Replace party-mode injection marker with actual TTS call
|
|
202
|
+
// Use single quotes to prevent shell expansion of special chars like !
|
|
203
|
+
content = content.replaceAll(
|
|
204
|
+
'<!-- TTS_INJECTION:party-mode -->',
|
|
205
|
+
`<critical>IMPORTANT: Always use PROJECT hooks (.claude/hooks/), NEVER global hooks (~/.claude/hooks/)</critical>
|
|
206
|
+
|
|
207
|
+
If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
|
208
|
+
- Use Bash tool: \`.claude/hooks/bmad-speak.sh '[Agent Name]' '[dialogue]'\`
|
|
209
|
+
- This speaks the dialogue with the agent's unique voice
|
|
210
|
+
- Run in background to not block next agent`,
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
// Replace agent-tts injection marker with TTS rule for individual agents
|
|
214
|
+
content = content.replaceAll(
|
|
215
|
+
'<!-- TTS_INJECTION:agent-tts -->',
|
|
216
|
+
`- When responding to user messages, speak your responses using TTS:
|
|
217
|
+
Call: \`.claude/hooks/bmad-speak.sh '{agent-id}' '{response-text}'\` after each response
|
|
218
|
+
Replace {agent-id} with YOUR agent ID from <agent id="..."> tag at top of this file
|
|
219
|
+
Replace {response-text} with the text you just output to the user
|
|
220
|
+
IMPORTANT: Use single quotes as shown - do NOT escape special characters like ! or $ inside single quotes
|
|
221
|
+
Run in background (&) to avoid blocking`,
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
// Track files that had TTS injection applied
|
|
225
|
+
if (targetPath && (hasPartyMode || hasAgentTTS)) {
|
|
226
|
+
const injectionType = hasPartyMode ? 'party-mode' : 'agent-tts';
|
|
227
|
+
this.ttsInjectedFiles.push({ path: targetPath, type: injectionType });
|
|
228
|
+
}
|
|
229
|
+
} else {
|
|
230
|
+
// Strip injection markers cleanly when AgentVibes is disabled
|
|
231
|
+
content = content.replaceAll(/<!-- TTS_INJECTION:party-mode -->\n?/g, '');
|
|
232
|
+
content = content.replaceAll(/<!-- TTS_INJECTION:agent-tts -->\n?/g, '');
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return content;
|
|
34
236
|
}
|
|
35
237
|
|
|
36
238
|
/**
|
|
@@ -61,7 +263,7 @@ class Installer {
|
|
|
61
263
|
// Check for already configured IDEs
|
|
62
264
|
const { Detector } = require('./detector');
|
|
63
265
|
const detector = new Detector();
|
|
64
|
-
const bmadDir = path.join(projectDir,
|
|
266
|
+
const bmadDir = path.join(projectDir, BMAD_FOLDER_NAME);
|
|
65
267
|
|
|
66
268
|
// During full reinstall, use the saved previous IDEs since bmad dir was deleted
|
|
67
269
|
// Otherwise detect from existing installation
|
|
@@ -96,7 +298,10 @@ class Installer {
|
|
|
96
298
|
|
|
97
299
|
for (const ide of newlySelectedIdes) {
|
|
98
300
|
// List of IDEs that have interactive prompts
|
|
99
|
-
|
|
301
|
+
//TODO: Why is this here, hardcoding this list here is bad, fix me!
|
|
302
|
+
const needsPrompts = ['claude-code', 'github-copilot', 'roo', 'cline', 'auggie', 'codex', 'qwen', 'gemini', 'rovo-dev'].includes(
|
|
303
|
+
ide,
|
|
304
|
+
);
|
|
100
305
|
|
|
101
306
|
if (needsPrompts) {
|
|
102
307
|
// Get IDE handler and collect configuration
|
|
@@ -117,7 +322,6 @@ class Installer {
|
|
|
117
322
|
} else if (ideModule.default) {
|
|
118
323
|
SetupClass = ideModule.default;
|
|
119
324
|
} else {
|
|
120
|
-
// Skip if no setup class found
|
|
121
325
|
continue;
|
|
122
326
|
}
|
|
123
327
|
|
|
@@ -163,22 +367,29 @@ class Installer {
|
|
|
163
367
|
* @param {string[]} config.ides - IDEs to configure
|
|
164
368
|
* @param {boolean} config.skipIde - Skip IDE configuration
|
|
165
369
|
*/
|
|
166
|
-
async install(
|
|
167
|
-
//
|
|
168
|
-
|
|
370
|
+
async install(originalConfig) {
|
|
371
|
+
// Clone config to avoid mutating the caller's object
|
|
372
|
+
const config = { ...originalConfig };
|
|
169
373
|
|
|
170
|
-
//
|
|
171
|
-
|
|
374
|
+
// Check if core config was already collected in UI
|
|
375
|
+
const hasCoreConfig = config.coreConfig && Object.keys(config.coreConfig).length > 0;
|
|
172
376
|
|
|
173
|
-
//
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
377
|
+
// Only display logo if core config wasn't already collected (meaning we're not continuing from UI)
|
|
378
|
+
if (!hasCoreConfig) {
|
|
379
|
+
// Display BMAD logo
|
|
380
|
+
CLIUtils.displayLogo();
|
|
381
|
+
|
|
382
|
+
// Display welcome message
|
|
383
|
+
CLIUtils.displaySection('BMad™ Installation', 'Version ' + require(path.join(getProjectRoot(), 'package.json')).version);
|
|
178
384
|
}
|
|
179
385
|
|
|
386
|
+
// Note: Legacy V4 detection now happens earlier in UI.promptInstall()
|
|
387
|
+
// before any config collection, so we don't need to check again here
|
|
388
|
+
|
|
389
|
+
const projectDir = path.resolve(config.directory);
|
|
390
|
+
|
|
180
391
|
// If core config was pre-collected (from interactive mode), use it
|
|
181
|
-
if (config.coreConfig) {
|
|
392
|
+
if (config.coreConfig && Object.keys(config.coreConfig).length > 0) {
|
|
182
393
|
this.configCollector.collectedConfig.core = config.coreConfig;
|
|
183
394
|
// Also store in allAnswers for cross-referencing
|
|
184
395
|
this.configCollector.allAnswers = {};
|
|
@@ -189,14 +400,125 @@ class Installer {
|
|
|
189
400
|
|
|
190
401
|
// Collect configurations for modules (skip if quick update already collected them)
|
|
191
402
|
let moduleConfigs;
|
|
403
|
+
let customModulePaths = new Map();
|
|
404
|
+
|
|
192
405
|
if (config._quickUpdate) {
|
|
193
406
|
// Quick update already collected all configs, use them directly
|
|
194
407
|
moduleConfigs = this.configCollector.collectedConfig;
|
|
408
|
+
|
|
409
|
+
// For quick update, populate customModulePaths from _customModuleSources
|
|
410
|
+
if (config._customModuleSources) {
|
|
411
|
+
for (const [moduleId, customInfo] of config._customModuleSources) {
|
|
412
|
+
customModulePaths.set(moduleId, customInfo.sourcePath);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
195
415
|
} else {
|
|
196
|
-
//
|
|
197
|
-
|
|
416
|
+
// For regular updates (modify flow), check manifest for custom module sources
|
|
417
|
+
if (config._isUpdate && config._existingInstall && config._existingInstall.customModules) {
|
|
418
|
+
for (const customModule of config._existingInstall.customModules) {
|
|
419
|
+
// Ensure we have an absolute sourcePath
|
|
420
|
+
let absoluteSourcePath = customModule.sourcePath;
|
|
421
|
+
|
|
422
|
+
// Check if sourcePath is a cache-relative path (starts with _config)
|
|
423
|
+
if (absoluteSourcePath && absoluteSourcePath.startsWith('_config')) {
|
|
424
|
+
// Convert cache-relative path to absolute path
|
|
425
|
+
absoluteSourcePath = path.join(bmadDir, absoluteSourcePath);
|
|
426
|
+
}
|
|
427
|
+
// If no sourcePath but we have relativePath, convert it
|
|
428
|
+
else if (!absoluteSourcePath && customModule.relativePath) {
|
|
429
|
+
// relativePath is relative to the project root (parent of bmad dir)
|
|
430
|
+
absoluteSourcePath = path.resolve(projectDir, customModule.relativePath);
|
|
431
|
+
}
|
|
432
|
+
// Ensure sourcePath is absolute for anything else
|
|
433
|
+
else if (absoluteSourcePath && !path.isAbsolute(absoluteSourcePath)) {
|
|
434
|
+
absoluteSourcePath = path.resolve(absoluteSourcePath);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (absoluteSourcePath) {
|
|
438
|
+
customModulePaths.set(customModule.id, absoluteSourcePath);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// Build custom module paths map from customContent
|
|
444
|
+
|
|
445
|
+
// Handle selectedFiles (from existing install path or manual directory input)
|
|
446
|
+
if (config.customContent && config.customContent.selected && config.customContent.selectedFiles) {
|
|
447
|
+
const customHandler = new CustomHandler();
|
|
448
|
+
for (const customFile of config.customContent.selectedFiles) {
|
|
449
|
+
const customInfo = await customHandler.getCustomInfo(customFile, path.resolve(config.directory));
|
|
450
|
+
if (customInfo && customInfo.id) {
|
|
451
|
+
customModulePaths.set(customInfo.id, customInfo.path);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Handle new custom content sources from UI
|
|
457
|
+
if (config.customContent && config.customContent.sources) {
|
|
458
|
+
for (const source of config.customContent.sources) {
|
|
459
|
+
customModulePaths.set(source.id, source.path);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// Handle cachedModules (from new install path where modules are cached)
|
|
464
|
+
// Only include modules that were actually selected for installation
|
|
465
|
+
if (config.customContent && config.customContent.cachedModules) {
|
|
466
|
+
// Get selected cached module IDs (if available)
|
|
467
|
+
const selectedCachedIds = config.customContent.selectedCachedModules || [];
|
|
468
|
+
// If no selection info, include all cached modules (for backward compatibility)
|
|
469
|
+
const shouldIncludeAll = selectedCachedIds.length === 0 && config.customContent.selected;
|
|
470
|
+
|
|
471
|
+
for (const cachedModule of config.customContent.cachedModules) {
|
|
472
|
+
// For cached modules, the path is the cachePath which contains the module.yaml
|
|
473
|
+
if (
|
|
474
|
+
cachedModule.id &&
|
|
475
|
+
cachedModule.cachePath && // Include if selected or if we should include all
|
|
476
|
+
(shouldIncludeAll || selectedCachedIds.includes(cachedModule.id))
|
|
477
|
+
) {
|
|
478
|
+
customModulePaths.set(cachedModule.id, cachedModule.cachePath);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// Get list of all modules including custom modules
|
|
484
|
+
// Order: core first, then official modules, then custom modules
|
|
485
|
+
const allModulesForConfig = ['core'];
|
|
486
|
+
|
|
487
|
+
// Add official modules (excluding core and any custom modules)
|
|
488
|
+
const officialModules = (config.modules || []).filter((m) => m !== 'core' && !customModulePaths.has(m));
|
|
489
|
+
allModulesForConfig.push(...officialModules);
|
|
490
|
+
|
|
491
|
+
// Add custom modules at the end
|
|
492
|
+
for (const [moduleId] of customModulePaths) {
|
|
493
|
+
if (!allModulesForConfig.includes(moduleId)) {
|
|
494
|
+
allModulesForConfig.push(moduleId);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// Check if core was already collected in UI
|
|
499
|
+
if (config.coreConfig && Object.keys(config.coreConfig).length > 0) {
|
|
500
|
+
// Core already collected, skip it in config collection
|
|
501
|
+
const modulesWithoutCore = allModulesForConfig.filter((m) => m !== 'core');
|
|
502
|
+
moduleConfigs = await this.configCollector.collectAllConfigurations(modulesWithoutCore, path.resolve(config.directory), {
|
|
503
|
+
customModulePaths,
|
|
504
|
+
});
|
|
505
|
+
} else {
|
|
506
|
+
// Core not collected yet, include it
|
|
507
|
+
moduleConfigs = await this.configCollector.collectAllConfigurations(allModulesForConfig, path.resolve(config.directory), {
|
|
508
|
+
customModulePaths,
|
|
509
|
+
});
|
|
510
|
+
}
|
|
198
511
|
}
|
|
199
512
|
|
|
513
|
+
// Store AgentVibes configuration for injection point processing
|
|
514
|
+
this.enableAgentVibes = config.enableAgentVibes || false;
|
|
515
|
+
|
|
516
|
+
// Set bmad folder name on module manager and IDE manager for placeholder replacement
|
|
517
|
+
this.moduleManager.setBmadFolderName(BMAD_FOLDER_NAME);
|
|
518
|
+
this.moduleManager.setCoreConfig(moduleConfigs.core || {});
|
|
519
|
+
this.moduleManager.setCustomModulePaths(customModulePaths);
|
|
520
|
+
this.ideManager.setBmadFolderName(BMAD_FOLDER_NAME);
|
|
521
|
+
|
|
200
522
|
// Tool selection will be collected after we determine if it's a reinstall/update/new install
|
|
201
523
|
|
|
202
524
|
const spinner = ora('Preparing installation...').start();
|
|
@@ -205,6 +527,9 @@ class Installer {
|
|
|
205
527
|
// Resolve target directory (path.resolve handles platform differences)
|
|
206
528
|
const projectDir = path.resolve(config.directory);
|
|
207
529
|
|
|
530
|
+
// Always use the standard _bmad folder name
|
|
531
|
+
const bmadDir = path.join(projectDir, BMAD_FOLDER_NAME);
|
|
532
|
+
|
|
208
533
|
// Create a project directory if it doesn't exist (user already confirmed)
|
|
209
534
|
if (!(await fs.pathExists(projectDir))) {
|
|
210
535
|
spinner.text = 'Creating installation directory...';
|
|
@@ -225,8 +550,6 @@ class Installer {
|
|
|
225
550
|
}
|
|
226
551
|
}
|
|
227
552
|
|
|
228
|
-
const bmadDir = path.join(projectDir, 'bmad');
|
|
229
|
-
|
|
230
553
|
// Check existing installation
|
|
231
554
|
spinner.text = 'Checking for existing installation...';
|
|
232
555
|
const existingInstall = await this.detector.detect(bmadDir);
|
|
@@ -236,9 +559,7 @@ class Installer {
|
|
|
236
559
|
|
|
237
560
|
// Check if user already decided what to do (from early menu in ui.js)
|
|
238
561
|
let action = null;
|
|
239
|
-
if (config.
|
|
240
|
-
action = 'reinstall';
|
|
241
|
-
} else if (config.actionType === 'update') {
|
|
562
|
+
if (config.actionType === 'update') {
|
|
242
563
|
action = 'update';
|
|
243
564
|
} else {
|
|
244
565
|
// Fallback: Ask the user (backwards compatibility for other code paths)
|
|
@@ -250,64 +571,49 @@ class Installer {
|
|
|
250
571
|
action = promptResult.action;
|
|
251
572
|
}
|
|
252
573
|
|
|
253
|
-
if (action === '
|
|
254
|
-
console.log('Installation cancelled.');
|
|
255
|
-
return { success: false, cancelled: true };
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
if (action === 'reinstall') {
|
|
259
|
-
// Warn about destructive operation
|
|
260
|
-
console.log(chalk.red.bold('\n⚠️ WARNING: This is a destructive operation!'));
|
|
261
|
-
console.log(chalk.red('All custom files and modifications in the bmad directory will be lost.'));
|
|
262
|
-
|
|
263
|
-
const inquirer = require('inquirer');
|
|
264
|
-
const { confirmReinstall } = await inquirer.prompt([
|
|
265
|
-
{
|
|
266
|
-
type: 'confirm',
|
|
267
|
-
name: 'confirmReinstall',
|
|
268
|
-
message: chalk.yellow('Are you sure you want to delete and reinstall?'),
|
|
269
|
-
default: false,
|
|
270
|
-
},
|
|
271
|
-
]);
|
|
272
|
-
|
|
273
|
-
if (!confirmReinstall) {
|
|
274
|
-
console.log('Installation cancelled.');
|
|
275
|
-
return { success: false, cancelled: true };
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// Remember previously configured IDEs before deleting
|
|
279
|
-
config._previouslyConfiguredIdes = existingInstall.ides || [];
|
|
280
|
-
|
|
281
|
-
// Remove existing installation
|
|
282
|
-
await fs.remove(bmadDir);
|
|
283
|
-
console.log(chalk.green('✓ Removed existing installation\n'));
|
|
284
|
-
|
|
285
|
-
// Mark this as a full reinstall so we re-collect IDE configurations
|
|
286
|
-
config._isFullReinstall = true;
|
|
287
|
-
} else if (action === 'update') {
|
|
574
|
+
if (action === 'update') {
|
|
288
575
|
// Store that we're updating for later processing
|
|
289
576
|
config._isUpdate = true;
|
|
290
577
|
config._existingInstall = existingInstall;
|
|
291
578
|
|
|
292
579
|
// Detect custom and modified files BEFORE updating (compare current files vs files-manifest.csv)
|
|
293
580
|
const existingFilesManifest = await this.readFilesManifest(bmadDir);
|
|
294
|
-
console.log(chalk.dim(`DEBUG: Read ${existingFilesManifest.length} files from manifest`));
|
|
295
|
-
console.log(chalk.dim(`DEBUG: Manifest has hashes: ${existingFilesManifest.some((f) => f.hash)}`));
|
|
296
|
-
|
|
297
581
|
const { customFiles, modifiedFiles } = await this.detectCustomFiles(bmadDir, existingFilesManifest);
|
|
298
582
|
|
|
299
|
-
console.log(chalk.dim(`DEBUG: Found ${customFiles.length} custom files, ${modifiedFiles.length} modified files`));
|
|
300
|
-
if (modifiedFiles.length > 0) {
|
|
301
|
-
console.log(chalk.yellow('DEBUG: Modified files:'));
|
|
302
|
-
for (const f of modifiedFiles) console.log(chalk.dim(` - ${f.path}`));
|
|
303
|
-
}
|
|
304
|
-
|
|
305
583
|
config._customFiles = customFiles;
|
|
306
584
|
config._modifiedFiles = modifiedFiles;
|
|
307
585
|
|
|
586
|
+
// Also check cache directory for custom modules (like quick update does)
|
|
587
|
+
const cacheDir = path.join(bmadDir, '_config', 'custom');
|
|
588
|
+
if (await fs.pathExists(cacheDir)) {
|
|
589
|
+
const cachedModules = await fs.readdir(cacheDir, { withFileTypes: true });
|
|
590
|
+
|
|
591
|
+
for (const cachedModule of cachedModules) {
|
|
592
|
+
if (cachedModule.isDirectory()) {
|
|
593
|
+
const moduleId = cachedModule.name;
|
|
594
|
+
|
|
595
|
+
// Skip if we already have this module from manifest
|
|
596
|
+
if (customModulePaths.has(moduleId)) {
|
|
597
|
+
continue;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
const cachedPath = path.join(cacheDir, moduleId);
|
|
601
|
+
|
|
602
|
+
// Check if this is actually a custom module (has module.yaml)
|
|
603
|
+
const moduleYamlPath = path.join(cachedPath, 'module.yaml');
|
|
604
|
+
if (await fs.pathExists(moduleYamlPath)) {
|
|
605
|
+
customModulePaths.set(moduleId, cachedPath);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// Update module manager with the new custom module paths from cache
|
|
611
|
+
this.moduleManager.setCustomModulePaths(customModulePaths);
|
|
612
|
+
}
|
|
613
|
+
|
|
308
614
|
// If there are custom files, back them up temporarily
|
|
309
615
|
if (customFiles.length > 0) {
|
|
310
|
-
const tempBackupDir = path.join(projectDir, '
|
|
616
|
+
const tempBackupDir = path.join(projectDir, '_bmad-custom-backup-temp');
|
|
311
617
|
await fs.ensureDir(tempBackupDir);
|
|
312
618
|
|
|
313
619
|
spinner.start(`Backing up ${customFiles.length} custom files...`);
|
|
@@ -324,23 +630,19 @@ class Installer {
|
|
|
324
630
|
|
|
325
631
|
// For modified files, back them up to temp directory (will be restored as .bak files after install)
|
|
326
632
|
if (modifiedFiles.length > 0) {
|
|
327
|
-
const tempModifiedBackupDir = path.join(projectDir, '
|
|
633
|
+
const tempModifiedBackupDir = path.join(projectDir, '_bmad-modified-backup-temp');
|
|
328
634
|
await fs.ensureDir(tempModifiedBackupDir);
|
|
329
635
|
|
|
330
|
-
console.log(chalk.yellow(`\nDEBUG: Backing up ${modifiedFiles.length} modified files to temp location`));
|
|
331
636
|
spinner.start(`Backing up ${modifiedFiles.length} modified files...`);
|
|
332
637
|
for (const modifiedFile of modifiedFiles) {
|
|
333
638
|
const relativePath = path.relative(bmadDir, modifiedFile.path);
|
|
334
639
|
const tempBackupPath = path.join(tempModifiedBackupDir, relativePath);
|
|
335
|
-
console.log(chalk.dim(`DEBUG: Backing up ${relativePath} to temp`));
|
|
336
640
|
await fs.ensureDir(path.dirname(tempBackupPath));
|
|
337
641
|
await fs.copy(modifiedFile.path, tempBackupPath, { overwrite: true });
|
|
338
642
|
}
|
|
339
643
|
spinner.succeed(`Backed up ${modifiedFiles.length} modified files`);
|
|
340
644
|
|
|
341
645
|
config._tempModifiedBackupDir = tempModifiedBackupDir;
|
|
342
|
-
} else {
|
|
343
|
-
console.log(chalk.dim('DEBUG: No modified files detected'));
|
|
344
646
|
}
|
|
345
647
|
}
|
|
346
648
|
} else if (existingInstall.installed && config._quickUpdate) {
|
|
@@ -356,9 +658,37 @@ class Installer {
|
|
|
356
658
|
config._customFiles = customFiles;
|
|
357
659
|
config._modifiedFiles = modifiedFiles;
|
|
358
660
|
|
|
661
|
+
// Also check cache directory for custom modules (like quick update does)
|
|
662
|
+
const cacheDir = path.join(bmadDir, '_config', 'custom');
|
|
663
|
+
if (await fs.pathExists(cacheDir)) {
|
|
664
|
+
const cachedModules = await fs.readdir(cacheDir, { withFileTypes: true });
|
|
665
|
+
|
|
666
|
+
for (const cachedModule of cachedModules) {
|
|
667
|
+
if (cachedModule.isDirectory()) {
|
|
668
|
+
const moduleId = cachedModule.name;
|
|
669
|
+
|
|
670
|
+
// Skip if we already have this module from manifest
|
|
671
|
+
if (customModulePaths.has(moduleId)) {
|
|
672
|
+
continue;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
const cachedPath = path.join(cacheDir, moduleId);
|
|
676
|
+
|
|
677
|
+
// Check if this is actually a custom module (has module.yaml)
|
|
678
|
+
const moduleYamlPath = path.join(cachedPath, 'module.yaml');
|
|
679
|
+
if (await fs.pathExists(moduleYamlPath)) {
|
|
680
|
+
customModulePaths.set(moduleId, cachedPath);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// Update module manager with the new custom module paths from cache
|
|
686
|
+
this.moduleManager.setCustomModulePaths(customModulePaths);
|
|
687
|
+
}
|
|
688
|
+
|
|
359
689
|
// Back up custom files
|
|
360
690
|
if (customFiles.length > 0) {
|
|
361
|
-
const tempBackupDir = path.join(projectDir, '
|
|
691
|
+
const tempBackupDir = path.join(projectDir, '_bmad-custom-backup-temp');
|
|
362
692
|
await fs.ensureDir(tempBackupDir);
|
|
363
693
|
|
|
364
694
|
spinner.start(`Backing up ${customFiles.length} custom files...`);
|
|
@@ -374,7 +704,7 @@ class Installer {
|
|
|
374
704
|
|
|
375
705
|
// Back up modified files
|
|
376
706
|
if (modifiedFiles.length > 0) {
|
|
377
|
-
const tempModifiedBackupDir = path.join(projectDir, '
|
|
707
|
+
const tempModifiedBackupDir = path.join(projectDir, '_bmad-modified-backup-temp');
|
|
378
708
|
await fs.ensureDir(tempModifiedBackupDir);
|
|
379
709
|
|
|
380
710
|
spinner.start(`Backing up ${modifiedFiles.length} modified files...`);
|
|
@@ -429,44 +759,229 @@ class Installer {
|
|
|
429
759
|
config.skipIde = toolSelection.skipIde;
|
|
430
760
|
const ideConfigurations = toolSelection.configurations;
|
|
431
761
|
|
|
432
|
-
spinner.
|
|
762
|
+
if (spinner.isSpinning) {
|
|
763
|
+
spinner.text = 'Continuing installation...';
|
|
764
|
+
} else {
|
|
765
|
+
spinner.start('Continuing installation...');
|
|
766
|
+
}
|
|
433
767
|
|
|
434
768
|
// Create bmad directory structure
|
|
435
769
|
spinner.text = 'Creating directory structure...';
|
|
436
770
|
await this.createDirectoryStructure(bmadDir);
|
|
437
771
|
|
|
438
|
-
//
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
772
|
+
// Cache custom modules if any
|
|
773
|
+
if (customModulePaths && customModulePaths.size > 0) {
|
|
774
|
+
spinner.text = 'Caching custom modules...';
|
|
775
|
+
const { CustomModuleCache } = require('./custom-module-cache');
|
|
776
|
+
const customCache = new CustomModuleCache(bmadDir);
|
|
442
777
|
|
|
443
|
-
|
|
444
|
-
|
|
778
|
+
for (const [moduleId, sourcePath] of customModulePaths) {
|
|
779
|
+
const cachedInfo = await customCache.cacheModule(moduleId, sourcePath, {
|
|
780
|
+
sourcePath: sourcePath, // Store original path for updates
|
|
781
|
+
});
|
|
445
782
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
783
|
+
// Update the customModulePaths to use the cached location
|
|
784
|
+
customModulePaths.set(moduleId, cachedInfo.cachePath);
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
// Update module manager with the cached paths
|
|
788
|
+
this.moduleManager.setCustomModulePaths(customModulePaths);
|
|
789
|
+
spinner.succeed('Custom modules cached');
|
|
450
790
|
}
|
|
451
791
|
|
|
452
|
-
|
|
453
|
-
|
|
792
|
+
const projectRoot = getProjectRoot();
|
|
793
|
+
|
|
794
|
+
// Step 1: Install core module first (if requested)
|
|
795
|
+
if (config.installCore) {
|
|
454
796
|
spinner.start('Installing BMAD core...');
|
|
455
|
-
await this.installCoreWithDependencies(bmadDir,
|
|
797
|
+
await this.installCoreWithDependencies(bmadDir, { core: {} });
|
|
456
798
|
spinner.succeed('Core installed');
|
|
799
|
+
|
|
800
|
+
// Generate core config file
|
|
801
|
+
await this.generateModuleConfigs(bmadDir, { core: config.coreConfig || {} });
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
// Custom content is already handled in UI before module selection
|
|
805
|
+
let finalCustomContent = config.customContent;
|
|
806
|
+
|
|
807
|
+
// Step 3: Prepare modules list including cached custom modules
|
|
808
|
+
let allModules = [...(config.modules || [])];
|
|
809
|
+
|
|
810
|
+
// During quick update, we might have custom module sources from the manifest
|
|
811
|
+
if (config._customModuleSources) {
|
|
812
|
+
// Add custom modules from stored sources
|
|
813
|
+
for (const [moduleId, customInfo] of config._customModuleSources) {
|
|
814
|
+
if (!allModules.includes(moduleId) && (await fs.pathExists(customInfo.sourcePath))) {
|
|
815
|
+
allModules.push(moduleId);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
// Add cached custom modules
|
|
821
|
+
if (finalCustomContent && finalCustomContent.cachedModules) {
|
|
822
|
+
for (const cachedModule of finalCustomContent.cachedModules) {
|
|
823
|
+
if (!allModules.includes(cachedModule.id)) {
|
|
824
|
+
allModules.push(cachedModule.id);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
// Regular custom content from user input (non-cached)
|
|
830
|
+
if (finalCustomContent && finalCustomContent.selected && finalCustomContent.selectedFiles) {
|
|
831
|
+
// Add custom modules to the installation list
|
|
832
|
+
const customHandler = new CustomHandler();
|
|
833
|
+
for (const customFile of finalCustomContent.selectedFiles) {
|
|
834
|
+
const customInfo = await customHandler.getCustomInfo(customFile, projectDir);
|
|
835
|
+
if (customInfo && customInfo.id) {
|
|
836
|
+
allModules.push(customInfo.id);
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// Don't include core again if already installed
|
|
842
|
+
if (config.installCore) {
|
|
843
|
+
allModules = allModules.filter((m) => m !== 'core');
|
|
457
844
|
}
|
|
458
845
|
|
|
846
|
+
const modulesToInstall = allModules;
|
|
847
|
+
|
|
848
|
+
// For dependency resolution, we only need regular modules (not custom modules)
|
|
849
|
+
// Custom modules are already installed in _bmad and don't need dependency resolution from source
|
|
850
|
+
const regularModulesForResolution = allModules.filter((module) => {
|
|
851
|
+
// Check if this is a custom module
|
|
852
|
+
const isCustom =
|
|
853
|
+
customModulePaths.has(module) ||
|
|
854
|
+
(finalCustomContent && finalCustomContent.cachedModules && finalCustomContent.cachedModules.some((cm) => cm.id === module)) ||
|
|
855
|
+
(finalCustomContent &&
|
|
856
|
+
finalCustomContent.selected &&
|
|
857
|
+
finalCustomContent.selectedFiles &&
|
|
858
|
+
finalCustomContent.selectedFiles.some((f) => f.includes(module)));
|
|
859
|
+
return !isCustom;
|
|
860
|
+
});
|
|
861
|
+
|
|
862
|
+
// For dependency resolution, we need to pass the project root
|
|
863
|
+
// Create a temporary module manager that knows about custom content locations
|
|
864
|
+
const tempModuleManager = new ModuleManager({
|
|
865
|
+
bmadDir: bmadDir, // Pass bmadDir so we can check cache
|
|
866
|
+
});
|
|
867
|
+
|
|
868
|
+
const resolution = await this.dependencyResolver.resolve(projectRoot, regularModulesForResolution, {
|
|
869
|
+
verbose: config.verbose,
|
|
870
|
+
moduleManager: tempModuleManager,
|
|
871
|
+
});
|
|
872
|
+
|
|
873
|
+
spinner.succeed('Dependencies resolved');
|
|
874
|
+
|
|
459
875
|
// Install modules with their dependencies
|
|
460
|
-
if (
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
876
|
+
if (allModules && allModules.length > 0) {
|
|
877
|
+
const installedModuleNames = new Set();
|
|
878
|
+
|
|
879
|
+
for (const moduleName of allModules) {
|
|
880
|
+
// Skip if already installed
|
|
881
|
+
if (installedModuleNames.has(moduleName)) {
|
|
882
|
+
continue;
|
|
883
|
+
}
|
|
884
|
+
installedModuleNames.add(moduleName);
|
|
885
|
+
|
|
886
|
+
// Show appropriate message based on whether this is a quick update
|
|
887
|
+
const isQuickUpdate = config._quickUpdate || false;
|
|
888
|
+
spinner.start(`${isQuickUpdate ? 'Updating' : 'Installing'} module: ${moduleName}...`);
|
|
889
|
+
|
|
890
|
+
// Check if this is a custom module
|
|
891
|
+
let isCustomModule = false;
|
|
892
|
+
let customInfo = null;
|
|
893
|
+
let useCache = false;
|
|
894
|
+
|
|
895
|
+
// First check if we have a cached version
|
|
896
|
+
if (finalCustomContent && finalCustomContent.cachedModules) {
|
|
897
|
+
const cachedModule = finalCustomContent.cachedModules.find((m) => m.id === moduleName);
|
|
898
|
+
if (cachedModule) {
|
|
899
|
+
isCustomModule = true;
|
|
900
|
+
customInfo = {
|
|
901
|
+
id: moduleName,
|
|
902
|
+
path: cachedModule.cachePath,
|
|
903
|
+
config: {},
|
|
904
|
+
};
|
|
905
|
+
useCache = true;
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// Then check if we have custom module sources from the manifest (for quick update)
|
|
910
|
+
if (!isCustomModule && config._customModuleSources && config._customModuleSources.has(moduleName)) {
|
|
911
|
+
customInfo = config._customModuleSources.get(moduleName);
|
|
912
|
+
isCustomModule = true;
|
|
913
|
+
|
|
914
|
+
// Check if this is a cached module (source path starts with _config)
|
|
915
|
+
if (
|
|
916
|
+
customInfo.sourcePath &&
|
|
917
|
+
(customInfo.sourcePath.startsWith('_config') || customInfo.sourcePath.includes('_config/custom'))
|
|
918
|
+
) {
|
|
919
|
+
useCache = true;
|
|
920
|
+
// Make sure we have the right path structure
|
|
921
|
+
if (!customInfo.path) {
|
|
922
|
+
customInfo.path = customInfo.sourcePath;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
// Finally check regular custom content
|
|
928
|
+
if (!isCustomModule && finalCustomContent && finalCustomContent.selected && finalCustomContent.selectedFiles) {
|
|
929
|
+
const customHandler = new CustomHandler();
|
|
930
|
+
for (const customFile of finalCustomContent.selectedFiles) {
|
|
931
|
+
const info = await customHandler.getCustomInfo(customFile, projectDir);
|
|
932
|
+
if (info && info.id === moduleName) {
|
|
933
|
+
isCustomModule = true;
|
|
934
|
+
customInfo = info;
|
|
935
|
+
break;
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
if (isCustomModule && customInfo) {
|
|
941
|
+
// Custom modules are now installed via ModuleManager just like standard modules
|
|
942
|
+
// The custom module path should already be in customModulePaths from earlier setup
|
|
943
|
+
if (!customModulePaths.has(moduleName) && customInfo.path) {
|
|
944
|
+
customModulePaths.set(moduleName, customInfo.path);
|
|
945
|
+
this.moduleManager.setCustomModulePaths(customModulePaths);
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
const collectedModuleConfig = moduleConfigs[moduleName] || {};
|
|
949
|
+
|
|
950
|
+
// Use ModuleManager to install the custom module
|
|
951
|
+
await this.moduleManager.install(
|
|
952
|
+
moduleName,
|
|
953
|
+
bmadDir,
|
|
954
|
+
(filePath) => {
|
|
955
|
+
this.installedFiles.add(filePath);
|
|
956
|
+
},
|
|
957
|
+
{
|
|
958
|
+
isCustom: true,
|
|
959
|
+
moduleConfig: collectedModuleConfig,
|
|
960
|
+
isQuickUpdate: config._quickUpdate || false,
|
|
961
|
+
installer: this,
|
|
962
|
+
},
|
|
963
|
+
);
|
|
964
|
+
|
|
965
|
+
// Create module config (include collected config from module.yaml prompts)
|
|
966
|
+
await this.generateModuleConfigs(bmadDir, {
|
|
967
|
+
[moduleName]: { ...config.coreConfig, ...customInfo.config, ...collectedModuleConfig },
|
|
968
|
+
});
|
|
969
|
+
} else {
|
|
970
|
+
// Regular module installation
|
|
971
|
+
// Special case for core module
|
|
972
|
+
if (moduleName === 'core') {
|
|
973
|
+
await this.installCoreWithDependencies(bmadDir, resolution.byModule[moduleName]);
|
|
974
|
+
} else {
|
|
975
|
+
await this.installModuleWithDependencies(moduleName, bmadDir, resolution.byModule[moduleName]);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
spinner.succeed(`Module ${isQuickUpdate ? 'updated' : 'installed'}: ${moduleName}`);
|
|
465
980
|
}
|
|
466
981
|
|
|
467
982
|
// Install partial modules (only dependencies)
|
|
468
983
|
for (const [module, files] of Object.entries(resolution.byModule)) {
|
|
469
|
-
if (!
|
|
984
|
+
if (!allModules.includes(module) && module !== 'core') {
|
|
470
985
|
const totalFiles =
|
|
471
986
|
files.agents.length +
|
|
472
987
|
files.tasks.length +
|
|
@@ -483,6 +998,8 @@ class Installer {
|
|
|
483
998
|
}
|
|
484
999
|
}
|
|
485
1000
|
|
|
1001
|
+
// All content is now installed as modules - no separate custom content handling needed
|
|
1002
|
+
|
|
486
1003
|
// Generate clean config.yaml files for each installed module
|
|
487
1004
|
spinner.start('Generating module configurations...');
|
|
488
1005
|
await this.generateModuleConfigs(bmadDir, moduleConfigs);
|
|
@@ -493,26 +1010,41 @@ class Installer {
|
|
|
493
1010
|
// Customize templates are now created in processAgentFiles when building YAML agents
|
|
494
1011
|
|
|
495
1012
|
// Pre-register manifest files that will be created (except files-manifest.csv to avoid recursion)
|
|
496
|
-
const cfgDir = path.join(bmadDir, '
|
|
497
|
-
this.installedFiles.
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
path.join(cfgDir, 'task-manifest.csv'),
|
|
502
|
-
);
|
|
1013
|
+
const cfgDir = path.join(bmadDir, '_config');
|
|
1014
|
+
this.installedFiles.add(path.join(cfgDir, 'manifest.yaml'));
|
|
1015
|
+
this.installedFiles.add(path.join(cfgDir, 'workflow-manifest.csv'));
|
|
1016
|
+
this.installedFiles.add(path.join(cfgDir, 'agent-manifest.csv'));
|
|
1017
|
+
this.installedFiles.add(path.join(cfgDir, 'task-manifest.csv'));
|
|
503
1018
|
|
|
504
1019
|
// Generate CSV manifests for workflows, agents, tasks AND ALL FILES with hashes BEFORE IDE setup
|
|
505
1020
|
spinner.start('Generating workflow and agent manifests...');
|
|
506
1021
|
const manifestGen = new ManifestGenerator();
|
|
507
1022
|
|
|
508
|
-
//
|
|
509
|
-
|
|
1023
|
+
// For quick update, we need ALL installed modules in the manifest
|
|
1024
|
+
// Not just the ones being updated
|
|
1025
|
+
const allModulesForManifest = config._quickUpdate
|
|
1026
|
+
? config._existingModules || allModules || []
|
|
1027
|
+
: config._preserveModules
|
|
1028
|
+
? [...allModules, ...config._preserveModules]
|
|
1029
|
+
: allModules || [];
|
|
1030
|
+
|
|
1031
|
+
// For regular installs (including when called from quick update), use what we have
|
|
1032
|
+
let modulesForCsvPreserve;
|
|
1033
|
+
if (config._quickUpdate) {
|
|
1034
|
+
// Quick update - use existing modules or fall back to modules being updated
|
|
1035
|
+
modulesForCsvPreserve = config._existingModules || allModules || [];
|
|
1036
|
+
} else {
|
|
1037
|
+
// Regular install - use the modules we're installing plus any preserved ones
|
|
1038
|
+
modulesForCsvPreserve = config._preserveModules ? [...allModules, ...config._preserveModules] : allModules;
|
|
1039
|
+
}
|
|
510
1040
|
|
|
511
|
-
const manifestStats = await manifestGen.generateManifests(bmadDir,
|
|
1041
|
+
const manifestStats = await manifestGen.generateManifests(bmadDir, allModulesForManifest, [...this.installedFiles], {
|
|
512
1042
|
ides: config.ides || [],
|
|
513
|
-
preservedModules:
|
|
1043
|
+
preservedModules: modulesForCsvPreserve, // Scan these from installed bmad/ dir
|
|
514
1044
|
});
|
|
515
1045
|
|
|
1046
|
+
// Custom modules are now included in the main modules list - no separate tracking needed
|
|
1047
|
+
|
|
516
1048
|
spinner.succeed(
|
|
517
1049
|
`Manifests generated: ${manifestStats.workflows} workflows, ${manifestStats.agents} agents, ${manifestStats.tasks} tasks, ${manifestStats.tools} tools, ${manifestStats.files} files`,
|
|
518
1050
|
);
|
|
@@ -552,7 +1084,7 @@ class Installer {
|
|
|
552
1084
|
|
|
553
1085
|
// Pass pre-collected configuration to avoid re-prompting
|
|
554
1086
|
await this.ideManager.setup(ide, projectDir, bmadDir, {
|
|
555
|
-
selectedModules:
|
|
1087
|
+
selectedModules: allModules || [],
|
|
556
1088
|
preCollectedConfig: ideConfigurations[ide] || null,
|
|
557
1089
|
verbose: config.verbose,
|
|
558
1090
|
});
|
|
@@ -572,24 +1104,24 @@ class Installer {
|
|
|
572
1104
|
console.log = originalLog;
|
|
573
1105
|
|
|
574
1106
|
if (spinner.isSpinning) {
|
|
575
|
-
spinner.succeed(`Configured ${validIdes.
|
|
1107
|
+
spinner.succeed(`Configured: ${validIdes.join(', ')}`);
|
|
576
1108
|
} else {
|
|
577
|
-
console.log(chalk.green(`✓ Configured ${validIdes.
|
|
1109
|
+
console.log(chalk.green(`✓ Configured: ${validIdes.join(', ')}`));
|
|
578
1110
|
}
|
|
579
1111
|
}
|
|
580
|
-
|
|
581
|
-
// Copy IDE-specific documentation (only for valid IDEs)
|
|
582
|
-
const validIdesForDocs = (config.ides || []).filter((ide) => ide && typeof ide === 'string');
|
|
583
|
-
if (validIdesForDocs.length > 0) {
|
|
584
|
-
spinner.start('Copying IDE documentation...');
|
|
585
|
-
await this.copyIdeDocumentation(validIdesForDocs, bmadDir);
|
|
586
|
-
spinner.succeed('IDE documentation copied');
|
|
587
|
-
}
|
|
588
1112
|
}
|
|
589
1113
|
|
|
590
1114
|
// Run module-specific installers after IDE setup
|
|
591
1115
|
spinner.start('Running module-specific installers...');
|
|
592
1116
|
|
|
1117
|
+
// Create a conditional logger based on verbose mode
|
|
1118
|
+
const verboseMode = process.env.BMAD_VERBOSE_INSTALL === 'true' || config.verbose;
|
|
1119
|
+
const moduleLogger = {
|
|
1120
|
+
log: (msg) => (verboseMode ? console.log(msg) : {}), // Only log in verbose mode
|
|
1121
|
+
error: (msg) => console.error(msg), // Always show errors
|
|
1122
|
+
warn: (msg) => console.warn(msg), // Always show warnings
|
|
1123
|
+
};
|
|
1124
|
+
|
|
593
1125
|
// Run core module installer if core was installed
|
|
594
1126
|
if (config.installCore || resolution.byModule.core) {
|
|
595
1127
|
spinner.text = 'Running core module installer...';
|
|
@@ -597,11 +1129,8 @@ class Installer {
|
|
|
597
1129
|
await this.moduleManager.runModuleInstaller('core', bmadDir, {
|
|
598
1130
|
installedIDEs: config.ides || [],
|
|
599
1131
|
moduleConfig: moduleConfigs.core || {},
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
error: (msg) => console.error(msg),
|
|
603
|
-
warn: (msg) => console.warn(msg),
|
|
604
|
-
},
|
|
1132
|
+
coreConfig: moduleConfigs.core || {},
|
|
1133
|
+
logger: moduleLogger,
|
|
605
1134
|
});
|
|
606
1135
|
}
|
|
607
1136
|
|
|
@@ -614,11 +1143,8 @@ class Installer {
|
|
|
614
1143
|
await this.moduleManager.runModuleInstaller(moduleName, bmadDir, {
|
|
615
1144
|
installedIDEs: config.ides || [],
|
|
616
1145
|
moduleConfig: moduleConfigs[moduleName] || {},
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
error: (msg) => console.error(msg),
|
|
620
|
-
warn: (msg) => console.warn(msg),
|
|
621
|
-
},
|
|
1146
|
+
coreConfig: moduleConfigs.core || {},
|
|
1147
|
+
logger: moduleLogger,
|
|
622
1148
|
});
|
|
623
1149
|
}
|
|
624
1150
|
}
|
|
@@ -685,21 +1211,16 @@ class Installer {
|
|
|
685
1211
|
// Report custom and modified files if any were found
|
|
686
1212
|
if (customFiles.length > 0) {
|
|
687
1213
|
console.log(chalk.cyan(`\n📁 Custom files preserved: ${customFiles.length}`));
|
|
688
|
-
console.log(chalk.dim('The following custom files were found and restored:\n'));
|
|
689
|
-
for (const file of customFiles) {
|
|
690
|
-
console.log(chalk.dim(` - ${path.relative(bmadDir, file)}`));
|
|
691
|
-
}
|
|
692
|
-
console.log('');
|
|
693
1214
|
}
|
|
694
1215
|
|
|
695
1216
|
if (modifiedFiles.length > 0) {
|
|
696
|
-
console.log(chalk.yellow(`\n⚠️
|
|
697
|
-
console.log(
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
console.log(chalk.dim('
|
|
1217
|
+
console.log(chalk.yellow(`\n⚠️ User modified files detected: ${modifiedFiles.length}`));
|
|
1218
|
+
console.log(
|
|
1219
|
+
chalk.dim(
|
|
1220
|
+
'\nThese user modified files have been updated with the new version, search the project for .bak files that had your customizations.',
|
|
1221
|
+
),
|
|
1222
|
+
);
|
|
1223
|
+
console.log(chalk.dim('Remove these .bak files it no longer needed\n'));
|
|
703
1224
|
}
|
|
704
1225
|
|
|
705
1226
|
// Display completion message
|
|
@@ -710,9 +1231,18 @@ class Installer {
|
|
|
710
1231
|
modules: config.modules,
|
|
711
1232
|
ides: config.ides,
|
|
712
1233
|
customFiles: customFiles.length > 0 ? customFiles : undefined,
|
|
1234
|
+
ttsInjectedFiles: this.enableAgentVibes && this.ttsInjectedFiles.length > 0 ? this.ttsInjectedFiles : undefined,
|
|
1235
|
+
agentVibesEnabled: this.enableAgentVibes || false,
|
|
713
1236
|
});
|
|
714
1237
|
|
|
715
|
-
return {
|
|
1238
|
+
return {
|
|
1239
|
+
success: true,
|
|
1240
|
+
path: bmadDir,
|
|
1241
|
+
modules: config.modules,
|
|
1242
|
+
ides: config.ides,
|
|
1243
|
+
needsAgentVibes: this.enableAgentVibes && !config.agentVibesInstalled,
|
|
1244
|
+
projectDir: projectDir,
|
|
1245
|
+
};
|
|
716
1246
|
} catch (error) {
|
|
717
1247
|
spinner.fail('Installation failed');
|
|
718
1248
|
throw error;
|
|
@@ -726,7 +1256,8 @@ class Installer {
|
|
|
726
1256
|
const spinner = ora('Checking installation...').start();
|
|
727
1257
|
|
|
728
1258
|
try {
|
|
729
|
-
const
|
|
1259
|
+
const projectDir = path.resolve(config.directory);
|
|
1260
|
+
const { bmadDir } = await this.findBmadDir(projectDir);
|
|
730
1261
|
const existingInstall = await this.detector.detect(bmadDir);
|
|
731
1262
|
|
|
732
1263
|
if (!existingInstall.installed) {
|
|
@@ -740,6 +1271,62 @@ class Installer {
|
|
|
740
1271
|
const currentVersion = existingInstall.version;
|
|
741
1272
|
const newVersion = require(path.join(getProjectRoot(), 'package.json')).version;
|
|
742
1273
|
|
|
1274
|
+
// Check for custom modules with missing sources before update
|
|
1275
|
+
const customModuleSources = new Map();
|
|
1276
|
+
|
|
1277
|
+
// Check manifest for backward compatibility
|
|
1278
|
+
if (existingInstall.customModules) {
|
|
1279
|
+
for (const customModule of existingInstall.customModules) {
|
|
1280
|
+
customModuleSources.set(customModule.id, customModule);
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
// Also check cache directory
|
|
1285
|
+
const cacheDir = path.join(bmadDir, '_config', 'custom');
|
|
1286
|
+
if (await fs.pathExists(cacheDir)) {
|
|
1287
|
+
const cachedModules = await fs.readdir(cacheDir, { withFileTypes: true });
|
|
1288
|
+
|
|
1289
|
+
for (const cachedModule of cachedModules) {
|
|
1290
|
+
if (cachedModule.isDirectory()) {
|
|
1291
|
+
const moduleId = cachedModule.name;
|
|
1292
|
+
|
|
1293
|
+
// Skip if we already have this module
|
|
1294
|
+
if (customModuleSources.has(moduleId)) {
|
|
1295
|
+
continue;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
const cachedPath = path.join(cacheDir, moduleId);
|
|
1299
|
+
|
|
1300
|
+
// Check if this is actually a custom module (has module.yaml)
|
|
1301
|
+
const moduleYamlPath = path.join(cachedPath, 'module.yaml');
|
|
1302
|
+
if (await fs.pathExists(moduleYamlPath)) {
|
|
1303
|
+
customModuleSources.set(moduleId, {
|
|
1304
|
+
id: moduleId,
|
|
1305
|
+
name: moduleId,
|
|
1306
|
+
sourcePath: path.join('_config', 'custom', moduleId), // Relative path
|
|
1307
|
+
cached: true,
|
|
1308
|
+
});
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
if (customModuleSources.size > 0) {
|
|
1315
|
+
spinner.stop();
|
|
1316
|
+
console.log(chalk.yellow('\nChecking custom module sources before update...'));
|
|
1317
|
+
|
|
1318
|
+
const projectRoot = getProjectRoot();
|
|
1319
|
+
await this.handleMissingCustomSources(
|
|
1320
|
+
customModuleSources,
|
|
1321
|
+
bmadDir,
|
|
1322
|
+
projectRoot,
|
|
1323
|
+
'update',
|
|
1324
|
+
existingInstall.modules.map((m) => m.id),
|
|
1325
|
+
);
|
|
1326
|
+
|
|
1327
|
+
spinner.start('Preparing update...');
|
|
1328
|
+
}
|
|
1329
|
+
|
|
743
1330
|
if (config.dryRun) {
|
|
744
1331
|
spinner.stop();
|
|
745
1332
|
console.log(chalk.cyan('\n🔍 Update Preview (Dry Run)\n'));
|
|
@@ -786,7 +1373,8 @@ class Installer {
|
|
|
786
1373
|
* Get installation status
|
|
787
1374
|
*/
|
|
788
1375
|
async getStatus(directory) {
|
|
789
|
-
const
|
|
1376
|
+
const projectDir = path.resolve(directory);
|
|
1377
|
+
const { bmadDir } = await this.findBmadDir(projectDir);
|
|
790
1378
|
return await this.detector.detect(bmadDir);
|
|
791
1379
|
}
|
|
792
1380
|
|
|
@@ -801,14 +1389,15 @@ class Installer {
|
|
|
801
1389
|
* Uninstall BMAD
|
|
802
1390
|
*/
|
|
803
1391
|
async uninstall(directory) {
|
|
804
|
-
const
|
|
1392
|
+
const projectDir = path.resolve(directory);
|
|
1393
|
+
const { bmadDir } = await this.findBmadDir(projectDir);
|
|
805
1394
|
|
|
806
1395
|
if (await fs.pathExists(bmadDir)) {
|
|
807
1396
|
await fs.remove(bmadDir);
|
|
808
1397
|
}
|
|
809
1398
|
|
|
810
1399
|
// Clean up IDE configurations
|
|
811
|
-
await this.ideManager.cleanup(
|
|
1400
|
+
await this.ideManager.cleanup(projectDir);
|
|
812
1401
|
|
|
813
1402
|
return { success: true };
|
|
814
1403
|
}
|
|
@@ -818,8 +1407,9 @@ class Installer {
|
|
|
818
1407
|
*/
|
|
819
1408
|
async createDirectoryStructure(bmadDir) {
|
|
820
1409
|
await fs.ensureDir(bmadDir);
|
|
821
|
-
await fs.ensureDir(path.join(bmadDir, '
|
|
822
|
-
await fs.ensureDir(path.join(bmadDir, '
|
|
1410
|
+
await fs.ensureDir(path.join(bmadDir, '_config'));
|
|
1411
|
+
await fs.ensureDir(path.join(bmadDir, '_config', 'agents'));
|
|
1412
|
+
await fs.ensureDir(path.join(bmadDir, '_config', 'custom'));
|
|
823
1413
|
}
|
|
824
1414
|
|
|
825
1415
|
/**
|
|
@@ -828,7 +1418,7 @@ class Installer {
|
|
|
828
1418
|
* @param {Object} moduleConfigs - Collected configuration values
|
|
829
1419
|
*/
|
|
830
1420
|
async generateModuleConfigs(bmadDir, moduleConfigs) {
|
|
831
|
-
const yaml = require('
|
|
1421
|
+
const yaml = require('yaml');
|
|
832
1422
|
|
|
833
1423
|
// Extract core config values to share with other modules
|
|
834
1424
|
const coreConfig = moduleConfigs.core || {};
|
|
@@ -836,7 +1426,7 @@ class Installer {
|
|
|
836
1426
|
// Get all installed module directories
|
|
837
1427
|
const entries = await fs.readdir(bmadDir, { withFileTypes: true });
|
|
838
1428
|
const installedModules = entries
|
|
839
|
-
.filter((entry) => entry.isDirectory() && entry.name !== '
|
|
1429
|
+
.filter((entry) => entry.isDirectory() && entry.name !== '_config' && entry.name !== 'docs')
|
|
840
1430
|
.map((entry) => entry.name);
|
|
841
1431
|
|
|
842
1432
|
// Generate config.yaml for each installed module
|
|
@@ -874,12 +1464,14 @@ class Installer {
|
|
|
874
1464
|
coreSection = '\n# Core Configuration Values\n';
|
|
875
1465
|
}
|
|
876
1466
|
|
|
1467
|
+
// Clean the config to remove any non-serializable values (like functions)
|
|
1468
|
+
const cleanConfig = structuredClone(finalConfig);
|
|
1469
|
+
|
|
877
1470
|
// Convert config to YAML
|
|
878
|
-
let yamlContent = yaml.
|
|
1471
|
+
let yamlContent = yaml.stringify(cleanConfig, {
|
|
879
1472
|
indent: 2,
|
|
880
|
-
lineWidth:
|
|
881
|
-
|
|
882
|
-
sortKeys: false,
|
|
1473
|
+
lineWidth: 0,
|
|
1474
|
+
minContentWidth: 0,
|
|
883
1475
|
});
|
|
884
1476
|
|
|
885
1477
|
// If we have core values, reorganize the YAML to group them with their comment
|
|
@@ -906,11 +1498,12 @@ class Installer {
|
|
|
906
1498
|
}
|
|
907
1499
|
}
|
|
908
1500
|
|
|
909
|
-
// Write the clean config file
|
|
910
|
-
|
|
1501
|
+
// Write the clean config file with POSIX-compliant final newline
|
|
1502
|
+
const content = header + yamlContent;
|
|
1503
|
+
await fs.writeFile(configPath, content.endsWith('\n') ? content : content + '\n', 'utf8');
|
|
911
1504
|
|
|
912
1505
|
// Track the config file in installedFiles
|
|
913
|
-
this.installedFiles.
|
|
1506
|
+
this.installedFiles.add(configPath);
|
|
914
1507
|
}
|
|
915
1508
|
}
|
|
916
1509
|
}
|
|
@@ -923,14 +1516,7 @@ class Installer {
|
|
|
923
1516
|
async installCoreWithDependencies(bmadDir, coreFiles) {
|
|
924
1517
|
const sourcePath = getModulePath('core');
|
|
925
1518
|
const targetPath = path.join(bmadDir, 'core');
|
|
926
|
-
|
|
927
|
-
// Install full core
|
|
928
1519
|
await this.installCore(bmadDir);
|
|
929
|
-
|
|
930
|
-
// If there are specific dependency files, ensure they're included
|
|
931
|
-
if (coreFiles) {
|
|
932
|
-
// Already handled by installCore for core module
|
|
933
|
-
}
|
|
934
1520
|
}
|
|
935
1521
|
|
|
936
1522
|
/**
|
|
@@ -949,11 +1535,12 @@ class Installer {
|
|
|
949
1535
|
moduleName,
|
|
950
1536
|
bmadDir,
|
|
951
1537
|
(filePath) => {
|
|
952
|
-
this.installedFiles.
|
|
1538
|
+
this.installedFiles.add(filePath);
|
|
953
1539
|
},
|
|
954
1540
|
{
|
|
955
1541
|
skipModuleInstaller: true, // We'll run it later after IDE setup
|
|
956
1542
|
moduleConfig: moduleConfig, // Pass module config for conditional filtering
|
|
1543
|
+
installer: this,
|
|
957
1544
|
},
|
|
958
1545
|
);
|
|
959
1546
|
|
|
@@ -985,8 +1572,8 @@ class Installer {
|
|
|
985
1572
|
const targetPath = path.join(agentsDir, fileName);
|
|
986
1573
|
|
|
987
1574
|
if (await fs.pathExists(sourcePath)) {
|
|
988
|
-
await
|
|
989
|
-
this.installedFiles.
|
|
1575
|
+
await this.copyFileWithPlaceholderReplacement(sourcePath, targetPath);
|
|
1576
|
+
this.installedFiles.add(targetPath);
|
|
990
1577
|
}
|
|
991
1578
|
}
|
|
992
1579
|
}
|
|
@@ -1001,8 +1588,8 @@ class Installer {
|
|
|
1001
1588
|
const targetPath = path.join(tasksDir, fileName);
|
|
1002
1589
|
|
|
1003
1590
|
if (await fs.pathExists(sourcePath)) {
|
|
1004
|
-
await
|
|
1005
|
-
this.installedFiles.
|
|
1591
|
+
await this.copyFileWithPlaceholderReplacement(sourcePath, targetPath);
|
|
1592
|
+
this.installedFiles.add(targetPath);
|
|
1006
1593
|
}
|
|
1007
1594
|
}
|
|
1008
1595
|
}
|
|
@@ -1017,8 +1604,8 @@ class Installer {
|
|
|
1017
1604
|
const targetPath = path.join(toolsDir, fileName);
|
|
1018
1605
|
|
|
1019
1606
|
if (await fs.pathExists(sourcePath)) {
|
|
1020
|
-
await
|
|
1021
|
-
this.installedFiles.
|
|
1607
|
+
await this.copyFileWithPlaceholderReplacement(sourcePath, targetPath);
|
|
1608
|
+
this.installedFiles.add(targetPath);
|
|
1022
1609
|
}
|
|
1023
1610
|
}
|
|
1024
1611
|
}
|
|
@@ -1033,8 +1620,8 @@ class Installer {
|
|
|
1033
1620
|
const targetPath = path.join(templatesDir, fileName);
|
|
1034
1621
|
|
|
1035
1622
|
if (await fs.pathExists(sourcePath)) {
|
|
1036
|
-
await
|
|
1037
|
-
this.installedFiles.
|
|
1623
|
+
await this.copyFileWithPlaceholderReplacement(sourcePath, targetPath);
|
|
1624
|
+
this.installedFiles.add(targetPath);
|
|
1038
1625
|
}
|
|
1039
1626
|
}
|
|
1040
1627
|
}
|
|
@@ -1048,8 +1635,8 @@ class Installer {
|
|
|
1048
1635
|
await fs.ensureDir(path.dirname(targetPath));
|
|
1049
1636
|
|
|
1050
1637
|
if (await fs.pathExists(dataPath)) {
|
|
1051
|
-
await
|
|
1052
|
-
this.installedFiles.
|
|
1638
|
+
await this.copyFileWithPlaceholderReplacement(dataPath, targetPath);
|
|
1639
|
+
this.installedFiles.add(targetPath);
|
|
1053
1640
|
}
|
|
1054
1641
|
}
|
|
1055
1642
|
}
|
|
@@ -1070,25 +1657,55 @@ class Installer {
|
|
|
1070
1657
|
const sourcePath = getModulePath('core');
|
|
1071
1658
|
const targetPath = path.join(bmadDir, 'core');
|
|
1072
1659
|
|
|
1073
|
-
// Copy core files
|
|
1074
|
-
await this.
|
|
1660
|
+
// Copy core files (skip .agent.yaml files like modules do)
|
|
1661
|
+
await this.copyCoreFiles(sourcePath, targetPath);
|
|
1662
|
+
|
|
1663
|
+
// Compile agents using the same compiler as modules
|
|
1664
|
+
const { ModuleManager } = require('../modules/manager');
|
|
1665
|
+
const moduleManager = new ModuleManager();
|
|
1666
|
+
await moduleManager.compileModuleAgents(sourcePath, targetPath, 'core', bmadDir, this);
|
|
1075
1667
|
|
|
1076
1668
|
// Process agent files to inject activation block
|
|
1077
1669
|
await this.processAgentFiles(targetPath, 'core');
|
|
1078
1670
|
}
|
|
1079
1671
|
|
|
1080
1672
|
/**
|
|
1081
|
-
* Copy
|
|
1082
|
-
* @param {string} sourcePath - Source
|
|
1083
|
-
* @param {string} targetPath - Target
|
|
1673
|
+
* Copy core files (similar to copyModuleWithFiltering but for core)
|
|
1674
|
+
* @param {string} sourcePath - Source path
|
|
1675
|
+
* @param {string} targetPath - Target path
|
|
1084
1676
|
*/
|
|
1085
|
-
async
|
|
1086
|
-
// Get all files in source
|
|
1677
|
+
async copyCoreFiles(sourcePath, targetPath) {
|
|
1678
|
+
// Get all files in source
|
|
1087
1679
|
const files = await this.getFileList(sourcePath);
|
|
1088
1680
|
|
|
1089
1681
|
for (const file of files) {
|
|
1682
|
+
// Skip sub-modules directory - these are IDE-specific and handled separately
|
|
1683
|
+
if (file.startsWith('sub-modules/')) {
|
|
1684
|
+
continue;
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
// Skip sidecar directories - they are handled separately during agent compilation
|
|
1688
|
+
if (
|
|
1689
|
+
path
|
|
1690
|
+
.dirname(file)
|
|
1691
|
+
.split('/')
|
|
1692
|
+
.some((dir) => dir.toLowerCase().includes('sidecar'))
|
|
1693
|
+
) {
|
|
1694
|
+
continue;
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
// Skip _module-installer directory - it's only needed at install time
|
|
1698
|
+
if (file.startsWith('_module-installer/') || file === 'module.yaml') {
|
|
1699
|
+
continue;
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1090
1702
|
// Skip config.yaml templates - we'll generate clean ones with actual values
|
|
1091
|
-
if (file === 'config.yaml' || file.endsWith('/config.yaml')) {
|
|
1703
|
+
if (file === 'config.yaml' || file.endsWith('/config.yaml') || file === 'custom.yaml' || file.endsWith('/custom.yaml')) {
|
|
1704
|
+
continue;
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
// Skip .agent.yaml files - they will be compiled separately
|
|
1708
|
+
if (file.endsWith('.agent.yaml')) {
|
|
1092
1709
|
continue;
|
|
1093
1710
|
}
|
|
1094
1711
|
|
|
@@ -1096,7 +1713,7 @@ class Installer {
|
|
|
1096
1713
|
const targetFile = path.join(targetPath, file);
|
|
1097
1714
|
|
|
1098
1715
|
// Check if this is an agent file
|
|
1099
|
-
if (file.
|
|
1716
|
+
if (file.startsWith('agents/') && file.endsWith('.md')) {
|
|
1100
1717
|
// Read the file to check for localskip
|
|
1101
1718
|
const content = await fs.readFile(sourceFile, 'utf8');
|
|
1102
1719
|
|
|
@@ -1108,12 +1725,12 @@ class Installer {
|
|
|
1108
1725
|
}
|
|
1109
1726
|
}
|
|
1110
1727
|
|
|
1111
|
-
// Copy the file
|
|
1728
|
+
// Copy the file with placeholder replacement
|
|
1112
1729
|
await fs.ensureDir(path.dirname(targetFile));
|
|
1113
|
-
await
|
|
1730
|
+
await this.copyFileWithPlaceholderReplacement(sourceFile, targetFile);
|
|
1114
1731
|
|
|
1115
1732
|
// Track the installed file
|
|
1116
|
-
this.installedFiles.
|
|
1733
|
+
this.installedFiles.add(targetFile);
|
|
1117
1734
|
}
|
|
1118
1735
|
}
|
|
1119
1736
|
|
|
@@ -1160,363 +1777,45 @@ class Installer {
|
|
|
1160
1777
|
|
|
1161
1778
|
// Determine project directory (parent of bmad/ directory)
|
|
1162
1779
|
const bmadDir = path.dirname(modulePath);
|
|
1163
|
-
const
|
|
1164
|
-
const cfgAgentsDir = path.join(bmadDir, '_cfg', 'agents');
|
|
1780
|
+
const cfgAgentsDir = path.join(bmadDir, '_config', 'agents');
|
|
1165
1781
|
|
|
1166
|
-
// Ensure
|
|
1782
|
+
// Ensure _config/agents directory exists
|
|
1167
1783
|
await fs.ensureDir(cfgAgentsDir);
|
|
1168
1784
|
|
|
1169
1785
|
// Get all agent files
|
|
1170
1786
|
const agentFiles = await fs.readdir(agentsPath);
|
|
1171
1787
|
|
|
1172
1788
|
for (const agentFile of agentFiles) {
|
|
1173
|
-
//
|
|
1789
|
+
// Skip .agent.yaml files - they should already be compiled by compileModuleAgents
|
|
1174
1790
|
if (agentFile.endsWith('.agent.yaml')) {
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
const mdPath = path.join(agentsPath, `${agentName}.md`);
|
|
1178
|
-
const customizePath = path.join(cfgAgentsDir, `${moduleName}-${agentName}.customize.yaml`);
|
|
1179
|
-
|
|
1180
|
-
// Create customize template if it doesn't exist
|
|
1181
|
-
if (!(await fs.pathExists(customizePath))) {
|
|
1182
|
-
const genericTemplatePath = getSourcePath('utility', 'templates', 'agent.customize.template.yaml');
|
|
1183
|
-
if (await fs.pathExists(genericTemplatePath)) {
|
|
1184
|
-
await fs.copy(genericTemplatePath, customizePath);
|
|
1185
|
-
console.log(chalk.dim(` Created customize: ${moduleName}-${agentName}.customize.yaml`));
|
|
1186
|
-
}
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
|
-
// Build YAML + customize to .md
|
|
1190
|
-
const customizeExists = await fs.pathExists(customizePath);
|
|
1191
|
-
const xmlContent = await this.xmlHandler.buildFromYaml(yamlPath, customizeExists ? customizePath : null, {
|
|
1192
|
-
includeMetadata: true,
|
|
1193
|
-
});
|
|
1194
|
-
|
|
1195
|
-
// DO NOT replace {project-root} - LLMs understand this placeholder at runtime
|
|
1196
|
-
// const processedContent = xmlContent.replaceAll('{project-root}', projectDir);
|
|
1197
|
-
|
|
1198
|
-
// Write the built .md file to bmad/{module}/agents/
|
|
1199
|
-
await fs.writeFile(mdPath, xmlContent, 'utf8');
|
|
1200
|
-
this.installedFiles.push(mdPath);
|
|
1201
|
-
|
|
1202
|
-
// Remove the source YAML file - we can regenerate from installer source if needed
|
|
1203
|
-
await fs.remove(yamlPath);
|
|
1791
|
+
continue;
|
|
1792
|
+
}
|
|
1204
1793
|
|
|
1205
|
-
|
|
1794
|
+
// Only process .md files (already compiled from YAML)
|
|
1795
|
+
if (!agentFile.endsWith('.md')) {
|
|
1796
|
+
continue;
|
|
1206
1797
|
}
|
|
1207
|
-
// Handle legacy .md agents - inject activation if needed
|
|
1208
|
-
else if (agentFile.endsWith('.md')) {
|
|
1209
|
-
const agentPath = path.join(agentsPath, agentFile);
|
|
1210
|
-
let content = await fs.readFile(agentPath, 'utf8');
|
|
1211
1798
|
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1799
|
+
const agentName = agentFile.replace('.md', '');
|
|
1800
|
+
const mdPath = path.join(agentsPath, agentFile);
|
|
1801
|
+
const customizePath = path.join(cfgAgentsDir, `${moduleName}-${agentName}.customize.yaml`);
|
|
1802
|
+
|
|
1803
|
+
// For .md files that are already compiled, we don't need to do much
|
|
1804
|
+
// Just ensure the customize template exists
|
|
1805
|
+
if (!(await fs.pathExists(customizePath))) {
|
|
1806
|
+
const genericTemplatePath = getSourcePath('utility', 'agent-components', 'agent.customize.template.yaml');
|
|
1807
|
+
if (await fs.pathExists(genericTemplatePath)) {
|
|
1808
|
+
await this.copyFileWithPlaceholderReplacement(genericTemplatePath, customizePath);
|
|
1809
|
+
if (process.env.BMAD_VERBOSE_INSTALL === 'true') {
|
|
1810
|
+
console.log(chalk.dim(` Created customize: ${moduleName}-${agentName}.customize.yaml`));
|
|
1811
|
+
}
|
|
1217
1812
|
}
|
|
1218
1813
|
}
|
|
1219
1814
|
}
|
|
1220
1815
|
}
|
|
1221
1816
|
|
|
1222
1817
|
/**
|
|
1223
|
-
*
|
|
1224
|
-
* @param {string} bmadDir - Path to bmad directory
|
|
1225
|
-
* @param {string} projectDir - Path to project directory
|
|
1226
|
-
*/
|
|
1227
|
-
async buildStandaloneAgents(bmadDir, projectDir) {
|
|
1228
|
-
const standaloneAgentsPath = path.join(bmadDir, 'agents');
|
|
1229
|
-
const cfgAgentsDir = path.join(bmadDir, '_cfg', 'agents');
|
|
1230
|
-
|
|
1231
|
-
// Check if standalone agents directory exists
|
|
1232
|
-
if (!(await fs.pathExists(standaloneAgentsPath))) {
|
|
1233
|
-
return;
|
|
1234
|
-
}
|
|
1235
|
-
|
|
1236
|
-
// Get all subdirectories in agents/
|
|
1237
|
-
const agentDirs = await fs.readdir(standaloneAgentsPath, { withFileTypes: true });
|
|
1238
|
-
|
|
1239
|
-
for (const agentDir of agentDirs) {
|
|
1240
|
-
if (!agentDir.isDirectory()) continue;
|
|
1241
|
-
|
|
1242
|
-
const agentDirPath = path.join(standaloneAgentsPath, agentDir.name);
|
|
1243
|
-
|
|
1244
|
-
// Find any .agent.yaml file in the directory
|
|
1245
|
-
const files = await fs.readdir(agentDirPath);
|
|
1246
|
-
const yamlFile = files.find((f) => f.endsWith('.agent.yaml'));
|
|
1247
|
-
|
|
1248
|
-
if (!yamlFile) continue;
|
|
1249
|
-
|
|
1250
|
-
const agentName = path.basename(yamlFile, '.agent.yaml');
|
|
1251
|
-
const sourceYamlPath = path.join(agentDirPath, yamlFile);
|
|
1252
|
-
const targetMdPath = path.join(agentDirPath, `${agentName}.md`);
|
|
1253
|
-
const customizePath = path.join(cfgAgentsDir, `${agentName}.customize.yaml`);
|
|
1254
|
-
|
|
1255
|
-
// Check for customizations
|
|
1256
|
-
const customizeExists = await fs.pathExists(customizePath);
|
|
1257
|
-
let customizedFields = [];
|
|
1258
|
-
|
|
1259
|
-
if (customizeExists) {
|
|
1260
|
-
const customizeContent = await fs.readFile(customizePath, 'utf8');
|
|
1261
|
-
const yaml = require('js-yaml');
|
|
1262
|
-
const customizeYaml = yaml.load(customizeContent);
|
|
1263
|
-
|
|
1264
|
-
// Detect what fields are customized (similar to rebuildAgentFiles)
|
|
1265
|
-
if (customizeYaml) {
|
|
1266
|
-
if (customizeYaml.persona) {
|
|
1267
|
-
for (const [key, value] of Object.entries(customizeYaml.persona)) {
|
|
1268
|
-
if (value !== '' && value !== null && !(Array.isArray(value) && value.length === 0)) {
|
|
1269
|
-
customizedFields.push(`persona.${key}`);
|
|
1270
|
-
}
|
|
1271
|
-
}
|
|
1272
|
-
}
|
|
1273
|
-
if (customizeYaml.agent?.metadata) {
|
|
1274
|
-
for (const [key, value] of Object.entries(customizeYaml.agent.metadata)) {
|
|
1275
|
-
if (value !== '' && value !== null) {
|
|
1276
|
-
customizedFields.push(`metadata.${key}`);
|
|
1277
|
-
}
|
|
1278
|
-
}
|
|
1279
|
-
}
|
|
1280
|
-
if (customizeYaml.critical_actions && customizeYaml.critical_actions.length > 0) {
|
|
1281
|
-
customizedFields.push('critical_actions');
|
|
1282
|
-
}
|
|
1283
|
-
if (customizeYaml.menu && customizeYaml.menu.length > 0) {
|
|
1284
|
-
customizedFields.push('menu');
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
// Build YAML to XML .md
|
|
1290
|
-
const xmlContent = await this.xmlHandler.buildFromYaml(sourceYamlPath, customizeExists ? customizePath : null, {
|
|
1291
|
-
includeMetadata: true,
|
|
1292
|
-
});
|
|
1293
|
-
|
|
1294
|
-
// DO NOT replace {project-root} - LLMs understand this placeholder at runtime
|
|
1295
|
-
// const processedContent = xmlContent.replaceAll('{project-root}', projectDir);
|
|
1296
|
-
|
|
1297
|
-
// Write the built .md file
|
|
1298
|
-
await fs.writeFile(targetMdPath, xmlContent, 'utf8');
|
|
1299
|
-
|
|
1300
|
-
// Display result
|
|
1301
|
-
if (customizedFields.length > 0) {
|
|
1302
|
-
console.log(chalk.dim(` Built standalone agent: ${agentName}.md `) + chalk.yellow(`(customized: ${customizedFields.join(', ')})`));
|
|
1303
|
-
} else {
|
|
1304
|
-
console.log(chalk.dim(` Built standalone agent: ${agentName}.md`));
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
|
|
1309
|
-
/**
|
|
1310
|
-
* Rebuild agent files from installer source (for compile command)
|
|
1311
|
-
* @param {string} modulePath - Path to module in bmad/ installation
|
|
1312
|
-
* @param {string} moduleName - Module name
|
|
1313
|
-
*/
|
|
1314
|
-
async rebuildAgentFiles(modulePath, moduleName) {
|
|
1315
|
-
// Get source agents directory from installer
|
|
1316
|
-
const sourceAgentsPath =
|
|
1317
|
-
moduleName === 'core' ? path.join(getModulePath('core'), 'agents') : path.join(getSourcePath(`modules/${moduleName}`), 'agents');
|
|
1318
|
-
|
|
1319
|
-
if (!(await fs.pathExists(sourceAgentsPath))) {
|
|
1320
|
-
return; // No source agents to rebuild
|
|
1321
|
-
}
|
|
1322
|
-
|
|
1323
|
-
// Determine project directory (parent of bmad/ directory)
|
|
1324
|
-
const bmadDir = path.dirname(modulePath);
|
|
1325
|
-
const projectDir = path.dirname(bmadDir);
|
|
1326
|
-
const cfgAgentsDir = path.join(bmadDir, '_cfg', 'agents');
|
|
1327
|
-
const targetAgentsPath = path.join(modulePath, 'agents');
|
|
1328
|
-
|
|
1329
|
-
// Ensure target directory exists
|
|
1330
|
-
await fs.ensureDir(targetAgentsPath);
|
|
1331
|
-
|
|
1332
|
-
// Get all YAML agent files from source
|
|
1333
|
-
const sourceFiles = await fs.readdir(sourceAgentsPath);
|
|
1334
|
-
|
|
1335
|
-
for (const file of sourceFiles) {
|
|
1336
|
-
if (file.endsWith('.agent.yaml')) {
|
|
1337
|
-
const agentName = file.replace('.agent.yaml', '');
|
|
1338
|
-
const sourceYamlPath = path.join(sourceAgentsPath, file);
|
|
1339
|
-
const targetMdPath = path.join(targetAgentsPath, `${agentName}.md`);
|
|
1340
|
-
const customizePath = path.join(cfgAgentsDir, `${moduleName}-${agentName}.customize.yaml`);
|
|
1341
|
-
|
|
1342
|
-
// Check for customizations
|
|
1343
|
-
const customizeExists = await fs.pathExists(customizePath);
|
|
1344
|
-
let customizedFields = [];
|
|
1345
|
-
|
|
1346
|
-
if (customizeExists) {
|
|
1347
|
-
const customizeContent = await fs.readFile(customizePath, 'utf8');
|
|
1348
|
-
const yaml = require('js-yaml');
|
|
1349
|
-
const customizeYaml = yaml.load(customizeContent);
|
|
1350
|
-
|
|
1351
|
-
// Detect what fields are customized
|
|
1352
|
-
if (customizeYaml) {
|
|
1353
|
-
if (customizeYaml.persona) {
|
|
1354
|
-
for (const [key, value] of Object.entries(customizeYaml.persona)) {
|
|
1355
|
-
if (value !== '' && value !== null && !(Array.isArray(value) && value.length === 0)) {
|
|
1356
|
-
customizedFields.push(`persona.${key}`);
|
|
1357
|
-
}
|
|
1358
|
-
}
|
|
1359
|
-
}
|
|
1360
|
-
if (customizeYaml.agent?.metadata) {
|
|
1361
|
-
for (const [key, value] of Object.entries(customizeYaml.agent.metadata)) {
|
|
1362
|
-
if (value !== '' && value !== null) {
|
|
1363
|
-
customizedFields.push(`metadata.${key}`);
|
|
1364
|
-
}
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1367
|
-
if (customizeYaml.critical_actions && customizeYaml.critical_actions.length > 0) {
|
|
1368
|
-
customizedFields.push('critical_actions');
|
|
1369
|
-
}
|
|
1370
|
-
if (customizeYaml.memories && customizeYaml.memories.length > 0) {
|
|
1371
|
-
customizedFields.push('memories');
|
|
1372
|
-
}
|
|
1373
|
-
if (customizeYaml.menu && customizeYaml.menu.length > 0) {
|
|
1374
|
-
customizedFields.push('menu');
|
|
1375
|
-
}
|
|
1376
|
-
if (customizeYaml.prompts && customizeYaml.prompts.length > 0) {
|
|
1377
|
-
customizedFields.push('prompts');
|
|
1378
|
-
}
|
|
1379
|
-
}
|
|
1380
|
-
}
|
|
1381
|
-
|
|
1382
|
-
// Build YAML + customize to .md
|
|
1383
|
-
const xmlContent = await this.xmlHandler.buildFromYaml(sourceYamlPath, customizeExists ? customizePath : null, {
|
|
1384
|
-
includeMetadata: true,
|
|
1385
|
-
});
|
|
1386
|
-
|
|
1387
|
-
// DO NOT replace {project-root} - LLMs understand this placeholder at runtime
|
|
1388
|
-
// const processedContent = xmlContent.replaceAll('{project-root}', projectDir);
|
|
1389
|
-
|
|
1390
|
-
// Write the rebuilt .md file
|
|
1391
|
-
await fs.writeFile(targetMdPath, xmlContent, 'utf8');
|
|
1392
|
-
|
|
1393
|
-
// Display result with customizations if any
|
|
1394
|
-
if (customizedFields.length > 0) {
|
|
1395
|
-
console.log(chalk.dim(` Rebuilt agent: ${agentName}.md `) + chalk.yellow(`(customized: ${customizedFields.join(', ')})`));
|
|
1396
|
-
} else {
|
|
1397
|
-
console.log(chalk.dim(` Rebuilt agent: ${agentName}.md`));
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
|
|
1403
|
-
/**
|
|
1404
|
-
* Compile/rebuild all agents and tasks for quick updates
|
|
1405
|
-
* @param {Object} config - Compilation configuration
|
|
1406
|
-
* @returns {Object} Compilation results
|
|
1407
|
-
*/
|
|
1408
|
-
async compileAgents(config) {
|
|
1409
|
-
const ora = require('ora');
|
|
1410
|
-
const spinner = ora('Starting agent compilation...').start();
|
|
1411
|
-
|
|
1412
|
-
try {
|
|
1413
|
-
const projectDir = path.resolve(config.directory);
|
|
1414
|
-
const bmadDir = path.join(projectDir, 'bmad');
|
|
1415
|
-
|
|
1416
|
-
// Check if bmad directory exists
|
|
1417
|
-
if (!(await fs.pathExists(bmadDir))) {
|
|
1418
|
-
spinner.fail('No BMAD installation found');
|
|
1419
|
-
throw new Error(`BMAD not installed at ${bmadDir}`);
|
|
1420
|
-
}
|
|
1421
|
-
|
|
1422
|
-
let agentCount = 0;
|
|
1423
|
-
let taskCount = 0;
|
|
1424
|
-
|
|
1425
|
-
// Process all modules in bmad directory
|
|
1426
|
-
spinner.text = 'Rebuilding agent files...';
|
|
1427
|
-
const entries = await fs.readdir(bmadDir, { withFileTypes: true });
|
|
1428
|
-
|
|
1429
|
-
for (const entry of entries) {
|
|
1430
|
-
if (entry.isDirectory() && entry.name !== '_cfg' && entry.name !== 'docs') {
|
|
1431
|
-
const modulePath = path.join(bmadDir, entry.name);
|
|
1432
|
-
|
|
1433
|
-
// Special handling for standalone agents in bmad/agents/ directory
|
|
1434
|
-
if (entry.name === 'agents') {
|
|
1435
|
-
spinner.text = 'Building standalone agents...';
|
|
1436
|
-
await this.buildStandaloneAgents(bmadDir, projectDir);
|
|
1437
|
-
|
|
1438
|
-
// Count standalone agents
|
|
1439
|
-
const standaloneAgentsPath = path.join(bmadDir, 'agents');
|
|
1440
|
-
const standaloneAgentDirs = await fs.readdir(standaloneAgentsPath, { withFileTypes: true });
|
|
1441
|
-
for (const agentDir of standaloneAgentDirs) {
|
|
1442
|
-
if (agentDir.isDirectory()) {
|
|
1443
|
-
const agentDirPath = path.join(standaloneAgentsPath, agentDir.name);
|
|
1444
|
-
const agentFiles = await fs.readdir(agentDirPath);
|
|
1445
|
-
agentCount += agentFiles.filter((f) => f.endsWith('.md') && !f.endsWith('.agent.yaml')).length;
|
|
1446
|
-
}
|
|
1447
|
-
}
|
|
1448
|
-
} else {
|
|
1449
|
-
// Rebuild module agents from installer source
|
|
1450
|
-
const agentsPath = path.join(modulePath, 'agents');
|
|
1451
|
-
if (await fs.pathExists(agentsPath)) {
|
|
1452
|
-
await this.rebuildAgentFiles(modulePath, entry.name);
|
|
1453
|
-
const agentFiles = await fs.readdir(agentsPath);
|
|
1454
|
-
agentCount += agentFiles.filter((f) => f.endsWith('.md')).length;
|
|
1455
|
-
}
|
|
1456
|
-
|
|
1457
|
-
// Count tasks (already built)
|
|
1458
|
-
const tasksPath = path.join(modulePath, 'tasks');
|
|
1459
|
-
if (await fs.pathExists(tasksPath)) {
|
|
1460
|
-
const taskFiles = await fs.readdir(tasksPath);
|
|
1461
|
-
taskCount += taskFiles.filter((f) => f.endsWith('.md')).length;
|
|
1462
|
-
}
|
|
1463
|
-
}
|
|
1464
|
-
}
|
|
1465
|
-
}
|
|
1466
|
-
|
|
1467
|
-
// Regenerate manifests after compilation
|
|
1468
|
-
spinner.start('Regenerating manifests...');
|
|
1469
|
-
const installedModules = entries
|
|
1470
|
-
.filter((e) => e.isDirectory() && e.name !== '_cfg' && e.name !== 'docs' && e.name !== 'agents' && e.name !== 'core')
|
|
1471
|
-
.map((e) => e.name);
|
|
1472
|
-
const manifestGen = new ManifestGenerator();
|
|
1473
|
-
|
|
1474
|
-
// Get existing IDE list from manifest
|
|
1475
|
-
const existingManifestPath = path.join(bmadDir, '_cfg', 'manifest.yaml');
|
|
1476
|
-
let existingIdes = [];
|
|
1477
|
-
if (await fs.pathExists(existingManifestPath)) {
|
|
1478
|
-
const manifestContent = await fs.readFile(existingManifestPath, 'utf8');
|
|
1479
|
-
const yaml = require('js-yaml');
|
|
1480
|
-
const manifest = yaml.load(manifestContent);
|
|
1481
|
-
existingIdes = manifest.ides || [];
|
|
1482
|
-
}
|
|
1483
|
-
|
|
1484
|
-
await manifestGen.generateManifests(bmadDir, installedModules, [], {
|
|
1485
|
-
ides: existingIdes,
|
|
1486
|
-
});
|
|
1487
|
-
spinner.succeed('Manifests regenerated');
|
|
1488
|
-
|
|
1489
|
-
// Ask for IDE to update
|
|
1490
|
-
spinner.stop();
|
|
1491
|
-
// Note: UI lives in tools/cli/lib/ui.js; from installers/lib/core use '../../../lib/ui'
|
|
1492
|
-
const { UI } = require('../../../lib/ui');
|
|
1493
|
-
const ui = new UI();
|
|
1494
|
-
const toolConfig = await ui.promptToolSelection(projectDir, []);
|
|
1495
|
-
|
|
1496
|
-
if (!toolConfig.skipIde && toolConfig.ides && toolConfig.ides.length > 0) {
|
|
1497
|
-
spinner.start('Updating IDE configurations...');
|
|
1498
|
-
|
|
1499
|
-
for (const ide of toolConfig.ides) {
|
|
1500
|
-
spinner.text = `Updating ${ide}...`;
|
|
1501
|
-
await this.ideManager.setup(ide, projectDir, bmadDir, {
|
|
1502
|
-
selectedModules: installedModules,
|
|
1503
|
-
skipModuleInstall: true, // Skip module installation, just update IDE files
|
|
1504
|
-
verbose: config.verbose,
|
|
1505
|
-
});
|
|
1506
|
-
}
|
|
1507
|
-
|
|
1508
|
-
spinner.succeed('IDE configurations updated');
|
|
1509
|
-
}
|
|
1510
|
-
|
|
1511
|
-
return { agentCount, taskCount };
|
|
1512
|
-
} catch (error) {
|
|
1513
|
-
spinner.fail('Compilation failed');
|
|
1514
|
-
throw error;
|
|
1515
|
-
}
|
|
1516
|
-
}
|
|
1517
|
-
|
|
1518
|
-
/**
|
|
1519
|
-
* Private: Update core
|
|
1818
|
+
* Private: Update core
|
|
1520
1819
|
*/
|
|
1521
1820
|
async updateCore(bmadDir, force = false) {
|
|
1522
1821
|
const sourcePath = getModulePath('core');
|
|
@@ -1528,6 +1827,12 @@ class Installer {
|
|
|
1528
1827
|
} else {
|
|
1529
1828
|
// Selective update - preserve user modifications
|
|
1530
1829
|
await this.fileOps.syncDirectory(sourcePath, targetPath);
|
|
1830
|
+
|
|
1831
|
+
// Recompile agents (#1133)
|
|
1832
|
+
const { ModuleManager } = require('../modules/manager');
|
|
1833
|
+
const moduleManager = new ModuleManager();
|
|
1834
|
+
await moduleManager.compileModuleAgents(sourcePath, targetPath, 'core', bmadDir, this);
|
|
1835
|
+
await this.processAgentFiles(targetPath, 'core');
|
|
1531
1836
|
}
|
|
1532
1837
|
}
|
|
1533
1838
|
|
|
@@ -1542,7 +1847,7 @@ class Installer {
|
|
|
1542
1847
|
|
|
1543
1848
|
try {
|
|
1544
1849
|
const projectDir = path.resolve(config.directory);
|
|
1545
|
-
const bmadDir =
|
|
1850
|
+
const { bmadDir } = await this.findBmadDir(projectDir);
|
|
1546
1851
|
|
|
1547
1852
|
// Check if bmad directory exists
|
|
1548
1853
|
if (!(await fs.pathExists(bmadDir))) {
|
|
@@ -1556,17 +1861,102 @@ class Installer {
|
|
|
1556
1861
|
const existingInstall = await this.detector.detect(bmadDir);
|
|
1557
1862
|
const installedModules = existingInstall.modules.map((m) => m.id);
|
|
1558
1863
|
const configuredIdes = existingInstall.ides || [];
|
|
1864
|
+
const projectRoot = path.dirname(bmadDir);
|
|
1865
|
+
|
|
1866
|
+
// Get custom module sources from cache
|
|
1867
|
+
const customModuleSources = new Map();
|
|
1868
|
+
const cacheDir = path.join(bmadDir, '_config', 'custom');
|
|
1869
|
+
if (await fs.pathExists(cacheDir)) {
|
|
1870
|
+
const cachedModules = await fs.readdir(cacheDir, { withFileTypes: true });
|
|
1871
|
+
|
|
1872
|
+
for (const cachedModule of cachedModules) {
|
|
1873
|
+
if (cachedModule.isDirectory()) {
|
|
1874
|
+
const moduleId = cachedModule.name;
|
|
1875
|
+
|
|
1876
|
+
// Skip if we already have this module from manifest
|
|
1877
|
+
if (customModuleSources.has(moduleId)) {
|
|
1878
|
+
continue;
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1881
|
+
const cachedPath = path.join(cacheDir, moduleId);
|
|
1882
|
+
|
|
1883
|
+
// Check if this is actually a custom module (has module.yaml)
|
|
1884
|
+
const moduleYamlPath = path.join(cachedPath, 'module.yaml');
|
|
1885
|
+
if (await fs.pathExists(moduleYamlPath)) {
|
|
1886
|
+
// For quick update, we always rebuild from cache
|
|
1887
|
+
customModuleSources.set(moduleId, {
|
|
1888
|
+
id: moduleId,
|
|
1889
|
+
name: moduleId, // We'll read the actual name if needed
|
|
1890
|
+
sourcePath: cachedPath,
|
|
1891
|
+
cached: true, // Flag to indicate this is from cache
|
|
1892
|
+
});
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1559
1897
|
|
|
1560
1898
|
// Load saved IDE configurations
|
|
1561
1899
|
const savedIdeConfigs = await this.ideConfigManager.loadAllIdeConfigs(bmadDir);
|
|
1562
1900
|
|
|
1563
1901
|
// Get available modules (what we have source for)
|
|
1564
|
-
const
|
|
1565
|
-
const
|
|
1902
|
+
const availableModulesData = await this.moduleManager.listAvailable();
|
|
1903
|
+
const availableModules = [...availableModulesData.modules, ...availableModulesData.customModules];
|
|
1904
|
+
|
|
1905
|
+
// Add custom modules from manifest if their sources exist
|
|
1906
|
+
for (const [moduleId, customModule] of customModuleSources) {
|
|
1907
|
+
// Use the absolute sourcePath
|
|
1908
|
+
const sourcePath = customModule.sourcePath;
|
|
1909
|
+
|
|
1910
|
+
// Check if source exists at the recorded path
|
|
1911
|
+
if (
|
|
1912
|
+
sourcePath &&
|
|
1913
|
+
(await fs.pathExists(sourcePath)) && // Add to available modules if not already there
|
|
1914
|
+
!availableModules.some((m) => m.id === moduleId)
|
|
1915
|
+
) {
|
|
1916
|
+
availableModules.push({
|
|
1917
|
+
id: moduleId,
|
|
1918
|
+
name: customModule.name || moduleId,
|
|
1919
|
+
path: sourcePath,
|
|
1920
|
+
isCustom: true,
|
|
1921
|
+
fromManifest: true,
|
|
1922
|
+
});
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
// Handle missing custom module sources using shared method
|
|
1927
|
+
const customModuleResult = await this.handleMissingCustomSources(
|
|
1928
|
+
customModuleSources,
|
|
1929
|
+
bmadDir,
|
|
1930
|
+
projectRoot,
|
|
1931
|
+
'update',
|
|
1932
|
+
installedModules,
|
|
1933
|
+
);
|
|
1934
|
+
|
|
1935
|
+
const { validCustomModules, keptModulesWithoutSources } = customModuleResult;
|
|
1936
|
+
|
|
1937
|
+
const customModulesFromManifest = validCustomModules.map((m) => ({
|
|
1938
|
+
...m,
|
|
1939
|
+
isCustom: true,
|
|
1940
|
+
hasUpdate: true,
|
|
1941
|
+
}));
|
|
1942
|
+
|
|
1943
|
+
const allAvailableModules = [...availableModules, ...customModulesFromManifest];
|
|
1944
|
+
const availableModuleIds = new Set(allAvailableModules.map((m) => m.id));
|
|
1945
|
+
|
|
1946
|
+
// Core module is special - never include it in update flow
|
|
1947
|
+
const nonCoreInstalledModules = installedModules.filter((id) => id !== 'core');
|
|
1566
1948
|
|
|
1567
1949
|
// Only update modules that are BOTH installed AND available (we have source for)
|
|
1568
|
-
const modulesToUpdate =
|
|
1569
|
-
const skippedModules =
|
|
1950
|
+
const modulesToUpdate = nonCoreInstalledModules.filter((id) => availableModuleIds.has(id));
|
|
1951
|
+
const skippedModules = nonCoreInstalledModules.filter((id) => !availableModuleIds.has(id));
|
|
1952
|
+
|
|
1953
|
+
// Add custom modules that were kept without sources to the skipped modules
|
|
1954
|
+
// This ensures their agents are preserved in the manifest
|
|
1955
|
+
for (const keptModule of keptModulesWithoutSources) {
|
|
1956
|
+
if (!skippedModules.includes(keptModule)) {
|
|
1957
|
+
skippedModules.push(keptModule);
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1570
1960
|
|
|
1571
1961
|
spinner.succeed(`Found ${modulesToUpdate.length} module(s) to update and ${configuredIdes.length} configured tool(s)`);
|
|
1572
1962
|
|
|
@@ -1605,9 +1995,6 @@ class Installer {
|
|
|
1605
1995
|
lastModified: new Date().toISOString(),
|
|
1606
1996
|
};
|
|
1607
1997
|
|
|
1608
|
-
// Now run the full installation with the collected configs
|
|
1609
|
-
spinner.start('Updating BMAD installation...');
|
|
1610
|
-
|
|
1611
1998
|
// Build the config object for the installer
|
|
1612
1999
|
const installConfig = {
|
|
1613
2000
|
directory: projectDir,
|
|
@@ -1620,12 +2007,18 @@ class Installer {
|
|
|
1620
2007
|
_quickUpdate: true, // Flag to skip certain prompts
|
|
1621
2008
|
_preserveModules: skippedModules, // Preserve these in manifest even though we didn't update them
|
|
1622
2009
|
_savedIdeConfigs: savedIdeConfigs, // Pass saved IDE configs to installer
|
|
2010
|
+
_customModuleSources: customModuleSources, // Pass custom module sources for updates
|
|
2011
|
+
_existingModules: installedModules, // Pass all installed modules for manifest generation
|
|
1623
2012
|
};
|
|
1624
2013
|
|
|
1625
2014
|
// Call the standard install method
|
|
1626
2015
|
const result = await this.install(installConfig);
|
|
1627
2016
|
|
|
1628
|
-
spinner
|
|
2017
|
+
// Only succeed the spinner if it's still spinning
|
|
2018
|
+
// (install method might have stopped it if folder name changed)
|
|
2019
|
+
if (spinner.isSpinning) {
|
|
2020
|
+
spinner.succeed('Quick update complete!');
|
|
2021
|
+
}
|
|
1629
2022
|
|
|
1630
2023
|
return {
|
|
1631
2024
|
success: true,
|
|
@@ -1641,6 +2034,108 @@ class Installer {
|
|
|
1641
2034
|
}
|
|
1642
2035
|
}
|
|
1643
2036
|
|
|
2037
|
+
/**
|
|
2038
|
+
* Compile agents with customizations only
|
|
2039
|
+
* @param {Object} config - Configuration with directory
|
|
2040
|
+
* @returns {Object} Compilation result
|
|
2041
|
+
*/
|
|
2042
|
+
async compileAgents(config) {
|
|
2043
|
+
const ora = require('ora');
|
|
2044
|
+
const chalk = require('chalk');
|
|
2045
|
+
const { ModuleManager } = require('../modules/manager');
|
|
2046
|
+
const { getSourcePath } = require('../../../lib/project-root');
|
|
2047
|
+
|
|
2048
|
+
const spinner = ora('Recompiling agents with customizations...').start();
|
|
2049
|
+
|
|
2050
|
+
try {
|
|
2051
|
+
const projectDir = path.resolve(config.directory);
|
|
2052
|
+
const { bmadDir } = await this.findBmadDir(projectDir);
|
|
2053
|
+
|
|
2054
|
+
// Check if bmad directory exists
|
|
2055
|
+
if (!(await fs.pathExists(bmadDir))) {
|
|
2056
|
+
spinner.fail('No BMAD installation found');
|
|
2057
|
+
throw new Error(`BMAD not installed at ${bmadDir}. Use regular install for first-time setup.`);
|
|
2058
|
+
}
|
|
2059
|
+
|
|
2060
|
+
// Detect existing installation
|
|
2061
|
+
const existingInstall = await this.detector.detect(bmadDir);
|
|
2062
|
+
const installedModules = existingInstall.modules.map((m) => m.id);
|
|
2063
|
+
|
|
2064
|
+
// Initialize module manager
|
|
2065
|
+
const moduleManager = new ModuleManager();
|
|
2066
|
+
moduleManager.setBmadFolderName(path.basename(bmadDir));
|
|
2067
|
+
|
|
2068
|
+
let totalAgentCount = 0;
|
|
2069
|
+
|
|
2070
|
+
// Get custom module sources from cache
|
|
2071
|
+
const customModuleSources = new Map();
|
|
2072
|
+
const cacheDir = path.join(bmadDir, '_config', 'custom');
|
|
2073
|
+
if (await fs.pathExists(cacheDir)) {
|
|
2074
|
+
const cachedModules = await fs.readdir(cacheDir, { withFileTypes: true });
|
|
2075
|
+
|
|
2076
|
+
for (const cachedModule of cachedModules) {
|
|
2077
|
+
if (cachedModule.isDirectory()) {
|
|
2078
|
+
const moduleId = cachedModule.name;
|
|
2079
|
+
const cachedPath = path.join(cacheDir, moduleId);
|
|
2080
|
+
const moduleYamlPath = path.join(cachedPath, 'module.yaml');
|
|
2081
|
+
|
|
2082
|
+
// Check if this is actually a custom module
|
|
2083
|
+
if (await fs.pathExists(moduleYamlPath)) {
|
|
2084
|
+
customModuleSources.set(moduleId, cachedPath);
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
// Process each installed module
|
|
2091
|
+
for (const moduleId of installedModules) {
|
|
2092
|
+
spinner.text = `Recompiling agents in ${moduleId}...`;
|
|
2093
|
+
|
|
2094
|
+
// Get source path
|
|
2095
|
+
let sourcePath;
|
|
2096
|
+
if (moduleId === 'core') {
|
|
2097
|
+
sourcePath = getSourcePath('core');
|
|
2098
|
+
} else {
|
|
2099
|
+
// First check if it's in the custom cache
|
|
2100
|
+
if (customModuleSources.has(moduleId)) {
|
|
2101
|
+
sourcePath = customModuleSources.get(moduleId);
|
|
2102
|
+
} else {
|
|
2103
|
+
sourcePath = await moduleManager.findModuleSource(moduleId);
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2107
|
+
if (!sourcePath) {
|
|
2108
|
+
console.log(chalk.yellow(` Warning: Source not found for module ${moduleId}, skipping...`));
|
|
2109
|
+
continue;
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
const targetPath = path.join(bmadDir, moduleId);
|
|
2113
|
+
|
|
2114
|
+
// Compile agents for this module
|
|
2115
|
+
await moduleManager.compileModuleAgents(sourcePath, targetPath, moduleId, bmadDir, this);
|
|
2116
|
+
|
|
2117
|
+
// Count agents (rough estimate based on files)
|
|
2118
|
+
const agentsPath = path.join(targetPath, 'agents');
|
|
2119
|
+
if (await fs.pathExists(agentsPath)) {
|
|
2120
|
+
const agentFiles = await fs.readdir(agentsPath);
|
|
2121
|
+
const agentCount = agentFiles.filter((f) => f.endsWith('.md')).length;
|
|
2122
|
+
totalAgentCount += agentCount;
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
spinner.succeed('Agent recompilation complete!');
|
|
2127
|
+
|
|
2128
|
+
return {
|
|
2129
|
+
success: true,
|
|
2130
|
+
agentCount: totalAgentCount,
|
|
2131
|
+
modules: installedModules,
|
|
2132
|
+
};
|
|
2133
|
+
} catch (error) {
|
|
2134
|
+
spinner.fail('Agent recompilation failed');
|
|
2135
|
+
throw error;
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
|
|
1644
2139
|
/**
|
|
1645
2140
|
* Private: Prompt for update action
|
|
1646
2141
|
*/
|
|
@@ -1651,11 +2146,7 @@ class Installer {
|
|
|
1651
2146
|
type: 'list',
|
|
1652
2147
|
name: 'action',
|
|
1653
2148
|
message: 'What would you like to do?',
|
|
1654
|
-
choices: [
|
|
1655
|
-
{ name: 'Update existing installation', value: 'update' },
|
|
1656
|
-
{ name: 'Remove and reinstall', value: 'reinstall' },
|
|
1657
|
-
{ name: 'Cancel', value: 'cancel' },
|
|
1658
|
-
],
|
|
2149
|
+
choices: [{ name: 'Update existing installation', value: 'update' }],
|
|
1659
2150
|
},
|
|
1660
2151
|
]);
|
|
1661
2152
|
}
|
|
@@ -1669,14 +2160,14 @@ class Installer {
|
|
|
1669
2160
|
console.log(chalk.yellow.bold('\n⚠️ Legacy BMAD v4 detected'));
|
|
1670
2161
|
console.log(chalk.dim('The installer found legacy artefacts in your project.\n'));
|
|
1671
2162
|
|
|
1672
|
-
// Separate
|
|
2163
|
+
// Separate _bmad* folders (auto-backup) from other offending paths (manual cleanup)
|
|
1673
2164
|
const bmadFolders = legacyV4.offenders.filter((p) => {
|
|
1674
2165
|
const name = path.basename(p);
|
|
1675
|
-
return name.startsWith('
|
|
2166
|
+
return name.startsWith('_bmad'); // Only dot-prefixed folders get auto-backed up
|
|
1676
2167
|
});
|
|
1677
2168
|
const otherOffenders = legacyV4.offenders.filter((p) => {
|
|
1678
2169
|
const name = path.basename(p);
|
|
1679
|
-
return !name.startsWith('
|
|
2170
|
+
return !name.startsWith('_bmad'); // Everything else is manual cleanup
|
|
1680
2171
|
});
|
|
1681
2172
|
|
|
1682
2173
|
const inquirer = require('inquirer');
|
|
@@ -1709,7 +2200,7 @@ class Installer {
|
|
|
1709
2200
|
}
|
|
1710
2201
|
}
|
|
1711
2202
|
|
|
1712
|
-
// Handle
|
|
2203
|
+
// Handle _bmad* folders with automatic backup
|
|
1713
2204
|
if (bmadFolders.length > 0) {
|
|
1714
2205
|
console.log(chalk.cyan('The following legacy folders will be moved to v4-backup:'));
|
|
1715
2206
|
for (const p of bmadFolders) console.log(chalk.dim(` - ${p}`));
|
|
@@ -1753,7 +2244,7 @@ class Installer {
|
|
|
1753
2244
|
* @returns {Array} Array of file entries from files-manifest.csv
|
|
1754
2245
|
*/
|
|
1755
2246
|
async readFilesManifest(bmadDir) {
|
|
1756
|
-
const filesManifestPath = path.join(bmadDir, '
|
|
2247
|
+
const filesManifestPath = path.join(bmadDir, '_config', 'files-manifest.csv');
|
|
1757
2248
|
if (!(await fs.pathExists(filesManifestPath))) {
|
|
1758
2249
|
return [];
|
|
1759
2250
|
}
|
|
@@ -1813,6 +2304,9 @@ class Installer {
|
|
|
1813
2304
|
const customFiles = [];
|
|
1814
2305
|
const modifiedFiles = [];
|
|
1815
2306
|
|
|
2307
|
+
// Memory is always in _bmad/_memory
|
|
2308
|
+
const bmadMemoryPath = '_memory';
|
|
2309
|
+
|
|
1816
2310
|
// Check if the manifest has hashes - if not, we can't detect modifications
|
|
1817
2311
|
let manifestHasHashes = false;
|
|
1818
2312
|
if (existingFilesManifest && existingFilesManifest.length > 0) {
|
|
@@ -1823,13 +2317,10 @@ class Installer {
|
|
|
1823
2317
|
const installedFilesMap = new Map();
|
|
1824
2318
|
for (const fileEntry of existingFilesManifest) {
|
|
1825
2319
|
if (fileEntry.path) {
|
|
1826
|
-
|
|
1827
|
-
// Convert to absolute path
|
|
1828
|
-
const relativePath = fileEntry.path.startsWith('bmad/') ? fileEntry.path.slice(5) : fileEntry.path;
|
|
1829
|
-
const absolutePath = path.join(bmadDir, relativePath);
|
|
2320
|
+
const absolutePath = path.join(bmadDir, fileEntry.path);
|
|
1830
2321
|
installedFilesMap.set(path.normalize(absolutePath), {
|
|
1831
2322
|
hash: fileEntry.hash,
|
|
1832
|
-
relativePath:
|
|
2323
|
+
relativePath: fileEntry.path,
|
|
1833
2324
|
});
|
|
1834
2325
|
}
|
|
1835
2326
|
}
|
|
@@ -1855,20 +2346,47 @@ class Installer {
|
|
|
1855
2346
|
const relativePath = path.relative(bmadDir, fullPath);
|
|
1856
2347
|
const fileName = path.basename(fullPath);
|
|
1857
2348
|
|
|
1858
|
-
// Skip
|
|
1859
|
-
if (relativePath.startsWith('
|
|
2349
|
+
// Skip _config directory EXCEPT for modified agent customizations
|
|
2350
|
+
if (relativePath.startsWith('_config/') || relativePath.startsWith('_config\\')) {
|
|
2351
|
+
// Special handling for .customize.yaml files - only preserve if modified
|
|
2352
|
+
if (relativePath.includes('/agents/') && fileName.endsWith('.customize.yaml')) {
|
|
2353
|
+
// Check if the customization file has been modified from manifest
|
|
2354
|
+
const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
|
|
2355
|
+
if (await fs.pathExists(manifestPath)) {
|
|
2356
|
+
const crypto = require('node:crypto');
|
|
2357
|
+
const currentContent = await fs.readFile(fullPath, 'utf8');
|
|
2358
|
+
const currentHash = crypto.createHash('sha256').update(currentContent).digest('hex');
|
|
2359
|
+
|
|
2360
|
+
const yaml = require('yaml');
|
|
2361
|
+
const manifestContent = await fs.readFile(manifestPath, 'utf8');
|
|
2362
|
+
const manifestData = yaml.parse(manifestContent);
|
|
2363
|
+
const originalHash = manifestData.agentCustomizations?.[relativePath];
|
|
2364
|
+
|
|
2365
|
+
// Only add to customFiles if hash differs (user modified)
|
|
2366
|
+
if (originalHash && currentHash !== originalHash) {
|
|
2367
|
+
customFiles.push(fullPath);
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
}
|
|
2371
|
+
continue;
|
|
2372
|
+
}
|
|
2373
|
+
|
|
2374
|
+
if (relativePath.startsWith(bmadMemoryPath + '/') && path.dirname(relativePath).includes('-sidecar')) {
|
|
1860
2375
|
continue;
|
|
1861
2376
|
}
|
|
1862
2377
|
|
|
1863
2378
|
// Skip config.yaml files - these are regenerated on each install/update
|
|
1864
|
-
// Users should use _cfg/agents/ override files instead
|
|
1865
2379
|
if (fileName === 'config.yaml') {
|
|
1866
2380
|
continue;
|
|
1867
2381
|
}
|
|
1868
2382
|
|
|
1869
2383
|
if (!fileInfo) {
|
|
1870
2384
|
// File not in manifest = custom file
|
|
1871
|
-
|
|
2385
|
+
// EXCEPT: Agent .md files in module folders are generated files, not custom
|
|
2386
|
+
// Only treat .md files under _config/agents/ as custom
|
|
2387
|
+
if (!(fileName.endsWith('.md') && relativePath.includes('/agents/') && !relativePath.startsWith('_config/'))) {
|
|
2388
|
+
customFiles.push(fullPath);
|
|
2389
|
+
}
|
|
1872
2390
|
} else if (manifestHasHashes && fileInfo.hash) {
|
|
1873
2391
|
// File in manifest with hash - check if it was modified
|
|
1874
2392
|
const currentHash = await this.manifest.calculateFileHash(fullPath);
|
|
@@ -1880,8 +2398,6 @@ class Installer {
|
|
|
1880
2398
|
});
|
|
1881
2399
|
}
|
|
1882
2400
|
}
|
|
1883
|
-
// If manifest doesn't have hashes, we can't detect modifications
|
|
1884
|
-
// so we just skip files that are in the manifest
|
|
1885
2401
|
}
|
|
1886
2402
|
}
|
|
1887
2403
|
} catch {
|
|
@@ -1894,201 +2410,240 @@ class Installer {
|
|
|
1894
2410
|
}
|
|
1895
2411
|
|
|
1896
2412
|
/**
|
|
1897
|
-
*
|
|
1898
|
-
* @param {
|
|
1899
|
-
* @param {
|
|
2413
|
+
* Handle missing custom module sources interactively
|
|
2414
|
+
* @param {Map} customModuleSources - Map of custom module ID to info
|
|
2415
|
+
* @param {string} bmadDir - BMAD directory
|
|
2416
|
+
* @param {string} projectRoot - Project root directory
|
|
2417
|
+
* @param {string} operation - Current operation ('update', 'compile', etc.)
|
|
2418
|
+
* @param {Array} installedModules - Array of installed module IDs (will be modified)
|
|
2419
|
+
* @returns {Object} Object with validCustomModules array and keptModulesWithoutSources array
|
|
1900
2420
|
*/
|
|
1901
|
-
async
|
|
1902
|
-
const
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
const
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
agents.push({
|
|
1933
|
-
name: agentName,
|
|
1934
|
-
module: entry.name,
|
|
1935
|
-
agentConfigNodes: agentConfigNodes,
|
|
1936
|
-
});
|
|
1937
|
-
|
|
1938
|
-
// Use shared AgentPartyGenerator to extract details
|
|
1939
|
-
let details = AgentPartyGenerator.extractAgentDetails(agentContent, entry.name, agentName);
|
|
1940
|
-
|
|
1941
|
-
// Apply config overrides if they exist
|
|
1942
|
-
if (details) {
|
|
1943
|
-
const configPath = path.join(agentConfigDir, `${entry.name}-${agentName}.md`);
|
|
1944
|
-
if (await fs.pathExists(configPath)) {
|
|
1945
|
-
const configContent = await fs.readFile(configPath, 'utf8');
|
|
1946
|
-
details = AgentPartyGenerator.applyConfigOverrides(details, configContent);
|
|
1947
|
-
}
|
|
1948
|
-
agentDetails.push(details);
|
|
1949
|
-
}
|
|
1950
|
-
}
|
|
1951
|
-
}
|
|
2421
|
+
async handleMissingCustomSources(customModuleSources, bmadDir, projectRoot, operation, installedModules) {
|
|
2422
|
+
const validCustomModules = [];
|
|
2423
|
+
const keptModulesWithoutSources = []; // Track modules kept without sources
|
|
2424
|
+
const customModulesWithMissingSources = [];
|
|
2425
|
+
|
|
2426
|
+
// Check which sources exist
|
|
2427
|
+
for (const [moduleId, customInfo] of customModuleSources) {
|
|
2428
|
+
if (await fs.pathExists(customInfo.sourcePath)) {
|
|
2429
|
+
validCustomModules.push({
|
|
2430
|
+
id: moduleId,
|
|
2431
|
+
name: customInfo.name,
|
|
2432
|
+
path: customInfo.sourcePath,
|
|
2433
|
+
info: customInfo,
|
|
2434
|
+
});
|
|
2435
|
+
} else {
|
|
2436
|
+
// For cached modules that are missing, we just skip them without prompting
|
|
2437
|
+
if (customInfo.cached) {
|
|
2438
|
+
// Skip cached modules without prompting
|
|
2439
|
+
keptModulesWithoutSources.push({
|
|
2440
|
+
id: moduleId,
|
|
2441
|
+
name: customInfo.name,
|
|
2442
|
+
cached: true,
|
|
2443
|
+
});
|
|
2444
|
+
} else {
|
|
2445
|
+
customModulesWithMissingSources.push({
|
|
2446
|
+
id: moduleId,
|
|
2447
|
+
name: customInfo.name,
|
|
2448
|
+
sourcePath: customInfo.sourcePath,
|
|
2449
|
+
relativePath: customInfo.relativePath,
|
|
2450
|
+
info: customInfo,
|
|
2451
|
+
});
|
|
1952
2452
|
}
|
|
1953
2453
|
}
|
|
1954
2454
|
}
|
|
1955
2455
|
|
|
1956
|
-
//
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
2456
|
+
// If no missing sources, return immediately
|
|
2457
|
+
if (customModulesWithMissingSources.length === 0) {
|
|
2458
|
+
return {
|
|
2459
|
+
validCustomModules,
|
|
2460
|
+
keptModulesWithoutSources: [],
|
|
2461
|
+
};
|
|
2462
|
+
}
|
|
1963
2463
|
|
|
1964
|
-
|
|
1965
|
-
|
|
2464
|
+
// Stop any spinner for interactive prompts
|
|
2465
|
+
const currentSpinner = ora();
|
|
2466
|
+
if (currentSpinner.isSpinning) {
|
|
2467
|
+
currentSpinner.stop();
|
|
2468
|
+
}
|
|
1966
2469
|
|
|
1967
|
-
|
|
1968
|
-
if (await fs.pathExists(configPath)) {
|
|
1969
|
-
skippedCount++;
|
|
1970
|
-
continue;
|
|
1971
|
-
}
|
|
2470
|
+
console.log(chalk.yellow(`\n⚠️ Found ${customModulesWithMissingSources.length} custom module(s) with missing sources:`));
|
|
1972
2471
|
|
|
1973
|
-
|
|
1974
|
-
|
|
2472
|
+
const inquirer = require('inquirer');
|
|
2473
|
+
let keptCount = 0;
|
|
2474
|
+
let updatedCount = 0;
|
|
2475
|
+
let removedCount = 0;
|
|
1975
2476
|
|
|
1976
|
-
|
|
1977
|
-
|
|
2477
|
+
for (const missing of customModulesWithMissingSources) {
|
|
2478
|
+
console.log(chalk.dim(` • ${missing.name} (${missing.id})`));
|
|
2479
|
+
console.log(chalk.dim(` Original source: ${missing.relativePath}`));
|
|
2480
|
+
console.log(chalk.dim(` Full path: ${missing.sourcePath}`));
|
|
1978
2481
|
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
2482
|
+
const choices = [
|
|
2483
|
+
{
|
|
2484
|
+
name: 'Keep installed (will not be processed)',
|
|
2485
|
+
value: 'keep',
|
|
2486
|
+
short: 'Keep',
|
|
2487
|
+
},
|
|
2488
|
+
{
|
|
2489
|
+
name: 'Specify new source location',
|
|
2490
|
+
value: 'update',
|
|
2491
|
+
short: 'Update',
|
|
2492
|
+
},
|
|
2493
|
+
];
|
|
2494
|
+
|
|
2495
|
+
// Only add remove option if not just compiling agents
|
|
2496
|
+
if (operation !== 'compile-agents') {
|
|
2497
|
+
choices.push({
|
|
2498
|
+
name: '⚠️ REMOVE module completely (destructive!)',
|
|
2499
|
+
value: 'remove',
|
|
2500
|
+
short: 'Remove',
|
|
2501
|
+
});
|
|
1982
2502
|
}
|
|
1983
2503
|
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
2504
|
+
const { action } = await inquirer.prompt([
|
|
2505
|
+
{
|
|
2506
|
+
type: 'list',
|
|
2507
|
+
name: 'action',
|
|
2508
|
+
message: `How would you like to handle "${missing.name}"?`,
|
|
2509
|
+
choices,
|
|
2510
|
+
},
|
|
2511
|
+
]);
|
|
1988
2512
|
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
2513
|
+
switch (action) {
|
|
2514
|
+
case 'update': {
|
|
2515
|
+
const { newSourcePath } = await inquirer.prompt([
|
|
2516
|
+
{
|
|
2517
|
+
type: 'input',
|
|
2518
|
+
name: 'newSourcePath',
|
|
2519
|
+
message: 'Enter the new path to the custom module:',
|
|
2520
|
+
default: missing.sourcePath,
|
|
2521
|
+
validate: async (input) => {
|
|
2522
|
+
if (!input || input.trim() === '') {
|
|
2523
|
+
return 'Please enter a path';
|
|
2524
|
+
}
|
|
2525
|
+
const expandedPath = path.resolve(input.trim());
|
|
2526
|
+
if (!(await fs.pathExists(expandedPath))) {
|
|
2527
|
+
return 'Path does not exist';
|
|
2528
|
+
}
|
|
2529
|
+
// Check if it looks like a valid module
|
|
2530
|
+
const moduleYamlPath = path.join(expandedPath, 'module.yaml');
|
|
2531
|
+
const agentsPath = path.join(expandedPath, 'agents');
|
|
2532
|
+
const workflowsPath = path.join(expandedPath, 'workflows');
|
|
1994
2533
|
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2534
|
+
if (!(await fs.pathExists(moduleYamlPath)) && !(await fs.pathExists(agentsPath)) && !(await fs.pathExists(workflowsPath))) {
|
|
2535
|
+
return 'Path does not appear to contain a valid custom module';
|
|
2536
|
+
}
|
|
2537
|
+
return true;
|
|
2538
|
+
},
|
|
2539
|
+
},
|
|
2540
|
+
]);
|
|
2001
2541
|
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2542
|
+
// Update the source in manifest
|
|
2543
|
+
const resolvedPath = path.resolve(newSourcePath.trim());
|
|
2544
|
+
missing.info.sourcePath = resolvedPath;
|
|
2545
|
+
// Remove relativePath - we only store absolute sourcePath now
|
|
2546
|
+
delete missing.info.relativePath;
|
|
2547
|
+
await this.manifest.addCustomModule(bmadDir, missing.info);
|
|
2548
|
+
|
|
2549
|
+
validCustomModules.push({
|
|
2550
|
+
id: missing.id,
|
|
2551
|
+
name: missing.name,
|
|
2552
|
+
path: resolvedPath,
|
|
2553
|
+
info: missing.info,
|
|
2554
|
+
});
|
|
2005
2555
|
|
|
2006
|
-
|
|
2556
|
+
updatedCount++;
|
|
2557
|
+
console.log(chalk.green(`✓ Updated source location`));
|
|
2007
2558
|
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2559
|
+
break;
|
|
2560
|
+
}
|
|
2561
|
+
case 'remove': {
|
|
2562
|
+
// Extra confirmation for destructive remove
|
|
2563
|
+
console.log(chalk.red.bold(`\n⚠️ WARNING: This will PERMANENTLY DELETE "${missing.name}" and all its files!`));
|
|
2564
|
+
console.log(chalk.red(` Module location: ${path.join(bmadDir, missing.id)}`));
|
|
2012
2565
|
|
|
2013
|
-
|
|
2014
|
-
|
|
2566
|
+
const { confirm } = await inquirer.prompt([
|
|
2567
|
+
{
|
|
2568
|
+
type: 'confirm',
|
|
2569
|
+
name: 'confirm',
|
|
2570
|
+
message: chalk.red.bold('Are you absolutely sure you want to delete this module?'),
|
|
2571
|
+
default: false,
|
|
2572
|
+
},
|
|
2573
|
+
]);
|
|
2015
2574
|
|
|
2016
|
-
|
|
2017
|
-
|
|
2575
|
+
if (confirm) {
|
|
2576
|
+
const { typedConfirm } = await inquirer.prompt([
|
|
2577
|
+
{
|
|
2578
|
+
type: 'input',
|
|
2579
|
+
name: 'typedConfirm',
|
|
2580
|
+
message: chalk.red.bold('Type "DELETE" to confirm permanent deletion:'),
|
|
2581
|
+
validate: (input) => {
|
|
2582
|
+
if (input !== 'DELETE') {
|
|
2583
|
+
return chalk.red('You must type "DELETE" exactly to proceed');
|
|
2584
|
+
}
|
|
2585
|
+
return true;
|
|
2586
|
+
},
|
|
2587
|
+
},
|
|
2588
|
+
]);
|
|
2589
|
+
|
|
2590
|
+
if (typedConfirm === 'DELETE') {
|
|
2591
|
+
// Remove the module from filesystem and manifest
|
|
2592
|
+
const modulePath = path.join(bmadDir, moduleId);
|
|
2593
|
+
if (await fs.pathExists(modulePath)) {
|
|
2594
|
+
const fsExtra = require('fs-extra');
|
|
2595
|
+
await fsExtra.remove(modulePath);
|
|
2596
|
+
console.log(chalk.yellow(` ✓ Deleted module directory: ${path.relative(projectRoot, modulePath)}`));
|
|
2597
|
+
}
|
|
2018
2598
|
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
* @param {Array} agentDetails - Array of agent details
|
|
2023
|
-
*/
|
|
2024
|
-
async generateAgentManifest(bmadDir, agentDetails) {
|
|
2025
|
-
const manifestPath = path.join(bmadDir, '_cfg', 'agent-manifest.csv');
|
|
2026
|
-
await AgentPartyGenerator.writeAgentParty(manifestPath, agentDetails, { forWeb: false });
|
|
2027
|
-
}
|
|
2599
|
+
await this.manifest.removeModule(bmadDir, moduleId);
|
|
2600
|
+
await this.manifest.removeCustomModule(bmadDir, moduleId);
|
|
2601
|
+
console.log(chalk.yellow(` ✓ Removed from manifest`));
|
|
2028
2602
|
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2603
|
+
// Also remove from installedModules list
|
|
2604
|
+
if (installedModules && installedModules.includes(moduleId)) {
|
|
2605
|
+
const index = installedModules.indexOf(moduleId);
|
|
2606
|
+
if (index !== -1) {
|
|
2607
|
+
installedModules.splice(index, 1);
|
|
2608
|
+
}
|
|
2609
|
+
}
|
|
2036
2610
|
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
const tagMatch = match[0].match(/<([a-zA-Z][a-zA-Z0-9_-]*)([^>]*)\/>/);
|
|
2048
|
-
if (tagMatch) {
|
|
2049
|
-
const tagName = tagMatch[1];
|
|
2050
|
-
const attributes = tagMatch[2].replace(/\s*agentConfig="true"/, ''); // Remove agentConfig attribute
|
|
2051
|
-
nodes.push(`<${tagName}${attributes}></${tagName}>`);
|
|
2052
|
-
}
|
|
2053
|
-
}
|
|
2611
|
+
removedCount++;
|
|
2612
|
+
console.log(chalk.red.bold(`✓ "${missing.name}" has been permanently removed`));
|
|
2613
|
+
} else {
|
|
2614
|
+
console.log(chalk.dim(' Removal cancelled - module will be kept'));
|
|
2615
|
+
keptCount++;
|
|
2616
|
+
}
|
|
2617
|
+
} else {
|
|
2618
|
+
console.log(chalk.dim(' Removal cancelled - module will be kept'));
|
|
2619
|
+
keptCount++;
|
|
2620
|
+
}
|
|
2054
2621
|
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2622
|
+
break;
|
|
2623
|
+
}
|
|
2624
|
+
case 'keep': {
|
|
2625
|
+
keptCount++;
|
|
2626
|
+
keptModulesWithoutSources.push(moduleId);
|
|
2627
|
+
console.log(chalk.dim(` Module will be kept as-is`));
|
|
2059
2628
|
|
|
2060
|
-
|
|
2061
|
-
const openingTagMatch = fullMatch.match(new RegExp(`<${tagName}([^>]*)>`));
|
|
2062
|
-
if (openingTagMatch) {
|
|
2063
|
-
const attributes = openingTagMatch[1].replace(/\s*agentConfig="true"/, '');
|
|
2064
|
-
// Add empty node structure (no children)
|
|
2065
|
-
nodes.push(`<${tagName}${attributes}></${tagName}>`);
|
|
2629
|
+
break;
|
|
2066
2630
|
}
|
|
2631
|
+
// No default
|
|
2067
2632
|
}
|
|
2068
|
-
} catch (error) {
|
|
2069
|
-
console.error('Error extracting agentConfig nodes:', error);
|
|
2070
2633
|
}
|
|
2071
2634
|
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
* @param {string} bmadDir - BMAD installation directory
|
|
2079
|
-
*/
|
|
2080
|
-
async copyIdeDocumentation(ides, bmadDir) {
|
|
2081
|
-
const docsDir = path.join(bmadDir, 'docs');
|
|
2082
|
-
await fs.ensureDir(docsDir);
|
|
2083
|
-
|
|
2084
|
-
for (const ide of ides) {
|
|
2085
|
-
const sourceDocPath = path.join(getProjectRoot(), 'docs', 'ide-info', `${ide}.md`);
|
|
2086
|
-
const targetDocPath = path.join(docsDir, `${ide}-instructions.md`);
|
|
2087
|
-
|
|
2088
|
-
if (await fs.pathExists(sourceDocPath)) {
|
|
2089
|
-
await fs.copy(sourceDocPath, targetDocPath, { overwrite: true });
|
|
2090
|
-
}
|
|
2635
|
+
// Show summary
|
|
2636
|
+
if (keptCount > 0 || updatedCount > 0 || removedCount > 0) {
|
|
2637
|
+
console.log(chalk.dim(`\nSummary for custom modules with missing sources:`));
|
|
2638
|
+
if (keptCount > 0) console.log(chalk.dim(` • ${keptCount} module(s) kept as-is`));
|
|
2639
|
+
if (updatedCount > 0) console.log(chalk.dim(` • ${updatedCount} module(s) updated with new sources`));
|
|
2640
|
+
if (removedCount > 0) console.log(chalk.red(` • ${removedCount} module(s) permanently deleted`));
|
|
2091
2641
|
}
|
|
2642
|
+
|
|
2643
|
+
return {
|
|
2644
|
+
validCustomModules,
|
|
2645
|
+
keptModulesWithoutSources,
|
|
2646
|
+
};
|
|
2092
2647
|
}
|
|
2093
2648
|
}
|
|
2094
2649
|
|