feat(skill): built-in opencode-meta skill (#26617)

This commit is contained in:
Kit Langton
2026-05-09 22:05:37 -04:00
committed by GitHub
parent 79d6b10d7c
commit 10ea59066f
5 changed files with 393 additions and 0 deletions
+20
View File
@@ -17,6 +17,7 @@ import { ConfigMarkdown } from "@/config/markdown"
import { Glob } from "@opencode-ai/core/util/glob"
import * as Log from "@opencode-ai/core/util/log"
import { Discovery } from "./discovery"
import CUSTOMIZE_OPENCODE_SKILL_BODY from "./prompt/customize-opencode.md" with { type: "text" }
const log = Log.create({ service: "skill" })
const CLAUDE_EXTERNAL_DIR = ".claude"
@@ -25,6 +26,15 @@ const EXTERNAL_SKILL_PATTERN = "skills/**/SKILL.md"
const OPENCODE_SKILL_PATTERN = "{skill,skills}/**/SKILL.md"
const SKILL_PATTERN = "**/SKILL.md"
// Built-in skill that ships with opencode. The model's intuition for what an
// opencode.json should look like is often wrong, and opencode hard-fails on
// invalid config, so users hit cryptic startup errors. Loading this skill
// when the model is asked to touch opencode's own config files gives it the
// actual schemas instead of guesses.
const CUSTOMIZE_OPENCODE_SKILL_NAME = "customize-opencode"
const CUSTOMIZE_OPENCODE_SKILL_DESCRIPTION =
"Use ONLY when the user is editing or creating opencode's own configuration: opencode.json, opencode.jsonc, files under .opencode/, or files under ~/.config/opencode/. Also use when creating or fixing opencode agents, subagents, skills, plugins, MCP servers, or permission rules. Do not use for the user's own application code, or for any project that is not configuring opencode itself."
export const Info = Schema.Struct({
name: Schema.String,
description: Schema.optional(Schema.String),
@@ -230,6 +240,16 @@ export const layer = Layer.effect(
const state = yield* InstanceState.make(
Effect.fn("Skill.state")(function* () {
const s: State = { skills: {}, dirs: new Set() }
// Register the built-in skill BEFORE disk discovery so a user-disk
// skill with the same name can override it.
if (Flag.OPENCODE_EXPERIMENTAL_CUSTOMIZE_SKILL) {
s.skills[CUSTOMIZE_OPENCODE_SKILL_NAME] = {
name: CUSTOMIZE_OPENCODE_SKILL_NAME,
description: CUSTOMIZE_OPENCODE_SKILL_DESCRIPTION,
location: "<built-in>",
content: CUSTOMIZE_OPENCODE_SKILL_BODY,
}
}
yield* loadSkills(s, yield* InstanceState.get(discovered), bus)
return s
}),