Files
claude-plugin-nvim-agentic/skills/editor-act/SKILL.md
T
oleks 3c5851e95e v0.5.0: route the neovim MCP through MetaMCP
mcp-neovim-server no longer runs as a per-session npx stdio child.
It is now a MetaMCP namespace upstream on emmett (one persistent
process), reached over Streamable-HTTP via the mcp-session-pool:

  Claude Code -> pool.localhost:12010/p/neovim/mcp
    -> MetaMCP neovim namespace -> mcp-neovim-server -> nvim socket

- .mcp.json: stdio npx server -> streamable-http pool endpoint
- agents/companion.md + skills: tool names are now 3-segment
  (mcp__neovim__neovim__vim_*) — the MetaMCP aggregation shape; the
  surface description and unavailability runbook updated for the
  three-link path (nvim socket / MetaMCP / session)
- README: connection-path diagram

Host side (servers/emmett, deployed separately): neovim added to
services.mcp-session-pool.upstreams; metamcp.nix seeds the neovim
mcp_servers row + mapping and adds nodejs to the unit PATH.
2026-05-21 11:19:49 +03:00

130 lines
4.8 KiB
Markdown

---
name: editor-act
description: |
Drive the user's running Neovim instance — open files, run user
commands, trigger keymaps, jump to LSP locations, toggle UI,
evaluate small lua snippets. Uses the `mcp__neovim__neovim__*` tools
(`vim_command`, `vim_file_open`, `vim_window`, …) against the live
instance. Prefers the user's own commands and keymaps over teaching
new vim syntax. Will *not* edit buffer contents — that work is
handed off via the `claude-code-handoff` skill. Trigger on
"open <file> in nvim",
"jump to definition of", "show file finder", "split this", "toggle
neo-tree", "run this command in my nvim", "go to next diagnostic",
"save my buffer".
disable-model-invocation: false
allowed-tools: Bash, Read, Skill, AskUserQuestion, mcp__neovim__neovim__*
---
# editor-act — do things in the user's nvim
Owner: `nvim-agentic-companion:companion`. This skill is for *acting*
on the running editor in ways that **do not modify buffer contents**.
For buffer edits, invoke `claude-code-handoff` instead.
## Preconditions
`mcp__neovim__neovim__*` tools must be present. If they aren't, stop and tell
the user to restart nvim + Claude Code (see `editor-introspect` for
the recovery message).
## The action hierarchy
When you need to do X, pick the lowest-impact form that works:
1. **An existing user command** the user already has — `:Telescope find_files`,
`:Neotree`, `:Trouble`, `:GitSigns ...`. These reflect how the user
already navigates and produce no surprises.
2. **A user keymap** — when the user asks "open the file finder," running
their `<leader>ff` is preferable to running `:Telescope find_files`
directly: same result, but if they later remap it you also get the
new behavior. Feed the keys via `nvim_feedkeys` after running them
through `nvim_replace_termcodes` — see the "Common patterns" block
at the bottom of this file for the canonical snippet.
3. **A built-in vim command**`:edit`, `:vsplit`, `:tabnew`, `:write`,
`:bnext` — fine for navigation when no plugin command applies.
4. **Lua eval** — last resort, for things with no command surface:
`lua vim.diagnostic.goto_next()` or `lua vim.lsp.buf.definition()`.
Keep snippets short and obvious. Never paste multi-line scripts.
## Safe actions you can do without asking
- Open a file (`:edit`, `:vsplit`, `:tabnew <path>`).
- Jump to a location, definition, or reference (`vim.lsp.buf.*`,
`vim.diagnostic.goto_*`).
- Trigger a user command/keymap they already have.
- Toggle a UI element (file tree, trouble, bufferline state).
- Run `:write` *if* the buffer's only change is one you just made via a
user-blessed command (e.g. they asked you to format and you ran
`:lua vim.lsp.buf.format()`).
## Actions that require a confirmation first
`AskUserQuestion` before:
- Closing windows or buffers (`:q`, `:bd`, `:tabclose`, `:close`).
- Writing files the user did *not* just ask you to write.
- Touching files outside the current project root.
- Changing global state: colorscheme, leader, options that affect every
buffer.
- Running anything destructive against the filesystem from inside lua
(`os.remove`, `vim.fn.delete`, etc.).
## Actions you do not do
- **Editing buffer contents.** If the user wants code changed, that's
`claude-code-handoff`'s job. Do not type characters into a buffer
via `feedkeys`, do not `nvim_buf_set_text`, do not paste into a buffer.
The reason: changes should land as a *diff* the user can review via
claudecode.nvim's accept/reject UI, not as silent mutations.
- **Quitting nvim** (`:qa`, `:wqa`).
- **Source new lua / vimscript files** the user didn't approve. The
declarative config is the source of truth.
## After each action
Leave one short trail sentence in your response: what you did, and what
the user should see. Examples:
- "Ran `<leader>ff` — telescope file picker is open in your nvim window."
- "Jumped to `lualine/init.lua:312` via `vim.lsp.buf.definition()`."
- "Opened `neovim.nix` in a vsplit on your right pane."
If the action didn't produce visible feedback (e.g. you only saved a
buffer), say so — the user can't tell from the screen alone.
## Common patterns
**Open a file from a path you just produced:**
```vim
:e /home/oleks/projects/servers/emmett/nixos/neovim.nix
```
**Open at a specific line:**
```vim
:e +199 /home/oleks/projects/servers/emmett/nixos/neovim.nix
```
**Find what the user has mapped, then run their mapping:**
```vim
:verbose nmap <leader>ff " confirm what's there
" then feed the keys so their setup runs end-to-end
:lua local k = vim.api.nvim_replace_termcodes("<leader>ff", true, false, true)
:lua vim.api.nvim_feedkeys(k, "n", false)
```
**Move to next LSP diagnostic in current buffer:**
```vim
:lua vim.diagnostic.goto_next()
```
**List loaded LSP clients for the current buffer:**
```vim
:lua print(vim.inspect(vim.lsp.get_clients({ bufnr = 0 })))
```