Skip to content

Commit ba1698c

Browse files
committed
feat(terminal): add integrated Claude terminal support
Change-Id: I973687af9592634125ab87088b64b943cdd388bd Signed-off-by: Thomas Kosiewski <[email protected]>
1 parent dd4f4c1 commit ba1698c

21 files changed

+1144
-197
lines changed

.github/workflows/claude-review.yaml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Claude Code Review
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize] # Runs on new PRs and updates
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
code-review:
12+
runs-on: ubuntu-latest
13+
steps:
14+
# Check out the code to allow git diff operations
15+
- name: Checkout code
16+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
17+
with:
18+
fetch-depth: 0 # Fetch full history for accurate diffs
19+
persist-credentials: false
20+
21+
- name: Run Code Review with Claude
22+
id: code-review
23+
uses: anthropics/claude-code-action@8b9d5bb25a638c9aa5103496c0139d99b4936d42 # beta
24+
with:
25+
# Define the review focus areas
26+
prompt: "Review the PR changes. Focus on code quality, potential bugs, and performance issues. Suggest improvements where appropriate."
27+
28+
# Limited tools for safer review operations
29+
allowed_tools: >-
30+
[
31+
"Bash(git diff --name-only HEAD~1)",
32+
"Bash(git diff HEAD~1)",
33+
"View",
34+
"GlobTool",
35+
"GrepTool"
36+
]
37+
38+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}

.github/workflows/claude.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ on:
1010
pull_request_review:
1111
types: [submitted]
1212

13+
permissions:
14+
contents: read
15+
1316
jobs:
1417
claude:
1518
if: |
@@ -23,12 +26,13 @@ jobs:
2326
id-token: write
2427
steps:
2528
- name: Checkout repository
26-
uses: actions/checkout@v4
29+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
2730
with:
2831
fetch-depth: 1
32+
persist-credentials: false
2933

3034
- name: Run Claude Code
3135
id: claude
32-
uses: anthropics/claude-code-action@beta
36+
uses: anthropics/claude-code-action@8b9d5bb25a638c9aa5103496c0139d99b4936d42 # beta
3337
with:
3438
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}

.github/workflows/test.yml

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ on:
66
pull_request:
77
branches: [main]
88

9+
permissions:
10+
contents: read
11+
912
jobs:
1013
unit-tests:
1114
runs-on: ubuntu-latest
@@ -14,21 +17,23 @@ jobs:
1417
neovim-version: ["stable", "nightly"]
1518

1619
steps:
17-
- uses: actions/checkout@v3
20+
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
21+
with:
22+
persist-credentials: false
1823

1924
- name: Setup Neovim
20-
uses: rhysd/action-setup-vim@v1
25+
uses: rhysd/action-setup-vim@8e931b9954b19d4203d5caa5ff5521f3bc21dcc7 # v1.4.2
2126
with:
2227
neovim: true
2328
version: ${{ matrix.neovim-version }}
2429

2530
- name: Setup Lua
26-
uses: leafo/gh-actions-lua@v10
31+
uses: leafo/gh-actions-lua@8aace3457a2fcf3f3c4e9007ecc6b869ff6d74d6 # v11
2732
with:
2833
luaVersion: "5.1"
2934

3035
- name: Setup Luarocks
31-
uses: leafo/gh-actions-luarocks@v4
36+
uses: leafo/gh-actions-luarocks@4c082a5fad45388feaeb0798dbd82dbd7dc65bca # v5
3237

3338
- name: Install dependencies
3439
run: |
@@ -52,7 +57,7 @@ jobs:
5257
luacov-console -r lcov > lcov.info
5358
5459
- name: Upload coverage report
55-
uses: codecov/codecov-action@v3
60+
uses: codecov/codecov-action@c16abc29c95fcf9174b58eb7e1abf4c866893bc8 # v4
5661
with:
5762
files: ./tests/lcov.info
5863
fail_ci_if_error: false
@@ -65,18 +70,20 @@ jobs:
6570
neovim-version: ["stable"]
6671

