bmad-method 6.0.0-alpha.15 → 6.0.0-alpha.17
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 +8 -4
- package/.github/scripts/discord-helpers.sh +21 -2
- package/.github/workflows/discord.yaml +31 -7
- package/.github/workflows/manual-release.yaml +12 -42
- package/.markdownlint-cli2.yaml +2 -2
- package/.prettierignore +2 -2
- package/.vscode/settings.json +1 -1
- package/CHANGELOG.md +126 -1
- package/LICENSE +1 -1
- package/README.md +29 -2
- package/docs/agent-customization-guide.md +10 -10
- package/docs/custom-content-installation.md +100 -196
- package/docs/custom-content.md +122 -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/opencode.md +1 -1
- package/docs/ide-info/rovo-dev.md +1 -1
- package/docs/index.md +2 -2
- package/docs/installers-bundlers/ide-injections.md +2 -2
- package/docs/installers-bundlers/installers-modules-platforms-reference.md +25 -25
- package/docs/sample-custom-modules/README.md +11 -0
- package/docs/sample-custom-modules/sample-unitary-module/README.md +8 -0
- package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/agents/commit-poet/commit-poet.agent.yaml +1 -1
- package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/agents/toolsmith/toolsmith.agent.yaml +14 -14
- package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/module.yaml +5 -1
- package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/workflows/quiz-master/steps/step-01-init.md +2 -2
- package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/workflows/quiz-master/steps/step-02-q1.md +1 -1
- package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/workflows/quiz-master/steps/step-03-q2.md +1 -1
- package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/workflows/quiz-master/steps/step-04-q3.md +1 -1
- package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/workflows/quiz-master/steps/step-05-q4.md +1 -1
- package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/workflows/quiz-master/steps/step-06-q5.md +1 -1
- package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/workflows/quiz-master/steps/step-07-q6.md +1 -1
- package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/workflows/quiz-master/steps/step-08-q7.md +1 -1
- package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/workflows/quiz-master/steps/step-09-q8.md +1 -1
- package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/workflows/quiz-master/steps/step-10-q9.md +1 -1
- package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/workflows/quiz-master/steps/step-11-q10.md +1 -1
- package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/workflows/quiz-master/steps/step-12-results.md +1 -1
- package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/workflows/quiz-master/workflow.md +1 -1
- package/docs/sample-custom-modules/sample-wellness-module/README.md +6 -0
- package/{example-custom-module/mwm → docs/sample-custom-modules/sample-wellness-module}/agents/meditation-guide.agent.yaml +37 -39
- package/docs/sample-custom-modules/sample-wellness-module/agents/wellness-companion/foo.md +3 -0
- package/docs/sample-custom-modules/sample-wellness-module/agents/wellness-companion/wellness-companion-sidecar/addition1.md +1 -0
- package/{example-custom-module/mwm → docs/sample-custom-modules/sample-wellness-module}/agents/wellness-companion/wellness-companion.agent.yaml +8 -13
- package/docs/sample-custom-modules/sample-wellness-module/module.yaml +17 -0
- package/{example-custom-module/mwm → docs/sample-custom-modules/sample-wellness-module}/workflows/wellness-journal/workflow.md +3 -3
- package/docs/v4-to-v6-upgrade.md +27 -27
- package/docs/web-bundles-gemini-gpt-guide.md +6 -458
- package/eslint.config.mjs +2 -2
- package/package.json +1 -1
- package/src/core/agents/bmad-master.agent.yaml +6 -11
- package/src/core/module.yaml +10 -24
- package/src/core/resources/excalidraw/README.md +6 -6
- package/src/core/tasks/advanced-elicitation.xml +3 -3
- package/src/core/tasks/index-docs.xml +1 -1
- package/src/core/tasks/validate-workflow.xml +1 -1
- package/src/core/tasks/workflow.xml +4 -4
- package/src/core/tools/shard-doc.xml +12 -12
- package/src/core/workflows/brainstorming/workflow.md +3 -3
- package/src/core/workflows/party-mode/steps/step-01-agent-loading.md +2 -2
- package/src/core/workflows/party-mode/workflow.md +4 -4
- package/src/modules/bmb/agents/bmad-builder.agent.yaml +15 -15
- package/src/modules/bmb/{README.md → docs/README.md} +15 -27
- package/src/modules/bmb/docs/agents/agent-compilation.md +3 -3
- package/src/modules/bmb/docs/agents/agent-menu-patterns.md +23 -24
- package/src/modules/bmb/docs/agents/expert-agent-architecture.md +21 -22
- package/src/modules/bmb/docs/agents/index.md +1 -1
- package/src/modules/bmb/docs/agents/simple-agent-architecture.md +17 -52
- package/src/modules/bmb/docs/agents/understanding-agent-types.md +6 -6
- package/src/modules/bmb/docs/workflows/architecture.md +1 -1
- package/src/modules/bmb/docs/workflows/common-workflow-tools.csv +3 -3
- package/src/modules/bmb/docs/workflows/templates/step-01-init-continuable-template.md +1 -1
- package/src/modules/bmb/docs/workflows/templates/step-1b-template.md +1 -1
- package/src/modules/bmb/docs/workflows/templates/step-file.md +3 -3
- package/src/modules/bmb/docs/workflows/templates/step-template.md +3 -3
- package/src/modules/bmb/docs/workflows/templates/workflow-template.md +2 -2
- package/src/modules/bmb/docs/workflows/templates/workflow.md +1 -1
- package/src/modules/bmb/module.yaml +6 -16
- package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper.agent.yaml +7 -7
- package/src/modules/bmb/reference/agents/module-examples/README.md +3 -4
- package/src/modules/bmb/reference/agents/module-examples/security-engineer.agent.yaml +5 -5
- package/src/modules/bmb/reference/agents/module-examples/trend-analyst.agent.yaml +7 -7
- package/src/modules/bmb/reference/agents/simple-examples/README.md +1 -1
- package/src/modules/bmb/reference/agents/simple-examples/commit-poet.agent.yaml +1 -1
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-01-init.md +1 -1
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-01b-continue.md +1 -1
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-02-profile.md +3 -3
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-03-assessment.md +3 -3
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-04-strategy.md +5 -5
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md +5 -5
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-06-prep-schedule.md +5 -5
- package/src/modules/bmb/reference/workflows/meal-prep-nutrition/workflow.md +2 -2
- package/src/modules/bmb/workflows/create-agent/data/reference/agents/module-examples/README.md +1 -3
- package/src/modules/bmb/workflows/create-agent/data/reference/agents/module-examples/security-engineer.agent.yaml +6 -6
- package/src/modules/bmb/workflows/create-agent/data/reference/agents/module-examples/trend-analyst.agent.yaml +7 -7
- package/src/modules/bmb/workflows/create-agent/data/reference/agents/simple-examples/README.md +1 -1
- package/src/modules/bmb/workflows/create-agent/data/reference/agents/simple-examples/commit-poet.agent.yaml +1 -1
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-01-init.md +1 -1
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-01b-continue.md +1 -1
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-02-profile.md +3 -3
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-03-assessment.md +3 -3
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-04-strategy.md +5 -5
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md +5 -5
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-06-prep-schedule.md +5 -5
- package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/workflow.md +2 -2
- package/src/modules/bmb/workflows/create-agent/data/validation-complete.md +5 -5
- package/src/modules/bmb/workflows/create-agent/steps/step-01-brainstorm.md +5 -5
- package/src/modules/bmb/workflows/create-agent/steps/step-02-discover.md +7 -11
- package/src/modules/bmb/workflows/create-agent/steps/step-03-persona.md +7 -7
- package/src/modules/bmb/workflows/create-agent/steps/step-04-commands.md +10 -10
- package/src/modules/bmb/workflows/create-agent/steps/step-05-name.md +7 -6
- package/src/modules/bmb/workflows/create-agent/steps/step-06-build.md +20 -58
- package/src/modules/bmb/workflows/create-agent/steps/step-07-validate.md +6 -6
- package/src/modules/bmb/workflows/create-agent/steps/{step-11-celebrate.md → step-08-celebrate.md} +3 -7
- 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 +2 -35
- package/src/modules/bmb/workflows/create-module/steps/step-01-init.md +4 -4
- package/src/modules/bmb/workflows/create-module/steps/step-01b-continue.md +2 -2
- package/src/modules/bmb/workflows/create-module/steps/step-02-concept.md +5 -5
- package/src/modules/bmb/workflows/create-module/steps/step-03-components.md +5 -5
- package/src/modules/bmb/workflows/create-module/steps/step-04-structure.md +6 -6
- package/src/modules/bmb/workflows/create-module/steps/step-05-config.md +5 -5
- package/src/modules/bmb/workflows/create-module/steps/step-06-agents.md +9 -9
- package/src/modules/bmb/workflows/create-module/steps/step-07-workflows.md +5 -5
- package/src/modules/bmb/workflows/create-module/steps/step-08-installer.md +8 -8
- package/src/modules/bmb/workflows/create-module/steps/step-09-documentation.md +7 -7
- package/src/modules/bmb/workflows/create-module/steps/step-10-roadmap.md +7 -7
- package/src/modules/bmb/workflows/create-module/steps/step-11-validate.md +6 -6
- package/src/modules/bmb/workflows/create-module/templates/agent.template.md +15 -19
- package/src/modules/bmb/workflows/create-module/templates/module.template.yaml +1 -1
- package/src/modules/bmb/workflows/create-module/workflow.md +3 -3
- package/src/modules/bmb/workflows/create-workflow/steps/step-01-init.md +4 -4
- package/src/modules/bmb/workflows/create-workflow/steps/step-02-gather.md +6 -6
- package/src/modules/bmb/workflows/create-workflow/steps/step-03-tools-configuration.md +5 -5
- package/src/modules/bmb/workflows/create-workflow/steps/step-04-plan-review.md +4 -4
- package/src/modules/bmb/workflows/create-workflow/steps/step-05-output-format-design.md +4 -4
- package/src/modules/bmb/workflows/create-workflow/steps/step-06-design.md +11 -11
- package/src/modules/bmb/workflows/create-workflow/steps/step-07-build.md +14 -14
- package/src/modules/bmb/workflows/create-workflow/steps/step-08-review.md +4 -4
- package/src/modules/bmb/workflows/create-workflow/steps/step-09-complete.md +2 -2
- package/src/modules/bmb/workflows/create-workflow/workflow.md +2 -2
- package/src/modules/bmb/workflows/edit-agent/steps/step-01-discover-intent.md +3 -3
- package/src/modules/bmb/workflows/edit-agent/steps/step-02-analyze-agent.md +13 -13
- package/src/modules/bmb/workflows/edit-agent/steps/step-03-propose-changes.md +5 -5
- package/src/modules/bmb/workflows/edit-agent/steps/step-04-apply-changes.md +3 -3
- package/src/modules/bmb/workflows/edit-agent/steps/step-05-validate.md +5 -5
- package/src/modules/bmb/workflows/edit-agent/workflow.md +1 -1
- package/src/modules/bmb/workflows/edit-workflow/steps/step-01-analyze.md +4 -4
- package/src/modules/bmb/workflows/edit-workflow/steps/step-02-discover.md +3 -3
- package/src/modules/bmb/workflows/edit-workflow/steps/step-03-improve.md +6 -6
- package/src/modules/bmb/workflows/edit-workflow/steps/step-04-validate.md +3 -3
- package/src/modules/bmb/workflows/edit-workflow/steps/step-05-compliance-check.md +3 -3
- package/src/modules/bmb/workflows/edit-workflow/workflow.md +1 -1
- package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-01-validate-goal.md +3 -3
- package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-02-workflow-validation.md +5 -5
- package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-03-step-validation.md +6 -6
- package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-04-file-validation.md +4 -4
- package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-05-intent-spectrum-validation.md +4 -4
- package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-06-web-subprocess-validation.md +4 -4
- package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-07-holistic-analysis.md +4 -4
- package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-08-generate-report.md +3 -3
- package/src/modules/bmb/workflows/workflow-compliance-check/workflow.md +1 -1
- package/src/modules/bmb/workflows-legacy/edit-module/README.md +1 -17
- package/src/modules/bmb/workflows-legacy/edit-module/checklist.md +3 -4
- package/src/modules/bmb/workflows-legacy/edit-module/instructions.md +4 -5
- package/src/modules/bmb/workflows-legacy/edit-module/workflow.yaml +10 -10
- package/src/modules/bmb/workflows-legacy/module-brief/README.md +2 -2
- package/src/modules/bmb/workflows-legacy/module-brief/instructions.md +2 -2
- package/src/modules/bmb/workflows-legacy/module-brief/workflow.yaml +4 -4
- package/src/modules/bmgd/README.md +1 -1
- package/src/modules/bmgd/agents/game-architect.agent.yaml +6 -6
- package/src/modules/bmgd/agents/game-designer.agent.yaml +7 -7
- package/src/modules/bmgd/agents/game-dev.agent.yaml +10 -10
- package/src/modules/bmgd/agents/game-scrum-master.agent.yaml +21 -21
- package/src/modules/bmgd/module.yaml +2 -8
- package/src/modules/bmgd/workflows/1-preproduction/brainstorm-game/instructions.md +1 -1
- package/src/modules/bmgd/workflows/1-preproduction/brainstorm-game/workflow.yaml +9 -9
- package/src/modules/bmgd/workflows/1-preproduction/game-brief/instructions.md +1 -1
- package/src/modules/bmgd/workflows/1-preproduction/game-brief/workflow.yaml +8 -8
- package/src/modules/bmgd/workflows/2-design/gdd/instructions-gdd.md +4 -4
- package/src/modules/bmgd/workflows/2-design/gdd/workflow.yaml +30 -30
- package/src/modules/bmgd/workflows/2-design/narrative/instructions-narrative.md +1 -1
- package/src/modules/bmgd/workflows/2-design/narrative/workflow.yaml +5 -5
- package/src/modules/bmgd/workflows/3-technical/game-architecture/instructions.md +1 -1
- package/src/modules/bmgd/workflows/3-technical/game-architecture/workflow.yaml +2 -2
- package/src/modules/bmgd/workflows/4-production/code-review/instructions.md +4 -4
- package/src/modules/bmgd/workflows/4-production/code-review/workflow.yaml +2 -2
- package/src/modules/bmgd/workflows/4-production/correct-course/checklist.md +1 -1
- package/src/modules/bmgd/workflows/4-production/correct-course/instructions.md +2 -2
- package/src/modules/bmgd/workflows/4-production/correct-course/workflow.yaml +2 -2
- package/src/modules/bmgd/workflows/4-production/create-story/instructions.md +2 -2
- package/src/modules/bmgd/workflows/4-production/create-story/workflow.yaml +2 -2
- package/src/modules/bmgd/workflows/4-production/dev-story/instructions.md +2 -2
- package/src/modules/bmgd/workflows/4-production/dev-story/workflow.yaml +2 -2
- package/src/modules/bmgd/workflows/4-production/epic-tech-context/checklist.md +1 -1
- package/src/modules/bmgd/workflows/4-production/epic-tech-context/instructions.md +2 -2
- package/src/modules/bmgd/workflows/4-production/epic-tech-context/workflow.yaml +2 -2
- package/src/modules/bmgd/workflows/4-production/retrospective/instructions.md +2 -2
- package/src/modules/bmgd/workflows/4-production/retrospective/workflow.yaml +3 -3
- package/src/modules/bmgd/workflows/4-production/sprint-planning/instructions.md +2 -2
- package/src/modules/bmgd/workflows/4-production/sprint-planning/workflow.yaml +2 -2
- package/src/modules/bmgd/workflows/4-production/story-context/checklist.md +1 -1
- package/src/modules/bmgd/workflows/4-production/story-context/context-template.xml +2 -2
- package/src/modules/bmgd/workflows/4-production/story-context/instructions.md +2 -2
- package/src/modules/bmgd/workflows/4-production/story-context/workflow.yaml +2 -2
- package/src/modules/bmgd/workflows/4-production/story-done/instructions.md +1 -1
- package/src/modules/bmgd/workflows/4-production/story-done/workflow.yaml +2 -2
- package/src/modules/bmgd/workflows/4-production/story-ready/instructions.md +1 -1
- package/src/modules/bmgd/workflows/4-production/story-ready/workflow.yaml +2 -2
- package/src/modules/bmm/README.md +1 -1
- package/src/modules/bmm/agents/analyst.agent.yaml +9 -9
- package/src/modules/bmm/agents/architect.agent.yaml +8 -8
- package/src/modules/bmm/agents/dev.agent.yaml +5 -5
- package/src/modules/bmm/agents/pm.agent.yaml +8 -8
- package/src/modules/bmm/agents/quick-flow-solo-dev.agent.yaml +5 -5
- package/src/modules/bmm/agents/sm.agent.yaml +11 -11
- package/src/modules/bmm/agents/tea.agent.yaml +13 -13
- package/src/modules/bmm/agents/tech-writer.agent.yaml +9 -9
- package/src/modules/bmm/agents/ux-designer.agent.yaml +6 -6
- package/src/modules/bmm/docs/README.md +0 -25
- package/src/modules/bmm/docs/agents-guide.md +16 -14
- package/src/modules/bmm/docs/brownfield-guide.md +6 -6
- package/src/modules/bmm/docs/enterprise-agentic-development.md +3 -3
- package/src/modules/bmm/docs/faq.md +5 -18
- package/src/modules/bmm/docs/glossary.md +3 -4
- package/src/modules/bmm/docs/images/README.md +1 -1
- package/src/modules/bmm/docs/images/workflow-method-greenfield.excalidraw +8 -8
- package/src/modules/bmm/docs/party-mode.md +3 -3
- package/src/modules/bmm/docs/quick-flow-solo-dev.md +5 -5
- package/src/modules/bmm/docs/quick-spec-flow.md +2 -16
- package/src/modules/bmm/docs/quick-start.md +3 -3
- package/src/modules/bmm/docs/test-architecture.md +15 -23
- package/src/modules/bmm/docs/troubleshooting.md +6 -25
- package/src/modules/bmm/docs/workflow-document-project-reference.md +1 -1
- package/src/modules/bmm/docs/workflows-implementation.md +3 -104
- package/src/modules/bmm/module.yaml +25 -24
- package/src/modules/bmm/testarch/knowledge/overview.md +0 -1
- package/src/modules/bmm/workflows/1-analysis/{product-brief → create-product-brief}/steps/step-01-init.md +1 -1
- package/src/modules/bmm/workflows/1-analysis/{product-brief → create-product-brief}/steps/step-01b-continue.md +1 -1
- package/src/modules/bmm/workflows/1-analysis/{product-brief → create-product-brief}/steps/step-02-vision.md +3 -3
- package/src/modules/bmm/workflows/1-analysis/{product-brief → create-product-brief}/steps/step-03-users.md +3 -3
- package/src/modules/bmm/workflows/1-analysis/{product-brief → create-product-brief}/steps/step-04-metrics.md +3 -3
- package/src/modules/bmm/workflows/1-analysis/{product-brief → create-product-brief}/steps/step-05-scope.md +3 -3
- package/src/modules/bmm/workflows/1-analysis/{product-brief → create-product-brief}/steps/step-06-complete.md +5 -3
- package/src/modules/bmm/workflows/1-analysis/{product-brief → create-product-brief}/workflow.md +2 -2
- package/src/modules/bmm/workflows/1-analysis/research/workflow.md +2 -2
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +4 -4
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +4 -4
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +4 -4
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +4 -4
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +4 -4
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +4 -4
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +4 -4
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +4 -4
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +4 -4
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +4 -4
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +4 -4
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +4 -4
- package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +2 -2
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-01-init.md +1 -1
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-01b-continue.md +1 -1
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-02-discovery.md +3 -3
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-03-success.md +7 -7
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-04-journeys.md +8 -8
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-05-domain.md +12 -12
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-06-innovation.md +12 -12
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-07-project-type.md +10 -10
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-08-scoping.md +7 -7
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-09-functional.md +9 -9
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-10-nonfunctional.md +9 -9
- package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-11-complete.md +1 -1
- package/src/modules/bmm/workflows/2-plan-workflows/prd/workflow.md +2 -2
- package/src/modules/bmm/workflows/3-solutioning/{implementation-readiness → check-implementation-readiness}/steps/step-01-document-discovery.md +1 -1
- package/src/modules/bmm/workflows/3-solutioning/{implementation-readiness → check-implementation-readiness}/steps/step-02-prd-analysis.md +1 -1
- package/src/modules/bmm/workflows/3-solutioning/{implementation-readiness → check-implementation-readiness}/steps/step-03-epic-coverage-validation.md +6 -6
- package/src/modules/bmm/workflows/3-solutioning/{implementation-readiness → check-implementation-readiness}/steps/step-04-ux-alignment.md +1 -1
- package/src/modules/bmm/workflows/3-solutioning/{implementation-readiness → check-implementation-readiness}/steps/step-05-epic-quality-review.md +2 -2
- package/src/modules/bmm/workflows/3-solutioning/{implementation-readiness → check-implementation-readiness}/steps/step-06-final-assessment.md +1 -1
- package/src/modules/bmm/workflows/3-solutioning/{implementation-readiness → check-implementation-readiness}/workflow.md +1 -1
- package/src/modules/bmm/workflows/3-solutioning/{architecture → create-architecture}/steps/step-01-init.md +1 -1
- package/src/modules/bmm/workflows/3-solutioning/{architecture → create-architecture}/steps/step-02-context.md +4 -4
- package/src/modules/bmm/workflows/3-solutioning/{architecture → create-architecture}/steps/step-03-starter.md +4 -4
- package/src/modules/bmm/workflows/3-solutioning/{architecture → create-architecture}/steps/step-04-decisions.md +4 -4
- package/src/modules/bmm/workflows/3-solutioning/{architecture → create-architecture}/steps/step-05-patterns.md +4 -4
- package/src/modules/bmm/workflows/3-solutioning/{architecture → create-architecture}/steps/step-06-structure.md +4 -4
- package/src/modules/bmm/workflows/3-solutioning/{architecture → create-architecture}/steps/step-07-validation.md +4 -4
- package/src/modules/bmm/workflows/3-solutioning/{architecture → create-architecture}/steps/step-08-complete.md +3 -3
- package/src/modules/bmm/workflows/3-solutioning/{architecture → create-architecture}/workflow.md +2 -2
- package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +3 -3
- package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +3 -3
- package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +3 -3
- package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +3 -3
- package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +3 -3
- package/src/modules/bmm/workflows/4-implementation/code-review/instructions.xml +4 -3
- package/src/modules/bmm/workflows/4-implementation/code-review/workflow.yaml +2 -2
- package/src/modules/bmm/workflows/4-implementation/correct-course/checklist.md +1 -1
- package/src/modules/bmm/workflows/4-implementation/correct-course/instructions.md +2 -2
- package/src/modules/bmm/workflows/4-implementation/correct-course/workflow.yaml +2 -2
- package/src/modules/bmm/workflows/4-implementation/create-story/checklist.md +2 -2
- package/src/modules/bmm/workflows/4-implementation/create-story/instructions.xml +5 -5
- package/src/modules/bmm/workflows/4-implementation/create-story/template.md +3 -5
- package/src/modules/bmm/workflows/4-implementation/create-story/workflow.yaml +2 -2
- package/src/modules/bmm/workflows/4-implementation/dev-story/checklist.md +2 -2
- package/src/modules/bmm/workflows/4-implementation/dev-story/instructions.xml +11 -8
- package/src/modules/bmm/workflows/4-implementation/dev-story/workflow.yaml +2 -2
- package/src/modules/bmm/workflows/4-implementation/retrospective/instructions.md +3 -3
- package/src/modules/bmm/workflows/4-implementation/retrospective/workflow.yaml +3 -3
- package/src/modules/bmm/workflows/4-implementation/sprint-planning/instructions.md +15 -22
- package/src/modules/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +4 -5
- package/src/modules/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +2 -2
- package/src/modules/bmm/workflows/4-implementation/sprint-status/instructions.md +90 -35
- package/src/modules/bmm/workflows/4-implementation/sprint-status/workflow.yaml +2 -2
- package/src/modules/bmm/workflows/bmad-quick-flow/create-tech-spec/workflow.yaml +5 -5
- package/src/modules/bmm/workflows/bmad-quick-flow/quick-dev/workflow.yaml +7 -7
- package/src/modules/bmm/workflows/document-project/instructions.md +5 -5
- package/src/modules/bmm/workflows/document-project/workflow.yaml +2 -2
- package/src/modules/bmm/workflows/document-project/workflows/deep-dive.yaml +5 -5
- package/src/modules/bmm/workflows/document-project/workflows/full-scan.yaml +5 -5
- package/src/modules/bmm/workflows/{diagrams → excalidraw-diagrams}/create-dataflow/instructions.md +1 -1
- package/src/modules/bmm/workflows/{diagrams → excalidraw-diagrams}/create-dataflow/workflow.yaml +6 -6
- package/src/modules/bmm/workflows/{diagrams → excalidraw-diagrams}/create-diagram/instructions.md +2 -2
- package/src/modules/bmm/workflows/{diagrams → excalidraw-diagrams}/create-diagram/workflow.yaml +6 -6
- package/src/modules/bmm/workflows/{diagrams → excalidraw-diagrams}/create-flowchart/instructions.md +2 -2
- package/src/modules/bmm/workflows/{diagrams → excalidraw-diagrams}/create-flowchart/workflow.yaml +6 -6
- package/src/modules/bmm/workflows/{diagrams → excalidraw-diagrams}/create-wireframe/instructions.md +1 -1
- package/src/modules/bmm/workflows/{diagrams → excalidraw-diagrams}/create-wireframe/workflow.yaml +6 -6
- package/src/modules/bmm/workflows/generate-project-context/steps/step-01-discover.md +2 -2
- package/src/modules/bmm/workflows/generate-project-context/steps/step-02-generate.md +3 -3
- package/src/modules/bmm/workflows/generate-project-context/steps/step-03-complete.md +2 -2
- package/src/modules/bmm/workflows/generate-project-context/workflow.md +5 -5
- package/src/modules/bmm/workflows/testarch/atdd/instructions.md +2 -2
- package/src/modules/bmm/workflows/testarch/atdd/workflow.yaml +2 -2
- package/src/modules/bmm/workflows/testarch/automate/instructions.md +2 -2
- package/src/modules/bmm/workflows/testarch/automate/workflow.yaml +2 -2
- package/src/modules/bmm/workflows/testarch/ci/instructions.md +1 -1
- package/src/modules/bmm/workflows/testarch/ci/workflow.yaml +2 -2
- package/src/modules/bmm/workflows/testarch/framework/instructions.md +3 -3
- package/src/modules/bmm/workflows/testarch/framework/workflow.yaml +2 -2
- package/src/modules/bmm/workflows/testarch/nfr-assess/instructions.md +1 -1
- package/src/modules/bmm/workflows/testarch/nfr-assess/workflow.yaml +2 -2
- package/src/modules/bmm/workflows/testarch/test-design/instructions.md +3 -3
- package/src/modules/bmm/workflows/testarch/test-design/test-design-template.md +1 -1
- package/src/modules/bmm/workflows/testarch/test-design/workflow.yaml +10 -4
- package/src/modules/bmm/workflows/testarch/test-review/instructions.md +1 -1
- package/src/modules/bmm/workflows/testarch/test-review/workflow.yaml +2 -2
- package/src/modules/bmm/workflows/testarch/trace/instructions.md +6 -6
- package/src/modules/bmm/workflows/testarch/trace/workflow.yaml +2 -2
- package/src/modules/bmm/workflows/workflow-status/init/instructions.md +1 -1
- package/src/modules/bmm/workflows/workflow-status/init/workflow.yaml +4 -4
- package/src/modules/bmm/workflows/workflow-status/instructions.md +3 -3
- package/src/modules/bmm/workflows/workflow-status/project-levels.yaml +1 -1
- package/src/modules/bmm/workflows/workflow-status/workflow.yaml +2 -2
- package/src/modules/cis/agents/brainstorming-coach.agent.yaml +4 -4
- package/src/modules/cis/agents/creative-problem-solver.agent.yaml +4 -4
- package/src/modules/cis/agents/design-thinking-coach.agent.yaml +4 -4
- package/src/modules/cis/agents/innovation-strategist.agent.yaml +4 -4
- package/src/modules/cis/agents/presentation-master.agent.yaml +3 -3
- 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.agent.yaml → storyteller/storyteller.agent.yaml} +9 -4
- package/src/modules/cis/module.yaml +3 -8
- package/src/modules/cis/{README.md → readme.md} +1 -1
- package/src/modules/cis/workflows/README.md +1 -1
- package/src/modules/cis/workflows/design-thinking/instructions.md +2 -2
- package/src/modules/cis/workflows/design-thinking/workflow.yaml +7 -7
- package/src/modules/cis/workflows/innovation-strategy/instructions.md +2 -2
- package/src/modules/cis/workflows/innovation-strategy/workflow.yaml +7 -7
- package/src/modules/cis/workflows/problem-solving/instructions.md +2 -2
- package/src/modules/cis/workflows/problem-solving/workflow.yaml +7 -7
- package/src/modules/cis/workflows/storytelling/instructions.md +2 -2
- package/src/modules/cis/workflows/storytelling/workflow.yaml +7 -7
- 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/{templates → agent-components}/agent.customize.template.yaml +0 -1
- 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 +1 -1
- package/test/test-agent-schema.js +2 -2
- package/tools/cli/README.md +1 -607
- package/tools/cli/commands/build.js +7 -7
- package/tools/cli/commands/install.js +9 -20
- package/tools/cli/commands/list.js +13 -1
- package/tools/cli/installers/lib/core/config-collector.js +243 -73
- package/tools/cli/installers/lib/core/custom-module-cache.js +36 -16
- package/tools/cli/installers/lib/core/dependency-resolver.js +2 -2
- package/tools/cli/installers/lib/core/detector.js +16 -16
- package/tools/cli/installers/lib/core/ide-config-manager.js +9 -7
- package/tools/cli/installers/lib/core/installer.js +595 -1006
- package/tools/cli/installers/lib/core/manifest-generator.js +43 -40
- package/tools/cli/installers/lib/core/manifest.js +23 -20
- package/tools/cli/installers/lib/custom/handler.js +16 -49
- package/tools/cli/installers/lib/ide/_base-ide.js +26 -33
- package/tools/cli/installers/lib/ide/antigravity.js +3 -3
- package/tools/cli/installers/lib/ide/claude-code.js +3 -3
- package/tools/cli/installers/lib/ide/codex.js +2 -2
- package/tools/cli/installers/lib/ide/gemini.js +6 -6
- package/tools/cli/installers/lib/ide/kiro-cli.js +2 -2
- package/tools/cli/installers/lib/ide/opencode.js +2 -2
- package/tools/cli/installers/lib/ide/roo.js +15 -5
- package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +2 -2
- package/tools/cli/installers/lib/ide/shared/module-injections.js +2 -2
- package/tools/cli/installers/lib/ide/shared/task-tool-command-generator.js +2 -2
- package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +4 -4
- package/tools/cli/installers/lib/ide/templates/agent-command-template.md +1 -1
- package/tools/cli/installers/lib/ide/templates/gemini-agent-command.toml +3 -3
- package/tools/cli/installers/lib/ide/templates/gemini-task-command.toml +3 -3
- package/tools/cli/installers/lib/ide/templates/workflow-command-template.md +1 -1
- package/tools/cli/installers/lib/modules/manager.js +304 -313
- package/tools/cli/lib/activation-builder.js +8 -13
- package/tools/cli/lib/agent/compiler.js +68 -168
- package/tools/cli/lib/agent/installer.js +8 -128
- package/tools/cli/lib/agent-analyzer.js +2 -2
- package/tools/cli/lib/agent-party-generator.js +5 -17
- package/tools/cli/lib/config.js +2 -2
- package/tools/cli/lib/platform-codes.js +2 -2
- package/tools/cli/lib/ui.js +610 -551
- package/tools/cli/lib/xml-handler.js +3 -55
- package/tools/cli/lib/yaml-format.js +4 -6
- package/tools/cli/lib/yaml-xml-builder.js +14 -26
- package/tools/flattener/ignoreRules.js +1 -1
- package/tools/flattener/xml.js +1 -7
- package/tools/lib/xml-utils.js +13 -0
- package/tools/migrate-custom-module-paths.js +2 -2
- package/tools/validate-agent-schema.js +2 -2
- package/docs/v6-open-items.md +0 -17
- package/example-custom-content/README.md +0 -8
- package/example-custom-module/mwm/README.md +0 -9
- package/example-custom-module/mwm/agents/cbt-coach/cbt-coach-sidecar/cognitive-distortions.md +0 -47
- package/example-custom-module/mwm/agents/cbt-coach/cbt-coach-sidecar/thought-records.md +0 -17
- package/example-custom-module/mwm/agents/cbt-coach/cbt-coach.agent.yaml +0 -151
- package/example-custom-module/mwm/agents/crisis-navigator.agent.yaml +0 -138
- package/example-custom-module/mwm/module.yaml +0 -28
- package/example-custom-module/mwm/workflows/cbt-thought-record/README.md +0 -31
- package/example-custom-module/mwm/workflows/cbt-thought-record/workflow.md +0 -45
- package/example-custom-module/mwm/workflows/crisis-support/README.md +0 -31
- package/example-custom-module/mwm/workflows/crisis-support/workflow.md +0 -45
- package/src/core/agents/bmad-web-orchestrator.agent.xml +0 -113
- package/src/modules/bmb/_module-installer/installer.js +0 -76
- package/src/modules/bmb/docs/agents/module-agent-architecture.md +0 -367
- package/src/modules/bmb/workflows/create-agent/steps/step-08-setup.md +0 -179
- package/src/modules/bmb/workflows/create-agent/steps/step-09-customize.md +0 -197
- package/src/modules/bmb/workflows/create-agent/steps/step-10-build-tools.md +0 -180
- package/src/modules/bmb/workflows/create-agent/templates/agent_commands.md +0 -21
- package/src/modules/bmb/workflows/create-agent/templates/agent_persona.md +0 -25
- package/src/modules/bmb/workflows/create-agent/templates/agent_purpose_and_type.md +0 -23
- package/src/modules/bmm/tasks/daily-standup.xml +0 -85
- package/src/modules/cis/agents/README.md +0 -104
- package/src/utility/models/action-command-header.md +0 -0
- package/src/utility/models/agent-activation-ide.xml +0 -51
- package/src/utility/models/agent-activation-web.xml +0 -50
- package/src/utility/models/agent-command-header.md +0 -1
- 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 -7
- package/src/utility/models/fragments/activation-steps.xml +0 -16
- package/src/utility/models/fragments/handler-action.xml +0 -4
- package/src/utility/models/fragments/handler-exec.xml +0 -6
- package/src/utility/models/fragments/handler-multi.xml +0 -14
- 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/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 -1764
- package/tools/cli/installers/lib/core/post-install-sidecar-replacement.js +0 -79
- 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/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/agents/toolsmith/toolsmith-sidecar/instructions.md +0 -0
- /package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/agents/toolsmith/toolsmith-sidecar/knowledge/bundlers.md +0 -0
- /package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/agents/toolsmith/toolsmith-sidecar/knowledge/deploy.md +0 -0
- /package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/agents/toolsmith/toolsmith-sidecar/knowledge/docs.md +0 -0
- /package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/agents/toolsmith/toolsmith-sidecar/knowledge/installers.md +0 -0
- /package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/agents/toolsmith/toolsmith-sidecar/knowledge/modules.md +0 -0
- /package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/agents/toolsmith/toolsmith-sidecar/knowledge/tests.md +0 -0
- /package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/agents/toolsmith/toolsmith-sidecar/memories.md +0 -0
- /package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/workflows/quiz-master/templates/csv-headers.template +0 -0
- /package/{example-custom-content → docs/sample-custom-modules/sample-unitary-module}/workflows/wassup/workflow.md +0 -0
- /package/{example-custom-module/mwm → docs/sample-custom-modules/sample-wellness-module}/agents/wellness-companion/wellness-companion-sidecar/insights.md +0 -0
- /package/{example-custom-module/mwm → docs/sample-custom-modules/sample-wellness-module}/agents/wellness-companion/wellness-companion-sidecar/instructions.md +0 -0
- /package/{example-custom-module/mwm → docs/sample-custom-modules/sample-wellness-module}/agents/wellness-companion/wellness-companion-sidecar/memories.md +0 -0
- /package/{example-custom-module/mwm → docs/sample-custom-modules/sample-wellness-module}/agents/wellness-companion/wellness-companion-sidecar/patterns.md +0 -0
- /package/{example-custom-module/mwm → docs/sample-custom-modules/sample-wellness-module}/workflows/daily-checkin/README.md +0 -0
- /package/{example-custom-module/mwm → docs/sample-custom-modules/sample-wellness-module}/workflows/daily-checkin/workflow.md +0 -0
- /package/{example-custom-module/mwm → docs/sample-custom-modules/sample-wellness-module}/workflows/guided-meditation/README.md +0 -0
- /package/{example-custom-module/mwm → docs/sample-custom-modules/sample-wellness-module}/workflows/guided-meditation/workflow.md +0 -0
- /package/{example-custom-module/mwm → docs/sample-custom-modules/sample-wellness-module}/workflows/wellness-journal/README.md +0 -0
- /package/src/modules/bmgd/workflows/4-production/code-review/{backlog_template.md → backlog-template.md} +0 -0
- /package/src/modules/bmm/workflows/1-analysis/{product-brief → create-product-brief}/product-brief.template.md +0 -0
- /package/src/modules/bmm/workflows/3-solutioning/{implementation-readiness → check-implementation-readiness}/templates/readiness-report-template.md +0 -0
- /package/src/modules/bmm/workflows/3-solutioning/{architecture → create-architecture}/architecture-decision-template.md +0 -0
- /package/src/modules/bmm/workflows/3-solutioning/{architecture → create-architecture}/data/domain-complexity.csv +0 -0
- /package/src/modules/bmm/workflows/3-solutioning/{architecture → create-architecture}/data/project-types.csv +0 -0
- /package/src/modules/bmm/workflows/3-solutioning/{architecture → create-architecture}/steps/step-01b-continue.md +0 -0
- /package/src/modules/bmm/workflows/{diagrams → excalidraw-diagrams}/_shared/excalidraw-library.json +0 -0
- /package/src/modules/bmm/workflows/{diagrams → excalidraw-diagrams}/_shared/excalidraw-templates.yaml +0 -0
- /package/src/modules/bmm/workflows/{diagrams → excalidraw-diagrams}/create-dataflow/checklist.md +0 -0
- /package/src/modules/bmm/workflows/{diagrams → excalidraw-diagrams}/create-diagram/checklist.md +0 -0
- /package/src/modules/bmm/workflows/{diagrams → excalidraw-diagrams}/create-flowchart/checklist.md +0 -0
- /package/src/modules/bmm/workflows/{diagrams → excalidraw-diagrams}/create-wireframe/checklist.md +0 -0
- /package/src/utility/{models/fragments/handler-data.xml → agent-components/handler-data.txt} +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
const path = require('node:path');
|
|
2
2
|
const fs = require('fs-extra');
|
|
3
|
-
const yaml = require('
|
|
3
|
+
const yaml = require('yaml');
|
|
4
4
|
const chalk = require('chalk');
|
|
5
5
|
const { XmlHandler } = require('../../../lib/xml-handler');
|
|
6
6
|
const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
|
|
7
|
+
const { filterCustomizationData } = require('../../../lib/agent/compiler');
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Manages the installation, updating, and removal of BMAD modules.
|
|
@@ -12,7 +13,7 @@ const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/p
|
|
|
12
13
|
*
|
|
13
14
|
* @class ModuleManager
|
|
14
15
|
* @requires fs-extra
|
|
15
|
-
* @requires
|
|
16
|
+
* @requires yaml
|
|
16
17
|
* @requires chalk
|
|
17
18
|
* @requires XmlHandler
|
|
18
19
|
*
|
|
@@ -27,7 +28,7 @@ class ModuleManager {
|
|
|
27
28
|
this.modulesSourcePath = getSourcePath('modules');
|
|
28
29
|
this.xmlHandler = new XmlHandler();
|
|
29
30
|
this.bmadFolderName = 'bmad'; // Default, can be overridden
|
|
30
|
-
this.
|
|
31
|
+
this.customModulePaths = new Map(); // Initialize custom module paths
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
/**
|
|
@@ -47,50 +48,30 @@ class ModuleManager {
|
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
/**
|
|
50
|
-
*
|
|
51
|
+
* Set custom module paths for priority lookup
|
|
52
|
+
* @param {Map<string, string>} customModulePaths - Map of module ID to source path
|
|
53
|
+
*/
|
|
54
|
+
setCustomModulePaths(customModulePaths) {
|
|
55
|
+
this.customModulePaths = customModulePaths;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Copy a file to the target location
|
|
51
60
|
* @param {string} sourcePath - Source file path
|
|
52
61
|
* @param {string} targetPath - Target file path
|
|
62
|
+
* @param {boolean} overwrite - Whether to overwrite existing files (default: true)
|
|
53
63
|
*/
|
|
54
|
-
async copyFileWithPlaceholderReplacement(sourcePath, targetPath) {
|
|
55
|
-
|
|
56
|
-
const textExtensions = ['.md', '.yaml', '.yml', '.txt', '.json', '.js', '.ts', '.html', '.css', '.sh', '.bat', '.csv'];
|
|
57
|
-
const ext = path.extname(sourcePath).toLowerCase();
|
|
58
|
-
|
|
59
|
-
// Check if this is a text file that might contain placeholders
|
|
60
|
-
if (textExtensions.includes(ext)) {
|
|
61
|
-
try {
|
|
62
|
-
// Read the file content
|
|
63
|
-
let content = await fs.readFile(sourcePath, 'utf8');
|
|
64
|
-
|
|
65
|
-
// Replace escape sequence {*bmad_folder*} with literal {bmad_folder}
|
|
66
|
-
if (content.includes('{*bmad_folder*}')) {
|
|
67
|
-
content = content.replaceAll('{*bmad_folder*}', '{bmad_folder}');
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Replace {bmad_folder} placeholder with actual folder name
|
|
71
|
-
if (content.includes('{bmad_folder}')) {
|
|
72
|
-
content = content.replaceAll('{bmad_folder}', this.bmadFolderName);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Write to target with replaced content
|
|
76
|
-
await fs.ensureDir(path.dirname(targetPath));
|
|
77
|
-
await fs.writeFile(targetPath, content, 'utf8');
|
|
78
|
-
} catch {
|
|
79
|
-
// If reading as text fails (might be binary despite extension), fall back to regular copy
|
|
80
|
-
await fs.copy(sourcePath, targetPath, { overwrite: true });
|
|
81
|
-
}
|
|
82
|
-
} else {
|
|
83
|
-
// Binary file or other file type - just copy directly
|
|
84
|
-
await fs.copy(sourcePath, targetPath, { overwrite: true });
|
|
85
|
-
}
|
|
64
|
+
async copyFileWithPlaceholderReplacement(sourcePath, targetPath, overwrite = true) {
|
|
65
|
+
await fs.copy(sourcePath, targetPath, { overwrite });
|
|
86
66
|
}
|
|
87
67
|
|
|
88
68
|
/**
|
|
89
|
-
* Copy a directory recursively
|
|
69
|
+
* Copy a directory recursively
|
|
90
70
|
* @param {string} sourceDir - Source directory path
|
|
91
71
|
* @param {string} targetDir - Target directory path
|
|
72
|
+
* @param {boolean} overwrite - Whether to overwrite existing files (default: true)
|
|
92
73
|
*/
|
|
93
|
-
async copyDirectoryWithPlaceholderReplacement(sourceDir, targetDir) {
|
|
74
|
+
async copyDirectoryWithPlaceholderReplacement(sourceDir, targetDir, overwrite = true) {
|
|
94
75
|
await fs.ensureDir(targetDir);
|
|
95
76
|
const entries = await fs.readdir(sourceDir, { withFileTypes: true });
|
|
96
77
|
|
|
@@ -99,81 +80,108 @@ class ModuleManager {
|
|
|
99
80
|
const targetPath = path.join(targetDir, entry.name);
|
|
100
81
|
|
|
101
82
|
if (entry.isDirectory()) {
|
|
102
|
-
await this.copyDirectoryWithPlaceholderReplacement(sourcePath, targetPath);
|
|
83
|
+
await this.copyDirectoryWithPlaceholderReplacement(sourcePath, targetPath, overwrite);
|
|
103
84
|
} else {
|
|
104
|
-
await this.copyFileWithPlaceholderReplacement(sourcePath, targetPath);
|
|
85
|
+
await this.copyFileWithPlaceholderReplacement(sourcePath, targetPath, overwrite);
|
|
105
86
|
}
|
|
106
87
|
}
|
|
107
88
|
}
|
|
108
89
|
|
|
109
90
|
/**
|
|
110
|
-
*
|
|
111
|
-
* @
|
|
91
|
+
* Copy sidecar directory to _bmad/_memory location with update-safe handling
|
|
92
|
+
* @param {string} sourceSidecarPath - Source sidecar directory path
|
|
93
|
+
* @param {string} agentName - Name of the agent (for naming)
|
|
94
|
+
* @param {string} bmadMemoryPath - This should ALWAYS be _bmad/_memory
|
|
95
|
+
* @param {boolean} isUpdate - Whether this is an update (default: false)
|
|
96
|
+
* @param {string} bmadDir - BMAD installation directory
|
|
97
|
+
* @param {Object} installer - Installer instance for file tracking
|
|
112
98
|
*/
|
|
113
|
-
async
|
|
114
|
-
const
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
99
|
+
async copySidecarToMemory(sourceSidecarPath, agentName, bmadMemoryPath, isUpdate = false, bmadDir = null, installer = null) {
|
|
100
|
+
const crypto = require('node:crypto');
|
|
101
|
+
const sidecarTargetDir = path.join(bmadMemoryPath, `${agentName}-sidecar`);
|
|
102
|
+
|
|
103
|
+
// Ensure target directory exists
|
|
104
|
+
await fs.ensureDir(bmadMemoryPath);
|
|
105
|
+
await fs.ensureDir(sidecarTargetDir);
|
|
106
|
+
|
|
107
|
+
// Get existing files manifest for update checking
|
|
108
|
+
let existingFilesManifest = [];
|
|
109
|
+
if (isUpdate && installer) {
|
|
110
|
+
existingFilesManifest = await installer.readFilesManifest(bmadDir);
|
|
111
|
+
}
|
|
124
112
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
) {
|
|
133
|
-
continue;
|
|
134
|
-
}
|
|
113
|
+
// Build map of existing sidecar files with their hashes
|
|
114
|
+
const existingSidecarFiles = new Map();
|
|
115
|
+
for (const fileEntry of existingFilesManifest) {
|
|
116
|
+
if (fileEntry.path && fileEntry.path.includes(`${agentName}-sidecar/`)) {
|
|
117
|
+
existingSidecarFiles.set(fileEntry.path, fileEntry.hash);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
135
120
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
121
|
+
// Get all files in source sidecar
|
|
122
|
+
const sourceFiles = await this.getFileList(sourceSidecarPath);
|
|
140
123
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
124
|
+
for (const file of sourceFiles) {
|
|
125
|
+
const sourceFilePath = path.join(sourceSidecarPath, file);
|
|
126
|
+
const targetFilePath = path.join(sidecarTargetDir, file);
|
|
127
|
+
|
|
128
|
+
// Calculate current source file hash
|
|
129
|
+
const sourceHash = crypto
|
|
130
|
+
.createHash('sha256')
|
|
131
|
+
.update(await fs.readFile(sourceFilePath))
|
|
132
|
+
.digest('hex');
|
|
133
|
+
|
|
134
|
+
// Path relative to bmad directory
|
|
135
|
+
const relativeToBmad = path.join('_memory', `${agentName}-sidecar`, file);
|
|
136
|
+
|
|
137
|
+
if (isUpdate && (await fs.pathExists(targetFilePath))) {
|
|
138
|
+
// Calculate current target file hash
|
|
139
|
+
const currentTargetHash = crypto
|
|
140
|
+
.createHash('sha256')
|
|
141
|
+
.update(await fs.readFile(targetFilePath))
|
|
142
|
+
.digest('hex');
|
|
143
|
+
|
|
144
|
+
// Get the last known hash from files-manifest
|
|
145
|
+
const lastKnownHash = existingSidecarFiles.get(relativeToBmad);
|
|
146
|
+
|
|
147
|
+
if (lastKnownHash) {
|
|
148
|
+
// We have a record of this file
|
|
149
|
+
if (currentTargetHash === lastKnownHash) {
|
|
150
|
+
// File hasn't been modified by user, safe to update
|
|
151
|
+
await this.copyFileWithPlaceholderReplacement(sourceFilePath, targetFilePath, true);
|
|
152
|
+
if (process.env.BMAD_VERBOSE_INSTALL === 'true') {
|
|
153
|
+
console.log(chalk.dim(` Updated sidecar file: ${relativeToBmad}`));
|
|
145
154
|
}
|
|
146
|
-
|
|
147
|
-
//
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const customConfigPath = path.join(fullPath, '_module-installer', 'custom.yaml');
|
|
151
|
-
const rootCustomConfigPath = path.join(fullPath, 'custom.yaml');
|
|
152
|
-
|
|
153
|
-
if (
|
|
154
|
-
(await fs.pathExists(moduleConfigPath)) ||
|
|
155
|
-
(await fs.pathExists(installerConfigPath)) ||
|
|
156
|
-
(await fs.pathExists(customConfigPath)) ||
|
|
157
|
-
(await fs.pathExists(rootCustomConfigPath))
|
|
158
|
-
) {
|
|
159
|
-
modulePaths.add(fullPath);
|
|
160
|
-
// Don't scan inside modules - they might have their own nested structures
|
|
161
|
-
continue;
|
|
155
|
+
} else {
|
|
156
|
+
// User has modified the file, preserve it
|
|
157
|
+
if (process.env.BMAD_VERBOSE_INSTALL === 'true') {
|
|
158
|
+
console.log(chalk.dim(` Preserving user-modified file: ${relativeToBmad}`));
|
|
162
159
|
}
|
|
163
|
-
|
|
164
|
-
// Recursively scan subdirectories
|
|
165
|
-
await scanDirectory(fullPath, excludePaths);
|
|
166
160
|
}
|
|
161
|
+
} else {
|
|
162
|
+
// First time seeing this file in manifest, copy it
|
|
163
|
+
await this.copyFileWithPlaceholderReplacement(sourceFilePath, targetFilePath, true);
|
|
164
|
+
if (process.env.BMAD_VERBOSE_INSTALL === 'true') {
|
|
165
|
+
console.log(chalk.dim(` Added new sidecar file: ${relativeToBmad}`));
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
} else {
|
|
169
|
+
// New installation
|
|
170
|
+
await this.copyFileWithPlaceholderReplacement(sourceFilePath, targetFilePath, true);
|
|
171
|
+
if (process.env.BMAD_VERBOSE_INSTALL === 'true') {
|
|
172
|
+
console.log(chalk.dim(` Copied sidecar file: ${relativeToBmad}`));
|
|
167
173
|
}
|
|
168
|
-
} catch {
|
|
169
|
-
// Ignore errors (e.g., permission denied)
|
|
170
174
|
}
|
|
171
|
-
}
|
|
172
175
|
|
|
173
|
-
|
|
174
|
-
|
|
176
|
+
// Track the file in the installer's file tracking system
|
|
177
|
+
if (installer && installer.installedFiles) {
|
|
178
|
+
installer.installedFiles.add(targetFilePath);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
175
181
|
|
|
176
|
-
|
|
182
|
+
// Return list of files that were processed
|
|
183
|
+
const processedFiles = sourceFiles.map((file) => path.join('_memory', `${agentName}-sidecar`, file));
|
|
184
|
+
return processedFiles;
|
|
177
185
|
}
|
|
178
186
|
|
|
179
187
|
/**
|
|
@@ -218,43 +226,19 @@ class ModuleManager {
|
|
|
218
226
|
}
|
|
219
227
|
}
|
|
220
228
|
|
|
221
|
-
//
|
|
222
|
-
if (this.
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
const
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
if (moduleInfo && !modules.some((m) => m.id === moduleInfo.id) && !customModules.some((m) => m.id === moduleInfo.id)) {
|
|
235
|
-
// Avoid duplicates - skip if we already have this module ID
|
|
236
|
-
if (moduleInfo.isCustom) {
|
|
237
|
-
customModules.push(moduleInfo);
|
|
238
|
-
} else {
|
|
239
|
-
modules.push(moduleInfo);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Also check for cached custom modules in _cfg/custom/
|
|
245
|
-
if (this.bmadDir) {
|
|
246
|
-
const customCacheDir = path.join(this.bmadDir, '_cfg', 'custom');
|
|
247
|
-
if (await fs.pathExists(customCacheDir)) {
|
|
248
|
-
const cacheEntries = await fs.readdir(customCacheDir, { withFileTypes: true });
|
|
249
|
-
for (const entry of cacheEntries) {
|
|
250
|
-
if (entry.isDirectory()) {
|
|
251
|
-
const cachePath = path.join(customCacheDir, entry.name);
|
|
252
|
-
const moduleInfo = await this.getModuleInfo(cachePath, entry.name, '_cfg/custom');
|
|
253
|
-
if (moduleInfo && !modules.some((m) => m.id === moduleInfo.id) && !customModules.some((m) => m.id === moduleInfo.id)) {
|
|
254
|
-
moduleInfo.isCustom = true;
|
|
255
|
-
moduleInfo.fromCache = true;
|
|
256
|
-
customModules.push(moduleInfo);
|
|
257
|
-
}
|
|
229
|
+
// Check for cached custom modules in _config/custom/
|
|
230
|
+
if (this.bmadDir) {
|
|
231
|
+
const customCacheDir = path.join(this.bmadDir, '_config', 'custom');
|
|
232
|
+
if (await fs.pathExists(customCacheDir)) {
|
|
233
|
+
const cacheEntries = await fs.readdir(customCacheDir, { withFileTypes: true });
|
|
234
|
+
for (const entry of cacheEntries) {
|
|
235
|
+
if (entry.isDirectory()) {
|
|
236
|
+
const cachePath = path.join(customCacheDir, entry.name);
|
|
237
|
+
const moduleInfo = await this.getModuleInfo(cachePath, entry.name, '_config/custom');
|
|
238
|
+
if (moduleInfo && !modules.some((m) => m.id === moduleInfo.id) && !customModules.some((m) => m.id === moduleInfo.id)) {
|
|
239
|
+
moduleInfo.isCustom = true;
|
|
240
|
+
moduleInfo.fromCache = true;
|
|
241
|
+
customModules.push(moduleInfo);
|
|
258
242
|
}
|
|
259
243
|
}
|
|
260
244
|
}
|
|
@@ -312,7 +296,7 @@ class ModuleManager {
|
|
|
312
296
|
// Read module config for metadata
|
|
313
297
|
try {
|
|
314
298
|
const configContent = await fs.readFile(configPath, 'utf8');
|
|
315
|
-
const config = yaml.
|
|
299
|
+
const config = yaml.parse(configContent);
|
|
316
300
|
|
|
317
301
|
// Use the code property as the id if available
|
|
318
302
|
if (config.code) {
|
|
@@ -333,66 +317,50 @@ class ModuleManager {
|
|
|
333
317
|
|
|
334
318
|
/**
|
|
335
319
|
* Find the source path for a module by searching all possible locations
|
|
336
|
-
* @param {string}
|
|
320
|
+
* @param {string} moduleCode - Code of the module to find (from module.yaml)
|
|
337
321
|
* @returns {string|null} Path to the module source or null if not found
|
|
338
322
|
*/
|
|
339
|
-
async findModuleSource(
|
|
323
|
+
async findModuleSource(moduleCode) {
|
|
340
324
|
const projectRoot = getProjectRoot();
|
|
341
325
|
|
|
342
|
-
// First
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
// Check if this looks like a module (has module.yaml)
|
|
346
|
-
const moduleConfigPath = path.join(srcModulePath, 'module.yaml');
|
|
347
|
-
const installerConfigPath = path.join(srcModulePath, '_module-installer', 'module.yaml');
|
|
348
|
-
|
|
349
|
-
if ((await fs.pathExists(moduleConfigPath)) || (await fs.pathExists(installerConfigPath))) {
|
|
350
|
-
return srcModulePath;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
// Also check for custom.yaml in src/modules/_module-installer
|
|
354
|
-
const customConfigPath = path.join(srcModulePath, '_module-installer', 'custom.yaml');
|
|
355
|
-
if (await fs.pathExists(customConfigPath)) {
|
|
356
|
-
return srcModulePath;
|
|
357
|
-
}
|
|
326
|
+
// First check custom module paths if they exist
|
|
327
|
+
if (this.customModulePaths && this.customModulePaths.has(moduleCode)) {
|
|
328
|
+
return this.customModulePaths.get(moduleCode);
|
|
358
329
|
}
|
|
359
330
|
|
|
360
|
-
//
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
}
|
|
331
|
+
// Search in src/modules by READING module.yaml files to match by code
|
|
332
|
+
if (await fs.pathExists(this.modulesSourcePath)) {
|
|
333
|
+
const entries = await fs.readdir(this.modulesSourcePath, { withFileTypes: true });
|
|
334
|
+
for (const entry of entries) {
|
|
335
|
+
if (entry.isDirectory()) {
|
|
336
|
+
const modulePath = path.join(this.modulesSourcePath, entry.name);
|
|
367
337
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
const installerConfigPath = path.join(modulePath, '_module-installer', 'module.yaml');
|
|
373
|
-
const customConfigPath = path.join(modulePath, '_module-installer', 'custom.yaml');
|
|
374
|
-
const rootCustomConfigPath = path.join(modulePath, 'custom.yaml');
|
|
375
|
-
|
|
376
|
-
let configPath = null;
|
|
377
|
-
if (await fs.pathExists(moduleConfigPath)) {
|
|
378
|
-
configPath = moduleConfigPath;
|
|
379
|
-
} else if (await fs.pathExists(installerConfigPath)) {
|
|
380
|
-
configPath = installerConfigPath;
|
|
381
|
-
} else if (await fs.pathExists(customConfigPath)) {
|
|
382
|
-
configPath = customConfigPath;
|
|
383
|
-
} else if (await fs.pathExists(rootCustomConfigPath)) {
|
|
384
|
-
configPath = rootCustomConfigPath;
|
|
385
|
-
}
|
|
338
|
+
// Read module.yaml to get the code
|
|
339
|
+
const moduleConfigPath = path.join(modulePath, 'module.yaml');
|
|
340
|
+
const installerConfigPath = path.join(modulePath, '_module-installer', 'module.yaml');
|
|
341
|
+
const customConfigPath = path.join(modulePath, '_module-installer', 'custom.yaml');
|
|
386
342
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
343
|
+
let configPath = null;
|
|
344
|
+
if (await fs.pathExists(moduleConfigPath)) {
|
|
345
|
+
configPath = moduleConfigPath;
|
|
346
|
+
} else if (await fs.pathExists(installerConfigPath)) {
|
|
347
|
+
configPath = installerConfigPath;
|
|
348
|
+
} else if (await fs.pathExists(customConfigPath)) {
|
|
349
|
+
configPath = customConfigPath;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
if (configPath) {
|
|
353
|
+
try {
|
|
354
|
+
const configContent = await fs.readFile(configPath, 'utf8');
|
|
355
|
+
const config = yaml.parse(configContent);
|
|
356
|
+
if (config.code === moduleCode) {
|
|
357
|
+
return modulePath;
|
|
358
|
+
}
|
|
359
|
+
} catch (error) {
|
|
360
|
+
// Continue to next module if parse fails
|
|
361
|
+
console.warn(`Warning: Failed to parse module config at ${configPath}: ${error.message}`);
|
|
362
|
+
}
|
|
393
363
|
}
|
|
394
|
-
} catch {
|
|
395
|
-
// Skip if can't read config
|
|
396
364
|
}
|
|
397
365
|
}
|
|
398
366
|
}
|
|
@@ -402,7 +370,7 @@ class ModuleManager {
|
|
|
402
370
|
|
|
403
371
|
/**
|
|
404
372
|
* Install a module
|
|
405
|
-
* @param {string} moduleName -
|
|
373
|
+
* @param {string} moduleName - Code of the module to install (from module.yaml)
|
|
406
374
|
* @param {string} bmadDir - Target bmad directory
|
|
407
375
|
* @param {Function} fileTrackingCallback - Optional callback to track installed files
|
|
408
376
|
* @param {Object} options - Additional installation options
|
|
@@ -416,7 +384,10 @@ class ModuleManager {
|
|
|
416
384
|
|
|
417
385
|
// Check if source module exists
|
|
418
386
|
if (!sourcePath) {
|
|
419
|
-
|
|
387
|
+
// Provide a more user-friendly error message
|
|
388
|
+
throw new Error(
|
|
389
|
+
`Source for module '${moduleName}' is not available. It will be retained but cannot be updated without its source files.`,
|
|
390
|
+
);
|
|
420
391
|
}
|
|
421
392
|
|
|
422
393
|
// Check if this is a custom module and read its custom.yaml values
|
|
@@ -427,14 +398,14 @@ class ModuleManager {
|
|
|
427
398
|
if (await fs.pathExists(rootCustomConfigPath)) {
|
|
428
399
|
try {
|
|
429
400
|
const customContent = await fs.readFile(rootCustomConfigPath, 'utf8');
|
|
430
|
-
customConfig = yaml.
|
|
401
|
+
customConfig = yaml.parse(customContent);
|
|
431
402
|
} catch (error) {
|
|
432
403
|
console.warn(chalk.yellow(`Warning: Failed to read custom.yaml for ${moduleName}:`, error.message));
|
|
433
404
|
}
|
|
434
405
|
} else if (await fs.pathExists(moduleInstallerCustomPath)) {
|
|
435
406
|
try {
|
|
436
407
|
const customContent = await fs.readFile(moduleInstallerCustomPath, 'utf8');
|
|
437
|
-
customConfig = yaml.
|
|
408
|
+
customConfig = yaml.parse(customContent);
|
|
438
409
|
} catch (error) {
|
|
439
410
|
console.warn(chalk.yellow(`Warning: Failed to read custom.yaml for ${moduleName}:`, error.message));
|
|
440
411
|
}
|
|
@@ -450,7 +421,6 @@ class ModuleManager {
|
|
|
450
421
|
|
|
451
422
|
// Check if already installed
|
|
452
423
|
if (await fs.pathExists(targetPath)) {
|
|
453
|
-
console.log(chalk.yellow(`Module '${moduleName}' already installed, updating...`));
|
|
454
424
|
await fs.remove(targetPath);
|
|
455
425
|
}
|
|
456
426
|
|
|
@@ -462,7 +432,7 @@ class ModuleManager {
|
|
|
462
432
|
await this.copyModuleWithFiltering(sourcePath, targetPath, fileTrackingCallback, options.moduleConfig);
|
|
463
433
|
|
|
464
434
|
// Compile any .agent.yaml files to .md format
|
|
465
|
-
await this.compileModuleAgents(sourcePath, targetPath, moduleName, bmadDir);
|
|
435
|
+
await this.compileModuleAgents(sourcePath, targetPath, moduleName, bmadDir, options.installer);
|
|
466
436
|
|
|
467
437
|
// Process agent files to inject activation block
|
|
468
438
|
await this.processAgentFiles(targetPath, moduleName);
|
|
@@ -506,6 +476,10 @@ class ModuleManager {
|
|
|
506
476
|
} else {
|
|
507
477
|
// Selective update - preserve user modifications
|
|
508
478
|
await this.syncModule(sourcePath, targetPath);
|
|
479
|
+
|
|
480
|
+
// Recompile agents (#1133)
|
|
481
|
+
await this.compileModuleAgents(sourcePath, targetPath, moduleName, bmadDir, options.installer);
|
|
482
|
+
await this.processAgentFiles(targetPath, moduleName);
|
|
509
483
|
}
|
|
510
484
|
|
|
511
485
|
return {
|
|
@@ -569,7 +543,7 @@ class ModuleManager {
|
|
|
569
543
|
if (await fs.pathExists(configPath)) {
|
|
570
544
|
try {
|
|
571
545
|
const configContent = await fs.readFile(configPath, 'utf8');
|
|
572
|
-
const config = yaml.
|
|
546
|
+
const config = yaml.parse(configContent);
|
|
573
547
|
Object.assign(moduleInfo, config);
|
|
574
548
|
} catch (error) {
|
|
575
549
|
console.warn(`Failed to read installed module config:`, error.message);
|
|
@@ -590,29 +564,21 @@ class ModuleManager {
|
|
|
590
564
|
// Get all files in source
|
|
591
565
|
const sourceFiles = await this.getFileList(sourcePath);
|
|
592
566
|
|
|
593
|
-
// Game development files to conditionally exclude
|
|
594
|
-
const gameDevFiles = [
|
|
595
|
-
'agents/game-architect.agent.yaml',
|
|
596
|
-
'agents/game-designer.agent.yaml',
|
|
597
|
-
'agents/game-dev.agent.yaml',
|
|
598
|
-
'workflows/1-analysis/brainstorm-game',
|
|
599
|
-
'workflows/1-analysis/game-brief',
|
|
600
|
-
'workflows/2-plan-workflows/gdd',
|
|
601
|
-
];
|
|
602
|
-
|
|
603
567
|
for (const file of sourceFiles) {
|
|
604
568
|
// Skip sub-modules directory - these are IDE-specific and handled separately
|
|
605
569
|
if (file.startsWith('sub-modules/')) {
|
|
606
570
|
continue;
|
|
607
571
|
}
|
|
608
572
|
|
|
609
|
-
//
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
573
|
+
// Only skip sidecar directories - they are handled separately during agent compilation
|
|
574
|
+
// But still allow other files in agent directories
|
|
575
|
+
const isInAgentDirectory = file.startsWith('agents/');
|
|
576
|
+
const isInSidecarDirectory = path
|
|
577
|
+
.dirname(file)
|
|
578
|
+
.split('/')
|
|
579
|
+
.some((dir) => dir.toLowerCase().endsWith('-sidecar'));
|
|
580
|
+
|
|
581
|
+
if (isInSidecarDirectory) {
|
|
616
582
|
continue;
|
|
617
583
|
}
|
|
618
584
|
|
|
@@ -622,8 +588,7 @@ class ModuleManager {
|
|
|
622
588
|
}
|
|
623
589
|
|
|
624
590
|
// Skip config.yaml templates - we'll generate clean ones with actual values
|
|
625
|
-
|
|
626
|
-
if (file === 'config.yaml' || file.endsWith('/config.yaml') || file === 'custom.yaml' || file.endsWith('/custom.yaml')) {
|
|
591
|
+
if (file === 'config.yaml' || file.endsWith('/config.yaml')) {
|
|
627
592
|
continue;
|
|
628
593
|
}
|
|
629
594
|
|
|
@@ -632,25 +597,6 @@ class ModuleManager {
|
|
|
632
597
|
continue;
|
|
633
598
|
}
|
|
634
599
|
|
|
635
|
-
// Skip user documentation if install_user_docs is false
|
|
636
|
-
if (moduleConfig.install_user_docs === false && (file.startsWith('docs/') || file.startsWith('docs\\'))) {
|
|
637
|
-
console.log(chalk.dim(` Skipping user documentation: ${file}`));
|
|
638
|
-
continue;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
// Skip game development content if include_game_planning is false
|
|
642
|
-
if (moduleConfig.include_game_planning === false) {
|
|
643
|
-
const shouldSkipGameDev = gameDevFiles.some((gamePath) => {
|
|
644
|
-
// Check if file path starts with or is within any game dev directory
|
|
645
|
-
return file === gamePath || file.startsWith(gamePath + '/') || file.startsWith(gamePath + '\\');
|
|
646
|
-
});
|
|
647
|
-
|
|
648
|
-
if (shouldSkipGameDev) {
|
|
649
|
-
console.log(chalk.dim(` Skipping game dev content: ${file}`));
|
|
650
|
-
continue;
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
|
|
654
600
|
const sourceFile = path.join(sourcePath, file);
|
|
655
601
|
const targetFile = path.join(targetPath, file);
|
|
656
602
|
|
|
@@ -695,12 +641,12 @@ class ModuleManager {
|
|
|
695
641
|
|
|
696
642
|
// IMPORTANT: Replace escape sequence and placeholder BEFORE parsing YAML
|
|
697
643
|
// Otherwise parsing will fail on the placeholder
|
|
698
|
-
yamlContent = yamlContent.replaceAll('
|
|
699
|
-
yamlContent = yamlContent.replaceAll('
|
|
644
|
+
yamlContent = yamlContent.replaceAll('_bmad', '_bmad');
|
|
645
|
+
yamlContent = yamlContent.replaceAll('_bmad', this.bmadFolderName);
|
|
700
646
|
|
|
701
647
|
try {
|
|
702
648
|
// First check if web_bundle exists by parsing
|
|
703
|
-
const workflowConfig = yaml.
|
|
649
|
+
const workflowConfig = yaml.parse(yamlContent);
|
|
704
650
|
|
|
705
651
|
if (workflowConfig.web_bundle === undefined) {
|
|
706
652
|
// No web_bundle section, just write (placeholders already replaced above)
|
|
@@ -780,11 +726,12 @@ class ModuleManager {
|
|
|
780
726
|
* @param {string} targetPath - Target module path
|
|
781
727
|
* @param {string} moduleName - Module name
|
|
782
728
|
* @param {string} bmadDir - BMAD installation directory
|
|
729
|
+
* @param {Object} installer - Installer instance for file tracking
|
|
783
730
|
*/
|
|
784
|
-
async compileModuleAgents(sourcePath, targetPath, moduleName, bmadDir) {
|
|
731
|
+
async compileModuleAgents(sourcePath, targetPath, moduleName, bmadDir, installer = null) {
|
|
785
732
|
const sourceAgentsPath = path.join(sourcePath, 'agents');
|
|
786
733
|
const targetAgentsPath = path.join(targetPath, 'agents');
|
|
787
|
-
const cfgAgentsDir = path.join(bmadDir, '
|
|
734
|
+
const cfgAgentsDir = path.join(bmadDir, '_config', 'agents');
|
|
788
735
|
|
|
789
736
|
// Check if agents directory exists in source
|
|
790
737
|
if (!(await fs.pathExists(sourceAgentsPath))) {
|
|
@@ -815,84 +762,133 @@ class ModuleManager {
|
|
|
815
762
|
// Create customize template if it doesn't exist
|
|
816
763
|
if (!(await fs.pathExists(customizePath))) {
|
|
817
764
|
const { getSourcePath } = require('../../../lib/project-root');
|
|
818
|
-
const genericTemplatePath = getSourcePath('utility', '
|
|
765
|
+
const genericTemplatePath = getSourcePath('utility', 'agent-components', 'agent.customize.template.yaml');
|
|
819
766
|
if (await fs.pathExists(genericTemplatePath)) {
|
|
820
767
|
await this.copyFileWithPlaceholderReplacement(genericTemplatePath, customizePath);
|
|
821
|
-
|
|
768
|
+
// Only show customize creation in verbose mode
|
|
769
|
+
if (process.env.BMAD_VERBOSE_INSTALL === 'true') {
|
|
770
|
+
console.log(chalk.dim(` Created customize: ${moduleName}-${agentName}.customize.yaml`));
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
// Store original hash for modification detection
|
|
774
|
+
const crypto = require('node:crypto');
|
|
775
|
+
const customizeContent = await fs.readFile(customizePath, 'utf8');
|
|
776
|
+
const originalHash = crypto.createHash('sha256').update(customizeContent).digest('hex');
|
|
777
|
+
|
|
778
|
+
// Store in main manifest
|
|
779
|
+
const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
|
|
780
|
+
let manifestData = {};
|
|
781
|
+
if (await fs.pathExists(manifestPath)) {
|
|
782
|
+
const manifestContent = await fs.readFile(manifestPath, 'utf8');
|
|
783
|
+
const yaml = require('yaml');
|
|
784
|
+
manifestData = yaml.parse(manifestContent);
|
|
785
|
+
}
|
|
786
|
+
if (!manifestData.agentCustomizations) {
|
|
787
|
+
manifestData.agentCustomizations = {};
|
|
788
|
+
}
|
|
789
|
+
manifestData.agentCustomizations[path.relative(bmadDir, customizePath)] = originalHash;
|
|
790
|
+
|
|
791
|
+
// Write back to manifest
|
|
792
|
+
const yaml = require('yaml');
|
|
793
|
+
// Clean the manifest data to remove any non-serializable values
|
|
794
|
+
const cleanManifestData = structuredClone(manifestData);
|
|
795
|
+
|
|
796
|
+
const updatedContent = yaml.stringify(cleanManifestData, {
|
|
797
|
+
indent: 2,
|
|
798
|
+
lineWidth: 0,
|
|
799
|
+
});
|
|
800
|
+
await fs.writeFile(manifestPath, updatedContent, 'utf8');
|
|
822
801
|
}
|
|
823
802
|
}
|
|
824
803
|
|
|
825
|
-
// Check for customizations
|
|
804
|
+
// Check for customizations and build answers object
|
|
826
805
|
let customizedFields = [];
|
|
806
|
+
let answers = {};
|
|
827
807
|
if (await fs.pathExists(customizePath)) {
|
|
828
808
|
const customizeContent = await fs.readFile(customizePath, 'utf8');
|
|
829
|
-
const customizeData = yaml.
|
|
809
|
+
const customizeData = yaml.parse(customizeContent);
|
|
830
810
|
customizedFields = customizeData.customized_fields || [];
|
|
831
|
-
}
|
|
832
|
-
|
|
833
|
-
// Load core config to get agent_sidecar_folder
|
|
834
|
-
const coreConfigPath = path.join(bmadDir, 'bmb', 'config.yaml');
|
|
835
|
-
let coreConfig = {};
|
|
836
811
|
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
812
|
+
// Build answers object from customizations (filter empty values)
|
|
813
|
+
if (customizeData.persona) {
|
|
814
|
+
Object.assign(answers, filterCustomizationData(customizeData.persona));
|
|
815
|
+
}
|
|
816
|
+
if (customizeData.agent?.metadata) {
|
|
817
|
+
const filteredMetadata = filterCustomizationData(customizeData.agent.metadata);
|
|
818
|
+
if (Object.keys(filteredMetadata).length > 0) {
|
|
819
|
+
Object.assign(answers, { metadata: filteredMetadata });
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
if (customizeData.critical_actions && customizeData.critical_actions.length > 0) {
|
|
823
|
+
answers.critical_actions = customizeData.critical_actions;
|
|
824
|
+
}
|
|
825
|
+
if (customizeData.memories && customizeData.memories.length > 0) {
|
|
826
|
+
answers.memories = customizeData.memories;
|
|
827
|
+
}
|
|
841
828
|
}
|
|
842
829
|
|
|
843
830
|
// Check if agent has sidecar
|
|
844
831
|
let hasSidecar = false;
|
|
845
832
|
try {
|
|
846
|
-
const
|
|
847
|
-
const agentYaml = yamlLib.parse(yamlContent);
|
|
833
|
+
const agentYaml = yaml.parse(yamlContent);
|
|
848
834
|
hasSidecar = agentYaml?.agent?.metadata?.hasSidecar === true;
|
|
849
835
|
} catch {
|
|
850
836
|
// Continue without sidecar processing
|
|
851
837
|
}
|
|
852
838
|
|
|
853
839
|
// Compile with customizations if any
|
|
854
|
-
const { xml } = compileAgent(yamlContent,
|
|
840
|
+
const { xml } = await compileAgent(yamlContent, answers, agentName, relativePath, { config: this.coreConfig || {} });
|
|
855
841
|
|
|
856
|
-
//
|
|
857
|
-
|
|
858
|
-
const processedXml = xml.replaceAll('{bmad_folder}', this.bmadFolderName);
|
|
859
|
-
await fs.writeFile(targetMdPath, processedXml, 'utf8');
|
|
860
|
-
} else {
|
|
861
|
-
await fs.writeFile(targetMdPath, xml, 'utf8');
|
|
862
|
-
}
|
|
842
|
+
// Write the compiled agent
|
|
843
|
+
await fs.writeFile(targetMdPath, xml, 'utf8');
|
|
863
844
|
|
|
864
|
-
//
|
|
845
|
+
// Handle sidecar copying if present
|
|
865
846
|
if (hasSidecar) {
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
const
|
|
847
|
+
// Get the agent's directory to look for sidecar
|
|
848
|
+
const agentDir = path.dirname(agentFile);
|
|
849
|
+
const sidecarDirName = `${agentName}-sidecar`;
|
|
850
|
+
const sourceSidecarPath = path.join(agentDir, sidecarDirName);
|
|
870
851
|
|
|
871
|
-
//
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
.
|
|
875
|
-
.replaceAll('{bmad_folder}', path.basename(bmadDir));
|
|
852
|
+
// Check if sidecar directory exists
|
|
853
|
+
if (await fs.pathExists(sourceSidecarPath)) {
|
|
854
|
+
// Memory is always in _bmad/_memory
|
|
855
|
+
const bmadMemoryPath = path.join(bmadDir, '_memory');
|
|
876
856
|
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
await fs.ensureDir(agentSidecarDir);
|
|
857
|
+
// Determine if this is an update (by checking if agent already exists)
|
|
858
|
+
const isUpdate = await fs.pathExists(targetMdPath);
|
|
880
859
|
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
const totalFiles = sidecarResult.copied.length + sidecarResult.preserved.length;
|
|
860
|
+
// Copy sidecar to memory location with update-safe handling
|
|
861
|
+
const copiedFiles = await this.copySidecarToMemory(sourceSidecarPath, agentName, bmadMemoryPath, isUpdate, bmadDir, installer);
|
|
884
862
|
|
|
885
|
-
|
|
886
|
-
|
|
863
|
+
if (process.env.BMAD_VERBOSE_INSTALL === 'true' && copiedFiles.length > 0) {
|
|
864
|
+
console.log(chalk.dim(` Sidecar files processed: ${copiedFiles.length} files`));
|
|
865
|
+
}
|
|
866
|
+
} else if (process.env.BMAD_VERBOSE_INSTALL === 'true') {
|
|
867
|
+
console.log(chalk.yellow(` Warning: Agent marked as having sidecar but ${sidecarDirName} directory not found`));
|
|
887
868
|
}
|
|
888
|
-
|
|
889
|
-
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
// Copy any non-sidecar files from agent directory (e.g., foo.md)
|
|
872
|
+
const agentDir = path.dirname(agentFile);
|
|
873
|
+
const agentEntries = await fs.readdir(agentDir, { withFileTypes: true });
|
|
874
|
+
|
|
875
|
+
for (const entry of agentEntries) {
|
|
876
|
+
if (entry.isFile() && !entry.name.endsWith('.agent.yaml') && !entry.name.endsWith('.md')) {
|
|
877
|
+
// Copy additional files (like foo.md) to the agent target directory
|
|
878
|
+
const sourceFile = path.join(agentDir, entry.name);
|
|
879
|
+
const targetFile = path.join(targetDir, entry.name);
|
|
880
|
+
await this.copyFileWithPlaceholderReplacement(sourceFile, targetFile);
|
|
890
881
|
}
|
|
891
882
|
}
|
|
892
883
|
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
884
|
+
// Only show compilation details in verbose mode
|
|
885
|
+
if (process.env.BMAD_VERBOSE_INSTALL === 'true') {
|
|
886
|
+
console.log(
|
|
887
|
+
chalk.dim(
|
|
888
|
+
` Compiled agent: ${agentName} -> ${path.relative(targetPath, targetMdPath)}${hasSidecar ? ' (with sidecar)' : ''}`,
|
|
889
|
+
),
|
|
890
|
+
);
|
|
891
|
+
}
|
|
896
892
|
} catch (error) {
|
|
897
893
|
console.warn(chalk.yellow(` Failed to compile agent ${agentName}:`, error.message));
|
|
898
894
|
}
|
|
@@ -931,28 +927,23 @@ class ModuleManager {
|
|
|
931
927
|
* @param {string} moduleName - Module name
|
|
932
928
|
*/
|
|
933
929
|
async processAgentFiles(modulePath, moduleName) {
|
|
934
|
-
const agentsPath = path.join(modulePath, 'agents');
|
|
935
|
-
|
|
936
|
-
//
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
//
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
// Inject the activation block using XML handler
|
|
952
|
-
content = this.xmlHandler.injectActivationSimple(content);
|
|
953
|
-
await fs.writeFile(agentFile, content, 'utf8');
|
|
954
|
-
}
|
|
955
|
-
}
|
|
930
|
+
// const agentsPath = path.join(modulePath, 'agents');
|
|
931
|
+
// // Check if agents directory exists
|
|
932
|
+
// if (!(await fs.pathExists(agentsPath))) {
|
|
933
|
+
// return; // No agents to process
|
|
934
|
+
// }
|
|
935
|
+
// // Get all agent MD files recursively
|
|
936
|
+
// const agentFiles = await this.findAgentMdFiles(agentsPath);
|
|
937
|
+
// for (const agentFile of agentFiles) {
|
|
938
|
+
// if (!agentFile.endsWith('.md')) continue;
|
|
939
|
+
// let content = await fs.readFile(agentFile, 'utf8');
|
|
940
|
+
// // Check if content has agent XML and no activation block
|
|
941
|
+
// if (content.includes('<agent') && !content.includes('<activation')) {
|
|
942
|
+
// // Inject the activation block using XML handler
|
|
943
|
+
// content = this.xmlHandler.injectActivationSimple(content);
|
|
944
|
+
// await fs.writeFile(agentFile, content, 'utf8');
|
|
945
|
+
// }
|
|
946
|
+
// }
|
|
956
947
|
}
|
|
957
948
|
|
|
958
949
|
/**
|
|
@@ -1008,7 +999,7 @@ class ModuleManager {
|
|
|
1008
999
|
|
|
1009
1000
|
for (const agentFile of yamlFiles) {
|
|
1010
1001
|
const agentPath = path.join(sourceAgentsPath, agentFile);
|
|
1011
|
-
const agentYaml = yaml.
|
|
1002
|
+
const agentYaml = yaml.parse(await fs.readFile(agentPath, 'utf8'));
|
|
1012
1003
|
|
|
1013
1004
|
// Check if agent has menu items with workflow-install
|
|
1014
1005
|
const menuItems = agentYaml?.agent?.menu || [];
|
|
@@ -1030,10 +1021,10 @@ class ModuleManager {
|
|
|
1030
1021
|
const installWorkflowPath = item['workflow-install']; // Where to copy TO
|
|
1031
1022
|
|
|
1032
1023
|
// Parse SOURCE workflow path
|
|
1033
|
-
// Handle both
|
|
1034
|
-
// Example: {project-root}/
|
|
1024
|
+
// Handle both _bmad placeholder and hardcoded 'bmad'
|
|
1025
|
+
// Example: {project-root}/_bmad/bmm/workflows/4-implementation/create-story/workflow.yaml
|
|
1035
1026
|
// Or: {project-root}/bmad/bmm/workflows/4-implementation/create-story/workflow.yaml
|
|
1036
|
-
const sourceMatch = sourceWorkflowPath.match(/\{project-root\}\/(
|
|
1027
|
+
const sourceMatch = sourceWorkflowPath.match(/\{project-root\}\/(?:_bmad)\/([^/]+)\/workflows\/(.+)/);
|
|
1037
1028
|
if (!sourceMatch) {
|
|
1038
1029
|
console.warn(chalk.yellow(` Could not parse workflow path: ${sourceWorkflowPath}`));
|
|
1039
1030
|
continue;
|
|
@@ -1042,9 +1033,9 @@ class ModuleManager {
|
|
|
1042
1033
|
const [, sourceModule, sourceWorkflowSubPath] = sourceMatch;
|
|
1043
1034
|
|
|
1044
1035
|
// Parse INSTALL workflow path
|
|
1045
|
-
//
|
|
1046
|
-
// Example: {project-root}/
|
|
1047
|
-
const installMatch = installWorkflowPath.match(/\{project-root\}\/(
|
|
1036
|
+
// Handle_bmad
|
|
1037
|
+
// Example: {project-root}/_bmad/bmgd/workflows/4-production/create-story/workflow.yaml
|
|
1038
|
+
const installMatch = installWorkflowPath.match(/\{project-root\}\/(_bmad)\/([^/]+)\/workflows\/(.+)/);
|
|
1048
1039
|
if (!installMatch) {
|
|
1049
1040
|
console.warn(chalk.yellow(` Could not parse workflow-install path: ${installWorkflowPath}`));
|
|
1050
1041
|
continue;
|
|
@@ -1096,9 +1087,9 @@ class ModuleManager {
|
|
|
1096
1087
|
async updateWorkflowConfigSource(workflowYamlPath, newModuleName) {
|
|
1097
1088
|
let yamlContent = await fs.readFile(workflowYamlPath, 'utf8');
|
|
1098
1089
|
|
|
1099
|
-
// Replace config_source: "{project-root}/
|
|
1100
|
-
// with config_source: "{project-root}/
|
|
1101
|
-
// Note: At this point
|
|
1090
|
+
// Replace config_source: "{project-root}/_bmad/OLD_MODULE/config.yaml"
|
|
1091
|
+
// with config_source: "{project-root}/_bmad/NEW_MODULE/config.yaml"
|
|
1092
|
+
// Note: At this point _bmad has already been replaced with actual folder name
|
|
1102
1093
|
const configSourcePattern = /config_source:\s*["']?\{project-root\}\/[^/]+\/[^/]+\/config\.yaml["']?/g;
|
|
1103
1094
|
const newConfigSource = `config_source: "{project-root}/${this.bmadFolderName}/${newModuleName}/config.yaml"`;
|
|
1104
1095
|
|