English · 简体中文
A local, bounded component catalog CLI for React/TypeScript codebases. It indexes components from source declarations and inline JSDoc, then lets an AI coding agent retrieve only the component, import path, Props, constraints and usage it needs — without reading the whole repository.
It is not a UI documentation site, a runtime component library, or an MCP server. It is a shell CLI over a saved JSON catalog.
| CLI | 0.5.0 |
| Skill revision | 14 |
| Config schema | 2 |
| Catalog schema | 7 |
| Node | >=22 |
| Runtime dependency | TypeScript 5.9.3 only |
| License | MIT |
Table of contents
AI coding agents are good at writing components and expensive at rediscovering an existing design system. Component Catalog gives them a bounded, project-specific index:
- Find the existing component before creating a duplicate — search by export name, task tag, vocabulary alias or Prop.
- Get the integration facts, not the whole file — ID, export, import path, required Props, constraints and usage counts.
- Bound context in large monorepos — query output is capped;
typeScope: "componentRoots"avoids loading the server/lib/Prisma graph. - Keep the index verifiable —
audit,checkandverifycover enrollment, freshness and representative queries.
Typical searches this project is designed for: React component catalog, component discovery for AI agents, TypeScript component search, find component import path and props, bounded codebase context.
Published to the npm registry as a public scoped package:
npm install @codecantbuild/component-catalog
npx @codecantbuild/component-catalog --versionOr install the GitHub Release tarball, which has identical contents and needs no registry:
npm install https://github.com/AleFlyX/component-catalog/releases/download/v0.5.0/codecantbuild-component-catalog-0.5.0.tgz
./node_modules/.bin/component-catalog --versionCI runs tests on every v* tag, verifies the tag matches the package version, packs and creates the Release. The npm package is published manually from the main branch.
Five minutes from a checkout to a queryable catalog. examples/basic is a minimal project that needs no browser runtime.
npm ci
node bin/component-catalog.mjs doctor --installation --expect-version 0.5.0 --expect-skill-revision 14
node bin/component-catalog.mjs scan examples/basic/src --summary
node bin/component-catalog.mjs --config examples/basic/component-catalog.config.json generate
node bin/component-catalog.mjs --config examples/basic/component-catalog.config.json search 按钮search returns one bounded JSON object. Every item names the signal that matched it:
{
"items": [
{
"id": "demo.ui.Button",
"exportName": "Button",
"importPath": "@demo/ui/Button",
"layer": "shared",
"matched": "task",
"requiredProps": ["label"],
"tasks": ["button"],
"status": "stable",
"reuse": { "scope": "project" }
}
],
"truncated": false,
"omitted": { "items": 0, "byLimit": 0, "byBytes": 0 }
}matched is the important field: task means a task tag matched, name an ID or export name, prop a Prop name, and summary only that the word appeared in prose. Treat summary as the weakest signal.
When you need one API detail, ask for that detail rather than the whole component:
node bin/component-catalog.mjs --config examples/basic/component-catalog.config.json \
get demo.ui.Button --prop disabled{
"component": {
"id": "demo.ui.Button",
"importPath": "@demo/ui/Button",
"constraints": ["Supply a short, actionable label."],
"prop": {
"name": "disabled",
"displayType": "boolean | undefined",
"required": false,
"defaultValue": "false",
"schemaStatus": "complete"
}
},
"selection": { "kind": "prop", "name": "disabled", "partial": true }
}component-catalog search "form" --limit 5
component-catalog search rowKey --details
component-catalog get ui.forms.BusinessForm
component-catalog get ui.forms.BusinessForm ui.forms.CustomerPicker
component-catalog get ui.forms.BusinessForm --prop disabled
component-catalog get ui.forms.BusinessForm --from src/features/orders/Page.tsxRules that keep queries cheap and honest:
- Run one
searchfirst. When--detailsalready returnedimportPath,requiredPropsand the first constraint, do not callgetto confirm them. - Use
getonly for constraints, examples or full Prop context. Several IDs belong in oneget, but never combine them with--propor--from. - For mixed intent use
--per-layer 3; a single-layer catalog expands that default to 5. Use--per-layer 5only when a multi-layer catalog has many strong candidates in one layer. --layer autosuits single-intent queries only. A mixed query must return acomponentsarray covering every role, with missing roles marked explicitly.- When no dedicated component exists but a general one clearly serves the role, return the general component with a caveat. Mark
missingonly when nothing in the domain serves it. - On a weak or empty result, change the wording, use
--briefor--limit 10, or fall back toscan. Never callgetwith a guessed ID.
Output is capped at 4 KiB for search and 16 KiB for get. truncated means byte capping; more matches than the limit appear as omitted.byLimit. Set COMPONENT_CATALOG_LOG=<path> to write a local JSONL usage log; it never records source content.
/**
* Renders the order form shell used by the orders feature.
* @componentCatalog
* @catalogStatus experimental
* @catalogTask business-form
* @catalogConstraint Submit state is owned by the caller.
* @catalogExample production src/features/orders/Form.tsx | Order form
*/
export function BusinessForm(props: { disabled?: boolean }) { /* ... */ }summary,status, and at least one task, constraint and example are required.experimentalmay have no stable example;stableneeds a production or preview example.- Excluded candidates use
@componentCatalogIgnore internal|non-component|unsupported: <reason>. Do not delete markers silently. - After adding, changing, moving or deleting a component, run
audit → generate → check. The full lifecycle lives in maintenance.md.
Copy the whole skills/component-catalog directory into the agent's skill location — not just SKILL.md. The directory carries the CLI, schema, references and dependency manifest.
npm ci --prefix "<skill-directory>/scripts" --ignore-scripts --no-audit --no-fund
node "<skill-directory>/scripts/bin/component-catalog.mjs" \
doctor --installation --expect-version 0.5.0 --expect-skill-revision 14The skill routes by intent: an ordinary query never loads the setup workflow, and a missing configuration is not permission to initialize a catalog. When scope is unclear the agent presents candidate directories, counts and a recommendation before asking.
For setup in a project whose users type Chinese, seed the template with init --locale zh-CN; summaries and task tags stay English either way. init never guesses a language.
Machine-readable project summary for crawlers: llms.txt.
Choose typeScope before the first generate; it is a configuration decision, not a query flag.
| Project shape | Use |
|---|---|
| Small/medium, components import only project UI | typeScope: "project" (default) |
| Large monorepo importing a server/lib/trpc/Prisma graph | typeScope: "componentRoots" |
componentRoots loads only the component-root type graph; imports outside the roots become shallow any types. Local Props stay typed, inherited ones may be any/partial.
The full remediation contract — suppression defaults, typeCheck semantics and the suppressedType* report fields — is owned by setup.md § Large-repository type scope. When generation runs out of memory, switch typeScope and regenerate rather than raising the heap, and state the type-fidelity tradeoff in your handoff.
Is this a Storybook or a component documentation site?
No. Storybook is a UI explorer and documentation surface. Component Catalog is a CLI that turns selected component declarations into a compact JSON index for coding agents. It does not render components or replace runtime checks.
Is this an MCP server?
No. It is a shell CLI with local files and bounded JSON output. It can be invoked by any agent or script that can run a command; no editor extension or MCP transport is bundled.
Does it work with Claude Code, Cursor, Codex or other coding agents?
It is agent-agnostic: the integration surface is the CLI plus the bundled SKILL.md. Agent-specific installation and permissions are managed by the host.
Does it reduce token usage?
In the local airport benchmark (5 tasks, 3 runs), reading source used about 462.8K total tokens, while catalog-details used about 100.2K — roughly 78% fewer in that setting. This is a local benchmark with a 30-entry scoped catalog, not a universal guarantee; setup cost and task shape matter. Benchmark data is intentionally kept out of the public repo.
Does it index the entire repository?
No. It indexes supported JS/JSX/TS/TSX declarations in explicitly configured component roots, and requires a decision for candidates. Routes, pages, unsupported formats and unselected components may be excluded; discovery.status=partial reports acknowledged gaps.
Does querying modify source or the catalog?
No. search and get are read-only. generate writes the catalog; audit, check and verify do not regenerate it.
Why did a component get enrolled but stay unfindable in Chinese?
Because enrollment and vocabulary are separate concerns. A component is searchable by its English task tag immediately, while an ordinary-language query needs a vocabulary entry mapping that wording to the tag. audit reports such tasks under discovery.unreachablePrimaryTasks; it is advisory, so nothing fails.
- Only PascalCase value exports, default exports and explicitly marked declarations in JS/JSX/TS/TSX are scanned. Vue, Svelte, MDX, cross-file HOCs and anonymous default exports may be unsupported.
- Props extraction depends on TypeScript. Complex generics, unions and inheritance may be
partial/unsupported;anyor empty fields do not prove a component accepts no Props. typeScope: "componentRoots"is an explicit memory/fidelity tradeoff, not a full type check.- The catalog is a discovery aid; project architecture, runtime code and the project's own checks remain authoritative.
For installation detail, configuration contract, boundaries and troubleshooting, see setup.md.
npm test # 117 tests
npm run check # syntax + tests
npm run build # packaging manifestContribution rules, fixture layout and release steps live in CONTRIBUTING.md. Documentation ownership and the single-source-of-truth map live in AGENTS.md.
Cross-agent evaluation method: evaluation.md. Concrete tasks, answers and fixture paths stay outside the SKILL; evaluation data lives in the gitignored test/audits/.
MIT © 2026 AleFlyX