AGENT INSTRUCTIONS DRIFT CHECK · RUNS IN YOUR BROWSER

Does your AI coding agent's instruction file still match your repo?

Paste your AGENTS.md, CLAUDE.md, .cursorrules, or copilot-instructions.md and see every file path it references that no longer exists, every npm run script it names that isn't defined in package.json, and known interpreter-mismatch shell footguns — a bare pytest or mypy that can silently resolve to the wrong Python and waste an agent's whole run chasing a phantom failure.

Nothing is uploaded. Pasted text is parsed entirely in this browser. The optional folder picker reads only file names from your chosen folder, never file contents, and nothing leaves your device either way.

1. Paste your instructions file

Prefer a CLI, or want this as a CI gate?

Same logic, zero dependencies, one file:

node cli.mjs check AGENTS.md                         # resolves refs from the current directory
node cli.mjs check AGENTS.md --root .                 # explicit root
node cli.mjs check CLAUDE.md --package package.json   # explicit package.json
node cli.mjs check AGENTS.md --json                   # machine-readable

Get cli.mjs — Node 18+, nothing to install. It reads only the instructions file, an optional package.json, and the local paths the instructions file itself names: no network call, ever. Exits 1 if anything is found, so it works as a CI gate on the same review that renames a file or a script.

What's checked

CheckHow
Broken file referenceA markdown link target or an inline `code span` that looks like a path (has a slash and a letter-led extension, or is a well-known bare filename like README.md) is resolved against your repo root and flagged if it doesn't exist
Undefined npm scriptnpm run <name>, npm test, and npm start references are checked against your package.json's scripts map, if you supply one
Interpreter-mismatch footgunA bare pytest or mypy inside a fenced code block, without a python3 -m (or python -m) prefix on the same line

Restricted to markdown links and inline code spans on purpose — that is how instruction files actually cite a path when they mean it literally, and scanning ordinary prose for anything path-shaped would flag far more false positives than real drift. A shorthand reference that relies on nearby prose for its directory ("the same validate.py as above") reports as not found even when a longer form of the same path exists elsewhere — a known, disclosed limitation, not a bug. See why these files rot, and where this checker's own edges are, or this checker vs. checking it by hand.

Common questions

Why do AI agent instruction files go stale?

AGENTS.md and CLAUDE.md are prose, so nothing mechanical keeps them in sync with the repo the way a compiler keeps a type signature in sync with a call site. A script gets renamed, a doc gets moved, a package.json script gets renamed in a refactor -- and the instruction file still points an agent (or a new human contributor) at the old name. The agent then either fails on a command that no longer exists or, worse, silently succeeds against the wrong tool.

What is an interpreter-mismatch footgun?

A bare tool invocation like pytest or mypy that, on a machine where that tool was installed in isolation (a uv tool install, a pipx install), resolves to a different Python interpreter than the one the repository's own dependencies were installed into. The command runs, produces a plausible-looking result (often "module not found"), and is easy to misread as a real failure in the code rather than a wrong interpreter. python3 -m pytest always resolves against the same interpreter as the rest of the repo's tooling.

Does this check whether the instructions are good advice?

No. It never judges tone, completeness, or whether a rule makes sense -- only whether a thing the file points at (a file path, an npm script, a known-bad shell pattern) still matches what the repo actually has today. That is a narrower, purely mechanical question, and it is the one a stale reference actually breaks on.

Is anything uploaded?

No. The browser page parses the text you paste and the file names it reads from a folder you pick entirely in your own browser, and never sends any of it anywhere. It reads only file names from the folder picker, never file contents. The CLI reads only local files -- no network call, ever.