Your agent doesn't know the bug in your exact version.
landmine reads your lockfile, finds the open GitHub issues filed against the versions you pin, and puts them where your coding agent reads them, with the workaround from the thread. Before it writes the code that hits them.
Open source, MIT. Works with Claude Code, Codex, Cursor and 17 more agents.
$npx landmines scan && npx landmines install --rulesReads every lockfile in the project, indexes the open issues for each exact version, then writes the known-bugs section into AGENTS.md and CLAUDE.md and adds the pre-edit hook. Needs Node ≥ 22.12 and a GitHub token with no scopes. Quickstart
$claude mcp add --transport http landmine https://landmine.tech/mcpNothing to install or sign into. Codex: codex mcp add landmine --url https://landmine.tech/mcp. Cursor, OpenCode and any client with Streamable HTTP take the same URL. Setup for each
Works with the agents you already use: 20 of them, plus anything that reads AGENTS.md or speaks MCP.
The agent reaches for the broken API. landmine stops it once.
Replayed from a real headless Claude Code 2.1.304 session, abridged. The prompt didn't mention bugs; the hook quoted the issue and its workaround, and the agent changed course on its own.
await db.$client.end(). The landmine hook flagged a known bug in drizzle-orm 0.36.0 (#3402). I avoided that by creating the pool myself.Lockfile in. Known bugs out. Before the edit.
Each hit is checked to really name the version you pin, tied to the code symbols it is about, and given the most useful workaround from its thread.
Scan
Explore ↗Reads your lockfiles, resolves each exact version, and finds the open GitHub issues filed against it.
Tell the agent first
Explore ↗A short known-bugs section in the file your agent already reads, ranked by the APIs your code calls. The part that measured as working.
Pre-edit hook
Explore ↗Pauses an edit once when it uses an API from a matching issue, quotes the workaround, then lets the retry through. Offline, about 0.11 s.
MCP server
Explore ↗For when the agent is already looking: a confusing error, or a dependency it is about to add. Local over stdio, or hosted with nothing to install.
Told up front, the agent steps around it.
landmine-bench: 21 held-out tasks built from bugs filed after the model's training cutoff, each a feature request whose obvious implementation hits an open upstream bug. A hidden test decides.
Claude Sonnet 5.5's pass rate with landmine's known-bugs section in CLAUDE.md (72/84 → 83/84 runs).
Against what you'd use instead
passed / 42Sonnet 5.5, 21 tasks × 2 seeds, one batch.
Confirmation run
Wins and losses on unseen seeds, in a run written down before it ran. p = 0.03.
Sessions that went looking
With web search or the Context7 MCP available, the agent called neither. It didn't think to look.
Per edit, offline
The hook's cost on our test machine, Node start-up included, with a 149 KB index.
A short list, in the file it already reads.
landmine rules writes a marked section into AGENTS.md and CLAUDE.md: the open issues for your exact versions, ranked by the APIs your code actually calls, each with its workaround.
- Only issues that name the version you pin, each checked against the thread.
- Tied to code symbols, so the agent knows which call to avoid.
- Framed as untrusted third-party text. The agent is told never to follow it blindly.
Real bugs your agent would walk into.
Across 28 popular open-source projects, 10 of them coding agents, the median lockfile pins 395 open GitHub issues filed against its exact versions. In a random audit, 30 of 40 really named the version. Each card below passed a separate read of the full thread.
`sympy.discrete.transforms.fft` performs inverse FFT
sympy.discrete.transforms.fft uses the opposite sign in the exponent, so it effectively computes the inverse DFT (e.g. fft([0,1,0,0]) returns [1, I, -1, -I] instead of [1, -I, -1, I]).
Controlled drawer with `modal={false}` does not work because of bug in `useControllableState`
A controlled Drawer with modal={false} that is opened from outside (via the open prop) leaves pointer-events: none on the body, blocking interaction with the rest of the page.
Tokens rotation does not persist the new token
When the `jwt` callback refreshes an access token, next-auth does not persist the returned token, so later requests keep using the old, expired one.
Bug: a component loses its state when its type changes from React.lazy to the component the lazy resolved to
When an element's type changes from a React.lazy wrapper to the plain component it resolved to, React remounts it and discards its state (e.g. RSC client components later rendered from plain JSX).
Turbopack generates external module references with hashes that don't match installed packages when node_modules structure differs
Turbopack production builds reference external modules by hashed aliases (e.g. require-in-the-middle-<hash>) that fail with "Cannot find module" when node_modules is reinstalled or laid out differently at runtime; next build --webpack works.
Unhandled 'error' event when using AbortSignal to cancel requests
Aborting a node-fetch request with a body via AbortSignal can crash the process with an unhandled 'error' event, because the request body stream has no error listener when destroyed.
Import issues with ESM and CJS
Recent releases mislabel the CommonJS build as ESM (type: module with a .js CJS file), so tools such as Vitest, Playwright and Sanity fail with "ReferenceError: exports is not defined"; 2.1.8 works.
CSS cascade order differs between dev and production when using auto-imported component styles
Production builds can link auto-imported component CSS chunks in a different order than dev (e.g. a component stylesheet before index.css), so the CSS cascade differs between dev and production and the wrong rules win.
outputSchema always emitted as JSON Schema draft-07, breaking clients that only accept 2020-12
McpServer always emits tool `outputSchema` as JSON Schema draft-07 with no way to choose 2020-12, so clients that accept only 2020-12 reject every tool that declares an outputSchema.
pytube.exceptions.RegexMatchError: get_throttling_function_name: could not find match for multiple
pytube raises `RegexMatchError: get_throttling_function_name: could not find match for multiple` when fetching streams because its regex no longer matches YouTube's player JS.
Header cell collapses when resizable set to true and promoted to staging environment
In production builds, react-data-grid header cells collapse when columns are resizable, sortable or frozen, because the minifier merges its nested `@layer` CSS rules.
Duplicate Location and x-nextjs-stale-time in Header using redirect/permanentRedirect alongside dynamic 'force-static'
Next.js emits duplicate `Location` headers for `redirect()`/`permanentRedirect()` on static/ISR routes, which some proxies and clients turn into a broken `/target,/target` redirect.
Getting 'sharredString's when trying to parse XSLX in the streaming mode
The streaming XLSX reader sometimes returns { sharedString: n } placeholder objects instead of the actual cell strings.
[v9] Data update from external source doesn't trigger rerenders in components with table object references
In TanStack Table v9 with React Compiler, replacing `data` from an external source does not re-render components built with `createTableHook`, so they keep showing stale rows.
One command for every agent in the repo.
install finds the agents configured in your project and writes each one its own hook or plugin, in its own deny format.
Pre-edit hook 15
Pauses a matching edit once, then lets the retry through.
- Claude Code
- Codex CLI
- Cursor
- Gemini CLI
- GitHub Copilot
- Windsurf / Devin
- Antigravity
- Factory Droid
- Augment
- Kiro
- Qwen Code
- Crush
- Goose
- OpenHands
- Trae
In-process plugin 5
Runs inside the agent and rejects the tool call.
- OpenCode
- Kilo Code
- Cline
- Amp
- Pi
Rules + MCP any
For agents without a pre-edit hook: the rules section, an Agent Skill and the MCP server.
- Freebuff
- Aider
- Zed
- Roo Code
- Continue
- Warp
live means run end to end against the real agent. The rest are built from each agent's documentation and tested against its payload shapes. What install writes for each.
Hosted MCP server, nothing to install
https://landmine.tech/mcp looks up the open issues filed against any exact npm or PyPI version, and checks a snippet against them. No sign-in.
$claude mcp add --transport http landmine https://landmine.tech/mcpYour terminal, your MCP client, or just ask.
Every route ends in the same place: the open issues for your exact versions, in front of the agent before it edits. uninstall removes all of it.
- Local and read-only. Only dependency names and versions leave your machine.
- Commit
.landmine/index.jsonand your team's agents share one index. - Also
npm i -D landminesorbrew install devanshranjan10/tap/landmines.
# find the open issues filed against your exact versions $ npx landmines scan # known-bugs section in AGENTS.md + CLAUDE.md, plus the pre-edit hook $ npx landmines install --rules # optional backstop for any agent: check what a commit adds $ npx landmines check --staged --exit-code
# hosted: nothing to install $ claude mcp add --transport http landmine https://landmine.tech/mcp $ codex mcp add landmine --url https://landmine.tech/mcp # local, over your project's index (stdio) $ npx landmines install --mcp claude,cursor
# Claude Code plugin: the hook, the MCP server and /landmines:scan $ claude plugin marketplace add devanshranjan10/landmines $ claude plugin install landmines@landmines # then, inside Claude Code › /landmines:scan
# paste this to your coding agent Set up landmine in this project: run npx landmines scan, then npx landmines install --rules. Before editing code that uses a dependency, read the "Known open bugs" section in CLAUDE.md, and tell me which issue you worked around. # agent-readable instructions: llms-install.md
What the numbers don't say.
It's our benchmark
No public benchmark measured this, so we built landmine-bench. Splits were frozen before tuning, a confirmation run was written down before it ran, and every result file is public.
Selection
Every trap is a bug landmine had already indexed. The benchmark shows it helps once a bug is in the index, not how many bugs it finds. Only open issues that name your exact version are found.
Prompt wording
With fully specified prompts the agent already avoids most traps (19/21 unaided, 21/21 with landmine). The gap shows up when the request reads like a real one.
The hook alone
The pre-edit hook didn't measurably beat no help. Telling the agent up front did, which is why --rules comes first.
What is landmine?
A free, open-source command-line tool (npm package landmines, MIT) that finds the open GitHub issues filed against the exact dependency versions a project pins, and puts them where a coding agent reads them before it writes code: a known-bugs section in AGENTS.md and CLAUDE.md, a pre-edit hook, and an MCP server. Each entry carries the affected API and the workaround from the issue thread.
Doesn't web search or Context7 already solve this?
Not in our measurement. On the same 21 held-out tasks, in one batch, Claude Sonnet 5.5 passed 36/42 with web search on, 35/42 with the Context7 docs MCP, 35/42 with no help, and 42/42 with the landmine rules section. In all 84 web-search and Context7 sessions the agent never called either tool: nothing told it there was a bug to look for.
How is this different from Dependabot, npm audit or Snyk?
Those tools report security vulnerabilities from advisory databases and propose upgrades. landmine reports ordinary open bugs (wrong results, crashes, type errors) filed as GitHub issues against the version you pin, whether or not a fix exists, and delivers them to the coding agent with the workaround from the thread, before it writes the code.
Which languages and lockfiles?
JavaScript/TypeScript (npm package-lock.json, pnpm, yarn classic and berry, bun) and Python (uv.lock, poetry.lock, Pipfile.lock, pinned requirements*.txt). Direct dependencies only.
Does landmine send my code anywhere?
No. scan and lookup send dependency names and versions to registry.npmjs.org, pypi.org and api.github.com. The hook and the local MCP server's index tools never touch the network. The hosted server at landmine.tech/mcp receives the versions you look up and any snippet you pass to its landmine_check, and stores no snippets.
Isn't issue text from GitHub a prompt-injection risk?
Yes, and landmine treats it as one. Every quote reaches the agent inside one delimited block labelled as untrusted third-party text, forged delimiters are neutralised, HTML is stripped, length is capped, quotes that pipe downloads into a shell or link unfamiliar hosts are flagged, and the agent is told never to follow instructions inside them.
Check your lockfile before your agent does.
Needs Node ≥ 22.12 and a GitHub token with no scopes. Commit .landmine/index.json and your team's agents share it.