← Blog
explainx / blog

oh-my-pi (omp): the batteries-included terminal coding agent that gets edits right the first time

oh-my-pi (omp) is a fork of Pi that adds hash-anchored edits, LSP integration, DAP debugging, 40+ providers, 32 tools, and subagent orchestration—all in ~27k lines of Rust. Installation, architecture, and when to choose omp over Claude Code or Cursor.

12 min readYash Thakker
Terminal AgentsCoding Agentsoh-my-piDeveloper ToolsAgent HarnessLSPDebugging

MDX restores the committed source plus an HTML comment attribution; plain text bundles the rendered markdown body with the explainx.ai attribution footer.

oh-my-pi (omp): the batteries-included terminal coding agent that gets edits right the first time

oh-my-pi (omp) is the terminal coding agent that answers a blunt question: why do agents keep failing edits that should work? Built by Can Bölük as a fork of Mario Zechner's Pi, omp adds the harness engineering missing from most agent surfaces—hash-anchored edits that eliminate whitespace battles, LSP integration so renames propagate correctly, DAP-driven debugging against live binaries, 40+ model providers with per-role routing, and subagent orchestration across isolated worktrees. The repository has climbed to 5.5k+ stars in months, with a 458-fork ecosystem and 177 contributors—signals that teams want production-grade tools, not demo prompts.

This article is a field guide: what problem it solves, the core architecture, installation paths, feature comparison, and when to choose omp over Claude Code, Cursor, or a custom harness.

TL;DR

QuestionShort answer
What is it?A batteries-included terminal coding agent forked from Pi, adding hashline edits, LSP/DAP, 40+ providers, 32 tools, and subagent fan-out.
Primary sourcegithub.com/can1357/oh-my-pi (MIT).
AttributionFork of Pi by Mario Zechner; maintained by Can Bölük.
Install (macOS/Linux)curl -fsSL https://omp.sh/install | sh
Install (Bun)bun install -g @oh-my-pi/pi-coding-agent
Install (Windows)irm https://omp.sh/install.ps1 | iex
Key differentiatorHash-anchored edits (hashline format) eliminate string-not-found loops; LSP provides IDE-grade intelligence; DAP drives real debuggers.
Related ecosystemPairs with agent skills, MCP servers, and harness engineering patterns.

The official site and docs provide installation, provider configuration, and tool reference.


The problem: why agents fail at edits

The upstream README quotes a harsh truth from production usage:

  1. String replacement fails — Whitespace, line endings, or stale context make old_string not match, so the edit is rejected or corrupts the file.
  2. Renames are incomplete — The agent renames a symbol in one file but misses re-exports, barrel imports, or aliased references.
  3. No debugging story — When a binary segfaults or a service hangs, the agent sprinkles console.log or print() instead of attaching a real debugger.
  4. Search is slow — Every grep or find forks a subprocess; on large monorepos, this adds seconds per call.
  5. One provider, one bill — Most harnesses lock you into a single API; if that provider hits quota or throws 429s, the session dies.

oh-my-pi addresses all five with harness engineering: structural changes that make the failure mode impossible, not one-off prompt patches.


Core architecture: ~27k lines of Rust doing the work other harnesses shell out for

omp ships three Rust crates compiled into a single N-API addon:

CrateWhat it does~LoC
pi-shellEmbedded bash (brush-shell fork), persistent sessions, timeout/abort, custom builtins3,700
pi-grepRegex search, parallel/sequential, glob & type filters, fuzzy find1,900
pi-asttree-sitter structural summaries and ast-grep pattern matching/rewrites1,040

Plus keys (Kitty keyboard protocol), text (ANSI-aware width/truncation), highlight (syntect), pty (portable-pty), glob (ignore + globset), image (decode/encode/resize), tokens (tiktoken BPE), html (HTML→Markdown), and more—all in-process on the libuv thread pool. No fork/exec on the hot path.

Platform targets: linux-x64, linux-arm64, darwin-x64, darwin-arm64, win32-x64. The same omp binary runs on macOS, Linux, and Windows—no WSL bridge.


Feature 01: Hash-anchored edits (hashline format)

Problem: str_replace diffs fail when whitespace, line endings, or model hallucination makes old_string not match.

Solution: The model references content hashes as anchors instead of retyping lines. If anchors diverge (the file changed since the agent read it), the patch is rejected before it corrupts anything.

Impact: Grok 4 Fast spends 61% fewer output tokens on the same work. Gemini 3 Flash gains +5 pp over str_replace. MiniMax doubles its pass rate—same weights, same prompt, different edit format.

Example:

