AI Coding Guides Deep Dives
Deep Dive • v0.73.0 • TypeScript/Node 20+ • MIT • 26 Providers • Updated May 2026

Pi Mono: The Minimalist Kernel

Pi is a coding agent that deliberately ships without MCP, without sub-agents, and without permission gates. Instead, it provides a razor-sharp tool core, tree-structured JSONL sessions, a differential-rendering TUI, and an extension system that lets you build everything else yourself — including Pi Packages, shareable bundles installable via npm or git.

(Alright, ad over. Back to the serious technical analysis.)

What is Pi Mono?

Pi Mono (@mariozechner/pi-coding-agent, version 0.73.0) is a TypeScript-based coding agent CLI created by Mario Zechner (badlogic). It lives in a monorepo with five current packages, all at the same version and under the MIT license:

Package Name What it does
coding-agent @mariozechner/pi-coding-agent The core CLI — tool definitions, mode entry points, extension loading
ai @mariozechner/pi-ai Unified multi-provider LLM API — 26 providers, 10 API implementations
agent @mariozechner/pi-agent-core Agent runtime — agent loop, transcript management, event system
tui @mariozechner/pi-tui Differential terminal UI engine — only redraws changed cells
web-ui @mariozechner/pi-web-ui Web components (Lit) — chat panel, artifacts, sandboxed iframes, JS REPL

The current packages/ directory is agent, ai, coding-agent, tui, and web-ui. Older references to mom and pods no longer match the fresh repo snapshot.

The project is hosted at pi.dev (domain donated by exe.dev) and its logo lives at shittycodingagent.ai — a self-deprecating branding choice that signals the project's no-nonsense attitude.

🚫

Deliberately missing features

The README is explicit about what Pi does not include:

  • No MCP — The author argues CLI tools + skills are sufficient. Extensions can add MCP.
  • No sub-agents — Spawn separate pi instances via tmux, or build your own with extensions.
  • No permission popups — Run in a container, or build your own confirmation flow with extensions.
  • No plan mode — Plans are expected to be written to files.
  • No built-in todos — They confuse models per the author.
  • No background bash — Use tmux for persistent processes.

This philosophical stance makes Pi fundamentally different from Claude Code, OpenHands, and DeerFlow. It is not trying to be an operating system or a framework — it is a focused tool with a clear opinion about what a coding agent should be.

The Four Run Modes

💻

Interactive TUI

The default mode. A full terminal UI with streaming messages, tool execution display, session navigation, model selector, and settings dialogs. Built on a custom differential rendering engine that only redraws changed terminal cells at 60fps throttle (16ms min). Supports Kitty graphics protocol for images and hardware cursor via APC escape sequences for IME positioning.

📄

Print Mode

Single-shot mode for scripting. Feed it a prompt, get a response. Useful for CI pipelines, automated code reviews, and batch processing. No TUI overhead — just stdout.

🔌

RPC Mode

JSONL-based protocol for embedding pi in other applications. Stdin/stdout communication with structured JSON messages — similar to how VS Code extensions communicate with language servers. Ideal for IDE integration.

📦

SDK Mode

Embed pi as a library in other Node.js applications. Import the SDK directly and control the agent programmatically — useful for building custom integrations or wrapping pi in another product.

Tool System: JSON Function Calling with TypeBox

Pi uses JSON Schema-based function calling, not XML wrappers or raw CLI parsing. Tools are defined using TypeBox schemas (@sinclair/typebox), providing type-safe parameter validation at runtime. Tool arguments are validated using AJV — if validation fails, the error is returned to the LLM as an isError: true tool result, allowing the model to retry without human intervention.

The core tool set includes 7 tools, split into two groups:

Tool Category Details
read Coding Read file with configurable max lines/bytes, truncation notices
bash Coding Shell execution with streaming output, process tree killing, 10MB stdout/stderr cap, temp file fallback for overflow
edit Coding Precise text replacement with multiple disjoint edits per call, fuzzy matching, uniqueness validation, reverse-order application
write Coding Write entire files, auto-create parent directories, file mutation queue for concurrent safety
grep Read-only Regex content search across files
find Read-only File path search by name or pattern
ls Read-only Directory listing

