Commit Graph

562 Commits

Author SHA1 Message Date
can1357 7fb18faf4c fix(coding-agent): backported pi-mono changes (1feccfed..b21b42d0)
packages/ai:
- feat: expose provider responseId on AssistantMessage
- feat: lazy-load provider modules for faster startup
- fix: hash foreign Responses API tool call IDs exceeding 64-char limit
- fix: ignore null chunks in openai-completions streams
- fix: keep image tool results inline for Gemini 3+ and Antigravity
- fix: correct Bedrock Claude 4.6 context window to 200k
- fix: support prompt caching for Bedrock application inference profiles
- fix: add OpenRouter reasoning payload format
- fix: ignore placeholder Vertex API keys
- fix: skip AJV validation in restricted runtimes
- fix: Anthropic OAuth client injection and responseId extraction
- fix: Codex incomplete/failed response status handling

packages/agent:
- fix: defer steering until after tool execution completes

packages/tui:
- feat: namespaced keybinding IDs with KeybindingsManager conflict detection
- feat: configurable select list column sizing (#2154 by @markusylisiurunen)
- fix: stream truncateToWidth for large strings
- fix: skip Termux height redraws
- fix: stop evicting unrelated default keybindings
- fix: resolve raw backspace ambiguity on Windows Terminal
- fix: clear stale scrollback on session switch (#2155 by @Perlence)
- fix: remove trailing markdown block spacing (#2152 by @markusylisiurunen)

packages/coding-agent:
- feat: add resizable share sidebar (#2435 by @dmmulroy)
- feat: emit OSC 133 command-executed marker
- feat: reload custom themes from disk watcher
- feat: add --fork session flag
- feat: file mutation queue for serialized writes
- feat: initial message consolidation utility
- fix: keybindings migrated to namespaced IDs
- fix: resolve waitForRetry() race when auto-retry produces tool calls
- fix: handle slash-delimited /model refs
- fix: refresh active model after provider updates
- fix: extended transient error patterns for retry
2026-03-22 18:28:40 +01:00
can1357 2771c2399d feat(autoresearch): introduced autonomous experiment loop with metric-driven optimization
- 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.
2026-03-22 16:50:13 +01:00
can1357 c0f5711588 revert: exclusive end 2026-03-22 16:49:49 +01:00
can1357 c11cd9023a test(tools): added createTestToolContext helper for consistent tool testing
- 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.
2026-03-22 13:57:02 +01:00
can1357 d4b6e869cb feat(coding-agent): implemented pattern-based bash interceptor rules + exclusive range semantics
- 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.
2026-03-22 12:53:16 +01:00
can1357 a4026c588e fix(ai): corrected thinking config format and model context windows across 100+ definitions
- 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.
2026-03-21 17:34:38 +01:00
luke 47dc03b835 fix: prevent TUI freeze on massive bash output and fix spinner rendering (#500)
- Sync OutputSink.push(): eliminate promise chain per chunk, buffer
  management and onChunk run inline, file writes deferred via queue
- 64KB native read buffer (was 4KB): reduces chunk count ~16x
- chunkThrottleMs in OutputSink: gate onChunk to every 50ms
- BashExecutionComponent streaming throttle: gate + 100-line cap
- Remove requestRender from chunk callbacks: spinner drives renders
- Remove double sanitization in appendOutput (already done by OutputSink)
- Inline SEGMENT_RESET in TUI doRender buffer writes: eliminates O(N)
  string allocations per frame from #applyLineResets
- Cache header Text in BashExecutionComponent (created once, reused)
- Gate sixel mask computation behind protocol + passthrough check
- Fix spinner: #spinnerFrame made optional, interval calls #updateDisplay
- Remove pendingChunks promise chains from bash-executor and bash-interactive
2026-03-21 16:05:42 +01:00
can1357 4f7b61ab62 feat(coding-agent): added MCP server auto-reconnect with SSE monitoring
- 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.
2026-03-20 23:48:38 +01:00
can1357 c718104e8b fix(patch): handled plus-prefixed hashline IDs in diff-style output
Fixes #485
2026-03-20 23:37:04 +01:00
can1357 51228e9811 refactor(coding-agent): restructured MCP reconnection tracking and error handling
- 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.
2026-03-20 23:32:07 +01:00
Miroslav Drbal [ApoC] 8b028224e3 feat: auto-reconnect MCP servers on connection loss (#482)
* 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>
2026-03-20 23:27:30 +01:00
can1357 51fb0ade87 feat: add discoveryDefaultServers config for MCP discovery mode
fixes #470
2026-03-18 23:05:33 +01:00
Miroslav Drbal [ApoC] 21a86a693d feat(mcp): implement roots/list and server-to-client request handling (#474)
* 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>
2026-03-18 23:02:22 +01:00
can1357 22a876bb8f feat(coding-agent): added automatic deduplication of context files by content
- 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.
2026-03-18 23:00:17 +01:00
can1357 fb76484aa4 fix: route all app-level shortcuts through KeybindingsManager
fixes #468
2026-03-18 22:46:22 +01:00
can1357 38eeeeda1b fix: deduplicate custom SYSTEM.md in context assembly
fixes #473
2026-03-18 22:43:40 +01:00
can1357 7cd4c65574 feat(coding-agent): added auto-generated file detection controls and improved accuracy
- 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"].
2026-03-18 10:53:37 +01:00
can1357 afc2276a12 refactor(ai): extracted OpenAI compat logic into dedicated module
- 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.
2026-03-17 16:07:26 +01:00
can1357 0c1586f747 test(coding-agent/discovery): extracted envPlaceholder helper for test clarity
- Extracted environment variable placeholder generation into helper function for test readability.
- Refactored 9 test assertions to use envPlaceholder() helper instead of inline template strings.
2026-03-17 14:53:45 +01:00
can1357 e8eed16c1e chore: reformat 2026-03-17 14:52:06 +01:00
slact 2825c894f5 feat: session deletion (#448)
* feat: session deletion

* better session deletion cleanup error handling

* fix: complete deletion including artifacts
fix: native confirmation for session deletion

* even better native configmation for session picker

* fix(coding-agent): detach active session before deletion

* fix(coding-agent): keep failed session deletes visible

* fix(coding-agent): await session delete command

* fix(coding-agent): surface session artifact cleanup failures

---------

Co-authored-by: can1357 <me@can.ac>
Co-authored-by: Can Bölük <can1357@users.noreply.github.com>
2026-03-17 14:51:21 +01:00
Dragoy 5520eac002 fix(storage): support SQLite 3.37 without unixepoch (#451)
* fix(storage): support SQLite 3.37 without unixepoch

* fix(history): recreate index after migration
2026-03-17 14:50:32 +01:00
maximhar e27ceb2f96 fix: persist MCP discovery tool selections across session lifecycle (#453)
* fix: persist MCP discovery selections across session lifecycle

* fix: restore MCP discovery state on branch switches

* fix: preserve explicit MCP baseline on old branch contexts

* fix(coding-agent): preserve cleared MCP selections on resume

* fix(coding-agent): isolate MCP defaults across session switches

* fix(coding-agent): preserve MCP defaults across outages

---------

Co-authored-by: can1357 <me@can.ac>
2026-03-17 14:49:54 +01:00
maximhar 571510bdf3 fix: MCP OAuth exact redirect URIs for Slack-style providers (#454)
* Add exact MCP OAuth redirect URI support

* Allow proxied HTTPS loopback MCP redirects

* Fix MCP OAuth busy-port test determinism

* Make MCP OAuth redirect test deterministic

* fix(coding-agent): honor exact loopback redirect ports

* fix(coding-agent): expand env vars in standalone MCP oauth config

---------

Co-authored-by: can1357 <me@can.ac>
2026-03-17 14:49:23 +01:00
can1357 9148ec01ec feat(session-manager): added optional sessionDir with multi-root migration support
- 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.
2026-03-16 16:06:04 +01:00
can1357 2cc53e86f1 feat(coding-agent): required sessionDir parameter to enforce explicit session path resolution
- Made sessionDir parameter required in SessionManager.create(), continueRecent(), and forkFrom() methods.
- Added SessionManager.getDefaultSessionDir() static method to explicitly resolve canonical default session directory.
- Changed SessionManager.list() signature to accept sessionDir directly instead of computing from cwd.
- Fixed SDK-created default sessions to honor configured agentDir for session storage and symlink-equivalent path resolution.
2026-03-16 15:46:06 +01:00
can1357 78177af8bc feat(coding-agent): added symlink resolution and path alias handling for consistent directory behavior
- 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.
2026-03-16 15:24:18 +01:00
can1357 7d6c60f957 feat(tools): added quoted path support to grep, ast_grep, find, and ast_edit tools
- 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.
2026-03-16 14:26:22 +01:00
daandden b7978c9e0d feat: add undo action and fix hotkeys rendering (#438)
* Fix prompt action undo and hotkeys rendering

* Fix prompt action test typechecks

* Simplify undo and hotkeys PR

* Fix editor formatting
2026-03-16 14:05:21 +01:00
maximhar 94ad651d17 feat: add MCP tool discovery search (#352)
* 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>
2026-03-16 13:43:43 +01:00
can1357 ab49511632 feat(coding-agent): implemented dynamic llama.cpp server capability detection
- 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.
2026-03-15 23:54:03 +01:00
daandden 70bf7bbed2 fix(coding-agent): preserve unconsumed inline args in template expansion (#314)
* docs: map existing codebase

* fix(coding-agent): preserve unconsumed inline args in template expansion

fixes #281

* chore: remove .planning codebase artifacts

* Match OpenCode command fallback behavior

* Format inline arg fallback changes

---------

Co-authored-by: Vũ Anh Nguyễn <vu.anh.nguyen@mgm-tp.com>
2026-03-15 23:07:35 +01:00
can1357 82b70ead61 feat(coding-agent): added Ollama context discovery and attribution control
- 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
2026-03-15 23:05:20 +01:00
can1357 bdcc08a50c feat(coding-agent/session): added automatic migration of legacy session directories
- 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.
2026-03-15 22:56:18 +01:00
can1357 dbc1c4af1d feat(coding-agent): added attribution option to control billing and initiator tracking
- 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()`.
2026-03-15 22:56:18 +01:00
can1357 3f1d7c6882 test: isolated plugin discovery test with XDG_DATA_HOME environment variable
- 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.
2026-03-15 17:36:59 +01:00
can1357 b8e82008e3 feat(coding-agent): added extension filtering and granular capability identification
- Added `toExtensionId()` method to all capability types for granular extension identification and disabling.
- Added `disabledExtensions` and `includeDisabled` options to LoadOptions for filtering disabled capabilities by extension ID.
- Added plugin manifest support for `extensions` entry points with automatic discovery from installed plugins.
- Fixed skill loading to properly respect disabled skill names from custom directories.
- Improved cross-platform path handling by using `path.basename()` instead of string splitting in context file and state manager.
- Refactored capability index loading to validate source metadata and filter disabled extensions before processing.
2026-03-15 17:26:46 +01:00
can1357 31427a8eef feat(patch): implemented binary-safe file rename with move-only validation
- Added support for move-only file operations that preserve exact bytes including binary content and special characters.
- Added validation to reject move operations where source and destination paths are identical.
- Implemented dedicated move-only handler with parent directory creation and binary-safe file rename operations.
- Added error handling for move operations on non-existent source files.
2026-03-15 16:50:48 +01:00
can1357 07389a4da0 chore: reformat 2026-03-15 16:43:17 +01:00
Variable Fate 1957c702a4 fix(move): resolve quoted Windows paths and fresh-session ENOENT (#416) (#418)
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
2026-03-15 16:39:30 +01:00
汐 2ae1a042d8 feat(utils): full XDG Base Directory support for all path helpers (#407)
* feat(utils): full XDG Base Directory support for all path helpers

Implement XDG-first resolution across all omp path helpers, extend the
migration command to cover every data/state/cache location, and fix
five data-safety issues found in review.

dirs.ts:
- Add getXdgCachePath() helper ($XDG_CACHE_HOME/omp/<subpath>)
- Add isDefaultAgentDir() helper: XDG lookup is only valid when the
  resolved agentDir equals the process default (~/.omp/agent); custom
  profiles set via PI_CODING_AGENT_DIR or setAgentDir() are never
  silently redirected to the global XDG database
- Update 15 functions to XDG-first resolution:
    data:  getPluginsDir, getRemoteDir, getRemoteHostDir, getPythonEnvDir,
           getWorktreeBaseDir
    state: getReportsDir, getSshControlDir, getCrashLogPath, getDebugLogPath
    cache: getPuppeteerDir, getGpuCachePath, getNativesDir
- Guard XDG lookup with isDefaultAgentDir(agentDir ?? getAgentDir()) in
  all 9 agent-subdir helpers so that callers passing the global default
  agentDir still resolve to the migrated XDG location, while callers
  passing a non-default agentDir or running under a custom profile via
  setAgentDir() bypass XDG entirely
- Plugin-derived helpers delegate to getPluginsDir() and follow XDG
  resolution automatically

migrate-xdg.ts:
- Add getXdgCacheHome() helper
- Extend MigrationItem.category to include 'cache'
- Add 12 new migration entries: reports, plugins, remote, ssh-control,
  remote-host, python-env, puppeteer, wt, gpu_cache.json, natives,
  omp-crash.log, omp-debug.log
- Refuse to run when PI_CODING_AGENT_DIR points to a non-default
  profile: migration only makes sense for the default ~/.omp/agent tree
- copyDirectory returns skipped source paths (target existed, non-force)
- verifyIntegrity: remove size-mismatch early-return that masked stale
  targets as successful copies
- executeMigration: delete only entries that were actually copied;
  use rmdir on source dir so it is removed only when empty, preserving
  any skipped files for a subsequent --force run
- executeMigration: rename partial target to <target>.bak on integrity
  failure instead of deleting; preserves pre-existing user data while
  preventing getXdgDataPath from treating the partial tree as
  authoritative; source remains intact for re-copy on next run

test isolation:
- Set XDG_DATA_HOME/XDG_STATE_HOME to non-existent paths in
  memories-runtime.test.ts beforeEach/afterEach to prevent
  getXdgDataPath/getXdgStatePath from resolving to real user data

* fix(utils,coding-agent): fix XDG support issues

dirs.ts:
- Refactor path resolution into DirResolver class. XDG base dirs are
  resolved once at construction from env vars (Linux only, no
  existsSync). setAgentDir creates a fresh instance, naturally
  invalidating all cached paths and recomputing isDefaultProfile.
- getRootSubdir/agentSubdir accept optional XdgCategory parameter;
  when set, the XDG base replaces the config root. Every accessor
  is a one-liner delegate.
- Non-Linux platforms: XDG fields are null, zero overhead. No
  filesystem probing, no string comparisons on the hot path.
- Config-only subdirs (themes, tools, commands, prompts, modules)
  have no XDG category — they stay under the config root.
- Remove `import { env } from 'bun'`, use process.env consistently.
- Restore JSDoc comments to document actual defaults (~/.omp/...).

migrate-xdg.ts:
- Gate migrateToXdg on Linux — exits with clear error on other
  platforms.
- Fix data loss bug: verifyIntegrity now accepts a Set of skipped
  paths and skips verification for files that were intentionally not
  copied (pre-existing at target in non-force mode).
- Fix nested directory source deletion: recursive removeSourceEntries
  walks the tree and only deletes files not in the skipped set.
- Remove dead _sourcePath variable and unused force parameter from
  verifyIntegrity.
- Remove `import { env } from 'bun'`, use process.env consistently.

logger.ts:
- Revert JSDoc to document ~/.omp/logs/ as default.

oauth.ts:
- Replace direct getAgentSubdir call with getTestAuthPath().

CHANGELOG.md:
- Merge duplicate section headers under [Unreleased].
- Add missing blank line before [13.11.1].

---------

Co-authored-by: can1357 <me@can.ac>
2026-03-14 14:52:12 +01:00
can1357 2a20bd302e feat(ai): support extra body fields in openai-completions requests
Fixes #363
2026-03-14 13:52:12 +01:00
can1357 8f18464cd7 feat(config): reorganized settings into 8 focused categories with 15+ new customization options
- Reorganized settings tabs from 12 to 8 focused categories (appearance, model, interaction, context, editing, tools, tasks, providers) with consolidated status line settings.
- Added 15+ new settings for status line customization, sampling parameters, speech-to-text, web search, and edit mode configuration.
- Changed default agent model from `default` to `pi/task` for independent subtask configuration and updated model resolution to support single-pattern inheritance fallback.
- Updated system prompt to use ISO 8601 date format (YYYY-MM-DD) and renamed 25+ UI labels for consistency across settings interface.
- Updated tab icon symbols across unicode, nerd, and ASCII presets to reflect new tab organization.
- Simplified settings definitions and removed unused imports to reduce code complexity.
2026-03-14 13:44:20 +01:00
can1357 090a9cd14c feat(coding-agent): enabled task model role configuration for independent subtask execution
- Added task model role configuration enabling dedicated subtask execution with independent model selection.
- Changed default agent model from 'default' to 'pi/task' for independent subtask model configuration.
- Added single-pattern inheritance fallback allowing pi/task agents to inherit session model when unconfigured.
- Refactored model resolution logic into resolveAgentModelPatterns() function with structured fallback handling.
- Added resolveConfiguredModelPatterns() and helper functions for improved model pattern resolution.
2026-03-14 13:38:30 +01:00
can1357 b5faa7d4be feat(coding-agent): added cursor navigation to message boundaries
- Added `moveCursorToMessageStart()` and `moveCursorToMessageEnd()` prompt actions for cursor navigation to message boundaries.
- Exposed editor methods for cursor movement to message start and end positions in InputController keybindings.
- Implemented message boundary navigation in Editor class with private helper methods for cursor positioning.
- Removed remote compaction settings test suite to align with feature deprecation.
2026-03-14 13:38:29 +01:00
can1357 ca2860b200 feat: added OpenAI compatibility config and 10 new AI models with reasoning support
- Added support for provider-level OpenAI compatibility configuration enabling reasoning effort mapping and streaming usage fallback across models.
- Added 10 new AI models (DeepSeek V3.2, Llama 3.1 405B, Mistral Large 3, Pixtral Large, and others) with updated pricing and context windows.
- Fixed autocomplete to preserve ./ prefix in relative file/directory path completions and paste marker expansion to handle regex tokens literally.
- Changed system prompt date format to ISO 8601 and tool download timeout from 15s to 120s for improved cross-platform compatibility.
- Refactored OpenAI completions provider to extract token parsing logic and support choice-level usage fallback with improved message serialization.
2026-03-14 13:38:29 +01:00
can1357 b22d063888 feat: enabled async shell cancellation with fallback execution and timeout recovery
- 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.
2026-03-14 13:38:29 +01:00
can1357 2f151fea9a fix(tests): added resource cleanup methods and initiatorOverride support
- 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.
2026-03-14 11:25:40 +01:00
can1357 ea1d76b79e fix(tests): typing in tests for Context and event typing 2026-03-14 11:06:32 +01:00
can1357 967d8cc05b fix(coding-agent): changed session.dispose() to await 2026-03-14 11:03:55 +01:00