Skip to content

Bring back async API, allow API connection to LSP process#2620

Merged
andrewbranch merged 46 commits intomicrosoft:mainfrom
andrewbranch:api
Feb 6, 2026
Merged

Bring back async API, allow API connection to LSP process#2620
andrewbranch merged 46 commits intomicrosoft:mainfrom
andrewbranch:api

Conversation

@andrewbranch
Copy link
Member

@andrewbranch andrewbranch commented Jan 30, 2026

  • Brings back the async, JSON-RPC-based API client that existed in intermediate commits of Scaffold IPC-based API #711 but was ultimately deleted.
  • Adds a proper JSON-RPC API server for said async client (rather than abusing the LSP server as the prototype in Scaffold IPC-based API #711 did).
  • The new API server stack is less tightly coupled between method handlers and transport/protocol, so now a single implementation of API handlers and session management (api.Session) can be used over either STDIO or UDS / named pipe, and communicate over either JSON-RPC or the custom sync protocol we built on top of MessagePack.
  • The LSP now supports a custom command that initializes an (async) API server listening on a UDS / named pipe. In this mode, the data backing the API server is the Snapshot owned by the LSP session. Our VS Code extension exposes a command that calls this API initialization method and returns the API connection, which will allow third party extensions and LSP servers to query TypeScript’s LSP state.

The API surface area is still early prototype quality and very incomplete; this PR doesn’t add any methods. But the infrastructure provides the beginnings of a path toward replacing TS Server plugins, and will hopefully make it less cumbersome to maintain both a sync and async version of the API. (It’s still pretty annoying in the TS client code, thanks to async function coloring in JavaScript. Possibly future codegen can help us out a little there.)

Also incidentally fixes #2630, as I needed some additional features out of the extension as I started to play with this, which were difficult to add without fixing the lifetime issues.

@andrewbranch andrewbranch marked this pull request as ready for review January 30, 2026 23:56
Copilot AI review requested due to automatic review settings January 30, 2026 23:56
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR reintroduces the async JSON-RPC-based API that was prototyped in #711 and adds infrastructure for LSP-based API connections. The implementation refactors the API server stack to support both synchronous (MessagePack) and asynchronous (JSON-RPC) protocols, allowing a single api.Session to work over either STDIO or Unix domain socket/named pipe transports.

Changes:

  • Introduces a generic jsonrpc package that extracts common JSON-RPC types from lsproto, enabling code reuse
  • Adds api.Session with protocol abstraction supporting both sync (MessagePack) and async (JSON-RPC) connections
  • Implements LSP custom command custom/initializeAPISession to expose API connections to VS Code extensions
  • Splits TypeScript API client into sync and async variants with shared base interfaces

Reviewed changes

Copilot reviewed 46 out of 48 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
internal/jsonrpc/ New package with common JSON-RPC types and base protocol handling
internal/lsproto/ Refactored to use jsonrpc types, reducing code duplication
internal/api/session.go Core API session managing requests, registries, and lifecycle
internal/api/conn_*.go Connection implementations for sync and async request handling
internal/api/protocol_*.go Protocol adapters for MessagePack and JSON-RPC
internal/api/transport*.go Platform-specific transport for pipes/sockets
internal/api/callbackfs.go Virtual filesystem with client-side callbacks
internal/lsp/server.go LSP integration for API session initialization
_packages/api/src/async/ New async TypeScript client using vscode-jsonrpc
_packages/api/src/base/ Shared types and object registry for sync/async clients
_packages/api/test/ Split tests into sync and async variants
_extension/ VS Code command to expose API connection paths

@jakebailey
Copy link
Member

It’s still pretty annoying in the TS client code, thanks to async function coloring in JavaScript. Possibly future codegen can help us out a little there.

If we wanted to be very clever, we could do what babel does and use gensync (which I am biased towards having written their types).

@andrewbranch andrewbranch requested a review from gabritto February 4, 2026 21:26
@andrewbranch
Copy link
Member Author

andrewbranch commented Feb 5, 2026

What? What version of tinybench did it install? 3.1.1 doesn't even have that many lines. How could it have installed anything else?

Edit: Jake changed it in main 😄

go 1.25

require (
github.com/Microsoft/go-winio v0.6.2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After merging, we'll need to update NOTICE (I'll do it, no worries)

@andrewbranch andrewbranch added this pull request to the merge queue Feb 6, 2026
Merged via the queue into microsoft:main with commit 8214cab Feb 6, 2026
20 checks passed
@andrewbranch andrewbranch deleted the api branch February 6, 2026 23:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multiple Language Client instances persist after TSDK switch

5 participants