terminal.stop() wasn't fully releasing the terminal when vim editor was
opened with Ctrl+G. Two consequences:
1. Renders landed on vim's screen. Streaming message_update events kept
scheduling doRender() via nextTick after the TUI was stopped. A stopped
flag now gates requestRender() and the nextTick callback, preventing
any render tick while an external editor owns the terminal.
2. Keystrokes were swallowed. process.stdin stayed in flowing mode -
start() called resume() but stop() never called pause(). libuv kept
reading from fd 0, racing with vim for input on the same tty. Added
the matching pause() so the editor gets exclusive access.
PR: #2
Co-authored-by: arg3t <arg3t@users.noreply.github.com>
Previously, any LSP server failure during initialize (process crash, missing
binary, rustup proxy error) was reported as a generic "timed out" message.
The process exit and its stderr were ignored; only the per-request timeout
fired, hiding the actual cause.
proc.exited now rejects all pending requests with the server's stderr output.
ptree already captures stderr and awaits its completion for non-zero exits,
so peekStderr() is reliable at this point. The first rejection wins the race
against the timeout; the other finds the request already removed and no-ops.
Also added warmupTimeoutMs to ServerConfig, allowing per-server override of
the global 5s warmup cap via lsp.json/lsp.yaml. Servers without it fall back
to WARMUP_TIMEOUT_MS as before.
Timeout error messages now include the configured duration for clarity when
they do legitimately fire.
- Simplified cache key computation by replacing multi-field comparison with single bigint hash using xxHash64.
- Reduced Cache type from three fields (key, width, bgSample) to two fields (key, result) by consolidating cache validation logic.
- Refactored matchCache method to accept precomputed cache key instead of individual parameters, improving performance and reducing comparison overhead.
- Added native find module for high-performance filesystem discovery with glob pattern matching and .gitignore support.
- Made grep, html, image, and text native functions asynchronous to prevent blocking the event loop.
- Updated native function names to use camelCase convention for JavaScript interoperability.
- Extended grep and text functions to accept Uint8Array/Buffer input for zero-copy operations.
- Delegated file discovery logic from JavaScript to native Rust implementation for improved performance.
Two bugs caused by terminal.stop() not fully releasing the terminal:
1. Streaming renders overwrote vim: requestRender() scheduled doRender()
via process.nextTick even after stop(). Added a 'stopped' flag that
gates requestRender() — no tick is scheduled while the TUI is stopped.
The flag is cleared in start(), so renders resume when the TUI restarts.
2. Keystrokes raced between Node and vim: process.stdin stayed in flowing
mode after stop() because resume() in start() had no matching pause().
libuv kept calling read() on fd 0, competing with vim for input from
the same tty. Added process.stdin.pause() to stop() so the external
editor gets exclusive access to the input queue.
Previously, any LSP server failure during initialize (process crash, missing
binary, rustup proxy error) was reported as a generic "timed out" message.
The process exit and its stderr were ignored; only the per-request timeout
fired, hiding the actual cause.
proc.exited now rejects all pending requests with the server's stderr output.
ptree already captures stderr and awaits its completion for non-zero exits,
so peekStderr() is reliable at this point. The first rejection wins the race
against the timeout; the other finds the request already removed and no-ops.
Also added warmupTimeoutMs to ServerConfig, allowing per-server override of
the global 5s warmup cap via lsp.json/lsp.yaml. Servers without it fall back
to WARMUP_TIMEOUT_MS as before.
Timeout error messages now include the configured duration for clarity when
they do legitimately fire.
- Migrated native bindings from WebAssembly (wasm-bindgen) to Node.js N-API architecture for improved performance and platform support.
- Replaced worker pool-based async architecture with synchronous native addon calls, eliminating thread overhead and simplifying the API.
- Added new grep module with ripgrep-backed filesystem search supporting parallel processing, glob filtering, and context line extraction.
- Updated build system to compile Rust crates to platform-specific .node binaries instead of WASM modules.
- Removed WASI implementation and worker pool infrastructure no longer needed with N-API native bindings.
- Updated CI/CD pipeline to build native addons for multiple platforms (Linux x64/arm64, macOS x64/arm64, Windows x64) and include them in releases.
- Added phased execution guidance for migrations and refactors to prevent parallel work on dependent layers.
- Added example demonstrating phased execution pattern for porting WASM to N-API with sequential foundation, parallel implementation, integration, and dependent layer phases.
- Migrated environment variable handling to use centralized getEnv() and getEnvApiKey() utilities from pi-ai package.
- Removed environment variable denylist that previously blocked API keys from being passed to subprocesses.
- Simplified web search error messages by removing provider-specific configuration hints.
- Eliminated duplicate environment variable and .env file parsing logic across web search providers by delegating to centralized utilities.
- Extracted manual space padding logic into a reusable `padding()` utility function across all UI components and utilities.
- Optimized padding operations by introducing a pre-allocated 512-space buffer in the `padding()` function to reduce repeated string allocations.
- Updated all imports across 30 files to use the new `padding()` function from pi-tui instead of inline `' '.repeat()` calls.
- Renamed local variables from `padding` to `pad`, `padSize`, `indent`, or `linePad` to avoid naming conflicts with the imported `padding()` function.
- Exported the `padding()` utility function from the tui package index for public use.
- Implemented caching in table and cell results renderers to avoid redundant recalculations when width or cell data hasn't changed.
- Added cache invalidation logic to clear cached render results when cell data or spinner state changes.
- Updated task tool documentation to clarify that subagents can access parent conversation context via a searchable file, reducing need to repeat information in context parameter.
- Revised critical instruction section to guide users toward leveraging searchable parent context file instead of requiring self-contained context.
- Added getCompactContext() API to agent session for accessing parent conversation context.
- Implemented automatic submit_result tool injection for subagents with explicit tool lists.
- Added contextFile parameter to ExecutorOptions for passing parent conversation context to subagents.
- Enhanced subagent system prompt with conditional context file instructions and improved code formatting.
- Removed schema override notification from task summary prompt to simplify output.
- Implemented formatCompactContext() method to format conversation history for subagent consumption.
- Removed getShellName() function and replaced with SettingsManager.getGlobalShellConfig() call for more accurate shell detection.
- Updated import to include SettingsManager from settings-manager module.
- Clarified that user instructions about delegation override tool-use defaults in system prompt.
- Updated coordinator guidance to emphasize Task tool preference for substantial work with improved emphasis on context window limitations.
- Enhanced `context` parameter documentation to require self-contained information for subagents, including file contents and user requirements.
- Prevented interactive commands from blocking on stdin by redirecting from /dev/null in POSIX shell sessions.
- Prevented interactive commands from blocking on stdin by redirecting from /dev/null in Fish shell sessions.
- Added explanatory comments documenting stdin redirection behavior and explicit pipe handling.
- Added persistent shell session support for bash tool with environment variable preservation across commands.
- Added shellForceBasic setting to force bash/sh even if user's default shell is different (default: true).
- Added OMP_SHELL_PERSIST environment variable to control persistent shell behavior (set to 0 to disable).
- Restructured system prompt with coordinator-specific guidance for parallel task delegation.
- Added OpenCode Zen provider with API key-based authentication supporting multiple AI models.
- Added four new free models via OpenCode provider: glm-4.7-free, kimi-k2.5-free, minimax-m2.1-free, and trinity-large-preview-free.
- Added glm-4.7-flash model via Zai provider.
- Updated pricing and configuration for multiple models across Kimi, MiniMax, OpenRouter, Anthropic, Vercel AI Gateway, and Zai providers.
- Removed google/gemini-2.0-flash-exp:free from OpenRouter and stealth models from Vercel AI Gateway.
- Improved OAuth token refresh error handling to distinguish between definitive auth failures and transient errors.
- Added logic to only remove credentials for definitive failures (invalid_grant, revoked, expired tokens) while temporarily blocking credentials for transient errors like network timeouts.
- Enhanced error message handling in commit agent to display error messages when stopReason is 'error'.
- Added debug stack trace output for agent errors when DEBUG environment variable is set.
- Added grep CLI subcommand with support for pattern matching, file globbing, context lines, and multiple output modes (content, files-with-matches, count).
- Added diff syntax highlighting support with distinct colors for inserted and deleted lines in code output.
- Implemented FileReader abstraction for cross-platform file reading with mmap support and 4MB size limit.
- Refactored worker pool initialization to support both compiled and development build environments using resolveWorkerSpecifier utility.
- Enhanced markdown rendering with improved inline style context handling and blockquote formatting with text wrapping.
- Replaced external strip-ansi dependency with Bun's built-in stripANSI method across all packages.
- Added Kimi Code provider with support for both OpenAI and Anthropic API formats.
- Added kimiApiFormat configuration option to allow users to select between 'openai' and 'anthropic' API formats for Kimi Code provider.
- Added Kimi API format setting in the tools configuration tab with descriptions for each format option.
- Refactored Anthropic provider authentication logic to support multiple API endpoints including Kimi's Anthropic-compatible API.
- Updated OpenAI completions provider to route direct Kimi models to dedicated Kimi provider implementation.
- Simplified find tool API by removing separate `path` parameter and consolidating pattern parsing into a single `pattern` parameter that includes the search path.
- Added automatic recursive search for simple patterns like `*.ts` by implicitly prefixing them with `**/` when no explicit path is provided.
- Implemented `parsePatternPath()` function to intelligently extract base directory and glob pattern from user input, supporting patterns like `src/**/*.tsx`, `lib/*.json`, and `*.md`.
- Fixed rate limit issues with Kimi models by always sending max_tokens parameter, which Kimi uses for TPM calculation regardless of actual output.
- Added detection for Kimi models (kimi-code provider or moonshotai/kimi ID) to apply the max_tokens workaround.
- Consolidated box component cache state from four separate properties into a single typed Cache object with key, width, bgSample, and result fields.
- Extracted image line detection logic into centralized TERMINAL_INFO.isImageLine() method, removing duplicate containsImage() implementations from Markdown and TUI classes.
- Simplified cache validation in box component by introducing matchCache() method to compare current parameters against cached values.
- Removed trimStart() call from TerminalInfo.isImageLine() to check image protocol at line start without whitespace stripping.
- Replaced interface-based terminal capabilities with class-based TerminalInfo model.
- Converted ImageProtocol from union type to enum with escape sequence values.
- Removed detectCapabilities, getCapabilities, and resetCapabilitiesCache functions in favor of eager TERMINAL_ID and TERMINAL_INFO constants.
- Introduced TerminalId type and KNOWN_TERMINALS registry for terminal detection.
- Updated renderImage and TUI.queryCellSize to use TERMINAL_INFO directly instead of calling getCapabilities().
- Updated exports in index.ts to reflect new API surface.
- Added `get_bytes_gif()` method to PhotonImage for exporting images as GIF bytes.
- Added `get_bytes_webp()` method to PhotonImage for exporting images as lossless WebP bytes.
- Enabled 'gif' and 'webp' features for the image crate dependency.
- Added 'Open: artifact folder' menu option to debug selector for quick access to session artifacts.
- Implemented handleOpenArtifacts() method to open session artifact directories in the native file manager with cross-platform support (macOS, Windows, Linux).
- Added fs/promises import for directory existence validation.
packages/ai:
- fix: handle "sensitive" stop reason from Anthropic API
- fix: normalize tool call IDs with special characters for Responses API
- fix: add overflow detection for Bedrock, MiniMax, Kimi providers
- fix: 429 status is rate limiting, not context overflow
packages/tui:
- fix: refactored autocomplete state tracking
- fix: file autocomplete should not trigger on empty text
- fix: configurable autocomplete max visible items
- fix: improved table column width calculation with word-aware wrapping
packages/coding-agent:
- fix: preserve external config.yml edits on save (#1046 by @nicobailonMD)
- fix: resolve macOS NFD and curly quote variants in file paths
- Added `RequestOptions` interface to worker pool with support for `timeoutMs`, `signal`, and `transfer` properties.
- Added `stuckGracePeriodMs` configuration option to `WorkerPoolOptions` for graceful handling of stuck workers after timeout.
- Enhanced worker pool request method to accept `RequestOptions` object parameter instead of simple transfer array, enabling timeout and abort signal handling.
- Implemented comprehensive timeout and abort signal handling in worker pool with support for combined signals and grace period before force-terminating stuck workers.
- Removed html2text tool from coding agent in favor of native WASM html-to-markdown converter.
- Exported `RequestOptions` type from natives package public API.