A hook stands in front of Claude's Read tool. Small files pass straight through. Big files get diverted to a cheaper model that answers the question, so your context window never swallows a 2,000-line file.
Read hits five quick checksThe hook runs before the tool. It reads the call's JSON, applies these checks in order, and either steps aside or denies with a message pointing Claude at ask-deepseek. The order is the logic, so the cheap exits come first.
No path, or the file does not exist. Nothing to gate.
allowAn offset, pages, or limit ≤ 200 means Claude already asked for a portion.
Images, archives, media, databases. Let the real tool handle them.
allowhead -n 201 checks the size without slurping the whole file.
More than 200 lines and no slice. Deny, and hand Claude the ask-deepseek command.
When a file is over the line, the hook answers the tool call with a deny and a reason. Claude reads the reason, runs the suggested ask-deepseek command itself, and keeps going with a short answer instead of the whole file.
› Read src/server/router.ts # 1,840 lines hook · deepseek-read-hook ─────────────── permissionDecision: deny reason: File has 1,840 lines (cutoff 200). Ask Composer instead: ask-deepseek "where are routes defined?" \ src/server/router.ts › ask-deepseek "where are routes defined?" src/server/router.ts composer · grok-composer-2.5-fast ✓ → 7 routes in registerRoutes(): GET /health, POST /login, GET /users/:id, ... (~0.7k tokens)
ask-deepseek is a symlink to a composer script. It bundles the file contents with your question, sends them to a fast Composer model through a local gateway, and falls back to DeepSeek's API if that call fails.
grok-composer-2.5-fast via CLIProxy on :8317.
A long file read inline is pure ballast: it fills the window, pushes earlier work out, and costs premium tokens on every following turn. A focused answer is a few hundred tokens that actually move the task forward.
ask-deepseek
Shell command (symlinked to composer) that answers questions about one or more files and prints the result to stdout.
deepseek-read-hook.sh
The PreToolUse hook. Parses the Read call with jq, runs the five checks, and returns allow or deny.
~/.claude/settings.json
Registers the hook against the Read matcher. One block connects the gate to every read Claude makes.