diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 0ee8c012..2537c1f1 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.3.0" + ".": "0.4.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 869d18ef..1a5584fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,26 +2,53 @@ ## [Unreleased] -### Features - -- `User ClaudeCodeSendComplete` autocmd, fired once per file when a send is accepted while Claude is connected, with `data = { file_path, start_line, end_line, context }` (lines 0-indexed). Lets you run arbitrary post-send logic — in particular, focus a Claude session running outside Neovim (`provider = "none"`/`"external"`), e.g. via `tmux select-pane`, which `focus_after_send` cannot do. ([#228](https://github.com/coder/claudecode.nvim/issues/228)) -- `:ClaudeCodeCloseAllDiffs` command to close pending Claude diffs at once (e.g. proposals orphaned by resolving them via Claude remote control). A diff you accepted with `:w` closes once the file holds the accepted text. When the file does not hold it yet, the command puts the text into the file's buffer as unsaved changes, for `:w` or `:e!`, so accepted edits are never discarded. ([#248](https://github.com/coder/claudecode.nvim/issues/248)) -- `:ClaudeCodeSendText {text}` command (and `require("claudecode.terminal").send_to_terminal(text, opts)` function) to send arbitrary text to the open Claude terminal as if typed at the prompt, submitting it by default. `:ClaudeCodeSendText!` inserts the text without submitting. Handy for scripting and keymaps; multi-line text is sent via bracketed paste. Works with the in-editor `native`/`snacks` providers only — `external`/`none` run Claude outside Neovim, where there is no pane to write to. ([#197](https://github.com/coder/claudecode.nvim/issues/197)) -- `terminal.auto_insert` option (default `true`) controlling whether the Claude terminal auto-enters insert/terminal mode when its window gains focus. With the default Snacks provider, switching back into the terminal window (e.g. `l`) previously re-entered terminal mode and jumped to the bottom prompt, discarding your Normal-mode scroll/reading position; set `auto_insert = false` to stay in Normal mode and preserve the scroll position (press `i` to type). Applies to the `native` and `snacks` providers and the new-tab diff terminal. ([#232](https://github.com/coder/claudecode.nvim/issues/232), [#145](https://github.com/coder/claudecode.nvim/issues/145)) -- `diff_opts.layout = "unified"`: a unified diff rendered in a single buffer with deleted (red/strikethrough) and added (green) lines interleaved, as a compact alternative to the two-pane `"vertical"`/`"horizontal"` layouts. Requires Neovim >= 0.9.0; the `ClaudeCodeInlineDiffAdd`/`Delete`/`AddSign`/`DeleteSign` highlight groups are customizable. ([#82](https://github.com/coder/claudecode.nvim/issues/82), [#195](https://github.com/coder/claudecode.nvim/pull/195), [#293](https://github.com/coder/claudecode.nvim/issues/293)) - -### Bug Fixes - -- The native terminal provider now adopts only terminal buffers it started, which it marks with `b:claudecode_native_terminal`. Before, `:ClaudeCode`, `:ClaudeCodeFocus`, and `:ClaudeCodeOpen` adopted any visible terminal whose name contained `claude`, for example a shell started inside a `claudecode.nvim` checkout. Upgrade note: a terminal that an older plugin version started (for example after `:Lazy reload` following an upgrade), or that a session file restored, carries no mark and is no longer adopted. The next open starts a second Claude session, and the old terminal keeps running until you close its buffer or quit Claude in it. ([#349](https://github.com/coder/claudecode.nvim/pull/349)) -- `closeAllDiffTabs` no longer destroys diffs it does not own. It previously closed every window with `&diff` set and force-deleted any buffer named like `*.diff`/`diff://`/`fugitive://`, so an open diffview.nvim, fugitive, or native `:diffsplit` review was wiped out — and because the Claude CLI calls this tool at the start of every turn, it happened on essentially every prompt. The tool is now scoped to claudecode's own tracked diffs (matching the official VS Code extension, which only closes the tabs it labelled). Relatedly, `openFile`/`openDiff` no longer reuse a window that is in diff mode, which previously `:edit`-ed over one side of an unrelated diff and broke its layout. ([#277](https://github.com/coder/claudecode.nvim/issues/277)) -- The Claude terminal now adds the loopback hosts (`localhost`, `127.0.0.1`, `::1`) to `no_proxy`/`NO_PROXY`, so a configured `http_proxy`/`all_proxy` no longer tunnels Claude's `ws://127.0.0.1` IDE connection and causes queued @ mentions to time out. Existing `no_proxy` exclusions are preserved. ([#70](https://github.com/coder/claudecode.nvim/issues/70)) -- `focus_after_send = true` no longer fails silently with `terminal.provider = "none"`/`"external"`: those providers run Claude outside Neovim, so focus cannot move there. A one-time warning is now emitted at setup pointing to the new `User ClaudeCodeSendComplete` autocmd, which you can hook to focus your own terminal. (`focus_after_send` still only auto-focuses the in-editor providers.) ([#228](https://github.com/coder/claudecode.nvim/issues/228)) -- Rejecting a Claude diff with `:q` (or `:close` / `c` / closing the tab) now resolves it as rejected, matching the documented behavior. The proposed buffer is a scratch buffer that `:q` only hides, so the existing `BufDelete`/`BufUnload`/`BufWipeout` autocmds never fired; a `WinClosed` autocmd now handles window-close rejection. ([#238](https://github.com/coder/claudecode.nvim/issues/238)) -- Push quickly-made visual selections to Claude reliably. Selections made and released faster than the selection-tracking debounce were never broadcast, and any selection was wiped shortly after leaving visual mode when Claude runs in an external terminal (the `/ide` flow) — so single-line selections in particular often never reached Claude. Selections are now flushed synchronously on visual-mode exit (from the `'<`/`'>` marks) and persist until the cursor actually moves; a single-line linewise `V` made right after a charwise selection is also no longer mis-extracted to a single character. ([#246](https://github.com/coder/claudecode.nvim/issues/246)) -- Diffs opened via `openDiff` no longer linger forever when they are resolved outside this Neovim or their Claude session goes away. Pending diffs are now automatically closed when the client that opened them disconnects or the integration is stopped, and `closeAllDiffTabs` now also resolves/cleans the diff module's tracked state instead of only closing windows. ([#248](https://github.com/coder/claudecode.nvim/issues/248)) -- Show diffs when the Claude Code terminal is the only window (no other splits). Previously `openDiff` failed with "No suitable editor window found"; now a split is created to host the diff, matching the behavior of the `openFile` tool. ([#231](https://github.com/coder/claudecode.nvim/issues/231)) -- Fix the "climbing cursor" in the Snacks terminal: hiding and re-showing the Claude panel no longer leaves the cursor one row above the prompt (so typed text lands on the wrong line). The Snacks provider now hides/shows without destroying the window — floats are parked via `nvim_win_set_config({hide=...})` and splits are recreated like the native provider — which preserves the cursor anchor Claude re-renders against on focus-in. Splits are fixed on all supported Neovim versions; the float fix requires Neovim >= 0.10. ([#240](https://github.com/coder/claudecode.nvim/issues/240), [#183](https://github.com/coder/claudecode.nvim/issues/183)) -- Work around a Neovim core bug (< 0.12.2) that fragmented large bracketed pastes into the terminal across `vim.paste` phases, making Cmd+V appear to truncate content. Added a scoped, version-gated `vim.paste` shim controlled by `terminal.fix_streamed_paste` (`"auto"` by default; no-op on Neovim >= 0.12.2). ([#161](https://github.com/coder/claudecode.nvim/issues/161)) +## [0.4.0] - 2026-11-09 + +### Added + +- `:ClaudeCodeSendText {text}` command and `require("claudecode.terminal").send_to_terminal(text, opts)` to send arbitrary text to the open Claude terminal as if typed at the prompt (submitting by default; `:ClaudeCodeSendText!` inserts without submitting). Multi-line text is sent via bracketed paste. Works with the in-editor `native`/`snacks` providers only. ([#197](https://github.com/coder/claudecode.nvim/issues/197), [#272](https://github.com/coder/claudecode.nvim/pull/272)) +- `:checkhealth claudecode` health check that verifies Neovim version, `setup()`, the Claude CLI, terminal provider, WebSocket server, lock file, and live connection state. ([#275](https://github.com/coder/claudecode.nvim/pull/275)) +- `:ClaudeCodeCloseAllDiffs` command to close pending Claude diffs at once. A diff accepted with `:w` closes once the file holds the accepted text; otherwise the accepted text is put into the buffer as unsaved changes for `:w`/`:e!` so edits are never discarded. ([#248](https://github.com/coder/claudecode.nvim/issues/248), [#261](https://github.com/coder/claudecode.nvim/pull/261)) +- `diff_opts.layout = "unified"`: a VS Code-style unified diff rendered in a single buffer with interleaved deleted/added lines, as a compact alternative to `"vertical"`/`"horizontal"`. Documented to require Neovim >= 0.9.0. Customizable via the `ClaudeCodeInlineDiffAdd`/`Delete`/`AddSign`/`DeleteSign` highlight groups. ([#195](https://github.com/coder/claudecode.nvim/pull/195), [#295](https://github.com/coder/claudecode.nvim/pull/295), [#297](https://github.com/coder/claudecode.nvim/pull/297)) +- `User ClaudeCodeSendComplete` autocmd, fired once per file when a send is accepted while Claude is connected, with `data = { file_path, start_line, end_line, context }` (lines 0-indexed). Enables post-send logic such as focusing a Claude session running outside Neovim. ([#228](https://github.com/coder/claudecode.nvim/issues/228), [#265](https://github.com/coder/claudecode.nvim/pull/265)) +- `User ClaudeCodeDiffOpened` / `ClaudeCodeDiffClosed` autocmds carrying diff metadata, plus `diff_opts.auto_resize_terminal` (default `true`) to opt out of plugin-managed terminal width during diffs and `terminal.diff_split_width_percentage` to set a distinct terminal width while a diff is open. ([#270](https://github.com/coder/claudecode.nvim/pull/270)) +- `terminal.auto_insert` option (default `true`): set to `false` to stay in Normal mode when refocusing the Claude terminal and preserve your scroll position instead of jumping to the prompt. ([#233](https://github.com/coder/claudecode.nvim/pull/233)) +- `ClaudeCodeTreeAdd` / `as` support in snacks.nvim pickers (`snacks_picker_list`), covering `Snacks.explorer()` and modal `Snacks.picker.files()`/`grep()`. ([#192](https://github.com/coder/claudecode.nvim/issues/192), [#269](https://github.com/coder/claudecode.nvim/pull/269)) +- netrw file selection for `as` / `:ClaudeCodeTreeAdd`, supporting marked files and the file under the cursor. ([#62](https://github.com/coder/claudecode.nvim/pull/62)) + +### Changed + +- Model picker labels are now version-free evergreen aliases (`Claude Opus (Latest)`, `Claude Sonnet (Latest)`, `Claude Haiku (Latest)`), with new 1M-context variants (`opus[1m]`, `sonnet[1m]`) and a `Default (account recommended)` entry. ([#146](https://github.com/coder/claudecode.nvim/pull/146), [#256](https://github.com/coder/claudecode.nvim/pull/256)) +- `:checkhealth claudecode` and the MCP `serverInfo.version` now report the real plugin version from the `VERSION` file instead of a hard-coded value. ([#437](https://github.com/coder/claudecode.nvim/pull/437)) + +### Fixed + +- The Snacks provider no longer fails to launch Claude when a model alias contains shell-glob characters (e.g. `opus[1m]`); the command is now passed as an argv list with no shell interpretation. ([#256](https://github.com/coder/claudecode.nvim/pull/256)) +- The native terminal now adopts only terminal buffers it started (marked with `b:claudecode_native_terminal`), instead of any visible terminal whose name contains `claude`. Upgrade note: a terminal that an older plugin version started (for example after `:Lazy reload` following an upgrade), or that a session file restored, carries no mark and is no longer adopted. The next open starts a second Claude session, and the old terminal keeps running until you close its buffer or quit Claude in it. ([#349](https://github.com/coder/claudecode.nvim/pull/349), [#352](https://github.com/coder/claudecode.nvim/pull/352), [#364](https://github.com/coder/claudecode.nvim/pull/364)) +- `closeAllDiffTabs` is now scoped to claudecode's own tracked diffs and no longer wipes out an open diffview.nvim, fugitive, or native `:diffsplit` review; `openFile`/`openDiff` also never reuse a window that is in diff mode. ([#277](https://github.com/coder/claudecode.nvim/issues/277), [#290](https://github.com/coder/claudecode.nvim/pull/290)) +- `close_tab` now closes only the diff with that tab name and never deletes a user buffer. ([#373](https://github.com/coder/claudecode.nvim/pull/373)) +- Closing the native terminal, for example with `:ClaudeCodeClose`, now stops the Claude job instead of leaving it running. ([#336](https://github.com/coder/claudecode.nvim/pull/336)) +- The Claude terminal now adds loopback hosts to `no_proxy`/`NO_PROXY` so a configured proxy no longer tunnels Claude's `ws://127.0.0.1` IDE connection and times out queued @ mentions. ([#70](https://github.com/coder/claudecode.nvim/issues/70), [#268](https://github.com/coder/claudecode.nvim/pull/268)) +- `focus_after_send = true` with `provider = "none"`/`"external"` now emits a one-time warning pointing to the `User ClaudeCodeSendComplete` autocmd instead of failing silently. ([#228](https://github.com/coder/claudecode.nvim/issues/228), [#265](https://github.com/coder/claudecode.nvim/pull/265)) +- Rejecting a Claude diff with `:q` / `:close` / `c` (or closing the tab) now resolves it as rejected via a `WinClosed` autocmd. ([#266](https://github.com/coder/claudecode.nvim/pull/266)) +- Quickly-made and single-line visual selections are now pushed to Claude reliably; selections are flushed synchronously on visual-mode exit and persist until the cursor moves, including in the external `/ide` flow and Select mode. ([#246](https://github.com/coder/claudecode.nvim/issues/246), [#267](https://github.com/coder/claudecode.nvim/pull/267), [#367](https://github.com/coder/claudecode.nvim/pull/367), [#381](https://github.com/coder/claudecode.nvim/pull/381), [#388](https://github.com/coder/claudecode.nvim/pull/388)) +- Pending diffs are now automatically closed when the client that opened them disconnects or the integration stops, so orphaned proposals no longer linger. ([#248](https://github.com/coder/claudecode.nvim/issues/248), [#261](https://github.com/coder/claudecode.nvim/pull/261)) +- `openDiff` now works when the Claude terminal is the only window, creating a split to host the diff instead of failing with "No suitable editor window found". ([#260](https://github.com/coder/claudecode.nvim/pull/260)) +- Fixed the "climbing cursor" in the Snacks terminal, where the cursor sat one row above Claude's prompt after hide and show. On Neovim >= 0.10 a floating terminal is now hidden instead of closed. A split is still closed on hide and created again on show, which keeps the cursor in place. Floating terminals on Neovim < 0.10 keep the old behavior. ([#240](https://github.com/coder/claudecode.nvim/issues/240), [#183](https://github.com/coder/claudecode.nvim/issues/183), [#271](https://github.com/coder/claudecode.nvim/pull/271)) +- Worked around a Neovim core bug (< 0.12.2) that fragmented large bracketed pastes into the terminal; controlled by `terminal.fix_streamed_paste` (`"auto"` by default). ([#252](https://github.com/coder/claudecode.nvim/pull/252)) +- `openFile` now selects exactly the requested line range or matched text, keeps the user's Visual mode, unsaved changes, focus and preview window intact, never prompts W11/W12, and never picks the preview window as the main editor window. ([#353](https://github.com/coder/claudecode.nvim/pull/353), [#365](https://github.com/coder/claudecode.nvim/pull/365), [#370](https://github.com/coder/claudecode.nvim/pull/370), [#375](https://github.com/coder/claudecode.nvim/pull/375), [#382](https://github.com/coder/claudecode.nvim/pull/382), [#384](https://github.com/coder/claudecode.nvim/pull/384), [#387](https://github.com/coder/claudecode.nvim/pull/387), [#396](https://github.com/coder/claudecode.nvim/pull/396), [#408](https://github.com/coder/claudecode.nvim/pull/408)) +- `getDiagnostics` now handles plain file paths without a `file://` URI scheme, and IDE diagnostics return grouped URI-based payloads with editor-native ranges and severity names. ([#163](https://github.com/coder/claudecode.nvim/pull/163), [#274](https://github.com/coder/claudecode.nvim/pull/274)) +- `:ClaudeCodeAdd` and `openFile` now handle `$` in file paths. ([#286](https://github.com/coder/claudecode.nvim/pull/286)) +- Prevented a segfault when accepting a new-file diff with `render-markdown.nvim` installed, by turning off diff mode before the post-write redraw. ([#224](https://github.com/coder/claudecode.nvim/pull/224)) +- The auth token is now generated from a CSPRNG and the lock file is written atomically with mode `0600` in a `0700` directory. ([#259](https://github.com/coder/claudecode.nvim/pull/259)) +- Detect system sleep/wake and reset client keepalive timestamps to prevent false disconnections. ([#141](https://github.com/coder/claudecode.nvim/pull/141)) +- The WebSocket server now retries port binding on `EADDRINUSE` (parallel instances), closes connections on malformed/oversized or binary frames with the correct status, joins fragmented messages, validates UTF-8 per message, and never repeats a client id within a process. ([#258](https://github.com/coder/claudecode.nvim/pull/258), [#283](https://github.com/coder/claudecode.nvim/issues/283), [#378](https://github.com/coder/claudecode.nvim/pull/378), [#383](https://github.com/coder/claudecode.nvim/pull/383), [#390](https://github.com/coder/claudecode.nvim/pull/390), [#395](https://github.com/coder/claudecode.nvim/pull/395), [#405](https://github.com/coder/claudecode.nvim/pull/405), [#422](https://github.com/coder/claudecode.nvim/pull/422), [#431](https://github.com/coder/claudecode.nvim/pull/431)) +- Legacy `diff_opts` (e.g. `vertical_split`, `open_in_current_tab`) now take effect again after the config merge-order regression. ([#142](https://github.com/coder/claudecode.nvim/pull/142)) +- `:q` on a diff window no longer hangs; floating diff terminals keep focus; empty buffers are wiped when the terminal provider is `none`; and accepted diffs are handed over in the buffer's own line-ending format. ([#178](https://github.com/coder/claudecode.nvim/pull/178), [#223](https://github.com/coder/claudecode.nvim/pull/223), [#266](https://github.com/coder/claudecode.nvim/pull/266), [#392](https://github.com/coder/claudecode.nvim/pull/392)) + +### Compatibility + +- Integration tests now run on Neovim v0.8.0, and a new-tab diff no longer fails there because Neovim 0.8 has no `statuscolumn`. The unified layout is documented to require Neovim >= 0.9.0, and the v0.8.0 integration tests skip it. ([#369](https://github.com/coder/claudecode.nvim/pull/369), [#394](https://github.com/coder/claudecode.nvim/pull/394)) ## [0.3.0] - 2025-09-15 diff --git a/VERSION b/VERSION index 0d91a54c..1d0ba9ea 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.0 +0.4.0