Skip to content

Commit 9abf142

Browse files
committed
Merge branch 'main' into feat/support-send-for-snacks-explorer
Change-Id: I6c810fbb8c3c0eedcff14ebe491f2f5825ee209f Signed-off-by: Thomas Kosiewski <[email protected]>
2 parents 6fd3196 + 7573e8e commit 9abf142

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+2719
-209
lines changed

.envrc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
#!/usr/bin/env bash
22

3-
if ! has nix_direnv_version || ! nix_direnv_version 3.0.6; then
4-
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.6/direnvrc" "sha256-RYcUJaRMf8oF5LznDrlCXbkOQrywm0HDv1VjYGaJGdM="
3+
if ! has nix_direnv_version || ! nix_direnv_version 3.0.7; then
4+
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.7/direnvrc" "sha256-RYcUJaRMf8oF5LznDrlCXbkOQrywm0HDv1VjYGaJGdM="
55
fi
66

77
nix_direnv_manual_reload
88

99
use flake .
10+
11+
# Add fixtures/bin to PATH for nvim config aliases
12+
PATH_add fixtures/bin

ARCHITECTURE.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ lua/claudecode/
235235

236236
## Testing
237237

238+
### Automated Testing
239+
238240
Three-layer testing strategy using busted:
239241

240242
```lua
@@ -264,6 +266,30 @@ describe("full flow", function()
264266
end)
265267
```
266268

269+
### Integration Testing with Fixtures
270+
271+
Manual testing with real Neovim configurations in the `fixtures/` directory:
272+
273+
```bash
274+
# Test with different file explorers
275+
source fixtures/nvim-aliases.sh
276+
vv nvim-tree # Test with nvim-tree integration
277+
vv oil # Test with oil.nvim integration
278+
vv netrw # Test with built-in netrw
279+
280+
# Each fixture provides:
281+
# - Complete Neovim configuration
282+
# - Plugin dependencies
283+
# - Development keybindings
284+
# - Integration-specific testing scenarios
285+
```
286+
287+
**Fixture Architecture**:
288+
289+
- `fixtures/bin/` - Helper scripts (`vv`, `vve`, `list-configs`)
290+
- `fixtures/[integration]/` - Complete Neovim configs for testing
291+
- `fixtures/nvim-aliases.sh` - Shell aliases for easy testing
292+
267293
## Performance & Security
268294

269295
- **Debounced Updates**: 50ms delay on selection changes

CLAUDE.md

Lines changed: 185 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,23 @@ claudecode.nvim - A Neovim plugin that implements the same WebSocket-based MCP p
3737
- `nix develop` - Enter development shell with all dependencies
3838
- `nix fmt` - Format all files using nix formatter
3939

40+
### Integration Testing with Fixtures
41+
42+
The `fixtures/` directory contains test Neovim configurations for verifying plugin integrations:
43+
44+
- `vv <config>` - Start Neovim with a specific fixture configuration
45+
- `vve <config>` - Start Neovim with a fixture config in edit mode
46+
- `list-configs` - Show available fixture configurations
47+
- Source `fixtures/nvim-aliases.sh` to enable these commands
48+
49+
**Available Fixtures**:
50+
51+
- `netrw` - Tests with Neovim's built-in file explorer
52+
- `nvim-tree` - Tests with nvim-tree.lua file explorer
53+
- `oil` - Tests with oil.nvim file explorer
54+
55+
**Usage**: `source fixtures/nvim-aliases.sh && vv oil` starts Neovim with oil.nvim configuration
56+
4057
## Architecture Overview
4158

4259
### Core Components
@@ -65,14 +82,28 @@ The WebSocket server implements secure authentication using:
6582
- **Lock File Discovery**: Tokens stored in `~/.claude/ide/[port].lock` for Claude CLI
6683
- **MCP Compliance**: Follows official Claude Code IDE authentication protocol
6784

68-
### MCP Tools Architecture
85+
### MCP Tools Architecture (✅ FULLY COMPLIANT)
6986

70-
Tools are registered with JSON schemas and handlers. MCP-exposed tools include:
87+
**Complete VS Code Extension Compatibility**: All tools now implement identical behavior and output formats as the official VS Code extension.
7188

