Commit Graph

1855 Commits

Author SHA1 Message Date
can1357 dc4aeb7b88 refactor(coding-agent): renamed todo_write tool to todo
- Renamed `TodoWriteTool` to `TodoTool` and its source/prompt files.
- Updated tool registration, schema, renderers, and gating to `todo`.
- Adjusted cursor provider native tool names and tests to match.
- Renamed strike-animation constants and `todo-error-reminder` type.
2026-06-04 02:45:30 +02:00
can1357 b9c204c69e feat(session): added indexed async session backends and removed synchronous read APIs
- Added `IndexedSessionStorage` with `SessionStorageBackend` for index-based storage reads.
- Removed `readTextSync` from the public `SessionStorage` API and sync backends.
- Changed Redis and SQL backends to warm `{size, mtimeMs}` metadata and read via `readTextSlices`.
- Added per-path write queues and `drain()` to serialize operations and surface first failures.
2026-06-04 02:27:06 +02:00
can1357 5e17edf1ec refactor(coding-agent): restructured session text slicing to use unified head/tail reads
- Replaced SessionStorage readTextPrefix/readTextSuffix with readTextSlices.
- Added peekFileEnds utility to read bounded file head/tail in one handle.
- Updated session-manager list/recent reads to consume unified head/tail slices.
- Expanded storage tests for head/tail and UTF-8-boundary slice extraction.
2026-06-04 02:07:34 +02:00
can1357 e6716d086d feat(coding-agent): added lifecycle status to session picker
- Classified each session's final message as done, interrupted, aborted, error, or pending from a 32 KiB tail read.
- Rendered the status as a colored segment on the session metadata line.
- Added `peekFileTail` and `readTextSuffix` across storage backends to read file tails in one pass.
- Simplified `MemorySessionStorage` to a string array mirror with a sidecar mtime map.
2026-06-04 01:58:25 +02:00
can1357 b1b4b0c0ed feat(coding-agent/tools): allowed .. aliases for line range selectors
- Extended line selector parsing in path-utils to accept `..` as a forgiving alias for `-`, with `..` normalized during chunk parsing.
- Updated selector-matching regexes for file selectors and internal URL selectors to recognize alias-style ranges in single chunks and comma-separated lists.
- Added tests covering `N..M`, `N..`, mixed separators, inverted-range errors, and path-splitting behavior with `:N..M` selectors and `foo:../bar.ts` paths.
2026-06-04 01:35:39 +02:00
can1357 53aaced81f feat: enabled text-sizing and fixed OSC66 and DECCARA rendering behavior
- Added `textSizing` terminal capability and `tui.textSizing` setting for Kitty OSC66 scaling.
- Updated OSC66 range and visible-width handling to preserve grapheme slice behavior.
- Updated markdown rendering to apply heading text sizing only when enabled.
- Fixed DECCARA trailing-background fill tracking and DECRPM status 3/4 recognition.
2026-06-04 01:33:48 +02:00
can1357 ea105b4211 refactor(packages/coding-agent): reorganized notification flow and tests
- Updated completion and ask notifications to pass structured payloads.
- Updated completion and ask notifications to include explicit message metadata fields.
- Adjusted abort-guard and retry-capability tests for the new notification/options behavior.
2026-06-04 00:59:59 +02:00
can1357 48017b5f67 feat(packages/coding-agent): added terminal protocol debug diagnostics
- Added debug menu options for terminal state and protocol checks with new handlers.
- Added terminal diagnostics models and collectors to report geometry, protocol flags, and multiplexer data.
- Added protocol-probe utilities to encode RGB PNGs, generate sample content, and render test panels.
- Added support components for verbatim line rendering and OSC66-scaled text rows.
- Added tests validating image encoding, OSC66 output, and terminal state formatting.
2026-06-04 00:50:46 +02:00
can1357 ead9e72602 feat(ai): classified account rate limits as quota exhaustion
- Added account rate-limit pattern matching for QUOTA_EXHAUSTED.
- Treated account rate limits as credential-rotatable usage limits.
2026-06-03 23:08:58 +02:00
can1357 8647ab6883 fix(fetch): repaired collapsed URL scheme from path normalization
- Restored `https:/` → `https://` before URL parsing and detection.
- Prevented path-normalized URLs from falling through to filesystem lookup.
2026-06-03 23:03:44 +02:00
can1357 13d116bf15 fix(hashline): treated empty replace hunks as deletes
- Updated the grammar to parse replace hunks with zero body lines.
- Changed empty replace execution to emit delete edits across the target range.
- Updated tests to verify empty replace syntax deletes lines while empty inserts still throw errors.
2026-06-03 22:53:19 +02:00
can1357 9a544b6ee0 feat(coding-agent): added radio markers for single-choice ask options
- Rendered single-choice questions with circular radio glyphs instead of checkboxes.
- Kept rectangular checkboxes for multi-select questions.
- Added radio.selected/unselected symbols to unicode, nerd-font, and ASCII presets.
2026-06-03 22:21:06 +02:00
can1357 a1a9176c19 fix(coding-agent/modes): collapsed hook option descriptions in compact overflow mode
- Updated hook option rendering to support description modes for full text, bounded rows, or hidden detail output.
- Adjusted compact-mode row budgeting so list height is based on labels, preventing a single description from consuming the visible budget.
- Added pre-wrapping with ellipsis truncation for selected option descriptions and updated overflow tests to validate the collapsed label-first behavior.
2026-06-03 21:34:07 +02:00
can1357 2e14db49ca fix(coding-agent/utils): fixed jj workspace detection for non-default .jj/repo indirection
- Detection now recognized `.jj/repo` as workspace metadata whether it is a directory or a file.
- Repository resolution followed `.jj/repo` file indirection so non-default `jj workspace add` workspaces resolved their shared store path.
- Tests were added to confirm `jj.repo.is` and `jj.repo.resolve` handle file-backed `.jj/repo` workspaces correctly.
2026-06-03 16:37:03 +02:00
can1357 e1b2809154 feat(coding-agent): added plan read matching and compaction protection behavior
- Added shared `getReadToolPath` API to extract paired read `path` values for protection matchers.
- Added `createPlanReadMatcher` and session wiring so compaction prune/shake keeps active plan reads intact.
- Updated `todo-write` instructions to initialize every user-supplied plan item as an individual task.
- Added compaction tests validating plan reads are protected from prune and shake while regular reads are still removable.
2026-06-03 16:14:15 +02:00
can1357 ed5db7bf3a test(coding-agent): fixed hanging tests by using non-empty assistant content
- Empty `content: []` triggered the empty-stop guard, short-circuiting the agent_end handler before compaction checks ran.
- Replaced with a minimal text turn so auto-compaction queue resume tests complete under fake timers.
2026-06-03 10:48:48 +02:00
can1357 17b6de2fc7 test(ai): replaced curl-based LM Studio detection with model discovery
- Added async `discoverLmStudioModel()` to query the OpenAI and native LM Studio APIs, resolving the actual model id, name, and context window.
- Replaced hardcoded `execSync curl` availability check with API-driven discovery controlled by `PI_LOCAL_LLM` env var.
- Simplified compaction test spy to match on provider only, removing fragile context-marker filtering.
2026-06-03 10:17:43 +02:00
can1357 eda1a1056b feat(coding-agent): added matcherDigest hook for TTSR wire-format normalization
- Added optional `AgentTool.matcherDigest(args)` hook so tools can expose plain source text instead of wire-encoded arguments to TTSR rule matchers.
- Implemented `matcherDigest` on edit (all modes: hashline, patch, apply_patch, replace) and write tools, stripping patch prefixes and JSON escaping.
- Added `TtsrManager.checkSnapshot()` to replace the scoped buffer with a tool digest rather than appending raw deltas.
- Fixed TTSR conditions never matching streamed edit/write calls whose wire format obscured real content.
2026-06-03 10:05:24 +02:00
can1357 6baa985672 feat(coding-agent): added ts-no-deprecated-leftovers builtin rule
- Warns against leaving `@deprecated` compatibility shims instead of finishing a refactor.
- Registered in the builtin rule index and covered by the defaults test.
2026-06-03 00:13:24 +02:00
can1357 bce01ce0db refactor(jj): restructured exports into namespaced repo and diff objects
- Grouped `isRepository`, `workspaceRoot`, and `clearWorkspaceRootCache` under a `repo` namespace (`repo.is`, `repo.root`, `repo.clearRootCache`).
- Promoted `diff` to a named export with a `changedFiles` sub-method via `Object.assign`.
- Added `ensureAvailable` check and `nameOnly` support to `diff`.
- Updated callers and tests to use the new API surface.
2026-06-03 00:13:05 +02:00
can1357 9b4a951919 refactor(jj): replaced subprocess-based workspace detection with fs walk
- Replaced `jj workspace root` subprocess call with a local `.jj/repo/store` directory traversal, eliminating process spawning overhead.
- Added LRU cache for resolved workspace roots to avoid redundant filesystem walks.
- Renamed internal `runCommand` helpers to `git`/`jj` for clarity.
- Replaced git subprocess setup in review test with mocked `git.status` and `git.diff` calls.
2026-06-03 00:10:23 +02:00
Can Bölük f936122e60 Merge branch 'main' into jj-support-in-review 2026-06-03 00:59:35 +03:00
Can Bölük 486090d72e Merge branch 'main' into fix/empty-stop-guard 2026-06-03 00:45:49 +03:00
Can Bölük c96d5111a1 Merge pull request #1724 from Kukkerem/feat/discoverable-builtin-names
feat(coding-agent): name discoverable built-in tools in search_tool_bm25 description
2026-06-03 00:43:25 +03:00
can1357 cd9fc55572 fix: aborted internal background jobs during shell cancellation
- Added Job::abort_internal_tasks to abort internal async tasks and drop their join handles.
- Updated shell cancellation paths to call this abort logic and handle mutable shell job lists before signaling remaining process groups.
- Added Rust and TypeScript tests that verify cancellation prevents background shell jobs from completing after abort.
2026-06-02 19:30:40 +02:00
zolszabo f878eb97c6 Merge remote-tracking branch 'origin/main' into feat/discoverable-builtin-names 2026-06-02 18:18:23 +02:00
can1357 2debe7c924 Merge branch 'farm/1089210f/bug-unhandled-epipe-rejection-in-stdiotr' 2026-06-02 18:14:09 +02:00
can1357 46bbf70d49 Merge remote-tracking branch 'origin/farm/316bc3ee/fix-tui-image-paste' 2026-06-02 18:14:04 +02:00
zolszabo 55f0d97f0b feat(coding-agent): name discoverable built-in tools in search_tool_bm25 description
Surface the hidden discoverable built-in tool names (write, find, search, lsp, task, ...) in the search_tool_bm25 description when tools.discoveryMode is "all", so a model can form a targeted BM25 query by name instead of guessing or falling back to shell. mcp-only mode is unchanged (no built-ins advertised) and the total-tools count still includes them.
2026-06-02 17:55:28 +02:00
roboomp d28bee5db0 fix(providers): loaded special provider model cache
Loaded cached startup models for special built-in providers alongside standard provider descriptors so boot-time model resolution can see cached Google Antigravity, Gemini CLI, and OpenAI Codex discoveries before refresh.\n\nFixes #1721
2026-06-02 15:55:01 +00:00
roboomp 6598c69a2f fix(mcp-stdio): made close() unconditional in resource teardown
Per second review on #1711: when notify()'s write failed, #handleClose()
flipped #connected=false before the throw. connectToServer()'s catch
then called transport.close(), but close() early-returned because
#connected was already false — so #process.kill() and the readLoop
await never ran. A subprocess that closed its stdin without exiting
(parent EPIPE, transport dead, subprocess alive) would leak.

