Files
claude-plugin-nvim-agentic/skills/editor-introspect/SKILL.md
T
oleks acf207e53b Initial commit: nvim-agentic-companion plugin
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
2026-05-21 00:22:05 +03:00

111 lines
4.6 KiB
Markdown

---
name: editor-introspect
description: |
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".
disable-model-invocation: false
allowed-tools: 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_keymap` returns 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
`:checkhealth` whole.
- 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:
1. `messages` — did something fail at startup?
2. `:checkhealth <suspected-module>` — does the module itself complain?
3. `verbose set <option>?` or `verbose nmap <key>` — is something overriding?
4. `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_number` from
`{{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
`:messages` dump verbatim unless the user asks.