import { describe, expect } from "bun:test" import { Effect, Exit, Fiber } from "effect" import { define } from "@opencode-ai/plugin/v2/effect" import { AgentV2 } from "@opencode-ai/core/agent" import { PluginV2 } from "@opencode-ai/core/plugin" import { testEffect } from "./lib/effect" import { PluginTestLayer } from "./plugin/fixture" const it = testEffect(PluginTestLayer) describe("PluginV2", () => { it.effect("waits for a plugin and returns immediately once active", () => Effect.gen(function* () { const plugins = yield* PluginV2.Service const id = PluginV2.ID.make("waited") const waiting = yield* plugins.wait(id).pipe(Effect.forkChild) yield* plugins.add(id, () => Effect.void) yield* Fiber.join(waiting) yield* plugins.wait(id) }), ) it.effect("propagates plugin activation defects to waiters", () => Effect.gen(function* () { const plugins = yield* PluginV2.Service const id = PluginV2.ID.make("failed") const waiting = yield* plugins.wait(id).pipe(Effect.exit, Effect.forkChild) const added = yield* plugins.add(id, () => Effect.die("boom")).pipe(Effect.exit) const pending = yield* Fiber.join(waiting) const later = yield* plugins.wait(id).pipe(Effect.exit) expect(Exit.isFailure(added)).toBe(true) expect(Exit.isFailure(pending)).toBe(true) expect(Exit.isFailure(later)).toBe(true) }), ) it.effect("adds, replaces, and removes plugins", () => Effect.gen(function* () { const plugins = yield* PluginV2.Service const agents = yield* AgentV2.Service let description = "first" const managed = () => define({ id: "managed", effect: (ctx) => ctx.agent .transform((agents) => agents.update("configured", (agent) => { agent.description = description }), ) .pipe(Effect.asVoid), }) yield* plugins.add(PluginV2.ID.make("managed"), managed().effect) expect((yield* agents.get(AgentV2.ID.make("configured")))?.description).toBe("first") description = "second" yield* plugins.add(PluginV2.ID.make("managed"), managed().effect) expect((yield* agents.get(AgentV2.ID.make("configured")))?.description).toBe("second") yield* plugins.remove(PluginV2.ID.make("managed")) expect(yield* agents.get(AgentV2.ID.make("configured"))).toBeUndefined() }), ) })