https://github.com/jeduden/mdsmith
fast, auto-fixing Markdown linter and formatter. Checks style, readability, structure, and cross-file integrity.
https://github.com/jeduden/mdsmith
ai-generated-code ai-generated-content formatter go golang linter markdown readme spec-driven spec-driven-development specification style
Last synced: 10 days ago
JSON representation
fast, auto-fixing Markdown linter and formatter. Checks style, readability, structure, and cross-file integrity.
- Host: GitHub
- URL: https://github.com/jeduden/mdsmith
- Owner: jeduden
- License: mit
- Created: 2026-02-08T21:03:38.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-05-03T21:23:40.000Z (16 days ago)
- Last Synced: 2026-05-03T21:27:34.373Z (16 days ago)
- Topics: ai-generated-code, ai-generated-content, formatter, go, golang, linter, markdown, readme, spec-driven, spec-driven-development, specification, style
- Language: Go
- Homepage:
- Size: 167 MB
- Stars: 4
- Watchers: 0
- Forks: 0
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Codeowners: .github/CODEOWNERS
- Security: docs/security/2026-04-05-adversarial-markdown.md
- Agents: AGENTS.md
Awesome Lists containing this project
README
# 🔨 mdsmith
[![Build][ci-badge]][ci-link]
[![Quality][grc-badge]][grc-link]
[![Coverage][cov-badge]][cov-link]
A fast, auto-fixing Markdown linter and formatter for docs, READMEs,
and AI-generated content. Checks style, readability, structure, and
cross-file integrity. Written in Go.

