Docs · v0.2
Everything landmine does, in one page.
Scan once, tell the agent first, keep the hook as a backstop. Node ≥ 22.12. The npm package is landmines, with an s; it installs the landmine and landmines commands.
Quickstart
In your project's root:
npx landmines scan # find the open issues filed against your exact versions npx landmines install --rules # known-bugs section in AGENTS.md + CLAUDE.md, plus the pre-edit hook
scan needs a GitHub token, because GitHub search and GraphQL require auth. It uses GITHUB_TOKEN, then GH_TOKEN, then gh auth token. A token with no scopes is enough for public repositories.
Start with the rules section. On landmine-bench it took Claude Sonnet 5.5 from 86% to 99%; the hook alone didn't significantly beat no help. --rules writes both. Claude Code doesn't read AGENTS.md, which is why CLAUDE.md gets its own copy.
Re-run scan after you change dependencies. The hook only reads the index.
Install options
npx landmines <command> # no install npm i -D landmines # dev dependency (recommended for teams) npm i -g landmines # global: `landmine` and `landmines` on PATH brew install devanshranjan10/tap/landmines # Homebrew (also: devanshranjan10/tap/landmine)
install writes the hook command that matches how you installed, so it keeps working for everyone:
| Installed as | Command it writes |
|---|---|
| dev dependency | npx --no-install landmines hook |
npx / pnpm dlx / bunx | the pinned npx -y landmines@<version> hook |
| global | landmine hook |
| source checkout | absolute paths, with a warning |
The same package is on GitHub Packages as @devanshranjan10/landmines; that needs a token with read:packages, so npm is the simpler route. landmine (no s) on npm is an unrelated package.
Teams and CI
npm i -D landmines npx landmines scan && npx landmines install --rules git add .landmine/index.json .landmine/cards AGENTS.md CLAUDE.md
- Commit the index.
.landmine/index.json(and.landmine/cards/) lets teammates and CI share one index..landmine/.gitignorekeeps the raw cache and the per-machine install registry out of git. - Pre-commit or CI backstop, for agents with no pre-edit hook:
npx landmines check --staged --exit-codechecks only the lines a commit adds and exits 1 on a blocking match. - Refresh the index on a schedule with
npx landmines scan. If a package can't be fetched, its previous issues are kept, marked stale, and the scan exits 2.
Commands
Run each as npx landmines <command>, or landmine <command> after a global install.
| Command | What it does |
|---|---|
scan | Reads lockfiles, queries npm, PyPI and GitHub, and writes .landmine/index.json. Raw responses are cached for 24 h. Flags: --refresh, --offline (re-analyse the cache, no network), --max-issues 100, --prod, --json, -q. |
install | Adds the hook or plugin for Claude Code plus every agent whose config is in the project. Leaves your other hooks alone; running it again is harmless. --harness auto|all|<names>, --mode block|warn, --heads-up, --mcp [agents], --rules [files]. |
rules | Prints, or writes between <!-- landmine:start/end --> markers, a short known-bugs section any agent reads, ranked by the APIs your code uses. --write <files>, --skill (full list as an Agent Skill), --max 15, --rank usage|confidence. |
cards | Optional. A model reads each indexed issue once and writes a trigger card. At most 50 new model calls per run unless --all. --provider anthropic|claude-cli|openai, --model, --from, --export. |
check <files> | Treats whole files as just written and reports matches, marked [blocks: …] or [heads-up only]. --exit-code [--strict], --json. |
check --staged | Checks only the lines staged for commit. |
mcp | Runs the MCP server over stdio. |
list [package] | Shows indexed issues; by default only the ones the hook can act on. --all, --json. |
share | One postable line about this project's scan, plus a README badge. Counts and package names only. |
uninstall | Removes landmine's hook entries, plugin files, rules sections and skill. |
hook | The hook entry point: harness payload on stdin, response on stdout. You don't call it yourself. |
Agents
One normaliser reads every agent's payload shape (tool names, argument keys, patch formats) and answers in that agent's own deny format. live means run end to end against the real agent; "from docs" means built from the agent's documentation (and source, where open) with each payload shape covered by a test.
| Agent | What install writes | Verified |
|---|---|---|
| Claude Code | PreToolUse hook, .claude/settings.json | live 2.1.304: blocked once, agent changed approach |
| Codex CLI | PreToolUse on apply_patch, .codex/hooks.json | live 0.159.0; trust the hook with /hooks |
| OpenCode | plugin, .opencode/plugins/landmine.ts | loaded live in 1.18.33; a blocked edit not yet run live |
| Cursor | preToolUse, .cursor/hooks.json | from docs |
| Gemini CLI | BeforeTool, .gemini/settings.json | from docs |
| GitHub Copilot | .github/hooks/landmine.json | from docs |
| Windsurf / Devin | pre_write_code, .devin/hooks.json | from docs |
| Antigravity | .agents/hooks.json | from docs |
| Factory Droid | .factory/hooks.json | from docs |
| Augment (Auggie) | .augment/settings.json | from docs |
| Kiro | .kiro/hooks/landmine.json | from docs |
| Qwen Code | .qwen/settings.json | from docs |
| Crush | crush.json | from docs |
| Goose | .agents/plugins/landmine/ | from docs |
| OpenHands | .openhands/hooks.json | from docs |
| Trae | .trae/hooks.json | from docs |
| Kilo Code | plugin, .kilo/plugin/landmine.ts | tested against a stub host |
| Cline | plugin, .cline/plugins/landmine.ts | tested against a stub host |
| Amp | plugin, .amp/plugins/landmine.ts | tested against a stub host |
| Pi | extension, .pi/extensions/landmine.ts | tested against a stub host |
| Freebuff, Aider, Zed, Roo, Continue, Warp… | no pre-edit hook: rules --write AGENTS.md, rules --skill, install --mcp, check --staged | rules, skill and MCP config tested |
install --mcp <agents> registers the MCP server in the project config of 16 agents: Claude Code, Cursor, Gemini CLI, Qwen, Copilot, Droid, Kiro, Trae, Antigravity, Freebuff, Roo, Warp, Pi, OpenCode, Kilo and Crush. Codex, Windsurf and Cline keep MCP servers in user-level config; for Codex run codex mcp add landmine -- npx -y landmines mcp.
Hook behaviour
- Blocks once, then steps aside. The default
--mode blockdenies an edit once per issue per agent session, and only for corroborated matches: the edit uses an issue's symbol and the file also uses something else the issue names (an option, a sibling API, the database driver). The retry goes through. - Weaker matches are dropped by default: on held-out real code about 93% of them didn't apply.
--heads-uppasses them as non-blocking context;--mode warnnever blocks. - Fast and offline. About 0.11 s per call including Node startup, with a 149 KB index. It never touches the network.
- Never says "allow", so your own permission prompts still apply.
- Fails open. Any error, a missing index or an unknown payload means no output, and the edit goes through.
MCP server
The hook stays quiet unless a match is strong. The MCP server is for when the agent is already looking: a confusing error, or behaviour it can't explain. Three read-only tools:
landmine_check: a file in the project, or a snippet.landmine_search: error text or an API name.landmine_list: the indexed issues.
npx landmines install --mcp claude,cursor # comma-separated; plain --mcp means Claude CodeIn a live Claude Code session, asked whether inconsistent RootModel equality was a known bug in the pinned pydantic, Claude called landmine_search and answered with pydantic#10544, reported against 2.9.2.
Trigger cards
Optional. A model reads each issue thread once and writes a card: the APIs, the extra conditions that make the bug fire, tokens that show the workaround is already applied, and the workaround. Each card is self-checked against the issue's own repro. The hook, rules and MCP server use cards when present; the hook never calls a model.
npx landmines cards --provider claude-cli # uses an existing Claude Code login npx landmines cards --provider openai # any OpenAI-compatible endpoint (OPENAI_BASE_URL) npx landmines cards --provider anthropic # needs @anthropic-ai/sdk installed
Cards are cached per issue, version and model. Each run prints its plan first and caps new model calls at 50 unless you pass --all.
Lockfiles and languages
- npm:
package-lock.jsonv1–v3,npm-shrinkwrap.json - pnpm:
pnpm-lock.yaml5.4, 6 and 9 - yarn: classic and berry
- bun:
bun.lock(text; binarybun.lockbis not supported) - Python:
uv.lock,poetry.lock,Pipfile.lock, pinnedrequirements*.txt
Only direct dependencies are checked. Source files: JS/TS (.js .jsx .ts .tsx .mjs .cjs .mts .cts) and Python (.py .pyi), read with a tolerant lexer so half-written code works. In .vue, .svelte and .astro files, template expressions can be missed.
Exit codes
| Code | Meaning |
|---|---|
0 | Success. |
1 | check --exit-code found a match that would block an edit. With --strict, a heads-up match counts too. |
2 | An error or a partial result: bad input, a scan that couldn't fetch every package, or cards that failed. |
The hook always exits 0 (it fails open), except in the exit2 format, where a block is exit code 2 with the reason on stderr.
Security
- Untrusted text reaches your agent. Issue titles, quotes and card summaries come from strangers on GitHub. landmine puts all of it inside one delimited untrusted block, neutralises forged delimiters, strips HTML, caps length, flags quotes that pipe a download into a shell or link unfamiliar hosts, and tells the agent never to follow instructions inside them. Don't let an agent run a quoted workaround without reading it.
- Network.
scansends your direct dependency names and versions to registry.npmjs.org, pypi.org and api.github.com.cardssends each indexed issue's public thread to the model provider you choose. Nothing else leaves your machine. - Credentials. The GitHub token is sent only to api.github.com and never written to the index, cache or logs.
- Files. Only
.landmine/, the agent config filesinstallnames, and the marker-delimited rules sections.installrefuses to rewrite a settings file it can't parse without losing comments.
Report vulnerabilities privately through the repository's security advisory form.
Uninstall
npx landmines uninstall
Removes landmine's hook entries, plugin files, rules sections and skill, deletes config files and directories it leaves empty, and skips config it never touched. Delete .landmine/ to remove the index.