fix(skill): unify skill resolution to support user custom skills

sisyphus_task was only loading builtin skills via resolveMultipleSkills().
Now uses resolveMultipleSkillsAsync() which merges discoverSkills() + builtin skills.

- Add getAllSkills(), extractSkillTemplate(), resolveMultipleSkillsAsync()
- Update sisyphus_task to use async skill resolution
- Refactor skill tool to reuse unified getAllSkills()
- Add async skill resolution tests
This commit is contained in:
justsisyphus
2026-01-16 01:57:57 +09:00
parent 5de3d4fb7d
commit 207a39b17a
4 changed files with 198 additions and 12 deletions

View File

@@ -1,10 +1,9 @@
import { dirname } from "node:path"
import { readFileSync } from "node:fs"
import { tool, type ToolDefinition } from "@opencode-ai/plugin"
import { TOOL_DESCRIPTION_NO_SKILLS, TOOL_DESCRIPTION_PREFIX } from "./constants"
import type { SkillArgs, SkillInfo, SkillLoadOptions } from "./types"
import { discoverSkills, type LoadedSkill } from "../../features/opencode-skill-loader"
import { parseFrontmatter } from "../../shared/frontmatter"
import type { LoadedSkill } from "../../features/opencode-skill-loader"
import { getAllSkills, extractSkillTemplate } from "../../features/opencode-skill-loader/skill-content"
import type { SkillMcpManager, SkillMcpClientInfo, SkillMcpServerContext } from "../../features/skill-mcp-manager"
import type { Tool, Resource, Prompt } from "@modelcontextprotocol/sdk/types.js"
@@ -48,9 +47,7 @@ async function extractSkillBody(skill: LoadedSkill): Promise<string> {
}
if (skill.path) {
const content = readFileSync(skill.path, "utf-8")
const { body } = parseFrontmatter(content)
return body.trim()
return extractSkillTemplate(skill)
}
const templateMatch = skill.definition.template?.match(/<skill-instruction>([\s\S]*?)<\/skill-instruction>/)
@@ -135,7 +132,7 @@ export function createSkillTool(options: SkillLoadOptions = {}): ToolDefinition
const getSkills = async (): Promise<LoadedSkill[]> => {
if (options.skills) return options.skills
if (cachedSkills) return cachedSkills
cachedSkills = await discoverSkills({ includeClaudeCodePaths: !options.opencodeOnly })
cachedSkills = await getAllSkills()
return cachedSkills
}