bmad-method-test-architecture-enterprise 2.0.4-next.4 → 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/.claude-plugin/marketplace.json +10 -10
- package/README.md +28 -13
- package/cli/atdd-red-check.js +1 -1
- package/cli/atdd-runner.js +1 -1
- package/cli/automate.js +3 -3
- package/cli/ci-runner.js +1 -1
- package/cli/lib/automate-prompt.js +1 -1
- package/cli/lib/framework-setup.js +2 -2
- package/cli/lib/resolve-skill.js +2 -2
- package/cli/lib/resolve-tea-config.js +42 -5
- package/cli/lib/test-design-parser.js +1 -1
- package/cli/lib/workflow-cli.js +5 -1
- package/cli/migrate-customizations.js +254 -0
- package/cli/nfr-runner.js +1 -1
- package/cli/nfr.js +2 -2
- package/cli/teach.js +4 -4
- package/cli/test-design.js +2 -2
- package/cli/test-review.js +3 -3
- package/cli/trace.js +2 -2
- package/cli/transcript-runner.js +1 -1
- package/package.json +5 -3
- package/skills/bmad-tea/SKILL.md +4 -2
- package/skills/bmad-tea/customize.toml +10 -10
- package/skills/{bmad-testarch-automate → bmad-tea-automate}/SKILL.md +3 -1
- package/skills/{bmad-testarch-automate → bmad-tea-automate}/checklist.md +1 -1
- package/skills/{bmad-testarch-nfr → bmad-tea-automate}/customize.toml +1 -1
- package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/customize.toml +1 -1
- package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/instructions.md +1 -1
- package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/workflow.yaml +2 -2
- package/skills/{bmad-testarch-automate → bmad-tea-automate}/resources/test-generation-routing.md +14 -14
- package/skills/{bmad-testarch-automate → bmad-tea-automate}/workflow.yaml +2 -2
- package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/SKILL.md +4 -2
- package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/inspection-record.md +1 -1
- package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/customize.toml +1 -1
- package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/ci.md +4 -4
- package/skills/{bmad-testarch-framework → bmad-tea-framework}/SKILL.md +5 -3
- package/skills/bmad-tea-framework/ci/customize.toml +10 -0
- package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/instructions.md +1 -1
- package/skills/{bmad-testarch-framework → bmad-tea-framework}/customize.toml +2 -2
- package/skills/{bmad-testarch-framework → bmad-tea-framework}/resources/framework-setup-progress.example.md +1 -1
- package/skills/{bmad-testarch-framework → bmad-tea-framework}/resources/hooks/tea-enforce.cjs +2 -2
- package/skills/{bmad-testarch-framework → bmad-tea-framework}/resources/setup-phase-completion.md +1 -1
- package/skills/{bmad-testarch-framework → bmad-tea-framework}/resources/setup-routing.md +3 -3
- package/skills/{bmad-testarch-framework → bmad-tea-framework}/resources/setup-run-progress.example.md +1 -1
- package/skills/{bmad-testarch-framework → bmad-tea-framework}/steps-c/step-04-docs-and-scripts.md +2 -2
- package/skills/{bmad-testarch-framework → bmad-tea-framework}/workflow.yaml +2 -2
- package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/SKILL.md +3 -1
- package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/checklist.md +3 -3
- package/skills/{bmad-testarch-trace → bmad-tea-nfr}/customize.toml +1 -1
- package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/instructions.md +1 -1
- package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/nfr-report-template.md +3 -3
- package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/resources/nfr-assessment.example.md +4 -4
- package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/workflow.yaml +2 -2
- package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/SKILL.md +3 -1
- package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/customize.toml +1 -1
- package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/instructions.md +2 -2
- package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/steps-c/step-04-session-01.md +1 -1
- package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/steps-c/step-04-session-03.md +2 -2
- package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/steps-c/step-04-session-05.md +2 -2
- package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/steps-e/step-e-02-apply-edits.md +2 -2
- package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/SKILL.md +3 -1
- package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/checklist.md +3 -3
- package/skills/{bmad-testarch-automate → bmad-tea-test-design}/customize.toml +1 -1
- package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/resources/test-design-epic-3.example.md +5 -5
- package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/test-design-qa-template.md +1 -1
- package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/test-design-template.md +3 -3
- package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/workflow.yaml +2 -2
- package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/SKILL.md +3 -1
- package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/customize.toml +1 -1
- package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/instructions.md +1 -1
- package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/workflow.yaml +2 -2
- package/skills/{bmad-testarch-trace → bmad-tea-trace}/SKILL.md +3 -1
- package/skills/{bmad-testarch-trace → bmad-tea-trace}/checklist.md +2 -2
- package/skills/bmad-tea-trace/customize.toml +38 -0
- package/skills/{bmad-testarch-trace → bmad-tea-trace}/instructions.md +1 -1
- package/skills/{bmad-testarch-trace → bmad-tea-trace}/resources/traceability-matrix.example.md +1 -1
- package/skills/{bmad-testarch-trace → bmad-tea-trace}/steps-c/step-04-analyze-gaps.md +3 -3
- package/skills/{bmad-testarch-trace → bmad-tea-trace}/trace-template.md +2 -2
- package/skills/{bmad-testarch-trace → bmad-tea-trace}/workflow.yaml +2 -2
- package/skills/bmod-tea/bmod.toml +11 -11
- package/skills/bmod-tea/help/help.md +10 -10
- package/skills/bmod-tea/help/integrations.md +2 -2
- package/skills/bmod-tea/knowledge/burn-in.md +1 -1
- package/skills/bmod-tea/knowledge/risk-governance.md +1 -1
- package/skills/bmod-tea/knowledge/test-healing-patterns.md +1 -1
- package/skills/bmod-tea/migration-1.toml +11 -11
- package/skills/bmad-testarch-test-design/customize.toml +0 -38
- /package/skills/{bmad-teach-me-testing → bmad-tea-automate}/bmod.toml +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/instructions.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/atdd-checklist-template.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/checklist.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/resources/atdd-checklist-2-4-guest-checkout.example.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/steps-c/step-01-preflight-and-context.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/steps-c/step-01b-resume.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/steps-c/step-02-generation-mode.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/steps-c/step-03-test-strategy.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/steps-c/step-04-generate-tests.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/steps-c/step-04a-subagent-api-failing.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/steps-c/step-04b-subagent-e2e-failing.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/steps-c/step-04c-aggregate.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/steps-c/step-05-validate-and-complete.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/steps-e/step-01-assess.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/steps-e/step-02-apply-edit.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/red/steps-v/step-01-validate.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/resources/automation-summary.example.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/resources/run-and-heal.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/steps-c/step-01-preflight-and-context.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/steps-c/step-01b-resume.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/steps-c/step-02-identify-targets.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/steps-c/step-03-generate-tests.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/steps-c/step-03a-subagent-api.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/steps-c/step-03b-subagent-backend.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/steps-c/step-03b-subagent-e2e.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/steps-c/step-03b-subagent-mobile.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/steps-c/step-03c-aggregate.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/steps-c/step-04-validate-and-summarize.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/steps-e/step-01-assess.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/steps-e/step-02-apply-edit.md +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-automate}/steps-v/step-01-validate.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/README.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/contract.skeleton.json +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/evaluation-ci-plan.template.json +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/evaluation-folder.gitignore +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/evaluation.json +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/evaluator-conditions.template.json +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/evaluators/LEARNED.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/evaluators/agentevals-frameworks.json +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/evaluators/agentevals-trajectory.mjs +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/evaluators/command-evaluator.mjs +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/evaluators/frameworks.json +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/evaluators/installed-version.mjs +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/evaluators/mapping.json +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/evaluators/promptfoo-assertions.mjs +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/evaluators/promptfoo-frameworks.json +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/http-probe-port.conformance.mjs +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/http-probe-port.mjs +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/requirements-statement.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/assets/scoring-policy.template.json +0 -0
- /package/skills/{bmad-testarch-automate → bmad-tea-evaluate}/bmod.toml +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/adapters.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/authoring-routing.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/contract.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/corpus-agent.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/corpus-ai-feature.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/corpus-skill.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/corpus-test-review-mechanism.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/corpus-tool-use-system.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/corpus-workflow.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/corpus.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/evaluator.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/gaps.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/harness.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/inspection.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/intake.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/mutation.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/oracles.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-evaluate}/references/run.md +0 -0
- /package/skills/{bmad-testarch-evaluate → bmad-tea-framework}/bmod.toml +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/checklist.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/azure-pipelines-template.yaml +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/checklist.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/github-actions-template.yaml +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/gitlab-ci-template.yaml +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/harness-pipeline-template.yaml +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/jenkins-pipeline-template.groovy +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/resources/ci-pipeline-progress.example.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/steps-c/step-01-preflight.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/steps-c/step-01b-resume.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/steps-c/step-02-generate-pipeline.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/steps-c/step-03-configure-quality-gates.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/steps-c/step-03b-render-evaluation-plans.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/steps-c/step-04-validate-and-summary.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/steps-e/step-01-assess.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/steps-e/step-02-apply-edit.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/ci/steps-v/step-01-validate.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/instructions.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/resources/setup-parallel.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/resources/setup-state.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/steps-c/step-01-preflight.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/steps-c/step-01b-resume.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/steps-c/step-02-select-framework.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/steps-c/step-03-scaffold-framework.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/steps-c/step-05-validate-and-summary.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/steps-e/step-01-assess.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/steps-e/step-02-apply-edit.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-framework}/steps-v/step-01-validate.md +0 -0
- /package/skills/{bmad-testarch-framework → bmad-tea-nfr}/bmod.toml +0 -0
- /package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/steps-c/nfr-status-definitions.md +0 -0
- /package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/steps-c/step-01-load-context.md +0 -0
- /package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/steps-c/step-01b-resume.md +0 -0
- /package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/steps-c/step-02-define-thresholds.md +0 -0
- /package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/steps-c/step-03-gather-evidence.md +0 -0
- /package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/steps-c/step-04-evaluate-and-score.md +0 -0
- /package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/steps-c/step-04a-subagent-security.md +0 -0
- /package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/steps-c/step-04b-subagent-performance.md +0 -0
- /package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/steps-c/step-04c-subagent-reliability.md +0 -0
- /package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/steps-c/step-04d-subagent-maintainability.md +0 -0
- /package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/steps-c/step-04e-aggregate-nfr.md +0 -0
- /package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/steps-c/step-05-generate-report.md +0 -0
- /package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/steps-e/step-01-assess.md +0 -0
- /package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/steps-e/step-02-apply-edit.md +0 -0
- /package/skills/{bmad-testarch-nfr → bmad-tea-nfr}/steps-v/step-01-validate.md +0 -0
- /package/skills/{bmad-testarch-nfr → bmad-tea-teach-me-testing}/bmod.toml +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/checklist.md +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/data/curriculum.yaml +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/data/quiz-questions.yaml +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/data/role-paths.yaml +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/data/session-content-map.yaml +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/data/tea-resources-index.yaml +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/resources/tea-completion-summary.example.md +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/steps-c/step-01-init.md +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/steps-c/step-01b-continue.md +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/steps-c/step-02-assess.md +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/steps-c/step-03-session-menu.md +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/steps-c/step-04-session-02.md +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/steps-c/step-04-session-04.md +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/steps-c/step-04-session-06.md +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/steps-c/step-04-session-07.md +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/steps-c/step-05-completion.md +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/steps-e/step-e-01-assess-workflow.md +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/steps-v/step-v-01-validate.md +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/templates/completion-summary-template.md +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/templates/progress-template.yaml +0 -0
- /package/skills/{bmad-teach-me-testing → bmad-tea-teach-me-testing}/templates/session-notes-template.md +0 -0
- /package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/bmod.toml +0 -0
- /package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/instructions.md +0 -0
- /package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/steps-c/step-01-detect-mode.md +0 -0
- /package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/steps-c/step-01b-resume.md +0 -0
- /package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/steps-c/step-02-load-context.md +0 -0
- /package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/steps-c/step-03-risk-and-testability.md +0 -0
- /package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/steps-c/step-04-coverage-plan.md +0 -0
- /package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/steps-c/step-05-generate-output.md +0 -0
- /package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/steps-e/step-01-assess.md +0 -0
- /package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/steps-e/step-02-apply-edit.md +0 -0
- /package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/steps-v/step-01-validate.md +0 -0
- /package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/test-design-architecture-template.md +0 -0
- /package/skills/{bmad-testarch-test-design → bmad-tea-test-design}/test-design-handoff-template.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/bmod.toml +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/checklist.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/resources/test-review.example.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/steps-c/criteria-registry.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/steps-c/step-01-load-context.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/steps-c/step-01b-resume.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/steps-c/step-02-discover-tests.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/steps-c/step-03-quality-evaluation.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/steps-c/step-03a-subagent-determinism.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/steps-c/step-03b-subagent-isolation.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/steps-c/step-03c-subagent-maintainability.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/steps-c/step-03e-subagent-performance.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/steps-c/step-03f-aggregate-scores.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/steps-c/step-04-generate-report.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/steps-e/step-01-assess.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/steps-e/step-02-apply-edit.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/steps-v/step-01-validate.md +0 -0
- /package/skills/{bmad-testarch-test-review → bmad-tea-test-review}/test-review-template.md +0 -0
- /package/skills/{bmad-testarch-trace → bmad-tea-trace}/bmod.toml +0 -0
- /package/skills/{bmad-testarch-trace → bmad-tea-trace}/resources/live-verification-results.example.json +0 -0
- /package/skills/{bmad-testarch-trace → bmad-tea-trace}/steps-c/step-01-load-context.md +0 -0
- /package/skills/{bmad-testarch-trace → bmad-tea-trace}/steps-c/step-01b-resume.md +0 -0
- /package/skills/{bmad-testarch-trace → bmad-tea-trace}/steps-c/step-02-discover-tests.md +0 -0
- /package/skills/{bmad-testarch-trace → bmad-tea-trace}/steps-c/step-03-map-criteria.md +0 -0
- /package/skills/{bmad-testarch-trace → bmad-tea-trace}/steps-c/step-05-gate-decision.md +0 -0
- /package/skills/{bmad-testarch-trace → bmad-tea-trace}/steps-e/step-01-assess.md +0 -0
- /package/skills/{bmad-testarch-trace → bmad-tea-trace}/steps-e/step-02-apply-edit.md +0 -0
- /package/skills/{bmad-testarch-trace → bmad-tea-trace}/steps-v/step-01-validate.md +0 -0
|
@@ -30,22 +30,22 @@
|
|
|
30
30
|
{
|
|
31
31
|
"name": "bmad-method-test-architecture-enterprise",
|
|
32
32
|
"source": "./",
|
|
33
|
-
"description": "Master Test Architect module for quality strategy, test generation in red and expand modes with automatic run-and-heal, combined framework and CI setup, CI/CD quality gates, and structured testing education.
|
|
34
|
-
"version": "
|
|
33
|
+
"description": "Master Test Architect module for quality strategy, test generation in red and expand modes with automatic run-and-heal, combined framework and CI setup, CI/CD quality gates, and structured testing education. Existing CI and ATDD customizations can be migrated to the new skill names. Part of the BMad Method ecosystem.",
|
|
34
|
+
"version": "3.0.0",
|
|
35
35
|
"author": {
|
|
36
36
|
"name": "Murat K Ozcan (TEA Creator) & Brian (BMad) Madison"
|
|
37
37
|
},
|
|
38
38
|
"skills": [
|
|
39
39
|
"./skills/bmod-tea",
|
|
40
40
|
"./skills/bmad-tea",
|
|
41
|
-
"./skills/bmad-
|
|
42
|
-
"./skills/bmad-
|
|
43
|
-
"./skills/bmad-
|
|
44
|
-
"./skills/bmad-
|
|
45
|
-
"./skills/bmad-
|
|
46
|
-
"./skills/bmad-
|
|
47
|
-
"./skills/bmad-
|
|
48
|
-
"./skills/bmad-teach-me-testing"
|
|
41
|
+
"./skills/bmad-tea-automate",
|
|
42
|
+
"./skills/bmad-tea-evaluate",
|
|
43
|
+
"./skills/bmad-tea-framework",
|
|
44
|
+
"./skills/bmad-tea-nfr",
|
|
45
|
+
"./skills/bmad-tea-test-design",
|
|
46
|
+
"./skills/bmad-tea-test-review",
|
|
47
|
+
"./skills/bmad-tea-trace",
|
|
48
|
+
"./skills/bmad-tea-teach-me-testing"
|
|
49
49
|
]
|
|
50
50
|
}
|
|
51
51
|
]
|
package/README.md
CHANGED
|
@@ -46,37 +46,52 @@ To install a tagged release, replace `<version>` with the release number:
|
|
|
46
46
|
npx skills add https://github.com/bmad-code-org/bmad-method-test-architecture-enterprise/tree/v<version>/skills
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
### Upgrading to 3.0
|
|
50
|
+
|
|
51
|
+
The eight direct workflow commands now share the `bmad-tea-*` prefix. Replace `bmad-testarch-automate`, `-evaluate`, `-framework`, `-nfr`, `-test-design`, `-test-review`, and `-trace` with the same suffix under `bmad-tea-`. Replace `bmad-teach-me-testing` with `bmad-tea-teach-me-testing`. The 3.0 package does not publish the old slash commands. The `bmad-tea` agent, `bmod-tea` module, menu codes, and `tea-*` CLI executables keep their names.
|
|
52
|
+
|
|
53
|
+
After installing 3.0, move project customizations to the new names:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npx --package=bmad-method-test-architecture-enterprise@3 tea-migrate-customizations --project-root . --check
|
|
57
|
+
npx --package=bmad-method-test-architecture-enterprise@3 tea-migrate-customizations --project-root .
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
This includes old CI and ATDD customization files and old skill references in custom `bmad-tea` agent menus. The command moves old-only files with their comments and permissions intact. When both old and new filenames exist, it reports both paths and asks for a manual merge so no comments or values are lost. Resolve the reported files, then rerun the command. See the [configuration reference](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/reference/configuration/) for details.
|
|
61
|
+
|
|
62
|
+
An existing host may retain the old skill folders after installing 3.0. Check the host's project and global skills folders, back up any edits in the old folders, and move those eight folders out of skill discovery. The [troubleshooting guide](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/reference/troubleshooting/#old-slash-commands-still-appear-after-30) lists the exact folders and a safe cleanup sequence. Restart the host so its command list refreshes.
|
|
63
|
+
|
|
49
64
|
<a id="start-with-one-workflow"></a>
|
|
50
65
|
|
|
51
66
|
## Start with one skill
|
|
52
67
|
|
|
53
68
|
Eight commands start the eight workflows: Framework includes CI setup; Automate includes red and expand modes.
|
|
54
69
|
|
|
55
|
-
In Claude Code, Cursor, and Windsurf, type `/bmad-
|
|
56
|
-
In Codex, type `$bmad-
|
|
70
|
+
In Claude Code, Cursor, and Windsurf, type `/bmad-tea-test-design` in chat.
|
|
71
|
+
In Codex, type `$bmad-tea-test-design`.
|
|
57
72
|
You can also load `/bmad-tea` or `$bmad-tea` and choose a menu code.
|
|
58
73
|
Each skill can run directly in a fresh session.
|
|
59
74
|
|
|
60
75
|
| Skill | Command | Menu | Use it to |
|
|
61
76
|
| ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | ---- | ---------------------------------------------------- |
|
|
62
|
-
| [Automate](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/how-to/workflows/run-automate/) | `/bmad-
|
|
63
|
-
| [Test Review](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/how-to/workflows/run-test-review/) | `/bmad-
|
|
64
|
-
| [Test Design](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/how-to/workflows/run-test-design/) | `/bmad-
|
|
65
|
-
| [Framework](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/how-to/workflows/setup-test-framework/) | `/bmad-
|
|
66
|
-
| [NFR](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/how-to/workflows/run-nfr-assess/) | `/bmad-
|
|
67
|
-
| [Trace](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/how-to/workflows/run-trace/) | `/bmad-
|
|
68
|
-
| [Teach Me Testing](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/how-to/workflows/teach-me-testing/) | `/bmad-teach-me-testing`
|
|
77
|
+
| [Automate](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/how-to/workflows/run-automate/) | `/bmad-tea-automate` | TA | Generate red acceptance scaffolds or expand coverage |
|
|
78
|
+
| [Test Review](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/how-to/workflows/run-test-review/) | `/bmad-tea-test-review` | RV | Audit test quality and score findings |
|
|
79
|
+
| [Test Design](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/how-to/workflows/run-test-design/) | `/bmad-tea-test-design` | TD | Plan risks, coverage, and NFR evidence |
|
|
80
|
+
| [Framework](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/how-to/workflows/setup-test-framework/) | `/bmad-tea-framework` | TF | Set up a test framework, CI, or both |
|
|
81
|
+
| [NFR](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/how-to/workflows/run-nfr-assess/) | `/bmad-tea-nfr` | NR | Audit implemented NFR evidence |
|
|
82
|
+
| [Trace](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/how-to/workflows/run-trace/) | `/bmad-tea-trace` | TR | Map requirements to tests and decide a release gate |
|
|
83
|
+
| [Teach Me Testing](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/how-to/workflows/teach-me-testing/) | `/bmad-tea-teach-me-testing` | TMT | Learn testing through seven sessions |
|
|
69
84
|
|
|
70
85
|
Evaluate:
|
|
71
86
|
|
|
72
|
-
- [Evaluate](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/tutorials/evaluate-your-first-skill/): `/bmad-
|
|
87
|
+
- [Evaluate](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/tutorials/evaluate-your-first-skill/): `/bmad-tea-evaluate`, menu `EV`. Build and run a behavioral evaluation.
|
|
73
88
|
|
|
74
|
-
Framework and CI setup share one skill, `bmad-
|
|
89
|
+
Framework and CI setup share one skill, `bmad-tea-framework`.
|
|
75
90
|
Ask for framework only, CI only, or both; TEA infers the scope from your prompt and asks "Do you want CI too?" once when CI scope is unclear in an interactive session. An unattended request with unclear scope runs framework setup only and states that CI was excluded.
|
|
76
|
-
Request CI setup through `/bmad-
|
|
91
|
+
Request CI setup through `/bmad-tea-framework` or the agent's `CI` menu code. Migrated CI customizations remain usable.
|
|
77
92
|
Create, Resume, Validate, and Edit remain available for the selected setup scope.
|
|
78
93
|
|
|
79
|
-
Automation uses `red` mode before implementation and `expand` mode for existing code. Request red mode through `/bmad-
|
|
94
|
+
Automation uses `red` mode before implementation and `expand` mode for existing code. Request red mode through `/bmad-tea-automate` or the agent's `AT` menu code; the direct command defaults to expand. Migrated customization files and saved progress remain usable. Create runs execute the generated tests and repair test issues for up to three rounds. Red confirms the intended missing behavior; expand aims for passing coverage and reports product defects.
|
|
80
95
|
|
|
81
96
|
For Codex, replace the leading `/` in the table with `$`.
|
|
82
97
|
The agent menu also accepts `GATE` to route you through test review, NFR evidence audit, and trace Phase 2.
|
package/cli/atdd-red-check.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* tea-atdd-red-check — activates and executes the scaffolds
|
|
4
|
-
* `bmad-
|
|
4
|
+
* `bmad-tea-atdd` wrote, and reports what actually happened.
|
|
5
5
|
*
|
|
6
6
|
* This is the deterministic half of the ATDD suite, and it carries no vendor
|
|
7
7
|
* knowledge at all: it never calls a model, never resolves a credential, and
|
package/cli/atdd-runner.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* tea-atdd-runner — the command the ATDD behavioral contract names for
|
|
4
4
|
* generation.
|
|
5
5
|
*
|
|
6
|
-
* `bmad-
|
|
6
|
+
* `bmad-tea-atdd` reads a story's acceptance criteria and writes red-phase
|
|
7
7
|
* test scaffolds under the project's `tests/` directory, one deliverable this
|
|
8
8
|
* eval measures by executing rather than reading. Generation and execution are
|
|
9
9
|
* two separate commands: this one drives the workflow and leaves the scaffolds
|
package/cli/automate.js
CHANGED
|
@@ -135,11 +135,11 @@ async function main(argv) {
|
|
|
135
135
|
if (options.projectSkill) {
|
|
136
136
|
const candidates = ['.claude/skills', '.agents/skills', 'skills', '_bmad/tea/workflows/testarch'];
|
|
137
137
|
options.skillRoot = candidates
|
|
138
|
-
.map((directory) => path.join(root, directory, 'bmad-
|
|
138
|
+
.map((directory) => path.join(root, directory, 'bmad-tea-automate'))
|
|
139
139
|
.find((candidate) => fs.existsSync(path.join(candidate, 'SKILL.md')));
|
|
140
|
-
if (!options.skillRoot) throw new Error('project-installed bmad-
|
|
140
|
+
if (!options.skillRoot) throw new Error('project-installed bmad-tea-automate skill is missing');
|
|
141
141
|
}
|
|
142
|
-
skillRoot = resolveWorkflowSkill({ projectRoot: root, skillName: 'bmad-
|
|
142
|
+
skillRoot = resolveWorkflowSkill({ projectRoot: root, skillName: 'bmad-tea-automate', skillRoot: options.skillRoot });
|
|
143
143
|
if (!fs.existsSync(path.join(skillRoot, '..', 'bmod-tea', 'knowledge', 'tea-index.csv')))
|
|
144
144
|
throw new Error('the selected skill has no sibling bmod-tea knowledge base');
|
|
145
145
|
if (options.story) story = artifactPath(root, options.story, '--story');
|
package/cli/ci-runner.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* tea-ci-runner: the command the CI behavioral contract names.
|
|
4
4
|
*
|
|
5
|
-
* `bmad-
|
|
5
|
+
* `bmad-tea-ci` scaffolds a pipeline for the project it is run in and
|
|
6
6
|
* writes one deliverable a linter can hold to account, the platform's own
|
|
7
7
|
* workflow file, which for GitHub Actions is `.github/workflows/test.yml`.
|
|
8
8
|
* Measuring that needs a command to point at, and this file is that command.
|
|
@@ -27,7 +27,7 @@ function resolveGenerationConfig(projectRoot, checkpointPath, operation, skillRo
|
|
|
27
27
|
};
|
|
28
28
|
if (!['none', 'auto', 'cli', 'mcp'].includes(tea.tea_browser_automation))
|
|
29
29
|
throw new Error('tea_browser_automation must be none, auto, cli or mcp');
|
|
30
|
-
const namespace = mode === 'red' ? 'bmad-
|
|
30
|
+
const namespace = mode === 'red' ? 'bmad-tea-atdd' : 'bmad-tea-automate';
|
|
31
31
|
const sibling = path.join(skillRoot, '..', namespace, 'customize.toml');
|
|
32
32
|
const defaultsPath =
|
|
33
33
|
mode === 'red' && !fs.existsSync(sibling)
|
|
@@ -12,7 +12,7 @@ const { spawnSync } = require('node:child_process');
|
|
|
12
12
|
const { runAgent } = require('./run-agent');
|
|
13
13
|
const { resolveTeaConfig } = require('./resolve-tea-config');
|
|
14
14
|
|
|
15
|
-
const SKILL_NAME = 'bmad-
|
|
15
|
+
const SKILL_NAME = 'bmad-tea-framework';
|
|
16
16
|
const SCOPES = ['framework', 'ci', 'both'];
|
|
17
17
|
const OPERATIONS = ['create', 'resume', 'validate', 'edit'];
|
|
18
18
|
|
|
@@ -607,7 +607,7 @@ function prepareSetup({ projectRoot, skillRoot, config, options }) {
|
|
|
607
607
|
throw problem('Resume has an uncertain started hook. Record explicit operator recovery in the journal before headless execution.');
|
|
608
608
|
const scope = options.operation === 'resume' ? before.data.setup_scope : options.scope;
|
|
609
609
|
const ciConfig = ['ci', 'both'].includes(scope)
|
|
610
|
-
? resolveTeaConfig({ projectRoot, skillRoot: path.join(skillRoot, '
|
|
610
|
+
? resolveTeaConfig({ projectRoot, skillRoot: path.join(skillRoot, 'ci'), skillName: 'bmad-tea-ci' })
|
|
611
611
|
: null;
|
|
612
612
|
const requiredHooks = {};
|
|
613
613
|
for (const [phase, settings] of [
|
package/cli/lib/resolve-skill.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Resolve the installed bmad-
|
|
2
|
+
* Resolve the installed bmad-tea-test-review skill root inside a consuming project.
|
|
3
3
|
*
|
|
4
4
|
* Probe order mirrors BMAD installer outputs: BMAD core layout, Claude Code, Codex.
|
|
5
5
|
* The skill remains the source of truth for review logic; the CLI only locates it.
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
const fs = require('node:fs');
|
|
9
9
|
const path = require('node:path');
|
|
10
10
|
|
|
11
|
-
const SKILL_NAME = 'bmad-
|
|
11
|
+
const SKILL_NAME = 'bmad-tea-test-review';
|
|
12
12
|
|
|
13
13
|
// The classic installer's location comes last: a project upgraded from v6 can still hold that copy, and it must not shadow the skill the v7 install added.
|
|
14
14
|
const SKILL_CANDIDATES = [
|
|
@@ -285,7 +285,7 @@ function parseToml(content, label) {
|
|
|
285
285
|
}
|
|
286
286
|
|
|
287
287
|
/** Resolve trusted skill defaults and project workflow overrides from the same configuration source. */
|
|
288
|
-
function readWorkflowCustomization(source, skillRoot, projectRoot, skillName = 'bmad-
|
|
288
|
+
function readWorkflowCustomization(source, skillRoot, projectRoot, skillName = 'bmad-tea-test-review') {
|
|
289
289
|
if (!skillRoot) return {};
|
|
290
290
|
const defaultsPath = path.join(skillRoot, 'customize.toml');
|
|
291
291
|
source.recordInput?.(defaultsPath);
|
|
@@ -296,10 +296,24 @@ function readWorkflowCustomization(source, skillRoot, projectRoot, skillName = '
|
|
|
296
296
|
if (error.code !== 'ENOENT') throw configError(`Failed to load ${defaultsPath}: ${error.message}`);
|
|
297
297
|
}
|
|
298
298
|
if (!/^[a-z0-9][a-z0-9-]*$/.test(skillName)) throw configError('Workflow skill name must be a lowercase kebab-case name');
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
299
|
+
const oldName =
|
|
300
|
+
skillName === 'bmad-tea-teach-me-testing'
|
|
301
|
+
? 'bmad-teach-me-testing'
|
|
302
|
+
: skillName.startsWith('bmad-tea-')
|
|
303
|
+
? skillName.replace('bmad-tea-', 'bmad-testarch-')
|
|
304
|
+
: null;
|
|
305
|
+
for (const suffix of ['.toml', '.user.toml']) {
|
|
306
|
+
const legacyPath = oldName && path.join('_bmad', 'custom', oldName + suffix);
|
|
307
|
+
const currentPath = path.join('_bmad', 'custom', skillName + suffix);
|
|
308
|
+
const legacyContent = legacyPath && source.read(legacyPath);
|
|
309
|
+
const currentContent = source.read(currentPath);
|
|
310
|
+
const legacy = legacyContent === null ? {} : parseToml(legacyContent, source.label(legacyPath));
|
|
311
|
+
const current = currentContent === null ? {} : parseToml(currentContent, source.label(currentPath));
|
|
312
|
+
const conflict = conflictingValue(legacy, current);
|
|
313
|
+
if (conflict) {
|
|
314
|
+
throw configError(`Conflicting workflow customization ${conflict} in ${source.label(legacyPath)} and ${source.label(currentPath)}`);
|
|
315
|
+
}
|
|
316
|
+
merged = mergeTables(merged, unionEqualCustomizationValues(legacy, current));
|
|
303
317
|
}
|
|
304
318
|
if (merged.workflow !== undefined && !isPlainObject(merged.workflow)) {
|
|
305
319
|
throw configError('Workflow customization must contain a [workflow] table');
|
|
@@ -327,6 +341,29 @@ function readWorkflowCustomization(source, skillRoot, projectRoot, skillName = '
|
|
|
327
341
|
return workflow;
|
|
328
342
|
}
|
|
329
343
|
|
|
344
|
+
/** Find the first setting whose legacy and current values disagree. */
|
|
345
|
+
function conflictingValue(legacy, current, prefix = '') {
|
|
346
|
+
for (const [key, oldValue] of Object.entries(legacy)) {
|
|
347
|
+
if (!Object.hasOwn(current, key)) continue;
|
|
348
|
+
const next = prefix ? `${prefix}.${key}` : key;
|
|
349
|
+
const newValue = current[key];
|
|
350
|
+
if (isPlainObject(oldValue) && isPlainObject(newValue)) {
|
|
351
|
+
const nested = conflictingValue(oldValue, newValue, next);
|
|
352
|
+
if (nested) return nested;
|
|
353
|
+
} else if (JSON.stringify(oldValue) !== JSON.stringify(newValue)) return next;
|
|
354
|
+
}
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/** Combine old and new names for one layer without appending an identical array twice. */
|
|
359
|
+
function unionEqualCustomizationValues(legacy, current) {
|
|
360
|
+
const result = { ...legacy };
|
|
361
|
+
for (const [key, value] of Object.entries(current)) {
|
|
362
|
+
result[key] = isPlainObject(result[key]) && isPlainObject(value) ? unionEqualCustomizationValues(result[key], value) : value;
|
|
363
|
+
}
|
|
364
|
+
return result;
|
|
365
|
+
}
|
|
366
|
+
|
|
330
367
|
/** Coerce the keys this CLI cares about out of a raw TEA config table. */
|
|
331
368
|
function pickTeaValues(table, source) {
|
|
332
369
|
const values = {};
|
|
@@ -74,7 +74,7 @@ function isReferenceHeading(heading) {
|
|
|
74
74
|
* second risk table, an explanatory sentence, an HTML comment). `Reference:` and
|
|
75
75
|
* `References:` open citations, so they label nothing; so does `For example:`.
|
|
76
76
|
*
|
|
77
|
-
* The shipped worked example, `bmad-
|
|
77
|
+
* The shipped worked example, `bmad-tea-test-design/resources/test-design-epic-3.example.md`,
|
|
78
78
|
* shows the register this rule keeps: the three band tables under `## Risk Assessment`
|
|
79
79
|
* (`### High Risks: Score 6 or Greater`, `### Medium Risks: Score 3 to 4`,
|
|
80
80
|
* `### Low Risks: Score 1 to 2`), none of whose headings or lead-ins labels anything.
|
package/cli/lib/workflow-cli.js
CHANGED
|
@@ -111,7 +111,11 @@ function resolveWorkflowSkill({ projectRoot, skillName, skillRoot }) {
|
|
|
111
111
|
if (!fs.statSync(path.join(knowledge, 'tea-index.csv')).isFile()) throw new Error('sibling bmod-tea knowledge is missing');
|
|
112
112
|
return fs.realpathSync(root);
|
|
113
113
|
} catch (error) {
|
|
114
|
-
throw new WorkflowError(
|
|
114
|
+
throw new WorkflowError(
|
|
115
|
+
'environment-configuration',
|
|
116
|
+
`${skillName} is unavailable at ${root}: ${error.message}. Install TEA with npx skills add bmad-code-org/bmad-method-test-architecture-enterprise`,
|
|
117
|
+
{ cause: error },
|
|
118
|
+
);
|
|
115
119
|
}
|
|
116
120
|
}
|
|
117
121
|
/** Activate the actual skill using authoritative config and caller run inputs. */
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/** Move pre-3.0 TEA customization files and menu references to canonical names. */
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { isDeepStrictEqual } = require('node:util');
|
|
6
|
+
const TOML = require('smol-toml');
|
|
7
|
+
|
|
8
|
+
const NAMES = ['automate', 'evaluate', 'framework', 'nfr', 'test-design', 'test-review', 'trace', 'atdd', 'ci'];
|
|
9
|
+
const PAIRS = [
|
|
10
|
+
...NAMES.map((suffix) => [`bmad-testarch-${suffix}`, `bmad-tea-${suffix}`]),
|
|
11
|
+
['bmad-teach-me-testing', 'bmad-tea-teach-me-testing'],
|
|
12
|
+
];
|
|
13
|
+
const MENU_NAMES = new Map(PAIRS);
|
|
14
|
+
MENU_NAMES.set('bmad-testarch-atdd', 'bmad-tea-automate');
|
|
15
|
+
MENU_NAMES.set('bmad-testarch-ci', 'bmad-tea-framework');
|
|
16
|
+
|
|
17
|
+
function isTable(value) {
|
|
18
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function conflictAt(oldValue, newValue, key = '') {
|
|
22
|
+
for (const [name, value] of Object.entries(oldValue)) {
|
|
23
|
+
if (!Object.hasOwn(newValue, name)) continue;
|
|
24
|
+
const location = key ? `${key}.${name}` : name;
|
|
25
|
+
if (isTable(value) && isTable(newValue[name])) {
|
|
26
|
+
const nested = conflictAt(value, newValue[name], location);
|
|
27
|
+
if (nested) return nested;
|
|
28
|
+
} else if (!isDeepStrictEqual(value, newValue[name])) return location;
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function parse(file, source) {
|
|
34
|
+
try {
|
|
35
|
+
return TOML.parse(source);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
throw new Error(`Cannot parse ${file}: ${error.message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Reject links and non-files before any content is read or changed. */
|
|
42
|
+
function readFile(file) {
|
|
43
|
+
let stat;
|
|
44
|
+
try {
|
|
45
|
+
stat = fs.lstatSync(file);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
if (error.code === 'ENOENT') return null;
|
|
48
|
+
throw new Error(`Cannot inspect ${file}: ${error.message}`);
|
|
49
|
+
}
|
|
50
|
+
if (!stat.isFile() || stat.isSymbolicLink())
|
|
51
|
+
throw new Error(`Customization path must be a regular file, not a symlink or special file: ${file}`);
|
|
52
|
+
return { file, stat, text: fs.readFileSync(file, 'utf8') };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function checkDirectory(directory, required = false) {
|
|
56
|
+
let stat;
|
|
57
|
+
try {
|
|
58
|
+
stat = fs.lstatSync(directory);
|
|
59
|
+
} catch (error) {
|
|
60
|
+
if (error.code === 'ENOENT' && !required) return false;
|
|
61
|
+
if (error.code === 'ENOENT') throw new Error(`Project root does not exist: ${directory}`);
|
|
62
|
+
throw new Error(`Cannot inspect ${directory}: ${error.message}`);
|
|
63
|
+
}
|
|
64
|
+
if (!stat.isDirectory() || stat.isSymbolicLink()) throw new Error(`Customization path must be a real directory: ${directory}`);
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Edit only skill assignments inside agent menu entries, retaining every other byte. */
|
|
69
|
+
function rewriteMenu(file, source) {
|
|
70
|
+
const original = parse(file, source);
|
|
71
|
+
const menus = original.agent?.menu;
|
|
72
|
+
if (menus !== undefined && !Array.isArray(menus)) throw new Error(`Expected [[agent.menu]] entries in ${file}`);
|
|
73
|
+
const expected = structuredClone(original);
|
|
74
|
+
let expectedChanges = 0;
|
|
75
|
+
for (const menu of expected.agent?.menu ?? []) {
|
|
76
|
+
if (typeof menu.skill !== 'string' || !(menu.skill.startsWith('bmad-testarch-') || menu.skill === 'bmad-teach-me-testing')) continue;
|
|
77
|
+
const replacement = MENU_NAMES.get(menu.skill);
|
|
78
|
+
if (!replacement) throw new Error(`Unknown legacy menu skill ${JSON.stringify(menu.skill)} in ${file}; update it manually`);
|
|
79
|
+
menu.skill = replacement;
|
|
80
|
+
expectedChanges++;
|
|
81
|
+
}
|
|
82
|
+
if (expectedChanges === 0) return null;
|
|
83
|
+
let inMenu = false;
|
|
84
|
+
let actualChanges = 0;
|
|
85
|
+
const lines = source.split(/(\r?\n)/);
|
|
86
|
+
for (let index = 0; index < lines.length; index += 2) {
|
|
87
|
+
const line = lines[index];
|
|
88
|
+
if (/^\s*\[/.test(line)) inMenu = /^\s*\[\[agent\.menu\]\]\s*(?:#.*)?$/.test(line);
|
|
89
|
+
if (!inMenu) continue;
|
|
90
|
+
const match = /^(\s*skill\s*=\s*)(["'])([^"']+)\2(\s*(?:#.*)?)$/.exec(line);
|
|
91
|
+
if (!match || !MENU_NAMES.has(match[3])) continue;
|
|
92
|
+
lines[index] = `${match[1]}${match[2]}${MENU_NAMES.get(match[3])}${match[2]}${match[4]}`;
|
|
93
|
+
actualChanges++;
|
|
94
|
+
}
|
|
95
|
+
const rewritten = lines.join('');
|
|
96
|
+
if (actualChanges !== expectedChanges || !isDeepStrictEqual(parse(file, rewritten), expected)) {
|
|
97
|
+
throw new Error(`Cannot safely rewrite legacy menu skill references in ${file}; update them manually`);
|
|
98
|
+
}
|
|
99
|
+
return rewritten;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function preflight(customRoot) {
|
|
103
|
+
const actions = [];
|
|
104
|
+
for (const [oldName, newName] of PAIRS) {
|
|
105
|
+
for (const suffix of ['.toml', '.user.toml']) {
|
|
106
|
+
const oldFile = path.join(customRoot, oldName + suffix);
|
|
107
|
+
const newFile = path.join(customRoot, newName + suffix);
|
|
108
|
+
const old = readFile(oldFile);
|
|
109
|
+
const current = readFile(newFile);
|
|
110
|
+
if (!old) continue;
|
|
111
|
+
const oldValue = parse(oldFile, old.text);
|
|
112
|
+
if (current) {
|
|
113
|
+
const newValue = parse(newFile, current.text);
|
|
114
|
+
const conflict = conflictAt(oldValue, newValue);
|
|
115
|
+
if (conflict) throw new Error(`Conflicting ${conflict} in ${oldFile} and ${newFile}`);
|
|
116
|
+
throw new Error(
|
|
117
|
+
`Both ${oldFile} and ${newFile} exist. Merge their values and comments manually into ${newFile}, then remove ${oldFile} and rerun.`,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
actions.push({ kind: 'move', oldFile, newFile, old });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
for (const suffix of ['.toml', '.user.toml']) {
|
|
124
|
+
const file = path.join(customRoot, 'bmad-tea' + suffix);
|
|
125
|
+
const old = readFile(file);
|
|
126
|
+
if (!old) continue;
|
|
127
|
+
const rewritten = rewriteMenu(file, old.text);
|
|
128
|
+
if (rewritten !== null) actions.push({ kind: 'rewrite', oldFile: file, newFile: file, old, text: rewritten });
|
|
129
|
+
}
|
|
130
|
+
return actions;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function unchanged(snapshot) {
|
|
134
|
+
const current = readFile(snapshot.file);
|
|
135
|
+
return (
|
|
136
|
+
current !== null &&
|
|
137
|
+
current.stat.dev === snapshot.stat.dev &&
|
|
138
|
+
current.stat.ino === snapshot.stat.ino &&
|
|
139
|
+
current.stat.mode === snapshot.stat.mode &&
|
|
140
|
+
current.text === snapshot.text
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Apply staged changes under one exclusive lock and undo completed actions on failure. */
|
|
145
|
+
function applyActions(actions, customRoot, beforeAction) {
|
|
146
|
+
const completed = [];
|
|
147
|
+
const temporary = [];
|
|
148
|
+
let rollbackSafe = true;
|
|
149
|
+
try {
|
|
150
|
+
for (const [index, action] of actions.entries()) {
|
|
151
|
+
if (action.kind !== 'rewrite') continue;
|
|
152
|
+
const temp = path.join(customRoot, `.tea-migration-${process.pid}-${index}.tmp`);
|
|
153
|
+
fs.writeFileSync(temp, action.text, { flag: 'wx', mode: action.old.stat.mode & 0o777 });
|
|
154
|
+
fs.chmodSync(temp, action.old.stat.mode & 0o777);
|
|
155
|
+
action.temp = temp;
|
|
156
|
+
temporary.push(temp);
|
|
157
|
+
}
|
|
158
|
+
for (const [index, action] of actions.entries()) {
|
|
159
|
+
beforeAction?.(action, index);
|
|
160
|
+
if (!unchanged(action.old)) throw new Error(`Customization changed during migration: ${action.oldFile}`);
|
|
161
|
+
if (action.kind === 'move') {
|
|
162
|
+
if (readFile(action.newFile) !== null) throw new Error(`Customization appeared during migration: ${action.newFile}`);
|
|
163
|
+
fs.linkSync(action.oldFile, action.newFile);
|
|
164
|
+
completed.push(action);
|
|
165
|
+
fs.unlinkSync(action.oldFile);
|
|
166
|
+
} else {
|
|
167
|
+
const backup = path.join(customRoot, `.tea-migration-${process.pid}-${index}.bak`);
|
|
168
|
+
fs.linkSync(action.oldFile, backup);
|
|
169
|
+
action.backup = backup;
|
|
170
|
+
completed.push(action);
|
|
171
|
+
fs.renameSync(action.temp, action.oldFile);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
} catch (error) {
|
|
175
|
+
const rollbackErrors = [];
|
|
176
|
+
for (const action of completed.toReversed()) {
|
|
177
|
+
try {
|
|
178
|
+
if (action.kind === 'move') {
|
|
179
|
+
if (!fs.existsSync(action.oldFile)) fs.linkSync(action.newFile, action.oldFile);
|
|
180
|
+
fs.unlinkSync(action.newFile);
|
|
181
|
+
} else {
|
|
182
|
+
if (fs.existsSync(action.oldFile)) fs.unlinkSync(action.oldFile);
|
|
183
|
+
fs.linkSync(action.backup, action.oldFile);
|
|
184
|
+
fs.unlinkSync(action.backup);
|
|
185
|
+
}
|
|
186
|
+
} catch (rollbackError) {
|
|
187
|
+
rollbackErrors.push(`${action.oldFile}: ${rollbackError.message}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
rollbackSafe = rollbackErrors.length === 0;
|
|
191
|
+
throw new Error(`${error.message}${rollbackErrors.length > 0 ? `; rollback needs manual repair: ${rollbackErrors.join('; ')}` : ''}`);
|
|
192
|
+
} finally {
|
|
193
|
+
if (rollbackSafe) for (const action of actions) if (action.backup && fs.existsSync(action.backup)) fs.unlinkSync(action.backup);
|
|
194
|
+
for (const temp of temporary) if (fs.existsSync(temp)) fs.unlinkSync(temp);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function migrate(projectRoot, { check = false, beforeAction } = {}) {
|
|
199
|
+
const root = path.resolve(projectRoot);
|
|
200
|
+
checkDirectory(root, true);
|
|
201
|
+
const bmadRoot = path.join(root, '_bmad');
|
|
202
|
+
if (!checkDirectory(bmadRoot)) return [];
|
|
203
|
+
const customRoot = path.join(bmadRoot, 'custom');
|
|
204
|
+
if (!checkDirectory(customRoot)) return [];
|
|
205
|
+
if (check) return preflight(customRoot);
|
|
206
|
+
const lock = path.join(customRoot, '.tea-migration.lock');
|
|
207
|
+
try {
|
|
208
|
+
fs.mkdirSync(lock, { mode: 0o700 });
|
|
209
|
+
} catch (error) {
|
|
210
|
+
if (error.code === 'EEXIST') {
|
|
211
|
+
throw new Error(
|
|
212
|
+
`Migration lock exists at ${lock}. Check for a running migration; if none is running, inspect and remove the stale lock directory, then retry.`,
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
throw new Error(`Cannot lock ${customRoot} for migration: ${error.message}`);
|
|
216
|
+
}
|
|
217
|
+
try {
|
|
218
|
+
const actions = preflight(customRoot);
|
|
219
|
+
applyActions(actions, customRoot, beforeAction);
|
|
220
|
+
return actions;
|
|
221
|
+
} finally {
|
|
222
|
+
fs.rmdirSync(lock);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function main(argv = process.argv.slice(2)) {
|
|
227
|
+
const usage = 'Usage: tea-migrate-customizations [--project-root PATH] [--check]';
|
|
228
|
+
const rootIndex = argv.indexOf('--project-root');
|
|
229
|
+
if (rootIndex !== -1 && (!argv[rootIndex + 1] || argv[rootIndex + 1].startsWith('--'))) throw new Error('--project-root requires a path');
|
|
230
|
+
if (argv.some((arg, index) => arg !== '--check' && arg !== '--project-root' && index !== rootIndex + 1)) throw new Error(usage);
|
|
231
|
+
const projectRoot = rootIndex < 0 ? process.cwd() : path.resolve(argv[rootIndex + 1]);
|
|
232
|
+
const check = argv.includes('--check');
|
|
233
|
+
const actions = migrate(projectRoot, { check });
|
|
234
|
+
for (const action of actions) {
|
|
235
|
+
process.stdout.write(
|
|
236
|
+
action.kind === 'rewrite'
|
|
237
|
+
? `${check ? 'Would update' : 'Updated'} menu references in ${action.oldFile}\n`
|
|
238
|
+
: `${check ? 'Would move ' : ''}${action.oldFile} -> ${action.newFile}\n`,
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
if (actions.length === 0) process.stdout.write('No legacy TEA customizations found.\n');
|
|
242
|
+
return 0;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (require.main === module) {
|
|
246
|
+
try {
|
|
247
|
+
process.exitCode = main();
|
|
248
|
+
} catch (error) {
|
|
249
|
+
process.stderr.write(`${error.message}\n`);
|
|
250
|
+
process.exitCode = 2;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
module.exports = { migrate, main };
|
package/cli/nfr-runner.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* tea-nfr-runner — the command the NFR behavioral contract names.
|
|
4
4
|
*
|
|
5
|
-
* `bmad-
|
|
5
|
+
* `bmad-tea-nfr` audits the evidence a team already holds and writes one
|
|
6
6
|
* deliverable, `{test_artifacts}/nfr/nfr-assessment-{run_key}.md`. Measuring that needs a
|
|
7
7
|
* command to point at, and TEA shipped none: `tea-test-review`,
|
|
8
8
|
* `tea-fragment-selection-runner`, and `tea-trace-runner` all exist and an NFR
|
package/cli/nfr.js
CHANGED
|
@@ -95,8 +95,8 @@ function run(argv) {
|
|
|
95
95
|
)
|
|
96
96
|
throw new WorkflowError('usage', 'requirement inputs cannot also be implementation evidence');
|
|
97
97
|
const protection = protectSources(projectRoot, [...inputs, ...options.implementation, ...options.evidence]);
|
|
98
|
-
const skillRoot = resolveWorkflowSkill({ projectRoot, skillName: 'bmad-
|
|
99
|
-
const resolvedConfig = resolveTeaConfig({ projectRoot, skillRoot, skillName: 'bmad-
|
|
98
|
+
const skillRoot = resolveWorkflowSkill({ projectRoot, skillName: 'bmad-tea-nfr', skillRoot: options.skillRoot });
|
|
99
|
+
const resolvedConfig = resolveTeaConfig({ projectRoot, skillRoot, skillName: 'bmad-tea-nfr' });
|
|
100
100
|
const artifactRoot = options.outputDir ?? resolvedConfig.configSnapshot.modules.tea.test_artifacts;
|
|
101
101
|
if (typeof artifactRoot !== 'string' || !artifactRoot.trim())
|
|
102
102
|
throw new WorkflowError('environment-configuration', '--output-dir or TEA test_artifacts must be a nonempty string');
|
package/cli/teach.js
CHANGED
|
@@ -106,13 +106,13 @@ function run(argv = process.argv) {
|
|
|
106
106
|
const inputFile = options.messageFile ? readInput(root, options.messageFile, '--message-file') : null;
|
|
107
107
|
const message = inputFile ? new TextDecoder('utf-8', { fatal: true }).decode(fs.readFileSync(inputFile)) : options.message;
|
|
108
108
|
if (!message.trim()) throw new WorkflowError('usage', 'learner message must be nonempty');
|
|
109
|
-
const skillRoot = resolveWorkflowSkill({ projectRoot: root, skillName: 'bmad-teach-me-testing', skillRoot: options.skillRoot });
|
|
109
|
+
const skillRoot = resolveWorkflowSkill({ projectRoot: root, skillName: 'bmad-tea-teach-me-testing', skillRoot: options.skillRoot });
|
|
110
110
|
const consumedInputs = new Set();
|
|
111
111
|
const inputPatterns = new Map();
|
|
112
112
|
const config = resolveTeaConfig({
|
|
113
113
|
projectRoot: root,
|
|
114
114
|
skillRoot,
|
|
115
|
-
skillName: 'bmad-teach-me-testing',
|
|
115
|
+
skillName: 'bmad-tea-teach-me-testing',
|
|
116
116
|
inputPaths: consumedInputs,
|
|
117
117
|
inputPatterns,
|
|
118
118
|
});
|
|
@@ -149,8 +149,8 @@ function run(argv = process.argv) {
|
|
|
149
149
|
'_bmad/custom/config.user.toml',
|
|
150
150
|
'package.json',
|
|
151
151
|
'package-lock.json',
|
|
152
|
-
'_bmad/custom/bmad-teach-me-testing.toml',
|
|
153
|
-
'_bmad/custom/bmad-teach-me-testing.user.toml',
|
|
152
|
+
'_bmad/custom/bmad-tea-teach-me-testing.toml',
|
|
153
|
+
'_bmad/custom/bmad-tea-teach-me-testing.user.toml',
|
|
154
154
|
].map((file) => path.join(root, file)),
|
|
155
155
|
].filter(Boolean);
|
|
156
156
|
const guard = () => {
|
package/cli/test-design.js
CHANGED
|
@@ -324,8 +324,8 @@ function run(argv) {
|
|
|
324
324
|
if (options.scope === 'system' && inputs.length < 2)
|
|
325
325
|
throw new WorkflowError('usage', 'system scope requires two distinct input documents');
|
|
326
326
|
const inputDigests = inputs.map((file) => [file, digest(file)]);
|
|
327
|
-
const skillRoot = resolveWorkflowSkill({ projectRoot, skillName: 'bmad-
|
|
328
|
-
const resolvedConfig = resolveTeaConfig({ projectRoot, skillRoot, skillName: 'bmad-
|
|
327
|
+
const skillRoot = resolveWorkflowSkill({ projectRoot, skillName: 'bmad-tea-test-design', skillRoot: options.skillRoot });
|
|
328
|
+
const resolvedConfig = resolveTeaConfig({ projectRoot, skillRoot, skillName: 'bmad-tea-test-design' });
|
|
329
329
|
const outputValue =
|
|
330
330
|
options.outputDir || resolvedConfig.configSnapshot.modules.tea.test_artifacts.replaceAll('{project-root}', projectRoot);
|
|
331
331
|
const outputDir = projectPath(projectRoot, outputValue, '--output-dir');
|
package/cli/test-review.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* tea-test-review — headless runner for the bmad-
|
|
3
|
+
* tea-test-review — headless runner for the bmad-tea-test-review skill.
|
|
4
4
|
*
|
|
5
5
|
* Runs the review skill shipped in this package (or, with --project-skill, the
|
|
6
6
|
* copy a consuming project vendored), splits the PR diff into
|
|
@@ -582,7 +582,7 @@ async function runReview(session) {
|
|
|
582
582
|
.name('tea-test-review')
|
|
583
583
|
.version(TEA_CLI_VERSION)
|
|
584
584
|
.description(
|
|
585
|
-
"Headless runner for the bmad-
|
|
585
|
+
"Headless runner for the bmad-tea-test-review skill: scopes the review to the PR's changed test files, reads the rest of the diff as context, and emits a JSON verdict with CI-friendly exit codes. `tea-test-review render --help` renders a verdict into the comment, check-run and summary text.",
|
|
586
586
|
)
|
|
587
587
|
.option(
|
|
588
588
|
'--base <ref>',
|
|
@@ -1014,7 +1014,7 @@ async function runReview(session) {
|
|
|
1014
1014
|
fail(
|
|
1015
1015
|
EXIT.ENV_ERROR,
|
|
1016
1016
|
`The TEA knowledge base is not installed beside the skill (expected ${path.resolve(knowledgeIndex)}).\n` +
|
|
1017
|
-
'Install bmod-tea next to bmad-
|
|
1017
|
+
'Install bmod-tea next to bmad-tea-test-review: npx skills add bmad-code-org/bmad-method-test-architecture-enterprise --skill bmod-tea',
|
|
1018
1018
|
);
|
|
1019
1019
|
}
|
|
1020
1020
|
|