fix(skill): pass directory to getAllSkills and fix async test timing

This commit is contained in:
Sami Jawhar
2026-04-03 20:43:18 +00:00
parent f540249838
commit d2d1541377
5 changed files with 27 additions and 7 deletions
@@ -12,7 +12,8 @@ export function clearSkillCache(): void {
export async function getAllSkills(options?: SkillResolutionOptions): Promise<LoadedSkill[]> {
const browserProvider = options?.browserProvider ?? "playwright"
const teamModeEnabled = options?.teamModeEnabled ?? false
const cacheKey = `${browserProvider}:${teamModeEnabled ? "team-on" : "team-off"}`
const directory = options?.directory ?? ""
const cacheKey = `${directory}:${browserProvider}:${teamModeEnabled ? "team-on" : "team-off"}`
const hasDisabledSkills = options?.disabledSkills && options.disabledSkills.size > 0
// Skip cache if disabledSkills is provided (varies between calls)
+1
View File
@@ -273,6 +273,7 @@ export function createToolRegistry(args: {
enabledPluginsOverride: pluginConfig.claude_code?.plugins_override,
})
const skillTool = factories.createSkillTool({
directory: ctx.directory,
commands,
skills: skillContext.mergedSkills,
mcpManager: managers.skillMcpManager,
@@ -1,6 +1,10 @@
/// <reference types="bun-types" />
import { describe, expect, it } from "bun:test"
import { describe, expect, it, beforeEach, afterEach } from "bun:test"
import { mkdtempSync, rmSync } from "node:fs"
import { join } from "node:path"
import { tmpdir } from "node:os"
import { createSkillTool } from "./tools"
import type { LoadedSkill } from "../../features/opencode-skill-loader/types"
function requireFresh<T>(modulePath: string): T {
@@ -11,7 +15,7 @@ function requireFresh<T>(modulePath: string): T {
return require(modulePath) as T
}
function createSkillTool(...args: Parameters<typeof import("./tools").createSkillTool>): ReturnType<typeof import("./tools").createSkillTool> {
function createFreshSkillTool(...args: Parameters<typeof import("./tools").createSkillTool>): ReturnType<typeof import("./tools").createSkillTool> {
return requireFresh<typeof import("./tools")>("./tools").createSkillTool(...args)
}
@@ -35,17 +39,28 @@ async function waitForRefresh(predicate: () => boolean): Promise<void> {
return
}
await new Promise<void>((resolve) => setTimeout(resolve, 10))
await new Promise<void>((resolve) => setTimeout(resolve, 50))
}
throw new Error("Timed out waiting for async skill description refresh")
}
describe("skill tool - async native skill description refresh", () => {
let testDir: string
beforeEach(() => {
testDir = mkdtempSync(join(tmpdir(), "skill-async-test-"))
})
afterEach(() => {
rmSync(testDir, { recursive: true, force: true })
})
it("updates description after async native skills resolve", async () => {
//#given
let allCallCount = 0
const tool = createSkillTool({
const tool = createFreshSkillTool({
directory: testDir,
skills: [createMockSkill("seeded-skill")],
commands: [],
nativeSkills: {
+3 -2
View File
@@ -25,7 +25,7 @@ import {
mergeNativeSkills,
} from "./native-skills"
export function createSkillTool(options: SkillLoadOptions = {}): ToolDefinition {
export function createSkillTool(options: SkillLoadOptions): ToolDefinition {
let cachedDescription: string | null = null
const getSkills = async (context?: ToolContext): Promise<LoadedSkill[]> => {
@@ -37,6 +37,7 @@ export function createSkillTool(options: SkillLoadOptions = {}): ToolDefinition
disabledSkills: options?.disabledSkills,
browserProvider: options?.browserProvider,
teamModeEnabled: options?.teamModeEnabled,
directory: options.directory,
})) ?? []
const allSkills = options.skills ? [...options.skills] : discovered
@@ -191,4 +192,4 @@ export function createSkillTool(options: SkillLoadOptions = {}): ToolDefinition
})
}
export const skill: ToolDefinition = createSkillTool()
export const skill: ToolDefinition = createSkillTool({ directory: process.cwd() })
+2
View File
@@ -33,6 +33,8 @@ export interface SkillLoadOptions {
/** Git master configuration for watermark/co-author settings */
gitMasterConfig?: GitMasterConfig
disabledSkills?: Set<string>
/** Project directory for skill discovery and base directory resolution. Must be ctx.directory from PluginContext — process.cwd() is unsafe in OpenCode. */
directory: string
/** Browser automation provider for provider-gated skill filtering */
browserProvider?: BrowserAutomationProvider
/** Whether team mode built-in docs should be exposed */