bmad-fh 6.0.0-alpha.052779ef
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.coderabbit.yaml +40 -0
- package/.githooks/post-checkout +129 -0
- package/.githooks/pre-commit +63 -0
- package/.githooks/pre-push +135 -0
- package/.github/CODE_OF_CONDUCT.md +128 -0
- package/.github/FUNDING.yaml +15 -0
- package/.github/ISSUE_TEMPLATE/config.yaml +8 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
- package/.github/ISSUE_TEMPLATE/issue.md +32 -0
- package/.github/scripts/discord-helpers.sh +34 -0
- package/.github/workflows/bundle-latest.yaml +330 -0
- package/.github/workflows/discord.yaml +90 -0
- package/.github/workflows/docs.yaml +63 -0
- package/.github/workflows/manual-release.yaml +190 -0
- package/.github/workflows/publish-multi-artifact.yaml +54 -0
- package/.github/workflows/quality.yaml +115 -0
- package/.husky/pre-commit +20 -0
- package/.markdownlint-cli2.yaml +41 -0
- package/.nvmrc +1 -0
- package/.prettierignore +9 -0
- package/.vscode/settings.json +97 -0
- package/CHANGELOG.md +1394 -0
- package/CNAME +1 -0
- package/CONTRIBUTING.md +306 -0
- package/CONTRIBUTORS.md +32 -0
- package/LICENSE +30 -0
- package/README.md +126 -0
- package/SECURITY.md +85 -0
- package/TRADEMARK.md +55 -0
- package/Wordmark.png +0 -0
- package/banner-bmad-method.png +0 -0
- package/docs/404.md +9 -0
- package/docs/_README_WORKFLOW_DIAGRAMS.md +40 -0
- package/docs/_STYLE_GUIDE.md +367 -0
- package/docs/_archive/customize-workflows.md +30 -0
- package/docs/_archive/getting-started-bmadv4.md +247 -0
- package/docs/_archive/vendor-workflows.md +52 -0
- package/docs/downloads.md +72 -0
- package/docs/explanation/agents/barry-quick-flow.md +328 -0
- package/docs/explanation/agents/index.md +19 -0
- package/docs/explanation/architecture/four-phases.md +107 -0
- package/docs/explanation/architecture/preventing-agent-conflicts.md +111 -0
- package/docs/explanation/architecture/why-solutioning-matters.md +75 -0
- package/docs/explanation/bmm/index.md +131 -0
- package/docs/explanation/core/index.md +18 -0
- package/docs/explanation/core-concepts/agent-roles.md +179 -0
- package/docs/explanation/core-concepts/index.md +35 -0
- package/docs/explanation/core-concepts/what-are-agents.md +97 -0
- package/docs/explanation/core-concepts/what-are-modules.md +85 -0
- package/docs/explanation/core-concepts/what-are-workflows.md +204 -0
- package/docs/explanation/faq/brownfield-faq.md +73 -0
- package/docs/explanation/faq/getting-started-faq.md +67 -0
- package/docs/explanation/faq/implementation-faq.md +52 -0
- package/docs/explanation/faq/index.md +16 -0
- package/docs/explanation/faq/levels-and-tracks-faq.md +52 -0
- package/docs/explanation/faq/planning-faq.md +41 -0
- package/docs/explanation/faq/tools-faq.md +277 -0
- package/docs/explanation/faq/workflows-faq.md +61 -0
- package/docs/explanation/features/advanced-elicitation.md +95 -0
- package/docs/explanation/features/brainstorming-techniques.md +92 -0
- package/docs/explanation/features/party-mode.md +95 -0
- package/docs/explanation/features/quick-flow.md +149 -0
- package/docs/explanation/features/tea-overview.md +410 -0
- package/docs/explanation/features/web-bundles.md +34 -0
- package/docs/explanation/philosophy/facilitation-over-generation.md +333 -0
- package/docs/explanation/philosophy/testing-as-engineering.md +112 -0
- package/docs/explanation/tea/engagement-models.md +710 -0
- package/docs/explanation/tea/fixture-architecture.md +457 -0
- package/docs/explanation/tea/knowledge-base-system.md +554 -0
- package/docs/explanation/tea/network-first-patterns.md +853 -0
- package/docs/explanation/tea/risk-based-testing.md +586 -0
- package/docs/explanation/tea/test-quality-standards.md +907 -0
- package/docs/how-to/brownfield/add-feature-to-existing.md +74 -0
- package/docs/how-to/brownfield/document-existing-project.md +66 -0
- package/docs/how-to/brownfield/index.md +84 -0
- package/docs/how-to/brownfield/quick-fix-in-brownfield.md +77 -0
- package/docs/how-to/brownfield/use-tea-for-enterprise.md +526 -0
- package/docs/how-to/brownfield/use-tea-with-existing-tests.md +577 -0
- package/docs/how-to/customization/customize-agents.md +212 -0
- package/docs/how-to/customization/enable-tea-mcp-enhancements.md +424 -0
- package/docs/how-to/customization/index.md +23 -0
- package/docs/how-to/customization/integrate-playwright-utils.md +813 -0
- package/docs/how-to/customization/shard-large-documents.md +101 -0
- package/docs/how-to/get-answers-about-bmad.md +102 -0
- package/docs/how-to/installation/index.md +12 -0
- package/docs/how-to/installation/install-bmad.md +111 -0
- package/docs/how-to/installation/install-custom-modules.md +118 -0
- package/docs/how-to/installation/upgrade-to-v6.md +131 -0
- package/docs/how-to/workflows/bmgd-quick-flow.md +156 -0
- package/docs/how-to/workflows/conduct-research.md +97 -0
- package/docs/how-to/workflows/create-architecture.md +119 -0
- package/docs/how-to/workflows/create-epics-and-stories.md +109 -0
- package/docs/how-to/workflows/create-prd.md +91 -0
- package/docs/how-to/workflows/create-product-brief.md +94 -0
- package/docs/how-to/workflows/create-story.md +102 -0
- package/docs/how-to/workflows/create-ux-design.md +100 -0
- package/docs/how-to/workflows/implement-story.md +97 -0
- package/docs/how-to/workflows/quick-spec.md +122 -0
- package/docs/how-to/workflows/run-atdd.md +436 -0
- package/docs/how-to/workflows/run-automate.md +653 -0
- package/docs/how-to/workflows/run-brainstorming-session.md +73 -0
- package/docs/how-to/workflows/run-code-review.md +89 -0
- package/docs/how-to/workflows/run-implementation-readiness.md +125 -0
- package/docs/how-to/workflows/run-nfr-assess.md +679 -0
- package/docs/how-to/workflows/run-sprint-planning.md +94 -0
- package/docs/how-to/workflows/run-test-design.md +98 -0
- package/docs/how-to/workflows/run-test-review.md +605 -0
- package/docs/how-to/workflows/run-trace.md +883 -0
- package/docs/how-to/workflows/setup-ci.md +712 -0
- package/docs/how-to/workflows/setup-party-mode.md +89 -0
- package/docs/how-to/workflows/setup-test-framework.md +98 -0
- package/docs/index.md +63 -0
- package/docs/migration-guide.md +365 -0
- package/docs/multi-scope-guide.md +379 -0
- package/docs/plans/multi-scope-parallel-artifacts-plan.md +695 -0
- package/docs/reference/agents/index.md +109 -0
- package/docs/reference/configuration/core-tasks.md +67 -0
- package/docs/reference/configuration/global-config.md +28 -0
- package/docs/reference/glossary/index.md +159 -0
- package/docs/reference/tea/commands.md +254 -0
- package/docs/reference/tea/configuration.md +678 -0
- package/docs/reference/tea/knowledge-base.md +340 -0
- package/docs/reference/workflows/core-workflows.md +32 -0
- package/docs/reference/workflows/document-project.md +73 -0
- package/docs/reference/workflows/index.md +12 -0
- package/docs/tutorials/getting-started/getting-started-bmadv6.md +246 -0
- package/docs/tutorials/getting-started/images/workflow-method-greenfield.excalidraw +5034 -0
- package/docs/tutorials/getting-started/images/workflow-method-greenfield.svg +4 -0
- package/docs/tutorials/getting-started/images/workflow-overview.jpg +0 -0
- package/docs/tutorials/getting-started/tea-lite-quickstart.md +444 -0
- package/docs/tutorials/getting-started/workflow-overview.jpg +0 -0
- package/eslint.config.mjs +152 -0
- package/package.json +117 -0
- package/prettier.config.mjs +32 -0
- package/src/bmm/_module-installer/installer.js +48 -0
- package/src/bmm/_module-installer/platform-specifics/claude-code.js +35 -0
- package/src/bmm/_module-installer/platform-specifics/windsurf.js +32 -0
- package/src/bmm/agents/analyst.agent.yaml +41 -0
- package/src/bmm/agents/architect.agent.yaml +33 -0
- package/src/bmm/agents/dev.agent.yaml +38 -0
- package/src/bmm/agents/pm.agent.yaml +51 -0
- package/src/bmm/agents/quick-flow-solo-dev.agent.yaml +32 -0
- package/src/bmm/agents/sm.agent.yaml +47 -0
- package/src/bmm/agents/tea.agent.yaml +68 -0
- package/src/bmm/agents/tech-writer/tech-writer-sidecar/documentation-standards.md +224 -0
- package/src/bmm/agents/tech-writer/tech-writer.agent.yaml +49 -0
- package/src/bmm/agents/ux-designer.agent.yaml +30 -0
- package/src/bmm/data/README.md +29 -0
- package/src/bmm/data/project-context-template.md +40 -0
- package/src/bmm/module.yaml +64 -0
- package/src/bmm/sub-modules/claude-code/config.yaml +4 -0
- package/src/bmm/sub-modules/claude-code/injections.yaml +242 -0
- package/src/bmm/sub-modules/claude-code/readme.md +87 -0
- package/src/bmm/teams/default-party.csv +21 -0
- package/src/bmm/teams/team-fullstack.yaml +12 -0
- package/src/bmm/testarch/knowledge/api-request.md +442 -0
- package/src/bmm/testarch/knowledge/api-testing-patterns.md +843 -0
- package/src/bmm/testarch/knowledge/auth-session.md +552 -0
- package/src/bmm/testarch/knowledge/burn-in.md +273 -0
- package/src/bmm/testarch/knowledge/ci-burn-in.md +675 -0
- package/src/bmm/testarch/knowledge/component-tdd.md +486 -0
- package/src/bmm/testarch/knowledge/contract-testing.md +957 -0
- package/src/bmm/testarch/knowledge/data-factories.md +500 -0
- package/src/bmm/testarch/knowledge/email-auth.md +721 -0
- package/src/bmm/testarch/knowledge/error-handling.md +725 -0
- package/src/bmm/testarch/knowledge/feature-flags.md +750 -0
- package/src/bmm/testarch/knowledge/file-utils.md +463 -0
- package/src/bmm/testarch/knowledge/fixture-architecture.md +401 -0
- package/src/bmm/testarch/knowledge/fixtures-composition.md +382 -0
- package/src/bmm/testarch/knowledge/intercept-network-call.md +430 -0
- package/src/bmm/testarch/knowledge/log.md +429 -0
- package/src/bmm/testarch/knowledge/network-error-monitor.md +405 -0
- package/src/bmm/testarch/knowledge/network-first.md +486 -0
- package/src/bmm/testarch/knowledge/network-recorder.md +527 -0
- package/src/bmm/testarch/knowledge/nfr-criteria.md +670 -0
- package/src/bmm/testarch/knowledge/overview.md +286 -0
- package/src/bmm/testarch/knowledge/playwright-config.md +730 -0
- package/src/bmm/testarch/knowledge/probability-impact.md +601 -0
- package/src/bmm/testarch/knowledge/recurse.md +421 -0
- package/src/bmm/testarch/knowledge/risk-governance.md +615 -0
- package/src/bmm/testarch/knowledge/selective-testing.md +732 -0
- package/src/bmm/testarch/knowledge/selector-resilience.md +527 -0
- package/src/bmm/testarch/knowledge/test-healing-patterns.md +644 -0
- package/src/bmm/testarch/knowledge/test-levels-framework.md +473 -0
- package/src/bmm/testarch/knowledge/test-priorities-matrix.md +373 -0
- package/src/bmm/testarch/knowledge/test-quality.md +664 -0
- package/src/bmm/testarch/knowledge/timing-debugging.md +372 -0
- package/src/bmm/testarch/knowledge/visual-debugging.md +524 -0
- package/src/bmm/testarch/tea-index.csv +34 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/product-brief.template.md +10 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +177 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +161 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +199 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +202 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +205 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +219 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +194 -0
- package/src/bmm/workflows/1-analysis/create-product-brief/workflow.md +58 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +137 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +229 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +238 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +206 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +234 -0
- package/src/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +443 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +182 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +237 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-02-customer-insights.md +200 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +249 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +259 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +177 -0
- package/src/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +475 -0
- package/src/bmm/workflows/1-analysis/research/research.template.md +29 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +137 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +239 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +248 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +202 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +239 -0
- package/src/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +486 -0
- package/src/bmm/workflows/1-analysis/research/workflow.md +173 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01-init.md +135 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +127 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +190 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +216 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +219 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +234 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +252 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +254 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +224 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +224 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +241 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +248 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +237 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +264 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +228 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +13 -0
- package/src/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +43 -0
- package/src/bmm/workflows/2-plan-workflows/prd/data/domain-complexity.csv +13 -0
- package/src/bmm/workflows/2-plan-workflows/prd/data/prd-purpose.md +197 -0
- package/src/bmm/workflows/2-plan-workflows/prd/data/project-types.csv +11 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-01-init.md +191 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-01b-continue.md +153 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-02-discovery.md +224 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-03-success.md +226 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-04-journeys.md +213 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-05-domain.md +207 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-06-innovation.md +226 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-07-project-type.md +237 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-08-scoping.md +228 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-09-functional.md +231 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-10-nonfunctional.md +242 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-11-polish.md +217 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-12-complete.md +180 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-01-discovery.md +247 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-01b-legacy-conversion.md +208 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-02-review.md +249 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-03-edit.md +253 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-04-complete.md +168 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-01-discovery.md +218 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-02-format-detection.md +191 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-02b-parity-check.md +209 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-03-density-validation.md +174 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-04-brief-coverage-validation.md +214 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-05-measurability-validation.md +228 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-06-traceability-validation.md +217 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-07-implementation-leakage-validation.md +205 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-08-domain-compliance-validation.md +243 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-09-project-type-validation.md +263 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-10-smart-validation.md +209 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-11-holistic-quality-validation.md +264 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-12-completeness-validation.md +242 -0
- package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-13-report-complete.md +232 -0
- package/src/bmm/workflows/2-plan-workflows/prd/templates/prd-template.md +10 -0
- package/src/bmm/workflows/2-plan-workflows/prd/validation-report-prd-workflow.md +433 -0
- package/src/bmm/workflows/2-plan-workflows/prd/workflow.md +150 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +190 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +178 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +179 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +139 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +252 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +133 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/templates/readiness-report-template.md +4 -0
- package/src/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +55 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/architecture-decision-template.md +12 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/data/domain-complexity.csv +11 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/data/project-types.csv +7 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01-init.md +153 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +164 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +224 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +331 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +318 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +359 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +379 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +359 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +352 -0
- package/src/bmm/workflows/3-solutioning/create-architecture/workflow.md +50 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +259 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +233 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +272 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +145 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -0
- package/src/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +59 -0
- package/src/bmm/workflows/4-implementation/code-review/checklist.md +23 -0
- package/src/bmm/workflows/4-implementation/code-review/instructions.xml +227 -0
- package/src/bmm/workflows/4-implementation/code-review/workflow.yaml +51 -0
- package/src/bmm/workflows/4-implementation/correct-course/checklist.md +288 -0
- package/src/bmm/workflows/4-implementation/correct-course/instructions.md +206 -0
- package/src/bmm/workflows/4-implementation/correct-course/workflow.yaml +60 -0
- package/src/bmm/workflows/4-implementation/create-story/checklist.md +358 -0
- package/src/bmm/workflows/4-implementation/create-story/instructions.xml +345 -0
- package/src/bmm/workflows/4-implementation/create-story/template.md +49 -0
- package/src/bmm/workflows/4-implementation/create-story/workflow.yaml +61 -0
- package/src/bmm/workflows/4-implementation/dev-story/checklist.md +80 -0
- package/src/bmm/workflows/4-implementation/dev-story/instructions.xml +410 -0
- package/src/bmm/workflows/4-implementation/dev-story/workflow.yaml +27 -0
- package/src/bmm/workflows/4-implementation/retrospective/instructions.md +1443 -0
- package/src/bmm/workflows/4-implementation/retrospective/workflow.yaml +58 -0
- package/src/bmm/workflows/4-implementation/sprint-planning/checklist.md +33 -0
- package/src/bmm/workflows/4-implementation/sprint-planning/instructions.md +225 -0
- package/src/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +55 -0
- package/src/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +54 -0
- package/src/bmm/workflows/4-implementation/sprint-status/instructions.md +229 -0
- package/src/bmm/workflows/4-implementation/sprint-status/workflow.yaml +36 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +156 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +120 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +113 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +113 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +106 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-06-resolve-findings.md +140 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +52 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-01-understand.md +189 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-02-investigate.md +144 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-03-generate.md +128 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-04-review.md +191 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/tech-spec-template.md +74 -0
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md +79 -0
- package/src/bmm/workflows/document-project/checklist.md +245 -0
- package/src/bmm/workflows/document-project/documentation-requirements.csv +12 -0
- package/src/bmm/workflows/document-project/instructions.md +221 -0
- package/src/bmm/workflows/document-project/templates/deep-dive-template.md +345 -0
- package/src/bmm/workflows/document-project/templates/index-template.md +169 -0
- package/src/bmm/workflows/document-project/templates/project-overview-template.md +103 -0
- package/src/bmm/workflows/document-project/templates/project-scan-report-schema.json +160 -0
- package/src/bmm/workflows/document-project/templates/source-tree-template.md +135 -0
- package/src/bmm/workflows/document-project/workflow.yaml +30 -0
- package/src/bmm/workflows/document-project/workflows/deep-dive-instructions.md +298 -0
- package/src/bmm/workflows/document-project/workflows/deep-dive.yaml +31 -0
- package/src/bmm/workflows/document-project/workflows/full-scan-instructions.md +1106 -0
- package/src/bmm/workflows/document-project/workflows/full-scan.yaml +31 -0
- package/src/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-library.json +90 -0
- package/src/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-templates.yaml +127 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-dataflow/checklist.md +39 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-dataflow/instructions.md +130 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-dataflow/workflow.yaml +27 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-diagram/checklist.md +43 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-diagram/instructions.md +141 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-diagram/workflow.yaml +27 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-flowchart/checklist.md +49 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-flowchart/instructions.md +241 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-flowchart/workflow.yaml +27 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-wireframe/checklist.md +38 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-wireframe/instructions.md +133 -0
- package/src/bmm/workflows/excalidraw-diagrams/create-wireframe/workflow.yaml +27 -0
- package/src/bmm/workflows/generate-project-context/project-context-template.md +21 -0
- package/src/bmm/workflows/generate-project-context/steps/step-01-discover.md +184 -0
- package/src/bmm/workflows/generate-project-context/steps/step-02-generate.md +318 -0
- package/src/bmm/workflows/generate-project-context/steps/step-03-complete.md +278 -0
- package/src/bmm/workflows/generate-project-context/workflow.md +49 -0
- package/src/bmm/workflows/testarch/atdd/atdd-checklist-template.md +364 -0
- package/src/bmm/workflows/testarch/atdd/checklist.md +374 -0
- package/src/bmm/workflows/testarch/atdd/instructions.md +806 -0
- package/src/bmm/workflows/testarch/atdd/workflow.yaml +47 -0
- package/src/bmm/workflows/testarch/automate/checklist.md +582 -0
- package/src/bmm/workflows/testarch/automate/instructions.md +1324 -0
- package/src/bmm/workflows/testarch/automate/workflow.yaml +54 -0
- package/src/bmm/workflows/testarch/ci/checklist.md +248 -0
- package/src/bmm/workflows/testarch/ci/github-actions-template.yaml +198 -0
- package/src/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +149 -0
- package/src/bmm/workflows/testarch/ci/instructions.md +536 -0
- package/src/bmm/workflows/testarch/ci/workflow.yaml +47 -0
- package/src/bmm/workflows/testarch/framework/checklist.md +321 -0
- package/src/bmm/workflows/testarch/framework/instructions.md +481 -0
- package/src/bmm/workflows/testarch/framework/workflow.yaml +49 -0
- package/src/bmm/workflows/testarch/nfr-assess/checklist.md +407 -0
- package/src/bmm/workflows/testarch/nfr-assess/instructions.md +722 -0
- package/src/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +445 -0
- package/src/bmm/workflows/testarch/nfr-assess/workflow.yaml +49 -0
- package/src/bmm/workflows/testarch/test-design/checklist.md +235 -0
- package/src/bmm/workflows/testarch/test-design/instructions.md +788 -0
- package/src/bmm/workflows/testarch/test-design/test-design-template.md +294 -0
- package/src/bmm/workflows/testarch/test-design/workflow.yaml +56 -0
- package/src/bmm/workflows/testarch/test-review/checklist.md +472 -0
- package/src/bmm/workflows/testarch/test-review/instructions.md +628 -0
- package/src/bmm/workflows/testarch/test-review/test-review-template.md +390 -0
- package/src/bmm/workflows/testarch/test-review/workflow.yaml +48 -0
- package/src/bmm/workflows/testarch/trace/checklist.md +655 -0
- package/src/bmm/workflows/testarch/trace/instructions.md +1047 -0
- package/src/bmm/workflows/testarch/trace/trace-template.md +675 -0
- package/src/bmm/workflows/testarch/trace/workflow.yaml +57 -0
- package/src/bmm/workflows/workflow-status/init/instructions.md +346 -0
- package/src/bmm/workflows/workflow-status/init/workflow.yaml +30 -0
- package/src/bmm/workflows/workflow-status/instructions.md +397 -0
- package/src/bmm/workflows/workflow-status/paths/enterprise-brownfield.yaml +103 -0
- package/src/bmm/workflows/workflow-status/paths/enterprise-greenfield.yaml +100 -0
- package/src/bmm/workflows/workflow-status/paths/method-brownfield.yaml +103 -0
- package/src/bmm/workflows/workflow-status/paths/method-greenfield.yaml +100 -0
- package/src/bmm/workflows/workflow-status/project-levels.yaml +59 -0
- package/src/bmm/workflows/workflow-status/workflow-status-template.yaml +24 -0
- package/src/bmm/workflows/workflow-status/workflow.yaml +32 -0
- package/src/core/_module-installer/installer.js +60 -0
- package/src/core/agents/bmad-master.agent.yaml +30 -0
- package/src/core/lib/scope/artifact-resolver.js +298 -0
- package/src/core/lib/scope/event-logger.js +400 -0
- package/src/core/lib/scope/index.js +30 -0
- package/src/core/lib/scope/scope-context.js +301 -0
- package/src/core/lib/scope/scope-initializer.js +456 -0
- package/src/core/lib/scope/scope-manager.js +512 -0
- package/src/core/lib/scope/scope-migrator.js +434 -0
- package/src/core/lib/scope/scope-sync.js +483 -0
- package/src/core/lib/scope/scope-validator.js +294 -0
- package/src/core/lib/scope/state-lock.js +336 -0
- package/src/core/module.yaml +53 -0
- package/src/core/resources/excalidraw/README.md +160 -0
- package/src/core/resources/excalidraw/excalidraw-helpers.md +127 -0
- package/src/core/resources/excalidraw/library-loader.md +50 -0
- package/src/core/resources/excalidraw/validate-json-instructions.md +79 -0
- package/src/core/tasks/editorial-review-prose.xml +91 -0
- package/src/core/tasks/editorial-review-structure.xml +198 -0
- package/src/core/tasks/index-docs.xml +65 -0
- package/src/core/tasks/review-adversarial-general.xml +46 -0
- package/src/core/tasks/shard-doc.xml +109 -0
- package/src/core/tasks/workflow.xml +277 -0
- package/src/core/workflows/advanced-elicitation/methods.csv +51 -0
- package/src/core/workflows/advanced-elicitation/workflow.xml +117 -0
- package/src/core/workflows/brainstorming/brain-methods.csv +62 -0
- package/src/core/workflows/brainstorming/steps/step-01-session-setup.md +197 -0
- package/src/core/workflows/brainstorming/steps/step-01b-continue.md +122 -0
- package/src/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -0
- package/src/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -0
- package/src/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -0
- package/src/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -0
- package/src/core/workflows/brainstorming/steps/step-03-technique-execution.md +399 -0
- package/src/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -0
- package/src/core/workflows/brainstorming/template.md +15 -0
- package/src/core/workflows/brainstorming/workflow.md +58 -0
- package/src/core/workflows/party-mode/steps/step-01-agent-loading.md +138 -0
- package/src/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +187 -0
- package/src/core/workflows/party-mode/steps/step-03-graceful-exit.md +157 -0
- package/src/core/workflows/party-mode/workflow.md +194 -0
- package/src/utility/agent-components/activation-rules.txt +6 -0
- package/src/utility/agent-components/activation-steps.txt +28 -0
- package/src/utility/agent-components/agent-command-header.md +1 -0
- package/src/utility/agent-components/agent.customize.template.yaml +41 -0
- package/src/utility/agent-components/handler-action.txt +4 -0
- package/src/utility/agent-components/handler-data.txt +5 -0
- package/src/utility/agent-components/handler-exec.txt +19 -0
- package/src/utility/agent-components/handler-multi.txt +14 -0
- package/src/utility/agent-components/handler-tmpl.txt +5 -0
- package/src/utility/agent-components/handler-validate-workflow.txt +7 -0
- package/src/utility/agent-components/handler-workflow.txt +10 -0
- package/src/utility/agent-components/menu-handlers.txt +6 -0
- package/test/README.md +295 -0
- package/test/fixtures/agent-schema/invalid/critical-actions/actions-as-string.agent.yaml +27 -0
- package/test/fixtures/agent-schema/invalid/critical-actions/empty-string-in-actions.agent.yaml +30 -0
- package/test/fixtures/agent-schema/invalid/menu/empty-menu.agent.yaml +22 -0
- package/test/fixtures/agent-schema/invalid/menu/missing-menu.agent.yaml +20 -0
- package/test/fixtures/agent-schema/invalid/menu-commands/empty-command-target.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-commands/no-command-target.agent.yaml +24 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/camel-case.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/compound-invalid-format.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/compound-mismatched-kebab.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/duplicate-triggers.agent.yaml +31 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/empty-trigger.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/leading-asterisk.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/snake-case.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/menu-triggers/trigger-with-spaces.agent.yaml +25 -0
- package/test/fixtures/agent-schema/invalid/metadata/empty-module-string.agent.yaml +26 -0
- package/test/fixtures/agent-schema/invalid/metadata/empty-name.agent.yaml +24 -0
- package/test/fixtures/agent-schema/invalid/metadata/extra-metadata-fields.agent.yaml +27 -0
- package/test/fixtures/agent-schema/invalid/metadata/missing-id.agent.yaml +23 -0
- package/test/fixtures/agent-schema/invalid/persona/empty-principles-array.agent.yaml +24 -0
- package/test/fixtures/agent-schema/invalid/persona/empty-string-in-principles.agent.yaml +27 -0
- package/test/fixtures/agent-schema/invalid/persona/extra-persona-fields.agent.yaml +27 -0
- package/test/fixtures/agent-schema/invalid/persona/missing-role.agent.yaml +24 -0
- package/test/fixtures/agent-schema/invalid/prompts/empty-content.agent.yaml +29 -0
- package/test/fixtures/agent-schema/invalid/prompts/extra-prompt-fields.agent.yaml +31 -0
- package/test/fixtures/agent-schema/invalid/prompts/missing-content.agent.yaml +28 -0
- package/test/fixtures/agent-schema/invalid/prompts/missing-id.agent.yaml +28 -0
- package/test/fixtures/agent-schema/invalid/top-level/empty-file.agent.yaml +5 -0
- package/test/fixtures/agent-schema/invalid/top-level/extra-top-level-keys.agent.yaml +28 -0
- package/test/fixtures/agent-schema/invalid/top-level/missing-agent-key.agent.yaml +11 -0
- package/test/fixtures/agent-schema/invalid/yaml-errors/invalid-indentation.agent.yaml +19 -0
- package/test/fixtures/agent-schema/invalid/yaml-errors/malformed-yaml.agent.yaml +18 -0
- package/test/fixtures/agent-schema/valid/critical-actions/empty-critical-actions.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/critical-actions/no-critical-actions.agent.yaml +22 -0
- package/test/fixtures/agent-schema/valid/critical-actions/valid-critical-actions.agent.yaml +27 -0
- package/test/fixtures/agent-schema/valid/menu/multiple-menu-items.agent.yaml +31 -0
- package/test/fixtures/agent-schema/valid/menu/single-menu-item.agent.yaml +22 -0
- package/test/fixtures/agent-schema/valid/menu-commands/all-command-types.agent.yaml +38 -0
- package/test/fixtures/agent-schema/valid/menu-commands/multiple-commands.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/menu-triggers/compound-triggers.agent.yaml +31 -0
- package/test/fixtures/agent-schema/valid/menu-triggers/kebab-case-triggers.agent.yaml +34 -0
- package/test/fixtures/agent-schema/valid/metadata/core-agent-with-module.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/metadata/empty-module-name-in-path.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/metadata/malformed-path-treated-as-core.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/metadata/module-agent-correct.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/metadata/module-agent-missing-module.agent.yaml +23 -0
- package/test/fixtures/agent-schema/valid/metadata/wrong-module-value.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/persona/complete-persona.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/prompts/empty-prompts.agent.yaml +24 -0
- package/test/fixtures/agent-schema/valid/prompts/no-prompts.agent.yaml +22 -0
- package/test/fixtures/agent-schema/valid/prompts/valid-prompts-minimal.agent.yaml +28 -0
- package/test/fixtures/agent-schema/valid/prompts/valid-prompts-with-description.agent.yaml +30 -0
- package/test/fixtures/agent-schema/valid/top-level/minimal-core-agent.agent.yaml +24 -0
- package/test/test-agent-schema.js +387 -0
- package/test/test-cli-integration.sh +159 -0
- package/test/test-installation-components.js +214 -0
- package/test/test-scope-e2e.js +439 -0
- package/test/test-scope-system.js +781 -0
- package/test/unit-test-schema.js +133 -0
- package/tools/bmad-npx-wrapper.js +38 -0
- package/tools/build-docs.js +577 -0
- package/tools/cli/README.md +7 -0
- package/tools/cli/bmad-cli.js +58 -0
- package/tools/cli/commands/install.js +87 -0
- package/tools/cli/commands/scope.js +474 -0
- package/tools/cli/external-official-modules.yaml +41 -0
- package/tools/cli/installers/install-messages.yaml +58 -0
- package/tools/cli/installers/lib/core/config-collector.js +1079 -0
- package/tools/cli/installers/lib/core/custom-module-cache.js +259 -0
- package/tools/cli/installers/lib/core/dependency-resolver.js +739 -0
- package/tools/cli/installers/lib/core/detector.js +223 -0
- package/tools/cli/installers/lib/core/ide-config-manager.js +156 -0
- package/tools/cli/installers/lib/core/installer.js +2585 -0
- package/tools/cli/installers/lib/core/manifest-generator.js +963 -0
- package/tools/cli/installers/lib/core/manifest.js +590 -0
- package/tools/cli/installers/lib/custom/handler.js +363 -0
- package/tools/cli/installers/lib/ide/_base-ide.js +654 -0
- package/tools/cli/installers/lib/ide/antigravity.js +486 -0
- package/tools/cli/installers/lib/ide/auggie.js +244 -0
- package/tools/cli/installers/lib/ide/claude-code.js +487 -0
- package/tools/cli/installers/lib/ide/cline.js +269 -0
- package/tools/cli/installers/lib/ide/codex.js +375 -0
- package/tools/cli/installers/lib/ide/crush.js +300 -0
- package/tools/cli/installers/lib/ide/cursor.js +169 -0
- package/tools/cli/installers/lib/ide/gemini.js +301 -0
- package/tools/cli/installers/lib/ide/github-copilot.js +383 -0
- package/tools/cli/installers/lib/ide/iflow.js +191 -0
- package/tools/cli/installers/lib/ide/kilo.js +250 -0
- package/tools/cli/installers/lib/ide/kiro-cli.js +326 -0
- package/tools/cli/installers/lib/ide/manager.js +244 -0
- package/tools/cli/installers/lib/ide/opencode.js +257 -0
- package/tools/cli/installers/lib/ide/qwen.js +372 -0
- package/tools/cli/installers/lib/ide/roo.js +270 -0
- package/tools/cli/installers/lib/ide/rovo-dev.js +290 -0
- package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +96 -0
- package/tools/cli/installers/lib/ide/shared/bmad-artifacts.js +158 -0
- package/tools/cli/installers/lib/ide/shared/module-injections.js +136 -0
- package/tools/cli/installers/lib/ide/shared/task-tool-command-generator.js +119 -0
- package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +242 -0
- package/tools/cli/installers/lib/ide/templates/agent-command-template.md +29 -0
- package/tools/cli/installers/lib/ide/templates/gemini-agent-command.toml +14 -0
- package/tools/cli/installers/lib/ide/templates/gemini-task-command.toml +12 -0
- package/tools/cli/installers/lib/ide/templates/workflow-command-template.md +30 -0
- package/tools/cli/installers/lib/ide/templates/workflow-commander.md +45 -0
- package/tools/cli/installers/lib/ide/trae.js +313 -0
- package/tools/cli/installers/lib/ide/windsurf.js +258 -0
- package/tools/cli/installers/lib/message-loader.js +85 -0
- package/tools/cli/installers/lib/modules/external-manager.js +133 -0
- package/tools/cli/installers/lib/modules/manager.js +1362 -0
- package/tools/cli/lib/activation-builder.js +163 -0
- package/tools/cli/lib/agent/compiler.js +522 -0
- package/tools/cli/lib/agent/installer.js +716 -0
- package/tools/cli/lib/agent/template-engine.js +152 -0
- package/tools/cli/lib/agent-analyzer.js +109 -0
- package/tools/cli/lib/agent-party-generator.js +194 -0
- package/tools/cli/lib/cli-utils.js +227 -0
- package/tools/cli/lib/config.js +213 -0
- package/tools/cli/lib/file-ops.js +204 -0
- package/tools/cli/lib/platform-codes.js +116 -0
- package/tools/cli/lib/project-root.js +77 -0
- package/tools/cli/lib/prompts.js +433 -0
- package/tools/cli/lib/ui.js +1591 -0
- package/tools/cli/lib/xml-handler.js +177 -0
- package/tools/cli/lib/xml-to-markdown.js +82 -0
- package/tools/cli/lib/yaml-format.js +245 -0
- package/tools/cli/lib/yaml-xml-builder.js +587 -0
- package/tools/cli/scripts/migrate-workflows.js +273 -0
- package/tools/docs/BUNDLE_DISTRIBUTION_SETUP.md +95 -0
- package/tools/docs/index.md +2 -0
- package/tools/fix-doc-links.js +288 -0
- package/tools/flattener/aggregate.js +76 -0
- package/tools/flattener/binary.js +80 -0
- package/tools/flattener/discovery.js +71 -0
- package/tools/flattener/files.js +35 -0
- package/tools/flattener/ignoreRules.js +172 -0
- package/tools/flattener/main.js +483 -0
- package/tools/flattener/projectRoot.js +201 -0
- package/tools/flattener/prompts.js +44 -0
- package/tools/flattener/stats.helpers.js +368 -0
- package/tools/flattener/stats.js +75 -0
- package/tools/flattener/test-matrix.js +409 -0
- package/tools/flattener/xml.js +82 -0
- package/tools/format-workflow-md.js +263 -0
- package/tools/lib/xml-utils.js +13 -0
- package/tools/maintainer/review-pr-README.md +55 -0
- package/tools/maintainer/review-pr.md +242 -0
- package/tools/migrate-custom-module-paths.js +124 -0
- package/tools/platform-codes.yaml +157 -0
- package/tools/schema/agent.js +493 -0
- package/tools/validate-agent-schema.js +110 -0
- package/tools/validate-doc-links.js +363 -0
- package/tools/validate-svg-changes.sh +356 -0
- package/website/README.md +76 -0
- package/website/astro.config.mjs +228 -0
- package/website/public/favicon.ico +0 -0
- package/website/public/img/bmad-dark.png +0 -0
- package/website/public/img/bmad-light.png +0 -0
- package/website/public/img/logo.svg +4 -0
- package/website/public/robots.txt +37 -0
- package/website/src/components/Banner.astro +59 -0
- package/website/src/components/Header.astro +121 -0
- package/website/src/components/MobileMenuFooter.astro +53 -0
- package/website/src/content/config.ts +6 -0
- package/website/src/lib/site-url.js +25 -0
- package/website/src/rehype-markdown-links.js +102 -0
- package/website/src/styles/custom.css +485 -0
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
# Auth Session Utility
|
|
2
|
+
|
|
3
|
+
## Principle
|
|
4
|
+
|
|
5
|
+
Persist authentication tokens to disk and reuse across test runs. Support multiple user identifiers, ephemeral authentication, and worker-specific accounts for parallel execution. Fetch tokens once, use everywhere. **Works for both API-only tests and browser tests.**
|
|
6
|
+
|
|
7
|
+
## Rationale
|
|
8
|
+
|
|
9
|
+
Playwright's built-in authentication works but has limitations:
|
|
10
|
+
|
|
11
|
+
- Re-authenticates for every test run (slow)
|
|
12
|
+
- Single user per project setup
|
|
13
|
+
- No token expiration handling
|
|
14
|
+
- Manual session management
|
|
15
|
+
- Complex setup for multi-user scenarios
|
|
16
|
+
|
|
17
|
+
The `auth-session` utility provides:
|
|
18
|
+
|
|
19
|
+
- **Token persistence**: Authenticate once, reuse across runs
|
|
20
|
+
- **Multi-user support**: Different user identifiers in same test suite
|
|
21
|
+
- **Ephemeral auth**: On-the-fly user authentication without disk persistence
|
|
22
|
+
- **Worker-specific accounts**: Parallel execution with isolated user accounts
|
|
23
|
+
- **Automatic token management**: Checks validity, renews if expired
|
|
24
|
+
- **Flexible provider pattern**: Adapt to any auth system (OAuth2, JWT, custom)
|
|
25
|
+
- **API-first design**: Get tokens for API tests without browser overhead
|
|
26
|
+
|
|
27
|
+
## Pattern Examples
|
|
28
|
+
|
|
29
|
+
### Example 1: Basic Auth Session Setup
|
|
30
|
+
|
|
31
|
+
**Context**: Configure global authentication that persists across test runs.
|
|
32
|
+
|
|
33
|
+
**Implementation**:
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
// Step 1: Configure in global-setup.ts
|
|
37
|
+
import { authStorageInit, setAuthProvider, configureAuthSession, authGlobalInit } from '@seontechnologies/playwright-utils/auth-session';
|
|
38
|
+
import myCustomProvider from './auth/custom-auth-provider';
|
|
39
|
+
|
|
40
|
+
async function globalSetup() {
|
|
41
|
+
// Ensure storage directories exist
|
|
42
|
+
authStorageInit();
|
|
43
|
+
|
|
44
|
+
// Configure storage path
|
|
45
|
+
configureAuthSession({
|
|
46
|
+
authStoragePath: process.cwd() + '/playwright/auth-sessions',
|
|
47
|
+
debug: true,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Set custom provider (HOW to authenticate)
|
|
51
|
+
setAuthProvider(myCustomProvider);
|
|
52
|
+
|
|
53
|
+
// Optional: pre-fetch token for default user
|
|
54
|
+
await authGlobalInit();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default globalSetup;
|
|
58
|
+
|
|
59
|
+
// Step 2: Create auth fixture
|
|
60
|
+
import { test as base } from '@playwright/test';
|
|
61
|
+
import { createAuthFixtures, setAuthProvider } from '@seontechnologies/playwright-utils/auth-session';
|
|
62
|
+
import myCustomProvider from './custom-auth-provider';
|
|
63
|
+
|
|
64
|
+
// Register provider early
|
|
65
|
+
setAuthProvider(myCustomProvider);
|
|
66
|
+
|
|
67
|
+
export const test = base.extend(createAuthFixtures());
|
|
68
|
+
|
|
69
|
+
// Step 3: Use in tests
|
|
70
|
+
test('authenticated request', async ({ authToken, request }) => {
|
|
71
|
+
const response = await request.get('/api/protected', {
|
|
72
|
+
headers: { Authorization: `Bearer ${authToken}` },
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
expect(response.ok()).toBeTruthy();
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Key Points**:
|
|
80
|
+
|
|
81
|
+
- Global setup runs once before all tests
|
|
82
|
+
- Token fetched once, reused across all tests
|
|
83
|
+
- Custom provider defines your auth mechanism
|
|
84
|
+
- Order matters: configure, then setProvider, then init
|
|
85
|
+
|
|
86
|
+
### Example 2: Multi-User Authentication
|
|
87
|
+
|
|
88
|
+
**Context**: Testing with different user roles (admin, regular user, guest) in same test suite.
|
|
89
|
+
|
|
90
|
+
**Implementation**:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { test } from '../support/auth/auth-fixture';
|
|
94
|
+
|
|
95
|
+
// Option 1: Per-test user override
|
|
96
|
+
test('admin actions', async ({ authToken, authOptions }) => {
|
|
97
|
+
// Override default user
|
|
98
|
+
authOptions.userIdentifier = 'admin';
|
|
99
|
+
|
|
100
|
+
const { authToken: adminToken } = await test.step('Get admin token', async () => {
|
|
101
|
+
return { authToken }; // Re-fetches with new identifier
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Use admin token
|
|
105
|
+
const response = await request.get('/api/admin/users', {
|
|
106
|
+
headers: { Authorization: `Bearer ${adminToken}` },
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Option 2: Parallel execution with different users
|
|
111
|
+
test.describe.parallel('multi-user tests', () => {
|
|
112
|
+
test('user 1 actions', async ({ authToken }) => {
|
|
113
|
+
// Uses default user (e.g., 'user1')
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test('user 2 actions', async ({ authToken, authOptions }) => {
|
|
117
|
+
authOptions.userIdentifier = 'user2';
|
|
118
|
+
// Uses different token for user2
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Key Points**:
|
|
124
|
+
|
|
125
|
+
- Override `authOptions.userIdentifier` per test
|
|
126
|
+
- Tokens cached separately per user identifier
|
|
127
|
+
- Parallel tests isolated with different users
|
|
128
|
+
- Worker-specific accounts possible
|
|
129
|
+
|
|
130
|
+
### Example 3: Ephemeral User Authentication
|
|
131
|
+
|
|
132
|
+
**Context**: Create temporary test users that don't persist to disk (e.g., testing user creation flow).
|
|
133
|
+
|
|
134
|
+
**Implementation**:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import { applyUserCookiesToBrowserContext } from '@seontechnologies/playwright-utils/auth-session';
|
|
138
|
+
import { createTestUser } from '../utils/user-factory';
|
|
139
|
+
|
|
140
|
+
test('ephemeral user test', async ({ context, page }) => {
|
|
141
|
+
// Create temporary user (not persisted)
|
|
142
|
+
const ephemeralUser = await createTestUser({
|
|
143
|
+
role: 'admin',
|
|
144
|
+
permissions: ['delete-users'],
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// Apply auth directly to browser context
|
|
148
|
+
await applyUserCookiesToBrowserContext(context, ephemeralUser);
|
|
149
|
+
|
|
150
|
+
// Page now authenticated as ephemeral user
|
|
151
|
+
await page.goto('/admin/users');
|
|
152
|
+
|
|
153
|
+
await expect(page.getByTestId('delete-user-btn')).toBeVisible();
|
|
154
|
+
|
|
155
|
+
// User and token cleaned up after test
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Key Points**:
|
|
160
|
+
|
|
161
|
+
- No disk persistence (ephemeral)
|
|
162
|
+
- Apply cookies directly to context
|
|
163
|
+
- Useful for testing user lifecycle
|
|
164
|
+
- Clean up automatic when test ends
|
|
165
|
+
|
|
166
|
+
### Example 4: Testing Multiple Users in Single Test
|
|
167
|
+
|
|
168
|
+
**Context**: Testing interactions between users (messaging, sharing, collaboration features).
|
|
169
|
+
|
|
170
|
+
**Implementation**:
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
test('user interaction', async ({ browser }) => {
|
|
174
|
+
// User 1 context
|
|
175
|
+
const user1Context = await browser.newContext({
|
|
176
|
+
storageState: './auth-sessions/local/user1/storage-state.json',
|
|
177
|
+
});
|
|
178
|
+
const user1Page = await user1Context.newPage();
|
|
179
|
+
|
|
180
|
+
// User 2 context
|
|
181
|
+
const user2Context = await browser.newContext({
|
|
182
|
+
storageState: './auth-sessions/local/user2/storage-state.json',
|
|
183
|
+
});
|
|
184
|
+
const user2Page = await user2Context.newPage();
|
|
185
|
+
|
|
186
|
+
// User 1 sends message
|
|
187
|
+
await user1Page.goto('/messages');
|
|
188
|
+
await user1Page.fill('#message', 'Hello from user 1');
|
|
189
|
+
await user1Page.click('#send');
|
|
190
|
+
|
|
191
|
+
// User 2 receives message
|
|
192
|
+
await user2Page.goto('/messages');
|
|
193
|
+
await expect(user2Page.getByText('Hello from user 1')).toBeVisible();
|
|
194
|
+
|
|
195
|
+
// Cleanup
|
|
196
|
+
await user1Context.close();
|
|
197
|
+
await user2Context.close();
|
|
198
|
+
});
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Key Points**:
|
|
202
|
+
|
|
203
|
+
- Each user has separate browser context
|
|
204
|
+
- Reference storage state files directly
|
|
205
|
+
- Test real-time interactions
|
|
206
|
+
- Clean up contexts after test
|
|
207
|
+
|
|
208
|
+
### Example 5: Worker-Specific Accounts (Parallel Testing)
|
|
209
|
+
|
|
210
|
+
**Context**: Running tests in parallel with isolated user accounts per worker to avoid conflicts.
|
|
211
|
+
|
|
212
|
+
**Implementation**:
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
// playwright.config.ts
|
|
216
|
+
export default defineConfig({
|
|
217
|
+
workers: 4, // 4 parallel workers
|
|
218
|
+
use: {
|
|
219
|
+
// Each worker uses different user
|
|
220
|
+
storageState: async ({}, use, testInfo) => {
|
|
221
|
+
const workerIndex = testInfo.workerIndex;
|
|
222
|
+
const userIdentifier = `worker-${workerIndex}`;
|
|
223
|
+
|
|
224
|
+
await use(`./auth-sessions/local/${userIdentifier}/storage-state.json`);
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Tests run in parallel, each worker with its own user
|
|
230
|
+
test('parallel test 1', async ({ page }) => {
|
|
231
|
+
// Worker 0 uses worker-0 account
|
|
232
|
+
await page.goto('/dashboard');
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
test('parallel test 2', async ({ page }) => {
|
|
236
|
+
// Worker 1 uses worker-1 account
|
|
237
|
+
await page.goto('/dashboard');
|
|
238
|
+
});
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Key Points**:
|
|
242
|
+
|
|
243
|
+
- Each worker has isolated user account
|
|
244
|
+
- No conflicts in parallel execution
|
|
245
|
+
- Token management automatic per worker
|
|
246
|
+
- Scales to any number of workers
|
|
247
|
+
|
|
248
|
+
### Example 6: Pure API Authentication (No Browser)
|
|
249
|
+
|
|
250
|
+
**Context**: Get auth tokens for API-only tests using auth-session disk persistence.
|
|
251
|
+
|
|
252
|
+
**Implementation**:
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
// Step 1: Create API-only auth provider (no browser needed)
|
|
256
|
+
// playwright/support/api-auth-provider.ts
|
|
257
|
+
import { type AuthProvider } from '@seontechnologies/playwright-utils/auth-session';
|
|
258
|
+
|
|
259
|
+
const apiAuthProvider: AuthProvider = {
|
|
260
|
+
getEnvironment: (options) => options.environment || 'local',
|
|
261
|
+
getUserIdentifier: (options) => options.userIdentifier || 'api-user',
|
|
262
|
+
|
|
263
|
+
extractToken: (storageState) => {
|
|
264
|
+
// Token stored in localStorage format for disk persistence
|
|
265
|
+
const tokenEntry = storageState.origins?.[0]?.localStorage?.find(
|
|
266
|
+
(item) => item.name === 'auth_token'
|
|
267
|
+
);
|
|
268
|
+
return tokenEntry?.value;
|
|
269
|
+
},
|
|
270
|
+
|
|
271
|
+
isTokenExpired: (storageState) => {
|
|
272
|
+
const expiryEntry = storageState.origins?.[0]?.localStorage?.find(
|
|
273
|
+
(item) => item.name === 'token_expiry'
|
|
274
|
+
);
|
|
275
|
+
if (!expiryEntry) return true;
|
|
276
|
+
return Date.now() > parseInt(expiryEntry.value, 10);
|
|
277
|
+
},
|
|
278
|
+
|
|
279
|
+
manageAuthToken: async (request, options) => {
|
|
280
|
+
const email = process.env.TEST_USER_EMAIL;
|
|
281
|
+
const password = process.env.TEST_USER_PASSWORD;
|
|
282
|
+
|
|
283
|
+
if (!email || !password) {
|
|
284
|
+
throw new Error('TEST_USER_EMAIL and TEST_USER_PASSWORD must be set');
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Pure API login - no browser!
|
|
288
|
+
const response = await request.post('/api/auth/login', {
|
|
289
|
+
data: { email, password },
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
if (!response.ok()) {
|
|
293
|
+
throw new Error(`Auth failed: ${response.status()}`);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const { token, expiresIn } = await response.json();
|
|
297
|
+
const expiryTime = Date.now() + expiresIn * 1000;
|
|
298
|
+
|
|
299
|
+
// Return storage state format for disk persistence
|
|
300
|
+
return {
|
|
301
|
+
cookies: [],
|
|
302
|
+
origins: [
|
|
303
|
+
{
|
|
304
|
+
origin: process.env.API_BASE_URL || 'http://localhost:3000',
|
|
305
|
+
localStorage: [
|
|
306
|
+
{ name: 'auth_token', value: token },
|
|
307
|
+
{ name: 'token_expiry', value: String(expiryTime) },
|
|
308
|
+
],
|
|
309
|
+
},
|
|
310
|
+
],
|
|
311
|
+
};
|
|
312
|
+
},
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
export default apiAuthProvider;
|
|
316
|
+
|
|
317
|
+
// Step 2: Create auth fixture
|
|
318
|
+
// playwright/support/fixtures.ts
|
|
319
|
+
import { test as base } from '@playwright/test';
|
|
320
|
+
import { createAuthFixtures, setAuthProvider } from '@seontechnologies/playwright-utils/auth-session';
|
|
321
|
+
import apiAuthProvider from './api-auth-provider';
|
|
322
|
+
|
|
323
|
+
setAuthProvider(apiAuthProvider);
|
|
324
|
+
|
|
325
|
+
export const test = base.extend(createAuthFixtures());
|
|
326
|
+
|
|
327
|
+
// Step 3: Use in tests - token persisted to disk!
|
|
328
|
+
// tests/api/authenticated-api.spec.ts
|
|
329
|
+
import { test } from '../support/fixtures';
|
|
330
|
+
import { expect } from '@playwright/test';
|
|
331
|
+
|
|
332
|
+
test('should access protected endpoint', async ({ authToken, apiRequest }) => {
|
|
333
|
+
// authToken is automatically loaded from disk or fetched if expired
|
|
334
|
+
const { status, body } = await apiRequest({
|
|
335
|
+
method: 'GET',
|
|
336
|
+
path: '/api/me',
|
|
337
|
+
headers: { Authorization: `Bearer ${authToken}` },
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
expect(status).toBe(200);
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
test('should create resource with auth', async ({ authToken, apiRequest }) => {
|
|
344
|
+
const { status, body } = await apiRequest({
|
|
345
|
+
method: 'POST',
|
|
346
|
+
path: '/api/orders',
|
|
347
|
+
headers: { Authorization: `Bearer ${authToken}` },
|
|
348
|
+
body: { items: [{ productId: 'prod-1', quantity: 2 }] },
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
expect(status).toBe(201);
|
|
352
|
+
expect(body.id).toBeDefined();
|
|
353
|
+
});
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
**Key Points**:
|
|
357
|
+
|
|
358
|
+
- Token persisted to disk (not in-memory) - survives test reruns
|
|
359
|
+
- Provider fetches token once, reuses until expired
|
|
360
|
+
- Pure API authentication - no browser context needed
|
|
361
|
+
- `authToken` fixture handles disk read/write automatically
|
|
362
|
+
- Environment variables validated with clear error message
|
|
363
|
+
|
|
364
|
+
### Example 7: Service-to-Service Authentication
|
|
365
|
+
|
|
366
|
+
**Context**: Test microservice authentication patterns (API keys, service tokens) with proper environment validation.
|
|
367
|
+
|
|
368
|
+
**Implementation**:
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
// tests/api/service-auth.spec.ts
|
|
372
|
+
import { test as base, expect } from '@playwright/test';
|
|
373
|
+
import { test as apiFixture } from '@seontechnologies/playwright-utils/api-request/fixtures';
|
|
374
|
+
import { mergeTests } from '@playwright/test';
|
|
375
|
+
|
|
376
|
+
// Validate environment variables at module load
|
|
377
|
+
const SERVICE_API_KEY = process.env.SERVICE_API_KEY;
|
|
378
|
+
const INTERNAL_SERVICE_URL = process.env.INTERNAL_SERVICE_URL;
|
|
379
|
+
|
|
380
|
+
if (!SERVICE_API_KEY) {
|
|
381
|
+
throw new Error('SERVICE_API_KEY environment variable is required');
|
|
382
|
+
}
|
|
383
|
+
if (!INTERNAL_SERVICE_URL) {
|
|
384
|
+
throw new Error('INTERNAL_SERVICE_URL environment variable is required');
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const test = mergeTests(base, apiFixture);
|
|
388
|
+
|
|
389
|
+
test.describe('Service-to-Service Auth', () => {
|
|
390
|
+
test('should authenticate with API key', async ({ apiRequest }) => {
|
|
391
|
+
const { status, body } = await apiRequest({
|
|
392
|
+
method: 'GET',
|
|
393
|
+
path: '/internal/health',
|
|
394
|
+
baseUrl: INTERNAL_SERVICE_URL,
|
|
395
|
+
headers: { 'X-API-Key': SERVICE_API_KEY },
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
expect(status).toBe(200);
|
|
399
|
+
expect(body.status).toBe('healthy');
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
test('should reject invalid API key', async ({ apiRequest }) => {
|
|
403
|
+
const { status, body } = await apiRequest({
|
|
404
|
+
method: 'GET',
|
|
405
|
+
path: '/internal/health',
|
|
406
|
+
baseUrl: INTERNAL_SERVICE_URL,
|
|
407
|
+
headers: { 'X-API-Key': 'invalid-key' },
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
expect(status).toBe(401);
|
|
411
|
+
expect(body.code).toBe('INVALID_API_KEY');
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
test('should call downstream service with propagated auth', async ({ apiRequest }) => {
|
|
415
|
+
const { status, body } = await apiRequest({
|
|
416
|
+
method: 'POST',
|
|
417
|
+
path: '/internal/aggregate-data',
|
|
418
|
+
baseUrl: INTERNAL_SERVICE_URL,
|
|
419
|
+
headers: {
|
|
420
|
+
'X-API-Key': SERVICE_API_KEY,
|
|
421
|
+
'X-Request-ID': `test-${Date.now()}`,
|
|
422
|
+
},
|
|
423
|
+
body: { sources: ['users', 'orders', 'inventory'] },
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
expect(status).toBe(200);
|
|
427
|
+
expect(body.aggregatedFrom).toHaveLength(3);
|
|
428
|
+
});
|
|
429
|
+
});
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**Key Points**:
|
|
433
|
+
|
|
434
|
+
- Environment variables validated at module load with clear errors
|
|
435
|
+
- API key authentication (simpler than OAuth - no disk persistence needed)
|
|
436
|
+
- Test internal/service endpoints
|
|
437
|
+
- Validate auth rejection scenarios
|
|
438
|
+
- Correlation ID for request tracing
|
|
439
|
+
|
|
440
|
+
> **Note**: API keys are typically static secrets that don't expire, so disk persistence (auth-session) isn't needed. For rotating service tokens, use the auth-session provider pattern from Example 6.
|
|
441
|
+
|
|
442
|
+
## Custom Auth Provider Pattern
|
|
443
|
+
|
|
444
|
+
**Context**: Adapt auth-session to your authentication system (OAuth2, JWT, SAML, custom).
|
|
445
|
+
|
|
446
|
+
**Minimal provider structure**:
|
|
447
|
+
|
|
448
|
+
```typescript
|
|
449
|
+
import { type AuthProvider } from '@seontechnologies/playwright-utils/auth-session';
|
|
450
|
+
|
|
451
|
+
const myCustomProvider: AuthProvider = {
|
|
452
|
+
getEnvironment: (options) => options.environment || 'local',
|
|
453
|
+
|
|
454
|
+
getUserIdentifier: (options) => options.userIdentifier || 'default-user',
|
|
455
|
+
|
|
456
|
+
extractToken: (storageState) => {
|
|
457
|
+
// Extract token from your storage format
|
|
458
|
+
return storageState.cookies.find((c) => c.name === 'auth_token')?.value;
|
|
459
|
+
},
|
|
460
|
+
|
|
461
|
+
extractCookies: (tokenData) => {
|
|
462
|
+
// Convert token to cookies for browser context
|
|
463
|
+
return [
|
|
464
|
+
{
|
|
465
|
+
name: 'auth_token',
|
|
466
|
+
value: tokenData,
|
|
467
|
+
domain: 'example.com',
|
|
468
|
+
path: '/',
|
|
469
|
+
httpOnly: true,
|
|
470
|
+
secure: true,
|
|
471
|
+
},
|
|
472
|
+
];
|
|
473
|
+
},
|
|
474
|
+
|
|
475
|
+
isTokenExpired: (storageState) => {
|
|
476
|
+
// Check if token is expired
|
|
477
|
+
const expiresAt = storageState.cookies.find((c) => c.name === 'expires_at');
|
|
478
|
+
return Date.now() > parseInt(expiresAt?.value || '0');
|
|
479
|
+
},
|
|
480
|
+
|
|
481
|
+
manageAuthToken: async (request, options) => {
|
|
482
|
+
// Main token acquisition logic
|
|
483
|
+
// Return storage state with cookies/localStorage
|
|
484
|
+
},
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
export default myCustomProvider;
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
## Integration with API Request
|
|
491
|
+
|
|
492
|
+
```typescript
|
|
493
|
+
import { test } from '@seontechnologies/playwright-utils/fixtures';
|
|
494
|
+
|
|
495
|
+
test('authenticated API call', async ({ apiRequest, authToken }) => {
|
|
496
|
+
const { status, body } = await apiRequest({
|
|
497
|
+
method: 'GET',
|
|
498
|
+
path: '/api/protected',
|
|
499
|
+
headers: { Authorization: `Bearer ${authToken}` },
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
expect(status).toBe(200);
|
|
503
|
+
});
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
## Related Fragments
|
|
507
|
+
|
|
508
|
+
- `api-testing-patterns.md` - Pure API testing patterns (no browser)
|
|
509
|
+
- `overview.md` - Installation and fixture composition
|
|
510
|
+
- `api-request.md` - Authenticated API requests
|
|
511
|
+
- `fixtures-composition.md` - Merging auth with other utilities
|
|
512
|
+
|
|
513
|
+
## Anti-Patterns
|
|
514
|
+
|
|
515
|
+
**❌ Calling setAuthProvider after globalSetup:**
|
|
516
|
+
|
|
517
|
+
```typescript
|
|
518
|
+
async function globalSetup() {
|
|
519
|
+
configureAuthSession(...)
|
|
520
|
+
await authGlobalInit() // Provider not set yet!
|
|
521
|
+
setAuthProvider(provider) // Too late
|
|
522
|
+
}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
**✅ Register provider before init:**
|
|
526
|
+
|
|
527
|
+
```typescript
|
|
528
|
+
async function globalSetup() {
|
|
529
|
+
authStorageInit()
|
|
530
|
+
configureAuthSession(...)
|
|
531
|
+
setAuthProvider(provider) // First
|
|
532
|
+
await authGlobalInit() // Then init
|
|
533
|
+
}
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
**❌ Hardcoding storage paths:**
|
|
537
|
+
|
|
538
|
+
```typescript
|
|
539
|
+
const storageState = './auth-sessions/local/user1/storage-state.json'; // Brittle
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
**✅ Use helper functions:**
|
|
543
|
+
|
|
544
|
+
```typescript
|
|
545
|
+
import { getTokenFilePath } from '@seontechnologies/playwright-utils/auth-session';
|
|
546
|
+
|
|
547
|
+
const tokenPath = getTokenFilePath({
|
|
548
|
+
environment: 'local',
|
|
549
|
+
userIdentifier: 'user1',
|
|
550
|
+
tokenFileName: 'storage-state.json',
|
|
551
|
+
});
|
|
552
|
+
```
|