72-
- `openFile` - Opens files with optional line/text selection
73-
- `getCurrentSelection` - Gets current text selection
74-
- `getOpenEditors` - Lists currently open files
89+
**MCP-Exposed Tools** (with JSON schemas):
90+
91+
- `openFile` - Opens files with optional line/text selection (startLine/endLine), preview mode, text pattern matching, and makeFrontmost flag
92+
- `getCurrentSelection` - Gets current text selection from active editor
93+
- `getLatestSelection` - Gets most recent text selection (even from inactive editors)
94+
- `getOpenEditors` - Lists currently open files with VS Code-compatible `tabs` structure
7595
- `openDiff` - Opens native Neovim diff views
96+
- `checkDocumentDirty` - Checks if document has unsaved changes
97+
- `saveDocument` - Saves document with detailed success/failure reporting
98+
- `getWorkspaceFolders` - Gets workspace folder information
99+
- `closeAllDiffTabs` - Closes all diff-related tabs and windows
100+
- `getDiagnostics` - Gets language diagnostics (errors, warnings) from the editor
101+
102+
**Internal Tools** (not exposed via MCP):
103+
104+
- `close_tab` - Internal-only tool for tab management (hardcoded in Claude Code)
105+
106+
**Format Compliance**: All tools return MCP-compliant format: `{content: [{type: "text", text: "JSON-stringified-data"}]}`
76107

77108
### Key File Locations
78109

@@ -81,6 +112,33 @@ Tools are registered with JSON schemas and handlers. MCP-exposed tools include:
81112
- `plugin/claudecode.lua` - Plugin loader with version checks
82113
- `tests/` - Comprehensive test suite with unit, component, and integration tests
83114

115+
## MCP Protocol Compliance
116+
117+
### Protocol Implementation Status
118+
119+
-**WebSocket Server**: RFC 6455 compliant with MCP message format
120+
-**Tool Registration**: JSON Schema-based tool definitions
121+
-**Authentication**: UUID v4 token-based secure handshake
122+
-**Message Format**: JSON-RPC 2.0 with MCP content structure
123+
-**Error Handling**: Comprehensive JSON-RPC error responses
124+
125+
### VS Code Extension Compatibility
126+
127+
claudecode.nvim implements **100% feature parity** with Anthropic's official VS Code extension:
128+
129+
- **Identical Tool Set**: All 10 VS Code tools implemented
130+
- **Compatible Formats**: Output structures match VS Code extension exactly
131+
- **Behavioral Consistency**: Same parameter handling and response patterns
132+
- **Error Compatibility**: Matching error codes and messages
133+
134+
### Protocol Validation
135+
136+
Run `make test` to verify MCP compliance:
137+
138+
- **Tool Format Validation**: All tools return proper MCP structure
139+
- **Schema Compliance**: JSON schemas validated against VS Code specs
140+
- **Integration Testing**: End-to-end MCP message flow verification
141+
84142
## Testing Architecture
85143

86144
Tests are organized in three layers:
@@ -91,6 +149,33 @@ Tests are organized in three layers:
91149

92150
Test files follow the pattern `*_spec.lua` or `*_test.lua` and use the busted framework.
93151

152+
### Test Infrastructure
153+
154+
**JSON Handling**: Custom JSON encoder/decoder with support for:
155+
156+
- Nested objects and arrays
157+
- Special Lua keywords as object keys (`["end"]`)
158+
- MCP message format validation
159+
- VS Code extension output compatibility
160+
161+
**Test Pattern**: Run specific test files during development:
162+
163+
```bash
164+
# Run specific tool tests with proper LUA_PATH
165+
export LUA_PATH="./lua/?.lua;./lua/?/init.lua;./?.lua;./?/init.lua;$LUA_PATH"
166+
busted tests/unit/tools/specific_tool_spec.lua --verbose
167+
168+
# Or use make for full validation
169+
make test # Recommended for complete validation
170+
```
171+
172+
**Coverage Metrics**:
173+
174+
- **320+ tests** covering all MCP tools and core functionality
175+
- **Unit Tests**: Individual tool behavior and error cases
176+
- **Integration Tests**: End-to-end MCP protocol flow
177+
- **Format Tests**: MCP compliance and VS Code compatibility
178+
94179
### Test Organization Principles
95180

96181
- **Isolation**: Each test should be independent and not rely on external state
@@ -274,9 +359,103 @@ rg "0\.1\.0" . # Should only show CHANGELOG.md historical entries
274359
4. **Document Changes**: Update relevant documentation (this file, PROTOCOL.md, etc.)
275360
5. **Commit**: Only commit after successful `make` execution
276361