6772
steps:
68-
- uses: actions/checkout@v3
73+
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
74+
with:
75+
persist-credentials: false
6976

7077
- name: Setup Neovim
71-
uses: rhysd/action-setup-vim@v1
78+
uses: rhysd/action-setup-vim@8e931b9954b19d4203d5caa5ff5521f3bc21dcc7 # v1.4.2
7279
with:
7380
neovim: true
7481
version: ${{ matrix.neovim-version }}
7582

7683
- name: Install test dependencies
7784
run: |
7885
git clone --depth 1 https://github.com/nvim-lua/plenary.nvim ~/.local/share/nvim/site/pack/vendor/start/plenary.nvim
79-
ln -s $(pwd) ~/.local/share/nvim/site/pack/vendor/start/claudecode.nvim
86+
ln -s "$(pwd)" ~/.local/share/nvim/site/pack/vendor/start/claudecode.nvim
8087
8188
- name: Run integration tests
8289
run: |

ARCHITECTURE.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,32 @@ The plugin monitors text selections in Neovim:
7777
- Formats selection data according to MCP protocol
7878
- Sends updates to Claude via WebSocket
7979

80-
### 5. Environment Integration
80+
### 5. Terminal Integration
81+
82+
The plugin provides a dedicated terminal interface for Claude Code CLI:
83+
84+
- Uses [folke/snacks.nvim](https://github.com/folke/snacks.nvim) for terminal management
85+
- Creates a vertical split terminal with customizable size and position
86+
- Supports focus, toggle, and close operations
87+
- Maintains terminal state across operations
88+
- Automatically cleans up on window close
89+
90+
```
91+
┌─────────────┐ ┌─────────────────┐ ┌─────────────┐
92+
│ │ │ │ │ │
93+
│ Neovim │◄───┤ Claude Terminal │◄───┤ Claude CLI │
94+
│ Buffers │ │ (Snacks.nvim) │ │ │
95+
└─────────────┘ └─────────────────┘ └─────────────┘
96+
```
97+
98+
### 6. Environment Integration
8199

82100
The plugin manages the environment for Claude CLI:
83101

84102
- Sets required environment variables:
85103
- `CLAUDE_CODE_SSE_PORT`: The WebSocket server port
86104
- `ENABLE_IDE_INTEGRATION`: Enabled flag
87-
- Provides terminal integration for launching Claude
105+
- Provides configuration for the terminal command
88106

89107
## Message Flow
90108

@@ -141,6 +159,7 @@ lua/claudecode/
141159
│ ├── editor.lua # Editor information tools
142160
│ └── selection.lua # Selection management tools
143161
├── selection.lua # Selection tracking
162+
├── terminal.lua # Terminal management (uses Snacks.nvim)
144163
├── environment.lua # Environment variable management
145164
└── util.lua # Utility functions
146165
```
@@ -170,6 +189,7 @@ tests/
170189
├── unit/
171190
│ ├── config_spec.lua
172191
│ ├── server_spec.lua
192+
│ ├── terminal_spec.lua
173193
│ └── tools_spec.lua
174194
├── component/
175195
│ ├── server_spec.lua

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ check:
88
@echo "Checking Lua files for syntax errors..."
99
@find lua -name "*.lua" -type f -exec lua -e "assert(loadfile('{}'))" \;
1010
@echo "Running luacheck..."
11-
@luacheck lua/ --no-unused-args --no-max-line-length || echo "⚠️ Luacheck warnings - continuing anyway"
11+
@luacheck lua/ tests/ --no-unused-args --no-max-line-length
1212

1313
# Format all files
1414
format:

README.md

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,19 @@ A Neovim plugin that integrates with Claude Code CLI to provide a seamless AI co
1212
- 🔍 Selection tracking to provide context to Claude
1313
- 🛠️ Integration with Neovim's buffer and window management
1414
- 📝 Support for file operations and diagnostics
15-
- 🖥️ Terminal integration for launching Claude with proper environment
15+
- 🖥️ Interactive vertical split terminal for Claude sessions (via `folke/snacks.nvim`)
1616
- 🔒 Automatic cleanup on exit - server shutdown and lockfile removal
1717

1818
## Requirements
1919

2020
- Neovim >= 0.8.0
2121
- Claude Code CLI installed and in your PATH
2222
- Lua >= 5.1
23+
- **Required for terminal integration:** [folke/snacks.nvim](https://github.com/folke/snacks.nvim) - Terminal management plugin
2324
- Optional: plenary.nvim for additional utilities
2425

26+
Note: The terminal feature requires Snacks.nvim to be installed and available. If not available, the terminal commands will display an error message, but the core Claude Code integration will still function.
27+
2528
## Installation
2629

2730
### Using [lazy.nvim](https://github.com/folke/lazy.nvim)
@@ -31,8 +34,11 @@ A Neovim plugin that integrates with Claude Code CLI to provide a seamless AI co
3134
"ThomasK33/claudecode.nvim",
3235
dependencies = {
3336
"nvim-lua/plenary.nvim",
37+
"folke/snacks.nvim", -- Added dependency
3438
},
3539
config = function()
40+
-- Ensure snacks is loaded if you want to use the terminal immediately
41+
-- require("snacks") -- Or handle this in your init.lua
3642
require("claudecode").setup({
3743
-- Optional configuration
3844
})
@@ -45,7 +51,10 @@ A Neovim plugin that integrates with Claude Code CLI to provide a seamless AI co
4551
```lua
4652
use {
4753
"ThomasK33/claudecode.nvim",
48-
requires = { "nvim-lua/plenary.nvim" },
54+
requires = {
55+
"nvim-lua/plenary.nvim",
56+
"folke/snacks.nvim", -- Added dependency
57+
},
4958
config = function()
5059
require("claudecode").setup({
5160
-- Optional configuration
@@ -64,13 +73,28 @@ return {
6473
"ThomasK33/claudecode.nvim",
6574
dependencies = {
6675
"nvim-lua/plenary.nvim",
76+
"folke/snacks.nvim", -- Added dependency
6777
},
6878
opts = {
69-
-- Optional configuration
79+
-- Optional configuration for claudecode main
80+
-- Example:
81+
-- terminal_cmd = "claude --magic-flag",
82+
83+
-- Configuration for the interactive terminal can also be nested here:
84+
terminal = {
85+
split_side = "left", -- "left" or "right"
86+
split_width_percentage = 0.4, -- 0.0 to 1.0
87+
},
7088
},
89+
-- The main require("claudecode").setup(opts) will handle passing
90+
-- opts.terminal to the terminal module's setup.
91+
config = true, -- or function(_, opts) require("claudecode").setup(opts) end
7192
keys = {
7293
{ "<leader>cc", "<cmd>ClaudeCodeStart<cr>", desc = "Start Claude Code" },
7394
{ "<leader>cs", "<cmd>ClaudeCodeSend<cr>", desc = "Send to Claude Code" },
95+
{ "<leader>ct", "<cmd>ClaudeCode<cr>", desc = "Toggle Claude Terminal" },
96+
{ "<leader>co", "<cmd>ClaudeCodeOpen<cr>", desc = "Open Claude Terminal" },
97+
{ "<leader>cx", "<cmd>ClaudeCodeClose<cr>", desc = "Close Claude Terminal" },
7498
},
7599
},
76100
}
@@ -87,16 +111,27 @@ return {
87111
name = "claudecode.nvim",
88112
dependencies = {
89113
"nvim-lua/plenary.nvim",
114+
"folke/snacks.nvim", -- Added dependency
90115
},
91116
dev = true,
92117
opts = {
93-
-- Development configuration
118+
-- Development configuration for claudecode main
94119
log_level = "debug",
95120
auto_start = true, -- Optional: auto-start the server
121+
122+
-- Example terminal configuration for dev:
123+
terminal = {
124+
split_side = "right",
125+
split_width_percentage = 0.25,
126+
},
96127
},
128+
config = true,
97129
keys = {
98130
{ "<leader>cc", "<cmd>ClaudeCodeStart<cr>", desc = "Start Claude Code" },
99131
{ "<leader>cs", "<cmd>ClaudeCodeSend<cr>", desc = "Send to Claude Code" },
132+
{ "<leader>ct", "<cmd>ClaudeCode<cr>", desc = "Toggle Claude Terminal" },
133+
{ "<leader>co", "<cmd>ClaudeCodeOpen<cr>", desc = "Open Claude Terminal" },
134+
{ "<leader>cx", "<cmd>ClaudeCodeClose<cr>", desc = "Close Claude Terminal" },
100135
},
101136
},
102137
}
@@ -120,13 +155,24 @@ require("claudecode").setup({
120155
auto_start = false,
121156

122157
-- Custom terminal command to use when launching Claude
123-
terminal_cmd = nil, -- e.g., "toggleterm"
158+
-- This command is used by the new interactive terminal feature.
159+
-- If nil or empty, it defaults to "claude".
160+
terminal_cmd = nil, -- e.g., "my_claude_wrapper_script" or "claude --project-foo"
124161

125162
-- Log level (trace, debug, info, warn, error)
126163
log_level = "info",
127164

128165
-- Enable sending selection updates to Claude
129166
track_selection = true,
167+
168+
-- Configuration for the interactive terminal (passed to claudecode.terminal.setup by the main setup function)
169+
terminal = {
170+
-- Side for the vertical split ('left' or 'right')
171+
split_side = "right", -- Default
172+
173+
-- Width of the terminal as a percentage of total editor width (0.0 to 1.0)
174+
split_width_percentage = 0.30, -- Default
175+
}
130176
})
131177
```
132178

@@ -154,6 +200,9 @@ require("claudecode").setup({
154200
- `:ClaudeCodeStop` - Stop the server
155201
- `:ClaudeCodeStatus` - Show connection status
156202
- `:ClaudeCodeSend` - Send current selection to Claude
203+
- `:ClaudeCode` - Toggle the Claude Code interactive terminal window
204+
- `:ClaudeCodeOpen` - Open (or focus) the Claude Code terminal window
205+
- `:ClaudeCodeClose` - Close the Claude Code terminal window
157206

158207
## Keymaps
159208

@@ -162,6 +211,10 @@ No default keymaps are provided. Add your own in your configuration:
162211
```lua
163212
vim.keymap.set("n", "<leader>cc", "<cmd>ClaudeCodeStart<cr>", { desc = "Start Claude Code" })
164213
vim.keymap.set({"n", "v"}, "<leader>cs", "<cmd>ClaudeCodeSend<cr>", { desc = "Send to Claude Code" })
214+
+vim.keymap.set("n", "<leader>ct", "<cmd>ClaudeCode<cr>", { desc = "Toggle Claude Terminal" })
215+
+-- Or more specific maps:
216+
+-- vim.keymap.set("n", "<leader>co", "<cmd>ClaudeCodeOpen<cr>", { desc = "Open Claude Terminal" })
217+
+-- vim.keymap.set("n", "<leader>cx", "<cmd>ClaudeCodeClose<cr>", { desc = "Close Claude Terminal" })
165218
```
166219

167220
## Architecture

flake.nix

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@
2121
nixpkgs-fmt.enable = true; # Nix formatter
2222
prettier.enable = true; # Markdown/YAML/JSON formatter
2323
shfmt.enable = true; # Shell formatter
24+
actionlint.enable = true; # GitHub Actions linter
25+
zizmor.enable = true; # GitHub Actions security analyzer
26+
shellcheck.enable = true; # Shell script analyzer
2427
};
28+
settings.formatter.shellcheck.options = [ "--exclude=SC1091,SC2016" ];
2529
};
2630
in
2731
{

0 commit comments

Comments
 (0)