feat(docs): add machine-readable api-index.json for all tokens and classes - #271
Conversation
…asses Generate docs/api-index.json — a single, spreadsheet-style catalogue of every public framework element (design tokens AND classes) for editor integrations, autocomplete, tooltip hints and docs tooling. Each row carries rich metadata columns: type, stability tier (PUBLIC/PUBLIC-ADVANCED/INTERNAL), category, group + description (derived from the existing section-banner comments — no new annotation syntax), source files, @layer, bundle membership, and per-type facets (token namespace/value/aliasOf/registered/animatable/syntax/inherits/fallback; class selector/prefix/kind/variant/baseClass). A self-describing _meta block with counts and a column schema is included for consumers. - scripts/gen-api-index.js: new generator, reuses the canonical comment/string-masking parse contract; token/class counts line up with registry.json (769 tokens, 173 .sf-, 40 .is-, 9 unprefixed). - scripts/token-tiers.js: extract the INTERNAL/ADVANCED tier sets into a shared module; gen-token-index.js now imports them (byte-identical output, verified). - wire into the build: npm run docs chain + docs:api script, register the output in scripts/artifacts.json (CI freshness), ship via package.json exports/files, and publish alongside the bundles on the dist branch. Co-authored-by: Jack Granatowski <contact@codeslash.net>
|
Warning Review limit reached
More reviews will be available in 32 minutes and 38 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThis PR establishes a shared token tier contract, extracts it into an authoritative module, refactors the existing token index generator to use it, implements a new API index generator that catalogs tokens and CSS classes with metadata and tier information, and integrates the generated index into package exports and CI publishing. ChangesAPI Index Generation & Token Tier Extraction
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
scripts/gen-api-index.js (1)
344-345: ⚡ Quick winFail fast when a source file is missing
FILE_METAmapping.Line 344 and Line 438 assume
FILE_META[rel]exists. IfTOKEN_FILES/CLASS_FILESgains a new source without metadata, the script throws a generic property-access error instead of a clear contract failure.Proposed refactor
+function metaFor(rel) { + const meta = FILE_META[rel]; + if (!meta) { + throw new Error(`[docs:api] Missing FILE_META entry for source file: ${rel}`); + } + return meta; +} + function buildTokenEntries(bundlesFor) { const fb = fallbackNames(); const merged = new Map(); // name -> entry for (const rel of TOKEN_FILES) { const rows = extractTokensFromFile(rel); - const meta = FILE_META[rel]; + const meta = metaFor(rel); @@ function extractClassesFromFile(rel) { @@ - const meta = FILE_META[rel]; + const meta = metaFor(rel);Also applies to: 438-439
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/gen-api-index.js` around lines 344 - 345, The code assumes FILE_META[rel] exists and will throw an opaque error if it doesn't; add an explicit check after computing const meta = FILE_META[rel] (and the analogous spot for the second usage) and if meta is undefined throw a clear Error that includes the offending rel (and whether it came from TOKEN_FILES or CLASS_FILES) and instructs to add the required metadata to FILE_META; update the blocks around rows iteration to validate meta before accessing its properties so the script fails fast with a helpful message.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/gen-api-index.js`:
- Around line 348-368: The token objects created in merged.set(...) (see the
constructor setting name, type, tier, ... bundles) omit the fallbackOnly
property for regular tokens, making the column sparse; add fallbackOnly: false
to the object literal in the merged.set call that initializes normal token
entries (the block that sets value, aliasOf, registered, animatable, etc.) so
every row has a boolean, and ensure the later legacy-only branch (the other
merged.set around the legacy handling) continues to set fallbackOnly: true;
update both spots referenced in this diff (the regular token creation and the
legacy branch around lines 405-422) to keep the property consistent.
---
Nitpick comments:
In `@scripts/gen-api-index.js`:
- Around line 344-345: The code assumes FILE_META[rel] exists and will throw an
opaque error if it doesn't; add an explicit check after computing const meta =
FILE_META[rel] (and the analogous spot for the second usage) and if meta is
undefined throw a clear Error that includes the offending rel (and whether it
came from TOKEN_FILES or CLASS_FILES) and instructs to add the required metadata
to FILE_META; update the blocks around rows iteration to validate meta before
accessing its properties so the script fails fast with a helpful message.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: caa403d8-f067-464f-8be0-328c579a2bfc
📒 Files selected for processing (7)
.github/workflows/publish-dist.ymldocs/api-index.jsonpackage.jsonscripts/artifacts.jsonscripts/gen-api-index.jsscripts/gen-token-index.jsscripts/token-tiers.js
| merged.set(name, { | ||
| name, | ||
| type: 'token', | ||
| tier: tierOf(name), | ||
| namespace: namespaceOf(name), | ||
| category: meta.category, | ||
| area: meta.area, | ||
| group: data.group || '', | ||
| description: data.description || '', | ||
| value: data.value ?? null, | ||
| aliasOf: aliasTarget(data.value), | ||
| registered: !!data.registered, | ||
| animatable: !!data.registered, | ||
| syntax: data.syntax ?? null, | ||
| inherits: data.inherits ?? null, | ||
| hasFallback: fb.has(name), | ||
| optional: rel.startsWith('optional/'), | ||
| layer: data.layer || null, | ||
| sourceFiles: [rel], | ||
| bundles: new Set(bundlesFor(rel)), | ||
| }); |
There was a problem hiding this comment.
Emit fallbackOnly: false for non-legacy token rows.
Line 348 initializes regular token entries without fallbackOnly, while Line 421 sets it to true for legacy-only rows. This makes the token column sparse and can break consumers expecting a boolean token field in every row.
Proposed fix
merged.set(name, {
name,
type: 'token',
tier: tierOf(name),
namespace: namespaceOf(name),
@@
syntax: data.syntax ?? null,
inherits: data.inherits ?? null,
hasFallback: fb.has(name),
+ fallbackOnly: false,
optional: rel.startsWith('optional/'),
layer: data.layer || null,
sourceFiles: [rel],
bundles: new Set(bundlesFor(rel)),
});Also applies to: 405-422
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/gen-api-index.js` around lines 348 - 368, The token objects created
in merged.set(...) (see the constructor setting name, type, tier, ... bundles)
omit the fallbackOnly property for regular tokens, making the column sparse; add
fallbackOnly: false to the object literal in the merged.set call that
initializes normal token entries (the block that sets value, aliasOf,
registered, animatable, etc.) so every row has a boolean, and ensure the later
legacy-only branch (the other merged.set around the legacy handling) continues
to set fallbackOnly: true; update both spots referenced in this diff (the
regular token creation and the legacy branch around lines 405-422) to keep the
property consistent.
- gen-api-index.js now also emits docs/api-index.md, a browseable companion generated from the SAME data as the JSON (tokens and classes split into per-category tables) so the two can never drift. Registered in scripts/artifacts.json for CI freshness. - tests/api-index-sync.test.js: node:test regression asserting api-index.json stays in sync with the authoritative registry.json (token/class name parity, fallback-only isolation, _meta count consistency, and per-row column/enum well-formedness). Wired into the pretest chain. No fast-check dependency.
This pull request was created by @kiro-agent on behalf of @jackgranatowski 👻
Comment with /kiro fix to address specific feedback or /kiro all to address everything.
Learn about Kiro Web
What
Adds
docs/api-index.json— a single, auto-generated, machine-readable catalogue of every public framework element (design tokens and classes), built for editor integrations, autocomplete/IntelliSense, tooltip hints, and docs tooling.Think of it as a spreadsheet: one row per element, many metadata columns.
Each entry (row) carries
name,type(token|class),tier(PUBLIC/PUBLIC-ADVANCED/INTERNAL),category,area,group,description,sourceFiles,layer,bundles(which tiers ship it),optionalnamespace(color/space/font/…),value,aliasOf,registered,animatable,syntax,inherits,hasFallback,fallbackOnlyselector,prefix(sf/is/``),kind, `isVariant`, `baseClass`A self-describing
_metablock includesgenerated_by, source lists, the full bundle list, counts (by type / tier / category) and aschemadocumenting every column — so consumers can introspect the format.Where descriptions/categories come from
No new annotation syntax was introduced.
group+descriptionare derived from the existing section-banner comments in the source CSS;category/layer/bundlescome from the file +bundle.config.json; token tiers come from the existing contract.How it's wired in
scripts/gen-api-index.js— new generator. Reuses the canonical comment/string-masking parse contract used by the other generators. Output is deterministic (verified byte-identical across runs).scripts/token-tiers.js— extracted theINTERNAL/ADVANCEDtier sets into a shared module;gen-token-index.jsnow imports them (token-index output is byte-identical, verified).npm run docschain + added adocs:apiscript; registered the output inscripts/artifacts.jsonso CI's freshness check enforces it; shipped viapackage.jsonexports/files; and copied next to the bundles on the publisheddistbranch (CDN), e.g.…/SLASHED@dist/api-index.json.Counts (cross-checked against
registry.json)1024 elements: 802 tokens (incl. 33 legacy HSL fallback-only channels, flagged) + 222 classes (173
.sf-, 40.is-, 9 unprefixed). The 769 core tokens / 173 / 40 / 9 all matchregistry.json.Testing
node scripts/check-artifacts.js --check(the CI freshness job) passes — full bundle + docs build clean.gen-token-index.jsrefactor produces no diff indocs/token-index.{json,md}.Summary by CodeRabbit