362+
### Integration Development Guidelines
363+
364+
**Adding New Integrations** (file explorers, terminals, etc.):
365+
366+
1. **Implement Integration**: Add support in relevant modules (e.g., `lua/claudecode/tools/`)
367+
2. **Create Fixture Configuration**: **REQUIRED** - Add a complete Neovim config in `fixtures/[integration-name]/`
368+
3. **Test Integration**: Use fixture to verify functionality with `vv [integration-name]`
369+
4. **Update Documentation**: Add integration to fixtures list and relevant tool documentation
370+
5. **Run Full Test Suite**: Ensure `make` passes with new integration
371+
372+
**Fixture Requirements**:
373+
374+
- Complete Neovim configuration with plugin dependencies
375+
- Include `dev-claudecode.lua` with development keybindings
376+
- Test all relevant claudecode.nvim features with the integration
377+
- Document any integration-specific behaviors or limitations
378+
379+
### MCP Tool Development Guidelines
380+
381+
**Adding New Tools**:
382+
383+
1. **Study Existing Patterns**: Review `lua/claudecode/tools/` for consistent structure
384+
2. **Implement Handler**: Return MCP format: `{content: [{type: "text", text: JSON}]}`
385+
3. **Add JSON Schema**: Define parameters and expose via MCP (if needed)
386+
4. **Create Tests**: Both unit tests and integration tests required
387+
5. **Update Documentation**: Add to this file's MCP tools list
388+
389+
**Tool Testing Pattern**:
390+
391+
```lua
392+
-- All tools should return MCP-compliant format
393+
local result = tool_handler(params)
394+
expect(result).to_be_table()
395+
expect(result.content).to_be_table()
396+
expect(result.content[1].type).to_be("text")
397+
local parsed = json_decode(result.content[1].text)
398+
-- Validate parsed structure matches VS Code extension
399+
```
400+
401+
**Error Handling Standard**:
402+
403+
```lua
404+
-- Use consistent JSON-RPC error format
405+
error({
406+
code = -32602, -- Invalid params
407+
message = "Description of the issue",
408+
data = "Additional context"
409+
})
410+
```
411+
277412
### Code Quality Standards
278413

279-
- **Test Coverage**: Maintain comprehensive test coverage (currently 314+ tests)
414+
- **Test Coverage**: Maintain comprehensive test coverage (currently **320+ tests**, 100% success rate)
280415
- **Zero Warnings**: All code must pass luacheck with 0 warnings/errors
416+
- **MCP Compliance**: All tools must return proper MCP format with JSON-stringified content
417+
- **VS Code Compatibility**: New tools must match VS Code extension behavior exactly
281418
- **Consistent Formatting**: Use `nix fmt` or `stylua` for consistent code style
282419
- **Documentation**: Update CLAUDE.md for architectural changes, PROTOCOL.md for protocol changes
420+
421+
### Development Quality Gates
422+
423+
1. **`make check`** - Syntax and linting (0 warnings required)
424+
2. **`make test`** - All tests passing (320/320 success rate required)
425+
3. **`make format`** - Consistent code formatting
426+
4. **MCP Validation** - Tools return proper format structure
427+
5. **Integration Test** - End-to-end protocol flow verification
428+
429+
## Development Troubleshooting
430+
431+
### Common Issues
432+
433+
**Test Failures with LUA_PATH**:
434+
435+
```bash
436+
# Tests can't find modules - use proper LUA_PATH
437+
export LUA_PATH="./lua/?.lua;./lua/?/init.lua;./?.lua;./?/init.lua;$LUA_PATH"
438+
busted tests/unit/specific_test.lua
439+
```
440+
441+
**JSON Format Issues**:
442+
443+
- Ensure all tools return: `{content: [{type: "text", text: "JSON-string"}]}`
444+
- Use `vim.json.encode()` for proper JSON stringification
445+
- Test JSON parsing with custom test decoder in `tests/busted_setup.lua`
446+
447+
**MCP Tool Registration**:
448+
449+
- Tools with `schema = nil` are internal-only
450+
- Tools with schema are exposed via MCP
451+
- Check `lua/claudecode/tools/init.lua` for registration patterns
452+
453+
**Authentication Testing**:
454+
455+
```bash
456+
# Verify auth token generation
457+
cat ~/.claude/ide/*.lock | jq .authToken
458+
459+
# Test WebSocket connection
460+
websocat ws://localhost:PORT --header "x-claude-code-ide-authorization: $(cat ~/.claude/ide/*.lock | jq -r .authToken)"
461+
```

