diff --git a/packages/core/src/config/plugin/external.ts b/packages/core/src/config/plugin/external.ts index c67f67d4811..70271dec23f 100644 --- a/packages/core/src/config/plugin/external.ts +++ b/packages/core/src/config/plugin/external.ts @@ -2,7 +2,7 @@ export * as ConfigExternalPlugin from "./external" import type { Plugin as EffectPlugin } from "@opencode-ai/plugin/v2/effect" import type { Plugin as PromisePlugin } from "@opencode-ai/plugin/v2/promise" -import { Effect, Schema, Stream } from "effect" +import { Effect, Schema } from "effect" import path from "path" import { fileURLToPath, pathToFileURL } from "url" import { Config } from "../../config" @@ -42,7 +42,6 @@ export const Plugin = define({ const fs = yield* FSUtil.Service const location = yield* Location.Service const npm = yield* Npm.Service - const active = new Set() const load = Effect.fn("ConfigExternalPlugin.load")(function* () { const configured: { package: string; options?: Record }[] = [] @@ -117,23 +116,7 @@ export const Plugin = define({ }).pipe(Effect.catchCause(() => Effect.succeed(undefined))), ).pipe(Effect.map((plugins) => plugins.filter((plugin) => plugin !== undefined))) }) - const reconcile = Effect.fn("ConfigExternalPlugin.reconcile")(function* () { - const plugins = yield* load() - const next = new Set(plugins.map((plugin) => plugin.id)) - for (const id of active) { - if (!next.has(id)) yield* ctx.plugin.remove(id) - } - for (const plugin of plugins) yield* ctx.plugin.add(plugin) - active.clear() - for (const id of next) active.add(id) - }) - - yield* reconcile() - yield* ctx.event.subscribe().pipe( - Stream.filter((event) => event.type === "config.updated"), - Stream.runForEach(() => reconcile()), - Effect.forkScoped({ startImmediately: true }), - ) + for (const plugin of yield* load()) yield* ctx.plugin.add(plugin) }), }) diff --git a/packages/core/test/config/reload.test.ts b/packages/core/test/config/reload.test.ts index 0ee2f0467e6..3550bddb95a 100644 --- a/packages/core/test/config/reload.test.ts +++ b/packages/core/test/config/reload.test.ts @@ -27,7 +27,7 @@ const decode = Schema.decodeUnknownSync(Config.Info) const document = path.join(import.meta.dir, "opencode.json") describe("config plugin reloads", () => { - it.live("reloads every config-backed domain", () => + it.live("reloads config-backed domains without reloading external plugins", () => Effect.gen(function* () { const agents = yield* AgentV2.Service const catalog = yield* Catalog.Service @@ -69,8 +69,7 @@ describe("config plugin reloads", () => { (yield* commands.get("second"))?.description === "Second command" && (yield* references.list()).some((reference) => reference.name === "second") && (yield* catalog.provider.get(ProviderV2.ID.make("first"))) === undefined && - (yield* catalog.provider.get(ProviderV2.ID.make("second"))) !== undefined && - (yield* agents.get(AgentV2.ID.make("configured")))?.description === "Second plugin" + (yield* catalog.provider.get(ProviderV2.ID.make("second"))) !== undefined ) }), ) @@ -81,10 +80,7 @@ describe("config plugin reloads", () => { expect( (yield* skills.sources()).some((source) => source.type === "directory" && source.path === "/skills/second"), ).toBe(true) - - entries = [config("second")] - yield* events.publish(ConfigSchema.Event.Updated, {}) - yield* waitUntil(agents.get(AgentV2.ID.make("configured")).pipe(Effect.map((agent) => agent === undefined))) + expect((yield* agents.get(AgentV2.ID.make("configured")))?.description).toBe("First plugin") }).pipe(Effect.provideService(Global.Service, Global.Service.of(Global.make()))), ) })