@windyroad/style-guide 0.2.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/.claude-plugin/plugin.json +5 -0
- package/agents/agent.md +83 -0
- package/bin/install.mjs +42 -0
- package/hooks/hooks.json +16 -0
- package/hooks/lib/review-gate.sh +102 -0
- package/hooks/style-guide-enforce-edit.sh +58 -0
- package/hooks/style-guide-eval.sh +34 -0
- package/hooks/style-guide-mark-reviewed.sh +49 -0
- package/hooks/style-guide-reset-marker.sh +22 -0
- package/package.json +28 -0
- package/skills/wr:style-guide/SKILL.md +96 -0
package/agents/agent.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent
|
|
3
|
+
description: Style guide reviewer for CSS and visual design changes. Use before
|
|
4
|
+
editing any CSS, style tokens, or visual styling in component style blocks,
|
|
5
|
+
.css files, or inline styles. Reads docs/STYLE-GUIDE.md and reviews proposed
|
|
6
|
+
changes against the guide. Reports violations with suggested fixes.
|
|
7
|
+
tools:
|
|
8
|
+
- Read
|
|
9
|
+
- Glob
|
|
10
|
+
- Grep
|
|
11
|
+
model: inherit
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
You are the Style Guide Lead. You review proposed styling changes against the project's docs/STYLE-GUIDE.md before any visual styling is edited. You are a reviewer, not an editor.
|
|
15
|
+
|
|
16
|
+
## Your Role
|
|
17
|
+
|
|
18
|
+
1. Read `docs/STYLE-GUIDE.md` in the project to load the current guide
|
|
19
|
+
2. Read the file(s) being edited to understand the existing styles and context
|
|
20
|
+
3. Review proposed changes against every section of the guide
|
|
21
|
+
4. Report: OK if compliant, or list specific violations with suggested fixes
|
|
22
|
+
|
|
23
|
+
## What You Check
|
|
24
|
+
|
|
25
|
+
All review criteria come from `docs/STYLE-GUIDE.md`. Read the guide first and apply its sections. Typical sections include:
|
|
26
|
+
|
|
27
|
+
- **Color tokens / palette** — whether colours use defined tokens, not hardcoded values
|
|
28
|
+
- **Typography** — font stacks, type scale, weight usage
|
|
29
|
+
- **Spacing** — spacing scale, touch target sizes
|
|
30
|
+
- **Component patterns** — button variants, form inputs, cards, tables
|
|
31
|
+
- **Layout & responsive** — mobile-first approach, breakpoints, max-widths
|
|
32
|
+
- **Motion & animation** — `prefers-reduced-motion` support, duration tokens
|
|
33
|
+
- **Dark mode** — CSS custom property usage, contrast in both modes
|
|
34
|
+
- **Border radius & shadows** — defined scales
|
|
35
|
+
|
|
36
|
+
If the guide defines additional sections, check those too. Do not invent rules that are not in the guide.
|
|
37
|
+
|
|
38
|
+
Additionally, always check WCAG AA contrast requirements regardless of whether the guide mentions them:
|
|
39
|
+
- Text on background: 4.5:1 minimum
|
|
40
|
+
- Large text (18px+ bold or 24px+): 3:1 minimum
|
|
41
|
+
- UI components and borders: 3:1
|
|
42
|
+
|
|
43
|
+
## How to Report
|
|
44
|
+
|
|
45
|
+
If the styling is compliant:
|
|
46
|
+
> **Style Guide Review: PASS**
|
|
47
|
+
> No violations found. Styling aligns with the style guide.
|
|
48
|
+
|
|
49
|
+
If there are violations, list each one:
|
|
50
|
+
|
|
51
|
+
> **Style Guide Review: VIOLATIONS FOUND**
|
|
52
|
+
>
|
|
53
|
+
> 1. **[Section/Rule]** - File: `path`, Line ~N
|
|
54
|
+
> - **Issue**: What is wrong
|
|
55
|
+
> - **Current**: The offending CSS/style
|
|
56
|
+
> - **Fix**: Suggested replacement using the correct token
|
|
57
|
+
>
|
|
58
|
+
> 2. ...
|
|
59
|
+
|
|
60
|
+
## Guide Gap Detection
|
|
61
|
+
|
|
62
|
+
If the code introduces a UI component, visual pattern, or design token not covered by `docs/STYLE-GUIDE.md`, flag this as a guide gap:
|
|
63
|
+
|
|
64
|
+
> **Style Guide Review: GUIDE UPDATE NEEDED**
|
|
65
|
+
>
|
|
66
|
+
> The code introduces [component/pattern/token] which is not covered by the current style guide.
|
|
67
|
+
> Recommended addition to `docs/STYLE-GUIDE.md`: [specific section/content to add]
|
|
68
|
+
|
|
69
|
+
This is a FAIL verdict — the guide must be updated before the code can proceed. Write `printf 'FAIL' > /tmp/style-guide-verdict` for guide gaps.
|
|
70
|
+
|
|
71
|
+
## Verdict
|
|
72
|
+
|
|
73
|
+
After completing your review, write your verdict to `/tmp/style-guide-verdict`:
|
|
74
|
+
- `printf 'PASS' > /tmp/style-guide-verdict` — styling is compliant and guide covers the patterns used
|
|
75
|
+
- `printf 'FAIL' > /tmp/style-guide-verdict` — violations found or guide gap detected
|
|
76
|
+
|
|
77
|
+
## Constraints
|
|
78
|
+
|
|
79
|
+
- You are read-only. You do not edit files (except writing the verdict file).
|
|
80
|
+
- You review styling in `.css` files and `<style>` blocks in component files.
|
|
81
|
+
- If the change has no visual/styling impact (logic, copy, structure only), report PASS.
|
|
82
|
+
- Do not review copy or text content (that is the voice-and-tone-lead's job).
|
|
83
|
+
- Do not review accessibility markup (that is the accessibility-lead's job).
|
package/bin/install.mjs
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { resolve, dirname } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const utils = await import(resolve(__dirname, "../../shared/install-utils.mjs"));
|
|
8
|
+
|
|
9
|
+
const PLUGIN = "wr-style-guide";
|
|
10
|
+
const DEPS = [];
|
|
11
|
+
|
|
12
|
+
const flags = utils.parseStandardArgs(process.argv);
|
|
13
|
+
|
|
14
|
+
if (flags.help) {
|
|
15
|
+
console.log(`
|
|
16
|
+
Usage: npx @windyroad/style-guide [options]
|
|
17
|
+
|
|
18
|
+
Style guide enforcement for CSS and UI components
|
|
19
|
+
|
|
20
|
+
Options:
|
|
21
|
+
--update Update this plugin and its skills
|
|
22
|
+
--uninstall Remove this plugin
|
|
23
|
+
--dry-run Show what would be done without executing
|
|
24
|
+
--help, -h Show this help
|
|
25
|
+
`);
|
|
26
|
+
process.exit(0);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (flags.dryRun) {
|
|
30
|
+
utils.setDryRun(true);
|
|
31
|
+
console.log("[dry-run mode — no commands will be executed]\n");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
utils.checkPrerequisites();
|
|
35
|
+
|
|
36
|
+
if (flags.uninstall) {
|
|
37
|
+
utils.uninstallPackage(PLUGIN);
|
|
38
|
+
} else if (flags.update) {
|
|
39
|
+
utils.updatePackage(PLUGIN);
|
|
40
|
+
} else {
|
|
41
|
+
utils.installPackage(PLUGIN, { deps: DEPS });
|
|
42
|
+
}
|
package/hooks/hooks.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"UserPromptSubmit": [
|
|
4
|
+
{ "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/style-guide-eval.sh" }] }
|
|
5
|
+
],
|
|
6
|
+
"PreToolUse": [
|
|
7
|
+
{ "matcher": "Edit|Write", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/style-guide-enforce-edit.sh" }] }
|
|
8
|
+
],
|
|
9
|
+
"PostToolUse": [
|
|
10
|
+
{ "matcher": "Agent", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/style-guide-mark-reviewed.sh" }] }
|
|
11
|
+
],
|
|
12
|
+
"Stop": [
|
|
13
|
+
{ "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/style-guide-reset-marker.sh" }] }
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Shared gate logic for review enforcement hooks (a11y, voice-tone, style-guide).
|
|
3
|
+
# Sourced by *-enforce-edit.sh hooks and review-plan-enforce.sh.
|
|
4
|
+
# Provides: check_review_gate, review_gate_deny, review_gate_parse_error
|
|
5
|
+
|
|
6
|
+
# Source shared portable helpers (_mtime, _hashcmd)
|
|
7
|
+
_REVIEW_GATE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
+
source "$_REVIEW_GATE_DIR/gate-helpers.sh"
|
|
9
|
+
|
|
10
|
+
# Check review gate marker. Returns 0 if marker is valid (allow), 1 if invalid (deny).
|
|
11
|
+
# Sets REVIEW_GATE_REASON on failure.
|
|
12
|
+
# Usage: check_review_gate "$SESSION_ID" "style-guide" "docs/STYLE-GUIDE.md"
|
|
13
|
+
check_review_gate() {
|
|
14
|
+
local SESSION_ID="$1"
|
|
15
|
+
local SYSTEM="$2" # e.g., "a11y", "voice-tone", "style-guide"
|
|
16
|
+
local POLICY_FILE="$3" # e.g., "docs/STYLE-GUIDE.md"
|
|
17
|
+
local MARKER="/tmp/${SYSTEM}-reviewed-${SESSION_ID}"
|
|
18
|
+
local HASH_FILE="/tmp/${SYSTEM}-reviewed-${SESSION_ID}.hash"
|
|
19
|
+
local TTL_SECONDS="${REVIEW_TTL:-600}"
|
|
20
|
+
|
|
21
|
+
# 1. Marker must exist
|
|
22
|
+
if [ ! -f "$MARKER" ]; then
|
|
23
|
+
REVIEW_GATE_REASON="No ${SYSTEM} review marker found. The ${SYSTEM} agent must review first."
|
|
24
|
+
return 1
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# 2. TTL check — marker mtime must be within TTL
|
|
28
|
+
local NOW=$(date +%s)
|
|
29
|
+
local MARKER_TIME=$(_mtime "$MARKER")
|
|
30
|
+
local AGE=$(( NOW - MARKER_TIME ))
|
|
31
|
+
if [ "$AGE" -ge "$TTL_SECONDS" ]; then
|
|
32
|
+
rm -f "$MARKER" "$HASH_FILE"
|
|
33
|
+
REVIEW_GATE_REASON="${SYSTEM} review expired (${AGE}s old, TTL ${TTL_SECONDS}s). Re-run the ${SYSTEM} agent."
|
|
34
|
+
return 1
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# 3. Drift detection — policy file hash must match
|
|
38
|
+
if [ -f "$HASH_FILE" ] && [ -n "$POLICY_FILE" ]; then
|
|
39
|
+
local STORED_HASH=$(cat "$HASH_FILE")
|
|
40
|
+
local CURRENT_HASH=""
|
|
41
|
+
if [ -f "$POLICY_FILE" ]; then
|
|
42
|
+
CURRENT_HASH=$(cat "$POLICY_FILE" | _hashcmd | cut -d' ' -f1)
|
|
43
|
+
elif [ -d "$POLICY_FILE" ]; then
|
|
44
|
+
# Directory (e.g., docs/decisions/) — hash all .md files
|
|
45
|
+
CURRENT_HASH=$(find "$POLICY_FILE" -name '*.md' -not -name 'README.md' -print0 | sort -z | xargs -0 cat 2>/dev/null | _hashcmd | cut -d' ' -f1)
|
|
46
|
+
else
|
|
47
|
+
CURRENT_HASH="missing"
|
|
48
|
+
fi
|
|
49
|
+
if [ "$STORED_HASH" != "$CURRENT_HASH" ]; then
|
|
50
|
+
rm -f "$MARKER" "$HASH_FILE"
|
|
51
|
+
REVIEW_GATE_REASON="${SYSTEM} policy file changed since last review. Re-run the ${SYSTEM} agent."
|
|
52
|
+
return 1
|
|
53
|
+
fi
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# Slide TTL window forward
|
|
57
|
+
touch "$MARKER"
|
|
58
|
+
return 0
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
# Store policy file hash after a successful review.
|
|
62
|
+
# Usage: store_review_hash "$SESSION_ID" "style-guide" "docs/STYLE-GUIDE.md"
|
|
63
|
+
store_review_hash() {
|
|
64
|
+
local SESSION_ID="$1"
|
|
65
|
+
local SYSTEM="$2"
|
|
66
|
+
local POLICY_FILE="$3"
|
|
67
|
+
local HASH_FILE="/tmp/${SYSTEM}-reviewed-${SESSION_ID}.hash"
|
|
68
|
+
|
|
69
|
+
if [ -n "$POLICY_FILE" ]; then
|
|
70
|
+
local HASH=""
|
|
71
|
+
if [ -f "$POLICY_FILE" ]; then
|
|
72
|
+
HASH=$(cat "$POLICY_FILE" | _hashcmd | cut -d' ' -f1)
|
|
73
|
+
elif [ -d "$POLICY_FILE" ]; then
|
|
74
|
+
HASH=$(find "$POLICY_FILE" -name '*.md' -not -name 'README.md' -print0 | sort -z | xargs -0 cat 2>/dev/null | _hashcmd | cut -d' ' -f1)
|
|
75
|
+
else
|
|
76
|
+
HASH="missing"
|
|
77
|
+
fi
|
|
78
|
+
echo "$HASH" > "$HASH_FILE"
|
|
79
|
+
fi
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# Emit fail-closed deny JSON for PreToolUse hooks.
|
|
83
|
+
review_gate_deny() {
|
|
84
|
+
local REASON="$1"
|
|
85
|
+
cat <<EOF
|
|
86
|
+
{
|
|
87
|
+
"hookSpecificOutput": {
|
|
88
|
+
"hookEventName": "PreToolUse",
|
|
89
|
+
"permissionDecision": "deny",
|
|
90
|
+
"permissionDecisionReason": "$REASON"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
EOF
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# Emit fail-closed deny JSON for parse failures.
|
|
97
|
+
review_gate_parse_error() {
|
|
98
|
+
cat <<'EOF'
|
|
99
|
+
{ "hookSpecificOutput": { "hookEventName": "PreToolUse", "permissionDecision": "deny",
|
|
100
|
+
"permissionDecisionReason": "BLOCKED: Could not parse hook input. Gate is fail-closed." } }
|
|
101
|
+
EOF
|
|
102
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Style Guide - PreToolUse enforcement hook
|
|
3
|
+
# BLOCKS Edit/Write to UI source files until style-guide-lead is consulted.
|
|
4
|
+
# Uses shared review-gate.sh for TTL, drift detection, and fail-closed.
|
|
5
|
+
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
7
|
+
source "$SCRIPT_DIR/lib/review-gate.sh"
|
|
8
|
+
|
|
9
|
+
INPUT=$(cat)
|
|
10
|
+
|
|
11
|
+
FILE_PATH=$(echo "$INPUT" | python3 -c "
|
|
12
|
+
import sys, json
|
|
13
|
+
try:
|
|
14
|
+
data = json.load(sys.stdin)
|
|
15
|
+
print(data.get('tool_input', {}).get('file_path', ''))
|
|
16
|
+
except:
|
|
17
|
+
print('')
|
|
18
|
+
" 2>/dev/null || echo "")
|
|
19
|
+
|
|
20
|
+
SESSION_ID=$(echo "$INPUT" | python3 -c "
|
|
21
|
+
import sys, json
|
|
22
|
+
try:
|
|
23
|
+
data = json.load(sys.stdin)
|
|
24
|
+
print(data.get('session_id', ''))
|
|
25
|
+
except:
|
|
26
|
+
print('')
|
|
27
|
+
" 2>/dev/null || echo "")
|
|
28
|
+
|
|
29
|
+
if [ -z "$SESSION_ID" ]; then
|
|
30
|
+
review_gate_parse_error
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
if [ -z "$FILE_PATH" ]; then
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# Gate all UI source files (CSS and component files)
|
|
39
|
+
case "$FILE_PATH" in
|
|
40
|
+
*.css|*.html|*.jsx|*.tsx|*.vue|*.svelte|*.ejs|*.hbs) ;;
|
|
41
|
+
*) exit 0 ;;
|
|
42
|
+
esac
|
|
43
|
+
|
|
44
|
+
BASENAME=$(basename "$FILE_PATH")
|
|
45
|
+
|
|
46
|
+
# If no policy file exists, block and direct to create skill
|
|
47
|
+
if [ ! -f "docs/STYLE-GUIDE.md" ]; then
|
|
48
|
+
review_gate_deny "BLOCKED: Cannot edit '${BASENAME}' because docs/STYLE-GUIDE.md does not exist. Run /wr-style-guide:create to generate a style guide for this project, then delegate to wr-style-guide:agent for review."
|
|
49
|
+
exit 0
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Check gate with TTL + drift detection
|
|
53
|
+
if check_review_gate "$SESSION_ID" "style-guide" "docs/STYLE-GUIDE.md"; then
|
|
54
|
+
exit 0
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
review_gate_deny "BLOCKED: Cannot edit '${BASENAME}' without style guide review. You MUST first delegate to wr-style-guide:agent using the Agent tool (subagent_type: 'wr-style-guide:agent'). ${REVIEW_GATE_REASON}"
|
|
58
|
+
exit 0
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Style Guide - UserPromptSubmit hook
|
|
3
|
+
# Detects STYLE-GUIDE.md in the project and injects delegation instruction.
|
|
4
|
+
# If the file doesn't exist, instructs Claude to create it via the agent.
|
|
5
|
+
|
|
6
|
+
if [ -f "docs/STYLE-GUIDE.md" ]; then
|
|
7
|
+
cat <<'HOOK_OUTPUT'
|
|
8
|
+
INSTRUCTION: MANDATORY STYLE GUIDE CHECK. YOU MUST FOLLOW THIS.
|
|
9
|
+
DETECTED: docs/STYLE-GUIDE.md exists in this project.
|
|
10
|
+
|
|
11
|
+
This is a NON-OPTIONAL instruction. You MUST use the style-guide-lead agent
|
|
12
|
+
before editing any .css or UI component file. This is proactive.
|
|
13
|
+
Do not wait for the user to ask.
|
|
14
|
+
|
|
15
|
+
REQUIRED ACTIONS:
|
|
16
|
+
1. Use the Agent tool to delegate to wr-style-guide:agent
|
|
17
|
+
(subagent_type: "wr-style-guide:agent")
|
|
18
|
+
2. The style-guide-lead will review proposed styling against docs/STYLE-GUIDE.md
|
|
19
|
+
3. Do NOT write or edit styling without style-guide-lead review FIRST
|
|
20
|
+
4. Do NOT skip this step even if you think you can handle it yourself
|
|
21
|
+
|
|
22
|
+
SCOPE: All .css and UI component files (.html, .jsx, .tsx, .vue, .svelte, .ejs, .hbs).
|
|
23
|
+
Does NOT apply to: .ts/.js backend files, .md files, config files.
|
|
24
|
+
HOOK_OUTPUT
|
|
25
|
+
else
|
|
26
|
+
# Check if this is a web project (has UI files)
|
|
27
|
+
if ls src/**/*.tsx src/**/*.jsx src/**/*.css src/**/*.html 2>/dev/null | head -1 | grep -q .; then
|
|
28
|
+
cat <<'HOOK_OUTPUT'
|
|
29
|
+
NOTE: This project has UI files but no docs/STYLE-GUIDE.md.
|
|
30
|
+
If the user's task involves editing CSS or UI components, the edit will be blocked
|
|
31
|
+
until a style guide exists. Run /wr-style-guide:create to generate one.
|
|
32
|
+
HOOK_OUTPUT
|
|
33
|
+
fi
|
|
34
|
+
fi
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Style Guide - PostToolUse hook for Agent tool
|
|
3
|
+
# Creates a session marker when style-guide-lead has been consulted with PASS verdict.
|
|
4
|
+
# This marker unlocks the style-guide-enforce-edit.sh PreToolUse block.
|
|
5
|
+
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
7
|
+
source "$SCRIPT_DIR/lib/review-gate.sh"
|
|
8
|
+
|
|
9
|
+
INPUT=$(cat)
|
|
10
|
+
|
|
11
|
+
SUBAGENT=$(echo "$INPUT" | jq -r '.tool_input.subagent_type // empty') || true
|
|
12
|
+
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty') || true
|
|
13
|
+
|
|
14
|
+
if [ -z "$SESSION_ID" ]; then
|
|
15
|
+
exit 0
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
case "$SUBAGENT" in
|
|
19
|
+
*style-guide-lead*|*wr-style-guide*)
|
|
20
|
+
VERDICT_FILE="/tmp/style-guide-verdict"
|
|
21
|
+
VERDICT=""
|
|
22
|
+
if [ -f "$VERDICT_FILE" ]; then
|
|
23
|
+
VERDICT=$(cat "$VERDICT_FILE")
|
|
24
|
+
rm -f "$VERDICT_FILE"
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
case "$VERDICT" in
|
|
28
|
+
PASS)
|
|
29
|
+
touch "/tmp/style-guide-reviewed-${SESSION_ID}"
|
|
30
|
+
store_review_hash "$SESSION_ID" "style-guide" "docs/STYLE-GUIDE.md"
|
|
31
|
+
;;
|
|
32
|
+
FAIL)
|
|
33
|
+
# Do NOT create marker — review found issues
|
|
34
|
+
;;
|
|
35
|
+
*)
|
|
36
|
+
# No verdict file — backward compat, allow with marker
|
|
37
|
+
touch "/tmp/style-guide-reviewed-${SESSION_ID}"
|
|
38
|
+
store_review_hash "$SESSION_ID" "style-guide" "docs/STYLE-GUIDE.md"
|
|
39
|
+
;;
|
|
40
|
+
esac
|
|
41
|
+
|
|
42
|
+
# Plan review: agent completion = reviewed.
|
|
43
|
+
# The main agent must actually run the review agent to reach this hook.
|
|
44
|
+
# No verdict file needed — PostToolUse:Agent is the unforgeable signal.
|
|
45
|
+
touch "/tmp/style-guide-plan-reviewed-${SESSION_ID}"
|
|
46
|
+
;;
|
|
47
|
+
esac
|
|
48
|
+
|
|
49
|
+
exit 0
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Style Guide - Stop hook
|
|
3
|
+
# Removes the session marker so the next prompt requires a fresh style review.
|
|
4
|
+
# This tightens the gate from per-session to per-turn.
|
|
5
|
+
|
|
6
|
+
INPUT=$(cat)
|
|
7
|
+
|
|
8
|
+
SESSION_ID=$(echo "$INPUT" | python3 -c "
|
|
9
|
+
import sys, json
|
|
10
|
+
data = json.load(sys.stdin)
|
|
11
|
+
print(data.get('session_id', ''))
|
|
12
|
+
" 2>/dev/null)
|
|
13
|
+
|
|
14
|
+
if [ -n "$SESSION_ID" ]; then
|
|
15
|
+
rm -f "/tmp/style-guide-reviewed-${SESSION_ID}" \
|
|
16
|
+
"/tmp/style-guide-reviewed-${SESSION_ID}.hash" \
|
|
17
|
+
"/tmp/style-guide-verdict" \
|
|
18
|
+
"/tmp/style-guide-plan-reviewed-${SESSION_ID}" \
|
|
19
|
+
"/tmp/style-guide-plan-verdict"
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
exit 0
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@windyroad/style-guide",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Style guide enforcement for CSS and UI components",
|
|
5
|
+
"bin": {
|
|
6
|
+
"windyroad-style-guide": "./bin/install.mjs"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/windyroad/agent-plugins.git",
|
|
13
|
+
"directory": "packages/style-guide"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"claude-code",
|
|
17
|
+
"claude-code-plugin",
|
|
18
|
+
"ai-agent",
|
|
19
|
+
"ai-coding"
|
|
20
|
+
],
|
|
21
|
+
"files": [
|
|
22
|
+
"bin/",
|
|
23
|
+
"agents/",
|
|
24
|
+
"hooks/",
|
|
25
|
+
"skills/",
|
|
26
|
+
".claude-plugin/"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wr:style-guide
|
|
3
|
+
description: Create or update the project's docs/STYLE-GUIDE.md by examining existing CSS, components, and design patterns, then asking the user about style preferences.
|
|
4
|
+
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Style Guide Generator
|
|
8
|
+
|
|
9
|
+
Create or update `docs/STYLE-GUIDE.md` tailored to this project's visual design and component patterns. The style-guide-lead agent reads this file to review CSS and UI component changes.
|
|
10
|
+
|
|
11
|
+
## What belongs in docs/STYLE-GUIDE.md
|
|
12
|
+
|
|
13
|
+
- **Design tokens**: Colors, spacing, typography, border radius, shadows
|
|
14
|
+
- **Component patterns**: How common UI elements should be built
|
|
15
|
+
- **Layout conventions**: Grid system, responsive breakpoints, spacing rhythm
|
|
16
|
+
- **CSS conventions**: Naming, architecture (BEM, utility-first, CSS modules, etc.)
|
|
17
|
+
- **Do/Don't examples**: Concrete examples drawn from the actual project
|
|
18
|
+
- **Last reviewed date**: When the guide was last reviewed or updated
|
|
19
|
+
|
|
20
|
+
## Steps
|
|
21
|
+
|
|
22
|
+
### 1. Discover project context
|
|
23
|
+
|
|
24
|
+
Examine the project to understand its current styling approach.
|
|
25
|
+
|
|
26
|
+
**Find the CSS architecture** by scanning for:
|
|
27
|
+
- CSS/SCSS/Sass/Less files and their structure
|
|
28
|
+
- Tailwind config (`tailwind.config.*`)
|
|
29
|
+
- CSS-in-JS patterns (styled-components, emotion, CSS modules)
|
|
30
|
+
- Design token files or theme configuration
|
|
31
|
+
- Component library usage (MUI, Chakra, Radix, shadcn, etc.)
|
|
32
|
+
|
|
33
|
+
**Discover design patterns**:
|
|
34
|
+
- Color palette (scan CSS custom properties, Tailwind config, or theme files)
|
|
35
|
+
- Typography scale (font sizes, weights, line heights in use)
|
|
36
|
+
- Spacing system (consistent spacing values or ad-hoc)
|
|
37
|
+
- Component structure (how are common patterns like cards, buttons, forms built?)
|
|
38
|
+
- Responsive approach (breakpoints, mobile-first vs desktop-first)
|
|
39
|
+
|
|
40
|
+
**Identify inconsistencies**:
|
|
41
|
+
- Are there multiple color values that should be the same token?
|
|
42
|
+
- Mixed approaches (some components use utility classes, others use custom CSS)?
|
|
43
|
+
- Inconsistent spacing or typography?
|
|
44
|
+
|
|
45
|
+
### 2. Check for existing guide
|
|
46
|
+
|
|
47
|
+
If `docs/STYLE-GUIDE.md` already exists, read it. Identify:
|
|
48
|
+
- Whether it still reflects the current CSS architecture
|
|
49
|
+
- Whether examples reference classes or patterns that no longer exist
|
|
50
|
+
- Whether the last reviewed date is stale (> 2 weeks)
|
|
51
|
+
|
|
52
|
+
### 3. Draft the style guide
|
|
53
|
+
|
|
54
|
+
Based on project discovery, draft sections covering:
|
|
55
|
+
|
|
56
|
+
**CSS Architecture**:
|
|
57
|
+
What approach this project uses and why (utility-first, BEM, CSS modules, etc.).
|
|
58
|
+
|
|
59
|
+
**Design Tokens**:
|
|
60
|
+
Document the token system (colors, spacing, typography, shadows, borders). Reference the actual source (CSS variables, Tailwind config, theme file).
|
|
61
|
+
|
|
62
|
+
**Component Patterns**:
|
|
63
|
+
How to build common UI elements. At least cover: buttons, forms, cards, navigation, layout containers.
|
|
64
|
+
|
|
65
|
+
**Layout and Responsive**:
|
|
66
|
+
Grid system, breakpoints, spacing rhythm, container widths.
|
|
67
|
+
|
|
68
|
+
**Do/Don't Examples**:
|
|
69
|
+
At least 5 concrete pairs drawn from the actual project. Show the wrong way and the right way.
|
|
70
|
+
|
|
71
|
+
**Naming Conventions**:
|
|
72
|
+
Class naming, file naming, component naming patterns.
|
|
73
|
+
|
|
74
|
+
### 4. Confirm with the user
|
|
75
|
+
|
|
76
|
+
You MUST use the AskUserQuestion tool to collect user confirmation.
|
|
77
|
+
|
|
78
|
+
Present:
|
|
79
|
+
1. The CSS architecture summary and ask if it's accurate
|
|
80
|
+
2. The design tokens discovered and ask if any are wrong or missing
|
|
81
|
+
3. The component patterns and ask if the direction is right
|
|
82
|
+
4. Whether any specific requirements are missing (e.g., dark mode, accessibility contrast requirements, animation preferences)
|
|
83
|
+
|
|
84
|
+
### 5. Write docs/STYLE-GUIDE.md
|
|
85
|
+
|
|
86
|
+
Write the guide including:
|
|
87
|
+
- A header with "Last reviewed" date (today's date)
|
|
88
|
+
- All sections from step 3, refined based on user feedback from step 4
|
|
89
|
+
- A note that the wr-style-guide:agent reads this file to review CSS and UI changes
|
|
90
|
+
|
|
91
|
+
If updating rather than creating:
|
|
92
|
+
- Preserve existing guidance the user hasn't asked to change
|
|
93
|
+
- Show the user a diff of what changed
|
|
94
|
+
- Update the "Last reviewed" date
|
|
95
|
+
|
|
96
|
+
$ARGUMENTS
|