The default tool set is read, bash, edit, write (4 tools). In read-only mode, it switches to read, grep, find, ls.

The Edit Tool: Precision Engineering

Pi's edit tool is one of the most carefully designed components in any coding agent. It does not use unified diff patches or whole-file rewrites. Instead:

How edits work

  1. Multiple disjoint edits per call: The model can specify several oldText/newText pairs in a single tool call.
  2. Non-overlapping validation: Each oldText is matched against the original file, not incrementally. All edits are validated to ensure they don't overlap.
  3. Reverse-order application: Edits are applied from bottom to top of the file, maintaining stable line offsets as changes accumulate.
  4. Exact matching first: The tool tries to find an exact string match for each oldText.
  5. Fuzzy matching fallback: If exact matching fails, it normalizes trailing whitespace, Unicode quotes (smart quotes), Unicode dashes, and special spaces before trying again.
  6. Uniqueness validation: Each oldText must appear exactly once in the file. If it appears zero or multiple times, the edit is rejected with a clear error.
  7. Line ending preservation: Detects CRLF vs LF and restores original line endings after edits.
  8. BOM handling: Strips byte-order marks before matching, then prepends them back on write.

After applying edits, Pi generates a custom diff with line numbers and 4 lines of context for display in the TUI.

🔒

File mutation queue

Pi serializes write/edit operations targeting the same file using per-file promise chains (file-mutation-queue.ts). This prevents race conditions when the LLM attempts concurrent edits to the same file — a subtle bug that plagues many other agents.

Bash Tool: Streaming with Safety

Pi's bash tool has several notable features:

Session Management: Tree-Structured JSONL (v3)

Pi's session system is one of its most distinctive features. Sessions are stored as JSONL files with tree structure, enabling branching without file proliferation. The current session format version is v3.

JSONL
{"type": "message", "id": "abc123", "parentId": null, "role": "user", "content": "..."}
{"type": "message", "id": "def456", "parentId": "abc123", "role": "assistant", ...}
{"type": "toolResult", "id": "ghi789", "parentId": "def456", "toolName": "bash", ...}
{"type": "thinking_level_change", "id": "...", "parentId": "...", "level": "high"}
{"type": "model_change", "id": "...", "parentId": "...", "model": "anthropic/claude-sonnet-4-5"}
{"type": "compaction", "id": "jkl012", "parentId": "abc123", "summary": "...", "firstKeptEntryId": "xyz", "tokensBefore": 120000}
{"type": "branch_summary", "id": "mno345", "parentId": "abc123", ...}
{"type": "label", "id": "...", "parentId": "...", "label": "bookmark-name"}

Each entry has an id and parentId, creating a tree within a single file. Entry types include: message, thinking_level_change, model_change, compaction, branch_summary, custom, custom_message, label, and session_info.

This enables:

Sessions auto-save to ~/.pi/agent/sessions/ organized by working directory. Commands like pi -c (continue most recent), pi -r (resume from list), and --session <path> provide flexible session control.

Agent Runtime: Parallel Tool Execution & Steering

The agent runtime in packages/agent/src/ is where the core agentic loop lives. The Agent class wraps agentLoop() and agentLoopContinue() with sophisticated state management:

Key runtime features

  • Parallel tool execution (default): Tools run concurrently. Configurable as "parallel" or "sequential".
  • Steering messages: steer() queues messages delivered after the current turn — real-time interruption without breaking the loop.
  • Follow-up messages: followUp() queues messages delivered only after the agent stops — different delivery semantics from steering.
  • PendingMessageQueue: Two delivery modes — one-at-a-time vs all — for fine-grained control over message delivery timing.
  • Event subscription: Comprehensive event system with listener promises awaited in order. Events include: agent_start, agent_end, tool_call, tool_result, message_start, message_update, message_end, turn_start, turn_end, session_start, session_compact, session_tree, model_select, context, user_bash, input, before_provider_request.
  • beforeToolCall / afterToolCall hooks: Extensions can intercept and modify tool execution.
  • Abort handling: abort() and waitForIdle() for lifecycle control. Failed runs produce assistant messages with stopReason: "error" or "aborted".

Model Support: 26 Providers Across 10 APIs

