skill.test.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import path from "path"
  2. import { describe, expect } from "bun:test"
  3. import { Effect, Layer, Schema } from "effect"
  4. import { Config } from "@opencode-ai/core/config"
  5. import { ConfigSkillPlugin } from "@opencode-ai/core/config/plugin/skill"
  6. import { Global } from "@opencode-ai/core/global"
  7. import { Location } from "@opencode-ai/core/location"
  8. import { AbsolutePath } from "@opencode-ai/core/schema"
  9. import { SkillV2 } from "@opencode-ai/core/skill"
  10. import { location } from "../fixture/location"
  11. import { testEffect } from "../lib/effect"
  12. const it = testEffect(Layer.empty)
  13. const decode = Schema.decodeUnknownSync(Config.Info)
  14. describe("ConfigSkillPlugin.Plugin", () => {
  15. it.effect("registers configured skill directories and URLs", () =>
  16. Effect.gen(function* () {
  17. const directory = AbsolutePath.make("/repo/packages/app")
  18. const sources: SkillV2.Source[] = []
  19. const transform = Effect.fnUntraced(function* () {
  20. return Effect.fnUntraced(function* (update: (editor: SkillV2.Editor) => void) {
  21. update({
  22. source: (source) => sources.push(source),
  23. list: () => sources,
  24. })
  25. })
  26. })
  27. yield* ConfigSkillPlugin.Plugin.effect.pipe(
  28. Effect.provideService(
  29. Config.Service,
  30. Config.Service.of({
  31. entries: () =>
  32. Effect.succeed([
  33. new Config.Document({
  34. type: "document",
  35. info: decode({
  36. skills: ["./skills", "~/shared-skills", "/opt/skills", "https://example.test/skills/"],
  37. }),
  38. }),
  39. ]),
  40. }),
  41. ),
  42. Effect.provideService(Global.Service, Global.Service.of(Global.make({ home: "/home/test" }))),
  43. Effect.provideService(Location.Service, Location.Service.of(location({ directory }))),
  44. Effect.provideService(
  45. SkillV2.Service,
  46. SkillV2.Service.of({
  47. transform,
  48. sources: () => Effect.succeed(sources),
  49. list: () => Effect.succeed([]),
  50. forAgent: () => Effect.succeed([]),
  51. }),
  52. ),
  53. )
  54. expect(sources).toEqual([
  55. new SkillV2.DirectorySource({ type: "directory", path: AbsolutePath.make(path.join(directory, "skills")) }),
  56. new SkillV2.DirectorySource({
  57. type: "directory",
  58. path: AbsolutePath.make(path.join("/home/test", "shared-skills")),
  59. }),
  60. new SkillV2.DirectorySource({ type: "directory", path: AbsolutePath.make("/opt/skills") }),
  61. new SkillV2.UrlSource({ type: "url", url: "https://example.test/skills/" }),
  62. ])
  63. }),
  64. )
  65. })