He doesn't waste shots.
A plugin for your coding agent that fits the model, effort level, and context to each task — before the tokens are spent, not after. Built for Claude Code; also Codex, Gemini, Cursor & Windsurf (experimental).
deadeye init codex / init gemini. Cursor / Windsurf get the coder persona as a rules file: deadeye init cursor.npm install express mocha: 553 bytes of progress spam
shrank to 55, errors still passed through. Three separate real
measurements, not one number blended across different situations —
run /deadeye-stats savings to see your own numbers.
Why deadeye
Most tools optimize after the fact, guess at the savings, or ship your code to a server. deadeye does none of that.
Verbose test/build/install output is trimmed before it enters context — measured on real runs, not averaged: 485 bytes → 99, a 202-line passing suite → 55.
The coder persona a subagent inherits dropped from 7,666 to 1,073 bytes per spawn — measured, on every spawn.
Every figure is a real row in decisions.jsonl — and 95% of events (the quiet no-ops) aren't logged at all. No invented savings for code never written.
No phone-home, no API keys, no telemetry. All state lives in one file under ~/.deadeye/.
Model, effort, and context are fit ahead of the call from four cheap signals — no extra LLM call, no keyword-matching, reasoning always visible.
If anything inside it errors, your call passes through untouched. It advises on your main session — it never seizes your settings or your model.
How it decides
A lot of routing tools just match words in your prompt — see "architecture," assume it's a big job. deadeye instead looks at a few real signals about the task, then works out the cheapest model and effort level that should still get it done properly. The reasoning behind every decision is always visible, never a black box.
Real output, from this repo, this
session. Nothing actually changes unless you turn a setting to
enforce — by default, deadeye only advises.
Missing information never buys the
cheapest model. When deadeye can't tell how big a change is, it defaults
to a capable middle (sonnet-tier), reserving the top tier for genuinely
hard work — picking cheaper always needs real evidence above a confidence
bar. Optionally, an on-demand AI judge (claude -p, no API
key) classifies the truly ambiguous cases for a sharper call.
settings.json stays yours, untouched.Range card
Each one works on its own, has its own on/off setting, and can be switched off without touching the others.
| What | What it does | Default |
|---|---|---|
| Context | Trims verbose command output before it enters context — test suites across nine language ecosystems, builds, linters, package installs, pod logs, log tails. Also flags wasteful patterns: re-reading unchanged files, whole-reads of huge files, a command re-run (identical, or the same target with only flag changes), a URL re-fetched, an oversized MCP response, a paste-sized prompt, a long exploration streak better handed to a subagent, and a good moment to /compact before auto-compact lands mid-task. The biggest, safest win. | on |
| Coder | A lean-first coding persona injected every session (it survives compaction) and into subagents: question whether the code needs to exist, stdlib before custom code, one line before fifty — plus a live security check on what's written and its dependencies. Three levels — spotter, marksman, sniper. | marksman |
| Security | The exfiltration guard — a Read of a credential file, or a Bash command shipping one out, escalates to a permission prompt the model can't answer for itself. Adding a known-vulnerable dependency asks too; existing ones get flagged at session start. Independent of coder mode. | ask |
| Codebase map | A persistent per-project map — directory/package skeleton, most-touched files accumulated across every session, recent exploration notes — injected once per session so a fresh session doesn't re-explore the repo from scratch. | on |
| Effort | Suggests lower effort for mechanical steps. Has no effect if CLAUDE_EFFORT is already pinned for the session — /deadeye-status tells you plainly if that's the case. | advise |
| Model | Picks the model when a subagent starts. Prices come from a table built into the binary, refreshed each release — there's no live pricing API a background hook process could reach. | advise |
| Plan gate | Asks once before a multi-file edit that skipped writing a plan first, then stays quiet for the rest of that task. | soft |
| Workflow | Suggests the ultracode keyword when a task looks like genuine parallel/fan-out work. Only ever suggests it — never starts one for you. | on |
Fits alongside the built-ins
Claude Code ships its own reviews, plan mode, and size-based output truncation. deadeye doesn't compete — it layers under and around them. The three deepest — coder mode, security, and the codebase map — expand below.
| /code-review, /simplify | deadeye-review is the lean lens only: verified findings, net-lines accounting, cuts that flow into the debt ledger — the working diff by default, or the whole repo with --repo. Instant local pass; escalate to ultra for pre-merge depth. | layers |
| /security-review | deadeye-guard is the diff-scoped lean pass: live regex/manifest advisories while you type, then a verify-before-report deep check on demand across seven exposure classes — injection, secrets, authz, crypto, exposure, vulnerable deps, DoS — with native-auditor (govulncheck / OSV) coverage. Escalate to /security-review for the full audit. | layers |
| PR review | deadeye-pr runs a whole PR through four lenses — over-engineering, correctness, performance, security — as terse tagged findings, each carrying its proof and confirmed against the repo's own tools and tests. Severity-ranked; prints locally, opt-in --post for inline per-line comments. Huge PRs fan out to parallel subagents — each spawned at the cheapest model tier its cluster needs, the top tier reserved for risky surfaces — so nothing is truncated and the review stays cheap. | four lenses |
| Plan mode | Native plan mode exists but nothing triggers it — deadeye's gate notices a risky multi-file edit coming and nudges into it. | triggers |
| Output truncation | Native truncation is size-based at 30K chars. deadeye rewrites commands before they run so only failure context enters at all — and stacks under the native cap. | stacks |
| Subagent models | Native subagents inherit the parent's model. deadeye recommends the cheapest tier the evidence supports, says why, and learns from your escalations — with an opt-in AI judge (claude -p, no API key) for the genuinely ambiguous cases. | advises |
| Coding persona | No native equivalent — coder mode is deadeye's own ground. | unique |
| Other hosts | Experimental: the same daemon serves OpenAI's Codex through its hooks — output trimming, coder persona, plan gate, decision log — via deadeye init codex. Gemini CLI gets the coder persona and session guidance now (init gemini); its tool-level engine waits on live schema verification. Cursor and Windsurf have no hook contract, so they get the coder persona alone as a rules file (init cursor / init windsurf). And /deadeye-pr — the four-lens PR review — installs on all four via init in each host's native command format, experimental until live-verified. | five hosts |
Beyond routing and trimming, deadeye can inject a coding persona: a lazy-senior-dev discipline that pushes every change toward the leanest solution that actually works. Injected at every session start — it survives compaction — and travels into subagents too.
| Spotter | Calls the shot, doesn't take it: builds what's asked, names the leaner alternative in one line. You pick. | light |
| Marksman | The lean-first ladder enforced: YAGNI, stdlib before custom code, native before dependencies, shortest working diff. | default |
| Sniper | One shot only. Ships the one-liner and challenges the rest of the requirement in the same breath. | max |
Deliberate shortcuts get a
deadeye: comment naming the ceiling and upgrade trigger —
/deadeye-debt collects them into a ledger. Safety isn't
just preserved, it's checked for: input validation, error handling
that prevents data loss, security, and accessibility stay at every
level, and a live pass flags injection, secrets, weak crypto, and
vulnerable dependencies as you write.
Off any time: say
normal mode, or DEADEYE_CODER=off. An
optional statusline badge shows each session's live level — deadeye
offers the setup once and never edits your settings itself.
| Inject | The ruleset ships embedded in the binary. At every session start the daemon prints it into the model's context, filtered to the active level — a marksman session never pays tokens for the other levels' rows. | start |
| Survive | When Claude Code compacts a long conversation, the hook fires again and re-injects at whatever level you'd switched to. No drift back to over-building. | compact |
| Travel | Subagents inherit a condensed card — just the behavior-bearing rules. Measured: 7,666 bytes per spawn before, 1,073 after, an 86.0% cut on every spawn. Scope it with coder.subagent_matcher. | −86.0% |
| Resolve | Kill switch beats your session switch, beats coder.default_level in config, beats the built-in default. Switches last until the session ends. | precedence |
| Guard | Every Edit/Write is checked against the ADDED text only — injection shapes, secrets, provider tokens, weak crypto, TLS-off, across five languages — plus the dependency itself on a manifest edit. Independent of the persona level now, so stop coder doesn't silence it. Deep pass on demand: /deadeye-guard. | check-your-backstop |
Every answer keeps one shape:
code first, then at most three short lines — what was skipped, and
when to add it. Bug fixes go to the root cause every caller routes
through, not the one path the ticket named. Comments follow their
own rule: the why, never the what — and corner-cuts use a pinned
grammar (deadeye: … ceiling: … upgrade: …) that
/deadeye-debt parses reliably.
The safe form is usually the
SHORT form — a parameterized query beats hand-rolled escaping,
exec.Command(bin, args...) beats building a shell
string. Lean and safe are the same move.
Editing a manifest checks the
dependency too: a bundled table flags packages the platform has
since absorbed (request → fetch,
moment → Temporal/date-fns),
and an optional OSV.dev lookup catches known vulnerabilities — name
and version only, nothing else about the code, and never on the
hook's response path: a cache miss refreshes in the background and
informs the next edit, never blocks this one. Turn just
that lookup off with coder.security_osv: false; the
bundled table keeps working fully offline. /deadeye-guard
is the on-demand deep pass — diff-scoped, verifies a missing
sanitizer or authz check against the surrounding code before
reporting it, and runs govulncheck/npm
audit/pip-audit/cargo audit when
installed.
The real attack on a coding agent isn't bad code you write — it's malicious content in a repo or a web page telling the agent to read your credentials and ship them out. deadeye already sits at the exact choke points, so it watches them: the moment that matters escalates to a prompt you answer, not one the model can talk itself past.
Covers ssh private keys,
~/.aws/credentials, .env,
~/.claude/.credentials.json, ~/.netrc,
kube/docker/gcloud/gh tokens, and your own
security.sensitive_paths — on Read and on a
Bash command shaped to ship one out (a credential piped to
curl/nc/scp, an env dump to the network). Default
ask; soften to advise or off.
| Its own axis | The exfil guard is security.exfil, not part of coder mode — turning the persona off never turns it off. Only DEADEYE=off or security.exfil: "off" does. | ask |
| Not a mood | The live Edit/Write check (injection shapes, secrets, provider tokens, weak crypto, TLS-off, across five languages) no longer dies when you say stop coder. Security is part of coding, not the persona's voice. | advise |
| Vulnerable deps | Adding a package with a confirmed OSV advisory asks by name (coder.security: "ask"). And once per session deadeye flags what's already in your tree with a known advisory. | ask |
| Provider tokens | A bare ghp_…, xoxb-…, sk-ant-…, Stripe live key, or signed JWT pasted as a literal is caught even with no key = around it — length-bound so prose never trips it. | secret |
Honest ceiling: the exfil guard
matches regex-visible shapes, not shell obfuscation or a novel
egress binary. It shrinks the blast radius of the common automated
attack — it isn't a sandbox. /deadeye-guard is the
deep, diff-scoped pass with native auditors.
A fresh session normally burns 15–40 tool calls
rediscovering the project — directory layout, what each package does,
which files matter. deadeye persists that per project under
~/.deadeye/map/ and injects it once, at the first prompt.
| Skeleton | Directory rows with file counts and, for Go repos, each package's one-line doc-comment purpose. Built from git ls-files, regenerated only when the tracked-file list changes. | map.md |
| Touch counter | A path → sessions counter merged at every session end, ranked by relevance rather than recency — a file touched in 14 of 20 sessions stays on top. | touched.json |
| Exploration notes | The explore skill caches its summary via deadeye notes-append so the next session inherits findings instead of re-deriving them. Newest 5 kept. | notes.md |
First-ever session in a project gets nothing — the map is written at session end, so value starts at session #2. Resumed or compacted sessions are skipped; their context already carries the exploration.
Lives under
mode.codemap (off/on,
default on) — the same DEADEYE=off kill
switch turns it off along with everything else.
Measured, not estimated
Every time deadeye trims something, it logs which rule
fired. Every decision is logged with what went into it. Nothing here is
a made-up formula that turns "we ran N tool calls" into a savings
number — if it isn't a real row in decisions.jsonl, it
doesn't get printed.
Unedited output from a real feature task run through the installed plugin — a cheaper model suggested before a subagent started, both commands trimmed, an end-of-turn savings summary. The 25,800 figure is each rule’s own labelled estimate; the 485 → 99 and 10,301 → 55 numbers up top are the measured ones. Yours shows whatever your log holds — and quiet noop rows (95% of events) aren’t logged at all.
Install
macOS and Linux need nothing else. Windows: grab the binary from Releases first — self-bootstrap there isn't built yet.
No. Everything it remembers lives in one file on your own machine,
at ~/.deadeye/. No hosted service, no API keys, no
telemetry.
That's exactly the failure mode it's built to avoid. When it isn't
confident about a task, it defaults to the more capable option —
picking something cheaper always needs real evidence first. If you
find a case where it under-powered a task, that's a bug — report it
along with the /deadeye-route output.
Each rewrite rule is conservative by design, and every one of them can be turned off individually in config. A rule that loses information the agent actually needed is a bug in that rule — please report it along with the command.
No — nothing can do that reliably partway through a session. deadeye actually changes the model for subagents, where most of the token spend happens, and only advises (never enforces) on the main session.
No. The persona never simplifies away input validation at
trust boundaries, error handling that prevents data loss,
security measures, or accessibility basics — at any level. And
every deliberate shortcut it does take gets a
deadeye: marker with an upgrade trigger, so
/deadeye-debt can hold it accountable later.
Because efficiency isn't spending less — it's not missing.