feat(server): wire Server.listen() through native HttpApi listener (kill-switch)#25595
Closed
kitlangton wants to merge 2 commits into
Closed
feat(server): wire Server.listen() through native HttpApi listener (kill-switch)#25595kitlangton wants to merge 2 commits into
kitlangton wants to merge 2 commits into
Conversation
Bridge workspace-proxy WebSocket upgrades inside the Bun.serve listener so the Hono path's WorkspaceRouterMiddleware → ServerProxy.websocket flow has a native equivalent. The HttpApi handler still owns HTTP; the listener now also resolves the workspace target inline (?workspace=… or session lookup), upgrades the client connection, and bridges it to a remote WebSocket with queueing, subprotocol forwarding, and close-code propagation. This unblocks flipping Server.listen() over to the new listener but does not flip it — the Hono path remains canonical. Bun-only; node:http + ws adapter is a follow-up (TODO inline).
…ill-switch) When the effect-httpapi backend is selected, Server.listen() now delegates to HttpApiListener.listen() — a native Bun.serve listener with inline WebSocket upgrade handling — instead of routing through the Hono runtime adapter (Hono.fetch + createBunWebSocket). The Hono backend path is unchanged, and a kill-switch env var (OPENCODE_HTTPAPI_LEGACY_LISTENER) forces the effect-httpapi backend back through the Hono adapter as an escape hatch if the native listener regresses for a user. This unblocks the Hono deletion arc by giving the native listener real production traffic on dev/beta/local channels (where OPENCODE_EXPERIMENTAL_HTTPAPI defaults on) while leaving prod/latest channels on the Hono path.
Contributor
Author
|
Closing — redundant. The effect-httpapi backend already has full WS + proxy support via HttpApiProxy.websocket + workspace-routing middleware. The real fix is to swap adapter.createFetch for Effect's BunHttpServer.layer in Server.listen()'s effect-httpapi path. Replacement PR coming. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
effect-httpapibackend is selected,Server.listen()now delegates toHttpApiListener.listen()(nativeBun.serve+ inline WS upgrades) instead of routing through the Hono runtime adapter (Hono.fetch+createBunWebSocket).OPENCODE_HTTPAPI_LEGACY_LISTENERforces the effect-httpapi backend back through the Hono adapter as an escape hatch.Why now
This is step 6a of the Hono deletion arc. Stacks on top of:
Server.openapi()backed by HttpApi spec)Together those got the native listener to functional parity with the Hono path. This PR finally gives it production traffic — on
dev/beta/localinstall channels whereOPENCODE_EXPERIMENTAL_HTTPAPIalready defaults on.prod/latestchannels still go through the Hono path until the rollout is complete.Kill switch
When set, the effect-httpapi backend goes back through
adapter.create(app).runtime.listen()(i.e. Hono is wrapping the HttpApi handler again). Has no effect when the Hono backend is already selected. The flag is documented inflag.tsnext toOPENCODE_EXPERIMENTAL_HTTPAPI.What's NOT in this PR
BunHttpServer.layeris the only path that gives us Bun.serve's path-based WS upgrade hook.--honodebug flag forServer.openapi()(kept for spec diffability).Behavior diff for the native path
webHandlerwebHandlerdirectlycreateBunWebSocketBun.serve#fetch→server.upgrade(...)WorkspaceRouterMiddleware→ServerProxy.websocketresolveWorkspaceProxy→ inline bridge inhttpapi-listener.tsServer.urlmodule exportlisten({ port: 0 })fallbackstart(4096) ?? start(0)(matches existing behavior)opencode.server.backendonlyopencode.server.listener=bun-nativeTest plan
bun run typecheckclean (13/13)bun run test test/server/— 172 pass / 0 fail / 2 todo (covers the newhttpapi-listener.test.tsworkspace-proxy + PTY paths from feat(httpapi-listener): workspace-proxy WS forwarding #25594)opencode serveon a dev channel and exercise the SDK end-to-endOPENCODE_HTTPAPI_LEGACY_LISTENER=1and confirm the Hono adapter path comes back (look foropencode.server.listenerabsent from the structured log)