@cregis-dev/cckit 0.3.0 → 0.4.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/README.md +15 -3
- package/package.json +1 -1
- package/registry.json +234 -200
- package/src/commands/init.js +19 -15
- package/src/commands/update.js +9 -4
- package/src/core/plugin-installer.js +59 -13
- package/src/utils/fs.js +6 -1
- package/templates/bmad/_config/bmad-help.csv +2 -1
- package/templates/bmad/_config/files-manifest.csv +437 -431
- package/templates/bmad/_config/ides/claude-code.yaml +5 -5
- package/templates/bmad/_config/ides/trae.yaml +5 -5
- package/templates/bmad/_config/task-manifest.csv +7 -6
- package/templates/bmad/_config/workflow-manifest.csv +34 -34
- package/templates/bmad/bmm/agents/qa.md +1 -1
- package/templates/bmad/bmm/config.yaml +1 -1
- package/templates/bmad/bmm/module-help.csv +1 -1
- package/templates/bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +1 -1
- package/templates/bmad/bmm/workflows/1-analysis/create-product-brief/workflow.md +1 -1
- package/templates/bmad/bmm/workflows/1-analysis/research/workflow-domain-research.md +1 -1
- package/templates/bmad/bmm/workflows/1-analysis/research/workflow-market-research.md +1 -1
- package/templates/bmad/bmm/workflows/1-analysis/research/workflow-technical-research.md +1 -1
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-12-complete.md +1 -1
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +1 -1
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/workflow-create-prd.md +1 -1
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/workflow-edit-prd.md +1 -1
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md +1 -1
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +1 -1
- package/templates/bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +1 -1
- package/templates/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +1 -1
- package/templates/bmad/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +1 -1
- package/templates/bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +1 -1
- package/templates/bmad/bmm/workflows/3-solutioning/create-architecture/workflow.md +1 -1
- package/templates/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +1 -1
- package/templates/bmad/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +1 -1
- package/templates/bmad/bmm/workflows/4-implementation/code-review/workflow.yaml +1 -1
- package/templates/bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml +1 -1
- package/templates/bmad/bmm/workflows/4-implementation/create-story/workflow.yaml +1 -1
- package/templates/bmad/bmm/workflows/4-implementation/dev-story/workflow.yaml +1 -1
- package/templates/bmad/bmm/workflows/4-implementation/retrospective/workflow.yaml +1 -1
- package/templates/bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +1 -1
- package/templates/bmad/bmm/workflows/4-implementation/sprint-status/workflow.yaml +1 -1
- package/templates/bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +1 -1
- package/templates/bmad/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md +1 -1
- package/templates/bmad/bmm/workflows/document-project/workflow.yaml +1 -1
- package/templates/bmad/bmm/workflows/generate-project-context/workflow.md +1 -1
- package/templates/bmad/bmm/workflows/qa-generate-e2e-tests/workflow.yaml +2 -2
- package/templates/bmad/commands/bmad-bmm-check-implementation-readiness.md +2 -2
- package/templates/bmad/commands/bmad-bmm-code-review.md +4 -4
- package/templates/bmad/commands/bmad-bmm-correct-course.md +4 -4
- package/templates/bmad/commands/bmad-bmm-create-architecture.md +2 -2
- package/templates/bmad/commands/bmad-bmm-create-epics-and-stories.md +2 -2
- package/templates/bmad/commands/bmad-bmm-create-prd.md +2 -2
- package/templates/bmad/commands/bmad-bmm-create-product-brief.md +2 -2
- package/templates/bmad/commands/bmad-bmm-create-story.md +4 -4
- package/templates/bmad/commands/bmad-bmm-create-ux-design.md +2 -2
- package/templates/bmad/commands/bmad-bmm-dev-story.md +4 -4
- package/templates/bmad/commands/bmad-bmm-document-project.md +4 -4
- package/templates/bmad/commands/bmad-bmm-domain-research.md +2 -2
- package/templates/bmad/commands/bmad-bmm-edit-prd.md +2 -2
- package/templates/bmad/commands/bmad-bmm-generate-project-context.md +2 -2
- package/templates/bmad/commands/bmad-bmm-market-research.md +2 -2
- package/templates/bmad/commands/bmad-bmm-qa-generate-e2e-tests.md +4 -4
- package/templates/bmad/commands/bmad-bmm-quick-dev.md +2 -2
- package/templates/bmad/commands/bmad-bmm-quick-spec.md +2 -2
- package/templates/bmad/commands/bmad-bmm-retrospective.md +4 -4
- package/templates/bmad/commands/bmad-bmm-sprint-planning.md +4 -4
- package/templates/bmad/commands/bmad-bmm-sprint-status.md +4 -4
- package/templates/bmad/commands/bmad-bmm-technical-research.md +2 -2
- package/templates/bmad/commands/bmad-bmm-validate-prd.md +2 -2
- package/templates/bmad/commands/bmad-brainstorming.md +2 -2
- package/templates/bmad/commands/bmad-editorial-review-prose.md +1 -1
- package/templates/bmad/commands/bmad-editorial-review-structure.md +1 -1
- package/templates/bmad/commands/bmad-help.md +1 -1
- package/templates/bmad/commands/bmad-index-docs.md +1 -1
- package/templates/bmad/commands/bmad-party-mode.md +2 -2
- package/templates/bmad/commands/bmad-review-adversarial-general.md +1 -1
- package/templates/bmad/commands/bmad-review-edge-case-hunter.md +10 -0
- package/templates/bmad/commands/bmad-shard-doc.md +1 -1
- package/templates/bmad/commands/bmad-tea-teach-me-testing.md +2 -2
- package/templates/bmad/commands/bmad-tea-testarch-atdd.md +4 -4
- package/templates/bmad/commands/bmad-tea-testarch-automate.md +4 -4
- package/templates/bmad/commands/bmad-tea-testarch-ci.md +4 -4
- package/templates/bmad/commands/bmad-tea-testarch-framework.md +4 -4
- package/templates/bmad/commands/bmad-tea-testarch-nfr.md +4 -4
- package/templates/bmad/commands/bmad-tea-testarch-test-design.md +4 -4
- package/templates/bmad/commands/bmad-tea-testarch-test-review.md +4 -4
- package/templates/bmad/commands/bmad-tea-testarch-trace.md +4 -4
- package/templates/bmad/core/config.yaml +1 -1
- package/templates/bmad/core/module-help.csv +1 -0
- package/templates/bmad/core/tasks/editorial-review-prose.xml +1 -1
- package/templates/bmad/core/tasks/editorial-review-structure.xml +1 -1
- package/templates/bmad/core/tasks/help.md +1 -1
- package/templates/bmad/core/tasks/index-docs.xml +1 -1
- package/templates/bmad/core/tasks/review-adversarial-general.xml +1 -1
- package/templates/bmad/core/tasks/review-edge-case-hunter.xml +63 -0
- package/templates/bmad/core/tasks/shard-doc.xml +1 -1
- package/templates/bmad/core/workflows/advanced-elicitation/workflow.xml +1 -1
- package/templates/bmad/core/workflows/brainstorming/steps/step-01-session-setup.md +31 -18
- package/templates/bmad/core/workflows/brainstorming/steps/step-01b-continue.md +1 -1
- package/templates/bmad/core/workflows/brainstorming/steps/step-03-technique-execution.md +2 -2
- package/templates/bmad/core/workflows/brainstorming/steps/step-04-idea-organization.md +2 -2
- package/templates/bmad/core/workflows/brainstorming/workflow.md +4 -2
- package/templates/bmad/core/workflows/party-mode/workflow.md +1 -1
- package/templates/bmad/tea/config.yaml +5 -1
- package/templates/bmad/tea/testarch/knowledge/contract-testing.md +24 -2
- package/templates/bmad/tea/testarch/knowledge/pact-mcp.md +204 -0
- package/templates/bmad/tea/testarch/knowledge/pactjs-utils-consumer-helpers.md +211 -0
- package/templates/bmad/tea/testarch/knowledge/pactjs-utils-overview.md +210 -0
- package/templates/bmad/tea/testarch/knowledge/pactjs-utils-provider-verifier.md +315 -0
- package/templates/bmad/tea/testarch/knowledge/pactjs-utils-request-filter.md +224 -0
- package/templates/bmad/tea/testarch/tea-index.csv +5 -0
- package/templates/bmad/tea/workflows/testarch/README.md +1 -1
- package/templates/bmad/tea/workflows/testarch/atdd/steps-c/step-01-preflight-and-context.md +30 -0
- package/templates/bmad/tea/workflows/testarch/atdd/steps-c/step-04-generate-tests.md +159 -57
- package/templates/bmad/tea/workflows/testarch/atdd/steps-c/step-04a-subagent-api-failing.md +215 -0
- package/templates/bmad/tea/workflows/testarch/atdd/steps-c/step-04b-subagent-e2e-failing.md +244 -0
- package/templates/bmad/tea/workflows/testarch/atdd/steps-c/step-04c-aggregate.md +31 -15
- package/templates/bmad/tea/workflows/testarch/atdd/validation-report-20260127-095021.md +1 -1
- package/templates/bmad/tea/workflows/testarch/atdd/validation-report-20260127-102401.md +3 -3
- package/templates/bmad/tea/workflows/testarch/atdd/workflow.yaml +2 -2
- package/templates/bmad/tea/workflows/testarch/automate/steps-c/step-01-preflight-and-context.md +32 -0
- package/templates/bmad/tea/workflows/testarch/automate/steps-c/step-03-generate-tests.md +215 -101
- package/templates/bmad/tea/workflows/testarch/automate/steps-c/step-03a-subagent-api.md +193 -0
- package/templates/bmad/tea/workflows/testarch/automate/steps-c/step-03b-subagent-backend.md +246 -0
- package/templates/bmad/tea/workflows/testarch/automate/steps-c/step-03b-subagent-e2e.md +213 -0
- package/templates/bmad/tea/workflows/testarch/automate/steps-c/step-03c-aggregate.md +38 -22
- package/templates/bmad/tea/workflows/testarch/automate/validation-report-20260127-095021.md +1 -1
- package/templates/bmad/tea/workflows/testarch/automate/validation-report-20260127-102401.md +3 -3
- package/templates/bmad/tea/workflows/testarch/automate/workflow.yaml +2 -2
- package/templates/bmad/tea/workflows/testarch/ci/steps-c/step-02-generate-pipeline.md +124 -1
- package/templates/bmad/tea/workflows/testarch/ci/steps-c/step-03-configure-quality-gates.md +7 -0
- package/templates/bmad/tea/workflows/testarch/ci/validation-report-20260127-095021.md +1 -1
- package/templates/bmad/tea/workflows/testarch/ci/validation-report-20260127-102401.md +3 -3
- package/templates/bmad/tea/workflows/testarch/ci/workflow.yaml +2 -2
- package/templates/bmad/tea/workflows/testarch/framework/steps-c/step-03-scaffold-framework.md +126 -3
- package/templates/bmad/tea/workflows/testarch/framework/validation-report-20260127-095021.md +1 -1
- package/templates/bmad/tea/workflows/testarch/framework/validation-report-20260127-102401.md +3 -3
- package/templates/bmad/tea/workflows/testarch/framework/workflow.yaml +2 -2
- package/templates/bmad/tea/workflows/testarch/nfr-assess/steps-c/step-04-evaluate-and-score.md +150 -36
- package/templates/bmad/tea/workflows/testarch/nfr-assess/steps-c/step-04a-subagent-security.md +138 -0
- package/templates/bmad/tea/workflows/testarch/nfr-assess/steps-c/step-04b-subagent-performance.md +84 -0
- package/templates/bmad/tea/workflows/testarch/nfr-assess/steps-c/step-04c-subagent-reliability.md +85 -0
- package/templates/bmad/tea/workflows/testarch/nfr-assess/steps-c/step-04d-subagent-scalability.md +88 -0
- package/templates/bmad/tea/workflows/testarch/nfr-assess/steps-c/step-04e-aggregate-nfr.md +27 -10
- package/templates/bmad/tea/workflows/testarch/nfr-assess/validation-report-20260127-095021.md +1 -1
- package/templates/bmad/tea/workflows/testarch/nfr-assess/validation-report-20260127-102401.md +3 -3
- package/templates/bmad/tea/workflows/testarch/nfr-assess/workflow.yaml +2 -2
- package/templates/bmad/tea/workflows/testarch/teach-me-testing/data/tea-resources-index.yaml +3 -3
- package/templates/bmad/tea/workflows/testarch/teach-me-testing/workflow-plan-teach-me-testing.md +6 -6
- package/templates/bmad/tea/workflows/testarch/teach-me-testing/workflow.md +1 -1
- package/templates/bmad/tea/workflows/testarch/test-design/steps-c/step-02-load-context.md +30 -0
- package/templates/bmad/tea/workflows/testarch/test-design/steps-c/step-05-generate-output.md +72 -1
- package/templates/bmad/tea/workflows/testarch/test-design/validation-report-20260127-095021.md +1 -1
- package/templates/bmad/tea/workflows/testarch/test-design/validation-report-20260127-102401.md +3 -3
- package/templates/bmad/tea/workflows/testarch/test-design/workflow.yaml +2 -2
- package/templates/bmad/tea/workflows/testarch/test-review/steps-c/step-01-load-context.md +29 -1
- package/templates/bmad/tea/workflows/testarch/test-review/steps-c/step-03-quality-evaluation.md +147 -46
- package/templates/bmad/tea/workflows/testarch/test-review/steps-c/step-03a-subagent-determinism.md +214 -0
- package/templates/bmad/tea/workflows/testarch/test-review/steps-c/step-03b-subagent-isolation.md +125 -0
- package/templates/bmad/tea/workflows/testarch/test-review/steps-c/step-03c-subagent-maintainability.md +102 -0
- package/templates/bmad/tea/workflows/testarch/test-review/steps-c/step-03e-subagent-performance.md +117 -0
- package/templates/bmad/tea/workflows/testarch/test-review/steps-c/step-03f-aggregate-scores.md +10 -10
- package/templates/bmad/tea/workflows/testarch/test-review/validation-report-20260127-095021.md +1 -1
- package/templates/bmad/tea/workflows/testarch/test-review/validation-report-20260127-102401.md +3 -3
- package/templates/bmad/tea/workflows/testarch/test-review/workflow.yaml +2 -2
- package/templates/bmad/tea/workflows/testarch/trace/steps-c/step-04-analyze-gaps.md +92 -1
- package/templates/bmad/tea/workflows/testarch/trace/validation-report-20260127-095021.md +1 -1
- package/templates/bmad/tea/workflows/testarch/trace/validation-report-20260127-102401.md +3 -3
- package/templates/bmad/tea/workflows/testarch/trace/workflow.yaml +2 -2
- package/templates/ecc/agents/chief-of-staff.md +151 -0
- package/templates/ecc/commands/claw.md +79 -0
- package/templates/ecc/rules/README.md +23 -2
- package/templates/ecc/rules/common/development-workflow.md +37 -0
- package/templates/ecc/rules/common/git-workflow.md +2 -23
- package/templates/ecc/rules/swift/coding-style.md +47 -0
- package/templates/ecc/rules/swift/hooks.md +20 -0
- package/templates/ecc/rules/swift/patterns.md +66 -0
- package/templates/ecc/rules/swift/security.md +33 -0
- package/templates/ecc/rules/swift/testing.md +45 -0
- package/templates/ecc/skills/api-design/SKILL.md +1 -0
- package/templates/ecc/skills/article-writing/SKILL.md +85 -0
- package/templates/ecc/skills/backend-patterns/SKILL.md +1 -0
- package/templates/ecc/skills/clickhouse-io/SKILL.md +1 -0
- package/templates/ecc/skills/coding-standards/SKILL.md +1 -0
- package/templates/ecc/skills/configure-ecc/SKILL.md +32 -4
- package/templates/ecc/skills/content-engine/SKILL.md +88 -0
- package/templates/ecc/skills/content-hash-cache-pattern/SKILL.md +1 -0
- package/templates/ecc/skills/continuous-learning/SKILL.md +2 -1
- package/templates/ecc/skills/continuous-learning-v2/SKILL.md +4 -1
- package/templates/ecc/skills/continuous-learning-v2/hooks/observe.sh +14 -7
- package/templates/ecc/skills/cost-aware-llm-pipeline/SKILL.md +1 -0
- package/templates/ecc/skills/cpp-coding-standards/SKILL.md +1 -0
- package/templates/ecc/skills/cpp-testing/SKILL.md +1 -0
- package/templates/ecc/skills/database-migrations/SKILL.md +1 -0
- package/templates/ecc/skills/deployment-patterns/SKILL.md +1 -0
- package/templates/ecc/skills/django-patterns/SKILL.md +1 -0
- package/templates/ecc/skills/django-security/SKILL.md +1 -0
- package/templates/ecc/skills/django-tdd/SKILL.md +1 -0
- package/templates/ecc/skills/django-verification/SKILL.md +1 -0
- package/templates/ecc/skills/docker-patterns/SKILL.md +1 -0
- package/templates/ecc/skills/e2e-testing/SKILL.md +1 -0
- package/templates/ecc/skills/eval-harness/SKILL.md +1 -0
- package/templates/ecc/skills/foundation-models-on-device/SKILL.md +243 -0
- package/templates/ecc/skills/frontend-patterns/SKILL.md +1 -0
- package/templates/ecc/skills/frontend-slides/SKILL.md +184 -0
- package/templates/ecc/skills/frontend-slides/STYLE_PRESETS.md +330 -0
- package/templates/ecc/skills/golang-patterns/SKILL.md +1 -0
- package/templates/ecc/skills/golang-testing/SKILL.md +1 -0
- package/templates/ecc/skills/investor-materials/SKILL.md +96 -0
- package/templates/ecc/skills/investor-outreach/SKILL.md +76 -0
- package/templates/ecc/skills/iterative-retrieval/SKILL.md +1 -0
- package/templates/ecc/skills/java-coding-standards/SKILL.md +1 -0
- package/templates/ecc/skills/jpa-patterns/SKILL.md +1 -0
- package/templates/ecc/skills/liquid-glass-design/SKILL.md +279 -0
- package/templates/ecc/skills/market-research/SKILL.md +75 -0
- package/templates/ecc/skills/nutrient-document-processing/SKILL.md +1 -1
- package/templates/ecc/skills/postgres-patterns/SKILL.md +1 -0
- package/templates/ecc/skills/project-guidelines-example/SKILL.md +1 -0
- package/templates/ecc/skills/python-patterns/SKILL.md +1 -0
- package/templates/ecc/skills/python-testing/SKILL.md +1 -0
- package/templates/ecc/skills/regex-vs-llm-structured-text/SKILL.md +1 -0
- package/templates/ecc/skills/search-first/SKILL.md +3 -1
- package/templates/ecc/skills/security-review/SKILL.md +1 -0
- package/templates/ecc/skills/security-scan/SKILL.md +1 -0
- package/templates/ecc/skills/skill-stocktake/SKILL.md +176 -0
- package/templates/ecc/skills/skill-stocktake/scripts/quick-diff.sh +87 -0
- package/templates/ecc/skills/skill-stocktake/scripts/save-results.sh +56 -0
- package/templates/ecc/skills/skill-stocktake/scripts/scan.sh +170 -0
- package/templates/ecc/skills/springboot-patterns/SKILL.md +1 -0
- package/templates/ecc/skills/springboot-security/SKILL.md +1 -0
- package/templates/ecc/skills/springboot-tdd/SKILL.md +1 -0
- package/templates/ecc/skills/springboot-verification/SKILL.md +1 -0
- package/templates/ecc/skills/strategic-compact/SKILL.md +1 -0
- package/templates/ecc/skills/swift-actor-persistence/SKILL.md +1 -0
- package/templates/ecc/skills/swift-concurrency-6-2/SKILL.md +216 -0
- package/templates/ecc/skills/swift-protocol-di-testing/SKILL.md +1 -0
- package/templates/ecc/skills/swiftui-patterns/SKILL.md +259 -0
- package/templates/ecc/skills/tdd-workflow/SKILL.md +1 -0
- package/templates/ecc/skills/verification-loop/SKILL.md +1 -0
- package/templates/ecc/skills/visa-doc-translate/README.md +86 -0
- package/templates/ecc/skills/visa-doc-translate/SKILL.md +117 -0
- package/templates/ext-skills/pinchtab/SKILL.md +89 -486
- package/templates/ext-skills/pinchtab/TRUST.md +69 -0
- package/templates/ext-skills/pinchtab/references/api.md +297 -0
- package/templates/ext-skills/pinchtab/references/env.md +45 -0
- package/templates/ext-skills/pinchtab/references/profiles.md +107 -0
- package/templates/plugins/claude-code-setup/.claude-plugin/plugin.json +9 -0
- package/templates/plugins/claude-code-setup/LICENSE +202 -0
- package/templates/plugins/claude-code-setup/README.md +29 -0
- package/templates/plugins/claude-code-setup/automation-recommender-example.png +0 -0
- package/templates/plugins/claude-code-setup/skills/claude-automation-recommender/SKILL.md +288 -0
- package/templates/plugins/claude-code-setup/skills/claude-automation-recommender/references/hooks-patterns.md +226 -0
- package/templates/plugins/claude-code-setup/skills/claude-automation-recommender/references/mcp-servers.md +263 -0
- package/templates/plugins/claude-code-setup/skills/claude-automation-recommender/references/plugins-reference.md +98 -0
- package/templates/plugins/claude-code-setup/skills/claude-automation-recommender/references/skills-reference.md +408 -0
- package/templates/plugins/claude-code-setup/skills/claude-automation-recommender/references/subagent-templates.md +181 -0
- package/templates/plugins/claude-md-management/.claude-plugin/plugin.json +9 -0
- package/templates/plugins/claude-md-management/LICENSE +202 -0
- package/templates/plugins/claude-md-management/README.md +40 -0
- package/templates/plugins/claude-md-management/claude-md-improver-example.png +0 -0
- package/templates/plugins/claude-md-management/commands/revise-claude-md.md +54 -0
- package/templates/plugins/claude-md-management/revise-claude-md-example.png +0 -0
- package/templates/plugins/claude-md-management/skills/claude-md-improver/SKILL.md +179 -0
- package/templates/plugins/claude-md-management/skills/claude-md-improver/references/quality-criteria.md +109 -0
- package/templates/plugins/claude-md-management/skills/claude-md-improver/references/templates.md +253 -0
- package/templates/plugins/claude-md-management/skills/claude-md-improver/references/update-guidelines.md +150 -0
- package/templates/plugins/code-simplifier/.claude-plugin/plugin.json +9 -0
- package/templates/plugins/code-simplifier/LICENSE +202 -0
- package/templates/plugins/code-simplifier/agents/code-simplifier.md +52 -0
- package/templates/plugins/commit-commands/.claude-plugin/plugin.json +9 -0
- package/templates/plugins/commit-commands/LICENSE +202 -0
- package/templates/plugins/commit-commands/README.md +225 -0
- package/templates/plugins/commit-commands/commands/clean_gone.md +53 -0
- package/templates/plugins/commit-commands/commands/commit-push-pr.md +20 -0
- package/templates/plugins/commit-commands/commands/commit.md +17 -0
- package/templates/trae-bmad/rules/bmad-bmm-check-implementation-readiness.md +2 -2
- package/templates/trae-bmad/rules/bmad-bmm-code-review.md +4 -4
- package/templates/trae-bmad/rules/bmad-bmm-correct-course.md +4 -4
- package/templates/trae-bmad/rules/bmad-bmm-create-architecture.md +2 -2
- package/templates/trae-bmad/rules/bmad-bmm-create-epics-and-stories.md +2 -2
- package/templates/trae-bmad/rules/bmad-bmm-create-prd.md +2 -2
- package/templates/trae-bmad/rules/bmad-bmm-create-product-brief.md +2 -2
- package/templates/trae-bmad/rules/bmad-bmm-create-story.md +4 -4
- package/templates/trae-bmad/rules/bmad-bmm-create-ux-design.md +2 -2
- package/templates/trae-bmad/rules/bmad-bmm-dev-story.md +4 -4
- package/templates/trae-bmad/rules/bmad-bmm-document-project.md +4 -4
- package/templates/trae-bmad/rules/bmad-bmm-domain-research.md +2 -2
- package/templates/trae-bmad/rules/bmad-bmm-edit-prd.md +2 -2
- package/templates/trae-bmad/rules/bmad-bmm-generate-project-context.md +2 -2
- package/templates/trae-bmad/rules/bmad-bmm-market-research.md +2 -2
- package/templates/trae-bmad/rules/bmad-bmm-qa-generate-e2e-tests.md +4 -4
- package/templates/trae-bmad/rules/bmad-bmm-quick-dev.md +2 -2
- package/templates/trae-bmad/rules/bmad-bmm-quick-spec.md +2 -2
- package/templates/trae-bmad/rules/bmad-bmm-retrospective.md +4 -4
- package/templates/trae-bmad/rules/bmad-bmm-sprint-planning.md +4 -4
- package/templates/trae-bmad/rules/bmad-bmm-sprint-status.md +4 -4
- package/templates/trae-bmad/rules/bmad-bmm-technical-research.md +2 -2
- package/templates/trae-bmad/rules/bmad-bmm-validate-prd.md +2 -2
- package/templates/trae-bmad/rules/bmad-brainstorming.md +2 -2
- package/templates/trae-bmad/rules/bmad-editorial-review-prose.md +1 -1
- package/templates/trae-bmad/rules/bmad-editorial-review-structure.md +1 -1
- package/templates/trae-bmad/rules/bmad-help.md +1 -1
- package/templates/trae-bmad/rules/bmad-index-docs.md +1 -1
- package/templates/trae-bmad/rules/bmad-party-mode.md +2 -2
- package/templates/trae-bmad/rules/bmad-review-adversarial-general.md +1 -1
- package/templates/trae-bmad/rules/bmad-review-edge-case-hunter.md +10 -0
- package/templates/trae-bmad/rules/bmad-shard-doc.md +1 -1
- package/templates/trae-bmad/rules/bmad-tea-teach-me-testing.md +2 -2
- package/templates/trae-bmad/rules/bmad-tea-testarch-atdd.md +4 -4
- package/templates/trae-bmad/rules/bmad-tea-testarch-automate.md +4 -4
- package/templates/trae-bmad/rules/bmad-tea-testarch-ci.md +4 -4
- package/templates/trae-bmad/rules/bmad-tea-testarch-framework.md +4 -4
- package/templates/trae-bmad/rules/bmad-tea-testarch-nfr.md +4 -4
- package/templates/trae-bmad/rules/bmad-tea-testarch-test-design.md +4 -4
- package/templates/trae-bmad/rules/bmad-tea-testarch-test-review.md +4 -4
- package/templates/trae-bmad/rules/bmad-tea-testarch-trace.md +4 -4
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
# Pact.js Utils Provider Verifier
|
|
2
|
+
|
|
3
|
+
## Principle
|
|
4
|
+
|
|
5
|
+
Use `buildVerifierOptions`, `buildMessageVerifierOptions`, `handlePactBrokerUrlAndSelectors`, and `getProviderVersionTags` from `@seontechnologies/pactjs-utils` to assemble complete provider verification configuration in a single call. These utilities handle local/remote flow detection, broker URL resolution, consumer version selector strategy, and CI-aware version tagging. The caller controls breaking change behavior via the required `includeMainAndDeployed` parameter.
|
|
6
|
+
|
|
7
|
+
## Rationale
|
|
8
|
+
|
|
9
|
+
### Problems with manual VerifierOptions
|
|
10
|
+
|
|
11
|
+
- **30+ lines of scattered config**: Assembling `VerifierOptions` manually requires broker URL, token, selectors, state handlers, request filters, version info, publish flags — all in one object
|
|
12
|
+
- **Environment variable logic**: Different env vars for local vs remote, CI vs local dev, breaking change vs normal flow
|
|
13
|
+
- **Consumer version selector complexity**: Choosing between `mainBranch`, `deployedOrReleased`, `matchingBranch`, and `includeMainAndDeployed` requires understanding Pact Broker semantics
|
|
14
|
+
- **Breaking change coordination**: When a provider intentionally breaks a contract, manual selector switching is error-prone
|
|
15
|
+
- **Cross-execution protection**: `PACT_PAYLOAD_URL` webhook payloads need special handling to verify only the triggering pact
|
|
16
|
+
|
|
17
|
+
### Solutions
|
|
18
|
+
|
|
19
|
+
- **`buildVerifierOptions`**: Single function that reads env vars, selects the right flow, and returns complete `VerifierOptions`
|
|
20
|
+
- **`buildMessageVerifierOptions`**: Same as above for message/Kafka provider verification
|
|
21
|
+
- **`handlePactBrokerUrlAndSelectors`**: Pure function for broker URL + selector resolution (used internally, also exported for advanced use)
|
|
22
|
+
- **`getProviderVersionTags`**: Extracts CI branch/tag info from environment for provider version tagging
|
|
23
|
+
|
|
24
|
+
## Pattern Examples
|
|
25
|
+
|
|
26
|
+
### Example 1: HTTP Provider Verification (Remote Flow)
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { Verifier } from '@pact-foundation/pact';
|
|
30
|
+
import { buildVerifierOptions, createRequestFilter } from '@seontechnologies/pactjs-utils';
|
|
31
|
+
import type { StateHandlers } from '@seontechnologies/pactjs-utils';
|
|
32
|
+
|
|
33
|
+
const stateHandlers: StateHandlers = {
|
|
34
|
+
'movie with id 1 exists': {
|
|
35
|
+
setup: async (params) => {
|
|
36
|
+
await db.seed({ movies: [{ id: params?.id ?? 1, name: 'Inception' }] });
|
|
37
|
+
},
|
|
38
|
+
teardown: async () => {
|
|
39
|
+
await db.clean('movies');
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
'no movies exist': async () => {
|
|
43
|
+
await db.clean('movies');
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// buildVerifierOptions reads these env vars automatically:
|
|
48
|
+
// - PACT_BROKER_BASE_URL (broker URL)
|
|
49
|
+
// - PACT_BROKER_TOKEN (broker auth)
|
|
50
|
+
// - PACT_PAYLOAD_URL (webhook trigger — cross-execution protection)
|
|
51
|
+
// - PACT_BREAKING_CHANGE (if "true", uses includeMainAndDeployed selectors)
|
|
52
|
+
// - GITHUB_SHA (provider version)
|
|
53
|
+
// - CI (publish verification results if "true")
|
|
54
|
+
|
|
55
|
+
const opts = buildVerifierOptions({
|
|
56
|
+
provider: 'SampleMoviesAPI',
|
|
57
|
+
port: '3001',
|
|
58
|
+
includeMainAndDeployed: process.env.PACT_BREAKING_CHANGE !== 'true',
|
|
59
|
+
stateHandlers,
|
|
60
|
+
requestFilter: createRequestFilter({
|
|
61
|
+
tokenGenerator: () => process.env.TEST_AUTH_TOKEN ?? 'test-token',
|
|
62
|
+
}),
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
await new Verifier(opts).verifyProvider();
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Key Points**:
|
|
69
|
+
|
|
70
|
+
- Set `PACT_BROKER_BASE_URL` and `PACT_BROKER_TOKEN` as env vars — `buildVerifierOptions` reads them automatically
|
|
71
|
+
- `port` is a string (e.g., `'3001'`) — the function builds `providerBaseUrl: http://localhost:${port}` internally
|
|
72
|
+
- `includeMainAndDeployed` is **required** — set `true` for normal flow, `false` for breaking changes
|
|
73
|
+
- State handlers support both simple functions and `{ setup, teardown }` objects
|
|
74
|
+
- `params` in state handlers correspond to the `JsonMap` from consumer's `createProviderState`
|
|
75
|
+
- Verification results are published by default (`publishVerificationResult` defaults to `true`)
|
|
76
|
+
|
|
77
|
+
### Example 2: Local Flow (Monorepo, No Broker)
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import { Verifier } from '@pact-foundation/pact';
|
|
81
|
+
import { buildVerifierOptions } from '@seontechnologies/pactjs-utils';
|
|
82
|
+
|
|
83
|
+
// When PACT_BROKER_BASE_URL is NOT set, buildVerifierOptions
|
|
84
|
+
// falls back to local pact file verification
|
|
85
|
+
const opts = buildVerifierOptions({
|
|
86
|
+
provider: 'SampleMoviesAPI',
|
|
87
|
+
port: '3001',
|
|
88
|
+
includeMainAndDeployed: true,
|
|
89
|
+
// Specify local pact files directly — skips broker entirely
|
|
90
|
+
pactUrls: ['./pacts/movie-web-SampleMoviesAPI.json'],
|
|
91
|
+
stateHandlers: {
|
|
92
|
+
'movie exists': async (params) => {
|
|
93
|
+
await db.seed({ movies: [{ id: params?.id }] });
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
await new Verifier(opts).verifyProvider();
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Example 3: Message Provider Verification (Kafka/Async)
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { Verifier } from '@pact-foundation/pact';
|
|
105
|
+
import { buildMessageVerifierOptions } from '@seontechnologies/pactjs-utils';
|
|
106
|
+
|
|
107
|
+
const opts = buildMessageVerifierOptions({
|
|
108
|
+
provider: 'OrderEventsProducer',
|
|
109
|
+
includeMainAndDeployed: process.env.PACT_BREAKING_CHANGE !== 'true',
|
|
110
|
+
// Message handlers return the message content that the provider would produce
|
|
111
|
+
messageProviders: {
|
|
112
|
+
'an order created event': async () => ({
|
|
113
|
+
orderId: 'order-123',
|
|
114
|
+
userId: 'user-456',
|
|
115
|
+
items: [{ productId: 'prod-789', quantity: 2 }],
|
|
116
|
+
createdAt: new Date().toISOString(),
|
|
117
|
+
}),
|
|
118
|
+
'an order cancelled event': async () => ({
|
|
119
|
+
orderId: 'order-123',
|
|
120
|
+
reason: 'customer_request',
|
|
121
|
+
cancelledAt: new Date().toISOString(),
|
|
122
|
+
}),
|
|
123
|
+
},
|
|
124
|
+
stateHandlers: {
|
|
125
|
+
'order exists': async (params) => {
|
|
126
|
+
await db.seed({ orders: [{ id: params?.orderId }] });
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
await new Verifier(opts).verifyProvider();
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Key Points**:
|
|
135
|
+
|
|
136
|
+
- `buildMessageVerifierOptions` adds `messageProviders` to the verifier config
|
|
137
|
+
- Each message provider function returns the expected message payload
|
|
138
|
+
- State handlers work the same as HTTP verification
|
|
139
|
+
- Broker integration works identically (same env vars)
|
|
140
|
+
|
|
141
|
+
### Example 4: Breaking Change Coordination
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
// When a provider intentionally introduces a breaking change:
|
|
145
|
+
//
|
|
146
|
+
// 1. Set PACT_BREAKING_CHANGE=true in CI environment
|
|
147
|
+
// 2. Your test reads the env var and passes includeMainAndDeployed: false
|
|
148
|
+
// to buildVerifierOptions — this verifies ONLY against the matching
|
|
149
|
+
// branch, skipping main/deployed consumers that would fail
|
|
150
|
+
// 3. Coordinate with consumer team to update their pact on a matching branch
|
|
151
|
+
// 4. Remove PACT_BREAKING_CHANGE flag after consumer updates
|
|
152
|
+
|
|
153
|
+
// In CI environment (.github/workflows/provider-verify.yml):
|
|
154
|
+
// env:
|
|
155
|
+
// PACT_BREAKING_CHANGE: 'true'
|
|
156
|
+
|
|
157
|
+
// Your provider test code reads the env var:
|
|
158
|
+
const isBreakingChange = process.env.PACT_BREAKING_CHANGE === 'true';
|
|
159
|
+
|
|
160
|
+
const opts = buildVerifierOptions({
|
|
161
|
+
provider: 'SampleMoviesAPI',
|
|
162
|
+
port: '3001',
|
|
163
|
+
includeMainAndDeployed: !isBreakingChange, // false during breaking changes
|
|
164
|
+
stateHandlers: {
|
|
165
|
+
/* ... */
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
// When includeMainAndDeployed is false (breaking change):
|
|
169
|
+
// selectors = [{ matchingBranch: true }]
|
|
170
|
+
// When includeMainAndDeployed is true (normal):
|
|
171
|
+
// selectors = [{ matchingBranch: true }, { mainBranch: true }, { deployedOrReleased: true }]
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Example 5: handlePactBrokerUrlAndSelectors (Advanced)
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { handlePactBrokerUrlAndSelectors } from '@seontechnologies/pactjs-utils';
|
|
178
|
+
import type { VerifierOptions } from '@pact-foundation/pact';
|
|
179
|
+
|
|
180
|
+
// For advanced use cases — mutates the options object in-place (returns void)
|
|
181
|
+
const options: VerifierOptions = {
|
|
182
|
+
provider: 'SampleMoviesAPI',
|
|
183
|
+
providerBaseUrl: 'http://localhost:3001',
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
handlePactBrokerUrlAndSelectors({
|
|
187
|
+
pactPayloadUrl: process.env.PACT_PAYLOAD_URL,
|
|
188
|
+
pactBrokerUrl: process.env.PACT_BROKER_BASE_URL,
|
|
189
|
+
consumer: undefined, // or specific consumer name
|
|
190
|
+
includeMainAndDeployed: true,
|
|
191
|
+
options, // mutated in-place: sets pactBrokerUrl, consumerVersionSelectors, or pactUrls
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// After call, options has been mutated with:
|
|
195
|
+
// - options.pactBrokerUrl (from pactBrokerUrl param)
|
|
196
|
+
// - options.consumerVersionSelectors (based on includeMainAndDeployed)
|
|
197
|
+
// OR if pactPayloadUrl matches: options.pactUrls = [pactPayloadUrl]
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Note**: `handlePactBrokerUrlAndSelectors` is called internally by `buildVerifierOptions`. You rarely need it directly — use it only for advanced custom verifier assembly.
|
|
201
|
+
|
|
202
|
+
### Example 6: getProviderVersionTags
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
import { getProviderVersionTags } from '@seontechnologies/pactjs-utils';
|
|
206
|
+
|
|
207
|
+
// Extracts version tags from CI environment
|
|
208
|
+
const tags = getProviderVersionTags();
|
|
209
|
+
|
|
210
|
+
// In GitHub Actions on branch "feature/add-movies" (non-breaking):
|
|
211
|
+
// tags = ['dev', 'feature/add-movies']
|
|
212
|
+
//
|
|
213
|
+
// In GitHub Actions on main branch (non-breaking):
|
|
214
|
+
// tags = ['dev', 'main']
|
|
215
|
+
//
|
|
216
|
+
// In GitHub Actions with PACT_BREAKING_CHANGE=true:
|
|
217
|
+
// tags = ['feature/add-movies'] (no 'dev' tag)
|
|
218
|
+
//
|
|
219
|
+
// Locally (no CI):
|
|
220
|
+
// tags = ['local']
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Environment Variables Reference
|
|
224
|
+
|
|
225
|
+
| Variable | Required | Description | Default |
|
|
226
|
+
| ---------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
|
|
227
|
+
| `PACT_BROKER_BASE_URL` | For remote flow | Pact Broker / PactFlow URL | — |
|
|
228
|
+
| `PACT_BROKER_TOKEN` | For remote flow | API token for broker authentication | — |
|
|
229
|
+
| `GITHUB_SHA` | Recommended | Provider version for verification result publishing (auto-set by GitHub Actions) | `'unknown'` |
|
|
230
|
+
| `GITHUB_BRANCH` | Recommended | Branch name for provider version branch and version tags (**not auto-set** — define as `${{ github.head_ref \|\| github.ref_name }}`) | `'main'` |
|
|
231
|
+
| `PACT_PAYLOAD_URL` | Optional | Webhook payload URL — triggers verification of specific pact only | — |
|
|
232
|
+
| `PACT_BREAKING_CHANGE` | Optional | Set to `"true"` to use breaking change selector strategy | `'false'` |
|
|
233
|
+
| `CI` | Auto-detected | When `"true"`, enables verification result publishing | — |
|
|
234
|
+
|
|
235
|
+
## Key Points
|
|
236
|
+
|
|
237
|
+
- **Flow auto-detection**: If `PACT_BROKER_BASE_URL` is set → remote flow; otherwise → local flow (requires `pactUrls`)
|
|
238
|
+
- **`port` is a string**: Pass port number as string (e.g., `'3001'`); function builds `http://localhost:${port}` internally
|
|
239
|
+
- **`includeMainAndDeployed` is required**: `true` = verify matchingBranch + mainBranch + deployedOrReleased; `false` = verify matchingBranch only (for breaking changes)
|
|
240
|
+
- **Selector strategy**: Normal flow (`includeMainAndDeployed: true`) includes all selectors; breaking change flow (`false`) includes only `matchingBranch`
|
|
241
|
+
- **Webhook support**: `PACT_PAYLOAD_URL` takes precedence — verifies only the specific pact that triggered the webhook
|
|
242
|
+
- **State handler types**: Both `async (params) => void` and `{ setup: async (params) => void, teardown: async () => void }` are supported
|
|
243
|
+
- **Version publishing**: Verification results are published by default (`publishVerificationResult` defaults to `true`)
|
|
244
|
+
|
|
245
|
+
## Related Fragments
|
|
246
|
+
|
|
247
|
+
- `pactjs-utils-overview.md` — installation, decision tree, design philosophy
|
|
248
|
+
- `pactjs-utils-consumer-helpers.md` — consumer-side state parameter creation
|
|
249
|
+
- `pactjs-utils-request-filter.md` — auth injection for provider verification
|
|
250
|
+
- `contract-testing.md` — foundational patterns with raw Pact.js
|
|
251
|
+
|
|
252
|
+
## Anti-Patterns
|
|
253
|
+
|
|
254
|
+
### Wrong: Manual broker URL and selector assembly
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
// ❌ Manual environment variable handling
|
|
258
|
+
const opts: VerifierOptions = {
|
|
259
|
+
provider: 'my-api',
|
|
260
|
+
providerBaseUrl: 'http://localhost:3001',
|
|
261
|
+
pactBrokerUrl: process.env.PACT_BROKER_BASE_URL,
|
|
262
|
+
pactBrokerToken: process.env.PACT_BROKER_TOKEN,
|
|
263
|
+
publishVerificationResult: process.env.CI === 'true',
|
|
264
|
+
providerVersion: process.env.GIT_SHA || process.env.GITHUB_SHA || 'dev',
|
|
265
|
+
providerVersionBranch: process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME,
|
|
266
|
+
consumerVersionSelectors:
|
|
267
|
+
process.env.PACT_BREAKING_CHANGE === 'true'
|
|
268
|
+
? [{ matchingBranch: true }]
|
|
269
|
+
: [{ matchingBranch: true }, { mainBranch: true }, { deployedOrReleased: true }],
|
|
270
|
+
pactUrls: process.env.PACT_PAYLOAD_URL ? [process.env.PACT_PAYLOAD_URL] : undefined,
|
|
271
|
+
stateHandlers: {
|
|
272
|
+
/* ... */
|
|
273
|
+
},
|
|
274
|
+
requestFilter: (req, res, next) => {
|
|
275
|
+
req.headers['authorization'] = `Bearer ${process.env.TEST_TOKEN}`;
|
|
276
|
+
next();
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Right: Use buildVerifierOptions
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
// ✅ All env var logic handled internally
|
|
285
|
+
const opts = buildVerifierOptions({
|
|
286
|
+
provider: 'my-api',
|
|
287
|
+
port: '3001',
|
|
288
|
+
includeMainAndDeployed: process.env.PACT_BREAKING_CHANGE !== 'true',
|
|
289
|
+
stateHandlers: {
|
|
290
|
+
/* ... */
|
|
291
|
+
},
|
|
292
|
+
requestFilter: createRequestFilter({
|
|
293
|
+
tokenGenerator: () => process.env.TEST_TOKEN ?? 'test-token',
|
|
294
|
+
}),
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Wrong: Hardcoding consumer version selectors
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
// ❌ Hardcoded selectors — breaks when flow changes
|
|
302
|
+
consumerVersionSelectors: [{ mainBranch: true }, { deployedOrReleased: true }],
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Right: Let buildVerifierOptions choose selectors
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
// ✅ Selector strategy adapts to PACT_BREAKING_CHANGE env var
|
|
309
|
+
const opts = buildVerifierOptions({
|
|
310
|
+
/* ... */
|
|
311
|
+
});
|
|
312
|
+
// Selectors chosen automatically based on environment
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
_Source: @seontechnologies/pactjs-utils provider-verifier module, pact-js-example-provider CI workflows_
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Pact.js Utils Request Filter
|
|
2
|
+
|
|
3
|
+
## Principle
|
|
4
|
+
|
|
5
|
+
Use `createRequestFilter` and `noOpRequestFilter` from `@seontechnologies/pactjs-utils` to inject authentication headers during provider verification. The pluggable token generator pattern prevents double-Bearer bugs and separates auth concerns from verification logic.
|
|
6
|
+
|
|
7
|
+
## Rationale
|
|
8
|
+
|
|
9
|
+
### Problems with manual request filters
|
|
10
|
+
|
|
11
|
+
- **Express type gymnastics**: Pact's `requestFilter` expects `(req, res, next) => void` with Express-compatible types — but Pact doesn't re-export these types
|
|
12
|
+
- **Double-Bearer bug**: Easy to write `Authorization: Bearer Bearer ${token}` when the token generator already includes the prefix
|
|
13
|
+
- **Inline complexity**: Auth logic mixed with verifier config makes tests harder to read
|
|
14
|
+
- **No-op boilerplate**: Providers without auth still need a pass-through function or `undefined`
|
|
15
|
+
|
|
16
|
+
### Solutions
|
|
17
|
+
|
|
18
|
+
- **`createRequestFilter`**: Accepts `{ tokenGenerator: () => string }` — generator returns raw token value synchronously, filter adds `Bearer ` prefix
|
|
19
|
+
- **`noOpRequestFilter`**: Pre-built pass-through for providers without auth requirements
|
|
20
|
+
- **Bearer prefix contract**: `tokenGenerator` returns raw value (e.g., `"abc123"`), filter always adds `"Bearer "` — impossible to double-prefix
|
|
21
|
+
|
|
22
|
+
## Pattern Examples
|
|
23
|
+
|
|
24
|
+
### Example 1: Basic Auth Injection
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { buildVerifierOptions, createRequestFilter } from '@seontechnologies/pactjs-utils';
|
|
28
|
+
|
|
29
|
+
const opts = buildVerifierOptions({
|
|
30
|
+
provider: 'SampleMoviesAPI',
|
|
31
|
+
port: '3001',
|
|
32
|
+
includeMainAndDeployed: true,
|
|
33
|
+
stateHandlers: {
|
|
34
|
+
/* ... */
|
|
35
|
+
},
|
|
36
|
+
requestFilter: createRequestFilter({
|
|
37
|
+
// tokenGenerator returns raw token — filter adds "Bearer " prefix
|
|
38
|
+
tokenGenerator: () => 'test-auth-token-123',
|
|
39
|
+
}),
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Every request during verification will have:
|
|
43
|
+
// Authorization: Bearer test-auth-token-123
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Key Points**:
|
|
47
|
+
|
|
48
|
+
- `tokenGenerator` is **synchronous** (`() => string`) — if you need async token fetching, resolve the token before creating the filter
|
|
49
|
+
- Return the raw token value, NOT `"Bearer ..."` — the filter adds the prefix
|
|
50
|
+
- Filter sets `Authorization` header on every request during verification
|
|
51
|
+
|
|
52
|
+
### Example 2: Dynamic Token (Pre-resolved)
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { createRequestFilter } from '@seontechnologies/pactjs-utils';
|
|
56
|
+
|
|
57
|
+
// Since tokenGenerator is synchronous, fetch the token before creating the filter
|
|
58
|
+
let cachedToken: string;
|
|
59
|
+
|
|
60
|
+
async function setupRequestFilter() {
|
|
61
|
+
const response = await fetch('http://localhost:8080/auth/token', {
|
|
62
|
+
method: 'POST',
|
|
63
|
+
headers: { 'Content-Type': 'application/json' },
|
|
64
|
+
body: JSON.stringify({
|
|
65
|
+
clientId: process.env.TEST_CLIENT_ID,
|
|
66
|
+
clientSecret: process.env.TEST_CLIENT_SECRET,
|
|
67
|
+
}),
|
|
68
|
+
});
|
|
69
|
+
const { access_token } = await response.json();
|
|
70
|
+
cachedToken = access_token;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const requestFilter = createRequestFilter({
|
|
74
|
+
tokenGenerator: () => cachedToken, // Synchronous — returns pre-fetched token
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const opts = buildVerifierOptions({
|
|
78
|
+
provider: 'SecureAPI',
|
|
79
|
+
port: '3001',
|
|
80
|
+
includeMainAndDeployed: true,
|
|
81
|
+
stateHandlers: {
|
|
82
|
+
/* ... */
|
|
83
|
+
},
|
|
84
|
+
requestFilter,
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Example 3: No-Auth Provider
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { buildVerifierOptions, noOpRequestFilter } from '@seontechnologies/pactjs-utils';
|
|
92
|
+
|
|
93
|
+
// For providers that don't require authentication
|
|
94
|
+
const opts = buildVerifierOptions({
|
|
95
|
+
provider: 'PublicAPI',
|
|
96
|
+
port: '3001',
|
|
97
|
+
includeMainAndDeployed: true,
|
|
98
|
+
stateHandlers: {
|
|
99
|
+
/* ... */
|
|
100
|
+
},
|
|
101
|
+
requestFilter: noOpRequestFilter,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// noOpRequestFilter is equivalent to: (req, res, next) => next()
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Example 4: Integration with buildVerifierOptions
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import { buildVerifierOptions, createRequestFilter } from '@seontechnologies/pactjs-utils';
|
|
111
|
+
import type { StateHandlers } from '@seontechnologies/pactjs-utils';
|
|
112
|
+
|
|
113
|
+
// Complete provider verification setup
|
|
114
|
+
const stateHandlers: StateHandlers = {
|
|
115
|
+
'user is authenticated': async () => {
|
|
116
|
+
// Auth state is handled by the request filter, not state handler
|
|
117
|
+
},
|
|
118
|
+
'movie exists': {
|
|
119
|
+
setup: async (params) => {
|
|
120
|
+
await db.seed({ movies: [{ id: params?.id }] });
|
|
121
|
+
},
|
|
122
|
+
teardown: async () => {
|
|
123
|
+
await db.clean('movies');
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const requestFilter = createRequestFilter({
|
|
129
|
+
tokenGenerator: () => process.env.TEST_AUTH_TOKEN ?? 'fallback-token',
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const opts = buildVerifierOptions({
|
|
133
|
+
provider: 'SampleMoviesAPI',
|
|
134
|
+
port: process.env.PORT ?? '3001',
|
|
135
|
+
includeMainAndDeployed: process.env.PACT_BREAKING_CHANGE !== 'true',
|
|
136
|
+
stateHandlers,
|
|
137
|
+
requestFilter,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Run verification
|
|
141
|
+
await new Verifier(opts).verifyProvider();
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Key Points
|
|
145
|
+
|
|
146
|
+
- **Bearer prefix contract**: `tokenGenerator` returns raw value → filter adds `"Bearer "` → impossible to double-prefix
|
|
147
|
+
- **Synchronous only**: `tokenGenerator` must return `string` (not `Promise<string>`) — pre-resolve async tokens before creating the filter
|
|
148
|
+
- **Separation of concerns**: Auth logic in `createRequestFilter`, verification logic in `buildVerifierOptions`
|
|
149
|
+
- **noOpRequestFilter**: Use for providers without auth — cleaner than `undefined` or inline no-op
|
|
150
|
+
- **Express compatible**: The returned filter matches Pact's expected `(req, res, next) => void` signature
|
|
151
|
+
|
|
152
|
+
## Related Fragments
|
|
153
|
+
|
|
154
|
+
- `pactjs-utils-overview.md` — installation, utility table, decision tree
|
|
155
|
+
- `pactjs-utils-provider-verifier.md` — buildVerifierOptions integration
|
|
156
|
+
- `contract-testing.md` — foundational patterns with raw Pact.js
|
|
157
|
+
|
|
158
|
+
## Anti-Patterns
|
|
159
|
+
|
|
160
|
+
### Wrong: Manual Bearer prefix with double-prefix risk
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
// ❌ Risk of double-prefix: "Bearer Bearer token"
|
|
164
|
+
requestFilter: (req, res, next) => {
|
|
165
|
+
const token = getToken(); // What if getToken() returns "Bearer abc123"?
|
|
166
|
+
req.headers['authorization'] = `Bearer ${token}`;
|
|
167
|
+
next();
|
|
168
|
+
};
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Right: Use createRequestFilter with raw token
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
// ✅ tokenGenerator returns raw value — filter handles prefix
|
|
175
|
+
requestFilter: createRequestFilter({
|
|
176
|
+
tokenGenerator: () => getToken(), // Returns "abc123", not "Bearer abc123"
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Wrong: Inline auth logic in verifier config
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
// ❌ Auth logic mixed with verifier config
|
|
184
|
+
const opts: VerifierOptions = {
|
|
185
|
+
provider: 'my-api',
|
|
186
|
+
providerBaseUrl: 'http://localhost:3001',
|
|
187
|
+
requestFilter: (req, res, next) => {
|
|
188
|
+
const clientId = process.env.CLIENT_ID;
|
|
189
|
+
const clientSecret = process.env.CLIENT_SECRET;
|
|
190
|
+
// 10 lines of token fetching logic...
|
|
191
|
+
req.headers['authorization'] = `Bearer ${token}`;
|
|
192
|
+
next();
|
|
193
|
+
},
|
|
194
|
+
// ... rest of config
|
|
195
|
+
};
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Right: Separate auth into createRequestFilter
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
// ✅ Clean separation — async setup wraps token fetch (CommonJS-safe)
|
|
202
|
+
async function setupVerifierOptions() {
|
|
203
|
+
const token = await fetchAuthToken(); // Resolve async token BEFORE creating filter
|
|
204
|
+
|
|
205
|
+
const requestFilter = createRequestFilter({
|
|
206
|
+
tokenGenerator: () => token, // Synchronous — returns pre-fetched value
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
return buildVerifierOptions({
|
|
210
|
+
provider: 'my-api',
|
|
211
|
+
port: '3001',
|
|
212
|
+
includeMainAndDeployed: true,
|
|
213
|
+
requestFilter,
|
|
214
|
+
stateHandlers: {
|
|
215
|
+
/* ... */
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// In tests/hooks, callers can await setupVerifierOptions():
|
|
221
|
+
// const opts = await setupVerifierOptions();
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
_Source: @seontechnologies/pactjs-utils request-filter module, pact-js-example-provider verification tests_
|
|
@@ -32,5 +32,10 @@ burn-in,Burn-in Runner,"Smart test selection, git diff for CI optimization","ci,
|
|
|
32
32
|
network-error-monitor,Network Error Monitor,"HTTP 4xx/5xx detection for UI tests","monitoring,playwright-utils,ui",extended,knowledge/network-error-monitor.md
|
|
33
33
|
fixtures-composition,Fixtures Composition,"mergeTests composition patterns for combining utilities","fixtures,playwright-utils",extended,knowledge/fixtures-composition.md
|
|
34
34
|
api-testing-patterns,API Testing Patterns,"Pure API test patterns without browser: service testing, microservices, GraphQL","api,backend,service-testing,api-testing,microservices,graphql,no-browser",specialized,knowledge/api-testing-patterns.md
|
|
35
|
+
pactjs-utils-overview,Pact.js Utils Overview,"Installation, contract testing flows, utility table","pactjs-utils,contract-testing,pact,api,backend,microservices",specialized,knowledge/pactjs-utils-overview.md
|
|
36
|
+
pactjs-utils-consumer-helpers,Pact.js Utils Consumer Helpers,"createProviderState, toJsonMap for type-safe provider states","pactjs-utils,consumer,contract-testing,pact,api",specialized,knowledge/pactjs-utils-consumer-helpers.md
|
|
37
|
+
pactjs-utils-provider-verifier,Pact.js Utils Provider Verifier,"buildVerifierOptions, buildMessageVerifierOptions for provider verification","pactjs-utils,provider,contract-testing,pact,api,backend,ci",specialized,knowledge/pactjs-utils-provider-verifier.md
|
|
38
|
+
pactjs-utils-request-filter,Pact.js Utils Request Filter,"createRequestFilter, noOpRequestFilter for auth injection","pactjs-utils,auth,contract-testing,pact",specialized,knowledge/pactjs-utils-request-filter.md
|
|
39
|
+
pact-mcp,Pact MCP Server,"SmartBear MCP for PactFlow: generate tests, review, can-i-deploy, provider states","pact,mcp,pactflow,contract-testing,broker",specialized,knowledge/pact-mcp.md
|
|
35
40
|
adr-quality-readiness-checklist,ADR Quality Readiness Checklist,"8-category 29-criteria framework for ADR testability and NFR assessment","nfr,testability,adr,quality,assessment,checklist",extended,knowledge/adr-quality-readiness-checklist.md
|
|
36
41
|
playwright-cli,Playwright CLI,"Token-efficient CLI for AI coding agents: element refs, sessions, snapshots, browser automation","cli,browser,agent,automation,snapshot",core,knowledge/playwright-cli.md
|
|
@@ -54,7 +54,7 @@ This folder contains the Test Architect (TEA) workflows converted to step-file a
|
|
|
54
54
|
## References
|
|
55
55
|
|
|
56
56
|
- Step-file architecture: `docs/explanation/step-file-architecture.md`
|
|
57
|
-
-
|
|
57
|
+
- Subagent patterns: `docs/explanation/subagent-architecture.md`
|
|
58
58
|
|
|
59
59
|
## TEA Workflows
|
|
60
60
|
|
|
@@ -84,6 +84,8 @@ If any are missing: **HALT** and notify the user.
|
|
|
84
84
|
From `{config_source}`:
|
|
85
85
|
|
|
86
86
|
- `tea_use_playwright_utils`
|
|
87
|
+
- `tea_use_pactjs_utils`
|
|
88
|
+
- `tea_pact_mcp`
|
|
87
89
|
- `tea_browser_automation`
|
|
88
90
|
- `test_stack_type`
|
|
89
91
|
|
|
@@ -111,6 +113,22 @@ Load fragments based on their `tier` classification in `tea-index.csv`:
|
|
|
111
113
|
|
|
112
114
|
**Detection**: Scan `{test_dir}` for files containing `page.goto` or `page.locator`. If none found, use API-only profile.
|
|
113
115
|
|
|
116
|
+
### Pact.js Utils Loading
|
|
117
|
+
|
|
118
|
+
**If `tea_use_pactjs_utils` is enabled** (and `{detected_stack}` is `backend` or `fullstack`, or microservices indicators detected):
|
|
119
|
+
|
|
120
|
+
Load: `pactjs-utils-overview.md`, `pactjs-utils-consumer-helpers.md`, `pactjs-utils-provider-verifier.md`, `pactjs-utils-request-filter.md`
|
|
121
|
+
|
|
122
|
+
**If `tea_use_pactjs_utils` is disabled** but contract testing is relevant:
|
|
123
|
+
|
|
124
|
+
Load: `contract-testing.md`
|
|
125
|
+
|
|
126
|
+
### Pact MCP Loading
|
|
127
|
+
|
|
128
|
+
**If `tea_pact_mcp` is `"mcp"`:**
|
|
129
|
+
|
|
130
|
+
Load: `pact-mcp.md`
|
|
131
|
+
|
|
114
132
|
## 5. Load Knowledge Base Fragments
|
|
115
133
|
|
|
116
134
|
Use `{knowledgeIndex}` to load:
|
|
@@ -150,6 +168,18 @@ Use `{knowledgeIndex}` to load:
|
|
|
150
168
|
- `test-priorities-matrix.md`
|
|
151
169
|
- `ci-burn-in.md`
|
|
152
170
|
|
|
171
|
+
**Pact.js Utils (if enabled):**
|
|
172
|
+
|
|
173
|
+
- `pactjs-utils-overview.md`, `pactjs-utils-consumer-helpers.md`, `pactjs-utils-provider-verifier.md`, `pactjs-utils-request-filter.md`
|
|
174
|
+
|
|
175
|
+
**Contract Testing (if pactjs-utils disabled but relevant):**
|
|
176
|
+
|
|
177
|
+
- `contract-testing.md`
|
|
178
|
+
|
|
179
|
+
**Pact MCP (if tea_pact_mcp is "mcp"):**
|
|
180
|
+
|
|
181
|
+
- `pact-mcp.md`
|
|
182
|
+
|
|
153
183
|
---
|
|
154
184
|
|
|
155
185
|
## 6. Confirm Inputs
|