fix: use correct 'skills' directory path and respect OPENCODE_CONFIG_DIR

- Change skill directory from 'skill' (singular) to 'skills' (plural) to match OpenCode standard
- Use getOpenCodeConfigDir() to respect OPENCODE_CONFIG_DIR environment variable
- Update documentation and tests to reflect correct paths

Fixes #810
This commit is contained in:
Jonas Herrmansdsoerfer
2026-01-21 13:12:27 +01:00
parent 52acb37478
commit 1a4106120d
6 changed files with 13 additions and 11 deletions

View File

@@ -147,8 +147,8 @@ Three specializations in one:
### Custom Skills
Load custom skills from:
- `.opencode/skill/*/SKILL.md` (project)
- `~/.config/opencode/skill/*/SKILL.md` (user)
- `.opencode/skills/*/SKILL.md` (project)
- `~/.config/opencode/skills/*/SKILL.md` (user)
- `.claude/skills/*/SKILL.md` (Claude Code compat)
- `~/.claude/skills/*/SKILL.md` (Claude Code user)

View File

@@ -36,7 +36,7 @@ features/
| Type | Priority (highest first) |
|------|--------------------------|
| Commands | `.opencode/command/` > `~/.config/opencode/command/` > `.claude/commands/` > `~/.claude/commands/` |
| Skills | `.opencode/skill/` > `~/.config/opencode/skill/` > `.claude/skills/` > `~/.claude/skills/` |
| Skills | `.opencode/skills/` > `~/.config/opencode/skills/` > `.claude/skills/` > `~/.claude/skills/` |
| Agents | `.claude/agents/` > `~/.claude/agents/` |
| MCPs | `.claude/.mcp.json` > `.mcp.json` > `~/.claude/.mcp.json` |

View File

@@ -5,7 +5,7 @@ import { tmpdir } from "os"
import type { LoadedSkill } from "./types"
const TEST_DIR = join(tmpdir(), "async-loader-test-" + Date.now())
const SKILLS_DIR = join(TEST_DIR, ".opencode", "skill")
const SKILLS_DIR = join(TEST_DIR, ".opencode", "skills")
function createTestSkill(name: string, content: string, mcpJson?: object): string {
const skillDir = join(SKILLS_DIR, name)

View File

@@ -4,7 +4,7 @@ import { join } from "path"
import { tmpdir } from "os"
const TEST_DIR = join(tmpdir(), "skill-loader-test-" + Date.now())
const SKILLS_DIR = join(TEST_DIR, ".opencode", "skill")
const SKILLS_DIR = join(TEST_DIR, ".opencode", "skills")
function createTestSkill(name: string, content: string, mcpJson?: object): string {
const skillDir = join(SKILLS_DIR, name)

View File

@@ -1,11 +1,11 @@
import { promises as fs } from "fs"
import { join, basename } from "path"
import { homedir } from "os"
import yaml from "js-yaml"
import { parseFrontmatter } from "../../shared/frontmatter"
import { sanitizeModelField } from "../../shared/model-sanitizer"
import { resolveSymlinkAsync, isMarkdownFile } from "../../shared/file-utils"
import { getClaudeConfigDir } from "../../shared"
import { getOpenCodeConfigDir } from "../../shared/opencode-config-dir"
import type { CommandDefinition } from "../claude-code-command-loader/types"
import type { SkillScope, SkillMetadata, LoadedSkill, LazyContentLoader } from "./types"
import type { SkillMcpConfig } from "../skill-mcp-manager/types"
@@ -187,13 +187,14 @@ export async function loadProjectSkills(): Promise<Record<string, CommandDefinit
}
export async function loadOpencodeGlobalSkills(): Promise<Record<string, CommandDefinition>> {
const opencodeSkillsDir = join(homedir(), ".config", "opencode", "skill")
const configDir = getOpenCodeConfigDir({ binary: "opencode" })
const opencodeSkillsDir = join(configDir, "skills")
const skills = await loadSkillsFromDir(opencodeSkillsDir, "opencode")
return skillsToRecord(skills)
}
export async function loadOpencodeProjectSkills(): Promise<Record<string, CommandDefinition>> {
const opencodeProjectDir = join(process.cwd(), ".opencode", "skill")
const opencodeProjectDir = join(process.cwd(), ".opencode", "skills")
const skills = await loadSkillsFromDir(opencodeProjectDir, "opencode-project")
return skillsToRecord(skills)
}
@@ -249,11 +250,12 @@ export async function discoverProjectClaudeSkills(): Promise<LoadedSkill[]> {
}
export async function discoverOpencodeGlobalSkills(): Promise<LoadedSkill[]> {
const opencodeSkillsDir = join(homedir(), ".config", "opencode", "skill")
const configDir = getOpenCodeConfigDir({ binary: "opencode" })
const opencodeSkillsDir = join(configDir, "skills")
return loadSkillsFromDir(opencodeSkillsDir, "opencode")
}
export async function discoverOpencodeProjectSkills(): Promise<LoadedSkill[]> {
const opencodeProjectDir = join(process.cwd(), ".opencode", "skill")
const opencodeProjectDir = join(process.cwd(), ".opencode", "skills")
return loadSkillsFromDir(opencodeProjectDir, "opencode-project")
}

View File

@@ -18,7 +18,7 @@ export interface SkillInfo {
}
export interface SkillLoadOptions {
/** When true, only load from OpenCode paths (.opencode/skill/, ~/.config/opencode/skill/) */
/** When true, only load from OpenCode paths (.opencode/skills/, ~/.config/opencode/skills/) */
opencodeOnly?: boolean
/** Pre-merged skills to use instead of discovering */
skills?: LoadedSkill[]