mcpField
L
link-validation

link-validation

github.com/terrylicaTesting & quality2134 installsUpdated 1d ago
Repository

About link-validation

A skill for checking Markdown links in a repository with lychee. It is intended for documentation contributors who need to catch broken internal links before committing; checks run offline and report results in the terminal.

Key features

  1. 01Offline Markdown link checks
  2. 02Relative and root-relative link resolution
  3. 03Anchor fragment validation
  4. 04Repository-root detection
  5. 05Terminal summary and exit code

Use cases

  1. 01Check documentation before committing
  2. 02Find broken internal links
  3. 03Verify links after editing docs

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/terrylica/cc-skills --skill link-validation

After installing, type/link-validationin Claude Code to confirm it loaded.

Bundled filesreferences/evolution-log.md

Details

From the project README

Link Validation Skill

Validates markdown links in your workspace using lychee.

Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.

When to Use This Skill

Use this skill when:

  • Checking for broken links in markdown files
  • Validating link paths before committing documentation
  • Proving a doc change left no dangling internal link

How to Run It

The working path is the offline lychee check in tasks/link-check.sh. Inside the cc-skills repository it is part of the quality gate:

moon run repo:link-check     # this check alone
moon run repo:check          # the whole gate, link-check included
bash tasks/link-check.sh     # the same script without moon

In any other workspace, run the same lychee command from the repository root:

lychee --offline --no-progress --root-dir "$(git rev-parse --show-toplevel)" './**/*.md'

Add --config lychee.toml when the repository has one; lychee also loads ./lychee.toml by itself.

What the Check Does

tasks/link-check.sh:

  1. cds to the working-tree root (git rev-parse --show-toplevel, so it is correct inside a worktree too)
  2. Runs bunx lychee --config lychee.toml --offline --no-progress --root-dir <repo root> './**/*.md'
  3. Excludes plugins/statusline-tools/tests/fixtures, whose links are broken on purpose
  4. Prints lychee's summary line, then ✓ every internal link resolves or ✗ broken internal links found (lychee exit N), and exits with lychee's exit code

It checks relative links, root-relative links (/docs/adr/x.md, resolved through --root-dir) and #anchor fragments. It is offline by design: external URL liveness depends on the network and on other sites' uptime, so it is not checked. Nothing is written to disk except lychee's own .lycheecache; the result is the terminal output and the exit code.

A path that exists on one machine only (~/..., another repository) cannot pass. Write it as inline code instead of a link.

Requirements

  • lychee: tasks/link-check.sh runs it through bunx, so Bun is enough there; elsewhere install it (brew install lychee)

Configuration

cc-skills keeps one lychee config, lychee.toml at the repository root. It holds the path and URL exclusions and include_fragments = "anchor-only" (lychee 0.24 rejects the old boolean true). The statusline-tools Stop hook reads the same file when it exists.

Related Checks

  • Link portability in skills (absolute repo paths that break once installed): the link-validator skill
  • Path policy at session end: the statusline-tools Stop hook runs lint-relative-paths and lychee, and writes .lychee-results.json for the status line

History

This skill used to describe a Stop hook, hooks/stop-link-check.py, that wrote .link-check-results.md. link-tools never had a hooks.json, so the hook never ran; it was deleted in issue #33.

References


Troubleshooting

IssueCauseSolution
lychee not foundNot installedbrew install lychee, or run through bunx lychee
Config fails to loadinclude_fragments = trueUse include_fragments = "anchor-only" (lychee 0.24 and later)
Every /docs/... link failsNo --root-dirPass --root-dir with the absolute repository root
A link to ~/... failsPath exists on one machine onlyWrite it as inline code, not a link
A fixture's broken link failsFixture not excludedAdd it to --exclude-path or the config's exclude_path

Post-Execution Reflection

After this skill completes, check before closing:

  1. Did the command succeed? — If not, fix the instruction or error table that caused the failure.
  2. Did parameters or output change? — If the underlying tool's interface drifted, update Usage examples and Parameters table to match.
  3. Was a workaround needed? — If you had to improvise (different flags, extra steps), update this SKILL.md so the next invocation doesn't need the same workaround.

Only update if the issue is real and reproducible — not speculative.

Comments

Markdown supported