bmad-method-test-architecture-enterprise 0.1.1-beta.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/.github/CODE_OF_CONDUCT.md +128 -0
- package/.github/FUNDING.yaml +15 -0
- package/.github/ISSUE_TEMPLATE/config.yaml +11 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +70 -0
- package/.github/ISSUE_TEMPLATE/issue.md +61 -0
- package/.github/workflows/docs.yaml +66 -0
- package/.github/workflows/manual-release.yaml +195 -0
- package/.github/workflows/quality.yaml +114 -0
- package/.husky/pre-commit +20 -0
- package/.markdownlint-cli2.yaml +36 -0
- package/.nvmrc +1 -0
- package/.prettierignore +9 -0
- package/.vscode/settings.json +47 -0
- package/CHANGELOG.md +217 -0
- package/CONTRIBUTING.md +268 -0
- package/LICENSE +26 -0
- package/README.md +300 -0
- package/SECURITY.md +85 -0
- package/TEA-MODULE-MIGRATION-PLAN.md +3788 -0
- package/docs/404.md +20 -0
- package/docs/MIGRATION.md +447 -0
- package/docs/explanation/engagement-models.md +767 -0
- package/docs/explanation/fixture-architecture.md +484 -0
- package/docs/explanation/knowledge-base-system.md +599 -0
- package/docs/explanation/network-first-patterns.md +884 -0
- package/docs/explanation/risk-based-testing.md +628 -0
- package/docs/explanation/step-file-architecture.md +609 -0
- package/docs/explanation/subprocess-architecture.md +578 -0
- package/docs/explanation/subprocess-implementation-status.md +327 -0
- package/docs/explanation/tea-overview.md +425 -0
- package/docs/explanation/test-quality-standards.md +965 -0
- package/docs/explanation/testing-as-engineering.md +111 -0
- package/docs/glossary/index.md +160 -0
- package/docs/how-to/brownfield/use-tea-for-enterprise.md +571 -0
- package/docs/how-to/brownfield/use-tea-with-existing-tests.md +631 -0
- package/docs/how-to/customization/enable-tea-mcp-enhancements.md +455 -0
- package/docs/how-to/customization/integrate-playwright-utils.md +846 -0
- package/docs/how-to/workflows/run-atdd.md +460 -0
- package/docs/how-to/workflows/run-automate.md +690 -0
- package/docs/how-to/workflows/run-nfr-assess.md +731 -0
- package/docs/how-to/workflows/run-test-design.md +144 -0
- package/docs/how-to/workflows/run-test-review.md +638 -0
- package/docs/how-to/workflows/run-trace.md +951 -0
- package/docs/how-to/workflows/setup-ci.md +761 -0
- package/docs/how-to/workflows/setup-test-framework.md +99 -0
- package/docs/index.md +122 -0
- package/docs/reference/commands.md +300 -0
- package/docs/reference/configuration.md +729 -0
- package/docs/reference/knowledge-base.md +365 -0
- package/docs/reference/troubleshooting.md +717 -0
- package/docs/tutorials/tea-lite-quickstart.md +465 -0
- package/eslint.config.mjs +152 -0
- package/package.json +117 -0
- package/prettier.config.mjs +32 -0
- package/release_notes.md +28 -0
- package/src/_module-installer/installer.js +92 -0
- package/src/agents/tea.agent.yaml +63 -0
- package/src/module-help.csv +9 -0
- package/src/module.yaml +91 -0
- package/src/testarch/knowledge/adr-quality-readiness-checklist.md +377 -0
- package/src/testarch/knowledge/api-request.md +442 -0
- package/src/testarch/knowledge/api-testing-patterns.md +851 -0
- package/src/testarch/knowledge/auth-session.md +548 -0
- package/src/testarch/knowledge/burn-in.md +273 -0
- package/src/testarch/knowledge/ci-burn-in.md +675 -0
- package/src/testarch/knowledge/component-tdd.md +486 -0
- package/src/testarch/knowledge/contract-testing.md +957 -0
- package/src/testarch/knowledge/data-factories.md +500 -0
- package/src/testarch/knowledge/email-auth.md +721 -0
- package/src/testarch/knowledge/error-handling.md +725 -0
- package/src/testarch/knowledge/feature-flags.md +750 -0
- package/src/testarch/knowledge/file-utils.md +456 -0
- package/src/testarch/knowledge/fixture-architecture.md +401 -0
- package/src/testarch/knowledge/fixtures-composition.md +382 -0
- package/src/testarch/knowledge/intercept-network-call.md +426 -0
- package/src/testarch/knowledge/log.md +426 -0
- package/src/testarch/knowledge/network-error-monitor.md +401 -0
- package/src/testarch/knowledge/network-first.md +486 -0
- package/src/testarch/knowledge/network-recorder.md +527 -0
- package/src/testarch/knowledge/nfr-criteria.md +670 -0
- package/src/testarch/knowledge/overview.md +286 -0
- package/src/testarch/knowledge/playwright-config.md +730 -0
- package/src/testarch/knowledge/probability-impact.md +601 -0
- package/src/testarch/knowledge/recurse.md +421 -0
- package/src/testarch/knowledge/risk-governance.md +615 -0
- package/src/testarch/knowledge/selective-testing.md +732 -0
- package/src/testarch/knowledge/selector-resilience.md +527 -0
- package/src/testarch/knowledge/test-healing-patterns.md +644 -0
- package/src/testarch/knowledge/test-levels-framework.md +473 -0
- package/src/testarch/knowledge/test-priorities-matrix.md +373 -0
- package/src/testarch/knowledge/test-quality.md +664 -0
- package/src/testarch/knowledge/timing-debugging.md +372 -0
- package/src/testarch/knowledge/visual-debugging.md +524 -0
- package/src/testarch/tea-index.csv +35 -0
- package/src/workflows/testarch/README.md +74 -0
- package/src/workflows/testarch/atdd/atdd-checklist-template.md +363 -0
- package/src/workflows/testarch/atdd/checklist.md +374 -0
- package/src/workflows/testarch/atdd/instructions.md +38 -0
- package/src/workflows/testarch/atdd/steps-c/step-01-preflight-and-context.md +110 -0
- package/src/workflows/testarch/atdd/steps-c/step-02-generation-mode.md +79 -0
- package/src/workflows/testarch/atdd/steps-c/step-03-test-strategy.md +76 -0
- package/src/workflows/testarch/atdd/steps-c/step-04-generate-tests.md +228 -0
- package/src/workflows/testarch/atdd/steps-c/step-04a-subprocess-api-failing.md +215 -0
- package/src/workflows/testarch/atdd/steps-c/step-04b-subprocess-e2e-failing.md +212 -0
- package/src/workflows/testarch/atdd/steps-c/step-04c-aggregate.md +329 -0
- package/src/workflows/testarch/atdd/steps-c/step-05-validate-and-complete.md +68 -0
- package/src/workflows/testarch/atdd/steps-e/step-01-assess.md +65 -0
- package/src/workflows/testarch/atdd/steps-e/step-02-apply-edit.md +60 -0
- package/src/workflows/testarch/atdd/steps-v/step-01-validate.md +67 -0
- package/src/workflows/testarch/atdd/validation-report-20260127-095021.md +73 -0
- package/src/workflows/testarch/atdd/validation-report-20260127-102401.md +116 -0
- package/src/workflows/testarch/atdd/workflow-plan.md +21 -0
- package/src/workflows/testarch/atdd/workflow.md +39 -0
- package/src/workflows/testarch/atdd/workflow.yaml +47 -0
- package/src/workflows/testarch/automate/checklist.md +582 -0
- package/src/workflows/testarch/automate/instructions.md +43 -0
- package/src/workflows/testarch/automate/steps-c/step-01-preflight-and-context.md +127 -0
- package/src/workflows/testarch/automate/steps-c/step-02-identify-targets.md +95 -0
- package/src/workflows/testarch/automate/steps-c/step-03-generate-tests.md +199 -0
- package/src/workflows/testarch/automate/steps-c/step-03a-subprocess-api.md +183 -0
- package/src/workflows/testarch/automate/steps-c/step-03b-subprocess-e2e.md +181 -0
- package/src/workflows/testarch/automate/steps-c/step-03c-aggregate.md +300 -0
- package/src/workflows/testarch/automate/steps-c/step-04-validate-and-summarize.md +69 -0
- package/src/workflows/testarch/automate/steps-e/step-01-assess.md +65 -0
- package/src/workflows/testarch/automate/steps-e/step-02-apply-edit.md +60 -0
- package/src/workflows/testarch/automate/steps-v/step-01-validate.md +67 -0
- package/src/workflows/testarch/automate/validation-report-20260127-095021.md +72 -0
- package/src/workflows/testarch/automate/validation-report-20260127-102401.md +114 -0
- package/src/workflows/testarch/automate/workflow-plan.md +20 -0
- package/src/workflows/testarch/automate/workflow.md +39 -0
- package/src/workflows/testarch/automate/workflow.yaml +54 -0
- package/src/workflows/testarch/ci/checklist.md +247 -0
- package/src/workflows/testarch/ci/github-actions-template.yaml +198 -0
- package/src/workflows/testarch/ci/gitlab-ci-template.yaml +149 -0
- package/src/workflows/testarch/ci/instructions.md +38 -0
- package/src/workflows/testarch/ci/steps-c/step-01-preflight.md +92 -0
- package/src/workflows/testarch/ci/steps-c/step-02-generate-pipeline.md +82 -0
- package/src/workflows/testarch/ci/steps-c/step-03-configure-quality-gates.md +75 -0
- package/src/workflows/testarch/ci/steps-c/step-04-validate-and-summary.md +67 -0
- package/src/workflows/testarch/ci/steps-e/step-01-assess.md +65 -0
- package/src/workflows/testarch/ci/steps-e/step-02-apply-edit.md +60 -0
- package/src/workflows/testarch/ci/steps-v/step-01-validate.md +67 -0
- package/src/workflows/testarch/ci/validation-report-20260127-095021.md +72 -0
- package/src/workflows/testarch/ci/validation-report-20260127-102401.md +114 -0
- package/src/workflows/testarch/ci/workflow-plan.md +20 -0
- package/src/workflows/testarch/ci/workflow.md +39 -0
- package/src/workflows/testarch/ci/workflow.yaml +47 -0
- package/src/workflows/testarch/framework/checklist.md +320 -0
- package/src/workflows/testarch/framework/instructions.md +38 -0
- package/src/workflows/testarch/framework/steps-c/step-01-preflight.md +75 -0
- package/src/workflows/testarch/framework/steps-c/step-02-select-framework.md +73 -0
- package/src/workflows/testarch/framework/steps-c/step-03-scaffold-framework.md +120 -0
- package/src/workflows/testarch/framework/steps-c/step-04-docs-and-scripts.md +70 -0
- package/src/workflows/testarch/framework/steps-c/step-05-validate-and-summary.md +68 -0
- package/src/workflows/testarch/framework/steps-e/step-01-assess.md +65 -0
- package/src/workflows/testarch/framework/steps-e/step-02-apply-edit.md +60 -0
- package/src/workflows/testarch/framework/steps-v/step-01-validate.md +67 -0
- package/src/workflows/testarch/framework/validation-report-20260127-095021.md +73 -0
- package/src/workflows/testarch/framework/validation-report-20260127-102401.md +116 -0
- package/src/workflows/testarch/framework/workflow-plan.md +22 -0
- package/src/workflows/testarch/framework/workflow.md +39 -0
- package/src/workflows/testarch/framework/workflow.yaml +49 -0
- package/src/workflows/testarch/nfr-assess/checklist.md +407 -0
- package/src/workflows/testarch/nfr-assess/instructions.md +36 -0
- package/src/workflows/testarch/nfr-assess/nfr-report-template.md +462 -0
- package/src/workflows/testarch/nfr-assess/steps-c/step-01-load-context.md +85 -0
- package/src/workflows/testarch/nfr-assess/steps-c/step-02-define-thresholds.md +82 -0
- package/src/workflows/testarch/nfr-assess/steps-c/step-03-gather-evidence.md +64 -0
- package/src/workflows/testarch/nfr-assess/steps-c/step-04-evaluate-and-score.md +140 -0
- package/src/workflows/testarch/nfr-assess/steps-c/step-04a-subprocess-security.md +138 -0
- package/src/workflows/testarch/nfr-assess/steps-c/step-04b-subprocess-performance.md +84 -0
- package/src/workflows/testarch/nfr-assess/steps-c/step-04c-subprocess-reliability.md +85 -0
- package/src/workflows/testarch/nfr-assess/steps-c/step-04d-subprocess-scalability.md +88 -0
- package/src/workflows/testarch/nfr-assess/steps-c/step-04e-aggregate-nfr.md +219 -0
- package/src/workflows/testarch/nfr-assess/steps-c/step-05-generate-report.md +71 -0
- package/src/workflows/testarch/nfr-assess/steps-e/step-01-assess.md +65 -0
- package/src/workflows/testarch/nfr-assess/steps-e/step-02-apply-edit.md +60 -0
- package/src/workflows/testarch/nfr-assess/steps-v/step-01-validate.md +67 -0
- package/src/workflows/testarch/nfr-assess/validation-report-20260127-095021.md +73 -0
- package/src/workflows/testarch/nfr-assess/validation-report-20260127-102401.md +116 -0
- package/src/workflows/testarch/nfr-assess/workflow-plan.md +19 -0
- package/src/workflows/testarch/nfr-assess/workflow.md +39 -0
- package/src/workflows/testarch/nfr-assess/workflow.yaml +49 -0
- package/src/workflows/testarch/test-design/checklist.md +410 -0
- package/src/workflows/testarch/test-design/instructions.md +52 -0
- package/src/workflows/testarch/test-design/steps-c/step-01-detect-mode.md +109 -0
- package/src/workflows/testarch/test-design/steps-c/step-02-load-context.md +127 -0
- package/src/workflows/testarch/test-design/steps-c/step-03-risk-and-testability.md +85 -0
- package/src/workflows/testarch/test-design/steps-c/step-04-coverage-plan.md +98 -0
- package/src/workflows/testarch/test-design/steps-c/step-05-generate-output.md +97 -0
- package/src/workflows/testarch/test-design/steps-e/step-01-assess.md +65 -0
- package/src/workflows/testarch/test-design/steps-e/step-02-apply-edit.md +60 -0
- package/src/workflows/testarch/test-design/steps-v/step-01-validate.md +67 -0
- package/src/workflows/testarch/test-design/test-design-architecture-template.md +222 -0
- package/src/workflows/testarch/test-design/test-design-qa-template.md +296 -0
- package/src/workflows/testarch/test-design/test-design-template.md +294 -0
- package/src/workflows/testarch/test-design/validation-report-20260127-095021.md +73 -0
- package/src/workflows/testarch/test-design/validation-report-20260127-102401.md +116 -0
- package/src/workflows/testarch/test-design/workflow-plan.md +22 -0
- package/src/workflows/testarch/test-design/workflow.md +39 -0
- package/src/workflows/testarch/test-design/workflow.yaml +71 -0
- package/src/workflows/testarch/test-review/checklist.md +472 -0
- package/src/workflows/testarch/test-review/instructions.md +36 -0
- package/src/workflows/testarch/test-review/steps-c/step-01-load-context.md +101 -0
- package/src/workflows/testarch/test-review/steps-c/step-02-discover-tests.md +69 -0
- package/src/workflows/testarch/test-review/steps-c/step-03-quality-evaluation.md +184 -0
- package/src/workflows/testarch/test-review/steps-c/step-03a-subprocess-determinism.md +214 -0
- package/src/workflows/testarch/test-review/steps-c/step-03b-subprocess-isolation.md +125 -0
- package/src/workflows/testarch/test-review/steps-c/step-03c-subprocess-maintainability.md +102 -0
- package/src/workflows/testarch/test-review/steps-c/step-03d-subprocess-coverage.md +111 -0
- package/src/workflows/testarch/test-review/steps-c/step-03e-subprocess-performance.md +117 -0
- package/src/workflows/testarch/test-review/steps-c/step-03f-aggregate-scores.md +246 -0
- package/src/workflows/testarch/test-review/steps-c/step-04-generate-report.md +72 -0
- package/src/workflows/testarch/test-review/steps-e/step-01-assess.md +65 -0
- package/src/workflows/testarch/test-review/steps-e/step-02-apply-edit.md +60 -0
- package/src/workflows/testarch/test-review/steps-v/step-01-validate.md +67 -0
- package/src/workflows/testarch/test-review/test-review-template.md +390 -0
- package/src/workflows/testarch/test-review/validation-report-20260127-095021.md +72 -0
- package/src/workflows/testarch/test-review/validation-report-20260127-102401.md +114 -0
- package/src/workflows/testarch/test-review/workflow-plan.md +18 -0
- package/src/workflows/testarch/test-review/workflow.md +39 -0
- package/src/workflows/testarch/test-review/workflow.yaml +48 -0
- package/src/workflows/testarch/trace/checklist.md +642 -0
- package/src/workflows/testarch/trace/instructions.md +36 -0
- package/src/workflows/testarch/trace/steps-c/step-01-load-context.md +80 -0
- package/src/workflows/testarch/trace/steps-c/step-02-discover-tests.md +69 -0
- package/src/workflows/testarch/trace/steps-c/step-03-map-criteria.md +65 -0
- package/src/workflows/testarch/trace/steps-c/step-04-analyze-gaps.md +244 -0
- package/src/workflows/testarch/trace/steps-c/step-05-gate-decision.md +232 -0
- package/src/workflows/testarch/trace/steps-e/step-01-assess.md +65 -0
- package/src/workflows/testarch/trace/steps-e/step-02-apply-edit.md +60 -0
- package/src/workflows/testarch/trace/steps-v/step-01-validate.md +67 -0
- package/src/workflows/testarch/trace/trace-template.md +675 -0
- package/src/workflows/testarch/trace/validation-report-20260127-095021.md +73 -0
- package/src/workflows/testarch/trace/validation-report-20260127-102401.md +116 -0
- package/src/workflows/testarch/trace/workflow-plan.md +21 -0
- package/src/workflows/testarch/trace/workflow.md +39 -0
- package/src/workflows/testarch/trace/workflow.yaml +57 -0
- package/test/README.md +23 -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/schema/agent.js +491 -0
- package/test/test-agent-schema.js +387 -0
- package/test/test-installation-components.js +183 -0
- package/test/test-knowledge-base.js +199 -0
- package/test/unit-test-schema.js +133 -0
- package/test/validate-agent-schema.js +110 -0
- package/tools/build-docs.js +575 -0
- package/tools/fix-doc-links.js +288 -0
- package/tools/schema/agent.js +491 -0
- package/tools/validate-agent-schema.js +111 -0
- package/tools/validate-doc-links.js +371 -0
- package/tools/verify-paths.js +100 -0
- package/website/README.md +137 -0
- package/website/astro.config.mjs +158 -0
- package/website/package-lock.json +6856 -0
- package/website/package.json +23 -0
- package/website/public/favicon.ico +0 -0
- package/website/public/img/tea-logo.svg +7 -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/pages/404.astro +11 -0
- package/website/src/rehype-base-paths.js +89 -0
- package/website/src/rehype-markdown-links.js +117 -0
- package/website/src/styles/custom.css +499 -0
- package/website/tsconfig.json +9 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fix Documentation Links
|
|
3
|
+
*
|
|
4
|
+
* Converts relative markdown links to repo-relative paths with .md extension.
|
|
5
|
+
* This ensures links work both in GitHub and on the Astro/Starlight site
|
|
6
|
+
* (the rehype plugin transforms /docs/path/file.md → /path/file/ at build time).
|
|
7
|
+
*
|
|
8
|
+
* - ./file.md → /docs/current/path/file.md
|
|
9
|
+
* - ../other/file.md → /docs/resolved/path/file.md
|
|
10
|
+
* - /path/file/ → /docs/path/file.md (or /docs/path/file/index.md if it's a directory)
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* node tools/fix-doc-links.js # Dry run (shows what would change)
|
|
14
|
+
* node tools/fix-doc-links.js --write # Actually write changes
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const fs = require('node:fs');
|
|
18
|
+
const path = require('node:path');
|
|
19
|
+
|
|
20
|
+
const DOCS_ROOT = path.resolve(__dirname, '../docs');
|
|
21
|
+
const DRY_RUN = !process.argv.includes('--write');
|
|
22
|
+
|
|
23
|
+
// Regex to match markdown links:
|
|
24
|
+
// - [text](path.md) or [text](path.md#anchor) - existing .md links
|
|
25
|
+
// - [text](/path/to/page/) or [text](/path/to/page/#anchor) - site-relative links to convert
|
|
26
|
+
const MARKDOWN_LINK_REGEX = /\[([^\]]*)\]\(([^)]+(?:\.md|\/))(?:#[^)]*)?(?:\?[^)]*)?\)/g;
|
|
27
|
+
// Simpler approach: match all markdown links and filter in the handler
|
|
28
|
+
const ALL_MARKDOWN_LINKS_REGEX = /\[([^\]]*)\]\(([^)]+)\)/g;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get all markdown files in docs directory, excluding _* directories/files
|
|
32
|
+
*/
|
|
33
|
+
function getMarkdownFiles(dir) {
|
|
34
|
+
const files = [];
|
|
35
|
+
|
|
36
|
+
function walk(currentDir) {
|
|
37
|
+
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
38
|
+
|
|
39
|
+
for (const entry of entries) {
|
|
40
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
41
|
+
|
|
42
|
+
// Skip underscore-prefixed entries
|
|
43
|
+
if (entry.name.startsWith('_')) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (entry.isDirectory()) {
|
|
48
|
+
walk(fullPath);
|
|
49
|
+
} else if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
50
|
+
files.push(fullPath);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
walk(dir);
|
|
56
|
+
return files;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Convert a markdown link href to repo-relative path with .md extension
|
|
61
|
+
*
|
|
62
|
+
* @param {string} href - The original href (e.g., "./file.md", "/path/to/page/", "/path/to/page/#anchor")
|
|
63
|
+
* @param {string} currentFilePath - Absolute path to the file containing this link
|
|
64
|
+
* @returns {string|null} - Repo-relative path (e.g., "/docs/path/to/file.md"), or null if shouldn't be converted
|
|
65
|
+
*/
|
|
66
|
+
function convertToRepoRelative(href, currentFilePath) {
|
|
67
|
+
// Skip external links
|
|
68
|
+
if (href.includes('://') || href.startsWith('mailto:') || href.startsWith('tel:')) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Skip anchor-only links
|
|
73
|
+
if (href.startsWith('#')) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Extract anchor and query string if present
|
|
78
|
+
let anchor = '';
|
|
79
|
+
let query = '';
|
|
80
|
+
let pathPortion = href;
|
|
81
|
+
|
|
82
|
+
const hashIndex = href.indexOf('#');
|
|
83
|
+
const queryIndex = href.indexOf('?');
|
|
84
|
+
|
|
85
|
+
if (hashIndex !== -1 || queryIndex !== -1) {
|
|
86
|
+
const firstDelimiter = Math.min(hashIndex === -1 ? Infinity : hashIndex, queryIndex === -1 ? Infinity : queryIndex);
|
|
87
|
+
pathPortion = href.slice(0, Math.max(0, firstDelimiter));
|
|
88
|
+
|
|
89
|
+
const suffix = href.slice(Math.max(0, firstDelimiter));
|
|
90
|
+
const anchorInSuffix = suffix.indexOf('#');
|
|
91
|
+
|
|
92
|
+
if (suffix.startsWith('?')) {
|
|
93
|
+
if (anchorInSuffix === -1) {
|
|
94
|
+
query = suffix;
|
|
95
|
+
} else {
|
|
96
|
+
query = suffix.slice(0, Math.max(0, anchorInSuffix));
|
|
97
|
+
anchor = suffix.slice(Math.max(0, anchorInSuffix));
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
anchor = suffix;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Skip non-documentation links (images, external assets, etc.)
|
|
105
|
+
const ext = path.extname(pathPortion).toLowerCase();
|
|
106
|
+
if (
|
|
107
|
+
ext &&
|
|
108
|
+
ext !== '.md' &&
|
|
109
|
+
!['.md'].includes(ext) && // Has an extension that's not .md - skip unless it's a trailing slash path
|
|
110
|
+
!pathPortion.endsWith('/')
|
|
111
|
+
) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Check if original path ends with / (directory reference) BEFORE path.join normalizes it
|
|
116
|
+
const isDirectoryPath = pathPortion.endsWith('/');
|
|
117
|
+
|
|
118
|
+
let absolutePath;
|
|
119
|
+
|
|
120
|
+
if (pathPortion.startsWith('/docs/')) {
|
|
121
|
+
// Already repo-relative with /docs/ prefix
|
|
122
|
+
absolutePath = path.join(path.dirname(DOCS_ROOT), pathPortion);
|
|
123
|
+
} else if (pathPortion.startsWith('/')) {
|
|
124
|
+
// Site-relative (e.g., /tutorials/getting-started/) - resolve from docs root
|
|
125
|
+
absolutePath = path.join(DOCS_ROOT, pathPortion);
|
|
126
|
+
} else {
|
|
127
|
+
// Relative path (./, ../, or bare filename) - resolve from current file's directory
|
|
128
|
+
const currentDir = path.dirname(currentFilePath);
|
|
129
|
+
absolutePath = path.resolve(currentDir, pathPortion);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Convert to repo-relative path (with /docs/ prefix)
|
|
133
|
+
let repoRelative = '/docs/' + path.relative(DOCS_ROOT, absolutePath);
|
|
134
|
+
|
|
135
|
+
// Normalize path separators for Windows
|
|
136
|
+
repoRelative = repoRelative.split(path.sep).join('/');
|
|
137
|
+
|
|
138
|
+
// If original path was a directory reference (ended with /), check for index.md or file.md
|
|
139
|
+
if (isDirectoryPath) {
|
|
140
|
+
const relativeDir = repoRelative.slice(6); // Remove '/docs/'
|
|
141
|
+
|
|
142
|
+
// Handle root path case (relativeDir is empty or just '.')
|
|
143
|
+
const normalizedDir = relativeDir === '' || relativeDir === '.' ? '' : relativeDir;
|
|
144
|
+
const indexPath = path.join(DOCS_ROOT, normalizedDir, 'index.md');
|
|
145
|
+
const filePath = normalizedDir ? path.join(DOCS_ROOT, normalizedDir + '.md') : null;
|
|
146
|
+
|
|
147
|
+
if (fs.existsSync(indexPath)) {
|
|
148
|
+
// Avoid double slash when repoRelative is '/docs/' (root case)
|
|
149
|
+
repoRelative = repoRelative.endsWith('/') ? repoRelative + 'index.md' : repoRelative + '/index.md';
|
|
150
|
+
} else if (filePath && fs.existsSync(filePath)) {
|
|
151
|
+
repoRelative = repoRelative + '.md';
|
|
152
|
+
} else {
|
|
153
|
+
// Neither exists - default to index.md and let validation catch it
|
|
154
|
+
repoRelative = repoRelative.endsWith('/') ? repoRelative + 'index.md' : repoRelative + '/index.md';
|
|
155
|
+
}
|
|
156
|
+
} else if (!repoRelative.endsWith('.md')) {
|
|
157
|
+
// Path doesn't end with .md - add .md
|
|
158
|
+
repoRelative = repoRelative + '.md';
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return repoRelative + query + anchor;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Process a single markdown file, skipping links inside fenced code blocks
|
|
166
|
+
*
|
|
167
|
+
* @param {string} filePath - Absolute path to the file
|
|
168
|
+
* @returns {Object} - { changed: boolean, original: string, updated: string, changes: Array }
|
|
169
|
+
*/
|
|
170
|
+
function processFile(filePath) {
|
|
171
|
+
const original = fs.readFileSync(filePath, 'utf-8');
|
|
172
|
+
const changes = [];
|
|
173
|
+
|
|
174
|
+
// Extract fenced code blocks and replace with placeholders
|
|
175
|
+
const codeBlocks = [];
|
|
176
|
+
const CODE_PLACEHOLDER = '\u0000CODE_BLOCK_';
|
|
177
|
+
|
|
178
|
+
let contentWithPlaceholders = original.replaceAll(/```[\s\S]*?```/g, (match) => {
|
|
179
|
+
const index = codeBlocks.length;
|
|
180
|
+
codeBlocks.push(match);
|
|
181
|
+
return `${CODE_PLACEHOLDER}${index}\u0000`;
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Process links only in non-code-block content
|
|
185
|
+
contentWithPlaceholders = contentWithPlaceholders.replaceAll(ALL_MARKDOWN_LINKS_REGEX, (match, linkText, href) => {
|
|
186
|
+
const newHref = convertToRepoRelative(href, filePath);
|
|
187
|
+
|
|
188
|
+
// Skip if conversion returned null (external link, anchor, etc.)
|
|
189
|
+
if (newHref === null) {
|
|
190
|
+
return match;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Only record as change if actually different
|
|
194
|
+
if (newHref !== href) {
|
|
195
|
+
changes.push({ from: href, to: newHref });
|
|
196
|
+
return `[${linkText}](${newHref})`;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return match;
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// Restore code blocks
|
|
203
|
+
const updated = contentWithPlaceholders.replaceAll(
|
|
204
|
+
new RegExp(`${CODE_PLACEHOLDER}(\\d+)\u0000`, 'g'),
|
|
205
|
+
(match, index) => codeBlocks[parseInt(index, 10)],
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
changed: changes.length > 0,
|
|
210
|
+
original,
|
|
211
|
+
updated,
|
|
212
|
+
changes,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Validate that a repo-relative link points to an existing file
|
|
218
|
+
*/
|
|
219
|
+
function validateLink(repoRelativePath) {
|
|
220
|
+
// Strip anchor/query
|
|
221
|
+
const checkPath = repoRelativePath.split('#')[0].split('?')[0];
|
|
222
|
+
|
|
223
|
+
// Remove /docs/ prefix to get path relative to DOCS_ROOT
|
|
224
|
+
const relativePath = checkPath.startsWith('/docs/') ? checkPath.slice(6) : checkPath.slice(1);
|
|
225
|
+
|
|
226
|
+
return fs.existsSync(path.join(DOCS_ROOT, relativePath));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Main execution
|
|
230
|
+
console.log(`\nScanning docs in: ${DOCS_ROOT}`);
|
|
231
|
+
console.log(`Mode: ${DRY_RUN ? 'DRY RUN (use --write to apply changes)' : 'WRITE MODE'}\n`);
|
|
232
|
+
|
|
233
|
+
const files = getMarkdownFiles(DOCS_ROOT);
|
|
234
|
+
console.log(`Found ${files.length} markdown files (excluding _* paths)\n`);
|
|
235
|
+
|
|
236
|
+
let totalChanges = 0;
|
|
237
|
+
let filesChanged = 0;
|
|
238
|
+
const brokenLinks = [];
|
|
239
|
+
|
|
240
|
+
for (const filePath of files) {
|
|
241
|
+
const relativePath = path.relative(DOCS_ROOT, filePath);
|
|
242
|
+
const result = processFile(filePath);
|
|
243
|
+
|
|
244
|
+
if (result.changed) {
|
|
245
|
+
filesChanged++;
|
|
246
|
+
totalChanges += result.changes.length;
|
|
247
|
+
|
|
248
|
+
console.log(`\n${relativePath}`);
|
|
249
|
+
for (const change of result.changes) {
|
|
250
|
+
const isValid = validateLink(change.to);
|
|
251
|
+
const status = isValid ? ' ' : '! ';
|
|
252
|
+
|
|
253
|
+
console.log(`${status} ${change.from}`);
|
|
254
|
+
console.log(` -> ${change.to}`);
|
|
255
|
+
|
|
256
|
+
if (!isValid) {
|
|
257
|
+
brokenLinks.push({
|
|
258
|
+
file: relativePath,
|
|
259
|
+
link: change.to,
|
|
260
|
+
original: change.from,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (!DRY_RUN) {
|
|
266
|
+
fs.writeFileSync(filePath, result.updated, 'utf-8');
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
console.log(`\n${'─'.repeat(60)}`);
|
|
272
|
+
console.log(`\nSummary:`);
|
|
273
|
+
console.log(` Files scanned: ${files.length}`);
|
|
274
|
+
console.log(` Files with changes: ${filesChanged}`);
|
|
275
|
+
console.log(` Total link updates: ${totalChanges}`);
|
|
276
|
+
|
|
277
|
+
if (brokenLinks.length > 0) {
|
|
278
|
+
console.log(`\n! Potential broken links (${brokenLinks.length}):`);
|
|
279
|
+
for (const bl of brokenLinks) {
|
|
280
|
+
console.log(` ${bl.file}: ${bl.link}`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (DRY_RUN && totalChanges > 0) {
|
|
285
|
+
console.log(`\nRun with --write to apply these changes`);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
console.log('');
|