- Simplified hashline edit location API by replacing separate `line` and `block` properties with unified `range` property accepting `{ pos, end }` anchors.
- Renamed hashline helper functions from `hlineref`/`hlinefull` to `href`/`hline` for improved brevity and consistency.
- Added detection for `kysely-codegen` generated files in auto-generated file guard with corresponding test coverage.
- Added 13 new AI model configurations and updated token limits and pricing for existing models across multiple providers.
- Enhanced file type validation in grep native to reject symlinks, FIFOs, sockets, and non-regular files with improved error handling.
Puppeteer's bundled Chromium is a dynamically-linked FHS binary that
cannot run on NixOS. On startup, resolveSystemChromium() checks for
/etc/NIXOS and searches for a usable binary in order:
1. chromium on PATH
2. chromium-browser on PATH
3. ~/.nix-profile/bin/chromium
4. /run/current-system/sw/bin/chromium
The resolved path is passed as executablePath to puppeteer.launch().
Result is cached per process. On non-NixOS systems the function returns
undefined immediately, leaving Puppeteer's default resolution intact.
- Added SearchDb class for stateful shared search database instances enabling persistent file indexing and frecency tracking across grep, glob, and fuzzyFind operations.
- Added optional db parameter to grep(), glob(), and fuzzyFind() functions for database-backed searching with improved performance via cached file indices.
- Replaced grep-searcher with fff-grep and added fff-search dependency for enhanced file discovery and search capabilities with memory-mapped file support.
- Migrated fuzzy file discovery from fd module to fff module with SearchDb integration for stateful caching and improved search performance.
- Exported SearchDb type from @oh-my-pi/pi-natives public API for type-safe usage in grep, glob, and fuzzyFind workflows.
- Added root path alias feature to resolve bare `/` to session working directory in path resolution.
- Updated browser tool to use `resolveToCwd()` for consistent workspace-relative path handling.
- Added comprehensive test suite validating root path alias resolution across grep, read, find, ast_grep, and ast_edit tools.
- Refactored theme color validation to use single source of truth with THEME_COLOR_RECORD object.
- Simplified model registry to defer per-model overrides to dedicated method and use constant for role IDs.
- Refactored tree list rendering to pre-render items once for consistent line counts across phases.
- Refactored question result formatting to use early returns and consistently include question ID in output.
- Updated hook editor hint text to include ctrl+g external editor option when prompt style is enabled.
- Removed unused isLogicalLineStart property from LayoutLine interface in editor component.
- Extracted screenshot formatting logic into dedicated `formatScreenshot()` function with options support.
- Consolidated prompt source deduplication into `dedupePromptSource()` helper to prevent rule duplication.
- Refactored editor text sanitization to use `replaceTabs()` utility for consistent tab width handling.
- Added test coverage verifying editor respects configured tab width when loading text programmatically.
- Simplified null/empty checks across TypeScript codebase using optional chaining operator (?.) for improved readability.
- Replaced explicit null checks in validation logic with optional chaining in oauth-discovery, gemini-cli, claude, zai, and lsp modules.
- Updated error handling in Rust command invocation to use double question mark operator (??) for cmd_result.
- Consolidated null validation patterns across tools (bash-skill-urls, browser, gemini-image, resolve) and keybindings using optional chaining.
The grep, ast_grep, and ast_edit renderers used group-count-based
collapse that always included the first group unconditionally,
allowing collapsed output to remain visually large when a single
group contained many lines.
Add maxCollapsedLines to renderTreeList that enforces a strict
total-line cap in collapsed mode. Items that exceed the remaining
budget are skipped entirely (no broken fragments). The isLast tree
branch is computed after the budget check to avoid double-last
branches when a summary line follows.
Remove the per-tool getCollapsedMatchLimit / getCollapsedChangeLimit
helpers that are now redundant.
Fixes#455
Made-with: Cursor
- Changed bash interceptor configuration from boolean flags to customizable pattern-based rules array.
- Clarified hashline range replace semantics: end parameter is now strictly exclusive boundary.
- Fixed bash interceptor to apply built-in default rules when no custom patterns are configured.
- Updated hashline range validation and calculations to enforce exclusive end semantics throughout.
- Added renderInlineMarkdown() utility function to support inline markdown rendering with optional base color styling.
- Refactored ask tool to render questions and option labels with markdown formatting for improved text styling.
- Updated hook-input and hook-selector components to render titles as markdown with theme-aware styling.
- Implemented recursive token processing for nested markdown elements including bold, italic, code, links, and strikethrough.
Fixes#491
screenshotDir is a default save location, not an anchor for explicit
paths. A relative params.path should always resolve against cwd so its
semantics are stable and predictable regardless of user settings.
When screenshotDir or params.path is set, the full-resolution PNG buffer
is written to disk. Previously mimeType/bytes in details still reflected
the resized payload sent to the model, making metadata inconsistent with
the actual saved file.
Now savedBuffer/savedMimeType track what is written, and details reflects
that. Display output distinguishes 'Saved' vs 'Model' when full-res is
used, and collapses to a single Format/Dimensions line for temp-only.
Previously wrote to /tmp unconditionally then copied to user path,
resulting in two files. Now resolves a single destination upfront:
1. params.path (absolute, or relative to screenshotDir/cwd)
2. screenshotDir + auto-timestamp filename
3. /tmp fallback (original behaviour, unchanged)
Also: user-defined destinations receive the full-res buffer;
/tmp fallback retains the API-compressed copy as before.
Users can now configure browser.screenshotDir as ~/Downloads or
~/Pictures and use params.path as ~/screenshots/foo.png without
needing to supply fully-qualified paths.
- Add `browser.screenshotDir` setting (tools tab) for a persistent
default screenshot directory, configurable via /settings
- Honour the existing `path` parameter in the screenshot action,
which was declared in the schema but never consumed by the implementation
- Resolution order: params.path (abs) > join(screenshotDir, params.path)
> join(screenshotDir, screenshot-<timestamp>.png) > /tmp only
- Writes full-resolution buffer to disk (not the API-compressed copy)
- Creates destination directory recursively if it doesn't exist
- details.screenshotPath reflects the actual saved location
Fixes: path param silently ignored since removal in v11.5.0
- Added automatic stripping of hashline display prefixes (LINE#ID:) from write tool content when hashline edit mode is enabled, preventing models from accidentally copying display markers into files.
- Implemented stripHashlinePrefixes() utility to remove hashline-only prefixes without affecting diff markers.
- Added stripWriteContent() helper to conditionally clean write content based on file display mode configuration.
- Updated write tool result message to notify users when hashline prefixes were auto-stripped.
- Added `edit.blockAutoGenerated` setting to control enforcement of auto-generated file detection.
- Improved auto-generated file detection to use language-specific comment parsing instead of broad regex patterns, reducing false positives.
- Enhanced marker detection to scan only leading header comments (1024-byte limit) rather than entire file prefix for better accuracy.
- Fixed tool argument validation to properly handle string 'null' values on optional LLM tool arguments.
- Improved type safety by changing validateToolCall and validateToolArguments return types from any to ToolCall["arguments"].
- Added auto-generated file detection guard to prevent modification of generated code in Edit and Write tools.
- Implemented checkAutoGeneratedFile() to validate file paths against auto-generated markers (protoc, sqlc, buf, swagger).
- Implemented checkAutoGeneratedFileContent() to scan file content prefix for auto-generated patterns before processing.
- Added pre-write validation in Write tool to block overwriting of auto-generated files.
- Added support for quoted paths in grep, ast_grep, find, and ast_edit tools to handle paths with spaces.
- Introduced normalizePathLikeInput() utility function for consistent path and glob parameter normalization across tools.
- Enhanced ast_grep error messaging to warn about parse issues and suggest narrowing path/glob or setting lang parameter.
- Added comprehensive tests for quoted path handling in grep, ast_grep, and find tools with pattern matching.
- Added overload for `prompt()` method accepting string input with optional options parameter.
- Added type guard `supportsMCPToolDiscoveryExecution()` with `MCPDiscoveryExecutionSession` type predicate for safer session type narrowing.
- Added default parameter value to `refreshToolChoiceForActiveTools()` for improved robustness.
* Add MCP tool discovery search and live refresh
* Fix MCP discovery review feedback
* Address remaining MCP discovery review comments
* feat: compact MCP discovery search results
* fix: align MCP discovery search contract
* feat: add MCP server tool counts to discovery hints
* fix(agent): corrected stale toolChoice validation against active tools
- Fixed stale forced toolChoice passed to provider after mid-turn tool refresh by validating against active tools.
- Added refreshToolChoiceForActiveTools() to filter invalid tool choices when available tools change.
- Changed getToolChoice config to use computed function instead of static property for dynamic validation.
- Fixed MCP tool selection tracking in coding-agent to distinguish between discovery-enabled and non-discovery sessions.
- Updated search_tool_bm25 to filter already-selected tools before applying limit parameter.
---------
Co-authored-by: can1357 <me@can.ac>
- Exposed `settings` instance in `CustomToolContext` for session-specific configuration access.
- Improved artifact spill configuration to use session settings with schema defaults as fallback.
- Refactored type annotations and removed Required wrappers for better type safety in settings handling.
- Replaced AgentTool type with Tool type in tool registry for improved type consistency.
- Add compaction.thresholdTokens as fixed token limit alternative to percentage
- Token limit takes priority over percentage when set; options from 25K-500K
- Add more artifact spill threshold options (1KB-1MB) with size descriptions
- Add more artifact tail bytes/lines options with descriptions
- Clean up stale duplicate schema entries from tab reorganization
- Fix statusLine.separator UI metadata
Co-authored-by: Can Bölük <can1357@users.noreply.github.com>
Two /move bugs on Windows:
1. Quoted absolute paths (e.g. /move "C:\...") were treated as relative
because surrounding quotes weren't stripped before path.isAbsolute().
2. /move before any model response threw ENOENT because the session
.jsonl file hadn't been created on disk yet (lazy-persist).
Changes:
- Extract stripOuterDoubleQuotes() helper in path-utils.ts, use in
handleMoveCommand() with empty-after-strip guard
- Guard session file rename with existsSync in moveTo(), leaving
artifact dir rename independently guarded
- Guard #rewriteFile() with hadSessionFile || hasAssistant to preserve
lazy-persist while still updating header cwd for existing files
- Add comprehensive test suite (13 tests) covering all moveTo() edge
cases including header-only sessions, deferred persistence, and
artifact migration
* feat: spill large tool results to artifacts, show tail
- Add centralized spillLargeResultToArtifact() in wrappedExecute pipeline
- Tool results exceeding 50KB saved as session artifacts via saveArtifact()
- Content truncated to tail (20KB / 500 lines) instead of head
- Truncation notice includes artifact:// reference for full output retrieval
- Skip spill when tool already saved its own artifact (bash/python/ssh)
- Update formatFullOutputReference to use action-oriented wording
* feat: per-turn token usage display on assistant messages
* fix: TS errors in output-meta truncation fields
* fix(browser): route localhost through proxy when PUPPETEER_PROXY is set
Chrome bypasses proxies for localhost/loopback by default (since v72).
Add --proxy-bypass-list=<-loopback> so localhost traffic reaches mitmdump,
enabling proxy_traffic.log to capture auth flows for local targets.
Made-with: Cursor
* fix(browser): make proxy loopback bypass opt-in via PUPPETEER_PROXY_BYPASS_LOOPBACK
Made-with: Cursor
- Fixed boolean type coercion in fetch and executor modules by wrapping truncation flags with Boolean() cast.
- Removed maxBytes property from truncation metadata to simplify output metadata structure.
- Normalized optional result properties with explicit fallbacks in output-meta module.
- Updated test expectations to reflect undefined truncation properties instead of false/null values.
- Simplified TruncationResult interface by making maxLines, maxBytes, and other derived fields optional, reducing redundancy.
- Refactored noTruncResult helper to auto-compute totalLines and totalBytes, eliminating repetitive parameter passing.
- Removed truncatedBy null checks and conditional formatting logic in truncation notice functions for cleaner output.
- Consolidated internal URL handling to use noTruncResult and removed unused displayMode variable.
- Clarified documentation in read.md to distinguish filesystem output from text output formatting.
- Threaded Settings parameter through renderUrl and renderHtmlToText functions for dependency injection.
- Changed settings import from default export to type-only import in fetch.ts.
- Added vi.clearAllMocks() calls to test setup hooks for proper mock isolation.