- Added Auto QA tool (`report_tool_issue`) for automated tracking of unexpected tool behavior with environment variable and setting support.
- Added Python tool environment warmup on first execution to ensure prelude helpers are available before use.
- Fixed Python prelude introspection to respect execution timeout and signal options, preventing hangs.
- Refactored prelude documentation caching and loading logic into reusable helper functions with test environment awareness.
- Enhanced kernel introspection with optional timeout and signal parameters for better execution control.
- Added system prompt guidance to encourage agents to report tool issues via Auto QA when available.
- Extracted prompt rendering and formatting utilities from coding-agent to centralized pi-utils package with new API surface (prompt.render, prompt.format, prompt.registerHelper).
- Migrated parseFrontmatter utility from coding-agent to pi-utils package; updated 8 files to import from @oh-my-pi/pi-utils.
- Removed 170-line prompt-format.ts module and consolidated 192 lines of Handlebars helper registrations into pi-utils prompt module.
- Updated 60+ files across coding-agent and typescript-edit-benchmark to use new prompt.render() and prompt.format() API from pi-utils.
- Simplified prompt-templates.ts by delegating core functionality to pi-utils while retaining custom helper registrations (jtdToTypeScript, jsonStringify, etc.).
- Reorganized edit tool from `patch/` to `edit/` directory with dedicated mode subdirectories (chunk, patch, hashline, replace).
- Replaced line-scoped edit operations with substring-based `find` parameter and added `replace_body` operation for preserving signatures.
- Added chunk focus modes (Expanded, Collapsed, Container) and focused rendering to display only touched chunks and adjacent siblings.
- Implemented notebook (ipynb) language support with virtual source conversion and cell-based chunk parsing.
- Enhanced chunk edit error messages with consistent checksum mismatch reporting and improved chunk selector auto-resolution.
- Extracted edit mode implementations into separate modules with improved helper functions and LSP integration for diagnostics.
- Eager todo enforcement now skips prompts ending with question marks or exclamation marks, treating them as queries or commands rather than statements requiring task planning.
- Added 2 test cases validating that eager todo enforcement is skipped for prompts ending with question and exclamation marks.
- Removed native binding validation function that checked required exports at load time.
- Enhanced native module loader to check XDG_DATA_HOME environment variable before ~/.omp/natives fallback.
- Removed dependency on @oh-my-pi/pi-utils from native module loader by inlining helper functions.
- Migrated child process termination from waitForChildProcess utility to killTree native binding.
- Added MacOSPowerAssertion native module to prevent idle-sleep on macOS during active sessions.
- Integrated power assertion lifecycle management into coding-agent session with automatic start/stop.
- Implemented N-API bindings for macOS IOKit power assertions with RAII cleanup and cross-platform no-op fallback.
- Reformatted indentation from spaces to tabs across Rust chunk module for consistency.
- Migrated react-edit-benchmark package to typescript-edit-benchmark with pi-mono source repository.
- Added InProcessClient implementation to eliminate subprocess spawning overhead in benchmark runs.
- Extended benchmark configuration with chunk edit variant, retry limits, and conversation dump support.
- Refactored runner.ts to support both RPC and in-process client modes with improved error telemetry.
- Cleaned up 129 benchmark report files from react-edit-benchmark/runs directory.
- Fixed memory leak by cancelling idle compaction timer on event controller disposal.
- Fixed session resumption to preserve last non-empty session when starting fresh.
- Fixed stash detection to use git ref resolution instead of output parsing for reliability.
- Fixed secret obfuscation to deobfuscate restored session messages locally while keeping LLM messages obfuscated.
- Fixed stash pop operation to preserve staged changes with --index flag after task branch merges.
- Changed idle compaction settings from enum to numeric type for flexible configuration.
When entering plan mode, the thinking level configured on the plan role
(e.g., 'anthropic/claude-sonnet-4-5:xhigh') was discarded because
#resolveRoleModel() called resolveModelRoleValue() but only returned
.model, dropping the thinking level.
This is the same class of bug that was fixed in cycleRoleModels (which
correctly preserves and applies thinking level from role configs).
#applyPlanModeModel was the remaining unfixed call site.
Changes:
- Refactor #resolveRoleModel to #resolveRoleModelFull returning the
full ResolvedModelRoleValue instead of just Model
- Add resolveRoleModelWithThinking() public method exposing the full
resolution result
- Add optional thinkingLevel param to setModelTemporary() for atomic
model+thinking switches (eliminates two-step set-then-apply pattern)
- Bundle model+thinking into paired state objects in InteractiveMode
(#planModePreviousModelState, #pendingModelSwitch) — eliminates
4 parallel fields that could desync
- Simplify #applyPlanModeModel, flushPendingModelSwitch, #exitPlanMode
to single setModelTemporary calls
- Collapse cycleRoleModels two-step into single setModelTemporary call
- Add 6 tests for resolveRoleModelWithThinking
* feat(rules): implemented alwaysApply auto-injection into system prompt
rules with alwaysApply: true were parsed by all providers and used to
exclude the rule from rulebookRules, but the inclusion half was never
built — rule content was silently dropped. now:
- full content is injected directly into the system prompt (before the
rulebook rules section) in both default and custom prompt templates
- rules remain addressable via rule:// for re-reading
- ttsr rules still take priority (condition + alwaysApply goes to ttsr only)
updated rulebook-matching-pipeline.md to reflect the three-bucket split
(ttsr > always-apply > rulebook) and corrected the rule:// resolution
docs.
* feat(browser): implement screenshot path saving
- 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
* feat(browser): expand ~ in screenshotDir and path params
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.
* fix(browser): write screenshot to exactly one location
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.
* feat(settings): add text input support for plain string settings
Settings with type: "string" and no submenu now render as an editable
text field in the /settings TUI panel instead of being silently skipped.
- settings-defs.ts: add TextInputSettingDef interface; pathToSettingDef
falls through to { type: "text" } for any plain string schema entry
- settings-selector.ts: add TextInputSubmenu class (mirrors
ConfigInputSubmenu from plugin-settings.ts); add "text" case to
#defToItem; add #createTextInput method
This makes browser.screenshotDir visible and editable in the Tools tab.
Empty field on submit clears the setting (falls back to /tmp behavior).
* fix(settings): text input — cursor at end, block tab navigation
- Cursor: call handleInput(ctrl+e) after setValue to jump to end of
pre-filled string instead of leaving it at position 0
- Tab/arrow guard: add #textInputActive flag; suppress tab-switch and
left/right routing to tab bar while a TextInputSubmenu is open, so
arrow keys reach the Input component's cursor movement handlers
instead of switching settings tabs
* fix(browser): expand ~\ (Windows backslash) in screenshot paths
expandHome now handles both Unix ~/... and Windows ~\... separators,
matching user expectation on all platforms. Addresses Codex review.
* fix(coding-agent): use expandPath for screenshots
* docs: add changelog for screenshot path option
Bug fixes:
- Add browser.screenshotDir to settings-schema.ts (lost during rebase conflict)
- Fix stale expandHome comment to expandPath in settings-selector.ts
- Final screenshotDir description: Directory to save screenshots with ~ support
* fix: biome format corrections for screenshot-path-option branch
* fix: add missing #textInputActive field and screenshotDir default
* fix(browser): align screenshot metadata with saved file contents
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.
* fix(browser): resolve params.path relative to cwd regardless of screenshotDir
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.
* fix(tui): enforce strict line budget for collapsed tool output
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
* WIP
* WIP
* cleanup
* docs(coding-agent): update changelog for custom model tags and cycle order
* Fix custom model precedence across load and refresh
* feat(ask): add multiline editor support for custom input
* feat(extension-ui): add dialog options and abort signal support to editor
* docs(ask): add multiline editor and timeout behavior guidance
* docs(ask): simplify multiline input documentation
* fix(tui): preserve terminal scrollback during full redraws
Replace destructive \x1b[3J\x1b[2J\x1b[H full-redraw sequence with
scrollback-preserving repaint helpers:
- seedTranscript: first paint with no prior frame, writes full transcript
without clearing scrollback
- repaintViewport: trusted-frame repaints that scroll viewport-shift
delta into scrollback before overwriting visible rows in-place
- Height-increase handler that pushes revealed scrollback back before
reclaiming the display
Replace requestRender(true) state destruction with a one-shot
without resetting #previousLines or cursor bookkeeping.
Track #previousHeight to detect terminal height increases that pull
scrollback lines into the visible area.
fixes#507
* fix(tui): fix exit gaps, content shrink drift, and overlay cursor recovery
- Rewrite stop() to use viewport-relative cursor positioning instead of
content-length, preventing blank gaps when content is shorter than viewport
- Replace trailing \r\n\x1b[2K clear loops in repaintViewport() and
height-increase path with \r\n\x1b[J to avoid cursor drift past content
- Add 12 TUI regression tests for exit gaps, content shrink, and overlay
dismiss cursor recovery
- Add 6 coding-agent controller tests for /new and /tree commands
* fix(tui): redraw sparse height increases atomically
* fix(coding-agent,tui): address review regressions
* fix(tui): reseed after terminal resume
* test(ai): avoid leaking kagi module mocks
* fix(ask): keep multiline custom input in prompt gutter
* fix(ask): preserve multiselect choices on editor dismiss
* fix(ask): honor app interrupt in prompt editor
* fix(coding-agent): preserve new-session approval state
* feat(core): add session-scoped model/provider retry fallback policy
* feat(core): validate retry fallback chains on session startup
* fix(ask): preserve prior answer when custom editor dismissed in single-select
* fix(core): harden retry fallback policy semantics
* fix(core): correct retry fallback edge cases
* test(coding-agent): removed macOS fallback test case from theme detection
- Removed test case for macOS fallback behavior inside Zellij.
* refactor: simplified null checks using optional chaining across TypeScript and Rust modules
- 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.
* chore: bump version to 13.15.1
* fix(core): address PR review on fallback retry behavior
* test(ai): refactored auth storage test to use spyOn for cleaner mocks
- Refactored auth storage test to use vi.spyOn() instead of vi.mock() for cleaner mock management.
- Simplified mock type definitions by leveraging bun:test's Mock type import.
* chore: bump version to 13.15.2
* Fix stale OpenAI Responses replay across session boundaries (#534)
* Fix stale OpenAI Responses replay across session boundaries
Fixes#505
* Fix CI tests for session replay change
* Harden session reload and switch rollback
* Guard session switch snapshots
* fix(coding-agent): preserve responses replay snapshots
* Normalize pasted image formats before attach (#543)
Co-authored-by: iter <itertoolz@gmail.com>
* Allow overriding the Codex web search model (#516)
* Allow codex web search model override
* Handle blank codex web search model
* feat(ai): add gemini-3.1-pro-preview models to google-vertex provider (#521)
Add gemini-3.1-pro-preview and gemini-3.1-pro-preview-customtools to
the google-vertex provider in models.json, matching the existing
google-generative-ai entries.
Fixes#520
Co-authored-by: Muness Castle <munesscastle@artium.ai>
* Make temporary model selector keybinding configurable (#539)
Fixes#533
* chore: bump models.json
* refactor(coding-agent): migrated test mocks to vitest spyOn with Symbol.dispose cleanup
- Migrated test mocking from bun:test mock API to vitest spyOn pattern across 9 test files.
- Extracted mock setup logic into reusable helper functions with Symbol.dispose cleanup pattern.
- Replaced manual beforeEach/afterEach and try-finally blocks with TypeScript 5.2 using declarations.
- Removed 178 lines of boilerplate mock initialization and restoration code from test suite.
* chore: bump version to 13.15.3
* fix(ask): restore prompt-style enter handling
* fix(tui): avoid blank scrollback regressions
* fix(models): keep same-id replacements authoritative
* fix(tui): enforce collapsed line budgets
* fix(models): unify selector role sources
* fix(rules): dedupe always-apply prompt injection
* fix(browser): show saved screenshot path
* style: format merged PR fixes
* refactor(coding-agent): restructured screenshot and prompt utilities into focused helpers
- 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.
* refactor(coding-agent): restructured validation and rendering for consistency
- 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.
* revert: 535 due to TUI regressions
* test(coding-agent): corrected hook-editor assertion for keybinding render
- Corrected assertion in hook-editor test to verify external editor keybinding is rendered.
* feat(tools): added root path alias to resolve bare / to working directory
- 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.
* feat(prompts/tools): clarified hashline block boundary handling with examples
- Improved hashline tool documentation with clearer guidance on block boundary handling and closing delimiter duplication prevention.
- Added concrete example demonstrating correct anchor placement when replacing entire blocks including closing braces.
- Reorganized boundary duplication warnings into actionable self-check guidance with visual comparison steps.
* chore: bump version to 13.16.0
* fix(coding-agent): fixed python kernel startup hangs (#548)
* fix(coding-agent): fixed python kernel startup hangs
* fix(coding-agent): fixed startup timeout regressions
* fix(coding-agent): preserved startup cancellation typing
* perf(pi-natives): optimized memory allocation with MiMalloc integration
- Integrated MiMalloc as global allocator to improve memory allocation performance.
* feat: fff
- 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.
* feat(pi-natives): added unified picker coordination for file search operations
- Added `wait_for_picker_scan()` function to search_db module with cancellation token support for polling picker scan completion.
- Integrated picker-based file search into glob matching logic with `collect_files_from_picker()` helper to reuse shared SearchDb picker results.
- Refactored fff and grep modules to use centralized `wait_for_picker_scan()` wrapper instead of direct FilePicker calls, improving cancellation handling.
- Propagated SearchDb instance through agent session initialization and input controller to enable unified file picker coordination across search operations.
* chore: bump version to 13.16.1
* fix: install zig in CI
* feat(tui): make inline image max-width configurable via tui.maxInlineImageColumns (#551)
* feat(tui): make inline image max-width configurable via tui.maxInlineImageColumns
* fix(tui): handle 0 as unlimited in maxInlineImageColumns; drop || undefined coercion
* feat(browser): auto-detect NixOS and use system Chromium (#550)
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.
* feat(pi-natives): added automatic parenthesis escaping in regex patterns
- Added automatic escaping of unescaped parentheses in regex patterns when group syntax errors occur, enabling literal function call patterns like `fetchAnthropicProvider(` to work as search queries.
- Extracted regex matcher builder into separate function for reusability and error recovery logic.
- Added 2 test cases validating parenthesis escaping behavior for both escaped and literal parentheses.
- Fixed documentation formatting in sanitize_braces comment.
* style: reformat
* chore: bump version to 13.16.2
* fix: only show update banner when npm version is strictly newer (#552)
* fix(ai): corrected OAuth credential updates to replace in-place instead of accumulating soft-deleted rows
- Fixed OAuth credential updates to replace matching credentials in-place rather than creating disabled rows, preventing unbounded accumulation of soft-deleted credentials.
- Modified OAuth credential saving to preserve unrelated identities instead of replacing all credentials for a provider.
- Updated credential identity resolution to use provider context for more accurate email deduplication.
- Implemented upsertAuthCredentialForProvider method to handle credential matching and in-place updates.
- Added 5 test cases covering credential preservation across reauth, multi-account scenarios, and stale cache handling.
* chore: bump version to 13.16.3
* feat: introduced unified range API for hashline edits and model catalog updates
- 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.
* chore: bump version to 13.16.4
* fix: pin rustc-hash to 2.1.1 to avoid SIGILL on CI
rustc-hash 2.1.2 (released today) refactored hash_bytes to use
split_first_chunk, which produces illegal instructions when compiled
with nightly + -C target-cpu=x86-64-v3 on CI runners.
* fix(ci): pin nightly to 2026-03-27 to avoid codegen SIGILL regression
Today's nightly produces illegal instructions when compiled with
-C target-cpu=x86-64-v3. Reverts the unnecessary rustc-hash pin from
the previous commit since the real cause is the nightly compiler.
Also lets Cargo.lock return to rustc-hash 2.1.2 (not the culprit).
* fix(ci): add rustup target fallback for pinned nightly cross-compile
* fix(coding-agent): do not prompt to use grep and find tools if they are disabled (#566)
Co-authored-by: le-cameleon <200889489+le-cameleon@users.noreply.github.com>
* fix(natives): skipped grep special files (#565)
avoided opening fifos and other special filesystem nodes during grep and added fifo regressions in native and coding-agent tests.
* fix: skill baseDir regex fails on Windows backslash paths (#554)
The regex that strips SKILL.md from the path to compute baseDir only
matches forward slashes. On Windows where paths use backslashes, the
replace is a no-op and baseDir equals the full SKILL.md file path.
This breaks sub-path resolution for skills: the subpath gets appended
to the SKILL.md file path instead of the skill directory.
Fix: use character class matching both path separators.
---------
Co-authored-by: deadcode-walker <268043493+deadcode-walker@users.noreply.github.com>
Co-authored-by: Rens Tillmann <rens@super-forms.com>
Co-authored-by: haiyang.zhou <haiyang.zhou@seamoney.com>
Co-authored-by: Leo P <junk@slact.net>
Co-authored-by: Zakhar Kogan <36503576+zaharkogan@users.noreply.github.com>
Co-authored-by: Vu Anh Nguyen <vuanhng00@gmail.com>
Co-authored-by: can1357 <me@can.ac>
Co-authored-by: daandden <64765666+daandden@users.noreply.github.com>
Co-authored-by: iter <72358817+itertea@users.noreply.github.com>
Co-authored-by: iter <itertoolz@gmail.com>
Co-authored-by: Cheol Kang <dev@cheol.me>
Co-authored-by: Muness Castle <931+muness@users.noreply.github.com>
Co-authored-by: Muness Castle <munesscastle@artium.ai>
Co-authored-by: zamo <falby97@proton.me>
Co-authored-by: elikoga <elikowa@gmail.com>
Co-authored-by: BayLee4 <63376748+BayLee4@users.noreply.github.com>
Co-authored-by: le-cameleon <200889489+le-cameleon@users.noreply.github.com>
Co-authored-by: Wiedzmin <56316383+art-wiedzmin@users.noreply.github.com>
- Added `wait_for_picker_scan()` function to search_db module with cancellation token support for polling picker scan completion.
- Integrated picker-based file search into glob matching logic with `collect_files_from_picker()` helper to reuse shared SearchDb picker results.
- Refactored fff and grep modules to use centralized `wait_for_picker_scan()` wrapper instead of direct FilePicker calls, improving cancellation handling.
- Propagated SearchDb instance through agent session initialization and input controller to enable unified file picker coordination across search operations.
- Added contract system for validating benchmark commands, metrics, scope paths, constraints, and off-limits paths.
- Contract validation enforces matching initialization parameters against autoresearch.md before init_experiment.
- Segment fingerprinting detects configuration drift and warns when metrics are not directly comparable.
- Added pending run detection and recovery to resume incomplete experiments from .autoresearch/runs/.
- Run directories organize artifacts with benchmark logs and optional checks logs for traceability.
- Extended experiment state to track run number, command, scope, off-limits, constraints, and fingerprint.
- Fixed rate-limit-utils to recognize and classify 'usage limit' errors as QUOTA_EXHAUSTED instead of transient.
- Added isUsageLimitError() utility function for unified detection of persistent quota limit errors across providers.
- Fixed Codex provider to return immediately on usage-limit errors instead of retrying, preventing unnecessary 5-minute delays.
- Removed usage.?limit pattern from TRANSIENT_MESSAGE_PATTERN to prevent misclassification of persistent quota errors.
- Added ACP (Agent Client Protocol) mode for headless agent operation via --mode acp flag.
- Integrated Agent Client Protocol SDK with session management, streaming communication, and event mapping.
- Added ensureOnDisk() method to SessionManager for immediate session persistence without requiring assistant messages.
- Changed session persistence to use atomic file rewrite for unflushed sessions.
- Implemented AcpAgent class with session management, prompt handling, MCP server configuration, and event streaming.
- Simplified plan mode enforcement by removing tool retrieval and restoration logic.
- Replaced tool existence checks with registry lookup to reduce intermediate variables.
* 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>
- Added `attribution` option to `PromptOptions` for controlling billing and initiator attribution.
- Updated subagent prompts to explicitly set `attribution: "agent"` for accurate billing attribution.
- Refactored message attribution logic to use configurable `promptAttribution` with fallback defaults.
- Added test coverage for `attribution` option in subagent reminder prompts.
Fixes#439.
feat(coding-agent): added attribution option and explicit session directory control
- Added `attribution` option to `PromptOptions` for explicit billing and initiator attribution control.
- Updated `SessionManager.create()` to require both `cwd` and `sessionDir` parameters for explicit session directory control.
- Changed session directory naming for temporary working directories from `--` format to `-tmp-` prefix.
- Made `cwd` and `sessionDir` fields mutable in SessionManager to support session relocation.
- Fixed automatic migration of legacy session directories to new `-tmp-` prefixed naming scheme.
- Updated all test fixtures to pass both `cwd` and `sessionDir` parameters to `SessionManager.create()`.
- Schedule auto-removal of completed/abandoned tasks after ~1 minute delay
- Strip already-done tasks when restoring session from branch history
- Add todo_auto_clear event to trigger UI refresh on removal
- Add blank line before Todos header for visual spacing
- 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.
- Added per-rule `interruptMode` override capability to TTSR interrupt logic via optional frontmatter field.
- Changed interrupt behavior to respect per-rule `interruptMode` settings with fallback to global `ttsr.interruptMode` configuration.
- Extended `Rule` and `RuleConfig` interfaces with optional `interruptMode` property for granular control.
- Updated rule discovery to extract and validate `interruptMode` from frontmatter with proper enum type checking.
- Changed abort() method signature to return Promise<void> instead of void, making it async-compatible.
- Added bash executor fallback to one-shot shell execution when persistent sessions fail to respond to cancellation.
- Fixed bash execution timeout handling to prevent subsequent commands from hanging after hard timeouts.
- Extracted abort token management into ShellAbortState for thread-safe cancellation handling across shell sessions.
- Added SessionManager.close() method for proper cleanup of persistent writers and session resources.
- Added `close()` method to SessionManager and AuthStorage for proper resource cleanup and finalization of prepared statements.
- Added `initiatorOverride` option support in OpenAI and Anthropic providers for message attribution control.
- Fixed resource leaks in RpcClient timeout handling by centralizing timeout creation with unref() and adding explicit clearTimeout() calls.
- Fixed AgentSession disposal to call SessionManager's `close()` method for guaranteed resource cleanup instead of fallback flush.
- Updated all test suites to properly dispose AuthStorage instances in cleanup hooks to prevent resource leaks between tests.
Three early-return paths in #runAutoCompaction emitted auto_compaction_end
with result=undefined, aborted=false, and no errorMessage when compaction
was legitimately not needed (no model selected, no candidate models
available, or nothing to compact yet). The event-controller had no way to
distinguish these benign skips from a genuine failure, and fell through to
show the warning:
'Auto context-full maintenance failed; continuing without maintenance'
This was visible after a successful compaction: the next threshold check
would find nothing new to compact (prepareCompaction returns null), emit a
soft-skip event, and trigger the false warning.
Add skipped?: boolean to the auto_compaction_end event type and set it on
the three soft-skip paths. Update the event-controller to treat skipped
events as silent no-ops. Propagate the field through the extension and
hook AutoCompactionEndEvent interfaces so extensions can observe the
distinction.
- Changed eager todo reminder message role from 'developer' to 'custom' with customType field for better message categorization.
- Removed userRequest parameter from eager todo prelude generation to simplify prompt template rendering.
- Updated eager todo prompt to avoid redundant todo_write calls unless task state materially changed.
- Modified eager todo reminder message to use string content with display: false property instead of array format.