// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0 // // The coding-agent contract this template ships: CLAUDE.md imports AGENTS.md instead of repeating it, the // committed Claude Code settings keep secrets unreadable and a push behind a person, the support-report skill is // readable by its tool, and the format-on-edit hook formats only this repository's own source files. import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs" import { tmpdir } from "node:os" import { join } from "node:path" import { afterEach, describe, expect, it } from "vitest" import { fileToFormat } from "../scripts/agent-format.mjs" const APP_ROOT = new URL("..", import.meta.url).pathname const read = (path: string) => readFileSync(join(APP_ROOT, path), "utf8") const made: string[] = [] afterEach(() => { for (const dir of made.splice(0)) rmSync(dir, { recursive: true, force: true }) }) describe("the coding-agent contract", () => { it("has CLAUDE.md import AGENTS.md, the one source of the rules", () => { expect(read("CLAUDE.md")).toMatch(/^@AGENTS\.md$/m) expect(read("AGENTS.md")).toContain("## Work that starts from a support report") }) it("commits Claude Code settings that refuse .env reads and ask before a push or a migration run", () => { const settings = JSON.parse(read(".claude/settings.json")) expect(settings.permissions.deny).toEqual(expect.arrayContaining(["Read(/.env)", "Read(/.env.local)"])) expect(settings.permissions.ask).toEqual(expect.arrayContaining(["Bash(git push *)", "Bash(pnpm migrate *)"])) expect(settings.permissions.allow).toContain("Bash(pnpm gate)") // Nothing that publishes or deploys is pre-approved. for (const rule of settings.permissions.allow) expect(rule).not.toMatch(/push|migrate|deploy/) expect(read(".gitignore")).toContain(".claude/settings.local.json") }) it("ships the support-report skill with the frontmatter its tool reads first", () => { const skill = read(".claude/skills/fix-support-report/SKILL.md") expect(skill.startsWith("---\nname: fix-support-report\ndescription: ")).toBe(true) expect(skill).toMatch(/Reproduce it before changing code/) }) }) describe("the format-on-edit hook", () => { it("names a repository source file Biome formats, and nothing else", () => { const root = mkdtempSync(join(tmpdir(), "agent-format-")) made.push(root) writeFileSync(join(root, "a.ts"), "export const a = 1\n") writeFileSync(join(root, "notes.md"), "# notes\n") expect(fileToFormat({ tool_input: { file_path: join(root, "a.ts") } }, root)).toBe("a.ts") expect(fileToFormat({ tool_input: { file_path: "a.ts" } }, root)).toBe("a.ts") expect(fileToFormat({ tool_input: { file_path: "notes.md" } }, root)).toBeNull() expect(fileToFormat({ tool_input: { file_path: "missing.ts" } }, root)).toBeNull() expect(fileToFormat({ tool_input: { file_path: "../outside.ts" } }, root)).toBeNull() expect(fileToFormat({ tool_input: {} }, root)).toBeNull() expect(fileToFormat(null, root)).toBeNull() }) })