К основному содержанию
скилл CX Codex

lsp-dead-code — скилл для Claude Code: поиск мёртвого кода

Скилл перечисляет экспортируемые символы файла и проверяет каждый на ссылки по всему проекту. Помогает понять, какие экспорты можно удалять.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add blackwell-systems/agent-lsp --skill lsp-dead-code -a claude-code
Открыть на GitHub

Что делает lsp-dead-code

Скилл работает через MCP-сервер agent-lsp. Сначала он вызывает list_symbols и получает список символов в файле, затем для каждого экспортируемого символа дёргает find_references с include_declaration: false — так определение не попадает в счёт, и ноль означает отсутствие вызовов, а не вхождений. Результат — отчёт с классификацией: подтверждённые кандидаты на удаление, символы, найденные только в тестах, и активные.

Что считается экспортом, зависит от языка: в Go — идентификатор с заглавной буквы, в TypeScript — ключевое слово export или публичный член класса, в Python — имя без _ в начале, в Java и C# — public или protected, в Rust — pub.

Перед запуском нужен работающий MCP-сервер agent-lsp и проиндексированный проект. Без индексации find_references вернёт пустой список даже для символов, которые точно используются, — поэтому в скилле есть обязательный шаг прогрева: проверка ссылок на заведомо живом символе. Если он даёт ноль, скилл ждёт и повторяет, а после 15 секунд перезапускает LSP-сервер. Ещё одна ловушка — регистрация через передачу значения: обработчик, отданный в server.AddTool(HandleFoo), для LSP выглядит мёртвым, и скилл советует дополнительно искать имя через grep по файлам сборки. Удалять что-либо без ручной проверки отчёта не стоит.

Какие задачи решает

  • найти экспорты без единой ссылки в проекте
  • почистить публичный API пакета перед релизом
  • отличить символы, используемые только в тестах, от действительно мёртвых
  • проверить, не сломается ли удаление обработчика, зарегистрированного через передачу значения
  • разобраться, почему LSP не видит ссылки на живой символ

Примеры запросов агенту

  • Проверь internal/api/handlers.go на мёртвый код
  • Какие экспорты в pkg/client/client.go нигде не вызываются?
  • Прогони lsp-dead-code по server.go и покажи отчёт

Как установить lsp-dead-code

1Через Skills CLI (Vercel)

npx skills add blackwell-systems/agent-lsp --skill lsp-dead-code -a claude-code

2Вручную: положить файлы

~/.claude/skills/lsp-dead-code/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/lsp-dead-code/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о lsp-dead-code

Как установить lsp-dead-code в Claude Code?

Выполните npx skills add blackwell-systems/agent-lsp --skill lsp-dead-code -a claude-code. Скилл появится в ~/.claude/skills/lsp-dead-code/SKILL.md.

Что делает lsp-dead-code?

Перечисляет экспортируемые символы файла и проверяет ссылки на каждый из них по всему проекту. На выходе — отчёт с кандидатами на удаление и пометками о тестовом использовании.

Что нужно для работы скилла?

MCP-сервер agent-lsp и проиндексированный проект. Если LSP ещё не запущен, скилл вызывает mcp__lsp__start_lsp с корнем проекта.

Исходный текст

SKILL.md · MIT
---
name: lsp-dead-code
description: Enumerate exported symbols in a file and surface those with zero references across the workspace. Use when auditing for dead code, cleaning up APIs, or checking which exports are safe to remove.
argument-hint: "[file-path]"
user-invocable: true
allowed-tools: mcp__lsp__list_symbols mcp__lsp__find_references mcp__lsp__open_document mcp__lsp__safe_delete_symbol
license: MIT
compatibility: Requires the agent-lsp MCP server (github.com/blackwell-systems/agent-lsp)
metadata:
  required-capabilities: documentSymbolProvider referencesProvider
---

> Requires the agent-lsp MCP server.

# lsp-dead-code

Audit an exported symbol list for zero-reference candidates. Calls
`list_symbols` to enumerate symbols, then checks each exported
symbol with `find_references` to find callers. Produces a classified report.

## When to Use

Use this skill when you want to identify dead code in a file — exported
symbols that are defined but never called anywhere in the workspace. Common
use cases:

- Cleaning up APIs before a release
- Identifying legacy exports that can be safely removed
- Auditing a package for unused public surface area

**Important:** This skill surfaces *candidates*. Always review results
manually before deleting anything. See the Caveats section below.

## What counts as "exported"

| Language   | Exported means...                                                      |
|------------|------------------------------------------------------------------------|
| Go         | Identifier starts with an uppercase letter (e.g. `MyFunc`, `MyType`)  |
| TypeScript | Has `export` keyword; or is a public class member (no `private`)       |
| Python     | Not prefixed with `_`; or explicitly listed in `__all__`               |
| Java/C#    | Has `public` or `protected` visibility modifier                        |
| Rust       | Has `pub` keyword                                                      |

## Prerequisites