close() no longer guards on #connected for the resource phase. It still
calls #handleClose() once (idempotent — only if #connected is true), then
unconditionally walks the cleanup chain (kill process, null #process,
await + null #readLoop), each step individually guarded so repeat calls
remain no-ops. onClose still fires exactly once per transport lifetime.

Two new tests in StdioTransport.close: (1) close() called after the
read-loop has already EOF'd and torn down still completes cleanup
without throwing and without re-firing onClose; (2) repeated close()
calls fire onClose exactly once and leave #connected=false.
2026-06-02 12:35:35 +00:00
roboomp b870732258 fix(mcp-stdio): surfaced notify() write failures so handshake fails loudly
Per review on #1711: when the write inside notify() fails (FileSink EPIPE
on Windows during the initialize/notifications-initialized race), silently
closing the transport while still resolving the notify promise let
initializeConnection() return a 'connected' handle wrapping a dead
transport. The manager only wires its reconnect onClose handler after
connectToServer() resolves, so a swallowed handshake failure would
neither reconnect nor fail the connection — it would just leak.

notify() now still calls #handleClose() on write failure (so any wired
onClose runs) but additionally throws `Transport closed while sending
notification "<method>"`. The single in-tree notify caller is
initializeConnection() at client.ts:122; the rejection propagates into
connectToServer()'s catch (which closes the transport and rethrows) and
on into the manager's pending-connection error path. #sendResponse() is
unchanged — silent on failure, since a dead subprocess has no use for
the response.

