Claude Code plugin that fits the model, effort, and context to each task — fewer tokens, same quality. Deterministic policy kernel in the hooks; every number it reports is measured, not estimated.
FAQ
deadeye is a Claude Code plugin with 7 hand-picked skills for development work, indexed on Flowy. Install it with the command on its page. It includes deadeye-coder, deadeye-debt, deadeye-gain. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
> /plugin marketplace add deepaksinghcs14/deadeye-cc> /plugin install deadeye@deadeye
Repo: deepaksinghcs14/deadeye-cc
He doesn't check twice or spray and pray — he doesn't need to. deadeye is a Claude Code plugin that watches what your agent is about to do — spawn a subagent, dump a noisy test log, make a big multi-file edit — and picks the cheapest model, effort level, and amount of context that will still get the job done right. Left on its own, Claude Code tends to spend more tokens than a task actually needs. deadeye catches that before the tokens are gone. Site →
You ask your agent to run the test suite before merging, and one test is actually broken.
Without deadeye:
All 14 lines of verbose output enter context — 4
PASSlines, then the failure, no differently weighted than if all 5 had passed.
With deadeye:
--- FAIL: TestReconciliationAppliesTaxBeforeDiscount (0.00s) FAIL FAIL canondemo/orders 0.539s FAIL
(On that real run: 485 bytes shrank to 99 — a 79.6% reduction — and the
failure details stayed fully intact. On this repo's own full test suite,
which all passes: 10,301 bytes shrank to 55, a 99.5% reduction. On a real
npm install express mocha: 553 bytes of progress/funding/audit spam
shrank to 55, a 90.1% reduction, with errors and warnings still passed
through when they occur. Three separate real measurements, not one number
averaged across different situations — see
the site for details, or
run /deadeye-audit to see your own numbers. One gotcha worth knowing: an
early, naive version of this filter could report a passing test suite as
"failed" whenever the filter pattern matched nothing. That's fixed now,
and tested against both directions.)
deadeye also shows one quiet line at the end of a turn, telling you how
much it's kept out of context so far this session — deadeye: ~9,600 bytes kept out of context this session (1 rewrite). It only shows up
when that total has actually grown since the last time you saw it.
Not a scripted demo — a real feature task run through the installed
plugin: add a Mark() method to a small package, write a test for it,
verify with go test and go build, and hand part of the work off to a
subagent. Here's the decision log for that one turn:
PreToolUse/Agent advise all evidence supports downshift: low complexity, confidence >= threshold
SubagentStart noop
PreToolUse/Bash rewrite reason=test-filter
PreToolUse/Bash rewrite reason=build-filter
Stop savings-shown bytes_after=25800
(One thing has changed since this log was captured: as of v0.7.0 quiet
events aren't logged at all — on one real machine noop rows were 812 of
856 total, ~95% noise — so your log will show only the rows where deadeye
actually did something.)
deadeye recommended a cheaper model before the subagent even started, both
the test and build commands had their noisy output trimmed, and the turn
ended with deadeye: ~25,800 bytes kept out of context this session (2 rewrites). That 25,800 number is an estimate each rewrite rule carries
around (the same number /deadeye-audit prints, and it labels it as an
estimate right there in the output) — not a fresh measurement of this
specific task, whose real output happened to be pretty small. The
485 → 99 and 10,301 → 55 numbers above are the actual measured ones;
this example is here to show the model-picking, output-trimming, and
end-of-turn summary all working together on one real task, not to add a
third headline number.
1. Look Checks a few cheap, deterministic signals: files touched, recent git activity, whether tests exist nearby, how the request reads
2. Decide Picks the cheapest (model, effort) combination that should still clear the bar for this task
3. Apply Rewrites the subagent's model, trims noisy command output, and asks before risky multi-file edits
4. Learn If you manually pick a bigger model than it recommended, it remembers and gets more cautious for that kind of task next time
The rule behind all four steps: when it doesn't know, it goes big.
Missing or shaky evidence never buys a cheaper model or a lower effort
level — deadeye defaults to the most capable option. Picking something
cheaper requires real supporting evidence and a minimum confidence level;
picking something more capable never needs a reason. Every decision is
printable — run /deadeye-route any time to see the full reasoning, not
a black box. Full config schema:
schema/config.schema.json.
/plugin marketplace add deepaksinghcs14/deadeye-cc
/plugin install deadeye@deadeye
That's everything on macOS/Linux — hooks, slash commands, and the binary bootstraps itself on first use (downloaded once from Releases, sha256-verified). On Windows the hooks and daemon work too (PowerShell hook scripts ship in the plugin) — but grab the binary from Releases yourself first (self-bootstrap isn't built there), and the optional statusline badge is bash-only for now.
deadeye also runs under OpenAI's Codex CLI, whose experimental hooks system speaks (nearly) the same contract. Install the binary (from source or Releases), then:
deadeye init codex
That shows you the exact ~/.codex/hooks.json changes and writes them
only after you confirm — deadeye never edits another tool's config
silently. Codex will ask you to trust the hooks on first run (its
prompt, not ours), and hooks need [features] hooks = true in
~/.codex/config.toml.
What works on Codex — verified live, not assumed: output trimming and
all advisories (rewrites confirmed working through real Codex runs),
the coder persona (injected at session start, re-injected after
compaction, level switching by typing /deadeye-coder … as a prompt),
the plan gate (Codex edits arrive as apply_patch), /deadeye-mute,
and the full decision log. Not on Codex: model routing (no subagent
surface to route) and the statusline badge. Update any time with one
command — deadeye update fetches the latest release, sha256-verifies
it, and swaps it in atomically (the daemon hands over on the next hook
call). Remove cleanly with deadeye uninstall codex.
go install github.com/deepaksinghcs14/deadeye-cc/cmd/deadeye@latest
A binary already on PATH always beats the bootstrap, so your build stays in charge.
deadeye uninstall --purge # removes the binary, the daemon socket, and ~/.deadeye
Then /plugin uninstall deadeye@deadeye in Claude Code.
| Command | What it does |
|---|---|
/deadeye-status | Shows current modes, coder level, kill switches, model list, and whether the background daemon is running |
/deadeye-route [task] | Shows what deadeye would decide for a task, and why — without actually doing anything |
/deadeye-audit | Prints a savings report straight from the decision log |
/deadeye-gain | Compact measured-impact scoreboard from the same log |
/deadeye-coder [level] | Switch or report the coder persona level |
/deadeye-mute [off] | Mute advisories, plan-gate nags, and workflow hints for this session (rewrites keep working) |
/deadeye-review | Over-engineering review of the current diff |
/deadeye-sweep | Whole-repo over-engineering audit |
/deadeye-debt | Ledger of every deadeye: shortcut marker in the repo |
/deadeye-help | Quick-reference card for all of the above |
deadeye lessons [reset] | Inspect (or clear) the recorded routing outcomes that bias future decisions |
deadeye update | Update the managed binary to the latest release (sha256-verified, atomic) — the one-command updater for Codex-only installs |
deadeye uninstall --purge | Removes the binary, its background process, and all local state |
deadeye also ships a coding persona: a lazy-senior-dev discipline that pushes every change toward the leanest solution that actually works — question whether the code needs to exist at all, reach for the standard library before custom code, native platform features before dependencies, one line before fifty. It's injected at the start of every session (surviving compaction) and travels into subagents too.
Three intensity levels:
| Level | What it does |
|---|---|
spotter | Builds what's asked, but names the leaner alternative in one line — you pick |
marksman | The lean-first ladder enforced. Shortest working diff. Default. |
sniper | Maximum minimalism — ships the one-liner and challenges the rest of the requirement in the same breath |
/deadeye-coder spotter|marksman|sniper|off/deadeye-coder default <level>
(writes deadeye's own ~/.deadeye/config.json — never Claude's settings)normal mode or stop coderDEADEYE_CODER=offOne canonical ruleset ships embedded in the deadeye binary. At every
session start the background daemon prints it straight into the model's
context, filtered to the active level — so a marksman session never
pays tokens for the spotter and sniper rows. Long sessions hold: when
Claude Code compacts the conversation, the SessionStart hook fires again
and the persona is re-injected at whatever level you'd switched to.
Subagents inherit it too — but not the whole thing: they get a condensed
card carrying just the behavior-bearing rules. Measured from the decision
log: 6,029 bytes per spawn before, 887 after — an 85.3% cut, paid on
every single subagent your sessions ever launch. (Scope subagent
injection with coder.subagent_matcher in config if you only want it in
some agent types.)
Which level governs a session is resolved in strict order: the
DEADEYE_CODER=off kill switch wins, then an explicit /deadeye-coder
switch you made this session, then coder.default_level from config,
then the built-in default (marksman). Level switches are handled by the
daemon, take effect on your next message, and last until the session ends.
The persona is a decision ladder the model climbs before writing anything, stopping at the first rung that holds:
Concretely, the same request comes back differently per level. Ask for "a cache for these API responses" and:
functools.lru_cache
covers this in one line if you'd rather not own a cache class."@lru_cache(maxsize=1000) on the fetch function and
notes what was skipped and when to add it.Answers follow a fixed shape — code first, then at most three short lines: what was skipped, and when to add it. Bug fixes go to the root cause (one guard in the shared function every caller routes through, not a patch on the one path the ticket named). And the discipline never cuts safety: input validation, error handling that prevents data loss, security, and accessibility survive every level.
Comments get their own discipline: terseness governs the response,
never the code's why-comments — the persona comments the constraint or
tradeoff the code can't show, renames before it annotates, deletes
comments that restate the next line, and gives every exported function a
one-line contract doc. Deliberate corner-cuts use a pinned, greppable
grammar — deadeye: <shortcut>. ceiling: <limit>. upgrade: <trigger>. —
so /deadeye-debt parses the ledger reliably, and TODO stays reserved
for work not done yet.
When the persona does deliberately cut a corner with a known ceiling, it
leaves a deadeye: comment naming the ceiling and the upgrade trigger —
/deadeye-debt collects those into a ledger so shortcuts get tracked
instead of forgotten, /deadeye-review checks the current diff for
over-engineering, and /deadeye-sweep audits the whole repo for what's
still cuttable. An optional statusline badge shows each session's live
level; deadeye will offer (once) to set it up, and never edits your
settings itself.
Already running another lean-coding persona plugin? Uninstall it before enabling coder mode — two overlapping personas means paying for both rulesets every session.
Claude Code ships its own /code-review (with a paid multi-agent
"ultra" tier), /simplify, /security-review, plan mode, and size-based
output truncation. deadeye doesn't compete with those — it covers what
they don't:
| Claude Code built-in | What deadeye adds |
|---|---|
/code-review / /simplify — correctness & cleanup reviews, on demand | /deadeye-review is the lean lens only: verified findings, net: -N lines accounting, and cuts that flow into the deadeye: debt ledger. Run it as the instant local pass; escalate to /code-review ultra for depth before a merge |
| Plan mode — exists, but nothing triggers it | deadeye's plan gate notices a risky multi-file edit coming and nudges into plan mode |
| Bash output truncation — size-based, at 30,000 chars | deadeye rewrites commands before they run so only failure context enters at all — content-based, and it stacks under the native cap |
| Subagent models — inherit the parent's model | deadeye recommends the cheapest tier the evidence supports, explains why, and learns from your escalations |
| Coding persona — none | Coder mode: the lean-first discipline, injected every session, surviving compaction, traveling into subagents |
| What | Modes | What it does |
|---|---|---|
| Context hygiene | off / on | Trims verbose command output before it enters context — test suites (Go, JS, Python, Rust, Java, Gradle, .NET, Ruby, PHP), builds, linters, package installs, pod logs, log tails. Flags unbounded dumps before they run: unscoped git diff/git log, terraform plan, kubectl get -o yaml, npm ls, bare find/tree/du, full package lists, and content-mode Grep with no limit. Also flags wasteful reads: re-reading a file that hasn't changed, whole-reads of huge files, and running the identical command twice in a row |
| Coder persona | off / spotter / marksman / sniper | The lean-first coding discipline above, injected per session and into subagents |
| Effort level | off / advise | Suggests using lower effort for mechanical steps; has no effect if CLAUDE_EFFORT is already pinned for the session |
| Model choice | off / advise / enforce | Picks the model for a subagent — only when you didn't already choose one yourself |
| Plan-first gate | off / soft / hard | Suggests (or requires) a short plan before a risky multi-file edit |
| Workflow suggestion | off / on | Flags tasks that look like they'd benefit from running many things in parallel — only ever suggests it, never starts one on its own |
Each of these works independently — you can turn any one off without
affecting the others. Settings live in ~/.deadeye/config.json, with an
optional project-level .deadeye.json that overrides it for one repo.
Four env vars act as kill switches: DEADEYE=off turns everything off;
DEADEYE_PREPROCESS=off, DEADEYE_GATE=off, and DEADEYE_CODER=off
turn off just the context hygiene, just the plan gate, or just the coder
persona, respectively.
make check # vet, gofmt, tests -- everything CI runs
make build # ./bin/deadeye
scripts/gen-catalog.go regenerates the compiled-in model/pricing table
after editing its seed prices — there's no reachable pricing API to fetch
from at runtime, so this is a release-time step, not a background refresh.
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.
Why not just ask an LLM which model to use? Four cheap, predictable signals — how many files are touched, recent git activity, whether tests exist nearby, and how the request is phrased — are enough to make a reasonable call, and they're free to check (no extra API call needed). Asking an LLM to decide would spend tokens just to figure out how to save tokens, and would add a network dependency this tool is specifically built to avoid.
Will it make Claude dumber?
That's exactly the failure mode it's built to avoid. When deadeye isn't
confident about a task, it defaults to the more capable option — picking
something cheaper always requires real evidence first. If you ever find a
case where it under-powered a task, that's a bug — report it along with
the /deadeye-route output.
What doesn't it know how to do (yet)? It can't tell whether an edit actually broke something later — it only knows when you manually pick a bigger model than it suggested, not whether a test started failing afterward. It doesn't know which other repos depend on the one you're editing — that's a different tool's job, greybeard. And it can't tell whether you approved or declined a plan-gate prompt, because Claude Code doesn't report that back to plugins — so it just asks once per task and doesn't ask again either way.
Why "deadeye"? Because efficiency isn't spending less — it's not missing.
MIT — third-party notices in THIRD-PARTY.md.
.claude-plugin/
marketplace.json
plugin.json
.github/
workflows/
ci.yml
pages.yml
release.yml
.gitignore
.goreleaser.yaml
assets/
logo-dark.svg
logo.svg
CHANGELOG.md
cmd/
deadeye/
advice_test.go
audit.go
capture.go
coder_test.go
coder.go
color.go
daemon_test.go
daemon.go
decide.go
gain_test.go
gain.go
hook_test.go
hook.go
initcodex_test.go
initcodex.go
lessons_test.go
lessons.go
main.go
mute.go
plangate_test.go
plangate.go
route.go
state.go
status.go
stop_test.go
sysproc_unix.go
sysproc_windows.go
uninstall.go
update_test.go
update.go
workflow_test.go
workflow.go
commands/
deadeye-audit.md
deadeye-mute.md
deadeye-route.md
deadeye-status.md
docs/
site/
apple-touch-icon.png
favicon.svg
index.html
logo-dark.svg
logo.svg
og.png
go.mod
hooks/
bootstrap.sh
deadeye-codex-hook.sh
deadeye-hook.ps1
deadeye-hook.sh
deadeye-statusline.sh
hooks.json
internal/
catalog/
catalog_gen.go
catalog_test.go
catalog.go
coder/
coder_test.go
coder.go
ruleset.md
size_test.go
config/
config_test.go
config.go
hookio/
types_test.go
types.go
inject/
inject_test.go
inject.go
kernel/
integration_test.go
kernel_test.go
kernel.go
lessons/
lessons_test.go
lessons.go
logstore/
logstore_test.go
logstore.go
meta/
meta_test.go
meta.go
testdata/
versionprobe/
main.go
preprocess/
rules_test.go
rules.go
testdata/
go_build_fail.txt
go_test_buildfail.txt
go_test_fail.txt
go_test_pass.txt
jest_fail.txt
mocha_fail.txt
pytest_fail.txt
proto/
proto.go
sessionmem/
sessionmem_test.go
sessionmem.go
signals/
providers_test.go
providers.go
signals.go
LICENSE
Makefile
README.md
schema/
config.schema.json
scripts/
gen-catalog.go
skills/
deadeye-coder/
SKILL.md
deadeye-debt/
SKILL.md
deadeye-gain/
SKILL.md
deadeye-help/
SKILL.md
deadeye-review/
SKILL.md
deadeye-sweep/
SKILL.md
explore/
SKILL.md
testdata/
payloads/
codex/
posttooluse.json
pretooluse_apply_patch.json
pretooluse.json
sessionstart.json
stop.json
userpromptsubmit.json
posttooluse_bash.json
pretooluse_agent.json
pretooluse_bash.json
sessionend.json
sessionstart.json
stop.json
subagentstart.json
userpromptsubmit.json
THIRD-PARTY.md© 2026 Flowy · Free and open source
Built for Claude Code · Not affiliated with Anthropic