Skip to content

Commit b1307d5

Browse files
authored
refactor(config): migrate skills, formatter, console-state to Effect Schema (#23162)
1 parent dc16013 commit b1307d5

6 files changed

Lines changed: 46 additions & 36 deletions

File tree

packages/opencode/src/config/config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export const Info = z
100100
.record(z.string(), ConfigCommand.Info)
101101
.optional()
102102
.describe("Command configuration, see https://opencode.ai/docs/commands"),
103-
skills: ConfigSkills.Info.optional().describe("Additional skill folder paths"),
103+
skills: ConfigSkills.Info.zod.optional().describe("Additional skill folder paths"),
104104
watcher: z
105105
.object({
106106
ignore: z.array(z.string()).optional(),
@@ -188,7 +188,7 @@ export const Info = z
188188
)
189189
.optional()
190190
.describe("MCP (Model Context Protocol) server configurations"),
191-
formatter: ConfigFormatter.Info.optional(),
191+
formatter: ConfigFormatter.Info.zod.optional(),
192192
lsp: ConfigLSP.Info.zod.optional(),
193193
instructions: z.array(z.string()).optional().describe("Additional instruction files or patterns to include"),
194194
layout: Layout.optional().describe("@deprecated Always uses stretch layout."),
Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
import z from "zod"
1+
import { Schema } from "effect"
2+
import { zod } from "@/util/effect-zod"
23

3-
export const ConsoleState = z.object({
4-
consoleManagedProviders: z.array(z.string()),
5-
activeOrgName: z.string().optional(),
6-
switchableOrgCount: z.number().int().nonnegative(),
7-
})
8-
9-
export type ConsoleState = z.infer<typeof ConsoleState>
4+
export class ConsoleState extends Schema.Class<ConsoleState>("ConsoleState")({
5+
consoleManagedProviders: Schema.mutable(Schema.Array(Schema.String)),
6+
activeOrgName: Schema.optional(Schema.String),
7+
switchableOrgCount: Schema.Number,
8+
}) {
9+
static readonly zod = zod(this)
10+
}
1011

11-
export const emptyConsoleState: ConsoleState = {
12+
export const emptyConsoleState: ConsoleState = ConsoleState.make({
1213
consoleManagedProviders: [],
1314
activeOrgName: undefined,
1415
switchableOrgCount: 0,
15-
}
16+
})
Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
export * as ConfigFormatter from "./formatter"
22

3-
import z from "zod"
3+
import { Schema } from "effect"
4+
import { zod } from "@/util/effect-zod"
5+
import { withStatics } from "@/util/schema"
46

5-
export const Entry = z.object({
6-
disabled: z.boolean().optional(),
7-
command: z.array(z.string()).optional(),
8-
environment: z.record(z.string(), z.string()).optional(),
9-
extensions: z.array(z.string()).optional(),
10-
})
7+
export const Entry = Schema.Struct({
8+
disabled: Schema.optional(Schema.Boolean),
9+
command: Schema.optional(Schema.mutable(Schema.Array(Schema.String))),
10+
environment: Schema.optional(Schema.Record(Schema.String, Schema.String)),
11+
extensions: Schema.optional(Schema.mutable(Schema.Array(Schema.String))),
12+
}).pipe(withStatics((s) => ({ zod: zod(s) })))
1113

12-
export const Info = z.union([z.boolean(), z.record(z.string(), Entry)])
13-
export type Info = z.infer<typeof Info>
14+
export const Info = Schema.Union([Schema.Boolean, Schema.Record(Schema.String, Entry)]).pipe(
15+
withStatics((s) => ({ zod: zod(s) })),
16+
)
17+
export type Info = Schema.Schema.Type<typeof Info>
Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1-
import z from "zod"
1+
import { Schema } from "effect"
2+
import { zod } from "@/util/effect-zod"
3+
import { withStatics } from "@/util/schema"
24

3-
export const Info = z.object({
4-
paths: z.array(z.string()).optional().describe("Additional paths to skill folders"),
5-
urls: z
6-
.array(z.string())
7-
.optional()
8-
.describe("URLs to fetch skills from (e.g., https://example.com/.well-known/skills/)"),
9-
})
5+
export const Info = Schema.Struct({
6+
paths: Schema.optional(Schema.Array(Schema.String)).annotate({
7+
description: "Additional paths to skill folders",
8+
}),
9+
urls: Schema.optional(Schema.Array(Schema.String)).annotate({
10+
description: "URLs to fetch skills from (e.g., https://example.com/.well-known/skills/)",
11+
}),
12+
}).pipe(withStatics((s) => ({ zod: zod(s) })))
1013

11-
export type Info = z.infer<typeof Info>
14+
export type Info = Schema.Schema.Type<typeof Info>
1215

1316
export * as ConfigSkills from "./skills"

packages/opencode/src/server/routes/instance/experimental.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export const ExperimentalRoutes = lazy(() =>
4949
description: "Active Console provider metadata",
5050
content: {
5151
"application/json": {
52-
schema: resolver(ConsoleState),
52+
schema: resolver(ConsoleState.zod),
5353
},
5454
},
5555
},

packages/sdk/js/src/v2/gen/types.gen.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,6 +1807,12 @@ export type Provider = {
18071807
}
18081808
}
18091809

1810+
export type ConsoleState = {
1811+
consoleManagedProviders: Array<string>
1812+
activeOrgName?: string
1813+
switchableOrgCount: number
1814+
}
1815+
18101816
export type ToolIds = Array<string>
18111817

18121818
export type ToolListItem = {
@@ -2933,11 +2939,7 @@ export type ExperimentalConsoleGetResponses = {
29332939
/**
29342940
* Active Console provider metadata
29352941
*/
2936-
200: {
2937-
consoleManagedProviders: Array<string>
2938-
activeOrgName?: string
2939-
switchableOrgCount: number
2940-
}
2942+
200: ConsoleState
29412943
}
29422944

29432945
export type ExperimentalConsoleGetResponse = ExperimentalConsoleGetResponses[keyof ExperimentalConsoleGetResponses]

0 commit comments

Comments
 (0)