## ✨ Why mdsmith
**🔧 Stop hand-formatting Markdown.**
Whitespace, heading style, code fences, bare URLs, list
indentation, table alignment — `mdsmith fix` handles them
in place. Multi-pass fixing resolves cascading changes so
you don't run it twice. `mdsmith check` is the read-only
sibling for CI.
**🔗 Catch broken links before they merge.**
Refactors silently break Markdown links and anchors.
[`cross-file-reference-integrity`](internal/rules/MDS027-cross-file-reference-integrity/README.md)
flags every missing file and missing heading anchor in PR
review. Pair it with
[`required-structure`](internal/rules/MDS020-required-structure/README.md)
to enforce that each file has the sections it should
(reusable schemas live in your repo and are referenced by
path or named via `kinds:`), and
[`directory-structure`](internal/rules/MDS033-directory-structure/README.md)
to keep Markdown in the folders it belongs.
**🤖 Stop AI from bloating your docs.**
LLMs produce walls of text. Cap file length with
[`max-file-length`](internal/rules/MDS022-max-file-length/README.md),
section length with
[`max-section-length`](internal/rules/MDS036-max-section-length/README.md),
and tokens with
[`token-budget`](internal/rules/MDS028-token-budget/README.md).
[`paragraph-readability`](internal/rules/MDS023-paragraph-readability/README.md)
and
[`paragraph-structure`](internal/rules/MDS024-paragraph-structure/README.md)
hold reading-grade and sentence count in line.
[`duplicated-content`](internal/rules/MDS037-duplicated-content/README.md)
flags verbatim repetition across files.
**📋 Make tables of contents and indexes maintain themselves.**
Embed `` for a heading list,
`` for a table built from front matter,
or `` to splice in another file. `mdsmith fix`
regenerates them in place. After a merge conflict in one
of these blocks, `merge-driver install` registers a Git
driver that resolves it automatically.
**📊 Gate releases on doc status.**
`mdsmith query 'status: "✅"' plan/` lists every plan
that's done — pipe it to a release script, or fail the
release if anything is still open.
`mdsmith metrics rank --by token-estimate --top 10 docs/` is the
PR-time complement: spot the file an AI just doubled in
size before it lands.
**📖 Make rule docs readable by AI agents (and humans).**
`mdsmith help rule [name]` prints the full rule spec —
settings, examples, diagnostics — straight from the
binary. No network calls. Drop the output into
`.cursor/rules`, `AGENTS.md`, or `CLAUDE.md` and your
agent knows the rules without an extra fetch.
**🆚 How does it compare?** See:
- [How mdsmith compares to other Markdown linters.](docs/background/markdown-linters.md)
/catalog?>
## 📦 Installation
```bash
go install github.com/jeduden/mdsmith/cmd/mdsmith@latest
```
## 🚀 Usage
```text
mdsmith [flags] [files...]
```
### Commands
| Command | Description |
|--------------------------------------------------------------|--------------------------------------------------------------------------------------|
| [`check`](docs/reference/cli/check.md) | Lint Markdown files for style issues. |
| [`fix`](docs/reference/cli/fix.md) | Auto-fix lint issues in Markdown files in place. |
| [`help`](docs/reference/cli/help.md) | Show built-in documentation for rules, metrics, and concept pages. |
| [`init`](docs/reference/cli/init.md) | Generate a default `.mdsmith.yml` config in the current directory. |
| [`kinds`](docs/reference/cli/kinds.md) | Inspect declared file kinds and resolve effective rule config per file. |
| [`merge-driver`](docs/reference/cli/merge-driver.md) | Git merge driver that resolves conflicts inside generated sections. |
| [`metrics`](docs/reference/cli/metrics.md) | List and rank shared Markdown metrics (file length, token estimate, readability, …). |
| [`pre-merge-commit`](docs/reference/cli/pre-merge-commit.md) | Install / manage a pre-merge-commit hook that runs `mdsmith fix` after a merge. |
| [`query`](docs/reference/cli/query.md) | Select Markdown files by a CUE expression on front matter. |
| [`version`](docs/reference/cli/version.md) | Print the mdsmith build version and exit. |
/catalog?>
Files can be paths, directories (walked recursively for `*.md`
and `*.markdown`), or glob patterns. Directories respect
`.gitignore` by default;
use `--no-gitignore` to override. Explicitly named files are
never filtered by `.gitignore`.
### Examples
```bash
mdsmith check docs/ # lint a directory
mdsmith fix README.md # auto-fix in place
mdsmith check -f json docs/ # JSON output
mdsmith metrics rank --by bytes --top 10 .
```
See the [CLI reference](docs/reference/cli.md) for shared
flags, exit codes, output format, and configuration merge
semantics. Individual subcommand pages above cover their
own flags and examples.
## ⚙️ Configuration
Run `mdsmith init` to generate a `.mdsmith.yml` with every rule and its
defaults. Without a config, rules run with built-in defaults.
```yaml
rules:
line-length:
max: 120
fenced-code-language: false
ignore:
- "vendor/**"
overrides:
- glob: ["CHANGELOG.md"]
rules:
no-duplicate-headings: false
```
Rules are `true` (defaults), `false` (off), or an object with settings.
`overrides` apply per file pattern; later entries take precedence.
Config is discovered by walking up to the repo root; `--config` overrides.
Commit `.mdsmith.yml` so contributors share the same rule settings and
mdsmith upgrades become an explicit, reviewable change. Run
`mdsmith version` to see the build you have installed.
## 📚 More
- [Guides](docs/guides/index.md) — directives, structure, migration
- [Rule directory](internal/rules/index.md) — every rule with status
- [CLI reference](docs/reference/cli.md)
- [Contributor guide](docs/development/index.md) — Go 1.24+, build, test, style
## 📄 License
[MIT](LICENSE)
[ci-badge]: https://github.com/jeduden/mdsmith/actions/workflows/ci.yml/badge.svg?branch=main
[ci-link]: https://github.com/jeduden/mdsmith/actions/workflows/ci.yml?query=branch%3Amain
[grc-badge]: https://goreportcard.com/badge/github.com/jeduden/mdsmith
[grc-link]: https://goreportcard.com/report/github.com/jeduden/mdsmith
[cov-badge]: https://codecov.io/gh/jeduden/mdsmith/branch/main/graph/badge.svg
[cov-link]: https://codecov.io/gh/jeduden/mdsmith/branch/main