feat(docs): expand ComponentGrid in llms.txt output#1509
feat(docs): expand ComponentGrid in llms.txt output#1509
Conversation
Add a rule that transforms <ComponentGrid /> into a categorized markdown list of components so /llms/docs/components.txt exposes the full component index instead of a bare MDX tag. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
📝 WalkthroughWalkthrough로컬 컴포넌트 문서 디렉터리를 스캔해 frontmatter 기반 엔트리를 수집·캐시하고, 카테고리별로 그룹화한 마이그된 Markdown 링크 목록을 생성해 Changes
Sequence Diagram(s)sequenceDiagram
participant LLM as "LLM Processor"
participant Rule as "ComponentGrid Rule"
participant FS as "Filesystem (docs/components)"
participant Cache as "In-memory Cache"
LLM->>Rule: encounters <ComponentGrid /> node
Rule->>Cache: check cached entries
alt cache miss
Rule->>FS: scan category folders & read .mdx files
FS-->>Rule: return file list and frontmatter
Rule->>Rule: parse frontmatter, filter deprecated, build entries
Rule->>Cache: store entries
end
Rule->>Rule: buildMarkdown(grouped entries)
Rule-->>LLM: return HTML node with generated markdown
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 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 docstrings
🧪 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: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/app/_llms/rules/component-grid-rule.test.ts`:
- Around line 5-30: The tests in component-grid-rule.test.ts use partial
matching (toContain/not.toContain) against normalizeLLMBodyWithRules output;
replace these with full-fixture comparisons using normalizeForAssert and
readFixture: import { normalizeForAssert, readFixture } from
'docs/app/_llms/test-utils.ts', call const expected =
readFixture('<appropriate-fixture-filename>.md') and assert
expect(normalizeForAssert(actual)).toBe(normalizeForAssert(expected)); update
each test ("expands ComponentGrid...", "excludes deprecated components...") to
use this pattern and corresponding fixtures, and rename the third test from
"leaves the node as-is when no components are available" to "non-target node
passthrough" (or similar) while also asserting full-fixture equality for the
passthrough case using normalizeForAssert. Ensure tests still call
normalizeLLMBodyWithRules(input, [componentGridRule]) as before.
In `@docs/app/_llms/rules/component-grid-rule.ts`:
- Around line 28-42: parseFrontmatter currently returns all frontmatter values
as strings so a frontmatter like deprecated: false becomes the string "false"
and is treated truthily; update parseFrontmatter to detect boolean-like values
(at least for the "deprecated" key) and convert "true"/"false"
(case-insensitive) to actual booleans (true/false) before storing in result, or
more generally parse "true"/"false" and numeric strings to proper types;
reference the parseFrontmatter function and the "deprecated" frontmatter key so
the boolean false is not treated as truthy in the downstream filter that
excludes deprecated components.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 7cfa20d2-5930-43f0-ab0e-243cd406575d
📒 Files selected for processing (3)
docs/app/_llms/rules/component-grid-rule.test.tsdocs/app/_llms/rules/component-grid-rule.tsdocs/app/_llms/rules/index.ts
Alpha Preview (Docs)
|
- Treat deprecated: false / "no" / empty as not deprecated so valid components are no longer filtered out by the string-coerced parser. - Switch tests to fixture-based equality via readFixture / normalizeForAssert to match the project's _llms test convention, and add unit coverage for isDeprecatedValue. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Alpha Preview (Stackflow SPA)
|
Alpha Preview (Storybook)
|
There was a problem hiding this comment.
🧹 Nitpick comments (4)
docs/app/_llms/rules/component-grid-rule.ts (4)
86-91: 모듈 수준 캐시는 프로세스 생애 동안 무효화되지 않습니다.
cachedEntries가 첫 호출 이후 영구히 재사용되므로, dev 서버가 장시간 떠 있는 상태에서 컴포넌트 MDX를 추가/수정/삭제해도/llms/docs/components.txt결과에 반영되지 않습니다. 빌드 타임에만 실행된다면 문제없지만, HMR/런타임 호출 경로가 있다면NODE_ENV !== 'production'에서 캐시를 우회하거나 파일 mtime 기반 무효화를 고려해 주세요.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/app/_llms/rules/component-grid-rule.ts` around lines 86 - 91, The module-level cache (cachedEntries) never invalidates, so getEntries() will return stale ComponentEntry[] after files change; update getEntries() to invalidate or bypass the cache when NODE_ENV !== 'production' (or when file mtimes change): e.g., check process.env.NODE_ENV and call loadEntries() directly in dev, or track last-modified timestamps of the source MDX files and refresh cachedEntries when any mtime is newer; target symbols: cachedEntries, getEntries, and loadEntries.
50-52:titleCase는 첫 글자만 대문자화합니다.
(form-controls)같은 다단어/하이픈 카테고리 폴더가 생기면"Form-controls"처럼 어색하게 출력됩니다. 현재 카테고리 폴더 네이밍 컨벤션이 단일 소문자 단어로 고정되어 있다면 문제 없지만, 향후 확장을 고려해 단어 경계별 대문자화(또는 하이픈/언더스코어 처리)를 권장합니다.♻️ 예시
-function titleCase(value: string): string { - return value.charAt(0).toUpperCase() + value.slice(1); -} +function titleCase(value: string): string { + return value + .split(/[-_\s]+/) + .filter(Boolean) + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join(" "); +}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/app/_llms/rules/component-grid-rule.ts` around lines 50 - 52, titleCase currently only uppercases the first character and yields awkward results for multi-word or hyphenated names; update the titleCase function to split the input on hyphens, underscores or spaces (e.g. using a regex like /[-_\s]+/), capitalize the first letter of each segment and lowercase the rest, then join the segments with a space so inputs like "form-controls" or "multi_word name" become "Form Controls" (handle empty segments safely).
108-111: description 내 특수문자로 마크다운이 깨질 수 있습니다.프론트매터
description에],), 개행, 백틱 등이 포함되면- [title](url) — description라인이 깨집니다. 프론트매터 파싱 단계에서 따옴표는 이미 벗겨지므로, 렌더 시점에 최소한]/)/개행 정도는 이스케이프하거나 치환하는 것을 권장합니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/app/_llms/rules/component-grid-rule.ts` around lines 108 - 111, description에 포함된 특수문자 때문에 마크다운이 깨집니다; for (const entry of list) 루프에서 suffix를 만들기 전에 entry.description을 안전하게 치환/이스케이프하세요 (예: ']' → '\]', ')' → '\)', 줄바꿈은 공백 또는 '\\n'으로 대체, 백틱은 '\`'로 이스케이프 등). 그런 다음 lines.push(`- [${entry.title}](${entry.url})${suffix}`)에서 치환된 safeDescription을 사용하도록 변경하세요.
33-48:parseFrontmatter유틸리티는 프론트매터 파싱 개선으로 이점을 볼 수 있습니다.현재 정규식
/^["']|["']$/g는 비대칭 입력(예:title: 'Hello")을 예기치 않게 처리하며, 프로젝트에 이미 있는yaml@^2.8.2라이브러리를 사용하면 더 견고하게 만들 수 있습니다. 실제 문서의 프론트매터는 따옴표 없는 단순 key-value 형식(title: Docs MCP,description: ...)이므로 현재 동작에 즉각적인 문제는 없지만, 더 견고한 파싱을 위해 yaml 패키지 활용을 검토할 수 있습니다.참고로,
componentGridRule의 Rule 인터페이스 구현(이름, match, transform)은 적절하게 분리되어 있고, 에러 처리도 안전하게 원본 노드를 반환하고 있습니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/app/_llms/rules/component-grid-rule.ts` around lines 33 - 48, Replace the fragile manual frontmatter parsing in parseFrontmatter with the project's yaml library: keep the existing frontmatter extraction (the regex that finds the --- block) but pass match[1] to YAML.parse (imported from the yaml@^2.8.2 package) to obtain a parsed object, then convert/normalize its values to strings (e.g., String(value)) before returning a Record<string,string>; catch and return {} on parse errors so behavior remains safe. Ensure you update the parseFrontmatter function to import YAML and to handle non-string YAML values and exceptions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@docs/app/_llms/rules/component-grid-rule.ts`:
- Around line 86-91: The module-level cache (cachedEntries) never invalidates,
so getEntries() will return stale ComponentEntry[] after files change; update
getEntries() to invalidate or bypass the cache when NODE_ENV !== 'production'
(or when file mtimes change): e.g., check process.env.NODE_ENV and call
loadEntries() directly in dev, or track last-modified timestamps of the source
MDX files and refresh cachedEntries when any mtime is newer; target symbols:
cachedEntries, getEntries, and loadEntries.
- Around line 50-52: titleCase currently only uppercases the first character and
yields awkward results for multi-word or hyphenated names; update the titleCase
function to split the input on hyphens, underscores or spaces (e.g. using a
regex like /[-_\s]+/), capitalize the first letter of each segment and lowercase
the rest, then join the segments with a space so inputs like "form-controls" or
"multi_word name" become "Form Controls" (handle empty segments safely).
- Around line 108-111: description에 포함된 특수문자 때문에 마크다운이 깨집니다; for (const entry of
list) 루프에서 suffix를 만들기 전에 entry.description을 안전하게 치환/이스케이프하세요 (예: ']' → '\]',
')' → '\)', 줄바꿈은 공백 또는 '\\n'으로 대체, 백틱은 '\`'로 이스케이프 등). 그런 다음 lines.push(`-
[${entry.title}](${entry.url})${suffix}`)에서 치환된 safeDescription을 사용하도록 변경하세요.
- Around line 33-48: Replace the fragile manual frontmatter parsing in
parseFrontmatter with the project's yaml library: keep the existing frontmatter
extraction (the regex that finds the --- block) but pass match[1] to YAML.parse
(imported from the yaml@^2.8.2 package) to obtain a parsed object, then
convert/normalize its values to strings (e.g., String(value)) before returning a
Record<string,string>; catch and return {} on parse errors so behavior remains
safe. Ensure you update the parseFrontmatter function to import YAML and to
handle non-string YAML values and exceptions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 63621421-39bf-49d6-b860-49914712fd80
📒 Files selected for processing (5)
docs/app/_llms/__fixtures__/component-grid/basic.output.mddocs/app/_llms/__fixtures__/component-grid/passthrough.input.mdxdocs/app/_llms/__fixtures__/component-grid/passthrough.output.mdxdocs/app/_llms/rules/component-grid-rule.test.tsdocs/app/_llms/rules/component-grid-rule.ts
✅ Files skipped from review due to trivial changes (3)
- docs/app/_llms/fixtures/component-grid/passthrough.output.mdx
- docs/app/_llms/fixtures/component-grid/passthrough.input.mdx
- docs/app/_llms/fixtures/component-grid/basic.output.md
🚧 Files skipped from review as they are similar to previous changes (1)
- docs/app/_llms/rules/component-grid-rule.test.ts
Replace hardcoded /llms/docs/components/{slug}.txt template with the
existing getLLMMarkdownUrl helper so URL construction stays centralized.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
♻️ Duplicate comments (1)
docs/app/_llms/rules/component-grid-rule.ts (1)
16-21:⚠️ Potential issue | 🟡 Minor
deprecated판정은 true 계열 allowlist로 좁히는 편이 안전합니다.현재는 빈 값/
false/no만 제외해서deprecated: off나deprecated: 0같은 false 계열 값도 deprecated로 처리되어 컴포넌트 인덱스에서 빠질 수 있습니다. 명시적인 true 계열만 제외하도록 좁혀 주세요.🐛 제안 수정
export function isDeprecatedValue(value: string | undefined): boolean { if (value === undefined) return false; const normalized = value.trim().toLowerCase(); if (normalized === "") return false; - return normalized !== "false" && normalized !== "no"; + return normalized === "true" || normalized === "yes" || normalized === "on" || normalized === "1"; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/app/_llms/rules/component-grid-rule.ts` around lines 16 - 21, The isDeprecatedValue function currently treats any value other than empty/"false"/"no" as deprecated, which mislabels values like "off" or "0"; update isDeprecatedValue to return true only for an explicit true allowlist (e.g., "true","yes","1","on") and false for all other values (still returning false for undefined/empty). Modify the logic inside isDeprecatedValue to normalize the input and check membership in that explicit true-set instead of using the current negative checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@docs/app/_llms/rules/component-grid-rule.ts`:
- Around line 16-21: The isDeprecatedValue function currently treats any value
other than empty/"false"/"no" as deprecated, which mislabels values like "off"
or "0"; update isDeprecatedValue to return true only for an explicit true
allowlist (e.g., "true","yes","1","on") and false for all other values (still
returning false for undefined/empty). Modify the logic inside isDeprecatedValue
to normalize the input and check membership in that explicit true-set instead of
using the current negative checks.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: ff14e8c9-dadf-42fa-924b-5b15a4344355
📒 Files selected for processing (1)
docs/app/_llms/rules/component-grid-rule.ts
Add a rule that transforms into a categorized markdown list of components so /llms/docs/components.txt exposes the full component index instead of a bare MDX tag.
Summary by CodeRabbit
릴리스 노트
새로운 기능
테스트