---
name: lsp-bootstrap
effort: medium
description: >
  Install, verify, and document the LSP symbol-search layer for this project.
  Detects languages (TypeScript, Python, Go, Rust, Ruby), installs the matching
  language servers (global npm install where possible, system command otherwise),
  verifies binaries are reachable on $PATH, and writes lsp.installed_servers to
  baldart.config.yml. Use when the user says /lsp-bootstrap, "install LSP",
  "set up symbol search", or after enabling features.has_lsp_layer for the
  first time. Idempotent — re-running on an already-configured project
  re-verifies and reports drift.
---

# LSP Bootstrap

Set up the LSP (Language Server Protocol) layer that lets agents and skills
search by symbol instead of by string. Without this layer, code search burns
context on textual collisions; with it, references resolve to the same symbol
**before** Claude reads any file.

## Project Context

**Reads from `baldart.config.yml`:** `features.has_lsp_layer`, `lsp.installed_servers`, `lsp.auto_verify`.
**Gated by features:** `features.has_lsp_layer` — this skill refuses to run when the flag is `false`, prompting the user to flip it via `npx baldart configure` first.
**Overlay:** loads `.baldart/overlays/lsp-bootstrap.md` if present — project-specific install commands (e.g. a system-managed pyright via uv, a non-standard gopls path).
**On missing keys:** ask the user; do not assume defaults. See `framework/agents/project-context.md` § 3.

## Effort

**Baseline:** `effort: medium` (frontmatter). **Inline override:** pass
`effort=<low|medium|high|xhigh|max>` anywhere in the invocation to scale
reasoning depth for this run — detect it once at kickoff and strip the token
before consuming user input. Level→behavior mapping, parsing contract, and
precedence caveats: `framework/agents/effort-protocol.md`.


## What This Skill Does

1. Reads `baldart.config.yml` and confirms `features.has_lsp_layer: true`.
2. Probes the cwd via `src/utils/lsp-adapters/` to detect which languages are
   present (markers: `tsconfig.json`, `pyproject.toml`, `go.mod`, `Cargo.toml`,
   `Gemfile`, plus heuristic fallbacks).
3. For each detected language:
   - **npm-global** adapters (TypeScript, Python via pyright): runs `npm install
     -g <pkg>` with user confirmation. The install is **global** on purpose —
     the consumer (Claude Code's LSP tool) spawns the server by name from
     `$PATH`, and a project-local devDep under `node_modules/.bin/` is not on
     `$PATH`, so it would never be reachable.
   - **system** adapters (Go gopls, Rust rust-analyzer, Ruby ruby-lsp): prints
     the install command for the user to run in a separate terminal. Does NOT
     execute system-level installs automatically.
4. Verifies each binary is **reachable on `$PATH` the same way the consumer
   spawns it** (`command -v <binary>`), then runs `<binary> --version` for the
   functional check. A binary present only in `node_modules/.bin` (legacy
   devDep) is reported as `installed-but-unreachable`, NOT `verified`.
5. Updates `lsp.installed_servers` in `baldart.config.yml`. Both `verified` and
   `installed-but-unreachable` servers are recorded (the latter so re-runs don't
   reinstall blindly and `baldart doctor` keeps flagging the mismatch);
   system-mode pending installs are recorded too.
6. Prints a summary table and points the user to
   `framework/agents/code-search-protocol.md` for runtime behavior.

## Workflow

1. **Refusal check.** If `features.has_lsp_layer: false` (or missing):
   ```
   This project hasn't opted in to the LSP layer yet.
   Run `npx baldart configure` and answer YES to "Enable LSP symbol-search layer?"
   then re-run /lsp-bootstrap.
   ```
   Stop here. Do not proceed.

2. **Probe.** Call the BALDART installer (internally `src/utils/lsp-installer.js`):
   ```
   node -e 'const L=require("./.framework/src/utils/lsp-installer"); console.log(JSON.stringify(new L().recommend(),null,2))'
   ```
   Show the detected languages with their `installMode`.

3. **Confirm per server.** For each recommended server, ask the user. Skip the
   ones already in `lsp.installed_servers` unless they fail verify.

4. **Install.** Run the appropriate `installCommand()`. Capture failures into a
   "Skipped" bucket — never abort the whole skill on one failure.

5. **Verify.** For each installed server, the installer first checks `$PATH`
   reachability (`command -v <binary>` — exactly how the consumer spawns it),
   then runs `verifyCommand()`. Mark each result `verified`,
   `installed-but-unreachable` (present in node_modules but not on `$PATH` —
   print the global-install fix), or `not-installed`.

6. **Persist.** Update `baldart.config.yml`:
   ```yaml
   lsp:
     installed_servers: [typescript, python]
     auto_verify: true
   ```

7. **Output.** A compact one-line status, in the project's `identity.language`
   from `baldart.config.yml` (English default). Matches the brevity of
   `/cont` rather than its specific Italian phrasing.

## Output Contract

A single short status block — never a multi-page report. Format:

```
LSP bootstrap:
  ✓ typescript-language-server (npm -g, on $PATH, verified)
  ⚠ pyright — installed but not on $PATH; run `npm install -g pyright`, then `baldart doctor`
  ⚠ gopls — run `go install golang.org/x/tools/gopls@latest`, then `baldart doctor`
  · ruby — not detected (no Gemfile)
Config updated: baldart.config.yml lsp.installed_servers = [typescript, python, go]
Next: codebase-architect will now prefer LSP find-references over Grep for symbols.
Note: the first LSP query after a cold start may under-report references until the
workspace finishes indexing — re-run the query once warm if a count looks low.
```

`verified` is reserved for binaries that resolve on `$PATH` (the consumer's
spawn path). Never report `verified` for a binary that only `npx --no-install`
can find — that is precisely the false positive this skill must not emit.

## Notes

- This skill never edits source code or installs binaries that aren't language
  servers — its only side effect is `npm install -g <lsp-package>` (global, so
  the binary is reachable on `$PATH`) and a YAML write to `baldart.config.yml`.
- For Claude Code users: in addition to the binaries, you may need to load a
  code-intelligence plugin (`/plugin` in Claude Code). That step is documented
  in the printed output when applicable, but the skill does NOT manage Claude
  Code plugins directly.
- Re-run safely. The skill diffs the current `lsp.installed_servers` against
  recommended + verified, so additions / removals / repairs are all idempotent.

## See Also

- `framework/agents/code-search-protocol.md` — runtime fallback rules
- `src/utils/lsp-adapters/` — per-language install/verify recipes
- `src/commands/configure.js` — same install flow when first enabling the flag
