diff --git a/packages/opencode/src/lsp/lsp.ts b/packages/opencode/src/lsp/lsp.ts index aa519f9f7e..833285e7b5 100644 --- a/packages/opencode/src/lsp/lsp.ts +++ b/packages/opencode/src/lsp/lsp.ts @@ -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 +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 +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 + }), +}) + .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 +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, diff --git a/packages/opencode/src/server/routes/instance/file.ts b/packages/opencode/src/server/routes/instance/file.ts index bbef679a85..f92fe6e7e5 100644 --- a/packages/opencode/src/server/routes/instance/file.ts +++ b/packages/opencode/src/server/routes/instance/file.ts @@ -90,7 +90,7 @@ export const FileRoutes = lazy(() => description: "Symbols", content: { "application/json": { - schema: resolver(LSP.Symbol.array()), + schema: resolver(LSP.Symbol.zod.array()), }, }, }, diff --git a/packages/opencode/src/server/routes/instance/index.ts b/packages/opencode/src/server/routes/instance/index.ts index 0038c59619..e8a038fabc 100644 --- a/packages/opencode/src/server/routes/instance/index.ts +++ b/packages/opencode/src/server/routes/instance/index.ts @@ -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()), }, }, }, diff --git a/packages/opencode/src/session/message-v2.ts b/packages/opencode/src/session/message-v2.ts index 20528763b8..58bee8d1eb 100644 --- a/packages/opencode/src/session/message-v2.ts +++ b/packages/opencode/src/session/message-v2.ts @@ -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({