✓ AST Edit: console.log($X) (proposed) 3 replacements · 1 file
✓ Accept: 3 replacements in 1 file (AST Edit)
Applied 3 replacements in src/auth.ts.

The replacement count previews before apply; the change is staged, then accepted with a reason.


Feature 02: LSP integration—everything your IDE knows, the agent knows

Problem: The agent renames a symbol in one file but misses re-exports, barrel files, or aliased imports.

Solution: The lsp tool exposes diagnostics, navigation (go-to-definition, references), symbols, renames, code actions, and raw LSP requests. When the agent renames, it goes through workspace/willRenameFiles, so downstream updates happen correctly.

Example workflow:

✓ LSP references: formatBytes → 5 hits across 3 files
✓ LSP rename: formatBytes → formatFileSize
  - format.ts: 2 edits
  - report.ts: 2 edits
  - cli.ts: 1 edit
✓ Search formatBytes → 0 matches
Rename complete.

Supported operations:

  • Diagnostics (errors, warnings, hints)
  • Navigation (definition, references, implementations, type-definition)
  • Symbols (document, workspace)
  • Renames (with willRenameFiles propagation)
  • Code actions (quick fixes, refactors)
  • Raw requests (custom LSP methods)

Feature 03: Drives a real debugger (DAP)

Problem: When a binary segfaults, a Go service hangs, or a Python process wedges, the agent sprinkles print() instead of inspecting state.

Solution: The debug tool speaks DAP (Debug Adapter Protocol). It attaches lldb (native), dlv (Go), debugpy (Python), and other DAP-compatible adapters—breakpoints, stepping, threads, stack inspection, variable evaluation.

Example session (lldb-dap):

✓ Debug attach: /tmp/omp-native/demo
  Adapter: lldb-dap
  Status: stopped
  Frame: xorshift32
  Instruction pointer: 0x10000055C
  Location: demo.c:6:10

✓ Debug scopes: locals
  x = 57351

✓ Debug evaluate: 7 ^ (7 << 13)
  = 57351

Agent: "x went from 7 → 57351 (= 7 ^ (7<<13)), confirming the xorshift step."

Supported operations:

  • Launch or attach
  • Breakpoints (line, conditional, logpoints)
  • Stepping (step, next, step-in, step-out, continue)
  • Threads and stack frames
  • Scopes and variables
  • Evaluate expressions
  • Pause, restart, disconnect

Feature 04: 40+ providers, one interface

Problem: Most harnesses lock you into one API. If that provider hits quota, throws 429s, or has a model outage, the session dies.

Solution: omp routes by role (default, smol, slow, plan, commit). Each role can have a fallback chain; when the primary throws 429s, the next entry takes the rest of the turn—restored on cooldown. Round-robin credentials per provider rotate with session affinity and per-credential backoff.

Provider categories:

CategoryExamples
Frontier APIsAnthropic (oauth), OpenAI, Google Gemini (oauth), xAI, Mistral, Groq, Cerebras, Fireworks, Together, Hugging Face, NVIDIA, OpenRouter, Perplexity (oauth)
Coding plansCursor (oauth), GitHub Copilot (oauth), Codex (oauth), Kimi Code, Moonshot, MiniMax Coding Plan, Alibaba Coding Plan, Qwen Portal, Z.AI/GLM
Self-hostedOllama (local), LM Studio (local), llama.cpp (local), vLLM (local), LiteLLM

Custom providers: Declare anything that speaks openai-completions, anthropic-messages, google-generative-ai, or google-vertex in ~/.omp/agent/models.yml.

Role-based routing example:

modelRoles:
  default: anthropic/sonnet-4.5
  smol: groq/llama-3.3-70b-versatile
  slow: openai/o1
  plan: anthropic/opus-4.5
  commit: anthropic/haiku-4

Feature 05: 32 tools, one namespace

omp ships 32 tools in the same namespace as read and bash. The active set is controlled by --tools read,edit,bash,...; the rest stay hidden but indexed—search_tool_bm25 pulls them back mid-session when tools.discoveryMode allows.

Tool categories:

CategoryTools
Files & searchread, write, edit, ast_edit, ast_grep, search, find
Runtimebash, eval (Python + JavaScript), recipe (task runners), ssh
Code intelligencelsp (LSP operations), debug (DAP sessions)
Coordinationtask (subagent fan-out), irc (inter-agent prose), todo_write, job (background job control), ask (structured questions)
Outside the boxbrowser (Puppeteer), web_search (14 providers), github (gh CLI), generate_image, inspect_image, render_mermaid
Memory & statecheckpoint, rewind, retain (Hindsight), recall, reflect
Misccalc, resolve (preview apply/discard), search_tool_bm25

