migrate LSP data schemas to Effect Schema (#23745)

This commit is contained in:
Kit Langton
2026-04-21 17:26:50 -04:00
committed by GitHub
parent caaddf0964
commit 7933657135
4 changed files with 49 additions and 54 deletions

View File

@@ -10,9 +10,11 @@ import { Config } from "../config"
import { Flag } from "@/flag/flag"
import { Process } from "../util"
import { spawn as lspspawn } from "./launch"
import { Effect, Layer, Context } from "effect"
import { Effect, Layer, Context, Schema } from "effect"
import { InstanceState } from "@/effect"
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
import { withStatics } from "@/util/schema"
import { zod, ZodOverride } from "@/util/effect-zod"
const log = Log.create({ service: "lsp" })
@@ -20,60 +22,53 @@ export const Event = {
Updated: BusEvent.define("lsp.updated", z.object({})),
}
export const Range = z
.object({
start: z.object({
line: z.number(),
character: z.number(),
}),
end: z.object({
line: z.number(),
character: z.number(),
}),
})
.meta({
ref: "Range",
})
export type Range = z.infer<typeof Range>
const Position = Schema.Struct({
line: Schema.Number,
character: Schema.Number,
})
export const Symbol = z
.object({
name: z.string(),
kind: z.number(),
location: z.object({
uri: z.string(),
range: Range,
}),
})
.meta({
ref: "Symbol",
})
export type Symbol = z.infer<typeof Symbol>
export const Range = Schema.Struct({
start: Position,
end: Position,
})
.annotate({ identifier: "Range" })
.pipe(withStatics((s) => ({ zod: zod(s) })))
export type Range = typeof Range.Type
export const DocumentSymbol = z
.object({
name: z.string(),
detail: z.string().optional(),
kind: z.number(),
export const Symbol = Schema.Struct({
name: Schema.String,
kind: Schema.Number,
location: Schema.Struct({
uri: Schema.String,
range: Range,
selectionRange: Range,
})
.meta({
ref: "DocumentSymbol",
})
export type DocumentSymbol = z.infer<typeof DocumentSymbol>
}),
})
.annotate({ identifier: "Symbol" })
.pipe(withStatics((s) => ({ zod: zod(s) })))
export type Symbol = typeof Symbol.Type
export const Status = z
.object({
id: z.string(),
name: z.string(),
root: z.string(),
status: z.union([z.literal("connected"), z.literal("error")]),
})
.meta({
ref: "LSPStatus",
})
export type Status = z.infer<typeof Status>
export const DocumentSymbol = Schema.Struct({
name: Schema.String,
detail: Schema.optional(Schema.String),
kind: Schema.Number,
range: Range,
selectionRange: Range,
})
.annotate({ identifier: "DocumentSymbol" })
.pipe(withStatics((s) => ({ zod: zod(s) })))
export type DocumentSymbol = typeof DocumentSymbol.Type
export const Status = Schema.Struct({
id: Schema.String,
name: Schema.String,
root: Schema.String,
status: Schema.Literals(["connected", "error"]).annotate({
[ZodOverride]: z.union([z.literal("connected"), z.literal("error")]),
}),
})
.annotate({ identifier: "LSPStatus" })
.pipe(withStatics((s) => ({ zod: zod(s) })))
export type Status = typeof Status.Type
enum SymbolKind {
File = 1,

View File

@@ -90,7 +90,7 @@ export const FileRoutes = lazy(() =>
description: "Symbols",
content: {
"application/json": {
schema: resolver(LSP.Symbol.array()),
schema: resolver(LSP.Symbol.zod.array()),
},
},
},

View File

@@ -260,7 +260,7 @@ export const InstanceRoutes = (upgrade: UpgradeWebSocket): Hono => {
description: "LSP server status",
content: {
"application/json": {
schema: resolver(LSP.Status.array()),
schema: resolver(LSP.Status.zod.array()),
},
},
},

View File

@@ -159,7 +159,7 @@ export const FileSource = FilePartSourceBase.extend({
export const SymbolSource = FilePartSourceBase.extend({
type: z.literal("symbol"),
path: z.string(),
range: LSP.Range,
range: LSP.Range.zod,
name: z.string(),
kind: z.number().int(),
}).meta({