deadeye.

He doesn't waste shots.

A plugin for your coding agent that picks the right model, effort level, and amount of context for the task in front of it — before the tokens are spent, not after. Built for Claude Code; runs on OpenAI's Codex CLI too (experimental).

built for Claude Code works with Codex CLI · experimental
$ /plugin marketplace add deepaksinghcs14/deadeye-cc
$ /plugin install deadeye@deadeye
Hooks register themselves. Binary bootstraps on first use, sha256-verified.
On Codex CLI: install the binary, then deadeye init codex.
go test -v — raw485 bytes
14 lines — 4 PASS lines, 1 FAIL with its
context, carried into the conversation whole.
go test -v — deadeye99 bytes
$ go test ./... -v 2>&1 | grep -A 5 -E '(FAIL|ERROR|error:|panic:)' | head -120 --- FAIL: TestReconciliationAppliesTaxBeforeDiscount (0.00s) FAIL FAIL canondemo/orders 0.539s FAIL
The rewrite happens before the command runs.
79.6%–99.5% smaller, measured on real runs, not averaged. This run: 485 bytes shrank to 99. This repo's own full test suite (202 lines, 10,301 bytes, all passing): shrank to 55 bytes. A real 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-audit to see your own numbers.

How it decides

Reads the task, not keywords

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.

  • LookWhich files are touched, recent git activity, whether tests exist nearby, how specific the request reads. Four cheap signals — no LLM call, no network request.
  • DecideModel and effort level matter together — a mid-tier model on high effort can match a top-tier model on low effort. deadeye works out the cheapest combination that should still clear the bar for this task, not a fixed tier picked by rule of thumb.
  • ApplyPicks the model when a subagent starts — but only if you didn't already pick one yourself. Trims noisy output before it enters context. Asks before a multi-file edit that skipped a plan.
  • LearnIf you manually pick a bigger model than it recommended, that gets logged and makes it more cautious for that kind of task next time. Detecting "this edit actually broke something later" is still on the roadmap.
/deadeye-route "fix the null check in handler.go" Evidence: promptshape complexity=0.00 confidence=0.85 filescope complexity=0.15 confidence=0.85 gitchurn complexity=0.30 confidence=0.82 testpresence complexity=0.10 confidence=0.80 Decision: model: claude-haiku-4-5-20251001 effort: medium confidence: 0.80 reason: all evidence supports downshift: low complexity, confidence >= threshold

Real output, from this repo, this session. Nothing actually changes unless you turn a setting to enforce — by default, deadeye only advises.

Range card

Six things it manages

Each one works on its own, has its own on/off setting, and can be switched off without touching the others.

What / effect / default settingoff · advise · enforce
WhatWhat it doesDefault
ContextTrims verbose command output before it enters context — test suites across nine language ecosystems, builds, linters, package installs, pod logs, log tails. Also flags wasteful reads: re-reading unchanged files, whole-reads of huge files, identical commands run twice in a row. The biggest, safest win.on
CoderA 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. Three levels — spotter, marksman, sniper.marksman
EffortSuggests 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
ModelPicks 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 gateAsks once before a multi-file edit that skipped writing a plan first, then stays quiet for the rest of that task.soft
WorkflowSuggests the ultracode keyword when a task looks like genuine parallel/fan-out work. Only ever suggests it — never starts one for you.on

Coder mode

A marksman's coding discipline

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.

Level / discipline/deadeye-coder
SpotterCalls the shot, doesn't take it: builds what's asked, names the leaner alternative in one line. You pick.light
MarksmanThe lean-first ladder enforced: YAGNI, stdlib before custom code, native before dependencies, shortest working diff.default
SniperOne 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 is never cut: input validation, error handling that prevents data loss, security, and accessibility stay, at every level.

/deadeye-coder sniper DEADEYE CODER CHANGED — level: sniper every session start: DEADEYE CODER ACTIVE — level: sniper the ladder, abridged: 1. Does this need to exist at all? 2. Already in this codebase? 3. Stdlib does it? 4. Native platform feature covers it? 5. Already-installed dependency solves it? 6. Can it be one line? 7. Only then: the minimum code that works.

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.

How it worksone ruleset, filtered
InjectThe 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
SurviveWhen 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
TravelSubagents inherit a condensed card — just the behavior-bearing rules. Measured: 6,029 bytes per spawn before, 887 after, an 85.3% cut on every spawn. Scope it with coder.subagent_matcher.−85.3%
ResolveKill switch beats your session switch, beats coder.default_level in config, beats the built-in default. Switches last until the session ends.precedence
the same request, per level -- "add a cache for these API responses": spotter Done, cache added. FYI: lru_cache covers this in one line if you'd rather not own a cache class. marksman @lru_cache(maxsize=1000) on the fetch function. Skipped custom cache class, add when lru_cache measurably falls short. sniper No cache until a profiler says so. When it does: @lru_cache. A hand-rolled TTL cache is a bug farm with a hit rate.

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.

