code-intelligence
Use when navigating or refactoring code with a language server - choosing between semantic (LSP), exact-text (rg), and fuzzy/semantic search; anchoring LSP calls by position; gating degraded results; and disclosing tool substitutions, in any language.
Install
npx skills add https://github.com/antonbabenko/agent-plugins/tree/master/plugins/code-intelligence/skills/code-intelligence
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install antonbabenko-agent-plugins@llmmart
git clone https://github.com/antonbabenko/agent-plugins.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole antonbabenko/agent-plugins collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Code Intelligence
Pick the search tool by task, not by habit. Generic and language-agnostic;
domain skills extend it with server capability matrices and ecosystem
prerequisites - for example the terraform-skill plugin (same marketplace)
owns the terraform-ls capability matrix and Terraform setup. It is
model-triggered guidance, not enforcement.
Tool Precedence
| Goal | Use | Tradeoff |
|---|---|---|
| Symbol relationships: definition, references, call sites, rename safety | Language server (LSP) at a position | Needs a running server + indexed workspace |
| Exact text, known name, exhaustive enumeration, config/value files | rg then Read |
No semantic scope; matches strings in comments too |
| Conceptual / fuzzy / "where might this live" / cross-repo discovery | A semantic/neural search tool, if the host provides one | Not exact; never use for counts or completeness claims |
Detail: Precedence Table, When LSP Is Wrong.
Calling the LSP
- DO call at a position (
file:line:character). Anchor the position with a text search for a known occurrence first. - DON'T pass a bare symbol name and expect resolution. A name-only call that returns empty is a usage defect, not server failure.
- DO Read the returned locations for source text; LSP returns locations and symbols, not the lines.
- DO retry once on a cold start: the first call after launch may return empty while the server indexes.
- DO prefer the server's own operation when it advertises it: use
rename/prepareRenamefor renames and call hierarchy for callers - they carry language-specific semantics a manual pass misses. - DON'T report an unsupported operation as a finding. When the server lacks
one, redirect:
findReferences(then filter to call sites) instead of call hierarchy; enumerate references then hand-edit instead of a rename provider.
Detail: Position Anchoring, Unsupported Operations.
Degradation Gate
Two distinct cases:
- No LSP at all (host exposes no language-server tool, or the server fails to start): that IS unavailability. Disclose it on the first line (see below) and use text search. The gate does not apply - there is nothing to gate.
- LSP callable but a position-anchored call returns empty: do NOT conclude
"unavailable" yet. Pass ALL three:
documentSymbolon an in-scope file returns symbols -> server responsive (responsiveness only, NOT proof of complete reference coverage).- The failing call was position-anchored (not symbol-name-only).
- That anchored call still returned empty after a cold-start retry.
Only after the three-part case passes is a disclosed text fallback warranted.
Detail: Degradation Gate.
Disclose Substitutions
State any tool substitution OR omission on the FIRST line of the response, not in a later summary (post-hoc accounting is a rule violation):
Intended: <tool>. Actual: <tool>. Reason: <why>. Impact: <completeness/confidence>.
Detail: Disclosure Format.
Do Not Invent a Missing Tool
Before claiming a tool (e.g. rg) is shimmed, aliased, or absent, prove it:
type -a <tool>, ls -l the resolved path, <tool> --version shows the
expected banner. An unproven "tool is missing" claim followed by a fallback is
a verification failure, not a sanctioned substitution.
If genuinely absent or aliased: prefer the LSP for semantic tasks; for exact
text use the host-approved text search; git grep / grep only as an
explicitly disclosed last resort, never the default substitute.
Detail: Anti-Phantom-Shim Proof.
Files (agent-plugins)
-
references
-
degradation-and-disclosure.md 2.5 KB
# Degradation and Disclosure What to prove before falling back, how to announce a fallback, and how to prove a tool is really missing. ## Degradation Gate First separate two cases: - **No LSP at all**: the host exposes no language-server tool, or the server will not start. This is genuine unavailability - the gate does not apply. Disclose on the first line (see Disclosure Format) and use text search. - **LSP callable, position-anchored call returns empty**: a degraded or unindexed workspace can legitimately do this. Do not conclude "unavailable" - run the gate. Gate (second case only). Pass ALL three before claiming "LSP degraded, using text search": 1. `documentSymbol` on an in-scope file returns symbols. The server is responsive. This proves responsiveness ONLY, not complete reference coverage. 2. The failing call was position-anchored, not symbol-name-only. 3. That anchored call still returned empty after a cold-start retry. All three pass -> a disclosed text fallback is warranted. Any fails -> fix the call or the setup; do not fall back yet. Distinguish: a name-only call returning empty is a usage defect (gate fails at 2). A position-anchored call on a responsive server returning empty is genuine degradation (gate passes). ## Disclosure Format State any tool substitution OR omission on the FIRST line of the response: `Intended: <tool>. Actual: <tool>. Reason: <why>. Impact: <completeness/confidence>.` - Covers substitution (used a different tool) AND omission (skipped a step or scope). - First line, same response. A later closing summary is a rule violation - the reader must see the caveat before the conclusion. - One line, factual, no hedging. The impact clause states what confidence is lost (e.g. "text matches only, may include comments/strings"). ## Anti-Phantom-Shim Proof Do not claim a tool is shimmed, aliased, replaced, or missing without proof. Verify before asserting: 1. `type -a <tool>` - resolve what actually runs. 2. `ls -l <resolved-path>` - confirm the binary exists and is executable. 3. `<tool> --version` - confirm it prints the expected banner. If it prints the expected version, the tool is real - investigate the execution context (sandbox, PATH, shell) before any fallback. An unproven "tool is missing" claim followed by a fallback is a verification failure, not a sanctioned substitution. If genuinely absent or aliased: prefer the LSP for semantic tasks; for exact text use the host-approved text search; `git grep` / `grep` only as an explicitly disclosed last resort, never the default substitute. -
lsp-calls.md 2.4 KB
# LSP Calls Generic mechanics for driving a language server. Operation names follow LSP: `goToDefinition`, `findReferences`, `hover`, `documentSymbol`, `workspaceSymbol`, `goToImplementation`, call hierarchy. Availability is host-gated - the host decides whether an LSP tool is exposed at all. ## Position Anchoring The server resolves by source position, not by symbol name. - Call with `file:line:character` pointing at an occurrence of the symbol. - Find that occurrence first with a text search (a known use or the declaration), then issue the LSP call at that location. - A bare-name call is unsupported; an empty result from one is a usage defect, not degradation. Example: to find callers of `parseConfig`, `rg -n 'parseConfig'` to get a line, then `findReferences` at that line/column. Works the same whether the language is Go, Python, or TypeScript. ## Cold Start And Retry The first call after the server launches may return empty or partial while it indexes the workspace. - Retry the same call once after a short pause before drawing any conclusion. - A still-empty result after retry feeds the degradation gate; it is not immediate proof the server is broken. ## Unsupported Operations Not every server implements every operation. `goToImplementation`, call hierarchy (`prepareCallHierarchy` / `incomingCalls` / `outgoingCalls`), and rename are commonly absent. - DO check advertised capabilities first. When the server supports `rename` / `prepareRename` or call hierarchy, use it - it carries language semantics a manual pass misses. - DON'T call an unsupported operation and report its absence as a finding. - DO redirect only when the operation is genuinely unsupported: `findReferences` (filtered to call sites) instead of call hierarchy; enumerate references then edit by hand instead of a rename provider. - DON'T guess support - confirm via advertised capabilities or a language skill that documents them. ## Reading Results LSP returns locations and symbols, not source lines. - After `goToDefinition` / `findReferences`, Read each returned location to see and act on the actual code. - For multi-edit changes in one file, Read that file again immediately before each edit - earlier edits shift line/character offsets and a stale view produces corrupted edits. - `documentSymbol` returns a structural outline; use it as a liveness probe and to navigate, not as a reference set. -
tool-precedence.md 2.6 KB
# Tool Precedence LSP for symbol meaning, text search for literals, semantic search for fuzzy discovery. The three are not interchangeable. ## Precedence Table | Task | Tool | Why | |------|------|-----| | Where is this symbol defined? | LSP `goToDefinition` at a use site | Resolves scope, imports, shadowing - text search cannot | | Every reference of a symbol | LSP `findReferences` at the symbol | Excludes same-named-but-unrelated tokens; includes definition/imports/reads/writes, not only calls | | Callers specifically | LSP call hierarchy if the server supports it, else `findReferences` filtered to call sites | `findReferences` alone is broader than callers | | Rename | LSP `rename` / `prepareRename` if supported, else `findReferences` + per-file manual edits | Server rename carries language semantics; manual edits hit comments/strings/unrelated scopes if not filtered | | Exact literal, error string, config key | `rg` then Read | Deterministic, fast, complete for text | | Enumerate all matches / count occurrences | `rg` | Exact and exhaustive; semantic search drops matches | | "Where is auth handled?", "which module owns X" | Semantic/neural search (if host provides) | Intent-level, no exact symbol to anchor on | A directive that says one search tool replaces all search applies to broad discovery only. It does not override LSP for symbol work or `rg` for exact enumeration. ## When LSP Is Wrong Skip the LSP and go straight to `rg` + Read for: - Exact text or a known literal you can match directly. - Known-name lookup where you already have the file and just need the line. - Config / value files (data, not a symbol graph). - Comments, generated docs, lockfiles, changelogs. - Any file the language server does not index (non-source, vendored output). LSP answers "what does this symbol mean and where is it used", not "where does this string appear". Using it for the latter is slower and no more accurate. ## Semantic Search Scope Semantic / neural search is for conceptual discovery when there is no exact token to anchor on: "where is rate limiting", "which package handles billing". - DO use it to locate a starting area, then switch to LSP or `rg` for precision. - DON'T use it for exhaustive enumeration or any count - it drops exact matches and cannot prove completeness. - DON'T cite its results as "all" of anything. Treat output as leads, not a closed set. Example: "find everywhere we validate JWTs" - semantic search points at the auth package; `rg 'jwt'` plus LSP `findReferences` on the verifier function (see [Position Anchoring](lsp-calls.md#position-anchoring)) gives the complete set.
-
-
SKILL.md 4.2 KB
--- name: code-intelligence description: Use when navigating or refactoring code with a language server - choosing between semantic (LSP), exact-text (rg), and fuzzy/semantic search; anchoring LSP calls by position; gating degraded results; and disclosing tool substitutions, in any language. license: Apache-2.0 metadata: author: Anton Babenko version: 0.5.0 --- # Code Intelligence Pick the search tool by task, not by habit. Generic and language-agnostic; domain skills extend it with server capability matrices and ecosystem prerequisites - for example the `terraform-skill` plugin (same marketplace) owns the terraform-ls capability matrix and Terraform setup. It is model-triggered guidance, not enforcement. ## Tool Precedence | Goal | Use | Tradeoff | |------|-----|----------| | Symbol relationships: definition, references, call sites, rename safety | Language server (LSP) at a position | Needs a running server + indexed workspace | | Exact text, known name, exhaustive enumeration, config/value files | `rg` then Read | No semantic scope; matches strings in comments too | | Conceptual / fuzzy / "where might this live" / cross-repo discovery | A semantic/neural search tool, if the host provides one | Not exact; never use for counts or completeness claims | Detail: [Precedence Table](references/tool-precedence.md#precedence-table), [When LSP Is Wrong](references/tool-precedence.md#when-lsp-is-wrong). ## Calling the LSP - DO call at a position (`file:line:character`). Anchor the position with a text search for a known occurrence first. - DON'T pass a bare symbol name and expect resolution. A name-only call that returns empty is a usage defect, not server failure. - DO Read the returned locations for source text; LSP returns locations and symbols, not the lines. - DO retry once on a cold start: the first call after launch may return empty while the server indexes. - DO prefer the server's own operation when it advertises it: use `rename` / `prepareRename` for renames and call hierarchy for callers - they carry language-specific semantics a manual pass misses. - DON'T report an unsupported operation as a finding. When the server lacks one, redirect: `findReferences` (then filter to call sites) instead of call hierarchy; enumerate references then hand-edit instead of a rename provider. Detail: [Position Anchoring](references/lsp-calls.md#position-anchoring), [Unsupported Operations](references/lsp-calls.md#unsupported-operations). ## Degradation Gate Two distinct cases: - **No LSP at all** (host exposes no language-server tool, or the server fails to start): that IS unavailability. Disclose it on the first line (see below) and use text search. The gate does not apply - there is nothing to gate. - **LSP callable but a position-anchored call returns empty:** do NOT conclude "unavailable" yet. Pass ALL three: 1. `documentSymbol` on an in-scope file returns symbols -> server responsive (responsiveness only, NOT proof of complete reference coverage). 2. The failing call was position-anchored (not symbol-name-only). 3. That anchored call still returned empty after a cold-start retry. Only after the three-part case passes is a disclosed text fallback warranted. Detail: [Degradation Gate](references/degradation-and-disclosure.md#degradation-gate). ## Disclose Substitutions State any tool substitution OR omission on the FIRST line of the response, not in a later summary (post-hoc accounting is a rule violation): `Intended: <tool>. Actual: <tool>. Reason: <why>. Impact: <completeness/confidence>.` Detail: [Disclosure Format](references/degradation-and-disclosure.md#disclosure-format). ## Do Not Invent a Missing Tool Before claiming a tool (e.g. `rg`) is shimmed, aliased, or absent, prove it: `type -a <tool>`, `ls -l` the resolved path, `<tool> --version` shows the expected banner. An unproven "tool is missing" claim followed by a fallback is a verification failure, not a sanctioned substitution. If genuinely absent or aliased: prefer the LSP for semantic tasks; for exact text use the host-approved text search; `git grep` / `grep` only as an explicitly disclosed last resort, never the default substitute. Detail: [Anti-Phantom-Shim Proof](references/degradation-and-disclosure.md#anti-phantom-shim-proof).
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.