/** * agents.test.ts — markdown agent-definition loader. */ import { describe, expect, it } from "bun:test"; import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { extensionRoot, loadAgents } from "../src/agents.js"; /** Build an agent markdown file with frontmatter + body. */ async function writeAgent( dir: string, file: string, name: string, body: string, tools?: string[], ): Promise { const lines = ["---", `name: ${name}`]; if (tools) { lines.push("allowedTools:"); for (const t of tools) lines.push(` - ${t}`); } lines.push("---", body, ""); await writeFile(join(dir, file), lines.join("\n"), "utf8"); return join(dir, file); } describe("loadAgents", () => { it("loads scanner.md and fixer.md shipped with the extension", async () => { const agents = await loadAgents(); expect(agents.has("scanner")).toBe(true); expect(agents.has("fixer")).toBe(true); const scanner = agents.get("scanner"); expect(scanner).toBeDefined(); expect(scanner?.systemPrompt).toContain("scanner"); expect(scanner?.allowedTools).toContain("read"); expect(scanner?.allowedTools).not.toContain("edit"); // scanner is read-only expect(scanner?.sourcePath).toContain("agents/scanner.md"); const fixer = agents.get("fixer"); expect(fixer?.allowedTools).toContain("edit"); }); it("extensionRoot resolves to the package directory", () => { expect(extensionRoot()).toMatch(/(pygenium|pygienium)$/); }); it("project-local agents override the extension's by name", async () => { const cwd = await mkdtemp(join(tmpdir(), "pygium-agents-")); try { await mkdir(join(cwd, "agents")); const path = await writeAgent( join(cwd, "agents"), "scanner.md", "scanner", "Project-tuned scanner prompt.", ["read", "grep", "find", "edit"], ); const agents = await loadAgents({ cwd }); const scanner = agents.get("scanner"); expect(scanner?.systemPrompt).toContain("Project-tuned"); expect(scanner?.allowedTools).toContain("edit"); // repo override widens tools expect(scanner?.sourcePath).toBe(path); // Extension baseline is retained for agents the repo doesn't override. expect(agents.get("fixer")).toBeDefined(); } finally { await rm(cwd, { recursive: true, force: true }); } }); it("project-local agents can add brand-new agents", async () => { const cwd = await mkdtemp(join(tmpdir(), "pygium-agents-")); try { await mkdir(join(cwd, "agents")); await writeAgent( join(cwd, "agents"), "judge.md", "judge", "Scoring judge.", ); const agents = await loadAgents({ cwd }); expect(agents.has("judge")).toBe(true); expect(agents.get("judge")?.systemPrompt).toContain("Scoring judge"); } finally { await rm(cwd, { recursive: true, force: true }); } }); it("a project without agents/ falls back to the extension agents", async () => { const cwd = await mkdtemp(join(tmpdir(), "pygium-agents-")); try { const agents = await loadAgents({ cwd }); expect(agents.has("scanner")).toBe(true); expect(agents.has("fixer")).toBe(true); } finally { await rm(cwd, { recursive: true, force: true }); } }); });