diff --git a/.github/workflows/update-plugins-md.yml b/.github/workflows/update-plugins-md.yml index fa2c824..7dc2aac 100644 --- a/.github/workflows/update-plugins-md.yml +++ b/.github/workflows/update-plugins-md.yml @@ -1,4 +1,4 @@ -name: Update PLUGINS.md +name: Update generated files on: workflow_dispatch: @@ -19,11 +19,12 @@ jobs: - run: git remote set-url origin git@github.com:patternfly/ai-helpers.git - run: | bash scripts/generate-plugins-md.sh - git diff --quiet PLUGINS.md README.md || { + bash scripts/generate-skills-json.sh + git diff --quiet PLUGINS.md README.md dist/skills.json || { git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" - git add PLUGINS.md README.md - git commit -m "docs: auto-update PLUGINS.md and README plugin table" + git add PLUGINS.md README.md dist/skills.json + git commit -m "docs: auto-update PLUGINS.md, README plugin table, and skills index" git pull --rebase git push } diff --git a/dist/skills.json b/dist/skills.json new file mode 100644 index 0000000..42de44f --- /dev/null +++ b/dist/skills.json @@ -0,0 +1,178 @@ +{ + "version": "1", + "generated": "2026-05-06T15:53:09.000Z", + "meta": { + "source": "patternfly/ai-helpers", + "totalSkills": 28 + }, + "skills": [ + { + "name": "css-var-analyzer", + "plugin": "design-foundations", + "description": "Analyze CSS custom property usage, redefinitions, and naming patterns in PatternFly SCSS components. Use when auditing --pf- variables, debugging missing definitions, tracing SCSS variable cascades, or finding unused CSS custom properties.", + "content": "---\nname: css-var-analyzer\ndescription: Analyze CSS custom property usage, redefinitions, and naming patterns in PatternFly SCSS components. Use when auditing --pf- variables, debugging missing definitions, tracing SCSS variable cascades, or finding unused CSS custom properties.\n---\n\n# CSS Variable Analyzer\n\nAnalyze CSS variable usage, redefinitions, and naming patterns in PatternFly SCSS components.\n\n## What It Analyzes\n\n- **Variable redefinitions** - How variables cascade through modifiers, states, and nested selectors\n- **Undefined variables** - Variables used but never defined within the component\n- **Unused variables** - Variables defined but never referenced\n- **Naming conventions** - Validates SCSS interpolation (`--#{$component}--property`) vs hardcoded names\n- **Redefinition chains** - Complete cascade documentation for any variable\n\n## Requirements\n\n**Node.js** is required to run the analysis scripts.\n\n```bash\ncommand -v node >/dev/null 2>&1 || { echo \"Error: This skill requires Node.js.\" >&2; exit 1; }\n```\n\nThe skill expects a PatternFly project structure with components in `src/patternfly/components/`.\n\n## Usage\n\n### Basic analysis\n```text\nAnalyze CSS variables for the tabs component\n```\n\n### Variable drill-down\n```text\nShow me the redefinition chain for the inset variable in tabs\n```\n\n### Modifier analysis\n```text\nShow me variables for the vertical modifier in tabs\n```\n\n## How It Works\n\nThe skill uses two Node.js scripts in `$CLAUDE_SKILL_DIR`:\n\n1. **css-var-analyzer.js** - Parses SCSS files, extracts variable definitions/usages, builds redefinition chains, detects issues\n2. **format-css-report.js** - Formats the analysis JSON into readable Markdown reports\n\nThe analyzer categorizes definitions by context: root (`@include pf-root`), modifier (`.pf-m-*`), state (`:hover`, `:focus`), media query, breakpoint, and nested selectors.\n\n## Output\n\nA Markdown report with:\n- Summary statistics (total vars, redefined count/%, undefined, unused, naming violations)\n- Issues section (undefined variables, unused variables, naming violations)\n- Redefinition summary (top 15 most-redefined variables)\n- For drill-downs: complete definition chain with file locations, contexts, and code snippets" + }, + { + "name": "icon-finder", + "plugin": "design-foundations", + "description": "Find icons from the Red Hat Design System (@rhds/icons) by use case. Searches the Red Hat Icons demo site by keyword, returns matching icon names with a visual HTML preview for comparison. Use when the user asks to find an icon, search for an icon by purpose, pick an icon for a UI, or get icon options for a use case.", + "content": "---\nname: icon-finder\ndescription: Find icons from the Red Hat Design System (@rhds/icons) by use case. Searches the Red Hat Icons demo site by keyword, returns matching icon names with a visual HTML preview for comparison. Use when the user asks to find an icon, search for an icon by purpose, pick an icon for a UI, or get icon options for a use case.\n---\n\n# Icon Finder (Red Hat Icons)\n\nFind UI icons from [@rhds/icons](https://github.com/RedHat-UX/red-hat-icons) based on a described use case.\n\n## Workflow\n\n1. **Interpret use case** – Derive 1–3 search terms from the user's message (e.g. \"merge\" → merge, combine, branch; \"export\" → export, download, share).\n2. **Get icon list** – Fetch the demo site: `https://red-hat-icons.netlify.app/`. Extract **only** icon names from lines containing `set=\"ui\"` — look for the pattern `set=\"ui\" icon=\"\"`. Ignore icons from any other set.\n3. **Match** – Filter the `ui` icon names by your search terms. Prefer exact or prefix match. When an icon has a `-fill` counterpart, treat them as **one result** (they share a card in the preview). Return **5–8** unique icon concepts.\n4. **Generate preview** – Build an HTML file using the template below. Each icon is loaded via an `` tag pointing to the raw GitHub URL — no API calls or base64 decoding needed. Write to `icon-finder-preview.html` in the user's workspace or home directory.\n5. **Open preview** – Open the HTML file in the user's default browser (see \"Opening the preview\" section).\n6. **Respond** – Show the match table. Then ask: *\"Do any of these work, or would you like me to do a deeper search? I can cast a wider net using related concepts and synonyms you might not have thought of.\"*\n7. **Deep search (only if the user asks for it)** – See \"Deep search fallback\" section below.\n\n## Icon set\n\nThis skill uses **only** the `ui` set (interface actions, status, navigation — ~542 icons). Do not search or return icons from any other set (`standard`, `microns`, `social`).\n\n## Response format\n\n```markdown\n### Matches for \"[use case]\"\n\n| Icon | Fill | Use when |\n|------|------|----------|\n| `hybrid-cloud` | yes | Multi-provider dashboards, infrastructure overview pages. |\n| `multi-cloud` | no | Provider comparison views, cloud strategy settings. |\n...\n\n**Usage:**\n\\`\\`\\`html\n\n\\`\\`\\`\n\nInstall: `npm install @rhds/icons`\n\nDo any of these work, or would you like me to do a deeper search? I can cast a wider net using related concepts and synonyms you might not have thought of.\n```\n\n## Raw SVG URL pattern\n\nEach icon's SVG is available at:\n\n```\nhttps://raw.githubusercontent.com/RedHat-UX/red-hat-icons/main/src/ui/.svg\n```\n\nFor example: `https://raw.githubusercontent.com/RedHat-UX/red-hat-icons/main/src/ui/cluster.svg`\n\n## HTML preview template\n\nUse this exact template. It loads PatternFly 6 CSS from a CDN — no build step required. Replace `` with one card per match. Icons are loaded as `` tags — the user's browser fetches them directly from GitHub.\n\n```html\n\n\n\n \n \n Icon Finder – Results\n \n \n\n\n
\n
\n

Icon Finder Results

\n

From @rhds/icons (set: UI)

\n

Prompt:

\n

Search terms:

\n
\n \n \n
\n\n\n```\n\nEach card replaces ``. All cards use the same structure — a `
` card with one or two icon variants inside. Each variant is an independently clickable ``.\n\n**Card with fill variant** (two variants side-by-side):\n\n```html\n
\n
\n \n
icon-name
\n
UI context: where in a software UI this icon fits
\n
\n
\n```\n\n**Card without fill variant** (single variant):\n\n```html\n
\n
\n \n
icon-name
\n
UI context: where in a software UI this icon fits
\n
\n
\n```\n\nReplace `` with the user's original message and `` with a comma-separated list of the search terms derived in step 1 of the workflow.\n\n## Opening the preview\n\nAfter writing `icon-finder-preview.html`, open it in the user's default browser. The page loads PatternFly CSS from a CDN and icon SVGs from GitHub, so it works fine as a local file — no server needed.\n\n## Deep search fallback\n\nThe initial search matches on direct keywords only. If the user isn't satisfied, the deep search expands to synonyms, related concepts, and adjacent terminology they may not have thought of.\n\n### How it works\n\n1. **Expand the search terms** — Starting from the user's original use case, brainstorm 10–20 related terms across these categories:\n - **Synonyms:** direct alternatives (e.g. \"merge\" → combine, join, unite, fuse)\n - **Related concepts:** things in the same domain (e.g. \"cloud cluster\" → topology, network, hub, infrastructure, region)\n - **Abstract/metaphorical:** shapes or ideas that could represent the concept (e.g. \"cluster\" → nodes, grid, constellation, beehive, atom)\n - **Technical terms:** domain-specific jargon (e.g. \"cloud environments\" → tenant, orchestration, federation, interoperability)\n2. **Re-scan the full icon list** — Using the already-fetched demo site content (step 2 of the main workflow), match all `ui` set icon names against the expanded term list.\n3. **Deduplicate** — Remove any icons already shown in the initial results.\n4. **Generate expanded preview** — Build a new `icon-finder-preview.html` with two sections:\n - \"Original matches\" — the initial results (kept for reference)\n - \"Additional finds\" — the new icons from the expanded search\n Use the same HTML template but add a section label before each gallery using PatternFly content styling:\n ```html\n

Section title

\n ```\n5. **Open and respond** — Follow steps 5–6 of the main workflow. Present the new icons in a separate table below the originals.\n\n### Example expansion\n\nFor \"cluster of different cloud environments\":\n\n| Category | Initial terms | Expanded terms |\n|----------|--------------|----------------|\n| Synonyms | cluster, cloud | group, collection, aggregate, pool |\n| Related concepts | hybrid-cloud, multi-cloud, edge | topology, network, hub, infrastructure, region, zone, federation |\n| Abstract | — | nodes, constellation, atom, venn-diagram, interconnect |\n| Technical | — | tenant, orchestration, interoperability, data-connections, distribute |\n\n### Guidelines\n\n- Aim for **8–15 additional icons** in the expanded results — enough to be useful, not so many as to overwhelm.\n- Don't repeat icons from the initial results. Each icon and its `-fill` variant count as a single result (shown side-by-side on one card).\n- The deep search reuses the demo site content already fetched in step 2 — no additional network requests needed beyond what the main workflow already did.\n- Works identically in Cursor and Claude Code — no browser or special tools required.\n\n## Notes\n\n- Icon names are the only metadata; there are no descriptions in the source. The agent infers meaning from the name. Card hints use the format `UI context: description` and should describe **where in a software UI the icon would be used** — not just reword the name. Think about specific pages, features, buttons, or dashboard elements where the icon fits. For example, prefer `UI context: power status indicators, energy consumption dashboards` over `UI context: zappy energy` for `electricity`. The same software-UI framing applies to the \"Use when\" column in the markdown response table.\n- Many icons have outline and `-fill` variants. Show both side-by-side on a single card rather than using two separate cards.\n- Do not clone the repo. Use the demo site for listing icons and raw GitHub URLs for rendering.\n- Do NOT fetch individual SVG content from the GitHub API. The `` tags in the HTML let the user's browser load them directly — this is much faster." + }, + { + "name": "pf-ai-experience-patterns", + "plugin": "design-foundations", + "description": "Apply Red Hat's AI design language for AI-powered demos and features. Use when user mentions AI experience, chatbots, virtual assistants, AI generation, or product prototypes. Proactively applies even without explicit request.", + "content": "---\nname: pf-ai-experience-patterns\ndescription: Apply Red Hat's AI design language for AI-powered demos and features. Use when user mentions AI experience, chatbots, virtual assistants, AI generation, or product prototypes. Proactively applies even without explicit request.\n---\n\n# Red Hat AI Experience Design Patterns\n\nThis skill applies Red Hat's official design language for AI-enabled features (last updated February 2026). When building AI features, proactively apply these patterns to create transparent, polished, brand-compliant experiences.\n\n**Authoritative source:** [https://staging.patternfly.org/ai/design-language](https://staging.patternfly.org/ai/design-language)\n\n**Supporting files in this skill:**\n\n- `guidelines/design-rules.md` — Detailed iconography, chatbot, color, and animation rules\n- `guidelines/reference-mapping.md` — Reference image lookup tables for review findings\n- `references/` — 21 extracted visual examples from key pages\n- `references/REFERENCE-INDEX.md` — Descriptions of each reference image\n\n## Core Principles\n\nEvery AI experience must follow these three principles:\n\n1. **Be transparent** — Users want to know when they are interacting with AI. Make it clear using labels and visual cues.\n2. **Make it personable, but not human** — AI should be polite and follow Red Hat voice and tone, but shouldn't act as though the user is interacting with a human.\n3. **Stay within the Red Hat brand and design language** — Follow PatternFly and design system standards so AI experiences look and feel like Red Hat.\n\n## Transparency Requirements\n\n**Critical**: It should ALWAYS be clear when and how AI is being used.\n\n- **Don't rely on just one indicator.** Use at minimum one visual AND one verbal indicator.\n - Visual: Icons with AI sparkles, animations\n - Verbal: \"with AI\", \"AI-assisted\", \"AI-generated\" in labels or button text\n- **High-risk interactions**: Consider additional indicators (consult with AIA Reviewers)\n\n**For AI-assisted features** (search, generation, editing): Place a transparency notice at the beginning of the experience. Minimum text: *\"This feature uses AI technology. Do not include any personal information or other sensitive information in your input.\"* Include persistent notice: *\"Always review AI-generated content prior to use.\"* Reference the Red Hat Privacy Statement.\n\n**For virtual assistants/chatbots**: Show notice before user interacts and before any content is generated. Include an info icon (ℹ️) with persistent \"Always review AI-generated content prior to use.\" Use AI icon + \"AI\" tag as visual and verbal indicators.\n\n**For AI-generated content**: Must include a label AND icon indicating content was created using AI (e.g., Sparkle icon + \"AI-assisted results\" heading).\n\n## Iconography Summary\n\nRed Hat uses **9 official `rh-ui-icon-ai-*` icons** based on sparkles. Always pair icons with text (\"...with AI\", \"...by AI\"). Never create custom AI icons — request via #help-brand. See `guidelines/design-rules.md` for the full icon list and rules.\n\n## Chatbot Summary\n\nAll chatbots must use **Red Hat's robot icon** as their avatar. Use PatternFly non-status color tokens for avatar colors. No gradients on launch buttons or chat message boxes. See `guidelines/design-rules.md` for full chatbot and chat message rules.\n\n## Color & Animation Summary\n\nDon't use color coding or gradients to indicate AI. AI features use the same colors as other interface elements. Use premade sparkle animations only — triggered on hover/click, loop once. See `guidelines/design-rules.md` for full color table and animation rules.\n\n## Review Workflow\n\nWhen analyzing a design against Red Hat AI patterns:\n\n### Step 1: Identify what's being used\n\n- What AI capabilities are shown? (generation, search, troubleshooting, chatbot, etc.)\n- Are transparency notices present?\n- Which icons are being used?\n- Is this a chatbot (should use robot avatar) or another AI feature?\n- Are there visual + verbal indicator pairs?\n\n### Step 1a: Run a gradient sweep (required)\n\nBefore deciding compliance, inspect the full UI for gradients on AI-related surfaces:\n\n- AI labels and badges (e.g., \"AI Generated\", \"AI-assisted\", \"By AI\")\n- Chat launchers/buttons and any chatbot trigger controls\n- Chat composer/message box borders, fills, and focus rings\n- AI cards, panels, and highlighted callouts\n- Any shimmer/glow treatment implying AI \"thinking\" or progress\n\nIf any of the above uses gradient color, mark as ❌ failed.\n\n### Step 2: Categorize each requirement\n\n- ✅ **Compliant** — Meets the guideline\n- ❌ **Missing/Failed** — Does not meet the guideline\n\n### Step 3: Select reference images for failed items\n\nRead `guidelines/reference-mapping.md` to find the correct reference image for each failed check.\n\n### Step 4: Summarize findings\n\nPresent a results table, then show the reference image for each ❌ item with a brief explanation of what needs to change.\n\n**Results table format:**\n\n| Category | Status |\n| ------------ | ---------------- |\n| [Check item] | ✅ Compliant |\n| [Check item] | ❌ Missing/Failed |\n\n**For each ❌ item**, show the reference image and explain what needs to change. Always show reference images for failed items so users can visually compare the correct pattern against their current implementation.\n\n---\n\n## Quick Reference Checklist\n\n**Transparency:**\n\n- At least one visual indicator (icon with sparkle)\n- At least one verbal indicator (\"with AI\", \"AI-assisted\", etc.)\n- Appropriate transparency notice for feature type\n- \"Always review AI-generated content prior to use\" notice where applicable\n\n**Iconography:**\n\n- Using official `rh-ui-icon-ai-*` icons (not creating custom ones)\n- Icons paired with text labels\n- For chatbots: robot icon as avatar\n\n**Color & Styling:**\n\n- Using standard PatternFly/Red Hat colors\n- No gradients on AI labels/badges, chat buttons/launchers, or chat message/composer boxes\n- No gradients to indicate thinking/progress\n- No special \"AI colors\"; follows existing color status associations\n\n**Brand Compliance:**\n\n- Follows PatternFly component patterns\n- Personable but not human in tone\n- Looks and feels like Red Hat\n\n---\n\n## Additional Resources\n\n- **PatternFly AI Design Language** (authoritative source): [https://staging.patternfly.org/ai/design-language](https://staging.patternfly.org/ai/design-language)\n- PatternFly ChatBot Extension: [https://staging.patternfly.org/extensions/chatbot/overview/design-guidelines](https://staging.patternfly.org/extensions/chatbot/overview/design-guidelines)\n- PatternFly Colors: [https://staging.patternfly.org/foundations-and-styles/color](https://staging.patternfly.org/foundations-and-styles/color)\n- Red Hat Design System: [https://ux.redhat.com/](https://ux.redhat.com/)\n- Red Hat Brand Standards: [http://brand.redhat.com/](http://brand.redhat.com/)\n- `@patternfly/react-icons` package: [https://www.npmjs.com/package/@patternfly/react-icons](https://www.npmjs.com/package/@patternfly/react-icons)\n- Request new icons or animations: #help-brand on Slack\n\n> Guidelines updated February 2026. This skill does not replace AI Assessment, Privacy Impact Assessment, or other required reviews.\n\n---\n\n*Remember: The goal is transparency. Users want to know when they're interacting with AI. Over-communicate rather than under-communicate.*" + }, + { + "name": "pf-analyze-modifiers", + "plugin": "design-foundations", + "description": "Find, list, and summarize PatternFly component modifiers (pf-m- classes) across the codebase. Use when analyzing component styling patterns, documenting modifier usage, or auditing CSS consistency.", + "content": "---\nname: pf-analyze-modifiers\ndescription: Find, list, and summarize PatternFly component modifiers (pf-m- classes) across the codebase. Use when analyzing component styling patterns, documenting modifier usage, or auditing CSS consistency.\n---\n\n# Analyze Modifiers\n\nDiscover, analyze, and document PatternFly modifier classes (`pf-m-*`) across component SCSS files. Search the codebase for modifier patterns, calculate usage statistics, and produce organized Markdown reports.\n\n## Input\n\nThe user will specify a scope: all components (default), a specific component, a specific modifier, or a directory. If no scope is given, analyze all components.\n\n## Output\n\nWrite a Markdown file with:\n\n### Summary\n- Total unique modifiers found\n- Total components analyzed\n- Top 5 most frequently used modifiers (with count)\n- Top 5 components with the most modifiers (with count)\n\n### Modifier Listings\n\n**Default: By Modifier (Alphabetical)**\n```markdown\n## pf-m-{modifier-name}\n- Component1\n- Component2\n```\n\n**Alternative: By Component**\n```markdown\n## Component Name\n- pf-m-modifier1\n- pf-m-modifier2\n```\n\n### File naming\n- `modifiers-listing.md` for complete listings\n- `{component-name}-modifiers.md` for component-specific analysis\n- `{modifier-name}-usage.md` for modifier-specific analysis\n\n## Usage Examples\n\n### Analyze all modifiers\n```text\nUser: /design-foundations:pf-analyze-modifiers\n```\n\n### Analyze specific component\n```text\nUser: /design-foundations:pf-analyze-modifiers for the Button component\n```\n\n### Find modifier usage\n```text\nUser: /design-foundations:pf-analyze-modifiers find where pf-m-disabled is used\n```\n\n### Compare modifiers\n```text\nUser: /design-foundations:pf-analyze-modifiers compare pf-m-expanded and pf-m-collapsed\n```\n\n## Modifier Categories Reference\n\n### State\npf-m-disabled, pf-m-active, pf-m-current, pf-m-selected, pf-m-hover, pf-m-focus\n\n### Size\npf-m-sm, pf-m-md, pf-m-lg, pf-m-xl, pf-m-2xl, pf-m-compact\n\n### Layout\npf-m-vertical, pf-m-horizontal, pf-m-inline, pf-m-block, pf-m-grid\n\n### Visual\npf-m-plain, pf-m-bordered, pf-m-raised, pf-m-filled, pf-m-outline\n\n### Color\npf-m-red, pf-m-blue, pf-m-green, pf-m-orange, pf-m-purple, pf-m-teal, pf-m-yellow\n\n### Responsive\npf-m-{base}-on-sm, pf-m-{base}-on-md, pf-m-{base}-on-lg, pf-m-{base}-on-xl, pf-m-{base}-on-2xl\n\n### Semantic/Status\npf-m-success, pf-m-warning, pf-m-danger, pf-m-info, pf-m-custom\n\n## Notes\n\n- Some components have multiple SCSS files (e.g., Table: table.scss, table-grid.scss, table-tree-view.scss) - consolidate under a single component name.\n- Some modifiers use dynamic values (`pf-m-align-items-*`, `pf-m-width-*`, `pf-m-inset-*`) - list with asterisk notation.\n- Include responsive variants, pseudo-state contexts, and element-specific modifiers (e.g., `pf-v6-c-component__item.pf-m-current`)." + }, + { + "name": "pf-class-migration-scanner", + "plugin": "design-foundations", + "description": "Scans for legacy PatternFly class usage and recommends PF6-safe replacements. Use when modernizing older PatternFly codebases.", + "content": "---\nname: pf-class-migration-scanner\ndescription: Scans for legacy PatternFly class usage and recommends PF6-safe replacements. Use when modernizing older PatternFly codebases.\n---\n\n# PF Class Migration Scanner\n\nLocate legacy PatternFly class names and migration risks.\n\nWhen migration recommendations are ambiguous, query the PatternFly MCP server first to verify the latest supported component patterns and tokens.\n\n## Migration scope\n\n- Legacy versioned classes (`pf-v5-*`, `pf-v4-*`)\n- Unversioned legacy classes (`pf-c-*`, `pf-u-*`, `pf-l-*`)\n- Legacy token patterns (`--pf-v6-*`, `--pf-global-*`) that should use semantic tokens (`--pf-t--*`)\n\n## Scan commands\n\n```bash\nrg \"pf-v5-|pf-v4-|pf-c-|pf-u-|pf-l-\" src\nrg \"--pf-v6-|--pf-global-\" src\n```\n\n## Replacement guidance\n\n- Prefer PatternFly React component props and composition first.\n- If a utility class is still needed, use `pf-v6-u-*` variants.\n- Prefer semantic tokens (`--pf-t--*`) over hardcoded values and legacy token names.\n\n## Output format\n\nFor each finding include:\n\n- file path\n- current class/token\n- recommended PF6 replacement\n- confidence (`high`, `medium`, `low`)" + }, + { + "name": "pf-raw-colors-scan", + "plugin": "design-foundations", + "description": "\"Analyze the provided code to find any raw color values assigned to styling properties. Flag these values as technical debt and suggest their replacement with design tokens.\"", + "content": "---\nname: pf-raw-colors-scan\ndescription: \"Analyze the provided code to find any raw color values assigned to styling properties. Flag these values as technical debt and suggest their replacement with design tokens.\"\n---\n\n### Role\nYou are a Senior Design Systems Engineer specializing in CSS refactoring and Design Token implementation.\n\n### Objective\nAnalyze the provided code to find any raw color values (HEX, RGB, RGBA, HSL, HSLA) assigned to styling properties. Flag these values as technical debt and suggest their replacement with design tokens.\n\n### Scanning Logic\n1. **Regex Pattern Match:** Identify values matching:\n * HEX: `/#([A-Fa-f0-9]{3}){1,2}\\b/`\n * RGB/A: `/rgba?\\((\\d+,\\s*){2,3}\\d+(,\\s*0?\\.\\d+)?\\)/`\n * HSL/A: `/hsla?\\(\\d+,\\s*([\\d.]+%,\\s*){1,2}[\\d.]+(%|,\\s*0?\\.\\d+)?\\)/`\n2. **Named Colors (The \"X11 List\"):**\n * Identify all 148 CSS standard named color (e.g., from 'aliceblue' through 'yellowgreen').\n * **Focus:** Flag common values like 'white', 'black', 'red', 'blue' and 'transparent' (if 'transparent' should be a token like '--color-none'). \n3. **Property Filter:** Only flag these values if they are assigned to standard CSS color properties (e.g., `background-color`, `border`, `box-shadow`).\n4. **Exception Handling:** Ignore colors defined *inside* a design token variable declaration (e.g., ignore the value in `$blue-500: #007bff;`).\n\n### Output Format\nFor every violation found, provide:\n- **File Name:** [Name]\n- **File Path:** [Path]\n- **Line Number:** [Number]\n- **Property:** [The CSS Property]\n- **Raw Value:** [The detected color]\n- **Recommendation:** \"Replace with a semantic or primitive design token (e.g., --color-brand-primary).\"" + }, + { + "name": "pf-token-auditor", + "plugin": "design-foundations", + "description": "Validate and bridge Figma design styles to PatternFly 6 design tokens. Use when auditing Figma designs against PatternFly tokens, validating token naming, translating Figma styles to composite tokens, or when the user mentions \"token validation\", \"token audit\", \"design tokens\", \"Figma audit\", \"Figma variables\", \"token bridge\", or \"PF tokens\".", + "content": "---\nname: pf-token-auditor\ndescription: Validate and bridge Figma design styles to PatternFly 6 design tokens. Use when auditing Figma designs against PatternFly tokens, validating token naming, translating Figma styles to composite tokens, or when the user mentions \"token validation\", \"token audit\", \"design tokens\", \"Figma audit\", \"Figma variables\", \"token bridge\", or \"PF tokens\".\ndisable-model-invocation: true\n---\n\n# PatternFly Design Token Auditor & Bridge\n\nAudit designs (from Figma or raw CSS) against the PatternFly token architecture. Bridge Figma style outputs to PatternFly 6 composite and semantic tokens.\n\nFor token categories, unit mappings, theme files, and pairing tables, see [token-reference.md](token-reference.md).\n\nThis skill specifies **what** a good audit delivers; it does not prescribe **how** to fetch Figma data, call APIs, or order tool use—use whatever your environment already exposes for Figma, docs, and code search.\n\n## What a successful audit delivers\n\n1. **Correct theme lens** — Judgments match the right PatternFly theme (default vs Red Hat, etc.); see Theme File Map in [token-reference.md](token-reference.md#theme-file-map).\n2. **Defensible findings** — Each issue or pass ties to token semantics, cites descriptions where it matters, and names both Figma-side and CSS-side tokens when relevant.\n3. **Navigable context** — For Figma-sourced work, the reader can **open the exact layer(s)** from the report (deep links; multi-node findings link every node).\n4. **Honest gaps** — Unknowns and missing tokens are labeled as such, with escalation paths when there is no definition to apply.\n5. **Optional Figma edits** — If the user opts in, the file afterward reflects **only** what they agreed to apply ([Applying changes in Figma](#applying-changes-in-figma-figma-use)).\n\n## Inputs you must satisfy (outcomes)\n\n**Theme:** Infer default vs Red Hat from brand accent when present: `#ee0000` → Red Hat; `#0066cc` → default upstream.\n\n**Figma audits:** You can name layers, variables, and **stable node ids** for anything you cite; you can build correct file URLs (including branch files). Retain `fileKey` / branch key from the user’s link for deep links.\n\n**CSS-only audits:** Interpret the values given; confirm theme/mode if ambiguous.\n\n## Descriptions, classification, and naming\n\n**Evidence:** Findings that recommend or reject a token should quote or paraphrase **official usage** from [PatternFly tokens](https://www.patternfly.org/tokens/all-patternfly-tokens) or project docs when that strengthens the verdict.\n\n**Hierarchy:** Classify each property:\n\n| Layer | Prefix Pattern | Verdict |\n|-------|---------------|---------|\n| Palette | `--pf-t--color--{hue}--{shade}` | REJECT |\n| Base | `--pf-t--global--color--{concept}--{number}` | WARN |\n| Semantic | `--pf-t--global--{concept}--color--{context}--{state}` | PASS |\n| Component | `--pf-v6-c-{component}--{Property}` | PASS |\n| Raw hex/rgb | `#abc123`, `rgb(...)` | REJECT |\n\n**Naming shape:** Tokens are concept-based, never element-based (`font--size--heading--h1`, not `h1--font--size`). Full shape: `--pf-t--global--{concept}--{property}--{modifier}--{state}`.\n\n## Judgment criteria (Rules 0–9)\n\n#### Rule 0 — Prefer Purpose-Specific Semantic Tokens\nAlways cross-reference purpose-specific semantic tokens (see [token-reference.md](token-reference.md#purpose-specific-spacer-tokens)) before falling back to generic scale tokens. Purpose-specific tokens encode design intent and can be overridden independently.\n\n- WRONG: `--pf-t--global--spacer--md` (generic)\n- RIGHT: `--pf-t--global--spacer--gap--action-to-action--default` (purpose-specific)\n\n#### Rule 1 — No Palette Tokens\nPalette tokens are raw values. Always map to semantic equivalents.\n\n#### Rule 2 — On-{Context} Foreground Matching\nForeground elements (text, icons) on a colored background must use `on-` tokens that exactly match the background context. Using `on-brand--default` on a `brand--accent` background is wrong — it may pass in one theme but fail in others. See the full pairing table in [token-reference.md](token-reference.md#on-context-foreground-pairing).\n\n#### Rule 3 — Figma-to-CSS Unit Mapping\nFigma outputs `px`; PatternFly CSS uses `rem` (font/icon/spacer/breakpoint) and unitless multipliers (line-height). Convert with `1rem = 16px`. Do NOT flag unit differences as value mismatches. Only two line-height tokens exist (`--body` = 1.5, `--heading` = 1.3). See mapping tables in [token-reference.md](token-reference.md#figma-to-css-unit-mapping).\n\n#### Rule 4 — Composite Token Bridge\nWhen Figma outputs individual shadow or glass properties, recommend the single composite token (`--box-shadow--sm/md/lg`, `--background--color--glass--primary--default`). See composites in [token-reference.md](token-reference.md#box-shadow-composites-in-tokens-localscss).\n\n#### Rule 5 — Theme & collection awareness\n**Outcome:** Judgments use the theme the design is actually using (collections, modes, brand accents)—not the wrong theme file. See Theme File Map in [token-reference.md](token-reference.md#theme-file-map).\n\n#### Rule 6 — Contextual Token Pairing\nSibling properties (background, border, text, icon) on the same element should share the same context. If a context-specific token does not yet exist in CSS, flag as ESCALATION RECOMMENDED. See pairing table in [token-reference.md](token-reference.md#contextual-token-pairing).\n\n#### Rule 7 — Figma-to-Code Drift Detection\nWhen a Figma variable value differs from its CSS token value, do NOT treat as an error. Figma is the upstream source of truth. Flag as **SYNC REQUIRED** and report both values.\n\n#### Rule 8 — Unbound Figma Properties\nHardcoded values not backed by a Figma variable need fixing in the Figma file. Only suggest semantic tokens as replacements — never base/numbered tokens. If no semantic token exists, state that explicitly and provide the closest matches.\n\n#### Rule 9 — Component Implementation Cross-Check\nWhen the design represents a known PatternFly component, compare the Figma token usage against the component's SCSS implementation. Flag differences as **IMPLEMENTATION DRIFT** — distinguish between likely errors and intentional design proposals. Include the component file path and selector for reference.\n\n## Before escalating\n\n**Outcome:** “No matching token” only after you have checked PatternFly token sources (e.g. `src/patternfly/base/tokens/` and component SCSS when available, plus docs)—so the gap is real, not a search miss.\n\n## Report the user receives\n\n**Outcome:** Someone reading the audit can **understand each verdict**, **trust the evidence**, **open the right Figma layers** (when applicable), and **act** on fixes without re-deriving context.\n\n**Each finding should make clear:**\n\n- **Status** — One of: VALIDATED, COMPOSITE FOUND, CONTEXT MISMATCH, IMPLEMENTATION DRIFT, SYNC REQUIRED, FIGMA FIX NEEDED, ESCALATION RECOMMENDED.\n- **Where** — Layer name, node id(s), and an **Open in Figma** deep link to the **innermost** relevant node when the source is Figma ([link format](#figma-deep-links)).\n- **What & why** — Property, current vs recommended mapping, short reason, and quoted or cited token **descriptions** when they carry the argument.\n- **Visual grounding (issues)** — For non-passing Figma findings, include something that shows the problem (e.g. a crop or screenshot of that node)—enough that the issue is recognizable without opening the file.\n- **Both names** — Figma variable path (or raw value) and CSS token where both exist.\n\n### Finding table (expected shape)\n\n| Detail | Value |\n|--------|-------|\n| Layer | `{node name}` (`{node-id}`) — [Open in Figma](https://www.figma.com/design/{fileKey}/{fileSlug}?node-id={idWithHyphens}) |\n| Property | `{css property}` |\n| Current | `{Figma variable}` → `{CSS token}` |\n| — description | *\"{official usage description}\"* |\n| Recommended | `{correct token}` (if applicable) |\n| — description | *\"{description of recommended token}\"* |\n| Reason | `{brief explanation}` |\n\nFor **FIGMA FIX NEEDED**, the reader should also see what to bind, from what, and how to do it in plain language (Figma-variable slash path, not Plugin API).\n\n### Multi-node (“Affected nodes”) findings\n\n**Outcome:** If several layers share one finding, **every** listed node is one click from the report—no bare `1259:780` lists. Example: [`1259:780`](https://www.figma.com/design/{fileKey}/{fileSlug}?node-id=1259-780) (Primary Default text), [`1259:782`](https://www.figma.com/design/{fileKey}/{fileSlug}?node-id=1259-782) (Primary Hover text)—or one **Open in Figma** link per bullet line.\n\n### Figma deep links\n\n**Outcome:** Links open the **correct file and node** (including branch files).\n\nUse `https://www.figma.com/design/{fileKey}/{fileSlug}?node-id={idWithHyphens}` where **`node-id` uses hyphens** (`41:7106` → `node-id=41-7106`). For `/design/.../branch/{branchKey}/...`, **`branchKey` is the `fileKey`**. Reuse the file slug from the user’s URL when you have it. Example: `[Open in Figma](https://www.figma.com/design/hIHHno4fZBKmTifVjuNqiz/Login-Screen---PatternFly?node-id=41-7106)` for node `41:7106`. If no stable node exists, omit the link and say why.\n\n### Validated tokens summary\n\n**Outcome:** Passes are listed in a compact table (property, Figma variable, CSS token, PASS). Add **Open in Figma** per row when a pass maps to a single identifiable node; skip the column when the pass is file-wide or aggregated.\n\n## Optional: apply fixes in Figma\n\n**Scope:** Only statuses with a direct Figma edit path—see mapping:\n\n| Actionable Status | Intended result in the file |\n|-------------------|------------------------------|\n| FIGMA FIX NEEDED | Hardcoded value → recommended variable binding |\n| CONTEXT MISMATCH | Property rebound to the correct semantic context |\n| COMPOSITE FOUND | Primitives replaced by the composite token / variable |\n| SYNC REQUIRED | Variable value aligned with the agreed source of truth |\n\nVALIDATED, IMPLEMENTATION DRIFT, and ESCALATION RECOMMENDED are **out of scope** for file writes unless the user explicitly asks otherwise.\n\n### User choice (outcomes)\n\n**Outcome:** The user always has an **unambiguous** way to say: apply everything, walk item-by-item, skip, per-item apply / skip / apply-rest, or propose a **custom** fix for one item—without inferring intent from vague chat.\n\n**Contract — stable ids** (map host pickers or numbered replies to behavior):\n\n| Id (batch) | Meaning |\n|------------|---------|\n| `update_all` | Apply every actionable finding |\n| `update_individually` | Confirm each finding before it runs |\n| `skip` | Change nothing in Figma |\n\n| Id (per item) | Meaning |\n|----------------|---------|\n| `apply` | Apply the skill’s recommendation for this item |\n| `provide_own` | User supplies an alternative; you confirm, then apply only that |\n| `skip` | Leave this item unchanged |\n| `apply_remaining` | Apply this item and all later items without further prompts |\n\n**Outcome:** Prefer the host’s **structured choice** when it exists; otherwise offer **numbered replies** (`1`/`2`/`3` etc.) with the id mapping printed beside the numbers. Do not end with only informal bullets and no explicit mapping.\n\n**Custom path (`provide_own`) outcome:** The user’s alternative is captured in chat, **restated as a one-line plan**, **explicitly confirmed**, then applied (or clarified if unsafe/ambiguous). The final summary marks those as **user-specified**.\n\n### Applying changes in Figma (figma-use)\n\n**Outcome:** The Figma file matches what the user **actually chose**—all, some, none, or a **confirmed** custom alternative. Skipped findings stay untouched.\n\n**Delegation:** Performing edits belongs in the **`figma-use`** skill (how to drive the file, validate edits, and recover from errors). This auditor only supplies a **complete brief**: resolved apply-path ids, scope of findings to run now, and per-finding node ids, names, statuses, properties, and target bindings or values (including user-approved custom text for `provide_own`).\n\n**After edits:** The user can see what landed, what did not, and what was never attempted—without this file duplicating Plugin API or script guidance.\n\n### Post-application\n\n**Outcome:** A short inventory—applied, skipped, failed (with enough to retry or fix manually)—so the session does not end ambiguously.\n\n## Escalation\n\n**Outcome:** If no PatternFly token fits, say so plainly and point to **community** ([PatternFly Slack](https://join.slack.com/t/patternfly/shared_invite/zt-3spaxzss2-w1PPDTgvqENVqNvhPDQP~w)) and **formal proposals** ([GitHub Token Proposal](https://github.com/patternfly/design-tokens/issues/new)) instead of inventing names in the audit.\n\n## Where token definitions live (reference)\n\nToken definitions live in `src/patternfly/base/tokens/`:\n- `tokens-palette.scss` — raw color palette\n- `tokens-default.scss` — light theme semantic tokens\n- `tokens-local.scss` — composite tokens, glass composites\n- `tokens-dark.scss`, `tokens-glass.scss`, `tokens-highcontrast.scss` — theme overrides\n\nFor the full token category reference, see [token-reference.md](token-reference.md)." + }, + { + "name": "pf-tokens", + "plugin": "design-foundations", + "description": "Build CSS design tokens for PatternFly core and copy them to the PatternFly repository.", + "content": "---\nname: pf-tokens\ndescription: Build CSS design tokens for PatternFly core and copy them to the PatternFly repository.\n---\n\nBuild CSS design tokens for PatternFly core and move them to the PatternFly repository.\n\n## What to do\n\n1. Build the SCSS for PatternFly core using the `build:scss:core` script\n2. Copy the generated CSS files from the build output to the PatternFly repository's token directory (PatternFly is typically cloned as a sibling directory)\n\n## Expected outcome\n\nThe PatternFly repository's `src/patternfly/base/tokens/` directory contains the freshly built CSS token files from this repository's build output at `packages/module/build/css/`." + }, + { + "name": "figma-changes", + "plugin": "figma", + "description": "Identify Figma design changes and generate code update checklists. Use when the user asks to \"check Figma updates\", \"track design changes\", \"what changed in Figma\", \"create changelog from Figma\", or \"what code needs updating based on Figma\".", + "content": "---\nname: figma-changes\ndescription: Identify Figma design changes and generate code update checklists. Use when the user asks to \"check Figma updates\", \"track design changes\", \"what changed in Figma\", \"create changelog from Figma\", or \"what code needs updating based on Figma\".\nversion: 3.1.0\n---\n\n# Figma Design Change Tracker\n\nTrack Figma design updates and generate code checklists for PatternFly.\n\n## What This Skill Does\n\n1. Fetches recent changes from Figma version history\n2. Analyzes design updates to components\n3. Compares design specs with code implementation\n4. Generates three types of reports (see below)\n5. Creates actionable checklists for developers\n\n## Output Files\n\n**FIGMA_CHANGELOG.md** - Internal design team changelog with all updates\n**RELEASE_NOTES.md** - Consumer-facing release notes\n**figma-updates-[date].md** - Detailed checklist with token changes\n\nSee [report-templates.md](report-templates.md) for full template examples.\n\n## What to Analyze\n\nFor each component update, focus on:\n\n- **Colors** - Background, border, text, hover/focus states\n- **Typography** - Font size, weight, line height\n- **Spacing** - Padding, gaps, margins\n- **Layout** - Dimensions, alignment, structure\n- **Variants** - States (hover, focus, disabled) and sizes\n- **Changes** - Elements added or removed\n\n## Status Determination\n\nAssign each update one of three statuses:\n\n**✅ Design-only** - Figma documenting what's already in code\n**⚠️ Code update needed** - Design is ahead of code\n**🔍 Needs verification** - Unclear if code matches design\n\n### How to Determine Status\n\n1. Check if there's a related GitHub issue\n - Issue closed/merged → Likely ✅ Design-only\n - Issue open → Likely ⚠️ Code update needed\n - No issue → Check token comparison\n\n2. Compare design tokens with code\n - Values match → ✅ Design-only\n - Values differ → ⚠️ Code update needed\n - Can't compare → 🔍 Needs verification\n\n3. Check recent git commits (last 2 weeks)\n - Recent work on component → Possibly ✅ Design-only\n - No recent work → Possibly ⚠️ Code update needed\n\n> See [references/troubleshooting.md](references/troubleshooting.md) for detailed decision tree and automation commands.\n\n## Report Format\n\n### For Each Component Update\n\nInclude:\n- **Date** - When the design was updated\n- **Designer** - Who made the change\n- **Page/Context** - Where in Figma (e.g., \"Chatbot: Filters\")\n- **Status** - ✅ / ⚠️ / 🔍\n- **Links** - Figma, PatternFly.org, GitHub issues\n\n### For Code Updates (⚠️ status only)\n\nCreate token comparison tables:\n\n| ✓ | Token | Current | New | Where Used |\n|---|-------|---------|-----|------------|\n| [ ] | `--pf-c-button--BackgroundColor` | `#0066CC` | `#004080` | Button background |\n\nList files that need updating:\n- `Button.scss` - Update color tokens\n- `Button.md` - Update documentation\n- `Button.test.tsx` - Update snapshots\n\n## Key Guidelines\n\n**Be Specific** - Use exact token names and values\n**Link Everything** - Figma, PatternFly.org, GitHub\n**Prioritize** - High (breaking, a11y), Medium (updates), Low (docs)\n**Note Context** - Always include the Figma page/section\n\n## Examples\n\n**Code Update Needed:**\n```\n### Button - 2026-03-16\n**Status**: ⚠️ Code update needed\n**By**: Sarah Designer | **Page**: Component Library\n\nPrimary button color updated for better accessibility (WCAG AA).\n\nToken: `--pf-c-button--m-primary--BackgroundColor`\nChange: `#0066CC` → `#004080`\n```\n\n**Design-Only:**\n```\n### Card - 2026-03-10\n**Status**: ✅ Design-only\n**Related**: Issue #915 (closed)\n\nFigma updated to match PatternFly 6.0.0. No code changes needed.\n```\n\n## Additional Resources\n\n- [Report Templates](report-templates.md) - Full template examples\n- [Troubleshooting](references/troubleshooting.md) - Common issues\n- [Validation Checklists](references/validation-checklists.md) - Quality checks\n- [Token Mappings](examples/token-mappings.json) - Figma ↔ Code mapping" + }, + { + "name": "figma-icon-finder", + "plugin": "figma", + "description": "Identifies PatternFly icons used in Figma mockups and provides the correct import statements for React components. Use when given a Figma screenshot or URL and the user needs to know which PatternFly icons to import.", + "content": "---\nname: figma-icon-finder\ndescription: Identifies PatternFly icons used in Figma mockups and provides the correct import statements for React components. Use when given a Figma screenshot or URL and the user needs to know which PatternFly icons to import.\nargument-hint: \"[path/to/figma-screenshot.png] or [figma-url] or use @file for autocomplete\"\n---\n\n# Figma Icon Finder\n\nAnalyze Figma design mockups to identify PatternFly icons and provide the correct import statements for React implementation.\n\n## Workflow\n\n### Step 1: Get the design image\n\n- If `$ARGUMENTS` contains an image file path (`.png`, `.jpg`, `.jpeg`, `.webp`): read and analyze it\n- If `$ARGUMENTS` contains a Figma URL: ask the user to provide a screenshot\n- If no arguments: ask the user for a screenshot path\n\n### Step 2: Load icon reference\n\nRead `references/common-icons.md` for the full categorized icon list with visual descriptions and usage patterns.\n\n### Step 3: Analyze the design\n\nExamine the image and identify all icons. For each icon:\n\n1. Note its visual characteristics (shape, style, filled vs outlined)\n2. Consider its context (where it appears, what action it represents)\n3. Match to PatternFly icons using the reference and visual similarity\n4. If uncertain, list candidates with confidence levels\n\n### Step 4: Categorize icons\n\nSeparate identified icons into two groups:\n\n**Explicit import icons** — icons you need to import from `@patternfly/react-icons`:\n- Action icons (edit, delete, copy, etc.)\n- Status indicators used standalone\n- Navigation and object icons\n\n**Component-managed icons** — icons automatically handled by PatternFly components (no import needed):\n- Checkbox states → `Checkbox` component\n- Tree expand/collapse → `TreeView` component\n- Sort indicators → `Table` with sort props\n- Search input icons → `SearchInput` component\n- Dropdown/Select carets → `Dropdown`/`Select` components\n- Pagination controls → `Pagination` component\n\nAsk the user their preferred output detail level (brief vs detailed) and whether to include component-managed icons in the report.\n\n### Step 5: Generate report\n\n**Brief format** — for each icon, show the component usage and a combined import statement:\n\n```tsx\n// Modal close button (top-right corner)\n\n\n// Error status indicator\n\n```\n\n```typescript\nimport { TimesCircleIcon, ExclamationCircleIcon } from '@patternfly/react-icons';\nimport { Icon } from '@patternfly/react-core';\n```\n\n**Detailed format** — for each icon, include:\n- Visual description and location in the design\n- PatternFly match with confidence level\n- Import statement and usage example\n- Context-specific notes (accessibility, status wrapping, etc.)\n- A combined copy-paste-ready import block at the end\n\nFor status icons, always show the `Icon` wrapper pattern:\n\n```tsx\nimport { Icon } from '@patternfly/react-core';\n\n\n\n\n\n```\n\n### Accessibility reminders\n\n- Interactive icons in buttons need `aria-label` or visible text\n- Decorative icons should have `aria-hidden=\"true\"`\n- Status icons should use the `Icon` wrapper with `status` prop\n\n## Edge Cases\n\n- **Multiple possible matches**: list all candidates with confidence levels and recommend based on semantic context\n- **Low-quality image**: request a higher-resolution screenshot and provide best guesses\n- **Component-managed icons**: explain that no import is needed and which component handles it" + }, + { + "name": "pf-compliance-checker", + "plugin": "figma", + "description": "Check Figma designs against PatternFly v6 design system standards. Use when a user provides a Figma URL and wants to validate compliance with PatternFly colors, typography, spacing, components, and UX patterns.", + "content": "---\nname: pf-compliance-checker\ndescription: Check Figma designs against PatternFly v6 design system standards. Use when a user provides a Figma URL and wants to validate compliance with PatternFly colors, typography, spacing, components, and UX patterns.\n---\n\n# PatternFly Compliance Checker\n\nAnalyze Figma prototypes against PatternFly v6 design system standards — components, spacing, typography, colors, and UX patterns.\n\n## Requirements\n\n- Node.js 18+\n- `node-fetch` package (`npm install node-fetch`)\n- `FIGMA_TOKEN` environment variable (or a `figma-config.env` file in the scripts directory)\n- View access to the Figma file\n\n## Workflow\n\n### Step 1: Validate input\n\nAccept a Figma file URL from the user. Valid formats:\n- `https://www.figma.com/design/FILE_ID/FILE_NAME`\n- `https://www.figma.com/file/FILE_ID/FILE_NAME`\n\n### Step 2: Run the checker\n\n```bash\nnode \"$CLAUDE_SKILL_DIR/scripts/patternfly-check.js\" \"\"\n```\n\nThe script fetches the Figma file via API and analyzes all elements for PatternFly v6 compliance. An HTML report opens automatically in the browser.\n\n### Step 3: Present the summary\n\nAfter the script completes, summarize the results for the user:\n\n- Overall compliance score (percentage)\n- Critical violations count and top categories\n- Minor deviations count\n- Recommendations for priority fixes\n\n### Step 4: Suggest next steps\n\n- Focus on critical violations first — use pattern-based grouping to fix multiple issues at once\n- Use the \"Export JSON\" button in the report for developer handoff\n- Re-run after fixes to track improvement\n\n## What gets checked\n\n**Components** (17 types): buttons, form inputs, cards, alerts, navigation, tables, modals, tooltips, pagination, breadcrumbs, badges, tabs, accordions, wizards, drawers\n\n**Design tokens**: colors (PatternFly palette), typography (Red Hat fonts, sizes, weights), spacing (4px grid scale), border radius\n\n**Advanced checks**: component states (hover, focus, disabled), spacing relationships, typography hierarchy (H1 count), microcopy consistency (Delete vs Remove), component library usage (detached instances)" + }, + { + "name": "pf-design-mode", + "plugin": "figma", + "description": "Create and edit Figma design files using the Figma MCP workflow with PatternFly-approved libraries only. Use when the user asks to build, update, restyle, or restructure Figma frames/components and wants write operations.", + "content": "---\nname: pf-design-mode\ndescription: Create and edit Figma design files using the Figma MCP workflow with PatternFly-approved libraries only. Use when the user asks to build, update, restyle, or restructure Figma frames/components and wants write operations.\ndisable-model-invocation: true\n---\n\n# PatternFly Design Mode\n\nUse this skill for write-focused design tasks in Figma.\n\n## Required prerequisites\n\nThis skill requires two skills from the **official Figma plugin** — see the [plugin README](../../README.md) for install instructions.\n\n- `figma-use` — mandatory before every `use_figma` call; never skip it\n- `figma-generate-design` — required when the task involves creating a full page or screen from code\n\nRules:\n\n- Never call `use_figma` directly without first loading `figma-use`.\n- If the task includes broad screen creation from code, pair `figma-use` with `figma-generate-design`.\n\n## Approved component sources (strict)\n\nUse components and patterns only from the files listed in `references/approved-sources.md`.\n\nRules:\n\n- Do not use components from any other library or file.\n- Only use semantic design tokens and spacers from the approved files.\n- Do not create ad-hoc replacement components when an approved component/pattern exists.\n- If a needed component/pattern is missing in these sources, stop and ask the user before proceeding.\n\n## Pattern-first selection (strict)\n\nWhenever possible, prefer larger patterns denoted with the `🧰` emoji.\n\n- Select `🧰` patterns before assembling equivalent UI from smaller components.\n- Only compose from smaller components when no suitable `🧰` pattern exists for the requirement.\n\n## Page creation behavior (strict)\n\nIf the user asks to \"make a new page\":\n\n- Do not replace, clear, or mutate existing page content as the starting point.\n- Create a new top-level frame for subsequent changes.\n- Apply all new work to that new frame unless the user explicitly asks to edit an existing frame.\n\n## When to use\n\nUse this skill when a request includes one or more of the following:\n\n- \"Create this in Figma\", \"edit this Figma file\", \"update this screen\"\n- \"Make a new page\" or equivalent phrasing for a new screen\n- Layout restructuring (auto-layout, spacing, constraints, frame hierarchy)\n- Component/variant updates, token/variable binding, or style cleanup\n- Figma URL-driven implementation work\n\n## Workflow\n\n1. Confirm target\n - Identify `fileKey` and `nodeId` from the Figma URL when provided.\n - Clarify expected output (new frame, edits to an existing frame, component updates).\n\n2. Load prerequisite skill\n - Invoke the `figma-use` skill instructions first.\n\n3. Resolve approved assets with pattern-first priority\n - Search and import from the approved PatternFly files only (see `references/approved-sources.md`).\n - Prefer matching `🧰` patterns first, then fall back to smaller components if needed.\n - Verify each chosen component/pattern comes from an approved source.\n\n4. Handle page intent\n - If request is \"make a new page\", create a new top-level frame first.\n - Otherwise, edit only the user-specified existing frame/scope.\n\n5. Make incremental edits\n - Prefer editing existing nodes/components over rebuilding from scratch (except new-page requests).\n - Use approved design-system components and variables instead of hardcoded values.\n - Apply changes in small batches and verify after each batch.\n\n6. Validate outcome\n - Check hierarchy, alignment, spacing, constraints, and variant states.\n - Ensure all inserted components/patterns come from approved sources only.\n - Confirm `🧰` patterns were used whenever a suitable option exists.\n\n## Guardrails\n\n- Reuse approved library assets first; avoid duplicate ad-hoc components.\n- Bind variables/tokens where possible (color, type, spacing, radius).\n- Keep names semantic and stable for handoff (frames, components, variants).\n- If requirements are ambiguous, ask a focused clarification question before making large edits." + }, + { + "name": "duplicate-epic", + "plugin": "issue-management", + "description": "Use when `/duplicate-epic ` should clone a Jira Epic, Story, or Bug into the PF project, resolve non-epic inputs to their parent epic, link back to the source, and attach the new epic to a PF feature.", + "content": "---\nname: duplicate-epic\ndescription: Use when `/duplicate-epic ` should clone a Jira Epic, Story, or Bug into the PF project, resolve non-epic inputs to their parent epic, link back to the source, and attach the new epic to a PF feature.\ndisable-model-invocation: true\n---\n\n# Duplicate Epic\n\nClones a Jira epic (e.g., from the `COST` project) into the PatternFly (`PF`) Jira space, ensures it carries an \"is duplicated by\" link referencing the original, and sets it as a child of the given feature.\n\n## Requirements\n\n| Tool | Purpose | Install |\n|---|---|---|\n| `curl` | Jira REST API calls | pre-installed on macOS; `brew install curl` |\n| `jq` | JSON parsing and payload construction | `brew install jq` |\n\nThe script checks for both tools at startup and exits with a helpful message if either is missing.\n\n## Input Parsing\n\nThe command takes exactly two positional arguments:\n\n| Position | Name | Description |\n|---|---|---|\n| `$1` | `issue` | Any Jira issue key or full URL — Epic, Story, Bug, etc. |\n| `$2` | `feature` | The PF feature key or full URL to assign the new epic to |\n\nBoth bare keys and full URLs are accepted:\n\n| Input | Parsed key |\n|---|---|\n| `COST-7355` | `COST-7355` |\n| `https://redhat.atlassian.net/browse/COST-7355` | `COST-7355` |\n| `PF-3868` | `PF-3868` |\n| `https://redhat.atlassian.net/browse/PF-3868` | `PF-3868` |\n\nPass `$1` and `$2` directly to the script — no further parsing required.\n\n## Prerequisites\n\nThe script requires two environment variables:\n\n| Variable | Description |\n|---|---|\n| `JIRA_USER_EMAIL` | Atlassian account email |\n| `JIRA_API_TOKEN` | API token from [id.atlassian.com/manage/api-tokens](https://id.atlassian.com/manage/api-tokens) |\n\nIf either is missing, ask the user for their email and direct them to create an API token, then set the variables inline when running the script.\n\n## Workflow\n\nRun the script from the skill directory:\n\n```bash\ncd $CLAUDE_SKILL_DIR\nbash scripts/duplicate_epic.sh \n```\n\nThe first argument (`issue`) may be an Epic, Story, Bug, or any other issue type. If it is not an Epic, the script automatically resolves its parent epic before cloning.\n\n**Examples:**\n\n```bash\nbash scripts/duplicate_epic.sh COST-7355 PF-3868\nbash scripts/duplicate_epic.sh COST-7309 PF-3868 # story/bug — script walks up to parent epic automatically\n```\n\nWith inline credentials:\n\n```bash\nJIRA_USER_EMAIL=\"you@example.com\" JIRA_API_TOKEN=\"your-token\" \\\n bash scripts/duplicate_epic.sh COST-7170 PF-3406\n```\n\n## What the Script Does\n\n1. **Resolve current user** — looks up the account ID for the authenticated user (used for the assignee field).\n2. **Resolve to an epic** — fetches the given issue. If it is not an `Epic` (e.g., it is a Story or Bug), the script walks up to its parent epic using `fields.parent` (next-gen projects) or `fields.customfield_10014` (classic epic link). Exits with an error if no parent epic can be found.\n3. **Find existing clone** — checks the resolved epic's `Duplicate` issue links for any `PF-` issue; skips creation if found.\n4. **Clone** — if no clone exists, creates a new Epic in the `PF` project copying the summary and labels. The description is sanitized before cloning: `mediaSingle` and `media` nodes (embedded attachments) are stripped, so embedded images and file attachments will not appear in the PF copy.\n5. **Ensure \"is duplicated by\" link** — adds a `Duplicate` link so the new epic displays \"is duplicated by {ORIGINAL EPIC}\" in its linked work items; skips if already present.\n6. **Set parent and assignee** — assigns the new epic as a child of the given feature and assigns it to the current user (resolved automatically via the API token).\n7. **Display results** — prints clickable URLs for the feature, new epic, and original epic.\n\n## Output\n\nAfter a successful run, display these URLs to the user:\n\n```\nFeature: https://redhat.atlassian.net/browse/PF-3406\nNew Epic: https://redhat.atlassian.net/browse/PF-XXXX\nOriginal Epic: https://redhat.atlassian.net/browse/COST-7170\nInput Issue: https://redhat.atlassian.net/browse/COST-7309 ← only shown when input was not itself an epic\n```" + }, + { + "name": "pf-bug-triage", + "plugin": "issue-management", + "description": "Performs preliminary triage of opened issues marked as bugs. Suggests what needs to be updated to fix reported bugs, provides context for assignees, and tags the most appropriate maintainer when the issue contains questions. Use when triaging bug issues, reviewing new bug reports, or preparing issues for assignment.", + "content": "---\nname: pf-bug-triage\ndescription: Performs preliminary triage of opened issues marked as bugs. Suggests what needs to be updated to fix reported bugs, provides context for assignees, and tags the most appropriate maintainer when the issue contains questions. Use when triaging bug issues, reviewing new bug reports, or preparing issues for assignment.\n---\n\n# Bug Triage\n\nPerforms preliminary triage of opened issues labeled as bugs. Produces a structured triage summary with fix suggestions and maintainer recommendations.\n\n## Input\n\nThe user provides an issue (title, body, labels, and optionally linked files or component names). The issue must be marked or labeled as a bug.\n\n## Triage Workflow\n\n### 1. Parse the Issue\n\nExtract from the issue:\n- **Summary** — One-sentence description of the bug\n- **Reproduction steps** — Are they clear and complete?\n- **Expected vs actual behavior** — Is the distinction stated?\n- **Environment** — Versions, browser, OS if mentioned\n- **Affected area** — Component, file path, or feature inferred from description\n\n### 2. Assess Completeness\n\nFlag if missing:\n- [ ] Reproduction steps\n- [ ] Expected vs actual behavior\n- [ ] Version/environment info\n- [ ] Minimal reproduction (code, sandbox, or repo link)\n\nSuggest what the reporter should add before the issue can be triaged effectively.\n\n### 3. Identify Fix Location\n\nSearch the codebase for:\n- Component names, file paths, or imports mentioned in the issue\n- Related code in `packages/`, `src/`, or equivalent\n- Tests that might need updates\n- Documentation that might be wrong\n\nSuggest **what needs to be updated** to fix the bug:\n- Specific files or components\n- Likely root cause (logic, styling, accessibility, API usage)\n- Tests to add or modify\n- Any docs to update\n\n### 4. Determine Maintainer\n\nFind the most appropriate maintainer to tag when the issue **contains questions** (e.g., \"Is this expected?\", \"How should we handle X?\"):\n\n1. **Check CODEOWNERS** — If present, match issue paths to ownership:\n - Map affected files/components to CODEOWNERS entries\n - Tag the owner(s) for the most relevant path(s)\n\n2. **Check CONTRIBUTING.md / MAINTAINERS** — Look for maintainer lists, areas of responsibility, or \"who to ask\" sections.\n\n3. **Infer from codebase** — If no CODEOWNERS:\n - Recent commits to affected files\n - Component/package naming (e.g., `packages/react-table` → table maintainers)\n - Comments or author info in relevant files\n\n4. **Fallback** — If unclear, suggest: \"Tag @patternfly/react-core-maintainers\" or the repo's default maintainer group.\n\n**Only suggest tagging when the issue explicitly asks a question** that requires maintainer input. Do not tag for straightforward bugs that just need implementation.\n\nFor CODEOWNERS format and when-to-tag guidance, see [reference.md](reference.md).\n\n## Output Format\n\nProduce a triage comment or summary using this template:\n\n```markdown\n## Bug Triage Summary\n\n### Summary\n[One-sentence bug description]\n\n### Completeness\n- [ ] Reproduction steps clear\n- [ ] Expected vs actual stated\n- [ ] Environment/versions provided\n- [ ] Minimal reproduction available\n\n[If incomplete: List what the reporter should add]\n\n### Suggested Fix\n**Likely location:** [files, components, or packages]\n**Root cause:** [brief hypothesis]\n**Changes needed:**\n- [ ] [Specific change 1]\n- [ ] [Specific change 2]\n- [ ] [Tests to add/modify]\n- [ ] [Docs to update if applicable]\n\n### Context for Assignee\n[2–4 bullets: key files to look at, related patterns, similar past fixes, or docs to reference]\n\n### Maintainer Tag (if issue has questions)\n**Suggested:** @[username or team]\n**Reason:** [Why this maintainer — e.g., \"Owns Table component per CODEOWNERS\"]\n```\n\n## Rules\n\n- Be concise. Each section should be 1–3 sentences or bullets.\n- Only suggest maintainer tags when the issue **asks a question** requiring maintainer input.\n- If the codebase is unavailable, state what you would search for and produce a partial triage.\n- Use the repo's actual structure (e.g., `packages/react-core`, `packages/react-table`) when suggesting locations." + }, + { + "name": "pf-create-issue", + "plugin": "issue-management", + "description": "Create GitHub issues for PatternFly repositories with smart templates, followup tracking, and duplicate detection.", + "content": "---\nname: pf-create-issue\ndescription: Create GitHub issues for PatternFly repositories with smart templates, followup tracking, and duplicate detection.\n---\n\n# PatternFly Issue Creator\n\nCreate well-structured issues for PatternFly repos. Handles templates, cross-repo followups, and duplicate detection.\n\n## What to Do\n\n### 1. Determine Target Repo\n\n**Detect context** from git remote, file paths, or keywords in user's request to suggest relevant repos:\n\n- React/JSX/component/props → patternfly-react\n- Token/design token → design-tokens\n- CSS/HTML/core/stylesheet/style → patternfly\n- guidelines/documentation/website → patternfly-org\n- a11y/accessibility/aria/screen reader/wcag → patternfly or patternfly-react, depending on other context\n- Migration/codemod/upgrade → pf-codemods\n- Extension → list PatternFly extension repos\n\n**Ask which repo** if not obvious. Show context-based suggestions first.\n\n### 2. Choose Issue Type\n\n**A. New Issue** - Fresh issue for target repo\n**B. Followup Issue** - Work needed in target PatternFly repo after changes in source PatternFly repo\n\n### 3A. New Issue Workflow\n\n**Find templates:**\n\n1. Check current directory `.github/ISSUE_TEMPLATE/`\n2. If not found, fetch from GitHub using `gh api` (if available)\n3. If not found, ask for local clone path or search for local clone\n4. If none found, offer blank issue\n\n**Pre-populate fields** from context:\n\n- Title: \"Bug - [description]\" or \"[Component] - [description]\" (feature) or \"[description]\" (tech debt/other issue type)\n- Component, description, steps, expected/actual behavior from user's request\n- Version from package.json if available\n\n**Ask user to confirm/edit** each pre-filled field. For blank fields, ask user to provide.\n\n### 3B. Followup Issue Workflow\n\n**Ask how to determine followup work:**\n\n1. User describes it themselves\n2. Analyze git commits to suggest work\n\n**If analyzing commits:**\n\n- Get commits since branch diverged from main\n- Identify relevant changes only (new CSS classes, tokens, breaking changes, new features, accessibility updates, updated or new examples/demos)\n- Filter out auto-inherited changes (style updates that version bump handles)\n\n**Analyze target repo** (if found locally or local file path provided by user):\n\n- Search for component files affected by changes\n- Read current implementation (markup, classes, props, interfaces, examples)\n- Generate specific tasks with file paths: \"Add `variant` prop to CardHeader.tsx:24\"\n- If not found, provide generic suggestions\n\n**Search for related/dependent components** when suggesting work:\n\n- Select → also consider Menu, Popper, MenuToggle, Dropdown\n- DatePicker → also consider Calendar, TextInput\n- Table → also consider Checkbox, Pagination, Toolbar\n (See full list in patterns below)\n\n**Detect PR** for current branch using `gh pr view` (if available). Ask user if they want to reference it.\n\n**Structure followup issue:**\n\n- Title: Type-prefixed like new issues\n- Context section: Link to source PR or branch\n- Changes section: Only relevant changes (omit auto-inherited)\n- Work needed: Specific tasks (with file:line if analyzed) or generic tasks\n\n### 4. Check for Similar Issues\n\n**Search with multiple strategies** using `gh issue list` (if available):\n\n1. Exact: component + feature\n2. Broad: component only\n3. Related components: dependent/child components (Menu or Popper for Select and Dropdown, AccordionItem for Accordion)\n4. Features: keywords like \"keyboard\", \"variant\", \"loading\"\n5. Synonyms: \"danger\"→\"error\"/\"destructive\", \"loading\"→\"spinner\"/\"pending\"\n6. Closed issues: recent completions\n\n**Score and deduplicate:**\n\n- High: Same component + feature\n- High-Medium: Related component + feature (note: \"Menu (used by Select)\")\n- Medium: Same component OR feature\n- Lower: Synonyms, related concepts\n\n**Show top 5-10 results** with relevance labels. Ask: create new, comment on existing, or cancel.\n\n**If no gh CLI**, skip check and inform user where to search manually before continuing to create a new issue.\n\n### 5. Create or Save\n\n**With gh CLI** (if authenticated): Offer to create directly or save to file\n**Without gh CLI**: Save to file at user defined path or to `~/Desktop/[repo]-issue-[timestamp].md` by default\n\nInclude title, body, and instructions to create manually if saved.\n\n### 6. Confirm\n\nReport success (issue URL or file path). For followups, suggest linking to related work.\n\n## Component Relationships\n\nWhen searching for duplicates or analyzing followup work, consider these dependencies:\n\n**Uses Popper:**\n\n- Select, Dropdown, DatePicker, TimePicker, Popover, Tooltip\n\n**Uses Menu:**\n\n- Select, Dropdown, DatePicker, TimePicker\n\n**Uses Form components:**\n\n- Form → FormGroup, TextInput, Checkbox, Radio, Select\n\n**Card family:**\n\n- Card → CardHeader, CardBody, CardFooter\n\n**Table family:**\n\n- Table → Checkbox, Pagination, Toolbar\n\n**Modal family:**\n\n- Modal, Wizard → Backdrop\n\n**List family:**\n\n- DataList → Checkbox, Radio\n\n## Title Formats\n\n- **Bug**: \"Bug - [description]\"\n- **Feature**: \"[Component] - [description]\" (no \"Feature\" prefix)\n- **Tech Debt**: \"[description]\" (no prefix)\n\n## Followup Patterns\n\n| Source Repo | Target Repo | Common Followup Work |\n| ----- | ----- | ------------------------------------ |\n| **patternfly** (HTML/CSS) | **patternfly-react** | Update React component to use new CSS classes, tokens, or structure; make updates to examples/demos for parity |\n| **patternfly-react** | **patternfly** | Update HTML/CSS component to use new CSS classes or structure; make updates to examples/demos for parity |\n| **design-tokens** | **patternfly** | Apply new token variables | |\n| **patternfly** or **patternfly-react** | patternfly-org | Update design guidelines or accessibility documentation for component changes |\n| **patternfly-react** | **pf-codemods** | Update or add a codemod, typically for breaking or mass changes |\n\n## Arguments\n\n- `/pf-create-issue` - Interactive\n- `/pf-create-issue [repo]` - Target specific repo\n- `/pf-create-issue followup [repo]` - Create followup\n\n## Key Behaviors\n\n- Pre-fill what you can from context\n- Filter followup changes to only what needs action in target repo\n- Search broadly for duplicates (component relationships, synonyms)\n- Fall back gracefully when gh CLI unavailable\n- Support both markdown and YAML templates" + }, + { + "name": "quarterly-initiative-report", + "plugin": "issue-management", + "description": "Generate comprehensive quarterly Jira status reports with progress tracking, RAG assessment, blocker identification, cross-project duplicate link analysis, and Q+1 recommendations. Use when generating quarterly reports, tracking initiative progress, or analyzing epic completion metrics across Jira projects with labels.", + "content": "---\nname: quarterly-initiative-report\ndescription: Generate comprehensive quarterly Jira status reports with progress tracking, RAG assessment, blocker identification, cross-project duplicate link analysis, and Q+1 recommendations. Use when generating quarterly reports, tracking initiative progress, or analyzing epic completion metrics across Jira projects with labels.\ndisable-model-invocation: false\n---\n\n# Quarterly Initiative Status Report\n\nGenerate comprehensive quarterly status reports for Jira initiatives with progress tracking, RAG (Red/Amber/Green) status assessment, blocker identification, and next-quarter priority recommendations.\n\n## Requirements\n\n| Tool | Purpose | Check |\n|---|---|---|\n| `curl` | Jira REST API calls | `command -v curl` |\n| `jq` | JSON parsing | `command -v jq` or `brew install jq` |\n\n## Prerequisites\n\nThis skill requires Jira API credentials configured as environment variables:\n\n| Variable | Description | Example |\n|---|---|---|\n| `ATLASSIAN_EMAIL` | Your Atlassian account email | `user@company.com` |\n| `ATLASSIAN_API_TOKEN` | API token from [id.atlassian.com/manage-profile/security/api-tokens](https://id.atlassian.com/manage-profile/security/api-tokens) | `ATATT3xFfGF0...` |\n| `ATLASSIAN_SITE_URL` | Your Atlassian instance URL | `https://company.atlassian.net` |\n\n### Setting Environment Variables\n\n**Option 1: In AI tool settings** (Claude Code settings.json, Cursor config):\n```json\n{\n \"env\": {\n \"ATLASSIAN_EMAIL\": \"your-email@company.com\",\n \"ATLASSIAN_API_TOKEN\": \"your-token-here\",\n \"ATLASSIAN_SITE_URL\": \"https://your-company.atlassian.net\"\n }\n}\n```\n\n**Option 2: Shell environment**:\n```bash\nexport ATLASSIAN_EMAIL=\"your-email@company.com\"\nexport ATLASSIAN_API_TOKEN=\"your-token-here\"\nexport ATLASSIAN_SITE_URL=\"https://your-company.atlassian.net\"\n```\n\n**Verify credentials:**\n```bash\ncurl -s -u \"$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN\" \\\n -H \"Accept: application/json\" \\\n \"$ATLASSIAN_SITE_URL/rest/api/3/myself\" | jq '.displayName'\n```\n\n## Usage\n\nWhen invoked, gather from the user:\n1. **Jira Project Key** (e.g., \"PF\" for PatternFly)\n2. **Label** identifying the initiative (e.g., \"Q1-2026\" or \"Q12026\")\n\nThen execute the workflow below to generate the comprehensive report.\n\n## Workflow\n\n### Step 1: Fetch All Epics with the Label\n\n```bash\n# Search for all epics/initiatives with the label\ncurl -s -u \"$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN\" \\\n -H \"Accept: application/json\" \\\n -X POST \\\n -H \"Content-Type: application/json\" \\\n -d '{\"jql\":\"project=PROJECT AND labels=\\\"LABEL\\\" AND type IN (Epic, Initiative)\",\"fields\":[\"key\",\"summary\",\"status\",\"assignee\",\"duedate\",\"issuetype\",\"labels\"],\"maxResults\":1000}' \\\n \"$ATLASSIAN_SITE_URL/rest/api/3/search/jql\"\n```\n\n### Step 2: For Each Epic, Gather Complete Metrics\n\n**Process for EVERY epic (including closed):**\n\n1. **Fetch direct sub-issues:**\n```bash\ncurl -s -u \"$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN\" \\\n -H \"Accept: application/json\" \\\n -X POST \\\n -H \"Content-Type: application/json\" \\\n -d '{\"jql\":\"parent=EPIC-KEY\",\"fields\":[\"key\",\"summary\",\"status\",\"priority\"],\"maxResults\":1000}' \\\n \"$ATLASSIAN_SITE_URL/rest/api/3/search/jql\" | \\\n jq '{\n total: (.issues | length),\n done: ([.issues[] | select(.fields.status.statusCategory.key == \"done\")] | length),\n in_progress: ([.issues[] | select(.fields.status.statusCategory.key == \"indeterminate\")] | length),\n todo: ([.issues[] | select(.fields.status.statusCategory.key == \"new\")] | length),\n completion_pct: (if (.issues | length) > 0 then (([.issues[] | select(.fields.status.statusCategory.key == \"done\")] | length) * 100 / (.issues | length) | floor) else 0 end)\n }'\n```\n\n2. **Check for duplicate links (CRITICAL for all epics):**\n```bash\n# Check EVERY epic for cross-project duplicate links\ncurl -s -u \"$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN\" \\\n -H \"Accept: application/json\" \\\n \"$ATLASSIAN_SITE_URL/rest/api/3/issue/EPIC-KEY?fields=issuelinks\" | \\\n jq '{\n key: .key,\n duplicates: [.fields.issuelinks[] | select(.type.name == \"Duplicate\") | {\n linked_issue: (if .outwardIssue then .outwardIssue.key else .inwardIssue.key end),\n linked_type: (if .outwardIssue then .outwardIssue.fields.issuetype.name else .inwardIssue.fields.issuetype.name end)\n }]\n }'\n```\n\n3. **For each linked epic, fetch its child issues:**\n```bash\ncurl -s -u \"$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN\" \\\n -H \"Accept: application/json\" \\\n -X POST \\\n -H \"Content-Type: application/json\" \\\n -d '{\"jql\":\"parent=LINKED-EPIC-KEY\",\"fields\":[\"key\",\"summary\",\"status\"],\"maxResults\":1000}' \\\n \"$ATLASSIAN_SITE_URL/rest/api/3/search/jql\" | \\\n jq '{\n total: (.issues | length),\n done: ([.issues[] | select(.fields.status.statusCategory.key == \"done\")] | length),\n in_progress: ([.issues[] | select(.fields.status.statusCategory.key == \"indeterminate\")] | length),\n todo: ([.issues[] | select(.fields.status.statusCategory.key == \"new\")] | length)\n }'\n```\n\n**IMPORTANT:** Combine direct children + linked epic children for total metrics. Many cross-project initiatives track significant work via duplicate links (e.g., AAP, MTV, CONSOLE, SAT projects).\n\n### Step 3: Calculate Aggregate Metrics\n\n- **Total Issues:** Sum all direct + linked issues across all epics\n- **Overall Completion:** (Total Done / Total Issues) × 100\n- **Epic Counts:** Closed, In Progress, New\n- **Cross-Project Work:** Issues tracked via duplicate links\n\n### Step 4: Identify Blockers\n\n```bash\n# Find high-priority or blocked issues\ncurl -s -u \"$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN\" \\\n -H \"Accept: application/json\" \\\n -X POST \\\n -H \"Content-Type: application/json\" \\\n -d '{\"jql\":\"project=PROJECT AND labels=\\\"LABEL\\\" AND (status=Blocked OR priority=Highest)\",\"fields\":[\"key\",\"summary\",\"status\",\"priority\",\"assignee\"],\"maxResults\":1000}' \\\n \"$ATLASSIAN_SITE_URL/rest/api/3/search/jql\"\n```\n\n### Step 5: Determine RAG Status\n\nFor each epic, evaluate in this order (first match wins):\n- **🔴 Red (Critical):** <40% complete OR critical blockers OR unassigned near deadline\n- **🟡 Amber (At Risk):** 40-74% complete OR 1-2 non-critical blockers\n- **🟢 Green (On Track):** ≥75% complete OR ≥50% with no blockers\n\n### Step 6: Generate Report\n\nStructure the output markdown report with these sections:\n\n## Report Structure\n\n```markdown\n# Quarterly Initiative Status Report: [Initiative Name]\n**Reporting Period:** [Quarter/Year]\n**Report Date:** [Current Date]\n**Overall Status:** 🟢/🟡/🔴 [RAG]\n\n---\n\n## Executive Summary\n\n[2-3 paragraphs: overall health, key achievements, critical concerns]\n\n**Key Metrics:**\n- Overall Completion: X% (Y/Z issues)\n- Epics Completed: A of B\n- Critical Blockers: C\n\n---\n\n## Initiative Overview\n\n**Initiative:** [Label/Name]\n**Quarter:** Q# YYYY\n**Timeline:** [Start] - [End]\n**Days Remaining:** X days\n\n**Goals:** [Extracted from initiative description or inferred]\n\n---\n\n## Epic Status Dashboard\n\n| Epic | Owner | Status | Progress | RAG | Notes |\n|------|-------|--------|----------|-----|-------|\n| [KEY] [Summary] | [Owner] | In Progress | 75% (15/20) | 🟢 | |\n| [KEY] [Summary] | [Owner] | In Progress | 45% (9/20) | 🟡 | Has 1 blocker |\n| [KEY] [Summary] | [Owner] | New | 0% (0/10) | 🔴 | Unassigned |\n\n---\n\n## Detailed Metrics\n\n### Overall Progress\n- **Total Issues:** X\n- **Completed:** Y (Z%)\n- **In Progress:** A (B%)\n- **To Do:** C (D%)\n\n### Cross-Project Work\n- **Total Linked Issues:** N (via duplicate epics)\n- **Projects:** AAP, MTV, CONSOLE, SAT, etc.\n- **Linked Completion:** P%\n\n### By Epic\n[For each epic with duplicate links, show:]\n- **[Epic Key]** - [Summary]: X direct children (Y% complete)\n - Linked via duplicates: [Linked Epic Key] (Z children, W% complete)\n - Combined: Total issues, overall %\n\n---\n\n## Blockers and Risks\n\n### Critical Blockers (Immediate Action Required)\n1. **[Epic Key]:** [Description]\n - Impact: High/Medium/Low\n - Recommendation: [Action]\n\n### Risks (Monitor Closely)\n1. **[Risk]:** [Description]\n - Likelihood: High/Medium/Low\n - Impact: High/Medium/Low\n - Mitigation: [Strategy]\n\n---\n\n## Q+1 Priority Recommendations\n\n### Must Complete (Carryover)\n1. **[Epic/Task]** - [Reason why critical]\n\n### High Priority (Next Phase)\n1. **[Suggested Work]** - [Builds on completed X]\n\n---\n\n## Appendix\n\n### Methodology\n- Data source: Jira REST API v3\n- Reporting period: [Dates]\n- Status categories: \"done\", \"indeterminate\", \"new\"\n\n### Complete Epic Reference Table\n\n| Epic | Summary | Owner | Done | In Prog | To Do | Total | % | Link |\n|------|---------|-------|------|---------|-------|-------|---|------|\n| **[KEY]** | [Summary] | [Owner] | X | Y | Z | N | P% | [View]([url]) |\n\n**Notes:**\n- * Indicates epic with cross-project duplicate links\n- Total includes direct + linked epic work\n- Sorted by completion % (descending)\n\n**Summary Totals:**\n- Total Issues: X\n- Completed: Y (Z%)\n```\n\n## Best Practices\n\n1. **Check ALL epics for duplicate links** - Even closed epics may track work in other projects\n2. **Report cross-project work** - Many initiatives span multiple Jira projects (AAP, MTV, etc.)\n3. **Use data-driven RAG** - Don't guess; base status on actual completion %\n4. **Track trends** - Compare with previous reports to show velocity\n5. **Be concise in executive summary** - Decision-makers want key facts\n6. **Include appendix table** - Full epic reference with links for drill-down\n\n## Common Patterns\n\n**Epic with no direct children but has linked work:**\n```\nEpic PF-3227: Ansible Nexus Migration (Closed)\n Direct children: 0 issues\n Linked via duplicates:\n - AAP-58793: 16 issues (16 done, 100%)\n Combined: 16 issues, 100% complete ✅\n```\n\n**Epic with both direct and linked work:**\n```\nEpic PF-3408: Ansible Q1 Features (In Progress)\n Direct children: 0 issues\n Linked via duplicates:\n - AAP-60038: 63 issues (55 done, 87%)\n - AAP-57961: 18 issues (18 done, 100%)\n - AAP-59349: 56 issues (22 done, 39%)\n Combined: 137 issues, 69% complete\n```\n\n## Example Invocation\n\n**User:** \"Generate a quarterly report for PF project with label Q12026\"\n\n**Assistant actions:**\n1. Confirm project key and label with user\n2. Fetch all epics with label\n3. For each epic:\n - Fetch direct children\n - Check for duplicate links\n - Fetch linked epic children\n - Calculate combined metrics\n4. Calculate aggregate statistics\n5. Identify blockers and assign RAG status\n6. Generate comprehensive markdown report\n7. Save report to file with date in filename\n\n**Output file:** `Q1-2026-Q12026-Quarterly-Report-[DATE].md`" + }, + { + "name": "summarize-jira-issues", + "plugin": "issue-management", + "description": "\"Summarize Jira sprint issues and contributions for the current user. Use when the user asks to: (1) See what's left in the sprint, (2) Summarize their assigned work, (3) Prioritize sprint tasks, (4) See issues they're contributing to, or (5) Understand what to work on next. Focuses on active sprint work first, then shows contributor roles and backlog.\"", + "content": "---\nname: summarize-jira-issues\ndescription: \"Summarize Jira sprint issues and contributions for the current user. Use when the user asks to: (1) See what's left in the sprint, (2) Summarize their assigned work, (3) Prioritize sprint tasks, (4) See issues they're contributing to, or (5) Understand what to work on next. Focuses on active sprint work first, then shows contributor roles and backlog.\"\n---\n\n# Summarize My Jira Issues\n\nFetch sprint issues assigned to or contributed by the current user, summarize the workload, and provide prioritization recommendations.\n\n## Workflow\n\n1. **Get user identity** - Identify the current user's Jira account\n2. **Fetch sprint issues** - Query active sprint items (assigned + contributing)\n3. **Fetch contributor issues** - Query issues where user is listed as contributor\n4. **Analyze workload** - Categorize by sprint commitment vs contributions\n5. **Generate summary** - Present sprint-focused overview with recommendations\n\n## Step 1: Get User Identity\n\nIdentify the current user's Atlassian account and accessible Jira resources (account ID and cloud ID).\n\n## Step 2: Fetch Sprint Issues\n\nRun these queries in parallel via the Atlassian MCP:\n\n**Active sprint issues assigned to user** (open statuses, ordered by priority then status):\n```jql\nassignee = currentUser() AND sprint in openSprints() AND status NOT IN (Done, Closed, Resolved) ORDER BY priority DESC, status ASC\n```\n\n**Sprint issues completed this sprint** (most recently resolved first):\n```jql\nassignee = currentUser() AND sprint in openSprints() AND status IN (Done, Closed, Resolved) ORDER BY resolved DESC\n```\n\n## Step 3: Fetch Contributor Issues\n\nQuery issues where the user is a contributor but not the assignee. Run in parallel with sprint queries.\n\n```jql\n\"Contributor[User Picker (multiple users)]\" = currentUser() AND assignee != currentUser() AND status NOT IN (Done, Closed, Resolved) ORDER BY priority DESC, updated DESC\n```\n\n**Note:** The contributor field name varies by Jira instance. Common alternatives: `\"Contributors\"`, `cf[XXXXX]`. If the query fails, try alternate field names or ask the user.\n\n## Step 4: Fetch Backlog (Brief)\n\nFetch a brief backlog summary — sprint work takes priority. Limit to ~10 results.\n\n```jql\nassignee = currentUser() AND (sprint is EMPTY OR sprint not in openSprints()) AND status NOT IN (Done, Closed, Resolved) ORDER BY priority DESC, updated DESC\n```\n\n## Step 5: Analyze Workload\n\n### Sprint Focus\n\nThe primary analysis should be on sprint items:\n\n| Category | Criteria | Action |\n|----------|----------|--------|\n| 🔴 **Sprint - In Progress** | Active sprint items being worked on | Complete these first |\n| 🟡 **Sprint - To Do** | Sprint items not yet started | Start after in-progress items |\n| 🟢 **Sprint - Done** | Completed this sprint | Track velocity |\n\n### Contributor Analysis\n\nFor issues where user is a contributor:\n\n| Category | Criteria | Action |\n|----------|----------|--------|\n| 👥 **Active Contributions** | In Progress items you're helping with | May need your input |\n| 📋 **Pending Contributions** | To Do items you'll contribute to | Be aware of upcoming work |\n\n### Backlog (Brief)\n\nOnly highlight backlog items that are:\n- High priority and may need sprint inclusion\n- Blocked or stale and need attention\n- Quick wins that could be done if sprint work completes early\n\n## Step 6: Generate Summary\n\nPresent findings using this sprint-focused structure.\n\n### Summary Output Template\n\n```markdown\n# Sprint Summary\n\n## Sprint Status\n- **Sprint Items Remaining:** [count]\n- **In Progress:** [count] | **To Do:** [count]\n- **Completed This Sprint:** [count]\n\n---\n\n## 🎯 Your Sprint Commitment\n\n### In Progress\n[List sprint items currently being worked on]\n\n| Issue | Summary | Status | Updated |\n|-------|---------|--------|---------|\n| PROJ-123 | [summary] | In Progress | Today |\n\n### To Do\n[List sprint items not yet started]\n\n| Issue | Summary | Priority |\n|-------|---------|----------|\n| PROJ-456 | [summary] | High |\n\n### ✅ Completed This Sprint\n[Brief list of completed sprint work]\n\n- PROJ-111: [summary]\n- PROJ-222: [summary]\n\n---\n\n## 👥 Contributing To\n\nIssues where you're listed as a contributor (owned by others):\n\n| Issue | Summary | Owner | Status | Updated |\n|-------|---------|-------|--------|---------|\n| PROJ-789 | [summary] | @owner | In Progress | Yesterday |\n\n**Action needed:** [Note any contributor items that may need your input soon]\n\n---\n\n## 📋 Backlog Highlights\n\n[Only show if relevant - keep brief]\n\n**[count] items in backlog** (not in current sprint)\n\nNotable items:\n- [Any high priority items that might need sprint inclusion]\n- [Any blocked items needing attention]\n\n---\n\n## Recommended Focus Order\n\n1. **Now:** [Most urgent sprint item]\n2. **Next:** [Second priority]\n3. **Watch:** [Contributor items that may need input]\n```\n\n## Tips for Quality Summaries\n\n**Sprint first:**\n- Always lead with sprint commitment\n- Sprint items are the primary deliverables\n- Backlog is secondary context only\n\n**Contributor awareness:**\n- Highlight contributor items that are \"In Progress\" - you may be needed\n- Note who owns each contributor issue\n- Flag if contributor items are blocked waiting on you\n\n**Keep backlog brief:**\n- Only show top 5-10 backlog items\n- Focus on items that might need sprint inclusion\n- Don't overwhelm with full backlog listing\n\n**Adapt to sprint state:**\n- Early sprint: Focus on planning and getting started\n- Mid sprint: Focus on progress and blockers\n- Late sprint: Focus on completion and carryover risk\n\n## Example Queries\n\n**All sprint issues (any status):**\n```jql\nassignee = currentUser() AND sprint in openSprints()\n```\n\n**Sprint items at risk (not started, sprint half over):**\n```jql\nassignee = currentUser() AND sprint in openSprints() AND status = \"To Do\"\n```\n\n**Contributor issues in progress:**\n```jql\n\"Contributor[User Picker (multiple users)]\" = currentUser() AND status = \"In Progress\"\n```\n\n**Contributor issues updated recently:**\n```jql\n\"Contributor[User Picker (multiple users)]\" = currentUser() AND updated >= -3d\n```\n\n**High-priority backlog (not in sprint):**\n```jql\nassignee = currentUser() AND sprint is EMPTY AND priority IN (Highest, High) AND status NOT IN (Done, Closed, Resolved)\n```\n\n**Backlog items not updated in 30 days:**\n```jql\nassignee = currentUser() AND sprint is EMPTY AND updated < -30d AND status NOT IN (Done, Closed, Resolved)\n```" + }, + { + "name": "pf-component-structure", + "plugin": "react", + "description": "Guide for PatternFly React component structure — audits, correct nesting, and layout debugging. Use when building with @patternfly/react-core or @patternfly/react-table, scanning code for hierarchy violations, or fixing spacing and alignment issues.", + "content": "---\nname: pf-component-structure\ndescription: Guide for PatternFly React component structure — audits, correct nesting, and layout debugging. Use when building with @patternfly/react-core or @patternfly/react-table, scanning code for hierarchy violations, or fixing spacing and alignment issues.\n---\n\nUse this skill when you need a **structural audit** of PatternFly usage, or when fixing layouts caused by skipped wrappers. For day-to-day composition rules while writing UI, use the **component-structure-audit** agent (react plugin) or your client’s equivalent subagent for PatternFly structure.\n\n## PatternFly MCP\n\nIf `@patternfly/patternfly-mcp` is available, use it for current props, examples, and new components. This skill and the reference files define **nesting and wrapper rules**; the MCP fills in API details.\n\n## Why structure matters\n\nLayout CSS targets specific parent-child trees. Skipping wrappers (`ToolbarContent`, `CardBody`, `PageSection`, etc.) breaks spacing and alignment; custom CSS is usually papering over a wrong tree. **Use every structural wrapper PatternFly provides for that region.**\n\n## Where the hierarchies live\n\nReference files hold trees, props notes, examples, and anti-patterns — not duplicated here:\n\n| Area | File |\n|------|------|\n| Page, PageSection, PageGroup, PageSidebar, Masthead | `references/page-layout.md` |\n| Card, Modal, Drawer, EmptyState, Sidebar | `references/containers.md` |\n| Table, DataList, DescriptionList | `references/data-components.md` |\n| Nav, Tabs, Toolbar | `references/navigation-toolbar.md` |\n\nRead the relevant file before suggesting structure for that family.\n\n## Auditing component structure\n\n### How to run\n\n1. Ask the user which directory or files to audit. Default to the current working directory.\n2. Search for files importing from `@patternfly/react-core` or `@patternfly/react-table`.\n3. For each file, check for the violations below.\n4. Report findings grouped by file, with line numbers and the specific violation.\n5. If the user requests fixes, apply them. Only fix unambiguous structural issues — if a fix would change behavior or needs a design decision, report it and ask.\n\n### Violations to detect\n\nUse the same structural rules as the **component-structure-audit** agent; during a scan, flag the issues below. **Anti-pattern examples** live in the reference files for each family.\n\n| Area | Flag |\n|------|------|\n| Page layout | Direct `` children that aren’t `` / ``; `` without ``; `` without `` (info) |\n| Masthead | `` / `` not under ``; `` outside `` |\n| Toolbar | `` children aren’t ``; controls in `` / `` without `` |\n| Card | Raw content in `` outside `` / `` / ``; expandable card missing `` |\n| Modal | Missing `` / `` / ``; missing `aria-labelledby` or `aria-label` |\n| Drawer | `` as child of `` instead of `panelContent`; `` without ``; `` not under `` in `` |\n| Navigation | `` not under ``; extra `` inside `` |\n| Table | `` direct under ``; `` / ``.\n\n**Needs user input:** New `aria-label` / `aria-labelledby` text; choosing `titleText` vs ``; unclear nested intent.\n\n### Custom CSS\n\n**During an audit:** If spacing or padding overrides sit next to a structural issue, add an info line, e.g.:\n\n```\n[INFO] file/path.tsx:42 - Custom CSS spacing override near structural violation\n .my-toolbar-fix { padding: 8px } may compensate for missing \n```\n\n**Before suggesting new overrides:** Map the symptom to a missing wrapper when possible — page content → `PageSection` / `PageBody`; toolbar → `ToolbarContent` / `ToolbarItem`; card → `CardBody`; nav → `NavList`; description list → `DescriptionListGroup`; drawer panel → `panelContent` prop (see reference files for full trees)." + }, + { + "name": "pf-import-checker", + "plugin": "react", + "description": "Audits and fixes PatternFly import paths, with emphasis on charts, chatbot, and component-groups. Use when imports fail or PatternFly modules are unresolved.", + "content": "---\nname: pf-import-checker\ndescription: Audits and fixes PatternFly import paths, with emphasis on charts, chatbot, and component-groups. Use when imports fail or PatternFly modules are unresolved.\n---\n\n# PF Import Checker\n\nFind and fix invalid PatternFly import patterns.\n\nBefore proposing import fixes, use the PatternFly MCP server to confirm current package paths and examples from the latest docs.\n\n## What to check\n\n1. Charts imported from `@patternfly/react-charts` root (invalid for Victory components).\n2. Chatbot imports not using `@patternfly/chatbot/dist/dynamic/*`.\n3. Component-group imports not using `@patternfly/react-component-groups/dist/dynamic/*`.\n4. Missing package CSS imports for features in use.\n\n## Validation commands\n\n```bash\nrg \"@patternfly/react-charts['\\\"]\" src\nrg \"@patternfly/chatbot['\\\"]\" src\nrg \"@patternfly/react-component-groups['\\\"]\" src\n```\n\n## Correct import examples\n\n```tsx\nimport { ChartDonut } from \"@patternfly/react-charts/victory\";\nimport { Chatbot } from \"@patternfly/chatbot/dist/dynamic/Chatbot\";\nimport { BulkSelect } from \"@patternfly/react-component-groups/dist/dynamic/BulkSelect\";\n```\n\n## Output format\n\nProvide:\n\n- offending file paths\n- exact import lines to replace\n- corrected import lines\n- any CSS import additions needed" + }, + { + "name": "pf-library-test-writer", + "plugin": "react", + "description": "Write unit tests for contributors to PatternFly libraries (patternfly-react, patternfly-chatbot, etc.), not for consumers of PatternFly components. Use `unit-test-generator` for consumer application tests instead.", + "content": "---\nname: pf-library-test-writer\ndescription: Write unit tests for contributors to PatternFly libraries (patternfly-react, patternfly-chatbot, etc.), not for consumers of PatternFly components. Use `unit-test-generator` for consumer application tests instead.\n---\n\nWrite unit tests for components and features within PatternFly ecosystem libraries (patternfly-react, patternfly-chatbot, patternfly-virtual-assistant, and other JS/TS-based PatternFly libraries). Unlike `unit-test-generator` which tests at the network boundary, this skill **mocks child components** for unit isolation of individual library components.\n\nThese conventions are based on the [PatternFly testing wiki](https://github.com/patternfly/patternfly-react/wiki/React-Testing-Library-Basics,-Best-Practices,-and-Guidelines).\n\n## Input\n\nThe user will provide a component file path, component code, or describe a new feature. Read the component source before writing tests.\n\n## Test File Structure\n\n```typescript\nimport { render, screen, waitFor } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport { ComponentName } from '../ComponentName';\n```\n\n## File Organization\n\n- **Separate test file per exported component.** Do not create monolithic test files.\n- Name the file `ComponentName.test.tsx` next to the source file.\n\n```text\nButton/\n├── Button.tsx\n├── Button.test.tsx\n├── ButtonVariant.tsx\n└── ButtonVariant.test.tsx\n```\n\n## Mocking Child Components\n\nDefault to **mocking child components** for unit testing prop-passing behavior:\n\n```typescript\njest.mock('../RandomHeader', () => () =>

Header text

);\n```\n\nWith props:\n\n```typescript\njest.mock('../Header', () => ({\n Header: ({ children, ...props }) =>

{children}

\n}));\n```\n\n## Test Nesting\n\n- **Do NOT** wrap all tests in a `describe()` that just names the component.\n- **Do** use `describe()` to group tests that share setup.\n- Use `test()` outside `describe()`, `it()` inside `describe()`.\n\n```typescript\ntest('renders with default props', () => { ... });\ntest('applies custom className', () => { ... });\n\ndescribe('when disabled', () => {\n it('has disabled attribute', () => { ... });\n it('does not fire onClick', () => { ... });\n});\n```\n\n## Snapshots\n\n- **DO** use snapshots for component structure and element ordering.\n- **DO NOT** use snapshots to verify CSS classes. Use `toHaveClass` instead.\n\n```typescript\n// Structure -- snapshot is appropriate\nconst { asFragment } = render();\nexpect(asFragment()).toMatchSnapshot();\n\n// Classes -- use toHaveClass, not snapshot\nexpect(screen.getByRole('button')).toHaveClass('pf-m-primary');\n```\n\n## Coverage Checklist\n\nCover these for every component:\n\n1. **Default rendering** -- renders with only required props\n2. **Prop variations** -- each prop value produces expected output\n3. **Custom className** -- merges with internal classes\n4. **Spread props** -- extra props forwarded to root element\n5. **Children** -- renders children correctly\n6. **Callbacks** -- event handlers fire with correct arguments (and don't fire when they shouldn't)\n7. **Conditional rendering** -- elements show/hide based on props\n8. **Accessibility** -- ARIA roles, labels, keyboard interaction\n9. **Snapshot** -- structure verification where appropriate (NOT for classes)\n\n## Output\n\nOutput the complete test file ready to save. Name it `ComponentName.test.tsx`." + }, + { + "name": "pf-project-scaffolder", + "plugin": "react", + "description": "Scaffolds PatternFly React projects with PF6-safe dependencies, imports, and starter layout. Use when creating a new PatternFly app or bootstrapping a migration sandbox.", + "content": "---\nname: pf-project-scaffolder\ndescription: Scaffolds PatternFly React projects with PF6-safe dependencies, imports, and starter layout. Use when creating a new PatternFly app or bootstrapping a migration sandbox.\n---\n\n# PF Project Scaffolder\n\nCreate a clean PatternFly React starting point with current conventions.\n\nUse the PatternFly MCP server as the primary source for up-to-date component APIs, usage examples, and migration-safe setup guidance.\n\n## Recommended starting point\n\nUse the official PatternFly React seed repository first when possible.\n\n```bash\ngit clone https://github.com/patternfly/patternfly-react-seed\ncd patternfly-react-seed\nnpm install\nnpm run start:dev\n```\n\n## Required dependencies\n\n```bash\nnpm install @patternfly/react-core @patternfly/react-icons @patternfly/react-table\n```\n\nFeature-based dependencies:\n\n```bash\nnpm install @patternfly/react-charts victory\nnpm install @patternfly/chatbot\nnpm install @patternfly/react-component-groups\n```\n\n## Baseline app requirements\n\n```tsx\nimport \"@patternfly/react-core/dist/styles/base.css\";\n```\n\nAdd feature CSS only when relevant:\n\n```tsx\nimport \"@patternfly/patternfly/patternfly-charts.css\";\nimport \"@patternfly/chatbot/dist/css/main.css\";\nimport \"@patternfly/react-component-groups/dist/css/main.css\";\n```\n\n## Initial quality checklist\n\n- Uses PatternFly v6 classes and semantic tokens.\n- Uses PatternFly components for layout (`PageSection`, `Stack`, `Grid`) before utility classes.\n- Handles loading, error, and empty states for data views.\n- Includes accessible names/labels for interactive controls." + }, + { + "name": "pf-unit-test-generator", + "plugin": "react", + "description": "Generate a comprehensive unit test file for a given React component", + "content": "---\nname: pf-unit-test-generator\ndescription: Generate a comprehensive unit test file for a given React component\n---\n\nGenerate a comprehensive unit test file for the given React component.\n\n## Input\n\nThe user will provide a component file path or component code. Read the component source before generating tests.\n\n## How to Generate\n\n1. Identify what the component does: rendering, user interactions, conditional states, async operations.\n2. Look up any PatternFly components used so you understand their expected props and behaviors.\n3. Generate a complete test file covering all branches.\n\n## Test File Structure\n\n```typescript\nimport { describe, expect, it, beforeEach } from \"@jest/globals\";\nimport { render, screen, waitFor } from \"@testing-library/react\";\nimport userEvent from \"@testing-library/user-event\";\n```\n\nOrganize tests into `describe` blocks: `rendering`, `user interactions`, `conditional rendering`, `async operations`, `accessibility` -- only include sections that apply.\n\n## Rules\n\n**Queries** -- use in this order:\n1. `getByRole` (always first choice)\n2. `getByLabelText`\n3. `getByText`\n4. `getByTestId` (last resort only)\n\n**Interactions** -- always `userEvent`, never `fireEvent`:\n```typescript\nconst user = userEvent.setup();\nawait user.click(screen.getByRole(\"button\", { name: \"Save\" }));\n```\n\n**Mocking** -- mock at the network boundary:\n- Mock API calls and external services\n- Never mock child components or PatternFly components\n- Place all mocks at top of file\n- `jest.clearAllMocks()` in `beforeEach`\n\n**Async** -- prefer `findBy*` over `waitFor` for waiting on elements:\n```typescript\nexpect(await screen.findByText(\"Success\")).toBeInTheDocument();\n```\n\nUse `waitFor` only for non-query assertions:\n```typescript\nawait waitFor(() => {\n expect(onComplete).toHaveBeenCalled();\n});\n```\n\n**What to test:**\n- Your application logic and component composition\n- All conditional rendering branches (loading, error, empty, populated)\n- User interactions and their effects\n- Callback invocations with correct arguments\n\n**What NOT to test:**\n- PatternFly component internals (they're already tested)\n- Implementation details (state, internal functions)\n- CSS classes or styling\n\n## Output\n\nOutput the complete test file ready to save. Name it `ComponentName.test.tsx` matching the source file." + }, + { + "name": "write-example-description", + "plugin": "react", + "description": "Helps PatternFly developers write and refine example descriptions and demo descriptions for PatternFly.org. Covers (1) component example MD files: prose under each ### heading before the ts block in packages/react-core/src/components/*/examples/*.md; (2) demo MD files: prose under ## Demos / ### Demo name in packages/react-core/src/demos. Uses PatternFly MCP for UX writing and content guidelines, suggests cross-links, and asks the user to accept or request changes. Run only when the user asks.", + "content": "---\nname: write-example-description\ndescription: >-\n Helps PatternFly developers write and refine example descriptions and demo\n descriptions for PatternFly.org. Covers (1) component example MD files: prose\n under each ### heading before the ts block in\n packages/react-core/src/components/*/examples/*.md; (2) demo MD files: prose\n under ## Demos / ### Demo name in packages/react-core/src/demos. Uses\n PatternFly MCP for UX writing and content guidelines, suggests cross-links,\n and asks the user to accept or request changes. Run only when the user asks.\n---\n\n# PatternFly example and demo descriptions\n\nUse this skill when a PatternFly developer needs to write or edit:\n\n1. **Component example descriptions** – the text under each `### Example name` (h3) and above the ` ```ts file='./ExampleName.tsx' ``` ` block in `packages/react-core/src/components/*/examples/*.md`. This content appears on the **React** tab of component pages on PatternFly.org.\n2. **Demo descriptions** – the text under each `### Demo name` in `packages/react-core/src/demos`. Demos appear as a separate **Demos** tab on the component/pattern page (alongside React examples, HTML, Design guidelines, and sometimes Accessibility).\n\nContent should be clear, on-brand, and cross-linked where helpful. For **component examples**, use a concept intro only when the example introduces **unique functionality or the primary use** of the component (e.g. Basic); for **variations and follow-on examples**, jump straight to the benefit/implementation (e.g. \"To remove the home link…\"). See \"Lead with the benefit (component examples)\" below. The skill can also be used for short intros (e.g. composable blurbs under `## Examples` or an intro under `## Demos`). **Apply this skill only when the user asks** for help writing or editing example or demo descriptions; do not invoke it proactively. After completing a request, you may offer once to check the file for other opportunities.\n\n## Who this is for\n\n- A developer who just added a new example or demo and needs a first draft of the description.\n- Anyone closing gaps where examples or demos have no description or only a heading.\n- Non-writers who want a strong first draft that can be reviewed by content design later or published as-is when time is limited.\n\n## Workflow\n\n1. **Gather context**\n - Identify the file type: **component examples** (`.../components/*/examples/*.md`) or **demos** (`.../demos/**/*.md`), and the specific example or demo (heading + ts file).\n - Read the example’s or demo’s TSX/implementation if needed to understand what it shows and which props/features are used.\n - Read any existing description and nearby examples/demos in the same MD file for tone and length.\n\n2. **Align with PatternFly content guidelines**\n - Call the **PatternFly MCP** to load current guidance:\n - Use `searchPatternFlyDocs` with `searchQuery: \"writing\"` (or `\"patternfly design guidelines\"` or `\"content design\"`) to find content design resources.\n - Use `usePatternFlyDocs` with `name: \"Writing\"` (or `\"content design\"` or the returned resource names/URLs) to fetch:\n - **Brand voice and tone** – friendly, approachable, collaborative, inventive; avoid jargon and fluff.\n - **Best practices** – clear, concise, user-focused; lead with benefit; positive, action-oriented language.\n - **PatternFly design guidelines** – present tense; second person (\"you\"); active voice; sentence-case headings; descriptive hyperlinks; relative URLs for PatternFly pages. (Note: bolding component names on first use applies to design guidelines pages, not example documentation—do not bold component names in example descriptions.)\n - **Accessibility and localization** – plain language, short sentences, consistent terminology.\n - Apply these when drafting or revising the example or demo description.\n\n3. **Draft the description**\n - **For component examples:** **When the example introduces unique functionality or the primary use** (e.g. Basic): use a **concept intro sentence** (\"A [component] gives users…\") then **technical implementation sentence(s)**. **When the example is a variation or follow-on** (e.g. \"Without home link\", \"With dropdown\"): skip the concept intro and start with the benefit/implementation—e.g. \"To remove the home link, use…\" or \"To add a dropdown to a breadcrumb item, use…\". Always lead with the benefit in the first sentence the reader sees; keep concept and implementation in separate sentences when you use a concept intro. Do **not** bold component names in example descriptions.\n - **For demos:** Use the demo-specific structure below (opening sentence + \"In this demo:\" + bullet list of props/features). Mention what the demo shows and how key props or features are used.\n - In both cases: Use \"you\" and active voice, and be direct and concise. **Punctuation:** Avoid semicolons. Prefer commas or new sentences to join ideas. Use em dashes occasionally if they improve clarity. Use backticks for prop/attribute names (e.g. `isExpanded`). **Example and demo headings (h3):** Use sentence case—only the first word and proper nouns capitalized (e.g. \"Read only\", \"Expanded with array\", \"Inline compact with truncation\"). **Component names:** Do not capitalize component names unless at the beginning of a sentence. When referring to the React component in a code way, use angle-bracket form: ``. **Only mention the React component (e.g. ``) when multiple components are involved or it helps clarify the sentence**—otherwise just \"use `propName`\" or \"set `propName`\" is enough (e.g. \"To reduce vertical spacing between rows, use `isCompact`.\" not \"set `isCompact` on ``\"). In running prose, use lowercase: \"the page component,\" \"the notification drawer.\"\n - Add **cross-links** only when **directly relevant**—e.g. when referencing a specific example of another component, or when the reader would likely want to cross-check. Generally, linking to other components or patterns mentioned in the description is usually relevant. When building component links:\n - **Nested components**: If the target component’s MD file has a `subsection` in its frontmatter, use `/components//` (e.g. Form with `subsection: forms` → `/components/forms/form`). Otherwise use `/components/` (e.g. `/components/button`, `/components/card`).\n - Use `[Component label](/components/...)` or `/components/.../design-guidelines` when pointing to design/usage.\n - **Pattern**: `[Pattern label](/patterns/pattern-name)`.\n - **Same-page example**: `[link text](#anchor)`. Anchor = heading text lowercased, spaces to hyphens (e.g. `#selectable`, `#cards-as-tiles`).\n - **Content design**: `/content-design/overview` as a generic landing, or specific paths like `/content-design/writing-guides/tooltips`. Paths here can be less consistent; use overview when unsure.\n - **Foundations and styles**: e.g. `/foundations-and-styles/iconography`, `/foundations-and-styles/design-tokens/overview`.\n - Use **relative** paths only; use descriptive link text (not \"click here\").\n\n### Lead with the benefit (component examples)\n\n**When to use a concept intro:** If the example is the **first or Basic one** and introduces what the component is, use a concept intro. Sometimes you’ll also want a concept intro for a **later example** when there are **complex implementation details** to share—that’s an option when it helps the reader.\n\n**When to skip the concept intro:** For **variations and follow-on examples** (e.g. \"Without home link\", \"With heading\", \"With dropdown\"), **jump straight to the benefit/implementation**. Start with \"To [do x], use…\" or \"To [achieve y],…\" so the reader still sees the outcome first, but don’t repeat what the component is.\n\n**When in doubt:** Prefer the shorter description and one clear benefit sentence.\n\n**With concept intro** (e.g. Basic / primary use):\n\n1. **Concept intro sentence:** What the component displays or does (e.g. \"A basic data list displays a structured set of items, each with one or more cells in a row.\" or \"A back to top component gives users a quick way to return to the top of a long page.\")\n2. **Optional component structure sentence(s):** When it helps clarify, describe the hierarchy using `` (e.g. \"A `` includes a `` containing one or more ``.\")\n3. **Technical implementation sentence(s):** How to use props or control behavior (e.g. \"In a `` you can control the layout of content by using `isFilled` and `alignRight`.\") and any real-use caveats.\n\n**Preferred example (data list Basic):**\n\n```markdown\nA basic data list displays a structured set of items, each with one or more cells in a row.\n\nA `` includes a `` containing one or more ``. In a `` you can control the layout of content by using `isFilled` and `alignRight`.\n```\n\n**Another example (back to top):**\n\n```markdown\nA back to top component gives users a quick way to return to the top of a long page. This example sets `isAlwaysVisible` so the control is visible in the short demo. In a real page, the control should appear after the user scrolls 400px.\n```\n\n**Without concept intro** (variation / follow-on): Start with \"To [benefit], use…\" and **do not name the React component unless multiple components are involved or it clarifies**. Prefer \"use `propName`\" over \"set `propName` on ``.\"\n\n```markdown\nTo reduce vertical spacing between rows, use `isCompact`.\n```\n\n```markdown\nTo remove the home link from the breadcrumb, use [prop or approach].\n```\n\nUse the same \"To [benefit], use…\" shape for variation examples; only omit the concept intro sentence so you don’t repeat the concept on every example.\n\n**Avoid / Prefer:**\n\n- **Avoid:** \"Use isCompact to reduce spacing.\" **Prefer:** \"To reduce vertical spacing between rows, use `isCompact`.\"\n- **Avoid:** \"Passing `isBordered` to an Avatar will add a border.\" **Prefer:** \"To add a border to an avatar and further separate it from the background, use `isBordered`.\"\n\n### Demo description structure\n\nFor **demos**, prefer this format so readers know what the demo shows and how it’s built:\n\n1. **Opening sentence:** Lead with what the demo shows—**vary the phrasing**. Options include a short descriptive sentence (e.g. \"A basic notification drawer opens from the masthead and displays a list of notifications.\") or user-focused (\"You can [achieve X] by [approach].\"). Avoid repeating \"This demo demonstrates\" across demos.\n2. **\"In this demo:\" or \"This demo includes:\"** followed by a bullet list. Each item can tie a prop or feature to what it does, or describe an element in the demo:\n - \"The `propName` prop is used to [effect].\" / \"A `ref`, which is passed to [thing] and used with the [component]'s `onExpand` callback to [effect].\"\n - \"[Thing] with [details], in both [state A] and [state B] states.\"\n\nExample (descriptive style):\n\n```markdown\nA basic notification drawer opens from the masthead and displays a list of notifications.\n\nThis demo includes:\n\n- A `ref`, which is passed to the notification drawer and used with the page component's `onNotificationDrawerExpand` callback to move focus into the drawer when it opens.\n- Notification items with a header and body, in both \"read\" and \"unread\" states.\n```\n\nUse lowercase for component names in prose (\"the page component\"); use `` when referring to the React component in a code way (e.g. \"pass `ref` to the `` component\").\n\nKeep bullets concise; use backticks for prop/component names. **Length:** A very simple demo may need only an opening sentence (no bullets). Other demos may have multiple sentences and lists of 5+ bullets—that’s fine. What matters is capturing the **unique aspects** of the demo, **why the demo matters**, and **what it is showing to users**. Cross-link to components or patterns when directly relevant (same rules as component examples).\n\n4. **Present and iterate**\n - **Share the suggested description in raw markdown** (e.g. in a fenced code block or clearly formatted block) so the user can easily copy and paste. Write the example description in markdown (links, backticks for props, etc.).\n - Ask the user to either:\n - **Accept** the suggestion (then insert it into the MD file), or\n - **Request changes** by saying what they don’t like (e.g. too long, wrong emphasis, different link).\n - If they request changes, revise and show again; repeat until they accept or are satisfied.\n - Optionally, once done: \"Do you want me to check this file for other opportunities?\" (e.g. other examples missing descriptions). Do not over-suggest this; ask at most once per interaction.\n\n5. **Apply the final text**\n - **Component examples:** Insert or replace the description after the `### Example name` line and before the ` ```ts file='./...' ``` ` block.\n - **Demos:** Insert or replace the description after the `### Demo name` line and before the ` ```ts file='./...' ``` ` block (demos may use `isFullscreen` on the code block).\n - **Rewriting vs updating:** If the user is **rewriting** (replacing) existing content, the new description can **override** existing content, including tables—but **make the user aware** that you removed or replaced something (e.g. \"I replaced the previous paragraph and the table with the description below.\"). If they are **updating or adding** (not doing a full rewrite), tack the new content on where appropriate; do not replace existing prose or tables unless they asked for a rewrite.\n - If the user would like content design review, suggest they tag the content designer for review (no need to add PR labels; a brief note is enough).\n\n## MD structure reference\n\n**Component examples** (`packages/react-core/src/components/*/examples/*.md`):\n\n```markdown\n### Example heading\n\n**If primary/unique (e.g. Basic):** [Concept intro: \"A [component] gives users [benefit].\"] [Technical implementation sentence(s).] **If variation/follow-on:** [Start with \"To [benefit], use…\" or \"To [do x],…\"; no concept intro.] Optional [cross-link](/components/other) if relevant.\n\n```ts file='./ExampleName.tsx'\n```\n```\n\n**Demos** (`packages/react-core/src/demos/**/*.md`):\n\n```markdown\n## Demos\n\nOptional intro paragraph under ## Demos (e.g. focus management note).\n\n### Demo heading\n\n[Varied opening: e.g. \"A basic [thing] opens from… and displays…\" or \"You can [xyz] by [abc].\"]\n\nThis demo includes:\n\n- [Bullet tying prop/feature to effect, or describing element.]\n- [Bullet…]\n\n```ts file='./examples/DemoName.tsx' isFullscreen\n```\n```\n\n- Descriptions are optional but recommended; some examples and demos have none.\n- Same-file anchors (component examples): from the exact heading text, lowercased, spaces → hyphens (e.g. \"Cards as tiles\" → `#cards-as-tiles`).\n\n## Link conventions (PatternFly.org)\n\n| Target | Path form | Example |\n|--------|-----------|--------|\n| Component (no subsection) | `/components/` | `/components/card`, `/components/button` |\n| Component (with subsection in frontmatter) | `/components//` | `/components/forms/form`, `/components/menus/menu` |\n| Component design guidelines | `/components/.../design-guidelines` | `/components/tooltip/design-guidelines` |\n| Component accessibility | `/components/.../accessibility` | `/components/alert/accessibility` |\n| Pattern | `/patterns/` | `/patterns/primary-detail` |\n| Same-page example | `#anchor` | `#selectable`, `#cards-as-tiles` |\n| Content design (generic) | `/content-design/overview` | Use when linking to content design generally |\n| Content design (specific) | `/content-design/...` | `/content-design/writing-guides/tooltips` |\n| Foundations and styles | `/foundations-and-styles/...` | `/foundations-and-styles/iconography`, `/foundations-and-styles/design-tokens/overview` |\n\nDetermine component paths by checking the target component’s MD frontmatter for `subsection` (e.g. `subsection: forms` → `/components/forms/form`). Design guidelines and some writing guides live in patternfly-org; the docs site exposes the paths above.\n\n## Quality checks\n\nBefore suggesting the description:\n\n- [ ] When in doubt, prefer the shorter description and one clear benefit sentence.\n- [ ] No semicolons in descriptions. Prefer commas or new sentences (em dashes occasionally).\n- [ ] Matches brand voice (friendly, clear, no jargon, \"you\" and active voice).\n- [ ] Example and demo headings (h3) in sentence case (first word and proper nouns only). Component names: lowercase in prose unless starting a sentence; use `` when referring to the React component as code. Do not bold component names in example or demo descriptions.\n- [ ] **Component examples:** Concept intro only for unique/primary-use examples (e.g. Basic); optional component-structure sentence using `` when it helps; variation examples start with \"To [benefit], use…\" and omit component name unless multiple or clarifying. Props in backticks.\n- [ ] **Demos:** Varied opening; \"In this demo:\" or \"This demo includes:\" with bullet list of props/features and what they do.\n- [ ] Cross-links only where directly relevant; use subsection for nested components.\n- [ ] Relative URLs only; descriptive link text.\n- [ ] Suggested text shared in raw markdown so the user can copy and paste.\n\n## Optional: when the user hasn’t specified a file or example\n\nIf the user asks for help with \"example descriptions\" or \"demo descriptions\" but doesn’t point to a file or example:\n\n- Ask which file they want to work on (component examples path or demos path) and which example or demo (heading or ts file name).\n- Optionally list examples or demos in that file that are missing descriptions so they can choose." + }, + { + "name": "analytics-repo-pruning", + "plugin": "repo-management", + "description": "Flags archived or inactive Git repositories listed in PatternFly Analytics repos.json so entries can be pruned. Use when reviewing repos.json, auditing tracked codebases, or removing stale or archived repos from analytics.", + "content": "---\nname: analytics-repo-pruning\ndescription: Flags archived or inactive Git repositories listed in PatternFly Analytics repos.json so entries can be pruned. Use when reviewing repos.json, auditing tracked codebases, or removing stale or archived repos from analytics.\n---\n\n# Analytics repo pruning\n\nKeep PatternFly Analytics from tracking **archived** repositories and repos with **no meaningful code activity** past a configurable threshold (default **730 days**).\n\n## Plugin placement\n\nThis skill lives under **repo-management** as **cross-repo / analytics inventory** work (repository health and maintenance).\n\n## Input\n\n- **File:** `repos.json` (project root or path the user supplies). Expect a top-level `repos` array; each entry has `git` (clone URL) and `name` (display label).\n\n## Outcomes\n\nFor every row, assign one bucket:\n\n| Bucket | Meaning |\n|--------|---------|\n| **archived** | Host marks the project archived / read-only |\n| **stale** | Last code activity is before the cutoff |\n| **could not verify** | Auth failure, network, or unsupported host—**not** the same as stale |\n| **active** | Neither archived nor stale |\n\nUse the host’s best signal for **real code activity** (e.g. last push to the default branch), not noisy metadata-only updates. Field names and API notes: [reference.md](reference.md).\n\n## How to work\n\n1. Read `repos.json` and collect all `git` URLs with their `name`.\n2. For each URL, determine host (**GitHub**, **GitLab** including private instances, or other).\n3. Query the host using **whatever authenticated access the user’s environment already provides** (host CLI, REST with tokens, etc.). Prefer a deterministic per-repo lookup; if one path fails, try another before giving up.\n4. Do **not** treat auth or network failures as “stale”—bucket those as **could not verify** with a short reason.\n5. Produce the report below. **Do not** remove or edit `repos.json` entries unless the user explicitly asks.\n\n## Edge cases\n\n- **404 / moved / renamed:** Flag for manual verification; do not assume delete.\n- **Forks and mirrors:** Same rules; stale mirrors may still be poor analytics targets.\n- **Unknown hosts:** **could not verify** with explanation—not stale.\n\n## Optional script\n\nFor a repeatable local run, execute the bundled **Bash** script `scripts/analytics-repo-pruning.sh` next to this skill. Requires `jq` and either `gh` or `curl` (typically pre-installed). Pass the path to `repos.json`; optional `--days ` and `--json`. Does not modify `repos.json`.\n\n## Report format\n\nUse markdown with:\n\n1. **Threshold** (days) and **run date**\n2. **Archived** — table: name, git, notes\n3. **Stale** — table: name, git, last activity (and which field was used)\n4. **Could not verify** — table: name, git, reason\n5. **Active** — brief count or one-line summary\n\n**Good output:** Clear buckets, honest “unknown,” timestamps tied to named fields, no silent edits to the JSON file.\n\n**Bad output:** Calling repos stale because API calls failed, or pruning the list without explicit user consent.\n\n## Additional resources\n\n- [reference.md](reference.md) — host APIs, fields, encoding, and CLI patterns" + }, + { + "name": "dependency-recommender", + "plugin": "repo-management", + "description": "Analyzes the project's manifests and code patterns, then recommends NPM or other dependencies that would reduce complexity, increase stability, and improve reusability—with a short rationale per recommendation.", + "content": "---\nname: dependency-recommender\ndescription: Analyzes the project's manifests and code patterns, then recommends NPM or other dependencies that would reduce complexity, increase stability, and improve reusability—with a short rationale per recommendation.\ndisable-model-invocation: true\n---\n\n# Dependency Recommender\n\nRecommend dependencies that would help this project reduce complexity, increase stability, and improve reusability. Output a structured list with a clear rationale for each recommendation.\n\n## When to use\n\nInvoke this skill when the user asks for dependency recommendations, library suggestions, \"what packages could help this project\", or tech-stack / dependency review.\n\n## Instructions\n\n1. **Gather context**\n - Read root and workspace package manifests (`package.json`, `package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, or `requirements.txt`, `Cargo.toml`, etc.).\n - Optionally scan source for patterns: manual date handling, custom validators, repeated HTTP/API logic, ad-hoc state, duplicated utilities. Use this to tailor recommendations.\n\n2. **Apply dependency knowledge**\n - Consider widely adopted, well-maintained packages in the project's ecosystem(s).\n - Map common problems (validation, dates, errors, HTTP, state, testing, formatting) to standard solutions.\n - Respect existing stack (e.g. don't suggest a different test runner if one is already standard). Note version/compatibility when relevant.\n\n3. **Produce the output** using the format below. Every recommendation must have a project-specific \"Why here\" reason—no generic \"you could use X\" without tying it to this codebase.\n\n## Output format\n\nUse this structure. Group by category (e.g. Validation, Date/time, Testing) when it helps. Omit categories that have no recommendations.\n\n```markdown\n## Dependency recommendations for [project or repo name]\n\n### [Category name]\n- **[package name]** ([ecosystem], e.g. NPM) – [One-line: what it does.]\n - **Why here:** [Project-specific reason: what in this codebase it would replace, simplify, or improve.]\n - **Note:** [Optional: caveats, integration with existing deps, bundle size, compatibility.]\n```\n\nKeep each recommendation concise. Prefer a short, actionable list over long prose.\n\n## Scope\n\n- **In scope:** Recommendations with rationale; grouping by category; multiple ecosystems; project-aware reasons.\n- **Out of scope:** Do not modify lockfiles or install packages; do not run security/CVE scans. Focus on analysis and recommendations only." + }, + { + "name": "pf-org-version-update", + "plugin": "repo-management", + "description": "Updates the patternfly-org repo for a new PatternFly release or release candidate. Fetches or applies specified versions, updates package.json files and versions.json, and then provides the user with steps to run the build and regenerate screenshots locally. Use when preparing a PatternFly release, updating PF versions in this repo, or when the user asks to update patternfly-org for a new release.", + "content": "---\nname: pf-org-version-update\ndescription: Updates the patternfly-org repo for a new PatternFly release or release candidate. Fetches or applies specified versions, updates package.json files and versions.json, and then provides the user with steps to run the build and regenerate screenshots locally. Use when preparing a PatternFly release, updating PF versions in this repo, or when the user asks to update patternfly-org for a new release.\n---\n\n# PatternFly Org Version Update\n\nUpdates patternfly-org for a new PatternFly release or release candidate: resolve versions, update all package.json and versions.json, then provide the user with steps to run install, build, and optionally update documentation screenshots locally.\n\n## 1. Resolve Versions\n\n**If the user provided specific versions** (e.g. in the command or message): use those versions. Do **not** run `latest-versions.sh`.\n\n**If no versions were specified**: run from repo root:\n\n```bash\n./scripts/latest-versions.sh -e\n```\n\nThe `-e` flag includes extension packages. Output is one line per package in the form:\n\n```\n\"@patternfly/package-name\": \"X.Y.Z\",\n```\n\nParse this output to build the set of package versions. Use these as the source of truth for the rest of the workflow.\n\n## 2. Update package.json Files\n\nUpdate PatternFly dependencies only in these locations. **Do not** modify `packages/site/package.json` or any other package.json not listed here.\n\n### Root `package.json`\n\nIn `devDependencies` and `resolutions`, update every `@patternfly/*` entry with the resolved versions. Only change PatternFly packages; leave other dependencies unchanged.\n\n### `packages/documentation-site/package.json`\n\nIn `dependencies`, update every `@patternfly/*` entry with the resolved versions. Only change PatternFly packages; leave other dependencies unchanged.\n\n### `packages/documentation-framework/package.json`\n\nIn `peerDependencies`, update every `@patternfly/*` entry with the resolved versions. Only change PatternFly packages; leave other dependencies unchanged.\n\n## 3. Update versions.json\n\nFile: `packages/documentation-framework/versions.json`.\n\n### 3.1 New release object\n\nInsert a **new** object at the **start** of the `\"Releases\"` array with:\n\n- **`\"name\"`**: version from `@patternfly/react-core` (e.g. `\"6.3.0\"` or `\"6.5.0-prerelease.33\"`).\n- **`\"date\"`**: current date in `YYYY-MM-DD`.\n- **`\"latest\"`**: `true`.\n- **`\"versions\"`**: object with **all** PatternFly packages and their versions. Use the resolved version set; for any package not in that set, copy the version from the current \"latest\" release so the list stays complete and consistent.\n\n### 3.2 Previous latest release\n\nFind the release that currently has `\"latest\": true`. Change it to `\"hidden\": true` (remove `\"latest\": true`). Do not change anything else in that entry.\n\n### 3.3 Validation\n\n- Exactly one release has `\"latest\": true`.\n- All others have `\"hidden\": true`.\n- New release is first in the array.\n- Every release’s `versions` object includes the same package keys (alphabetical order); only version values change.\n\n### 3.4 versions object package list\n\nEach release’s `versions` must include these packages (alphabetical order):\n\n- `@patternfly/chatbot`\n- `@patternfly/patternfly`\n- `@patternfly/quickstarts`\n- `@patternfly/react-catalog-view-extension`\n- `@patternfly/react-charts`\n- `@patternfly/react-code-editor`\n- `@patternfly/react-component-groups`\n- `@patternfly/react-console`\n- `@patternfly/react-core`\n- `@patternfly/react-data-view`\n- `@patternfly/react-drag-drop`\n- `@patternfly/react-icons`\n- `@patternfly/react-log-viewer`\n- `@patternfly/react-styles`\n- `@patternfly/react-table`\n- `@patternfly/react-tokens`\n- `@patternfly/react-templates`\n- `@patternfly/react-topology`\n- `@patternfly/react-user-feedback`\n- `@patternfly/react-virtualized-extension`\n\nNew release object shape:\n\n```json\n{\n \"name\": \"X.Y.Z\",\n \"date\": \"YYYY-MM-DD\",\n \"latest\": true,\n \"versions\": {\n \"@patternfly/chatbot\": \"...\",\n \"@patternfly/patternfly\": \"...\",\n \"@patternfly/react-*\": \"...\",\n \"... (all packages above, alphabetically)\"\n }\n}\n```\n\n### 3.5 Conventions\n\n- Release name = `@patternfly/react-core` version.\n- Use current date for new releases.\n- Some packages (e.g. react-charts, chatbot) may use different version numbers; use the resolved or existing latest value for those.\n\n## 4. Verification Checklist\n\nBefore proceeding:\n\n- [ ] Root package.json devDependencies (all @patternfly/\\* entries) updated\n- [ ] documentation-site package.json dependencies (all @patternfly/\\* entries) updated\n- [ ] documentation-framework package.json peerDependencies (all @patternfly/\\* entries) updated\n- [ ] packages/site/package.json was **not** modified\n- [ ] New release added at top of versions.json Releases array with `\"latest\": true`\n- [ ] Previous latest now has `\"hidden\": true`\n- [ ] Only one object has `\"latest\": true`\n- [ ] Version numbers consistent across root, documentation-site, documentation-framework, and versions.json\n\n## 5. Build and Screenshots (user-run only)\n\nThe agent **does not** run `yarn install`, `yarn build`, `yarn serve`, or `yarn screenshots` (sandbox limits: cache/lockfile, long build, Puppeteer/Chrome). After completing steps 1–4, give the user the following instructions to run locally from the repo root for the purpose of updating documentation screenshots.\n\n1. **Install**\n\n ```bash\n yarn install\n ```\n\n2. **Build**\n\n ```bash\n yarn build\n ```\n\n3. **Serve** — in a terminal, start the server and leave it running:\n\n ```bash\n yarn serve\n ```\n\n Wait until the docs are being served (e.g. \"Serving build/patternfly-org/site at...\" or similar).\n\n4. **Screenshots** — in a second terminal:\n\n ```bash\n yarn screenshots\n ```\n\n Run to completion.\n\n5. When `yarn screenshots` has finished, stop the serve process.\n\nAfter providing the user with the steps to update screenshots, the skill is done.\n\n## Summary\n\n| Step | Action |\n| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Versions | User-provided → use as-is. Otherwise run `./scripts/latest-versions.sh -e` and parse output. |\n| package.json | Update root, documentation-site, and documentation-framework: every @patternfly/\\* entry with resolved versions; only change PF packages. Never change packages/site. |\n| versions.json | Add new release at top with `latest: true`, set previous latest to `hidden: true`, same package list everywhere. |\n| Build / Screenshots | Do **not** run install, build, serve, or screenshots. Give user the full list of steps: `yarn install`, `yarn build`, `yarn serve` (one terminal), `yarn screenshots` (second terminal). |" + }, + { + "name": "semantic-release-troubleshooting", + "plugin": "repo-management", + "description": "Diagnose and fix semantic-release issues when a specific version is not being released. Use when semantic-release skips a version, fails to release, or when troubleshooting after git push --force, squashed commits, permission errors, or reference already exists.", + "content": "---\nname: semantic-release-troubleshooting\ndescription: >-\n Diagnose and fix semantic-release issues when a specific version is not being\n released. Use when semantic-release skips a version, fails to release, or when\n troubleshooting after git push --force, squashed commits, permission errors,\n or reference already exists.\ndisable-model-invocation: true\n---\n\n# semantic-release Troubleshooting\n\nWhen a specific version is not being released, follow this diagnostic workflow.\n\n## 1. Identify the Problem\n\nDetermine which scenario matches:\n\n| Symptom | Section |\n|---------|---------|\n| `You do not have permission to publish` (403) | → [Permission error](#permission-error) |\n| Release skipped; commits not counted | → [Squashed commits](#squashed-commits) |\n| `reference already exists` when pushing tag | → [Tag conflict](#tag-conflict) |\n| Release not found after `git push --force` | → [History rewrite recovery](#history-rewrite-recovery) |\n\n## 2. Permission Error\n\n**Cause:** npm registry auth or package name/ownership issues.\n\n**Diagnosis:** Verify package name availability on the npm registry.\n\n**Fix:** If the package name is taken, update `package.json` with a different name or use an [npm scope](https://docs.npmjs.com/cli/v11/using-npm/scope/). Ensure proper [npm registry authentication](https://github.com/semantic-release/npm#npm-registry-authentication) and confirm the user has [publish permissions](https://docs.npmjs.com/cli/v8/commands/npm-team/).\n\n## 3. Squashed Commits\n\n**Cause:** semantic-release uses [commit message convention](https://github.com/semantic-release/semantic-release#commit-message-format). Squashed commits often get non-compliant messages and are ignored.\n\n**Diagnosis:** Check that commit messages follow conventional commit format.\n\n**Fix:** Ensure commit messages follow the semantic-release convention with proper prefixes (`feat:`, `fix:`, `fix!:`, `BREAKING CHANGE:`). Each squashed commit should represent one logical change; avoid combining unrelated features. Rewrite non-compliant commit messages to match the required format.\n\n## 4. Tag Conflict (`reference already exists`)\n\n**Cause:** A tag with the target version exists but is not in the current branch's history.\n\n**Diagnosis:** Confirm whether the tag exists and identify which branches contain it.\n\n**Fix:**\n- If the release was published: Merge the commits from that release into your release branch.\n- If no published release: Delete the conflicting tag locally and from the remote repository.\n\n## 5. History Rewrite Recovery (after `git push --force`)\n\n**Cause:** `git push --force` rewrites history; tags and git notes tied to old commits become invalid.\n\n**Diagnosis:** Identify orphaned tags and notes that point to old (rewritten) commits.\n\n**Fix:** Recover in this order:\n1. Delete orphaned tags from both remote and local repositories\n2. Re-create tags pointing to the corresponding new commits\n3. Re-create git notes for each tag with appropriate channel configuration (e.g., `{\"channels\":[\"beta\"]}` for beta channel only, or `{\"channels\":[null,\"beta\"]}` for both default and beta channels)\n4. Force push the updated notes to the remote repository\n\n## Reference\n\nFull documentation: [semantic-release Troubleshooting](https://semantic-release.gitbook.io/semantic-release/support/troubleshooting)" + }, + { + "name": "summarize-pr-reviews", + "plugin": "repo-management", + "description": "\"Summarize GitHub pull requests awaiting review from the current user. Use when the user asks to: (1) See their pending PR reviews, (2) Summarize PRs they need to review, (3) Get an overview of review requests, (4) Prioritize their code review queue, or (5) Understand what PRs are waiting for their review.\"", + "content": "---\nname: summarize-pr-reviews\ndescription: \"Summarize GitHub pull requests awaiting review from the current user. Use when the user asks to: (1) See their pending PR reviews, (2) Summarize PRs they need to review, (3) Get an overview of review requests, (4) Prioritize their code review queue, or (5) Understand what PRs are waiting for their review.\"\n---\n\n# Summarize My PR Review Queue\n\nFetch all GitHub pull requests where the current user is requested as a reviewer, summarize the changes, and provide prioritization recommendations.\n\n## Workflow\n\n1. **Get user identity** - Identify the current GitHub user\n2. **Search for review requests** - Query GitHub for PRs requesting the user's review\n3. **Fetch PR details** - Get diff stats, reviews, CI status, and context for each PR\n4. **Analyze and categorize** - Size, priority, and complexity assessment\n5. **Generate summary** - Present a clear overview with prioritization recommendations\n\n## Step 1: Get User Identity\n\nIdentify the authenticated GitHub user's login.\n\n## Step 2: Search for PRs Requesting Review\n\nSearch for open PRs where the user is requested as a reviewer, sorted by most recently updated. Run both queries in parallel:\n\n- **Primary:** Open PRs awaiting your review\n- **Secondary:** Open PRs you've already reviewed but haven't approved (may have new changes)\n\nIf the user asks about a specific org or repo, scope the search accordingly.\n\n## Step 3: Fetch PR Details\n\nFor each PR found, fetch in parallel: metadata (title, author, labels, created date), files changed (count, lines added/deleted, key paths), existing reviews and their states, and CI/check status.\n\nExtract from each PR:\n- Title and description\n- Author\n- Number of files changed, lines added/deleted\n- Labels (especially priority, urgent, blocker, critical)\n- How long it's been open\n- CI/check status (passing, failing, pending)\n- Existing reviews and their states (approved, changes requested, commented)\n\n## Step 4: Analyze and Categorize\n\n### Size Categories\n\n| Size | Criteria | Review Time Estimate |\n|------|----------|---------------------|\n| 🟢 **Small** | <100 lines changed, <5 files | ~10-15 min |\n| 🟡 **Medium** | 100-500 lines, 5-15 files | ~30-60 min |\n| 🔴 **Large** | >500 lines or >15 files | 1+ hours |\n\n### Priority Signals\n\nFlag PRs as high-priority when:\n- Labeled `priority`, `urgent`, `blocker`, or `critical`\n- Open >3 days without any review\n- Author has pinged or requested re-review\n- Blocking other work (mentioned in description)\n- Failing CI that needs investigation\n- Security fix or hotfix\n\n### Complexity Indicators\n\nNote when PRs involve:\n- Multiple reviewers requested\n- Files spread across different areas of the codebase\n- New dependencies added\n- Database migrations or API changes\n- Configuration or infrastructure changes\n\n## Step 5: Generate Summary\n\nStructure the output in this order. Adapt detail level to queue size: full detail for <5 PRs, grouped summaries for 5-15, top priorities only for >15.\n\n### At a Glance\n\nOpen with a quick snapshot:\n- Total PRs awaiting review\n- Breakdown by size (small / medium / large)\n- Oldest PR waiting\n\n### Priority Reviews (Address First)\n\nTable of PRs that are urgent, stale (>3 days without review), security/hotfix, or blocking others. Include a \"Why Priority\" column.\n\nFor each priority PR, provide a detail block:\n- **Repository** and **Author**\n- **Changes:** `+X/-Y` lines across N files\n- **Summary of Changes:** Brief description from title, description, and files changed\n- **Key files to review:** Top 2-3 files with brief explanation\n- **Review notes:** CI failures, existing review comments, blockers\n\n### Standard Reviews\n\nRemaining PRs in suggested review order. Table with PR number, repository, author, size, wait time, and notes. Detail blocks for each.\n\n### Quick Reviews (Small PRs)\n\nCompact table of small PRs that can be knocked out quickly — good for short time blocks.\n\n### Needs Attention\n\nFlag concerning patterns:\n- **Stale PRs:** Open >7 days without review\n- **Failed CI:** PRs with failing checks\n- **Re-review requested:** PRs you reviewed but have new commits\n\n### Suggested Review Order\n\nNumbered list combining priority, size, and wait time into a recommended sequence. End with an estimated total review time.\n\n## Tips for Quality Summaries\n\n**Understand the changes:**\n- Read the PR description carefully\n- Look at file types changed to understand scope\n- Note if tests are included\n\n**Identify what matters:**\n- Focus on the \"why\" not just the \"what\"\n- Highlight breaking changes or API modifications\n- Note new dependencies or configuration changes\n\n**Make it actionable:**\n- Suggest a specific review order\n- Estimate review time for planning\n- Flag PRs that can be quick wins\n\n**Provide context:**\n- Link directly to each PR with full URL\n- Show how long PRs have been waiting\n- Note if CI is passing/failing\n\n**Adapt to queue size:**\n- For <5 PRs: Detailed summary of each\n- For 5-15 PRs: Group by priority, summarize key points\n- For >15 PRs: Focus on top priorities, list others briefly" + } + ] +} diff --git a/scripts/generate-skills-json.sh b/scripts/generate-skills-json.sh new file mode 100755 index 0000000..6283d32 --- /dev/null +++ b/scripts/generate-skills-json.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +# Generates dist/skills.json from all SKILL.md files across plugins. +# Output format matches the schema expected by patternfly-mcp's aiHelpers.skills.ts. + +set -euo pipefail +cd "$(git rev-parse --show-toplevel)" + +OUTPUT="dist/skills.json" +mkdir -p "$(dirname "$OUTPUT")" + +get_frontmatter_field() { + local file="$1" + local field="$2" + local frontmatter value + + frontmatter=$(sed -n '/^---$/,/^---$/p' "$file") + value=$(echo "$frontmatter" | grep "^${field}:" | sed "s/^${field}: *//") + + if [ "$value" = ">-" ] || [ "$value" = ">" ] || [ "$value" = "|" ] || [ "$value" = "|-" ]; then + value=$(echo "$frontmatter" | sed -n "/^${field}:/,/^[a-zA-Z_-]*:\|^---$/{ /^${field}:/d; /^[a-zA-Z_-]*:/d; /^---$/d; p; }" | sed 's/^ *//' | tr '\n' ' ' | sed 's/ *$//') + fi + + echo "$value" +} + +count=0 +first=true + +{ + printf '{\n "version": "1",\n "generated": "%s",\n "meta": {\n "source": "patternfly/ai-helpers"\n },\n "skills": [\n' "$(date -u +%Y-%m-%dT%H:%M:%S.000Z)" + + for plugin_dir in plugins/*/; do + plugin=$(basename "$plugin_dir") + [ -d "${plugin_dir}skills" ] || continue + + for skill_dir in "${plugin_dir}skills"/*/; do + [ -d "$skill_dir" ] || continue + skill_file="${skill_dir}SKILL.md" + [ -f "$skill_file" ] || continue + + name=$(get_frontmatter_field "$skill_file" "name") + description=$(get_frontmatter_field "$skill_file" "description") + content=$(cat "$skill_file") + + [ -z "$name" ] && name=$(basename "$skill_dir") + + if [ "$first" = true ]; then + first=false + else + printf ',\n' + fi + + jq -n \ + --arg name "$name" \ + --arg plugin "$plugin" \ + --arg description "$description" \ + --arg content "$content" \ + '{ name: $name, plugin: $plugin, description: $description, content: $content }' \ + | sed 's/^/ /' + + count=$((count + 1)) + done + done + + printf '\n ]\n}\n' +} > "$OUTPUT" + +# Patch totalSkills into meta +jq --argjson total "$count" '.meta.totalSkills = $total' "$OUTPUT" > "${OUTPUT}.tmp" && mv "${OUTPUT}.tmp" "$OUTPUT" + +echo "Generated $OUTPUT ($count skills)"
` in body rows or `` in header rows; `` without `dataLabel` (**WARN**) |\n| DataList | Missing `aria-label` on ``; item without ``; row without ``; `` inside `` (should be sibling) |\n| Tabs | Tab label as children instead of `title`; `` without `eventKey` |\n| EmptyState | `` directly under ``; mixing `titleText`/`icon` with explicit `` |\n| DescriptionList | Terms/descriptions directly under `` without `` |\n\n### Report format\n\nFor each violation:\n\n```\n[ERROR|WARN] file/path.tsx:42 - has direct children that are not \n Found: