██████ ██████
███▒▒███ ███▒▒███
▒███ ▒███▒███ ▒███
▒███ ▒███▒███ ▒███
▒▒██████ ▒▒██████
▒▒▒▒▒▒ ▒▒▒▒▒▒
"Double-o, agent's best friend."
Or: how I learned to stop worrying and love my context-efficient command runner for AI coding agents.
AI coding agents waste context tokens on verbose command output. A single cargo build
can produce thousands of lines that the agent must process but rarely needs in full.
oo solves this transparently:
- Commands run normally — oo wraps them, not replaces them
- Output is classified and compressed using patterns
- Agents get the signal (pass/fail, errors, summaries) without the noise
- No agent modification required — just prefix commands with
oo
Unlike manual truncation (head/tail), oo understands command semantics. Unlike
agent-native output limits, oo preserves the information the agent actually needs.
AI agents see everything you print. A cargo test run producing 8 KB of output
costs the agent hundreds of tokens just to learn "tests passed." Multiply that
across a session and the context window fills with noise, not signal. oo runs
commands for you and collapses their output to what the agent actually needs.
Without oo: Your agent receives the full output.
$ cargo test
Compiling myapp v0.1.0 (/path/to/myapp)
Finished test [unoptimized + debuginfo] target(s) in 0.52s
Running unittests src/lib.rs (target/debug/deps/myapp)
running 47 tests
test auth::tests::login_success ... ok
test auth::tests::login_invalid_password ... ok
test db::tests::connection_pool ... ok
... 44 more tests ...
test result: ok. 47 passed; 0 failed; finished in 2.1s
With oo: Your agent gets the signal.
$ oo cargo test
✓ cargo test (47 passed, 2.1s)
Large output with a known success pattern collapses to a single summary line.
When things fail: Actionable errors, no noise.
$ oo pytest tests/
✗ pytest
FAILED tests/test_api.py::test_login - AssertionError: expected 200, got 401
FAILED tests/test_api.py::test_create_user - ValueError: email already exists
=== 2 failed, 45 passed in 1.8s ===
Failure output is filtered to the actionable tail.
Large unrecognised output: Indexed for retrieval.
$ oo gh issue list
● gh (indexed 47.2 KiB → use `oo recall` to query)
Query indexed output with oo recall "<terms>". Small outputs (≤4 KB) pass through
unchanged. Larger unpatterned output — whether from data commands like git log and
ls or content commands like git show and git diff — is indexed in full, and only a
byte-bounded head+tail slice is displayed with a truncation marker (... [N bytes truncated → use oo recall to query] ...), so large cat, jq, or sh -c output
cannot blow an agent's context window. See the patterns guide
for details.
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/randomm/oo/releases/latest/download/oo-installer.sh | shThe installer detects your platform, downloads the correct binary, and adds it to
~/.cargo/bin/by default. If you don't use Rust, restart your shell or runexport PATH="$HOME/.cargo/bin:$PATH"to makeooavailable. Use--prefix=/usr/localfor system-wide installs.
Download from GitHub Releases:
# macOS (Apple Silicon)
curl -LO https://github.com/randomm/oo/releases/latest/download/double-o-aarch64-apple-darwin.tar.xz
tar xf double-o-aarch64-apple-darwin.tar.xz
sudo mv double-o-aarch64-apple-darwin/oo /usr/local/bin/
# Linux (x86_64)
curl -LO https://github.com/randomm/oo/releases/latest/download/double-o-x86_64-unknown-linux-gnu.tar.xz
tar xf double-o-x86_64-unknown-linux-gnu.tar.xz
sudo mv double-o-x86_64-unknown-linux-gnu/oo /usr/local/bin/
# Linux (ARM64)
curl -LO https://github.com/randomm/oo/releases/latest/download/double-o-aarch64-unknown-linux-gnu.tar.xz
tar xf double-o-aarch64-unknown-linux-gnu.tar.xz
sudo mv double-o-aarch64-unknown-linux-gnu/oo /usr/local/bin/cargo install double-ogit clone https://github.com/randomm/oo.git
cd oo
cargo build --release
cp target/release/oo /usr/local/bin/# Wrap any command — output is classified and compressed
$ oo cargo test
✓ cargo test (47 passed, 2.1s)
# Large unrecognised output is indexed — query it later
$ oo git log --oneline -100
● git (indexed 12.4 KiB → use `oo recall` to query)
$ oo recall "merge commit"
# Teach oo a new pattern for an unrecognised command
$ oo learn rspec spec/Shell semantics: oo runs programs directly — it does not invoke a shell. Use
oo sh -c '<command>' when you need shell syntax (pipes, &&, globbing):
oo sh -c 'git log --oneline | head -20'See the savings indicator spec for how the
[saved N KiB] figure on the indicator line works.
| Command | Description |
|---|---|
oo <cmd> [args...] |
Run a shell command with context-efficient output |
oo recall <query> |
Search indexed output from this session |
oo forget |
Clear all indexed output for this session |
oo learn <cmd> [args...] |
Run command and teach oo a new output pattern via LLM |
oo help <cmd> |
Fetch a cheat sheet for cmd from cheat.sh |
oo init |
Generate .claude/hooks.json and print AGENTS.md snippet |
oo version |
Print version |
Note:
oo helpsources from cheat.sh which covers common Unix tools. For modern CLIs not yet in cheat.sh (e.g.,gh,kamal), useoo learn <cmd>to teachoothe command's output patterns.
Add this to your system prompt or CLAUDE.md:
Prefix all shell commands with `oo`. Use `oo recall "<query>"` to search large outputs.
That's it. The agent runs oo cargo test, gets ✓ cargo test (47 passed, 2.1s),
and moves on.
oo ships with 24 patterns that match commands automatically:
| Command | Success | Failure strategy |
|---|---|---|
pytest |
{passed} passed, {time}s |
tail 30 lines |
cargo test |
{passed} passed, {time}s |
tail 40 lines |
go test |
ok ({time}s) |
tail 30 lines |
jest / vitest / npx jest |
{passed} passed, {time}s |
tail 30 lines |
ruff check |
quiet (no output on pass) | smart truncate |
eslint |
quiet | smart truncate |
cargo build |
quiet | head 20 lines |
go build |
quiet | head 20 lines |
tsc |
quiet | head 20 lines |
cargo clippy |
quiet | smart truncate |
npm test |
{passed} passed, {time}s |
tail 30 lines |
yarn test |
{passed} passed, {time}s |
tail 30 lines |
pnpm test |
{passed} passed, {time}s |
tail 30 lines |
bun test |
{passed} passed, {time}s |
tail 30 lines |
cargo tarpaulin |
{cov}% coverage |
tail 20 lines |
cargo fmt |
quiet | grep for "Diff in" |
mypy |
Success: no issues found / error count |
head 20 lines |
rubocop |
{offenses} offenses |
head 30 lines |
ruff format |
{count} files reformatted |
head 20 lines |
prettier |
quiet | head 20 lines |
npm run build |
quiet | head 20 lines |
yarn build |
Done in {time}s |
head 20 lines |
pnpm build |
quiet | head 20 lines |
bun build |
quiet | head 20 lines |
Add your own patterns with oo learn <cmd> (generates a TOML pattern file via
LLM) or write one manually in ~/.config/oo/patterns/.
What if oo doesn't recognize my command?
Unknown commands pass through unchanged under 4 KB. Larger output is indexed in full for
later retrieval via oo recall, with only a byte-bounded head+tail slice displayed (marked
with a truncation line). Use oo learn <command> to teach oo a compression pattern.
Can I disable compression for a command?
Unknown commands already show a bounded head+tail slice with the full output stored for
oo recall (nothing is lost). For commands with built-in patterns, you can override with
a custom TOML pattern. See Custom Patterns.
Does oo work in CI? It can, but oo is designed for interactive AI agent sessions where context tokens matter. In CI, full output is usually fine.
Which LLM providers does oo learn support?
Anthropic only. Set ANTHROPIC_API_KEY in your environment.
See Learning Patterns.
oo: command not found
Ensure ~/.cargo/bin is in your PATH, or use the full path to the binary.
Pattern not matching my command
Run oo patterns to see all loaded patterns and their command regexes.
Custom patterns in ~/.config/oo/patterns/ override built-ins.
oo learn fails or produces bad patterns
Ensure ANTHROPIC_API_KEY is set. Run the command normally first so oo has
real output to analyze. See Learning Patterns.
Documentation Index — Extensive project documentation:
- Testing Guide — How to run, write, and understand tests
- Architecture — System design and module responsibilities
- Security Model — Trust assumptions and data handling
- CLI Reference — All subcommands, output tiers, and the savings indicator spec
- Configuration — Environment variables, config files, and platform paths
- Custom Patterns — Creating patterns for command output compression
- Learning Patterns — Using
oo learnto generate patterns automatically - Changelog — Release history
For contributors: See CONTRIBUTING.md for development setup and workflow. For agents: See AGENTS.md for project-specific agent conventions.
Apache-2.0 — see LICENSE.
oo help fetches content from cheat.sh, which includes
tldr-pages content (CC BY 4.0). See
NOTICE.