diff --git a/README.md b/README.md index 72e846d3b..4dd3ddbf6 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@

- Pi Monorepo + omp

- AI coding agent for the terminal + A coding agent with the IDE wired in. + omp.sh

@@ -18,1698 +19,424 @@

- Fork of badlogic/pi-mono by @mariozechner + Fork of Pi by @mariozechner

-## Table of Contents +The most capable agent surface that ships. Continuously tuned by real-world use — complete out of the box, open all the way down. -- [Highlights](#highlights) -- [Installation](#installation) -- [Getting Started](#getting-started) - - [Terminal Setup](#terminal-setup) - - [API Keys & OAuth](#api-keys--oauth) - - [First 15 Minutes (Recommended)](#first-15-minutes-recommended) -- [Usage](#usage) - - [Slash Commands](#slash-commands) - - [Editor Features](#editor-features) - - [Keyboard Shortcuts](#keyboard-shortcuts) - - [Bash Mode](#bash-mode) - - [Image Support](#image-support) -- [Sessions](#sessions) - - [Session Management](#session-management) - - [Context Compaction](#context-compaction) - - [Branching](#branching) - - [Memory](#memory) -- [Configuration](#configuration) - - [Project Context Files](#project-context-files) - - [Custom System Prompt](#custom-system-prompt) - - [Custom Models and Providers](#custom-models-and-providers) - - [Settings File](#settings-file) -- [Extensions](#extensions) - - [Themes](#themes) - - [Custom Slash Commands](#custom-slash-commands) - - [Skills](#skills) - - [Hooks](#hooks) - - [Custom Tools](#custom-tools) - - [Marketplace](#marketplace) -- [CLI Reference](#cli-reference) -- [Tools](#tools) -- [Programmatic Usage](#programmatic-usage) - - [SDK](#sdk) - - [RPC Mode](#rpc-mode) - - [ACP Mode](#acp-mode) - - [HTML Export](#html-export) -- [Philosophy](#philosophy) -- [Development](#development) -- [Monorepo Packages](#monorepo-packages) -- [License](#license) +**40+** providers · **32** built-in tools · **13** lsp ops · **27** dap ops · **~27k** lines of Rust core. ---- +## Install -## Highlights +**macOS · Linux** -### + Commit Tool (AI-Powered Git Commits) +```sh +curl -fsSL https://omp.sh/install | sh +``` -AI-powered conventional commit generation with intelligent change analysis: +**Bun (recommended)** -- **Agentic mode**: Tool-based git inspection with `git-overview`, `git-file-diff`, `git-hunk` for fine-grained analysis -- **Split commits**: Automatically separates unrelated changes into atomic commits with dependency ordering -- **Hunk-level staging**: Stage individual hunks when changes span multiple concerns -- **Changelog generation**: Proposes and applies changelog entries to `CHANGELOG.md` files -- **Commit validation**: Detects filler words, meta phrases, and enforces conventional commit format -- **Legacy mode**: `--legacy` flag for deterministic pipeline when preferred -- Run via `omp commit` with options: `--push`, `--dry-run`, `--no-changelog`, `--context` - -### + Eval Tool (Multi-Language Code Execution) - -

- eval -

