- Added support for comma/space-separated path lists in find, grep, ast_grep, and ast_edit tools, allowing users to search multiple directories with a single query (e.g., 'apps/,packages/,phases/' or 'apps/ packages/ phases/').
- Added resolveMultiSearchPath and resolveMultiFindPattern utility functions to path-utils for intelligent parsing and resolution of multi-path search inputs with automatic common base path detection.
- Updated tool documentation for find, grep, ast_grep, and ast_edit to clarify that path parameters accept files, directories, glob patterns, or comma/space-separated path lists.
- Refactored path resolution logic in find, grep, ast_grep, and ast_edit tools to use unified multi-path handling with intelligent delimiter detection (comma or whitespace).
- Exported `submitInteractiveInput()` function for programmatic submission of user input in interactive mode.
- Fixed continue special path to skip optimistic submission state check for already-started prompts.
- Added 2 test cases covering continue submission behavior and optimistic state cancellation.
* Add OAuth token refresh for MCP connections
Proactive refresh with 5-minute buffer before token expiry, plus
retry on 401/403 with automatic token refresh for HTTP transports.
Persist tokenUrl, clientId, and clientSecret in auth config so
refresh can happen without re-prompting the user.
* docs(coding-agent): updated CHANGELOG for MCP OAuth token refresh
- Preserved text signature metadata (id and phase) when building OpenAI native history during session compaction.
- Added test case validating that codex assistant text signature metadata is correctly preserved in remote compaction history.
- Added `onPayload` callback option to intercept and transform provider request payloads before transmission across agent and AI packages.
- Added structured text signature metadata with phase information to OpenAI and Azure OpenAI providers for enhanced response tracking.
- Added `before_provider_request` extension event to coding-agent for chaining payload transformations across multiple handlers.
- Improved error messages in `response.failed` events with detailed error codes, messages, and incomplete reasons from provider responses.
- Added background model discovery with provider status tracking and 24-hour model caching to improve startup performance.
- Changed model discovery timeout from 3000ms to 250ms and deferred blocking refresh to background operations for faster initialization.
- Fixed model discovery to preserve cached models when providers are unavailable or unauthenticated.
- Added validation in Kitty key formatting to reject unsupported modifiers and improved error handling.
- Reorganized CI workflow to run TypeScript linting in check job and conditional Rust checks in native job matrix.
- Updated system prompt and tool guidance to recommend combined investigation-and-edit workflows and maintainable code practices.
- Removed provider parameter from web search tool schema; provider selection now handled internally.
- Removed deprecated no_fallback option from search parameters; fallback behavior is now automatic.
- Renamed SearchParams type to SearchToolParams and introduced SearchQueryParams for CLI queries.
- Updated executeSearch() to accept SearchQueryParams with optional provider selection.
- Extracted loading animation lifecycle management into centralized ensureLoadingAnimation() method.
- Consolidated duplicate loading animation setup across event-controller and interactive-mode into single reusable method.
- Updated showError() to properly clean up loading animation state when errors occur.
- Added comprehensive test coverage for InputController escape key behavior with optimistic submission.
- Added Tavily web search provider with API key authentication and credential discovery from environment or database.
- Integrated Tavily as highest-priority search provider in fallback chain with structured response mapping and error handling.
- Added Tavily OAuth login flow in CLI and auth-storage with manual API key input and validation.
- Added comprehensive test suite for Tavily provider covering registration, response mapping, error handling, and credential validation.
Fixes#313
- Removed Kagi Universal Summarizer integration from fetch tool and YouTube scraper.
- Removed `fetch.useKagiSummarizer` configuration setting from settings schema.
- Simplified renderHtmlToText() and renderUrl() functions by removing Kagi summarization fallback logic.
- Fixed indentation inconsistencies in test files from tabs to spaces.
- Resolved symlinked paths before passing to brush shell to keep `pwd` output aligned with canonical Git worktree paths.
- Added `resolveShellCwd` helper that safely resolves symlinks and falls back to original path on error.
- Added test case verifying symlinked directories are canonicalized before execution.
- Added `env` parameter to bash tool for safe environment variable passing without shell re-parsing.
- Added support for rendering partial environment variable assignments in command preview during streaming.
- Updated bash tool prompt to recommend `env` parameter for multiline, quote-heavy, and untrusted values.
- Refactored tool execution component to conditionally merge partial JSON arguments during streaming.
- Added helper functions for environment variable normalization, escaping, and formatting.
- Added docs.rs scraper for extracting Rust crate documentation from rustdoc JSON, supporting modules, functions, structs, traits, enums, and other Rust items with intelligent caching.
- Implemented rustdoc JSON parsing with type rendering for complex Rust types including generics, lifetimes, trait bounds, and qualified paths.
- Added caching layer for rustdoc JSON with date-based versioning for 'latest' releases to reduce repeated fetches.
- Added skipPostPromptRecoveryWait option to HandoffOptions for deferring recovery work in handoff operations.
- Added deferred auto-compaction scheduling for threshold-triggered handoffs via post-prompt task queue.
- Extracted handoff document template to dedicated system prompt file for improved maintainability and reusability.
- Changed handoff prompt generation to use template rendering with custom focus instructions support.
- Refactored prompt-in-flight tracking from boolean flag to counter for proper nested operation handling.
- Moved llms.txt endpoint discovery to fallback strategy when rendered page content is low quality, prioritizing page-specific content over site-wide files.
- Enhanced llms.txt endpoint detection to scope candidates to the requested URL path, searching section-specific files before site-wide ones.
- Replaced getOrigin() with buildLlmEndpointCandidates() to generate path-scoped endpoint candidates with depth-based fallback strategy.
- Updated tryLlmEndpoints() to accept full URL and return endpoint metadata alongside content for better fallback tracking.
- Added 2 integration tests validating section-scoped llms.txt discovery and preference for rendered content over site-wide files.
- Renamed parameter names in ast-grep and ast-edit tools from `patterns`/`selector` to `pat`/`sel` for brevity across schema, implementation, and tests.
- Expanded ast-grep and ast-edit tool documentation with 12+ new usage guidelines, examples, and critical notes on pattern syntax, metavariable placement, and error handling.
- Updated CHANGELOG.md to document parameter renames and expanded tool guidance for AST pattern syntax and metavariable usage.
- Reformatted test assertions and type annotations across ast-edit and ast-grep test files for improved readability.
- Added `glob` parameter to `ast_grep`, `ast_edit`, and `grep` tools for filtering files relative to `path`.
- Implemented `combineSearchGlobs()` utility to merge glob patterns from multiple sources instead of throwing errors.
- Changed `grep` tool to combine glob patterns when both `path` and `glob` parameters are provided.
- Updated tool documentation to recommend pairing `path`, `glob`, and `lang` for language-scoped search in mixed repositories.
- Added comprehensive test coverage for combined path and glob parameter handling across grep, ast_grep, and ast_edit tools.
- Added automatic Ollama model capability detection via /api/show endpoint to discover reasoning and input modality support.
- Improved Kagi API error handling with structured error parsing for JSON and plain text response formats.
- Fixed Cerebras streaming compatibility by omitting stream_options.include_usage parameter.
- Simplified API key credential storage to always replace credentials instead of merging for non-minimax providers.
- Updated Kagi Search API key format from 'kagi_...' to 'KG_...' and clarified beta access requirement in provider description.
Fixes#326.
Fixes#321.
Fixes#298.
- Added `disabledCause` parameter to credential deletion methods to track reason credentials are disabled.
- Changed credential disabling mechanism from boolean `disabled` flag to `disabled_cause` text field for better auditability.
- Fixed credential purging to respect disabled credentials during email deduplication operations.
- Refactored `replaceAuthCredentialsForProvider()` to update matching credentials instead of deleting all, preserving credential history.
- Added incremental history mode to OpenAI responses .
- Changed OpenAI Codex to exclusively use websockets v2 protocol with fatal error detection for automatic SSE fallback.
- Fixed Gemini model parsing to strip `-preview` suffix for consistent model identification across API calls.
- Improved websocket error handling to extract and report detailed error messages from error events.
- Removed deprecated BETA_RESPONSES_WEBSOCKETS constant and websocket v2 feature flag branching logic.
- 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.
- Added serviceTier option to OpenAI providers for controlling processing priority and cost across agent, completions, responses, and codex APIs.
- Added providerPayload field to messages for transport-native history reconstruction in OpenAI Responses and Codex APIs.
- Added /fast slash command and serviceTier setting to coding-agent for toggling OpenAI priority mode with fast mode indicator.
- Added remote compaction support with encrypted reasoning preservation for OpenAI models in coding-agent.
- Removed usage caching layer across all providers and refactored UsageFetchContext to eliminate cache and now dependencies.
- Fixed OpenAI Codex streaming service_tier inclusion, provider retry logic with exponential backoff, and email-based credential deduplication.
- Added auto-correction logic for off-by-one range start errors in hashline edits.
- Added safety check to prevent false-positive auto-correction when position already includes boundary.
- Added test coverage for off-by-one range correction and duplicate leading line handling.
- Extracted turn-aborted-guidance prompt to external markdown file for better maintainability.
- Added RedactedThinkingContent type to support secure encrypted reasoning blocks in Anthropic messages.
- Updated message transformation logic to preserve signed thinking blocks and redacted thinking for latest assistant messages in Anthropic conversations.
- Added handling for redacted_thinking events in Anthropic stream processing with type, data, and index fields.
- Added comprehensive tests validating redacted thinking block preservation and Anthropic thinking immutability during message transformation.
- Added `read.defaultLimit` setting to configure default line count for read tool output (default 300 lines).
- Added preset options (200, 300, 500, 1000, 5000 lines) for read default limit in settings UI.
- Updated read tool to distinguish between default and maximum limits per call in prompt documentation.
- Refactored read tool limit logic to use configurable default limit with bounds validation.
- Fixed provider session state not being cleared when branching or navigating tree history, preventing resource leaks with codex provider sessions.
- Added calls to `#closeCodexProviderSessionsForHistoryRewrite()` in branch and navigateTree methods to ensure proper cleanup.
- Added test coverage for provider session cleanup during history branching and tree navigation.
- Extracted thinking module with ThinkingEffort, ThinkingLevel, and ThinkingMode types to centralize reasoning configuration across packages.
- Migrated ThinkingLevel type from pi-agent-core to pi-ai package with new validation functions parseThinkingLevel() and getAvailableThinkingLevel().
- Consolidated thinking level constants and descriptions into reusable exports (ALL_THINKING_LEVELS, THINKING_MODE_DESCRIPTIONS) for consistent UI display.
- Removed local thinking-effort-label utility and replaced formatThinkingEffortLabel() with centralized formatThinking() function from pi-ai.
- Refactored thinking mode handling to distinguish ThinkingSelector (user-facing with 'off' option) from ThinkingEffort (provider-level).
- Added buildCompactHashlineDiffPreview() function to generate collapsed diff previews for tool responses.
- Enhanced EditTool response to include diff summary with added/removed line counts and compact preview.
- Added project-level discovery for .agent/ and .agents/ directories walking up to repository root.
- Implemented helper functions for truncating long diff runs (collapseFromStart, collapseFromEnd, collapseFromMiddle).
* feat: monorepo-friendly discovery for AGENTS.md and skills
Support hierarchical config discovery in monorepos by walking up from
cwd through ancestor directories, combining files from all levels
instead of only checking the immediate working directory.
AGENTS.md context files:
- Change dedup key from file.level to file.level + depth, so context
files at different directory levels coexist instead of shadowing
- Root AGENTS.md and sub-project AGENTS.md are both included in the
system prompt, ordered from least specific to most specific
Skills:
- Modify all 4 providers with project-level skill directories (native,
claude, codex, opencode) to walk up from cwd through ancestors,
scanning for skills at each level
- Skills at closer directories win on name conflicts via existing
name-based dedup
Repo root boundary:
- Add findRepoRoot() utility that detects .git to identify repo root
- Add repoRoot field to LoadContext, computed once in loadCapability()
- All walk-up traversals (AGENTS.md, skills, nearest config dir) stop
at the repo root, preventing discovery from leaking outside the repo
- When not in a git repo, falls back to walking to filesystem root
Files changed:
- capability/fs.ts: add findRepoRoot()
- capability/types.ts: add repoRoot to LoadContext
- capability/index.ts: compute repoRoot in loadCapability()
- capability/context-file.ts: depth-aware dedup key
- discovery/agents-md.ts: bound walk-up at repo root
- discovery/builtin.ts: getAncestorDirs stopAt param, skill walk-up
- discovery/claude.ts: skill walk-up with repo root bound
- discovery/codex.ts: skill walk-up with repo root bound
- discovery/opencode.ts: skill walk-up with repo root bound
- extensibility/skills.ts: add repoRoot to inline LoadContext
* feat(agents-provider): add project-level discovery with ancestor walk-up for all capability types
The agents provider (.agent/.agents directories) previously only loaded
capabilities from the user home directory (~/.agent/, ~/.agents/). This
meant project-level .agents/ directories in monorepo roots were not
discovered when sessions started from subdirectories.
Add getProjectPathCandidates() helper that walks from cwd up to repoRoot,
scanning both .agent/ and .agents/ at each ancestor level. Apply this to
all six capability types: skills, rules, prompts, commands, context files
(AGENTS.md), and system prompts (SYSTEM.md). This matches the ancestor
walk-up behavior already present in the builtin (.omp), claude, codex,
and opencode providers.
All loaders now parallelize project-level and user-level scans via
Promise.all. Project-level results appear closest-first so dedup at the
capability layer picks the nearest override.
* fix(discovery): remove hard cap of 20 on ancestor directory walking
All walk-up loops already terminate naturally at repoRoot or filesystem
root. The depth < 20 / .slice(0, 20) / MAX_DEPTH caps were redundant
safety guards that would silently stop discovery in deeply nested
projects.
Removed from: agents.ts, agents-md.ts, builtin.ts, claude.ts, codex.ts,
opencode.ts, and corresponding test files.
* fix(agents-provider): set depth on project-level ContextFile entries for correct dedup
loadContextFiles was creating project-level ContextFile entries without
a depth field. Since contextFileCapability.key uses
`project:${file.depth ?? 0}`, all ancestor-level AGENTS.md files
collapsed to the same key and only the first survived dedup.
Compute depth via calculateDepth(cwd, ancestorDir) where ancestorDir is
two levels up from the file path (past the .agent/.agents config dir).
This gives each ancestor level a distinct dedup key.
* fix(discovery): stop ancestor walk-up at $HOME when not in a git repo
When repoRoot is null (no .git found), walk-up loops traversed all the
way to filesystem root. This caused $HOME to be scanned as a project-
level directory and then again as user-level, producing duplicates.
All providers now use `ctx.repoRoot ?? ctx.home` as the stop boundary:
stop at repoRoot if in a repo, otherwise stop at home. Applied to
agents.ts, agents-md.ts, builtin.ts, claude.ts, codex.ts, and
opencode.ts.
* fix(context-files): clamp depth >= 0 in dedup key and fix provider depth computations
The dedup key `project:${file.depth}` used raw depth, which could be
negative when providers computed it from config subdirectories (e.g.
.claude/, .github/, .gemini/) rather than the ancestor directory. This
caused same-scope cwd-level files to get distinct keys like project:-1
and project:0, bypassing dedup and injecting conflicting instructions.
Two-layer fix:
1. Key function: clamp to Math.max(0, depth) so any file at or below
cwd is treated as cwd-scope (depth 0). Defensive against future
providers.
2. Providers: fix root cause in claude.ts, gemini.ts, github.ts to
compute depth from the ancestor directory (parent of the config
subdir), not the config subdir itself.
---------
Co-authored-by: Can Bölük <can1357@users.noreply.github.com>
parseModelString now extracts valid thinking level suffixes (e.g.,
"anthropic/claude-opus-4-6:high") instead of treating them as part of
the model ID. This enables per-role thinking levels in config:
modelRoles:
slow: anthropic/claude-opus-4-6:high
default: anthropic/claude-opus-4-6:low
smol: google/gemini-3-flash:medium
The thinking level is applied at startup, in SDK fallback resolution,
and during Ctrl+P role cycling. The original config string is preserved
on role cycle so the suffix round-trips correctly.
- Added language module with 39 supported languages and tree-sitter parser bindings for ast-grep integration.
- Exported dedupeParseErrors utility function to remove duplicate parse error messages in tool output.
- Fixed duplicate parse error messages when multiple patterns fail on the same file.
- Replaced language alias lookup with O(1) phf::Map and added 30+ new language aliases (golang, julia, toml, zig, etc.).
- Migrated from ast-grep-language to direct tree-sitter language dependencies for improved language support.