diff --git a/src/lib/config-handler.ts b/src/lib/config-handler.ts index 32f7bba..f4a639d 100644 --- a/src/lib/config-handler.ts +++ b/src/lib/config-handler.ts @@ -252,5 +252,23 @@ export function createConfigHandler(deps: ConfigHandlerDeps) { ...bundledSkills, ...existingCommands, } + + // skills.paths exists at runtime (v2 SDK types) but not in our v1 import + registerSkillsPaths(config, bundledSkillsDir) + } +} + +// Config.skills exists in v2 SDK types but not v1 — bridge until import upgrade +type ConfigWithSkills = Config & { + skills?: { paths?: string[] } +} + +/** Register a directory for OpenCode's native skill discovery (`skill` tool). */ +export function registerSkillsPaths(config: Config, skillsDir: string): void { + const extended = config as ConfigWithSkills + extended.skills ??= {} + extended.skills.paths ??= [] + if (!extended.skills.paths.includes(skillsDir)) { + extended.skills.paths.push(skillsDir) } } diff --git a/tests/integration/opencode.test.ts b/tests/integration/opencode.test.ts index f05b3df..5d3cf57 100644 --- a/tests/integration/opencode.test.ts +++ b/tests/integration/opencode.test.ts @@ -263,6 +263,60 @@ Integration test content.`, 'description: A skill for integration testing', ) }) + + test('registers bundled skills dir in config.skills.paths', async () => { + const skillsDir = path.join(testEnv.bundledDir, 'skills') + const handler = createConfigHandler({ + directory: testEnv.projectDir, + bundledSkillsDir: skillsDir, + bundledAgentsDir: path.join(testEnv.bundledDir, 'agents'), + bundledCommandsDir: path.join(testEnv.bundledDir, 'commands'), + }) + + const config: Config = {} + await handler(config) + + const extended = config as Config & { skills?: { paths?: string[] } } + expect(extended.skills?.paths).toContain(skillsDir) + }) + + test('preserves existing skills.paths entries', async () => { + const skillsDir = path.join(testEnv.bundledDir, 'skills') + const handler = createConfigHandler({ + directory: testEnv.projectDir, + bundledSkillsDir: skillsDir, + bundledAgentsDir: path.join(testEnv.bundledDir, 'agents'), + bundledCommandsDir: path.join(testEnv.bundledDir, 'commands'), + }) + + const existingPath = '/some/other/skills' + const config = { skills: { paths: [existingPath] } } as Config & { + skills?: { paths?: string[] } + } + await handler(config as Config) + + const extended = config as Config & { skills?: { paths?: string[] } } + expect(extended.skills?.paths).toContain(existingPath) + expect(extended.skills?.paths).toContain(skillsDir) + }) + + test('does not duplicate skills.paths on repeated calls', async () => { + const skillsDir = path.join(testEnv.bundledDir, 'skills') + const handler = createConfigHandler({ + directory: testEnv.projectDir, + bundledSkillsDir: skillsDir, + bundledAgentsDir: path.join(testEnv.bundledDir, 'agents'), + bundledCommandsDir: path.join(testEnv.bundledDir, 'commands'), + }) + + const config: Config = {} + await handler(config) + await handler(config) + + const extended = config as Config & { skills?: { paths?: string[] } } + const count = extended.skills?.paths?.filter((p) => p === skillsDir).length + expect(count).toBe(1) + }) }) describe('opencode availability check', () => {