Download packages/core/test/config/plugin.test.ts from SaylorTwift/opencode: direct link, hf CLI and curl.
- Browser
- Download file 8.76 kB
-
https://huggingface.co/SaylorTwift/opencode/resolve/main/packages/core/test/config/plugin.test.ts
- Command line
-
hf download hf://SaylorTwift/opencode/packages/core/test/config/plugin.test.ts
-
curl -L -o plugin.test.ts https://huggingface.co/SaylorTwift/opencode/resolve/main/packages/core/test/config/plugin.test.ts
8.76 kB
| import path from "path" | |
| import { describe, expect } from "bun:test" | |
| import { Effect, Schema } from "effect" | |
| import { AgentV2 } from "@opencode-ai/core/agent" | |
| import { Config } from "@opencode-ai/core/config" | |
| import { ConfigExternalPlugin } from "@opencode-ai/core/config/plugin/external" | |
| import { FSUtil } from "@opencode-ai/core/fs-util" | |
| import { Location } from "@opencode-ai/core/location" | |
| import { Npm } from "@opencode-ai/core/npm" | |
| import { PluginV2 } from "@opencode-ai/core/plugin" | |
| import { PluginHost } from "@opencode-ai/core/plugin/host" | |
| import { AbsolutePath } from "@opencode-ai/core/schema" | |
| import { testEffect } from "../lib/effect" | |
| import { PluginTestLayer } from "../plugin/fixture" | |
| const it = testEffect(PluginTestLayer) | |
| const decode = Schema.decodeUnknownSync(Config.Info) | |
| describe("ConfigExternalPlugin", () => { | |
| it.live("resolves and loads a configured Promise plugin with options", () => | |
| Effect.gen(function* () { | |
| const plugins = yield* PluginV2.Service | |
| const agents = yield* AgentV2.Service | |
| const fs = yield* FSUtil.Service | |
| const location = yield* Location.Service | |
| const npm = yield* Npm.Service | |
| const host = yield* PluginHost.make(plugins) | |
| const document = path.join(import.meta.dir, "opencode.json") | |
| yield* ConfigExternalPlugin.Plugin.effect(host).pipe( | |
| Effect.provideService(PluginV2.Service, plugins), | |
| Effect.provideService(FSUtil.Service, fs), | |
| Effect.provideService(Location.Service, location), | |
| Effect.provideService(Npm.Service, npm), | |
| Effect.provideService( | |
| Config.Service, | |
| Config.Service.of({ | |
| entries: () => | |
| Effect.succeed([ | |
| new Config.Document({ | |
| type: "document", | |
| path: document, | |
| info: decode({ | |
| plugins: [ | |
| { | |
| package: "../plugin/fixtures/config-promise-plugin.ts", | |
| options: { description: "Loaded from config" }, | |
| }, | |
| ], | |
| }), | |
| }), | |
| ]), | |
| }), | |
| ), | |
| ) | |
| expect(yield* waitForAgent(agents, "configured")).toMatchObject({ | |
| description: "Loaded from config", | |
| mode: "subagent", | |
| }) | |
| }), | |
| ) | |
| it.live("loads a configured Effect plugin with options", () => | |
| Effect.gen(function* () { | |
| const plugins = yield* PluginV2.Service | |
| const agents = yield* AgentV2.Service | |
| const fs = yield* FSUtil.Service | |
| const location = yield* Location.Service | |
| const npm = yield* Npm.Service | |
| const host = yield* PluginHost.make(plugins) | |
| yield* ConfigExternalPlugin.Plugin.effect(host).pipe( | |
| Effect.provideService(PluginV2.Service, plugins), | |
| Effect.provideService(FSUtil.Service, fs), | |
| Effect.provideService(Location.Service, location), | |
| Effect.provideService(Npm.Service, npm), | |
| Effect.provideService( | |
| Config.Service, | |
| Config.Service.of({ | |
| entries: () => | |
| Effect.succeed([ | |
| new Config.Document({ | |
| type: "document", | |
| path: path.join(import.meta.dir, "opencode.json"), | |
| info: decode({ | |
| plugins: [ | |
| { | |
| package: "../plugin/fixtures/config-effect-plugin.ts", | |
| options: { description: "Effect plugin from config" }, | |
| }, | |
| ], | |
| }), | |
| }), | |
| ]), | |
| }), | |
| ), | |
| ) | |
| expect(yield* waitForAgent(agents, "effect-configured")).toMatchObject({ | |
| description: "Effect plugin from config", | |
| mode: "subagent", | |
| }) | |
| }), | |
| ) | |
| it.live("ignores invalid plugins and continues loading", () => | |
| Effect.gen(function* () { | |
| const plugins = yield* PluginV2.Service | |
| const agents = yield* AgentV2.Service | |
| const fs = yield* FSUtil.Service | |
| const location = yield* Location.Service | |
| const npm = yield* Npm.Service | |
| const host = yield* PluginHost.make(plugins) | |
| yield* ConfigExternalPlugin.Plugin.effect(host).pipe( | |
| Effect.provideService(PluginV2.Service, plugins), | |
| Effect.provideService(FSUtil.Service, fs), | |
| Effect.provideService(Location.Service, location), | |
| Effect.provideService(Npm.Service, npm), | |
| Effect.provideService( | |
| Config.Service, | |
| Config.Service.of({ | |
| entries: () => | |
| Effect.succeed([ | |
| new Config.Document({ | |
| type: "document", | |
| path: path.join(import.meta.dir, "opencode.json"), | |
| info: decode({ | |
| plugins: [ | |
| "../plugin/fixtures/missing-plugin.ts", | |
| "../plugin/fixtures/invalid-plugin.ts", | |
| { | |
| package: "../plugin/fixtures/config-promise-plugin.ts", | |
| options: { description: "Loaded after invalid plugins" }, | |
| }, | |
| ], | |
| }), | |
| }), | |
| ]), | |
| }), | |
| ), | |
| ) | |
| expect(yield* waitForAgent(agents, "configured")).toMatchObject({ | |
| description: "Loaded after invalid plugins", | |
| }) | |
| }), | |
| ) | |
| it.live("installs and resolves npm plugin packages", () => | |
| Effect.gen(function* () { | |
| const plugins = yield* PluginV2.Service | |
| const agents = yield* AgentV2.Service | |
| const fs = yield* FSUtil.Service | |
| const location = yield* Location.Service | |
| const host = yield* PluginHost.make(plugins) | |
| let installed: string | undefined | |
| const npm = Npm.Service.of({ | |
| add: (spec) => | |
| Effect.sync(() => { | |
| installed = spec | |
| return { | |
| directory: import.meta.dir, | |
| entrypoint: path.join(import.meta.dir, "../plugin/fixtures/config-promise-plugin.ts"), | |
| } | |
| }), | |
| install: () => Effect.void, | |
| which: () => Effect.succeed(undefined), | |
| }) | |
| yield* ConfigExternalPlugin.Plugin.effect(host).pipe( | |
| Effect.provideService(PluginV2.Service, plugins), | |
| Effect.provideService(FSUtil.Service, fs), | |
| Effect.provideService(Location.Service, location), | |
| Effect.provideService(Npm.Service, npm), | |
| Effect.provideService( | |
| Config.Service, | |
| Config.Service.of({ | |
| entries: () => | |
| Effect.succeed([ | |
| new Config.Document({ | |
| type: "document", | |
| info: decode({ | |
| plugins: [ | |
| { | |
| package: "example-plugin@1.0.0", | |
| options: { description: "Installed from npm" }, | |
| }, | |
| ], | |
| }), | |
| }), | |
| ]), | |
| }), | |
| ), | |
| ) | |
| expect(yield* waitForAgent(agents, "configured")).toMatchObject({ | |
| description: "Installed from npm", | |
| }) | |
| expect(installed).toBe("example-plugin@1.0.0") | |
| }), | |
| ) | |
| it.live("loads plugin files from config directories", () => | |
| Effect.gen(function* () { | |
| const plugins = yield* PluginV2.Service | |
| const agents = yield* AgentV2.Service | |
| const fs = yield* FSUtil.Service | |
| const location = yield* Location.Service | |
| const npm = yield* Npm.Service | |
| const host = yield* PluginHost.make(plugins) | |
| yield* ConfigExternalPlugin.Plugin.effect(host).pipe( | |
| Effect.provideService(PluginV2.Service, plugins), | |
| Effect.provideService(FSUtil.Service, fs), | |
| Effect.provideService(Location.Service, location), | |
| Effect.provideService(Npm.Service, npm), | |
| Effect.provideService( | |
| Config.Service, | |
| Config.Service.of({ | |
| entries: () => | |
| Effect.succeed([ | |
| new Config.Directory({ | |
| type: "directory", | |
| path: AbsolutePath.make(path.join(import.meta.dir, "fixtures")), | |
| }), | |
| ]), | |
| }), | |
| ), | |
| ) | |
| expect(yield* waitForAgent(agents, "directory")).toMatchObject({ | |
| description: "Loaded from plugin directory", | |
| mode: "subagent", | |
| }) | |
| }), | |
| ) | |
| }) | |
| const waitForAgent = Effect.fnUntraced(function* (agents: AgentV2.Interface, id: string) { | |
| for (let attempt = 0; attempt < 100; attempt++) { | |
| const agent = yield* agents.get(AgentV2.ID.make(id)) | |
| if (agent) return agent | |
| yield* Effect.sleep("10 millis") | |
| } | |
| return yield* Effect.die(`Timed out waiting for agent ${id}`) | |
| }) | |