AI Coding Guides Deep Dives
Deep Dive • v0.66.1+ • TypeScript/Node 20+ • MIT • 26 Providers • Updated April 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.66.1) is a TypeScript-based coding agent CLI created by Mario Zechner (badlogic). It lives in a monorepo with six sibling packages, all at the same version and under the MIT license:

PackageNameWhat it does
coding-agent@mariozechner/pi-coding-agentThe core CLI — tool definitions, mode entry points, extension loading
ai@mariozechner/pi-aiUnified multi-provider LLM API — 24 providers, 10 API implementations
agent@mariozechner/pi-agent-coreAgent runtime — agent loop, transcript management, event system
tui@mariozechner/pi-tuiDifferential terminal UI engine — only redraws changed cells
web-ui@mariozechner/pi-web-uiWeb components (Lit) — chat panel, artifacts, sandboxed iframes, JS REPL
mom@mariozechner/pi-momSlack bot — delegates to pi agent with sandbox (host or Docker)
pods@mariozechner/pivLLM pod manager — SSH GPU provisioning, model start/stop on remote pods

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:

ToolCategoryDetails
readCodingRead file with configurable max lines/bytes, truncation notices
bashCodingShell execution with streaming output, process tree killing, 10MB stdout/stderr cap, temp file fallback for overflow
editCodingPrecise text replacement with multiple disjoint edits per call, fuzzy matching, uniqueness validation, reverse-order application
writeCodingWrite entire files, auto-create parent directories, file mutation queue for concurrent safety
grepRead-onlyRegex content search across files
findRead-onlyFile path search by name or pattern
lsRead-onlyDirectory 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: 23 Providers

Pi supports 24 providers via the unified @mariozechner/pi-ai package. The KnownProviders enum lists them all:

#ProviderAPI ImplementationAuth Methods
1anthropicanthropic-messagesAPI key, OAuth (auth.json)
2openaiopenai-completionsAPI key
3googlegoogle-generative-aiAPI key
4google-gemini-cligoogle-gemini-cliOAuth (auth.json)
5google-antigravitygoogle-gemini-cliOAuth (auth.json)
6google-vertexgoogle-vertexGoogle ADC (GOOGLE_APPLICATION_CREDENTIALS)
7azure-openai-responsesazure-openai-responsesAPI key
8openai-codexopenai-codex-responsesAPI key
9github-copilotopenai-completionsOAuth (GitHub token)
10xaiopenai-completionsAPI key
11groqopenai-completionsAPI key
12cerebrasopenai-completionsAPI key
13openrouteropenai-completionsAPI key
14vercel-ai-gatewayopenai-completionsAPI key
15zaiopenai-completionsAPI key
16mistralmistral-conversationsAPI key
17minimaxopenai-completionsAPI key
18minimax-cnopenai-completionsAPI key
19huggingfaceopenai-completionsAPI key
20opencodeopenai-completionsAPI key
21opencode-goopenai-completionsAPI key
22kimi-codingopenai-completionsAPI key
24cloudflare-workers-aiopenai-completionsAPI key + Account ID

Only 10 APIs are actually implemented — the remaining 14 providers reuse compatible API shapes (most use OpenAI-compatible completions, some use Anthropic-compatible).

Model Resolution System

The ModelRegistry manages built-in models (auto-generated in models.generated.ts14,278 lines) 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

CategoryExample EventsWhat Extensions Can Do
Resourceresources_discoverInject custom resources (context files, etc.)
Sessionsession_start, session_before_compact, session_treeModify session state, fork, navigate
Agentbefore_provider_request, message_end, agent_startObserve/modify agent behavior
Tooltool_call, tool_result, beforeToolCallBlock, modify, or augment tool execution
Modelmodel_selectOverride model selection
InputinputTransform or handle user input
Turnturn_start, turn_endPer-turn telemetry, timing
Messagemessage_start, message_update, message_endStream 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.

Sibling Packages: Mom and Pods

mom — Slack Bot

@mariozechner/pi-mom is a Slack bot that delegates messages to the pi coding agent. It uses Anthropic's sandbox runtime (@anthropic-ai/sandbox-runtime) and supports both host and Docker sandbox execution. Features include channel-based store with per-channel memory (MEMORY.md files), Slack file attachment handling (images), and custom tools for Slack upload functionality.

pods — vLLM Pod Manager

