@@ -4,8 +4,23 @@ import { Flag } from "@opencode-ai/core/flag/flag"
44import { Instance } from "../../src/project/instance"
55import { InstanceRoutes } from "../../src/server/routes/instance"
66import { WorkspaceRoutes } from "../../src/server/routes/control/workspace"
7- import { FilePaths } from "../../src/server/routes/instance/httpapi/file"
7+ import { ConfigApi } from "../../src/server/routes/instance/httpapi/config"
8+ import { EventPaths } from "../../src/server/routes/instance/httpapi/event"
9+ import { ExperimentalApi } from "../../src/server/routes/instance/httpapi/experimental"
10+ import { FileApi , FilePaths } from "../../src/server/routes/instance/httpapi/file"
11+ import { InstanceApi } from "../../src/server/routes/instance/httpapi/instance"
12+ import { McpApi } from "../../src/server/routes/instance/httpapi/mcp"
13+ import { PermissionApi } from "../../src/server/routes/instance/httpapi/permission"
14+ import { ProjectApi } from "../../src/server/routes/instance/httpapi/project"
15+ import { ProviderApi } from "../../src/server/routes/instance/httpapi/provider"
16+ import { PtyApi , PtyPaths } from "../../src/server/routes/instance/httpapi/pty"
17+ import { QuestionApi } from "../../src/server/routes/instance/httpapi/question"
18+ import { SessionApi } from "../../src/server/routes/instance/httpapi/session"
19+ import { SyncApi } from "../../src/server/routes/instance/httpapi/sync"
20+ import { TuiApi } from "../../src/server/routes/instance/httpapi/tui"
21+ import { WorkspaceApi } from "../../src/server/routes/instance/httpapi/workspace"
822import * as Log from "@opencode-ai/core/util/log"
23+ import { HttpApi , HttpApiGroup } from "effect/unstable/httpapi"
924import { resetDatabase } from "../fixture/db"
1025import { tmpdir } from "../fixture/fixture"
1126
@@ -30,6 +45,39 @@ function routeKey(route: ReturnType<typeof InstanceRoutes>["routes"][number]) {
3045 return `${ route . method } ${ route . path } `
3146}
3247
48+ function reflectedHttpApiRoutes ( ) {
49+ const routes = [
50+ `GET ${ EventPaths . event } ` ,
51+ `GET ${ PtyPaths . connect } ` ,
52+ ]
53+
54+ function addRoutes < Id extends string , Groups extends HttpApiGroup . Any > ( api : HttpApi . HttpApi < Id , Groups > ) {
55+ HttpApi . reflect ( api , {
56+ onGroup ( ) { } ,
57+ onEndpoint ( { endpoint } ) {
58+ routes . push ( `${ endpoint . method } ${ endpoint . path } ` )
59+ } ,
60+ } )
61+ }
62+
63+ addRoutes ( ConfigApi )
64+ addRoutes ( ExperimentalApi )
65+ addRoutes ( FileApi )
66+ addRoutes ( InstanceApi )
67+ addRoutes ( McpApi )
68+ addRoutes ( PermissionApi )
69+ addRoutes ( ProjectApi )
70+ addRoutes ( ProviderApi )
71+ addRoutes ( PtyApi )
72+ addRoutes ( QuestionApi )
73+ addRoutes ( SessionApi )
74+ addRoutes ( SyncApi )
75+ addRoutes ( TuiApi )
76+ addRoutes ( WorkspaceApi )
77+
78+ return [ ...new Set ( routes ) ]
79+ }
80+
3381function authorization ( username : string , password : string ) {
3482 return `Basic ${ Buffer . from ( `${ username } :${ password } ` ) . toString ( "base64" ) } `
3583}
@@ -69,6 +117,21 @@ describe("HttpApi Hono bridge", () => {
69117 expect ( [ ...bridgeRoutes ] . filter ( ( route ) => ! legacyRoutes . includes ( route ) ) . sort ( ) ) . toEqual ( [ ] )
70118 } )
71119
120+ test ( "mounts every Effect HttpApi route through the Hono bridge" , ( ) => {
121+ Flag . OPENCODE_EXPERIMENTAL_HTTPAPI = false
122+ const legacy = InstanceRoutes ( websocket )
123+ Flag . OPENCODE_EXPERIMENTAL_HTTPAPI = true
124+ const experimental = InstanceRoutes ( websocket )
125+
126+ const bridgeRoutes = new Set (
127+ experimental . routes . slice ( 0 , experimental . routes . length - legacy . routes . length ) . map ( routeKey ) ,
128+ )
129+ const httpApiRoutes = reflectedHttpApiRoutes ( )
130+
131+ expect ( httpApiRoutes . filter ( ( route ) => ! bridgeRoutes . has ( route ) ) ) . toEqual ( [ ] )
132+ expect ( [ ...bridgeRoutes ] . filter ( ( route ) => ! httpApiRoutes . includes ( route ) ) . sort ( ) ) . toEqual ( [ ] )
133+ } )
134+
72135 test ( "allows requests when auth is disabled" , async ( ) => {
73136 await using tmp = await tmpdir ( { git : true } )
74137 await Bun . write ( `${ tmp . path } /hello.txt` , "hello" )
0 commit comments