Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b5b3a2a
chore(plugin): add the koobiq-react Claude Code marketplace
lskramarov Oct 1, 2026
a2ec5be
feat(plugin): add koobiq-check, a deterministic Koobiq checker for pr…
lskramarov Oct 1, 2026
01b6032
test(plugin): add stub Koobiq packages for koobiq-check tests
lskramarov Oct 1, 2026
e6921c6
test(plugin): cover koobiq-check with fixture apps
lskramarov Oct 1, 2026
b415839
fix(plugin): treat documented react-core hooks and primitives as public
lskramarov Oct 1, 2026
57dd59d
feat(plugin): add the Koobiq reviewer agent and /koobiq:review
lskramarov Oct 1, 2026
1479e11
feat(plugin): add /koobiq:init for agent instructions in products
lskramarov Oct 1, 2026
6116181
feat(plugin): add the Koobiq ESLint/Stylelint preset and /koobiq:setu…
lskramarov Oct 1, 2026
dd67e60
feat(plugin): add /koobiq:upgrade
lskramarov Oct 1, 2026
6af859b
feat(plugin): resolve local barrels and add the --typecheck tier
lskramarov Oct 1, 2026
38b70a5
docs(plugin): document the Claude Code plugin
lskramarov Oct 1, 2026
7f95fe7
chore(ci): run the Claude Code plugin tests
lskramarov Oct 1, 2026
502223b
feat(plugin): add the JSON Schema of the koobiq-check report
lskramarov Oct 1, 2026
351f6b2
feat(plugin): version the plugin on its own and check bumps in CI
lskramarov Oct 23, 2026
add621f
feat(plugin): clone only the plugin from the marketplace repository
lskramarov Oct 23, 2026
18a9d88
fix(plugin): offer --offline in /koobiq:upgrade instead of the unhand…
lskramarov Oct 23, 2026
3f0e8e2
test(plugin): check deprecate() messages in the source and the docs r…
lskramarov Oct 23, 2026
6945766
docs(plugin): document first steps, configuration and rules of the pl…
lskramarov Oct 23, 2026
043d3bd
chore(ci): move the Claude Code plugin checks to their own workflow
lskramarov Oct 26, 2026
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
17 changes: 17 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "koobiq-react",
Comment thread
artembelik marked this conversation as resolved.
"description": "Claude Code plugins for products built with Koobiq React (@koobiq/react-components).",
"owner": {
"name": "Koobiq",
"url": "https://github.com/koobiq"
},
"plugins": [
{
"name": "koobiq",
"source": "./plugins/koobiq",
"description": "Review product UI code against the Koobiq design system, migrate off deprecated APIs, upgrade the library and lint Koobiq usage.",
"category": "development",
"tags": ["design-system", "react", "code-review", "a11y", "koobiq"]
}
]
}
42 changes: 42 additions & 0 deletions .github/workflows/plugin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Claude Code plugin

on:
push:
branches:
- main
pull_request:

permissions:
contents: read # clone the repository (actions/checkout)

jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: ./.github/actions/setup-node
- name: Plugin tests
run: pnpm run test:plugin
- name: Plugin version
if: github.event_name == 'pull_request'
run: |
git fetch --no-tags --depth=1 origin "+refs/heads/$BASE_REF:refs/remotes/origin/$BASE_REF"
node scripts/check-plugin-version.mjs "origin/$BASE_REF"
env:
BASE_REF: ${{ github.base_ref }}

contract:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: ./.github/actions/setup-node
- name: Build packages
run: pnpm run build
- name: Check the plugin against the build
run: node --test plugins/koobiq/scripts/tests/real.test.mjs
env:
KOOBIQ_DS_DIR: packages/components
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ test-results

# api-extractor temp
tools/public_api_guard/temp

# Claude Code plugin eval results
plugins/*/evals/results/
2 changes: 1 addition & 1 deletion .nano-staged.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export default {
'eslint --fix',
'vitest related --run',
],
'**/*.{css}': ['stylelint --fix'],
'**/*.{css}': ['stylelint --fix --allow-empty-input'],
'**/*': () => 'pnpm type-check',
'*': ['prettier --write --ignore-unknown'],
};
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ CHANGELOG.md
tools/public_api_guard/
.husky/_/
next-env.d.ts
plugins/koobiq/scripts/tests/fixtures/
plugins/koobiq/evals/
2 changes: 2 additions & 0 deletions .stylelintignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ playwright-report/
test-results/
templates/nextjs/template
templates/vite/template
plugins/koobiq/scripts/tests/fixtures/
plugins/koobiq/evals/
26 changes: 21 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ Selected paths. The root also holds the lint, format, commit, and deploy configs
│ └── code-block.ts # `@koobiq/react-components/code-block` entry
├── docs/ # Guide MDX pages rendered in Storybook (numeric prefix sets the order)
├── .storybook/ # Storybook config, MDX doc blocks (Meta, Story, Props, Status, Alert), decorators
├── .claude-plugin/ # Claude Code plugin marketplace `koobiq-react` (for product teams)
├── plugins/koobiq/ # The `koobiq` Claude Code plugin: reviewer agent, skills, checker, lint preset
├── tools/
│ ├── api-extractor/ # Public API guard runner + config.json (guarded components/packages)
│ ├── e2e/ # Docker image, Compose files and runner of the Playwright e2e suite
Expand Down Expand Up @@ -121,9 +123,11 @@ pnpm approve-api react-core # refresh one package (react-primitives | react-core
pnpm e2e:docker # Playwright screenshot tests in Docker, where the baselines belong
pnpm e2e:docker -g Button # filter by test title; arguments go to `pnpm e2e:components`
pnpm e2e:docker:update-snapshots # rewrite changed and missing baselines

