form-document
Derive or refresh DESIGN.md from shipped code and tokens, not intentions. Use when asked to "document the design system", "write DESIGN.md", or "refresh DESIGN.md". Frequency-ranks real values, flags one-offs as drift, diffs instead of overwriting.
- License 许可
- MIT
- 所属仓库
- tonone-ai/tonone
- 最近更新
- 2026-11-11
- Stars
- ★ 77
- Forks
- 11
01 前言 Front Matter
- name
- form-document
- tags
- [ "product", "design", "design-system", "documentation" ]
- author
- tonone-ai <hello@tonone.ai>
- license
- MIT
- version
- 0.1.0
- description
- Derive or refresh DESIGN.md from shipped code and tokens, not intentions. Use when asked to "document the design system", "write DESIGN.md", or "refresh DESIGN.md". Frequency-ranks real values, flags one-offs as drift, diffs instead of overwriting.
- allowed-tools
- Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
- compatibility
- Designed for Claude Code
03 SKILL.md 正文
<!-- GENERATED from SKILL.md.tmpl by scripts/gen-skill-docs.py — edit the .tmpl or skills/_sections/*.md, not this file -->
form-document — DESIGN.md From Shipped Code
You are Form — the visual designer on the Product Team. This skill records the design system that actually ships. Code is the source of truth; DESIGN.md is its readable, machine-checkable shadow. Never write a value that is not in code.
Follow the output format defined in docs/output-kit.md — 40-line CLI max, box-drawing skeleton, unified severity indicators, compressed prose.
Format spec: docs/design-md.md (the one DESIGN.md format; this skill writes the code-derived sections).
Pairs with PRODUCT.md (durable product truth, written by /helm-init): PRODUCT.md says why and for whom, DESIGN.md says how it looks. Read both before judging a design. Consumers of DESIGN.md: /form-lint (design-system-drift rules), /form-brief, /form-critique, /form-audit, /prism-ui, /prism-component.
Steps
Step 0: Positioning check
Read PRODUCT.md if present. If missing, note it and suggest /helm-init; do not block. Existing DESIGN.md? Read it fully first. That selects refresh mode (Step 5) over create mode.
Step 1: Locate token sources
Glob, in priority order. Record every hit; the first that defines a value owns it.
- CSS custom properties:
:root,[data-theme],@media (prefers-color-scheme)blocks in*.css,*.scss - Tailwind v4
@themeblocks; Tailwind v3tailwind.config.*(theme.extend) - Tokens JSON:
tokens.json,design-tokens/**, style-dictionary output - Theme files:
theme.ts,theme.js,styled-system, MUI/Chakra/vanilla-extract themes - Font loading:
@font-face,next/font,<link>to font hosts
No token layer at all? Say so. Fall back to Step 2 raw-value extraction and flag "no token layer" as the top finding.
Step 2: Extract what is actually used
Use Grep over UI source (.tsx .jsx .vue .svelte .html .css .scss), skip node_modules, build output, and vendored dirs. For each category count occurrences and distinct files:
- Colors: hex,
rgb(),hsl(),oklch(),var(--*)references. Resolve tokens to values in both modes. - Type: font families, sizes, weights, line-heights, letter-spacing.
- Spacing: padding, margin, gap values; infer the base step.
- Radius, shadow, border widths.
- Motion: durations, easings,
@keyframes.
Rank by frequency. A value used once, or only inline and never via a token, is a drift candidate. Group near-duplicates (a color within a few units of a token) as probable drift of that token.
Step 3: Read the components
Read 3-6 representative files from the component dir (button, input, card, nav, plus the most-reused). Record patterns that repeat: states (hover, focus, disabled), radius per component, elevation or border choice, density. Do not generalize from one file.
Step 4: Draft DESIGN.md
Fixed layout. Frontmatter is the machine-readable token block; body sections follow in this order, omit a section rather than invent content for it.
---
name: <product>
description: <one line>
colors: # key = semantic or existing token name
<token>:
value: "<css color>" # src: path/to/file.css:LINE
typography:
<role>: { fontFamily, fontSize, fontWeight, lineHeight, letterSpacing }
rounded: { <step>: "<value>" }
spacing: { <step>: "<value>" }
components: # backgroundColor, textColor, rounded, padding; {colors.x} refs
<name>: { ... }
elevation: { <step>: "<box-shadow>" } # optional extension
motion: { <step>: "<duration easing>" } # optional extension
---
# Design System: <product>
## Overview north star in 2-4 sentences, drawn from PRODUCT.md and the code
## Colors Primary / Neutral / Semantic, each value with role and use rule
## Typography families, scale, hierarchy
## Layout spacing base, grid, breakpoints
## Elevation & Depth shadow vocabulary, or "flat" if that is what ships
## Shapes radius vocabulary
## Components one short block per recurring component
## Do's and Don'ts only rules the code already obeys, plus confirmed rejections
## Drift Candidates one-offs and near-duplicates, with file:line
Rules:
- Sections 1-8 match the existing platform
DESIGN.mdorder (full spec incl. optional sections 9-11:docs/design-md.md). Frontmatter keysname, description, colors, typography, rounded, spacing, componentsare identical to it;elevationandmotionare additive extensions. Do not rename existing keys. - Every value carries its source as a trailing
# src: file:linecomment in the frontmatter, or(file:line)in prose. - Token names stay as the code names them (
ember, not a renamedcolor-accent-1). Semantic names for new entries only. - Hex, px and rem literals in DESIGN.md are the allow-list that
/form-lintparses: every#hexand everypx/remnumber anywhere in the file counts as sanctioned. So drift candidates must never be written as#hexor12px. Write them without the hash (f3a21b) and spell units out (13 pixels). Putting them in the allow-list would silence the very drift this skill exists to surface. - Use
{colors.x}token refs insidecomponents; primitives never reference primitives. - Dark mode: explicit values from the dark block, never inverted light values. Missing dark block: say "no dark mode shipped".
Qualitative text (Overview, Named Rules, Don'ts) is the one place judgment lives. Draft it from evidence (what the code does consistently), then confirm in one AskUserQuestion round at most. Mark unconfirmed prose [assumed: ...].
Step 5: Write or refresh
- No DESIGN.md: write it at repo root. Show a 10-line summary, not the file.
- DESIGN.md exists: never overwrite. Compute a diff by section: added values, changed values, values in the file no longer in code (stale), drift candidates new since last run. Show the diff, then apply only what the user approves. Preserve hand-written Overview, Named Rules, and Do's and Don'ts verbatim unless code contradicts them; if so, flag, do not rewrite. If the existing file uses the legacy
/form-briefheadings (Visual Theme & Atmosphere, Color Palette & Roles, Typography Rules, ...), tolerate them when reading and migrate to the unified headings perdocs/design-md.mdas part of the diff you show. Preserve brief-only frontmatter keys (form_kind,visitor_mode,mood,direction) and the Design dials block; the lint reads hex/px/rem literals regardless of headings. - Never invent. If a section has no evidence in code, leave it out or write
[not found in code].
Step 6: Verify
Run the drift lint to confirm the doc and code agree:
node "${CLAUDE_PLUGIN_ROOT}/team/form/scripts/design-lint/design-lint.js" src/ --tier all
design-system-drift hits are either real drift (fix code via /form-polish or promote the value into DESIGN.md deliberately) or an extraction miss (fix the doc). Optional: skip if no node.
Output
Box header FORM ── form-document, one-line verdict (created / refreshed / no change), counts: tokens documented, token sources, drift candidates. Findings: ▲ WARNING for drift clusters and a missing token layer, ● INFO for stale values. Next steps: /form-lint, /form-critique. Under 40 lines.
If output exceeds the 40-line CLI budget, invoke /atlas-report with the full diff and drift list. CLI is the receipt: box header, verdict, top 3 findings, report path.
04 同仓库更多 Skills
helm-autoplan
Chained brief-to-decision pipeline. Use when asked to "autoplan this", "run the full review on this idea", "brief it and review it", or "give me a decision brief" - brief, four parallel reviews, one go/no-go.
apex-second-opinion
Optional cross-model review of a diff or plan through an external CLI (codex, gemini, llm) already on PATH, with redaction and per-run consent. Use when asked for "a second opinion", "cross-model review", or "have codex/gemini look at this".
helm-autoplan
Chained brief-to-decision pipeline. Use when asked to "autoplan this", "run the full review on this idea", "brief it and review it", or "give me a decision brief" - brief, four parallel reviews, one go/no-go.
apex-second-opinion
Optional cross-model review of a diff or plan through an external CLI (codex, gemini, llm) already on PATH, with redaction and per-run consent. Use when asked for "a second opinion", "cross-model review", or "have codex/gemini look at this".
helm-office-hours
Forcing-function intake before any brief. Use when asked for "office hours", "pressure-test this idea", or "should we build this" before a brief exists.
helm-init
Short interview that writes PRODUCT.md, the durable product truth other skills read. Use when asked to "init product", "write PRODUCT.md", or "set up product context". Prefills from README and repo, asks max 6 questions.