From a7ce39e75877455a035a16ae54eb7d0ea10f96ca Mon Sep 17 00:00:00 2001 From: Sami Jawhar Date: Fri, 3 Apr 2026 20:56:47 +0000 Subject: [PATCH] fix(skill): read plugin-modified config for skills.paths discovery Plugin config() hooks that mutate cfg.skills.paths (e.g. superpowers) were invisible to skill discovery because each service's makeRuntime creates a separate InstanceState scope. Plugin.config() now exposes the post-hook config as the single source of truth. --- packages/opencode/src/plugin/index.ts | 15 +++++++++++++-- packages/opencode/src/skill/index.ts | 6 +++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/opencode/src/plugin/index.ts b/packages/opencode/src/plugin/index.ts index 814e7870a44e..56486956dbc2 100644 --- a/packages/opencode/src/plugin/index.ts +++ b/packages/opencode/src/plugin/index.ts @@ -23,6 +23,7 @@ export namespace Plugin { type State = { hooks: Hooks[] + config: Config.Info } // Hook names that follow the (input, output) => Promise trigger pattern @@ -41,6 +42,7 @@ export namespace Plugin { output: Output, ) => Effect.Effect readonly list: () => Effect.Effect + readonly config: () => Effect.Effect readonly init: () => Effect.Effect } @@ -237,7 +239,7 @@ export namespace Plugin { Effect.forkScoped, ) - return { hooks } + return { hooks, config: cfg } }), ) @@ -261,11 +263,16 @@ export namespace Plugin { return s.hooks }) + const cfg = Effect.fn("Plugin.config")(function* () { + const s = yield* InstanceState.get(state) + return s.config + }) + const init = Effect.fn("Plugin.init")(function* () { yield* InstanceState.get(state) }) - return Service.of({ trigger, list, init }) + return Service.of({ trigger, list, config: cfg, init }) }), ) @@ -287,4 +294,8 @@ export namespace Plugin { export async function init() { return runPromise((svc) => svc.init()) } + + export async function config(): Promise { + return runPromise((svc) => svc.config()) + } } diff --git a/packages/opencode/src/skill/index.ts b/packages/opencode/src/skill/index.ts index cde36dd52d07..3e02b17d68e0 100644 --- a/packages/opencode/src/skill/index.ts +++ b/packages/opencode/src/skill/index.ts @@ -164,7 +164,11 @@ export namespace Skill { yield* scan(state, bus, dir, OPENCODE_SKILL_PATTERN) } - const cfg = yield* config.get() + // Read config that includes plugin config() hook mutations. + // Plugin.config() returns the config after all plugins' config() hooks + // have run, so skills.paths includes plugin-registered directories. + const { Plugin } = yield* Effect.promise(() => import("../plugin")) + const cfg = yield* Effect.promise(() => Plugin.config()) for (const item of cfg.skills?.paths ?? []) { const expanded = item.startsWith("~/") ? path.join(os.homedir(), item.slice(2)) : item const dir = path.isAbsolute(expanded) ? expanded : path.join(directory, expanded)