فهرست منبع

fix(core): disable external plugin hot reload

Dax Raad 1 ماه پیش
والد
کامیت
8e0856c43b
2فایلهای تغییر یافته به همراه5 افزوده شده و 26 حذف شده
  1. 2 19
      packages/core/src/config/plugin/external.ts
  2. 3 7
      packages/core/test/config/reload.test.ts

+ 2 - 19
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<string>()
     const load = Effect.fn("ConfigExternalPlugin.load")(function* () {
       const configured: { package: string; options?: Record<string, unknown> }[] = []
 
@@ -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)
   }),
 })
 

+ 3 - 7
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()))),
   )
 })