Lints and auto-fixes Markdown files to enforce GitHub Flavored Markdown (GFM) rules.
Note: Compatible with any LLM agent (Claude Code, OpenAI, OpenCode, etc.).
Agents creating or editing Markdown files in this repository MUST:
- Run lint validation immediately after every tool, editor, or script action that creates or edits a
.mdfile - Check fenced code blocks before committing
- Validate table column consistency before pushing
- Use
lint.jsas the canonical entry point — notnpxdirectly - Prefer auto-fix (
lint.js <path>) before manual formatting
Agents SHOULD NOT:
- Rewrite semantic prose for style-only reasons
- Alter code fence languages without certainty
- Normalize intentionally preserved formatting
- Modify generated content sections directly
- Batch multiple Markdown edits and lint later — lint each changed Markdown file immediately
This repository treats Markdown linting as agent-safe repository governance:
- Formatting must be deterministic and idempotent
- Configuration, documentation, and script behavior must stay in sync
- Table formatting preserves semantic alignment (
:---,---:,:---:) - Fenced code blocks are safety boundaries and must not be rewritten as prose
lint.jsis the canonical entry point for all automated and manual runs
Run lint immediately after each Markdown file creation or edit, regardless of whether the change came from write_file, apply_patch, an editor, or a script:
node ${HERMES_SKILL_DIR}/lint.js <path>Do not skip this step.
- Check repository consistency:
node scripts/check-consistency.js - Check fenced blocks:
node ${HERMES_SKILL_DIR}/lint.js --fences <path> - Validate tables:
node ${HERMES_SKILL_DIR}/lint.js --validate <path> - Final lint:
node ${HERMES_SKILL_DIR}/lint.js --check <path>
Update the Rules Enforced section in AGENTS.md, skills/markdown-lint/references/rules.md, plus the README policy summary and changelog when behavior changes. Then run:
node scripts/check-consistency.js# Lint (read-only)
node ${HERMES_SKILL_DIR}/lint.js --check <file>
# Fix after creating or editing Markdown
node ${HERMES_SKILL_DIR}/lint.js <file>
# Fix all in directory
node ${HERMES_SKILL_DIR}/lint.js --all <dir>
# Check fenced code blocks
node ${HERMES_SKILL_DIR}/lint.js --fences <path>
# Validate table columns (exit 1 on mismatch)
node ${HERMES_SKILL_DIR}/lint.js --validate <path>These rules are configured in skills/markdown-lint/references/.markdownlint.json:
| Rule | Description | Config |
|---|---|---|
| MD003 | Atx style headings | atx |
| MD007 | List indent | 2 spaces |
| MD009 | No trailing spaces | 2 spaces allowed |
| MD010 | No hard tabs | enabled |
| MD012 | Multiple blanks | max 1 |
| MD013 | Line length | disabled |
| MD014 | No dollar signs before commands without output | enabled |
| MD024 | Multiple headings same content | disabled |
| MD025 | Multiple top-level headings | disabled |
| MD026 | No punctuation after heading | .,;:! |
| MD029 | Ordered list style | ordered |
| MD030 | List marker space | enabled |
| MD032 | Blanks around lists | enabled |
| MD033 | No inline HTML | disabled |
| MD034 | No bare URLs | disabled |
| MD035 | Horizontal rule style | --- |
| MD036 | Emphasis in headings | disabled |
| MD040 | Fenced code language | disabled |
| MD041 | First line is top-level heading | enabled |
| MD045 | No alt text (images) | enabled |
| MD046 | Code block style | fenced |
| MD047 | Single trailing newline | enabled |
| MD048 | Code fence style | backtick |
| MD051 | Links inline | disabled |
| MD052 | Links without text | disabled |
| MD055 | Table pipe style | disabled |
| MD060 | Table column alignment | aligned |
| Level | CI | Merge | Description |
|---|---|---|---|
| BLOCKING | fails | blocked | Table column mismatch, unclosed fences |
| WARNING | fails | blocked | markdownlint rule violation |
| INFO | passes | allowed | Disabled-rule guidance |
| Error | Severity | Cause | Fix |
|---|---|---|---|
| MD018: No space after hash | WARNING | Missing space after # |
## Heading |
| MD047: Single trailing newline | WARNING | File missing final newline | Add blank line at end |
| MD056: Table column count | BLOCKING | Separator width mismatch | Run format-tables.js |
| MD060: Table pipe position | WARNING | Pipes misaligned | Run format-tables.js |
| Unclosed code fence | BLOCKING | Opener/closer mismatch | Run --fences check |
Blank fences are valid for output examples:
output here
Use text for intentional blank-fence examples. Use markdown for examples of markdown output.
Before:
| Name | Age |
| --- | ---: |
| Alice | 25 |After:
| Name | Age |
| :---- | --: |
| Alice | 25 |Before:
##No spaceAfter:
## No spaceBefore:
Intro paragraph
- Item one
- Item two
Next paragraphAfter:
Intro paragraph
- Item one
- Item two
Next paragraphBefore: ***
After: ---
lint.jsis the canonical entry point — use it instead ofnpxdirectly- MD040 is disabled — blank fences are allowed for output examples
- MD055 is disabled — leading/trailing
|on tables is optional - MD033 is disabled — inline HTML is allowed
- MD060 is
aligned— preserve semantic table alignment - Use
${HERMES_SKILL_DIR}or absolute paths in scripts
Add to ~/.hermes/config.yaml:
hooks:
post_tool_call:
- matcher: write_file
command: "node ~/.hermes/skills/markdown-lint/scripts/post-write.js"
hooks_auto_accept: trueRestart Hermes. This is optional — the mandatory lint rule handles the common case.
- Update top-level
versioninSKILL.mdfrontmatter on changes - Document changes in
README.mdchangelog - Run
node scripts/check-consistency.jsafter rule/config/doc edits - Keep the README changelog current for user-visible behavior, contract, and validation changes
Canonical entry point: skills/markdown-lint/SKILL.md
Helper scripts:
| File | Purpose |
|---|---|
lint.js |
Root developer wrapper |
scripts/check-consistency.js |
Checks config/docs consistency |
skills/markdown-lint/lint.js |
Pipeline wrapper — canonical entry point |
skills/markdown-lint/scripts/check-fences.js |
Validates fenced code blocks |
skills/markdown-lint/scripts/post-write.js |
Auto-lint hook (optional) |
skills/markdown-lint/references/format-tables.js |
Single-pass table formatter |
skills/markdown-lint/references/rules.md |
Full documented rule table |
skills/markdown-lint/references/.markdownlint.json |
Lint rules config |