- Added mcpServerName and mcpToolName optional properties to tool definitions for MCP server discovery and tool name tracking.
- Changed aborted tool call handling to preserve existing tool results instead of replacing with synthetic 'aborted' results at turn boundaries.
- Extracted flushPendingToolCalls() and flushPendingAbortedToolCalls() helpers to consolidate orphaned tool call handling logic.
- Updated tool result handling to use message timestamps instead of Date.now() for synthetic results consistency.
* feat(mcp): implement roots/list and server-to-client request handling
Add support for MCP server-to-client JSON-RPC requests across both
stdio and HTTP transports, enabling servers to query client capabilities
such as roots/list during initialization.
Transport layer (types.ts, stdio.ts, http.ts):
- Add onRequest callback to MCPTransport interface for server-initiated
requests; add toJsonRpcError helper for error code propagation
- Classify incoming messages by checking method+id (request), id-only
(response), method-only (notification); guard against id:null per
JSON-RPC 2.0 spec
- StdioTransport: detect server requests in #handleMessage, respond via
#sendResponse writing JSON-RPC response to subprocess stdin
- HttpTransport: detect server requests via #dispatchSSEMessage across
all SSE streams (dedicated listener, POST response drain, notify
piggybacking), respond via #sendServerResponse POST with proper
Accept header and session ID
- Refactor startSSEListener to resolve once SSE GET connects (not when
stream ends), enabling await before notifications/initialized; reset
#sseConnection via .finally() for reconnection after transient failure
- #parseSSEResponse continues reading after capturing the primary
response to drain piggybacked server requests/notifications; clears
timeout after capture so drain phase is unbounded
- notify() reads text/event-stream response bodies for piggybacked
messages; cancels non-SSE response bodies to release connections
- #sendServerResponse includes AbortSignal.timeout and cancels response
body; fire-and-forget handlers wrapped in try/catch to prevent
unhandled rejections
Client wiring (client.ts):
- Add onRequest to connectToServer options, wire to transport before
initialization
- Add awaitable onInitialized hook in initializeConnection, called
between initialize response (which sets session ID) and initialized
notification, so SSE stream is open when server sends roots/list
- Pass only signal to transport.request (not full options object)
- Hoist transport ref to outer scope; close on timeout/abort to prevent
orphaned transports when SSE GET hangs
Manager (manager.ts):
- Wire onRequest handler in connectServers for all MCP connections
- Handle roots/list by returning project CWD as file:// URI via
pathToFileURL; return -32601 for unsupported methods
Tests (mcp-roots-list.test.ts):
- toJsonRpcError: code extraction, defaults, non-Error values
- Message classification spec tests: request/response/notification/
unknown dispatch, id:null and id:0 edge cases
- Roots response shape: file:// URI generation, Windows paths, spaces
* fix(mcp): return SSE response immediately instead of blocking on stream drain
The #parseSSEResponse loop continued iterating the SSE stream after
capturing the response for the expected request ID. Since clearTimeout
was called after capture, a server that holds the SSE stream open for
follow-up events (permitted by Streamable HTTP) would block the
request() call indefinitely.
Return the result as soon as it's captured and drain remaining
messages in a detached background task via #readSSEStream, which
already handles dispatch and error swallowing.
* fix(mcp): handle batched JSON-RPC messages in both transports
JSON-RPC 2.0 section 6 allows sending an array of request/notification
objects as a batch. If a server sent a batch, the message classifier
in both transports would fail the 'method in message' check on the
array object and silently drop all contained messages.
Add an Array.isArray guard at the top of #handleMessage (stdio) and
#dispatchSSEMessage (http) that recurses into each element. Defensive
measure — no known MCP server sends batches today, but the guard is
cheap and correct per the JSON-RPC spec.
* fix(mcp): address second Codex review round
- http: break from SSE loop before starting background drain to avoid
ReadableStream locked error (the for-await iterator still holds the
reader when #drainSSEBackground was called inline)
- types: toJsonRpcError now accepts plain { code, message } objects,
not just Error instances, so onRequest handlers can throw structured
JSON-RPC errors without wrapping in Error
- test: relax Windows path name assertion to toBeTruthy since
path.basename is platform-dependent for backslash paths; add tests
for plain-object toJsonRpcError
* fix(mcp): address third Codex review round
- parseSSEResponse: flatten JSON-RPC batch arrays before checking for
the expected response, so a server that batches the primary response
with piggybacked requests/notifications in a single SSE event still
has the response extracted correctly
- sendServerResponse: retry once on 401/403 via onAuthError, matching
the auth-refresh logic in #executeRequest; prevents server-initiated
request replies from failing after token expiry on long-lived SSE
sessions
---------
Co-authored-by: Miroslav Drbal <miroslav.drbal@gendigital.com>
- Added automatic deduplication of identical context files by content, keeping the closest (lowest depth) copy when duplicates are discovered.
- Implemented dedupeExactContextFiles() function to filter duplicate context entries in both explicit and discovered file lists.
- Added 3 test cases covering deduplication of explicit context entries, discovered context entries, and preservation of distinct entries.
- 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 `args` field to ShellResult to capture the executed command.
- Added `exit_code` property to ShellResult as an alias for `returncode`.
- Added `check_returncode()` method to ShellResult to raise CalledProcessError on non-zero exit codes.
- Renamed `code` field to `returncode` in ShellResult with backward-compatible `code` property.
- Updated `run()` command documentation to clarify available ShellResult fields.
- Extracted OpenAI compatibility detection and resolution logic into dedicated `openai-completions-compat` module.
- Refactored `detectCompat()` and `getCompat()` to delegate to new compat module functions with simplified conditional logic.
- Fixed OAuth redirect URI validation to preserve exact configured values without trailing slash normalization.
- Improved session deletion to return boolean status and display error messages in UI instead of silently failing.
- Added `/session delete` command with Delete key support and confirmation dialogs for session management.
- Extracted environment variable placeholder generation into helper function for test readability.
- Refactored 9 test assertions to use envPlaceholder() helper instead of inline template strings.
- Made sessionDir parameter optional in SessionManager.create(), forkFrom(), continueRecent(), and list() methods with automatic default computation.
- Updated SessionManager.getDefaultSessionDir() to accept optional agentDir parameter for custom sessions root configuration.
- Changed SessionManager.list() signature to require cwd parameter as first argument with sessionDir now optional.
- Implemented multi-root session migration support by replacing global migration state with per-root tracking and extracting session directory encoding logic.
- Added resolveManagedSessionRoot() function to determine if session directory is managed and extract its root.
- Added symlink and path alias resolution to session directory handling for consistent behavior across aliased home and temp directories.
- Improved status line path display to strip display roots using canonical path resolution, correctly handling symlink-equivalent directory aliases.
- Added support for quoted paths in grep, ast_grep, and find tools to properly handle directory names with spaces.
- Improved ast_grep error messaging when no matches found with parse errors to suggest narrowing path/glob or setting language.
- Extracted path utility functions (resolveEquivalentPath, normalizePathForComparison, pathIsWithin, relativePathWithinRoot) to shared utils package.
- Added comprehensive test coverage for symlink alias resolution in status line path rendering and session directory handling.
- 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>
- Updated llama.cpp model discovery to read context window from the `/props` endpoint's `default_generation_settings.n_ctx` field instead of using hardcoded 128000 default.
- Updated llama.cpp model discovery to detect vision capabilities from the `/props` endpoint's `modalities.vision` field instead of defaulting to text-only input.
- Changed llama.cpp `maxTokens` calculation to respect discovered context window limits, capping at 8192 or the server's context window, whichever is smaller.
- Added `#toLlamaCppNativeBaseUrl()` helper to normalize llama.cpp base URLs by stripping `/v1` suffix for native endpoint access.
- Added 3 test cases to verify context window, vision capability, and authorization header handling in llama.cpp discovery.
- Added automatic Ollama model context window discovery from metadata for accurate token limits.
- Added `attribution` option to `PromptOptions` for explicit billing and initiator attribution control.
- Added automatic clearing of completed and abandoned todo tasks after ~1 minute.
- Changed session directory migration to use `-tmp-` prefix instead of double-dash format.
- Updated Ollama model registration to use discovered context window instead of hardcoded 128000 token default.
Fixes#440
- Added automatic migration of legacy absolute-path session directories with double-dash format to new canonical locations.
- Enhanced session directory encoding to use `-tmp-` prefix for temporary directories instead of legacy double-dash format for improved clarity.
- Extracted session directory migration logic into reusable helper functions for better maintainability.
- Updated test setup to mock home directory and verify session migration behavior with temporary paths.
- 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.
- Updated plugin extension discovery test to use XDG_DATA_HOME instead of HOME for environment isolation.
- Replaced manual path construction with getPluginsDir() utility for consistency.
- Added XDG directory structure setup and path cache rebuild to ensure correct plugin resolution.
- 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>