Fits alongside the built-ins

Covers what Claude Code doesn't

Claude Code ships its own reviews, plan mode, and size-based output truncation. deadeye doesn't compete — it layers under and around them.

Built-inwhat deadeye adds
/code-review, /simplifydeadeye-review is the lean lens only: verified findings, net-lines accounting, cuts that flow into the debt ledger. Instant local pass; escalate to ultra for pre-merge depth.layers
Plan modeNative plan mode exists but nothing triggers it — deadeye's gate notices a risky multi-file edit coming and nudges into it.triggers
Output truncationNative 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 modelsNative subagents inherit the parent's model. deadeye recommends the cheapest tier the evidence supports, says why, and learns from your escalations.advises
Coding personaNo native equivalent — coder mode is deadeye's own ground.unique
Codex CLIExperimental: the same daemon serves OpenAI's Codex through its hooks system — output trimming, coder persona, plan gate, and the decision log, verified against real Codex runs. deadeye init codex shows the exact config change and writes nothing without your yes; deadeye update is the one-command updater.two hosts

Measured, not estimated

Every number here comes from a logged decision

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.

/deadeye-audit real session, this repo -- add Mark() + test, subagent delegated 17 decisions logged by surface PostToolUse 7 PreToolUse/Edit 3 PreToolUse/Agent 1 SessionEnd 1 PreToolUse/Bash 2 Stop 2 SubagentStart 1 by action advise 1 noop 13 rewrite 2 savings-shown 1 preprocessing rewrites (estimated bytes -- see each rule's EstBeforeBytes/EstAfterBytes, not a measurement of this run) build-filter 1x ~15,000 → ~9,600 bytes test-filter 1x ~30,000 → ~9,600 bytes total ~45,000 → ~19,200 bytes (~25,800 saved) Cross-check these figures against /usage's plugin attribution.

Real /deadeye-audit output, unedited: a real feature task (add a method, write its test, verify with go build/go test, hand part of it to a subagent) run through the installed plugin — not a scripted demo. deadeye suggested a cheaper model before the subagent started, both commands had their output trimmed, and the turn ended with a savings summary. The 25,800 figure is each rewrite rule's own estimate (the same number this command always prints, and it labels it as an estimate right there in the output). The 485 → 99 and 10,301 → 55 numbers above are the real measured ones; this log is here to show model-picking, output-trimming, and the end-of-turn summary all firing together on one real task. Yours will show whatever your own log contains — and since v0.7.0, quiet noop events (95% of all rows on one real machine: 812 of 856) aren't logged at all, so your log holds only the rows where deadeye actually did something. Newest measured win, same log: the coder persona a subagent inherits went from 6,029 bytes per spawn to 887 — an 85.3% cut, logged as coder-subagent bytes_after on every spawn.

The rule behind everything

When it doesn't know, it goes big

Missing information never buys a cheaper model. If deadeye can't tell how big or risky a change really is, it assumes the worst case. Picking something cheaper always needs real supporting evidence above a minimum confidence level; picking something more capable never needs a reason.

  • Wrong-but-expensive is recoverableWorst case, it costs you some money. Wrong-but-cheap costs you a bad diff, plus the time spent finding it.
  • Never touches your settingsdeadeye keeps its own state in one file. Your settings.json stays yours, untouched.
  • Never blocks your workIf anything inside deadeye errors, that call just passes through untouched. A tool like this should never be the reason your work stops.

Install

Two commands

/plugin marketplace add deepaksinghcs14/deadeye-cc /plugin install deadeye@deadeye

macOS and Linux need nothing else. Windows: grab the binary from Releases first — self-bootstrap there isn't built yet.

Turn it off

DEADEYE=off everything DEADEYE_PREPROCESS=off context hygiene DEADEYE_GATE=off plan gate DEADEYE_CODER=off coder persona
Does it phone home?

No. Everything it remembers lives in one file on your own machine, at ~/.deadeye/. No hosted service, no API keys, no telemetry.

Will it make Claude dumber?

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.

It rewrote a command and I needed the full 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.

Can it change the model my main session is using?

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.

Does coder mode cut corners on safety?

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.

Why "deadeye"?

Because efficiency isn't spending less — it's not missing.