import { expect, test } from "bun:test"; import type { Plugin } from "@opencode/plugin"; import type { Context } from "@opencode/plugin/effect/plugin"; import { Effect } from "effect"; import quota from "../src/quota-plugin.js"; import multiWork from "../src/multi-work.js"; import { QuotaRpc } from "../src/quota-rpc.js"; import { AgentsRpc } from "../src/agents-rpc.js"; test("Quota loads independently and retains its RPC ID and nullable status", async () => { let controller: ReadableStreamDefaultController; const stream = new ReadableStream({ start(value) { controller = value; }, }); let status: (() => Promise) | undefined; let disposed = false; let modelHook = false; const context = { options: {}, location: { directory: "/fixture" }, integration: { connection: { async active() { return undefined; }, }, }, event: { subscribe({ signal }: { signal: AbortSignal }) { signal.addEventListener("abort", () => controller.close(), { once: true }); return stream; }, }, rpc: { async register(definition: typeof QuotaRpc, handlers: { status: () => Promise }) { expect(definition.id).toBe("stanp-opencode.quota"); status = handlers.status; return { async dispose() { disposed = true; }, events: { async emit() {} }, }; }, }, session: { async hook(name: string) { expect(name).toBe("model.request"); modelHook = true; return { async dispose() {} }; }, }, }; // SAFETY: Quota with no credentials uses only these native host services. // Absent agent/model/MCP APIs fail if independence regresses. const setup = quota.setup as ( context: Pick, ) => ReturnType; const cleanup = await setup(context); expect(quota.id).toBe("stanp-opencode.quota"); expect(await status!()).toBeNull(); expect(modelHook).toBe(true); if (cleanup) await cleanup(); expect(disposed).toBe(true); }); test("Multi-work rejects missing Agents before any Herdr operations or registrations", async () => { const context = { rpc: (definition: typeof AgentsRpc) => { expect(definition.id).toBe("stanp-opencode.agents"); return { permissions: () => Effect.fail(new Error("RPC not registered")) }; }, }; // SAFETY: Missing Agents fails at the first RPC call; no other host service is accessed. const activate = multiWork.effect as ( context: Pick, ) => ReturnType; const result = await Effect.runPromiseExit( Effect.scoped(activate({ ...context, options: {} })), ); expect(String(result)).toContain("Multi-work requires Agents loaded before it"); });