Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/skills/curate-carbon-component/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
name: curate-carbon-component
description: Curate or review one Carbon React component's authored skill metadata and agent-facing Storybook examples. Use when extending component skill coverage or changing docs/component-metadata; do not use for ordinary component implementation alone.
---

# Curate a Carbon component

Read `docs/component-metadata/README.md` before making changes. It defines the
source-of-truth split, metadata fields, example criteria, and completion checks.

Keep the task to one active component unless the user requests a wider scope. If
a component has not been chosen, run `npm run skills:status` and select from the
active components awaiting review; do not spend coverage effort on deprecated
components unless migration guidance is specifically needed.

Inspect the component source, its Storybook stories and MDX, and its current
generated component file before authoring metadata. Treat Carbon source and
Storybook as the primary developer-facing sources. Fusion guidance may provide
useful supplementary design context when available, but it is not a prerequisite
and must not override Carbon's documented behaviour. Do not infer product
guidance from prop names or component behaviour. Add only guidance that changes
an agent's decisions. Omit optional fields instead of repeating the summary or
filling a template.

Keep capability and design decisions separate. Explain what props and visual
variants enable, plus any technical constraints, without prescribing when a
designer should choose them. Prescriptive guidance belongs here only when it is
needed for component selection, accessibility, implementation correctness, or a
documented Carbon requirement.

Curate a small set of focused, consumer-useful stories. Do not curate playground
stories or examples using deprecated APIs. Preserve the Storybook patterns the
project wants to use; improve the extractor or source story when necessary
rather than rewriting stories merely for extraction. If a selected example is
incomplete or inaccessible, correct the source story so Storybook and the skill
remain aligned.

Never edit `skills/carbon-react/` directly. Run `npm run build:skills`, inspect
the generated component and every linked example, then run:

```shell
npm run test:skills
npm run build:skills -- --check
npm run type-check
```

Finish only when the generated guidance is concise, imports and props are
current, deprecations are represented accurately, examples are understandable
without Storybook context, and the checks pass.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ jobs:
- name: Ensure the Carbon skills are up to date (run npm run build:skills locally to fix this error)
run: npm run build:skills -- --check

- name: Test the Carbon skill metadata validation
run: npm run test:skills

