Skip to content

Commit b5274fc

Browse files
committed
feat(config): add Zod schema validation and JSON Schema generation
- Add Zod schema for oh-my-opencode.json configuration validation - Generate JSON Schema at build time for IDE autocompletion - Add safeParse validation with error reporting on config load - Export OhMyOpenCodeConfigSchema for programmatic usage - Add build:schema script and ./schema.json export - Update README with $schema usage documentation
1 parent 8e5064c commit b5274fc

File tree

3 files changed

+100
-0
lines changed

3 files changed

+100
-0
lines changed

script/build-schema.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env bun
2+
import * as z from "zod"
3+
import { OhMyOpenCodeConfigSchema } from "../src/config/schema"
4+
5+
const SCHEMA_OUTPUT_PATH = "dist/oh-my-opencode.schema.json"
6+
7+
async function main() {
8+
console.log("Generating JSON Schema...")
9+
10+
const jsonSchema = z.toJSONSchema(OhMyOpenCodeConfigSchema, {
11+
io: "input",
12+
target: "draft-7",
13+
})
14+
15+
const finalSchema = {
16+
$schema: "http://json-schema.org/draft-07/schema#",
17+
$id: "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/dist/oh-my-opencode.schema.json",
18+
title: "Oh My OpenCode Configuration",
19+
description: "Configuration schema for oh-my-opencode plugin",
20+
...jsonSchema,
21+
}
22+
23+
await Bun.write(SCHEMA_OUTPUT_PATH, JSON.stringify(finalSchema, null, 2))
24+
25+
console.log(`✓ JSON Schema generated: ${SCHEMA_OUTPUT_PATH}`)
26+
}
27+
28+
main()

src/config/index.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export {
2+
OhMyOpenCodeConfigSchema,
3+
AgentOverrideConfigSchema,
4+
AgentOverridesSchema,
5+
McpNameSchema,
6+
AgentNameSchema,
7+
} from "./schema"
8+
9+
export type {
10+
OhMyOpenCodeConfig,
11+
AgentOverrideConfig,
12+
AgentOverrides,
13+
McpName,
14+
AgentName,
15+
} from "./schema"

src/config/schema.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { z } from "zod"
2+
3+
const PermissionValue = z.enum(["ask", "allow", "deny"])
4+
5+
const BashPermission = z.union([
6+
PermissionValue,
7+
z.record(z.string(), PermissionValue),
8+
])
9+
10+
const AgentPermissionSchema = z.object({
11+
edit: PermissionValue.optional(),
12+
bash: BashPermission.optional(),
13+
webfetch: PermissionValue.optional(),
14+
doom_loop: PermissionValue.optional(),
15+
external_directory: PermissionValue.optional(),
16+
})
17+
18+
export const AgentNameSchema = z.enum([
19+
"oracle",
20+
"librarian",
21+
"explore",
22+
"frontend-ui-ux-engineer",
23+
"document-writer",
24+
])
25+
26+
export const McpNameSchema = z.enum(["websearch_exa", "context7"])
27+
28+
export const AgentOverrideConfigSchema = z.object({
29+
model: z.string().optional(),
30+
temperature: z.number().min(0).max(2).optional(),
31+
top_p: z.number().min(0).max(1).optional(),
32+
prompt: z.string().optional(),
33+
tools: z.record(z.string(), z.boolean()).optional(),
34+
disable: z.boolean().optional(),
35+
description: z.string().optional(),
36+
mode: z.enum(["subagent", "primary", "all"]).optional(),
37+
color: z
38+
.string()
39+
.regex(/^#[0-9A-Fa-f]{6}$/)
40+
.optional(),
41+
permission: AgentPermissionSchema.optional(),
42+
})
43+
44+
export const AgentOverridesSchema = z.record(AgentNameSchema, AgentOverrideConfigSchema)
45+
46+
export const OhMyOpenCodeConfigSchema = z.object({
47+
$schema: z.string().optional(),
48+
disabled_mcps: z.array(McpNameSchema).optional(),
49+
disabled_agents: z.array(AgentNameSchema).optional(),
50+
agents: AgentOverridesSchema.optional(),
51+
})
52+
53+
export type OhMyOpenCodeConfig = z.infer<typeof OhMyOpenCodeConfigSchema>
54+
export type AgentOverrideConfig = z.infer<typeof AgentOverrideConfigSchema>
55+
export type AgentOverrides = z.infer<typeof AgentOverridesSchema>
56+
export type McpName = z.infer<typeof McpNameSchema>
57+
export type AgentName = z.infer<typeof AgentNameSchema>

0 commit comments

Comments
 (0)