https://github.com/jeduden/mdsmith
Lint and format the Markdown agents read and write
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: 15 days ago
JSON representation
Lint and format the Markdown agents read and write
- Host: GitHub
- URL: https://github.com/jeduden/mdsmith
- Owner: jeduden
- License: mit
- Created: 2026-02-08T21:03:38.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-03-26T21:47:42.000Z (22 days ago)
- Last Synced: 2026-03-27T09:40:53.204Z (21 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: 1.52 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 19
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
# ๐จ mdsmith
A fast, auto-fixing Markdown linter and formatter for docs, READMEs,
and AI-generated content. Checks style, readability, and structure.
Written in Go.

## โจ Why mdsmith
**๐ Progressive disclosure with catalogs.**
The [`catalog`](internal/rules/MDS019-catalog/README.md) rule generates summary
tables from file front matter and keeps them in sync.
Link each row to the full document โ
readers see the overview first and drill down on demand.
Run `mdsmith fix` and the table updates itself.
**๐ค Keep AI verbosity in check.**
AI tools produce walls of text.
[`max-file-length`](internal/rules/MDS022-max-file-length/README.md)
caps document size,
[`paragraph-readability`](internal/rules/MDS023-paragraph-readability/README.md)
enforces a reading-grade ceiling,
and [`paragraph-structure`](internal/rules/MDS024-paragraph-structure/README.md)
limits sentence count and length.
[`token-budget`](internal/rules/MDS028-token-budget/README.md)
adds a token-aware
budget with heuristic and tokenizer modes.
Set the thresholds in `.mdsmith.yml` and let CI enforce them.
**๐ AI-ready rule specs โ no remote calls.**
`mdsmith help rule` lists every rule with its ID and description.
`mdsmith help rule ` prints the full spec: settings, examples,
diagnostics. All docs are compiled into the binary โ works offline,
works in CI, works as a source for `.cursor/rules` or `AGENTS.md`.
`mdsmith help metrics` and `mdsmith help metrics ` do the same
for shared file metrics.
**๐ง Auto-fix.**
`mdsmith fix` corrects most rules in place.
Whitespace, heading style, code fences, bare URLs, list indentation,
table alignment, and generated sections โ all handled.
Multi-pass fixing resolves cascading changes automatically.
## ๐ฆ Installation
```bash
go install github.com/jeduden/mdsmith/cmd/mdsmith@latest
```
## ๐ Usage
```text
mdsmith [flags] [files...]
```
### Commands
| Command | Description |
|----------------|------------------------------------------------|
| `check` | Lint files (default command) |
| `fix` | Auto-fix issues in place |
| `query` | Select files by CUE expression on front matter |
| `help` | Show help for docs and topics |
| `metrics` | List and rank Markdown metrics |
| `merge-driver` | Git merge driver for regenerable sections |
| `init` | Generate `.mdsmith.yml` |
| `version` | Print version, exit |
Files can be paths, directories (walked recursively for `*.md`),
or glob patterns.
With no arguments and no piped input, mdsmith exits 0.
When walking directories, mdsmith respects `.gitignore` files by default.
Files matched by `.gitignore` patterns are skipped, including patterns from
nested `.gitignore` files in subdirectories and ancestor directories.
Explicitly named file paths are never filtered by gitignore.
Use `--no-gitignore` to disable this behavior and lint all files.
### Flags
| Flag | Description |
|------------------|------------------|
| `-c`, `--config` | Config path |
| `-f`, `--format` | `text` or `json` |
| `--no-color` | Plain output |
| `--no-gitignore` | Skip gitignore |
| `-q`, `--quiet` | Quiet mode |
### 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 .
```
### Output
Diagnostics are printed to stderr with source context when available:
```text
README.md:10:81 MDS001 line too long (135 > 80)
8 | Context lines appear above and below the diagnostic with line numbers.
9 | They help you see the surrounding code at a glance.
10 | This line is deliberately made long so it exceeds the eighty character limit and keeps going and going.
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท^
11 | A dot path runs from column 1 to the caret, marking the line and column.
12 | Up to two lines of context are shown on each side.
```
Each diagnostic shows a header (`file:line:col rule message`).
When source context is available, up to 5 surrounding lines appear
with a dot path (`ยทยทยทยท^`) pointing to the exact column.
### Exit codes
| Code | Meaning |
|------|--------------------------------|
| 0 | No lint issues found |
| 1 | Lint issues found |
| 2 | Runtime or configuration error |
## โ๏ธ Configuration
Create a `.mdsmith.yml` in your project root, or run
`mdsmith init` to generate one with every rule and its
default settings.
Without a config file, rules run with their built-in
defaults.
```yaml
rules:
line-length:
max: 120
fenced-code-language: false
ignore:
- "vendor/**"
overrides:
- files: ["CHANGELOG.md"]
rules:
no-duplicate-headings: false
```
Rules can be `true` (enable with defaults), `false` (disable),
or an object with settings.
The `overrides` list applies different rules per file pattern.
Later overrides take precedence.
Config is discovered by walking up from the current directory to the repo root.
Use `--config` to override.
### Bootstrapping with `mdsmith init`
Run `mdsmith init` to generate a `.mdsmith.yml` with every rule and its
default enablement and settings. This pins the config to the current defaults so
that future
mdsmith upgrades (which may change defaults) do not silently alter your
lint results. Review the generated file and adjust settings to match your
project's conventions.
```bash
mdsmith init
# creates .mdsmith.yml with all rule defaults
```
Commit the generated file to version control.
This ensures every contributor uses the same rule settings.
Upgrades become an explicit, reviewable change.
## ๐ Guides
See the [Guides index](docs/guides/index.md) for
directives, structure enforcement, and migration.
## ๐ Rules
See the
[Rule Directory](internal/rules/index.md)
for the complete list with status and description.
## ๐ ๏ธ Development
Requires Go 1.24+. See
[`docs/development/index.md`](docs/development/index.md) for the full
contributor guide (build commands, project layout,
workflow, code style, and PR conventions).
## ๐ Documentation
- [CLI design](docs/design/cli.md)
- [Design archetypes](docs/design/archetypes/)
- [Guides](docs/guides/)
- [Background](docs/background/)
- [Plans](plan/)
## ๐ License
[MIT](LICENSE)