diff --git a/skills/lsp-setup/SKILL.md b/skills/lsp-setup/SKILL.md new file mode 100644 index 00000000..cfbcc08c --- /dev/null +++ b/skills/lsp-setup/SKILL.md @@ -0,0 +1,69 @@ +--- +name: lsp-setup +description: 'Install and configure LSP servers for any programming language to work with GitHub Copilot CLI. Detects the OS, installs the right LSP server, and generates the LSP configuration (user-level or repo-level). Say "setup LSP" to start.' +--- + +# LSP Setup for GitHub Copilot CLI + +**UTILITY SKILL** — installs and configures Language Server Protocol servers for Copilot CLI. +USE FOR: "setup LSP", "install language server", "configure LSP for Java", "add TypeScript LSP", "enable code intelligence" +DO NOT USE FOR: general coding tasks, IDE/editor LSP configuration, non-Copilot-CLI setups + +## Workflow + +1. **Ask the language** — use `ask_user` to ask which programming language(s) the user wants LSP support for +2. **Detect the OS** — run `uname -s` (or check for Windows via `$env:OS` / `%OS%`) to determine macOS, Linux, or Windows +3. **Look up the LSP server** — read `references/lsp-servers.md` for known servers, install commands, and config snippets +4. **Ask scope** — use `ask_user` to ask whether the config should be user-level (`~/.copilot/lsp-config.json`) or repo-level (`.github/lsp.json`) +5. **Install the server** — run the appropriate install command for the detected OS +6. **Write the config** — merge the new server entry into the chosen config file (`~/.copilot/lsp-config.json` for user-level, `.github/lsp.json` for repo-level); create it if missing, preserve existing entries +7. **Verify** — confirm the LSP binary is on `$PATH` and the config file is valid JSON + +## Configuration Format + +Copilot CLI reads LSP configuration from two locations (repo-level takes precedence): + +- **User-level**: `~/.copilot/lsp-config.json` +- **Repo-level**: `.github/lsp.json` + +The JSON structure: + +```json +{ + "lspServers": { + "": { + "command": "", + "args": ["--stdio"], + "fileExtensions": { + ".": "", + ".": "" + } + } + } +} +``` + +### Key rules + +- `command` is the binary name (must be on `$PATH`) or an absolute path. +- `args` almost always includes `"--stdio"` to use standard I/O transport. +- `fileExtensions` maps each file extension (with leading dot) to a [Language ID](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers). +- Multiple servers can coexist in `lspServers`. +- When merging into an existing file, **never overwrite** other server entries — only add or update the target language key. + +## Behavior + +- Always use `ask_user` with `choices` when asking the user to pick a language or scope. +- If the language is not listed in `references/lsp-servers.md`, search the web for " LSP server" and guide the user through manual configuration. +- If a package manager is not available (e.g. no Homebrew on macOS), suggest alternative install methods from the reference file. +- After installation, run `which ` (or `where.exe` on Windows) to confirm the binary is accessible. +- Show the user the final config JSON before writing it. +- If the config file already exists, read it first and merge — do not clobber. + +## Verification + +After setup, tell the user: + +1. Launch `copilot` in a project with files of the configured language +2. Run `/lsp` to check the server status +3. Try code intelligence features like go-to-definition or hover diff --git a/skills/lsp-setup/references/lsp-servers.md b/skills/lsp-setup/references/lsp-servers.md new file mode 100644 index 00000000..26411ac6 --- /dev/null +++ b/skills/lsp-setup/references/lsp-servers.md @@ -0,0 +1,426 @@ +# Known LSP Servers for Copilot CLI + +Reference data for the `lsp-setup` skill. Each section contains install commands per OS and a ready-to-use config snippet. + +> **Config snippet format**: Each snippet below shows the object to insert as a value under the top-level `lspServers` key. A complete config file looks like: `{ "lspServers": { } }`. When adding multiple languages, merge their snippets as sibling keys under `lspServers`. + +--- + +## TypeScript / JavaScript + +**Server**: [typescript-language-server](https://github.com/typescript-language-server/typescript-language-server) + +### Install + +| OS | Command | +|---------|-------------------------------------------------------| +| Any | `npm install -g typescript typescript-language-server` | + +### Config snippet + +```json +{ + "typescript": { + "command": "typescript-language-server", + "args": ["--stdio"], + "fileExtensions": { + ".ts": "typescript", + ".tsx": "typescriptreact", + ".js": "javascript", + ".jsx": "javascriptreact" + } + } +} +``` + +--- + +## Java + +**Server**: [Eclipse JDT Language Server (jdtls)](https://github.com/eclipse-jdtls/eclipse.jdt.ls) + +Requires **Java 21+** on `JAVA_HOME` or `$PATH`. + +### Install + +| OS | Command | +|---------|-----------------------------------| +| macOS | `brew install jdtls` | +| Linux | Check distro repos for `jdtls` or `eclipse.jdt.ls`; alternatively download from https://download.eclipse.org/jdtls/milestones/ | +| Windows | Download from https://download.eclipse.org/jdtls/milestones/ and add `bin/` to `PATH` | + +On macOS with Homebrew, the binary is installed as `jdtls` on `$PATH`. + +### Config snippet + +```json +{ + "java": { + "command": "jdtls", + "args": [], + "fileExtensions": { + ".java": "java" + } + } +} +``` + +> **Note**: The `jdtls` wrapper script handles `--stdio` mode internally. If using a manual install, you may need to invoke the launcher jar directly — see the [jdtls README](https://github.com/eclipse-jdtls/eclipse.jdt.ls#running-from-command-line-with-wrapper-script) for details. + +--- + +## Python + +**Server**: [pylsp (python-lsp-server)](https://github.com/python-lsp/python-lsp-server) + +### Install + +| OS | Command | +|---------|----------------------------------------| +| Any | `pip install python-lsp-server` | +| macOS | `brew install python-lsp-server` | + +### Config snippet + +```json +{ + "python": { + "command": "pylsp", + "args": [], + "fileExtensions": { + ".py": "python" + } + } +} +``` + +### Alternative: Pyright + +**Server**: [pyright](https://github.com/microsoft/pyright) (via [basedpyright](https://github.com/DetachHead/basedpyright) or [pyright](https://www.npmjs.com/package/pyright)) + +| OS | Command | +|---------|----------------------------------------------------| +| Any | `npm install -g pyright` | +| Any | `pip install basedpyright` (for basedpyright fork) | + +```json +{ + "python": { + "command": "pyright-langserver", + "args": ["--stdio"], + "fileExtensions": { + ".py": "python" + } + } +} +``` + +--- + +## Go + +**Server**: [gopls](https://github.com/golang/tools/tree/master/gopls) + +### Install + +| OS | Command | +|---------|--------------------------------------------| +| Any | `go install golang.org/x/tools/gopls@latest` | +| macOS | `brew install gopls` | + +### Config snippet + +```json +{ + "go": { + "command": "gopls", + "args": ["serve"], + "fileExtensions": { + ".go": "go" + } + } +} +``` + +--- + +## Rust + +**Server**: [rust-analyzer](https://github.com/rust-lang/rust-analyzer) + +### Install + +| OS | Command | +|---------|--------------------------------| +| Any | `rustup component add rust-analyzer` | +| macOS | `brew install rust-analyzer` | +| Linux | Distribution package or `rustup` | +| Windows | `rustup component add rust-analyzer` or download from GitHub releases | + +### Config snippet + +```json +{ + "rust": { + "command": "rust-analyzer", + "args": [], + "fileExtensions": { + ".rs": "rust" + } + } +} +``` + +--- + +## C / C++ + +**Server**: [clangd](https://clangd.llvm.org/) + +### Install + +| OS | Command | +|---------|----------------------------------------| +| macOS | `brew install llvm` (clangd included) or Xcode command line tools | +| Linux | `apt install clangd` / `dnf install clang-tools-extra` | +| Windows | Download LLVM from https://releases.llvm.org/ | + +### Config snippet + +```json +{ + "cpp": { + "command": "clangd", + "args": ["--background-index"], + "fileExtensions": { + ".c": "c", + ".h": "c", + ".cpp": "cpp", + ".cxx": "cpp", + ".cc": "cpp", + ".hpp": "cpp", + ".hxx": "cpp" + } + } +} +``` + +--- + +## C# (.NET) + +**Server**: [OmniSharp](https://github.com/OmniSharp/omnisharp-roslyn) or [csharp-ls](https://github.com/razzmatazz/csharp-language-server) + +### Install (csharp-ls) + +| OS | Command | +|---------|-------------------------------------------------| +| Any | `dotnet tool install --global csharp-ls` | + +### Config snippet + +```json +{ + "csharp": { + "command": "csharp-ls", + "args": [], + "fileExtensions": { + ".cs": "csharp" + } + } +} +``` + +--- + +## Ruby + +**Server**: [solargraph](https://github.com/castwide/solargraph) + +### Install + +| OS | Command | +|---------|---------------------------| +| Any | `gem install solargraph` | + +### Config snippet + +```json +{ + "ruby": { + "command": "solargraph", + "args": ["stdio"], + "fileExtensions": { + ".rb": "ruby", + ".rake": "ruby", + ".gemspec": "ruby" + } + } +} +``` + +--- + +## PHP + +**Server**: [intelephense](https://github.com/bmewburn/vscode-intelephense) + +### Install + +| OS | Command | +|---------|--------------------------------------------| +| Any | `npm install -g intelephense` | + +### Config snippet + +```json +{ + "php": { + "command": "intelephense", + "args": ["--stdio"], + "fileExtensions": { + ".php": "php" + } + } +} +``` + +--- + +## Kotlin + +**Server**: [kotlin-language-server](https://github.com/fwcd/kotlin-language-server) + +### Install + +| OS | Command | +|---------|---------------------------------------------------| +| macOS | `brew install kotlin-language-server` | +| Any | Download from GitHub releases and add to `PATH` | + +### Config snippet + +```json +{ + "kotlin": { + "command": "kotlin-language-server", + "args": [], + "fileExtensions": { + ".kt": "kotlin", + ".kts": "kotlin" + } + } +} +``` + +--- + +## Swift + +**Server**: [sourcekit-lsp](https://github.com/swiftlang/sourcekit-lsp) (bundled with Swift toolchain) + +### Install + +| OS | Command | +|---------|----------------------------------------------------------------| +| macOS | Included with Xcode; binary at `xcrun sourcekit-lsp` | +| Linux | Included with Swift toolchain; install from https://swift.org | + +### Config snippet + +```json +{ + "swift": { + "command": "sourcekit-lsp", + "args": [], + "fileExtensions": { + ".swift": "swift" + } + } +} +``` + +> On macOS you may need to use the full path: `/usr/bin/sourcekit-lsp` or set `command` to `xcrun` with `args: ["sourcekit-lsp"]`. + +--- + +## Lua + +**Server**: [lua-language-server](https://github.com/LuaLS/lua-language-server) + +### Install + +| OS | Command | +|---------|--------------------------------------| +| macOS | `brew install lua-language-server` | +| Linux | Download from GitHub releases | +| Windows | Download from GitHub releases | + +### Config snippet + +```json +{ + "lua": { + "command": "lua-language-server", + "args": [], + "fileExtensions": { + ".lua": "lua" + } + } +} +``` + +--- + +## YAML + +**Server**: [yaml-language-server](https://github.com/redhat-developer/yaml-language-server) + +### Install + +| OS | Command | +|---------|----------------------------------------------| +| Any | `npm install -g yaml-language-server` | + +### Config snippet + +```json +{ + "yaml": { + "command": "yaml-language-server", + "args": ["--stdio"], + "fileExtensions": { + ".yaml": "yaml", + ".yml": "yaml" + } + } +} +``` + +--- + +## Bash / Shell + +**Server**: [bash-language-server](https://github.com/bash-lsp/bash-language-server) + +### Install + +| OS | Command | +|---------|-----------------------------------------------| +| Any | `npm install -g bash-language-server` | + +### Config snippet + +```json +{ + "bash": { + "command": "bash-language-server", + "args": ["start"], + "fileExtensions": { + ".sh": "shellscript", + ".bash": "shellscript", + ".zsh": "shellscript" + } + } +} +```