- Added git branch isolation for autoresearch sessions with automatic branch creation, reuse, and worktree safety checks.
- Added scope definition sections (Files in Scope, Off Limits, Constraints) to autoresearch template for explicit session boundaries.
- Added keybinding matcher utilities for consistent escape/cancel key handling across interactive components.
- Added ASI metadata validation (hypothesis and rollback context) in log_experiment tool for experiment tracking.
- Refactored keybinding logic across 13 components to use centralized matcher functions instead of inline key checks.
- Renamed hashline operation types for clarity: append->append_at, prepend->prepend_at, append_eof->append_file, prepend_bof->prepend_file.
- Updated all operation type references in patch implementation, tests, and documentation to reflect new naming convention.
- Restructured hashline tool documentation with hierarchical sections and simplified examples for improved clarity.
- Consolidated validation rules and added explicit warning about invalid anchors and operation/field combinations.
- Added `defaultInactive` property to ToolDefinition for conditional tool registration and activation control.
- Added dynamic tool activation/deactivation API `setActiveTools()` for managing experiment tools in autoresearch mode.
- Replaced single `command-start.md` workflow with separate `command-initialize.md` and `command-resume.md` prompts for autoresearch initialization and session resumption.
- Added interactive intent dialog for autoresearch optimization goals with automatic session resumption detection based on autoresearch.md presence.
- Refactored autoresearch command handler to distinguish resume vs initialize flows and dynamically activate/deactivate experiment tools based on mode and session state.
- Added retry mechanism for benchmark tasks with separate system and retry prompt templates to improve edit success rates.
- Introduced autocorrect tracking metrics including autocorrect-free success rate and edit autocorrect counts in task and benchmark summaries.
- Refactored prompt building into modular functions (buildBenchmarkSystemPrompt, buildInitialBenchmarkPrompt, buildRetryBenchmarkPrompt) with BenchmarkPromptDelivery type for distinguishing initial and follow-up messages.
- Added session management with cache-keyed provider session IDs using xxHash64 and centralized RPC argument building via prepareBenchmarkSessionSetup.
- Refactored hashline edit operations from implicit `replace` to explicit `replace_line` and `replace_range` with mandatory `end` parameter for ranges.
- Added file-level operations `append_eof` and `prepend_bof` for boundary insertions, making `pos` required for anchor-based operations.
- Enforced stricter anchor validation per operation type and simplified edit application logic by separating file-level from anchor-based operations.
- Updated hashline edit application to preserve duplicated boundary lines without auto-correction, changing previous behavior.
- Added autoresearch extension with autonomous experiment loop supporting init, run, and log experiment tools for metric-driven optimization.
- Added widget placement system enabling extensions to position UI components above or below the editor via ExtensionWidgetOptions.
- Added dashboard controller with interactive overlay for viewing experiment results, metrics, and progress with keyboard navigation.
- Removed auto-correction logic for off-by-one range edits in hashline editor to preserve user intent in patch operations.
- Added state reconstruction utilities to parse autoresearch.jsonl logs and rebuild experiment state across sessions.
- Added comprehensive type definitions and helper utilities for metric parsing, ASI validation, and process management.
- Added createTestToolContext helper to construct AgentToolContext instances for tool tests.
- Updated 2 test cases to use createTestToolContext instead of inline object literals for consistency.
- Added imports for AgentToolContext and SessionManager to support new test helper.
- 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
- 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.
- Fixed thinking configuration format by replacing `levels` array with `minLevel`/`maxLevel` properties across 100+ model definitions.
- Corrected GPT-5.4 mini/nano context window from 400000 to 272000 tokens for accurate token limit reporting.
- Normalized GPT-5.4 variant priority handling to use parsed variant instead of raw model IDs for consistent behavior.
- Added "mini" variant support to OpenAI model parsing regex and updated thinking mode configuration for Claude models.
- Fixed test robustness by replacing exact string matching with numeric range comparison to handle BSD seq notation on macOS.
- Corrected model generation script execution order to apply policy overrides before promotion target linking.
- Restructured model policy application logic to improve readability and reduce nesting.
- Extracted model override application into dedicated function calls for consistency.
- Added auto-reconnect capability for MCP servers with SSE stream monitoring and exponential retry backoff.
- Added tool-level reconnect handling for retriable connection errors (ECONNREFUSED, ECONNRESET, 404/502/503).
- Added `/mcp reconnect <name>` command for manual MCP server recovery.
- Improved reconnect robustness by aborting retries when MCP configuration changes via epoch checking.
- Extended transport reconnect handling to all transport types (stdio, HTTP/SSE) with unified onClose logic.
- Added comprehensive test coverage for MCPManager reconnect behavior and tool-level abort propagation.
- Replaced custom withAbort() implementation with untilAborted() utility from pi-utils for consistent abort handling.
- Extracted normalizeToolArgs() helper to consolidate argument normalization logic across renderCall(), renderResult(), and execute() methods.
- Added MCPToolCallParams type import to improve type safety for tool parameter handling.
- Fixed STT Alt+H mic cursor rendering to measure the actual microphone glyph width, preventing one-column TUI overflow crashes when the active symbol preset uses a wide icon (#484).
- Extracted mic cursor styling into dedicated method to consolidate color and width calculation logic.
Fixes#484
- Refactored MCP manager reconnection logic to track configuration changes via reconnectEpoch parameter.
- Consolidated error pattern matching in tool-bridge to use lowercase normalization for consistent comparison.
- Extracted retry provider variables to eliminate repeated ternary expressions in error handling.
- Reformatted code across multiple files for improved readability with consistent multi-line formatting.
- Added test coverage for transport reconnection scenarios including connection reuse after reconnection.
- Updated explore agent thinking level from off to med for improved reasoning.
- Simplified explore agent output schema: consolidated file references into single `ref` field with optional line ranges instead of separate `path`, `line_start`, `line_end` fields.
- Removed `code` section from explore agent output (critical code excerpts no longer extracted).
- Removed `dependencies`, `risks`, and `start_here` sections from explore agent output.
The 8e3e0ebf9 refactor centralized thinking inference but dropped
Bedrock-specific handling:
- inferAnthropicSupportedEfforts gated xhigh on anthropic-messages API,
excluding Bedrock models
- inferThinkingControlMode returned 'budget' for all Bedrock models
instead of 'anthropic-adaptive' for 4.6+
- parseAnthropicModel regex captured Bedrock date suffixes (20250819)
as version components, causing parseSemVer to return null
Fixes:
- Remove API guard from inferAnthropicSupportedEfforts so Opus 4.6+
gets xhigh regardless of API transport
- Add Anthropic version checks to Bedrock case in
inferThinkingControlMode (4.6+ adaptive, 4.5+ budget-effort)
- Narrow version regex from \d+ to \d{1,2} so date suffixes in
Bedrock model IDs are not absorbed
- Update four stale Bedrock Opus 4.6 entries in models.json
- Add thinkingBudgets.xhigh (default 32768) to settings schema
* feat: auto-reconnect MCP servers on connection loss
When an HTTP SSE stream drops (server restart, network interruption),
the transport fires onClose, and the manager proactively reconnects
with retry backoff (500ms, 1s, 2s, 4s). Tools are kept in the registry
during reconnection so they remain selected and available to the agent.
If proactive reconnection fails, stale tools stay registered. When the
agent calls one, the tool bridge detects the retriable connection error
(ECONNREFUSED, ECONNRESET, stale session 404/502/503, etc.), triggers
reconnectServer on the manager, and retries the call once on the fresh
connection. Concurrent reconnect attempts for the same server are deduped.
connectToServer now always installs a default onRequest handler for ping
and roots/list (using getProjectDir()), so all connections -- including
short-lived test/probe ones -- properly respond to server-initiated
requests during initialization.
Post-connection setup (resources, prompts, subscriptions) is extracted
into a shared #loadServerResourcesAndPrompts method used by both initial
connection and reconnection paths.
Add /mcp reconnect <name> command for manual recovery after extended
outages where both proactive and reactive reconnection have failed.
* docs: add changelog entry for MCP auto-reconnect
* fix: address P1 review findings in MCP reconnection
- Save server configs before connection attempt so deferred tools can
reconnect even when the initial connection timed out (P1-1)
- Make waitForConnection() and getConnectionStatus() aware of in-flight
reconnections so callers wait instead of failing immediately (P1-2)
- Add epoch counter incremented on disconnectAll() and checked in
connectAndWireServer() to invalidate stale reconnect attempts that
outlive a manager reset/reload (P1-3)
- Skip servers with pending reconnections in connectServers() to prevent
parallel connection attempts for the same server
* fix: deferred tool reconnect and non-blocking transport teardown
- DeferredMCPTool.execute now reconnects when getConnection() fails
("MCP server not connected"), not only on network errors from
callTool. Servers that missed the startup window can now be woken
by the first tool call against their cached tools. (P1-4)
- #doReconnect fire-and-forgets the old transport close instead of
awaiting it. HttpTransport.close() sends a DELETE with 30s timeout;
blocking here delayed the first reconnect attempt by that amount
on every server restart. (P1-5)
* fix: abort-aware reconnect waits and preserve tool selection on reconnect
- Wrap all reconnect() awaits with withAbort(signal) so user
cancellation (Esc) interrupts the reconnect backoff loop instead
of blocking for up to 7.5s. Applies to MCPTool (1 site) and
DeferredMCPTool (2 sites). (P2-1)
- Remove activateDiscoveredMCPTools call from /mcp reconnect handler.
refreshMCPTools already preserves the user's prior MCP tool
selection; the extra activation was silently opting into all
server tools including ones the user had not enabled. (P2-2)
* fix: rebind MCPTool connection after reconnect, add stdio retriable error
- MCPTool.connection is now mutable; after a successful reconnect retry,
this.connection is rebound to the fresh connection so subsequent calls
on the same instance (e.g. batched tool calls) use it instead of
triggering another reconnect cycle. (P2-3)
- Add "Transport closed" to RETRIABLE_PATTERNS. StdioTransport rejects
pending requests with this message when the subprocess dies, which
should trigger the reconnect path just like HTTP transport errors. (P2-4)
---------
Co-authored-by: Miroslav Drbal <miroslav.drbal@gendigital.com>
Co-authored-by: Can Bölük <can1357@users.noreply.github.com>
Apply user modelOverrides after hardcoded defaults so contextWindow
and other fields from models.json take precedence.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Simplified plan mode enforcement by removing tool retrieval and restoration logic.
- Replaced tool existence checks with registry lookup to reduce intermediate variables.
- 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 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.