Pi's current README describes 26 built-in providers exposed through the unified @mariozechner/pi-ai layer. The important detail is not just breadth, but the split between subscription-backed logins and a large API-key matrix.

Subscription-backed logins

  • Anthropic Claude Pro/Max
  • OpenAI ChatGPT Plus/Pro (Codex)
  • GitHub Copilot

API-key providers

Anthropic, OpenAI, Azure OpenAI, DeepSeek, Google Gemini, Google Vertex, Amazon Bedrock, Mistral, Groq, Cerebras, Cloudflare AI Gateway, Cloudflare Workers AI, xAI, OpenRouter, Vercel AI Gateway, ZAI, OpenCode Zen, OpenCode Go, Hugging Face, Fireworks, Kimi For Coding, MiniMax, Xiaomi MiMo, and three Xiaomi MiMo token-plan endpoints.

Only 10 API implementations sit underneath that list. Most providers reuse compatible OpenAI-, Anthropic-, or Google-style transports, which is why Pi can stay minimalist while still supporting a huge provider catalog.

Model Resolution System

The ModelRegistry manages built-in and custom models. Resolution supports:

Auth Storage

Credentials are stored at ~/.pi/agent/auth.json with 0o600 permissions (owner read/write only). The file uses proper-lockfile with retry logic for multi-instance safety — if you run two pi instances simultaneously, they won't corrupt each other's auth state.

Extension System: Build Everything Else

Pi's extension system is where the real power lies. Extensions are loaded at runtime using jiti (TypeScript runtime executor — a custom fork @mariozechner/jiti with virtualModules support for compiled Bun binaries), and they can hook into virtually every aspect of the agent.

TypeScript
// Example extension: Permission gate for dangerous commands
export default function(pi: ExtensionAPI) {
  pi.on("tool_call", async (event, ctx) => {
    if (event.toolName === "bash" && event.input.command?.includes("rm -rf")) {
      const ok = await ctx.ui.confirm("Dangerous!", "Allow rm -rf?");
      if (!ok) return { block: true, reason: "Blocked by user" };
    }
  });
}

The ExtensionAPI provides:

Extension Discovery Order

  1. Project-local: cwd/.pi/extensions/
  2. Global: ~/.pi/agent/extensions/
  3. Explicitly configured: Via settings or -e flag
  4. Pi Packages: Discovered from installed packages

No recursion beyond one level — extensions are intentionally flat and discoverable.

Event Categories

Category Example Events What Extensions Can Do
Resource resources_discover Inject custom resources (context files, etc.)
Session session_start, session_before_compact, session_tree Modify session state, fork, navigate
Agent before_provider_request, message_end, agent_start Observe/modify agent behavior
Tool tool_call, tool_result, beforeToolCall Block, modify, or augment tool execution
Model model_select Override model selection
Input input Transform or handle user input
Turn turn_start, turn_end Per-turn telemetry, timing
Message message_start, message_update, message_end Stream interception, custom rendering

Pi Packages (Pip): Shareable Bundles

One of Pi's most distinctive features is its package system. Pi Packages (sometimes called "Pip") are shareable bundles installable via npm or git:

CLI
pi install npm:@foo/pi-tools
pi install git:github.com/user/repo

Packages declare their contents via a pi key in package.json. They can contain:

Auto-discovery scans extensions/, skills/, prompts/, and themes/ directories within installed packages. This creates a genuine ecosystem — you don't need to write code to extend Pi, you can just install a package.

Skills: Markdown-Based Tool Definitions

Pi supports Agent Skills — markdown files following the Agent Skills standard at agentskills.io. Skills are essentially self-contained tool definitions with instructions that the agent can discover and use.

Instead of MCP servers, Pi expects you to build CLI tools with READMEs (or Skills) and extensions. The philosophy is that the overhead of MCP is unnecessary when a well-structured CLI tool plus its documentation provides the same capability.

Context Files: Auto-Loaded Project Knowledge

Pi automatically loads AGENTS.md and CLAUDE.md files from the current working directory up through parent directories, plus a global location. This means the agent picks up project-specific conventions, coding standards, and instructions without any explicit configuration.

TUI: Differential Rendering

