From 391aa382810e2eb9d408e92c7e9ffc16d33248fd Mon Sep 17 00:00:00 2001 From: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Date: Sun, 5 Jul 2026 10:40:55 -0500 Subject: [PATCH] test(core): serve skill fixtures locally (#35429) --- packages/core/test/skill-discovery.test.ts | 143 +++++++++++---------- 1 file changed, 77 insertions(+), 66 deletions(-) diff --git a/packages/core/test/skill-discovery.test.ts b/packages/core/test/skill-discovery.test.ts index e875beb931..28071c926f 100644 --- a/packages/core/test/skill-discovery.test.ts +++ b/packages/core/test/skill-discovery.test.ts @@ -1,36 +1,42 @@ import fs from "fs/promises" import path from "path" import { describe, expect, test } from "bun:test" -import { Effect, Layer } from "effect" -import { HttpClient, HttpClientResponse } from "effect/unstable/http" +import { Effect } from "effect" import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder" -import { LayerNodePlatform } from "@opencode-ai/core/effect/app-node-platform" -import { LayerNode } from "@opencode-ai/core/effect/layer-node" import { Global } from "@opencode-ai/core/global" import { SkillDiscovery } from "@opencode-ai/core/skill/discovery" import { tmpdir } from "./fixture/tmpdir" -const base = "https://skills.example.test/catalog/" +type Fixture = { + tmp: Awaited> + server: Bun.Server + state: { + skills: unknown[] + files: Record + requests: string[] + } + base: string +} -async function pull(skills: unknown[], files: Record = {}, cache?: Awaited>) { - const tmp = cache ?? (await tmpdir()) - const requests: string[] = [] - const http = Layer.succeed( - HttpClient.HttpClient, - HttpClient.make((request) => - Effect.sync(() => requests.push(request.url)).pipe( - Effect.map(() => { - const body = request.url === `${base}index.json` ? JSON.stringify({ skills }) : files[request.url] - return HttpClientResponse.fromWeb( - request, - new Response(body ?? "Not Found", { status: body === undefined ? 404 : 200 }), - ) - }), - ), - ), - ) +async function pull(skills: unknown[], files: Record = {}, fixture?: Fixture) { + const state = fixture?.state ?? { skills, files, requests: [] } + state.skills = skills + state.files = files + state.requests = [] + const server = + fixture?.server ?? + Bun.serve({ + port: 0, + fetch(request) { + state.requests.push(request.url) + const pathname = new URL(request.url).pathname + const body = pathname === "/catalog/index.json" ? JSON.stringify({ skills: state.skills }) : state.files[pathname] + return new Response(body ?? "Not Found", { status: body === undefined ? 404 : 200 }) + }, + }) + const tmp = fixture?.tmp ?? (await tmpdir()) + const base = fixture?.base ?? new URL("/catalog/", server.url).href const skillDiscoveryLayer = AppNodeBuilder.build(SkillDiscovery.node, [ - [LayerNodePlatform.httpClient, http], [Global.node, Global.layerWith({ cache: tmp.path })], ]) const directories = await Effect.runPromise( @@ -38,7 +44,12 @@ async function pull(skills: unknown[], files: Record = {}, cache return yield* (yield* SkillDiscovery.Service).pull(base) }).pipe(Effect.provide(skillDiscoveryLayer)), ) - return { tmp, requests, directories } + return { tmp, server, state, base, requests: state.requests, directories } +} + +async function dispose(fixture: Fixture) { + await fixture.server.stop(true) + await fixture.tmp[Symbol.asyncDispose]() } describe("SkillDiscovery.pull", () => { @@ -46,10 +57,10 @@ describe("SkillDiscovery.pull", () => { const result = await pull([{ name: "../outside", files: ["SKILL.md"] }]) try { expect(result.directories).toEqual([]) - expect(result.requests).toEqual([`${base}index.json`]) + expect(result.requests).toEqual([`${result.base}index.json`]) expect(await fs.readdir(result.tmp.path)).toEqual([]) } finally { - await result.tmp[Symbol.asyncDispose]() + await dispose(result) } }) @@ -57,10 +68,10 @@ describe("SkillDiscovery.pull", () => { const result = await pull([{ name: "deploy", files: ["SKILL.md", "../outside.md"] }]) try { expect(result.directories).toEqual([]) - expect(result.requests).toEqual([`${base}index.json`]) + expect(result.requests).toEqual([`${result.base}index.json`]) expect(await fs.readdir(result.tmp.path)).toEqual([]) } finally { - await result.tmp[Symbol.asyncDispose]() + await dispose(result) } }) @@ -68,10 +79,10 @@ describe("SkillDiscovery.pull", () => { const result = await pull([{ name: "deploy", files: ["SKILL.md", "/tmp/outside.md"] }]) try { expect(result.directories).toEqual([]) - expect(result.requests).toEqual([`${base}index.json`]) + expect(result.requests).toEqual([`${result.base}index.json`]) expect(await fs.readdir(result.tmp.path)).toEqual([]) } finally { - await result.tmp[Symbol.asyncDispose]() + await dispose(result) } }) @@ -79,87 +90,87 @@ describe("SkillDiscovery.pull", () => { const result = await pull([{ name: "deploy", files: ["SKILL.md", "https://evil.example.test/outside.md"] }]) try { expect(result.directories).toEqual([]) - expect(result.requests).toEqual([`${base}index.json`]) + expect(result.requests).toEqual([`${result.base}index.json`]) expect(await fs.readdir(result.tmp.path)).toEqual([]) } finally { - await result.tmp[Symbol.asyncDispose]() + await dispose(result) } }) test("downloads safe nested files under the skill root", async () => { const result = await pull([{ name: "deploy", files: ["SKILL.md", "references/guide.md"] }], { - [`${base}deploy/SKILL.md`]: "# Deploy", - [`${base}deploy/references/guide.md`]: "# Guide", + "/catalog/deploy/SKILL.md": "# Deploy", + "/catalog/deploy/references/guide.md": "# Guide", }) try { expect(result.directories).toHaveLength(1) expect(result.requests.toSorted()).toEqual( - [`${base}index.json`, `${base}deploy/SKILL.md`, `${base}deploy/references/guide.md`].toSorted(), + [ + `${result.base}index.json`, + `${result.base}deploy/SKILL.md`, + `${result.base}deploy/references/guide.md`, + ].toSorted(), ) expect(await fs.readFile(path.join(result.directories[0], "SKILL.md"), "utf8")).toBe("# Deploy") expect(await fs.readFile(path.join(result.directories[0], "references", "guide.md"), "utf8")).toBe("# Guide") } finally { - await result.tmp[Symbol.asyncDispose]() + await dispose(result) } }) test("refreshes cached files when the version changes", async () => { - const tmp = await tmpdir() + const first = await pull( + [{ name: "deploy", version: "1", files: ["SKILL.md"] }], + { "/catalog/deploy/SKILL.md": "# Old" }, + ) try { - const first = await pull( - [{ name: "deploy", version: "1", files: ["SKILL.md"] }], - { - [`${base}deploy/SKILL.md`]: "# Old", - }, - tmp, - ) const second = await pull( [{ name: "deploy", version: "2", files: ["SKILL.md"] }], - { - [`${base}deploy/SKILL.md`]: "# New", - }, - tmp, + { "/catalog/deploy/SKILL.md": "# New" }, + first, ) expect(await fs.readFile(path.join(first.directories[0], "SKILL.md"), "utf8")).toBe("# New") - expect(second.requests).toContain(`${base}deploy/SKILL.md`) + expect(second.requests).toContain(`${first.base}deploy/SKILL.md`) const third = await pull( [{ name: "deploy", version: "2", files: ["SKILL.md"] }], - { [`${base}deploy/SKILL.md`]: "# Ignored" }, - tmp, + { "/catalog/deploy/SKILL.md": "# Ignored" }, + first, ) - expect(third.requests).toEqual([`${base}index.json`]) + expect(third.requests).toEqual([`${first.base}index.json`]) } finally { - await tmp[Symbol.asyncDispose]() + await dispose(first) } }) test("publishes complete updates and removes stale files", async () => { - const tmp = await tmpdir() + const first = await pull( + [{ name: "deploy", version: "1", files: ["SKILL.md", "old.md"] }], + { + "/catalog/deploy/SKILL.md": "# Old", + "/catalog/deploy/old.md": "old reference", + }, + ) try { - const first = await pull( - [{ name: "deploy", version: "1", files: ["SKILL.md", "old.md"] }], - { - [`${base}deploy/SKILL.md`]: "# Old", - [`${base}deploy/old.md`]: "old reference", - }, - tmp, - ) const root = first.directories[0] await pull( [{ name: "deploy", version: "2", files: ["SKILL.md", "missing.md"] }], - { [`${base}deploy/SKILL.md`]: "# Partial" }, - tmp, + { "/catalog/deploy/SKILL.md": "# Partial" }, + first, ) expect(await fs.readFile(path.join(root, "SKILL.md"), "utf8")).toBe("# Old") expect(await fs.readFile(path.join(root, "old.md"), "utf8")).toBe("old reference") - await pull([{ name: "deploy", version: "3", files: ["SKILL.md"] }], { [`${base}deploy/SKILL.md`]: "# New" }, tmp) + await pull( + [{ name: "deploy", version: "3", files: ["SKILL.md"] }], + { "/catalog/deploy/SKILL.md": "# New" }, + first, + ) expect(await fs.readFile(path.join(root, "SKILL.md"), "utf8")).toBe("# New") expect(await Bun.file(path.join(root, "old.md")).exists()).toBe(false) } finally { - await tmp[Symbol.asyncDispose]() + await dispose(first) } }) })