faf-cli 7.12.0 → 7.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -39,7 +39,7 @@ detected from your real stack, scored, and versioned with your code. No drift. N
39
39
  FAF defines. AGENTS.md instructs. AI codes.
40
40
 
41
41
  <!-- trophy — bottom of hero -->
42
- [![FAF Trophy 100%](https://img.shields.io/badge/FAF-%F0%9F%8F%86%20100%25-000000?labelColor=FF6B35)](https://faf.one)
42
+ [![FAF Trophy 100%](https://img.shields.io/badge/FAF-%E2%9C%AA%20100%25-000000?labelColor=FF6B35)](https://faf.one)
43
43
 
44
44
  </div>
45
45
 
@@ -63,24 +63,24 @@ No setup, no drift, no re-explaining.
63
63
  ## Install
64
64
 
65
65
  ```bash
66
- bunx faf # Bun — zero install, fastest path
67
- npx faf # npm — works everywhere
68
- brew install wolfe-jam/faf/faf-cli && faf # Homebrew (auto-taps)
66
+ bunx faf auto # Bun — zero install, fastest path
67
+ npx faf auto # npm — works everywhere
68
+ brew install wolfe-jam/faf/faf-cli && faf auto # Homebrew (auto-taps)
69
69
  ```
70
70
 
71
- > `faf` is shorthand for `faf-cli auto` — same behavior, fewer keystrokes.
71
+ > `faf` with no arguments shows your project's score; `faf auto` detects and fills.
72
72
 
73
73
  ---
74
74
 
75
75
  ## Quick Start
76
76
 
77
77
  ```bash
78
- # ANY GitHub repo — no clone, no install, 2 seconds
78
+ # ANY GitHub repo — one shallow clone, no install, 2 seconds
79
79
  bunx faf-cli git https://github.com/facebook/react
80
80
 
81
81
  # Your own project
82
82
  bunx faf-cli init # Create .faf
83
- bunx faf-cli auto # Zero to 100% in one command
83
+ bunx faf-cli auto # Fill every tech slot from the repo, then score
84
84
  bunx faf-cli go # Interactive interview to gold code
85
85
  ```
86
86
 
@@ -101,16 +101,16 @@ Run `faf` with no arguments:
101
101
  | Command | What it does |
102
102
  |---------|--------------|
103
103
  | `faf init` | Create `project.faf` from your local project |
104
- | `faf git <url>` | Instant `.faf` from any GitHub repo — no clone |
104
+ | `faf git <url>` | Instant `.faf` from any GitHub repo (a shallow clone) |
105
105
  | `faf auto` | Detect stack, fill every slot it can, score |
106
106
  | `faf go` | Guided interview to fill the human-only slots |
107
107
  | `faf score` | Check AI-readiness (0–100%) |
108
108
  | `faf export` | Author `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `.cursorrules` |
109
- | `faf sync` | Bi-directional `.faf` ↔ `CLAUDE.md` |
109
+ | `faf sync` | `.faf` → `CLAUDE.md` (pull: Trophy-gated backfill) |
110
110
  | `faf memory` | `.fafm` soul ops — convert Claude memory, etch, recall, ls, show |
111
111
  | `faf diff` / `log` | Semantic context diff + score timeline across git history |
112
112
  | `faf hooks --install` | Pre-commit guard against context regression |
113
- | `faf compile` / `decompile` | `.faf` ↔ `.fafb` sealed binary |
113
+ | `faf compile` / `decompile` | `.faf` → `.fafb` sealed binary; `decompile` shows a `.fafb`'s sections as JSON |
114
114
  | `faf check` | Validate a `.faf` file |
115
115
  | `faf recover` | Rebuild `.faf` from an existing `CLAUDE.md` / `AGENTS.md` |
116
116
  | `faf show` | Render `project.faf` to a browsable HTML page |
@@ -132,22 +132,36 @@ faf memory etch "a durable fact" --id my-fact
132
132
  faf memory show
133
133
  ```
134
134
 
135
- ### What's New in v7.12.0 — The Open Renderers Edition
136
-
137
- **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.**
138
-
139
- ```ts
140
- import { renderAgentsMd, enrichFromRepo, injectFafBlock, updateExistingFaf, writeFaf } from 'faf-cli';
141
- ```
142
-
143
- - **Renderers are public** — `renderAgentsMd` · `renderGeminiMd` · `renderCursorrules` · `renderClaudeMd` · `renderCopilotInstructions` and their `write*` pairs. An MCP server or an editor extension writes the same bytes `faf export` writes, instead of carrying its own copy that drifts.
144
- - **`enrichFromRepo(dir, data)`** — the repo-facts step `faf export --agents` runs first (commands, key files, secrets location) is exported too. Hand-authored values win; detection fills the gaps.
145
- - **`updateExistingFaf(dir, existing)`** — the exact chain `faf auto` runs on an existing `project.faf`: existing wins, then interrogated → detected → Turbo-Cat → Relentless fill the empties. `faf auto` itself now calls it. `writeFaf` / `serializeFaf` write the file the way faf-cli does.
146
- - **One injector, one rule** — `injectFafBlock` / `findFafBlock` locate the managed block by whole marker 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.
147
- - **Fixed: `faf export --agents` stacked its own output.** 7.1.4–7.11.0 quoted the marker tokens in prose and matched them as substrings, so every re-run appended the old block's tail (58 → 107 → 156 lines). Fixed at both ends; a file already stacked is repaired on its next export.
135
+ ### What's New in v7.13.0 — The Co-Author Edition
136
+
137
+ **You and your AI co-author project.faf — AI fills the tech facts from your repo, you write the 6Ws — and faf-cli only touches what it wrote: links can't lead it outside your project, a failed write keeps the original, and your comments, values and notes stay as you left them.**
138
+
139
+ - **faf writes its block, you write the rest.** faf touches only its managed block and its own section. A file with no faf markers is always prefixed, never taken over, even one that starts with faf's old stamp.
140
+ - **`project.faf` edits keep your file as written.** Comments, exact values (`1.10` stays `1.10`), anchors and keys faf doesn't know all survive. An edit changes only what it changes, and a no-op writes nothing.
141
+ - **If it's a fact, faf fills the slot.** A typed `None` or `N/A` is an empty slot, and the app-type decides which slots count.
142
+ - `faf auto` fills a tech slot only from a repo fact. With no fact, the slot stays empty; only `project.type` falls back to `library`, and says so on its line.
143
+ - With no fact, your words stay in a slot the app-type uses, and that slot scores 0 until filled.
144
+ - In a slot the app-type leaves out, `faf auto` writes `slotignored` (shown as N/A).
145
+ - The 6Ws stay yours: faf never replaces your words there, and `faf go` asks for the empty ones.
146
+ - **`faf ai enhance` is retired.** project.faf isn't enhanced: tech slots come from repo facts, and the 6Ws come from you.
147
+ - **Links and encodings are checked first.** faf refuses, in one line, to write:
148
+ - through a link that leaves the project;
149
+ - into `.git`, beyond its own hook section and diff driver;
150
+ - over a whole file faf didn't render;
151
+ - over a file that isn't UTF-8.
152
+ - **A whole file faf renders is replaced only when it's still exactly what faf wrote.** project.html and the Server and A2A cards now carry a render hash. If you edited one, faf leaves it and says so; `--force` replaces it.
153
+ - **One-time step when upgrading:** faf can't tell whether a project.html, Server Card or A2A card written before 7.13 was edited. The first run that would change one refuses it once, and that run exits 1. Check the file for hand edits, then run the same command once with `--force`; after that faf recognises its own output.
154
+ - **A failed write keeps the original.** faf writes to a temp file and renames it into place, so a full disk or a killed process leaves your file as it was. A file you edit while faf is writing is left alone.
155
+ - **Memory stays yours.**
156
+ - `soul.fafm` keeps its curated index, its facts and its comments, and etching an id that already exists merges into that fact.
157
+ - Tri-sync (`FAF_PRO=1`) writes Claude Code's own memory file as one section on top, and Claude's notes stay.
158
+ - **Detection stays inside the project.** Turbo-Cat no longer reads parent folders, so a monorepo root's stack no longer leaks into a package.
159
+ - **For builders.** New exports: `resolveInside`, `safeWriteFile`, `updateFafFile`, `writeClaudeMemory`, `FafDNAManager`, `authorFafFromRepo`, `registryTitle`, `isNonProjectRoot` and `scoreText`. `writeFaf` on an existing file now merges; pass `{ replace: true }` for the old overwrite.
160
+ - **Node 22+.** The engine floor matches CI (22 and 24).
148
161
 
149
162
  **Recent sprint**
150
163
 
164
+ - 🤝 [7.13.0](https://github.com/Wolfe-Jam/faf-cli/releases/tag/v7.13.0) The Co-Author Edition
151
165
  - 🧩 [7.12.0](https://github.com/Wolfe-Jam/faf-cli/releases/tag/v7.12.0) The Open Renderers Edition
152
166
  - 🖥️ [7.11.0](https://github.com/Wolfe-Jam/faf-cli/releases/tag/v7.11.0) The VS Code Edition
153
167
  - 📚 [7.10.0](https://github.com/Wolfe-Jam/faf-cli/releases/tag/v7.10.0) The Full-Facts Edition
@@ -189,8 +203,8 @@ Your own rules for the AI — *"use full words in identifiers," "use bun, not np
189
203
  ## Sync
190
204
 
191
205
  ```
192
- bi-sync: .faf ←── 8ms ──→ CLAUDE.md
193
- tri-sync: .faf ←── 8ms ──→ CLAUDE.md ↔ MEMORY.md
206
+ sync: .faf ──── 8ms ───→ CLAUDE.md (pull: Trophy-gated backfill)
207
+ tri-sync: .faf ──── 8ms ───→ CLAUDE.md + Claude Code's MEMORY.md (Pro: faf's block only; Claude's notes kept)
194
208
  ```
195
209
 
196
210
  ---