summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorKit Langton <[email protected]>2026-04-30 20:48:14 -0400
committerGitHub <[email protected]>2026-04-30 20:48:14 -0400
commit5c2e06f353eb00e1c4576ef24fb208eb3af935f8 (patch)
tree5ac8b5033ca4b91a559eca92dba14ed3973212d9
parenta499fe2b1751f79a44808066ec053c36071a9f28 (diff)
downloadopencode-5c2e06f353eb00e1c4576ef24fb208eb3af935f8.tar.gz
opencode-5c2e06f353eb00e1c4576ef24fb208eb3af935f8.zip
Document HttpApi route patterns (#25188)
-rw-r--r--packages/opencode/src/server/routes/instance/httpapi/AGENTS.md35
1 files changed, 35 insertions, 0 deletions
diff --git a/packages/opencode/src/server/routes/instance/httpapi/AGENTS.md b/packages/opencode/src/server/routes/instance/httpapi/AGENTS.md
new file mode 100644
index 000000000..757d7aed0
--- /dev/null
+++ b/packages/opencode/src/server/routes/instance/httpapi/AGENTS.md
@@ -0,0 +1,35 @@
+# HttpApi Route Patterns
+
+Use `HttpApiBuilder.group(...)` for normal HTTP endpoints, including streaming HTTP responses such as server-sent events. Handlers should yield stable services once while building the handler layer, then close over those services in endpoint implementations.
+
+```ts
+export const sessionHandlers = HttpApiBuilder.group(InstanceHttpApi, "session", (handlers) =>
+ Effect.gen(function* () {
+ const session = yield* Session.Service
+
+ return handlers.handle("list", () => session.list())
+ }),
+)
+```
+
+For SSE endpoints, stay in `HttpApiBuilder.group(...)` and return `HttpServerResponse.stream(...)` from the handler. Annotate the endpoint success schema with `HttpApiSchema.asText({ contentType: "text/event-stream" })` so OpenAPI documents the stream content type.
+
+Use raw `HttpRouter.use(...)` only for routes that do not fit the request/response HttpApi model, such as WebSocket upgrade routes or catch-all fallback routes. Yield stable services at route-layer construction and close over them in `router.add(...)` callbacks.
+
+```ts
+export const rawRoute = HttpRouter.use((router) =>
+ Effect.gen(function* () {
+ const pty = yield* Pty.Service
+
+ yield* router.add("GET", PtyPaths.connect, (request) => connectPty(request, pty))
+ }),
+)
+```
+
+Avoid `Effect.provide(SomeLayer)` inside request handlers or raw route callbacks. Stable layers should be provided once at the application/layer boundary, not rebuilt or scoped per request.
+
+Avoid `HttpRouter.provideRequest(...)` unless the dependency is intentionally request-level. Prefer `HttpRouter.use(...)` for stable app services.
+
+Use `Effect.provideService(...)` in middleware only for request-derived context, such as `WorkspaceRouteContext`, `InstanceRef`, or `WorkspaceRef`. Do not use it to smuggle stable services through request effects when they can be yielded at layer construction.
+
+When adding middleware, compose it at the layer boundary and keep the route tree explicit in `server.ts`. Shared router middleware such as auth, workspace routing, and instance context should stay visible where routes are assembled.