# Changelog ## [Unreleased] ### Added - Added `ToolSession` interface to unify tool creation with session context including cwd, UI availability, and rulebook rules - Added Bun Worker-based execution for subagent tasks, replacing subprocess spawning for improved performance and event streaming - Added `toolNames` option to filter which built-in tools are included in agent sessions - Added `BUILTIN_TOOLS` registry constant for programmatic access to available tool factories - Added unit tests for `createTools` function covering tool filtering and conditional tool creation ### Changed - Changed subagent execution from spawning separate `omp` processes to running in Bun Workers with direct event streaming - Changed tool factories to accept `ToolSession` parameter instead of separate cwd and options arguments - Changed `createTools` to return tools as a Map and support conditional tool creation based on session context - Changed system prompt builder to dynamically generate tool descriptions from the tool registry - Changed task tool description to be generated from a template with dynamic agent list injection - Changed tool creation to use a unified `ToolSession` interface instead of separate parameters for cwd, options, and callbacks - Changed `createTools` to return tools as a Map instead of an array for consistent tool registry access - Changed system prompt builder to receive tool registry Map for dynamic tool description generation - Changed subprocess usage tracking to accumulate incrementally from message_end events rather than parsing stored events after completion ### Removed - Removed `browser` embedded agent from task tool agent discovery - Removed `recursive` property from agent definitions - Removed environment variables `OMP_NO_SUBAGENTS`, `OMP_BLOCKED_AGENT`, and `OMP_SPAWNS` for subagent control - Removed pre-instantiated tool exports (`readTool`, `bashTool`, `editTool`, `writeTool`, `grepTool`, `findTool`, `lsTool`) in favor of factory functions - Removed `createCodingTools` and `createReadOnlyTools` helper functions - Removed `codingTools` and `readOnlyTools` convenience exports - Removed `wrapToolsWithExtensions` function from extensions API - Removed `hidden` property support from custom tools - Removed subagent and question custom tool examples ### Fixed - Fixed memory accumulation in task subprocess by streaming events directly to disk instead of storing in memory - Fixed session persistence to exclude transient streaming data (partialJson, jsonlEvents) that was causing unnecessary storage bloat - Fixed createTools respecting explicit tool lists instead of returning all non-hidden tools ## [3.21.0] - 2026-01-06 ### Changed - Switched from local `@oh-my-pi/pi-ai` to upstream `@mariozechner/pi-ai` package ### Added - Added `webSearchProvider` setting to override auto-detection priority (Exa > Perplexity > Anthropic) - Added `imageProvider` setting to override auto-detection priority (OpenRouter > Gemini) - Added `git.enabled` setting to enable/disable the structured git tool - Added `offset` and `limit` parameters to Output tool for paginated reading of large outputs - Added provider fallback chain for web search that tries all configured providers before failing - Added `WebSearchProviderError` class with HTTP status for actionable provider error messages - Added bash interceptor rule to block git commands when structured git tool is enabled - Added validation requiring `message` parameter for git commit operations (prevents interactive editor) - Added output ID hints in multi-agent Task results pointing to Output tool for full logs - Added fuzzy matching support for `all: true` mode in edit tool, enabling replacement of similar text blocks with whitespace differences - Added `all` parameter to edit tool for replacing all occurrences instead of requiring unique matches - Added OpenRouter support for image generation when `OPENROUTER_API_KEY` is set - Added ImageMagick fallback for image processing when sharp module is unavailable - Added slash commands to the extensions inspector panel for visibility and management - Added support for file-based slash commands from `commands/` directories - Added `$ARGUMENTS` placeholder for slash command argument substitution, aligning with Claude and Codex conventions ### Changed - Refactored tool renderers to be co-located with their respective tool implementations for improved code organization - Changed web search to try all configured providers in sequence with fallback before reporting errors - Changed default Anthropic web search model from `claude-sonnet-4-5-20250514` to `claude-haiku-4-5` - Changed read tool to show first 50KB of oversized lines instead of directing users to bash sed - Changed web_fetch to use `Bun.which()` instead of spawning `which`/`where` for command detection - Changed web_fetch to check Content-Length header before downloading to reject oversized files early - Changed generate_image tool to save images to temp files and report paths instead of inline base64 - Changed system prompt with tool usage guidance (ground answers with tools, minimize context, iterate on results) - Changed Task tool prompt with plan-then-execute guidance and output tool hints - Changed edit tool success message to report count when replacing multiple occurrences with `all: true` - Changed default image generation model to `gemini-3-pro-image-preview` - Changed error message for multiple occurrences to suggest using `all: true` option - Changed web_fetch tool label from `web_fetch` to `Web Fetch` for improved display - Changed argument substitution order in slash commands to process positional args ($1, $2) before wildcards ($@, $ARGUMENTS) to prevent re-substitution issues - Changed image tool name from `gemini_image` to `generate_image` with label `GenerateImage` ### Fixed - Fixed read tool markitdown truncation message using broken template string (missing `${` around format call) - Fixed web_fetch URL normalization order to run before special handlers - Fixed TUI image display for generate_image tool by sourcing images from details.images in addition to content blocks - Fixed context file preview in inspector panel to display content correctly instead of attempting async file reads - Fixed Linux ARM64 installs failing on fresh Debian when the `sharp` module is unavailable during session image compression ## [3.20.1] - 2026-01-06 ### Fixed - Fixed find tool failing to match patterns with path separators (e.g., `reports/**`) by enabling full-path matching in fd ### Changed - Changed multi-task display to show task descriptions instead of agent names when available - Changed ls tool to show relative modification times (e.g., "2d ago", "just now") for each entry ## [3.20.0] - 2026-01-06 ### Added - Added extensions API with auto-discovery (`.omp/extensions`) and `--extension`/`-e` loading for custom tools, commands, and lifecycle hooks - Added prompt templates loaded from global and project `.omp/prompts` directories with `/template` expansion in the input box - Built-in provider overrides in `models.json`: override just `baseUrl` to route a built-in provider through a proxy while keeping all its models, or define `models` to fully replace the provider - Shell commands without context contribution: use `!!command` to execute a bash command that is shown in the TUI and saved to session history but excluded from LLM context. Useful for running commands you don't want the AI to see - Added VoiceSupervisor class for realtime voice mode using OpenAI Realtime API with continuous mic streaming and semantic VAD turn detection - Added VoiceController class for steering user input and deciding presentation of assistant responses - Added echo suppression and noise floor filtering for microphone input during voice playback - Added fallback transcript handling when realtime assistant produces no tool call or audio output - Added voice progress notifications that speak partial results after 15 seconds of streaming - Added platform-specific audio tool detection with helpful installation instructions for missing tools - Added realtime voice mode using OpenAI gpt-5-realtime with continuous mic streaming, interruptible input, and supervisor-controlled spoken updates - Added `gemini_image` tool for Gemini Nano Banana image generation when `GEMINI_API_KEY` (or `GOOGLE_API_KEY`) is set - Added `description` field to task tool for displaying short user-facing summaries in progress output - Added `getApiKeyForProvider()` method to ModelRegistry for retrieving API keys by provider name - Added voice settings configuration for transcription model, TTS model, voice, and audio format - Added shared render utilities module with standardized formatting functions for truncation, byte/token/duration display, and tree rendering - Added `resolveOmpCommand()` helper to resolve subprocess command from environment or entry point - Added `/background` (or `/bg`) command to detach UI and continue agent execution in the background - Added completion notification system with configurable methods (bell, osc99, osc9, auto, off) when agent finishes - Added `completionNotification` setting to configure how the agent notifies on completion - Added `OMP_NOTIFICATIONS` environment variable to suppress notifications globally - Added `/wt` slash command for git worktree management with create, list, merge, remove, status, spawn, and parallel operations - Added worktree library with collapse strategies (simple, merge-base, rebase) for merging changes between worktrees - Added worktree session tracking for managing agent tasks across isolated worktrees - Added structured git tool with safety guards, caching, and GitHub operations - Added `cycleRoleModels()` method to cycle through configured role-based models in a fixed order with deduplication - Added language-specific file icons to LSP diagnostics output showing file locations - Added language-specific file icon to edit tool header display ### Changed - Changed voice mode toggle from Caps Lock to Ctrl+Y with auto-send on silence behavior - Changed default TTS model from gpt-4o-mini-tts to tts-1 - Changed voice mode description to reflect realtime input/output with auto-send on silence - Updated hotkeys help to show Ctrl+Y for voice mode toggle instead of Caps Lock - Voice mode now uses OpenAI Realtime (gpt-5-realtime) with Ctrl+Y toggle and auto-send on silence - Updated web search tool to support `auto` as explicit provider option for auto-detection - Standardized tool result rendering across grep, find, ls, notebook, ask, output, and web search tools with consistent tree formatting and expand hints - Updated grep and find tool output to display language-specific icons for files and folder icons for directories - Updated file listing to display language-specific icons based on file extension instead of generic file icons ### Fixed - Fixed task tool race condition where subprocess stdout events were skipped due to `resolved` flag being set before stream readers finished, causing completed tasks to display "0 tools · 0 tokens" - `/model` selector now opens instantly instead of waiting for OAuth token refresh. Token refresh is deferred until a model is actually used - Fixed cross-platform browser opening to work on Windows (via cmd /c start) and fail gracefully when unavailable ## [3.15.1] - 2026-01-05 ### Added - Added 65 new built-in color themes including dark variants (abyss, aurora, cavern, copper, cosmos, eclipse, ember, equinox, lavender, lunar, midnight, nebula, rainforest, reef, sakura, slate, solstice, starfall, swamp, taiga, terminal, tundra, twilight, volcanic), light variants (aurora-day, canyon, cirrus, coral, dawn, dunes, eucalyptus, frost, glacier, haze, honeycomb, lagoon, lavender, meadow, mint, opal, orchard, paper, prism, sand, savanna, soleil, wetland, zenith), and material themes (alabaster, amethyst, anthracite, basalt, birch, graphite, limestone, mahogany, marble, obsidian, onyx, pearl, porcelain, quartz, sandstone, titanium) ### Fixed - Fixed status line end cap rendering to properly apply background colors and use correct powerline separator characters ## [3.15.0] - 2026-01-05 ### Added - Added spinner type variants (status and activity) with distinct animation frames per symbol preset - 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 `isError` property in tool result events to be optional instead of required - 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 spinner animation crash when spinner frames array is empty by adding length check - 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 `@mariozechner/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 `