- Extracted stream parsing utilities into reusable functions in pi-utils package (readLines, readJsonl, parseJsonlLenient, readSseJson).
- Replaced manual buffer management with ConcatSink class for efficient stream handling across multiple modules.
- Simplified SSE stream parsing in google-gemini-cli provider by using readSseJson utility instead of manual reader setup.
- Refactored MCP stdio transport to use readLines utility for cleaner line-based stream processing.
- Updated RPC client and mode to use readJsonl utility, removing duplicate JSONL parsing logic.
- Optimized buffer allocations by using allocUnsafe where data is immediately populated and reusing empty buffer instances.
- Refactored SSE stream parsing to use generic `readSseJson` utility instead of domain-specific handlers across multiple packages.
- Migrated from Node.js Buffer API to Web standard APIs (Uint8Array, TextDecoder, DataView) for cross-platform compatibility.
- Simplified stream transformation pipeline by consolidating multiple stream operations into unified `createTextLineSplitter` utility.
- Refactored `ptree.ts` to remove complex stream pumping infrastructure and simplify stderr handling with direct async iteration.
- Rewrote stream utilities to operate at binary level with byte-level parsing for improved efficiency and reduced string allocations.
- Updated TypeScript configuration to include DOM.AsyncIterable type definitions for async iterable DOM API support.
- Migrated all environment variable access from Node.js `process.env` to Bun runtime `Bun.env` API across the entire codebase.
- Updated 71 files including source code, tests, documentation, and configuration to use Bun's native environment variable API.
- Added comprehensive environment variables documentation in `packages/coding-agent/docs/environment-variables.md` covering 100+ environment variables organized by category.
- Updated CHANGELOG entries to reflect migration from `process.env` to `Bun.env` and environment variable prefix changes (PI_* vs OMP_*).
- Maintained identical behavior and logic across all changes - only the environment variable access method was updated.
- Replaced nanoid and randomUUID with Snowflake ID generator across codebase for consistent distributed ID generation.
- Created new Snowflake utility module in packages/utils with support for 64-bit distributed ID generation with configurable epoch, machine ID, and sequence numbers.
- Updated session ID format documentation from nanoid to snowflake hex string format (16 hex characters).
- Removed nanoid dependency from package.json as it is now replaced by internal Snowflake implementation.
- 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.
- Extracted process management utilities from coding-agent shell module into dedicated procmgr module in utils package.
- Migrated shell configuration retrieval to SettingsManager class with new getGlobalShellConfig() static method.
- Replaced custom killProcessTree() implementation with new terminate() function supporting graceful shutdown with timeout and AbortSignal.
- Updated ptree.ChildProcess to use generic type parameter for input stream masking and delegated process termination to procmgr.terminate().
- Centralized process management across coding-agent modules to use SettingsManager and procmgr utilities instead of standalone shell functions.
- Simplified ptree API by removing spawnGroup and spawnAttached variants, consolidating into single spawn function.
- Replaced AsyncQueue class with simpler pushStream utility function for stream management.
- Refactored ChildProcess class to use AbortController instead of callback-based signal handling.
- Renamed captureText method to wait and execText function to exec for clearer API semantics.
- Removed mode parameter from exec function, eliminating distinction between spawn modes.
- Updated all call sites across coding-agent to use simplified ptree API.
- Added configurable ask timeout and notification settings to control ask tool behavior and user notifications.
- Added AskSettings interface with timeout (in seconds, default 30) and notification method properties to settings manager.
- Added ask timeout and notification configuration options to settings UI with values for timeout (off, 15, 30, 60, 120 seconds) and notification methods (auto, bell, osc99, osc9, off).
- Refactored process execution across multiple tools (exec, fetch, grep, read, youtube scraper) to use centralized ptree.execText() API instead of custom implementations.
- Refactored ChildProcess class in ptree to use public readonly properties and Promise.withResolvers() for cleaner exit handling.
- Migrated process spawning from `cspawn` to `spawnGroup` and `spawnAttached` APIs with explicit resource management using TypeScript's `using` statement.
- Refactored `ChildProcess` class to support process group management with new `isProcessGroup` getter and `[Symbol.dispose]()` method for automatic cleanup.
- Removed `cspawn` from public API exports in pi-utils, replacing it with `spawnGroup` and `spawnAttached` functions.
- Simplified `ChildProcess.kill()` method signature by removing signal parameter and eliminated `killAndWait()` method in favor of async disposable pattern.
- Converted `killChild` function to async implementation using Bun's `$` template and sleep-based polling for process termination.
- Extracted type guard functions for improved type safety and code reusability across RPC and migration modules.
- Centralized AgentEvent type validation into a dedicated Set constant and type guard function in rpc-client.
- Replaced inline type assertions with type guard functions in RPC response and event handling logic.
- Refactored test utilities to use parseSessionEntries helper and type guard functions for cleaner test code.
- Added reasoning content configuration properties to OpenAI compatibility settings.
- Replaced external JSON/JSONL parsing libraries with Bun's built-in JSON5 and JSONL APIs across all packages.
- Removed dependencies: json5, ndjson, get-east-asian-width, json-stringify-safe, split2, through2, and @types/ndjson.
- Replaced custom text width and ANSI wrapping implementations with Bun.stringWidth() and Bun.wrapAnsi() APIs.
- Updated Bun type definitions from ^1.2.17 to ^1.2.18 and bun-types from ^1.3.5 to ^1.3.7.
- Refactored JSONL parsing throughout codebase to use Bun.JSONL.parse() and Bun.JSONL.parseChunk() with improved buffer management and error handling.
- Updated test assertions to use Bun.stringWidth() for dynamic width calculations instead of hardcoded values.
- Removed Prettier configuration files (.prettierignore and .prettierrc) and migrated formatting to Biome.
- Updated Biome configuration from version 2.3.11 to 2.3.12 and changed arrowParentheses rule from 'always' to 'asNeeded'.
- Pinned @biomejs/biome dependency to exact version 2.3.12 in package.json and bun.lock.
- Applied consistent arrow function formatting across 489 files by removing unnecessary parentheses around single parameters.
- Removed blank lines after comment blocks and reorganized imports for consistency across the codebase.
- Converted readdirSync, readFileSync, and statSync to async readdir, readFile, stat across skills and agent discovery.
- Made scanDirectoryForSkills async and refactored custom directory scanning to use Promise.all for concurrent processing.
- Updated agent discovery to use fs/promises for async file reading and refactored helper patterns.
- Added AgentParsingError exception class for better error handling during agent parsing.
- Added filesystem error type guards (isEnoent, isEacces, isPerm, etc.) to pi-utils for safe error checking.
- Added color manipulation utilities to pi-utils for accessibility features.
- Added color-blind mode setting to settings manager.
- Migrated plugins, settings, and config modules from sync to async file operations.
- Updated error handling to use new pi-utils type guards for type-safe checking.
- Removed WASM generation script; use Bun `wasm?raw` loader for imports.
- Added bunfig.toml with loaders for `.md`, `.py`, and `.wasm?raw` text imports.
- Added types/assets/index.d.ts for global TypeScript module declarations.
- Unified TypeScript configuration with tsgo-based checking across monorepo.
- Removed build and WASM steps from install and publish pipelines.
- Added tsconfig.publish.json files to all packages with optimized publish-time configuration.
- Updated all package.json scripts with prepublishOnly hooks for correct type checking during publish.
- Added @oh-my-pi/omp-stats path mappings to root tsconfig.json for consistent imports.
- Added WASM generation script for photon module and integrated into install:dev script.
- converted relative imports to path aliases ($c/*, $ai/*, $tui/*, etc.) across all packages
- added per-package tsconfig.json with complete path mappings for runtime resolution
- set importModuleSpecifier to non-relative for IDE auto-import preferences
- updated dev script to run from monorepo root for consistent path resolution
- Created new @oh-my-pi/pi-utils workspace package with shared utilities for logging, process management, stream handling, and temporary directory management.
- Migrated all packages to use centralized logger from @oh-my-pi/pi-utils instead of local winston implementations.
- Replaced custom process spawning and stream reading implementations with standardized cspawn and readLines utilities across all modules.
- Converted synchronous file operations and process spawning to async patterns using Bun shell syntax and fs/promises.
- Added streaming edit abort functionality with configurable setting to abort on patch preview failures.
- Updated test framework from vitest to bun:test across all test suites.
- Refactored output sanitization logic into centralized streaming-output module.
- Converted tool implementations from factory functions to class-based architecture.
- Updated SSH executor to use shared output streaming infrastructure.
- Moved voice recording logic from function to class-based implementation.
- Added automatic retry logic for OpenAI Codex responses with configurable delay and max retries.
- Added input event handlers for extensions to intercept user input and argument completion support.
- Added Emacs-style kill ring for text deletion operations with Alt+D and Ctrl+Y keybindings.
- Added configurable editor padding via editorPaddingX theme option and setMaxHeight() method.
- Fixed tool prefix handling in Claude provider to use case-insensitive comparison.
- Enhanced Kitty keyboard protocol support for better key detection and shifted symbol handling.
- Added setFooter(), setHeader(), and setEditorComponent() methods to ExtensionUIContext for custom UI components.
- Exported InteractiveModeOptions type and numerous UI components for programmatic SDK usage.
- Added --no-tools flag to disable all built-in tools and --no-extensions flag to disable extension discovery.
- Changed bash tool output truncation to recalculate on terminal resize instead of using cached width.
- Fixed Wayland clipboard copy (wl-copy) no longer blocking when the process doesn't exit promptly.
- Updated model pricing and renamed nex-agi/deepseek-v3.1-nex-n1 model removing :free suffix.
- Port pi-ai from upstream with Bun-first approach (source files, no dist)
- Add cli_ prefix to tool names in OAuth mode to avoid collisions
- Improve beta header handling with proper deduplication
- Convert codex-instructions.md to Bun text embed
- Strip .js extensions from all imports
- Added in-memory session storage abstraction with SessionStorage interface and MemorySessionStorage implementation.
- Added configurable bash interceptor rules with pattern-based command interception settings.
- Added AbortSignal support to 80+ web scrapers for request cancellation.
- Changed task tool to require explicit task `id` field and single `agent` parameter at top level.
- Removed `submit_review` tool - reviewers now use `complete` tool with structured output.
- Replaced Date.now() and crypto.randomUUID() with nanoid() for unique ID generation throughout codebase.
- Replaced crypto.randomUUID() with nanoid() for ID generation across session-manager and rpc-mode.
- Added RecentSessionInfo class with lazy getters for fullName, name, and timeAgo properties.
- Simplified session retrieval by consolidating isValidSessionFile() into getSortedSessions() helper.
- Added nanoid ^5.1.6 dependency and removed duplicate safe-buffer entries from lockfile.
- Added `pi update` command for checking and installing CLI updates from GitHub releases or bun.
- Added cross-platform installer scripts (shell and PowerShell) with automatic PATH configuration.
- Changed HTML export to use compile-time bundled templates via Bun macros.
- Changed `exportToHtml` and `exportFromFile` functions to async operations.
- Added mutex-based synchronization to prevent race conditions in LSP client, session context, and RPC mode.
- Fixed resource leaks by ensuring stream reader locks are released in try/finally blocks.
- Fixed duplicate processing issues by tracking in-flight operations in runner creation and message writes.
- Fixed event listener mutation during iteration by copying array before emitting.
- Added abort controller cleanup to prevent memory leaks in auto-compaction and retry logic.
- Added centralized file logger with winston and daily rotation to ~/.pi/logs/ directory.
- Exposed logger property to hook and custom tool APIs for extension logging.
- Replaced silent error suppression with debug/warning logging across 20+ catch blocks.
- Removed separate Exa error logger in favor of centralized logging system.
- Renamed npm package scope from @mariozechner to @oh-my-pi across all packages for consistent branding.
- Removed packages/pods directory and all related pod management functionality.
- Updated import paths and module declarations throughout codebase to reflect new package names.
- Reformatted code with consistent trailing comma removal and ternary operator alignment.
- Added MCP (Model Context Protocol) support with stdio and HTTP transports for external tool integration.
- Implemented plugin system with install, enable, configure, and doctor commands for extensibility.
- Added 22 Exa MCP tools for web search, LinkedIn, company research, and websets operations.
- Introduced LSP tool with rust-analyzer support for code intelligence (diagnostics, hover, references, code actions).
- Added task tool for delegating work to specialized subagents with parallel execution support.
- Implemented web_search and web_fetch tools with Anthropic and Perplexity provider support.
Merged 53 commits from pi/main including:
- Export HTML rewrite with tree sidebar and /share command
- Hooks API enhancements (custom status, editor, session management)
- Edit diff preview before tool execution
- TUI fixes (Unicode format chars, OSC 8 hyperlinks, emoji optimization)
- Gemini CLI rate limit retry with server-provided delay
- Various bug fixes and documentation updates
Resolved conflicts by preserving Bun migration (spawn→Bun.spawn,
fs→Bun.file) while accepting upstream's new features and APIs.
- Migrated from Node.js to Bun runtime to leverage native TypeScript execution and faster startup times.
- Replaced npm with bun package manager and updated lockfile format.
- Converted Node.js APIs (child_process, fs, readline) to Bun equivalents across all packages.
- Updated shebang lines from node/tsx to bun for CLI entry points.
- Removed TypeScript build step by using source files directly as package entry points.
- Updated CI workflows to use Bun instead of Node.js for installation and testing.
Move line count from header to footer to avoid changing the first line
during streaming, which was triggering full screen re-renders in the
TUI's differential rendering logic.
CustomToolContext now has:
- isIdle() - check if agent is streaming
- hasQueuedMessages() - check if user has queued messages
- abort() - abort current operation (fire-and-forget)
Changed abort() signature from Promise<void> to void in both
HookContext and CustomToolContext. The abort is fire-and-forget:
it calls session.abort() without awaiting, so the abort signal
is set immediately while waitForIdle() runs in the background.
Fixes#388
- Remove session_before_new and session_new hook events
- Add reason: 'new' | 'resume' to session_before_switch and session_switch events
- Remove 'new' reason from custom tool onSession (use 'switch' for both /new and /resume)
- Rename reset() to newSession(options?) in AgentSession
- Add NewSessionOptions with optional parentSession for lineage tracking
- Rename branchedFrom to parentSession in SessionHeader
- Rename RPC reset command to new_session with optional parentSession
- Update example hooks to use new event structure
- Update documentation and changelog
Based on discussion in #293
- Add theme property to HookUIContext interface
- Implement in interactive, RPC, and no-op contexts
- Add status-line.ts example hook
- Document styling with theme colors in hooks.md
* Add ctx.ui.setStatus(key, text) API for hooks to display status in footer
- Add setStatus to HookUIContext interface
- Implement in interactive mode (FooterComponent)
- Implement in RPC mode (fire-and-forget)
- Add no-op implementations for headless contexts
- Multiple statuses displayed on single line, sorted by key
- Supports ANSI styling (hooks handle their own colors)
* Remove setStatus from changelog for now
* Fix hook status API to follow TUI rules
- Sanitize status text: replace newlines, tabs, carriage returns with spaces
- Truncate combined status line to terminal width using truncateToWidth
- Update JSDoc to document sanitization and truncation behavior
- Remove unused createHookUIContext method
- Add missing setStatus to test mock
* Add setStatus to changelog
* Use dim ellipsis for hook status truncation for consistency with footer style
---------
Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
- Add setEditorText() and getEditorText() to HookUIContext for prompt generator pattern
- custom() now accepts async factories for fire-and-forget work
- Add CancellableLoader component to tui package
- Add BorderedLoader component for hooks with cancel UI
- Export HookAPI, HookContext, HookFactory from main package
- Update all examples to import from packages instead of relative paths
- Update hooks.md and custom-tools.md documentation
fixes#350