fix-refs
v0.1.2
Published
Auto-fix file-path references in Markdown when the target file is moved.
Readme
fix-refs
Auto-fix broken file-path references in Markdown when a file is moved.
When a .md document links to another file in your project (e.g. [guide](../src/file.cs)), moving that file silently breaks the link. fix-refs scans your Markdown, finds references that no longer resolve, locates where each file moved to, and rewrites the path in place — keeping it relative if it was relative, absolute if it was absolute, and changing nothing else in the document.
Install
npm install -g fix-refsRequires Node.js 18 or later.
Quick start
# Move into your project, then run:
fix-refs --dry-run # preview what would change
fix-refs # apply fixes
git diff # verify only link paths changedUsage
fix-refs [target] [flags]target controls which Markdown files are scanned. It can be a file, a folder, or a glob pattern. Leave it out to scan every .md file in the project automatically.
The workspace (-w) controls where fix-refs looks for the moved file. It searches this directory tree to find where a broken link's target ended up. By default it uses your git root, so you usually don't need to set it — just cd into your project and run fix-refs.
Examples
# Scan every .md file in the current project (most common usage)
# fix-refs automatically uses the git root as the workspace
fix-refs
# Only scan .md files inside a specific folder (still searches the whole project for moved files)
fix-refs ./docs
# Only scan a single file
fix-refs README.md
# Preview what would change without actually writing anything — always a good idea first
fix-refs --dry-run
# Explicitly set the project root, useful when running from outside the project directory
fix-refs -w /path/to/project
# Skip the interactive prompt when a moved file has multiple possible matches
# (instead of asking you to pick, it leaves the link as-is and reports it)
fix-refs --yes
# Output a JSON report instead of the normal text summary
# Useful in CI pipelines or scripts that need to parse the results
fix-refs --json
# Ignore a folder when scanning and searching
fix-refs --exclude "**/generated/**"Flags
| Flag | Short | Description |
|------|-------|-------------|
| --workspace <dir> | -w | The project root fix-refs searches when looking for a moved file. Defaults to the git root, or the current directory if not in a git repo. You rarely need to set this manually. |
| --dry-run | -n | Show what would change without writing any files. Always safe to run. |
| --yes | -y | Non-interactive mode. When a broken link could match more than one file, skip it instead of prompting you to choose. |
| --json | | Output a machine-readable JSON report instead of the normal text summary. Suppresses the interactive prompt automatically. |
| --exclude <glob> | | Ignore an extra folder or pattern when scanning and searching. Can be repeated for multiple patterns. |
| --verbose | | Print the name of every file as it is scanned. |
| --help | | Show usage. |
Exit codes
| Code | Meaning |
|------|---------|
| 0 | Nothing was broken, or every broken link was successfully fixed. |
| 1 | At least one link is still broken — either the file couldn't be found anywhere, or it matched multiple places and was skipped. |
| 2 | Unexpected error (e.g. a file couldn't be read). |
Exit code 1 is useful in CI — it causes the pipeline to fail if any link was left unresolved.
How it works
fix-refs parses each Markdown file into an AST, extracts every link and image destination, checks whether the target file exists, and for any that don't, searches the workspace for a file with the same name. If exactly one match is found, the path is rewritten in place using the original AST byte offsets — only the URL token changes, everything else (formatting, titles, surrounding text) is untouched.
- Relative links stay relative; absolute links stay absolute.
#fragmentand?querysuffixes are preserved.- Percent-encoding and angle-bracket wrapping are preserved.
- External URLs (
https://,mailto:, etc.) and pure anchors (#section) are never touched. - Files are written atomically (temp file + rename) so an interrupted run can't corrupt a document.
- Respects
.gitignorewhen indexing the workspace.
When a moved file matches multiple candidates, fix-refs prompts you to pick one interactively. In non-interactive mode (--yes, --json, or piped output), it skips and reports the ambiguity instead of guessing.
Updating
To install a newer version:
npm install -g fix-refs