jev-usher
September 20, 2026 · View on GitHub
The doorman for your context window.
jev-usher routes clear tasks to a suitable Claude model and filters noisy tool output, with originals kept for recovery. TypeSafe's JEV judges relevance; deterministic rules decide what to send.
Use it through Claude Code, the local comparison UI, or the TypeScript library. See measured results and tradeoffs for token use, latency, and test methodology.
original tool output → JEV judgments → deterministic policy → selected context
│ │
└──────── original kept for recovery ┘
Status: preview. The launcher enables routing and recoverable filtering; direct plugin and settings installations require filtering to be enabled separately. Filtering supports specific output formats and can omit useful information. Inspect decisions and compare answers in the UI before using it in ongoing work. Token reduction alone does not prove lower cost or unchanged quality.
Quickstart: local test UI
Requirements: Node.js 20 or newer, a TypeSafe API key, and Claude Code 2.1.278 or newer signed in to your subscription for paired tests. Use a current Node 22 or 24 release to develop. Offline tests need no API key.
git clone https://github.com/cvsgireesh/jev-usher.git
cd jev-usher
npm ci
npm run check
export JEV_API_KEY='your-typesafe-key'
node bin/jev-usher.mjs ui
Open http://127.0.0.1:4318. Choose a task and a baseline Claude model, then click
Run comparison. Read Without jev-usher and With jev-usher side by side,
with token counts, elapsed time, and estimated JEV cost below. The baseline
defaults to Sonnet; jev-usher uses automatic model routing and context filtering.
Connection setup and technical details stay collapsed until you need them.
The UI starts no model calls until you run a comparison. JEV calls spend TypeSafe credits; the two Claude runs consume your subscription allowance.
The UI runs on your computer. JEV judgments still use TypeSafe's hosted API, and Claude requests use Anthropic's service. Read the local UI guide and data handling for the exact boundary.
Claude Code setup
Start a new Claude session with automatic model routing and recoverable filtering:
node /absolute/path/to/jev-usher/bin/jev-usher.mjs claude "Find the cause of the retry failure"
JEV judges the launch prompt and selects Haiku, Sonnet, or Opus when confident.
Uncertain or unavailable routing keeps Claude's configured model. Explicit
--model arguments and ANTHROPIC_MODEL take precedence;
--no-route keeps Claude's configured model. Resumed conversations keep their
model selection. Routing applies at session start and does not change models
between turns. Pass Claude options after --:
node /absolute/path/to/jev-usher/bin/jev-usher.mjs claude "Continue the investigation" -- --continue
Set JEVUSHER_FILTER=0 to keep launcher routing while disabling output filtering.
To use Claude directly, load the checkout as a plugin:
claude --plugin-dir /absolute/path/to/jev-usher
Or install settings hooks in the project where you want them:
node /absolute/path/to/jev-usher/bin/jev-usher.mjs install
node /absolute/path/to/jev-usher/bin/jev-usher.mjs doctor
Choose one method to avoid duplicate hooks. Settings hooks use the installed local
executable; keep the checkout at that path. Run the same command with uninstall
to remove them. Installation alone does not enable output filtering or screening.
See Claude Code configuration for supported tools, explicit
memory inputs, filtering, and recovery.
TypeScript example
After building, install the checkout into your application with
npm install /absolute/path/to/jev-usher:
import { JevUsher } from "jev-usher";
const usher = new JevUsher();
const result = await usher.usher.admit({
goal: "Find the widget service retry limit",
candidates: [
{ id: "config", text: "Widget retries failed requests at most three times." },
{ id: "picnic", text: "The office picnic is on Sunday." },
],
budget: 2000,
});
// Pass the selected text to your model; retain the originals for recovery.
console.log(result.admitted, result.verdicts);
| Component | Library behavior | Claude Code integration |
|---|---|---|
| Filter | Screens and selects tool-output chunks | Recoverable Read, diagnostic Bash, Grep, Glob, and allowlisted MCP output filtering |
| Usher | Selects supplied memory within a budget | Injects from an explicitly configured JSONL store |
| Gate | Shortlists capabilities, then selects | Adds a hint; does not remove Claude's skill catalog |
| Router | Selects a configured model tier | Launcher selects the session model; prompt-hook hints remain advisory |
| Compactor | Keeps, shortens, or drops text blocks | Library only; does not replace native compaction |
| Screen | Flags possible injected instructions | Opt-in warning; not a permission system |
| StopGate | Recommends ending or continuing a loop | Optional completion check; not installed by default |
See the API reference for thresholds, budgets, and result types.
The plugin does not discover private memories or override CLAUDE.md or configured
permissions. After a filtered source read, it requires recovery of the original
before a native Edit or Write. All admitted memory and capability records are explicit inputs.
Limits and failure behavior
JEV returns typed Choice, Score, and Noul judgments, not generated summaries.
The client pins jev-1.13.0. JEV can misclassify adversarial text, and irrelevant
context can reduce accuracy. Confidence is not proof that a decision is correct.
TypeSafe model limits ·
Known limitations
- Hook failures leave the original tool result available. Unsupported formats pass through. Recovery must succeed before any result is replaced.
- Library memory admission keeps uncertain material within its hard budget; even an outage fallback can exclude useful material when the budget is small.
- Library compaction preserves uncertain blocks verbatim, even over
keepBudget. Confident reductions are lossy; the caller owns transcript integrity and recovery. - Screening returns
unavailablefor missing or invalid answers. Apassmeans nothing detected, not that text is safe to execute. - Requests and concurrency are bounded. Oversized inputs fall back instead of receiving a misleading judgment on a silently truncated sample.
Read architecture and accounting for resource bounds and which figures are estimates.
Common questions
Will this reduce my Claude subscription bill? A fixed subscription fee does not decrease when a prompt shrinks. Smaller inputs may help usage allowance, but retries, output, prompt caching, and task quality also matter. Compare completed tasks; API dollar estimates are not subscription savings.
Does everything stay local? No. The UI and hooks run locally, but text chosen for evaluation is sent to TypeSafe. Claude tests also send the provided test task inputs to Anthropic. No API key is needed for offline tests.
Does it replace Claude's memory, tool search, or prompt cache? No. It works with explicit inputs and supported tool outputs. Comparisons should preserve Claude's native features in both runs.
Can I use it without Claude Code? Yes. The TypeScript library accepts caller-owned candidates and returns decisions. Your application decides how to use the selected text.
Development and support
npm run check # offline tests, typecheck, and build
npm run test:package # install and exercise a packed artifact
# Optional paid evaluation with provided test fixtures:
npm run eval:live -- --live --out /tmp/jev-usher-evaluation.json
npm run eval:claude -- --live --out /tmp/jev-usher-claude.json
Read Contributing or agent instructions to work on the repository. Report a reproducible problem through GitHub issues. Keep credentials, private transcripts, and generated test reports out of issues and commits.
Local UI · Claude Code · Results · API reference · Privacy · Security · Documentation index for agents
Independent project; not affiliated with or endorsed by TypeSafe or Anthropic. JEV is TypeSafe's model. MIT licensed.