DEVELOPMENT.md

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ Quick guide for contributors to the claudecode.nvim project.
77
```none
88
claudecode.nvim/
99
├── .github/workflows/ # CI workflow definitions
10+
├── fixtures/ # Test Neovim configurations for integration testing
11+
│ ├── bin/ # Helper scripts (vv, vve, list-configs)
12+
│ ├── netrw/ # Neovim config testing with built-in file explorer
13+
│ ├── nvim-tree/ # Neovim config testing with nvim-tree.lua
14+
│ ├── oil/ # Neovim config testing with oil.nvim
15+
│ └── nvim-aliases.sh # Shell aliases for fixture testing
1016
├── lua/claudecode/ # Plugin implementation
1117
│ ├── server/ # WebSocket server implementation
1218
│ ├── tools/ # MCP tool implementations and schema management
@@ -118,7 +124,49 @@ make format
118124
2. Create a feature branch
119125
3. Implement your changes with tests
120126
4. Run the test suite to ensure all tests pass
121-
5. Submit a pull request
127+
5. **For integrations**: Create a fixture configuration for testing
128+
6. Submit a pull request
129+
130+
### Integration Testing with Fixtures
131+
132+
When adding support for new integrations (file explorers, terminals, etc.), you **must** provide a fixture configuration for testing:
133+
134+
**Requirements**:
135+
136+
- Complete Neovim configuration in `fixtures/[integration-name]/`
137+
- Include plugin dependencies and proper setup
138+
- Add `dev-claudecode.lua` with development keybindings
139+
- Test all relevant claudecode.nvim features with the integration
140+
141+
**Usage**:
142+
143+
```bash
144+
# Source fixture aliases
145+
source fixtures/nvim-aliases.sh
146+
147+
# Test with specific integration
148+
vv nvim-tree # Start Neovim with nvim-tree configuration
149+
vv oil # Start Neovim with oil.nvim configuration
150+
vv netrw # Start Neovim with built-in netrw configuration
151+
152+
# List available configurations
153+
list-configs
154+
```
155+
156+
**Example fixture structure** (`fixtures/my-integration/`):
157+
158+
```
159+
my-integration/
160+
├── init.lua # Main Neovim config
161+
├── lua/
162+
│ ├── config/
163+
│ │ └── lazy.lua # Plugin manager setup
164+
│ └── plugins/
165+
│ ├── dev-claudecode.lua # claudecode.nvim development config
166+
│ ├── init.lua # Base plugins
167+
│ └── my-integration.lua # Integration-specific plugin config
168+
└── lazy-lock.json # Plugin lockfile (if using lazy.nvim)
169+
```
122170

123171
## Implementation Details
124172

README.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@
44
![Neovim version](https://img.shields.io/badge/Neovim-0.8%2B-green)
55
![Status](https://img.shields.io/badge/Status-beta-blue)
66

7-
> ⚠️ **Important**: IDE integrations are currently broken in Claude Code releases newer than v1.0.27. Please use [Claude Code v1.0.27](https://www.npmjs.com/package/@anthropic-ai/claude-code/v/1.0.27) or older until these issues are resolved:
8-
>
9-
> - [Claude Code not detecting IDE integrations #2299](https://github.com/anthropics/claude-code/issues/2299)
10-
> - [IDE integration broken after update #2295](https://github.com/anthropics/claude-code/issues/2295)
11-
127
**The first Neovim IDE integration for Claude Code** — bringing Anthropic's AI coding assistant to your favorite editor with a pure Lua implementation.
138

149
> 🎯 **TL;DR:** When Anthropic released Claude Code with VS Code and JetBrains support, I reverse-engineered their extension and built this Neovim plugin. This plugin implements the same WebSocket-based MCP protocol, giving Neovim users the same AI-powered coding experience.
@@ -38,6 +33,7 @@ When Anthropic released Claude Code, they only supported VS Code and JetBrains.
3833
{ "<leader>af", "<cmd>ClaudeCodeFocus<cr>", desc = "Focus Claude" },
3934
{ "<leader>ar", "<cmd>ClaudeCode --resume<cr>", desc = "Resume Claude" },
4035
{ "<leader>aC", "<cmd>ClaudeCode --continue<cr>", desc = "Continue Claude" },
36+
{ "<leader>am", "<cmd>ClaudeCodeSelectModel<cr>", desc = "Select Claude model" },
4137
{ "<leader>ab", "<cmd>ClaudeCodeAdd %<cr>", desc = "Add current buffer" },
4238
{ "<leader>as", "<cmd>ClaudeCodeSend<cr>", mode = "v", desc = "Send to Claude" },
4339
{
@@ -91,6 +87,7 @@ That's it! The plugin will auto-configure everything else.
9187

9288
- `:ClaudeCode` - Toggle the Claude Code terminal window
9389
- `:ClaudeCodeFocus` - Smart focus/toggle Claude terminal
90+
- `:ClaudeCodeSelectModel` - Select Claude model and open terminal with optional arguments
9491
- `:ClaudeCodeSend` - Send current visual selection to Claude
9592
- `:ClaudeCodeAdd <file-path> [start-line] [end-line]` - Add specific file to Claude context with optional line range
9693
- `:ClaudeCodeDiffAccept` - Accept diff changes
@@ -157,6 +154,7 @@ For deep technical details, see [ARCHITECTURE.md](./ARCHITECTURE.md).
157154
split_width_percentage = 0.30,
158155
provider = "auto", -- "auto", "snacks", or "native"
159156
auto_close = true,
157+
snacks_win_opts = {}, -- Opts to pass to `Snacks.terminal.open()`
160158
},
161159

162160
-- Diff Integration

0 commit comments

Comments
 (0)