# Changelog ## [Unreleased] ### Added - Added animated spinner for task tool progress display during subagent execution - Added language/file type icons for read tool output with support for 35+ file types - Added async cleanup registry for graceful session flush on SIGINT, SIGTERM, and SIGHUP signals - Added subagent token usage aggregation to session statistics and task tool results - Added streaming NDJSON writer for session persistence with proper backpressure handling - Added `flush()` method to SessionManager for explicit control over pending write completion - Added `/exit` slash command to exit the application from interactive mode - Added fuzzy path matching suggestions when read tool encounters file-not-found errors, showing closest matches using Levenshtein distance - Added `status.shadowed` symbol for theme customization to properly indicate shadowed extension state - Added Biome CLI-based linter client as alternative to LSP for more reliable diagnostics - Added LinterClient interface for pluggable formatter/linter implementations - Added status line segment editor for arranging and toggling status line components - Added status line presets (default, minimal, compact, developer, balanced) for quick configuration - Added status line separator styles (powerline, powerline-thin, arrow, slash, pipe, space) - Added configurable status line segments including time, hostname, and subagent count - Added symbol customization via theme overrides for icons, separators, and glyphs - Added 30+ built-in color themes including Catppuccin, Dracula, Nord, Gruvbox, Tokyo Night, and more - Added configurable status line with customizable segments, presets, and separators - Added status line segment editor for arranging and toggling status line components - Added symbol preset setting to switch between Unicode, Nerd Font, and ASCII glyphs - Added file size limit (20MB) for image files to prevent memory issues during serialization ### Changed - Changed `SessionManager.open()` and `SessionManager.continueRecent()` to async methods for proper initialization - Changed session file writes to use atomic rename pattern with fsync for crash-safe persistence - Changed read tool display to show file type icons and metadata inline with path - Changed `AgentSession.dispose()` to async method that flushes pending writes before cleanup - Changed read tool result display to hide content by default with expand hint, showing only metadata until expanded - Changed diagnostics display to group messages by file with tree structure and severity icons - Changed diff stats formatting to use colored +/- indicators with slash separators - Changed session persistence to use streaming writes instead of synchronous file appends for better performance - Changed read tool to automatically redirect to ls when given a directory path instead of a file - Changed tool description prompts to be more concise with clearer usage guidelines and structured formatting - Moved tool description prompts from inline strings to external markdown files in `src/prompts/tools/` directory for better maintainability - Changed Exa web search provider from MCP protocol to direct REST API for simpler integration - Changed web search result rendering to handle malformed response data with fallback text display - Changed compaction prompts to preserve tool outputs, command results, and repository state in context summaries - Changed init prompt to include runtime/tooling preferences section and improved formatting guidelines - Changed reviewer prompt to require evidence-backed findings anchored to diff hunks with stricter suggestion block formatting - Changed system prompt to include explicit core behavior guidelines for task completion and progress updates - Changed task prompt to emphasize end-to-end task completion and tool verification - Moved all prompt templates from inline strings to external markdown files in `src/prompts/` directory for better maintainability - Changed tool result renderers to use structured tree layouts with consistent expand hints and truncation indicators - Changed grep, find, and ls tools to show scope path and detailed truncation reasons in output - Changed web search and web fetch result rendering to display structured metadata sections with bounded content previews - Changed task/subagent progress rendering to use badge-style status labels and structured output sections - Changed notebook tool to display cell content preview with line counts - Changed ask tool result to show checkbox-style selection indicators - Changed output tool to include provenance metadata and content previews for retrieved outputs - Changed collapsed tool views to show consistent "Ctrl+O to expand" hints with remaining item counts - Changed Biome integration to use CLI instead of LSP to avoid stale diagnostics issues - Changed hardcoded UI symbols throughout codebase to use theme-configurable glyphs - Changed tree drawing characters to use theme-defined box-drawing symbols - Changed status line rendering to support left/right segment positioning with separators - Changed hardcoded UI symbols to use theme-configurable glyphs throughout the interface - Changed tree drawing characters to use theme-defined box-drawing symbols - Changed CLI image attachments to resize if larger than 2048px (fit within 1920x1080) and convert >2MB images to JPEG ### Removed - Removed custom renderers for ls, find, and grep tools in favor of generic tool display ### Fixed - Fixed session persistence to properly await all queued writes before closing or switching sessions - Fixed session persistence to truncate oversized content blocks before writing to prevent memory exhaustion - Fixed extension list and inspector panel to use correct symbols for disabled and shadowed states instead of reusing unrelated status icons - Fixed token counting for subagent progress to handle different usage object formats (camelCase and snake_case) - Fixed image file handling by adding 20MB size limit to prevent memory issues during serialization - Fixed session persistence to truncate oversized entries before writing JSONL to prevent out-of-memory errors ## [3.14.0] - 2026-01-04 ### Added - Added `getUsageStatistics()` method to SessionManager for tracking cumulative token usage and costs across session messages ### Changed - Changed status line to display usage statistics more efficiently by using centralized session statistics instead of recalculating from entries ## [3.13.1337] - 2026-01-04 ## [3.9.1337] - 2026-01-04 ### Changed - Changed default for `lsp.formatOnWrite` setting from `true` to `false` - Updated status line thinking level display to use emoji icons instead of abbreviated text - Changed auto-compact indicator from "(auto)" text to icon ### Fixed - Fixed status line not updating token counts and cost after starting a new session - Fixed stale diagnostics persisting after file content changes in LSP client ## [3.8.1337] - 2026-01-04 ### Added - Added automatic browser opening after exporting session to HTML - Added automatic browser opening after sharing session as a Gist ### Fixed - Fixed session titles not persisting to file when set before first flush ## [3.7.1337] - 2026-01-04 ### Added - Added `EditMatchError` class for structured error handling in edit operations - Added `utils` module export with `once` and `untilAborted` helper functions - Added in-memory LSP content sync via `syncContent` and `notifySaved` client methods ### Changed - Refactored LSP integration to use writethrough callbacks for edit and write tools, improving performance by syncing content in-memory before disk writes - Simplified FileDiagnosticsResult interface with renamed fields: `diagnostics` → `messages`, `hasErrors` → `errored`, `serverName` → `server` - Session title generation now triggers before sending the first message rather than after agent work begins ### Fixed - Fixed potential text decoding issues in bash executor by using streaming TextDecoder instead of Buffer.toString() ## [3.6.1337] - 2026-01-03 ## [3.5.1337] - 2026-01-03 ### Added - Added session header and footer output in text mode showing version, model, provider, thinking level, and session ID - Added Extension Control Center dashboard accessible via `/extensions` command for unified management of all providers and extensions - Added ability to enable/disable individual extensions with persistent settings - Added three-column dashboard layout with sidebar tree, extension list, and inspector panel - Added fuzzy search filtering for extensions in the dashboard - Added keyboard navigation with Tab to cycle panes, j/k for navigation, Space to toggle, Enter to expand/collapse ### Changed - Redesigned Extension Control Center from 3-column layout to tabbed interface with horizontal provider tabs and 2-column grid - Replaced sidebar tree navigation with provider tabs using TAB/Shift+TAB cycling ### Fixed - Fixed title generation flag not resetting when starting a new session ## [3.4.1337] - 2026-01-03 ### Added - Added Time Traveling Stream Rules (TTSR) feature that monitors agent output for pattern matches and injects rule reminders mid-stream - Added `ttsr_trigger` frontmatter field for rules to define regex patterns that trigger mid-stream injection - Added TTSR settings for enabled state, context mode (keep/discard partial output), and repeat mode (once/after-gap) ### Fixed - Fixed excessive subprocess spawns by caching git status for 1 second in the footer component ## [3.3.1337] - 2026-01-03 ### Changed - Improved `/status` command output formatting to use consistent column alignment across all sections - Updated version update notification to suggest `omp update` instead of manual npm install command ## [3.1.1337] - 2026-01-03 ### Added - Added `spawns` frontmatter field for agent definitions to control which sub-agents can be spawned - Added spawn restriction enforcement preventing agents from spawning unauthorized sub-agents ### Fixed - Fixed duplicate skill loading when the same SKILL.md file was discovered through multiple paths ## [3.0.1337] - 2026-01-03 ### Added - Added unified capability-based discovery system for loading configuration from multiple AI coding tools (Claude Code, Cursor, Windsurf, Gemini, Codex, Cline, GitHub Copilot, VS Code) - Added support for discovering MCP servers, rules, skills, hooks, tools, slash commands, prompts, and context files from tool-specific config directories - Added Discovery settings tab in interactive mode to enable/disable individual configuration providers - Added provider source attribution showing which tool contributed each configuration item - Added support for Cursor MDC rule format with frontmatter (description, globs, alwaysApply) - Added support for Windsurf rules from .windsurf/rules/*.md and global_rules.md - Added support for Cline rules from .clinerules file or directory - Added support for GitHub Copilot instructions with applyTo glob patterns - Added support for Gemini extensions and system.md customization files - Added support for Codex AGENTS.md and config.toml settings - Added automatic migration of `PI_*` environment variables to `OMP_*` equivalents for backwards compatibility - Added multi-path config discovery supporting `.omp`, `.pi`, and `.claude` directories with priority ordering - Added `getConfigDirPaths()`, `findConfigFile()`, and `readConfigFile()` functions for unified config resolution - Added documentation for config module usage patterns ### Changed - Changed MCP tool name parsing to use last underscore separator for better server name handling - Changed /config output to show provider attribution for discovered items - Renamed CLI binary from `pi` to `omp` and updated all command references - Changed config directory from `.pi` to `.omp` with fallback support for legacy paths - Renamed environment variables from `PI_*` to `OMP_*` prefix (e.g., `OMP_SMOL_MODEL`, `OMP_SLOW_MODEL`) - Changed model role alias prefix from `pi/` to `omp/` (e.g., `omp/slow` instead of `pi/slow`) ## [2.3.1337] - 2026-01-03 ## [2.2.1337] - 2026-01-03 ## [2.1.1337] - 2026-01-03 ### Added - Added `omp update` command to check for and install updates from GitHub releases or via bun ### Changed - Changed HTML export to use compile-time bundled templates via Bun macros for improved performance - Changed `exportToHtml` and `exportFromFile` functions to be async - Simplified build process by embedding assets (themes, templates, agents, commands) directly into the binary at compile time - Removed separate asset copying steps from build scripts ## [2.0.1337] - 2026-01-03 ### Added - Added shell environment snapshot to preserve user aliases, functions, and shell options when executing bash commands - Added support for `OMP_BASH_NO_CI`, `OMP_BASH_NO_LOGIN`, and `OMP_SHELL_PREFIX` environment variables for shell customization - Added zsh support alongside bash for shell detection and configuration ### Changed - Changed shell detection to prefer user's `$SHELL` when it's bash or zsh, with improved fallback path resolution - Changed Edit tool to reject `.ipynb` files with guidance to use NotebookEdit tool instead ## [1.500.0] - 2026-01-03 ### Added - Added provider tabs to model selector with Tab/Arrow navigation for filtering models by provider - Added context menu to model selector for choosing model role (Default, Smol, Slow) instead of keyboard shortcuts - Added LSP diagnostics display in tool execution output showing errors and warnings after file edits - Added centralized file logger with daily rotation to `~/.omp/logs/` for debugging production issues - Added `logger` property to hook and custom tool APIs for error/warning/debug logging - Added `output` tool to read full agent/task outputs by ID when truncated previews are insufficient - Added `task` tool to reviewer agent, enabling parallel exploration of large codebases during reviews - Added subprocess tool registry for extracting and rendering tool data from subprocess agents in real-time - Added combined review result rendering showing verdict and findings in a tree structure - Auto-read file mentions: Reference files with `@path/to/file.ext` syntax in prompts to automatically inject their contents, eliminating manual Read tool calls - Added `hidden` property for custom tools to exclude them from default tool list unless explicitly requested - Added `explicitTools` option to `createAgentSession` for enabling hidden tools by name - Added example review tools (`report_finding`, `submit_review`) with structured findings accumulation and verdict rendering - Added `/review` example command for interactive code review with branch comparison, uncommitted changes, and commit review modes - Custom TypeScript slash commands: Create programmable commands at `~/.omp/agent/commands/[name]/index.ts` or `.omp/commands/[name]/index.ts`. Commands export a factory returning `{ name, description, execute(args, ctx) }`. Return a string to send as LLM prompt, or void for fire-and-forget actions. Full access to `HookCommandContext` for UI dialogs, session control, and shell execution. - Claude command directories: Markdown slash commands now also load from `~/.claude/commands/` and `.claude/commands/` (parallel to existing `.omp/commands/` support) - `commands.enableClaudeUser` and `commands.enableClaudeProject` settings to disable Claude command directory loading - `/export --copy` option to copy entire session as formatted text to clipboard ### Changed - Changed model selector keyboard shortcuts from S/L keys to a context menu opened with Enter - Changed model role indicators from symbols (✓ ⚡ 🧠) to labeled badges ([ DEFAULT ] [ SMOL ] [ SLOW ]) - Changed model list sorting to include secondary sort by model ID within each provider - Changed silent error suppression to log warnings and debug info for tool errors, theme loading, and command loading failures - Changed Task tool progress display to show agent index (e.g., `reviewer(0)`) for easier Output tool ID derivation - Changed Task tool output to only include file paths when Output tool is unavailable, providing Read tool fallback - Changed Task tool output references to use simpler ID format (e.g., `reviewer_0`) with line/char counts for Output tool integration - Changed subagent recursion prevention from blanket blocking to same-agent blocking. Non-recursive agents can now spawn other agent types (e.g., reviewer can spawn explore agents) but cannot spawn themselves. - Changed `/review` command from markdown to interactive TypeScript with mode selection menu (branch comparison, uncommitted changes, commit review, custom) - Changed bundled commands to be overridable by user/project commands with same name - Changed subprocess termination to wait for message_end event to capture accurate token counts - Changed token counting in subprocess to accumulate across messages instead of overwriting - Updated bundled `reviewer` agent to use structured review tools with priority-based findings (P0-P3) and formal verdict submission - Task tool now streams artifacts in real-time: input written before spawn, session jsonl written by subprocess, output written at completion ### Removed - Removed separate Exa error logger in favor of centralized logging system - Removed `findings_count` parameter from `submit_review` tool - findings are now counted automatically - Removed artifacts location display from task tool output ### Fixed - Fixed race condition in event listener iteration by copying array before iteration to prevent mutation during callbacks - Fixed potential memory leak from orphaned abort controllers by properly aborting existing controllers before replacement - Fixed stream reader resource leak by adding proper `releaseLock()` calls in finally blocks - Fixed hook API methods throwing clear errors when handlers are not initialized instead of silently failing - Fixed LSP client race conditions with concurrent client creation and file operations using proper locking - Fixed Task tool progress display showing stale data by cloning progress objects before passing to callbacks - Fixed Task tool missing final progress events by waiting for readline to close before resolving - Fixed RPC mode race condition with concurrent prompt commands by serializing execution - Fixed pre-commit hook race condition causing `index.lock` errors when GitKraken/IDE git integrations detect file changes during formatting - Fixed Task tool output artifacts (`out.md`) containing duplicated text from streaming updates - Fixed Task tool progress display showing repeated nearly-identical lines during streaming - Fixed Task tool subprocess model selection ignoring agent's configured model and falling back to settings default. The `--model` flag now accepts `provider/model` format directly. - Fixed Task tool showing "done + succeeded" when aborted; now correctly displays "⊘ aborted" status ## [1.341.0] - 2026-01-03 ### Added - Added interruptMode setting to control when queued messages are processed during tool execution. - Implemented getter and setter methods in SettingsManager for interrupt mode persistence. - Exposed interruptMode configuration in interactive settings UI with immediate/wait options. - Wired interrupt mode through AgentSession and SDK to enable runtime configuration. - Model roles: Configure different models for different purposes (default, smol, slow) via `/model` selector - Model selector key bindings: Enter sets default, S sets smol, L sets slow, Escape closes - Model selector shows role markers: ✓ for default, ⚡ for smol, 🧠 for slow - `pi/` model aliases in Task tool agent definitions (e.g., `model: pi/smol, haiku, flash, mini`) - Smol model auto-discovery using priority chain: haiku > flash > mini - Slow model auto-discovery using priority chain: gpt-5.2-codex > codex > gpt > opus > pro - CLI args for model roles: `--smol ` and `--slow ` (ephemeral, not persisted) - Env var overrides: `OMP_SMOL_MODEL` and `OMP_SLOW_MODEL` - Title generation now uses configured smol model from settings - LSP diagnostics on edit: Edit tool can now return LSP diagnostics after editing code files. Disabled by default to avoid noise during multi-edit sequences. Enable via `lsp.diagnosticsOnEdit` setting. - LSP workspace diagnostics: New `lsp action=workspace_diagnostics` command checks the entire project for errors. Auto-detects project type and uses appropriate checker (rust-analyzer/cargo for Rust, tsc for TypeScript, go build for Go, pyright for Python). - LSP local binary resolution: LSP servers installed in project-local directories are now discovered automatically. Checks `node_modules/.bin/` for Node.js projects, `.venv/bin/`/`venv/bin/` for Python projects, and `vendor/bundle/bin/` for Ruby projects before falling back to `$PATH`. - LSP format on write: Write tool now automatically formats code files using LSP after writing. Uses the language server's built-in formatter (e.g., rustfmt for Rust, gofmt for Go). Controlled via `lsp.formatOnWrite` setting (enabled by default). - LSP diagnostics on write: Write tool now returns LSP diagnostics (errors/warnings) after writing code files. This gives immediate feedback on syntax errors and type issues. Controlled via `lsp.diagnosticsOnWrite` setting (enabled by default). - LSP server warmup at startup: LSP servers are now started at launch to avoid cold-start delays when first writing files. - LSP server status in welcome banner: Shows which language servers are active and ready. - Edit fuzzy match setting: Added `edit.fuzzyMatch` setting (enabled by default) to control whether the edit tool accepts high-confidence fuzzy matches for whitespace/indentation differences. Toggle via `/settings`. - Multi-server LSP diagnostics: Diagnostics now query all applicable language servers for a file type. For TypeScript/JavaScript projects with Biome, this means both type errors (from tsserver) and lint errors (from Biome) are reported together. - Comprehensive LSP server configurations for 40+ languages including Rust, Go, Python, Java, Kotlin, Scala, Haskell, OCaml, Elixir, Ruby, PHP, C#, Lua, Nix, and many more. Each server includes sensible defaults for args, settings, and init options. - Extended LSP config file search paths: Now searches for `lsp.json`, `.lsp.json` in project root and `.omp/` subdirectory, plus user-level configs in `~/.omp/` and home directory. ### Changed - LSP settings moved to dedicated "LSP" tab in `/settings` for better organization - Improved grep tool description to document pagination options (`headLimit`, `offset`) and clarify recursive search behavior - LSP idle timeout now disabled by default. Configure via `idleTimeoutMs` in lsp.json to auto-shutdown inactive servers. - Model settings now use role-based storage (`modelRoles` map) instead of single `defaultProvider`/`defaultModel` fields. Supports multiple model roles (default, small, etc.) - Session model persistence now uses `"provider/modelId"` string format with optional role field ### Fixed - Recent sessions now show in welcome banner (was never wired up). - Auto-generated session titles: Sessions are now automatically titled based on the first message using a small model (Haiku/GPT-4o-mini/Flash). Titles are shown in the terminal window title, recent sessions list, and --resume picker. The resume picker shows title with dimmed first message preview below. ## [1.340.0] - 2026-01-03 ### Changed - Replaced vendored highlight.js and marked.js with CDN-hosted versions for smaller exports - Added runtime minification for HTML, CSS, and JS in session exports - Session share URL now uses gistpreview.github.io instead of shittycodingagent.ai ## [1.339.0] - 2026-01-03 ### Added - MCP project config setting to disable loading `.mcp.json`/`mcp.json` from project root - Support for both `mcp.json` and `.mcp.json` filenames (prefers `mcp.json` if both exist) - Automatic Exa MCP server filtering with API key extraction for native integration ## [1.338.0] - 2026-01-03 ### Added - Bash interceptor setting to block shell commands that have dedicated tools (disabled by default, enable via `/settings`) ### Changed - Refactored settings UI to declarative definitions for easier maintenance - Shell detection now respects `$SHELL` environment variable before falling back to bash/sh - Tool binary detection now uses `Bun.which()` instead of spawning processes ### Fixed - CLI help text now accurately lists all default tools ## [1.337.1] - 2026-01-02 ### Added - MCP support and plugin system for external tool integration - Git context to system prompt for repo awareness - Bash interception to guide tool selection - Fuzzy matching to handle indentation variance in edit tool - Specialized Exa tools with granular toggles - `/share` command for exporting conversations to HTML - Edit diff preview before tool execution ### Changed - Renamed package scope to @oh-my-pi for consistent branding - Simplified toolset and enhanced navigation - Improved process cleanup with tree kill - Updated CI/CD workflows for GitHub Actions with provenance-signed npm publishing ### Fixed - Template string interpolation in image read output - Prevented full re-renders during write tool streaming - Edit tool failing on files with UTF-8 BOM ## [1.337.0] - 2026-01-02 Initial release under @oh-my-pi scope. See previous releases at [badlogic/pi-mono](https://github.com/badlogic/pi-mono). ## [0.31.1] - 2026-01-02 ### Fixed - Model selector no longer allows negative index when pressing arrow keys before models finish loading ([#398](https://github.com/badlogic/pi-mono/pull/398) by [@mitsuhiko](https://github.com/mitsuhiko)) - Type guard functions (`isBashToolResult`, etc.) now exported at runtime, not just in type declarations ([#397](https://github.com/badlogic/pi-mono/issues/397)) ## [0.31.0] - 2026-01-02 This release introduces session trees for in-place branching, major API changes to hooks and custom tools, and structured compaction with file tracking. ### Session Tree Sessions now use a tree structure with `id`/`parentId` fields. This enables in-place branching: navigate to any previous point with `/tree`, continue from there, and switch between branches while preserving all history in a single file. **Existing sessions are automatically migrated** (v1 → v2) on first load. No manual action required. New entry types: `BranchSummaryEntry` (context from abandoned branches), `CustomEntry` (hook state), `CustomMessageEntry` (hook-injected messages), `LabelEntry` (bookmarks). See [docs/session.md](docs/session.md) for the file format and `SessionManager` API. ### Hooks Migration The hooks API has been restructured with more granular events and better session access. **Type renames:** - `HookEventContext` → `HookContext` - `HookCommandContext` is now a new interface extending `HookContext` with session control methods **Event changes:** - The monolithic `session` event is now split into granular events: `session_start`, `session_before_switch`, `session_switch`, `session_before_branch`, `session_branch`, `session_before_compact`, `session_compact`, `session_shutdown` - `session_before_switch` and `session_switch` events now include `reason: "new" | "resume"` to distinguish between `/new` and `/resume` - New `session_before_tree` and `session_tree` events for `/tree` navigation (hook can provide custom branch summary) - New `before_agent_start` event: inject messages before the agent loop starts - New `context` event: modify messages non-destructively before each LLM call - Session entries are no longer passed in events. Use `ctx.sessionManager.getEntries()` or `ctx.sessionManager.getBranch()` instead **API changes:** - `pi.send(text, attachments?)` → `pi.sendMessage(message, triggerTurn?)` (creates `CustomMessageEntry`) - New `pi.appendEntry(customType, data?)` for hook state persistence (not in LLM context) - New `pi.registerCommand(name, options)` for custom slash commands (handler receives `HookCommandContext`) - New `pi.registerMessageRenderer(customType, renderer)` for custom TUI rendering - New `ctx.isIdle()`, `ctx.abort()`, `ctx.hasQueuedMessages()` for agent state (available in all events) - New `ctx.ui.editor(title, prefill?)` for multi-line text editing with Ctrl+G external editor support - New `ctx.ui.custom(component)` for full TUI component rendering with keyboard focus - New `ctx.ui.setStatus(key, text)` for persistent status text in footer (multiple hooks can set their own) - New `ctx.ui.theme` getter for styling text with theme colors - `ctx.exec()` moved to `pi.exec()` - `ctx.sessionFile` → `ctx.sessionManager.getSessionFile()` - New `ctx.modelRegistry` and `ctx.model` for API key resolution **HookCommandContext (slash commands only):** - `ctx.waitForIdle()` - wait for agent to finish streaming - `ctx.newSession(options?)` - create new sessions with optional setup callback - `ctx.branch(entryId)` - branch from a specific entry - `ctx.navigateTree(targetId, options?)` - navigate the session tree These methods are only on `HookCommandContext` (not `HookContext`) because they can deadlock if called from event handlers that run inside the agent loop. **Removed:** - `hookTimeout` setting (hooks no longer have timeouts; use Ctrl+C to abort) - `resolveApiKey` parameter (use `ctx.modelRegistry.getApiKey(model)`) See [docs/hooks.md](docs/hooks.md) and [examples/hooks/](examples/hooks/) for the current API. ### Custom Tools Migration The custom tools API has been restructured to mirror the hooks pattern with a context object. **Type renames:** - `CustomAgentTool` → `CustomTool` - `ToolAPI` → `CustomToolAPI` - `ToolContext` → `CustomToolContext` - `ToolSessionEvent` → `CustomToolSessionEvent` **Execute signature changed:** ```typescript // Before (v0.30.2) execute(toolCallId, params, signal, onUpdate) // After execute(toolCallId, params, onUpdate, ctx, signal?) ``` The new `ctx: CustomToolContext` provides `sessionManager`, `modelRegistry`, `model`, and agent state methods: - `ctx.isIdle()` - check if agent is streaming - `ctx.hasQueuedMessages()` - check if user has queued messages (skip interactive prompts) - `ctx.abort()` - abort current operation (fire-and-forget) **Session event changes:** - `CustomToolSessionEvent` now only has `reason` and `previousSessionFile` - Session entries are no longer in the event. Use `ctx.sessionManager.getBranch()` or `ctx.sessionManager.getEntries()` to reconstruct state - Reasons: `"start" | "switch" | "branch" | "tree" | "shutdown"` (no separate `"new"` reason; `/new` triggers `"switch"`) - `dispose()` method removed. Use `onSession` with `reason: "shutdown"` for cleanup See [docs/custom-tools.md](docs/custom-tools.md) and [examples/custom-tools/](examples/custom-tools/) for the current API. ### SDK Migration **Type changes:** - `CustomAgentTool` → `CustomTool` - `AppMessage` → `AgentMessage` - `sessionFile` returns `string | undefined` (was `string | null`) - `model` returns `Model | undefined` (was `Model | null`) - `Attachment` type removed. Use `ImageContent` from `@oh-my-pi/pi-ai` instead. Add images directly to message content arrays. **AgentSession API:** - `branch(entryIndex: number)` → `branch(entryId: string)` - `getUserMessagesForBranching()` returns `{ entryId, text }` instead of `{ entryIndex, text }` - `reset()` → `newSession(options?)` where options has optional `parentSession` for lineage tracking - `newSession()` and `switchSession()` now return `Promise` (false if cancelled by hook) - New `navigateTree(targetId, options?)` for in-place tree navigation **Hook integration:** - New `sendHookMessage(message, triggerTurn?)` for hook message injection **SessionManager API:** - Method renames: `saveXXX()` → `appendXXX()` (e.g., `appendMessage`, `appendCompaction`) - `branchInPlace()` → `branch()` - `reset()` → `newSession(options?)` with optional `parentSession` for lineage tracking - `createBranchedSessionFromEntries(entries, index)` → `createBranchedSession(leafId)` - `SessionHeader.branchedFrom` → `SessionHeader.parentSession` - `saveCompaction(entry)` → `appendCompaction(summary, firstKeptEntryId, tokensBefore, details?)` - `getEntries()` now excludes the session header (use `getHeader()` separately) - `getSessionFile()` returns `string | undefined` (undefined for in-memory sessions) - New tree methods: `getTree()`, `getBranch()`, `getLeafId()`, `getLeafEntry()`, `getEntry()`, `getChildren()`, `getLabel()` - New append methods: `appendCustomEntry()`, `appendCustomMessageEntry()`, `appendLabelChange()` - New branch methods: `branch(entryId)`, `branchWithSummary()` **ModelRegistry (new):** `ModelRegistry` is a new class that manages model discovery and API key resolution. It combines built-in models with custom models from `models.json` and resolves API keys via `AuthStorage`. ```typescript import { discoverAuthStorage, discoverModels } from "@oh-my-pi/pi-coding-agent"; const authStorage = discoverAuthStorage(); // ~/.omp/agent/auth.json const modelRegistry = discoverModels(authStorage); // + ~/.omp/agent/models.json // Get all models (built-in + custom) const allModels = modelRegistry.getAll(); // Get only models with valid API keys const available = await modelRegistry.getAvailable(); // Find specific model const model = modelRegistry.find("anthropic", "claude-sonnet-4-20250514"); // Get API key for a model const apiKey = await modelRegistry.getApiKey(model); ``` This replaces the old `resolveApiKey` callback pattern. Hooks and custom tools access it via `ctx.modelRegistry`. **Renamed exports:** - `messageTransformer` → `convertToLlm` - `SessionContext` alias `LoadedSession` removed See [docs/sdk.md](docs/sdk.md) and [examples/sdk/](examples/sdk/) for the current API. ### RPC Migration **Session commands:** - `reset` command → `new_session` command with optional `parentSession` field **Branching commands:** - `branch` command: `entryIndex` → `entryId` - `get_branch_messages` response: `entryIndex` → `entryId` **Type changes:** - Messages are now `AgentMessage` (was `AppMessage`) - `prompt` command: `attachments` field replaced with `images` field using `ImageContent` format **Compaction events:** - `auto_compaction_start` now includes `reason` field (`"threshold"` or `"overflow"`) - `auto_compaction_end` now includes `willRetry` field - `compact` response includes full `CompactionResult` (`summary`, `firstKeptEntryId`, `tokensBefore`, `details`) See [docs/rpc.md](docs/rpc.md) for the current protocol. ### Structured Compaction Compaction and branch summarization now use a structured output format: - Clear sections: Goal, Progress, Key Information, File Operations - File tracking: `readFiles` and `modifiedFiles` arrays in `details`, accumulated across compactions - Conversations are serialized to text before summarization to prevent the model from "continuing" them The `before_compact` and `before_tree` hook events allow custom compaction implementations. See [docs/compaction.md](docs/compaction.md). ### Interactive Mode **`/tree` command:** - Navigate the full session tree in-place - Search by typing, page with ←/→ - Filter modes (Ctrl+O): default → no-tools → user-only → labeled-only → all - Press `l` to label entries as bookmarks - Selecting a branch switches context and optionally injects a summary of the abandoned branch **Entry labels:** - Bookmark any entry via `/tree` → select → `l` - Labels appear in tree view and persist as `LabelEntry` **Theme changes (breaking for custom themes):** Custom themes must add these new color tokens or they will fail to load: - `selectedBg`: background for selected/highlighted items in tree selector and other components - `customMessageBg`: background for hook-injected messages (`CustomMessageEntry`) - `customMessageText`: text color for hook messages - `customMessageLabel`: label color for hook messages (the `[customType]` prefix) Total color count increased from 46 to 50. See [docs/theme.md](docs/theme.md) for the full color list and copy values from the built-in dark/light themes. **Settings:** - `enabledModels`: allowlist models in `settings.json` (same format as `--models` CLI) ### Added - `ctx.ui.setStatus(key, text)` for hooks to display persistent status text in the footer ([#385](https://github.com/badlogic/pi-mono/pull/385) by [@prateekmedia](https://github.com/prateekmedia)) - `ctx.ui.theme` getter for styling status text and other output with theme colors - `/share` command to upload session as a secret GitHub gist and get a shareable URL via shittycodingagent.ai ([#380](https://github.com/badlogic/pi-mono/issues/380)) - HTML export now includes a tree visualization sidebar for navigating session branches ([#375](https://github.com/badlogic/pi-mono/issues/375)) - HTML export supports keyboard shortcuts: Ctrl+T to toggle thinking blocks, Ctrl+O to toggle tool outputs - HTML export supports theme-configurable background colors via optional `export` section in theme JSON ([#387](https://github.com/badlogic/pi-mono/pull/387) by [@mitsuhiko](https://github.com/mitsuhiko)) - HTML export syntax highlighting now uses theme colors and matches TUI rendering - **Snake game example hook**: Demonstrates `ui.custom()`, `registerCommand()`, and session persistence. See [examples/hooks/snake.ts](examples/hooks/snake.ts). - **`thinkingText` theme token**: Configurable color for thinking block text. ([#366](https://github.com/badlogic/pi-mono/pull/366) by [@paulbettner](https://github.com/paulbettner)) ### Changed - **Entry IDs**: Session entries now use short 8-character hex IDs instead of full UUIDs - **API key priority**: `ANTHROPIC_OAUTH_TOKEN` now takes precedence over `ANTHROPIC_API_KEY` - HTML export template split into separate files (template.html, template.css, template.js) for easier maintenance ### Fixed - HTML export now properly sanitizes user messages containing HTML tags like `