Oh My Pi (omp) Getting Started Tutorial
Oh My Pi (command-line abbreviation omp) is an open-source AI coding agent that runs in the terminal, forked from Mario Zechner's Pi by Can Bölük and greatly expanded.
Oh My Pi's core philosophy is:Tools shouldn't just "connect"; they should be polished to perfection—Every tool is benchmark-tuned, with edit hit rate, search speed, and LSP integration all striving to be the best in class.
-
Official website:omp.sh

What is omp?
omp is aterminal-firstAI coding agent. It doesn't depend on any IDE; it runs as a full-featured TUI in your terminal, integrating LSP, DAP debugger, Python/JavaScript dual execution kernels, subagent parallelism, cross-session memory, and a set of 32 benchmark-tuned tools.
Differences from other AI coding tools
| Dimension | Claude Code / similar tools | omp |
|---|---|---|
| Edit format | str_replace (error-prone) | Hashline (content hash anchors, resistant to whitespace differences) |
| File reading | Full-text dump | Structure summary + on-demand expansion |
| LSP | None or limited | Complete 14 LSP operations (including rename, jump, code actions) |
| Debugger | None | Complete DAP: lldb, dlv, debugpy |
| Subagents | None or limited | Parallel subagents, isolated workspaces, typed return values |
| Search | Shell-invoked ripgrep | In-process ripgrep, no fork/exec |
| Behavior correction | Relies on prompt | Stream rules: regex match → mid-token injection → retry |
| Cross-session memory | None | Hindsight memory bank (project-level) |
| Code execution | Python sandbox | Persistent Python + Bun dual kernels, can call each other's Agent tools |
| Tech stack | Pure JS/Python | ~55,000 lines of Rust core + TypeScript |
Installation
This section covers the various ways to install omp on macOS, Linux, and Windows.
macOS / Linux (Recommended)
$ curl -fsSL https://omp.sh/install | sh
The install script automatically detects whether Bun is available: if Bun (≥ 1.3.14) is present, it installs via Bun first; otherwise it downloads a prebuilt binary.
Homebrew(macOS / Linux)
$ brew install can1357/tap/omp
Bun (Recommended, get the latest version)
$ bun install -g @oh-my-pi/pi-coding-agent
Windows(PowerShell)
$ irm https://omp.sh/install.ps1 | iex
Windows supports native running without WSL.
Version pinning (mise)
$ mise use -g github:can1357/oh-my-pi
Verify installation
$ omp --version
Shell auto-completion
omp dynamically generates completion scripts from CLI metadata, so subcommands, flags, and enum values never drift from the actual CLI:
# zsh(加入 ~/.zshrc) eval "$(omp completions zsh)" # bash(加入 ~/.bashrc) eval "$(omp completions bash)" # fish omp completions fish > ~/.config/fish/completions/omp.fish
Build from source
$ git clone https://github.com/can1357/oh-my-pi $ cd oh-my-pi $ bun setup # 安装 Bun 工作区依赖并构建 Rust N-API 插件 $ bun dev # 启动开发版 CLI # 修改 Rust 代码后,重新构建原生插件 $ bun run build:native
Initial configuration: Log in to model provider
After running omp for the first time, use /login or /model to configure your AI provider.
Method 1: OAuth one-click login (no API Key needed)
omp supports logging in to multiple providers via OAuth—the simplest way:
/login # 打开交互式提供商选择器
Providers supporting OAuth include: Anthropic, OpenAI Codex, Google Antigravity (Gemini), Perplexity, Cursor, GitHub Copilot, GitLab Duo, and more.
Method 2: API Key (direct provider connection)
# 在环境变量里设置(推荐写入 ~/.zshrc 或 ~/.bashrc) export ANTHROPIC_API_KEY="sk-ant-xxxx" export OPENAI_API_KEY="sk-xxxx" export GOOGLE_API_KEY="xxxx"
Or configure directly in omp:
/model # 打开模型选择器,可以在这里配置 Key
Method 3: Coding Plan subscription
If you're already subscribed to Cursor, GitHub Copilot, Kilo, Kimi Code, MiniMax Coding Plan, etc., you can route directly to your subscription:
/login # 选择对应的 Coding Plan 提供商,OAuth 授权
Method 4: Local models (Ollama / LM Studio)
# 先启动 Ollama $ ollama serve # 在 omp 里选择 Ollama 提供商(key 可选) /model # 选择 Ollama,指向 http://localhost:11434
Configuration path
All configuration is stored in the ~/.omp/ directory:
~/.omp/
agent/
settings.yml # 主配置文件
models.yml # 自定义模型/提供商
keybindings.yml # 快捷键绑定
rules/ # 流规则(stream rules)
skills/ # 技能文档
First conversation: TUI basics
This section introduces omp's full-screen TUI interface and basic interaction methods.
Launch omp
# 在项目目录下启动 $ cd ~/your-project $ omp
After omp starts, it enters the full-screen TUI (terminal user interface). Tool calls are rendered as cards, and edit operations show a preview before being written to disk.
Note: omp uses the Kitty keyboard protocol. It is recommended to run it in terminals that support this protocol (Kitty, Ghostty, WezTerm, iTerm2) for the best experience.
Basic interaction
Enter your task and press Enter to send:
> Analyze the directory structure of this project and tell me what the main modules are.
omp automatically calls tools such as read and search to scan the codebase and returns a structured summary.
Common key bindings
| Key | Function |
|---|---|
| Enter | Send message |
| Ctrl+J / Shift+Enter | Newline within message (does not send) |
| Ctrl+P | Cycle through available models for the current role |
| Shift+Ctrl+P | Cycle in reverse |
| Ctrl+T | Expand/collapse Todo panel |
| Ctrl+C | Interrupt current task |
| Esc | Cancel pending confirmation |
| ↑ / ↓ | Browse historical messages / options |
| ? | Insert ? on empty input; use /hotkeys to view shortcut list |
Single execution (non-interactive mode)
# 一次性执行任务并退出 $ omp -p "列出所有 .ts 文件里未使用的 export" # 管道输入 $ git diff HEAD~1 | omp -p "给这个 diff 写一个精简的 commit message"
Resume historical sessions
$ omp --resume # 打开会话选择器(Tab 补全可用) $ omp --resume <id> # 直接恢复指定会话
Core tools explained in detail
omp's 32 tools are unified under one namespace; read, search, and bash are the three most frequently used in daily work.
read: Unified reading interface
read is one of omp's killer tools. It doesn't just read files—it understands content structure:
# 读文件(返回结构化摘要,而非全文 dump) read src/auth/login.ts # 读目录(返回树形结构概览) read src/ # 读 URL(返回结构化 Markdown,锚点保留) read https://docs.anthropic.com/en/api/messages # 读 arxiv 论文 PDF read https://arxiv.org/pdf/2604.10739v1 # 读 SQLite 数据库 read data/app.db # 读 GitHub PR(统一路径接口) read pr://can1357/oh-my-pi/1428 # 读 PR 的 diff read pr://can1357/oh-my-pi/1428/diff/1 # 读 GitHub Issue read issue://can1357/oh-my-pi/142
Key design: for files, read returns a Tree-sitter generatedstructured summary(function names, class names, important comments) instead of dumping the entire file into the context. This greatly saves tokens while retaining key information. When detailed content is needed, the Agent calls read again to expand specific sections.
search:in-process ripgrep
# 正则搜索(无 fork/exec,直接在进程内跑)
search "useState\(" src/
# 带文件类型过滤
search "TODO:" --type ts
# 在内部 URL 上搜索(如 PR diff)
search "loginUser" pr://can1357/oh-my-pi/1063/diff
edit: Hashline precise editing
See the next section for details. This is one of omp's most technically sophisticated tools.
bash: Persistent shell session
# 执行命令(bash 会话在调用间保持存活) bash: npm test bash: git log --oneline -10 bash: cargo build --release
omp's bash tool embeds the full brush shell (a Rust implementation of bash). Instead of forking a new process each time, it maintains a persistent session where environment variables and working directory are preserved across calls.
eval: Python + JavaScript persistent kernels
See later sections for details.
lsp: Complete LSP operations
See later sections for details.
todo: Task management
omp has a built-in structured task list supporting phases and task status tracking. Ctrl+T toggles Todo panel visibility.
ask: Structured questions
When the Agent needs a user decision, it calls ask to pop up an interactive selector with recommended options, rather than mixing questions into the output.
Hashline: More precise file editing
This is one of omp's most important technical innovations. This section introduces how Hashline works and its benchmark results.
Problems with traditional str_replace
Most other Agents use the str_replace format to have the model output "old content" + "new content" pairs. The problem is:
- The model tends to get spaces, newlines, and quotes in the old content wrong
- Once the file is modified after the Agent's operation, the anchor becomes invalid
- Errors cause many retries, consuming more tokens
Hashline's solution
Hashline has the modeluse a content hash to identify the lines to modifyinstead of retyping that content:
# Hashline patch 示例(Agent 内部生成,你不需要手写)
@@{a3f2}
- const result = compute(x)
+ const result = compute(x, options)
@@{b7c1}
- return null
+ return undefined
{a3f2} is the hash prefix of the target line content. If the file changes cause the hash to mismatch, the patch will berejectedinstead of silently applying to the wrong place.
Benchmark results
Measured data from the README:
| Model | Metric | Effect |
|---|---|---|
| Grok Code Fast 1 | Edit success rate | 6.7% → 68.3% (10x improvement) |
| Gemini 3 Flash | vs str_replace | +5 percentage points, surpassing Google's own best implementation |
| Grok 4 Fast | Output token consumption | Reduced by 61% |
| MiniMax | Pass rate | Improved 2.1x (weights and prompt completely unchanged) |
ast_edit: Structured code rewriting
A higher-level editing tool than Hashline; it uses ast-grep pattern matching followed by structured rewriting:
# 把所有 console.log(...) 替换掉 ast_edit: console.log($X) → logger.debug($X)
ast_edit first returns aproposed (preview) card; only after the Agent confirms and calls resolve does it actually write to disk—an atomic operation that either succeeds completely or changes nothing.
ast_grep: Structured code search
Supports Tree-sitter syntax matching for 50+ languages:
# 找出所有没有 await 的 async 函数调用 ast_grep: "promise.then($X)"
LSP integration: What the IDE knows, the Agent knows too
omp integrates a complete LSP (Language Server Protocol) client, supporting 14 operations.
Configure LSP server
Configure in the project directory's .omp/, or via omp's configuration wizard:
Examples
lsp:
servers:
typescript:
command: typescript-language-server
args: ["--stdio"]
rust-analyzer:
command: rust-analyzer
python:
command: pylsp
14 LSP operations
| Operation | Description |
|---|---|
| diagnostics | Get diagnostic errors for a file/workspace (like IDE red squiggles) |
| hover | Get type information and doc comments for a symbol |
| definition | Go to definition |
| references | Find all references |
| rename | Rename symbol (via workspace/willRenameFiles, ensuring re-exports and barrel files are updated synchronously) |
| code_action | Get and execute code actions (e.g., auto-import, fix lint errors) |
| completion | Get completion list |
| signature_help | Get function signature help |
| document_symbols | Get all symbols in a file |
| workspace_symbols | Search for symbols across the entire workspace |
| format | Format file |
| range_format | Format selected range |
| implementation | Go to interface implementation |
| type_definition | Go to type definition |
The right way to rename
Ordinary Agents rename by searching for strings and replacing them one by one, which is prone to missing or wrongly replacing. omp does it through the LSP protocol:
> 把 formatBytes 函数重命名为 humanizeFileSize
# omp 内部执行:
lsp.references("formatBytes") → 找到 5 处引用,分布在 3 个文件
lsp.rename("formatBytes", "humanizeFileSize") → 通过 LSP workspace/willRenameFiles
search "formatBytes" → 0 matches ✓ 完成
Re-exports, barrel files (index.ts), and aliased imports are all correctly updated because renaming goes through the LSP protocol rather than text replacement.
Debugger integration (DAP)
omp implements a complete DAP (Debug Adapter Protocol) client, supporting 28 debug operations.
Supported debuggers
| Language | Debugger |
|---|---|
| C / C++ / Rust | lldb-dap / codelldb |
| Go | dlv(Delve) |
| Python | debugpy |
| Node.js / TypeScript | Node.js built-in inspector |
| General | Any DAP-compatible debugger |
Typical scenario: Locating a C program crash
> 这个 C 程序一直 segfault,帮我找原因
# omp 内部执行:
debug.launch("lldb-dap", "./build/demo")
debug.continue() # 运行到崩溃
debug.pause()
debug.stackTrace() # 查看调用栈
debug.scopes(frameId) # 查看局部变量
debug.evaluate("*ptr") # 评估表达式
Typical scenario: Investigating Go service deadlocks
> Go 服务挂住了,帮我看看
# omp 内部执行:
debug.attach("dlv", pid)
debug.threads() # 列出所有 goroutine
debug.stackTrace(threadId) # 查看挂住的 goroutine 调用栈
No more sprinkling fmt.Println or console.log throughout the code—omp directly drives a real debugger.
Subagents: Parallel processing
When a task can be split into mutually independent subtasks, omp uses the task tool to spawn parallel subagents, each running in an isolated workspace and returning a typed result object.
Workspace isolation mechanism
omp uses platform-native filesystem snapshots to isolate subagent workspaces:
| Operating system / filesystem | Isolation mechanism |
|---|---|
| macOS(APFS) | APFS clone (instant, zero copy-on-write) |
| Linux(btrfs/zfs) | reflink |
| Linux(overlayfs) | overlay mount |
| Windows | projfs / rcopy |
Each subagent gets an independent workspace copy, with no interference and no merge conflicts.
Usage examples
> 我有三个微服务:auth-service、api-service、worker-service。
请同时检查它们的依赖有没有已知的安全漏洞,分别出报告。
# omp 内部执行:
task(workers=[
{name: "auth", workdir: "services/auth"},
{name: "api", workdir: "services/api"},
{name: "worker", workdir: "services/worker"}
])
# 三个子 Agent 并行跑,各自输出结构化 JSON:
# { findings: [...], severity: "high", affected: ["lodash@4.17.15"] }
# 父 Agent 合并结果,汇总报告
Inter-subagent communication (IRC)
Parallel subagents can communicate via the irc tool with short messages to coordinate work:
# 子 Agent A:
irc.send("ComponentsExports", {exports: ["Button", "Input"]})
# 子 Agent B 收到消息后调整自己的分析范围
Pulling subagent results
The parent Agent can directly access a subagent's structured output using path syntax:
# 读取子 Agent findings 的第一条记录的 path 字段 read agent://<subagent-id>/findings.0.path
Hindsight: Cross-session memory
Hindsight is omp's project-level memory system that lets the Agent retain understanding of the codebase between sessions.
How it works
- retainWhen the Agent discovers valuable information during operation, it proactively calls retain to write to the memory bank
- recallSearch the memory bank by keywords
- reflectHave Hindsight synthesize information from the memory bank to generate a synthetic answer
- At the end of each session, omp automatically compresses the session into a "mental model", loaded in the first round of the next session
Scope
Hindsight isproject-level—what you learn in project A won't leak into project B. Memory is stored in the .omp/ directory (or sharded by project in ~/.omp/).
Actual effects
The first time you use omp in a project, you need to explain the project structure. After using it for a while, omp knows on its own:
- What tech stack this project uses
- Responsibility division of the main modules
- What refactors were done before
- Which files are "minefields" (places that often cause problems)
Code execution: Python + JavaScript dual kernels
Most Agent tools only provide a Python sandbox. omp runs two persistent kernels, and both can call back into the Agent's own tools.
Python kernel (eval)
Examples
import pandas as pd
df = pd.read_csv(tool.read("data/sales.csv")) # Use the Agent's read tool to load files
print(df.describe())
result = tool.search("revenue", "src/") # Search in the codebase
JavaScript (Bun) kernel (eval)
Examples
const data = tool.read("data/sales.csv") // Can also call Agent tools
const top = data.split('\n').slice(1)
.map(line => line.split(','))
.sort((a, b) => +b[2] - +a[2])
.slice(0, 5)
console.table(top)
Dual kernels share Prelude
The two kernels share a prelude (preloaded context). You can process data in Python, then generate charts in JS—the whole process is a continuous eval session without leaving the tool interface.
Stream Rules: Real-time behavior correction
This is omp's unique real-time behavior correction mechanism, solving the problem of "the model not obeying".
Problems with traditional approaches
Writing all rules into the System Prompt costs the full token amount in every conversation, and the model may still ignore them.
How Stream Rules work
Rules aredormantuntil the trigger condition appears:
- Regular expressions monitor the model's streaming output
- Once matched (at the mid-token level), immediately abort the current stream
- Inject the rule content into context as a system reminder
- Regenerate from the same position
- Injected rules survive context compression
Examples
# ~/.omp/agent/rules/no-box-leak.yml
name: box-leak
pattern: "Box::leak"
reminder: |
Do not use Box::leak in production code paths.
Memory leaks will cause the service to OOM under high load.
Use Arc<str> or other reference-counted approaches instead.
Effect: when the model writes Box::leak, the stream is aborted, the rule is injected, and the model automatically corrects to Arc
Quickly create rules with /omfg
omp provides a helper command that lets you describe rules in natural language, and it generates the regex and rule file:
/omfg 不要在任何地方用 any 类型,要求用具体的类型定义或 unknown
omp generates, validates, and saves the rule; it takes effect next time.
Model routing: 40+ providers, four roles
omp uses roles rather than model names to dispatch work, achieving "the right model for the right task".
Four model roles
| Role | Purpose | CLI Flag | Environment variable |
|---|---|---|---|
| default | General conversation and code generation | Default | — |
| smol | Cheap sub-agent exploration | --smol | PI_SMOL_MODEL |
| slow | Deep reasoning tasks | --slow | PI_SLOW_MODEL |
| plan | Planning mode | --plan | PI_PLAN_MODEL |
# 启动时指定角色覆盖 $ omp --smol # 整个会话使用 smol 模型(低成本) $ omp --slow # 使用慢速推理模型(高质量) $ omp --plan # 使用计划专用模型
Switching models in a session
/model # 打开交互式模型选择器 /model claude-sonnet-4.6 # 切换到指定模型 Ctrl+P # 循环切换当前角色的可用模型
Custom providers (~/.omp/agent/models.yml)
Examples
providers:
my-company-llm:
type: openai-completions
baseUrl: https://llm.internal.company.com/v1
apiKey: "${MY_LLM_KEY}"
models:
- id: gpt-4o
name: Internal GPT-4o
Failover chains
Examples
retry:
fallbackChains:
default:
- anthropic/claude-sonnet-4.6
- openai/gpt-4o
- google/gemini-2.0-flash
Path-level model binding
Examples
models:
enabledModels:
- path: ~/projects/side-project
models: ["deepseek/deepseek-coder"]
Key rotation (multi-Key load balancing)
Examples
providers:
anthropic:
apiKeys:
- "${ANTHROPIC_KEY_1}"
- "${ANTHROPIC_KEY_2}"
- "${ANTHROPIC_KEY_3}"
# Automatic rotation; switch to the next key after a single key exceeds the limit
Common slash command quick reference
Type / in the chat input box to trigger command completion.
| Command | Function |
|---|---|
| /model | Open model selector |
| /login | Log in to provider (OAuth) |
| /resume | Resume historical session |
| /review | Code review for current branch / specified commit / uncommitted changes |
| /commit | Smart commit splitting |
| /omfg | Create stream rules in natural language |
| /debug | Open debug/report/profiling tools |
| /hotkeys | View all keyboard shortcuts |
| /reload-plugins | Hot reload plugins |
| /compact | Manually compress context (save tokens) |
| /? | Show help |
/review: Code review with priorities
# 审查当前分支 vs main /review # 审查指定 commit /review abc1234 # 审查未提交的改动 /review --unstaged
omp spawns dedicated reviewer sub-agents to scan in parallel. Each issue is sorted by P0-P3 priority with a confidence score. P0 = blocks release, P3 = optional improvement.
/commit: Atomic commit splitting
$ omp commit
omp reads the entire working tree (git_overview + git_file_diff + git_hunk), splitting unrelated changes into independent atomic commits, ordered by dependency:
- Source code commits come before tests, docs, and config
- Changes with dependencies are not incorrectly grouped
- Circular dependencies are rejected; nothing is written
- Lockfiles such as package-lock.json and Cargo.lock are excluded from analysis
Plugins and extensions
omp plugins are TypeScript modules using the exact same API as built-in tools, with no reserved interfaces.
Install plugins
$ omp install <plugin-name> # 从 npm 安装 $ omp install github:user/repo # 从 GitHub 安装 $ omp install ./path/to/plugin # 从本地路径安装
Create plugins
You can just have omp write it for you:
> 给我创建一个插件,添加 /deploy 命令, 自动运行测试、构建、然后 SSH 上传到生产服务器
omp generates the plugin code; it takes effect immediately after you /reload-plugins.
Hot reload
No need to restart omp after modifying plugin code:
/reload-plugins
ACP: Using omp in the Zed editor
$ omp acp
Connect omp to the Zed editor via the Agent Client Protocol. omp reads the buffer you're editing, writes files via the editor's save path, launches a shell in the editor's terminal, and destructive operations trigger a permission dialog.
Migrating from other tools
A major advantage of omp isout-of-the-box readingConfig files already created by other tools are read directly, no migration scripts needed:
| Tool | Config file | How omp reads it |
|---|---|---|
| Cursor | .cursor/rules/*.mdc | Auto-inherited |
| Claude Code | .claude/settings.json、CLAUDE.md | Auto-inherited |
| Cline | .clinerules | Auto-inherited |
| GitHub Copilot | .github/copilot/instructions.md(applyTo) | Auto-inherited |
| Codex | AGENTS.md | Auto-inherited |
| Windsurf | .windsurfrules | Auto-inherited |
| Gemini CLI | .gemini/ configuration | Auto-inherited |
On first run, omp scans the working directory and automatically loads all detected formats.
Resources and community
- Website:omp.sh
- GitHub:github.com/can1357/oh-my-pi(MIT open source)
- Tool docs:omp.sh/docs/tools
- Provider docs:omp.sh/docs/providers
- SDK docs:omp.sh/docs/sdk
- Changelog:github.com/can1357/oh-my-pi/CHANGELOG.md
- npm:@oh-my-pi/pi-coding-agent
- Discord:discord.gg/4NMW9cdXZa