Stop paying to re-read
the same output.
OMNI is a shell hook for your coding agent. It drops the noise from command output before the model reads it, and returns what the model has already been shown as a handle rather than the bytes again: 10.7% off build and test output, 69.6% across all 9,478 replayed commands.
brew install fajarhide/tap/omni Then omni init. Also on and
v0.7.9 Stable
Reproducible on tests/fixtures/: 16,515 B of test output becomes 1,153 B, a 93.0% cut.
Where it fails, then what it promises
A tool that asks to sit between you and your output should lead with the parts that go badly.
- 1 in 26commands is touched at all
- and the other 96.1% are handed back with zero bytes added, because taking anything would be unsafe or would not pay for its own marker. That is why it is safe to leave on for everything: not one call in 9,478 came out larger. On the ones it does touch, file reads give up 1.5%.
- 21 to 61 msper hooked command
- and the cost grows with your history rather than with the payload. A 496 byte
git statustakes about 21ms against a fresh database and about 61ms against a 205 MB one. A 16.5 KBcargo testtakes 24ms and 65ms. Budget for it. - exit != 0never compressed
- Failing commands pass through whole, structured output is never touched, and a distiller that cannot parse its input stays quiet instead of guessing.
- Reversible
- Everything cut is archived to local SQLite keyed by SHA-256, for inputs up to 64 KB. The marker carries the handle and
omni retrieveprints the original on any host. Above the cap nothing is archived and the marker says so, with the size. The archive is a rolling 30 day window, so a handle older than that will not resolve. issue 271 - Never invents
- A distiller that parsed no signal hands back the raw output. It will not write a green "no errors" line that nothing supports. issue 143
- Never hides
- Any command that exits non-zero passes through untouched. A buried error costs more than an uncompressed one. issue 120
- Never mangles
- JSON, YAML, NDJSON and CSV go through byte for byte, because a corrupted payload costs more than a missed compression. pipeline::format
Any tool claiming to save 90% of every command is telling you it summarised output you needed.
The second read is free
A filter removes a line because a pattern calls it noise. The ledger removes it because your agent is already holding it. Filters are what every tool in this category ships. The ledger is the part that is not.
- 214 Bthe second read
- A file your agent reads twice costs full price, then this. The repeat comes back as one marker carrying a handle, because those bytes are already in its context, and
omni retrievehands the file back in full if it is ever needed. - 68.4%of raw bytes
- were lines the agent had already been shown, and 64.7% still are after every distiller has run. Filtering barely dents repetition, because repetition is not noise. It is signal that was already delivered.
- 1.5%off file reads
- the largest class in the corpus at 1,056 calls and 1.89 MB. The filters take 0.0% of it and the ledger takes 1.5%, because a second read is bytes the agent is already holding rather than lines anyone had to guess at.
- Across sessions
- The store is one SQLite file keyed by project path rather than by agent, so a second agent in the same directory gets a handle for output an earlier session produced. That marker reads
from an earlier sessionand notalready shown, because this agent has genuinely never seen those bytes. - A compaction ends it
- The licence to replace forty lines with a handle is that the agent is still holding those lines. When the context window compacts, that stops being true, so OMNI deliberately forgets what it had shown. It cannot stop a compaction, only push it further out.
One marker carries all of it: [OMNI: 40 lines already shown, omni retrieve bc7e821a4340073e]. The count, what happened to those lines, and the handle that undoes it.
Head to head on the same 9,478 traces, identical bytes into every arm, OMNI with its ledger is the top row at 69.6%. The closest arm is headroom's dedup at 65.8%, then lean-ctx at 49.4%; rtk's filters take 6.2% and reach 61.4% once our ledger is bolted on, which is the clearest statement of where the work happens. Our filters alone take 32.6%, and lean-ctx beats that sub-component on a corpus built for exactly that shape. Every row is published, that one included. benchmarks
Your agent also forgets everything overnight
- New session
- You re-explain the project layout, which module is broken, and that it is Postgres rather than MySQL. The agent already has it. You carry on from where you stopped.
- Bug you already fixed
- The agent walks into the same framework quirk it solved yesterday, because nothing kept the answer. The agent pulls the stored fix back through omni_recall before it repeats the mistake.
- Cursor to Claude Code
- New editor, new agent, no context. You start over. The session summary is injected on the way in. The new agent is current.
- Agent drifts off task
- Three prompts later it is refactoring something you never asked about. omni goal restates the objective on every prompt.
What each host lets OMNI do
Only a host that can rewrite its own tool output gets shell distillation. The rest get memory, and no claim of more. omni doctor prints the tier for every host you have installed.
- Full
- Claude Code, Codex CLI, Gemini CLI, Aider (pipe) The host applies OMNI's rewrite, so the model reads distilled output from its own built-in tools.
- Handoff-first
- Cursor, Windsurf The host cannot rewrite built-in tool output.
omni_rundistils anything you route through it, andomni init --cursorinstalls the rule that makes the agent reach for it. - MCP-only
- Cline, Roo, OpenCode, VS Code, Zed, Copilot, Antigravity, Hermes, Pi Memory, recall and session state. No shell distillation, and no claim of it.
9,478 real commands, replayed on the release binary
One developer's actual usage, not a fixture set chosen to flatter the result. 23.09 MB in, 7.03 MB out.
Read the corpus before the number. This window is unusual and it inflates everything below: 286 groups of byte-identical payloads account for 80.6% of these bytes, and 148 of the 9,478 calls carry 64.7% of them. It was a week of building and benchmarking OMNI itself. The same harness over a week of ordinary work reads 14.9%.
| Class | Calls | In | Filters | With ledger |
|---|---|---|---|---|
other | 6,457 | 4.81 MB | 0.8% | |
file read | 1,056 | 1.89 MB | 0.0% | |
git | 899 | 0.86 MB | 5.1% | |
search | 810 | 0.77 MB | 3.4% | |
infra | 215 | 0.14 MB | 3.2% | |
build and test | 41 | 0.02 MB | 9.0% |
build and test over 41 calls file read over 1,056 calls build and test carries the result and file read is close to a no-op. The weak row stays in the table, because quietly dropping the rows that look bad is how 69.6% turns into a fake 90%. Most tools in this category publish one big percentage; we publish the weak rows beside the strong ones so you can find your own workload in the table. Run omni stats for your own.
What people ask before installing it
- Does OMNI delete my logs?
- No. What it cuts is archived to a local SQLite store keyed by SHA-256, and the marker carries the handle that pulls the original back. Inputs over 64 KB are not archived, and the marker on those says so with the size. Nothing leaves your machine.
- Will it slow down my terminal?
- Yes, measurably. OMNI runs on every hooked command and the cost grows with your history. A 496 byte git status takes about 21ms against a fresh database and about 61ms against a 205 MB one. A 16.5 KB cargo test takes about 24ms and 65ms.
- How much does it actually save?
- On the output that actually carries noise, build and test is 10.7%. On file reads it is 1.5%, most of which is the ledger rather than the filters. Across the whole mix it averages 69.6%, because OMNI leaves 96.1% of 9,478 replayed commands untouched rather than inventing a saving, and adds zero bytes to them. Read the per-class number for the work you actually do rather than the average, which is a mean over one mix and not a promise for yours. That average also depends on what you run: the corpus behind it is a heavy week, and an ordinary one reads 14.9%.
- Can it hide an error from my agent?
- No. Any command that exits non-zero passes through verbatim, uncompressed. Structured output such as JSON, YAML, NDJSON and CSV is never touched. A distiller that cannot parse its input returns the raw output rather than summarising it.
- Which agents does it work with?
- Fifteen hosts across three tiers, listed above under Supported agents, and what you get differs by tier. Only a host that can rewrite its own tool output gets shell distillation; the rest get memory and no claim of more. It installs as a shell hook rather than a wrapper, so nothing about how you work changes.
- Can I add filters for my own tools?
- There are no filters to add. The pattern-matching layer was retired in 0.7.4 after it measured at 2,018 bytes over 6,656 commands, 0.031% of the corpus, while costing 5 to 7ms of the hook's 10ms budget. What remains is the Rust distillers and the ledger, both compiled in, so the set that runs is the set the tests cover. If a tool needs handling, open an issue and it ships in the binary for everyone.
- How do I get back something OMNI folded?
- omni retrieve <handle>, where the handle is the 16 characters inside the marker. It works on every host, with or without MCP, and agents that have the MCP server wired can call omni_retrieve instead. The archive is a rolling 30 day window, so a handle older than that will not resolve.
- What does OMNI cost?
- Nothing. It is Apache 2.0 licensed with no paid tier, no account and no telemetry. If it saves you nothing, omni stats will tell you so and omni reset removes it.
The ten you will use, all of them local
omni help lists the rest. No account, and nothing about your machine leaves it.
- omni init
- Wire the hook into Claude Code, Cursor, Windsurf, Codex or Antigravity. Interactive.
- omni doctor --fix
- Check the hooks and the MCP wiring, then repair whatever is broken.
- omni stats
- What it actually saved on your machine. Takes
--today,--week,--month. - omni retrieve
- Print what a marker archived, by the 16 characters inside it. Works on every host, MCP or not.
- omni diff
- The last raw input beside what the agent received. This is how you check its work.
- omni dashboard
- The same numbers
omni statsreads, in a browser. Loopback only, read only. - omni session --status
- Context pressure, stored engrams, and the errors still open in this session.
- omni goal
- Set the objective once. OMNI restates it on every prompt so the agent stops drifting.
- omni remember
- Store a project rule or a gotcha in local SQLite. Recalled by semantic search later.
- omni reset
- Take it back out. Clean uninstall, keeping a backup of your config.
Seven stages, and the second one usually ends it
- Read
- A shell hook catches stdout on its way to the agent. Nothing about how you work changes.
- Guard
- Non-zero exit, or JSON, YAML, NDJSON, CSV? Straight through. This branch is taken more often than not.
- Score
- Every line gets a weight. Stack frames and errors score high, progress bars and passing tests score low.
- Distill
- A command-specific reader runs on the raw text. Returning the input is always allowed, inventing a summary is not.
- Collapse
- A fallback rather than a step, taken only when the distilled form failed to earn its keep. Runs of near-identical lines fold into a count.
- Ledger
- What survives is checked against what this session has already been shown. A run of lines the agent is still holding becomes one marker and a handle. This is where most of the saving now comes from.
- Persist
- Everything cut is hashed into local SQLite before the marker is written, so a handle never names content that was not stored. Inputs over 64 KB are the one exception, and they say so.
If OMNI panics it fails open: the raw output passes through and your agent never notices. That is the design, not a safety net bolted on afterwards.
Apache 2.0, no account, no paid tier
Built by one developer who got tired of paying to read progress bars. If it saves you nothing, omni stats will say so and omni reset removes it. That is the whole deal.