The terminal UI in packages/tui/ is not just another blessed/inquirer wrapper. It implements a custom differential rendering engine:

Web UI: Lit Components, Artifacts, and JS REPL

The @mariozechner/pi-web-ui package (built with Lit and @mariozechner/mini-lit) provides a complete web-based agent interface:

Components

Artifact System

Pi has a full artifact rendering system with types for:

Sandboxed Runtime

SandboxedIframe with runtime providers:

JavaScript REPL

Pi includes a javascriptReplTool that renders an interactive JavaScript REPL in the web UI for tool results. This is unique among coding agents — most just show text output.

Document Extraction

The extractDocumentTool handles PDFs, DOCX, and XLSX files via pdfjs-dist, docx-preview, and xlsx — allowing the agent to read complex document formats.

Storage

IndexedDB backend with stores for sessions, settings, custom providers, and provider keys.

Error Handling and Recovery

Pi's error handling is multi-layered:

Error recovery mechanisms

  • Tool-level errors: Thrown errors in tool execute() are caught by the agent loop and reported to the LLM as isError: true tool results, allowing the model to retry.
  • Abort signals: All tools support AbortSignal. Abort is handled gracefully — tools clean up resources, close temp files, and return partial results.
  • Auto-retry: The session has auto-retry for compaction failures. When context overflow triggers compaction, if compaction fails, the system recovers and retries.
  • Extension error isolation: Extension handlers are wrapped in try/catch. Errors emit via emitError() to registered listeners but do not crash the agent.
  • Process tree cleanup: Bash tool kills entire process trees on abort/timeout, preventing orphaned processes.

How Pi Compares to Other Agents

Feature Pi Mono Claude Code Crush Qwen Code
Primary Language TypeScript TypeScript (Bun) Go TypeScript
Tool Protocol JSON Function Calling (TypeBox) MCP (JSON-RPC) JSON Function Calling JSON Function Calling
MCP Support ❌ Deliberately absent (extensions can add) ✅ Native, core feature ✅ Instruction injection ✅ Lifecycle management
Sub-Agents ❌ Via extensions/Pi Packages only ✅ Built-in ❌ Not present ✅ Built-in
Permissions ❌ Via extensions only ✅ Built-in system ✅ Built-in ✅ Built-in
Session Format Tree-structured JSONL (v3) Proprietary Proprietary Proprietary
File Editing Precise text replacement (multi-edit) Diffs Diffs Diffs
Extensibility Extensions + Skills + Pi Packages Limited Limited Extensions
Model Count 26 providers (10 APIs) Anthropic only Multiple Multiple
Run Modes 4 (TUI, Print, RPC, SDK) TUI TUI TUI
TUI Rendering Differential (changed cells only) React/Ink Custom Go TUI Ink
Web UI ✅ Lit components, artifacts, JS REPL
Package System ✅ Pi Packages (npm/git)
License MIT Proprietary MIT Apache 2.0

Strengths and Weaknesses

Strengths

  • Minimalist philosophy: Ships only what is necessary, everything else is opt-in via extensions, skills, or Pi Packages.
  • Tree-structured sessions: Unique branching/forking within single JSONL files with v3 format, labels, and compaction tracking.
  • Four run modes: Interactive TUI, print, RPC, and SDK — the most flexible deployment options in this set.
  • Precise text editing: Non-overlapping edits with fuzzy matching, uniqueness validation, and multi-edit per call.
  • 26 model providers: Genuinely provider-agnostic across 10 API implementations, from Anthropic to Bedrock to Xiaomi MiMo.
  • Differential TUI: Only redraws changed cells at 60fps — the most efficient terminal rendering in this set.
  • Pi Packages: Shareable bundles installable via npm/git create a genuine extension ecosystem.
  • Parallel tool execution: Tools run concurrently by default, with sequential option.
  • Steering/followup queues: Real-time message interruption without breaking the agent loop.
  • Open source (MIT): Fully auditable code, no proprietary components.
  • Web UI with artifacts: Full artifact system with sandboxed iframes, JS REPL, and document extraction.
  • File mutation queue: Per-file locking prevents concurrent write conflicts.
  • Auth with file locking: Multi-instance safe credential storage.

