TL;DR: faf-cli opens its renderers, injector and faf auto update chain as public exports — consumers compose instead of port —
and faf export --agents is idempotent again: one block, every run.
In Plain English
Old state. MCP servers and editor extensions copied faf-cli's writers for AGENTS.md, GEMINI.md, .cursorrules, CLAUDE.md. Those copies drifted. And faf export --agents stacked its own block on every re-run.
Fix. The same functions faf export and faf auto use are now public. The injector finds the managed block by whole
marker lines at column 0 — not by substring.
New state. Import from faf-cli and you write the same bytes
the CLI writes. Re-export is one block, every run. A file the old injector stacked is
repaired on the next export.
npm install -g faf-cli@7.12.0 faf export --agentsTry it without installing: bunx faf-cli@7.12.0 --version (or npx --yes faf-cli@7.12.0). Pin the version in
scripts — @latest drifts.
What happened since The VS Code Edition
One blog, one arc — no post per patch. Last write-up was v7.11.0 The VS Code Edition (computeDrift() as a library). This cut opens the rest of the write path.
What 7.12.0 is
Lesson: compose, don't port. The bytes faf export writes should come from one place.
import { renderAgentsMd, enrichFromRepo, injectFafBlock, updateExistingFaf, writeFaf } from 'faf-cli';- Renderers are public —
renderAgentsMd·renderGeminiMd·renderCursorrules·renderClaudeMd·renderCopilotInstructionsand theirwrite*pairs. enrichFromRepo(dir, data)— the repo-facts stepfaf export --agentsruns first. Hand-authored values win; detection fills gaps.updateExistingFaf(dir, existing)— the exact chainfaf autoruns on an existingproject.faf.faf autoitself now calls it.- One injector —
injectFafBlock/findFafBlockmatch markers as whole lines at column 0. Fenced examples are skipped. An unbalanced fence inside the block cannot hide the end marker. CRLF and BOM survive. A block that lost its end marker is prefixed, never overwritten.
faf export --agents is idempotent again
From 7.1.4 through 7.11.0 the rendered blockquote quoted the marker tokens in prose, and the injector located the block by substring. Every re-run cut the old block at the quote and appended its stale tail — AGENTS.md grew ~49 lines per export. Both ends are fixed. A file already stacked is repaired on its next export.
Try it
Install (global):
npm install -g faf-cli@7.12.0 # short name, same bits: npm install -g faf@7.12.0Try (no install):
bunx faf-cli@7.12.0 --version bunx faf-cli@7.12.0 export --agentsMore: The VS Code Edition (v7.11.0) · v7.12.0 release · repo.
Technical details
- Version: 7.12.0 (September 9, 2026)
- New exports:
renderAgentsMd/writeAgentsMd·renderGeminiMd·renderCursorrules·renderCopilotInstructions·renderClaudeMd/readClaudeMd/parseClaudeMd/fafMetaTag·injectFafBlock/findFafBlock/FAF_START/FAF_END·enrichFromRepo·updateExistingFaf/fillEmpties·serializeFaf/writeFaf - Packages: dual-published —
faf-cliandfaf, same version - Tests: 1417/1417
- Score: ✪ Trophy 100%
Feedback welcome
Questions, nits, suggestions — guide the next version. Tell us what you want to see.
