Ensure accessibility in UI components including semantic HTML, ARIA attributes, keyboard navigation, and WCAG 2.2 AA compliance.
日本語の概要は準備中です。原文の説明を表示しています。
Compiler-level code intelligence via native LSP — definitions, references, types, call hierarchies, and diagnostics.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
<identity> Compiler-level code intelligence skill. Uses Claude Code's native LSP tool to provide type-safe navigation: go-to-definition, find-references, hover info, call hierarchies, and workspace symbol search. Includes an automated diagnostics runner for dead-code detection and broken-import scanning. Complements text search (ripgrep), semantic search (code-semantic-search), and structural search (code-structural-search) with compiler- verified precision. </identity> <capabilities> - Navigate to symbol definitions across the workspace (goToDefinition) - Find all references to a symbol (findReferences) - Get type information and documentation on hover (hover) - List all symbols in a document (documentSymbol) - Search symbols across the workspace by name (workspaceSymbol) - Navigate to interface/abstract method implementations (goToImplementation) - Build call hierarchy trees: callers (incomingCalls) and callees (outgoingCalls) - Prepare call hierarchy items at a position (prepareCallHierarchy) - **Automated diagnostics**: Run dead-code and broken-import scans via `lsp-diagnostics-runner.cjs` </capabilities>PREREQUISITE: LSP tools are deferred. Load first: ToolSearch({query:"select:LSP"}) CRITICAL: LSP returns EMPTY for .cjs files. Use ripgrep for .cjs instead.
Use lsp-navigator when you need compiler-verified precision rather than text-based heuristics:
Use the diagnostics runner (lsp-diagnostics-runner.cjs) when you need:
Do NOT use for:
pnpm search:code first)| Operation | Purpose | Best For |
|---|---|---|
goToDefinition | Find where a symbol is defined | Navigating to source of imported functions/classes |
findReferences | Find all usages of a symbol | Impact analysis before refactoring |
hover | Get type info and docs | Verifying parameter types, checking API contracts |
documentSymbol | List all symbols in a file | File structure overview, finding entry points |
workspaceSymbol | Search symbols by name | Finding functions/classes across the workspace |
goToImplementation | Find implementations of interface | Tracing concrete behavior of abstract types |
prepareCallHierarchy | Get call hierarchy item ⚠️ Always call this BEFORE incomingCalls/outgoingCalls or you get silent empty results. | Setting up for incoming/outgoing call analysis |
incomingCalls | Find all callers | Understanding who depends on this function |
outgoingCalls | Find all callees | Understanding what a function depends on |
All operations require: filePath (absolute path), line (1-based), character (1-based).
| Question | Tool | Why |
|---|---|---|
"Where is foo defined?" | lsp-navigator (goToDefinition) | Compiler-precise, follows imports/re-exports |
"Who calls foo?" | lsp-navigator (incomingCalls) | Complete call graph, not just text matches |
"What type does foo return?" | lsp-navigator (hover) | Compiler-resolved types, including generics |
"Find all usages of foo" | lsp-navigator (findReferences) | Compiler-aware, excludes comments/strings |
| "Find files about authentication" | code-semantic-search | Conceptual search, not tied to symbol names |
"Find foo in all .cjs files" | ripgrep (rg -F "foo") | Fastest for exact text, works without LSP |
| "Find all async functions" | code-structural-search | AST pattern matching, language-agnostic |
| "What functions are in this file?" | lsp-navigator (documentSymbol) | Structured symbol list with types |
| "Find class X across workspace" | lsp-navigator (workspaceSymbol) | Name-based but compiler-indexed |
| "Find code similar to this pattern" | code-semantic-search | Embedding-based similarity |
| "Find all try-catch blocks" | code-structural-search | AST pattern: try { $$ } catch ($E) { $$ } |
| "What does this function call?" | lsp-navigator (outgoingCalls) | Full dependency graph of a function |
"Find foo in comments too" | ripgrep | LSP excludes non-code; rg searches all text |
Decision Flowchart:
START: What do you need?
|
+--> Need compiler-verified type/definition/reference info?
| YES --> lsp-navigator
| NO
| |
+--> Need conceptual/intent-based code discovery?
| YES --> code-semantic-search / pnpm search:code
| NO
| |
+--> Need AST pattern matching (structural shape)?
| YES --> code-structural-search
| NO
| |
+--> Need exact text/literal match?
YES --> ripgrep / rg -F
The complete search preference order (see also code-standards.md):
1. pnpm search:code -- hybrid BM25 + semantic (discovery, default)
2. lsp-navigator -- compiler-level definitions, references, types
3. Skill({ skill: 'ripgrep' }) -- fast text/regex search
4. Skill({ skill: 'code-semantic-search' }) -- conceptual/intent search
5. Skill({ skill: 'code-structural-search' }) -- AST pattern matching
6. Grep -- FALLBACK ONLY (advanced regex, single-file)
Note: lsp-navigator sits at position 2 because once you know a symbol/location (found via position 1), LSP provides the most precise navigation. Discovery (position 1) is still needed to find initial entry points.
<instructions>After editing a file, verify types and references are correct:
// After editing src/auth/jwt.ts line 45
// Step 1: Verify the function signature is correct
lsp_hover({ filePath: '/abs/path/src/auth/jwt.ts', line: 45, character: 10 });
// Step 2: Check that imported symbol resolves
lsp_goToDefinition({ filePath: '/abs/path/src/auth/jwt.ts', line: 3, character: 15 });
// Step 3: Verify references haven't broken
lsp_findReferences({ filePath: '/abs/path/src/auth/jwt.ts', line: 45, character: 10 });
Pattern: Edit → hover to verify types → goToDefinition to verify imports resolve → findReferences to verify callers still work.
Creator/updater agents trace execution flows:
// Tracing how a hook is called
// Step 1: Find the function definition
lsp_goToDefinition({
filePath: '/abs/path/.claude/hooks/routing/routing-guard.cjs',
line: 15,
character: 5,
});
// Step 2: Find all callers
lsp_prepareCallHierarchy({
filePath: '/abs/path/.claude/hooks/routing/routing-guard.cjs',
line: 15,
character: 5,
});
lsp_incomingCalls({
filePath: '/abs/path/.claude/hooks/routing/routing-guard.cjs',
line: 15,
character: 5,
});
// Step 3: Find what this function calls
lsp_outgoingCalls({
filePath: '/abs/path/.claude/hooks/routing/routing-guard.cjs',
line: 15,
character: 5,
});
Pattern: goToDefinition (anchor) → prepareCallHierarchy → incomingCalls (who calls me?) → outgoingCalls (what do I call?).
QA agent checks types without running full test suite:
// After a code change, verify types across affected files
// Step 1: Get all symbols in the changed file
lsp_documentSymbol({ filePath: '/abs/path/src/middleware/auth.ts', line: 1, character: 1 });
// Step 2: For each exported symbol, check references still resolve
lsp_findReferences({ filePath: '/abs/path/src/middleware/auth.ts', line: 10, character: 15 });
// Step 3: Hover over key interfaces to verify type contracts
lsp_hover({ filePath: '/abs/path/src/middleware/auth.ts', line: 5, character: 20 });
Pattern: documentSymbol (what changed?) → findReferences (who's affected?) → hover (do types still match?).
Reflection agent verifies agent claims:
// Agent claimed it called `validateToken(token: string)` but review suggests wrong signature
// Step 1: Check actual type
lsp_hover({ filePath: '/abs/path/src/auth/validate.ts', line: 12, character: 10 });
// If hover shows `validateToken(token: JWTPayload)` not `string`, agent hallucinated
// Step 2: Check if the parameter type was changed recently
lsp_findReferences({ filePath: '/abs/path/src/auth/validate.ts', line: 12, character: 25 });
Pattern: hover (ground-truth type check) → findReferences (impact of the actual signature).
Use documentSymbol → findReferences as an automated sweep to detect exported symbols
with zero external references. This pattern powers the lsp-diagnostics-runner.cjs script.
// Step 1: List all symbols in the file
lsp_documentSymbol({
filePath: '/abs/path/.claude/lib/memory/memory-manager.cjs',
line: 1,
character: 1,
});
// Step 2: For each exported symbol, check for external references
lsp_findReferences({
filePath: '/abs/path/.claude/lib/memory/memory-manager.cjs',
line: 42,
character: 15,
});
// If results contain only the defining file → potential dead export
Automated script: .claude/tools/cli/lsp-diagnostics-runner.cjs implements this pattern
using ripgrep as a fallback (since LSP has limited CJS support — see Anti-Patterns table).
# Run dead-exports check on all lib files
node .claude/tools/cli/lsp-diagnostics-runner.cjs --check dead-exports --format markdown
# Exclude archived directories
node .claude/tools/cli/lsp-diagnostics-runner.cjs --check dead-exports --exclude-pattern "_archive"
Note on hook exports (false positives): Hook files (.claude/hooks/**) export functions
for testability but are invoked via stdin/stdout protocol, not require(). Their exports
appear as dead code because test suites use dynamic require; the diagnostics runner
marks hook export findings as LOW severity for this reason.
Verify that hooks registered in .claude/settings.json exist on disk and their internal
require() chains resolve without errors.
// Step 1: Locate the hook registration in settings.json
// (use ripgrep — LSP won't index JSON well for CJS references)
// rg "routing-guard" .claude/settings.json
// Step 2: Confirm the hook file exists and resolves its imports
lsp_goToDefinition({
filePath: '/abs/path/.claude/hooks/routing/routing-guard.cjs',
line: 1,
character: 1,
});
// Step 3: Check the exports the hook provides (for testability audit)
lsp_documentSymbol({
filePath: '/abs/path/.claude/hooks/routing/routing-guard.cjs',
line: 1,
character: 1,
});
Hybrid approach (more reliable for .cjs files): Combine ripgrep for settings.json
registration lookup with require.resolve() for import chain validation:
# Find all registered hooks
node -e "const s = require('./.claude/settings.json'); console.log(JSON.stringify(s.hooks, null, 2))"
# Verify a hook's require chain resolves
node -e "require('./.claude/hooks/routing/routing-guard.cjs'); console.log('OK')"
Script: .claude/tools/cli/lsp-diagnostics-runner.cjs
An automated scanner that finds dead code, broken imports, and unreferenced functions using
ripgrep + require.resolve(). Use this instead of manual LSP calls for bulk analysis of
.cjs CommonJS files (where native LSP has limited support).
# Find exported symbols that nobody imports (dead code)
node .claude/tools/cli/lsp-diagnostics-runner.cjs --check dead-exports
# Find require() calls that don't resolve (broken imports)
node .claude/tools/cli/lsp-diagnostics-runner.cjs --check broken-imports
# Run both checks, exclude archived code
node .claude/tools/cli/lsp-diagnostics-runner.cjs --check dead-exports --check broken-imports --exclude-pattern "_archive"
# Target specific directories
node .claude/tools/cli/lsp-diagnostics-runner.cjs --check dead-exports --glob ".claude/lib/routing/*.cjs"
node .claude/tools/cli/lsp-diagnostics-runner.cjs --check dead-exports --glob ".claude/hooks/**/*.cjs"
# Output as markdown (for reports)
node .claude/tools/cli/lsp-diagnostics-runner.cjs --check dead-exports --format markdown --output report.md
| Flag | Default | Description |
|---|---|---|
--check <type> | (required) | dead-exports, broken-imports, or unreferenced-functions (repeatable) |
--glob <pattern> | .claude/lib/**/*.cjs | File glob pattern to scan |
--exclude-pattern <pat> | (none) | Exclude files matching pattern (e.g., _archive) |
--format <fmt> | table | Output format: table, json, or markdown |
--output <file> | (stdout) | Write results to file |
| Severity | Meaning |
|---|---|
| HIGH | Broken import (require doesn't resolve) — likely runtime error |
| MEDIUM | Dead export in non-hook file — probably unused code |
| LOW | Dead export in hook file — expected (hooks export for testing) |
Hook files (.claude/hooks/**) export functions for testability but are invoked via
stdin/stdout JSON protocol, not require(). Their exports always appear as "dead"
because no production code imports them — only test files do. The runner marks these
as LOW severity automatically. Do not treat hook dead-exports as bugs.
// Invoke as a skill for guidance, then use native LSP tool directly
Skill({ skill: 'lsp-navigator' });
// Then call LSP operations natively:
// lsp_goToDefinition({ filePath, line, character })
// lsp_findReferences({ filePath, line, character })
// lsp_hover({ filePath, line, character })
// lsp_documentSymbol({ filePath, line, character })
// lsp_workspaceSymbol({ filePath, line, character })
// lsp_goToImplementation({ filePath, line, character })
// lsp_prepareCallHierarchy({ filePath, line, character })
// lsp_incomingCalls({ filePath, line, character })
// lsp_outgoingCalls({ filePath, line, character })
</instructions>
Use lsp-navigator to self-correct after edits:
Use lsp-navigator for lightweight static analysis:
Use lsp-navigator to improve review accuracy:
Use lsp-navigator for architectural analysis:
Use lsp-navigator for safe refactoring:
Use lsp-navigator for root cause analysis:
Use lsp-navigator to verify agent claims:
Use lsp-navigator to trace data flows:
Input validated against schemas/input.schema.json before execution.
Output contract defined in schemas/output.schema.json.
Pre-execute hook: hooks/pre-execute.cjs validates filePath is absolute and line/character are positive integers before invoking any LSP operation.
prepareCallHierarchy before incomingCalls/outgoingCalls — the call hierarchy operations require a prepared item from prepareCallHierarchy at the target position.| Anti-Pattern | Why It Fails | Correct Approach |
|---|---|---|
| Using LSP to "search for" a concept | LSP needs a position, not a query | Use search:code for discovery, then LSP for navigation |
| Relative file paths | LSP resolves against workspace root; may hit wrong file | Always use absolute paths |
| 0-based line numbers | Off-by-one errors; navigates to wrong symbol | LSP is 1-based for both line and character |
| Skipping prepareCallHierarchy | incomingCalls/outgoingCalls need a prepared item | Always call prepareCallHierarchy first |
| Using LSP instead of rg for text-in-comments | LSP only sees code symbols, not text in comments/strings | Use ripgrep for text that includes non-code content |
| Trusting empty LSP results as "no references" | Language server may not be running or file may not be indexed | Verify LSP is active; fall back to ripgrep if empty |
| Using LSP on .cjs CommonJS files expecting TypeScript types | CJS files may have limited LSP support depending on workspace config | Fall back to ripgrep or structural search for .cjs files |
In practice, most LSP operations (goToDefinition, findReferences, hover) return empty
results for .cjs CommonJS files in this workspace. The TypeScript language server does not
fully index CJS modules without explicit jsconfig.json or tsconfig.json coverage.
What this means:
.cjs files: prefer ripgrep (rg -F) for reference counting and require.resolve() for import validation.documentSymbol may work on .cjs files for listing top-level exports, but is unreliable.require.resolve()) proved more effective than LSP for the agent-studio codebase's .cjs hook and lib files.Recommendation: Use LSP as the primary tool for .ts and .js (ESM) files. For .cjs files,
treat LSP as a secondary option and fall back to ripgrep immediately if LSP returns empty results.
On Windows, path.relative() and other Node.js path utilities return backslash (\) separators
instead of forward slashes. LSP operations and file path comparisons expect forward-slash paths.
Rules for Windows compatibility:
filePath.replace(/\\/g, '/')lsp-diagnostics-runner.cjs) handles this via its normalizePath() utility[^/\\]* in regex patterns if path normalization is uncertainpath.relative() output directly in regex or glob patterns without normalizingExample:
// WRONG: path.relative() returns backslashes on Windows
const relPath = path.relative(projectRoot, filePath); // ".claude\\lib\\routing.cjs"
// CORRECT: normalize before use
const relPath = path.relative(projectRoot, filePath).replace(/\\/g, '/');
// ".claude/lib/routing.cjs"
This is Sharp Edge SE-01 in the codebase. See .claude/rules/safety-rules.md for full details.
Before starting:
Read .claude/context/memory/learnings.md
After completing:
.claude/context/memory/learnings.md.claude/context/memory/issues.md.claude/context/memory/decisions.mdASSUME INTERRUPTION: If it's not in memory, it didn't happen.
| Language | Server | Install |
|---|---|---|
| C/C++ | clangd | apt install clangd / brew install llvm |
| Go | gopls | go install golang.org/x/tools/gopls@latest |
| Python | pyright | npm i -g pyright |
| Rust | rust-analyzer | rustup component add rust-analyzer |
| Java | jdtls | brew install jdtls / Eclipse JDT LS release |
| TS/JS | typescript-language-server | npm i -g typescript-language-server |
| Lua | lua-language-server | brew install lua-language-server |
| Bash | bashls | npm i -g bash-language-server |
| JSON | jsonls | npm i -g vscode-langservers-extracted |
| YAML | yamlls | npm i -g yaml-language-server |
| TOML | taplo | cargo install taplo-cli |
| Markdown | marksman | brew install marksman / GitHub releases |
Note: Claude Code activates these automatically when installed — no manual start required.
LSP for .cjs files remains unreliable; use ripgrep as primary for CommonJS files.
Auto-enable LSP server selection via a PostToolUse(Read) hook:
// .claude/hooks/lsp-enable.cjs
'use strict';
const path = require('path');
const input = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8'));
const filePath = input?.tool_input?.file_path || '';
const ext = path.extname(filePath);
const serverMap = {
'.py': 'pyright',
'.rs': 'rust-analyzer',
'.go': 'gopls',
'.ts': 'typescript-language-server',
'.js': 'typescript-language-server',
'.lua': 'lua-language-server',
'.sh': 'bashls',
};
const server = serverMap[ext];
if (server) {
process.stdout.write(JSON.stringify({ lspServer: server }));
}
process.exit(0);
Register in .claude/settings.json:
{ "event": "PostToolUse", "tool": "Read", "command": "node .claude/hooks/lsp-enable.cjs" }
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Ensure accessibility in UI components including semantic HTML, ARIA attributes, keyboard navigation, and WCAG 2.2 AA compliance.
日本語の概要は準備中です。原文の説明を表示しています。
Use when you want to improve response quality through meta-cognitive reasoning. Applies 15+ reasoning methods to reconsider and refine initial outputs.
日本語の概要は準備中です。原文の説明を表示しています。
N-round opposing-stance debates for trade-off analysis. Assigns pro/con roles to agents, runs structured debate rounds with quality scoring, and produces a moderator synthesis with confidence-rated recommendation. Generalizable to architecture, technology, security, and design decisions.
日本語の概要は準備中です。原文の説明を表示しています。
Force adversarial code review stance that eliminates confirmation bias — reviewer must find issues or re-analyze
日本語の概要は準備中です。原文の説明を表示しています。
Creates specialized AI agents on-demand when no existing agent matches a request. Use when the Router cannot find a suitable agent for a task. Enables self-evolution by generating persistent agents.
日本語の概要は準備中です。原文の説明を表示しています。
LLM-as-judge evaluation framework with 5-dimension rubric (accuracy, groundedness, coherence, completeness, helpfulness) for scoring AI-generated content quality with weighted composite scores and evidence citations
日本語の概要は準備中です。原文の説明を表示しています。