pnpm test:plugin # node --test for the Claude Code plugin in plugins/koobiq
```

CI (`.github/workflows`) runs `type-check`, `format:check`, `lint:css --max-warnings=0`, `lint:js --max-warnings=0`, `vitest --run`, `build && check-api`, and the e2e screenshot tests in Docker on an arm64 runner. Because of `--max-warnings=0`, Stylelint/ESLint **warnings fail CI**.
CI (`.github/workflows`) runs `type-check`, `format:check`, `lint:css --max-warnings=0`, `lint:js --max-warnings=0`, `vitest --run`, `build && check-api`, the e2e screenshot tests in Docker on an arm64 runner, and, in `plugin.yml`, the Claude Code plugin checks (`test:plugin`, the version check on pull requests, the contract test against a build). Because of `--max-warnings=0`, Stylelint/ESLint **warnings fail CI**.

## Component Architecture

Expand Down Expand Up @@ -216,16 +220,18 @@ Public `--kbq-<component>-*` variables are override points.
- Props with a fixed set of allowed values are exported as `as const` arrays plus a derived union type:

```ts
export const buttonVariant = ['contrast-filled', 'fade-contrast-filled', ...] as const;
export type ButtonVariant = (typeof buttonVariant)[number];
export const buttonPropVariant = ['contrast-filled', 'fade-contrast-filled', ...] as const;
export type ButtonPropVariant = (typeof buttonPropVariant)[number];
```

- All boolean props default to `false`. If `true` would be the natural default, invert the name (e.g. `hideArrow` instead of `showArrow={true}`).
- Deprecated props warn via `deprecate()` (from `@koobiq/logger`) guarded by `process.env.NODE_ENV !== 'production'`:

```tsx
if (process.env.NODE_ENV !== 'production' && 'disabled' in props) {
deprecate('Button: "disabled" is deprecated. Use "isDisabled" instead.');
deprecate(
'Button: the "disabled" prop is deprecated. Use "isDisabled" prop to replace it.'
);
}
```

Expand Down Expand Up @@ -314,7 +320,7 @@ Any change to an existing component's exported types/signatures needs the same `

