import { describe, expect, test, afterAll } from 'bun:test'; import { mkdtempSync, rmSync, readFileSync, existsSync, writeFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { writeAgentBrief } from './agent-brief'; /** * Both harnesses have to find the brief. * * Claude Code discovers `CLAUDE.md`, opencode discovers `AGENTS.md` and nothing else. Every brief the * platform wrote was `CLAUDE.md`, so under opencode a commander, a bot and a plugin chat were each * briefed with nothing — silently, which is why it lasted. */ const root = mkdtempSync(join(tmpdir(), 'agent-brief-')); afterAll(() => rmSync(root, { recursive: true, force: true })); const dir = (name: string) => { const d = join(root, name); rmSync(d, { recursive: true, force: true }); Bun.spawnSync(['mkdir', '-p', d]); return d; }; describe('writeAgentBrief', () => { test('writes the content as AGENTS.md and a POINTER as CLAUDE.md', async () => { const d = dir('both'); await writeAgentBrief(d, '# Brief\n\nthe real instructions\n'); expect(readFileSync(join(d, 'AGENTS.md'), 'utf8')).toContain('the real instructions'); const pointer = readFileSync(join(d, 'CLAUDE.md'), 'utf8'); expect(pointer).toContain('AGENTS.md'); // The pointer must NOT be a second copy — two copies of a file rewritten every turn will disagree, // and the stale one is the one somebody reads. expect(pointer).not.toContain('the real instructions'); }); test('is idempotent — an unchanged brief writes nothing', async () => { const d = dir('idempotent'); expect(await writeAgentBrief(d, 'same\n')).toBe(true); expect(await writeAgentBrief(d, 'same\n')).toBe(false); }); test('rewrites when the content changes, because that is how a template reaches a bot', async () => { const d = dir('rewrite'); await writeAgentBrief(d, 'v1\n'); expect(await writeAgentBrief(d, 'v2\n')).toBe(true); expect(readFileSync(join(d, 'AGENTS.md'), 'utf8')).toBe('v2\n'); }); test('onlyIfAbsent never touches a brief the agent has extended', async () => { // A commander writes its own job into this file over days. Rewriting it because the template // changed would delete what it agreed with the owner. const d = dir('extended'); await writeAgentBrief(d, 'generated\n'); writeFileSync(join(d, 'AGENTS.md'), 'generated\n\n## JOB\n\nwatch the thing\n'); expect(await writeAgentBrief(d, 'a new template\n', { onlyIfAbsent: true })).toBe(false); expect(readFileSync(join(d, 'AGENTS.md'), 'utf8')).toContain('watch the thing'); }); test('onlyIfAbsent still creates both files the first time', async () => { const d = dir('first'); expect(await writeAgentBrief(d, 'generated\n', { onlyIfAbsent: true })).toBe(true); expect(existsSync(join(d, 'AGENTS.md'))).toBe(true); expect(existsSync(join(d, 'CLAUDE.md'))).toBe(true); }); });