diff options
| author | Aiden Cline <[email protected]> | 2025-10-30 10:56:30 -0500 |
|---|---|---|
| committer | Aiden Cline <[email protected]> | 2025-10-30 10:56:40 -0500 |
| commit | 42e0b47a7db1ce06f422211ed3818c49474d4614 (patch) | |
| tree | 1cb3a708df48ff732525dc5c6173505fecedeaa3 | |
| parent | 2d5df3ad7671f3fe6d7f46b65218f6901c77e9d6 (diff) | |
| download | opencode-42e0b47a7db1ce06f422211ed3818c49474d4614.tar.gz opencode-42e0b47a7db1ce06f422211ed3818c49474d4614.zip | |
fix: better frontmatter errors
| -rw-r--r-- | packages/opencode/src/cli/error.ts | 13 | ||||
| -rw-r--r-- | packages/opencode/src/config/config.ts | 11 | ||||
| -rw-r--r-- | packages/opencode/src/config/markdown.ts | 29 |
3 files changed, 43 insertions, 10 deletions
diff --git a/packages/opencode/src/cli/error.ts b/packages/opencode/src/cli/error.ts index 1bc20de32..7c873ae50 100644 --- a/packages/opencode/src/cli/error.ts +++ b/packages/opencode/src/cli/error.ts @@ -1,3 +1,4 @@ +import { ConfigMarkdown } from "@/config/markdown" import { Config } from "../config/config" import { MCP } from "../mcp" import { UI } from "./ui" @@ -7,16 +8,22 @@ export function FormatError(input: unknown) { return `MCP server "${input.data.name}" failed. Note, opencode does not support MCP authentication yet.` if (Config.JsonError.isInstance(input)) { return ( - `Config file at ${input.data.path} is not valid JSON(C)` + (input.data.message ? `: ${input.data.message}` : "") + `Config file at ${input.data.path} is not valid JSON(C)` + + (input.data.message ? `: ${input.data.message}` : "") ) } if (Config.ConfigDirectoryTypoError.isInstance(input)) { return `Directory "${input.data.dir}" in ${input.data.path} is not valid. Use "${input.data.suggestion}" instead. This is a common typo.` } + if (ConfigMarkdown.FrontmatterError.isInstance(input)) { + return `Failed to parse frontmatter in ${input.data.path}:\n${input.data.message}` + } if (Config.InvalidError.isInstance(input)) return [ - `Config file at ${input.data.path} is invalid` + (input.data.message ? `: ${input.data.message}` : ""), - ...(input.data.issues?.map((issue) => "↳ " + issue.message + " " + issue.path.join(".")) ?? []), + `Config file at ${input.data.path} is invalid` + + (input.data.message ? `: ${input.data.message}` : ""), + ...(input.data.issues?.map((issue) => "↳ " + issue.message + " " + issue.path.join(".")) ?? + []), ].join("\n") if (UI.CancelledError.isInstance(input)) return "" diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 12a5c1624..031c4d82a 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -9,7 +9,6 @@ import { Global } from "../global" import fs from "fs/promises" import { lazy } from "../util/lazy" import { NamedError } from "../util/error" -import matter from "gray-matter" import { Flag } from "../flag/flag" import { Auth } from "../auth" import { @@ -21,6 +20,7 @@ import { Instance } from "../project/instance" import { LSPServer } from "../lsp/server" import { BunProc } from "@/bun" import { Installation } from "@/installation" +import { ConfigMarkdown } from "./markdown" export namespace Config { const log = Log.create({ service: "config" }) @@ -191,8 +191,7 @@ export namespace Config { dot: true, cwd: dir, })) { - const content = await Bun.file(item).text() - const md = matter(content) + const md = await ConfigMarkdown.parse(item) if (!md.data) continue const name = (() => { @@ -231,8 +230,7 @@ export namespace Config { dot: true, cwd: dir, })) { - const content = await Bun.file(item).text() - const md = matter(content) + const md = await ConfigMarkdown.parse(item) if (!md.data) continue // Extract relative path from agent folder for nested agents @@ -274,8 +272,7 @@ export namespace Config { dot: true, cwd: dir, })) { - const content = await Bun.file(item).text() - const md = matter(content) + const md = await ConfigMarkdown.parse(item) if (!md.data) continue const config = { diff --git a/packages/opencode/src/config/markdown.ts b/packages/opencode/src/config/markdown.ts index a4dcbf5d4..3e84bbf43 100644 --- a/packages/opencode/src/config/markdown.ts +++ b/packages/opencode/src/config/markdown.ts @@ -1,3 +1,7 @@ +import { NamedError } from "@/util/error" +import matter from "gray-matter" +import { z } from "zod" + export namespace ConfigMarkdown { export const FILE_REGEX = /(?<![\w`])@(\.?[^\s`,.]*(?:\.[^\s`,.]+)*)/g export const SHELL_REGEX = /!`([^`]+)`/g @@ -9,4 +13,29 @@ export namespace ConfigMarkdown { export function shell(template: string) { return Array.from(template.matchAll(SHELL_REGEX)) } + + export async function parse(filePath: string) { + const template = await Bun.file(filePath).text() + + try { + const md = matter(template) + return md + } catch (err) { + throw new FrontmatterError( + { + path: filePath, + message: `Failed to parse YAML frontmatter: ${err instanceof Error ? err.message : String(err)}`, + }, + { cause: err }, + ) + } + } + + export const FrontmatterError = NamedError.create( + "ConfigFrontmatterError", + z.object({ + path: z.string(), + message: z.string(), + }), + ) } |