read handles 10+ internal schemes:

  • pr://, issue:// — GitHub PRs and issues
  • agent://<id>/findings.0.path — pull fields from subagent output
  • conflict://N — each merge conflict becomes a URL; write @theirs, @ours, or @base
  • skill://, rule:// — walk skills and rules transparently

Example (conflict resolution):

✓ Read src/session.ts (⚠ 1 conflict)
✓ Write conflict://1 · 1 line
  Content: @theirs
Resolved.

Feature 06: Subagent orchestration (task tool)

Problem: Fan-out work across isolated contexts without merge conflicts or orphaned edits.

Solution: The task tool spawns subagents in parallel, each running in an isolated workspace:

  • APFS clones (macOS)
  • btrfs reflinks (Linux)
  • zfs clones (Linux/BSD)
  • overlayfs (Linux)
  • projfs (Windows)
  • rcopy (fallback)

Each worker runs its own tool surface and yields a schema-validated object the parent reads directly—no prose to parse.

Example:

✓ Task: ComponentsExports (in-progress)
✓ Task: RoutesExports (in-progress)

Constraints:
- IRC DM between peers required

Results:
  ComponentsExports → { exports: [...], duration: 12.3s, cost: $0.04 }
  RoutesExports → { exports: [...], duration: 11.8s, cost: $0.03 }

Findings:
- 47 component exports
- 23 route exports
- IRC coordination note: one-sided handshake (ComponentsExports sent, RoutesExports did not reply)

Feature 07: web_search with 14 providers and site-aware extraction

Problem: Generic web fetch returns stripped HTML; the agent loses link structure and can't cite or follow anchors.

Solution: web_search chains 14 providers (auto mode walks the chain; pin one by name). Site-aware extraction turns GitHub, arXiv, Stack Overflow, npm, PyPI, crates.io, docs.rs, and more into structured markdown with anchors and link targets intact.

Providers: auto (chain), exa, brave, jina, kimi, zai, anthropic (oauth), perplexity, gemini (oauth), codex (oauth), tavily, parallel, kagi, synthetic, searxng (self-hosted).

Example:

✓ web_search: "inference-time compute scaling"
  Provider: perplexity
  10 ranked sources

✓ read https://arxiv.org/pdf/2604.10739v1
  Extracted: structured markdown with sections, equations, citations

Agent: "The paper reports a 3.2× improvement on MATH with 64 test-time samples vs greedy decoding (Table 2, page 5)."

Feature 08: Time-traveling stream rules

Problem: The model goes off-script; you want to inject a correction mid-stream without paying context tax on every turn.

Solution: Stream rules sit dormant until a regex match aborts the stream mid-token, injects the rule as a system reminder, and retries from the same point. Injections survive compaction, so the fix sticks.

Example:

✓ Reading src.rs
Agent: "Let me use Box::leak to..."
⚠ Request aborted
⚠ Injecting rule: box-leak
  "Don't reach for Box::leak in production code paths."
Agent: "On second thought, Arc<str> is safer here. Should I proceed?"

Feature 09: Hindsight—memory the agent curates

Problem: The agent forgets codebase facts between sessions.

Solution: Hindsight lets the agent write facts mid-run with retain, pull them back with recall, and compress each session into a mental model that loads on the first turn of the next one. Project-scoped by default.

Tools:

  • retain — queue durable facts into the active Hindsight bank
  • recall — search the bank for raw memories
  • reflect — ask Hindsight to synthesize an answer over the bank

Feature 10: Four entry points—interactive, one-shot, RPC, ACP

Same engine, four wrappers:

ModeWhen to use
Interactive (TUI)Default. Tool calls render as cards, edits preview before apply, ambiguity routes through the ask tool.
One-shot (omp -p)Single prompt, exit. Useful in CI or scripts.
Node SDKEmbed the session in a Node/TypeScript process. @oh-my-pi/pi-coding-agent exposes ModelRegistry, SessionManager, createAgentSession.
RPC (omp --mode rpc)NDJSON commands over stdio. For non-Node embedders or process isolation.
ACP (omp acp)Agent Client Protocol (JSON-RPC). When the editor advertises capabilities, tool I/O routes through it and writes are gated by session/request_permission.

SDK example:

import { ModelRegistry, SessionManager, createAgentSession, discoverAuthStorage } from "@oh-my-pi/pi-coding-agent";

const auth = await discoverAuthStorage();
const models = new ModelRegistry(auth);
await models.refresh();