If LSP is not yet initialized, call `mcp__lsp__start_lsp` with the
workspace root first:

```
mcp__lsp__start_lsp({ "root_dir": "/your/workspace" })
```

agent-lsp supports auto-inference from file paths, so explicit start is
only required when switching workspaces or on a cold session.

## Step 0 — Verify indexing is complete (mandatory)

**Do not skip this step.** An under-indexed workspace returns `[]` for
symbols that ARE referenced, producing false dead-code candidates.

Pick one symbol you know is actively used (e.g. the primary constructor,
a widely-called utility function). Call `find_references` on it:

```
mcp__lsp__find_references({
  "file_path": "/abs/path/to/file.go",
  "line": <known-active symbol line>,
  "column": <known-active symbol column>,
  "include_declaration": false
})
```

**If this returns `[]`:** the workspace is not indexed. Wait 3–5 seconds
and retry. Do not proceed until a known-active symbol returns ≥1 reference.
If it never returns results after 15 seconds, restart the LSP server with
`mcp__lsp__restart_lsp_server` and re-open the target file.

## Step 1 — Open the file and enumerate symbols

Open the file so the language server tracks it, then fetch all symbols:

```
mcp__lsp__open_document({ "file_path": "/abs/path/to/file.go" })

mcp__lsp__list_symbols({ "file_path": "/abs/path/to/file.go" })
```

Collect the full symbol list. Filter to **exported symbols only** using the
language-appropriate rule from the table above.

**Coordinate note:** `list_symbols` returns 1-based coordinates.
Pass `selectionRange.start.line` and `selectionRange.start.character`
directly to `find_references` — no conversion needed.

**"no identifier found" error:** This means the column points to whitespace
or a keyword rather than the identifier name. This happens with methods
whose receiver prefix shifts the name rightward (e.g. `func (c *Client) MethodName`
— the name starts at column 21, not column 1). Fix: grep the declaration
line for the symbol name to find its exact column:

```
grep -n "MethodName" file.go
# count characters to find the 1-based column of the name
```

Then retry `find_references` with the corrected column.

## Step 2 — Check references for each exported symbol

For each exported symbol, call `find_references` with
`include_declaration: false` so the definition site itself is excluded
from the count. A count of 0 means no callers, not no occurrences.

```
mcp__lsp__find_references({
  "file_path": "/abs/path/to/file.go",
  "line": <selectionRange.start.line>,
  "column": <selectionRange.start.character>,
  "include_declaration": false
})
```

Record the result for each symbol:
```
{ symbol_name, kind, line, reference_count, locations[] }
```

**Batching note:** For files with many exported symbols (>20), process in
batches of 5–10 to avoid overwhelming the LSP server.

**Zero-reference cross-check (required before classifying as dead):**
When `find_references` returns `[]` for a symbol that looks foundational
(a handler, a constructor, a type used as a field), do not trust LSP alone.
LSP can miss references made through value-passing, interface satisfaction,
or function registration patterns (e.g. `server.AddResource(HandleFoo)`).
Before classifying as dead, run a text search in the primary wiring files:

```
grep -r "SymbolName" main.go server.go cmd/ internal/
```

If grep finds the name in a registration or assignment context, the symbol
is active — LSP just couldn't resolve the indirect reference. Update your
classification accordingly.

## Step 3 — Classify and report

Classify each exported symbol by reference count:

- **Zero references (LSP + grep)** — confirmed dead candidate. Flag with WARNING.
- **Zero LSP, found by grep** — active via registration/value pattern. Mark as ACTIVE.
- **1–2 references** — review manually. May be test-only usage.
- **3+ references** — active symbol. Not dead code.

For test-only references: if all locations are in `_test.go` files (Go) or
files named `*.test.*` / `*.spec.*`, mark the symbol as "test-only" in
the report rather than "zero-reference".

Produce the Dead Code Report using the format in
[references/patterns.md](references/patterns.md).

## Caveats

The following cases produce zero LSP references even though the symbol IS
used at runtime. Do not delete any zero-reference candidate without
manual review:

1. **Incomplete indexing.** `find_references` only searches files open or
   indexed by the language server. If the workspace is partially indexed,
   results may be incomplete. The Step 0 warm-up check catches this.

2. **Registration patterns.** Symbols passed as values to registration
   functions (e.g. `server.AddTool(HandleFoo)`, `http.HandleFunc("/", handler)`)
   appear as zero LSP references from the *definition site* because gopls
   tracks the call to the registrar, not the handler name. Always grep
   wiring files for zero-reference handlers before classifying as dead.

3. **Reflection and dynamic dispatch.** Symbols used via reflection
   (`reflect.TypeOf` in Go, `Class.forName` in Java) or dynamic dispatch
   have no static call sites visible to the LSP.

4. **`//go:linkname` and assembly.** Go symbols linked via `//go:linkname`
   or referenced from assembly files will show zero LSP references.

5. **Library public API.** Exported symbols called from external packages
   not present in the workspace will show zero references even if
   consumers exist.

