ma-agents 2.22.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.opencode/skills/.ma-agents.json +99 -99
- package/lib/bmad-cache/bmb/.claude-plugin/marketplace.json +22 -0
- package/lib/bmad-cache/bmb/.markdownlint-cli2.yaml +1 -0
- package/lib/bmad-cache/bmb/_git_preserved/index +0 -0
- package/lib/bmad-cache/bmb/_git_preserved/logs/HEAD +1 -1
- package/lib/bmad-cache/bmb/_git_preserved/logs/refs/heads/main +1 -1
- package/lib/bmad-cache/bmb/_git_preserved/logs/refs/remotes/origin/HEAD +1 -1
- package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-0de89e0854d5b2b3b3b0c1ee56eee73a739f15e7.idx +0 -0
- package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-0de89e0854d5b2b3b3b0c1ee56eee73a739f15e7.pack +0 -0
- package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-0de89e0854d5b2b3b3b0c1ee56eee73a739f15e7.rev +0 -0
- package/lib/bmad-cache/bmb/_git_preserved/packed-refs +1 -1
- package/lib/bmad-cache/bmb/_git_preserved/refs/heads/main +1 -1
- package/lib/bmad-cache/bmb/_git_preserved/shallow +1 -1
- package/lib/bmad-cache/bmb/package-lock.json +2 -2
- package/lib/bmad-cache/bmb/package.json +7 -4
- package/lib/bmad-cache/bmb/skills/bmad-agent-builder/scripts/generate-html-report.py +534 -0
- package/lib/bmad-cache/bmb/{src/skills → skills}/bmad-agent-builder/scripts/prepass-execution-deps.py +4 -35
- package/lib/bmad-cache/bmb/{src/skills → skills}/bmad-agent-builder/scripts/prepass-prompt-metrics.py +2 -75
- package/lib/bmad-cache/bmb/{src/skills → skills}/bmad-agent-builder/scripts/prepass-structure-capabilities.py +3 -194
- package/lib/bmad-cache/bmb/{src/skills → skills}/bmad-agent-builder/scripts/scan-path-standards.py +104 -18
- package/lib/bmad-cache/bmb/skills/bmad-builder-setup/assets/module-help.csv +6 -0
- package/lib/bmad-cache/bmb/skills/bmad-builder-setup/assets/module.yaml +20 -0
- package/lib/bmad-cache/bmb/skills/bmad-builder-setup/scripts/cleanup-legacy.py +259 -0
- package/lib/bmad-cache/bmb/skills/bmad-builder-setup/scripts/merge-config.py +408 -0
- package/lib/bmad-cache/bmb/skills/bmad-builder-setup/scripts/merge-help-csv.py +220 -0
- package/lib/bmad-cache/bmb/skills/bmad-builder-setup/scripts/tests/test-cleanup-legacy.py +429 -0
- package/lib/bmad-cache/bmb/skills/bmad-builder-setup/scripts/tests/test-merge-config.py +644 -0
- package/lib/bmad-cache/bmb/skills/bmad-builder-setup/scripts/tests/test-merge-help-csv.py +237 -0
- package/lib/bmad-cache/bmb/skills/bmad-workflow-builder/scripts/generate-html-report.py +539 -0
- package/lib/bmad-cache/bmb/{src/skills → skills}/bmad-workflow-builder/scripts/prepass-execution-deps.py +5 -30
- package/lib/bmad-cache/bmb/{src/skills → skills}/bmad-workflow-builder/scripts/prepass-workflow-integrity.py +0 -5
- package/lib/bmad-cache/bmb/{src/skills → skills}/bmad-workflow-builder/scripts/scan-path-standards.py +103 -16
- package/lib/bmad-cache/bmb/skills/module-help.csv +6 -0
- package/lib/bmad-cache/bmb/skills/module.yaml +20 -0
- package/lib/bmad-cache/bmb/tools/validate-doc-links.cjs +407 -0
- package/lib/bmad-cache/bmb/tools/validate-file-refs.mjs +1 -1
- package/lib/bmad-cache/cache-manifest.json +16 -10
- package/lib/bmad-cache/cis/.claude-plugin/marketplace.json +33 -0
- package/lib/bmad-cache/cis/_git_preserved/index +0 -0
- package/lib/bmad-cache/cis/_git_preserved/logs/HEAD +1 -1
- package/lib/bmad-cache/cis/_git_preserved/logs/refs/heads/main +1 -1
- package/lib/bmad-cache/cis/_git_preserved/logs/refs/remotes/origin/HEAD +1 -1
- package/lib/bmad-cache/cis/_git_preserved/objects/pack/pack-9d60aae6b09bbea0d0c5e79fdbe96e8f66de84e6.idx +0 -0
- package/lib/bmad-cache/cis/_git_preserved/objects/pack/{pack-157d7eb8d527233a8607d926fc74ebf87f2ae0d3.pack → pack-9d60aae6b09bbea0d0c5e79fdbe96e8f66de84e6.pack} +0 -0
- package/lib/bmad-cache/cis/_git_preserved/objects/pack/pack-9d60aae6b09bbea0d0c5e79fdbe96e8f66de84e6.rev +0 -0
- package/lib/bmad-cache/cis/_git_preserved/packed-refs +1 -1
- package/lib/bmad-cache/cis/_git_preserved/refs/heads/main +1 -1
- package/lib/bmad-cache/cis/_git_preserved/shallow +1 -1
- package/lib/bmad-cache/cis/package-lock.json +17015 -0
- package/lib/bmad-cache/cis/package.json +3 -4
- package/lib/bmad-cache/cis/src/module-help.csv +6 -6
- package/lib/bmad-cache/cis/src/skills/bmad-cis-agent-brainstorming-coach/bmad-skill-manifest.yaml +11 -0
- package/lib/bmad-cache/cis/src/skills/bmad-cis-agent-creative-problem-solver/bmad-skill-manifest.yaml +11 -0
- package/lib/bmad-cache/cis/src/skills/bmad-cis-agent-design-thinking-coach/bmad-skill-manifest.yaml +11 -0
- package/lib/bmad-cache/cis/src/skills/bmad-cis-agent-innovation-strategist/bmad-skill-manifest.yaml +11 -0
- package/lib/bmad-cache/cis/src/skills/bmad-cis-agent-presentation-master/bmad-skill-manifest.yaml +11 -0
- package/lib/bmad-cache/cis/src/skills/bmad-cis-agent-storyteller/bmad-skill-manifest.yaml +11 -0
- package/lib/bmad-cache/gds/.claude-plugin/marketplace.json +58 -0
- package/lib/bmad-cache/gds/_git_preserved/index +0 -0
- package/lib/bmad-cache/gds/_git_preserved/logs/HEAD +1 -1
- package/lib/bmad-cache/gds/_git_preserved/logs/refs/heads/main +1 -1
- package/lib/bmad-cache/gds/_git_preserved/logs/refs/remotes/origin/HEAD +1 -1
- package/lib/bmad-cache/gds/_git_preserved/objects/pack/pack-8099a88fca0ad946a573316a00887a2921ca1712.idx +0 -0
- package/lib/bmad-cache/gds/_git_preserved/objects/pack/{pack-44faafb9245b4ca17ad81bd6c9e6fc52fb5915a1.pack → pack-8099a88fca0ad946a573316a00887a2921ca1712.pack} +0 -0
- package/lib/bmad-cache/gds/_git_preserved/objects/pack/pack-8099a88fca0ad946a573316a00887a2921ca1712.rev +0 -0
- package/lib/bmad-cache/gds/_git_preserved/packed-refs +1 -1
- package/lib/bmad-cache/gds/_git_preserved/refs/heads/main +1 -1
- package/lib/bmad-cache/gds/_git_preserved/shallow +1 -1
- package/lib/bmad-cache/gds/package.json +1 -0
- package/lib/bmad-cache/gds/src/module-help.csv +35 -35
- package/lib/bmad-cache/tea/.claude-plugin/marketplace.json +33 -0
- package/lib/bmad-cache/tea/CHANGELOG.md +2 -14
- package/lib/bmad-cache/tea/README.md +31 -18
- package/lib/bmad-cache/tea/_git_preserved/index +0 -0
- package/lib/bmad-cache/tea/_git_preserved/objects/pack/pack-d243f64f83b36190434d68872a69a40870c53030.idx +0 -0
- package/lib/bmad-cache/tea/_git_preserved/objects/pack/{pack-96ec1ce3a9ef4c891e00e060795b4434ba8f7163.pack → pack-d243f64f83b36190434d68872a69a40870c53030.pack} +0 -0
- package/lib/bmad-cache/tea/_git_preserved/objects/pack/pack-d243f64f83b36190434d68872a69a40870c53030.rev +0 -0
- package/lib/bmad-cache/tea/_git_preserved/packed-refs +1 -1
- package/lib/bmad-cache/tea/_git_preserved/refs/heads/main +1 -1
- package/lib/bmad-cache/tea/_git_preserved/refs/tags/v1.7.3 +1 -0
- package/lib/bmad-cache/tea/_git_preserved/shallow +1 -1
- package/lib/bmad-cache/tea/docs/explanation/knowledge-base-system.md +5 -5
- package/lib/bmad-cache/tea/docs/explanation/step-file-architecture.md +2 -2
- package/lib/bmad-cache/tea/docs/explanation/tea-overview.md +3 -3
- package/lib/bmad-cache/tea/docs/glossary/index.md +1 -1
- package/lib/bmad-cache/tea/docs/how-to/customization/extend-tea-with-custom-workflows.md +73 -0
- package/lib/bmad-cache/tea/docs/how-to/workflows/teach-me-testing.md +7 -7
- package/lib/bmad-cache/tea/docs/index.md +2 -1
- package/lib/bmad-cache/tea/docs/reference/commands.md +4 -1
- package/lib/bmad-cache/tea/docs/reference/configuration.md +37 -15
- package/lib/bmad-cache/tea/docs/reference/knowledge-base.md +75 -73
- package/lib/bmad-cache/tea/docs/reference/troubleshooting.md +32 -19
- package/lib/bmad-cache/tea/docs/tutorials/learn-testing-tea-academy.md +3 -3
- package/lib/bmad-cache/tea/package-lock.json +2 -2
- package/lib/bmad-cache/tea/package.json +2 -1
- package/lib/bmad-cache/tea/src/agents/bmad-tea/SKILL.md +70 -0
- package/lib/bmad-cache/tea/src/agents/bmad-tea/bmad-skill-manifest.yaml +14 -0
- package/lib/bmad-cache/tea/src/module-help.csv +10 -10
- package/lib/bmad-cache/tea/src/module.yaml +8 -8
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/checklist.md +1 -1
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/data/curriculum.yaml +1 -1
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/data/session-content-map.yaml +26 -14
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/data/tea-resources-index.yaml +108 -73
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/instructions.md +2 -2
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-03-session-menu.md +1 -1
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-01.md +3 -3
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-04-session-07.md +14 -6
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/steps-c/step-05-completion.md +3 -3
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/templates/certificate-template.md +1 -1
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-teach-me-testing/workflow-plan-teach-me-testing.md +8 -8
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/atdd-checklist-template.md +1 -1
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-01-preflight-and-context.md +3 -3
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-04a-subagent-api-failing.md +9 -1
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/steps-c/step-01-preflight-and-context.md +1 -1
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-automate/steps-c/step-03b-subagent-e2e.md +2 -2
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/steps-c/step-02-generate-pipeline.md +6 -0
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-ci/steps-c/step-03-configure-quality-gates.md +6 -1
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-framework/steps-c/step-03-scaffold-framework.md +3 -2
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-nfr/steps-c/step-01-load-context.md +1 -1
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-design/steps-c/step-02-load-context.md +1 -1
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/steps-c/step-01-load-context.md +1 -1
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-test-review/test-review-template.md +11 -11
- package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-trace/steps-c/step-01-load-context.md +1 -1
- package/lib/bmad-cache/tea/test/test-installation-components.js +85 -21
- package/lib/bmad-cache/tea/test/test-knowledge-base.js +1 -1
- package/lib/bmad-cache/tea/tools/validate-agent-schema.js +105 -5
- package/lib/bmad-cache/wds/.claude-plugin/marketplace.json +35 -0
- package/lib/bmad-cache/wds/.markdownlint-cli2.yaml +38 -0
- package/lib/bmad-cache/wds/.nvmrc +1 -0
- package/lib/bmad-cache/wds/.prettierignore +9 -0
- package/lib/bmad-cache/wds/LICENSE +27 -0
- package/lib/bmad-cache/wds/README.md +126 -0
- package/lib/bmad-cache/wds/_git_preserved/HEAD +1 -0
- package/lib/bmad-cache/wds/_git_preserved/config +13 -0
- package/lib/bmad-cache/wds/_git_preserved/description +1 -0
- package/lib/bmad-cache/wds/_git_preserved/hooks/applypatch-msg.sample +15 -0
- package/lib/bmad-cache/wds/_git_preserved/hooks/commit-msg.sample +24 -0
- package/lib/bmad-cache/wds/_git_preserved/hooks/fsmonitor-watchman.sample +174 -0
- package/lib/bmad-cache/wds/_git_preserved/hooks/post-update.sample +8 -0
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-applypatch.sample +14 -0
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-commit.sample +49 -0
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-merge-commit.sample +13 -0
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-push.sample +53 -0
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-rebase.sample +169 -0
- package/lib/bmad-cache/wds/_git_preserved/hooks/pre-receive.sample +24 -0
- package/lib/bmad-cache/wds/_git_preserved/hooks/prepare-commit-msg.sample +42 -0
- package/lib/bmad-cache/wds/_git_preserved/hooks/push-to-checkout.sample +78 -0
- package/lib/bmad-cache/wds/_git_preserved/hooks/sendemail-validate.sample +77 -0
- package/lib/bmad-cache/wds/_git_preserved/hooks/update.sample +128 -0
- package/lib/bmad-cache/wds/_git_preserved/index +0 -0
- package/lib/bmad-cache/wds/_git_preserved/info/exclude +6 -0
- package/lib/bmad-cache/wds/_git_preserved/logs/HEAD +1 -0
- package/lib/bmad-cache/wds/_git_preserved/logs/refs/heads/main +1 -0
- package/lib/bmad-cache/wds/_git_preserved/logs/refs/remotes/origin/HEAD +1 -0
- package/lib/bmad-cache/wds/_git_preserved/objects/pack/pack-92d32f26e3a97a0786dcea5cb2c24bf90384521c.idx +0 -0
- package/lib/bmad-cache/wds/_git_preserved/objects/pack/pack-92d32f26e3a97a0786dcea5cb2c24bf90384521c.pack +0 -0
- package/lib/bmad-cache/wds/_git_preserved/objects/pack/pack-92d32f26e3a97a0786dcea5cb2c24bf90384521c.rev +0 -0
- package/lib/bmad-cache/wds/_git_preserved/packed-refs +2 -0
- package/lib/bmad-cache/wds/_git_preserved/refs/heads/main +1 -0
- package/lib/bmad-cache/wds/_git_preserved/refs/remotes/origin/HEAD +1 -0
- package/lib/bmad-cache/wds/_git_preserved/shallow +1 -0
- package/lib/bmad-cache/wds/eslint.config.mjs +152 -0
- package/lib/bmad-cache/wds/package.json +82 -0
- package/lib/bmad-cache/wds/prettier.config.mjs +32 -0
- package/lib/bmad-cache/wds/src/agents/wds-agent-freya-ux/bmad-skill-manifest.yaml +12 -0
- package/lib/bmad-cache/wds/src/agents/wds-agent-saga-analyst/bmad-skill-manifest.yaml +12 -0
- package/lib/bmad-cache/wds/src/module-help.csv +18 -0
- package/lib/bmad-cache/wds/src/module.yaml +148 -0
- package/lib/bmad-cache/wds/src/workflows/wds-1-project-brief/bmad-skill-manifest.yaml +1 -0
- package/lib/bmad-cache/wds/src/workflows/wds-1-project-brief/templates/platform-requirements.template.yaml +69 -0
- package/lib/bmad-cache/wds/src/workflows/wds-2-trigger-mapping/bmad-skill-manifest.yaml +1 -0
- package/lib/bmad-cache/wds/src/workflows/wds-3-scenarios/bmad-skill-manifest.yaml +1 -0
- package/lib/bmad-cache/wds/src/workflows/wds-4-ux-design/bmad-skill-manifest.yaml +1 -0
- package/lib/bmad-cache/wds/src/workflows/wds-4-ux-design/templates/design-delivery.template.yaml +104 -0
- package/lib/bmad-cache/wds/src/workflows/wds-4-ux-design/templates/test-scenario.template.yaml +192 -0
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/bmad-skill-manifest.yaml +1 -0
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/components/dev-mode.css +164 -0
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/components/dev-mode.html +18 -0
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/components/dev-mode.js +430 -0
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/demo-data-template.json +63 -0
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/page-template.html +465 -0
- package/lib/bmad-cache/wds/src/workflows/wds-5-agentic-development/templates/work-file-template.yaml +264 -0
- package/lib/bmad-cache/wds/src/workflows/wds-6-asset-generation/bmad-skill-manifest.yaml +1 -0
- package/lib/bmad-cache/wds/src/workflows/wds-7-design-system/bmad-skill-manifest.yaml +1 -0
- package/lib/bmad-cache/wds/src/workflows/wds-7-design-system/templates/catalog.template.html +363 -0
- package/lib/bmad-cache/wds/src/workflows/wds-8-product-evolution/bmad-skill-manifest.yaml +1 -0
- package/lib/bmad-customize/bmm-architect.customize.yaml +6 -0
- package/lib/bmad-customize/bmm-bmad-master.customize.yaml +6 -0
- package/lib/bmad-customize/bmm-dev.customize.yaml +6 -0
- package/lib/bmad-customize/bmm-pm.customize.yaml +6 -0
- package/lib/bmad-customize/bmm-qa.customize.yaml +6 -0
- package/lib/bmad-customize/bmm-sm.customize.yaml +6 -0
- package/lib/bmad-customize/bmm-tech-writer.customize.yaml +6 -0
- package/lib/bmad-customize/bmm-ux-designer.customize.yaml +6 -0
- package/lib/bmad-extension/module-help.csv +37 -7
- package/lib/bmad-extension/module.yaml +4 -2
- package/lib/bmad-extension/skills/add-sprint/.gitkeep +0 -0
- package/lib/bmad-extension/skills/add-sprint/SKILL.md +121 -0
- package/lib/bmad-extension/skills/add-sprint/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/add-to-sprint/.gitkeep +0 -0
- package/lib/bmad-extension/skills/add-to-sprint/SKILL.md +215 -0
- package/lib/bmad-extension/skills/add-to-sprint/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/bmad-ma-agent-cyber/.gitkeep +0 -0
- package/lib/bmad-extension/skills/bmad-ma-agent-cyber/SKILL.md +44 -0
- package/lib/bmad-extension/skills/bmad-ma-agent-cyber/bmad-skill-manifest.yaml +11 -0
- package/lib/bmad-extension/skills/bmad-ma-agent-devops/.gitkeep +0 -0
- package/lib/bmad-extension/skills/bmad-ma-agent-devops/SKILL.md +44 -0
- package/lib/bmad-extension/skills/bmad-ma-agent-devops/bmad-skill-manifest.yaml +11 -0
- package/lib/bmad-extension/skills/bmad-ma-agent-mil498/.gitkeep +0 -0
- package/lib/bmad-extension/skills/bmad-ma-agent-mil498/SKILL.md +48 -0
- package/lib/bmad-extension/skills/bmad-ma-agent-mil498/bmad-skill-manifest.yaml +11 -0
- package/lib/bmad-extension/skills/bmad-ma-agent-sre/.gitkeep +0 -0
- package/lib/bmad-extension/skills/bmad-ma-agent-sre/SKILL.md +44 -0
- package/lib/bmad-extension/skills/bmad-ma-agent-sre/bmad-skill-manifest.yaml +11 -0
- package/lib/bmad-extension/skills/create-bug-story/.gitkeep +0 -0
- package/lib/bmad-extension/skills/create-bug-story/SKILL.md +195 -0
- package/lib/bmad-extension/skills/create-bug-story/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/cyber-generate-certs/.gitkeep +0 -0
- package/lib/bmad-extension/skills/cyber-generate-certs/SKILL.md +27 -0
- package/lib/bmad-extension/skills/cyber-generate-certs/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/cyber-immunity-estimation/.gitkeep +0 -0
- package/lib/bmad-extension/skills/cyber-immunity-estimation/SKILL.md +29 -0
- package/lib/bmad-extension/skills/cyber-immunity-estimation/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/cyber-security-audit/.gitkeep +0 -0
- package/lib/bmad-extension/skills/cyber-security-audit/SKILL.md +27 -0
- package/lib/bmad-extension/skills/cyber-security-audit/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/cyber-vault-secrets/.gitkeep +0 -0
- package/lib/bmad-extension/skills/cyber-vault-secrets/SKILL.md +28 -0
- package/lib/bmad-extension/skills/cyber-vault-secrets/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/cyber-verify-docker-users/.gitkeep +0 -0
- package/lib/bmad-extension/skills/cyber-verify-docker-users/SKILL.md +23 -0
- package/lib/bmad-extension/skills/cyber-verify-docker-users/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/cyber-verify-image-signature/.gitkeep +0 -0
- package/lib/bmad-extension/skills/cyber-verify-image-signature/SKILL.md +22 -0
- package/lib/bmad-extension/skills/cyber-verify-image-signature/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/cyber-vulnerability-scan/.gitkeep +0 -0
- package/lib/bmad-extension/skills/cyber-vulnerability-scan/SKILL.md +28 -0
- package/lib/bmad-extension/skills/cyber-vulnerability-scan/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/devops-configure-infrastructure/.gitkeep +0 -0
- package/lib/bmad-extension/skills/devops-configure-infrastructure/SKILL.md +27 -0
- package/lib/bmad-extension/skills/devops-configure-infrastructure/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/devops-disconnected-deployment/.gitkeep +0 -0
- package/lib/bmad-extension/skills/devops-disconnected-deployment/SKILL.md +27 -0
- package/lib/bmad-extension/skills/devops-disconnected-deployment/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/devops-docker-compose-setup/.gitkeep +0 -0
- package/lib/bmad-extension/skills/devops-docker-compose-setup/SKILL.md +26 -0
- package/lib/bmad-extension/skills/devops-docker-compose-setup/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/devops-manage-helm/.gitkeep +0 -0
- package/lib/bmad-extension/skills/devops-manage-helm/SKILL.md +28 -0
- package/lib/bmad-extension/skills/devops-manage-helm/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/devops-sign-docker-image/.gitkeep +0 -0
- package/lib/bmad-extension/skills/devops-sign-docker-image/SKILL.md +24 -0
- package/lib/bmad-extension/skills/devops-sign-docker-image/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/mil498-ocd/.gitkeep +0 -0
- package/lib/bmad-extension/skills/mil498-ocd/SKILL.md +30 -0
- package/lib/bmad-extension/skills/mil498-ocd/bmad-skill-manifest.yaml +5 -0
- package/lib/bmad-extension/skills/mil498-ocd/prompts/01-discover-project-artifacts.md +26 -0
- package/lib/bmad-extension/skills/mil498-ocd/prompts/02-load-template.md +10 -0
- package/lib/bmad-extension/skills/mil498-ocd/prompts/03-generate-document.md +90 -0
- package/lib/bmad-extension/skills/mil498-ocd/prompts/04-validate.md +14 -0
- package/lib/bmad-extension/skills/mil498-ocd/prompts/05-review.md +15 -0
- package/lib/bmad-extension/skills/mil498-ocd/prompts/06-save.md +15 -0
- package/lib/bmad-extension/skills/mil498-ocd/template.md +169 -0
- package/lib/bmad-extension/skills/mil498-sdd/.gitkeep +0 -0
- package/lib/bmad-extension/skills/mil498-sdd/SKILL.md +30 -0
- package/lib/bmad-extension/skills/mil498-sdd/bmad-skill-manifest.yaml +5 -0
- package/lib/bmad-extension/skills/mil498-sdd/prompts/01-discover-project-artifacts.md +50 -0
- package/lib/bmad-extension/skills/mil498-sdd/prompts/02-load-template.md +10 -0
- package/lib/bmad-extension/skills/mil498-sdd/prompts/03-generate-document.md +98 -0
- package/lib/bmad-extension/skills/mil498-sdd/prompts/04-validate.md +16 -0
- package/lib/bmad-extension/skills/mil498-sdd/prompts/05-review.md +15 -0
- package/lib/bmad-extension/skills/mil498-sdd/prompts/06-save.md +19 -0
- package/lib/bmad-extension/skills/mil498-sdd/template.md +163 -0
- package/lib/bmad-extension/skills/mil498-sdp/.gitkeep +0 -0
- package/lib/bmad-extension/skills/mil498-sdp/SKILL.md +30 -0
- package/lib/bmad-extension/skills/mil498-sdp/bmad-skill-manifest.yaml +5 -0
- package/lib/bmad-extension/skills/mil498-sdp/prompts/01-discover-project-artifacts.md +32 -0
- package/lib/bmad-extension/skills/mil498-sdp/prompts/02-load-template.md +10 -0
- package/lib/bmad-extension/skills/mil498-sdp/prompts/03-generate-document.md +187 -0
- package/lib/bmad-extension/skills/mil498-sdp/prompts/04-validate.md +13 -0
- package/lib/bmad-extension/skills/mil498-sdp/prompts/05-review.md +15 -0
- package/lib/bmad-extension/skills/mil498-sdp/prompts/06-save.md +14 -0
- package/lib/bmad-extension/skills/mil498-sdp/template.md +307 -0
- package/lib/bmad-extension/skills/mil498-srs/.gitkeep +0 -0
- package/lib/bmad-extension/skills/mil498-srs/SKILL.md +30 -0
- package/lib/bmad-extension/skills/mil498-srs/bmad-skill-manifest.yaml +5 -0
- package/lib/bmad-extension/skills/mil498-srs/prompts/01-discover-project-artifacts.md +42 -0
- package/lib/bmad-extension/skills/mil498-srs/prompts/02-load-template.md +10 -0
- package/lib/bmad-extension/skills/mil498-srs/prompts/03-generate-document.md +100 -0
- package/lib/bmad-extension/skills/mil498-srs/prompts/04-validate.md +16 -0
- package/lib/bmad-extension/skills/mil498-srs/prompts/05-review.md +15 -0
- package/lib/bmad-extension/skills/mil498-srs/prompts/06-save.md +18 -0
- package/lib/bmad-extension/skills/mil498-srs/template.md +219 -0
- package/lib/bmad-extension/skills/mil498-ssdd/.gitkeep +0 -0
- package/lib/bmad-extension/skills/mil498-ssdd/SKILL.md +32 -0
- package/lib/bmad-extension/skills/mil498-ssdd/bmad-skill-manifest.yaml +5 -0
- package/lib/bmad-extension/skills/mil498-ssdd/prompts/01-discover-project-artifacts.md +32 -0
- package/lib/bmad-extension/skills/mil498-ssdd/prompts/02-load-template.md +10 -0
- package/lib/bmad-extension/skills/mil498-ssdd/prompts/03-csci-discovery-interview.md +43 -0
- package/lib/bmad-extension/skills/mil498-ssdd/prompts/04-generate-document.md +96 -0
- package/lib/bmad-extension/skills/mil498-ssdd/prompts/05-validate.md +14 -0
- package/lib/bmad-extension/skills/mil498-ssdd/prompts/06-review.md +16 -0
- package/lib/bmad-extension/skills/mil498-ssdd/prompts/07-save.md +16 -0
- package/lib/bmad-extension/skills/mil498-ssdd/template.md +154 -0
- package/lib/bmad-extension/skills/mil498-sss/.gitkeep +0 -0
- package/lib/bmad-extension/skills/mil498-sss/SKILL.md +31 -0
- package/lib/bmad-extension/skills/mil498-sss/bmad-skill-manifest.yaml +5 -0
- package/lib/bmad-extension/skills/mil498-sss/prompts/01-discover-project-artifacts.md +31 -0
- package/lib/bmad-extension/skills/mil498-sss/prompts/02-load-template.md +10 -0
- package/lib/bmad-extension/skills/mil498-sss/prompts/03-generate-document.md +108 -0
- package/lib/bmad-extension/skills/mil498-sss/prompts/04-validate.md +16 -0
- package/lib/bmad-extension/skills/mil498-sss/prompts/05-review.md +15 -0
- package/lib/bmad-extension/skills/mil498-sss/prompts/06-save.md +15 -0
- package/lib/bmad-extension/skills/mil498-sss/template.md +225 -0
- package/lib/bmad-extension/skills/mil498-std/.gitkeep +0 -0
- package/lib/bmad-extension/skills/mil498-std/SKILL.md +30 -0
- package/lib/bmad-extension/skills/mil498-std/bmad-skill-manifest.yaml +5 -0
- package/lib/bmad-extension/skills/mil498-std/prompts/01-discover-project-artifacts.md +42 -0
- package/lib/bmad-extension/skills/mil498-std/prompts/02-load-template.md +10 -0
- package/lib/bmad-extension/skills/mil498-std/prompts/03-generate-document.md +117 -0
- package/lib/bmad-extension/skills/mil498-std/prompts/04-validate.md +15 -0
- package/lib/bmad-extension/skills/mil498-std/prompts/05-review.md +15 -0
- package/lib/bmad-extension/skills/mil498-std/prompts/06-save.md +15 -0
- package/lib/bmad-extension/skills/mil498-std/template.md +188 -0
- package/lib/bmad-extension/skills/modify-sprint/.gitkeep +0 -0
- package/lib/bmad-extension/skills/modify-sprint/SKILL.md +259 -0
- package/lib/bmad-extension/skills/modify-sprint/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/project-context-expansion/.gitkeep +0 -0
- package/lib/bmad-extension/skills/project-context-expansion/SKILL.md +238 -0
- package/lib/bmad-extension/skills/project-context-expansion/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/sprint-status-view/.gitkeep +0 -0
- package/lib/bmad-extension/skills/sprint-status-view/SKILL.md +202 -0
- package/lib/bmad-extension/skills/sprint-status-view/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/sre-check-deployment-status/.gitkeep +0 -0
- package/lib/bmad-extension/skills/sre-check-deployment-status/SKILL.md +32 -0
- package/lib/bmad-extension/skills/sre-check-deployment-status/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/sre-check-secrets/.gitkeep +0 -0
- package/lib/bmad-extension/skills/sre-check-secrets/SKILL.md +23 -0
- package/lib/bmad-extension/skills/sre-check-secrets/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/sre-check-system-status/.gitkeep +0 -0
- package/lib/bmad-extension/skills/sre-check-system-status/SKILL.md +27 -0
- package/lib/bmad-extension/skills/sre-check-system-status/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/sre-day-2-ops/.gitkeep +0 -0
- package/lib/bmad-extension/skills/sre-day-2-ops/SKILL.md +26 -0
- package/lib/bmad-extension/skills/sre-day-2-ops/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/sre-deployment-strategies/.gitkeep +0 -0
- package/lib/bmad-extension/skills/sre-deployment-strategies/SKILL.md +28 -0
- package/lib/bmad-extension/skills/sre-deployment-strategies/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/sre-fix-deployments/.gitkeep +0 -0
- package/lib/bmad-extension/skills/sre-fix-deployments/SKILL.md +25 -0
- package/lib/bmad-extension/skills/sre-fix-deployments/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/sre-gitops-status/.gitkeep +0 -0
- package/lib/bmad-extension/skills/sre-gitops-status/SKILL.md +25 -0
- package/lib/bmad-extension/skills/sre-gitops-status/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad.js +541 -1
- package/lib/installer.js +12 -8
- package/opencode.json +1 -4
- package/package.json +3 -3
- package/test/bmad-extension.test.js +115 -69
- package/test/bmad-version-bump.test.js +313 -0
- package/test/convert-agents-to-skills.test.js +245 -0
- package/test/extension-module-restructure.test.js +359 -0
- package/test/integration-verification.test.js +71 -40
- package/test/migration-validation.test.js +499 -0
- package/test/migration.test.js +832 -0
- package/test/opencode-json-injection.test.js +25 -17
- package/test/opencode-json-merge.test.js +52 -33
- package/test/story-15-5-workflow-skills.test.js +311 -0
- package/test/yes-flag.test.js +8 -1
- package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-c6e539e2308f8ed764c5b54b6ab68a67f8a3796b.idx +0 -0
- package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-c6e539e2308f8ed764c5b54b6ab68a67f8a3796b.pack +0 -0
- package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-c6e539e2308f8ed764c5b54b6ab68a67f8a3796b.rev +0 -0
- package/lib/bmad-cache/bmb/samples/bmad-agent-dream-weaver/bmad-manifest.json +0 -62
- package/lib/bmad-cache/bmb/samples/bmad-excalidraw/bmad-manifest.json +0 -18
- package/lib/bmad-cache/bmb/src/module-help.csv +0 -7
- package/lib/bmad-cache/bmb/src/module.yaml +0 -20
- package/lib/bmad-cache/bmb/src/skills/bmad-agent-builder/bmad-manifest.json +0 -24
- package/lib/bmad-cache/bmb/src/skills/bmad-agent-builder/scripts/bmad-manifest-schema.json +0 -103
- package/lib/bmad-cache/bmb/src/skills/bmad-agent-builder/scripts/generate-html-report.py +0 -1002
- package/lib/bmad-cache/bmb/src/skills/bmad-agent-builder/scripts/manifest.py +0 -420
- package/lib/bmad-cache/bmb/src/skills/bmad-workflow-builder/bmad-manifest.json +0 -23
- package/lib/bmad-cache/bmb/src/skills/bmad-workflow-builder/scripts/bmad-manifest-schema.json +0 -103
- package/lib/bmad-cache/bmb/src/skills/bmad-workflow-builder/scripts/generate-html-report.py +0 -1002
- package/lib/bmad-cache/bmb/src/skills/bmad-workflow-builder/scripts/manifest.py +0 -420
- package/lib/bmad-cache/cis/_git_preserved/objects/pack/pack-157d7eb8d527233a8607d926fc74ebf87f2ae0d3.idx +0 -0
- package/lib/bmad-cache/cis/_git_preserved/objects/pack/pack-157d7eb8d527233a8607d926fc74ebf87f2ae0d3.rev +0 -0
- package/lib/bmad-cache/cis/src/agents/brainstorming-coach.agent.yaml +0 -21
- package/lib/bmad-cache/cis/src/agents/creative-problem-solver.agent.yaml +0 -21
- package/lib/bmad-cache/cis/src/agents/design-thinking-coach.agent.yaml +0 -21
- package/lib/bmad-cache/cis/src/agents/innovation-strategist.agent.yaml +0 -21
- package/lib/bmad-cache/cis/src/agents/presentation-master.agent.yaml +0 -53
- package/lib/bmad-cache/cis/src/agents/storyteller/storyteller.agent.yaml +0 -25
- package/lib/bmad-cache/cis/src/teams/creative-squad.yaml +0 -7
- package/lib/bmad-cache/cis/src/teams/default-party.csv +0 -12
- package/lib/bmad-cache/cis/src/workflows/README.md +0 -175
- package/lib/bmad-cache/gds/_git_preserved/objects/pack/pack-44faafb9245b4ca17ad81bd6c9e6fc52fb5915a1.idx +0 -0
- package/lib/bmad-cache/gds/_git_preserved/objects/pack/pack-44faafb9245b4ca17ad81bd6c9e6fc52fb5915a1.rev +0 -0
- package/lib/bmad-cache/gds/_git_preserved/refs/tags/v0.2.2 +0 -1
- package/lib/bmad-cache/tea/_git_preserved/objects/pack/pack-96ec1ce3a9ef4c891e00e060795b4434ba8f7163.idx +0 -0
- package/lib/bmad-cache/tea/_git_preserved/objects/pack/pack-96ec1ce3a9ef4c891e00e060795b4434ba8f7163.rev +0 -0
- package/lib/bmad-cache/tea/_git_preserved/refs/tags/v1.7.0 +0 -1
- package/lib/bmad-cache/tea/docs/MIGRATION.md +0 -488
- package/lib/bmad-cache/tea/src/agents/tea.agent.yaml +0 -67
- package/lib/bmad-cache/tea/src/teams/default-party.csv +0 -2
- package/lib/bmad-customizations/bmm-cyber.customize.yaml +0 -24
- package/lib/bmad-customizations/bmm-devops.customize.yaml +0 -24
- package/lib/bmad-customizations/bmm-mil498.customize.yaml +0 -36
- package/lib/bmad-customizations/bmm-sre.customize.yaml +0 -24
- package/lib/bmad-customizations/cyber.md +0 -71
- package/lib/bmad-customizations/devops.md +0 -71
- package/lib/bmad-customizations/mil498.md +0 -75
- package/lib/bmad-customizations/sre.md +0 -71
- package/lib/bmad-extension/agents/bmm-architect.customize.yaml +0 -5
- package/lib/bmad-extension/agents/bmm-bmad-master.customize.yaml +0 -5
- package/lib/bmad-extension/agents/bmm-cyber.customize.yaml +0 -30
- package/lib/bmad-extension/agents/bmm-dev.customize.yaml +0 -5
- package/lib/bmad-extension/agents/bmm-devops.customize.yaml +0 -30
- package/lib/bmad-extension/agents/bmm-mil498.customize.yaml +0 -42
- package/lib/bmad-extension/agents/bmm-pm.customize.yaml +0 -5
- package/lib/bmad-extension/agents/bmm-qa.customize.yaml +0 -5
- package/lib/bmad-extension/agents/bmm-sm.customize.yaml +0 -5
- package/lib/bmad-extension/agents/bmm-sre.customize.yaml +0 -30
- package/lib/bmad-extension/agents/bmm-tech-writer.customize.yaml +0 -5
- package/lib/bmad-extension/agents/bmm-ux-designer.customize.yaml +0 -5
- /package/lib/bmad-cache/bmb/{src/skills → skills}/bmad-agent-builder/scripts/scan-scripts.py +0 -0
- /package/lib/bmad-cache/bmb/{src/skills → skills}/bmad-workflow-builder/scripts/prepass-prompt-metrics.py +0 -0
- /package/lib/bmad-cache/bmb/{src/skills → skills}/bmad-workflow-builder/scripts/scan-scripts.py +0 -0
- /package/lib/bmad-cache/{bmb/src/skills/bmad-agent-builder → cis/src/skills/bmad-cis-design-thinking}/bmad-skill-manifest.yaml +0 -0
- /package/lib/bmad-cache/cis/src/{workflows → skills}/bmad-cis-design-thinking/design-methods.csv +0 -0
- /package/lib/bmad-cache/{bmb/src/skills/bmad-workflow-builder → cis/src/skills/bmad-cis-innovation-strategy}/bmad-skill-manifest.yaml +0 -0
- /package/lib/bmad-cache/cis/src/{workflows → skills}/bmad-cis-innovation-strategy/innovation-frameworks.csv +0 -0
- /package/lib/bmad-cache/cis/src/{workflows/bmad-cis-design-thinking → skills/bmad-cis-problem-solving}/bmad-skill-manifest.yaml +0 -0
- /package/lib/bmad-cache/cis/src/{workflows → skills}/bmad-cis-problem-solving/solving-methods.csv +0 -0
- /package/lib/bmad-cache/cis/src/{workflows/bmad-cis-innovation-strategy → skills/bmad-cis-storytelling}/bmad-skill-manifest.yaml +0 -0
- /package/lib/bmad-cache/cis/src/{workflows → skills}/bmad-cis-storytelling/story-types.csv +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/adr-quality-readiness-checklist.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/api-request.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/api-testing-patterns.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/auth-session.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/burn-in.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/ci-burn-in.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/component-tdd.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/contract-testing.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/data-factories.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/email-auth.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/error-handling.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/feature-flags.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/file-utils.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/fixture-architecture.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/fixtures-composition.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/intercept-network-call.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/log.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/network-error-monitor.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/network-first.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/network-recorder.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/nfr-criteria.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/overview.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/pact-consumer-di.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/pact-consumer-framework-setup.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/pact-mcp.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/pactjs-utils-consumer-helpers.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/pactjs-utils-overview.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/pactjs-utils-provider-verifier.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/pactjs-utils-request-filter.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/playwright-cli.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/playwright-config.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/probability-impact.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/recurse.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/risk-governance.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/selective-testing.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/selector-resilience.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/test-healing-patterns.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/test-levels-framework.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/test-priorities-matrix.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/test-quality.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/timing-debugging.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/knowledge/visual-debugging.md +0 -0
- /package/lib/bmad-cache/tea/src/{testarch → agents/bmad-tea/resources}/tea-index.csv +0 -0
- /package/lib/bmad-cache/{cis/src/workflows/bmad-cis-problem-solving → wds/src/workflows/wds-0-alignment-signoff}/bmad-skill-manifest.yaml +0 -0
- /package/lib/bmad-cache/{cis/src/workflows/bmad-cis-storytelling → wds/src/workflows/wds-0-project-setup}/bmad-skill-manifest.yaml +0 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# /// script
|
|
3
|
+
# requires-python = ">=3.9"
|
|
4
|
+
# dependencies = []
|
|
5
|
+
# ///
|
|
6
|
+
"""Remove legacy module directories from _bmad/ after config migration.
|
|
7
|
+
|
|
8
|
+
After merge-config.py and merge-help-csv.py have migrated config data and
|
|
9
|
+
deleted individual legacy files, this script removes the now-redundant
|
|
10
|
+
directory trees. These directories contain skill files that are already
|
|
11
|
+
installed at .claude/skills/ (or equivalent) — only the config files at
|
|
12
|
+
_bmad/ root need to persist.
|
|
13
|
+
|
|
14
|
+
When --skills-dir is provided, the script verifies that every skill found
|
|
15
|
+
in the legacy directories exists at the installed location before removing
|
|
16
|
+
anything. Directories without skills (like _config/) are removed directly.
|
|
17
|
+
|
|
18
|
+
Exit codes: 0=success (including nothing to remove), 1=validation error, 2=runtime error
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import argparse
|
|
22
|
+
import json
|
|
23
|
+
import shutil
|
|
24
|
+
import sys
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def parse_args():
|
|
29
|
+
parser = argparse.ArgumentParser(
|
|
30
|
+
description="Remove legacy module directories from _bmad/ after config migration."
|
|
31
|
+
)
|
|
32
|
+
parser.add_argument(
|
|
33
|
+
"--bmad-dir",
|
|
34
|
+
required=True,
|
|
35
|
+
help="Path to the _bmad/ directory",
|
|
36
|
+
)
|
|
37
|
+
parser.add_argument(
|
|
38
|
+
"--module-code",
|
|
39
|
+
required=True,
|
|
40
|
+
help="Module code being cleaned up (e.g. 'bmb')",
|
|
41
|
+
)
|
|
42
|
+
parser.add_argument(
|
|
43
|
+
"--also-remove",
|
|
44
|
+
action="append",
|
|
45
|
+
default=[],
|
|
46
|
+
help="Additional directory names under _bmad/ to remove (repeatable)",
|
|
47
|
+
)
|
|
48
|
+
parser.add_argument(
|
|
49
|
+
"--skills-dir",
|
|
50
|
+
help="Path to .claude/skills/ — enables safety verification that skills "
|
|
51
|
+
"are installed before removing legacy copies",
|
|
52
|
+
)
|
|
53
|
+
parser.add_argument(
|
|
54
|
+
"--verbose",
|
|
55
|
+
action="store_true",
|
|
56
|
+
help="Print detailed progress to stderr",
|
|
57
|
+
)
|
|
58
|
+
return parser.parse_args()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def find_skill_dirs(base_path: str) -> list:
|
|
62
|
+
"""Find directories that contain a SKILL.md file.
|
|
63
|
+
|
|
64
|
+
Walks the directory tree and returns the leaf directory name for each
|
|
65
|
+
directory containing a SKILL.md. These are considered skill directories.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
List of skill directory names (e.g. ['bmad-agent-builder', 'bmad-builder-setup'])
|
|
69
|
+
"""
|
|
70
|
+
skills = []
|
|
71
|
+
root = Path(base_path)
|
|
72
|
+
if not root.exists():
|
|
73
|
+
return skills
|
|
74
|
+
for skill_md in root.rglob("SKILL.md"):
|
|
75
|
+
skills.append(skill_md.parent.name)
|
|
76
|
+
return sorted(set(skills))
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def verify_skills_installed(
|
|
80
|
+
bmad_dir: str, dirs_to_check: list, skills_dir: str, verbose: bool = False
|
|
81
|
+
) -> list:
|
|
82
|
+
"""Verify that skills in legacy directories exist at the installed location.
|
|
83
|
+
|
|
84
|
+
Scans each directory in dirs_to_check for skill folders (containing SKILL.md),
|
|
85
|
+
then checks that a matching directory exists under skills_dir. Directories
|
|
86
|
+
that contain no skills (like _config/) are silently skipped.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
List of verified skill names.
|
|
90
|
+
|
|
91
|
+
Raises SystemExit(1) if any skills are missing from skills_dir.
|
|
92
|
+
"""
|
|
93
|
+
all_verified = []
|
|
94
|
+
missing = []
|
|
95
|
+
|
|
96
|
+
for dirname in dirs_to_check:
|
|
97
|
+
legacy_path = Path(bmad_dir) / dirname
|
|
98
|
+
if not legacy_path.exists():
|
|
99
|
+
continue
|
|
100
|
+
|
|
101
|
+
skill_names = find_skill_dirs(str(legacy_path))
|
|
102
|
+
if not skill_names:
|
|
103
|
+
if verbose:
|
|
104
|
+
print(
|
|
105
|
+
f"No skills found in {dirname}/ — skipping verification",
|
|
106
|
+
file=sys.stderr,
|
|
107
|
+
)
|
|
108
|
+
continue
|
|
109
|
+
|
|
110
|
+
for skill_name in skill_names:
|
|
111
|
+
installed_path = Path(skills_dir) / skill_name
|
|
112
|
+
if installed_path.is_dir():
|
|
113
|
+
all_verified.append(skill_name)
|
|
114
|
+
if verbose:
|
|
115
|
+
print(
|
|
116
|
+
f"Verified: {skill_name} exists at {installed_path}",
|
|
117
|
+
file=sys.stderr,
|
|
118
|
+
)
|
|
119
|
+
else:
|
|
120
|
+
missing.append(skill_name)
|
|
121
|
+
if verbose:
|
|
122
|
+
print(
|
|
123
|
+
f"MISSING: {skill_name} not found at {installed_path}",
|
|
124
|
+
file=sys.stderr,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
if missing:
|
|
128
|
+
error_result = {
|
|
129
|
+
"status": "error",
|
|
130
|
+
"error": "Skills not found at installed location",
|
|
131
|
+
"missing_skills": missing,
|
|
132
|
+
"skills_dir": str(Path(skills_dir).resolve()),
|
|
133
|
+
}
|
|
134
|
+
print(json.dumps(error_result, indent=2))
|
|
135
|
+
sys.exit(1)
|
|
136
|
+
|
|
137
|
+
return sorted(set(all_verified))
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def count_files(path: Path) -> int:
|
|
141
|
+
"""Count all files recursively in a directory."""
|
|
142
|
+
count = 0
|
|
143
|
+
for item in path.rglob("*"):
|
|
144
|
+
if item.is_file():
|
|
145
|
+
count += 1
|
|
146
|
+
return count
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def cleanup_directories(
|
|
150
|
+
bmad_dir: str, dirs_to_remove: list, verbose: bool = False
|
|
151
|
+
) -> tuple:
|
|
152
|
+
"""Remove specified directories under bmad_dir.
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
(removed, not_found, total_files_removed) tuple
|
|
156
|
+
"""
|
|
157
|
+
removed = []
|
|
158
|
+
not_found = []
|
|
159
|
+
total_files = 0
|
|
160
|
+
|
|
161
|
+
for dirname in dirs_to_remove:
|
|
162
|
+
target = Path(bmad_dir) / dirname
|
|
163
|
+
if not target.exists():
|
|
164
|
+
not_found.append(dirname)
|
|
165
|
+
if verbose:
|
|
166
|
+
print(f"Not found (skipping): {target}", file=sys.stderr)
|
|
167
|
+
continue
|
|
168
|
+
|
|
169
|
+
if not target.is_dir():
|
|
170
|
+
if verbose:
|
|
171
|
+
print(f"Not a directory (skipping): {target}", file=sys.stderr)
|
|
172
|
+
not_found.append(dirname)
|
|
173
|
+
continue
|
|
174
|
+
|
|
175
|
+
file_count = count_files(target)
|
|
176
|
+
if verbose:
|
|
177
|
+
print(
|
|
178
|
+
f"Removing {target} ({file_count} files)",
|
|
179
|
+
file=sys.stderr,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
try:
|
|
183
|
+
shutil.rmtree(target)
|
|
184
|
+
except OSError as e:
|
|
185
|
+
error_result = {
|
|
186
|
+
"status": "error",
|
|
187
|
+
"error": f"Failed to remove {target}: {e}",
|
|
188
|
+
"directories_removed": removed,
|
|
189
|
+
"directories_failed": dirname,
|
|
190
|
+
}
|
|
191
|
+
print(json.dumps(error_result, indent=2))
|
|
192
|
+
sys.exit(2)
|
|
193
|
+
|
|
194
|
+
removed.append(dirname)
|
|
195
|
+
total_files += file_count
|
|
196
|
+
|
|
197
|
+
return removed, not_found, total_files
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def main():
|
|
201
|
+
args = parse_args()
|
|
202
|
+
|
|
203
|
+
bmad_dir = args.bmad_dir
|
|
204
|
+
module_code = args.module_code
|
|
205
|
+
|
|
206
|
+
# Build the list of directories to remove
|
|
207
|
+
dirs_to_remove = [module_code, "core"] + args.also_remove
|
|
208
|
+
# Deduplicate while preserving order
|
|
209
|
+
seen = set()
|
|
210
|
+
unique_dirs = []
|
|
211
|
+
for d in dirs_to_remove:
|
|
212
|
+
if d not in seen:
|
|
213
|
+
seen.add(d)
|
|
214
|
+
unique_dirs.append(d)
|
|
215
|
+
dirs_to_remove = unique_dirs
|
|
216
|
+
|
|
217
|
+
if args.verbose:
|
|
218
|
+
print(f"Directories to remove: {dirs_to_remove}", file=sys.stderr)
|
|
219
|
+
|
|
220
|
+
# Safety check: verify skills are installed before removing
|
|
221
|
+
verified_skills = None
|
|
222
|
+
if args.skills_dir:
|
|
223
|
+
if args.verbose:
|
|
224
|
+
print(
|
|
225
|
+
f"Verifying skills installed at {args.skills_dir}",
|
|
226
|
+
file=sys.stderr,
|
|
227
|
+
)
|
|
228
|
+
verified_skills = verify_skills_installed(
|
|
229
|
+
bmad_dir, dirs_to_remove, args.skills_dir, args.verbose
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
# Remove directories
|
|
233
|
+
removed, not_found, total_files = cleanup_directories(
|
|
234
|
+
bmad_dir, dirs_to_remove, args.verbose
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
# Build result
|
|
238
|
+
result = {
|
|
239
|
+
"status": "success",
|
|
240
|
+
"bmad_dir": str(Path(bmad_dir).resolve()),
|
|
241
|
+
"directories_removed": removed,
|
|
242
|
+
"directories_not_found": not_found,
|
|
243
|
+
"files_removed_count": total_files,
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if args.skills_dir:
|
|
247
|
+
result["safety_checks"] = {
|
|
248
|
+
"skills_verified": True,
|
|
249
|
+
"skills_dir": str(Path(args.skills_dir).resolve()),
|
|
250
|
+
"verified_skills": verified_skills,
|
|
251
|
+
}
|
|
252
|
+
else:
|
|
253
|
+
result["safety_checks"] = None
|
|
254
|
+
|
|
255
|
+
print(json.dumps(result, indent=2))
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
if __name__ == "__main__":
|
|
259
|
+
main()
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# /// script
|
|
3
|
+
# requires-python = ">=3.9"
|
|
4
|
+
# dependencies = ["pyyaml"]
|
|
5
|
+
# ///
|
|
6
|
+
"""Merge module configuration into shared _bmad/config.yaml and config.user.yaml.
|
|
7
|
+
|
|
8
|
+
Reads a module.yaml definition and a JSON answers file, then writes or updates
|
|
9
|
+
the shared config.yaml (core values at root + module section) and config.user.yaml
|
|
10
|
+
(user_name, communication_language, plus any module variable with user_setting: true).
|
|
11
|
+
Uses an anti-zombie pattern for the module section in config.yaml.
|
|
12
|
+
|
|
13
|
+
Legacy migration: when --legacy-dir is provided, reads old per-module config files
|
|
14
|
+
from {legacy-dir}/{module-code}/config.yaml and {legacy-dir}/core/config.yaml.
|
|
15
|
+
Matching values serve as fallback defaults (answers override them). After a
|
|
16
|
+
successful merge, the legacy config.yaml files are deleted. Only the current
|
|
17
|
+
module and core directories are touched — other module directories are left alone.
|
|
18
|
+
|
|
19
|
+
Exit codes: 0=success, 1=validation error, 2=runtime error
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
import argparse
|
|
23
|
+
import json
|
|
24
|
+
import sys
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
import yaml
|
|
29
|
+
except ImportError:
|
|
30
|
+
print("Error: pyyaml is required (PEP 723 dependency)", file=sys.stderr)
|
|
31
|
+
sys.exit(2)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def parse_args():
|
|
35
|
+
parser = argparse.ArgumentParser(
|
|
36
|
+
description="Merge module config into shared _bmad/config.yaml with anti-zombie pattern."
|
|
37
|
+
)
|
|
38
|
+
parser.add_argument(
|
|
39
|
+
"--config-path",
|
|
40
|
+
required=True,
|
|
41
|
+
help="Path to the target _bmad/config.yaml file",
|
|
42
|
+
)
|
|
43
|
+
parser.add_argument(
|
|
44
|
+
"--module-yaml",
|
|
45
|
+
required=True,
|
|
46
|
+
help="Path to the module.yaml definition file",
|
|
47
|
+
)
|
|
48
|
+
parser.add_argument(
|
|
49
|
+
"--answers",
|
|
50
|
+
required=True,
|
|
51
|
+
help="Path to JSON file with collected answers",
|
|
52
|
+
)
|
|
53
|
+
parser.add_argument(
|
|
54
|
+
"--user-config-path",
|
|
55
|
+
required=True,
|
|
56
|
+
help="Path to the target _bmad/config.user.yaml file",
|
|
57
|
+
)
|
|
58
|
+
parser.add_argument(
|
|
59
|
+
"--legacy-dir",
|
|
60
|
+
help="Path to _bmad/ directory to check for legacy per-module config files. "
|
|
61
|
+
"Matching values are used as fallback defaults, then legacy files are deleted.",
|
|
62
|
+
)
|
|
63
|
+
parser.add_argument(
|
|
64
|
+
"--verbose",
|
|
65
|
+
action="store_true",
|
|
66
|
+
help="Print detailed progress to stderr",
|
|
67
|
+
)
|
|
68
|
+
return parser.parse_args()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def load_yaml_file(path: str) -> dict:
|
|
72
|
+
"""Load a YAML file, returning empty dict if file doesn't exist."""
|
|
73
|
+
file_path = Path(path)
|
|
74
|
+
if not file_path.exists():
|
|
75
|
+
return {}
|
|
76
|
+
with open(file_path, "r", encoding="utf-8") as f:
|
|
77
|
+
content = yaml.safe_load(f)
|
|
78
|
+
return content if content else {}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def load_json_file(path: str) -> dict:
|
|
82
|
+
"""Load a JSON file."""
|
|
83
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
84
|
+
return json.load(f)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# Keys that live at config root (shared across all modules)
|
|
88
|
+
_CORE_KEYS = frozenset(
|
|
89
|
+
{"user_name", "communication_language", "document_output_language", "output_folder"}
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def load_legacy_values(
|
|
94
|
+
legacy_dir: str, module_code: str, module_yaml: dict, verbose: bool = False
|
|
95
|
+
) -> tuple[dict, dict, list]:
|
|
96
|
+
"""Read legacy per-module config files and return core/module value dicts.
|
|
97
|
+
|
|
98
|
+
Reads {legacy_dir}/core/config.yaml and {legacy_dir}/{module_code}/config.yaml.
|
|
99
|
+
Only returns values whose keys match the current schema (core keys or module.yaml
|
|
100
|
+
variable definitions). Other modules' directories are not touched.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
(legacy_core, legacy_module, files_found) where files_found lists paths read.
|
|
104
|
+
"""
|
|
105
|
+
legacy_core: dict = {}
|
|
106
|
+
legacy_module: dict = {}
|
|
107
|
+
files_found: list = []
|
|
108
|
+
|
|
109
|
+
# Read core legacy config
|
|
110
|
+
core_path = Path(legacy_dir) / "core" / "config.yaml"
|
|
111
|
+
if core_path.exists():
|
|
112
|
+
core_data = load_yaml_file(str(core_path))
|
|
113
|
+
files_found.append(str(core_path))
|
|
114
|
+
for k, v in core_data.items():
|
|
115
|
+
if k in _CORE_KEYS:
|
|
116
|
+
legacy_core[k] = v
|
|
117
|
+
if verbose:
|
|
118
|
+
print(f"Legacy core config: {list(legacy_core.keys())}", file=sys.stderr)
|
|
119
|
+
|
|
120
|
+
# Read module legacy config
|
|
121
|
+
mod_path = Path(legacy_dir) / module_code / "config.yaml"
|
|
122
|
+
if mod_path.exists():
|
|
123
|
+
mod_data = load_yaml_file(str(mod_path))
|
|
124
|
+
files_found.append(str(mod_path))
|
|
125
|
+
for k, v in mod_data.items():
|
|
126
|
+
if k in _CORE_KEYS:
|
|
127
|
+
# Core keys duplicated in module config — only use if not already set
|
|
128
|
+
if k not in legacy_core:
|
|
129
|
+
legacy_core[k] = v
|
|
130
|
+
elif k in module_yaml and isinstance(module_yaml[k], dict):
|
|
131
|
+
# Module-specific key that matches a current variable definition
|
|
132
|
+
legacy_module[k] = v
|
|
133
|
+
if verbose:
|
|
134
|
+
print(
|
|
135
|
+
f"Legacy module config: {list(legacy_module.keys())}", file=sys.stderr
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
return legacy_core, legacy_module, files_found
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def apply_legacy_defaults(answers: dict, legacy_core: dict, legacy_module: dict) -> dict:
|
|
142
|
+
"""Apply legacy values as fallback defaults under the answers.
|
|
143
|
+
|
|
144
|
+
Legacy values fill in any key not already present in answers.
|
|
145
|
+
Explicit answers always win.
|
|
146
|
+
"""
|
|
147
|
+
merged = dict(answers)
|
|
148
|
+
|
|
149
|
+
if legacy_core:
|
|
150
|
+
core = merged.get("core", {})
|
|
151
|
+
filled_core = dict(legacy_core) # legacy as base
|
|
152
|
+
filled_core.update(core) # answers override
|
|
153
|
+
merged["core"] = filled_core
|
|
154
|
+
|
|
155
|
+
if legacy_module:
|
|
156
|
+
mod = merged.get("module", {})
|
|
157
|
+
filled_mod = dict(legacy_module) # legacy as base
|
|
158
|
+
filled_mod.update(mod) # answers override
|
|
159
|
+
merged["module"] = filled_mod
|
|
160
|
+
|
|
161
|
+
return merged
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def cleanup_legacy_configs(
|
|
165
|
+
legacy_dir: str, module_code: str, verbose: bool = False
|
|
166
|
+
) -> list:
|
|
167
|
+
"""Delete legacy config.yaml files for this module and core only.
|
|
168
|
+
|
|
169
|
+
Returns list of deleted file paths.
|
|
170
|
+
"""
|
|
171
|
+
deleted = []
|
|
172
|
+
for subdir in (module_code, "core"):
|
|
173
|
+
legacy_path = Path(legacy_dir) / subdir / "config.yaml"
|
|
174
|
+
if legacy_path.exists():
|
|
175
|
+
if verbose:
|
|
176
|
+
print(f"Deleting legacy config: {legacy_path}", file=sys.stderr)
|
|
177
|
+
legacy_path.unlink()
|
|
178
|
+
deleted.append(str(legacy_path))
|
|
179
|
+
return deleted
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def extract_module_metadata(module_yaml: dict) -> dict:
|
|
183
|
+
"""Extract non-variable metadata fields from module.yaml."""
|
|
184
|
+
meta = {}
|
|
185
|
+
for k in ("name", "description"):
|
|
186
|
+
if k in module_yaml:
|
|
187
|
+
meta[k] = module_yaml[k]
|
|
188
|
+
meta["version"] = module_yaml.get("module_version") # null if absent
|
|
189
|
+
if "default_selected" in module_yaml:
|
|
190
|
+
meta["default_selected"] = module_yaml["default_selected"]
|
|
191
|
+
return meta
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def apply_result_templates(
|
|
195
|
+
module_yaml: dict, module_answers: dict, verbose: bool = False
|
|
196
|
+
) -> dict:
|
|
197
|
+
"""Apply result templates from module.yaml to transform raw answer values.
|
|
198
|
+
|
|
199
|
+
For each answer, if the corresponding variable definition in module.yaml has
|
|
200
|
+
a 'result' field, replaces {value} in that template with the answer. Skips
|
|
201
|
+
the template if the answer already contains '{project-root}' to prevent
|
|
202
|
+
double-prefixing.
|
|
203
|
+
"""
|
|
204
|
+
transformed = {}
|
|
205
|
+
for key, value in module_answers.items():
|
|
206
|
+
var_def = module_yaml.get(key)
|
|
207
|
+
if (
|
|
208
|
+
isinstance(var_def, dict)
|
|
209
|
+
and "result" in var_def
|
|
210
|
+
and "{project-root}" not in str(value)
|
|
211
|
+
):
|
|
212
|
+
template = var_def["result"]
|
|
213
|
+
transformed[key] = template.replace("{value}", str(value))
|
|
214
|
+
if verbose:
|
|
215
|
+
print(
|
|
216
|
+
f"Applied result template for '{key}': {value} → {transformed[key]}",
|
|
217
|
+
file=sys.stderr,
|
|
218
|
+
)
|
|
219
|
+
else:
|
|
220
|
+
transformed[key] = value
|
|
221
|
+
return transformed
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def merge_config(
|
|
225
|
+
existing_config: dict,
|
|
226
|
+
module_yaml: dict,
|
|
227
|
+
answers: dict,
|
|
228
|
+
verbose: bool = False,
|
|
229
|
+
) -> dict:
|
|
230
|
+
"""Merge answers into config, applying anti-zombie pattern.
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
existing_config: Current config.yaml contents (may be empty)
|
|
234
|
+
module_yaml: The module definition
|
|
235
|
+
answers: JSON with 'core' and/or 'module' keys
|
|
236
|
+
verbose: Print progress to stderr
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
Updated config dict ready to write
|
|
240
|
+
"""
|
|
241
|
+
config = dict(existing_config)
|
|
242
|
+
module_code = module_yaml.get("code")
|
|
243
|
+
|
|
244
|
+
if not module_code:
|
|
245
|
+
print("Error: module.yaml must have a 'code' field", file=sys.stderr)
|
|
246
|
+
sys.exit(1)
|
|
247
|
+
|
|
248
|
+
# Migrate legacy core: section to root
|
|
249
|
+
if "core" in config and isinstance(config["core"], dict):
|
|
250
|
+
if verbose:
|
|
251
|
+
print("Migrating legacy 'core' section to root", file=sys.stderr)
|
|
252
|
+
config.update(config.pop("core"))
|
|
253
|
+
|
|
254
|
+
# Strip user-only keys from config — they belong exclusively in config.user.yaml
|
|
255
|
+
for key in _CORE_USER_KEYS:
|
|
256
|
+
if key in config:
|
|
257
|
+
if verbose:
|
|
258
|
+
print(f"Removing user-only key '{key}' from config (belongs in config.user.yaml)", file=sys.stderr)
|
|
259
|
+
del config[key]
|
|
260
|
+
|
|
261
|
+
# Write core values at root (global properties, not nested under "core")
|
|
262
|
+
# Exclude user-only keys — those belong exclusively in config.user.yaml
|
|
263
|
+
core_answers = answers.get("core")
|
|
264
|
+
if core_answers:
|
|
265
|
+
shared_core = {k: v for k, v in core_answers.items() if k not in _CORE_USER_KEYS}
|
|
266
|
+
if shared_core:
|
|
267
|
+
if verbose:
|
|
268
|
+
print(f"Writing core config at root: {list(shared_core.keys())}", file=sys.stderr)
|
|
269
|
+
config.update(shared_core)
|
|
270
|
+
|
|
271
|
+
# Anti-zombie: remove existing module section
|
|
272
|
+
if module_code in config:
|
|
273
|
+
if verbose:
|
|
274
|
+
print(
|
|
275
|
+
f"Removing existing '{module_code}' section (anti-zombie)",
|
|
276
|
+
file=sys.stderr,
|
|
277
|
+
)
|
|
278
|
+
del config[module_code]
|
|
279
|
+
|
|
280
|
+
# Build module section: metadata + variable values
|
|
281
|
+
module_section = extract_module_metadata(module_yaml)
|
|
282
|
+
module_answers = apply_result_templates(
|
|
283
|
+
module_yaml, answers.get("module", {}), verbose
|
|
284
|
+
)
|
|
285
|
+
module_section.update(module_answers)
|
|
286
|
+
|
|
287
|
+
if verbose:
|
|
288
|
+
print(
|
|
289
|
+
f"Writing '{module_code}' section with keys: {list(module_section.keys())}",
|
|
290
|
+
file=sys.stderr,
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
config[module_code] = module_section
|
|
294
|
+
|
|
295
|
+
return config
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
# Core keys that are always written to config.user.yaml
|
|
299
|
+
_CORE_USER_KEYS = ("user_name", "communication_language")
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def extract_user_settings(module_yaml: dict, answers: dict) -> dict:
|
|
303
|
+
"""Collect settings that belong in config.user.yaml.
|
|
304
|
+
|
|
305
|
+
Includes user_name and communication_language from core answers, plus any
|
|
306
|
+
module variable whose definition contains user_setting: true.
|
|
307
|
+
"""
|
|
308
|
+
user_settings = {}
|
|
309
|
+
|
|
310
|
+
core_answers = answers.get("core", {})
|
|
311
|
+
for key in _CORE_USER_KEYS:
|
|
312
|
+
if key in core_answers:
|
|
313
|
+
user_settings[key] = core_answers[key]
|
|
314
|
+
|
|
315
|
+
module_answers = answers.get("module", {})
|
|
316
|
+
for var_name, var_def in module_yaml.items():
|
|
317
|
+
if isinstance(var_def, dict) and var_def.get("user_setting") is True:
|
|
318
|
+
if var_name in module_answers:
|
|
319
|
+
user_settings[var_name] = module_answers[var_name]
|
|
320
|
+
|
|
321
|
+
return user_settings
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def write_config(config: dict, config_path: str, verbose: bool = False) -> None:
|
|
325
|
+
"""Write config dict to YAML file, creating parent dirs as needed."""
|
|
326
|
+
path = Path(config_path)
|
|
327
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
328
|
+
|
|
329
|
+
if verbose:
|
|
330
|
+
print(f"Writing config to {path}", file=sys.stderr)
|
|
331
|
+
|
|
332
|
+
with open(path, "w", encoding="utf-8") as f:
|
|
333
|
+
yaml.dump(
|
|
334
|
+
config,
|
|
335
|
+
f,
|
|
336
|
+
default_flow_style=False,
|
|
337
|
+
allow_unicode=True,
|
|
338
|
+
sort_keys=False,
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
def main():
|
|
343
|
+
args = parse_args()
|
|
344
|
+
|
|
345
|
+
# Load inputs
|
|
346
|
+
module_yaml = load_yaml_file(args.module_yaml)
|
|
347
|
+
if not module_yaml:
|
|
348
|
+
print(f"Error: Could not load module.yaml from {args.module_yaml}", file=sys.stderr)
|
|
349
|
+
sys.exit(1)
|
|
350
|
+
|
|
351
|
+
answers = load_json_file(args.answers)
|
|
352
|
+
existing_config = load_yaml_file(args.config_path)
|
|
353
|
+
|
|
354
|
+
if args.verbose:
|
|
355
|
+
exists = Path(args.config_path).exists()
|
|
356
|
+
print(f"Config file exists: {exists}", file=sys.stderr)
|
|
357
|
+
if exists:
|
|
358
|
+
print(f"Existing sections: {list(existing_config.keys())}", file=sys.stderr)
|
|
359
|
+
|
|
360
|
+
# Legacy migration: read old per-module configs as fallback defaults
|
|
361
|
+
legacy_files_found = []
|
|
362
|
+
if args.legacy_dir:
|
|
363
|
+
module_code = module_yaml.get("code", "")
|
|
364
|
+
legacy_core, legacy_module, legacy_files_found = load_legacy_values(
|
|
365
|
+
args.legacy_dir, module_code, module_yaml, args.verbose
|
|
366
|
+
)
|
|
367
|
+
if legacy_core or legacy_module:
|
|
368
|
+
answers = apply_legacy_defaults(answers, legacy_core, legacy_module)
|
|
369
|
+
if args.verbose:
|
|
370
|
+
print("Applied legacy values as fallback defaults", file=sys.stderr)
|
|
371
|
+
|
|
372
|
+
# Merge and write config.yaml
|
|
373
|
+
updated_config = merge_config(existing_config, module_yaml, answers, args.verbose)
|
|
374
|
+
write_config(updated_config, args.config_path, args.verbose)
|
|
375
|
+
|
|
376
|
+
# Merge and write config.user.yaml
|
|
377
|
+
user_settings = extract_user_settings(module_yaml, answers)
|
|
378
|
+
existing_user_config = load_yaml_file(args.user_config_path)
|
|
379
|
+
updated_user_config = dict(existing_user_config)
|
|
380
|
+
updated_user_config.update(user_settings)
|
|
381
|
+
if user_settings:
|
|
382
|
+
write_config(updated_user_config, args.user_config_path, args.verbose)
|
|
383
|
+
|
|
384
|
+
# Legacy cleanup: delete old per-module config files
|
|
385
|
+
legacy_deleted = []
|
|
386
|
+
if args.legacy_dir:
|
|
387
|
+
legacy_deleted = cleanup_legacy_configs(
|
|
388
|
+
args.legacy_dir, module_yaml["code"], args.verbose
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
# Output result summary as JSON
|
|
392
|
+
module_code = module_yaml["code"]
|
|
393
|
+
result = {
|
|
394
|
+
"status": "success",
|
|
395
|
+
"config_path": str(Path(args.config_path).resolve()),
|
|
396
|
+
"user_config_path": str(Path(args.user_config_path).resolve()),
|
|
397
|
+
"module_code": module_code,
|
|
398
|
+
"core_updated": bool(answers.get("core")),
|
|
399
|
+
"module_keys": list(updated_config.get(module_code, {}).keys()),
|
|
400
|
+
"user_keys": list(user_settings.keys()),
|
|
401
|
+
"legacy_configs_found": legacy_files_found,
|
|
402
|
+
"legacy_configs_deleted": legacy_deleted,
|
|
403
|
+
}
|
|
404
|
+
print(json.dumps(result, indent=2))
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
if __name__ == "__main__":
|
|
408
|
+
main()
|