Test coverage updated to document the surfaced-rejection contract and
also assert transport.connected flips to false.
2026-06-02 12:28:07 +00:00
roboomp 3dacaf263f fix(mcp-stdio): swallowed EPIPE from notify and sendResponse stdin writes
StdioTransport.notify() and #sendResponse() wrote to the subprocess's
stdin without try/catch, while the sibling request() already wrapped the
same write/flush. The #connected guard cannot close the race: connect()
sets it synchronously; #handleClose() only clears it from the read loop's
finally after EOF on stdout — strictly later than the parent's next
stdin write. When an MCP server exits between the initialize response and
the notifications/initialized notification, Bun's FileSink throws EPIPE
synchronously on Windows and the async notify wrapper surfaces it as an
unhandled rejection.

Route both call sites through a new writeFrame(stdin, frame) helper that
catches synchronous sink failures and returns a boolean. notify() now
tears the transport down via #handleClose() on failure so the reconnect
machinery engages; #sendResponse() stays silent because a dead subprocess
has no use for the response. The redundant inner try/catch around
#sendResponse in #handleServerRequest() is removed.

Fixes #1710
2026-06-02 12:22:23 +00:00
roboomp 56c47e8447 style: bun run fix 2026-06-02 11:15:22 +00:00
roboomp 5174ba0155 fix(tui): registered ctrl-v image paste on windows
Kept Ctrl+V as a default clipboard-image paste shortcut on Windows while preserving Alt+V as the Windows Terminal-safe fallback.

