2026-04-13 14:04:32 +00:00
# HttpApi migration
2026-04-24 21:36:49 +00:00
Plan for replacing instance Hono route implementations with Effect `HttpApi` while preserving behavior, OpenAPI, and SDK output during the transition.
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
## End State
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
- JSON route contracts and handlers live in `src/server/routes/instance/httpapi/*` .
- Route modules own their `HttpApiGroup` , schemas, handlers, and route-level middleware.
- `httpapi/server.ts` only composes groups, instance lookup, observability, and the web handler bridge.
- Hono route implementations are deleted once their `HttpApi` replacements are default, tested, and represented in the SDK/OpenAPI pipeline.
- Streaming, SSE, and websocket routes move later through Effect HTTP primitives or another explicit replacement plan; they do not need to fit `HttpApi` if `HttpApi` is the wrong abstraction.
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
## Current State
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
- `OPENCODE_EXPERIMENTAL_HTTPAPI` gates the bridge. Default behavior still uses Hono.
- The bridge mounts selected paths in `server/routes/instance/index.ts` before legacy Hono routes.
- Legacy Hono routes remain for default behavior and for `hono-openapi` SDK generation.
- `HttpApi` auth is independent of Hono auth.
- `Authorization` is attached in each route module, not centrally wrapped in `server.ts` .
- Auth supports Basic auth and the legacy `auth_token` query parameter through `HttpApiSecurity.apiKey` .
- Instance context is provided by `httpapi/server.ts` using `directory` , `workspace` , and `x-opencode-directory` .
- `Observability.layer` is provided in the Effect route layer and deduplicated through the shared `memoMap` .
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
## Migration Rules
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
- Preserve runtime behavior first. Semantic changes, new error behavior, or route shape changes need separate PRs.
- Migrate one route group, or one coherent subset of a route group, at a time.
- Reuse existing services. Do not re-architect service logic during HTTP boundary migration.
- Effect Schema owns route DTOs. Keep `.zod` only as compatibility for remaining Hono/OpenAPI surfaces.
- Regenerate the SDK after schema or OpenAPI-affecting changes and verify the diff is expected.
- Do not delete a Hono route until the SDK/OpenAPI pipeline no longer depends on its Hono `describeRoute` entry.
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
## Schema Notes
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
- Use `Schema.Struct(...).annotate({ identifier })` for named OpenAPI refs when handlers return plain objects.
- Use `Schema.Class` only when the handler returns real class instances or the constructor requirement is intentional.
- Keep nested anonymous shapes as `Schema.Struct` unless a named SDK type is useful.
- Avoid parallel hand-written Zod and Effect definitions for the same route boundary.
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
## Phases
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
### 1. Stabilize The Bridge
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
Before porting more routes, cover the bridge behavior that every route depends on.
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
- Add tests that hit the Hono-mounted `HttpApi` bridge, not just `HttpApiBuilder.layer` directly.
- Cover auth disabled, Basic auth success, `auth_token` success, missing credentials, and bad credentials.
- Cover `directory` and `x-opencode-directory` instance selection.
- Verify generated SDK output remains unchanged for non-SDK work.
- Fix or remove any implemented-but-unmounted `HttpApi` groups.
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
### 2. Complete The Inventory
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
Create a route inventory from the actual Hono registrations and classify each route.
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
Statuses:
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
- `bridged` : served through the `HttpApi` bridge when the flag is on.
- `implemented` : `HttpApi` group exists but is not mounted through Hono.
- `next` : good JSON candidate for near-term porting.
- `later` : portable, but needs schema/service cleanup first.
- `special` : SSE, websocket, streaming, or UI bridge behavior that likely needs raw Effect HTTP rather than `HttpApi` .
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
### 3. Finish JSON Route Parity
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
Port remaining JSON routes in small batches.
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
Good near-term candidates:
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
- top-level reads: `GET /path` , `GET /vcs` , `GET /vcs/diff` , `GET /command` , `GET /agent` , `GET /skill` , `GET /lsp` , `GET /formatter`
- simple mutations: `POST /instance/dispose`
- experimental JSON reads: console, tool, worktree list, resource list
- deferred JSON mutations: `PATCH /config` , project git init, workspace/worktree create/remove/reset, file search, MCP auth flows
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
Keep large or stateful groups for later:
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
- `session`
- `sync`
- process-level experimental routes
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
### 4. Move OpenAPI And SDK Generation
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
Hono routes cannot be deleted while `hono-openapi` is the source of SDK generation.
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
Required before route deletion:
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
- Generate the public OpenAPI surface from Effect `HttpApi` for ported routes.
- Keep operation IDs, schemas, status codes, and SDK type names stable unless the change is intentional.
- Compare generated SDK output against `dev` for every route group deletion.
- Remove Hono OpenAPI stubs only after Effect OpenAPI is the SDK source for those paths.
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
### 5. Make HttpApi Default For JSON Routes
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
After JSON parity and SDK generation are covered:
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
- Flip the bridge default for ported JSON routes.
- Keep a short-lived fallback flag for the old Hono implementation.
- Run the same tests against both the default and fallback path during rollout.
- Stop adding new Hono handlers for JSON routes once the default flips.
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
### 6. Delete Hono Route Implementations
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
Delete Hono routes group-by-group after each group meets the deletion criteria.
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
Deletion criteria:
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
- `HttpApi` route is mounted by default.
- Behavior is covered by bridge-level tests.
- OpenAPI/SDK generation comes from Effect for that path.
- SDK diff is zero or explicitly accepted.
- Legacy Hono route is no longer needed as a fallback.
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
After deleting a group:
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
- Remove its Hono route file or dead endpoints.
- Remove its `.route(...)` registration from `instance/index.ts` .
- Remove duplicate Zod-only route DTOs if Effect Schema now owns the type.
- Regenerate SDK and verify output.
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
### 7. Replace Special Routes
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
Special routes need explicit designs before Hono can disappear completely.
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
- `event` : SSE
- `pty` : websocket
- `tui` : UI/control bridge behavior
- streaming `session` endpoints
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
Use raw Effect HTTP routes where `HttpApi` does not fit. The goal is deleting Hono implementations, not forcing every transport shape through `HttpApi` .
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
## Current Route Status
2026-04-13 14:04:32 +00:00
2026-04-24 21:38:31 +00:00
| Area | Status | Notes |
| ------------------------ | ----------------- | -------------------------------------------------------------- |
| `question` | `bridged` | `GET /question` , reply, reject |
| `permission` | `bridged` | list and reply |
| `provider` | `bridged` | list, auth, OAuth authorize/callback |
| `config` | `bridged` partial | reads only; mutation remains Hono |
| `project` | `bridged` partial | reads only; git-init remains Hono |
| `file` | `bridged` partial | list/content/status only |
| `mcp` | `bridged` partial | status only |
| `workspace` | `implemented` | `HttpApi` group exists, but bridge mounting needs verification |
| top-level instance reads | `next` | path, vcs, command, agent, skill, lsp, formatter |
| experimental JSON routes | `next/later` | console, tool, worktree, resource, global session list |
| `session` | `later/special` | large stateful surface plus streaming |
| `sync` | `later` | process/control side effects |
| `event` | `special` | SSE |
| `pty` | `special` | websocket |
| `tui` | `special` | UI bridge |
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
## Next PRs
2026-04-13 14:04:32 +00:00
2026-04-24 21:36:49 +00:00
1. Add bridge-level auth and instance-context tests for the current `HttpApi` bridge.
2. Produce a generated route inventory from Hono registrations and update `Current Route Status` with exact paths.
3. Fix the `workspace` status: mount it if it should be reachable, or remove it from the composed `HttpApi` layer.
4. Port the top-level JSON reads.
5. Start the Effect OpenAPI/SDK generation path for already-bridged routes.
2026-04-14 19:43:49 +00:00
## Checklist
2026-04-24 21:36:49 +00:00
- [x] Add first `HttpApi` JSON route slices.
- [x] Bridge selected `HttpApi` routes into Hono behind `OPENCODE_EXPERIMENTAL_HTTPAPI` .
- [x] Reuse existing Effect services in handlers.
- [x] Provide auth, instance lookup, and observability in the Effect route layer.
- [x] Attach auth middleware in route modules.
- [x] Support `auth_token` as a query security scheme.
- [ ] Add bridge-level auth and instance tests.
- [ ] Complete exact Hono route inventory.
- [ ] Resolve implemented-but-unmounted route groups.
- [ ] Port remaining JSON routes.
- [ ] Generate SDK/OpenAPI from Effect routes.
- [ ] Flip ported JSON routes to default-on with fallback.
- [ ] Delete replaced Hono route implementations.
- [ ] Replace SSE/websocket/streaming Hono routes with non-Hono implementations.