PatternFly Compliance Checker for Figma Files#19
PatternFly Compliance Checker for Figma Files#19phcox wants to merge 4 commits intopatternfly:mainfrom
Conversation
|
Example compliance report: |
|
this is cool. i havent used figma in a year but this is very cool. |
|
Thanks @JustinXHale. This is just the first version and I'm sure I'll be updating and improving it in the near future. If you end up using it on a Figma design, please send me any feedback you have. |
| @@ -0,0 +1,246 @@ | |||
| # PatternFly Compliance Checker | |||
There was a problem hiding this comment.
Files are loose in plugins/pf-react/skills/ instead of in a skill subdirectory. This needs to be plugins/<plugin>/skills/pf-compliance-checker/SKILL.md - named SKILL.md, inside a directory matching the skill name.
| @@ -0,0 +1,246 @@ | |||
| # PatternFly Compliance Checker | |||
|
|
|||
There was a problem hiding this comment.
Missing required frontmatter (name and description). Every skill needs this for the AI to decide when to load it.
|
|
||
| ## Prerequisites | ||
| - Figma token stored in: `/Users/patrickcox/.claude/projects/-Users-patrickcox/memory/figma-config.env` | ||
| - Node.js installed |
There was a problem hiding this comment.
Hardcoded paths to /Users/patrickcox/... throughout - these won't work for anyone else. Use $CLAUDE_SKILL_DIR to reference the script relative to the skill directory.
| @@ -0,0 +1,321 @@ | |||
| # How to Use the PatternFly Compliance Checker Skill | |||
There was a problem hiding this comment.
A 321-line user guide on top of a 246-line skill definition is a lot. The skill itself should be self-contained - usage docs belong in the plugin README, not as a separate file in the skills directory.
| @@ -0,0 +1,2723 @@ | |||
| #!/usr/bin/env node | |||
There was a problem hiding this comment.
This checks Figma designs, so it belongs in the figma plugin, not react. The figma plugin exists for anything that requires Figma as input.
| @@ -0,0 +1 @@ | |||
|
|
|||
There was a problem hiding this comment.
Empty placeholder file - can be removed.
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
📝 WalkthroughWalkthroughIntroduces a new PatternFly Compliance Checker skill for the pf-react plugin, consisting of a Node.js CLI tool that validates Figma UI prototypes against PatternFly v6 design standards, generating an HTML compliance report with detailed violations, fixes, and analytics. Changes
Sequence Diagram(s)sequenceDiagram
participant User as User/CLI
participant Config as Config<br/>(figma-config.env)
participant FigmaAPI as Figma API
participant Analyzer as Compliance<br/>Analyzer
participant Report as HTML Report<br/>Generator
User->>Config: Load FIGMA_TOKEN
User->>User: Parse Figma URL<br/>(extract file ID)
User->>FigmaAPI: Fetch Figma file<br/>with token
FigmaAPI-->>User: Return file structure
User->>Analyzer: Recursively analyze<br/>document nodes
Analyzer->>Analyzer: Check components<br/>(buttons, inputs, cards, etc.)
Analyzer->>Analyzer: Validate design tokens<br/>(spacing, sizing, colors)
Analyzer->>Analyzer: Classify findings<br/>(critical/warning/compliant)
Analyzer->>Analyzer: Compute compliance<br/>scores & patterns
Analyzer-->>Report: Pass ComplianceReport
Report->>Report: Generate HTML with<br/>collapsible sections
Report->>Report: Build JSON export &<br/>Figma links
Report-->>User: Write timestamped<br/>.html file
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Rationale: The Guidelines AppliedPer skill-creator standards: verified clear documentation (purpose, trigger, prerequisites, execution flow, examples, error scenarios, success metrics), comprehensive usage patterns (natural-language and programmatic paths), explicit error handling (missing token, invalid URL, API failures), expected output specifications (HTML structure, JSON schema), and constraint documentation (rate limits, performance, token expiry). Implementation aligns with CLIbased skill patterns providing single-file executable, environment-based configuration, and automated artifact generation (timestamped reports). Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
♻️ Duplicate comments (3)
plugins/pf-react/skills/placeholder.txt (1)
1-1:⚠️ Potential issue | 🟠 MajorReplace this placeholder with a real skill scaffold (or remove it).
An empty
placeholder.txtunderplugins/pf-react/skills/does not match the required skill layout. Please create a proper skill directory (kebab-case, PatternFly-specific name prefixed withpf-) with aSKILL.md, and place it under the domain-appropriate plugin (pf-figmafor Figma tooling).As per coding guidelines: "
plugins/*/skills/**: Create a directory under the plugin'sskills/folder with the patternplugins/<plugin-name>/skills/your-skill/" and "plugins/*/+(skills|agents)/**: Use thepf-prefix on skill and agent names that are PatternFly-specific." Based on learnings: "Add aSKILL.mdfile..." and "Choose the appropriate plugin...pf-figma(design tooling)."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@plugins/pf-react/skills/placeholder.txt` at line 1, The placeholder.txt in plugins/pf-react/skills is invalid; replace it by creating a new skill directory named in kebab-case with the pf- prefix (e.g., pf-figma-skill) under the appropriate plugin (move to plugins/pf-figma/skills/), add a SKILL.md describing the skill (purpose, inputs, outputs, examples), remove the empty placeholder.txt, and ensure the new directory follows the required pattern plugins/<plugin-name>/skills/pf-<your-skill>/ so the skill scaffold matches the repo conventions.plugins/pf-react/skills/patternfly-check-skill.md (2)
1-24:⚠️ Potential issue | 🟠 MajorTurn this into a discoverable skill package before landing it.
This is still in the wrong plugin for a Figma tool, sits loose under
skills/, is not namedSKILL.md, has no required frontmatter, and the current name misses the requiredpf-prefix. Please move the whole skill into something likeplugins/pf-figma/skills/pf-patternfly-compliance-checker/SKILL.mdand makenamematch the directory.Based on learnings: "Choose the appropriate plugin for your skill based on its domain: pf-react (component development), pf-styling (visual implementation), pf-a11y (accessibility), pf-figma (design tooling), or pf-workflow (project operations)", "Frontmatter is required in SKILL.md with
nameanddescription", and "The skill directory name, SKILL.md file name, and frontmatternamemust all match to avoid confusing behavior when invoking the skill."; as per coding guidelines:plugins/*/skills/**must useplugins/<plugin-name>/skills/your-skill/and PatternFly-specific skill names need thepf-prefix.
14-16:⚠️ Potential issue | 🟠 MajorDrop the workstation-specific paths from the skill body.
These commands/output locations only work on one machine, and the output path is wrong anyway because the CLI writes to the caller's current working directory. Reference the checker relative to the skill directory instead of baking in
/Users/patrickcox/....Based on learnings: "Use
$CLAUDE_SKILL_DIRto reference scripts relative to the skill directory — it resolves to the directory containing SKILL.md regardless of where the repo is cloned" and "Skills must be tool-agnostic — they run in both Claude Code and Cursor. Avoid referencing a specific tool (e.g., use 'Assistant:' instead of 'Claude:' in examples)."Also applies to: 34-36, 49-54, 80-81
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@plugins/pf-react/skills/patternfly-check-skill.md` around lines 14 - 16, Remove workstation-specific absolute paths and tool-specific references in plugins/pf-react/skills/patternfly-check-skill.md: replace any hard-coded paths like `/Users/patrickcox/...` with a relative reference using $CLAUDE_SKILL_DIR to point to scripts/checker inside the skill directory, update output paths to reflect the caller's CWD (do not bake in machine paths), and replace tool-specific labels such as "Claude:" with neutral "Assistant:"; apply these changes to the occurrences around the shown ranges (lines 14-16, 34-36, 49-54, 80-81) so the skill is portable and tool-agnostic.
🧹 Nitpick comments (2)
plugins/pf-react/skills/SKILL-USAGE.md (1)
1-1: Rename this guide if it survives the skill repackage.
SKILL-USAGE.mdbreaks the repo-wide kebab-case filename rule. If you keep a separate guide after moving the skill, rename it to something likeskill-usage.md.As per coding guidelines:
**/*: "Use kebab-case for directory and file names".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@plugins/pf-react/skills/SKILL-USAGE.md` at line 1, The filename SKILL-USAGE.md violates the repo kebab-case rule; rename the file to a kebab-case name such as skill-usage.md and update any references to it (documentation links, README entries, or tooling that expects SKILL-USAGE.md) so they point to the new name; ensure the commit and PR include the renamed file only (or a git mv) to preserve history and update any mentions of "SKILL-USAGE.md" in the repository to "skill-usage.md".plugins/pf-react/skills/patternfly-check-skill.md (1)
24-48: Trim this to a shorter, outcome-first skill brief.The numbered shell steps, sample console transcript, and browser instructions read like a local runbook. A skill-creator-style
SKILL.mdhere should stay concise and focus on trigger, desired outcome, constraints, and follow-up guidance.Based on learnings: "Describe outcomes, not implementation in skills — tell the AI what to accomplish, not how to do it."
Also applies to: 56-64
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@plugins/pf-react/skills/patternfly-check-skill.md` around lines 24 - 48, Update the "Execution Steps" section of plugins/pf-react/skills/patternfly-check-skill.md (the "Execution Steps" heading and the numbered steps 1–3) to a concise, outcome-first SKILL.md: remove the local runbook-style numbered shell commands and verbose parsing checklist, and replace them with a short trigger/intent statement, the desired outcome (what the compliance check should produce, e.g., "Produce an HTML report summarizing PatternFly violations with Figma deep links"), key constraints or inputs (valid Figma URL formats), and brief follow-up guidance (what to do with the report); apply the same trimming to the content referenced at lines 56–64 so the file focuses on outcomes, constraints, and next steps rather than implementation details.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@plugins/pf-react/skills/patternfly-check.js`:
- Around line 1187-1194: The detached-instance metric is never incremented
because getComponentSource only calls checkIfDetached when node.componentId
exists, but checkIfDetached returns true only when componentId is missing;
update getComponentSource to compute isDetached by calling checkIfDetached(node)
regardless of node.componentId (or invert the condition inside checkIfDetached
so it detects detached instances even when componentId is present), and return
that boolean as the isDetached field so the detached-instance metric and
"Component Library Sync" section can register correctly; adjust the same pattern
in the other occurrence around lines 1205-1214 (the duplicate getComponentSource
usage).
- Around line 2684-2689: The report HTML is written (report.generateHTML ->
html, fs.writeFileSync(outputPath, html, 'utf-8')) but never auto-opens; modify
the function to launch the default browser after writing by invoking a
cross-platform opener (e.g., use Node's child_process.exec or the 'open'
package) to open outputPath, and handle errors gracefully (log on failure).
Ensure you reference outputPath when calling the opener and keep the existing
console.log messages.
- Around line 649-650: The template embeds untrusted Figma-derived values (e.g.,
this.fileName, layer names, issue/fix text, microcopy and the JSON payload)
directly into HTML and an inline <script>; sanitize these before embedding by
escaping HTML special characters when inserting into markup (implement and use a
helper like escapeHtml for values such as this.fileName, layer names, issue/fix
text, microcopy) and by safely serializing data into the script (use
JSON.stringify for the payload and then escape any "</script>" sequences or use
a safe wrapper that replaces "</" with "<\\/") so no attacker-supplied string
can break out of the HTML or script context; update all affected interpolations
(including the occurrences noted around the template: the current
this.fileName/this.date insertion and the other ranges referenced) to use these
escaping/serialization helpers.
- Around line 1162-1181: The current isPatternFlyComponent function flags any
instance with generic nouns (e.g., "button", "card") as PatternFly; change it to
only detect explicit PF identifiers by removing generic component words and
instead checking for explicit markers on the instance/component metadata: use
node.componentId or resolve the instance's main component (e.g.,
node.mainComponent or look up by node.componentId) and inspect its
name/pluginData/libraryKey for exact tokens like "pf-", "patternfly",
"pattern-fly", "PatternFly", or "redhat" (case-insensitive). Update
isPatternFlyComponent to return true only if those explicit identifiers are
present in the component's id/name/pluginData, and no longer rely on generic
nouns like "button", "card", "modal", etc.
- Around line 16-33: Currently the code always tries to read CONFIG_PATH and
exits if figma-config.env is missing; change the logic to first check
process.env.FIGMA_TOKEN and assign that to FIGMA_TOKEN if present, and only if
not present attempt to read CONFIG_PATH (the existing fs.readFileSync/tokenMatch
logic). Update the error path in the catch/else to only exit if neither
process.env.FIGMA_TOKEN nor the file provided a token, referencing CONFIG_PATH
and FIGMA_TOKEN so CI/headless runs that set FIGMA_TOKEN in the environment work
without requiring the local figma-config.env file.
- Around line 35-67: The checker hardcodes old v6 token names (e.g. --pf-v6-*)
in PATTERNFLY_TOKENS (colors, typography, components) and will recommend
non-existent tokens; update all token name strings to the repository's canonical
--pf-t--* naming scheme (e.g. map tokens like --pf-v6-global--FontSize--md to
--pf-t--global--font--size--md) and ensure the typography size entries in
PATTERNFLY_TOKENS.typography remain the same values ([12,14,16,18,20,24]) but
use the --pf-t--global--font--size--* token names, and similarly rename
color/component tokens to their --pf-t-- equivalents so the checker emits
repository-standard token recommendations.
In `@plugins/pf-react/skills/SKILL-USAGE.md`:
- Around line 8-16: The markdown code fences in SKILL-USAGE.md are missing
languages (triggering MD040); update the fenced blocks such as the Figma URL
snippet and the "Option 2: Direct Command" shell example by adding appropriate
fence languages — mark conversational/example text blocks as `text` and
command-line snippets (e.g., the node invocation shown under "Option 2: Direct
Command") as `bash`; also apply the same changes to the other flagged ranges
(around lines 202-206 and 301-303) so all examples are annotated for
markdownlint.
- Around line 13-27: The usage doc currently shows machine-specific absolute
paths; update SKILL-USAGE.md to use repo-relative commands and examples that
match how the script writes output to process.cwd() (e.g., run the
patternfly-check script with a relative path like node
./plugins/pf-react/skills/patternfly-check.js and reference output files
relative to the repo working directory), and replace all other absolute examples
(including the alias example and any fixed output paths mentioned around lines
214-216 and 295-303) with portable repo-relative forms so users on other
machines can run the script without editing paths; refer to the script name
patternfly-check.js and the use of process.cwd() when making the edits.
---
Duplicate comments:
In `@plugins/pf-react/skills/patternfly-check-skill.md`:
- Around line 14-16: Remove workstation-specific absolute paths and
tool-specific references in plugins/pf-react/skills/patternfly-check-skill.md:
replace any hard-coded paths like `/Users/patrickcox/...` with a relative
reference using $CLAUDE_SKILL_DIR to point to scripts/checker inside the skill
directory, update output paths to reflect the caller's CWD (do not bake in
machine paths), and replace tool-specific labels such as "Claude:" with neutral
"Assistant:"; apply these changes to the occurrences around the shown ranges
(lines 14-16, 34-36, 49-54, 80-81) so the skill is portable and tool-agnostic.
In `@plugins/pf-react/skills/placeholder.txt`:
- Line 1: The placeholder.txt in plugins/pf-react/skills is invalid; replace it
by creating a new skill directory named in kebab-case with the pf- prefix (e.g.,
pf-figma-skill) under the appropriate plugin (move to plugins/pf-figma/skills/),
add a SKILL.md describing the skill (purpose, inputs, outputs, examples), remove
the empty placeholder.txt, and ensure the new directory follows the required
pattern plugins/<plugin-name>/skills/pf-<your-skill>/ so the skill scaffold
matches the repo conventions.
---
Nitpick comments:
In `@plugins/pf-react/skills/patternfly-check-skill.md`:
- Around line 24-48: Update the "Execution Steps" section of
plugins/pf-react/skills/patternfly-check-skill.md (the "Execution Steps" heading
and the numbered steps 1–3) to a concise, outcome-first SKILL.md: remove the
local runbook-style numbered shell commands and verbose parsing checklist, and
replace them with a short trigger/intent statement, the desired outcome (what
the compliance check should produce, e.g., "Produce an HTML report summarizing
PatternFly violations with Figma deep links"), key constraints or inputs (valid
Figma URL formats), and brief follow-up guidance (what to do with the report);
apply the same trimming to the content referenced at lines 56–64 so the file
focuses on outcomes, constraints, and next steps rather than implementation
details.
In `@plugins/pf-react/skills/SKILL-USAGE.md`:
- Line 1: The filename SKILL-USAGE.md violates the repo kebab-case rule; rename
the file to a kebab-case name such as skill-usage.md and update any references
to it (documentation links, README entries, or tooling that expects
SKILL-USAGE.md) so they point to the new name; ensure the commit and PR include
the renamed file only (or a git mv) to preserve history and update any mentions
of "SKILL-USAGE.md" in the repository to "skill-usage.md".
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 5eb16ad0-35a3-4af2-b57d-04963b92a91d
📒 Files selected for processing (4)
plugins/pf-react/skills/SKILL-USAGE.mdplugins/pf-react/skills/patternfly-check-skill.mdplugins/pf-react/skills/patternfly-check.jsplugins/pf-react/skills/placeholder.txt
| // Load Figma token from config | ||
| const CONFIG_PATH = path.join(__dirname, 'figma-config.env'); | ||
| let FIGMA_TOKEN = ''; | ||
|
|
||
| try { | ||
| const configContent = fs.readFileSync(CONFIG_PATH, 'utf-8'); | ||
| const tokenMatch = configContent.match(/FIGMA_TOKEN=(.+)/); | ||
| if (tokenMatch) { | ||
| FIGMA_TOKEN = tokenMatch[1].trim(); | ||
| } else { | ||
| console.error('Error: FIGMA_TOKEN not found in figma-config.env'); | ||
| process.exit(1); | ||
| } | ||
| } catch (error) { | ||
| console.error(`Error loading config file: ${error.message}`); | ||
| console.error(`Expected location: ${CONFIG_PATH}`); | ||
| process.exit(1); | ||
| } |
There was a problem hiding this comment.
Support FIGMA_TOKEN from the environment before falling back to a local file.
Right now the CLI hard-exits unless figma-config.env exists beside the script. That blocks CI/headless use and nudges users toward keeping a PAT next to the contributed skill files.
💡 Suggested change
const CONFIG_PATH = path.join(__dirname, 'figma-config.env');
-let FIGMA_TOKEN = '';
+let FIGMA_TOKEN = process.env.FIGMA_TOKEN || '';
-try {
- const configContent = fs.readFileSync(CONFIG_PATH, 'utf-8');
- const tokenMatch = configContent.match(/FIGMA_TOKEN=(.+)/);
- if (tokenMatch) {
- FIGMA_TOKEN = tokenMatch[1].trim();
- } else {
- console.error('Error: FIGMA_TOKEN not found in figma-config.env');
- process.exit(1);
- }
-} catch (error) {
- console.error(`Error loading config file: ${error.message}`);
- console.error(`Expected location: ${CONFIG_PATH}`);
- process.exit(1);
-}
+if (!FIGMA_TOKEN) {
+ try {
+ const configContent = fs.readFileSync(CONFIG_PATH, 'utf-8');
+ const tokenMatch = configContent.match(/FIGMA_TOKEN=(.+)/);
+ if (tokenMatch) {
+ FIGMA_TOKEN = tokenMatch[1].trim();
+ }
+ } catch {}
+}
+
+if (!FIGMA_TOKEN) {
+ console.error('Error: set FIGMA_TOKEN or add figma-config.env next to this script');
+ console.error(`Expected fallback location: ${CONFIG_PATH}`);
+ process.exit(1);
+}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@plugins/pf-react/skills/patternfly-check.js` around lines 16 - 33, Currently
the code always tries to read CONFIG_PATH and exits if figma-config.env is
missing; change the logic to first check process.env.FIGMA_TOKEN and assign that
to FIGMA_TOKEN if present, and only if not present attempt to read CONFIG_PATH
(the existing fs.readFileSync/tokenMatch logic). Update the error path in the
catch/else to only exit if neither process.env.FIGMA_TOKEN nor the file provided
a token, referencing CONFIG_PATH and FIGMA_TOKEN so CI/headless runs that set
FIGMA_TOKEN in the environment work without requiring the local figma-config.env
file.
| // PatternFly v6 Design Tokens | ||
| const PATTERNFLY_TOKENS = { | ||
| colors: { | ||
| primary: '#0066CC', | ||
| danger: '#C9190B', | ||
| success: '#3E8635', | ||
| warning: '#F0AB00', | ||
| info: '#2B9AF3', | ||
| textPrimary: '#151515', | ||
| textSecondary: '#6A6E73', | ||
| background: '#FFFFFF', | ||
| disabledText: '#D2D2D2', | ||
| border: '#D2D2D2', | ||
| hoverBackground: '#F0F0F0', | ||
| stripedRow: '#FAFAFA', | ||
| darkBackground: '#151515', | ||
| darkSurface: '#212427', | ||
| darkPrimary: '#2B9AF3', | ||
| darkTextPrimary: '#FFFFFF', | ||
| darkTextSecondary: '#C7C7C7', | ||
| darkBorder: '#4F5255', | ||
| tooltipBackground: '#151515', | ||
| }, | ||
| typography: { | ||
| fontFamilyHeading: 'Red Hat Display', | ||
| fontFamilyBody: 'Red Hat Text', | ||
| h1: { size: 24, lineHeight: 32, weight: 500 }, | ||
| h2: { size: 20, lineHeight: 30, weight: 500 }, | ||
| h3: { size: 18, lineHeight: 27, weight: 500 }, | ||
| h4: { size: 16, lineHeight: 24, weight: 500 }, | ||
| body: { size: 14, lineHeight: 21, weight: 400 }, | ||
| small: { size: 12, lineHeight: 18, weight: 400 }, | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Checker token references:"
rg -n --no-heading --fixed-strings -- '--pf-v6' plugins/pf-react/skills/patternfly-check.js | sed -n '1,40p'
echo
echo "Canonical PatternFly token references already in this repo:"
rg -n --no-heading --fixed-strings -- '--pf-t--' \
plugins/pf-styling/skills/pf-token-auditor/token-reference.md \
plugins/pf-figma/skills/figma-changes/examples/token-mappings.json | sed -n '1,60p'
echo
echo "Checker typography tables:"
sed -n '58,67p;1797,1805p;1836,1856p' plugins/pf-react/skills/patternfly-check.jsRepository: patternfly/ai-helpers
Length of output: 3614
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Searching for --pf-t-- token naming ==="
rg --no-heading --fixed-strings -- '--pf-t--' . 2>/dev/null | head -20 || echo "No --pf-t-- tokens found"
echo
echo "=== Looking for token reference files ==="
find . -type f -name "*token*" | grep -E "\.(json|md|js|ts)$" | head -20
echo
echo "=== Checking pf-styling plugin structure ==="
find ./plugins/pf-styling -type f -name "*.md" -o -name "*.json" 2>/dev/null | head -20
echo
echo "=== Searching for typography sizes 28 or 36 ==="
rg --no-heading --fixed-strings -- '28px\|36px' . 2>/dev/null | grep -i 'typography\|font\|size' | head -20Repository: patternfly/ai-helpers
Length of output: 2133
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== File structure under plugins/pf-react/skills ==="
find ./plugins/pf-react/skills -type f -name "*.js" -o -name "*.json" -o -name "*.md" | head -30
echo
echo "=== Searching for 28px in entire repo ==="
rg --no-heading '28' ./plugins --type js | grep -i 'typography\|font\|size' | head -15
echo
echo "=== Searching for 36px in entire repo ==="
rg --no-heading '36' ./plugins --type js | grep -i 'typography\|font\|size' | head -15Repository: patternfly/ai-helpers
Length of output: 619
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Full typography mapping in checker (lines 1790-1810) ==="
sed -n '1790,1810p' plugins/pf-react/skills/patternfly-check.js
echo
echo "=== Color/token mappings in checker (lines 1830-1860) ==="
sed -n '1830,1860p' plugins/pf-react/skills/patternfly-check.jsRepository: patternfly/ai-helpers
Length of output: 2529
Token naming in the checker does not match repository standards.
The checker hardcodes --pf-v6-* token names throughout (typography, colors, components), but the repository's canonical styling standards documented in docs/guidelines/styling-standards.md use the --pf-t--* naming scheme. The checker will recommend non-existent tokens like --pf-v6-global--FontSize--md instead of --pf-t--global--font--size--md.
The typography sizes [12, 14, 16, 18, 20, 24] in the checker are correct but use outdated token names. Update to match the --pf-t--* scheme used in docs/guidelines/styling-standards.md and examples in docs/troubleshooting/common-issues.md.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@plugins/pf-react/skills/patternfly-check.js` around lines 35 - 67, The
checker hardcodes old v6 token names (e.g. --pf-v6-*) in PATTERNFLY_TOKENS
(colors, typography, components) and will recommend non-existent tokens; update
all token name strings to the repository's canonical --pf-t--* naming scheme
(e.g. map tokens like --pf-v6-global--FontSize--md to
--pf-t--global--font--size--md) and ensure the typography size entries in
PATTERNFLY_TOKENS.typography remain the same values ([12,14,16,18,20,24]) but
use the --pf-t--global--font--size--* token names, and similarly rename
color/component tokens to their --pf-t-- equivalents so the checker emits
repository-standard token recommendations.
| <p><strong>File:</strong> ${this.fileName}</p> | ||
| <p><strong>Date:</strong> ${this.date}</p> |
There was a problem hiding this comment.
Escape all Figma-derived strings before embedding them in the report.
fileName, layer names, issues, fixes, microcopy text, and the JSON payload are interpolated directly into HTML and into an inline <script>. A malicious Figma label like </script><script>...</script> will execute when the saved report is opened locally.
Also applies to: 723-727, 783-787, 933-933, 1003-1007, 1051-1075
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@plugins/pf-react/skills/patternfly-check.js` around lines 649 - 650, The
template embeds untrusted Figma-derived values (e.g., this.fileName, layer
names, issue/fix text, microcopy and the JSON payload) directly into HTML and an
inline <script>; sanitize these before embedding by escaping HTML special
characters when inserting into markup (implement and use a helper like
escapeHtml for values such as this.fileName, layer names, issue/fix text,
microcopy) and by safely serializing data into the script (use JSON.stringify
for the payload and then escape any "</script>" sequences or use a safe wrapper
that replaces "</" with "<\\/") so no attacker-supplied string can break out of
the HTML or script context; update all affected interpolations (including the
occurrences noted around the template: the current this.fileName/this.date
insertion and the other ranges referenced) to use these escaping/serialization
helpers.
| function isPatternFlyComponent(node) { | ||
| if (!node) return false; | ||
|
|
||
| // Instance nodes with component info | ||
| if (node.type === 'INSTANCE' && node.componentId) { | ||
| // Check if component name suggests PatternFly | ||
| const name = (node.name || '').toLowerCase(); | ||
| const componentName = name; | ||
|
|
||
| // Common PatternFly component naming patterns | ||
| const pfPatterns = [ | ||
| 'pf-', 'patternfly', 'red hat', | ||
| // Component types | ||
| 'button', 'card', 'modal', 'alert', 'table', | ||
| 'navigation', 'nav', 'breadcrumb', 'pagination', | ||
| 'tabs', 'accordion', 'wizard', 'drawer', 'tooltip' | ||
| ]; | ||
|
|
||
| return pfPatterns.some(pattern => componentName.includes(pattern)); | ||
| } |
There was a problem hiding this comment.
Generic component words are enough to count a custom instance as “PatternFly”.
Any instance named Button, Card, Modal, etc. satisfies this heuristic even if it came from a private library, so the "Component Sources" section can materially over-report PF adoption. This should key off explicit PF identifiers or library metadata, not generic component nouns.
🧭 Suggested change
- const pfPatterns = [
- 'pf-', 'patternfly', 'red hat',
- // Component types
- 'button', 'card', 'modal', 'alert', 'table',
- 'navigation', 'nav', 'breadcrumb', 'pagination',
- 'tabs', 'accordion', 'wizard', 'drawer', 'tooltip'
- ];
+ const pfPatterns = ['pf-', 'patternfly', 'red hat'];🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@plugins/pf-react/skills/patternfly-check.js` around lines 1162 - 1181, The
current isPatternFlyComponent function flags any instance with generic nouns
(e.g., "button", "card") as PatternFly; change it to only detect explicit PF
identifiers by removing generic component words and instead checking for
explicit markers on the instance/component metadata: use node.componentId or
resolve the instance's main component (e.g., node.mainComponent or look up by
node.componentId) and inspect its name/pluginData/libraryKey for exact tokens
like "pf-", "patternfly", "pattern-fly", "PatternFly", or "redhat"
(case-insensitive). Update isPatternFlyComponent to return true only if those
explicit identifiers are present in the component's id/name/pluginData, and no
longer rely on generic nouns like "button", "card", "modal", etc.
| function getComponentSource(node) { | ||
| if (node.type === 'INSTANCE' && node.componentId) { | ||
| return { | ||
| isInstance: true, | ||
| isPatternFly: isPatternFlyComponent(node), | ||
| componentId: node.componentId, | ||
| isDetached: checkIfDetached(node) | ||
| }; |
There was a problem hiding this comment.
detached can never increment on the current call path.
getComponentSource() only calls checkIfDetached() when node.componentId exists, but checkIfDetached() only returns true when componentId is missing. The detached-instance metric and the "Component Library Sync" section are therefore dead today.
Also applies to: 1205-1214
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@plugins/pf-react/skills/patternfly-check.js` around lines 1187 - 1194, The
detached-instance metric is never incremented because getComponentSource only
calls checkIfDetached when node.componentId exists, but checkIfDetached returns
true only when componentId is missing; update getComponentSource to compute
isDetached by calling checkIfDetached(node) regardless of node.componentId (or
invert the condition inside checkIfDetached so it detects detached instances
even when componentId is present), and return that boolean as the isDetached
field so the detached-instance metric and "Component Library Sync" section can
register correctly; adjust the same pattern in the other occurrence around lines
1205-1214 (the duplicate getComponentSource usage).
| const html = report.generateHTML(); | ||
| const outputPath = path.join(process.cwd(), `patternfly-compliance-report-${Date.now()}.html`); | ||
| fs.writeFileSync(outputPath, html, 'utf-8'); | ||
|
|
||
| console.log(`\n✓ Report saved to: ${outputPath}`); | ||
| console.log(` Open this file in your browser to view the full report.`); |
There was a problem hiding this comment.
The report is saved, but never auto-opened.
This function writes the HTML and logs the path, but it never launches a browser. Both markdown files in this PR document an auto-open step, so either implement it here or change the docs to say opening is manual.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@plugins/pf-react/skills/patternfly-check.js` around lines 2684 - 2689, The
report HTML is written (report.generateHTML -> html,
fs.writeFileSync(outputPath, html, 'utf-8')) but never auto-opens; modify the
function to launch the default browser after writing by invoking a
cross-platform opener (e.g., use Node's child_process.exec or the 'open'
package) to open outputPath, and handle errors gracefully (log on failure).
Ensure you reference outputPath when calling the opener and keep the existing
console.log messages.
| ``` | ||
| Check this Figma design for PatternFly compliance: | ||
| https://www.figma.com/design/ABC123/My-Dashboard | ||
| ``` | ||
|
|
||
| ### Option 2: Direct Command | ||
| ``` | ||
| node /Users/patrickcox/.claude/projects/-Users-patrickcox/memory/patternfly-check.js "https://www.figma.com/design/ABC123/My-Dashboard" | ||
| ``` |
There was a problem hiding this comment.
Add fence languages to the blocks already flagged by markdownlint.
MD040 is firing here. Mark the conversational examples as text and the shell snippets as bash.
Also applies to: 202-206, 301-303
🧰 Tools
🪛 markdownlint-cli2 (0.22.0)
[warning] 8-8: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
[warning] 14-14: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@plugins/pf-react/skills/SKILL-USAGE.md` around lines 8 - 16, The markdown
code fences in SKILL-USAGE.md are missing languages (triggering MD040); update
the fenced blocks such as the Figma URL snippet and the "Option 2: Direct
Command" shell example by adding appropriate fence languages — mark
conversational/example text blocks as `text` and command-line snippets (e.g.,
the node invocation shown under "Option 2: Direct Command") as `bash`; also
apply the same changes to the other flagged ranges (around lines 202-206 and
301-303) so all examples are annotated for markdownlint.
| ### Option 2: Direct Command | ||
| ``` | ||
| node /Users/patrickcox/.claude/projects/-Users-patrickcox/memory/patternfly-check.js "https://www.figma.com/design/ABC123/My-Dashboard" | ||
| ``` | ||
|
|
||
| ### Option 3: Bash Alias (Optional) | ||
| Add to your `.zshrc` or `.bashrc`: | ||
| ```bash | ||
| alias pf-check='node /Users/patrickcox/.claude/projects/-Users-patrickcox/memory/patternfly-check.js' | ||
| ``` | ||
|
|
||
| Then use: | ||
| ```bash | ||
| pf-check "https://www.figma.com/design/ABC123/My-Dashboard" | ||
| ``` |
There was a problem hiding this comment.
Make the usage examples portable.
These /Users/patrickcox/... commands and the fixed /Users/patrickcox/patternfly-compliance-report-... output path only work on one machine. The implementation writes to process.cwd() in plugins/pf-react/skills/patternfly-check.js, so the guide should use repo-relative examples instead.
Also applies to: 214-216, 295-303
🧰 Tools
🪛 markdownlint-cli2 (0.22.0)
[warning] 14-14: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@plugins/pf-react/skills/SKILL-USAGE.md` around lines 13 - 27, The usage doc
currently shows machine-specific absolute paths; update SKILL-USAGE.md to use
repo-relative commands and examples that match how the script writes output to
process.cwd() (e.g., run the patternfly-check script with a relative path like
node ./plugins/pf-react/skills/patternfly-check.js and reference output files
relative to the repo working directory), and replace all other absolute examples
(including the alias example and any fixed output paths mentioned around lines
214-216 and 295-303) with portable repo-relative forms so users on other
machines can run the script without editing paths; refer to the script name
patternfly-check.js and the use of process.cwd() when making the edits.
PatternFly v6 Compliance Checker - Skill Summary
Overview
An automated design system compliance validation tool that analyzes Figma UI prototypes against PatternFly v6 standards. Generates detailed HTML reports with actionable findings, deep links to violations, and batch export capabilities.
Purpose
Enable UX designers to validate their Figma designs against Red Hat's PatternFly v6 design system before developer handoff, reducing design-to-dev inconsistencies and ensuring brand compliance.
Key Features
1. Comprehensive Component Validation (17 Types)
2. Advanced Analysis Features
3. Interactive HTML Report
4. Accurate PatternFly v6 Token Validation
Updated March 2026 with official PatternFly v6 specifications:
Technical Specifications
Input
https://www.figma.com/design/FILE_ID/FILE_NAMEhttps://www.figma.com/file/FILE_ID/FILE_NAMEOutput
/Users/patrickcox/patternfly-compliance-report-[timestamp].htmlPerformance
Scoring
Usage
Command Line
node /Users/patrickcox/.claude/projects/-Users-patrickcox/memory/patternfly-check.js "https://www.figma.com/design/ABC123/My-Dashboard"Via Claude Code (Natural Language)
Via Alias (Optional)
Report Structure
Executive Summary
Component Sources
Top Priority Fixes
Critical Violations (Collapsed by default)
Minor Deviations (Collapsed by default)
Typography Hierarchy (Collapsed by default)
Spacing Consistency (Collapsed by default)
Compliant Elements (Collapsed by default)
Batch Operations
Dependencies
Files
patternfly-check.js- Main implementation (2000+ lines)patternfly-check-skill.md- Skill specificationSKILL-USAGE.md- User guideNEW-FEATURES-SUMMARY.md- v2 features documentationTOKEN-CORRECTIONS-2026-03.md- Token accuracy changelogfigma-config.env- Figma API token storageMEMORY.md- Project memory and preferencesVersion History
Version 2.0 (March 2026)
Version 1.0 (Initial)
Use Cases
Design Review
Run before design reviews to catch violations early:
Developer Handoff
Export violations as JSON for development tickets:
Team Compliance Tracking
Track compliance improvements over time:
Pattern Library Audit
Check component library usage:
Success Metrics
Excellent Compliance
Good Compliance
Integration Opportunities
With Jira
With CI/CD
With Design System Updates
Limitations
Not Validated
Manual Review Needed
Support
License & Attribution
Built for Red Hat PatternFly Design Team
Uses official PatternFly v6 design tokens
Figma API integration via node-fetch
Summary by CodeRabbit
New Features
Documentation