.version
0.4.0
lsp-client/lsp-skill · GitHub
Semantic code analysis via LSP. Navigate code (definitions, references, implementations), search symbols, preview refactorings, and get file outlines. Use for exploring unfamiliar codebases or performing safe refactoring.
프로젝트 폴더에서 아래 명령어를 실행하고, 설치할 에이전트를 선택하세요.
npx skills add lsp-client/lsp-skill --skill lsp-code-analysis설치 명령을 직접 실행해야 적용됩니다. 지원 에이전트와 필요한 권한·라이선스는 제작자의 안내를 확인하세요.
.version0.4.0
assets/bp_template.md# Best Practice: [Title] ## When to Use [Describe the scenario/condition when this guide applies] ## Strategy [Core approach or principle] ## Workflow 1. **[Step Name]** ```bash lsp <command> ... ``` **Why**: [Brief explanation] 2. **[Step Name]** ```bash lsp <command> ... ``` **Why**: [Brief explanation] ## Tips - [Practical tip 1] - [Practical tip 2]
LICENSEMIT License Copyright (c) 2026 observerw Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
references/bp_backend.md# Best Practice Index: Backend | Scenario | Guide | |----------|-------| | Python API Investigation | [bp_backend_python.md](bp_backend_python.md) | | Database Schema Mapping | [bp_backend_db.md](bp_backend_db.md) |
references/bp_frontend.md# Best Practice Index: Frontend | Scenario | Guide | |----------|-------| | React Component Exploration | [bp_frontend_react.md](bp_frontend_react.md) | | TypeScript Type Analysis | [bp_frontend_typescript.md](bp_frontend_typescript.md) |
references/monorepo.md# Monorepo and Multi-root Workspaces ## Overview By default, the LSP tool starts servers using **automatic project root detection** based on the target file's location. In monorepo or multi-root workspace scenarios, use the `--project` parameter to analyze symbols across multiple packages or crates simultaneously. ## The `--project` Parameter ### When to Use Agents MUST use `--project <workspace_root>` **ONLY** when: 1. **Cross-package analysis is required**: Finding references or implementations across multiple crates/packages 2. **Shared symbols**: Analyzing code that is defined in one package but used in others 3. **Workspace-wide refactoring**: Renaming symbols that span multiple packages Agents MUST NOT use `--project` for single-package projects or when the target symbol is confined to one package. ### Behavior - **Purpose**: Overrides automatic root detection and forces the LSP server to initialize at the **workspace root** - **Effect**: Indexes all member packages/crates simultaneously, enabling cross-package semantic analysis - **Performance**: Slower initialization but broader analysis scope ### Syntax ```bash lsp <command> [options] --project <workspace_root_path> ``` **Parameters**: - `<workspace_root_path>`: Absolute or relative path to the workspace root (e.g., directory containing `Cargo.toml` workspace file or root `package.json`) ## Examples ### Rust Cargo Workspace ```bash # Find all usages of a shared function across the entire workspace lsp reference -L "crates/core/src/utils.rs:parse_config" --project /path/to/workspace # Find all implementations of a trait defined in a common crate lsp reference -L "crates/api/src/traits.rs:DataProvider" --impl --project /path/to/workspace # Preview rename across all workspace crates lsp rename preview new_name -L "crates/shared/src/lib.rs:old_name" --project /path/to/workspace ``` ### JavaScript/TypeScript Monorepo ```bash # Find all imports of a shared component across packages lsp reference -L "packages/ui/src/Button.tsx:Button" --project /path/to/monorepo # Find type definition used across multiple packages lsp definition -L "packages/app/src/index.ts:42@UserConfig<|>" --type --project /path/to/monorepo ```
references/refactor.md# Refactoring Guide **CRITICAL**: You MUST follow this guide before any refactoring operations. ## General Safety Rules 1. **Always preview first** - Review all changes before executing 2. **Verify the target** - Use `lsp locate --check` if uncertain 3. **Commit first** - Always have a way to revert changes ## Rename Workspace-wide symbol renaming. ```bash # Step 1: Preview all changes lsp rename preview new_name -L "models.py:OldName" # Step 2: Review the preview output, then execute lsp rename execute <rename_id> # Optional: Exclude files/directories lsp rename execute <rename_id> --exclude tests/ --exclude legacy/ ``` **You MUST preview before executing.**
scripts/update.sh#!/bin/bash
set -e
REPO="lsp-client/lsp-skill"
SKILL_NAME="lsp-code-analysis"
# Cleanup function for temporary files
cleanup() {
rm -f "$TMP_ZIP" 2>/dev/null || true
rm -rf "$TMP_DIR" 2>/dev/null || true
}
trap cleanup EXIT INT TERM
# Automatically detect skill directory (parent of scripts/)
SKILL_DIR=$(cd "$(dirname "$0")/.." && pwd)
VERSION_FILE="$SKILL_DIR/.version"
# Validate SKILL.md exists
[ -f "$SKILL_DIR/SKILL.md" ] || { echo "Error: SKILL.md not found in '$SKILL_DIR'."; exit 1; }
echo "Checking lsp-cli installation..."
uv tool install --python 3.13 lsp-cli@latest
LATEST_CLI_VERSION=$(uv tool list | grep "^lsp-cli " | awk '{print $2}' | sed 's/^v//')
CURRENT_CLI_VERSION=$(cat "$VERSION_FILE" 2>/dev/null || echo "unknown")
if [ "$LATEST_CLI_VERSION" = "$CURRENT_CLI_VERSION" ]; then
echo "✓ $SKILL_NAME is already up to date (lsp-cli version $LATEST_CLI_VERSION)."
exit 0
fi
echo "lsp-cli version mismatch ($CURRENT_CLI_VERSION -> $LATEST_CLI_VERSION). Proceeding with update..."
# Get current version from SKILL.md
CURRENT_VERSION=$(grep "^version:" "$SKILL_DIR/SKILL.md" | sed 's/^version: *//' || echo "unknown")
echo "Checking for updates for $SKILL_NAME..."
# Fetch latest release info
RELEASE_DATA=$(curl -sSL "https://api.github.com/repos/$REPO/releases/latest" 2>/dev/null || echo "")
LATEST_VERSION=$(echo "$RELEASE_DATA" | grep '"tag_name":' | head -n 1 | sed -E 's/.*"tag_name": "([^"]+)".*/\1/' || echo "")
if [ -z "$LATEST_VERSION" ]; then
echo "Warning: Could not determine latest version from GitHub."
echo "Current version: $CURRENT_VERSION"
else
echo "Current version: $CURRENT_VERSION"
echo "Latest version: $LATEST_VERSION"
# Strip leading 'v' from versions for comparison
if [ "${LATEST_VERSION#v}" = "${CURRENT_VERSION#v}" ]; then
echo "✓ $SKILL_NAME files are already at the latest version."
else
echo "Updating $SKILL_NAME to $LATEST_VERSION..."
# Download archive
DOWNLOAD_URL="https://github.com/$REPO/releases/latest/download/lsp-code-analysis.zip"
TMP_ZIP=$(mktemp)
echo "Downloading from GitHub releases..."
curl -sSL -f -o "$TMP_ZIP" "$DOWNLOAD_URL" || { echo "Error: Failed to download update."; exit 1; }
echo "Extracting to $SKILL_DIR..."
# Create temporary extraction directory
TMP_DIR=$(mktemp -d)
unzip -q "$TMP_ZIP" -d "$TMP_DIR"
# Find where SKILL.md is and copy that directory's content
SKILL_PATH=$(find "$TMP_DIR" -name "SKILL.md" -path "*/lsp-code-analysis/SKILL.md" | head -n 1)
if [ -n "$SKILL_PATH" ]; then
EXTRACTED_SKILL_DIR=$(dirname "$SKILL_PATH")
# Remove old content (except hidden files and scripts directory)
find "$SKILL_DIR" -mindepth 1 -not -name '.*' -not -name 'scripts' -exec rm -rf {} + 2>/dev/null || true
# Copy new content (including hidden files)
cp -r "$EXTRACTED_SKILL_DIR"/. "$SKILL_DIR/"
echo "✓ Successfully updated $SKILL_NAME to $LATEST_VERSION."
else
echo "Error: Could not find SKILL.md in the downloaded archive."
exit 1
fi
fi
fi
# Update .version file to match lsp-cli version
echo "$LATEST_CLI_VERSION" > "$VERSION_FILE"
echo "Setup complete! The lsp-code-analysis skill is ready."
SKILL.md--- name: lsp-code-analysis description: Semantic code analysis via LSP. Navigate code (definitions, references, implementations), search symbols, preview refactorings, and get file outlines. Use for exploring unfamiliar codebases or performing safe refactoring. license: LICENSE --- # LSP Code Analysis ## IMPORTANT: PREREQUISITE To use this skill, you **MUST** follow these steps: 1. **Check for updates**: Run the [update script](scripts/update.sh) to ensure you are using the latest version of the tool. 2. **Verify project support**: Run `lsp server start <project_path>` to start the LSP server and confirm the project is supported. **IF YOU DO NOT PERFORM THESE STEPS, YOU ARE NOT ALLOWED TO USE THIS SKILL.** ## Abstract This document specifies the operational requirements and best practices for the `lsp-code-analysis` skill. It provides a semantic interface to codebase navigation, analysis and refactoring via the Language Server Protocol (LSP). ## Overview You are provided with `lsp` CLI tool for semantic code navigation and analysis. It SHOULD be preferred over `read` or `grep` for most code understanding tasks. Usages: - **Semantic navigation**: Jump to definitions, find references, locate implementations - understands code structure, not just text patterns. - **Language-aware**: Distinguishes between variables, functions, classes, types - eliminates false positives from text search. - **Cross-file intelligence**: Trace dependencies, refactor safely across entire codebase - knows what imports what. - **Type-aware**: Get precise type information, signatures, documentation - without reading implementation code. ### Tool Selection **Guideline**: You SHOULD prioritize LSP commands for code navigation and analysis. Agents MAY use `read` or `grep` ONLY when semantic analysis is not applicable (e.g., searching for comments or literal strings). | Task | Traditional Tool | Recommended LSP Command | | ------------------- | ---------------- | ----------------------------------------------- | | **Find Definition** | `grep`, `read` | [`definition`](#definition-navigate-to-source) | | **Find Usages** | `grep -r` | [`reference`](#reference-find-all-usages) | | **Understand File** | `read` | [`outline`](#outline-file-structure) | | **View Docs/Types** | `read` | [`doc`](#doc-get-documentation) | | **Refactor** | `sed` | See [Refactoring Guide](references/refactor.md) | ## Commands All commands support `-h` or `--help`. ### Locating Symbols Most commands use a unified locating syntax via the `--scope` and `--find` options. **Arguments**: `<file_path>` **Options**: - `--scope`: Narrow search to a symbol body or line range. - `--find`: Text pattern to find within the scope. **Scope Formats**: - `<line>`: Single line number (e.g., `42`). - `<start>,<end>`: Line range (e.g., `10,20`). Use `0` for end to mean till EOF (e.g., `10,0`). - `<symbol_path>`: Symbol path with dots (e.g., `MyClass.my_method`). **Find Pattern (`--find`)**: The `--find` option narrows the target to a **text pattern within the selected scope**: - The scope is determined by `--scope` (line/range/symbol). If no `--scope` is given, the entire file is the scope. - Pattern matching is **whitespace-insensitive**: differences in spaces, tabs, and newlines are ignored. - You MAY include the cursor marker `<|>` inside the pattern to specify the **exact position of interest** within the match (for example, on a variable name, keyword, or operator). - If `--find` is omitted, the command uses the start of the scope (or a tool-specific default) as the navigation target. **Cursor Marker (`<|>`)**: The `<|>` marker indicates the exact position for symbol resolution. It represents the character immediately to its right. Use it within the find pattern to point to a specific element (e.g., `user.<|>name` to target the `name` property). **Examples**: - `lsp doc foo.py --find "self.<|>"` - Find `self.` in entire file, position at the character after the dot (typically for completion or member access) - `lsp doc foo.py --scope 42 --find "return <|>result"` - Find `return result` on line 42, position at `r` of `result` - `lsp doc foo.py --scope 10,20 --find "if <|>condition"` - Find `if condition` in lines 10-20, position at `c` of `condition` - `lsp doc foo.py --scope MyClass.my_method --find "self.<|>"` - Find `self.` within `MyClass.my_method`, position after the dot - `lsp doc foo.py --scope MyClass` - Target the `MyClass` symbol directly **Guideline for Scope vs. Find**: - Use `--scope <symbol_path>` (e.g., `--scope MyClass`, `--scope MyClass.my_method`) to target **classes, functions, or methods**. This is the most robust and preferred way to target symbol. - Use `--find` (often combined with `--scope`) to target variables or specific positions. Use this when the target is not a uniquely named symbol or when you need to pinpoint a specific usage within a code block. Agents MAY use `lsp locate <file_path> --scope <scope> --find <find>` to verify if the target exists in the file and view its context before running other commands. ```bash # Verify location exists lsp locate main.py --scope 42 --find "<|>process_data" ``` ### Pagination Use pagination for large result sets like `reference` or `search`. - `--pagination-id <ID>`: (Required) Unique session ID for consistent paging. - `--max-items <N>`: Page size. - `--start-index <N>`: Offset (0-based). **Example**: ```bash # Page 1 lsp search "User" --max-items 20 --pagination-id "task_123" # Page 2 lsp search "User" --max-items 20 --start-index 20 --pagination-id "task_123" ``` **Guideline**: Use pagination with a unique ID for common symbols to fetch results in manageable chunks. Increment `--start-index` using the same ID to browse. ### Outline: File Structure Get hierarchical symbol structure without reading implementation. ```bash # Get main symbols (classes, functions, methods) lsp outline <file_path> # Get all symbols including variables and parameters lsp outline <file_path> --all ``` Agents SHOULD use `outline` before reading files to avoid unnecessary context consumption. ### Definition: Navigate to Source Navigate to where symbols are defined. ```bash # Jump to where User.get_id is defined lsp definition models.py --scope User.get_id # Find where an imported variable comes from lsp definition main.py --scope 42 --find "<|>config" # Find declaration (e.g., header files, interface declarations) lsp definition models.py --scope 25 --mode declaration --find "<|>provider" # Find the class definition of a variable's type lsp definition models.py --scope 30 --find "<|>user" --mode type_definition ``` ### Reference: Find All Usages Find where symbols are used or implemented. ```bash # Find all places where logger is referenced lsp reference main.py --scope MyClass.run --find "<|>logger" # Find all concrete implementations of an interface/abstract class lsp reference api.py --scope "IDataProvider" --mode implementations # Get more surrounding code context for each reference lsp reference app.py --scope 10 --find "<|>my_var" --context-lines 5 # Limit results for large codebases lsp reference utils.py --find "<|>helper" --max-items 50 --start-index 0 ``` ### Doc: Get Documentation Get documentation and type information without navigating to source. ```bash # Get docstring and type info for symbol at line 42 lsp doc main.py --scope 42 # Get API documentation for process_data function lsp doc models.py --scope process_data ``` Agents SHOULD prefer `doc` over `read` when only documentation or type information is needed. ### Search: Global Symbol Search Search for symbols across the workspace when location is unknown. ```bash # Search by name (defaults to current directory) lsp search "MyClassName" # Search in specific project lsp search "UserModel" --project /path/to/project # Filter by symbol kind (can specify multiple times) lsp search "init" --kinds function --kinds method # Limit and paginate results for large codebases lsp search "Config" --max-items 10 lsp search "User" --max-items 20 --start-index 0 ``` Agents SHOULD use `--kinds` to filter results and reduce noise. ### Symbol: Get Complete Symbol Code Get the full source code of the symbol containing a location. ```bash # Get complete code of the function/class at line 15 lsp symbol main.py --scope 15 # Get full UserClass implementation lsp symbol utils.py --scope UserClass # Get complete method implementation lsp symbol models.py --scope User.validate ``` Response includes: symbol name, kind (class/function/method), range, and **complete source code**. Agents SHOULD use `symbol` to read targeted code blocks instead of using `read` on entire files. ### Refactoring Operations Read [Refactoring Guide](references/refactor.md) for rename, extract, and other safe refactoring operations. ### Server: Manage Background Servers The background manager starts automatically. Manual control is OPTIONAL. ```bash # List running servers lsp server list # Start server for a project lsp server start <path> # Stop server for a project lsp server stop <path> # Shutdown the background manager lsp server shutdown ``` ## Best Practices ### General Workflows #### Understanding Unfamiliar Code The RECOMMENDED sequence for exploring new codebases: ```bash # Step 1: Start with outline - Get file structure without reading implementation lsp outline <file_path> # Step 2: Inspect signatures - Use doc to understand API contracts lsp doc <file_path> --scope <symbol_name> # Step 3: Navigate dependencies - Follow definition chains lsp definition <file_path> --scope <symbol_name> # Step 4: Map usage - Find where code is called with reference lsp reference <file_path> --scope <symbol_name> ``` #### Debugging Unknown Behavior ```bash # Step 1: Locate symbol definition workspace-wide lsp search "<symbol_name>" # Step 2: Verify implementation details lsp definition <file_path> --scope <symbol_name> # Step 3: Trace all callers to understand invocation context lsp reference <file_path> --scope <symbol_name> ``` ### Finding Interface Implementations ```bash # Step 1: Locate interface definition lsp search "IUserService" --kinds interface # Step 2: Find all implementations lsp reference src/interfaces.py --scope IUserService --mode implementations ``` ### Tracing Data Flow ```bash # Step 1: Find where data is created lsp search UserDTO --kinds class # Step 2: Find where it's used lsp reference models.py --scope UserDTO # Step 3: Check transformations lsp doc transform.py --scope map_to_dto ``` ### Understanding Type Hierarchies ```bash # Step 1: Get class outline lsp outline models.py # Step 2: Find subclasses (references to base) lsp reference models.py --scope BaseModel # Step 3: Check type definitions lsp definition models.py --scope BaseModel --mode type_definition ``` ### Performance Tips ```bash # Use outline instead of reading entire files lsp outline large_file.py # Better than: read large_file.py # Use symbol paths for nested structures (more precise than line numbers) lsp definition models.py --scope User.Profile.validate # Limit results in large codebases lsp search "User" --max-items 20 # Use doc to understand APIs without navigating to source lsp doc api.py --scope fetch_data # Get docs/types without jumping to definition # Verify locate strings if commands fail lsp locate main.py --scope 42 --find "<|>my_var" ``` ### Domain-Specific Guides For specialized scenarios, see: - **Monorepo**: [monorepo.md](references/monorepo.md) - **Frontend**: [bp_frontend.md](references/bp_frontend.md) - **Backend**: [bp_backend.md](references/bp_backend.md)