import { describe, expect } from "bun:test" import { Effect, Layer } from "effect" import type { Agent } from "../../src/agent/agent" import { NamedError } from "@opencode-ai/core/util/error" import { Skill } from "../../src/skill" import { Permission } from "../../src/permission" import { SystemPrompt } from "../../src/session/system" import { testEffect } from "../lib/effect" const skills: Skill.Info[] = [ { name: "zeta-skill", description: "Zeta skill.", location: "/tmp/zeta-skill/SKILL.md", content: "# zeta-skill", }, { name: "alpha-skill", description: "Alpha skill.", location: "/tmp/alpha-skill/SKILL.md", content: "# alpha-skill", }, { name: "middle-skill", description: "Middle skill.", location: "/tmp/middle-skill/SKILL.md", content: "# middle-skill", }, ] const build: Agent.Info = { name: "build", mode: "primary", permission: Permission.fromConfig({ "*": "allow" }), options: {}, } const it = testEffect( SystemPrompt.layer.pipe( Layer.provide( Layer.succeed( Skill.Service, Skill.Service.of({ get: (name) => Effect.succeed(skills.find((skill) => skill.name === name)), all: () => Effect.succeed(skills), dirs: () => Effect.succeed([]), available: () => Effect.succeed(skills), }), ), ), ), ) describe("session.system", () => { it.effect("skills output is sorted by name and stable across calls", () => Effect.gen(function* () { const prompt = yield* SystemPrompt.Service const first = yield* prompt.skills(build) const second = yield* prompt.skills(build) const output = first ?? (yield* Effect.fail(new NamedError.Unknown({ message: "missing skills output" }))) expect(first).toBe(second) const alpha = output.indexOf("alpha-skill") const middle = output.indexOf("middle-skill") const zeta = output.indexOf("zeta-skill") expect(alpha).toBeGreaterThan(-1) expect(middle).toBeGreaterThan(alpha) expect(zeta).toBeGreaterThan(middle) }), ) })