Skip to content

Commit 8269b6f

Browse files
committed
feat(skill): add hidden frontmatter field to skills
Add a hidden boolean field to skill frontmatter, mirroring the existing AgentConfig.hidden field. Skills with hidden: true are excluded from the LLM tool description (available_skills) but remain accessible via the /skills dialog and the skill tool for manual invocation. Closes #29189
1 parent 748fcb7 commit 8269b6f

1 file changed

Lines changed: 8 additions & 3 deletions

File tree

packages/opencode/src/skill/index.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const CUSTOMIZE_OPENCODE_SKILL_DESCRIPTION =
3636
export const Info = Schema.Struct({
3737
name: Schema.String,
3838
description: Schema.optional(Schema.String),
39+
hidden: Schema.optional(Schema.Boolean),
3940
location: Schema.String,
4041
content: Schema.String,
4142
})
@@ -49,11 +50,12 @@ const Issue = Schema.StructWithRest(
4950
[Schema.Record(Schema.String, Schema.Unknown)],
5051
)
5152

52-
function isSkillFrontmatter(data: unknown): data is { name: string; description?: string } {
53+
function isSkillFrontmatter(data: unknown): data is { name: string; description?: string; hidden?: boolean } {
5354
return (
5455
isRecord(data) &&
5556
typeof data.name === "string" &&
56-
(data.description === undefined || typeof data.description === "string")
57+
(data.description === undefined || typeof data.description === "string") &&
58+
(data.hidden === undefined || typeof data.hidden === "boolean")
5759
)
5860
}
5961

@@ -135,6 +137,7 @@ const add = Effect.fnUntraced(function* (state: State, match: string, bus: Bus.I
135137
state.skills[md.data.name] = {
136138
name: md.data.name,
137139
description: md.data.description,
140+
hidden: md.data.hidden,
138141
location: match,
139142
content: md.content,
140143
}
@@ -305,7 +308,9 @@ export const layer = Layer.effect(
305308

306309
const available = Effect.fn("Skill.available")(function* (agent?: Agent.Info) {
307310
const s = yield* InstanceState.get(state)
308-
const list = Object.values(s.skills).toSorted((a, b) => a.name.localeCompare(b.name))
311+
const list = Object.values(s.skills)
312+
.filter((skill) => skill.hidden !== true)
313+
.toSorted((a, b) => a.name.localeCompare(b.name))
309314
if (!agent) return list
310315
return list.filter((skill) => Permission.evaluate("skill", skill.name, agent.permission).action !== "deny")
311316
})

0 commit comments

Comments
 (0)