6. **Declaration excluded from count.** The definition site is not counted
   (`include_declaration: false`). A count of 0 means no callers found,
   not that the symbol never appears in the source tree.

7. **Always review before deleting.** Zero LSP references is a signal to
   investigate, not a guarantee the symbol is unused.

## Step 4 — Next steps

After generating the report:

- **For each zero-reference symbol (confirmed by grep):** Run `lsp-impact`
  on the symbol to confirm. If `lsp-impact` also finds zero references, it
  is safe to consider for removal. Still check the Caveats section above.

- **For symbols with only test-file references:** Mark as "test-only" in
  the report. These may be candidates for removal if the tests themselves
  are redundant, but should not be deleted without reviewing whether the
  tests serve a documentation or contract purpose.

- **For symbols with 1–2 references in production code:** These are likely
  active but lightly used. Do not remove without checking whether they are
  part of a committed public API.

## Step 5 — Optional cleanup with `safe_delete_symbol`

After reviewing the dead code report and confirming candidates with the user,
you may offer to remove confirmed zero-reference symbols using `safe_delete_symbol`:

```
mcp__lsp__safe_delete_symbol({
  "file_path": "/abs/path/to/file.go",
  "symbol_path": "DeadFunction"
})
```

This tool performs its own reference check before deleting. If any references
exist (even ones missed in the initial scan), the deletion is refused.

**Requirements before using this step:**

1. The user has explicitly confirmed they want the symbol removed.
2. The symbol was classified as a confirmed dead candidate (zero LSP + zero grep references).
3. You have reviewed the Caveats section above and communicated relevant risks.

Do NOT auto-delete symbols without user confirmation. Present the dead code
report first, let the user select which symbols to remove, then execute
`safe_delete_symbol` for each approved removal.

© blackwell-systems · MIT · blackwell-systems/agent-lsp

Похожие скиллы

Все скиллы по теме «Код-ревью и рефакторинг» →
improve-codebase-architecture Matt Pocock Скилл ищет архитектурные узкие места в кодовой базе и показывает варианты углубления модулей в HTML-отчёте. Подойдёт для ревью перед рефакторингом. 1 163 035установок tdd Matt Pocock Скилл управляет циклом красный-зелёный в TDD: проверяет, что тесты пишутся до кода, держит их на уровне публичных интерфейсов и не завязывает на внутреннюю структуру. 1 141 062установок triage Matt Pocock Скилл проводит issue и внешние PR через роли триажа, проверку и подготовку брифа для агента. Подойдёт мейнтейнеру, который разбирает очередь задач. 990 453установок codebase-design Matt Pocock Скилл помогает проектировать модули с небольшим интерфейсом и скрытой внутри сложностью. Подходит для рефакторинга, тестируемости и поиска чистого seam. 850 344установок code-review Matt Pocock Проверяет изменения от выбранной точки по стандартам репозитория и требованиям задачи. Нужен для ревью ветки, PR или незавершённой работы. 789 521установок implement Matt Pocock Выполняет задачу по спецификации или тикетам, ведёт работу через тесты и завершает её ревью с коммитом. Подходит для задач, где нужен дисциплинированный цикл разработки. 774 700установок

Из того же набора9

lsp-test-correlation Находит тесты, которые покрывают изменённый файл, и запускает только их. Пригодится, когда правишь один файл и не хочешь гонять весь набор. CX Codex +1 ★ 165звёзд репо lsp-rename Переименовывает функции, методы, переменные и типы по всему проекту в два этапа: сначала показывает все затронутые места, потом меняет их после подтверждения. CX Codex +1 ★ 165звёзд репо lsp-local-symbols Показывает, какие функции и типы объявлены в файле, где используется переменная и какой у неё тип. Пригодится перед правкой одного файла. CX Codex +1 ★ 165звёзд репо lsp-impact Показывает всех вызывающих, супертипы и подтипы, число ссылок на символ или файл до того, как вы что-то поменяете. Пригодится при рефакторинге и удалении кода. CX Codex +1 ★ 165звёзд репо lsp-fix-all Прогоняет все диагностики в файле и применяет доступные quick-fix от языкового сервера. Пригодится, когда в файле накопились ошибки и предупреждения перед новой работой. CX Codex +1 ★ 165звёзд репо lsp-edit-symbol Меняет функцию, тип или переменную по имени, когда точный файл и позиция неизвестны. Работает через MCP-сервер agent-lsp. CX Codex +1 ★ 165звёзд репо lsp-architecture Собирает структурный обзор кодовой базы: языки, пакеты, точки входа, зависимости и горячие файлы. Один вызов вместо ручного обхода репозитория. CX Codex +1 ★ 165звёзд репо agent-lsp Координирует языковые серверы и предоставляет агенту 65 инструментов для работы с кодом на 32 языках без постоянного повторного сканирования. CX Codex +1 ★ 165звёзд репо

Спонсоры проекта

Компании, которые помогают держать аналитику открытой