From e3f756488aa8cee45f16c87cb777cd2ec6b6f609 Mon Sep 17 00:00:00 2001 From: Alex Verkhovsky Date: Sat, 6 Dec 2025 10:40:07 -0800 Subject: [PATCH] feat(quality): add markdownlint-cli2 to quality checks (#1039) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add markdownlint-cli2 as dev dependency - Add lint:md script to package.json - Add markdownlint job to CI workflow - Configure 5 rules: heading-increment, no-duplicate-heading, no-trailing-punctuation, no-bare-urls, no-space-in-emphasis - Fix existing violations across 19 markdown files - No auto-fix to prevent destructive changes Closes #1034 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Co-authored-by: Brian --- .github/ISSUE_TEMPLATE/idea_submission.md | 2 +- .github/workflows/quality.yaml | 19 + .markdownlint-cli2.yaml | 42 ++ package-lock.json | 445 +++++++++++++++++- package.json | 10 +- .../resources/excalidraw/library-loader.md | 4 +- .../steps/step-01-session-setup.md | 2 +- .../docs/agents/module-agent-architecture.md | 2 +- .../docs/workflows/templates/step-template.md | 4 +- .../steps/step-05-shopping.md | 2 +- .../steps/step-05-shopping.md | 2 +- .../create-workflow/steps/step-09-complete.md | 2 +- .../edit-agent/steps/step-02-analyze-agent.md | 4 +- .../edit-workflow/steps/step-04-validate.md | 2 +- src/modules/bmm/docs/faq.md | 2 +- src/modules/bmm/docs/images/README.md | 2 +- src/modules/bmm/docs/test-architecture.md | 12 +- .../workflow-document-project-reference.md | 2 +- .../bmm/testarch/knowledge/ci-burn-in.md | 2 +- .../bmm/testarch/knowledge/overview.md | 2 +- .../workflows/deep-dive-instructions.md | 4 +- .../bmm/workflows/testarch/ci/checklist.md | 2 +- .../testarch/test-review/instructions.md | 2 +- tools/cli/README.md | 6 +- 24 files changed, 543 insertions(+), 35 deletions(-) create mode 100644 .markdownlint-cli2.yaml diff --git a/.github/ISSUE_TEMPLATE/idea_submission.md b/.github/ISSUE_TEMPLATE/idea_submission.md index aec346ae..6ab26d5b 100644 --- a/.github/ISSUE_TEMPLATE/idea_submission.md +++ b/.github/ISSUE_TEMPLATE/idea_submission.md @@ -8,7 +8,7 @@ assignees: '' # Idea: [Replace with a clear, actionable title] -### PASS Framework +## PASS Framework **P**roblem: diff --git a/.github/workflows/quality.yaml b/.github/workflows/quality.yaml index fc750b62..8111ca44 100644 --- a/.github/workflows/quality.yaml +++ b/.github/workflows/quality.yaml @@ -3,6 +3,7 @@ name: Quality & Validation # Runs comprehensive quality checks on all PRs: # - Prettier (formatting) # - ESLint (linting) +# - markdownlint (markdown quality) # - Schema validation (YAML structure) # - Agent schema tests (fixture-based validation) # - Installation component tests (compilation) @@ -50,6 +51,24 @@ jobs: - name: ESLint run: npm run lint + markdownlint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: markdownlint + run: npm run lint:md + validate: runs-on: ubuntu-latest steps: diff --git a/.markdownlint-cli2.yaml b/.markdownlint-cli2.yaml new file mode 100644 index 00000000..84d44c7d --- /dev/null +++ b/.markdownlint-cli2.yaml @@ -0,0 +1,42 @@ +# markdownlint-cli2 configuration +# https://github.com/DavidAnson/markdownlint-cli2 + +ignores: + - node_modules/** + - test/fixtures/** + - CODE_OF_CONDUCT.md + - .bmad/** + - .bmad*/** + - .agent/** + - .claude/** + - .roo/** + - .codex/** + - .agentvibes/** + - .kiro/** + - sample-project/** + - test-project-install/** + - z*/** + +# Rule configuration +config: + # Disable all rules by default + default: false + + # Heading levels should increment by one (h1 -> h2 -> h3, not h1 -> h3) + MD001: true + + # Duplicate sibling headings (same heading text at same level under same parent) + MD024: + siblings_only: true + + # Trailing commas in headings (likely typos) + MD026: + punctuation: "," + + # Bare URLs - may not render as links in all parsers + # Should use or [text](url) format + MD034: true + + # Spaces inside emphasis markers - breaks rendering + # e.g., "* text *" won't render as emphasis + MD037: true diff --git a/package-lock.json b/package-lock.json index 80746370..1001ce87 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "bmad-method", - "version": "6.0.0-alpha.12", + "version": "6.0.0-alpha.13", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "bmad-method", - "version": "6.0.0-alpha.12", + "version": "6.0.0-alpha.13", "license": "MIT", "dependencies": { "@kayvan/markdown-tree-parser": "^1.6.1", @@ -42,6 +42,7 @@ "husky": "^9.1.7", "jest": "^30.0.4", "lint-staged": "^16.1.1", + "markdownlint-cli2": "^0.19.1", "prettier": "^3.5.3", "prettier-plugin-packagejson": "^2.5.19", "yaml-eslint-parser": "^1.2.3", @@ -97,6 +98,7 @@ "integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", @@ -1672,6 +1674,19 @@ "dev": true, "license": "MIT" }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -1798,6 +1813,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/katex": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", + "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -1819,6 +1841,7 @@ "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.10.0" } @@ -2135,6 +2158,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2496,6 +2520,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001735", "electron-to-chromium": "^1.5.204", @@ -2793,6 +2818,28 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chardet": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.0.tgz", @@ -3298,6 +3345,19 @@ "node": ">=10.13.0" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/environment": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", @@ -3350,6 +3410,7 @@ "integrity": "sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", @@ -4421,6 +4482,32 @@ "node": ">=8" } }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -4444,6 +4531,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -4490,6 +4588,17 @@ "node": ">=0.10.0" } }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -5478,6 +5587,13 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, "node_modules/jsonfile": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", @@ -5490,6 +5606,33 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/katex": { + "version": "0.16.25", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.25.tgz", + "integrity": "sha512-woHRUZ/iF23GBP1dkDQMh1QBad9dmr8/PAwNA54VrSOVYgI12MAcE14TqnDdQOdzyEonGzMepYnqBMYdsoAr8Q==", + "dev": true, + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -5544,6 +5687,16 @@ "dev": true, "license": "MIT" }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/lint-staged": { "version": "16.1.5", "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.1.5.tgz", @@ -5988,6 +6141,132 @@ "tmpl": "1.0.5" } }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdownlint": { + "version": "0.39.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.39.0.tgz", + "integrity": "sha512-Xt/oY7bAiHwukL1iru2np5LIkhwD19Y7frlsiDILK62v3jucXCD6JXlZlwMG12HZOR+roHIVuJZrfCkOhp6k3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark": "4.0.2", + "micromark-core-commonmark": "2.0.3", + "micromark-extension-directive": "4.0.0", + "micromark-extension-gfm-autolink-literal": "2.1.0", + "micromark-extension-gfm-footnote": "2.1.0", + "micromark-extension-gfm-table": "2.1.1", + "micromark-extension-math": "3.1.0", + "micromark-util-types": "2.0.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli2": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.19.1.tgz", + "integrity": "sha512-p3JTemJJbkiMjXEMiFwgm0v6ym5g8K+b2oDny+6xdl300tUKySxvilJQLSea48C6OaYNmO30kH9KxpiAg5bWJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "globby": "15.0.0", + "js-yaml": "4.1.1", + "jsonc-parser": "3.3.1", + "markdown-it": "14.1.0", + "markdownlint": "0.39.0", + "markdownlint-cli2-formatter-default": "0.0.6", + "micromatch": "4.0.8" + }, + "bin": { + "markdownlint-cli2": "markdownlint-cli2-bin.mjs" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli2-formatter-default": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.6.tgz", + "integrity": "sha512-VVDGKsq9sgzu378swJ0fcHfSicUnMxnL8gnLm/Q4J/xsNJ4e5bA6lvAz7PCzIl0/No0lHyaWdqVD2jotxOSFMQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + }, + "peerDependencies": { + "markdownlint-cli2": ">=0.0.4" + } + }, + "node_modules/markdownlint-cli2/node_modules/globby": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-15.0.0.tgz", + "integrity": "sha512-oB4vkQGqlMl682wL1IlWd02tXCbquGWM4voPEI85QmNKCaw8zGTm1f1rubFgkg3Eli2PtKlFgrnmUqasbQWlkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.5", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdownlint-cli2/node_modules/path-type": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdownlint-cli2/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mdast-util-from-markdown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", @@ -6060,6 +6339,13 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -6146,6 +6432,102 @@ "micromark-util-types": "^2.0.0" } }, + "node_modules/micromark-extension-directive": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-4.0.0.tgz", + "integrity": "sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/micromark-factory-destination": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", @@ -6868,6 +7250,33 @@ "node": ">=6" } }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "dev": true, + "license": "MIT" + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -7089,6 +7498,7 @@ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -7156,6 +7566,16 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/pure-rand": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", @@ -7911,6 +8331,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -8040,6 +8461,13 @@ "node": ">=14.17" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, "node_modules/undici-types": { "version": "7.10.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", @@ -8047,6 +8475,19 @@ "devOptional": true, "license": "MIT" }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/unified": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", diff --git a/package.json b/package.json index d452a763..b3031495 100644 --- a/package.json +++ b/package.json @@ -34,13 +34,14 @@ "install:bmad": "node tools/cli/bmad-cli.js install", "lint": "eslint . --ext .js,.cjs,.mjs,.yaml --max-warnings=0", "lint:fix": "eslint . --ext .js,.cjs,.mjs,.yaml --fix", + "lint:md": "markdownlint-cli2 \"**/*.md\"", "prepare": "husky", "rebundle": "node tools/cli/bundlers/bundle-web.js rebundle", "release:major": "gh workflow run \"Manual Release\" -f version_bump=major", "release:minor": "gh workflow run \"Manual Release\" -f version_bump=minor", "release:patch": "gh workflow run \"Manual Release\" -f version_bump=patch", "release:watch": "gh run watch", - "test": "npm run test:schemas && npm run test:install && npm run validate:bundles && npm run validate:schemas && npm run lint && npm run format:check", + "test": "npm run test:schemas && npm run test:install && npm run validate:bundles && npm run validate:schemas && npm run lint && npm run lint:md && npm run format:check", "test:coverage": "c8 --reporter=text --reporter=html npm run test:schemas", "test:install": "node test/test-installation-components.js", "test:schemas": "node test/test-agent-schema.js", @@ -56,7 +57,11 @@ "eslint --fix", "npm run format:fix" ], - "*.{json,md}": [ + "*.json": [ + "npm run format:fix" + ], + "*.md": [ + "markdownlint-cli2", "npm run format:fix" ] }, @@ -90,6 +95,7 @@ "husky": "^9.1.7", "jest": "^30.0.4", "lint-staged": "^16.1.1", + "markdownlint-cli2": "^0.19.1", "prettier": "^3.5.3", "prettier-plugin-packagejson": "^2.5.19", "yaml-eslint-parser": "^1.2.3", diff --git a/src/core/resources/excalidraw/library-loader.md b/src/core/resources/excalidraw/library-loader.md index 6a66c963..6fe5ea07 100644 --- a/src/core/resources/excalidraw/library-loader.md +++ b/src/core/resources/excalidraw/library-loader.md @@ -4,7 +4,7 @@ ## Purpose -Load external .excalidrawlib files from https://libraries.excalidraw.com or custom sources. +Load external .excalidrawlib files from or custom sources. ## Planned Capabilities @@ -34,7 +34,7 @@ libraries: ## Implementation Notes -This will be developed when agents need to leverage the extensive library ecosystem available at https://libraries.excalidraw.com. +This will be developed when agents need to leverage the extensive library ecosystem available at . Hundreds of pre-built component libraries exist for: diff --git a/src/core/workflows/brainstorming/steps/step-01-session-setup.md b/src/core/workflows/brainstorming/steps/step-01-session-setup.md index 32052106..54a0f636 100644 --- a/src/core/workflows/brainstorming/steps/step-01-session-setup.md +++ b/src/core/workflows/brainstorming/steps/step-01-session-setup.md @@ -135,7 +135,7 @@ _[Content based on conversation about session parameters and facilitator approac When user selects approach, append the session overview content directly to `{output_folder}/analysis/brainstorming-session-{{date}}.md` using the structure from above. -#### E. Continue to Technique Selection +### E. Continue to Technique Selection "**Session setup complete!** I have a clear understanding of your goals and can select the perfect techniques for your brainstorming needs. diff --git a/src/modules/bmb/docs/agents/module-agent-architecture.md b/src/modules/bmb/docs/agents/module-agent-architecture.md index 490782bd..acbaf457 100644 --- a/src/modules/bmb/docs/agents/module-agent-architecture.md +++ b/src/modules/bmb/docs/agents/module-agent-architecture.md @@ -203,7 +203,7 @@ Module agents use the same injection process as simple agents: 2. **Activation block** with standard steps 3. **Menu handlers** based on usage (workflow, exec, tmpl, data) 4. **Rules section** for consistent behavior -5. **Auto-injected** *help and *exit commands +5. **Auto-injected** \*help and \*exit commands **Key difference:** Module agents load **module-specific config** instead of core config: diff --git a/src/modules/bmb/docs/workflows/templates/step-template.md b/src/modules/bmb/docs/workflows/templates/step-template.md index cc10e8e5..1c525e2c 100644 --- a/src/modules/bmb/docs/workflows/templates/step-template.md +++ b/src/modules/bmb/docs/workflows/templates/step-template.md @@ -149,13 +149,13 @@ ONLY WHEN [C continue option] is selected and [completion requirements], will yo -## Common Menu Patterns to use in the final sequence item in a step file. +## Common Menu Patterns to use in the final sequence item in a step file FYI Again - party mode is useful for the user to reach out and get opinions from other agents. Advanced elicitation is use to direct you to think of alternative outputs of a sequence you just performed. -### Standard Menu - when a sequence in a step results in content produced by the agent or human that could be improved before proceeding. +### Standard Menu - when a sequence in a step results in content produced by the agent or human that could be improved before proceeding ```markdown ### N. Present MENU OPTIONS diff --git a/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md b/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md index f08bc957..8fce50d4 100644 --- a/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md +++ b/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md @@ -132,7 +132,7 @@ You are a **strategic shopping partner** who: - Plans for real-life shopping scenarios - Minimizes food waste thoughtfully -## 📝 OUTPUT REQUIREMENTS: +## 📊 STATUS UPDATE: Update workflow.md frontmatter: diff --git a/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md b/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md index 4fc72b3a..95d33017 100644 --- a/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md +++ b/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md @@ -132,7 +132,7 @@ You are a **strategic shopping partner** who: - Plans for real-life shopping scenarios - Minimizes food waste thoughtfully -## 📝 OUTPUT REQUIREMENTS: +## 📊 STATUS UPDATE: Update workflow.md frontmatter: diff --git a/src/modules/bmb/workflows/create-workflow/steps/step-09-complete.md b/src/modules/bmb/workflows/create-workflow/steps/step-09-complete.md index f6985c4f..cb2708ed 100644 --- a/src/modules/bmb/workflows/create-workflow/steps/step-09-complete.md +++ b/src/modules/bmb/workflows/create-workflow/steps/step-09-complete.md @@ -156,7 +156,7 @@ Update {workflowPlanFile} frontmatter: Display: **Workflow Creation Complete!** [T] Test Workflow [M] Make Adjustments [D] Get Help -#### Menu Handling Logic: +### Menu Handling Logic: - IF T: Offer to run the newly created workflow with sample data - IF M: Offer to make specific adjustments to the workflow diff --git a/src/modules/bmb/workflows/edit-agent/steps/step-02-analyze-agent.md b/src/modules/bmb/workflows/edit-agent/steps/step-02-analyze-agent.md index 1803974c..b4a0d50b 100644 --- a/src/modules/bmb/workflows/edit-agent/steps/step-02-analyze-agent.md +++ b/src/modules/bmb/workflows/edit-agent/steps/step-02-analyze-agent.md @@ -85,9 +85,9 @@ Load the agent file from the path provided in step 1: - Load and read the .agent.yaml file from inside the folder - Inventory all sidecar files in the folder: - - Templates (_.md, _.txt) + - Templates (`_.md`, `_.txt`) - Documentation files - - Knowledge base files (_.csv, _.json, \*.yaml) + - Knowledge base files (`_.csv`, `_.json`, `*.yaml`) - Any other resources referenced by the agent - Note: Expert agent with sidecar structure diff --git a/src/modules/bmb/workflows/edit-workflow/steps/step-04-validate.md b/src/modules/bmb/workflows/edit-workflow/steps/step-04-validate.md index e16db35e..c2e67bca 100644 --- a/src/modules/bmb/workflows/edit-workflow/steps/step-04-validate.md +++ b/src/modules/bmb/workflows/edit-workflow/steps/step-04-validate.md @@ -152,7 +152,7 @@ Then load and append content from {completionTemplate} Display: **Select an Option:** [A] Advanced Elicitation [P] Party Mode [C] Continue -#### EXECUTION RULES: +### EXECUTION RULES: - ALWAYS halt and wait for user input after presenting menu - ONLY proceed to next step when user selects 'C' diff --git a/src/modules/bmm/docs/faq.md b/src/modules/bmm/docs/faq.md index 71b8e925..7766137e 100644 --- a/src/modules/bmm/docs/faq.md +++ b/src/modules/bmm/docs/faq.md @@ -532,7 +532,7 @@ Trust your expertise - BMM supports your decisions. ### Q: How do I report a bug or request a feature? -**A:** Open a GitHub issue at: https://github.com/bmad-code-org/BMAD-METHOD/issues +**A:** Open a GitHub issue at: Please include: diff --git a/src/modules/bmm/docs/images/README.md b/src/modules/bmm/docs/images/README.md index cc943e47..331fdd53 100644 --- a/src/modules/bmm/docs/images/README.md +++ b/src/modules/bmm/docs/images/README.md @@ -4,7 +4,7 @@ When you edit `workflow-method-greenfield.excalidraw`, regenerate the SVG: -1. Open https://excalidraw.com/ +1. Open 2. Load the `.excalidraw` file 3. Click menu (☰) → Export image → SVG 4. **Set "Scale" to 1x** (default is 2x) diff --git a/src/modules/bmm/docs/test-architecture.md b/src/modules/bmm/docs/test-architecture.md index 4c2a4de5..2ab2da3c 100644 --- a/src/modules/bmm/docs/test-architecture.md +++ b/src/modules/bmm/docs/test-architecture.md @@ -138,12 +138,12 @@ Epic/Release Gate → TEA: *nfr-assess, *trace Phase 2 (release decision) **Standard agents**: 1-3 workflows per phase **TEA**: 8 workflows across Phase 3, Phase 4, and Release Gate -| Phase | TEA Workflows | Frequency | Purpose | -| ----------- | ----------------------------------------------------- | ---------------- | ---------------------------------------------- | -| **Phase 2** | (none) | - | Planning phase - PM defines requirements | -| **Phase 3** | *framework, *ci | Once per project | Setup test infrastructure AFTER architecture | -| **Phase 4** | *test-design, *atdd, *automate, *test-review, \*trace | Per epic/story | Test planning per epic, then per-story testing | -| **Release** | *nfr-assess, *trace (Phase 2: gate) | Per epic/release | Go/no-go decision | +| Phase | TEA Workflows | Frequency | Purpose | +| ----------- | --------------------------------------------------------- | ---------------- | ---------------------------------------------- | +| **Phase 2** | (none) | - | Planning phase - PM defines requirements | +| **Phase 3** | \*framework, \*ci | Once per project | Setup test infrastructure AFTER architecture | +| **Phase 4** | \*test-design, \*atdd, \*automate, \*test-review, \*trace | Per epic/story | Test planning per epic, then per-story testing | +| **Release** | \*nfr-assess, \*trace (Phase 2: gate) | Per epic/release | Go/no-go decision | **Note**: `*trace` is a two-phase workflow: Phase 1 (traceability) + Phase 2 (gate decision). This reduces cognitive load while maintaining natural workflow. diff --git a/src/modules/bmm/docs/workflow-document-project-reference.md b/src/modules/bmm/docs/workflow-document-project-reference.md index 4948fa63..3bd8749e 100644 --- a/src/modules/bmm/docs/workflow-document-project-reference.md +++ b/src/modules/bmm/docs/workflow-document-project-reference.md @@ -57,7 +57,7 @@ Choose the right scan depth for your needs: - Initial understanding of project structure - Planning next steps before deeper analysis -**Does NOT read:** Source code files (_.js, _.ts, _.py, _.go, etc.) +**Does NOT read:** Source code files (`_.js`, `_.ts`, `_.py`, `_.go`, etc.) ### 2. Deep Scan diff --git a/src/modules/bmm/testarch/knowledge/ci-burn-in.md b/src/modules/bmm/testarch/knowledge/ci-burn-in.md index 65d40695..b907c906 100644 --- a/src/modules/bmm/testarch/knowledge/ci-burn-in.md +++ b/src/modules/bmm/testarch/knowledge/ci-burn-in.md @@ -662,7 +662,7 @@ Before deploying your CI pipeline, verify: - [ ] **Artifact retention**: 30 days for reports, 7 days for failure artifacts - [ ] **Parallelization**: Matrix strategy uses fail-fast: false - [ ] **Burn-in enabled**: Changed specs run 5-10x before merge -- [ ] **wait-on app startup**: CI waits for app (wait-on: 'http://localhost:3000') +- [ ] **wait-on app startup**: CI waits for app (wait-on: '') - [ ] **Secrets documented**: README lists required secrets (API keys, tokens) - [ ] **Local parity**: CI scripts runnable locally (npm run test:ci) diff --git a/src/modules/bmm/testarch/knowledge/overview.md b/src/modules/bmm/testarch/knowledge/overview.md index 3a60e349..5fbb9801 100644 --- a/src/modules/bmm/testarch/knowledge/overview.md +++ b/src/modules/bmm/testarch/knowledge/overview.md @@ -262,7 +262,7 @@ import { apiRequest } from '@seontechnologies/playwright-utils/api-request'; // The official `@seontechnologies/playwright-utils` repository provides working examples of all patterns described in these fragments. -**Repository:** https://github.com/seontechnologies/playwright-utils +**Repository:** **Key resources:** diff --git a/src/modules/bmm/workflows/document-project/workflows/deep-dive-instructions.md b/src/modules/bmm/workflows/document-project/workflows/deep-dive-instructions.md index 621c843c..c88dfb08 100644 --- a/src/modules/bmm/workflows/document-project/workflows/deep-dive-instructions.md +++ b/src/modules/bmm/workflows/document-project/workflows/deep-dive-instructions.md @@ -20,7 +20,7 @@ {{#if has_api_routes}} -### API Routes ({{api_route_count}} endpoints found) +## API Routes ({{api_route_count}} endpoints found) {{#each api_route_groups}} {{group_index}}. {{group_name}} - {{endpoint_count}} endpoints in `{{path}}` @@ -29,7 +29,7 @@ {{#if has_feature_modules}} -### Feature Modules ({{feature_count}} features) +## Feature Modules ({{feature_count}} features) {{#each feature_modules}} {{module_index}}. {{module_name}} - {{file_count}} files in `{{path}}` diff --git a/src/modules/bmm/workflows/testarch/ci/checklist.md b/src/modules/bmm/workflows/testarch/ci/checklist.md index 330ebe38..6853a24d 100644 --- a/src/modules/bmm/workflows/testarch/ci/checklist.md +++ b/src/modules/bmm/workflows/testarch/ci/checklist.md @@ -4,7 +4,7 @@ - [ ] Git repository initialized (`.git/` exists) - [ ] Git remote configured (`git remote -v` shows origin) -- [ ] Test framework configured (playwright.config._ or cypress.config._) +- [ ] Test framework configured (`playwright.config._` or `cypress.config._`) - [ ] Local tests pass (`npm run test:e2e` succeeds) - [ ] Team agrees on CI platform - [ ] Access to CI platform settings (if updating) diff --git a/src/modules/bmm/workflows/testarch/test-review/instructions.md b/src/modules/bmm/workflows/testarch/test-review/instructions.md index 0bf378cc..a0f49b57 100644 --- a/src/modules/bmm/workflows/testarch/test-review/instructions.md +++ b/src/modules/bmm/workflows/testarch/test-review/instructions.md @@ -524,7 +524,7 @@ await expect(page.locator('[data-testid="user-menu"]')).toBeVisible({ timeout: 1 ### 1. Use Data Factory for Test User (Lines 23, 32, 41) **Severity**: P1 (High) -**Issue**: Hardcoded email 'test@example.com' - maintainability risk +**Issue**: Hardcoded email `test@example.com` - maintainability risk **Fix**: Create factory function for test users **Knowledge**: See data-factories.md diff --git a/tools/cli/README.md b/tools/cli/README.md index 5c794f16..c2dc6d1f 100644 --- a/tools/cli/README.md +++ b/tools/cli/README.md @@ -604,6 +604,6 @@ node tools/cli/regenerate-manifests.js ## Support -- **Issues**: https://github.com/bmad-code-org/BMAD-METHOD/issues -- **Discord**: https://discord.gg/gk8jAdXWmj (#general-dev, #bugs-issues) -- **YouTube**: https://www.youtube.com/@BMadCode +- **Issues**: +- **Discord**: (#general-dev, #bugs-issues) +- **YouTube**: