Skip to content

Commit c8683a5

Browse files
committed
feat(docs): mermaid theme-value guard + brand-source docs + README quickstart
- checkDiagrams: a `%%{init` block must now carry the brand's actual color values (ember #f26430 + warm-black #171310 from brand.json), not merely a theme directive — a diagram can no longer declare a theme yet render off-brand. New docs_check test covers both the branded-pass and missing-values-flagged cases. - ARCHITECTURE.md: document brand.json.colors as the single color source both public pages derive from, and the parity/diagram guards that keep it honest. - README: lead with a "Start in 60 seconds" block so the first screen is actionable, linking to the full quickstart and command reference. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019PXuKmJp92Gdo2FudNjSx2
1 parent 32b666a commit c8683a5

5 files changed

Lines changed: 64 additions & 5 deletions

File tree

ARCHITECTURE.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,14 @@ every intra-repo Markdown anchor (`#x` and `path.md#x`) against the target's rea
240240
(GitHub-exact slugs — em-dashes yield `--`, never collapsed), killing the dead-anchor class;
241241
and `checkRoadmap` fails when the ROADMAP's "Now" marker trails the shipped `package.json`
242242
version. The two public pages
243-
(`landing/index.html` + the `build-pages.mjs` status page) share one set of design tokens,
244-
enforced for parity (plus non-empty changes list, no phantom webfont) by
245-
`test/pages.test.js` — so neither the docs' numbers nor the site's look can silently drift.
243+
(`landing/index.html` + the `build-pages.mjs` status page) derive from ONE color source —
244+
`brand.json.colors` (full dark + light palettes), emitted as CSS by `src/brand.js`
245+
(`rootTokensCss()`). `test/pages.test.js` enforces full-palette parity: every hex in
246+
`brand.json` must appear on both surfaces, so the palette can't fork into "two palettes
247+
claiming to be one" again (plus non-empty changes list, no phantom webfont, present
248+
social/favicon metadata). `checkDiagrams` extends the same single-source rule to Mermaid —
249+
every `%%{init` theme must carry the brand's ember + warm-black hexes — so neither the docs'
250+
numbers nor the site's look can silently drift.
246251