const { session } = await createAgentSession({
    sessionManager: SessionManager.inMemory(),
    authStorage: auth,
    modelRegistry: models,
});
await session.prompt("list .ts files");

Installation

PlatformCommand
macOS / Linuxcurl -fsSL https://omp.sh/install | sh
Bun (recommended)bun install -g @oh-my-pi/pi-coding-agent
Windows (PowerShell)irm https://omp.sh/install.ps1 | iex
mise (pinned versions)mise use -g github:can1357/oh-my-pi

Requirements: Bun ≥ 1.3.14.

Configuration: ~/.omp/agent/models.yml for provider routing, ~/.omp/agent/settings.yml for tool defaults, rules, and extensions.


When to choose omp over Claude Code / Cursor / Codex

Factoroh-my-pi (omp)Claude Code / Cursor / Codex
Edit accuracyHash-anchored (hashline) format eliminates string-not-found loopsString replacement or unified diff (subject to whitespace battles)
Code intelligenceLSP integration (diagnostics, references, renames with propagation)IDE-provided intelligence (not directly accessible to agent in most cases)
DebuggingDAP-driven (lldb, dlv, debugpy)No debugger integration
Provider flexibility40+ providers with per-role routing, fallback chains, round-robin credentialsLocked to vendor (Claude, OpenAI, GitHub, etc.) or limited multi-provider support
Subagent orchestrationtask tool with isolated worktrees (APFS/btrfs/overlayfs)No native subagent fan-out
Terminal-firstTUI, one-shot, RPC, ACPIDE-integrated (VS Code, JetBrains, web)
Web search14 providers with site-aware extractionLimited or no web search
ExtensibilityTypeScript extensions, MCP servers, skills, hooksPlugin marketplaces (Cursor), limited extension model
Use caseTerminal workflows, CI, custom harness, multi-provider, subagent fan-outInteractive IDE workflows, fast prototyping, single-provider simplicity

Bottom line: Use Claude Code/Cursor for interactive IDE workflows with strong UX. Use omp when you need terminal workflows, edit accuracy, LSP/DAP integration, custom provider routing, or subagent orchestration.


Monorepo structure

omp is a TypeScript + Rust monorepo. Key packages:

PackageDescription
@oh-my-pi/pi-aiMulti-provider LLM client with streaming and model/provider integration
@oh-my-pi/pi-agent-coreAgent runtime with tool calling and state management
@oh-my-pi/pi-coding-agentInteractive coding agent CLI and SDK
@oh-my-pi/pi-tuiTerminal UI library with differential rendering
@oh-my-pi/pi-nativesN-API bindings for grep, shell, image, text, syntax highlighting
@oh-my-pi/pi-utilsShared utilities (logging, streams, dirs/env/process helpers)
@oh-my-pi/omp-statsLocal observability dashboard for AI usage statistics

Rust crates:

  • pi-natives — aggregates shell, AST, grep, etc.
  • pi-shell — embedded bash (brush-shell fork) + PTY
  • pi-ast — tree-sitter + ast-grep
  • pi-iso — workspace isolation (APFS/btrfs/zfs/overlayfs/projfs)

Full source: github.com/can1357/oh-my-pi


Extensibility: config, hooks, extensions

omp inherits config from eight formats on disk:

  • Cursor .cursorrules
  • Cline .clinerules
  • Codex AGENTS.md
  • GitHub Copilot applyTo
  • Claude Code CLAUDE.md
  • And more

No migration script. The config your team wrote last quarter works tonight.

Extensions: TypeScript modules loaded from ~/.omp/extensions or project-local .omp/extensions. Same tool API, same slash-command registry, same hotkey table the built-ins use.

Example: Ask omp to write the piece you're missing, then /reload-plugins.


Benchmarks and evidence

ModelMetricWhat changed
Grok Code Fast 16.7% → 68.3%Tenfold lift when hashline format stops eating the model alive
Gemini 3 Flash+5 ppOver str_replace—beats Google's own best attempt at the format
Grok 4 Fast−61% tokensOutput collapses once the retry loop on bad diffs disappears
MiniMax2.1× pass ratePass rate more than doubles—same weights, same prompt

read tool: summarized snippets, ideal defaults, selector hit rate search tool: fastest in the west (in-process ripgrep) lsp tool: everything your IDE knows, the agent knows prompts: adjusted relentlessly for each model

Full post: omp.sh blog


Related on ExplainX


Sources


Repository stats, model support, and CLI features change frequently. Treat this as May 21, 2026 context—verify installation commands and provider lists before production deployment. oh-my-pi is MIT-licensed; contributions welcome.

Related posts