- Introduced Effort enum and ThinkingConfig metadata for per-model reasoning capabilities with min/max effort levels.
- Migrated thinking level API from string-based ThinkingLevel to structured Effort enum across agent and AI packages.
- Added model-thinking module with effort mapping, policy application, and semantic versioning utilities for provider-specific thinking modes.
- Removed supportsXhigh() function and replaced effort clamping with model-aware validation using ThinkingConfig metadata.
- Expanded models.json with thinking configuration objects for 50+ models including Claude, Gemini, and OpenAI variants.
- Added Python analysis scripts for edit tool usage patterns and tool invocation stream processing.
- Removed await from stream() calls that return async iterables directly.
- Removed await from synchronous utility functions like findApiKey(), resolvePythonRuntime(), and getToolPath().
- Removed await from prerenderMermaid() and findExaKey() calls that don't require awaiting.
- Added `/login <provider>` command for direct OAuth provider login with automatic selector routing.
- Added Kagi API key authentication support as new OAuth provider across ai and coding-agent packages.
- Added optional `providerId` parameter to `showOAuthSelector()` for direct provider selection without manual input.
- Simplified web search result formatting by removing empty sections (Answer, Sources, Meta, Related).
- Fixed MCP tool schema dereferencing and Ajv validation warnings for non-standard format keywords.
- Refactored OAuth login/logout logic into extracted handler methods for improved maintainability.
- Fixed exit_plan_mode handler to abort active agent turn before opening plan approval selector, ensuring proper session cleanup.
- Added test to verify abort is called before handleExitPlanModeTool in exit_plan_mode event handling.
- Added transcript export option to debug menu that writes visible TUI conversation to a temporary text file.
- Implemented handleDebugTranscriptCommand in CommandController to render chat messages, strip ANSI codes, and write to temp directory.
- Updated InteractiveModeContext interface and InteractiveMode to expose the new debug transcript command handler.
/plan without args still toggles plan mode on/off as before.
/plan <prompt> enters plan mode and immediately starts planning
with the given prompt, skipping the extra enter-then-type step.
Add cross-platform terminal dark/light mode detection using the Mode 2031
VT extension (DECSET 2031). On startup, query the terminal's current
appearance with CSI ? 996 n, then subscribe to live appearance change
notifications with CSI ? 2031 h. When the OS or terminal switches between
dark and light mode, the terminal sends a DSR that triggers an automatic
theme re-evaluation.
Previously, detectTerminalBackground() only checked the COLORFGBG
environment variable once at launch — a static value that never updates
when the system appearance changes mid-session. The SIGWINCH listener
only fires on terminal resize, not on appearance changes.
Mode 2031 is supported by Ghostty, Kitty (0.38.1+), Contour (0.4.0+),
VTE/GNOME Terminal (0.82.0+), and tmux (3.6+). Unsupported terminals
silently ignore the escape sequences and fall back to the existing
COLORFGBG heuristic.
After plan approval, handleClearCommand() creates a new session with a
fresh artifacts directory. The local:// URL is session-scoped, so the
renamed plan file in the old session local dir was unreachable from
the execution session.
Write the plan content to the new session local dir after the session
switch so the titled plan artifact resolves correctly.
- Consolidated @oh-my-pi/pi-utils subpath imports into single package root import across 100+ files.
- Moved tryParseJson utility from local web scrapers module to @oh-my-pi/pi-utils package for centralized JSON parsing.
- Renamed loadSkillsFromDir to scanSkillsFromDir and refactored skill discovery to use fs.promises.readdir instead of glob-based approach.
- Replaced custom parseJSON with tryParseJson across discovery modules for consistent error handling.
- Removed emitCustomToolSessionEvent method and cleanupSshResources function, consolidating shutdown logic into dispose method.
- Updated glob pattern construction to use GlobBuilder with literal_separator(true) for improved path handling.
- Introduced OAuthManualInputManager and routed callback-server logins to await pasted redirect URLs with a visible tip.
- Extended /login slash command to submit redirect URLs, block overlapping logins, and covered manual callbacks in tests.
- Propagated onManualCodeInput through OAuth provider login helpers with a default authorization prompt.
- Resolved docs index generation paths using path.resolve relative to the script directory.
- Added getTodoPhases() and setTodoPhases() methods to ToolSession API for in-memory todo phase management.
- Added getLatestTodoPhasesFromEntries() export to retrieve todo phases from session history entries.
- Changed todo state management from file-based (todos.json) to in-memory session cache with automatic persistence.
- Changed todo phases to sync from session branch history during branching and rewriting operations.
- Removed file-based todo loading logic and replaced with session-based todo phase retrieval throughout codebase.
- Renamed the `notes://` protocol to `local://` for better clarity.
- Updated all internal references, prompts, and tool documentation.
- Migrated plan storage paths to use the new `local://` scheme.
- Replaced plan:// protocol with notes:// for session-scoped artifact storage and plan finalization.
- Added title parameter to exit_plan_mode tool to enable plan file renaming during approval workflow.
- Implemented NotesProtocolHandler for notes:// URL scheme with path traversal protection and session fallback.
- Added renameApprovedPlanFile function to handle plan artifact finalization with validation and error handling.
- Updated system prompt documentation to reference notes:// protocol and internal URL schemes for artifact access.
- Added async background job execution for bash and task tools with configurable concurrency limits and automatic result delivery.
- Added cancel_job tool and /jobs slash command to manage and inspect running background jobs with status display.
- Added jobs:// internal protocol handler for querying job status and retrieving job execution details.
- Added async.enabled and async.maxJobs settings to control background job execution behavior.
- Enhanced status line to display count of running background jobs with visual indicator.
- Implemented AsyncJobManager with exponential backoff retry delivery, job lifecycle tracking, and automatic eviction.
Fixes#56.
- Migrated timing instrumentation from custom utils/timings module to centralized logger.time() and logger.timeAsync() methods across coding-agent and natives packages.
- Removed PI_DEBUG_STARTUP environment variable and debugStartup() function, consolidating debug output to logger.debug() for conditional logging.
- Replaced custom TextDecoder buffer decoding with native toString('utf-8') method in natives package for simplified string conversion.
- Added RingBuffer<T> circular buffer implementation to pi-utils with comprehensive test coverage for efficient queue operations.
- Enhanced logger interface with time() and timeAsync() methods providing unified operation timing and performance tracking across packages.
onAutocompleteUpdate was calling requestRender(true), which resets all
differential rendering state on every keystroke while the slash menu is
open (debounced at 100ms). This caused the TUI to perform a full screen
clear and repaint on each filter update, producing visible flicker when
the editor is pushed to the bottom of the terminal.
onAutocompleteCancel retains requestRender(true) since it fires only
once on dismissal and the forced redraw is needed to erase the stale
menu rows that the differential renderer would otherwise leave on screen.
onAutocompleteUpdate is changed to requestRender() (no force), letting
the differential renderer repaint only the changed lines within the
autocomplete area.
- Added SSH host management feature with `ssh` CLI command and `/ssh` slash command for add, list, and remove operations.
- Added SSH configuration support at project (.omp/ssh.json) and user (~/.omp/agent/ssh.json) scopes with host discovery from project files.
- Added SSH host configuration flags: --host, --user, --port, --key, --desc, --compat, and --scope for flexible host setup.
- Removed automatic line relocation on stale hash references; now fails with error instead.
Wire the existing TUI autocompleteMaxVisible plumbing into the
declarative settings system so it appears in /settings under the
Input tab. Users can pick from 3/5/7/10/15/20 items; the TUI editor
clamps to 3-20 regardless.
- Add autocompleteMaxVisible to SETTINGS_SCHEMA (number, default 5)
- Add OPTION_PROVIDERS entry for the submenu dropdown
- Handle runtime side-effect in selector-controller
- Set initial value from settings on editor construction
- Add tests for default, runtime, persistence, and config loading
- Added animated microphone icon with color cycling during voice recording and transcription states.
- Added support for discovering skills via symbolic links in the skills directory.
- Changed STT status messages to display via state change callbacks instead of dedicated status line segment.
- Removed dedicated STT status line segment in favor of animated cursor-based feedback.
- Added cursor override feature to TUI editor for customizing end-of-text cursor glyph with ANSI-styled strings.
Cross-platform audio recording with automatic tool detection and
fallback chain (SoX > FFmpeg > arecord > PowerShell mciSendString).
Transcription via Python openai-whisper with automatic pip install
on first use.
Recording:
- SoX with explicit waveaudio device on Windows (-t waveaudio 0)
- FFmpeg with auto-detected dshow device name on Windows
- arecord for ALSA on Linux
- PowerShell mciSendString as zero-dependency Windows fallback
- Process health check after spawn, graceful stop for FFmpeg/PS
- Fallback chain: if one tool fails, tries the next automatically
Transcription:
- Python openai-whisper as primary backend (pip install openai-whisper)
- Custom WAV loader in transcribe.py using Python wave module
- Resamples to 16kHz mono via numpy (no ffmpeg dependency)
- Passes float32 numpy array directly to whisper.transcribe()
- 120s timeout with process kill guard
TUI integration:
- Alt+H keybinding to toggle recording (configurable in keybindings)
- /stt command with on|off|status|setup subcommands
- Status line segment showing REC/STT state
- Transcribed text inserted directly into editor prompt
- Lazy controller instantiation on first use
Settings:
- stt.enabled (default: false)
- stt.language (default: en)
- stt.modelName (default: base.en)
New files: packages/coding-agent/src/stt/{downloader,index,recorder,
setup,stt-controller,transcribe.py,transcriber}.ts
- Added autonomous memory extraction and consolidation system with two-phase pipeline for extracting durable knowledge and consolidating into reusable skills.
- Added /memory slash command with subcommands (view, clear, reset, enqueue, rebuild) for inspecting and managing memory maintenance.
- Added configurable memory settings including concurrency limits, lease timeouts, token budgets, and rollout age constraints.
- Added memory injection payload that includes learned context in system prompts with operational rules for reading and using memory artifacts.
- Improved system prompt building to support memory guidance injection and enhanced error handling in resolvePromptInput function for multiline input.
- Replaced all direct `process.cwd()` calls with `getProjectDir()` utility function across 40+ files to centralize project directory resolution logic.
- Added `getProjectDir()` and `setProjectDir()` functions to `@oh-my-pi/pi-utils/dirs` module to provide abstracted project directory management.
- Made `SessionManager.list()` method asynchronous to support asynchronous session discovery operations.
- Updated default working directory resolution throughout codebase to use `getProjectDir()` instead of `process.cwd()` for improved project directory detection.
- Extracted directory path utilities from multiple packages into a centralized '@oh-my-pi/pi-utils/dirs' module.
- Moved 30+ path helper functions (getAgentDir, getConfigRootDir, getPluginsDir, getMCPConfigPath, etc.) from scattered locations into a single shared utility module.
- Consolidated APP_NAME, CONFIG_DIR_NAME, and VERSION constants into the centralized dirs module for reuse across packages.
- Updated 70+ import statements across packages/ai, packages/coding-agent, packages/stats, and packages/tui to use the new centralized module.
- Removed local path construction logic and replaced with utility function calls for improved maintainability and consistency.
- Deleted packages/coding-agent/src/extensibility/plugins/paths.ts as its functions were moved to the centralized dirs module.
- Added /move slash command to allow users to relocate sessions to different working directories.
- Added moveTo() method to SessionManager for programmatic session relocation with file system operations and rollback support.
- Added refreshSlashCommandState() method to InteractiveMode for dynamic slash command reloading when changing directories.
- Added setSlashCommands() method to AgentSession to allow external management of file-based slash commands.
- Added handleMoveCommand() handler in command-controller to process /move commands with validation and error handling.
* + /mcp
- Reloads MCP manager in runtime state (no restart needed) and syncs with mcp.json.
- Handles OAuth discovery/auth flow automatically for auth-required servers.
- Validates server names and config shape before saving.
- Persists OAuth credentials in auth storage and links them to MCP config.
- Provides immediate connection checks and clear status messages.
- Supports enable/disable, reauth, and unauth flows that are easy to get wrong by hand.
* active agent tool registry runtime reload + token support for bearer auth http based transport
* +session rebind on succesful connection
* fix(coding-agent): address /mcp check failures
---------
Co-authored-by: can1357 <me@can.ac>
- Ensured todoItems is cleared when no session file exists or todo file cannot be loaded.
- Added explicit initialization of todoItems to empty array in error and no-session-file cases to prevent stale todo data from persisting.
- Removed getCursorPosition() method from Component interface and implementations, eliminating hardware cursor positioning support.
- Changed PI_HARDWARE_CURSOR environment variable default from implicit true to explicit '1' with fallback pattern.
- Changed PI_CLEAR_ON_SHRINK environment variable default from implicit false to explicit '0' with fallback pattern.
- Added screen clearing on TUI startup to prevent shell prompts from bleeding into first rendered frame.
- Refactored full-render logic into reusable fullRender() helper function.
- Added ModeChangeEntry type export to public API for tracking agent mode transitions.
- Added mode and modeData fields to SessionContext to track active agent mode state across sessions.
- Added appendModeChange() method to SessionManager for recording mode transition entries.
- Added plan mode state restoration from session entries when resuming interactive mode sessions.
- Updated HTML export filter to treat mode_change entries as settings entries alongside model changes and thinking level changes.
- Added type validation for tool arguments in HTML export template with error handling for invalid values.
- Fixed model switches deferred during streaming to apply correctly when the stream completes, preventing model changes from being lost.
- Added pendingModelSwitch field to track deferred model changes during active streams.
- Added flushPendingModelSwitch() method to apply deferred model switches after streaming completes.
- Modified switchToPlanModel() to defer model changes when a stream is active instead of applying immediately.
- Modified exitPlanMode() to defer model restoration when a stream is active instead of applying immediately.
- Modified EventController to call flushPendingModelSwitch() when stream completion is detected.
- Fixed plan mode toggles during streaming to inject plan-mode context immediately, preventing file edits while in plan mode.
- Updated file mention processing to respect image auto-resize settings.
- Added sendPlanModeContext method to inject plan mode context message into conversation history.
- Migrated environment variable access from function-based `getEnv()` API to object property-based `$env` API across 43 files in the monorepo.
- Simplified `packages/utils/src/env.ts` by removing scoped environment variable logic (EnvScope, getEnvMap, getEnv functions) and replacing with direct `process.env` reference exported as `$env`.
- Updated `packages/ai/src/stream.ts` to remove environment parameter from KeyResolver functions and use global `$env` object instead of passed-in env parameter.
- Migrated environment variable access from direct process.env to centralized getEnv() utility function across all packages.
- Renamed environment variable prefix from OMP_ to PI_ throughout codebase (e.g., OMP_CODING_AGENT_DIR -> PI_CODING_AGENT_DIR).
- Removed automatic environment variable migration from PI_ to OMP_ prefixes via migrate-env.ts module.
- Removed env setting from configuration schema and applyEnvironmentVariables() method from settings.
- Updated CI/CD build configuration to use PI_COMPILED flag instead of OMP_COMPILED.
- Changed venvPath property in PythonRuntime from nullable (string | null) to optional (string | undefined).
- Added default generic type parameter to Model interface, allowing Model to be used without explicit type argument.
- Removed explicit <any> generic type parameters from Model type annotations throughout codebase, leveraging new default parameter.
- Updated @anthropic-ai/sdk from ^0.71.2 to ^0.72.1 in packages/ai.
- Updated @aws-sdk/client-bedrock-runtime from ^3.975.0 to ^3.982.0 in packages/ai.
- Updated @google/genai from ^1.38.0 to ^1.39.0 in packages/ai.
- Updated @smithy/node-http-handler from ^4.4.8 to ^4.4.9 in packages/ai.
- Updated openai from ^6.16.0 to ^6.17.0 in packages/ai.
- Removed proxy-agent and undici dependencies from packages/ai.
- Added Python prelude caching to improve startup performance by caching helper functions and module discovery results.
- Added OMP_DEBUG_STARTUP environment variable for detailed startup stage tracing across initialization pipeline.
- Changed Python kernel initialization to require shared gateway mode, removing support for local kernel gateway startup.
- Improved error handling in shared gateway acquisition with automatic retries on 5xx status codes.
- Added repro-stuck.ts script for reproducing and debugging rare CLI hang issues with Chrome DevTools integration.
- Added trace-loader.ts preload script for tracing module resolution during startup diagnostics.
- Changed TextInput type parameter to string in truncateToWidth(), visibleWidth(), sliceWithWidth(), and extractSegments() functions in native bindings.
- Removed TextInput type export from public API of pi-natives package.
- Removed format.ellipsis symbol from theme configuration, replacing all theme-based ellipsis references with hardcoded Unicode ellipsis character (...).
- Removed ellipsis property from SymbolTheme interface in pi-tui package.
- Removed truncateToWidth, sliceWithWidth, and extractSegments wrapper functions from pi-tui public API, now re-exporting directly from pi-natives.
- Added early return optimizations in truncateToWidth() and sliceWithWidth() native functions to skip native calls when possible.