design system token v0.5.1

This commit is contained in:
Juan
2026-04-16 11:10:06 -05:00
parent b8168261a1
commit 64d7df1439
4 changed files with 107 additions and 87 deletions

View File

@@ -60,7 +60,7 @@ The design system provides three things for AI agents:
| File | What it is | Where it goes | | File | What it is | Where it goes |
|------|-----------|---------------| |------|-----------|---------------|
| **SKILL.md** | Full design system reference (tokens, all components, composition rules, extension protocol) | `.claude/skills/` — works in Claude Code, Cursor, OpenCode, Anigravity, etc. | | **SKILL.md** | Full design system reference (tokens, all components, composition rules, extension protocol) | `.claude/skills/` — works in Claude Code, Cursor, OpenCode, Anigravity, etc. |
| **AGENT.md** | Short project instructions telling the AI *how* to use the design system (like CLAUDE.md but portable) | Project root — copy as `AGENT.md`, `CLAUDE.md`, `.cursorrules`, or `.github/copilot-instructions.md` | | **AGENTS.md** | Short project instructions telling the AI *how* to use the design system (follows the [agents.md](https://agents.md) convention) | Project root — copy as `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, or `.github/copilot-instructions.md` |
| **MCP Server** | Runtime tools for looking up components, validating colors, suggesting components | Configured in `.mcp.json` | | **MCP Server** | Runtime tools for looking up components, validating colors, suggesting components | Configured in `.mcp.json` |
All are auto-generated from the same sources (`tokens/*.json` and `lib/catalog.ts`). All are auto-generated from the same sources (`tokens/*.json` and `lib/catalog.ts`).
@@ -71,11 +71,14 @@ All are auto-generated from the same sources (`tokens/*.json` and `lib/catalog.t
./skill/install.sh /path/to/your/project ./skill/install.sh /path/to/your/project
``` ```
This will: This **copies** (not symlinks) the following into your project:
1. Symlink `SKILL.md` into `.claude/skills/` (full reference for any AI agent) 1. `SKILL.md` `.claude/skills/greyhaven-design-system.md` (full reference)
2. Copy `AGENT.md` into the project root (project-level instructions) 2. `AGENTS.md` project root (project-level instructions)
3. Copy Aspekta font files into `public/fonts/` 3. Aspekta font files `public/fonts/`
4. Print CSS import instructions
The script also prints the CSS `@font-face` block and MCP server config to add next.
**Re-run the script after design system updates** to refresh your copies.
### SKILL.md (full reference) ### SKILL.md (full reference)
@@ -84,43 +87,37 @@ The skill file gives any AI agent full design system context — every token, ev
**It's a global standard** — works with Claude Code, Cursor, OpenCode, Anigravity, and any tool that reads skill files. **It's a global standard** — works with Claude Code, Cursor, OpenCode, Anigravity, and any tool that reads skill files.
```bash ```bash
# Via install script # Via install script (recommended — also handles fonts + AGENTS.md)
./skill/install.sh /path/to/your/project ./skill/install.sh /path/to/your/project
# Or manually # Or copy manually
mkdir -p /path/to/your/project/.claude/skills mkdir -p /path/to/your/project/.claude/skills
ln -sf /absolute/path/to/greyhaven-design-system/skill/SKILL.md \ cp /path/to/greyhaven-design-system/skill/SKILL.md \
/path/to/your/project/.claude/skills/greyhaven-design-system.md /path/to/your/project/.claude/skills/greyhaven-design-system.md
``` ```
### AGENT.md (project instructions) ### AGENTS.md (project instructions)
Short, directive instructions that tell the AI agent *how* to work in the project — use TypeScript, use semantic tokens, reference the MCP tools, etc. This is the equivalent of `CLAUDE.md` but portable across tools. Short, directive instructions that tell the AI agent *how* to work in the project — use TypeScript, use semantic tokens, reference the MCP tools, etc. Follows the [agents.md](https://agents.md) convention so it works with most AI coding tools out of the box.
**Copy it to your project root** under whichever name your tool reads: **Copy it to your project root** under whichever name your tool reads:
```bash ```bash
# Claude Code # Standard (agents.md convention — Cursor, OpenCode, Windsurf, Aider, etc.)
cp /path/to/greyhaven-design-system/skill/AGENT.md /path/to/your/project/CLAUDE.md cp /path/to/greyhaven-design-system/skill/AGENTS.md /path/to/your/project/AGENTS.md
# Cursor # Claude Code
cp /path/to/greyhaven-design-system/skill/AGENT.md /path/to/your/project/.cursorrules cp /path/to/greyhaven-design-system/skill/AGENTS.md /path/to/your/project/CLAUDE.md
# Cursor (legacy)
cp /path/to/greyhaven-design-system/skill/AGENTS.md /path/to/your/project/.cursorrules
# GitHub Copilot # GitHub Copilot
mkdir -p /path/to/your/project/.github mkdir -p /path/to/your/project/.github
cp /path/to/greyhaven-design-system/skill/AGENT.md /path/to/your/project/.github/copilot-instructions.md cp /path/to/greyhaven-design-system/skill/AGENTS.md /path/to/your/project/.github/copilot-instructions.md
# Or just use the install script which symlinks AGENT.md to the root
./skill/install.sh /path/to/your/project
# Or manually
ln -sf /absolute/path/to/greyhaven-design-system/skill/AGENT.md \
/path/to/your/project/AGENT.md
``` ```
Some tools use different file names. You can also symlink as: Or use the install script, which copies `AGENTS.md` to the project root automatically.
- `.cursorrules` (Cursor)
- `.github/copilot-instructions.md` (GitHub Copilot)
### Option C: MCP Server ### Option C: MCP Server

View File

@@ -1,15 +1,15 @@
#!/usr/bin/env npx tsx #!/usr/bin/env npx tsx
/** /**
* Generates skill/SKILL.md and skill/AGENT.md from the shared component * Generates skill/SKILL.md and skill/AGENTS.md from the shared component
* catalog and W3C DTCG token files. Run via `pnpm skill:build`. * catalog and W3C DTCG token files. Run via `pnpm skill:build`.
* *
* Both the MCP server and this script read from lib/catalog.ts and * Both the MCP server and this script read from lib/catalog.ts and
* tokens/*.json, so all outputs stay in sync. * tokens/*.json, so all outputs stay in sync.
* *
* Outputs: * Outputs:
* skill/SKILL.md — Claude Code skill (loaded via .claude/skills/) * skill/SKILL.md Full design system reference (tokens, components, rules)
* skill/AGENT.md — Generic AI agent instructions (Cursor, Copilot, etc.) * skill/AGENTS.md — Project-level instructions for any AI coding agent
*/ */
import * as fs from 'fs' import * as fs from 'fs'
@@ -45,7 +45,7 @@ function componentCount(): number {
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Shared content blocks (used by both SKILL.md and AGENT.md) // Shared content blocks (used by both SKILL.md and AGENTS.md)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function buildDesignPhilosophy(): string { function buildDesignPhilosophy(): string {
@@ -261,7 +261,7 @@ This skill gives you full context to generate pixel-perfect, on-brand UI using t
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// AGENT.md (project-level instructions for non-Claude AI agents) // AGENTS.md (project-level instructions for non-Claude AI agents)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function generateAgent(): string { function generateAgent(): string {
@@ -279,8 +279,8 @@ function generateAgent(): string {
> **Auto-generated** by the Greyhaven Design System. > **Auto-generated** by the Greyhaven Design System.
> Re-generate: \`pnpm skill:build\` in the design system repo. > Re-generate: \`pnpm skill:build\` in the design system repo.
> >
> Copy this file to your project root as \`AGENT.md\`, \`.cursorrules\`, > Copy this file to your project root as \`AGENTS.md\` (standard), \`CLAUDE.md\`,
> or \`.github/copilot-instructions.md\` depending on your AI tool. > \`.cursorrules\`, or \`.github/copilot-instructions.md\` depending on your AI tool.
This project uses the **Greyhaven Design System**. This project uses the **Greyhaven Design System**.
@@ -345,12 +345,12 @@ function main() {
const skillLines = skill.split('\n').length const skillLines = skill.split('\n').length
console.log(`skill/SKILL.md generated (${skillLines} lines, ${componentCount()} components)`) console.log(`skill/SKILL.md generated (${skillLines} lines, ${componentCount()} components)`)
// AGENT.md // AGENTS.md
const agent = generateAgent() const agent = generateAgent()
const agentPath = path.join(outDir, 'AGENT.md') const agentPath = path.join(outDir, 'AGENTS.md')
fs.writeFileSync(agentPath, agent, 'utf-8') fs.writeFileSync(agentPath, agent, 'utf-8')
const agentLines = agent.split('\n').length const agentLines = agent.split('\n').length
console.log(`skill/AGENT.md generated (${agentLines} lines, ${componentCount()} components)`) console.log(`skill/AGENTS.md generated (${agentLines} lines, ${componentCount()} components)`)
} }
main() main()

View File

@@ -3,8 +3,8 @@
> **Auto-generated** by the Greyhaven Design System. > **Auto-generated** by the Greyhaven Design System.
> Re-generate: `pnpm skill:build` in the design system repo. > Re-generate: `pnpm skill:build` in the design system repo.
> >
> Copy this file to your project root as `AGENT.md`, `.cursorrules`, > Copy this file to your project root as `AGENTS.md` (standard), `CLAUDE.md`,
> or `.github/copilot-instructions.md` depending on your AI tool. > `.cursorrules`, or `.github/copilot-instructions.md` depending on your AI tool.
This project uses the **Greyhaven Design System**. This project uses the **Greyhaven Design System**.

View File

@@ -1,11 +1,14 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# install.sh — Install the Greyhaven Design System into a consuming project. # install.sh — Install the Greyhaven Design System into a consuming project.
# #
# Copies (does NOT symlink) files so the consuming project owns its copies.
# Re-run this script to pull updated versions after design system changes.
#
# What it does: # What it does:
# 1. Symlinks SKILL.md into .claude/skills/ (for Claude Code) # 1. Copies SKILL.md into .claude/skills/ (for Claude Code)
# 2. Symlinks AGENT.md into the project root (for non-Claude AI agents) # 2. Copies AGENTS.md into the project root (standard convention)
# 3. Copies Aspekta font files + @font-face CSS into public/fonts/ # 3. Copies Aspekta font files + font-face.css into public/fonts/
# 4. Prints CSS import instructions for the consuming project # 4. Prints CSS import + MCP setup instructions
# #
# Usage: # Usage:
# ./skill/install.sh /path/to/your/project # ./skill/install.sh /path/to/your/project
@@ -15,7 +18,7 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
SKILL_FILE="${SCRIPT_DIR}/SKILL.md" SKILL_FILE="${SCRIPT_DIR}/SKILL.md"
AGENT_FILE="${SCRIPT_DIR}/AGENT.md" AGENTS_FILE="${SCRIPT_DIR}/AGENTS.md"
FONTS_DIR="${REPO_ROOT}/public/fonts" FONTS_DIR="${REPO_ROOT}/public/fonts"
if [ $# -ge 1 ]; then if [ $# -ge 1 ]; then
@@ -34,41 +37,43 @@ if [ ! -d "$TARGET_PROJECT" ]; then
exit 1 exit 1
fi fi
# Helper: backup existing file/symlink and copy new one
copy_with_backup() {
local src="$1"
local dst="$2"
if [ -L "$dst" ]; then
# Remove any existing symlink (leftover from old installs)
rm "$dst"
elif [ -f "$dst" ]; then
mv "$dst" "${dst}.bak"
echo " (backed up existing file to $(basename "${dst}.bak"))"
fi
cp "$src" "$dst"
}
echo "Installing Greyhaven Design System into ${TARGET_PROJECT}" echo "Installing Greyhaven Design System into ${TARGET_PROJECT}"
echo "" echo ""
# ── 1. Claude Skill ──────────────────────────────────────────────────────── # ── 1. SKILL.md ────────────────────────────────────────────────────────────
if [ -f "$SKILL_FILE" ]; then if [ -f "$SKILL_FILE" ]; then
SKILLS_DIR="${TARGET_PROJECT}/.claude/skills" SKILLS_DIR="${TARGET_PROJECT}/.claude/skills"
mkdir -p "$SKILLS_DIR" mkdir -p "$SKILLS_DIR"
LINK_PATH="${SKILLS_DIR}/greyhaven-design-system.md" DST="${SKILLS_DIR}/greyhaven-design-system.md"
copy_with_backup "$SKILL_FILE" "$DST"
if [ -L "$LINK_PATH" ]; then echo "[ok] SKILL.md: ${DST}"
rm "$LINK_PATH"
elif [ -f "$LINK_PATH" ]; then
mv "$LINK_PATH" "${LINK_PATH}.bak"
fi
ln -s "$SKILL_FILE" "$LINK_PATH"
echo "[ok] Claude Skill: ${LINK_PATH} -> ${SKILL_FILE}"
else else
echo "[skip] SKILL.md not found — run 'pnpm skill:build' first" echo "[skip] SKILL.md not found — run 'pnpm skill:build' first"
fi fi
# ── 2. AGENT.md ─────────────────────────────────────────────────────────── # ── 2. AGENTS.md ───────────────────────────────────────────────────────────
if [ -f "$AGENT_FILE" ]; then if [ -f "$AGENTS_FILE" ]; then
AGENT_LINK="${TARGET_PROJECT}/AGENT.md" DST="${TARGET_PROJECT}/AGENTS.md"
copy_with_backup "$AGENTS_FILE" "$DST"
if [ -L "$AGENT_LINK" ]; then echo "[ok] AGENTS.md: ${DST}"
rm "$AGENT_LINK"
elif [ -f "$AGENT_LINK" ]; then
mv "$AGENT_LINK" "${AGENT_LINK}.bak"
fi
ln -s "$AGENT_FILE" "$AGENT_LINK"
echo "[ok] AGENT.md: ${AGENT_LINK} -> ${AGENT_FILE}"
else else
echo "[skip] AGENT.md not found — run 'pnpm skill:build' first" echo "[skip] AGENTS.md not found — run 'pnpm skill:build' first"
fi fi
# ── 3. Fonts ─────────────────────────────────────────────────────────────── # ── 3. Fonts ───────────────────────────────────────────────────────────────
@@ -76,16 +81,15 @@ if [ -d "$FONTS_DIR" ]; then
TARGET_FONTS="${TARGET_PROJECT}/public/fonts" TARGET_FONTS="${TARGET_PROJECT}/public/fonts"
mkdir -p "$TARGET_FONTS" mkdir -p "$TARGET_FONTS"
# Copy only Aspekta woff2 files and the font-face CSS
copied=0 copied=0
for f in "$FONTS_DIR"/Aspekta-*.woff2; do for f in "$FONTS_DIR"/Aspekta-*.woff2; do
[ -f "$f" ] || continue [ -f "$f" ] || continue
cp -n "$f" "$TARGET_FONTS/" 2>/dev/null && copied=$((copied + 1)) || true cp "$f" "$TARGET_FONTS/"
copied=$((copied + 1))
done done
# Copy font-face.css
if [ -f "$FONTS_DIR/font-face.css" ]; then if [ -f "$FONTS_DIR/font-face.css" ]; then
cp -n "$FONTS_DIR/font-face.css" "$TARGET_FONTS/" 2>/dev/null || true cp "$FONTS_DIR/font-face.css" "$TARGET_FONTS/"
fi fi
echo "[ok] Fonts: ${copied} Aspekta woff2 files copied to ${TARGET_FONTS}/" echo "[ok] Fonts: ${copied} Aspekta woff2 files copied to ${TARGET_FONTS}/"
@@ -93,18 +97,37 @@ else
echo "[skip] Fonts dir not found at ${FONTS_DIR}" echo "[skip] Fonts dir not found at ${FONTS_DIR}"
fi fi
# ── Done ─────────────────────────────────────────────────────────────────── # ── Next steps ─────────────────────────────────────────────────────────────
echo "" cat <<'EOF'
echo "Done! Next steps for your project's CSS entry point:"
echo "" Done!
echo " /* Add these @font-face declarations to your global CSS */"
echo " @font-face { font-family: 'Aspekta'; font-weight: 400; font-display: swap; src: url('/fonts/Aspekta-400.woff2') format('woff2'); }" ─── Next steps ────────────────────────────────────────────────────────────
echo " @font-face { font-family: 'Aspekta'; font-weight: 500; font-display: swap; src: url('/fonts/Aspekta-500.woff2') format('woff2'); }"
echo " @font-face { font-family: 'Aspekta'; font-weight: 600; font-display: swap; src: url('/fonts/Aspekta-600.woff2') format('woff2'); }" 1. Add Aspekta @font-face to your global CSS:
echo " @font-face { font-family: 'Aspekta'; font-weight: 700; font-display: swap; src: url('/fonts/Aspekta-700.woff2') format('woff2'); }"
echo "" @font-face { font-family: 'Aspekta'; font-weight: 400; font-display: swap; src: url('/fonts/Aspekta-400.woff2') format('woff2'); }
echo " /* Or import the full set: */" @font-face { font-family: 'Aspekta'; font-weight: 500; font-display: swap; src: url('/fonts/Aspekta-500.woff2') format('woff2'); }
echo " @import url('/fonts/font-face.css');" @font-face { font-family: 'Aspekta'; font-weight: 600; font-display: swap; src: url('/fonts/Aspekta-600.woff2') format('woff2'); }
echo "" @font-face { font-family: 'Aspekta'; font-weight: 700; font-display: swap; src: url('/fonts/Aspekta-700.woff2') format('woff2'); }
echo " /* Set your font stack: */"
echo " --font-sans: 'Aspekta', ui-sans-serif, system-ui, sans-serif;" (Or import the full set: @import url('/fonts/font-face.css');)
And set the font stack:
--font-sans: 'Aspekta', ui-sans-serif, system-ui, sans-serif;
2. (Optional) Register the Greyhaven MCP server. Create .mcp.json in your
project root:
{
"mcpServers": {
"greyhaven": {
"command": "npx",
"args": ["tsx", "<ABSOLUTE_PATH_TO_GREYHAVEN_REPO>/mcp/server.ts"]
}
}
}
3. Re-run this script after design system updates to refresh your copies.
EOF