[PR #13332] feat(lsp): non-blocking initialization + configurable diagnostics timeout #14620

Open
opened 2026-02-16 18:19:24 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/13332

State: open
Merged: No


What does this PR do?

On large projects (Android monorepo with kotlin-lsp), getClients() blocks 45+ seconds waiting for LSP init, which causes timeouts and makes the editor unusable during startup. The 3s diagnostics timeout is also too short for heavy language servers like ESLint.

This PR does two things:

  1. Makes getClients() non-blocking — changes the return type from Promise<LSPClient.Info[]> to LSPClient.Info[]. Returns immediately with whatever clients are ready (or [] during init), spawns servers in the background, and notifies via Bus.publish(Event.Updated) when new clients come online. The editor stays responsive from the first keystroke.

  2. Makes diagnostics timeout configurable — adds OPENCODE_EXPERIMENTAL_LSP_DIAGNOSTICS_TIMEOUT_MS flag (default bumped from 3s to 10s). Uses the existing number() helper and follows the same pattern as OPENCODE_EXPERIMENTAL_BASH_DEFAULT_TIMEOUT_MS.

Fixes #13328
Related: #7477, #13272, #13154

Files changed:

  • packages/opencode/src/lsp/index.ts — non-blocking getClients()
  • packages/opencode/src/lsp/index.test.ts — 6 tests for non-blocking behavior
  • packages/opencode/src/flag/flag.ts — new OPENCODE_EXPERIMENTAL_LSP_DIAGNOSTICS_TIMEOUT_MS flag
  • packages/opencode/src/lsp/client.ts — uses configurable timeout instead of hardcoded 3s
  • packages/opencode/src/lsp/client.test.ts — 3 tests for timeout configuration

How did you verify your code works?

  • 9 new tests (6 for non-blocking init, 3 for configurable timeout)
  • Full suite: 935 pass, 5 skip, 0 fail
  • Typecheck: 12/12 packages pass
  • Manually tested with kotlin-lsp on an Android monorepo — editor loads instantly, LSP features appear as servers become ready
**Original Pull Request:** https://github.com/anomalyco/opencode/pull/13332 **State:** open **Merged:** No --- ### What does this PR do? On large projects (Android monorepo with `kotlin-lsp`), `getClients()` blocks 45+ seconds waiting for LSP init, which causes timeouts and makes the editor unusable during startup. The 3s diagnostics timeout is also too short for heavy language servers like ESLint. This PR does two things: 1. **Makes `getClients()` non-blocking** — changes the return type from `Promise<LSPClient.Info[]>` to `LSPClient.Info[]`. Returns immediately with whatever clients are ready (or `[]` during init), spawns servers in the background, and notifies via `Bus.publish(Event.Updated)` when new clients come online. The editor stays responsive from the first keystroke. 2. **Makes diagnostics timeout configurable** — adds `OPENCODE_EXPERIMENTAL_LSP_DIAGNOSTICS_TIMEOUT_MS` flag (default bumped from 3s to 10s). Uses the existing `number()` helper and follows the same pattern as `OPENCODE_EXPERIMENTAL_BASH_DEFAULT_TIMEOUT_MS`. Fixes #13328 Related: #7477, #13272, #13154 **Files changed:** - `packages/opencode/src/lsp/index.ts` — non-blocking `getClients()` - `packages/opencode/src/lsp/index.test.ts` — 6 tests for non-blocking behavior - `packages/opencode/src/flag/flag.ts` — new `OPENCODE_EXPERIMENTAL_LSP_DIAGNOSTICS_TIMEOUT_MS` flag - `packages/opencode/src/lsp/client.ts` — uses configurable timeout instead of hardcoded 3s - `packages/opencode/src/lsp/client.test.ts` — 3 tests for timeout configuration ### How did you verify your code works? - 9 new tests (6 for non-blocking init, 3 for configurable timeout) - Full suite: 935 pass, 5 skip, 0 fail - Typecheck: 12/12 packages pass - Manually tested with `kotlin-lsp` on an Android monorepo — editor loads instantly, LSP features appear as servers become ready
yindo added the pull-request label 2026-02-16 18:19:24 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#14620