omp: the harness that orchestrates your coding agents
TL;DR
omp (Oh My Pi) is more than a coding-agent CLI: it's a harness where skills, hooks, subagents and per-model budget live in the config. Used daily, this guide shows the real setup, the gates, and the first steps to migrate without rewriting everything.
A bare coding-agent CLI is an LLM, a shell and a text editor. Three problems then recur, whatever the model’s quality: edits miss the expected format, every retry re-reads the whole context, and nothing stands between the agent and the repo. The layer that fixes these three problems is the harness. This guide documents the one I use daily, omp (Oh My Pi), and what it changes in practice.
Why a harness above a coding-agent CLI?
The clearest demonstration comes from the project’s own “the harness problem” post: on an edit format the model keeps “eating”, the same model’s success rate goes from 6.7% to 68.3% as soon as the harness fixes the format before editing. The model doesn’t change; the layer around it does.
My experience matches the mechanism: in a bare CLI, a failed rewrite costs a full context turn; in a harness where the edit is verified before being applied, the failure shows immediately and doesn’t burn a whole cycle. It’s the same argument as for gates: a rule the system enforces holds, a rule you hope gets read gets forgotten.
What is omp, concretely?
omp is a fork of Pi (Mario Zechner), TypeScript with a Rust core (~80k lines), MIT license, ~24k stars. What changes versus the competition:
- 60+ providers and per-role routing: the model is no longer a constant, it’s a config variable;
- 31 built-in tools, including LSP (14 operations), DAP (28 operations), two persistent kernels (Python + Bun) that can call back into the agent’s tools;
- hash-anchored edits: the patch is verified against the actual content before being applied;
- skills, hooks, subagents: the material of this guide.
Installation, two options:
# macOS · Linux
curl -fsSL https://omp.sh/install | sh
# or via bun
bun install -g @oh-my-pi/pi-coding-agent
How does omp load its configuration?
omp reads config from several levels, in this priority order:
~/.omp/agent/ → user config (skills, agents, hooks, config.yml)
<cwd>/.omp/ → project config, overrides the user level
.claude/ .codex/ → compatibility sources, read at lower priority
Discovery is deterministic: for each capability (skills, hooks, agents, tools), the native .omp source wins, then the compatibility sources, deduplicated by name. Profiles (omp --profile <name>) isolate full configs, handy for separating a work context from a personal one.
How do I put my rules under gate?
Hooks are event interceptors: tool_call before execution (can block), tool_result after (can rewrite), plus session events. A hook is a TypeScript module exporting a factory:
import type { HookAPI } from "@oh-my-pi/pi-coding-agent/extensibility/hooks"
export default function (pi: HookAPI): void {
pi.on("tool_call", async (event, ctx) => {
if (event.toolName !== "bash") return
const cmd = String(event.input.command ?? "")
if (!cmd.includes("rm -rf")) return
if (!ctx.hasUI) return { block: true, reason: "rm -rf blocked (no UI)" }
const ok = await ctx.ui.confirm("Dangerous command", `Allow: ${cmd}`)
if (!ok) return { block: true, reason: "user denied command" }
})
}
That’s exactly the guidelines → guardrails shift: the rule is no longer text the agent will eventually drop out of its context window, it’s a constraint the system enforces. My commit and push gates (review before commit, tests before push) live in the repo hooks, and omp runs them.
How do I organize skills?
A skill is a <name>/SKILL.md folder with a name + description frontmatter. At startup, omp injects only name and description into the system prompt; the content is read on demand via skill://<name>, or invoked interactively via /skill:<name>.
~/.omp/agent/skills/
├─ morning/SKILL.md # daily briefing
├─ review/SKILL.md # review process
└─ veille-postcursors/SKILL.md # async editorial watch
That’s the key point for cost: a skill doesn’t pay a context tax on every turn, it only costs when read. I’ve stacked dozens of process skills without inflating the permanent context, where putting everything in a single instruction file would have cost on every request.
How do I orchestrate subagents?
Agents are markdown files with frontmatter, discovered in ~/.omp/agent/agents/*.md and .omp/agents/*.md:
---
name: reviewer
description: Review a change for correctness.
model: "@review"
---
Review the assigned change and report concrete findings.
The role’s model is set in config.yml, without touching agent definitions:
modelRoles:
review: openai/gpt-5.4:high
Orchestration: the task tool fans out into isolated worktrees, each subagent has its own tool surface, and the final result is schema-validated. The hub (Alt+A) shows the live roster: status, activity, cost, tokens per agent. You can read a subagent’s transcript, send it a steering message, revive a parked agent, or kill a stuck one without aborting the parent session. Subagents can also talk to each other (IRC), enabling cross-checks without bouncing every result back through the main session.
How do I keep control of the budget?
Per-role routing is the main lever: a review role on a budget model, a deep role on a premium model. On code review, I measured the gap under controlled conditions (same code, same prompt, blind):
What it costs
Prices checked on
- deepseek-v4-flash (shallow) 4 HIGH bugs found out of 4
- $0.012/call
- glm 4 HIGH bugs found out of 4
- $0.21/review
- grok 4 HIGH bugs found out of 4
- $0.44/review
The budget model found all 4 HIGH bugs, including one the premium model missed. Review depth is a measurable choice, not a dogma: unit reviews go to the cheap model, architectural reviews to the premium one. The detailed figures of this setup (budget windows, guardrails, per-model monitoring) will get their own dispatches; here, keep the method: the budget is set in config, not in your head.
What does it change day to day?
What’s better, in no particular order:
- One place for everything: skills, hooks, agents, models live in the config, versioned like the rest.
- The hub changes delegation: you no longer spawn a subagent blind, you watch it work and steer it live.
- Multi-provider is real: the daily model (deepseek-v4-flash via opencode-go) and the reasoning model coexist in the same session.
- Integrated tooling: LSP for cross-file renames, debugger for crashes, kernels for data analysis, without leaving the terminal.
And the cons, because a guide without cons isn’t credible:
- Young layer: recent fork, docs and config formats still move (automatic migrations exist, which proves it moves).
- The name “omp” is ambiguous in search: it collides with other projects, SEO will come from content, not the name.
- The skill ecosystem is younger than Claude Code’s: you write your own, fewer ready-made packs.
- Budget models hold up thanks to the harness, but deep reasoning on complex legacy code remains premium-model work; the harness doesn’t compensate for everything.
Where to start?
No big-bang. Five steps, in order:
- Install (curl or bun, see above) and run
ompon a small project. - Point at your existing config: your
.claudefiles are read in compatibility mode, you lose nothing on day one. - Add ONE hook that blocks a dangerous command (the
rm -rfexample above is copy-paste ready). - Write ONE skill for a process you repeat every week.
- Define ONE specialized agent with its model role in
config.yml.
The harness doesn’t make the model smarter; it makes failure visible, context manageable, and rules enforced. That’s already a lot. For the rest, agentic workflow principles and multi-agent context management complete this guide.
Frequently Asked Questions
- How does omp compare to Claude Code or opencode?
- omp isn't a wrapper around one provider: it's a complete harness, a fork of Pi, that accepts 60+ providers. Claude Code remains usable as a model/provider through the config-source compatibility. Where opencode is a terminal-first CLI, omp adds the orchestration layer: skills, hooks, subagents, LSP, debugger, evaluation kernels.
- Can I reuse my existing Claude Code configuration?
- Yes. The .claude, .codex and .gemini sources are read in compatibility mode, with lower priority than native .omp config. You can migrate gradually: keep your Claude hooks and agents while porting them, with no paralysis period.
- What does it cost?
- The tool is open-source (MIT license), free. You pay for the models you choose, like with any other harness. The gain with omp is per-role routing: a budget model for unit reviews, a premium model for deep reasoning.
- Do I need a premium model for it to work?
- No, and that's the point. Hash-anchored edits and the tooling make budget models hold up far better than in a bare CLI. In my blind code review experiment, a model at $0.012 per call found all 4 HIGH bugs a premium model found.
- Is omp the same as tmux/herdr?
- No, they're different layers. herdr multiplexes sessions and agents in the terminal; omp is the agent itself, with its internal orchestration. They complement each other: you can drive omp from herdr, and omp's hub drives its own subagents.