Updated keybinding docs and regression coverage for the platform-specific default.

Fixes #1708
2026-06-02 11:15:09 +00:00
can1357 ffbdc1056a test(coding-agent): removed CLI help load-order regression test from coding-agent
- Deleted `cli-help-load-order.test.ts` from `packages/coding-agent/test`.
2026-06-02 12:39:53 +02:00
can1357 a09b1de9f8 test(coding-agent): added timeout and teardown safety to streaming edit tests
- Defined a 20-second timeout constant for randomized streaming-edit patch tests and passed it to the success and failure cases.
- Restructured per-seed cleanup to await session disposal inside a nested finally block before closing auth storage.
- Preserved existing assertions for abort behavior while running each random chunk stream through the updated paths.
2026-06-02 12:37:12 +02:00
can1357 6c4421f3fc test(coding-agent): removed claude-trace CLI integration tests
- Deleted `packages/coding-agent/test/claude-trace-cli.test.ts`, removing tests for Claude trace CLI option parsing and message capture behavior.
2026-06-02 12:25:03 +02:00
Patrik Sundberg f5114a4ba9 Support JJ workspaces in review 2026-06-02 10:45:58 +01:00
can1357 f53efd75ca test(coding-agent/discovery): updated discovery plugin name expectations in tests
- Updated listClaudePluginRoots test assertions to expect unprefixed skill identifiers.
- Adjusted both manifest and outside-skill discovery expectations to match the updated naming.
- Ensured the tests now look for plain skill names instead of namespaced values.
2026-06-02 11:16:56 +02:00
can1357 fbed7d1787 fix: expanded tool argument parsing to accept delimiter-separated paths
- Expanded path parsing to split top-level comma, semicolon, and whitespace entries.
- Updated find/search and scope resolution to apply delimiter expansion before path-spec validation.
- Updated read tool fallback to try split path parts before raising missing-path errors.
- Coerced bare string arguments into singleton arrays for array-typed schemas.
2026-06-02 11:14:02 +02:00
can1357 7ad8e1260e feat(coding-agent): added Claude Code MITM proxy for /v1/messages capture
- Added local CONNECT proxy with TLS interception to capture Claude API traffic.
- Drives Claude Code via headless PTY/xterm and extracts the first /v1/messages exchange.
- Added `claude:trace` npm script and CLI with JSON/text output modes.
- Added integration test using a fake Claude script against a local TLS server.
2026-06-02 10:31:40 +02:00
can1357 53b998fc9c Merge remote-tracking branch 'origin/farm/1e6f50e9/document-anthropic-search-env-vars' 2026-06-02 10:11:15 +02:00
roboomp b3bcf966ee fix(coding-agent): resolve exa credentials through auth storage
ExaProvider.isAvailable() and searchExa() now consult AuthStorage so Exa credentials configured through the broker/credential store work alongside EXA_API_KEY, matching the other API-key search providers.

