/CLAUDE.md
CLAUDE.md at /CLAUDE.md
Path: CLAUDE.md
zudo-test-wisdom
Takazudo's frontend testing strategy guide, built with zudo-doc (zfb stack, MDX, Tailwind CSS v4).
Commands
pnpm dev # Start zfb dev server (4321) + doc-history server (4322)
pnpm build # Build static site via zfb build
pnpm preview # Preview built site
pnpm check # zfb type checking
pnpm format:md # Format MDX files
pnpm b4push # Pre-push validation (format + drift + pins + typecheck + build + html + links)
pnpm setup:doc-skill # Generate test-wisdom skill + symlink all skillsContent Structure
English (default):
src/->content/ docs/ /docs/ . . . Japanese:
src/->content/ docs- ja/ /ja/ docs/ . . . Japanese docs mirror the English directory structure
Bilingual rule: When creating or updating any doc page, ALWAYS update both the English (docs/) and Japanese (docs-ja/) versions in the same PR. Keep code blocks identical between languages -- only translate surrounding prose. Executable code blocks stay byte-identical between EN and JA; display-only text inside diagrams (mermaid node/edge labels, tree-diagram comments) may be translated.
Exception: Pages with generated: true in frontmatter (e.g., claude-resources auto-generated pages) do not require Japanese translations.
Content Categories
Top-level directories under src/. Directories with header nav entries are mapped via categoryMatch in the headerNav list in zfb.config.ts:
overview/- Introduction and purpose of the testing guidetesting-levels/- The 6 testing levels from unit to AI-based verificationdecision-guide/- Which level to use, common failure patterns, required behaviorstool-patterns/- Patterns organized around a specific tool, not a project shape (Vitest, Playwright, visual regression, browser-in-container verification, cargo-nextest)project-recipes/- Patterns organized around a repo/project shape, not a single tool (backend, Tauri, remark/rehype plugins, built-site integrity, dependency replacement)ci-operations/- Running suites across CI, deploys, and releases (environment-tiered testing, smoke tests, scheduled re-exam, branch strategy, publishing, runner sizing, CI-skip markers and merge hygiene, gate optimization)test-integrity/- Ways tests deceive (flakes, false greens, self-agreement, fixture traps) and the discipline preventing themtools-reference/- Quick reference of tools per testing level
Auto-generated directories (no header nav entry, managed by claude-resources integration):
claude-md/- CLAUDE.md file documentation (noPage: true)claude-skills/- Claude Skills documentation (noPage: true)
Writing Docs
All documentation files use .mdx format with YAML frontmatter.
Frontmatter Fields
Schema is the zudo-doc package default (shipped by @takazudo/zudo-doc; override via buildDocsSchema in zfb.config.ts if ever needed):
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Page title, rendered as the page h1 |
description | string | No | Subtitle displayed below the title |
sidebar_position | number | No | Sort order within category (lower = higher). Always set this for predictable ordering |
sidebar_label | string | No | Custom text for sidebar display (overrides title) |
generated | boolean | No | Build-time generated content (skip translation) |
Content Rules
No h1 in content: The frontmatter
titleis automatically rendered as the page h1. Start your content with## h2headings.Always set
sidebar_position: Without it, pages sort alphabetically which is unpredictable.Kebab-case file names: Use
my-article.mdx, notmyArticle.mdx.No body
hr(---) in MDX content. A separator that marks a real topic shift should be expressed with heading structure instead (see the deflaking-recipe restructure). (auto-generated pages — claude-md/, claude-skills/, and anygenerated: truepage — are exempt: they may contain---inside embedded examples and must never be hand-edited. This excludesdocs-, a hand-maintained locale stub with noja/ claude/ index. mdx generated: truemarker.)
Linking Between Docs
Use relative file paths with the .mdx extension:
[Link text](./sibling-page.mdx)
[Link text](../other-category/page.mdx#anchor)Admonitions
Available globally without imports: <Note>, <Tip>, <Info>, <Warning>, <Danger>
Navigation Structure
Navigation is filesystem-driven. Directory structure directly becomes sidebar navigation. Pages ordered by sidebar_position (ascending). Category index pages (index.mdx) control category position.
Content Creation Workflow
Create English
.mdxfile undersrc/withcontent/ docs/ titleandsidebar_positionWrite content starting with
## h2headings (not# h1)Create matching Japanese file under
src/content/ docs- ja/ Keep code blocks identical -- only translate prose
Run
pnpm format:mdthenpnpm buildto verify
Skills
This repo contains test-related Claude Code skills under .claude/skills/:
test-wisdom/- Doc-lookup skill (generated bypnpm setup:doc-skill, gitignored -- do NOT track or edit directly)verify-ui/- Deterministic CSS/computed-style verification (tracked in git)headless-browser/- Headless browser screenshots and interaction (tracked in git; bundles its own Playwright)
Run pnpm setup:doc-skill to generate the test-wisdom skill and symlink it to ~/.claude/skills/ (and ~/.codex/skills/).
It also symlinks the tracked skills (verify-ui, verify-ui-ai, headless-browser) into the same global directory by default — a create-zudo-doc 5.x template feature (LINK_TRACKED_SKILLS), pulled in by the Aug-2026 zudo-doc 5.x migration, not something this repo added. scripts/ is a create-zudo-doc template file guarded by pnpm check:template-drift; local edits must be intentional and recorded in .template-drift-allowlist, otherwise they are silently overwritten on the next template re-sync. Pass --no-link-tracked-skills to skip that step and symlink only the generated skill.
Improving the shared template is an upstream change — see /.
The test-wisdom name is pinned as an explicit $1 override in the setup:doc-skill script entry, so that is the name generated regardless of what the current zudo-doc 5.x template would derive. Its derivation is suffix-aware (zudolab/zudo-doc#3154): a PROJECT_NAME already ending in -wisdom is used as-is, so the derived default here is zudo-test-wisdom rather than the doubled zudo-test-wisdom-wisdom it produced before. .gitignore covers that project-name variant too, so neither name leaves a tracked stray.
The doubled-suffix behaviour is historical. The template still computes the legacy <packageName>-wisdom name, but only to detect leftover directories from the old rule and warn about them — and that warning is silent here, because it fires only when the derived default is actually in use and this repo always passes the explicit override.
Playwright needs no manual install step. headless-browser bundles Playwright and installs it on demand; verify-ui falls back to that bundle, or to its own directory when used standalone. Both self-heal on a fresh machine and retry once — see each skill's SKILL.md. Agents must NOT stop and ask the user to run npx playwright install; a missing browser is a setup gap, not a decision.
Both skills are designed to work standalone (symlinked or copied without this repo), so each carries its own bootstrap — headless- is the shared, idempotent entry point. Keep them self-sufficient: do not move recovery logic into setup-doc-skill.sh only.
One invariant to preserve if you touch the install path: browser downloads must be driven by the resolved Playwright package's own cli.js, never a bare npx playwright install. Each version pins its own browser revisions, so npx (which fetches @latest) installs a revision the resolved module never looks for — the launch then fails with Executable doesn't exist despite a "successful" install.
Typography
The
futura-editorialtheme pack owns display typography: Jost at weight 400 for doc h1 titles, the home hero heading, and the header site name.Heading weights follow the pack: doc h2 uses 400 and h3 uses 500.
The pack supplies Noto Sans for Latin body text and Space Mono for code.
The host's only font override adds Noto Sans JP before system fallbacks in the pack's sans stack. Keep its
headwebfont links inzfb.config.ts; the pack's bundled fonts cover Latin glyphs only.
Project Layout
zudo-doc 5.x is a thin host shell — all wiring (components, config types, utils, routes, chrome) lives inside @takazudo/zudo-doc, driven by the single zudoDoc() config.
pages/ # Thin route stubs (package-owned routes injected at build)
index.tsx # Home: re-exports @takazudo/zudo-doc/routes/index
docs/[[...slug]].tsx # EN doc route stub
[locale]/docs/[[...slug]].tsx # JA doc route stub
src/
content/ # MDX doc pages (docs/ + docs-ja/)
styles/global.css # Package CSS imports + host brand overrides
zfb.config.ts # The single config file — zudoDoc({ ... }) Site Config
Base path:
/(root — no subpath prefix)Live URL:
https:/ / zudo- test- wisdom. takazudomodular. com/ Settings + build config:
zfb.config.ts(the singlezudoDoc()config)
CI/CD
PR checks: typecheck + build + Cloudflare Workers static assets preview
Main deploy: build →
wrangler deploy→ Cloudflare Workers + IFTTT notificationHosting: Cloudflare Workers static assets (not Pages)
Secrets:
CLOUDFLARE_ACCOUNT_ID,CLOUDFLARE_API_TOKEN,IFTTT_PROD_NOTIFY