feat: Add LS startup indicator

Description

Follow-up to !3180 (merged) which introduced LanguageServerStartupMonitor with phase tracking and detailed startup logging.

This MR adds a status bar indicator that surfaces Language Server startup progress and failures directly in the VS Code UI, so users don't need to open the Output channel to understand what's happening.

Behaviour

The indicator is debounced - it only appears if startup takes longer than 2s, so fast startups show nothing and there is no flicker.

Phase Status bar Tooltip
Spawning (>2s) $(loading~spin) GitLab: Starting Language Server... Waiting for Language Server process to start
Handshake (>2s) $(loading~spin) GitLab: Starting Language Server... LSP initialize handshake in progress
Running $(check) GitLab: Language Server started Language Server started successfully
Failed $(error) GitLab: Language Server failed to start Language Server failed to start. Try to restart the GitLab extension.

On success, the indicator shows the $(check) state for 3s before disappearing. On failure it stays visible permanently and handleError surfaces the error message as a VS Code notification.

References #2269 (closed)

How has this been tested?

Scenario 1 - Happy path (fast startup)

Run npm run build:desktop, run extension in development host.

If startup completes in under 2s, nothing appears in the status bar - no flicker.

Scenario 2 - Happy path (slow startup)

If startup takes longer than 2s, observe the status bar (bottom of the VS Code window): In the LS, delay initialize handler by more than 2 seconds. Add:

await new Promise((resolve) => setTimeout(resolve, 10000));

Link the updated LS in the extension running bun run watch -- --editor=vscode.

  1. $(loading~spin) GitLab: Starting Language Server... appears with tooltip Waiting for Language Server process to start
  2. Tooltip updates to LSP initialize handshake in progress once the handshake begins
  3. $(check) GitLab: Language Server started shows for 3s
  4. Item disappears

2026-05-05_22.25.49

Scenario 3 - Spawn failure

Remove LS js bundle in dist-desktop/assets/language-server/main-bundle-node.js, run extension (without build).

The status bar shows $(error) GitLab: Language Server failed to start and a VS Code error notification appears.

Rebuild after.

2026-05-05_22.32.47

Scenario 4 - Handshake timeout (process spawns but LSP initialize hangs)

In the LS, delay initialize handler by more than 30 seconds. Add:

await new Promise((resolve) => setTimeout(resolve, 35000));

Link the updated LS in the extension running bun run watch -- --editor=vscode.

After 2s the spinner appears in the status bar. After 30s the status bar shows $(error) GitLab: Language Server failed to start and an error notification fires.

  • If src/browser or src/common has been modified, please consider interoperability with the Web IDE. See Running the Extension in WebIDE.
  • Consider an end-to-end test for significant new features that aren't covered by integration tests.

Screenshots (if appropriate)

What CHANGELOG entry will this MR create?

  • fix: Bug fix fixes - a user-facing issue in production - included in changelog
  • feature: New feature - a user-facing change which adds functionality - included in changelog
  • BREAKING CHANGE: (fix or feature that would cause existing functionality to change) - should bump major version, mentioned in the changelog
  • None - other non-user-facing changes
Edited by Olena Horal-Koretska

Merge request reports

Loading
Loading