magi-code 0.77.1

Repository-aware CLI coding agent for terminal work
Documentation
# LSP diagnostics

[Feature docs index](README.md) · [Repository README](../../README.md)

## Overview

LSP diagnostics are an opt-in live feedback loop for coding sessions. After successful `write` or `hash_edit`, magi-code can sync the changed file to a language server, wait briefly for fresh diagnostics, and append a capped `DIAGNOSTICS` block to the same tool result.

This creates a faster edit → instant truth loop for syntax, type, and compiler-style feedback. It complements normal project checks; it does not replace `cargo check`, tests, linters, or repository-specific verification.

## Enablement and settings

LSP is disabled by default. Enable it in non-secret `settings.json` only when the needed language servers are installed on `PATH`.

```json
{
  "capabilities": { "lsp": {
    "enabled": true,
    "inject_diagnostics_on_edit": true,
    "diagnostics_wait_ms": 2000,
    "idle_shutdown_minutes": 10,
    "servers": {
      "rust-analyzer": { "command": "rust-analyzer", "args": [] },
      "typescript-language-server": { "command": "typescript-language-server", "args": ["--stdio"] }
    }
  }
} }
```

Fields:

| Field | Behavior |
| --- | --- |
| `enabled` | Starts LSP support for the session. Default `false`; disabled mode spawns no language servers and injects no diagnostics. |
| `inject_diagnostics_on_edit` | When `true`, successful `write` and `hash_edit` calls can append fresh diagnostics to tool output. Default `true` when LSP is enabled. |
| `diagnostics_wait_ms` | Total edit-injection LSP budget, including cold spawn, initialize, sync, and diagnostic wait. Default `2000`; max `30000`. |
| `idle_shutdown_minutes` | Idle server shutdown window. Default `10`; max `240`. |
| `servers` | Optional command/args overrides for built-in server route keys. Values are direct process args, not shell-expanded. |

## Supported language defaults

Built-in routes:

| Files | Language id | Server key | Default command |
| --- | --- | --- | --- |
| `.rs` | `rust` | `rust-analyzer` | `rust-analyzer` |
| `.ts`, `.tsx` | `typescript` | `typescript-language-server` | `typescript-language-server --stdio` |
| `.js`, `.jsx` | `javascript` | `typescript-language-server` | `typescript-language-server --stdio` |
| `.py` | `python` | `pyright-langserver` | `pyright-langserver --stdio` |
| `.go` | `go` | `gopls` | `gopls` |

First release supports command/args overrides for these route keys. It does not add code actions, rename, formatting, hover, completion, semantic tokens, custom extension routing, or multi-root workspaces.

## Edit injection behavior

Injection runs only after successful `write` or `hash_edit` file mutations. The changed file must be a UTF-8 text file inside the workspace root and match a supported route. Shell/external-editor changes are not watched.

When fresh diagnostics arrive before `diagnostics_wait_ms`, magi-code appends a redacted block shaped like:

```text
DIAGNOSTICS (rust-analyzer, src/example.rs):
  ERROR [E0382] line 42: borrow of moved value: `value`
  WARNING [unused_imports] line 3: unused import: `std::fmt`
  (2 shown, 0 truncated)
```

Injected blocks show errors and warnings, omit information/hints, cap at 20 diagnostics, and cap appended text at about 2 KiB. No fresh diagnostics before the deadline means no block is appended; magi-code does not emit empty placeholders.

## Limits and caps

| Surface | Cap |
| --- | --- |
| Edit injection | 20 diagnostics and about 2 KiB appended text. |
| Edit wait | `diagnostics_wait_ms`, including spawn/init/sync/wait. |
| Server lifetime | Autonomous watchdog shutdown after `idle_shutdown_minutes` without accepted live-client use; planned idle shutdown/restart does not consume recovery budget. |

Caps keep provider-visible tool output small and deterministic.

## Degradation/failure behavior

LSP never changes edit success. Missing binaries, spawn failures, crashes, stale diagnostics, indexing delays, timeouts, unsupported file types, and disabled settings degrade by skipping injection.

Server lifecycle behavior:

- Servers spawn lazily on the first matching edit.
- Warm servers are reused within the session.
- Idle servers are stopped by the autonomous watchdog after the configured idle window and restart on the next matching edit.
- Unexpected client failures allow two recoveries after the initial attempt; the third unexpected failure disables that server for the session. Planned idle stop/restart does not change this counter.
- Edit injection stays quiet unless fresh diagnostics are available.

## Privacy/redaction boundaries

LSP output follows normal tool-output privacy rules:

- Injected diagnostics are redacted before provider-visible output or session persistence.
- Raw language-server stdout/stderr is never exposed to provider context, sessions, hooks, or docs.
- Server child processes run with filtered environment handling; provider API keys and token-shaped environment variables are not forwarded.
- Edit diagnostic injection is workspace-bound.
- `settings.json` is non-secret; do not place credentials in LSP server command args.

## Troubleshooting

Missing server:

- Confirm `capabilities.lsp.enabled=true`.
- Install the needed language server and confirm its command is on `PATH`.
- Override `capabilities.lsp.servers.<server>.command` and `args` only when the default command differs.

Indexing delay:

- Some servers need time to index project metadata before returning useful diagnostics.
- Increase `diagnostics_wait_ms` only if slower edit results are acceptable.
- Run normal project checks when LSP output is incomplete or stale.

Stale diagnostics:

- Edit injection requires fresh diagnostics for the synced file version when the server supplies versions.
- If no block appears, run another edit or use normal project checks.
- Cached diagnostics are latest-known language-server state, not final build truth.

## Related docs

- [PRD-0076: Post-Edit LSP Diagnostic Injection]../prd/0076-post-edit-lsp-diagnostic-injection.md
- [ADR-0056: Narrow Embedded LSP to Post-Edit Diagnostic Injection]../adr/0056-narrow-embedded-lsp-to-post-edit-diagnostic-injection.md
- [PRD-0071: LSP-Backed Live Diagnostics]../prd/0071-lsp-backed-live-diagnostics.md (superseded history)
- [ADR-0047: Embedded Blocking LSP Client Runtime]../adr/0047-embedded-blocking-lsp-client-runtime.md (superseded history)
- [Tools and safety model]tools-and-safety.md
- [Configuration]configuration.md

---

[Back to feature docs](README.md) · [Back to repository README](../../README.md)