| name | markdown-linting |
| description | Comprehensive markdown linting guidance using markdownlint-cli2. Run, execute, check, and validate markdown files. Fix linting errors (MD0XX rules). Configure .markdownlint-cli2.jsonc (rules and ignores). Set up VS Code extension and GitHub Actions workflows. Use when working with markdown files, encountering validation errors, configuring markdownlint, setting up linting workflows, troubleshooting linting issues, or establishing markdown quality standards. |
| allowed-tools | Read, Bash, Glob, Grep |
Markdown Linting
This skill provides comprehensive guidance for markdown linting using markdownlint-cli2, the industry-standard markdown linter that can be used in any project.
Table of Contents
- Overview
- When to Use This Skill
- First Use: Installation and Setup
- Quick Start
- Unified Tooling Architecture
- CRITICAL: Configuration Policy
- CRITICAL: NO AUTOMATED SCRIPTS
- Running Linting Locally
- Intelligent Fix Handling
- VS Code Extension Setup (Optional/Advanced)
- GitHub Actions Integration (Optional/Advanced)
- Customizing Rules (Requires Approval)
- Troubleshooting
- Best Practices
- Resources
- Evaluation Scenarios
- Multi-Model Testing Notes
- Version History
- Last Updated
Overview
This tooling enables enforcement of strict markdown quality standards through automated linting. Markdown files can be validated using markdownlint-cli2 with a unified tooling approach that ensures zero configuration drift across VS Code, CLI, and CI/CD environments.
Core Philosophy:
- Single source of truth:
.markdownlint-cli2.jsonccontains all configuration (rules, ignores, options) - Unified tooling: Same
markdownlint-cli2engine everywhere (VS Code, CLI, CI/CD) - Strict enforcement: Fix content to comply with rules, not rules to accommodate content
- Quality-first: Linting rules are intentional and enforce documentation quality
When to Use This Skill
This skill should be used when:
- User encounters markdown linting errors (MD001, MD013, MD033, etc.)
- User asks about markdown validation, formatting, or quality standards
- User needs to configure
.markdownlint-cli2.jsonc(rules, ignores, or options) - User asks about configuration file setup or structure
- User wants to set up VS Code markdown linting extension
- User needs to troubleshoot markdown linting issues
- User asks how to run markdown linting locally
- User wants to understand GitHub Actions markdown validation
- User is working with markdown files and needs quality guidance
First Use: Installation and Setup
If this is your first time setting up markdown linting, see the comprehensive installation guide:
This guide covers:
- Prerequisites (Node.js/npm)
- Detection of existing setup
- Two approaches: npx (zero setup) vs local install (full features)
- Configuration file creation (
.markdownlint-cli2.jsonc) - Configuring rules, ignores, and options in one file
- Verification steps
- Troubleshooting setup issues
Quick detection check:
# Check if you're already set up
ls .markdownlint-cli2.jsonc # Configuration exists?
npm list markdownlint-cli2 # Package installed?
cat package.json | grep "lint:md" # Scripts configured?
If any of these are missing, follow the Installation and Setup Guide first.
Quick Start
Option 1: Using npx (zero setup required):
# Check all markdown files
npx markdownlint-cli2 "**/*.md"
# Auto-fix issues
npx markdownlint-cli2 "**/*.md" --fix
Option 2: Using npm scripts (if configured):
# Check all markdown files for linting errors
npm run lint:md
# Auto-fix fixable linting issues
npm run lint:md:fix
Option 3: VS Code extension for real-time linting (optional/advanced):
- Install
davidanson.vscode-markdownlintfrom VS Code marketplace - Create
.markdownlint-cli2.jsoncconfiguration (see installation guide) - Linting happens as you type with auto-fix on save enabled (if configured)
Unified Tooling Architecture
When configured, markdownlint-cli2 can be used everywhere to ensure zero configuration drift:
Tooling Components
CLI Tool (
markdownlint-cli2) - Core component, use this first- Can be run via npx (zero setup) or local install
- Used for local validation and pre-commit checks
- Foundation for all other integrations
VS Code Extension (
davidanson.vscode-markdownlint) - Optional/Advanced- Uses same
markdownlint-cli2engine as CLI - Real-time linting as you type
- Auto-fix on save and paste (configurable in
.vscode/settings.json) - See VS Code Extension Setup
- Uses same
GitHub Actions (
markdownlint-cli2-action) - Optional/Advanced- Same engine as VS Code and CLI
- Runs automatically on PRs that modify markdown files (when configured)
- Same rules as local development (no surprises)
- See GitHub Actions Configuration
Configuration Source
All tools read .markdownlint-cli2.jsonc in the project root as the single source of truth:
{
"gitignore": true,
"ignores": ["vendor/**/*.md"],
"config": {
"default": true,
"MD013": false
}
}
What this contains:
gitignore: Automatically excludes files from.gitignoreignores: Additional glob patterns to exclude from lintingconfig: Linting rules (all defaults enabled, MD013 disabled for long lines)
Configuration precedence (in decreasing order):
.markdownlint-cli2.{jsonc,yaml,cjs}file - Single source of truth- VS Code user/workspace settings (avoid - not portable)
- Default configuration
Note: Changes to .markdownlint-cli2.jsonc apply instantly to all tools (VS Code, CLI, GitHub Actions)
CRITICAL: Configuration Policy
IMPORTANT - Read this before modifying any configuration:
Strict Policy - Never Modify Without Approval
- DO NOT modify
.markdownlint-cli2.jsoncwithout explicit approval - Strict linting rules are intentional and enforce documentation quality
- If linting errors occur, fix the content to comply with the rules, NOT the rules themselves
- Only request rule changes if there is a compelling architectural reason
- When in doubt, ask before relaxing any linting rules
Why This Policy Exists
- Quality enforcement: Linting rules maintain documentation consistency and professionalism
- Best practices: Rules encode markdown best practices accumulated over years
- Accessibility: Many rules improve screen reader and markdown parser compatibility
- Maintainability: Consistent formatting makes documentation easier to maintain
- Collaboration: Shared standards reduce friction in code reviews
Proper Response to Linting Errors
Correct approach:
Error: MD022/blanks-around-headings - Headings should be surrounded by blank lines
Action: Add blank lines before and after the heading in the markdown file
Incorrect approach:
Error: MD022/blanks-around-headings - Headings should be surrounded by blank lines
Action: Disable MD022 rule in .markdownlint-cli2.jsonc
Exception: If you genuinely believe a rule should be modified, present your case to the user with:
- The specific rule and why it's problematic
- Examples of where it causes issues
- Architectural or usability rationale
- Proposed configuration change
The user will make the final decision on whether to modify the configuration.
CRITICAL: NO AUTOMATED SCRIPTS
⚠️ SCRIPTS ARE STRICTLY PROHIBITED FOR MARKDOWN LINTING FIXES ⚠️
NEVER use automated scripts to fix markdown files. This includes:
- Python/Bash scripts that modify multiple files at once
- Regex-based find-and-replace operations across files
- Any automated tool that makes bulk changes without human review per-change
- "Smart" fixers that detect and add language specifiers to code blocks
Why This Policy Exists
A) Scripts are dangerous - we have seen real issues:
- Context blindness: Scripts cannot understand semantic context (e.g., a code block showing tool output vs actual code that needs syntax highlighting)
- Over-application: Scripts apply fixes uniformly, even where inappropriate
- Cascading damage: One wrong assumption affects hundreds of files, requiring painful manual cleanup
- False language detection: Adding
textor other language specifiers to blocks that intentionally have none
B) Manual fixes are slower but more accurate and safer:
While manually fixing linting errors one-by-one takes longer, it ensures:
- Each change is reviewed in context before application
- Semantic meaning is preserved (not just syntactic correctness)
- Edge cases are handled appropriately
- No collateral damage to unrelated content
The speed/accuracy trade-off is worth it. A script that "saves time" but requires hours of cleanup is a net loss.
Nested Code Blocks: A Critical Complexity
Documentation often contains markdown within markdown - examples showing how to write markdown, skill documentation with code samples, templates, etc. This creates nested structures that scripts cannot handle correctly:
Example: A skill showing how to write a code block:
Here's how to create a Python code block:
````markdown
```python
def hello():
print("Hello, world!")
```
````
In this example:
- The outer fence uses 4 backticks (`````markdown`)
- The inner fence uses 3 backticks (
```python) - A script seeing
```might incorrectly add language specifiers or break the nesting
Common nested patterns to watch for:
```{language}- Regular code block with syntax highlighting````markdown- Wrapper showing markdown examples (uses 4+ backticks)- Code blocks inside code blocks (documentation about documentation)
- Example output that should NOT have language specifiers
Scripts cannot reliably distinguish:
- Which backtick fence is the "real" one vs an example
- Whether a bare
```is intentional (raw output) or needs a language - The semantic purpose of each code block
Real-World Failure Example
A script added text language specifiers to code blocks showing MCP tool output, Notion searches, and other non-code examples. These blocks were intentionally bare (no language specifier) to show raw output without syntax highlighting. The script's "fix" required hundreds of manual edits to undo.
The ONLY Acceptable Approach
- Run
markdownlint-cli2 --fixfor safe, built-in auto-fixes (trailing spaces, blank lines, etc.) - For "unfixable" errors (MD040, MD024, etc.), use the Edit tool to make targeted, contextual fixes one at a time
- Review each change before applying - understand WHY the error exists and whether the fix is semantically correct
- Look at surrounding context - is this a nested code block? An example? Raw output?
- If a fix seems mechanical/repetitive, STOP and ask the user before proceeding
If You Even Consider Using a Script
- STOP immediately
- Ask the user explicitly: "I'm considering automating this with a script. Are you sure? Scripts have caused painful cleanup in the past."
- Only proceed if user explicitly confirms AND you've triple-checked the script logic
- Test on ONE file first and show the user the diff before bulk application
MD040 (fenced-code-language) Special Guidance
The MD040 rule requires code blocks to have language specifiers. However:
- DO NOT blindly add
textto all blocks without language specifiers - Some blocks intentionally have no language (showing raw output, examples, templates)
- Ask yourself: "Is this showing code that needs syntax highlighting, or raw output?"
- When in doubt, ask the user rather than guessing
Questions to ask before adding a language specifier:
- Is this actual code, or example output/results?
- Is this inside a larger markdown example (nested)?
- Would syntax highlighting help or hurt readability here?
- Did the author intentionally leave it bare?
Running Linting Locally
CRITICAL: Auto-Fix Workflow
When running linting validation, ALWAYS automatically fix ALL errors (both fixable and "unfixable") without asking for user confirmation.
Workflow:
- Run linting validation command (npx or npm scripts)
- If errors are found:
- IMMEDIATELY run the auto-fix command (
--fixflag) without prompting - Report what was auto-fixed
- For any remaining "unfixable" errors:
- Read the affected files to understand context
- Analyze the error and surrounding content
- Apply intelligent fixes based on context (see "Intelligent Fix Handling" below)
- Re-run linting to verify fixes
- IMMEDIATELY run the auto-fix command (
- If no errors are found, report success
DO NOT ask "Would you like me to auto-fix?" or "Would you like me to investigate?" - just fix everything automatically.
Prerequisites
For npx approach (zero setup):
- Node.js 18+ and npm 8+ installed
- No additional setup required
For local install approach:
# Install dependencies (first time only)
npm install
If your project doesn't have markdownlint-cli2 installed, see the Installation and Setup Guide.
Check All Markdown Files
With npx:
npx markdownlint-cli2 "**/*.md"
With npm scripts (if configured):
npm run lint:md
What this does:
- Runs
markdownlint-cli2against all.mdfiles in the project - Automatically excludes
node_modulesdirectory - Outputs errors with file paths and line numbers
- Exit code 0 if no errors, non-zero if errors found
Example output:
docs/setup-guide.md:45:1 MD022/blanks-around-headings Headings should be surrounded by blank lines
README.md:12:81 MD009/no-trailing-spaces Trailing spaces
Auto-Fix Fixable Issues
With npx:
npx markdownlint-cli2 "**/*.md" --fix
With npm scripts (if configured):
npm run lint:md:fix
What this does:
- Automatically fixes issues that can be safely corrected
- Modifies files in place
- Reports remaining unfixable issues
Fixable issues include:
- Trailing spaces (MD009)
- Missing blank lines (MD012, MD022)
- List marker consistency (MD004, MD007)
- Code fence style (MD048)
Non-fixable issues require intelligent analysis and manual fixes:
- Heading structure (MD001, MD025)
- Duplicate headings (MD024)
- Line length (MD013, if enabled)
- Link references (MD051, MD052)
Intelligent Fix Handling
When "unfixable" errors remain after auto-fix, automatically analyze and fix them.
For detailed strategies on handling each error type, see the dedicated guide:
This guide covers:
- MD024 - Duplicate Headings (context-aware renaming or removal)
- MD001/MD025 - Heading Structure (hierarchy fixes)
- MD051/MD052 - Link References (anchor and reference link corrections)
- MD013 - Line Length (intelligent wrapping)
- General principles for context-aware analysis
- Verification and reporting best practices
- Performance optimization with parallel Task agents
Quick summary:
- Run auto-fix first:
npx markdownlint-cli2 "**/*.md" --fix - For remaining errors, read affected files to understand context
- Apply intelligent fixes based on error patterns (see guide)
- Always re-run linting to verify all errors are resolved
- Report what was fixed and how
VS Code Extension Setup (Optional/Advanced)
For VS Code integration, see the dedicated guide:
The VS Code extension (davidanson.vscode-markdownlint) provides real-time linting in your editor. The guide covers:
- Extension installation and verification
- Auto-fix configuration (format on save, format on paste)
- Interactive linting features (squiggly underlines, quick fixes)
- Keyboard shortcuts for all fix methods
- Configuration precedence and troubleshooting
- Best practices for team usage
This is optional but highly recommended for regular markdown work.
GitHub Actions Integration (Optional/Advanced)
For CI/CD integration, see the dedicated guide:
GitHub Actions Configuration Guide
GitHub Actions can automatically validate markdown files on PRs and pushes. The guide covers:
- Complete workflow file configuration
- Trigger setup (PR and push events with path filtering)
- Action versions (checkout@v5, markdownlint-cli2-action@v21)
- Workflow execution flow and results interpretation
- Viewing and fixing CI failures
- Advanced configuration (custom globs, auto-fix, branch protection)
- Troubleshooting common issues
This is optional but highly recommended for team projects.
Customizing Rules (Requires Approval)
WARNING: Only modify with explicit approval per policy above.
For detailed rule information, see the comprehensive guide:
The rules reference covers:
- All 60+ MD rules with descriptions and examples
- Rule categories (auto-fixable vs manual-fix required)
- Configuration syntax for customizing rules
- Common rule modifications (disable, configure parameters)
- Inline comment syntax for per-file overrides
- Links to official documentation for each rule
Quick syntax reminder:
{
"default": true, // Enable all defaults
"MD013": false, // Disable specific rule
"MD033": { // Configure with options
"allowed_elements": ["br"]
}
}
Troubleshooting
Common issues and solutions:
Issue: "Command not found: markdownlint-cli2"
Solution: Run npm install or use npx: npx markdownlint-cli2 "**/*.md"
Issue: Too many linting errors to fix manually
Solution:
- Run auto-fix:
npx markdownlint-cli2 "**/*.md" --fix - Fix remaining errors in batches
- See Installation Guide for detailed troubleshooting
Issue: VS Code or GitHub Actions problems
For detailed troubleshooting, see the dedicated guides:
- VS Code issues: VS Code Extension Setup
- GitHub Actions issues: GitHub Actions Configuration
Issue: Unclear rule violations
Solution: Check Markdownlint Rules Reference for rule explanations, examples, and official documentation links.
Best Practices
For comprehensive best practices on markdown linting, configuration management, collaboration, and skill automation:
The guide covers:
- Writing markdown effectively with linting in mind
- Configuration management and rule customization
- Collaboration patterns and team workflows
- Skill automation for Claude Code usage
- When and how to use parallel Task agents for efficiency
Resources
Official Documentation
- markdownlint-cli2 README: github.com/DavidAnson/markdownlint-cli2
- markdownlint rules: github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md
- VS Code extension: marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint
- GitHub Action: github.com/DavidAnson/markdownlint-cli2-action
Project Configuration Files
These files should be created in your project root (see installation guides for setup):
- Configuration:
.markdownlint-cli2.jsonc(required for custom rules) - NPM scripts:
package.json(optional, for npm run commands) - VS Code settings:
.vscode/settings.json(optional, for auto-fix on save) - GitHub workflow:
.github/workflows/markdown-lint.yml(optional, for CI/CD)
Supporting Documentation
This skill includes reference documentation in the references/ directory:
- references/installation-setup.md - Start here: Installation and first-time setup
- references/intelligent-fixing-guide.md - Strategies for fixing "unfixable" errors
- references/markdownlint-rules.md - Detailed rule explanations and customization
- references/best-practices.md - Best practices for writing, configuration, collaboration, and automation
- references/vscode-extension-setup.md - VS Code integration guide (optional/advanced)
- references/github-actions-config.md - CI/CD workflow setup (optional/advanced)
Evaluation Scenarios
These scenarios are used to evaluate skill activation, guidance quality, and multi-model compatibility.
Scenario 1: First-time setup
{
"name": "First-time setup",
"query": "I need to set up markdown linting in my project",
"context": "User has no existing markdown linting configuration",
"files": [],
"expected_behavior": [
"Skill activates successfully",
"Loads references/installation-setup.md for comprehensive guidance",
"Provides step-by-step installation instructions",
"Distinguishes between npx (zero-setup) and local install approaches",
"Guides through .markdownlint-cli2.jsonc configuration",
"Includes verification steps"
],
"test_models": ["sonnet", "haiku", "opus"]
}
Scenario 2: Fix linting errors
{
"name": "Fix linting errors",
"query": "I'm getting MD022 errors, how do I fix them?",
"context": "User has linting errors and needs guidance on fixes",
"files": ["sample-file.md"],
"expected_behavior": [
"Skill activates for error type and rule explanation",
"Explains MD022 rule (blanks around headings)",
"Provides auto-fix command (npx markdownlint-cli2 --fix)",
"Explains both automatic and intelligent fix approaches",
"References intelligent-fixing-guide.md if needed",
"Provides verification steps"
],
"test_models": ["sonnet", "haiku", "opus"]
}
Scenario 3: VS Code integration
{
"name": "VS Code integration",
"query": "How do I enable auto-fix on save in VS Code?",
"context": "User wants to integrate markdown linting into their editor workflow",
"files": [],
"expected_behavior": [
"Skill activates for VS Code integration",
"Loads references/vscode-extension-setup.md",
"Provides extension installation instructions",
"Explains auto-fix configuration in .vscode/settings.json",
"Documents keyboard shortcuts and interactive features",
"Includes troubleshooting for common VS Code issues"
],
"test_models": ["sonnet", "haiku", "opus"]
}
Scenario 4: GitHub Actions CI setup
{
"name": "GitHub Actions CI setup",
"query": "Add markdown linting to GitHub Actions",
"context": "User wants to automate markdown validation in CI/CD pipeline",
"files": [".github/workflows/"],
"expected_behavior": [
"Skill activates for GitHub Actions integration",
"Loads references/github-actions-config.md",
"Provides complete workflow file configuration",
"Explains trigger setup (PR and push events)",
"Documents workflow execution and results interpretation",
"Includes configuration for auto-fix and branch protection"
],
"test_models": ["sonnet", "haiku", "opus"]
}
Scenario 5: Configuration customization
{
"name": "Configuration customization",
"query": "How do I disable MD013 line length rule?",
"context": "User needs to customize linting rules for their project",
"files": [".markdownlint-cli2.jsonc"],
"expected_behavior": [
"Skill activates for rule customization",
"Explains configuration policy (fix content, not rules)",
"Provides .markdownlint-cli2.jsonc configuration example",
"Shows syntax for disabling/configuring specific rules",
"References references/markdownlint-rules.md for rule details",
"Emphasizes verification of changes across all tools"
],
"test_models": ["sonnet", "haiku", "opus"]
}
Multi-Model Testing Notes
Tested with:
- Claude Sonnet: Optimal performance, follows hub architecture well
- Claude Haiku: (To be tested - should work given explicit instructions)
- Claude Opus: (To be tested - may over-analyze, content is appropriately scoped)
Observations: Skill's explicit command examples and clear decision trees should work well across all model tiers.
Version History
- v2.0.0 (2025-11-30): Migrated to code-quality plugin in claude-code-plugins repo
- v1.2.0 (2025-11-17): Extracted Intelligent Fixing Guide - moved detailed error fixing strategies to separate reference file, reduced SKILL.md size for better token efficiency
- v1.1.0 (2025-11-17): Deduplicated content - removed duplicated reference material, streamlined to hub architecture
- v1.0.2 (2025-11-17): Version updates - updated to markdownlint-cli2 v0.19.0, Node 20+ requirement, action v21
- v1.0.1 (2025-01-09): Improved portability - removed repository-specific language, enhanced first-use guidance
- v1.0.0 (2025-01-09): Initial release - migrated from
.claude/memory/workflows.md
Last Updated
Date: 2025-12-27 Model: claude-opus-4-5-20251101