refactor(httpapi): simplify file search bridge

This commit is contained in:
Kit Langton
2026-04-24 01:14:46 -04:00
parent ad02a76122
commit 4374eebf0e
5 changed files with 44 additions and 31 deletions
+2 -2
View File
@@ -53,7 +53,7 @@ const Begin = Schema.Struct({
}),
})
export const MatchData = Schema.Struct({
export const SearchMatch = Schema.Struct({
path: PathText,
lines: Schema.Struct({
text: Schema.String,
@@ -73,7 +73,7 @@ export const MatchData = Schema.Struct({
export const Match = Schema.Struct({
type: Schema.Literal("match"),
data: MatchData,
data: SearchMatch,
})
const End = Schema.Struct({
@@ -21,7 +21,7 @@ export const FileRoutes = lazy(() =>
description: "Matches",
content: {
"application/json": {
schema: resolver(Ripgrep.MatchData.zod.array()),
schema: resolver(Ripgrep.SearchMatch.zod.array()),
},
},
},
@@ -1,9 +1,9 @@
import { File } from "@/file"
import { Ripgrep } from "@/file/ripgrep"
import { LSP } from "@/lsp"
import * as InstanceState from "@/effect/instance-state"
import { Effect, Layer, Schema } from "effect"
import { HttpApi, HttpApiBuilder, HttpApiEndpoint, HttpApiError, HttpApiGroup, OpenApi } from "effect/unstable/httpapi"
import { LSP } from "@/lsp"
const FileQuery = Schema.Struct({
path: Schema.String,
@@ -43,7 +43,7 @@ export const FileApi = HttpApi.make("file")
.add(
HttpApiEndpoint.get("find", FilePaths.find, {
query: FindTextQuery,
success: Schema.Array(Ripgrep.MatchData),
success: Schema.Array(Ripgrep.SearchMatch),
}).annotateMerge(
OpenApi.annotations({
identifier: "find.text",
@@ -120,10 +120,11 @@ export const fileHandlers = Layer.unwrap(
Effect.gen(function* () {
const svc = yield* File.Service
const ripgrep = yield* Ripgrep.Service
const lsp = yield* LSP.Service
const find = Effect.fn("FileHttpApi.find")(function* (ctx: { query: { pattern: string } }) {
return yield* ripgrep
.search({ cwd: (yield* InstanceState.context).directory, pattern: ctx.query.pattern, limit: 10 })
.search({ cwd: yield* InstanceState.directory, pattern: ctx.query.pattern, limit: 10 })
.pipe(
Effect.map((result) => result.items),
Effect.catch(() => Effect.fail(new HttpApiError.BadRequest({}))),
@@ -141,8 +142,8 @@ export const fileHandlers = Layer.unwrap(
})
})
const findSymbol = Effect.fn("FileHttpApi.findSymbol")(function* () {
return []
const findSymbol = Effect.fn("FileHttpApi.findSymbol")(function* (ctx: { query: { query: string } }) {
return yield* lsp.workspaceSymbol(ctx.query.query)
})
const list = Effect.fn("FileHttpApi.list")(function* (ctx: { query: { path: string } }) {
@@ -167,4 +168,4 @@ export const fileHandlers = Layer.unwrap(
.handle("status", status),
)
}),
).pipe(Layer.provide(File.defaultLayer), Layer.provide(Ripgrep.defaultLayer))
).pipe(Layer.provide(File.defaultLayer), Layer.provide(Ripgrep.defaultLayer), Layer.provide(LSP.defaultLayer))
@@ -37,26 +37,38 @@ export const InstanceRoutes = (upgrade: UpgradeWebSocket): Hono => {
if (Flag.OPENCODE_EXPERIMENTAL_HTTPAPI) {
const handler = ExperimentalHttpApiServer.webHandler().handler
const context = Context.empty() as Context.Context<unknown>
app.get("/question", (c) => handler(c.req.raw, context))
app.post("/question/:requestID/reply", (c) => handler(c.req.raw, context))
app.post("/question/:requestID/reject", (c) => handler(c.req.raw, context))
app.get("/permission", (c) => handler(c.req.raw, context))
app.post("/permission/:requestID/reply", (c) => handler(c.req.raw, context))
app.get("/config", (c) => handler(c.req.raw, context))
app.get("/config/providers", (c) => handler(c.req.raw, context))
app.get("/provider", (c) => handler(c.req.raw, context))
app.get("/provider/auth", (c) => handler(c.req.raw, context))
app.post("/provider/:providerID/oauth/authorize", (c) => handler(c.req.raw, context))
app.post("/provider/:providerID/oauth/callback", (c) => handler(c.req.raw, context))
app.get("/project", (c) => handler(c.req.raw, context))
app.get("/project/current", (c) => handler(c.req.raw, context))
app.get(FilePaths.find, (c) => handler(c.req.raw, context))
app.get(FilePaths.findFile, (c) => handler(c.req.raw, context))
app.get(FilePaths.findSymbol, (c) => handler(c.req.raw, context))
app.get(FilePaths.list, (c) => handler(c.req.raw, context))
app.get(FilePaths.content, (c) => handler(c.req.raw, context))
app.get(FilePaths.status, (c) => handler(c.req.raw, context))
app.get(McpPaths.status, (c) => handler(c.req.raw, context))
app.on(
"GET",
[
"/question",
"/permission",
"/config",
"/config/providers",
"/provider",
"/provider/auth",
"/project",
"/project/current",
FilePaths.find,
FilePaths.findFile,
FilePaths.findSymbol,
FilePaths.list,
FilePaths.content,
FilePaths.status,
McpPaths.status,
],
(c) => handler(c.req.raw, context),
)
app.on(
"POST",
[
"/question/:requestID/reply",
"/question/:requestID/reject",
"/permission/:requestID/reply",
"/provider/:providerID/oauth/authorize",
"/provider/:providerID/oauth/callback",
],
(c) => handler(c.req.raw, context),
)
}
return app
@@ -121,7 +121,7 @@ export const McpRoutes = lazy(() =>
description: "OAuth authentication completed",
content: {
"application/json": {
schema: resolver(MCP.Status.zod),
schema: resolver(MCP.Status.zod),
},
},
},
@@ -153,7 +153,7 @@ export const McpRoutes = lazy(() =>
description: "OAuth authentication completed",
content: {
"application/json": {
schema: resolver(MCP.Status.zod),
schema: resolver(MCP.Status.zod),
},
},
},