feat(server): web-standard fetch handler entry - #41896
Merged
Merged
Conversation
Adds ServerFetch: the HttpApi routes exposed as a web-standard (request: Request) => Promise<Response> handler, for runtimes that hand requests to the embedder instead of letting it bind a port - workerd Workers and Durable Objects, Deno.serve, Bun.serve, test harnesses. ServerFetch.make is the Effect-native scoped constructor; create() is a thin Promise adapter with an explicit dispose for hosts without an Effect runtime. The application layer builds eagerly inside the caller's scope, before the handler exists. The lazy alternative (toWebHandlerLayerWith) builds on first request, and on workerd a first request that aborts mid-build interrupts layer construction and wedges every subsequent request (Effect-TS/effect#6319 class); a regression test pins the abort-then-serve behavior. Auth and CORS follow the Node server's exact semantics: options.password enforces Basic auth, isAllowedCorsOrigin gates origins.
kitlangton
force-pushed
the
server-fetch-handler
branch
from
August 12, 2026 01:27
d4d8d9c to
07be99f
Compare
kitlangton
enabled auto-merge (squash)
August 12, 2026 01:28
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.
What
Adds
ServerFetch.maketo@opencode-ai/server: the same HttpApi routes as the Node server process, exposed as a web-standard(request: Request) => Promise<Response>handler — no port binding, no listener ownership, no signal handlers.Destination context — who consumes this
The consumer is the embedded SDK: an
OpenCode.createthat boots the full server in-process and talks to it through this handler instead of a socket, so a Cloudflare Durable Object can host one OpenCode server per Slack thread (live today against a local branch). Follow-ups stack on this seam in order: (1) a workerd runtime profile — Shell/FileSystem/Pty service replacements for a runtime with no subprocesses; (2) an SDK./workerdentrypoint wiring profile + handler + DO-SQLite; (3) a workerd-spike test package as a CI purity guard that the server bundle stays free of node-only imports. The same entry serves Deno.serve/Bun.serve embedders and plain test harnesses. This PR is deliberately just the transport seam.Design: eager, not lazy — this is load-bearing
Effect v4 offers two converter shapes.
toWebHandlerLayerWithbuilds the application layer lazily on the first request — and on workerd, a first request that aborts mid-build interrupts layer construction and permanently wedges every subsequent request (the Effect-TS/effect#6319 failure class, independently rediscovered by alchemy's workerd deploy post-mortem).ServerFetch.maketherefore builds the layer eagerly inside the caller'sScopebefore any handler exists, andtoWebHandlerWith(context)serves requests from the pre-built context. A regression test pins abort-the-first-request-then-serve.Parity
createRoutessemantics exactly —options.passwordenforces Basic auth; omitting it serves open (documented; embedders front it with their own access control).isAllowedCorsOriginmiddleware as the Node listener path.resumeSuspendedSessionsboot hook forks the execution-journal resume after layer boot, for runtimes that die without teardown.Testing
packages/server/test/fetch.test.ts, all against in-memory databases:Full
packages/serversuite green (33 tests). Note: repo-widetypecheckis currently red at v2 head itself (pre-existing nodenext TS2835s infff-bun/packages/ai, unrelated).