Adds a Claude Code agent and three skills for collaborating with the user's running Neovim instance via mcp-neovim-server and the official coder/claudecode.nvim plugin: - agents/companion.md — the nvim companion identity, prefers runtime introspection over training-data guessing - skills/editor-introspect — read-only queries against the live editor - skills/editor-act — safe driving (open, jump, toggle, run); no buffer edits - skills/claude-code-handoff — delegate buffer edits to the in-editor Claude Code session so users get a diff to accept or reject
4.6 KiB
name, description, disable-model-invocation, allowed-tools
| name | description | disable-model-invocation | allowed-tools |
|---|---|---|---|
| editor-introspect | Read-only inspection of the user's running Neovim instance via `mcp__neovim__*` tools. Use whenever a question depends on the live editor state: what is mapped to a key, which buffers are open, what the cursor is on, what diagnostics exist, which plugins are loaded, what the messages buffer says. Returns concrete facts grounded in the running instance — never guesses from training data. Trigger on "what's bound to", "what's mapped to", "what buffers", "show me the keymaps", "is X loaded", "what plugins are active", "current selection", "what's the cursor on", "any diagnostics", "lualine theme actually applied". | false | Bash, Read |
editor-introspect — read the live nvim instance
Owner: nvim-agentic-companion:companion. This skill is for reading
the running editor. Never use it to mutate state — use editor-act
for that.
Preconditions
The user's nvim must be running with an RPC socket reachable by the
mcp-neovim-server MCP server. If mcp__neovim__* tools are not
present in this session, stop and tell the user:
The neovim MCP server isn't connected to this Claude Code session. Start (or restart) nvim so it creates the socket at
{{nvim_socket}}, then restart Claude Code.
Do not try to fake introspection from the config alone.
The introspection vocabulary
These are the queries you should reach for first. All are runnable
via mcp__neovim__nvim_command (returns the rendered command output)
or mcp__neovim__nvim_eval (returns a value).
Keymaps
verbose nmap <leader>ff— what (and where in lua) is<leader>ff?verbose imap <C-Space>— same for insert mode.nmap <leader>— all normal-mode mappings starting with leader.- For machine-readable form prefer:
lua print(vim.inspect(vim.api.nvim_get_keymap("n")))…then grep client-side.nvim_get_keymapreturns the LHS, RHS, mode, desc, and the file/line set when known.
Buffers, windows, tabs
ls!— list buffers, including hidden.lua print(vim.inspect(vim.api.nvim_list_bufs()))lua print(vim.api.nvim_buf_get_name(0))— current buffer path.lua print(vim.inspect(vim.api.nvim_tabpage_list_wins(0)))- For the visible layout the user is staring at, prefer windows over buffers.
Cursor, selection, mode
lua print(vim.inspect(vim.api.nvim_win_get_cursor(0)))—[row, col].lua print(vim.fn.mode())—n,i,v,V,^V, etc.- For the current visual selection text:
lua print(vim.fn.getregion(vim.fn.getpos("v"), vim.fn.getpos("."), {type=vim.fn.mode()}))(Neovim ≥ 0.10).
Options
set option?— value of a single option (set number?).verbose set option?— and the file that last set it.lua print(vim.bo.filetype)/vim.wo.wrap/vim.o.background.
Diagnostics
lua print(vim.inspect(vim.diagnostic.get(0)))— current buffer's diagnostics.lua print(vim.inspect(vim.diagnostic.count()))— counts by severity.lua print(vim.lsp.get_active_clients() | vim.iter ... | ...)— which LSPs are attached.
Plugins / runtime
lua print(vim.inspect(package.loaded["lualine"]) ~= nil)— is X loaded?messages— startup warnings, last few notifications.checkhealth <module>— for a single module; the long-form output is huge, so prefer specific modules (e.g.:checkhealth lualine) over:checkhealthwhole.- For the lualine theme actually in use:
lua print(require("lualine").get_config().options.theme)
"Why is X happening?"
When the user reports a symptom, the introspection script is:
messages— did something fail at startup?:checkhealth <suspected-module>— does the module itself complain?verbose set <option>?orverbose nmap <key>— is something overriding?vim.lsp.get_active_clients()/vim.diagnostic.get(0)— is LSP behaving?
Stop as soon as you have the answer. Do not run a sweep when one query is enough.
How to report findings
- Quote the exact runtime output you got, not a paraphrase.
- When citing config provenance, give
file_path:line_numberfrom{{config_path}}(default/home/oleks/projects/servers/emmett/nixos/neovim.nix). - If runtime disagrees with config, say so explicitly: "Config sets X but the loaded value is Y — likely a stale build / missing reload."
- For long outputs, summarize and offer to drill in. Don't paste a 200-line
:messagesdump verbatim unless the user asks.