247252
**Auto-release (`.github/workflows/bump.yml` + `scripts/bump.mjs`).** A push to `master`
248253
runs `bump.mjs auto`: it releases only when a `feat`/`fix`/`perf`/breaking commit landed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ design` passes spacing-scale, radius-levels, and shadow-levels with a healthy
4545
block, with a 256-color fallback when the terminal can't do truecolor. New
4646
`test/statusline.test.js` smoke-tests the segments, the exact truecolor hexes, the
4747
fallback, and graceful degradation on minimal input.
48+
- **Mermaid theme-value guard.** `forge docs check`'s `checkDiagrams` now verifies each
49+
`%%{init` block carries the brand's actual color values (ember + warm-black from
50+
`brand.json`), not just that a theme directive is present — a diagram can no longer
51+
declare a theme and still render off-brand. README leads with a `Start in 60 seconds`
52+
block, and `ARCHITECTURE.md` documents `brand.json` as the single color source.
4853

4954
### Fixed
5055

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,21 @@ delivers them into every tool you use.
2626
> **Status: beta.** The core (`init`, `sync`, `substrate`, `impact`, `ledger`, guards) is
2727
> tested and in daily use; some flags may change before `1.0`.
2828
29+
## Start in 60 seconds
30+
31+
```bash
32+
npm install -g @codewithjuber/forgekit # or: npm install -g github:CodeWithJuber/forgekit
33+
forge init # emit every AI tool's native config from one source
34+
forge doctor # verify providers, hooks, and MCP wiring
35+
```
36+
37+
That's it — your agents now share one source of truth. The
38+
[full quickstart](#60-second-quickstart) walks through the loop; [Commands](#commands)
39+
lists everything `forge` can do.
40+
2941
## Contents
3042

43+
- [Start in 60 seconds](#start-in-60-seconds)
3144
- [The problem](#the-problem)
3245
- [How it works — the loop](#how-it-works--the-loop)
3346
- [What you get](#what-you-get)

src/docs_check.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,24 @@ function checkDiagrams(root, issues) {
200200
severity: "error",
201201
detail: `${rel}: a mermaid diagram has no branded \`%%{init\` theme — it renders in Mermaid's off-brand default`,
202202
});
203+
} else {
204+
// Presence of `%%{init` isn't enough — the theme must carry the actual brand
205+
// VALUES from the single color source (brand.json.colors.dark), or a diagram can
206+
// declare a theme and still render in off-brand colors. Require the load-bearing
207+
// identity hexes: the ember accent and the warm-black canvas.
208+
const dark = BRAND.colors?.dark ?? {};
209+
for (const [role, hex] of [
210+
["ember accent (lineColor)", dark.brand],
211+
["warm-black canvas (tertiaryColor)", dark.bg],
212+
]) {
213+
if (hex && !block.toLowerCase().includes(hex.toLowerCase())) {
214+
issues.push({
215+
check: "diagrams",
216+
severity: "error",
217+
detail: `${rel}: a mermaid \`%%{init\` theme is missing the brand ${role} \`${hex}\` — it declares a theme but not the brand.json colors`,
218+
});
219+
}
220+
}
203221
}
204222
if (block.includes("\\n")) {
205223
issues.push({

test/docs_check.test.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,13 @@ test("docsCheck: an undocumented MCP tool is flagged", () => {
116116
assert.ok(r.issues.some((i) => i.check === "mcp-tools" && i.detail.includes(TOOLS[0].name)));
117117
});
118118

119+
// A theme that carries the actual brand color VALUES (ember #f26430 + warm-black
120+
// #171310), not just the `%%{init` directive.
121+
const BRAND_INIT =
122+
"%%{init: {'theme':'base','themeVariables':{'primaryColor':'#201a15','lineColor':'#f26430','tertiaryColor':'#171310'}}}%%";
123+
119124
test("docsCheck: a branded mermaid diagram with <br/> passes; diagrams is a checked dimension", () => {
120-
const good =
121-
"```mermaid\n%%{init: {'theme':'base'}}%%\nflowchart LR\n A[\"a<br/>b\"] --> B[\"c\"]\n```\n";
125+
const good = `\`\`\`mermaid\n${BRAND_INIT}\nflowchart LR\n A["a<br/>b"] --> B["c"]\n\`\`\`\n`;
122126
const r = docsCheck({
123127
root: fixtureRoot((f) => ({
124128
...f,
@@ -129,6 +133,20 @@ test("docsCheck: a branded mermaid diagram with <br/> passes; diagrams is a chec
129133
assert.ok(r.checked.includes("diagrams"));
130134
});
131135

136+
test("docsCheck: a mermaid theme missing the brand color values is flagged", () => {
137+
// Has `%%{init` but not the brand.json hexes — declares a theme, renders off-brand.
138+
const bad = "```mermaid\n%%{init: {'theme':'base'}}%%\nflowchart LR\n A --> B\n```\n";
139+
const root = fixtureRoot((f) => ({
140+
...f,
141+
"ARCHITECTURE.md": `${f["ARCHITECTURE.md"]}\n${bad}`,
142+
}));
143+
const r = docsCheck({ root });
144+
assert.ok(
145+
r.issues.some((i) => i.check === "diagrams" && /missing the brand/.test(i.detail)),
146+
"a theme without the brand hexes is flagged",
147+
);
148+
});
149+
132150
test("docsCheck: an unstyled mermaid diagram (no branded theme) is flagged", () => {
133151
const bad = "```mermaid\nflowchart LR\n A --> B\n```\n";
134152
const root = fixtureRoot((f) => ({

0 commit comments

Comments
 (0)