test:
name: Test with Node ${{ matrix.node }} (${{ matrix.shard }}, 4)
runs-on: ubuntu-latest
Expand Down
17 changes: 13 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,25 @@ More details about how we test can be found in our [Testing Guide](contributing/

## Keeping skills up to date

Updating skills is a required part of the contribution process. When making changes that affect a component's API, props, behaviour, usage patterns or documentation the corresponding skill file(s) in `skills/` **must** be updated to reflect those changes.
Files in `skills/carbon-react/` are generated and must not be edited directly. When making changes that affect a component's API, props, behaviour, usage patterns or documentation, regenerate them with:

Failure to keep skills in sync with the codebase will result in a **lint failure**, blocking your pull request from being merged.
```shell
npm run build:skills
```

To add authored component guidance or curate Storybook examples for agent use, follow the [component skill metadata guide](docs/component-metadata/README.md). Add only information that changes an agent's decisions; source-derived API details remain owned by the component code.

When updating a component, update its skills file alongside your code changes in the same pull request. In many cases, running the build command will automatically generate the required skill changes for you:
Copilot users can ask the agent to use the `curate-carbon-component` skill for this workflow.

Before raising a pull request, run:

```shell
npm run build:skills
npm run test:skills
npm run build:skills -- --check
```

CI runs both commands and fails if metadata is invalid or generated files have drifted.

## Bugs

### Where to find known issues
Expand Down
85 changes: 85 additions & 0 deletions docs/component-metadata/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Component skill metadata

This directory contains the human-authored part of the Carbon React skill. One
JSON file represents one component that has been reviewed for agent use. The
absence of a file means that the component still uses source-generated API data
and uncurated Storybook examples; it does not mean that placeholder guidance
should be added.

## Sources of truth

| Information | Source |
| ---------------------------------------------------------------- | ------------------------------------------------------ |
| Public exports, imports, props, types, defaults and deprecations | Component source, read by the generator |
| Developer usage guidance | Carbon Storybook MDX and stories |
| Supplementary design context | Fusion guidance, when available and relevant |
| Curated decision guidance, pitfalls and example selection | `docs/component-metadata/<component>.json` |
| Runnable example implementation | The selected Storybook story |
| Agent-facing Markdown | `skills/carbon-react/`, generated; never edit directly |

This split keeps facts that can silently drift tied to code while allowing
maintainers to author product guidance that cannot be inferred reliably.

## Add or review a component

1. Create a kebab-case JSON file matching the generated component name. Use
`pill.json` as the structural example, but assess the component independently.
2. Inspect Carbon's Storybook MDX and stories as the primary developer guidance.
Consult Fusion for supplementary design context when it is available and
relevant, but do not make curation depend on access to it or let it override
Carbon's documented behaviour.
3. Write a concise `summary` that distinguishes the component. Add optional
sections only when they change an agent's decision; do not repeat the summary
in `useWhen` or add text merely to fill a section.
4. Describe what props and visual variants enable without deciding when a
designer should choose them. Include prescriptive guidance only for component
selection, accessibility, implementation correctness, or an explicit Carbon
requirement.
5. Select only stories that demonstrate useful consumer behaviour. Playground
stories are interactive documentation and should not be curated by default.
A selected story must resolve to public consumer imports after generation,
avoid deprecated APIs, and produce a focused example that makes sense outside
Storybook.
6. Improve the source story when the example itself is incomplete, inaccessible,
or uses an obsolete pattern. Do not compensate by hand-editing generated
Markdown.
7. Run `npm run build:skills`, then review the component entry and every generated
example as an agent-facing consumer would.

Supported fields:

| Field | Required | Purpose |
| -------------- | -------- | --------------------------------------------------------------------- |
| `component` | Yes | Exact generated component name, such as `Pill` or `ButtonNext`. |
| `summary` | Yes | One sentence explaining the component's distinct purpose. |
| `useWhen` | No | Situations not already obvious from the summary. |
| `avoidWhen` | No | Important boundaries that are clearer without naming one alternative. |
| `alternatives` | No | A non-deprecated Carbon component and when to choose it instead. |
| `pitfalls` | No | Non-obvious accessibility, composition or implementation risks. |
| `examples` | No | Story export names and descriptions explaining why each is useful. |

Omit an optional field when there is no useful content. If supplied, list fields
must be non-empty. The generator rejects unknown fields, invalid component or
story references, deprecated alternatives, deprecated APIs in curated examples,
and curated examples that retain source-relative imports.

## Completion checklist

- The metadata adds decision-making value and contains no duplicated filler.
- Guidance is grounded in Carbon documentation and behaviour rather than
inferred from the component name or API shape.
- Visual variant guidance explains capability without making contextual design
decisions for the consumer.
- Alternatives and selected stories use current, public APIs.
- Curated examples are focused, accessible, syntactically valid, and readable
without interpreting Storybook composition.
- The generated component file has accurate imports, props, defaults and
deprecation details.
- `npm run test:skills`, `npm run build:skills -- --check`, and
`npm run type-check` pass.

Run `npm run skills:status` to list reviewed components and those still awaiting
authored metadata. Deprecated components are reported separately and do not need
authored metadata unless useful migration guidance is missing. Coverage is
intentionally incremental; CI checks correctness and generated-file drift rather
than requiring filler for every component.
34 changes: 34 additions & 0 deletions docs/component-metadata/pill.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"component": "Pill",
"summary": "A compact visual indicator that highlights information or status.",
"useWhen": [
"An item's status needs to be prominent at a glance; this is Pill's primary use.",
"A short label helps categorise an item; this is secondary to communicating status."
],
"alternatives": [
{
"component": "ButtonNext",
"when": "The element's primary purpose is to perform an action rather than display information or status."
}
],
"pitfalls": [
"Give a removable pill a clear, unique accessible label that describes the relationship between the pill and its removal button.",
"Use a left icon only with size L.",
"Keep the Pill itself out of the tab order; only its removal button should receive keyboard focus.",
"Add visually hidden context when the pill's meaning is not clear from its visible label and surroundings."
],
"examples": [
{
"story": "Wrapped",
"description": "Allow an unusually long label to wrap within a constrained width."
},
{
"story": "WithRemoveButton",
"description": "Make a pill removable with onDelete and give its removal button a clear, contextual accessible label."
},
{
"story": "InverseOnDarkBackground",
"description": "Apply inverse styling to a pill."
}
]
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
"build:generate-package-json-files": "node ./scripts/generate_package_json_files/index.js",
"build:move-svg": "node ./scripts/copy_svg/index.js",
"build:skills": "node ./scripts/skills/build_skills.mjs",
"skills:status": "node ./scripts/skills/build_skills.mjs --metadata-status",
"test:skills": "node --test ./scripts/skills/*.test.mjs",
"generate-tokens": "rimraf ./src/components/tokens-wrapper/static-tokens && node ./scripts/generate_tokens/generate_tokens.mjs --include-dark"
},
"repository": {
Expand Down
Loading
Loading