- -Persistent multi-language REPL for the agent. One tool, two backends, a shared helper prelude — replaces the previous standalone Python tool: - -- **Cell header format**: One header per cell — `*** Cell :"" [t:<duration>] [rst]`. `lang` is `py` or `js`; `t:` sets a per-cell timeout, `rst` wipes the cell's own language kernel before running -- **Python backend**: Spawns one `python -u runner.py` subprocess per kernel speaking NDJSON over stdin/stdout. Cancellation sends `SIGINT` (real `KeyboardInterrupt`); the same subprocess is reused across cells in session mode. No Jupyter dependency -- **JavaScript backend**: Worker-pool runtime with `process`, Web APIs, `Buffer`, `fs/promises`, and `Bun` globals; top-level `await` works, static ESM imports are rewritten to resolve against the session cwd -- **Shared prelude**: `read`, `write`, `display`, `tree`, `diff`, `env`, `output`, plus `tool.<name>(args)` to invoke any session tool (read, write, edit, github, …) from inside a cell -- **Browser-tab JS shares the runtime**: `browser` tool `run` cells expose the same helper globals and ESM rewriting as `eval` JS cells -- **Magics without IPython**: `%pip`, `%cd`, `%env`, `%time`, `%timeit`, `%%bash`, `%%capture`, `%%writefile`, `!shell`, … work natively in the subprocess backend -- **Markdown / image rendering**: `display()` accepts text, JSON, dataframes, figures, images; `text/markdown` output renders inline; mermaid fences render as graphics in iTerm2 / Kitty -- Toggle backends via `eval.py` / `eval.js` settings; install Python with `omp setup python` - -### + LSP Integration (Language Server Protocol) - -<p align="center"> - <img src="https://github.com/can1357/oh-my-pi/blob/main/assets/lspv.webp?raw=true" alt="lsp"> -</p> - -Full IDE-like code intelligence with automatic formatting and diagnostics: - -- **13 LSP operations**: `diagnostics`, `definition`, `type_definition`, `implementation`, `references`, `hover`, `symbols`, `rename`, `rename_file`, `code_actions`, `request`, `capabilities`, `status`, `reload` -- **Format-on-write**: Auto-format code using the language server's formatter (rustfmt, gofmt, prettier, etc.) -- **Diagnostics on write/edit**: Immediate feedback on syntax errors and type issues after every file change -- **Workspace diagnostics**: Check entire project for errors with `lsp` action `diagnostics` (without a file) -- **40+ language configs**: Out-of-the-box support for Rust, Go, Python, TypeScript, Java, Kotlin, Scala, Haskell, OCaml, Elixir, Ruby, PHP, C#, Lua, Nix, and many more -- **File renames**: `rename_file` routes through `workspace/willRenameFiles` / `didRenameFiles` so import updates land before the disk move; `apply: false` previews edits -- **Arbitrary requests**: `request` invokes any LSP method with auto-built `textDocument`/`position` params or raw JSON payload -- **Local binary resolution**: Auto-discovers project-local LSP servers in `node_modules/.bin/`, `.venv/bin/`, etc. -- **Symbol disambiguation**: `occurrence` parameter resolves repeated symbols on the same line - -### + DAP Integration (Debug Adapter Protocol) - -Drive a real debugger from the agent — set breakpoints, step through code, inspect threads/stack/variables, and pause runaway processes — instead of bisecting with `printf`: - -- **27 debug operations**: `launch`, `attach`, `set_breakpoint` / `remove_breakpoint` (source or function, with optional `condition`), `set_instruction_breakpoint`, `data_breakpoint_info` / `set_data_breakpoint`, `continue`, `step_over` / `step_in` / `step_out`, `pause`, `evaluate` (`context: "repl"` for raw debugger commands), `stack_trace`, `threads`, `scopes`, `variables`, `disassemble`, `read_memory` / `write_memory`, `modules`, `loaded_sources`, `output` (captured stdout/stderr), `custom_request`, `terminate`, `sessions` -- **14 bundled adapters**: `gdb`, `lldb-dap`, `codelldb`, `debugpy`, `dlv`, `js-debug-adapter`, `netcoredbg`, `kotlin-debug-adapter`, `rdbg` (Ruby), `php-debug-adapter`, `bash-debug-adapter`, `dart-debug-adapter`, `flutter-debug-adapter`, `elixir-ls-debugger` -- **Auto-selection**: Adapter is inferred from program path / extension + workspace root markers (`Cargo.toml`, `go.mod`, `pyproject.toml`, …); override with `adapter: "lldb-dap"` when you want a specific debugger -- **Local + remote**: `pid` for local attach, `port` for remote attach where the adapter supports it -- **Pause runaway code**: `pause` interrupts a running program so the agent can inspect threads / stack / variables before deciding to `continue` or `terminate` -- **Single active session**: One debug session at a time per agent; `terminate` cleans up; `sessions` lists tracked sessions -- Gated by `debug.enabled` (default `true`); the adapter binary must be reachable on `PATH` (or the program's project dir) at launch time - -### + Time Traveling Streamed Rules (TTSR) - -<p align="center"> - <img src="https://github.com/can1357/oh-my-pi/blob/main/assets/ttsr.webp?raw=true" alt="ttsr"> -</p> - -Zero context-use rules that inject themselves only when needed: - -- **Pattern-triggered injection**: Rules define regex triggers that watch the model's output stream -- **Just-in-time activation**: When a pattern matches, the stream aborts, the rule injects as a system reminder, and the request retries -- **Zero upfront cost**: TTSR rules consume no context until they're actually relevant -- **One-shot per session**: Each rule only triggers once, preventing loops -- Define via `ttsrTrigger` field in rule files (regex pattern) - -Example: A "don't use deprecated API" rule only activates when the model starts writing deprecated code, saving context for sessions that never touch that API. - -### + Interactive Code Review - -<p align="center"> - <img src="https://github.com/can1357/oh-my-pi/blob/main/assets/review.webp?raw=true" alt="review"> -</p> - -Structured code review with priority-based findings: - -- **`/review` command**: Interactive mode selection (branch comparison, uncommitted changes, commit review) -- **Structured findings**: `report_finding` tool with priority levels (P0-P3: critical → nit) -- **Verdict rendering**: aggregates findings into approve/request-changes/comment -- Combined result tree showing verdict and all findings - -### + Task Tool (Subagent System) - -<p align="center"> - <img src="https://github.com/can1357/oh-my-pi/blob/main/assets/task.webp?raw=true" alt="task"> -</p> - -Parallel execution framework with specialized agents, live peer messaging, and real-time streaming: - -- **7 bundled agents**: `explore`, `plan`, `designer`, `reviewer`, `librarian`, `task`, `quick_task` -- **IRC peer messaging**: Subagents see live siblings + parent in their `# IRC Peers` block and can DM each other mid-flight via the `irc` tool, so a serial waterfall can become parallel with one round-trip clarification -- **Real-time artifact streaming**: Task outputs stream as they're created, not just at completion -- **Full output access**: Read complete subagent output via `agent://<id>` resources (or extract a JSON field via `agent://<id>/path`) when previews truncate -- **Isolation backends**: `task.isolation.mode` selects from `auto`, `apfs`, `btrfs`, `zfs`, `reflink`, `overlayfs`, `projfs`, `block-clone`, `rcopy` (PAL-backed copy-on-write filesystems), with patch or branch merge strategies -- **Async background jobs**: Background execution with configurable concurrency (up to 100 jobs); the unified `job` tool handles `poll`, `cancel`, and `list` with per-agent ownership scoping -- **Agent Control Center**: `/agents` dashboard for managing and creating custom agents -- **AI-powered agent creation**: Generate custom agent definitions with the architect model -- **Per-agent model overrides**: Assign specific models to individual agents via swarm extension -- User-level (`~/.omp/agent/agents/`) and project-level (`.omp/agents/`) custom agents - -### + IRC Peer Messaging - -Live agent-to-agent messaging across parent and subagent sessions — no file polling, no orchestrator round-trips: - -- **`irc` tool**: `op: "list"` enumerates visible peers (`0-Main`, task ids like `0-AuthLoader`); `op: "send"` delivers a DM or `to: "all"` broadcast -- **Synchronous side-channel**: The recipient generates a prose reply on an ephemeral turn even while its main loop is mid-tool-call; the exchange is injected into both transcripts on the next turn -- **Live in-chat rendering**: The main agent's UI relays every peer exchange so the human sees coordination happen -- **`AgentRegistry`**: Process-global registry pre-registers each subagent before its system prompt is built, so initial `# IRC Peers` blocks reflect siblings spawned in the same batch -- Gated by `irc.enabled` (default `true`) - -### + GitHub as Virtual Filesystem - -Issues, PRs, and diffs are addressable as virtual markdown files. The agent doesn't learn a new tool surface to browse GitHub — it just `read`s a URL, the same way it reads any other file. No copy-pasting issue bodies into prompts, no scraping PR pages, no separate "github" subcommand to remember: - -- **Read an issue**: `read issue://1234` — rendered as markdown with title, author, labels, body, and threaded comments -- **Read a PR**: `read pr://1234` (append `?comments=0` to skip the discussion). Each PR view points the agent at the matching diff URL -- **Read a diff**: `read pr://1234/diff` (changed-file listing), `read pr://1234/diff/3` (third file only), `read pr://1234/diff/all` (full unified diff). Hashline anchors work on diff slices, so the agent can quote a hunk by anchor without reproducing whitespace -- **Browse**: bare `read issue://` or `read pr://` lists recent items; filter with `?state=open|closed|merged|all`, `?author=`, `?label=`, `?limit=` -- **Cross-repo**: `read issue://owner/repo/N` works the same way for repositories outside the current checkout -- **Background refresh**: A soft TTL serves recent fetches instantly; a hard TTL serves stale-but-readable while a background fetch refreshes the cache, so the agent never blocks on a network round-trip to re-read the same issue mid-session - -The complementary `github` tool covers the operations a URL can't model: `pr_create`, `pr_checkout`, `pr_push`, `run_watch`, and the `search_*` family (issues, PRs, code, commits, repos) with relative-time filters like `since: "3d"` / `until: "1w"`. Search calls `gh api` directly so multi-qualifier queries (`is:merged is:pr`) reach GitHub verbatim instead of getting silently re-quoted by `gh search`. - -### + Hindsight Memory - -Opt-in long-term memory backend that records facts, retrieves them on relevant turns, and curates project-level mental models: - -- **Three tools**: `retain` (queue a memory write — non-blocking, batched up to 16 items / 5s), `recall` (search prior memories), `reflect` (post-session summarization) -- **Scoping modes**: `hindsight.scoping` is `global`, `per-project`, or `per-project-tagged` (default — global + project memories merge on recall via tags) -- **Mental models**: Bank-level curated summaries injected as `<mental_models>` developer instructions. Built-in seeds for user preferences, project conventions, and project decisions; manage via `/memory mm list|show|refresh|history|seed|reload|delete` -- **First-turn recall**: Auto-injects relevant memories as a `<memories>` block before the opening user message -- **Retention hygiene**: `<mental_models>` and recall blocks are stripped before storing transcripts so curated context never feeds back as new memory -- **Backend selector**: `memory.backend` is `off`, `local`, or `hindsight`; subagents persist into the parent's bank - -### + ACP Mode (Agent Client Protocol) - -Run omp as an ACP server over stdio so any compliant editor or harness can drive it: - -- **`omp acp` subcommand**: Launches with the same stdout-quiet semantics as `--mode rpc` so no banner leaks into the JSON-RPC channel -- **Client bridge**: When the client advertises capabilities, `bash` routes through `terminal/*`, `read`/`write` route through `fs/read_text_file` / `fs/write_text_file` (surfacing unsaved editor buffers), and `bash`/`edit`/`write`/`ast_edit` are gated by `session/request_permission` (with `allow_always` / `reject_always` decisions remembered for the session) -- **Slash-command parity**: ACP equivalents for `/jobs`, `/changelog`, `/dump`, `/copy`, `/hotkeys`, `/extensions`, `/agents`, `/model`, `/plan`, `/loop`, `/btw`, `/login`, `/logout`, `/resume`, `/tree`, `/branch`, `/new`, `/drop`, `/handoff`, `/fork`, `/export`, `/share`, `/todo`, `/memory`, `/move`, `/mcp`, `/ssh`, `/marketplace`, `/plugins`, plus `/skill:<name>` -- **Plan mode advertised as ACP mode**: `session/new`/`load`/`resume`/`fork` expose a `plan` mode alongside `default`; `session/set_mode` toggles plan-mode for the next turn -- **Rich tool reporting**: Edit results emit `diff` `ToolCallContent` (per-file `oldText` / `newText`); `tool_call_update` `locations` refresh from in-flight args; `StopReason` differentiates `end_turn`, `max_tokens`, `refusal`, `cancelled` -- **Custom extension methods** are prefixed `_omp/*` per the ACP `_`-prefix requirement for non-spec methods - -### + Loop Mode - -`/loop [count|duration]` re-issues the last user prompt automatically: - -- **Bounded by count or time**: `/loop 10` stops after 10 iterations; `/loop 10m` / `/loop 10min` stops after the duration; bare `/loop` toggles unbounded mode -- **Configurable per-iteration action**: Repeat the last prompt, run a stored prompt, or fire a custom action -- **Status line**: Enabled status surfaces the configured limit and remaining budget -- **Strict argument parsing**: Malformed counts or durations surface a usage error instead of silently enabling unbounded loop - -### + Conflict Resolution - -First-class git merge-conflict workflow inside `read` and `write`: - -- **`read` detection**: Each fully-formed column-0 marker block (`<<<<<<<` … `>>>>>>>`) is registered with a session-stable `#N` id and a warning badge (`⚠ N`) on the read tool UI. `read <path>:conflicts` returns a one-line-per-block index of every unresolved conflict -- **Inspect sides**: `read conflict://<N>` shows the recorded region; `read conflict://<N>/ours|theirs|base` shows one side with original-file line alignment -- **Resolve with content tokens**: `write({ path: "conflict://<N>", content })` splices the recorded marker region. `content` may be replacement text or any combination of shorthand tokens `@ours`, `@theirs`, `@base`, `@both` -- **Bulk resolve**: `write({ path: "conflict://*", content })` expands tokens per conflict across every registered block in one call -- **Safe splice**: Validates the live file still contains the recorded markers before splicing, and re-locates the block by exact marker content if line numbers have shifted out-of-band - -### + Internal URL Read Schemes - -`read` is the single entry point for everything the agent might need to inspect — files, URLs, and a family of internal schemes: - -- **`local://`** — session-shared artifacts (`local://PLAN.md`, briefs passed to subagents) -- **`agent://<id>` / `agent://<id>/<json.path>`** — full subagent output, with optional JSON field extraction -- **`artifact://<id>`** — spilled tool output truncated in the live transcript -- **`memory://root`** — project memory summary -- **`issue://<N>` / `pr://<N>`** — GitHub issues, PRs, and diffs as virtual markdown files (see GitHub as Virtual Filesystem) -- **`mcp://<uri>`** — MCP resource fetched via the active manager -- **`skill://<name>` / `skill://<name>/<path>`** — skill instructions and files -- **`rule://<name>`** — rule details -- **`conflict://<N>`** — merge-conflict regions captured by a prior read - -Resolution is process-global so parents and subagents see each other's outputs without explicit wiring. - -### + Recipe Tool (Project Task Runner) - -Run project tasks through one tool that auto-detects every common runner in the working directory: - -- **Auto-detection**: `package.json` scripts (including workspace packages), `Cargo.toml` bin/example/test targets, `Justfile`, `Makefile`, `Taskfile.yml` -- **Single `op` argument**: `op: "test"` or `op: "build --release"`; monorepo namespacing uses `/` (`pkg-a/test`, `crate/bin/server`) -- **Runner-qualified syntax**: `runnerId:task` disambiguates identical task names across multiple runners -- **Auto-availability**: Requesting `bash` automatically pulls in `recipe` when a supported manifest is detected; `bash` stays independently available -- **Unified output**: Same shape as `bash` — exit code, stdout/stderr merged, artifact spillover for long output - -### + Model Roles - -<p align="center"> - <img src="https://github.com/can1357/oh-my-pi/blob/main/assets/models.webp?raw=true" alt="models"> -</p> - -Configure different models for different purposes with automatic discovery: - -- **Role-based routing**: `default`, `smol`, `slow`, `plan`, and `commit` roles -- **Configurable discovery**: Role defaults are auto-resolved and can be overridden per role -- **Role-based selection**: Task tool agents can use `model: pi/smol` for cost-effective exploration -- **Generic OpenAI-compat discovery**: Any provider exposing `/v1/models` (llama.cpp, Ollama, LM Studio, vLLM, OpenRouter forks) is auto-enumerated; keyless-by-design providers are treated as authenticated -- **Explicit prefixes are honored**: `<provider>/<id>` no longer silently falls back to a different provider when the exact pair isn't in the bundled catalog -- CLI args (`--smol`, `--slow`, `--plan`) and env vars (`PI_SMOL_MODEL`, `PI_SLOW_MODEL`, `PI_PLAN_MODEL`) -- Configure roles interactively via `/model` selector and persist assignments to settings - -### + Todo Tool (Task Tracking) - -Structured task management with phased progress tracking: - -- **Phased task lists**: Organize work into named phases with ordered tasks; the renderer numbers phases visually (Ⅰ. Ⅱ. Ⅲ. …) -- **Content-addressed identity**: Tasks are identified by their `content` text and phases by their `name` — no synthetic IDs -- **5 operations**: `init` (setup), `add_phase`, `add_task`, `update` (status changes), `remove_task`, plus `note` for follow-up text -- **4 task states**: `pending`, `in_progress`, `completed`, `abandoned` -- **Auto-normalization**: Ensures exactly one task is `in_progress` at all times -- **Persistent panel**: Todo list displays above the editor with real-time progress -- **`/todo` slash command**: `edit`, `copy`, `start`, `done`, `drop`, `rm`, `append`, `replace`, `export`, `import` operations with fuzzy phase/content matching -- **Markdown export/import**: `/todo export [path]` and `/todo import [path]` round-trip through `TODO.md` -- **Completion reminders**: Agent warned when stopping with incomplete todos (`todo.reminders` setting) - -### + Ask Tool (Interactive Questioning) - -<p align="center"> - <img src="https://github.com/can1357/oh-my-pi/blob/main/assets/ask.webp?raw=true" alt="ask"> -</p> - -Structured user interaction with typed options: - -- **Multiple choice questions**: Present options with descriptions for user selection -- **Multi-select support**: Allow multiple answers when choices aren't mutually exclusive -- **Multi-part questions**: Ask multiple related questions in sequence via `questions` array parameter -- **No default timeout**: `ask.timeout` defaults to `0` (wait indefinitely); set to a non-zero seconds value to auto-select the recommended option - -### + Custom TypeScript Slash Commands - -<p align="center"> - <img src="https://github.com/can1357/oh-my-pi/blob/main/assets/slash.webp?raw=true" alt="slash"> -</p> - -Programmable commands with full API access: - -- Create at `~/.omp/agent/commands/[name]/index.ts` or `.omp/commands/[name]/index.ts` -- Export factory returning `{ name, description, execute(args, ctx) }` -- Full access to `HookCommandContext` for UI dialogs, session control, shell execution -- Return string to send as LLM prompt, or void for fire-and-forget actions -- Also loads from Claude Code directories (`~/.claude/commands/`, `.claude/commands/`) - -### + Universal Config Discovery - -<p align="center"> - <img src="https://github.com/can1357/oh-my-pi/blob/main/assets/discovery.webp?raw=true" alt="discovery"> -</p> - -Unified capability-based discovery that loads configuration from 8 AI coding tools: - -- **Multi-tool support**: Claude Code, Cursor, Windsurf, Gemini, Codex, Cline, GitHub Copilot, VS Code -- **Discovers everything**: MCP servers, rules, skills, hooks, tools, slash commands, prompts, context files -- **Native format support**: Cursor MDC frontmatter, Windsurf rules, Cline `.clinerules`, Copilot `applyTo` globs, Gemini `system.md`, Codex `AGENTS.md` -- **Provider attribution**: See which tool contributed each configuration item -- **Discovery settings**: Enable/disable individual providers via `/extensions` interactive dashboard -- **Priority ordering**: Multi-path resolution across `.omp`, `.claude`, `.codex`, and `.gemini` directories - -### + MCP & Plugin System - -<p align="center"> - <img src="https://github.com/can1357/oh-my-pi/blob/main/assets/perplexity.webp?raw=true" alt="perplexity"> -</p> - -Full Model Context Protocol support with external tool integration: - -- Stdio and HTTP transports for connecting to MCP servers -- **OAuth support**: Explicit `clientId` and `callbackPort` in MCP server config, manual OAuth callbacks via slash commands -- **Browser server filtering**: Automatically filters browser-type MCP servers to prevent conflicts with built-in browser tool -- **Automatic Exa filtering**: Extracts Exa API keys and prefers the native Exa integration -- **Stable tool ordering**: Reconnects no longer reshuffle the tools array, preserving Anthropic prompt caching across MCP transport flaps -- **Config schema + setup guide**: [`docs/mcp-config.md`](./docs/mcp-config.md) and [`packages/coding-agent/src/config/mcp-schema.json`](./packages/coding-agent/src/config/mcp-schema.json) -- Plugin CLI (`omp plugin install/enable/configure/doctor`) -- Hot-loadable plugins from `~/.omp/plugins/` with npm/bun integration -- `disabledServers` works on both project-level and user-level third-party servers - -### + Web Search & Fetch - -<p align="center"> - <img src="https://github.com/can1357/oh-my-pi/blob/main/assets/arxiv.webp?raw=true" alt="arxiv"> -</p> - -Multi-provider search and full-page scraping with specialized handlers: - -- **Multi-provider search**: `auto`, `exa`, `brave`, `jina`, `kimi`, `zai`, `anthropic`, `perplexity`, `gemini`, `codex`, `synthetic` -- **Specialized handlers**: Site-specific extraction for code hosts, registries, research sources, forums, and docs -- **Package registries**: npm, PyPI, crates.io, Hex, Hackage, NuGet, Maven, RubyGems, Packagist, pub.dev, Go packages -- **Security databases**: NVD, OSV, CISA KEV vulnerability data -- HTML-to-markdown conversion with link preservation - -### + SSH Tool - -Remote command execution with persistent connections: - -- **Project discovery**: Reads SSH hosts from `ssh.json` / `.ssh.json` in your project -- **Host management**: Add, remove, and list hosts via `omp ssh` CLI or `/ssh` slash command -- **Persistent connections**: Reuses SSH connections across commands for faster execution; OpenSSH `%C` ControlMaster sockets so different user/port/jump-host combos don't share a master -- **OS/shell detection**: Automatically detects remote OS and shell type -- **SSHFS mounts**: Optional automatic mounting of remote directories -- **Compat mode**: Windows host support with automatic shell probing; native Windows callers skip multiplexing (Win32-OpenSSH does not support it) - -### + Browser Tool (Puppeteer with Stealth) - -Headless browser automation with 14 stealth scripts to evade bot detection: - -- **`open` / `run` / `close` flow**: Named tabs survive across `run` calls and across subagents; `run` executes async JavaScript with `page`, `browser`, `tab`, `display`, `assert`, `wait` in scope -- **Shared runtime with `eval`**: Tab JS exposes the same helper globals (`read`, `write`, `display`, `tool.<name>`) and supports top-level `await` plus static ESM imports rewritten against the session cwd -- **Tab helpers**: `tab.observe()` accessibility snapshot with stable element ids, `tab.id(n)`, `tab.click`, `tab.fill`, `tab.type`, `tab.select`, `tab.uploadFile`, `tab.drag`, `tab.scrollIntoView`, `tab.waitForUrl`, `tab.waitForResponse`, `tab.evaluate`, `tab.screenshot`, `tab.extract` -- **Drive Electron desktop apps**: Same tool, same selectors — point it at any CDP-enabled Electron binary and the agent can click buttons, fill forms, run JS in the renderer, screenshot, and observe the accessibility tree. `app.path: "/Applications/Cursor.app/Contents/MacOS/Cursor"` spawns (or reuses) the app with `--remote-debugging-port`; `app.cdp_url: "http://127.0.0.1:9222"` attaches to an already-running instance; `app.target: "Settings"` substring-matches a `BrowserWindow` title/URL when the app exposes several. Used in practice to debug VS Code, Cursor, Slack, Discord, Spotify, and any Electron / NW.js / CEF wrapper that exposes CDP -- **14 stealth plugins**: toString tampering, WebGL fingerprinting, audio context, screen dimensions, font enumeration, plugin/mime-type mocking, hardware concurrency, codec availability, iframe detection, locale spoofing, worker detection, and more -- **User agent spoofing**: Removes `HeadlessChrome`, generates proper Client Hints brand lists, applies overrides via CDP Network and Emulation domains -- **Selector flexibility**: CSS, `aria/`, `text/`, `xpath/`, `pierce/` query handlers for Shadow DOM piercing -- **Reader mode**: `tab.extract()` uses Mozilla Readability for clean article extraction -- **Headless/visible toggle**: Switch modes at runtime via `/browser` command or `browser.headless` setting -- **One-command Chromium fetch**: the browser tool auto-downloads a known-good Chromium on first use; prebuilt binaries embed the tab worker entry via `with { type: "file" }` so single-file binaries no longer fail with `Timed out initializing browser tab worker` -- **NixOS support**: Automatically detects NixOS (`/etc/NIXOS`) and resolves a system Chromium since Puppeteer's bundled binary cannot run on a non-FHS system - -### + Cursor Provider - -Use your Cursor Pro subscription for AI completions: - -- **Browser-based OAuth**: Authenticate through Cursor's OAuth flow -- **Tool execution bridge**: Maps Cursor's native tools to omp equivalents (read, write, shell, diagnostics) -- **Conversation caching**: Persists context across requests in the same session -- **Shell streaming**: Real-time stdout/stderr during command execution - -### + Multi-Credential Support - -Distribute load across multiple API keys: - -- **Round-robin distribution**: Automatically cycles through credentials per session -- **Usage-aware selection**: For OpenAI Codex, checks account limits before credential selection -- **Automatic fallback**: Switches credentials mid-session when rate limits are hit -- **Consistent hashing**: `Bun.hash.xxHash32` over the session id ensures stable credential assignment per session -- **Disable events**: Extensions can subscribe to `credential_disabled` to react when an OAuth token is soft-disabled (e.g. `invalid_grant`) without regex-matching error messages - -### + Image Generation - -Create images directly from the agent: - -- **Gemini integration**: Uses `gemini-3-pro-image-preview` by default -- **OpenRouter fallback**: Automatically uses OpenRouter when `OPENROUTER_API_KEY` is set -- **Inline display**: Images render in terminals supporting Kitty/iTerm2 graphics -- Saves to temp files and reports paths for further manipulation - -### + TUI Overhaul - -Modern terminal interface with smart session management: - -- **Auto session titles**: Sessions automatically titled based on first message using commit model, fallback to smol -- **Welcome screen**: Logo, tips, recent sessions with selection -- **Powerline footer**: Model, cwd, git branch/status, token usage, context % -- **LSP status**: Shows which language servers are active and ready -- **Hotkeys**: `?` displays shortcuts when editor empty -- **Persistent prompt history**: SQLite-backed with `Ctrl+R` search across sessions; substring fallback for FTS5-missed infix queries -- **Grouped tool display**: Consecutive Read calls shown in compact tree view -- **Streaming text preview**: Real-time delta updates during agent output -- **`/context` panel**: Estimated context-usage breakdown for the active session -- **Overlay UI**: Custom hooks can display components as bottom-centered overlays -- **Configurable tab width**: `display.tabWidth` setting with `.editorconfig` integration -- **Ctrl+D draft persistence**: Pressing Ctrl+D with editor text saves it as a per-session draft; resuming the session restores it -- **Scrollback preservation**: Uses home+erase-below instead of clear-screen -- **Emergency terminal restore**: Crash handlers prevent terminal corruption -- **Power assertions**: macOS `power.preventIdleSleep` / `preventSystemSleep` / `declareUserActive` / `preventDisplaySleep` settings keep the machine awake only while a prompt is in flight - -### + Hashline Edits (v3) - -Hashline gives every line a short content-hash anchor. The model references anchors instead of reproducing text — no whitespace reproduction, no "string not found", no ambiguous matches. If the file changed since the last read, hashes won't match and the edit is rejected before anything gets corrupted. - -Hashline v3 adds: - -- **Atom mode**: Compact patch language with `+`/`-`/`=`/`<` ops, range-delete (`-LidA..LidB`), range-replace (`LidA..LidB=TEXT`), and continuation lines (`\TEXT` / `\`) for multi-line replacements -- **`splice_block`**: Bracketed `(anchor)`, `[anchor]`, `[anchor`, `anchor]` locators target whole nodes or block bodies with auto-inferred delimiters (`{` for C-family, `(` for Lisp-family) -- **Structural ordinals**: Anchor a single repeated symbol on a line via ordinal disambiguation -- **Multiline sed**: `sed` as an object (`{pat, rep, g?, i?}`) with sequential chaining when multiple `sed` ops target the same anchor; global by default -- **Stale-anchor recovery**: When anchors no longer match, edits replay against a session-scoped read/search snapshot and 3-way-merge onto the current file; success output flags when recovery was used -- **Brace-shape heuristics**: Auto-absorb of duplicated structural-closing lines (`}`, `);`, `]`) when keeping them would unbalance brackets; warnings when `@Lid` lands on an opener at sibling indent (likely off-by-one foot-gun) -- **Inline syntax**: `< ANCHOR>TEXT` and `+ ANCHOR>TEXT` (separator configurable via `PI_HL_SEP`, default `>`) for one-line prepends/appends without a payload block -- **`\*** Abort` recovery marker\*\*: Stream corruption mid-patch aborts safely instead of applying partial edits - -Benchmarked across 16 models, 180 tasks, 3 runs each: - -- **Grok Code Fast 1**: 6.7% → 68.3% — a _tenfold_ improvement hidden behind mechanical patch failures -- **Gemini 3 Flash**: +5pp over `str_replace`, beating Google's own best attempt -- **Grok 4 Fast**: 61% fewer output tokens — stopped burning context on retry loops -- **MiniMax**: more than doubled success rate -- Matches or beats `str_replace` for nearly every model tested; weakest models gain the most - -### + Native Engine (Rust N-API) - -~27,000 lines of Rust across three crates (`pi-natives`, `pi-shell`, `pi-ast`) compiled to a platform-tagged N-API addon, providing performance-critical operations without shelling out to external commands: - -| Module | Lines | What it does | Powered by | -| -------------- | -----: | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | -| **grep** | ~1,900 | Regex search over files and in-memory content, parallel/sequential modes, glob/type filtering, context lines, fuzzy find for autocomplete | `grep-regex`, `grep-searcher`, `grep-matcher` (ripgrep internals) | -| **shell** | ~3,700 | Embedded bash execution with persistent sessions, streaming output, timeout/abort, custom builtins, command minimizer (`pi-shell` crate) | [brush-shell](https://github.com/reubeno/brush) (vendored) | -| **text** | ~1,450 | ANSI-aware visible width, truncation with ellipsis, column slicing, text wrapping that preserves SGR codes across line breaks — all UTF-16 optimized | `unicode-width`, `unicode-segmentation` | -| **keys** | ~1,490 | Kitty keyboard protocol parser with legacy xterm/VT100 fallback, modifier support, PHF perfect-hash lookup | `phf` | -| **summarize** | ~1,040 | Tree-sitter structural source summaries with configurable body / comment elision; backs `read`'s default code summary output (`pi-ast` crate) | `tree-sitter`, `ast-grep-core` | -| **ast** | ~1,000 | ast-grep pattern matching and structural rewrites driving the `ast_edit` / `ast_grep` tools | `ast-grep-core` | -| **fs_cache** | ~840 | Mtime-keyed file cache shared by read/grep/lsp so repeated reads of the same file are zero-IO | — | -| **highlight** | ~470 | Syntax highlighting with 11 semantic color categories, 30+ language aliases | `syntect` | -| **pty** | ~455 | Native PTY allocation for `bash` `pty: true` (sudo, ssh interactive prompts) | `portable-pty` | -| **workspace** | ~385 | Workspace tree walker with gitignore + AGENTS.md discovery in one pass | `ignore`, `git2` | -| **glob** | ~410 | Filesystem discovery with glob patterns, type filtering, mtime sorting, `.gitignore` respect | `ignore`, `globset` (ripgrep internals) | -| **appearance** | ~270 | Mode 2031 detection + native macOS dark/light appearance via CoreFoundation FFI | `core-foundation` | -| **power** | ~270 | macOS power-assertion API for idle/system/display-sleep prevention during in-flight prompts | `IOKit` FFI | -| **task** | ~260 | Blocking work scheduler on libuv thread pool, cooperative/external cancellation, timeout, profiling hooks | `tokio`, `napi` | -| **iso** | ~245 | ISO 8601 / RFC 3339 datetime parsing and formatting | `time` | -| **prof** | ~240 | Always-on circular buffer profiler with folded-stack output and optional SVG flamegraph generation | `inferno` | -| **fd** | ~250 | Filesystem walker for `find`-tool replacement | `ignore` | -| **ps** | ~195 | Cross-platform process tree kill and descendant listing — `/proc` on Linux, `libproc` on macOS, `CreateToolhelp32Snapshot` on Windows | `libc` | -| **image** | ~190 | Decode/encode PNG/JPEG/WebP/GIF, resize with 5 sampling filters | `image` | -| **clipboard** | ~80 | Text copy and image read from system clipboard — no `xclip`/`pbcopy` needed | `arboard` | -| **tokens** | ~65 | O200k / Cl100k BPE token counting for context budgets; both tables embedded | `tiktoken-rs` | -| **html** | ~50 | HTML-to-Markdown conversion with optional content cleaning | `html-to-markdown-rs` | - -Supported platforms: `linux-x64`, `linux-arm64`, `darwin-x64`, `darwin-arm64`, `win32-x64`. - -### ... and many more - -- **`omp acp` subcommand**: Run as an Agent Client Protocol server over stdio -- **`omp config` subcommand**: Manage settings from CLI (`list`, `get`, `set`, `reset`, `path`) -- **`omp setup` subcommand**: Install optional dependencies (`omp setup python`, `omp setup stt`) -- **`omp stats` subcommand**: Local observability dashboard for AI usage (requests, cost, cache rate, tokens/s) with input/output token totals -- **`omp jupyter` was removed**: the Python `eval` backend now runs as a subprocess (no Jupyter dependency) -- **`xhigh` thinking level**: Extended reasoning for Anthropic models with increased token budgets -- **Hide-thinking toggle**: `Ctrl+T` instructs the provider to omit reasoning summaries entirely, not just hide them client-side -- **Background mode**: `/background` detaches UI and continues agent execution -- **Completion notifications**: Configurable bell/OSC99/OSC9 when agent finishes -- **65+ built-in themes**: Catppuccin, Dracula, Nord, Gruvbox, Tokyo Night, Poimandres, and material variants -- **Automatic dark/light switching**: Mode 2031 terminal detection, native macOS appearance via CoreFoundation FFI, COLORFGBG fallback -- **Auto environment detection**: OS, distro, kernel, CPU, GPU, shell, terminal, DE in system prompt -- **Git context**: System prompt includes branch, status, recent commits -- **Workspace tree in system prompt**: Recency-sorted depth-≤3 tree of recent files / directories with truncation notices -- **AGENTS.md context discovery**: gitignore-aware walk that surfaces directory-scoped AGENTS.md and forwards results to subagents (no redundant rescans on spawn) -- **Bun runtime**: Native TypeScript execution, faster startup, all packages migrated -- **Centralized file logging**: Debug logs with daily rotation to `~/.omp/logs/` -- **Bash interceptor**: Optionally block shell commands that have dedicated tools — checks the original command before `cd …&&` normalization -- **Per-command PTY control**: `bash` tool supports `pty: true` for commands requiring a real terminal (sudo, ssh) -- **@file auto-read**: Type `@path/to/file` in prompts to inject file contents inline -- **AST tools**: `ast_grep` and `ast_edit` for syntax-aware code search and codemods via ast-grep -- **Plan mode**: approval surface offers three outcomes — execute (purge), keep full transcript, or compact context (re-anchors plan on a fresh cache breakpoint). Completion routes through the existing `resolve` tool with `action: "apply"` and an `extra: { title }` payload -- **`/btw` ephemeral turns**: One-shot model query that doesn't pollute the session transcript -- **Sampling controls**: `topP`, `topK`, `minP`, `presencePenalty`, `repetitionPenalty` settings for fine-grained model tuning - ---- - -## Installation - -### Via Bun (recommended) - -Requires [Bun](https://bun.sh) **>= 1.3.14**: - -```bash +```sh bun install -g @oh-my-pi/pi-coding-agent ``` -### Via installer script - -**Linux / macOS:** - -```bash -curl -fsSL https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.sh | sh -``` - -**Windows (PowerShell):** +**Windows (PowerShell)** ```powershell -irm https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.ps1 | iex +irm https://omp.sh/install.ps1 | iex ``` -By default, the installer uses Bun when available (and compatible), otherwise installs the prebuilt binary. +**Pinned versions (mise)** -Options: - -- POSIX (`install.sh`): `--source`, `--binary`, `--ref <ref>`, `-r <ref>` -- PowerShell (`install.ps1`): `-Source`, `-Binary`, `-Ref <ref>` -- `--ref`/`-Ref` with binary mode must reference a release tag; branch/commit refs require source mode - -Set custom install directory with `PI_INSTALL_DIR`. - -Examples: - -```bash -# Source install (Bun) -curl -fsSL https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.sh | sh -s -- --source - -# Install release tag via binary -curl -fsSL https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.sh | sh -s -- --binary --ref v15.0.0 - -# Install branch/commit via source -curl -fsSL https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.sh | sh -s -- --source --ref main -``` - -```powershell -# Install release tag via binary -& ([scriptblock]::Create((irm https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.ps1))) -Binary -Ref v15.0.0 -# Install branch/commit via source -& ([scriptblock]::Create((irm https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.ps1))) -Source -Ref main -``` - -### Via [mise](https://mise.jdx.dev) - -```bash +```sh mise use -g github:can1357/oh-my-pi ``` -### Manual download - -Download binaries directly from [GitHub Releases](https://github.com/can1357/oh-my-pi/releases/latest). - ---- - -## Getting Started - -### Terminal Setup - -Pi uses the [Kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/) for reliable modifier key detection. Most modern terminals support this protocol, but some require configuration. - -**Kitty, iTerm2:** Work out of the box. - -**Ghostty:** Add to your Ghostty config (`~/.config/ghostty/config`): - -``` -keybind = alt+backspace=text:\x1b\x7f -keybind = shift+enter=text:\n -``` - -**wezterm:** Create `~/.wezterm.lua`: - -```lua -local wezterm = require 'wezterm' -local config = wezterm.config_builder() -config.enable_kitty_keyboard = true -return config -``` - -**Windows Terminal:** Does not support the Kitty keyboard protocol. Shift+Enter cannot be distinguished from Enter. Use Ctrl+Enter for multi-line input instead. All other keybindings work correctly. - -### API Keys & OAuth - -**Option 1: Environment variables** (common examples) - -| Provider | Environment Variable | -| ----------------------------------------------- | -------------------------------------------- | -| Anthropic | `ANTHROPIC_API_KEY` | -| OpenAI | `OPENAI_API_KEY` | -| Google | `GEMINI_API_KEY` | -| Mistral | `MISTRAL_API_KEY` | -| Groq | `GROQ_API_KEY` | -| Cerebras | `CEREBRAS_API_KEY` | -| Fireworks (`fireworks`) | `FIREWORKS_API_KEY` | -| Hugging Face (`huggingface`) | `HUGGINGFACE_HUB_TOKEN` or `HF_TOKEN` | -| Synthetic | `SYNTHETIC_API_KEY` | -| NVIDIA (`nvidia`) | `NVIDIA_API_KEY` | -| NanoGPT (`nanogpt`) | `NANO_GPT_API_KEY` | -| Together (`together`) | `TOGETHER_API_KEY` | -| Ollama (`ollama`) | `OLLAMA_API_KEY` _(optional)_ | -| Ollama Cloud (`ollama-cloud`) | `OLLAMA_CLOUD_API_KEY` | -| LiteLLM (`litellm`) | `LITELLM_API_KEY` | -| LM Studio (`lm-studio`) | `LM_STUDIO_API_KEY` _(optional)_ | -| llama.cpp (`llama.cpp`) | `LLAMA_CPP_API_KEY` _(optional)_ | -| Xiaomi MiMo (`xiaomi`) | `XIAOMI_API_KEY` | -| Moonshot (`moonshot`) | `MOONSHOT_API_KEY` | -| Venice (`venice`) | `VENICE_API_KEY` | -| Kilo Gateway (`kilo`) | `KILO_API_KEY` | -| GitLab Duo (`gitlab-duo`) | `GITLAB_TOKEN` _(or OAuth)_ | -| Cursor (`cursor`) | _OAuth only_ | -| Antigravity (`google-antigravity`) | _OAuth only_ | -| Jina (`jina`, web search) | `JINA_API_KEY` | -| Kagi (`kagi`, web search) | `KAGI_API_KEY` | -| Tavily (`tavily`, web search) | `TAVILY_API_KEY` | -| Parallel (`parallel`, web search) | `PARALLEL_API_KEY` | -| Perplexity | `PERPLEXITY_API_KEY` or `PERPLEXITY_COOKIES` | -| xAI | `XAI_API_KEY` | -| OpenRouter | `OPENROUTER_API_KEY` | -| OpenCode Go (`opencode-go`) | `OPENCODE_API_KEY` | -| OpenCode Zen (`opencode-zen`) | `OPENCODE_API_KEY` | -| Z.AI | `ZAI_API_KEY` | -| ZenMux (`zenmux`) | `ZENMUX_API_KEY` | -| MiniMax Coding Plan (`minimax-code`) | `MINIMAX_CODE_API_KEY` | -| MiniMax Coding Plan CN (`minimax-code-cn`) | `MINIMAX_CODE_CN_API_KEY` | -| Alibaba Coding Plan (`alibaba-coding-plan`) | `ALIBABA_CODING_PLAN_API_KEY` | -| Qwen Portal (`qwen-portal`) | `QWEN_OAUTH_TOKEN` or `QWEN_PORTAL_API_KEY` | -| vLLM (`vllm`) | `VLLM_API_KEY` | -| Cloudflare AI Gateway (`cloudflare-ai-gateway`) | `CLOUDFLARE_AI_GATEWAY_API_KEY` | -| Vercel AI Gateway (`vercel-ai-gateway`) | `AI_GATEWAY_API_KEY` | -| Qianfan (`qianfan`) | `QIANFAN_API_KEY` | - -See [Environment Variables](docs/environment-variables.md) for the full list. - -**Option 2: `/login` (interactive auth / API key setup)** - -Use `/login` with supported providers (alphabetical): - -- Alibaba Coding Plan (`alibaba-coding-plan`) -- Anthropic (Claude Pro/Max) -- Antigravity (`google-antigravity`, Gemini 3 / Claude / GPT-OSS) -- Cerebras (`cerebras`) -- ChatGPT Plus/Pro (Codex, `openai-codex`) -- Cloudflare AI Gateway (`cloudflare-ai-gateway`) -- Cursor (`cursor`) -- Fireworks (`fireworks`) -- GitHub Copilot (`github-copilot`) -- GitLab Duo (`gitlab-duo`) -- Google Cloud Code Assist (Gemini CLI, `google-gemini-cli`) -- Hugging Face Inference (`huggingface`) -- Kagi (`kagi`) -- Kilo Gateway (`kilo`) -- Kimi Code (`kimi-code`) -- LiteLLM (`litellm`) -- LM Studio (local / self-hosted, `lm-studio`) -- llama.cpp (local / self-hosted, `llama.cpp`) -- MiniMax Coding Plan (International, `minimax-code`) -- MiniMax Coding Plan (China, `minimax-code-cn`) -- Moonshot (Kimi API, `moonshot`) -- NanoGPT (`nanogpt`) -- NVIDIA (`nvidia`) -- Ollama (local / self-hosted, `ollama`) -- Ollama Cloud (`ollama-cloud`) -- OpenCode Go (`opencode-go`) -- OpenCode Zen (`opencode-zen`) -- Parallel (`parallel`, web search) -- Perplexity -- Qianfan (`qianfan`) -- Qwen Portal (`qwen-portal`) -- Synthetic -- Tavily (`tavily`, web search) -- Together (`together`) -- Venice (`venice`) -- Vercel AI Gateway (`vercel-ai-gateway`) -- vLLM (local OpenAI-compatible, `vllm`) -- Xiaomi MiMo (`xiaomi`) -- Z.AI (GLM Coding Plan) -- ZenMux (`zenmux`) - -**Provider-specific login notes:** - -- **`ollama`** — API key optional. Leave unset for local no-auth instances; set `OLLAMA_API_KEY` for authenticated hosts. -- **`llama.cpp`** — API key optional. Leave unset for local no-auth instances; set `LLAMA_CPP_API_KEY` for authenticated hosts. -- **`lm-studio`** — API key optional. Leave unset for local no-auth instances; set `LM_STUDIO_API_KEY` for authenticated hosts. -- **`vllm`** — paste your key in `/login` (or use `VLLM_API_KEY`). For local no-auth servers, any placeholder value works (for example `vllm-local`). -- **`nanogpt`** — `/login nanogpt` opens `https://nano-gpt.com/api` and prompts for your `sk-...` key (or set `NANO_GPT_API_KEY`). Validates the key via NanoGPT's models endpoint, not a fixed model entitlement. -- **`cloudflare-ai-gateway`** — set the provider base URL to `https://gateway.ai.cloudflare.com/v1/<account_id>/<gateway_id>/anthropic` (for example in `~/.omp/agent/models.yml`). - -```bash -omp -/login -``` - -**Credential behavior:** - -- `/login` appends credentials for the provider (it does not wipe existing entries) -- `/logout` clears saved credentials for the selected provider -- Credentials are stored in `~/.omp/agent/agent.db` -- For the same provider, saved API key credentials are selected before OAuth credentials - -### First 15 Minutes (Recommended) - -This is the practical onboarding flow for new users. - -#### 1) Set up providers - -- **API keys** (fastest): export `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY`, etc. -- **OAuth subscriptions**: run `/login` and authenticate with your provider account - -#### 2) Configure model roles via `/model` - -Use `/model` in the TUI and assign role models: - -- `default` → normal implementation work -- `smol` → fast/cheap exploration and lightweight tasks -- `slow` → deep reasoning for complex debugging/refactors -- `plan` → model used while plan mode is active (`/plan`) -- `commit` → model used by commit/changelog workflows - -This setup is interactive and persisted for you. - -#### 3) Use `/plan` before making large changes - -`/plan` toggles plan mode. Use it when you want architecture and execution sequencing before edits. - -Typical flow: - -1. Run `/plan` -2. Ask for a concrete implementation plan -3. Refine the plan -4. Approve and execute - -#### 4) Review context via `/extensions` - -If context usage is unexpectedly high, inspect discovered external provider assets (rules/prompts/context/hooks/extensions). - -Run `/extensions` and: - -- Browse provider tabs (`Tab` / `Shift+Tab`) -- Inspect each item source (`via <provider>` + file path) -- Disable full providers or specific items you don't want (`Space`) - -#### 5) Manage subagents via `/agents` - -Open the Agent Control Center to inspect, configure, and toggle subagents (the `task` tool's dispatch targets). - -Run `/agents` and: - -- Browse discovered agents (built-in, project, user, and marketplace-installed) -- Inspect each agent's source file, model, tools, and system prompt -- Enable/disable agents per project, or scope-toggle to user/project -- Open the underlying agent definition for editing - ---- - ---- - -## Usage - -### Slash Commands - -These are **in-chat slash commands** (not CLI subcommands). - -| Command | Description | -| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `/settings` | Open settings menu | -| `/plan [prompt]` | Toggle plan mode | -| `/model` (`/models`) | Open model selector | -| `/fast [on\|off\|status]` | Toggle OpenAI service-tier fast mode | -| `/loop [count\|duration]` | Toggle loop mode (re-submits next prompt after each yield) | -| `/export [path]` | Export session to HTML | -| `/dump` | Copy session transcript to clipboard | -| `/share` | Upload session as a secret GitHub gist | -| `/copy [last\|code\|all\|cmd]` | Copy last agent message / code block(s) / last bash or python command | -| `/todo <subcommand>` | View/edit todo list (`edit`, `copy`, `export`, `import`, `append`, `start`, `done`, `drop`, `rm`) | -| `/session [info\|delete]` | Show session info or delete the current session | -| `/usage` | Show provider usage and limits | -| `/jobs` | Show async background jobs status | -| `/changelog [full]` | Show changelog entries | -| `/hotkeys` | Show keyboard shortcuts | -| `/tools` | Show tools currently visible to the agent | -| `/context` | Show estimated context usage breakdown | -| `/extensions` (`/status`) | Open Extension Control Center dashboard | -| `/agents` | Open Agent Control Center dashboard | -| `/tree` | Navigate session tree (switch branches) | -| `/branch` | Branch from a previous message (tree or message selector) | -| `/fork` | Fork from a previous message into a new session | -| `/resume` | Open session picker | -| `/new` | Start a new session | -| `/drop` | Delete current session and start a new one | -| `/compact [focus]` | Manually compact session context | -| `/handoff [focus]` | Hand off context to a new session | -| `/btw <question>` | Ephemeral side question using the current context | -| `/retry` | Retry the last failed agent turn | -| `/rename <title>` | Rename the current session | -| `/move <path>` | Move session to a different working directory | -| `/background` (`/bg`) | Detach UI and continue running in background | -| `/browser [headless\|visible]` | Toggle browser headless/visible mode | -| `/mcp <subcommand>` | Manage MCP servers (`add`, `list`, `remove`, `test`, `reauth`, `unauth`, `enable`, `disable`, `smithery-search`, `smithery-login`, `smithery-logout`, `reconnect`, `reload`, `resources`, `prompts`, `notifications`) | -| `/ssh <subcommand>` | Manage SSH hosts (`add`, `list`, `remove`) | -| `/memory <subcommand>` | Inspect/clear/rebuild memory (`view`, `clear`/`reset`, `enqueue`/`rebuild`, `mm list\|show\|refresh\|history\|seed\|delete\|reload`) | -| `/marketplace <subcommand>` | Manage marketplace sources and plugins (`add`, `remove`, `update`, `list`, `discover`, `install`, `uninstall`, `installed`, `upgrade`) | -| `/plugins [list\|enable\|disable]` | View and manage installed plugins (npm + marketplace) | -| `/reload-plugins` | Reload skills, commands, hooks, tools, agents, and MCP | -| `/force <tool> [prompt]` | Force the next turn to use a specific tool | -| `/debug` | Open debug tools selector | -| `/login` / `/logout` | OAuth login/logout | -| `/exit` (`/quit`) | Exit interactive mode | +macOS · Linux · Windows · bun ≥ 1.3.14 -Installed skills are dispatchable as `/skill:<name>`. Bundled custom commands include `/review` (interactive code review launcher). +## Every tool, _benchmaxxed_. -### Editor Features +Edits that land on the first attempt. Reads that summarize files instead of dumping their content. Searches that return instantly. Pick any model — omp will get it right. -**File reference (`@`):** Type `@` to fuzzy-search project files. Respects `.gitignore`. +| model | metric | what | +| ---------------- | ------------ | --------------------------------------------------------------------- | +| Grok Code Fast 1 | 6.7% → 68.3% | Tenfold lift the moment the edit format stops eating the model alive. | +| Gemini 3 Flash | +5 pp | Over str_replace — beats Google's own best attempt at the format. | +| Grok 4 Fast | −61% tokens | Output collapses once the retry loop on bad diffs disappears. | +| MiniMax | 2.1× | Pass rate more than doubles. Same weights, same prompt. | -**Path completion (Tab):** Complete relative paths, `../`, `~/`, etc. +- `read` : summarized snippets · ideal defaults · selector hit rate +- `search` : fastest in the west +- `lsp` : everything your IDE knows, the agent knows +- `prompts` : adjusted relentlessly for each model -**Drag & drop:** Drag files from your file manager into the terminal. +[Read the full post ↗](https://blog.can.ac/2026/02/12/the-harness-problem/) -**Paste images (Ctrl+V):** Paste images from the clipboard alongside drag-and-drop attachment. +## The Pi _you love_, with **batteries included**. -**Multi-line paste:** Pasted content is collapsed in preview but sent in full. +Originally built on [Mario Zechner](https://github.com/mariozechner)'s wonderful [Pi](https://github.com/badlogic/pi-mono), omp adds everything you're missing. -**Message queuing:** Submit messages while the agent is working; queue behavior is configurable in `/settings`. +### 01 · Code execution w/ tool-calling -### Keyboard Shortcuts +Most harnesses give the agent a Python sandbox and call it done. Ours runs persistent Python and a Bun worker, and either kernel can call back into the agent's own tools — read, search, task — over a loopback bridge. The agent loads a CSV with tool.read from inside Python, charts it from JavaScript, and never leaves the cell. -**Navigation:** +![omp TUI: a single eval session with `[1/2] pandas describe` (Python) printing a real DataFrame.describe() table, followed by `[2/2] top scorer` (JavaScript) running a reduce. Footer: 'Both kernels ran in one session.'](https://omp.sh/captures/eval.webp) -| Key | Action | -| ------------------------ | -------------------------------------------- | -| Arrow keys | Move cursor / browse history (Up when empty) | -| Option+Left/Right | Move by word | -| Ctrl+A / Home / Cmd+Left | Start of line | -| Ctrl+E / End / Cmd+Right | End of line | +### 02 · LSP wired into every write -**Editing:** +Ask for a rename and you get a rename. The call goes through workspace/willRenameFiles, so re-exports, barrel files, and aliased imports update before the file moves. Everything your IDE knows, the agent knows. -| Key | Action | -| ------------------------- | ----------------------- | -| Enter | Send message | -| Shift+Enter / Alt+Enter | New line | -| Ctrl+W / Option+Backspace | Delete word backwards | -| Ctrl+U | Delete to start of line | -| Ctrl+K | Delete to end of line | +![omp TUI: `LSP references` returns five hits across three files for the symbol `formatBytes`, then `LSP rename` applies the change with edits to format.ts/report.ts/cli.ts, then a `Search formatBytes 0 matches` confirmation. Final line: 'Rename complete. Five edits across three files…'.](https://omp.sh/captures/lsp.webp) -**Other:** +### 03 · Drives a real debugger -| Key | Action | -| --------------------- | ----------------------------------------------------------- | -| Tab | Path completion / accept autocomplete | -| Escape | Cancel autocomplete / abort streaming | -| Ctrl+C | Clear editor (first) / exit (second) | -| Ctrl+D | Exit (when editor is empty) | -| Ctrl+Z | Suspend to background (use `fg` in shell to resume) | -| Shift+Tab | Cycle thinking level | -| Ctrl+P / Shift+Ctrl+P | Cycle role models (slow/default/smol), temporary on shift | -| Alt+P | Select model temporarily | -| Ctrl+L | Open model selector | -| Alt+Shift+P | Toggle plan mode | -| Ctrl+R | Search prompt history | -| Ctrl+O | Toggle tool output expansion | -| Ctrl+T | Toggle thinking mode (hide reasoning summaries server-side) | -| Ctrl+G | Edit message in external editor (`$VISUAL` or `$EDITOR`) | -| Alt+H | Toggle speech-to-text recording | +A C binary segfaults: the agent attaches lldb, steps to the bad pointer, reads the frame. A Go service hangs: it attaches dlv and walks the goroutines. A Python process is wedged: debugpy, pause, inspect, evaluate. Most agents are still sprinkling print statements. -### Bash Mode +![omp TUI: a live lldb-dap session against a native binary at /tmp/omp-native/demo. Adapter=lldb-dap, Status=stopped, Frame=xorshift32, Instruction pointer 0x10000055C, Location demo.c:6:10. Debug scopes and Debug variables cards show locals (x = 57351) and the agent confirms the math: x went from 7 → 57351 (= 7 ^ (7<<13)).](https://omp.sh/clips/dap-poster.webp) -Prefix commands with `!` to execute them and include output in context: +_[Watch the capture ↗](https://omp.sh/clips/dap.mp4)_ -```bash -!git status -!ls -la -``` +### 04 · Time-traveling stream rules -Use `!!` to execute but **exclude output from LLM context**: +Your rules sit dormant until the model goes off-script. A regex match aborts the stream mid-token, injects the rule as a system reminder, and retries from the same point. You get course-correction without paying context tax on every turn. Injections survive compaction, so the fix sticks. -```bash -!!git status -``` +![omp TUI: agent reading src.rs and about to write Box::leak when the request aborts (red `Error: Request was aborted`), an amber `⚠ Injecting rule: box-leak` card injects the rule body `Don't reach for Box::leak in production code paths`, and the agent then course-corrects by proposing `Arc<str>` and asking the user to confirm.](https://omp.sh/clips/ttsr-poster.webp) -Output streams in real-time. Press Escape to cancel. +_[Watch the capture ↗](https://omp.sh/clips/ttsr.mp4)_ -### Image Support +### 05 · First-class subagents -**Attach images by reference:** +Split a job across workers and get typed results back. task fans out into isolated worktrees, each worker runs its own tool surface, and the final yield is a schema-validated object the parent reads directly. No prose to parse, no merge conflicts between siblings, no orphaned edits. -```text -What's in @/path/to/image.png? -``` +![omp TUI showing `task` spawning two subagents `ComponentsExports` and `RoutesExports`, the constraints block requiring an IRC DM between peers, the per-subagent status cards with cost and duration, and a final Findings section listing both exports plus an honest 'IRC coordination note' about a one-sided handshake.](https://omp.sh/clips/irc-poster.webp) -Or paste/drop images directly (`Ctrl+V` or drag-and-drop). +_[Watch the capture ↗](https://omp.sh/clips/irc.mp4)_ -Supported formats: `.jpg`, `.jpeg`, `.png`, `.gif`, `.webp` +### 06 · Read a pdf on arxiv, why not? -Toggle inline images via `/settings` or set `terminal.showImages: false`. +web_search chains fourteen ranked providers and hands whatever URLs it finds straight to read. Arxiv PDFs, GitHub pages, Stack Overflow threads come back as structured markdown with anchors intact — the same tool surface you use on local files. Cite, follow, quote, never lose where you came from. ---- +![omp TUI: web_search returns 10 ranked Perplexity sources for inference-time compute scaling, the agent picks an arxiv paper, calls read https://arxiv.org/pdf/2604.10739v1, and summarizes the paper's headline result with real numbers.](https://omp.sh/clips/web-poster.webp) -## Sessions +_[Watch the capture ↗](https://omp.sh/clips/web.mp4)_ -Sessions are stored as JSONL with a tree structure for branching and replay. +### 07 · Unapologetically native. Even on Windows. -See [docs/session.md](docs/session.md) for the file format and API. +Other agents shell out to rg, grep, find, and bash. On many machines those binaries don't exist, and on the ones where they do, every call costs a fork-exec round-trip. omp links the real implementations into the process. ripgrep, glob, find: in-process. brush is the bash, with sessions that survive across calls. The same omp binary runs on macOS, Linux, and Windows — no WSL bridge. -### Session Management +### 08 · Code review with priorities and a verdict -Sessions auto-save to `~/.omp/agent/sessions/` (grouped by working directory). +Get a clear verdict on whether the change ships, with every issue ranked P0 through P3 and scored for confidence. /review spawns dedicated reviewer subagents that sweep branches, single commits, or uncommitted work in parallel. You tackle what blocks release first; nothing important hides in a wall of prose. -```bash -omp --continue # Continue most recent session -omp -c +### 09 · Hashline: edit by content hash -omp --resume # Open session picker -omp -r +Perfect edits, fewer tokens. The model points at anchors instead of retyping the lines it wants to change, so whitespace battles and string-not-found loops just stop happening. Edit a stale file and the anchors diverge — we reject the patch before it corrupts anything. Grok 4 Fast spends 61% fewer output tokens on the same work. -omp --resume <id-prefix> # Resume by session ID prefix -omp --resume <path> # Resume by explicit .jsonl path -omp --session <value> # Alias of --resume -omp --no-session # Ephemeral mode (don't save) -``` +### 10 · GitHub is just another filesystem -Session IDs are Snowflake-style hex IDs (not UUIDs). +Other harnesses bolt on gh_issue_view, gh_pr_view, gh_search — each with its own parameters the agent has to learn and you have to debug. We skipped that. read already handles paths; PRs are paths. One interface to teach the model, one surface to keep correct. -### Context Compaction +### 11 · Hindsight: memory the agent curates -Long sessions can exhaust context windows. Compaction summarizes older messages while keeping recent context. +The agent remembers your codebase between sessions. It writes facts mid-run with retain, pulls them back with recall, and compresses each session into a mental model that loads on the first turn of the next one. Project-scoped by default, so what it learns about this repo stays with this repo. -**Manual:** `/compact` or `/compact Focus on the API changes` +### 12 · ACP: editor-drivable agent -**Automatic:** Enable via `/settings`. +Run omp inside Zed and you get the same agent you drive from the terminal — reading the buffer you're actually looking at, writing through the editor's save path, spawning shells in the editor's terminal. Destructive tools pause for a permission prompt you can answer once and forget. No bridge, no plugin, no second brain to keep in sync. -- **Overflow recovery**: model returns context overflow; compact and retry. -- **Threshold maintenance**: context exceeds configured headroom after a successful turn. +### 13 · Inherits what your other tools already wrote -**Plan mode:** when approving a plan, `Approve and compact context` distills the plan-mode discussion into a summary and starts execution in the same session — a middle ground between `Approve and execute` (fresh context) and `Approve and keep context` (full history preserved). +Every other agent ships an importer and expects you to convert. omp reads the eight formats already on disk in their native shape — Cursor MDC, Cline .clinerules, Codex AGENTS.md, Copilot applyTo, and the rest. No migration script, no YAML-to-TOML port, no "supported subset" footnotes. The config your team wrote last quarter still works tonight. -**Configuration** (`~/.omp/agent/config.yml`): +### 14 · omp commit: atomic splits, validated messages -```yaml -compaction: - enabled: true - reserveTokens: 16384 - keepRecentTokens: 20000 - autoContinue: true -``` +omp reads the working tree through git-overview, git-file-diff, and git-hunk, then splits unrelated changes into atomic commits ordered by their dependencies. Cycles are rejected before anything is written. Source files score above tests, docs, and configs, so the headline commit is the one that matters. Lock files are excluded from analysis entirely. -See [docs/compaction.md](docs/compaction.md) for internals and hook integration. +### 15 · Read PRs. _Walk skills._ Pull JSON out of subagents. -### Branching +Ten internal schemes — `pr://`, `issue://`, `agent://`, `skill://`, `rule://`, and the rest — resolve transparently inside every FS-shaped tool the agent already calls. `read pr://1428` returns the same shape as `read src/foo.ts`. `search` walks a diff like a directory. `agent://<id>/findings.0.path` pulls a field out of a subagent's output by path. -**In-place navigation (`/tree`):** Navigate the session tree without creating new files. +![omp TUI reading pr://can1357/oh-my-pi/1063 and then /diff/1, showing hunk headers, added lines, and a [MODIFIED] (+12 -0) summary.](https://omp.sh/captures/pr.webp) -- Search by typing, page with ←/→ -- Filter modes (`Ctrl+O`): default → no-tools → user-only → labeled-only → all -- Press `Shift+L` to label entries as bookmarks +### 16 · Conflict resolution, made easy. -**Create new session (`/branch` / `/fork`):** Branch to a new session file from a selected previous message. +Each merge conflict becomes one URL. The agent writes `@theirs`, `@ours`, or `@base` to `conflict://N` and the file resolves cleanly. Bulk form: `conflict://*`. -### Memory +![omp TUI: ✓ Read src/session.ts (⚠ 1 conflict), then ✓ Write conflict://1 · 1 line with content @theirs, then a confirmation 'Resolved.'](https://omp.sh/clips/conflict-poster.webp) -omp ships two memory backends, selected via `memory.backend` (`off | local | hindsight`). +_[Watch the capture ↗](https://omp.sh/clips/conflict.mp4)_ -**Legacy local backend (`memory.backend: local`)** +### 17 · Preview, then accept. -The agent extracts durable knowledge from past sessions and injects a compact summary at startup. The pipeline runs in the background and never blocks the active session. Memory is isolated per project (working directory) and stored under `~/.omp/agent/memories/`. The agent can pull deeper context via `memory://root/MEMORY.md` and `memory://root/skills/<name>/SKILL.md`. +`ast_edit` returns a _(proposed)_ card with the replacement count. The change is staged. The agent calls `resolve` with a reason; the TUI turns it into an **Accept** card and the disk move happens — atomic, all or nothing. -Manage via the `/memory` slash command: +![omp TUI: ✓ AST Edit: console.log($X) (proposed) 3 replacements · 1 file, then ✓ Accept: 3 replacements in 1 file (AST Edit), followed by 'Applied 3 replacements in src/auth.ts.'](https://omp.sh/clips/codemod-poster.webp) -- `/memory view` — show current injection payload -- `/memory clear` (or `/memory reset`) — delete all memory data and artifacts -- `/memory enqueue` (or `/memory rebuild`) — force consolidation at next startup +_[Watch the capture ↗](https://omp.sh/clips/codemod.mp4)_ -> See [Memory Documentation](docs/memory.md). +## Whatever the task needs, _it's already in the box_. -**Hindsight backend (`memory.backend: hindsight`)** +32 tools live in the same namespace as `read` and `bash`. Pin the active set with `--tools read,edit,bash,…` and the rest stay hidden but indexed — `search_tool_bm25` pulls them back in mid-session when `tools.discoveryMode` says so. -Opt-in remote memory backed by [Hindsight](https://hindsight.vectorize.io) (Cloud or self-hosted). Instead of injecting a static summary, Hindsight surfaces three tools to the agent — `retain` (store durable facts), `recall` (search prior memories), and `reflect` (synthesise an answer across many memories) — and runs an auto-recall on the first turn so prior context lands before the model speaks. +**Files & search** -- **Per-session state**: each session aliases a bank; subagents reuse the parent's bank so retains/recalls persist to the same place. -- **Bank scoping**: `hindsight.scoping` selects `global` (one shared bank), `per-project` (isolated per cwd), or `per-project-tagged` (shared bank with `project:<cwd>` tags so global + project memories merge on recall). -- **Mental models**: long-running curated summaries (user preferences, project conventions) are seeded once per bank and refreshed automatically after consolidations; an `<mental_models>` block is spliced into the system prompt. -- **Maintenance**: `/memory mm list|show|refresh|history|seed|delete|reload` from the TUI; `/memory view|clear|enqueue` still apply. +- `read` — files, dirs, archives, SQLite, PDFs, notebooks, URLs, and internal `://` schemes through one path. +- `write` — create or overwrite a file, archive entry, or SQLite row. +- `edit` — hashline patches with content-hash anchors and stale-anchor recovery. +- `ast_edit` — structural rewrites previewed before apply, via ast-grep. +- `ast_grep` — structural code queries over 50+ tree-sitter grammars. +- `search` — regex over files, globs, and internal URLs. +- `find` — glob-based path lookup; reach for `search` when you need content matches. -Configure via `hindsight.apiUrl`, `hindsight.apiToken`, `hindsight.bankId`, and `hindsight.scoping` in `config.yml`. +**Runtime** ---- +- `bash` — workspace shell, with optional PTY or background-job dispatch. +- `eval` — persistent Python and JavaScript cells with shared prelude and tool re-entry. +- `recipe` — invoke a target from a detected task runner — bun, just, make, cargo. +- `ssh` — one remote command against a configured host. -## Configuration +**Code intelligence** -### Project Context Files +- `lsp` — diagnostics, navigation, symbols, renames, code actions, raw requests. +- `debug` — drive a DAP session — breakpoints, stepping, threads, stack, variables. -omp discovers project context from supported config directories (for example `.omp`, `.claude`, `.codex`, `.gemini`). +**Coordination** -Common files: +- `task` — fan out subagents in parallel, optionally workspace-isolated. +- `irc` — short prose between live agents in this process. +- `todo_write` — ordered mutations over the session todo list with phase tracking. +- `job` — wait on or cancel background jobs. +- `ask` — structured follow-up questions for interactive runs. -- `AGENTS.md` -- `CLAUDE.md` +**Outside the box** -Use these for: +- `browser` — Puppeteer tabs over headless Chromium or CDP-attached apps. +- `web_search` — one query across configured providers, returning answer plus citations. +- `github` — GitHub CLI ops — repo, PR, issues, code search, Actions run-watch. +- `generate_image` — generate or edit raster images via Gemini image models. +- `inspect_image` — vision-model analysis of a local image file. +- `render_mermaid` — Mermaid source to terminal-friendly ASCII or PNG. -- Project instructions and guardrails -- Common commands and workflows -- Architecture documentation -- Coding/testing conventions +**Memory & state** -### Custom System Prompt +- `checkpoint` — mark conversation state for a later collapse-and-report. +- `rewind` — prune exploratory context, keep a concise report. +- `retain` — queue durable facts into the active Hindsight bank. +- `recall` — search the Hindsight bank for raw memories. +- `reflect` — ask Hindsight to synthesize an answer over the bank. -Replace the default system prompt by creating `SYSTEM.md`: +**Misc** -1. **Project-local:** `.omp/SYSTEM.md` (takes precedence) -2. **Global:** `~/.omp/agent/SYSTEM.md` (fallback) +- `calc` — deterministic arithmetic — no model in the loop. +- `resolve` — apply or discard a queued preview action. +- `search_tool_bm25` — BM25 over the hidden tool index; activates top matches mid-session. -`--system-prompt` overrides both files. Use `--append-system-prompt` to append additional instructions. +Setting-gated, off by default: `github`, `calc`, `inspect_image`, `render_mermaid`, `checkpoint`, `rewind`, `search_tool_bm25`, `retain`, `recall`, `reflect`. Flip them on once, scoped per project. -### Custom Models and Providers +[Full reference →](https://omp.sh/docs/tools) -Add custom providers/models via `~/.omp/agent/models.yml`. +## Forty-plus providers, hundreds of models, _one /model away_. -`models.json` is still supported for legacy configs, but `models.yml` is the modern format. +Roles route work by intent. `default` for normal turns. `smol` for cheap subagent fan-out. `slow` for deep reasoning. `plan` for plan mode. `commit` for changelogs. Override at launch with `--smol`, `--slow`, or `--plan`; cycle through the configured models for the active role with `Ctrl+P`. Swap the active model mid-session with the `/model` slash command. -> See [models.yml provider integration guide](docs/models.md) for schema and merge behavior. +Auth tags below: `oauth` signs in with your provider account, `plan` routes through a coding-plan subscription, `local` runs against a local server with the key optional. -```yaml -providers: - ollama: - baseUrl: http://localhost:11434/v1 - apiKey: OLLAMA_API_KEY - api: openai-completions - models: - - id: llama-3.1-8b - name: Llama 3.1 8B (Local) - reasoning: false - input: [text] - cost: - input: 0 - output: 0 - cacheRead: 0 - cacheWrite: 0 - contextWindow: 128000 - maxTokens: 32000 +### Frontier APIs - llama.cpp: - baseUrl: http://127.0.0.1:8080 - api: openai-responses - auth: none - discovery: - type: llama.cpp +Direct APIs and gateways. Mix providers per role. -equivalence: - overrides: - zenmux/codex: gpt-5.3-codex - p-codex/codex: gpt-5.3-codex - exclude: - - demo/codex-preview -``` +Anthropic `oauth` · OpenAI · OpenAI Codex `oauth` · Google Gemini · Google Antigravity `oauth` · xAI · Mistral · Groq · Cerebras · Fireworks · Together · Hugging Face · NVIDIA · OpenRouter · Synthetic · Vercel AI Gateway · Cloudflare AI Gateway · Perplexity `oauth` -**Supported APIs:** `openai-completions`, `openai-responses`, `openai-codex-responses`, `azure-openai-responses`, `anthropic-messages`, `google-generative-ai`, `google-vertex` +### Coding plans -Canonical ids are official upstream model ids such as `claude-sonnet-4-6` or `gpt-5.3-codex`. Use `equivalence.overrides` to map custom provider variants into those canonical groups while keeping explicit `provider/model` selection available. +Subscription-routed. `/login` attaches the session. -**Path-scoped model config:** `modelRoles` and other model selectors can be overridden per working directory by nesting a `paths:` map under the setting — useful for pinning a heavier model on one repo without changing the global default. See [docs/models.md](docs/models.md). +Cursor `oauth` · GitHub Copilot `oauth` · GitLab Duo · Kimi Code `plan` · Moonshot · MiniMax Coding Plan `plan` · MiniMax Coding Plan CN `plan` · Alibaba Coding Plan `plan` · Qwen Portal · Z.AI / GLM Coding Plan `plan` · Xiaomi MiMo · Qianfan · NanoGPT · Venice · Kilo · ZenMux · OpenCode Go · OpenCode Zen -### Settings File +### Run it yourself -Global settings are stored in: +OpenAI-compatible `/v1/models`. Local instances skip the key. -- `~/.omp/agent/config.yml` +Ollama `local` · Ollama Cloud · LM Studio `local` · llama.cpp `local` · vLLM `local` · LiteLLM -Project overrides are loaded from discovered project settings files (commonly `.omp/settings.json`). +### Four knobs that make routing useful -Global `config.yml` example: +- **Custom providers** — Declare anything that speaks `openai-completions`, `openai-responses`, `openai-codex-responses`, `azure-openai-responses`, `anthropic-messages`, `google-generative-ai`, or `google-vertex` in `~/.omp/agent/models.yml`. +- **Fallback chains** — Per-role chains under `retry.fallbackChains`. When the primary throws 429s or hits a quota wall, the next entry takes the rest of the turn — restored on cooldown. +- **Path-scoped roles** — Nest `paths:` under `modelRoles` to pin a heavier `default` on one repo without touching the global config. Closest path wins. +- **Round-robin credentials** — Stack API keys per provider and the runtime rotates with session affinity and per-credential backoff. Useful when one key would burn its quota by lunch. -```yaml -theme: - dark: titanium - light: light - -enabledModels: - - "anthropic/*" - - "gpt-5.3-codex" - - "gemini-2.5-pro:high" +Full provider & routing reference at [omp.sh/docs/providers](https://omp.sh/docs/providers). -modelRoles: - default: claude-sonnet-4-6 - plan: claude-opus-4-6:high - smol: anthropic/claude-sonnet-4-6 -modelProviderOrder: - - github-copilot - - zenmux - - openai -defaultThinkingLevel: high - -retry: - enabled: true - # Number of retries before giving up on rate limits/server errors - maxRetries: 3 - # Wait this long as a base (exponentially backed off) unless the API provides a retry-after-ms - baseDelayMs: 2000 - # Configure role-specific model fallback chains - fallbackChains: - default: - - "openai/gpt-4o-mini" - - "openai/gpt-4o" - plan: - - "anthropic/claude-sonnet-4-6:high" - - "openai/o3:high" - # Whether to revert to the primary model when a fallback's cooldown expires - fallbackRevertPolicy: cooldown-expiry -steeringMode: one-at-a-time -followUpMode: one-at-a-time -interruptMode: immediate +## Fourteen backends. _One tool the agent already knows_. -shellPath: C:\\path\\to\\bash.exe -hideThinkingBlock: false -collapseChangelog: false +`web_search` is built in, not bolted on. `auto` walks a fourteen-provider chain; pin one by name if you already pay for it. Behind every hit, site-aware extraction turns GitHub, registries, arXiv, Stack Overflow, and docs into structured markdown — anchors and link targets survive. -disabledProviders: [] -disabledExtensions: [] - -compaction: - enabled: true - reserveTokens: 16384 - keepRecentTokens: 20000 - autoContinue: true - -memory: - backend: local # off | local | hindsight - -skills: - enabled: true - -terminal: - showImages: true +### Search providers -display: - tabWidth: 4 # Tab rendering width (.editorconfig integration) +Fourteen backends. Pin one, or let `auto` walk the chain in order. -topP: -1 # Nucleus sampling (0-1, -1 = provider default) -topK: -1 # Top-K tokens (-1 = provider default) -minP: -1 # Minimum probability (0-1, -1 = provider default) +| provider | auth | +| ------------ | ---------------------- | +| `auto` | chain | +| `exa` | `EXA_API_KEY` (or mcp) | +| `brave` | `BRAVE_API_KEY` | +| `jina` | `JINA_API_KEY` | +| `kimi` | `MOONSHOT_API_KEY` | +| `zai` | `ZAI_API_KEY` | +| `anthropic` | oauth | +| `perplexity` | `PERPLEXITY_API_KEY` | +| `gemini` | oauth | +| `codex` | oauth | +| `tavily` | `TAVILY_API_KEY` | +| `parallel` | `PARALLEL_API_KEY` | +| `kagi` | `KAGI_API_KEY` | +| `synthetic` | `SYNTHETIC_API_KEY` | +| `searxng` | self-hosted | -tools: - discoveryMode: all # off | mcp-only | all +### Specialised handlers -eval: - py: true - js: true +The agent gets structured content, not stripped HTML. -recipe: - enabled: true +- **Code hosts** — github, gitlab +- **Package registries** — npm, PyPI, crates.io, Hex, Hackage, NuGet, Maven, RubyGems, Packagist, pub.dev, Go packages +- **Research sources** — arxiv, semantic scholar +- **Forums** — stack overflow, reddit, hn +- **Docs** — mdn, readthedocs, docs.rs -irc: - enabled: true +Pages convert to markdown with link structure intact. The agent can cite, follow, and quote without losing anchors. -github: - cache: - enabled: true - softTtlSec: 300 - hardTtlSec: 86400 +### Security databases -plan: - enabled: true +Vuln lookups answer with vendor data, not blog summaries. -async: - enabled: false - maxJobs: 100 +- **NVD** — national vulnerability database +- **OSV** — open source vuln feed +- **CISA KEV** — known exploited vulns -task: - eager: false - isolation: - # auto lets the native PAL pick the best CoW backend; explicit values - # pin to one of: apfs | btrfs | zfs | reflink | overlayfs | projfs | - # block-clone | rcopy | none - mode: none - merge: patch # patch | branch - commits: generic # generic | ai -``` +[`web_search` reference ↗](https://omp.sh/docs/tools#web_search) -`modelRoles` may use either canonical ids or explicit `provider/model` selectors. `modelProviderOrder` decides which provider backs a canonical model when multiple equivalent variants are available. +## Drives a _real browser_. _Or your Slack?_ -Legacy migration notes: +Stealth's on by default, so pages see a normal user instead of a headless bot. The same API drives any Electron app in place — point it at Slack and the agent reads your DMs the way it reads the web. -- `settings.json` → `config.yml` -- `queueMode` → `steeringMode` -- flat `theme: "..."` → `theme.dark` / `theme.light` -- `memories.enabled: true|false` → `memory.backend: local|off` -- `task.isolation.enabled` + legacy modes (`worktree`, `fuse-overlay`, `fuse-projfs`) → `task.isolation.mode` enum (`auto`, `apfs`, `btrfs`, `zfs`, `reflink`, `overlayfs`, `projfs`, `block-clone`, `rcopy`, `none`) +![omp TUI driving the browser tool against DuckDuckGo](https://omp.sh/captures/browser.webp) ---- +**Also drives:** localhost dev servers · Electron apps via `app.path` · existing Chromium via `cdp_url`. Tabs persist across tool calls. ---- +## Roughly **~27,000** lines of Rust, doing the work other harnesses shell out for. -## Extensions +Three crates, one platform-tagged N-API addon. Search, shell, AST, highlight, PTY, image decode, BPE counting — all in-process on the libuv pool. No fork/exec on the hot path. -### Themes +- Crates: `pi-natives`, `pi-shell`, `pi-ast` +- Platforms: `linux-x64`, `linux-arm64`, `darwin-x64`, `darwin-arm64`, `win32-x64` -Built-in themes include `dark`, `light`, and many bundled variants. +The table below is a per-module breakdown that intentionally omits glue and tests. -**Automatic dark/light switching**: omp detects terminal appearance via Mode 2031, native macOS CoreFoundation FFI, or `COLORFGBG` fallback, and switches between `theme.dark` and `theme.light` automatically. +| Module | What it does | Powered by | ~LoC | +| ---------- | ------------------------------------------------------------------------------------ | ----------------------------------------- | ----: | +| shell | Embedded bash · persistent sessions · timeout/abort · custom builtins | brush-shell (vendored) | 3,700 | +| grep | Regex search · parallel/sequential · glob & type filters · fuzzy find | grep-regex · grep-searcher | 1,900 | +| keys | Kitty keyboard protocol with xterm fallback · PHF perfect-hash lookup | phf | 1,490 | +| text | ANSI-aware width · truncation · column slicing · SGR-preserving wrap | unicode-width · segmentation | 1,450 | +| summarize | Tree-sitter structural source summaries with elision controls | tree-sitter · ast-grep-core | 1,040 | +| ast | ast-grep pattern matching and structural rewrites | ast-grep-core | 1,000 | +| fs_cache | Mtime-keyed file cache shared by read · grep · lsp | in-tree | 840 | +| highlight | Syntax highlighting · 11 semantic categories · 30+ aliases | syntect | 470 | +| pty | Native PTY allocation for sudo · ssh interactive prompts | portable-pty | 455 | +| glob | Discovery with glob · type filters · mtime sort · gitignore respect | ignore · globset | 410 | +| workspace | Workspace walker with gitignore + AGENTS.md discovery in one pass | ignore · git2 | 385 | +| appearance | Mode 2031 + native macOS dark/light via CoreFoundation FFI | core-foundation | 270 | +| power | macOS power-assertion API for idle/system/display-sleep prevention | IOKit FFI | 270 | +| task | Blocking work on libuv thread pool · cancellation · timeout · profiling | tokio · napi | 260 | +| fd | Filesystem walker for find-tool replacement | ignore | 250 | +| iso | Workspace isolation shim · apfs · btrfs · zfs · reflink · overlayfs · projfs · rcopy | pi-iso (PAL) | 245 | +| prof | Circular buffer profiler with folded-stack and SVG flamegraph output | inferno | 240 | +| ps | Cross-platform process-tree kill and descendant listing | libc · libproc · CreateToolhelp32Snapshot | 195 | +| image | Decode/encode PNG · JPEG · WebP · GIF · resize with 5 filters | image | 190 | +| clipboard | Text copy and image read from system clipboard · no xclip/pbcopy | arboard | 80 | +| tokens | O200k / Cl100k BPE token counting · both tables embedded | tiktoken-rs | 65 | +| html | HTML to Markdown with optional content cleaning | html-to-markdown-rs | 50 | -Select theme via `/settings` or set in `~/.omp/agent/config.yml`: +## Four entry points: _interactive_, _one-shot_, RPC, and ACP. -```yaml -theme: - dark: titanium - light: light -``` +Same engine, four wrappers. `omp` runs the TUI. `omp -p` answers a single prompt and exits. The Node SDK embeds the session in your process. `omp --mode rpc` and `omp acp` hand the wheel to another program over stdio. -**Custom themes:** create `~/.omp/agent/themes/*.json`. +### Interactive — when in doubt, the agent asks -> See [Theme Documentation](docs/theme.md). +The TUI is the default surface. Tool calls render as cards, edits preview before they land, and ambiguity routes through the `ask` tool — a structured option picker the agent can call mid-turn. The keyboard handles the rest. -### Custom Slash Commands +The same prompt cards surface over ACP, so editors get the picker without writing one. -Define reusable prompt commands as Markdown files: +![omp TUI: the ask tool renders an option picker with three choices, a (Recommended) badge on the first, and 'up/down navigate · enter select · esc cancel' footer.](https://omp.sh/captures/ask.webp) -- Global: `~/.omp/agent/commands/*.md` -- Project: `.omp/commands/*.md` -- Also discovered: `~/.claude/commands/`, `.claude/commands/`, `~/.codex/commands/`, `.codex/commands/` +### SDK — embed in Node -```markdown ---- -description: Review staged git changes ---- +`@oh-my-pi/pi-coding-agent` -Review the staged changes (`git diff --cached`). Focus on: - -- Bugs and logic errors -- Security issues -- Error handling gaps -``` - -Filename (without `.md`) becomes the command name. - -Argument placeholders: - -- `$1`, `$2`, ... positional arguments -- `$@` and `$ARGUMENTS` for all arguments joined - -TypeScript custom commands are also supported — drop an `index.ts` into a per-command folder and default-export a factory: - -- `~/.omp/agent/commands/<name>/index.ts` -- `.omp/commands/<name>/index.ts` - -Bundled TypeScript command: `/review`. - -### Skills - -Skills are capability packages loaded on-demand. - -Common locations: - -- `~/.omp/agent/skills/*/SKILL.md` -- `.omp/skills/*/SKILL.md` -- `~/.claude/skills/*/SKILL.md`, `.claude/skills/*/SKILL.md` -- `~/.codex/skills/*/SKILL.md`, `.codex/skills/*/SKILL.md` - -```markdown ---- -name: brave-search -description: Web search via Brave Search API. ---- - -# Brave Search -``` - -`description` drives matching; `name` defaults to the folder name when omitted. - -Disable skills with `omp --no-skills` or `skills.enabled: false`. - -> See [Skills Documentation](docs/skills.md). - -### Hooks - -Hooks are TypeScript modules that subscribe to lifecycle events. - -Hook locations: - -- Global: `~/.omp/agent/hooks/pre/*.ts`, `~/.omp/agent/hooks/post/*.ts` -- Project: `.omp/hooks/pre/*.ts`, `.omp/hooks/post/*.ts` -- CLI: `--hook <path>` (treated as an alias for `--extension`) - -```typescript -import type { HookAPI } from "@oh-my-pi/pi-coding-agent/extensibility/hooks"; - -export default function (omp: HookAPI) { - omp.on("tool_call", async (event, ctx) => { - if ( - event.toolName === "bash" && - /sudo/.test(event.input.command as string) - ) { - const ok = await ctx.ui.confirm( - "Allow sudo?", - event.input.command as string, - ); - if (!ok) return { block: true, reason: "Blocked by user" }; - } - return undefined; - }); -} -``` - -Inject messages from hooks with: +Node and TypeScript hosts pull the engine in directly. The package exposes `ModelRegistry`, `SessionManager`, `createAgentSession`, and `discoverAuthStorage`; the session emits typed events you subscribe to. ```ts -omp.sendMessage(message, { triggerTurn: true }); -``` +import { ModelRegistry, SessionManager, createAgentSession, discoverAuthStorage } from "@oh-my-pi/pi-coding-agent"; -> See [Hooks Documentation](docs/hooks.md) and [examples/hooks/](packages/coding-agent/examples/hooks/). For richer integrations (tools + commands + events from one module) prefer `ExtensionAPI`. +const auth = await discoverAuthStorage(); +const models = new ModelRegistry(auth); +await models.refresh(); -### Custom Tools - -Custom tools extend the built-in toolset and are callable by the model. - -Auto-discovered locations: - -- Global: `~/.omp/agent/tools/*/index.ts` -- Project: `.omp/tools/*/index.ts` - -```typescript -import { Type } from "@sinclair/typebox"; -import type { CustomToolFactory } from "@oh-my-pi/pi-coding-agent"; -const factory: CustomToolFactory = () => ({ - name: "greet", - label: "Greeting", - description: "Generate a greeting", - parameters: Type.Object({ - name: Type.String({ description: "Name to greet" }), - }), - async execute(_toolCallId, params) { - const { name } = params as { name: string }; - return { content: [{ type: "text", text: `Hello, ${name}!` }] }; - }, -}); -export default factory; -``` - -> See [Custom Tools Documentation](docs/custom-tools.md) and [examples/custom-tools/](packages/coding-agent/examples/custom-tools/). - -### Marketplace - -omp ships a Claude-compatible plugin marketplace: discover, install, and manage plugins (skills, commands, hooks, MCP/LSP servers) from Git-hosted catalogs or local directories. - -A **marketplace** is a Git repo (or directory) with a `.claude-plugin/marketplace.json` catalog. A **plugin** is identified as `name@marketplace` (e.g. `code-review@claude-plugins-official`) and can be installed at **user** scope (default, `~/.omp/plugins/`) or **project** scope (`.omp/plugins/`, shadows user installs). - -```text -/marketplace add anthropics/claude-plugins-official -/marketplace discover # browse catalogs -/marketplace install code-review@claude-plugins-official -/marketplace list | remove | update | uninstall | upgrade | installed -/plugins list # all installed plugins (npm + marketplace) -/plugins enable|disable <name@marketplace> -``` - -Or just type `/marketplace` with no arguments to open the interactive browser. The same operations are available via `omp plugin ...` from the CLI. - -> See [Marketplace Documentation](docs/marketplace.md). - ---- - -## CLI Reference - -```bash -omp [options] [@files...] [messages...] -omp <command> [args] [flags] -``` - -### Options - -| Option | Description | -| ------------------------------------- | ------------------------------------------------------------------ | -| `--provider <name>` | Provider hint (legacy; prefer `--model`) | -| `--model <id>` | Model ID (supports fuzzy match) | -| `--smol <id>` | Override the `smol` role model for this run | -| `--slow <id>` | Override the `slow` role model for this run | -| `--plan <id>` | Override the `plan` role model for this run | -| `--models <patterns>` | Comma-separated model patterns for role cycling | -| `--list-models [pattern]` | List available models (optional fuzzy filter) | -| `--thinking <level>` | Thinking level: `off`, `minimal`, `low`, `medium`, `high`, `xhigh` | -| `--api-key <key>` | API key (overrides environment/provider lookup) | -| `--system-prompt <text\|file>` | Replace system prompt | -| `--append-system-prompt <text\|file>` | Append to system prompt | -| `--mode <mode>` | Output mode: `text`, `json`, `rpc`, `acp`, `rpc-ui` | -| `--print`, `-p` | Non-interactive: process prompt and exit | -| `--continue`, `-c` | Continue most recent session | -| `--resume`, `-r [id\|path]` | Resume by ID prefix/path (or open picker if omitted) | -| `--session <value>` | Alias of `--resume` | -| `--session-dir <dir>` | Directory for session storage and lookup | -| `--no-session` | Don't save session | -| `--fork <id>` | Fork from a specific message ID | -| `--tools <tools>` | Restrict to comma-separated built-in tool names | -| `--no-tools` | Disable all built-in tools | -| `--no-lsp` | Disable LSP integration | -| `--no-pty` | Disable PTY-based interactive bash execution | -| `--extension <path>`, `-e` | Load extension file (repeatable) | -| `--hook <path>` | Load hook/extension file (repeatable) | -| `--plugin-dir <path>` | Load plugin from directory (repeatable) | -| `--no-extensions` | Disable extension discovery (`-e` paths still load) | -| `--no-skills` | Disable skills discovery and loading | -| `--skills <patterns>` | Comma-separated glob patterns to filter skills | -| `--no-rules` | Disable rules discovery and loading | -| `--allow-home` | Allow starting from home dir without auto-chdir | -| `--no-title` | Disable automatic session title generation | -| `--export <file> [output]` | Export session to HTML | -| `--help`, `-h` | Show help | -| `--version`, `-v` | Show version | - -### Subcommands - -`omp` also ships dedicated subcommands: - -| Command | Description | -| -------------- | ---------------------------------------------------------------- | -| `acp` | Run as an Agent Client Protocol server (editor integration) | -| `agents` | Manage agent definitions (e.g. `omp agents unpack`) | -| `commit` | Generate and apply git commits with the agentic commit pipeline | -| `config` | Inspect or edit settings (`config.yml`) | -| `grep` | Standalone content search using the in-tree ripgrep wrapper | -| `grievances` | Review queued tool-issue / autoqa grievances | -| `plugin` | Manage npm-installed plugins | -| `read` | CLI inspector for files, archives, tool outputs, and `*://` URIs | -| `search` (`q`) | Run the multi-provider web-search tool from the shell | -| `setup` | First-run setup (Python kernel, OAuth, model defaults) | -| `shell` | Spawn an interactive shell session through omp's bash runtime | -| `ssh` | Manage SSH host definitions used by the `ssh` tool | -| `stats` | Inspect session/usage statistics | -| `update` | Update the installed omp binary | - -### File Arguments - -Include files with `@` prefix: - -```bash -omp @prompt.md "Answer this" -omp @screenshot.png "What's in this image?" -omp @requirements.md @design.png "Implement this" -``` - -Text files are wrapped in `<file ...>` blocks. Images are attached. - -### Examples - -```bash -# Interactive mode -omp - -# Non-interactive prompt -omp -p "List all .ts files in src/" - -# Continue / resume -omp -c "What did we discuss?" -omp -r abc123 - -# Restrict toolset for a read-only review -omp --tools read,search,find -p "Review the architecture" - -# Editor integration (ACP server, stdio transport) -omp acp - -# Agentic commit on staged changes -omp commit - -# Inspect a tool output by artifact URI -omp read 'artifact://abc123' - -# Model cycling with patterns -omp --models "sonnet:high,haiku:low" - -# Export a session to HTML -omp --export session.jsonl output.html -``` - -### Environment Variables - -| Variable | Description | -| ------------------------------------------------- | -------------------------------------------------------- | -| `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, etc. | Provider credentials | -| `PI_CODING_AGENT_DIR` | Override agent data directory (default: `~/.omp/agent`) | -| `PI_PACKAGE_DIR` | Override package directory resolution | -| `PI_SMOL_MODEL`, `PI_SLOW_MODEL`, `PI_PLAN_MODEL` | Role-model overrides | -| `PI_NO_PTY` | Disable PTY-based bash execution | -| `PI_PY`, `PI_JS` | Gate the python / JavaScript backends of the `eval` tool | -| `PI_HL_SEP` | Override the hashline payload separator (single char) | -| `OMP_GITHUB_CACHE_DB` | Override the GitHub view cache database path | -| `VISUAL`, `EDITOR` | External editor for Ctrl+G | - -See [Environment Variables](docs/environment-variables.md) for the complete reference. - ---- - -## Tools - -Use `--tools <list>` to restrict available built-in tools. - -### Built-in Tool Names (`--tools`) - -| Tool | Description | -| ------------------ | --------------------------------------------------------------------------------------- | -| `ask` | Ask the user structured follow-up questions (interactive mode) | -| `bash` | Execute shell commands | -| `eval` | Run code in a persistent kernel (Python and JavaScript backends) | -| `calc` | Deterministic calculator/evaluator | -| `ssh` | Execute commands on configured SSH hosts | -| `github` | Op-based wrapper around the GitHub CLI (`repo_view`, `pr_*`, `search_*`, `run_watch`) | -| `recipe` | Run a recipe / target from the project's task runner (bun, just, make, …) | -| `irc` | Send short messages between live agents (main ↔ subagents) | -| `edit` | In-place file editing with anchors | -| `write` | Create/overwrite files | -| `find` | Find files by glob pattern | -| `search` | Search file contents (regex) | -| `ast_grep` | Structural code search using AST matching (ast-grep) | -| `ast_edit` | Structural AST-aware code rewrites (ast-grep) | -| `lsp` | Language server actions (multi-operation) | -| `debug` | Debugger access via DAP (launch/attach, breakpoints, stepping, threads/stack/variables) | -| `read` | Read files, directories, archives, SQLite, PDFs, notebooks, URLs | -| `inspect_image` | Extract image content with a vision model | -| `render_mermaid` | Render Mermaid diagrams to ASCII or PNG | -| `browser` | Browser automation tool (model-facing name: `puppeteer`) | -| `task` | Launch subagents for parallel execution | -| `job` | Manage async background jobs (poll, cancel, list) | -| `todo_write` | Phased task tracking with progress management | -| `web_search` | Multi-provider web search | -| `search_tool_bm25` | Tool-discovery search over hidden built-in / MCP / extension tools | -| `generate_image` | Generate or edit images using Gemini image models | -| `checkpoint` | Save a workspace checkpoint | -| `rewind` | Rewind the workspace to a previous checkpoint | -| `retain` | Persist a memory note (hindsight backend) | -| `recall` | Recall memory notes (hindsight backend) | -| `reflect` | Trigger memory consolidation (hindsight backend) | - -Notes: - -- `ask` requires interactive UI. -- `ssh` requires configured SSH hosts. -- Some tools are setting-gated and are excluded from the active toolset unless enabled: - - `calc` ← `calc.enabled` - - `browser` ← `browser.enabled` - - `github` ← `github.enabled` - - `recipe` ← `recipe.enabled` - - `irc` ← `irc.enabled` (and only attached to the main agent when `async.enabled` is true) - - `inspect_image` ← `inspect_image.enabled` - - `render_mermaid` ← `renderMermaid.enabled` - - `web_search` ← `web_search.enabled` - - `find` / `search` ← `find.enabled` / `search.enabled` - - `ast_grep` / `ast_edit` ← `astGrep.enabled` / `astEdit.enabled` - - `lsp` ← `lsp.enabled` (and `--no-lsp` is not set) - - `checkpoint` / `rewind` ← `checkpoint.enabled` - - `debug` ← `debug.enabled` - - `search_tool_bm25` ← `tools.discoveryMode !== "off"` (or legacy `mcp.discoveryMode`) - - `retain` / `recall` / `reflect` ← `memory.backend === "hindsight"` - - `eval` python/JS backends individually gated by `eval.py` / `eval.js` (or the `PI_PY` / `PI_JS` env vars) - -Example: - -`omp --tools read,search,find -p "Review this codebase"` - -For adding new tools, see [Custom Tools](#custom-tools). - ---- - -## Programmatic Usage - -### SDK - -For embedding omp in Node.js/TypeScript applications, use the SDK: - -```typescript -import { - ModelRegistry, - SessionManager, - createAgentSession, - discoverAuthStorage, -} from "@oh-my-pi/pi-coding-agent"; -const authStorage = await discoverAuthStorage(); -const modelRegistry = new ModelRegistry(authStorage); -await modelRegistry.refresh(); const { session } = await createAgentSession({ - sessionManager: SessionManager.inMemory(), - authStorage, - modelRegistry, + sessionManager: SessionManager.inMemory(), + authStorage: auth, + modelRegistry: models, }); -session.subscribe((event) => { - if ( - event.type === "message_update" && - event.assistantMessageEvent.type === "text_delta" - ) { - process.stdout.write(event.assistantMessageEvent.delta); - } -}); -await session.prompt("What files are in the current directory?"); +await session.prompt("list .ts files"); ``` -The SDK provides control over: +### RPC — drive over stdio -- Model selection and thinking level -- System prompt (replace or append) -- Built-in/custom tools -- Hooks, skills, context files, slash commands -- Session persistence (`SessionManager`) -- Settings (`Settings`) -- API key and OAuth resolution +`omp --mode rpc` -> See [SDK Documentation](docs/sdk.md) and [examples/sdk/](packages/coding-agent/examples/sdk/). +For non-Node embedders, or when you want process isolation. NDJSON commands in, response and event frames out. `--mode rpc-ui` adds tool cards, selectors, and dialogs as `extension_ui_request` frames the host must answer. -### RPC Mode - -For embedding from other languages or process isolation: - -```bash -omp --mode rpc --no-session -# or, for embedders that want to drive the TUI (tool cards, dialogs, selectors) over the protocol: -omp --mode rpc-ui --no-session +``` +$ omp --mode rpc --no-session +> {"id":"r1","type":"prompt","message":"list .ts files"} +< {"id":"r1","type":"response", ...} +> {"id":"r2","type":"set_model","provider":"anthropic","modelId":"sonnet-4.5"} +> {"id":"r3","type":"abort"} ``` -Send JSON commands on stdin: +### ACP — speak to editors -```json -{"id":"req-1","type":"prompt","message":"List all .ts files"} -{"id":"req-2","type":"abort"} -{"id":"req-3","type":"get_login_providers"} -{"id":"req-4","type":"login","providerId":"anthropic"} -{"id":"req-5","type":"handoff"} -``` +`omp acp` -Responses are emitted as `type: "response"`; session events and extension UI requests stream on stdout as they occur. +The [Agent Client Protocol](https://github.com/zed-industries/agent-client-protocol) over JSON-RPC. When the editor advertises capabilities, tool I/O routes through it and writes are gated by `session/request_permission`. -Available command families (non-exhaustive): `prompt` / `steer` / `follow_up` / `abort` / `abort_and_prompt`, `new_session` / `switch_session` / `branch` / `handoff`, `get_state` / `get_messages` / `get_session_stats`, `set_model` / `cycle_model` / `get_available_models`, `set_thinking_level`, `compact` / `set_auto_compaction`, `bash` / `abort_bash`, `set_host_tools` (register host-side tools the agent can call back into), `get_login_providers` / `login`, `export_html`. +| omp tool | ACP route | +| ----------------------------- | ----------------------------------- | +| `bash` | `terminal/create + terminal/output` | +| `read` | `fs/read_text_file` | +| `write` | `fs/write_text_file` | +| `edit, ast_edit, write, bash` | `session/request_permission` | -`--mode rpc-ui` adds full UI plumbing on top of the same protocol: tool execution cards, selectors, dialogs, and other interactive surfaces are streamed as `extension_ui_request` frames that the embedder must answer with `extension_ui_response`. `--mode rpc` keeps it headless (no UI requests). +Full reference: [omp.sh/docs/sdk](https://omp.sh/docs/sdk). -> See [RPC Documentation](docs/rpc.md) for the full protocol. +## A harness worth keeping is one you _don't_ outgrow. -### ACP Mode +Pick it up at **[omp.sh](https://omp.sh)**. -For embedding in editors that speak the [Agent Client Protocol](https://github.com/zed-industries/agent-client-protocol) (e.g. Zed): +omp is a fork of [Pi](https://github.com/badlogic/pi-mono) by [Mario Zechner](https://github.com/mariozechner), rewritten as a coding-first surface: sessions, subagents, slash commands, extensions — all TypeScript, all MIT, all on [GitHub](https://github.com/can1357/oh-my-pi). Shape it from config, hook it from outside, or read the source when you need to. -```bash -omp acp -# equivalent to: omp --mode acp -``` +### Primitives -ACP mode starts a JSON-RPC server over stdio. It does **not** require a configured model at startup — the client can drive `initialize` and `authenticate` (including `/login`) before any model is selected. A `terminal` auth method is advertised when the client opts in via `clientCapabilities.auth.terminal` and falls back to an embedded interactive login flow. +An extension is a TypeScript module. Same tool API, same slash-command registry, same hotkey table, same TUI primitives the built-ins use. Nothing is reserved. -When the client advertises capabilities at `initialize`, the agent routes tool I/O through them via the `ClientBridge` abstraction (`packages/coding-agent/src/session/client-bridge.ts`): +### Discovery -- `bash` → `terminal/create` + `terminal/output` (per-call client-side terminals) -- `read` → `fs/read_text_file` (so unsaved editor buffers and in-memory edits are visible) -- `write` → `fs/write_text_file` (writes go through the editor and let it track agent changes) -- `bash`, `edit`, `write`, and `ast_edit` are gated behind `session/request_permission` when the client supports it; `allow_always` / `reject_always` decisions are remembered per tool for the session lifetime +On first run omp inherits whatever is already on disk: rules, skills, and MCP servers from `.claude`, `.cursor`, `.windsurf`, `.gemini`, `.codex`, `.cline`, `.github/copilot`, and `.vscode`. No migration script. -Slash commands available to ACP clients reach feature parity with the TUI for non-interactive flows, including `/model`, `/plan`, `/loop`, `/login`, `/logout`, `/agents`, `/extensions`, `/plugins`, `/marketplace`, `/mcp`, `/ssh`, `/session`, `/branch`, `/fork`, `/new`, `/resume`, `/drop`, `/handoff`, `/move`, `/memory`, `/todo`, `/jobs`, `/changelog`, `/dump`, `/copy`, `/hotkeys`, `/btw`, `/tree`, `/export`, `/share`, plus all `/skill:<name>` commands. The full set is registered in `packages/coding-agent/src/slash-commands/acp-builtins.ts`. +### Extensibility -Beyond stock ACP methods, the agent exposes a small set of `_omp/*` extension methods for omp-aware clients (renamed from `omp/*` in 15.0.0 to match the ACP spec's `_`-prefix requirement for non-spec methods): - -- `_omp/sessions/listAll` — paginated cross-cwd session index -- `_omp/projects/list` — discovered project cwds with session counts -- `_omp/chats/byCwd` — sessions filtered by working directory -- `_omp/usage` — token/cost rollup for active sessions -- `_omp/extensions` / `_omp/extensions/toggle` — list and toggle discovered extensions - -Mode-aware notifications are also wired up: `session/set_mode` and `session/set_session_config_option("mode", …)` both emit `current_mode_update`; `/model` emits `config_option_update` after a model switch so client config selectors stay in sync; `tool_call_update.locations` is kept fresh from in-flight tool args so editors can "follow along" multi-file edits. - -### HTML Export - -```bash -omp --export session.jsonl # Auto-generated filename -omp --export session.jsonl output.html # Custom filename -``` - -Works with session files and JSON event logs from `--mode json`. - ---- +Ask omp to write the piece you're missing, then `/reload-plugins`. Keep it local, ship it in a `marketplace`, or publish it to npm. ## Philosophy @@ -1763,5 +490,14 @@ For architecture and contribution guidelines, see [packages/coding-agent/DEVELOP MIT. See [LICENSE](LICENSE). -Copyright (c) 2025 Mario Zechner -Copyright (c) 2025-2026 Can Bölük +© 2025 Mario Zechner +© 2025-2026 Can Bölük + +_made for terminals that stay open_ + +- [omp.sh](https://omp.sh) +- [GitHub](https://github.com/can1357/oh-my-pi) +- [Changelog](https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/CHANGELOG.md) +- [npm](https://www.npmjs.com/package/@oh-my-pi/pi-coding-agent) +- [Discord](https://discord.gg/4NMW9cdXZa) +- [MIT](https://github.com/can1357/oh-my-pi/blob/main/LICENSE) diff --git a/assets/hero.png b/assets/hero.png index 0481f8f09..0146f9053 100644 Binary files a/assets/hero.png and b/assets/hero.png differ