diff --git a/.changeset/add-groq-provider.md b/.changeset/add-groq-provider.md deleted file mode 100644 index 287db3cdc..000000000 --- a/.changeset/add-groq-provider.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": minor ---- - -Added first-class provider template for Groq to the setup wizard. diff --git a/.changeset/add-orcarouter-provider.md b/.changeset/add-orcarouter-provider.md deleted file mode 100644 index 24753dfb5..000000000 --- a/.changeset/add-orcarouter-provider.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": minor ---- - -Added first-class provider template for OrcaRouter to the setup wizard. diff --git a/.changeset/add-vscode-copy-button.md b/.changeset/add-vscode-copy-button.md deleted file mode 100644 index 3ffada6f6..000000000 --- a/.changeset/add-vscode-copy-button.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Added a copy-to-clipboard button to the VS Code extension's chat panel: hovering over a user prompt or agent response bubble reveals a clipboard icon that copies the raw markdown text and briefly shows a checkmark to confirm. Streamed agent responses always copy the latest in-progress text. Closes #746. diff --git a/.changeset/bash-output-truncation.md b/.changeset/bash-output-truncation.md deleted file mode 100644 index 82fda973f..000000000 --- a/.changeset/bash-output-truncation.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -`execute_bash` and custom tools now truncate long output by keeping both the head and the tail (tail-weighted) instead of only the head, so the actionable part of compiler/test-runner output (error list, failure summary, exit status) — which usually lands at the end — isn't discarded. diff --git a/.changeset/bounded-string-replace-results.md b/.changeset/bounded-string-replace-results.md deleted file mode 100644 index e84f806d6..000000000 --- a/.changeset/bounded-string-replace-results.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Bound `string_replace` results to a context window around the edited range. diff --git a/.changeset/bright-models-fix.md b/.changeset/bright-models-fix.md deleted file mode 100644 index d3f5c970e..000000000 --- a/.changeset/bright-models-fix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@nanocollective/nanocoder': patch ---- - -Fixed the Atlas Cloud wizard to store provider-qualified GPT-5.6 model IDs, while preserving compatibility with existing shorthand configurations. Thanks to @RealBhupesh. Closes #803. diff --git a/.changeset/bright-tools-cap.md b/.changeset/bright-tools-cap.md deleted file mode 100644 index 806b978b6..000000000 --- a/.changeset/bright-tools-cap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@nanocollective/nanocoder': patch ---- - -Bound oversized tool results before they re-enter model context while preserving both the beginning and the actionable tail. diff --git a/.changeset/calm-diffs-shrink.md b/.changeset/calm-diffs-shrink.md deleted file mode 100644 index f4ceedd3a..000000000 --- a/.changeset/calm-diffs-shrink.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@nanocollective/nanocoder': patch ---- - -Fixed `diff_edit` returning the entire modified file by limiting results to changed-region previews. Thanks to @RealBhupesh. Closes #795. diff --git a/.changeset/chubby-books-behave.md b/.changeset/chubby-books-behave.md deleted file mode 100644 index 3f8ac054d..000000000 --- a/.changeset/chubby-books-behave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": minor ---- - -Added a /commit slash command that generates Conventional Commit messages from staged Git diffs using the active LLM client. Thanks to @DeepamJha. Closes #757. diff --git a/.changeset/cold-cobras-brake.md b/.changeset/cold-cobras-brake.md deleted file mode 100644 index f846af2a0..000000000 --- a/.changeset/cold-cobras-brake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Added a nanocoder svg pulse effect as a visual loading indicator in vscode extension. It uses the provided svg and css to create a pulsing animation that indicates when the agent is processing a request. diff --git a/.changeset/cozy-snails-rule.md b/.changeset/cozy-snails-rule.md deleted file mode 100644 index a845151cc..000000000 --- a/.changeset/cozy-snails-rule.md +++ /dev/null @@ -1,2 +0,0 @@ ---- ---- diff --git a/.changeset/eight-seas-matter.md b/.changeset/eight-seas-matter.md deleted file mode 100644 index 8db5dc365..000000000 --- a/.changeset/eight-seas-matter.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@nanocollective/nanocoder': patch ---- - -Defer ink and @/app loading in the CLI entry point until the interactive TUI branch, so --acp, --plain and auth paths no longer pay the Ink/App module-graph cost at startup. diff --git a/.changeset/feat-consolidate-upload.md b/.changeset/feat-consolidate-upload.md deleted file mode 100644 index e6d8520f3..000000000 --- a/.changeset/feat-consolidate-upload.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": minor ---- - -Consolidated upload actions under a single '+' menu in the VS Code webview to reduce UI clutter and improve scalability for future attachment types. diff --git a/.changeset/feat-file-attach.md b/.changeset/feat-file-attach.md deleted file mode 100644 index ae0141028..000000000 --- a/.changeset/feat-file-attach.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": minor ---- - -Added context attachment functionality with UI for file/folder chips and drag-and-drop support. diff --git a/.changeset/feat-vscode-settings-dashboard.md b/.changeset/feat-vscode-settings-dashboard.md deleted file mode 100644 index df0d4b664..000000000 --- a/.changeset/feat-vscode-settings-dashboard.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": minor ---- - -Added Settings Tab to the VS Code extension webview for configuring providers and behavior directly from the UI. diff --git a/.changeset/fix-bash-command-leading-whitespace.md b/.changeset/fix-bash-command-leading-whitespace.md deleted file mode 100644 index e9555a1b7..000000000 --- a/.changeset/fix-bash-command-leading-whitespace.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed bash commands entered with `!` keeping the whitespace that followed the prefix, so `! git status` now runs `git status` instead of ` git status`. diff --git a/.changeset/fix-cancel-stops-execution.md b/.changeset/fix-cancel-stops-execution.md deleted file mode 100644 index ad77ca111..000000000 --- a/.changeset/fix-cancel-stops-execution.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed the VS Code extension's stop button leaving a request running. Two holes: `AcpSession.cancel()` aborted the current controller and immediately replaced it with a fresh one, so a cancel that landed before the turn read the signal — the window while the agent is still resolving the prompt's file references — handed the turn an unaborted controller and the stop was lost. The controller is now rotated when a turn begins instead. Separately, the extension never answered the agent's pending permission request when you hit stop: the tool card kept its spinner and Allow/Deny buttons, and because the request stayed on the pending list every later message was refused with "Please approve or deny the pending tool before sending a new message" until the window was reloaded. Stopping (or reconnecting after the agent process restarts) now resolves those requests as cancelled. Thanks to @akramcodez. Closes #864. diff --git a/.changeset/fix-copilot-reasoning-item-id-rotation.md b/.changeset/fix-copilot-reasoning-item-id-rotation.md deleted file mode 100644 index 497607c31..000000000 --- a/.changeset/fix-copilot-reasoning-item-id-rotation.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed `Cannot read properties of undefined (reading 'summaryParts')` when streaming from GitHub Copilot with reasoning models such as `gpt-5.3-codex`. Copilot's Responses API proxy rotates the opaque reasoning item id mid-stream while `output_index` stays stable, so the OpenAI Responses parser looked up state that was never registered and the stream died. Copilot's response stream is now normalized before it reaches the parser: a rotated id is mapped back to the reasoning item already tracked at that `output_index`, and a reasoning item that was never announced is announced first. Closes #719. diff --git a/.changeset/fix-empty-thought-dropdown.md b/.changeset/fix-empty-thought-dropdown.md deleted file mode 100644 index f4abb83c5..000000000 --- a/.changeset/fix-empty-thought-dropdown.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed the VS Code extension's thought dropdown expanding to nothing. Streamed tokens are batched behind a 150ms timer, and the reasoning/text routing flag was driven by the `reasoning-start` / `text-start` markers around a batch rather than by the deltas that filled it — so any provider whose ordering differs (the OpenAI Responses API defers `reasoning-end` until the reasoning item completes; openai-compatible providers reopen reasoning without closing text; some emit deltas with no start marker at all) delivered reasoning as assistant text and left the thought view empty. Routing now follows the delta type and flushes the pending batch before switching streams, so a batch always leaves on the callback it was filled for. Whitespace-only reasoning no longer emits an ACP thought chunk, is no longer stored on the message, and no longer opens a thought section, so the empty "Thought for 0s" bubbles are gone. Thanks to @akramcodez. Closes #853. diff --git a/.changeset/fix-fetch-url-ipv6-loopback.md b/.changeset/fix-fetch-url-ipv6-loopback.md deleted file mode 100644 index 413395d89..000000000 --- a/.changeset/fix-fetch-url-ipv6-loopback.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Block IPv6 loopback in the `fetch_url` SSRF guard. The validator rejected `127.0.0.1` but let `http://[::1]:8080` through, so the loopback protection could be bypassed over IPv6. It now also rejects `[::1]` (and its expanded/IPv4-mapped spellings) and the `[::]` unspecified address. Closes #734. diff --git a/.changeset/fix-json-usage-block-reporting.md b/.changeset/fix-json-usage-block-reporting.md deleted file mode 100644 index 812cb451a..000000000 --- a/.changeset/fix-json-usage-block-reporting.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed the `usage` block in the `--plain --json` run report being emitted as all zeros for providers that report no token telemetry, and reading as zero total spend for providers that report input/output counts without a total. The block is now omitted entirely unless at least one token count is actually reported, and `totalTokens` falls back to input+output when the provider omits it, so downstream harnesses can distinguish "no telemetry available" from a genuine zero. diff --git a/.changeset/fix-korean-terminal-input.md b/.changeset/fix-korean-terminal-input.md deleted file mode 100644 index 096d21a3e..000000000 --- a/.changeset/fix-korean-terminal-input.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed multibyte terminal input being corrupted when an alternate-screen stdin chunk split a UTF-8 character, which could affect Korean and other IME input. diff --git a/.changeset/fix-mcp-failed-tool-discovery.md b/.changeset/fix-mcp-failed-tool-discovery.md deleted file mode 100644 index 261a59417..000000000 --- a/.changeset/fix-mcp-failed-tool-discovery.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed an MCP server staying visible as connected when its initial `tools/list` call failed. `connectToServer()` now registers the client, transport, and config only after tool discovery succeeds, and closes the partially-established client on failure so its transport/child process doesn't leak. diff --git a/.changeset/fix-prompt-history-end.md b/.changeset/fix-prompt-history-end.md deleted file mode 100644 index 8e97f3766..000000000 --- a/.changeset/fix-prompt-history-end.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed prompt history navigation returning an invalid value after reaching the end of the history. `getNextString()` now returns `null`, matching the behavior of the other history navigation methods. diff --git a/.changeset/fix-update-cache-network-guards.md b/.changeset/fix-update-cache-network-guards.md deleted file mode 100644 index d91dde6c6..000000000 --- a/.changeset/fix-update-cache-network-guards.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed update checks incorrectly recording a successful check after a registry fetch failure, corrected `BoundedMap.has()` for entries whose value is `undefined`, and restored network-error classification for Node.js errno codes. Closes #739, #738, and #737. diff --git a/.changeset/fix-vscode-reject-all-await.md b/.changeset/fix-vscode-reject-all-await.md deleted file mode 100644 index 081317901..000000000 --- a/.changeset/fix-vscode-reject-all-await.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed the VS Code extension's **Reject All** running rejection cleanups concurrently: `rejectAll()` fired the async `rejectChange()` without awaiting, so overlapping cleanups raced over shared editor state (stale tab snapshots in `closeEditors()`). Rejections now run sequentially, mirroring `applyAll()`. Thanks to @jmdlrg. Closes #725. diff --git a/.changeset/fix-vscode-short-message-wrap.md b/.changeset/fix-vscode-short-message-wrap.md deleted file mode 100644 index 1cdf7a3c0..000000000 --- a/.changeset/fix-vscode-short-message-wrap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed short user messages wrapping mid-word in the VS Code extension chat. The message bubble carried `max-w-[85%]` on top of the turn wrapper's own `max-w-[85%]`, so the inner percentage resolved against the wrapper's shrink-to-fit width and squeezed each bubble to 85% of its own content - combined with `break-words`, "hey" rendered as "he" / "y". The bubble now uses `max-w-full` and the cap lives only on the wrapper. diff --git a/.changeset/fix-vscode-tool-aggregator-reset.md b/.changeset/fix-vscode-tool-aggregator-reset.md deleted file mode 100644 index ae0fb3da1..000000000 --- a/.changeset/fix-vscode-tool-aggregator-reset.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed new tool calls landing back in an earlier card instead of a fresh one when a thought, reply, edit card, or plan update came in between. Closes #856. - -Fixed a manually collapsed tool card re-expanding on its next update. - -Reused one footer per agent turn instead of creating one per text segment. - -Fixed a turn's copy button sometimes copying a newer turn's text instead of its own. diff --git a/.changeset/fix-vscode-windows-cli-spawn.md b/.changeset/fix-vscode-windows-cli-spawn.md deleted file mode 100644 index 159e0cf8b..000000000 --- a/.changeset/fix-vscode-windows-cli-spawn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed the VS Code extension being unable to start the CLI on Windows. `where.exe` lists npm's unexecutable extensionless shim before `nanocoder.cmd`, and the first line was taken blindly; spawning a `.cmd` also fails with EINVAL because Node refuses to run one without a shell (CVE-2024-27980). Discovery now ranks `where.exe` matches by extension, the CLI is launched via the JS entrypoint resolved from the shim, and a `.cmd` that cannot be resolved falls back to a quoted shell spawn. Spawn failures are also caught and reported in the Nanocoder output channel instead of being swallowed as an unhandled rejection that left the UI stuck on "Connecting". diff --git a/.changeset/fix-wizard-list-overflow.md b/.changeset/fix-wizard-list-overflow.md deleted file mode 100644 index 3774f0bbb..000000000 --- a/.changeset/fix-wizard-list-overflow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed the provider wizard appearing to hang after picking models. Finishing model selection with `d` returned to the raw provider template list, where the only way to proceed was scrolling past every template to a trailing "Done & Save" — a ~34-row screen that overflows a normal terminal, so the entry was off screen and the wizard looked stuck. Adding a provider now lands on the wizard's root menu, which offers "Done & Save" up front, and the template, edit, and MCP server lists scroll within the terminal height instead of overflowing it. diff --git a/.changeset/group-vscode-thought-blocks.md b/.changeset/group-vscode-thought-blocks.md deleted file mode 100644 index cab1b0428..000000000 --- a/.changeset/group-vscode-thought-blocks.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Grouped the VS Code extension's streamed thoughts into a single expandable section per response instead of one dropdown per thought block. Thoughts interrupted by answer text or tool calls now resume in the same section, separated by a blank line, and the header reports the total time spent reasoning ("Thought for 12s") rather than one short duration per fragment. The section still auto-expands while thoughts stream and collapses when they stop, but stops doing so once the user toggles it by hand. Closes #854. diff --git a/.changeset/improve-vscode-cli-discovery-nvm.md b/.changeset/improve-vscode-cli-discovery-nvm.md deleted file mode 100644 index 67da2c718..000000000 --- a/.changeset/improve-vscode-cli-discovery-nvm.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed an issue where the VS Code extension failed to locate the Nanocoder CLI for users using Node version managers (NVM, Volta, fnm, pnpm, bun). A fallback directory scan is now performed when `which`/`where` cannot resolve the binary under the extension host's minimal PATH. The child-process PATH is also enriched with the CLI's directory only when a co-located `node` binary is present, preventing shadowing of a user's version-manager Node. Thanks to @akramcodez. diff --git a/.changeset/list-directory-opt-in-sizes.md b/.changeset/list-directory-opt-in-sizes.md deleted file mode 100644 index 6f508c4a6..000000000 --- a/.changeset/list-directory-opt-in-sizes.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": minor ---- - -`list_directory` no longer includes file sizes by default — they cost an `lstat` syscall per file plus output tokens for information that's rarely needed just to orient in a directory. Pass `showSizes=true` to opt back in, or use `read_file` with `metadata_only=true` for a single file's size. diff --git a/.changeset/loud-plums-invite.md b/.changeset/loud-plums-invite.md deleted file mode 100644 index f37778630..000000000 --- a/.changeset/loud-plums-invite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Setup wizard's config location picker now shows the resolved path next to each option instead of a bare label. diff --git a/.changeset/per-response-usage-indicator.md b/.changeset/per-response-usage-indicator.md deleted file mode 100644 index 96e98e810..000000000 --- a/.changeset/per-response-usage-indicator.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": minor ---- - -Added a per-response token usage and estimated cost indicator. Every assistant message in the CLI now ends with a subtle gray footer showing the provider-reported token count and estimated cost (e.g. `Tokens: 4.2k | ~$0.01`), computed from models.dev pricing; the cost segment is omitted for local/free models and the footer falls back to the previous client-side estimate when the provider reports no usage. The VS Code extension shows the same indicator under each finished response, fed by the per-turn usage now returned on the ACP prompt response. Note: the estimate prices all input tokens at the standard rate — cache read/write discounts are not factored in, so costs can be overstated for providers with prompt caching. Closes #756. diff --git a/.changeset/preserve-manual-session-title.md b/.changeset/preserve-manual-session-title.md deleted file mode 100644 index 7a3ae58d4..000000000 --- a/.changeset/preserve-manual-session-title.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@nanocollective/nanocoder': patch ---- - -Fixed a renamed session losing its manual title when reopened in the CLI. The ACP agent rebuilds the session record field-by-field on every save and wasn't carrying `titleManuallySet` through, so the flag was dropped from disk after the next message. The title survived inside the VS Code extension via its own guard, but the CLI's autosave then saw an unflagged session and overwrote the user's name with an auto-derived one. diff --git a/.changeset/quiet-git-diffs.md b/.changeset/quiet-git-diffs.md deleted file mode 100644 index 11dcd8663..000000000 --- a/.changeset/quiet-git-diffs.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Bound oversized multi-file `git_diff` results to a 20-entry diffstat while preserving the total file count, and kept file-scoped results as bounded head-and-tail patches. diff --git a/.changeset/quiet-rays-cache.md b/.changeset/quiet-rays-cache.md deleted file mode 100644 index 53748b889..000000000 --- a/.changeset/quiet-rays-cache.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Prevent concurrent file-cache reads from clearing a newer pending read. diff --git a/.changeset/restore-acp-provider-identifiers.md b/.changeset/restore-acp-provider-identifiers.md deleted file mode 100644 index c9a592c62..000000000 --- a/.changeset/restore-acp-provider-identifiers.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed ACP provider discovery after the SDK 1.3 update by including the required provider identifier. diff --git a/.changeset/scope-copy-to-last-response.md b/.changeset/scope-copy-to-last-response.md deleted file mode 100644 index ad25d21a5..000000000 --- a/.changeset/scope-copy-to-last-response.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -VS Code extension: `/copy` and `/copy code` now address the whole last assistant response rather than its final text fragment, so a tool call between the code block and the closing prose no longer hides the block. Also collapses inner whitespace in the `/copy code` intercept, reports "No response to copy yet" on an empty transcript, and replies with a pointer instead of "Unrecognized slash command" if `/copy` reaches the ACP agent. diff --git a/.changeset/search-results-compact-separator.md b/.changeset/search-results-compact-separator.md deleted file mode 100644 index 0954cda74..000000000 --- a/.changeset/search-results-compact-separator.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -`search_file_contents` no longer puts a blank line between context-free matches, and decides its layout from the `contextLines` argument rather than sniffing each match for a newline. A context block that collapsed to a single line (single-line files, or when truncation dropped every newline) previously rendered with the exact-match header and a doubled line number. diff --git a/.changeset/search-results-grep-format.md b/.changeset/search-results-grep-format.md deleted file mode 100644 index d9569e2b8..000000000 --- a/.changeset/search-results-grep-format.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -`search_file_contents` now formats results grep-style (`file:line:content`, one line per match) instead of spreading each match across three lines with a blank separator. Matches with `contextLines` still show the full multi-line context block, now with a `-` header separator matching grep's convention. diff --git a/.changeset/settings-consolidation.md b/.changeset/settings-consolidation.md deleted file mode 100644 index 24e65c8ff..000000000 --- a/.changeset/settings-consolidation.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": minor ---- - -Moved the rest of nanocoder's configuration into the `/settings` menu, so you can set things up without editing `.json` files by hand. Settings are grouped into Appearance, Input, Behavior, Providers, and Advanced tabs. New menu items let you set the default mode, auto-compact, sessions, reasoning traces, tool auto-approval, and a Web Search API key; view your configured providers and MCP servers before opening the setup wizards; open the Tune Model and Connect IDE wizards; and see the active `NANOCODER_*` environment variables. Advanced also includes an in-app JSON editor for `agents.config.json`: edit strings with the cursor inside the quotes, flip booleans with the arrow keys, and save atomically (a crash can't leave a half-written file). diff --git a/.changeset/show-user-bash-output.md b/.changeset/show-user-bash-output.md deleted file mode 100644 index d5741cdc4..000000000 --- a/.changeset/show-user-bash-output.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fixed user-typed `!` bash commands showing no output in the transcript. Previously the completed card only displayed the command, a status dot, and a token count — the actual result was sent to the model but never shown to the person who typed the command. Completed `!` commands now render their stdout and stderr (tail-capped at 20 lines, with a note when earlier lines are hidden). Model-invoked `execute_bash` calls keep their compact display. diff --git a/.changeset/six-goats-rhyme.md b/.changeset/six-goats-rhyme.md deleted file mode 100644 index 3ee617547..000000000 --- a/.changeset/six-goats-rhyme.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Add token usage block to the --plain --json run report. Downstream tooling consuming headless JSON output can now read input/output/total token counts per run, when the provider reports them. Closes #821. diff --git a/.changeset/sunset-setup-commands.md b/.changeset/sunset-setup-commands.md deleted file mode 100644 index 4ca098476..000000000 --- a/.changeset/sunset-setup-commands.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": minor ---- - -Sunset `/setup-providers` and `/setup-mcp` in favour of `/settings`. Both retired names still work for now — they open the matching `/settings` tab with a notice instead of erroring. `/settings` now takes a tab argument (`/settings providers`, `/settings mcp`), MCP has its own settings tab, and provider edits made from settings apply to the running session instead of waiting for the next launch. Selecting a provider or MCP server in settings now opens that entry's edit/delete choice directly, with a separate row for adding a new one. diff --git a/.changeset/tame-waves-move.md b/.changeset/tame-waves-move.md deleted file mode 100644 index a845151cc..000000000 --- a/.changeset/tame-waves-move.md +++ /dev/null @@ -1,2 +0,0 @@ ---- ---- diff --git a/.changeset/tasty-books-mix.md b/.changeset/tasty-books-mix.md deleted file mode 100644 index a845151cc..000000000 --- a/.changeset/tasty-books-mix.md +++ /dev/null @@ -1,2 +0,0 @@ ---- ---- diff --git a/.changeset/themed-selection-highlight.md b/.changeset/themed-selection-highlight.md deleted file mode 100644 index 38dc61812..000000000 --- a/.changeset/themed-selection-highlight.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@nanocollective/nanocoder': patch ---- - -Fixed the unreadable selection highlight in the setup wizards and other list selectors. `ink-select-input`'s built-in indicator and selected-label renderer hardcode a dark `blue` that ignores the active theme and all but vanishes against a dark terminal; every selector now routes through `StyledSelectInput` and highlights with the theme's `primary` colour instead. Also raised five themes whose highlight or body text fell below WCAG AA contrast against their own background (cherry-blossom, ayu-light, everforest-light, volcanic-ash, solarized-light). Closes #827. diff --git a/.changeset/tolocalestring-llm-payload.md b/.changeset/tolocalestring-llm-payload.md deleted file mode 100644 index 493c0587e..000000000 --- a/.changeset/tolocalestring-llm-payload.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Dropped `toLocaleString()` thousands-separators from strings returned to the model (`read_file`'s metadata output and validator error, `list_directory`'s per-entry size, and `@file`-mention metadata). Comma separators cost extra tokens without adding meaning for the model. Left them in place in the terminal display components, where they're actually useful. diff --git a/.changeset/tough-poems-read.md b/.changeset/tough-poems-read.md deleted file mode 100644 index 632368715..000000000 --- a/.changeset/tough-poems-read.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Return a useful preview before requiring ranged reads for very large files diff --git a/.changeset/true-moons-tease.md b/.changeset/true-moons-tease.md deleted file mode 100644 index a845151cc..000000000 --- a/.changeset/true-moons-tease.md +++ /dev/null @@ -1,2 +0,0 @@ ---- ---- diff --git a/.changeset/twelve-peaches-dig.md b/.changeset/twelve-peaches-dig.md deleted file mode 100644 index 66dc2f7f5..000000000 --- a/.changeset/twelve-peaches-dig.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Fix notification titles showing stale project name after changing directories with /cd diff --git a/.changeset/vscode-agent-action-roadmap.md b/.changeset/vscode-agent-action-roadmap.md deleted file mode 100644 index e98e6bef8..000000000 --- a/.changeset/vscode-agent-action-roadmap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -The VS Code chat panel now shows the agent's queued work, not just what it has already done. Every tool call in a turn is announced before the batch runs, so the checklist reads queued → running → done, and rows are labelled in plain English ("Reading source/x.ts", "Running pnpm test") instead of raw tool names. Queued edits read "Edit x.ts" until they actually run, and their Open Diff action only becomes clickable once the diff exists — previously the card claimed the edit was already done and clicking through raised "Change not found". File edits render as their own card with an Open Diff action again — the panel had been matching tool names the agent never sends, which made that card unreachable and left failed edits spinning forever. Cancelling a turn now settles every queued row rather than leaving the ones behind the cancelled tool spinning, which also fixes the same stall in other ACP clients such as Zed. The task checklist is now scoped to the turn that produced it instead of one card reused for the whole session. diff --git a/.changeset/vscode-code-lens-actions.md b/.changeset/vscode-code-lens-actions.md deleted file mode 100644 index c79ac7af7..000000000 --- a/.changeset/vscode-code-lens-actions.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": minor ---- - -Added editor code lenses to the VS Code extension: every function, method, constructor and class now carries `Explain Code` and `Generate Tests` links, and clicking one reveals the chat view and sends that symbol - instruction, `file:startLine-endLine` and the source, fenced with the document language - as a prompt. Symbols come from the language server, so no per-language parsing is involved, and the lenses can be turned off with `nanocoder.codeLens`. Long symbols are capped before being inlined, so a lens click on a large class cannot spend a whole context window on one turn. Also fixes a pre-existing hang where sending a message while a tool approval was still pending left the composer spinning forever. Closes #750. diff --git a/.changeset/vscode-context-mentions.md b/.changeset/vscode-context-mentions.md deleted file mode 100644 index 81ebc71ff..000000000 --- a/.changeset/vscode-context-mentions.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": minor ---- - -Added `@` mention autocomplete to the VS Code extension's chat composer: typing `@` opens a floating dropdown of workspace files, folders and open editors, and selecting one attaches it as a context chip. Search runs on the extension host, which merges your `files.exclude` and `search.exclude` settings into the exclude list so hidden files stay out of the dropdown, and a bare `@` lists open editor tabs with no disk I/O. Attached files are now read with a 100 KB cap and binaries are skipped, so a mis-picked lockfile can no longer swallow the context window. Closes #747. diff --git a/.changeset/vscode-escape-cancels-request.md b/.changeset/vscode-escape-cancels-request.md deleted file mode 100644 index ed31b0673..000000000 --- a/.changeset/vscode-escape-cancels-request.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Pressing Escape in the VS Code extension's chat panel now instantly cancels an in-flight LLM request, mirroring the Stop button. -The listener is registered on the webview's `document` (not just the chat input) so it fires even when focus has moved to a tool card, button, or the streaming response area. -Also added a `nanocoder.cancel` command for the Command Palette. -The backend already tears down the in-flight request via `AbortController` when a cancel is received, so this stops token generation immediately rather than just hiding output, and cancelling now shows a clean "Cancelled by user" note inline in the chat instead of an error toast. - -Cancelling while a tool is waiting for approval no longer wedges the chat. -Previously the pending permission resolver was left in place, so the extension kept reporting an outstanding prompt and rejected every later message with "Please approve or deny the pending tool" until the window was reloaded. -Cancelling (or starting a new chat) now answers any outstanding permission requests with a cancelled outcome and dismisses their approval cards. - -Fixed cancelled tool cards rendering with the error icon. -ACP has no `cancelled` tool status, so a cancel arrives as `failed` with `Cancelled by user` in the raw output, but the webview matched that string case-sensitively against `cancelled` and never hit it. diff --git a/.changeset/vscode-image-upload.md b/.changeset/vscode-image-upload.md deleted file mode 100644 index d196b8666..000000000 --- a/.changeset/vscode-image-upload.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": minor ---- - -Added support for image uploads and pasting in the VS Code extension chat panel, allowing users to send multimodal messages (text + images) to the AI assistant. diff --git a/.changeset/vscode-session-rename.md b/.changeset/vscode-session-rename.md deleted file mode 100644 index 35061f97f..000000000 --- a/.changeset/vscode-session-rename.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Improved session management in the VS Code extension: - -- **Session renaming**: Sessions can now be renamed directly from the History view. A `renameSession` ACP extension method (`extMethod`) is implemented on the CLI's ACP agent and backed by the existing session manager, so a session's title can be updated in place without a full resume. -- **History view navigation**: Creating a new chat or resuming a session from the History list now returns to the active chat view instead of leaving the panel stuck on the session list. diff --git a/.changeset/wacky-tables-shout.md b/.changeset/wacky-tables-shout.md deleted file mode 100644 index 16adcb944..000000000 --- a/.changeset/wacky-tables-shout.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Clarify read-before-edit refusal messages to specify that files over 300 lines need a ranged read diff --git a/.changeset/wicked-kiwis-send.md b/.changeset/wicked-kiwis-send.md deleted file mode 100644 index 1d72bba89..000000000 --- a/.changeset/wicked-kiwis-send.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": minor ---- - -VS Code extension: Added `/copy code` and a Ctrl+Alt+Shift+C (Cmd+Alt+Shift+C on macOS) keybinding to copy the last code block from the previous assistant response. diff --git a/.changeset/widen-terminal-width.md b/.changeset/widen-terminal-width.md deleted file mode 100644 index 824d41416..000000000 --- a/.changeset/widen-terminal-width.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -Increased the bounded terminal content width from 120 to 200 columns so wide terminals use more available space while retaining a sane layout cap. diff --git a/.changeset/write-file-echo.md b/.changeset/write-file-echo.md deleted file mode 100644 index a60495f47..000000000 --- a/.changeset/write-file-echo.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nanocollective/nanocoder": patch ---- - -`write_file` no longer echoes the full file contents back after writing. The model already authored that content as the tool call arguments, so returning it again was pure duplication that scaled with file size and got re-sent on every later step of the agent loop. The confirmation message (line/char/token counts) is unchanged. diff --git a/CHANGELOG.md b/CHANGELOG.md index a6005fa87..1d2bb2c09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,89 @@ # @nanocollective/nanocoder +# 1.30.0 + +- Added first-class provider template for Groq to the setup wizard. +- Added first-class provider template for OrcaRouter to the setup wizard. +- Added a /commit slash command that generates Conventional Commit messages from staged Git diffs using the active LLM client. Thanks to @DeepamJha. Closes #757. +- Consolidated upload actions under a single '+' menu in the VS Code webview to reduce UI clutter and improve scalability for future attachment types. +- Added context attachment functionality with UI for file/folder chips and drag-and-drop support. +- Added Settings Tab to the VS Code extension webview for configuring providers and behavior directly from the UI. +- `list_directory` no longer includes file sizes by default — they cost an `lstat` syscall per file plus output tokens for information that's rarely needed just to orient in a directory. Pass `showSizes=true` to opt back in, or use `read_file` with `metadata_only=true` for a single file's size. +- Added a per-response token usage and estimated cost indicator. Every assistant message in the CLI now ends with a subtle gray footer showing the provider-reported token count and estimated cost (e.g. `Tokens: 4.2k | ~$0.01`), computed from models.dev pricing; the cost segment is omitted for local/free models and the footer falls back to the previous client-side estimate when the provider reports no usage. The VS Code extension shows the same indicator under each finished response, fed by the per-turn usage now returned on the ACP prompt response. Note: the estimate prices all input tokens at the standard rate — cache read/write discounts are not factored in, so costs can be overstated for providers with prompt caching. Closes #756. +- Moved the rest of nanocoder's configuration into the `/settings` menu, so you can set things up without editing `.json` files by hand. Settings are grouped into Appearance, Input, Behavior, Providers, and Advanced tabs. New menu items let you set the default mode, auto-compact, sessions, reasoning traces, tool auto-approval, and a Web Search API key; view your configured providers and MCP servers before opening the setup wizards; open the Tune Model and Connect IDE wizards; and see the active `NANOCODER_*` environment variables. Advanced also includes an in-app JSON editor for `agents.config.json`: edit strings with the cursor inside the quotes, flip booleans with the arrow keys, and save atomically (a crash can't leave a half-written file). +- Sunset `/setup-providers` and `/setup-mcp` in favour of `/settings`. Both retired names still work for now — they open the matching `/settings` tab with a notice instead of erroring. `/settings` now takes a tab argument (`/settings providers`, `/settings mcp`), MCP has its own settings tab, and provider edits made from settings apply to the running session instead of waiting for the next launch. Selecting a provider or MCP server in settings now opens that entry's edit/delete choice directly, with a separate row for adding a new one. +- Added editor code lenses to the VS Code extension: every function, method, constructor and class now carries `Explain Code` and `Generate Tests` links, and clicking one reveals the chat view and sends that symbol - instruction, `file:startLine-endLine` and the source, fenced with the document language - as a prompt. Symbols come from the language server, so no per-language parsing is involved, and the lenses can be turned off with `nanocoder.codeLens`. Long symbols are capped before being inlined, so a lens click on a large class cannot spend a whole context window on one turn. Also fixes a pre-existing hang where sending a message while a tool approval was still pending left the composer spinning forever. Closes #750. +- Added `@` mention autocomplete to the VS Code extension's chat composer: typing `@` opens a floating dropdown of workspace files, folders and open editors, and selecting one attaches it as a context chip. Search runs on the extension host, which merges your `files.exclude` and `search.exclude` settings into the exclude list so hidden files stay out of the dropdown, and a bare `@` lists open editor tabs with no disk I/O. Attached files are now read with a 100 KB cap and binaries are skipped, so a mis-picked lockfile can no longer swallow the context window. Closes #747. +- Added support for image uploads and pasting in the VS Code extension chat panel, allowing users to send multimodal messages (text + images) to the AI assistant. +- VS Code extension: Added `/copy code` and a Ctrl+Alt+Shift+C (Cmd+Alt+Shift+C on macOS) keybinding to copy the last code block from the previous assistant response. + +- Added a copy-to-clipboard button to the VS Code extension's chat panel: hovering over a user prompt or agent response bubble reveals a clipboard icon that copies the raw markdown text and briefly shows a checkmark to confirm. Streamed agent responses always copy the latest in-progress text. Closes #746. +- `execute_bash` and custom tools now truncate long output by keeping both the head and the tail (tail-weighted) instead of only the head, so the actionable part of compiler/test-runner output (error list, failure summary, exit status) — which usually lands at the end — isn't discarded. +- Bound `string_replace` results to a context window around the edited range. +- Fixed the Atlas Cloud wizard to store provider-qualified GPT-5.6 model IDs, while preserving compatibility with existing shorthand configurations. Thanks to @RealBhupesh. Closes #803. +- Bound oversized tool results before they re-enter model context while preserving both the beginning and the actionable tail. +- Fixed `diff_edit` returning the entire modified file by limiting results to changed-region previews. Thanks to @RealBhupesh. Closes #795. +- Added a nanocoder svg pulse effect as a visual loading indicator in vscode extension. It uses the provided svg and css to create a pulsing animation that indicates when the agent is processing a request. +- Defer ink and @/app loading in the CLI entry point until the interactive TUI branch, so --acp, --plain and auth paths no longer pay the Ink/App module-graph cost at startup. +- Fixed bash commands entered with `!` keeping the whitespace that followed the prefix, so `! git status` now runs `git status` instead of ` git status`. +- Fixed the VS Code extension's stop button leaving a request running. Two holes: `AcpSession.cancel()` aborted the current controller and immediately replaced it with a fresh one, so a cancel that landed before the turn read the signal — the window while the agent is still resolving the prompt's file references — handed the turn an unaborted controller and the stop was lost. The controller is now rotated when a turn begins instead. Separately, the extension never answered the agent's pending permission request when you hit stop: the tool card kept its spinner and Allow/Deny buttons, and because the request stayed on the pending list every later message was refused with "Please approve or deny the pending tool before sending a new message" until the window was reloaded. Stopping (or reconnecting after the agent process restarts) now resolves those requests as cancelled. Thanks to @akramcodez. Closes #864. +- Fixed `Cannot read properties of undefined (reading 'summaryParts')` when streaming from GitHub Copilot with reasoning models such as `gpt-5.3-codex`. Copilot's Responses API proxy rotates the opaque reasoning item id mid-stream while `output_index` stays stable, so the OpenAI Responses parser looked up state that was never registered and the stream died. Copilot's response stream is now normalized before it reaches the parser: a rotated id is mapped back to the reasoning item already tracked at that `output_index`, and a reasoning item that was never announced is announced first. Closes #719. +- Fixed the VS Code extension's thought dropdown expanding to nothing. Streamed tokens are batched behind a 150ms timer, and the reasoning/text routing flag was driven by the `reasoning-start` / `text-start` markers around a batch rather than by the deltas that filled it — so any provider whose ordering differs (the OpenAI Responses API defers `reasoning-end` until the reasoning item completes; openai-compatible providers reopen reasoning without closing text; some emit deltas with no start marker at all) delivered reasoning as assistant text and left the thought view empty. Routing now follows the delta type and flushes the pending batch before switching streams, so a batch always leaves on the callback it was filled for. Whitespace-only reasoning no longer emits an ACP thought chunk, is no longer stored on the message, and no longer opens a thought section, so the empty "Thought for 0s" bubbles are gone. Thanks to @akramcodez. Closes #853. +- Block IPv6 loopback in the `fetch_url` SSRF guard. The validator rejected `127.0.0.1` but let `http://[::1]:8080` through, so the loopback protection could be bypassed over IPv6. It now also rejects `[::1]` (and its expanded/IPv4-mapped spellings) and the `[::]` unspecified address. Closes #734. +- Fixed the `usage` block in the `--plain --json` run report being emitted as all zeros for providers that report no token telemetry, and reading as zero total spend for providers that report input/output counts without a total. The block is now omitted entirely unless at least one token count is actually reported, and `totalTokens` falls back to input+output when the provider omits it, so downstream harnesses can distinguish "no telemetry available" from a genuine zero. +- Fixed multibyte terminal input being corrupted when an alternate-screen stdin chunk split a UTF-8 character, which could affect Korean and other IME input. +- Fixed an MCP server staying visible as connected when its initial `tools/list` call failed. `connectToServer()` now registers the client, transport, and config only after tool discovery succeeds, and closes the partially-established client on failure so its transport/child process doesn't leak. +- Fixed prompt history navigation returning an invalid value after reaching the end of the history. `getNextString()` now returns `null`, matching the behavior of the other history navigation methods. +- Fixed update checks incorrectly recording a successful check after a registry fetch failure, corrected `BoundedMap.has()` for entries whose value is `undefined`, and restored network-error classification for Node.js errno codes. Closes #739, #738, and #737. +- Fixed the VS Code extension's **Reject All** running rejection cleanups concurrently: `rejectAll()` fired the async `rejectChange()` without awaiting, so overlapping cleanups raced over shared editor state (stale tab snapshots in `closeEditors()`). Rejections now run sequentially, mirroring `applyAll()`. Thanks to @jmdlrg. Closes #725. +- Fixed short user messages wrapping mid-word in the VS Code extension chat. The message bubble carried `max-w-[85%]` on top of the turn wrapper's own `max-w-[85%]`, so the inner percentage resolved against the wrapper's shrink-to-fit width and squeezed each bubble to 85% of its own content - combined with `break-words`, "hey" rendered as "he" / "y". The bubble now uses `max-w-full` and the cap lives only on the wrapper. +- Fixed new tool calls landing back in an earlier card instead of a fresh one when a thought, reply, edit card, or plan update came in between. Closes #856. + +Fixed a manually collapsed tool card re-expanding on its next update. + +Reused one footer per agent turn instead of creating one per text segment. + +Fixed a turn's copy button sometimes copying a newer turn's text instead of its own. +- Fixed the VS Code extension being unable to start the CLI on Windows. `where.exe` lists npm's unexecutable extensionless shim before `nanocoder.cmd`, and the first line was taken blindly; spawning a `.cmd` also fails with EINVAL because Node refuses to run one without a shell (CVE-2024-27980). Discovery now ranks `where.exe` matches by extension, the CLI is launched via the JS entrypoint resolved from the shim, and a `.cmd` that cannot be resolved falls back to a quoted shell spawn. Spawn failures are also caught and reported in the Nanocoder output channel instead of being swallowed as an unhandled rejection that left the UI stuck on "Connecting". +- Fixed the provider wizard appearing to hang after picking models. Finishing model selection with `d` returned to the raw provider template list, where the only way to proceed was scrolling past every template to a trailing "Done & Save" — a ~34-row screen that overflows a normal terminal, so the entry was off screen and the wizard looked stuck. Adding a provider now lands on the wizard's root menu, which offers "Done & Save" up front, and the template, edit, and MCP server lists scroll within the terminal height instead of overflowing it. +- Grouped the VS Code extension's streamed thoughts into a single expandable section per response instead of one dropdown per thought block. Thoughts interrupted by answer text or tool calls now resume in the same section, separated by a blank line, and the header reports the total time spent reasoning ("Thought for 12s") rather than one short duration per fragment. The section still auto-expands while thoughts stream and collapses when they stop, but stops doing so once the user toggles it by hand. Closes #854. +- Fixed an issue where the VS Code extension failed to locate the Nanocoder CLI for users using Node version managers (NVM, Volta, fnm, pnpm, bun). A fallback directory scan is now performed when `which`/`where` cannot resolve the binary under the extension host's minimal PATH. The child-process PATH is also enriched with the CLI's directory only when a co-located `node` binary is present, preventing shadowing of a user's version-manager Node. Thanks to @akramcodez. +- Setup wizard's config location picker now shows the resolved path next to each option instead of a bare label. +- Fixed a renamed session losing its manual title when reopened in the CLI. The ACP agent rebuilds the session record field-by-field on every save and wasn't carrying `titleManuallySet` through, so the flag was dropped from disk after the next message. The title survived inside the VS Code extension via its own guard, but the CLI's autosave then saw an unflagged session and overwrote the user's name with an auto-derived one. +- Bound oversized multi-file `git_diff` results to a 20-entry diffstat while preserving the total file count, and kept file-scoped results as bounded head-and-tail patches. +- Prevent concurrent file-cache reads from clearing a newer pending read. +- Fixed ACP provider discovery after the SDK 1.3 update by including the required provider identifier. +- VS Code extension: `/copy` and `/copy code` now address the whole last assistant response rather than its final text fragment, so a tool call between the code block and the closing prose no longer hides the block. Also collapses inner whitespace in the `/copy code` intercept, reports "No response to copy yet" on an empty transcript, and replies with a pointer instead of "Unrecognized slash command" if `/copy` reaches the ACP agent. +- `search_file_contents` no longer puts a blank line between context-free matches, and decides its layout from the `contextLines` argument rather than sniffing each match for a newline. A context block that collapsed to a single line (single-line files, or when truncation dropped every newline) previously rendered with the exact-match header and a doubled line number. +- `search_file_contents` now formats results grep-style (`file:line:content`, one line per match) instead of spreading each match across three lines with a blank separator. Matches with `contextLines` still show the full multi-line context block, now with a `-` header separator matching grep's convention. +- Fixed user-typed `!` bash commands showing no output in the transcript. Previously the completed card only displayed the command, a status dot, and a token count — the actual result was sent to the model but never shown to the person who typed the command. Completed `!` commands now render their stdout and stderr (tail-capped at 20 lines, with a note when earlier lines are hidden). Model-invoked `execute_bash` calls keep their compact display. +- Add token usage block to the --plain --json run report. Downstream tooling consuming headless JSON output can now read input/output/total token counts per run, when the provider reports them. Closes #821. +- Fixed the unreadable selection highlight in the setup wizards and other list selectors. `ink-select-input`'s built-in indicator and selected-label renderer hardcode a dark `blue` that ignores the active theme and all but vanishes against a dark terminal; every selector now routes through `StyledSelectInput` and highlights with the theme's `primary` colour instead. Also raised five themes whose highlight or body text fell below WCAG AA contrast against their own background (cherry-blossom, ayu-light, everforest-light, volcanic-ash, solarized-light). Closes #827. +- Dropped `toLocaleString()` thousands-separators from strings returned to the model (`read_file`'s metadata output and validator error, `list_directory`'s per-entry size, and `@file`-mention metadata). Comma separators cost extra tokens without adding meaning for the model. Left them in place in the terminal display components, where they're actually useful. +- Return a useful preview before requiring ranged reads for very large files +- Fix notification titles showing stale project name after changing directories with /cd +- The VS Code chat panel now shows the agent's queued work, not just what it has already done. Every tool call in a turn is announced before the batch runs, so the checklist reads queued → running → done, and rows are labelled in plain English ("Reading source/x.ts", "Running pnpm test") instead of raw tool names. Queued edits read "Edit x.ts" until they actually run, and their Open Diff action only becomes clickable once the diff exists — previously the card claimed the edit was already done and clicking through raised "Change not found". File edits render as their own card with an Open Diff action again — the panel had been matching tool names the agent never sends, which made that card unreachable and left failed edits spinning forever. Cancelling a turn now settles every queued row rather than leaving the ones behind the cancelled tool spinning, which also fixes the same stall in other ACP clients such as Zed. The task checklist is now scoped to the turn that produced it instead of one card reused for the whole session. +- Pressing Escape in the VS Code extension's chat panel now instantly cancels an in-flight LLM request, mirroring the Stop button. +The listener is registered on the webview's `document` (not just the chat input) so it fires even when focus has moved to a tool card, button, or the streaming response area. +Also added a `nanocoder.cancel` command for the Command Palette. +The backend already tears down the in-flight request via `AbortController` when a cancel is received, so this stops token generation immediately rather than just hiding output, and cancelling now shows a clean "Cancelled by user" note inline in the chat instead of an error toast. + +Cancelling while a tool is waiting for approval no longer wedges the chat. +Previously the pending permission resolver was left in place, so the extension kept reporting an outstanding prompt and rejected every later message with "Please approve or deny the pending tool" until the window was reloaded. +Cancelling (or starting a new chat) now answers any outstanding permission requests with a cancelled outcome and dismisses their approval cards. + +Fixed cancelled tool cards rendering with the error icon. +ACP has no `cancelled` tool status, so a cancel arrives as `failed` with `Cancelled by user` in the raw output, but the webview matched that string case-sensitively against `cancelled` and never hit it. +- Improved session management in the VS Code extension: + +- **Session renaming**: Sessions can now be renamed directly from the History view. A `renameSession` ACP extension method (`extMethod`) is implemented on the CLI's ACP agent and backed by the existing session manager, so a session's title can be updated in place without a full resume. +- **History view navigation**: Creating a new chat or resuming a session from the History list now returns to the active chat view instead of leaving the panel stuck on the session list. +- Clarify read-before-edit refusal messages to specify that files over 300 lines need a ranged read +- Increased the bounded terminal content width from 120 to 200 columns so wide terminals use more available space while retaining a sane layout cap. +- `write_file` no longer echoes the full file contents back after writing. The model already authored that content as the tool call arguments, so returning it again was pure duplication that scaled with file size and got re-sent on every later step of the agent loop. The confirmation message (line/char/token counts) is unchanged. + +If there are any problems, feedback or thoughts please drop an issue or message us through Discord! Thank you for using Nanocoder. + # 1.29.0 - Added the ability to attach to a running subagent session from the terminal UI for interactive debugging. This feature allows users to inspect exactly what a subagent is doing in real-time, including streaming text and reasoning. You can press `Ctrl+S` while a subagent is running to attach to it, cycle between multiple running subagents, and press `Esc` to detach. diff --git a/package.json b/package.json index d28b72e3c..724cbdacc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@nanocollective/nanocoder", "main": "dist/cli.js", - "version": "1.29.0", + "version": "1.30.0", "description": "An open coding agent for your terminal, built by a community collective rather than a company. Bring your own model, keep your code on your machine, and owe nothing to anyone.", "keywords": [ "cli",