Refs #1695
2026-06-02 08:00:35 +00:00
roboomp b3ec588921 fix(coding-agent): honored Anthropic search base URL for fallback auth
- Passed ANTHROPIC_SEARCH_BASE_URL through to Anthropic web search calls that use authStorage fallback credentials instead of only applying it with ANTHROPIC_SEARCH_API_KEY.
- Added regression coverage asserting fallback Anthropic credentials use the search-specific base URL.
- Updated the environment and web_search docs to reflect the actual credential and base URL resolution order.

Fixes #1694
2026-06-02 07:57:34 +00:00
roboomp 963bdebf53 fix(coding-agent): require exa api key for web search
Exa web search no longer advertises availability without EXA_API_KEY and searchExa fails before attempting unauthenticated MCP.

Fixes #1695
2026-06-02 07:54:19 +00:00
roboomp dbdc77697c fix(coding-agent): retried session resume even when initial restore failed
Post-extension session-model retry now covers the case where the initial restore failed entirely (e.g. saved default unavailable, last active role supplied by an extension) and the settings default filled in the active model. Also recomputes thinking-level from full precedence against the reclaimed model so a fallback model's defaultLevel does not become sticky.\n\nFixes #1649
2026-06-02 09:15:45 +02:00
roboomp 0494454528 fix(coding-agent): retried role restore after extension providers
Initial startup resume runs before extension providers register, so a role model supplied by an extension fell back to the saved default. Retry the preferred session-model candidates once provider registrations are processed and re-resolve thinking level for the new model.\n\nFixes #1649
2026-06-02 09:15:45 +02:00
roboomp cf9eb5b0f9 fix(coding-agent): skipped temporary resume models
Treat temporary model_change roles as non-restorable when resuming sessions so context-promotion and retry-fallback models do not override the saved default.\n\nFixes #1649
2026-06-02 09:15:45 +02:00
roboomp 43405962b7 style: bun run fix 2026-06-02 09:15:45 +02:00