plugins/actually-lsp/skills/actually-lsp-doctor/SKILL.md
Diagnose and fix LSP setup for the current project's detected ecosystems (Rust, TypeScript, Ruby). Use when the SessionStart hook nudged about a missing LSP plugin, when the env isn't ready (no `bundle install`, no `cargo build`, missing server binary), when LSP calls are failing, or when the user invokes `/actually-lsp-doctor` directly. Walks the per-ecosystem state machine, reports what's missing, then runs the fix.
npx skillsauth add technicalpickles/pickled-claude-plugins actually-lsp-doctorInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Parse the user's args from the invocation:
fix as the first arg means skip the diagnostic report and jump straight to action.rust | typescript | ruby as an arg narrows focus to that ecosystem.Read .claude/actually-lsp.json in the current project root. If missing, run detection: source lib/detect.sh and lib/ecosystems.sh from the plugin root (the env var CLAUDE_PLUGIN_ROOT points there), call detect_ecosystems "$PWD", and for each detected ecosystem compute the current state per the rules in CONTEXT.md.
fix arg present)Output a per-ecosystem report. For each ecosystem:
CONTEXT.md's six states)ready ecosystems: what's needed to reach readydismissed ecosystems: note them but don't propose actionKeep tone terse. No celebration messaging.
For each ecosystem in no-lsp-plugin, server-not-runnable, or error:
no-lsp-plugin: try claude plugin install <recommended_plugin>@claude-plugins-official via Bash. The user gets a permission prompt. If denied, output the slash command form (/plugin install <recommended_plugin>@claude-plugins-official) and ask the user to run it themselves.
server-not-runnable: run env fixes per ecosystem via Bash. All env fixes auto-run; the user has implicit project consent.
cargo buildnpm installbundle install, plus gem install ruby-lsp if command -v ruby-lsp is emptyerror: surface the cached last_error from the state file. Ask the user how to proceed.
Re-run detection (same as Step 1's "if missing" path) and compute the new state per ecosystem. Hold the result in memory; don't write the state file yet. Step 5 may downgrade ready ecosystems before persistence.
The goal is to ground a ready verdict in an actual LSP response, not just env state. Env can say "server should run" while the server fails to answer queries (not indexed yet, wrong workspace root, crashed).
For each ecosystem whose computed state is ready:
Ensure the LSP tool is loaded. If it isn't available in this session, call ToolSearch with query select:LSP. If ToolSearch returns no match, skip the probe for every ecosystem and note "LSP tool unavailable in session" in the report. Do not downgrade any state. This is an environment issue, not an ecosystem failure.
Find a sample source file under $PROJECT_DIR:
find "$PROJECT_DIR" -maxdepth 4 -type f -name '*.rs' -print -quitfind "$PROJECT_DIR" -maxdepth 4 -type f \( -name '*.ts' -o -name '*.tsx' \) -print -quitfind "$PROJECT_DIR" -maxdepth 4 -type f -name '*.rb' -print -quitIf no file is found, skip the probe for this ecosystem and note "no sample file" in the report. Do not downgrade.
Call LSP documentSymbol against the sample file at line: 1, character: 1.
On error or non-array response: downgrade the ecosystem to error and set last_error to the stringified LSP response (or a short summary if the response is large). Env said the server should be runnable, so a probe failure is a real LSP failure worth surfacing on the next SessionStart.
On success: count the symbols in the response array. State stays ready. The count is for the report only; nothing extra goes into the state file.
Write the (possibly probe-updated) per-ecosystem state to .claude/actually-lsp.json using write_state from lib/state.sh. Output one status line per ecosystem:
ready with successful probe: <ecosystem>: ready (LSP: N symbols)ready with skipped probe: <ecosystem>: ready (LSP: skipped, <reason>)error from probe failure: <ecosystem>: error (LSP probe failed: <summary>)<ecosystem>: <state> plus the recovery hint from Step 2Keep tone terse. No celebration messaging.
tools
--- name: writing-for-scannability description: Use when structuring prose so readers can skim it - drafting or restructuring READMEs, docs, PR or issue bodies, design docs, RFCs, or any long-form text where a wall of prose hides the structure. Also use when explicitly asked to make something scannable or skimmable, convert prose to a list, surface a buried list, fix a wall of text, or decide whether bullets or prose fit. Strong signal: text with parallel sentence shapes, contrast markers ("that
development
Ignore actually-lsp nudges for an ecosystem in this project. Use when the user wants to silence, dismiss, or ignore the LSP setup nudges for a specific ecosystem (Rust, TypeScript, Ruby), or invokes `/actually-lsp-ignore` directly. Writes `dismissed=true` to `.claude/actually-lsp.json`. Persistent across sessions for this project only.
tools
--- name: investigating-runs description: Use whenever the user mentions a GitHub Actions / GHA run, even casually — invoke this skill before reaching for raw `gh` commands, because the bundled `gha-snapshot` helper distills `gh run view --log-failed` (a firehose) into a readable block with per-job status, failed-step log tails, and annotations. Specific triggers (any one is enough): a `github.com/.../actions/runs/...` URL; the phrase "GitHub Actions" or "GHA"; the `gh run` CLI; a failing workfl
tools
Use when querying or modifying tasks via the taskwarrior CLI - dense recipes for listing, single-field lookups, multi-task batched lookups, full-text search, and the soft description-length convention. Activates on `task list`, `task add`, `task info`, `task done`, "what's on the backlog", "find a task", or any taskwarrior interaction.