Skip to content

jeduden/mdsmith

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1,553 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ”¨ mdsmith

Build Quality Coverage

A fast, auto-fixing Markdown linter and formatter for docs, READMEs, and AI-generated content. Checks style, readability, structure, and cross-file integrity. One static Go binary.

One static Go binary checks 523 Markdown files in about 0.2 s. That is roughly 10x faster than Node markdownlint. It does more per file than the Rust linters; closing the rest of that gap is active work.

Numbers above come from a reproducible benchmark, not hand-typed copy.

mdsmith demo

Why mdsmith

mdsmith is one rule engine behind every surface: the CLI, the LSP server, and the VS Code extension all run the same checks. Neovim and other LSP-aware editors plug in through the same server; a Claude Code plugin is available for users of that editor. This page is the shared overview. The README includes it; the website renders it and links each card to a fuller page.

Core (every repo)

These features pay off on a single README and scale up to a docs monorepo.

Auto-fix Markdown formatting. mdsmith fix rewrites whitespace, headings, code fences, bare URLs, list indentation, and table alignment in place. It loops until edits stabilize. mdsmith check is the read-only CI sibling.

Live diagnostics wherever you write. mdsmith lsp emits diagnostics, quick-fixes, and navigation. Any LSP-aware editor can consume it. The VS Code extension and the Claude Code plugin surface the same data.

Rename without breaking links. Rename a heading and every workspace anchor link to it is rewritten in one atomic edit. Link-ref labels rename with their uses. A colliding slug fails loudly instead of breaking links.

See the dependency graph. mdsmith deps lists what a file pulls in, or what depends on it. The LSP call-hierarchy walks the same <?include?>, <?catalog?>, <?build?>, and link graph in your editor.

Cross-file integrity. Built-in rules flag broken links and missing anchors, enforce per-file section schemas, and keep Markdown in the right folders. Schemas can be inline on a file kind or shared via proto.md files.

Scale (large docs sites)

These features show up when the repo grows past a handful of files: includes, catalogs, dependency graphs, release gates, and size budgets.

Size and readability limits. Cap file, section, and token-budget size. Enforce reading grade and sentence count. Flag verbatim copy-paste across files. Three rules ship on by default; two are opt-in.

Self-maintaining sections. On mdsmith fix, <?toc?> rebuilds a heading TOC, <?catalog?> generates an index from front matter, and <?include?> splices in another file. A Git merge driver resolves conflicts in those blocks.

Gate releases on doc status. mdsmith list query selects files by a CUE expression on front matter. mdsmith metrics rank ranks files by any shared metric. Both pipe straight into a release script.

Fast on every run. A single static Go binary with no runtime to boot. The workspace walk runs in parallel and embeds are linted once, so CI and editor feedback stay instant.

Quality you can verify. The build, Go Report Card, and coverage badges at the top of the README report live project health. mdsmith lints its own docs with the rules it ships, and a coverage gate blocks merges that drop below the line.

File kinds and schemas. Tag each file with a kind, then validate its headings and front matter against a schema declared inline on the kind or shared via a proto.md template. A whole directory obeys one contract.

Conventions and flavors. Pin a convention to get a curated rule preset and a target renderer flavor in one switch. MDS034 flags syntax the flavor will not render. A placeholder vocabulary spares template tokens.

Build artifacts in sync. <?build?> declares an artifact and a recipe. mdsmith fix keeps the section body in sync with the recipe output. MDS040 shell-safety-checks the recipe without running it.

Git-native, conflict-free. A merge driver auto-resolves conflicts inside generated blocks. A pre-merge-commit hook re-runs mdsmith fix and re-stages the result, so generated content never blocks a merge.

Config you can explain. Config layers deep-merge rule by rule: defaults, convention, kinds, then overrides. --explain and mdsmith kinds resolve show which layer set each effective value.

Editors and agents. A bundled VS Code extension and Claude Code plugins drive the same mdsmith lsp server, so diagnostics, fix-on-save, and navigation reach your editor and your coding agent unchanged.

Installs everywhere. One version-stamped Go binary ships through go install, npm, pip, uvx, mise, asdf, and GitHub Releases. No postinstall network call, so locked-down CI installs offline.

πŸ†š How does it compare? See:

πŸ”— Link handling internals. See:

πŸ“¦ Installation

CLI:

go install github.com/jeduden/mdsmith/cmd/mdsmith@latest
npm install -g @mdsmith/cli    # or: npx @mdsmith/cli
pip install mdsmith            # or: uvx mdsmith / pipx install mdsmith

Editor extension (LSP-backed; runs mdsmith lsp):

code --install-extension jeduden.mdsmith     # VS Code, Codespaces (Marketplace)
codium --install-extension jeduden.mdsmith   # Cursor, VSCodium, Theia, Gitpod (Open VSX)

Any LSP-aware editor (Neovim, Helix, JetBrains via the LSP plugin) works by pointing at mdsmith lsp.

Claude Code plugin (inline diagnostics plus definition, references, symbol search, and call-hierarchy queries across your docs):

/plugin marketplace add jeduden/mdsmith
/plugin install mdsmith-lsp@mdsmith
/reload-plugins

More: the install guide covers direct downloads and mise (asdf pending). VS Code integration covers settings, code actions, and troubleshooting.

πŸš€ Usage

mdsmith <command> [flags] [files...]

Commands

Command Description
check Lint Markdown files for style issues.
deps List a file's dependency-graph edges (includes, links, catalogs, builds).
export Write a portable, directive-free copy of a Markdown file.
extract Emit a schema-conformant Markdown file as a JSON/YAML/msgpack data tree.
fix Auto-fix lint issues in Markdown files in place.
help Show built-in documentation for rules, metrics, and concept pages.
init Generate a default .mdsmith.yml config in the current directory.
kinds Inspect declared file kinds and resolve effective rule config per file.
list Selection-style commands that walk the workspace and emit matches.
list backlinks List workspace links that point at a file.
list query Select Markdown files by a CUE expression on front matter.
lsp Run a Language Server Protocol server on stdio for editor integrations.
merge-driver Git merge driver that resolves conflicts inside generated sections.
metrics List and rank shared Markdown metrics (file length, token estimate, readability, …).
pre-merge-commit Install / manage a pre-merge-commit hook that runs mdsmith fix after a merge.
rename Rename a heading or link-reference label and rewrite every dependent edit.
version Print the mdsmith build version and exit.

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

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 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.

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

πŸ“„ License

MIT