Weaknesses

  • No built-in permissions: Must build your own or run in a container — not ideal for production out-of-the-box.
  • No MCP: Deliberate choice, but means interoperability with MCP servers requires custom extensions.
  • No sub-agents: Cannot delegate work to child agents natively.
  • Only 7 core tools: Minimal built-in tool set compared to Claude Code's 40+ or Wintermolt's 16+.
  • Smaller ecosystem: Fewer pre-built extensions and packages compared to Claude Code or OpenHands.
  • Learning curve: Extension-first approach means more upfront work to reach feature parity with other agents.
  • Node.js dependency: Requires Node.js 20+ (or Bun), unlike Go or Zig agents that compile to native binaries.

Key Files to Read

Component Path What to Look For
Tool definitions packages/coding-agent/src/core/tools/*.ts TypeBox schemas, execute/render methods
Edit diff logic packages/coding-agent/src/core/tools/edit-diff.ts Non-overlapping edits, fuzzy matching, reverse-order application
Bash execution packages/coding-agent/src/core/tools/bash.ts Streaming, rolling buffer, process tree killing, temp file fallback
File mutation queue packages/coding-agent/src/core/tools/file-mutation-queue.ts Per-file locking for concurrent safety
Agent loop packages/agent/src/agent-loop.ts Parallel execution, steering/followup queues, event system
Model registry packages/ai/src/providers/models.generated.ts 14,278 lines of auto-generated model definitions
Model resolver packages/coding-agent/src/core/model-resolver.ts Glob patterns, alias resolution, thinking levels, ambiguity rejection
Extension types packages/coding-agent/src/core/extensions/types.ts 20+ event definitions, ExtensionAPI interface
Extension runner packages/coding-agent/src/core/extensions/runner.ts Extension lifecycle management
Agent session packages/coding-agent/src/core/agent-session.ts JSONL tree structure, compaction, fork, v3 format
TUI rendering packages/tui/src/tui.ts Differential rendering, 16ms throttle, Kitty graphics
Interactive mode packages/coding-agent/src/modes/interactive/interactive-mode.ts TUI setup, component wiring
RPC mode packages/coding-agent/src/modes/rpc/rpc-mode.ts JSONL protocol implementation
Auth storage packages/coding-agent/src/core/auth.ts File locking, 0o600 permissions, multi-instance safety
Web UI artifacts packages/web-ui/src/tools/artifacts/ HtmlArtifact, ImageArtifact, sandboxed iframes, runtime providers
JS REPL packages/web-ui/src/tools/javascript-repl.ts Interactive JavaScript REPL for web UI

Fresh Repo Snapshot

The fresh repo snapshot makes Pi's direction clearer than older versions of this page did: keep the core small, grow the provider surface, and let extensions or packages own the rest.

Version 0.73.0

The current CLI package is @mariozechner/pi-coding-agent at 0.73.0, not the older 0.66.x line this page previously described.

26 providers

Provider breadth has grown materially. The README now lists 26 built-in providers across subscriptions and API keys, while still routing through only 10 underlying API implementations.

Five-package monorepo

The current packages/ directory is leaner than older summaries: agent, ai, coding-agent, tui, and web-ui are the live packages in this checkout.

Prompt and tool compatibility work

Recent Pi work adds prompt-template depth, provider expansion, OAuth flows, and cross-agent tool-name normalization rather than bolting on MCP or a built-in subagent framework.

Final Verdict

Who is Pi Mono for?

Pi Mono is for developers who want a clean, minimalist coding agent that they can extend to match their exact workflow. It is the anti-Claude-Code: instead of shipping with every feature baked in, it ships a razor-sharp kernel and expects you to build the rest.

If you value simplicity, extensibility, and open-source transparency, Pi is compelling. The differential TUI, tree-structured sessions, parallel tool execution, and Pi Packages system show genuine engineering depth beneath the minimalist surface.

If you want out-of-the-box permissions, MCP interoperability, and sub-agent delegation, you will need to build those yourself — or choose Claude Code, OpenHands, or DeerFlow instead.

The extension system is powerful enough to recreate any missing feature. The question is not whether Pi can do something — it is whether you want to build it yourself. For many developers, that is exactly the point.