### Install and Setup Tools with Mise Source: https://github.com/coder/claudecode.nvim/blob/main/DEVELOPMENT.md Install all project dependencies and build necessary test tools using mise. Ensure mise is activated in your shell for PATH management. ```bash mise install mise run setup ``` -------------------------------- ### Install Mise Tools Source: https://github.com/coder/claudecode.nvim/blob/main/CLAUDE.md Install all the development tools required for the project, such as Neovim and LuaJIT, as defined in the mise.toml configuration. ```bash mise install ``` -------------------------------- ### Start Repro Workspace Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/repro/example/README.md Source the nvim-aliases.sh script and run the repro command to set up the temporary Neovim workspace. ```sh source fixtures/nvim-aliases.sh repro ``` -------------------------------- ### Start Neovim with Fixture Configuration Source: https://github.com/coder/claudecode.nvim/blob/main/CLAUDE.md Launch Neovim using a specific test configuration from the fixtures directory. This is used for integration testing. ```bash vv ``` -------------------------------- ### Live Reproduction Setup Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/issue-238/README.md This setup involves two terminals. Terminal 1 runs Neovim with the fixture's configuration. Terminal 2 holds the WebSocket connection open while you attempt to reject the diff in Neovim. ```sh # Terminal 1 — the editor under test: source fixtures/nvim-aliases.sh vv issue-238 example/target.txt # (equivalently: NVIM_APPNAME=issue-238 XDG_CONFIG_HOME=fixtures nvim fixtures/issue-238/example/target.txt) # The server auto-starts; check the lock file: ls ~/.claude/ide/*.lock ``` ```sh # Terminal 2 — open a diff and HOLD the socket open while you reject in Neovim: scripts/repro_issue_238.sh --file "$PWD/fixtures/issue-238/example/target.txt" --hold 30 ``` -------------------------------- ### Run Snacks Picker Example Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/snacks-picker/README.md Execute this command to run the snacks-picker fixture. This is used to reproduce and test the integration. ```bash source fixtures/nvim-aliases.sh vv snacks-picker ``` -------------------------------- ### Build Lua Test Rocks Source: https://github.com/coder/claudecode.nvim/blob/main/CLAUDE.md Build the necessary Lua test rocks (busted, luacheck, luacov) and install them into the ./.luarocks directory. This is a setup step for testing. ```bash mise run setup ``` -------------------------------- ### Create WebSocket Server Source: https://github.com/coder/claudecode.nvim/blob/main/PROTOCOL.md Starts a WebSocket server listening on localhost only. Ensure the port is randomized for security. ```lua -- Listen on localhost only (important!) local server = create_websocket_server("127.0.0.1", random_port) ``` -------------------------------- ### Install Claude Code Native Binary Source: https://github.com/coder/claudecode.nvim/blob/main/README.md Install the experimental native binary version of Claude Code using a curl script or by upgrading an existing installation. ```bash # Fresh install (recommended) curl -fsSL claude.ai/install.sh | bash ``` ```bash # From existing Claude Code installation claude install ``` -------------------------------- ### Source Nvim Aliases and Start Fixture Source: https://github.com/coder/claudecode.nvim/blob/main/CLAUDE.md Source the nvim-aliases.sh script to enable fixture commands, then start Neovim with the 'oil' fixture configuration. This demonstrates enabling and using fixture commands. ```bash source fixtures/nvim-aliases.sh && vv oil ``` -------------------------------- ### TCP Server Setup with vim.loop Source: https://github.com/coder/claudecode.nvim/blob/main/ARCHITECTURE.md Sets up a TCP server on localhost using Neovim's `vim.loop` for network operations. Requires a port to be specified. ```lua -- server/tcp.lua - TCP server using vim.loop local tcp = vim.loop.new_tcp() tcp:bind("127.0.0.1", port) -- Always localhost! tcp:listen(128, on_connection) ``` -------------------------------- ### Configure Claudecode.nvim for Native Binary Installation Source: https://github.com/coder/claudecode.nvim/blob/main/README.md Configure the `claudecode.nvim` plugin for the native binary installation by setting `terminal_cmd` to the output of `which claude`. ```lua { "coder/claudecode.nvim", dependencies = { "folke/snacks.nvim" }, opts = { terminal_cmd = "/path/to/your/claude", -- Use output from 'which claude' }, config = true, -- Also copy the `cmd = { ... }` list from the Installation section above so the -- :ClaudeCode* commands load without having to press a key first. keys = { -- Your keymaps here }, } ``` -------------------------------- ### Interactive Reproduction Setup Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/issue-70/README.md Set up the environment for interactive reproduction of Issue 70. This involves exporting proxy variables and unsetting no_proxy. ```sh # proxy set, localhost NOT excluded export http_proxy=http://127.0.0.1:1 https_proxy=http://127.0.0.1:1 all_proxy=http://127.0.0.1:1 unset no_proxy NO_PROXY source fixtures/nvim-aliases.sh && vv issue-70 # or the explicit form below # NVIM_APPNAME=issue-70 XDG_CONFIG_HOME="$PWD/fixtures" nvim fixtures/issue-70/sample.txt ``` -------------------------------- ### Setup Claudecode with Custom CWD Provider Source: https://github.com/coder/claudecode.nvim/blob/main/README.md Configure claudecode.nvim with a custom cwd_provider function to dynamically determine the terminal's working directory. This example prioritizes the git root. ```lua require("claudecode").setup({ terminal = { cwd_provider = function(ctx) -- Prefer repo root; fallback to file's directory local cwd = require("claudecode.cwd").git_root(ctx.file_dir or ctx.cwd) or ctx.file_dir or ctx.cwd return cwd end, }, }) ``` -------------------------------- ### Start Claude Code Server Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/repro/example/README.md Initiate the Claude code server and open the ClaudeCode interface within Neovim. ```vim :ClaudeCodeStart :ClaudeCode ``` -------------------------------- ### Configure Claudecode.nvim for Local Installation Source: https://github.com/coder/claudecode.nvim/blob/main/README.md Configure the `claudecode.nvim` plugin to use a locally installed Claude Code by specifying the `terminal_cmd` option with the path to the local binary. ```lua { "coder/claudecode.nvim", dependencies = { "folke/snacks.nvim" }, opts = { terminal_cmd = "~/.claude/local/claude", -- Point to local installation }, config = true, -- Also copy the `cmd = { ... }` list from the Installation section above so the -- :ClaudeCode* commands load without having to press a key first. keys = { -- Your keymaps here }, } ``` -------------------------------- ### Install claudecode.nvim with lazy.nvim Source: https://github.com/coder/claudecode.nvim/blob/main/README.md This snippet shows how to install the claudecode.nvim plugin using the lazy.nvim package manager. It includes dependencies, configuration options, and a comprehensive list of commands that enable lazy-loading of the plugin. ```lua { "coder/claudecode.nvim", dependencies = { "folke/snacks.nvim" }, config = true, -- `cmd` lets lazy.nvim create command stubs that load the plugin on first use, -- so `:ClaudeCode` and friends work on a fresh start. Without it, a keys-only -- spec defers loading until a a* mapping is pressed and the commands -- would not exist yet. cmd = { "ClaudeCode", "ClaudeCodeFocus", "ClaudeCodeSelectModel", "ClaudeCodeAdd", "ClaudeCodeSend", "ClaudeCodeTreeAdd", "ClaudeCodeStatus", "ClaudeCodeStart", "ClaudeCodeStop", "ClaudeCodeOpen", "ClaudeCodeClose", "ClaudeCodeDiffAccept", "ClaudeCodeDiffDeny", "ClaudeCodeCloseAllDiffs", }, keys = { { "a", nil, desc = "AI/Claude Code" }, { "ac", "ClaudeCode", desc = "Toggle Claude" }, { "af", "ClaudeCodeFocus", desc = "Focus Claude" }, { "ar", "ClaudeCode --resume", desc = "Resume Claude" }, { "aC", "ClaudeCode --continue", desc = "Continue Claude" }, { "am", "ClaudeCodeSelectModel", desc = "Select Claude model" }, { "ab", "ClaudeCodeAdd %", desc = "Add current buffer" }, { "as", "ClaudeCodeSend", mode = "v", desc = "Send to Claude" }, { "as", "ClaudeCodeTreeAdd", desc = "Add file", ft = { "NvimTree", "neo-tree", "oil", "minifiles", "netrw", "snacks_picker_list" }, }, -- Diff management { "aa", "ClaudeCodeDiffAccept", desc = "Accept diff" }, { "ad", "ClaudeCodeDiffDeny", desc = "Deny diff" }, }, } ``` -------------------------------- ### Buggy Output Example (Snacks Provider) Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/cursor-toggle-repro/README.md This output demonstrates the cursor being one row above the prompt after toggling the window with the 'snacks' provider. ```text -- provider=snacks -- baseline: cursorRow=9 promptRow=9 delta=0 after toggle 1: cursorRow=8 promptRow=9 delta=1 <- BUG (cursor one row above ❯) -- provider=native -- baseline: cursorRow=9 promptRow=9 delta=0 after toggle 1: cursorRow=9 promptRow=9 delta=0 <- fine ``` -------------------------------- ### Get Diagnostics Output Source: https://github.com/coder/claudecode.nvim/blob/main/PROTOCOL.md Example output format for language diagnostics, showing an array of diagnostics for a given file URI, including message, severity, range, and source. ```json { "content": [ { "type": "text", "text": "[{\"uri\": \"file:///path/to/file\", \"diagnostics\": [{\"message\": \"Error message\", \"severity\": \"Error\", \"range\": {\"start\": {\"line\": 0, \"character\": 0}}, \"source\": \"typescript\"}]}]" } ] } ``` -------------------------------- ### Start Neovim with Fixture Config in Edit Mode Source: https://github.com/coder/claudecode.nvim/blob/main/CLAUDE.md Launch Neovim with a specific fixture configuration and immediately enter edit mode. Useful for testing file handling or initial states. ```bash vve ``` -------------------------------- ### Native Neovim Diff Setup Source: https://github.com/coder/claudecode.nvim/blob/main/ARCHITECTURE.md Sets up a native Neovim diff view by creating a temporary file with new content, opening the original file, enabling diff mode, splitting the window, and enabling diff mode for the new file. Requires `vim.fn.tempname()` and `write_file`. ```lua -- Create temp file with proposed changes local temp_file = vim.fn.tempname() write_file(temp_file, new_content) -- Open diff in current tab to reduce clutter vim.cmd("edit " .. original_file) vim.cmd("diffthis") vim.cmd("vsplit " .. temp_file) vim.cmd("diffthis") ``` -------------------------------- ### Run Remote Diff Fixture Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/remote-diff/README.md Start the claudecode.nvim editor under test with the remote-diff fixture. This sets up the environment to observe diff behavior. ```sh # Terminal 1 — the editor under test: source fixtures/nvim-aliases.sh vv remote-diff # (equivalently: NVIM_APPNAME=remote-diff XDG_CONFIG_HOME=fixtures nvim a.txt) # The server auto-starts; check the lock file exists: # ls ~/.claude/ide/*.lock ``` -------------------------------- ### Run Live Confirmation Fixture Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/issue-228/README.md This command launches Neovim with a minimal fixture to test the `:ClaudeCodeSend` path and the new `ClaudeCodeSendComplete` event. It uses the `none` provider and a stubbed connection, allowing for manual testing of the send completion logic and observing the setup warning. ```sh nvim -u fixtures/issue-228/live.lua fixtures/issue-228/sample.txt ``` -------------------------------- ### Handle ClaudeCodeDiffOpened Event Source: https://github.com/coder/claudecode.nvim/blob/main/README.md Set up a User autocmd to react when a diff is opened. This example resizes the terminal window to 20% of the total columns. ```lua vim.api.nvim_create_autocmd("User", { pattern = "ClaudeCodeDiffOpened", callback = function(ev) local term = ev.data.terminal_window if term and vim.api.nvim_win_is_valid(term) then vim.api.nvim_win_set_width(term, math.floor(vim.o.columns * 0.20)) end end, }) ``` -------------------------------- ### Custom Terminal Provider Implementation Source: https://github.com/coder/claudecode.nvim/blob/main/README.md Implement a custom terminal provider by defining required functions like 'setup', 'open', 'close', and 'simple_toggle'. This offers maximum flexibility for terminal integration. ```lua require("claudecode").setup({ terminal = { provider = { -- Required functions setup = function(config) -- Initialize your terminal provider end, open = function(cmd_string, env_table, effective_config, focus) -- Open terminal with command and environment -- focus parameter controls whether to focus terminal (defaults to true) end, close = function() -- Close the terminal end, simple_toggle = function(cmd_string, env_table, effective_config) -- Simple show/hide toggle end, focus_toggle = function(cmd_string, env_table, effective_config) -- Smart toggle: focus terminal if not focused, hide if focused end, get_active_bufnr = function() -- Return terminal buffer number or nil return 123 -- example end, is_available = function() -- Return true if provider can be used return true end, -- Optional functions (auto-generated if not provided) toggle = function(cmd_string, env_table, effective_config) -- Defaults to calling simple_toggle for backward compatibility end, _get_terminal_for_test = function() -- For testing only, defaults to return nil return nil end, }, }, }) ``` -------------------------------- ### Setup Claudecode with Static CWD Source: https://github.com/coder/claudecode.nvim/blob/main/README.md Configure claudecode.nvim to use a specific static path as the terminal's working directory. This is set within the terminal configuration. ```lua require("claudecode").setup({ terminal = { cwd = vim.fn.expand("~/projects/my-app"), }, }) ``` -------------------------------- ### claudecode.nvim Plugin Configuration Source: https://github.com/coder/claudecode.nvim/blob/main/README.md This Lua configuration snippet shows how to set up the claudecode.nvim plugin. It covers server settings, send/focus behavior, selection tracking, terminal options, and diff integration. Ensure to adjust `terminal_cmd` for your local Claude installation. ```lua { "coder/claudecode.nvim", dependencies = { "folke/snacks.nvim" }, opts = { -- Server Configuration port_range = { min = 10000, max = 65535 }, auto_start = true, log_level = "info", -- "trace", "debug", "info", "warn", "error" terminal_cmd = nil, -- Custom terminal command (default: "claude") -- For local installations: "~/.claude/local/claude" -- For native binary: use output from 'which claude' -- Send/Focus Behavior -- When true, successful sends focus the in-editor Claude terminal if already -- connected. NOTE: this only works for in-editor providers (snacks/native); -- it has no effect with provider = "none"/"external" (Claude runs outside -- Neovim). For those, hook the `User ClaudeCodeSendComplete` event (see Events). focus_after_send = false, -- Selection Tracking track_selection = true, visual_demotion_delay_ms = 50, -- Terminal Configuration terminal = { split_side = "right", -- "left" or "right" split_width_percentage = 0.30, -- Optional: shrink (or widen) the terminal while a diff is open. Defaults to -- split_width_percentage when unset, preserving today's behavior. diff_split_width_percentage = nil, -- e.g. 0.20 to give diffs more room provider = "auto", -- "auto", "snacks", "native", "external", "none", or custom provider table auto_close = true, snacks_win_opts = {}, -- Opts to pass to `Snacks.terminal.open()` - see Floating Window section below -- Work around a Neovim core bug (< 0.12.2) that fragments large pastes into -- the terminal, making Cmd+V appear to truncate ([#161]). true | false | "auto" -- ("auto", the default, enables it only on affected Neovim versions). fix_streamed_paste = "auto", -- Provider-specific options provider_opts = { -- Command for external terminal provider. Can be: -- 1. String with %s placeholder: "alacritty -e %s" (backward compatible) -- 2. String with two %s placeholders: "alacritty --working-directory %s -e %s" (cwd, command) -- 3. Function returning command: function(cmd, env) return "alacritty -e " .. cmd end external_terminal_cmd = nil, }, }, -- Diff Integration diff_opts = { layout = "vertical", -- "vertical" or "horizontal" open_in_new_tab = false, keep_terminal_focus = false, -- If true, moves focus back to terminal after diff opens hide_terminal_in_new_tab = false, auto_resize_terminal = true, -- Let the plugin manage the terminal width across the diff lifecycle; set false to own it via the User autocmds below -- on_new_file_reject = "keep_empty", -- "keep_empty" or "close_window" -- Legacy aliases (still supported): -- vertical_split = true, -- open_in_current_tab = true, }, }, keys = { -- Your keymaps here }, } ``` -------------------------------- ### Check Claude Command Path Source: https://github.com/coder/claudecode.nvim/blob/main/README.md Use the `which` command to determine the current path of the `claude` command. This helps differentiate between global and local installations. ```bash # Check where claude command points which claude ``` -------------------------------- ### External Terminal Provider Configuration (Simple) Source: https://github.com/coder/claudecode.nvim/blob/main/README.md Configure the 'external' provider to run Claude Code in a separate terminal application. This example uses a simple string template for the command. ```lua -- Using a string template (simple) { "coder/claudecode.nvim", opts = { terminal = { provider = "external", provider_opts = { external_terminal_cmd = "alacritty -e %s", -- %s is replaced with claude command -- Or with working directory: "alacritty --working-directory %s -e %s" (first %s = cwd, second %s = command) }, }, }, } ``` -------------------------------- ### Get Diagnostics for File Source: https://github.com/coder/claudecode.nvim/blob/main/PROTOCOL.md Retrieves language diagnostics for a specific file URI. If no URI is provided, diagnostics for all files are returned. The output is a JSON-stringified array of diagnostics. ```json { "uri": "file:///path/to/file.js" } ``` -------------------------------- ### Setup Claudecode with Git Repository CWD Source: https://github.com/coder/claudecode.nvim/blob/main/README.md Configure claudecode.nvim to use the git repository root as the terminal's working directory. This option is forwarded to the terminal configuration. ```lua require("claudecode").setup({ -- Top-level aliases are supported and forwarded to terminal config git_repo_cwd = true, }) ``` -------------------------------- ### Open File and Select Text Source: https://github.com/coder/claudecode.nvim/blob/main/PROTOCOL.md Opens a specified file in the editor. Optionally, it can select a range of text within the file based on start and end text patterns. The file can be made the active tab or opened in preview mode. ```json { "filePath": "/path/to/file.js", "preview": false, "startText": "function hello", "endText": "} " "selectToEndOfLine": false, "makeFrontmost": true } ``` -------------------------------- ### Verify Claude Installation Health Source: https://github.com/coder/claudecode.nvim/blob/main/README.md Run `claude doctor` to check the health and integrity of your Claude Code installation. ```bash # Verify installation health claude doctor ``` -------------------------------- ### List Available Fixture Configurations Source: https://github.com/coder/claudecode.nvim/blob/main/CLAUDE.md Display all the available Neovim configurations within the fixtures/ directory that can be used for testing. ```bash list-configs ``` -------------------------------- ### Run Snacks Explorer Fixture Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/snacks-explorer/README.md Execute this bash command to set up and run the Snacks Explorer fixture. It sources Neovim aliases and launches the explorer with a sample text file. ```bash source fixtures/nvim-aliases.sh # `vv` always cd's to the fixtures/ dir, so pass the file path relative to it. vv snacks-explorer snacks-explorer/example/sample.txt ``` -------------------------------- ### Headless Proof: Key-Bound Action Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/snacks-picker/README.md Illustrates the outcome of the key-bound action (Path A), confirming that files are successfully sent. ```text # Key-bound action (Path A), 2 files multi-selected: send_at_mention_results: alpha.lua=true,beta.lua=true ``` -------------------------------- ### Open File (Detailed Output) Source: https://github.com/coder/claudecode.nvim/blob/main/PROTOCOL.md Returns detailed information about the opened file, including its success status, absolute path, language ID, and line count, when not made the frontmost tab. ```json { "content": [ { "type": "text", "text": "{\"success\": true, \"filePath\": \"/absolute/path/to/file.js\", \"languageId\": \"javascript\", \"lineCount\": 42}" } ] } ``` -------------------------------- ### Get Current Selection (No Editor) Source: https://github.com/coder/claudecode.nvim/blob/main/PROTOCOL.md Handles the case where no active editor is found, returning a success status of false and an informative message. ```json { "content": [ { "type": "text", "text": "{\"success\": false, \"message\": \"No active editor found\"}" } ] } ``` -------------------------------- ### Recommended: Complete Validation with Mise Source: https://github.com/coder/claudecode.nvim/blob/main/CLAUDE.md Run formatting, linting, and testing in a single command for complete code validation. This is the recommended command at the end of editing sessions. ```bash mise run all ``` -------------------------------- ### Get Open Editors Source: https://github.com/coder/claudecode.nvim/blob/main/PROTOCOL.md Fetches information about all currently open editor tabs within the IDE. The output is a JSON-stringified array containing details for each tab. ```json { "content": [ { "type": "text", "text": "{\"tabs\": [{\"uri\": \"file:///path/to/file\", \"isActive\": true, \"label\": \"filename.ext\", \"languageId\": \"javascript\", \"isDirty\": false}]}" } ] } ``` -------------------------------- ### Headless Proof: With Handler Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/snacks-picker/README.md Shows the successful state with the in-core snacks_picker_list handler enabled, indicating files are processed correctly. ```text # With the in-core handler, 2 files multi-selected: handler_basenames: alpha.lua,beta.lua dispatch_files: 2 err: nil ``` -------------------------------- ### Common Mise Tasks Source: https://github.com/coder/claudecode.nvim/blob/main/DEVELOPMENT.md Execute common development tasks like formatting, linting, and testing using mise. Run 'mise tasks' to see all available commands. ```bash mise run all mise run test mise run check mise run format ``` -------------------------------- ### Connect Real Claude CLI to Neovim MCP Server Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/remote-diff/README.md Configure and launch the real Claude CLI to interact with the Neovim MCP server for more realistic testing of diff handling. ```sh # Point a real Claude at this Neovim's MCP server (use the port from the lock file): PORT=$(basename "$(ls ~/.claude/ide/*.lock | head -1)" .lock) cd "$(jq -r .workspaceFolders[0] ~/.claude/ide/$PORT.lock)" ENABLE_IDE_INTEGRATION=true CLAUDE_CODE_SSE_PORT=$PORT claude --ide ``` -------------------------------- ### Get Workspace Folders Source: https://github.com/coder/claudecode.nvim/blob/main/PROTOCOL.md Retrieves information about all workspace folders currently open in the IDE. The output is a JSON-stringified object containing folder details and the root path. ```json { "content": [ { "type": "text", "text": "{\"success\": true, \"folders\": [{\"name\": \"project-name\", \"uri\": \"file:///path/to/workspace\", \"path\": \"/path/to/workspace\"}], \"rootPath\": \"/path/to/workspace\"}" } ] } ``` -------------------------------- ### Get Current Selection (Success) Source: https://github.com/coder/claudecode.nvim/blob/main/PROTOCOL.md Retrieves the currently selected text in the active editor, along with its file path and selection range. This is returned as a JSON-stringified object. ```json { "content": [ { "type": "text", "text": "{\"success\": true, \"text\": \"selected content\", \"filePath\": \"/path/to/file\", \"selection\": {\"start\": {\"line\": 0, \"character\": 0}, \"end\": {\"line\": 0, \"character\": 10}}}" } ] } ``` -------------------------------- ### Verify Auth Token Generation Source: https://github.com/coder/claudecode.nvim/blob/main/CLAUDE.md Use this command to verify the generation of your authentication token by displaying its content from the lock file. ```bash cat ~/.claude/ide/*.lock | jq .authToken ``` -------------------------------- ### List Available Mise Tasks Source: https://github.com/coder/claudecode.nvim/blob/main/CLAUDE.md Display all the tasks that are available to be run using the 'mise run' command. This is useful for discovering project commands. ```bash mise tasks ``` -------------------------------- ### Unit Tests for Frame Parser Source: https://github.com/coder/claudecode.nvim/blob/main/ARCHITECTURE.md Example of unit tests for the frame parser module, focusing on isolated function testing. Ensure the parser correctly handles masked frames. ```lua -- Unit tests: isolated function testing describe("frame parser", function() it("handles masked frames", function() local frame = parse_frame(masked_data) assert.equals("hello", frame.payload) end) end) ``` -------------------------------- ### Get Latest Selection Source: https://github.com/coder/claudecode.nvim/blob/main/PROTOCOL.md Retrieves the most recent text selection, even if it's not from the currently active editor. Returns JSON-stringified selection data or an error message if no selection is available. ```json {"success": false, "message": "No selection available"} ``` -------------------------------- ### Run Specific Test File Source: https://github.com/coder/claudecode.nvim/blob/main/CLAUDE.md Execute a single test file using the busted framework. Assumes mise has set the LUA_PATH environment variable. ```bash # Run a specific test file (mise sets LUA_PATH automatically) busted tests/unit/tools/specific_tool_spec.lua --verbose ``` -------------------------------- ### Open File (Success Output) Source: https://github.com/coder/claudecode.nvim/blob/main/PROTOCOL.md Provides the output when a file is successfully opened and made the active editor tab. ```json { "content": [ { "type": "text", "text": "Opened file: /path/to/file.js" } ] } ``` -------------------------------- ### None (No-Op) Terminal Provider Configuration Source: https://github.com/coder/claudecode.nvim/blob/main/README.md Use the 'none' provider when managing the Claude CLI externally. This configuration disables in-editor terminal management, making it suitable for advanced setups. ```lua { "coder/claudecode.nvim", opts = { terminal = { provider = "none", -- no UI actions; server + tools remain available }, }, } ``` -------------------------------- ### Variable Renaming with AST-grep Source: https://github.com/coder/claudecode.nvim/blob/main/STORY.md This example demonstrates how AST-grep can be used to semantically rename variables in JavaScript code based on their usage patterns. It's useful for understanding and refactoring obfuscated code. ```javascript // Before const L = new McpToolRegistry(); // After const toolRegistry = new McpToolRegistry(); ``` -------------------------------- ### Run Gate Harness Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/issue-228/README.md This shell command executes the gate harness from the repository root to verify the fix for issue #228. It tests various provider and flag combinations to ensure the warning and event firing work as expected. ```sh # from the repo root bash fixtures/issue-228/run.sh ``` ```sh # or: nvim -u NONE -l fixtures/issue-228/repro.lua ``` -------------------------------- ### Custom Terminal Provider Implementation Source: https://github.com/coder/claudecode.nvim/blob/main/README.md This Lua code defines a custom terminal provider for Claudecode.nvim, integrating with a hypothetical 'my_terminal' plugin. It includes functions for setup, opening, closing, toggling, focusing, and checking availability of the terminal. ```lua local my_terminal_provider = { setup = function(config) -- Store config for later use self.config = config end, open = function(cmd_string, env_table, effective_config, focus) if focus == nil then focus = true end local my_terminal = require("my_terminal") my_terminal.open({ cmd = cmd_string, env = env_table, width = effective_config.split_width_percentage, side = effective_config.split_side, focus = focus, }) end, close = function() require("my_terminal").close() end, simple_toggle = function(cmd_string, env_table, effective_config) require("my_terminal").toggle() end, focus_toggle = function(cmd_string, env_table, effective_config) local my_terminal = require("my_terminal") if my_terminal.is_focused() then my_terminal.hide() else my_terminal.focus() end end, get_active_bufnr = function() return require("my_terminal").get_bufnr() end, is_available = function() local ok, _ = pcall(require, "my_terminal") return ok end, } require("claudecode").setup({ terminal = { provider = my_terminal_provider, }, }) ``` -------------------------------- ### Snacks.nvim Window Position Variations Source: https://github.com/coder/claudecode.nvim/blob/main/README.md Illustrates different `snacks_win_opts` configurations for window positioning, including bottom, right, and centered float with fixed dimensions. ```lua -- Bottom floating (like a drawer) snacks_win_opts = { position = "bottom", height = 0.4, width = 1.0, border = "single", } ``` ```lua -- Side floating panel snacks_win_opts = { position = "right", width = 0.4, height = 1.0, border = "rounded", } ``` ```lua -- Small centered popup snacks_win_opts = { position = "float", width = 120, -- Fixed width in columns height = 30, -- Fixed height in rows border = "double", backdrop = 90, } ``` -------------------------------- ### Run Full Test Suite Source: https://github.com/coder/claudecode.nvim/blob/main/CLAUDE.md Execute the entire test suite for complete MCP compliance validation. This command is recommended for comprehensive testing. ```bash # Or run the whole suite mise run test # Recommended for complete validation ``` -------------------------------- ### Configure Claude Code Diff Options Source: https://github.com/coder/claudecode.nvim/blob/main/CLAUDE.md Customize diff behavior such as layout, focus management, and new file rejection. This setup is useful for managing focus between the terminal and diff buffers and controlling how new files are handled during diff rejections. ```lua require("claudecode").setup({ diff_opts = { layout = "vertical", -- "vertical" or "horizontal" keep_terminal_focus = true, -- If true, moves focus back to terminal after diff opens open_in_new_tab = true, -- Open diff in a separate tab hide_terminal_in_new_tab = true, -- In the new tab, do not show Claude terminal on_new_file_reject = "keep_empty", -- "keep_empty" or "close_window" auto_resize_terminal = true, -- false = own terminal width via ClaudeCodeDiffOpened/Closed User autocmds -- Legacy aliases (still supported): -- vertical_split = true, -- open_in_current_tab = true, }, }) ``` -------------------------------- ### Open Git Diff (Diff Rejected Output) Source: https://github.com/coder/claudecode.nvim/blob/main/PROTOCOL.md Indicates that the diff has been rejected by the user. ```json { "content": [ { "type": "text", "text": "DIFF_REJECTED" } ] } ``` -------------------------------- ### Format Code Source: https://github.com/coder/claudecode.nvim/blob/main/DEVELOPMENT.md Format the project's code according to predefined style guidelines. This ensures a consistent and readable codebase. ```bash mise run format ``` -------------------------------- ### Run All Tests Source: https://github.com/coder/claudecode.nvim/blob/main/AGENTS.md Execute the full test suite using the mise task runner. This command ensures all tests pass and coverage is generated. ```bash mise run test ``` -------------------------------- ### Flexible Terminal Management with Provider Pattern Source: https://github.com/coder/claudecode.nvim/blob/main/ARCHITECTURE.md Opens a terminal command, preferring the `Snacks.nvim` provider if available for flexible window positioning. Falls back to a native `vsplit | terminal` command if `Snacks.nvim` is not present. ```lua -- Snacks.nvim provider (preferred) if has_snacks then Snacks.terminal.open(cmd, { win = { position = "right", width = 0.3 } }) else -- Native fallback vim.cmd("vsplit | terminal " .. cmd) end ``` -------------------------------- ### Automated Reproduction Script Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/issue-70/README.md Run this script from the repository root to automatically reproduce Issue 70. It requires Neovim, a logged-in 'claude' user, agent-tty, and jq. ```sh # from repo root; needs nvim + a logged-in `claude` + agent-tty + jq bash scripts/repro_issue_70.sh ``` -------------------------------- ### claudecode.nvim Project Structure Source: https://github.com/coder/claudecode.nvim/blob/main/DEVELOPMENT.md Overview of the claudecode.nvim project directory layout, detailing the purpose of key directories and files. ```none claudecode.nvim/ ├── .github/workflows/ # CI workflow definitions ├── fixtures/ # Test Neovim configurations for integration testing │ ├── bin/ # Helper scripts (vv, vve, list-configs) │ ├── mini-files/ # Neovim config testing with mini.files │ ├── netrw/ # Neovim config testing with built-in file explorer │ ├── nvim-tree/ # Neovim config testing with nvim-tree.lua │ ├── oil/ # Neovim config testing with oil.nvim │ └── nvim-aliases.sh # Shell aliases for fixture testing ├── lua/claudecode/ # Plugin implementation │ ├── server/ # WebSocket server implementation │ ├── tools/ # MCP tool implementations and schema management │ ├── config.lua # Configuration management │ ├── diff.lua # Diff provider system (native Neovim support) │ ├── init.lua # Plugin entry point │ ├── lockfile.lua # Lock file management │ ├── selection.lua # Selection tracking │ └── terminal.lua # Terminal management ├── plugin/ # Plugin loader ├── tests/ # Test suite │ ├── unit/ # Unit tests │ ├── component/ # Component tests │ ├── integration/ # Integration tests │ └── mocks/ # Test mocks ├── README.md # User documentation ├── ARCHITECTURE.md # Architecture documentation └── DEVELOPMENT.md # Development guide ``` -------------------------------- ### Open Git Diff (File Saved Output) Source: https://github.com/coder/claudecode.nvim/blob/main/PROTOCOL.md Indicates that the diff has been accepted and the file content has been saved. ```json { "content": [ { "type": "text", "text": "FILE_SAVED" } ] } ``` -------------------------------- ### Headless Proof: Issue State Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/snacks-picker/README.md Demonstrates the error state when the snacks_picker_list handler is missing and the list window is focused. ```text # Without the snacks_picker_list handler (the issue #192 state), list focused: focused_filetype: snacks_picker_list dispatch_error: Not in a supported tree buffer (current filetype: snacks_picker_list) ``` -------------------------------- ### Test WebSocket Connection with Missing Auth Header Source: https://github.com/coder/claudecode.nvim/blob/main/CLAUDE.md This command tests the server's rejection when the authentication header is missing. ```bash websocat ws://localhost:PORT ``` -------------------------------- ### External Terminal Provider Configuration (Advanced Function) Source: https://github.com/coder/claudecode.nvim/blob/main/README.md For dynamic command generation with the 'external' provider, use a function. This allows for conditional command construction based on the environment. ```lua -- Using a function for dynamic command generation (advanced) { "coder/claudecode.nvim", opts = { terminal = { provider = "external", provider_opts = { external_terminal_cmd = function(cmd, env) -- You can build complex commands based on environment or conditions if vim.fn.has("mac") == 1 then return { "osascript", "-e", string.format('tell app "Terminal" to do script "%s"', cmd) } else return "alacritty -e " .. cmd end end, }, }, }, } ``` -------------------------------- ### Run Interactive Script with Auth Source: https://github.com/coder/claudecode.nvim/blob/main/CLAUDE.md This script automatically detects and uses authentication tokens from the lock file for interactive sessions. ```bash cd scripts/ ./claude_interactive.sh # Automatically reads auth token from lock file ``` -------------------------------- ### Shell Aliases for Integration Testing Source: https://github.com/coder/claudecode.nvim/blob/main/ARCHITECTURE.md Shell aliases provided in `fixtures/nvim-aliases.sh` for easily running integration tests with different Neovim configurations and file explorers. Use the `vv` command followed by the desired integration name. ```bash # Test with different file explorers source fixtures/nvim-aliases.sh vv nvim-tree # Test with nvim-tree integration vv oil # Test with oil.nvim integration vv mini-files # Test with mini.files integration vv netrw # Test with built-in netrw ``` -------------------------------- ### Dry-Run Release Automation Source: https://github.com/coder/claudecode.nvim/blob/main/DEVELOPMENT.md Execute the release automation script in dry-run mode to preview changes without making actual modifications. This requires setting up dependencies and providing necessary API keys and repository information. ```bash mise install NPM_CONFIG_IGNORE_SCRIPTS=true npm ci --prefix scripts GITHUB_TOKEN=... \ GITHUB_REPOSITORY=coder/claudecode.nvim \ RELEASE_PLEASE_TARGET_BRANCH=your-branch \ ANTHROPIC_API_KEY=... \ ./scripts/run-release-please.sh --dry-run ``` -------------------------------- ### Keymaps for Accepting/Denying Diffs Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/issue-238/README.md These keymaps allow for accepting (`aa`) or denying (`ad`) the currently focused diff. The deny action is expected to work correctly, unlike the ':q' command. ```vim aa ad ``` -------------------------------- ### Write Lock File with Authentication Token Source: https://github.com/coder/claudecode.nvim/blob/main/PROTOCOL.md Generates a secure 128-bit authentication token and writes it to a lock file along with process ID and workspace information. Uses the OS CSPRNG for token generation. ```lua -- ~/.claude/ide/[port].lock -- Generate a 128-bit token (32-char lowercase hex) from the OS CSPRNG. -- Never use math.random for this; a weak token is worse than a startup error. local bytes = vim.loop.random(16) -- 16 secure random bytes local auth_token = bytes:gsub(".", function(c) return string.format("%02x", string.byte(c)) end) local lock_data = { pid = vim.fn.getpid(), workspaceFolders = { vim.fn.getcwd() }, ideName = "YourEditor", transport = "ws", authToken = auth_token } write_json(lock_path, lock_data) ``` -------------------------------- ### Reproduce Issue #238 Headless Source: https://github.com/coder/claudecode.nvim/blob/main/fixtures/issue-238/README.md Run this command to quickly test the bug without a full Neovim session. It drives the diff.lua script and performs a ':q' to check if the exit code indicates a bug (1) or a fix (0). ```sh nvim --headless -u NONE -l scripts/repro_issue_238.lua; echo "exit: $?" ``` -------------------------------- ### Resource Cleanup on Vim Exit Source: https://github.com/coder/claudecode.nvim/blob/main/ARCHITECTURE.md Sets up an autocommand (`VimLeavePre`) to ensure that server resources, such as the WebSocket server and lock files, are properly stopped and cleaned up when Neovim exits. ```lua vim.api.nvim_create_autocmd("VimLeavePre", { callback = function() M.stop() -- Stop server, remove lock file end }) ``` -------------------------------- ### Tool Registration with JSON Schema Source: https://github.com/coder/claudecode.nvim/blob/main/ARCHITECTURE.md Registers a tool with its name, JSON schema for validation, and an implementation function. The schema defines the expected parameters for the tool. Requires a `registry` table. ```lua -- Tool registration M.register("openFile", { type = "object", properties = { filePath = { type = "string", description = "Path to open" } }, required = { "filePath" } }, function(params) -- Implementation vim.cmd("edit " .. params.filePath) return { content = {{ type = "text", text = "Opened" }} } end) ```