bmad-method 6.0.0-alpha.16 → 6.0.0-alpha.18
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 +7 -3
- 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 +193 -2
- 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 +13 -13
- package/docs/sample-custom-modules/README.md +11 -0
- package/docs/sample-custom-modules/sample-unitary-module/README.md +8 -0
- package/docs/sample-custom-modules/sample-unitary-module/agents/commit-poet/commit-poet.agent.yaml +129 -0
- package/docs/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith-sidecar/instructions.md +70 -0
- package/docs/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith-sidecar/knowledge/bundlers.md +111 -0
- package/docs/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith-sidecar/knowledge/deploy.md +70 -0
- package/docs/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith-sidecar/knowledge/docs.md +114 -0
- package/docs/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith-sidecar/knowledge/installers.md +134 -0
- package/docs/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith-sidecar/knowledge/modules.md +161 -0
- package/docs/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith-sidecar/knowledge/tests.md +103 -0
- package/docs/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith-sidecar/memories.md +17 -0
- package/docs/sample-custom-modules/sample-unitary-module/agents/toolsmith/toolsmith.agent.yaml +109 -0
- package/docs/sample-custom-modules/sample-unitary-module/module.yaml +8 -0
- package/docs/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-01-init.md +168 -0
- package/docs/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-02-q1.md +155 -0
- package/docs/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-03-q2.md +89 -0
- package/docs/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-04-q3.md +36 -0
- package/docs/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-05-q4.md +36 -0
- package/docs/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-06-q5.md +36 -0
- package/docs/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-07-q6.md +36 -0
- package/docs/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-08-q7.md +36 -0
- package/docs/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-09-q8.md +36 -0
- package/docs/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-10-q9.md +36 -0
- package/docs/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-11-q10.md +36 -0
- package/docs/sample-custom-modules/sample-unitary-module/workflows/quiz-master/steps/step-12-results.md +150 -0
- package/docs/sample-custom-modules/sample-unitary-module/workflows/quiz-master/templates/csv-headers.template +1 -0
- package/docs/sample-custom-modules/sample-unitary-module/workflows/quiz-master/workflow.md +54 -0
- package/docs/sample-custom-modules/sample-unitary-module/workflows/wassup/workflow.md +26 -0
- package/docs/sample-custom-modules/sample-wellness-module/README.md +6 -0
- package/docs/sample-custom-modules/sample-wellness-module/agents/meditation-guide.agent.yaml +136 -0
- 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/docs/sample-custom-modules/sample-wellness-module/agents/wellness-companion/wellness-companion-sidecar/insights.md +13 -0
- package/docs/sample-custom-modules/sample-wellness-module/agents/wellness-companion/wellness-companion-sidecar/instructions.md +30 -0
- package/docs/sample-custom-modules/sample-wellness-module/agents/wellness-companion/wellness-companion-sidecar/memories.md +13 -0
- package/docs/sample-custom-modules/sample-wellness-module/agents/wellness-companion/wellness-companion-sidecar/patterns.md +17 -0
- package/docs/sample-custom-modules/sample-wellness-module/agents/wellness-companion/wellness-companion.agent.yaml +120 -0
- package/docs/sample-custom-modules/sample-wellness-module/module.yaml +17 -0
- package/docs/sample-custom-modules/sample-wellness-module/workflows/daily-checkin/README.md +32 -0
- package/docs/sample-custom-modules/sample-wellness-module/workflows/daily-checkin/workflow.md +45 -0
- package/docs/sample-custom-modules/sample-wellness-module/workflows/guided-meditation/README.md +31 -0
- package/docs/sample-custom-modules/sample-wellness-module/workflows/guided-meditation/workflow.md +45 -0
- package/docs/sample-custom-modules/sample-wellness-module/workflows/wellness-journal/README.md +31 -0
- package/docs/sample-custom-modules/sample-wellness-module/workflows/wellness-journal/workflow.md +45 -0
- 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 +11 -18
- 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 +20 -21
- 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 -15
- 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 +3 -3
- package/src/modules/bmb/workflows/create-agent/steps/step-01-brainstorm.md +4 -4
- package/src/modules/bmb/workflows/create-agent/steps/step-02-discover.md +6 -10
- package/src/modules/bmb/workflows/create-agent/steps/step-03-persona.md +6 -6
- package/src/modules/bmb/workflows/create-agent/steps/step-04-commands.md +9 -9
- package/src/modules/bmb/workflows/create-agent/steps/step-05-name.md +6 -5
- package/src/modules/bmb/workflows/create-agent/steps/step-06-build.md +19 -57
- package/src/modules/bmb/workflows/create-agent/steps/step-07-validate.md +5 -5
- package/src/modules/bmb/workflows/create-agent/steps/{step-11-celebrate.md → step-08-celebrate.md} +2 -6
- 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 +4 -4
- package/src/modules/bmb/workflows/create-module/steps/step-03-components.md +4 -4
- 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 +8 -8
- 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 +2 -2
- package/src/modules/bmb/workflows/edit-agent/steps/step-02-analyze-agent.md +12 -12
- package/src/modules/bmb/workflows/edit-agent/steps/step-03-propose-changes.md +4 -4
- package/src/modules/bmb/workflows/edit-agent/steps/step-04-apply-changes.md +2 -2
- package/src/modules/bmb/workflows/edit-agent/steps/step-05-validate.md +4 -4
- 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/_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 +26 -11
- package/src/modules/bmgd/agents/game-designer.agent.yaml +41 -21
- package/src/modules/bmgd/agents/game-dev.agent.yaml +34 -18
- package/src/modules/bmgd/agents/game-qa.agent.yaml +64 -0
- package/src/modules/bmgd/agents/game-scrum-master.agent.yaml +32 -44
- package/src/modules/bmgd/agents/game-solo-dev.agent.yaml +56 -0
- package/src/modules/bmgd/docs/README.md +180 -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/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 +27 -16
- package/src/modules/bmgd/teams/default-party.csv +2 -0
- package/src/modules/bmgd/teams/team-gamedev.yaml +12 -1
- package/src/modules/bmgd/workflows/1-preproduction/brainstorm-game/instructions.md +1 -1
- 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 +35 -14
- package/src/modules/bmgd/workflows/1-preproduction/game-brief/instructions.md +1 -1
- 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 +43 -12
- 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 +54 -34
- package/src/modules/bmgd/workflows/2-design/narrative/instructions-narrative.md +1 -1
- 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 +55 -10
- package/src/modules/bmgd/workflows/3-technical/game-architecture/instructions.md +1 -1
- 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 +302 -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 +51 -22
- 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 +19 -16
- 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 +12 -7
- package/src/modules/bmgd/workflows/4-production/create-story/checklist.md +332 -214
- package/src/modules/bmgd/workflows/4-production/create-story/instructions.xml +298 -0
- package/src/modules/bmgd/workflows/4-production/create-story/template.md +3 -5
- package/src/modules/bmgd/workflows/4-production/create-story/workflow.yaml +13 -8
- package/src/modules/bmgd/workflows/4-production/dev-story/checklist.md +65 -23
- package/src/modules/bmgd/workflows/4-production/dev-story/instructions.xml +409 -0
- package/src/modules/bmgd/workflows/4-production/dev-story/workflow.yaml +14 -4
- package/src/modules/bmgd/workflows/4-production/retrospective/instructions.md +5 -5
- package/src/modules/bmgd/workflows/4-production/retrospective/workflow.yaml +14 -9
- package/src/modules/bmgd/workflows/4-production/sprint-planning/instructions.md +33 -42
- package/src/modules/bmgd/workflows/4-production/sprint-planning/sprint-status-template.yaml +13 -13
- package/src/modules/bmgd/workflows/4-production/sprint-planning/workflow.yaml +7 -2
- 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 +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/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 -4
- package/src/modules/bmm/module.yaml +25 -23
- 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 +1 -1
- 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 +1 -1
- 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 -7
- 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 +16 -18
- package/tools/cli/commands/list.js +13 -1
- package/tools/cli/installers/lib/core/config-collector.js +224 -59
- package/tools/cli/installers/lib/core/custom-module-cache.js +18 -10
- 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 +634 -1040
- package/tools/cli/installers/lib/core/installer.js.bak +3204 -0
- 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 -46
- 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 +315 -312
- package/tools/cli/lib/activation-builder.js +8 -13
- package/tools/cli/lib/agent/compiler.js +166 -167
- 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 +678 -564
- 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/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 -366
- 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/bmgd/workflows/2-design/gdd/instructions-gdd.md +0 -502
- package/src/modules/bmgd/workflows/4-production/code-review/instructions.md +0 -398
- package/src/modules/bmgd/workflows/4-production/create-story/instructions.md +0 -256
- package/src/modules/bmgd/workflows/4-production/dev-story/instructions.md +0 -267
- package/src/modules/bmgd/workflows/4-production/epic-tech-context/checklist.md +0 -17
- package/src/modules/bmgd/workflows/4-production/epic-tech-context/instructions.md +0 -164
- package/src/modules/bmgd/workflows/4-production/epic-tech-context/template.md +0 -76
- package/src/modules/bmgd/workflows/4-production/epic-tech-context/workflow.yaml +0 -58
- package/src/modules/bmgd/workflows/4-production/story-context/checklist.md +0 -16
- package/src/modules/bmgd/workflows/4-production/story-context/context-template.xml +0 -34
- package/src/modules/bmgd/workflows/4-production/story-context/instructions.md +0 -209
- package/src/modules/bmgd/workflows/4-production/story-context/workflow.yaml +0 -63
- package/src/modules/bmgd/workflows/4-production/story-done/instructions.md +0 -111
- package/src/modules/bmgd/workflows/4-production/story-done/workflow.yaml +0 -28
- package/src/modules/bmgd/workflows/4-production/story-ready/instructions.md +0 -117
- package/src/modules/bmgd/workflows/4-production/story-ready/workflow.yaml +0 -25
- 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 -1754
- 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 -27
- package/tools/cli/test-yaml-builder.js +0 -43
- /package/src/modules/bmgd/workflows/1-preproduction/game-brief/{template.md → templates/game-brief-template.md} +0 -0
- /package/src/modules/bmgd/workflows/2-design/gdd/{gdd-template.md → templates/gdd-template.md} +0 -0
- /package/src/modules/bmgd/workflows/2-design/narrative/{narrative-template.md → templates/narrative-template.md} +0 -0
- /package/src/modules/bmgd/workflows/3-technical/game-architecture/{architecture-template.md → templates/architecture-template.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
package/tools/cli/lib/ui.js
CHANGED
|
@@ -1,23 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* File: tools/cli/lib/ui.js
|
|
3
|
-
*
|
|
4
|
-
* BMAD Method - Business Model Agile Development Method
|
|
5
|
-
* Repository: https://github.com/paulpreibisch/BMAD-METHOD
|
|
6
|
-
*
|
|
7
|
-
* Copyright (c) 2025 Paul Preibisch
|
|
8
|
-
* Licensed under the Apache License, Version 2.0
|
|
9
|
-
*
|
|
10
|
-
* ---
|
|
11
|
-
*
|
|
12
|
-
* @fileoverview Interactive installation prompts and user input collection for BMAD CLI
|
|
13
|
-
* @context Guides users through installation configuration including core settings, modules, IDEs, and optional AgentVibes TTS
|
|
14
|
-
* @architecture Facade pattern - presents unified installation flow, delegates to Detector/ConfigCollector/IdeManager for specifics
|
|
15
|
-
* @dependencies inquirer (prompts), chalk (formatting), detector.js (existing installation detection)
|
|
16
|
-
* @entrypoints Called by install.js command via ui.promptInstall(), returns complete configuration object
|
|
17
|
-
* @patterns Progressive disclosure (prompts in order), early IDE selection (Windows compat), AgentVibes auto-detection
|
|
18
|
-
* @related installer.js (consumes config), AgentVibes#34 (TTS integration), promptAgentVibes()
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
1
|
const chalk = require('chalk');
|
|
22
2
|
const inquirer = require('inquirer');
|
|
23
3
|
const path = require('node:path');
|
|
@@ -30,16 +10,15 @@ const { CustomHandler } = require('../installers/lib/custom/handler');
|
|
|
30
10
|
* UI utilities for the installer
|
|
31
11
|
*/
|
|
32
12
|
class UI {
|
|
33
|
-
constructor() {}
|
|
34
|
-
|
|
35
13
|
/**
|
|
36
14
|
* Prompt for installation configuration
|
|
37
15
|
* @returns {Object} Installation configuration
|
|
38
16
|
*/
|
|
39
17
|
async promptInstall() {
|
|
40
18
|
CLIUtils.displayLogo();
|
|
41
|
-
|
|
42
|
-
|
|
19
|
+
|
|
20
|
+
// Display changelog link
|
|
21
|
+
console.log(chalk.cyan('\n📋 Read the latest updates: https://github.com/bmad-code-org/BMAD-METHOD/blob/main/CHANGELOG.md\n'));
|
|
43
22
|
|
|
44
23
|
const confirmedDirectory = await this.getConfirmedDirectory();
|
|
45
24
|
|
|
@@ -53,21 +32,138 @@ class UI {
|
|
|
53
32
|
await installer.handleLegacyV4Migration(confirmedDirectory, legacyV4);
|
|
54
33
|
}
|
|
55
34
|
|
|
56
|
-
// Check
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
35
|
+
// Check for legacy folders and prompt for rename before showing any menus
|
|
36
|
+
let hasLegacyCfg = false;
|
|
37
|
+
let hasLegacyBmadFolder = false;
|
|
38
|
+
let bmadDir = null;
|
|
39
|
+
let legacyBmadPath = null;
|
|
40
|
+
|
|
41
|
+
// First check for legacy .bmad folder (instead of _bmad)
|
|
42
|
+
// Only check if directory exists
|
|
43
|
+
if (await fs.pathExists(confirmedDirectory)) {
|
|
44
|
+
const entries = await fs.readdir(confirmedDirectory, { withFileTypes: true });
|
|
45
|
+
for (const entry of entries) {
|
|
46
|
+
if (entry.isDirectory() && entry.name === '.bmad') {
|
|
47
|
+
hasLegacyBmadFolder = true;
|
|
48
|
+
legacyBmadPath = path.join(confirmedDirectory, '.bmad');
|
|
49
|
+
bmadDir = legacyBmadPath;
|
|
50
|
+
|
|
51
|
+
// Check if it has _cfg folder
|
|
52
|
+
const cfgPath = path.join(legacyBmadPath, '_cfg');
|
|
53
|
+
if (await fs.pathExists(cfgPath)) {
|
|
54
|
+
hasLegacyCfg = true;
|
|
55
|
+
}
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// If no .bmad found, check for current installations
|
|
62
|
+
if (!hasLegacyBmadFolder) {
|
|
63
|
+
const bmadResult = await installer.findBmadDir(confirmedDirectory);
|
|
64
|
+
bmadDir = bmadResult.bmadDir;
|
|
65
|
+
hasLegacyCfg = bmadResult.hasLegacyCfg;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (hasLegacyBmadFolder || hasLegacyCfg) {
|
|
69
|
+
console.log(chalk.yellow('\n⚠️ Legacy folder structure detected'));
|
|
70
|
+
|
|
71
|
+
let message = 'The following folders need to be renamed:\n';
|
|
72
|
+
if (hasLegacyBmadFolder) {
|
|
73
|
+
message += chalk.dim(` • ".bmad" → "_bmad"\n`);
|
|
74
|
+
}
|
|
75
|
+
if (hasLegacyCfg) {
|
|
76
|
+
message += chalk.dim(` • "_cfg" → "_config"\n`);
|
|
77
|
+
}
|
|
78
|
+
console.log(message);
|
|
79
|
+
|
|
80
|
+
const { shouldRename } = await inquirer.prompt([
|
|
81
|
+
{
|
|
82
|
+
type: 'confirm',
|
|
83
|
+
name: 'shouldRename',
|
|
84
|
+
message: 'Would you like the installer to rename these folders for you?',
|
|
85
|
+
default: true,
|
|
86
|
+
},
|
|
87
|
+
]);
|
|
88
|
+
|
|
89
|
+
if (!shouldRename) {
|
|
90
|
+
console.log(chalk.red('\n❌ Installation cancelled'));
|
|
91
|
+
console.log(chalk.dim('You must manually rename the folders before proceeding:'));
|
|
92
|
+
if (hasLegacyBmadFolder) {
|
|
93
|
+
console.log(chalk.dim(` • Rename ".bmad" to "_bmad"`));
|
|
94
|
+
}
|
|
95
|
+
if (hasLegacyCfg) {
|
|
96
|
+
console.log(chalk.dim(` • Rename "_cfg" to "_config"`));
|
|
97
|
+
}
|
|
98
|
+
process.exit(0);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Perform the renames
|
|
103
|
+
const ora = require('ora');
|
|
104
|
+
const spinner = ora('Updating folder structure...').start();
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
// First rename .bmad to _bmad if needed
|
|
108
|
+
if (hasLegacyBmadFolder) {
|
|
109
|
+
const newBmadPath = path.join(confirmedDirectory, '_bmad');
|
|
110
|
+
await fs.move(legacyBmadPath, newBmadPath);
|
|
111
|
+
bmadDir = newBmadPath;
|
|
112
|
+
spinner.succeed('Renamed ".bmad" to "_bmad"');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Then rename _cfg to _config if needed
|
|
116
|
+
if (hasLegacyCfg) {
|
|
117
|
+
spinner.start('Renaming configuration folder...');
|
|
118
|
+
const oldCfgPath = path.join(bmadDir, '_cfg');
|
|
119
|
+
const newCfgPath = path.join(bmadDir, '_config');
|
|
120
|
+
await fs.move(oldCfgPath, newCfgPath);
|
|
121
|
+
spinner.succeed('Renamed "_cfg" to "_config"');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
spinner.succeed('Folder structure updated successfully');
|
|
125
|
+
} catch (error) {
|
|
126
|
+
spinner.fail('Failed to update folder structure');
|
|
127
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Check if there's an existing BMAD installation (after any folder renames)
|
|
61
133
|
const hasExistingInstall = await fs.pathExists(bmadDir);
|
|
62
134
|
|
|
63
|
-
//
|
|
135
|
+
// Collect IDE tool selection early - we need this to know if we should ask about TTS
|
|
136
|
+
let toolSelection;
|
|
137
|
+
let agentVibesConfig = { enabled: false, alreadyInstalled: false };
|
|
138
|
+
let claudeCodeSelected = false;
|
|
139
|
+
|
|
140
|
+
if (!hasExistingInstall) {
|
|
141
|
+
// For new installations, collect IDE selection first
|
|
142
|
+
// We don't have modules yet, so pass empty array
|
|
143
|
+
toolSelection = await this.promptToolSelection(confirmedDirectory, []);
|
|
144
|
+
|
|
145
|
+
// Check if Claude Code was selected
|
|
146
|
+
claudeCodeSelected = toolSelection.ides && toolSelection.ides.includes('claude-code');
|
|
147
|
+
|
|
148
|
+
// If Claude Code was selected, ask about TTS
|
|
149
|
+
if (claudeCodeSelected) {
|
|
150
|
+
const { enableTts } = await inquirer.prompt([
|
|
151
|
+
{
|
|
152
|
+
type: 'confirm',
|
|
153
|
+
name: 'enableTts',
|
|
154
|
+
message: 'Claude Code supports TTS (Text-to-Speech). Would you like to enable it?',
|
|
155
|
+
default: false,
|
|
156
|
+
},
|
|
157
|
+
]);
|
|
158
|
+
|
|
159
|
+
if (enableTts) {
|
|
160
|
+
agentVibesConfig = { enabled: true, alreadyInstalled: false };
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
64
165
|
let customContentConfig = { hasCustomContent: false };
|
|
65
|
-
if (hasExistingInstall) {
|
|
66
|
-
// Existing installation - prompt to add/update custom content
|
|
67
|
-
customContentConfig = await this.promptCustomContentForExisting();
|
|
68
|
-
} else {
|
|
69
|
-
// New installation - we'll prompt after creating the directory structure
|
|
70
|
-
// For now, set a flag to indicate we should ask later
|
|
166
|
+
if (!hasExistingInstall) {
|
|
71
167
|
customContentConfig._shouldAsk = true;
|
|
72
168
|
}
|
|
73
169
|
|
|
@@ -76,19 +172,41 @@ class UI {
|
|
|
76
172
|
|
|
77
173
|
// Only show action menu if there's an existing installation
|
|
78
174
|
if (hasExistingInstall) {
|
|
175
|
+
// Get version information
|
|
176
|
+
const { existingInstall } = await this.getExistingInstallation(confirmedDirectory);
|
|
177
|
+
const packageJsonPath = path.join(__dirname, '../../../package.json');
|
|
178
|
+
const currentVersion = require(packageJsonPath).version;
|
|
179
|
+
const installedVersion = existingInstall.version || 'unknown';
|
|
180
|
+
|
|
181
|
+
// Build menu choices dynamically
|
|
182
|
+
const choices = [];
|
|
183
|
+
|
|
184
|
+
// Always show Quick Update first (allows refreshing installation even on same version)
|
|
185
|
+
if (installedVersion !== 'unknown') {
|
|
186
|
+
choices.push({
|
|
187
|
+
name: `Quick Update (v${installedVersion} → v${currentVersion})`,
|
|
188
|
+
value: 'quick-update',
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Add custom agent compilation option
|
|
193
|
+
if (installedVersion !== 'unknown') {
|
|
194
|
+
choices.push({
|
|
195
|
+
name: 'Recompile Agents (apply customizations only)',
|
|
196
|
+
value: 'compile-agents',
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Common actions
|
|
201
|
+
choices.push({ name: 'Modify BMAD Installation', value: 'update' });
|
|
202
|
+
|
|
79
203
|
const promptResult = await inquirer.prompt([
|
|
80
204
|
{
|
|
81
205
|
type: 'list',
|
|
82
206
|
name: 'actionType',
|
|
83
207
|
message: 'What would you like to do?',
|
|
84
|
-
choices:
|
|
85
|
-
|
|
86
|
-
{ name: 'Modify BMAD Installation (Confirm or change each setting)', value: 'update' },
|
|
87
|
-
{ name: 'Remove BMad Folder and Reinstall (Full clean install - BMad Customization Will Be Lost)', value: 'reinstall' },
|
|
88
|
-
{ name: 'Compile Agents (Quick rebuild of all agent .md files)', value: 'compile' },
|
|
89
|
-
{ name: 'Cancel', value: 'cancel' },
|
|
90
|
-
],
|
|
91
|
-
default: 'quick-update',
|
|
208
|
+
choices: choices,
|
|
209
|
+
default: choices[0].value, // Use the first option as default
|
|
92
210
|
},
|
|
93
211
|
]);
|
|
94
212
|
|
|
@@ -105,163 +223,179 @@ class UI {
|
|
|
105
223
|
};
|
|
106
224
|
}
|
|
107
225
|
|
|
108
|
-
// Handle
|
|
109
|
-
if (actionType === 'compile') {
|
|
226
|
+
// Handle compile agents separately
|
|
227
|
+
if (actionType === 'compile-agents') {
|
|
228
|
+
// Only recompile agents with customizations, don't update any files
|
|
110
229
|
return {
|
|
111
|
-
actionType: 'compile',
|
|
230
|
+
actionType: 'compile-agents',
|
|
112
231
|
directory: confirmedDirectory,
|
|
232
|
+
customContent: { hasCustomContent: false },
|
|
113
233
|
};
|
|
114
234
|
}
|
|
115
235
|
|
|
116
|
-
//
|
|
117
|
-
|
|
236
|
+
// If actionType === 'update', handle it with the new flow
|
|
237
|
+
// Return early with modify configuration
|
|
238
|
+
if (actionType === 'update') {
|
|
239
|
+
// Get existing installation info
|
|
240
|
+
const { installedModuleIds } = await this.getExistingInstallation(confirmedDirectory);
|
|
241
|
+
|
|
242
|
+
console.log(chalk.dim(` Found existing modules: ${[...installedModuleIds].join(', ')}`));
|
|
243
|
+
const { changeModuleSelection } = await inquirer.prompt([
|
|
244
|
+
{
|
|
245
|
+
type: 'confirm',
|
|
246
|
+
name: 'changeModuleSelection',
|
|
247
|
+
message: 'Modify official module selection (BMad Method, BMad Builder, Creative Innovation Suite)?',
|
|
248
|
+
default: false,
|
|
249
|
+
},
|
|
250
|
+
]);
|
|
251
|
+
|
|
252
|
+
let selectedModules = [];
|
|
253
|
+
if (changeModuleSelection) {
|
|
254
|
+
// Show module selection with existing modules pre-selected
|
|
255
|
+
const moduleChoices = await this.getModuleChoices(new Set(installedModuleIds), { hasCustomContent: false });
|
|
256
|
+
selectedModules = await this.selectModules(moduleChoices, [...installedModuleIds]);
|
|
257
|
+
} else {
|
|
258
|
+
selectedModules = [...installedModuleIds];
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// After module selection, ask about custom modules
|
|
262
|
+
console.log('');
|
|
263
|
+
const { changeCustomModules } = await inquirer.prompt([
|
|
264
|
+
{
|
|
265
|
+
type: 'confirm',
|
|
266
|
+
name: 'changeCustomModules',
|
|
267
|
+
message: 'Modify custom module selection (add, update, or remove custom modules/agents/workflows)?',
|
|
268
|
+
default: false,
|
|
269
|
+
},
|
|
270
|
+
]);
|
|
271
|
+
|
|
272
|
+
let customModuleResult = { selectedCustomModules: [], customContentConfig: { hasCustomContent: false } };
|
|
273
|
+
if (changeCustomModules) {
|
|
274
|
+
customModuleResult = await this.handleCustomModulesInModifyFlow(confirmedDirectory, selectedModules);
|
|
275
|
+
} else {
|
|
276
|
+
// Preserve existing custom modules if user doesn't want to modify them
|
|
277
|
+
const { Installer } = require('../installers/lib/core/installer');
|
|
278
|
+
const installer = new Installer();
|
|
279
|
+
const { bmadDir } = await installer.findBmadDir(confirmedDirectory);
|
|
280
|
+
|
|
281
|
+
const cacheDir = path.join(bmadDir, '_config', 'custom');
|
|
282
|
+
if (await fs.pathExists(cacheDir)) {
|
|
283
|
+
const entries = await fs.readdir(cacheDir, { withFileTypes: true });
|
|
284
|
+
for (const entry of entries) {
|
|
285
|
+
if (entry.isDirectory()) {
|
|
286
|
+
customModuleResult.selectedCustomModules.push(entry.name);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Merge any selected custom modules
|
|
293
|
+
if (customModuleResult.selectedCustomModules.length > 0) {
|
|
294
|
+
selectedModules.push(...customModuleResult.selectedCustomModules);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Get tool selection
|
|
298
|
+
const toolSelection = await this.promptToolSelection(confirmedDirectory, selectedModules);
|
|
299
|
+
|
|
300
|
+
// TTS configuration - ask right after tool selection (matches new install flow)
|
|
301
|
+
const hasClaudeCode = toolSelection.ides && toolSelection.ides.includes('claude-code');
|
|
302
|
+
let enableTts = false;
|
|
303
|
+
|
|
304
|
+
if (hasClaudeCode) {
|
|
305
|
+
const { enableTts: enable } = await inquirer.prompt([
|
|
306
|
+
{
|
|
307
|
+
type: 'confirm',
|
|
308
|
+
name: 'enableTts',
|
|
309
|
+
message: 'Claude Code supports TTS (Text-to-Speech). Would you like to enable it?',
|
|
310
|
+
default: false,
|
|
311
|
+
},
|
|
312
|
+
]);
|
|
313
|
+
enableTts = enable;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Core config with existing defaults (ask after TTS)
|
|
317
|
+
const coreConfig = await this.collectCoreConfig(confirmedDirectory);
|
|
318
|
+
|
|
118
319
|
return {
|
|
119
|
-
actionType: '
|
|
320
|
+
actionType: 'update',
|
|
120
321
|
directory: confirmedDirectory,
|
|
322
|
+
installCore: true,
|
|
323
|
+
modules: selectedModules,
|
|
324
|
+
ides: toolSelection.ides,
|
|
325
|
+
skipIde: toolSelection.skipIde,
|
|
326
|
+
coreConfig: coreConfig,
|
|
327
|
+
customContent: customModuleResult.customContentConfig,
|
|
328
|
+
enableAgentVibes: enableTts,
|
|
329
|
+
agentVibesInstalled: false,
|
|
121
330
|
};
|
|
122
331
|
}
|
|
123
|
-
|
|
124
|
-
// Handle reinstall - DON'T return early, let it flow through configuration collection
|
|
125
|
-
// The installer will handle deletion when it sees actionType === 'reinstall'
|
|
126
|
-
// For now, just note that we're in reinstall mode and continue below
|
|
127
|
-
|
|
128
|
-
// If actionType === 'update' or 'reinstall', continue with normal flow below
|
|
129
332
|
}
|
|
130
333
|
|
|
334
|
+
// This section is only for new installations (update returns early above)
|
|
131
335
|
const { installedModuleIds } = await this.getExistingInstallation(confirmedDirectory);
|
|
132
|
-
const coreConfig = await this.collectCoreConfig(confirmedDirectory);
|
|
133
336
|
|
|
134
|
-
//
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
await fs.ensureDir(path.join(bmadDir, '_cfg'));
|
|
144
|
-
await fs.ensureDir(path.join(bmadDir, '_cfg', 'custom'));
|
|
145
|
-
|
|
146
|
-
// Now prompt for custom content
|
|
147
|
-
customContentConfig = await this.promptCustomContentLocation();
|
|
148
|
-
|
|
149
|
-
// If custom content found, cache it
|
|
150
|
-
if (customContentConfig.hasCustomContent) {
|
|
151
|
-
const { CustomModuleCache } = require('../installers/lib/core/custom-module-cache');
|
|
152
|
-
const cache = new CustomModuleCache(bmadDir);
|
|
153
|
-
|
|
154
|
-
const customHandler = new CustomHandler();
|
|
155
|
-
const customFiles = await customHandler.findCustomContent(customContentConfig.customPath);
|
|
156
|
-
|
|
157
|
-
for (const customFile of customFiles) {
|
|
158
|
-
const customInfo = await customHandler.getCustomInfo(customFile);
|
|
159
|
-
if (customInfo && customInfo.id) {
|
|
160
|
-
// Cache the module source
|
|
161
|
-
await cache.cacheModule(customInfo.id, customInfo.path, {
|
|
162
|
-
name: customInfo.name,
|
|
163
|
-
type: 'custom',
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
console.log(chalk.dim(` Cached ${customInfo.name} to _cfg/custom/${customInfo.id}`));
|
|
167
|
-
}
|
|
168
|
-
}
|
|
337
|
+
// Ask about official modules for new installations
|
|
338
|
+
const { wantsOfficialModules } = await inquirer.prompt([
|
|
339
|
+
{
|
|
340
|
+
type: 'confirm',
|
|
341
|
+
name: 'wantsOfficialModules',
|
|
342
|
+
message: 'Will you be installing any official BMad modules (BMad Method, BMad Builder, Creative Innovation Suite)?',
|
|
343
|
+
default: true,
|
|
344
|
+
},
|
|
345
|
+
]);
|
|
169
346
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
customContentConfig.cachedModules.push({
|
|
176
|
-
id: customInfo.id,
|
|
177
|
-
cachePath: path.join(bmadDir, '_cfg', 'custom', customInfo.id),
|
|
178
|
-
// Store relative path from cache for the manifest
|
|
179
|
-
relativePath: path.join('_cfg', 'custom', customInfo.id),
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
}
|
|
347
|
+
let selectedOfficialModules = [];
|
|
348
|
+
if (wantsOfficialModules) {
|
|
349
|
+
const moduleChoices = await this.getModuleChoices(installedModuleIds, { hasCustomContent: false });
|
|
350
|
+
selectedOfficialModules = await this.selectModules(moduleChoices);
|
|
351
|
+
}
|
|
183
352
|
|
|
184
|
-
|
|
185
|
-
|
|
353
|
+
// Ask about custom content
|
|
354
|
+
const { wantsCustomContent } = await inquirer.prompt([
|
|
355
|
+
{
|
|
356
|
+
type: 'confirm',
|
|
357
|
+
name: 'wantsCustomContent',
|
|
358
|
+
message: 'Would you like to install a local custom module (this includes custom agents and workflows also)?',
|
|
359
|
+
default: false,
|
|
360
|
+
},
|
|
361
|
+
]);
|
|
186
362
|
|
|
187
|
-
|
|
188
|
-
|
|
363
|
+
if (wantsCustomContent) {
|
|
364
|
+
customContentConfig = await this.promptCustomContentSource();
|
|
189
365
|
}
|
|
190
366
|
|
|
191
|
-
//
|
|
192
|
-
|
|
193
|
-
if (actionType === 'update' || actionType === 'reinstall') {
|
|
194
|
-
// Keep all existing installed modules during update/reinstall
|
|
195
|
-
selectedModules = [...installedModuleIds];
|
|
196
|
-
console.log(chalk.cyan('\n📦 Keeping existing modules: ') + selectedModules.join(', '));
|
|
197
|
-
} else {
|
|
198
|
-
// Only show module selection for new installs
|
|
199
|
-
const moduleChoices = await this.getModuleChoices(installedModuleIds, customContentConfig);
|
|
200
|
-
selectedModules = await this.selectModules(moduleChoices);
|
|
201
|
-
|
|
202
|
-
// Check which custom content items were selected
|
|
203
|
-
const selectedCustomContent = selectedModules.filter((mod) => mod.startsWith('__CUSTOM_CONTENT__'));
|
|
204
|
-
|
|
205
|
-
// For cached modules (new installs), check if any cached modules were selected
|
|
206
|
-
let selectedCachedModules = [];
|
|
207
|
-
if (customContentConfig.cachedModules) {
|
|
208
|
-
selectedCachedModules = selectedModules.filter(
|
|
209
|
-
(mod) => !mod.startsWith('__CUSTOM_CONTENT__') && customContentConfig.cachedModules.some((cm) => cm.id === mod),
|
|
210
|
-
);
|
|
211
|
-
}
|
|
367
|
+
// Store the selected modules for later
|
|
368
|
+
customContentConfig._selectedOfficialModules = selectedOfficialModules;
|
|
212
369
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
// Handle directory-based custom content (existing installs)
|
|
217
|
-
if (selectedCustomContent.length > 0) {
|
|
218
|
-
customContentConfig.selectedFiles = selectedCustomContent.map((mod) => mod.replace('__CUSTOM_CONTENT__', ''));
|
|
219
|
-
// Convert custom content to module IDs for installation
|
|
220
|
-
const customContentModuleIds = [];
|
|
221
|
-
const customHandler = new CustomHandler();
|
|
222
|
-
for (const customFile of customContentConfig.selectedFiles) {
|
|
223
|
-
// Get the module info to extract the ID
|
|
224
|
-
const customInfo = await customHandler.getCustomInfo(customFile);
|
|
225
|
-
if (customInfo) {
|
|
226
|
-
customContentModuleIds.push(customInfo.id);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
// Filter out custom content markers and add module IDs
|
|
230
|
-
selectedModules = [...selectedModules.filter((mod) => !mod.startsWith('__CUSTOM_CONTENT__')), ...customContentModuleIds];
|
|
231
|
-
}
|
|
370
|
+
// Build the final list of selected modules
|
|
371
|
+
let selectedModules = customContentConfig._selectedOfficialModules || [];
|
|
232
372
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
// No need to filter since they're already proper module IDs
|
|
237
|
-
}
|
|
238
|
-
} else if (customContentConfig.hasCustomContent) {
|
|
239
|
-
// User provided custom content but didn't select any
|
|
240
|
-
customContentConfig.selected = false;
|
|
241
|
-
customContentConfig.selectedFiles = [];
|
|
242
|
-
customContentConfig.selectedCachedModules = [];
|
|
243
|
-
}
|
|
373
|
+
// Add custom content modules if any were selected
|
|
374
|
+
if (customContentConfig && customContentConfig.selectedModuleIds) {
|
|
375
|
+
selectedModules = [...selectedModules, ...customContentConfig.selectedModuleIds];
|
|
244
376
|
}
|
|
245
377
|
|
|
246
|
-
//
|
|
247
|
-
|
|
378
|
+
// Remove core if it's in the list (it's always installed)
|
|
379
|
+
selectedModules = selectedModules.filter((m) => m !== 'core');
|
|
380
|
+
|
|
381
|
+
// Tool selection (already done for new installs at the beginning)
|
|
382
|
+
if (!toolSelection) {
|
|
383
|
+
toolSelection = await this.promptToolSelection(confirmedDirectory, selectedModules);
|
|
384
|
+
}
|
|
248
385
|
|
|
249
|
-
// Collect
|
|
250
|
-
|
|
251
|
-
const toolSelection = await this.promptToolSelection(confirmedDirectory, selectedModules);
|
|
386
|
+
// Collect configurations for new installations
|
|
387
|
+
const coreConfig = await this.collectCoreConfig(confirmedDirectory);
|
|
252
388
|
|
|
253
|
-
//
|
|
389
|
+
// TTS already handled at the beginning for new installs
|
|
254
390
|
|
|
255
391
|
return {
|
|
256
|
-
actionType:
|
|
392
|
+
actionType: 'install',
|
|
257
393
|
directory: confirmedDirectory,
|
|
258
|
-
installCore: true,
|
|
394
|
+
installCore: true,
|
|
259
395
|
modules: selectedModules,
|
|
260
|
-
// IDE selection collected after config, will be configured later
|
|
261
396
|
ides: toolSelection.ides,
|
|
262
397
|
skipIde: toolSelection.skipIde,
|
|
263
|
-
coreConfig: coreConfig,
|
|
264
|
-
// Custom content configuration
|
|
398
|
+
coreConfig: coreConfig,
|
|
265
399
|
customContent: customContentConfig,
|
|
266
400
|
enableAgentVibes: agentVibesConfig.enabled,
|
|
267
401
|
agentVibesInstalled: agentVibesConfig.alreadyInstalled,
|
|
@@ -280,7 +414,8 @@ class UI {
|
|
|
280
414
|
const { Installer } = require('../installers/lib/core/installer');
|
|
281
415
|
const detector = new Detector();
|
|
282
416
|
const installer = new Installer();
|
|
283
|
-
const
|
|
417
|
+
const bmadResult = await installer.findBmadDir(projectDir || process.cwd());
|
|
418
|
+
const bmadDir = bmadResult.bmadDir;
|
|
284
419
|
const existingInstall = await detector.detect(bmadDir);
|
|
285
420
|
const configuredIdes = existingInstall.ides || [];
|
|
286
421
|
|
|
@@ -350,8 +485,6 @@ class UI {
|
|
|
350
485
|
}
|
|
351
486
|
}
|
|
352
487
|
|
|
353
|
-
CLIUtils.displaySection('Tool Integration', 'Select AI coding assistants and IDEs to configure');
|
|
354
|
-
|
|
355
488
|
let answers;
|
|
356
489
|
let userConfirmedNoTools = false;
|
|
357
490
|
|
|
@@ -363,7 +496,7 @@ class UI {
|
|
|
363
496
|
name: 'ides',
|
|
364
497
|
message: 'Select tools to configure:',
|
|
365
498
|
choices: ideChoices,
|
|
366
|
-
pageSize:
|
|
499
|
+
pageSize: 30,
|
|
367
500
|
},
|
|
368
501
|
]);
|
|
369
502
|
|
|
@@ -389,9 +522,8 @@ class UI {
|
|
|
389
522
|
]);
|
|
390
523
|
|
|
391
524
|
if (goBack) {
|
|
392
|
-
// Re-display
|
|
525
|
+
// Re-display a message before looping back
|
|
393
526
|
console.log();
|
|
394
|
-
CLIUtils.displaySection('Tool Integration', 'Select AI coding assistants and IDEs to configure');
|
|
395
527
|
} else {
|
|
396
528
|
// User explicitly chose to proceed without tools
|
|
397
529
|
userConfirmedNoTools = true;
|
|
@@ -481,69 +613,33 @@ class UI {
|
|
|
481
613
|
* @param {Object} result - Installation result
|
|
482
614
|
*/
|
|
483
615
|
showInstallSummary(result) {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
const summary = [
|
|
487
|
-
`📁 Installation Path: ${result.path}`,
|
|
488
|
-
`📦 Modules Installed: ${result.modules?.length > 0 ? result.modules.join(', ') : 'core only'}`,
|
|
489
|
-
`🔧 Tools Configured: ${result.ides?.length > 0 ? result.ides.join(', ') : 'none'}`,
|
|
490
|
-
];
|
|
616
|
+
// Clean, simple completion message
|
|
617
|
+
console.log('\n' + chalk.green.bold('✨ BMAD is ready to use!'));
|
|
491
618
|
|
|
492
|
-
//
|
|
619
|
+
// Show installation summary in a simple format
|
|
620
|
+
console.log(chalk.dim(`Installed to: ${result.path}`));
|
|
621
|
+
if (result.modules && result.modules.length > 0) {
|
|
622
|
+
console.log(chalk.dim(`Modules: ${result.modules.join(', ')}`));
|
|
623
|
+
}
|
|
493
624
|
if (result.agentVibesEnabled) {
|
|
494
|
-
|
|
625
|
+
console.log(chalk.dim(`TTS: Enabled`));
|
|
495
626
|
}
|
|
496
627
|
|
|
497
|
-
|
|
498
|
-
borderColor: 'green',
|
|
499
|
-
borderStyle: 'round',
|
|
500
|
-
});
|
|
501
|
-
|
|
502
|
-
// Display TTS injection details if present
|
|
628
|
+
// TTS injection info (simplified)
|
|
503
629
|
if (result.ttsInjectedFiles && result.ttsInjectedFiles.length > 0) {
|
|
504
|
-
console.log(
|
|
505
|
-
console.log(chalk.
|
|
506
|
-
console.log(chalk.cyan.bold('═══════════════════════════════════════════════════\n'));
|
|
507
|
-
|
|
508
|
-
// Explain what TTS injection is
|
|
509
|
-
console.log(chalk.white.bold('What is TTS Injection?\n'));
|
|
510
|
-
console.log(chalk.dim(' TTS (Text-to-Speech) injection adds voice instructions to BMAD agents,'));
|
|
511
|
-
console.log(chalk.dim(' enabling them to speak their responses aloud using AgentVibes.\n'));
|
|
512
|
-
console.log(chalk.dim(' Example: When you activate the PM agent, it will greet you with'));
|
|
513
|
-
console.log(chalk.dim(' spoken audio like "Hey! I\'m your Project Manager. How can I help?"\n'));
|
|
514
|
-
|
|
515
|
-
console.log(chalk.green(`✅ TTS injection applied to ${result.ttsInjectedFiles.length} file(s):\n`));
|
|
516
|
-
|
|
517
|
-
// Group by type
|
|
518
|
-
const partyModeFiles = result.ttsInjectedFiles.filter((f) => f.type === 'party-mode');
|
|
519
|
-
const agentTTSFiles = result.ttsInjectedFiles.filter((f) => f.type === 'agent-tts');
|
|
520
|
-
|
|
521
|
-
if (partyModeFiles.length > 0) {
|
|
522
|
-
console.log(chalk.yellow(' Party Mode (multi-agent conversations):'));
|
|
523
|
-
for (const file of partyModeFiles) {
|
|
524
|
-
console.log(chalk.dim(` • ${file.path}`));
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
if (agentTTSFiles.length > 0) {
|
|
529
|
-
console.log(chalk.yellow(' Agent TTS (individual agent voices):'));
|
|
530
|
-
for (const file of agentTTSFiles) {
|
|
531
|
-
console.log(chalk.dim(` • ${file.path}`));
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
// Show backup info and restore command
|
|
536
|
-
console.log('\n' + chalk.white.bold('Backups & Recovery:\n'));
|
|
537
|
-
console.log(chalk.dim(' Pre-injection backups are stored in:'));
|
|
538
|
-
console.log(chalk.cyan(' ~/.bmad-tts-backups/\n'));
|
|
539
|
-
console.log(chalk.dim(' To restore original files (removes TTS instructions):'));
|
|
540
|
-
console.log(chalk.cyan(` bmad-tts-injector.sh --restore ${result.path}\n`));
|
|
541
|
-
|
|
542
|
-
console.log(chalk.cyan('💡 BMAD agents will now speak when activated!'));
|
|
543
|
-
console.log(chalk.dim(' Ensure AgentVibes is installed: https://agentvibes.org'));
|
|
630
|
+
console.log(chalk.dim(`\n💡 TTS enabled for ${result.ttsInjectedFiles.length} agent(s)`));
|
|
631
|
+
console.log(chalk.dim(' Agents will now speak when using AgentVibes'));
|
|
544
632
|
}
|
|
545
633
|
|
|
546
|
-
console.log(
|
|
634
|
+
console.log(chalk.yellow('\nThank you for helping test the early release version of the new BMad Core and BMad Method!'));
|
|
635
|
+
console.log(chalk.cyan('Stable Beta coming soon - please read the full README.md and linked documentation to get started!'));
|
|
636
|
+
|
|
637
|
+
// Add changelog link at the end
|
|
638
|
+
console.log(
|
|
639
|
+
chalk.magenta(
|
|
640
|
+
"\n📋 Want to see what's new? Check out the changelog: https://github.com/bmad-code-org/BMAD-METHOD/blob/main/CHANGELOG.md",
|
|
641
|
+
),
|
|
642
|
+
);
|
|
547
643
|
}
|
|
548
644
|
|
|
549
645
|
/**
|
|
@@ -573,8 +669,8 @@ class UI {
|
|
|
573
669
|
const { Installer } = require('../installers/lib/core/installer');
|
|
574
670
|
const detector = new Detector();
|
|
575
671
|
const installer = new Installer();
|
|
576
|
-
const
|
|
577
|
-
const existingInstall = await detector.detect(bmadDir);
|
|
672
|
+
const bmadDirResult = await installer.findBmadDir(directory);
|
|
673
|
+
const existingInstall = await detector.detect(bmadDirResult.bmadDir);
|
|
578
674
|
const installedModuleIds = new Set(existingInstall.modules.map((mod) => mod.id));
|
|
579
675
|
|
|
580
676
|
return { existingInstall, installedModuleIds };
|
|
@@ -593,7 +689,9 @@ class UI {
|
|
|
593
689
|
// Now collect with existing values as defaults (false = don't skip loading, true = skip completion message)
|
|
594
690
|
await configCollector.collectModuleConfig('core', directory, false, true);
|
|
595
691
|
|
|
596
|
-
|
|
692
|
+
const coreConfig = configCollector.collectedConfig.core;
|
|
693
|
+
// Ensure we always have a core config object, even if empty
|
|
694
|
+
return coreConfig || {};
|
|
597
695
|
}
|
|
598
696
|
|
|
599
697
|
/**
|
|
@@ -610,81 +708,28 @@ class UI {
|
|
|
610
708
|
const hasCustomContentItems = false;
|
|
611
709
|
|
|
612
710
|
// Add custom content items
|
|
613
|
-
if (customContentConfig && customContentConfig.hasCustomContent) {
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
path.
|
|
626
|
-
|
|
627
|
-
];
|
|
628
|
-
|
|
629
|
-
let moduleData = null;
|
|
630
|
-
let foundPath = null;
|
|
631
|
-
|
|
632
|
-
for (const configPath of possibleConfigPaths) {
|
|
633
|
-
if (await fs.pathExists(configPath)) {
|
|
634
|
-
try {
|
|
635
|
-
const yamlContent = await fs.readFile(configPath, 'utf8');
|
|
636
|
-
moduleData = yaml.load(yamlContent);
|
|
637
|
-
foundPath = configPath;
|
|
638
|
-
break;
|
|
639
|
-
} catch (error) {
|
|
640
|
-
throw new Error(`Failed to parse config at ${configPath}: ${error.message}`);
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
if (moduleData) {
|
|
646
|
-
// Use the name from the custom info if we have it
|
|
647
|
-
const moduleName = cachedModule.name || moduleData.name || cachedModule.id;
|
|
648
|
-
|
|
649
|
-
customContentItems.push({
|
|
650
|
-
name: `${chalk.cyan('✓')} ${moduleName} ${chalk.gray('(cached)')}`,
|
|
651
|
-
value: cachedModule.id, // Use module ID directly
|
|
652
|
-
checked: true, // Default to selected
|
|
653
|
-
cached: true,
|
|
654
|
-
});
|
|
655
|
-
} else {
|
|
656
|
-
// Module config not found - skip silently (non-critical)
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
} else if (customContentConfig.customPath) {
|
|
660
|
-
// Existing installation - show from directory
|
|
661
|
-
const customHandler = new CustomHandler();
|
|
662
|
-
const customFiles = await customHandler.findCustomContent(customContentConfig.customPath);
|
|
663
|
-
|
|
664
|
-
for (const customFile of customFiles) {
|
|
665
|
-
const customInfo = await customHandler.getCustomInfo(customFile);
|
|
666
|
-
if (customInfo) {
|
|
667
|
-
customContentItems.push({
|
|
668
|
-
name: `${chalk.cyan('✓')} ${customInfo.name} ${chalk.gray(`(${customInfo.relativePath})`)}`,
|
|
669
|
-
value: `__CUSTOM_CONTENT__${customFile}`, // Unique value for each custom content
|
|
670
|
-
checked: true, // Default to selected since user chose to provide custom content
|
|
671
|
-
path: customInfo.path, // Track path to avoid duplicates
|
|
672
|
-
});
|
|
673
|
-
}
|
|
711
|
+
if (customContentConfig && customContentConfig.hasCustomContent && customContentConfig.customPath) {
|
|
712
|
+
// Existing installation - show from directory
|
|
713
|
+
const customHandler = new CustomHandler();
|
|
714
|
+
const customFiles = await customHandler.findCustomContent(customContentConfig.customPath);
|
|
715
|
+
|
|
716
|
+
for (const customFile of customFiles) {
|
|
717
|
+
const customInfo = await customHandler.getCustomInfo(customFile);
|
|
718
|
+
if (customInfo) {
|
|
719
|
+
customContentItems.push({
|
|
720
|
+
name: `${chalk.cyan('✓')} ${customInfo.name} ${chalk.gray(`(${customInfo.relativePath})`)}`,
|
|
721
|
+
value: `__CUSTOM_CONTENT__${customFile}`, // Unique value for each custom content
|
|
722
|
+
checked: true, // Default to selected since user chose to provide custom content
|
|
723
|
+
path: customInfo.path, // Track path to avoid duplicates
|
|
724
|
+
});
|
|
674
725
|
}
|
|
675
726
|
}
|
|
676
727
|
}
|
|
677
728
|
|
|
678
729
|
// Add official modules
|
|
679
730
|
const { ModuleManager } = require('../installers/lib/modules/manager');
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
const shouldScanProject =
|
|
683
|
-
!isNewInstallation && customContentConfig && customContentConfig.hasCustomContent && customContentConfig.selected;
|
|
684
|
-
const moduleManager = new ModuleManager({
|
|
685
|
-
scanProjectForModules: shouldScanProject,
|
|
686
|
-
});
|
|
687
|
-
const { modules: availableModules, customModules: customModulesFromProject } = await moduleManager.listAvailable();
|
|
731
|
+
const moduleManager = new ModuleManager();
|
|
732
|
+
const { modules: availableModules, customModules: customModulesFromCache } = await moduleManager.listAvailable();
|
|
688
733
|
|
|
689
734
|
// First, add all items to appropriate sections
|
|
690
735
|
const allCustomModules = [];
|
|
@@ -692,14 +737,14 @@ class UI {
|
|
|
692
737
|
// Add custom content items from directory
|
|
693
738
|
allCustomModules.push(...customContentItems);
|
|
694
739
|
|
|
695
|
-
// Add custom modules from
|
|
696
|
-
for (const mod of
|
|
740
|
+
// Add custom modules from cache
|
|
741
|
+
for (const mod of customModulesFromCache) {
|
|
697
742
|
// Skip if this module is already in customContentItems (by path)
|
|
698
743
|
const isDuplicate = allCustomModules.some((item) => item.path && mod.path && path.resolve(item.path) === path.resolve(mod.path));
|
|
699
744
|
|
|
700
745
|
if (!isDuplicate) {
|
|
701
746
|
allCustomModules.push({
|
|
702
|
-
name: `${chalk.cyan('✓')} ${mod.name} ${chalk.gray(`(
|
|
747
|
+
name: `${chalk.cyan('✓')} ${mod.name} ${chalk.gray(`(cached)`)}`,
|
|
703
748
|
value: mod.id,
|
|
704
749
|
checked: isNewInstallation ? mod.defaultSelected || false : installedModuleIds.has(mod.id),
|
|
705
750
|
});
|
|
@@ -735,19 +780,20 @@ class UI {
|
|
|
735
780
|
* @param {Array} moduleChoices - Available module choices
|
|
736
781
|
* @returns {Array} Selected module IDs
|
|
737
782
|
*/
|
|
738
|
-
async selectModules(moduleChoices) {
|
|
739
|
-
CLIUtils.displaySection('Module Selection', 'Choose the BMAD modules to install');
|
|
740
|
-
|
|
783
|
+
async selectModules(moduleChoices, defaultSelections = []) {
|
|
741
784
|
const moduleAnswer = await inquirer.prompt([
|
|
742
785
|
{
|
|
743
786
|
type: 'checkbox',
|
|
744
787
|
name: 'modules',
|
|
745
788
|
message: 'Select modules to install:',
|
|
746
789
|
choices: moduleChoices,
|
|
790
|
+
default: defaultSelections,
|
|
747
791
|
},
|
|
748
792
|
]);
|
|
749
793
|
|
|
750
|
-
|
|
794
|
+
const selected = moduleAnswer.modules || [];
|
|
795
|
+
|
|
796
|
+
return selected;
|
|
751
797
|
}
|
|
752
798
|
|
|
753
799
|
/**
|
|
@@ -787,15 +833,16 @@ class UI {
|
|
|
787
833
|
if (stats.isDirectory()) {
|
|
788
834
|
const files = await fs.readdir(directory);
|
|
789
835
|
if (files.length > 0) {
|
|
790
|
-
// Check for any bmad installation (any folder with
|
|
836
|
+
// Check for any bmad installation (any folder with _config/manifest.yaml)
|
|
791
837
|
const { Installer } = require('../installers/lib/core/installer');
|
|
792
838
|
const installer = new Installer();
|
|
793
|
-
const
|
|
794
|
-
const hasBmadInstall =
|
|
839
|
+
const bmadResult = await installer.findBmadDir(directory);
|
|
840
|
+
const hasBmadInstall =
|
|
841
|
+
(await fs.pathExists(bmadResult.bmadDir)) && (await fs.pathExists(path.join(bmadResult.bmadDir, '_config', 'manifest.yaml')));
|
|
795
842
|
|
|
796
843
|
console.log(
|
|
797
844
|
chalk.gray(`Directory exists and contains ${files.length} item(s)`) +
|
|
798
|
-
(hasBmadInstall ? chalk.yellow(` including existing BMAD installation (${path.basename(bmadDir)})`) : ''),
|
|
845
|
+
(hasBmadInstall ? chalk.yellow(` including existing BMAD installation (${path.basename(bmadResult.bmadDir)})`) : ''),
|
|
799
846
|
);
|
|
800
847
|
} else {
|
|
801
848
|
console.log(chalk.gray('Directory exists and is empty'));
|
|
@@ -804,120 +851,6 @@ class UI {
|
|
|
804
851
|
}
|
|
805
852
|
}
|
|
806
853
|
|
|
807
|
-
/**
|
|
808
|
-
* Prompt for custom content location
|
|
809
|
-
* @returns {Object} Custom content configuration
|
|
810
|
-
*/
|
|
811
|
-
async promptCustomContentLocation() {
|
|
812
|
-
try {
|
|
813
|
-
// Skip custom content installation - always return false
|
|
814
|
-
return { hasCustomContent: false };
|
|
815
|
-
|
|
816
|
-
// TODO: Custom content installation temporarily disabled
|
|
817
|
-
// CLIUtils.displaySection('Custom Content', 'Optional: Add custom agents, workflows, and modules');
|
|
818
|
-
|
|
819
|
-
// const { hasCustomContent } = await inquirer.prompt([
|
|
820
|
-
// {
|
|
821
|
-
// type: 'list',
|
|
822
|
-
// name: 'hasCustomContent',
|
|
823
|
-
// message: 'Do you have custom content to install?',
|
|
824
|
-
// choices: [
|
|
825
|
-
// { name: 'No (skip custom content)', value: 'none' },
|
|
826
|
-
// { name: 'Enter a directory path', value: 'directory' },
|
|
827
|
-
// { name: 'Enter a URL', value: 'url' },
|
|
828
|
-
// ],
|
|
829
|
-
// default: 'none',
|
|
830
|
-
// },
|
|
831
|
-
// ]);
|
|
832
|
-
|
|
833
|
-
// if (hasCustomContent === 'none') {
|
|
834
|
-
// return { hasCustomContent: false };
|
|
835
|
-
// }
|
|
836
|
-
|
|
837
|
-
// TODO: Custom content installation temporarily disabled
|
|
838
|
-
// if (hasCustomContent === 'url') {
|
|
839
|
-
// console.log(chalk.yellow('\nURL-based custom content installation is coming soon!'));
|
|
840
|
-
// console.log(chalk.cyan('For now, please download your custom content and choose "Enter a directory path".\n'));
|
|
841
|
-
// return { hasCustomContent: false };
|
|
842
|
-
// }
|
|
843
|
-
|
|
844
|
-
// if (hasCustomContent === 'directory') {
|
|
845
|
-
// let customPath;
|
|
846
|
-
// while (!customPath) {
|
|
847
|
-
// let expandedPath;
|
|
848
|
-
// const { directory } = await inquirer.prompt([
|
|
849
|
-
// {
|
|
850
|
-
// type: 'input',
|
|
851
|
-
// name: 'directory',
|
|
852
|
-
// message: 'Enter directory to search for custom content (will scan subfolders):',
|
|
853
|
-
// default: process.cwd(), // Use actual current working directory
|
|
854
|
-
// validate: async (input) => {
|
|
855
|
-
// if (!input || input.trim() === '') {
|
|
856
|
-
// return 'Please enter a directory path';
|
|
857
|
-
// }
|
|
858
|
-
|
|
859
|
-
// try {
|
|
860
|
-
// expandedPath = this.expandUserPath(input.trim());
|
|
861
|
-
// } catch (error) {
|
|
862
|
-
// return error.message;
|
|
863
|
-
// }
|
|
864
|
-
|
|
865
|
-
// // Check if the path exists
|
|
866
|
-
// const pathExists = await fs.pathExists(expandedPath);
|
|
867
|
-
// if (!pathExists) {
|
|
868
|
-
// return 'Directory does not exist';
|
|
869
|
-
// }
|
|
870
|
-
|
|
871
|
-
// return true;
|
|
872
|
-
// },
|
|
873
|
-
// },
|
|
874
|
-
// ]);
|
|
875
|
-
|
|
876
|
-
// // Now expand the path for use after the prompt
|
|
877
|
-
// expandedPath = this.expandUserPath(directory.trim());
|
|
878
|
-
|
|
879
|
-
// // Check if directory has custom content
|
|
880
|
-
// const customHandler = new CustomHandler();
|
|
881
|
-
// const customFiles = await customHandler.findCustomContent(expandedPath);
|
|
882
|
-
|
|
883
|
-
// if (customFiles.length === 0) {
|
|
884
|
-
// console.log(chalk.yellow(`\nNo custom content found in ${expandedPath}`));
|
|
885
|
-
|
|
886
|
-
// const { tryAgain } = await inquirer.prompt([
|
|
887
|
-
// {
|
|
888
|
-
// type: 'confirm',
|
|
889
|
-
// name: 'tryAgain',
|
|
890
|
-
// message: 'Try a different directory?',
|
|
891
|
-
// default: true,
|
|
892
|
-
// },
|
|
893
|
-
// ]);
|
|
894
|
-
|
|
895
|
-
// if (tryAgain) {
|
|
896
|
-
// continue;
|
|
897
|
-
// } else {
|
|
898
|
-
// return { hasCustomContent: false };
|
|
899
|
-
// }
|
|
900
|
-
// }
|
|
901
|
-
|
|
902
|
-
// customPath = expandedPath;
|
|
903
|
-
// console.log(chalk.green(`\n✓ Found ${customFiles.length} custom content item(s):`));
|
|
904
|
-
// for (const file of customFiles) {
|
|
905
|
-
// const relativePath = path.relative(expandedPath, path.dirname(file));
|
|
906
|
-
// const folderName = path.dirname(file).split(path.sep).pop();
|
|
907
|
-
// console.log(chalk.dim(` • ${folderName} ${chalk.gray(`(${relativePath})`)}`));
|
|
908
|
-
// }
|
|
909
|
-
// }
|
|
910
|
-
|
|
911
|
-
// return { hasCustomContent: true, customPath };
|
|
912
|
-
// }
|
|
913
|
-
|
|
914
|
-
// return { hasCustomContent: false };
|
|
915
|
-
} catch (error) {
|
|
916
|
-
console.error(chalk.red('Error in custom content prompt:'), error);
|
|
917
|
-
return { hasCustomContent: false };
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
|
|
921
854
|
/**
|
|
922
855
|
* Confirm directory selection
|
|
923
856
|
* @param {string} directory - The directory path
|
|
@@ -1205,143 +1138,324 @@ class UI {
|
|
|
1205
1138
|
}
|
|
1206
1139
|
|
|
1207
1140
|
/**
|
|
1208
|
-
*
|
|
1209
|
-
* @
|
|
1141
|
+
* Load existing configurations to use as defaults
|
|
1142
|
+
* @param {string} directory - Installation directory
|
|
1143
|
+
* @returns {Object} Existing configurations
|
|
1210
1144
|
*/
|
|
1211
|
-
async
|
|
1145
|
+
async loadExistingConfigurations(directory) {
|
|
1146
|
+
const configs = {
|
|
1147
|
+
hasCustomContent: false,
|
|
1148
|
+
coreConfig: {},
|
|
1149
|
+
ideConfig: { ides: [], skipIde: false },
|
|
1150
|
+
agentVibesConfig: { enabled: false, alreadyInstalled: false },
|
|
1151
|
+
};
|
|
1152
|
+
|
|
1212
1153
|
try {
|
|
1213
|
-
//
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
//
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
//
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
//
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
//
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1154
|
+
// Load core config
|
|
1155
|
+
configs.coreConfig = await this.collectCoreConfig(directory);
|
|
1156
|
+
|
|
1157
|
+
// Load IDE configuration
|
|
1158
|
+
const configuredIdes = await this.getConfiguredIdes(directory);
|
|
1159
|
+
if (configuredIdes.length > 0) {
|
|
1160
|
+
configs.ideConfig.ides = configuredIdes;
|
|
1161
|
+
configs.ideConfig.skipIde = false;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
// Load AgentVibes configuration
|
|
1165
|
+
const agentVibesInstalled = await this.checkAgentVibesInstalled(directory);
|
|
1166
|
+
configs.agentVibesConfig = { enabled: agentVibesInstalled, alreadyInstalled: agentVibesInstalled };
|
|
1167
|
+
|
|
1168
|
+
return configs;
|
|
1169
|
+
} catch {
|
|
1170
|
+
// If loading fails, return empty configs
|
|
1171
|
+
console.warn('Warning: Could not load existing configurations');
|
|
1172
|
+
return configs;
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
/**
|
|
1177
|
+
* Get configured IDEs from existing installation
|
|
1178
|
+
* @param {string} directory - Installation directory
|
|
1179
|
+
* @returns {Array} List of configured IDEs
|
|
1180
|
+
*/
|
|
1181
|
+
async getConfiguredIdes(directory) {
|
|
1182
|
+
const { Detector } = require('../installers/lib/core/detector');
|
|
1183
|
+
const { Installer } = require('../installers/lib/core/installer');
|
|
1184
|
+
const detector = new Detector();
|
|
1185
|
+
const installer = new Installer();
|
|
1186
|
+
const bmadResult = await installer.findBmadDir(directory);
|
|
1187
|
+
const existingInstall = await detector.detect(bmadResult.bmadDir);
|
|
1188
|
+
return existingInstall.ides || [];
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
/**
|
|
1192
|
+
* Prompt user for custom content source location
|
|
1193
|
+
* @returns {Object} Custom content configuration
|
|
1194
|
+
*/
|
|
1195
|
+
async promptCustomContentSource() {
|
|
1196
|
+
const customContentConfig = { hasCustomContent: true, sources: [] };
|
|
1197
|
+
|
|
1198
|
+
// Keep asking for more sources until user is done
|
|
1199
|
+
while (true) {
|
|
1200
|
+
// First ask if user wants to add another module or continue
|
|
1201
|
+
if (customContentConfig.sources.length > 0) {
|
|
1202
|
+
const { action } = await inquirer.prompt([
|
|
1203
|
+
{
|
|
1204
|
+
type: 'list',
|
|
1205
|
+
name: 'action',
|
|
1206
|
+
message: 'Would you like to:',
|
|
1207
|
+
choices: [
|
|
1208
|
+
{ name: 'Add another custom module', value: 'add' },
|
|
1209
|
+
{ name: 'Continue with installation', value: 'continue' },
|
|
1210
|
+
],
|
|
1211
|
+
default: 'continue',
|
|
1212
|
+
},
|
|
1213
|
+
]);
|
|
1214
|
+
|
|
1215
|
+
if (action === 'continue') {
|
|
1216
|
+
break;
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
let sourcePath;
|
|
1221
|
+
let isValid = false;
|
|
1222
|
+
|
|
1223
|
+
while (!isValid) {
|
|
1224
|
+
const { path: inputPath } = await inquirer.prompt([
|
|
1225
|
+
{
|
|
1226
|
+
type: 'input',
|
|
1227
|
+
name: 'path',
|
|
1228
|
+
message: 'Enter the path to your custom content folder (or press Enter to cancel):',
|
|
1229
|
+
validate: async (input) => {
|
|
1230
|
+
// Allow empty input to cancel
|
|
1231
|
+
if (!input || input.trim() === '') {
|
|
1232
|
+
return true; // Allow empty to exit
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
try {
|
|
1236
|
+
// Expand the path
|
|
1237
|
+
const expandedPath = this.expandUserPath(input.trim());
|
|
1238
|
+
|
|
1239
|
+
// Check if path exists
|
|
1240
|
+
if (!(await fs.pathExists(expandedPath))) {
|
|
1241
|
+
return 'Path does not exist';
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
// Check if it's a directory
|
|
1245
|
+
const stat = await fs.stat(expandedPath);
|
|
1246
|
+
if (!stat.isDirectory()) {
|
|
1247
|
+
return 'Path must be a directory';
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
// Check for module.yaml in the root
|
|
1251
|
+
const moduleYamlPath = path.join(expandedPath, 'module.yaml');
|
|
1252
|
+
if (!(await fs.pathExists(moduleYamlPath))) {
|
|
1253
|
+
return 'Directory must contain a module.yaml file in the root';
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
// Try to parse the module.yaml to get the module ID
|
|
1257
|
+
try {
|
|
1258
|
+
const yaml = require('yaml');
|
|
1259
|
+
const content = await fs.readFile(moduleYamlPath, 'utf8');
|
|
1260
|
+
const moduleData = yaml.parse(content);
|
|
1261
|
+
if (!moduleData.code) {
|
|
1262
|
+
return 'module.yaml must contain a "code" field for the module ID';
|
|
1263
|
+
}
|
|
1264
|
+
} catch (error) {
|
|
1265
|
+
return 'Invalid module.yaml file: ' + error.message;
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
return true;
|
|
1269
|
+
} catch (error) {
|
|
1270
|
+
return 'Error validating path: ' + error.message;
|
|
1271
|
+
}
|
|
1272
|
+
},
|
|
1273
|
+
},
|
|
1274
|
+
]);
|
|
1275
|
+
|
|
1276
|
+
// If user pressed Enter without typing anything, exit the loop
|
|
1277
|
+
if (!inputPath || inputPath.trim() === '') {
|
|
1278
|
+
// If we have no modules yet, return false for no custom content
|
|
1279
|
+
if (customContentConfig.sources.length === 0) {
|
|
1280
|
+
return { hasCustomContent: false };
|
|
1281
|
+
}
|
|
1282
|
+
return customContentConfig;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
sourcePath = this.expandUserPath(inputPath);
|
|
1286
|
+
isValid = true;
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
// Read module.yaml to get module info
|
|
1290
|
+
const yaml = require('yaml');
|
|
1291
|
+
const moduleYamlPath = path.join(sourcePath, 'module.yaml');
|
|
1292
|
+
const moduleContent = await fs.readFile(moduleYamlPath, 'utf8');
|
|
1293
|
+
const moduleData = yaml.parse(moduleContent);
|
|
1294
|
+
|
|
1295
|
+
// Add to sources
|
|
1296
|
+
customContentConfig.sources.push({
|
|
1297
|
+
path: sourcePath,
|
|
1298
|
+
id: moduleData.code,
|
|
1299
|
+
name: moduleData.name || moduleData.code,
|
|
1300
|
+
});
|
|
1301
|
+
|
|
1302
|
+
console.log(chalk.green(`✓ Confirmed local custom module: ${moduleData.name || moduleData.code}`));
|
|
1344
1303
|
}
|
|
1304
|
+
|
|
1305
|
+
// Ask if user wants to add these to the installation
|
|
1306
|
+
const { shouldInstall } = await inquirer.prompt([
|
|
1307
|
+
{
|
|
1308
|
+
type: 'confirm',
|
|
1309
|
+
name: 'shouldInstall',
|
|
1310
|
+
message: `Install ${customContentConfig.sources.length} custom module(s) now?`,
|
|
1311
|
+
default: true,
|
|
1312
|
+
},
|
|
1313
|
+
]);
|
|
1314
|
+
|
|
1315
|
+
if (shouldInstall) {
|
|
1316
|
+
customContentConfig.selected = true;
|
|
1317
|
+
// Store paths to module.yaml files, not directories
|
|
1318
|
+
customContentConfig.selectedFiles = customContentConfig.sources.map((s) => path.join(s.path, 'module.yaml'));
|
|
1319
|
+
// Also include module IDs for installation
|
|
1320
|
+
customContentConfig.selectedModuleIds = customContentConfig.sources.map((s) => s.id);
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
return customContentConfig;
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
/**
|
|
1327
|
+
* Handle custom modules in the modify flow
|
|
1328
|
+
* @param {string} directory - Installation directory
|
|
1329
|
+
* @param {Array} selectedModules - Currently selected modules
|
|
1330
|
+
* @returns {Object} Result with selected custom modules and custom content config
|
|
1331
|
+
*/
|
|
1332
|
+
async handleCustomModulesInModifyFlow(directory, selectedModules) {
|
|
1333
|
+
// Get existing installation to find custom modules
|
|
1334
|
+
const { existingInstall } = await this.getExistingInstallation(directory);
|
|
1335
|
+
|
|
1336
|
+
// Check if there are any custom modules in cache
|
|
1337
|
+
const { Installer } = require('../installers/lib/core/installer');
|
|
1338
|
+
const installer = new Installer();
|
|
1339
|
+
const { bmadDir } = await installer.findBmadDir(directory);
|
|
1340
|
+
|
|
1341
|
+
const cacheDir = path.join(bmadDir, '_config', 'custom');
|
|
1342
|
+
const cachedCustomModules = [];
|
|
1343
|
+
|
|
1344
|
+
if (await fs.pathExists(cacheDir)) {
|
|
1345
|
+
const entries = await fs.readdir(cacheDir, { withFileTypes: true });
|
|
1346
|
+
for (const entry of entries) {
|
|
1347
|
+
if (entry.isDirectory()) {
|
|
1348
|
+
const moduleYamlPath = path.join(cacheDir, entry.name, 'module.yaml');
|
|
1349
|
+
if (await fs.pathExists(moduleYamlPath)) {
|
|
1350
|
+
const yaml = require('yaml');
|
|
1351
|
+
const content = await fs.readFile(moduleYamlPath, 'utf8');
|
|
1352
|
+
const moduleData = yaml.parse(content);
|
|
1353
|
+
|
|
1354
|
+
cachedCustomModules.push({
|
|
1355
|
+
id: entry.name,
|
|
1356
|
+
name: moduleData.name || entry.name,
|
|
1357
|
+
description: moduleData.description || 'Custom module from cache',
|
|
1358
|
+
checked: selectedModules.includes(entry.name),
|
|
1359
|
+
fromCache: true,
|
|
1360
|
+
});
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
const result = {
|
|
1367
|
+
selectedCustomModules: [],
|
|
1368
|
+
customContentConfig: { hasCustomContent: false },
|
|
1369
|
+
};
|
|
1370
|
+
|
|
1371
|
+
// Ask user about custom modules
|
|
1372
|
+
console.log(chalk.cyan('\n⚙️ Custom Modules'));
|
|
1373
|
+
if (cachedCustomModules.length > 0) {
|
|
1374
|
+
console.log(chalk.dim('Found custom modules in your installation:'));
|
|
1375
|
+
} else {
|
|
1376
|
+
console.log(chalk.dim('No custom modules currently installed.'));
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
// Build choices dynamically based on whether we have existing modules
|
|
1380
|
+
const choices = [];
|
|
1381
|
+
if (cachedCustomModules.length > 0) {
|
|
1382
|
+
choices.push(
|
|
1383
|
+
{ name: 'Keep all existing custom modules', value: 'keep' },
|
|
1384
|
+
{ name: 'Select which custom modules to keep', value: 'select' },
|
|
1385
|
+
{ name: 'Add new custom modules', value: 'add' },
|
|
1386
|
+
{ name: 'Remove all custom modules', value: 'remove' },
|
|
1387
|
+
);
|
|
1388
|
+
} else {
|
|
1389
|
+
choices.push({ name: 'Add new custom modules', value: 'add' }, { name: 'Cancel (no custom modules)', value: 'cancel' });
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
const { customAction } = await inquirer.prompt([
|
|
1393
|
+
{
|
|
1394
|
+
type: 'list',
|
|
1395
|
+
name: 'customAction',
|
|
1396
|
+
message:
|
|
1397
|
+
cachedCustomModules.length > 0 ? 'What would you like to do with custom modules?' : 'Would you like to add custom modules?',
|
|
1398
|
+
choices: choices,
|
|
1399
|
+
default: cachedCustomModules.length > 0 ? 'keep' : 'add',
|
|
1400
|
+
},
|
|
1401
|
+
]);
|
|
1402
|
+
|
|
1403
|
+
switch (customAction) {
|
|
1404
|
+
case 'keep': {
|
|
1405
|
+
// Keep all existing custom modules
|
|
1406
|
+
result.selectedCustomModules = cachedCustomModules.map((m) => m.id);
|
|
1407
|
+
console.log(chalk.dim(`Keeping ${result.selectedCustomModules.length} custom module(s)`));
|
|
1408
|
+
break;
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
case 'select': {
|
|
1412
|
+
// Let user choose which to keep
|
|
1413
|
+
const choices = cachedCustomModules.map((m) => ({
|
|
1414
|
+
name: `${m.name} ${chalk.gray(`(${m.id})`)}`,
|
|
1415
|
+
value: m.id,
|
|
1416
|
+
}));
|
|
1417
|
+
|
|
1418
|
+
const { keepModules } = await inquirer.prompt([
|
|
1419
|
+
{
|
|
1420
|
+
type: 'checkbox',
|
|
1421
|
+
name: 'keepModules',
|
|
1422
|
+
message: 'Select custom modules to keep:',
|
|
1423
|
+
choices: choices,
|
|
1424
|
+
default: cachedCustomModules.filter((m) => m.checked).map((m) => m.id),
|
|
1425
|
+
},
|
|
1426
|
+
]);
|
|
1427
|
+
result.selectedCustomModules = keepModules;
|
|
1428
|
+
break;
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
case 'add': {
|
|
1432
|
+
// By default, keep existing modules when adding new ones
|
|
1433
|
+
// User chose "Add new" not "Replace", so we assume they want to keep existing
|
|
1434
|
+
result.selectedCustomModules = cachedCustomModules.map((m) => m.id);
|
|
1435
|
+
|
|
1436
|
+
// Then prompt for new ones (reuse existing method)
|
|
1437
|
+
const newCustomContent = await this.promptCustomContentSource();
|
|
1438
|
+
if (newCustomContent.hasCustomContent && newCustomContent.selected) {
|
|
1439
|
+
result.selectedCustomModules.push(...newCustomContent.selectedModuleIds);
|
|
1440
|
+
result.customContentConfig = newCustomContent;
|
|
1441
|
+
}
|
|
1442
|
+
break;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
case 'remove': {
|
|
1446
|
+
// Remove all custom modules
|
|
1447
|
+
console.log(chalk.yellow('All custom modules will be removed from the installation'));
|
|
1448
|
+
break;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
case 'cancel': {
|
|
1452
|
+
// User cancelled - no custom modules
|
|
1453
|
+
console.log(chalk.dim('No custom modules will be added'));
|
|
1454
|
+
break;
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
return result;
|
|
1345
1459
|
}
|
|
1346
1460
|
}
|
|
1347
1461
|
|