All commits follow [Conventional Commits](https://www.conventionalcommits.org/) and are validated by commitlint — the `commit-msg` hook locally and the **PR title** in CI. `main` history is one squash commit per PR, so the PR title becomes the commit message. Only `feat` and `fix` appear in the changelog. Keep titles short (≤100 chars).

Format in practice: `type(scope): subject (DS-NNNN)` — scope is the component name (`fix(Button): …`; several: `fix(Flag, Sidebar): …`) or `components` when adding a new component; `DS-NNNN` is the tracker ticket, when there is one.
Format in practice: `type(scope): subject (DS-NNNN)` — scope is the component name (`fix(Button): …`; several: `fix(Flag, Sidebar): …`), `components` when adding a new component, or `plugin` for the Claude Code plugin; `DS-NNNN` is the tracker ticket, when there is one.

| Type | When to use |
| ---------- | ---------------------------------------- |
Expand All @@ -339,6 +345,16 @@ chore(deps): bump `typescript` from 5.7.3 to 6.0.3

`CHANGELOG.md` is generated at release time (`pnpm release`) — don't edit it by hand.

## Claude Code Plugin

`plugins/koobiq/` is a Claude Code plugin for **product teams**, published through `.claude-plugin/marketplace.json`. It reviews apps that use the library, not this repository. Maintainer notes are in `plugins/koobiq/README.md`.

- The plugin parses the built package. Keep the `deprecate()` message format above, the `kbq-<file>-<class>-<hash>` class names, the `<component>Prop<Name>` value arrays and the entry points stable, or update the plugin in the same PR. After `pnpm build`, `KOOBIQ_DS_DIR=packages/components pnpm test:plugin` checks the contract.
- When the setup steps in `docs/0-welcome.mdx` change, update `plugins/koobiq/skills/guidelines/references/setup.md` and `plugins/koobiq/skills/init/agents-block.md`.
- The plugin has its own semver in `plugins/koobiq/.claude-plugin/plugin.json`, and users receive a change only when it changes. A PR that changes the plugin bumps it and adds a section to `plugins/koobiq/CHANGELOG.md` (CI runs `node scripts/check-plugin-version.mjs`). `feat(plugin)` / `fix(plugin)` commits are hidden from the design system's `CHANGELOG.md`, so don't mark them breaking with `!`.
- After editing `marketplace.json` or `plugin.json`, run `claude plugin validate .`.
- Plugin scripts are dependency-free ESM (`.mjs`, Node.js 18.17+) and are excluded from `tsconfig.json`; test them with `pnpm test:plugin`.

## Important Notes for Agents

- When Storybook runs locally, an MCP server is available at `http://localhost:6006/mcp` (via `@storybook/addon-mcp`) — use it for component introspection.
Expand Down
36 changes: 36 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,39 @@ pnpm approve-api # refresh all
pnpm approve-api Button # refresh a single component
pnpm approve-api react-icons # refresh a single package
```

## 🤖 Claude Code plugin

`plugins/koobiq/` is a Claude Code plugin for teams that build products with Koobiq React
([user guide](https://react.koobiq.io/?path=/docs/ai-claude-code-plugin--docs)). It reads the built
package, so some changes to the library reach it:

- Write prop deprecations in the format from the
[Deprecation Strategy](https://react.koobiq.io/?path=/docs/deprecation-strategy--docs) page:
`pnpm test:plugin` checks every `deprecate()` call.
- Keep the generated class names (`kbq-<file>-<class>-<hash>`), the `<component>Prop<Name>` value
arrays and the package entry points stable, or update the plugin in the same pull request. After
`pnpm build`, the contract test checks them:

```bash
KOOBIQ_DS_DIR=packages/components pnpm test:plugin
```

- When the setup steps on the Welcome page change, update
`plugins/koobiq/skills/guidelines/references/setup.md` and `plugins/koobiq/skills/init/agents-block.md`.

When you change the plugin itself:

- Bump `version` in `plugins/koobiq/.claude-plugin/plugin.json` (semver) and add a section to
`plugins/koobiq/CHANGELOG.md`: users receive a change only when the version changes. CI checks both:

```bash
node scripts/check-plugin-version.mjs origin/main
```

- Use the `plugin` commit scope, for example `fix(plugin): …`. These commits stay out of the
library's changelog.
- Run `pnpm test:plugin` and `claude plugin validate .`, and try the plugin in a product with
`claude --plugin-dir /path/to/react-components/plugins/koobiq`.

Maintainer notes: [plugins/koobiq/README.md](https://github.com/koobiq/react-components/blob/main/plugins/koobiq/README.md).
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,8 @@ Here are a few helpful links for getting started with Koobiq React:
- [@koobiq/react-icons](https://github.com/koobiq/icons) — a collection of React-icons (maintained in the [koobiq/icons](https://github.com/koobiq/icons) repository).
- [@koobiq/react-core](https://github.com/koobiq/react-components/tree/main/packages/core) — common utilities and hooks used by Koobiq React packages.
- [@koobiq/logger](https://github.com/koobiq/react-components/tree/main/packages/logger) — the utilities for displaying the log on the client side.

## 🤖 AI tools

- [Claude Code plugin](https://react.koobiq.io/?path=/docs/ai-claude-code-plugin--docs) — reviews product code against the design system, helps upgrade Koobiq React and installs a lint preset. Install it in Claude Code with `/plugin marketplace add koobiq/react-components`, then `/plugin install koobiq@koobiq-react`.
- [LLMs.txt](https://react.koobiq.io/?path=/docs/ai-llms-txt--docs) — the documentation in a form AI tools can read.
11 changes: 11 additions & 0 deletions docs/0-welcome.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ export default function App() {
}
```

**Working with Claude Code**

The [Claude Code plugin](?path=/docs/ai-claude-code-plugin--docs) checks this setup in your app, keeps Claude on Koobiq components and tokens while it writes UI, and reviews your changes against the design system:

```text
/plugin marketplace add koobiq/react-components
/plugin install koobiq@koobiq-react
```

Other AI tools can read the documentation through [LLMs.txt](?path=/docs/ai-llms-txt--docs).

## Browser Support

[Check compatible browsers](https://browsersl.ist/#q=baseline+widely+available)
4 changes: 4 additions & 0 deletions docs/12-llms.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ We support [LLMs.txt](https://llmstxt.org/) files to make Koobiq React documenta
Use [`llms.txt`](https://react.koobiq.io/llms.txt) as the starting point.

Support depends on the AI tool. Some tools can use these files directly, while others may require you to open or attach them manually.

## Claude Code

The [Claude Code plugin](?path=/docs/ai-claude-code-plugin--docs) goes further: it reviews product code against the design system, helps upgrade Koobiq React and installs a lint preset.
Loading
Loading