@mariozechner/pi (the pods package, confusingly named) is a CLI for managing vLLM deployments on GPU pods. Features include pod setup via SSH with mount commands, vLLM installation (latest release, nightly, or GPT-OSS variant), model start/stop with memory allocation, context window, and GPU count configuration, SSH command execution and shell access, and interactive agent chat with models running on pods. Config is stored in ~/.pi/.

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

FeaturePi MonoClaude CodeCrushQwen Code
Primary LanguageTypeScriptTypeScript (Bun)GoTypeScript
Tool ProtocolJSON Function Calling (TypeBox)MCP (JSON-RPC)JSON Function CallingJSON 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 FormatTree-structured JSONL (v3)ProprietaryProprietaryProprietary
File EditingPrecise text replacement (multi-edit)DiffsDiffsDiffs
ExtensibilityExtensions + Skills + Pi PackagesLimitedLimitedExtensions
Model Count24 providers (10 APIs)Anthropic onlyMultipleMultiple
Run Modes4 (TUI, Print, RPC, SDK)TUITUITUI
TUI RenderingDifferential (changed cells only)React/InkCustom Go TUIInk
Web UI✅ Lit components, artifacts, JS REPL
Package System✅ Pi Packages (npm/git)
LicenseMITProprietaryMITApache 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.
  • 23 model providers: Genuinely provider-agnostic across 10 API implementations, from Anthropic to Bedrock to MiniMax.
  • 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

ComponentPathWhat to Look For
Tool definitionspackages/coding-agent/src/core/tools/*.tsTypeBox schemas, execute/render methods
Edit diff logicpackages/coding-agent/src/core/tools/edit-diff.tsNon-overlapping edits, fuzzy matching, reverse-order application
Bash executionpackages/coding-agent/src/core/tools/bash.tsStreaming, rolling buffer, process tree killing, temp file fallback
File mutation queuepackages/coding-agent/src/core/tools/file-mutation-queue.tsPer-file locking for concurrent safety
Agent looppackages/agent/src/agent-loop.tsParallel execution, steering/followup queues, event system
Model registrypackages/ai/src/providers/models.generated.ts14,278 lines of auto-generated model definitions
Model resolverpackages/coding-agent/src/core/model-resolver.tsGlob patterns, alias resolution, thinking levels, ambiguity rejection
Extension typespackages/coding-agent/src/core/extensions/types.ts20+ event definitions, ExtensionAPI interface
Extension runnerpackages/coding-agent/src/core/extensions/runner.tsExtension lifecycle management
Agent sessionpackages/coding-agent/src/core/agent-session.tsJSONL tree structure, compaction, fork, v3 format
TUI renderingpackages/tui/src/tui.tsDifferential rendering, 16ms throttle, Kitty graphics
Interactive modepackages/coding-agent/src/modes/interactive/interactive-mode.tsTUI setup, component wiring
RPC modepackages/coding-agent/src/modes/rpc/rpc-mode.tsJSONL protocol implementation
Auth storagepackages/coding-agent/src/core/auth.tsFile locking, 0o600 permissions, multi-instance safety
Web UI artifactspackages/web-ui/src/tools/artifacts/HtmlArtifact, ImageArtifact, sandboxed iframes, runtime providers
JS REPLpackages/web-ui/src/tools/javascript-repl.tsInteractive JavaScript REPL for web UI

Updates in This Iteration

Pi Mono received significant updates with ~22,697 insertions and ~5,517 deletions:

New AI Provider Features

The packages/ai package now supports 26 providers across multiple APIs. New features include thinking levels (minimal, low, medium, high, xhigh), cache retention control, and tool name normalization for Claude Code compatibility.

Claude Code Tool Normalization

Added normalizeToolName() to map Claude Code tool names (Read, Write, Edit, Bash, Grep, Glob, etc.) to Pi tool names — enabling cross-agent tool compatibility.

OAuth Authentication

Built-in OAuth flows for Anthropic and GitHub Copilot providers. Streamlines auth setup for these providers.

Prompt Caching

Session-based caching with sessionId support for efficient token usage across related requests.

Cross-Provider Handoffs

Seamless transitions between providers — agents can switch between OpenAI, Anthropic, Google, and other providers mid-conversation.

New Test Coverage

67 test files including new tests for anthropic-eager-tool-input, cache retention, cross-provider handoff, tool name normalization, and thinking disable functionality.

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.