plugin-agent-regression.test.ts 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import { expect } from "bun:test"
  2. import { FSUtil } from "@opencode-ai/core/fs-util"
  3. import { LocationServiceMap, locationServiceMapLayer } from "@opencode-ai/core/location-layer"
  4. import { Effect, Layer } from "effect"
  5. import { FetchHttpClient } from "effect/unstable/http"
  6. import path from "path"
  7. import { pathToFileURL } from "url"
  8. import { Agent } from "../../src/agent/agent"
  9. import { EventV2Bridge } from "../../src/event-v2-bridge"
  10. import { Config } from "../../src/config/config"
  11. import { Env } from "../../src/env"
  12. import { RuntimeFlags } from "../../src/effect/runtime-flags"
  13. import { Plugin } from "../../src/plugin"
  14. import { AccountTest } from "../fake/account"
  15. import { AuthTest } from "../fake/auth"
  16. import { NpmTest } from "../fake/npm"
  17. import { ProviderTest } from "../fake/provider"
  18. import { SkillTest } from "../fake/skill"
  19. import { testEffect } from "../lib/effect"
  20. import { PLUGIN_AGENT } from "../fixture/agent-plugin.constants"
  21. // `it.instance` skips InstanceBootstrap so LSP / MCP don't spin up — those
  22. // services hang during scope teardown on Windows and aren't needed
  23. // to verify plugin → config hook → Agent.list.
  24. const pluginUrl = pathToFileURL(path.join(import.meta.dir, "..", "fixture", "agent-plugin.ts")).href
  25. const provider = ProviderTest.fake()
  26. const configLayer = Config.layer.pipe(
  27. Layer.provide(FSUtil.defaultLayer),
  28. Layer.provide(Env.defaultLayer),
  29. Layer.provide(AuthTest.empty),
  30. Layer.provide(AccountTest.empty),
  31. Layer.provide(NpmTest.noop),
  32. Layer.provide(FetchHttpClient.layer),
  33. )
  34. const pluginLayer = Plugin.layer.pipe(
  35. Layer.provide(EventV2Bridge.defaultLayer),
  36. Layer.provide(configLayer),
  37. Layer.provide(RuntimeFlags.layer({ disableDefaultPlugins: true })),
  38. )
  39. const agentLayer = Agent.layer.pipe(
  40. Layer.provide(configLayer),
  41. Layer.provide(AuthTest.empty),
  42. Layer.provide(SkillTest.empty),
  43. Layer.provide(provider.layer),
  44. Layer.provide(pluginLayer),
  45. Layer.provide(locationServiceMapLayer),
  46. Layer.provide(RuntimeFlags.layer({ disableDefaultPlugins: true })),
  47. )
  48. const it = testEffect(Layer.mergeAll(agentLayer, pluginLayer))
  49. it.instance(
  50. "plugin-registered agents appear in Agent.list",
  51. () =>
  52. Effect.gen(function* () {
  53. yield* Plugin.Service.use((p) => p.init())
  54. const agents = yield* Agent.use.list()
  55. const added = agents.find((agent) => agent.name === PLUGIN_AGENT.name)
  56. expect(added?.description).toBe(PLUGIN_AGENT.description)
  57. expect(added?.mode).toBe(PLUGIN_AGENT.mode)
  58. }),
  59. { config: { plugin: [pluginUrl] } },
  60. )