Repository navigation
feat(plugin): add Koobiq Claude Code plugin for product teams (DS-5683) - #495
Conversation
Register a plugin marketplace at the repository root with one plugin, koobiq, for products built with @koobiq/react-components. Exclude the plugin's test fixtures and eval results from repo lint, format and type-check.
…oduct code koobiq-check reads the installed @koobiq/react-components, design tokens and icons, then checks product code for setup mistakes, non-public and internal imports, deprecated props/components/exports (from the runtime deprecate() messages, which the d.ts loses for forwardRef components), unknown/deprecated/legacy tokens, hashed CSS-module classes, literal colors, raw HTML controls, controlled-prop mistakes, missing labels and native date formatting. The shared decision core lives in lint/koobiq-core.mjs so the upcoming lint presets agree with it. Zero dependencies (Node >= 18.17); TypeScript is borrowed from the product for parsing, with a regex tier when it is missing. The pre-commit Stylelint task now allows empty input, so commits that only touch Stylelint-ignored CSS (templates, plugin fixtures) pass.
Minimal @koobiq/react-components, design-tokens, react-icons, react-core and react-primitives packages that mirror the real build: deprecated props inlined without JSDoc, a wrong JSDoc replacement corrected by the runtime message, deprecated exports and slotProps, hashed classes and override points in style.css, legacy and web/new token sets. They live under lib/ because dist/ and node_modules/ are gitignored.
bad-app seeds one violation per rule and is matched exactly against its // expect: annotations; good-app must produce no findings; js-app runs the regex tier without TypeScript; monorepo checks per-package knowledge and app-only setup checks. Unit tests cover the core, parsers, report and CLI; real.test.mjs runs on the starter templates and, with KOOBIQ_DS_DIR, checks the contract with a built DS.
The docs present react-core hooks (useBoolean, useMediaQuery, …), FileSizeFormatter and the Button/Link primitives to consumers, so importing them is not an internal-layer violation. A declared internal package is reported only when versions drift or nothing imports it.
- koobiq:guidelines (model-invoked) holds the product rules and a references/ knowledge base: setup, component choice, props and forms, TypeScript, styling with tokens, a11y, i18n, public API and upgrades, severity and output. Every rule id it mentions exists in the RULES registry (checked by a test). - koobiq:reviewer is a read-only agent that triages koobiq-check candidates and reviews a batch of files against the installed DS, with hard evidence rules (props in the installed d.ts, tokens in the installed CSS, replacements that really exist). - /koobiq:review scopes the change (branch diff by default), runs koobiq-review-prep to batch files and candidates, fans out reviewer agents, re-verifies errors, reports via ReportFindings or markdown and can apply safe fixes with --fix.
init-agents.mjs plans (and with --apply writes) a managed Koobiq block in the product's AGENTS.md or CLAUDE.md — picked the way Claude Code loads instruction files — refreshing it idempotently and keeping the project's exceptions list. --share merges the koobiq-react marketplace into .claude/settings.json so teammates get the plugin after trusting the folder. The skill shows the diff, asks before writing and runs the setup checks.
…p-lint eslint.koobiq.mjs (flat config, local koobiq/* rules) and stylelint.koobiq.mjs (Stylelint 16 plugins) reuse the koobiq-core decisions, so CI enforces the same rules as koobiq-check: deprecated props/exports (catalog-based, catching what @typescript-eslint/ no-deprecated misses), non-public imports, other UI kits and icon sets, unknown/deprecated tokens, hashed classes, exact-match literal colors, missing labels and controlled-prop mistakes. setup-lint.mjs detects the package manager and the ESLint/Stylelint setup, copies the preset into .koobiq/ with a version and content hash (re-runs update unmodified copies and keep local edits), creates missing configs and prints the config edits and install commands the skill applies after confirmation. The var() scanner moved into the core so the checker and both presets share it.
koobiq-upgrade.mjs gathers what changes between two versions for the components a product uses: the CHANGELOG range (entries marked relevant by scope or as breaking), diffs of the public API reports at both tags (available from 0.34.0), peer dependency changes and the docs lifecycle status. It caches fetched files for offline runs. The skill turns it, together with the checker inventory, into a file-by-file migration checklist and bumps versions only after confirmation.
- T2: named imports from local barrels (relative paths and tsconfig
aliases, `export {…} from` / `export * from`, depth 3) bind to Koobiq
exports, so deprecations and props are checked through `@/ui`; the
inventory records the barrel in `via`.
- T3 (`--typecheck`): the TypeScript language service reports deprecated
Koobiq members the catalog cannot see — wrappers typed with Koobiq props,
aliases, destructuring, property access. Members are resolved on the
owner type; a JSDoc replacement is kept only when that type has it
(`isReadonly` → `isReadOnly`). Grouped by tsconfig, solution-style
references, at most 200 files / 60 s, deduped against the catalog.
- Review prep takes `--typecheck` (used by `/koobiq:review --deep`) and
reports the TypeScript tier; the reviewer knows the candidate sources.
- Tests for barrels, the language-service tier and the i18n rules.
- docs/13-claude-code-plugin.mdx ("AI/Claude Code plugin"): what the plugin
checks, requirements, installation for one person and for a team,
commands and review options, severity, a sample report, exceptions,
upgrade, the lint preset rules, other AI tools, network and files,
updating, removing and troubleshooting.
- Links from the LLMs.txt page and an "AI tools" section in the README.
- plugins/koobiq/README.md: maintainer notes (layout, rule registry, the
contract with the built package, preset versions, tests).
- AGENTS.md: the plugin in the repository structure, `pnpm test:plugin`,
the `plugin` commit scope and a section on keeping the contract; the
deprecate() and enum-array examples now match the source.
- units.yml: `pnpm run test:plugin` after the Vitest run. - api.yml: after the build, the plugin contract test against packages/components (deprecate() messages, CSS Module class names, enum arrays, field components, docs ids), so DS changes that break the plugin fail the PR that makes them. - The contract test says to build first when KOOBIQ_DS_DIR has no exports; the TypeScript tier test skips without csstype.
scripts/koobiq-check.schema.json describes every field of the report (meta, findings, inventory) with additionalProperties: false, so new fields have to be added to the contract. schema.test.mjs validates reports from every fixture — full and summary inventories, the regex tier, a monorepo, changed mode, truncation and local barrels — with a small built-in validator. The CLI help and the reviewer agent point to the schema.
|
Important Review skippedToo many files! This PR contains 147 files, which is 47 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.
|
|
Visit the preview URL for this PR (updated for commit 043d3bd): https://react-koobiq-next--prs-495-jtito2ju.web.app (expires Sat, 31 Oct 2026 07:15:01 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: fc29847d4a9e5cb1adf458c76a9b681c76e2eeff |
- plugin.json gets "version": "1.0.0". Users receive a change only when it changes, so a pull request that changes released plugin files bumps it and adds a section to plugins/koobiq/CHANGELOG.md. - scripts/check-plugin-version.mjs checks both against the base branch (tests, evals, the README and the changelog need no bump); units.yml runs it on pull requests. - koobiq-check --version and the report's tool.version read plugin.json. - feat(plugin) and fix(plugin) commits are hidden from the design-system CHANGELOG; the plugin keeps its own. - The plugin README describes releases and the internal format versions (preset, report schema, AGENTS.md block); fixes the --plugin-dir example that prettier-plugin-sh had mangled. AGENTS.md notes the rule.
The marketplace is the whole Koobiq React repository. The settings that /koobiq:init --share writes now set sparsePaths [".claude-plugin", "plugins"], and the docs show `claude plugin marketplace add … --sparse`. The docs page also explains the plugin's own version and changelog and what autoUpdate does.
…ule table - Every deprecate() call that deprecates a prop must use the format the plugin parses; the build-level contract test only counted messages, so a single message in another format went unnoticed. - The rule table on the docs page must list every rule of RULES, in the column of its detector.
…ugin - Claude Code plugin page: first steps from /koobiq:init to /koobiq:upgrade, the .koobiq/check.json reference, the rule catalog by category and detector, pinning the plugin to a release tag. - Welcome: how to install the plugin, next to the setup it checks. - Deprecation Strategy: the deprecate() message format is read by the plugin and checked by pnpm test:plugin. - Contributing: what library and plugin changes need (the contract, version bumps, the changelog, the commit scope, tests).
There was a problem hiding this comment.
🔵 Needs a closer look
It introduces a large, self-contained plugin runtime (much of it outside the provided diff) plus release/CI and commit-and-tag-version scope-hiding changes whose correctness depends on behavior I cannot execute here, warranting human verification.
No open issues 🎉
What changed in this PR
This PR adds koobiq, a Claude Code plugin for product teams that build UIs with @koobiq/react-components, plus the koobiq-react marketplace at the repo root. The plugin is a self-contained, dependency-free ESM subsystem (checker, review/upgrade/setup-lint/init skills, a read-only reviewer agent, ESLint/Stylelint presets, and an extensive test suite with stub-package fixtures) that reads the DS version installed in the product's node_modules rather than the latest docs. It also wires the plugin into repo tooling (CI, lint/format ignores, independent versioning) and documentation.
Changes:
- New plugin under
plugins/koobiq/**and marketplace manifest.claude-plugin/marketplace.json, with independent semver gated byscripts/check-plugin-version.mjs. - CI integration:
test:plugininunits.yml+ plugin version check on PRs; contract test against the build inapi.yml. - Tooling/doc updates:
package.jsonscripts and hiddenfeat(plugin)/fix(plugin)changelog types, ESLint/Prettier/Stylelint/tsconfig/gitignore ignores, and docs (AGENTS.md, README, CONTRIBUTING,docs/0,docs/9,docs/12, newdocs/13).
| File(s) | Description |
|---|---|
scripts/check-plugin-version.mjs |
New CI guard enforcing a plugin version bump + CHANGELOG section for released-file changes. |
plugins/koobiq/scripts/koobiq-check.mjs, lib/{cli,format-text,ts,barrels}.mjs, lib/checks/style.mjs |
Deterministic checker entrypoint, arg parsing, text output, TS loader, barrel resolver, style-fact bridge. |
plugins/koobiq/lint/stylelint.koobiq.mjs |
Stylelint preset reusing koobiq-core decisions. |
plugins/koobiq/skills/**/*.md, agents/reviewer.md |
Slash-command skills, references, and the read-only reviewer agent prompt. |
plugins/koobiq/scripts/tests/** (tests + fixtures/stubs) |
Unit/e2e tests and stub @koobiq/* packages and sample apps with expect: annotations. |
plugins/koobiq/{README,CHANGELOG}.md, .claude-plugin/plugin.json, .claude-plugin/marketplace.json |
Plugin maintainer docs, changelog, manifest, and marketplace registration. |
.github/workflows/{units,api}.yml |
Run plugin tests, PR version check, and build-contract test. |
package.json |
test:plugin/koobiq-check scripts; hidden feat(plugin)/fix(plugin) changelog types. |
eslint.config.mjs, .prettierignore, .stylelintignore, .nano-staged.mjs, tsconfig.json, .gitignore |
Exclude fixtures/evals/plugin scripts from tooling; --allow-empty-input for Stylelint. |
AGENTS.md, CONTRIBUTING.md, docs/{0,9,12}-*.mdx |
Document the plugin, its contract, and the DS deprecate() message format. |
I verified that referenced-but-not-diffed modules (lib/engine.mjs, koobiq-core.mjs, real.test.mjs, the schema, etc.) exist, that relative import/path resolution in the shown test and lib files is correct, and that the doc/config claims match the real codebase (buttonPropVariant, the deprecate() message wording, and --kbq-layer-* values). I did not find a confident, concrete defect within the changed regions I was shown.
Review effort: Balanced
plugin.yml runs the plugin tests and the version check (pull requests only) in one job and the contract test against a build in another, so a plugin failure no longer fails the unit tests or the API check. units.yml and api.yml are back to their main versions.
Summary
добавляет
koobiq— Claude Code-плагин для продуктовых команд, которые пишут UI на@koobiq/react-components. маркетплейсkoobiq-reactживёт в этом репо:/plugin marketplace add koobiq/react-components, затем/plugin install koobiq@koobiq-react./koobiq:review— ревью кода продукта на соответствие DS. детерминированный чекерkoobiq-checkнаходит кандидатов, read-only агентыkoobiq:reviewerих проверяют и ищут то, что скрипт не видит: выбор компонента, композицию, типизацию обёрток, тему. отчёт по severity; флаги--fix,--deep,--all,--base,--offline./koobiq:upgrade— changelog между версиями, диффы публичного API используемых компонентов и peer-зависимостей → чек-лист миграции сfile:line. бамп и правки кода только после подтверждения./koobiq:setup-lint— копирует в продукт ESLint- и Stylelint-пресет на общем с чекером ядре правил, чтобы CI держал правила без Claude./koobiq:init— управляемый блок правил Koobiq в AGENTS.md или CLAUDE.md продукта;--shareрегистрирует маркетплейс в.claude/settings.json.koobiq:guidelines— правила и справочник, Claude подгружает их сам, когда пишет UI в Koobiq-приложении.знания берутся из пакетов, установленных в продукте: сообщения
deprecate()и JSDoc из d.ts, enum-массивы, классы и точки кастомизации изstyle.css, наборы токенов (new и legacy), манифест иконок. поэтому советы соответствуют версии вnode_modules, а не последней документации.коммиты идут по этапам, их удобно смотреть по одному.
что ещё меняется в репо
.claude-plugin/marketplace.jsonиplugins/koobiq/**. скрипты — ESM без зависимостей (Node.js 18.17+), исключены изtsconfig.json. фикстуры исключены из ESLint, Stylelint и Prettier: в их аннотацияхexpect:зашиты номера строк.docs/13-claude-code-plugin.mdx(AI → Claude Code plugin), ссылка с LLMs.txt, раздел «AI tools» в README.pnpm test:plugin, scopeplugin, раздел про контракт. примерыdeprecate()и enum-массивов приведены к формату из кода (the "x" prop is deprecated,buttonPropVariant).pnpm run test:pluginвunits.yml, contract-тест против сборки вapi.yml. это отдельный коммит, его легко убрать.1.0.0вplugin.jsonи свойplugins/koobiq/CHANGELOG.md. пользователи получают изменения, только когда меняется версия, поэтому PR, меняющий плагин, поднимает её и добавляет раздел в changelog. это проверяетscripts/check-plugin-version.mjsвunits.yml.feat(plugin)иfix(plugin)скрыты в конфигеcommit-and-tag-version: в CHANGELOG DS изменения плагина не попадают. отсюда следствие: этот PR тоже не попадёт в release notes DS./koobiq:init --shareпрописываетsparsePaths, и коллеги клонируют только.claude-pluginиplugins, а не весь репозиторий.контракт с DS
плагин разбирает собранный пакет: формат сообщений
deprecate(), имена классовkbq-<file>-<class>-<hash>, массивы<component>Prop<Name>, поля сlabel?: FormFieldLabelProps, точки входа, id страниц документации. шаг вapi.ymlуронит PR, который это сломает.что проверить
pnpm test:plugin— 60 тестов: unit, e2e на фикстурах с точным набором ожидаемых находок, паритет пресетов, JSON Schema отчёта, стартовые шаблоны. послеpnpm buildcontract-тест:KOOBIQ_DS_DIR=packages/components pnpm test:plugin.claude plugin validate .— одно предупреждение: нетversion, так задумано (пользователи следуют за коммитами).claude --plugin-dir <путь к этому checkout>/plugins/koobiq, затем/koobiq:review --all. на стартовых шаблонах ожидаются legacy-токены, а на vite-шаблоне ещё необъявленный@koobiq/design-tokensиisBrowserиз react-core.ещё не сделано: живые прогоны скиллов на копии шаблона и eval'ы плагина. страницу документации я проверил компиляцией MDX (компилятор Storybook с
remark-gfm), в Storybook глазами не смотрел.найдено по дороге (отдельные задачи)
@deprecatedу инлайновыхXDeprecatedProps, поэтому TypeScript и@typescript-eslint/no-deprecatedне видят около половины устаревших пропсов (Input, Textarea, Checkbox, Toggle, Radio, Modal, Popover, Tooltip, SidePanel). плагин берёт их изdeprecate().isVisitableвместоallowVisited,isReadonlyвместоisReadOnly.@koobiq/design-tokensи импортируетisBrowserиз react-core.🤖 Generated with Claude Code