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.


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

DimensionClaude Code / similar toolsomp
Edit formatstr_replace (error-prone)Hashline (content hash anchors, resistant to whitespace differences)
File readingFull-text dumpStructure summary + on-demand expansion
LSPNone or limitedComplete 14 LSP operations (including rename, jump, code actions)
DebuggerNoneComplete DAP: lldb, dlv, debugpy
SubagentsNone or limitedParallel subagents, isolated workspaces, typed return values
SearchShell-invoked ripgrepIn-process ripgrep, no fork/exec
Behavior correctionRelies on promptStream rules: regex match → mid-token injection → retry
Cross-session memoryNoneHindsight memory bank (project-level)
Code executionPython sandboxPersistent Python + Bun dual kernels, can call each other's Agent tools
Tech stackPure 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

KeyFunction
EnterSend message
Ctrl+J / Shift+EnterNewline within message (does not send)
Ctrl+PCycle through available models for the current role
Shift+Ctrl+PCycle in reverse
Ctrl+TExpand/collapse Todo panel
Ctrl+CInterrupt current task
EscCancel 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:

ModelMetricEffect
Grok Code Fast 1Edit success rate6.7% → 68.3% (10x improvement)
Gemini 3 Flashvs str_replace+5 percentage points, surpassing Google's own best implementation
Grok 4 FastOutput token consumptionReduced by 61%
MiniMaxPass rateImproved 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

# ~/.omp/agent/settings.yml (example snippet)
lsp
:
  servers
:
    typescript
:
      command
: typescript-language-server
      args
: ["--stdio"]
    rust-analyzer
:
      command
: rust-analyzer
    python
:
      command
: pylsp

14 LSP operations

OperationDescription
diagnosticsGet diagnostic errors for a file/workspace (like IDE red squiggles)
hoverGet type information and doc comments for a symbol
definitionGo to definition
referencesFind all references
renameRename symbol (via workspace/willRenameFiles, ensuring re-exports and barrel files are updated synchronously)
code_actionGet and execute code actions (e.g., auto-import, fix lint errors)
completionGet completion list
signature_helpGet function signature help
document_symbolsGet all symbols in a file
workspace_symbolsSearch for symbols across the entire workspace
formatFormat file
range_formatFormat selected range
implementationGo to interface implementation
type_definitionGo 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

LanguageDebugger
C / C++ / Rustlldb-dap / codelldb
Godlv(Delve)
Pythondebugpy
Node.js / TypeScriptNode.js built-in inspector
GeneralAny 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 / filesystemIsolation mechanism
macOS(APFS)APFS clone (instant, zero copy-on-write)
Linux(btrfs/zfs)reflink
Linux(overlayfs)overlay mount
Windowsprojfs / 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: ["[email protected]"] }

# 父 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

# In the eval tool, Python can call omp's tool.*
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

// Within the same eval session, you can switch to the JS kernel
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:

  1. Regular expressions monitor the model's streaming output
  2. Once matched (at the mid-token level), immediately abort the current stream
  3. Inject the rule content into context as a system reminder
  4. Regenerate from the same position
  5. Injected rules survive context compression

Examples

# Example: forbid using Box::leak
# ~/.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, without user intervention.

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

RolePurposeCLI FlagEnvironment variable
defaultGeneral conversation and code generationDefault—
smolCheap sub-agent exploration--smolPI_SMOL_MODEL
slowDeep reasoning tasks--slowPI_SLOW_MODEL
planPlanning mode--planPI_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

span style="color: #0053A6;">
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

# When Claude hits a 429 rate limit, automatically switch to GPT
retry
:
  fallbackChains
:
    default
:
     - anthropic/claude-sonnet-4.6
      - openai/gpt-4o
      - google/gemini-2.0-flash

Path-level model binding

Examples

# This specific repo forces deepseek (low cost), without affecting global config
models
:
  enabledModels
:
    - path
: ~/projects/side-project
      models
: ["deepseek/deepseek-coder"]

Key rotation (multi-Key load balancing)

Examples

span style="color: #0053A6;">
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.

CommandFunction
/modelOpen model selector
/loginLog in to provider (OAuth)
/resumeResume historical session
/reviewCode review for current branch / specified commit / uncommitted changes
/commitSmart commit splitting
/omfgCreate stream rules in natural language
/debugOpen debug/report/profiling tools
/hotkeysView all keyboard shortcuts
/reload-pluginsHot reload plugins
/compactManually 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 &lt;plugin-name&gt;          # 从 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:

ToolConfig fileHow omp reads it
Cursor.cursor/rules/*.mdcAuto-inherited
Claude Code.claude/settings.json、CLAUDE.mdAuto-inherited
Cline.clinerulesAuto-inherited
GitHub Copilot.github/copilot/instructions.md(applyTo)Auto-inherited
CodexAGENTS.mdAuto-inherited
Windsurf.windsurfrulesAuto-inherited
Gemini CLI.gemini/ configurationAuto-inherited

On first run, omp scans the working directory and automatically loads all detected formats.


Resources and community

Other extensions